31 Commits

Author SHA1 Message Date
Apcallover
80213b18e9 flat: 微调 2025-12-16 20:24:03 +08:00
4a03b4d4cb feat : 新增一体机支付宝扫码登录页 2025-12-16 16:51:56 +08:00
Apcallover
77dfab84f1 flat: 暂存,新增一体机sdk,和一体机环境 2025-12-16 15:36:42 +08:00
33f1d0a8ab 修改宽屏判断阈值 2025-12-16 10:34:40 +08:00
92d87347d0 Merge branch 'main-ALL-IN-ONE' of http://124.243.245.42:3000/sdz/qingdao-employment-service into main-ALL-IN-ONE 2025-12-16 09:31:56 +08:00
add2cfeac4 静态资源压缩 2025-12-16 09:31:54 +08:00
Apcallover
8e316cf2a1 flat: 2025-12-16 09:30:45 +08:00
Apcallover
d6bf2648de Merge branch 'main-ALL-IN-ONE' of http://124.243.245.42:3000/sdz/qingdao-employment-service into main-ALL-IN-ONE 2025-12-16 09:25:54 +08:00
0a2d523a40 fix 2025-12-16 09:25:02 +08:00
8a138bed99 fix 文案 2025-12-16 09:23:18 +08:00
Apcallover
d9f0356491 flat:修改 2025-12-16 09:22:57 +08:00
ff941848b1 fix 2025-12-16 09:20:42 +08:00
e19673b99e delete 2025-12-15 17:58:12 +08:00
7260043942 style 2025-12-15 17:42:53 +08:00
c351bfa54f style 2025-12-15 17:39:08 +08:00
dd81468f47 feat : 对接简历匹配职位接口 修改样式 2025-12-15 17:37:10 +08:00
79207ee66a fix 2025-12-15 16:09:22 +08:00
215ec11fe7 Merge branch 'main-ALL-IN-ONE' of http://124.243.245.42:3000/sdz/qingdao-employment-service into main-ALL-IN-ONE 2025-12-15 16:08:46 +08:00
74f13d26a8 fix 下拉加载 2025-12-15 16:04:08 +08:00
Apcallover
e6cb12659d flat: 修改 2025-12-15 15:56:47 +08:00
4571744f2e fix 2025-12-15 15:46:06 +08:00
3ce8e65abc fix 2025-12-15 15:43:12 +08:00
159efd166a fix 适配 2025-12-15 15:40:16 +08:00
817fa27136 fix 聊天页tabbar显示隐藏 2025-12-15 15:23:30 +08:00
cb9f626788 fix 1080 2025-12-15 15:20:44 +08:00
330eec226f feat: 一体机适配 2025-12-15 15:11:11 +08:00
4983d9cbc7 暂时提交 2025-12-15 10:54:30 +08:00
fa1132ebe9 临时style适配 2025-12-12 16:35:02 +08:00
30764cec57 fix 传参 2025-12-12 10:50:45 +08:00
cb1052346e feat : 足迹日期选择新增有记录的日期项; request改为proxy + header url 2025-12-11 14:04:17 +08:00
Apcallover
2b1a87b65e flat: 未知 2025-12-10 11:20:05 +08:00
86 changed files with 3767 additions and 376 deletions

59
App.vue
View File

@@ -6,32 +6,41 @@ import usePageAnimation from './hook/usePageAnimation';
import useDictStore from './stores/useDictStore';
const { $api, navTo, appendScriptTagElement, aes_Decrypt, sm2_Decrypt, safeReLaunch } = inject('globalFunction');
import config from '@/config.js';
import baseDB from '@/utils/db.js';
usePageAnimation();
const appword = 'aKd20dbGdFvmuwrt'; // 固定值
onLaunch((options) => {
// uni.hideTabBar();
useDictStore().getDictData();
try {
if (lightAppJssdk.user) {
console.warn('爱山东环境');
getUserInfo();
useUserStore().changMiniProgramAppStatus(false);
} catch {
console.log('不是爱山东平台,使用测试登陆');
useUserStore().changMachineEnv(false);
return;
}
if (isY9MachineType()) {
console.warn('求职一体机环境');
baseDB.resetAndReinit(); // 清空indexdb
useUserStore().logOutApp();
useUserStore().changMiniProgramAppStatus(true);
useUserStore().initSeesionId(); //更新
let token = uni.getStorageSync('token') || ''; // 同步获取 缓存信息
if (token) {
useUserStore()
.loginSetToken(token)
.then(() => {
$api.msg('登录成功');
});
} else {
safeReLaunch('/pages/login/login');
// uni.redirectTo({
// url: '/pages/login/login',
// });
}
useUserStore().changMachineEnv(true);
return;
}
// 正式上线去除此方法
console.warn('浏览器环境');
useUserStore().changMiniProgramAppStatus(true);
useUserStore().changMachineEnv(false);
useUserStore().initSeesionId(); //更新
let token = uni.getStorageSync('token') || '';
if (token) {
useUserStore()
.loginSetToken(token)
.then(() => {
$api.msg('登录成功');
});
} else {
safeReLaunch('/pages/login/login');
}
});
@@ -45,6 +54,12 @@ onHide(() => {
console.log('App Hide');
});
function isY9MachineType() {
const ua = navigator.userAgent;
const isY9Machine = /Y9-ZYYH/i.test(ua); // 匹配机器型号
return isY9Machine;
}
function getUserInfo() {
lightAppJssdk.user.getUserInfoWithEncryptedParamByAppId({
appId: config.appInfo.loveShandong, // 接入方在成功创建应用后自动生成
@@ -111,15 +126,9 @@ function loginCallback(userInfo) {
.then((resume) => {
if (resume.data.jobTitleId) {
useUserStore().initSeesionId();
// uni.reLaunch({
// url: '/pages/index/index',
// });
safeReLaunch('/pages/index/index');
} else {
safeReLaunch('/pages/login/login');
// uni.redirectTo({
// url: '/pages/login/login',
// });
}
});
});
@@ -183,7 +192,7 @@ uni-modal,
@font-face {
font-family: DIN-Medium;
src: url('https://qd.zhaopinzao8dian.com/file/csn/DIN-Medium.woff2') format('woff2');
src: url('./static/font/DIN-Medium.woff2') format('woff2');
font-display: swap;
}

32
common/wide-screen.css Normal file
View File

@@ -0,0 +1,32 @@
/* toast大小改为rpx */
uni-toast .uni-sample-toast {
width: 300rpx !important;
}
uni-toast .uni-simple-toast__text {
font-size: 30rpx !important;
padding: 15rpx 25rpx !important;
border-radius: 15rpx !important;
}
uni-toast .uni-toast {
width: 160rpx !important;
padding: 15rpx 25rpx !important;
border-radius: 15rpx !important;
}
uni-toast .uni-toast__icon {
width: 45rpx !important;
height: 45rpx !important;
}
uni-toast .uni-toast__content {
font-size: 30rpx !important;
}
.uni-load-more{
height: 40rpx !important;
}
.uni-load-more svg{
height: 30rpx !important;
width: 30rpx !important;
}
.uni-load-more__text{
font-size: 30rpx !important;
}

View File

@@ -27,7 +27,7 @@
</view>
<!-- 主体内容区域 -->
<view class="container-main">
<view class="container-main" :style="{ backgroundColor: mainbackGroundColor }">
<scroll-view v-if="useScrollView" scroll-y class="main-scroll" @scrolltolower="handleScrollToLower">
<slot></slot>
</scroll-view>
@@ -70,6 +70,10 @@ defineProps({
type: String,
default: '#ffffff',
},
mainbackGroundColor: {
type: String,
default: '',
},
useScrollView: {
type: Boolean,
default: true,

View File

@@ -0,0 +1,664 @@
.uniui-cart-filled:before {
content: "\e6d0";
}
.uniui-gift-filled:before {
content: "\e6c4";
}
.uniui-color:before {
content: "\e6cf";
}
.uniui-wallet:before {
content: "\e6b1";
}
.uniui-settings-filled:before {
content: "\e6ce";
}
.uniui-auth-filled:before {
content: "\e6cc";
}
.uniui-shop-filled:before {
content: "\e6cd";
}
.uniui-staff-filled:before {
content: "\e6cb";
}
.uniui-vip-filled:before {
content: "\e6c6";
}
.uniui-plus-filled:before {
content: "\e6c7";
}
.uniui-folder-add-filled:before {
content: "\e6c8";
}
.uniui-color-filled:before {
content: "\e6c9";
}
.uniui-tune-filled:before {
content: "\e6ca";
}
.uniui-calendar-filled:before {
content: "\e6c0";
}
.uniui-notification-filled:before {
content: "\e6c1";
}
.uniui-wallet-filled:before {
content: "\e6c2";
}
.uniui-medal-filled:before {
content: "\e6c3";
}
.uniui-fire-filled:before {
content: "\e6c5";
}
.uniui-refreshempty:before {
content: "\e6bf";
}
.uniui-location-filled:before {
content: "\e6af";
}
.uniui-person-filled:before {
content: "\e69d";
}
.uniui-personadd-filled:before {
content: "\e698";
}
.uniui-arrowthinleft:before {
content: "\e6d2";
}
.uniui-arrowthinup:before {
content: "\e6d3";
}
.uniui-arrowthindown:before {
content: "\e6d4";
}
.uniui-back:before {
content: "\e6b9";
}
.uniui-forward:before {
content: "\e6ba";
}
.uniui-arrow-right:before {
content: "\e6bb";
}
.uniui-arrow-left:before {
content: "\e6bc";
}
.uniui-arrow-up:before {
content: "\e6bd";
}
.uniui-arrow-down:before {
content: "\e6be";
}
.uniui-arrowthinright:before {
content: "\e6d1";
}
.uniui-down:before {
content: "\e6b8";
}
.uniui-bottom:before {
content: "\e6b8";
}
.uniui-arrowright:before {
content: "\e6d5";
}
.uniui-right:before {
content: "\e6b5";
}
.uniui-up:before {
content: "\e6b6";
}
.uniui-top:before {
content: "\e6b6";
}
.uniui-left:before {
content: "\e6b7";
}
.uniui-arrowup:before {
content: "\e6d6";
}
.uniui-eye:before {
content: "\e651";
}
.uniui-eye-filled:before {
content: "\e66a";
}
.uniui-eye-slash:before {
content: "\e6b3";
}
.uniui-eye-slash-filled:before {
content: "\e6b4";
}
.uniui-info-filled:before {
content: "\e649";
}
.uniui-reload:before {
content: "\e6b2";
}
.uniui-micoff-filled:before {
content: "\e6b0";
}
.uniui-map-pin-ellipse:before {
content: "\e6ac";
}
.uniui-map-pin:before {
content: "\e6ad";
}
.uniui-location:before {
content: "\e6ae";
}
.uniui-starhalf:before {
content: "\e683";
}
.uniui-star:before {
content: "\e688";
}
.uniui-star-filled:before {
content: "\e68f";
}
.uniui-calendar:before {
content: "\e6a0";
}
.uniui-fire:before {
content: "\e6a1";
}
.uniui-medal:before {
content: "\e6a2";
}
.uniui-font:before {
content: "\e6a3";
}
.uniui-gift:before {
content: "\e6a4";
}
.uniui-link:before {
content: "\e6a5";
}
.uniui-notification:before {
content: "\e6a6";
}
.uniui-staff:before {
content: "\e6a7";
}
.uniui-vip:before {
content: "\e6a8";
}
.uniui-folder-add:before {
content: "\e6a9";
}
.uniui-tune:before {
content: "\e6aa";
}
.uniui-auth:before {
content: "\e6ab";
}
.uniui-person:before {
content: "\e699";
}
.uniui-email-filled:before {
content: "\e69a";
}
.uniui-phone-filled:before {
content: "\e69b";
}
.uniui-phone:before {
content: "\e69c";
}
.uniui-email:before {
content: "\e69e";
}
.uniui-personadd:before {
content: "\e69f";
}
.uniui-chatboxes-filled:before {
content: "\e692";
}
.uniui-contact:before {
content: "\e693";
}
.uniui-chatbubble-filled:before {
content: "\e694";
}
.uniui-contact-filled:before {
content: "\e695";
}
.uniui-chatboxes:before {
content: "\e696";
}
.uniui-chatbubble:before {
content: "\e697";
}
.uniui-upload-filled:before {
content: "\e68e";
}
.uniui-upload:before {
content: "\e690";
}
.uniui-weixin:before {
content: "\e691";
}
.uniui-compose:before {
content: "\e67f";
}
.uniui-qq:before {
content: "\e680";
}
.uniui-download-filled:before {
content: "\e681";
}
.uniui-pyq:before {
content: "\e682";
}
.uniui-sound:before {
content: "\e684";
}
.uniui-trash-filled:before {
content: "\e685";
}
.uniui-sound-filled:before {
content: "\e686";
}
.uniui-trash:before {
content: "\e687";
}
.uniui-videocam-filled:before {
content: "\e689";
}
.uniui-spinner-cycle:before {
content: "\e68a";
}
.uniui-weibo:before {
content: "\e68b";
}
.uniui-videocam:before {
content: "\e68c";
}
.uniui-download:before {
content: "\e68d";
}
.uniui-help:before {
content: "\e679";
}
.uniui-navigate-filled:before {
content: "\e67a";
}
.uniui-plusempty:before {
content: "\e67b";
}
.uniui-smallcircle:before {
content: "\e67c";
}
.uniui-minus-filled:before {
content: "\e67d";
}
.uniui-micoff:before {
content: "\e67e";
}
.uniui-closeempty:before {
content: "\e66c";
}
.uniui-clear:before {
content: "\e66d";
}
.uniui-navigate:before {
content: "\e66e";
}
.uniui-minus:before {
content: "\e66f";
}
.uniui-image:before {
content: "\e670";
}
.uniui-mic:before {
content: "\e671";
}
.uniui-paperplane:before {
content: "\e672";
}
.uniui-close:before {
content: "\e673";
}
.uniui-help-filled:before {
content: "\e674";
}
.uniui-paperplane-filled:before {
content: "\e675";
}
.uniui-plus:before {
content: "\e676";
}
.uniui-mic-filled:before {
content: "\e677";
}
.uniui-image-filled:before {
content: "\e678";
}
.uniui-locked-filled:before {
content: "\e668";
}
.uniui-info:before {
content: "\e669";
}
.uniui-locked:before {
content: "\e66b";
}
.uniui-camera-filled:before {
content: "\e658";
}
.uniui-chat-filled:before {
content: "\e659";
}
.uniui-camera:before {
content: "\e65a";
}
.uniui-circle:before {
content: "\e65b";
}
.uniui-checkmarkempty:before {
content: "\e65c";
}
.uniui-chat:before {
content: "\e65d";
}
.uniui-circle-filled:before {
content: "\e65e";
}
.uniui-flag:before {
content: "\e65f";
}
.uniui-flag-filled:before {
content: "\e660";
}
.uniui-gear-filled:before {
content: "\e661";
}
.uniui-home:before {
content: "\e662";
}
.uniui-home-filled:before {
content: "\e663";
}
.uniui-gear:before {
content: "\e664";
}
.uniui-smallcircle-filled:before {
content: "\e665";
}
.uniui-map-filled:before {
content: "\e666";
}
.uniui-map:before {
content: "\e667";
}
.uniui-refresh-filled:before {
content: "\e656";
}
.uniui-refresh:before {
content: "\e657";
}
.uniui-cloud-upload:before {
content: "\e645";
}
.uniui-cloud-download-filled:before {
content: "\e646";
}
.uniui-cloud-download:before {
content: "\e647";
}
.uniui-cloud-upload-filled:before {
content: "\e648";
}
.uniui-redo:before {
content: "\e64a";
}
.uniui-images-filled:before {
content: "\e64b";
}
.uniui-undo-filled:before {
content: "\e64c";
}
.uniui-more:before {
content: "\e64d";
}
.uniui-more-filled:before {
content: "\e64e";
}
.uniui-undo:before {
content: "\e64f";
}
.uniui-images:before {
content: "\e650";
}
.uniui-paperclip:before {
content: "\e652";
}
.uniui-settings:before {
content: "\e653";
}
.uniui-search:before {
content: "\e654";
}
.uniui-redo-filled:before {
content: "\e655";
}
.uniui-list:before {
content: "\e644";
}
.uniui-mail-open-filled:before {
content: "\e63a";
}
.uniui-hand-down-filled:before {
content: "\e63c";
}
.uniui-hand-down:before {
content: "\e63d";
}
.uniui-hand-up-filled:before {
content: "\e63e";
}
.uniui-hand-up:before {
content: "\e63f";
}
.uniui-heart-filled:before {
content: "\e641";
}
.uniui-mail-open:before {
content: "\e643";
}
.uniui-heart:before {
content: "\e639";
}
.uniui-loop:before {
content: "\e633";
}
.uniui-pulldown:before {
content: "\e632";
}
.uniui-scan:before {
content: "\e62a";
}
.uniui-bars:before {
content: "\e627";
}
.uniui-checkbox:before {
content: "\e62b";
}
.uniui-checkbox-filled:before {
content: "\e62c";
}
.uniui-shop:before {
content: "\e62f";
}
.uniui-headphones:before {
content: "\e630";
}
.uniui-cart:before {
content: "\e631";
}

View File

@@ -0,0 +1,664 @@
export type IconsData = {
id : string
name : string
font_family : string
css_prefix_text : string
description : string
glyphs : Array<IconsDataItem>
}
export type IconsDataItem = {
font_class : string
unicode : string
}
export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
] as IconsDataItem[]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

Binary file not shown.

View File

@@ -0,0 +1,110 @@
<template>
<!-- #ifdef APP-NVUE -->
<text :style="styleObj" class="my-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="styleObj" class="my-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
<slot></slot>
</text>
<!-- #endif -->
</template>
<script>
import { fontData } from './my-icons_file_vue.js';
const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val)) ? val + 'rpx' : val;
}
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './my-icons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "my-icons",
'src': "url('" + iconUrl + "')"
});
// #endif
/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'my-icons',
emits: ['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ''
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {
icons: fontData
}
},
computed: {
unicode() {
let code = this.icons.find(v => v.font_class === this.type)
if (code) {
return code.unicode
}
return ''
},
iconSize() {
return getVal(this.size)
},
styleObj() {
if (this.fontFamily !== '') {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
}
return `color: ${this.color}; font-size: ${this.iconSize};`
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
@import './my-icons.css';
@font-face {
font-family: my-icons;
src: url('./my-icons.ttf');
}
/* #endif */
.my-icons {
font-family: my-icons;
text-decoration: none;
text-align: center;
}
</style>

View File

@@ -0,0 +1,649 @@
export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

View File

@@ -1,7 +1,7 @@
<template>
<view class="expected-station">
<view class="sex-search" v-if="search">
<uni-icons class="iconsearch" type="search" size="20"></uni-icons>
<my-icons class="iconsearch" type="search" size="40"></my-icons>
<input class="uni-input searchinput" confirm-type="search" />
</view>
<view class="sex-content">

View File

@@ -4,7 +4,7 @@
<!-- 头部 -->
<view class="modal-header">
<text class="back-btn" @click="handleClose">
<uni-icons type="left" size="24"></uni-icons>
<my-icons type="left" size="48"></my-icons>
</text>
<text class="modal-title">{{ title }}</text>
<view class="back-btn"></view>

View File

@@ -21,6 +21,12 @@
<script setup>
import { ref, onMounted, computed } from 'vue';
import { useReadMsg } from '@/stores/useReadMsg';
import useScreenStore from '@/stores/useScreenStore'
const screenStore = useScreenStore()
const {isWideScreen} = screenStore
const props = defineProps({
currentpage: {
type: Number,
@@ -79,7 +85,7 @@ const tabbarList = computed(() => [
]);
onMounted(() => {
uni.hideTabBar();
if(isWideScreen)uni.hideTabBar();
currentItem.value = props.currentpage;
});

View File

@@ -4,11 +4,12 @@ export default {
// baseUrl: 'http://192.168.3.29:8081',
// baseUrl: 'http://10.213.6.207:19010/api',
// 语音转文字
// vioceBaseURl: 'wss://qd.zhaopinzao8dian.com/api/system/asr/connect', // 自定义
vioceBaseURl: 'wss://fw.rc.qingdao.gov.cn/rgpp-api/api/system/asr/connect', // 内网
vioceBaseURl: 'wss://qd.zhaopinzao8dian.com/api/app/asr/connect', // 自定义
// vioceBaseURl: 'wss://fw.rc.qingdao.gov.cn/rgpp-api/api/app/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: 'http://39.98.44.136:19527', //直接替换即可
// indexedDB
DBversion: 3,
// 只使用本地缓寸的数据

View File

@@ -8,11 +8,13 @@
export class PiperTTS {
constructor(config = {}) {
this.baseUrl = config.baseUrl || 'http://localhost:5001';
this.wsUrl = config.wsUrl || '/ws/synthesize'
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; // 下一段音频的预定播放时间
@@ -56,7 +58,7 @@ export class PiperTTS {
this.onStatus('正在建立连接...', 'processing');
try {
const wsUrl = this.baseUrl.replace(/^http/, 'ws') + '/ws/synthesize';
const wsUrl = this.baseUrl.replace(/^http/, 'ws') + this.wsUrl;
this.ws = new WebSocket(wsUrl);
this.ws.binaryType = 'arraybuffer';

View File

@@ -6,6 +6,10 @@ import {
watch
} from 'vue'
import useScreenStore from '@/stores/useScreenStore'
const screenStore = useScreenStore()
export function useColumnCount(onChange = () => {}) {
const columnCount = ref(0)
const columnSpace = ref(2)
@@ -20,18 +24,21 @@ export function useColumnCount(onChange = () => {}) {
// }
// }
const calcColumn = () => {
const width = uni.getSystemInfoSync().windowWidth
// const width = uni.getSystemInfoSync().windowWidth
const {foldFeature,foldCount} = screenStore
let count = 2
if (width >= 1000) {
count = 5
} else if (width >= 750) {
count = 4
} else if (width >= 500) {
count = 3
} else {
count = 2
}
//折叠屏2*屏幕数量
if(foldFeature) count = foldCount * 2
else count = 2
// if (width >= 1000) {
// count = 5
// } else if (width >= 750) {
// count = 4
// } else if (width >= 500) {
// count = 3
// } else {
// count = 2
// }
if (count !== columnCount.value) {
columnCount.value = count

View File

@@ -22,17 +22,19 @@
<script>
eruda.init();
</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>
// VConsole 默认会挂载到 `window.VConsole` 上
var vConsole = new window.VConsole();
</script> -->
</script>
<!-- 爱山东jssdk 本sdk存在性能问题 -->
<script type="text/javascript" src="./static/js/jsbridge.js"></script>
<!-- <script type="text/javascript" src="./static/js/jweixin-1.4.0.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/pixi.min.js"></script>
</head>
<body>
<div id="app"><!--app-html--></div>

View File

@@ -6,6 +6,7 @@ import {
import globalFunction from '@/common/globalFunction'
import '@/lib/string-similarity.min.js'
import similarityJobs from '@/utils/similarity_Job.js';
import useScreenStore from './stores/useScreenStore'
// 组件
import AppLayout from './components/AppLayout/AppLayout.vue';
@@ -22,6 +23,7 @@ import renderDeliveryRecord from '@/components/renderDeliveryRecord/renderDelive
import renderJobCollectionRecord from '@/components/renderJobCollectionRecord/renderJobCollectionRecord.vue';
import renderCompanyCollectionRecord from '@/components/renderCompanyCollectionRecord/renderCompanyCollectionRecord.vue';
import renderJobViewRecord from '@/components/renderJobViewRecord/renderJobViewRecord.vue';
import MyIcons from '@/components/My-icons/my-icons.vue';
// import Tabbar from '@/components/tabbar/midell-box.vue'
// 自动导入 directives 目录下所有指令
console.log(lightAppJssdk)
@@ -33,8 +35,7 @@ import {
createSSRApp,
} from 'vue'
const foldFeature = window.visualViewport && 'segments' in window.visualViewport
console.log('是否支持多段屏幕:', foldFeature)
// 全局组件
export function createApp() {
@@ -53,6 +54,7 @@ export function createApp() {
app.component('renderJobCollectionRecord', renderJobCollectionRecord) //渲染岗位收藏记录
app.component('renderCompanyCollectionRecord', renderCompanyCollectionRecord) //渲染公司收藏记录
app.component('renderJobViewRecord', renderJobViewRecord) //渲染岗位浏览记录
app.component('MyIcons', MyIcons)
// app.component('tabbar-custom', Tabbar)
for (const path in directives) {
@@ -74,6 +76,9 @@ export function createApp() {
store.use(createUnistorage());
app.use(store);
// 初始化屏幕检测
const screenStore = useScreenStore()
screenStore.initScreenDetection()
return {
app,
Pinia

View File

@@ -1,14 +1,27 @@
<template>
<view class="collection-content">
<renderDeliveryRecord
v-if="pageState.list.length"
seeDate="applyTime"
:list="pageState.list"
:longitude="longitudeVal"
:latitude="latitudeVal"
></renderDeliveryRecord>
<empty v-else :is-position="true"></empty>
</view>
<AppLayout
title="投递记录"
:use-scroll-view="true"
mainback-ground-color="#f4f4f4"
:show-bg-image="false"
@onScrollBottom="getJobList()"
>
<template #headerleft v-if="isMiniProgram">
<view class="btnback">
<image src="@/static/icon/back.png" @click="navBack"></image>
</view>
</template>
<view class="collection-content">
<renderDeliveryRecord
v-if="pageState.list.length"
seeDate="applyTime"
:list="pageState.list"
:longitude="longitudeVal"
:latitude="latitudeVal"
></renderDeliveryRecord>
<empty v-else :is-position="true"></empty>
</view>
</AppLayout>
</template>
<script setup>
@@ -16,7 +29,7 @@ import dictLabel from '@/components/dict-Label/dict-Label.vue';
import { reactive, inject, watch, ref, onMounted } from 'vue';
import { onLoad, onShow, onReachBottom } from '@dcloudio/uni-app';
import useUserStore from '@/stores/useUserStore';
const { $api, navTo, vacanciesTo } = inject('globalFunction');
const { $api, navTo, vacanciesTo, navBack } = inject('globalFunction');
import { storeToRefs } from 'pinia';
import useLocationStore from '@/stores/useLocationStore';
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
@@ -38,19 +51,6 @@ onLoad(() => {
getJobList();
});
onMounted(() => {
// #ifdef H5
if (!isMiniProgram.value) {
const a = document.getElementsByClassName('uni-page-head-hd')[0];
a.style.display = 'none';
}
// #endif
});
onReachBottom(() => {
getJobList();
});
function getJobList(type = 'add') {
if (type === 'refresh') {
pageState.page = 1;
@@ -83,11 +83,18 @@ function getJobList(type = 'add') {
</script>
<style lang="stylus" scoped>
.btnback{
width: 64rpx;
height: 64rpx;
}
image {
height: 100%;
width: 100%;
}
.collection-content{
padding: 1rpx 28rpx 20rpx 28rpx;
background: #F4F4F4;
height: 100%;
min-height: calc(100vh - var(--window-top) - var(--status-bar-height) - var(--window-bottom));
position: relative;
}
</style>

View File

@@ -184,10 +184,13 @@ function getThirdPartyJobsList(type = 'add') {
let params = {
current: pageState.current,
pageSize: pageState.pageSize,
gsID:companyId,
gsmc:companyName,
zphID:zphId
};
$api.createRequest(
`/app/internal/jobThirdPart?gsID=${companyId}&gsmc=${companyName}&zphID=${zphId}`,
`/app/internal/jobThirdPart`,
params,
'GET',
true

View File

@@ -18,7 +18,7 @@
</view>
<view class="content-list">
<view class="list-search">
<uni-icons type="search" color="#333333" size="24"></uni-icons>
<my-icons type="search" color="#333333" size="48"></my-icons>
<input
class="search-input"
v-model="inputVal"

View File

@@ -9,7 +9,7 @@
<view class="collection-search">
<view class="search-content">
<view class="header-input button-click">
<uni-icons class="iconsearch" color="#6A6A6A" type="search" size="22"></uni-icons>
<my-icons class="iconsearch" color="#6A6A6A" type="search" size="44"></my-icons>
<input
class="input"
@confirm="searchCollection"

View File

@@ -9,7 +9,7 @@
<view class="collection-search">
<view class="search-content">
<view class="header-input button-click">
<uni-icons class="iconsearch" color="#6A6A6A" type="search" size="22"></uni-icons>
<my-icons class="iconsearch" color="#6A6A6A" type="search" size="44"></my-icons>
<input
class="input"
@confirm="searchCollection"

View File

@@ -153,9 +153,11 @@ function getCompanyList(type = 'add') {
let params = {
current: pageState.current,
pageSize: pageState.pageSize,
zphID:jobFairId,
zphmc:jobFairName
};
$api.createRequest(
`/app/internal/companyThirdPart/?zphID=${jobFairId}&zphmc=${jobFairName}`,
`/app/internal/companyThirdPart`,
params,
'GET',
true

View File

@@ -1,8 +1,15 @@
<template>
<view class="collection-content">
<renderJobs :list="list" :longitude="longitudeVal" :latitude="latitudeVal"></renderJobs>
<loadmore ref="loadmoreRef"></loadmore>
</view>
<AppLayout title="更多岗位" :use-scroll-view="true" :show-bg-image="false" @onScrollBottom="loadMore">
<template #headerleft v-if="isMiniProgram">
<view class="btnback">
<image src="@/static/icon/back.png" @click="navBack"></image>
</view>
</template>
<view class="collection-content">
<renderJobs :list="list" :longitude="longitudeVal" :latitude="latitudeVal"></renderJobs>
<loadmore ref="loadmoreRef"></loadmore>
</view>
</AppLayout>
</template>
<script setup>
@@ -16,6 +23,7 @@ import useLocationStore from '@/stores/useLocationStore';
import { usePagination } from '@/hook/usePagination';
import { jobMoreMap } from '@/utils/markdownParser';
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
const { isMiniProgram } = storeToRefs(useUserStore());
const loadmoreRef = ref(null);
// 响应式搜索条件(可以被修改)
@@ -57,17 +65,20 @@ function removeNullProperties(obj) {
}
return obj;
}
onReachBottom(() => {
loadMore();
});
</script>
<style lang="stylus" scoped>
.btnback{
width: 64rpx;
height: 64rpx;
}
image {
height: 100%;
width: 100%;
}
.collection-content{
padding: 1rpx 28rpx 20rpx 28rpx;
background: #F4F4F4;
height: 100%
min-height: calc(100vh - var(--window-top) - var(--status-bar-height) - var(--window-bottom));
height: 100%;
}
</style>

View File

@@ -1,44 +1,51 @@
<template>
<view class="reser-content">
<scroll-view :scroll-x="true" :show-scrollbar="false" class="tab-scroll">
<view class="content-top">
<view
class="top-item button-click"
:class="{ active: state.tabIndex === 'all' }"
@click="changeOption('all')"
>
全部
</view>
<view
class="top-item button-click"
:class="{ active: state.tabIndex === index }"
v-for="(item, index) in userInfo.jobTitle"
:key="index"
@click="changeOption(index)"
>
{{ item }}
</view>
<AppLayout title="新职位推荐" :use-scroll-view="false" :show-bg-image="false">
<template #headerleft v-if="isMiniProgram">
<view class="btnback">
<image src="@/static/icon/back.png" @click="navBack"></image>
</view>
</scroll-view>
<view class="main">
<scroll-view class="scroll-view" scroll-y @scrolltolower="scrollBottom">
<view class="list">
<renderJobs
v-if="pageState.list.length"
:longitude="longitudeVal"
:latitude="latitudeVal"
></renderJobs>
<empty v-else></empty>
</template>
<view class="reser-content">
<scroll-view :scroll-x="true" :show-scrollbar="false" class="tab-scroll">
<view class="content-top">
<view
class="top-item button-click"
:class="{ active: state.tabIndex === 'all' }"
@click="changeOption('all')"
>
全部
</view>
<view
class="top-item button-click"
:class="{ active: state.tabIndex === index }"
v-for="(item, index) in userInfo.jobTitle"
:key="index"
@click="changeOption(index)"
>
{{ item }}
</view>
</view>
</scroll-view>
<view class="main">
<scroll-view class="scroll-view" scroll-y @scrolltolower="scrollBottom">
<view class="list">
<renderJobs
v-if="pageState.list.length"
:longitude="longitudeVal"
:latitude="latitudeVal"
></renderJobs>
<empty v-else></empty>
</view>
</scroll-view>
</view>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { reactive, inject, watch, ref, onMounted, onBeforeUnmount } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
const { $api, navTo, debounce, customSystem } = inject('globalFunction');
const { $api, navTo, debounce, customSystem, navBack } = inject('globalFunction');
import { storeToRefs } from 'pinia';
import useLocationStore from '@/stores/useLocationStore';
import useUserStore from '@/stores/useUserStore';
@@ -58,15 +65,6 @@ const state = reactive({
tabIndex: 'all',
});
onMounted(() => {
// #ifdef H5
if (!isMiniProgram.value) {
const a = document.getElementsByClassName('uni-page-head-hd')[0];
a.style.display = 'none';
}
// #endif
});
onLoad(() => {
getList('refresh');
});
@@ -116,9 +114,17 @@ function getList(type = 'add', loading = true) {
</script>
<style lang="stylus" scoped>
.btnback{
width: 64rpx;
height: 64rpx;
}
image {
height: 100%;
width: 100%;
}
.reser-content{
width: 100%;
height: calc(100vh - var(--window-top) - var(--status-bar-height) - var(--window-bottom));
height: 100%;
display: flex;
flex-direction: column;
.content-top{

View File

@@ -168,7 +168,7 @@
</view>
<view v-else class="btn-wq button-click" @click="jobApply">
<span v-if="jobInfo.isApply">立即前往</span>
<span v-if="!jobInfo.isApply">立即投递</span>
<span v-if="!jobInfo.isApply">立即前往</span>
</view>
</view>
</template>
@@ -185,7 +185,7 @@ import dictLabel from '@/components/dict-Label/dict-Label.vue';
import RadarMap from './component/radarMap.vue';
import { storeToRefs } from 'pinia';
import useUserStore from '@/stores/useUserStore';
const { isMiniProgram } = storeToRefs(useUserStore());
const { isMiniProgram, hasLogin } = storeToRefs(useUserStore());
const { $api, navTo, getLenPx, parseQueryParams, navBack, isEmptyObject } = inject('globalFunction');
import config from '@/config.js';
@@ -252,7 +252,10 @@ function getDetail(jobId) {
const { latitude, longitude, companyName, companyId } = resData.data;
jobInfo.value = resData.data;
getCompanyIsAJobs(companyId);
getCompetivetuveness(jobId);
if (hasLogin.value) {
getCompetivetuveness(jobId);
}
if (latitude && longitude) {
initMapCovers(latitude, longitude, companyName);
@@ -285,7 +288,12 @@ function getCompanyIsAJobs(...args) {
if (dataType.value === 2) {
// 第三方数据获取公司职位数量
const [gsID, gsmc, zphID] = args;
$api.createRequest(`/app/internal/jobThirdPart?gsID=${gsID}&gsmc=${gsmc}&zphID=${zphID}`).then((resData) => {
const params = {
gsID,
gsmc,
zphID,
};
$api.createRequest(`/app/internal/jobThirdPart`, params).then((resData) => {
companyCount.value = resData.total;
});
} else {

View File

@@ -1,5 +1,11 @@
<template>
<view class="reser-content">
<AppLayout title="我的预约" :use-scroll-view="false" :show-bg-image="false">
<template #headerleft v-if="isMiniProgram">
<view class="btnback">
<image src="@/static/icon/back.png" @click="navBack"></image>
</view>
</template>
<view class="reser-content">
<view class="content-top">
<view
class="top-item"
@@ -12,7 +18,7 @@
</view>
</view>
<view class="main">
<scroll-view class="height-100" scroll-y>
<scroll-view class="height-100" scroll-y @scrolltolower="getList('add')">
<view>
<view class="card" v-for="(item, index) in pageState.list" :key="index">
<view
@@ -38,24 +44,25 @@
:blat="latitudeVal"
:blong="longitudeVal"
></convert-distance> -->
</view>
</view>
</view>
</view>
<view class="footer" v-if="isTimePassed(item.zphjbsj)">
<view class="card_cancel" @click="updateCancel(item)">取消预约</view>
<view class="footer" v-if="isTimePassed(item.zphjbsj)">
<view class="card_cancel" @click="updateCancel(item)">取消预约</view>
</view>
</view>
</view>
</view>
<empty v-if="!pageState.list.length"></empty>
</scroll-view>
<empty v-if="!pageState.list.length"></empty>
</scroll-view>
</view>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { reactive, inject, watch, ref, onMounted, onBeforeUnmount } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
const { $api, navTo, debounce, customSystem } = inject('globalFunction');
const { $api, navTo, debounce, customSystem, navBack } = inject('globalFunction');
import Countdown from './component/countdown.vue';
import { storeToRefs } from 'pinia';
import useLocationStore from '@/stores/useLocationStore';
@@ -92,18 +99,9 @@ onLoad(() => {
getList();
});
onMounted(() => {
// #ifdef H5
if (!isMiniProgram.value) {
const a = document.getElementsByClassName('uni-page-head-hd')[0];
a.style.display = 'none';
}
// #endif
});
function chnageRanOption(item) {
ranItem.value = item;
getList();
getList('refresh');
}
function updateCancel(item) {
@@ -155,9 +153,17 @@ function getList(type = 'add', loading = true) {
</script>
<style lang="stylus" scoped>
.btnback{
width: 64rpx;
height: 64rpx;
}
image {
height: 100%;
width: 100%;
}
.reser-content{
width: 100%;
height: calc(100vh - var(--window-top) - var(--status-bar-height) - var(--window-bottom));
height:100%;
display: flex;
flex-direction: column;
.content-top{

View File

@@ -26,7 +26,7 @@
<view
class="item button-click"
:class="{
optional: item.isThisMonth && hasZphInData(item),
optional: (item.isThisMonth && hasZphInData(item)) || hasViewRecordInData(item),
noOptional: !item.isThisMonth,
active: current.date === item.date && item.isThisMonth,
}"
@@ -62,6 +62,7 @@ const pages = reactive({
year: 0,
month: 0,
});
const hasViewRecordDateArray = ref([]);
const hasZphDateArray = ref([]);
onLoad((options) => {
@@ -76,6 +77,7 @@ onLoad((options) => {
new Array(recordNum.value + 1).fill(null).map(() => {
addMonth();
});
updateViewRecordDateArray()
} else {
initPagesDate();
new Array(recordNum.value).fill(null).map(() => {
@@ -83,7 +85,7 @@ onLoad((options) => {
});
}
if (options.entrance === 'careerfair') {
updateDateArray();
updateCareerFairDateArray();
}
});
@@ -92,6 +94,17 @@ function hasZphInData(item) {
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 : [];
return dateArray.some((date) => {
@@ -99,7 +112,7 @@ function hasZphInData(item) {
});
}
async function updateDateArray() {
async function updateCareerFairDateArray() {
const LoadCache = (resData) => {
if (resData.code === 200) {
hasZphDateArray.value = resData.data;
@@ -107,6 +120,14 @@ async function updateDateArray() {
};
$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() {
if (isValidDateString(current.value.date)) {
@@ -307,6 +328,7 @@ function getMonthCalendarData({ year, month, selectableDates = [] }) {
justify-content: center
border-radius: 20rpx 20rpx 20rpx 20rpx;
padding: 16rpx 0
margin: 0 2rpx;
margin-bottom: 20rpx
.item-top{
font-weight: 600;

View File

@@ -8,7 +8,7 @@
<view class="card-subTitle">{{ item.subTitle }}</view>
<view class="card-btns" v-if="item.noticeType === '2'" @click="seeBussiness(item)">
<view class="btns-text">立即查看</view>
<view class="btns-text"><uni-icons type="forward" color="#256bfa" size="18"></uni-icons></view>
<view class="btns-text"><my-icons type="forward" color="#256bfa" size="32"></my-icons></view>
</view>
</view>
</view>

View File

@@ -2,7 +2,7 @@
<div class="video-container">
<view class="back-box" v-if="isMiniProgram">
<view class="btn">
<uni-icons type="left" size="26" color="#FFFFFF" @click="navBack"></uni-icons>
<my-icons type="left" size="52" color="#FFFFFF" @click="navBack"></my-icons>
</view>
</view>
<mTikTok :video-list="state.videoList" :pause-type="1" :controls="false" @loadMore="loadMore" @change="change">
@@ -15,7 +15,7 @@
</text>
<view class="seedetail" @click="nextDetail">
查看详情
<uni-icons type="right" color="#FFFFFF" size="14"></uni-icons>
<my-icons type="right" color="#FFFFFF" size="28"></my-icons>
</view>
</view>
</view>

View File

@@ -228,6 +228,7 @@ const changeendTime = () => {
background: #f5f5f5;
padding: 20rpx;
box-sizing: border-box;
font-size: 28rpx;
}
}

View File

@@ -126,7 +126,8 @@
"path": "pages/Intendedposition/Intendedposition",
"style": {
"navigationBarTitleText": "投递记录",
"navigationBarBackgroundColor": "#FFFFFF"
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom"
}
},
{
@@ -184,7 +185,8 @@
"path": "pages/reservation/reservation",
"style": {
"navigationBarTitleText": "我的预约",
"navigationBarBackgroundColor": "#FFFFFF"
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom"
}
},
{
@@ -199,7 +201,8 @@
"path": "pages/newJobPosition/newJobPosition",
"style": {
"navigationBarTitleText": "新职位推荐",
"navigationBarBackgroundColor": "#FFFFFF"
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom"
}
},
{
@@ -221,7 +224,8 @@
"path": "pages/moreJobs/moreJobs",
"style": {
"navigationBarTitleText": "更多岗位",
"navigationBarBackgroundColor": "#FFFFFF"
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom"
}
}
]
@@ -277,7 +281,7 @@
// "enablePullDownRefresh": false,
// "navigationStyle": "custom",
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcMaxDeviceWidth": 750,
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcIncludeWidth": 750
},
"uniIdRouter": {}

View File

@@ -12,7 +12,7 @@
</view>
</view>
<view class="header-input btn-feel">
<uni-icons class="iconsearch" color="#666666" type="search" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666666" type="search" size="32"></my-icons>
<input class="input" placeholder="招聘会" placeholder-class="inputplace" />
</view>
<view class="header-date">

View File

@@ -12,7 +12,7 @@
</view>
</view>
<view class="header-input btn-feel">
<uni-icons class="iconsearch" color="#666666" type="search" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666666" type="search" size="36"></my-icons>
<input
v-model="pageState.zphmc"
confirm-type="search"
@@ -100,7 +100,7 @@
<empty v-if="!fairList.length" content="暂时没有结果,下一天也许就有惊喜"></empty>
</scroll-view>
</view>
<!-- <Tabbar :currentpage="1"></Tabbar> -->
<Tabbar v-show="showTabbar" :currentpage="1"></Tabbar>
</view>
</view>
</template>
@@ -114,6 +114,19 @@ import { storeToRefs } from 'pinia';
import config from '@/config';
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
const { $api, navTo, cloneDeep, debounce } = inject('globalFunction');
import useScreenStore from '@/stores/useScreenStore'
const screenStore = useScreenStore()
const showTabbar = ref(false)
watch(
() => screenStore.isWideScreen,
(newVal) => {
showTabbar.value = newVal
},
{ immediate: true }
)
const weekList = ref([]);
const fairList = ref([]);
const currentDay = ref({});

View File

@@ -15,7 +15,7 @@
placeholder-class="input-placeholder"
placeholder="请输入搜索历史对话"
/>
<uni-icons class="input-search" type="search" size="20"></uni-icons>
<my-icons class="input-search" type="search" size="40"></my-icons>
</view>
<scroll-view scroll-y :show-scrollbar="false" class="chat-scroll">
<view
@@ -63,15 +63,15 @@
<ai-paging ref="paging"></ai-paging>
</view>
<!-- 自定义tabbar -->
<!-- <view class="chatmain-footer" v-show="!isDrawerOpen">
<view class="chatmain-footer" v-show="!isDrawerOpen && showTabbar">
<Tabbar :currentpage="2"></Tabbar>
</view> -->
</view>
</view>
</view>
</template>
<script setup>
import { ref, inject, nextTick, computed } from 'vue';
import { ref, inject, nextTick, computed, watch } from 'vue';
const { $api, navTo, insertSortData } = inject('globalFunction');
import { onLoad, onShow, onHide } from '@dcloudio/uni-app';
import Tabbar from '@/components/tabbar/midell-box.vue';
@@ -88,6 +88,19 @@ import config from '@/config';
const searchText = ref('');
const paging = ref(null);
import useScreenStore from '@/stores/useScreenStore';
const screenStore = useScreenStore();
const showTabbar = ref(false);
watch(
() => screenStore.isWideScreen,
(newVal) => {
showTabbar.value = newVal;
},
{ immediate: true }
);
// 实时过滤
const filteredList = computed(() => {
// console.log(tabeList.value);
@@ -111,7 +124,7 @@ onHide(() => {
paging.value?.handleTouchCancel();
if (isDrawerOpen.value) {
isDrawerOpen.value = false;
uni.showTabBar();
if (!screenStore.isWideScreen) uni.showTabBar();
}
});
@@ -120,7 +133,7 @@ const toggleDrawer = () => {
if (isDrawerOpen.value) {
uni.hideTabBar();
} else {
uni.showTabBar();
if (!screenStore.isWideScreen) uni.showTabBar();
}
};

View File

@@ -185,7 +185,7 @@
<!-- btn -->
<CollapseTransition :show="showfile">
<view class="area-tips">
<uni-icons type="info-filled" color="#ADADAD" size="15"></uni-icons>
<my-icons type="info-filled" color="#ADADAD" size="30"></my-icons>
上传后自动解析简历内容
</view>
<view class="area-file">
@@ -233,7 +233,7 @@
<!-- <image class="file-icon" @click="jumpUrl(file)" :src=""></image> -->
</view>
<view class="file-del" catchtouchmove="true" @click="delfile(file)">
<uni-icons type="closeempty" color="#FFFFFF" size="10"></uni-icons>
<my-icons type="closeempty" color="#FFFFFF" size="20"></my-icons>
</view>
</view>
</view>
@@ -267,6 +267,8 @@ import AudioWave from './AudioWave.vue';
import WaveDisplay from './WaveDisplay.vue';
import FileIcon from './fileIcon.vue';
import FileText from './fileText.vue';
import useScreenStore from '@/stores/useScreenStore'
const screenStore = useScreenStore();
// 系统功能hook和阿里云hook
import { useAudioRecorder } from '@/hook/useRealtimeRecorder2.js';
// import { useAudioRecorder } from '@/hook/useSystemSpeechReader.js';
@@ -446,7 +448,7 @@ const scrollToBottom = throttle(function () {
}, 500);
function getGuess() {
$api.chatRequest('/app/chat/guest', { sessionId: chatSessionID.value }, 'POST').then((res) => {
$api.createRequest('/app/chat/guest', { sessionId: chatSessionID.value }, 'POST').then((res) => {
guessList.value = res.data;
showGuess.value = true;
nextTick(() => {
@@ -619,14 +621,14 @@ function confirmFeeBack(value) {
useChatGroupDBStore()
.badFeedback(feebackData.value, value)
.then(() => {
uni.showTabBar()
if (!screenStore.isWideScreen) uni.showTabBar()
feeback.value?.close();
feeBackTips.value?.open();
});
}
function colseFeeBack() {
uni.showTabBar()
if (!screenStore.isWideScreen) uni.showTabBar()
}
function readMarkdown(value, index) {
@@ -898,6 +900,7 @@ image-margin-top = 40rpx
position: relative
background: #F5F5F5;
border-radius: 60rpx 60rpx 60rpx 60rpx;
font-size: 28rpx;
}
.input_vio
flex: 1;

View File

@@ -1,9 +1,25 @@
<template>
<view class="container" id="pixi-box" ref="pixiContainerRef"></view>
<view class="out">
<view v-if="loading" class="loading">
<view class="semicircle-loader"></view>
</view>
<view v-else class="container" id="pixi-box" ref="pixiContainerRef"></view>
</view>
</template>
<script setup>
import { onMounted, onUnmounted, ref, nextTick } from 'vue';
import { onMounted, onUnmounted, ref, nextTick, watch } from 'vue';
const props = defineProps({
tags: {
type: Array,
default: [],
},
loading: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['tag-click']);
// DOM Ref
@@ -15,10 +31,9 @@ let tagsContainer = null;
let activeTagInstances = [];
// 配置数据
const mockTags = [
{ name: '医生', bgColor: 0x0069fe, fontColor: 0xffffff, size: 17, opacity: 1.0, angle: 0, radius: 0 },
const tagsConfig = ref([
{ bgColor: 0x0069fe, fontColor: 0xffffff, size: 16, opacity: 1.0, angle: 0, radius: 0 },
{
name: '工程师',
bgColor: 0x87e2ec,
fontColor: 0xffffff,
size: 14,
@@ -28,7 +43,6 @@ const mockTags = [
tailRotation: Math.PI / 2,
},
{
name: '建筑师',
bgColor: 0xffebeb,
tailColor: 0xffe1e1,
fontColor: 0xff6969,
@@ -36,62 +50,47 @@ const mockTags = [
opacity: 1,
angle: -Math.PI / 4.2,
radius: 125,
tailRotation: (3 * Math.PI) / 4,
tailRotation: (3 * Math.PI) / 4.5,
},
{
name: '律师',
bgColor: 0x21ea85,
fontColor: 0xffffff,
size: 15,
opacity: 1,
angle: -Math.PI / 10,
radius: 130,
tailRotation: (3 * Math.PI) / 4,
tailRotation: (3 * Math.PI) / 4.2,
},
{
name: '记者',
bgColor: 0xebf3ff,
tailColor: 0xb9d3ff,
fontColor: 0x1d71ef,
size: 12,
opacity: 1,
angle: Math.PI / 120,
radius: 130,
tailRotation: (3 * Math.PI) / 3.4,
angle: Math.PI / 18,
radius: 135,
tailRotation: (3 * Math.PI) / 4.3,
},
{
name: '程序员',
bgColor: 0xffd4b6,
fontColor: 0xffffff,
size: 14,
opacity: 1,
angle: Math.PI / 7,
radius: 120,
tailRotation: (5 * Math.PI) / 4,
angle: Math.PI / 4.3,
radius: 100,
tailRotation: -(3 * Math.PI) / 4.5,
},
{
name: '摄影师',
bgColor: 0xd8e5fe,
tailColor: 0xb9d3ff,
fontColor: 0x1d71ef,
size: 11,
opacity: 1,
angle: Math.PI / 3,
radius: 79,
tailRotation: (3 * Math.PI) / 2,
},
{
name: '设计师',
bgColor: 0xff9400,
fontColor: 0xffffff,
size: 14,
opacity: 1,
angle: (2 * Math.PI) / 3,
radius: 92,
tailRotation: (7 * Math.PI) / 4,
tailRotation: -Math.PI / 2.4,
},
{
name: '心理咨询师',
bgColor: 0xebf3ff,
tailColor: 0xb9d3ff,
fontColor: 0x1d71ef,
@@ -99,35 +98,45 @@ const mockTags = [
opacity: 1,
angle: (5.4 * Math.PI) / 6,
radius: 110,
tailRotation:(3 * Math.PI) /1.78,
tailRotation: (3 * Math.PI) / 1.79,
},
{
name: '护士',
bgColor: 0xff6969,
fontColor: 0xffffff,
size: 15,
size: 14,
opacity: 1,
angle: (6.3 * Math.PI) / 5.9,
radius: 110,
tailRotation: Math.PI / 4,
angle: (6.3 * Math.PI) / 5.8,
radius: 120,
tailRotation: Math.PI / 2.9,
},
{
name: '会计',
bgColor: 0xfce9c9,
fontColor: 0xfbc55f,
size: 13,
opacity: 1,
angle: (7.2 * Math.PI) / 5.9,
radius: 120,
tailRotation: Math.PI / 4,
tailRotation: Math.PI / 3,
},
];
]);
watch(
() => props.tags,
(val) => {
if (val && val.length) {
tagsConfig.value.map((tag, index) => {
// console.log(val[index])
tag.name = val[index]?.job_name;
});
setTimeout(() => {
initPixi();
}, 100);
}
},
{ deep: true }
);
onMounted(async () => {
await nextTick();
setTimeout(() => {
initPixi();
}, 100);
window.addEventListener('resize', handleResize);
});
@@ -177,19 +186,18 @@ const initPixi = () => {
};
const renderScene = (sw, sh) => {
let ratio = window.innerWidth / 400;
if (ratio < 1) ratio = 1;
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);
tagsConfig.value.forEach((data, index) => {
const scaledRadius = data.radius * ratio;
let x = sw / 2 + scaledRadius * Math.cos(data.angle);
let y = sh / 2 + scaledRadius * Math.sin(data.angle);
const tag = createTag(data, index);
const tag = createTag(data, index, ratio);
tagsContainer.addChild(tag);
@@ -216,7 +224,13 @@ const renderScene = (sw, sh) => {
};
if (data.radius > 0) {
const tail = createCometTail( data.tailColor || data.bgColor, data.tailRotation, tag.width);
const tail = createCometTail(
data.tailColor || data.bgColor,
data.tailRotation,
tag.width,
tag.height,
ratio
);
tag.addChildAt(tail, 0);
tag.updateTail = () => tail.updateAnim();
}
@@ -227,7 +241,6 @@ const renderScene = (sw, sh) => {
// 动画循环
app.ticker.add(() => {
const screenH = app.screen.height;
activeTagInstances.forEach((tag) => {
const meta = tag.userData;
if (meta) {
@@ -247,7 +260,8 @@ const renderScene = (sw, sh) => {
});
};
const createTag = (tagData, index) => {
const createTag = (tagData, index, ratio) => {
if (ratio > 1) ratio = ratio * 0.9;
const tagGroup = new PIXI.Container();
tagGroup.eventMode = 'static';
tagGroup.cursor = 'pointer';
@@ -256,15 +270,15 @@ const createTag = (tagData, index) => {
const text = new PIXI.Text(tagData.name, {
fontFamily: ['PingFang SC', 'Microsoft YaHei', 'Arial'],
fontSize: tagData.size,
fontSize: tagData.size * ratio,
fill: tagData.fontColor,
padding: 4,
padding: 4 * ratio,
resolution: 2,
});
text.anchor.set(0.5);
const paddingH = 26;
const paddingV = 10;
const paddingH = 26 * ratio;
const paddingV = 10 * ratio;
let bgWidth = text.width + paddingH;
let bgHeight = text.height + paddingV;
@@ -281,14 +295,15 @@ const createTag = (tagData, index) => {
return tagGroup;
};
const createCometTail = (bgColor, tailRotation, parentWidth) => {
const createCometTail = (bgColor, tailRotation, parentWidth, parentHeight, ratio) => {
if (ratio > 1) ratio = ratio;
const tailGroup = new PIXI.Container();
const graphics = new PIXI.Graphics();
tailGroup.addChild(graphics);
const baseLength = 45;
const startWidth = parentWidth * 0.6;
const endWidth = 20;
const baseLength = 45 * ratio;
const startWidth = parentHeight + 20 * ratio;
const endWidth = parentHeight * 0.4;
let breathPhase = Math.random() * Math.PI * 2;
const breathSpeed = 0.04;
@@ -335,35 +350,44 @@ const createCometTail = (bgColor, tailRotation, parentWidth) => {
const handleResize = () => {
const container = getContainerDOM();
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;
});
app.destroy(true, { children: true, texture: true, baseTexture: true });
app = null;
initPixi();
};
</script>
<style scoped>
.out {
width: 100%;
height: 100%;
}
.loading {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.semicircle-loader {
width: 150rpx;
height: 150rpx;
border: 12rpx solid #f3f3f3;
border-top: 12rpx solid #3498db;
border-radius: 50%;
animation: spin 1.2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.container {
width: 100%;
height: 500rpx;
height: 100%;
position: relative;
overflow: hidden;
color: #b9d3ff;

View File

@@ -3,7 +3,7 @@
<view class="nav-hidden hidden-animation" :class="{ 'hidden-height': isScrollingDown }">
<view class="container-search">
<view class="search-input button-click" @click="navTo('/pages/search/search')">
<uni-icons class="iconsearch" color="#666666" type="search" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666666" type="search" size="32"></my-icons>
<text class="inpute">职位名称薪资要求等</text>
</view>
<!-- <view class="chart button-click">职业图谱</view> -->
@@ -42,7 +42,7 @@
</view>
</scroll-view>
<view class="jobs-add button-click" @click="navTo('/packageA/pages/addPosition/addPosition')">
<uni-icons class="iconsearch" color="#666D7F" type="plusempty" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666D7F" type="plusempty" size="32"></my-icons>
<text>添加</text>
</view>
</view>
@@ -121,7 +121,7 @@
</view>
<!-- <view class="falls-card-matchingrate">
<view class=""><matchingDegree :job="job"></matchingDegree></view>
<uni-icons type="star" size="30"></uni-icons>
<my-icons type="star" size="60"></my-icons>
</view> -->
</view>
</view>

View File

@@ -61,7 +61,7 @@
<image class="match-card-bg" src="@/static/icon/match-card-bg.png" />
<view class="title">简历匹配职位</view>
<view class="match-item-container">
<AIMatch @tag-click="handleTagClick"></AIMatch>
<AIMatch :tags="matchTags" :loading="matchLoading" @tag-click="handleTagClick"></AIMatch>
</view>
</view>
</view>
@@ -209,7 +209,7 @@
</view>
<!-- <view class="falls-card-matchingrate">
<view class=""><matchingDegree :job="job"></matchingDegree></view>
<uni-icons type="star" size="30"></uni-icons>
<my-icons type="star" size="60"></my-icons>
</view> -->
</view>
<view v-if="!job.education" class="recommend-card" :class="{ isBut: job.isBut }">
@@ -259,7 +259,7 @@ const { $api, navTo, vacanciesTo, formatTotal, throttle } = inject('globalFuncti
import { onLoad, onShow } from '@dcloudio/uni-app';
import { storeToRefs } from 'pinia';
import useUserStore from '@/stores/useUserStore';
const { userInfo } = storeToRefs(useUserStore());
const { userInfo, hasLogin } = storeToRefs(useUserStore());
import useDictStore from '@/stores/useDictStore';
const { getTransformChildren, oneDictData } = useDictStore();
import useLocationStore from '@/stores/useLocationStore';
@@ -280,6 +280,9 @@ const isSticky = ref(false);
const showScrollBottom = ref(false);
const scrollTop = ref(0);
const matchTags = ref([]);
const matchLoading = ref(false);
const emits = defineEmits(['onShowTabbar']);
const waterfallsFlowRef = ref(null);
@@ -311,6 +314,8 @@ const rangeOptions = ref([
]);
const isLoaded = ref(false);
const colors = ['#0069FE', '#FF9400', '#FF6969', '#21EA85', '#87E2EC'];
const occupations = [
'律师',
'工程师',
@@ -354,13 +359,41 @@ const occupations = [
'导游',
];
const colors = ['#0069FE', '#FF9400', '#FF6969', '#21EA85', '#87E2EC'];
onMounted(() => {
let firstEntry = uni.getStorageSync('firstEntry') === false ? false : true; // 默认未读
maskFirstEntry.value = firstEntry;
getMatchTags();
});
async function getMatchTags() {
if (hasLogin.value) {
try {
matchLoading.value = true;
const { data } = await $api.createRequest('/app/user/getJobAdviceByResume');
matchTags.value = data;
matchLoading.value = false;
} catch (err) {
console.error('简历匹配职位获取失败');
}
} else {
const vals = getRandomStrings(occupations).map((text) => ({
job_name: text,
score: 0,
}));
matchTags.value = vals;
}
}
function getRandomStrings(arr, count = 10) {
const size = Math.min(arr.length, count);
const shuffled = [...arr];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled.slice(0, size);
}
const checkStickyStatus = (e) => {
scrollTop.value = e.detail.scrollTop;
nextTick(() => {
@@ -387,7 +420,7 @@ function closeVideoTip() {
const handleTagClick = (tagInfo) => {
console.log('点击的标签信息:', tagInfo);
$api.msg('暂未开放');
navTo(`/pages/search/search?keyWord=${encodeURIComponent(tagInfo.name)}`);
};
const handleItemClick = (item) => {
@@ -541,6 +574,7 @@ function openFilter() {
}
showFilter.value = false;
getJobList('refresh');
emits('onShowTabbar', true);
},
cancel: () => {
showFilter.value = false;
@@ -1013,6 +1047,7 @@ defineExpose({ loadData });
top:0;
.match-item-container
width:100%;
height:400rpx;
margin-top:30rpx;
position :relative;
z-index:1

View File

@@ -23,7 +23,7 @@
</view>
</scroll-view>
<view class="jobs-add button-click" @click="navTo('/pages/search/search')">
<uni-icons class="iconsearch" color="#666D7F" type="search" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666D7F" type="search" size="36"></my-icons>
<text>搜索</text>
</view>
</view>
@@ -55,7 +55,7 @@
<view class="title">{{ job.jobTitle }}</view>
<view class="desc">
<image class="point3" src="/static/icon/point3.png"></image>
<!-- <uni-icons type="location" size="14"></uni-icons> -->
<!-- <my-icons type="location" size="28"></my-icons> -->
<view class="descText">{{ job.companyName }}</view>
</view>
</view>

View File

@@ -41,7 +41,7 @@
</swiper>
</view>
<!-- <Tabbar v-show="showTabbar" :currentpage="0"></Tabbar> -->
<Tabbar v-show="showTabbar" :currentpage="0"></Tabbar>
<!-- maskFristEntry -->
<view class="maskFristEntry" v-if="maskFristEntry">
@@ -63,6 +63,12 @@ import { onLoad, onShow } from '@dcloudio/uni-app';
import IndexRefactor from './components/index-refactor.vue';
import IndexOne from './components/index-one.vue';
import IndexTwo from './components/index-two.vue';
import useScreenStore from '@/stores/useScreenStore'
const screenStore = useScreenStore()
const {isWideScreen} = screenStore
const loadedMap = reactive([false, false]);
const swiperRefs = [ref(null), ref(null)];
// const components = [IndexOne, IndexTwo];
@@ -70,7 +76,7 @@ const components = [IndexRefactor, IndexTwo];
import { storeToRefs } from 'pinia';
import { useReadMsg } from '@/stores/useReadMsg';
const { unreadCount } = storeToRefs(useReadMsg());
const showTabbar = ref(true);
const showTabbar = ref(false);
const maskFristEntry = ref(false);
const disableTouch = ref(false);
@@ -78,12 +84,24 @@ const startPointX = ref(0);
const totalPage = 2;
const THRESHOLD = 5;
watch(
() => screenStore.isWideScreen,
(newVal) => {
showTabbar.value = newVal
},
{ immediate: true }
)
onLoad(() => {
// 判断浏览器是否有 fristEntry 第一次进入
let fristEntry = uni.getStorageSync('fristEntry') === false ? false : true; // 默认未读
maskFristEntry.value = fristEntry;
maskFristEntry.value = fristEntry
if (fristEntry) {
uni.hideTabBar();
if(!isWideScreen)uni.hideTabBar();
else showTabbar.value = false
}else{
if(isWideScreen)showTabbar.value = true
}
// 预加载较重页面
setTimeout(() => {
@@ -145,7 +163,12 @@ function handleTouchMove(e) {
}
function changeShowTabbar(val) {
showTabbar.value = val;
if(isWideScreen){
showTabbar.value=val
}else{
if(val)uni.showTabBar()
else uni.hideTabBar()
}
}
//1 查看消息类型
@@ -200,12 +223,14 @@ function changeSwiperMsgType(e) {
function closeFristEntry() {
uni.setStorageSync('fristEntry', false);
maskFristEntry.value = false;
uni.showTabBar();
if(!isWideScreen)uni.showTabBar();
else showTabbar.value=true
}
function goExperience() {
closeFristEntry();
uni.showTabBar();
if(!isWideScreen)uni.showTabBar();
else showTabbar.value = true
state.current = 1;
}
</script>

View File

@@ -1,6 +1,60 @@
<template>
<AppLayout title="就业服务程序">
<tabcontrolVue :current="tabCurrent">
<!-- 扫码登录-->
<view class="alipay-login-container" v-if="isMachineEnv">
<view class="login-scan-area">
<view class="login-title">支付宝扫码登录</view>
<view class="qrcode-container">
<view class="qrcode-wrapper" @click="refreshQrcode">
<view class="qrcode-border">
<view class="qrcode-content">
<view class="qrcode-pattern">
<image
class="qrcode-img"
src="@/static/icon/qrcode-example.png"
mode="scaleToFill"
/>
<view class="qrcode-corner top-left"></view>
<view class="qrcode-corner top-right"></view>
<view class="qrcode-corner bottom-left"></view>
<view class="scan-line" :style="{ top: scanLineTop + 'rpx' }"></view>
</view>
<!-- 二维码过期提示 -->
<view v-if="qrcodeExpired" class="expired-overlay">
<text class="expired-text">二维码已过期</text>
<view class="refresh-btn" @click.stop="refreshQrcode">
<text class="refresh-text">点击刷新</text>
</view>
</view>
</view>
</view>
<view class="qrcode-tips">
<text class="tips-text">使用支付宝扫一扫登录</text>
<text class="tips-subtext">扫一扫后点击确认完成登录</text>
</view>
</view>
</view>
<!-- 刷新提示 -->
<view class="refresh-tips" v-if="countdown > 0">
<view class="countdown-text">
<span class="countdown-num">{{ countdown }}</span>
秒后二维码过期
</view>
</view>
</view>
<!-- 扫码成功提示 -->
<view v-if="showSuccessTip" class="success-tip">
<view class="success-content">
<view class="success-icon"></view>
<text class="success-text">登录成功</text>
</view>
</view>
</view>
<!-- 正常登录-->
<tabcontrolVue v-else :current="tabCurrent">
<template v-slot:tab0>
<view class="login-content">
<image class="logo" src="@/static/logo.png"></image>
@@ -110,21 +164,23 @@
</tabcontrolVue>
<SelectJobs ref="selectJobsModel"></SelectJobs>
<!-- 后门 -->
<!-- <view class="backdoor" @click="loginbackdoor">
<uni-icons type="gift-filled" size="30"></uni-icons>
</view> -->
<view class="backdoor" @click="loginbackdoor">
<my-icons type="gift-filled" size="60"></my-icons>
</view>
</AppLayout>
</template>
<script setup>
import { storeToRefs } from 'pinia';
import tabcontrolVue from './components/tabcontrol.vue';
import SelectJobs from '@/components/selectJobs/selectJobs.vue';
import { reactive, inject, watch, ref, onMounted } from 'vue';
import { reactive, inject, watch, ref, onMounted, onUnmounted } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import useUserStore from '@/stores/useUserStore';
import useDictStore from '@/stores/useDictStore';
const { $api, navTo } = inject('globalFunction');
const { loginSetToken, getUserResume } = useUserStore();
const { isMachineEnv } = storeToRefs(useUserStore());
const { getDictSelectOption, oneDictData } = useDictStore();
const openSelectPopup = inject('openSelectPopup');
// status
@@ -152,12 +208,71 @@ const fromValue = reactive({
experience: '1',
});
// 扫码登录相关状态
const qrcodeExpired = ref(false);
const scanLineTop = ref(0);
const countdown = ref(0);
let scanInterval = null;
let countdownTimer = null;
// 登录成功提示
const showSuccessTip = ref(false);
onLoad((parmas) => {
getTreeselect();
$api.msg('请完善微简历');
if (!isMachineEnv.value) $api.msg('请完善微简历');
});
onMounted(() => {});
onMounted(() => {
startScanAnimation();
resetCountdown();
// 模拟扫码成功
setTimeout(() => {
// showSuccessTip.value=true
}, 5000);
});
onUnmounted(() => {
showSuccessTip.value = false;
stopScanAnimation();
clearInterval(countdownTimer);
});
// 刷新二维码
const refreshQrcode = () => {
qrcodeExpired.value = false;
resetCountdown();
startScanAnimation();
// TODO
};
// 重置倒计时
const resetCountdown = () => {
countdown.value = 60;
clearInterval(countdownTimer);
countdownTimer = setInterval(() => {
if (countdown.value > 0) {
countdown.value--;
} else {
qrcodeExpired.value = true;
clearInterval(countdownTimer);
stopScanAnimation();
}
}, 1000);
};
// 开始扫描动画
const startScanAnimation = () => {
clearInterval(scanInterval);
scanInterval = setInterval(() => {
scanLineTop.value = (scanLineTop.value + 2) % 300;
}, 30);
};
// 停止扫描动画
const stopScanAnimation = () => {
clearInterval(scanInterval);
};
function changeSex(sex) {
fromValue.sex = sex;
@@ -250,6 +365,11 @@ function getTreeselect() {
}
function loginbackdoor() {
if (isMachineEnv.value) {
useUserStore().logOutApp();
$api.msg('返回首页');
return;
}
$api.createRequest('/app/mock/login', {}, 'post').then((resData) => {
$api.msg('模拟帐号密码测试登录成功');
loginSetToken(resData.token).then((resume) => {
@@ -311,6 +431,449 @@ function complete() {
}
</script>
<style lang="scss" scoped>
.alipay-login-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* 扫码登录区域样式 */
.login-scan-area {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 40rpx;
}
.login-title {
font-size: 36rpx;
font-weight: 600;
color: #1677ff;
margin-bottom: 40rpx;
text-align: center;
}
.qrcode-container {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 40rpx;
}
.qrcode-wrapper {
display: flex;
flex-direction: column;
align-items: center;
}
.qrcode-border {
width: 400rpx;
height: 400rpx;
background-color: #fff;
border-radius: 20rpx;
padding: 20rpx;
box-shadow: 0 8rpx 30rpx rgba(22, 119, 255, 0.1);
margin-bottom: 30rpx;
position: relative;
}
.qrcode-content {
width: 100%;
height: 100%;
background-color: #f8f8f8;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.qrcode-pattern {
width: 300rpx;
height: 300rpx;
background-color: #fff;
position: relative;
}
.qrcode-img {
width: 100%;
height: 100%;
}
.qrcode-corner {
position: absolute;
width: 60rpx;
height: 60rpx;
border: 6rpx solid #1677ff;
&.top-left {
top: 0;
left: 0;
border-right: none;
border-bottom: none;
border-radius: 10rpx 0 0 0;
}
&.top-right {
top: 0;
right: 0;
border-left: none;
border-bottom: none;
border-radius: 0 10rpx 0 0;
}
&.bottom-left {
bottom: 0;
left: 0;
border-right: none;
border-top: none;
border-radius: 0 0 0 10rpx;
}
}
.scan-line {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 6rpx;
background: linear-gradient(90deg, transparent, #1677ff, transparent);
z-index: 10;
}
.expired-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
border-radius: 10rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 20;
}
.expired-text {
font-size: 32rpx;
color: #fff;
margin-bottom: 30rpx;
}
.refresh-btn {
padding: 16rpx 40rpx;
background-color: #1677ff;
border-radius: 50rpx;
}
.refresh-text {
font-size: 28rpx;
color: #fff;
}
.qrcode-tips {
display: flex;
flex-direction: column;
align-items: center;
}
.tips-text {
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.tips-subtext {
font-size: 24rpx;
color: #666;
}
.refresh-tips {
margin-bottom: 40rpx;
}
.countdown-text {
font-size: 24rpx;
color: #999;
display: flex;
align-items: center;
}
.countdown-num {
margin-right: 5rpx;
color: #1677ff;
font-size: 30rpx;
}
.switch-method {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 0;
border-top: 1rpx solid #f0f0f0;
}
.switch-text {
font-size: 28rpx;
color: #666;
}
.switch-btn {
display: flex;
align-items: center;
}
.btn-text {
font-size: 28rpx;
color: #1677ff;
margin-right: 10rpx;
}
.icon-arrow {
font-size: 28rpx;
color: #1677ff;
}
/* 账号密码登录区域样式 */
.login-password-area {
width: 100%;
display: flex;
flex-direction: column;
padding: 0 40rpx;
}
.password-header {
display: flex;
align-items: center;
margin-bottom: 60rpx;
}
.back-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
}
.icon-back {
font-size: 36rpx;
color: #333;
}
.login-form {
width: 100%;
}
.form-item {
margin-bottom: 40rpx;
position: relative;
}
.item-label {
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.item-input {
width: 100%;
height: 80rpx;
background-color: #f8f8f8;
border-radius: 10rpx;
padding: 0 24rpx;
font-size: 28rpx;
color: #333;
}
.input-placeholder {
color: #999;
font-size: 28rpx;
}
.forget-password {
position: absolute;
right: 0;
top: 0;
font-size: 26rpx;
color: #1677ff;
}
.login-btn {
width: 100%;
height: 90rpx;
background-color: #1677ff;
border-radius: 50rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 60rpx;
&.disabled {
background-color: #a0cfff;
}
}
.login-btn-text {
font-size: 32rpx;
color: #fff;
font-weight: 500;
}
.agreement {
display: flex;
align-items: center;
justify-content: center;
margin-top: 40rpx;
flex-wrap: wrap;
}
.agreement-checkbox {
margin-right: 10rpx;
}
.checkbox-icon {
width: 32rpx;
height: 32rpx;
border-radius: 6rpx;
border: 2rpx solid #ddd;
display: flex;
align-items: center;
justify-content: center;
&.checked {
background-color: #1677ff;
border-color: #1677ff;
}
}
.checkmark {
font-size: 24rpx;
color: #fff;
}
.agreement-text {
font-size: 24rpx;
color: #666;
margin-right: 6rpx;
}
.agreement-link {
font-size: 24rpx;
color: #1677ff;
margin-right: 6rpx;
}
.other-login {
margin-top: 80rpx;
}
.other-title {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 50rpx;
}
.title-line {
flex: 1;
height: 1rpx;
background-color: #eee;
}
.title-text {
font-size: 24rpx;
color: #999;
margin: 0 20rpx;
}
.login-methods {
display: flex;
justify-content: center;
gap: 100rpx;
}
.method-item {
display: flex;
flex-direction: column;
align-items: center;
}
.method-icon {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 40rpx;
color: #fff;
margin-bottom: 20rpx;
&.scan-icon {
background-color: #1677ff;
}
&.sms-icon {
background-color: #52c41a;
}
}
.method-text {
font-size: 24rpx;
color: #666;
}
/* 登录成功提示 */
.success-tip {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.success-content {
background-color: #fff;
border-radius: 20rpx;
padding: 60rpx 80rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.success-icon {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background-color: #52c41a;
display: flex;
align-items: center;
justify-content: center;
font-size: 60rpx;
color: #fff;
margin-bottom: 30rpx;
}
.success-text {
font-size: 32rpx;
color: #333;
}
</style>
<style lang="stylus" scoped>
.backdoor{
position: fixed;

View File

@@ -62,7 +62,7 @@
<text class="left-text">素质测评</text>
</view>
<view class="row-right">
<uni-icons color="#909090" type="right" size="14"></uni-icons>
<my-icons color="#909090" type="right" size="28"></my-icons>
</view>
</view>
<view class="main-row btn-feel" @click="handleItemClick('模拟面试')">
@@ -71,7 +71,7 @@
<text class="left-text">AI面试</text>
</view>
<view class="row-right">
<uni-icons color="#909090" type="right" size="14"></uni-icons>
<my-icons color="#909090" type="right" size="28"></my-icons>
</view>
</view>
<view class="main-row btn-feel">
@@ -82,7 +82,7 @@
<view class="row-right">已开启</view>
</view>
</view>
<!-- <view class="card-back button-click" @click="logOut">退出登录</view> -->
<view class="card-back button-click" v-if="isMachineEnv" @click="logOut">退出登录</view>
<uni-popup ref="popup" type="dialog">
<uni-popup-dialog
mode="base"
@@ -95,9 +95,9 @@
></uni-popup-dialog>
</uni-popup>
</view>
<!-- <template #footer>
<Tabbar :currentpage="4"></Tabbar>
</template> -->
<template #footer>
<Tabbar v-show="showTabbar" :currentpage="4"></Tabbar>
</template>
</AppLayout>
</template>
@@ -110,8 +110,22 @@ import FileUploader from '@/utils/FileUploader.js';
import config from '@/config';
const { $api, navTo } = inject('globalFunction');
import useUserStore from '@/stores/useUserStore';
const popup = ref(null);
const { userInfo, Completion, counts } = storeToRefs(useUserStore());
const { userInfo, Completion, counts, isMachineEnv } = storeToRefs(useUserStore());
import useScreenStore from '@/stores/useScreenStore';
const screenStore = useScreenStore();
const showTabbar = ref(false);
watch(
() => screenStore.isWideScreen,
(newVal) => {
showTabbar.value = newVal;
},
{ immediate: true }
);
function logOut() {
popup.value.open();

View File

@@ -40,7 +40,7 @@
</swiper>
</view>
<!-- <Tabbar :currentpage="3"></Tabbar> -->
<Tabbar v-show="showTabbar" :currentpage="3"></Tabbar>
</view>
</view>
</template>
@@ -58,6 +58,19 @@ import { storeToRefs } from 'pinia';
import { useReadMsg } from '@/stores/useReadMsg';
const { unreadCount } = storeToRefs(useReadMsg());
import useScreenStore from '@/stores/useScreenStore'
const screenStore = useScreenStore()
const showTabbar = ref(false)
watch(
() => screenStore.isWideScreen,
(newVal) => {
showTabbar.value = newVal
},
{ immediate: true }
)
const disableTouch = ref(false);
const startPointX = ref(0);
const totalPage = 2;

View File

@@ -5,7 +5,7 @@
<text>热门商圈</text>
<text class="color_333333 button-click" @click="handleOpenBusinessDistrict">
更多
<uni-icons type="forward" color="#333333" size="14"></uni-icons>
<my-icons type="forward" color="#333333" size="28"></my-icons>
</text>
</view>
<scroll-view class="scroll-head" :scroll-x="true" :scroll-into-view="activeTab" :show-scrollbar="false">
@@ -46,7 +46,7 @@
</view>
</scroll-view>
<view class="jobs-add button-click" @click="navTo('/packageA/pages/addPosition/addPosition')">
<uni-icons class="iconsearch" color="#666D7F" type="plusempty" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666D7F" type="plusempty" size="36"></my-icons>
<text>添加</text>
</view>
</view>

View File

@@ -2,7 +2,7 @@
<scroll-view :scroll-y="true" class="nearby-scroll" @scrolltolower="scrollBottom">
<view class="nearby-map" @touchmove.stop.prevent>
<map
style="width: 100%; height: 400px"
style="width: 100%; height:410rpx "
:latitude="latitudeVal"
:longitude="longitudeVal"
:markers="mapCovers"
@@ -51,7 +51,7 @@
</view>
</scroll-view>
<view class="jobs-add button-click" @click="navTo('/packageA/pages/addPosition/addPosition')">
<uni-icons class="iconsearch" color="#666D7F" type="plusempty" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666D7F" type="plusempty" size="36"></my-icons>
<text>添加</text>
</view>
</view>
@@ -362,11 +362,11 @@ defineExpose({ loadData, handleFilterConfirm });
height: 100%;
background: #f4f4f4;
.nearby-map
height: 767rpx;
height: 400rpx;
background: #e8e8e8;
overflow: hidden
.nearby-list
min-height: calc(100% - 384rpx)
min-height: calc(100% - 400rpx)
background: #f4f4f4
display: flex;
flex-direction: column;

View File

@@ -72,7 +72,7 @@
</view>
</scroll-view>
<view class="jobs-add button-click" @click="navTo('/packageA/pages/addPosition/addPosition')">
<uni-icons class="iconsearch" color="#666D7F" type="plusempty" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666D7F" type="plusempty" size="36"></my-icons>
<text>添加</text>
</view>
</view>

View File

@@ -42,7 +42,7 @@
</view>
</scroll-view>
<view class="jobs-add button-click" @click="navTo('/packageA/pages/addPosition/addPosition')">
<uni-icons class="iconsearch" color="#666D7F" type="plusempty" size="18"></uni-icons>
<my-icons class="iconsearch" color="#666D7F" type="plusempty" size="36"></my-icons>
<text>添加</text>
</view>
</view>

View File

@@ -9,13 +9,13 @@
@click="navBack"
></image>
<view class="search-box">
<uni-icons
<my-icons
class="iconsearch"
color="#666666"
type="search"
size="18"
size="36"
@confirm="searchCollection"
></uni-icons>
></my-icons>
<input
class="inputed"
type="text"
@@ -73,7 +73,7 @@
<view class="content-top">
<view class="top-left">历史搜索</view>
<view class="top-right button-click" @click="remove">
<uni-icons type="trash" color="#C1C1C1" size="20"></uni-icons>
<my-icons type="trash" color="#C1C1C1" size="40"></my-icons>
</view>
</view>
<view class="content-history">
@@ -155,7 +155,11 @@ const { columnCount, columnSpace } = useColumnCount(() => {
});
});
onLoad(() => {
onLoad((options) => {
if(options.keyWord){
searchValue.value = decodeURIComponent(options.keyWord)
searchBtn()
}
let arr = uni.getStorageSync('searchList');
if (arr) {
historyList.value = uni.getStorageSync('searchList');

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 B

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

69
static/js/jsbridge.js Normal file
View File

@@ -0,0 +1,69 @@
(() => {
if (!/android/.test(navigator.userAgent.toLowerCase())) {
console.error("当前环境不支持WebView桥接通信, 请检查是否为安卓环境");
return
}
let bridge;
function setupWebViewJavascriptBridge(callback) {
return new Promise((reslove, reject) => {
if (window.WebViewJavascriptBridge) {
bridge = window.WebViewJavascriptBridge;
callback && callback()
reslove()
} else {
document.addEventListener(
"WebViewJavascriptBridgeReady",
function () {
bridge = window.WebViewJavascriptBridge;
callback && callback()
reslove()
},
false
);
}
})
}
let funcs = {}
setupWebViewJavascriptBridge(() => {
bridge.init()
bridge.registerHandler("ampeHHCommunication", (data) => {
console.log('[zyh][registerHandler]',data);
data = JSON.parse(data || '{}');
let eventName = data.eventName || '{}';
let eventData = JSON.parse(data.eventData || '{}');
if (funcs[eventName]) {
for (let callback of funcs[eventName]) {
callback({type: eventName, data: eventData})
}
}
});
})
window.hh = {
async call(funcName, params, callback) {
if (!bridge) {
await setupWebViewJavascriptBridge()
}
bridge.callHandler(funcName, params, callback);
},
async on(funcName, callback) {
if (funcs[funcName]) {
funcs[funcName].add(callback)
} else {
funcs[funcName] = new Set([callback])
}
},
off(funcName, callback) {
if (!funcs[funcName]) {
return false
}
if (!callback) {
return delete funcs[funcName]
}
let res = funcs[funcName].delete(callback)
if(funcs[funcName].size <= 0) {
delete funcs[funcName]
}
return res
}
};
})();

View File

@@ -14,26 +14,47 @@ const useLocationStore = defineStore("location", () => {
const longitudeVal = ref(null) // 经度
const latitudeVal = ref(null) //纬度
function getLocation() {
function getLocation() { // 获取经纬度两个平台
return new Promise((resole, reject) => {
try {
lightAppJssdk.map.getLocation({
success: function(data) {
longitudeVal.value = Number(data.longitude)
latitudeVal.value = Number(data.latitude)
resole(data)
},
fail: function(data) {
longitudeVal.value = 120.382665
latitudeVal.value = 36.066938
resole({
longitude: 120.382665,
latitude: 36.066938
})
msg('用户位置获取失败')
console.log('失败', data)
}
})
if (lightAppJssdk.map) {
lightAppJssdk.map.getLocation({
success: function(data) {
longitudeVal.value = Number(data.longitude)
latitudeVal.value = Number(data.latitude)
resole(data)
},
fail: function(data) {
longitudeVal.value = 120.382665
latitudeVal.value = 36.066938
resole({
longitude: 120.382665,
latitude: 36.066938
})
msg('用户位置获取失败')
}
})
} else {
uni.getLocation({
type: 'gcj02',
highAccuracyExpireTime: 3000,
isHighAccuracy: true,
success: function(data) {
longitudeVal.value = Number(data.longitude)
latitudeVal.value = Number(data.latitude)
resole(data)
},
fail: function(data) {
longitudeVal.value = 120.382665
latitudeVal.value = 36.066938
resole({
longitude: 120.382665,
latitude: 36.066938
})
msg('用户位置获取失败')
}
});
}
} catch (e) {
longitudeVal.value = 120.382665
latitudeVal.value = 36.066938

283
stores/useScreenStore.js Normal file
View File

@@ -0,0 +1,283 @@
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
// 屏幕检测管理器类
class ScreenDetectionManager {
constructor() {
this.WIDE_SCREEN_CSS_ID = 'wide-screen-css';
this.WIDE_SCREEN_CSS_PATH = '../common/wide-screen.css';
this.resizeTimer = null;
this.resizeListeners = [];
this.cssLink = null;
}
// 获取屏幕宽度
getScreenWidth() {
if (typeof window === 'undefined') return 0;
// 优先使用 uni.getSystemInfo
if (typeof uni !== 'undefined' && uni.getSystemInfo) {
return new Promise((resolve) => {
uni.getSystemInfo({
success: (res) => {
const width = res.screenWidth || res.windowWidth || window.innerWidth;
resolve(width);
},
fail: () => {
resolve(this.getWindowWidth());
}
});
});
}
return Promise.resolve(this.getWindowWidth());
}
// 备用方案:使用 window 对象
getWindowWidth() {
if (typeof window === 'undefined') return 0;
return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
}
// 检测折叠屏
checkVisualViewport() {
if (window.visualViewport?.segments?.length > 1) {
return {
foldable: true,
count: window.visualViewport.segments.length - 1
}
}
else {
return {
foldable: false,
count: 1
}
}
}
// 动态加载 CSS
loadWideScreenCSS() {
if (typeof window === 'undefined' || this.cssLink) return null;
try {
this.cssLink = document.createElement('link');
this.cssLink.id = this.WIDE_SCREEN_CSS_ID;
this.cssLink.rel = 'stylesheet';
this.cssLink.href = this.WIDE_SCREEN_CSS_PATH;
// 添加加载成功/失败监听
this.cssLink.onload = () => {
console.log('🎨 宽屏 CSS 文件加载成功');
};
this.cssLink.onerror = () => {
console.error('❌ 宽屏 CSS 文件加载失败');
this.cssLink = null;
};
document.head.appendChild(this.cssLink);
return this.cssLink;
} catch (error) {
console.error('加载 CSS 失败:', error);
this.cssLink = null;
return null;
}
}
// 移除 CSS
removeWideScreenCSS() {
if (this.cssLink && this.cssLink.parentNode) {
try {
this.cssLink.parentNode.removeChild(this.cssLink);
this.cssLink = null;
console.log('🗑️ 宽屏 CSS 文件已移除');
return true;
} catch (error) {
console.error('移除 CSS 失败:', error);
return false;
}
}
return false;
}
// 更新 CSS 状态
updateWideScreenCSS(isWideScreen) {
if (isWideScreen) {
return this.loadWideScreenCSS();
} else {
return this.removeWideScreenCSS();
}
}
//显示/隐藏默认tabbar
updateTabbar(isWideScreen){
if(isWideScreen) uni.hideTabBar()
else uni.showTabBar()
}
// 添加 resize 监听器
addResizeListener(callback, delay = 250) {
if (typeof window === 'undefined') return () => {};
const handler = () => {
clearTimeout(this.resizeTimer);
this.resizeTimer = setTimeout(() => {
callback();
}, delay);
};
window.addEventListener('resize', handler);
this.resizeListeners.push({ callback, handler });
// 返回清理函数
return () => this.removeResizeListener(callback);
}
// 移除 resize 监听器
removeResizeListener(callback) {
const index = this.resizeListeners.findIndex(item => item.callback === callback);
if (index > -1) {
const { handler } = this.resizeListeners[index];
window.removeEventListener('resize', handler);
this.resizeListeners.splice(index, 1);
}
}
}
// 创建屏幕状态 store
const useScreenStore = defineStore('screen', () => {
// 状态
const screenWidth = ref(0);
const isInitialized = ref(false);
const isLoading = ref(false);
const foldFeature = ref(false);
const foldCount = ref(0);
const isWideScreen = computed(() => {
return screenWidth.value >= 900;
});
// 管理器实例
const manager = new ScreenDetectionManager();
// 初始化屏幕检测
const initScreenDetection = async () => {
if (isLoading.value || isInitialized.value) return;
isLoading.value = true;
try {
// 检测屏幕状态
const width = await manager.getScreenWidth();
const { foldable, count } = manager.checkVisualViewport();
foldFeature.value = foldable;
foldCount.value = count;
screenWidth.value = width;
isInitialized.value = true;
console.log(`📱 屏幕检测完成: ${width}px, 宽屏: ${isWideScreen.value}`);
console.log(`是否为折叠屏: ${foldFeature.value},折叠屏数量:${foldCount.value}`);
// 根据状态加载或移除 CSS
manager.updateWideScreenCSS(isWideScreen.value);
manager.updateTabbar(isWideScreen.value);
// 设置 resize 监听
setupResizeListener();
return {
screenWidth: width,
isWideScreen: isWideScreen.value,
foldable,
count
};
} catch (error) {
console.error('初始化屏幕检测失败:', error);
return null;
} finally {
isLoading.value = false;
}
};
// 手动更新屏幕状态
const updateScreenStatus = async () => {
try {
const width = await manager.getScreenWidth();
const { foldable, count } = manager.checkVisualViewport();
// 保存旧状态
const oldWidth = screenWidth.value;
const oldIsWideScreen = isWideScreen.value;
const oldFoldable = foldFeature.value;
const oldFoldCount = foldCount.value;
// 更新状态
screenWidth.value = width;
foldFeature.value = foldable;
foldCount.value = count;
// 检查宽屏状态是否发生变化
if (oldIsWideScreen !== isWideScreen.value) {
console.log(`🔄 屏幕状态变化: ${oldIsWideScreen ? '宽屏' : '非宽屏'} -> ${isWideScreen.value ? '宽屏' : '非宽屏'}`);
console.log(`屏幕宽度变化: ${oldWidth}px -> ${width}px`);
manager.updateWideScreenCSS(isWideScreen.value);
manager.updateTabbar(isWideScreen.value);
}
// 检查折叠屏状态是否发生变化
if (oldFoldable !== foldable || oldFoldCount !== count) {
console.log(`折叠屏状态变化: ${oldFoldable ? '是' : '否'}->${foldable ? '是' : '否'}, 折叠数: ${oldFoldCount}->${count}`);
}
return {
screenWidth: width,
isWideScreen: isWideScreen.value,
foldable,
count
};
} catch (error) {
console.error('更新屏幕状态失败:', error);
return null;
}
};
// 设置 resize 监听
let cleanupResizeListener = () => {};
const setupResizeListener = () => {
if (typeof window === 'undefined') return;
cleanupResizeListener = manager.addResizeListener(async () => {
await updateScreenStatus();
}, 300);
};
// 手动触发屏幕检测
const detectScreen = () => {
return updateScreenStatus();
};
return {
// 状态
foldFeature,
foldCount,
screenWidth,
isInitialized,
isLoading,
// 响应式计算属性
isWideScreen,
// 方法
initScreenDetection,
updateScreenStatus,
detectScreen,
};
});
export default useScreenStore;

View File

@@ -18,6 +18,7 @@ import {
msg,
$api,
} from '../common/globalFunction';
import baseDB from '@/utils/db.js';
// 简历完成度计算
function getResumeCompletionPercentage(resume) {
@@ -59,6 +60,7 @@ const useUserStore = defineStore("user", () => {
const seesionId = ref('')
const counts = ref({})
const isMiniProgram = ref(false)
const isMachineEnv = ref(false)
const login = (value) => {
hasLogin.value = true;
@@ -84,6 +86,20 @@ const useUserStore = defineStore("user", () => {
});
}
const logOutApp = () => {
hasLogin.value = false;
token.value = ''
resume.value = {}
userInfo.value = {}
role.value = {}
uni.clearStorageSync('userInfo')
uni.clearStorageSync('token')
uni.switchTab({
url: '/pages/index/index',
});
}
const getUserInfo = () => {
return new Promise((reslove, reject) => {
createRequest('/getInfo', {}, 'get').then((userInfo) => {
@@ -110,7 +126,9 @@ const useUserStore = defineStore("user", () => {
// 获取消息列表
useReadMsg().fetchMessages()
// 获取用户信息
return getUserResume()
const resume = await getUserResume()
await baseDB.init(); // 登录成功初始化
return resume
}
const setUserInfo = (values) => {
@@ -145,6 +163,9 @@ const useUserStore = defineStore("user", () => {
isMiniProgram.value = val
}
function changMachineEnv(val) {
isMachineEnv.value = val
}
// 导入
return {
@@ -154,6 +175,7 @@ const useUserStore = defineStore("user", () => {
resume,
login,
logOut,
logOutApp,
loginSetToken,
getUserResume,
initSeesionId,
@@ -162,7 +184,9 @@ const useUserStore = defineStore("user", () => {
getUserstatistics,
counts,
isMiniProgram,
changMiniProgramAppStatus
changMiniProgramAppStatus,
changMachineEnv,
isMachineEnv
}
}, {
unistorage: true,

View File

@@ -34,11 +34,12 @@ const useChatGroupDBStore = defineStore("messageGroup", () => {
const chatSessionID = ref('')
const lastDateRef = ref('')
async function init() {
async function init() { // 初始化数据,有则用,无则更新
// 获取所有数据
setTimeout(async () => {
if (!baseDB.isDBReady) await baseDB.initDB();
const result = await baseDB.db.getAll(tableName.value);
console.log('result', result)
// 1、判断是否有数据没数据请求服务器
if (result.length) {
console.warn('本地数据库存在数据')
@@ -216,7 +217,7 @@ const useChatGroupDBStore = defineStore("messageGroup", () => {
userBadFeedback: content,
}
$api.chatRequest('/stepped', parmas, 'POST').then((res) => {
$api.createRequest('/stepped', parmas, 'POST').then((res) => {
baseDB.db.update(massageName.value, dbData) // 更新本地数据库
messages.value.forEach((item) => {
if (item.id === dbData.id) {
@@ -230,7 +231,7 @@ const useChatGroupDBStore = defineStore("messageGroup", () => {
// 云端数据
function getHistory() {
$api.chatRequest('/app/chat/getHistory').then((res) => {
$api.createRequest('/app/chat/getHistory').then((res) => {
if (!res.data.list.length) return
let tabel = parseHistory(res.data.list)
if (tabel && tabel.length) {
@@ -250,14 +251,14 @@ const useChatGroupDBStore = defineStore("messageGroup", () => {
const params = {
sessionId: chatSessionID.value
}
$api.chatRequest('/app/chat/detail', params, 'GET', loading).then((res) => {
$api.createRequest('/app/chat/detail', params, 'GET', loading).then((res) => {
let list = parseHistoryDetail(res.data.list, chatSessionID.value)
if (list.length) {
baseDB.db.add(massageName.value, list).then((ids) => {
messages.value = listAddId(list, ids)
});
}
console.log('解析后:', list)
// console.log('解析后:', list)
}).catch(() => {
msg('请求出现异常,请联系工作人员')
})

View File

@@ -1,24 +1,50 @@
// BaseDBStore.js
import IndexedDBHelper from '@/common/IndexedDBHelper.js'
// import UniStorageHelper from '../common/UniStorageHelper'
import useChatGroupDBStore from '@/stores/userChatGroupStore'
import config from '@/config'
class BaseStore {
db = null
isDBReady = false
dbName = 'BrowsingHistory' // 'AppMainDB'
dbName = 'AppMainDB'
initPromise = null
constructor() {
this.initPromise = this.checkAndInitDB()
// 不再自动执行初始化
}
async getDB() {
if (!this.initPromise) {
this.initPromise = this.checkAndInitDB();
/**
* 手动初始化入口、建立连接、如果版本号不对付才会清理
* 建议在登录成功后调用await baseDB.init()
*/
async init() {
// 如果已经有初始化任务在进行了,直接返回该任务
if (this.initPromise) {
return this.initPromise;
}
// 创建初始化任务
this.initPromise = this.checkAndInitDB();
try {
await this.initPromise;
console.log('数据库初始化成功');
} catch (error) {
this.initPromise = null; // 初始化失败允许下次重试
console.error('数据库初始化失败:', error);
throw error;
}
return this.db;
}
/**
* 获取数据库实例
* 如果没初始化,会强制触发一次 init
*/
async getDB() {
if (!this.isDBReady) {
return await this.init();
}
await this.initPromise; // 等待初始化完成
return this.db;
}
@@ -28,30 +54,28 @@ class BaseStore {
}
const localVersion = uni.getStorageSync('indexedDBVersion') || 1
console.log('DBVersion: ', localVersion, config.DBversion)
if (localVersion === config.DBversion) {
return this.initDB() // 🟢 记得加 return
if (Number(localVersion) === Number(config.DBversion)) {
return this.initDB()
} else {
console.log('清空本地数据库')
await this.clearDB() // 🟢 建议用 await
console.log('检测到版本更新,清空重置旧数据库')
await this.clearDB()
uni.setStorageSync('indexedDBVersion', config.DBversion);
return this.initDB(); // 🟢 记得加 return
return this.initDB();
}
}
initDB() {
// // #ifdef H5
this.db = new IndexedDBHelper(this.dbName, config.DBversion);
// // #endif
return this.db.openDB([{
name: 'record',
keyPath: "id",
autoIncrement: true,
autoIncrement: true
},
{
name: 'messageGroup',
keyPath: "id",
autoIncrement: true,
autoIncrement: true
},
{
name: 'messages',
@@ -65,12 +89,12 @@ class BaseStore {
},
{
name: 'api_cache',
keyPath: "cacheKey", // 使用 URL+参数 作为主键
keyPath: "cacheKey",
indexes: []
}
]).then(async () => {
// 这里原来的逻辑保留
if (useChatGroupDBStore) {
// 确保 Pinia Store 已准备好后再初始化子项
useChatGroupDBStore().init()
}
this.isDBReady = true
@@ -79,13 +103,44 @@ class BaseStore {
}
async clearDB() {
return new Promise((resolve, rejetc) => {
new IndexedDBHelper().deleteDB(this.dbName).then(() => {
resolve()
})
})
// 修正拼写错误并优化 Promise 写法
return new IndexedDBHelper().deleteDB(this.dbName);
}
/**
* 彻底清空数据库并重新初始化
* 适用于切换账号或手动清理缓存
* 非特殊情况不要重置!!!!!!!!!!!!!!!
*/
async resetAndReinit() {
console.warn('开始执行数据库重置...');
if (this.db && this.db.db) {
this.db.db.close();
}
try {
await this.clearDB();
// 3. 重置内部状态
this.db = null;
this.isDBReady = false;
this.initPromise = null;
uni.setStorageSync('indexedDBVersion', config.DBversion);
// 5. 重新调用初始化流程
await this.init();
console.log('数据库重置及初始化完成');
return true;
} catch (error) {
console.error('数据库重置失败:', error);
throw error;
}
}
}
// 导出实例
const baseDB = new BaseStore()
export default baseDB

View File

@@ -126,20 +126,24 @@ const jobAnalyzer = {
_mergeAllStats: (results) => {
const merged = {}
// 合并岗位类别(添加前缀)
Object.entries(results.categories).forEach(([k, v]) => {
merged[`岗位:${k}`] = v
})
try {
// 合并岗位类别(添加前缀)
Object.entries(results.categories).forEach(([k, v]) => {
merged[`岗位:${k}`] = v
})
// 合并工作地区(添加前缀)
Object.entries(results.areas).forEach(([k, v]) => {
merged[`地区:${k}`] = v
})
// 合并工作地区(添加前缀)
Object.entries(results.areas).forEach(([k, v]) => {
merged[`地区:${k}`] = v
})
// 合并经验要求(添加前缀)
Object.entries(results.experience).forEach(([k, v]) => {
merged[`经验:${k}`] = v
})
// 合并经验要求(添加前缀)
Object.entries(results.experience).forEach(([k, v]) => {
merged[`经验:${k}`] = v
})
} catch (error) {
return merged
}
return merged
},

View File

@@ -82,7 +82,8 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h
})
}
let header = {
...headers
...headers,
'X-Target-URI': url
};
const userStore = useUserStore();
const token = userStore.token;
@@ -117,7 +118,8 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h
// ------------------------------------------------------------------
return new Promise((resolve, reject) => {
uni.request({
url: config.baseUrl + url,
url: config.baseUrl + '/app/proxy',
// url: config.baseUrl + url,
method: method,
data: requestData,
header,