|
|
@@ -11,6 +11,9 @@ import com.jeeplus.common.utils.excel.ExportExcel;
|
|
|
import com.jeeplus.common.utils.excel.ExportKnowledgeBaseExcel;
|
|
|
import com.jeeplus.common.web.BaseController;
|
|
|
import com.jeeplus.modules.WorkKnowledgeBase.entity.UserPointDetail;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WkPointSnapshotDetail;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WkPointSnapshotInfo;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WkPointSnapshotSummary;
|
|
|
import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBasePoint;
|
|
|
import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgeBasePointRule;
|
|
|
import com.jeeplus.modules.WorkKnowledgeBase.dao.WorkKnowledgeBasePointRuleDao;
|
|
|
@@ -19,6 +22,8 @@ import com.jeeplus.modules.WorkKnowledgeBase.service.WorkKnowledgeBasePointExcha
|
|
|
import com.jeeplus.modules.WorkKnowledgeBase.service.WorkKnowledgeBasePointService;
|
|
|
import com.jeeplus.modules.WorkKnowledgeBase.service.WorkKnowledgeBaseTreeService;
|
|
|
import com.jeeplus.modules.WorkKnowledgeBase.service.WorkKnowledgePointCategoryService;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.entity.WorkKnowledgePointCategory;
|
|
|
+import com.jeeplus.modules.WorkKnowledgeBase.service.WkPointSnapshotService;
|
|
|
import com.jeeplus.modules.sys.entity.User;
|
|
|
import com.jeeplus.modules.sys.service.OfficeService;
|
|
|
import com.jeeplus.modules.sys.utils.UserUtils;
|
|
|
@@ -70,13 +75,16 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
@Autowired
|
|
|
private WorkKnowledgeBasePointRuleDao pointRuleDao;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private WkPointSnapshotService wkPointSnapshotService;
|
|
|
+
|
|
|
@ModelAttribute
|
|
|
- public WorkKnowledgeBasePoint get(@RequestParam(required=false) String id) {
|
|
|
+ public WorkKnowledgeBasePoint get(@RequestParam(required = false) String id) {
|
|
|
WorkKnowledgeBasePoint entity = null;
|
|
|
- if (StringUtils.isNotBlank(id)){
|
|
|
+ if (StringUtils.isNotBlank(id)) {
|
|
|
entity = workKnowledgeBasePointService.get(id);
|
|
|
}
|
|
|
- if (entity == null){
|
|
|
+ if (entity == null) {
|
|
|
entity = new WorkKnowledgeBasePoint();
|
|
|
}
|
|
|
return entity;
|
|
|
@@ -89,8 +97,8 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
@RequestMapping(value = {"list", ""})
|
|
|
public String list(WorkKnowledgeBasePoint workKnowledgeBasePoint, HttpServletRequest request, HttpServletResponse response, Model model) {
|
|
|
//进行查询之后进行任何操作,返回还是查询之后的数据页面
|
|
|
- if (StringUtils.isNotBlank(workKnowledgeBasePoint.getToflag())){
|
|
|
- if (workKnowledgeBasePoint.getToflag().equals("1")){
|
|
|
+ if (StringUtils.isNotBlank(workKnowledgeBasePoint.getToflag())) {
|
|
|
+ if (workKnowledgeBasePoint.getToflag().equals("1")) {
|
|
|
request.getSession().removeAttribute("searchPoint");
|
|
|
WorkKnowledgeBasePoint searchPoint = workKnowledgeBasePoint;
|
|
|
request.getSession().setAttribute("searchPoint", searchPoint);
|
|
|
@@ -99,14 +107,14 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
//判断经办人是否为空,为空则赋值为null 防止查找为空的数据
|
|
|
String userId = null;
|
|
|
String userName = null;
|
|
|
- if(StringUtils.isBlank(workKnowledgeBasePoint.getSubmitterName())){
|
|
|
+ if (StringUtils.isBlank(workKnowledgeBasePoint.getSubmitterName())) {
|
|
|
workKnowledgeBasePoint.setSubmitterName(null);
|
|
|
workKnowledgeBasePoint.setSubmitterId(null);
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
//如果ID和名称都有值,说明是通过选择器选的精确查询
|
|
|
- if(StringUtils.isNotBlank(workKnowledgeBasePoint.getSubmitterId())){
|
|
|
+ if (StringUtils.isNotBlank(workKnowledgeBasePoint.getSubmitterId())) {
|
|
|
userId = workKnowledgeBasePoint.getSubmitterId();
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
//如果经办人名称有值但ID为空,说明是手动输入的模糊查询
|
|
|
userName = workKnowledgeBasePoint.getSubmitterName();
|
|
|
}
|
|
|
@@ -114,9 +122,9 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
|
|
|
User user = UserUtils.getUser();
|
|
|
Subject subject = SecurityUtils.getSubject();
|
|
|
- if(user.isAdmin() || subject.isPermitted("workKnowledgeBase:point:listAll")){
|
|
|
+ if (user.isAdmin() || subject.isPermitted("workKnowledgeBase:point:listAll")) {
|
|
|
workKnowledgeBasePoint.setIsAdmin("admin");
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
workKnowledgeBasePoint.setIsAdmin("user");
|
|
|
// 普通用户只能查看自己的积分,设置当前用户ID
|
|
|
workKnowledgeBasePoint.setUserId(user.getId());
|
|
|
@@ -135,7 +143,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
/**
|
|
|
* 查看,增加,编辑知识库积分管理表单页面
|
|
|
*/
|
|
|
- @RequiresPermissions(value={"workKnowledgeBase:point:view","workKnowledgeBase:point:add","workKnowledgeBase:point:edit"},logical= Logical.OR)
|
|
|
+ @RequiresPermissions(value = {"workKnowledgeBase:point:view", "workKnowledgeBase:point:add", "workKnowledgeBase:point:edit"}, logical = Logical.OR)
|
|
|
@RequestMapping(value = "form")
|
|
|
public String form(WorkKnowledgeBasePoint workKnowledgeBasePoint, Model model) {
|
|
|
model.addAttribute("workKnowledgeBasePoint", workKnowledgeBasePoint);
|
|
|
@@ -145,16 +153,16 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
/**
|
|
|
* 保存知识库积分管理
|
|
|
*/
|
|
|
- @RequiresPermissions(value={"workKnowledgeBase:point:add","workKnowledgeBase:point:edit"},logical=Logical.OR)
|
|
|
+ @RequiresPermissions(value = {"workKnowledgeBase:point:add", "workKnowledgeBase:point:edit"}, logical = Logical.OR)
|
|
|
@RequestMapping(value = "save")
|
|
|
- public String save(WorkKnowledgeBasePoint workKnowledgeBasePoint, Model model, RedirectAttributes redirectAttributes) throws Exception{
|
|
|
- if (!beanValidator(model, workKnowledgeBasePoint)){
|
|
|
+ public String save(WorkKnowledgeBasePoint workKnowledgeBasePoint, Model model, RedirectAttributes redirectAttributes) throws Exception {
|
|
|
+ if (!beanValidator(model, workKnowledgeBasePoint)) {
|
|
|
return form(workKnowledgeBasePoint, model);
|
|
|
}
|
|
|
|
|
|
workKnowledgeBasePointService.save(workKnowledgeBasePoint);
|
|
|
addMessage(redirectAttributes, "保存知识库积分管理成功");
|
|
|
- return "redirect:"+ Global.getAdminPath()+"/workKnowledgeBase/point/?repage";
|
|
|
+ return "redirect:" + Global.getAdminPath() + "/workKnowledgeBase/point/?repage";
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -166,7 +174,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
workKnowledgeBasePointService.delete(workKnowledgeBasePoint);
|
|
|
addMessage(redirectAttributes, "删除知识库积分管理成功");
|
|
|
|
|
|
- return "redirect:"+Global.getAdminPath()+"/workKnowledgeBase/point/?repage";
|
|
|
+ return "redirect:" + Global.getAdminPath() + "/workKnowledgeBase/point/?repage";
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -186,7 +194,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
Page<UserPointDetail> page = workKnowledgeBasePointDetailService.findUserPointDetailPage(new Page<>(request, response), userPointDetail);
|
|
|
// 查询该用户在当前分类(含子节点)下的积分总和(根据积分类型筛选)
|
|
|
int totalPoint = workKnowledgeBasePointDetailService.sumUserPointByColumnId(
|
|
|
- userPointDetail.getUserId(), userPointDetail.getColumnId(), userPointDetail.getPointType());
|
|
|
+ userPointDetail.getUserId(), userPointDetail.getColumnId(), userPointDetail.getPointType());
|
|
|
model.addAttribute("page", page);
|
|
|
model.addAttribute("userPointDetail", userPointDetail);
|
|
|
model.addAttribute("totalPoint", totalPoint);
|
|
|
@@ -195,12 +203,13 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
|
|
|
/**
|
|
|
* 预览兑换明细(只读,不写DB,返回JSON)
|
|
|
+ *
|
|
|
* @param exchangeType 兑换类型:basic-基础积分, contribution-贡献积分
|
|
|
*/
|
|
|
@RequiresPermissions("workKnowledgeBase:point:listAll")
|
|
|
@RequestMapping(value = "previewExchange")
|
|
|
@ResponseBody
|
|
|
- public Map<String, Object> previewExchange(@RequestParam(required=false) String exchangeType) {
|
|
|
+ public Map<String, Object> previewExchange(@RequestParam(required = false) String exchangeType) {
|
|
|
Map<String, Object> result = new HashMap<>();
|
|
|
try {
|
|
|
if (StringUtils.isBlank(exchangeType)) {
|
|
|
@@ -220,11 +229,12 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
|
|
|
/**
|
|
|
* 预览兑换明细页面(iframe弹窗用)
|
|
|
+ *
|
|
|
* @param exchangeType 兑换类型:basic-基础积分, contribution-贡献积分
|
|
|
*/
|
|
|
@RequiresPermissions("workKnowledgeBase:point:listAll")
|
|
|
@RequestMapping(value = "previewExchangePage")
|
|
|
- public String previewExchangePage(@RequestParam(required=false) String exchangeType, Model model) {
|
|
|
+ public String previewExchangePage(@RequestParam(required = false) String exchangeType, Model model) {
|
|
|
if (StringUtils.isBlank(exchangeType)) {
|
|
|
exchangeType = "basic";
|
|
|
}
|
|
|
@@ -241,20 +251,21 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
|
|
|
/**
|
|
|
* 批量兑换积分并导出Excel
|
|
|
+ *
|
|
|
* @param exchangeType 兑换类型:basic-基础积分, contribution-贡献积分
|
|
|
*/
|
|
|
@RequiresPermissions("workKnowledgeBase:point:listAll")
|
|
|
@RequestMapping(value = "exportExchange")
|
|
|
- public String exportExchange(@RequestParam(required=false) String exchangeType,
|
|
|
+ public String exportExchange(@RequestParam(required = false) String exchangeType,
|
|
|
HttpServletResponse response, RedirectAttributes redirectAttributes) {
|
|
|
try {
|
|
|
// 默认兑换基础积分
|
|
|
if (StringUtils.isBlank(exchangeType)) {
|
|
|
exchangeType = "basic";
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
System.out.println("========== 开始导出积分兑换,类型:" + exchangeType + " ==========");
|
|
|
-
|
|
|
+
|
|
|
// 执行批量兑换并获取导出数据
|
|
|
List<WorkKnowledgeBasePoint> exportList = pointExchangeService.batchExchangeForExport(exchangeType);
|
|
|
System.out.println("========== 导出数据条数:" + (exportList != null ? exportList.size() : 0) + " ==========");
|
|
|
@@ -287,7 +298,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
exportExcel.addCell(row, col++, item.getUserName(), 2, String.class);
|
|
|
exportExcel.addCell(row, col++, item.getOfficeName(), 2, String.class);
|
|
|
exportExcel.addCell(row, col++, item.getMobile() != null ? item.getMobile() : (item.getPhone() != null ? item.getPhone() : ""), 2, String.class);
|
|
|
-
|
|
|
+
|
|
|
// 根据兑换类型添加对应列
|
|
|
if ("basic".equals(exchangeType)) {
|
|
|
// 基础积分兑换:显示可兑换积分、基础积分兑换量、兑换后剩余积分
|
|
|
@@ -346,6 +357,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
Set<Integer> directRuleIndices = new HashSet<>(); // 直接规则L2(无子分类的L1下的规则)
|
|
|
Set<Integer> subtotalIndices = new HashSet<>(); // 汇总列索引
|
|
|
Set<Integer> remainingIndices = new HashSet<>(); // 未兑换积分列索引
|
|
|
+ Set<Integer> deductionIndices = new HashSet<>(); // 扣除积分列索引(仅贡献积分组)
|
|
|
Map<Integer, Integer> exchangeColumnIndexMap = new HashMap<>(); // L1索引 -> 已兑换积分列的j索引
|
|
|
List<List<String>> secondLevelCategoryIds = new ArrayList<>(); // 每个L1对应的L2 categoryId列表
|
|
|
List<List<String>> directRuleIds = new ArrayList<>(); // 每个L1对应的直接规则ruleId列表
|
|
|
@@ -387,6 +399,10 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
remainingIndices.add(i * 1000 + j);
|
|
|
catIdsForL1.add("");
|
|
|
drIdsForL1.add("");
|
|
|
+ } else if ("deduction".equals(km.get("type"))) {
|
|
|
+ deductionIndices.add(i * 1000 + j);
|
|
|
+ catIdsForL1.add("");
|
|
|
+ drIdsForL1.add("");
|
|
|
} else {
|
|
|
// exchange类型,记录该L1组的exchange列索引
|
|
|
exchangeColumnIndexMap.put(i, j);
|
|
|
@@ -417,20 +433,28 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
|
|
|
// 3. 收集用户ID
|
|
|
List<String> userIds = employeeList.stream()
|
|
|
- .map(WorkKnowledgeBasePoint::getUserId)
|
|
|
- .filter(StringUtils::isNotBlank)
|
|
|
- .collect(Collectors.toList());
|
|
|
+ .map(WorkKnowledgeBasePoint::getUserId)
|
|
|
+ .filter(StringUtils::isNotBlank)
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
|
- // 4a. 按rule分组积分(point>0)
|
|
|
+ // 4a. 按rule分组积分(包含负数扣分)
|
|
|
java.util.Map<String, java.util.Map<String, Integer>> pointsByRule = new java.util.HashMap<>();
|
|
|
+ // 扣分标准(category_id=10)的积分单独汇总,归入贡献积分小计
|
|
|
+ java.util.Map<String, Integer> deductionByUser = new java.util.HashMap<>();
|
|
|
if (!userIds.isEmpty()) {
|
|
|
List<java.util.Map<String, Object>> ruleResults =
|
|
|
- workKnowledgeBasePointDetailService.sumPointsByRuleGrouped(userIds, queryParam.getBeginDate(), queryParam.getEndDate());
|
|
|
+ workKnowledgeBasePointDetailService.sumPointsByRuleGrouped(userIds, queryParam.getBeginDate(), queryParam.getEndDate());
|
|
|
for (java.util.Map<String, Object> r : ruleResults) {
|
|
|
String uid = (String) r.get("userId");
|
|
|
+ String catId = String.valueOf(r.get("categoryId"));
|
|
|
String rid = String.valueOf(r.get("ruleId"));
|
|
|
int pts = ((Number) r.get("totalPoint")).intValue();
|
|
|
- pointsByRule.computeIfAbsent(uid, k -> new java.util.HashMap<>()).put(rid, pts);
|
|
|
+ if ("10".equals(catId)) {
|
|
|
+ // 扣分标准的积分单独汇总
|
|
|
+ deductionByUser.merge(uid, pts, Integer::sum);
|
|
|
+ } else {
|
|
|
+ pointsByRule.computeIfAbsent(uid, k -> new java.util.HashMap<>()).put(rid, pts);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -459,7 +483,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
java.util.Map<String, java.util.Map<String, Integer>> exchangeByL1 = new java.util.HashMap<>();
|
|
|
if (!userIds.isEmpty()) {
|
|
|
List<java.util.Map<String, Object>> exResults =
|
|
|
- workKnowledgeBasePointDetailService.sumExchangeByFirstLevelCategory(userIds, queryParam.getBeginDate(), queryParam.getEndDate());
|
|
|
+ workKnowledgeBasePointDetailService.sumExchangeByFirstLevelCategory(userIds, queryParam.getBeginDate(), queryParam.getEndDate());
|
|
|
for (java.util.Map<String, Object> r : exResults) {
|
|
|
String uid = (String) r.get("userId");
|
|
|
String lid = String.valueOf(r.get("firstLevelId"));
|
|
|
@@ -498,7 +522,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
if (directRuleIndices.contains(i * 1000 + j)) {
|
|
|
// 直接规则L2(如"基础积分"下的规则),直接从pointsByRule取数据
|
|
|
String ruleId = (i < directRuleIds.size() && j < directRuleIds.get(i).size())
|
|
|
- ? directRuleIds.get(i).get(j) : "";
|
|
|
+ ? directRuleIds.get(i).get(j) : "";
|
|
|
int drVal = emps.stream().mapToInt(e -> {
|
|
|
java.util.Map<String, Integer> m = pointsByRule.get(e.getUserId());
|
|
|
return m != null && m.containsKey(ruleId) ? m.get(ruleId) : 0;
|
|
|
@@ -507,7 +531,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
} else if (l2LeafIndices.contains(i * 1000 + j)) {
|
|
|
// L2叶子列(如"阅读"、"点赞"),使用L2级汇总数据
|
|
|
String catId = (i < secondLevelCategoryIds.size() && j < secondLevelCategoryIds.get(i).size())
|
|
|
- ? secondLevelCategoryIds.get(i).get(j) : "";
|
|
|
+ ? secondLevelCategoryIds.get(i).get(j) : "";
|
|
|
int leafVal = emps.stream().mapToInt(e -> {
|
|
|
java.util.Map<String, Integer> m = l2PointsByCategory.get(e.getUserId());
|
|
|
return m != null && m.containsKey(catId) ? m.get(catId) : 0;
|
|
|
@@ -519,6 +543,12 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
} else if (remainingIndices.contains(i * 1000 + j)) {
|
|
|
// 未兑换积分列(占位符,后面计算 subtotal - exchange)
|
|
|
row.put("remaining_" + i, 0);
|
|
|
+ } else if (deductionIndices.contains(i * 1000 + j)) {
|
|
|
+ // 扣除积分列(仅贡献积分组),从deductionByUser取数据
|
|
|
+ int dedVal = emps.stream().mapToInt(e ->
|
|
|
+ deductionByUser.getOrDefault(e.getUserId(), 0)
|
|
|
+ ).sum();
|
|
|
+ row.put("exchange_" + i + "_" + j, dedVal);
|
|
|
} else {
|
|
|
// 已兑换积分列
|
|
|
int exVal = emps.stream().mapToInt(e -> {
|
|
|
@@ -530,8 +560,8 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
} else {
|
|
|
for (int k = 0; k < l3ForL2.size(); k++) {
|
|
|
String ruleKey = (i < dataKeysL3.size() && j < dataKeysL3.get(i).size()
|
|
|
- && k < dataKeysL3.get(i).get(j).size())
|
|
|
- ? dataKeysL3.get(i).get(j).get(k) : "";
|
|
|
+ && k < dataKeysL3.get(i).get(j).size())
|
|
|
+ ? dataKeysL3.get(i).get(j).get(k) : "";
|
|
|
String ruleId = ruleKey.startsWith("rule_") ? ruleKey.substring(5) : "";
|
|
|
int ruleVal = emps.stream().mapToInt(e -> {
|
|
|
java.util.Map<String, Integer> m = pointsByRule.get(e.getUserId());
|
|
|
@@ -548,8 +578,8 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
if (subtotalIndices.contains(i * 1000 + j) || remainingIndices.contains(i * 1000 + j)) {
|
|
|
// 跳过汇总列和未兑换积分列本身
|
|
|
continue;
|
|
|
- } else if (directRuleIndices.contains(i * 1000 + j) || l2LeafIndices.contains(i * 1000 + j)) {
|
|
|
- // 直接规则L2或L2叶子列,直接取值
|
|
|
+ } else if (directRuleIndices.contains(i * 1000 + j) || l2LeafIndices.contains(i * 1000 + j) || deductionIndices.contains(i * 1000 + j)) {
|
|
|
+ // 直接规则L2、L2叶子列、扣除积分列,直接取值
|
|
|
Object v = row.get("exchange_" + i + "_" + j);
|
|
|
if (v instanceof Number) subtotal += ((Number) v).intValue();
|
|
|
} else if (!l3ForL2.isEmpty()) {
|
|
|
@@ -584,7 +614,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
companyRow.put("label", "公司汇总");
|
|
|
companyData.add(companyRow);
|
|
|
excel.addTripleHeaderSheet("公司级", "公司级积分统计汇总" + dateRangeSuffix,
|
|
|
- prefixHeadersCompany, firstLevelHeaders, secondLevelHeaders, thirdLevelHeaders, companyData);
|
|
|
+ prefixHeadersCompany, firstLevelHeaders, secondLevelHeaders, thirdLevelHeaders, companyData);
|
|
|
|
|
|
// ========== 2. 部门级汇总 ==========
|
|
|
Map<String, List<WorkKnowledgeBasePoint>> deptMap = new LinkedHashMap<>();
|
|
|
@@ -599,7 +629,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
deptData.add(row);
|
|
|
}
|
|
|
excel.addTripleHeaderSheet("部门级", "部门级积分统计汇总" + dateRangeSuffix,
|
|
|
- prefixHeadersDept, firstLevelHeaders, secondLevelHeaders, thirdLevelHeaders, deptData);
|
|
|
+ prefixHeadersDept, firstLevelHeaders, secondLevelHeaders, thirdLevelHeaders, deptData);
|
|
|
|
|
|
// ========== 3. 员工级明细 ==========
|
|
|
List<Map<String, Object>> empData = new ArrayList<>();
|
|
|
@@ -610,7 +640,7 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
empData.add(row);
|
|
|
}
|
|
|
excel.addTripleHeaderSheet("员工级", "员工级积分统计明细" + dateRangeSuffix,
|
|
|
- prefixHeadersAll, firstLevelHeaders, secondLevelHeaders, thirdLevelHeaders, empData);
|
|
|
+ prefixHeadersAll, firstLevelHeaders, secondLevelHeaders, thirdLevelHeaders, empData);
|
|
|
|
|
|
String fileName = "知识库统计表_" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
|
|
|
excel.write(response, fileName);
|
|
|
@@ -621,4 +651,295 @@ public class WorkKnowledgeBasePointController extends BaseController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 知识库积分看板页面(从知识库管理菜单进入,可选择月份)
|
|
|
+ */
|
|
|
+ @RequiresPermissions("workKnowledgeBase:point:list")
|
|
|
+ @RequestMapping(value = "dashboard")
|
|
|
+ public String dashboard(Model model) {
|
|
|
+ // 默认显示上个月
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
+ cal.add(Calendar.MONTH, -1);
|
|
|
+ int defaultYear = cal.get(Calendar.YEAR);
|
|
|
+ int defaultMonth = cal.get(Calendar.MONTH) + 1;
|
|
|
+ model.addAttribute("defaultYear", defaultYear);
|
|
|
+ model.addAttribute("defaultMonth", defaultMonth);
|
|
|
+ return "modules/WorkKnowledgeBase/workKnowledgeBasePointDashboard";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 看板数据接口(公司级+部门级汇总)
|
|
|
+ */
|
|
|
+ @RequiresPermissions("workKnowledgeBase:point:list")
|
|
|
+ @RequestMapping(value = "dashboardData")
|
|
|
+ @ResponseBody
|
|
|
+ public Map<String, Object> dashboardData(Integer year, Integer month) {
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ try {
|
|
|
+ List<WkPointSnapshotSummary> dataList = wkPointSnapshotService.getDashboardData(year, month);
|
|
|
+ // 分离公司级和部门级数据
|
|
|
+ List<WkPointSnapshotSummary> companyData = new ArrayList<>();
|
|
|
+ List<WkPointSnapshotSummary> deptData = new ArrayList<>();
|
|
|
+ for (WkPointSnapshotSummary item : dataList) {
|
|
|
+ if ("1".equals(item.getGradeType())) {
|
|
|
+ companyData.add(item);
|
|
|
+ } else if ("2".equals(item.getGradeType())) {
|
|
|
+ deptData.add(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询所有员工快照明细,聚合贡献积分各列(field3-field14)
|
|
|
+ List<WkPointSnapshotInfo> allInfos = wkPointSnapshotService.getAllEmployeeInfos(year, month);
|
|
|
+ // 公司级聚合(field1~field15全部聚合)
|
|
|
+ Map<String, Integer> companyContrib = new LinkedHashMap<>();
|
|
|
+ for (int f = 1; f <= 15; f++) companyContrib.put("field" + f, 0);
|
|
|
+ for (WkPointSnapshotInfo info : allInfos) {
|
|
|
+ for (int f = 1; f <= 15; f++) {
|
|
|
+ String val = getFieldValue(info, f);
|
|
|
+ companyContrib.merge("field" + f, parseInt(val), Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 部门级聚合(按officeId分组)
|
|
|
+ Map<String, Map<String, Integer>> deptContribMap = new LinkedHashMap<>();
|
|
|
+ for (WkPointSnapshotInfo info : allInfos) {
|
|
|
+ String oid = info.getOfficeId() != null ? info.getOfficeId() : "";
|
|
|
+ Map<String, Integer> deptContrib = deptContribMap.computeIfAbsent(oid, k -> {
|
|
|
+ Map<String, Integer> m = new LinkedHashMap<>();
|
|
|
+ for (int f = 1; f <= 15; f++) m.put("field" + f, 0);
|
|
|
+ return m;
|
|
|
+ });
|
|
|
+ for (int f = 1; f <= 15; f++) {
|
|
|
+ String val = getFieldValue(info, f);
|
|
|
+ deptContrib.merge("field" + f, parseInt(val), Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ result.put("success", true);
|
|
|
+ result.put("companyData", companyData);
|
|
|
+ result.put("deptData", deptData);
|
|
|
+ result.put("companyContrib", companyContrib);
|
|
|
+ result.put("deptContribMap", deptContribMap);
|
|
|
+
|
|
|
+ // 构建L2分类名称→ID映射,供前端钻取查询使用
|
|
|
+ Map<String, String> l2CategoryIdMap = new LinkedHashMap<>();
|
|
|
+ List<WorkKnowledgePointCategory> firstLevelList = workKnowledgePointCategoryService.findFirstLevelList();
|
|
|
+ for (WorkKnowledgePointCategory fl : firstLevelList) {
|
|
|
+ List<WorkKnowledgePointCategory> children = workKnowledgePointCategoryService.findChildrenByParentId(fl.getId());
|
|
|
+ for (WorkKnowledgePointCategory child : children) {
|
|
|
+ l2CategoryIdMap.put(child.getCategoryName(), child.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ result.put("l2CategoryIdMap", l2CategoryIdMap);
|
|
|
+ } catch (Exception e) {
|
|
|
+ result.put("success", false);
|
|
|
+ result.put("message", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getFieldValue(WkPointSnapshotInfo info, int fieldNum) {
|
|
|
+ switch (fieldNum) {
|
|
|
+ case 1: return info.getField1();
|
|
|
+ case 2: return info.getField2();
|
|
|
+ case 3: return info.getField3();
|
|
|
+ case 4: return info.getField4();
|
|
|
+ case 5: return info.getField5();
|
|
|
+ case 6: return info.getField6();
|
|
|
+ case 7: return info.getField7();
|
|
|
+ case 8: return info.getField8();
|
|
|
+ case 9: return info.getField9();
|
|
|
+ case 10: return info.getField10();
|
|
|
+ case 11: return info.getField11();
|
|
|
+ case 12: return info.getField12();
|
|
|
+ case 13: return info.getField13();
|
|
|
+ case 14: return info.getField14();
|
|
|
+ case 15: return info.getField15();
|
|
|
+ default: return "0";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private int parseInt(String val) {
|
|
|
+ if (val == null || val.isEmpty()) return 0;
|
|
|
+ try { return Integer.parseInt(val); } catch (NumberFormatException e) { return 0; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 部门员工明细子页面(iframe弹窗用)
|
|
|
+ */
|
|
|
+ @RequiresPermissions("workKnowledgeBase:point:list")
|
|
|
+ @RequestMapping(value = "deptEmployeesPage")
|
|
|
+ public String deptEmployeesPage(Integer year, Integer month, String officeId, String officeName,
|
|
|
+ String submitterId, String submitterName,
|
|
|
+ String searchOfficeId, String searchOfficeName,
|
|
|
+ Model model) {
|
|
|
+ // 树形部门选择器覆盖初始officeId
|
|
|
+ String effectiveOfficeId = StringUtils.isNotBlank(searchOfficeId) ? searchOfficeId : officeId;
|
|
|
+ String effectiveOfficeName = StringUtils.isNotBlank(searchOfficeName) ? searchOfficeName : officeName;
|
|
|
+ // 人员筛选:优先用ID精确匹配,否则用名称模糊查询
|
|
|
+ String filterUserId = StringUtils.isNotBlank(submitterId) ? submitterId : null;
|
|
|
+ String filterUserName = StringUtils.isNotBlank(submitterId) ? null : submitterName;
|
|
|
+ List<WkPointSnapshotInfo> empList = wkPointSnapshotService.getDepartmentEmployeeInfos(year, month, effectiveOfficeId, filterUserId, filterUserName, null);
|
|
|
+ List<WkPointSnapshotSummary> summaryList = wkPointSnapshotService.getDepartmentEmployees(year, month, effectiveOfficeId, filterUserId, filterUserName, null);
|
|
|
+ // 按userId构建Summary映射,方便JSP通过员工field取汇总值
|
|
|
+ Map<String, WkPointSnapshotSummary> summaryMap = new LinkedHashMap<>();
|
|
|
+ for (WkPointSnapshotSummary s : summaryList) {
|
|
|
+ summaryMap.put(s.getUserId(), s);
|
|
|
+ }
|
|
|
+ model.addAttribute("empList", empList);
|
|
|
+ model.addAttribute("summaryMap", summaryMap);
|
|
|
+ model.addAttribute("year", year);
|
|
|
+ model.addAttribute("month", month);
|
|
|
+ model.addAttribute("officeId", effectiveOfficeId != null ? effectiveOfficeId : "");
|
|
|
+ model.addAttribute("officeName", effectiveOfficeName != null ? effectiveOfficeName : "");
|
|
|
+ model.addAttribute("submitterId", submitterId != null ? submitterId : "");
|
|
|
+ model.addAttribute("submitterName", submitterName != null ? submitterName : "");
|
|
|
+ model.addAttribute("searchOfficeId", searchOfficeId != null ? searchOfficeId : "");
|
|
|
+ model.addAttribute("searchOfficeName", searchOfficeName != null ? searchOfficeName : "");
|
|
|
+ // 计算日期范围用于显示
|
|
|
+ if (year != null && month != null) {
|
|
|
+ String beginDate = String.format("%04d-%02d-01", year, month);
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
+ cal.set(year, month - 1, 1);
|
|
|
+ int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
|
|
+ String endDate = String.format("%04d-%02d-%02d", year, month, maxDay);
|
|
|
+ model.addAttribute("beginDate", beginDate);
|
|
|
+ model.addAttribute("endDate", endDate);
|
|
|
+ }
|
|
|
+ // L2分类名称→ID映射,供员工明细页钻取使用
|
|
|
+ Map<String, String> l2CategoryIdMap = new LinkedHashMap<>();
|
|
|
+ List<WorkKnowledgePointCategory> firstLevelList = workKnowledgePointCategoryService.findFirstLevelList();
|
|
|
+ for (WorkKnowledgePointCategory fl : firstLevelList) {
|
|
|
+ List<WorkKnowledgePointCategory> children = workKnowledgePointCategoryService.findChildrenByParentId(fl.getId());
|
|
|
+ for (WorkKnowledgePointCategory child : children) {
|
|
|
+ l2CategoryIdMap.put(child.getCategoryName(), child.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ model.addAttribute("l2CategoryIdMap", l2CategoryIdMap);
|
|
|
+ return "modules/WorkKnowledgeBase/workKnowledgeBasePointDeptEmployees";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 部门下员工数据接口(返回快照明细,含field3-field14贡献积分明细)
|
|
|
+ */
|
|
|
+ @RequiresPermissions("workKnowledgeBase:point:list")
|
|
|
+ @RequestMapping(value = "departmentEmployees")
|
|
|
+ @ResponseBody
|
|
|
+ public Map<String, Object> departmentEmployees(Integer year, Integer month, String officeId) {
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ try {
|
|
|
+ List<WkPointSnapshotInfo> empList = wkPointSnapshotService.getDepartmentEmployeeInfos(year, month, officeId, null, null, null);
|
|
|
+ result.put("success", true);
|
|
|
+ result.put("data", empList);
|
|
|
+ } catch (Exception e) {
|
|
|
+ result.put("success", false);
|
|
|
+ result.put("message", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 员工快照详情接口
|
|
|
+ */
|
|
|
+ @RequiresPermissions("workKnowledgeBase:point:list")
|
|
|
+ @RequestMapping(value = "employeeSnapshot")
|
|
|
+ @ResponseBody
|
|
|
+ public Map<String, Object> employeeSnapshot(Integer year, Integer month, String userId) {
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ try {
|
|
|
+ WkPointSnapshotInfo info = wkPointSnapshotService.getEmployeeSnapshot(year, month, userId);
|
|
|
+ result.put("success", true);
|
|
|
+ result.put("data", info);
|
|
|
+ } catch (Exception e) {
|
|
|
+ result.put("success", false);
|
|
|
+ result.put("message", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 积分钻取明细页面(从快照明细表查询,确保与看板数字一致)
|
|
|
+ */
|
|
|
+ @RequiresPermissions("workKnowledgeBase:point:list")
|
|
|
+ @RequestMapping(value = "pointDrillDown")
|
|
|
+ public String pointDrillDown(Integer year, Integer month, String officeId, String officeName, String userId,
|
|
|
+ String categoryId, String categoryName, Integer ruleType,
|
|
|
+ String columnId, String shareName,
|
|
|
+ String submitterId, String submitterName,
|
|
|
+ String searchOfficeId, String searchOfficeName,
|
|
|
+ HttpServletRequest request, HttpServletResponse response, Model model) {
|
|
|
+ WkPointSnapshotDetail query = new WkPointSnapshotDetail();
|
|
|
+ query.setSnapshotYear(year);
|
|
|
+ query.setSnapshotMonth(month);
|
|
|
+ // 树形选择器覆盖初始值
|
|
|
+ String effectiveOfficeId = StringUtils.isNotBlank(searchOfficeId) ? searchOfficeId : (officeId != null ? officeId : "");
|
|
|
+ String effectiveUserId = StringUtils.isNotBlank(submitterId) ? submitterId : userId;
|
|
|
+ query.setOfficeId(effectiveOfficeId);
|
|
|
+ query.setUserId(effectiveUserId);
|
|
|
+ query.setCategoryId(categoryId);
|
|
|
+ query.setRuleType(ruleType);
|
|
|
+ // columnId="deduction"表示扣除积分钻取,SQL会过滤负积分
|
|
|
+ if ("deduction".equals(columnId)) {
|
|
|
+ query.setColumnId("deduction");
|
|
|
+ }
|
|
|
+ // 文档名称模糊查询
|
|
|
+ if (StringUtils.isNotBlank(shareName)) {
|
|
|
+ query.setShareNameQuery(shareName);
|
|
|
+ }
|
|
|
+ // 人员名称回退:当未选择用户但有输入名称时,用名称模糊查询
|
|
|
+ if (StringUtils.isBlank(submitterId) && StringUtils.isNotBlank(submitterName)) {
|
|
|
+ query.setUserNameQuery(submitterName);
|
|
|
+ }
|
|
|
+ // 部门名称回退:当未选择部门但有输入名称时,用名称模糊查询
|
|
|
+ if (StringUtils.isBlank(searchOfficeId) && StringUtils.isNotBlank(searchOfficeName)) {
|
|
|
+ query.setOfficeNameQuery(searchOfficeName);
|
|
|
+ }
|
|
|
+ Page<WkPointSnapshotDetail> page = wkPointSnapshotService.findDrillDownPage(
|
|
|
+ new Page<>(request, response), query);
|
|
|
+ model.addAttribute("page", page);
|
|
|
+ model.addAttribute("year", year);
|
|
|
+ model.addAttribute("month", month);
|
|
|
+ model.addAttribute("officeId", effectiveOfficeId);
|
|
|
+ model.addAttribute("officeName", officeName != null ? officeName : "");
|
|
|
+ model.addAttribute("userId", effectiveUserId != null ? effectiveUserId : "");
|
|
|
+ model.addAttribute("categoryId", categoryId);
|
|
|
+ model.addAttribute("categoryName", categoryName != null ? categoryName : "");
|
|
|
+ model.addAttribute("ruleType", ruleType);
|
|
|
+ model.addAttribute("columnId", columnId);
|
|
|
+ model.addAttribute("shareName", shareName != null ? shareName : "");
|
|
|
+ model.addAttribute("submitterId", submitterId != null ? submitterId : "");
|
|
|
+ model.addAttribute("submitterName", submitterName != null ? submitterName : "");
|
|
|
+ model.addAttribute("searchOfficeId", searchOfficeId != null ? searchOfficeId : "");
|
|
|
+ model.addAttribute("searchOfficeName", searchOfficeName != null ? searchOfficeName : "");
|
|
|
+ // 计算日期范围用于显示
|
|
|
+ if (year != null && month != null) {
|
|
|
+ String beginDate = String.format("%04d-%02d-01", year, month);
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
+ cal.set(year, month - 1, 1);
|
|
|
+ int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
|
|
+ String endDate = String.format("%04d-%02d-%02d", year, month, maxDay);
|
|
|
+ model.addAttribute("beginDate", beginDate);
|
|
|
+ model.addAttribute("endDate", endDate);
|
|
|
+ }
|
|
|
+ return "modules/WorkKnowledgeBase/workKnowledgeBasePointDrillDown";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 手动触发快照生成(供管理员使用)
|
|
|
+ */
|
|
|
+ @RequiresPermissions("workKnowledgeBase:point:listAll")
|
|
|
+ @RequestMapping(value = "generateSnapshot")
|
|
|
+ @ResponseBody
|
|
|
+ public Map<String, Object> generateSnapshot(Integer year, Integer month) {
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ try {
|
|
|
+ wkPointSnapshotService.generateSnapshot(year, month);
|
|
|
+ result.put("success", true);
|
|
|
+ result.put("message", year + "年" + month + "月快照数据生成成功");
|
|
|
+ } catch (Exception e) {
|
|
|
+ result.put("success", false);
|
|
|
+ result.put("message", "生成失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
}
|