dev_202412
yujialong 1 month ago
parent c8b0df3774
commit 28d2a2b6fb
  1. 4
      src/api/index.js
  2. 328
      src/pages/account/login/index.vue
  3. 5
      src/pages/account/redirect/index.vue
  4. 26
      src/pages/achievement/info/course.vue
  5. 14
      src/pages/achievement/list/project.vue
  6. 29
      src/pages/achievement/show/index.vue
  7. 8
      src/pages/match/add/set.vue
  8. 2
      src/pages/match/manage/matchSignup.vue
  9. 32
      src/pages/match/manage/trialReport.vue
  10. 4
      src/pages/resourse/list/index.vue
  11. 16
      src/pages/student/list/index.vue
  12. 4
      src/router/permission.js
  13. 2
      src/router/routes.js
  14. 17
      src/store/modules/user.js

@ -127,8 +127,8 @@ export default {
reportDetail: `occupationlab/occupationlab/achievement/reportDetail`, // 查看实验报告
schoolCourseByAchievement: `nakadai/nakadai/curriculum/schoolCourseByAchievement`, // 获取学校购买订单后的课程
spliceClass: `occupationlab/occupationlab/achievement/spliceClass`,
exportLabReport: `occupationlab/occupationlab/achievement/exportLabReport`,
exportBankExperimentReport: `occupationlab/occupationlab/achievement/exportBankExperimentReport`,
exportLabReport: `${host}occupationlab/occupationlab/achievement/exportLabReport`,
exportBankExperimentReport: `${host}occupationlab/occupationlab/achievement/exportBankExperimentReport`,
editExperimentalData: 'occupationlab/occupationlab/experimentalReport/editExperimentalData',
practiceActivity: 'occupationlab/occupationlab/achievement/practiceActivity',
practiceByProduct: `occupationlab/occupationlab/achievement/practiceByProduct`,

@ -1,328 +0,0 @@
<template>
<div class="wrap">
<div class="main">
<div class="box">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="账号登录" name="1"></el-tab-pane>
<el-tab-pane label="手机号/邮箱登录" name="2"></el-tab-pane>
<el-form :model="loginForm" :rules="loginRules" ref="loginForm" style="margin-top: 20px">
<el-form-item v-if="activeName === '1'" prop="account">
<el-input v-model.trim="loginForm.account" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item v-if="activeName === '2'" prop="account">
<el-input v-model.trim="loginForm.account" placeholder="请输入手机号/邮箱"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model.trim="loginForm.password">
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input placeholder="请输入验证码" v-model.trim="loginForm.code" @keyup.enter.native="submitFormLogin">
</el-input>
<img @click="getVerImg" :src="verificationIMG" class="verification" alt="">
</el-form-item>
<el-button class="submit" type="primary" @click="submitFormLogin">马上登录</el-button>
</el-form>
</el-tabs>
</div>
</div>
<el-dialog title="绑定手机号" :visible.sync="phoneVisible" :close-on-click-modal="false" width="30%">
<div style='padding: 0 13px 20px 13px;'>
依据国家政策法规需绑定手机号进行网络实名才可登录使用本平台
</div>
<el-form ref="form" label-width="60px">
<el-form-item label="手机号">
<el-input style="width: 100%;" placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
</el-form-item>
<el-form-item label="验证码">
<div style="display: flex;">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendPhoneCode" :disabled="phoneDisabled">{{
phoneBtnText }}
</el-button>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="phoneVisible = false"> </el-button>
<el-button type="primary" @click="phoneSubmit"> </el-button>
</span>
</el-dialog>
<v-footer class="footer"></v-footer>
</div>
</template>
<script>
import { mapActions, mapMutations } from "vuex";
import vFooter from "@/layouts/footer";
import util from "@/libs/util";
import Setting from "@/setting";
export default {
data: function () {
return {
activeName: "1",
loginForm: {
account: "",
password: "",
code: "", //
random: "", //
distinguish: 1, // ,1,2
type: 0, // 0-> 1-> 2->
platform: Setting.platformId
},
loginRules: {
account: [{ required: true, message: "请输入账号", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
code: [{ required: true, message: "请输入验证码", trigger: "blur" }]
},
verificationIMG: "",
phoneVisible: false, //
phone: "",
phoneCode: "",
phoneDisabled: false,
phoneTimer: null,
phoneBtnText: "发送验证码"
};
},
components: {
vFooter
},
created () {
this.getVerImg();
},
mounted () {
//
this.$once("hook:beforeDestroy", function () {
clearInterval(this.phoneTimer);
this.phoneTimer = null;
});
},
methods: {
...mapMutations("user", [
"SET_ROLENAME", 'SET_FROM'
]),
getVerImg () { //
this.loginForm.random = Math.floor(Math.random() * 999999999);
this.verificationIMG = this.api.verification + "?random=" + `${this.loginForm.random}`;
},
handleClick (tab, event) { //
this.loginForm.account = "";
this.$refs.loginForm.clearValidate();
this.loginRules.account[0].message = tab.index === "1" ? "请输入账号" : "请输入手机号/邮箱";
},
submitFormLogin () { //
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loginForm.distinguish = Number(this.activeName);
this.$post(this.api.logins, this.loginForm).then(res => {
if (res && res.status == 30001) {
this.phoneVisible = true;
}
this.getVerImg()
this.loginForm.code = ''
util.local.set(Setting.tokenKey, res.data.token, Setting.tokenExpires);
this.SET_FROM(false)
this.getRole()
this.queryCustomer()
}).catch(res => {
this.getVerImg()
this.loginForm.code = ''
})
} else {
return util.errorMsg("请检查表单数据");
}
});
},
//
getRole () {
this.$post(`${this.api.getUserAllRoleByToken}?platformId=${Setting.platformId}`).then(res => {
this.SET_ROLENAME(res)
}).catch(err => { })
},
queryCustomer () { //
const path = '/product/list' //
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => {
const list = res.permissionMenu[0].children
this.$router.push(list.find(e => e.path === path) ? path : list[0].path)
}).catch(err => { })
},
phoneCountdown () {
let count = 60;
if (!this.phoneTimer) {
this.phoneDisabled = true;
this.phoneTimer = setInterval(() => {
console.log("倒计时中");
if (count > 0) {
count--;
this.phoneBtnText = `${count}秒后重试`;
} else {
this.phoneDisabled = false;
clearInterval(this.phoneTimer);
this.phoneTimer = null;
this.phoneBtnText = `发送验证码`;
}
}, 1000);
}
},
sendPhoneCode () {
if (!this.phone) return util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return util.warningMsg("请输入正确的手机号");
let data = {
platform: Setting.platformId,
phone: this.phone,
types: 2
};
this.$post(this.api.sendPhoneOrEmailCode, data).then(res => {
if (res.message.opener) {
this.phoneCountdown();
this.phoneOpener = res.message.opener;
} else {
util.errorMsg(res.message);
}
}).catch(res => { });
},
phoneSubmit () {
if (!this.phone) return util.warningMsg("请输入手机号");
if (!/^1[3456789]\d{9}$/.test(this.phone)) return util.warningMsg("请输入正确的手机号");
if (!this.phoneCode) return util.warningMsg("请输入验证码");
let data = {
phone: this.phone,
types: 2,
code: this.phoneCode,
opener: this.phoneOpener,
platform: Setting.platformId,
account: this.loginForm.account
};
this.$post(this.api.bindPhoneOrEmail, data).then(res => {
util.successMsg("绑定成功");
this.loginForm.phone = this.phone;
this.phoneVisible = false;
util.local.set(Setting.tokenKey, res.token, Setting.tokenExpires);
let redirect = this.$route.query.redirect ? decodeURIComponent(this.$route.query.redirect) : "/index";
this.$router.replace(redirect);
util.successMsg("登录成功");
this.queryCustomer();
}).catch(res => {
});
}
}
};
</script>
<style lang="scss" scoped>
.wrap {
position: relative;
width: 100%;
height: 100%;
background-image: url(../../../assets/img/login-bg.png);
background-size: 100%;
.header {
width: 100%;
height: 60px;
position: absolute;
top: 0;
left: 0;
background-color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 18px;
.logo {
width: 150px;
margin-left: 20px;
&.hh {
width: 220px;
}
}
}
/deep/ .main {
position: absolute;
left: 50%;
top: 42px;
transform: translate(-50%, 0);
width: 1200px;
height: 82%;
margin-top: 60px;
background-image: url(../../../assets/img/login-input.png);
box-shadow: 0px 0px 79px 0px rgba(11, 15, 65, 0.36);
overflow: hidden;
.box {
width: 548px;
position: absolute;
left: 50%;
top: 50px;
transform: translate(-50%, 0);
.el-tabs__nav-scroll {
display: flex;
justify-content: center;
}
.el-tabs__nav-wrap::after {
background-color: #fff;
opacity: 0;
.el-tabs__active-bar {
background-color: #000;
border-radius: 2px;
}
.el-tabs__item {
padding: 0 90px;
color: #999;
&:hover {
color: #000;
}
&.is-active {
color: #333;
font-weight: bold;
}
}
}
.el-input__inner {
height: 80px;
line-height: 80px;
border: 1px solid rgba(220, 220, 220, 1);
border-radius: 2px;
}
.verification {
position: absolute;
top: 1px;
right: 1px;
width: 160px;
height: 78px;
cursor: pointer;
}
.submit {
width: 100%;
height: 88px;
margin-bottom: 50px;
font-weight: bold;
background: linear-gradient(90deg, rgba(94, 206, 253, 1), rgba(91, 67, 231, 1));
box-shadow: 0px 7px 27px 0px rgba(50, 129, 255, 0.51);
border-radius: 10px;
}
}
}
.footer {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
}
</style>

@ -16,14 +16,13 @@ export default {
localStorage.removeItem('opened')
localStorage.removeItem('review_token')
localStorage.removeItem('reviewPath')
this.token ? this.setLogin() : this.$router.replace('/login')
this.token ? this.setLogin() : this.$store.dispatch('user/logout')
},
methods: {
...mapMutations("user", [
"SET_ROLENAME", 'SET_FROM'
"SET_ROLENAME"
]),
setLogin () {
this.SET_FROM(true)
Util.session.set(Setting.tokenKey, window.atob(decodeURI(this.token)))
this.getOss()
this.getRole()

@ -71,8 +71,6 @@
</div>
<div>
<el-button type="primary" @click="exportData">导出成绩列表</el-button>
<!-- <el-button type="primary"
@click="exportReport">导出成绩详情</el-button> -->
</div>
</div>
<el-table :data="listData" class="table" ref="table" :key="curTab" header-align="center"
@ -351,30 +349,6 @@ export default {
util.downloadFileDirect(`${practice ? '练习' : '考核'}成绩列表.xlsx`, new Blob([res.data]))
}).catch(res => { })
},
//
exportReport () {
//
const list = this.multipleSelection.length ? this.multipleSelection : this.listDataAll
list.forEach(async e => {
if (e.reportId) {
try {
const { report, userScores } = await this.$get(`${this.api.reportDetail}?reportId=${e.reportId}`)
userScores.map((e, i) => {
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
})
for (const i in report) {
if (report[i] && typeof report[i] === 'string') report[i] = report[i].replace(/<[^>]+>/g, '')
}
report.purpose = report.purpose.replace(/<[^>]+>/g, '')
const res = await this.$post(this.api[userScores.find(e => e.lcRuleRecords) ? 'exportBankExperimentReport' : 'exportLabReport'], {
...report,
experimentalData: userScores
})
util.downloadFileDirect(`${e.userName}的实验报告.docx`, new Blob([res]))
} catch (e) { }
}
})
},
handleDelete (row) { //
this.$confirm("确定要删除吗?", "提示", {
type: "warning"

@ -210,19 +210,12 @@ export default {
...this.form,
mallId: cur.mallId || '',
systemId: cur.systemId || '',
courseType: this.$parent.active === 'tab2' ? 1 : 0,
courseType: this.$parent.active === 'tab2' ? 0 : 1,
pageNum: this.page,
pageSize: this.pageSize,
};
this.$post(this.api.getAchievementInfo, data).then(res => {
let list = []
if (this.$parent.active === 'tab3' && !permissions) {
list = res.page
this.total = res.total
} else {
list = res.page.records
this.total = res.page.total
}
this.$post(this.api.getAchievementInfo, data).then(({ page }) => {
const list = page.records
list.map(e => {
// isAdmin1 isdel=1courseDel=1 (1. 2.3)isAdmin0isDel1
e.canDel = permissions ?
@ -230,6 +223,7 @@ export default {
(e.isAdmin === 0 && e.isDel === 1) || (e.isAdmin === 1 && e.isDel === 1 && e.courseDel === 1)
})
this.listData = list
this.total = page.total
this.$nextTick(() => {
this.loading = false
});

@ -139,11 +139,16 @@
</template>
<script>
import util from "@/libs/util";
import Setting from '@/setting'
import Util from '@/libs/util'
import Axios from 'axios'
export default {
data () {
return {
reportId: this.$route.query.reportId,
headers: {
token: Util.session.get(Setting.tokenKey)
},
title: "实验报告",
form: {
className: "",
@ -253,16 +258,20 @@ export default {
if (form[i] && typeof form[i] === 'string') form[i] = form[i].replace(/<[^>]+>/g, '')
}
if (form.purpose) form.purpose = form.purpose.replace(/<[^>]+>/g, '')
this.$post(this.isLc ? this.api.exportBankExperimentReport : this.api.exportLabReport, {
...form,
experimentalData: list
}).then(res => {
console.log(res)
util.downloadFileDirect(`实验报告.docx`, new Blob([res]))
this.exporting = false
}).catch(res => {
try {
const res = await Axios.post(this.api[this.isLc ? 'exportBankExperimentReport' : 'exportLabReport'], {
...form,
experimentalData: list
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : `实验报告.docx`, new Blob([res.data]))
} finally {
this.exporting = false
})
}
},
}
};

@ -36,7 +36,7 @@
<div class="inline-input">
<!-- 选择系统 -->
<el-select v-if="courseSystem" v-model="systemId" placeholder="请选择系统" @change="getProject">
<el-select v-if="courseSystem" v-model="systemId" placeholder="请选择系统" clearable @change="getProject">
<el-option v-for="(item, i) in services" :key="i" :label="item.systemName" :value="item.systemId">
</el-option>
</el-select>
@ -243,7 +243,8 @@ export default {
})
this.services = data
if (data.length) {
this.systemId = this.form.systemId || data[0].systemId
// this.systemId = this.form.systemId || ''
this.systemId = ''
this.getProject()
this.loadIns = Loading.service()
}
@ -298,7 +299,8 @@ export default {
const { data } = await this.$get(this.api.getProjectListOfSystem, {
pageNum: this.page,
pageSize: this.pageSize,
systemId: this.systemId
systemId: this.systemId,
type: this.isTheory ? 3 : 1
})
if (this.isTheory) {
data.records.forEach(e => {

@ -198,7 +198,7 @@
</template>
<script>
import Util from "@/libs/util";
import Util from '@/libs/util'
import axios from 'axios'
import Setting from "@/setting";
export default {

@ -139,11 +139,16 @@
</template>
<script>
import util from "@/libs/util";
import Setting from '@/setting'
import Util from '@/libs/util'
import Axios from 'axios'
export default {
data () {
return {
reportId: this.$route.query.reportId,
headers: {
token: Util.session.get(Setting.tokenKey)
},
title: "实验报告",
form: {
className: "",
@ -216,7 +221,7 @@ export default {
this.expData = list
this.loading = false
},
exportPage () {
async exportPage () {
this.exporting = true
const form = Object.assign(this.form, this.infoData)
const list = JSON.parse(JSON.stringify(this.expData))
@ -225,23 +230,26 @@ export default {
if (item && item.runThePicture) e.runThePicture = item.runThePicture
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
e.id = i + 1
// if (e.referenceAnswer && typeof e.referenceAnswer === 'string') e.referenceAnswer = e.referenceAnswer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
})
for (const i in form) {
if (form[i] && typeof form[i] === 'string') form[i] = form[i].replace(/<[^>]+>/g, '')
}
form.purpose = form.purpose.replace(/<[^>]+>/g, '')
this.$post(this.isLc ? this.api.exportBankExperimentReport : this.api.exportLabReport, {
...form,
experimentalData: list
}).then(res => {
console.log(res)
util.downloadFileDirect(`实验报告.docx`, new Blob([res]))
this.exporting = false
}).catch(res => {
try {
const res = await Axios.post(this.api[this.isLc ? 'exportBankExperimentReport' : 'exportLabReport'], {
...form,
experimentalData: list
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : `实验报告.docx`, new Blob([res.data]))
} finally {
this.exporting = false
})
}
},
}
};

@ -85,10 +85,12 @@
<el-table-column prop="editor" label="编辑人" width="130" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope">
<template v-if="scope.row.isDownload || active">
<el-button type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" @click="download(scope.row)">下载</el-button>
</template>
<el-button type="text" @click="preview(scope.row)">预览</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button>
<el-button v-if="scope.row.isDownload || active" type="text" @click="del(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>

@ -1009,8 +1009,20 @@ export default {
async exportData () {
if (this.listData.length) {
this.exporting = true
//
const res = await axios.post(this.api.excelExportStudentList, this.multipleSelection.length ? this.multipleSelection : [], {
//
let data = {
architectureId: this.architectureId,
level: this.orgLevel,
keyWord: this.keyWord,
pageNum: this.page,
pageSize: this.pageSize
}
if (this.multipleSelection.length) {
data = {
studentList: this.multipleSelection
}
}
const res = await axios.post(this.api.excelExportStudentList, data, {
headers: this.headers,
responseType: 'blob'
})

@ -8,8 +8,8 @@ router.beforeEach((to, from, next) => {
document.title = Setting.titleSuffix
const role = util.session.get(Setting.tokenKey)
if (!role && !whiteList.includes(to.path)) {
store.dispatch('user/logout')
Setting.isDev || store.dispatch('user/logout')
} else {
next()
}
});
})

@ -12,7 +12,7 @@ const frameIn = [
// 默认路由配置
{
path: "/",
redirect: "/login"
redirect: "/redirect"
},
{
path: "/",

@ -18,7 +18,6 @@ export default {
dataTime: "",
roleName: '',
schoolId: '',
fromClient: false, // 是否从学生端登录
logView: false // 是否查询过日志状态,如果有,则不再调接口
},
mutations: {
@ -44,9 +43,6 @@ export default {
SET_ROLENAME: (state, roleName) => {
state.roleName = roleName
},
SET_FROM: (state, fromClient) => {
state.fromClient = fromClient
},
SET_SCHOOLID: (state, schoolId) => {
state.schoolId = schoolId
},
@ -85,14 +81,11 @@ export default {
post(api.logout).then(() => {
util.local.remove(Setting.storeKey)
util.local.remove(Setting.tokenKey)
if (state.fromClient) {
util.cookies.remove('serverLogin')
location.href = Setting.isDev
? `http://${location.hostname}:8082/#/`
: `${location.origin}/#/login`
} else {
location.reload()
}
util.session.remove(Setting.tokenKey)
window.opener && window.opener.location.reload()
location.href = Setting.isDev
? `http://${location.hostname}:8082/#/`
: `${location.origin}/#/login`
resolve()
}).catch(error => {
reject(error)

Loading…
Cancel
Save