Files
ks-app-employment-service/components/modifyExpectedPosition/modifyExpectedPosition.vue
史典卓 0216f6053a flat:AI+
2025-03-28 15:19:42 +08:00

324 lines
8.1 KiB
Vue

<template>
<view v-if="show" class="popup-container">
<view class="popup-content">
<!-- 标题 -->
<view class="title">岗位推荐</view>
<!-- 圆环 -->
<view class="circle-content" :style="{ height: contentHeight * 2 + 'rpx' }">
<!-- 渲染岗位标签 -->
<view class="tabs">
<!-- 动画 -->
<view
class="circle"
:style="{ height: circleDiameter * 2 + 'rpx', width: circleDiameter * 2 + 'rpx' }"
@click="serchforIt"
>
搜一搜
</view>
<view
v-for="(item, index) in jobList"
:key="index"
class="tab"
:style="getLabelStyle(index)"
@click="selectTab(item)"
>
{{ item.name }}
</view>
</view>
</view>
<!-- 关闭按钮 -->
<button class="close-btn" @click="closePopup">完成</button>
</view>
<!-- piker -->
<custom-popup :content-h="100" :visible="state.visible" :header="false">
<view class="popContent">
<view class="s-header">
<view class="heade-lf" @click="state.visible = false">取消</view>
<view class="heade-ri" @click="confimPopup">确认</view>
</view>
<view class="sex-content fl_1">
<expected-station
:search="false"
@onChange="changeJobTitleId"
:station="state.stations"
:max="5"
></expected-station>
</view>
</view>
</custom-popup>
</view>
</template>
<script setup>
import { ref, inject, computed, onMounted, defineProps, defineEmits, reactive } from 'vue';
import useUserStore from '@/stores/useUserStore';
const { $api, navTo, setCheckedNodes } = inject('globalFunction');
const { getUserResume } = useUserStore();
const props = defineProps({
show: Boolean, // 是否显示弹窗
jobList: Array, // 职位列表
});
const contentHeight = ref(373);
const circleDiameter = ref(113);
const screenWidth = ref(375); // 默认值,避免初始化报错
const screenHeight = ref(667);
const centerX = ref(187.5); // 圆心X
const centerY = ref(333.5); // 圆心Y
const radius = ref(120); // 圆半径
const tabPositions = ref([]); // 存储计算好的随机坐标
const emit = defineEmits(['update:show']);
const userInfo = ref({});
const state = reactive({
jobTitleId: '',
stations: [],
visible: false,
});
const closePopup = () => {
emit('update:show', false);
};
const updateScreenSize = () => {
const systemInfo = uni.getSystemInfoSync();
screenWidth.value = systemInfo.windowWidth;
screenHeight.value = systemInfo.windowHeight;
centerX.value = screenWidth.value / 2;
centerY.value = screenHeight.value / 2 - contentHeight.value / 2; // 让圆心稍微上移
};
function serchforIt() {
if (state.stations.length) {
state.visible = true;
return;
}
$api.createRequest('/app/common/jobTitle/treeselect', {}, 'GET').then((resData) => {
if (userInfo.value.jobTitleId) {
const ids = userInfo.value.jobTitleId.split(',').map((id) => Number(id));
setCheckedNodes(resData.data, ids);
}
state.jobTitleId = userInfo.value.jobTitleId;
state.stations = resData.data;
state.visible = true;
});
}
function confimPopup() {
$api.createRequest('/app/user/resume', { jobTitleId: state.jobTitleId }, 'post').then((resData) => {
$api.msg('完成');
state.visible = false;
getUserResume().then(() => {
initload();
});
});
}
function selectTab(item) {
console.log(item);
}
function changeJobTitleId(ids) {
state.jobTitleId = ids;
}
function getLabelStyle(index) {
// 基础半径(根据标签数量动态调整)
const baseRadius = Math.min(Math.max(props.jobList.length * 15, 130), screenWidth.value * 0.4);
// 基础角度间隔
const angleStep = 360 / props.jobList.length;
// 随机扰动参数
const randomRadius = baseRadius + Math.random() * 60 - 50;
const randomAngle = angleStep * index + Math.random() * 20 - 10;
// 极坐标转笛卡尔坐标
const radians = (randomAngle * Math.PI) / 180;
const x = Math.cos(radians) * randomRadius;
const y = Math.sin(radians) * randomRadius;
return {
left: `calc(50% + ${x}px)`,
top: `calc(50% + ${y}px)`,
transform: 'translate(-50%, -50%)',
};
}
onMounted(() => {
userInfo.value = useUserStore().userInfo;
updateScreenSize();
});
</script>
<style scoped>
/* 全屏弹窗 */
.popup-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
overflow: hidden;
z-index: 999;
}
/* 弹窗内容 */
.popup-content {
position: relative;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, #007aff, #005bbb);
text-align: center;
flex-direction: column;
display: flex;
justify-content: space-around;
align-items: center;
}
.title {
padding-left: 20rpx;
width: calc(100% - 20rpx);
height: 68rpx;
font-family: Inter, Inter;
font-weight: 400;
font-size: 56rpx;
color: #ffffff;
line-height: 65rpx;
text-align: left;
font-style: normal;
text-transform: none;
}
.circle-content {
width: 731rpx;
height: 747rpx;
position: relative;
}
.circle {
width: 225rpx;
height: 225rpx;
background: linear-gradient(145deg, #13c57c 0%, #8dc5ae 100%);
border-radius: 50%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-weight: 400;
font-size: 35rpx;
color: #ffffff;
text-align: center;
line-height: 225rpx;
}
.circle::before,
.circle::after {
width: 225rpx;
height: 225rpx;
background: linear-gradient(145deg, #13c57c 0%, #8dc5ae 100%);
border-radius: 50%;
position: absolute;
left: 0;
top: 0;
z-index: -1;
content: '';
}
@keyframes larger2 {
0% {
transform: scale(1);
}
100% {
transform: scale(2.5);
opacity: 0;
}
}
.circle::after {
animation: larger1 2s infinite;
}
@keyframes larger1 {
0% {
transform: scale(1);
}
100% {
transform: scale(3.5);
opacity: 0;
}
}
.circle::before {
animation: larger2 2s infinite;
}
/* 岗位标签 */
.tabs {
position: relative;
width: 100%;
height: 100%;
border-radius: 50%;
z-index: 3;
}
.tab {
position: absolute;
white-space: nowrap;
padding: 8rpx 16rpx;
background: #fff;
border-radius: 40rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
transition: all 0.5s ease;
}
/* 关闭按钮 */
.close-btn {
width: 549rpx;
line-height: 85rpx;
height: 85rpx;
background: #2ecc71;
color: #ffffff;
}
/* popup */
.popContent {
padding: 24rpx;
background: #4778ec;
height: calc(100% - 49rpx);
.sex-content {
border-radius: 20rpx;
width: 100%;
margin-top: 20rpx;
margin-bottom: 40rpx;
display: flex;
overflow: hidden;
height: calc(100% - 100rpx);
border: 1px solid #4778ec;
}
.s-header {
display: flex;
justify-content: space-between;
text-align: center;
font-size: 16px;
.heade-lf {
line-height: 30px;
width: 50px;
height: 30px;
border-radius: 4px;
border: 1px solid #666666;
color: #666666;
background: #ffffff;
}
.heade-ri {
line-height: 30px;
width: 50px;
height: 30px;
border-radius: 4px;
border: 1px solid #1b66ff;
background-color: #1b66ff;
color: #ffffff;
}
}
}
</style>