Merge branch 'zcwy-zsx0223' into 'master'

Zcwy zsx0223

See merge request !173
This commit is contained in:
joshen
2024-04-18 17:36:46 +08:00
21 changed files with 2993 additions and 8 deletions

4
.env
View File

@@ -4,6 +4,8 @@ VUE_APP_BASE=/manage
VUE_APP_BASE_API=/manageApi
# systemApi
VUE_APP_SYS_API=/systemapi
# activityApi
VUE_APP_ACT_API=/activityApi
# 教师节上传图片文件夹id
VUE_APP_PIC_FOLDERID=1147577187794841600
# 教师节上传zip文件夹id
@@ -45,5 +47,7 @@ VUE_APP_H5=//u-pre.boe.com/student-h5
VUE_APP_AVATAR_PATH=/upload/
# 旧版管理员界面
VUE_APP_OLD_MANAGE=//u-pre.boe.com/resource/index.html
# 测评管理界面
VUE_APP_EVA_MANAGE=//u-pre.boe.com/quiz/index.html
# 批量面授报名模板
VUE_APP_FACE_STUDENT_TEMPLATE=批量面授报名模版-1673963663229.xlsx

View File

@@ -34,5 +34,7 @@ VUE_APP_FILE_PATH=/upload/boe/file/
VUE_APP_AVATAR_PATH=/upload/
# 旧版管理员界面
VUE_APP_OLD_MANAGE=//u.boe.com/resource/index.html
# 测评管理界面
VUE_APP_EVA_MANAGE=//u.boe.com/quiz/index.html
# 批量面授报名模板
VUE_APP_FACE_STUDENT_TEMPLATE=/file/批量面授报名模版-1679595925822.xlsx

View File

@@ -26,5 +26,7 @@ VUE_APP_H5=//u.boe.com/student-h5-release
VUE_APP_AVATAR_PATH=/upload/
# 旧版管理员界面
VUE_APP_OLD_MANAGE=//u-pre.boe.com/resource/index.html
# 测评管理界面
VUE_APP_EVA_MANAGE=//u-pre.boe.com/quiz/index.html
# 批量面授报名模板
VUE_APP_FACE_STUDENT_TEMPLATE=批量面授报名模版-1673963663229.xlsx

View File

@@ -61,3 +61,6 @@ http.interceptors.response.use(
);
export default http;
export function timeoutUpload(uploadTime) {
http.defaults.timeout = uploadTime;
}

39
src/api/evaluation.js Normal file
View File

@@ -0,0 +1,39 @@
// 测评上传
import http from "./configPublic";
const ACTIVITYAPI = '/activityApi'
import {getCookieForName} from "@/api/method";
//查询测评
export const list = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/list`,obj)
//导入
export const importList = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/import`,obj, {
headers: { "Content-Type": "multipart/form-data",token:getCookieForName("token") },
})
//保存
export const save = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/save`,obj)
//保存测评详情
export const saveEvaluationDetail = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/detail/saveEvaluationDetail`,obj)
//测评封面上传
export const uploadImage = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/upload-image`,obj,{
headers: { "Content-Type": "multipart/form-data",token:getCookieForName("token") },
})
//权限管理
export const adminList = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/permission/adminList`,obj)
//权限启用
export const updateStatus = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/permission/updateStatus`,obj)
//测评删除
export const deleteList = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/delete`,obj)
//测评详情展示
export const getPage = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/detail/getPage`,obj)
//测评详情删除
export const deleteById = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/detail/deleteById`,obj)
//测评清空
export const clear = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/evaluation/clear`,obj)
//保存启用的人员信息
export const savePermission = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/permission/savePermission`,obj)
//权限列表
export const saveLists = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/permission/list`,obj)
//删除配置管理
export const deleteId = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/permission/delete`,obj)
//普通管理员权限
export const getByUserId = (obj) => http.post(`${process.env.VUE_APP_ACT_API}/permission/getByUserId`,obj)

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -538,6 +538,29 @@
},
];
}
if (n.indexOf("/evaluationupload") !== -1 || n.indexOf("/EvaluationUpload") !== -1) {
state.list = [
{
name: "测评",
},
{
name: '测评报告'
}
];
}
if (n.indexOf("/evadown") !== -1 || n.indexOf("/EvaDown") !== -1) {
state.list = [
{
name: "测评",
},
{
name: '测评报告'
},
{
name: route.query.name
}
];
}
if (n.indexOf("/download") !== -1 || n.indexOf("/download") !== -1) {
state.list = [
{

View File

@@ -422,6 +422,35 @@
</div>
<router-link to="/qamanage">问答管理</router-link>
</a-menu-item>
<a-sub-menu key="sub23" @titleClick="titleClick" v-if="checkMenu('evaluationupload')">
<template #icon>
<div class="imgBox">
<img
style="width: 16px; height: 16px"
src="../assets/images/navleft/grateful.png"
/>
</div>
</template>
<template #title>测评</template>
<a-menu-item key="sub23-1" v-if="checkMenu('evaluationupload')">
<span
:class="{
circleActive: selectedKeys[0] === 'sub23-1' ? true : false,
circle: selectedKeys[0] === 'sub23-1' ? false : true,
}"
></span>
<router-link to="/evaluationupload">测评上传</router-link>
</a-menu-item>
<a-menu-item key="sub23-2">
<span
:class="{
circleActive: selectedKeys[0] === 'sub22-2' ? true : false,
circle: selectedKeys[0] === 'sub22-2' ? false : true,
}"
></span>
<a target="_blank" :href="evaluationManagement">测评管理</a>
</a-menu-item>
</a-sub-menu>
<a-menu-item key="sub15" @titleClick="titleClick" v-if="checkMenu('download')">
<div class="imgBox">
<img
@@ -647,6 +676,9 @@
<a-menu-item key="sub15" @titleClick="titleClick">
<router-link to="/download">问答</router-link>
</a-menu-item>
<a-menu-item key="sub23" @titleClick="titleClick">
<router-link to="/evaluationupload">测评</router-link>
</a-menu-item>
<a-menu-item key="sub18" v-if="checkMenu('OldSystemManage')">
<router-link target="_blank" to="/oldsystemmanage">旧版</router-link>
@@ -698,7 +730,8 @@ export default {
"sub19",
"sub20",
"sub21",
"sub22"
"sub22",
"sub23",
],
openKeys: localStorage.getItem("openKeys")
? JSON.parse(localStorage.getItem("openKeys"))
@@ -908,6 +941,12 @@ export default {
selectedKeys: "sub14",
pagename: "问答管理",
},
{
href: "/evaluationupload",
openKeys: "sub23",
selectedKeys: "sub23-1",
pagename: "测评上传",
},
{
href: "/download",
openKeys: "sub15",
@@ -1009,7 +1048,8 @@ export default {
},
],
oldManage: window.location.protocol + process.env.VUE_APP_OLD_MANAGE
oldManage: window.location.protocol + process.env.VUE_APP_OLD_MANAGE,
evaluationManagement: window.location.protocol + process.env.VUE_APP_EVA_MANAGE
});
const onOpenChange = (openKeys) => {

36
src/utils/zipdownload.js Normal file
View File

@@ -0,0 +1,36 @@
import axios from 'axios'
import {getCookieForName} from "@/api/method";
const mimeMap = {
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
zip: 'application/zip'
}
const baseUrl = process.env.VUE_APP_ACT_API
export function downLoadZip(str, filename) {
var url = baseUrl + str
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getCookieForName("token") }
}).then(res => {
resolveBlob(res, mimeMap.zip,filename)
})
}
/**
* 解析blob响应内容并下载
* @param {*} res blob响应内容
* @param {String} mimeType MIME类型
*/
export function resolveBlob(res, mimeType,filename) {
const link = document.createElement('a');// 创建a标签
let blob = new Blob([res.data], { type: mimeType }); // 设置文件类型
link.style.display = "none";
link.href = URL.createObjectURL(blob); // 创建URL
link.setAttribute("download", `${filename}`);
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
}

View File

@@ -0,0 +1,331 @@
<template>
<div class="returneva">
<router-link to="/evaluationupload">
<div style="display: flex">
<img class="img2" src="../../assets/images/leveladd/back.png" />
<div class="return">返回</div>
</div>
</router-link>
</div>
<div class="evadown">
<div class="down_header">
<div class="down_header_title" @click="downloadAll">
<div class="down_header_btn" v-if="downloadShow">
<div class="btnText">全量下载</div>
</div>
</div>
<div class="down_header_title" style="display: flex;">
<div class="down_header_search">
<a-input
v-model:value="searchName"
placeholder="查询姓名或工号或导入者"
style="width: 270px; height: 40px; border-radius: 8px;margin-right: 14px;"
/>
</div>
<div class="down_header_btn btn1" @click="searchList">
<div class="search"></div>
<span class="btnText">搜索</span>
</div>
<div class="down_header_btn btn2" @click="searchNo">
<div class="search"></div>
<span class="btnText">重置</span>
</div>
</div>
</div>
<div class="tablelist">
<a-table
:columns="columns"
:data-source="tableData"
:loading="tableLoading"
:scroll="{ x: 'max-content' }"
:pagination="pagination"
>
<template #operation="{ record, column }">
<a-space>
<a-button type="link" v-if="downloadShow" @click="downloadItem(record)">
<a-tooltip>
<template #title>下载</template>
<span class="download"></span>
</a-tooltip>
</a-button>
<a-button type="link" v-if="deleteIds" @click="deleteItem(record)">
<a-tooltip>
<template #title>删除</template>
<span class="delete"></span>
</a-tooltip>
</a-button>
</a-space>
</template>
</a-table>
</div>
</div>
</template>
<script>
import { ref,onMounted, reactive,toRefs,computed,watch } from "vue";
import dialog from "@/utils/dialog";
import { getPage,deleteById } from "@/api/evaluation";
import { useRoute } from "vue-router";
import { message } from "ant-design-vue";
import { useStore } from "vuex";
import {boeRequest} from "@/api/request";
import {downLoadZip} from "@/utils/zipdownload";
export default {
name: "evadown",
components: {},
setup() {
const store = useStore();
const userInfo = computed(()=>store.state.userInfo)
const route = useRoute();
const state = reactive({
downloadShow: route.query.permission=='true'?true:false,
deleteIds: route.query.deleteIds=='true'?true:false,
searchName: '',
tableLoading: false,
tableData:[],
total: 0,
params: {
pageNo: 1,
pageSize: 10,
},
})
const columns = ref([
{
title: "姓名",
dataIndex: "studentName",
key: "studentName",
className: "h",
ellipsis: true,
align: "center",
width: 100,
},
{
title: "工号",
dataIndex: "workNum",
key: "workNum",
className: "h",
ellipsis: true,
align: "center",
width: 100,
},
{
title: "评测名称",
dataIndex: "evaluationName",
key: "evaluationName",
className: "h",
ellipsis: true,
align: "center",
width: 100,
},
{
title: "上传人",
dataIndex: "uploadName",
key: "uploadName",
className: "h",
ellipsis: true,
align: "center",
width: 100,
},
{
title: "上传日期",
dataIndex: "updateTime",
key: "updateTime",
className: "h",
ellipsis: true,
align: "center",
width: 100,
},
{
title: "操作",
width: "20%",
dataIndex: "operation",
key: "operation",
align: "center",
slots: { customRender: "operation" },
},
])
const pagination = computed(() => ({
total: state.total,
showSizeChanger: true,
showQuickJumper: false,
current: state.params.pageNo,
pageSize: state.params.pageSize,
onChange: changePagination,
}))
const changePagination = (page,pageSize) => {
state.params.pageNo = page
state.params.pageSize = pageSize
listData()
}
watch(()=>state.params.pageSize,(val)=>{
state.params.pageNo = 1
listData()
})
const downloadAll = (record) => {
if(state.total == 0){
message.info('请先上传报告')
return
}
// window.open(`/activityApi/evaluation/download?id=${route.query.id}`);
downLoadZip(`/evaluation/download?id=${route.query.id}`,route.query.name)
}
const listData = async () => {
state.tableLoading = true
await boeRequest('/activityApi/evaluation/detail/getPage post',{
pid:route.query.id,
pageNo: state.params.pageNo,
pageSize: state.params.pageSize,
searchParam:state.searchName
}).then((res)=>{
if(res.code === 200){
state.tableLoading = false
state.tableData = res.data.records,
state.total = res.data.total
}
})
// await getPage({
// pid:route.query.id,
// pageNo: state.params.pageNo,
// pageSize: state.params.pageSize,
// searchParam:state.searchName
// }).then((res) => {
// if(res.code === 200){
// state.tableLoading = false
// state.tableData = res.data.records,
// console.log(state.tableData,'data')
// state.total = res.data.total
// }
// })
}
const searchList = () => {
state.params.pageNo = 1
listData()
}
const searchNo = () => {
state.searchName = ''
state.params.pageNo = 1
listData()
}
const downloadItem = (record) => {
window.open(`/activityApi/evaluation/detail/downloadById?id=${record.id}`)
};
const deleteItem = (record) => {
dialog({
content: '请您确认是否要删除该报告?',
ok: () => {
deleteById({id:record.id,kid:record.kid,pid:route.query.id}).then((res)=>{
message.success('删除成功')
listData()
})
},
});
};
onMounted(() => {
listData()
})
return {
...toRefs(state),
columns,
deleteItem,
downloadItem,
pagination,
listData,
searchList,
searchNo,
downloadAll,
userInfo,
}
},
}
</script>
<style lang="scss" scoped>
.returneva{
position: absolute;
right: 0;
top: 139px;
.img2{
width: 42px;
height: 42px;
}
.return{
font-size: 14px;
margin-top: 10px;
margin-right: 102px;
}
}
.evadown {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.down_header{
margin-left: 38px;
margin-right: 38px;
margin-top: 30px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.down_header_title{
margin-right: 20px;
margin-bottom: 20px;
.down_header_btn {
padding: 0px 26px 0px 26px;
height: 38px;
background: #4ea6ff;
border-radius: 8px;
border: 1px solid rgba(64, 158, 255, 1);
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 36px;
margin-left: 5px;
}
}
.btn1 {
.search {
width: 15px;
height: 17px;
background-image: url("../../assets/images/courseManage/search0.png");
}
}
.btn2 {
.search {
width: 16px;
height: 18px;
background-image: url("../../assets/images/courseManage/reset0.png");
}
}
}
}
.tablelist{
padding: 10px 35px;
.download{
width: 19px;
height: 20px;
background: url("../../assets/images/evaluation/download.png") no-repeat;
background-size: 100%;
}
.delete{
width: 19px;
height: 20px;
background: url("../../assets/images/evaluation/delete.png") no-repeat;
background-size: 100%;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -542,7 +542,7 @@
<div
class="operation"
style="cursor: pointer"
@click="openCourse(item,key)"
@click="openCourse(item,key,index)"
v-if="item.type == 2"
>
开课
@@ -1568,9 +1568,9 @@ export default {
window.open(`${process.env.VUE_APP_BASE_API}/admin/assessment/manage/export?type=${2}&pid=${item.id}&courseId=${item.courseId}`)
};
const coursePlanRef = ref();
const openCourse = async (item,index) => {
const openCourse = async (item,key,index) => {
await GetRouterDraftDetail(state.routerId).then((item)=>{
coursePlanRef.value.openDrawer(item.data.data.chapterList[0].draftTaskList[index]);
coursePlanRef.value.openDrawer(item.data.data.chapterList[index].draftTaskList[key]);
})
}
const qrCodeItems = ref([]);

View File

@@ -676,7 +676,7 @@
<div
class="operation"
style="cursor: pointer"
@click="openCourse(item,key)"
@click="openCourse(item,key,index)"
v-if="item.type == 2"
>
开课
@@ -2450,9 +2450,9 @@ export default {
window.open(`${process.env.VUE_APP_BASE_API}/admin/assessment/manage/export?type=${1}&pid=${item.id}&courseId=${item.courseId}`)
};
const coursePlanRef = ref();
const openCourse = async (item,index) => {
const openCourse = async (item,key,index) => {
await apitl.getDraftTask({projectId: item.projectId}).then((item)=>{
coursePlanRef.value.openDrawer(item.data.data.stageList[0].taskDraftDtoList[index]);
coursePlanRef.value.openDrawer(item.data.data.stageList[index].taskDraftDtoList[key]);
})
}
const qrCodeItems = ref([]);