提案流程

This commit is contained in:
2026-10-09 10:06:08 +08:00
parent fc39bc8020
commit aff992faf0
55 changed files with 1150 additions and 708 deletions
@@ -62,7 +62,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool :label="pageForm.pullTime ? pageForm.pullTime + '数据' : '全部数据'">
<el-button type="primary" size="mini" :loading="pullLoading" @click="pull" icon="el-icon-download">拉取信息中心数据</el-button>
<el-button type="primary" size="mini" :loading="pullLoading" @click="pull" icon="el-icon-download">拉取本地中间表数据</el-button>
<el-button type="danger" size="mini" @click="openDelete" icon="el-icon-delete">删除本地数据源</el-button>
</table-tool>
<el-table :key="tableKey" :data="tableData" @sort-change="pageOrder" header-align="center" v-loading="tableLoading">
@@ -124,7 +124,7 @@ layout("/layouts/platform.html"){
},
methods: {
pull() {
this.$confirm("确定要拉取数据源吗?", "提示", {
this.$confirm("确定从本地中间表更新单位并拉取人员数据源吗?", "提示", {
type: "warning",
confirmButtonText: "确定",
cancelButtonText: "取消"
@@ -12,7 +12,6 @@ const PROPOSAL_INFO = {
</h3>
<el-descriptions :column="3" border>
<el-descriptions-item label="提案编号">{{ viewData.code }}</el-descriptions-item>
<el-descriptions-item label="立案编号">{{ viewData.caseFilingCode || '暂无' }}</el-descriptions-item>
<el-descriptions-item label="提案人">{{viewData.createUserName }}</el-descriptions-item>
<el-descriptions-item label="提案时间">{{ viewData.createTime }}</el-descriptions-item>
<el-descriptions-item label="教代会届次"> {{ viewData.sessionName || '暂无' }}</el-descriptions-item>
@@ -215,7 +214,7 @@ const PROPOSAL_INFO = {
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="承办单位"
v-if="['opinion_unit_reply','unit_reply','two_unit_reply','master_reply','slave_reply'].includes(task.taskName)" :span="3">
v-if="['opinion_unit_reply','unit_reply','two_unit_reply','opinion_master_reply','master_reply','slave_reply'].includes(task.taskName)" :span="3">
{{task.ext.underTakeName}}
</el-descriptions-item>
@@ -359,7 +358,7 @@ const PROPOSAL_INFO = {
* @return 仅用于查看页面的展示数组;原始任务及每条答复内容均保存在 replyTasks 中
*/
groupReplyTasks(tasks) {
const replyTaskNames = ["opinion_unit_reply", "unit_reply", "two_unit_reply", "master_reply", "slave_reply"]
const replyTaskNames = ["opinion_unit_reply", "unit_reply", "two_unit_reply", "opinion_master_reply", "master_reply", "slave_reply"]
const replyTasks = (tasks || []).filter((task) => replyTaskNames.includes(task.taskName))
if (!replyTasks.length) {
return tasks || []
@@ -384,8 +383,7 @@ const PROPOSAL_INFO = {
/**
* 获取提案任务所属的展示阶段。
* 未单列的预审核、委员审议、确认承办单位和复核记录统一放在委员会立案阶段,
* 答复后的校领导审批通过 legacyStage 标识排在承办单位答复之后。
* 按当前 WF 节点顺序展示两级主席审核、立案、答复、校领导审批和评价。
*
* @param task 单条已办任务
* @return 数字类型的阶段顺序
@@ -397,8 +395,9 @@ const PROPOSAL_INFO = {
if (taskName === "invite") return 15
if (taskName === "second") return 20
if (taskName === "delegation") return 30
if (["opinion_unit_reply", "unit_reply", "two_unit_reply", "master_reply", "slave_reply"].includes(taskName)) return 50
if (taskName === "schoolLeader" && legacyStage === "replyLeaderAudit") return 55
if (taskName === "schoolUnionChairApproval") return 35
if (["opinion_unit_reply", "unit_reply", "two_unit_reply", "opinion_master_reply", "master_reply", "slave_reply"].includes(taskName)) return 50
if (taskName === "school_leader" || taskName === "schoolLeader" && legacyStage === "replyLeaderAudit") return 55
if (taskName === "feedback") return 60
return 40
},
@@ -27,12 +27,12 @@ layout("/layouts/platform.html"){
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
<el-table-column prop="name" label="单位名称" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column prop="code" label="单位编码" sortable="custom" width="150px"></el-table-column>
<!-- <el-table-column prop="branchSchoolLeader" label="分管校领导及联系方式" width="180px"></el-table-column>-->
<el-table-column prop="unitLeader" label="单位领导" sortable="custom" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="350px">
<el-table-column prop="branchSchoolLeader" label="单位分管校领导" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column prop="unitLeader" label="单位负责人" sortable="custom" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="390px">
<template slot-scope="{row}">
<!-- <el-button size="mini" type="primary" @click="$refs.userRef.onOpen(row.id,true)">设置分管校领导</el-button>-->
<el-button size="mini" type="primary" @click="$refs.userRef.onOpen(row.id,false)">设置单位领导</el-button>
<el-button size="mini" type="primary" @click="$refs.userRef.onOpen(row.id,false)">设置负责人</el-button>
<el-button size="mini" type="primary" @click="$refs.userRef.onOpen(row.id,true)">设置校领导</el-button>
<el-button size="mini" type="danger" @click="onDelete(row)">删除</el-button>
</template>
</el-table-column>
@@ -1,6 +1,6 @@
const USER_COMPONENT = {
template: `
<el-dialog title="设置领导" :visible.sync="visible" width="1000px" :close-on-click-modal="false">
<el-dialog :title="isSchoolLeader ? '设置校领导' : '设置负责人'" :visible.sync="visible" width="1000px" :close-on-click-modal="false">
<el-transfer
ref="transferRef"
:titles="['可选人员', '已选人员']"
@@ -25,7 +25,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -186,7 +185,6 @@ layout("/layouts/platform.html"){
},
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
@@ -23,7 +23,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -123,7 +122,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName"},
{label: "代表团", prop: "delegationName"},
@@ -265,7 +265,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
@@ -308,10 +307,6 @@ layout("/layouts/platform.html"){
{
label: '提案人',
value: 'createUserName'
},
{
label: '立案编号',
value: 'caseFilingCode'
}
]
}
@@ -23,7 +23,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -70,7 +69,6 @@ layout("/layouts/platform.html"){
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="立案编号" prop="caseFilingCode" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
@@ -21,7 +21,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -55,7 +54,6 @@ layout("/layouts/platform.html"){
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="立案编号" prop="caseFilingCode" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
@@ -113,11 +111,6 @@ layout("/layouts/platform.html"){
<el-input maxlength="100" placeholder="提案编号" v-model="formData.code"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="立案编号" prop="caseFilingCode">
<el-input maxlength="100" placeholder="立案编号" v-model="formData.caseFilingCode"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
@@ -19,7 +19,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -49,7 +48,6 @@ layout("/layouts/platform.html"){
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="立案编号" prop="caseFilingCode" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
@@ -19,7 +19,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -132,7 +131,6 @@ layout("/layouts/platform.html"){
tableColumns: [
{prop: 'code', label: '提案编号'},
{prop: 'caseFilingCode', label: '立案编号'},
{prop: 'name', label: '提案名称'},
{prop: 'typeName', label: '提案类别'},
{prop: 'delegationName', label: '代表团'},
@@ -21,7 +21,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -55,7 +54,6 @@ layout("/layouts/platform.html"){
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="立案编号" prop="caseFilingCode" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
@@ -19,7 +19,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -49,7 +48,6 @@ layout("/layouts/platform.html"){
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="立案编号" prop="caseFilingCode" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
@@ -148,7 +148,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName", width: "80px"},
{label: "提案类别", prop: "typeName"},
@@ -204,7 +204,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{ label: "提案编号", prop: "code" },
{ label: "立案编号", prop: "caseFilingCode" },
{ label: "提案名称", prop: "name", width: "200px" },
{ label: "提案类别", prop: "typeName" },
{ label: "届次", prop: "sessionName" },
@@ -116,7 +116,7 @@ layout("/layouts/platform.html"){
</div>
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules" label-suffix="">
<el-form-item label="立案结果" prop="tf_caseFilingResult"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
:rules="[{required:pendingSubmitType === 1,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_caseFilingResult" size="small" @change="handleCaseFilingResultChange">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code"
border>{{item.label}}
@@ -135,7 +135,7 @@ layout("/layouts/platform.html"){
<el-form-item
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '办理单位' : '主办单位'"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择办理单位' : '请选择主办单位',trigger:['change','blur']}]"
:rules="[{required:pendingSubmitType === 1 && ['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择办理单位' : '请选择主办单位',trigger:['change','blur']}]"
prop="tf_masterUnitIds"
>
<el-select v-model="formData.tf_masterUnitIds" filterable clearable multiple
@@ -204,7 +204,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
@@ -221,6 +220,7 @@ layout("/layouts/platform.html"){
tf_slaveUnitIds: []
},
showApprovalForm: false,
pendingSubmitType: 1,
sessionOptions: [],
delegationOptions: [],
unionOptions: [],
@@ -341,8 +341,9 @@ layout("/layouts/platform.html"){
if (!val || !val.length) {
return
}
// 当前页面需要回显上一环节“提案委员会立案”保存的主办/协办单位或办理单位。
var data = val[val.length - 1]
// 仅回显立案审核的历史数据;校工会主席意见没有立案字段,不能清空本次表单。
var data = val.slice().reverse().find((task) => task.ext && task.ext.tf_caseFilingResult)
if (!data) return
this.$set(this.formData, "tf_caseFilingResult", data.ext.tf_caseFilingResult)
this.$set(this.formData, "tf_caseFilingType", data.ext.tf_caseFilingType)
this.$set(this.formData, "tf_masterUnitIds", this.normalizeUnitIds(data.ext.tf_masterUnitIds))
@@ -352,6 +353,7 @@ layout("/layouts/platform.html"){
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.pendingSubmitType = 1
this.formData = {
proposalId: row.id,
processTaskId: row.taskId,
@@ -365,6 +367,9 @@ layout("/layouts/platform.html"){
},
handleTaskAction(val) {
// 退回只需要审核意见;立案结果与承办单位仅在正式提交时必填。
this.pendingSubmitType = val
this.$refs.formRef.clearValidate()
this.$refs.formRef.validate(valid => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
@@ -405,7 +410,7 @@ layout("/layouts/platform.html"){
}
const loading = createLoading('提交中')
this.$axios.post("/platform/proposal/committeeFilingUnit/executeTask", {
this.$axios.post("/platform/proposal/committeeFiling/executeTask", {
data: JSON.stringify(params)
}).then((res) => {
if (res.code === 0) {
@@ -444,7 +449,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/platform/proposal/committeeFilingUnit/revokeTask", {
this.$axios.post("/platform/proposal/committeeFiling/revokeTask", {
taskId: row.taskId,
proposalId: row.id
}).then((res) => {
@@ -16,7 +16,6 @@ layout("/layouts/platform.html"){
<el-select slot="prepend" style="width: 110px" v-model="pageForm.proposalSearchField">
<el-option label="提案名称" value="name"></el-option>
<el-option label="提案编号" value="code"></el-option>
<el-option label="立案编号" value="caseFilingCode"></el-option>
</el-select>
</el-input>
</search-item>
@@ -93,7 +92,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "220px"},
{label: "提案人", prop: "createUserName", width: "90px"},
{label: "提案类别", prop: "typeName"},
@@ -107,7 +107,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName", width: "80px"},
{label: "提案类别", prop: "typeName"},
@@ -122,7 +122,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "是否并案", prop: "merge"},
@@ -112,7 +112,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName", width: "80px"},
{label: "提案类别", prop: "typeName"},
@@ -155,9 +154,9 @@ layout("/layouts/platform.html"){
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName,
taskName: row.taskName || "校工会主席审核",
taskKey: row.taskKey
}
this.$refs.proposalInfoRef.onOpen(row)
@@ -146,7 +146,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "办理单位", prop: "undertakeUnits", width: "260px"},
@@ -71,26 +71,7 @@ layout("/layouts/platform.html"){
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=":"
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
</el-row>
</div>
</proposal-info>
<proposal-info ref="proposalInfoRef"></proposal-info>
</template>
</guava>
</div>
@@ -118,14 +99,13 @@ layout("/layouts/platform.html"){
{label: "提交方式", prop: "mannerName"},
{label: "附议人数量", prop: "secondedNum"},
{label: "已附议", prop: "secondedAgreeNum"},
{label: "团长审核", prop: "delegationAudit"},
{label: "分工会主席审核", prop: "delegationAudit"},
],
pageForm: {
approval: false,
searchName: "proposalName",
searchName2: "su.username",
},
showApprovalForm: false,
sessionOptions: []
}
},
@@ -133,7 +113,6 @@ layout("/layouts/platform.html"){
// 查看
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
@@ -291,7 +291,6 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "立案结果", prop: "caseFilingResult"},
@@ -463,10 +462,10 @@ layout("/layouts/platform.html"){
// 加载候选人列表
loadCandidates(taskId) {
$.get("/flow/common/candidate", {taskId}).then((res) => {
this.$axios.post("/flow/common/candidate", {taskId}).then((res) => {
if (res.code === 0) {
this.candidates = res.data.candidates
this.supportCandidate = res.data.support
this.$set(this, "candidates", res.data.candidates)
this.$set(this, "supportCandidate", res.data.support)
}
})
},
@@ -88,7 +88,7 @@ layout("/layouts/platform.html"){
</template>
<template #edit>
<el-form :model="formData" :rules="formRules" label-width="150px" ref="form" v-loading="formLoading">
<el-form :model="formData" :rules="welfareFormRules" label-width="150px" ref="form" v-loading="formLoading">
<el-form-item label="沿用往期福利" v-if="!formData.id">
<el-select clearable filterable placeholder="请选择往期福利" style="width: 100%"
v-model="reuseProjectId" @change="reuseHistoryProject">
@@ -126,6 +126,15 @@ layout("/layouts/platform.html"){
<el-col :span="12">
<el-form-item prop="provideTime" label="发放时间">
<el-date-picker
v-if="formData.provideMode === 99"
style="width: 100%"
v-model="formData.provideTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择发放时间" @change="provideTimeChange">
</el-date-picker>
<el-date-picker
v-else
style="width: 100%"
v-model="formData.provideTime"
type="datetimerange"
@@ -196,7 +205,7 @@ layout("/layouts/platform.html"){
</el-row>
<el-form-item label="发放形式" prop="provideMode">
<el-radio-group size="medium" v-model="formData.provideMode">
<el-radio-group size="medium" v-model="formData.provideMode" @change="provideModeChange">
<el-radio-button :key="item.code" :label="item.code" v-for="item in welfareProvideMode">{{item.name}}</el-radio-button>
</el-radio-group>
</el-form-item>
@@ -275,24 +284,30 @@ layout("/layouts/platform.html"){
// { prop: "gift", label: "福利礼品" },
// { prop: "provideTimeStart", label: "发放时间" }
],
formRules: {
name: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
festival: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
provideTime: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
choiceTime: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
provideAddress: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
provideMode: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
signMode: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
noticePushMode: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
gift: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
multiSelectNum: [{ required: true, message: "必填", trigger: ["blur", "change"] }]
},
welfarePersonTypeList: [],
historyProjectOptions: [],
reuseProjectId: null,
welfareOptionKey: 0
}
},
computed: {
welfareFormRules() {
// 慰问金只要求项目名称和单个发放时间,其他发放形式沿用原有校验。
const requiredForOtherMode = this.formData.provideMode !== 99
return {
name: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
festival: [{ required: requiredForOtherMode, message: "必选", trigger: ["blur", "change"] }],
provideTime: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
choiceTime: [{ required: requiredForOtherMode, message: "必选", trigger: ["blur", "change"] }],
provideAddress: [{ required: requiredForOtherMode, message: "必选", trigger: ["blur", "change"] }],
provideMode: [{ required: true, message: "必选", trigger: ["blur", "change"] }],
signMode: [{ required: requiredForOtherMode, message: "必选", trigger: ["blur", "change"] }],
noticePushMode: [{ required: requiredForOtherMode, message: "必选", trigger: ["blur", "change"] }],
gift: [{ required: requiredForOtherMode, message: "必填", trigger: ["blur", "change"] }],
multiSelectNum: [{ required: requiredForOtherMode, message: "必填", trigger: ["blur", "change"] }]
}
}
},
methods: {
dropdownCommand(command) {
const { type, data } = command
@@ -310,30 +325,31 @@ layout("/layouts/platform.html"){
this.sendMsg(data)
}
},
async save() {
const formValid = await this.$refs["form"].validate()
if (formValid) {
if (this.formData.flexible) {
save() {
this.$refs["form"].validate((formValid) => {
if (!formValid) {
return
}
const formData = clone(this.formData)
formData.provideAddress = "工会"
try {
this.submitLoading = true
const resp = await this.$axios.post(loc() + "/save", { data: JSON.stringify(formData) })
if (resp.code === 0) {
this.$refs.guava.index()
this.doSearch()
this.$message.success(resp.msg)
} else {
this.$message.error(resp.msg)
}
} catch (e) {
this.notifyWarning(e.status)
} finally {
this.submitLoading = false
}
}
this.submitLoading = true
this.$axios.post(loc() + "/save", { data: JSON.stringify(formData) })
.then((resp) => {
if (resp.code === 0) {
this.$refs.guava.index()
this.doSearch()
this.$message.success(resp.msg)
} else {
this.$message.error(resp.msg)
}
})
.catch((e) => {
this.notifyWarning(e.status)
})
.finally(() => {
this.submitLoading = false
})
})
},
isCheckBoxChange() {
this.formData.welfareProjectSubjects = [
@@ -354,7 +370,11 @@ layout("/layouts/platform.html"){
]
},
provideTimeChange() {
if (this.formData.provideTime && this.formData.provideTime.length) {
// 单个发放时间同时写入原有开始、结束字段,保持保存接口和项目实体不变。
if (this.formData.provideMode === 99) {
this.$set(this.formData, "provideTimeStart", this.formData.provideTime || "")
this.$set(this.formData, "provideTimeEnd", this.formData.provideTime || "")
} else if (this.formData.provideTime && this.formData.provideTime.length) {
this.formData.provideTimeStart = this.formData.provideTime[0]
this.formData.provideTimeEnd = this.formData.provideTime[1]
} else {
@@ -362,25 +382,35 @@ layout("/layouts/platform.html"){
this.formData.provideTimeEnd = ""
}
},
provideModeChange() {
// 两种日期控件的 v-model 类型不同,切换发放形式时清除旧值。
this.$set(this.formData, "provideTime", null)
this.provideTimeChange()
this.$refs.form.clearValidate()
},
choiceTimeChange() {
if (this.formData.choiceTime && this.formData.choiceTime.length) {
this.formData.choiceTimeStart = this.formData.choiceTime[0]
this.formData.choiceTimeEnd = this.formData.choiceTime[1]
this.formData.provideTimeStart = this.formData.choiceTime[0]
this.formData.provideTimeEnd = this.formData.choiceTime[1]
if (this.formData.provideMode !== 99) {
this.formData.provideTimeStart = this.formData.choiceTime[0]
this.formData.provideTimeEnd = this.formData.choiceTime[1]
}
} else {
this.formData.choiceTimeStart = ""
this.formData.choiceTimeEnd = ""
this.formData.provideTimeStart = ""
this.formData.provideTimeEnd = ""
if (this.formData.provideMode !== 99) {
this.formData.provideTimeStart = ""
this.formData.provideTimeEnd = ""
}
}
},
sendMsg(row) {},
async openAdd() {
this.$set(this, "reuseProjectId", null)
if (this.$refs.form) this.$refs.form.resetFields()
this.$set(this, "formData", {
provideMode: 99,
isPushHome: false,
signMode: 4,
isRoutine: true,
@@ -388,11 +418,11 @@ layout("/layouts/platform.html"){
defaultFlexibleGifts: 0,
flexible: false,
noticePushMode: 1,
options: [],
welfareProjectSubjects: [],
flexibleGifts: [{}]
})
this.$refs.guava.edit()
if (this.$refs.form) this.$refs.form.resetFields()
await this.loadHistoryProjectOptions()
},
// 查询可沿用的历史福利项目,用于下拉选择。
@@ -430,7 +460,8 @@ layout("/layouts/platform.html"){
const projectData = clone(resp.data)
this.clearReuseProjectIdentifiers(projectData)
this.$set(projectData, "choiceTime", [projectData.choiceTimeStart, projectData.choiceTimeEnd])
this.$set(projectData, "provideTime", [projectData.provideTimeStart, projectData.provideTimeEnd])
this.$set(projectData, "provideTime", projectData.provideMode === 99
? projectData.provideTimeStart : [projectData.provideTimeStart, projectData.provideTimeEnd])
this.$set(this, "formData", projectData)
this.$set(this, "welfareOptionKey", this.welfareOptionKey + 1)
} catch (e) {
@@ -479,7 +510,8 @@ layout("/layouts/platform.html"){
this.submitLoading = false
if (resp.code === 0) {
const data = resp.data
data.provideTime = [data.provideTimeStart, data.provideTimeEnd]
data.provideTime = data.provideMode === 99
? data.provideTimeStart : [data.provideTimeStart, data.provideTimeEnd]
data.choiceTime = [data.choiceTimeStart, data.choiceTimeEnd]
this.formData = data
this.$refs.guava.edit()
@@ -509,6 +541,10 @@ layout("/layouts/platform.html"){
this.welfareProvideMode.map((v) => {
v.code = Number(v.code)
})
// 新形式暂由本页面补充,避免依赖未纳入代码仓库的系统字典初始化数据。
if (!this.welfareProvideMode.some((v) => v.code === 99)) {
this.welfareProvideMode.push({ code: 99, name: "慰问金" })
}
this.welfareSignMode = await this.$businessTool.getDictOptions("welfareSignMode")
this.welfareSignMode.map((v) => {
v.code = Number(v.code)
@@ -9,7 +9,6 @@ const PROPOSAL_INFO = {
<van-cell-group :border="false">
<van-cell title="提案编号">{{ viewData.code || '--' }}</van-cell>
<van-cell title="提案名称">{{ viewData.name || '--' }}</van-cell>
<van-cell title="立案编号">{{ viewData.caseFilingCode || '暂无' }}</van-cell>
<van-cell title="立案结果" v-if="viewData.caseFilingResult">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="viewData.caseFilingResult"></dict-tag>
@@ -189,7 +188,7 @@ const PROPOSAL_INFO = {
<template v-else>
<van-cell title="办理单位"
v-if="['opinion_unit_reply', 'unit_reply', 'two_unit_reply', 'master_reply', 'slave_reply'].includes(selectedTask.taskName)">
v-if="['opinion_unit_reply', 'unit_reply', 'two_unit_reply', 'opinion_master_reply', 'master_reply', 'slave_reply'].includes(selectedTask.taskName)">
{{ selectedTask.ext.underTakeName || '--' }}
</van-cell>
<van-cell title="办理用户">
@@ -10,7 +10,7 @@ const PROPOSAL_TASK_POPUP = {
<div v-if="isApproval">
<van-form ref="formRef">
<template
v-if="kind === 'delegation' || kind === 'preAudit' || kind === 'schoolLeaderApproval'">
v-if="kind === 'delegation' || kind === 'schoolUnionChairApproval' || kind === 'schoolLeaderApproval'">
<section class="proposal-view-card">
<h2 class="proposal-view-card__title">审批意见<span
class="proposal-audit-card__required">*</span></h2>
@@ -114,6 +114,27 @@ const PROPOSAL_TASK_POPUP = {
:rules="[{required:true,message:'请填写审批意见'}]"></van-field>
</section>
</template>
<template v-if="kind === 'committeeFiling'">
<section class="proposal-view-card">
<h2 class="proposal-view-card__title">立案审核<span class="proposal-audit-card__required">*</span></h2>
<van-field :value="filingResultName" label="立案结果" readonly required is-link
placeholder="请选择立案结果" @click="openLayer('filing-result-picker')"></van-field>
<van-field v-if="formData.tf_caseFilingResult === 'CONFIRM_FILING' || formData.tf_caseFilingResult === 'SUGGESTION'"
:value="selectedFilingMasterNames"
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '办理单位' : '主办单位'"
readonly required is-link placeholder="请选择单位"
@click="openFilingUnitPicker('master')"></van-field>
<van-field v-if="formData.tf_caseFilingResult === 'CONFIRM_FILING'"
:value="selectedFilingSlaveNames" label="协办单位"
readonly is-link placeholder="可选"
@click="openFilingUnitPicker('slave')"></van-field>
<h2 class="proposal-view-card__title">审核意见<span class="proposal-audit-card__required">*</span></h2>
<van-field v-model="formData.tf_opinion" class="proposal-audit-field"
name="tf_opinion" type="textarea" rows="6" label=""
placeholder="请输入审核意见" required maxlength="500" show-word-limit
:rules="[{required:true,message:'请填写审核意见'}]"></van-field>
</section>
</template>
</van-form>
<div class="proposal-popup-form-actions" v-if="kind === 'delegation'">
<van-button type="primary" block :loading="formLoading" class="proposal-soft-button"
@@ -128,7 +149,7 @@ const PROPOSAL_TASK_POPUP = {
@click="prepareSubmit(6)">退回
</van-button>
</div>
<div class="proposal-popup-form-actions proposal-pre-audit-actions" v-else-if="kind === 'preAudit'"
<div class="proposal-popup-form-actions proposal-pre-audit-actions" v-else-if="kind === 'schoolUnionChairApproval'"
style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr))">
<van-button type="primary" :loading="formLoading"
class="proposal-soft-button proposal-pre-audit-button--primary"
@@ -148,6 +169,18 @@ const PROPOSAL_TASK_POPUP = {
</van-button>
</div>
<div class="proposal-popup-form-actions proposal-pre-audit-actions" v-else-if="kind === 'committeeFiling'"
style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr))">
<van-button type="primary" :loading="formLoading"
class="proposal-soft-button proposal-pre-audit-button--primary"
style="grid-column:1 / -1" @click="prepareSubmit(1)">提交</van-button>
<van-button type="info" :loading="formLoading"
class="proposal-soft-button proposal-pre-audit-button--info"
@click="prepareSubmit(4)">退回(不审核)</van-button>
<van-button type="info" :loading="formLoading"
class="proposal-soft-button proposal-pre-audit-button--info"
@click="prepareSubmit(6)">退回(审核)</van-button>
</div>
<div class="proposal-popup-form-actions" v-else-if="kind === 'schoolLeaderApproval'">
<van-button type="primary" block :loading="formLoading" class="proposal-soft-button"
@@ -211,11 +244,32 @@ const PROPOSAL_TASK_POPUP = {
<div class="reply-unit-empty" v-else>暂无可选办理单位</div>
</div>
</van-popup>
<van-popup v-model="filingResultPickerVisible" position="bottom" :close-on-click-overlay="false">
<van-picker show-toolbar :columns="(dict.type.PROPOSAL_CASE_FILING_RESULT || []).map((item) => ({text:item.label,value:item.code}))"
@confirm="confirmFilingResult" @cancel="closeLayer('filing-result-picker')"></van-picker>
</van-popup>
<van-popup v-model="filingUnitPickerVisible" position="bottom" round :close-on-click-overlay="false" :style="{height:'70%'}">
<div class="reply-unit-popup">
<div class="reply-unit-toolbar">
<button type="button" @click="closeLayer('filing-unit-picker')">取消</button>
<div class="reply-unit-toolbar-title">{{filingUnitType === 'master' ? '选择主办单位' : '选择协办单位'}}</div>
<button type="button" @click="confirmFilingUnits">确定</button>
</div>
<div class="reply-unit-list">
<van-checkbox-group v-model="pendingFilingUnitIds">
<van-cell v-for="item in filingUnitOptions" :key="item.id" clickable :title="item.name"
@click="toggleFilingUnit(item)">
<template #right-icon><van-checkbox :name="item.id" @click.stop></van-checkbox></template>
</van-cell>
</van-checkbox-group>
</div>
</div>
</van-popup>
<van-dialog :value="confirmVisible" title="提示" message="您确定要提交吗?" show-cancel-button
@confirm="submit" @cancel="closeLayer('submit-confirm')"></van-dialog>
</van-popup>
`,
dicts: ["PROPOSAL_FEEDBACK", "UNDERTAKE_SUGGESTION", "PROPOSAL_REPLY_IMPLEMENT"],
dicts: ["PROPOSAL_FEEDBACK", "UNDERTAKE_SUGGESTION", "PROPOSAL_REPLY_IMPLEMENT", "PROPOSAL_CASE_FILING_RESULT"],
components: {"proposal-info": PROPOSAL_INFO},
props: {kind: {type: String, required: true}, pageKey: {type: String, required: true}},
data() {
@@ -231,6 +285,11 @@ const PROPOSAL_TASK_POPUP = {
implementPickerVisible: false,
candidatePickerVisible: false,
replyUnitPickerVisible: false,
filingResultPickerVisible: false,
filingUnitPickerVisible: false,
filingUnitType: "master",
filingUnitOptions: [],
pendingFilingUnitIds: [],
confirmVisible: false,
supportCandidate: false,
candidates: [],
@@ -245,8 +304,9 @@ const PROPOSAL_TASK_POPUP = {
},
title() {
const titles = {
delegation: "团长审核",
preAudit: "校工会预审核",
delegation: "分工会主席审核",
schoolUnionChairApproval: "校工会主席审核",
committeeFiling: "提案委员立案审核",
schoolLeaderApproval: "分管校领导审批",
feedbackEvaluation: "反馈评价",
suggestion: "承办单位意见",
@@ -258,6 +318,16 @@ const PROPOSAL_TASK_POPUP = {
selectedReplyUnitNames() {
const ids = this.formData.tf_secondReplyUnitIds || [];
return this.replyUnitOptions.filter((item) => ids.indexOf(item.unitId) > -1).map((item) => item.unitName + "(" + (item.isMaster ? "主办" : "协办") + ")").join("、")
},
filingResultName() {
const item = (this.dict.type.PROPOSAL_CASE_FILING_RESULT || []).find((entry) => entry.code === this.formData.tf_caseFilingResult);
return item ? item.label : ""
},
selectedFilingMasterNames() {
return this.filingUnitOptions.filter((item) => (this.formData.tf_masterUnitIds || []).includes(item.id)).map((item) => item.name).join("、")
},
selectedFilingSlaveNames() {
return this.filingUnitOptions.filter((item) => (this.formData.tf_slaveUnitIds || []).includes(item.id)).map((item) => item.name).join("、")
}
},
methods: {
@@ -268,6 +338,8 @@ const PROPOSAL_TASK_POPUP = {
this.$set(this, "implementPickerVisible", stack.includes("implement-picker"));
this.$set(this, "candidatePickerVisible", stack.includes("candidate-picker"));
this.$set(this, "replyUnitPickerVisible", stack.includes("reply-unit-picker"));
this.$set(this, "filingResultPickerVisible", stack.includes("filing-result-picker"));
this.$set(this, "filingUnitPickerVisible", stack.includes("filing-unit-picker"));
this.$set(this, "confirmVisible", stack.includes("submit-confirm"))
},
openLayer(name) {
@@ -280,8 +352,9 @@ const PROPOSAL_TASK_POPUP = {
/** row 提供详情主键和当前 WF 任务参数,action 为 view 或 approval。 */
open(row, action) {
const defaultTaskNames = {
delegation: "团长审核",
preAudit: "校工会预审核",
delegation: "分工会主席审核",
schoolUnionChairApproval: "校工会主席审核",
committeeFiling: "提案委员立案审核",
feedbackEvaluation: "反馈评价",
unitReply: "承办单位答复",
caseCheck: "提案委员会审查"
@@ -312,6 +385,12 @@ const PROPOSAL_TASK_POPUP = {
this.$set(this.formData, "tf_secondReplyUnitIds", []);
this.loadReplyUnits(row.id)
}
if (action === "approval" && this.kind === "committeeFiling") {
this.$set(this.formData, "tf_caseFilingResult", row.caseFilingResult || "");
this.$set(this.formData, "tf_masterUnitIds", []);
this.$set(this.formData, "tf_slaveUnitIds", []);
this.loadFilingUnits()
}
this.openLayer("detail")
},
loadCandidates(taskId) {
@@ -369,6 +448,41 @@ const PROPOSAL_TASK_POPUP = {
this.$set(this.formData, "tf_secondReplyUnitIds", [...this.pendingReplyUnitIds]);
this.closeLayer("reply-unit-picker")
},
/** 立案审核的主办、协办单位均来自本项目承办单位目录。 */
loadFilingUnits() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res && res.code === 0) this.$set(this, "filingUnitOptions", res.data || [])
})
},
/** value 为结果字典项;切换结果时清理不再适用的承办单位,并设置可编辑的默认意见。 */
confirmFilingResult(value) {
this.$set(this.formData, "tf_caseFilingResult", value.value);
this.$set(this.formData, "tf_masterUnitIds", []);
this.$set(this.formData, "tf_slaveUnitIds", []);
const opinions = {CONFIRM_FILING: "经提案委员会审理,该提案确定立案。", SUGGESTION: "经提案委员会审理,该提案作为意见建议。", NOT: "经提案委员会审理,该提案不予立案。"};
this.$set(this.formData, "tf_opinion", opinions[value.value] || "");
this.closeLayer("filing-result-picker")
},
/** type 为 master 或 slave,使用全局历史栈打开对应的单位选择弹层。 */
openFilingUnitPicker(type) {
this.$set(this, "filingUnitType", type);
this.$set(this, "pendingFilingUnitIds", [...(this.formData[type === "master" ? "tf_masterUnitIds" : "tf_slaveUnitIds"] || [])]);
this.openLayer("filing-unit-picker")
},
/** item 为承办单位;再次点击同一单位时取消选中。 */
toggleFilingUnit(item) {
const ids = [...this.pendingFilingUnitIds];
const index = ids.indexOf(item.id);
if (index >= 0) ids.splice(index, 1); else ids.push(item.id);
this.$set(this, "pendingFilingUnitIds", ids)
},
/** 保存当前选择,排除已在另一类承办单位中选过的记录。 */
confirmFilingUnits() {
const opposite = this.filingUnitType === "master" ? "tf_slaveUnitIds" : "tf_masterUnitIds";
const ids = this.pendingFilingUnitIds.filter((id) => !(this.formData[opposite] || []).includes(id));
this.$set(this.formData, this.filingUnitType === "master" ? "tf_masterUnitIds" : "tf_slaveUnitIds", ids);
this.closeLayer("filing-unit-picker")
},
buildCaseCheckData() {
const data = {...this.formData};
const units = data.tf_caseCheckNeedSecondReply === 1 ? this.replyUnitOptions.filter((item) => data.tf_secondReplyUnitIds.indexOf(item.unitId) > -1) : [];
@@ -395,6 +509,10 @@ const PROPOSAL_TASK_POPUP = {
this.$toast(opinionConfig.message)
return
}
if (this.kind === "committeeFiling" && value === 1) {
if (!this.formData.tf_caseFilingResult) return this.$toast("请选择立案结果");
if (["CONFIRM_FILING", "SUGGESTION"].includes(this.formData.tf_caseFilingResult) && !(this.formData.tf_masterUnitIds || []).length) return this.$toast("请选择主办或办理单位")
}
this.$refs.formRef.validate().then(() => {
this.$set(this, "pendingSubmitType", value);
this.openLayer("submit-confirm")
@@ -416,13 +534,29 @@ const PROPOSAL_TASK_POPUP = {
...this.buildCaseCheckData(),
submitType: this.pendingSubmitType
} : {...this.formData, submitType: this.pendingSubmitType}
if (this.kind === "preAudit") {
if (this.kind === "schoolUnionChairApproval") {
data.taskName = "startTask";
if (this.pendingSubmitType === 4) {
data.tf_sourceTaskKey = this.formData.taskKey;
data.tf_audit = false
}
}
if (this.kind === "committeeFiling") {
const masters = this.filingUnitOptions.filter((item) => (data.tf_masterUnitIds || []).includes(item.id));
const slaves = this.filingUnitOptions.filter((item) => (data.tf_slaveUnitIds || []).includes(item.id));
data.tf_masterUnitId = masters.length ? masters[0].id : "";
data.tf_masterUnitName = masters.length ? masters[0].name : "";
data.tf_masterUnitNames = masters.map((item) => item.name);
data.tf_masterUnitNameStr = data.tf_masterUnitNames.join(",");
data.tf_slaveUnitNames = slaves.map((item) => item.name);
data.tf_slaveUnitNameStr = data.tf_slaveUnitNames.join(",");
data.tf_helpunitreply = slaves.length ? "HAS_HELP_UNIT" : "NO_HELP_UNIT";
if (this.pendingSubmitType === 4) {
data.taskName = "startTask";
data.tf_sourceTaskKey = this.formData.taskKey;
data.tf_audit = false
}
}
if (this.kind === "unitReply") {
delete data.underTakeIsMaster;
delete data.underTakeName
@@ -432,6 +566,7 @@ const PROPOSAL_TASK_POPUP = {
data.tf_masterUnitId = res.data.tf_masterUnitId;
return this.$axios.post("/flow/common/executeTask", {data: JSON.stringify(data)})
})
else if (this.kind === "committeeFiling") request = this.$axios.post("/platform/proposal/committeeFiling/executeTask", {data: JSON.stringify(data)})
else request = this.$axios.post("/flow/common/executeTask", {data: JSON.stringify(data)})
}
request.then((res) => {
@@ -300,7 +300,6 @@ layout("/layouts/platform_h5.html"){
</div>
</template>
<template v-slot="{index,row}">
<table-column label="立案编号">{{row.caseFilingCode || '--'}}</table-column>
<table-column label="提案类别">{{row.typeName || '--'}}</table-column>
<table-column label="提案人">{{row.createUserName || '--'}}</table-column>
<table-column label="教代会">{{row.sessionName || '--'}}</table-column>
@@ -0,0 +1,415 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style>
body {
background-color: #f3f7fd;
}
.proposal-pre-audit-page {
min-height: 100vh;
padding-bottom: calc(24px + env(safe-area-inset-bottom));
box-sizing: border-box;
background-color: #f3f7fd;
}
.proposal-pre-audit-page .van-nav-bar {
background-color: #fff;
}
.proposal-pre-audit-page .van-nav-bar__title {
color: #172033;
font-size: 16px;
font-weight: 600;
}
.proposal-pre-audit-page .van-nav-bar .van-icon,
.proposal-pre-audit-page .van-nav-bar__text {
color: #1989fa;
}
.proposal-pre-audit-content {
padding: 0 12px;
}
.proposal-pre-audit-sticky {
padding: 22px 12px 1px;
box-sizing: border-box;
background-color: #f3f7fd;
}
.proposal-pre-audit-search {
margin: 0 0 8px;
padding: 0;
overflow: hidden;
border-radius: 12px;
background-color: #fff;
box-shadow: 0 5px 16px rgba(43, 73, 112, .1);
}
.proposal-pre-audit-search .van-search__content {
height: 42px;
padding-left: 12px;
align-items: center;
border-radius: 12px;
background-color: #fff;
}
.proposal-pre-audit-search .van-field__control {
color: #263548;
font-size: 14px;
}
.proposal-pre-audit-search .van-field__control::placeholder {
color: #a7b0bf;
}
.proposal-pre-audit-filter {
margin: 0 0 10px;
overflow: hidden;
border-radius: 10px;
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
transition: border-radius .18s ease;
}
.proposal-pre-audit-filter.is-open {
border-radius: 10px 10px 0 0;
}
.proposal-pre-audit-filter .van-dropdown-menu__bar,
.proposal-pre-audit-filter .van-dropdown-menu__item,
.proposal-pre-audit-filter .van-dropdown-menu__title {
height: 44px;
}
.proposal-pre-audit-filter .van-dropdown-menu__bar {
box-shadow: none;
}
.proposal-pre-audit-filter .van-dropdown-menu__title {
display: inline-flex;
align-items: center;
color: #66758a;
font-size: 14px;
line-height: 20px;
}
.proposal-pre-audit-filter .van-dropdown-menu__title--active,
.proposal-pre-audit-filter .van-dropdown-item__option--active,
.proposal-pre-audit-filter .van-dropdown-item__option--active .van-dropdown-item__icon {
color: #1989fa;
}
.proposal-pre-audit-filter .van-dropdown-item__content {
width: calc(100% - 24px);
margin: 0 12px;
overflow: hidden;
box-sizing: border-box;
border-radius: 0 0 12px 12px;
box-shadow: 0 10px 24px rgba(31, 65, 108, .14);
}
.proposal-pre-audit-filter .van-dropdown-item__option {
display: flex;
min-height: 48px;
padding: 0 16px;
align-items: center;
color: #46566c;
font-size: 14px;
}
.proposal-pre-audit-list .empty-state {
display: none;
}
.proposal-pre-audit-empty {
display: flex;
min-height: 280px;
padding: 46px 18px 36px;
align-items: center;
justify-content: center;
flex-direction: column;
box-sizing: border-box;
text-align: center;
}
.proposal-pre-audit-empty img {
display: block;
width: 86%;
max-width: 290px;
height: auto;
object-fit: contain;
}
.proposal-pre-audit-empty__title {
margin-top: 14px;
color: #50627a;
font-size: 15px;
line-height: 22px;
font-weight: 600;
}
.proposal-pre-audit-empty__hint {
margin-top: 5px;
color: #9aa7b8;
font-size: 12px;
line-height: 18px;
}
.proposal-pre-audit-card-header {
display: flex;
margin-bottom: 7px;
align-items: flex-start;
justify-content: space-between;
}
.proposal-pre-audit-card-heading {
min-width: 0;
padding-right: 10px;
flex: 1;
}
.proposal-pre-audit-card-title {
overflow: hidden;
color: #253247;
font-size: 15px;
line-height: 22px;
font-weight: 600;
text-overflow: ellipsis;
white-space: nowrap;
}
.proposal-pre-audit-card-code {
margin-top: 1px;
color: #9ba6b6;
font-size: 12px;
line-height: 18px;
}
.proposal-pre-audit-status {
display: inline-flex;
flex: none;
}
.proposal-pre-audit-status .van-tag {
display: inline-flex;
min-height: 24px;
padding: 3px 9px;
align-items: center;
box-sizing: border-box;
border: 0;
border-radius: 12px;
font-size: 12px;
line-height: 18px;
white-space: nowrap;
}
@media (max-width: 350px) {
.proposal-pre-audit-content,
.proposal-pre-audit-sticky {
padding-right: 10px;
padding-left: 10px;
}
}
</style>
<style id="style-proposal-task-popup-h5">
<!--#include("../../common/info.css"){}#-->
<!--#include("../theme.css"){}#-->
</style>
<div id="app" v-cloak>
<div class="proposal-pre-audit-page">
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="提案委员立案审核" placeholder fixed></van-nav-bar>
<van-sticky :offset-top="46">
<div class="proposal-pre-audit-sticky">
<van-search
v-model="pageForm.name"
class="proposal-pre-audit-search"
placeholder="请输入提案名称搜索"
shape="round"
clearable
@search="doSearch"
@clear="doSearch"
></van-search>
<van-dropdown-menu
class="proposal-pre-audit-filter"
:class="{'is-open': filterOpened}"
active-color="#1989fa"
>
<van-dropdown-item
v-model="pageForm.sessionId"
:options="sessionOptions"
:multiple="false"
@change="doSearch"
@open="onFilterOpen"
@close="onFilterClose"
></van-dropdown-item>
<van-dropdown-item
v-model="pageForm.approvalText"
:options="approvalOptions"
:multiple="false"
@change="approvalChange"
@open="onFilterOpen"
@close="onFilterClose"
></van-dropdown-item>
</van-dropdown-menu>
</div>
</van-sticky>
<main class="proposal-pre-audit-content">
<div class="proposal-pre-audit-list">
<!-- 列表无记录时使用与“我的提案”一致的提案专用空状态。 -->
<div v-if="pageForm.totalCount === 0" class="proposal-pre-audit-empty">
<img src="/assets/mobile/img/proposal/proposal-empty.png" alt="暂无提案记录插画">
<div class="proposal-pre-audit-empty__title">暂无提案记录</div>
<div class="proposal-pre-audit-empty__hint">当前筛选条件下暂时没有提案</div>
</div>
<table-list api="/platform/proposal/committeeFiling/pageData" :page_form.sync="pageForm" @ready="onReady"
ref="tableListRef" title="name">
<template #header="{index,row}">
<div class="proposal-pre-audit-card-header">
<div class="proposal-pre-audit-card-heading">
<div class="proposal-pre-audit-card-title">{{row.name}}</div>
<div class="proposal-pre-audit-card-code">编号:{{row.code || '--'}}</div>
</div>
<enum-tag
class="proposal-pre-audit-status"
v-if="row.instanceState"
:value="row.instanceState"
name="ProcessInstanceStateEnum"
label_key="message"
size="small"
></enum-tag>
</div>
</template>
<template v-slot="{index,row}">
<table-column label="提案类别">{{row.typeName || '--'}}</table-column>
<table-column label="提案人">{{row.createUserName || '--'}}</table-column>
<table-column label="教代会">{{row.sessionName || '--'}}</table-column>
<table-column label="代表团">{{row.delegationName || '--'}}</table-column>
<table-column label="当前节点">{{row.curTaskName || '--'}}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="onView(row,index)">
<van-icon class="proposal-action-icon" name="eye-o"></van-icon>
<span>查看</span>
</div>
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row,index)">
<van-icon class="proposal-action-icon" name="edit"></van-icon>
<span>审核</span>
</div>
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
<van-icon class="proposal-action-icon" name="revoke"></van-icon>
<span>撤回</span>
</div>
</template>
</table-list>
</div>
</main>
</div>
<proposal-task-popup ref="taskPopup" kind="committeeFiling" page-key="proposal-committee-filing-task" @success="doSearch"></proposal-task-popup>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
<!--#include("../../common/task-popup.js"){}#-->
new Vue({
el: "#app",
store,
components: {"proposal-task-popup": PROPOSAL_TASK_POPUP},
data() {
return {
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: "",
name: null,
sessionId: null,
approvalText: "0",
approval: false
},
sessionOptions: [],
filterOpened: false,
approvalOptions: [
{text: "未审核", value: "0"},
{text: "已审核", value: "1"}
],
}
},
methods: {
onReady() {
this.listSession(false)
},
onFilterOpen() {
this.filterOpened = true
},
onFilterClose() {
this.filterOpened = false
},
// 审核状态下拉使用字符串展示,查询接口使用布尔值区分已审核和未审核。
approvalChange(value) {
this.$set(this.pageForm, "approval", value === "1")
this.doSearch()
},
// 与其他提案 H5 页面一致加载全部教代会;首次进入默认选中最新一届,缓存恢复时不覆盖原筛选条件。
listSession(skipDefaultSearch) {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = [{text: "全部教代会", value: null}]
.concat(res.data.map((item) => ({text: item.fullName, value: item.id})))
if (skipDefaultSearch) return
this.$set(this.pageForm, "sessionId", res.data.length > 0 ? res.data[0].id : null)
this.doSearch()
}
})
},
onView(row, index) {
this.$refs.taskPopup.open(row, "view")
},
onApproval(row, index) {
this.$refs.taskPopup.open(row, "approval")
},
onRevoke(row) {
this.$dialog.confirm({
title: "提示",
message: "您确定要撤回吗?"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()
}
})
})
},
doSearch() {
this.$nextTick(() => {
this.$set(this.pageForm, "pageNumber", 1)
this.$set(this.pageForm, "totalCount", 0)
this.$refs.tableListRef.doSearch()
})
}
},
created() {
const tab = new URLSearchParams(window.location.search).get("tab")
if (tab === "done") {
this.$set(this.pageForm, "approval", true)
this.$set(this.pageForm, "approvalText", "1")
} else if (tab === "todo") {
this.$set(this.pageForm, "approval", false)
this.$set(this.pageForm, "approvalText", "0")
}
}
})
</script>
<!--#
}
#-->
@@ -235,7 +235,7 @@ layout("/layouts/platform_h5.html"){
</style>
<div id="app" v-cloak>
<div class="proposal-delegation-page">
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="团长审核" placeholder fixed></van-nav-bar>
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="分工会主席审核" placeholder fixed></van-nav-bar>
<van-sticky :offset-top="46">
<div class="proposal-delegation-sticky">
<van-search
@@ -218,7 +218,7 @@ layout("/layouts/platform_h5.html"){
</style>
<div id="app" v-cloak>
<div class="proposal-pre-audit-page">
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="校工会预审核" placeholder fixed></van-nav-bar>
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="校工会主席审核" placeholder fixed></van-nav-bar>
<van-sticky :offset-top="46">
<div class="proposal-pre-audit-sticky">
<van-search
@@ -263,7 +263,7 @@ layout("/layouts/platform_h5.html"){
<div class="proposal-pre-audit-empty__title">暂无提案记录</div>
<div class="proposal-pre-audit-empty__hint">当前筛选条件下暂时没有提案</div>
</div>
<table-list api="/platform/proposal/pre/audit/pageData" :page_form.sync="pageForm" @ready="onReady"
<table-list api="/platform/proposal/schoolUnionChairApproval/pageData" :page_form.sync="pageForm" @ready="onReady"
ref="tableListRef" title="name">
<template #header="{index,row}">
<div class="proposal-pre-audit-card-header">
@@ -282,7 +282,6 @@ layout("/layouts/platform_h5.html"){
</div>
</template>
<template v-slot="{index,row}">
<table-column label="立案编号">{{row.caseFilingCode || '--'}}</table-column>
<table-column label="提案类别">{{row.typeName || '--'}}</table-column>
<table-column label="提案人">{{row.createUserName || '--'}}</table-column>
<table-column label="教代会">{{row.sessionName || '--'}}</table-column>
@@ -307,7 +306,7 @@ layout("/layouts/platform_h5.html"){
</div>
</main>
</div>
<proposal-task-popup ref="taskPopup" kind="preAudit" page-key="proposal-pre-audit-task" @success="doSearch"></proposal-task-popup>
<proposal-task-popup ref="taskPopup" kind="schoolUnionChairApproval" page-key="proposal-school-union-chair-task" @success="doSearch"></proposal-task-popup>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
@@ -285,7 +285,7 @@ const todo = {
this.$toast("当前流程暂不支持手机端审核,请前往PC端页面审核!");
return;
}
this.$pjaxReplace(h5FormKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey+ "&tab=" + this.activeTab)
this.$pjaxReplace(h5FormKey + "?taskId=" + taskId + "&bizId=" + businessNo + "&taskKey=" + taskKey + "&tab=" + this.activeTab)
},
// 根据当前列表类型统一展示流程状态,发起列表保留流程实例的实际状态。