This commit is contained in:
Paidax
2025-10-17 15:49:02 +08:00
parent 1cb3ee9d58
commit ca2e204395
28 changed files with 1841 additions and 30 deletions
@@ -90,7 +90,7 @@ layout("/layouts/platform.html"){
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "sign", label: "签字" },
{ prop: "taskName", label: "当前节点"},
{ prop: "curTaskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
unions: [],
@@ -100,7 +100,7 @@ layout("/layouts/platform.html"){
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "changeTypes", label: "变更类型", sortable: true, width: 200 },
{ prop: "applyDateTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "curTaskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
@@ -74,7 +74,7 @@ layout("/layouts/platform.html"){
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "changeTypes", label: "变更类型", sortable: true, width: 200 },
{ prop: "applyDateTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "curTaskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
changeTypeData: [],
@@ -102,7 +102,7 @@ layout("/layouts/platform.html"){
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "changeTypes", label: "变更类型", sortable: true, width: 200 },
{ prop: "applyDateTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "curTaskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
@@ -100,7 +100,7 @@ layout("/layouts/platform.html"){
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "changeTypes", label: "变更类型", sortable: true, width: 200 },
{ prop: "applyDateTime", label: "申请时间", sortable: true },
{ prop: "taskName", label: "当前节点"},
{ prop: "curTaskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
@@ -0,0 +1,277 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style scoped>
.drag-area {
border: 1px dashed #ddd;
padding: 10px;
margin-top: 10px;
min-height: 50px;
}
.drag-item {
background: #f5f5f5;
padding: 8px;
margin: 4px 0;
cursor: move;
}
.ghost {
opacity: 0.5;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="业务名称">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入业务名称"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="数据列表">
<el-button size="small" @click="openAdd" type="primary">添加</el-button>
</table-tool>
<el-table :data="tableData" style="width: 100%" stripe border :header-cell-style="{background:'#FAFAFA'}"
row-key="id" @sort-change="pageOrder">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column
align="center"
header-align="center"
v-for="column in tableColumns"
show-overflow-tooltip
:label="column.label"
:prop="column.prop"
:width="column.width"
:sortable="column.sortable"
>
<template scope="{row}" v-if="column.prop === 'isActive'">
<el-switch v-model="row.isActive" @change="doUpdateActive(row)"></el-switch>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" width="200px" fixed="right">
<template scope="{row}">
<el-button size="mini" @click="openEdit(row)" type="primary">编辑</el-button>
<el-button size="mini" @click="onDelete(row)" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="120px">
<el-form-item label="业务名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入业务名称"></el-input>
</el-form-item>
<el-form-item label="业务编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入业务编码"></el-input>
</el-form-item>
<el-form-item label="排序编号" prop="sortNum">
<el-input-number v-model="formData.sortNum" placeholder="请输入排序编号" style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item label="审核流程步骤" prop="workflowSteps">
<!-- 1. 步骤多选池 -->
<el-checkbox-group v-model="selectedSteps" @change="onCheckChange">
<el-checkbox
v-for="opt in stepOptions"
:key="opt.value"
:label="opt.value">
{{ opt.label }}
</el-checkbox>
</el-checkbox-group>
<!-- 2. 已选步骤(可拖拽排序) -->
<draggable
v-model="formData.workflowSteps"
handle=".handle"
class="drag-area"
ghost-class="ghost">
<div v-for="(step, idx) in formData.workflowSteps" :key="step.stepCode" class="drag-item handle">
<i class="el-icon-menu"></i>
<el-tag size="small" style="width: 15%">{{ '第' + (idx + 1) + '步' }}. {{ step.stepName }}</el-tag>
<el-select
v-if="!step.stepName.includes('核对')"
v-model="step.assignRole"
multiple
filterable
clearable
placeholder="处理角色"
size="mini"
style="width: 30%; margin:0 8px">
<el-option v-for="role in roles" :key="role.code"
:label="role.name" :value="role.code"></el-option>
</el-select>
<el-button type="danger" icon="el-icon-delete" size="mini" circle @click="removeStep(idx)"></el-button>
</div>
</draggable>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="doSave">提交配置</el-button>
</el-form-item>
</el-form>
</template>
</guava>
</div>
<script>
new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return{
pageForm: {},
tableData: [],
tableColumns: [
{ prop: "name", label: "业务名称", sortable: true },
{ prop: "code", label: "业务编码", sortable: true },
{ prop: "sortNum", label: "排序编号", sortable: true },
{ prop: "isActive", label: "是否启用" }
],
formData: {
name: '',
code: '',
targetTable: '',
workflowSteps: []
},
formRules: {
name: [{ required: true, message: '请输入业务名称', trigger: ['blur', 'change'] }],
code: [{ required: true, message: '请输入业务编码', trigger: ['blur', 'change'] }],
sortNum: [{ required: true, message: '请输入排序编号', trigger: ['blur', 'change'] }],
workflowSteps: [{ required: true, message: '请填写审核流程步骤', trigger: ['blur', 'change'] }]
},
selectedSteps: [],
stepOptions: [
{ value: 'personal', label: '个人核对' },
{ value: 'unionGroupCheck', label: '工会小组核对' },
{ value: 'branchUnionCheck', label: '分工会核对' },
{ value: 'schoolUnionCheck', label: '校工会核对' },
{ value: 'unionGroupAudit', label: '工会小组审核' },
{ value: 'branchUnionAudit', label: '分工会审核' },
{ value: 'schoolUnionAudit', label: '校工会审核' },
],
roles: []
}
},
methods: {
openAdd() {
this.$refs.guava.edit()
},
doSave() {
if (!this.formData.workflowSteps) {
this.$message.error('请配置审核流程步骤')
}
this.$refs.formRef.validate(valid => {
if (valid) {
this.$confirm("您确定要提交吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
const formData = clone(this.formData)
formData.workflowSteps = JSON.stringify(this.formData.workflowSteps)
this.$axios.post('/platform/personnel/check/verification/config/doAddOrModify', formData)
.then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
this.$refs.guava.index()
} else {
this.$message.error(res.msg)
}
})
})
}
})
},
doUpdateActive(row) {
this.$axios.post('/platform/personnel/check/verification/config/doUpdateActive', {id: row.id})
.then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
} else {
this.$message.error(res.msg)
}
})
},
openEdit(row) {
this.$axios.post('/platform/personnel/check/verification/config/findOne', {id: row.id})
.then(res => {
if (res.code === 0) {
this.formData = res.data
this.selectedSteps = res.data.workflowSteps.map(v => v.stepCode)
this.$refs.guava.edit()
} else {
this.$message.error(res.msg)
}
})
},
onDelete(row) {
this.$confirm("您确定要删除吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/personnel/check/verification/config/onDelete', {id: row.id})
.then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
})
},
onCheckChange(codes) {
// 先删掉已取消的
this.formData.workflowSteps = this.formData.workflowSteps
.filter(s => codes.includes(s.stepCode))
// 再追加新勾选的
const existCodes = this.formData.workflowSteps.map(s => s.stepCode)
codes.forEach(code => {
if (!existCodes.includes(code)) {
const data = this.stepOptions.find(opt => opt.value === code)
this.formData.workflowSteps.push({
stepName: data.label,
stepCode: data.value,
assignRole: []
})
}
})
},
removeStep(idx) {
const code = this.formData.workflowSteps[idx].stepCode
this.formData.workflowSteps.splice(idx, 1)
// 同步 checkbox
this.selectedSteps = this.selectedSteps.filter(c => c !== code)
},
async listRoles() {
const resp = await this.$axios.post('/platform/personnel/check/verification/config/listRoles')
if (resp.code === 0) {
this.roles = resp.data
}
}
},
created() {
this.pageData()
this.listRoles()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,83 @@
const basicInfoForm = {
template: /*language=HTML*/ `
<div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="120px">
<el-form-item label="事项名称" prop="title">
<el-input v-model="formData.title" placeholder="请输入事项名称"></el-input>
</el-form-item>
<el-form-item label="业务类型" prop="businessType">
<el-select v-model="formData.businessType" @change="setConfig" placeholder="请选择业务类型" style="width: 100%">
<el-option
v-for="item in businessList"
:key="item.code"
:label="item.name"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker
v-model="formData.startTime"
type="datetime"
placeholder="选择开始时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%;">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker
v-model="formData.endTime"
type="datetime"
placeholder="选择结束时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%;">
</el-date-picker>
</el-form-item>
<el-form-item style="text-align: right">
<el-button type="primary" @click="doSubmit">下一步:配置流程</el-button>
</el-form-item>
</el-form>
</div>
`,
data() {
return {
businessList: [],
formData: {},
formRules: {
title: [{ required: true, message: '请输入事项名称', trigger: ['blur', 'change'] }],
businessType: [{ required: true, message: '请选择业务类型', trigger: ['blur', 'change'] }],
startTime: [{ required: true, message: '请选择开始时间', trigger: ['blur', 'change'] }],
endTime: [{ required: true, message: '请选择结束时间', trigger: ['blur', 'change'] }]
}
}
},
methods: {
async listBusiness() {
const resp = await this.$axios.post('/platform/personnel/check/verification/config/findAll')
if (resp.code === 0) {
this.businessList = resp.data
}
},
setConfig(val){
if (val) {
this.formData.businessConfig = this.businessList.find(item => item.code === val)
} else {
this.formData.businessConfig = {}
}
},
doSubmit() {
this.$refs.formRef.validate(valid => {
if (valid) {
this.$emit('next', { ...this.formData })
}
})
}
},
async created() {
await this.listBusiness()
}
}
@@ -0,0 +1,294 @@
const importAndMap = {
template: /*language=HTML*/ `
<div>
<h3>导入人员数据并配置字段</h3>
<div style="margin-top: 15px">
<!-- 文件上传 -->
<div class="upload-area">
<el-upload
drag
class="upload-box"
action="#"
:auto-upload="false"
:on-change="handleFileChange"
:file-list="fileList"
accept=".xlsx,.xls"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将 Excel 文件拖到此处,或<em>点击上传</em></div>
<div style="color: darkred">支持 .xlsx、.xls 格式,文件大小不超过 20MB,第一行必须为表头且表头中必须包含【工号】字段</div>
</el-upload>
</div>
<!-- 表头选择区域 -->
<div v-if="headers.length > 0" class="field-selection" style="margin-top: 20px;">
<h4>请选择需要核对的字段:</h4>
<p style="color: #999; margin-bottom: 10px;">
已从文件中读取到 {{ headers.length }} 个字段,勾选后将在审核流程中允许修改。
<br>
<small style="color: green">💡 提示:下方数据预览显示全部字段,用于核对数据准确性。</small>
</p>
<!-- 全选 / 反选 -->
<div style="margin-bottom: 10px;">
<el-button size="small" @click="selectAll">全选</el-button>
<el-button size="small" @click="deselectAll">取消全选</el-button>
</div>
<!-- 字段列表 -->
<el-table :data="headerList" size="small" max-height="500" :show-header="false" style="width: 100%">
<el-table-column width="60">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.selected"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="字段名称" prop="name">
<template slot-scope="scope">
<strong>{{ scope.row.name }}</strong>
</template>
</el-table-column>
<el-table-column label="示例值" prop="sample">
<template slot-scope="scope">
<span style="color: #666;">{{ scope.row.sample || '空' }}</span>
</template>
</el-table-column>
</el-table>
<!-- 数据预览 -->
<div style="margin-top: 20px;">
<h4>数据预览(前 5 条)</h4>
<div v-if="previewData.length === 0" style="color:#999; font-style:italic;">
暂无预览数据,请检查文件内容
</div>
<el-table v-else :data="previewData" border max-height="300" style="width: 100%">
<el-table-column
v-for="col in allPreviewColumns"
:key="col"
:prop="col"
:label="col"
/>
</el-table>
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="actions" style="margin-top: 30px; text-align: right;">
<el-button @click="$emit('prev')">上一步</el-button>
<el-button type="primary" @click="submitTask" :disabled="!canSubmit"
:loading="submitting">完成创建并导入数据</el-button>
</div>
</div>
`,
props: {
baseData: {type: Object}
},
data() {
return {
fileList: [],
workbook: null,
headers: [], // 原始表头数组
rawData: [], // 解析出的原始二维数组
headerList: [], // { name, sample, selected }
previewData: [], // 对象数组,用于预览
submitting: false
}
},
computed: {
allPreviewColumns() {
return this.headers
},
selectedHeaders() {
return this.headerList.filter(h => h.selected).map(h => h.name)
},
canSubmit() {
return this.selectedHeaders.length > 0 && this.rawData.length > 0
}
},
methods: {
handleFileChange(file, fileList) {
this.fileList = fileList.map(item => {
// 确保 item.raw 存在(即用户选择的原始 File 对象)
if (item.raw) {
return item;
} else {
// 兼容已有文件
return { ...item, raw: item.url ? null : item.response?.data?.file };
}
});
// 只处理 .xlsx .xls 文件
const allowedTypes = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
if (!allowedTypes.includes(file.raw.type)) {
this.$message.error('请上传 Excel 文件(.xls 或 .xlsx')
this.fileList = this.fileList.filter(f => f.uid !== file.uid) // 移除无效文件
return
}
// 读取文件内容
this.readExcel(file.raw)
},
async readExcel(rawFile) {
try {
const reader = new FileReader()
reader.onload = (e) => {
const data = new Uint8Array(e.target.result)
const workbook = XLSX.read(data, { type: 'array' })
const firstSheet = workbook.Sheets[workbook.SheetNames[0]]
const jsonData = XLSX.utils.sheet_to_json(firstSheet, { header: 1 })
if (jsonData.length < 2) {
this.$message.warning('数据为空或缺少表头')
return
}
this.headers = jsonData[0].filter(h => h)
this.rawData = jsonData.slice(1)
// 初始化字段选择列表(所有字段默认可编辑?或让用户选)
this.headerList = this.headers.map((h, idx) => ({
name: h,
sample: this.rawData[0] ? this.rawData[0][idx] : '',
selected: true // 默认都允许修改,也可以让用户决定
}))
this.$message.success('成功加载 ' + this.rawData.length + ' 条数据,共 ' + this.headers.length + ' 个字段')
this.generatePreview()
}
reader.readAsArrayBuffer(rawFile)
} catch (err) {
this.$message.error('文件解析失败')
console.error(err)
}
},
resetState() {
this.headers = []
this.rawData = []
this.headerList = []
this.previewData = []
this.fileList = []
},
generatePreview() {
try {
this.previewData = this.rawData.slice(0, 5).map(row => {
const obj = {}
this.headers.forEach((header, idx) => {
const cleanHeader = (header || '').trim()
if (!cleanHeader) return
obj[cleanHeader] = row[idx] == null ? '' : String(row[idx]).trim()
})
return obj
})
} catch (err) {
console.error('生成预览失败', err)
this.previewData = []
}
},
selectAll() {
this.headerList.forEach(h => h.selected = true)
},
deselectAll() {
this.headerList.forEach(h => h.selected = false)
},
gridFormatter(row, column) {
const val = row[column.property]
return val == null ? '-' : String(val)
},
async submitTask() {
if (!this.canSubmit) {
this.$message.warning('请至少选择一个字段')
return
}
this.submitting = true
try {
this.baseData.fieldConfig = this.headerList
.map(h => ({
fieldCode: h.name,
fieldName: h.name,
isRequired: h.selected,
sortOrder: this.headers.indexOf(h.name)
}))
const formData = new FormData()
formData.append('file', this.fileList[0].raw)
formData.append('baseData', JSON.stringify(this.baseData))
console.log(formData)
this.$emit('finish', formData)
} catch (err) {
this.$message.error('提交失败:' + (err.message || '未知错误'))
} finally {
this.submitting = false
}
}
},
mounted() {
const s = document.createElement("script")
s.type = "text/javascript"
s.src = "/assets/platform/plugins/xlsx/xlsx.full.min.js"
document.body.appendChild(s)
},
style: /*language=CSS*/ `
/deep/ .upload-area {
border: 2px dashed #d9d9d9;
border-radius: 8px;
padding: 4px;
text-align: center;
background: #fafafa;
transition: all 0.3s ease;
margin-bottom: 15px;
}
/deep/ .upload-area:hover {
border-color: #409eff;
background: #f0f9ff;
}
/deep/ .el-upload-dragger{
background: none !important;
border: none !important;
}
/deep/ .import-and-map {
padding: 20px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0,0,0,0.05);
}
/deep/ .upload-box {
width: 100%;
margin: 0 auto;
}
/deep/ .field-selection {
padding: 15px;
border: 1px solid #eee;
border-radius: 6px;
background: #f9f9f9;
}
/deep/ .actions {
text-align: right;
}
/deep/ .el-table th {
font-weight: bold;
color: #333;
}
`
}
@@ -0,0 +1,79 @@
<!--#include("basicInfoForm.js"){}#-->
<!--#include("workflowConfig.js"){}#-->
<!--#include("importAndMap.js"){}#-->
const Manage = {
template: /*language=HTML*/ `
<div class="create-task-page">
<!-- 步骤条 -->
<el-steps :active="currentStep" finish-status="success" align-center style="margin: 20px 0;">
<el-step title="基本信息"></el-step>
<el-step title="配置流程"></el-step>
<el-step title="导入数据 & 映射字段"></el-step>
</el-steps>
<div class="form-container">
<!-- 基本信息 -->
<div v-show="currentStep === 0">
<basicInfoForm ref="basicInfoFormRef" @next="gotoNext"/>
</div>
<!-- 流程配置 -->
<div v-show="currentStep === 1">
<workflowConfig ref="workflowConfigRef" :base-data.sync="formData" @prev="currentStep--" @next="gotoNext"/>
</div>
<!-- 导入 + 字段映射 -->
<div v-show="currentStep === 2">
<importAndMap
ref="importAndMapRef"
:base-data.sync="formData"
@finish="onFinish"
@prev="currentStep--"
/>
</div>
</div>
</div>
`,
data() {
return {
currentStep: 0,
newTaskId: '',
formData: {
businessConfig: {}
}
}
},
components: {
basicInfoForm,
workflowConfig,
importAndMap
},
methods: {
gotoNext(formData) {
this.formData = formData
this.currentStep++
if (this.currentStep === 1) {
this.$nextTick(() => {
this.$refs.workflowConfigRef.init()
})
}
},
onFinish(formData) {
this.$confirm('确定要提交吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const resp = await this.$axios.post('/platform/personnel/check/verification/manage/doAddOrModify', formData)
if (resp.code === 0){
this.$message.success(resp.msg)
}
})
},
},
style: /*language=CSS*/ `
`
}
@@ -0,0 +1,128 @@
const workflowConfig = {
template: /*language=HTML*/ `
<div>
<h3>配置审核流程(勾选添加审核步骤,拖拽调整顺序,点击删除)</h3>
<div style="margin-top: 15px">
<el-checkbox-group v-model="selectedSteps" @change="onCheckChange">
<el-checkbox
v-for="opt in stepOptions"
:key="opt.value"
:label="opt.value">
{{ opt.label }}
</el-checkbox>
</el-checkbox-group>
<draggable
v-model="baseData.businessConfig.workflowSteps"
handle=".handle"
class="drag-area"
ghost-class="ghost">
<div v-for="(step, idx) in baseData.businessConfig.workflowSteps" :key="step.stepCode" class="drag-item handle">
<i class="el-icon-menu"></i>
<el-tag size="small" style="width: 15%">{{ '第' + (idx + 1) + '步' }}. {{ step.stepName }}
</el-tag>
<el-select
v-if="!step.stepName.includes('核对')"
v-model="step.assignRole"
multiple
filterable
clearable
placeholder="处理角色"
size="mini"
style="width: 30%; margin:0 8px">
<el-option v-for="role in roles" :key="role.code"
:label="role.name" :value="role.code"></el-option>
</el-select>
<el-button type="danger" icon="el-icon-delete" size="mini" circle
@click="removeStep(idx)"></el-button>
</div>
</draggable>
</div>
<div style="margin-top: 20px;text-align: right">
<el-button @click="$emit('prev')">上一步</el-button>
<el-button type="primary" @click="$emit('next', baseData)">下一步:导入数据</el-button>
</div>
</div>
`,
props: {
baseData: {type: Object}
},
data() {
return {
selectedSteps: [],
stepOptions: [
{ value: 'personal', label: '个人核对' },
{ value: 'unionGroupCheck', label: '工会小组核对' },
{ value: 'branchUnionCheck', label: '分工会核对' },
{ value: 'schoolUnionCheck', label: '校工会核对' },
{ value: 'unionGroupAudit', label: '工会小组审核' },
{ value: 'branchUnionAudit', label: '分工会审核' },
{ value: 'schoolUnionAudit', label: '校工会审核' },
],
roles: []
}
},
methods: {
onCheckChange(codes) {
// 先删掉已取消的
this.baseData.businessConfig.workflowSteps = this.baseData.businessConfig.workflowSteps
.filter(s => codes.includes(s.stepCode))
// 再追加新勾选的
const existCodes = this.baseData.businessConfig.workflowSteps.map(s => s.stepCode)
codes.forEach(code => {
if (!existCodes.includes(code)) {
const data = this.stepOptions.find(opt => opt.value === code)
this.baseData.businessConfig.workflowSteps.push({
stepName: data.label,
stepCode: data.value,
assignRole: []
})
}
})
},
removeStep(idx) {
const code = this.baseData.businessConfig.workflowSteps[idx].stepCode
this.baseData.businessConfig.workflowSteps.splice(idx, 1)
// 同步 checkbox
this.selectedSteps = this.selectedSteps.filter(c => c !== code)
},
async listRoles() {
const resp = await this.$axios.post('/platform/personnel/check/verification/config/listRoles')
if (resp.code === 0) {
this.roles = resp.data
}
},
init() {
this.selectedSteps = this.baseData.businessConfig.workflowSteps.map(s => s.stepCode)
}
},
created() {
this.listRoles()
},
style: /*language=CSS*/ `
/deep/ .drag-area {
border: 1px dashed #ddd;
padding: 10px;
margin-top: 10px;
min-height: 50px;
}
/deep/ .drag-item {
background: #f5f5f5;
padding: 8px;
margin: 4px 0;
cursor: move;
}
/deep/ .ghost {
opacity: 0.5;
}
`
}
@@ -0,0 +1,126 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
@change="doSearch"
placeholder="请选择年度"
type="year"
style="width: 100%"
v-model="pageForm.year"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="任务名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入任务名称"
clearable
style="width: 100%"
v-model="pageForm.searchKeyword"
></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="数据列表">
<el-button size="small" @click="openAdd" type="primary">新建</el-button>
</table-tool>
<el-table :data="tableData" style="width: 100%" stripe border :header-cell-style="{background:'#FAFAFA'}"
row-key="id" @sort-change="pageOrder">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
<el-table-column
align="center"
header-align="center"
v-for="column in tableColumns"
show-overflow-tooltip
:label="column.label"
:prop="column.prop"
:width="column.width"
:sortable="column.sortable"
></el-table-column>
<el-table-column align="center" header-align="center" label="操作" width="200px" fixed="right">
<template scope="{row}">
<el-button size="mini" @click="openView(row)" type="primary">查看</el-button>
<el-button size="mini" @click="openEdit(row)" type="primary">编辑</el-button>
<el-button size="mini" @click="onDelete(row)" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<info ref="infoRef"></info>
</template>
<template #edit>
<manage ref="manageRef"></manage>
</template>
</guava>
</div>
<script>
<!--#include("add/manage.js"){}#-->
<!--#include("info.js"){}#-->
new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return{
tableColumns: [
{ prop: "taskName", label: "任务名称", sortable: true },
{ prop: "fileName", label: "导入文件名称", sortable: true },
{ prop: "startTime", label: "开始时间", sortable: true },
{ prop: "endTime", label: "结束时间", sortable: true },
{ prop: "status", label: "当前状态" }
],
}
},
components: {
'info': INFO,
'manage': Manage,
},
methods: {
openAdd(){
this.$refs.guava.edit()
},
openView(row){
},
openEdit(row){
},
onDelete(row){
this.$confirm("您确定要删除吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/personnel/check/manage/onDelete', {id: row.id})
.then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
})
}
},
created() {
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,16 @@
const INFO = {
template: /*language=HTML*/ `
`,
data() {
return {
}
},
methods: {
},
created() {
}
}