Merge remote-tracking branch 'origin/main'

This commit is contained in:
2026-05-22 15:02:11 +08:00
59 changed files with 4615 additions and 406 deletions
@@ -25,6 +25,9 @@ const flowMixins = {
console.log(this.$refs)
console.log(this.$refs.guava)
// 首页待办已完成页面跳转,自动定位待办详情逻辑暂未启用时,及时关闭加载动画避免页面卡住
loading.close();
// this.oepnAudit({})
//
//
@@ -420,7 +420,7 @@ layout("/layouts/v4/baseLayout.html"){
this.$message.warning("当前流程没有配置地址")
return
}
window.open(formKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey)
window.open(formKey + "?taskId=" + taskId + "&bizId=" + businessNo + "&taskKey=" + taskKey)
},
// 获取空状态文本
@@ -0,0 +1,223 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.appeal-search-page .search {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
column-gap: 20px;
row-gap: 10px;
}
.appeal-search-page .search .search-item {
width: 100%;
}
.appeal-search-page .search .search-item-label {
width: 76px;
min-width: 76px;
margin-right: 8px;
}
.appeal-search-page .search .search-item-option {
min-width: calc(100% - 76px - 8px);
}
@media screen and (max-width: 1350px) {
.appeal-search-page .search {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@media screen and (max-width: 1200px) {
.appeal-search-page .search {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media screen and (max-width: 992px) {
.appeal-search-page .search {
grid-template-columns: 1fr;
}
}
</style>
<div id="app" v-cloak>
<guava ref="guava" class="appeal-search-page">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" style="width: 100%" placeholder="请选择年度"></el-date-picker>
</search-item>
<search-item label="申诉类型">
<el-select v-model="pageForm.appealTypeId" filterable clearable style="width: 100%" placeholder="请选择申诉类型">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="申诉标题">
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入申诉标题" @keyup.enter.native="doSearch"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.approval">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="taskId" style="width: 100%">
<el-table-column type="index" label="序号" width="60" :index="indexMethod"></el-table-column>
<el-table-column prop="title" label="申诉标题" show-overflow-tooltip></el-table-column>
<el-table-column prop="userName" label="申诉人" width="100"></el-table-column>
<el-table-column prop="appealTypeName" label="申诉类型" width="140"></el-table-column>
<el-table-column prop="defendantUnitName" label="被申诉单位" width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="applyDate" label="申请日期" width="120"></el-table-column>
<el-table-column prop="curTaskName" label="当前节点" width="120"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" width="120">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="210">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
<el-button size="mini" type="primary" v-if="row.taskState === 10" @click="onDeal(row)">审核</el-button>
<el-button size="mini" type="danger" v-if="row.canRevoke" @click="onRevoke(row)">撤回</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<appeal-info ref="infoRef"></appeal-info>
</template>
</guava>
<el-dialog title="受理申诉" :visible.sync="dialogVisible" width="900px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="130px">
<el-form-item label="申诉标题">
<el-input v-model="formData.title" disabled></el-input>
</el-form-item>
<el-form-item label="作出决定日期" prop="decisionDate" :rules="[{required:true,message:'请选择决定日期',trigger:'change'}]">
<el-date-picker v-model="formData.decisionDate" value-format="yyyy-MM-dd" type="date" style="width: 100%"></el-date-picker>
</el-form-item>
<el-form-item label="处理决定内容" prop="decisionContent" :rules="[{required:true,validator:validateText,message:'请输入处理决定内容',trigger:['blur','change']}]">
<el-input v-model="formData.decisionContent" type="textarea" :rows="5" maxlength="2000" show-word-limit placeholder="请输入处理决定内容"></el-input>
</el-form-item>
<el-form-item label="事实理由及依据" prop="legalBasis" :rules="[{required:true,validator:validateText,message:'请输入事实理由及依据',trigger:['blur','change']}]">
<el-input v-model="formData.legalBasis" type="textarea" :rows="6" maxlength="3000" show-word-limit placeholder="请输入事实理由及依据"></el-input>
</el-form-item>
<el-form-item label="决定书附件" prop="decisionFiles">
<file-upload :value.sync="formData.decisionFiles" :upload_number="5" upload_mode="drag" upload_result_category="array" complete_result></file-upload>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogVisible=false">取消</el-button>
<el-button type="warning" @click="doAccept(6)">退回修改</el-button>
<el-button type="danger" @click="doAccept(2)">不予受理</el-button>
<el-button type="primary" @click="doAccept(1)">受理并转执行</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"appeal-info": APPEAL_INFO
},
data() {
return {
pageForm: {
approval: false
},
typeOptions: [],
dialogVisible: false,
formData: {},
currentTaskId: null
}
},
methods: {
onOpen(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onDeal(row) {
this.currentTaskId = row.taskId
this.$axios.post("/platform/appeal/accept/queryTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.formData = res.data || row
if (!this.formData.decisionDate) {
this.$set(this.formData, "decisionDate", this.$moment().format("YYYY-MM-DD"))
}
this.dialogVisible = true
}
})
},
doAccept(submitType) {
const submit = () => {
this.$axios.post("/platform/appeal/accept/accept", {
data: JSON.stringify(this.formData),
taskId: this.currentTaskId,
submitType
}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.dialogVisible = false
this.pageData()
}
})
}
if (submitType !== 6) {
this.$refs.formRef.validate((valid) => {
if (valid) submit()
})
} else {
submit()
}
},
validateText(rule, value, callback) {
if (!(value || "").trim()) {
callback(new Error(rule.message))
return
}
callback()
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
loadTypeOptions() {
this.$axios.post("/platform/appeal/common/typeOptions").then((res) => {
if (res.code === 0) this.typeOptions = res.data || []
})
}
},
created() {
this.loadTypeOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,127 @@
const APPEAL_INFO = {
name: "AppealInfo",
/*language=HTML*/
template: `
<div class="appeal-info">
<div class="process-title">申诉基础信息</div>
<h3 style="text-align: center;font-weight: 600" class="pt10 pb10">{{ viewData.title }}</h3>
<el-descriptions :column="3" border>
<el-descriptions-item label="申诉人">{{ text(viewData.userName) }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ text(viewData.sex) }}</el-descriptions-item>
<el-descriptions-item label="出生年月">{{ text(viewData.birthday) }}</el-descriptions-item>
<el-descriptions-item label="政治面貌">{{ text(viewData.political) }}</el-descriptions-item>
<el-descriptions-item label="工号">{{ text(viewData.loginName) }}</el-descriptions-item>
<el-descriptions-item label="所在单位">{{ text(viewData.unitName) }}</el-descriptions-item>
<el-descriptions-item label="岗位">{{ text(viewData.positionName) }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ text(viewData.mobile) }}</el-descriptions-item>
<el-descriptions-item label="申请日期">{{ text(viewData.applyDate) }}</el-descriptions-item>
<el-descriptions-item label="住址" :span="3">{{ text(viewData.address) }}</el-descriptions-item>
<el-descriptions-item label="申诉类型">{{ text(viewData.appealTypeName) }}</el-descriptions-item>
<el-descriptions-item label="业务状态">
<el-tag size="mini">{{ viewData.state || '草稿' }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="被申诉单位">{{ text(viewData.defendantUnitName) }}</el-descriptions-item>
<el-descriptions-item label="被申诉单位地址" :span="2">{{ text(viewData.defendantAddress) }}</el-descriptions-item>
<el-descriptions-item label="被申诉单位电话">{{ text(viewData.defendantContact) }}</el-descriptions-item>
<el-descriptions-item label="申诉事项" :span="3">
<div class="text-left" style="white-space: pre-wrap;" v-text="plainText(viewData.appealMatter)"></div>
</el-descriptions-item>
<el-descriptions-item label="申诉理由" :span="3">
<div class="text-left" style="white-space: pre-wrap;" v-text="plainText(viewData.reason)"></div>
</el-descriptions-item>
<el-descriptions-item label="申诉要求" :span="3">
<div class="text-left" style="white-space: pre-wrap;" v-text="plainText(viewData.request)"></div>
</el-descriptions-item>
<el-descriptions-item label="申诉材料附件" :span="3">
<file-preview :files="viewData.files" complete_result></file-preview>
</el-descriptions-item>
<el-descriptions-item label="申诉人签名" :span="3">
<el-image v-if="viewData.signature" :src="viewData.signature" class="signature-image"></el-image>
<span v-else>暂无</span>
</el-descriptions-item>
</el-descriptions>
<div class="process-title mt10" v-if="viewData.acceptTime || viewData.decisionContent">受理与处理决定</div>
<el-descriptions :column="3" border v-if="viewData.acceptTime || viewData.decisionContent">
<el-descriptions-item label="受理人">{{ viewData.acceptUserName }}</el-descriptions-item>
<el-descriptions-item label="受理时间">{{ viewData.acceptTime }}</el-descriptions-item>
<el-descriptions-item label="决定日期">{{ viewData.decisionDate }}</el-descriptions-item>
<el-descriptions-item label="决定内容" :span="3">
<div class="text-left" style="white-space: pre-wrap;" v-text="plainText(viewData.decisionContent)"></div>
</el-descriptions-item>
<el-descriptions-item label="事实理由及依据" :span="3">
<div class="text-left" style="white-space: pre-wrap;" v-text="plainText(viewData.legalBasis)"></div>
</el-descriptions-item>
<el-descriptions-item label="决定书附件" :span="3">
<file-preview :files="viewData.decisionFiles" complete_result></file-preview>
</el-descriptions-item>
</el-descriptions>
<div class="process-title mt10" v-if="viewData.executeTime || viewData.executeContent">执行情况</div>
<el-descriptions :column="3" border v-if="viewData.executeTime || viewData.executeContent">
<el-descriptions-item label="执行人">{{ viewData.executeUserName }}</el-descriptions-item>
<el-descriptions-item label="执行时间">{{ viewData.executeTime }}</el-descriptions-item>
<el-descriptions-item label="执行状态">{{ viewData.state }}</el-descriptions-item>
<el-descriptions-item label="执行情况" :span="3">
<div class="text-left" style="white-space: pre-wrap;" v-text="plainText(viewData.executeContent)"></div>
</el-descriptions-item>
<el-descriptions-item label="执行附件" :span="3">
<file-preview :files="viewData.executeFiles" complete_result></file-preview>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="mt10" :key="task.id">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3">
<el-descriptions-item label="办理用户">
{{ task.taskFormData && task.taskFormData.userName ? task.taskFormData.userName : task.ext.initiatorName }}
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" :span="3" v-if="task.taskFormData && task.taskFormData.tf_opinion">
<div v-html="task.taskFormData.tf_opinion"></div>
</el-descriptions-item>
</el-descriptions>
</div>
</template>
</div>
`,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
viewData: {},
doneTasks: []
}
},
methods: {
onOpen(row) {
this.viewData = {...row}
this.getDoneTasks()
},
getDoneTasks() {
if (!this.viewData.id) {
this.doneTasks = []
return
}
this.$axios.post("/flow/common/doneTasks", {bizId: this.viewData.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data || []
}
})
},
text(value) {
return value || "-"
},
plainText(value) {
return (value || "")
.replace(/<br\s*\/?>/gi, "\n")
.replace(/<\/p>/gi, "\n")
.replace(/<[^>]+>/g, "")
.replace(/&nbsp;/g, " ")
.trim() || "-"
}
}
}
@@ -0,0 +1,205 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.appeal-search-page .search {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
column-gap: 20px;
row-gap: 10px;
}
.appeal-search-page .search .search-item {
width: 100%;
}
.appeal-search-page .search .search-item-label {
width: 76px;
min-width: 76px;
margin-right: 8px;
}
.appeal-search-page .search .search-item-option {
min-width: calc(100% - 76px - 8px);
}
@media screen and (max-width: 1350px) {
.appeal-search-page .search {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@media screen and (max-width: 1200px) {
.appeal-search-page .search {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media screen and (max-width: 992px) {
.appeal-search-page .search {
grid-template-columns: 1fr;
}
}
</style>
<div id="app" v-cloak>
<guava ref="guava" class="appeal-search-page">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" style="width: 100%" placeholder="请选择年度"></el-date-picker>
</search-item>
<search-item label="申诉类型">
<el-select v-model="pageForm.appealTypeId" filterable clearable style="width: 100%" placeholder="请选择申诉类型">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="申诉标题">
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入申诉标题" @keyup.enter.native="doSearch"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表">
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.approval">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="taskId" style="width: 100%">
<el-table-column type="index" label="序号" width="60" :index="indexMethod"></el-table-column>
<el-table-column prop="title" label="申诉标题" show-overflow-tooltip></el-table-column>
<el-table-column prop="userName" label="申诉人" width="100"></el-table-column>
<el-table-column prop="appealTypeName" label="申诉类型" width="140"></el-table-column>
<el-table-column prop="defendantUnitName" label="被申诉单位" width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="applyDate" label="申请日期" width="120"></el-table-column>
<el-table-column prop="curTaskName" label="当前节点" width="120"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" width="120">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="210">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
<el-button size="mini" type="primary" v-if="row.taskState === 10" @click="onDeal(row)">审核</el-button>
<el-button size="mini" type="danger" v-if="row.canRevoke" @click="onRevoke(row)">撤回</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<appeal-info ref="infoRef"></appeal-info>
</template>
</guava>
<el-dialog title="执行反馈" :visible.sync="dialogVisible" width="900px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="120px">
<el-form-item label="申诉标题">
<el-input v-model="formData.title" disabled></el-input>
</el-form-item>
<el-form-item label="执行情况" prop="executeContent" :rules="[{required:true,validator:validateText,message:'请输入执行情况',trigger:['blur','change']}]">
<el-input v-model="formData.executeContent" type="textarea" :rows="5" maxlength="2000" show-word-limit placeholder="请输入执行情况"></el-input>
</el-form-item>
<el-form-item label="执行附件" prop="executeFiles">
<file-upload :value.sync="formData.executeFiles" :upload_number="5" upload_mode="drag" upload_result_category="array" complete_result></file-upload>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="doExecute">提交</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"appeal-info": APPEAL_INFO
},
data() {
return {
pageForm: {
approval: false
},
typeOptions: [],
dialogVisible: false,
formData: {},
currentTaskId: null
}
},
methods: {
onOpen(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onDeal(row) {
this.currentTaskId = row.taskId
this.$axios.post("/platform/appeal/execute/queryTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.formData = res.data || row
this.dialogVisible = true
}
})
},
doExecute() {
this.$refs.formRef.validate((valid) => {
if (!valid) return
this.$axios.post("/platform/appeal/execute/execute", {
data: JSON.stringify(this.formData),
taskId: this.currentTaskId
}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.dialogVisible = false
this.pageData()
}
})
})
},
validateText(rule, value, callback) {
if (!(value || "").trim()) {
callback(new Error(rule.message))
return
}
callback()
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
loadTypeOptions() {
this.$axios.post("/platform/appeal/common/typeOptions").then((res) => {
if (res.code === 0) this.typeOptions = res.data || []
})
}
},
created() {
this.loadTypeOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,169 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.appeal-search-page .search {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
column-gap: 20px;
row-gap: 10px;
}
.appeal-search-page .search .search-item {
width: 100%;
}
.appeal-search-page .search .search-item-label {
width: 76px;
min-width: 76px;
margin-right: 8px;
}
.appeal-search-page .search .search-item-option {
min-width: calc(100% - 76px - 8px);
}
@media screen and (max-width: 1350px) {
.appeal-search-page .search {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@media screen and (max-width: 1200px) {
.appeal-search-page .search {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media screen and (max-width: 992px) {
.appeal-search-page .search {
grid-template-columns: 1fr;
}
}
</style>
<div id="app" v-cloak>
<guava ref="guava" class="appeal-search-page">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" style="width: 100%" placeholder="请选择年度"></el-date-picker>
</search-item>
<search-item label="申诉类型">
<el-select v-model="pageForm.appealTypeId" filterable clearable style="width: 100%" placeholder="请选择申诉类型">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="申诉标题">
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入申诉标题" @keyup.enter.native="doSearch"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button type="primary" size="small" icon="el-icon-plus" @click="onWrite">提交申诉</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" label="序号" width="60" :index="indexMethod"></el-table-column>
<el-table-column prop="title" label="申诉标题" show-overflow-tooltip></el-table-column>
<el-table-column prop="appealTypeName" label="申诉类型" width="140"></el-table-column>
<el-table-column prop="defendantUnitName" label="被申诉单位" width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="applyDate" label="申请日期" width="120"></el-table-column>
<el-table-column prop="state" label="业务状态" width="110">
<template slot-scope="{row}">
<el-tag size="mini">{{ row.state || '草稿' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="taskName" label="当前节点" width="120"></el-table-column>
<el-table-column label="操作" fixed="right" width="200">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
<el-button size="mini" type="primary" v-if="canEdit(row)" @click="onEdit(row)">修改</el-button>
<el-button size="mini" type="warning" v-if="row.canRevoke" @click="onRevoke(row)">撤回</el-button>
<el-button size="mini" type="danger" v-if="!row.instanceId || row.state === '草稿'" @click="onDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<appeal-info ref="infoRef"></appeal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"appeal-info": APPEAL_INFO
},
data() {
return {
pageForm: {
year: new Date().getFullYear().toString()
},
typeOptions: []
}
},
methods: {
onWrite() {
window.location.href = "/platform/appeal/write"
},
onOpen(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
canEdit(row) {
return !row.instanceId || row.state === '草稿' || row.state === '退回修改'
},
onEdit(row) {
let url = "/platform/appeal/write?id=" + row.id
if (row.startTaskId) {
url += "&taskId=" + row.startTaskId
}
window.location.href = url
},
onDelete(row) {
this.$confirm("您确定删除该申诉吗?", "提示", {type: "warning"}).then(() => {
this.$axios.post("/platform/appeal/mine/delete", {id: row.id}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onRevoke(row) {
this.$confirm("您确定撤回当前申诉吗?", "提示", {type: "warning"}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
loadTypeOptions() {
this.$axios.post("/platform/appeal/common/typeOptions").then((res) => {
if (res.code === 0) this.typeOptions = res.data || []
})
}
},
created() {
this.loadTypeOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,289 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.appeal-query-page .stat-row {
margin: 10px 0;
}
.appeal-query-page .stat-row .el-col {
margin-bottom: 10px;
}
.appeal-query-page .stat-card {
border: 1px solid #ebeef5;
border-radius: 6px;
}
.appeal-query-page .stat-card .el-card__body {
padding: 14px 16px;
}
.appeal-query-page .stat-card-content {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 72px;
}
.appeal-query-page .stat-title {
color: #606266;
font-size: 13px;
line-height: 20px;
}
.appeal-query-page .stat-value {
margin-top: 8px;
color: #303133;
font-size: 28px;
font-weight: 600;
line-height: 32px;
}
.appeal-query-page .stat-tip {
margin-top: 4px;
color: #909399;
font-size: 12px;
line-height: 18px;
}
.appeal-query-page .stat-icon {
width: 42px;
height: 42px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
}
.appeal-query-page .stat-total .stat-icon {
color: #409eff;
background: #ecf5ff;
}
.appeal-query-page .stat-wait .stat-icon {
color: #e6a23c;
background: #fdf6ec;
}
.appeal-query-page .stat-execute .stat-icon {
color: #13c2c2;
background: #e6fffb;
}
.appeal-query-page .stat-finish .stat-icon {
color: #67c23a;
background: #f0f9eb;
}
.appeal-query-page .table-card {
border-radius: 6px;
}
.appeal-search-page .search {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
column-gap: 20px;
row-gap: 10px;
}
.appeal-search-page .search .search-item {
width: 100%;
}
.appeal-search-page .search .search-item-label {
width: 76px;
min-width: 76px;
margin-right: 8px;
}
.appeal-search-page .search .search-item-option {
min-width: calc(100% - 76px - 8px);
}
@media screen and (max-width: 1350px) {
.appeal-search-page .search {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@media screen and (max-width: 1200px) {
.appeal-search-page .search {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media screen and (max-width: 992px) {
.appeal-search-page .search {
grid-template-columns: 1fr;
}
}
</style>
<div id="app" v-cloak>
<guava ref="guava" class="appeal-query-page appeal-search-page">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" style="width: 100%" placeholder="请选择年度"></el-date-picker>
</search-item>
<search-item label="申诉类型">
<el-select v-model="pageForm.appealTypeId" filterable clearable style="width: 100%" placeholder="请选择申诉类型">
<el-option v-for="item in typeOptions" :key="item.id" :label="typeOptionLabel(item)" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="申诉标题">
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入申诉标题" @keyup.enter.native="doSearch"></el-input>
</search-item>
<search-item label="业务状态">
<el-select v-model="pageForm.state" clearable style="width: 100%" placeholder="请选择业务状态">
<el-option label="待受理" value="待受理"></el-option>
<el-option label="退回修改" value="退回修改"></el-option>
<el-option label="待执行" value="待执行"></el-option>
<el-option label="已办结" value="已办结"></el-option>
</el-select>
</search-item>
<search-item label="申诉单位">
<el-select v-model="pageForm.unitId" filterable clearable style="width: 100%" placeholder="请选择申诉单位">
<el-option v-for="item in unitOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="被申诉单位">
<el-select v-model="pageForm.defendantUnitId" filterable clearable style="width: 100%" placeholder="请选择被申诉单位">
<el-option v-for="item in unitOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-row :gutter="12" class="stat-row">
<el-col v-for="item in statCards" :key="item.prop" :xs="24" :sm="12" :md="6" :lg="6">
<el-card shadow="never" class="stat-card" :class="item.className">
<div class="stat-card-content">
<div>
<div class="stat-title">{{ item.title }}</div>
<div class="stat-value">{{ statisticValue(item.prop) }}</div>
<div class="stat-tip">{{ item.tip }}</div>
</div>
<div class="stat-icon">
<i :class="item.icon"></i>
</div>
</div>
</el-card>
</el-col>
</el-row>
<el-card shadow="never" class="table-card">
<table-tool label="申诉列表"></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" label="序号" width="60" :index="indexMethod"></el-table-column>
<el-table-column prop="title" label="申诉标题" show-overflow-tooltip></el-table-column>
<el-table-column prop="userName" label="申诉人" width="100"></el-table-column>
<el-table-column prop="unitName" label="申诉单位" width="170" show-overflow-tooltip></el-table-column>
<el-table-column prop="appealTypeName" label="申诉类型" width="140"></el-table-column>
<el-table-column prop="defendantUnitName" label="被申诉单位" width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="applyDate" label="申请日期" width="120"></el-table-column>
<el-table-column prop="state" label="业务状态" width="100">
<template slot-scope="{row}">
<el-tag :type="stateTagType(row.state)" size="mini">{{ row.state || '草稿' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="instanceState" label="流程状态" width="110">
<template slot-scope="{row}">
<enum-tag v-if="row.instanceState" :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="90">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<appeal-info ref="infoRef"></appeal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"appeal-info": APPEAL_INFO
},
data() {
return {
pageForm: {
year: new Date().getFullYear().toString()
},
typeOptions: [],
unitOptions: [],
statCards: [
{title: "申诉总数", prop: "totalCount", tip: "当前筛选范围", icon: "el-icon-document", className: "stat-total"},
{title: "待受理", prop: "waitAcceptCount", tip: "委员会待审核", icon: "el-icon-time", className: "stat-wait"},
{title: "待执行", prop: "waitExecuteCount", tip: "单位待反馈", icon: "el-icon-s-operation", className: "stat-execute"},
{title: "已办结", prop: "finishCount", tip: "流程已结束", icon: "el-icon-finished", className: "stat-finish"}
],
statistics: {}
}
},
methods: {
statisticValue(prop) {
return (this.statistics && this.statistics[prop]) || 0
},
typeOptionLabel(item) {
return item.enabled === false || item.enabled === 0 ? item.name + "(已停用)" : item.name
},
stateTagType(state) {
const map = {
"待受理": "warning",
"退回修改": "danger",
"待执行": "",
"已办结": "success"
}
return map[state] || "info"
},
onOpen(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
doSearch() {
this.pageNumber = 1
this.pageData()
this.loadStatistics()
},
loadOptions() {
this.$axios.post("/platform/appeal/common/queryTypeOptions").then((res) => {
if (res.code === 0) this.typeOptions = res.data || []
})
this.$businessTool.listUnit().then((res) => {
this.unitOptions = res || []
})
},
loadStatistics() {
this.$axios.post("/platform/appeal/query/statistics", this.pageForm).then((res) => {
if (res.code === 0) this.statistics = res.data || {}
})
}
},
created() {
this.loadOptions()
this.pageData()
this.loadStatistics()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,181 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.appeal-search-page .search {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
column-gap: 20px;
row-gap: 10px;
}
.appeal-search-page .search .search-item {
width: 100%;
}
.appeal-search-page .search .search-item-label {
width: 76px;
min-width: 76px;
margin-right: 8px;
}
.appeal-search-page .search .search-item-option {
min-width: calc(100% - 76px - 8px);
}
@media screen and (max-width: 1350px) {
.appeal-search-page .search {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@media screen and (max-width: 1200px) {
.appeal-search-page .search {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media screen and (max-width: 992px) {
.appeal-search-page .search {
grid-template-columns: 1fr;
}
}
</style>
<div id="app" v-cloak>
<guava class="appeal-search-page">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="类型名称">
<el-input v-model="pageForm.name" clearable maxlength="100" placeholder="请输入类型名称" @keyup.enter.native="doSearch"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button type="primary" size="small" icon="el-icon-plus" @click="onAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" label="序号" width="60" :index="indexMethod"></el-table-column>
<el-table-column prop="name" label="类型名称" show-overflow-tooltip></el-table-column>
<el-table-column prop="sort" label="排序" width="100"></el-table-column>
<el-table-column prop="enabled" label="是否启用" width="120">
<template slot-scope="{row}">
<el-switch
v-model="row.enabled"
:disabled="row.enabledLoading"
active-color="#13ce66"
inactive-color="#ff4949"
@change="(val)=>{onEnabledChange(row, val)}">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="165">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="onEdit(row)">编辑</el-button>
<el-button size="mini" type="danger" @click="onDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</guava>
<el-dialog :title="formData.id ? '编辑申诉类型' : '新增申诉类型'" :visible.sync="dialogVisible" width="500px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="100px">
<el-form-item label="类型名称" prop="name" :rules="[{required:true,message:'请输入类型名称',trigger:'blur'}]">
<el-input v-model="formData.name" maxlength="100" show-word-limit clearable placeholder="请输入类型名称"></el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="formData.sort" :min="0" controls-position="right" style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item label="是否启用" prop="enabled">
<el-switch v-model="formData.enabled"></el-switch>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
dialogVisible: false,
pageForm: {},
formData: {}
}
},
methods: {
onAdd() {
this.formData = {enabled: true, sort: 0}
this.dialogVisible = true
},
onEdit(row) {
this.formData = {...row}
this.dialogVisible = true
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (!valid) return
this.$axios.post("/platform/appeal/type/save", {data: JSON.stringify(this.formData)}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.dialogVisible = false
this.pageData()
}
})
})
},
onEnabledChange(row, enabled) {
const oldEnabled = !enabled
const actionName = enabled ? "启用" : "禁用"
this.$confirm("您确定要" + actionName + "申诉类型“" + row.name + "”吗?", "提示", {type: "warning"}).then(() => {
this.$set(row, "enabledLoading", true)
this.$axios.post("/platform/appeal/type/statusChange", {id: row.id, enabled: enabled}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
} else {
row.enabled = oldEnabled
this.$message.error(res.msg)
}
this.$set(row, "enabledLoading", false)
}).catch(() => {
row.enabled = oldEnabled
this.$set(row, "enabledLoading", false)
})
}).catch(() => {
row.enabled = oldEnabled
})
},
onDelete(row) {
this.$confirm("您确定删除申诉类型“" + row.name + "”吗?", "提示", {type: "warning"}).then(() => {
this.$axios.post("/platform/appeal/type/delete", {id: row.id}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
} else {
this.$message.error(res.msg)
}
})
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,259 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<custom-card>
<snaker-start slot="header" label="提交申诉" define_key="SSGL"></snaker-start>
<el-form :model="formData" :rules="formRules" ref="formRef" label-width="130px">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="申诉人" prop="userName">
<el-input v-model="formData.userName" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="性别" prop="sex">
<el-input v-model="formData.sex" clearable maxlength="20" show-word-limit></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="出生年月" prop="birthday">
<el-date-picker v-model="formData.birthday" value-format="yyyy-MM-dd" type="date" style="width: 100%" placeholder="请选择出生年月"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="政治面貌" prop="political">
<el-input v-model="formData.political" clearable maxlength="100" show-word-limit></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="工号" prop="loginName">
<el-input v-model="formData.loginName" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所在单位" prop="unitName">
<el-input v-model="formData.unitName" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="岗位" prop="positionName">
<el-input v-model="formData.positionName" clearable maxlength="100" show-word-limit></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="联系电话" prop="mobile">
<el-input v-model="formData.mobile" clearable maxlength="100" placeholder="请输入手机或办公电话"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请日期" prop="applyDate">
<el-date-picker v-model="formData.applyDate" value-format="yyyy-MM-dd" type="date" style="width: 100%" placeholder="请选择申请日期"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="住址" prop="address">
<el-input v-model="formData.address" clearable maxlength="300" show-word-limit></el-input>
</el-form-item>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="申诉类型" prop="appealTypeId">
<el-select v-model="formData.appealTypeId" filterable clearable style="width: 100%" @change="onTypeChange">
<el-option v-for="item in typeOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="申诉标题" prop="title">
<el-input v-model="formData.title" clearable maxlength="200" show-word-limit placeholder="请输入申诉标题"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="被申诉单位" prop="defendantUnitId">
<el-select v-model="formData.defendantUnitId" filterable clearable style="width: 100%" @change="onUnitChange">
<el-option v-for="item in unitOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="被申诉单位地址" prop="defendantAddress">
<el-input v-model="formData.defendantAddress" clearable maxlength="300" show-word-limit></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="被申诉单位电话" prop="defendantContact">
<el-input v-model="formData.defendantContact" clearable maxlength="100" placeholder="请输入联系电话"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="申诉事项" prop="appealMatter">
<el-input v-model="formData.appealMatter" type="textarea" :rows="5" maxlength="1000" show-word-limit placeholder="请输入申诉事项"></el-input>
</el-form-item>
<el-form-item label="申诉理由" prop="reason">
<el-input v-model="formData.reason" type="textarea" :rows="6" maxlength="2000" show-word-limit placeholder="请输入申诉理由"></el-input>
</el-form-item>
<el-form-item label="申诉要求" prop="request">
<el-input v-model="formData.request" type="textarea" :rows="5" maxlength="1000" show-word-limit placeholder="请输入申诉要求"></el-input>
</el-form-item>
<el-form-item label="申诉人签名" prop="signature">
<pc-signature v-model="formData.signature"></pc-signature>
</el-form-item>
<el-form-item label="申诉材料附件" prop="files">
<file-upload :value.sync="formData.files" :upload_number="5" upload_mode="drag" upload_result_category="array" complete_result></file-upload>
</el-form-item>
</el-form>
<template slot="footer">
<el-button type="primary" @click="onSave">保存</el-button>
<el-button type="primary" @click="onSubmit">{{ hasTaskId() ? '提交' : '提交申诉' }}</el-button>
</template>
</custom-card>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
store,
data() {
return {
typeOptions: [],
unitOptions: [],
taskId: null,
formData: {},
formRules: {
sex: [{required: true, message: "请输入性别", trigger: "blur"}],
birthday: [{required: true, message: "请选择出生年月", trigger: "change"}],
political: [{required: true, message: "请输入政治面貌", trigger: "blur"}],
positionName: [{required: true, message: "请输入岗位", trigger: "blur"}],
mobile: [
{required: true, message: "请输入联系电话", trigger: "blur"},
{validator: this.validatePhone, trigger: "blur"}
],
applyDate: [{required: true, message: "请选择申请日期", trigger: "change"}],
address: [{required: true, message: "请输入住址", trigger: "blur"}],
appealTypeId: [{required: true, message: "请选择申诉类型", trigger: "change"}],
defendantUnitId: [{required: true, message: "请选择被申诉单位", trigger: "change"}],
defendantAddress: [{required: true, message: "请输入被申诉单位地址", trigger: "blur"}],
defendantContact: [
{required: true, message: "请输入被申诉单位电话", trigger: "blur"},
{validator: this.validatePhone, trigger: "blur"}
],
title: [{required: true, message: "请输入申诉标题", trigger: "blur"}],
appealMatter: [{required: true, validator: this.validateText, message: "请输入申诉事项", trigger: ["blur", "change"]}],
reason: [{required: true, validator: this.validateText, message: "请输入申诉理由", trigger: ["blur", "change"]}],
request: [{required: true, validator: this.validateText, message: "请输入申诉要求", trigger: ["blur", "change"]}],
signature: [{required: true, message: "请完成申诉人签名", trigger: ["blur", "change"]}],
files: [{required: true, validator: this.validateFiles, message: "请上传申诉材料附件", trigger: "change"}]
}
}
},
methods: {
validatePhone(rule, value, callback) {
if (!value) {
callback()
return
}
const reg = /^((1[3-9]\d{9})|(0\d{2,3}-?\d{7,8})|(\d{6,12}))$/
if (!reg.test(value)) {
callback(new Error("请输入正确的联系电话"))
return
}
callback()
},
validateText(rule, value, callback) {
if (!(value || "").trim()) {
callback(new Error(rule.message))
return
}
callback()
},
validateFiles(rule, value, callback) {
if (!value || !value.length) {
callback(new Error(rule.message))
return
}
callback()
},
queryParam(name) {
return new URLSearchParams(window.location.search).get(name)
},
loadOptions() {
this.$axios.post("/platform/appeal/common/typeOptions").then((res) => {
if (res.code === 0) this.typeOptions = res.data || []
})
this.$businessTool.listUnit().then((res) => {
this.unitOptions = res || []
})
},
loadCurrentUser() {
this.$axios.post("/platform/appeal/write/currentUserInfo").then((res) => {
if (res.code === 0) {
this.formData = Object.assign({}, res.data, this.formData)
}
})
},
loadInfo(id) {
this.$axios.post("/platform/appeal/write/info", {id}).then((res) => {
if (res.code === 0 && res.data) {
this.formData = res.data
}
})
},
onTypeChange(val) {
const item = this.typeOptions.find((type) => type.id === val)
this.$set(this.formData, "appealTypeName", item ? item.name : "")
},
onUnitChange(val) {
const item = this.unitOptions.find((unit) => unit.id === val)
this.$set(this.formData, "defendantUnitName", item ? item.name : "")
this.$set(this.formData, "defendantAddress", item ? item.address : this.formData.defendantAddress)
this.$set(this.formData, "defendantContact", item ? item.telephone : this.formData.defendantContact)
},
onSave() {
this.$axios.post("/platform/appeal/write/save", {data: JSON.stringify(this.formData)}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.formData = res.data
}
})
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (!valid) return
const url = this.hasTaskId() ? "/platform/appeal/write/submitAgain" : "/platform/appeal/write/submit"
this.$confirm("您确定提交该申诉吗?", "提示", {type: "warning"}).then(() => {
this.$axios.post(url, {data: JSON.stringify(this.formData), taskId: this.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
window.location.href = "/platform/appeal/mine"
}
})
})
})
},
hasTaskId() {
return !!this.taskId && this.taskId !== "undefined" && this.taskId !== "null"
}
},
created() {
this.taskId = this.queryParam("taskId")
const id = this.queryParam("id")
this.loadOptions()
if (id) {
this.loadInfo(id)
} else {
this.loadCurrentUser()
}
}
})
</script>
<!--#
}
#-->
@@ -10,12 +10,12 @@ layout("/layouts/platform.html"){
<table-tool label="子女信息"></table-tool>
<el-descriptions :column="2" border>
<el-descriptions-item label="就读年级">
<el-form-item prop="childRelationship">
<dict-select v-model="formData.childRelationship" code="CHILD_MANAGE_GRADE" style="width: 100%" placeholder="请选择就读年级">
<el-form-item prop="childrenGrade">
<dict-select v-model="formData.childrenGrade" code="CHILD_MANAGE_GRADE" style="width: 100%" placeholder="请选择就读年级">
</dict-select>
</el-form-item></el-descriptions-item>
<el-descriptions-item label="入学年份">
<el-form-item prop="childrenBirthday">
<el-form-item prop="childrenYear">
<el-date-picker
v-model="formData.childrenYear"
type="year"
@@ -146,7 +146,7 @@ layout("/layouts/platform.html"){
bizId: GetQueryString("bizId"),
formData: {},
formRules: {
childRelationship: [{ required: true, message: '请选择就读年级', trigger: 'change' }],
childrenGrade: [{ required: true, message: '请选择就读年级', trigger: 'change' }],
childrenYear: [{ required: true, message: '请选择入学年份', trigger: 'change' }],
childrenName: [{ required: true, message: '请输入子女姓名', trigger: 'blur' }],
childrenIdCard: [{ required: true, message: '请输入子女身份证号', trigger: 'blur' }, {pattern: /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/, message: '请输入正确的身份证号码', trigger: 'blur'}],
@@ -220,6 +220,7 @@ layout("/layouts/platform.html"){
unionId: union.id,
mobile: mobile,
// 自动填充监护人1信息
guardianUserId1: id,
guardianUserName1: username,
guardianLoginName1: loginname,
guardianMobile1: mobile,
@@ -21,8 +21,8 @@ const INFO = {
<el-descriptions-item label="学位">{{ viewData.academicDegree }}</el-descriptions-item>
<el-descriptions-item label="党政职务">{{ viewData.position }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitname }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionname }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="所属校区">{{ viewData.campus }}</el-descriptions-item>
<el-descriptions-item label="身份证号码">{{ viewData.idCard }}</el-descriptions-item>
@@ -51,26 +51,26 @@ const INFO = {
<el-descriptions-item></el-descriptions-item>
<!-- <template v-if="viewData.loginname == $store.state.user.loginname">-->
<template>
<template v-if="viewData.loginname == $store.state.user.loginname">
<el-descriptions-item label="家庭主要成员" :span="3">
<el-table v-if="viewData.families&&viewData.families.length"
:data="viewData.families" size="mini" border
:header-cell-style="{background:'#eff3f6'}"
style="width: 100%">
<el-table-column prop="relation" label="与本人关系" align="center"
<el-table-column prop="relation" label="关系" align="center"
header-align="center">
</el-table-column>
<el-table-column prop="name" label="姓名" align="center" header-align="center">
</el-table-column>
<el-table-column prop="unit" label="单位" align="center" header-align="center">
<el-table-column prop="unit" label="工作单位" align="center" header-align="center">
</el-table-column>
<el-table-column prop="remark" label="备注" align="center" header-align="center">
</el-table-column>
</el-table>
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<template slot="label">个人简况</template>
<el-descriptions-item label="个人简历" :span="3">
<template slot="label">个人简历</template>
<div v-if="viewData.personalData" class="text-left" v-html="viewData.personalData"></div>
<span v-else>无数据</span>
</el-descriptions-item>
@@ -15,8 +15,8 @@ const MEMBER_ALL_CHANGE_INFO = {
<el-descriptions-item label="学位">{{ viewData.academicDegree }}</el-descriptions-item>
<el-descriptions-item label="党政职务">{{ viewData.position }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitname }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionname }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="所属校区">{{ viewData.campus }}</el-descriptions-item>
<el-descriptions-item label="身份证号码">{{ viewData.idCard }}</el-descriptions-item>
@@ -56,7 +56,7 @@ const MEMBER_ALL_CHANGE_INFO = {
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<template slot="label">个人简况</template>
<div v-if="viewData.vita" class="text-left" v-html="viewData.vita"></div>
<div v-if="viewData.personalData" class="text-left" v-html="viewData.personalData"></div>
<span v-else>无数据</span>
</el-descriptions-item>
</template>
@@ -350,9 +350,11 @@ const MEMBER_CHANGE = {
},
methods: {
getUnionName(val){
debugger
const data = this.units.find(v => v.id === val)
this.$set(this.formData, 'unionName', data ? data.unionName : '')
// 选择工作单位后,同步保存单位名称和所属工会信息,避免变更记录快照不一致。
this.$set(this.formData, 'unitName', data ? data.name : null)
this.$set(this.formData, 'unionId', data ? (data.unionId || data.unionid) : null)
this.$set(this.formData, 'unionName', data ? (data.unionName || data.unionname) : '')
},
allowFields(prop) {
return !this.allowChangeFields.map(v => v.code).includes(prop)
@@ -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: "curTaskName", label: "当前节点"},
{ prop: "taskName", label: "当前节点"},
{ prop: "instanceState", label: "流程状态"}
],
changeTypeData: [],
@@ -428,7 +428,10 @@
},
getUnionName(val){
const data = this.units.find(v => v.id === val)
this.$set(this.formData, 'unionName', data ? data.unionname : '')
// 选择工作单位后,同步保存单位名称和所属工会信息,避免变更记录快照不一致。
this.$set(this.formData, 'unitName', data ? data.name : null)
this.$set(this.formData, 'unionId', data ? (data.unionId || data.unionid) : null)
this.$set(this.formData, 'unionName', data ? (data.unionName || data.unionname) : '')
},
allowFields(prop) {
return !this.allowChangeFields.map(v => v.code).includes(prop)
@@ -427,7 +427,10 @@ layout("/layouts/platform.html"){
// 获取表单工会名称
getUnionName(val){
const data = this.units.find(v => v.id === val)
this.$set(this.formData, 'unionName', data ? data.unionName : '')
// 选择工作单位后,同步保存单位名称和所属工会信息,避免变更记录快照不一致。
this.$set(this.formData, 'unitName', data ? data.name : null)
this.$set(this.formData, 'unionId', data ? (data.unionId || data.unionid) : null)
this.$set(this.formData, 'unionName', data ? (data.unionName || data.unionname) : '')
},
// 获取表单可编辑的字段信息
allowFields(prop) {
@@ -14,8 +14,8 @@
<el-descriptions-item label="学位">{{ viewData.academicDegree }}</el-descriptions-item>
<el-descriptions-item label="党政职务">{{ viewData.position }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitname }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionname }}</el-descriptions-item>
<el-descriptions-item label="工作单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="所属工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="所属校区">{{ viewData.campus }}</el-descriptions-item>
<el-descriptions-item label="身份证号码">{{ viewData.idCard }}</el-descriptions-item>
@@ -54,7 +54,7 @@
</el-descriptions-item>
<el-descriptions-item label="个人简况" :span="3">
<template slot="label">个人简况</template>
<div v-if="viewData.vita" class="text-left" v-html="viewData.vita"></div>
<div v-if="viewData.personalData" class="text-left" v-html="viewData.personalData"></div>
<span v-else>无数据</span>
</el-descriptions-item>
</el-descriptions>
@@ -0,0 +1,136 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" class="platform" v-cloak>
<guava ref="guava" padding="0 5%">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="yearChange"></el-date-picker>
</search-item>
<search-item label="任务名称">
<el-select v-model="pageForm.checkTaskId"
clearable
filterable
placeholder="请选择任务"
style="width: 100%"
@change="doSearch">
<el-option v-for="item in taskOptions"
:key="item.id"
:label="item.taskName"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId"
clearable
filterable
placeholder="请选择所属工会"
style="width: 100%"
@change="doSearch">
<el-option v-for="item in unions"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="工会确认情况统计"></table-tool>
<el-table :data="tableData"
:size="tableSize"
row-key="unionId"
style="width: 100%"
v-loading="tableLoading"
ref="table"
class="vi-table">
<el-table-column type="index" :index="indexMethod" label="序号" width="80px" align="center" header-align="center"></el-table-column>
<el-table-column prop="unionName" label="工会名称" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="totalCount" label="总人数" align="center" header-align="center"></el-table-column>
<el-table-column prop="confirmedCount" label="已确认人数" align="center" header-align="center"></el-table-column>
<el-table-column prop="unconfirmedCount" label="未确认人数" align="center" header-align="center"></el-table-column>
<el-table-column prop="completeStatus" label="确认完成状态" align="center" header-align="center"></el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageForm: {
year: moment().format("YYYY"),
checkTaskId: "",
unionId: ""
},
unions: [],
taskOptions: []
}
},
methods: {
yearChange() {
return $.get("/platform/member/check/confirm/listEnabledTask", {year: this.pageForm.year}).then((resp) => {
if (resp.code === 0) {
this.taskOptions = resp.data || []
if (this.taskOptions.length > 0 && !this.pageForm.checkTaskId) {
this.$set(this.pageForm, "checkTaskId", this.taskOptions[0].id)
}
if (this.taskOptions.length === 0) {
this.$set(this.pageForm, "checkTaskId", "")
}
this.doSearch()
} else {
this.notifyError(resp.msg)
}
})
},
pageData() {
if (!this.pageForm.year || !this.pageForm.checkTaskId) {
this.tableData = []
this.$set(this.pageForm, "totalCount", 0)
return Promise.resolve()
}
this.tableLoading = true
return $.post("/platform/member/check/confirm/pageData", this.pageForm).then((resp) => {
if (resp.code === 0) {
this.tableData = resp.data.list || []
this.$set(this.pageForm, "totalCount", resp.data.totalCount || 0)
} else {
this.notifyError(resp.msg)
}
}).always(() => {
this.tableLoading = false
})
},
doSearch() {
this.$set(this.pageForm, "pageNumber", 1)
return this.pageData()
}
},
created() {
this.$businessTool.listUnion().then((res) => {
this.unions = res
if (!this.pageForm.unionId && this.unions && this.unions.length === 1) {
this.$set(this.pageForm, "unionId", this.unions[0].id)
}
})
this.yearChange()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,513 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" class="platform" v-cloak>
<guava ref="guava" padding="0 5%">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="yearChange"></el-date-picker>
</search-item>
<search-item label="任务名称">
<el-select v-model="pageForm.checkTaskId"
placeholder="请选择任务"
clearable
filterable
style="width: 100%"
@change="doSearch">
<el-option v-for="item in taskOptions"
:key="item.id"
:label="item.taskName"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="姓名/工号">
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入姓名或工号"></el-input>
</search-item>
<search-item label="所属工会" v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN'])">
<el-select v-model="pageForm.unionIds"
placeholder="请选择所属工会"
clearable
filterable
style="width: 100%"
@change="flushUnits"
@clear="flushUnits">
<el-option v-for="item in unions"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select v-model="pageForm.unitIds"
placeholder="请选择所属单位"
clearable
filterable
multiple
collapse-tags
style="width: 100%">
<el-option v-for="item in units"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="确认状态">
<el-select v-model="pageForm.audit" placeholder="请选择确认状态" clearable style="width: 100%">
<el-option label="已确认" :value="true"></el-option>
<el-option label="未确认" :value="false"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="人员名单">
<el-button type="primary" size="small" @click="openImport">导入名单</el-button>
<el-button type="primary" size="small" @click="openAddUser">添加人员</el-button>
<el-button type="primary" size="small" @click="exportData">导出</el-button>
<el-button type="primary" size="small" :disabled="!pageForm.checkTaskId" @click="doAuditByUnion(true)">按工会确认</el-button>
<el-button type="danger" size="small" :disabled="!pageForm.checkTaskId" @click="doAuditByUnion(false)">按工会取消确认</el-button>
<el-button type="primary" size="small" :disabled="selectedIds.length === 0" @click="doConfirmSelected(true)">勾选确认</el-button>
<el-button type="danger" size="small" :disabled="selectedIds.length === 0" @click="doConfirmSelected(false)">勾选取消确认</el-button>
<el-button type="danger" size="small" :disabled="selectedIds.length === 0" @click="deleteSelected">批量删除</el-button>
</table-tool>
<el-table :data="tableData"
style="width: 100%"
row-key="id"
:size="tableSize"
v-loading="tableLoading"
@selection-change="handleSelectionChange"
@sort-change="pageOrder"
ref="table"
class="vi-table">
<el-table-column type="selection" width="55" align="center" header-align="center"></el-table-column>
<el-table-column type="index" :index="indexMethod" label="序号" width="80px" align="center" header-align="center"></el-table-column>
<el-table-column prop="loginname" label="工号" align="center" header-align="center"></el-table-column>
<el-table-column prop="username" label="姓名" align="center" header-align="center"></el-table-column>
<el-table-column prop="sex" label="性别" align="center" header-align="center"></el-table-column>
<el-table-column prop="unionName" label="所属工会" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="unitName" label="所属单位" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="taskName" label="任务名称" min-width="180px" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="mobile" label="手机号" align="center" header-align="center"></el-table-column>
<el-table-column prop="idCard" label="身份证号" min-width="170px" align="center" header-align="center"></el-table-column>
<el-table-column prop="branchUnionChecked" label="确认状态" align="center" header-align="center">
<template slot-scope="{row}">
<el-tag type="success" v-if="row.branchUnionChecked">已确认</el-tag>
<el-tag type="info" v-else>未确认</el-tag>
</template>
</el-table-column>
<el-table-column prop="auditTime" label="确认时间" min-width="160px" align="center" header-align="center"></el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</guava>
<el-dialog title="添加人员" :visible.sync="addUserVisible" width="80%" :close-on-click-modal="false">
<el-card shadow="never">
<search @search="addUserDoSearch">
<search-item label="姓名">
<el-input v-model="addUserPageForm.userName" @keyup.enter.native="addUserDoSearch" clearable placeholder="请输入姓名"></el-input>
</search-item>
<search-item label="工号">
<el-input v-model="addUserPageForm.loginName" @keyup.enter.native="addUserDoSearch" clearable placeholder="请输入工号"></el-input>
</search-item>
<search-item label="性别">
<el-select v-model="addUserPageForm.sexTypes" clearable multiple collapse-tags placeholder="请选择性别" style="width: 100%">
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</search-item>
<search-item label="出生开始">
<el-date-picker v-model="addUserPageForm.birthdayStartDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择出生开始"
style="width: 100%"></el-date-picker>
</search-item>
<search-item label="出生结束">
<el-date-picker v-model="addUserPageForm.birthdayEndDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择出生结束"
style="width: 100%"></el-date-picker>
</search-item>
<search-item label="所属工会" v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN'])">
<el-select v-model="addUserPageForm.unionIds"
clearable
filterable
placeholder="请选择所属工会"
style="width: 100%"
@change="addUserUnionChange"
@clear="addUserUnionChange">
<el-option v-for="item in addUserUnionOptions"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select v-model="addUserPageForm.unitIds"
clearable
filterable
multiple
collapse-tags
placeholder="请选择所属单位"
style="width: 100%">
<el-option v-for="item in addUserUnitOptions"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="人员类型">
<dict-select clearable
code="USER_PERSON_TYPE"
multiple
collapse-tags
placeholder="请选择人员类型"
v-model="addUserPageForm.personTypes"></dict-select>
</search-item>
<search-item label="在职状态">
<dict-select clearable
code="USER_STATE"
multiple
collapse-tags
placeholder="请选择人员状态"
v-model="addUserPageForm.userStates"></dict-select>
</search-item>
<search-item label="是否会员">
<el-select v-model="addUserPageForm.isMember" clearable placeholder="请选择是否会员" style="width: 100%">
<el-option label="是" :value="true"></el-option>
<el-option label="否" :value="false"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<el-table :data="addUserTableData"
:size="tableSize"
row-key="id"
v-loading="addUserTableLoading"
style="width: 100%">
<el-table-column type="index" :index="addUserIndexMethod" label="序号" width="80px" align="center"></el-table-column>
<el-table-column prop="loginname" label="工号" align="center" header-align="center"></el-table-column>
<el-table-column prop="username" label="姓名" align="center" header-align="center"></el-table-column>
<el-table-column prop="sex" label="性别" align="center" header-align="center"></el-table-column>
<el-table-column prop="birthday" label="出生日期" align="center" header-align="center"></el-table-column>
<el-table-column prop="personType" label="人员类型" align="center" header-align="center"></el-table-column>
<el-table-column prop="userState" label="在职状态" align="center" header-align="center"></el-table-column>
<el-table-column prop="unionName" label="所属工会" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="unitName" label="所属单位" align="center" header-align="center" show-overflow-tooltip></el-table-column>
</el-table>
<div class="mt10 text-right">
<el-pagination background
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="addUserPageForm.pageNumber"
:page-size.sync="addUserPageForm.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="addUserPageForm.totalCount || 0"
@size-change="addUserPageData"
@current-change="addUserPageData"></el-pagination>
</div>
</el-card>
<template slot="footer">
<el-button @click="addUserVisible=false">取消</el-button>
<el-button type="primary" @click="submitAddUser">确定</el-button>
</template>
</el-dialog>
<excel-import
ref="excelImportRef"
url="/platform/member/check/roster/importCheckUser"
template_url="/platform/member/check/roster/downloadTem"
:visible.sync="importVisible"
title="导入人员名单"
width="700px"
:extra_params="{checkTaskId:pageForm.checkTaskId}"
@import-success="doSearch"
></excel-import>
</div>
<script nonce="${cspNonce!}">
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageForm: {
year: moment().format("YYYY"),
checkTaskId: "",
searchKeyword: "",
unionIds: "",
unitIds: [],
audit: null
},
unions: [],
units: [],
taskOptions: [],
selectedIds: [],
importVisible: false,
addUserVisible: false,
addUserTableLoading: false,
addUserTableData: [],
addUserUnionOptions: [],
addUserUnitOptions: [],
addUserPageForm: {}
}
},
methods: {
handleSelectionChange(rows) {
this.selectedIds = rows.map(function (item) {
return item.id
})
},
yearChange() {
return $.get("/platform/member/check/roster/listEnabledTask", {year: this.pageForm.year}).then((resp) => {
if (resp.code === 0) {
this.taskOptions = resp.data || []
if (this.taskOptions.length > 0 && !this.pageForm.checkTaskId) {
this.$set(this.pageForm, "checkTaskId", this.taskOptions[0].id)
}
if (this.taskOptions.length === 0) {
this.$set(this.pageForm, "checkTaskId", "")
}
this.doSearch()
} else {
this.notifyError(resp.msg)
}
})
},
pageData() {
this.tableLoading = true
return $.post("/platform/member/check/roster/pageData", {
pageForm: JSON.stringify(this.pageForm)
}).then((resp) => {
if (resp.code === 0) {
this.tableData = resp.data.list || []
this.$set(this.pageForm, "totalCount", resp.data.totalCount || 0)
this.selectedIds = []
} else {
this.notifyError(resp.msg)
}
}).always(() => {
this.tableLoading = false
})
},
doSearch() {
this.$set(this.pageForm, "pageNumber", 1)
return this.pageData()
},
flushUnits() {
this.$set(this.pageForm, "unitIds", [])
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
this.$businessTool.listUnit(this.pageForm.unionIds).then((res) => {
this.units = res
})
} else {
this.$businessTool.listUnit().then((res) => {
this.units = res
})
}
this.doSearch()
},
openImport() {
if (!this.pageForm.checkTaskId) {
this.notifyWarning("请先选择任务")
return
}
this.importVisible = true
},
resetAddUserPageForm() {
this.addUserPageForm = {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
checkTaskId: "",
userName: "",
loginName: "",
sexTypes: [],
birthdayStartDate: "",
birthdayEndDate: "",
unionIds: "",
unitIds: [],
personTypes: [],
userStates: [],
isMember: null
}
this.addUserTableData = []
},
openAddUser() {
if (!this.pageForm.checkTaskId) {
this.notifyWarning("请先选择任务")
return
}
this.resetAddUserPageForm()
this.$set(this.addUserPageForm, "checkTaskId", this.pageForm.checkTaskId)
this.addUserVisible = true
this.$businessTool.listUnion().then((res) => {
this.addUserUnionOptions = res
})
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
this.$businessTool.listUnit(this.addUserPageForm.unionIds).then((res) => {
this.addUserUnitOptions = res
})
} else {
this.$businessTool.listUnit().then((res) => {
this.addUserUnitOptions = res
})
}
this.addUserPageData()
},
addUserUnionChange() {
this.$set(this.addUserPageForm, "unitIds", [])
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
this.$businessTool.listUnit(this.addUserPageForm.unionIds).then((res) => {
this.addUserUnitOptions = res
})
}
},
addUserPageData() {
this.addUserTableLoading = true
return $.post("/platform/member/check/roster/notCheckUserPageData", {
pageForm: JSON.stringify(this.addUserPageForm)
}).then((resp) => {
if (resp.code === 0) {
this.addUserTableData = resp.data.list || []
this.$set(this.addUserPageForm, "totalCount", resp.data.totalCount || 0)
} else {
this.notifyError(resp.msg)
}
}).always(() => {
this.addUserTableLoading = false
})
},
addUserDoSearch() {
this.$set(this.addUserPageForm, "pageNumber", 1)
this.addUserPageData()
},
addUserIndexMethod(index) {
return (this.addUserPageForm.pageNumber - 1) * this.addUserPageForm.pageSize + index + 1
},
submitAddUser() {
if (!this.pageForm.checkTaskId) {
this.notifyWarning("请先选择任务")
return
}
this.$set(this.addUserPageForm, "checkTaskId", this.pageForm.checkTaskId)
this.$confirm("当前筛选出" + (this.addUserPageForm.totalCount || 0) + "条数据,确认添加到人员名单吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
const loading = this.$loading({
lock: true,
text: "数据保存中,请稍后...",
spinner: "el-icon-loading"
})
$.post("/platform/member/check/roster/addCheckUser", {
pageForm: JSON.stringify(this.addUserPageForm)
}).then((resp) => {
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.addUserVisible = false
this.doSearch()
} else {
this.notifyError(resp.msg)
}
}).always(() => {
loading.close()
})
})
},
doAuditByUnion(flag) {
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"]) && !this.pageForm.unionIds) {
this.notifyWarning("请选择需要确认的分工会")
return
}
const msg = flag ? "确定按当前任务和分工会确认名单吗?" : "确定按当前任务和分工会取消确认吗?"
this.$confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
$.post("/platform/member/check/roster/doConfirmUser", {
checkTaskId: this.pageForm.checkTaskId,
unionId: this.pageForm.unionIds,
flag: flag
}).then((resp) => {
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.doSearch()
} else {
this.notifyError(resp.msg)
}
})
})
},
doConfirmSelected(flag) {
const msg = flag ? "确定确认勾选人员吗?" : "确定取消确认勾选人员吗?"
this.$confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
$.post("/platform/member/check/roster/doConfirmSelected", {
ids: this.selectedIds.join(","),
flag: flag
}).then((resp) => {
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.doSearch()
} else {
this.notifyError(resp.msg)
}
})
})
},
deleteSelected() {
this.$confirm("确认删除勾选人员吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
$.post("/platform/member/check/roster/deleteSelected", {
ids: this.selectedIds.join(",")
}).then((resp) => {
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.doSearch()
} else {
this.notifyError(resp.msg)
}
})
})
},
exportData() {
const form = JSON.stringify(this.pageForm)
window.open("/platform/member/check/roster/exportCheckUser?pageForm=" + encodeURIComponent(form))
}
},
created() {
this.$businessTool.listUnion().then((res) => {
this.unions = res
if (!this.pageForm.unionIds && this.unions && this.unions.length === 1) {
this.$set(this.pageForm, "unionIds", this.unions[0].id)
}
})
this.flushUnits()
this.yearChange()
}
})
</script>
<!--#
}
#-->
@@ -1,28 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
</guava>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: '#app',
data() {
return{
}
},
methods: {
},
created() {
}
})
</script>
<!--#
}
#-->
@@ -1,25 +1,215 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"></el-date-picker>
</search-item>
<search-item label="任务名称">
<el-input v-model="pageForm.taskName" placeholder="请输入任务名称查询" clearable></el-input>
</search-item>
<!-- <search-item label="发布状态">-->
<!-- <el-select v-model="pageForm.isEnabled" placeholder="请选择发布状态" clearable style="width: 100%">-->
<!-- <el-option label="已发布" :value="true"></el-option>-->
<!-- <el-option label="未发布" :value="false"></el-option>-->
<!-- </el-select>-->
<!-- </search-item>-->
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="任务列表">
<el-button size="small" type="primary" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData"
row-key="id"
:size="tableSize"
v-loading="tableLoading"
class="vi-table">
<el-table-column type="index" width="80px" label="序号" :index="indexMethod" align="center" header-align="center"></el-table-column>
<el-table-column prop="taskName" label="任务名称" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="year" label="年度" align="center" header-align="center"></el-table-column>
<el-table-column prop="startTime" label="开始时间" align="center" header-align="center" min-width="160px"></el-table-column>
<el-table-column prop="endTime" label="结束时间" align="center" header-align="center" min-width="160px"></el-table-column>
<el-table-column prop="isEnabled" label="是否发布" align="center" header-align="center">
<template slot-scope="{row}">
<el-switch v-model="row.isEnabled"
active-color="#13ce66"
inactive-color="#ff4949"
@change="switchChange(row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180px" fixed="right" align="center" header-align="center">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
<el-button size="mini" type="danger" @click="onDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="100px" :rules="rules">
<el-form-item label="任务名称" prop="taskName">
<el-input v-model="formData.taskName" maxlength="20" placeholder="请输入任务名称"></el-input>
</el-form-item>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker v-model="formData.startTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择开始时间"
style="width: 100%"></el-date-picker>
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker v-model="formData.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择结束时间"
style="width: 100%"></el-date-picker>
</el-form-item>
<el-form-item label="内容详情" prop="description">
<el-input v-model="formData.description" type="textarea" :rows="5" placeholder="请输入内容详情"></el-input>
</el-form-item>
<!-- <el-form-item label="是否发布" prop="isEnabled">-->
<!-- <el-switch v-model="formData.isEnabled" active-color="#13ce66" inactive-color="#ff4949"></el-switch>-->
<!-- </el-form-item>-->
</el-form>
<template slot="footer">
<el-button @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</template>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: '#app',
data() {
return{
}
},
methods: {
},
created() {
}
})
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
computed: {
dialogTitle() {
return this.formData.id ? "编辑任务" : "新增任务"
}
},
data() {
return {
pageForm: {
year: moment().format("YYYY"),
taskName: "",
isEnabled: null
},
dialogVisible: false,
formData: {
taskName: "",
startTime: "",
endTime: "",
description: "",
isEnabled: true
},
rules: {
taskName: [{required: true, message: "请输入任务名称", trigger: ["change", "blur"]}],
startTime: [{required: true, message: "请选择开始时间", trigger: ["change", "blur"]}],
endTime: [{required: true, message: "请选择结束时间", trigger: ["change", "blur"]}],
description: [{required: true, message: "请输入内容详情", trigger: ["change", "blur"]}]
}
}
},
methods: {
pageData() {
this.tableLoading = true
return $.post("/platform/member/check/task/pageData", this.pageForm).then((resp) => {
if (resp.code === 0) {
this.tableData = resp.data.list || []
this.$set(this.pageForm, "totalCount", resp.data.totalCount || 0)
} else {
this.notifyError(resp.msg)
}
}).always(() => {
this.tableLoading = false
})
},
doSearch() {
this.$set(this.pageForm, "pageNumber", 1)
return this.pageData()
},
openAdd() {
this.formData = {
taskName: "",
startTime: "",
endTime: "",
description: "",
isEnabled: true
}
this.dialogVisible = true
this.$nextTick(() => {
this.$refs.formRef.clearValidate()
})
},
openEdit(row) {
$.get("/platform/member/check/task/findOne", {id: row.id}).then((resp) => {
if (resp.code === 0) {
this.formData = Object.assign({}, resp.data)
this.dialogVisible = true
} else {
this.notifyError(resp.msg)
}
})
},
submitForm() {
this.$refs.formRef.validate((valid) => {
if (!valid) {
return
}
$.post("/platform/member/check/task/doAddOrModify", {
data: JSON.stringify(this.formData)
}).then((resp) => {
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.dialogVisible = false
this.doSearch()
} else {
this.notifyError(resp.msg)
}
})
})
},
switchChange(row) {
$.post("/platform/member/check/task/switchChange", row).then((resp) => {
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.pageData()
} else {
this.notifyError(resp.msg)
}
})
},
onDelete(id) {
this.$confirm("确认删除该任务及其人员名单吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
$.post("/platform/member/check/task/delete", {id: id}).then((resp) => {
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.doSearch()
} else {
this.notifyError(resp.msg)
}
})
}).catch(() => {})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
@@ -1,26 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
</div>
<script nonce="${cspNonce!}">
new Vue({
el: '#app',
data() {
return{
}
},
methods: {
},
created() {
}
})
</script>
<!--#
}
#-->
@@ -112,6 +112,7 @@ layout("/layouts/platform.html"){
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
@@ -169,7 +169,8 @@ const selectView = {
selectedOptions: [],
detailVisible: false,
currentOption: null,
activeNames:[]
activeNames:[],
defaultWelfareImage: "/assets/platform/img/v4/not-image.png"
}
},
computed: {
@@ -179,7 +180,7 @@ const selectView = {
return {
...item,
optionName: option.optionName || "未知选项",
imgUrl: option.imgUrl,
imgUrl: option.imgUrl || this.defaultWelfareImage,
description: option.description
}
})
@@ -267,7 +268,11 @@ const selectView = {
},
handleImageError(e) {
e.target.src = "/static/images/default-welfare.png"
// 兜底图加载失败时不再重复替换,避免控制台持续刷 404。
if (!e || !e.target || e.target.src.indexOf(this.defaultWelfareImage) > -1) {
return
}
e.target.src = this.defaultWelfareImage
},
formatDate(dateStr) {