项目结构:

java
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 16:59
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : Const.java
* explain : 学习 类
**/
package DivideConquer.Constants;
import java.util.List;
import java.util.Map;
public class Const {
// 风控阈值 10万元
public static final double RISK_AMOUNT_THRESHOLD = 100000.0;
// 门店列表
public static final List<String> SHOP_LIST = List.of("福田店", "南山店");
// 季度-月份映射
public static final Map<Integer, int[]> QUARTER_MONTH_MAP = Map.of(
1, new int[]{1,2,3},
2, new int[]{4,5,6},
3, new int[]{7,8,9},
4, new int[]{10,11,12}
);
// 品类
public static final List<String> CATEGORY_LIST = List.of("黄金", "钻石", "彩宝", "银饰");
// 权限常量
public static final String PERM_DIAMOND_ADJUST = "钻石调价";
public static final String PERM_EXPORT_ALL_SHOP = "全门店数据导出";
public static final String PERM_SHOP_ADJUST = "本店调价";
public static final String PERM_MODIFY_ROLE = "修改角色权限";
public static final String PERM_VIEW_SELF_SALE = "查看个人业绩";
public static final String PERM_VIEW_STOCK = "库存盘点";
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:01
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : JewelryOrder.java
* explain : 学习 类
**/
package DivideConquer.Entity;
public class JewelryOrder {
private String orderId;
private String shopName;
private int saleMonth;
private int quarter;
private String category;
private double saleAmount;
private double profit;
private String sellerId;
public JewelryOrder() {}
public JewelryOrder(String orderId, String shopName, int saleMonth, int quarter, String category, double saleAmount, double profit, String sellerId) {
this.orderId = orderId;
this.shopName = shopName;
this.saleMonth = saleMonth;
this.quarter = quarter;
this.category = category;
this.saleAmount = saleAmount;
this.profit = profit;
this.sellerId = sellerId;
}
// getter setter
public String getOrderId() { return orderId; }
public void setOrderId(String orderId) { this.orderId = orderId; }
public String getShopName() { return shopName; }
public void setShopName(String shopName) { this.shopName = shopName; }
public int getSaleMonth() { return saleMonth; }
public void setSaleMonth(int saleMonth) { this.saleMonth = saleMonth; }
public int getQuarter() { return quarter; }
public void setQuarter(int quarter) { this.quarter = quarter; }
public String getCategory() { return category; }
public void setCategory(String category) { this.category = category; }
public double getSaleAmount() { return saleAmount; }
public void setSaleAmount(double saleAmount) { this.saleAmount = saleAmount; }
public double getProfit() { return profit; }
public void setProfit(double profit) { this.profit = profit; }
public String getSellerId() { return sellerId; }
public void setSellerId(String sellerId) { this.sellerId = sellerId; }
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:02
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : JewelryRoleNode.java
* explain : 学习 类
**/
package DivideConquer.Entity;
import java.util.List;
public class JewelryRoleNode {
private String roleName;
private List<String> permissions;
private JewelryRoleNode left;
private JewelryRoleNode right;
public JewelryRoleNode() {}
public String getRoleName() { return roleName; }
public void setRoleName(String roleName) { this.roleName = roleName; }
public List<String> getPermissions() { return permissions; }
public void setPermissions(List<String> permissions) { this.permissions = permissions; }
public JewelryRoleNode getLeft() { return left; }
public void setLeft(JewelryRoleNode left) { this.left = left; }
public JewelryRoleNode getRight() { return right; }
public void setRight(JewelryRoleNode right) { this.right = right; }
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:01
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : SaleSummary.java
* explain : 学习 类
**/
package DivideConquer.Entity;
import java.util.HashMap;
import java.util.Map;
public class SaleSummary {
private double totalSales = 0.0;
private double totalProfit = 0.0;
private double gold = 0.0;
private double diamond = 0.0;
private double gem = 0.0;
private double silver = 0.0;
// 合并两个统计结果 Combine
public SaleSummary add(SaleSummary other) {
SaleSummary res = new SaleSummary();
res.totalSales = this.totalSales + other.totalSales;
res.totalProfit = this.totalProfit + other.totalProfit;
res.gold = this.gold + other.gold;
res.diamond = this.diamond + other.diamond;
res.gem = this.gem + other.gem;
res.silver = this.silver + other.silver;
return res;
}
// 单订单生成汇总 Conquer最小单元
public static SaleSummary buildSingleSummary(JewelryOrder order) {
SaleSummary s = new SaleSummary();
s.totalSales = order.getSaleAmount();
s.totalProfit = order.getProfit();
switch (order.getCategory()) {
case "黄金": s.gold = order.getSaleAmount(); break;
case "钻石": s.diamond = order.getSaleAmount(); break;
case "彩宝": s.gem = order.getSaleAmount(); break;
case "银饰": s.silver = order.getSaleAmount(); break;
}
return s;
}
// 转Map打印
public Map<String, Double> toMap() {
Map<String, Double> map = new HashMap<>();
map.put("总销售额", totalSales);
map.put("总毛利", totalProfit);
map.put("黄金", gold);
map.put("钻石", diamond);
map.put("彩宝", gem);
map.put("银饰", silver);
return map;
}
// getter setter
public double getTotalSales() { return totalSales; }
public void setTotalSales(double totalSales) { this.totalSales = totalSales; }
public double getTotalProfit() { return totalProfit; }
public void setTotalProfit(double totalProfit) { this.totalProfit = totalProfit; }
public double getGold() { return gold; }
public void setGold(double gold) { this.gold = gold; }
public double getDiamond() { return diamond; }
public void setDiamond(double diamond) { this.diamond = diamond; }
public double getGem() { return gem; }
public void setGem(double gem) { this.gem = gem; }
public double getSilver() { return silver; }
public void setSilver(double silver) { this.silver = silver; }
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:08
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : OrderRepository.java
* explain : 学习 类
**/
package DivideConquer.Repository;
import DivideConquer.Constants.Const;
import DivideConquer.Entity.JewelryOrder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class OrderRepository {
private final List<JewelryOrder> data = new ArrayList<>();
public void add(JewelryOrder order) {
data.add(order);
}
public void batchAdd(List<JewelryOrder> orders) {
data.addAll(orders);
}
public List<JewelryOrder> getAll() {
return new ArrayList<>(data);
}
// Divide 按门店拆分
public Map<String, List<JewelryOrder>> splitByShop() {
Map<String, List<JewelryOrder>> map = new HashMap<>();
for (String shop : Const.SHOP_LIST) {
map.put(shop, new ArrayList<>());
}
for (JewelryOrder o : data) {
if (map.containsKey(o.getShopName())) {
map.get(o.getShopName()).add(o);
}
}
return map;
}
// Divide 按月份拆分
public Map<Integer, List<JewelryOrder>> splitByMonth() {
Map<Integer, List<JewelryOrder>> map = new HashMap<>();
for (int m = 1; m <= 12; m++) {
map.put(m, new ArrayList<>());
}
for (JewelryOrder o : data) {
map.get(o.getSaleMonth()).add(o);
}
return map;
}
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:10
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : RoleRepository.java
* explain : 学习 类
**/
package DivideConquer.Repository;
import DivideConquer.Entity.JewelryRoleNode;
public class RoleRepository {
private JewelryRoleNode root;
public void setRoot(JewelryRoleNode root) {
this.root = root;
}
public JewelryRoleNode getRoot() {
return root;
}
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:00
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : Util.java
* explain : 学习 类
**/
package DivideConquer.Utils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Util {
// 金额格式化保留两位小数
public static String formatFloat(double val) {
return String.format("%.2f", val);
}
// 多线程批量并行执行任务
public static List<Object> parallelBatchExecute(List<Callable<Object>> tasks) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(4);
List<Future<Object>> futures = pool.invokeAll(tasks);
List<Object> results = new ArrayList<>();
for (Future<Object> f : futures) {
results.add(f.get());
}
pool.shutdown();
return results;
}
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:15
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : PermissionService.java
* explain : 学习 类
**/
package DivideConquer.Service;
import DivideConquer.DAC.PermDAC;
import DivideConquer.Entity.JewelryOrder;
import DivideConquer.Entity.JewelryRoleNode;
import DivideConquer.Repository.RoleRepository;
import java.util.List;
public class PermissionService {
private final RoleRepository repo;
private final PermDAC dac;
public PermissionService(RoleRepository repo) {
this.repo = repo;
this.dac = new PermDAC();
}
public boolean hasPermission(String permKey) {
JewelryRoleNode root = repo.getRoot();
return dac.checkPerm(root, permKey);
}
public List<JewelryOrder> getVisibleOrders(List<JewelryOrder> allOrders, String sellerId) {
JewelryRoleNode root = repo.getRoot();
if (root == null) return List.of();
return dac.filterOrderByPerm(allOrders, root.getPermissions(), sellerId);
}
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:18
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : RiskScreenService.java
* explain : 学习 类
**/
package DivideConquer.Service;
import DivideConquer.DAC.RiskDAC;
import DivideConquer.Entity.JewelryOrder;
import DivideConquer.Repository.OrderRepository;
import java.util.List;
public class RiskScreenService {
private final OrderRepository repo;
private final RiskDAC dac;
public RiskScreenService(OrderRepository repo, double threshold) {
this.repo = repo;
this.dac = new RiskDAC(threshold);
}
public List<JewelryOrder> scanHighAmountOrders() {
List<JewelryOrder> all = repo.getAll();
return dac.scanRisk(all);
}
public void modifyThreshold(double newVal) {
dac.setThreshold(newVal);
}
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:16
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : SaleStatService.java
* explain : 学习 类
**/
package DivideConquer.Service;
import DivideConquer.Constants.Const;
import DivideConquer.DAC.StatDAC;
import DivideConquer.Entity.JewelryOrder;
import DivideConquer.Entity.SaleSummary;
import DivideConquer.Repository.OrderRepository;
import DivideConquer.Utils.Util;
import java.util.*;
import java.util.concurrent.Callable;
public class SaleStatService {
private final OrderRepository repo;
private final StatDAC dac;
public SaleStatService(OrderRepository repo) {
this.repo = repo;
this.dac = new StatDAC();
}
// 多线程并行分治门店统计
public Map<String, SaleSummary> statByShopParallel() throws Exception {
Map<String, List<JewelryOrder>> shopSplit = repo.splitByShop();
List<Callable<Object>> tasks = new ArrayList<>();
List<String> shopNames = new ArrayList<>();
for (Map.Entry<String, List<JewelryOrder>> entry : shopSplit.entrySet()) {
shopNames.add(entry.getKey());
List<JewelryOrder> ords = entry.getValue();
tasks.add(() -> dac.calcTotal(ords));
}
List<Object> resList = Util.parallelBatchExecute(tasks);
Map<String, SaleSummary> shopResult = new HashMap<>();
SaleSummary totalAll = new SaleSummary();
for (int i = 0; i < shopNames.size(); i++) {
SaleSummary sum = (SaleSummary) resList.get(i);
shopResult.put(shopNames.get(i), sum);
totalAll = totalAll.add(sum);
}
shopResult.put("集团全部门店合计", totalAll);
return shopResult;
}
// 按月分治,合并季度、年度
public Map<String, Object> statByTime() {
Map<Integer, List<JewelryOrder>> monthSplit = repo.splitByMonth();
Map<Integer, SaleSummary> monthSummary = new HashMap<>();
for (Map.Entry<Integer, List<JewelryOrder>> kv : monthSplit.entrySet()) {
monthSummary.put(kv.getKey(), dac.calcTotal(kv.getValue()));
}
Map<Integer, SaleSummary> quarterSummary = new HashMap<>();
quarterSummary.put(1, new SaleSummary());
quarterSummary.put(2, new SaleSummary());
quarterSummary.put(3, new SaleSummary());
quarterSummary.put(4, new SaleSummary());
SaleSummary yearTotal = new SaleSummary();
for (Map.Entry<Integer, int[]> qKv : Const.QUARTER_MONTH_MAP.entrySet()) {
int q = qKv.getKey();
for (int m : qKv.getValue()) {
quarterSummary.put(q, quarterSummary.get(q).add(monthSummary.get(m)));
}
}
for (SaleSummary s : monthSummary.values()) {
yearTotal = yearTotal.add(s);
}
Map<String, SaleSummary> monthMap = new HashMap<>();
for (int m = 1; m <= 12; m++) {
monthMap.put(m + "月", monthSummary.get(m));
}
Map<String, Object> ret = new HashMap<>();
ret.put("月度明细", monthMap);
ret.put("季度汇总", quarterSummary);
ret.put("年度总报表", yearTotal);
return ret;
}
}
/**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:19
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : JewelryDACApp.java
* explain : 学习 类
**/
package DivideConquer.App;
import DivideConquer.Constants.Const;
import DivideConquer.Entity.JewelryOrder;
import DivideConquer.Entity.JewelryRoleNode;
import DivideConquer.Entity.SaleSummary;
import DivideConquer.Repository.OrderRepository;
import DivideConquer.Repository.RoleRepository;
import DivideConquer.Service.PermissionService;
import DivideConquer.Service.RiskScreenService;
import DivideConquer.Service.SaleStatService;
import java.util.List;
import java.util.Map;
public class JewelryDACApp {
private final OrderRepository orderRepo;
private final RoleRepository roleRepo;
public final PermissionService permSvc;
public final SaleStatService saleStatSvc;
public final RiskScreenService riskSvc;
public JewelryDACApp() {
orderRepo = new OrderRepository();
roleRepo = new RoleRepository();
permSvc = new PermissionService(roleRepo);
saleStatSvc = new SaleStatService(orderRepo);
riskSvc = new RiskScreenService(orderRepo, Const.RISK_AMOUNT_THRESHOLD);
}
// 订单仓储代理
public void addOrder(JewelryOrder o) {
orderRepo.add(o);
}
public void batchAddOrders(List<JewelryOrder> orders) {
orderRepo.batchAdd(orders);
}
// 权限树初始化
public void buildPermissionTree(JewelryRoleNode root) {
roleRepo.setRoot(root);
}
// 对外业务接口
public boolean checkPermission(String permKey) {
return permSvc.hasPermission(permKey);
}
public List<JewelryOrder> getUserVisibleOrders(String sellerId) {
List<JewelryOrder> all = orderRepo.getAll();
return permSvc.getVisibleOrders(all, sellerId);
}
public Map<String, SaleSummary> queryShopSalesStat() throws Exception {
return saleStatSvc.statByShopParallel();
}
public Map<String, Object> queryTimeSalesStat() {
return saleStatSvc.statByTime();
}
public List<JewelryOrder> queryRiskOrders() {
return riskSvc.scanHighAmountOrders();
}
}
调用:
java
**
* encoding: utf-8
* 版权所有 2026 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述:Divide and Conquer Algorithm
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2026 - 2026/7/19 - 17:21
* User : geovindu
* Product : IntelliJ IDEA
* Project : JavaAlgorithms
* File : DivideConquerBll.java
* explain : 学习 类
**/
package Bll;
import DivideConquer.App.JewelryDACApp;
import DivideConquer.Constants.Const;
import DivideConquer.Entity.JewelryOrder;
import DivideConquer.Entity.JewelryRoleNode;
import DivideConquer.Entity.SaleSummary;
import DivideConquer.Utils.Util;
import java.util.List;
import java.util.Map;
public class DivideConquerBll {
public void Demo()
{
JewelryDACApp app = new JewelryDACApp();
// 模拟测试订单
List<JewelryOrder> mockOrders = List.of(
new JewelryOrder("O001", "福田店", 2, 1, "黄金", 6280, 1300, "S001"),
new JewelryOrder("O002", "福田店", 3, 1, "钻石", 128600, 48000, "S001"),
new JewelryOrder("O003", "南山店", 5, 2, "彩宝", 8900, 3600, "S002"),
new JewelryOrder("O004", "南山店", 6, 2, "钻石", 96000, 39000, "S002"),
new JewelryOrder("O005", "福田店", 9, 3, "银饰", 499, 220, "S003"),
new JewelryOrder("O006", "南山店", 11, 4, "钻石", 156000, 62000, "S004"),
new JewelryOrder("O007", "福田店", 12, 4, "黄金", 8600, 1800, "S003")
);
app.batchAddOrders(mockOrders);
// 构建权限二叉树
JewelryRoleNode guide = new JewelryRoleNode();
guide.setRoleName("门店导购");
guide.setPermissions(List.of(Const.PERM_VIEW_SELF_SALE));
JewelryRoleNode keeper = new JewelryRoleNode();
keeper.setRoleName("仓管");
keeper.setPermissions(List.of(Const.PERM_VIEW_STOCK));
JewelryRoleNode shopMgr = new JewelryRoleNode();
shopMgr.setRoleName("门店店长");
shopMgr.setPermissions(List.of(Const.PERM_SHOP_ADJUST));
shopMgr.setLeft(guide);
shopMgr.setRight(keeper);
JewelryRoleNode areaMgr = new JewelryRoleNode();
areaMgr.setRoleName("华南区域经理");
areaMgr.setPermissions(List.of(Const.PERM_DIAMOND_ADJUST));
areaMgr.setLeft(shopMgr);
JewelryRoleNode groupAdmin = new JewelryRoleNode();
groupAdmin.setRoleName("集团管理员");
groupAdmin.setPermissions(List.of(Const.PERM_EXPORT_ALL_SHOP, Const.PERM_MODIFY_ROLE));
groupAdmin.setLeft(areaMgr);
app.buildPermissionTree(groupAdmin);
// 1. 并行分治门店业绩
System.out.println("======= 【并行分治-门店业绩汇总】 =======");
try {
Map<String, SaleSummary> shopStat = app.queryShopSalesStat();
for (Map.Entry<String, SaleSummary> entry : shopStat.entrySet()) {
System.out.printf("\n【%s】%n", entry.getKey());
Map<String, Double> dataMap = entry.getValue().toMap();
for (Map.Entry<String, Double> d : dataMap.entrySet()) {
System.out.printf("%s: %s%n", d.getKey(), Util.formatFloat(d.getValue()));
}
}
}
catch (Exception e) {
e.printStackTrace();
}
// 2. 时间分治报表
System.out.println("\n======= 【时间分治-年度经营报表】 =======");
Map<String, Object> timeStat = app.queryTimeSalesStat();
SaleSummary yearSum = (SaleSummary) timeStat.get("年度总报表");
System.out.printf("全年总销售额:%s,全年毛利:%s%n", Util.formatFloat(yearSum.getTotalSales()), Util.formatFloat(yearSum.getTotalProfit()));
System.out.println("\n季度汇总:");
Map<Integer, SaleSummary> quarterMap = (Map<Integer, SaleSummary>) timeStat.get("季度汇总");
for (Map.Entry<Integer, SaleSummary> q : quarterMap.entrySet()) {
System.out.printf("Q%d 销售总额:%s%n", q.getKey(), Util.formatFloat(q.getValue().getTotalSales()));
}
// 3. 风控高客单订单
System.out.println("\n======= 【风控分治-超10万异常订单】 =======");
List<JewelryOrder> riskList = app.queryRiskOrders();
if (!riskList.isEmpty()) {
for (JewelryOrder item : riskList) {
System.out.printf("订单%s | %s | %s | %s元%n",
item.getOrderId(), item.getShopName(), item.getCategory(), Util.formatFloat(item.getSaleAmount()));
}
} else {
System.out.println("无风险订单");
}
// 4. 权限校验
System.out.println("\n======= 【树形分治权限校验】 =======");
System.out.printf("区域经理是否可钻石调价:%b%n", app.checkPermission(Const.PERM_DIAMOND_ADJUST));
System.out.printf("店长是否可导出全门店数据:%b%n", app.checkPermission(Const.PERM_EXPORT_ALL_SHOP));
System.out.printf("集团是否可修改角色权限:%b%n", app.checkPermission(Const.PERM_MODIFY_ROLE));
// 5. 导购数据权限过滤
System.out.println("\n======= 【分治数据权限过滤-导购S001可见订单】 =======");
List<JewelryOrder> userOrders = app.getUserVisibleOrders("S001");
for (JewelryOrder o : userOrders) {
System.out.printf("%s | 开单人:%s | %s%n", o.getOrderId(), o.getSellerId(), Util.formatFloat(o.getSaleAmount()));
}
}
}