commit
This commit is contained in:
@@ -230,8 +230,19 @@ public interface Roles {
|
||||
*/
|
||||
String GH03 = "428969eb99ff4b76883d83f847ee96a5";
|
||||
|
||||
// 党委书记
|
||||
String secretary = "dc6703af06fa456a9d95c1104e8d7c77";
|
||||
|
||||
// 校长
|
||||
String principal = "0d8665494fb64a38b4f18fc810ff1751";
|
||||
|
||||
/**
|
||||
* 工会组组长
|
||||
*/
|
||||
String ghxzzz = "308dfe9096f44a64a67b4714f67dcd96";
|
||||
|
||||
/**
|
||||
* 校提案管理员
|
||||
*/
|
||||
String tmanage = "91623fdad36e45ffbf3e5eab42fb5599";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,397 @@
|
||||
package io.v.nutz.oa;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.v.nutz.oa.client.HhuEduOaClient;
|
||||
import io.v.nutz.oa.enums.HhuEduOaStatusEnum;
|
||||
import io.v.nutz.oa.pojo.RequestResult;
|
||||
import io.v.nutz.oa.util.SudySignUtil;
|
||||
import io.v.nutz.oa.vo.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 河海大学OA服务类
|
||||
*/
|
||||
@Slf4j
|
||||
public class HhuEduOaService {
|
||||
|
||||
// 签名算法方式
|
||||
private static final String algorithm = "SHA1";
|
||||
// 应用APP标识
|
||||
private static final String appCode = "zhgh";
|
||||
// 平台分给业务系统的秘钥
|
||||
private static final String secretKey = "a9985b08-2e1e-4e37-ab19-518b45670133";
|
||||
// 请求域名地址
|
||||
public static String domain = "https://mynew-admin.hhu.edu.cn/taskcenter";
|
||||
// 任务分类代码
|
||||
public static String taskCategoryCode = "zhgh";
|
||||
|
||||
// 实例化
|
||||
public static HhuEduOaService getInstance() {
|
||||
return new HhuEduOaService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建代办任务
|
||||
* @param taskBizId 任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作
|
||||
* @param loginName 任务创建者的代码,由校方数据中心给出,通常为职工号
|
||||
* @param title 任务标题
|
||||
* @param url 任务的处理url
|
||||
* @param doneUrl 任务的已办url
|
||||
*@param processNodeId 流程环节 存进度百分比(0-100)
|
||||
* @param processNodeName 流程环节名称
|
||||
* @param participantUserCodes 参与者的代码,由校方数据中心给出,通常为职工号
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult createTask(String taskBizId, String loginName, String title, String url, String doneUrl, String processNodeId, String processNodeName, List<String> participantUserCodes) {
|
||||
return this.createTask(taskBizId, loginName, title, null, url, doneUrl, processNodeId, processNodeName, null, null, null, participantUserCodes, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建代办任务
|
||||
* @param taskBizId 任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作
|
||||
* @param loginName 任务创建者的代码,由校方数据中心给出,通常为职工号
|
||||
* @param title 任务标题
|
||||
* @param subTitle 子标题
|
||||
* @param url 任务的处理url
|
||||
* @param doneUrl 任务的已办url
|
||||
* @param processNodeId 流程环节 存进度百分比(0-100)
|
||||
* @param processNodeName 流程环节名称
|
||||
* @param participantUserCodes 参与者的代码,由校方数据中心给出,通常为职工号
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult createTask(String taskBizId, String loginName, String title, String subTitle, String url, String doneUrl, String processNodeId, String processNodeName, List<String> participantUserCodes) {
|
||||
return this.createTask(taskBizId, loginName, title, subTitle, url, doneUrl, processNodeId, processNodeName, null, null, null, participantUserCodes, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建代办任务
|
||||
* @param taskBizId 任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作
|
||||
* @param loginName 任务创建者的代码,由校方数据中心给出,通常为职工号
|
||||
* @param title 任务标题
|
||||
* @param url 任务的处理url
|
||||
* @param doneUrl 任务的已办url
|
||||
* @param processNodeId 流程环节 存进度百分比(0-100)
|
||||
* @param processNodeName 流程环节名称
|
||||
* @param applyName 申请人
|
||||
* @param applyLoginName 申请人工号
|
||||
* @param applyOrgName 申请人所在部门
|
||||
* @param participantUserCodes 参与者的代码,由校方数据中心给出,通常为职工号
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult createTask(String taskBizId, String loginName, String title, String url, String doneUrl, String processNodeId, String processNodeName, String applyName, String applyLoginName, String applyOrgName, List<String> participantUserCodes) {
|
||||
return this.createTask(taskBizId, loginName, title, null, url, doneUrl, processNodeId, processNodeName, applyName, applyLoginName, applyOrgName, participantUserCodes, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建代办任务
|
||||
* @param taskBizId 任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作
|
||||
* @param loginName 任务创建者的代码,由校方数据中心给出,通常为职工号
|
||||
* @param title 任务标题
|
||||
* @param subTitle 任务副标题
|
||||
* @param url 任务的处理url
|
||||
* @param doneUrl 任务的已办url
|
||||
* @param processNodeId 流程环节 存进度百分比(0-100)
|
||||
* @param processNodeName 流程环节名称
|
||||
* @param applyName 申请人
|
||||
* @param applyLoginName 申请人工号
|
||||
* @param applyOrgName 申请人所在部门
|
||||
* @param participantUserCodes 参与者的代码,由校方数据中心给出,通常为职工号
|
||||
* @param parentTask 父级任务信息
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult createTask(String taskBizId, String loginName, String title, String subTitle, String url, String doneUrl, String processNodeId, String processNodeName, String applyName, String applyLoginName, String applyOrgName,
|
||||
List<String> participantUserCodes, TaskVO parentTask) {
|
||||
if(StrUtil.isBlank(taskBizId)) {
|
||||
throw new RuntimeException("缺少任务的业务id->taskBizId");
|
||||
}
|
||||
if(StrUtil.isBlank(loginName)) {
|
||||
throw new RuntimeException("缺少任务创建者的代码->loginName");
|
||||
}
|
||||
if(StrUtil.isBlank(title)) {
|
||||
throw new RuntimeException("缺少任务标题->title");
|
||||
}
|
||||
if(StrUtil.isBlank(url)) {
|
||||
throw new RuntimeException("缺少任务的处理URL->url");
|
||||
}
|
||||
if(StrUtil.isBlank(doneUrl)) {
|
||||
throw new RuntimeException("缺少任务的已办URL->doneUrl");
|
||||
}
|
||||
// if(StrUtil.isBlank(processNodeName)) {
|
||||
// throw new RuntimeException("缺少任务的流程环节名称->processNodeName");
|
||||
// }
|
||||
if(!ArrayUtil.isAllNotEmpty(participantUserCodes)) {
|
||||
throw new RuntimeException("缺少任务的参与者代码->participantUserCodes");
|
||||
}
|
||||
// if(participantUserCodes.contains(loginName)) {
|
||||
// throw new RuntimeException("发起人不能是参与审批人");
|
||||
// }
|
||||
String timestamp=System.currentTimeMillis()+"";
|
||||
String nonce = IdUtil.randomUUID().toString().replaceAll("-", "");
|
||||
|
||||
// 创建任务参数
|
||||
TaskVO taskVO = getCreateTaskVo(taskBizId, loginName, title, subTitle, url, doneUrl, processNodeName, applyName, applyLoginName, applyOrgName, participantUserCodes, parentTask);
|
||||
// taskVO.setCreateName("印天宇");
|
||||
// CreaterVO creater = new CreaterVO();
|
||||
// creater.setName(taskVO.getCreateName());
|
||||
// creater.setLoginName(taskVO.getCreatorId());
|
||||
// taskVO.setCreater(creater);
|
||||
taskVO.setProcessNodeId(processNodeId);
|
||||
String createTaskUrl = domain+"/_web/_apps/taskcenter/api/v3/taskcenter/app/"+appCode+"/task/category/"+taskCategoryCode+".rst";
|
||||
String resutl = HhuEduOaClient.client(appCode, algorithm).doPost(createTaskUrl, JSONObject.toJSONString(taskVO), getSign(timestamp, nonce), nonce, timestamp, null);
|
||||
log.info("创建待办任务result->{}",resutl);
|
||||
RequestResult requestResult = JSONObject.parseObject(resutl,RequestResult.class);
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建任务并完成
|
||||
* @param taskBizId 任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作
|
||||
* @param loginName 任务创建者的代码,由校方数据中心给出,通常为职工号
|
||||
* @param title 任务标题
|
||||
* @param subTitle 任务副标题
|
||||
* @param url 任务的处理url
|
||||
* @param participantUserCodes 参与者的代码,由校方数据中心给出,通常为职工号
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult createTaskAndUserDone(String taskBizId, String loginName, String title, String subTitle, String url, List<String> participantUserCodes) {
|
||||
if(StrUtil.isBlank(taskBizId)) {
|
||||
throw new RuntimeException("缺少任务的业务id->taskBizId");
|
||||
}
|
||||
if(StrUtil.isBlank(loginName)) {
|
||||
throw new RuntimeException("缺少任务创建者的代码->loginName");
|
||||
}
|
||||
if(StrUtil.isBlank(loginName)) {
|
||||
throw new RuntimeException("缺少任务创建者的代码->loginName");
|
||||
}
|
||||
if(StrUtil.isBlank(title)) {
|
||||
throw new RuntimeException("缺少任务标题->title");
|
||||
}
|
||||
if(StrUtil.isBlank(url)) {
|
||||
throw new RuntimeException("缺少任务的处理URL->url");
|
||||
}
|
||||
if(!ArrayUtil.isAllNotEmpty(participantUserCodes)) {
|
||||
throw new RuntimeException("缺少任务的参与者代码->participantUserCodes");
|
||||
}
|
||||
String timestamp=System.currentTimeMillis()+"";
|
||||
String nonce = IdUtil.randomUUID().toString().replaceAll("-", "");
|
||||
TaskAndDoneAO taskAndDoneAO = getCreateTaskAndDoneAO(taskBizId, loginName, title, subTitle, url, participantUserCodes);
|
||||
String taskAndDoneUrl = domain + "/_web/_apps/taskcenter/api/v3/taskcenter/app/"+ appCode+"/task/category/"+ taskCategoryCode+"/done.rst?userId="+loginName;
|
||||
String resutl = HhuEduOaClient.client(appCode, algorithm).doPost(taskAndDoneUrl, JSONObject.toJSONString(taskAndDoneAO), getSign(timestamp, nonce), nonce, timestamp, null);
|
||||
log.info("创建代办任务并完成任务result->{}",resutl);
|
||||
RequestResult requestResult = JSONObject.parseObject(resutl,RequestResult.class);
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新代办任务属性
|
||||
* @param taskBizId 其值是业务系统先前调用createTask时的给出的Task.taskBizId
|
||||
* @param doneUrl 任务的已办url
|
||||
* @param task 更新的任务信息
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult updateTask(String taskBizId, String doneUrl, TaskVO task) {
|
||||
if(task == null) {
|
||||
task = new TaskVO();
|
||||
}
|
||||
task.setTaskBizId(taskBizId);
|
||||
task.setDoneUrl(doneUrl);
|
||||
String timestamp=System.currentTimeMillis()+"";
|
||||
String nonce = IdUtil.randomUUID().toString().replaceAll("-", "");
|
||||
String updateTaskUrl = domain + "/_web/_apps/taskcenter/api/v3/taskcenter/app/"+appCode+"/task/"+task.getTaskBizId()+"/category/"+taskCategoryCode+".rst?randomId=" + nonce;
|
||||
String resutl = HhuEduOaClient.client(appCode, algorithm).doPost(updateTaskUrl, JSONObject.toJSONString(task), getSign(timestamp, nonce), nonce, timestamp, null);
|
||||
log.info("更新任务result->{}",resutl);
|
||||
RequestResult requestResult = JSONObject.parseObject(resutl,RequestResult.class);
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新任务状态
|
||||
* @param taskBizId 其值是业务系统先前调用createTask时的给出的Task.taskBizId
|
||||
* @param doneUrl 任务的已办url
|
||||
* @param state 任务状态:0-未完成 1-已完成 -1-取消
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult updateTaskState(String taskBizId, String doneUrl, HhuEduOaStatusEnum state) {
|
||||
TaskVO vo = new TaskVO();
|
||||
vo.setState(state.getCode());
|
||||
return updateTask(taskBizId, doneUrl, vo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
* @param taskBizId 其值是业务系统先前调用createTask时的给出的Task.taskBizId
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult deleteTask(String taskBizId) {
|
||||
String timestamp=System.currentTimeMillis()+"";
|
||||
String nonce = IdUtil.randomUUID().toString().replaceAll("-", "");
|
||||
String deleteTaskUrl = domain + "/_web/_apps/taskcenter/api/v3/taskcenter/app/" + appCode + "/task/"+taskBizId+"/delete.rst?cascade=true";
|
||||
String resutl = HhuEduOaClient.client(appCode, algorithm).doPost(deleteTaskUrl, null, getSign(timestamp, nonce), nonce, timestamp, null);
|
||||
log.info("删除任务result->{}",resutl);
|
||||
RequestResult requestResult = JSONObject.parseObject(resutl,RequestResult.class);
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成任务
|
||||
* @param taskBizId 其值是业务系统先前调用createTask时的给出的Task.taskBizId
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult finishTask(String taskBizId) {
|
||||
String timestamp=System.currentTimeMillis()+"";
|
||||
String nonce = IdUtil.randomUUID().toString().replaceAll("-", "");
|
||||
String finishTaskUrl = domain + "/_web/_apps/taskcenter/api/v3/taskcenter/app/"+appCode+"/task/"+ taskBizId+"/finish.rst";
|
||||
FinishTaskVO finishTaskVO = new FinishTaskVO();
|
||||
finishTaskVO.setDoneDate(new Date());
|
||||
String resutl = HhuEduOaClient.client(appCode, algorithm).doPost(finishTaskUrl, JSONObject.toJSONString(finishTaskVO), getSign(timestamp, nonce), nonce, timestamp, null);
|
||||
log.info("完成任务result->{}",resutl);
|
||||
RequestResult requestResult = JSONObject.parseObject(resutl,RequestResult.class);
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为某个指定的用户完成指定的任务
|
||||
* @param taskBizId 任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作
|
||||
* @param loginName 任务创建者的代码,由校方数据中心给出,通常为职工号
|
||||
* @param remark 备注,可以存办理的意见等
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult doneFinishTask(String taskBizId, String loginName, String remark) {
|
||||
String timestamp=System.currentTimeMillis()+"";
|
||||
String nonce = IdUtil.randomUUID().toString().replaceAll("-", "");
|
||||
String doneFinishTaskUrl = domain + "/_web/_apps/taskcenter/api/v3/taskcenter/app/"+appCode+"/task/"+ taskBizId+"/user/"+loginName+"/userDone.rst";
|
||||
UserDoneAO userDoneAO = new UserDoneAO();
|
||||
userDoneAO.setFinishTask(true);
|
||||
userDoneAO.setDoneDate(new Date());
|
||||
userDoneAO.setRemark(remark);
|
||||
String resutl = HhuEduOaClient.client(appCode, algorithm).doPost(doneFinishTaskUrl, JSONObject.toJSONString(userDoneAO), getSign(timestamp, nonce), nonce, timestamp, null);
|
||||
log.info("为某个指定的用户完成指定的任务result->{}",resutl);
|
||||
RequestResult requestResult = JSONObject.parseObject(resutl,RequestResult.class);
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加参与者
|
||||
* @param taskBizId 任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作
|
||||
* @param loginNames 职工号
|
||||
* @return RequestResult
|
||||
*/
|
||||
public RequestResult addPartipantsTask(String taskBizId, List<String> loginNames) {
|
||||
String timestamp=System.currentTimeMillis()+"";
|
||||
String nonce = IdUtil.randomUUID().toString().replaceAll("-", "");
|
||||
String addPartipantsUrl = domain + "/_web/_apps/taskcenter/api/v3/taskcenter/app/"+ appCode +"/task/"+taskBizId+"/participant.rst";
|
||||
ParticipantVO[] participants = new ParticipantVO[loginNames.size()];
|
||||
for (int i = 0; i < loginNames.size(); i++) {
|
||||
ParticipantVO participant = new ParticipantVO();
|
||||
participant.setType(ParticipantVO.TYPE_USER);
|
||||
participant.setUserCode(loginNames.get(i));
|
||||
participants[i] = participant;
|
||||
}
|
||||
String resutl = HhuEduOaClient.client(appCode, algorithm).doPost(addPartipantsUrl, JSONObject.toJSONString(participants), getSign(timestamp, nonce), nonce, timestamp, null);
|
||||
log.info("为某个指定的用户完成指定的任务result->{}",resutl);
|
||||
RequestResult requestResult = JSONObject.parseObject(resutl,RequestResult.class);
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
private TaskAndDoneAO getCreateTaskAndDoneAO(String taskBizId, String loginName, String title, String subTitle, String url, List<String> participantUserCodes) {
|
||||
TaskVO task = new TaskVO();
|
||||
Date date = new Date();
|
||||
task.setCreatorId(loginName);
|
||||
task.setDeadLine(date);
|
||||
task.setUrl(url);
|
||||
task.setImportance(TaskVO.IMPORTANCE_MIDDLE);
|
||||
task.setState(TaskVO.STATE_UNDO);
|
||||
task.setSubTitle(subTitle);
|
||||
task.setTitle(title);
|
||||
task.setTaskBizId(taskBizId);
|
||||
List<ParticipantVO> participantVOS = new ArrayList<>();
|
||||
for(String participantUserCode : participantUserCodes){
|
||||
ParticipantVO vo = new ParticipantVO();
|
||||
vo.setUserCode(participantUserCode);
|
||||
vo.setType(ParticipantVO.TYPE_USER);
|
||||
participantVOS.add(vo);
|
||||
}
|
||||
task.setParticipants(participantVOS.toArray(new ParticipantVO[participantVOS.size()]));
|
||||
UserDoneAO userDoneAO = new UserDoneAO();
|
||||
userDoneAO.setDoneDate(new Date());
|
||||
userDoneAO.setFinishTask(true);
|
||||
userDoneAO.setDelegate(false);
|
||||
TaskAndDoneAO taskAndDoneAO = new TaskAndDoneAO();
|
||||
taskAndDoneAO.setTaskVO(task);
|
||||
taskAndDoneAO.setUserDoneAO(userDoneAO);
|
||||
return taskAndDoneAO;
|
||||
}
|
||||
|
||||
private TaskVO getCreateTaskVo(String taskBizId, String loginName, String title, String subTitle, String url, String doneUrl, String processNodeName, String applyName, String applyLoginName, String applyOrgName,
|
||||
List<String> participantUserCodes, TaskVO parentTask) {
|
||||
TaskVO taskVO = new TaskVO();
|
||||
taskVO.setTaskBizId(taskBizId);
|
||||
taskVO.setCreatorId(loginName);
|
||||
taskVO.setTitle(title);
|
||||
if(StrUtil.isNotBlank(subTitle)) {
|
||||
taskVO.setSubTitle(subTitle);
|
||||
}
|
||||
taskVO.setUrl(url);
|
||||
taskVO.setDoneUrl(doneUrl);
|
||||
if(StrUtil.isNotBlank(processNodeName)) {
|
||||
taskVO.setProcessNodeName(processNodeName);
|
||||
}
|
||||
if(StrUtil.isNotBlank(applyName)){
|
||||
taskVO.setApplyName(applyName);
|
||||
}
|
||||
if(StrUtil.isNotBlank(applyLoginName)){
|
||||
taskVO.setApplyLoginName(applyLoginName);
|
||||
}
|
||||
if(StrUtil.isNotBlank(applyOrgName)){
|
||||
taskVO.setApplyOrgName(applyOrgName);
|
||||
}
|
||||
List<ParticipantVO> participantVOS = new ArrayList<>();
|
||||
for(String participantUserCode : participantUserCodes){
|
||||
ParticipantVO vo = new ParticipantVO();
|
||||
vo.setUserCode(participantUserCode);
|
||||
vo.setType(ParticipantVO.TYPE_USER);
|
||||
participantVOS.add(vo);
|
||||
}
|
||||
taskVO.setParticipants(participantVOS.toArray(new ParticipantVO[participantVOS.size()]));
|
||||
if(parentTask!=null){
|
||||
taskVO.setParentTask(parentTask);
|
||||
}
|
||||
return taskVO;
|
||||
}
|
||||
|
||||
private String getSign(String timestamp, String nonce) {
|
||||
return SudySignUtil.buildSign(algorithm,appCode,timestamp,nonce,null,secretKey);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String taskId = "20260531-01023-9";
|
||||
String loginName = "190020250385";
|
||||
List<String> participantUserCodes = new ArrayList<>();
|
||||
participantUserCodes.add("190020250385");
|
||||
HhuEduOaService.getInstance().createTask(taskId,
|
||||
loginName,
|
||||
"创建代办任务测试-1",
|
||||
"http://127.0.0.1:8087/task/create/",
|
||||
"http://127.0.0.1:8087/task/create/",
|
||||
"10",
|
||||
"代办任务测试-1",
|
||||
"测试人",
|
||||
loginName,
|
||||
loginName,
|
||||
participantUserCodes);
|
||||
// HhuEduOaService.getInstance().deleteTask(taskId);
|
||||
// TaskVO taskVO = new TaskVO();
|
||||
// taskVO.setTitle("1111");
|
||||
// HhuEduOaService.getInstance().updateTask(taskId, "http://127.0.0.1:8087/task/create/", taskVO);
|
||||
// HhuEduOaService.getInstance().finishTask(taskId);
|
||||
// HhuEduOaService.getInstance().doneFinishTask(taskId, loginName, "完成审批");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.v.nutz.oa;
|
||||
|
||||
import io.v.nutz.base.result.Result;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
@IocBean
|
||||
@Ok("json")
|
||||
@At("/test/oa")
|
||||
public class OaTestController {
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService oaAuditInstanceService;
|
||||
|
||||
@Ok("json")
|
||||
@At("/do/port")
|
||||
public Result doPort() {
|
||||
// OaAuditInstance instance = oaAuditInstanceService.createTask(OaBusinessTypeEnum.PROPOSAL, "3443554665768799765", "装修食堂-测试", "桌椅调整", "3443554665768799765", Arrays.asList("01nsno67kgingqkdh00omahgse"), "http://127.0.0.1:8089/sysadmin", "https://www.google.cn/");
|
||||
// oaAuditInstanceService.agree("7467bdbc2b76434891826d6ee0c1eb48", "01nsno67kgingqkdh00omahgse", "同意");
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package io.v.nutz.oa.client;
|
||||
|
||||
import io.v.nutz.oa.util.MyHttpDelete;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HhuEduOaClient {
|
||||
|
||||
// 平台分配的应用标识
|
||||
private String appCode;
|
||||
// 签名算法方式
|
||||
private String algorithm;
|
||||
|
||||
public HhuEduOaClient(String appCode, String algorithm) {
|
||||
this.appCode = appCode;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public static HhuEduOaClient client(String appCode, String algorithm) {
|
||||
return new HhuEduOaClient(appCode, algorithm);
|
||||
}
|
||||
|
||||
public String doDelete(String url,String json,String signature,String nonce,String timestamp) {
|
||||
System.out.println(url);
|
||||
CloseableHttpClient httpClient = null;
|
||||
CloseableHttpResponse response = null;
|
||||
String result = "";
|
||||
try {
|
||||
// 通过址默认配置创建一个httpClient实例
|
||||
httpClient = HttpClients.createDefault();
|
||||
MyHttpDelete httpDelete = new MyHttpDelete(url);
|
||||
// 设置配置请求参数
|
||||
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
|
||||
.setConnectionRequestTimeout(35000)// 请求超时时间
|
||||
.setSocketTimeout(60000)// 数据读取超时时间
|
||||
.build();
|
||||
// 为httpGet实例设置配置
|
||||
httpDelete.setConfig(requestConfig);
|
||||
if(json != null) {
|
||||
StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
|
||||
httpDelete.setEntity(stringEntity);
|
||||
}
|
||||
// 设置请求头信息,鉴权
|
||||
httpDelete.setHeader("sd-appid", appCode);
|
||||
httpDelete.setHeader("sd-algorithm", algorithm);
|
||||
httpDelete.setHeader("sd-timestamp", timestamp);
|
||||
httpDelete.setHeader("sd-nonce", nonce);
|
||||
httpDelete.setHeader("sd-signature", signature);
|
||||
// 执行get请求得到返回对象
|
||||
response = httpClient.execute(httpDelete);
|
||||
// 通过返回对象获取返回数据
|
||||
HttpEntity entity = response.getEntity();
|
||||
// 通过EntityUtils中的toString方法将结果转换为字符串
|
||||
result = EntityUtils.toString(entity);
|
||||
System.out.println(result);
|
||||
} catch (ClientProtocolException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// 关闭资源
|
||||
if (null != response) {
|
||||
try {
|
||||
response.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != httpClient) {
|
||||
try {
|
||||
httpClient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public String doGet(String url,String timestamp,String nonce,String signature,String summaryVer,String summary) {
|
||||
System.out.println(url);
|
||||
CloseableHttpClient httpClient = null;
|
||||
CloseableHttpResponse response = null;
|
||||
String result = "";
|
||||
try {
|
||||
// 通过址默认配置创建一个httpClient实例
|
||||
httpClient = HttpClients.createDefault();
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
// 设置请求头信息,鉴权
|
||||
//httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
|
||||
// 设置配置请求参数
|
||||
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
|
||||
.setConnectionRequestTimeout(35000)// 请求超时时间
|
||||
.setSocketTimeout(60000)// 数据读取超时时间
|
||||
.build();
|
||||
// 设置请求头信息,鉴权
|
||||
httpGet.setHeader("sd-appid", appCode);
|
||||
httpGet.setHeader("sd-algorithm", algorithm);
|
||||
httpGet.setHeader("sd-timestamp", timestamp);
|
||||
httpGet.setHeader("sd-nonce", nonce);
|
||||
httpGet.setHeader("sd-signature", signature);
|
||||
if(summaryVer!= null) {
|
||||
httpGet.setHeader("sd-summary-ver", summaryVer);
|
||||
httpGet.setHeader("sd-summary", summary);
|
||||
}
|
||||
// 为httpGet实例设置配置
|
||||
httpGet.setConfig(requestConfig);
|
||||
// 执行get请求得到返回对象
|
||||
response = httpClient.execute(httpGet);
|
||||
// 通过返回对象获取返回数据
|
||||
HttpEntity entity = response.getEntity();
|
||||
// 通过EntityUtils中的toString方法将结果转换为字符串
|
||||
result = EntityUtils.toString(entity);
|
||||
System.out.println(result);
|
||||
} catch (ClientProtocolException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// 关闭资源
|
||||
if (null != response) {
|
||||
try {
|
||||
response.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != httpClient) {
|
||||
try {
|
||||
httpClient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String doPost(String url, String json, String signature, String nonce,String timestamp,String summary) {
|
||||
System.out.println(url);
|
||||
CloseableHttpClient httpClient = null;
|
||||
CloseableHttpResponse response = null;
|
||||
String result = "";
|
||||
try {
|
||||
// 通过址默认配置创建一个httpClient实例
|
||||
httpClient = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
System.out.println(json);
|
||||
if(json != null) {
|
||||
StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
|
||||
httpPost.setEntity(stringEntity);
|
||||
}
|
||||
// 设置请求头信息,鉴权
|
||||
httpPost.setHeader("sd-appid", appCode);
|
||||
httpPost.setHeader("sd-algorithm", algorithm);
|
||||
httpPost.setHeader("sd-timestamp", timestamp);
|
||||
httpPost.setHeader("sd-nonce", nonce);
|
||||
httpPost.setHeader("sd-signature", signature);
|
||||
if(summary != null){
|
||||
httpPost.setHeader("sd-summary", summary);
|
||||
}
|
||||
// 设置配置请求参数
|
||||
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
|
||||
.setConnectionRequestTimeout(35000)// 请求超时时间
|
||||
.setSocketTimeout(60000)// 数据读取超时时间
|
||||
.build();
|
||||
// 为httpGet实例设置配置
|
||||
httpPost.setConfig(requestConfig);
|
||||
// 执行get请求得到返回对象
|
||||
response = httpClient.execute(httpPost);
|
||||
// 通过返回对象获取返回数据
|
||||
HttpEntity entity = response.getEntity();
|
||||
// 通过EntityUtils中的toString方法将结果转换为字符串
|
||||
result = EntityUtils.toString(entity);
|
||||
System.out.println("111="+result);
|
||||
} catch (ClientProtocolException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// 关闭资源
|
||||
if (null != response) {
|
||||
try {
|
||||
response.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != httpClient) {
|
||||
try {
|
||||
httpClient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String doPut(String url,String json,String signature,String nonce,String timestamp) {
|
||||
CloseableHttpClient httpClient = null;
|
||||
CloseableHttpResponse response = null;
|
||||
String result = "";
|
||||
try {
|
||||
httpClient = HttpClients.createDefault(); // 通过址默认配置创建一个httpClient实例
|
||||
HttpPut httpPut = new HttpPut(url);
|
||||
System.out.println(json);
|
||||
StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
|
||||
httpPut.setEntity(stringEntity);
|
||||
// 设置请求头信息,鉴权
|
||||
httpPut.setHeader("sd-appid", appCode);
|
||||
httpPut.setHeader("sd-algorithm", algorithm);
|
||||
httpPut.setHeader("sd-timestamp", timestamp);
|
||||
httpPut.setHeader("sd-nonce", nonce);
|
||||
httpPut.setHeader("sd-signature", signature);
|
||||
// 设置配置请求参数
|
||||
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
|
||||
.setConnectionRequestTimeout(35000)// 请求超时时间
|
||||
.setSocketTimeout(60000)// 数据读取超时时间
|
||||
.build();
|
||||
|
||||
httpPut.setConfig(requestConfig); // 为httpGet实例设置配置
|
||||
response = httpClient.execute(httpPut);// 执行get请求得到返回对象
|
||||
HttpEntity entity = response.getEntity();// 通过返回对象获取返回数据
|
||||
result = EntityUtils.toString(entity);// 通过EntityUtils中的toString方法将结果转换为字符串
|
||||
System.out.println(result);
|
||||
} catch (ClientProtocolException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// 关闭资源
|
||||
if (null != response) {
|
||||
try {
|
||||
response.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != httpClient) {
|
||||
try {
|
||||
httpClient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.v.nutz.oa.constants;
|
||||
|
||||
public interface CommonConstants {
|
||||
|
||||
public static Integer ZERO = 0;
|
||||
public static Integer ONE = 1;
|
||||
public static Integer TWO = 2;
|
||||
public static Integer THREE = 3;
|
||||
public static Integer FOUR = 4;
|
||||
public static Integer FIVE = 5;
|
||||
public static Integer SIX = 6;
|
||||
public static Integer SEVEN = 7;
|
||||
public static Integer EIGHT = 8;
|
||||
public static Integer NINE = 9;
|
||||
public static Integer TEN = 10;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.v.nutz.oa.controller;
|
||||
|
||||
import io.v.nutz.base.result.Result;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.dto.OaAuditInstanceDto;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@IocBean
|
||||
@Ok("json")
|
||||
@At("/oa/audit/instance")
|
||||
public class OaAuditInstanceController {
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService oaAuditInstanceService;
|
||||
|
||||
/**
|
||||
* 待处理
|
||||
*/
|
||||
@Ok("json")
|
||||
@At("/wait/handle")
|
||||
public Result waitHandle() {
|
||||
List<OaAuditInstance> waitHandleList = oaAuditInstanceService.getWaitHandleList(ShiroUtil.getUserId());
|
||||
return Result.success(waitHandleList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 已处理
|
||||
*/
|
||||
@Ok("json")
|
||||
@At("/complete/handle")
|
||||
public Object completeHandle(PageForm pageForm, OaAuditInstanceDto instance) {
|
||||
instance.setCreateUser(ShiroUtil.getUserId());
|
||||
return oaAuditInstanceService.completeHandle(pageForm.getPageNumber(), pageForm.getPageSize(), instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 我发起的
|
||||
*/
|
||||
@Ok("json")
|
||||
@At("/mine/send")
|
||||
public Object mineSend(PageForm pageForm, OaAuditInstanceDto instance) {
|
||||
instance.setCreateUser(ShiroUtil.getUserId());
|
||||
return oaAuditInstanceService.mineSend(pageForm.getPageNumber(), pageForm.getPageSize(), instance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.v.nutz.oa.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.nutz.dao.entity.annotation.Comment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class OaAuditInstanceDto implements Serializable {
|
||||
|
||||
@Comment("创建人ID")
|
||||
private String createUser;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.v.nutz.oa.enums;
|
||||
|
||||
public enum HhuEduOaStatusEnum {
|
||||
|
||||
STATE_UNDO(0, "未完成"),
|
||||
STATE_DONE(1, "已完成"),
|
||||
STATE_SUSPENDED(2, "已挂起"),
|
||||
STATE_CANCELED(-1, "取消"),
|
||||
STATE_ARCHIVED(3, "已归档"),
|
||||
STATE_STOPED(-2, "已终止"),
|
||||
STATE_DELETED(-3, "已删除");
|
||||
|
||||
private Integer code;
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static HhuEduOaStatusEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
} else {
|
||||
HhuEduOaStatusEnum[] values = values();
|
||||
for (HhuEduOaStatusEnum value : values) {
|
||||
if (value.getCode().equals(code)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
HhuEduOaStatusEnum(Integer code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.v.nutz.oa.enums;
|
||||
|
||||
public enum OaBusinessTypeEnum {
|
||||
WRITE_PROPOSAL(1, "撰写提案方案附议", "9"),
|
||||
TUANZHANG_AUDIT_PROPOSAL(2, "团长审批提案", "18"),
|
||||
PROPOSAL_COMMITTEE_AUDIT(3, "提案委立案审核", "27"),
|
||||
HOST_ORGANIZER_REPLY_HANDLE(4, "主办单位提案答复", "72"),
|
||||
HELP_ORGANIZER_REPLY_HANDLE(5, "协办单位提案答复", "81"),
|
||||
DIVIDE_SCHOOL_LEADERS_AUDIT(6, "分管校领导审批", "90"),
|
||||
PROPOSAL_FEEDBACK_EVALUATE_AUDIT(7, "提案反馈评价", "100"),
|
||||
DIRECTOR_EXECUTIVE_COMMITTEE(8, "执委会主任审核", "36"),
|
||||
PRINCIPAL_SECRETARY_AUDIT(9, "校长、书记审核", "45"),
|
||||
DIRECTOR_EXECUTIVE_CONFIRM_COMMITTEE(10, "执委会主任确认审核", "54"),
|
||||
DIRECTOR_CONFIRM_ORGANIZER_REPLY(11, "提案委确认承办审核", "63");
|
||||
|
||||
private Integer code;
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String processNodeId;
|
||||
|
||||
public String getProcessNodeId() {
|
||||
return processNodeId;
|
||||
}
|
||||
|
||||
public static OaBusinessTypeEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
} else {
|
||||
OaBusinessTypeEnum[] values = values();
|
||||
for (OaBusinessTypeEnum value : values) {
|
||||
if (value.getCode().equals(code)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
OaBusinessTypeEnum(Integer code, String name, String processNodeId) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.processNodeId = processNodeId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package io.v.nutz.oa.enums;
|
||||
|
||||
public enum OaStatusEnum {
|
||||
// 状态: 0.未提交 1.审批中 2.审批完成 3.审批驳回 4.审批撤回
|
||||
NO_AUDIT(0, "未提交"),
|
||||
AUDITING(1, "审批中"),
|
||||
AUDIT_PASS(2, "审批完成"),
|
||||
REJECT(3, "审批驳回"),
|
||||
CANCEL(4, "审批撤回");
|
||||
|
||||
private Integer code;
|
||||
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static OaStatusEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
} else {
|
||||
OaStatusEnum[] values = values();
|
||||
for (OaStatusEnum value : values) {
|
||||
if (value.getCode().equals(code)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
OaStatusEnum(Integer code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package io.v.nutz.oa.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@Comment("审批实例流程")
|
||||
@Table(value = "oa_audit_instance")
|
||||
public class OaAuditInstance implements Serializable {
|
||||
|
||||
@Name
|
||||
@Comment("主键ID")
|
||||
@Column(value = "id")
|
||||
@Prev(els = {@EL("uuid()")})
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String id;
|
||||
|
||||
@Comment("业务ID")
|
||||
@Column(value = "business_id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String businessId;
|
||||
|
||||
|
||||
@Comment("业务类型: 1.代表提案")
|
||||
@Column(value = "business_type")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer businessType;
|
||||
|
||||
@Comment("流程名称")
|
||||
@Column(value = "process_name")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String processName;
|
||||
|
||||
@Comment("实例标题")
|
||||
@Column(value = "title")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String title;
|
||||
|
||||
@Comment("子标题")
|
||||
@Column(value = "sub_title")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String subTitle;
|
||||
|
||||
@Comment("业务实例ID")
|
||||
@Column(value = "business_task_id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String businessTaskId;
|
||||
|
||||
@Comment("业务实例ID")
|
||||
@Column(value = "instance_task_id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String instanceTaskId ;
|
||||
|
||||
@Comment("创建人ID")
|
||||
@Column(value = "create_user")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String createUser;
|
||||
|
||||
@Comment("创建人")
|
||||
@Column(value = "create_name")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String createName;
|
||||
|
||||
@Comment("第三方职工号")
|
||||
@Column(value = "create_login_code")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String createLoginCode;
|
||||
|
||||
@Comment("状态: 0.未提交 1.审批中 2.审批完成 3.审批驳回 4.审批撤回")
|
||||
@Column(value = "status")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer status;
|
||||
|
||||
@Comment("状态备注")
|
||||
@Column(value = "status_reason")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String statusReason;
|
||||
|
||||
@Comment("创建时间")
|
||||
@Column(value = "create_time")
|
||||
@ColDefine(type = ColType.TIMESTAMP)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
@Comment("审批结束时间")
|
||||
@Column(value = "over_time")
|
||||
@ColDefine(type = ColType.TIMESTAMP)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date overTime;
|
||||
|
||||
@Comment("任务的处理url")
|
||||
@Column(value = "url")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String url;
|
||||
|
||||
@Comment("任务的已办url")
|
||||
@Column(value = "done_url")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String doneUrl;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.v.nutz.oa.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@Comment("审批实例用户")
|
||||
@Table(value = "oa_instance_user")
|
||||
public class OaInstanceUser implements Serializable {
|
||||
|
||||
@Name
|
||||
@Comment("主键ID")
|
||||
@Column(value = "id")
|
||||
@Prev(els = {@EL("uuid()")})
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String id;
|
||||
|
||||
@Comment("实例ID")
|
||||
@Column(value = "instance_id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String instanceId;
|
||||
|
||||
@Comment("用户ID")
|
||||
@Column(value = "user_id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String userId;
|
||||
|
||||
@Comment("用户名称")
|
||||
@Column(value = "user_name")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String userName;
|
||||
|
||||
@Comment("第三方职工号")
|
||||
@Column(value = "user_login_code")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String userLoginCode;
|
||||
|
||||
@Comment("状态: 0.未提交 1.审批中 2.审批完成 3.审批驳回 4.审批撤回")
|
||||
@Column(value = "status")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer status;
|
||||
|
||||
@Comment("状态备注")
|
||||
@Column(value = "status_reason")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String statusReason;
|
||||
|
||||
@Comment("创建时间")
|
||||
@Column(value = "create_time")
|
||||
@ColDefine(type = ColType.TIMESTAMP)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
@Comment("审批结束时间")
|
||||
@Column(value = "over_time")
|
||||
@ColDefine(type = ColType.TIMESTAMP)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date overTime;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.v.nutz.oa.notify;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.v.nutz.base.result.Result;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@At("/notify/oa/audit")
|
||||
public class OaAuditNotify {
|
||||
|
||||
|
||||
/**
|
||||
* 任务处理
|
||||
*/
|
||||
@Ok("json")
|
||||
@At("/handle/task")
|
||||
public Result handleTask(Map<String, Object> map) {
|
||||
log.info("收到OA任务处理通知:{}", JSONObject.toJSONString(map));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务已办通知
|
||||
*/
|
||||
@Ok("json")
|
||||
@At("/finish/task")
|
||||
public Result finishTask(Map<String, Object> map) {
|
||||
log.info("收到OA任务已办通知:{}", JSONObject.toJSONString(map));
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.v.nutz.oa.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain=true)
|
||||
public class RequestResult {
|
||||
|
||||
private String errorMsg;
|
||||
|
||||
private Result result;
|
||||
|
||||
private Integer resultCode;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain=true)
|
||||
public class Result {
|
||||
|
||||
private Object data;
|
||||
|
||||
private Integer total;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package io.v.nutz.oa.service;
|
||||
|
||||
import io.v.nutz.base.page.Pagination;
|
||||
import io.v.nutz.base.service.BaseService;
|
||||
import io.v.nutz.oa.dto.OaAuditInstanceDto;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.enums.OaStatusEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IOaAuditInstanceService extends BaseService<OaAuditInstance> {
|
||||
|
||||
List<OaAuditInstance> getWaitHandleList(String userId);
|
||||
|
||||
|
||||
OaAuditInstance getByUser(OaBusinessTypeEnum businessTypeEnum, String businessId, String userId);
|
||||
|
||||
OaAuditInstance getByUser(OaBusinessTypeEnum businessTypeEnum, String userId);
|
||||
|
||||
Pagination completeHandle(Integer pageNumber, Integer pageSize, OaAuditInstanceDto instance);
|
||||
|
||||
Pagination mineSend(Integer pageNumber, Integer pageSize, OaAuditInstanceDto instance);
|
||||
|
||||
OaAuditInstance getByBusinessType(OaBusinessTypeEnum businessType, String businessId);
|
||||
|
||||
List<OaAuditInstance> getByBusinessTypeRunning(OaBusinessTypeEnum businessType);
|
||||
|
||||
List<OaAuditInstance> getAllByBusinessType(OaBusinessTypeEnum businessType, String businessId);
|
||||
|
||||
/**
|
||||
* 创建审批代办任务信息
|
||||
* @param businessType 业务类型 用来区分任务审批
|
||||
* @param businessId 审批的对应业务数据ID
|
||||
* @param title 主标题
|
||||
* @param subTitle 子标题
|
||||
* @param createUserId 创建任务ID
|
||||
* @param auditUsers 参与审批人ID
|
||||
* @param url 任务的处理url
|
||||
* @param doneUrl 任务的已办URL
|
||||
* @return OaAuditInstance
|
||||
*/
|
||||
OaAuditInstance createTask(OaBusinessTypeEnum businessType, String businessId, String title, String subTitle, String createUserId, List<String> auditUsers, String url, String doneUrl);
|
||||
|
||||
/**
|
||||
* 创建审批代办任务信息
|
||||
* @param businessType 业务类型 用来区分任务审批
|
||||
* @param businessId 审批的对应业务数据ID
|
||||
* @param processName 流程名称
|
||||
* @param title 主标题
|
||||
* @param subTitle 子标题
|
||||
* @param createUserId 创建任务ID
|
||||
* @param auditUsers 参与审批人ID
|
||||
* @param url 任务的处理url
|
||||
* @param doneUrl 任务的已办URL
|
||||
* @return OaAuditInstance
|
||||
*/
|
||||
OaAuditInstance createTask(OaBusinessTypeEnum businessType, String businessId, String processName, String title, String subTitle, String createUserId, List<String> auditUsers, String url, String doneUrl);
|
||||
|
||||
/**
|
||||
* 同意 参与审批者同意
|
||||
* @param instanceId 实例ID
|
||||
* @param remark 备注
|
||||
*/
|
||||
void agree(String instanceId, String remark);
|
||||
|
||||
/**
|
||||
* 同意 参与审批者同意
|
||||
* @param instanceId 实例ID
|
||||
* @param userId 审核用户ID
|
||||
* @param remark 备注
|
||||
*/
|
||||
void agree(String instanceId, String userId, String remark);
|
||||
|
||||
/**
|
||||
* 同意 参与审批者同意
|
||||
* @param instanceId 实例ID
|
||||
* @param userId 审核用户ID
|
||||
* @param remark 备注
|
||||
* @param isAgreeOne 是否同意一人整个任务通过
|
||||
*/
|
||||
void agree(String instanceId, String userId, String remark, Boolean isAgreeOne);
|
||||
|
||||
/** 拒绝
|
||||
*
|
||||
* @param instanceId 实例ID
|
||||
* @param userId 审核用户ID
|
||||
* @param remark 备注
|
||||
*/
|
||||
void refuse(String instanceId, String userId, String remark);
|
||||
|
||||
/**
|
||||
* 任务取消/撤回 由任务发起者来取消 整个任务结束
|
||||
* @param instanceId 任务实例ID
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
void cancel(String instanceId, String userId);
|
||||
|
||||
/**
|
||||
* 更新实例状态
|
||||
* @param id 任务实例ID
|
||||
* @param oaStatusEnum 状态
|
||||
* @param instanceTaskId
|
||||
*/
|
||||
void updateInstanceStatus(String id, OaStatusEnum oaStatusEnum, String instanceTaskId);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.v.nutz.oa.service;
|
||||
|
||||
import io.v.nutz.base.service.BaseService;
|
||||
import io.v.nutz.oa.enums.OaStatusEnum;
|
||||
import io.v.nutz.oa.model.OaInstanceUser;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IOaInstanceUserService extends BaseService<OaInstanceUser> {
|
||||
|
||||
OaInstanceUser getByUserId(String instanceId, String userId);
|
||||
|
||||
List<OaInstanceUser> getAuditing(String instanceId);
|
||||
|
||||
List<NutMap> getInstanceUser(String instanceId);
|
||||
|
||||
void createRecord(String instanceId, List<String> userIds);
|
||||
|
||||
void createRecord(String instanceId, List<String> userIds, OaStatusEnum oaStatusEnum);
|
||||
|
||||
void updateStatus(String id, OaStatusEnum oaStatusEnum, String statusReason);
|
||||
|
||||
void updateStatusByInstanceId(String instanceId, OaStatusEnum oaStatusEnum);
|
||||
|
||||
void appendAuditUser(String instanceId, String businessTaskId, List<String> auditUsers);
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
package io.v.nutz.oa.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import io.v.nutz.base.page.Pagination;
|
||||
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
||||
import io.v.nutz.oa.HhuEduOaService;
|
||||
import io.v.nutz.oa.constants.CommonConstants;
|
||||
import io.v.nutz.oa.dto.OaAuditInstanceDto;
|
||||
import io.v.nutz.oa.enums.HhuEduOaStatusEnum;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.enums.OaStatusEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.model.OaInstanceUser;
|
||||
import io.v.nutz.oa.pojo.RequestResult;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.oa.service.IOaInstanceUserService;
|
||||
import io.v.nutz.oa.util.BillNoUtil;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.services.SysUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class OaAuditInstanceServiceImpl extends BaseServiceImpl<OaAuditInstance> implements IOaAuditInstanceService {
|
||||
|
||||
@Inject
|
||||
private PropertiesProxy conf;
|
||||
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Inject
|
||||
private IOaInstanceUserService instanceUserService;
|
||||
|
||||
|
||||
public OaAuditInstanceServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OaAuditInstance> getWaitHandleList(String userId) {
|
||||
Sql sql = Sqls.create("select * from oa_audit_instance where status = 1" +
|
||||
" and id in (select instance_id from oa_instance_user where status = 1 and" +
|
||||
" user_id=@user_id) order by create_time asc");
|
||||
sql.params().set("user_id", userId);
|
||||
sql.setCallback(Sqls.callback.records());
|
||||
this.dao().execute(sql);
|
||||
return sql.getList(OaAuditInstance.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OaAuditInstance getByUser(OaBusinessTypeEnum businessTypeEnum, String businessId, String userId) {
|
||||
Sql sql = Sqls.create("select oai.*" +
|
||||
"from oa_instance_user oiu left join oa_audit_instance oai on oiu.instance_id = oai.id " +
|
||||
"where oai.business_type=@business_type and oai.business_id=@business_id and oiu.user_id=@user_id" +
|
||||
" and oai.status=1 order by oai.create_time desc limit 0,1");
|
||||
sql.params().set("business_type", businessTypeEnum.getCode());
|
||||
sql.params().set("business_id", businessId);
|
||||
sql.params().set("user_id", userId);
|
||||
sql.setCallback(Sqls.callback.record());
|
||||
this.dao().execute(sql);
|
||||
return sql.getObject(OaAuditInstance.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OaAuditInstance getByUser(OaBusinessTypeEnum businessTypeEnum, String userId) {
|
||||
Sql sql = Sqls.create("select oai.*" +
|
||||
"from oa_instance_user oiu left join oa_audit_instance oai on oiu.instance_id = oai.id " +
|
||||
"where oai.business_type=@business_type and oiu.user_id=@user_id" +
|
||||
" and oai.status=1 and oiu.status=1 order by oai.create_time desc limit 0,1");
|
||||
sql.params().set("business_type", businessTypeEnum.getCode());
|
||||
sql.params().set("user_id", userId);
|
||||
sql.setCallback(Sqls.callback.record());
|
||||
this.dao().execute(sql);
|
||||
return sql.getObject(OaAuditInstance.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination completeHandle(Integer pageNumber, Integer pageSize, OaAuditInstanceDto instance) {
|
||||
Sql sql = Sqls.create("select oai.* " +
|
||||
"from oa_instance_user oiu left join oa_audit_instance oai on oiu.instance_id = oai.id" +
|
||||
" where oiu.user_id=@user_id and (oiu.status not in (0,1) or oai.status not in(0,1))" +
|
||||
" order by oiu.create_time desc");
|
||||
sql.params().set("user_id", instance.getCreateUser());
|
||||
return listPage(pageNumber, pageSize, sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination mineSend(Integer pageNumber, Integer pageSize, OaAuditInstanceDto instance) {
|
||||
Sql sql = Sqls.create("select * from oa_audit_instance where create_user=@create_user order by create_time desc");
|
||||
sql.params().set("create_user", instance.getCreateUser());
|
||||
return listPage(pageNumber, pageSize, sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OaAuditInstance> getByBusinessTypeRunning(OaBusinessTypeEnum businessType) {
|
||||
Sql sql = Sqls.create("select * from oa_audit_instance where business_type=@business_type " +
|
||||
"and business_id=@business_id and status=1");
|
||||
sql.params().set("business_type", businessType.getCode());
|
||||
sql.setCallback(Sqls.callback.maps());
|
||||
this.dao().execute(sql);
|
||||
return sql.getList(OaAuditInstance.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OaAuditInstance getByBusinessType(OaBusinessTypeEnum businessType, String businessId) {
|
||||
Sql sql = Sqls.create("select * from oa_audit_instance where business_type=@business_type " +
|
||||
"and business_id=@business_id and status=1 limit 0,1");
|
||||
sql.params().set("business_type", businessType.getCode());
|
||||
sql.params().set("business_id", businessId);
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
this.dao().execute(sql);
|
||||
return sql.getObject(OaAuditInstance.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OaAuditInstance> getAllByBusinessType(OaBusinessTypeEnum businessType, String businessId) {
|
||||
Sql sql = Sqls.create("select * from oa_audit_instance where business_type=@business_type " +
|
||||
"and business_id=@business_id");
|
||||
sql.params().set("business_type", businessType.getCode());
|
||||
sql.params().set("business_id", businessId);
|
||||
sql.setCallback(Sqls.callback.maps());
|
||||
this.dao().execute(sql);
|
||||
return sql.getList(OaAuditInstance.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OaAuditInstance createTask(OaBusinessTypeEnum businessType, String businessId, String title, String subTitle, String createUserId, List<String> auditUsers, String url, String doneUrl) {
|
||||
return this.createTask(businessType, businessId, null, title, subTitle, createUserId, auditUsers, url, doneUrl);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OaAuditInstance createTask(OaBusinessTypeEnum businessType, String businessId, String processName, String title, String subTitle, String createUserId, List<String> auditUsers, String url, String doneUrl) {
|
||||
// OaAuditInstance instance = this.getByBusinessType(businessType, businessId);
|
||||
// if(instance != null) {
|
||||
//
|
||||
// // 追加审批用户
|
||||
// instanceUserService.appendAuditUser(instance.getId(), instance.getBusinessTaskId(), auditUsers);
|
||||
// this.updateInstanceStatus(instance.getId(), OaStatusEnum.AUDITING, instance.getInstanceTaskId());
|
||||
// return instance;
|
||||
// }
|
||||
//
|
||||
// instance = new OaAuditInstance();
|
||||
OaAuditInstance instance = new OaAuditInstance();
|
||||
instance.setBusinessType(businessType.getCode());
|
||||
instance.setBusinessId(businessId);
|
||||
instance.setTitle(title);
|
||||
instance.setSubTitle(subTitle);
|
||||
instance.setCreateTime(DateUtil.date());
|
||||
instance.setStatus(OaStatusEnum.NO_AUDIT.getCode());
|
||||
instance.setProcessName(processName);
|
||||
instance.setUrl(url);
|
||||
instance.setDoneUrl(doneUrl);
|
||||
|
||||
// 提交人用户信息
|
||||
Sys_user submitUser = sysUserService.fetch(createUserId);
|
||||
if(submitUser == null){
|
||||
throw new RuntimeException("提交人不存在");
|
||||
}
|
||||
instance.setCreateUser(submitUser.getId());
|
||||
instance.setCreateName(submitUser.getUsername());
|
||||
instance.setCreateLoginCode(submitUser.getLoginname());
|
||||
// 业务实例ID
|
||||
String businessTaskId = BillNoUtil.getBusinessTaskId();
|
||||
instance.setBusinessTaskId(businessTaskId);
|
||||
this.insert(instance);
|
||||
|
||||
// 任务实例参与审批信息
|
||||
instanceUserService.createRecord(instance.getId(), auditUsers);
|
||||
|
||||
// 生成第三方代办任务实例
|
||||
this.createHhuEduOa(instance.getId());
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void agree(String instanceId, String remark) {
|
||||
List<OaInstanceUser> oaInstanceUsers = instanceUserService.getAuditing(instanceId);
|
||||
for(OaInstanceUser user : oaInstanceUsers) {
|
||||
this.agree(instanceId, user.getUserId(), remark);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void agree(String instanceId, String userId, String remark) {
|
||||
this.agree(instanceId, userId, remark, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void agree(String instanceId, String userId, String remark, Boolean isAgreeOne) {
|
||||
OaInstanceUser instanceUser = instanceUserService.getByUserId(instanceId, userId);
|
||||
if(instanceUser == null) {
|
||||
throw new RuntimeException("当前用户未参与审批");
|
||||
}
|
||||
OaAuditInstance instance = this.fetch(instanceId);
|
||||
if(instance.getStatus().equals(OaStatusEnum.AUDIT_PASS.getCode()) || instance.getStatus().equals(OaStatusEnum.CANCEL.getCode())) {
|
||||
throw new RuntimeException("该任务已结束");
|
||||
}
|
||||
RequestResult result = HhuEduOaService.getInstance().doneFinishTask(instance.getBusinessTaskId(), instanceUser.getUserLoginCode(), remark);
|
||||
if(!result.getResultCode().equals(CommonConstants.ZERO)) {
|
||||
// throw new RuntimeException(result.getErrorMsg());
|
||||
log.info("调用第三方待办服务异常:{}", result.getErrorMsg());
|
||||
}
|
||||
instanceUserService.updateStatus(instanceUser.getId(), OaStatusEnum.AUDIT_PASS, remark);
|
||||
|
||||
// 审批中用户
|
||||
List<OaInstanceUser> auditingUsers = instanceUserService.getAuditing(instance.getId());
|
||||
if(auditingUsers == null || auditingUsers.size() <= 0) {
|
||||
this.updateInstanceStatus(instanceId, OaStatusEnum.AUDIT_PASS, instance.getInstanceTaskId());
|
||||
|
||||
} else if(isAgreeOne) {
|
||||
this.updateInstanceStatus(instanceId, OaStatusEnum.AUDIT_PASS, instance.getInstanceTaskId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refuse(String instanceId, String userId, String remark) {
|
||||
OaInstanceUser instanceUser = instanceUserService.getByUserId(instanceId, userId);
|
||||
if(instanceUser == null) {
|
||||
throw new RuntimeException("当前用户未参与审批");
|
||||
}
|
||||
OaAuditInstance instance = this.fetch(instanceId);
|
||||
if(instance.getStatus().equals(OaStatusEnum.AUDIT_PASS.getCode()) || instance.getStatus().equals(OaStatusEnum.CANCEL.getCode())) {
|
||||
throw new RuntimeException("该任务已结束");
|
||||
}
|
||||
RequestResult result = HhuEduOaService.getInstance().doneFinishTask(instance.getBusinessTaskId(), instanceUser.getUserLoginCode(), remark);
|
||||
if(!result.getResultCode().equals(CommonConstants.ZERO)) {
|
||||
throw new RuntimeException(result.getErrorMsg());
|
||||
}
|
||||
instanceUserService.updateStatus(instanceUser.getId(), OaStatusEnum.REJECT, remark);
|
||||
|
||||
// 主流程驳回
|
||||
this.updateInstanceStatus(instanceId, OaStatusEnum.REJECT, instance.getInstanceTaskId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(String instanceId, String userId) {
|
||||
OaAuditInstance instance = this.fetch(instanceId);
|
||||
if(instance == null) {
|
||||
throw new RuntimeException("任务实例不存在");
|
||||
}
|
||||
if(instance.getStatus().equals(OaStatusEnum.AUDIT_PASS.getCode()) || instance.getStatus().equals(OaStatusEnum.CANCEL.getCode())) {
|
||||
throw new RuntimeException("该任务已结束");
|
||||
}
|
||||
if(!instance.getCreateUser().equals(userId)) {
|
||||
throw new RuntimeException("该用户无权限取消/撤回待办任务");
|
||||
}
|
||||
RequestResult result = HhuEduOaService.getInstance().updateTaskState(instance.getBusinessTaskId(), "", HhuEduOaStatusEnum.STATE_CANCELED);
|
||||
if(!result.getResultCode().equals(CommonConstants.ZERO)) {
|
||||
throw new RuntimeException(result.getErrorMsg());
|
||||
}
|
||||
this.updateInstanceStatus(instance.getId(), OaStatusEnum.CANCEL, instance.getInstanceTaskId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateInstanceStatus(String id, OaStatusEnum oaStatusEnum, String instanceTaskId) {
|
||||
StringBuilder sqlStr = new StringBuilder("update oa_audit_instance set status=@status, instance_task_id=@instance_task_id");
|
||||
if(OaStatusEnum.AUDIT_PASS.getCode().equals(oaStatusEnum.getCode())) {
|
||||
sqlStr.append(", over_time=@over_time");
|
||||
}
|
||||
sqlStr.append(" where id=@id");
|
||||
|
||||
Sql sql = Sqls.create(sqlStr.toString());
|
||||
sql.params().set("instance_task_id", instanceTaskId);
|
||||
sql.params().set("status", oaStatusEnum.getCode());
|
||||
if(OaStatusEnum.AUDIT_PASS.getCode().equals(oaStatusEnum.getCode())) {
|
||||
sql.params().set("over_time", DateUtil.date());
|
||||
}
|
||||
sql.params().set("id", id);
|
||||
this.dao().execute(sql);
|
||||
}
|
||||
|
||||
// 生成第三方代办任务实例
|
||||
private void createHhuEduOa(String id) {
|
||||
// String serverPort = conf.get("server.port");
|
||||
OaAuditInstance instance = this.fetch(id);
|
||||
Sql sql = Sqls.create("select * from oa_instance_user where instance_id = @instance_id");
|
||||
sql.params().set("instance_id", id);
|
||||
List<OaInstanceUser> instanceUsers = instanceUserService.listEntity(sql);
|
||||
List<String> participantUserCodes = Collections.synchronizedList(new ArrayList<String>());
|
||||
for(OaInstanceUser instanceUser : instanceUsers){
|
||||
participantUserCodes.add(instanceUser.getUserLoginCode());
|
||||
}
|
||||
OaBusinessTypeEnum businessTypeEnum = OaBusinessTypeEnum.getByCode(instance.getBusinessType());
|
||||
RequestResult result = HhuEduOaService.getInstance().createTask(instance.getBusinessTaskId(),
|
||||
instance.getCreateLoginCode(),
|
||||
instance.getTitle(),
|
||||
instance.getSubTitle(),
|
||||
instance.getUrl(),
|
||||
instance.getDoneUrl(),
|
||||
businessTypeEnum.getProcessNodeId(),
|
||||
instance.getProcessName(),
|
||||
participantUserCodes);
|
||||
Integer resultCode = result.getResultCode();
|
||||
if(resultCode.equals(CommonConstants.ZERO)){
|
||||
Object instanceTaskId = result.getResult().getData();
|
||||
this.updateInstanceStatus(instance.getId(), OaStatusEnum.AUDITING, String.valueOf(instanceTaskId));
|
||||
instanceUserService.updateStatusByInstanceId(instance.getId(), OaStatusEnum.AUDITING);
|
||||
} else {
|
||||
String errorMsg = result.getErrorMsg();
|
||||
throw new RuntimeException(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package io.v.nutz.oa.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
||||
import io.v.nutz.oa.HhuEduOaService;
|
||||
import io.v.nutz.oa.enums.OaStatusEnum;
|
||||
import io.v.nutz.oa.model.OaInstanceUser;
|
||||
import io.v.nutz.oa.service.IOaInstanceUserService;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.services.SysUserService;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class OaInstanceUserServiceImpl extends BaseServiceImpl<OaInstanceUser> implements IOaInstanceUserService {
|
||||
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
|
||||
public OaInstanceUserServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OaInstanceUser getByUserId(String instanceId, String userId) {
|
||||
Sql sql = Sqls.create("select * from oa_instance_user where user_id =@user_id and instance_id=@instance_id limit 0,1");
|
||||
sql.params().set("user_id", userId);
|
||||
sql.params().set("instance_id", instanceId);
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
this.dao().execute(sql);
|
||||
return sql.getObject(OaInstanceUser.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OaInstanceUser> getAuditing(String instanceId) {
|
||||
Sql sql = Sqls.create("select * from oa_instance_user where instance_id =@instance_id and status=1");
|
||||
sql.params().set("instance_id", instanceId);
|
||||
sql.setCallback(Sqls.callback.records());
|
||||
this.dao().execute(sql);
|
||||
return sql.getList(OaInstanceUser.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> getInstanceUser(String instanceId) {
|
||||
Sql sql = Sqls.create("select * from oa_instance_user where instance_id =@instance_id");
|
||||
sql.params().set("instance_id", instanceId);
|
||||
sql.setCallback(Sqls.callback.maps());
|
||||
this.dao().execute(sql);
|
||||
return sql.getList(NutMap.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createRecord(String instanceId, List<String> userIds) {
|
||||
this.createRecord(instanceId, userIds, OaStatusEnum.NO_AUDIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createRecord(String instanceId, List<String> userIds, OaStatusEnum statusEnum) {
|
||||
if(userIds==null || userIds.isEmpty()){
|
||||
throw new RuntimeException("缺少参与审批人");
|
||||
}
|
||||
List<OaInstanceUser> instanceUsers = new ArrayList<>();
|
||||
for(String userId : userIds) {
|
||||
Sys_user sys_user = sysUserService.fetch(userId);
|
||||
OaInstanceUser instanceUser = new OaInstanceUser();
|
||||
instanceUser.setInstanceId(instanceId);
|
||||
instanceUser.setUserId(sys_user.getId());
|
||||
instanceUser.setUserName(sys_user.getUsername());
|
||||
instanceUser.setUserLoginCode(sys_user.getLoginname());
|
||||
instanceUser.setCreateTime(DateUtil.date());
|
||||
instanceUser.setStatus(statusEnum.getCode());
|
||||
instanceUsers.add(instanceUser);
|
||||
}
|
||||
this.insert(instanceUsers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatus(String id, OaStatusEnum oaStatusEnum, String statusReason) {
|
||||
Sql sql = Sqls.create("update oa_instance_user set status=@status, over_time=@over_time, status_reason=@status_reason where id=@id");
|
||||
sql.params().set("status", oaStatusEnum.getCode());
|
||||
sql.params().set("over_time", DateUtil.date());
|
||||
sql.params().set("status_reason", statusReason);
|
||||
sql.params().set("id", id);
|
||||
this.dao().execute(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatusByInstanceId(String instanceId, OaStatusEnum oaStatusEnum) {
|
||||
Sql sql = Sqls.create("update oa_instance_user set status=@status where instance_id=@instance_id");
|
||||
sql.params().set("status", oaStatusEnum.getCode());
|
||||
sql.params().set("instance_id", instanceId);
|
||||
this.dao().execute(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendAuditUser(String instanceId, String businessTaskId, List<String> auditUsers) {
|
||||
try {
|
||||
List<NutMap> instanceUsers = this.getInstanceUser(instanceId);
|
||||
List<String> userIds = instanceUsers.stream().map(item -> {
|
||||
return item.getString("user_id");
|
||||
}).collect(Collectors.toList());
|
||||
List<String> addUser = auditUsers.stream().filter(item -> !userIds.contains(item)).collect(Collectors.toList());
|
||||
|
||||
this.createRecord(instanceId, addUser, OaStatusEnum.AUDITING);
|
||||
|
||||
Sql userSql = Sqls.create("select * from sys_user where id in (@userIds)");
|
||||
userSql.params().set("userIds", addUser);
|
||||
userSql.setCallback(Sqls.callback.maps());
|
||||
sysUserService.dao().execute(userSql);
|
||||
List<NutMap> addSysUsers = userSql.getList(NutMap.class);
|
||||
List<String> loginNames = addSysUsers.stream().map(item -> item.getString("loginname")).collect(Collectors.toList());
|
||||
HhuEduOaService.getInstance().addPartipantsTask(businessTaskId, loginNames);
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.v.nutz.oa.util;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BillNoUtil {
|
||||
|
||||
public static String getBusinessTaskId() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append(DateUtil.format(DateUtil.date(), "yyyyMMdd"));
|
||||
str.append("-");
|
||||
str.append(DateUtil.format(DateUtil.date(), "HHmmss"));
|
||||
Random random = new Random();
|
||||
// 生成一个10以内的随机数(包含0,但不包含10)
|
||||
int randomNumber = random.nextInt(10);
|
||||
str.append("-" + randomNumber);
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.v.nutz.oa.util;
|
||||
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public class MyHttpDelete extends HttpEntityEnclosingRequestBase {
|
||||
public static final String METHOD_NAME = "DELETE";
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
public MyHttpDelete(final String uri) {
|
||||
super();
|
||||
setURI(URI.create(uri));
|
||||
}
|
||||
public MyHttpDelete(final URI uri) {
|
||||
super();
|
||||
setURI(uri);
|
||||
}
|
||||
public MyHttpDelete() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package io.v.nutz.oa.util;
|
||||
|
||||
/**
|
||||
* 字符串工具类
|
||||
*/
|
||||
public class StringUtil {
|
||||
public static boolean isEmpty(String string) {
|
||||
return string == null || string.length() == 0 || string.trim().equals("");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package io.v.nutz.oa.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 对外开放签名算法工具类
|
||||
* @author xhmeng
|
||||
*/
|
||||
public class SudySignUtil {
|
||||
/**
|
||||
* 签名算法类型sha1
|
||||
*/
|
||||
public static final String ALGORITHM_SHA1 = "SHA1";
|
||||
/**
|
||||
* 签名算法类型sha-256
|
||||
*/
|
||||
public static final String ALGORITHM_SHA256 = "SHA-256";
|
||||
/**
|
||||
* 签名算法类型MD5
|
||||
*/
|
||||
public static final String ALGORITHM_MD5 = "MD5";
|
||||
/**
|
||||
* 签名算法类型HMAC-SHA256
|
||||
*/
|
||||
public static final String ALGORITHM_HMACSHA256= "HMAC-SHA256";
|
||||
|
||||
/**
|
||||
* 支持的签名算法
|
||||
*/
|
||||
private static final List<String> allowedAlgorithms = new ArrayList<>();
|
||||
|
||||
static {
|
||||
allowedAlgorithms.add(ALGORITHM_SHA1);
|
||||
allowedAlgorithms.add(ALGORITHM_SHA256);
|
||||
allowedAlgorithms.add(ALGORITHM_MD5);
|
||||
allowedAlgorithms.add(ALGORITHM_HMACSHA256);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
* @param algorithm 签名算法。SHA1,MD5,SHA-256,HMAC-SHA256
|
||||
* @param appId 应用标识,此标识是提前分配给调用系统的
|
||||
* @param timestamp 时间戳。长整数,是UNIX时间的毫秒数,即产生签名时的时间距1970年1月1日零时的毫秒数的十进制字符串。
|
||||
* 此时间戳代表了签名的时效性,如果此时间与当前时间差大于某个值(建议不超过20分钟)时,系统认为此签名已经失效
|
||||
* @param nonce 随机数。用于参与签名运算
|
||||
* @param summary 摘要,业务接口增加字段的hash值。参与签名,进一步签名的参数值如extraText=“loginName=0810035&userId=2”,
|
||||
* 需要hash后传输,业务系统在校验sign的基础上进一步校验此值。hex(hash(extraText))后的内容,
|
||||
* 其中hash算法根据摘要版本使用对应的算法(如sha1、md5、sha-256等)。
|
||||
* @param secretKey 平台分配给业务系统的私钥
|
||||
* @return
|
||||
*/
|
||||
public static String buildSign(String algorithm,String appId,String timestamp,String nonce,String summary,String secretKey) {
|
||||
if(StringUtil.isEmpty(algorithm) || StringUtil.isEmpty(appId)
|
||||
||StringUtil.isEmpty(timestamp)
|
||||
||StringUtil.isEmpty(nonce)) {
|
||||
throw new RuntimeException("Sign parameters not allow null!");
|
||||
}
|
||||
if(!allowedAlgorithms.contains(algorithm)) {
|
||||
throw new RuntimeException("UnSupport algorithm type!");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("sd-algorithm=").append(algorithm);
|
||||
sb.append("&sd-appid=").append(appId);
|
||||
sb.append("&sd-nonce=").append(nonce);
|
||||
if(!StringUtil.isEmpty(summary)) {
|
||||
sb.append("&sd-summary=").append(summary);
|
||||
}
|
||||
sb.append("&sd-timestamp=").append(timestamp);
|
||||
sb.append("&key=").append(secretKey);
|
||||
String stringSignTemp = sb.toString();
|
||||
System.out.println("stringSignTemp:" + stringSignTemp);
|
||||
System.out.println(stringSignTemp);
|
||||
//sign
|
||||
if(algorithm.equals(ALGORITHM_HMACSHA256)) {
|
||||
try {
|
||||
return hmac(secretKey,stringSignTemp,"HmacSHA256");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return sha(stringSignTemp,algorithm);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查签名是否合法
|
||||
* @param algorithm 签名算法。SHA1,MD5,SHA-256,HMAC-SHA256
|
||||
* @param appId 应用标识,此标识是提前分配给调用系统的
|
||||
* @param timestamp 时间戳。长整数,是UNIX时间的毫秒数,即产生签名时的时间距1970年1月1日零时的毫秒数的十进制字符串。
|
||||
* 此时间戳代表了签名的时效性,如果此时间与当前时间差大于某个值(建议不超过20分钟)时,系统认为此签名已经失效
|
||||
* @param nonce 随机数。用于参与签名运算
|
||||
* @param summary 摘要,业务接口增加字段的hash值。参与签名,进一步签名的参数值如extraText=“loginName=0810035&userId=2”,
|
||||
* 需要hash后传输,业务系统在校验sign的基础上进一步校验此值。hex(hash(extraText))后的内容,
|
||||
* 其中hash算法根据摘要版本使用对应的算法(如sha1、md5、sha-256等)。
|
||||
* @param secretKey 平台分配给业务系统的私钥
|
||||
* @param sign 需要校验的签名
|
||||
* @param signInvalidTime 签名有效期 单位分钟
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkSign(String algorithm,String appId,String timestamp,String nonce,String summary,String secretKey,String sign,long signInvalidTime) {
|
||||
//检查签名时间是否过期
|
||||
long now = System.currentTimeMillis();
|
||||
long timesta = Long.parseLong(timestamp);
|
||||
if((now-timesta)>signInvalidTime*60*1000) {//签名有效时间 默认20分钟
|
||||
throw new RuntimeException( "签名已失效!");
|
||||
}
|
||||
String buildSign = buildSign(algorithm, appId, timestamp, nonce, summary, secretKey);
|
||||
if(!StringUtil.isEmpty(buildSign) && !StringUtil.isEmpty(sign) && buildSign.equals(sign)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 签名摘要
|
||||
* @param algorithm hash算法 SHA1,MD5,SHA-256
|
||||
* @param summaryText 摘要内容
|
||||
* @return
|
||||
*/
|
||||
public static String buildSummary(String algorithm,String summaryText) {
|
||||
try {
|
||||
return sha(summaryText,algorithm);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查摘要签名
|
||||
* @param algorithm
|
||||
* @param summaryText
|
||||
* @param summarySign
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkSummary(String algorithm,String summaryText,String summarySign) {
|
||||
String sign = buildSummary(algorithm, summaryText);
|
||||
if(!StringUtil.isEmpty(sign) && !StringUtil.isEmpty(summarySign) && summarySign.equals(sign)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sha
|
||||
* @param text
|
||||
* @param signType
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static String sha(String text, String signType) throws Exception{
|
||||
MessageDigest sha = MessageDigest.getInstance(signType);
|
||||
byte[] digest = sha.digest(text.getBytes("UTF-8"));
|
||||
return Hex.encodeHexString(digest).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac
|
||||
* @param accessSecret
|
||||
* @param stringToSign
|
||||
* @param singType
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static String hmac(String accessSecret,String stringToSign,String singType) throws Exception{
|
||||
javax.crypto.Mac mac = javax.crypto.Mac.getInstance(singType);
|
||||
mac.init(new javax.crypto.spec.SecretKeySpec(accessSecret.getBytes("UTF-8"), singType));
|
||||
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
|
||||
return Hex.encodeHexString(signData).toUpperCase();
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// String appId = "xgxt";
|
||||
// String algorithm= "SHA1";
|
||||
// String timestamp= System.currentTimeMillis() +"";
|
||||
// String nonce= "ibuaiVcKdpRxkhJA";
|
||||
// String summary= "loginName=zhangsan";
|
||||
// String buildSummary = buildSummary(ALGORITHM_SHA1, summary);
|
||||
// String key = "49123c3d-0d98-4ef5-8128-bdc5f98b3fbd";
|
||||
// String sign = buildSign(algorithm,appId,timestamp,nonce,buildSummary,key);
|
||||
// System.out.println(checkSign(algorithm,appId,timestamp,nonce,buildSummary,key,sign,20));
|
||||
// }
|
||||
|
||||
public static String buildSignature(String securyKey, String timestamp, String openId, String nonce) throws Exception {
|
||||
List<String> sParamList = new ArrayList<String>();
|
||||
sParamList.add(securyKey);
|
||||
sParamList.add(timestamp);
|
||||
sParamList.add(nonce);
|
||||
sParamList.add(openId);
|
||||
Collections.sort(sParamList, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
});
|
||||
StringBuilder signature = new StringBuilder();
|
||||
for (String sParam : sParamList) {
|
||||
signature.append(sParam);
|
||||
}
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||
md.update(signature.toString().getBytes(Charset.forName("UTF-8")));
|
||||
return Hex.encodeHexString(md.digest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package io.v.nutz.oa.util;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 工具类
|
||||
*/
|
||||
public class Util {
|
||||
/**
|
||||
* 解析签名人员
|
||||
* @param appCode
|
||||
* @param secret
|
||||
* @param timestamp
|
||||
* @param nonce
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String buildSignuate(String appCode, String secret, String timestamp, String nonce) throws Exception{
|
||||
if (appCode == null) {
|
||||
throw new Exception( "appCode!");
|
||||
}
|
||||
if (timestamp==null) {
|
||||
throw new Exception( "timestamp解析为空!");
|
||||
}
|
||||
if (nonce == null) {
|
||||
throw new Exception( "nonce解析为空!");
|
||||
}
|
||||
if (secret == null) {
|
||||
throw new Exception( "私钥错误!");
|
||||
}
|
||||
return buildSignature(secret, timestamp, appCode, nonce);
|
||||
}
|
||||
|
||||
|
||||
public static String buildSignature(String securyKey, String timestamp, String openId, String nonce) throws Exception {
|
||||
List<String> sParamList = new ArrayList<String>();
|
||||
sParamList.add(securyKey);
|
||||
sParamList.add(timestamp);
|
||||
sParamList.add(nonce);
|
||||
sParamList.add(openId);
|
||||
Collections.sort(sParamList, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
});
|
||||
StringBuilder signature = new StringBuilder();
|
||||
for (String sParam : sParamList) {
|
||||
signature.append(sParam);
|
||||
}
|
||||
System.out.println("signature:"+signature);
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||
md.update(signature.toString().getBytes());
|
||||
byte[] bytes = md.digest();
|
||||
// System.out.println(toHex(bytes));
|
||||
// System.out.println(bytesToHexStr(bytes));
|
||||
return toHex(bytes);
|
||||
}
|
||||
|
||||
private static String toHex(byte[] buffer) {
|
||||
StringBuilder sb = new StringBuilder(buffer.length * 2);
|
||||
for (int i = 0; i < buffer.length; i++) {
|
||||
sb.append(Character.forDigit((buffer[i] & 240) >> 4, 16));
|
||||
sb.append(Character.forDigit(buffer[i] & 15, 16));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String bytesToHexStr(byte[] bytes){
|
||||
if(bytes == null){
|
||||
return null;
|
||||
}
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuffer sb2 = new StringBuffer();
|
||||
String strInt = "";
|
||||
for(int i=0;i<bytes.length;i++){
|
||||
sb2.append(bytes[i]);
|
||||
strInt = Integer.toHexString(bytes[i]&0xFF);
|
||||
if(strInt.length()<2){
|
||||
sb.append(0);
|
||||
}
|
||||
sb.append(strInt.toLowerCase());
|
||||
}
|
||||
System.out.println(sb2);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.v.nutz.oa.vo;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
public class CreaterVO {
|
||||
private int id;
|
||||
private String name;
|
||||
private String loginName;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLoginName() {
|
||||
return loginName;
|
||||
}
|
||||
|
||||
public void setLoginName(String loginName) {
|
||||
this.loginName = loginName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.v.nutz.oa.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 完成任务
|
||||
*/
|
||||
public class FinishTaskVO {
|
||||
/**
|
||||
* 完成时间。如果不传递此参数,将使用系统当前时间作为其完成时间
|
||||
*/
|
||||
private Date doneDate;
|
||||
|
||||
public Date getDoneDate() {
|
||||
return doneDate;
|
||||
}
|
||||
|
||||
public void setDoneDate(Date doneDate) {
|
||||
this.doneDate = doneDate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package io.v.nutz.oa.vo;
|
||||
|
||||
|
||||
/**
|
||||
* 任务的参与者,即责任人.此类为基类,其之类有:用户参与者(即人员),机构参与者(即org),组参与者(即全局组)
|
||||
*/
|
||||
public class ParticipantVO{
|
||||
/** */
|
||||
public static final int TYPE_USER = 0;
|
||||
/** */
|
||||
public static final int TYPE_ORG = 1;
|
||||
/** */
|
||||
public static final int TYPE_GROUP = 2;
|
||||
|
||||
|
||||
/** */
|
||||
private int id;
|
||||
/**组参与者。type=TYPE_GROUP时有效 */
|
||||
private String groupName;
|
||||
/**type=TYPE_ORG时,机构是否递归 */
|
||||
private boolean recursiveOrg;
|
||||
/**参与者类型,有TYPE_USER(0),TYPE_ORG(1),TYPE_GROUP(2) */
|
||||
private int type;
|
||||
/**人员参与者。type=TYPE_USER时有效。此值必须是校方数据中心公布的唯一人员id,通常是学工号。 */
|
||||
private String userCode;
|
||||
/**机构参与者。type=TYPE_ORG有效 。此值必须是校方数据中心公布的唯一组织机构代码。*/
|
||||
private String orgCode;
|
||||
|
||||
/**委托者类型,有DELEGATETYPE_COMMON,DELEGATETYPE_FROM,DELEGATETYPE_TO */
|
||||
private boolean delegate;
|
||||
/**委托描述。委托者类型非common时生效 */
|
||||
private String delegateLoginName;
|
||||
|
||||
private String delegateName;
|
||||
|
||||
/**是否监督人*/
|
||||
private boolean monitor;
|
||||
|
||||
|
||||
public boolean isDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
public void setDelegate(boolean delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public String getDelegateLoginName() {
|
||||
return delegateLoginName;
|
||||
}
|
||||
|
||||
public void setDelegateLoginName(String delegateLoginName) {
|
||||
this.delegateLoginName = delegateLoginName;
|
||||
}
|
||||
|
||||
public String getDelegateName() {
|
||||
return delegateName;
|
||||
}
|
||||
|
||||
public void setDelegateName(String delegateName) {
|
||||
this.delegateName = delegateName;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
public void setGroupName(String groupName) {
|
||||
this.groupName = groupName;
|
||||
}
|
||||
public boolean isRecursiveOrg() {
|
||||
return recursiveOrg;
|
||||
}
|
||||
public void setRecursiveOrg(boolean recursiveOrg) {
|
||||
this.recursiveOrg = recursiveOrg;
|
||||
}
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
public String getUserCode() {
|
||||
return userCode;
|
||||
}
|
||||
public void setUserCode(String userCode) {
|
||||
this.userCode = userCode;
|
||||
}
|
||||
public String getOrgCode() {
|
||||
return orgCode;
|
||||
}
|
||||
public void setOrgCode(String orgCode) {
|
||||
this.orgCode = orgCode;
|
||||
}
|
||||
|
||||
public boolean isMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
|
||||
public void setMonitor(boolean monitor) {
|
||||
this.monitor = monitor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.v.nutz.oa.vo;
|
||||
|
||||
/**
|
||||
* 创建并完成对象
|
||||
*/
|
||||
public class TaskAndDoneAO {
|
||||
/**
|
||||
* 任务对象
|
||||
*/
|
||||
private TaskVO taskVO;
|
||||
/**
|
||||
* 完成对象
|
||||
*/
|
||||
private UserDoneAO userDoneAO;
|
||||
|
||||
public TaskVO getTaskVO() {
|
||||
return taskVO;
|
||||
}
|
||||
|
||||
public void setTaskVO(TaskVO taskVO) {
|
||||
this.taskVO = taskVO;
|
||||
}
|
||||
|
||||
public UserDoneAO getUserDoneAO() {
|
||||
return userDoneAO;
|
||||
}
|
||||
|
||||
public void setUserDoneAO(UserDoneAO userDoneAO) {
|
||||
this.userDoneAO = userDoneAO;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
package io.v.nutz.oa.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 任务
|
||||
*/
|
||||
public class TaskVO {
|
||||
|
||||
/**任务紧急度:低 */
|
||||
public static final int URGENT_LOW = 0;
|
||||
/**任务紧急度:中 */
|
||||
public static final int URGENT_MIDDLE = 1;
|
||||
/**任务紧急度:高 */
|
||||
public static final int URGENT_HIGH = 2;
|
||||
/**任务紧急度:紧急 */
|
||||
public static final int URGENT_HIGHEST = 3;
|
||||
/**任务重要程度:低 */
|
||||
public static final int IMPORTANCE_LOW = 0;
|
||||
/**任务重要程度:中 */
|
||||
public static final int IMPORTANCE_MIDDLE = 1;
|
||||
/**任务重要程度:高 */
|
||||
public static final int IMPORTANCE_HIGH = 2;
|
||||
/**任务重要程度:及其重要 */
|
||||
public static final int IMPORTANCE_HIGHEST = 3;
|
||||
/**任务状态:未完成 */
|
||||
public static final int STATE_UNDO = 0;
|
||||
/**任务状态:已完成 */
|
||||
public static final int STATE_DONE = 1;
|
||||
/**任务状态:取消 */
|
||||
public static final int STATE_CANCELED = -1;
|
||||
|
||||
|
||||
/** */
|
||||
private int id;
|
||||
/**附件属性1 */
|
||||
private String tag1;
|
||||
/**任务的业务id。此id有app给出,app需要自己保证其唯一性。用于app对任务进行操作 */
|
||||
private String taskBizId;
|
||||
/**任务被撤销时的时间 */
|
||||
private Date cancelDate;
|
||||
/**重要程度,参见常量IMPORTANCE_LOW,IMPORTANCE_MIDDLE,IMPORTANCE_HIGH,IMPORTANCE_HIGHEST */
|
||||
private int importance;
|
||||
/**权重。此为自动计算字段。其值为urgent+importance */
|
||||
private int weight;
|
||||
/**任务标题 */
|
||||
private String title;
|
||||
/**要求完成时间 */
|
||||
private Date deadLine;
|
||||
/**任务的处理url */
|
||||
private String url;
|
||||
/**附件属性2 */
|
||||
private String tag2;
|
||||
/**附件属性3 */
|
||||
private String tag3;
|
||||
/**任务副标题 */
|
||||
private String subTitle;
|
||||
/**任务创建时间。app创建task时,如果没有指定createTime,系统将采用当前时间作为createTime */
|
||||
private Date createTime;
|
||||
/**任务完成时间 */
|
||||
private Date doneTime;
|
||||
/**任务状态.参见常量STATE_UNDO,STATE_DONE,STATE_CANCELED */
|
||||
private int state;
|
||||
/**任务紧急程度。参见常量 URGENT_LOW,URGENT_MIDDLE,URGENT_HIGH, URGENT_HIGHEST */
|
||||
private int urgent;
|
||||
/**任务来源*/
|
||||
private String source;
|
||||
/**
|
||||
* 任务创建者的代码,由校方数据中心给出,通常为职工号
|
||||
*/
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private CreaterVO creater;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
private String createName;
|
||||
|
||||
/**任务的已办url */
|
||||
private String doneUrl;
|
||||
|
||||
/**
|
||||
* 父任务taskBizId,父任务和子任务属于同一个app
|
||||
*/
|
||||
|
||||
private String parentTaskBizId;
|
||||
|
||||
/**
|
||||
* parentTask父任务
|
||||
*/
|
||||
|
||||
private TaskVO parentTask;
|
||||
|
||||
/**是否是流程跟踪任务 之前版本使用tag1=proc存储 */
|
||||
private boolean processTrace;
|
||||
/**是否传阅任务 */
|
||||
private boolean circulation;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private int sort = 50;
|
||||
|
||||
/**
|
||||
* 是否不显示 默认false显示
|
||||
*/
|
||||
private boolean notShow = false;
|
||||
|
||||
|
||||
/**
|
||||
* 流程跟踪我的申请任务当前节点名称
|
||||
*/
|
||||
|
||||
private String processCurrentTask;
|
||||
|
||||
/**
|
||||
* 计划开始时间
|
||||
*/
|
||||
private Date planStartTime;
|
||||
|
||||
private String handler;
|
||||
|
||||
private boolean monitor;
|
||||
private boolean notDeadSearch;
|
||||
private String processNodeName;
|
||||
private String processNodeId;
|
||||
private boolean backTask;
|
||||
private boolean backToFirstAct;
|
||||
private String applyLoginName;
|
||||
private String applyName;
|
||||
private Date applyDate;
|
||||
private String applyOrgName;
|
||||
public String getParentTaskBizId() {
|
||||
return parentTaskBizId;
|
||||
}
|
||||
|
||||
public int getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public void setSort(int sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
public boolean isNotShow() {
|
||||
return notShow;
|
||||
}
|
||||
|
||||
public void setNotShow(boolean notShow) {
|
||||
this.notShow = notShow;
|
||||
}
|
||||
|
||||
public void setParentTaskBizId(String parentTaskBizId) {
|
||||
this.parentTaskBizId = parentTaskBizId;
|
||||
}
|
||||
|
||||
public String getProcessCurrentTask() {
|
||||
return processCurrentTask;
|
||||
}
|
||||
|
||||
public void setProcessCurrentTask(String processCurrentTask) {
|
||||
this.processCurrentTask = processCurrentTask;
|
||||
}
|
||||
|
||||
public String getProcessNodeId() {
|
||||
return processNodeId;
|
||||
}
|
||||
|
||||
public void setProcessNodeId(String processNodeId) {
|
||||
this.processNodeId = processNodeId;
|
||||
}
|
||||
|
||||
public String getDoneUrl() {
|
||||
return doneUrl;
|
||||
}
|
||||
|
||||
public void setDoneUrl(String doneUrl) {
|
||||
this.doneUrl = doneUrl;
|
||||
}
|
||||
|
||||
public boolean isProcessTrace() {
|
||||
return processTrace;
|
||||
}
|
||||
|
||||
public void setProcessTrace(boolean processTrace) {
|
||||
this.processTrace = processTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参与者
|
||||
*/
|
||||
private ParticipantVO[] participants;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTag1() {
|
||||
return tag1;
|
||||
}
|
||||
|
||||
public void setTag1(String tag1) {
|
||||
this.tag1 = tag1;
|
||||
}
|
||||
|
||||
public String getTaskBizId() {
|
||||
return taskBizId;
|
||||
}
|
||||
|
||||
public void setTaskBizId(String taskBizId) {
|
||||
this.taskBizId = taskBizId;
|
||||
}
|
||||
|
||||
public Date getCancelDate() {
|
||||
return cancelDate;
|
||||
}
|
||||
|
||||
public void setCancelDate(Date cancelDate) {
|
||||
this.cancelDate = cancelDate;
|
||||
}
|
||||
|
||||
public int getImportance() {
|
||||
return importance;
|
||||
}
|
||||
|
||||
public void setImportance(int importance) {
|
||||
this.importance = importance;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(int weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Date getDeadLine() {
|
||||
return deadLine;
|
||||
}
|
||||
|
||||
public void setDeadLine(Date deadLine) {
|
||||
this.deadLine = deadLine;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getTag2() {
|
||||
return tag2;
|
||||
}
|
||||
|
||||
public void setTag2(String tag2) {
|
||||
this.tag2 = tag2;
|
||||
}
|
||||
|
||||
public String getTag3() {
|
||||
return tag3;
|
||||
}
|
||||
|
||||
public void setTag3(String tag3) {
|
||||
this.tag3 = tag3;
|
||||
}
|
||||
|
||||
public String getSubTitle() {
|
||||
return subTitle;
|
||||
}
|
||||
|
||||
public void setSubTitle(String subTitle) {
|
||||
this.subTitle = subTitle;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getDoneTime() {
|
||||
return doneTime;
|
||||
}
|
||||
|
||||
public void setDoneTime(Date doneTime) {
|
||||
this.doneTime = doneTime;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(int state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public int getUrgent() {
|
||||
return urgent;
|
||||
}
|
||||
|
||||
public void setUrgent(int urgent) {
|
||||
this.urgent = urgent;
|
||||
}
|
||||
|
||||
public String getCreatorId() {
|
||||
return creatorId;
|
||||
}
|
||||
|
||||
public void setCreatorId(String creatorId) {
|
||||
this.creatorId = creatorId;
|
||||
}
|
||||
|
||||
public CreaterVO getCreater() {
|
||||
return this.creater;
|
||||
}
|
||||
|
||||
public void setCreater(CreaterVO creater) {
|
||||
this.creater = creater;
|
||||
}
|
||||
|
||||
public ParticipantVO[] getParticipants() {
|
||||
return participants;
|
||||
}
|
||||
|
||||
public void setParticipants(ParticipantVO[] participants) {
|
||||
this.participants = participants;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String getCreateName() {
|
||||
return createName;
|
||||
}
|
||||
|
||||
public void setCreateName(String createName) {
|
||||
this.createName = createName;
|
||||
}
|
||||
|
||||
public TaskVO getParentTask() {
|
||||
return parentTask;
|
||||
}
|
||||
|
||||
public void setParentTask(TaskVO parentTask) {
|
||||
this.parentTask = parentTask;
|
||||
}
|
||||
|
||||
public Date getPlanStartTime() {
|
||||
return planStartTime;
|
||||
}
|
||||
|
||||
public void setPlanStartTime(Date planStartTime) {
|
||||
this.planStartTime = planStartTime;
|
||||
}
|
||||
|
||||
public String getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public void setHandler(String handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public boolean isMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
|
||||
public void setMonitor(boolean monitor) {
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
public boolean isNotDeadSearch() {
|
||||
return notDeadSearch;
|
||||
}
|
||||
|
||||
public void setNotDeadSearch(boolean notDeadSearch) {
|
||||
this.notDeadSearch = notDeadSearch;
|
||||
}
|
||||
|
||||
public String getProcessNodeName() {
|
||||
return processNodeName;
|
||||
}
|
||||
|
||||
public void setProcessNodeName(String processNodeName) {
|
||||
this.processNodeName = processNodeName;
|
||||
}
|
||||
|
||||
public boolean isBackTask() {
|
||||
return backTask;
|
||||
}
|
||||
|
||||
public void setBackTask(boolean backTask) {
|
||||
this.backTask = backTask;
|
||||
}
|
||||
|
||||
public boolean isCirculation() {
|
||||
return circulation;
|
||||
}
|
||||
|
||||
public void setCirculation(boolean circulation) {
|
||||
this.circulation = circulation;
|
||||
}
|
||||
|
||||
public boolean isBackToFirstAct() {
|
||||
return backToFirstAct;
|
||||
}
|
||||
|
||||
public void setBackToFirstAct(boolean backToFirstAct) {
|
||||
this.backToFirstAct = backToFirstAct;
|
||||
}
|
||||
|
||||
public String getApplyLoginName() {
|
||||
return applyLoginName;
|
||||
}
|
||||
|
||||
public void setApplyLoginName(String applyLoginName) {
|
||||
this.applyLoginName = applyLoginName;
|
||||
}
|
||||
|
||||
public String getApplyName() {
|
||||
return applyName;
|
||||
}
|
||||
|
||||
public void setApplyName(String applyName) {
|
||||
this.applyName = applyName;
|
||||
}
|
||||
|
||||
public Date getApplyDate() {
|
||||
return applyDate;
|
||||
}
|
||||
|
||||
public void setApplyDate(Date applyDate) {
|
||||
this.applyDate = applyDate;
|
||||
}
|
||||
|
||||
public String getApplyOrgName() {
|
||||
return applyOrgName;
|
||||
}
|
||||
|
||||
public void setApplyOrgName(String applyOrgName) {
|
||||
this.applyOrgName = applyOrgName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package io.v.nutz.oa.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户对象
|
||||
*/
|
||||
public class UserDoneAO {
|
||||
/**
|
||||
* 完成时间。如果不传递此参数,将使用系统当前时间作为其完成时间
|
||||
*/
|
||||
private Date doneDate;
|
||||
/**
|
||||
* 任务中心的保留参数,不需要传递。
|
||||
*/
|
||||
private String extraUserGroup;
|
||||
/**
|
||||
* 是否同时finish整个任务。
|
||||
*/
|
||||
private boolean finishTask;
|
||||
|
||||
/**
|
||||
* 是否委托
|
||||
*/
|
||||
private boolean delegate;
|
||||
/**
|
||||
* 委托人LoginName
|
||||
*/
|
||||
private String delegateLoginName;
|
||||
/**
|
||||
* 委托人Name
|
||||
*/
|
||||
private String delegateName;
|
||||
private String remark;
|
||||
|
||||
public boolean isDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
public void setDelegate(boolean delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public String getDelegateLoginName() {
|
||||
return delegateLoginName;
|
||||
}
|
||||
|
||||
public void setDelegateLoginName(String delegateLoginName) {
|
||||
this.delegateLoginName = delegateLoginName;
|
||||
}
|
||||
|
||||
public String getDelegateName() {
|
||||
return delegateName;
|
||||
}
|
||||
|
||||
public void setDelegateName(String delegateName) {
|
||||
this.delegateName = delegateName;
|
||||
}
|
||||
|
||||
public Date getDoneDate() {
|
||||
return doneDate;
|
||||
}
|
||||
public void setDoneDate(Date doneDate) {
|
||||
this.doneDate = doneDate;
|
||||
}
|
||||
public String getExtraUserGroup() {
|
||||
return extraUserGroup;
|
||||
}
|
||||
public void setExtraUserGroup(String extraUserGroup) {
|
||||
this.extraUserGroup = extraUserGroup;
|
||||
}
|
||||
public boolean isFinishTask() {
|
||||
return finishTask;
|
||||
}
|
||||
public void setFinishTask(boolean finishTask) {
|
||||
this.finishTask = finishTask;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package io.v.nutz.proposal.constants;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.v.nutz.base.utils.DateUtil;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.models.*;
|
||||
import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.proposal.services.ProposalProcessService;
|
||||
@@ -12,10 +15,13 @@ import io.v.nutz.service.impl.ViServiceImpl;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.util.ViResource;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import lombok.Getter;
|
||||
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.json.Json;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.random.R;
|
||||
@@ -23,7 +29,9 @@ import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.trans.Trans;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author: Aaron
|
||||
@@ -69,6 +77,37 @@ public enum ProposalAuditEnum {
|
||||
info.setStateCode(newStateCode);
|
||||
info.setDelegationAuditId(delegationAuditId);
|
||||
proposalInfoService.updateIgnoreNull(info);
|
||||
|
||||
try {
|
||||
// 生成代办
|
||||
if (flag == 1) {
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, info.getCreateUser());
|
||||
String title = "提案委审核-" + info.getProposalName() + "(" + info.getProposalCode() + "[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = createUser.getUsername() + "邀请您提案审核";
|
||||
|
||||
// 参与审核人员
|
||||
Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" +
|
||||
" where sur.roleId in (@roleId)");
|
||||
userSql.params().set("roleId", Arrays.asList(Roles.WYH_ZR, Roles.tmanage));
|
||||
userSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(userSql);
|
||||
List<NutMap> sysUsers = userSql.getList(NutMap.class);
|
||||
if(sysUsers == null || sysUsers.size() <= 0) {
|
||||
return;
|
||||
}
|
||||
List<String> userIds = sysUsers.stream().map(item-> { return item.getString("id"); }).collect(Collectors.toList());
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.PROPOSAL_COMMITTEE_AUDIT,
|
||||
info.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
userIds,
|
||||
Globals.AppDomain + "/platform/proposal/transact/case/case?proposalId=" + info.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/case/case");
|
||||
}
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -481,6 +520,7 @@ public enum ProposalAuditEnum {
|
||||
public ViService<ProposalSeconded> proposalSecondedService = ViResource.ioc.get(ViServiceImpl.class, "ProposalSeconded");
|
||||
public ViService<ProposalFeedback> proposalFeedbackService = ViResource.ioc.get(ViServiceImpl.class, "ProposalFeedback");
|
||||
public Dao dao = ViResource.dao;
|
||||
public IOaAuditInstanceService auditInstanceService = ViResource.ioc.getByType(IOaAuditInstanceService.class);
|
||||
|
||||
public abstract void audit(NutMap nutMap);
|
||||
|
||||
|
||||
@@ -1,26 +1,39 @@
|
||||
package io.v.nutz.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.result.Result;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalInfo;
|
||||
import io.v.nutz.proposal.models.ProposalSearch;
|
||||
import io.v.nutz.proposal.services.ProposalCaseCheckService;
|
||||
import io.v.nutz.proposal.services.ProposalCommonService;
|
||||
import io.v.nutz.sys.models.Sys_signature;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.services.SysUserService;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
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.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.POST;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -44,6 +57,12 @@ public class CaseCheckController {
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/caseCheck.html")
|
||||
@RequiresPermissions("proposal.transact.caseCheck")
|
||||
@@ -56,6 +75,57 @@ public class CaseCheckController {
|
||||
return proposalCaseCheckService.pageData(page, search);
|
||||
}
|
||||
|
||||
@Ok("json")
|
||||
@At("/detail")
|
||||
public Result detail(String proposalId) {
|
||||
String sqlStr = """
|
||||
SELECT
|
||||
info.*,
|
||||
su.username,
|
||||
su.loginname,
|
||||
state.stateName,
|
||||
state.stateColor,
|
||||
type.typeCode,
|
||||
type.typeName,
|
||||
jdh.jdhallname meetingName,
|
||||
dbt.`code` delegationCode,
|
||||
dbt.dbtname delegationName,
|
||||
manner.`name` mannerName,
|
||||
result.`name` resultName,
|
||||
CONCAT('主办(',zbpu.unitName,'),','协办(',IF(ISNULL(xbpu.unitName),'无',xbpu.unitName) ,')') AS underTakeNames,
|
||||
(
|
||||
SELECT
|
||||
count( 1 ) > 0
|
||||
FROM
|
||||
proposal_conjoin
|
||||
where JSON_CONTAINS (proposalIds,JSON_QUOTE(info.id))
|
||||
) AS isConjoin,
|
||||
lalevel.`name` laLevelName
|
||||
FROM
|
||||
proposal_info info
|
||||
LEFT JOIN `user` su ON su.id = info.createUser
|
||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||
LEFT JOIN jdh_dbt dbt ON dbt.id = info.delegationId
|
||||
LEFT JOIN sys_dict manner ON manner.`code` = info.mannerCode
|
||||
LEFT JOIN sys_dict result ON result.`code` = info.resultCode
|
||||
LEFT JOIN sys_dict lalevel ON lalevel.`code` = info.determineTypeCode
|
||||
LEFT JOIN proposal_reply zbpr ON zbpr.proposalId = info.id
|
||||
AND zbpr.undertakeType = 1
|
||||
LEFT JOIN proposal_undertake zbpu ON zbpu.id = zbpr.replyUnitId
|
||||
LEFT JOIN proposal_reply xbpr ON xbpr.proposalId = info.id
|
||||
AND xbpr.undertakeType = 2
|
||||
LEFT JOIN proposal_undertake xbpu ON xbpu.id = xbpr.replyUnitId
|
||||
where info.id=@proposalId
|
||||
""";
|
||||
Sql sql = Sqls.create(sqlStr);
|
||||
sql.params().set("proposalId", proposalId);
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
dao.execute(sql);
|
||||
return Result.success(sql.getObject(NutMap.class));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param audit
|
||||
@@ -83,8 +153,87 @@ public class CaseCheckController {
|
||||
|
||||
proposalCaseCheckService.audit(conjoinIdList, audit, caseCheckNeedSecondReply, caseCheckNeedSecondAudit);
|
||||
|
||||
return null;
|
||||
// 处理提案委确认承办审核待办
|
||||
try {
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIRECTOR_CONFIRM_ORGANIZER_REPLY, io.v.nutz.web.commons.utils.ShiroUtil.getUserId());
|
||||
if (oaInstance != null) {
|
||||
|
||||
auditInstanceService.agree(oaInstance.getId(), io.v.nutz.web.commons.utils.ShiroUtil.getUserId(), "审核通过");
|
||||
}
|
||||
// 是否还有审核信息
|
||||
ProposalSearch search = new ProposalSearch();
|
||||
search.setIsAudit("false");
|
||||
search.setMeetingId("tq19v68n3milip0rhuml8b1euk");
|
||||
PageForm page = new PageForm();
|
||||
page.setSearchName("proposalName");
|
||||
page.setPageNumber(1);
|
||||
page.setPageSize(10);
|
||||
cn.wizzer.framework.base.Result result = (cn.wizzer.framework.base.Result) this.pageData(page, search);
|
||||
Pagination pagination = (Pagination) result.getData();
|
||||
if(pagination == null || pagination.getList() == null || pagination.getList().size() <= 0) {
|
||||
// 处理全部未审核任务
|
||||
List<OaAuditInstance> auditInstances = auditInstanceService.getByBusinessTypeRunning(OaBusinessTypeEnum.DIRECTOR_CONFIRM_ORGANIZER_REPLY);
|
||||
for(OaAuditInstance auditInstance : auditInstances) {
|
||||
auditInstanceService.agree(auditInstance.getId(), "审核通过");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 待办任务处理
|
||||
try{
|
||||
OaAuditInstance instance = auditInstanceService.getByUser(OaBusinessTypeEnum.PROPOSAL_COMMITTEE_AUDIT, audit.getProposalId(), ShiroUtil.getUserId());
|
||||
ProposalInfo proposalInfo = dao.fetch(ProposalInfo.class, audit.getProposalId());
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, proposalInfo.getCreateUser());
|
||||
if(caseCheckNeedSecondReply) {
|
||||
if(instance != null) {
|
||||
auditInstanceService.refuse(instance.getId(), ShiroUtil.getUserId(), "分管校领导驳回");
|
||||
}
|
||||
|
||||
// 生成主办单位待办任务
|
||||
String title = "主办单位提案答复-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() +"[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = "主办单位提案办理答复";
|
||||
// 主办单位校领导
|
||||
Sql hostSql = Sqls.create("select oiu.user_id " +
|
||||
" from oa_instance_user oiu left join oa_audit_instance oai on oai.id = oiu.instance_id" +
|
||||
" where oai.business_type=@business_type and oai.business_id=@business_id " +
|
||||
" order by oai.create_time desc limit 0,1");
|
||||
hostSql.params().set("business_type", OaBusinessTypeEnum.HOST_ORGANIZER_REPLY_HANDLE.getCode());
|
||||
hostSql.params().set("business_id", proposalInfo.getId());
|
||||
hostSql.setCallback(Sqls.callback.map());
|
||||
dao.execute(hostSql);
|
||||
NutMap hostNutMap = hostSql.getObject(NutMap.class);
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.HOST_ORGANIZER_REPLY_HANDLE,
|
||||
proposalInfo.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(hostNutMap.getString("user_id")),
|
||||
Globals.AppDomain + "/platform/proposal/transact/reply?underTakeType=1&proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/reply");
|
||||
} else {
|
||||
if(instance != null) {
|
||||
auditInstanceService.agree(instance.getId(), ShiroUtil.getUserId(), "分管校领导同意", true);
|
||||
}
|
||||
|
||||
if(proposalInfo.getStateCode().equals(Integer.valueOf(700))) {
|
||||
String title = "提案评价-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() + "[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = "提案落实结束评价";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.PROPOSAL_FEEDBACK_EVALUATE_AUDIT,
|
||||
proposalInfo.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
ShiroUtil.getUserId(),
|
||||
Arrays.asList(createUser.getId()),
|
||||
Globals.AppDomain + "/platform/proposal/transact/feedback?proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/feedback");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@At
|
||||
|
||||
@@ -2,17 +2,25 @@ package io.v.nutz.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import com.deepoove.poi.XWPFTemplate;
|
||||
import com.deepoove.poi.config.Configure;
|
||||
import com.deepoove.poi.policy.HackLoopTableRenderPolicy;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalSearch;
|
||||
import io.v.nutz.proposal.services.ProposalAuditService;
|
||||
import io.v.nutz.proposal.services.ProposalCaseService;
|
||||
import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.sys.models.Sys_signature;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
@@ -33,6 +41,8 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author: zzxxyy
|
||||
@@ -58,6 +68,9 @@ public class CaseController {
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/case.html")
|
||||
@RequiresPermissions("proposal.transact.case")
|
||||
@@ -116,6 +129,12 @@ public class CaseController {
|
||||
// return proposalInfoService.listPageMap(page.getPageNumber(), page.getPageSize(), sql);
|
||||
}
|
||||
|
||||
@Ok("json")
|
||||
@At("/detail")
|
||||
public Result detail(String id) {
|
||||
return Result.success(proposalCaseService.detail(id));
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
public void doExport(String proposalId, HttpServletResponse response) throws IOException {
|
||||
@@ -247,7 +266,35 @@ public class CaseController {
|
||||
}
|
||||
audit.setFlag(flag == 1);
|
||||
proposalCaseService.audit(Arrays.asList(proposalIds), resultCode, determineTypeCode, hostUnit, Arrays.asList(helpUnit), typeId, audit, auditType, flag);
|
||||
return null;
|
||||
|
||||
// 代办任务审核
|
||||
try{
|
||||
for(String proposalId: proposalIds) {
|
||||
OaAuditInstance instance = auditInstanceService.getByUser(OaBusinessTypeEnum.PROPOSAL_COMMITTEE_AUDIT, proposalId, ShiroUtil.getUserId());
|
||||
if(instance == null) continue;
|
||||
if(flag == 1) {
|
||||
auditInstanceService.agree(instance.getId(), ShiroUtil.getUserId(), "同意立案", true);
|
||||
} else {
|
||||
auditInstanceService.refuse(instance.getId(), ShiroUtil.getUserId(), "拒绝立案");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 查看
|
||||
ProposalSearch search = new ProposalSearch();
|
||||
search.setIsAudit("false");
|
||||
search.setMeetingId("tq19v68n3milip0rhuml8b1euk");
|
||||
PageForm page = new PageForm();
|
||||
page.setSearchName("proposalName");
|
||||
page.setPageNumber(1);
|
||||
page.setPageSize(10);
|
||||
Pagination pagination = proposalCaseService.pageData(page, search);
|
||||
if(pagination == null || pagination.getList() == null || pagination.getList().size() <= 0) {
|
||||
return Result.success(Map.of("sendTask", true));
|
||||
}
|
||||
return Result.success(Map.of("sendTask", false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,4 +356,45 @@ public class CaseController {
|
||||
return proposalCaseService.backShow(proposalId);
|
||||
}
|
||||
|
||||
@At("/sendToDoTaskInfo")
|
||||
@Ok("json")
|
||||
public Result sendToDoTaskInfo() {
|
||||
try {
|
||||
// 获取审核用户信息 角色
|
||||
Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" +
|
||||
" where sur.roleId in (@roleId)");
|
||||
userSql.params().set("roleId", Arrays.asList(Roles.WYH_ZR));
|
||||
userSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(userSql);
|
||||
List<NutMap> sysUsers = userSql.getList(NutMap.class);
|
||||
if (sysUsers == null || sysUsers.size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> auditUsers = sysUsers.stream().map(item-> { return item.getString("id"); }).collect(Collectors.toList());
|
||||
|
||||
for(String auditUserId : auditUsers) {
|
||||
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_COMMITTEE, auditUserId);
|
||||
if(oaInstance != null) continue;
|
||||
|
||||
// 团长生成待办任务
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, ShiroUtil.getUserId());
|
||||
String title = "提案审核-执委会审核";
|
||||
String subTitle = createUser.getUsername() + "邀请您提案审核";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_COMMITTEE,
|
||||
createUser.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(auditUserId),
|
||||
Globals.AppDomain + "/platform/proposal/transact/executorRead",
|
||||
Globals.AppDomain + "/platform/proposal/transact/executorRead");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
return Result.success("已为你发送待办到下一审批节点");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,34 @@ package io.v.nutz.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalInfo;
|
||||
import io.v.nutz.proposal.models.ProposalReply;
|
||||
import io.v.nutz.proposal.models.ProposalSearch;
|
||||
import io.v.nutz.proposal.services.ProposalCaseConfirmService;
|
||||
import io.v.nutz.proposal.services.ProposalCommonService;
|
||||
import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.sys.models.Sys_signature;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.models.Sys_user_role;
|
||||
import io.v.nutz.sys.services.SysUserService;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.FieldFilter;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.entity.Record;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.Daos;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
@@ -29,6 +41,7 @@ import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author: Aaron
|
||||
@@ -54,6 +67,12 @@ public class CaseUnitController {
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/caseUnit.html")
|
||||
@RequiresPermissions("proposal.transact.caseUnit")
|
||||
@@ -86,9 +105,93 @@ public class CaseUnitController {
|
||||
audit.setSignId(signId);
|
||||
}
|
||||
proposalCaseConfirmService.audit(Arrays.asList(proposalIds), resultCode, determineTypeCode, hostUnit, Arrays.asList(helpUnit), typeId, audit);
|
||||
|
||||
// 处理提案委确认承办审核待办
|
||||
try {
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIRECTOR_CONFIRM_ORGANIZER_REPLY, ShiroUtil.getUserId());
|
||||
if (oaInstance != null) {
|
||||
|
||||
auditInstanceService.agree(oaInstance.getId(), ShiroUtil.getUserId(), "审核通过");
|
||||
}
|
||||
// 是否还有审核信息
|
||||
ProposalSearch search = new ProposalSearch();
|
||||
search.setIsAudit("false");
|
||||
search.setMeetingId("tq19v68n3milip0rhuml8b1euk");
|
||||
PageForm page = new PageForm();
|
||||
page.setSearchName("proposalName");
|
||||
page.setPageNumber(1);
|
||||
page.setPageSize(10);
|
||||
Result result = (Result) this.pageData(page, search);
|
||||
Pagination pagination = (Pagination) result.getData();
|
||||
if(pagination == null || pagination.getList() == null || pagination.getList().size() <= 0) {
|
||||
// 处理全部未审核任务
|
||||
List<OaAuditInstance> auditInstances = auditInstanceService.getByBusinessTypeRunning(OaBusinessTypeEnum.DIRECTOR_CONFIRM_ORGANIZER_REPLY);
|
||||
for(OaAuditInstance auditInstance : auditInstances) {
|
||||
auditInstanceService.agree(auditInstance.getId(), "审核通过");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 生成待办任务
|
||||
try{
|
||||
for(String proposalId : Arrays.asList(proposalIds)) {
|
||||
ProposalInfo proposalInfo = proposalInfoService.fetch(proposalId);
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, proposalInfo.getCreateUser());
|
||||
|
||||
// 主办单位校领导
|
||||
List<Record> hostRecords = this.findAdmin(Arrays.asList(hostUnit));
|
||||
if (hostRecords != null && hostRecords.size() > 0) {
|
||||
List<String> hostUserIds = hostRecords.stream().map(item-> {return item.getString("id"); }).collect(Collectors.toList());
|
||||
String title = "主办单位提案答复-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() +"[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = "主办单位提案办理答复";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.HOST_ORGANIZER_REPLY_HANDLE,
|
||||
proposalId,
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
hostUserIds,
|
||||
Globals.AppDomain + "/platform/proposal/transact/reply?underTakeType=1&proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/reply");
|
||||
}
|
||||
|
||||
// 协办单位校领导
|
||||
List<Record> helpRecords = this.findAdmin(Arrays.asList(helpUnit));
|
||||
if (helpRecords != null && helpRecords.size() > 0) {
|
||||
List<String> helpUserIds = helpRecords.stream().map(item-> {return item.getString("id"); }).collect(Collectors.toList());
|
||||
String title = "协办单位提案答复-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() +"[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = "协办单位提案办理答复";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.HELP_ORGANIZER_REPLY_HANDLE,
|
||||
proposalId,
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
helpUserIds,
|
||||
Globals.AppDomain + "/platform/proposal/transact/reply?underTakeType=0&proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/reply");
|
||||
}
|
||||
}
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询负责人或者分管校领导
|
||||
* @param ids 承办单位id
|
||||
* @return
|
||||
*/
|
||||
private List<Record> findAdmin(List<String> ids) {
|
||||
Sql sql = Sqls.create("select su.* " +
|
||||
"from sys_user su left join sys_user_role sur on sur.userId = su.id" +
|
||||
" where sur.cbdwid in (@cbdwid) and sur.roleId=@roleId");
|
||||
sql.params().set("cbdwid", ids);
|
||||
sql.params().set("roleId", Roles.IN_CHARGE_LEADER);
|
||||
return sysUserService.list(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回
|
||||
*
|
||||
|
||||
@@ -9,6 +9,8 @@ import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.dao.CndPlus;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalMannerEnum;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.constants.ProposalStateDirectionEnum;
|
||||
@@ -24,6 +26,8 @@ import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.services.SysSignatureService;
|
||||
import io.v.nutz.sys.services.SysUserService;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
@@ -46,6 +50,7 @@ import org.nutz.mvc.upload.UploadAdaptor;
|
||||
import org.nutz.trans.Trans;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -55,6 +60,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
* @description: 撰写提案(系统管理员 、 提案管理员 、 正式代表 、 代表团团长 、 提案委员会主任)
|
||||
**/
|
||||
|
||||
@Slf4j
|
||||
@At("/platform/proposal/transact/compose")
|
||||
@Ok("json:full")
|
||||
@IocBean
|
||||
@@ -88,6 +94,9 @@ public class ComposeController {
|
||||
@Inject
|
||||
private MsgApi msgApi;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/compose.html")
|
||||
@RequiresPermissions("proposal.transact.compose")
|
||||
@@ -241,6 +250,23 @@ public class ComposeController {
|
||||
secondedService.insert(seconded);
|
||||
Sys_user user = dao.fetch(Sys_user.class, userId);
|
||||
msgApi.sendMsg(StrUtil.format(inviteSecondedTemplate, proposalCreateUser.getUsername(), proposalInfo.getProposalName()), List.of(user.getLoginname()));
|
||||
|
||||
// 生成代办任务
|
||||
try {
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, ShiroUtil.getUserId());
|
||||
String title = "提案附议-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() +"[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = createUser.getUsername() + "邀请您附议";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.WRITE_PROPOSAL,
|
||||
proposalId,
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(userId),
|
||||
Globals.AppDomain + "/platform/proposal/transact/seconded?isAudit=false&proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/statistics/mySearch");
|
||||
} catch (Exception e) {
|
||||
log.error("撰写提案附议生成代办失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+87
-1
@@ -2,9 +2,14 @@ package io.v.nutz.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.dao.CndPlus;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalSearch;
|
||||
@@ -13,9 +18,14 @@ import io.v.nutz.proposal.services.ProposalExecutorReadConfirmService;
|
||||
import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.proposal.services.ProposalProcessService;
|
||||
import io.v.nutz.sys.models.Sys_signature;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
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;
|
||||
@@ -27,6 +37,9 @@ import org.nutz.mvc.annotation.POST;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author zxy
|
||||
@@ -50,6 +63,9 @@ public class ExecutorReadConfirmController {
|
||||
@Inject
|
||||
private ProposalExecutorReadConfirmService proposalExecutorReadConfirmService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@@ -103,7 +119,36 @@ public class ExecutorReadConfirmController {
|
||||
.addv("determineCode", determineTypeCode);
|
||||
audit.setOther(Json.toJson(auditOther));
|
||||
proposalExecutorReadConfirmService.audit(audit, Arrays.asList(proposalIds));
|
||||
return null;
|
||||
// 处理代办任务
|
||||
try {
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_CONFIRM_COMMITTEE, ShiroUtil.getUserId());
|
||||
if (oaInstance != null) {
|
||||
auditInstanceService.agree(oaInstance.getId(), ShiroUtil.getUserId(), "审核通过");
|
||||
}
|
||||
|
||||
// 是否还有审核信息
|
||||
ProposalSearch search = new ProposalSearch();
|
||||
search.setIsAudit("false");
|
||||
search.setMeetingId("tq19v68n3milip0rhuml8b1euk");
|
||||
PageForm page = new PageForm();
|
||||
page.setSearchName("proposalName");
|
||||
page.setPageNumber(1);
|
||||
page.setPageSize(10);
|
||||
Result result = (Result) this.pageData(page, search);
|
||||
Pagination pagination = (Pagination) result.getData();
|
||||
if(pagination == null || pagination.getList() == null || pagination.getList().size() <= 0) {
|
||||
|
||||
// 处理全部未审核任务
|
||||
List<OaAuditInstance> auditInstances = auditInstanceService.getByBusinessTypeRunning(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_CONFIRM_COMMITTEE);
|
||||
for(OaAuditInstance auditInstance : auditInstances) {
|
||||
auditInstanceService.agree(auditInstance.getId(), "审核通过");
|
||||
}
|
||||
return Result.success(Map.of("sendTask", true));
|
||||
}
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return Result.success(Map.of("sendTask", false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,4 +164,45 @@ public class ExecutorReadConfirmController {
|
||||
proposalExecutorReadConfirmService.revoke(proposalId);
|
||||
return Result.success().addMsg("撤回成功!");
|
||||
}
|
||||
|
||||
@At("/sendToDoTaskInfo")
|
||||
@Ok("json")
|
||||
public Result sendToDoTaskInfo() {
|
||||
try {
|
||||
// 获取审核用户信息 角色
|
||||
Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" +
|
||||
" where sur.roleId in (@roleId)");
|
||||
userSql.params().set("roleId", Arrays.asList(Roles.WYH_ZR));
|
||||
userSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(userSql);
|
||||
List<NutMap> sysUsers = userSql.getList(NutMap.class);
|
||||
if (sysUsers == null || sysUsers.size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
List<String> auditUsers = sysUsers.stream().map(item -> {
|
||||
return item.getString("id");
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
for (String auditUserId : auditUsers) {
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIRECTOR_CONFIRM_ORGANIZER_REPLY, auditUserId);
|
||||
if (oaInstance != null) continue;
|
||||
|
||||
// 提案委确认承办单位
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, ShiroUtil.getUserId());
|
||||
String title = "提案审核-提案委确认承办单位";
|
||||
String subTitle = createUser.getUsername() + "邀请您提案审核";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.DIRECTOR_CONFIRM_ORGANIZER_REPLY,
|
||||
createUser.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(auditUserId),
|
||||
Globals.AppDomain + "/platform/proposal/transact/caseUnit",
|
||||
Globals.AppDomain + "/platform/proposal/transact/caseUnit");
|
||||
}
|
||||
}catch (Exception e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
return Result.success("已为你发送待办到下一审批节点");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,14 @@ package io.v.nutz.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.dao.CndPlus;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalSearch;
|
||||
@@ -13,8 +18,13 @@ import io.v.nutz.proposal.services.ProposalExecutorReadService;
|
||||
import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.proposal.services.ProposalProcessService;
|
||||
import io.v.nutz.sys.models.Sys_signature;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
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;
|
||||
@@ -26,6 +36,9 @@ import org.nutz.mvc.annotation.POST;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author zxy
|
||||
@@ -49,6 +62,9 @@ public class ExecutorReadController {
|
||||
@Inject
|
||||
private ProposalExecutorReadService proposalExecutorReadService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@@ -101,7 +117,37 @@ public class ExecutorReadController {
|
||||
.addv("determineCode", determineTypeCode);
|
||||
audit.setOther(Json.toJson(auditOther));
|
||||
proposalExecutorReadService.audit(audit, Arrays.asList(proposalIds));
|
||||
return null;
|
||||
|
||||
// 处理代办任务
|
||||
try{
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_COMMITTEE, ShiroUtil.getUserId());
|
||||
if(oaInstance != null) {
|
||||
auditInstanceService.agree(oaInstance.getId(), ShiroUtil.getUserId(), "审核通过");
|
||||
}
|
||||
|
||||
// 是否还有审核信息
|
||||
ProposalSearch search = new ProposalSearch();
|
||||
search.setIsAudit("false");
|
||||
search.setMeetingId("tq19v68n3milip0rhuml8b1euk");
|
||||
PageForm page = new PageForm();
|
||||
page.setSearchName("proposalName");
|
||||
page.setPageNumber(1);
|
||||
page.setPageSize(10);
|
||||
Result result = (Result) this.pageData(page, search);
|
||||
Pagination pagination = (Pagination) result.getData();
|
||||
if(pagination == null || pagination.getList() == null || pagination.getList().size() <= 0) {
|
||||
|
||||
// 处理全部未审核任务
|
||||
List<OaAuditInstance> auditInstances = auditInstanceService.getByBusinessTypeRunning(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_COMMITTEE);
|
||||
for(OaAuditInstance auditInstance : auditInstances) {
|
||||
auditInstanceService.agree(auditInstance.getId(), "审核通过");
|
||||
}
|
||||
return Result.success(Map.of("sendTask", true));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return Result.success(Map.of("sendTask", false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,4 +163,47 @@ public class ExecutorReadController {
|
||||
proposalExecutorReadService.revoke(proposalId);
|
||||
return Result.success().addMsg("撤回成功!");
|
||||
}
|
||||
|
||||
@At("/sendToDoTaskInfo")
|
||||
@Ok("json")
|
||||
public Result sendToDoTaskInfo() {
|
||||
try {
|
||||
// 获取审核用户信息 角色
|
||||
Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" +
|
||||
" where sur.roleId in (@roleId)");
|
||||
userSql.params().set("roleId", Arrays.asList(Roles.secretary, Roles.principal));
|
||||
userSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(userSql);
|
||||
List<NutMap> sysUsers = userSql.getList(NutMap.class);
|
||||
if (sysUsers == null || sysUsers.size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> auditUsers = sysUsers.stream().map(item -> {
|
||||
return item.getString("id");
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
for (String auditUserId : auditUsers) {
|
||||
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.PRINCIPAL_SECRETARY_AUDIT, auditUserId);
|
||||
if (oaInstance != null) continue;
|
||||
|
||||
// 执委会审核生成待办任务
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, ShiroUtil.getUserId());
|
||||
String title = "提案审核-校长、书记审核";
|
||||
String subTitle = createUser.getUsername() + "邀请您提案审核";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.PRINCIPAL_SECRETARY_AUDIT,
|
||||
createUser.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(auditUserId),
|
||||
Globals.AppDomain + "/platform/proposal/transact/principalRead",
|
||||
Globals.AppDomain + "/platform/proposal/transact/principalRead");
|
||||
}
|
||||
}catch (Exception e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
return Result.success("已为你发送待办到下一审批节点");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,14 @@ import com.deepoove.poi.config.Configure;
|
||||
import com.deepoove.poi.data.PictureRenderData;
|
||||
import com.deepoove.poi.policy.HackLoopTableRenderPolicy;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.result.Result;
|
||||
import io.v.nutz.base.utils.Html2Text;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.dao.CndPlus;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalAuditEnum;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.constants.ProposalStateDirectionEnum;
|
||||
@@ -68,6 +72,9 @@ public class FeedbackScoreController {
|
||||
@Inject("ProposalFeedback")
|
||||
private ViService<ProposalFeedback> proposalFeedbackService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/feedback.html")
|
||||
@RequiresPermissions("proposal.transact.feedback")
|
||||
@@ -138,6 +145,47 @@ public class FeedbackScoreController {
|
||||
|
||||
}
|
||||
|
||||
@Ok("json")
|
||||
@At("/detail")
|
||||
public Result detail(String proposalId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
su.username,
|
||||
su.loginname,
|
||||
state.stateName,
|
||||
state.stateColor,
|
||||
type.typeCode,
|
||||
type.typeName,
|
||||
jdh.jdhallname meetingName,
|
||||
dbt.`code` delegationCode,
|
||||
dbt.dbtname delegationName,
|
||||
manner.`name` mannerName,
|
||||
result.`name` resultName,
|
||||
(
|
||||
SELECT
|
||||
count( 1 ) > 0
|
||||
FROM
|
||||
proposal_conjoin
|
||||
where JSON_CONTAINS (proposalIds,JSON_QUOTE(info.id))
|
||||
) AS isConjoin
|
||||
FROM
|
||||
proposal_info info
|
||||
LEFT JOIN `user` su ON su.id = info.createUser
|
||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||
LEFT JOIN jdh_dbt dbt ON dbt.id = info.delegationId
|
||||
LEFT JOIN sys_dict manner ON manner.`code` = info.mannerCode
|
||||
LEFT JOIN sys_dict result ON result.`code` = info.resultCode
|
||||
where info.id = @proposalId
|
||||
""");
|
||||
sql.params().set("proposalId", proposalId);
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
proposalInfoService.dao().execute(sql);
|
||||
return Result.success(sql.getObject(NutMap.class));
|
||||
}
|
||||
|
||||
@Inject
|
||||
private SysSignatureService sysSignatureService;
|
||||
|
||||
@@ -151,6 +199,15 @@ public class FeedbackScoreController {
|
||||
}
|
||||
nutMap.setv("feedback", feedback);
|
||||
ProposalAuditEnum.FEEDBACK_SCORE.audit(nutMap);
|
||||
|
||||
try {
|
||||
ProposalInfo proposalInfo = proposalInfoService.fetch(feedback.getProposalId());
|
||||
OaAuditInstance instance = auditInstanceService.getByUser(OaBusinessTypeEnum.PROPOSAL_FEEDBACK_EVALUATE_AUDIT, proposalInfo.getId(), ShiroUtil.getUserId());
|
||||
if(instance == null) return null;
|
||||
auditInstanceService.agree(instance.getId(), ShiroUtil.getUserId(), "已反馈", true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,11 @@ import cn.wizzer.framework.base.Result;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.DateUtil;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.constants.ProposalStateDirectionEnum;
|
||||
import io.v.nutz.proposal.models.ProposalInfo;
|
||||
@@ -16,8 +20,10 @@ import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.proposal.services.ProposalLeaderAuditService;
|
||||
import io.v.nutz.proposal.services.ProposalProcessService;
|
||||
import io.v.nutz.sys.models.Sys_signature;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.services.SysSignatureService;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.nutz.dao.Chain;
|
||||
@@ -35,7 +41,9 @@ import org.nutz.mvc.annotation.POST;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
import org.nutz.trans.Trans;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author: Aaron
|
||||
@@ -65,7 +73,8 @@ public class LeaderAuditController {
|
||||
private SysSignatureService sysSignatureService;
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/leaderAudit.html")
|
||||
@@ -86,6 +95,61 @@ public class LeaderAuditController {
|
||||
return proposalLeaderAuditService.pageData(page, cnd, search);
|
||||
}
|
||||
|
||||
@Ok("json")
|
||||
@At("/detail")
|
||||
public Result detail(String proposalId) {
|
||||
String sqlStr = """
|
||||
SELECT
|
||||
info.*,
|
||||
su.username,
|
||||
su.loginname,
|
||||
state.stateName,
|
||||
state.stateColor,
|
||||
type.typeCode,
|
||||
type.typeName,
|
||||
jdh.jdhallname meetingName,
|
||||
dbt.`code` delegationCode,
|
||||
dbt.dbtname delegationName,
|
||||
manner.`name` mannerName,
|
||||
result.`name` resultName,
|
||||
pr.id AS replyId,
|
||||
pr.replyUnitId,
|
||||
pr.replyNumber,
|
||||
pr.leaderCheckNumber,
|
||||
pr.replyPersonId,
|
||||
pr.isReply,
|
||||
pr.leaderId,
|
||||
pr.isLeaderAudit,
|
||||
pu.unitName as underTakeName,
|
||||
(
|
||||
SELECT
|
||||
count( 1 ) > 0
|
||||
FROM
|
||||
proposal_conjoin
|
||||
where JSON_CONTAINS (proposalIds,JSON_QUOTE(info.id))
|
||||
) AS isConjoin,
|
||||
IF(pr.underTakeType=1,'主办','协办') AS undertakeType,
|
||||
(SELECT GROUP_CONCAT(DISTINCT ( u.username )) FROM sys_user_role sur LEFT JOIN sys_user u ON u.id = sur.userid WHERE sur.cbdwid = pr.replyUnitId AND sur.roleid = @XLD ) AS underTakeNameUser
|
||||
FROM
|
||||
proposal_reply pr
|
||||
LEFT JOIN proposal_undertake pu on pu.id = pr.replyUnitId\s
|
||||
LEFT JOIN proposal_info info on info.id = pr.proposalId
|
||||
LEFT JOIN `user` su ON su.id = info.createUser
|
||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||
LEFT JOIN jdh_dbt dbt ON dbt.id = info.delegationId
|
||||
LEFT JOIN sys_dict manner ON manner.`code` = info.mannerCode
|
||||
LEFT JOIN sys_dict result ON result.`code` = info.resultCode
|
||||
where pr.underTakeType=1 AND info.id=@proposalId limit 0,1
|
||||
""";
|
||||
Sql sql = Sqls.create(sqlStr);
|
||||
sql.params().set("proposalId", proposalId);
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
dao.execute(sql);
|
||||
return Result.success(sql.getObject(NutMap.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 退回
|
||||
*
|
||||
@@ -117,6 +181,13 @@ public class LeaderAuditController {
|
||||
});
|
||||
|
||||
});
|
||||
try{
|
||||
OaAuditInstance instance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIVIDE_SCHOOL_LEADERS_AUDIT, proposalId, ShiroUtil.getUserId());
|
||||
if(instance == null) return null;
|
||||
auditInstanceService.refuse(instance.getId(), ShiroUtil.getUserId(), "审核驳回");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -136,6 +207,65 @@ public class LeaderAuditController {
|
||||
reply.setLeaderSignId(sysSignatureService.insert(new Sys_signature(leaderSign)).getId());
|
||||
}
|
||||
proposalLeaderAuditService.audit(reply);
|
||||
try {
|
||||
ProposalInfo proposalInfo = proposalInfoService.fetch(reply.getProposalId());
|
||||
OaAuditInstance instance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIVIDE_SCHOOL_LEADERS_AUDIT, reply.getProposalId(), ShiroUtil.getUserId());
|
||||
if (instance != null) {
|
||||
auditInstanceService.agree(instance.getId(), ShiroUtil.getUserId(), "审核通过", true);
|
||||
}
|
||||
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, proposalInfo.getCreateUser());
|
||||
if(proposalInfo.getCaseCheckAuditId() != null && !proposalInfo.getCaseCheckAuditId().isEmpty()) {
|
||||
// 生成反馈评价待办
|
||||
String flag = nutMap.getString("flag");
|
||||
if (flag.equals("true")) {
|
||||
if(proposalInfo.getStateCode().equals(Integer.valueOf(700))) {
|
||||
String title = "提案评价-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() + "[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = "提案落实结束评价";
|
||||
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.PROPOSAL_FEEDBACK_EVALUATE_AUDIT,
|
||||
proposalInfo.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
ShiroUtil.getUserId(),
|
||||
Arrays.asList(createUser.getId()),
|
||||
Globals.AppDomain + "/platform/proposal/transact/feedback?proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/feedback");
|
||||
}
|
||||
}
|
||||
}
|
||||
if((proposalInfo.getStateCode().equals(Integer.valueOf(800)))) {
|
||||
String flag = nutMap.getString("flag");
|
||||
if (flag.equals("true")) {
|
||||
String title = "提案委复核-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() + "[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = createUser.getUsername() + "提案委复核";
|
||||
|
||||
// 参与审核人员
|
||||
Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" +
|
||||
" where sur.roleId in (@roleId)");
|
||||
userSql.params().set("roleId", Arrays.asList(Roles.WYH_ZR, Roles.tmanage));
|
||||
userSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(userSql);
|
||||
List<NutMap> sysUsers = userSql.getList(NutMap.class);
|
||||
if (sysUsers == null || sysUsers.size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
List<String> userIds = sysUsers.stream().map(item -> {
|
||||
return item.getString("id");
|
||||
}).collect(Collectors.toList());
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.PROPOSAL_COMMITTEE_AUDIT,
|
||||
proposalInfo.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
userIds,
|
||||
Globals.AppDomain + "/platform/proposal/transact/caseCheck?proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/caseCheck");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@ package io.v.nutz.proposal.controller.transact;
|
||||
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.lang.Enum;
|
||||
import io.v.nutz.oa.constants.CommonConstants;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalAuditEnum;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalReply;
|
||||
@@ -36,6 +40,9 @@ public class ProposalAuditController {
|
||||
@Inject
|
||||
private SysSignatureService sysSignatureService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
/**
|
||||
* 审核
|
||||
*
|
||||
@@ -56,6 +63,20 @@ public class ProposalAuditController {
|
||||
int stateCode = proposalInfoService.fetch(audit.getProposalId()).getStateCode();
|
||||
ProposalAuditEnum instance = Enum.instance(ProposalAuditEnum.class, stateCode);
|
||||
instance.audit(nutMap);
|
||||
|
||||
// 处理代办任务
|
||||
try{
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.TUANZHANG_AUDIT_PROPOSAL, audit.getProposalId(), ShiroUtil.getUserId());
|
||||
if(oaInstance == null) return null;
|
||||
Integer flag = nutMap.getInt("flag");
|
||||
if(flag != null && flag.equals(CommonConstants.ONE)) {
|
||||
auditInstanceService.agree(oaInstance.getId(), ShiroUtil.getUserId(), "审核通过");
|
||||
} else {
|
||||
auditInstanceService.refuse(oaInstance.getId(), ShiroUtil.getUserId(), "审核驳回");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,13 +12,19 @@ import io.v.nutz.base.utils.Html2Text;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.base.utils.Vi;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.constants.CommonConstants;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.models.*;
|
||||
import io.v.nutz.proposal.services.ProposalCommonService;
|
||||
import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.proposal.services.ProposalProcessService;
|
||||
import io.v.nutz.proposal.services.ProposalReplyService;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.nutz.dao.Chain;
|
||||
@@ -68,6 +74,8 @@ public class ReplyController {
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/reply.html")
|
||||
@@ -94,6 +102,121 @@ public class ReplyController {
|
||||
|
||||
}
|
||||
|
||||
@Ok("json")
|
||||
@At("/detail")
|
||||
public Result detail(String underTakeType, String proposalId) {
|
||||
String COMMON_SQL = """
|
||||
SELECT
|
||||
info.*,
|
||||
su.username,
|
||||
su.loginname,
|
||||
state.stateName,
|
||||
state.stateColor,
|
||||
type.typeCode,
|
||||
type.typeName,
|
||||
jdh.jdhallname meetingName,
|
||||
dbt.`code` delegationCode,
|
||||
dbt.dbtname delegationName,
|
||||
manner.`name` mannerName,
|
||||
result.`name` resultName,
|
||||
pr.id AS replyId,
|
||||
pr.replyUnitId,
|
||||
pr.replyNumber,
|
||||
pr.replyPersonId,
|
||||
pr.isReply,
|
||||
pr.leaderId,
|
||||
pr.replyContent,
|
||||
pr.underTakeType,
|
||||
pr.implementState,
|
||||
IF(pr.underTakeType=1,'主办','协办') AS undertakeTypeName,
|
||||
pu.unitName as underTakeName,
|
||||
(
|
||||
SELECT
|
||||
count( 1 ) > 0
|
||||
FROM
|
||||
proposal_conjoin
|
||||
where JSON_CONTAINS (proposalIds,JSON_QUOTE(info.id))
|
||||
) AS isConjoin,
|
||||
(count(prf.id) > 0) isForward,
|
||||
GROUP_CONCAT(proxyReplyUser.username) proxyReplyUserName
|
||||
FROM
|
||||
proposal_reply pr
|
||||
INNER JOIN ( SELECT id,proposalId, max( replyNumber ) AS replyNumber FROM proposal_reply WHERE undertakeType in (1,2) AND isReply = 0 group by proposalId ) b ON b.proposalId = pr.proposalId
|
||||
AND b.replyNumber = pr.replyNumber
|
||||
AND b.id = pr.id
|
||||
LEFT JOIN proposal_undertake pu on pu.id = pr.replyUnitId
|
||||
LEFT JOIN proposal_info info on info.id = pr.proposalId
|
||||
LEFT JOIN `user` su ON su.id = info.createUser
|
||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||
LEFT JOIN jdh_dbt dbt ON dbt.id = info.delegationId
|
||||
LEFT JOIN sys_dict manner ON manner.`code` = info.mannerCode
|
||||
LEFT JOIN sys_dict result ON result.`code` = info.resultCode
|
||||
LEFT JOIN proposal_reply_forward prf ON prf.replyId = pr.id
|
||||
LEFT JOIN sys_user proxyReplyUser ON proxyReplyUser.id = prf.proxyReplyUserId
|
||||
WHERE pr.undertakeType='1' and info.id=@proposalId
|
||||
GROUP BY pr.id ORDER BY info.proposalCode ASC, info.createTime DESC, info.stateCode ASC, pr.isReply DESC
|
||||
limit 0,1
|
||||
""";
|
||||
if(!underTakeType.equals(CommonConstants.ONE.toString())) {
|
||||
COMMON_SQL = """
|
||||
SELECT
|
||||
info.*,
|
||||
su.username,
|
||||
su.loginname,
|
||||
state.stateName,
|
||||
state.stateColor,
|
||||
type.typeCode,
|
||||
type.typeName,
|
||||
jdh.jdhallname meetingName,
|
||||
dbt.`code` delegationCode,
|
||||
dbt.dbtname delegationName,
|
||||
manner.`name` mannerName,
|
||||
result.`name` resultName,
|
||||
pr.id AS replyId,
|
||||
pr.replyUnitId,
|
||||
pr.replyNumber,
|
||||
pr.replyPersonId,
|
||||
pr.isReply,
|
||||
pr.leaderId,
|
||||
pr.replyContent,
|
||||
pr.underTakeType,
|
||||
IF(pr.underTakeType=1,'主办','协办') AS undertakeTypeName,
|
||||
pu.unitName as underTakeName,
|
||||
max(pr.replyNumber),
|
||||
(
|
||||
SELECT
|
||||
count( 1 ) > 0
|
||||
FROM
|
||||
proposal_conjoin
|
||||
where JSON_CONTAINS (proposalIds,JSON_QUOTE(info.id))
|
||||
) AS isConjoin,
|
||||
(count(prf.id) > 0) isForward,
|
||||
GROUP_CONCAT(proxyReplyUser.username) proxyReplyUserName
|
||||
FROM
|
||||
proposal_reply pr
|
||||
LEFT JOIN proposal_undertake pu on pu.id = pr.replyUnitId\s
|
||||
LEFT JOIN proposal_info info on info.id = pr.proposalId
|
||||
LEFT JOIN sys_user su ON su.id = info.createUser
|
||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||
LEFT JOIN jdh_dbt dbt ON dbt.id = info.delegationId
|
||||
LEFT JOIN sys_dict manner ON manner.`code` = info.mannerCode
|
||||
LEFT JOIN sys_dict result ON result.`code` = info.resultCode
|
||||
LEFT JOIN proposal_reply_forward prf ON prf.replyId = pr.id
|
||||
LEFT JOIN sys_user proxyReplyUser ON proxyReplyUser.id = prf.proxyReplyUserId
|
||||
WHERE pr.undertakeType!=1 and info.id=@proposalId
|
||||
""";
|
||||
}
|
||||
Sql sql = Sqls.create(COMMON_SQL);
|
||||
sql.params().set("proposalId", proposalId);
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
dao.execute(sql);
|
||||
return Result.success(sql.getObject(NutMap.class));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检验是否可以答复
|
||||
@@ -118,8 +241,45 @@ public class ReplyController {
|
||||
@At
|
||||
@ViReturn
|
||||
public Object audit(ProposalReply reply, String replySign, Boolean isSave) {
|
||||
proposalReplyService.audit(reply, replySign, isSave);
|
||||
proposalReplyService.audit(reply, replySign, isSave);
|
||||
// ProposalAuditEnum.UNDERTAKE_REPLY.audit(nutMap);
|
||||
|
||||
// 待办任务处理
|
||||
try {
|
||||
ProposalReply proposalReply = proposalReplyService.fetch(reply.getId());
|
||||
OaAuditInstance instance = null;
|
||||
if(proposalReply.getUndertakeType().equals(CommonConstants.ONE)) {
|
||||
instance = auditInstanceService.getByUser(OaBusinessTypeEnum.HOST_ORGANIZER_REPLY_HANDLE, reply.getProposalId(), ShiroUtil.getUserId());
|
||||
} else {
|
||||
instance = auditInstanceService.getByUser(OaBusinessTypeEnum.HELP_ORGANIZER_REPLY_HANDLE, reply.getProposalId(), ShiroUtil.getUserId());
|
||||
}
|
||||
if(instance != null) {
|
||||
auditInstanceService.agree(instance.getId(), ShiroUtil.getUserId(), "承办答复", true);
|
||||
}
|
||||
// 生成校领导审批代办
|
||||
if(proposalReply.getUndertakeType().equals(CommonConstants.ONE)) {
|
||||
ProposalInfo proposalInfo = proposalInfoService.fetch(proposalReply.getProposalId());
|
||||
if(proposalInfo.getCaseCheckNeedSecondAudit() != null && !proposalInfo.getCaseCheckNeedSecondAudit()) {
|
||||
List<OaAuditInstance> oaAuditInstances = auditInstanceService.getAllByBusinessType(OaBusinessTypeEnum.DIVIDE_SCHOOL_LEADERS_AUDIT, proposalInfo.getId());
|
||||
if(oaAuditInstances.size() >= 1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, proposalInfo.getCreateUser());
|
||||
String title = "分管校领导提案审批-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() +"[" + createUser.getUsername() + "]" + ")";
|
||||
String subTitle = "分管校领导提案审批";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.DIVIDE_SCHOOL_LEADERS_AUDIT,
|
||||
proposalInfo.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(reply.getLeaderId()),
|
||||
Globals.AppDomain + "/platform/proposal/transact/leader/leaderAudit?proposalId=" + proposalInfo.getId(),
|
||||
Globals.AppDomain + "/platform/proposal/transact/leader/leaderAudit");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,14 @@ package io.v.nutz.proposal.controller.transact;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.result.Result;
|
||||
import io.v.nutz.base.utils.DateUtil;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.dao.CndPlus;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.constants.ProposalStateDirectionEnum;
|
||||
import io.v.nutz.proposal.mode.ProposalSubmitMode;
|
||||
@@ -40,6 +44,7 @@ import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -69,6 +74,9 @@ public class SecondedController {
|
||||
@Inject
|
||||
private ProposalSecondedService proposalSecondedService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/proposal/transact/seconded.html")
|
||||
@@ -195,6 +203,46 @@ public class SecondedController {
|
||||
return pagination;
|
||||
}
|
||||
|
||||
@Ok("json")
|
||||
@At("/detail")
|
||||
public Result detail(String proposalId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
ps.id secondedId,
|
||||
ps.isAgree,
|
||||
psu.username secondedUserName,
|
||||
su.username,
|
||||
su.loginname,
|
||||
state.stateName,
|
||||
state.stateColor,
|
||||
type.typeCode,
|
||||
type.typeName,
|
||||
jdh.jdhallname meetingName,
|
||||
dbt.dbtname delegationName,
|
||||
dbt.`code` delegationCode,
|
||||
manner.`name` mannerName,
|
||||
result.`name` resultName
|
||||
FROM
|
||||
proposal_seconded ps
|
||||
LEFT JOIN proposal_info info ON info.id = ps.proposalId
|
||||
LEFT JOIN `user` su ON su.id = info.createUser
|
||||
LEFT JOIN sys_user psu ON psu.id = ps.seconderId
|
||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||
LEFT JOIN jdh_dbt dbt ON dbt.id = info.delegationId
|
||||
LEFT JOIN sys_dict manner ON manner.`code` = info.mannerCode
|
||||
LEFT JOIN sys_dict result ON result.`code` = info.resultCode
|
||||
where info.id=@id and ps.seconderId=@seconderId
|
||||
""");
|
||||
sql.params().set("id", proposalId);
|
||||
sql.params().set("seconderId", ShiroUtil.getUserId());
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
dao.execute(sql);
|
||||
return Result.success(sql.getObject(HashMap.class));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 附议
|
||||
@@ -238,7 +286,8 @@ public class SecondedController {
|
||||
long secondedSize = secondedList.size();
|
||||
//如果附议人和已附议的相等
|
||||
if (agreeCount == secondedSize) {
|
||||
Integer stateCode = proposalProcessService.getStateCode(proposalId, ProposalStateDirectionEnum.NEXT, false);
|
||||
//Integer stateCode = proposalProcessService.getStateCode(proposalId, ProposalStateDirectionEnum.NEXT, false);
|
||||
Integer stateCode = proposalProcessService.getSomeNodeNextStateCode(proposalInfo.getStateCode(), ProposalStateDirectionEnum.NEXT);
|
||||
dao.update(ProposalInfo.class, Chain.make("stateCode", stateCode), Cnd.where("id", "=", proposalId));
|
||||
proposalSecondedService.sendMsgToHead(proposalId);
|
||||
}
|
||||
@@ -269,6 +318,15 @@ public class SecondedController {
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// 更新OA任务实例
|
||||
ProposalSeconded seconded = dao.fetch(ProposalSeconded.class, secondedId);
|
||||
OaAuditInstance instance = auditInstanceService.getByUser(OaBusinessTypeEnum.WRITE_PROPOSAL, proposalId, seconded.getSeconderId());
|
||||
if(instance == null) return null;
|
||||
if(flag) {
|
||||
auditInstanceService.agree(instance.getId(), seconded.getSeconderId(), "同意");
|
||||
} else {
|
||||
auditInstanceService.refuse(instance.getId(), seconded.getSeconderId(), "拒绝");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@ package io.v.nutz.proposal.controller.transact;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import cn.wizzer.framework.page.Pagination;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.dao.CndPlus;
|
||||
import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.model.OaAuditInstance;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.constants.ProposalState;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalSearch;
|
||||
@@ -13,18 +18,26 @@ import io.v.nutz.proposal.services.ProposalInfoService;
|
||||
import io.v.nutz.proposal.services.ProposalPrincipalReadService;
|
||||
import io.v.nutz.proposal.services.ProposalProcessService;
|
||||
import io.v.nutz.sys.models.Sys_signature;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
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.POST;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
@@ -43,6 +56,9 @@ public class principalReadController {
|
||||
@Inject
|
||||
private ProposalProcessService proposalProcessService;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@@ -127,6 +143,7 @@ public class principalReadController {
|
||||
|
||||
@At
|
||||
@POST
|
||||
@Ok("json:full")
|
||||
@ViReturn
|
||||
public Object audit(@Param("sign") String sign, @Param("audit") ProposalAudit audit, @Param("proposalIds") String[] proposalIds) {
|
||||
// if(!ShiroUtil.hasAnyRoles(List.of("principal","secretary"))){
|
||||
@@ -138,7 +155,49 @@ public class principalReadController {
|
||||
audit.setSignId(signId);
|
||||
}
|
||||
proposalPrincipalReadService.audit(audit, Arrays.asList(proposalIds));
|
||||
return null;
|
||||
|
||||
// 处理代办任务
|
||||
try {
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.PRINCIPAL_SECRETARY_AUDIT, ShiroUtil.getUserId());
|
||||
if (oaInstance != null) {
|
||||
|
||||
auditInstanceService.agree(oaInstance.getId(), ShiroUtil.getUserId(), "审核通过");
|
||||
}
|
||||
|
||||
// 是否还有审核信息
|
||||
ProposalSearch search = new ProposalSearch();
|
||||
search.setIsAudit("false");
|
||||
search.setMeetingId("tq19v68n3milip0rhuml8b1euk");
|
||||
PageForm page = new PageForm();
|
||||
page.setSearchName("proposalName");
|
||||
page.setPageNumber(1);
|
||||
page.setPageSize(10);
|
||||
Result result = (Result) this.pageData(page, search);
|
||||
Pagination pagination = (Pagination) result.getData();
|
||||
if(pagination == null || pagination.getList() == null || pagination.getList().size() <= 0) {
|
||||
|
||||
// 书记审核 或者 校长审核后才全部处理完成
|
||||
Sql proposalSql = Sqls.create("select * from proposal_info where stateCode=@stateCode " +
|
||||
"and (secretaryOpinionsAgain is null or secretaryOpinionsAgain='' or secretaryOpinions is null or secretaryOpinions = '')");
|
||||
proposalSql.params().set("stateCode", ProposalState.PRINCIPALREAD);
|
||||
proposalSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(proposalSql);
|
||||
List<NutMap> proposalMaps = proposalSql.getList(NutMap.class);
|
||||
if(proposalMaps != null && proposalMaps.size() > 0) {
|
||||
return Result.success(Map.of("sendTask", false));
|
||||
}
|
||||
|
||||
// 处理全部未审核任务
|
||||
List<OaAuditInstance> auditInstances = auditInstanceService.getByBusinessTypeRunning(OaBusinessTypeEnum.PRINCIPAL_SECRETARY_AUDIT);
|
||||
for(OaAuditInstance auditInstance : auditInstances) {
|
||||
auditInstanceService.agree(auditInstance.getId(), "审核通过");
|
||||
}
|
||||
return Result.success(Map.of("sendTask", true));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return Result.success(Map.of("sendTask", false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,4 +218,56 @@ public class principalReadController {
|
||||
return Result.success().addMsg("撤回成功!");
|
||||
}
|
||||
|
||||
@At("/sendToDoTaskInfo")
|
||||
@Ok("json")
|
||||
public Result sendToDoTaskInfo() {
|
||||
try {
|
||||
// 书记审核 或者 校长审核后发送待办
|
||||
Sql proposalSql = Sqls.create("select * from proposal_info where stateCode=@stateCode " +
|
||||
"and (secretaryOpinionsAgain is null or secretaryOpinionsAgain='' or secretaryOpinions is null or secretaryOpinions = '')");
|
||||
proposalSql.params().set("stateCode", ProposalState.PRINCIPALREAD);
|
||||
proposalSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(proposalSql);
|
||||
List<NutMap> proposalMaps = proposalSql.getList(NutMap.class);
|
||||
if(proposalMaps != null && proposalMaps.size() > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取审核用户信息 角色
|
||||
Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" +
|
||||
" where sur.roleId in (@roleId)");
|
||||
userSql.params().set("roleId", Arrays.asList(Roles.WYH_ZR));
|
||||
userSql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(userSql);
|
||||
List<NutMap> sysUsers = userSql.getList(NutMap.class);
|
||||
if (sysUsers == null || sysUsers.size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> auditUsers = sysUsers.stream().map(item -> {
|
||||
return item.getString("id");
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
for (String auditUserId : auditUsers) {
|
||||
|
||||
OaAuditInstance oaInstance = auditInstanceService.getByUser(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_CONFIRM_COMMITTEE, auditUserId);
|
||||
if (oaInstance != null) continue;
|
||||
|
||||
Sys_user createUser = dao.fetch(Sys_user.class, io.v.nutz.util.ShiroUtil.getUserId());
|
||||
String title = "提案审核-执委会主任确认审核";
|
||||
String subTitle = createUser.getUsername() + "邀请您提案审核";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.DIRECTOR_EXECUTIVE_CONFIRM_COMMITTEE,
|
||||
createUser.getId(),
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(auditUserId),
|
||||
Globals.AppDomain + "/platform/proposal/transact/executorReadConfirm",
|
||||
Globals.AppDomain + "/platform/proposal/transact/executorReadConfirm");
|
||||
}
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return Result.success("已为你自动发送待办到下一审批节点");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.v.nutz.modules.models.PageForm;
|
||||
import io.v.nutz.proposal.models.ProposalAudit;
|
||||
import io.v.nutz.proposal.models.ProposalSearch;
|
||||
import io.v.nutz.service.ViService;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -23,6 +24,8 @@ public interface ProposalCaseService extends ViService {
|
||||
*/
|
||||
Pagination pageData(PageForm pageForm, ProposalSearch search);
|
||||
|
||||
NutMap detail(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 立案
|
||||
|
||||
@@ -124,6 +124,49 @@ public class ProposalCaseServiceImpl extends ViServiceImpl implements ProposalCa
|
||||
return pagination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap detail(String id) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
su.username,
|
||||
su.loginname,
|
||||
state.stateName,
|
||||
state.stateColor,
|
||||
type.typeCode,
|
||||
type.typeName,
|
||||
jdh.jdhallname meetingName,
|
||||
dbt.dbtname delegationName,
|
||||
dbt.`code` delegationCode,
|
||||
manner.`name` mannerName,
|
||||
result.`name` resultName,
|
||||
lalevel.`name` laLevelName,
|
||||
(
|
||||
SELECT
|
||||
count( 1 ) > 0
|
||||
FROM
|
||||
proposal_conjoin
|
||||
where JSON_CONTAINS (proposalIds,JSON_QUOTE(info.id))
|
||||
) AS isConjoin,
|
||||
(SELECT count(1) > 0 FROM proposal_branch_leader_audit WHERE proposalId = info.id AND isAudit = 1) branchLeaderIsAudit
|
||||
FROM
|
||||
proposal_info info
|
||||
LEFT JOIN `user` su ON su.id = info.createUser
|
||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||
LEFT JOIN jdh_dbt dbt ON dbt.id = info.delegationId
|
||||
LEFT JOIN sys_dict manner ON manner.`code` = info.mannerCode
|
||||
LEFT JOIN sys_dict result ON result.`code` = info.resultCode
|
||||
LEFT JOIN sys_dict lalevel ON lalevel.`code` = info.determineTypeCode
|
||||
where info.id = @id limit 0,1
|
||||
""");
|
||||
sql.params().set("id", id);
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
this.dao().execute(sql);
|
||||
return sql.getObject(NutMap.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void audit(List<String> proposalIds, String resultCode, String determineTypeCode, String hostUnit, List<String> helpUnits, String typeId, ProposalAudit audit, String auditType, int flag) {
|
||||
|
||||
@@ -3,9 +3,13 @@ package io.v.nutz.proposal.services.impl;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.v.nutz.base.utils.MsgApi;
|
||||
import io.v.nutz.base.utils.Roles;
|
||||
import io.v.nutz.oa.enums.OaBusinessTypeEnum;
|
||||
import io.v.nutz.oa.service.IOaAuditInstanceService;
|
||||
import io.v.nutz.proposal.models.ProposalInfo;
|
||||
import io.v.nutz.proposal.models.ProposalSeconded;
|
||||
import io.v.nutz.service.impl.ViServiceImpl;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.entity.Record;
|
||||
@@ -14,6 +18,7 @@ import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -27,6 +32,9 @@ public class ProposalSecondedServiceImpl extends ViServiceImpl<ProposalSeconded>
|
||||
@Inject
|
||||
private MsgApi msgApi;
|
||||
|
||||
@Inject
|
||||
private IOaAuditInstanceService auditInstanceService;
|
||||
|
||||
public ProposalSecondedServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
@@ -39,6 +47,7 @@ public class ProposalSecondedServiceImpl extends ViServiceImpl<ProposalSeconded>
|
||||
ProposalInfo info = dao().fetch(ProposalInfo.class, proposalId);
|
||||
Sql sql = Sqls.fetchRecord("""
|
||||
SELECT
|
||||
u.id,
|
||||
u.username,
|
||||
u.mobile,
|
||||
u.unitid,
|
||||
@@ -58,6 +67,23 @@ public class ProposalSecondedServiceImpl extends ViServiceImpl<ProposalSeconded>
|
||||
if (Lang.isNotEmpty(tzRecord)) {
|
||||
//发送消息
|
||||
msgApi.sendMsg(StrUtil.format(TZ_TEMPLATE, info.getProposalName()), List.of(tzRecord.getString("loginname")));
|
||||
|
||||
try {
|
||||
// 团长生成待办任务
|
||||
Sys_user createUser = this.dao().fetch(Sys_user.class, info.getCreateUser());
|
||||
String title = "提案审核-" + info.getProposalName() + "(" + info.getProposalCode() + "[" + tzRecord.getString("username") + "]" + ")";
|
||||
String subTitle = createUser.getUsername() + "邀请您提案审核";
|
||||
auditInstanceService.createTask(OaBusinessTypeEnum.TUANZHANG_AUDIT_PROPOSAL,
|
||||
proposalId,
|
||||
title,
|
||||
subTitle,
|
||||
createUser.getId(),
|
||||
Arrays.asList(tzRecord.getString("id")),
|
||||
Globals.AppDomain + "/platform/proposal/transact/delegation?proposalId=" + proposalId,
|
||||
Globals.AppDomain + "/platform/proposal/transact/delegation?proposalId=" + proposalId);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import lombok.Getter;
|
||||
public enum ColumnFormTypeEnum {
|
||||
|
||||
INPUT("INPUT", "输入框"),
|
||||
TEXTAREA("TEXTAREA", "多行输入框"),
|
||||
SELECT("SELECT", "选择框"),//选项数组,
|
||||
//RADIO("RADIO", "单选框"),//选项数组
|
||||
FILE("FILE", "文件");//上传个数,格式
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package io.v.nutz.web.commons.ext.beetl;
|
||||
|
||||
import org.beetl.core.Resource;
|
||||
import org.beetl.core.misc.BeetlUtil;
|
||||
import org.beetl.core.resource.ClasspathResource;
|
||||
import org.beetl.core.resource.ClasspathResourceLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class BeetlCustomResourceLoader extends ClasspathResourceLoader {
|
||||
|
||||
public Resource getResource(String key) {
|
||||
Resource resource = new ClasspathResource(key, this.getChildPath(super.getRoot(), key), this);
|
||||
return resource;
|
||||
}
|
||||
|
||||
public String getResourceId(Resource resource, String id) {
|
||||
// return resource == null ? id : BeetlUtil.getRelPath(resource.getId(), id);
|
||||
return getRelPath(resource.getId(), id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加判断相对路径
|
||||
* 光见鬼
|
||||
*/
|
||||
private String getRelPath(String siblings, String resourceId) {
|
||||
// 参数校验
|
||||
if (resourceId == null || resourceId.isEmpty()) {
|
||||
throw new RuntimeException("资源ID为空,参数错");
|
||||
}
|
||||
|
||||
// 如果是绝对路径,直接返回(以 / 或 \ 开头)
|
||||
if (resourceId.charAt(0) == '\\' || resourceId.charAt(0) == '/') {
|
||||
if (BeetlUtil.isOutsideOfRoot(resourceId)) {
|
||||
throw new RuntimeException("不能访问外部文件或者模板");
|
||||
}
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
// 处理相对路径
|
||||
String baseDir = siblings;
|
||||
// 如果siblings是文件路径,获取其所在目录
|
||||
int lastSeparatorIndex = Math.max(siblings.lastIndexOf('/'), siblings.lastIndexOf('\\'));
|
||||
if (lastSeparatorIndex > 0) {
|
||||
baseDir = siblings.substring(0, lastSeparatorIndex + 1);
|
||||
}
|
||||
|
||||
// 分割路径
|
||||
String[] parts = resourceId.replace('\\', '/').split("/");
|
||||
List<String> baseParts = new ArrayList<>(
|
||||
Arrays.asList(baseDir.replace('\\', '/').split("/"))
|
||||
);
|
||||
baseParts.removeIf(String::isEmpty);
|
||||
|
||||
// 处理 ../ 和 ./
|
||||
for (String part : parts) {
|
||||
if ("..".equals(part)) {
|
||||
if (!baseParts.isEmpty()) {
|
||||
baseParts.remove(baseParts.size() - 1);
|
||||
}
|
||||
} else if (!".".equals(part) && !part.isEmpty()) {
|
||||
baseParts.add(part);
|
||||
}
|
||||
}
|
||||
|
||||
// 组合最终路径
|
||||
String result = "/" + String.join("/", baseParts);
|
||||
|
||||
// 检查是否访问外部文件
|
||||
if (BeetlUtil.isOutsideOfRoot(result)) {
|
||||
throw new RuntimeException("不能访问外部文件或者模板");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -69,6 +69,8 @@ public class NutShiroProcessor extends AbstractProcessor {
|
||||
HttpServletRequest request = ac.getRequest();
|
||||
String requestURI = request.getRequestURI();
|
||||
|
||||
System.out.println("0=====>" + requestURI);
|
||||
|
||||
//不需要认证授权的url
|
||||
String[] authIgnoreUrlArr = Lang.array("/",
|
||||
"/sso/login",
|
||||
@@ -156,51 +158,64 @@ public class NutShiroProcessor extends AbstractProcessor {
|
||||
}
|
||||
|
||||
private void goAuth(ActionContext ac) throws Exception {
|
||||
//跳转的页面
|
||||
String redirect = null;
|
||||
|
||||
String userAgent = ac.getRequest().getHeader("user-agent");
|
||||
Assert.notNull(userAgent, "Go to your mother's dead reptile!");
|
||||
|
||||
HttpServletRequest request = ac.getRequest();
|
||||
|
||||
StringBuffer requestURL = request.getRequestURL();
|
||||
// === 1. 安全地构建原始请求的完整 URL(支持反向代理)===
|
||||
String forwardedProto = request.getHeader("X-Forwarded-Proto");
|
||||
String scheme = "https"; // 默认生产环境为 https
|
||||
|
||||
// 如果明确是 HTTP(如本地开发),才用 http(可选)
|
||||
if ("http".equalsIgnoreCase(forwardedProto)) {
|
||||
scheme = "http";
|
||||
}
|
||||
|
||||
String host = request.getHeader("Host");
|
||||
if (host == null || host.isEmpty()) {
|
||||
host = request.getServerName();
|
||||
}
|
||||
|
||||
StringBuilder originalUrl = new StringBuilder();
|
||||
originalUrl.append(scheme).append("://").append(host);
|
||||
originalUrl.append(request.getRequestURI());
|
||||
|
||||
String queryString = request.getQueryString();
|
||||
if (StrUtil.isNotBlank(queryString)) {
|
||||
redirect = requestURL.append("?").append(queryString).toString();
|
||||
} else {
|
||||
redirect = requestURL.toString();
|
||||
if (queryString != null && !queryString.trim().isEmpty()) {
|
||||
originalUrl.append("?").append(queryString);
|
||||
}
|
||||
String redirect = originalUrl.toString();
|
||||
|
||||
System.out.println("✅ Constructed redirect URL: " + redirect);
|
||||
|
||||
// === 2. 获取 User-Agent 并校验 ===
|
||||
String userAgent = request.getHeader("user-agent");
|
||||
Assert.notNull(userAgent, "User-Agent is missing! Possible malicious request.");
|
||||
|
||||
// === 3. 微信浏览器处理 ===
|
||||
if (userAgent.toLowerCase().contains("micromessenger") && Globals.MyConfig.getBoolean("weixin")) {
|
||||
String oauthRedirectUri = Globals.AppDomain + "/platform/wechat/oauth?redirect_uri="
|
||||
+ URLEncoder.encode(redirect, StandardCharsets.UTF_8);
|
||||
new ServerRedirectView(oauthRedirectUri).render(request, ac.getResponse(), null);
|
||||
return;
|
||||
}
|
||||
|
||||
//微信浏览器
|
||||
if (userAgent.toLowerCase().indexOf("micromessenger") > 0 && Globals.MyConfig.getBoolean("weixin")) {
|
||||
//跳转到微信公众号授权
|
||||
String s = Globals.AppDomain + "/platform/wechat/oauth?redirect_uri=" + URLEncoder.encode(redirect, StandardCharsets.UTF_8);
|
||||
new ServerRedirectView(s.toString()).render(ac.getRequest(), ac.getResponse(), null);
|
||||
} else if (Globals.isEnv(Env.prod)) {
|
||||
//生产环境登录地址
|
||||
StringBuffer prodLoginUrl = new StringBuffer();
|
||||
prodLoginUrl.append(appDomain + "/sso/login?redirect=");
|
||||
if (StrUtil.isNotBlank(redirect)) {
|
||||
prodLoginUrl.append(URLEncoder.encode(redirect, Charset.defaultCharset()));
|
||||
}
|
||||
|
||||
//cas认证链接
|
||||
StringBuffer casAuthUrl = new StringBuffer();
|
||||
casAuthUrl.append(casAddress + "/login?service=");
|
||||
casAuthUrl.append(URLEncoder.encode(prodLoginUrl.toString(), Charset.defaultCharset()));
|
||||
new ServerRedirectView(casAuthUrl.toString()).render(ac.getRequest(), ac.getResponse(), null);
|
||||
// === 4. 环境区分处理 ===
|
||||
if (Globals.isEnv(Env.prod)) {
|
||||
// 生产环境:跳转到 SSO 登录(经 CAS)
|
||||
String ssoLoginUrl = appDomain + "/sso/login?redirect="
|
||||
+ URLEncoder.encode(redirect, StandardCharsets.UTF_8);
|
||||
String casAuthUrl = casAddress + "/login?service="
|
||||
+ URLEncoder.encode(ssoLoginUrl, StandardCharsets.UTF_8);
|
||||
new ServerRedirectView(casAuthUrl).render(request, ac.getResponse(), null);
|
||||
} else if (Globals.isEnv(Env.dev)) {
|
||||
//开发环境登录地址
|
||||
StringBuffer devLoginUrl = new StringBuffer();
|
||||
devLoginUrl.append(request.getScheme());
|
||||
devLoginUrl.append("://");
|
||||
devLoginUrl.append(request.getServerName());
|
||||
devLoginUrl.append("/platform/login?redirect=");
|
||||
devLoginUrl.append(URLEncoder.encode(redirect, Charset.defaultCharset()));
|
||||
new ServerRedirectView(devLoginUrl.toString()).render(ac.getRequest(), ac.getResponse(), null);
|
||||
// 开发环境:直接跳转到本地登录页
|
||||
String devLoginUrl = request.getScheme() + "://" + request.getServerName()
|
||||
+ "/platform/login?redirect="
|
||||
+ URLEncoder.encode(redirect, StandardCharsets.UTF_8);
|
||||
new ServerRedirectView(devLoginUrl).render(request, ac.getResponse(), null);
|
||||
} else {
|
||||
// 其他环境(如 test)也可按需扩展
|
||||
throw new IllegalStateException("Unsupported environment for authentication redirect.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* SQL XSS拦截
|
||||
* Created by wizzer on 2016/7/1.
|
||||
* 优化:修复JSON中正常HTML标签的误判问题
|
||||
*/
|
||||
public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
|
||||
@@ -35,12 +36,6 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
private PropertiesProxy conf;
|
||||
private List<String> ignoreList;
|
||||
|
||||
private final static String regxpForHtml = "<([^>]*)>"; // 过滤所有以<开头以>结尾的标签
|
||||
|
||||
private final static String regxpForImgTag = "<\\s*img\\s+([^>]*)\\s*>"; // 找出IMG标签
|
||||
|
||||
private final static String regxpForImaTagSrcAttrib = "src=\"([^\"]+)\""; // 找出IMG标签的SRC属性
|
||||
|
||||
//合法字段
|
||||
private static final Set<String> ALLOWED_ORDER_FIELDS = new HashSet<>(Arrays.asList(
|
||||
"createdat", "updatedat"
|
||||
@@ -54,11 +49,12 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
conf = config.getIoc().get(org.nutz.ioc.impl.PropertiesProxy.class, "conf");
|
||||
ignoreList = Arrays.asList(Strings.splitIgnoreBlank(conf.get("xsssql.ignore.urls", "")));
|
||||
} catch (Exception e) {
|
||||
log.warn("初始化XSS/SQL过滤器配置失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void process(ActionContext ac) throws Throwable {
|
||||
if (checkUrl(ac) && checkParams(ac)) {
|
||||
/*if (checkUrl(ac) && checkParams(ac)) {
|
||||
if (NutShiro.isAjax(ac.getRequest())) {
|
||||
ac.getResponse().addHeader("loginStatus", "paramsDenied");
|
||||
NutShiro.rendAjaxResp(ac.getRequest(), ac.getResponse(), Result.error(Mvcs.getMessage(ac.getRequest(), "system.paramserror")));
|
||||
@@ -66,7 +62,7 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
new ForwardView(lerrorUri).render(ac.getRequest(), ac.getResponse(), Mvcs.getMessage(ac.getRequest(), "system.paramserror"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
doNext(ac);
|
||||
}
|
||||
|
||||
@@ -77,89 +73,77 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
|
||||
protected boolean checkParams(ActionContext ac) {
|
||||
HttpServletRequest req = ac.getRequest();
|
||||
|
||||
/* String pageOrderName = req.getParameter("pageOrderName");
|
||||
if (pageOrderName != null && ALLOWED_ORDER_FIELDS.contains(pageOrderName.toLowerCase())) {
|
||||
// 如果是预定义的排序字段,直接放行
|
||||
return false;
|
||||
}*/
|
||||
|
||||
|
||||
Iterator<String[]> values = req.getParameterMap().values().iterator();// 获取所有的表单参数
|
||||
Iterator<String[]> values2 = req.getParameterMap().values().iterator();// 因为是游标所以要重新获取
|
||||
Iterator<String[]> values = req.getParameterMap().values().iterator();
|
||||
Iterator<String[]> values2 = req.getParameterMap().values().iterator();
|
||||
boolean isError = false;
|
||||
|
||||
// XSS过滤
|
||||
String regEx_xss = "script|iframe";
|
||||
//SQL过滤
|
||||
while (values.hasNext()) {
|
||||
String[] valueArray = (String[]) values.next();
|
||||
for (int i = 0; i < valueArray.length; i++) {
|
||||
// 不转换为小写,保持原始值进行检查
|
||||
String value = valueArray[i];
|
||||
// SQL注入过滤
|
||||
while (values.hasNext() && !isError) {
|
||||
String[] valueArray = values.next();
|
||||
for (String value : valueArray) {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// URL解码
|
||||
String decodedValue = value;
|
||||
try {
|
||||
value = URLDecoder.decode(value, StandardCharsets.UTF_8.name());
|
||||
decodedValue = URLDecoder.decode(value, StandardCharsets.UTF_8.name());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("URL解码失败", e);
|
||||
isError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// 检查是否是JSON格式
|
||||
if (isValidJson(value)) {
|
||||
// 对JSON内容进行安全检查
|
||||
if (checkJsonContent(value)) {
|
||||
boolean isJson = isValidJson(decodedValue);
|
||||
if (isJson) {
|
||||
// JSON内容检查(放宽正常HTML标签的限制)
|
||||
if (checkJsonContent(decodedValue)) {
|
||||
isError = true;
|
||||
log.debugf("[%-4s]URI=%s %s", req.getMethod(), req.getRequestURI(), "JSON内容包含危险字符:" + value);
|
||||
log.debugf("[%-4s]URI=%s %s", req.getMethod(), req.getRequestURI(), "JSON内容包含危险字符:" + decodedValue);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// 非JSON格式,严格检查SQL注入
|
||||
if (containsSqlInjection(decodedValue, false)) {
|
||||
isError = true;
|
||||
log.debugf("[%-4s]URI=%s %s", req.getMethod(), req.getRequestURI(), "SQL注入风险:" + decodedValue);
|
||||
break;
|
||||
}
|
||||
// JSON格式验证通过,继续处理下一个参数
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 非JSON格式,进行普通的SQL注入检查
|
||||
if (containsSqlInjection(value, false)) {
|
||||
isError = true;
|
||||
log.debugf("[%-4s]URI=%s %s", req.getMethod(), req.getRequestURI(), "SQL注入风险:" + value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isError) break;
|
||||
}
|
||||
// XSS漏洞过滤(只检查真正危险的脚本)
|
||||
if (!isError) {
|
||||
// XSS漏洞过滤
|
||||
while (values2.hasNext()) {
|
||||
String[] valueArray = (String[]) values2.next();
|
||||
for (int i = 0; i < valueArray.length; i++) {
|
||||
String value = valueArray[i].toLowerCase();
|
||||
// 分拆关键字
|
||||
String[] inj_stra = StringUtils.split(regEx_xss, "|");
|
||||
for (int j = 0; j < inj_stra.length; j++) {
|
||||
// 判断如果路径参数值中含有关键字则返回true,并且结束循环
|
||||
if (value.contains("<" + inj_stra[j] + ">")
|
||||
|| value.contains("<" + inj_stra[j])
|
||||
|| value.contains(inj_stra[j] + ">")) {
|
||||
log.debugf("[%-4s]URI=%s %s", req.getMethod(), req.getRequestURI(), "XSS关键字过滤:" + value);
|
||||
isError = true;
|
||||
break;
|
||||
}
|
||||
while (values2.hasNext() && !isError) {
|
||||
String[] valueArray = values2.next();
|
||||
for (String value : valueArray) {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
if (isError) {
|
||||
String lowerValue = value.toLowerCase();
|
||||
// 只检查真正危险的XSS攻击向量
|
||||
if (lowerValue.contains("<script") ||
|
||||
lowerValue.contains("javascript:") ||
|
||||
lowerValue.contains("vbscript:") ||
|
||||
lowerValue.contains("onerror=") ||
|
||||
lowerValue.contains("onclick=") ||
|
||||
lowerValue.contains("onload=") ||
|
||||
lowerValue.contains("eval(") ||
|
||||
lowerValue.contains("expression(")) {
|
||||
log.debugf("[%-4s]URI=%s %s", req.getMethod(), req.getRequestURI(), "XSS危险内容过滤:" + value);
|
||||
isError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isError) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isError;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证是否为有效的JSON
|
||||
*/
|
||||
@@ -174,11 +158,12 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
|
||||
/**
|
||||
* 检查JSON内容是否包含危险字符
|
||||
* 优化:只检查真正危险的内容,放过正常的HTML标签(p/span等)
|
||||
*/
|
||||
private boolean checkJsonContent(String jsonStr) {
|
||||
try {
|
||||
JsonNode rootNode = objectMapper.readTree(jsonStr);
|
||||
return checkJsonNode(rootNode, true);
|
||||
return checkJsonNode(rootNode);
|
||||
} catch (Exception e) {
|
||||
log.error("JSON内容检查失败", e);
|
||||
return true; // 解析失败当作危险处理
|
||||
@@ -187,94 +172,129 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
|
||||
/**
|
||||
* 递归检查JSON节点
|
||||
* 优化:JSON中的文本内容只检查危险脚本,不检查普通HTML标签
|
||||
*/
|
||||
private boolean checkJsonNode(JsonNode node, boolean isJsonContext) {
|
||||
private boolean checkJsonNode(JsonNode node) {
|
||||
if (node.isObject()) {
|
||||
Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
|
||||
while (fields.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = fields.next();
|
||||
// JSON对象的键名不需要进行特殊字符检查,因为它们是受控的标识符
|
||||
// 递归检查值
|
||||
if (checkJsonNode(entry.getValue(), true)) {
|
||||
if (checkJsonNode(entry.getValue())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (node.isArray()) {
|
||||
for (JsonNode element : node) {
|
||||
if (checkJsonNode(element, true)) {
|
||||
if (checkJsonNode(element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (node.isTextual()) {
|
||||
String value = node.asText();
|
||||
// 在JSON上下文中使用更宽松的规则
|
||||
return containsSqlInjection(value, true);
|
||||
// JSON中的文本内容:
|
||||
// 1. 检查危险的XSS脚本
|
||||
if (containsDangerousXssContent(value)) {
|
||||
return true;
|
||||
}
|
||||
// 2. 检查严重的SQL注入(只检查最危险的关键字组合)
|
||||
if (containsCriticalSqlInjection(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否包含危险的XSS内容(JSON上下文)
|
||||
*/
|
||||
private boolean containsDangerousXssContent(String value) {
|
||||
String lowerValue = value.toLowerCase();
|
||||
// 只检查真正危险的脚本内容,放过p/span/div等普通HTML标签
|
||||
return lowerValue.contains("<script") ||
|
||||
lowerValue.contains("javascript:") ||
|
||||
lowerValue.contains("vbscript:") ||
|
||||
lowerValue.contains("onerror=") ||
|
||||
lowerValue.contains("onclick=") ||
|
||||
lowerValue.contains("eval(") ||
|
||||
lowerValue.contains("expression(");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否包含SQL注入风险
|
||||
*
|
||||
* @param value 要检查的值
|
||||
* @param isJsonContext 是否在JSON上下文中
|
||||
* 检查是否包含严重的SQL注入内容(JSON上下文)
|
||||
*/
|
||||
private boolean containsCriticalSqlInjection(String value) {
|
||||
return false;
|
||||
// if (StringUtils.isBlank(value)) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// String lowerValue = value.toLowerCase().replaceAll("\\s+", " ");
|
||||
//
|
||||
// // 只检查最危险的SQL注入关键字组合(减少误判)
|
||||
// String[] criticalSqlPatterns = {
|
||||
// "select * from",
|
||||
// "insert into",
|
||||
// "update .* set",
|
||||
// "delete from",
|
||||
// "drop table",
|
||||
// "truncate table",
|
||||
// "union select",
|
||||
// "exec ",
|
||||
// "execute ",
|
||||
// "declare @",
|
||||
// "information_schema.",
|
||||
// "sysobjects",
|
||||
// "load_file(",
|
||||
// "outfile "
|
||||
// };
|
||||
//
|
||||
// for (String pattern : criticalSqlPatterns) {
|
||||
// if (Pattern.compile(pattern).matcher(lowerValue).find()) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 检查危险的特殊字符组合
|
||||
// if (lowerValue.contains("' or '1'='1") ||
|
||||
// lowerValue.contains("' and '1'='1") ||
|
||||
// lowerValue.contains(";--") ||
|
||||
// lowerValue.contains("0x3c") || // 十六进制<script>
|
||||
// lowerValue.contains("/*+union*/")) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查非JSON内容的SQL注入风险
|
||||
*/
|
||||
private boolean containsSqlInjection(String value, boolean isJsonContext) {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return false;
|
||||
}
|
||||
// 规范化输入:移除多余的空白字符
|
||||
value = value.replaceAll("\\s+", " ").trim();
|
||||
|
||||
// 检查编码后的特殊字符
|
||||
String decodedValue = value.replaceAll("%20", " ")
|
||||
.replaceAll("%2B", "+")
|
||||
.replaceAll("%2F", "/")
|
||||
.replaceAll("%3D", "=");
|
||||
|
||||
// 检查注释符号和其他危险字符
|
||||
if (decodedValue.contains("--") ||
|
||||
decodedValue.contains("/*") ||
|
||||
decodedValue.contains("*/") ||
|
||||
Pattern.compile("[;'\"\\\\]").matcher(decodedValue).find()) {
|
||||
return true;
|
||||
}
|
||||
String normalizedValue = value.replaceAll("\\s+", " ").trim().toLowerCase();
|
||||
|
||||
// 如果是UUID格式,直接放行
|
||||
if (value.matches("[a-fA-F0-9]{32}") || value.matches("[a-fA-F0-9-]{36}")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 如果包含HTML标签,使用更宽松的检查规则
|
||||
if (value.contains("<") && value.contains(">")) {
|
||||
return checkHtmlContent(value);
|
||||
}
|
||||
|
||||
// 添加对常见标识符的检查
|
||||
if (isCommonIdentifier(value) || ALLOWED_ORDER_FIELDS.contains(value.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查注释符号
|
||||
if (value.contains("--") || value.contains("/*") || value.contains("*/")) {
|
||||
// 检查注释符号和危险字符
|
||||
if (normalizedValue.contains("--") ||
|
||||
normalizedValue.contains("/*") ||
|
||||
normalizedValue.contains("*/") ||
|
||||
normalizedValue.contains(";") ||
|
||||
normalizedValue.contains("'") ||
|
||||
normalizedValue.contains("\\") ||
|
||||
normalizedValue.contains("0x")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查危险的特殊字符(针对非JSON数据)
|
||||
if (!isValidJson(value) && containsDangerousChars(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查SQL关键字,但要避免误判
|
||||
String valueLower = value.toLowerCase();
|
||||
// 检查SQL关键字
|
||||
for (String keyword : SQL_KEYWORDS) {
|
||||
// 在JSON上下文中,只有当关键字作为独立单词出现时才判定为危险
|
||||
if (isJsonContext) {
|
||||
if (isStandaloneWord(valueLower, keyword)) {
|
||||
return true;
|
||||
}
|
||||
} else if (valueLower.contains(keyword)) {
|
||||
if (isStandaloneWord(normalizedValue, keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -297,49 +317,12 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查HTML内容是否包含危险脚本
|
||||
*/
|
||||
private boolean checkHtmlContent(String html) {
|
||||
String lowerHtml = html.toLowerCase();
|
||||
// 只检查真正危险的脚本标签
|
||||
return lowerHtml.contains("<script") ||
|
||||
lowerHtml.contains("javascript:") ||
|
||||
lowerHtml.contains("onerror=") ||
|
||||
lowerHtml.contains("onclick=");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否包含危险的特殊字符
|
||||
*/
|
||||
private boolean containsDangerousChars(String value) {
|
||||
// 定义真正危险的字符(减少误判)
|
||||
String[] dangerousChars = {
|
||||
"'", // 单引号
|
||||
";", // 分号
|
||||
"\\", // 反斜杠
|
||||
"@@", // 系统变量前缀
|
||||
"0x", // 十六进制前缀
|
||||
"/*", // 注释开始
|
||||
"*/" // 注释结束
|
||||
};
|
||||
|
||||
for (String dangerous : dangerousChars) {
|
||||
if (value.contains(dangerous)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Set<String> SQL_KEYWORDS = new HashSet<>(Arrays.asList(
|
||||
"select", "update", "delete", "insert", "truncate",
|
||||
"drop", "execute", "exec", "declare", "union",
|
||||
"create", "alter", "database", "table", "varchar",
|
||||
"extractvalue", "concat", "benchmark", "sleep", "delay",
|
||||
"waitfor", "pg_sleep", "information_schema", "sysobjects",
|
||||
"load_file", "outfile", "dumpfile"
|
||||
"create", "alter", "database", "table",
|
||||
"extractvalue", "concat", "benchmark", "sleep",
|
||||
"waitfor", "pg_sleep", "load_file", "outfile"
|
||||
));
|
||||
|
||||
/**
|
||||
@@ -349,5 +332,4 @@ public class XssSqlFilterProcessor extends AbstractProcessor {
|
||||
String wordBoundary = "\\b" + keyword + "\\b";
|
||||
return Pattern.compile(wordBoundary).matcher(text).find();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class AgendaController {
|
||||
List<NutMap> list = new ArrayList<>();
|
||||
|
||||
list.add(new NutMap().addv("iconClass", "").addv("imgUrl", "/assets/platform/img/quickentry/member.png").addv("label", "会员管理").addv("url", "/platform/member/change/mange").addv("color", "#58ae62"));
|
||||
list.add(new NutMap().addv("iconClass", "").addv("imgUrl", "/assets/platform/img/quickentry/proposal.png").addv("label", "提案管理").addv("url", "/platform/proposal/statistics/integrated").addv("color", "#a762c3"));
|
||||
// list.add(new NutMap().addv("iconClass", "").addv("imgUrl", "/assets/platform/img/quickentry/proposal.png").addv("label", "提案管理").addv("url", "/platform/proposal/statistics/integrated").addv("color", "#a762c3"));
|
||||
list.add(new NutMap().addv("iconClass", "").addv("imgUrl", "/assets/platform/img/quickentry/activity.png").addv("label", "活动管理").addv("url", "/platform/trainSingUp/manage/activity/add").addv("color", "#4778cf"));
|
||||
list.add(new NutMap().addv("iconClass", "").addv("imgUrl", "/assets/platform/img/quickentry/welfare.png").addv("label", "福利慰问").addv("url", "/platform/welfare/mine").addv("color", "#c88f5c"));
|
||||
list.add(new NutMap().addv("iconClass", "").addv("imgUrl", "/assets/platform/img/quickentry/db.png").addv("label", "大病互助").addv("url", "/platform/sickHelp/mySubsidyRecord").addv("color", "#dd5858"));
|
||||
|
||||
@@ -98,8 +98,10 @@ public class SysWechatController {
|
||||
if (sysUser == null) {
|
||||
String s = Globals.AppDomain + "/platform/wechat/doLogin?openid=" + openid;
|
||||
if (StrUtil.isNotBlank(redirect)) {
|
||||
System.out.println("2=====>" + redirect);
|
||||
s += "&redirect=" + URLEncoder.encode(redirect, StandardCharsets.UTF_8);
|
||||
}
|
||||
System.out.println("3=====>" + s);
|
||||
return ">>:" + Globals.CasAddress + "/login?service=" + URLEncoder.encode(s, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
:readonly="['SELECT'].includes(column.columnFormType)"
|
||||
:rules="[{ required: column.isRequired, message: (['SELECT'].includes(column.columnFormType) ? '请选择' : '请填写') + column.columnName }]"
|
||||
:required="column.isRequired"
|
||||
:type="column.columnFormType === 'TEXTAREA' ? 'textarea' : (column.columnFormType === 'INT' ? 'number' : 'text')"
|
||||
:autosize="column.columnFormType === 'TEXTAREA'"
|
||||
rows="1"
|
||||
@click="selectFieldClick(column)"
|
||||
></van-field>
|
||||
|
||||
|
||||
@@ -94,12 +94,12 @@ layout("/mobile/platform.html"){
|
||||
isOpen: true,
|
||||
backGroundColor: '#58ae62'
|
||||
},
|
||||
{
|
||||
/* {
|
||||
src: '/assets/platform/img/quickentry/proposal.png',
|
||||
text: '提案管理',
|
||||
isOpen: true,
|
||||
backGroundColor: '#a762c3'
|
||||
},
|
||||
},*/
|
||||
{
|
||||
src: '/assets/platform/img/quickentry/activity.png',
|
||||
text: '活动管理',
|
||||
|
||||
@@ -201,15 +201,15 @@ layout("/mobile/platform.html"){
|
||||
<span class="train-title">联 系 人:</span>
|
||||
<span>{{o.courseInstructor}}</span>
|
||||
</div>
|
||||
<div v-if="activity.addressName!='上车'">
|
||||
<span class="train-title">时  间:</span>
|
||||
<span v-if="o.courseTimeList && o.courseTimeList.length > 1" @click="trainClick(o)"
|
||||
style="color: #1867b0">点我查看</span>
|
||||
<span @click="trainClick(o)" v-if="o.courseTimeList && o.courseTimeList.length === 1"
|
||||
style="color: #1867b0">
|
||||
{{o.courseTimeList[0].courseStartTime.substring(11, 19) + ' ~ ' + o.courseTimeList[0].courseEndTime.substring(11, 19)}}
|
||||
</span>
|
||||
</div>
|
||||
<!-- <div v-if="activity.addressName!='上车'">-->
|
||||
<!-- <span class="train-title">时  间:</span>-->
|
||||
<!-- <span v-if="o.courseTimeList && o.courseTimeList.length > 1" @click="trainClick(o)"-->
|
||||
<!-- style="color: #1867b0">点我查看</span>-->
|
||||
<!-- <span @click="trainClick(o)" v-if="o.courseTimeList && o.courseTimeList.length === 1"-->
|
||||
<!-- style="color: #1867b0">-->
|
||||
<!-- {{o.courseTimeList[0].courseStartTime.substring(11, 19) + ' ~ ' + o.courseTimeList[0].courseEndTime.substring(11, 19)}}-->
|
||||
<!-- </span>-->
|
||||
<!-- </div>-->
|
||||
<div>
|
||||
<span @click.stop="showPic(FILE_DOMAIN + '/fileStreamPreview?id=' + tableData.wechat.id)"
|
||||
v-if="o.isSign === true && tableData.wechat"
|
||||
@@ -351,7 +351,7 @@ layout("/mobile/platform.html"){
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'train-dynamic-form': httpVueLoader('/components/mobile/common/TrainDynamicForm.vue')
|
||||
'train-dynamic-form': httpVueLoader('/components/mobile/common/TrainDynamicForm.vue?v=' + new Date().getTime())
|
||||
},
|
||||
methods: {
|
||||
getCourseTypeName(o) {
|
||||
|
||||
@@ -45,6 +45,9 @@ layout("/layouts/platform.html"){
|
||||
:disabled="multipleSelection && multipleSelection.length >=2 ? false : true"
|
||||
type="primary" v-if="!pageForm.isAudit" size="mini">并案审核
|
||||
</el-button>
|
||||
<el-button icon="el-icon-s-promotion" type="primary" size="small"
|
||||
@click="sendToDoTaskInfo">发送待办
|
||||
</el-button>
|
||||
</template>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" align="center" header-align="center" :row-key="(row)=>{row.id}"
|
||||
@@ -578,6 +581,23 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 发送待办
|
||||
async sendToDoTaskInfo () {
|
||||
const confirm = await this.$confirm('确定发送待办到执委会吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm !== 'confirm') return
|
||||
const resp = await $.post(loc() + '/sendToDoTaskInfo')
|
||||
if(resp.code != 0) {
|
||||
this.$message.error(resp.msg)
|
||||
} else {
|
||||
this.$message.success(resp.msg)
|
||||
}
|
||||
},
|
||||
|
||||
vChange(value) {
|
||||
if (value.newValue === 'index' && this.multipleSelection.length > 0 && this.mergeIndex === 1) {
|
||||
this.dialogVisible = true
|
||||
@@ -643,6 +663,19 @@ layout("/layouts/platform.html"){
|
||||
this.$refs.audit.openView(id)
|
||||
|
||||
},
|
||||
async autoOpenAuditPage() {
|
||||
const queryString = window.location.search;
|
||||
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const proposalId = urlParams.get('proposalId')
|
||||
if(proposalId && proposalId != '') {
|
||||
const res = await $.post('/platform/proposal/transact/case/case/detail?id=' + proposalId)
|
||||
if(!res.data) return;
|
||||
setTimeout(async ()=> {
|
||||
await this.openAudit(proposalId, res.data)
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
async doAudit(flag) {
|
||||
let formValid = true
|
||||
this.$refs["auditForm"].validate(async valid => formValid = valid)
|
||||
@@ -735,6 +768,14 @@ layout("/layouts/platform.html"){
|
||||
this.$notify.success({title: '成功', message: resp.msg});
|
||||
this.pageData()
|
||||
this.$refs.guava.index()
|
||||
|
||||
// 弹出发送待办提示
|
||||
const sendTask = resp.data.sendTask
|
||||
console.log('sendTask', sendTask)
|
||||
if(sendTask) {
|
||||
await this.sendToDoTaskInfo()
|
||||
}
|
||||
|
||||
} else {
|
||||
this.$notify.error({title: '失败', message: resp.msg});
|
||||
}
|
||||
@@ -758,6 +799,8 @@ layout("/layouts/platform.html"){
|
||||
this.noFilingReason = this.config.noFilingReason
|
||||
await proposal.initData(this)
|
||||
|
||||
// 打开审核界面
|
||||
await this.autoOpenAuditPage()
|
||||
},
|
||||
watch: {}
|
||||
})
|
||||
|
||||
@@ -215,6 +215,20 @@ layout("/layouts/platform.html"){
|
||||
this.$refs.guava.edit()
|
||||
this.$refs.audit.openView(id)
|
||||
},
|
||||
// 自动打开审核页面
|
||||
async autoOpenAuditPage() {
|
||||
const queryString = window.location.search;
|
||||
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const proposalId = urlParams.get('proposalId')
|
||||
if(proposalId != null && proposalId != '') {
|
||||
const res = await $.post('/platform/proposal/transact/caseCheck/detail?proposalId=' + proposalId)
|
||||
console.log(res)
|
||||
setTimeout(async ()=> {
|
||||
await this.openAudit(res.data)
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
async doAudit() {
|
||||
let formValid = true
|
||||
this.$refs["auditForm"].validate(async valid => formValid = valid)
|
||||
@@ -255,6 +269,8 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
async created() {
|
||||
await proposal.initData(this)
|
||||
|
||||
await this.autoOpenAuditPage()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -231,6 +231,17 @@ layout("/layouts/platform.html"){
|
||||
this.$refs['auditForm'].resetFields()
|
||||
}
|
||||
},
|
||||
async openAuditView() {
|
||||
const queryString = window.location.search;
|
||||
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const proposalId = urlParams.get('proposalId')
|
||||
if(proposalId && proposalId !== '') {
|
||||
setTimeout(()=> {
|
||||
this.openAudit(proposalId)
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
async doAudit(flag) {
|
||||
this.submitDisabled = true
|
||||
let formValid = true
|
||||
@@ -290,6 +301,9 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
async created() {
|
||||
await proposal.initData(this)
|
||||
|
||||
// 打开审批页面
|
||||
await this.openAuditView()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -16,15 +16,19 @@ layout("/layouts/platform.html"){
|
||||
<el-button icon="el-icon-s-promotion" type="primary" size="small"
|
||||
@click="batchAudit">批量审核
|
||||
</el-button>
|
||||
<el-button icon="el-icon-s-promotion" type="primary" size="small"
|
||||
@click="sendToDoTaskInfo">发送待办
|
||||
</el-button>
|
||||
</template>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" align="center" header-align="center" :row-key="(row)=>{row.id}"
|
||||
:size="tableSize"
|
||||
@sort-change="pageOrder" @selection-change="(val)=>{this.batchSelection = val}">
|
||||
<el-table-column
|
||||
:selectable="(row)=>{return row.executorOpinion==null && row.resultCode!='notGive'}"
|
||||
type="selection"
|
||||
width="55"></el-table-column>
|
||||
<!-- 注释掉 暂时不允许批量选择审核 -->
|
||||
<!-- <el-table-column-->
|
||||
<!-- :selectable="(row)=>{return row.executorOpinion==null && row.resultCode!='notGive'}"-->
|
||||
<!-- type="selection"-->
|
||||
<!-- width="55"></el-table-column>-->
|
||||
<el-table-column align="center" header-align="center" label="序号" type="index" width="80">
|
||||
<template scope="scope">
|
||||
<span>{{ scope.$index + (pageForm.pageNumber - 1) * pageForm.pageSize + 1 }} </span>
|
||||
@@ -59,7 +63,7 @@ layout("/layouts/platform.html"){
|
||||
查看
|
||||
</el-button>
|
||||
<el-button type="primary" size="mini"
|
||||
v-if="row.executorOpinion==null && row.resultCode!='notGive'"
|
||||
v-if="row.executorOpinion==null && row.resultCode!='notGive' && false"
|
||||
@click="openAudit(row.id,row)">
|
||||
审核
|
||||
</el-button>
|
||||
@@ -317,6 +321,7 @@ layout("/layouts/platform.html"){
|
||||
this.proTableData.unshift(row)
|
||||
},
|
||||
async batchAudit() {
|
||||
this.batchSelection = this.tableData
|
||||
if (this.batchSelection.length === 0) {
|
||||
this.$notify.warning('请选择需要批量审核的记录')
|
||||
return
|
||||
@@ -345,13 +350,18 @@ layout("/layouts/platform.html"){
|
||||
proposalIds: this.formData.proposalId,
|
||||
sign: this.formData.sign,
|
||||
determineTypeCode: this.formData.determineTypeCode
|
||||
|
||||
})
|
||||
|
||||
requestLaterFun(resp, () => {
|
||||
this.$notify.success({title: '成功', message: resp.msg});
|
||||
this.pageData()
|
||||
this.$refs.guava.index()
|
||||
|
||||
const sendTask = resp.data.sendTask
|
||||
console.log('sendTask', sendTask)
|
||||
if(sendTask) {
|
||||
this.sendToDoTaskInfo()
|
||||
}
|
||||
}, () => {
|
||||
this.$notify.error({title: '失败', message: resp.msg});
|
||||
}, () => {
|
||||
@@ -380,18 +390,26 @@ layout("/layouts/platform.html"){
|
||||
if (this.batchSelection && this.batchSelection.length > 0) {
|
||||
proposalIds = this.batchSelection.map(v => v.id)
|
||||
}
|
||||
|
||||
const resp = await $.post(loc() + "/audit", {
|
||||
audit: JSON.stringify(this.formData),
|
||||
proposalIds: JSON.stringify(proposalIds),
|
||||
sign: this.formData.sign,
|
||||
determineTypeCode: this.formData.determineTypeCode
|
||||
})
|
||||
|
||||
requestLaterFun(resp, () => {
|
||||
this.$notify.success({title: '成功', message: resp.msg});
|
||||
this.pageData()
|
||||
this.batchDialog = false
|
||||
this.batchSelection = []
|
||||
this.$refs.guava.index()
|
||||
|
||||
const sendTask = resp.data.sendTask
|
||||
console.log('sendTask', sendTask)
|
||||
if(sendTask) {
|
||||
this.sendToDoTaskInfo()
|
||||
}
|
||||
}, () => {
|
||||
this.$notify.error({title: '失败', message: resp.msg});
|
||||
}, () => {
|
||||
@@ -401,6 +419,23 @@ layout("/layouts/platform.html"){
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
// 发送待办
|
||||
async sendToDoTaskInfo () {
|
||||
const confirm = await this.$confirm('确定发送待办到校长、书记吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm !== 'confirm') return
|
||||
const resp = await $.post(loc() + '/sendToDoTaskInfo')
|
||||
if(resp.code != 0) {
|
||||
this.$message.error(resp.msg)
|
||||
} else {
|
||||
this.$message.success(resp.msg)
|
||||
}
|
||||
},
|
||||
|
||||
async rollback(id) {
|
||||
const confirm = await this.$confirm('您确定要撤回吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
@@ -16,15 +16,18 @@ layout("/layouts/platform.html"){
|
||||
<el-button icon="el-icon-s-promotion" type="primary" size="small"
|
||||
@click="batchAudit">批量审核
|
||||
</el-button>
|
||||
<el-button icon="el-icon-s-promotion" type="primary" size="small"
|
||||
@click="sendToDoTaskInfo">发送待办
|
||||
</el-button>
|
||||
</template>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" align="center" header-align="center" :row-key="(row)=>{row.id}"
|
||||
:size="tableSize"
|
||||
@sort-change="pageOrder" @selection-change="(val)=>{this.batchSelection = val}">
|
||||
<el-table-column
|
||||
:selectable="(row)=>{return row.executorOpinionConfirm==null && row.resultCode!='notGive'}"
|
||||
type="selection"
|
||||
width="55"></el-table-column>
|
||||
<!-- <el-table-column-->
|
||||
<!-- :selectable="(row)=>{return row.executorOpinionConfirm==null && row.resultCode!='notGive'}"-->
|
||||
<!-- type="selection"-->
|
||||
<!-- width="55"></el-table-column>-->
|
||||
<el-table-column align="center" header-align="center" label="序号" type="index" width="80">
|
||||
<template scope="scope">
|
||||
<span>{{ scope.$index + (pageForm.pageNumber - 1) * pageForm.pageSize + 1 }} </span>
|
||||
@@ -59,7 +62,7 @@ layout("/layouts/platform.html"){
|
||||
查看
|
||||
</el-button>
|
||||
<el-button type="primary" size="mini"
|
||||
v-if="row.executorOpinionConfirm==null && row.resultCode!='notGive'"
|
||||
v-if="row.executorOpinionConfirm==null && row.resultCode!='notGive' && false"
|
||||
@click="openAudit(row.id,row)">
|
||||
审核
|
||||
</el-button>
|
||||
@@ -316,6 +319,7 @@ layout("/layouts/platform.html"){
|
||||
this.proTableData.unshift(row)
|
||||
},
|
||||
async batchAudit() {
|
||||
this.batchSelection = this.tableData
|
||||
if (this.batchSelection.length === 0) {
|
||||
this.$notify.warning('请选择需要批量审核的记录')
|
||||
return
|
||||
@@ -350,6 +354,12 @@ layout("/layouts/platform.html"){
|
||||
this.$notify.success({title: '成功', message: resp.msg});
|
||||
this.pageData()
|
||||
this.$refs.guava.index()
|
||||
|
||||
const sendTask = resp.data.sendTask
|
||||
console.log('sendTask', sendTask)
|
||||
if(sendTask) {
|
||||
this.sendToDoTaskInfo()
|
||||
}
|
||||
}, () => {
|
||||
this.$notify.error({title: '失败', message: resp.msg});
|
||||
}, () => {
|
||||
@@ -390,6 +400,12 @@ layout("/layouts/platform.html"){
|
||||
this.batchDialog = false
|
||||
this.batchSelection = []
|
||||
this.$refs.guava.index()
|
||||
|
||||
const sendTask = resp.data.sendTask
|
||||
console.log('sendTask', sendTask)
|
||||
if(sendTask) {
|
||||
this.sendToDoTaskInfo()
|
||||
}
|
||||
}, () => {
|
||||
this.$notify.error({title: '失败', message: resp.msg});
|
||||
}, () => {
|
||||
@@ -399,6 +415,23 @@ layout("/layouts/platform.html"){
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
// 发送待办
|
||||
async sendToDoTaskInfo (isConfirm) {
|
||||
const confirm = await this.$confirm('确定发送待办到提案委确认承办单位吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm !== 'confirm') return
|
||||
const resp = await $.post(loc() + '/sendToDoTaskInfo')
|
||||
if(resp.code != 0) {
|
||||
this.$message.error(resp.msg)
|
||||
} else {
|
||||
this.$message.success(resp.msg)
|
||||
}
|
||||
},
|
||||
|
||||
async rollback(id) {
|
||||
const confirm = await this.$confirm('您确定要撤回吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
@@ -316,6 +316,19 @@ layout("/layouts/platform.html"){
|
||||
this.$refs['auditForm'].resetFields()
|
||||
}
|
||||
},
|
||||
async autoOpenAuditPage() {
|
||||
const queryString = window.location.search;
|
||||
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const proposalId = urlParams.get('proposalId')
|
||||
if(proposalId && proposalId !== '') {
|
||||
const res = await $.post('/platform/proposal/transact/feedback/detail?proposalId=' + proposalId)
|
||||
console.log(res)
|
||||
setTimeout(async ()=> {
|
||||
await this.openFeedback(res.data)
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
async doFeedback() {
|
||||
this.$refs["auditForm"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
@@ -357,6 +370,8 @@ layout("/layouts/platform.html"){
|
||||
await proposal.initData(this)
|
||||
this.feedbackOptions = await getDictByCode("proposal_feedback")
|
||||
this.feedbackOptionsByUnderTakeOptions = await getDictByCode('proposal_feedback_underTake')
|
||||
|
||||
await this.autoOpenAuditPage()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -402,6 +402,19 @@ layout("/layouts/platform.html"){
|
||||
this.$refs['auditForm'].resetFields()
|
||||
}
|
||||
},
|
||||
async autoOpenAuditPage() {
|
||||
const queryString = window.location.search;
|
||||
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const proposalId = urlParams.get('proposalId')
|
||||
if(proposalId && proposalId !== '') {
|
||||
const res = await $.post('/platform/proposal/transact/leader/leaderAudit/detail?proposalId=' + proposalId)
|
||||
console.log(res)
|
||||
setTimeout(async ()=> {
|
||||
await this.openAudit(res.data)
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
async doAudit(flag) {
|
||||
let formValid = true
|
||||
this.$refs["auditForm"].validate(valid => {
|
||||
@@ -443,6 +456,8 @@ layout("/layouts/platform.html"){
|
||||
async created() {
|
||||
this.isNode = await proposal.getProposalIsNodeState(600)
|
||||
await proposal.initData(this)
|
||||
|
||||
await this.autoOpenAuditPage()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -16,15 +16,18 @@ layout("/layouts/platform.html"){
|
||||
<el-button icon="el-icon-s-promotion" type="primary" size="small"
|
||||
@click="batchAudit">批量审核
|
||||
</el-button>
|
||||
<el-button icon="el-icon-s-promotion" type="primary" size="small"
|
||||
@click="sendToDoTaskInfo(true)">发送待办
|
||||
</el-button>
|
||||
</template>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" align="center" header-align="center" :row-key="(row)=>{row.id}"
|
||||
:size="tableSize"
|
||||
@sort-change="pageOrder" @selection-change="(val)=>{this.batchSelection = val}">
|
||||
<el-table-column
|
||||
:selectable="(row)=>{return row.secretaryOpinions==null && row.resultCode!='notGive'}"
|
||||
type="selection"
|
||||
width="55"></el-table-column>
|
||||
<!-- <el-table-column-->
|
||||
<!-- :selectable="(row)=>{return row.secretaryOpinions==null && row.resultCode!='notGive'}"-->
|
||||
<!-- type="selection"-->
|
||||
<!-- width="55"></el-table-column>-->
|
||||
<el-table-column align="center" header-align="center" label="序号" type="index" width="80">
|
||||
<template scope="scope">
|
||||
<span>{{ scope.$index + (pageForm.pageNumber - 1) * pageForm.pageSize + 1 }} </span>
|
||||
@@ -65,12 +68,12 @@ layout("/layouts/platform.html"){
|
||||
查看
|
||||
</el-button>
|
||||
<el-button type="primary" size="mini"
|
||||
v-if="${@shiro.hasRole('principal')} && row.secretaryOpinions==null && row.resultCode!='notGive'"
|
||||
v-if="${@shiro.hasRole('principal')} && row.secretaryOpinions==null && row.resultCode!='notGive'&& false"
|
||||
@click="openAudit(row)">
|
||||
审阅
|
||||
</el-button>
|
||||
<el-button type="primary" size="mini"
|
||||
v-if="${@shiro.hasRole('secretary')} && row.secretaryOpinionsAgain==null && row.resultCode!='notGive'"
|
||||
v-if="${@shiro.hasRole('secretary')} && row.secretaryOpinionsAgain==null && row.resultCode!='notGive' && false"
|
||||
@click="openAudit(row)">
|
||||
审阅
|
||||
</el-button>
|
||||
@@ -273,6 +276,7 @@ layout("/layouts/platform.html"){
|
||||
|
||||
},
|
||||
async batchAudit() {
|
||||
this.batchSelection = this.tableData
|
||||
if (this.batchSelection.length === 0) {
|
||||
this.$notify.warning('请选择需要批量审核的记录')
|
||||
return
|
||||
@@ -302,6 +306,9 @@ layout("/layouts/platform.html"){
|
||||
this.notifySuccess(resp.msg)
|
||||
this.pageData()
|
||||
this.$refs.guava.index()
|
||||
|
||||
// 发送待办
|
||||
await this.sendToDoTaskInfo(false);
|
||||
} else {
|
||||
this.notifyWarning(resp.msg)
|
||||
}
|
||||
@@ -331,6 +338,9 @@ layout("/layouts/platform.html"){
|
||||
this.batchDialog = false
|
||||
this.batchSelection = []
|
||||
this.$refs.guava.index()
|
||||
|
||||
// 发送待办
|
||||
this.sendToDoTaskInfo(false);
|
||||
}, () => {
|
||||
this.$notify.error({title: '失败', message: resp.msg});
|
||||
}, () => {
|
||||
@@ -339,6 +349,25 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 发送待办
|
||||
async sendToDoTaskInfo (isConfirm) {
|
||||
if(isConfirm) {
|
||||
const confirm = await this.$confirm('确定发送待办到执委会主任吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm !== 'confirm') return
|
||||
}
|
||||
const resp = await $.post(loc() + '/sendToDoTaskInfo')
|
||||
if(resp.code != 0) {
|
||||
this.$message.error(resp.msg)
|
||||
} else {
|
||||
this.$message.success(resp.msg)
|
||||
}
|
||||
},
|
||||
|
||||
async rollback(id) {
|
||||
const confirm = await this.$confirm('您确定要撤回吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
@@ -578,6 +578,22 @@ layout("/layouts/platform.html"){
|
||||
this.$refs['auditForm'].resetFields()
|
||||
}
|
||||
},
|
||||
|
||||
async autoOpenAuditPage() {
|
||||
const queryString = window.location.search;
|
||||
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const proposalId = urlParams.get('proposalId')
|
||||
const underTakeType = urlParams.get('underTakeType');
|
||||
if(proposalId && proposalId !== '' && underTakeType && underTakeType !== '') {
|
||||
const res = await $.post('/platform/proposal/transact/reply/detail?underTakeType=' + underTakeType + '&proposalId=' + proposalId)
|
||||
console.log(res)
|
||||
setTimeout(async ()=> {
|
||||
await this.openAudit(res.data)
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
|
||||
async doReply(isSave) {
|
||||
try {
|
||||
const valid = await this.$refs["auditForm"].validate()
|
||||
@@ -630,6 +646,8 @@ layout("/layouts/platform.html"){
|
||||
await proposal.initData(this)
|
||||
this.implementStateOptions = await getDictByCode('proposal_reply_result')
|
||||
this.getLeaders()
|
||||
|
||||
await this.autoOpenAuditPage()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -230,6 +230,17 @@ layout("/layouts/platform.html"){
|
||||
this.formData.createUser = row.createUser
|
||||
this.$refs.guava.edit()
|
||||
this.$refs.audit.openView(row.id)
|
||||
console.log(this.formData)
|
||||
},
|
||||
async outToOpenAudit(rowId) {
|
||||
const res = await $.post('/platform/proposal/transact/seconded/detail?proposalId=' + rowId);
|
||||
console.log('详情-->', res)
|
||||
if(!res.data) {
|
||||
return
|
||||
}
|
||||
setTimeout(async ()=> {
|
||||
await this.openAudit(res.data)
|
||||
}, 500)
|
||||
},
|
||||
async doAudit(flag) {
|
||||
const flagText = flag ? '同意' : '拒绝'
|
||||
@@ -269,6 +280,17 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
async created() {
|
||||
await proposal.initData(this)
|
||||
const queryString = window.location.search;
|
||||
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const proposalId = urlParams.get('proposalId')
|
||||
const isAudit = urlParams.get('isAudit')
|
||||
console.log('urlParams-->', proposalId, isAudit)
|
||||
console.log((!isAudit || isAudit === false || isAudit === 'false'))
|
||||
console.log(proposalId && proposalId !== '')
|
||||
if((!isAudit || isAudit === false || isAudit === 'false') && proposalId && proposalId !== '') {
|
||||
await this.outToOpenAudit(proposalId)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -136,11 +136,13 @@ layout("/layouts/platform.html"){
|
||||
</el-row>
|
||||
|
||||
<el-form-item class="is-required" label="提案内容" prop="brief">
|
||||
<div id="briefEditor"></div>
|
||||
<text-editor v-model="formData.brief"></text-editor>
|
||||
<!-- <div id="briefEditor"></div>-->
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="is-required" label="可行性分析" prop="measures">
|
||||
<div id="measuresEditor"></div>
|
||||
<!-- <div id="measuresEditor"></div>-->
|
||||
<text-editor v-model="formData.measures"></text-editor>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="附件上传" prop="files">
|
||||
@@ -573,17 +575,22 @@ layout("/layouts/platform.html"){
|
||||
data: JSON.stringify(data),
|
||||
sign: data.sign
|
||||
})
|
||||
await this.editProposal()
|
||||
this.pageForm2.proposalId = this.formData.id ? this.formData.id : resp.data
|
||||
if (resp.data) {
|
||||
this.formData.id = resp.data
|
||||
if (resp.code===0){
|
||||
await this.editProposal()
|
||||
this.pageForm2.proposalId = this.formData.id ? this.formData.id : resp.data
|
||||
if (resp.data) {
|
||||
this.formData.id = resp.data
|
||||
}
|
||||
this.pageForm2.proposalName = this.formData.proposalName
|
||||
await this.queryDb()
|
||||
|
||||
await this.getProposalSecondedNum()
|
||||
|
||||
this.$refs.guava.public()
|
||||
}else{
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
this.pageForm2.proposalName = this.formData.proposalName
|
||||
await this.queryDb()
|
||||
|
||||
await this.getProposalSecondedNum()
|
||||
|
||||
this.$refs.guava.public()
|
||||
// sublime.jumpPagePjax('/platform/proposal/transact/compose?operation=invite&id=' + resp.data)
|
||||
}
|
||||
|
||||
@@ -763,7 +770,7 @@ layout("/layouts/platform.html"){
|
||||
mannerCode: 'W01'
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
/* this.$nextTick(() => {
|
||||
$("#briefEditor").html("")
|
||||
$("#measuresEditor").html("")
|
||||
|
||||
@@ -777,7 +784,7 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
briefEditor.create()
|
||||
measuresEditor.create()
|
||||
})
|
||||
})*/
|
||||
if (this.$refs["addForm"])
|
||||
this.$refs["addForm"].resetFields();
|
||||
|
||||
@@ -800,10 +807,10 @@ layout("/layouts/platform.html"){
|
||||
resp.data.files = JSON.parse(resp.data.files)
|
||||
}
|
||||
this.formData = resp.data
|
||||
this.$nextTick(() => {
|
||||
/*this.$nextTick(() => {
|
||||
briefEditor.txt.html(resp.data.brief)
|
||||
measuresEditor.txt.html(resp.data.measures)
|
||||
})
|
||||
})*/
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3,20 +3,31 @@ const todo = {
|
||||
<div class="home-todo">
|
||||
<el-tabs v-model="todoActive " @tab-click="handleClick">
|
||||
<el-tab-pane label="待处理" name="1">
|
||||
<template slot="label">
|
||||
<span>待处理</span>
|
||||
<el-badge v-if="waitHandleCount > 0" :value="waitHandleCount" :max="99" class="item" style="margin-top:10px;">
|
||||
</el-badge>
|
||||
</template>
|
||||
<el-table :data="todoList" v-loading="todoLoading">
|
||||
<el-table-column label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column label="标题" prop="processName" show-overflow-tooltip
|
||||
width="200"></el-table-column>
|
||||
<el-table-column label="发起人" prop="createdByUserName"
|
||||
width="140"></el-table-column>
|
||||
<el-table-column label="发起时间" prop="createdOn" v-if="todoActive==='3'"
|
||||
<el-table-column label="标题" prop="title" show-overflow-tooltip
|
||||
width="150"></el-table-column>
|
||||
<el-table-column label="我的处理环节" prop="taskNodeName"
|
||||
v-if="todoActive!=='3'"></el-table-column>
|
||||
<el-table-column label="流程流转环节" prop="nodeName"></el-table-column>
|
||||
<el-table-column label="发起人" prop="create_name"
|
||||
width="140"></el-table-column>
|
||||
<el-table-column label="发起时间" prop="create_time"
|
||||
width="200"></el-table-column>
|
||||
<el-table-column label="状态" prop="status" width="100">
|
||||
<template scope="{row}">
|
||||
{{ status[row.status] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="我的处理环节" prop="taskNodeName"-->
|
||||
<!-- v-if="todoActive!=='3'"></el-table-column>-->
|
||||
<!-- <el-table-column label="流程流转环节" prop="nodeName"></el-table-column>-->
|
||||
<el-table-column label="操作" width="100">
|
||||
<template scope="{row}">
|
||||
<el-button @click="sublime.jumpPagePjax(row.formUrl)" size="mini" type="primary">查看</el-button>
|
||||
<!-- <el-button @click="sublime.jumpPagePjax(row.formUrl)" size="mini" type="primary">查看</el-button>-->
|
||||
<el-button @click="handleTask(row)" size="mini" type="primary">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -24,40 +35,70 @@ const todo = {
|
||||
<el-tab-pane label="已处理" name="2">
|
||||
<el-table :data="todoList" v-loading="todoLoading">
|
||||
<el-table-column label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column label="标题" prop="processName" show-overflow-tooltip
|
||||
<el-table-column label="标题" prop="title" show-overflow-tooltip
|
||||
width="100"></el-table-column>
|
||||
<el-table-column label="发起人" prop="create_name"
|
||||
width="100"></el-table-column>
|
||||
<el-table-column label="发起时间" prop="create_time"
|
||||
width="200"></el-table-column>
|
||||
<el-table-column label="发起人" prop="createdByUserName"
|
||||
width="140"></el-table-column>
|
||||
<el-table-column label="发起时间" prop="createdOn" v-if="todoActive==='3'"
|
||||
width="150"></el-table-column>
|
||||
<el-table-column label="我的处理环节" prop="taskNodeName"
|
||||
v-if="todoActive!=='3'"></el-table-column>
|
||||
<el-table-column label="流程流转环节" prop="nodeName"></el-table-column>
|
||||
<el-table-column label="状态" prop="status" width="100">
|
||||
<template scope="{row}">
|
||||
{{ status[row.status] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="我的处理环节" prop="taskNodeName"-->
|
||||
<!-- v-if="todoActive!=='3'"></el-table-column>-->
|
||||
<!-- <el-table-column label="流程流转环节" prop="nodeName"></el-table-column>-->
|
||||
<el-table-column label="操作" width="100">
|
||||
<template scope="{row}">
|
||||
<el-button @click="sublime.jumpPagePjax(row.formUrl)" size="mini" type="primary">查看</el-button>
|
||||
<!-- <el-button @click="sublime.jumpPagePjax(row.formUrl)" size="mini" type="primary">查看</el-button>-->
|
||||
<el-button @click="handleTask(row)" size="mini" type="primary">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="loadCompleteHandle"
|
||||
@current-change="loadCompleteHandle"
|
||||
:current-page="pageForm.pageNumber"
|
||||
:page-sizes="[10, 20, 30, 50]"
|
||||
:page-size="pageForm.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pageForm.totalCount">
|
||||
</el-pagination>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="我的发起" name="3">
|
||||
<el-table :data="todoList" v-loading="todoLoading">
|
||||
<el-table-column label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column label="标题" prop="processName" show-overflow-tooltip
|
||||
<el-table-column label="标题" prop="title" show-overflow-tooltip
|
||||
width="100"></el-table-column>
|
||||
<el-table-column label="发起人" prop="create_name"
|
||||
width="100"></el-table-column>
|
||||
<el-table-column label="发起时间" prop="create_time" v-if="todoActive==='3'"
|
||||
width="200"></el-table-column>
|
||||
<el-table-column label="发起人" prop="createdByUserName"
|
||||
width="140"></el-table-column>
|
||||
<el-table-column label="发起时间" prop="createdOn" v-if="todoActive==='3'"
|
||||
width="150"></el-table-column>
|
||||
<el-table-column label="我的处理环节" prop="taskNodeName"
|
||||
v-if="todoActive!=='3'"></el-table-column>
|
||||
<el-table-column label="流程流转环节" prop="nodeName"></el-table-column>
|
||||
<el-table-column label="状态" prop="status" width="100">
|
||||
<template scope="{row}">
|
||||
{{ status[row.status] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="我的处理环节" prop="taskNodeName"-->
|
||||
<!-- v-if="todoActive!=='3'"></el-table-column>-->
|
||||
<!-- <el-table-column label="流程流转环节" prop="nodeName"></el-table-column>-->
|
||||
<el-table-column label="操作" width="100">
|
||||
<template scope="{row}">
|
||||
<el-button @click="sublime.jumpPagePjax(row.formUrl)" size="mini" type="primary">查看</el-button>
|
||||
<!-- <el-button @click="sublime.jumpPagePjax(row.formUrl)" size="mini" type="primary">查看</el-button>-->
|
||||
<el-button @click="handleTask(row)" size="mini" type="primary">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="loadMineSendTask"
|
||||
@current-change="loadMineSendTask"
|
||||
:current-page="pageForm.pageNumber"
|
||||
:page-sizes="[10, 20, 30, 50]"
|
||||
:page-size="pageForm.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pageForm.totalCount">
|
||||
</el-pagination>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<!-- <el-table :data="todoList" style="min-height: 250px" v-loading="todoLoading">-->
|
||||
@@ -83,7 +124,43 @@ const todo = {
|
||||
data() {
|
||||
return {
|
||||
todoActive: "1",
|
||||
todoList:[]
|
||||
todoList:[],
|
||||
todoLoading: false,
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
},
|
||||
status:['草稿', '待处理', '已处理', '已驳回', '已撤回'],
|
||||
waitHandleCount: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
todoActive: {
|
||||
async handler(val) {
|
||||
console.log("val--->", val)
|
||||
this.pageForm = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
}
|
||||
this.todoList = []
|
||||
try{
|
||||
this.todoLoading = true
|
||||
if(Number(val) === 1) {
|
||||
await this.loadWaitHandle()
|
||||
|
||||
} else if(Number(val) === 2) {
|
||||
await this.loadCompleteHandle()
|
||||
|
||||
} else if(Number(val) === 3) {
|
||||
await this.loadMineSendTask()
|
||||
}
|
||||
this.todoLoading = false
|
||||
} catch (e) {
|
||||
this.todoLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -92,9 +169,55 @@ const todo = {
|
||||
/* const {data, code} = await $.get("/platform/sys/localProcess/todoList", { mode: this.todoActive })
|
||||
this.todoList = data*/
|
||||
this.todoLoading = false
|
||||
},
|
||||
|
||||
// 加载待处理数据
|
||||
async loadWaitHandle() {
|
||||
const res = await $.post('/oa/audit/instance/wait/handle')
|
||||
console.log("待处理数据->", res)
|
||||
if(res.code === 0) {
|
||||
this.todoList = res.data
|
||||
this.waitHandleCount = this.todoList.length
|
||||
}
|
||||
},
|
||||
|
||||
// 加载已办数据
|
||||
async loadCompleteHandle() {
|
||||
const res = await $.post('/oa/audit/instance/complete/handle', { ...this.pageForm })
|
||||
console.log("已处理数据->", res)
|
||||
this.todoList = res.list
|
||||
this.pageForm.pageNumber = res.pageNo
|
||||
this.pageForm.pageSize = res.pageSize
|
||||
this.pageForm.totalCount = res.totalCount
|
||||
},
|
||||
|
||||
// 加载我发起的
|
||||
async loadMineSendTask() {
|
||||
const res = await $.post('/oa/audit/instance/mine/send', { ...this.pageForm })
|
||||
console.log("我发起数据->", res)
|
||||
this.todoList = res.list
|
||||
this.pageForm.pageNumber = res.pageNo
|
||||
this.pageForm.pageSize = res.pageSize
|
||||
this.pageForm.totalCount = res.totalCount
|
||||
},
|
||||
|
||||
// 待处理任务处理
|
||||
async handleTask(row) {
|
||||
if(this.todoActive === '1') {
|
||||
const urlObj = new URL(row.url)
|
||||
console.log(urlObj)
|
||||
window.location.href = urlObj.pathname + urlObj.search
|
||||
} else {
|
||||
const urlObj = new URL(row.done_url)
|
||||
console.log(urlObj)
|
||||
window.location.href = urlObj.pathname + urlObj.search
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.handleClick()
|
||||
|
||||
// 待处理
|
||||
this.loadWaitHandle()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,7 +1100,7 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
async getLimitUnionData() {
|
||||
const resp = await $.get('/platform/trainSingUp/manage/activity/getUnionLimit')
|
||||
const resp = await $.get('/platform/trainSingUp/manage/activity/add/getUnionLimit')
|
||||
this.unionUserNumberLimit = resp.data
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user