Compare commits
39 Commits
qingdaoV0.
...
main-app
| Author | SHA1 | Date | |
|---|---|---|---|
| 60b4d2bef0 | |||
| 3c8176f84e | |||
| cb1052346e | |||
|
|
2b1a87b65e | ||
|
|
67f5dbbfb0 | ||
|
|
f24d95cedf | ||
|
|
c173fdd6a8 | ||
|
|
e0c4f18da0 | ||
|
|
a2ca068669 | ||
|
|
d01f153c6a | ||
|
|
2a5681f8e0 | ||
|
|
adc1c6ef06 | ||
|
|
09faeb3509 | ||
|
|
0d5e3024bc | ||
|
|
268648868f | ||
| 7ce14fa7e2 | |||
| 9a5bffae85 | |||
| 51e67a8c8f | |||
| 531681b74e | |||
| 7e0ec650b1 | |||
| 3a5d8ccb1a | |||
| 34bad16bf4 | |||
| f5099e9cc0 | |||
| 4295199887 | |||
|
|
7322e0854e | ||
|
|
d260e24265 | ||
|
|
c75653b7a3 | ||
|
|
805b384958 | ||
|
|
77f97892bc | ||
|
|
20191c9454 | ||
| fc2d0f90ec | |||
| 6b20c045a9 | |||
| 183c71da3c | |||
| 5e2f8ac169 | |||
| bca67b7f25 | |||
| 83a1078a4d | |||
| e4d100242b | |||
| 3eca164bde | |||
| a7d6b8709c |
25
App.vue
@@ -4,7 +4,7 @@ import { onLaunch, onShow, onHide } from '@dcloudio/uni-app';
|
|||||||
import useUserStore from './stores/useUserStore';
|
import useUserStore from './stores/useUserStore';
|
||||||
import usePageAnimation from './hook/usePageAnimation';
|
import usePageAnimation from './hook/usePageAnimation';
|
||||||
import useDictStore from './stores/useDictStore';
|
import useDictStore from './stores/useDictStore';
|
||||||
const { $api, navTo, appendScriptTagElement, aes_Decrypt, sm2_Decrypt } = inject('globalFunction');
|
const { $api, navTo, appendScriptTagElement, aes_Decrypt, sm2_Decrypt, safeReLaunch } = inject('globalFunction');
|
||||||
import config from '@/config.js';
|
import config from '@/config.js';
|
||||||
usePageAnimation();
|
usePageAnimation();
|
||||||
const appword = 'aKd20dbGdFvmuwrt'; // 固定值
|
const appword = 'aKd20dbGdFvmuwrt'; // 固定值
|
||||||
@@ -14,8 +14,10 @@ onLaunch((options) => {
|
|||||||
useDictStore().getDictData();
|
useDictStore().getDictData();
|
||||||
try {
|
try {
|
||||||
getUserInfo();
|
getUserInfo();
|
||||||
|
useUserStore().changMiniProgramAppStatus(false);
|
||||||
} catch {
|
} catch {
|
||||||
console.log('不是爱山东平台,使用测试登陆');
|
console.log('不是爱山东平台,使用测试登陆');
|
||||||
|
useUserStore().changMiniProgramAppStatus(true);
|
||||||
useUserStore().initSeesionId(); //更新
|
useUserStore().initSeesionId(); //更新
|
||||||
let token = uni.getStorageSync('token') || ''; // 同步获取 缓存信息
|
let token = uni.getStorageSync('token') || ''; // 同步获取 缓存信息
|
||||||
if (token) {
|
if (token) {
|
||||||
@@ -25,9 +27,10 @@ onLaunch((options) => {
|
|||||||
$api.msg('登录成功');
|
$api.msg('登录成功');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
uni.redirectTo({
|
safeReLaunch('/pages/login/login');
|
||||||
url: '/pages/login/login',
|
// uni.redirectTo({
|
||||||
});
|
// url: '/pages/login/login',
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -108,13 +111,15 @@ function loginCallback(userInfo) {
|
|||||||
.then((resume) => {
|
.then((resume) => {
|
||||||
if (resume.data.jobTitleId) {
|
if (resume.data.jobTitleId) {
|
||||||
useUserStore().initSeesionId();
|
useUserStore().initSeesionId();
|
||||||
uni.reLaunch({
|
// uni.reLaunch({
|
||||||
url: '/pages/index/index',
|
// url: '/pages/index/index',
|
||||||
});
|
// });
|
||||||
|
safeReLaunch('/pages/index/index');
|
||||||
} else {
|
} else {
|
||||||
uni.redirectTo({
|
safeReLaunch('/pages/login/login');
|
||||||
url: '/pages/login/login',
|
// uni.redirectTo({
|
||||||
});
|
// url: '/pages/login/login',
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,12 +33,17 @@ html {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* 布局调整 */
|
/* 布局调整 */
|
||||||
|
|
||||||
/* 点击动效 */
|
/* 点击动效 */
|
||||||
/* 缩小 */
|
/* 缩小 */
|
||||||
.button-click {
|
.button-click {
|
||||||
transition: transform 0.1s ease;
|
/* transition: transform 0.1s ease; */
|
||||||
|
transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-click:active {
|
.button-click:active {
|
||||||
@@ -67,7 +72,8 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn-feel {
|
.btn-feel {
|
||||||
transition: transform 0.15s ease;
|
transition: transform 0.5s ease;
|
||||||
|
/* transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); */
|
||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +90,8 @@ html {
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.1s ease, box-shadow 0.1s ease;
|
/* transition: transform 0.4s ease, box-shadow 0.1s ease; */
|
||||||
|
transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
/* box-shadow: 0 4px 0 #2C3E50; */
|
/* box-shadow: 0 4px 0 #2C3E50; */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,4 +479,159 @@ html {
|
|||||||
|
|
||||||
.height-100 {
|
.height-100 {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.pointEveNone {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* TransitionGroup 动画
|
||||||
|
* stagger 错峰
|
||||||
|
* fade-up-stagger --i 淡入上滑(经典错峰)
|
||||||
|
* pop-in-stagger --i 旋转缩放弹入(活泼)
|
||||||
|
* slide-left-stagger 从左侧滑入(消息流风格)
|
||||||
|
* blur-fade-stagger --i 渐显 + 模糊(毛玻璃感)
|
||||||
|
* bounce-up-stagger 从底部弹跳入场(物理感)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* 淡入上滑(经典错峰) */
|
||||||
|
.fade-up-stagger-enter-active {
|
||||||
|
transition: all 0.4s cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
||||||
|
transition-delay: calc(var(--i) * 0.1s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-stagger-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-stagger-leave-active {
|
||||||
|
transition: opacity 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-up-stagger-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
.pop-in-stagger-enter-active {
|
||||||
|
transition: all 0.45s cubic-bezier(0.68, -0.55, 0.27, 1.55);
|
||||||
|
transition-delay: calc(var(--i) * 0.08s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-in-stagger-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.7) rotate(-10deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-in-stagger-leave-active {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop-in-stagger-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.9) rotate(5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-stagger-enter-active {
|
||||||
|
transition: all 0.35s ease-out;
|
||||||
|
transition-delay: calc(var(--i) * 0.07s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-stagger-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-stagger-leave-active {
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-stagger-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 错峰动画 */
|
||||||
|
.stagger-enter-active {
|
||||||
|
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
|
transition-delay: calc(var(--i) * 0.42s);
|
||||||
|
/* 关键:120ms 间隔 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.stagger-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px) scale(0.95);
|
||||||
|
/* 更大位移 + 轻微缩放 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.stagger-leave-active {
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stagger-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stagger-move {
|
||||||
|
transition: transform 0.4s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blur-fade-stagger-enter-active {
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
transition-delay: calc(var(--i) * 0.09s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.blur-fade-stagger-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
filter: blur(8px);
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.blur-fade-stagger-leave-active {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blur-fade-stagger-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
filter: blur(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bounce-up-stagger-enter-active {
|
||||||
|
animation: stagger-bounce 0.6s forwards;
|
||||||
|
animation-delay: calc(var(--i) * 0.12s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bounce-up-stagger-leave-active {
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bounce-up-stagger-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes stagger-bounce {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(100px) scale(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: translateY(-10px) scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
80% {
|
||||||
|
transform: translateY(5px) scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
|
// #ifdef H5
|
||||||
import '@/lib/encryption/sm4.min.js'
|
import '@/lib/encryption/sm4.min.js'
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
import { sm4 } from 'sm-crypto';
|
||||||
|
// #endif
|
||||||
|
|
||||||
import useUserStore from "../stores/useUserStore";
|
import useUserStore from "../stores/useUserStore";
|
||||||
import {
|
import {
|
||||||
createRequestWithCache,
|
createRequestWithCache,
|
||||||
@@ -51,6 +58,23 @@ const prePage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function safeReLaunch(url) {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
const currentPage = pages[pages.length - 1];
|
||||||
|
|
||||||
|
// 移除传入url开头的斜杠用于对比
|
||||||
|
const cleanUrl = url.startsWith('/') ? url.slice(1) : url;
|
||||||
|
|
||||||
|
if (currentPage && currentPage.route === cleanUrl) {
|
||||||
|
console.log('已在当前页');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.reLaunch({
|
||||||
|
url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -285,7 +309,9 @@ function deg2rad(deg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function vacanciesTo(vacancies) {
|
function vacanciesTo(vacancies) {
|
||||||
if (vacancies >= 0) {
|
if (vacancies === null) {
|
||||||
|
return '-人'
|
||||||
|
} else if (vacancies >= 0) {
|
||||||
return vacancies + "人"
|
return vacancies + "人"
|
||||||
} else {
|
} else {
|
||||||
return '不限人数'
|
return '不限人数'
|
||||||
@@ -582,7 +608,6 @@ export function sm4Decrypt(key, value, mode = "hex") {
|
|||||||
cipherType: mode === 'hex' ? 'hex' : 'base64',
|
cipherType: mode === 'hex' ? 'hex' : 'base64',
|
||||||
padding: 'pkcs#5'
|
padding: 'pkcs#5'
|
||||||
});
|
});
|
||||||
|
|
||||||
return decrypted
|
return decrypted
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -625,7 +650,8 @@ export const $api = {
|
|||||||
sendingMiniProgramMessage,
|
sendingMiniProgramMessage,
|
||||||
copyText,
|
copyText,
|
||||||
aes_Decrypt,
|
aes_Decrypt,
|
||||||
createRequestWithCache
|
createRequestWithCache,
|
||||||
|
safeReLaunch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -658,5 +684,6 @@ export default {
|
|||||||
sm4Decrypt,
|
sm4Decrypt,
|
||||||
aes_Decrypt,
|
aes_Decrypt,
|
||||||
sm2_Decrypt,
|
sm2_Decrypt,
|
||||||
sm2_Encrypt
|
sm2_Encrypt,
|
||||||
|
safeReLaunch
|
||||||
}
|
}
|
||||||
@@ -92,6 +92,7 @@ const handleScrollToLower = () => {
|
|||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: calc(100% - var(--window-bottom));
|
height: calc(100% - var(--window-bottom));
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
}
|
}
|
||||||
.app-container {
|
.app-container {
|
||||||
// background-image: url('@/static/icon/background2.png');
|
// background-image: url('@/static/icon/background2.png');
|
||||||
@@ -102,6 +103,8 @@ const handleScrollToLower = () => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-top: calc(var(--window-top) + var(--status-bar-height));
|
||||||
.container-header {
|
.container-header {
|
||||||
min-height: calc(88rpx - 14rpx);
|
min-height: calc(88rpx - 14rpx);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -1,17 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>{{ salaryText }}</view>
|
<view>
|
||||||
|
<view v-if="!minSalary || !maxSalary">面议</view>
|
||||||
|
<view v-else class="texts">
|
||||||
|
<text class="num">{{ minSalary / 1000 }}</text>
|
||||||
|
<text class="unit">k</text>
|
||||||
|
<text class="gap">~</text>
|
||||||
|
<text class="num">{{ maxSalary / 1000 }}</text>
|
||||||
|
<text class="unit">k</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { inject, computed } from 'vue';
|
import { inject, computed } from "vue";
|
||||||
import useDictStore from '../../stores/useDictStore';
|
import useDictStore from "../../stores/useDictStore";
|
||||||
const { minSalary, maxSalary, isMonth } = defineProps(['minSalary', 'maxSalary', 'isMonth']);
|
const { minSalary, maxSalary } = defineProps(["minSalary", "maxSalary"]);
|
||||||
|
|
||||||
const salaryText = computed(() => {
|
|
||||||
if (!minSalary || !maxSalary) return '面议';
|
|
||||||
if (isMonth) {
|
|
||||||
return `${minSalary}-${maxSalary}/月`;
|
|
||||||
}
|
|
||||||
return `${minSalary / 1000}k-${maxSalary / 1000}k`;
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.texts{
|
||||||
|
letter-spacing: 1rpx;
|
||||||
|
}
|
||||||
|
.num{
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.unit{
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.gap{
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-left: 5rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,48 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-for="job in listData" :key="job.id">
|
<transition-group name="blur-fade-stagger" tag="view">
|
||||||
<view class="cards" @click="nextDetail(job)">
|
<view v-for="(job, index) in dataSource" :key="job.id" :style="{ '--i': 2 }">
|
||||||
<view class="card-company">
|
<view class="cards" @click="nextDetail(job)">
|
||||||
<text class="company line_1">{{ job.gsmc }}</text>
|
<view class="card-company">
|
||||||
</view>
|
<text class="company line_1">{{ job.gsmc }}</text>
|
||||||
<view class="card-bottom" >
|
</view>
|
||||||
<view class="fl_box fs_14" >
|
<view class="card-bottom">
|
||||||
<!-- <dict-tree-Label class="mar_ri10" dictType="industry" :value="job.industry"></dict-tree-Label>
|
<view class="fl_box fs_14">
|
||||||
|
<!-- <dict-tree-Label class="mar_ri10" dictType="industry" :value="job.industry"></dict-tree-Label>
|
||||||
<dict-Label dictType="scale" :value="job.scale"></dict-Label> -->
|
<dict-Label dictType="scale" :value="job.scale"></dict-Label> -->
|
||||||
<view>{{job.gsxy}}</view>
|
<view>{{ job.gsxy }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="ris">
|
||||||
|
<text class="fs_14">
|
||||||
|
在招职位·
|
||||||
|
<text class="color_256BFA">{{ job.zzgwsl || '-' }}</text>
|
||||||
|
个
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="ris" >
|
<view class="card-tags">
|
||||||
<text class="fs_14">
|
<view class="tag" v-if="job.nature">
|
||||||
在招职位·
|
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
|
||||||
<text class="color_256BFA">{{ job.zzgwsl || '-' }}</text>
|
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
|
||||||
个
|
</view>
|
||||||
</text>
|
<view class="tag">
|
||||||
</view>
|
{{ vacanciesTo(job.vacancies) }}
|
||||||
</view>
|
</view>
|
||||||
<view class="card-tags">
|
<view class="tag" v-if="job.qyxz">
|
||||||
<view class="tag" v-if="job.nature">
|
{{ job.qyxz }}
|
||||||
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
|
</view>
|
||||||
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
|
|
||||||
</view>
|
|
||||||
<view class="tag">
|
|
||||||
{{ vacanciesTo(job.vacancies) }}
|
|
||||||
</view>
|
|
||||||
<view class="tag" v-if="job.qyxz">
|
|
||||||
{{job.qyxz}}
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</transition-group>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { inject, computed, toRaw } from 'vue';
|
import { inject, computed, toRaw, watch, ref, nextTick } from 'vue';
|
||||||
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
|
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
|
||||||
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
||||||
const recommedIndexDb = useRecommedIndexedDBStore();
|
const recommedIndexDb = useRecommedIndexedDBStore();
|
||||||
|
|
||||||
|
const dataSource = ref([]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
list: {
|
list: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: '标题',
|
default: () => [],
|
||||||
},
|
},
|
||||||
longitude: {
|
longitude: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@@ -61,13 +65,49 @@ const props = defineProps({
|
|||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const processedIds = new Set();
|
||||||
|
watch(
|
||||||
|
() => props.list,
|
||||||
|
(newList) => {
|
||||||
|
if (!Array.isArray(newList)) return;
|
||||||
|
|
||||||
const listData = computed(() => {
|
let shouldReset = false;
|
||||||
return props.list;
|
|
||||||
});
|
if (dataSource.value.length > newList.length) {
|
||||||
|
shouldReset = true;
|
||||||
|
} else if (dataSource.value.length > 0 && newList.length > 0) {
|
||||||
|
// 注意:这里沿用你代码中使用的 item.id 作为唯一标识
|
||||||
|
const oldId = dataSource.value[0].id;
|
||||||
|
const newId = newList[0].id;
|
||||||
|
if (oldId !== newId) {
|
||||||
|
shouldReset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldReset) {
|
||||||
|
dataSource.value = [];
|
||||||
|
processedIds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const newItems = newList.filter((item) => !processedIds.has(item.id));
|
||||||
|
|
||||||
|
if (newItems.length === 0) return;
|
||||||
|
|
||||||
|
newItems.forEach((item) => processedIds.add(item.id));
|
||||||
|
const delay = 50;
|
||||||
|
newItems.forEach((item, index) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
dataSource.value.push(item);
|
||||||
|
}, index * delay);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
function nextDetail(company) {
|
function nextDetail(company) {
|
||||||
navTo(`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.gsID}&companyName=${company.gsmc}&zphId=${props.zphId}&dataType=2`);
|
navTo(
|
||||||
|
`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.gsID}&companyName=${company.gsmc}&zphId=${props.zphId}&dataType=2`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,54 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-for="job in listData" :key="job.id">
|
<transition-group name="blur-fade-stagger" tag="view">
|
||||||
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
|
<view v-for="job in dataSource" :key="job.id || job.jobId" :style="{ '--i': 2 }">
|
||||||
<view class="card-company">
|
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
|
||||||
<text class="company">{{ job.jobTitle }}</text>
|
<view class="card-company">
|
||||||
<view class="salary">
|
<text class="company">{{ job.jobTitle }}</text>
|
||||||
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
|
<view class="salary">
|
||||||
|
<Salary-Expectation
|
||||||
|
:max-salary="job.maxSalary"
|
||||||
|
:min-salary="job.minSalary"
|
||||||
|
></Salary-Expectation>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="card-companyName">{{ job.gwmc }}</view>
|
||||||
|
<view class="card-tags">
|
||||||
|
<view class="tag">
|
||||||
|
<dict-Label dictType="education" :value="job.education"></dict-Label>
|
||||||
|
</view>
|
||||||
|
<view class="tag">
|
||||||
|
<dict-Label dictType="experience" :value="job.experience"></dict-Label>
|
||||||
|
</view>
|
||||||
|
<view class="tag">
|
||||||
|
{{ vacanciesTo(job.vacancies) }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="card-bottom">
|
||||||
|
<view>{{ job.postingDate }}</view>
|
||||||
|
<view>
|
||||||
|
<convert-distance
|
||||||
|
:alat="job.latitude"
|
||||||
|
:along="job.longitude"
|
||||||
|
:blat="latitude"
|
||||||
|
:blong="longitude"
|
||||||
|
></convert-distance>
|
||||||
|
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="card-companyName">{{ job.gwmc }}</view>
|
<view class="date-jobTitle" v-else>
|
||||||
<view class="card-tags">
|
{{ job.title }}
|
||||||
<view class="tag">
|
|
||||||
<dict-Label dictType="education" :value="job.education"></dict-Label>
|
|
||||||
</view>
|
|
||||||
<view class="tag">
|
|
||||||
<dict-Label dictType="experience" :value="job.experience"></dict-Label>
|
|
||||||
</view>
|
|
||||||
<view class="tag">
|
|
||||||
{{ vacanciesTo(job.vacancies) }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="card-bottom">
|
|
||||||
<view>{{ job.postingDate }}</view>
|
|
||||||
<view>
|
|
||||||
<convert-distance
|
|
||||||
:alat="job.latitude"
|
|
||||||
:along="job.longitude"
|
|
||||||
:blat="latitude"
|
|
||||||
:blong="longitude"
|
|
||||||
></convert-distance>
|
|
||||||
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="date-jobTitle" v-else>
|
</transition-group>
|
||||||
{{ job.title }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { inject, computed, toRaw } from 'vue';
|
import { inject, computed, toRaw, ref, watch } from 'vue';
|
||||||
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
|
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
|
||||||
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
||||||
const recommedIndexDb = useRecommedIndexedDBStore();
|
const recommedIndexDb = useRecommedIndexedDBStore();
|
||||||
|
const dataSource = ref([]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
list: {
|
list: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -71,6 +77,51 @@ const listData = computed(() => {
|
|||||||
return props.list;
|
return props.list;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const processedIds = new Set();
|
||||||
|
watch(
|
||||||
|
() => props.list,
|
||||||
|
(newList) => {
|
||||||
|
if (!Array.isArray(newList)) return;
|
||||||
|
|
||||||
|
// --- 新增逻辑开始 ---
|
||||||
|
// 判断是否需要重置数据 (例如:点击了搜索、切换了Tab、或下拉刷新)
|
||||||
|
let shouldReset = false;
|
||||||
|
|
||||||
|
// 场景1: 新列表长度比当前渲染的列表短,说明发生了重置(如从20条变成了10条)
|
||||||
|
if (dataSource.value.length > newList.length) {
|
||||||
|
shouldReset = true;
|
||||||
|
}
|
||||||
|
// 场景2: 列表不为空,且第一条数据的ID发生了变化,说明是全新的搜索结果
|
||||||
|
else if (dataSource.value.length > 0 && newList.length > 0) {
|
||||||
|
const oldId = dataSource.value[0].id || dataSource.value[0].jobId;
|
||||||
|
const newId = newList[0].id || newList[0].jobId;
|
||||||
|
if (oldId !== newId) {
|
||||||
|
shouldReset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果判定为重置,则清空现有数据和ID记录
|
||||||
|
if (shouldReset) {
|
||||||
|
dataSource.value = [];
|
||||||
|
processedIds.clear();
|
||||||
|
}
|
||||||
|
// --- 新增逻辑结束 ---
|
||||||
|
|
||||||
|
const newItems = newList.filter((item) => !processedIds.has(item.id || item.jobId));
|
||||||
|
|
||||||
|
if (newItems.length === 0) return;
|
||||||
|
|
||||||
|
newItems.forEach((item) => processedIds.add(item.id || item.jobId));
|
||||||
|
const delay = 50;
|
||||||
|
newItems.forEach((item, index) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
dataSource.value.push(item);
|
||||||
|
}, index * delay);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true } // 建议加上 deep,虽然这里监听的是数组引用变化
|
||||||
|
);
|
||||||
|
|
||||||
function nextDetail(job) {
|
function nextDetail(job) {
|
||||||
// 记录岗位类型,用作数据分析
|
// 记录岗位类型,用作数据分析
|
||||||
if (job.jobCategory) {
|
if (job.jobCategory) {
|
||||||
|
|||||||
@@ -1,48 +1,54 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-for="job in listData" :key="job.id">
|
<transition-group name="blur-fade-stagger" tag="view">
|
||||||
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
|
<view v-for="job in dataSource" :key="job.id" :style="{ '--i': 2 }">
|
||||||
<view class="card-company">
|
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
|
||||||
<text class="company">{{ job.gwmc }}</text>
|
<view class="card-company">
|
||||||
<view class="salary">
|
<text class="company">{{ job.gwmc }}</text>
|
||||||
<Salary-Expectation :max-salary="job.maxSalary" :min-salary="job.minSalary"></Salary-Expectation>
|
<view class="salary">
|
||||||
|
<Salary-Expectation
|
||||||
|
:max-salary="job.maxSalary"
|
||||||
|
:min-salary="job.minSalary"
|
||||||
|
></Salary-Expectation>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="card-companyName">{{ job.gsmc }}</view>
|
||||||
<view class="card-companyName">{{ job.gsmc }}</view>
|
<view class="card-tags">
|
||||||
<view class="card-tags">
|
<view class="tag">
|
||||||
<view class="tag">
|
{{ job.xlyq == '不限' ? '学历不限' : job.xlyq }}
|
||||||
{{job.xlyq == '不限' ? '学历不限' : job.xlyq}}
|
</view>
|
||||||
|
<view class="tag">
|
||||||
|
{{ job.gwgzjy == '不限' ? '经验不限' : job.gwgzjy }}
|
||||||
|
</view>
|
||||||
|
<view class="tag">
|
||||||
|
{{ vacanciesTo(job.zprs) }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tag">
|
<view class="card-bottom">
|
||||||
{{job.gwgzjy == '不限' ? '经验不限' : job.gwgzjy}}
|
<view>{{ parseDateTime(job.createTime).date }}</view>
|
||||||
</view>
|
<view>
|
||||||
<view class="tag">
|
<!-- <convert-distance
|
||||||
{{ vacanciesTo(job.zprs) }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="card-bottom">
|
|
||||||
<view>{{ parseDateTime(job.createTime).date }}</view>
|
|
||||||
<view>
|
|
||||||
<!-- <convert-distance
|
|
||||||
:alat="job.latitude"
|
:alat="job.latitude"
|
||||||
:along="job.longitude"
|
:along="job.longitude"
|
||||||
:blat="latitude"
|
:blat="latitude"
|
||||||
:blong="longitude"
|
:blong="longitude"
|
||||||
></convert-distance>
|
></convert-distance>
|
||||||
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> -->
|
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> -->
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="date-jobTitle" v-else>
|
||||||
|
{{ job.title }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="date-jobTitle" v-else>
|
</transition-group>
|
||||||
{{ job.title }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { inject, computed, toRaw } from 'vue';
|
import { inject, computed, toRaw, ref, watch } from 'vue';
|
||||||
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
|
const { insertSortData, navTo, vacanciesTo } = inject('globalFunction');
|
||||||
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
||||||
const recommedIndexDb = useRecommedIndexedDBStore();
|
const recommedIndexDb = useRecommedIndexedDBStore();
|
||||||
|
const dataSource = ref([]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
list: {
|
list: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -71,6 +77,24 @@ const listData = computed(() => {
|
|||||||
return props.list;
|
return props.list;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const processedIds = new Set();
|
||||||
|
watch(
|
||||||
|
() => props.list,
|
||||||
|
(newList) => {
|
||||||
|
if (!Array.isArray(newList)) return;
|
||||||
|
const newItems = newList.filter((item) => !processedIds.has(item.id));
|
||||||
|
if (newItems.length === 0) return;
|
||||||
|
newItems.forEach((item) => processedIds.add(item.id));
|
||||||
|
const delay = 50;
|
||||||
|
newItems.forEach((item, index) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
dataSource.value.push(item);
|
||||||
|
}, index * delay);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
function nextDetail(job) {
|
function nextDetail(job) {
|
||||||
// 记录岗位类型,用作数据分析
|
// 记录岗位类型,用作数据分析
|
||||||
if (job.jobCategory) {
|
if (job.jobCategory) {
|
||||||
|
|||||||
25
config.js
@@ -4,15 +4,23 @@ export default {
|
|||||||
// baseUrl: 'http://192.168.3.29:8081',
|
// baseUrl: 'http://192.168.3.29:8081',
|
||||||
// baseUrl: 'http://10.213.6.207:19010/api',
|
// baseUrl: 'http://10.213.6.207:19010/api',
|
||||||
// 语音转文字
|
// 语音转文字
|
||||||
// vioceBaseURl: 'wss://qd.zhaopinzao8dian.com/api/speech-recognition',
|
// vioceBaseURl: 'wss://qd.zhaopinzao8dian.com/api/system/asr/connect', // 自定义
|
||||||
vioceBaseURl: 'wss://qd.zhaopinzao8dian.com/api/system/asr/connect', // 自定义
|
vioceBaseURl: 'wss://fw.rc.qingdao.gov.cn/rgpp-api/api/system/asr/connect', // 内网
|
||||||
// 语音合成
|
// 语音合成
|
||||||
speechSynthesis: 'wss://qd.zhaopinzao8dian.com/api/speech-synthesis',
|
speechSynthesis: 'wss://qd.zhaopinzao8dian.com/api/speech-synthesis',
|
||||||
speechSynthesis2: 'wss://resource.zhuoson.com/synthesis/',
|
speechSynthesis2: 'wss://resource.zhuoson.com/synthesis/', //直接替换即可
|
||||||
// indexedDB
|
// indexedDB
|
||||||
DBversion: 2,
|
DBversion: 3,
|
||||||
// 只使用本地缓寸的数据
|
// 只使用本地缓寸的数据
|
||||||
OnlyUseCachedDB: false,
|
OnlyUseCachedDB: false,
|
||||||
|
// 素质测评URL
|
||||||
|
Quality_assessment_URL: 'https://web1.isdapp.shandong.gov.cn/jmopen_files/unzip/3511c4a8b32c468489ace780d40f6d92/zycpvhyjw/index.html#/pages/evaluation_record/evaluation_record?uuid=2f19e4d676df4650b6fb7edf87461571',
|
||||||
|
// 职业指导
|
||||||
|
Career_guidance: 'https://web1.isdapp.shandong.gov.cn/jmopen_files/unzip/927b0032dfe3405ab0124fda9282ebdd/zyzd/index.html',
|
||||||
|
// ai 模拟面试
|
||||||
|
mock_interview: 'https://web1.isdapp.shandong.gov.cn/jmopen_files/unzip/4a21b3b6efec4f8db2c3d3d5fa51edc9/szjx-rgzn-xnsc/#/pages/interview/schedule',
|
||||||
|
// VR虚拟招聘会
|
||||||
|
virtualJobFair: 'https://web1.isdapp.shandong.gov.cn/jmopen_files/unzip/4a21b3b6efec4f8db2c3d3d5fa51edc9/szjx-rgzn-xnsc/#/pages/metaverse/job_fair',
|
||||||
// 使用模拟定位
|
// 使用模拟定位
|
||||||
UsingSimulatedPositioning: true,
|
UsingSimulatedPositioning: true,
|
||||||
// 应用信息
|
// 应用信息
|
||||||
@@ -78,5 +86,12 @@ export default {
|
|||||||
mode: 'ECB', // default
|
mode: 'ECB', // default
|
||||||
iv: 'UISwD9fW6cFh9SNS', // default is null
|
iv: 'UISwD9fW6cFh9SNS', // default is null
|
||||||
cipherType: 'base64' // default is base64
|
cipherType: 'base64' // default is base64
|
||||||
}
|
},
|
||||||
|
animations: [ //动画
|
||||||
|
'fade-up-stagger',
|
||||||
|
'pop-in-stagger',
|
||||||
|
'slide-left-stagger',
|
||||||
|
'blur-fade-stagger',
|
||||||
|
'bounce-up-stagger'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
214
hook/piper-sdk.js
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/**
|
||||||
|
* PiperTTS SDK - 兼容移动端的流式语音合成客户端
|
||||||
|
* 特性:
|
||||||
|
* 1. Web Audio API 实时调度,解决移动端不支持 MSE 的问题
|
||||||
|
* 2. 头部注入 (Header Injection) 技术,解决分片解码错误
|
||||||
|
* 3. 自动状态管理与事件回调
|
||||||
|
*/
|
||||||
|
export class PiperTTS {
|
||||||
|
constructor(config = {}) {
|
||||||
|
this.baseUrl = config.baseUrl || 'http://localhost:5001';
|
||||||
|
this.audioCtx = config.audioCtx || new(window.AudioContext || window.webkitAudioContext)();
|
||||||
|
this.onStatus = config.onStatus || ((msg, type) => console.log(`[Piper] ${msg}`));
|
||||||
|
this.onStart = config.onStart || (() => {});
|
||||||
|
this.onEnd = config.onEnd || (() => {});
|
||||||
|
|
||||||
|
// 内部状态
|
||||||
|
this.ws = null;
|
||||||
|
this.nextTime = 0; // 下一段音频的预定播放时间
|
||||||
|
this.audioHeader = null; // 保存WAV/MP3头部
|
||||||
|
this.chunkQueue = []; // 数据缓冲队列
|
||||||
|
this.queueSize = 0; // 当前缓冲区字节数
|
||||||
|
this.analyser = null; // 可视化分析器节点
|
||||||
|
|
||||||
|
// 配置参数
|
||||||
|
this.flushThreshold = 8 * 1024; // 8KB 阈值
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [重要] 初始化音频引擎
|
||||||
|
* 必须在用户点击事件(click/touch)中调用一次,否则手机上没声音
|
||||||
|
*/
|
||||||
|
async init() {
|
||||||
|
if (this.audioCtx.state === 'suspended') {
|
||||||
|
await this.audioCtx.resume();
|
||||||
|
this.onStatus('音频引擎已激活', 'success');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定可视化分析器
|
||||||
|
* @param {AnalyserNode} analyserNode - Web Audio Analyser节点
|
||||||
|
*/
|
||||||
|
attachVisualizer(analyserNode) {
|
||||||
|
this.analyser = analyserNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始合成并播放
|
||||||
|
* @param {string} text - 要合成的文本
|
||||||
|
* @param {object} options - 可选参数 {speaker_id, noise_scale, etc.}
|
||||||
|
*/
|
||||||
|
speak(text, options = {}) {
|
||||||
|
if (!text) return;
|
||||||
|
|
||||||
|
this.stop(); // 清理上一次播放
|
||||||
|
this.onStatus('正在建立连接...', 'processing');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const wsUrl = this.baseUrl.replace(/^http/, 'ws') + '/ws/synthesize';
|
||||||
|
this.ws = new WebSocket(wsUrl);
|
||||||
|
this.ws.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
|
this.ws.onopen = () => {
|
||||||
|
this.onStatus('连接成功,请求生成...', 'processing');
|
||||||
|
// 初始化时间轴:当前时间 + 缓冲延迟
|
||||||
|
this.nextTime = this.audioCtx.currentTime + 0.1;
|
||||||
|
this.onStart();
|
||||||
|
|
||||||
|
this.ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
text: text,
|
||||||
|
speaker_id: options.speakerId || null,
|
||||||
|
length_scale: options.lengthScale || 1.0,
|
||||||
|
noise_scale: options.noiseScale || 0.667,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.ws.onmessage = (event) => this._handleMessage(event);
|
||||||
|
|
||||||
|
this.ws.onclose = async () => {
|
||||||
|
// 处理剩余残余数据
|
||||||
|
if (this.chunkQueue.length > 0) {
|
||||||
|
await this._processQueue(true);
|
||||||
|
}
|
||||||
|
this.onStatus('播放结束', 'success');
|
||||||
|
this.onEnd();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.ws.onerror = (err) => {
|
||||||
|
console.error(err);
|
||||||
|
this.onStatus('连接发生错误', 'error');
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
this.onStatus(`启动失败: ${e.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止播放并重置状态
|
||||||
|
*/
|
||||||
|
stop() {
|
||||||
|
if (this.ws) {
|
||||||
|
this.ws.close();
|
||||||
|
this.ws = null;
|
||||||
|
}
|
||||||
|
// 重置缓冲
|
||||||
|
this.chunkQueue = [];
|
||||||
|
this.queueSize = 0;
|
||||||
|
this.audioHeader = null;
|
||||||
|
// 注意:Web Audio API 很难"立即停止"已经在 flight 中的 node,
|
||||||
|
// 除非我们追踪所有的 sourceNode 并调用 .stop()。
|
||||||
|
// 简单实现:suspend 再 resume 或者关闭 context (不推荐频繁关闭)。
|
||||||
|
// 这里的 stop 主要停止数据接收。
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 内部私有方法 ---
|
||||||
|
|
||||||
|
async _handleMessage(event) {
|
||||||
|
if (!(event.data instanceof ArrayBuffer)) return;
|
||||||
|
|
||||||
|
const chunk = event.data;
|
||||||
|
|
||||||
|
// 1. 捕获头部 (Header Injection 核心)
|
||||||
|
if (!this.audioHeader) {
|
||||||
|
// 截取前100字节作为通用头
|
||||||
|
this.audioHeader = chunk.slice(0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 入队
|
||||||
|
this.chunkQueue.push(chunk);
|
||||||
|
this.queueSize += chunk.byteLength;
|
||||||
|
|
||||||
|
// 3. 达到阈值则解码播放
|
||||||
|
if (this.queueSize >= this.flushThreshold) {
|
||||||
|
await this._processQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async _processQueue(isLast = false) {
|
||||||
|
if (this.chunkQueue.length === 0) return;
|
||||||
|
|
||||||
|
// 1. 合并 Buffer
|
||||||
|
const rawData = new Uint8Array(this.queueSize);
|
||||||
|
let offset = 0;
|
||||||
|
for (const chunk of this.chunkQueue) {
|
||||||
|
rawData.set(new Uint8Array(chunk), offset);
|
||||||
|
offset += chunk.byteLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空队列
|
||||||
|
this.chunkQueue = [];
|
||||||
|
this.queueSize = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 2. 构造带头部的 Buffer
|
||||||
|
let decodeTarget;
|
||||||
|
// 简单的头部检测逻辑,如果没有头,就拼上去
|
||||||
|
if (this.audioHeader && !this._hasHeader(rawData)) {
|
||||||
|
const newBuffer = new Uint8Array(this.audioHeader.byteLength + rawData.byteLength);
|
||||||
|
newBuffer.set(new Uint8Array(this.audioHeader), 0);
|
||||||
|
newBuffer.set(rawData, this.audioHeader.byteLength);
|
||||||
|
decodeTarget = newBuffer.buffer;
|
||||||
|
} else {
|
||||||
|
decodeTarget = rawData.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 解码
|
||||||
|
const decodedBuffer = await this.audioCtx.decodeAudioData(decodeTarget);
|
||||||
|
|
||||||
|
// 4. 播放调度
|
||||||
|
this._scheduleBuffer(decodedBuffer);
|
||||||
|
} catch (err) {
|
||||||
|
// 解码失败处理:如果是中间数据,放回队列头部等待拼接
|
||||||
|
if (!isLast) {
|
||||||
|
this.chunkQueue.unshift(rawData);
|
||||||
|
this.queueSize += rawData.byteLength;
|
||||||
|
} else {
|
||||||
|
console.warn('最后一段数据解码失败,丢弃', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduleBuffer(decodedBuffer) {
|
||||||
|
const source = this.audioCtx.createBufferSource();
|
||||||
|
source.buffer = decodedBuffer;
|
||||||
|
|
||||||
|
// 连接可视化
|
||||||
|
if (this.analyser) {
|
||||||
|
source.connect(this.analyser);
|
||||||
|
this.analyser.connect(this.audioCtx.destination);
|
||||||
|
} else {
|
||||||
|
source.connect(this.audioCtx.destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算播放时间:如果发生卡顿,立即播放;否则无缝衔接
|
||||||
|
const scheduleTime = Math.max(this.audioCtx.currentTime, this.nextTime);
|
||||||
|
source.start(scheduleTime);
|
||||||
|
|
||||||
|
// 更新下一段的开始时间
|
||||||
|
this.nextTime = scheduleTime + decodedBuffer.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasHeader(uint8Arr) {
|
||||||
|
if (uint8Arr.byteLength < 4) return false;
|
||||||
|
// Check "RIFF" (WAV)
|
||||||
|
if (uint8Arr[0] === 82 && uint8Arr[1] === 73 && uint8Arr[2] === 70) return true;
|
||||||
|
// Check "ID3" (MP3)
|
||||||
|
if (uint8Arr[0] === 73 && uint8Arr[1] === 68 && uint8Arr[2] === 51) return true;
|
||||||
|
// Check MP3 Sync Word (Simplify)
|
||||||
|
if (uint8Arr[0] === 0xff && (uint8Arr[1] & 0xe0) === 0xe0) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,13 +47,17 @@ export function useColumnCount(onChange = () => {}) {
|
|||||||
columnCount.value = 2
|
columnCount.value = 2
|
||||||
calcColumn()
|
calcColumn()
|
||||||
// if (process.client) {
|
// if (process.client) {
|
||||||
|
// #ifdef H5
|
||||||
window.addEventListener('resize', calcColumn)
|
window.addEventListener('resize', calcColumn)
|
||||||
|
// #endif
|
||||||
// }
|
// }
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// if (process.client) {
|
// if (process.client) {
|
||||||
|
// #ifdef H5
|
||||||
window.removeEventListener('resize', calcColumn)
|
window.removeEventListener('resize', calcColumn)
|
||||||
|
// #endif
|
||||||
// }
|
// }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -86,8 +86,7 @@ export function usePagination(
|
|||||||
const res = await requestFn(params)
|
const res = await requestFn(params)
|
||||||
|
|
||||||
const rawData = res[dataKey]
|
const rawData = res[dataKey]
|
||||||
const total = res[totalKey] || 99999999
|
|
||||||
console.log(total, rawData)
|
|
||||||
const data = typeof transformFn === 'function' ? transformFn(rawData) : rawData
|
const data = typeof transformFn === 'function' ? transformFn(rawData) : rawData
|
||||||
|
|
||||||
if (type === 'refresh') {
|
if (type === 'refresh') {
|
||||||
@@ -96,9 +95,9 @@ export function usePagination(
|
|||||||
list.value.push(...data)
|
list.value.push(...data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const total = res[totalKey] || list.value?.length
|
||||||
pageState.total = total
|
pageState.total = total
|
||||||
pageState.maxPage = Math.ceil(total / pageState.pageSize)
|
pageState.maxPage = Math.ceil(total / pageState.pageSize)
|
||||||
|
|
||||||
finished.value = list.value.length >= total
|
finished.value = list.value.length >= total
|
||||||
empty.value = list.value.length === 0
|
empty.value = list.value.length === 0
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -1,285 +1,168 @@
|
|||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
onMounted
|
onMounted,
|
||||||
|
watch
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
// 如果是 uni-app 环境,保留这些导入;如果是纯 Web Vue3,可以移除
|
|
||||||
import {
|
import {
|
||||||
onHide,
|
onHide,
|
||||||
onUnload
|
onUnload
|
||||||
} from '@dcloudio/uni-app'
|
} from '@dcloudio/uni-app'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
|
// 请确保 piper-sdk.js 已经正确 export class PiperTTS
|
||||||
|
import {
|
||||||
|
PiperTTS
|
||||||
|
} from './piper-sdk.js'
|
||||||
|
|
||||||
/**
|
|
||||||
* Piper TTS 播放钩子 (WebSocket MSE 流式版 - 含 cancelAudio)
|
|
||||||
* 依赖: 后端必须去除 MP3 ID3 标签 (-map_metadata -1)
|
|
||||||
*/
|
|
||||||
export function useTTSPlayer() {
|
export function useTTSPlayer() {
|
||||||
// 状态管理
|
// UI 状态
|
||||||
const isSpeaking = ref(false)
|
const isSpeaking = ref(false)
|
||||||
const isPaused = ref(false)
|
const isPaused = ref(false)
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
|
|
||||||
// 核心对象
|
// SDK 实例
|
||||||
let audio = null
|
let piper = null
|
||||||
let mediaSource = null
|
|
||||||
let sourceBuffer = null
|
|
||||||
let ws = null
|
|
||||||
|
|
||||||
// 缓冲队列管理
|
/**
|
||||||
let bufferQueue = []
|
* 初始化 SDK 实例
|
||||||
let isAppending = false
|
* 每次 stop 后 piper 会被置空,这里会重新创建
|
||||||
let isStreamEnded = false
|
*/
|
||||||
|
const initPiper = () => {
|
||||||
|
if (piper) return
|
||||||
|
|
||||||
// 初始化 Audio 监听器 (只运行一次)
|
let baseUrl = config.speechSynthesis2 || ''
|
||||||
const initAudioElement = () => {
|
baseUrl = baseUrl.replace(/\/$/, '')
|
||||||
if (!audio && typeof window !== 'undefined') {
|
|
||||||
audio = new Audio()
|
|
||||||
|
|
||||||
// 错误监听
|
piper = new PiperTTS({
|
||||||
audio.addEventListener('error', (e) => {
|
baseUrl: baseUrl,
|
||||||
// 如果是手动停止导致的 error (src 被置空),忽略
|
onStatus: (msg, type) => {
|
||||||
if (!audio.src) return
|
if (type === 'error') {
|
||||||
console.error('Audio Player Error:', e)
|
console.error('[TTS Error]', msg)
|
||||||
|
// 出错时不重置状态,交给用户手动处理或结束事件处理
|
||||||
|
resetState()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onStart: () => {
|
||||||
|
isLoading.value = false
|
||||||
|
isSpeaking.value = true
|
||||||
|
isPaused.value = false
|
||||||
|
},
|
||||||
|
onEnd: () => {
|
||||||
resetState()
|
resetState()
|
||||||
})
|
}
|
||||||
|
})
|
||||||
// 播放结束监听
|
|
||||||
audio.addEventListener('ended', () => {
|
|
||||||
resetState()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 核心朗读方法 (WebSocket)
|
* 核心朗读方法
|
||||||
* @param {string} text - 要朗读的文本
|
|
||||||
*/
|
*/
|
||||||
const speak = async (text) => {
|
const speak = async (text) => {
|
||||||
if (!text) return
|
if (!text) return
|
||||||
|
|
||||||
// 1. 提取文本
|
|
||||||
const processedText = extractSpeechText(text)
|
const processedText = extractSpeechText(text)
|
||||||
if (!processedText) return
|
if (!processedText) return
|
||||||
|
|
||||||
// 2. 彻底清理旧状态
|
// 1. 【关键修改】先彻底停止并销毁旧实例
|
||||||
cancelAudio()
|
// 这会断开 socket 并且 close AudioContext,确保上一个声音立即消失
|
||||||
initAudioElement()
|
await stop()
|
||||||
|
|
||||||
|
// 2. 初始化新实例 (因为 stop() 把 piper 设为了 null)
|
||||||
|
initPiper()
|
||||||
|
|
||||||
|
// 3. 更新 UI 为加载中
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
isSpeaking.value = true
|
|
||||||
isPaused.value = false
|
isPaused.value = false
|
||||||
isStreamEnded = false
|
isSpeaking.value = true // 预先设为 true,防止按钮闪烁
|
||||||
|
|
||||||
// 3. 检查环境
|
try {
|
||||||
if (!window.MediaSource || !window.WebSocket) {
|
// 4. 激活音频引擎 (移动端防静音关键)
|
||||||
console.error('当前环境不支持 MediaSource 或 WebSocket')
|
await piper.init()
|
||||||
|
|
||||||
|
// 5. 发送请求
|
||||||
|
piper.speak(processedText, {
|
||||||
|
speakerId: 0,
|
||||||
|
noiseScale: 0.667,
|
||||||
|
lengthScale: 1.0
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error('TTS Speak Error:', e)
|
||||||
resetState()
|
resetState()
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 4. 初始化 MSE
|
|
||||||
mediaSource = new MediaSource()
|
|
||||||
// 绑定 MSE 到 Audio
|
|
||||||
audio.src = URL.createObjectURL(mediaSource)
|
|
||||||
|
|
||||||
// 监听 MSE 打开事件
|
|
||||||
mediaSource.addEventListener('sourceopen', () => {
|
|
||||||
// 防止多次触发
|
|
||||||
if (mediaSource.sourceBuffers.length > 0) return
|
|
||||||
startWebSocketStream(processedText)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 尝试播放 (处理浏览器自动播放策略)
|
|
||||||
const playPromise = audio.play()
|
|
||||||
if (playPromise !== undefined) {
|
|
||||||
playPromise.catch(e => {
|
|
||||||
console.warn('自动播放被拦截 (需用户交互):', e)
|
|
||||||
// 保持 isSpeaking 为 true,UI 显示播放按钮,用户点击后调用 resume() 即可
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error('TTS Initialization Failed:', err)
|
|
||||||
cancelAudio()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动 WebSocket 流程
|
/**
|
||||||
const startWebSocketStream = (text) => {
|
* 暂停
|
||||||
const mime = 'audio/mpeg'
|
*/
|
||||||
|
const pause = async () => {
|
||||||
// 4.1 创建 SourceBuffer
|
if (piper && piper.audioCtx && piper.audioCtx.state === 'running') {
|
||||||
try {
|
await piper.audioCtx.suspend()
|
||||||
sourceBuffer = mediaSource.addSourceBuffer(mime)
|
|
||||||
sourceBuffer.addEventListener('updateend', () => {
|
|
||||||
isAppending = false
|
|
||||||
processQueue()
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
console.error('SourceBuffer Create Failed:', e)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4.2 计算 WebSocket 地址
|
|
||||||
let baseUrl = config.speechSynthesis2 || ''
|
|
||||||
baseUrl = baseUrl.replace(/\/$/, '')
|
|
||||||
const wsUrl = baseUrl.replace(/^http/, 'ws') + '/ws/synthesize'
|
|
||||||
|
|
||||||
// 4.3 建立连接
|
|
||||||
ws = new WebSocket(wsUrl)
|
|
||||||
ws.binaryType = 'arraybuffer' // 关键
|
|
||||||
|
|
||||||
ws.onopen = () => {
|
|
||||||
// console.log('WS Open')
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
text: text,
|
|
||||||
speaker_id: 0,
|
|
||||||
length_scale: 1.0,
|
|
||||||
noise_scale: 0.667
|
|
||||||
}))
|
|
||||||
isLoading.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
|
||||||
if (event.data instanceof ArrayBuffer) {
|
|
||||||
bufferQueue.push(event.data)
|
|
||||||
processQueue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ws.onerror = (e) => {
|
|
||||||
console.error('WS Error:', e)
|
|
||||||
cancelAudio()
|
|
||||||
}
|
|
||||||
|
|
||||||
ws.onclose = () => {
|
|
||||||
// console.log('WS Closed')
|
|
||||||
isStreamEnded = true
|
|
||||||
// 检查是否需要结束 MSE 流
|
|
||||||
checkEndOfStream()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理缓冲队列
|
|
||||||
const processQueue = () => {
|
|
||||||
if (!sourceBuffer || sourceBuffer.updating || bufferQueue.length === 0) {
|
|
||||||
// 如果队列空了,且流已结束,尝试结束 MSE
|
|
||||||
if (bufferQueue.length === 0 && isStreamEnded && !sourceBuffer.updating) {
|
|
||||||
checkEndOfStream()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isAppending = true
|
|
||||||
const chunk = bufferQueue.shift()
|
|
||||||
|
|
||||||
try {
|
|
||||||
sourceBuffer.appendBuffer(chunk)
|
|
||||||
} catch (e) {
|
|
||||||
// console.error('AppendBuffer Error:', e)
|
|
||||||
isAppending = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 结束 MSE 流
|
|
||||||
const checkEndOfStream = () => {
|
|
||||||
if (mediaSource && mediaSource.readyState === 'open' && bufferQueue.length === 0 && !sourceBuffer
|
|
||||||
?.updating) {
|
|
||||||
try {
|
|
||||||
mediaSource.endOfStream()
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const pause = () => {
|
|
||||||
if (audio && !audio.paused) {
|
|
||||||
audio.pause()
|
|
||||||
isPaused.value = true
|
isPaused.value = true
|
||||||
isSpeaking.value = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const resume = () => {
|
/**
|
||||||
if (audio && audio.paused) {
|
* 恢复
|
||||||
audio.play()
|
*/
|
||||||
|
const resume = async () => {
|
||||||
|
if (piper && piper.audioCtx && piper.audioCtx.state === 'suspended') {
|
||||||
|
await piper.audioCtx.resume()
|
||||||
isPaused.value = false
|
isPaused.value = false
|
||||||
isSpeaking.value = true
|
isSpeaking.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === 新增/核心方法:取消并停止 ===
|
/**
|
||||||
const cancelAudio = () => {
|
* 停止并重置 (核打击模式)
|
||||||
// 1. 断开 WebSocket (停止数据接收)
|
*/
|
||||||
if (ws) {
|
const stop = async () => {
|
||||||
// 移除监听器防止报错
|
if (piper) {
|
||||||
ws.onclose = null
|
// 1. 断开 WebSocket
|
||||||
ws.onerror = null
|
piper.stop()
|
||||||
ws.onmessage = null
|
|
||||||
ws.close()
|
|
||||||
ws = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 停止音频播放
|
// 2. 【关键】关闭 AudioContext
|
||||||
if (audio) {
|
// Web Audio API 中,已经 schedule 的 buffer 很难单独取消
|
||||||
audio.pause()
|
// 最直接的方法是关闭整个 Context
|
||||||
// 释放 Blob URL 内存
|
if (piper.audioCtx && piper.audioCtx.state !== 'closed') {
|
||||||
if (audio.src) {
|
try {
|
||||||
URL.revokeObjectURL(audio.src)
|
await piper.audioCtx.close()
|
||||||
audio.removeAttribute('src')
|
} catch (e) {
|
||||||
}
|
console.warn('AudioContext close failed', e)
|
||||||
audio.currentTime = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 清理 MSE 对象
|
|
||||||
if (mediaSource) {
|
|
||||||
try {
|
|
||||||
if (mediaSource.readyState === 'open') {
|
|
||||||
mediaSource.endOfStream()
|
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
}
|
||||||
mediaSource = null
|
|
||||||
|
// 3. 销毁实例引用
|
||||||
|
piper = null
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceBuffer = null
|
|
||||||
bufferQueue = []
|
|
||||||
isAppending = false
|
|
||||||
isStreamEnded = false
|
|
||||||
|
|
||||||
// 4. 重置 UI 状态
|
|
||||||
resetState()
|
resetState()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只是重置 UI 变量的辅助函数
|
// UI 状态重置
|
||||||
const resetState = () => {
|
const resetState = () => {
|
||||||
isSpeaking.value = false
|
isSpeaking.value = false
|
||||||
isPaused.value = false
|
isPaused.value = false
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 别名 stop -> cancelAudio (保持兼容性)
|
|
||||||
const stop = cancelAudio
|
|
||||||
|
|
||||||
// === 生命周期 ===
|
// === 生命周期 ===
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initAudioElement()
|
// 预初始化可以不做,等到点击时再做,避免空闲占用 AudioContext 资源
|
||||||
|
// initPiper()
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
cancelAudio()
|
stop()
|
||||||
audio = null
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (typeof onHide === 'function') onHide(cancelAudio)
|
// Uniapp 生命周期
|
||||||
if (typeof onUnload === 'function') onUnload(cancelAudio)
|
if (typeof onHide === 'function') onHide(stop)
|
||||||
|
if (typeof onUnload === 'function') onUnload(stop)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
speak,
|
speak,
|
||||||
pause,
|
pause,
|
||||||
resume,
|
resume,
|
||||||
stop,
|
stop,
|
||||||
cancelAudio, // 新增导出
|
cancelAudio: stop,
|
||||||
isSpeaking,
|
isSpeaking,
|
||||||
isPaused,
|
isPaused,
|
||||||
isLoading
|
isLoading
|
||||||
@@ -287,7 +170,7 @@ export function useTTSPlayer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提取文本逻辑
|
* 提取文本逻辑 (保持不变)
|
||||||
*/
|
*/
|
||||||
function extractSpeechText(markdown) {
|
function extractSpeechText(markdown) {
|
||||||
if (!markdown || markdown.indexOf('job-json') === -1) {
|
if (!markdown || markdown.indexOf('job-json') === -1) {
|
||||||
|
|||||||
@@ -22,15 +22,16 @@
|
|||||||
<script>
|
<script>
|
||||||
eruda.init();
|
eruda.init();
|
||||||
</script> -->
|
</script> -->
|
||||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
<!-- <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// VConsole 默认会挂载到 `window.VConsole` 上
|
// VConsole 默认会挂载到 `window.VConsole` 上
|
||||||
var vConsole = new window.VConsole();
|
var vConsole = new window.VConsole();
|
||||||
</script>
|
</script> -->
|
||||||
<!-- 爱山东jssdk 本sdk存在性能问题 -->
|
<!-- 爱山东jssdk 本sdk存在性能问题 -->
|
||||||
<script type="text/javascript" src="https://isdapp.shandong.gov.cn/jmopen/jssdk/index.js"></script>
|
<script type="text/javascript" src="https://isdapp.shandong.gov.cn/jmopen/jssdk/index.js"></script>
|
||||||
<!-- 只在内网有效 -->
|
<!-- 只在内网有效 -->
|
||||||
<script type="text/javascript" src="./static/js/SM.js"></script>
|
<script type="text/javascript" src="./static/js/SM.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"><!--app-html--></div>
|
<div id="app"><!--app-html--></div>
|
||||||
|
|||||||
8
main.js
@@ -4,7 +4,7 @@ import {
|
|||||||
createUnistorage
|
createUnistorage
|
||||||
} from "./uni_modules/pinia-plugin-unistorage";
|
} from "./uni_modules/pinia-plugin-unistorage";
|
||||||
import globalFunction from '@/common/globalFunction'
|
import globalFunction from '@/common/globalFunction'
|
||||||
import '@/lib/string-similarity.min.js'
|
// import '@/lib/string-similarity.min.js'
|
||||||
import similarityJobs from '@/utils/similarity_Job.js';
|
import similarityJobs from '@/utils/similarity_Job.js';
|
||||||
|
|
||||||
// 组件
|
// 组件
|
||||||
@@ -24,7 +24,10 @@ import renderCompanyCollectionRecord from '@/components/renderCompanyCollectionR
|
|||||||
import renderJobViewRecord from '@/components/renderJobViewRecord/renderJobViewRecord.vue';
|
import renderJobViewRecord from '@/components/renderJobViewRecord/renderJobViewRecord.vue';
|
||||||
// import Tabbar from '@/components/tabbar/midell-box.vue'
|
// import Tabbar from '@/components/tabbar/midell-box.vue'
|
||||||
// 自动导入 directives 目录下所有指令
|
// 自动导入 directives 目录下所有指令
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
console.log(lightAppJssdk)
|
console.log(lightAppJssdk)
|
||||||
|
// #endif
|
||||||
const directives = import.meta.glob('./directives/*.js', {
|
const directives = import.meta.glob('./directives/*.js', {
|
||||||
eager: true
|
eager: true
|
||||||
});
|
});
|
||||||
@@ -33,8 +36,11 @@ import {
|
|||||||
createSSRApp,
|
createSSRApp,
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
const foldFeature = window.visualViewport && 'segments' in window.visualViewport
|
const foldFeature = window.visualViewport && 'segments' in window.visualViewport
|
||||||
console.log('是否支持多段屏幕:', foldFeature)
|
console.log('是否支持多段屏幕:', foldFeature)
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
// 全局组件
|
// 全局组件
|
||||||
export function createApp() {
|
export function createApp() {
|
||||||
|
|||||||
763
package-lock.json
generated
Normal file
@@ -0,0 +1,763 @@
|
|||||||
|
{
|
||||||
|
"name": "qingdao-employment-service",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"pixi.js": "^7.4.2",
|
||||||
|
"sm-crypto": "^0.3.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/accessibility": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-R6VEolm8uyy1FB1F2qaLKxVbzXAFTZCF2ka8fl9lsz7We6ZfO4QpXv9ur7DvzratjCQUQVCKo0/V7xL5q1EV/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/events": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/app": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/app/-/app-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-ugkH3kOgjT8P1mTMY29yCOgEh+KuVMAn8uBxeY0aMqaUgIMysfpnFv+Aepp2CtvI9ygr22NC+OiKl+u+eEaQHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/assets": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/assets/-/assets-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-anxho59H9egZwoaEdM5aLvYyxoz6NCy3CaQIvNHD1bbGg8L16Ih0e26QSBR5fu53jl8OjT6M7s+p6n7uu4+fGA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/css-font-loading-module": "^0.0.12"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/color": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/color/-/color-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-av1LOvhHsiaW8+T4n/FgnOKHby55/w7VcA1HzPIHRBtEcsmxvSCDanT1HU2LslNhrxLPzyVx18nlmalOyt5OBg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@pixi/colord": "^2.9.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/colord": {
|
||||||
|
"version": "2.9.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/colord/-/colord-2.9.6.tgz",
|
||||||
|
"integrity": "sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/compressed-textures": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-VJrt7el6O4ZJSWkeOGXwrhJaiLg1UBhHB3fj42VR4YloYkAxpfd9K6s6IcbcVz7n9L48APKBMgHyaB2pX2Ck/A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/assets": "7.4.2",
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/constants": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-N9vn6Wpz5WIQg7ugUg2+SdqD2u2+NM0QthE8YzLJ4tLH2Iz+/TrnPKUJzeyIqbg3sxJG5ZpGGPiacqIBpy1KyA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/core": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/core/-/core-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-UbMtgSEnyCOFPzbE6ThB9qopXxbZ5GCof2ArB4FXOC5Xi/83MOIIYg5kf5M8689C5HJMhg2SrJu3xLKppF+CMg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@pixi/color": "7.4.2",
|
||||||
|
"@pixi/constants": "7.4.2",
|
||||||
|
"@pixi/extensions": "7.4.2",
|
||||||
|
"@pixi/math": "7.4.2",
|
||||||
|
"@pixi/runner": "7.4.2",
|
||||||
|
"@pixi/settings": "7.4.2",
|
||||||
|
"@pixi/ticker": "7.4.2",
|
||||||
|
"@pixi/utils": "7.4.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/pixijs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/display": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/display/-/display-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-DaD0J7gIlNlzO0Fdlby/0OH+tB5LtCY6rgFeCBKVDnzmn8wKW3zYZRenWBSFJ0Psx6vLqXYkSIM/rcokaKviIw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/events": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/events/-/events-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-Jw/w57heZjzZShIXL0bxOvKB+XgGIevyezhGtfF2ZSzQoSBWo+Fj1uE0QwKd0RIaXegZw/DhSmiMJSbNmcjifA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/extensions": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-Hmx2+O0yZ8XIvgomHM9GZEGcy9S9Dd8flmtOK5Aa3fXs/8v7xD08+ANQpN9ZqWU2Xs+C6UBlpqlt2BWALvKKKA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/extract": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-JOX27TRWjVEjauGBbF8PU7/g6LYXnivehdgqS5QlVDv1CNHTOrz/j3MdKcVWOhyZPbH5c9sh7lxyRxvd9AIuTQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/filter-alpha": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-9OsKJ+yvY2wIcQXwswj5HQBiwNGymwmqdxfp7mo+nZSBoDmxUqvMZzE9UNJ3eUlswuNvNRO8zNOsQvwdz7WFww==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/filter-blur": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-gOXBbIUx6CRZP1fmsis2wLzzSsofrqmIHhbf1gIkZMIQaLsc9T7brj+PaLTTiOiyJgnvGN5j20RZnkERWWKV0Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/filter-color-matrix": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-ykZiR59Gvj80UKs9qm7jeUTKvn+wWk6HBVJOmJbK9jFK5juakDWp7BbH26U78Q61EWj97kI1FdfcbMkuQ7rqkA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/filter-displacement": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-QS/eWp/ivsxef3xapNeGwpPX7vrqQQeo99Fux4k5zsvplnNEsf91t6QYJLG776AbZEu/qh8VYRBA5raIVY/REw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/filter-fxaa": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-U/ptJgDsfs/r8y2a6gCaiPfDu2IFAxpQ4wtfmBpz6vRhqeE4kI8yNIUx5dZbui57zlsJaW0BNacOQxHU0vLkyQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/filter-noise": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-Vy9ViBFhZEGh6xKkd3kFWErolZTwv1Y5Qb1bV7qPIYbvBECYsqzlR4uCrrjBV6KKm0PufpG/+NKC5vICZaqKzg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/graphics": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-jH4/Tum2RqWzHGzvlwEr7HIVduoLO57Ze705N2zQPkUD57TInn5911aGUeoua7f/wK8cTLGzgB9BzSo2kTdcHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/math": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-7jHmCQoYk6e0rfSKjdNFOPl0wCcdgoraxgteXJTTHv3r0bMNx2pHD9FJ0VvocEUG7XHfj55O3+u7yItOAx0JaQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/mesh": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-mEkKyQvvMrYXC3pahvH5WBIKtrtB63WixRr91ANFI7zXD+ESG6Ap6XtxMCJmXDQPwBDNk7SWVMiCflYuchG7kA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/mesh-extras": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-vNR/7wjxjs7sv9fGoKkHyU91ZAD+7EnMHBS5F3CVISlOIFxLi96NNZCB81oUIdky/90pHw40johd/4izR5zTyw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/mesh": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/mixin-cache-as-bitmap": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-6dgthi2ruUT/lervSrFDQ7vXkEsHo6CxdgV7W/wNdW1dqgQlKfDvO6FhjXzyIMRLSooUf5FoeluVtfsjkUIYrw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/mixin-get-child-by-name": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-0Cfw8JpQhsixprxiYph4Lj+B5n83Kk4ftNMXgM5xtZz+tVLz5s91qR0MqcdzwTGTJ7utVygiGmS4/3EfR/duRQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/display": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/mixin-get-global-position": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-LcsahbVdX4DFS2IcGfNp4KaXuu7SjAwUp/flZSGIfstyKOKb5FWFgihtqcc9ZT4coyri3gs2JbILZub/zPZj1w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/particle-container": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-B78Qq86kt0lEa5WtB2YFIm3+PjhKfw9La9R++GBSgABl+g13s2UaZ6BIPxvY3JxWMdxPm4iPrQPFX1QWRN68mw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/prepare": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-PugyMzReCHXUzc3so9PPJj2OdHwibpUNWyqG4mWY2UUkb6c8NAGK1AnAPiscOvLilJcv/XQSFoNhX+N1jrvJEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/graphics": "7.4.2",
|
||||||
|
"@pixi/text": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/runner": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-LPBpwym4vdyyDY5ucF4INQccaGyxztERyLTY1YN6aqJyyMmnc7iqXlIKt+a0euMBtNoLoxy6MWMvIuZj0JfFPA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/settings": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-pMN+L6aWgvUbwhFIL/BTHKe2ShYGPZ8h9wlVBnFHMtUcJcFLMF1B3lzuvCayZRepOphs6RY0TqvnDvVb585JhQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@pixi/constants": "7.4.2",
|
||||||
|
"@types/css-font-loading-module": "^0.0.12",
|
||||||
|
"ismobilejs": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/sprite": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-Ccf/OVQsB+HQV0Fyf5lwD+jk1jeU7uSIqEjbxenNNssmEdB7S5qlkTBV2EJTHT83+T6Z9OMOHsreJZerydpjeg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/sprite-animated": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-QPT6yxCUGOBN+98H3pyIZ1ZO6Y7BN1o0Q2IMZEsD1rNfZJrTYS3Q8VlCG5t2YlFlcB8j5iBo24bZb6FUxLOmsQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/sprite-tiling": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-Z8PP6ewy3nuDYL+NeEdltHAhuucVgia33uzAitvH3OqqRSx6a6YRBFbNLUM9Sx+fBO2Lk3PpV1g6QZX+NE5LOg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/spritesheet": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-YIvHdpXW+AYp8vD0NkjJmrdnVHTZKidCnx6k8ATSuuvCT6O5Tuh2N/Ul2oDj4/QaePy0lVhyhAbZpJW00Jr7mQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/assets": "7.4.2",
|
||||||
|
"@pixi/core": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/text": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/text/-/text-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-rZZWpJNsIQ8WoCWrcVg8Gi6L/PDakB941clo6dO3XjoII2ucoOUcnpe5HIkudxi2xPvS/8Bfq990gFEx50TP5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/text-bitmap": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-lPBMJ83JnpFVL+6ckQ8KO8QmwdPm0z9Zs/M0NgFKH2F+BcjelRNnk80NI3O0qBDYSEDQIE+cFbKoZ213kf7zwA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/assets": "7.4.2",
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/mesh": "7.4.2",
|
||||||
|
"@pixi/text": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/text-html": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/text-html/-/text-html-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-duOu8oDYeDNuyPozj2DAsQ5VZBbRiwIXy78Gn7H2pCiEAefw/Uv5jJYwdgneKME0e1tOxz1eOUGKPcI6IJnZjw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2",
|
||||||
|
"@pixi/text": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/ticker": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-cAvxCh/KI6IW4m3tp2b+GQIf+DoSj9NNmPJmsOeEJ7LzvruG8Ps7SKI6CdjQob5WbceL1apBTDbqZ/f77hFDiQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@pixi/extensions": "7.4.2",
|
||||||
|
"@pixi/settings": "7.4.2",
|
||||||
|
"@pixi/utils": "7.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@pixi/utils": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-aU/itcyMC4TxFbmdngmak6ey4kC5c16Y5ntIYob9QnjNAfD/7GTsYIBnP6FqEAyO1eq0MjkAALxdONuay1BG3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@pixi/color": "7.4.2",
|
||||||
|
"@pixi/constants": "7.4.2",
|
||||||
|
"@pixi/settings": "7.4.2",
|
||||||
|
"@types/earcut": "^2.1.0",
|
||||||
|
"earcut": "^2.2.4",
|
||||||
|
"eventemitter3": "^4.0.0",
|
||||||
|
"url": "^0.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/css-font-loading-module": {
|
||||||
|
"version": "0.0.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz",
|
||||||
|
"integrity": "sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/earcut": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/call-bind-apply-helpers": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/call-bound": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"get-intrinsic": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dunder-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"gopd": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/earcut": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/es-define-property": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-errors": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-object-atoms": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "4.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||||
|
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.1.1",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-proto": "^1.0.1",
|
||||||
|
"gopd": "^1.2.0",
|
||||||
|
"has-symbols": "^1.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"math-intrinsics": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dunder-proto": "^1.0.1",
|
||||||
|
"es-object-atoms": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gopd": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hasown": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ismobilejs": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/jsbn": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/math-intrinsics": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-inspect": {
|
||||||
|
"version": "1.13.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
|
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pixi.js": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-TifqgHGNofO7UCEbdZJOpUu7dUnpu4YZ0o76kfCqxDa4RS8ITc9zjECCbtalmuNXkVhSEZmBKQvE7qhHMqw/xg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@pixi/accessibility": "7.4.2",
|
||||||
|
"@pixi/app": "7.4.2",
|
||||||
|
"@pixi/assets": "7.4.2",
|
||||||
|
"@pixi/compressed-textures": "7.4.2",
|
||||||
|
"@pixi/core": "7.4.2",
|
||||||
|
"@pixi/display": "7.4.2",
|
||||||
|
"@pixi/events": "7.4.2",
|
||||||
|
"@pixi/extensions": "7.4.2",
|
||||||
|
"@pixi/extract": "7.4.2",
|
||||||
|
"@pixi/filter-alpha": "7.4.2",
|
||||||
|
"@pixi/filter-blur": "7.4.2",
|
||||||
|
"@pixi/filter-color-matrix": "7.4.2",
|
||||||
|
"@pixi/filter-displacement": "7.4.2",
|
||||||
|
"@pixi/filter-fxaa": "7.4.2",
|
||||||
|
"@pixi/filter-noise": "7.4.2",
|
||||||
|
"@pixi/graphics": "7.4.2",
|
||||||
|
"@pixi/mesh": "7.4.2",
|
||||||
|
"@pixi/mesh-extras": "7.4.2",
|
||||||
|
"@pixi/mixin-cache-as-bitmap": "7.4.2",
|
||||||
|
"@pixi/mixin-get-child-by-name": "7.4.2",
|
||||||
|
"@pixi/mixin-get-global-position": "7.4.2",
|
||||||
|
"@pixi/particle-container": "7.4.2",
|
||||||
|
"@pixi/prepare": "7.4.2",
|
||||||
|
"@pixi/sprite": "7.4.2",
|
||||||
|
"@pixi/sprite-animated": "7.4.2",
|
||||||
|
"@pixi/sprite-tiling": "7.4.2",
|
||||||
|
"@pixi/spritesheet": "7.4.2",
|
||||||
|
"@pixi/text": "7.4.2",
|
||||||
|
"@pixi/text-bitmap": "7.4.2",
|
||||||
|
"@pixi/text-html": "7.4.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/pixijs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/punycode": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
||||||
|
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"object-inspect": "^1.13.3",
|
||||||
|
"side-channel-list": "^1.0.0",
|
||||||
|
"side-channel-map": "^1.0.1",
|
||||||
|
"side-channel-weakmap": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-list": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"object-inspect": "^1.13.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-map": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bound": "^1.0.2",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.5",
|
||||||
|
"object-inspect": "^1.13.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-weakmap": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bound": "^1.0.2",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.5",
|
||||||
|
"object-inspect": "^1.13.3",
|
||||||
|
"side-channel-map": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/sm-crypto": {
|
||||||
|
"version": "0.3.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/sm-crypto/-/sm-crypto-0.3.13.tgz",
|
||||||
|
"integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"jsbn": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/url": {
|
||||||
|
"version": "0.11.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
|
||||||
|
"integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": "^1.4.1",
|
||||||
|
"qs": "^6.12.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"pixi.js": "^7.4.2",
|
||||||
|
"sm-crypto": "^0.3.13"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import { storeToRefs } from 'pinia';
|
|||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const state = reactive({});
|
const state = reactive({});
|
||||||
const pageState = reactive({
|
const pageState = reactive({
|
||||||
page: 0,
|
page: 0,
|
||||||
@@ -37,6 +38,15 @@ onLoad(() => {
|
|||||||
getJobList();
|
getJobList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// #ifdef H5
|
||||||
|
if (!isMiniProgram.value) {
|
||||||
|
const a = document.getElementsByClassName('uni-page-head-hd')[0];
|
||||||
|
a.style.display = 'none';
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
});
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
getJobList();
|
getJobList();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="" :use-scroll-view="false">
|
<AppLayout title="" :use-scroll-view="false">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btnback">
|
<view class="btnback">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -75,6 +75,8 @@ import { reactive, inject, watch, ref, onMounted, computed } from 'vue';
|
|||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
import dictLabel from '@/components/dict-Label/dict-Label.vue';
|
import dictLabel from '@/components/dict-Label/dict-Label.vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
const { $api, navTo, vacanciesTo, navBack } = inject('globalFunction');
|
const { $api, navTo, vacanciesTo, navBack } = inject('globalFunction');
|
||||||
@@ -182,10 +184,13 @@ function getThirdPartyJobsList(type = 'add') {
|
|||||||
let params = {
|
let params = {
|
||||||
current: pageState.current,
|
current: pageState.current,
|
||||||
pageSize: pageState.pageSize,
|
pageSize: pageState.pageSize,
|
||||||
|
gsID:companyId,
|
||||||
|
gsmc:companyName,
|
||||||
|
zphID:zphId
|
||||||
};
|
};
|
||||||
|
|
||||||
$api.createRequest(
|
$api.createRequest(
|
||||||
`/app/internal/jobThirdPart?gsID=${companyId}&gsmc=${companyName}&zphID=${zphId}`,
|
`/app/internal/jobThirdPart`,
|
||||||
params,
|
params,
|
||||||
'GET',
|
'GET',
|
||||||
true
|
true
|
||||||
@@ -220,7 +225,8 @@ function handleJobsListResponse(type, rows, total, pageKey) {
|
|||||||
const str = pageState.pageSize * (pageState[pageKey] - 1);
|
const str = pageState.pageSize * (pageState[pageKey] - 1);
|
||||||
const end = pageState.list.length;
|
const end = pageState.list.length;
|
||||||
const reslist = rows;
|
const reslist = rows;
|
||||||
pageState.list.splice(str, end, ...reslist);
|
pageState.list = [...pageState.list, ...rows];
|
||||||
|
// pageState.list.splice(str, end, ...reslist);
|
||||||
} else {
|
} else {
|
||||||
pageState.list = rows;
|
pageState.list = rows;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="添加岗位">
|
<AppLayout title="添加岗位">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -74,7 +74,7 @@ const { $api, navBack } = inject('globalFunction');
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
const { getUserResume } = useUserStore();
|
const { getUserResume } = useUserStore();
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo, isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const popup = ref(null);
|
const popup = ref(null);
|
||||||
const selectJobsModel = ref(null);
|
const selectJobsModel = ref(null);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="我的浏览" :show-bg-image="false" :use-scroll-view="false">
|
<AppLayout title="我的浏览" :show-bg-image="false" :use-scroll-view="false">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btnback">
|
<view class="btnback">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -46,7 +46,7 @@ import { onLoad, onShow } from '@dcloudio/uni-app';
|
|||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
const { $api, navTo, navBack } = inject('globalFunction');
|
const { $api, navTo, navBack } = inject('globalFunction');
|
||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo, isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const browseDate = ref('');
|
const browseDate = ref('');
|
||||||
@@ -123,6 +123,7 @@ function getJobList(type = 'add', loading = true) {
|
|||||||
reslist.shift();
|
reslist.shift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// pageState.list = [...pageState.list, ...rows];
|
||||||
pageState.list.splice(str, end, ...reslist);
|
pageState.list.splice(str, end, ...reslist);
|
||||||
pageState.lastDate = lastDate;
|
pageState.lastDate = lastDate;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="精选企业">
|
<AppLayout title="精选企业">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -28,7 +28,7 @@ const { $api, navBack, navTo } = inject('globalFunction');
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
const { getUserResume } = useUserStore();
|
const { getUserResume } = useUserStore();
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo, isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const list = ref([]);
|
const list = ref([]);
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout :title="title" :show-bg-image="false" @onScrollBottom="getDataList('add')">
|
<AppLayout :title="title" :show-bg-image="false" @onScrollBottom="getDataList('add')">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btnback">
|
<view class="btnback">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -39,6 +39,8 @@ import { storeToRefs } from 'pinia';
|
|||||||
const { $api, navTo, navBack } = inject('globalFunction');
|
const { $api, navTo, navBack } = inject('globalFunction');
|
||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
// state
|
// state
|
||||||
const title = ref('事业单位');
|
const title = ref('事业单位');
|
||||||
const cardInfo = ref({});
|
const cardInfo = ref({});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="我的收藏" :show-bg-image="false" :use-scroll-view="false">
|
<AppLayout title="我的收藏" :show-bg-image="false" :use-scroll-view="false">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -61,6 +61,8 @@ import { storeToRefs } from 'pinia';
|
|||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
const { $api, navBack } = inject('globalFunction');
|
const { $api, navBack } = inject('globalFunction');
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const type = ref(0);
|
const type = ref(0);
|
||||||
|
|
||||||
const pageState = reactive({
|
const pageState = reactive({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="" :use-scroll-view="false">
|
<AppLayout title="" :use-scroll-view="false">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btnback">
|
<view class="btnback">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
:longitude="longitudeVal"
|
:longitude="longitudeVal"
|
||||||
:latitude="latitudeVal"
|
:latitude="latitudeVal"
|
||||||
></renderCompanysOutData>
|
></renderCompanysOutData>
|
||||||
<empty v-else is-position></empty>
|
<empty v-if="!pageState.list.length" is-position></empty>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
@@ -110,6 +110,8 @@ import useLocationStore from '@/stores/useLocationStore';
|
|||||||
const { $api, navTo, vacanciesTo, navBack } = inject('globalFunction');
|
const { $api, navTo, vacanciesTo, navBack } = inject('globalFunction');
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
|
|
||||||
const isExpanded = ref(false);
|
const isExpanded = ref(false);
|
||||||
const fairInfo = ref({});
|
const fairInfo = ref({});
|
||||||
@@ -151,9 +153,11 @@ function getCompanyList(type = 'add') {
|
|||||||
let params = {
|
let params = {
|
||||||
current: pageState.current,
|
current: pageState.current,
|
||||||
pageSize: pageState.pageSize,
|
pageSize: pageState.pageSize,
|
||||||
|
zphID:jobFairId,
|
||||||
|
zphmc:jobFairName,
|
||||||
};
|
};
|
||||||
$api.createRequest(
|
$api.createRequest(
|
||||||
`/app/internal/companyThirdPart/?zphID=${jobFairId}&zphmc=${jobFairName}`,
|
`/app/internal/companyThirdPart/`,
|
||||||
params,
|
params,
|
||||||
'GET',
|
'GET',
|
||||||
true
|
true
|
||||||
@@ -163,7 +167,8 @@ function getCompanyList(type = 'add') {
|
|||||||
const str = pageState.pageSize * (pageState.current - 1);
|
const str = pageState.pageSize * (pageState.current - 1);
|
||||||
const end = pageState.list.length;
|
const end = pageState.list.length;
|
||||||
const reslist = rows;
|
const reslist = rows;
|
||||||
pageState.list.splice(str, end, ...reslist);
|
pageState.list = [...pageState.list, ...rows];
|
||||||
|
// pageState.list.splice(str, end, ...reslist);
|
||||||
} else {
|
} else {
|
||||||
pageState.list = rows;
|
pageState.list = rows;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="我的简历" title-color="#FFFFFF" back-gorund-color="#F4F4F4">
|
<AppLayout title="我的简历" title-color="#FFFFFF" back-gorund-color="#F4F4F4">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<image src="@/static/icon/back-white.png" @click="navBack"></image>
|
<image src="@/static/icon/back-white.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="subName">
|
<view class="subName">
|
||||||
<dict-Label class="mar_ri10" dictType="sex" :value="userInfo.sex"></dict-Label>
|
<dict-Label class="mar_ri10" dictType="sex" :value="userInfo.sex"></dict-Label>
|
||||||
<text class="mar_ri10">{{ userInfo.age }}岁</text>
|
<text class="mar_ri10">{{ userInfo.age || '-' }}岁</text>
|
||||||
<dict-Label class="mar_ri10" dictType="education" :value="userInfo.education"></dict-Label>
|
<dict-Label class="mar_ri10" dictType="education" :value="userInfo.education"></dict-Label>
|
||||||
<dict-Label
|
<dict-Label
|
||||||
class="mar_ri10"
|
class="mar_ri10"
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
:value="userInfo.politicalAffiliation"
|
:value="userInfo.politicalAffiliation"
|
||||||
></dict-Label>
|
></dict-Label>
|
||||||
</view>
|
</view>
|
||||||
<view class="subName">{{ userInfo.phone }}</view>
|
<view class="subName">{{ userInfo.phone || '未知手机号' }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tops-right">
|
<view class="tops-right">
|
||||||
<view class="right-imghead">
|
<view class="right-imghead">
|
||||||
@@ -137,7 +137,7 @@ import { onLoad, onShow } from '@dcloudio/uni-app';
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
import useDictStore from '@/stores/useDictStore';
|
import useDictStore from '@/stores/useDictStore';
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo, isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const { getUserResume } = useUserStore();
|
const { getUserResume } = useUserStore();
|
||||||
const { getDictData, oneDictData } = useDictStore();
|
const { getDictData, oneDictData } = useDictStore();
|
||||||
import config from '@/config.js';
|
import config from '@/config.js';
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ const { $api, navTo, debounce, customSystem } = inject('globalFunction');
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo, isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
|
|
||||||
const pageState = reactive({
|
const pageState = reactive({
|
||||||
@@ -58,6 +58,15 @@ const state = reactive({
|
|||||||
tabIndex: 'all',
|
tabIndex: 'all',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// #ifdef H5
|
||||||
|
if (!isMiniProgram.value) {
|
||||||
|
const a = document.getElementsByClassName('uni-page-head-hd')[0];
|
||||||
|
a.style.display = 'none';
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
});
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
getList('refresh');
|
getList('refresh');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,267 +1,295 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="个人信息" :sub-title="`完成度${percent}`" border back-gorund-color="#ffffff" :show-bg-image="false">
|
<AppLayout
|
||||||
<template #headerleft>
|
title="个人信息"
|
||||||
<view class="btn mar_le20 button-click" @click="navBack">取消</view>
|
:sub-title="`完成度${percent}`"
|
||||||
</template>
|
border
|
||||||
<template #headerright>
|
back-gorund-color="#ffffff"
|
||||||
<view class="btn mar_ri20 button-click" @click="confirm">确认</view>
|
:show-bg-image="false"
|
||||||
</template>
|
>
|
||||||
<view class="content">
|
<template #headerleft>
|
||||||
<view class="content-avatar">
|
<view class="btn mar_le20 button-click" @click="navBack">取消</view>
|
||||||
<view class="avatar-title">编辑头像</view>
|
</template>
|
||||||
<view @click="selectAvatar">
|
<template #headerright>
|
||||||
<image class="avatar" v-if="fromValue.avatar" :src="fromValue.avatar" />
|
<view class="btn mar_ri20 button-click" @click="confirm">确认</view>
|
||||||
<image class="avatar" v-else-if="fromValue.sex == '0'" src="@/static/icon/boy.png" />
|
</template>
|
||||||
<image class="avatar" v-else="fromValue.sex == '1'" src="@/static/icon/girl.png" />
|
<view class="content">
|
||||||
|
<view class="content-avatar">
|
||||||
|
<view class="avatar-title">编辑头像</view>
|
||||||
|
<view @click="selectAvatar">
|
||||||
|
<image class="avatar" v-if="fromValue.avatar" :src="fromValue.avatar" />
|
||||||
|
<image class="avatar" v-else-if="fromValue.sex == '0'" src="@/static/icon/boy.png" />
|
||||||
|
<image class="avatar" v-else="fromValue.sex == '1'" src="@/static/icon/girl.png" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-input">
|
||||||
|
<view class="input-titile">姓名</view>
|
||||||
|
<input class="input-con" v-model="fromValue.name" placeholder="请输入您的姓名" />
|
||||||
|
</view>
|
||||||
|
<view class="content-sex">
|
||||||
|
<view class="sex-titile">性别</view>
|
||||||
|
<view class="sext-ri">
|
||||||
|
<view class="sext-box" :class="{ 'sext-boxactive': fromValue.sex === 0 }" @click="changeSex(0)">
|
||||||
|
男
|
||||||
|
</view>
|
||||||
|
<view class="sext-box" :class="{ 'sext-boxactive': fromValue.sex === 1 }" @click="changeSex(1)">
|
||||||
|
女
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-input" @click="changeDateBirt">
|
||||||
|
<view class="input-titile">出生年月</view>
|
||||||
|
<input
|
||||||
|
class="input-con triangle pointEveNone"
|
||||||
|
v-model="fromValue.birthDate"
|
||||||
|
disabled
|
||||||
|
placeholder="请选择您的出生年月"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="content-input" @click="changeEducation">
|
||||||
|
<view class="input-titile">学历</view>
|
||||||
|
<input
|
||||||
|
class="input-con triangle pointEveNone"
|
||||||
|
v-model="state.educationText"
|
||||||
|
disabled
|
||||||
|
placeholder="请选择您的学历"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="content-input" @click="changePoliticalAffiliation">
|
||||||
|
<view class="input-titile">政治面貌</view>
|
||||||
|
<input
|
||||||
|
class="input-con triangle pointEveNone"
|
||||||
|
v-model="state.politicalAffiliationText"
|
||||||
|
disabled
|
||||||
|
placeholder="请选择您的政治面貌"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="content-input">
|
||||||
|
<view class="input-titile">手机号码</view>
|
||||||
|
<input class="input-con" v-model="fromValue.phone" placeholder="请输入您的手机号码" />
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</AppLayout>
|
||||||
<view class="content-input">
|
|
||||||
<view class="input-titile">姓名</view>
|
|
||||||
<input class="input-con" v-model="fromValue.name" placeholder="请输入您的姓名" />
|
|
||||||
</view>
|
|
||||||
<view class="content-sex">
|
|
||||||
<view class="sex-titile">性别</view>
|
|
||||||
<view class="sext-ri">
|
|
||||||
<view class="sext-box" :class="{ 'sext-boxactive': fromValue.sex === 0 }" @click="changeSex(0)"> 男 </view>
|
|
||||||
<view class="sext-box" :class="{ 'sext-boxactive': fromValue.sex === 1 }" @click="changeSex(1)"> 女 </view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="content-input" @click="changeDateBirt">
|
|
||||||
<view class="input-titile">出生年月</view>
|
|
||||||
<input class="input-con triangle" v-model="fromValue.birthDate" disabled placeholder="请选择您的出生年月" />
|
|
||||||
</view>
|
|
||||||
<view class="content-input" @click="changeEducation">
|
|
||||||
<view class="input-titile">学历</view>
|
|
||||||
<input class="input-con triangle" v-model="state.educationText" disabled placeholder="请选择您的学历" />
|
|
||||||
</view>
|
|
||||||
<view class="content-input" @click="changePoliticalAffiliation">
|
|
||||||
<view class="input-titile">政治面貌</view>
|
|
||||||
<input class="input-con triangle" v-model="state.politicalAffiliationText" disabled placeholder="请选择您的政治面貌" />
|
|
||||||
</view>
|
|
||||||
<view class="content-input">
|
|
||||||
<view class="input-titile">手机号码</view>
|
|
||||||
<input class="input-con" v-model="fromValue.phone" placeholder="请输入您的手机号码" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</AppLayout>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, inject, watch, ref, onMounted } from "vue";
|
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
||||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
const { $api, navTo, navBack, checkingPhoneRegExp } = inject("globalFunction");
|
const { $api, navTo, navBack, checkingPhoneRegExp } = inject('globalFunction');
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from 'pinia';
|
||||||
import useUserStore from "@/stores/useUserStore";
|
import useUserStore from '@/stores/useUserStore';
|
||||||
import useDictStore from "@/stores/useDictStore";
|
import useDictStore from '@/stores/useDictStore';
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo } = storeToRefs(useUserStore());
|
||||||
const { getUserResume } = useUserStore();
|
const { getUserResume } = useUserStore();
|
||||||
const { dictLabel, oneDictData } = useDictStore();
|
const { dictLabel, oneDictData } = useDictStore();
|
||||||
const openSelectPopup = inject("openSelectPopup");
|
const openSelectPopup = inject('openSelectPopup');
|
||||||
|
|
||||||
const percent = ref("0%");
|
const percent = ref('0%');
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
educationText: "",
|
educationText: '',
|
||||||
politicalAffiliationText: "",
|
politicalAffiliationText: '',
|
||||||
});
|
});
|
||||||
const fromValue = reactive({
|
const fromValue = reactive({
|
||||||
name: "",
|
name: '',
|
||||||
sex: 0,
|
sex: 0,
|
||||||
birthDate: "",
|
birthDate: '',
|
||||||
education: "",
|
education: '',
|
||||||
politicalAffiliation: "",
|
politicalAffiliation: '',
|
||||||
avatar: "",
|
avatar: '',
|
||||||
});
|
});
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
initLoad();
|
initLoad();
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// const { age, birthDate } = useUserStore().userInfo;
|
// const { age, birthDate } = useUserStore().userInfo;
|
||||||
// const newAge = calculateAge(birthDate);
|
// const newAge = calculateAge(birthDate);
|
||||||
// // 计算年龄是否对等
|
// // 计算年龄是否对等
|
||||||
// if (age != newAge) {
|
// if (age != newAge) {
|
||||||
// completeResume();
|
// completeResume();
|
||||||
// }
|
// }
|
||||||
// }, 1000);
|
// }, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
function initLoad() {
|
function initLoad() {
|
||||||
fromValue.name = userInfo.value.name;
|
fromValue.name = userInfo.value.name;
|
||||||
fromValue.sex = Number(userInfo.value.sex);
|
fromValue.sex = Number(userInfo.value.sex);
|
||||||
fromValue.phone = userInfo.value.phone;
|
fromValue.phone = userInfo.value.phone;
|
||||||
fromValue.birthDate = userInfo.value.birthDate;
|
fromValue.birthDate = userInfo.value.birthDate;
|
||||||
fromValue.education = userInfo.value.education;
|
fromValue.education = userInfo.value.education;
|
||||||
fromValue.politicalAffiliation = userInfo.value.politicalAffiliation;
|
fromValue.politicalAffiliation = userInfo.value.politicalAffiliation;
|
||||||
fromValue.avatar = userInfo.value.avatar;
|
fromValue.avatar = userInfo.value.avatar;
|
||||||
// 回显
|
// 回显
|
||||||
state.educationText = dictLabel("education", userInfo.value.education);
|
state.educationText = dictLabel('education', userInfo.value.education);
|
||||||
state.politicalAffiliationText = dictLabel("affiliation", userInfo.value.politicalAffiliation);
|
state.politicalAffiliationText = dictLabel('affiliation', userInfo.value.politicalAffiliation);
|
||||||
const result = getFormCompletionPercent(fromValue);
|
const result = getFormCompletionPercent(fromValue);
|
||||||
percent.value = result;
|
percent.value = result;
|
||||||
}
|
}
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
if (!fromValue.name) {
|
if (!fromValue.name) {
|
||||||
return $api.msg("请输入姓名");
|
return $api.msg('请输入姓名');
|
||||||
}
|
}
|
||||||
if (!fromValue.birthDate) {
|
if (!fromValue.birthDate) {
|
||||||
return $api.msg("请选择出生年月");
|
return $api.msg('请选择出生年月');
|
||||||
}
|
}
|
||||||
if (!fromValue.education) {
|
if (!fromValue.education) {
|
||||||
return $api.msg("请选择学历");
|
return $api.msg('请选择学历');
|
||||||
}
|
}
|
||||||
if (!fromValue.politicalAffiliation) {
|
if (!fromValue.politicalAffiliation) {
|
||||||
return $api.msg("请选择政治面貌");
|
return $api.msg('请选择政治面貌');
|
||||||
}
|
}
|
||||||
// if (!checkingPhoneRegExp(fromValue.phone)) {
|
// if (!checkingPhoneRegExp(fromValue.phone)) {
|
||||||
// return $api.msg('请输入正确手机号');
|
// return $api.msg('请输入正确手机号');
|
||||||
// }
|
// }
|
||||||
const params = {
|
const params = {
|
||||||
...fromValue,
|
...fromValue,
|
||||||
age: calculateAge(fromValue.birthDate),
|
age: calculateAge(fromValue.birthDate),
|
||||||
};
|
};
|
||||||
$api.createRequest("/app/user/resume", params, "post").then((resData) => {
|
$api.createRequest('/app/user/resume', params, 'post').then((resData) => {
|
||||||
$api.msg("完成");
|
$api.msg('完成');
|
||||||
state.disbleDate = true;
|
state.disbleDate = true;
|
||||||
getUserResume().then(() => {
|
getUserResume().then(() => {
|
||||||
navBack();
|
navBack();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeDateBirt = () => {
|
const changeDateBirt = () => {
|
||||||
const datearray = generateDatePickerArrays();
|
const datearray = generateDatePickerArrays();
|
||||||
const defaultIndex = getDatePickerIndexes(fromValue.birthDate);
|
let defaultIndex = [0, 0, 0];
|
||||||
openSelectPopup({
|
if (fromValue.birthDate) {
|
||||||
title: "年龄段",
|
const defaultIndex = getDatePickerIndexes(fromValue.birthDate);
|
||||||
maskClick: true,
|
}
|
||||||
data: datearray,
|
console.log(defaultIndex);
|
||||||
defaultIndex,
|
openSelectPopup({
|
||||||
success: (_, value) => {
|
title: '年龄段',
|
||||||
const [year, month, day] = value;
|
maskClick: true,
|
||||||
const dateStr = `${year.value}-${month.value}-${day.value}`;
|
data: datearray,
|
||||||
if (isValidDate(dateStr)) {
|
defaultIndex,
|
||||||
fromValue.birthDate = dateStr;
|
success: (_, value) => {
|
||||||
} else {
|
const [year, month, day] = value;
|
||||||
$api.msg("没有这一天");
|
const dateStr = `${year.value}-${month.value}-${day.value}`;
|
||||||
}
|
if (isValidDate(dateStr)) {
|
||||||
},
|
fromValue.birthDate = dateStr;
|
||||||
});
|
} else {
|
||||||
|
$api.msg('没有这一天');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
const changeEducation = () => {
|
const changeEducation = () => {
|
||||||
openSelectPopup({
|
openSelectPopup({
|
||||||
title: "学历",
|
title: '学历',
|
||||||
maskClick: true,
|
maskClick: true,
|
||||||
data: [oneDictData("education")],
|
data: [oneDictData('education')],
|
||||||
success: (_, [value]) => {
|
success: (_, [value]) => {
|
||||||
fromValue.education = value.value;
|
fromValue.education = value.value;
|
||||||
state.educationText = value.label;
|
state.educationText = value.label;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const changeSex = (sex) => {
|
const changeSex = (sex) => {
|
||||||
fromValue.sex = sex;
|
fromValue.sex = sex;
|
||||||
};
|
};
|
||||||
|
|
||||||
const changePoliticalAffiliation = () => {
|
const changePoliticalAffiliation = () => {
|
||||||
openSelectPopup({
|
openSelectPopup({
|
||||||
title: "政治面貌",
|
title: '政治面貌',
|
||||||
maskClick: true,
|
maskClick: true,
|
||||||
data: [oneDictData("affiliation")],
|
data: [oneDictData('affiliation')],
|
||||||
success: (_, [value]) => {
|
success: (_, [value]) => {
|
||||||
fromValue.politicalAffiliation = value.value;
|
fromValue.politicalAffiliation = value.value;
|
||||||
state.politicalAffiliationText = value.label;
|
state.politicalAffiliationText = value.label;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateDatePickerArrays(startYear = 1975, endYear = new Date().getFullYear()) {
|
function generateDatePickerArrays(startYear = 1975, endYear = new Date().getFullYear()) {
|
||||||
const years = [];
|
const years = [];
|
||||||
const months = [];
|
const months = [];
|
||||||
const days = [];
|
const days = [];
|
||||||
|
|
||||||
for (let y = startYear; y <= endYear; y++) {
|
for (let y = startYear; y <= endYear; y++) {
|
||||||
years.push(y.toString());
|
years.push(y.toString());
|
||||||
}
|
}
|
||||||
for (let m = 1; m <= 12; m++) {
|
for (let m = 1; m <= 12; m++) {
|
||||||
months.push(m.toString().padStart(2, "0"));
|
months.push(m.toString().padStart(2, '0'));
|
||||||
}
|
}
|
||||||
for (let d = 1; d <= 31; d++) {
|
for (let d = 1; d <= 31; d++) {
|
||||||
days.push(d.toString().padStart(2, "0"));
|
days.push(d.toString().padStart(2, '0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return [years, months, days];
|
return [years, months, days];
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidDate(dateString) {
|
function isValidDate(dateString) {
|
||||||
const [year, month, day] = dateString.split("-").map(Number);
|
const [year, month, day] = dateString.split('-').map(Number);
|
||||||
|
|
||||||
const date = new Date(year, month - 1, day); // 月份从0开始
|
const date = new Date(year, month - 1, day); // 月份从0开始
|
||||||
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
|
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateAge = (birthDate) => {
|
const calculateAge = (birthDate) => {
|
||||||
const birth = new Date(birthDate);
|
const birth = new Date(birthDate);
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
let age = today.getFullYear() - birth.getFullYear();
|
let age = today.getFullYear() - birth.getFullYear();
|
||||||
const monthDiff = today.getMonth() - birth.getMonth();
|
const monthDiff = today.getMonth() - birth.getMonth();
|
||||||
const dayDiff = today.getDate() - birth.getDate();
|
const dayDiff = today.getDate() - birth.getDate();
|
||||||
|
|
||||||
// 如果生日的月份还没到,或者刚到生日月份但当天还没过,则年龄减 1
|
// 如果生日的月份还没到,或者刚到生日月份但当天还没过,则年龄减 1
|
||||||
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
|
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
|
||||||
age--;
|
age--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return age;
|
return age;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getFormCompletionPercent(form) {
|
function getFormCompletionPercent(form) {
|
||||||
let total = Object.keys(form).length;
|
let total = Object.keys(form).length;
|
||||||
let filled = 0;
|
let filled = 0;
|
||||||
|
|
||||||
for (const key in form) {
|
for (const key in form) {
|
||||||
const value = form[key];
|
const value = form[key];
|
||||||
if (value !== "" && value !== null && value !== undefined) {
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
if (typeof value === "number") {
|
if (typeof value === 'number') {
|
||||||
filled += 1;
|
filled += 1;
|
||||||
} else if (typeof value === "string" && value.trim() !== "") {
|
} else if (typeof value === 'string' && value.trim() !== '') {
|
||||||
filled += 1;
|
filled += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (total === 0) return "0%";
|
if (total === 0) return '0%';
|
||||||
const percent = (filled / total) * 100;
|
const percent = (filled / total) * 100;
|
||||||
return percent.toFixed(0) + "%"; // 取整,不要小数点
|
return percent.toFixed(0) + '%'; // 取整,不要小数点
|
||||||
}
|
}
|
||||||
// 主函数
|
// 主函数
|
||||||
function getDatePickerIndexes(dateStr) {
|
function getDatePickerIndexes(dateStr) {
|
||||||
const [year, month, day] = dateStr.split("-");
|
const [year, month, day] = dateStr.split('-');
|
||||||
|
|
||||||
const [years, months, days] = generateDatePickerArrays();
|
const [years, months, days] = generateDatePickerArrays();
|
||||||
|
|
||||||
const yearIndex = years.indexOf(year);
|
const yearIndex = years.indexOf(year);
|
||||||
const monthIndex = months.indexOf(month);
|
const monthIndex = months.indexOf(month);
|
||||||
const dayIndex = days.indexOf(day);
|
const dayIndex = days.indexOf(day);
|
||||||
|
|
||||||
return [yearIndex, monthIndex, dayIndex];
|
return [yearIndex, monthIndex, dayIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectAvatar() {
|
function selectAvatar() {
|
||||||
uni.chooseImage({
|
uni.chooseImage({
|
||||||
sizeType: ["original", "compressed"],
|
sizeType: ['original', 'compressed'],
|
||||||
sourceType: ["album", "camera"],
|
sourceType: ['album', 'camera'],
|
||||||
count: 1,
|
count: 1,
|
||||||
success: ({ tempFilePaths, tempFiles }) => {
|
success: ({ tempFilePaths, tempFiles }) => {
|
||||||
$api
|
$api.uploadFile(tempFilePaths[0], true)
|
||||||
.uploadFile(tempFilePaths[0], true)
|
.then((res) => {
|
||||||
.then((res) => {
|
res = JSON.parse(res);
|
||||||
res = JSON.parse(res);
|
if (res.msg) fromValue.avatar = res.msg;
|
||||||
if (res.msg) fromValue.avatar = res.msg;
|
})
|
||||||
})
|
.catch((err) => {
|
||||||
.catch((err) => {
|
$api.msg('上传失败');
|
||||||
$api.msg("上传失败");
|
});
|
||||||
});
|
},
|
||||||
},
|
fail: (error) => {},
|
||||||
fail: (error) => {},
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="" backGorundColor="#F4F4F4">
|
<AppLayout title="" backGorundColor="#F4F4F4">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btnback">
|
<view class="btnback">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -183,6 +183,9 @@ import { reactive, inject, watch, ref, onMounted, computed } from 'vue';
|
|||||||
import { onLoad, onShow, onHide } from '@dcloudio/uni-app';
|
import { onLoad, onShow, onHide } from '@dcloudio/uni-app';
|
||||||
import dictLabel from '@/components/dict-Label/dict-Label.vue';
|
import dictLabel from '@/components/dict-Label/dict-Label.vue';
|
||||||
import RadarMap from './component/radarMap.vue';
|
import RadarMap from './component/radarMap.vue';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
|
|
||||||
const { $api, navTo, getLenPx, parseQueryParams, navBack, isEmptyObject } = inject('globalFunction');
|
const { $api, navTo, getLenPx, parseQueryParams, navBack, isEmptyObject } = inject('globalFunction');
|
||||||
import config from '@/config.js';
|
import config from '@/config.js';
|
||||||
@@ -282,7 +285,12 @@ function getCompanyIsAJobs(...args) {
|
|||||||
if (dataType.value === 2) {
|
if (dataType.value === 2) {
|
||||||
// 第三方数据获取公司职位数量
|
// 第三方数据获取公司职位数量
|
||||||
const [gsID, gsmc, zphID] = args;
|
const [gsID, gsmc, zphID] = args;
|
||||||
$api.createRequest(`/app/internal/jobThirdPart?gsID=${gsID}&gsmc=${gsmc}&zphID=${zphID}`).then((resData) => {
|
const params = {
|
||||||
|
gsID:gsID,
|
||||||
|
gsmc:gsmc,
|
||||||
|
zphID:zphID
|
||||||
|
}
|
||||||
|
$api.createRequest(`/app/internal/jobThirdPart`,params).then((resData) => {
|
||||||
companyCount.value = resData.total;
|
companyCount.value = resData.total;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import Countdown from './component/countdown.vue';
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo, isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
|
|
||||||
const pageState = reactive({
|
const pageState = reactive({
|
||||||
@@ -92,6 +92,15 @@ onLoad(() => {
|
|||||||
getList();
|
getList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// #ifdef H5
|
||||||
|
if (!isMiniProgram.value) {
|
||||||
|
const a = document.getElementsByClassName('uni-page-head-hd')[0];
|
||||||
|
a.style.display = 'none';
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
});
|
||||||
|
|
||||||
function chnageRanOption(item) {
|
function chnageRanOption(item) {
|
||||||
ranItem.value = item;
|
ranItem.value = item;
|
||||||
getList();
|
getList();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="选择日期" :use-scroll-view="false" back-gorund-color="#FAFAFA">
|
<AppLayout title="选择日期" :use-scroll-view="false" back-gorund-color="#FAFAFA">
|
||||||
<template #headerleft>
|
<template #headerleft>
|
||||||
<view class="btn">
|
<view class="btn" v-if="isMiniProgram">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<view
|
<view
|
||||||
class="item button-click"
|
class="item button-click"
|
||||||
:class="{
|
:class="{
|
||||||
optional: item.isThisMonth && hasZphInData(item),
|
optional: (item.isThisMonth && hasZphInData(item)) || hasViewRecordInData(item),
|
||||||
noOptional: !item.isThisMonth,
|
noOptional: !item.isThisMonth,
|
||||||
active: current.date === item.date && item.isThisMonth,
|
active: current.date === item.date && item.isThisMonth,
|
||||||
}"
|
}"
|
||||||
@@ -51,6 +51,9 @@ const { $api, navTo, navBack } = inject('globalFunction');
|
|||||||
const weekMap = ['日', '一', '二', '三', '四', '五', '六'];
|
const weekMap = ['日', '一', '二', '三', '四', '五', '六'];
|
||||||
const calendarData = ref([]);
|
const calendarData = ref([]);
|
||||||
const current = ref({});
|
const current = ref({});
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
import { Solar, Lunar } from '@/lib/lunar-javascript@1.7.2.js';
|
import { Solar, Lunar } from '@/lib/lunar-javascript@1.7.2.js';
|
||||||
|
|
||||||
const isRecord = ref(false);
|
const isRecord = ref(false);
|
||||||
@@ -59,7 +62,7 @@ const pages = reactive({
|
|||||||
year: 0,
|
year: 0,
|
||||||
month: 0,
|
month: 0,
|
||||||
});
|
});
|
||||||
|
const hasViewRecordDateArray = ref([]);
|
||||||
const hasZphDateArray = ref([]);
|
const hasZphDateArray = ref([]);
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
@@ -74,6 +77,7 @@ onLoad((options) => {
|
|||||||
new Array(recordNum.value + 1).fill(null).map(() => {
|
new Array(recordNum.value + 1).fill(null).map(() => {
|
||||||
addMonth();
|
addMonth();
|
||||||
});
|
});
|
||||||
|
updateViewRecordDateArray()
|
||||||
} else {
|
} else {
|
||||||
initPagesDate();
|
initPagesDate();
|
||||||
new Array(recordNum.value).fill(null).map(() => {
|
new Array(recordNum.value).fill(null).map(() => {
|
||||||
@@ -81,7 +85,7 @@ onLoad((options) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (options.entrance === 'careerfair') {
|
if (options.entrance === 'careerfair') {
|
||||||
updateDateArray();
|
updateCareerFairDateArray();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -90,6 +94,17 @@ function hasZphInData(item) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dateArray = Array.isArray(hasViewRecordDateArray.value) ? hasViewRecordDateArray.value : [];
|
||||||
|
|
||||||
|
return dateArray.some((date) => {
|
||||||
|
return typeof date === 'string' && date === item.date;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function hasViewRecordInData(item) {
|
||||||
|
if (!item || typeof item.date !== 'string') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const dateArray = Array.isArray(hasZphDateArray.value) ? hasZphDateArray.value : [];
|
const dateArray = Array.isArray(hasZphDateArray.value) ? hasZphDateArray.value : [];
|
||||||
|
|
||||||
return dateArray.some((date) => {
|
return dateArray.some((date) => {
|
||||||
@@ -97,7 +112,7 @@ function hasZphInData(item) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateDateArray() {
|
async function updateCareerFairDateArray() {
|
||||||
const LoadCache = (resData) => {
|
const LoadCache = (resData) => {
|
||||||
if (resData.code === 200) {
|
if (resData.code === 200) {
|
||||||
hasZphDateArray.value = resData.data;
|
hasZphDateArray.value = resData.data;
|
||||||
@@ -105,6 +120,14 @@ async function updateDateArray() {
|
|||||||
};
|
};
|
||||||
$api.createRequestWithCache('/app/internal/getDateList', {}, 'GET', false, {}, LoadCache).then(LoadCache);
|
$api.createRequestWithCache('/app/internal/getDateList', {}, 'GET', false, {}, LoadCache).then(LoadCache);
|
||||||
}
|
}
|
||||||
|
async function updateViewRecordDateArray() {
|
||||||
|
const LoadCache = (resData) => {
|
||||||
|
if (resData.code === 200) {
|
||||||
|
hasViewRecordDateArray.value = resData.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$api.createRequestWithCache('/app/user/getJobReviewDate', {}, 'GET', false, {}, LoadCache).then(LoadCache);
|
||||||
|
}
|
||||||
|
|
||||||
function backParams() {
|
function backParams() {
|
||||||
if (isValidDateString(current.value.date)) {
|
if (isValidDateString(current.value.date)) {
|
||||||
@@ -305,6 +328,7 @@ function getMonthCalendarData({ year, month, selectableDates = [] }) {
|
|||||||
justify-content: center
|
justify-content: center
|
||||||
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
||||||
padding: 16rpx 0
|
padding: 16rpx 0
|
||||||
|
margin: 0 2rpx;
|
||||||
margin-bottom: 20rpx
|
margin-bottom: 20rpx
|
||||||
.item-top{
|
.item-top{
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="video-container">
|
<div class="video-container">
|
||||||
<view class="back-box">
|
<view class="back-box" v-if="isMiniProgram">
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<uni-icons type="left" size="26" color="#FFFFFF" @click="navBack"></uni-icons>
|
<uni-icons type="left" size="26" color="#FFFFFF" @click="navBack"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
@@ -31,6 +31,8 @@ import mTikTok from '@/components/TikTok/TikTok.vue';
|
|||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js';
|
||||||
const recommedIndexDb = useRecommedIndexedDBStore();
|
const recommedIndexDb = useRecommedIndexedDBStore();
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
videoList: [],
|
videoList: [],
|
||||||
});
|
});
|
||||||
@@ -95,7 +97,7 @@ const change = (e) => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 24rpx;
|
left: 24rpx;
|
||||||
right: 24rpx;
|
right: 24rpx;
|
||||||
bottom: 30rpx;
|
bottom: calc( var(--window-bottom));
|
||||||
color: #fff;
|
color: #fff;
|
||||||
.title{
|
.title{
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|||||||
@@ -1,266 +1,278 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="电子名片" title-color="#FFFFFF" back-gorund-color="#F4F4F4">
|
<AppLayout title="电子名片" title-color="#FFFFFF" back-gorund-color="#F4F4F4">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<image src="@/static/icon/back-white.png" @click="navBack"></image>
|
<image src="@/static/icon/back-white.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<view class="mys-container">
|
<view class="mys-container">
|
||||||
<!-- 个人信息 -->
|
<!-- 个人信息 -->
|
||||||
<view class="card-top btn-feel">
|
<view class="card-top btn-feel">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view class="avatar">
|
<view class="avatar">
|
||||||
<image v-if="userInfo.avatar" :src="userInfo.avatar"></image>
|
<image v-if="userInfo.avatar" :src="userInfo.avatar"></image>
|
||||||
<image v-else-if="userInfo.sex == '0'" src="@/static/icon/boy.png"></image>
|
<image v-else-if="userInfo.sex == '0'" src="@/static/icon/boy.png"></image>
|
||||||
<image v-else src="@/static/icon/girl.png"></image>
|
<image v-else src="@/static/icon/girl.png"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-right">
|
<view class="info-right">
|
||||||
<view class="name">{{ userInfo.name || "编辑用户名" }}</view>
|
<view class="name">{{ userInfo.name || '编辑用户名' }}</view>
|
||||||
<view class="des">
|
<view class="des">
|
||||||
<dict-Label class="mar_ri10" dictType="sex" :value="userInfo.sex"></dict-Label>
|
<dict-Label class="mar_ri10" dictType="sex" :value="userInfo.sex"></dict-Label>
|
||||||
<text class="mar_ri10">|</text>
|
<text class="mar_ri10">|</text>
|
||||||
<text class="mar_ri10">{{ userInfo.age }}岁</text>
|
<text class="mar_ri10">{{ userInfo.age || '-' }}岁</text>
|
||||||
<text class="mar_ri10">|</text>
|
<text class="mar_ri10">|</text>
|
||||||
<dict-Label class="mar_ri10" dictType="education" :value="userInfo.education"></dict-Label>
|
<dict-Label class="mar_ri10" dictType="education" :value="userInfo.education"></dict-Label>
|
||||||
<!-- <text class="mar_ri10">|</text>
|
<!-- <text class="mar_ri10">|</text>
|
||||||
<dict-Label class="mar_ri10" dictType="affiliation" :value="userInfo.politicalAffiliation"></dict-Label> -->
|
<dict-Label class="mar_ri10" dictType="affiliation" :value="userInfo.politicalAffiliation"></dict-Label> -->
|
||||||
</view>
|
</view>
|
||||||
<view class="phone">
|
<view class="phone">
|
||||||
<image class="call-icon" src="@/static/icon/call.png" />
|
<image class="call-icon" src="@/static/icon/call.png" />
|
||||||
<view>{{ userInfo.phone }}</view>
|
<view>{{ userInfo.phone || '未知手机号' }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-bottom">
|
<view class="info-bottom">
|
||||||
<!-- <view>到岗:2025-11-02</view> -->
|
<!-- <view>到岗:2025-11-02</view> -->
|
||||||
<view></view>
|
<view></view>
|
||||||
<view>地点:青岛市-<dict-Label dictType="area" :value="Number(userInfo.area)"></dict-Label></view>
|
<view>
|
||||||
</view>
|
地点:青岛市-
|
||||||
<view class="des-card" style="margin-top: 24rpx">
|
<dict-Label dictType="area" :value="Number(userInfo.area)"></dict-Label>
|
||||||
<view class="fl_box fl_justbet">
|
</view>
|
||||||
<view style="white-space:nowrap">求职意向岗位</view>
|
</view>
|
||||||
<view class="line_1" style="padding-left:40rpx" >{{ userInfo.jobIntention || userInfo.jobTitle?.join(',') || '-' }}</view>
|
<view class="des-card" style="margin-top: 24rpx">
|
||||||
</view>
|
<view class="fl_box fl_justbet">
|
||||||
<view class="fl_box fl_justbet">
|
<view style="white-space: nowrap">求职意向岗位</view>
|
||||||
<view>毕业学校</view>
|
<view class="line_1" style="padding-left: 40rpx">
|
||||||
<view>{{ userInfo.graduationSchool || "-" }}</view>
|
{{ userInfo.jobIntention || userInfo.jobTitle?.join(',') || '--' }}
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="fl_box fl_justbet">
|
</view>
|
||||||
|
<view class="fl_box fl_justbet">
|
||||||
|
<view>毕业学校</view>
|
||||||
|
<view>{{ userInfo.graduationSchool || '--' }}</view>
|
||||||
|
</view>
|
||||||
|
<!-- <view class="fl_box fl_justbet">
|
||||||
<view>当前状态</view>
|
<view>当前状态</view>
|
||||||
<view>在职 看工作机会</view>
|
<view>在职 看工作机会</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="card btn-feel">
|
<view class="card btn-feel">
|
||||||
<view class="title">
|
<view class="title">
|
||||||
<image class="bg" src="@/static/icon/title-bg.png" />
|
<image class="bg" src="@/static/icon/title-bg.png" />
|
||||||
<view class="text">个人技能</view>
|
<view class="text">个人技能</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="skill-box">
|
<view class="skill-box">
|
||||||
<view class="skill-item" v-for="item in userInfo?.skillList" :key="item.id">{{ item.skill }}</view>
|
<view class="skill-item" v-for="item in userInfo?.skillList" :key="item.id">{{ item.skill }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="!userInfo?.skillList?.length" class="empty-box">
|
<view v-if="!userInfo?.skillList?.length" class="empty-box">
|
||||||
<image class="img" src="@/static/icon/empty.png" mode="widthFix"></image>
|
<image class="img" src="@/static/icon/empty.png" mode="widthFix"></image>
|
||||||
<view class="content">暂无个人技能</view>
|
<view class="content">暂无个人技能</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="card btn-feel">
|
<view class="card btn-feel">
|
||||||
<view class="title">
|
<view class="title">
|
||||||
<image class="bg" src="@/static/icon/title-bg.png" />
|
<image class="bg" src="@/static/icon/title-bg.png" />
|
||||||
<view class="text">关键经历</view>
|
<view class="text">关键经历</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="exp-box">
|
<view class="exp-box">
|
||||||
<view class="exp-item" v-for="(item, index) in userInfo?.workExp" :key="item.id">{{ index + 1 + "." }}{{ item.duty }}</view>
|
<view class="exp-item" v-for="(item, index) in userInfo?.workExp" :key="item.id">
|
||||||
</view>
|
{{ index + 1 + '.' }}{{ item.duty }}
|
||||||
<view v-if="!userInfo?.workExp?.length" class="empty-box">
|
</view>
|
||||||
<image class="img" src="@/static/icon/empty.png" mode="widthFix"></image>
|
</view>
|
||||||
<view class="content">暂无关键经历</view>
|
<view v-if="!userInfo?.workExp?.length" class="empty-box">
|
||||||
</view>
|
<image class="img" src="@/static/icon/empty.png" mode="widthFix"></image>
|
||||||
</view>
|
<view class="content">暂无关键经历</view>
|
||||||
<view class="card btn-feel">
|
</view>
|
||||||
<view class="title">
|
</view>
|
||||||
<image class="bg" src="@/static/icon/title-bg.png" />
|
<view class="card btn-feel">
|
||||||
<view class="text">荣誉及证书情况</view>
|
<view class="title">
|
||||||
</view>
|
<image class="bg" src="@/static/icon/title-bg.png" />
|
||||||
|
<view class="text">荣誉及证书情况</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<ul class="certificate-box">
|
<ul class="certificate-box">
|
||||||
<li class="certificate-item" v-for="(item, index) in userInfo?.certificateList" :key="item.id">{{ item.name }}</li>
|
<li class="certificate-item" v-for="(item, index) in userInfo?.certificateList" :key="item.id">
|
||||||
</ul>
|
{{ item.name }}
|
||||||
<view v-if="!userInfo?.certificateList?.length" class="empty-box">
|
</li>
|
||||||
<image class="img" src="@/static/icon/empty.png" mode="widthFix"></image>
|
</ul>
|
||||||
<view class="content">暂无荣誉证书</view>
|
<view v-if="!userInfo?.certificateList?.length" class="empty-box">
|
||||||
|
<image class="img" src="@/static/icon/empty.png" mode="widthFix"></image>
|
||||||
|
<view class="content">暂无荣誉证书</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</AppLayout>
|
||||||
</view>
|
|
||||||
</AppLayout>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, inject, watch, ref, onMounted, computed } from "vue";
|
import { reactive, inject, watch, ref, onMounted, computed } from 'vue';
|
||||||
const { $api, navTo, navBack } = inject("globalFunction");
|
const { $api, navTo, navBack } = inject('globalFunction');
|
||||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from 'pinia';
|
||||||
import useUserStore from "@/stores/useUserStore";
|
import useUserStore from '@/stores/useUserStore';
|
||||||
import useDictStore from "@/stores/useDictStore";
|
import useDictStore from '@/stores/useDictStore';
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo, isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const { getUserResume } = useUserStore();
|
const { getUserResume } = useUserStore();
|
||||||
const { getDictData, oneDictData } = useDictStore();
|
const { getDictData, oneDictData } = useDictStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.btn {
|
.btn {
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
image {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.card-top {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.9));
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background: #fff;
|
|
||||||
padding: 24rpx;
|
|
||||||
margin-top: 24rpx;
|
|
||||||
.title {
|
|
||||||
position: relative;
|
|
||||||
.bg {
|
|
||||||
width: 108rpx;
|
|
||||||
height: 16rpx;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
.text {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
font-size: 30rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.skill-box {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 16rpx;
|
|
||||||
margin-top: 24rpx;
|
|
||||||
.skill-item {
|
|
||||||
padding: 8rpx 20rpx;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #333;
|
|
||||||
background: #e7f1ff;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.exp-box {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 24rpx;
|
|
||||||
margin-top: 24rpx;
|
|
||||||
.exp-item {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.certificate-box {
|
|
||||||
margin-top: 24rpx;
|
|
||||||
padding-inline-start: 40rpx !important;
|
|
||||||
.certificate-item {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.mys-container {
|
|
||||||
padding: 28rpx;
|
|
||||||
.info {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 24rpx;
|
|
||||||
.avatar {
|
|
||||||
width: 160rpx;
|
|
||||||
height: 160rpx;
|
|
||||||
margin-right: 24rpx;
|
|
||||||
image{
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.info-right {
|
|
||||||
height: 160rpx;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
.name {
|
|
||||||
font-size: 40rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.des {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
.phone {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #999999;
|
|
||||||
.call-icon {
|
|
||||||
width: 24rpx;
|
|
||||||
height: 24rpx;
|
|
||||||
margin-right: 5rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.info-bottom {
|
|
||||||
background: linear-gradient(to right, #91b6ff, #87afff, #b7adff);
|
|
||||||
border-radius: 0 0 8rpx 8rpx;
|
|
||||||
padding: 12rpx 24rpx;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 26rpx;
|
width: 60rpx;
|
||||||
color: #333;
|
height: 60rpx;
|
||||||
}
|
image {
|
||||||
.des-card {
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-top {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.9));
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #fff;
|
||||||
padding: 24rpx;
|
padding: 24rpx;
|
||||||
font-size: 26rpx;
|
margin-top: 24rpx;
|
||||||
color: #666;
|
.title {
|
||||||
display: flex;
|
position: relative;
|
||||||
flex-direction: column;
|
.bg {
|
||||||
gap: 12rpx;
|
width: 108rpx;
|
||||||
}
|
height: 16rpx;
|
||||||
.empty-box {
|
position: absolute;
|
||||||
padding: 80rpx;
|
left: 0;
|
||||||
display: flex;
|
bottom: 0;
|
||||||
flex-direction: column;
|
}
|
||||||
align-items: center;
|
.text {
|
||||||
justify-content: center;
|
margin-left: 20rpx;
|
||||||
.img {
|
font-size: 30rpx;
|
||||||
width: 100%;
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.content {
|
}
|
||||||
margin-top: 24rpx;
|
.skill-box {
|
||||||
font-size: 30rpx;
|
display: flex;
|
||||||
color: #666;
|
flex-wrap: wrap;
|
||||||
|
gap: 16rpx;
|
||||||
|
margin-top: 24rpx;
|
||||||
|
.skill-item {
|
||||||
|
padding: 8rpx 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #333;
|
||||||
|
background: #e7f1ff;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.exp-box {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 24rpx;
|
||||||
|
margin-top: 24rpx;
|
||||||
|
.exp-item {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.certificate-box {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
padding-inline-start: 40rpx !important;
|
||||||
|
.certificate-item {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.mys-container {
|
||||||
|
padding: 28rpx;
|
||||||
|
.info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24rpx;
|
||||||
|
.avatar {
|
||||||
|
background: #e8e8e8;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
margin-right: 24rpx;
|
||||||
|
image {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info-right {
|
||||||
|
height: 160rpx;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
.name {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.des {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.phone {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999999;
|
||||||
|
.call-icon {
|
||||||
|
width: 24rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
margin-right: 5rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info-bottom {
|
||||||
|
background: linear-gradient(to right, #91b6ff, #87afff, #b7adff);
|
||||||
|
border-radius: 0 0 8rpx 8rpx;
|
||||||
|
padding: 12rpx 24rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.des-card {
|
||||||
|
padding: 24rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
.empty-box {
|
||||||
|
padding: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,245 +1,249 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="工作经历" border back-gorund-color="#ffffff" :show-bg-image="false">
|
<AppLayout title="工作经历" border back-gorund-color="#ffffff" :show-bg-image="false">
|
||||||
<template #headerleft>
|
<template #headerleft>
|
||||||
<view class="btn mar_le20 button-click" @click="navBack">取消</view>
|
<view class="btn mar_le20 button-click" @click="navBack">取消</view>
|
||||||
</template>
|
</template>
|
||||||
<template #headerright>
|
<template #headerright>
|
||||||
<view class="btn mar_ri20 button-click blue" @click="confirm">确认</view>
|
<view class="btn mar_ri20 button-click blue" @click="confirm">确认</view>
|
||||||
</template>
|
</template>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="content-input">
|
<view class="content-input">
|
||||||
<view class="input-titile">公司</view>
|
<view class="input-titile">公司</view>
|
||||||
<input class="input-con" v-model="fromValue.company" placeholder="请输入公司名称" />
|
<input class="input-con" v-model="fromValue.company" placeholder="请输入公司名称" />
|
||||||
</view>
|
</view>
|
||||||
<view class="content-input">
|
<view class="content-input">
|
||||||
<view class="input-titile">岗位</view>
|
<view class="input-titile">岗位</view>
|
||||||
<input class="input-con" v-model="fromValue.position" placeholder="请输入岗位" />
|
<input class="input-con" v-model="fromValue.position" placeholder="请输入岗位" />
|
||||||
</view>
|
</view>
|
||||||
<view class="content-input">
|
<view class="content-input">
|
||||||
<view class="input-titile">时间</view>
|
<view class="input-titile">时间</view>
|
||||||
<view class="flex-box">
|
<view class="flex-box">
|
||||||
<view class="input-box btn-feel" @click="changestartTime">
|
<view class="input-box btn-feel" @click="changestartTime">
|
||||||
<input v-model="fromValue.startTime" class="input-con triangle" disabled placeholder="开始时间" />
|
<input
|
||||||
<image class="icon" src="@/static/icon/arrow-down.png" />
|
v-model="fromValue.startTime"
|
||||||
</view>
|
class="input-con triangle"
|
||||||
<view class="gap">-</view>
|
disabled
|
||||||
<view class="input-box btn-feel" @click="changeendTime">
|
placeholder="开始时间"
|
||||||
<input v-model="fromValue.endTime" class="input-con triangle" disabled placeholder="至今" />
|
/>
|
||||||
<image class="icon" src="@/static/icon/arrow-down.png" />
|
<image class="icon" src="@/static/icon/arrow-down.png" />
|
||||||
</view>
|
</view>
|
||||||
|
<view class="gap">-</view>
|
||||||
|
<view class="input-box btn-feel" @click="changeendTime">
|
||||||
|
<input v-model="fromValue.endTime" class="input-con triangle" disabled placeholder="至今" />
|
||||||
|
<image class="icon" src="@/static/icon/arrow-down.png" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-input">
|
||||||
|
<view class="input-titile">工作内容</view>
|
||||||
|
<textarea class="text-area" placeholder="请输入工作内容" v-model="fromValue.duty"></textarea>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<!-- 时间选择器组件 -->
|
||||||
<view class="content-input">
|
<DatePicker ref="datePicker" />
|
||||||
<view class="input-titile">工作内容</view>
|
<template #footer v-if="fromValue.id">
|
||||||
<textarea class="text-area" placeholder="请输入工作内容" v-model="fromValue.duty"></textarea>
|
<view class="footer-container">
|
||||||
</view>
|
<view class="footer-button btn-feel" @click="delCurrent">删除该工作经历</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 时间选择器组件 -->
|
</template>
|
||||||
<DatePicker ref="datePicker" />
|
</AppLayout>
|
||||||
<template #footer v-if="fromValue.id">
|
|
||||||
<view class="footer-container">
|
|
||||||
<view class="footer-button btn-feel" @click="delCurrent">删除该工作经历</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</AppLayout>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, inject, watch, ref, onMounted, computed } from "vue";
|
import { reactive, inject, watch, ref, onMounted, computed } from 'vue';
|
||||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
const { $api, navTo, navBack } = inject("globalFunction");
|
const { $api, navTo, navBack } = inject('globalFunction');
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from 'pinia';
|
||||||
import useUserStore from "@/stores/useUserStore";
|
import useUserStore from '@/stores/useUserStore';
|
||||||
import useDictStore from "@/stores/useDictStore";
|
import useDictStore from '@/stores/useDictStore';
|
||||||
import DatePicker from "@/components/DatePicker/DatePicker.vue";
|
import DatePicker from '@/components/DatePicker/DatePicker.vue';
|
||||||
const { userInfo } = storeToRefs(useUserStore());
|
const { userInfo } = storeToRefs(useUserStore());
|
||||||
const { getUserResume } = useUserStore();
|
const { getUserResume } = useUserStore();
|
||||||
const { dictLabel, oneDictData } = useDictStore();
|
const { dictLabel, oneDictData } = useDictStore();
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
const fromValue = reactive({
|
const fromValue = reactive({
|
||||||
position: "",
|
position: '',
|
||||||
company: "",
|
company: '',
|
||||||
startTime: "",
|
startTime: '',
|
||||||
endTime: "",
|
endTime: '',
|
||||||
duty: "",
|
duty: '',
|
||||||
id: undefined,
|
id: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取时间选择器组件的引用
|
// 获取时间选择器组件的引用
|
||||||
const datePicker = ref();
|
const datePicker = ref();
|
||||||
|
|
||||||
onLoad((e) => {
|
onLoad((e) => {
|
||||||
initLoad(e?.id);
|
initLoad(e?.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
const confirm = async () => {
|
const confirm = async () => {
|
||||||
// 验证必填字段
|
// 验证必填字段
|
||||||
if (!fromValue.company) {
|
if (!fromValue.company) {
|
||||||
return $api.msg("请输入公司名称");
|
return $api.msg('请输入公司名称');
|
||||||
}
|
}
|
||||||
if (!fromValue.position) {
|
if (!fromValue.position) {
|
||||||
return $api.msg("请输入岗位");
|
return $api.msg('请输入岗位');
|
||||||
}
|
}
|
||||||
if (!fromValue.startTime) {
|
if (!fromValue.startTime) {
|
||||||
return $api.msg("请选择开始时间");
|
return $api.msg('请选择开始时间');
|
||||||
}
|
}
|
||||||
// 验证时间逻辑:结束时间不能早于开始时间
|
// 验证时间逻辑:结束时间不能早于开始时间
|
||||||
if (fromValue.endTime && new Date(fromValue.endTime) < new Date(fromValue.startTime)) {
|
if (fromValue.endTime && new Date(fromValue.endTime) < new Date(fromValue.startTime)) {
|
||||||
return $api.msg("结束时间不能早于开始时间");
|
return $api.msg('结束时间不能早于开始时间');
|
||||||
}
|
}
|
||||||
let res;
|
let res;
|
||||||
try {
|
try {
|
||||||
if (fromValue.id) {
|
if (fromValue.id) {
|
||||||
res = await $api.createRequest("/app/user/experience/edit", fromValue, "post");
|
res = await $api.createRequest('/app/user/experience/edit', fromValue, 'post');
|
||||||
} else {
|
} else {
|
||||||
res = await $api.createRequest("/app/user/experience/save", fromValue, "post");
|
res = await $api.createRequest('/app/user/experience/save', fromValue, 'post');
|
||||||
|
}
|
||||||
|
$api.msg('保存成功');
|
||||||
|
getUserResume().then(() => {
|
||||||
|
navBack();
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
$api.msg('保存失败');
|
||||||
}
|
}
|
||||||
$api.msg("保存成功");
|
|
||||||
getUserResume().then(() => {
|
|
||||||
navBack();
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
$api.msg("保存失败");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function delCurrent() {
|
function delCurrent() {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: "提示",
|
title: '提示',
|
||||||
content: "确认要删除此条工作经历吗?",
|
content: '确认要删除此条工作经历吗?',
|
||||||
showCancel: true,
|
showCancel: true,
|
||||||
success: async ({ confirm, cancel }) => {
|
success: async ({ confirm, cancel }) => {
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
await $api.createRequest("/app/user/experience/delete", { id: fromValue.id }, "post");
|
await $api.createRequest('/app/user/experience/delete', { id: fromValue.id }, 'post');
|
||||||
$api.msg("删除成功");
|
$api.msg('删除成功');
|
||||||
getUserResume().then(() => {
|
getUserResume().then(() => {
|
||||||
navBack();
|
navBack();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initLoad(id) {
|
function initLoad(id) {
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
$api
|
$api.createRequest(`/app/user/experience/getSingle/${id}`, {}, 'get')
|
||||||
.createRequest(`/app/user/experience/getSingle/${id}`, {}, "get")
|
.then((res) => {
|
||||||
.then((res) => {
|
Object.assign(fromValue, res.data);
|
||||||
Object.assign(fromValue, res.data);
|
})
|
||||||
})
|
.catch((err) => {
|
||||||
.catch((err) => {
|
console.error('获取工作经历失败:', err);
|
||||||
console.error("获取工作经历失败:", err);
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择开始时间
|
// 选择开始时间
|
||||||
const changestartTime = () => {
|
const changestartTime = () => {
|
||||||
console.log(1);
|
console.log(1);
|
||||||
datePicker.value.open({
|
datePicker.value.open({
|
||||||
title: "选择开始时间",
|
title: '选择开始时间',
|
||||||
defaultDate: fromValue.startTime,
|
defaultDate: fromValue.startTime,
|
||||||
success: (selectedDate) => {
|
success: (selectedDate) => {
|
||||||
fromValue.startTime = selectedDate;
|
fromValue.startTime = selectedDate;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 选择结束时间
|
// 选择结束时间
|
||||||
const changeendTime = () => {
|
const changeendTime = () => {
|
||||||
datePicker.value.open({
|
datePicker.value.open({
|
||||||
title: "选择结束时间",
|
title: '选择结束时间',
|
||||||
defaultDate: fromValue.endTime,
|
defaultDate: fromValue.endTime,
|
||||||
success: (selectedDate) => {
|
success: (selectedDate) => {
|
||||||
fromValue.endTime = selectedDate;
|
fromValue.endTime = selectedDate;
|
||||||
// 如果结束时间早于新的开始时间,清空结束时间
|
// 如果结束时间早于新的开始时间,清空结束时间
|
||||||
if (fromValue.startTime && new Date(fromValue.startTime) > new Date(selectedDate)) {
|
if (fromValue.startTime && new Date(fromValue.startTime) > new Date(selectedDate)) {
|
||||||
fromValue.endTime = "";
|
fromValue.endTime = '';
|
||||||
$api.msg("结束时间不能小于开始时间!");
|
$api.msg('结束时间不能小于开始时间!');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.btn.blue {
|
.btn.blue {
|
||||||
color: #1677ff;
|
color: #1677ff;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
padding: 28rpx;
|
padding: 28rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
height: calc(100% - 120rpx);
|
height: calc(100% - 120rpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-box {
|
.flex-box {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.gap {
|
|
||||||
font-size: 40rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
flex: 0.25;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
width: 75rpx;
|
|
||||||
height: 50rpx;
|
|
||||||
}
|
|
||||||
.input-box {
|
|
||||||
flex: 0.375;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
.gap {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
flex: 0.25;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
width: 75rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
}
|
||||||
|
.input-box {
|
||||||
|
flex: 0.375;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-input {
|
.content-input {
|
||||||
margin-bottom: 48rpx;
|
margin-bottom: 48rpx;
|
||||||
padding-bottom: 20rpx;
|
padding-bottom: 20rpx;
|
||||||
border-bottom: 2rpx solid #ebebeb;
|
border-bottom: 2rpx solid #ebebeb;
|
||||||
&:nth-last-of-type(1) {
|
&:nth-last-of-type(1) {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
.input-titile {
|
.input-titile {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #6a6a6a;
|
color: #6a6a6a;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
}
|
}
|
||||||
.input-con {
|
.input-con {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
line-height: 80rpx;
|
line-height: 80rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.triangle {
|
.triangle {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.text-area {
|
.text-area {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 700rpx;
|
height: 700rpx;
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-container {
|
.footer-container {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
box-shadow: 0rpx -4rpx 24rpx 0rpx rgba(11, 44, 112, 0.12);
|
box-shadow: 0rpx -4rpx 24rpx 0rpx rgba(11, 44, 112, 0.12);
|
||||||
border-radius: 0rpx 0rpx 0rpx 0rpx;
|
border-radius: 0rpx 0rpx 0rpx 0rpx;
|
||||||
padding: 40rpx 28rpx 20rpx 28rpx;
|
padding: 40rpx 28rpx 20rpx 28rpx;
|
||||||
.footer-button {
|
.footer-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 90rpx;
|
height: 90rpx;
|
||||||
background: #f93a4a;
|
background: #f93a4a;
|
||||||
border-radius: 8rpx;
|
border-radius: 8rpx;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
line-height: 90rpx;
|
line-height: 90rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
"path": "pages/index/index",
|
"path": "pages/index/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "青岛智慧就业平台",
|
"navigationBarTitleText": "青岛智慧就业平台",
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,56 +45,63 @@
|
|||||||
<view class="container-main">
|
<view class="container-main">
|
||||||
<scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLower">
|
<scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLower">
|
||||||
<view class="cards">
|
<view class="cards">
|
||||||
<view
|
<!-- #ifdef H5 -->
|
||||||
class="card press-button"
|
<transition-group name="stagger" tag="view" :css="true">
|
||||||
v-for="(item, index) in fairList"
|
<!-- #endif -->
|
||||||
:key="index"
|
<view
|
||||||
@click="
|
class="card press-button"
|
||||||
navTo(
|
v-for="(item, index) in fairList"
|
||||||
'/packageA/pages/exhibitors/exhibitors?jobFairId=' +
|
:key="item.zphID"
|
||||||
item.zphID +
|
:style="{ '--i': index }"
|
||||||
'&jobFairName=' +
|
@click="
|
||||||
item.zphmc
|
navTo(
|
||||||
)
|
'/packageA/pages/exhibitors/exhibitors?jobFairId=' +
|
||||||
"
|
item.zphID +
|
||||||
>
|
'&jobFairName=' +
|
||||||
<view class="card-title">{{ item.zphmc }}</view>
|
item.zphmc
|
||||||
<view class="card-row">
|
)
|
||||||
<text class="">{{ item.jbf }}</text>
|
"
|
||||||
<text class="">
|
>
|
||||||
<!-- <convert-distance
|
<view class="card-title">{{ item.zphmc }}</view>
|
||||||
|
<view class="card-row">
|
||||||
|
<text class="">{{ item.jbf }}</text>
|
||||||
|
<text class="">
|
||||||
|
<!-- <convert-distance
|
||||||
:alat="item.latitude"
|
:alat="item.latitude"
|
||||||
:along="item.longitude"
|
:along="item.longitude"
|
||||||
:blat="latitudeVal"
|
:blat="latitudeVal"
|
||||||
:blong="longitudeVal"
|
:blong="longitudeVal"
|
||||||
></convert-distance> -->
|
></convert-distance> -->
|
||||||
</text>
|
</text>
|
||||||
</view>
|
|
||||||
<view class="card-times">
|
|
||||||
<view class="time-left">
|
|
||||||
<view class="left-date">{{ parseDateTime(item.zphjbsj).time }}</view>
|
|
||||||
<view class="left-dateDay">{{ parseDateTime(item.zphjbsj).date }}</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="line"></view>
|
<view class="card-times">
|
||||||
<view class="time-center">
|
<view class="time-left">
|
||||||
<view class="center-date">
|
<view class="left-date">{{ parseDateTime(item.zphjbsj).time }}</view>
|
||||||
{{ getTimeStatus(item.zphjbsj, item.zphjzsj).statusText }}
|
<view class="left-dateDay">{{ parseDateTime(item.zphjbsj).date }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="center-dateDay">
|
<view class="line"></view>
|
||||||
{{ getHoursBetween(item.zphjbsj, item.zphjzsj) }}小时
|
<view class="time-center">
|
||||||
|
<view class="center-date">
|
||||||
|
{{ getTimeStatus(item.zphjbsj, item.zphjzsj).statusText }}
|
||||||
|
</view>
|
||||||
|
<view class="center-dateDay">
|
||||||
|
{{ getHoursBetween(item.zphjbsj, item.zphjzsj) }}小时
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="line"></view>
|
||||||
|
<view class="time-right">
|
||||||
|
<view class="left-date">{{ parseDateTime(item.zphjzsj).time }}</view>
|
||||||
|
<view class="left-dateDay">{{ parseDateTime(item.zphjzsj).date }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="line"></view>
|
<view class="recommend-card-line"></view>
|
||||||
<view class="time-right">
|
<view class="card-footer">内容简介:{{ item.zphjj }}</view>
|
||||||
<view class="left-date">{{ parseDateTime(item.zphjzsj).time }}</view>
|
|
||||||
<view class="left-dateDay">{{ parseDateTime(item.zphjzsj).date }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="recommend-card-line"></view>
|
<!-- #ifdef H5 -->
|
||||||
<view class="card-footer">内容简介:{{ item.zphjj }}</view>
|
</transition-group>
|
||||||
</view>
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
<empty v-if="!fairList.length"></empty>
|
<empty v-if="!fairList.length" content="暂时没有结果,下一天也许就有惊喜"></empty>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<!-- <Tabbar :currentpage="1"></Tabbar> -->
|
<!-- <Tabbar :currentpage="1"></Tabbar> -->
|
||||||
@@ -108,6 +115,7 @@ import { onLoad, onShow } from '@dcloudio/uni-app';
|
|||||||
import Tabbar from '@/components/tabbar/midell-box.vue';
|
import Tabbar from '@/components/tabbar/midell-box.vue';
|
||||||
import useLocationStore from '@/stores/useLocationStore';
|
import useLocationStore from '@/stores/useLocationStore';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
import config from '@/config';
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
const { $api, navTo, cloneDeep, debounce } = inject('globalFunction');
|
const { $api, navTo, cloneDeep, debounce } = inject('globalFunction');
|
||||||
const weekList = ref([]);
|
const weekList = ref([]);
|
||||||
@@ -140,6 +148,12 @@ onLoad(() => {
|
|||||||
getFair('refresh');
|
getFair('refresh');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleItemClick = (item) => {
|
||||||
|
lightAppJssdk.navigation.hide({
|
||||||
|
url: config.virtualJobFair,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function toSelectDate() {
|
function toSelectDate() {
|
||||||
navTo('/packageA/pages/selectDate/selectDate', {
|
navTo('/packageA/pages/selectDate/selectDate', {
|
||||||
query: {
|
query: {
|
||||||
@@ -171,7 +185,9 @@ function changeSwiperMsgType(e) {
|
|||||||
|
|
||||||
function seemsg(index) {
|
function seemsg(index) {
|
||||||
if (index === 1) {
|
if (index === 1) {
|
||||||
return $api.msg('功能确定中');
|
handleItemClick();
|
||||||
|
// $api.msg('功能确定中');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
state.current = index;
|
state.current = index;
|
||||||
}
|
}
|
||||||
@@ -201,7 +217,7 @@ function getFair(type = 'add') {
|
|||||||
if (currentDay.value?.fullDate) {
|
if (currentDay.value?.fullDate) {
|
||||||
params.zphjbsj = currentDay.value.fullDate.replace(/-/g, '');
|
params.zphjbsj = currentDay.value.fullDate.replace(/-/g, '');
|
||||||
}
|
}
|
||||||
$api.createRequest('/app/internal/jobFairThirdPart', params, 'GET', true).then((resData) => {
|
$api.createRequest('/app/internal/jobFairThirdPart', params, 'GET', false).then((resData) => {
|
||||||
const { rows, total } = resData;
|
const { rows, total } = resData;
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
// const str = pageState.pageSize * (pageState.page - 1);
|
// const str = pageState.pageSize * (pageState.page - 1);
|
||||||
@@ -324,6 +340,8 @@ function getNextDates({ startDate = '', count = 6 }) {
|
|||||||
.container-header {
|
.container-header {
|
||||||
background: url('@/static/icon/background2.png') 0 0 no-repeat;
|
background: url('@/static/icon/background2.png') 0 0 no-repeat;
|
||||||
background-size: 100% 400rpx;
|
background-size: 100% 400rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-top: calc(var(--window-top) + var(--status-bar-height));
|
||||||
.header-top{
|
.header-top{
|
||||||
display: flex;
|
display: flex;
|
||||||
line-height: calc(88rpx - 14rpx);
|
line-height: calc(88rpx - 14rpx);
|
||||||
|
|||||||
@@ -111,16 +111,16 @@ onHide(() => {
|
|||||||
paging.value?.handleTouchCancel();
|
paging.value?.handleTouchCancel();
|
||||||
if (isDrawerOpen.value) {
|
if (isDrawerOpen.value) {
|
||||||
isDrawerOpen.value = false;
|
isDrawerOpen.value = false;
|
||||||
// uni.showTabBar();
|
uni.showTabBar();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const toggleDrawer = () => {
|
const toggleDrawer = () => {
|
||||||
isDrawerOpen.value = !isDrawerOpen.value;
|
isDrawerOpen.value = !isDrawerOpen.value;
|
||||||
if (isDrawerOpen.value) {
|
if (isDrawerOpen.value) {
|
||||||
// uni.hideTabBar();
|
uni.hideTabBar();
|
||||||
} else {
|
} else {
|
||||||
// uni.showTabBar();
|
uni.showTabBar();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
386
pages/index/components/AIMatch.vue
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="container" id="pixi-box" ref="pixiContainerRef"></view>
|
||||||
|
|
||||||
|
<!-- renderjs 通信组件 -->
|
||||||
|
<view style="display: none" :change:random="appModule.initPixi" :random="random" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data: () => ({
|
||||||
|
random: 0,
|
||||||
|
}),
|
||||||
|
mounted() {
|
||||||
|
this.triggerRender();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
triggerRender() {
|
||||||
|
this.random++;
|
||||||
|
},
|
||||||
|
tagClick(tagData) {
|
||||||
|
this.$emit('tag-click', tagData);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script module="appModule" lang="renderjs">
|
||||||
|
import * as PIXI from "pixi.js";
|
||||||
|
|
||||||
|
// PIXI 变量
|
||||||
|
let app = null;
|
||||||
|
let tagsContainer = null;
|
||||||
|
let activeTagInstances = [];
|
||||||
|
|
||||||
|
|
||||||
|
// 配置数据
|
||||||
|
const mockTags = [
|
||||||
|
{ name: "医生", bgColor: 0x0069fe, fontColor: 0xffffff, size: 17, opacity: 1.0, angle: 0, radius: 0 },
|
||||||
|
{
|
||||||
|
name: "工程师",
|
||||||
|
bgColor: 0x87e2ec,
|
||||||
|
fontColor: 0xffffff,
|
||||||
|
size: 14,
|
||||||
|
opacity: 1,
|
||||||
|
angle: -Math.PI / 2,
|
||||||
|
radius: 68,
|
||||||
|
tailRotation: Math.PI / 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "建筑师",
|
||||||
|
bgColor: 0xffebeb,
|
||||||
|
tailColor: 0xffe1e1,
|
||||||
|
fontColor: 0xff6969,
|
||||||
|
size: 11.5,
|
||||||
|
opacity: 1,
|
||||||
|
angle: -Math.PI / 4.2,
|
||||||
|
radius: 125,
|
||||||
|
tailRotation: (3 * Math.PI) / 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "律师",
|
||||||
|
bgColor: 0x21ea85,
|
||||||
|
fontColor: 0xffffff,
|
||||||
|
size: 15,
|
||||||
|
opacity: 1,
|
||||||
|
angle: -Math.PI / 10,
|
||||||
|
radius: 130,
|
||||||
|
tailRotation: (3 * Math.PI) / 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "记者",
|
||||||
|
bgColor: 0xebf3ff,
|
||||||
|
tailColor: 0xb9d3ff,
|
||||||
|
fontColor: 0x1d71ef,
|
||||||
|
size: 12,
|
||||||
|
opacity: 1,
|
||||||
|
angle: Math.PI / 120,
|
||||||
|
radius: 130,
|
||||||
|
tailRotation: (3 * Math.PI) / 3.4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "程序员",
|
||||||
|
bgColor: 0xffd4b6,
|
||||||
|
fontColor: 0xffffff,
|
||||||
|
size: 14,
|
||||||
|
opacity: 1,
|
||||||
|
angle: Math.PI / 7,
|
||||||
|
radius: 120,
|
||||||
|
tailRotation: (5 * Math.PI) / 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "心理咨询师",
|
||||||
|
bgColor: 0xebf3ff,
|
||||||
|
tailColor: 0xb9d3ff,
|
||||||
|
fontColor: 0x1d71ef,
|
||||||
|
size: 10.5,
|
||||||
|
opacity: 1,
|
||||||
|
angle: (5.4 * Math.PI) / 6,
|
||||||
|
radius: 110,
|
||||||
|
tailRotation: (3 * Math.PI) / 1.78,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "护士",
|
||||||
|
bgColor: 0xff6969,
|
||||||
|
fontColor: 0xffffff,
|
||||||
|
size: 15,
|
||||||
|
opacity: 1,
|
||||||
|
angle: (6.3 * Math.PI) / 5.9,
|
||||||
|
radius: 110,
|
||||||
|
tailRotation: Math.PI / 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "会计",
|
||||||
|
bgColor: 0xfce9c9,
|
||||||
|
fontColor: 0xfbc55f,
|
||||||
|
size: 13,
|
||||||
|
opacity: 1,
|
||||||
|
angle: (7.2 * Math.PI) / 5.9,
|
||||||
|
radius: 120,
|
||||||
|
tailRotation: Math.PI / 4,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (app) {
|
||||||
|
app.destroy(true, { children: true, texture: true, baseTexture: true });
|
||||||
|
app = null;
|
||||||
|
}
|
||||||
|
window.removeEventListener("resize", this.handleResize());
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
async initPixi (random) {
|
||||||
|
if(!random) return
|
||||||
|
const container = document.querySelector('#pixi-box');
|
||||||
|
if (!container) return;
|
||||||
|
const width = container.clientWidth || 300;
|
||||||
|
const height = container.clientHeight || 300;
|
||||||
|
console.log(width,height);
|
||||||
|
|
||||||
|
if (app) return;
|
||||||
|
|
||||||
|
app = new PIXI.Application({
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
backgroundAlpha: 0,
|
||||||
|
backgroundColor: 0xf5f7fa,
|
||||||
|
antialias: true,
|
||||||
|
resolution: window?.devicePixelRatio ?? 1,
|
||||||
|
autoDensity: true,
|
||||||
|
});
|
||||||
|
app.view.style.touchAction = "auto";
|
||||||
|
|
||||||
|
container.appendChild(app.view);
|
||||||
|
|
||||||
|
tagsContainer = new PIXI.Container();
|
||||||
|
app.stage.addChild(tagsContainer);
|
||||||
|
|
||||||
|
this.renderScene(width, height);
|
||||||
|
window.addEventListener("resize", this.handleResize());
|
||||||
|
},
|
||||||
|
renderScene (sw, sh) {
|
||||||
|
tagsContainer.removeChildren();
|
||||||
|
activeTagInstances = [];
|
||||||
|
|
||||||
|
const baseSize = 375;
|
||||||
|
const scaleFactor = (Math.min(sw, sh) / baseSize) * 0.9;
|
||||||
|
|
||||||
|
mockTags.forEach((data, index) => {
|
||||||
|
const scaledRadius = data.radius * (scaleFactor < 1 ? 1 : scaleFactor * 0.8);
|
||||||
|
|
||||||
|
let x = sw / 2 + scaledRadius * Math.cos(data.angle);
|
||||||
|
let y = sh / 2 + scaledRadius * Math.sin(data.angle);
|
||||||
|
|
||||||
|
const tag = this.createTag(data, index);
|
||||||
|
|
||||||
|
tagsContainer.addChild(tag);
|
||||||
|
|
||||||
|
const safeW = tag.width / 2 + 10;
|
||||||
|
const safeH = tag.height / 2 + 10;
|
||||||
|
|
||||||
|
// 强制修正 x 和 y,使其不超出屏幕
|
||||||
|
x = clamp(x, safeW, sw - safeW);
|
||||||
|
y = clamp(y, safeH, sh - safeH);
|
||||||
|
|
||||||
|
tag.x = x;
|
||||||
|
tag.y = y;
|
||||||
|
|
||||||
|
// 4. 保存元数据
|
||||||
|
tag.userData = {
|
||||||
|
originalX: x,
|
||||||
|
originalY: y,
|
||||||
|
angle: data.angle,
|
||||||
|
radius: scaledRadius,
|
||||||
|
floatOffset: Math.random() * Math.PI * 2,
|
||||||
|
floatSpeed: 0.01 + Math.random() * 0.02,
|
||||||
|
floatRange: 2 + Math.random() * 2,
|
||||||
|
safeH: safeH,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data.radius > 0) {
|
||||||
|
const tail = this.createCometTail(data.tailColor || data.bgColor, data.tailRotation, tag.width);
|
||||||
|
tag.addChildAt(tail, 0);
|
||||||
|
tag.updateTail = () => tail.updateAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
activeTagInstances.push(tag);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 动画循环
|
||||||
|
app.ticker.add(() => {
|
||||||
|
const screenH = app.screen.height;
|
||||||
|
|
||||||
|
activeTagInstances.forEach((tag) => {
|
||||||
|
const meta = tag.userData;
|
||||||
|
if (meta) {
|
||||||
|
// 计算新的浮动位置
|
||||||
|
meta.floatOffset += meta.floatSpeed;
|
||||||
|
let nextY = meta.originalY + Math.sin(meta.floatOffset) * meta.floatRange;
|
||||||
|
|
||||||
|
// 再次进行边界检查
|
||||||
|
if (nextY < meta.safeH) nextY = meta.safeH;
|
||||||
|
if (nextY > screenH - meta.safeH) nextY = screenH - meta.safeH;
|
||||||
|
|
||||||
|
tag.y = nextY;
|
||||||
|
|
||||||
|
if (tag.updateTail) tag.updateTail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
createTag (tagData, index) {
|
||||||
|
const tagGroup = new PIXI.Container();
|
||||||
|
tagGroup.eventMode = "static";
|
||||||
|
tagGroup.cursor = "pointer";
|
||||||
|
|
||||||
|
tagGroup.on("pointertap", () =>{
|
||||||
|
this.$ownerInstance.callMethod('tagClick', tagData);
|
||||||
|
});
|
||||||
|
const text = new PIXI.Text(tagData.name, {
|
||||||
|
fontFamily: ["PingFang SC", "Microsoft YaHei", "Arial"],
|
||||||
|
fontSize: tagData.size,
|
||||||
|
fill: tagData.fontColor,
|
||||||
|
padding: 4,
|
||||||
|
resolution: 2,
|
||||||
|
});
|
||||||
|
text.anchor.set(0.5);
|
||||||
|
|
||||||
|
const paddingH = 26;
|
||||||
|
const paddingV = 10;
|
||||||
|
let bgWidth = text.width + paddingH;
|
||||||
|
let bgHeight = text.height + paddingV;
|
||||||
|
|
||||||
|
if (index === 0) bgWidth = Math.max(bgWidth, tagData.size * 4.5);
|
||||||
|
|
||||||
|
const bg = new PIXI.Graphics();
|
||||||
|
bg.beginFill(tagData.bgColor, tagData.opacity ?? 1);
|
||||||
|
bg.drawRoundedRect(-bgWidth / 2, -bgHeight / 2, bgWidth, bgHeight, bgHeight / 2);
|
||||||
|
bg.endFill();
|
||||||
|
|
||||||
|
tagGroup.addChild(bg);
|
||||||
|
tagGroup.addChild(text);
|
||||||
|
|
||||||
|
return tagGroup;
|
||||||
|
},
|
||||||
|
|
||||||
|
createCometTail (bgColor, tailRotation, parentWidth) {
|
||||||
|
const tailGroup = new PIXI.Container();
|
||||||
|
const graphics = new PIXI.Graphics();
|
||||||
|
tailGroup.addChild(graphics);
|
||||||
|
|
||||||
|
const baseLength = 45;
|
||||||
|
const startWidth = parentWidth * 0.6;
|
||||||
|
const endWidth = 20;
|
||||||
|
|
||||||
|
let breathPhase = Math.random() * Math.PI * 2;
|
||||||
|
const breathSpeed = 0.04;
|
||||||
|
|
||||||
|
tailGroup.updateAnim = () => {
|
||||||
|
breathPhase += breathSpeed;
|
||||||
|
const breathScale = 0.85 + 0.15 * Math.sin(breathPhase);
|
||||||
|
graphics.clear();
|
||||||
|
const currentLength = baseLength * breathScale;
|
||||||
|
|
||||||
|
const cos = Math.cos(tailRotation);
|
||||||
|
const sin = Math.sin(tailRotation);
|
||||||
|
const perpX = -sin;
|
||||||
|
const perpY = cos;
|
||||||
|
|
||||||
|
const p1 = { x: perpX * (startWidth / 2), y: perpY * (startWidth / 2) };
|
||||||
|
const p2 = { x: -perpX * (startWidth / 2), y: -perpY * (startWidth / 2) };
|
||||||
|
const endCX = cos * currentLength;
|
||||||
|
const endCY = sin * currentLength;
|
||||||
|
const p3 = { x: endCX - perpX * (endWidth / 2), y: endCY - perpY * (endWidth / 2) };
|
||||||
|
const p4 = { x: endCX + perpX * (endWidth / 2), y: endCY + perpY * (endWidth / 2) };
|
||||||
|
|
||||||
|
const segments = 8;
|
||||||
|
for (let i = 0; i < segments; i++) {
|
||||||
|
const t1 = i / segments;
|
||||||
|
const t2 = (i + 1) / segments;
|
||||||
|
const alpha = 0.4 * (1 - t1);
|
||||||
|
const sp1 = { x: p1.x + (p4.x - p1.x) * t1, y: p1.y + (p4.y - p1.y) * t1 };
|
||||||
|
const sp2 = { x: p2.x + (p3.x - p2.x) * t1, y: p2.y + (p3.y - p2.y) * t1 };
|
||||||
|
const ep1 = { x: p1.x + (p4.x - p1.x) * t2, y: p1.y + (p4.y - p1.y) * t2 };
|
||||||
|
const ep2 = { x: p2.x + (p3.x - p2.x) * t2, y: p2.y + (p3.y - p2.y) * t2 };
|
||||||
|
graphics.beginFill(bgColor, alpha);
|
||||||
|
graphics.moveTo(sp1.x, sp1.y);
|
||||||
|
graphics.lineTo(sp2.x, sp2.y);
|
||||||
|
graphics.lineTo(ep2.x, ep2.y);
|
||||||
|
graphics.lineTo(ep1.x, ep1.y);
|
||||||
|
graphics.endFill();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tailGroup.updateAnim();
|
||||||
|
return tailGroup;
|
||||||
|
},
|
||||||
|
|
||||||
|
handleResize () {
|
||||||
|
const container = document.querySelector('#pixi-box');
|
||||||
|
if (!app || !container) return;
|
||||||
|
const w = container.clientWidth || 300;
|
||||||
|
const h = container.clientHeight || 300;
|
||||||
|
|
||||||
|
app.renderer.resize(w, h);
|
||||||
|
|
||||||
|
activeTagInstances.forEach((tag) => {
|
||||||
|
const meta = tag.userData;
|
||||||
|
if (!meta) return;
|
||||||
|
|
||||||
|
let newX = w / 2 + meta.radius * Math.cos(meta.angle);
|
||||||
|
let newY = h / 2 + meta.radius * Math.sin(meta.angle);
|
||||||
|
|
||||||
|
const safeW = tag.width / 2 + 10;
|
||||||
|
const safeH = tag.height / 2 + 10;
|
||||||
|
|
||||||
|
meta.originalX = clamp(newX, safeW, w - safeW);
|
||||||
|
meta.originalY = clamp(newY, safeH, h - safeH);
|
||||||
|
meta.safeH = safeH; // 更新安全高度
|
||||||
|
|
||||||
|
tag.x = meta.originalX;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
height: 500rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #b9d3ff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -148,14 +148,14 @@
|
|||||||
<!-- 筛选 -->
|
<!-- 筛选 -->
|
||||||
<select-filter ref="selectFilterModel"></select-filter>
|
<select-filter ref="selectFilterModel"></select-filter>
|
||||||
|
|
||||||
<!-- <view class="maskFristEntry" v-if="maskFristEntry">
|
<view class="maskFristEntry" v-if="maskFristEntry">
|
||||||
<view class="entry-content">
|
<view class="entry-content">
|
||||||
<text class="text1">左滑查看视频</text>
|
<text class="text1">左滑查看视频</text>
|
||||||
<text class="text2">左滑查看视频</text>
|
<text class="text2">左滑查看视频</text>
|
||||||
<view class="goExperience">去体验</view>
|
<view class="goExperience">去体验</view>
|
||||||
<view class="maskFristEntry-Close" @click="closeFristEntry">1</view>
|
<view class="maskFristEntry-Close" @click="closeFristEntry">1</view>
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ const waterfallsFlowRef = ref(null);
|
|||||||
const loadmoreRef = ref(null);
|
const loadmoreRef = ref(null);
|
||||||
const conditionSearch = ref({});
|
const conditionSearch = ref({});
|
||||||
const waterfallcolumn = ref(2);
|
const waterfallcolumn = ref(2);
|
||||||
const maskFristEntry = ref(false);
|
const maskFristEntry = ref(true);
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
tabIndex: 'all',
|
tabIndex: 'all',
|
||||||
});
|
});
|
||||||
|
|||||||
1397
pages/index/components/index-refactor.vue
Normal file
@@ -35,7 +35,6 @@
|
|||||||
ref="waterfallsFlowRef"
|
ref="waterfallsFlowRef"
|
||||||
:column="columnCount"
|
:column="columnCount"
|
||||||
:columnSpace="columnSpace"
|
:columnSpace="columnSpace"
|
||||||
@loaded="imageloaded"
|
|
||||||
:value="list"
|
:value="list"
|
||||||
>
|
>
|
||||||
<template v-slot:default="job">
|
<template v-slot:default="job">
|
||||||
@@ -94,7 +93,7 @@ const state = reactive({
|
|||||||
// 响应式搜索条件(可以被修改)
|
// 响应式搜索条件(可以被修改)
|
||||||
const searchParams = ref({});
|
const searchParams = ref({});
|
||||||
const pageSize = ref(10);
|
const pageSize = ref(10);
|
||||||
const { list, loading, refresh, loadMore } = usePagination(
|
const { list, loading, refresh, loadMore,finished } = usePagination(
|
||||||
(params) => $api.createRequest('/app/job/littleVideo', params),
|
(params) => $api.createRequest('/app/job/littleVideo', params),
|
||||||
dataToImg, // 转换函数
|
dataToImg, // 转换函数
|
||||||
{
|
{
|
||||||
@@ -106,10 +105,25 @@ const { list, loading, refresh, loadMore } = usePagination(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
watch(()=>finished.value, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
// 确保瀑布流组件知道数据已加载完成
|
||||||
|
loadmoreRef.value?.change('noMore')
|
||||||
|
}else{
|
||||||
|
loadmoreRef.value?.change('more')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function imageloaded() {
|
// function imageloaded() {
|
||||||
loadmoreRef.value?.change('more');
|
// nextTick(() => {
|
||||||
}
|
// console.log('触发',finished.value)
|
||||||
|
// if (finished.value) {
|
||||||
|
// loadmoreRef.value?.change('noMore')
|
||||||
|
// } else {
|
||||||
|
// loadmoreRef.value?.change('more')
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
const { columnCount, columnSpace } = useColumnCount(() => {
|
const { columnCount, columnSpace } = useColumnCount(() => {
|
||||||
pageSize.value = 10 * (columnCount.value - 1);
|
pageSize.value = 10 * (columnCount.value - 1);
|
||||||
|
|||||||
@@ -1,70 +1,67 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="app-custom-root">
|
<view class="app-custom-root">
|
||||||
<view class="app-container">
|
<view class="container">
|
||||||
<!-- 主体内容区域 -->
|
<!-- 主体内容区域 -->
|
||||||
<view class="container-main">
|
<view class="container-main">
|
||||||
<swiper
|
<swiper class="swiper" :disable-touch="disableTouch" :current="state.current" @change="changeSwiperType">
|
||||||
class="swiper"
|
<!-- 绑定首页和尾页 -->
|
||||||
:disable-touch="disableTouch"
|
<swiper-item
|
||||||
:current="state.current"
|
@touchstart.passive="handleTouchStart"
|
||||||
@change="changeSwiperType"
|
@touchmove.passive="handleTouchMove"
|
||||||
>
|
@touchend="disableTouch = false"
|
||||||
<!-- 绑定首页和尾页 -->
|
class="swiper-item"
|
||||||
<swiper-item
|
v-for="(_, index) in 2"
|
||||||
@touchstart.passive="handleTouchStart"
|
:key="index"
|
||||||
@touchmove.passive="handleTouchMove"
|
>
|
||||||
@touchend="disableTouch = false"
|
<!-- #ifndef MP-WEIXIN -->
|
||||||
class="swiper-item"
|
<component
|
||||||
v-for="(_, index) in 2"
|
:is="components[index]"
|
||||||
:key="index"
|
@onShowTabbar="changeShowTabbar"
|
||||||
>
|
:ref="(el) => handelComponentsRef(el, index)"
|
||||||
<!-- #ifndef MP-WEIXIN -->
|
/>
|
||||||
<component
|
<!-- #endif -->
|
||||||
:is="components[index]"
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
@onShowTabbar="changeShowTabbar"
|
<IndexOne
|
||||||
:ref="(el) => handelComponentsRef(el, index)"
|
v-show="currentIndex === 0"
|
||||||
/>
|
@onShowTabbar="changeShowTabbar"
|
||||||
<!-- #endif -->
|
:ref="(el) => handelComponentsRef(el, index)"
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
/>
|
||||||
<IndexOne
|
<IndexTwo
|
||||||
v-show="currentIndex === 0"
|
v-show="currentIndex === 1"
|
||||||
@onShowTabbar="changeShowTabbar"
|
@onShowTabbar="changeShowTabbar"
|
||||||
:ref="(el) => handelComponentsRef(el, index)"
|
:ref="(el) => handelComponentsRef(el, index)"
|
||||||
/>
|
/>
|
||||||
<IndexTwo
|
<!-- #endif -->
|
||||||
v-show="currentIndex === 1"
|
</swiper-item>
|
||||||
@onShowTabbar="changeShowTabbar"
|
</swiper>
|
||||||
:ref="(el) => handelComponentsRef(el, index)"
|
</view>
|
||||||
/>
|
|
||||||
<!-- #endif -->
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- <Tabbar v-show="showTabbar" :currentpage="0"></Tabbar> -->
|
<!-- <Tabbar v-show="showTabbar" :currentpage="0"></Tabbar> -->
|
||||||
|
|
||||||
<!-- maskFristEntry -->
|
<!-- maskFristEntry -->
|
||||||
<view class="maskFristEntry" v-if="maskFristEntry">
|
<view class="maskFristEntry" v-if="maskFristEntry">
|
||||||
<view class="entry-content">
|
<view class="entry-content">
|
||||||
<text class="text1">左滑查看视频</text>
|
<text class="text1">左滑查看视频</text>
|
||||||
<text class="text2">快去体验吧~</text>
|
<text class="text2">快去体验吧~</text>
|
||||||
<view class="goExperience" @click="goExperience">去体验</view>
|
<view class="goExperience" @click="goExperience">去体验</view>
|
||||||
<view class="maskFristEntry-Close" @click="closeFristEntry"></view>
|
<view class="maskFristEntry-Close" @click="closeFristEntry"></view>
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
||||||
import Tabbar from '@/components/tabbar/midell-box.vue';
|
import Tabbar from '@/components/tabbar/midell-box.vue';
|
||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import IndexRefactor from './components/index-refactor.vue';
|
||||||
import IndexOne from './components/index-one.vue';
|
import IndexOne from './components/index-one.vue';
|
||||||
import IndexTwo from './components/index-two.vue';
|
import IndexTwo from './components/index-two.vue';
|
||||||
const loadedMap = reactive([false, false]);
|
const loadedMap = reactive([false, false]);
|
||||||
const swiperRefs = [ref(null), ref(null)];
|
const swiperRefs = [ref(null), ref(null)];
|
||||||
const components = [IndexOne, IndexTwo];
|
// const components = [IndexOne, IndexTwo];
|
||||||
|
const components = [IndexRefactor, IndexTwo];
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useReadMsg } from '@/stores/useReadMsg';
|
import { useReadMsg } from '@/stores/useReadMsg';
|
||||||
const { unreadCount } = storeToRefs(useReadMsg());
|
const { unreadCount } = storeToRefs(useReadMsg());
|
||||||
@@ -77,132 +74,134 @@ const totalPage = 2;
|
|||||||
const THRESHOLD = 5;
|
const THRESHOLD = 5;
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
// 判断浏览器是否有 fristEntry 第一次进入
|
// 判断浏览器是否有 fristEntry 第一次进入
|
||||||
let fristEntry = uni.getStorageSync('fristEntry') === false ? false : true; // 默认未读
|
let fristEntry = uni.getStorageSync('fristEntry') === false ? false : true; // 默认未读
|
||||||
maskFristEntry.value = fristEntry;
|
maskFristEntry.value = fristEntry;
|
||||||
if (fristEntry) {
|
if (fristEntry) {
|
||||||
uni.hideTabBar();
|
uni.hideTabBar();
|
||||||
}
|
}
|
||||||
// 预加载较重页面
|
// 预加载较重页面
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
uni.preloadPage({ url: '/packageA/pages/post/post' });
|
uni.preloadPage({ url: '/packageA/pages/post/post' });
|
||||||
uni.preloadPage({ url: '/pages/nearby/nearby' });
|
uni.preloadPage({ url: '/pages/nearby/nearby' });
|
||||||
uni.preloadPage({ url: '/pages/chat/chat' });
|
uni.preloadPage({ url: '/pages/chat/chat' });
|
||||||
uni.preloadPage({ url: '/packageA/pages/choiceness/choiceness' });
|
uni.preloadPage({ url: '/packageA/pages/choiceness/choiceness' });
|
||||||
}, 3000);
|
uni.preloadPage({ url: '/packageA/pages/reservation/reservation' });
|
||||||
|
uni.preloadPage({ url: '/packageA/pages/Intendedposition/Intendedposition' });
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
// 获取消息列表
|
// 获取消息列表
|
||||||
// useReadMsg().fetchMessages();
|
// useReadMsg().fetchMessages();
|
||||||
});
|
});
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
current: 0,
|
current: 0,
|
||||||
all: [{}],
|
all: [{}],
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handleTabChange(state.current);
|
handleTabChange(state.current);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handelComponentsRef = (el, index) => {
|
const handelComponentsRef = (el, index) => {
|
||||||
if (el) {
|
if (el) {
|
||||||
swiperRefs[index].value = el;
|
swiperRefs[index].value = el;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleTouchStart(e) {
|
function handleTouchStart(e) {
|
||||||
startPointX.value = e.touches[0].clientX;
|
startPointX.value = e.touches[0].clientX;
|
||||||
disableTouch.value = false;
|
disableTouch.value = false;
|
||||||
}
|
}
|
||||||
function handleTouchMove(e) {
|
function handleTouchMove(e) {
|
||||||
const currentX = e.touches[0].clientX;
|
const currentX = e.touches[0].clientX;
|
||||||
const diffX = currentX - startPointX.value;
|
const diffX = currentX - startPointX.value;
|
||||||
|
|
||||||
if (state.current === 0) {
|
if (state.current === 0) {
|
||||||
if (diffX > THRESHOLD) {
|
if (diffX > THRESHOLD) {
|
||||||
disableTouch.value = true;
|
disableTouch.value = true;
|
||||||
} else {
|
} else {
|
||||||
disableTouch.value = false;
|
disableTouch.value = false;
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (state.current === totalPage - 1) {
|
return;
|
||||||
if (diffX < -THRESHOLD) {
|
}
|
||||||
disableTouch.value = true;
|
if (state.current === totalPage - 1) {
|
||||||
} else {
|
if (diffX < -THRESHOLD) {
|
||||||
disableTouch.value = false;
|
disableTouch.value = true;
|
||||||
}
|
} else {
|
||||||
return;
|
disableTouch.value = false;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
disableTouch.value = false;
|
disableTouch.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeShowTabbar(val) {
|
function changeShowTabbar(val) {
|
||||||
showTabbar.value = val;
|
showTabbar.value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
//1 查看消息类型
|
//1 查看消息类型
|
||||||
function changeSwiperType(e) {
|
function changeSwiperType(e) {
|
||||||
const newIndex = e.detail.current;
|
const newIndex = e.detail.current;
|
||||||
const lastIndex = state.current;
|
const lastIndex = state.current;
|
||||||
|
|
||||||
const isSwipingRight = newIndex < lastIndex;
|
const isSwipingRight = newIndex < lastIndex;
|
||||||
const isSwipingLeft = newIndex > lastIndex;
|
const isSwipingLeft = newIndex > lastIndex;
|
||||||
|
|
||||||
if (lastIndex === 0 && isSwipingRight) {
|
if (lastIndex === 0 && isSwipingRight) {
|
||||||
disableTouch.value = true;
|
disableTouch.value = true;
|
||||||
state.current = 0;
|
state.current = 0;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
disableTouch.value = false;
|
disableTouch.value = false;
|
||||||
}, 50);
|
}, 50);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastIndex === totalPage - 1 && isSwipingLeft) {
|
if (lastIndex === totalPage - 1 && isSwipingLeft) {
|
||||||
disableTouch.value = true;
|
disableTouch.value = true;
|
||||||
state.current = lastIndex;
|
state.current = lastIndex;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
disableTouch.value = false;
|
disableTouch.value = false;
|
||||||
}, 50);
|
}, 50);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const index = e.detail.current;
|
const index = e.detail.current;
|
||||||
state.current = index;
|
state.current = index;
|
||||||
handleTabChange(index);
|
handleTabChange(index);
|
||||||
disableTouch.value = false;
|
disableTouch.value = false;
|
||||||
}
|
}
|
||||||
function changeType(index) {
|
function changeType(index) {
|
||||||
state.current = index;
|
state.current = index;
|
||||||
handleTabChange(index);
|
handleTabChange(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTabChange(index) {
|
function handleTabChange(index) {
|
||||||
if (!loadedMap[index]) {
|
if (!loadedMap[index]) {
|
||||||
swiperRefs[index].value?.loadData();
|
swiperRefs[index].value?.loadData();
|
||||||
loadedMap[index] = true;
|
loadedMap[index] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSwiperMsgType(e) {
|
function changeSwiperMsgType(e) {
|
||||||
const currented = e.detail.current;
|
const currented = e.detail.current;
|
||||||
state.current = currented;
|
state.current = currented;
|
||||||
}
|
}
|
||||||
// mask
|
// mask
|
||||||
function closeFristEntry() {
|
function closeFristEntry() {
|
||||||
uni.setStorageSync('fristEntry', false);
|
uni.setStorageSync('fristEntry', false);
|
||||||
maskFristEntry.value = false;
|
maskFristEntry.value = false;
|
||||||
uni.showTabBar();
|
uni.showTabBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
function goExperience() {
|
function goExperience() {
|
||||||
closeFristEntry();
|
closeFristEntry();
|
||||||
uni.showTabBar();
|
uni.showTabBar();
|
||||||
state.current = 1;
|
state.current = 1;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -214,7 +213,7 @@ function goExperience() {
|
|||||||
height: calc(100% - var(--window-bottom));
|
height: calc(100% - var(--window-bottom));
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.app-container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="AI+就业服务程序">
|
<AppLayout title="就业服务程序">
|
||||||
<tabcontrolVue :current="tabCurrent">
|
<tabcontrolVue :current="tabCurrent">
|
||||||
<template v-slot:tab0>
|
<template v-slot:tab0>
|
||||||
<view class="login-content">
|
<view class="login-content">
|
||||||
@@ -109,6 +109,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</tabcontrolVue>
|
</tabcontrolVue>
|
||||||
<SelectJobs ref="selectJobsModel"></SelectJobs>
|
<SelectJobs ref="selectJobsModel"></SelectJobs>
|
||||||
|
<!-- 后门 -->
|
||||||
<view class="backdoor" @click="loginbackdoor">
|
<view class="backdoor" @click="loginbackdoor">
|
||||||
<uni-icons type="gift-filled" size="30"></uni-icons>
|
<uni-icons type="gift-filled" size="30"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
@@ -153,6 +154,7 @@ const fromValue = reactive({
|
|||||||
|
|
||||||
onLoad((parmas) => {
|
onLoad((parmas) => {
|
||||||
getTreeselect();
|
getTreeselect();
|
||||||
|
$api.msg('请完善微简历');
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
@@ -283,7 +285,7 @@ function loginTest() {
|
|||||||
password: 'test',
|
password: 'test',
|
||||||
};
|
};
|
||||||
$api.createRequest('/app/login', params, 'post').then((resData) => {
|
$api.createRequest('/app/login', params, 'post').then((resData) => {
|
||||||
$api.msg('模拟帐号密码测试登录成功');
|
$api.msg('模拟帐号密码测试登录成功, 测试环境使用模拟定位');
|
||||||
loginSetToken(resData.token).then((resume) => {
|
loginSetToken(resData.token).then((resume) => {
|
||||||
if (resume.data.jobTitleId) {
|
if (resume.data.jobTitleId) {
|
||||||
// 设置推荐列表,每次退出登录都需要更新
|
// 设置推荐列表,每次退出登录都需要更新
|
||||||
@@ -312,8 +314,8 @@ function complete() {
|
|||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.backdoor{
|
.backdoor{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 24rpx;
|
||||||
bottom: 300rpx;
|
top: 100rpx;
|
||||||
}
|
}
|
||||||
.input-nx
|
.input-nx
|
||||||
position: relative
|
position: relative
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="row-right">已认证</view>
|
<view class="row-right">已认证</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="main-row btn-feel">
|
<view class="main-row btn-feel" @click="handleItemClick('素质测评')">
|
||||||
<view class="row-left">
|
<view class="row-left">
|
||||||
<image class="left-img" src="@/static/icon/server2.png"></image>
|
<image class="left-img" src="@/static/icon/server2.png"></image>
|
||||||
<text class="left-text">素质测评</text>
|
<text class="left-text">素质测评</text>
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<uni-icons color="#909090" type="right" size="14"></uni-icons>
|
<uni-icons color="#909090" type="right" size="14"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="main-row btn-feel">
|
<view class="main-row btn-feel" @click="handleItemClick('模拟面试')">
|
||||||
<view class="row-left">
|
<view class="row-left">
|
||||||
<image class="left-img" src="@/static/icon/server3.png"></image>
|
<image class="left-img" src="@/static/icon/server3.png"></image>
|
||||||
<text class="left-text">AI面试</text>
|
<text class="left-text">AI面试</text>
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
<view class="row-right">已开启</view>
|
<view class="row-right">已开启</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="card-back button-click" @click="logOut">退出登录</view>
|
<!-- <view class="card-back button-click" @click="logOut">退出登录</view> -->
|
||||||
<uni-popup ref="popup" type="dialog">
|
<uni-popup ref="popup" type="dialog">
|
||||||
<uni-popup-dialog
|
<uni-popup-dialog
|
||||||
mode="base"
|
mode="base"
|
||||||
@@ -107,6 +107,7 @@ import { storeToRefs } from 'pinia';
|
|||||||
import Tabbar from '@/components/tabbar/midell-box.vue';
|
import Tabbar from '@/components/tabbar/midell-box.vue';
|
||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
import FileUploader from '@/utils/FileUploader.js';
|
import FileUploader from '@/utils/FileUploader.js';
|
||||||
|
import config from '@/config';
|
||||||
const { $api, navTo } = inject('globalFunction');
|
const { $api, navTo } = inject('globalFunction');
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
const popup = ref(null);
|
const popup = ref(null);
|
||||||
@@ -137,6 +138,28 @@ function selectFile() {
|
|||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
function chooseFileUploadTest(pam) {}
|
function chooseFileUploadTest(pam) {}
|
||||||
|
|
||||||
|
const handleItemClick = (item) => {
|
||||||
|
switch (item) {
|
||||||
|
case '素质测评':
|
||||||
|
lightAppJssdk.navigation.hide({
|
||||||
|
url: config.Quality_assessment_URL,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case '就业指导':
|
||||||
|
lightAppJssdk.navigation.hide({
|
||||||
|
url: config.Career_guidance,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case '模拟面试':
|
||||||
|
lightAppJssdk.navigation.hide({
|
||||||
|
url: config.mock_interview,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$api.msg('暂未开放');
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@@ -280,6 +303,7 @@ function chooseFileUploadTest(pam) {}
|
|||||||
overflow: hidden
|
overflow: hidden
|
||||||
border-radius: 50%
|
border-radius: 50%
|
||||||
margin-right: 22rpx;
|
margin-right: 22rpx;
|
||||||
|
background: #e8e8e8;
|
||||||
.userindo-head-img
|
.userindo-head-img
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -180,16 +180,14 @@ function changeSwiperMsgType(e) {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.container-header {
|
.container-header {
|
||||||
height: calc(88rpx - 14rpx);
|
|
||||||
text-align: center;
|
|
||||||
line-height: calc(88rpx - 14rpx);
|
|
||||||
font-size: 32rpx;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 16rpx 44rpx 36rpx 44rpx;
|
padding: 16rpx 44rpx 36rpx 44rpx;
|
||||||
background: url('@/static/icon/msgTopbg.png') 0 0 no-repeat;
|
background: url('@/static/icon/msgTopbg.png') 0 0 no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-top: calc(var(--window-top) + var(--status-bar-height) + 20rpx);
|
||||||
.header-title {
|
.header-title {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<scroll-view scroll-y class="main-scroll">
|
<scroll-view scroll-y class="main-scroll">
|
||||||
<view class="scrollmain">
|
<view v-if="msgList.length" class="scrollmain">
|
||||||
<view
|
<view
|
||||||
class="list-card press-button"
|
class="list-card press-button"
|
||||||
v-for="(item, index) in msgList"
|
v-for="(item, index) in msgList"
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<empty v-if="!msgList.length"></empty>
|
<empty v-if="!msgList.length"></empty>
|
||||||
</view>
|
</view>
|
||||||
|
<empty v-else pdTop="200" content="暂无消息~"></empty>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<scroll-view scroll-y class="main-scroll">
|
<scroll-view scroll-y class="main-scroll">
|
||||||
<view class="scrollmain">
|
<view v-if="unreadMsgList.length" class="scrollmain">
|
||||||
<view
|
<view
|
||||||
class="list-card press-button"
|
class="list-card press-button"
|
||||||
v-for="(item, index) in unreadMsgList"
|
v-for="(item, index) in unreadMsgList"
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<empty v-if="!unreadMsgList.length"></empty>
|
<empty v-if="!unreadMsgList.length"></empty>
|
||||||
</view>
|
</view>
|
||||||
|
<empty v-else pdTop="200" content="暂无消息~"></empty>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppLayout title="附近" :use-scroll-view="false" :show-bg-image="false">
|
<AppLayout title="附近" :use-scroll-view="false" :show-bg-image="false">
|
||||||
<template #headerleft>
|
<template #headerleft v-if="isMiniProgram">
|
||||||
<view class="btnback">
|
<view class="btnback">
|
||||||
<image src="@/static/icon/back.png" @click="navBack"></image>
|
<image src="@/static/icon/back.png" @click="navBack"></image>
|
||||||
</view>
|
</view>
|
||||||
@@ -50,6 +50,9 @@ import threeComponent from './components/three.vue';
|
|||||||
import fourComponent from './components/four.vue';
|
import fourComponent from './components/four.vue';
|
||||||
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const { $api, debounce, throttle, navBack } = inject('globalFunction');
|
const { $api, debounce, throttle, navBack } = inject('globalFunction');
|
||||||
const loadedMap = reactive([false, false, false, false]);
|
const loadedMap = reactive([false, false, false, false]);
|
||||||
const swiperRefs = [ref(null), ref(null), ref(null), ref(null)];
|
const swiperRefs = [ref(null), ref(null), ref(null), ref(null)];
|
||||||
|
|||||||
@@ -2,7 +2,12 @@
|
|||||||
<view class="container">
|
<view class="container">
|
||||||
<view>
|
<view>
|
||||||
<view class="top">
|
<view class="top">
|
||||||
<image class="btnback button-click" src="@/static/icon/back.png" @click="navBack"></image>
|
<image
|
||||||
|
v-if="isMiniProgram"
|
||||||
|
class="btnback button-click"
|
||||||
|
src="@/static/icon/back.png"
|
||||||
|
@click="navBack"
|
||||||
|
></image>
|
||||||
<view class="search-box">
|
<view class="search-box">
|
||||||
<uni-icons
|
<uni-icons
|
||||||
class="iconsearch"
|
class="iconsearch"
|
||||||
@@ -91,6 +96,8 @@ import { useColumnCount } from '@/hook/useColumnCount';
|
|||||||
import { usePagination } from '@/hook/usePagination';
|
import { usePagination } from '@/hook/usePagination';
|
||||||
import img from '@/static/icon/filter.png';
|
import img from '@/static/icon/filter.png';
|
||||||
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
|
||||||
|
import useUserStore from '@/stores/useUserStore';
|
||||||
|
const { isMiniProgram } = storeToRefs(useUserStore());
|
||||||
const searchValue = ref('');
|
const searchValue = ref('');
|
||||||
const historyList = ref([]);
|
const historyList = ref([]);
|
||||||
const listCom = ref([]);
|
const listCom = ref([]);
|
||||||
@@ -253,9 +260,10 @@ function getJobList(type = 'add') {
|
|||||||
const str = pageState.pageSize * (pageState.page - 1);
|
const str = pageState.pageSize * (pageState.page - 1);
|
||||||
const end = listCom.value.length;
|
const end = listCom.value.length;
|
||||||
const reslist = rows;
|
const reslist = rows;
|
||||||
listCom.value.splice(str, end, ...reslist);
|
// listCom.value.splice(str, end, ...reslist);
|
||||||
|
listCom.value = [...listCom.value, ...reslist];
|
||||||
} else {
|
} else {
|
||||||
listCom.value = rows;
|
listCom.value = [...rows];
|
||||||
}
|
}
|
||||||
pageState.total = resData.total;
|
pageState.total = resData.total;
|
||||||
pageState.maxPage = Math.ceil(pageState.total / pageState.pageSize);
|
pageState.maxPage = Math.ceil(pageState.total / pageState.pageSize);
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 995 B After Width: | Height: | Size: 984 B |
|
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 414 B |
BIN
static/icon/add-circle.png
Normal file
|
After Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 209 B |
|
Before Width: | Height: | Size: 543 B After Width: | Height: | Size: 533 B |
BIN
static/icon/ai-card-bg.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 187 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 171 B |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
static/icon/bottom-card-bg.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 751 B After Width: | Height: | Size: 739 B |
|
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 217 B |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 843 B After Width: | Height: | Size: 834 B |
|
Before Width: | Height: | Size: 542 B After Width: | Height: | Size: 514 B |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 504 B |
|
Before Width: | Height: | Size: 443 B After Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 500 B |
|
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 557 B |
|
Before Width: | Height: | Size: 734 B After Width: | Height: | Size: 730 B |
BIN
static/icon/flame3.png
Normal file
|
After Width: | Height: | Size: 764 B |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 740 B After Width: | Height: | Size: 736 B |
BIN
static/icon/index-robot.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
static/icon/index-search.png
Normal file
|
After Width: | Height: | Size: 347 B |
BIN
static/icon/index-text-bg.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
static/icon/index-text-bg2.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
static/icon/item-bg-img1.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
static/icon/item-bg-img2.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
static/icon/item-bg-img3.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
static/icon/item-bg-text.png
Normal file
|
After Width: | Height: | Size: 775 B |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
static/icon/leart-gold.png
Normal file
|
After Width: | Height: | Size: 359 B |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.8 KiB |
BIN
static/icon/match-card-bg.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 1.2 KiB |