commit
This commit is contained in:
+68
@@ -1,11 +1,16 @@
|
||||
package io.v.nutz.zhgh.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import io.v.nutz.base.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.base.query.PageForm;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.models.Sys_user_role;
|
||||
import io.v.nutz.sys.services.SysLocalProcessService;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||
import io.v.nutz.web.commons.slog.annotation.SLog;
|
||||
import io.v.nutz.zhgh.proposal.constants.ProposalState;
|
||||
@@ -22,9 +27,12 @@ import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Chain;
|
||||
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.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
@@ -33,6 +41,8 @@ import org.nutz.mvc.annotation.Param;
|
||||
import org.nutz.trans.Trans;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
@@ -271,4 +281,62 @@ public class ProposalBranchLeaderSuffixAuditController {
|
||||
return null;
|
||||
}
|
||||
|
||||
@At
|
||||
@ViReturn
|
||||
@RequiresPermissions("proposal.transact.branchLeaderSuffixAudit")
|
||||
public Result sendNotify(@Param("sessionId") String sessionId, @Param("proposalId") String proposalId,
|
||||
@Param("title") String title, @Param("content") String content) {
|
||||
if (StrUtil.isBlank(sessionId)) {
|
||||
return Result.error("教代会届次信息为空");
|
||||
}
|
||||
try {
|
||||
// 找待校领导审核的提案
|
||||
List<ProposalInfo> list = dao.query(
|
||||
ProposalInfo.class,
|
||||
Cnd.where("teacherMeetingId", "=", sessionId)
|
||||
.andEX("id", "=", proposalId)
|
||||
.and("stateCode", "=", ProposalState.LEADER_SUFFIX_AUDIT)
|
||||
);
|
||||
// 再找承办单位id
|
||||
List<ProposalBranchLeaderSuffixAudit> auditList = dao.query(
|
||||
ProposalBranchLeaderSuffixAudit.class,
|
||||
Cnd.where("proposalId", "in", list.stream().map(ProposalInfo::getId).toList())
|
||||
.and("isAudit", "=", 0)
|
||||
);
|
||||
if(Lang.isEmpty(auditList)) {
|
||||
return Result.success();
|
||||
}
|
||||
List<String> undertakes = auditList.stream().map(ProposalBranchLeaderSuffixAudit::getUnderTakeId).distinct().toList();
|
||||
|
||||
// 根据承办单位id找承办单位
|
||||
List<ProposalUndertake> undertakeList = dao.query(ProposalUndertake.class, Cnd.where("id", "in", undertakes));
|
||||
|
||||
// 根据承办单位id找校领导
|
||||
List<Sys_user_role> userRoles = dao.query(Sys_user_role.class, Cnd.where("roleid", "=", Roles.XLD).and("cbdwid", "in", undertakes));
|
||||
Map<String, List<Sys_user_role>> userRoleMap = userRoles.stream().collect(Collectors.groupingBy(Sys_user_role::getCbdwid));
|
||||
|
||||
// 找人
|
||||
List<Sys_user> userList = dao.query(Sys_user.class, Cnd.where("id", "in", userRoles.stream().map(Sys_user_role::getUserId).toList()));
|
||||
Map<String, Sys_user> userMap = userList.stream().collect(Collectors.toMap(Sys_user::getId, o -> o));
|
||||
|
||||
String linkUrl = Globals.AppDomain + "/platform/proposal/transact/branchLeaderSuffixAudit";
|
||||
for (ProposalUndertake undertake : undertakeList) {
|
||||
// 可能有多个
|
||||
List<Sys_user_role> userRoleList = userRoleMap.get(undertake.getId());
|
||||
for (Sys_user_role userRole : userRoleList) {
|
||||
Sys_user user = userMap.get(userRole.getUserId());
|
||||
String loginname = user.getLoginname();
|
||||
if(content.contains("****") && StrUtil.isBlank(proposalId)) {
|
||||
content = content.replace("****", undertake.getUnitName());
|
||||
}
|
||||
msgApi.sendMsg(List.of("DingTalk"), loginname, 2, title, content, "", linkUrl);
|
||||
}
|
||||
}
|
||||
return Result.success();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+43
@@ -2,6 +2,8 @@ package io.v.nutz.zhgh.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import com.deepoove.poi.XWPFTemplate;
|
||||
import com.deepoove.poi.config.Configure;
|
||||
@@ -13,6 +15,7 @@ import io.v.nutz.base.utils.Html2Text;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.base.dao.CndPlus;
|
||||
import io.v.nutz.base.query.PageForm;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.sys.services.SysLocalProcessService;
|
||||
import io.v.nutz.web.commons.slog.annotation.SLog;
|
||||
import io.v.nutz.zhgh.proposal.constants.ProposalConstant;
|
||||
@@ -410,5 +413,45 @@ public class ProposalFeedbackScoreController {
|
||||
return null;
|
||||
}
|
||||
|
||||
@At
|
||||
@ViReturn
|
||||
@RequiresPermissions("proposal.transact.feedback")
|
||||
public Result sendNotify(@Param("sessionId") String sessionId, @Param("proposalId") String proposalId,
|
||||
@Param("title") String title, @Param("content") String content) {
|
||||
if(StrUtil.isBlank(sessionId)) {
|
||||
return Result.error("教代会届次信息为空");
|
||||
}
|
||||
try {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
info.proposalCode,
|
||||
info.proposalName,
|
||||
u.username,
|
||||
u.loginname
|
||||
FROM
|
||||
proposal_info info
|
||||
left join sys_user u on u.id = info.createUser
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("info.teacherMeetingId", "=", sessionId);
|
||||
cnd.and("info.stateCode", "=", ProposalState.FEEDBACKSCORE);
|
||||
cnd.andEX("info.id", "=", proposalId);
|
||||
cnd.asc("info.proposalCode");
|
||||
sql.setCondition(cnd);
|
||||
List<NutMap> list = proposalFeedbackService.listMap(sql);
|
||||
|
||||
String linkUrl = Globals.AppDomain + "/platform/proposal/transact/feedback";
|
||||
for (NutMap user : list) {
|
||||
String loginname = user.getString("loginname");
|
||||
System.out.println(JSONUtil.toJsonStr(user));
|
||||
msgApi.sendMsg(List.of("DingTalk"), loginname, 2, title, content, "", linkUrl);
|
||||
}
|
||||
return Result.success();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -3,6 +3,9 @@ package io.v.nutz.zhgh.proposal.services.impl;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import io.v.nutz.base.query.PageForm;
|
||||
import io.v.nutz.base.service.impl.ViServiceImpl;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.sys.models.Sys_user_role;
|
||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||
import io.v.nutz.zhgh.proposal.constants.ProposalState;
|
||||
import io.v.nutz.zhgh.proposal.models.ProposalReply;
|
||||
import io.v.nutz.zhgh.proposal.models.ProposalSearch;
|
||||
@@ -83,6 +86,13 @@ public class ProposalBranchLeaderSuffixAuditServiceImpl extends ViServiceImpl<Pr
|
||||
LEFT JOIN proposal_reply pr ON pr.replyUnitId=pbla.underTakeId AND pbla.proposalId=pr.proposalId
|
||||
$condition
|
||||
""");
|
||||
|
||||
if(!ShiroUtil.hasAnyRoles("sysadmin, A06, tamange, jdh10")) {
|
||||
List<Sys_user_role> userRoles = dao().query(Sys_user_role.class, Cnd.where("roleid", "=", Roles.XLD).and("userId", "=", ShiroUtil.getUserId()));
|
||||
List<String> list = userRoles.stream().map(Sys_user_role::getCbdwid).distinct().toList();
|
||||
cnd.and("pbla.underTakeId", "in", list);
|
||||
}
|
||||
|
||||
cnd.and("pr.undertakeType", "=", 1);
|
||||
cnd.desc("pbla.isMaster");
|
||||
cnd.groupBy("pbla.proposalId");
|
||||
|
||||
@@ -6,10 +6,13 @@ layout("/layouts/platform.html"){
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pro_table {
|
||||
padding-left: 65px;
|
||||
}
|
||||
.tooltip-alert,.el-alert{
|
||||
padding: 0;
|
||||
margin-top: 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
@@ -20,6 +23,10 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="分管领导审批办理" :app="this">
|
||||
<template #func>
|
||||
<el-button v-if="$auth.hasRole('sysadmin')" type="primary"
|
||||
@click="openSendMsg(null, 'oneKey')" size="small">
|
||||
一键提醒
|
||||
</el-button>
|
||||
</template>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" align="center" header-align="center" row-key="replyId"
|
||||
@@ -63,6 +70,10 @@ layout("/layouts/platform.html"){
|
||||
v-if="!row.isAudit"
|
||||
@click="openAudit(row)" type="primary" size="mini">审核
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="!row.isAudit && $auth.hasRoleOr('sysadmin, A06, tamange, jdh10')"
|
||||
@click="openSendMsg(row, 'normal')" type="warning" size="mini">催办
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -136,12 +147,55 @@ layout("/layouts/platform.html"){
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="sendMsgDialogVisible"
|
||||
title="请在下方填写需要发送的内容"
|
||||
width="50%"
|
||||
>
|
||||
<el-form :model="sendFormData" label-width="80px" ref="sendForm">
|
||||
<el-form-item label="提案名称" prop="userInfo" v-if="sendFormData.proposalName">
|
||||
<el-input placeholder="请选择提案名称" readonly v-model="sendFormData.proposalName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:rules="[{required: true, message: '请输入发送标题', trigger: ['blur', 'change']}]"
|
||||
label="发送标题"
|
||||
prop="title">
|
||||
<el-input
|
||||
placeholder="请输入发送标题"
|
||||
v-model="sendFormData.title">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
:rules="[{required: true, message: '请选择发送内容', trigger: ['blur', 'change']}]"
|
||||
label="发送内容"
|
||||
prop="content">
|
||||
<el-input
|
||||
:rows="6"
|
||||
placeholder="请输入内容"
|
||||
type="textarea"
|
||||
v-model="sendFormData.content">
|
||||
</el-input>
|
||||
<el-alert
|
||||
v-if="sendFormData.content.includes('****')"
|
||||
class="tooltip-alert"
|
||||
title="****会自动替换为每条提案的承办单位名称,请勿修改和删除!!!"
|
||||
type="warning">
|
||||
</el-alert>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<span class="dialog-footer" slot="footer">
|
||||
<el-button @click="sendMsgDialogVisible = false">取 消</el-button>
|
||||
<el-button @click="sendMsg" type="primary">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include("/platform/proposal/include/proposal_include.js"){}#-->
|
||||
|
||||
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
@@ -191,10 +245,64 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
isNode: false,
|
||||
oneKeyRemindDialogVisible: false,
|
||||
oneKeyTableData: []
|
||||
oneKeyTableData: [],
|
||||
|
||||
/**
|
||||
* 发送通知相关
|
||||
*/
|
||||
sendMsgDialogVisible: false,
|
||||
sendFormData: {
|
||||
sessionId: "",
|
||||
proposalId: "",
|
||||
proposalName: "",
|
||||
title: "提案审批通知",
|
||||
content: "尊敬的校领导,****有一个承办提案需要分管校领导审核同意,请点击审核。"
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openSendMsg(row, type) {
|
||||
this.sendFormData.proposalId = row ? row.id : null
|
||||
this.sendFormData.proposalName = row ? row.proposalName : null
|
||||
if(type === 'normal') {
|
||||
this.sendFormData.content = this.sendFormData.content.replace('****', row ? row.underTakeNames : '')
|
||||
} else {
|
||||
this.sendFormData.content = "尊敬的校领导,****有一个承办提案需要分管校领导审核同意,请点击审核。"
|
||||
}
|
||||
this.sendMsgDialogVisible = true
|
||||
},
|
||||
async sendMsg() {
|
||||
const valid = await this.$refs["sendForm"].validate()
|
||||
if (!valid) return
|
||||
const confirm = await this.$confirm("您确定要发送信息吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonTest: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
|
||||
if (confirm === "confirm") {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: "加载中,请稍后...",
|
||||
spinner: "el-icon-loading",
|
||||
background: "rgba(0, 0, 0, 0.7)"
|
||||
})
|
||||
|
||||
const resp = await $.post("/platform/proposal/transact/branchLeaderSuffixAudit/sendNotify", {
|
||||
sessionId: this.pageForm.meetingId,
|
||||
proposalId: this.sendFormData.proposalId,
|
||||
title: this.sendFormData.title,
|
||||
content: this.sendFormData.content
|
||||
})
|
||||
loading.close()
|
||||
if (resp.code === 0) {
|
||||
this.sendMsgDialogVisible = false
|
||||
this.$message.success(resp.msg)
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
}
|
||||
},
|
||||
async rollback(row) {
|
||||
const confirm = await this.$confirm('您确定要撤回吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
@@ -11,11 +11,15 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<proposal-search :page="pageForm" @search="doSearch" title="反馈"></proposal-search>
|
||||
<proposal-search :page="pageForm" @search="doSearch" title="反馈" ref="searchRef"></proposal-search>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="反馈评价" :app="this">
|
||||
<template #func>
|
||||
<el-button v-if="$auth.hasRole('sysadmin')" type="primary"
|
||||
@click="openSendMsg" size="small">
|
||||
一键提醒
|
||||
</el-button>
|
||||
<!-- <el-button @click="oneKeyRemind" size="small" type="primary"-->
|
||||
<!-- v-if="(${@shiro.hasRole('T01') || @shiro.hasRole('sysadmin')} && pageForm.isAudit==false)"-->
|
||||
<!-- >一键提醒-->
|
||||
@@ -58,6 +62,9 @@ layout("/layouts/platform.html"){
|
||||
<el-button v-if="[proposal.FEEDBACKSCORE].includes(row.stateCode)"
|
||||
@click="openFeedback(row)" size="mini" type="primary">反馈
|
||||
</el-button>
|
||||
<el-button v-if="[proposal.FEEDBACKSCORE].includes(row.stateCode) && $auth.hasRoleOr('sysadmin, A06, tamange, jdh10')"
|
||||
type="warning" @click="openSendMsg(row)" size="mini">催办
|
||||
</el-button>
|
||||
<!-- <el-button v-if="row.canRollBack" @click="doWithdraw(row)" size="mini"-->
|
||||
<!-- type="danger">撤回-->
|
||||
<!-- </el-button>-->
|
||||
@@ -147,6 +154,45 @@ layout("/layouts/platform.html"){
|
||||
<el-button @click="confirmOneKeyRemind" type="primary">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="sendMsgDialogVisible"
|
||||
title="请在下方填写需要发送的内容"
|
||||
width="50%"
|
||||
>
|
||||
<el-form :model="sendFormData" label-width="80px" ref="sendForm">
|
||||
<el-form-item label="提案名称" prop="userInfo" v-if="sendFormData.proposalName">
|
||||
<el-input placeholder="请选择提案名称" readonly v-model="sendFormData.proposalName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:rules="[{required: true, message: '请输入发送标题', trigger: ['blur', 'change']}]"
|
||||
label="发送标题"
|
||||
prop="title">
|
||||
<el-input
|
||||
placeholder="请输入发送标题"
|
||||
v-model="sendFormData.title">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
:rules="[{required: true, message: '请选择发送内容', trigger: ['blur', 'change']}]"
|
||||
label="发送内容"
|
||||
prop="content">
|
||||
<el-input
|
||||
:rows="6"
|
||||
placeholder="请输入内容"
|
||||
type="textarea"
|
||||
v-model="sendFormData.content">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span class="dialog-footer" slot="footer">
|
||||
<el-button @click="sendMsgDialogVisible = false">取 消</el-button>
|
||||
<el-button @click="sendMsg" type="primary">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -214,10 +260,69 @@ layout("/layouts/platform.html"){
|
||||
sign: [{required: true, message: '请使用【手机钉钉】扫描二维码进行签字', trigger: ['blur', 'change']}]
|
||||
},
|
||||
oneKeyRemindDialogVisible: false,
|
||||
oneKeyTableData: []
|
||||
oneKeyTableData: [],
|
||||
|
||||
/**
|
||||
* 发送通知相关
|
||||
*/
|
||||
sendMsgDialogVisible: false,
|
||||
sendFormData: {
|
||||
sessionId: "",
|
||||
proposalId: "",
|
||||
proposalName: "",
|
||||
title: "提案反馈通知",
|
||||
content: "尊敬的教代会代表,您在第jdhjs届教代会第jdhcs次会议上提交的提案,相关部门已作出办理回复,请点击评价反馈。"
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async openSendMsg(row) {
|
||||
if(!this.$refs.searchRef.allJdhOptions) {
|
||||
this.$message.warning('教代会信息为空')
|
||||
return
|
||||
}
|
||||
const jdh = this.$refs.searchRef.allJdhOptions.find(o => o.id === this.pageForm.meetingId)
|
||||
if(!jdh) {
|
||||
this.$message.warning('教代会信息为空')
|
||||
return
|
||||
}
|
||||
this.sendFormData.content = this.sendFormData.content.replace('jdhjs', jdh.jdhjs).replace('jdhcs', jdh.jdhcs)
|
||||
this.sendFormData.proposalId = row ? row.id : null
|
||||
this.sendFormData.proposalName = row ? row.proposalName : null
|
||||
this.sendMsgDialogVisible = true
|
||||
},
|
||||
async sendMsg() {
|
||||
const valid = await this.$refs["sendForm"].validate()
|
||||
if (!valid) return
|
||||
const confirm = await this.$confirm("您确定要发送信息吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonTest: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
|
||||
if (confirm === "confirm") {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: "加载中,请稍后...",
|
||||
spinner: "el-icon-loading",
|
||||
background: "rgba(0, 0, 0, 0.7)"
|
||||
})
|
||||
|
||||
const resp = await $.post("/platform/proposal/transact/feedback/sendNotify", {
|
||||
sessionId: this.pageForm.meetingId,
|
||||
proposalId: this.sendFormData.proposalId,
|
||||
title: this.sendFormData.title,
|
||||
content: this.sendFormData.content
|
||||
})
|
||||
loading.close()
|
||||
if (resp.code === 0) {
|
||||
this.sendMsgDialogVisible = false
|
||||
this.$message.success(resp.msg)
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
}
|
||||
},
|
||||
async oneKeyRemind() {
|
||||
const {meetingId} = this.pageForm
|
||||
if (!meetingId) {
|
||||
|
||||
@@ -414,7 +414,7 @@ layout("/layouts/platform.html"){
|
||||
async sendMsg() {
|
||||
const valid = await this.$refs["sendForm"].validate()
|
||||
if (!valid) return
|
||||
const confirm = await this.$confirm("您确定要向发送信息吗?", "提示", {
|
||||
const confirm = await this.$confirm("您确定要发送信息吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonTest: "取消",
|
||||
type: "warning"
|
||||
|
||||
Reference in New Issue
Block a user