first commit

This commit is contained in:
2026-01-08 14:58:16 +08:00
commit 556e5d64aa
9575 changed files with 1621095 additions and 0 deletions
@@ -0,0 +1,257 @@
const PROPOSAL_INFO = {
name: "ProposalInfo",
/*language=HTML*/
template: `
<div class="proposal-info">
<div class="process-title">
提案基础信息
</div>
<h3 style="text-align: center;font-weight: 600" class="pt10 pb10">
{{ viewData.name }}
</h3>
<el-descriptions :column="3" border>
<el-descriptions-item label="提案编号">{{ viewData.code }}</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>
<el-descriptions-item label="提案人单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item :label="viewData.mannerCode!=='W03'?'代表团名称':'委员会名称'">
{{ viewData.mannerCode !== 'W03' ? viewData.delegationName : viewData.committeeName }}
</el-descriptions-item>
<el-descriptions-item label="提案类别">
{{viewData.typeName}}
</el-descriptions-item>
<el-descriptions-item label="建议承办单位">
{{viewData.suggestUnits}}
</el-descriptions-item>
<el-descriptions-item label="立案结果" :span="2">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="viewData.caseFilingResult"></dict-tag>
</el-descriptions-item>
<!--<el-descriptions-item label="调研情况" :span="3">
<div class="text-left">{{viewData.researchFindings}}</div>
</el-descriptions-item>-->
<el-descriptions-item label="提案案由" :span="3">
<div class="text-left" v-html="viewData.brief"></div>
</el-descriptions-item>
<el-descriptions-item label="建议措施" :span="3">
<div class="text-left" v-html="viewData.measures"></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 :src="viewData.signature" class="signature-image">-->
<!-- <div slot="error" class="image-slot">-->
<!-- <i class="el-icon-picture-outline"></i>-->
<!-- </div>-->
<!-- </el-image>-->
<!-- </el-descriptions-item>-->
</el-descriptions>
<!--并案信息-->
<template v-if="viewData.merges">
<div class="process-title">
并案信息
</div>
<el-table :data="viewData.merges" size="medium">
<el-table-column label="序号" type="index" width="100px"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="操作" width="100px">
<template slot-scope="{row}">
<el-link type="primary" size="mini" @click="openView(row)">查看</el-link>
</template>
</el-table-column>
</el-table>
</template>
<!--委员会成员意见-->
<template v-if="viewData.commissionerOpinions && viewData.commissionerOpinions.length">
<div class="process-title">
委员会成员意见
</div>
<el-table :data="viewData.commissionerOpinions" size="medium">
<el-table-column label="序号" type="index" width="100px"></el-table-column>
<el-table-column label="委员" prop="commissionerName">
<template slot-scope="{row}">
{{row.commissionerName}}({{row.commissionerLoginName}})
</template>
</el-table-column>
<el-table-column label="立案结果" prop="caseFilingType">
<template slot-scope="{row}">
<div style="display: flex;justify-content: center">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
<template v-if="row.caseFilingType">
(
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="row.caseFilingType"></dict-tag>
)
</template>
</div>
</template>
</el-table-column>
<el-table-column label="意见" prop="opinionText"></el-table-column>
<el-table-column label="时间" prop="opinionTime"></el-table-column>
</el-table>
</template>
<el-dialog title="提案详情" :visible.sync="viewDialogVisible" width="1200px" append-to-body top="5vh">
<div style="max-height: 80vh;overflow-y: auto">
<proposal-info ref="infoDialogRef"></proposal-info>
</div>
</el-dialog>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
}}({{task.ext.initiatorAccount}})
</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>
<!--邀请附议人-->
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-else-if="task.taskName === 'invite'">
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间" :span="2">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="附议人" :span="3" v-if="task.taskName === 'invite'">
<el-table :data="task?.taskFormData?.seconder">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="联系方式" prop="mobile"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
</el-table>
</el-descriptions-item>
</el-descriptions>
<!--提案委员会立案-->
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-else-if="task.taskName === 'committee'">
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="立案结果">
<div style="display: flex;justify-content: center">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="task.ext.tf_caseFilingResult"></dict-tag>
<template v-if="task.ext.tf_caseFilingType">
(
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="task.ext.tf_caseFilingType"></dict-tag>
)
</template>
</div>
</el-descriptions-item>
<el-descriptions-item label="主办单位" :span="3">{{task.ext.tf_masterUnitName}}
</el-descriptions-item>
<el-descriptions-item label="协办单位" :span="3">{{task?.ext?.tf_slaveUnitNameStr}}
</el-descriptions-item>
<el-descriptions-item label="办理意见" :span="3">
<div v-html="task.taskFormData.tf_opinion"></div>
</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="承办单位"
v-if="['master_reply','slave_reply'].includes(task.taskName)" :span="3">
{{task.ext.underTakeName}}
</el-descriptions-item>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理评价" v-if="['feedback'].includes(task.taskName)" :span="3">
<dict-tag :options="dict.type.PROPOSAL_FEEDBACK"
:value="task.ext.tf_feedback"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理结果" v-else>
<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.ext.isFirstTaskNode">
<div v-html="task.taskFormData.tf_opinion"></div>
</el-descriptions-item>
</el-descriptions>
</div>
</template>
<slot></slot>
</div>
`,
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE", "PROCESS_TASK_SUBMIT_TYPE", "PROPOSAL_FEEDBACK"],
props: {
hide_slave: false
},
data() {
return {
viewData: {},
doneTasks: [],
row: null,
viewDialogVisible: false
}
},
methods: {
// 打开
onOpen(row) {
this.row = row
this.visible = true
this.getInfo()
this.getDoneTasks()
},
// 获取申请信息
getInfo() {
this.$axios.post("/platform/proposal/common/proposalInfo", {id: this.row.id}).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
// 查看提案
openView(row) {
this.viewDialogVisible = true
this.$nextTick(() => {
this.$refs.infoDialogRef.onOpen(row)
})
},
// 获取已办任务审批记录
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
},
style:
/*language=CSS*/
`
.proposal-info .el-descriptions__body .el-descriptions__table .el-descriptions-item__cell {
}
`
}
@@ -0,0 +1,123 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<template #header>
<h3 style="color: var(--color-primary)">提案全局配置</h3>
</template>
<el-form :model="formData" :rules="formRules" label-width="200px" ref="formRef" label-position="top" size="small">
<el-form-item label="附议人数量" prop="seconderNum">
<el-input-number :min="0" :max="10" v-model="formData.seconderNum"></el-input-number>
</el-form-item>
<el-form-item label="案由最少字数" prop="briefMinLength">
<el-input-number :min="0" v-model="formData.briefMinLength"></el-input-number>
</el-form-item>
<el-form-item label="校领导单位" prop="schoolLeaderUnitIds">
<el-select clearable filterable placeholder="校领导单位" multiple v-model="formData.schoolLeaderUnitIds" style="width: 100%">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unitOptions"></el-option>
</el-select>
</el-form-item>
<el-form-item label="协办单位是否需要答复" prop="slaveUnitNeedReply">
<el-radio-group v-model="formData.slaveUnitNeedReply" size="small">
<el-radio border :label="true"></el-radio>
<el-radio border :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="协办单位是否首先答复" prop="slaveUnitFirstReply" v-if="formData.slaveUnitNeedReply">-->
<!-- <span slot="label">-->
<!-- 协办单位是否首先答复-->
<!-- <el-tooltip content="开启后协办单位答复完成之后主办单位才可答复" placement="right">-->
<!-- <i class="el-icon-question"></i>-->
<!-- </el-tooltip>-->
<!-- </span>-->
<!-- <el-radio-group v-model="formData.slaveUnitFirstReply" size="small">-->
<!-- <el-radio border :label="true">是</el-radio>-->
<!-- <el-radio border :label="false">否</el-radio>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="协办单位领导单位是否需要审批" prop="slaveUnitLeaderNeedApprove">-->
<!-- <el-radio-group v-model="formData.slaveUnitLeaderNeedApprove" size="small">-->
<!-- <el-radio border :label="true">是</el-radio>-->
<!-- <el-radio border :label="false">否</el-radio>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<el-form-item label="撰写须知" prop="writeRemind">
<text-editor v-model="formData.writeRemind"></text-editor>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button type="primary" @click="save" style="width: 200px">保存</el-button>
</el-row>
</el-card>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
data() {
return {
unitOptions: [],
formData: {},
formRules: {
seconderNum: [{ required: true, message: "请输入附议人数量", trigger: ["blur", "change"] }],
briefMinLength: [{ required: true, message: "请输入案由最少字数", trigger: ["blur", "change"] }],
slaveUnitNeedReply: [{ required: true, message: "请选择协办单位是否需要答复", trigger: ["blur", "change"] }],
slaveUnitFirstReply: [{ required: true, message: "请选择协办单位是否首先答复", trigger: ["blur", "change"] }],
slaveUnitLeaderNeedApprove: [{ required: true, message: "请选择协办单位领导单位是否需要审批", trigger: ["blur", "change"] }],
writeRemind: [
{
required: true,
validator: (rule, value, callback) => {
value === "<p><br></p>" ? callback(new Error("请输入撰写须知")) : callback()
},
message: "请输入撰写须知",
trigger: ["blur", "change"]
}
],
schoolLeaderUnitIds: [{ required: true, message: "请选择校领导单位", trigger: ["blur", "change"] }]
}
}
},
watch: {
"formData.writeRemind"(val) {
this.$refs.formRef.validateField(["writeRemind"], (errMsg) => {})
}
},
methods: {
init() {
this.$axios.post(loc() + "/findOne").then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
},
save() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/update", {
config: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.init()
}
})
}
})
},
listUnit() {
this.$businessTool.listUnit().then((res) => (this.unitOptions = res))
}
},
created() {
this.init()
this.listUnit()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,106 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="名称">
<el-input v-model="pageForm.name" placeholder="请输入名称"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" border stripe>
<el-table-column label="序号" type="index" :index="indexMethod" width="50px"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="code" label="编码"></el-table-column>
<el-table-column label="操作" width="150px">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
<el-button size="mini" type="danger" @click="doDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :visible.sync="dialogVisible" :title="formData.id?'编辑':'新增'" width="500px">
<el-form :model="formData" :rules="formRules" label-width="80px" ref="formRef" size="small">
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入名称" max="10"></el-input>
</el-form-item>
<el-form-item label="编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入编码" max="10"></el-input>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="submit">提交</el-button>
</div>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
formRules: {
name: [{ required: true, message: "请输入名称", trigger: ["blur", "change"] }],
code: [{ required: true, message: "请输入编码", trigger: ["blur", "change"] }]
},
dialogVisible: false
}
},
methods: {
openAdd() {
this.formData = {}
this.dialogVisible = true
},
openEdit(row) {
this.formData = { ...row }
this.dialogVisible = true
},
submit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), this.formData).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.dialogVisible = false
this.pageData()
}
})
}
})
},
doDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post(loc() + "/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,92 @@
const BASIC_XC_FORM_COMPONENT = {
template: `
<div>
<table-tool>
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd()">新建机构</el-button>
</table-tool>
<el-table key="1" :data="tableData" ref="tableRef">
<el-table-column label="序号" type="index" :index="indexMethod"></el-table-column>
<el-table-column prop="name" label="机构名称"></el-table-column>
<el-table-column prop="name" label="机构编码"></el-table-column>
<el-table-column prop="name" label="备注"></el-table-column>
<el-table-column label="操作" width="100px">
<template slot-scope="{row}">
<el-link size="mini" type="primary" @click="openEdit(row)">编辑</el-link>
<el-link size="mini" type="danger" @click="del(row.id)">删除</el-link>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogFormVisible" :title="formData.id?'编辑':'新增'" width="40%">
<el-form :model="formData" ref="formRef" :rules="rules" label-width="100px">
<el-form-item label="上级机构">
<el-input :value="formData.parentName" disabled></el-input>
</el-form-item>
<el-form-item label="机构名称" prop="name">
<el-select v-if="parentData.name==='专门委员会'"
v-model="formData.committee"
value-key="id"
style="width: 100%"
@change="committeeChange"
:disabled="formData.id!=null">
<el-option v-for="i in committeeOptions" :label="i.name" :value="i" :key="i.id"></el-option>
</el-select>
<el-input v-else placeholder="请输入机构名称" :disabled="formData.id!=null"
v-model="formData.name"></el-input>
</el-form-item>
<el-form-item label="备注" prop="notes">
<el-input v-model="formData.notes" placeholder="请输入备注"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
</div>
`,
mixins: [initTableMixins],
data() {
return {
rules: {},
parentNode: {},
parentData: {},
committeeOptions: []
}
},
methods: {
openEdit(row) {},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), this.formData).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
this.$emit("refresh", null)
}
})
}
})
},
del(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post(loc() + "/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
this.$emit("refresh", null)
}
})
})
},
committeeChange(val) {}
}
}
@@ -0,0 +1,113 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row type="flex" :gutter="10" style="height: calc(100vh - 84px)">
<el-col :span="5">
<tree @node-click="treeNodeClick" ref="treeRef"></tree>
</el-col>
<el-col :span="19">
<el-card shadow="never" style="height: 100%" :body-style="{ height: '100%' , display: 'flex' , 'flex-direction': 'column' }">
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter);flex-shrink: 0">
<el-row type="flex" :gutter="20">
<el-col :span="6">
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入关键字"></el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
</el-col>
</el-row>
</el-card>
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter);flex: 1;" :body-style="{ height: '100%', display: 'flex' , 'flex-direction': 'column' }">
<table-tool>
<el-button type="primary" size="small" icon="el-icon-refresh" @click="syncSysUnit">同步系统单位</el-button>
</table-tool>
<el-table :data="tableData" border ref="tableRef" height="100%">
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
<el-table-column prop="name" label="单位名称" show-overflow-tooltip></el-table-column>
<el-table-column prop="code" label="单位编码" width="150px"></el-table-column>
<!-- <el-table-column prop="branchSchoolLeader" label="分管校领导及联系方式" width="180px"></el-table-column>-->
<el-table-column prop="unitLeader" label="单位领导及联系方式" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="350px">
<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="danger" @click="onDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</el-card>
</el-col>
</el-row>
<user ref="userRef" @refresh="doSearch"></user>
</div>
<script nonce="${cspNonce!}">
<!--#include("tree.js"){}#-->
<!--#include("user.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
tree: TREE_COMPONENT,
user: USER_COMPONENT
},
computed: {
hasChildren() {
if (this.currentTreeData) {
return this.currentTreeData.children && this.currentTreeData.children.length > 0
} else {
return false
}
}
},
data() {
return {
currentTreeNode: null,
currentTreeData: null
}
},
methods: {
treeNodeClick(data, node) {
this.currentTreeData = data
this.currentTreeNode = node
},
syncSysUnit() {
this.$axios.post(loc() + "/syncSysUnit").then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.$refs.treeRef.listTree()
}
})
},
onDelete (row) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
$.post(loc() + "/delete", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
this.$refs.treeRef.listTree()
}
})
})
},
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,66 @@
const TREE_COMPONENT = {
template: `
<el-card shadow="never" style="height: 100%" :body-style="{ height: '100%' }">
<el-input placeholder="输入关键字进行查找" v-model="name" clearable class="mb10">
</el-input>
<div style="max-height: calc(100% - 50px);overflow-y: auto">
<el-tree
:data="treeData"
ref="treeRef"
:expand-on-click-node="false"
:props="{
children: 'children',
label: 'name'
}"
default-expand-all
@node-click="treeNodeClick"
:filter-node-method="filterNode"
>
<template slot-scope="{ node, data }">
<span class="el-tree-node__label">
<i class="el-icon-folder-opened" v-if="node.level===1"></i>
<i class="el-icon-folder" v-else></i>
{{node.label}}
</span>
</template>
</el-tree>
</div>
</el-card>
`,
data() {
return {
currentTreeNode: null,
currentTreeData: null,
sessionOptions: [],
name: null,
treeData: []
}
},
watch: {
name(val) {
this.$refs.treeRef.filter(val)
}
},
methods: {
treeNodeClick(data, node) {
this.currentTreeData = data
this.currentTreeNode = node
this.$emit("node-click", data, node)
},
filterNode(value, data, node) {
if (!value) return true
return data.name.indexOf(value) !== -1
},
listTree() {
this.$axios.post("/platform/proposal/config/unit/tree").then((res) => {
if (res.code === 0) {
this.treeData = res.data
this.$emit("node-click", this.treeData[0], null)
}
})
}
},
created() {
this.listTree()
}
}
@@ -0,0 +1,66 @@
const USER_COMPONENT = {
template: `
<el-dialog title="设置领导" :visible.sync="visible" width="1000px" :close-on-click-modal="false">
<el-transfer
ref="transferRef"
:titles="['可选人员', '已选人员']"
filterable
:props="{
key: 'id',
label: 'label'
}"
:left-default-checked="[]"
:filter-method="filterUnit"
v-model="selectUserIds"
:data="allUsers"
></el-transfer>
<div slot="footer" class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
visible: false,
selectUserIds: [],
allUsers: [],
unitId: null,
isSchoolLeader: ""
}
},
methods: {
onOpen(id, isSchoolLeader) {
this.isSchoolLeader = isSchoolLeader
this.unitId = id
this.visible = true
this.$axios
.post("/platform/proposal/config/unit/" + (isSchoolLeader ? "branchSchoolLeaderTransferData" : "unitUsersTransferData"), { id })
.then((res) => {
this.selectUserIds = res.data.selectUserIds
this.allUsers = res.data.allUsers
})
this.$refs.transferRef.clearQuery("left")
this.$refs.transferRef.clearQuery("right")
},
doSubmit() {
this.$axios
.post("/platform/proposal/config/unit/" + (this.isSchoolLeader ? "updateBranchSchoolLeader" : "updateUnitLeader"), {
userIds: JSON.stringify(this.selectUserIds),
id: this.unitId
})
.then((res) => {
if (res.code === 0) {
this.visible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
},
filterUnit(query, item) {
return item.username.indexOf(query) > -1
}
}
}
@@ -0,0 +1,349 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.nodes-title {
font-size: 16px;
font-weight: 600;
color: #303133;
}
.nodes-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.node-card {
background: #fff;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-top: 4px solid var(--theme-color);
transition: all 0.3s ease;
display: flex;
align-items: center;
min-height: 80px;
position: relative;
}
.node-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
cursor: pointer;
}
.node-card.selected {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
border-top-width: 4px;
}
.node-card.selected .node-icon {
transform: scale(1.1);
}
.node-icon {
width: 50px;
height: 50px;
border-radius: 50%;
background: var(--theme-color);
display: flex;
align-items: center;
justify-content: center;
margin-right: 16px;
font-size: 24px;
color: #fff;
}
.node-content {
flex: 1;
}
.node-name {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 8px;
line-height: 1.4;
}
.node-count {
font-size: 28px;
font-weight: 700;
color: var(--theme-color);
line-height: 1;
}
.task-toggle {
position: absolute;
top: 8px;
right: 8px;
display: flex;
background: rgba(255, 255, 255, 0.9);
padding: 2px;
}
.task-toggle-btn {
padding: 4px 8px;
font-size: 12px;
border: none;
background: transparent;
color: #666;
cursor: pointer;
transition: all 0.2s ease;
min-width: 36px;
}
.task-toggle-btn.active {
background: var(--theme-color);
color: #fff;
}
.task-toggle-btn:hover:not(.active) {
background: rgba(0, 0, 0, 0.05);
}
@media (max-width: 768px) {
.nodes-title {
font-size: 14px;
}
.nodes-grid {
grid-template-columns: 1fr;
gap: 15px;
}
.node-card {
padding: 16px;
min-height: 70px;
}
.node-icon {
width: 40px;
height: 40px;
font-size: 20px;
margin-right: 12px;
}
.node-name {
font-size: 14px;
}
.node-count {
font-size: 24px;
}
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="sessionChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<div slot="header" class="nodes-title">统计看板</div>
<div class="nodes-grid">
<div
v-for="(node, index) in nodes"
:key="node.id"
class="node-card"
:class="{ selected: pageForm.selectNodeId === node.id }"
:style="'--theme-color:' + getThemeColor(index)"
@click="selectNode(node,index)"
>
<!-- task类型节点的切换按钮 -->
<div v-if="node.type === 'task'" class="task-toggle" @click.stop>
<button
class="task-toggle-btn"
:class="{ active: getNodeDisplayMode(node.id) === 'todo' }"
@click="setNodeDisplayMode(node, 'todo')"
>
待办
</button>
<button
class="task-toggle-btn"
:class="{ active: getNodeDisplayMode(node.id) === 'done' }"
@click="setNodeDisplayMode(node, 'done')"
>
已办
</button>
</div>
<div class="node-icon">
<i class="fa fa-tasks"></i>
</div>
<div class="node-content">
<div class="node-name">{{ node.name || '未命名节点' }}</div>
<div class="node-count">{{ getNodeCount(node) }}</div>
</div>
</div>
</div>
</el-card>
<el-card shadow="never" class="mt10">
<div slot="header" class="clearfix">
<span class="nodes-title">{{ tableCardTitle }}</span>
</div>
<el-table :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" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column label="主办单位" prop="masterUnitName" show-overflow-tooltip></el-table-column>
<el-table-column label="协办单位" prop="slaveUnitNames" show-overflow-tooltip></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
new Vue({
el: '#app',
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT"],
components: {
"proposal-info": PROPOSAL_INFO
},
mixins: [initTableMixins],
data() {
return {
sessionOptions: [],
nodes: [],
nodeDisplayModes: {}, // 存储每个节点的显示模式
pageForm: {
selectNodeId: null,
selectNodeType: null,
pageSize: 5
}
}
},
methods: {
// 查看
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
// 届次改变
sessionChange() {
this.getNodes()
this.doSearch()
},
// 获取届次
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.getNodes()
this.doSearch()
}
}
})
},
// 获取节点
getNodes() {
this.$axios.post('/platform/proposal/dashboard/listNode', {sessionId: this.pageForm.sessionId}).then(res => {
if (res.code === 0) {
this.nodes = res.data
}
})
},
// 获取主题色
getThemeColor(index) {
const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#722ED1']
return colors[index % colors.length]
},
// 节点选择
selectNode(node, index) {
this.pageForm.selectNodeId = node.id
this.pageForm.selectNodeType = node.type
this.pageForm.selectNodeMode = this.getNodeDisplayMode(node.id)
this.doSearch()
},
// 获取节点显示数量
getNodeCount(node) {
if (node.type === 'task') {
const displayMode = this.getNodeDisplayMode(node.id)
return displayMode === 'todo' ? (node.todoCount || 0) : (node.doneCount || 0)
}
return node.count || 0
},
// 获取节点显示模式
getNodeDisplayMode(nodeId) {
return this.nodeDisplayModes[nodeId] || 'todo' // 默认显示待办
},
// 设置节点显示模式
setNodeDisplayMode(node, mode) {
this.$set(this.nodeDisplayModes, node.id, mode)
this.selectNode(node, null)
}
},
computed: {
tableCardTitle() {
if (this.pageForm.selectNodeId) {
const selectedNode = this.nodes.find(node => node.id === this.pageForm.selectNodeId)
return selectedNode ? selectedNode.name : '提案总数'
}
return '提案总数'
}
},
created() {
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,333 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-tag {
cursor: pointer;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId"
@change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
<search-item label="承办单位">
<el-select clearable filterable placeholder="承办单位" v-model="pageForm.underTakeUnitId">
<el-option :key="item.code" :label="item.name" :value="item.id"
v-for="item in underTakeOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<div style="display: flex; align-items: center; min-height: 70px; border-bottom: 1px dashed rgb(230, 230, 230)">
<div style="width: 90px;margin-right: 10px">提案类别</div>
<div style="flex: 1;display: flex;gap: 5px;">
<el-tag
v-for="item in typeOptions"
:key="item.code"
:effect="pageForm.typeIds && pageForm.typeIds.includes(item.id) ? 'dark':'plain'"
@click="tagToggle('typeIds',item.id)"
>
{{ item.name }}
</el-tag>
</div>
</div>
<div style="display: flex; align-items: center; min-height: 70px; border-bottom: 1px dashed rgb(230, 230, 230)">
<div style="width: 90px;margin-right: 10px">立案结果</div>
<div style="flex: 1;display: flex;gap: 5px;">
<el-tag
v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT"
:key="item.code"
:effect="pageForm.caseFilingResults && pageForm.caseFilingResults.includes(item.code) ? 'dark':'plain'"
@click="tagToggle('caseFilingResults',item.code)"
>
{{ item.label }}
</el-tag>
</div>
</div>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportAllProposalAsZip">导出提案压缩包</el-button>
<el-button type="primary" size="small" @click="exportCollectZip">导出提案征集表压缩包</el-button>
<el-button type="primary" size="small" @click="exportAllProposalFeedBackAsZip">导出反馈表压缩包
</el-button>
<el-button type="primary" size="small" @click="exportSummaryAsExcel">导出汇总表</el-button>
<!-- <el-button type="primary" size="small" @click="exportProposalRegisterSummaryAsExcel">导出立案汇总表-->
<el-button type="primary" size="small" @click="exportCustomAsExcel">自定义导出</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"
fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'caseFilingType'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="row.caseFilingType"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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" min-width="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button size="mini" type="primary" @click="exportDocx(row.id)">导出</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
typeOptions: [],
delegationOptions: [],
underTakeOptions: [],
unionOptions: [],
unitOptions: [],
businessNo: "",
tabActive: "0",
pageForm: {
typeIds: [],
caseFilingResults: [],
unionId: null,
unitId: null
},
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "代表团", prop: "delegationName"},
{label: "立案结果", prop: "caseFilingResult"},
{label: "立案类型", prop: "caseFilingType"},
{label: "是否并案", prop: "merge"},
{label: "案由", prop: "brief", visible: false},
{label: "建议措施", prop: "measures", visible: false},
{label: "主办单位", prop: "masterUnitName"},
{label: "协办单位", prop: "slaveUnitNames"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
]
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
exportAllProposalAsZip() {
this.$downLoad(loc() + "/exportAllProposalAsZip", {
pageForm: JSON.stringify(this.pageForm)
})
},
exportCollectZip() {
this.$downLoad(loc() + "/exportCollectZip", {
pageForm: JSON.stringify(this.pageForm)
})
},
exportAllProposalFeedBackAsZip() {
this.$downLoad(loc() + "/exportAllProposalFeedBackAsZip", {
pageForm: JSON.stringify(this.pageForm)
})
},
exportDocx(id) {
this.$downLoad("/platform/proposal/common/exportProposalAsDocx", {id})
},
exportSummaryAsExcel() {
this.$downLoad("/platform/proposal/export/comprehensive/exportSummaryAsExcel", {
pageForm: JSON.stringify(this.pageForm)
})
},
exportProposalRegisterSummaryAsExcel() {
this.$downLoad("/platform/proposal/export/comprehensive/exportProposalRegisterSummaryAsExcel", {
pageForm: JSON.stringify(this.pageForm)
})
},
exportCustomAsExcel() {
this.$downLoad("/platform/proposal/export/comprehensive/exportCustomAsExcel", {
pageForm: JSON.stringify(this.pageForm),
tableColumns: JSON.stringify(this.tableColumns.filter(item => item.visible !== false))
})
},
tagToggle(key, val) {
if (this.pageForm[key].includes(val)) {
this.pageForm[key].splice(this.pageForm[key].indexOf(val), 1)
} else {
this.pageForm[key].push(val)
}
this.doSearch()
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
pageForm: JSON.stringify(this.pageForm)
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.listSession()
this.listUnderTake()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,268 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<el-card shadow="never">
<el-row type="flex" justify="center">
<el-select @change="doSearch" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId" style="width: 100%">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</el-row>
</el-card>
<el-row :gutter="10" class="mt10">
<el-col :span="12" v-loading="loading.satisfiedLoading">
<el-card class="box-card" shadow="never">
<div slot="header">
<span>提案满意度</span>
</div>
<div class="text item">
<div id="satisfiedChart"></div>
</div>
</el-card>
</el-col>
<el-col :span="12" v-loading="loading.typeLoading">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>提案类别</span>
</div>
<div class="text item">
<div id="typeChart"></div>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="10" class="mt10">
<el-col :span="12" v-loading="loading.resultLoading">
<el-card shadow="never">
<div slot="header" class="clearfix">
<span>立案结果</span>
</div>
<div class="text item">
<div id="resultChart"></div>
</div>
</el-card>
</el-col>
<el-col :span="12" v-loading="loading.stateLoading">
<el-card shadow="never">
<div slot="header" class="clearfix">
<span>提案状态</span>
</div>
<div class="text item">
<div id="stateChart"></div>
</div>
</el-card>
</el-col>
</el-row>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
const chart = {
satisfiedChart: undefined,
resultChart: undefined,
typeChart: undefined,
stateChart: undefined
}
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageForm: {
sessionId: null
},
sessionOptions: [],
loading: {
satisfiedLoading: false,
resultLoading: false,
typeLoading: false,
stateLoading: false
}
}
},
methods: {
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.doSearch()
}
}
})
},
doSearch() {
this.typeChart()
this.resultChart()
this.stateChart()
this.feedBackScoreChart()
},
typeChart() {
this.$axios.post(loc() + "/typeData", this.pageForm).then((res) => {
if (res.code === 0) {
this.loading.typeLoading = false
if (chart.typeChart) {
chart.typeChart.changeData(res.data)
return
}
chart.typeChart = new G2Plot.Column("typeChart", {
data: res.data,
xField: "typeName",
yField: "count",
meta: {
typeName: {
alias: "类别"
},
count: {
alias: "数量"
}
},
xAxis: {
label: {
autoRotate: true,
autoHide: false,
autoEllipsis: false
}
}
})
chart.typeChart.render()
}
})
},
resultChart() {
this.$axios.post(loc() + "/resultData", this.pageForm).then((res) => {
if (res.code === 0) {
if (chart.resultChart) {
chart.resultChart.changeData(res.data)
return
}
chart.resultChart = new G2Plot.Radar("resultChart", {
data: res.data,
xField: "name",
yField: "count",
seriesField: "type",
meta: {
count: {
alias: "数量",
min: 0
}
},
xAxis: {
line: null,
tickLine: null,
grid: {
line: {
style: {
lineDash: null
}
}
}
},
yAxis: {
line: null,
tickLine: null,
grid: {
line: {
type: "line",
style: {
lineDash: null
}
}
}
},
area: {},
point: {
size: 2
}
})
chart.resultChart.render()
}
})
},
stateChart() {
this.$axios.post(loc() + "/stateData", this.pageForm).then((res) => {
if (res.code === 0) {
if (chart.stateChart) {
chart.stateChart.changeData(res.data)
return
}
chart.stateChart = new G2Plot.Radar("stateChart", {
data: res.data,
xField: "name",
yField: "count",
meta: {
count: {
alias: '数量',
},
},
xAxis: {
line: null,
tickLine: null,
grid: {
line: {
style: {
lineDash: null
}
}
}
},
yAxis: {
line: null,
tickLine: null,
grid: {
line: {
type: "line",
style: {
lineDash: null
}
}
}
},
point: {
size: 2
}
})
chart.stateChart.render()
}
})
},
feedBackScoreChart() {
this.$axios.post(loc() + "/feedBackScoreData", this.pageForm).then((res) => {
if (res.code === 0) {
if (chart.feedBackScoreChart) {
chart.feedBackScoreChart.changeData(res.data)
return
}
chart.satisfiedChart = new G2Plot.Pie("satisfiedChart", {
data: res.data,
appendPadding: 10,
angleField: "count",
colorField: "name",
radius: 0.75,
color: ["#9661BC", "#5B8FF9", "#61DDAA"],
label: {
type: "spider",
labelHeight: 28,
content: "{name}\n{percentage}"
},
interactions: [{ type: "element-selected" }, { type: "element-active" }]
})
chart.satisfiedChart.render()
}
})
}
},
created() {
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,230 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable
v-model="pageForm.createUserKeyword"></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId"
@change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案类别">
<el-select clearable filterable multiple placeholder="提案类别" v-model="pageForm.typeIds">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in typeOptions"></el-option>
</el-select>
</search-item>
<search-item label="立案结果">
<el-select clearable filterable multiple placeholder="立案结果"
v-model="pageForm.caseFilingResults">
<el-option :key="item.code" :label="item.label" :value="item.code"
v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT"></el-option>
</el-select>
</search-item>
<search-item label="征集阶段">
<el-select v-model="pageForm.collectIds" clearable multiple filterable>
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in collectOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :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="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'instanceState'" 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="100px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName"},
{label: "代表团", prop: "delegationName"},
{label: "邀请附议人数", prop: "inviteCount"},
{label: "已附议人数", prop: "finishCount"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
sessionOptions: [],
collectOptions: [],
typeOptions: [],
delegationOptions: [],
underTakeOptions: [],
unionOptions: [],
unitOptions: [],
pageForm: {
typeIds: [],
caseFilingResults: [],
unionId: null,
unitId: null,
collectIds: []
}
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
listCollectState() {
this.$axios.post("/platform/proposal/query/collectProgress/collectState").then((res) => {
if (res.code === 0) {
this.collectOptions = res.data
}
})
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
pageForm: JSON.stringify(this.pageForm)
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.listSession()
this.listUnion()
this.listUnit()
this.listProposalType()
this.listCollectState()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,391 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-tag {
cursor: pointer;
}
.search-container {
display: flex;
align-items: center;
min-height: 50px;
border-bottom: 1px solid #ddd;
padding: 12px 0;
margin-bottom: 0;
}
.search-label {
width: 90px;
margin-right: 10px;
font-weight: normal;
color: #333;
font-size: 14px;
}
.search-content {
flex: 1;
display: flex;
gap: 5px;
}
.custom-search-box {
display: flex;
align-items: center;
width: 100%;
background: #ffffff;
border: 1px solid #ccc;
border-radius: 3px;
}
.custom-search-box:hover {
border-color: #999;
}
.custom-search-box:focus-within {
border-color: #4a90e2;
box-shadow: 0 0 3px rgba(74, 144, 226, 0.3);
}
.search-input {
flex: 1;
height: 35px;
padding: 0 10px;
border: none;
outline: none;
font-size: 14px;
color: #333;
background: transparent;
font-family: inherit;
width: 100%;
}
.search-input::placeholder {
color: #999;
}
.filter-row {
display: flex;
align-items: center;
min-height: 50px;
border-bottom: 1px dashed rgb(230, 230, 230);
}
.filter-label {
width: 90px;
margin-right: 10px;
}
.filter-tags {
flex: 1;
display: flex;
gap: 5px;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<!-- 万能搜索框 -->
<div class="search-container">
<div class="search-label">万能搜索</div>
<div class="search-content">
<div class="custom-search-box">
<input
type="text"
v-model="pageForm.commonKeyword"
placeholder="请输入关键词进行搜索"
class="search-input"
@keyup.enter="doSearch"
/>
</div>
</div>
</div>
<div class="filter-row">
<div class="filter-label">搜索来源</div>
<div class="filter-tags">
<el-tag
v-for="item in origins"
:key="item.value"
:effect="pageForm.origins && pageForm.origins.includes(item.value) ? 'dark':'plain'"
@click="tagToggle('origins',item.value)"
>
{{ item.label }}
</el-tag>
</div>
</div>
<div class="filter-row">
<div class="filter-label">届次</div>
<div class="filter-tags">
<el-tag
v-for="item in sessionOptions"
:key="item.id"
:effect="pageForm.sessionIds && pageForm.sessionIds.includes(item.id) ? 'dark':'plain'"
@click="tagToggle('sessionIds',item.id)"
>
{{ item.fullName }}
</el-tag>
</div>
</div>
<div class="filter-row">
<div class="filter-label">提案类别</div>
<div class="filter-tags">
<el-tag
v-for="item in typeOptions"
:key="item.code"
:effect="pageForm.typeIds && pageForm.typeIds.includes(item.id) ? 'dark':'plain'"
@click="tagToggle('typeIds',item.id)"
>
{{ item.name }}
</el-tag>
</div>
</div>
<div class="filter-row">
<div class="filter-label">立案结果</div>
<div class="filter-tags">
<el-tag
v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT"
:key="item.code"
:effect="pageForm.caseFilingResults && pageForm.caseFilingResults.includes(item.code) ? 'dark':'plain'"
@click="tagToggle('caseFilingResults',item.code)"
>
{{ item.label }}
</el-tag>
</div>
</div>
<div class="filter-row">
<div class="filter-label">立案类型</div>
<div class="filter-tags">
<el-tag
v-for="item in dict.type.PROPOSAL_CASE_FILING_TYPE"
:key="item.code"
:effect="pageForm.caseFilingTypes && pageForm.caseFilingTypes.includes(item.code) ? 'dark':'plain'"
@click="tagToggle('caseFilingTypes',item.code)"
>
{{ item.label }}
</el-tag>
</div>
</div>
<search @search="doSearch" class="mt10">
<search-item label="代表团">
<el-select clearable filterable placeholder="请选择所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="所属工会">
<el-select clearable filterable placeholder="请选择所属工会" v-model="pageForm.unionId"
@change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="请选择所属单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" ref="tableRef"
style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
<el-tag v-else type="warning" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button size="mini" type="primary" @click="exportDocx(row.id)">导出</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
const vue = new Vue({
el: "#app",
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
{label: "代表团", prop: "delegationName"},
{label: "立案结果", prop: "caseFilingResult"},
{label: "立案类型", prop: "caseFilingType"},
{label: "是否并案", prop: "merge"},
{label: "主办单位", prop: "masterUnitName"},
{label: "协办单位", prop: "slaveUnitNames"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
sessionOptions: [],
typeOptions: [],
delegationOptions: [],
underTakeOptions: [],
unionOptions: [],
unitOptions: [],
pageForm: {
origins: [],
sessionIds: [],
typeIds: [],
caseFilingResults: [],
caseFilingTypes: [],
unionId: null,
unitId: null
},
origins: [
{
label: '提案名称',
value: 'name'
},
{
label: '案由',
value: 'brief'
},
{
label: '答复内容',
value: 'answer'
},
{
label: '提案人',
value: 'createUserName'
}
]
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
exportDocx(id) {
this.$downLoad("/platform/proposal/common/exportProposalAsDocx", {id})
},
tagToggle(key, val) {
if (this.pageForm[key].includes(val)) {
this.pageForm[key].splice(this.pageForm[key].indexOf(val), 1)
} else {
this.pageForm[key].push(val)
}
this.doSearch()
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession", {
orderBy: "asc"
}).then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
pageForm: JSON.stringify(this.pageForm)
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.listSession()
this.listUnderTake()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,149 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<template>
<el-card shadow="never">
<el-row type="flex" justify="center">
<el-select @change="doSearch" clearable filterable placeholder="所属教代会" v-model="sessionId" style="width: 100%">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</el-row>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="代表团列表" :columns.sync="tableColumns"></table-tool>
<el-table :data="tableData" ref="tableRef" header-align="center" style="width: 100%" row-key="id" show-summary>
<el-table-column
:index="indexMethod"
label="序号"
type="index"
width="80px"
fixed="left"
></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template scope="{row}" v-if="column.prop=='dbtName'">
<el-link @click="openView(row)" type="primary">{{row.dbtName}}</el-link>
</template>
<template scope="{row}" v-else-if="column.prop=='caseRate'">
<span v-if="!isNaN(row.CONFIRM_FILING) && !isNaN(row.TOTAL) && row.TOTAL > 0">
{{ ((row.CONFIRM_FILING / row.TOTAL) * 100).toFixed(2) }}%
</span>
</template>
</el-table-column>
</el-table>
</el-card>
</template>
</guava>
<el-dialog :title="dialogTitle" :visible.sync="delegationVisible" width="70%" :close-on-click-modal="false">
<proposal-table
:delegation-id="delegationId"
:session-id="sessionId"
@view-single-proposal="viewSingleProposal"
ref="proposalTable"
></proposal-table>
</el-dialog>
<el-dialog title="提案详情" :visible.sync="proposalInfoVisible" width="1200px" append-to-body top="5vh">
<div style="max-height: 80vh; overflow-y: auto">
<proposal-info ref="infoRef"></proposal-info>
</div>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
<!--#include("proposalTable.js"){}#-->
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
sessionId: "",
sessionOptions: [],
tableColumns: [
{ label: "代表团名称", prop: "dbtName" },
{ label: "提案总数", prop: "TOTAL" },
],
delegationId: "",
dialogTitle: "",
delegationVisible: false,
proposalInfoVisible: false
}
},
components: {
"proposal-table": PROPOSAL_TABLE,
"proposal-info": PROPOSAL_INFO
},
methods: {
openView(row) {
this.delegationId = row.id
this.dialogTitle = row.dbtName + "所属提案"
this.delegationVisible = true
this.$nextTick(() => {
this.$refs.proposalTable.pageData()
})
},
viewSingleProposal(row) {
this.proposalInfoVisible = true
this.$nextTick(() => {
this.$refs.infoRef.onOpen(row)
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
},
setTableColumnsByProposalResult() {
this.$businessTool.getDictOptions("PROPOSAL_CASE_FILING_RESULT").then((data) => {
data.forEach((item) => {
this.tableColumns.push({
label: item.name,
prop: item.code
})
})
this.tableColumns.push({
label: "立案率",
prop: "caseRate"
})
})
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
sessionId: this.sessionId
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data
}
})
}
},
created() {
this.listSession()
this.setTableColumnsByProposalResult()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,50 @@
const PROPOSAL_TABLE = {
template: `
<div>
<el-table :data="tableData" ref="tableRef" header-align="center" style="width: 100%" row-key="id" @sort-change="pageOrder">
<el-table-column label="序号" width="50px" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="200px"></el-table-column>
<el-table-column label="提案名称" prop="name"></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="当前节点" prop="curTaskName"></el-table-column>
<el-table-column label="操作" fixed="right" width="100px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="$emit('view-single-proposal',row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
`,
props: {
sessionId: {
type: String,
required: true
},
delegationId: {
type: String,
required: true
}
},
mixins: [initTableMixins],
data() {
return {
pageForm: {}
}
},
methods: {
pageData() {
this.pageForm.sessionId = this.sessionId
this.pageForm.delegationId = this.delegationId
this.$axios.post("/platform/proposal/query/delegation/getProposalsByDelegation", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
}
}
@@ -0,0 +1,257 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-tag {
cursor: pointer;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId" @change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案类别">
<el-select clearable filterable multiple placeholder="提案类别" v-model="pageForm.typeIds">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in typeOptions"></el-option>
</el-select>
</search-item>
<search-item label="立案结果">
<el-select clearable filterable multiple placeholder="立案结果" v-model="pageForm.caseFilingResults">
<el-option :key="item.code" :label="item.label" :value="item.code" v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT"></el-option>
</el-select>
</search-item>
<search-item label="立案类型">
<el-select clearable filterable multiple placeholder="立案类型" v-model="pageForm.caseFilingTypes">
<el-option :key="item.code" :label="item.label" :value="item.code" v-for="item in dict.type.PROPOSAL_CASE_FILING_TYPE"></el-option>
</el-select>
</search-item>
<!-- <search-item label="承办单位">-->
<!-- <el-select clearable filterable placeholder="承办单位" v-model="pageForm.undertakeUnitId">-->
<!-- <el-option :key="item.code" :label="item.name" :value="item.code" v-for="item in underTakeOptions"></el-option>-->
<!-- </el-select>-->
<!-- </search-item>-->
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :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" width="120px" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="立案类型" prop="caseFilingType">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="row.caseFilingType"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="merge">
<template slot-scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
<el-tag v-else type="warning" size="small"></el-tag>
</template>
</el-table-column>
<el-table-column label="主办单位" prop="masterUnitName" show-overflow-tooltip></el-table-column>
<el-table-column label="协办单位" prop="slaveUnitNames" show-overflow-tooltip></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button size="mini" type="primary" @click="exportDocx(row.id)">导出</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
typeOptions: [],
delegationOptions: [],
underTakeOptions: [],
unionOptions: [],
unitOptions: [],
pageForm: {
typeIds: [],
caseFilingResults: [],
caseFilingTypes: [],
unionId: null,
unitId: null
}
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
exportDocx(id) {
this.$downLoad("/platform/proposal/common/exportProposalAsDocx", {id})
},
tagToggle(key, val) {
if (this.pageForm[key].includes(val)) {
this.pageForm[key].splice(this.pageForm[key].indexOf(val), 1)
} else {
this.pageForm[key].push(val)
}
this.doSearch()
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
pageForm: JSON.stringify(this.pageForm)
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.listSession()
this.listUnderTake()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,571 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.plagiarism-check-container {
}
.search-section {
margin-bottom: 20px;
}
.settings-section {
margin-bottom: 20px;
}
.similarity-level {
display: flex;
align-items: center;
margin: 10px 0;
}
.similarity-level .level-label {
width: 100px;
font-weight: bold;
}
.similarity-high {
color: #f56c6c;
}
.similarity-medium {
color: #e6a23c;
}
.similarity-low {
color: var( --color-success);
}
.result-card {
margin-bottom: 15px;
border-left: 4px solid #ddd;
transition: all 0.3s;
}
.result-card.high-similarity {
border-left-color: #f56c6c;
background-color: #fef0f0;
}
.result-card.medium-similarity {
border-left-color: #e6a23c;
background-color: #fdf6ec;
}
.result-card.low-similarity {
border-left-color: #67c23a;
background-color: #f0f9ff;
}
.similarity-progress {
margin: 10px 0;
}
.similar-content {
background-color: #f5f7fa;
padding: 10px;
border-radius: 4px;
margin: 10px 0;
font-size: 14px;
line-height: 1.6;
}
.highlight {
background-color: #ffeb3b;
padding: 2px 4px;
border-radius: 2px;
}
.stats-card {
text-align: center;
padding: 20px;
}
.stats-number {
font-size: 24px;
font-weight: bold;
color: var(--color-primary);
}
.loading-container {
text-align: center;
padding: 50px;
}
.empty-result {
text-align: center;
padding: 50px;
color: #909399;
}
</style>
<div id="app" v-cloak>
<div class="plagiarism-check-container">
<!-- 搜索区域 -->
<el-card shadow="never" class="search-section">
<div slot="header">
<span style="font-weight: 600">📝 提案查重检测</span>
</div>
<el-row :gutter="20">
<el-col :span="16">
<el-input
v-model="searchForm.keywords"
placeholder="请输入要查重的关键字或提案内容..."
type="textarea"
:rows="3"
maxlength="500"
show-word-limit
@keyup.ctrl.enter.native="startPlagiarismCheck"
></el-input>
</el-col>
<el-col :span="8">
<div style="height: 100%; display: flex; flex-direction: column; justify-content: space-between;">
<el-button
type="primary"
size="medium"
:loading="checking"
@click="startPlagiarismCheck"
style="margin-bottom: 10px;"
>
<i class="el-icon-search"></i> 开始查重
</el-button>
<el-button
size="medium"
@click="clearSearch"
style="margin: 0"
>
<i class="el-icon-refresh-left"></i> 清空重置
</el-button>
</div>
</el-col>
</el-row>
</el-card>
<!-- 查重设置区域 -->
<el-card shadow="never" class="settings-section">
<div slot="header">
<span style="font-weight: 600">⚙️ 查重设置</span>
</div>
<el-row :gutter="20">
<el-col :span="6">
<div>
<label>教代会届次:</label>
<el-select
v-model="searchForm.sessionId"
placeholder="选择届次"
clearable
style="width: 100%; margin-top: 5px;"
>
<el-option label="全部届次" value=""></el-option>
<el-option
v-for="item in sessionOptions"
:key="item.id"
:label="item.fullName"
:value="item.id"
></el-option>
</el-select>
</div>
</el-col>
<el-col :span="6">
<div>
<label>相似度阈值:{{ searchForm.similarityThreshold }}%</label>
<el-slider
v-model="searchForm.similarityThreshold"
:min="10"
:max="90"
:step="5"
show-stops
style="margin-top: 15px;"
></el-slider>
</div>
</el-col>
<el-col :span="6">
<div>
<label>匹配范围:</label>
<el-select v-model="searchForm.matchScope" multiple clearable
style="width: 100%; margin-top: 5px;">
<el-option label="全部" value="all"></el-option>
<el-option label="案名" value="name"></el-option>
<el-option label="案由" value="brief"></el-option>
<el-option label="建议措施" value="measures"></el-option>
</el-select>
</div>
</el-col>
<el-col :span="6">
<div>
<label>提案类别:</label>
<el-select
v-model="searchForm.typeId"
placeholder="选择类别"
clearable
style="width: 100%; margin-top: 5px;"
>
<el-option label="全部类别" value=""></el-option>
<el-option
v-for="item in typeOptions"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</div>
</el-col>
</el-row>
</el-card>
<!-- 结果统计区域 -->
<el-card shadow="never" v-if="hasSearched && !checking">
<div slot="header">
<span>📊 查重结果统计</span>
</div>
<el-row :gutter="20">
<el-col :span="6">
<div class="stats-card">
<div class="stats-number">{{ totalResults }}</div>
<div>检测到相似提案</div>
</div>
</el-col>
<el-col :span="6">
<div class="stats-card">
<div class="stats-number similarity-high">{{ highSimilarityCount }}</div>
<div>高度相似 (≥80%)</div>
</div>
</el-col>
<el-col :span="6">
<div class="stats-card">
<div class="stats-number similarity-medium">{{ mediumSimilarityCount }}</div>
<div>中度相似 (60-79%)</div>
</div>
</el-col>
<el-col :span="6">
<div class="stats-card">
<div class="stats-number similarity-low">{{ lowSimilarityCount }}</div>
<div>低度相似 (10-59%)</div>
</div>
</el-col>
</el-row>
</el-card>
<!-- 加载状态 -->
<div v-if="checking" class="loading-container">
<el-icon class="is-loading"><i class="el-icon-loading"></i></el-icon>
<p>正在进行查重检测,请稍候...</p>
</div>
<!-- 查重结果展示区域 -->
<div v-if="hasSearched && !checking">
<el-card shadow="never" v-if="plagiarismResults.length === 0">
<div class="empty-result">
<i class="el-icon-document" style="font-size: 48px; color: #c0c4cc;"></i>
<p>未发现相似提案</p>
<p style="font-size: 14px; color: #909399;">您可以尝试调整查重设置或更换关键词</p>
</div>
</el-card>
<div v-else>
<!-- 结果操作工具栏 -->
<el-card shadow="never" style="margin-bottom: 20px;">
<el-row>
<el-col :span="12">
<span style="font-weight: bold;">共找到 {{ plagiarismResults.length }} 个相似提案</span>
</el-col>
<el-col :span="12" style="text-align: right;">
<el-button-group>
<el-button size="mini" @click="sortResults('similarity')">
<i class="el-icon-sort"></i> 按相似度排序
</el-button>
<el-button size="mini" @click="sortResults('time')">
<i class="el-icon-time"></i> 按时间排序
</el-button>
</el-button-group>
</el-col>
</el-row>
</el-card>
<!-- 结果筛选 -->
<el-card shadow="never" style="margin-bottom: 20px;">
<div style="display: flex; align-items: center; gap: 20px;">
<span>快速筛选:</span>
<el-button-group>
<el-button
size="mini"
:type="resultFilter === 'all' ? 'primary' : ''"
@click="filterResults('all')"
>
全部 ({{ totalResults }})
</el-button>
<el-button
size="mini"
:type="resultFilter === 'high' ? 'danger' : ''"
@click="filterResults('high')"
>
高度相似 ({{ highSimilarityCount }})
</el-button>
<el-button
size="mini"
:type="resultFilter === 'medium' ? 'warning' : ''"
@click="filterResults('medium')"
>
中度相似 ({{ mediumSimilarityCount }})
</el-button>
<el-button
size="mini"
:type="resultFilter === 'low' ? 'success' : ''"
@click="filterResults('low')"
>
低度相似 ({{ lowSimilarityCount }})
</el-button>
</el-button-group>
</div>
</el-card>
<!-- 结果列表 -->
<el-card
v-for="(result, index) in filteredResults"
:key="index"
shadow="hover"
:class="['result-card', getSimilarityClass(result.similarity)]"
>
<div>
<el-row>
<el-col :span="18">
<h4 style="margin: 0 0 10px 0; color: #303133;">
{{ result.title }}
</h4>
<div style="margin-bottom: 10px;">
<el-tag size="mini" type="info">{{ result.sessionName }}</el-tag>
<el-tag size="mini" type="primary" style="margin-left: 5px;">{{ result.typeName }}
</el-tag>
<span style="margin-left: 10px; color: #909399; font-size: 12px;">
提案人: {{ result.createUserName }} | {{ result.createTime }}
</span>
</div>
</el-col>
<el-col :span="6" style="text-align: right;">
<div style="margin-bottom: 10px;">
<span :class="getSimilarityClass(result.similarity)"
style="font-size: 18px; font-weight: bold;">
{{ result.similarity }}%
</span>
</div>
<el-progress
:percentage="result.similarity"
:color="getSimilarityColor(result.similarity)"
:show-text="false"
class="similarity-progress"
></el-progress>
</el-col>
</el-row>
<div class="similar-content" v-if="result.similarContent">
<strong>相似内容片段:</strong>
<div v-html="highlightSimilarText(result.similarContent)"></div>
</div>
<div style="margin-top: 15px;">
<el-button size="mini" type="primary" @click="viewProposalDetail(result)">
<i class="el-icon-view"></i> 查看详情
</el-button>
</div>
</div>
</el-card>
</div>
</div>
</div>
<el-dialog title="提案详情" :visible.sync="viewDialogVisible" width="70%">
<proposal-info ref="infoRef"></proposal-info>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
checking: false,
hasSearched: false,
sessionOptions: [],
typeOptions: [],
searchForm: {
keywords: '',
sessionId: '',
similarityThreshold: 10,
matchScope: [],
typeId: ''
},
plagiarismResults: [],
resultFilter: 'all',
sortBy: 'similarity',
sortOrder: 'desc',
// 模拟数据,实际应从后端获取
mockResults: [],
viewDialogVisible: false,
}
},
computed: {
filteredResults() {
let results = [...this.plagiarismResults];
// 筛选
if (this.resultFilter !== 'all') {
results = results.filter(result => {
if (this.resultFilter === 'high') return result.similarity >= 80;
if (this.resultFilter === 'medium') return result.similarity >= 60 && result.similarity < 80;
if (this.resultFilter === 'low') return result.similarity < 60;
});
}
// 排序
results.sort((a, b) => {
let aValue, bValue;
if (this.sortBy === 'similarity') {
aValue = a.similarity;
bValue = b.similarity;
} else if (this.sortBy === 'time') {
aValue = new Date(a.createTime);
bValue = new Date(b.createTime);
}
if (this.sortOrder === 'desc') {
return bValue - aValue;
} else {
return aValue - bValue;
}
});
return results;
},
totalResults() {
return this.plagiarismResults.length;
},
highSimilarityCount() {
return this.plagiarismResults.filter(item => item.similarity >= 80).length;
},
mediumSimilarityCount() {
return this.plagiarismResults.filter(item => item.similarity >= 60 && item.similarity < 80).length;
},
lowSimilarityCount() {
return this.plagiarismResults.filter(item => item.similarity >= 10 && item.similarity < 60).length;
}
},
methods: {
startPlagiarismCheck() {
if (!this.searchForm.keywords.trim()) {
this.$message.warning('请输入要查重的关键字或内容');
return;
}
this.checking = true;
this.hasSearched = true;
this.$axios.post('/platform/proposal/query/plagiarismCheck/query', {
...this.searchForm,
matchScope: JSON.stringify(this.searchForm.matchScope)
}).then(res => {
if (res.code === 0) {
this.plagiarismResults = res.data;
if (this.plagiarismResults.length > 0) {
this.$message.success('查重完成,发现 ' + this.plagiarismResults.length + ' 个相似提案');
} else {
this.$message.info('查重完成,未发现相似提案');
}
}
}).finally(() => {
this.checking = false;
})
},
clearSearch() {
this.searchForm.keywords = '';
this.searchForm.sessionId = '';
this.searchForm.typeId = '';
this.searchForm.similarityThreshold = 60;
this.searchForm.matchScope = [];
this.plagiarismResults = [];
this.hasSearched = false;
},
getSimilarityClass(similarity) {
if (similarity >= 80) return 'high-similarity';
if (similarity >= 60) return 'medium-similarity';
return 'low-similarity';
},
getSimilarityColor(similarity) {
if (similarity >= 80) return '#f56c6c';
if (similarity >= 60) return '#e6a23c';
return '#67c23a';
},
//关键词高亮处理
highlightSimilarText(text) {
const keywords = this.searchForm.keywords.split(/\s+/).filter(k => k.trim());
let highlightedText = text;
keywords.forEach(keyword => {
const regex = new RegExp('(' + keyword + ')', 'gi');
highlightedText = highlightedText.replace(regex, '<span class="highlight">$1</span>');
});
return highlightedText;
},
// 排序功能
sortResults(type) {
if (this.sortBy === type) {
this.sortOrder = this.sortOrder === 'desc' ? 'asc' : 'desc';
} else {
this.sortBy = type;
this.sortOrder = 'desc';
}
},
// 筛选功能
filterResults(filter) {
this.resultFilter = filter;
},
// 查看提案详情功能
viewProposalDetail(result) {
this.viewDialogVisible = true;
this.$nextTick(() => {
this.$refs.infoRef.onOpen(result)
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
}
},
created() {
this.listSession();
this.listProposalType();
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,96 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="承办单位">
<el-select clearable filterable placeholder="承办单位" v-model="pageForm.undertakeUnitId">
<el-option :key="item.code" :label="item.name" :value="item.id" v-for="item in underTakeOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<el-table :data="tableData">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="单位名称" prop="unitName" width="400" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="提案总数" prop="sum" sortable></el-table-column>
<el-table-column label="主办提案">
<el-table-column label="提案数量" prop="masterSum" sortable></el-table-column>
<el-table-column label="已答复" prop="masterReplySum" sortable></el-table-column>
<el-table-column label="未答复" prop="masterNoReplySum" sortable></el-table-column>
</el-table-column>
<el-table-column label="协办提案">
<el-table-column label="提案数量" prop="slaveSum" sortable></el-table-column>
<el-table-column label="已答复" prop="slaveReplySum" sortable v-if="slaveNeedReply"></el-table-column>
<el-table-column label="未答复" prop="slaveNoReplySum" sortable v-if="slaveNeedReply"></el-table-column>
</el-table-column>
</el-table>
</el-card>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
underTakeOptions: [],
slaveNeedReply: false
}
},
methods: {
meetingChange() {
this.doSearch()
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
},
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
},
pageData() {
this.$axios.post(loc() + "/data", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.tableData
this.slaveNeedReply = res.data.slaveNeedReply
}
})
}
},
created() {
this.listSession()
this.listUnderTake()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,93 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="承办单位">
<el-select clearable filterable placeholder="承办单位" v-model="pageForm.undertakeUnitId">
<el-option :key="item.code" :label="item.name" :value="item.id"
v-for="item in underTakeOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<el-table :data="tableData">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="单位名称" prop="unitName" width="400" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="提案总数" prop="sum" sortable></el-table-column>
<el-table-column label="主办提案数" prop="masterSum" sortable></el-table-column>
<el-table-column label="协办提案数" prop="slaveSum" sortable></el-table-column>
<template v-for="dict in dict.type.PROPOSAL_FEEDBACK">
<el-table-column :label="dict.label" :prop="dict.code" sortable></el-table-column>
</template>
</el-table>
</el-card>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
dicts: ['PROPOSAL_FEEDBACK'],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
underTakeOptions: [],
}
},
methods: {
meetingChange() {
this.doSearch()
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
},
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
},
pageData() {
this.$axios.post(loc() + "/data", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data
}
})
}
},
created() {
this.listSession()
this.listUnderTake()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,251 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-tag {
cursor: pointer;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId" @change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
<search-item label="承办单位">
<el-select clearable filterable placeholder="承办单位" v-model="pageForm.underTakeUnitId">
<el-option :key="item.code" :label="item.name" :value="item.code" v-for="item in underTakeOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案类别">
<el-select clearable filterable multiple placeholder="提案类别" v-model="pageForm.typeIds">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in typeOptions"></el-option>
</el-select>
</search-item>
<search-item label="立案结果">
<el-select clearable filterable multiple placeholder="立案结果" v-model="pageForm.caseFilingResults">
<el-option :key="item.code" :label="item.label" :value="item.code" v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT"></el-option>
</el-select>
</search-item>
<search-item label="立案类型">
<el-select clearable filterable multiple placeholder="立案类型" v-model="pageForm.caseFilingTypes">
<el-option :key="item.code" :label="item.label" :value="item.code" v-for="item in dict.type.PROPOSAL_CASE_FILING_TYPE"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button type="primary" size="small" @click="exportYearReport">导出提案报告</el-button>
</table-tool>
<el-table :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" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column label="主办单位" prop="masterUnitName" show-overflow-tooltip></el-table-column>
<el-table-column label="协办单位" prop="slaveUnitNames" show-overflow-tooltip></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
typeOptions: [],
delegationOptions: [],
underTakeOptions: [],
unionOptions: [],
unitOptions: [],
pageForm: {
typeIds: [],
caseFilingResults: [],
unionId: null,
unitId: null
}
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
exportYearReport() {
this.$downLoad(loc() + "/exportYearReport", this.pageForm)
},
tagToggle(key, val) {
if (this.pageForm[key].includes(val)) {
this.pageForm[key].splice(this.pageForm[key].indexOf(val), 1)
} else {
this.pageForm[key].push(val)
}
this.doSearch()
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
pageForm: JSON.stringify(this.pageForm)
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.listSession()
this.listUnderTake()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,336 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId"
@change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :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" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="warning"></el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button size="mini" type="primary" @click="onOpenEdit(row)">修改</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
<template #edit>
<el-form :model="formData" ref="form" label-width="120px">
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item label="代表姓名" prop="createUserName">
<el-input readonly v-model="formData.createUserName" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提案时间" prop="createTime">
<el-input readonly v-model="formData.createTime" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item label="提案编号" prop="code"
:rules="[{required:true,message:'请输入提案编号',trigger:'blur'}]">
<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="name"
:rules="[{required:true,message:'请输入提案名称',trigger:'blur'}]">
<el-input maxlength="100" placeholder="提案名称" v-model="formData.name"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item label="提案方式" prop="source">
<el-input :value="dict.type.PROPOSAL_SOURCE.find(v=>v.code === formData.source)?.name"
disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提案类别" prop="typeId">
<el-select v-model="formData.typeId" style="width: 100%">
<el-option :key="item.code" :label="item.name" :value="item.id"
v-for="item in typeOptions"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item label="提案摘要" prop="excerpt">-->
<!-- <el-input-->
<!-- v-model="formData.excerpt"-->
<!-- type="textarea"-->
<!-- autosize-->
<!-- :autosize="{ minRows: 4, maxRows: 4}"-->
<!-- placeholder="提案摘要"-->
<!-- ></el-input>-->
<!-- </el-form-item>-->
<el-form-item label="建议承办单位" prop="suggestUnits">
<el-select v-model="formData.suggestUnits" multiple filterable style="width: 100%"
placeholder="请选择建议承办单位">
<el-option :key="item.id" :label="item.name" :value="item.name"
v-for="item in suggestUnitOptions"></el-option>
</el-select>
</el-form-item>
<el-form-item label="案由" prop="brief">
<text-editor v-model="formData.brief" key="brief" placeholder="案由"></text-editor>
</el-form-item>
<el-form-item label="建议措施" prop="measures">
<text-editor v-model="formData.measures" key="measures"
placeholder="建议措施"></text-editor>
</el-form-item>
<el-form-item label="附件上传" prop="files">
<file-upload
:value.sync="formData.files"
:upload_number="5"
upload_result_category="array"
upload_mode="drag"
complete_result
></file-upload>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()">取 消</el-button>
<el-button type="primary" @click="doUpdateBasic">确 定</el-button>
</el-row>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("/platform/zhgh/democratic/proposal/common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_SOURCE"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
typeOptions: [],
delegationOptions: [],
unionOptions: [],
unitOptions: [],
suggestUnitOptions: [],
pageForm: {
types: [],
caseFilingResults: [],
unionId: null,
unitId: null
},
typeDialog: false,
formData: {
suggestUnits: []
}
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onOpenEdit(row) {
this.$refs.guava.edit(() => {
let suggestUnits = []
try {
suggestUnits = JSON.parse(row.suggestUnits)
} catch (e) {
console.log(e)
}
this.formData = {
...row,
suggestUnits: suggestUnits
}
})
},
doUpdateBasic() {
this.$refs.form.validate((valid) => {
if (valid) {
this.$confirm("您确定要修改吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/senior/basic/update", {
info: JSON.stringify(this.formData)
}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.$refs.guava.index()
this.doSearch()
}
})
})
}
})
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
},
// 建议承办单位
listSuggestUnit() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.suggestUnitOptions = res.data
}
})
},
},
created() {
this.listSuggestUnit()
this.listSession()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,194 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId" @change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :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" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(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>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
typeOptions: [],
delegationOptions: [],
underTakeOptions: [],
unionOptions: [],
unitOptions: [],
pageForm: {
types: [],
caseFilingResults: [],
unionId: null,
unitId: null
}
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onDelete(id) {
this.$confirm("您确定删除该提案吗?", "提示", {
type: "warning"
}).then(() => {
this.$axios.post("/platform/senior/delete/delete", { id: id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
}
},
created() {
this.listSession()
this.listUnion()
this.listUnit()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,237 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="请选择所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="请输入提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="请输入提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="未答复列表">
<el-button type="primary" size="small" @click="onBatchHandle">
<i class="el-icon-s-promotion"></i>
批量催办
</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" reserve-selection width="55"></el-table-column>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'caseFilingResult'">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'instanceState'">
<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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="onHandle(row)" size="mini" type="primary">催办</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="proposalInfoRef"></proposal-info>
</template>
<template #edit>
<div class="process-title">所选提案列表</div>
<el-table :data="chooseTableData" style="width: 100%" max-height="600">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'caseFilingResult'">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
</el-table>
<div class="process-title">催办内容</div>
<el-input v-model="content" type="textarea" :rows="4" placeholder="请输入催办内容" max="500"></el-input>
<el-row type="flex" justify="end" class="mt20">
<el-button @click="$refs.guava.index()">取消</el-button>
<el-button @click="onSubmit" type="primary">提交</el-button>
</el-row>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["PROPOSAL_CASE_FILING_RESULT","PROPOSAL_REPLY_IMPLEMENT"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
pageForm: {},
formData: {},
sessionOptions: [],
delegationOptions: [],
tableColumns: [
{prop: 'code', label: '提案编号'},
{prop: 'name', label: '提案名称'},
{prop: 'typeName', label: '提案类别'},
{prop: 'delegationName', label: '代表团'},
{prop: 'caseFilingResult', label: '立案结果'},
{prop: 'curTaskName', label: '当前节点'},
{prop: 'underTakeName', label: '承办单位'},
{prop: 'taskName', label: '承办类型'},
{prop: 'actorName', label: '负责人'},
{prop: 'instanceState', label: '流程状态'},
],
chooseTableData: [],
multipleSelection: [],
content: '',
}
},
methods: {
onSubmit() {
if(!this.content) {
this.$message.warning('请输入催办内容')
return
}
this.$confirm("您选择了" + this.chooseTableData.length + "条提案,确定要催办吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/senior/expediting/submit", {
taskIds: JSON.stringify(this.chooseTableData.map(o => o.taskId)),
content: this.content
}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onBatchHandle() {
if(this.multipleSelection.length === 0) {
this.$message.warning('请先选择需要催办的提案')
return
}
this.chooseTableData = []
this.chooseTableData = clone(this.multipleSelection)
this.$refs.guava.edit()
},
onHandle(row) {
this.chooseTableData = []
this.chooseTableData.push(row)
this.$refs.guava.edit()
},
handleSelectionChange(val) {
this.multipleSelection = val
},
openView(row) {
this.$refs.guava.view(() => {
this.$refs.proposalInfoRef.onOpen(row)
})
},
// 教代会
async meetingChange(val) {
this.doSearch()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
this.listDelegation()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,292 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId"
@change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :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" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="warning"></el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="反馈评价" prop="tf_feedback" width="150px">
<template slot-scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_FEEDBACK" :value="row.tf_feedback"></dict-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button size="mini" type="primary" @click="onOpenEdit(row.instanceId)">修改</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
<el-dialog title="修改反馈评价" :visible.sync="editDialogVisible" width="50%">
<template v-for="task in tasks">
<el-descriptions border class="flow-task-form" :column="2" :key="task.id">
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果" :span="2">
<el-radio-group v-model="task.taskFormData.tf_feedback" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_FEEDBACK" :key="item.code"
:label="item.code" border>{{item.label}}
</el-radio>
</el-radio-group>
</el-descriptions-item>
<el-descriptions-item label="办理意见" :span="2" v-if="!task.ext.isFirstTaskNode">
<el-input
v-model="task.taskFormData.tf_opinion"
type="textarea"
:rows="3"
placeholder="请输入您的办理意见"
></el-input>
</el-descriptions-item>
<el-descriptions-item label="通讯地址" :span="2">
<el-input v-model="task.taskFormData.tf_address" placeholder="请输入通讯地址"
clearable></el-input>
</el-descriptions-item>
<el-descriptions-item label="联系电话" :span="2">
<el-input v-model="task.taskFormData.tf_phone" placeholder="请输入联系电话"
clearable></el-input>
</el-descriptions-item>
<el-descriptions-item label="邮政编码" :span="2">
<el-input v-model="task.taskFormData.tf_postcode" placeholder="请输入邮政编码"
clearable></el-input>
</el-descriptions-item>
</el-descriptions>
</template>
<el-row type="flex" justify="end" slot="footer">
<el-button @click="editDialogVisible=false">取 消</el-button>
<el-button type="primary" @click="onSubmit">确 定</el-button>
</el-row>
</el-dialog>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("/platform/zhgh/democratic/proposal/common/info.js"){}#-->
new Vue({
el: "#app",
store,
dicts: ['PROPOSAL_CASE_FILING_RESULT', 'PROCESS_TASK_SUBMIT_TYPE', 'PROPOSAL_FEEDBACK'],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
sessionOptions: [],
typeOptions: [],
delegationOptions: [],
unionOptions: [],
unitOptions: [],
pageForm: {
types: [],
caseFilingResults: [],
unionId: null,
unitId: null
},
tasks: [],
editDialogVisible: false
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onOpenEdit(instanceId) {
this.$axios.post('/platform/senior/feedback/info', {instanceId}).then(res => {
if (res.code === 0) {
this.tasks = res.data
if (this.tasks && this.tasks.length > 0) {
this.editDialogVisible = true
} else {
this.$message.warning("当前无法修改反馈评价")
}
}
})
},
onSubmit() {
const params = this.tasks.map(v => {
return {
id: v.id,
opinion: v?.taskFormData?.tf_opinion,
feedback: v?.taskFormData?.tf_feedback
}
})
this.$axios.post('/platform/senior/feedback/update', {data: JSON.stringify(params)}).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
this.editDialogVisible = false
this.doSearch()
}
})
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
pageForm: JSON.stringify(this.pageForm)
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.listSession()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,238 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案名称"
v-model="pageForm.name"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案编码">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案编码"
v-model="pageForm.code"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案分工会">
<el-select clearable filterable placeholder="分工会" v-model="pageForm.unionId" @change="pageForm.unitId=null;listUnit();">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案单位">
<el-select clearable filterable placeholder="提案单位" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unitOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :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" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
<el-button size="mini" type="primary" @click="onOpenEdit(row)">修改</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
<el-dialog title="修改提案类型" :close-on-click-modal="false" width="40%" :visible.sync="typeDialog">
<el-form :model="formData" ref="form" label-width="120px">
<el-form-item prop="oldTypeName" label="原类型">
<el-input disabled :value="formData.oldTypeName" type="text"></el-input>
</el-form-item>
<el-form-item prop="typeId" label="更改类型" :rules="[{required:true,message:'请选择类型',trigger:'blur'}]">
<el-select v-model="formData.typeId" style="width: 100%">
<el-option :key="item.code" :label="item.name" :value="item.id" v-for="item in typeOptions"></el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="typeDialog=false">取 消</el-button>
<el-button type="primary" @click="doUpdateType">确 定</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
typeOptions: [],
sessionOptions: [],
delegationOptions: [],
unionOptions: [],
unitOptions: [],
pageForm: {
types: [],
caseFilingResults: [],
unionId: null,
unitId: null
},
typeDialog: false
}
},
methods: {
onOpen(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
onOpenEdit(row) {
this.typeDialog = true
this.$nextTick(() => {
this.formData = {
id: row.id,
oldTypeName: this.typeOptions.find((item) => item.id === row.typeId)?.name,
typeId: null
}
})
},
doUpdateType() {
this.$refs.form.validate((valid) => {
if (valid) {
this.$confirm("您确定要修改吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/senior/type/update", this.formData).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.typeDialog = false
this.doSearch()
}
})
})
}
})
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => (this.unitOptions = res))
}
},
created() {
this.listSession()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,219 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable
v-model="pageForm.createUserKeyword"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" ref="tableRef" row-key="id" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"
fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="!row.pcoId" @click="openAudit(row)" size="mini" type="primary">审核</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
提案委员会成员意见
</div>
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules" label-suffix="">
<el-form-item label="立案结果" prop="caseFilingResult"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.caseFilingResult" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code"
border>{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="['CONFIRM_FILING'].includes(formData.caseFilingResult)" label="立案类型"
prop="caseFilingType"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.caseFilingType" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_TYPE" :label="item.code" border>
{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="审核意见" prop="opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="doSubmit" size="small" type="primary">提交</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "代表团", prop: "delegationName"},
{label: "立案票数", prop: "CONFIRM_FILING_COUNT"},
{label: "作为建议票数", prop: "SUGGESTION_COUNT"},
{label: "不予立案票数", prop: "NOT_COUNT"},
{label: "当前节点", prop: "taskName"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
formData: {
tf_masterUnitId: null,
tf_slaveUnitIds: []
},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
underTakeOptions: []
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
// 审批
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
proposalId: row.id,
caseFilingResult: null,
caseFilingType: null,
opinion: null
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
doSubmit() {
this.$refs.formRef.validate(async (valid) => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/proposal/commissioner/doApproval', this.formData).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
this.$refs.guava.index()
}
})
})
})
},
// 教代会
async meetingChange(val) {
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
},
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,339 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.createUserKeyword"></el-input>
</search-item>
<!-- <search-item label="提案人姓名">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人姓名"-->
<!-- v-model="pageForm.createUserName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
<!-- <search-item label="提案人工号">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人工号"-->
<!-- v-model="pageForm.createUserLoginName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" icon="el-icon-plus" size="small" @click="openMerge">并案审核</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" ref="tableRef" row-key="id" style="width: 100%">
<el-table-column type="selection" width="50" fixed="left" v-if="!pageForm.approval"></el-table-column>
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag v-if="row.taskState!==10"
:options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#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" label-width="120px" :rules="formRules" label-suffix="">
<el-form-item label="立案结果" prop="tf_caseFilingResult"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_caseFilingResult" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code"
border>{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="['CONFIRM_FILING'].includes(formData.tf_caseFilingResult)" label="立案类型"
prop="tf_caseFilingType"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_caseFilingType" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_TYPE" :label="item.code" border>
{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="主办单位"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:'必填',trigger:['change','blur']}]"
prop="tf_masterUnitId"
>
<el-select v-model="formData.tf_masterUnitId" filterable clearable style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="formData && formData.tf_slaveUnitIds.includes(item.id)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="协办单位"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
prop="tf_slaveUnitIds"
>
<el-select v-model="formData.tf_slaveUnitIds" filterable clearable multiple
style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="item.id===formData.tf_masterUnitId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核意见" prop="approvalOpinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
</div>
</proposal-info>
</template>
<template #public>
<merge ref="mergeRef" @close="$refs.guava.index()"></merge>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
<!--#include('merge.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO,
merge
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "立案结果", prop: "caseFilingResult"},
{label: "代表团", prop: "delegationName"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
formData: {
tf_masterUnitId: null,
tf_slaveUnitIds: []
},
formRules: {
tf_caseFilingResult: [{ required: true, message: "请选择立案结果", trigger: ["blur", "change"] }],
tf_caseFilingType: [{ required: true, message: "请选择立案类型", trigger: ["blur", "change"] }],
tf_masterUnitId: [{ required: true, message: "请选择主办单位", trigger: "blur" }],
approvalOpinion: [{ required: true, message: "请填写审核意见", trigger: "blur" }],
},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
underTakeOptions: []
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_masterUnitId: null,
tf_slaveUnitIds: []
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
// 是否有协办单位
let tf_helpunitreply;
if (this.formData.tf_slaveUnitIds && this.formData.tf_slaveUnitIds.length > 0) {
tf_helpunitreply = 'HAS_HELP_UNIT'
} else {
tf_helpunitreply = 'NO_HELP_UNIT'
}
const loading = createLoading('提交中')
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val,
tf_masterUnitName: this.formData.tf_masterUnitId ? this.underTakeOptions.find(v => v.id === this.formData.tf_masterUnitId)?.name : null,
tf_slaveUnitNames: this.formData.tf_slaveUnitIds.map(v => this.underTakeOptions.find(v2 => v2.id === v)?.name),
tf_slaveUnitNameStr: this.formData.tf_slaveUnitIds.map(v => this.underTakeOptions.find(v2 => v2.id === v)?.name).join(','),
tf_helpunitreply: tf_helpunitreply
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
}).finally(() => {
loading.close()
})
})
},
// 打开并案审核
openMerge() {
const selection = this.$refs.tableRef.selection
if (selection.length < 2) {
this.$message.warning('请先勾选需要并案审核的提案,至少需要两条提案')
return
}
this.$refs.guava.public(() => {
this.$refs.mergeRef.onOpen(selection, {
processTaskIds: selection.map(v => v.taskId),
taskName: selection[0].curTaskName,
tf_masterUnitId: null,
tf_slaveUnitIds: []
})
})
},
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()
}
})
})
},
// 教代会
async meetingChange(val) {
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
},
// 查询承办单位
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
this.listUnderTake()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,166 @@
const merge = {
template: /*language=HTML*/ `
<div>
<div class="process-title">
预选并案提案
</div>
<el-table :data="selection" ref="tableRef" row-key="id" style="width: 100%">
<el-table-column label="序号" width="50" type="index"></el-table-column>
<el-table-column label="提案编号" prop="code"></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="操作" fixed="right" width="100px">
<template scope="scope">
<el-button @click="onRemove(scope.$index)" size="mini" type="danger">移除</el-button>
</template>
</el-table-column>
</el-table>
<div>
<div class="process-title">
{{formData.taskName}}
</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']}]">
<el-radio-group v-model="formData.tf_caseFilingResult" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code"
border>{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="['CONFIRM_FILING'].includes(formData.tf_caseFilingResult)" label="立案类型"
prop="tf_caseFilingType"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_caseFilingType" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_TYPE" :label="item.code" border>
{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="主办单位"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:'必填',trigger:['change','blur']}]"
prop="tf_masterUnitId"
>
<el-select v-model="formData.tf_masterUnitId" filterable clearable style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="formData && formData.tf_slaveUnitIds.includes(item.id)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="协办单位"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
prop="tf_slaveUnitIds"
>
<el-select v-model="formData.tf_slaveUnitIds" filterable clearable multiple
style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="item.id===formData.tf_masterUnitId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核意见" prop="approvalOpinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$emit('close')" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
</div>
</div>
`,
dicts: ["PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE"],
data() {
return {
selection: [],
formData: {
tf_masterUnitId: null,
tf_slaveUnitIds: []
},
formRules: {
tf_caseFilingResult: [{ required: true, message: "请选择立案结果", trigger: ["blur", "change"] }],
tf_caseFilingType: [{ required: true, message: "请选择立案类型", trigger: ["blur", "change"] }],
tf_masterUnitId: [{ required: true, message: "请选择主办单位", trigger: "blur" }],
approvalOpinion: [{ required: true, message: "请填写审核意见", trigger: "blur" }],
},
underTakeOptions: []
}
},
methods: {
onOpen(selection, formData) {
this.selection = selection
this.formData = formData
this.listUnderTake()
},
// 移除
onRemove(index) {
if (this.selection.length === 2) {
this.$message.warning("并案审核至少两条提案")
return
}
this.selection.splice(index, 1)
},
// 查询承办单位
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
},
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
debugger
// 是否有协办单位
let tf_helpunitreply;
if (this.formData.tf_slaveUnitIds && this.formData.tf_slaveUnitIds.length > 0) {
tf_helpunitreply = 'HAS_HELP_UNIT'
} else {
tf_helpunitreply = 'NO_HELP_UNIT'
}
const loading = createLoading('提交中')
this.$axios.post("/platform/proposal/committeeFiling/merge", {
data: JSON.stringify({
...this.formData,
proposalIds: this.selection.map(v => v.id),
submitType: val,
tf_masterUnitName: this.formData.tf_masterUnitId ? this.underTakeOptions.find(v => v.id === this.formData.tf_masterUnitId)?.name : null,
tf_slaveUnitNames: this.formData.tf_slaveUnitIds.map(v => this.underTakeOptions.find(v2 => v2.id === v)?.name),
tf_slaveUnitNameStr: this.formData.tf_slaveUnitIds.map(v => this.underTakeOptions.find(v2 => v2.id === v)?.name).join(','),
tf_helpunitreply: tf_helpunitreply
})
}).then((res) => {
if (res.code === 0) {
this.$emit('close')
this.$message.success(res.msg)
this.doSearch()
}
}).finally(() => {
loading.close()
})
})
}
}
}
@@ -0,0 +1,430 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button @click="openConsolidationApproval" size="small" type="primary" class="mr5">重新并案审核</el-button>
<el-radio-group v-model="pageForm.approval" @change="doSearch();$refs.tableRef.clearSelection()" size="small">
<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"
ref="tableRef"
@sort-change="pageOrder"
header-align="center"
style="width: 100%"
:row-key="(val)=>{val.id + val.processInstanceTaskId}"
>
<el-table-column
v-if="!pageForm.approval"
type="selection"
reserve-selection
:selectable="(row)=>row.processInstanceTaskStatus==='ACTIVE'"
></el-table-column>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="120" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="代表团" prop="delegationName" show-overflow-tooltip></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.processInstanceTaskStatus==='ACTIVE'" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button>
<el-button
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #public>
<proposal-info ref="infoRef"></proposal-info>
<div v-if="showApprovalForm">
<div class="process-title">{{formData.processInstanceNodeName}}</div>
<el-alert v-if="formData.isConsolidation" type="success" title="提醒:本提案已并案,您只需审核一次即可!"></el-alert>
<el-divider></el-divider>
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">
<el-form-item label="立案结果" prop="caseFilingResult" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.caseFilingResult" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code" border>{{item.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="主办单位"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult),message:'必填',trigger:['change','blur']}]"
>
<el-select v-model="formData.hostUnitId" filterable clearable style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="formData && formData.helpUnitIds.includes(item.id)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="协办单位" v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult)">
<el-select v-model="formData.helpUnitIds" filterable clearable multiple style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="item.id===formData.hostUnitId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
</el-form-item>
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>-->
<!-- </el-form-item>-->
</el-form>
<el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button>
<el-button type="primary" @click="doApproval('DYNAMIC')">提交</el-button>
</el-row>
</div>
</template>
<template #edit>
<div class="process-title">并案提案列表</div>
<el-table :data="consolidationProposalTableData" size="small">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="120px" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" width="200px"></el-table-column>
<el-table-column label="代表团" prop="delegationName" width="300px"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" width="100px">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100px">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100px">
<template scope="{row}">
<el-link size="mini" type="primary" @click="openViewDialog(row)">查看</el-link>
</template>
</el-table-column>
</el-table>
<div class="process-title">{{consolidationFormData.processInstanceNodeName}}</div>
<el-form :model="consolidationFormData" ref="consolidationFormRef" label-position="left" label-width="80px">
<el-form-item label="立案结果" prop="caseFilingResult" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="consolidationFormData.caseFilingResult" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code" border>{{item.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="主办单位"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(consolidationFormData.caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(consolidationFormData.caseFilingResult),message:'必填',trigger:['change','blur']}]"
>
<el-select v-model="consolidationFormData.hostUnitId" filterable clearable style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="consolidationFormData && consolidationFormData.helpUnitIds.includes(item.id)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="协办单位" v-if="['CONFIRM_FILING','SUGGESTION'].includes(consolidationFormData.caseFilingResult)">
<el-select v-model="consolidationFormData.helpUnitIds" filterable clearable multiple style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="item.id===consolidationFormData.hostUnitId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="consolidationFormData.approvalOpinion"></user-opinion-textarea>
</el-form-item>
<el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<pc-signature v-model="consolidationFormData.approvalSignature"></pc-signature>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button>
<el-button type="primary" @click="doConsolidationApproval('PASS')">提交</el-button>
</el-row>
</template>
<el-dialog title="提案详情" :visible.sync="viewDialogVisible" width="1200px" top="50px" append-to-body>
<div style="max-height: 80vh; overflow-y: auto">
<proposal-info ref="infoDialogRef"></proposal-info>
</div>
</el-dialog>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
const vue = new Vue({
el: "#app",
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO_COMPONENT
},
data() {
return {
sessionOptions: [],
delegationOptions: [],
underTakeOptions: [],
formData: {
hostUnitIds: null,
helpUnitId: []
},
pageForm: {
approval: false
},
showApprovalForm: false,
//并案的提案列表
consolidationProposalTableData: [],
consolidationFormData: {},
viewDialogVisible: false
}
},
methods: {
openView(row) {
this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(row.id)
this.showApprovalForm = false
})
},
openApproval(row) {
this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(row.id)
this.formData = row.approvalParam
this.formData.isConsolidation = row.isConsolidation
this.$axios
.post(loc() + "/committeeFiling", {
processInstanceId: row.processInstanceId,
processInstanceTaskId: row.processInstanceTaskId
})
.then((res) => {
if (res.code === 0) {
this.$set(this.formData, "caseFilingResult", res.data.caseFilingResult)
this.$set(this.formData, "hostUnitId", res.data.hostUnitId)
this.$set(this.formData, "helpUnitIds", res.data.helpUnitIds || [])
this.$set(this.formData, "approvalOpinion", res.data.approvalOpinion)
this.$set(this.formData, "proposalIds", res.data.consolidationIds || [row.id])
}
})
this.showApprovalForm = true
})
},
doApproval(approvalType) {
this.formData.bpmTaskApprovalType = approvalType
this.$refs.approvalFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/approval", {
approval: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
openRevoke(taskId) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post(loc() + "/revoke", { taskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
viewSingleProposal(row) {
this.proposalInfoVisible = true
this.$nextTick(() => {
this.$refs.infoRef.onOpen(row.id)
})
},
//打开并案审核
openConsolidationApproval() {
const selection = this.$refs.tableRef.selection
if (selection.length < 2) {
this.$message.error("并案审核至少需要选择两条提案")
return
}
this.consolidationProposalTableData = selection
this.$refs.guava.edit()
this.consolidationFormData = selection[0].approvalParam
this.$set(this.consolidationFormData, "caseFilingResult", null)
this.$set(this.consolidationFormData, "hostUnitId", null)
this.$set(this.consolidationFormData, "helpUnitIds", [])
this.$set(this.consolidationFormData, "helpUnitIds", [])
this.$set(this.consolidationFormData, "approvalOpinion", null)
this.$set(
this.consolidationFormData,
"proposalIds",
selection.map((v) => v.id)
)
},
openViewDialog(row) {
this.viewDialogVisible = true
this.$nextTick(() => {
this.$refs.infoDialogRef.onOpen(row.id)
})
},
//并案审核
doConsolidationApproval() {
this.consolidationFormData.bpmTaskApprovalType = "DYNAMIC"
this.$refs.consolidationFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/approval", {
approval: JSON.stringify(this.consolidationFormData)
})
.then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$refs.tableRef.clearSelection()
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
//教代会change
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.delegationOptions = await proposal.getDelegation(val)
this.committeeOptions = await this.getInstitutions(val)
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
this.listDelegation()
}
}
})
},
listUnderTake() {
this.$axios.post(loc() + "/listUnderTake").then((res) => {
if (res.code === 0) {
this.underTakeOptions = res.data
}
})
}
},
created() {
this.listOpenSession()
this.listUnderTake()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,216 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.createUserKeyword"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#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="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "代表团", prop: "delegationName"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
showApprovalForm: false
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
})
},
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()
}
})
})
},
// 教代会
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.doSearch()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
this.listDelegation()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,237 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
<el-tag v-else type="warning" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'underTakeIsMaster'" scope="{row}">
<el-tag v-if="row.underTakeIsMaster" size="small">主办</el-tag>
<el-tag v-else type="warning" size="small">协办</el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">评价
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#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" label-width="120px" :rules="formRules" label-suffix="">
<el-form-item label="满意度" prop="tf_feedback"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_feedback" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_FEEDBACK" :key="item.code"
:label="item.code" border>{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<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="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["PROPOSAL_FEEDBACK"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "是否并案", prop: "merge"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
formData: {},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskKey: row.taskKey,
taskName: row.taskName,
instanceId: row.instanceId
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
const formData = {
...this.formData,
submitType: val
}
// 不满意
if (this.formData.tf_feedback === 'DISSATISFIED') {
const caseInfo = await this.getCaseInfo(this.formData.instanceId)
formData.tf_masterUnitId = caseInfo.tf_masterUnitId
}
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify(formData)
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
// 撤销
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()
}
})
})
},
// 获取立案信息
async getCaseInfo(instId) {
const {
data,
code
} = await this.$axios.post('/platform/proposal/feedbackEvaluation/caseInfo', {instId})
if (code === 0) {
return data
}
},
// 教代会
async meetingChange(val) {
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,153 @@
<div id="proposal-transact-apply-form">
<div>
<el-row type="flex" style="column-gap: 10px">
<el-col :span="6">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入工号或者姓名查询" clearable></el-input>
</el-col>
<el-col :span="6">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in delegationOptions"></el-option>
</el-select>
</el-col>
<el-col :span="4">
<el-button icon="el-icon-search" type="primary" @click="doSearch">查询</el-button>
</el-col>
</el-row>
<el-divider class="mt10 mb10"></el-divider>
<table-tool>
<el-radio-group v-model="pageForm.isInvite" @change="doSearch" size="small" style="margin-left: 5px">
<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"
ref="tableRef"
@sort-change="pageOrder"
size="small"
header-align="center"
style="width: 100%"
:row-key="getRowKey"
>
<el-table-column type="selection" reserve-selection v-if="!pageForm.isInvite"></el-table-column>
<el-table-column label="序号" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<!-- <el-table-column label="操作" width="150px">-->
<!-- <template scope="{row}">-->
<!-- <el-button size="mini" type="primary" @click="invite(row)">邀请</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
<snaker-flow-task-form-action @task-action="handleTaskAction"></snaker-flow-task-form-action>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#proposal-transact-apply-form",
store,
mixins: [initTableMixins],
data() {
return {
businessId: GetQueryString("businessId"),
sessionId: GetQueryString("sessionId"),
instanceId: GetQueryString("instanceId"),
secondedNum: 0,
pageForm: {
isInvite: false
},
config: {},
delegationOptions: []
}
},
methods: {
getRowKey(val) {
return val.loginName + this.pageForm.isInvite
},
// 数据查询
pageData() {
this.$axios
.post("/platform/proposal/invite/listSeconder", {
...this.pageForm,
sessionId: this.sessionId,
proposalId: this.businessId
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
//查询代表团
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
// 获取配置
async getConfig() {
const { code, data } = await this.$axios.post("/platform/proposal/common/config")
if (code === 0) {
this.config = data
}
},
handleTaskAction(val) {
console.log(val)
this.invite(val)
},
// 邀请
invite(val) {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.warning("请先选择附议人后再提交")
return
}
const loginNames = selection.map((s) => s.loginName)
const userName = selection.map((s) => s.userName)
this.$confirm("您确定要邀请" + userName.join("、") + "代表附议吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
tf_nextNodeOperator: selection.map((s) => s.userId),
tf_proposalId: this.businessId,
tf_seconders: JSON.stringify(selection)
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
})
}
},
created() {
debugger
this.getConfig()
this.listDelegation()
this.pageData()
}
})
</script>
@@ -0,0 +1,88 @@
<!--#
layout("/layouts/platform.html"){
#-->
<guava ref="guava">
<div id="app">
<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.title" placeholder="请输入标题" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code"></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
</guava>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/proposal/invite/pageData",
pageForm: {
approval: false
}
}
},
methods: {
openView(row) {
window.open(
"/flow/common/approval/form?taskId=" +
row.taskId +
"&instanceId=" +
row.instanceId +
"&businessId=" +
row.businessNo +
"&sessionId=" +
row.sessionId
)
},
onRevoke(row) {
console.log(row)
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,217 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns"></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'taskName'" scope="{row}">
<span>{{ (row.startTaskId) ? row.taskName : '待提交' }}</span>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="400px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" size="mini" type="primary"
@click="openEdit(row)">
编辑提案
</el-button>
<el-button
size="mini"
type="primary"
@click="onOpenInviteSeconder(row)"
v-if="row.taskKey === 'invite' || row.taskKey === 'second'"
>
邀请附议人
</el-button>
<el-button v-if="row.canRevoke" size="mini" type="danger" @click="openRevoke(row)">
撤回
</el-button>
<!-- v-if="row.taskKey === 'startTask' || !row.instanceId"-->
<el-button size="mini" type="danger" @click="del(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #public>
<invite-seconder ref="inviteSeconderRef" @refresh="doSearch"></invite-seconder>
</template>
<template #view>
<proposal-info ref="infoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
<!--#include("inviteSeconder.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO,
"invite-seconder": PROPOSAL_INVITE_SECONDER_COMPONENT
},
data() {
return {
sessionOptions: [],
businessNo: null,
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "代表团", prop: "delegationName"},
{label: "当前节点", prop: "taskName"},
{label: "流程状态", prop: "instanceState"}
]
}
},
methods: {
openView(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row)
})
},
openEdit(row) {
commonUtil.pjaxPush('/platform/proposal/write?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
},
openRevoke(row) {
this.$confirm("您确定要撤销申请吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
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()
}
})
})
},
onOpenInviteSeconder(row) {
this.$axios.post(loc() + "/inviteCheck", {id: row.id}).then((res) => {
if (res.code === 0) {
this.$refs.guava.public(() => {
this.$refs.inviteSeconderRef.onOpen(row)
})
}
})
},
//教代会change
async meetingChange(val) {
this.doSearch()
//this.delegationOptions = await proposal.getDelegation(val)
//this.committeeOptions = await this.getInstitutions(val)
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
withdraw({processInstId}) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post(loc() + "/withdraw", {processInstId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
del(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post(loc() + "/delete", {id}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
// 检测操作
checkOperation() {
const operation = GetQueryString("operation")
const bizId = GetQueryString("bizId")
if (!operation) return
if (operation === "invite" && bizId) {
// 邀请附议人
this.$axios.post('/platform/proposal/mine/selectOne',{id: bizId}).then(res=>{
if (res.code === 0) {
this.onOpenInviteSeconder(res.data)
}
})
}
}
},
created() {
this.listSession()
this.pageData()
this.checkOperation()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,183 @@
const PROPOSAL_INVITE_SECONDER_COMPONENT = {
/*language=HTML*/
template: `
<div>
<search @search="doSearch">
<search-item label="关键字">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入工号或者姓名查询"
clearable></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId"
style="width: 100%">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
</search>
<div style="display: flex;column-gap: 50px;">
<div style="flex: 1">
<el-divider class="mt10 mb10"></el-divider>
<div>
<table-tool label="代表数据">
<!-- <el-button size="small" @click="invite" type="primary" icon="el-icon-plus"-->
<!-- :disabled="pageForm.isInvite">邀请-->
<!-- </el-button>-->
<el-radio-group v-model="pageForm.isInvite" @change="doSearch" size="small"
style="margin-left: 5px;">
<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" ref="tableRef" @sort-change="pageOrder" header-align="center"
style="width: 100%" :row-key="getRowKey">
<el-table-column type="selection" reserve-selection
v-if="!pageForm.isInvite"></el-table-column>
<el-table-column label="序号" width="50px" type="index"
:index="indexMethod"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<!-- <el-table-column label="操作" width="150px">-->
<!-- <template scope="{row}">-->
<!-- <el-button size="mini" type="primary" @click="invite(row)">邀请</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
</div>
<div style="flex: 1">
<el-divider class="mt10 mb10"></el-divider>
<div v-if="$refs.tableRef">
<table-tool label="当前已选择"></table-tool>
<el-table :data="$refs.tableRef.selection">
<el-table-column label="序号" width="50px" type="index"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
</el-table>
<el-row type="flex" justify="center" class="p10">
<el-button @click="">取消</el-button>
<el-button @click="invite" type="primary">邀请</el-button>
</el-row>
</div>
</div>
</div>
</div>
`,
mixins: [initTableMixins],
data() {
return {
visible: false,
secondedNum: 0,
record: {},
pageForm: {
isInvite: false,
pageSize: 10
},
config: {},
delegationOptions: []
}
},
methods: {
getRowKey(val) {
return val.loginName + this.pageForm.isInvite
},
async onOpen(record) {
this.visible = true
this.record = record
await this.getConfig()
this.listDelegation()
this.pageData()
const {seconderNum} = this.config
this.$alert(
"1)请至少选择<span style='color: orange;font-weight: bold'>" +
seconderNum +
"</span>位以上(含" +
seconderNum +
"位)代表附议。<br>\n" +
"(2)邀请附议人后将不能再编辑提案,请确认提案内容后再邀请附议人。<br>",
{
title: "温馨提醒",
type: "warning",
dangerouslyUseHTMLString: true,
confirmButtonText: "确定",
callback: () => {
}
}
)
},
detail(id) {
},
invite() {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.warning("请先选择附议人后再邀请")
return
}
const loginNames = selection.map((s) => s.loginName)
const userName = selection.map((s) => s.userName)
this.$confirm("您确定要邀请" + userName.join("、") + "代表附议吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
const loading = createLoading('邀请中...')
this.$axios.post("/platform/proposal/mine/inviteSeconder", {
proposalId: this.record.id,
seconders: JSON.stringify(loginNames)
}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.$refs.tableRef.clearSelection()
this.pageData()
this.visible = false
this.$emit("refresh", null)
}
}).finally(() => loading.close())
})
},
pageData() {
this.$axios.post("/platform/proposal/mine/listSeconder", {
...this.pageForm,
sessionId: this.record.sessionId,
proposalId: this.record.id
}).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
//查询代表团
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.record.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
async getConfig() {
const {code, data} = await this.$axios.post("/platform/proposal/common/config")
if (code === 0) {
this.config = data
}
}
}
}
@@ -0,0 +1,244 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.createUserKeyword"></el-input>
</search-item>
<!-- <search-item label="提案人姓名">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人姓名"-->
<!-- v-model="pageForm.createUserName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
<!-- <search-item label="提案人工号">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人工号"-->
<!-- v-model="pageForm.createUserLoginName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
<el-tag v-else type="warning" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'underTakeIsMaster'" scope="{row}">
<el-tag v-if="row.underTakeIsMaster" size="small">主办</el-tag>
<el-tag v-else type="warning" size="small">协办</el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
</el-table>
<!--#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" label-width="120px" :rules="formRules" label-suffix="">
<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="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction('back')" size="small" type="danger">退回重新答复
</el-button>
<el-button @click="handleTaskAction('agree')" size="small" type="primary">同意答复</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "是否并案", prop: "merge"},
{label: "当前节点", prop: "curTaskName"},
{label: "审核人", prop: "auditUser"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
formData: {},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskKey: row.taskKey,
taskName: row.taskName,
proposalId: row.id
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
const formData = {
...this.formData,
tf_approval: val
}
delete formData.taskKey
delete formData.taskName
this.$axios.post("/platform/proposal/schoolLeaderApproval/executeTask", {
data: JSON.stringify(formData)
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
})
},
// 撤销
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()
}
})
})
},
// 教代会
async meetingChange(val) {
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,210 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</el-button>
<!-- <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回-->
<!-- </el-button>-->
</template>
</el-table-column>
</el-table>
<!--#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="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(20)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
{label: "代表团", prop: "delegationName"},
{label: "附议人", prop: "taskActorName"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_opinion: "同意该提案"
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
})
},
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()
}
})
})
},
// 教代会
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
this.listDelegation()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,320 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
/* 提案信息卡片样式 - OA风格 */
.proposal-info-card {
background: #ffffff;
border: 1px solid var(--border-color-lighter);
margin-bottom: 20px;
overflow: hidden;
}
.proposal-info-content {
padding: 16px;
background: #fafafa;
}
.info-item {
display: flex;
align-items: flex-start;
margin-bottom: 12px;
line-height: 1.6;
padding: 8px 12px;
background: #ffffff;
border-left: 3px solid var(--color-primary-2);
transition: all 0.2s ease;
}
.info-item:hover {
border-left-color: var(--color-primary);
}
.info-item:last-child {
margin-bottom: 0;
}
.info-item label {
color: var(--color-text-regular);
font-weight: 500;
min-width: 80px;
margin-right: 12px;
flex-shrink: 0;
font-size: 13px;
}
.info-item span {
color: var(--color-text-primary);
word-break: break-all;
flex: 1;
font-size: 13px;
}
</style>
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" style="width: 100%"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.createUserKeyword"></el-input>
</search-item>
<!-- <search-item label="提案人姓名">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人姓名"-->
<!-- v-model="pageForm.createUserName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
<!-- <search-item label="提案人工号">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人工号"-->
<!-- v-model="pageForm.createUserLoginName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
<template v-else-if="column.prop === 'suggestUnits'" scope="{row}">
{{ JSON.parse(row.suggestUnits)?.map(item => item).join('') || '' }}
</template>
<template v-else-if="column.prop === 'count'" scope="{ row }">
<el-link size="mini" type="primary" @click="openSuggestion(row)">{{ row.count }}</el-link>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" min-width="160px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="openAudit(row)" size="mini" type="primary">反馈意见</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
承办单位意见
</div>
<el-form :model="formData" ref="formRef" label-width="80px" :rules="formRules" label-suffix="">
<el-form-item label="承办意向" prop="result"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.result" size="small">
<el-radio v-for="item in dict.type.UNDERTAKE_SUGGESTION" :label="item.code" border>
{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="反馈意见" prop="opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<text-editor v-model="formData.opinion"></text-editor>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="onAudit()" size="small" type="primary">提交</el-button>
</el-row>
</div>
</proposal-info>
</template>
<template #view>
<template v-for="item,index in suggestionList">
<div style="display: flex; justify-content: space-between; align-items: center">
<div class="left-span-label">意见{{ index + 1 }}</div>
<div>
<el-button @click="onDelete(item)" size="mini" type="danger">删除</el-button>
</div>
</div>
<el-descriptions :column="2" border>
<el-descriptions-item label="反馈人">{{ item.userName }}</el-descriptions-item>
<el-descriptions-item label="所属单位">{{ item.unitName }}</el-descriptions-item>
<el-descriptions-item label="反馈时间">{{ item.time }}</el-descriptions-item>
<el-descriptions-item label="反馈结果">{{ item.result }}</el-descriptions-item>
<el-descriptions-item label="反馈意见">
<span v-html="item.opinion"></span>
</el-descriptions-item>
</el-descriptions>
</template>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["UNDERTAKE_SUGGESTION"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "代表团", prop: "delegationName"},
{label: "建议承办单位", prop: "suggestUnits"},
{label: "意见数", prop: "count"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
showApprovalForm: false,
formData: {},
sessionOptions: [],
suggestionList: [],
}
},
methods: {
openSuggestion(row) {
this.$axios.post('/platform/proposal/suggestion/selectSuggestion', {
proposalId: row.id,
}).then(res => {
if(res.code === 0) {
this.suggestionList = res.data
if(this.suggestionList.length === 0) {
this.$message.warning('暂无意见数')
return
}
this.$refs.guava.view()
} else {
this.$message.error(res.msg)
}
})
},
onDelete(row) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/proposal/suggestion/delete', { id: row.id, })
.then(res => {
if(res.code === 0) {
this.$message.success(res.msg)
this.$refs.guava.index()
this.pageData()
} else {
this.$message.error(res.msg)
}
})
})
},
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
proposalId: row.id,
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
onAudit() {
this.$refs.formRef.validate(valid => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/proposal/suggestion/suggest", this.formData).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
})
},
// 教代会
async meetingChange(val) {
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,256 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input>
</search-item>
<search-item label="提案人姓名">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人姓名"
v-model="pageForm.createUserName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="提案人工号">
<el-input
@keyup.enter.native="doSearch"
clearable
placeholder="请输入提案人工号"
v-model="pageForm.createUserLoginName"
style="width: 100%"
></el-input>
</search-item>
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<!-- <el-radio-group v-model="pageForm.approval" @change="doSearch" size="small" v-if="!pageForm.transfer" class="ml5">-->
<!-- <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"
@sort-change="pageOrder"
header-align="center"
style="width: 100%"
:row-key="(val)=>{val.id + val.processInstanceTaskId}"
>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column label="是否主办" prop="isMasterUnderTake" width="100">
<template scope="{row}">
<el-tag v-if="row.isMasterUnderTake" size="mini" type="success"></el-tag>
<el-tag v-else size="mini" type="info"></el-tag>
</template>
</el-table-column>
<el-table-column label="承办单位" prop="underTakeName" show-overflow-tooltip></el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" fixed="right" width="100px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
<!-- <el-button v-if="row.processInstanceTaskStatus==='ACTIVE'" @click="openApproval(row)" size="mini" type="primary">-->
<!-- 查阅-->
<!-- </el-button>-->
<!-- <el-button-->
<!-- v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"-->
<!-- @click="openRevoke(row.processInstanceTaskId)"-->
<!-- size="mini"-->
<!-- type="danger"-->
<!-- >-->
<!-- 撤回-->
<!-- </el-button>-->
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #public>
<proposal-info ref="infoRef"></proposal-info>
<div v-if="showApprovalForm">
<div class="process-title">{{formData.processInstanceNodeName}}</div>
<el-alert v-if="formData.isConsolidation" type="success" title="提醒:本提案已初步并案,您只需审批一次即可!"></el-alert>
<el-divider></el-divider>
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">
<el-form-item label="承办单位">
<el-input :value="formData.underTakeName" disabled></el-input>
</el-form-item>
<el-form-item label="能否承办" prop="canTake" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.canTake" size="small">
<el-radio label="可以承办" border>可以承办</el-radio>
<el-radio label="无法承办" border>无法承办</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="初步阅览意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-input
v-model="formData.approvalOpinion"
autosize
:autosize="{ minRows: 4}"
type="textarea"
placeholder="请输入初步阅览意见"
></el-input>
</el-form-item>
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>-->
<!-- </el-form-item>-->
</el-form>
<el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button>
<el-button type="primary" @click="doApproval('DYNAMIC')">提交</el-button>
</el-row>
</div>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
new Vue({
el: "#app",
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO_COMPONENT
},
data() {
return {
sessionOptions: [],
delegationOptions: [],
pageForm: {
approval: false,
transfer: false
},
showApprovalForm: false,
transferFormData: {},
transferDialogVisible: false,
transferUserOptions: []
}
},
methods: {
onOpen(row) {
this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(row.id)
this.showApprovalForm = false
})
},
openApproval(row) {
this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(row.id)
this.formData = row.approvalParam
this.$set(this.formData, "implementState", null)
this.$set(this.formData, "approvalOpinion", null)
this.formData.isConsolidation = row.isConsolidation
this.formData.underTakeName = row.underTakeName
this.formData.underTakeId = row.underTakeId
this.showApprovalForm = true
})
},
doApproval(approvalType) {
this.formData.bpmTaskApprovalType = approvalType
this.$refs.approvalFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/approval", {
approval: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
openRevoke(taskId) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post(loc() + "/revoke", { taskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
//教代会change
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.delegationOptions = await proposal.getDelegation(val)
this.committeeOptions = await this.getInstitutions(val)
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
this.listDelegation()
}
}
})
},
del() {},
openView(id) {}
},
created() {
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,435 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
/* 提案信息卡片样式 - OA风格 */
.proposal-info-card {
background: #ffffff;
border: 1px solid var(--border-color-lighter);
margin-bottom: 20px;
overflow: hidden;
}
.proposal-info-content {
padding: 16px;
background: #fafafa;
}
.info-item {
display: flex;
align-items: flex-start;
margin-bottom: 12px;
line-height: 1.6;
padding: 8px 12px;
background: #ffffff;
border-left: 3px solid var(--color-primary-2);
transition: all 0.2s ease;
}
.info-item:hover {
border-left-color: var(--color-primary);
}
.info-item:last-child {
margin-bottom: 0;
}
.info-item label {
color: var(--color-text-regular);
font-weight: 500;
min-width: 80px;
margin-right: 12px;
flex-shrink: 0;
font-size: 13px;
}
.info-item span {
color: var(--color-text-primary);
word-break: break-all;
flex: 1;
font-size: 13px;
}
</style>
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" style="width: 100%"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.createUserKeyword"></el-input>
</search-item>
<!-- <search-item label="提案人姓名">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人姓名"-->
<!-- v-model="pageForm.createUserName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
<!-- <search-item label="提案人工号">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人工号"-->
<!-- v-model="pageForm.createUserLoginName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<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" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
<el-tag v-else type="warning" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'underTakeIsMaster'" scope="{row}">
<el-tag v-if="row.underTakeIsMaster" size="small">主办</el-tag>
<el-tag v-else type="warning" size="small">协办</el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="转交" prop="transfer"
v-if="pageForm.approval && $auth.hasRoleOr('SYSADMIN,PROPOSAL_UNIT_LEADER')">
<template slot-scope="{row}">
{{row.transferUserName}}
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" min-width="250px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">答复
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
<!--承办单位领导、超级管理员才能转办-->
<el-button v-if="!pageForm.approval && $auth.hasRoleOr('SYSADMIN,PROPOSAL_UNIT_LEADER')"
@click="openTransfer(row)" size="mini" type="primary">转交
</el-button>
</template>
</el-table-column>
</el-table>
<!--#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" label-width="80px" :rules="formRules" label-suffix="">
<el-form-item label="承办单位">
<el-input :value="formData.underTakeName" disabled></el-input>
</el-form-item>
<el-form-item label="落实情况" prop="tf_implementState"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_implementState" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_REPLY_IMPLEMENT" :label="item.code" border>
{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="答复内容" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<text-editor v-model="formData.tf_opinion"></text-editor>
</el-form-item>
<el-form-item label="校领导" prop="tf_nextNodeOperator"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]"
v-if="supportCandidate && formData.underTakeIsMaster">
<el-select v-model="formData.tf_nextNodeOperator" placeholder="请选择校领导">
<el-option :key="item.id" :label="item.userName" :value="item.userId"
v-for="item in candidates"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
<el-dialog title="转交" :visible.sync="showTransferDialog" width="500px">
<!--展示提案基本信息 名称、编号等-->
<div class="proposal-info-card">
<div class="proposal-info-content">
<div class="info-item">
<label>提案编号:</label>
<span>{{ transferForm.code }}</span>
</div>
<div class="info-item">
<label>提案名称:</label>
<span>{{ transferForm.name }}</span>
</div>
<div class="info-item">
<label>代表团:</label>
<span>{{ transferForm.delegationName }}</span>
</div>
</div>
</div>
<el-form ref="transferFormRef" :model="transferForm" label-position="top">
<el-form-item label="转交给" prop="userId"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-select v-model="transferForm.userId"
placeholder="请选择转交用户"
filterable
remote
:remote-method="selectTransferUser"
style="width: 100%"
>
<el-option :key="item.id"
:label="item.username"
:value="item.id"
v-for="item in transferUserOptions"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="showTransferDialog = false" size="small">取消</el-button>
<el-button @click="handleTransfer" size="small" type="primary">提交</el-button>
</el-row>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
dicts: ["PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_REPLY_IMPLEMENT"],
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "立案结果", prop: "caseFilingResult"},
{label: "是否并案", prop: "merge"},
{label: "承办单位", prop: "underTakeName"},
{label: "承办类型", prop: "underTakeIsMaster"},
{label: "当前节点", prop: "curTaskName"},
{label: "审核人", prop: "auditUser"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
formData: {},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
candidates: [],
supportCandidate: false,
// 转交
showTransferDialog: false,
transferForm: {},
transferUserOptions: [],
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.loadCandidates(row.taskId)
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskKey: row.taskKey,
taskName: row.taskName,
proposalId: row.id,
underTakeName: row.underTakeName,
underTakeIsMaster: row.underTakeIsMaster
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
const loading = createLoading('提交中')
delete this.formData.underTakeIsMaster
delete this.formData.underTakeName
this.$axios.post("/platform/proposal/unitReply/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
}).finally(() => {
loading.close()
})
})
})
},
// 撤销
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()
}
})
})
},
// 加载候选人列表
loadCandidates(taskId) {
$.get("/flow/common/candidate", {taskId}).then((res) => {
if (res.code === 0) {
this.candidates = res.data.candidates
this.supportCandidate = res.data.support
}
})
},
// 打开转办
openTransfer(row) {
this.showTransferDialog = true
this.transferForm = {
taskId: row.taskId,
name: row.name,
code: row.code,
delegationName: row.delegationName
}
},
// 查询转办用户
selectTransferUser(keyword) {
this.$axios.post("/platform/proposal/unitReply/selectViceUser", {keyword}).then(res => {
if (res.code === 0) {
this.transferUserOptions = res.data
}
})
},
// 转办
handleTransfer() {
this.$refs.transferFormRef.validate(valid => {
if (!valid) return
const transferUserName = this.transferUserOptions.find(item => item.id === this.transferForm.userId)?.username
const name = this.transferForm.name
this.$confirm("您确定要将" + name + "提案转交给" + transferUserName + "办理吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post('/platform/proposal/unitReply/transfer', this.transferForm).then(res => {
if (res.code === 0) {
this.$message.success(res.msg)
this.showTransferDialog = false
this.doSearch()
}
})
})
})
},
// 教代会
async meetingChange(val) {
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,186 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
<search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.createUserKeyword"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<!-- <el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">-->
<!-- <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" @sort-change="pageOrder" style="width: 100%">
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
>
<template v-if="column.prop === 'caseFilingResult'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small"></el-tag>
</template>
<template v-else-if="column.prop === 'instanceState'" 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="100px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<proposal-info ref="proposalInfoRef"></proposal-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../../common/info.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "代表团", prop: "delegationName"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
approval: false
},
showApprovalForm: false
}
},
methods: {
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
if (!valid) return
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
})
},
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()
}
})
})
},
// 教代会
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.pageData()
this.listDelegation()
}
}
})
}
},
created() {
this.pageData()
this.listOpenSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,446 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style></style>
<div id="app" v-cloak>
<template>
<el-card shadow="never">
<snaker-start slot="header" label="撰写提案" define_key="JDHTA"></snaker-start>
<template>
<el-form :model="formData" :rules="formRules" label-width="120px" ref="addForm">
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item label="代表姓名" prop="createUserName">
<el-input readonly v-model="formData.createUserName" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提案时间" prop="createTime">
<el-input readonly v-model="formData.createTime" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item label="所属教代会" prop="sessionId">
<el-select
@change="meetingChange"
clearable
filterable
placeholder="所属教代会"
v-model="formData.sessionId"
style="width: 100%"
>
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属代表团" prop="delegationId">
<el-select clearable filterable placeholder="所属代表团" v-model="formData.delegationId"
style="width: 100%" disabled>
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</el-form-item>
<el-form-item label="所属委员会" prop="committeeId" v-if="formData.mannerCode=='W03'">
<el-select clearable filterable placeholder="所属委员会" v-model="formData.committeeId"
style="width: 100%">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in committeeOptions"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="单位" prop="unitName">
<el-input v-model="formData.unitName" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话" prop="mobile">
<el-input v-model="formData.mobile" clearable placeholder="联系电话"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item label="提案名称" prop="name">
<el-input maxlength="100" placeholder="提案名称" v-model="formData.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提案方式" prop="source">
<el-select v-model="formData.source" style="width: 100%">
<el-option :key="item.code" :label="item.name" :value="item.code"
v-for="item in sourceOptions"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-form-item label="提案类别" prop="typeId">
<el-select v-model="formData.typeId" style="width: 100%">
<el-option :key="item.code" :label="item.name" :value="item.id"
v-for="item in typeOptions"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item label="提案摘要" prop="excerpt">-->
<!-- <span slot="label">-->
<!-- 提案摘要-->
<!-- <el-tooltip content="请简述提案内容和依据、改进建议和措施摘要" placement="right">-->
<!-- <i class="el-icon-question"></i>-->
<!-- </el-tooltip>-->
<!-- </span>-->
<!-- <el-input-->
<!-- v-model="formData.excerpt"-->
<!-- type="textarea"-->
<!-- autosize-->
<!-- :autosize="{ minRows: 4, maxRows: 4}"-->
<!-- placeholder="提案摘要"-->
<!-- ></el-input>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="调研情况" prop="researchFindings">-->
<!-- <el-input-->
<!-- v-model="formData.researchFindings"-->
<!-- type="textarea"-->
<!-- autosize-->
<!-- :autosize="{ minRows: 4, maxRows: 4}"-->
<!-- placeholder="调研情况"-->
<!-- ></el-input>-->
<!-- </el-form-item>-->
<el-form-item label="建议承办单位" prop="suggestUnits">
<el-select v-model="formData.suggestUnits" multiple filterable style="width: 100%"
placeholder="请选择建议承办单位">
<el-option :key="item.id" :label="item.name" :value="item.name"
v-for="item in suggestUnitOptions"></el-option>
</el-select>
</el-form-item>
<el-form-item label="案由" prop="brief">
<text-editor v-model="formData.brief" key="brief" placeholder="案由"></text-editor>
</el-form-item>
<el-form-item label="建议措施" prop="measures">
<text-editor v-model="formData.measures" key="measures"
placeholder="建议措施"></text-editor>
</el-form-item>
<el-form-item label="附件上传" prop="files">
<file-upload
:value.sync="formData.files"
:upload_number="5"
upload_result_category="array"
upload_mode="drag"
complete_result
></file-upload>
</el-form-item>
<!-- <el-form-item label="电子签名" prop="signature">-->
<!-- <pc-signature v-model="formData.signature"></pc-signature>-->
<!-- </el-form-item>-->
</el-form>
<el-row justify="end" type="flex" v-if="isWriteTime">
<el-button type="primary" @click="onSave">保存</el-button>
<el-button type="primary" @click="onSubmit" v-if="!taskId">提交</el-button>
<el-button type="primary" @click="onSubmitAgain" v-else>提交</el-button>
</el-row>
</template>
</el-card>
</template>
<el-dialog title="提案撰写须知" :visible.sync="noticeDialogVisible" :show-close="false" width="50%">
<div v-html="proposalConfig.writeRemind" style="max-height: 50vh; overflow-y: auto"></div>
<div slot="footer">
<el-button type="primary" @click="noticeDialogVisible = false">我已知晓</el-button>
</div>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
const vue = new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formData: {},
sessionOptions: [],
sourceOptions: [],
delegationOptions: [],
committeeOptions: [],
typeOptions: [],
formRules: {
createUserName: [{required: true, message: "请填写提案人", trigger: ["blur", "change"]}],
createTime: [{required: true, message: "请填写提案时间", trigger: ["blur", "change"]}],
name: [{required: true, message: "请填写提案名称", trigger: ["blur", "change"]}],
source: [{required: true, message: "请选择提案方式", trigger: ["blur", "change"]}],
delegationId: [{required: true, message: "请选择所属代表团", trigger: ["blur", "change"]}],
sessionId: [{required: true, message: "请选择所属教代会", trigger: ["blur", "change"]}],
committeeId: [{required: true, message: "请选择所属委员会", trigger: ["blur", "change"]}],
typeId: [{required: true, message: "请选择提案类别", trigger: ["blur", "change"]}],
suggestUnits: [{required: true, message: "请选择建议承办单位", trigger: ["blur", "change"]}],
sign: [{required: true, message: "请扫描二维码进行签字", trigger: ["blur", "change"]}],
excerpt: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
researchFindings: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
brief: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
measures: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
unitName: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
mobile: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
signature: [{required: false, message: "请扫描二维码进行签字", trigger: ["blur", "change"]}]
},
proposalConfig: {},
noticeDialogVisible: false,
isWriteTime: true,
// 建议承办单位
suggestUnitOptions: []
}
},
methods: {
async onSave() {
const valid = await this.$refs["addForm"].validate()
if (valid) {
if (!this.formData.name || this.formData.name.trim().length < 1) {
this.$message.warning("请填写提案名称")
return
}
this.$axios.post("/platform/proposal/write/save", {info: JSON.stringify(this.formData)}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.formData = res.data
commonUtil.pjaxPush('/platform/proposal/mine')
}
})
}
},
// 提交
async onSubmit() {
const valid = await this.$refs["addForm"].validate()
if (valid) {
if (!this.formData.name || this.formData.name.trim().length < 1) {
this.$message.warning("请填写提案名称")
return
}
let brief = clone(this.formData.brief)
brief = removeHTMLTag(brief)
if (brief.length < this.proposalConfig.briefMinLength) {
this.$message.warning("提案内容和依据最少为" + this.proposalConfig.briefMinLength + "字")
return
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
const loading = createLoading('正在提交中')
this.$axios.post('/platform/proposal/write/submit', {info: JSON.stringify(this.formData)}).then(res => {
loading.close()
if (res.code === 0) {
this.$message.success("提交成功")
if (this.formData.source==="PERSONAL"){
this.$confirm("提交成功,是否立即去邀请附议人?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
commonUtil.pjaxPush('/platform/proposal/mine?bizId=' + res.data.id + "&operation=invite")
}).catch(() => {
this.$message.info("请到我的提案界面邀请附议人")
commonUtil.pjaxPush('/platform/proposal/mine')
})
}else{
commonUtil.pjaxPush('/platform/proposal/mine')
}
}
})
})
}
},
// 重新提交
async onSubmitAgain() {
const valid = await this.$refs["addForm"].validate()
if (valid) {
if (!this.formData.name || this.formData.name.trim().length < 1) {
this.$message.warning("请填写提案名称")
return
}
let brief = clone(this.formData.brief)
brief = removeHTMLTag(brief)
if (brief.length < this.proposalConfig.briefMinLength) {
this.$message.warning("提案内容和依据最少为" + this.proposalConfig.briefMinLength + "字")
return
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/proposal/write/submitAgain', {
info: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
commonUtil.pjaxPush('/platform/proposal/mine')
}
})
})
}
},
// 获取提案类别
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
// 获取配置
getProposalConfig() {
return this.$axios.post("/platform/proposal/common/config").then((res) => {
if (res.code === 0) {
this.proposalConfig = res.data
}
})
},
//教代会change
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.listDelegation()
this.searchMineDelegation()
// this.delegationOptions = await proposal.getDelegation(val)
// this.committeeOptions = await this.getInstitutions(val)
},
// 建议承办单位
listSuggestUnit() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
this.suggestUnitOptions = res.data
}
})
},
// 获取代表团
listDelegation() {
return this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
// 查询开启的教代会
listOpenSession(isModify = false) {
this.$axios.post("/platform/proposal/common/listOpenSession").then(async (res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (!isModify && this.sessionOptions) {
this.$set(this.formData, "sessionId", this.sessionOptions[0].id)
// 获取代表团
await this.searchMineDelegation()
// 检查是否在撰写时间内
this.checkWriteTime()
}
await this.listDelegation()
await this.listSource()
}
})
},
//查询自己有权限的撰写方式
listSource() {
return this.$axios.post("/platform/proposal/write/listSource", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) {
this.sourceOptions = res.data
}
})
},
//查询自己有权限的代表团
searchMineDelegation() {
return this.$axios.post("/platform/proposal/write/searchMineDelegation", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) {
this.$set(this.formData, "delegationId", res.data)
}
})
},
// 检查是否在撰写时间内
checkWriteTime() {
this.$axios.post("/platform/proposal/write/checkWriteTime", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) {
if (!res.data) {
this.$message.warning("当前时间不在撰写时间段内")
this.isWriteTime = false
} else {
this.isWriteTime = true
}
}
})
},
init() {
if (this.bizId) {
this.$axios.post("/platform/proposal/write/detail", {id: this.bizId}).then((res) => {
if (res.code === 0) {
this.formData = res.data
this.listOpenSession(true)
}
})
} else {
this.noticeDialogVisible = true
this.listOpenSession(false)
this.$set(this.formData, "createUserId", this.$store.state.user.id)
this.$set(this.formData, "createUserName", this.$store.state.user.username)
this.$set(this.formData, "createUserLoginName", this.$store.state.user.loginname)
this.$set(this.formData, "createTime", this.$moment().format("YYYY-MM-DD"))
this.$set(this.formData, "mobile", this.$store.state.user.mobile)
this.$set(this.formData, "unitName", this.$store.state.user.unit?.name)
}
}
},
created() {
this.init()
this.listSuggestUnit()
this.listProposalType()
this.getProposalConfig()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,170 @@
<div id="proposal-view">
<!-- <el-form ref="formRef" label-width="0" label-suffix="" class="flow-task-form">-->
<el-descriptions :column="2" border class="flow-task-form">
<el-descriptions-item label="提案名称" :span="2">{{ viewData.name }}</el-descriptions-item>
<el-descriptions-item label="提案编号">{{ viewData.code }}</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>
<el-descriptions-item label="提案人单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item :label="viewData.mannerCode!=='W03'?'代表团名称':'委员会名称'">
{{ viewData.mannerCode !== 'W03' ? viewData.delegationName : viewData.committeeName }}
</el-descriptions-item>
<el-descriptions-item label="提案类别">{{viewData.typeName}}</el-descriptions-item>
<el-descriptions-item label="立案结果" :span="2">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="viewData.caseFilingResult"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="提案摘要" :span="2">
<div class="text-left">{{viewData.excerpt}}</div>
</el-descriptions-item>
<el-descriptions-item label="提案内容" :span="2">
<div class="text-left" v-html="viewData.brief"></div>
</el-descriptions-item>
<el-descriptions-item label="改进建议和措施" :span="2">
<div class="text-left" v-html="viewData.measures"></div>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<file-preview :files="viewData.files" complete_result></file-preview>
</el-descriptions-item>
</el-descriptions>
<!-- <template v-for="task in doneTasks">-->
<!-- <div class="task-panel mt10">-->
<!-- <div class="task-panel-header">{{ task.displayName }}</div>-->
<!-- <el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-if="task.ext.isFirstTaskNode">-->
<!-- <el-descriptions-item label="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})</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>-->
<!-- <el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>-->
<!-- <el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</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="办理意见" v-if="!task.ext.isFirstTaskNode">{{ task.taskFormData.opinion }}</el-descriptions-item>-->
<!-- </el-descriptions>-->
<!-- </div>-->
<!-- </template>-->
<!-- 首先按 taskParentId 分组 -->
<template v-for="(group, parentId) in groupTasksByParentId(doneTasks)">
<div class="task-panel mt10" :key="parentId">
<!-- 显示主任务(parentId 为 0 或没有子任务的任务) -->
<template v-if="parentId === '0' || !group.children.length">
<div class="task-panel-header">{{ group.mainTask.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3">
<el-descriptions-item label="申请用户">
{{ group.mainTask.ext.initiatorName }}({{group.mainTask.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ group.mainTask.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="group.mainTask.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
</template>
<!-- 显示子任务 -->
<template v-for="(task, index) in group.children">
<div class="task-panel-header" :key="task.id" v-if="index === 0 || task.displayName !== group.children[index-1].displayName">
{{ task.displayName }}
</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id">
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</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="办理意见">{{ task.taskFormData.opinion }}</el-descriptions-item>
</el-descriptions>
</template>
</div>
</template>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#proposal-view",
store,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
viewData: {},
doneTasks: []
}
},
methods: {
info() {
this.$axios.post("/platform/proposal/view/info", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { instanceId: this.instanceId }).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
groupTasksByParentId(tasks) {
const groups = {}
// 首先找出所有主任务(taskParentId 为 0 的任务)
tasks.forEach((task) => {
const parentId = task.taskParentId || "0"
if (!groups[parentId]) {
groups[parentId] = {
mainTask: null,
children: []
}
}
if (parentId === "0") {
groups[parentId].mainTask = task
} else {
// 如果是子任务,尝试找到对应的主任务
if (!groups[parentId].mainTask) {
const mainTask = tasks.find((t) => t.id === task.taskParentId)
if (mainTask) {
groups[parentId].mainTask = mainTask
}
}
groups[parentId].children.push(task)
}
})
return groups
}
},
created() {
this.info()
this.getDoneTasks()
}
})
</script>
<style>
.task-panel {
background: white;
border-radius: 4px;
overflow: hidden;
}
.task-panel-header {
background: rgb(250, 250, 250);
border: 1px solid rgb(228, 231, 237);
border-bottom: none;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>