This commit is contained in:
=
2026-04-17 16:48:04 +08:00
parent a712e24168
commit 34ae7010d6
11 changed files with 764 additions and 111 deletions
@@ -343,6 +343,7 @@ public class ProposalMineController {
seconded.setUnionName(item.getString("unionName"));
seconded.setDelegationName(item.getString("delegationName"));
seconded.setMobile(item.getString("mobile"));
seconded.setMode(true);
seconded.setInviteTime(new Date());
return seconded;
}).toList();
@@ -1,6 +1,8 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
@@ -13,16 +15,20 @@ import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalSecondedService;
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
import java.util.List;
@@ -50,18 +56,18 @@ public class ProposalSecondedController {
@At("")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/seconded/index.html")
@SaCheckPermission("proposal.seconded")
@SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR)
public void index() {
}
@At("/h5")
@Ok("beetl:/platform/zhghh5/democratic/proposal/transact/seconded/index.html")
@SaCheckPermission("proposal.seconded")
@SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR)
public void h5Index() {
}
@At
@SaCheckPermission("proposal.seconded")
@SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR)
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
Sql sql = Sqls.create("""
SELECT
@@ -83,6 +89,7 @@ public class ProposalSecondedController {
t.finishTime,
t.taskParentId,
t.variable taskVariable,
ta.actorId taskActorUserId,
ta.actorName taskActorName,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
@@ -122,4 +129,16 @@ public class ProposalSecondedController {
return Result.success(pagination);
}
@At
@SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR)
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("修改提案附议信息")
@SLog(tag = "提案管理系统-附议提案", msg = "修改提案附议信息")
public Result updateInfo(@Param("proposalId") String proposalId,
@Param("taskActorUserId") String taskActorUserId,
@Param("opinion") String opinion,
@Param("submitType") Integer submitType) {
return proposalSecondedService.updateInviteSecondInfo(proposalId, taskActorUserId, opinion, submitType);
}
}
@@ -77,4 +77,15 @@ public class ProposalSecond extends BaseModel {
@ColDefine(type = ColType.BOOLEAN)
private Boolean isAgree;
@Column
@Comment("附议类型,true表示受邀附议,false表示主动附议")
@ColDefine(type = ColType.BOOLEAN)
@Default("1")
private Boolean mode;
@Column
@Comment("附议意见")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String opinion;
}
@@ -1,9 +1,29 @@
package com.budwk.app.zhgh.democratic.proposal.service;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalSecond;
public interface ProposalSecondedService extends BaseService<ProposalSecond> {
/**
* 保存受邀附议办理结果,并在“受邀附议 + 主动附议”总同意人数达到 2 人时自动推进到团长审核。
*
* @param proposalId 提案ID
* @param taskActorUserId 受邀附议办理人ID
* @param opinion 附议意见
* @param submitType 提交类型
* @return 处理结果
*/
Result updateInviteSecondInfo(String proposalId, String taskActorUserId, String opinion, Integer submitType);
/**
* 保存主动附议结果,并在“受邀附议 + 主动附议”总同意人数达到 2 人时自动推进到团长审核。
*
* @param proposalId 提案ID
* @param opinion 附议意见
* @param submitType 提交类型
* @return 处理结果
*/
Result handlePositiveSecond(String proposalId, String opinion, Integer submitType);
}
@@ -1,21 +1,163 @@
package com.budwk.app.zhgh.democratic.proposal.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.controllers.open.commons.service.CommonService;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalSecond;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalSecondedService;
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Dao;
import org.nutz.dao.Cnd;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.Date;
import java.util.List;
@IocBean(args = {"refer:dao"})
public class ProposalSecondedServiceImpl extends BaseServiceImpl<ProposalSecond> implements ProposalSecondedService {
@Inject
private CommonService commonService;
private FlowEngine flowEngine;
public ProposalSecondedServiceImpl(Dao dao) {
super(dao);
}
@Override
@Aop(TransAop.READ_COMMITTED)
public Result updateInviteSecondInfo(String proposalId, String taskActorUserId, String opinion, Integer submitType) {
ProposalSecond proposalSecond = dao().fetch(
ProposalSecond.class,
Cnd.where(ProposalSecond::getProposalId, "=", proposalId)
.and(ProposalSecond::getSeconderId, "=", taskActorUserId)
);
if (proposalSecond == null) {
return Result.error("未查询到附议记录");
}
proposalSecond.setIsAgree(ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode()));
proposalSecond.setOpinion(opinion);
proposalSecond.setSecondedTime(DateUtil.date());
dao().update(proposalSecond);
if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode())) {
autoAdvanceToDelegationWhenEnoughSeconders(proposalId);
}
return Result.success();
}
@Override
@Aop(TransAop.READ_COMMITTED)
public Result handlePositiveSecond(String proposalId, String opinion, Integer submitType) {
ProposalInfo proposalInfo = dao().fetch(ProposalInfo.class, proposalId);
if (proposalInfo == null) {
return Result.error("提案不存在");
}
ProposalSecond existsSecond = dao().fetch(
ProposalSecond.class,
Cnd.where(ProposalSecond::getProposalId, "=", proposalId)
.and(ProposalSecond::getSeconderId, "=", SecurityUtil.getUserId())
);
if (existsSecond != null) {
if (Boolean.TRUE.equals(existsSecond.getMode()) && existsSecond.getIsAgree() == null) {
return Result.error("您已在受邀附议名单中,请在受邀附议中处理");
}
return Result.error("您已附议过该提案");
}
View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", SecurityUtil.getUserId()));
if (user == null) {
return Result.error("未查询到当前用户信息");
}
Teacher_congress_delegate delegate = dao().fetch(
Teacher_congress_delegate.class,
Cnd.where("sessionId", "=", proposalInfo.getSessionId()).and("userId", "=", user.getId())
);
if (delegate == null) {
return Result.error("未查询到您的代表信息");
}
Teacher_congress_delegation delegation = dao().fetch(Teacher_congress_delegation.class, delegate.getDelegationId());
if (delegation == null) {
return Result.error("未查询到您所在的代表团信息");
}
ProposalSecond seconded = new ProposalSecond();
seconded.setProposalId(proposalId);
seconded.setSeconderId(user.getId());
seconded.setUserName(user.getUsername());
seconded.setLoginName(user.getLoginname());
seconded.setUnitName(user.getUnitName());
seconded.setUnionName(user.getUnionName());
seconded.setDelegationName(delegation.getName());
seconded.setMobile(user.getMobile());
seconded.setMode(false);
seconded.setInviteTime(new Date());
seconded.setOpinion(opinion);
seconded.setSecondedTime(new Date());
seconded.setIsAgree(ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode()));
dao().insert(seconded);
if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode())) {
autoAdvanceToDelegationWhenEnoughSeconders(proposalId);
}
return Result.success();
}
/**
* 统一按 proposal_second 里的“同意附议”人数判断是否已满足 2 人附议。
* 一旦满足 2 人,就用系统自动执行一个仍处于办理中的 second 任务来触发流程引擎会签合并,
* 这样 second 节点会自动废弃其余未办任务,并按流程定义流转到 delegation 节点。
*/
private void autoAdvanceToDelegationWhenEnoughSeconders(String proposalId) {
ProcessInstance processInstance = dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", proposalId));
if (processInstance == null) {
return;
}
long agreeCount = dao().count(
ProposalSecond.class,
Cnd.where(ProposalSecond::getProposalId, "=", proposalId)
.and(ProposalSecond::getIsAgree, "=", true)
);
if (agreeCount < 2) {
return;
}
int mergedCompletedCount = (int) Math.max(agreeCount - 1, 0);
List<ProcessTask> doingSecondTasks = flowEngine.processTaskService().getDoingTaskList(processInstance.getId(), new String[]{"second"});
if (doingSecondTasks.isEmpty()) {
return;
}
// 当前流程仍停留在 second 会签节点时,把“已同意附议人数”桥接到会签变量里。
// 这样系统自动完成一个 second 任务后,会签节点会按“累计 2 个同意”直接合并到团长审核。
String prefix = FlowConst.COUNTERSIGN_VARIABLE_PREFIX + "second_";
Dict instanceVariable = Dict.create();
instanceVariable.put(prefix + FlowConst.NR_OF_COMPLETED_INSTANCES, mergedCompletedCount);
instanceVariable.put(prefix + FlowConst.NR_OF_COMPLETED_AGREE_INSTANCES, mergedCompletedCount);
flowEngine.processInstanceService().addVariable(processInstance.getId(), instanceVariable);
Dict executeArgs = Dict.create();
executeArgs.put(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.AGREE.getCode());
executeArgs.put(FlowConst.TASK_FORM_DATA_PREFIX + "opinion", "满足两人附议,系统自动流转至团长审核");
executeArgs.put(prefix + FlowConst.NR_OF_COMPLETED_INSTANCES, mergedCompletedCount);
executeArgs.put(prefix + FlowConst.NR_OF_COMPLETED_AGREE_INSTANCES, mergedCompletedCount);
flowEngine.executeProcessTask(doingSecondTasks.get(0).getId(), FlowConst.AUTO_ID, executeArgs);
}
}
@@ -137,8 +137,34 @@ const PROPOSAL_INFO = {
<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="附议模式" prop="mode">
<template slot-scope="{ row }">
<el-tag size="mini" type="primary">邀请附议</el-tag>
</template>
</el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="主动附议" :span="3" v-if="task.taskName === 'invite'">
<el-table v-if="positiveSecondList.length > 0" :data="positiveSecondList">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="附议时间" prop="secondedTime"></el-table-column>
<el-table-column label="附议结果" prop="isAgree">
<template slot-scope="{ row }">
<el-tag v-if="row.isAgree === true" size="mini" type="success">同意</el-tag>
<el-tag v-else size="mini" type="danger">不同意</el-tag>
</template>
</el-table-column>
<el-table-column label="意见" prop="opinion" show-overflow-tooltip></el-table-column>
<el-table-column label="附议模式" prop="mode">
<template slot-scope="{ row }">
<el-tag size="mini" type="primary">主动附议</el-tag>
</template>
</el-table-column>
</el-table>
<span v-else>暂无主动附议信息</span>
</el-descriptions-item>
</el-descriptions>
<!--提案委员会立案-->
@@ -208,7 +234,8 @@ const PROPOSAL_INFO = {
viewData: {},
doneTasks: [],
row: null,
viewDialogVisible: false
viewDialogVisible: false,
positiveSecondList: [],
}
},
methods: {
@@ -218,6 +245,7 @@ const PROPOSAL_INFO = {
this.visible = true
this.getInfo()
this.getDoneTasks()
this.listPositiveSeconded()
},
// 获取申请信息
@@ -246,6 +274,15 @@ const PROPOSAL_INFO = {
})
},
// 获取主动附议信息
listPositiveSeconded() {
this.$axios.post("/platform/proposal/positiveSeconded/listPositiveSeconded", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.positiveSecondList = res.data
}
})
},
},
style:
/*language=CSS*/
@@ -2,25 +2,50 @@
layout("/layouts/platform.html"){
#-->
<div id="app">
<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="所属教代会"
<el-select @change="meetingChange" clearable filterable :placeholder="searchPlaceholder.session"
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
<el-input v-model="pageForm.name" :placeholder="searchPlaceholder.name" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<!-- <search-item label="姓名/工号" v-if="activeTab === 'positiveSeconded'">-->
<!-- <el-input clearable placeholder="请输入姓名或工号" v-model="pageForm.createUserKeyword"-->
<!-- @keyup.enter.native="doSearch"></el-input>-->
<!-- </search-item>-->
<search-item label="代表团" v-if="activeTab === 'positiveSeconded'">
<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>
</el-card>
<el-card shadow="never">
<el-tabs v-model="activeTab" type="card" @tab-click="tabChange">
<el-tab-pane name="inviteSeconded">
<span slot="label">
<i class="el-icon-message"></i>
受邀附议
</span>
</el-tab-pane>
<el-tab-pane name="positiveSeconded">
<span slot="label">
<i class="el-icon-edit-outline"></i>
主动附议
</span>
</el-tab-pane>
</el-tabs>
<table-tool :columns.sync="tableColumns">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已附议</el-radio-button>
@@ -54,10 +79,7 @@ layout("/layouts/platform.html"){
<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>-->
<el-button v-if="showAuditButton(row)" @click="openAudit(row)" size="mini" type="primary">附议</el-button>
</template>
</el-table-column>
</el-table>
@@ -68,7 +90,7 @@ layout("/layouts/platform.html"){
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
{{approvalTitle}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=":"
class="flow-task-form">
@@ -98,69 +120,236 @@ layout("/layouts/platform.html"){
components: {
"proposal-info": PROPOSAL_INFO
},
data() {
data: function () {
return {
tableColumns: [
activeTab: "inviteSeconded",
inviteColumns: [
{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"}
],
positiveColumns: [
{label: "提案编号", prop: "code"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
{label: "代表团", prop: "delegationName"},
{label: "当前节点", prop: "taskName"},
{label: "流程状态", prop: "instanceState"}
],
tableColumns: [],
pageForm: {
approval: false
approval: false,
name: "",
sessionId: null,
createUserKeyword: "",
delegationId: null,
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: ""
},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
row: {},
}
},
computed: {
approvalTitle: function () {
if (this.activeTab === "inviteSeconded") {
return this.formData.taskName
}
return "主动附议"
},
searchPlaceholder: function () {
if (this.activeTab === "inviteSeconded") {
return {
session: "所属教代会",
name: "提案名称"
}
}
return {
session: "请选择所属教代会",
name: "请输入提案名称"
}
}
},
methods: {
openView(row) {
syncTableColumns: function () {
if (this.activeTab === "inviteSeconded") {
this.$set(this, "tableColumns", this.inviteColumns)
} else {
this.$set(this, "tableColumns", this.positiveColumns)
}
},
currentPageDataUrl: function () {
if (this.activeTab === "inviteSeconded") {
return "/platform/proposal/seconded/pageData"
}
return "/platform/proposal/positiveSeconded/pageData"
},
tabChange: function () {
this.syncTableColumns()
this.$set(this, "tableData", [])
if (this.activeTab !== "positiveSeconded") {
this.$set(this.pageForm, "createUserKeyword", "")
this.$set(this.pageForm, "delegationId", null)
}
this.doSearch()
},
doSearch: function () {
this.tableKey = new Date().getTime()
this.$set(this.pageForm, "pageNumber", 1)
this.pageData()
},
pageOrder: function (column) {
this.$set(this.pageForm, "pageOrderName", column.prop)
this.$set(this.pageForm, "pageOrderBy", column.order)
this.pageData()
},
pageNumberChange: function (val) {
this.$set(this.pageForm, "pageNumber", val)
this.pageData()
},
pageSizeChange: function (val) {
this.$set(this.pageForm, "pageSize", val)
this.pageData()
},
pageData: function () {
this.tableLoading = true
this.$axios.post(this.currentPageDataUrl(), this.pageForm).then((res) => {
this.tableLoading = false
if (res.code === 0) {
this.$set(this, "tableData", res.data.list)
this.$set(this.pageForm, "totalCount", res.data.totalCount)
}
})
},
showAuditButton: function (row) {
if (this.activeTab === "inviteSeconded") {
return row.taskState === 10
}
return row.count === 0
},
openView: function (row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
})
},
openAudit(row) {
openAudit: async function (row) {
if (this.activeTab === "positiveSeconded") {
var validatePass = await this.validateCanSeconded(row.id)
if (!validatePass) {
return
}
}
this.$set(this, "row", row)
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_opinion: "同意该提案"
this.$set(this, "showApprovalForm", true)
if (this.activeTab === "inviteSeconded") {
this.$set(this, "formData", {
processTaskId: row.taskId,
sessionId: row.sessionId,
delegationId: row.delegationId,
taskName: row.curTaskName,
tf_opinion: "同意该提案"
})
} else {
this.$set(this, "formData", {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_opinion: "同意该提案"
})
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$refs.formRef.validate(valid => {
handleTaskAction: function (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()
}
})
if (this.activeTab === "inviteSeconded") {
this.handleInviteSeconded(val)
} else {
this.handlePositiveSeconded(val)
}
})
})
},
handleInviteSeconded: function (val) {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.updateSecond(val)
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
},
updateSecond: function (submitType) {
this.$axios.post("/platform/proposal/seconded/updateInfo", {
proposalId: this.row.id,
taskActorUserId: this.row.taskActorUserId,
opinion: this.formData.tf_opinion,
submitType: submitType,
})
},
handlePositiveSeconded: function (val) {
this.$axios.post("/platform/proposal/positiveSeconded/handle", {
proposalId: this.row.id,
opinion: this.formData.tf_opinion,
submitType: val
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
},
validateCanSeconded: function (proposalId) {
return this.$axios.post("/platform/proposal/positiveSeconded/validateCanSeconded", {
proposalId: proposalId
}).then((res) => {
if (res.code !== 0) {
this.$message.error(res.msg)
return false
}
return true
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
@@ -176,14 +365,16 @@ layout("/layouts/platform.html"){
})
},
// 教代会
async meetingChange(val) {
meetingChange: function () {
this.formData.delegationId = null
this.formData.committeeId = null
if (this.activeTab === "positiveSeconded") {
this.$set(this.pageForm, "delegationId", null)
this.listDelegation()
}
this.doSearch()
},
// 查询开启的教代会
listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) {
@@ -195,10 +386,18 @@ layout("/layouts/platform.html"){
}
}
})
}
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
}
},
created() {
this.syncTableColumns()
this.pageData()
this.listOpenSession()
}
@@ -335,10 +335,11 @@ layout("/layouts/platform.html"){
//教代会change
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.listDelegation()
this.searchMineDelegation()
this.$set(this.formData, "sessionId", val)
this.$set(this.formData, "source", "")
this.$set(this.formData, "delegationId", null)
this.$set(this.formData, "committeeId", null)
await this.loadSessionRelatedData()
// this.delegationOptions = await proposal.getDelegation(val)
// this.committeeOptions = await this.getInstitutions(val)
},
@@ -367,24 +368,44 @@ layout("/layouts/platform.html"){
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()
if (!isModify && this.sessionOptions && this.sessionOptions.length > 0) {
// 默认定位到当前用户在本届次下可用的提案会期,避免提案方式下拉为空。
let targetSession = this.sessionOptions[0]
for (let i = 0; i < this.sessionOptions.length; i++) {
const session = this.sessionOptions[i]
this.$set(this.formData, "sessionId", session.id)
const hasSource = await this.loadSessionRelatedData()
if (hasSource) {
targetSession = session
break
}
}
this.$set(this.formData, "sessionId", targetSession.id)
}
await this.listDelegation()
await this.listSource()
await this.loadSessionRelatedData()
}
})
},
// 会期相关数据需要同步刷新,保证提案方式、代表团和撰写时间判断一致。
async loadSessionRelatedData() {
await this.listDelegation()
await this.searchMineDelegation()
await this.listSource()
this.checkWriteTime()
return this.sourceOptions && this.sourceOptions.length > 0
},
//查询自己有权限的撰写方式
listSource() {
return this.$axios.post("/platform/proposal/write/listSource", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) {
this.sourceOptions = res.data
const sourceExists = this.sourceOptions.some(item => item.code === this.formData.source)
if (!sourceExists) {
const defaultSource = this.sourceOptions.length > 0 ? this.sourceOptions[0].code : ""
this.$set(this.formData, "source", defaultSource)
}
}
})
},
@@ -108,17 +108,38 @@ const PROPOSAL_INFO = {
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
<van-cell title="附议人" v-if="task.taskName === 'invite'"
class="direction-column-cell">
<el-table :data="task?.taskFormData?.seconder">
<el-table :data="task?.taskFormData?.seconder" size="mini" border>
<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="unitName" show-overflow-tooltip></el-table-column>
<el-table-column label="分工会" prop="unionName"
show-overflow-tooltip></el-table-column>
<el-table-column label="代表团" prop="delegationName"
show-overflow-tooltip></el-table-column>
<el-table-column label="附议模式" prop="mode">
<template slot-scope="{ row }">
<el-tag size="mini" type="primary">邀请附议</el-tag>
</template>
</el-table-column>
</el-table>
</van-cell>
<van-cell title="主动附议" v-if="task.taskName === 'invite'"
class="direction-column-cell">
<el-table v-if="positiveSecondList.length > 0" :data="positiveSecondList" size="mini" border>
<el-table-column label="姓名" prop="userName" show-overflow-tooltip></el-table-column>
<el-table-column label="附议时间" prop="secondedTime" show-overflow-tooltip></el-table-column>
<el-table-column label="附议结果" prop="isAgree">
<template slot-scope="{ row }">
<el-tag v-if="row.isAgree === true" size="mini" type="success">同意</el-tag>
<el-tag v-else size="mini" type="danger">不同意</el-tag>
</template>
</el-table-column>
<el-table-column label="意见" prop="opinion" show-overflow-tooltip></el-table-column>
<el-table-column label="附议模式" prop="mode">
<template slot-scope="{ row }">
<el-tag size="mini" type="primary">主动附议</el-tag>
</template>
</el-table-column>
</el-table>
<span v-else>暂无主动附议信息</span>
</van-cell>
</van-cell-group>
<!--提案委员会立案-->
@@ -179,6 +200,7 @@ const PROPOSAL_INFO = {
doneTasks: [],
row: null,
originalRow: null, // 用于保存原始数据,支持返回功能
positiveSecondList: [],
}
},
methods: {
@@ -188,6 +210,7 @@ const PROPOSAL_INFO = {
this.visible = true
this.getInfo()
this.getDoneTasks()
this.listPositiveSeconded()
},
// 关闭
@@ -236,5 +259,14 @@ const PROPOSAL_INFO = {
}
})
},
// 获取主动附议信息
listPositiveSeconded() {
this.$axios.post("/platform/proposal/positiveSeconded/listPositiveSeconded", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.positiveSecondList = res.data
}
})
},
}
};
@@ -14,16 +14,27 @@ layout("/layouts/platform_h5.html"){
></van-search>
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
<van-dropdown-item v-model="pageForm.sessionId" :options="sessionOptions" :multiple="false"
@change="doSearch"></van-dropdown-item>
@change="sessionChange"></van-dropdown-item>
<van-dropdown-item
v-if="activeTab === 'positiveSeconded'"
v-model="pageForm.delegationId"
:options="delegationOptions"
@change="doSearch"
></van-dropdown-item>
</van-dropdown-menu>
<van-tabs v-model="pageForm.approvalText"
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
<van-tabs v-model="activeTab" @change="tabChange">
<van-tab title="受邀附议" name="inviteSeconded"></van-tab>
<van-tab title="主动附议" name="positiveSeconded"></van-tab>
</van-tabs>
<van-tabs v-model="pageForm.approvalText" @change="approvalTabChange">
<van-tab title="已附议" name="1"></van-tab>
<van-tab title="未附议" name="0"></van-tab>
</van-tabs>
</van-sticky>
<table-list api="/platform/proposal/seconded/pageData" :page_form.sync="pageForm" @ready="onReady"
<table-list :api="currentApi" :page_form.sync="pageForm" @ready="onReady"
ref="tableListRef"
title="name">
<template v-slot="{index,row}">
@@ -31,21 +42,17 @@ layout("/layouts/platform_h5.html"){
<table-column label="提案类别">{{row.typeName}}</table-column>
<table-column label="提案人">{{row.createUserName}}</table-column>
<table-column label="代表团">{{row.delegationName}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column>
<table-column label="当前节点">{{ currentTaskName(row) }}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="onView(row)">
<i class="fa fa-eye"></i>
<span>查看</span>
</div>
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
<div class="action-btn" v-if="showApprovalButton(row)" @click="onApproval(row)">
<i class="fa fa-edit"></i>
<span>附议</span>
</div>
<!-- <div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">-->
<!-- <i class="fa fa-reply"></i>-->
<!-- <span>撤回</span>-->
<!-- </div>-->
</template>
</table-list>
@@ -83,6 +90,7 @@ layout("/layouts/platform_h5.html"){
store,
data() {
return {
activeTab: "inviteSeconded",
pageForm: {
pageNumber: 1,
pageSize: 10,
@@ -90,75 +98,175 @@ layout("/layouts/platform_h5.html"){
name: null,
sessionId: null,
approvalText: "0",
approval: false
approval: false,
delegationId: null
},
sessionOptions: [],
delegationOptions: [
{
text: "全部代表团",
value: null
}
],
formData: {},
showApprovalForm: false,
rules: {
approvalSignature: [{required: true, message: "请签字"}]
}
},
row: {},
}
},
components: {
"proposal-info": PROPOSAL_INFO
},
computed: {
currentApi() {
if (this.activeTab === "inviteSeconded") {
return "/platform/proposal/seconded/pageData"
}
return "/platform/proposal/positiveSeconded/pageData"
}
},
methods: {
onReady() {
this.listSession()
},
tabChange(val) {
this.activeTab = val
if (this.activeTab !== "positiveSeconded") {
this.$set(this.pageForm, "delegationId", null)
}
if (this.activeTab === "positiveSeconded" && this.pageForm.sessionId) {
this.listDelegation()
}
this.doSearch()
},
approvalTabChange(val) {
this.$set(this.pageForm, "approvalText", val)
this.$set(this.pageForm, "approval", val === "1")
this.doSearch()
},
sessionChange() {
this.$set(this.pageForm, "delegationId", null)
if (this.activeTab === "positiveSeconded" && this.pageForm.sessionId) {
this.listDelegation()
} else {
this.$set(this, "delegationOptions", [
{
text: "全部代表团",
value: null
}
])
}
this.doSearch()
},
listDelegation() {
if (!this.pageForm.sessionId) {
this.$set(this, "delegationOptions", [
{
text: "全部代表团",
value: null
}
])
return
}
this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) {
this.$set(this, "delegationOptions", [
{
text: "全部代表团",
value: null
}
].concat(res.data.map((v) => ({text: v.name, value: v.id}))))
}
})
},
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = [
this.$set(this, "sessionOptions", [
{
text: "全部届次",
value: null
}
].concat(res.data.map((v) => ({text: v.fullName, value: v.id})))
].concat(res.data.map((v) => ({text: v.fullName, value: v.id}))))
if (this.sessionOptions.length > 0) {
this.pageForm.sessionId = this.sessionOptions[0].value
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].value)
this.doSearch()
}
}
})
},
currentTaskName(row) {
if (this.activeTab === "inviteSeconded") {
return row.curTaskName
}
return row.taskName
},
showApprovalButton(row) {
if (this.activeTab === "inviteSeconded") {
return row.taskState === 10
}
return row.count === 0
},
onView(row) {
this.showApprovalForm = false
this.$set(this, "showApprovalForm", false)
this.$refs.proposalInfoRef.onOpen(row)
},
onApproval(row) {
this.showApprovalForm = true
this.$refs.proposalInfoRef.onOpen(row)
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_opinion: "同意该提案"
async onApproval(row) {
if (this.activeTab === "positiveSeconded") {
const validatePass = await this.validateCanSeconded(row.id)
if (!validatePass) {
return
}
}
this.$set(this, "row", row)
this.$set(this, "showApprovalForm", true)
this.$refs.proposalInfoRef.onOpen(row)
if (this.activeTab === "inviteSeconded") {
this.$set(this, "formData", {
processTaskId: row.taskId,
sessionId: row.sessionId,
delegationId: row.delegationId,
taskName: row.curTaskName,
tf_opinion: "同意该提案"
})
} else {
this.$set(this, "formData", {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_opinion: "同意该提案"
})
}
},
validateCanSeconded(proposalId) {
return this.$axios.post("/platform/proposal/positiveSeconded/validateCanSeconded", {
proposalId: proposalId
}).then((res) => {
if (res.code !== 0) {
this.$toast(res.msg)
return false
}
return true
})
},
async handleTaskAction(val) {
try {
await this.$refs.formRef.validate();
await this.$refs.formRef.validate()
this.$dialog.confirm({
title: "提示",
message: "您确定要提交吗?"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.proposalInfoRef.onClose()
this.$toast.success(res.msg)
this.doSearch()
}
})
if (this.activeTab === "inviteSeconded") {
this.handleInviteSeconded(val)
} else {
this.handlePositiveSeconded(val)
}
}).catch(() => {
})
@@ -167,6 +275,45 @@ layout("/layouts/platform_h5.html"){
}
},
handleInviteSeconded(val) {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.proposalInfoRef.onClose()
this.$toast.success(res.msg)
this.doSearch()
this.updateSecond(val)
}
})
},
handlePositiveSeconded(val) {
this.$axios.post("/platform/proposal/positiveSeconded/handle", {
proposalId: this.row.id,
opinion: this.formData.tf_opinion,
submitType: val
}).then((res) => {
if (res.code === 0) {
this.$refs.proposalInfoRef.onClose()
this.$toast.success(res.msg)
this.doSearch()
}
})
},
updateSecond(submitType) {
this.$axios.post("/platform/proposal/seconded/updateInfo", {
proposalId: this.row.id,
taskActorUserId: this.row.taskActorUserId,
opinion: this.formData.tf_opinion,
submitType: submitType,
})
},
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
@@ -609,15 +609,14 @@ layout("/layouts/platform_h5.html"){
//教代会change
async meetingChange(val) {
this.$set(this.formData, "sessionId", val);
this.$set(this.formData, "source", "");
this.$set(this.formData, "sourceName", "");
this.formData.delegationId = null;
this.formData.committeeId = null;
this.formData.delegationName = '';
this.formData.committeeName = '';
await this.listDelegation();
await this.searchMineDelegation();
await this.listSource();
// 检查是否在撰写时间内
this.checkWriteTime();
await this.loadSessionRelatedData();
},
// 获取代表团
@@ -644,28 +643,53 @@ layout("/layouts/platform_h5.html"){
if (res.code === 0) {
this.sessionOptions = res.data;
if (!isModify && this.sessionOptions && this.sessionOptions.length > 0) {
this.$set(this.formData, "sessionId", this.sessionOptions[0].id);
this.$set(this.formData, "sessionName", this.sessionOptions[0].fullName);
await this.listDelegation();
await this.listSource();
// 获取代表团
await this.searchMineDelegation();
// 检查是否在撰写时间内
this.checkWriteTime();
// 默认定位到当前用户在本届次下可用的提案会期,避免提案方式下拉为空。
let targetSession = this.sessionOptions[0];
for (let i = 0; i < this.sessionOptions.length; i++) {
const session = this.sessionOptions[i];
this.$set(this.formData, "sessionId", session.id);
this.$set(this.formData, "sessionName", session.fullName);
const hasSource = await this.loadSessionRelatedData();
if (hasSource) {
targetSession = session;
break;
}
}
this.$set(this.formData, "sessionId", targetSession.id);
this.$set(this.formData, "sessionName", targetSession.fullName);
} else {
await this.listDelegation();
await this.listSource();
await this.loadSessionRelatedData();
this.echoPicker()
}
await this.loadSessionRelatedData();
}
});
},
// 会期相关数据需要同步刷新,保证提案方式、代表团和撰写时间判断一致。
async loadSessionRelatedData() {
await this.listDelegation();
await this.searchMineDelegation();
await this.listSource();
this.checkWriteTime();
return this.sourceOptions && this.sourceOptions.length > 0;
},
//查询自己有权限的撰写方式
listSource() {
return this.$axios.post("/platform/proposal/write/listSource", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) {
this.sourceOptions = res.data;
const source = this.sourceOptions.find(item => item.code === this.formData.source);
if (source) {
this.$set(this.formData, "sourceName", source.name);
} else if (this.sourceOptions.length > 0) {
this.$set(this.formData, "source", this.sourceOptions[0].code);
this.$set(this.formData, "sourceName", this.sourceOptions[0].name);
} else {
this.$set(this.formData, "source", "");
this.$set(this.formData, "sourceName", "");
}
}
});
},