新购流程查看

This commit is contained in:
hayu 2025-12-04 08:55:46 +08:00
parent eecbff5ae2
commit 9934b4b340
7 changed files with 351 additions and 11 deletions

View File

@ -55,6 +55,7 @@
<th style="width:10%" class="center">收货人</th>
<th style="width:10%" class="center">采购状态</th>
<th style="width:10%" class="center">备注</th>
<th style="width:10%" class="center">流程查看</th>
<th style="width:8%" class="center">操作</th>
</tr>
</thead>

View File

@ -129,6 +129,9 @@ function getbaseList(init) {
html += "<td style='vertical-align:middle;' class='center'></td>";
}
html += "<td style='vertical-align:middle;' class='center'>"+ JY.Object.notEmpty(l.remark) + "</td>";
html += "<td style='vertical-align:middle;' class='center'>";
html += getCurrentStatusText(l.taskStatus, l.taskId, l.isFinish,l.isExamine,l.isApproval);
html += "</td>";
html += rowFunction(l.taskId,l.launchTime,l.finishTime,l.taskStatus,l.isFinish,l.isExamine);
html += "</tr>";
}
@ -144,6 +147,128 @@ function getbaseList(init) {
);
}
// 添加获取当前状态文本的函数
function getCurrentStatusText(taskStatus, taskId, isFinish,isExamine,isApproval) {
var status = parseInt(taskStatus) || 0;
var statusText = "";
var statusClass = "";
if (taskStatus=='4' && isFinish=='0'){
status = 4;
} else if (taskStatus=='4' && isFinish=='1' && isExamine=='0'){
status = 5;
} else if (taskStatus=='4' && isFinish=='1' && isExamine=='1' && isApproval!='0'){
status = 6;
} else if (taskStatus=='4' && isFinish=='1' && isExamine=='1' && isApproval=='0'){
status = 7;
}
// 根据状态获取对应的文本和样式类
switch(status) {
case 1:
statusText = "添加采购明细";
statusClass = "label-success";
break;
case 2:
statusText = "采购验收";
statusClass = "label-success";
break;
case 3:
statusText = "上传验收附件";
statusClass = "label-success";
break;
case 4:
statusText = "采购完成";
statusClass = "label-success";
break;
case 5:
statusText = "入库";
statusClass = "label-success";
break;
case 6:
statusText = "新购机具审核";
statusClass = "label-success";
break;
case 7:
statusText = "新购机具批准";
statusClass = "label-success";
break;
default:
statusText = "创建申请";
statusClass = "label-info";
break;
}
// 返回可点击的状态文本
return '<span class="label ' + statusClass + ' status-clickable" onclick="viewProcessDetails(\'' + taskId + '\', \'' + taskStatus + '\', \'' + isFinish + '\',\'' + isExamine + '\',\'' + isApproval + '\')" title="点击查看流程详情">' + statusText + '</span>';
}
// 保留原有的查看流程详情函数
function viewProcessDetails(taskId, taskStatus, isFinish,isExamine,isApproval) {
const contentHtml = renderProcessSteps(parseInt(taskStatus) || 0, isFinish,isExamine,isApproval);
layer.open({
type: 1,
title: '流程详情',
skin: 'layui-layer-demo',
area: ['800px', '300px'],
shadeClose: true,
shade: 0.8,
maxmin: false,
content: contentHtml
});
}
function renderProcessSteps(taskStatus, isFinish,isExamine,isApproval) {
if (taskStatus=='4' && isFinish=='0'){
taskStatus = 4;
} else if (taskStatus=='4' && isFinish=='1' && isExamine=='0'){
taskStatus = 5;
} else if (taskStatus=='4' && isFinish=='1' && isExamine=='1' && isApproval!='0'){
taskStatus = 6;
} else if (taskStatus=='4' && isFinish=='1' && isExamine=='1' && isApproval=='0'){
taskStatus = 7;
}
// 定义固定的流程节点(顺序不能变)
const steps = [
{ value: 0, text: "创建申请" },
{ value: 1, text: "添加采购明细" },
{ value: 2, text: "采购验收" },
{ value: 3, text: "上传验收附件" },
{ value: 4, text: "已采购完成" },
{ value: 5, text: "入库" },
{ value: 6, text: "新购机具审核" },
{ value: 7, text: "新购机具批准" },
];
let html = '<div style="padding: 20px; font-size: 14px;">';
html += '<h3 style="text-align:center; margin-bottom: 20px;">采购流程进度</h3>';
html += '<div style="display: flex; justify-content: space-between; position: relative; margin-bottom: 30px;">';
// 绘制连接线(可选美化)
html += '<div style="position: absolute; top: 16px; left: 0; right: 0; height: 2px; background-color: #ccc; z-index: 1;"></div>';
steps.forEach((step, index) => {
const isCompleted = taskStatus >= step.value;
const color = isCompleted ? '#333' : '#ccc';
const fontWeight = isCompleted ? 'bold' : 'normal';
html += `
<div style="text-align: center; z-index: 2; position: relative;">
<div style="width: 32px; height: 32px; line-height: 32px; border-radius: 50%; background-color: ${isCompleted ? '#1E90FF' : '#eee'}; color: white; margin: 0 auto 8px; font-weight: bold;">
${index + 1}
</div>
<div style="color: ${color}; font-weight: ${fontWeight}; white-space: nowrap;">${step.text}</div>
</div>
`;
});
html += '</div></div>';
return html;
}
function rowFunction(id,launchTime,finishTime,status,isFinish,isExamine) {
var h = "";
h += "<td style='vertical-align:middle;' class='center'>";

View File

@ -9,11 +9,22 @@
SELECT wta.ID as id, wta.LAUNCH_TIME AS launchTime,pu.`NAME` AS receiveName,
pu1.`NAME` AS launchName,if(mtt.`NAME` is not null,GROUP_CONCAT(DISTINCT mtt.`NAME` SEPARATOR ','),'') AS maType,wta.REMARK AS remark,
wta.FINISH_TIME AS finishTime,wta.TASK_STATUS AS taskStatus,
wta.TASK_ID as taskId,wtr.IS_FINISH as isFinish,wnd.IS_EXAMINE as isExamine
wta.TASK_ID as taskId,wtr.IS_FINISH as isFinish,wnd.IS_EXAMINE as isExamine,
IFNULL(wnds.num,0) as isApproval
FROM wf_task_appoint wta
LEFT JOIN wf_task_record wtr ON wtr.ID = wta.TASK_ID
LEFT JOIN wf_task_record wtr1 ON wtr.SUP_ID = wtr1.ID
LEFT JOIN wf_new_details wnd ON wnd.TASK_ID = wta.TASK_ID
LEFT JOIN (
SELECT
COUNT(*) as num,
TASK_ID
FROM
wf_new_details
WHERE
IS_APPROVAL='0'
GROUP BY TASK_ID
) wnds on wnds.TASK_ID=wta.TASK_ID
LEFT JOIN mm_type mt ON mt.ID = wnd.MODEL_ID
LEFT JOIN mm_type mtt ON mt.PARENT_ID = mtt.ID
LEFT JOIN pm_user pu ON pu.ID = wta.RECEIVE

View File

@ -7,6 +7,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.bonus.sys.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -16,11 +17,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import com.bonus.newInput.beans.NewInputBean;
import com.bonus.newInput.service.NewInputService;
import com.bonus.sys.AjaxRes;
import com.bonus.sys.BaseController;
import com.bonus.sys.GlobalConst;
import com.bonus.sys.Page;
import com.bonus.sys.UserShiroHelper;
import com.bonus.sys.beans.UserBean;
import com.bonus.sys.service.UserService;
@ -303,4 +299,11 @@ public class NewInputController extends BaseController<NewInputBean> {
return ar;
}
@ResponseBody
@RequestMapping(value = "getProcessInfo", method = RequestMethod.POST)
public AjaxRes getProcessInfo(NewInputBean o) {
return service.getProcessInfo(o);
}
}

View File

@ -73,4 +73,6 @@ public interface NewInputDao extends BaseDao<NewInputBean> {
public int deleteMachine(NewInputBean o);
public int delDetails(NewInputBean o);
public NewInputBean getNewInputByTaskId(NewInputBean o);
}

View File

@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletRequest;
import com.bonus.newInput.beans.NewInputBean;
import com.bonus.newInput.beans.NewInputQrcodeBean;
import com.bonus.sys.AjaxRes;
import com.bonus.sys.BaseService;
import com.bonus.sys.Page;
@ -27,4 +28,5 @@ public interface NewInputService extends BaseService<NewInputBean> {
public int deleteQrcode(NewInputBean o);
public AjaxRes getProcessInfo(NewInputBean o);
}

View File

@ -3,11 +3,11 @@ package com.bonus.newInput.service;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Enumeration;
import java.util.List;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import com.bonus.sys.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -21,9 +21,6 @@ import com.bonus.ma.dao.MachineTypeDao;
import com.bonus.newInput.beans.NewInputBean;
import com.bonus.newInput.dao.InputDetailsDao;
import com.bonus.newInput.dao.NewInputDao;
import com.bonus.sys.BaseServiceImp;
import com.bonus.sys.Page;
import com.bonus.sys.UserShiroHelper;
import com.bonus.wf.beans.TaskRecordBean;
import com.bonus.wf.dao.TaskRecordDao;
import com.oreilly.servlet.MultipartRequest;
@ -269,4 +266,203 @@ public class NewInputServiceImp extends BaseServiceImp<NewInputBean> implements
return res;
}
@Override
public AjaxRes getProcessInfo(NewInputBean o) {
AjaxRes ar = getAjaxRes();
try {
String taskId = o.getTaskId();
if (StringHelper.isEmpty(taskId)) {
ar.setRes(0);
ar.setResMsg("任务ID不能为空");
return ar;
}
NewInputBean mainInfo = dao.getNewInputByTaskId(o);
if (mainInfo == null) {
ar.setRes(0);
ar.setResMsg("未找到对应的采购任务");
return ar;
}
// 2. 获取当前状态
Integer currentStatus = mainInfo.getTaskStatus() != null ?
Integer.parseInt(mainInfo.getTaskStatus()) : 0;
// 3. 构建流程节点信息
List<Map<String, Object>> processNodes = new ArrayList<>();
// 固定节点定义
String[][] nodeDefinitions = {
{"0", "创建申请", "icon-file-alt"},
{"1", "添加设备", "icon-plus"},
{"2", "待验收", "icon-check"},
{"3", "待入库", "icon-inbox"},
{"4", "待审核", "icon-ok"},
{"5", "已完成", "icon-flag"}
};
for (String[] nodeDef : nodeDefinitions) {
Integer nodeId = Integer.parseInt(nodeDef[0]);
String nodeName = nodeDef[1];
String nodeIcon = nodeDef[2];
Map<String, Object> node = new HashMap<>();
node.put("id", nodeId);
node.put("name", nodeName);
node.put("icon", nodeIcon);
// 确定节点状态
if (nodeId < currentStatus) {
node.put("status", "completed");
node.put("statusText", "已完成");
node.put("statusColor", "#5cb85c");
} else if (nodeId == currentStatus) {
node.put("status", "current");
node.put("statusText", "进行中");
node.put("statusColor", "#337ab7");
} else {
node.put("status", "pending");
node.put("statusText", "未开始");
node.put("statusColor", "#999");
}
// 添加节点处理时间和处理人信息
Map<String, Object> nodeDetail = getNodeDetail(taskId, nodeId);
if (nodeDetail != null) {
node.putAll(nodeDetail);
}
processNodes.add(node);
}
// 4. 查询流程历史记录
List<Map<String, Object>> history = getProcessHistory(taskId);
// 5. 构建返回数据
Map<String, Object> result = new HashMap<>();
result.put("taskId", taskId);
result.put("launchName", mainInfo.getLaunchName());
result.put("currentStatus", currentStatus);
result.put("statusText", getStatusText(mainInfo.getTaskStatus()));
result.put("processNodes", processNodes);
result.put("history", history);
result.put("progress", calculateProgress(currentStatus, 6)); // 6个节点
ar.setRes(1);
ar.setResMsg("获取流程信息成功");
ar.setObj(result);
} catch (Exception e) {
logger.error("获取流程信息失败", e);
ar.setRes(0);
ar.setResMsg("获取流程信息失败:" + e.getMessage());
}
return ar;
}
// 获取节点详情
private Map<String, Object> getNodeDetail(String taskId, Integer nodeId) {
// 这里查询每个节点的具体处理信息
// 示例查询节点处理记录表
try {
Map<String, Object> params = new HashMap<>();
params.put("taskId", taskId);
params.put("nodeId", nodeId);
// 假设有 process_node_detail 表记录节点处理信息
// Map<String, Object> detail = jdbcTemplate.queryForMap(
// "SELECT handler, handle_time, remark FROM process_node_detail WHERE task_id = ? AND node_id = ?",
// taskId, nodeId
// );
// 这里返回模拟数据
Map<String, Object> detail = new HashMap<>();
if (nodeId == 1) {
detail.put("handler", "张三");
detail.put("handleTime", "2023-12-01 09:30:00");
detail.put("remark", "创建采购申请");
} else if (nodeId == 2) {
detail.put("handler", "张三");
detail.put("handleTime", "2023-12-01 10:00:00");
detail.put("remark", "添加了15种设备");
}
return detail;
} catch (Exception e) {
return null;
}
}
// 获取流程历史
private List<Map<String, Object>> getProcessHistory(String taskId) {
List<Map<String, Object>> history = new ArrayList<>();
// 这里查询流程历史记录表
// 示例SQL
// String sql = "SELECT node_id, node_name, handler, handle_time, remark " +
// "FROM process_history WHERE task_id = ? ORDER BY handle_time";
// List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, taskId);
// 返回模拟数据
history.add(createHistoryItem("创建申请", "张三", "2023-12-01 09:30", "提交采购申请"));
history.add(createHistoryItem("添加设备", "张三", "2023-12-01 10:00", "添加设备明细"));
return history;
}
private Map<String, Object> createHistoryItem(String node, String handler, String time, String remark) {
Map<String, Object> item = new HashMap<>();
item.put("node", node);
item.put("handler", handler);
item.put("time", time);
item.put("remark", remark);
return item;
}
// 计算进度
private Map<String, Object> calculateProgress(int currentStatus, int totalNodes) {
Map<String, Object> progress = new HashMap<>();
int percentage = (int) ((currentStatus - 1) * 100.0 / (totalNodes - 1));
percentage = Math.max(0, Math.min(100, percentage));
progress.put("percentage", percentage);
progress.put("currentStep", currentStatus);
progress.put("totalSteps", totalNodes);
progress.put("currentStepName", getStepName(currentStatus));
progress.put("nextStepName", getStepName(currentStatus + 1));
return progress;
}
private String getStepName(int step) {
switch (step) {
case 1: return "创建申请";
case 2: return "添加设备";
case 3: return "待验收";
case 4: return "待入库";
case 5: return "待审核";
case 6: return "已完成";
default: return "未知步骤";
}
}
private String getStatusText(String status) {
if (status == null) return "未知状态";
switch (status) {
case "0": return "草稿";
case "1": return "待添加采购明细";
case "2": return "待采购验收";
case "3": return "待上传验收附件";
case "4": return "待财务审核";
case "5": return "待领导审批";
case "6": return "已采购完成";
case "-1": return "已取消";
case "-2": return "已驳回";
default: return "未知状态";
}
}
}