【修改】前端提交代码
This commit is contained in:
19
src/api/system/tranparam/index.ts
Normal file
19
src/api/system/tranparam/index.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
// 通用参数实体
|
||||||
|
export interface TranParam {
|
||||||
|
id?: number
|
||||||
|
examSet: string // 0 是开启,1 否关闭
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 获取列表
|
||||||
|
export const getSet = () => {
|
||||||
|
return request.get({ url: '/exam/tranparam/getSetList' })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
export const updateSet = (data) => {
|
||||||
|
return request.put({ url: '/exam/tranparam/updateSet', data })
|
||||||
|
}
|
||||||
@@ -87,6 +87,11 @@ export const importUserTemplate = () => {
|
|||||||
export const importUserTemplateStu = () => {
|
export const importUserTemplateStu = () => {
|
||||||
return request.download({ url: '/system/user/get-import-template-stu' })
|
return request.download({ url: '/system/user/get-import-template-stu' })
|
||||||
}
|
}
|
||||||
|
// 下载学生试卷任务导入模板
|
||||||
|
export const importUserTaskStu = () => {
|
||||||
|
return request.download({ url: '/system/user/get-import-task-stu' })
|
||||||
|
}
|
||||||
|
|
||||||
// 下载教师导入模板
|
// 下载教师导入模板
|
||||||
export const importUserTemplateTeacher = () => {
|
export const importUserTemplateTeacher = () => {
|
||||||
return request.download({ url: '/system/user/get-import-template-teacher' })
|
return request.download({ url: '/system/user/get-import-template-teacher' })
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { service } from './service'
|
import { service } from './service'
|
||||||
|
|
||||||
import { config } from './config'
|
import { config } from './config'
|
||||||
|
import { TranParam } from '@/api/tranparam'
|
||||||
|
|
||||||
const { default_headers } = config
|
const { default_headers } = config
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ export default {
|
|||||||
const res = await request({ method: 'DELETE', ...option })
|
const res = await request({ method: 'DELETE', ...option })
|
||||||
return res.data as unknown as T
|
return res.data as unknown as T
|
||||||
},
|
},
|
||||||
put: async <T = any>(option: any) => {
|
put: async <T = any>(option: any, data: TranParam) => {
|
||||||
const res = await request({ method: 'PUT', ...option })
|
const res = await request({ method: 'PUT', ...option })
|
||||||
return res.data as unknown as T
|
return res.data as unknown as T
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ export default {
|
|||||||
small: '小'
|
small: '小'
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
welcome: '湖北省技能高考万维考试平台',
|
welcome: '万维智能实训平台',
|
||||||
message: '',
|
message: '',
|
||||||
tenantname: '租户名称',
|
tenantname: '租户名称',
|
||||||
username: '用户名',
|
username: '用户名',
|
||||||
@@ -128,7 +128,7 @@ export default {
|
|||||||
remember: '记住我',
|
remember: '记住我',
|
||||||
hasUser: '已有账号?去登录',
|
hasUser: '已有账号?去登录',
|
||||||
forgetPassword: '忘记密码?',
|
forgetPassword: '忘记密码?',
|
||||||
tenantNamePlaceholder: '请输入租户名称',
|
tenantNamePlaceholder: '请输入学校名称',
|
||||||
usernamePlaceholder: '请输入用户名',
|
usernamePlaceholder: '请输入用户名',
|
||||||
passwordPlaceholder: '请输入密码',
|
passwordPlaceholder: '请输入密码',
|
||||||
codePlaceholder: '请输入验证码',
|
codePlaceholder: '请输入验证码',
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ export const getDictLabel = (dictType: string, value: any): string => {
|
|||||||
export enum DICT_TYPE {
|
export enum DICT_TYPE {
|
||||||
USER_TYPE = 'user_type',
|
USER_TYPE = 'user_type',
|
||||||
COMMON_STATUS = 'common_status',
|
COMMON_STATUS = 'common_status',
|
||||||
|
C = 'c',
|
||||||
TERMINAL = 'terminal', // 终端
|
TERMINAL = 'terminal', // 终端
|
||||||
DATE_INTERVAL = 'date_interval', // 数据间隔
|
DATE_INTERVAL = 'date_interval', // 数据间隔
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
v-if="refreshTable"
|
v-if="refreshTable"
|
||||||
>
|
>
|
||||||
<el-table-column prop="name" label="专业名称" />
|
<el-table-column prop="name" label="专业名称" />
|
||||||
<el-table-column prop="roles" label="软件环境" />
|
<!-- <el-table-column prop="roles" label="软件环境" /> -->
|
||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
修改
|
修改
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button link type="danger" @click="handleDelete(scope.row.id)"> 删除 </el-button>
|
<el-button link type="danger" @click="handleDelete(scope.row.id)"> 删除 </el-button>
|
||||||
<!-- 第三级才显示规则按钮 -->
|
<!-- 第三级才显示规则按钮
|
||||||
<el-button
|
<el-button
|
||||||
v-if="scope.row.level === 3"
|
v-if="scope.row.level === 3"
|
||||||
link
|
link
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
@click="handleRule(scope.row)"
|
@click="handleRule(scope.row)"
|
||||||
>
|
>
|
||||||
软件环境
|
软件环境
|
||||||
</el-button>
|
</el-button>-->
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|||||||
@@ -119,7 +119,15 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="场次" prop="batch">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.batch"
|
||||||
|
placeholder="请输入场次"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
@@ -171,6 +179,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="试卷任务" align="center" prop="taskName" />
|
<el-table-column label="试卷任务" align="center" prop="taskName" />
|
||||||
|
<el-table-column label="场次" align="center" prop="batch" />
|
||||||
<el-table-column label="机器ip" align="center" prop="ip" width="180px"/>
|
<el-table-column label="机器ip" align="center" prop="ip" width="180px"/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="更新时间"
|
label="更新时间"
|
||||||
@@ -361,7 +370,8 @@ const queryParams = reactive({
|
|||||||
ip: undefined,
|
ip: undefined,
|
||||||
remainingTime: [],
|
remainingTime: [],
|
||||||
startTime: undefined,
|
startTime: undefined,
|
||||||
endTime: undefined
|
endTime: undefined,
|
||||||
|
batch: undefined
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|||||||
@@ -96,8 +96,12 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
</el-row>
|
<el-form-item label="标题" prop="contentText">
|
||||||
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -446,6 +450,7 @@ const formData = ref({
|
|||||||
pointNamesVo:'',
|
pointNamesVo:'',
|
||||||
chapteridDictTextVo:'',
|
chapteridDictTextVo:'',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -106,13 +106,11 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<!-- <el-row>
|
<el-col :span="12">
|
||||||
<el-col :span="12">
|
<el-form-item label="标题" prop="contentText">
|
||||||
<el-form-item label="来源" prop="resourceValue">
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
<el-input v-model="formData.resourceValue" placeholder="请输入来源" />
|
</el-form-item>
|
||||||
</el-form-item>
|
</el-col>
|
||||||
</el-col>
|
|
||||||
</el-row> -->
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
<div class="edit-left bottom-common">
|
<div class="edit-left bottom-common">
|
||||||
@@ -326,6 +324,7 @@ const formData = ref({
|
|||||||
pointNamesVo:'',
|
pointNamesVo:'',
|
||||||
chapteridDictTextVo:'',
|
chapteridDictTextVo:'',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -84,18 +84,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="审核状态" prop="audit">
|
<el-form-item label="标题" prop="contentText">
|
||||||
<el-select v-model="formData.audit" placeholder="请选择审核状态">
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
<el-option
|
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.QUESTION_AUDIT)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col> -->
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -381,6 +374,7 @@ const formData = ref<any>({
|
|||||||
pointNamesVo: '',
|
pointNamesVo: '',
|
||||||
chapteridDictTextVo: '',
|
chapteridDictTextVo: '',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -96,7 +96,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="标题" prop="contentText">
|
||||||
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -506,6 +510,7 @@ const formData = ref({
|
|||||||
pointNamesVo:'',
|
pointNamesVo:'',
|
||||||
chapteridDictTextVo:'',
|
chapteridDictTextVo:'',
|
||||||
content: '<p>---------------------------------------------------------------------</p><p> 请在打开的窗口中,进行下列操作,完成所有操作后,请关闭窗口。</p><p>---------------------------------------------------------------------</p><p>',
|
content: '<p>---------------------------------------------------------------------</p><p> 请在打开的窗口中,进行下列操作,完成所有操作后,请关闭窗口。</p><p>---------------------------------------------------------------------</p><p>',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -96,9 +96,12 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="标题" prop="contentText">
|
||||||
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
<div class="edit-left bottom-common">
|
<div class="edit-left bottom-common">
|
||||||
@@ -487,6 +490,7 @@ const formData = ref({
|
|||||||
pointNamesVo:'',
|
pointNamesVo:'',
|
||||||
chapteridDictTextVo:'',
|
chapteridDictTextVo:'',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
@@ -671,7 +675,7 @@ function flattenPsVoList(list, parentPath = '') {
|
|||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
result.push(...flattenPsVoList(item.children, currentPath));
|
result.push(...flattenPsVoList(item.children, currentPath));
|
||||||
} else {
|
} else {
|
||||||
const symbol = item.value === 'true' ? '✅' : item.value === 'false' ? '❌' : item.value;
|
const symbol = item.value ;
|
||||||
result.push({
|
result.push({
|
||||||
key: item.key, // 一定要有 key
|
key: item.key, // 一定要有 key
|
||||||
label: `${currentPath}: ${symbol}`,
|
label: `${currentPath}: ${symbol}`,
|
||||||
@@ -697,11 +701,7 @@ function flattenPsVoListOther(list, parentPath = '') {
|
|||||||
: item.key;
|
: item.key;
|
||||||
|
|
||||||
// 处理值显示(类似原函数的symbol逻辑)
|
// 处理值显示(类似原函数的symbol逻辑)
|
||||||
const valueDisplay = item.value === 'true'
|
const valueDisplay = item.value ;
|
||||||
? '✅'
|
|
||||||
: item.value === 'false'
|
|
||||||
? '❌'
|
|
||||||
: item.value ;
|
|
||||||
|
|
||||||
// 只有叶子节点(没有children属性)才添加到结果
|
// 只有叶子节点(没有children属性)才添加到结果
|
||||||
// 根据您的数据结构,type=1可能是叶子节点的标识
|
// 根据您的数据结构,type=1可能是叶子节点的标识
|
||||||
@@ -765,7 +765,7 @@ console.log(formData.value.fileUploads+"formData.value.fileUploads")
|
|||||||
|
|
||||||
|
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
// specialtyName: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }]
|
status: [{ required: true, message: '启用状态必填', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
// 左侧试题描述
|
// 左侧试题描述
|
||||||
@@ -1113,7 +1113,7 @@ const handleNodeClick = (data, node) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 构造一个 label,用 key 和 value 显示
|
// 构造一个 label,用 key 和 value 显示
|
||||||
const symbol = data.value === true ? '✅' : data.value === false ? '❌' : data.value;
|
const symbol = data.value ;
|
||||||
const label = `${data.key}: ${symbol}`;
|
const label = `${data.key}: ${symbol}`;
|
||||||
|
|
||||||
// 判断是否已存在,避免重复添加
|
// 判断是否已存在,避免重复添加
|
||||||
@@ -1154,8 +1154,12 @@ const updateSort = () => {
|
|||||||
item.sort = index + 1
|
item.sort = index + 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const removePoint = (index: number) => {
|
const removePoint = (row) => {
|
||||||
flatPointList.value.splice(index, 1);
|
for (let i = 0; i < flatPointList.value.length; i++) {
|
||||||
|
if (row.label == flatPointList.value[i].label) {
|
||||||
|
flatPointList.value.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,18 +84,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="审核状态" prop="audit">
|
<el-form-item label="标题" prop="contentText">
|
||||||
<el-select v-model="formData.audit" placeholder="请选择审核状态">
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
<el-option
|
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.QUESTION_AUDIT)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col> -->
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -313,6 +306,7 @@ const formData = ref({
|
|||||||
pointNamesVo: '',
|
pointNamesVo: '',
|
||||||
chapteridDictTextVo: '',
|
chapteridDictTextVo: '',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -84,6 +84,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="标题" prop="contentText">
|
||||||
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -252,6 +257,7 @@ const formData = ref({
|
|||||||
pointNamesVo: '',
|
pointNamesVo: '',
|
||||||
chapteridDictTextVo: '',
|
chapteridDictTextVo: '',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -84,18 +84,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="审核状态" prop="audit">
|
<el-form-item label="标题" prop="contentText">
|
||||||
<el-select v-model="formData.audit" placeholder="请选择审核状态">
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
<el-option
|
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.QUESTION_AUDIT)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col> -->
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -394,6 +387,7 @@ const formData = ref({
|
|||||||
pointNamesVo: '',
|
pointNamesVo: '',
|
||||||
chapteridDictTextVo: '',
|
chapteridDictTextVo: '',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -84,18 +84,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="审核状态" prop="audit">
|
<el-form-item label="标题" prop="contentText">
|
||||||
<el-select v-model="formData.audit" placeholder="请选择审核状态">
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
<el-option
|
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.QUESTION_AUDIT)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col> -->
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -406,6 +399,7 @@ const formData = ref({
|
|||||||
pointNamesVo: '',
|
pointNamesVo: '',
|
||||||
chapteridDictTextVo: '',
|
chapteridDictTextVo: '',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText: '',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -84,18 +84,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="审核状态" prop="audit">
|
<el-form-item label="标题" prop="contentText">
|
||||||
<el-select v-model="formData.audit" placeholder="请选择审核状态">
|
<el-input v-model="formData.contentText" placeholder="请输入标题" />
|
||||||
<el-option
|
|
||||||
v-for="dict in getStrDictOptions(DICT_TYPE.QUESTION_AUDIT)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col> -->
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="edit-bottom">
|
<div class="edit-bottom">
|
||||||
@@ -487,6 +480,7 @@ const formData = ref({
|
|||||||
pointNamesVo: '',
|
pointNamesVo: '',
|
||||||
chapteridDictTextVo: '',
|
chapteridDictTextVo: '',
|
||||||
content: '',
|
content: '',
|
||||||
|
contentText:'',
|
||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
quBankName: '',
|
quBankName: '',
|
||||||
|
|||||||
@@ -50,15 +50,15 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- <el-form-item label="手机号码" prop="mobile">-->
|
<el-form-item label="标题" prop="contentText">
|
||||||
<!-- <el-input-->
|
<el-input
|
||||||
<!-- v-model="queryParams.mobile"-->
|
v-model="queryParams.contentText"
|
||||||
<!-- placeholder="请输入手机号码"-->
|
placeholder="请输入标题"
|
||||||
<!-- clearable-->
|
clearable
|
||||||
<!-- @keyup.enter="handleQuery"-->
|
@keyup.enter="handleQuery"
|
||||||
<!-- class="!w-240px"-->
|
class="!w-240px"
|
||||||
<!-- />-->
|
/>
|
||||||
<!-- </el-form-item>-->
|
</el-form-item>
|
||||||
<!-- <el-form-item label="审核状态" prop="audit">
|
<!-- <el-form-item label="审核状态" prop="audit">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="queryParams.audit"
|
v-model="queryParams.audit"
|
||||||
@@ -179,6 +179,11 @@
|
|||||||
prop="quNum"
|
prop="quNum"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
/>
|
/>
|
||||||
|
<el-table-column label="标题" align="center" prop="contentText">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getFirstNChineseChars(row.contentText, 10) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="题干" align="center" prop="content" width="120">
|
<el-table-column label="题干" align="center" prop="content" width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ getFirstNChineseChars(row.content, 5) }}
|
{{ getFirstNChineseChars(row.content, 5) }}
|
||||||
@@ -428,6 +433,7 @@ const queryParams = reactive({
|
|||||||
specialtyName: '',
|
specialtyName: '',
|
||||||
courseName: '',
|
courseName: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
|
contentText:'',
|
||||||
pointNames: '',
|
pointNames: '',
|
||||||
chapteridDictText: '',
|
chapteridDictText: '',
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
@@ -829,20 +835,19 @@ const importFormRef = ref()
|
|||||||
|
|
||||||
/** 修改用户状态 */
|
/** 修改用户状态 */
|
||||||
const handleStatusChange = async (row: any) => {
|
const handleStatusChange = async (row: any) => {
|
||||||
|
const oldStatus = row.status
|
||||||
|
console.log(oldStatus)
|
||||||
try {
|
try {
|
||||||
// 修改状态的二次确认
|
await message.confirm(`确认要修改「${row.quNum}」的试题状态吗?`)
|
||||||
await message.confirm('确认要修改' + row.quNum + '"试题状态吗?')
|
await QuestionApi.updateQuStatus(row.quId, row.status)
|
||||||
// 发起修改状态
|
|
||||||
QuestionApi.updateQuStatus(row.quId, row.status)
|
|
||||||
// 刷新列表
|
|
||||||
await getList()
|
await getList()
|
||||||
} catch {
|
} catch {
|
||||||
// 取消后,进行恢复按钮
|
row.status = oldStatus
|
||||||
row.status =
|
await getList()
|
||||||
row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
const exportLoading = ref(false)
|
const exportLoading = ref(false)
|
||||||
|
|
||||||
@@ -931,23 +936,37 @@ const handleRole = (row: UserApi.UserVO) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getFirstNChineseChars(htmlStr) {
|
function getFirstNChineseChars(htmlStr,limit ) {
|
||||||
if (!htmlStr) return ''
|
if (!htmlStr) return ''
|
||||||
|
|
||||||
// 将 HTML 转为纯文本
|
// 尝试反转义(处理 < > 等)
|
||||||
const tempDiv = document.createElement('div')
|
const txt = document.createElement('textarea')
|
||||||
tempDiv.innerHTML = htmlStr
|
txt.innerHTML = htmlStr
|
||||||
let text = tempDiv.textContent || tempDiv.innerText || ''
|
htmlStr = txt.value // => <p>test</p>
|
||||||
|
|
||||||
// 去掉空格和换行
|
// 判断是否包含 HTML 标签
|
||||||
|
const hasHtmlTag = /<[^>]+>/.test(htmlStr)
|
||||||
|
|
||||||
|
// 提取纯文本
|
||||||
|
let text = hasHtmlTag
|
||||||
|
? (() => {
|
||||||
|
const tempDiv = document.createElement('div')
|
||||||
|
tempDiv.innerHTML = htmlStr
|
||||||
|
return tempDiv.textContent || tempDiv.innerText || ''
|
||||||
|
})()
|
||||||
|
: htmlStr
|
||||||
|
|
||||||
|
// 去空格和换行
|
||||||
text = text.replace(/\s+/g, '')
|
text = text.replace(/\s+/g, '')
|
||||||
|
|
||||||
// 匹配汉字
|
// 这里改成提取“中英文混合”而非仅中文
|
||||||
const match = text.match(/[\u4e00-\u9fa5]/g)
|
const match = text.match(/[\u4e00-\u9fa5a-zA-Z0-9]/g)
|
||||||
if (!match) return ''
|
if (!match) return ''
|
||||||
|
|
||||||
return match.slice(0, 6).join('')
|
return match.slice(0, limit).join('')+ '...';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
|||||||
58
src/views/system/set/examset/index.vue
Normal file
58
src/views/system/set/examset/index.vue
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<ContentWrap title="考试模式设置">
|
||||||
|
<el-card>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span>是否开启考试模式:</span>
|
||||||
|
<el-switch
|
||||||
|
v-model="examSet"
|
||||||
|
active-value="0"
|
||||||
|
inactive-value="1"
|
||||||
|
active-text="开启"
|
||||||
|
inactive-text="关闭"
|
||||||
|
@change="handleSwitchChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||||
|
import * as TranParamApi from '@/api/system/tranparam'
|
||||||
|
import type { TranParam } from '@/api/system/tranparam'
|
||||||
|
|
||||||
|
const examSet = ref<'0' | '1'>('1') // 默认关闭
|
||||||
|
const examId = ref<number | null>(null) // 👈 存储ID
|
||||||
|
// 页面加载时获取当前状态
|
||||||
|
const getExamSet = async () => {
|
||||||
|
const res = await TranParamApi.getSet()
|
||||||
|
const record = res.list?.[0]
|
||||||
|
examSet.value = record?.examSet ?? '1'
|
||||||
|
examId.value = record?.id ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getExamSet()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 修改考试模式
|
||||||
|
const handleSwitchChange = async (val: string) => {
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(`确定要${val === '0' ? '开启' : '关闭'}考试模式吗?`, '提示', {
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
const data: TranParam = {
|
||||||
|
id: examId.value!,
|
||||||
|
examSet: val
|
||||||
|
}
|
||||||
|
await TranParamApi.updateSet(data)
|
||||||
|
getExamSet();
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
examSet.value = val === '0' ? '1' : '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
150
src/views/system/set/param/SpecialtyForm.vue
Normal file
150
src/views/system/set/param/SpecialtyForm.vue
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" :title="dialogTitle">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
v-loading="formLoading"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="80px"
|
||||||
|
>
|
||||||
|
<el-form-item label="上级专业" prop="parentId">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="formData.parentId"
|
||||||
|
:data="specialtyTree"
|
||||||
|
:props="defaultProps"
|
||||||
|
check-strictly
|
||||||
|
default-expand-all
|
||||||
|
placeholder="请选择上级专业"
|
||||||
|
value-key="spId"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="专业名称" prop="spName">
|
||||||
|
<el-input v-model="formData.spName" placeholder="请输入专业名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-select v-model="formData.status" clearable placeholder="请选择状态">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
|
import * as SpecialtyApi from '@/api/exam/specialty'
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
|
import { FormRules } from 'element-plus'
|
||||||
|
|
||||||
|
defineOptions({ name: 'SpecialtyForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
title: '',
|
||||||
|
parentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
sort: undefined,
|
||||||
|
leaderUserId: undefined,
|
||||||
|
phone: undefined,
|
||||||
|
email: undefined,
|
||||||
|
status: CommonStatusEnum.ENABLE
|
||||||
|
})
|
||||||
|
const formRules = reactive<FormRules>({
|
||||||
|
parentId: [{ required: true, message: '上级专业不能为空', trigger: 'blur' }],
|
||||||
|
name: [{ required: true, message: '专业名称不能为空', trigger: 'blur' }],
|
||||||
|
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
const specialtyTree = ref() // 树形结构
|
||||||
|
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await SpecialtyApi.getSpecialty(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获得用户列表
|
||||||
|
userList.value = await UserApi.getSimpleUserList()
|
||||||
|
// 获得专业树
|
||||||
|
await getTree()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!formRef) return
|
||||||
|
const valid = await formRef.value.validate()
|
||||||
|
if (!valid) return
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await SpecialtyApi.createSpecialty(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await SpecialtyApi.updateSpecialty(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
title: '',
|
||||||
|
parentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
sort: undefined,
|
||||||
|
leaderUserId: undefined,
|
||||||
|
phone: undefined,
|
||||||
|
email: undefined,
|
||||||
|
status: CommonStatusEnum.ENABLE
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获得专业-课程-题型树 */
|
||||||
|
const getTree = async () => {
|
||||||
|
specialtyTree.value = []
|
||||||
|
const data = await SpecialtyApi.getSpecialtyPage()
|
||||||
|
let dept: Tree = { id: 0, name: '专业-课程-题型', children: [] }
|
||||||
|
dept.children = handleTree(data)
|
||||||
|
specialtyTree.value.push(dept)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
260
src/views/system/set/param/index.vue
Normal file
260
src/views/system/set/param/index.vue
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
|
||||||
|
<ContentWrap>
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="专业名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入专业名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="专业状态" prop="status">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.status"
|
||||||
|
placeholder="请选择专业状态"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<!-- <el-button type="primary" plain @click="openForm('create')">
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button> -->
|
||||||
|
<el-button type="danger" plain @click="toggleExpandAll">
|
||||||
|
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
row-key="id"
|
||||||
|
:default-expand-all="isExpandAll"
|
||||||
|
v-if="refreshTable"
|
||||||
|
>
|
||||||
|
<el-table-column prop="name" label="专业名称" />
|
||||||
|
<el-table-column prop="roles" label="软件环境" />
|
||||||
|
<el-table-column prop="status" label="状态">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
width="180"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<!-- <el-button link type="primary" @click="openForm('update', scope.row.id)">
|
||||||
|
修改
|
||||||
|
</el-button>
|
||||||
|
<el-button link type="danger" @click="handleDelete(scope.row.id)"> 删除 </el-button> -->
|
||||||
|
<!-- 第三级才显示规则按钮 -->
|
||||||
|
<el-button
|
||||||
|
v-if="scope.row.level === 3"
|
||||||
|
link
|
||||||
|
type="warning"
|
||||||
|
@click="handleRule(scope.row)"
|
||||||
|
>
|
||||||
|
软件环境
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</ContentWrap>
|
||||||
|
<el-dialog v-model="ruleDialogVisible" title="软件环境" width="600px">
|
||||||
|
<!-- 弹窗内容 -->
|
||||||
|
<el-form :model="formData" label-width="100px">
|
||||||
|
<el-form-item label="软件环境" prop="roles">
|
||||||
|
<!-- 当专业名称为“编程题”时显示下拉框,否则显示输入框 -->
|
||||||
|
<template v-if="formData.name === '编程题'">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.roles"
|
||||||
|
placeholder="请选择软件环境"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in softwareOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-input
|
||||||
|
v-model="formData.roles"
|
||||||
|
style="width: 240px"
|
||||||
|
placeholder="输入对应需要软件名称"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 弹窗底部按钮 -->
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="ruleDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleRuleSave">保存</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<SpecialtyForm ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import { handleTree } from '@/utils/tree'
|
||||||
|
import * as SpecialtyApi from '@/api/exam/specialty'
|
||||||
|
import SpecialtyForm from './SpecialtyForm.vue'
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
|
||||||
|
defineOptions({ name: 'SystemDept' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref() // 列表的数据
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
name: undefined,
|
||||||
|
status: undefined
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const isExpandAll = ref(true) // 是否展开,默认全部展开
|
||||||
|
const refreshTable = ref(true) // 重新渲染表格状态
|
||||||
|
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
|
const ruleDialogVisible = ref(false) // 控制弹窗显示
|
||||||
|
const currentRuleRow = ref<any>(null) // 当前点击的那一行数据
|
||||||
|
const formData = ref({
|
||||||
|
roles: '',
|
||||||
|
id: '',
|
||||||
|
name:''
|
||||||
|
})
|
||||||
|
const handleRule = async (row: any) => {
|
||||||
|
currentRuleRow.value = row.id
|
||||||
|
const res = await SpecialtyApi.getSpecialtyRole(currentRuleRow.value)
|
||||||
|
console.log(res)
|
||||||
|
formData.value.roles = res
|
||||||
|
formData.value.name = row.name
|
||||||
|
ruleDialogVisible.value = true
|
||||||
|
}
|
||||||
|
// 本地自定义下拉数据
|
||||||
|
const softwareOptions = ref([
|
||||||
|
{ label: 'Visual C++', value: 'Visual C++' },
|
||||||
|
{ label: 'VC++ 2010 Express', value: 'VC++ 2010 Express' },
|
||||||
|
{ label: 'CFree', value: 'CFree' },
|
||||||
|
{ label: 'Dev-c', value: 'Dev-c' },
|
||||||
|
{ label: 'Code::Blocks', value: 'Code::Blocks' },
|
||||||
|
{ label: 'VS2008', value: 'VS2008' },
|
||||||
|
{ label: 'VS2010', value: 'VS2010' },
|
||||||
|
{ label: 'VS2019', value: 'VS2019' },
|
||||||
|
])
|
||||||
|
const handleRuleSave = async () => {
|
||||||
|
formData.value.id = currentRuleRow.value
|
||||||
|
const data = formData.value
|
||||||
|
const res = await SpecialtyApi.setSpecialtyRole(data)
|
||||||
|
message.success(t(res))
|
||||||
|
handleQuery()
|
||||||
|
ruleDialogVisible.value = false
|
||||||
|
}
|
||||||
|
/** 查询部门列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await SpecialtyApi.getSpecialtyPage(queryParams)
|
||||||
|
console.log(data)
|
||||||
|
const treeData = handleTree(data)
|
||||||
|
list.value = addLevelToTree(treeData)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 展开/折叠操作 */
|
||||||
|
const toggleExpandAll = () => {
|
||||||
|
refreshTable.value = false
|
||||||
|
isExpandAll.value = !isExpandAll.value
|
||||||
|
nextTick(() => {
|
||||||
|
refreshTable.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await SpecialtyApi.deleteSpecialty(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
// 递归添加 level 字段
|
||||||
|
const addLevelToTree = (nodes, level = 1) => {
|
||||||
|
return nodes.map((node) => {
|
||||||
|
const newNode = { ...node, level }
|
||||||
|
if (newNode.children && newNode.children.length > 0) {
|
||||||
|
newNode.children = addLevelToTree(newNode.children, level + 1)
|
||||||
|
}
|
||||||
|
return newNode
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(async () => {
|
||||||
|
await getList()
|
||||||
|
// 获取用户列表
|
||||||
|
userList.value = await UserApi.getSimpleUserList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -33,32 +33,34 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<Pagination
|
<Pagination
|
||||||
:total="total"
|
:total="total"
|
||||||
v-model:page="queryParams.pageNo"
|
v-model:page="queryParams.pageNo"
|
||||||
v-model:limit="queryParams.pageSize"
|
v-model:limit="queryParams.pageSize"
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 新增/修改弹窗 -->
|
<!-- 新增/修改弹窗 -->
|
||||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
|
||||||
<el-form ref="formRef" :model="form" label-width="80px">
|
<el-form ref="formRef" :model="form" label-width="80px">
|
||||||
<el-form-item label="名称" prop="name" required>
|
<el-form-item label="名称" prop="name" required>
|
||||||
<el-input v-model="form.name" placeholder="请输入名称" />
|
<el-input v-model="form.name" placeholder="请输入名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
</ContentWrap> </template> <script lang="ts" setup> import { ref, reactive } from 'vue'
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup> import { ref, reactive } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import * as WhiteApi from '@/api/system/whiteList'
|
import * as WhiteApi from '@/api/system/whiteList'
|
||||||
// 你可以把 API 封装在这个文件里 // 数据
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const list = ref([])
|
const list = ref([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const queryParams = reactive({ pageNo: 1, pageSize: 10, name: '' })
|
const queryParams = reactive({ pageNo: 1, pageSize: 10, name: '' })
|
||||||
@@ -68,35 +70,36 @@ const dialogTitle = ref('')
|
|||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const form = reactive({ id: '', name: '', path: '', remark: '' })
|
const form = reactive({ id: '', name: '', path: '', remark: '' })
|
||||||
// 获取列表
|
// 获取列表
|
||||||
const getList = async () => { loading.value = true
|
const getList = async () => { loading.value = true
|
||||||
const params = {
|
const params = {
|
||||||
...queryParams,
|
...queryParams,
|
||||||
|
|
||||||
}
|
}
|
||||||
try { const res = await WhiteApi.getAppWhiteListCenter(params)
|
try { const res = await WhiteApi.getAppWhiteListCenter(params)
|
||||||
list.value = res.list
|
list.value = res.list
|
||||||
total.value = res.total
|
total.value = res.total
|
||||||
|
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
loading.value = false
|
loading.value = false
|
||||||
} }
|
} }
|
||||||
// 重置
|
// 重置
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryParams.name = ''
|
queryParams.name = ''
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openForm = async (type: string, id?: string) => {
|
const openForm = async (type: string, id?: string) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
if (type === 'create') {
|
if (type === 'create') {
|
||||||
dialogTitle.value = '新增白名单'
|
dialogTitle.value = '新增白名单'
|
||||||
Object.assign(form, { id: '', name: '', path: '', remark: '' })
|
Object.assign(form, { id: '', name: '', path: '', remark: '' })
|
||||||
} else {
|
} else {
|
||||||
dialogTitle.value = '修改白名单'
|
dialogTitle.value = '修改白名单'
|
||||||
const data = await WhiteApi.getWhite(id)
|
const data = await WhiteApi.getWhite(id)
|
||||||
Object.assign(form, data) }
|
Object.assign(form, data) }
|
||||||
} // 提交
|
}
|
||||||
|
// 提交
|
||||||
const submitForm = async () => {
|
const submitForm = async () => {
|
||||||
if (!form.name) {
|
if (!form.name) {
|
||||||
ElMessage.warning('请输入名称')
|
ElMessage.warning('请输入名称')
|
||||||
@@ -105,21 +108,26 @@ const form = reactive({ id: '', name: '', path: '', remark: '' })
|
|||||||
if (form.id) {
|
if (form.id) {
|
||||||
await WhiteApi.updateAppWhite(form)
|
await WhiteApi.updateAppWhite(form)
|
||||||
ElMessage.success('修改成功')
|
ElMessage.success('修改成功')
|
||||||
} else {
|
}
|
||||||
await WhiteApi.addAppWhite(form)
|
else {
|
||||||
ElMessage.success('新增成功')
|
await WhiteApi.addAppWhite(form)
|
||||||
}
|
ElMessage.success('新增成功')
|
||||||
dialogVisible.value = false
|
}
|
||||||
getList()
|
dialogVisible.value = false
|
||||||
}
|
getList()
|
||||||
|
}
|
||||||
// 删除
|
// 删除
|
||||||
const handleDelete = async (id: string) => {
|
const handleDelete = async (id: string) => {
|
||||||
ElMessageBox.confirm('确认删除该白名单?', '提示', {
|
ElMessageBox.confirm('确认删除该白名单?', '提示', {
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(async () => {
|
})
|
||||||
|
.then(async () => {
|
||||||
await WhiteApi.delWhite(id)
|
await WhiteApi.delWhite(id)
|
||||||
ElMessage.success('删除成功')
|
ElMessage.success('删除成功')
|
||||||
getList() }) }
|
getList()
|
||||||
// 初始化
|
}
|
||||||
getList()
|
)
|
||||||
|
}
|
||||||
|
// 初始化
|
||||||
|
getList()
|
||||||
</script>
|
</script>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage(); // 消息弹窗
|
const message = useMessage(); // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -150,7 +150,7 @@ const handleOpen = (type, paperId) => {
|
|||||||
console.log(paperId+"paperIdpaperId")
|
console.log(paperId+"paperIdpaperId")
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res || {};
|
const { educationPaperSchemeList, examQuestionList } = res || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ const fetchpaperOptions = async () => {
|
|||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
resetFields();
|
resetFields();
|
||||||
form.taskId = props.taskId;
|
form.taskId = props.taskId;
|
||||||
|
fetchpaperOptions();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate?.();
|
formRef.value?.clearValidate?.();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="学生导入" width="400">
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:action="importUrl + '?updateSupport=' + updateSupport + '&taskId=' + props.taskId"
|
||||||
|
:auto-upload="false"
|
||||||
|
:disabled="formLoading"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="submitFormError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="submitFormSuccess"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" />
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-center">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="updateSupport" />
|
||||||
|
是否更新已经存在的学生数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入 xls、xlsx 格式文件。</span>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="font-size: 12px; vertical-align: baseline"
|
||||||
|
type="primary"
|
||||||
|
@click="importTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
defineOptions({ name: 'SystemUserImportForm' })
|
||||||
|
const props = defineProps({
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const uploadRef = ref()
|
||||||
|
const importUrl =
|
||||||
|
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/system/user/importTaskStu'
|
||||||
|
const uploadHeaders = ref() // 上传 Header 头
|
||||||
|
const fileList = ref([]) // 文件列表
|
||||||
|
const updateSupport = ref(0) // 是否更新已经存在的用户数据
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = () => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
updateSupport.value = 0
|
||||||
|
fileList.value = []
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const submitForm = async () => {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
message.error('请上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
uploadHeaders.value = {
|
||||||
|
Authorization: 'Bearer ' + getAccessToken(),
|
||||||
|
'tenant-id': getTenantId()
|
||||||
|
}
|
||||||
|
formLoading.value = true
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件上传成功 */
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
const submitFormSuccess = (response: any) => {
|
||||||
|
if (response.code !== 0) {
|
||||||
|
message.error(response.msg)
|
||||||
|
formLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 拼接提示语
|
||||||
|
const data = response.data
|
||||||
|
let text = '上传成功数量:' + data.createUsernames.length + ';'
|
||||||
|
for (let username of data.createUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新成功数量:' + data.updateUsernames.length + ';'
|
||||||
|
for (const username of data.updateUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新失败数量:' + Object.keys(data.failureUsernames).length + ';'
|
||||||
|
for (const username in data.failureUsernames) {
|
||||||
|
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
|
||||||
|
}
|
||||||
|
message.alert(text)
|
||||||
|
formLoading.value = false
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emits('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 上传错误提示 */
|
||||||
|
const submitFormError = (): void => {
|
||||||
|
message.error('上传失败,请您重新上传!')
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = async (): Promise<void> => {
|
||||||
|
// 重置上传状态和文件
|
||||||
|
formLoading.value = false
|
||||||
|
await nextTick()
|
||||||
|
uploadRef.value?.clearFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件数超出提示 */
|
||||||
|
const handleExceed = (): void => {
|
||||||
|
message.error('最多只能上传一个文件!')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 下载模板操作 */
|
||||||
|
const importTemplate = async () => {
|
||||||
|
const res = await UserApi.importUserTaskStu()
|
||||||
|
download.excel(res, '任务学生导入模版.xls')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -205,14 +205,13 @@ const removeBatch = async () => {
|
|||||||
|
|
||||||
const res=await PersonApi.removeSessionStu(data);
|
const res=await PersonApi.removeSessionStu(data);
|
||||||
if(res =='删除成功'){
|
if(res =='删除成功'){
|
||||||
message.success(t('common.delSuccess'))
|
message.success('删除成功')
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
message.error(res)
|
message.error(res)
|
||||||
}
|
}
|
||||||
await getPersonList(); // 删除后刷新右侧列表
|
await getPersonList(); // 删除后刷新右侧列表
|
||||||
emit('done');
|
emit('done');
|
||||||
ElMessage.success('删除成功');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
|
|||||||
@@ -8,10 +8,25 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
|
<el-form-item label="场次" prop="batch">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.batch"
|
||||||
|
placeholder="请输入场次"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" /> 导入
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -83,6 +98,7 @@
|
|||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
||||||
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
||||||
|
<StudentImportForm ref="importFormRef" @success="getList" :task-id="props.taskId"/>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -90,6 +106,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|||||||
import * as SmsPersonlApi from '@/api/system/person';
|
import * as SmsPersonlApi from '@/api/system/person';
|
||||||
import PersonEdit from './components/person-edit.vue';
|
import PersonEdit from './components/person-edit.vue';
|
||||||
import PersonSearch from './components/person-serach.vue'
|
import PersonSearch from './components/person-serach.vue'
|
||||||
|
import StudentImportForm from './components/StudentImportForm.vue'
|
||||||
import * as SmsChannelApi from '@/api/system/session';
|
import * as SmsChannelApi from '@/api/system/session';
|
||||||
import { fa } from 'element-plus/es/locale';
|
import { fa } from 'element-plus/es/locale';
|
||||||
|
|
||||||
@@ -133,7 +150,7 @@ const queryFormRef = ref() // 搜索的表单
|
|||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
signature: undefined,
|
batch: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
createTime: [],
|
createTime: [],
|
||||||
taskId: props.taskId
|
taskId: props.taskId
|
||||||
@@ -220,6 +237,10 @@ if(res =='删除成功'){
|
|||||||
await getList()
|
await getList()
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
const importFormRef = ref()
|
||||||
|
const handleImport = () => {
|
||||||
|
importFormRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const openEdit = (type: string, row?: object) => {
|
const openEdit = (type: string, row?: object) => {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
|
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage(); // 消息弹窗
|
const message = useMessage(); // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -150,7 +150,7 @@ const handleOpen = (type, paperId) => {
|
|||||||
console.log(paperId+"paperIdpaperId")
|
console.log(paperId+"paperIdpaperId")
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res || {};
|
const { educationPaperSchemeList, examQuestionList } = res || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ const fetchpaperOptions = async () => {
|
|||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
resetFields();
|
resetFields();
|
||||||
form.taskId = props.taskId;
|
form.taskId = props.taskId;
|
||||||
|
fetchpaperOptions();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate?.();
|
formRef.value?.clearValidate?.();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
|
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage(); // 消息弹窗
|
const message = useMessage(); // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -150,7 +150,7 @@ const handleOpen = (type, paperId) => {
|
|||||||
console.log(paperId+"paperIdpaperId")
|
console.log(paperId+"paperIdpaperId")
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res || {};
|
const { educationPaperSchemeList, examQuestionList } = res || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ const fetchpaperOptions = async () => {
|
|||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
resetFields();
|
resetFields();
|
||||||
form.taskId = props.taskId;
|
form.taskId = props.taskId;
|
||||||
|
fetchpaperOptions();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate?.();
|
formRef.value?.clearValidate?.();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="学生导入" width="400">
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:action="importUrl + '?updateSupport=' + updateSupport + '&taskId=' + props.taskId"
|
||||||
|
:auto-upload="false"
|
||||||
|
:disabled="formLoading"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="submitFormError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="submitFormSuccess"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" />
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-center">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="updateSupport" />
|
||||||
|
是否更新已经存在的学生数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入 xls、xlsx 格式文件。</span>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="font-size: 12px; vertical-align: baseline"
|
||||||
|
type="primary"
|
||||||
|
@click="importTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
defineOptions({ name: 'SystemUserImportForm' })
|
||||||
|
const props = defineProps({
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const uploadRef = ref()
|
||||||
|
const importUrl =
|
||||||
|
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/system/user/importTaskStu'
|
||||||
|
const uploadHeaders = ref() // 上传 Header 头
|
||||||
|
const fileList = ref([]) // 文件列表
|
||||||
|
const updateSupport = ref(0) // 是否更新已经存在的用户数据
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = () => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
updateSupport.value = 0
|
||||||
|
fileList.value = []
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const submitForm = async () => {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
message.error('请上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
uploadHeaders.value = {
|
||||||
|
Authorization: 'Bearer ' + getAccessToken(),
|
||||||
|
'tenant-id': getTenantId()
|
||||||
|
}
|
||||||
|
formLoading.value = true
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件上传成功 */
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
const submitFormSuccess = (response: any) => {
|
||||||
|
if (response.code !== 0) {
|
||||||
|
message.error(response.msg)
|
||||||
|
formLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 拼接提示语
|
||||||
|
const data = response.data
|
||||||
|
let text = '上传成功数量:' + data.createUsernames.length + ';'
|
||||||
|
for (let username of data.createUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新成功数量:' + data.updateUsernames.length + ';'
|
||||||
|
for (const username of data.updateUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新失败数量:' + Object.keys(data.failureUsernames).length + ';'
|
||||||
|
for (const username in data.failureUsernames) {
|
||||||
|
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
|
||||||
|
}
|
||||||
|
message.alert(text)
|
||||||
|
formLoading.value = false
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emits('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 上传错误提示 */
|
||||||
|
const submitFormError = (): void => {
|
||||||
|
message.error('上传失败,请您重新上传!')
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = async (): Promise<void> => {
|
||||||
|
// 重置上传状态和文件
|
||||||
|
formLoading.value = false
|
||||||
|
await nextTick()
|
||||||
|
uploadRef.value?.clearFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件数超出提示 */
|
||||||
|
const handleExceed = (): void => {
|
||||||
|
message.error('最多只能上传一个文件!')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 下载模板操作 */
|
||||||
|
const importTemplate = async () => {
|
||||||
|
const res = await UserApi.importUserTaskStu()
|
||||||
|
download.excel(res, '任务学生导入模版.xls')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -205,14 +205,13 @@ const removeBatch = async () => {
|
|||||||
|
|
||||||
const res=await PersonApi.removeSessionStu(data);
|
const res=await PersonApi.removeSessionStu(data);
|
||||||
if(res =='删除成功'){
|
if(res =='删除成功'){
|
||||||
message.success(t('common.delSuccess'))
|
message.success('删除成功');
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
message.error(res)
|
message.error(res)
|
||||||
}
|
}
|
||||||
await getPersonList(); // 删除后刷新右侧列表
|
await getPersonList(); // 删除后刷新右侧列表
|
||||||
emit('done');
|
emit('done');
|
||||||
ElMessage.success('删除成功');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
|
|||||||
@@ -8,10 +8,25 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
|
<el-form-item label="场次" prop="batch">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.batch"
|
||||||
|
placeholder="请输入场次"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" /> 导入
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -83,6 +98,7 @@
|
|||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
||||||
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
||||||
|
<StudentImportForm ref="importFormRef" @success="getList" :task-id="props.taskId"/>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -91,6 +107,7 @@ import * as SmsPersonlApi from '@/api/system/person';
|
|||||||
import PersonEdit from './components/person-edit.vue';
|
import PersonEdit from './components/person-edit.vue';
|
||||||
import PersonSearch from './components/person-serach.vue'
|
import PersonSearch from './components/person-serach.vue'
|
||||||
import * as SmsChannelApi from '@/api/system/session';
|
import * as SmsChannelApi from '@/api/system/session';
|
||||||
|
import StudentImportForm from './components/StudentImportForm.vue'
|
||||||
import { fa } from 'element-plus/es/locale';
|
import { fa } from 'element-plus/es/locale';
|
||||||
|
|
||||||
defineOptions({ name: 'SystemSmsChannel' })
|
defineOptions({ name: 'SystemSmsChannel' })
|
||||||
@@ -133,7 +150,7 @@ const queryFormRef = ref() // 搜索的表单
|
|||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
signature: undefined,
|
batch: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
createTime: [],
|
createTime: [],
|
||||||
taskId: props.taskId
|
taskId: props.taskId
|
||||||
@@ -221,6 +238,10 @@ if(res =='删除成功'){
|
|||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const importFormRef = ref()
|
||||||
|
const handleImport = () => {
|
||||||
|
importFormRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
const openEdit = (type: string, row?: object) => {
|
const openEdit = (type: string, row?: object) => {
|
||||||
showEdit.value = true
|
showEdit.value = true
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
|
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage(); // 消息弹窗
|
const message = useMessage(); // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -150,7 +150,7 @@ const handleOpen = (type, paperId) => {
|
|||||||
console.log(paperId+"paperIdpaperId")
|
console.log(paperId+"paperIdpaperId")
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res || {};
|
const { educationPaperSchemeList, examQuestionList } = res || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ const fetchpaperOptions = async () => {
|
|||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
resetFields();
|
resetFields();
|
||||||
form.taskId = props.taskId;
|
form.taskId = props.taskId;
|
||||||
|
fetchpaperOptions();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate?.();
|
formRef.value?.clearValidate?.();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="学生导入" width="400">
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:action="importUrl + '?updateSupport=' + updateSupport + '&taskId=' + props.taskId"
|
||||||
|
:auto-upload="false"
|
||||||
|
:disabled="formLoading"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="submitFormError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="submitFormSuccess"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" />
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-center">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="updateSupport" />
|
||||||
|
是否更新已经存在的学生数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入 xls、xlsx 格式文件。</span>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="font-size: 12px; vertical-align: baseline"
|
||||||
|
type="primary"
|
||||||
|
@click="importTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
defineOptions({ name: 'SystemUserImportForm' })
|
||||||
|
const props = defineProps({
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const uploadRef = ref()
|
||||||
|
const importUrl =
|
||||||
|
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/system/user/importTaskStu'
|
||||||
|
const uploadHeaders = ref() // 上传 Header 头
|
||||||
|
const fileList = ref([]) // 文件列表
|
||||||
|
const updateSupport = ref(0) // 是否更新已经存在的用户数据
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = () => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
updateSupport.value = 0
|
||||||
|
fileList.value = []
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const submitForm = async () => {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
message.error('请上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
uploadHeaders.value = {
|
||||||
|
Authorization: 'Bearer ' + getAccessToken(),
|
||||||
|
'tenant-id': getTenantId()
|
||||||
|
}
|
||||||
|
formLoading.value = true
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件上传成功 */
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
const submitFormSuccess = (response: any) => {
|
||||||
|
if (response.code !== 0) {
|
||||||
|
message.error(response.msg)
|
||||||
|
formLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 拼接提示语
|
||||||
|
const data = response.data
|
||||||
|
let text = '上传成功数量:' + data.createUsernames.length + ';'
|
||||||
|
for (let username of data.createUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新成功数量:' + data.updateUsernames.length + ';'
|
||||||
|
for (const username of data.updateUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新失败数量:' + Object.keys(data.failureUsernames).length + ';'
|
||||||
|
for (const username in data.failureUsernames) {
|
||||||
|
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
|
||||||
|
}
|
||||||
|
message.alert(text)
|
||||||
|
formLoading.value = false
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emits('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 上传错误提示 */
|
||||||
|
const submitFormError = (): void => {
|
||||||
|
message.error('上传失败,请您重新上传!')
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = async (): Promise<void> => {
|
||||||
|
// 重置上传状态和文件
|
||||||
|
formLoading.value = false
|
||||||
|
await nextTick()
|
||||||
|
uploadRef.value?.clearFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件数超出提示 */
|
||||||
|
const handleExceed = (): void => {
|
||||||
|
message.error('最多只能上传一个文件!')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 下载模板操作 */
|
||||||
|
const importTemplate = async () => {
|
||||||
|
const res = await UserApi.importUserTaskStu()
|
||||||
|
download.excel(res, '任务学生导入模版.xls')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -205,14 +205,13 @@ const removeBatch = async () => {
|
|||||||
|
|
||||||
const res=await PersonApi.removeSessionStu(data);
|
const res=await PersonApi.removeSessionStu(data);
|
||||||
if(res =='删除成功'){
|
if(res =='删除成功'){
|
||||||
message.success(t('common.delSuccess'))
|
message.success('删除成功');
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
message.error(res)
|
message.error(res)
|
||||||
}
|
}
|
||||||
await getPersonList(); // 删除后刷新右侧列表
|
await getPersonList(); // 删除后刷新右侧列表
|
||||||
emit('done');
|
emit('done');
|
||||||
ElMessage.success('删除成功');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
|
|||||||
@@ -8,10 +8,25 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
|
<el-form-item label="场次" prop="batch">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.batch"
|
||||||
|
placeholder="请输入场次"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" /> 导入
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -83,6 +98,7 @@
|
|||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
||||||
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
||||||
|
<StudentImportForm ref="importFormRef" @success="getList" :task-id="props.taskId"/>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -90,6 +106,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|||||||
import * as SmsPersonlApi from '@/api/system/person';
|
import * as SmsPersonlApi from '@/api/system/person';
|
||||||
import PersonEdit from './components/person-edit.vue';
|
import PersonEdit from './components/person-edit.vue';
|
||||||
import PersonSearch from './components/person-serach.vue'
|
import PersonSearch from './components/person-serach.vue'
|
||||||
|
import StudentImportForm from './components/StudentImportForm.vue'
|
||||||
import * as SmsChannelApi from '@/api/system/session';
|
import * as SmsChannelApi from '@/api/system/session';
|
||||||
import { fa } from 'element-plus/es/locale';
|
import { fa } from 'element-plus/es/locale';
|
||||||
|
|
||||||
@@ -133,7 +150,7 @@ const queryFormRef = ref() // 搜索的表单
|
|||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
signature: undefined,
|
batch: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
createTime: [],
|
createTime: [],
|
||||||
taskId: props.taskId
|
taskId: props.taskId
|
||||||
@@ -220,6 +237,10 @@ if(res =='删除成功'){
|
|||||||
await getList()
|
await getList()
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
const importFormRef = ref()
|
||||||
|
const handleImport = () => {
|
||||||
|
importFormRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const openEdit = (type: string, row?: object) => {
|
const openEdit = (type: string, row?: object) => {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
|
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
const { educationPaperSchemeList, examQuestionList } = res.data || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage(); // 消息弹窗
|
const message = useMessage(); // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -150,7 +150,7 @@ const handleOpen = (type, paperId) => {
|
|||||||
console.log(paperId+"paperIdpaperId")
|
console.log(paperId+"paperIdpaperId")
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res || {};
|
const { educationPaperSchemeList, examQuestionList } = res || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ const fetchpaperOptions = async () => {
|
|||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
resetFields();
|
resetFields();
|
||||||
form.taskId = props.taskId;
|
form.taskId = props.taskId;
|
||||||
|
fetchpaperOptions();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate?.();
|
formRef.value?.clearValidate?.();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="学生导入" width="400">
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:action="importUrl + '?updateSupport=' + updateSupport + '&taskId=' + props.taskId"
|
||||||
|
:auto-upload="false"
|
||||||
|
:disabled="formLoading"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="submitFormError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="submitFormSuccess"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" />
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-center">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="updateSupport" />
|
||||||
|
是否更新已经存在的学生数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入 xls、xlsx 格式文件。</span>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="font-size: 12px; vertical-align: baseline"
|
||||||
|
type="primary"
|
||||||
|
@click="importTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
defineOptions({ name: 'SystemUserImportForm' })
|
||||||
|
const props = defineProps({
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const uploadRef = ref()
|
||||||
|
const importUrl =
|
||||||
|
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/system/user/importTaskStu'
|
||||||
|
const uploadHeaders = ref() // 上传 Header 头
|
||||||
|
const fileList = ref([]) // 文件列表
|
||||||
|
const updateSupport = ref(0) // 是否更新已经存在的用户数据
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = () => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
updateSupport.value = 0
|
||||||
|
fileList.value = []
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const submitForm = async () => {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
message.error('请上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
uploadHeaders.value = {
|
||||||
|
Authorization: 'Bearer ' + getAccessToken(),
|
||||||
|
'tenant-id': getTenantId()
|
||||||
|
}
|
||||||
|
formLoading.value = true
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件上传成功 */
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
const submitFormSuccess = (response: any) => {
|
||||||
|
if (response.code !== 0) {
|
||||||
|
message.error(response.msg)
|
||||||
|
formLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 拼接提示语
|
||||||
|
const data = response.data
|
||||||
|
let text = '上传成功数量:' + data.createUsernames.length + ';'
|
||||||
|
for (let username of data.createUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新成功数量:' + data.updateUsernames.length + ';'
|
||||||
|
for (const username of data.updateUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新失败数量:' + Object.keys(data.failureUsernames).length + ';'
|
||||||
|
for (const username in data.failureUsernames) {
|
||||||
|
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
|
||||||
|
}
|
||||||
|
message.alert(text)
|
||||||
|
formLoading.value = false
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emits('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 上传错误提示 */
|
||||||
|
const submitFormError = (): void => {
|
||||||
|
message.error('上传失败,请您重新上传!')
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = async (): Promise<void> => {
|
||||||
|
// 重置上传状态和文件
|
||||||
|
formLoading.value = false
|
||||||
|
await nextTick()
|
||||||
|
uploadRef.value?.clearFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件数超出提示 */
|
||||||
|
const handleExceed = (): void => {
|
||||||
|
message.error('最多只能上传一个文件!')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 下载模板操作 */
|
||||||
|
const importTemplate = async () => {
|
||||||
|
const res = await UserApi.importUserTaskStu()
|
||||||
|
download.excel(res, '任务学生导入模版.xls')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -205,14 +205,12 @@ const removeBatch = async () => {
|
|||||||
|
|
||||||
const res=await PersonApi.removeSessionStu(data);
|
const res=await PersonApi.removeSessionStu(data);
|
||||||
if(res =='删除成功'){
|
if(res =='删除成功'){
|
||||||
message.success(t('common.delSuccess'))
|
message.success('删除成功');
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
message.error(res)
|
message.error(res)
|
||||||
}
|
}
|
||||||
await getPersonList(); // 删除后刷新右侧列表
|
await getPersonList(); // 删除后刷新右侧列表
|
||||||
emit('done');
|
emit('done');
|
||||||
ElMessage.success('删除成功');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
|
|||||||
@@ -8,10 +8,25 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
|
<el-form-item label="场次" prop="batch">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.batch"
|
||||||
|
placeholder="请输入场次"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" /> 导入
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -83,6 +98,7 @@
|
|||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
||||||
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
||||||
|
<StudentImportForm ref="importFormRef" @success="getList" :task-id="props.taskId"/>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -90,6 +106,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|||||||
import * as SmsPersonlApi from '@/api/system/person';
|
import * as SmsPersonlApi from '@/api/system/person';
|
||||||
import PersonEdit from './components/person-edit.vue';
|
import PersonEdit from './components/person-edit.vue';
|
||||||
import PersonSearch from './components/person-serach.vue'
|
import PersonSearch from './components/person-serach.vue'
|
||||||
|
import StudentImportForm from './components/StudentImportForm.vue'
|
||||||
import * as SmsChannelApi from '@/api/system/session';
|
import * as SmsChannelApi from '@/api/system/session';
|
||||||
import { fa } from 'element-plus/es/locale';
|
import { fa } from 'element-plus/es/locale';
|
||||||
|
|
||||||
@@ -133,7 +150,7 @@ const queryFormRef = ref() // 搜索的表单
|
|||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
signature: undefined,
|
batch: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
createTime: [],
|
createTime: [],
|
||||||
taskId: props.taskId
|
taskId: props.taskId
|
||||||
@@ -220,7 +237,10 @@ if(res =='删除成功'){
|
|||||||
await getList()
|
await getList()
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
const importFormRef = ref()
|
||||||
|
const handleImport = () => {
|
||||||
|
importFormRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
const openEdit = (type: string, row?: object) => {
|
const openEdit = (type: string, row?: object) => {
|
||||||
showEdit.value = true
|
showEdit.value = true
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage(); // 消息弹窗
|
const message = useMessage(); // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -150,7 +150,7 @@ const handleOpen = (type, paperId) => {
|
|||||||
console.log(paperId+"paperIdpaperId")
|
console.log(paperId+"paperIdpaperId")
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res || {};
|
const { educationPaperSchemeList, examQuestionList } = res || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ const fetchpaperOptions = async () => {
|
|||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
resetFields();
|
resetFields();
|
||||||
form.taskId = props.taskId;
|
form.taskId = props.taskId;
|
||||||
|
fetchpaperOptions();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate?.();
|
formRef.value?.clearValidate?.();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="学生导入" width="400">
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:action="importUrl + '?updateSupport=' + updateSupport + '&taskId=' + props.taskId"
|
||||||
|
:auto-upload="false"
|
||||||
|
:disabled="formLoading"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="submitFormError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="submitFormSuccess"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" />
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-center">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="updateSupport" />
|
||||||
|
是否更新已经存在的学生数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入 xls、xlsx 格式文件。</span>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="font-size: 12px; vertical-align: baseline"
|
||||||
|
type="primary"
|
||||||
|
@click="importTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
defineOptions({ name: 'SystemUserImportForm' })
|
||||||
|
const props = defineProps({
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const uploadRef = ref()
|
||||||
|
const importUrl =
|
||||||
|
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/system/user/importTaskStu'
|
||||||
|
const uploadHeaders = ref() // 上传 Header 头
|
||||||
|
const fileList = ref([]) // 文件列表
|
||||||
|
const updateSupport = ref(0) // 是否更新已经存在的用户数据
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = () => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
updateSupport.value = 0
|
||||||
|
fileList.value = []
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const submitForm = async () => {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
message.error('请上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
uploadHeaders.value = {
|
||||||
|
Authorization: 'Bearer ' + getAccessToken(),
|
||||||
|
'tenant-id': getTenantId()
|
||||||
|
}
|
||||||
|
formLoading.value = true
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件上传成功 */
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
const submitFormSuccess = (response: any) => {
|
||||||
|
if (response.code !== 0) {
|
||||||
|
message.error(response.msg)
|
||||||
|
formLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 拼接提示语
|
||||||
|
const data = response.data
|
||||||
|
let text = '上传成功数量:' + data.createUsernames.length + ';'
|
||||||
|
for (let username of data.createUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新成功数量:' + data.updateUsernames.length + ';'
|
||||||
|
for (const username of data.updateUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新失败数量:' + Object.keys(data.failureUsernames).length + ';'
|
||||||
|
for (const username in data.failureUsernames) {
|
||||||
|
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
|
||||||
|
}
|
||||||
|
message.alert(text)
|
||||||
|
formLoading.value = false
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emits('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 上传错误提示 */
|
||||||
|
const submitFormError = (): void => {
|
||||||
|
message.error('上传失败,请您重新上传!')
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = async (): Promise<void> => {
|
||||||
|
// 重置上传状态和文件
|
||||||
|
formLoading.value = false
|
||||||
|
await nextTick()
|
||||||
|
uploadRef.value?.clearFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件数超出提示 */
|
||||||
|
const handleExceed = (): void => {
|
||||||
|
message.error('最多只能上传一个文件!')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 下载模板操作 */
|
||||||
|
const importTemplate = async () => {
|
||||||
|
const res = await UserApi.importUserTaskStu()
|
||||||
|
download.excel(res, '任务学生导入模版.xls')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -205,14 +205,13 @@ const removeBatch = async () => {
|
|||||||
|
|
||||||
const res=await PersonApi.removeSessionStu(data);
|
const res=await PersonApi.removeSessionStu(data);
|
||||||
if(res =='删除成功'){
|
if(res =='删除成功'){
|
||||||
message.success(t('common.delSuccess'))
|
message.success('删除成功');
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
message.error(res)
|
message.error(res)
|
||||||
}
|
}
|
||||||
await getPersonList(); // 删除后刷新右侧列表
|
await getPersonList(); // 删除后刷新右侧列表
|
||||||
emit('done');
|
emit('done');
|
||||||
ElMessage.success('删除成功');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
|
|||||||
@@ -8,10 +8,25 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
|
<el-form-item label="场次" prop="batch">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.batch"
|
||||||
|
placeholder="请输入场次"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" /> 导入
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -83,6 +98,7 @@
|
|||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
||||||
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
||||||
|
<StudentImportForm ref="importFormRef" @success="getList" :task-id="props.taskId"/>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -90,6 +106,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|||||||
import * as SmsPersonlApi from '@/api/system/person';
|
import * as SmsPersonlApi from '@/api/system/person';
|
||||||
import PersonEdit from './components/person-edit.vue';
|
import PersonEdit from './components/person-edit.vue';
|
||||||
import PersonSearch from './components/person-serach.vue'
|
import PersonSearch from './components/person-serach.vue'
|
||||||
|
import StudentImportForm from './components/StudentImportForm.vue'
|
||||||
import * as SmsChannelApi from '@/api/system/session';
|
import * as SmsChannelApi from '@/api/system/session';
|
||||||
import { fa } from 'element-plus/es/locale';
|
import { fa } from 'element-plus/es/locale';
|
||||||
|
|
||||||
@@ -133,7 +150,7 @@ const queryFormRef = ref() // 搜索的表单
|
|||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
signature: undefined,
|
batch: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
createTime: [],
|
createTime: [],
|
||||||
taskId: props.taskId
|
taskId: props.taskId
|
||||||
@@ -237,6 +254,10 @@ const openSearch = (type: string, row?: object) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const importFormRef = ref()
|
||||||
|
const handleImport = () => {
|
||||||
|
importFormRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, nextTick, computed } from 'vue';
|
import { ref, reactive, nextTick, computed } from 'vue';
|
||||||
import { useFormData } from '@/utils/use-form-data';
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
import { getPaperDetailByTaskId } from '@/api/system/paper';
|
import { getPaperDetailCenterByTaskId } from '@/api/system/paper';
|
||||||
const message = useMessage(); // 消息弹窗
|
const message = useMessage(); // 消息弹窗
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -150,7 +150,7 @@ const handleOpen = (type, paperId) => {
|
|||||||
console.log(paperId+"paperIdpaperId")
|
console.log(paperId+"paperIdpaperId")
|
||||||
if (props.paperId) {
|
if (props.paperId) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
getPaperDetailByTaskId(props.paperId)
|
getPaperDetailCenterByTaskId(props.paperId)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { educationPaperSchemeList, examQuestionList } = res || {};
|
const { educationPaperSchemeList, examQuestionList } = res || {};
|
||||||
if (Array.isArray(examQuestionList)) {
|
if (Array.isArray(examQuestionList)) {
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ const fetchpaperOptions = async () => {
|
|||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
resetFields();
|
resetFields();
|
||||||
form.taskId = props.taskId;
|
form.taskId = props.taskId;
|
||||||
|
fetchpaperOptions();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate?.();
|
formRef.value?.clearValidate?.();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="学生导入" width="400">
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="fileList"
|
||||||
|
:action="importUrl + '?updateSupport=' + updateSupport + '&taskId=' + props.taskId"
|
||||||
|
:auto-upload="false"
|
||||||
|
:disabled="formLoading"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="submitFormError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="submitFormSuccess"
|
||||||
|
accept=".xlsx, .xls"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" />
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-center">
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
<el-checkbox v-model="updateSupport" />
|
||||||
|
是否更新已经存在的学生数据
|
||||||
|
</div>
|
||||||
|
<span>仅允许导入 xls、xlsx 格式文件。</span>
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
style="font-size: 12px; vertical-align: baseline"
|
||||||
|
type="primary"
|
||||||
|
@click="importTemplate"
|
||||||
|
>
|
||||||
|
下载模板
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { getAccessToken, getTenantId } from '@/utils/auth'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
defineOptions({ name: 'SystemUserImportForm' })
|
||||||
|
const props = defineProps({
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const uploadRef = ref()
|
||||||
|
const importUrl =
|
||||||
|
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/system/user/importTaskStu'
|
||||||
|
const uploadHeaders = ref() // 上传 Header 头
|
||||||
|
const fileList = ref([]) // 文件列表
|
||||||
|
const updateSupport = ref(0) // 是否更新已经存在的用户数据
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = () => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
updateSupport.value = 0
|
||||||
|
fileList.value = []
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const submitForm = async () => {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
message.error('请上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
uploadHeaders.value = {
|
||||||
|
Authorization: 'Bearer ' + getAccessToken(),
|
||||||
|
'tenant-id': getTenantId()
|
||||||
|
}
|
||||||
|
formLoading.value = true
|
||||||
|
uploadRef.value!.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件上传成功 */
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
const submitFormSuccess = (response: any) => {
|
||||||
|
if (response.code !== 0) {
|
||||||
|
message.error(response.msg)
|
||||||
|
formLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 拼接提示语
|
||||||
|
const data = response.data
|
||||||
|
let text = '上传成功数量:' + data.createUsernames.length + ';'
|
||||||
|
for (let username of data.createUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新成功数量:' + data.updateUsernames.length + ';'
|
||||||
|
for (const username of data.updateUsernames) {
|
||||||
|
text += '< ' + username + ' >'
|
||||||
|
}
|
||||||
|
text += '更新失败数量:' + Object.keys(data.failureUsernames).length + ';'
|
||||||
|
for (const username in data.failureUsernames) {
|
||||||
|
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
|
||||||
|
}
|
||||||
|
message.alert(text)
|
||||||
|
formLoading.value = false
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emits('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 上传错误提示 */
|
||||||
|
const submitFormError = (): void => {
|
||||||
|
message.error('上传失败,请您重新上传!')
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = async (): Promise<void> => {
|
||||||
|
// 重置上传状态和文件
|
||||||
|
formLoading.value = false
|
||||||
|
await nextTick()
|
||||||
|
uploadRef.value?.clearFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 文件数超出提示 */
|
||||||
|
const handleExceed = (): void => {
|
||||||
|
message.error('最多只能上传一个文件!')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 下载模板操作 */
|
||||||
|
const importTemplate = async () => {
|
||||||
|
const res = await UserApi.importUserTaskStu()
|
||||||
|
download.excel(res, '任务学生导入模版.xls')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -205,14 +205,12 @@ const removeBatch = async () => {
|
|||||||
|
|
||||||
const res=await PersonApi.removeSessionStu(data);
|
const res=await PersonApi.removeSessionStu(data);
|
||||||
if(res =='删除成功'){
|
if(res =='删除成功'){
|
||||||
message.success(t('common.delSuccess'))
|
message.success('删除成功');
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
message.error(res)
|
message.error(res)
|
||||||
}
|
}
|
||||||
await getPersonList(); // 删除后刷新右侧列表
|
await getPersonList(); // 删除后刷新右侧列表
|
||||||
emit('done');
|
emit('done');
|
||||||
ElMessage.success('删除成功');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
|
|||||||
@@ -8,10 +8,26 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
|
<el-form-item label="场次" prop="batch">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.batch"
|
||||||
|
placeholder="请输入场次"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
@click="handleImport"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:upload" /> 导入
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -83,6 +99,7 @@
|
|||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
<person-edit v-model="showEdit" :task-Id="props.taskId" @done="reload" />
|
||||||
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
<PersonSearch :task-id="props.taskId" v-model="showPersonEdit" ref="stuAddRef" @done="reload" />
|
||||||
|
<StudentImportForm ref="importFormRef" @success="getList" :task-id="props.taskId"/>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
@@ -90,6 +107,7 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|||||||
import * as SmsPersonlApi from '@/api/system/person';
|
import * as SmsPersonlApi from '@/api/system/person';
|
||||||
import PersonEdit from './components/person-edit.vue';
|
import PersonEdit from './components/person-edit.vue';
|
||||||
import PersonSearch from './components/person-serach.vue'
|
import PersonSearch from './components/person-serach.vue'
|
||||||
|
import StudentImportForm from './components/StudentImportForm.vue'
|
||||||
import * as SmsChannelApi from '@/api/system/session';
|
import * as SmsChannelApi from '@/api/system/session';
|
||||||
import { fa } from 'element-plus/es/locale';
|
import { fa } from 'element-plus/es/locale';
|
||||||
|
|
||||||
@@ -133,8 +151,7 @@ const queryFormRef = ref() // 搜索的表单
|
|||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
signature: undefined,
|
batch: undefined,
|
||||||
status: undefined,
|
|
||||||
createTime: [],
|
createTime: [],
|
||||||
taskId: props.taskId
|
taskId: props.taskId
|
||||||
})
|
})
|
||||||
@@ -237,7 +254,10 @@ const openSearch = (type: string, row?: object) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const importFormRef = ref()
|
||||||
|
const handleImport = () => {
|
||||||
|
importFormRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = async (id: number) => {
|
const handleDelete = async (id: number) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user