flat: 暂存,新增一体机sdk,和一体机环境

This commit is contained in:
Apcallover
2025-12-16 15:36:42 +08:00
parent 33f1d0a8ab
commit 77dfab84f1
11 changed files with 214 additions and 60 deletions

50
App.vue
View File

@@ -11,26 +11,32 @@ const appword = 'aKd20dbGdFvmuwrt'; // 固定值
onLaunch((options) => {
useDictStore().getDictData();
try {
if (lightAppJssdk.user) {
console.warn('爱山东环境');
getUserInfo();
useUserStore().changMiniProgramAppStatus(false);
} catch {
console.log('不是爱山东平台,使用测试登陆');
return;
}
if (window.hh) {
console.warn('求职一体机环境');
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().initSeesionId(); //更新
let token = uni.getStorageSync('token') || '';
if (token) {
useUserStore()
.loginSetToken(token)
.then(() => {
$api.msg('登录成功');
});
} else {
safeReLaunch('/pages/login/login');
}
});
@@ -110,15 +116,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',
// });
}
});
});
@@ -130,7 +130,6 @@ function loginCallback(userInfo) {
@import '@/common/animation.css';
@import '@/common/common.css';
/* 修改pages tabbar样式 H5才有效 */
.uni-tabbar .uni-tabbar__item:nth-child(4) .uni-tabbar__bd .uni-tabbar__icon {
width: 108rpx !important;
@@ -163,7 +162,6 @@ uni-modal,
z-index: 998;
}
@font-face {
font-family: DingTalk JinBuTi;
src: url('/static/font/DingTalk JinBuTi_min.woff2') format('woff2');
@@ -184,7 +182,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;
}

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

@@ -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

@@ -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,12 +288,12 @@ function getCompanyIsAJobs(...args) {
if (dataType.value === 2) {
// 第三方数据获取公司职位数量
const [gsID, gsmc, zphID] = args;
const params={
const params = {
gsID,
gsmc,
zphID
}
$api.createRequest(`/app/internal/jobThirdPart`,params).then((resData) => {
zphID,
};
$api.createRequest(`/app/internal/jobThirdPart`, params).then((resData) => {
companyCount.value = resData.total;
});
} else {

View File

@@ -281,7 +281,7 @@
// "enablePullDownRefresh": false,
// "navigationStyle": "custom",
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcMaxDeviceWidth": 1200,
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcIncludeWidth": 750
},
"uniIdRouter": {}

View File

@@ -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';
@@ -316,6 +316,49 @@ const isLoaded = ref(false);
const colors = ['#0069FE', '#FF9400', '#FF6969', '#21EA85', '#87E2EC'];
const occupations = [
'律师',
'工程师',
'医生',
'教师',
'设计师',
'程序员',
'会计师',
'建筑师',
'护士',
'销售',
'经理',
'顾问',
'分析师',
'研究员',
'编辑',
'记者',
'摄影师',
'厨师',
'司机',
'保安',
'客服',
'行政',
'人事',
'市场',
'运营',
'产品',
'测试',
'运维',
'前端',
'后端',
'全栈',
'数据',
'策划',
'导演',
'演员',
'歌手',
'作家',
'画家',
'翻译',
'导游',
];
onMounted(() => {
let firstEntry = uni.getStorageSync('firstEntry') === false ? false : true; // 默认未读
maskFirstEntry.value = firstEntry;
@@ -323,17 +366,34 @@ onMounted(() => {
});
async function getMatchTags() {
try {
matchLoading.value = true;
const { data } = await $api.createRequest('/app/user/getJobAdviceByResume');
matchTags.value = data;
matchLoading.value = false;
} catch (err) {
console.err('简历匹配职位获取失败');
} finally {
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(() => {

View File

@@ -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"
@@ -112,22 +112,20 @@ 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()
import useScreenStore from '@/stores/useScreenStore';
const screenStore = useScreenStore();
const showTabbar = ref(false)
const showTabbar = ref(false);
watch(
() => screenStore.isWideScreen,
(newVal) => {
showTabbar.value = newVal
showTabbar.value = newVal;
},
{ immediate: true }
)
);
function logOut() {
popup.value.open();

Binary file not shown.

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

@@ -59,6 +59,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 +85,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) => {
@@ -145,6 +160,9 @@ const useUserStore = defineStore("user", () => {
isMiniProgram.value = val
}
function changMachineEnv(val) {
isMachineEnv.value = val
}
// 导入
return {
@@ -154,6 +172,7 @@ const useUserStore = defineStore("user", () => {
resume,
login,
logOut,
logOutApp,
loginSetToken,
getUserResume,
initSeesionId,
@@ -162,7 +181,9 @@ const useUserStore = defineStore("user", () => {
getUserstatistics,
counts,
isMiniProgram,
changMiniProgramAppStatus
changMiniProgramAppStatus,
changMachineEnv,
isMachineEnv
}
}, {
unistorage: true,