'考试管理人员管理'

This commit is contained in:
esacpe
2025-09-24 17:35:24 +08:00
parent c23bcb30df
commit 7d5a18597a
22 changed files with 420 additions and 145 deletions

View File

@ -39,37 +39,38 @@
</el-row>
<el-divider />
<!-- 人员 -->
<el-row class="peoRow" v-for="(item, index) in formData.courceList" :key="index">
<el-row class="peoRow" v-for="(item, index) in formData.pxkcList" :key="index">
<el-col :span="12">
<el-form-item label="培训日期" :prop="`courceList[${index}].pxrq`" style="width: 100%;" :rules="rules.pxrq">
<el-form-item label="培训日期" :prop="`pxkcList[${index}].pxrq`" style="width: 100%;" :rules="rules.pxrq">
<el-date-picker v-model="item.pxrq" type="date" value-format="YYYY-MM-DD" placeholder="请输入培训日期" style="width: 100%;" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="培训时间" prop="pxsj" style="width: 100%;">
<el-time-picker v-model="item.pxsj" value-format="HH:mm:ss" placeholder="请输入培训时间" style="width: 100%;" is-range range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间"/>
<el-form-item label="培训时间" :prop="`pxkcList[${index}].pxsj`" style="width: 100%;" :rules="rules.pxsj">
<el-date-picker v-model="item.pxsj" placeholder="请选择培训开始时间" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="课程名称" :prop="`courceList[${index}].kcmc`" style="width: 100%;" :rules="rules.kcmc">
<el-form-item label="课程名称" :prop="`pxkcList[${index}].kcmc`" style="width: 100%;" :rules="rules.kcmc">
<el-input v-model="item.kcmc" placeholder="请输入课程名称" style="width: 100%;"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="组织单位" :prop="`courceList[${index}].zzdw`" style="width: 100%;" :rules="rules.zzdw">
<el-form-item label="组织单位" :prop="`pxkcList[${index}].zzdw`" style="width: 100%;" :rules="rules.zzdw">
<el-input v-model="item.zzdw" placeholder="请输入组织单位" style="width: 100%;"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="授课教员" :prop="`courceList[${index}].skjy`" style="width: 100%;" :rules="rules.skjy">
<el-select v-model="item.skjy" placeholder="请选择授课教员" style="width: 100%;">
<el-form-item label="授课教员" :prop="`pxkcList[${index}].skjy`" style="width: 100%;" :rules="rules.skjy">
<el-input v-model="item.skjy" placeholder="请选择授课教员" style="width: 100%;"></el-input>
<!-- <el-select v-model="item.skjy" placeholder="请选择授课教员" style="width: 100%;">
<el-option label="张三" value="张三"></el-option>
<el-option label="李四" value="李四"></el-option>
</el-select>
</el-select> -->
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="培训内容" :prop="`courceList[${index}].pxnc`" style="width: 100%;" :rules="rules.pxnr">
<el-form-item label="培训内容" :prop="`pxkcList[${index}].pxnr`" style="width: 100%;" :rules="rules.pxnr">
<el-input v-model="item.pxnr" placeholder="请输入培训内容" style="width: 100%;"></el-input>
</el-form-item>
</el-col>
@ -81,15 +82,19 @@
<el-button type="primary" @click="addItem">新增课程</el-button>
</div>
</el-form>
<div class="table-title">培训保安人员 <el-icon size="20px" style="top: 4px;" color="green"><CirclePlusFilled /></el-icon> </div>
<div class="table-title" @click="hanbleClickSelect">培训保安人员 <el-icon size="20px" style="top: 4px;" color="green"><CirclePlusFilled /></el-icon> </div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="warning" @click="addEdit('updata', row)">删除</el-link>
</template>
<template #pxsc="{ row }">
<span>{{ row.pxsc }}h</span>
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="warning" @click="handleDelItem(row)">删除</el-link>
</template>
</MyTable>
</div>
<select-personnel-dialog ref="selectPersonnelRef" v-model="visible" @change="handleChange" />
</div>
</template>
@ -97,9 +102,13 @@
import { qcckPost } from "@/api/qcckApi.js";
import MyTable from '@/components/aboutTable/MyTable.vue';
import { ref, computed, reactive, getCurrentInstance } from 'vue'
import SelectPersonnelDialog from "./selectPersonnelDialog.vue";
const { proxy } = getCurrentInstance()
const visible = ref(false)
const showDialog = ref(false)
const formData = ref({
courceList: [{
pxkcList: [{
pxkcxm: '', //课程名称
pxzcdw: '', //组织单位
pxfcy: '', //授课教员
@ -107,9 +116,10 @@ const formData = ref({
}] //课程
})
const emits = defineEmits(['refresh'])
const FormRef = ref(null)
const pageData = reactive({
tableData: [{xm: '张三', sfzh: '123456789012345678', lxdh: '13800000000'}],
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
@ -126,8 +136,8 @@ const pageData = reactive({
{ label: "姓名", prop: "xm" },
{ label: "证件号码", prop: "sfzh" },
{ label: "联系号码", prop: "lxdh" },
{ label: "线上培训时长", prop: "sfzh" },
{ label: "所属单位", prop: "lxdh" },
{ label: "线上培训时长", prop: "pxsc", showSolt: true },
{ label: "所属单位", prop: "lxdw" },
]
});
@ -141,11 +151,17 @@ const rules = {
kcmc: [{ required: true, message: "请输入课程名称", trigger: "change" }],
zzdw: [{ required: true, message: "请输入组织单位", trigger: "change" }],
skjy: [{ required: true, message: "请选择授课教员", trigger: "change" }],
pxnr: [{ required: true, message: "请输入培训内容", trigger: "change" }]
pxnr: [{ required: true, message: "请输入培训内容", trigger: "change" }],
pxsj: [{ required: true, message: "请选择培训开始时间", trigger: "change" }],
}
const selectPersonnelRef = ref(null)
const hanbleClickSelect = () => {
selectPersonnelRef.value?.open()
}
const addItem = () => {
formData.value.courceList.push({
formData.value.pxkcList.push({
pxkcxm: '', //课程名称
pxzcdw: '', //组织单位
pxfcy: '', //授课教员
@ -154,21 +170,39 @@ const addItem = () => {
}
const delItem = (item,index) => {
if(formData.value.courceList.length === 1) return proxy.$message.error('请至少添加一门课程');
formData.value.courceList.splice(index,1)
if(formData.value.pxkcList.length === 1) return proxy.$message.error('请至少添加一门课程');
formData.value.pxkcList.splice(index,1)
}
const init = () => {
showDialog.value = true
showDialog.value = true
}
const close = () => {
showDialog.value = false
FormRef.value.resetFields()
showDialog.value = false
}
const save = async () => {
FormRef.value.validate((valid) => {
const handleDelItem = (row) => {
const index = pageData.tableData.findIndex(item => item.id === row.id)
pageData.tableData.splice(index, 1)
}
const handleChange = (val) => {
pageData.tableData = [...pageData.tableData, ...val]?.filter((i, index, arr) => arr?.findIndex(s => i?.id === s?.id) === index)
}
const save = () => {
if (pageData.tableData.length === 0) return proxy.$message.warning('请选择培训保安人员')
const ryidList = pageData.tableData?.map(i => i?.id)
const { pxkcList, pxxmid } = formData.value
FormRef.value.validate( async (valid) => {
const url = !formData.value?.id ? `/mosty-base/baxx/pxxm/add` : `/mosty-base/baxx/pxxm/edit`
const res = await qcckPost(formData.value, url)
await qcckPost({ pxkcList, pxxmid: res?.id, ryidList }, !formData.value?.id ? `/mosty-base/baxx/pxkc/saveList` : `/mosty-base/baxx/pxkc/updateList`)
proxy.$message.success('新增培训项目成功')
emits("refresh");
close()
})
}

View File

@ -16,22 +16,23 @@
<el-descriptions-item label="培训结束时间">{{ formData.jssj }}</el-descriptions-item>
</el-descriptions>
<el-descriptions column="2" border class="label" label-width="120px">
<el-descriptions-item label="培训日期">{{ courseInfo.pxrq }}</el-descriptions-item>
<el-descriptions-item label="培训时间">{{ courseInfo.pxsj }}</el-descriptions-item>
<el-descriptions-item label="课程名称">{{ courseInfo.kcmc }}</el-descriptions-item>
<el-descriptions-item label="组织单位">{{ courseInfo.zzdw }}</el-descriptions-item>
<el-descriptions-item label="授课教员">{{ courseInfo.skjy }}</el-descriptions-item>
<el-descriptions-item label="培训内容">{{ courseInfo.pxnr }}</el-descriptions-item>
<el-descriptions-item label="培训人员" :span="2">{{ courseInfo.ypxry }}</el-descriptions-item>
<template v-for="item in pageData.pxkcList" :key="item.id">
<el-descriptions column="2" border class="label" label-width="120px">
<el-descriptions-item label="培训日期">{{ item.pxrq }}</el-descriptions-item>
<el-descriptions-item label="培训时间">{{ item.pxsj }}</el-descriptions-item>
<el-descriptions-item label="课程名称">{{ item.kcmc }}</el-descriptions-item>
<el-descriptions-item label="组织单位">{{ item.zzdw }}</el-descriptions-item>
<el-descriptions-item label="授课教员">{{ item.skjy }}</el-descriptions-item>
<el-descriptions-item label="培训内容">{{ item.pxnr }}</el-descriptions-item>
<el-descriptions-item label="已培训人员" :span="2">{{ item.ypxry }}</el-descriptions-item>
<el-descriptions-item label="培训照片" :span="2">
<div class="imgWrapper">
<Upload v-model="courseInfo.pxzp" />
<Upload v-model="item.pxzp" />
</div>
</el-descriptions-item>
</el-descriptions>
</template>
<!-- <el-descriptions title="考试人员" column="2" border class="mt20"> -->
<div class="label">培训保安人员</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@ -41,7 +42,10 @@
<el-link type="warning" @click="addEdit('updata', row)">删除</el-link>
</template>
</MyTable>
<!-- </el-descriptions> -->
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
@ -51,6 +55,7 @@
import { ref, computed, reactive, getCurrentInstance } from 'vue'
import { qcckPost } from "@/api/qcckApi.js";
import MyTable from '@/components/aboutTable/MyTable.vue';
import Pages from "@/components/aboutTable/Pages.vue"
import Upload from "@/components/MyComponents/Upload/index.vue"
const { proxy } = getCurrentInstance()
@ -83,7 +88,8 @@ const dialogVisible = computed({
})
const pageData = reactive({
tableData: [{}],
tableData: [],
pxkcList: [],
keyCount: 0,
tableConfiger: {
haveControls: false,
@ -113,14 +119,36 @@ const close = () => {
dialogVisible.value = false
}
// 根据项目id获取培训课程
const getPxkcList = async ({ id }) => {
const res = await qcckPost({ pxxmid: id }, `/mosty-base/baxx/pxkc/list`)
if (res) {
pageData.pxkcList = res
}
}
// 获取保安信息培训课程管理详情
const getbaInfo = async () => {
const res = await qcckPost({}, `/mosty-base/baxx/pxkc/getInfo/${id}`)
const getbaInfo = async ({ id = '' }) => {
const res = await qcckPost({ id }, `/mosty-base/baxx/pxkc/getInfo/${id}`)
if (res) {
courseInfo.value = res
}
}
// 根据项目id获取培训人员
const getList = async ({ id = "" }) => {
const res = await qcckPost({
...pageData.pageConfiger,
pxxmid: id
}, `/mosty-base/baxx/pxry/page`)
if (res) {
console.log(res);
pageData.tableData = res.records || [];
pageData.total = res.total;
}
}
const open = (row = {}, type = 'view') => {
disabled.value = false
dialogVisible.value = true
@ -128,10 +156,9 @@ const open = (row = {}, type = 'view') => {
if (type === 'view') {
title.value = '保安线下考试详情'
visible.value = true
getbaInfo()
} else if (type === 'edit') {
title.value = '保安证申请'
visible.value = false
getbaInfo(row)
getPxkcList(row)
getList(row)
}
}

View File

@ -0,0 +1,121 @@
<template>
<div>
<el-dialog
title="选择人员"
v-model="visible"
width="50%"
:before-close="handleClose"
>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@chooseData="handleChooseData"
>
<template #pxsc="{ row }">
<span>{{ row.pxsc }}h</span>
</template>
</MyTable>
<template #footer>
<el-button @click="handleClose"> </el-button>
<el-button type="primary" @click="handleSubmit"> </el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { computed, ref, reactive, getCurrentInstance } from 'vue';
import { qcckPost } from "@/api/qcckApi.js";
import MyTable from '@/components/aboutTable/MyTable.vue';
const { proxy } = getCurrentInstance()
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
defaultSelectKeys: {
type: Array,
default: () => []
}
})
const emits = defineEmits(['update:modelValue', 'change'])
const visible = computed({
get() {
return props.modelValue
},
set(val) {
emits('update:modelValue', val)
}
})
const selectList = ref([])
const pageData = reactive({
tableData: [{}],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showIndex: false,
showSelectType: "checkBox",
haveControls: false,
loading: false
},
total: 0,
tableHeight: 300,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
},
controlsWidth: 180,
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "证件号码", prop: "sfzh" },
{ label: "联系电话", prop: "lxdh" },
{ label: "培训时长", prop: "pxsc", showSolt: true },
]
});
const open = async () => {
pageData.tableConfiger.loading = true;
try {
const res = await qcckPost({
...pageData.pageConfiger,
}, `/mosty-base/baxx/pxry/page`)
if (res) {
pageData.tableData = res.records || []
pageData.total = res.total
visible.value = true
}
} finally {
pageData.tableConfiger.loading = false
}
}
const handleClose = () => {
selectList.value = []
visible.value = false
}
const handleChooseData = (data) => {
selectList.value = data
}
const handleSubmit = () => {
if (selectList.value.length === 0) return proxy.$message.warning('请选择人员')
emits('change', selectList.value)
handleClose()
}
defineExpose({ open })
</script>
<style>
</style>

View File

@ -8,19 +8,10 @@
</div>
</div>
<div class="cntinfo">
<el-descriptions column="2" border label-width="120px">
<el-descriptions-item label="培训项目名称">{{ formData.xmmc }}</el-descriptions-item>
<el-descriptions-item label="考试时间">{{ formData.kskssj }}</el-descriptions-item>
<el-descriptions-item label="考试辖区">{{ formData.ksxq }}</el-descriptions-item>
<el-descriptions-item label="考试地址">{{ formData.ksdz }}</el-descriptions-item>
<el-descriptions-item label="监考民警">{{ formData.jkrxm }}</el-descriptions-item>
<el-descriptions-item label="考试方式">
<DictTag :value="formData.ksfs" :tag="false" :options="D_BAXX_KSFS" />
</el-descriptions-item>
</el-descriptions>
<form-message ref="formRef" v-model="formData" :rules="rules" :formList="formList" label-width="120px">
<!-- <el-descriptions title="考试人员" column="2" border class="mt20"> -->
<div class="label">培训保安人员</div>
</form-message>
<div class="table-title" @click="hanbleClickSelect">考试人员 <el-icon size="20px" style="top: 4px;" color="green"><CirclePlusFilled /></el-icon> </div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
>
@ -29,24 +20,26 @@
<el-link type="warning" @click="addEdit('updata', row)">删除</el-link>
</template>
</MyTable>
<!-- </el-descriptions> -->
</div>
<select-personnel-dialog ref="selectPersonnelRef" v-model="visible" @change="handleChange" />
</div>
</template>
<script setup>
import { ref, computed, reactive, getCurrentInstance } from 'vue'
import { qcckPost } from "@/api/qcckApi.js";
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import MyTable from '@/components/aboutTable/MyTable.vue';
import selectPersonnelDialog from './selectPersonnelDialog.vue';
const { proxy } = getCurrentInstance()
const { D_BAXX_KSFS } = proxy.$dict("D_BAXX_KSFS");
const title = ref('保安培训项目新增')
const loading = ref(false)
const disabled = ref(false)
const FormRef = ref(null)
const visible = ref(true)
const formRef = ref(null)
const visible = ref(false)
const viewAndUploadRef = ref(null)
const props = defineProps({
@ -72,7 +65,7 @@ const dialogVisible = computed({
})
const pageData = reactive({
tableData: [{}],
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
@ -94,32 +87,48 @@ const pageData = reactive({
]
});
const formList = reactive([
[
{ label: "培训项目名称", prop: "xmmc", type: "input" },
{ label: "考试时间", prop: "kskssj", type: "date"},
],
[
{ label: "考试辖区", prop: "ksxq", type: "input" },
{ label: "考试地址", prop: "ksdz", type: "input"},
],
[
{ label: "考试方式", prop: "ksfs", type: "select", options: D_BAXX_KSFS },
],
])
const rules = {
xmmc: [{ required: true, message: '请输入培训项目名称', trigger: 'blur' }],
kskssj: [{ required: true, message: '请选择考试时间', trigger: 'blur' }],
ksxq: [{ required: true, message: '请输入考试辖区', trigger: 'blur' }],
ksdz: [{ required: true, message: '请输入考试地址', trigger: 'blur' }],
ksfs: [{ required: true, message: '请选择考试方式', trigger: 'blur' }],
}
const formData = ref({})
const close = () => {
dialogVisible.value = false
}
const open = (row = {}, type = 'add') => {
const open = (row = {}) => {
disabled.value = false
dialogVisible.value = true
formData.value = { ...row }
if (type === 'view') {
title.value = '保安线下考试详情'
visible.value = true
} else if (type === 'edit') {
title.value = '保安证申请'
visible.value = false
}
title.value = '保安考试申请'
}
const save = () => {
FormRef.value.submit(() => {
if (pageData.tableData.length === 0) return proxy.$message.warning('请选择考试人员')
formRef.value.submit(() => {
loading.value = true;
const url = !formData.value?.id ? `/mosty-base/baxx/cyry/add` : `/mosty-base/baxx/cyry/edit`;
qcckPost(formData.value, url).then(() => {
qcckPost(formData.value, `mosty-base/baxx/pxxm/sqks`).then(() => {
loading.value = false;
proxy.$message.success("保存成功");
proxy.$message.success("申请考试成功");
emits("refresh");
close();
}).catch(() => {
@ -128,6 +137,15 @@ const save = () => {
});
}
const selectPersonnelRef = ref(null)
const hanbleClickSelect = () => {
selectPersonnelRef.value?.open()
}
const handleChange = (val) => {
pageData.tableData = [...pageData.tableData, ...val]?.filter((i, index, arr) => arr?.findIndex(s => i?.id === s?.id) === index)
}
const addEdit = (type, row) => {
viewAndUploadRef.value?.open(row, type)
}
@ -138,6 +156,20 @@ defineExpose({ open })
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
::v-deep {
.el-form--inline {
padding: 0 !important;
}
}
.table-title{
line-height: 40px;
text-align: center;
background: #f5f5f5;
color: #333;
cursor: pointer;
}
.label {
margin-top: 20px;
color: #000;

View File

@ -30,7 +30,7 @@
<view-project-details-dialog ref="viewProjectDetailsRef" v-model="isVisible" />
<preject-details-dialog ref="prejectDetailsRef" v-model="dialogVisible" />
<!-- 新增 -->
<AddPxxm ref="addPxxmRef" v-model="dialogVisible" />
<AddPxxm ref="addPxxmRef" v-model="dialogVisible" @refresh="getList" />
</div>
</template>
@ -44,6 +44,7 @@ import PageTitle from "@/components/aboutTable/PageTitle.vue";
import ViewProjectDetailsDialog from "./components/viewProjectDetailsDialog.vue";
import AddPxxm from './components/addPxxm.vue'
import PrejectDetailsDialog from "./components/prejectDetailsDialog.vue";
import { get } from "lodash";
const addPxxmRef = ref()
const prejectDetailsRef = ref(null);
const viewProjectDetailsRef = ref(null)