feat : 对接简历匹配职位接口 修改样式

This commit is contained in:
2025-12-15 17:37:10 +08:00
parent 79207ee66a
commit dd81468f47
3 changed files with 111 additions and 52 deletions

View File

@@ -1,9 +1,25 @@
<template>
<view class="container" id="pixi-box" ref="pixiContainerRef"></view>
<view class="out">
<view v-if="loading" class="loading">
<view class="semicircle-loader"></view>
</view>
<view v-else class="container" id="pixi-box" ref="pixiContainerRef"></view>
</view>
</template>
<script setup>
import { onMounted, onUnmounted, ref, nextTick } from "vue";
import { onMounted, onUnmounted, ref, nextTick ,watch} from "vue";
const props = defineProps({
tags: {
type: Array,
default: [],
},
loading: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["tag-click"]);
// DOM Ref
@@ -15,10 +31,10 @@ let tagsContainer = null;
let activeTagInstances = [];
// 配置数据
const mockTags = [
{ name: "医生", bgColor: 0x0069fe, fontColor: 0xffffff, size: 17, opacity: 1.0, angle: 0, radius: 0 },
const tagsConfig =ref(
[
{ bgColor: 0x0069fe, fontColor: 0xffffff, size: 16, opacity: 1.0, angle: 0, radius: 0 },
{
name: "工程师",
bgColor: 0x87e2ec,
fontColor: 0xffffff,
size: 14,
@@ -28,7 +44,6 @@ const mockTags = [
tailRotation: Math.PI / 2,
},
{
name: "建筑师",
bgColor: 0xffebeb,
tailColor: 0xffe1e1,
fontColor: 0xff6969,
@@ -36,62 +51,47 @@ const mockTags = [
opacity: 1,
angle: -Math.PI / 4.2,
radius: 125,
tailRotation: (3 * Math.PI) / 4,
tailRotation: (3 * Math.PI) / 4.5,
},
{
name: "律师",
bgColor: 0x21ea85,
fontColor: 0xffffff,
size: 15,
opacity: 1,
angle: -Math.PI / 10,
radius: 130,
tailRotation: (3 * Math.PI) / 4,
tailRotation: (3 * Math.PI) / 4.2,
},
{
name: "记者",
bgColor: 0xebf3ff,
tailColor: 0xb9d3ff,
fontColor: 0x1d71ef,
size: 12,
opacity: 1,
angle: Math.PI / 120,
radius: 130,
tailRotation: (3 * Math.PI) / 3.4,
angle: Math.PI / 18,
radius: 135,
tailRotation: (3 * Math.PI) / 4.3,
},
{
name: "程序员",
bgColor: 0xffd4b6,
fontColor: 0xffffff,
size: 14,
opacity: 1,
angle: Math.PI / 7,
radius: 120,
tailRotation: (5 * Math.PI) / 4,
angle: Math.PI / 4.3,
radius: 100,
tailRotation: -(3 * Math.PI) / 4.5,
},
{
name: "摄影师",
bgColor: 0xd8e5fe,
tailColor: 0xb9d3ff,
fontColor: 0x1d71ef,
size: 11,
opacity: 1,
angle: Math.PI / 3,
radius: 79,
tailRotation: (3 * Math.PI) / 2,
},
{
name: "设计师",
bgColor: 0xff9400,
fontColor: 0xffffff,
size: 14,
opacity: 1,
angle: (2 * Math.PI) / 3,
radius: 92,
tailRotation: (7 * Math.PI) / 4,
tailRotation: -Math.PI / 2.4,
},
{
name: "心理咨询师",
bgColor: 0xebf3ff,
tailColor: 0xb9d3ff,
fontColor: 0x1d71ef,
@@ -99,35 +99,48 @@ const mockTags = [
opacity: 1,
angle: (5.4 * Math.PI) / 6,
radius: 110,
tailRotation: (3 * Math.PI) / 1.78,
tailRotation: (3 * Math.PI) / 1.79,
},
{
name: "护士",
bgColor: 0xff6969,
fontColor: 0xffffff,
size: 15,
opacity: 1,
angle: (6.3 * Math.PI) / 5.9,
radius: 110,
tailRotation: Math.PI / 4,
angle: (6.3 * Math.PI) / 5.8,
radius: 120,
tailRotation: Math.PI / 2.9,
},
{
name: "会计",
bgColor: 0xfce9c9,
fontColor: 0xfbc55f,
size: 13,
opacity: 1,
angle: (7.2 * Math.PI) / 5.9,
radius: 120,
tailRotation: Math.PI / 4,
tailRotation: Math.PI / 3,
},
];
]
)
watch(
()=>props.tags,
(val)=>{
if(val&&val.length){
tagsConfig.value.map((tag,index)=>{
console.log(val[index])
tag.name = val[index]?.job_name
})
setTimeout(() => {
initPixi()
}, 100);
}
},
{deep:true}
)
onMounted(async () => {
await nextTick();
setTimeout(() => {
initPixi();
}, 100);
window.addEventListener("resize", handleResize);
});
@@ -182,7 +195,7 @@ const renderScene = (sw, sh) => {
tagsContainer.removeChildren();
activeTagInstances = [];
mockTags.forEach((data, index) => {
tagsConfig.value.forEach((data, index) => {
const scaledRadius = data.radius * ratio;
let x = sw / 2 + scaledRadius * Math.cos(data.angle);
@@ -215,7 +228,7 @@ const renderScene = (sw, sh) => {
};
if (data.radius > 0) {
const tail = createCometTail(data.tailColor || data.bgColor, data.tailRotation, tag.width, ratio);
const tail = createCometTail(data.tailColor || data.bgColor, data.tailRotation, tag.width, tag.height, ratio);
tag.addChildAt(tail, 0);
tag.updateTail = () => tail.updateAnim();
}
@@ -280,15 +293,15 @@ const createTag = (tagData, index, ratio) => {
return tagGroup;
};
const createCometTail = (bgColor, tailRotation, parentWidth, ratio) => {
if (ratio > 1) ratio = ratio * 0.9;
const createCometTail = (bgColor, tailRotation, parentWidth,parentHeight, ratio) => {
if (ratio > 1) ratio = ratio ;
const tailGroup = new PIXI.Container();
const graphics = new PIXI.Graphics();
tailGroup.addChild(graphics);
const baseLength = 45 * ratio;
const startWidth = parentWidth * 0.6;
const endWidth = 20 * ratio;
const startWidth = parentHeight + 20 * ratio;
const endWidth = parentHeight * 0.4;
let breathPhase = Math.random() * Math.PI * 2;
const breathSpeed = 0.04;
@@ -342,6 +355,30 @@ const handleResize = () => {
</script>
<style scoped>
.out{
width: 100%;
height: 100%;
}
.loading{
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.semicircle-loader {
width: 100rpx;
height: 100rpx;
border: 10rpx solid #f3f3f3;
border-top: 10rpx solid #3498db;
border-radius: 50%;
animation: spin 1.2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.container {
width: 100%;
height: 100%;

View File

@@ -61,7 +61,7 @@
<image class="match-card-bg" src="@/static/icon/match-card-bg.png" />
<view class="title">简历匹配职位</view>
<view class="match-item-container">
<AIMatch @tag-click="handleTagClick"></AIMatch>
<AIMatch :tags="matchTags" :loading="matchLoading" @tag-click="handleTagClick"></AIMatch>
</view>
</view>
</view>
@@ -280,6 +280,9 @@ const isSticky = ref(false);
const showScrollBottom = ref(false);
const scrollTop = ref(0);
const matchTags = ref([])
const matchLoading = ref(false)
const emits = defineEmits(['onShowTabbar']);
const waterfallsFlowRef = ref(null);
@@ -359,8 +362,23 @@ const colors = ['#0069FE', '#FF9400', '#FF6969', '#21EA85', '#87E2EC'];
onMounted(() => {
let firstEntry = uni.getStorageSync('firstEntry') === false ? false : true; // 默认未读
maskFirstEntry.value = firstEntry;
getMatchTags()
});
async function getMatchTags(){
try{
matchLoading.value=true
const {data} = await $api.createRequest('/app/user/getJobAdviceByResume')
matchTags.value = data
matchLoading.value=false
}catch(err){
console.err('简历匹配职位获取失败')
}finally{
}
}
const checkStickyStatus = (e) => {
scrollTop.value = e.detail.scrollTop;
nextTick(() => {
@@ -387,7 +405,7 @@ function closeVideoTip() {
const handleTagClick = (tagInfo) => {
console.log('点击的标签信息:', tagInfo);
$api.msg('暂未开放');
navTo(`/pages/search/search?keyWord=${encodeURIComponent(tagInfo.name)}`)
};
const handleItemClick = (item) => {

View File

@@ -155,7 +155,11 @@ const { columnCount, columnSpace } = useColumnCount(() => {
});
});
onLoad(() => {
onLoad((options) => {
if(options.keyWord){
searchValue.value = decodeURIComponent(options.keyWord)
searchBtn()
}
let arr = uni.getStorageSync('searchList');
if (arr) {
historyList.value = uni.getStorageSync('searchList');