first commit

This commit is contained in:
chenyuanfang
2024-12-16 19:49:49 +08:00
parent e548e6bf85
commit 1514cc6d92
35 changed files with 2376 additions and 86 deletions
+154 -4
View File
@@ -8,8 +8,15 @@
"name": "career_assistant",
"version": "0.1.0",
"dependencies": {
"axios": "^1.7.9",
"core-js": "^3.8.3",
"vue": "^3.2.13"
"js-md5": "^0.8.3",
"sha1": "^1.1.1",
"vant": "^4.9.10",
"vue": "^3.2.13",
"vue-router": "^4.5.0",
"vuex": "^4.0.2",
"weixin-js-sdk": "^1.6.5"
},
"devDependencies": {
"@babel/core": "^7.12.16",
@@ -2160,6 +2167,19 @@
"@types/node": "*"
}
},
"node_modules/@vant/popperjs": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
"integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
},
"node_modules/@vant/use": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
"integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/@vue/babel-helper-vue-jsx-merge-props": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz",
@@ -2738,6 +2758,11 @@
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
"dev": true
},
"node_modules/@vue/devtools-api": {
"version": "6.6.4",
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
},
"node_modules/@vue/reactivity": {
"version": "3.5.13",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz",
@@ -3245,6 +3270,11 @@
"lodash": "^4.17.14"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
@@ -3291,6 +3321,16 @@
"postcss": "^8.1.0"
}
},
"node_modules/axios": {
"version": "1.7.9",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.9.tgz",
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/babel-loader": {
"version": "8.4.1",
"resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.4.1.tgz",
@@ -3719,6 +3759,14 @@
"node": ">=8"
}
},
"node_modules/charenc": {
"version": "0.0.2",
"resolved": "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz",
"integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
"engines": {
"node": "*"
}
},
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
@@ -3921,6 +3969,17 @@
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"dev": true
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz",
@@ -4163,6 +4222,14 @@
"semver": "bin/semver"
}
},
"node_modules/crypt": {
"version": "0.0.2",
"resolved": "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz",
"integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
"engines": {
"node": "*"
}
},
"node_modules/css-declaration-sorter": {
"version": "6.4.1",
"resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
@@ -4682,6 +4749,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
@@ -5876,7 +5951,6 @@
"version": "1.15.9",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"dev": true,
"funding": [
{
"type": "individual",
@@ -5892,6 +5966,19 @@
}
}
},
"node_modules/form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
@@ -6794,6 +6881,11 @@
"@sideway/pinpoint": "^2.0.0"
}
},
"node_modules/js-md5": {
"version": "0.8.3",
"resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz",
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
},
"node_modules/js-message": {
"version": "1.0.7",
"resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
@@ -7359,7 +7451,6 @@
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -7368,7 +7459,6 @@
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"dependencies": {
"mime-db": "1.52.0"
},
@@ -8864,6 +8954,11 @@
"node": ">= 0.10"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -9504,6 +9599,18 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"dev": true
},
"node_modules/sha1": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/sha1/-/sha1-1.1.1.tgz",
"integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==",
"dependencies": {
"charenc": ">= 0.0.1",
"crypt": ">= 0.0.1"
},
"engines": {
"node": "*"
}
},
"node_modules/shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/shallow-clone/-/shallow-clone-3.0.1.tgz",
@@ -10428,6 +10535,19 @@
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/vant": {
"version": "4.9.10",
"resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.10.tgz",
"integrity": "sha512-N+QwOuhDxrH2f6+kN05ot6DHBvaM0e1lcoXVvf12rad2KnlybPQ9gjm0d+R+Nz/zydZbe3Fz6bwTssHItri0sw==",
"dependencies": {
"@vant/popperjs": "^1.3.0",
"@vant/use": "^1.6.0",
"@vue/shared": "^3.5.13"
},
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
@@ -10591,6 +10711,20 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/vue-router": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz",
"integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==",
"dependencies": {
"@vue/devtools-api": "^6.6.4"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/vue-style-loader": {
"version": "4.1.3",
"resolved": "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
@@ -10613,6 +10747,17 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
"node_modules/vuex": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz",
"integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==",
"dependencies": {
"@vue/devtools-api": "^6.0.0-beta.11"
},
"peerDependencies": {
"vue": "^3.0.2"
}
},
"node_modules/watchpack": {
"version": "2.4.2",
"resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.2.tgz",
@@ -11036,6 +11181,11 @@
"node": ">=0.8.0"
}
},
"node_modules/weixin-js-sdk": {
"version": "1.6.5",
"resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.5.tgz",
"integrity": "sha512-Gph1WAWB2YN/lMOFB/ymb+hbU/wYazzJgu6PMMktCy9cSCeW5wA6Zwt0dpahJbJ+RJEwtTv2x9iIu0U4enuVSQ=="
},
"node_modules/whatwg-fetch": {
"version": "3.6.20",
"resolved": "https://registry.npmmirror.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
+8 -1
View File
@@ -8,8 +8,15 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^1.7.9",
"core-js": "^3.8.3",
"vue": "^3.2.13"
"js-md5": "^0.8.3",
"sha1": "^1.1.1",
"vant": "^4.9.10",
"vue": "^3.2.13",
"vue-router": "^4.5.0",
"vuex": "^4.0.2",
"weixin-js-sdk": "^1.6.5"
},
"devDependencies": {
"@babel/core": "^7.12.16",
+20 -16
View File
@@ -1,26 +1,30 @@
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<router-view/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import store from "@/store";
export default {
name: 'App',
components: {
HelloWorld
}
data() {
return {
};
},
mounted() {
},
methods: {
},
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
* {
margin: 0;
padding: 0;
outline: none;
}
/deep/.toast-style{
background-color: antiquewhite;
font-size: 30px;
}
</style>
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
@font-face {
font-family: 'kn';
src: url('./KNFontMaiyuan.ttf');
font-weight: normal;
font-style: normal;
}
-58
View File
@@ -1,58 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
+130
View File
@@ -0,0 +1,130 @@
<template>
<div class="interview-question">
<div class="button-group">
<div class="question-title">问题{{ number }}</div>
<van-button
icon="volume-o"
type="primary"
@click="playQuestion"
:disabled="isSpeaking"
>{{ isSpeaking ? "播放中..." : "播放问题" }}</van-button
>
<van-button type="danger" @click="stopQuestion" :disabled="!isSpeaking"
>停止播放</van-button
>
</div>
<van-field
v-model="answer"
type="textarea"
placeholder="请输入回答"
rows="6"
class="custom-textarea"
/>
<van-button
class="next-button"
:type="isLastQuestion ? 'success' : 'primary'"
@click="nextQuestion"
:disabled="answer == ''"
>{{ isLastQuestion ? "提交" : "下一个" }}</van-button
>
</div>
</template>
<script>
import { Button, Field } from "vant";
export default {
props: {
questionObj: {
type: Object,
required: true,
},
onNext: {
type: Function,
required: true,
},
isLastQuestion: {
type: Boolean,
default: false,
},
number: {
type: Number,
default: null,
},
},
data() {
return {
answer: "",
isSpeaking: false, // 用于跟踪语音播放状态
};
},
computed: {
question() {
return this.questionObj.question;
},
},
watch: {
number(newVal, oldVal) {
if (newVal !== oldVal) {
this.resetAnswer();
}
},
},
methods: {
resetAnswer() {
this.answer = "";
},
playQuestion() {
if (!this.isSpeaking) {
this.isSpeaking = true;
const utterance = new SpeechSynthesisUtterance(this.question);
utterance.onend = () => {
this.isSpeaking = false;
};
window.speechSynthesis.speak(utterance);
}
},
stopQuestion() {
if (this.isSpeaking) {
window.speechSynthesis.cancel();
this.isSpeaking = false;
}
},
nextQuestion() {
this.stopQuestion();
this.onNext({ questionId: this.questionObj.id, answer: this.answer });
},
},
};
</script>
<style scoped>
.question-title {
font-size: 20px;
}
.interview-question {
display: flex;
flex-direction: column;
padding: 20px;
}
.button-group {
display: flex;
margin-bottom: 20px;
margin-left: 10px;
align-items: center;
gap: 20px;
}
.custom-textarea {
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 8px 12px;
font-size: 18px;
color: #606266;
margin-bottom: 40px;
}
.next-button {
width: 30%;
margin: 0 auto;
}
</style>
+59
View File
@@ -0,0 +1,59 @@
//基础配置
const file = require('@/json/default.json')
const setting = file["setting"]
const wechat = file["weChat"]
import constant from '@/configs/constant'
//基本配置
const config = {
//启动ip (nodejs有效)
defaultIp: setting["defaultIp"],
//启动端口 (nodejs有效)
port: parseInt(setting["port"]),
//项目域名
hostPath: setting['hostPath'],
//服务端地址 (http请求的时候的默认参数)
apiPath: setting['apiPath'],
//线上真实域名
masterHostPath: setting['masterHostPath'],
//重定向转发的API地址 (仅仅对NodeJS有效,打包后若模式为生产模式则会使用这个地址为服务端地址)
redirectApiPath: setting['redirectApiPath'],
//重定向转发的API地址路径 (仅仅对NodeJS有效)
redirectApiDefaultPath: setting['redirectApiDefaultPath'],
//默认语言 zh-中文
language: localStorage.getItem(constant.language) ? localStorage.getItem(constant.language) : setting['language'],
//当前模式 dev 开发模式 master生产模式
model: setting['model'],
//服务器地址 与打包路径一致
dir: '/' + setting['dir'] + '/',
//测试路由 true false
test: setting['test'],
agentid: setting['agentid'],
appid: setting['appid'],
// 微信登录链接
getWechatLogin:(url,shareFlag)=>{
// if(shareFlag){
// return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx48691d052a0c1db6&redirect_uri=" + encodeURIComponent(url) + "&response_type=code&scope=snsapi_userinfo&state=" + encodeURIComponent(shareFlag) + "#wechat_redirect"
// }else{
// return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx48691d052a0c1db6&redirect_uri=" + encodeURIComponent(url) + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
// }
return 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+setting['appid']+'&redirect_uri='+encodeURIComponent(url)+'&response_type=code&scope=snsapi_userinfo&agentid='+setting['agentid']+'&state=#wechat_redirect'
}
}
export default config
+28
View File
@@ -0,0 +1,28 @@
//基础配置
const file = require('@/json/default.json')
const setting = file["setting"]
const constant = {
userInfo: setting['cache']+"_USERINFO", // 用户信息
language: setting['cache']+"_LANGUAGE", // 语言
time: setting['cache']+"_TIME", // 过期时间
token: setting['cache']+"_TOKEN", // token
oldCode: setting['cache']+"_OLDCODE", // 上一个code
// 状态码
code: {
success: 200,// 成功
err: 300,// 失败
auth: 301,// 未授权
vip: 302// 没有权限 --弹提示即可
}
};
export default constant;
+149
View File
@@ -0,0 +1,149 @@
import httpUtil from "../utils/httpUtil";
const url = "/client"
export default {
// 编辑工厂简易申请表
editFacBaseResume(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/editFacBaseResume.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 编辑简易申请表
editBaseResume(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/editBaseResume.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 获取用户信息
getUserInfo(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/userInfo.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
//岗位列表
getPosition(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/getPosition.json", request).then(res => {
resolve(res.data)
}).catch(err => {
reject(err)
})
})
},
// 用户填写个人信息
setUserInfo(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/setUserInfo.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 用户填写家庭成员信息
setUserFamily(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/setUserFamily.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 用户填写教育经历
setUserEdu(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/setUserEdu.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 用户填写工作经历
setUserWork(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/setUserWork.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 用户填写其他信息
setUserOtherInfo(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/setUserOtherInfo.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 新登录
doLogin(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/doLogin.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 登录
login(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/user/info.json", request).then(res => {
resolve(res.data)
}).catch(err => {
reject(err)
})
})
},
upFile(file, type) {
return new Promise((resolve, reject) => {
var forms = new FormData()
var configs = {
headers: {'Content-Type': 'multipart/form-data'}
};
forms.append('file', file)
forms.append('type', type)
httpUtil.post(url + '/up.json', forms, configs).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
// 用户填写补充资料
setEditAddition (request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/editAddition.json", request).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
}
+33
View File
@@ -0,0 +1,33 @@
import httpUtil from "../utils/httpUtil";
import config from "@/configs/config";
const url = "/public"
export default {
// 分享参数
getWeChat(request) {
return new Promise((resolve, reject) => {
httpUtil.post(url + "/client/getWechatSignature.json", request).then(res => {
resolve(res.data)
}).catch(err => {
reject(err)
})
})
},
//文件上传
upFile(file, type) {
return new Promise((resolve, reject) => {
var forms = new FormData()
var configs = {
headers: {'Content-Type': 'multipart/form-data'}
};
forms.append('file', file)
forms.append('type', type)
httpUtil.post(url + '/up.json', forms, configs).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
}
+131
View File
@@ -0,0 +1,131 @@
{
"zh-cn": {
"auth": {
"group": {
"auth": {
"checkGroupNull": "请先选择功能后再提交!",
"success": "成功!"
},
"state":{
"disable":"不可用",
"normal":"正常"
},
"list":{
"id":"权限组编号",
"name":"组名称",
"state":"当前状态",
"deal":"操作"
},
"add":{
"name":"组名称",
"state":"当前状态",
"defaultPower":"默认权限"
}
},
"user": {
"submit": {
"null": "请选择用户"
},
"auth": {
"checkGroupNull": "请先选择功能后再提交!",
"success": "成功!"
},
"del": {
"is": "删除后不可恢复!是否删除?",
"confirmButtonText": "确定",
"cancelButtonText": "取消"
},
"state":{
"disable":"不可用",
"normal":"正常"
},
"list":{
"number":"编号",
"id":"绑定的ID",
"account":"账号",
"userName":"用户名",
"isAdmin":"是否为管理员",
"name":"管理员姓名",
"groupName":"权限组",
"state":"当前状态",
"deal":"操作"
},
"add":{
"choose":"选择用户",
"chooseBtn":"点击选择用户",
"account":"账号",
"keyword":"密码",
"checkPassword":"确认密码",
"departmentName":"部门",
"name":"人员",
"state":"用户状态",
"groupId":"选择权限组",
"isAdminBool":"是否为管理员"
}
}
}
},
"en": {
"auth": {
"group": {
"auth": {
"checkGroupNull": "Please select the function before submitting!",
"success": "success!"
},
"state":{
"disable":"Not available",
"normal":"Normal"
},
"list":{
"id":"number",
"name":"Permission group name",
"state":"Current State",
"deal":"Operation"
},
"add":{
"name":"Permission group name",
"state":"Current State",
"defaultPower":"Default permissions"
}
},
"user": {
"submit": {
"null": "Please select user"
},
"auth": {
"checkGroupNull": "Please select the function before submitting!",
"success": "success!"
},
"state":{
"disable":"Not available",
"normal":"Normal"
},
"list":{
"number":"number",
"id":"Administrator ID",
"name":"Administrator name",
"departmentName":"department",
"position":"position",
"groupName":"Permission group name",
"state":"Current State",
"deal":"Operation"
},
"add":{
"choose":"Select User",
"chooseBtn":"Click to select user",
"account":"account",
"keyword":"password",
"checkPassword":"Confirm password",
"departmentName":"department",
"name":"user",
"state":"User status",
"groupId":"Select permission group",
"isAdminBool":"Are you an administrator"
}
}
}
}
}
+138
View File
@@ -0,0 +1,138 @@
{
"zh-cn": {
"vip": {
"setting": {
"sortBtn":"应用分类",
"formList":{
"id":"应用编号",
"name":"应用名称",
"sort":"应用分类",
"path":"应用链接",
"state":"当前状态",
"authUserName":"应用负责人",
"deal":"操作"
},
"state":{
"disable":"不可用",
"normal":"正常"
},
"sortList":{
"title": "应用分类",
"id":"分类编号",
"name":"分类名称",
"deal":"操作"
},
"addSort":{
"chooseUser": "选择用户",
"chooseUserBtn": "点击选择用户",
"userName":"应用负责人",
"name":"应用名",
"classId":"应用分类",
"icon":"图标",
"iconUrl":"图标地址",
"path":"应用地址",
"stateBool":"状态"
},
"add": {
"null": "数据不能为空!",
"userNull": "请选择授权用户!"
},
"del": {
"is": "删除后不可恢复!是否删除?",
"confirmButtonText": "确定",
"cancelButtonText": "取消"
}
}
},
"list": {
"entrance": {
"isAdmin":"管理",
"emptyList":"暂无应用",
"msg": "是管理员,无法添加",
"admin": {
"edit": "编辑",
"title": "管理用户",
"adminNull": "暂无管理用户",
"add": "添加"
},
"user": {
"edit": "编辑",
"title": "授权用户",
"userNull": "暂无授权用户",
"add": "添加"
},
"del": {
"is": "是否确定删除?",
"confirmButtonText": "确定",
"cancelButtonText": "取消"
}
}
}
},
"en": {
"vip": {
"setting": {
"sortBtn":"Application Classification",
"formList":{
"id":"Application Number",
"name":"Application Name",
"sort":"Application Classification",
"path":"Application Link",
"state":"Current State",
"authUserName":"Application Manager",
"deal":"Operation"
},
"state":{
"disable":"Not available",
"normal":"Normal"
},
"sortList":{
"title": "Application Classification",
"id":"Application Number",
"name":"Application Name",
"deal":"Operation"
},
"addSort":{
"chooseUser": "Select User",
"chooseUserBtn": "Click to select user",
"userName":"Application Manager",
"name":"Application Name",
"classId":"Application Classification",
"icon":"Application Icon",
"iconUrl":"Application Icon Link",
"path":"Application Link",
"stateBool":"Current State"
},
"add": {
"null": "Data cannot be empty!",
"userNull": "Please select authorized user!"
}
}
},
"list": {
"entrance": {
"isAdmin":"Administration",
"emptyList":"No application",
"msg": " is an administrator and cannot be added",
"admin": {
"edit": "edit",
"title": "Manage users",
"adminNull": "No manage users",
"add": "add"
},
"user": {
"edit": "edit",
"title": "Authorized user",
"userNull": "No authorized user",
"add": "add"
},
"del": {
"is": "Are you sure you want to delete?",
"confirmButtonText": "delete",
"cancelButtonText": "cancel"
}
}
}
}
}
+22
View File
@@ -0,0 +1,22 @@
{
"zh-cn": {
"clock": {
"title":""
},
"records": {
"title":""
}
},
"en": {
"clock": {
"title":""
},
"records": {
"title":"Clock in records",
"other":{
"back":"Back"
}
}
}
}
+46
View File
@@ -0,0 +1,46 @@
{
"zh-cn": {
"auth": {
"title": "选择功能",
"inputPlaceholder": "输入关键字进行过滤",
"checkGroupNull": "请先选择功能后再提交!",
"auth":{
"get":"查询",
"edit":"编辑",
"add":"添加",
"del":"删除"
}
},
"userTree": {
"title": "选择成员",
"back": "返回上一层",
"msg":{
"limit1":"只能选择",
"limit2":"个节点",
"check":"只能选择当前分类最后的子分类"
}
}
},
"en": {
"auth": {
"title": "Selection function",
"inputPlaceholder": "Enter keywords to filter",
"checkGroupNull": "Please select the function before submitting!",
"auth":{
"get":"get",
"edit":"edit",
"add":"add",
"del":"del"
}
},
"userTree": {
"title": "Select members",
"back": "Back to the previous level",
"msg":{
"limit1":"You can only choose ",
"limit2":" Nodes",
"check":"Only the last subcategory of the current category can be selected"
}
}
}
}
+87
View File
@@ -0,0 +1,87 @@
{
"setting": {
"defaultIp": "0.0.0.0",
"port": 1025,
"hostPath": "http://localhost:1025",
"masterHostPath": "https://hr.wlcent.cn/fac/client/client",
"apiPath": "/api",
"redirectApiPath": "http://192.168.36.14/2024/fac/server/public/index.php",
"redirectApiPath": "https://hr.wlcent.cn/fac/server/public/index.php",
"redirectApiDefaultPath": "",
"language": "zh-cn",
"model": "dev",
"test": true,
"dir": "client",
"cache": "2024FacHR",
"agentid": "1000018",
"appid": "wxf20fccfd93d53fad"
},
"zh-cn": {
"hostTitle": "智能语音面试系统",
"info": ",您好!",
"login":{
"loginOut": "退出登录",
"loginMsg": "账号登录",
"loginBtn": "立即登录",
"username": "姓名",
"phone": "手机号码",
"loginSuccess": "登录成功"
},
"tab":{
"home": "首页",
"mine": "我的"
},
"language": "请选择语言",
"success": "成功",
"error": "失败",
"notNull": "不能为空",
"notFull": "请填写完整",
"windowNode": {
"add": "添加",
"edit": "编辑"
},
"btn": {
"submit": "提交",
"cancel": "取消"
},
"del": {
"is": "删除后不可恢复!是否删除?",
"confirmButtonText": "确定",
"cancelButtonText": "取消"
}
},
"en": {
"hostTitle": "FAC Client",
"info": "hi",
"tab":{
"home": "Daily Attendance",
"mine": "Mine"
},
"login":{
"loginOut": "Log out",
"loginMsg": "Account login",
"loginSuccess": "Login successful",
"loginBtn": "Sign in now",
"username": "username",
"phone": "phone"
},
"language": "Please select language",
"success": "success",
"error": "fail",
"notNull": "Cannot be empty",
"notFull": "please be sure to complete your data",
"windowNode": {
"add": "add",
"edit": "edit"
},
"btn": {
"submit": "submit",
"cancel": "cancel"
},
"del": {
"is": "It cannot be restored after deletion! Delete?",
"confirmButtonText": "delete",
"cancelButtonText": "cancel"
}
}
}
+22
View File
@@ -0,0 +1,22 @@
/**
*
* User: Diablo
* Date: 2021/3/30
* User: 544730126@qq.com
* Blog: https://blog.fenglide.com.cn/
* Project: vue-project
* Action: 获取json文件方法
*
*/
import config from "@/configs/config";
export default {
//获取语言包文件
getFile: (name = 'default', lang = true, language = config.language) => {
let file = require('./' + name + ".json")
if (lang) {
return file[language]
}
return file
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"zh-cn": {
"home": {
"title": "这是首页"
}
},
"en": {
"home": {
"title": "this is home"
}
}
}
+196
View File
@@ -0,0 +1,196 @@
{
"zh-cn": {
"mine": {
"tabs": {
"clock": "日常打卡",
"leave": "請假申請",
"forgot": "忘打卡申請",
"records":"考勤記錄",
"report":"銷量提報",
"reportRecords":"提報記錄",
"salesPhoto":"相片提交",
"overtime":"加班申請",
"opinion":"問題反饋",
"guide":"使用說明"
},
"rule":{
"empty":"暫無規則明細",
"title":"規則明細",
"name":"規則名稱",
"desc":"規則簡介",
"code":"規則編碼",
"buy_num":"購買數量",
"gift_num":"贈送數量",
"gift_arr":"贈送產品",
"sale_arr":"銷售產品",
"status":"規則狀態",
"work":"生效",
"unknowed":"未知狀態"
},
"order":{
"empty":"暫無訂單",
"title":"我的訂單",
"order_id":"訂單編號",
"user":"下單用戶",
"send_date":"送貨時間",
"shop":"門店",
"code":"門店編碼",
"address":"收貨地址",
"remark":"備註",
"money_count":"金額",
"ctime":"訂單創建時間",
"status":"是否確認",
"status_no":"未確認",
"status_yes":"已確認",
"status_cancel":"已取消",
"deal":"操作",
"lookup":"查看詳情",
"cancel_order":"取消訂單",
"editer":"最後修改用戶",
"edittime":"最後修改時間",
"name":"姓名",
"phone":"聯系電話",
"sap_order_num":"SAP銷售訂單號",
"pro_name":"產品名稱",
"pro_code":"編碼",
"pro_price":"價格",
"pro_unit":"單位",
"pro_num":"數量",
"pro_sum":"總價",
"gift":"加送",
"gift2":"擺檔",
"gift3":"贊助",
"sum":"總銀碼:HK$ ",
"loading":"正在加載",
"ending":"到底了"
}
},
"order":{
"search":{
"pro_sort":"商品分類",
"search":"條件搜索",
"search_name":"按名稱搜索",
"search_code":"按編碼搜索",
"search_price":"按價格區間搜索",
"pl_name":"請輸入名稱",
"pl_code":"請輸入編碼",
"pl_min":"請輸入最低價格",
"pl_max":"請輸入最高價格",
"cancel":"取消",
"ok":"搜索"
},
"pro_list":{
"support":"贊助",
"del":"刪除",
"empty":"暫無商品",
"goSum":"去結算",
"add_gift":"添加擺檔贈品",
"add_support":"添加贊助"
},
"order":{
"title":"訂單明細",
"shop_gift":"擺檔贈品明細",
"shop_gift_detial":"擺檔贈品明細",
"gift_flag2":"擺檔",
"gift_flag":"加送",
"gift":"加送贈品明細",
"num":"可選数量",
"support_list":"贊助贈品明細",
"support_flag":"贊助",
"sum":"總金額",
"search_shop":"檢索門店",
"search_shop_name":"用門店名稱檢索",
"search_shop_code":"用門店編碼檢索",
"shop":"門店",
"shop_msg":"請選擇門店",
"name":"姓名",
"name_msg":"姓名不能為空",
"phone":"聯系電話",
"phone_msg":"聯系電話不能為空",
"address":"收貨地址",
"address_msg":"收貨地址不能為空",
"time":"配送時間",
"time_msg":"請選擇配送時間",
"search_pay":"檢索付款方",
"search_pay_name":"用付款方名稱檢索",
"search_pay_code":"用付款方編碼檢索",
"pay_msg":"請選擇付款方",
"pay":"付款方",
"remark":"備註",
"sumbit":"提交",
"back":"返回下单列表",
"success":"下單成功",
"back_page":"返回下單頁面"
},
"msg":{
"all":"全部商品",
"price":"請填寫完整價格區間",
"over":"不能超過贈送數量"
}
}
},
"en": {
"mine": {
"tabs": {
"clock": "Daily attendance",
"leave": "Leave Application",
"forgot": "Forgot to clock",
"records":"Clock in records",
"report":"Sales report",
"reportRecords":"Report records"
},
"rule":{
"empty":"暫無規則明細",
"title":"規則明細",
"name":"規則名稱",
"desc":"規則簡介",
"code":"規則編碼",
"buy_num":"購買數量",
"gift_num":"贈送數量",
"gift_arr":"贈送產品",
"sale_arr":"銷售產品",
"status":"規則狀態",
"work":"生效",
"unknowed":"未知狀態"
},
"order":{
"empty":"暫無訂單",
"title":"我的訂單",
"order_id":"訂單編號",
"user":"下單用戶",
"send_date":"送貨時間",
"shop":"門店",
"code":"門店編碼",
"address":"收貨地址",
"remark":"備註",
"money_count":"金額",
"ctime":"訂單創建時間",
"status":"是否確認",
"status_no":"未確認",
"status_yes":"已確認",
"status_cancel":"已取消",
"deal":"操作",
"lookup":"查看詳情",
"cancel_order":"取消訂單",
"editer":"最後修改用戶",
"edittime":"最後修改時間",
"name":"姓名",
"phone":"聯系電話",
"sap_order_num":"SAP銷售訂單號",
"pro_name":"產品名稱",
"pro_code":"編碼",
"pro_price":"價格",
"pro_unit":"單位",
"pro_num":"數量",
"pro_sum":"總價",
"gift":"加送",
"gift2":"擺檔",
"gift3":"贊助",
"sum":"總銀碼:HK$ ",
"loading":"正在加載",
"ending":"到底了"
}
}
}
}
+80
View File
@@ -0,0 +1,80 @@
[
{
"path": "/index-two",
"name": "index-two",
"component": "two",
"meta": {
"title": "权限管理",
"icon": "el-icon-s-tools",
"key": 2000000,
"isLink": false,
"isMenu": true
}
},
{
"path": "/index-three",
"name": "index-three",
"component": "three",
"redirect": "/index-three-test",
"meta": {
"title": "应用",
"icon": "el-icon-s-grid",
"key": 3000000,
"isLink": false,
"isMenu": true,
"vip":{
"aa":{
"title":"分类管理功能",
"auth": {
"add": "url",
"up": "url"
}
},
"bb": {
"title": "应用管理功能",
"auth": {
"del": "url"
}
}
}
},
"children": [
{
"path": "/index-three-test",
"name": "index-three-test",
"component": "three/test",
"meta": {
"title": "应用入口",
"icon": "el-icon-collection",
"key": 3100000,
"isLink": false,
"isMenu": true
}
},
{
"path": "/index-three-test1",
"name": "index-three-test1",
"component": "three/test1",
"meta": {
"title": "应用管理",
"icon": "el-icon-setting",
"key": 3200000,
"isLink": false,
"isMenu": true
}
},
{
"path": "/index-three-detial",
"name": "index-three-detial",
"component": "three/detial",
"meta": {
"title": "应用管理详情",
"icon": "123",
"key": 3200000,
"isLink": false,
"isMenu": false
}
}
]
}
]
+19
View File
@@ -0,0 +1,19 @@
{
"zh-cn": {
"clock": {
"title":""
},
"records": {
"title":""
}
},
"en": {
"report": {
"title":"Sales report",
"other":{
"back":"Back"
}
}
}
}
+50 -3
View File
@@ -1,4 +1,51 @@
import { createApp } from 'vue'
import App from './App.vue'
import {createApp} from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
//请求工具包
import http from "@/utils/httpUtil";
//获取json文件包
import file from "@/json/file";
//工具方法包
import base from "@/utils/baseUtil";
createApp(App).mount('#app')
//引入animated
// import animated from 'animate.css'
// 引入vant
import Vant from 'vant';
import 'vant/lib/index.css'
import { Lazyload } from 'vant';
//常量包
import constant from "@/configs/constant";
import config from "@/configs/config";
// 引入外部字体
import '@/assets/font/font.css';
//注册一个APP
const app = createApp(App);
//注册全局变量
app.config.globalProperties.$http = http //请求变量
app.config.globalProperties.$file = file //获取文件变量
app.config.globalProperties.$defaultMessage = file.getFile()
app.config.globalProperties.$base = base //工具方法变量
app.config.globalProperties.$constant = constant //常量
app.config.globalProperties.$config = config
// app.config.globalProperties.$vueI18n = vueI18n
app.use(store);
app.use(router);
// app.use(vueI18n);
let language=localStorage.getItem(constant.language)
if(!language) language=config.language
// import('dayjs/locale/'+language)
// let locale = require('element-plus/lib/locale/lang/'+language).default
// app.use(ElementPlus,{locale});
app.use(Vant);
app.use(Lazyload);
// app.use(animated);
app.mount("#app");
+130
View File
@@ -0,0 +1,130 @@
import { createRouter, createWebHistory, createWebHashHistory } from "vue-router";
//引入文件包方法
import file from "@/json/file";
import constant from "@/configs/constant";
import config from "@/configs/config";
//加载本地语言数据文件
const defaultTitle = file.getFile()["hostTitle"];
const routes = [
{
path: "/",
name: "First",
redirect: "/index",
component: () => import("@/views/Index.vue"),
children: [
{
path: "/clear",
name: "clear",
component: () => import("@/views/clear/Index"),
meta: {requiresLogin: false}, // 设置元字段,不需要登录
},
{
path: "/login",
name: "Login",
component: () => import("@/views/login/Index")
},
{
path: '/index',
name: "Index",
component: () => import("@/views/index/Index"),
redirect: { name: 'Home' },
children: [{
path: "/home",
name: 'Home',
component: () => import("@/views/index/homepage/Index")
},
{
path: "/answer",
name: 'Answer',
component: () => import("@/views/index/answerPage/Index")
},
{
path: "/submit-success",
name: 'SubmitSuccess',
component: () => import("@/views/index/submitPage/Index")
},
]
}
// {
// path: "/index",
// name: "Index",
// component: () => import("@/views/index/Index"),
// redirect: { name: 'OfficeStandard' },
// children: [
// {
// path: "/index-application",
// name: "Application",
// meta: {
// key: 1000000,
// icon: "",
// title: "简历",
// isLink: true, // 是否标签常驻
// isMenu: false // 是否菜单显示
// },
// redirect: "/index-application-office",
// children: [{
// path: "/index-application-office",
// name: "Office",
// meta: {
// key: 1100000,
// icon: "",
// title: "校招简历",
// isLink: true, // 是否标签常驻
// isMenu: false // 是否菜单显示
// },
// component: () => import("@/views/index/application/office/Index")
// },
// {
// path: "/index-application-SubmitSuccess",
// name: "SubmitSuccess",
// meta: {
// key: 1400000,
// icon: "",
// title: "提交成功",
// isLink: true, // 是否标签常驻
// isMenu: false // 是否菜单显示
// },
// component: () => import("@/views/index/application/SubmitSuccess")
// }]
// }
// ]
// }
]
}
];
const router = createRouter({
// history: createWebHistory(config.model === 'dev' ? process.env.BASE_URL : config.dir),
history: createWebHashHistory(config.model === "dev" ? process.env.BASE_URL + config.dir : config.dir),
routes: routes
});
router.beforeEach((to, from, next) => {
document.title = defaultTitle
// 检查目标路由是否需要登录
if (to.meta.requiresLogin !== false) {
const userInfo = JSON.parse(localStorage.getItem(constant.userInfo));
const tokenExpireTime = parseInt(localStorage.getItem(constant.time));
const currentTime = Math.floor(Date.now() / 1000); // 获取当前时间,单位为秒
// 检查是否有用户信息及是否过期
if (!userInfo || currentTime >= tokenExpireTime) {
console.log('User not logged in or token expired, redirecting to login');
if (to.name !== 'Login'){
// 将用户重定向到登录页面,并传递type参数
next({ name: 'Login', query: { type: to.query.type } });
return; // 返回,确保不会继续导航
}
} else {
console.log('User is logged in, continuing navigation');
}
}
// 继续导航
next();
});
export default router;
+12
View File
@@ -0,0 +1,12 @@
import {createStore} from "vuex";
import constant from "@/configs/constant";
export default createStore({
state: {
menuRouter: "",
},
mutations: {},
actions: {},
modules: {},
});
+73
View File
@@ -0,0 +1,73 @@
/**
* 图片压缩工具类
* 最大高度和最大宽度都为 500,如果超出大小将等比例缩放。
*
* 注意可能出现压缩后比原图更大的情况,在调用的地方自己判断大小并决定上传压缩前或压缩后的图到服务器。
*/
// 将base64转换为blob
export function convertBase64UrlToBlob(urlData) {
let arr = urlData.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], {type: mime})
}
// 压缩图片
export function compressImage(path) {
//最大高度
const maxHeight = 500;
//最大宽度
const maxWidth = 500;
return new Promise((resolve, reject) => {
let img = new Image();
img.src = path;
img.onload = function () {
const originHeight = img.height;
const originWidth = img.width;
let compressedWidth = img.height;
let compressedHeight = img.width;
if ((originWidth > maxWidth) && (originHeight > maxHeight)) {
// 更宽更高,
if ((originHeight / originWidth) > (maxHeight / maxWidth)) {
// 更加严重的高窄型,确定最大高,压缩宽度
compressedHeight = maxHeight
compressedWidth = maxHeight * (originWidth / originHeight)
} else {
//更加严重的矮宽型, 确定最大宽,压缩高度
compressedWidth = maxWidth
compressedHeight = maxWidth * (originHeight / originWidth)
}
} else if (originWidth > maxWidth && originHeight <= maxHeight) {
// 更宽,但比较矮,以maxWidth作为基准
compressedWidth = maxWidth
compressedHeight = maxWidth * (originHeight / originWidth)
} else if (originWidth <= maxWidth && originHeight > maxHeight) {
// 比较窄,但很高,取maxHight为基准
compressedHeight = maxHeight
compressedWidth = maxHeight * (originWidth / originHeight)
} else {
// 符合宽高限制,不做压缩
}
// 生成canvas
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.height = compressedHeight;
canvas.width = compressedWidth;
context.clearRect(0, 0, compressedWidth, compressedHeight);
context.drawImage(img, 0, 0, compressedWidth, compressedHeight);
let base64 = canvas.toDataURL('image/*', 0.8);
let blob = convertBase64UrlToBlob(base64);
// 回调函数返回blob的值。也可根据自己的需求返回base64的值
resolve(blob)
}
})
}
+121
View File
@@ -0,0 +1,121 @@
/**
*
* User: Diablo
* Date: 2021/3/30
* User: 544730126@qq.com
* Blog: https://blog.fenglide.com.cn/
* Project: vue-project
* Action: 工具方法
*
*/
//路由包
import router from "@/router";
import constant from "@/configs/constant";
import config from "@/configs/config";
import store from '@/store/index'
// import wx from "weixin-js-sdk";
import publicHttp from "@/http/publicHttp";
import { Toast } from 'vant';
export default {
//清空缓存
removeCache() {
localStorage.removeItem(constant.userInfo)
localStorage.removeItem(constant.time)
localStorage.removeItem(constant.language)
localStorage.removeItem(constant.token)
localStorage.removeItem(constant.oldCode)
},
jsonp(setting){
setting.data = setting.data || {}
setting.key = setting.key||'callback'
setting.callback = setting.callback||function(){}
setting.data[setting.key] = '__onGetData__'
window.__onGetData__ = function(data){
setting.callback (data);
}
var script = document.createElement('script')
var query = []
for(var key in setting.data){
query.push( key + '='+ encodeURIComponent(setting.data[key]) )
}
script.src = setting.url + '?' + query.join('&')
document.head.appendChild(script)
document.head.removeChild(script)
},
// 接入企微sdk
setwx(callback){
let url = window.location.href
publicHttp.getWeChat({ url: url }).then((res) => {
if(res){
this.getwx(res,callback)
console.log(callback)
}
});
},
// 接入企微sdk
getwx(data,callback){
var that = this
console.log(data)
wx.config({
beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: config.appid, // 必填,企业微信的corpID
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.noncestr, // 必填,生成签名的随机串
signature: data.signature,// 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: ['checkJsApi','openLocation','getLocation','hideMenuItems','hideAllNonBaseMenuItem'] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
wx.ready(() => {
wx.checkJsApi({
jsApiList: ['openLocation','getLocation','hideMenuItems','hideAllNonBaseMenuItem'], // 需要检测的JS接口列表
success: function(res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
// setTimeout(function(){
// that.getLocation()
// wx.hideAllNonBaseMenuItem()
// },1000)
that.getLocation(callback)
wx.hideAllNonBaseMenuItem()
},
fail: function(res) {
if(res.errMsg.indexOf('function not exist') > -1){
alert('版本过低请升级')
}
}
});
});
wx.error(function(err){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
// console.log("微信验证失败123")
console.log(err)
// location.reload()
});
},
getLocation(callback){
let that=this
wx.getLocation({
type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
console.log(res.latitude) // 纬度,浮点数,范围为90 ~ -90
console.log(res.longitude) // 经度,浮点数,范围为180 ~ -180
callback(res)
},
error: function (res) {
if(res.errMsg==='auto:location:report:fail, gps closed.'){
Toast('请打开定位')
}else{
Toast({
type:'fail',
message: '定位失败',
duration:0,
forbidClick:true
});
}
},
});
},
}
+141
View File
@@ -0,0 +1,141 @@
/**
*
* User: Diablo
* Date: 2021/3/30
* User: 544730126@qq.com
* Blog: https://blog.fenglide.com.cn/
* Project: vue-project
* Action: axios封装
*
*/
import axios from "axios";//axios包
import config from "@/configs/config";
import md5 from "js-md5";
import sha1 from "sha1";
import constant from "../configs/constant";
import baseUtil from "./baseUtil";
import store from "@/store/index";
// import {ElMessage,ElLoading } from "element-plus";
import { showLoadingToast ,closeToast,Loading,Toast,Dialog,showNotify } from 'vant';
import router from "../router";
//当前模式
const model = config.model; //master生产模式 dev测试模式
//请求默认携带的参数
const defaultBaseUrl = model === "dev" ? config.apiPath : (config.redirectApiPath); //默认请求地址
const instance = axios.create({
baseURL: defaultBaseUrl,
headers: {
// "Authorization": md5(sha1(sha1("mmyx$_$wl") + parseInt(new Date().getTime() / 1000))),
// "Time": parseInt(new Date().getTime() / 1000),
},
});
let toast = null;
instance.interceptors.request.use(config => {
config.headers["Authorization"] = localStorage.getItem(constant.token)
config.headers["API-AUTH"] = md5(sha1(sha1("bzwcH64jZLZ67fia") + parseInt(new Date().getTime() / 1000)))
// config.headers["Language"] = localStorage.getItem(constant.language)
config.headers["API-TIME"] = parseInt(new Date().getTime() / 1000)
// config.headers["RequestType"] = model
// toast = Toast({
// type:'loading',
// duration:0,
// forbidClick:true,
// message:'',
// })
return config
})
// 响应监听
instance.interceptors.response.use(
res => {
// toast.clear()
if (res.data.code === constant.code.auth) {
baseUtil.removeCache();
setTimeout(()=>{
// router.push('/index')
window.location.href=config.masterHostPath
},1500)
/**
Dialog.confirm({
title: '',
message:'是否重新登录?',
})
.then(() => {
baseUtil.removeCache();
setTimeout(()=>{
// router.push('/index')
window.location.href=config.masterHostPath
},1500)
})
.catch(() => {
// on cancel
showNotify({'type':'danger','msg':'No Login'});
// Toast({
// type:'fail',
// message:'未登录状态',
// duration:0,
// overlay:true
// });
});
*/
}
if (res.data.code === constant.code.vip) {
showNotify({'type':'danger','message':res.data.msg});
}
return res;
},
err=>{
// closeLoading()
// toast.clear()
return err;
}
);
const http = {
//get请求
get: (path = "", data = {}, header = {}) => {
return new Promise((resolve, reject) => {
instance.get(path, {
params: data,
headers: header
}).then(res => {
if (res.data.code == constant.code.success) {
resolve(res.data);
} else {
showNotify({'type':'danger','message':res.data.msg});
// Toast(res.data.msg);
}
}).catch(err => {
reject(err);
});
});
},
//post 请求
post: (path = "", data = {}, config = {}) => {
return new Promise((resolve, reject) => {
instance.post(path, data, config
).then(res => {
closeToast();
if (config.responseType === 'blob') {
resolve(res.data)
}
if (res.data.code == constant.code.success) {
resolve(res.data);
} else {
showNotify({'type':'danger','message':res.data.msg});
}
}).catch(err => {
reject(err);
});
});
}
};
export default http;
+12
View File
@@ -0,0 +1,12 @@
<template>
<router-view/>
</template>
<script>
export default {
name: "Index"
}
</script>
<style scoped>
</style>
+19
View File
@@ -0,0 +1,19 @@
<template>
<div>clear</div>
</template>
<script>
import baseUtil from "@/utils/baseUtil";
export default {
name: "Index",
data() {
return {
};
},
mounted() {
console.log(localStorage.getItem(this.$constant.userInfo))
baseUtil.removeCache()
console.log(localStorage.getItem(this.$constant.userInfo))
}
}
</script>
+80
View File
@@ -0,0 +1,80 @@
<template>
<van-nav-bar title="智能语音面试系统">
<template #right>
<van-popover
:actions="actions"
@select="onSelect"
placement="bottom-end"
close-on-click-action
close-on-click-outside
>
<template #reference>
<van-icon name="ellipsis" size="35px" />
</template>
<template v-for="(action, index) in actions" :key="index">
<div class="action-item" @click="selectAction(action.text, index)">
<van-icon :name="action.icon" />
<span class="ellipsis">{{ action.text }}</span>
</div>
</template>
</van-popover>
</template>
</van-nav-bar>
<router-view />
</template>
<script>
import { showToast } from "vant";
export default {
name: "Index",
data() {
return {
userName: JSON.parse(localStorage.getItem(this.$constant.userInfo)).chineseName,
actions: [
{ text: '', icon: "contact-o" },
{ text: this.$defaultMessage['login']['loginOut'], icon: "cross" },
],
};
},
mounted() {
let userName = JSON.parse(
localStorage.getItem(this.$constant.userInfo)
).chineseName;
this.actions[0].text = userName;
},
methods: {
selectAction(text, index) {
switch (index) {
case 0:
showToast({
message: text,
position: "top",
});
break;
case 1: //退出登录
this.$router.push("/login");
break;
default:
console.error("Invalid index:", index); // 记录无效的索引
}
},
},
};
</script>
<style>
.action-item {
padding: 10px;
cursor: pointer;
}
.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 8px; /* 留出图标的空间 */
}
.van-nav-bar__title {
font-size: 18px;
}
</style>
+67
View File
@@ -0,0 +1,67 @@
<template>
<div>
<!-- 其他内容... -->
<interview-question
:questionObj="currentQuestion"
:on-next="handleNextQuestion"
:is-last-question="isLastQuestion"
:number="currentQuestionIndex + 1"
@submit="handleSubmit"
></interview-question>
<!-- 其他内容... -->
</div>
</template>
<script>
import InterviewQuestion from "@/components/InterviewQuestion";
export default {
components: {
InterviewQuestion,
},
data() {
return {
questionsList: [
{
id: 1,
question:
"您好,请问您是否通过大学英语六级考试?或者有其他雅思托福等英语成绩吗?",
},
{
id: 2,
question:
"您好,请问英语口语水平如何呢?是否可以接受口语测试呢,主要是电话问答形式",
},
{
id: 3,
question:
"我们这个岗位是培养储管理人员的,所以前期需要了解和熟悉全国的业务模式及业务情况,入职后的工作地点可能会有全国一二线城市的分配,您看能够接受吗?",
},
],
currentQuestionIndex: 0,
userAnswers: [],
};
},
computed: {
currentQuestion() {
return this.questionsList[this.currentQuestionIndex];
},
isLastQuestion() {
return this.currentQuestionIndex === this.questionsList.length - 1;
},
},
methods: {
handleNextQuestion(answer) {
this.userAnswers.push(answer);
if (this.isLastQuestion) {
// 处理提交答案的逻辑
this.handleSubmit();
} else {
this.currentQuestionIndex++;
}
},
handleSubmit() {
this.$router.push("/submit-success");
console.log("Final answer:", this.userAnswers);
},
},
};
</script>
+88
View File
@@ -0,0 +1,88 @@
<template>
<div class="home">
<div class="rules" @click="goToRules">
<h3>答题指南</h3>
<ol>
<li>听问题系统会通过语音播报一个问题</li>
<li>回答问题在指定的文本框中输入你的回答</li>
<li>
继续回答完成当前问题的回答后点击下一个按钮继续回答下一个问题
</li>
<li>
提交答案当所有问题都回答完毕后点击提交按钮来提交你的答案
</li>
</ol>
</div>
<van-button
icon="volume-o"
icon-position="right"
type="primary"
round
@click="startInterview"
>开始问答</van-button
>
</div>
</template>
<script>
import { useRouter } from "vue-router";
import { NavBar, Button } from "vant";
export default {
components: {
"van-nav-bar": NavBar,
"van-button": Button,
},
methods: {
onClickLeft() {
// 处理返回逻辑
},
goToRules() {
// 跳转到规则页面的逻辑
},
startInterview() {
this.$router.push("/answer");
},
},
};
</script>
<style scoped>
.rules {
cursor: pointer;
padding: 30px 20px;
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 18px;
color: #333;
margin-bottom: 50px;
}
.rules h3 {
text-align: center;
margin-bottom: 18px;
}
.rules ol {
margin: 0;
padding-left: 20px;
}
.rules li {
margin-bottom: 18px;
list-style-type: decimal;
}
.rules li:last-child {
margin-bottom: 0;
}
.rules:hover {
background-color: #f0f0f0;
}
.van-button {
margin: 0 auto;
display: block;
padding: 24px 40px;
font-size: 19px;
}
</style>
+42
View File
@@ -0,0 +1,42 @@
<template>
<div class="success">
<div class="top">
<div><van-icon name="passed" size="30px" color="#3498db" /></div>
<div class="top-text"><span>已完成问答</span></div>
</div>
<div class="bottom">
<!-- <p>如需修改信息</p>
<p>可重新扫码填写</p> -->
</div>
</div>
</template>
<script>
</script>
<style>
.success {
text-align: center;
padding: 100px;
margin: 100px auto;
}
.success > div {
margin-bottom: 10px;
}
.top {
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 10px;
/* margin-top: 50px; */
}
.icon {
/* margin-right: 15px; */
}
.top-text {
font-size: 25px;
color: #3498db;
margin-left: 6px;
}
.bottom p {
padding: 5px 0;
}
</style>
+175
View File
@@ -0,0 +1,175 @@
<template>
<div class="login-page">
<div class="login-div">
<!-- <img src='@/assets/logo.png' alt=''> -->
<div class="title">{{ $defaultMessage['hostTitle'] }}</div>
<div class="login">
<van-form ref="form" :model="form" label-width="60px" label-position="left">
<van-field :label="$defaultMessage['login']['username']" v-model="form.username"
:placeholder="$defaultMessage['login']['username']"></van-field>
<van-field :label="$defaultMessage['login']['phone']"
v-model="form.phone" type="phone"
:placeholder="$defaultMessage['login']['phone']"
:rules="[
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式不正确', trigger: 'blur' }
]">
</van-field>
<van-button type="primary" style="width: 100%;margin-top:50px;" @click="doLogin"
:disabled="!form.username||!form.phone">
{{ $defaultMessage['login']['loginBtn'] }}
</van-button>
</van-form>
</div>
</div>
</div>
<van-overlay :show="show" @click="show = false"/>
</template>
<script>
import {showNotify, showLoadingToast, Toast} from 'vant';
import clientHttp from "@/http/clientHttp";
export default {
data() {
return {
form: {username: '', phone: '', openId: ''},
show: false
}
},
components: {},
mounted() {
// this.wxLogin()
},
methods: {
checkUrl(name) {
let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
let r = window.location.search.substr(1).match(reg)
if (r != null) return unescape(r[2])
return null
},
//登录
doLogin() {
if (this.form.username === '') {
this.$message.error(this.$defaultMessage['login']['username'] + this.$defaultMessage['notNull']);
return false
}
if (this.form.phone === '') {
this.$message.error(this.$defaultMessage['login']['phone'] + this.$defaultMessage['notNull']);
return false
}
if (!/^1\d{10}$/.test(this.form.phone)) {
showNotify({'type': 'danger', 'message': '请输入有效的手机号码!'});
return false;
}
showLoadingToast({
message: 'Logging in...',
forbidClick: true,
loadingType: 'spinner',
duration: 0
});
// 手动触发表单校验
this.form.type = this.$route.query.type || '1'; //默认1; 1职能(完整) 2校招(职能简易) 3普工(普工简易)
clientHttp.doLogin(this.form).then(res => {
// this.$base.removeCache();
if (res.code == 200) {
showNotify({'type': 'success', 'message': '登录成功!'});
// 这里是用户信息
localStorage.setItem(this.$constant.time, res.data.exp)
localStorage.setItem(this.$constant.token, res.data.token)
localStorage.setItem(this.$constant.userInfo, JSON.stringify(res.data.user))
setTimeout(() => {
switch (this.form.type){
case '1':
this.$router.push('/index');
break;
}
}, 1000)
} else {
showNotify({'type': 'danger', 'message': res.msg});
}
})
},
loginJump(res) {
let that = this
// this.$message.success(this.$defaultMessage['login']['loginSuccess'])
setTimeout(() => {
// console.log(res.data.user)
// return
setTimeout(() => {
let url = that.$config.model === 'dev' ? '' : that.$config.masterHostPath
// if (that.$route.query.redirectUrl) {
// url += "/index?redirectUrl=" + that.$route.query.redirectUrl
// }
// window.location.href = url
that.$router.push('/index')
}, 500)
}, 1000)
}
}
}
</script>
<style scoped>
a {
color: #2b2b2b;
}
.login-page {
width: 100vw;
background: #fff;
text-align: center;
color: #2b2b2b;
height: 100vh;
/*background: url(../assets/bg.jpg) no-repeat;*/
/*background-position: center;*/
/*background-size: contain;*/
}
.login-div {
max-width: 500px;
margin: 0 auto;
background: #fff;
padding-right: 15px;
padding-left: 15px;
}
.title {
position: relative;
display: inline-block;
margin-top: 43px;
margin-bottom: 50px;
font-size: 22px;
font-weight: bold;
}
.title img {
width: 40px;
margin-right: 8px;
vertical-align: middle;
margin-top: -3px;
margin-left: -20px;
}
.code-overdue span {
padding: 6px 5px;
}
.code-overdue a {
text-decoration: underline;
color: #ed6d47;
}
/deep/ .about .el-input__inner {
border: 1px solid #ffffff !important;
}
/deep/ .el-form-item__label {
font-size: 16px !important;
}
</style>
+26 -4
View File
@@ -1,4 +1,26 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})
const config = require("./src/json/default.json")['setting'];
const apiJsonPath = config['apiPath']
//
module.exports = {
lintOnSave: false,//关闭es
publicPath: './',
outputDir: config['dir'],
devServer: {
host: config["defaultIp"],
port: parseInt(config["port"]),
proxy: {
[apiJsonPath]: {
target: config["redirectApiPath"],
changeOrigin: true,
pathRewrite: {
[apiJsonPath]: config["redirectApiDefaultPath"]
}
}
}
},
productionSourceMap: false,
chainWebpack: (config) => {
config.plugins.delete('prefetch');
}
}