diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/AuthorizationController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/AuthorizationController.java index 7e64291cf..073486569 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/AuthorizationController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/AuthorizationController.java @@ -74,7 +74,7 @@ public class AuthorizationController { @GetMapping("/permission") public CzgResult getPermission() { - return CzgResult.success(); + return CzgResult.success(StpKit.USER.getPermissionList()); } @Resource @@ -90,7 +90,13 @@ public class AuthorizationController { // rabbitPublisher.sendOrderPrintMsg("552"); // printMqListener.orderPrint("1"); // return CzgResult.success(Map.of("token", StpKit.USER.getShopId())); - return CzgResult.success(shopInfoService.getById(1)); + return CzgResult.success(StpKit.USER.getLoginId()); + } + + @GetMapping("test1") + public CzgResult login1() throws IOException { + authorizationService.switchTo(86L); + return CzgResult.success(StpKit.USER.getLoginId()); } /** diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopBranchController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopBranchController.java new file mode 100644 index 000000000..15ea862d3 --- /dev/null +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopBranchController.java @@ -0,0 +1,106 @@ +package com.czg.controller.admin; + +import com.czg.account.dto.ShopBranchDTO; +import com.czg.account.entity.ShopConfig; +import com.czg.account.enums.BranchDataSyncMethodEnum; +import com.czg.account.param.ShopBranchParam; +import com.czg.account.service.ShopBranchService; +import com.czg.account.service.ShopConfigService; +import com.czg.log.annotation.OperationLog; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +/** + * 分店管理 + * + * @author tankaikai + * @since 2025-04-07 14:05 + */ +@RestController +@RequestMapping("/admin/shop/branch") +public class ShopBranchController { + + @Resource + private ShopBranchService shopBranchService; + @Resource + private ShopConfigService shopConfigService; + + /** + * 分店列表 + */ + @GetMapping("page") + @OperationLog("分店管理-分页") + public CzgResult> getBranchPage(ShopBranchParam param) { + Long shopId = StpKit.USER.getShopId(0L); + param.setShopId(shopId); + Page data = shopBranchService.findPage(param); + return CzgResult.success(data); + } + + + /** + * 设置数据同步方式 + * + * @param dataSyncMethod 数据同步方式 auto-实时自动同步 manual-手动同步 + */ + @PostMapping("/setting/dataSyncMethod") + @OperationLog("分店管理-设置数据同步方式") + public CzgResult settingDataSyncMethod(@RequestParam String dataSyncMethod) { + Long shopId = StpKit.USER.getShopId(0L); + shopBranchService.settingDataSyncMethod(shopId, dataSyncMethod); + return CzgResult.success(); + } + + /** + * 同步启用 + * + * @param branchShopId 分店id + */ + @PostMapping("/data/sync/enable") + @OperationLog("分店管理-同步启用") + public CzgResult dataSyncEnable(@RequestParam Long branchShopId) { + shopBranchService.dataSyncEnable(branchShopId); + CzgResult ret = CzgResult.success(); + ret.setMsg("启用成功,数据正在后台同步中..."); + return ret; + } + + /** + * 账号启用 + * + * @param branchShopId 分店id + */ + @PostMapping("/account/enable") + @OperationLog("分店管理-账号启用") + public CzgResult accountEnable(@RequestParam Long branchShopId) { + shopBranchService.accountEnable(branchShopId); + return CzgResult.success(); + } + + /** + * 账号禁用 + * + * @param branchShopId 分店id + */ + @PostMapping("/account/disable") + @OperationLog("分店管理-账号禁用") + public CzgResult accountDisable(@RequestParam Long branchShopId) { + shopBranchService.accountDisable(branchShopId); + return CzgResult.success(); + } + + /** + * 获取数据同步方式 + * @return 数据同步方式 auto-实时自动同步 manual-手动同步 + */ + @GetMapping("/get/dataSyncMethod") + @OperationLog("分店管理-获取数据同步方式") + public CzgResult getDataSyncMethod() { + Long shopId = StpKit.USER.getShopId(0L); + ShopConfig shopConfig = shopConfigService.getById(shopId); + return CzgResult.success(shopConfig == null? BranchDataSyncMethodEnum.AUTO.getValue() : shopConfig.getBranchDataSyncMethod()); + } +} diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopInfoController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopInfoController.java index 863415121..d71a7acdd 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopInfoController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopInfoController.java @@ -1,10 +1,14 @@ package com.czg.controller.admin; +import cn.dev33.satoken.session.TokenSign; +import cn.hutool.core.collection.CollUtil; import com.czg.account.dto.PageDTO; +import com.czg.account.dto.shopinfo.ShopBranchSelectDTO; import com.czg.account.dto.shopinfo.ShopDetailDTO; import com.czg.account.dto.shopinfo.ShopInfoAddDTO; import com.czg.account.dto.shopinfo.ShopInfoEditDTO; import com.czg.account.entity.ShopInfo; +import com.czg.account.service.AuthorizationService; import com.czg.account.service.ShopInfoService; import com.czg.annotation.SaAdminCheckPermission; import com.czg.annotation.SaAdminCheckRole; @@ -12,17 +16,23 @@ import com.czg.resp.CzgResult; import com.czg.sa.StpKit; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; +import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** * 店铺管理 + * * @author Administrator */ @RestController @RequestMapping("/admin/shopInfo") public class ShopInfoController { private final ShopInfoService shopInfoService; + @Resource + private AuthorizationService authorizationService; public ShopInfoController(ShopInfoService shopInfoService) { this.shopInfoService = shopInfoService; @@ -35,8 +45,8 @@ public class ShopInfoController { @SaAdminCheckRole("管理员") @SaAdminCheckPermission(value = "shopInfo:list", name = "店铺列表") @GetMapping - public CzgResult> get(PageDTO pageDTO, String shopName, Integer status) { - return CzgResult.success(shopInfoService.get(pageDTO, shopName, status)); + public CzgResult> get(PageDTO pageDTO, String shopName, Integer status, Integer isHeadShop) { + return CzgResult.success(shopInfoService.get(pageDTO, shopName, status, isHeadShop)); } /** @@ -83,4 +93,37 @@ public class ShopInfoController { public CzgResult delete(@RequestParam Integer id) { return CzgResult.success(shopInfoService.remove(new QueryWrapper().eq(ShopInfo::getId, id))); } + + /** + * 店铺分店列表(下拉展示主店和分店使用,默认第一个是主店,其余是分店) + */ + @GetMapping("branchList") + public CzgResult> findShopBranch() { + Long shopId = StpKit.USER.getShopId(0L); + String tokenValue = StpKit.USER.getTokenInfo().getTokenValue(); + Long headId = StpKit.USER.getHeadId(); + List tokenSignList = StpKit.USER.getSession().getTokenSignList(); + if (headId != null && CollUtil.isEmpty(tokenSignList)) { + shopId = StpKit.USER.getHeadShopId(); + } else { + long count = tokenSignList.stream().filter(obj -> tokenValue.equals(obj.getValue())).count(); + if (headId != null && count == 0) { + shopId = StpKit.USER.getHeadShopId(); + } + } + List data = shopInfoService.findShopBranch(shopId); + return CzgResult.success(data); + } + + /** + * 切换店铺 + * + * @param shopId 店铺ID + */ + @PostMapping("/change/{shopId}") + public CzgResult change(@PathVariable Long shopId) { + authorizationService.switchTo(shopId); + return CzgResult.success(); + } + } diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java index 299e37c4f..f64e58273 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopUserController.java @@ -1,9 +1,7 @@ package com.czg.controller.admin; -import cn.hutool.core.util.StrUtil; import com.czg.account.dto.shopuser.*; import com.czg.account.entity.ShopUser; -import com.czg.account.entity.ShopUserFlow; import com.czg.account.service.ShopUserFlowService; import com.czg.account.service.ShopUserService; import com.czg.account.vo.ShopUserFlowVO; @@ -12,9 +10,7 @@ import com.czg.annotation.SaStaffCheckPermission; import com.czg.enums.ShopUserFlowBizEnum; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; -import com.czg.utils.PageUtil; import com.mybatisflex.core.paginate.Page; -import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import org.springframework.validation.annotation.Validated; @@ -47,7 +43,7 @@ public class ShopUserController { @GetMapping("/summary") @SaStaffCheckPermission("yun_xu_guan_li_hui_yuan_xin_xi") public CzgResult summary(Integer isVip) { - return CzgResult.success(shopUserService.getSummary(StpKit.USER.getShopId(), isVip)); + return CzgResult.success(shopUserService.getSummary(StpKit.USER.getUsableShopId(), isVip)); } /** @@ -71,7 +67,7 @@ public class ShopUserController { @GetMapping("/flow") @SaStaffCheckPermission("yun_xu_guan_li_hui_yuan_xin_xi") public CzgResult> flow(Integer userId, String bizCode, String startTime, String endTime) { - return CzgResult.success(shopUserFlowService.pageInfo(StpKit.USER.getShopId(), userId, bizCode, startTime, endTime)); + return CzgResult.success(shopUserFlowService.pageInfo(StpKit.USER.getUsableShopId(), userId, bizCode, startTime, endTime)); } /** @@ -87,7 +83,7 @@ public class ShopUserController { @GetMapping("/flow/download") @SaStaffCheckPermission("yun_xu_guan_li_hui_yuan_xin_xi") public void flowDownload(Integer userId, String bizCode, String startTime, String endTime, HttpServletResponse response) throws IOException { - shopUserFlowService.flowDownload(StpKit.USER.getShopId(), userId, bizCode, startTime, endTime, response); + shopUserFlowService.flowDownload(StpKit.USER.getUsableShopId(), userId, bizCode, startTime, endTime, response); } /** @@ -129,7 +125,7 @@ public class ShopUserController { @SaAdminCheckPermission(value = "shopUser:add", name = "店铺用户添加") @PostMapping public CzgResult add(@RequestBody @Validated ShopUserAddDTO shopUserAddDTO) { - return CzgResult.success(shopUserService.add(StpKit.USER.getShopId(), shopUserAddDTO)); + return CzgResult.success(shopUserService.add(StpKit.USER.getUsableShopId(), shopUserAddDTO)); } /** @@ -141,7 +137,7 @@ public class ShopUserController { @SaAdminCheckPermission(value = "shopUser:edit", name = "店铺用户修改") @PutMapping public CzgResult edit(@RequestBody @Validated ShopUserEditDTO shopUserEditDTO) { - return CzgResult.success(shopUserService.updateInfo(StpKit.USER.getShopId(), shopUserEditDTO)); + return CzgResult.success(shopUserService.updateInfo(StpKit.USER.getUsableShopId(), shopUserEditDTO)); } /** @@ -154,7 +150,7 @@ public class ShopUserController { @PutMapping("/money") public CzgResult editMoney(@RequestBody @Validated ShopUserMoneyEditDTO shopUserMoneyEditDTO) { shopUserMoneyEditDTO.setBizEnum(ShopUserFlowBizEnum.ADMIN_IN); - return CzgResult.success(shopUserService.updateMoney(StpKit.USER.getShopId(), shopUserMoneyEditDTO) > 0L); + return CzgResult.success(shopUserService.updateMoney(StpKit.USER.getUsableShopId(), shopUserMoneyEditDTO) > 0L); } } diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/SyncNoticeController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/SyncNoticeController.java new file mode 100644 index 000000000..ff13ad298 --- /dev/null +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/SyncNoticeController.java @@ -0,0 +1,92 @@ +package com.czg.controller.admin; + +import com.czg.account.entity.SyncNotice; +import com.czg.account.service.SyncNoticeService; +import com.czg.product.dto.SyncNoticeReadDTO; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * 通知中心-同步消息 + * @author Administrator + */ +@RestController +@RequestMapping("/admin/syncNotice") +public class SyncNoticeController { + @Resource + private SyncNoticeService syncNoticeService; + + /** + * 通知消息列表 + * @param name 名称 + * @param startTime 起始时间 + * @param endTime 结束时间 + * @param title 数据同步/数据变动/库存预警 + * @param isRead 0-未读 1-已读 + * @return 分页数据 + */ + @GetMapping + public CzgResult> page(@RequestParam(required = false) String name, @RequestParam(required = false) String startTime, + @RequestParam(required = false) String endTime, @RequestParam(required = false) String title, + @RequestParam(required = false) Integer isRead) { + return CzgResult.success(syncNoticeService.pageInfo(StpKit.USER.getShopId(), name, startTime, endTime, title, isRead)); + } + + /** + * 详情 + * @param id id + * @return 详细信息 + */ + @GetMapping("/detail") + public CzgResult detail(@RequestParam Long id) { + return CzgResult.success(syncNoticeService.getOne(new QueryWrapper().eq(SyncNotice::getShopId, StpKit.USER.getShopId()).eq(SyncNotice::getId, id))); + } + + + /** + * 已读消息, 不传递已读所有 + * @return 是否成功 + */ + @PutMapping("/read") + public CzgResult read(@RequestBody @Validated SyncNoticeReadDTO syncNoticeReadDTO) { + return CzgResult.success(syncNoticeService.read(StpKit.USER.getShopId(), syncNoticeReadDTO)); + } + + /** + * 清空已读 + * @return 是否成功 + */ + @DeleteMapping("/clear") + public CzgResult clear() { + return CzgResult.success(syncNoticeService.remove(new QueryWrapper().eq(SyncNotice::getShopId, StpKit.USER.getShopId()).eq(SyncNotice::getIsRead, 1))); + } + + /** + * 删除 + * @param id id + * @return 是否成功 + */ + @DeleteMapping + public CzgResult delete(@RequestParam Long id) { + return CzgResult.success(syncNoticeService.remove(new QueryWrapper().eq(SyncNotice::getShopId, StpKit.USER.getShopId()).eq(SyncNotice::getId, id))); + } + + + /** + * 消息统计 + * @return 消息记录数 + */ + @GetMapping("/count") + public CzgResult count(@RequestParam(required = false) Integer isRead) { + QueryWrapper queryWrapper = new QueryWrapper().eq(SyncNotice::getShopId, StpKit.USER.getShopId()); + queryWrapper.eq(SyncNotice::getIsRead, isRead); + return CzgResult.success(syncNoticeService.count(queryWrapper)); + } + +} diff --git a/cash-api/account-server/src/main/java/com/czg/controller/user/UShopUserController.java b/cash-api/account-server/src/main/java/com/czg/controller/user/UShopUserController.java index 2d0f4e8fe..7c3dc6f87 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/user/UShopUserController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/user/UShopUserController.java @@ -4,7 +4,6 @@ import com.czg.account.dto.shopuser.ShopUserAddDTO; import com.czg.account.dto.shopuser.ShopUserDetailDTO; import com.czg.account.dto.shopuser.ShopUserVipCardDTO; import com.czg.account.entity.MemberPointsLog; -import com.czg.account.entity.PointsExchangeRecord; import com.czg.account.entity.ShopUser; import com.czg.account.entity.ShopUserFlow; import com.czg.account.service.MemberPointsLogService; @@ -18,14 +17,9 @@ import com.czg.utils.PageUtil; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; -import lombok.Data; -import lombok.EqualsAndHashCode; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.HashSet; -import java.util.Objects; - /** * 店铺会员相关 * @@ -51,7 +45,7 @@ public class UShopUserController { */ @GetMapping public CzgResult get(Long shopId) { - return CzgResult.success(shopUserService.getInfo(shopId == null ? StpKit.USER.getShopId() : shopId, StpKit.USER.getLoginIdAsLong())); + return CzgResult.success(shopUserService.getInfo(shopId == null ? StpKit.USER.getUsableShopId() : shopId, StpKit.USER.getLoginIdAsLong())); } /** @@ -71,7 +65,7 @@ public class UShopUserController { */ @GetMapping("/code") public CzgResult code(Long shopId) { - return shopUserService.getCode(StpKit.USER.getLoginIdAsLong(), shopId == null ? StpKit.USER.getShopId() : shopId); + return shopUserService.getCode(StpKit.USER.getLoginIdAsLong(), shopId == null ? StpKit.USER.getUsableShopId() : shopId); } /** @@ -82,7 +76,7 @@ public class UShopUserController { @PostMapping @Debounce("#shopUserAddDTO.phone") public CzgResult join(@RequestBody @Validated ShopUserAddDTO shopUserAddDTO) { - return CzgResult.success(shopUserService.join(StpKit.USER.getShopId(), StpKit.USER.getLoginIdAsLong(), shopUserAddDTO)); + return CzgResult.success(shopUserService.join(StpKit.USER.getUsableShopId(), StpKit.USER.getLoginIdAsLong(), shopUserAddDTO)); } diff --git a/cash-api/account-server/src/main/java/com/czg/controller/user/UserController.java b/cash-api/account-server/src/main/java/com/czg/controller/user/UserController.java index cc422f9aa..2c4fc6a4b 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/user/UserController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/user/UserController.java @@ -1,15 +1,11 @@ package com.czg.controller.user; -import cn.dev33.satoken.stp.StpUtil; -import cn.hutool.core.bean.BeanUtil; import com.czg.account.dto.user.userinfo.UserInfoDTO; import com.czg.account.dto.user.userinfo.UserInfoEditDTO; import com.czg.account.dto.user.userinfo.UserInfoPwdEditDTO; -import com.czg.account.entity.UserInfo; import com.czg.account.service.UserInfoService; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; -import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.*; @@ -38,7 +34,7 @@ public class UserController { */ @PutMapping public CzgResult update(@RequestBody UserInfoEditDTO userInfoEditDTO) { - return CzgResult.success(userInfoService.updateInfo(StpKit.USER.getShopId(-1L), StpKit.USER.getLoginIdAsLong(), userInfoEditDTO)); + return CzgResult.success(userInfoService.updateInfo(StpKit.USER.getUsableShopId(), StpKit.USER.getLoginIdAsLong(), userInfoEditDTO)); } /** diff --git a/cash-api/order-server/src/main/java/com/czg/controller/NotifyController.java b/cash-api/order-server/src/main/java/com/czg/controller/NotifyController.java index ab2857f59..9b45af1a4 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/NotifyController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/NotifyController.java @@ -1,5 +1,7 @@ package com.czg.controller; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.thread.ThreadUtil; import com.alibaba.fastjson2.JSONObject; import com.czg.CzgPayUtils; import com.czg.entity.CzgBaseRespParams; @@ -9,10 +11,9 @@ import com.czg.task.StatisticTask; import com.czg.utils.AssertUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.Date; /** * @author ww @@ -32,7 +33,7 @@ public class NotifyController { @RequestMapping("/payCallBack") - public String notifyCallBack(@RequestBody CzgBaseRespParams respParams){ + public String notifyCallBack(@RequestBody CzgBaseRespParams respParams) { JSONObject czg = CzgPayUtils.getCzg(respParams); AssertUtil.isNull(czg, "支付回调数据为空"); log.info("支付回调数据为:{}", czg); @@ -41,7 +42,7 @@ public class NotifyController { } @RequestMapping("/refundCallBack") - public String refundCallBack(@RequestBody CzgBaseRespParams respParams){ + public String refundCallBack(@RequestBody CzgBaseRespParams respParams) { JSONObject czg = CzgPayUtils.getCzg(respParams); AssertUtil.isNull(czg, "退款回调数据为空"); log.info("退款回调数据为:{}", czg); @@ -51,8 +52,18 @@ public class NotifyController { @Resource private PrintMqListener printMqListener; + @RequestMapping("/test") public void test(@RequestParam String id) { printMqListener.orderPrint(id); } + + @GetMapping("/anew/statistic/history/data") + public String statistic(@RequestParam String now) { + String format = DateUtil.format(new Date(), "yyyyMMddHHmm"); + if (format.equals(now)) { + ThreadUtil.execAsync(() -> statisticTask.statisticHistoryData()); + } + return SUCCESS; + } } diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java index 7b759b8aa..74bf84b34 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/DataSummaryController.java @@ -44,8 +44,10 @@ public class DataSummaryController { public CzgResult getTradeData(DataSummaryTradeParam param) { ValidatorUtil.validateEntity(param, DefaultGroup.class); Long shopId = StpKit.USER.getShopId(0L); - param.setShopId(shopId); - ShopOrderStatistic data = dataSummaryService.getTradeData(param); + if (param.getShopId() == null) { + param.setShopId(shopId); + } + ShopOrderStatistic data = dataSummaryService.getArchiveTradeData(param); return CzgResult.success(data); } @@ -59,7 +61,9 @@ public class DataSummaryController { public CzgResult> getProductSaleData(DataSummaryProductSaleParam param) { ValidatorUtil.validateEntity(param, DefaultGroup.class); Long shopId = StpKit.USER.getShopId(0L); - param.setShopId(shopId); + if (param.getShopId() == null) { + param.setShopId(shopId); + } Page data = dataSummaryService.getProductSaleRankingPage(param); return CzgResult.success(data); } @@ -67,15 +71,18 @@ public class DataSummaryController { /** * 销售趋势柱状图 左下 * - * @param day 天数 + * @param day 天数 + * @param shopId 店铺id */ @GetMapping("dateAmount") @OperationLog("销售趋势柱状图 左下") @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju") //@SaAdminCheckPermission("dataSummary:dateAmount") - public CzgResult getDateAmount(@RequestParam Integer day) { + public CzgResult getDateAmount(@RequestParam Integer day, @RequestParam(required = false) Long shopId) { AssertUtil.isNull(day, "天数不能为空"); - Long shopId = StpKit.USER.getShopId(0L); + if (shopId == null) { + shopId = StpKit.USER.getShopId(0L); + } DataSummaryDateAmountVo data = dataSummaryService.getSummaryAmountData(shopId, day); return CzgResult.success(data); } @@ -84,13 +91,16 @@ public class DataSummaryController { * 支付占比饼图 左下 * * @param day 天数 + * @param shopId 店铺id */ @GetMapping("datePayType") @OperationLog("支付占比饼图 左下") @SaStaffCheckPermission("yun_xu_cha_kan_jing_ying_shu_ju") //@SaAdminCheckPermission("dataSummary:datePayType") - public CzgResult shopSummaryPayType(@RequestParam Integer day) { - Long shopId = StpKit.USER.getShopId(0L); + public CzgResult shopSummaryPayType(@RequestParam Integer day, @RequestParam(required = false) Long shopId) { + if (shopId == null) { + shopId = StpKit.USER.getShopId(0L); + } DataSummaryPayTypeVo data = dataSummaryService.getSummaryPayTypeData(shopId, day); return CzgResult.success(data); } diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java index 15fe88af4..b08584fc5 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/SaleSummaryController.java @@ -38,7 +38,9 @@ public class SaleSummaryController { //@SaAdminCheckPermission("saleSummary:count") public CzgResult summaryCount(SaleSummaryCountParam param) { Long shopId = StpKit.USER.getShopId(0L); - param.setShopId(shopId); + if (param.getShopId() == null) { + param.setShopId(shopId); + } SaleSummaryCountVo data = saleSummaryService.summaryCount(param); return CzgResult.success(data); } @@ -51,7 +53,9 @@ public class SaleSummaryController { //@SaAdminCheckPermission("saleSummary:page") public CzgResult> summaryPage(SaleSummaryCountParam param) { Long shopId = StpKit.USER.getShopId(0L); - param.setShopId(shopId); + if (param.getShopId() == null) { + param.setShopId(shopId); + } Page page = saleSummaryService.summaryPage(param); return CzgResult.success(page); } @@ -65,7 +69,9 @@ public class SaleSummaryController { //@SaAdminCheckPermission("saleSummary:export") public List summaryExport(SaleSummaryCountParam param) { Long shopId = StpKit.USER.getShopId(0L); - param.setShopId(shopId); + if (param.getShopId() == null) { + param.setShopId(shopId); + } return saleSummaryService.summaryList(param); } diff --git a/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java b/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java index cfb0c7828..0fbc03098 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/admin/TableSummaryController.java @@ -37,7 +37,9 @@ public class TableSummaryController { //@SaAdminCheckPermission("tableSummary:list") public CzgResult> summaryList(TableSummaryParam param) { Long shopId = StpKit.USER.getShopId(0L); - param.setShopId(shopId); + if (param.getShopId() == null) { + param.setShopId(shopId); + } List data = tableSummaryService.summaryList(param); return CzgResult.success(data); } @@ -51,7 +53,9 @@ public class TableSummaryController { //@SaAdminCheckPermission("tableSummary:export") public List summaryExport(TableSummaryParam param) { Long shopId = StpKit.USER.getShopId(0L); - param.setShopId(shopId); + if (param.getShopId() == null) { + param.setShopId(shopId); + } return tableSummaryService.summaryExportList(param); } diff --git a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java index e387fe681..b79d79794 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java @@ -1,13 +1,27 @@ package com.czg.task; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import com.czg.order.entity.ShopOrderStatistic; +import com.czg.order.entity.ShopProdStatistic; +import com.czg.order.entity.ShopTableOrderStatistic; import com.czg.order.service.ShopOrderStatisticService; import com.czg.order.service.ShopProdStatisticService; import com.czg.order.service.ShopTableOrderStatisticService; +import com.czg.service.order.mapper.ShopOrderStatisticMapper; +import com.czg.service.order.mapper.ShopProdStatisticMapper; +import com.czg.service.order.mapper.ShopTableOrderStatisticMapper; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.row.DbChain; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import java.time.LocalDate; +import java.util.List; + /** * @author Administrator */ @@ -20,15 +34,81 @@ public class StatisticTask { private ShopProdStatisticService shopProdStatisticService; @Resource private ShopOrderStatisticService shopOrderStatisticService; + @Resource + private ShopOrderStatisticMapper shopOrderStatisticMapper; + @Resource + private ShopProdStatisticMapper shopProdStatisticMapper; + @Resource + private ShopTableOrderStatisticMapper shopTableOrderStatisticMapper; -// @Scheduled(cron = "1/6 * * * * ? ") + /** + * 基础统计 + * + * @param dateTime 日期时间 + */ + private void baseStatistic(DateTime dateTime) { + try { + shopOrderStatisticService.statistic(dateTime); + } catch (Exception e) { + log.error("统计订单数据失败", e); + } + try { + shopProdStatisticService.statistic(dateTime); + } catch (Exception e) { + log.error("统计商品数据失败", e); + } + try { + shopTableOrderStatisticService.statistic(dateTime); + } catch (Exception e) { + log.error("统计桌台数据失败", e); + } + } + + // @Scheduled(cron = "1/6 * * * * ? ") @Scheduled(cron = "0 0 8 * * ?") public void run() { long start = System.currentTimeMillis(); log.info("定时任务执行,开始统计数据"); - shopOrderStatisticService.statistic(); - shopProdStatisticService.statistic(); - shopTableOrderStatisticService.statistic(); + // 获取前一天 + DateTime yesterday = DateUtil.yesterday(); + baseStatistic(yesterday); log.info("定时任务执行完毕,耗时:{}ms", start - System.currentTimeMillis()); } + + @Scheduled(cron = "0 0,15,30,45 * * * ? ") + public void run2() { + long start = System.currentTimeMillis(); + log.info("定时任务2执行,开始统计数据"); + // 获取当天 + DateTime today = DateUtil.date(); + baseStatistic(today); + log.info("定时任务2执行完毕,耗时:{}ms", start - System.currentTimeMillis()); + } + + /** + * 统计历史数据 + */ + public void statisticHistoryData() { + // 指定开始日期 + LocalDate startDate = LocalDate.of(2024, 3, 1); + // 指定结束日期 + LocalDate endDate = LocalDate.now(); + List shopIdList = DbChain.table("tb_shop_info").select("id").objListAs(Long.class); + List> split = CollUtil.split(shopIdList, 10); + // 1.清除历史统计的数据 + for (List splitIdList : split) { + splitIdList.parallelStream().forEach(shopId -> { + shopOrderStatisticMapper.deleteByQuery(QueryWrapper.create().eq(ShopOrderStatistic::getShopId, shopId)); + shopProdStatisticMapper.deleteByQuery(QueryWrapper.create().eq(ShopProdStatistic::getShopId, shopId)); + shopTableOrderStatisticMapper.deleteByQuery(QueryWrapper.create().eq(ShopTableOrderStatistic::getShopId, shopId)); + }); + } + // 2.开始从2024-3-1开始统计数据 + startDate.datesUntil(endDate.plusDays(1)).forEach(date -> { + System.out.println(date.toString()); + DateTime dateTime = DateUtil.parseDate(date.toString()); + System.out.println(dateTime); + baseStatistic(dateTime); + }); + } } diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsGroupController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsGroupController.java index e7c5d9028..99893966f 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsGroupController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsGroupController.java @@ -1,14 +1,18 @@ package com.czg.controller.admin; +import cn.hutool.core.thread.ThreadUtil; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ConsGroupDTO; import com.czg.product.service.ConsGroupService; +import com.czg.product.service.ShopSyncService; import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; import com.czg.utils.AssertUtil; import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -27,6 +31,8 @@ import java.util.List; @RequestMapping("/admin/product/consGroup") public class ConsGroupController { private final ConsGroupService consGroupService; + @Resource + private ShopSyncService shopSyncService; /** * 分页 @@ -72,6 +78,7 @@ public class ConsGroupController { //@SaAdminCheckPermission("consGroup:add") public CzgResult addConsGroup(@RequestBody @Validated({InsertGroup.class, DefaultGroup.class}) ConsGroupDTO dto) { consGroupService.addConsGroup(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -83,6 +90,7 @@ public class ConsGroupController { //@SaAdminCheckPermission("consGroup:update") public CzgResult updateConsGroup(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ConsGroupDTO dto) { consGroupService.updateConsGroup(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -98,6 +106,7 @@ public class ConsGroupController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); consGroupService.disableConsGroup(id); + asyncToBranchShop(id); return CzgResult.success(); } @@ -113,6 +122,15 @@ public class ConsGroupController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); consGroupService.enableConsGroup(id); + asyncToBranchShop(id); return CzgResult.success(); } + + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncConsGroupBySourceShop(shopId, id, sysUserId); + }); + } } \ No newline at end of file diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsInfoController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsInfoController.java index 8b86a7baa..b4d56b90c 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsInfoController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsInfoController.java @@ -1,12 +1,13 @@ package com.czg.controller.admin; +import cn.hutool.core.thread.ThreadUtil; import com.czg.enums.CrudEnum; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ConsInfoDTO; import com.czg.product.param.ConsInfoParam; -import com.czg.product.param.ConsReportDamageParam; import com.czg.product.param.ConsSubUnitParam; import com.czg.product.service.ConsInfoService; +import com.czg.product.service.ShopSyncService; import com.czg.product.vo.ConsStatisticsVo; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; @@ -16,6 +17,7 @@ import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -34,6 +36,8 @@ import java.util.List; @RequestMapping("/admin/product/cons") public class ConsInfoController { private final ConsInfoService consInfoService; + @Resource + private ShopSyncService shopSyncService; /** * 分页 @@ -79,6 +83,7 @@ public class ConsInfoController { //@SaAdminCheckPermission("consInfo:add") public CzgResult addConsInfo(@RequestBody @Validated({InsertGroup.class, DefaultGroup.class}) ConsInfoDTO dto) { consInfoService.addConsInfo(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -90,6 +95,7 @@ public class ConsInfoController { //@SaAdminCheckPermission("consInfo:update") public CzgResult updateConsInfo(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ConsInfoDTO dto) { consInfoService.updateConsInfo(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -120,6 +126,7 @@ public class ConsInfoController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); consInfoService.disableConsInfo(id); + asyncToBranchShop(id); return CzgResult.success(); } @@ -135,6 +142,7 @@ public class ConsInfoController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); consInfoService.enableConsInfo(id); + asyncToBranchShop(id); return CzgResult.success(); } @@ -167,6 +175,7 @@ public class ConsInfoController { ValidatorUtil.validateEntity(param, InsertGroup.class); } consInfoService.modifySubUnit(param); + asyncToBranchShop(param.getId()); return CzgResult.success(); } @@ -183,4 +192,12 @@ public class ConsInfoController { return CzgResult.success(data); } + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncConsInfoBySourceShop(shopId, id, sysUserId); + }); + } + } diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java index 669803197..c0020b192 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java @@ -17,6 +17,8 @@ import com.mybatisflex.core.paginate.Page; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** * 耗材进销存 @@ -90,9 +92,11 @@ public class ConsStockFlowController { @PostMapping("reportDamage") @OperationLog("耗材报损") //@SaAdminCheckPermission("consStockFlow:reportDamage") - public CzgResult reportDamage(@RequestBody ConsReportDamageParam param) { - ValidatorUtil.validateEntity(param, DefaultGroup.class); - consStockFlowService.reportDamage(param); + public CzgResult reportDamage(@RequestBody List params) { + params.forEach(item -> { + ValidatorUtil.validateEntity(item, DefaultGroup.class); + consStockFlowService.reportDamage(item); + }); return CzgResult.success(); } diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProdGroupController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProdGroupController.java index 10c9fbabf..bdd88e825 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProdGroupController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProdGroupController.java @@ -6,6 +6,7 @@ import com.czg.config.RabbitPublisher; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ProdGroupDTO; import com.czg.product.service.ProdGroupService; +import com.czg.product.service.ShopSyncService; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; import com.czg.utils.AssertUtil; @@ -13,6 +14,7 @@ import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -32,6 +34,8 @@ import java.util.List; public class ProdGroupController { private final ProdGroupService prodGroupService; private final RabbitPublisher rabbitPublisher; + @Resource + private ShopSyncService shopSyncService; /** * 分页 @@ -79,6 +83,7 @@ public class ProdGroupController { Long shopId = StpKit.USER.getShopId(0L); dto.setShopId(shopId); prodGroupService.addProdGroup(dto); + asyncToBranchShop(dto.getId()); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); @@ -95,6 +100,7 @@ public class ProdGroupController { Long shopId = StpKit.USER.getShopId(0L); dto.setShopId(shopId); prodGroupService.updateProdGroup(dto,true); + asyncToBranchShop(dto.getId()); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); @@ -111,6 +117,7 @@ public class ProdGroupController { Long shopId = StpKit.USER.getShopId(0L); dto.setShopId(shopId); prodGroupService.updateProdGroup(dto,false); + asyncToBranchShop(dto.getId()); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); @@ -145,6 +152,7 @@ public class ProdGroupController { AssertUtil.isNull(id, "{}不能为空", "id"); Long shopId = StpKit.USER.getShopId(0L); prodGroupService.disableProdGroup(shopId, id); + asyncToBranchShop(id); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); @@ -162,9 +170,18 @@ public class ProdGroupController { AssertUtil.isNull(id, "{}不能为空", "id"); Long shopId = StpKit.USER.getShopId(0L); prodGroupService.enableProdGroup(shopId, id); + asyncToBranchShop(id); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); return CzgResult.success(); } + + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncGroupBySourceShop(shopId, id, sysUserId); + }); + } } \ No newline at end of file diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java index 1a26a0c4c..73bec00e5 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ProductController.java @@ -2,8 +2,6 @@ package com.czg.controller.admin; import cn.hutool.core.convert.Convert; import cn.hutool.core.thread.ThreadUtil; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.util.StrUtil; import com.czg.annotation.SaStaffCheckPermission; import com.czg.config.RabbitPublisher; import com.czg.exception.CzgException; @@ -15,6 +13,8 @@ import com.czg.product.entity.ProductStockFlow; import com.czg.product.param.*; import com.czg.product.service.ProdConsRelationService; import com.czg.product.service.ProductService; +import com.czg.product.service.ShopSyncService; +import com.czg.product.service.UProductService; import com.czg.product.vo.ProductStatisticsVo; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; @@ -24,6 +24,7 @@ import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -44,6 +45,10 @@ public class ProductController { private final ProductService productService; private final ProdConsRelationService prodConsRelationService; private final RabbitPublisher rabbitPublisher; + @Resource + private ShopSyncService shopSyncService; + @Resource + private UProductService uProductService; /** * 商品-分页 @@ -65,22 +70,12 @@ public class ProductController { public CzgResult> getProductList(ProductDTO param) { Long shopId = StpKit.USER.getShopId(0L); param.setShopId(shopId); - ProductDTO cacheParam = new ProductDTO(); - cacheParam.setShopId(shopId); - List data = getProductCacheList(cacheParam, param); - productService.refreshProductStock(param, data); - return CzgResult.success(data); - } - - private List getProductCacheList(ProductDTO cacheParam, ProductDTO param) { - List productList = productService.getProductList(cacheParam); - if (StrUtil.isNotEmpty(param.getName())) { - productList = productList.stream().filter(obj -> StrUtil.contains(obj.getName(), param.getName())).toList(); - } - if (ObjUtil.isNotNull(param.getCategoryId())) { - productList = productList.stream().filter(obj -> param.getCategoryId().equals(obj.getCategoryId())).toList(); - } - return productList; + List productList = productService.getProductCacheList(param); + productService.refreshProductStock(param, productList); + productList.forEach(prod -> { + prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime())); + }); + return CzgResult.success(productList); } /** @@ -109,6 +104,7 @@ public class ProductController { Long shopId = StpKit.USER.getShopId(0L); dto.setShopId(shopId); productService.addProduct(dto); + asyncToBranchShop(dto.getId()); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); @@ -137,6 +133,7 @@ public class ProductController { Long shopId = StpKit.USER.getShopId(0L); dto.setShopId(shopId); productService.updateProduct(dto); + asyncToBranchShop(dto.getId()); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); @@ -151,6 +148,9 @@ public class ProductController { Long shopId = StpKit.USER.getShopId(0L); param.setShopId(shopId); productService.updateProductStock(param); + ThreadUtil.execAsync(() -> { + rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); + }); return CzgResult.success(); } @@ -168,6 +168,7 @@ public class ProductController { AssertUtil.isNull(id, "{}不能为空", "id"); Long shopId = StpKit.USER.getShopId(0L); productService.deleteProduct(shopId, id); + asyncToBranchShop(id); ThreadUtil.execAsync(() -> { rabbitPublisher.sendProductInfoChangeMsg(Convert.toStr(shopId)); }); @@ -216,6 +217,7 @@ public class ProductController { //@SaAdminCheckPermission("product:bind") public CzgResult bindCons(@RequestBody @Validated({DefaultGroup.class}) ProdConsBindDTO param) { prodConsRelationService.saveProdConsRelation(param); + asyncToBranchShop2(param.getId()); return CzgResult.success(); } @@ -227,6 +229,7 @@ public class ProductController { //@SaAdminCheckPermission("product:update") public CzgResult refundToStock(@RequestBody @Validated({DefaultGroup.class}) ProdRefundToStockParam param) { productService.refundToStock(param); + asyncToBranchShop(param.getId()); return CzgResult.success(); } @@ -282,4 +285,44 @@ public class ProductController { return CzgResult.success(data); } + /** + * 商品-报损 + */ + @PostMapping("sync") + @OperationLog("商品-同步主店商品信息") + //@SaAdminCheckPermission("product:sync") + public CzgResult sync() { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + boolean isEnableSync = StpKit.USER.isEnableSync(shopId); + long headShopId = StpKit.USER.getHeadShopId(); + if (!isEnableSync) { + throw new CzgException("主店未开启商品资料同步功能"); + } + if (shopId == headShopId) { + throw new CzgException("不存在主子店铺关系,无需同步商品信息"); + } + ThreadUtil.execAsync(() -> { + shopSyncService.sync(headShopId, shopId, sysUserId); + }); + CzgResult ret = CzgResult.success(); + ret.setMsg("操作成功,数据正在后台同步中..."); + return ret; + } + + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncProductBySourceShop(shopId, id, sysUserId); + }); + } + + private void asyncToBranchShop2(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncConsProBySourceShop(shopId, id, sysUserId); + }); + } } diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdCategoryController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdCategoryController.java index 2c9a1e1c6..d4019b030 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdCategoryController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdCategoryController.java @@ -1,14 +1,18 @@ package com.czg.controller.admin; +import cn.hutool.core.thread.ThreadUtil; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ShopProdCategoryDTO; import com.czg.product.service.ShopProdCategoryService; +import com.czg.product.service.ShopSyncService; import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; import com.czg.utils.AssertUtil; import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -27,6 +31,8 @@ import java.util.List; @RequestMapping("/admin/prod/category") public class ShopProdCategoryController { private final ShopProdCategoryService shopProdCategoryService; + @Resource + private ShopSyncService shopSyncService; @GetMapping("page") @OperationLog("商品分类-分页") @@ -58,6 +64,7 @@ public class ShopProdCategoryController { //@SaAdminCheckPermission("shopProdCategory:add") public CzgResult addShopProdCategory(@RequestBody @Validated({InsertGroup.class, DefaultGroup.class}) ShopProdCategoryDTO dto) { shopProdCategoryService.addShopProdCategory(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -66,6 +73,7 @@ public class ShopProdCategoryController { //@SaAdminCheckPermission("shopProdCategory:update") public CzgResult updateShopProdCategory(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ShopProdCategoryDTO dto) { shopProdCategoryService.updateShopProdCategory(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -86,6 +94,7 @@ public class ShopProdCategoryController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); shopProdCategoryService.disableShopProdCategory(id); + asyncToBranchShop(id); return CzgResult.success(); } @@ -96,7 +105,16 @@ public class ShopProdCategoryController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); shopProdCategoryService.enableShopProdCategory(id); + asyncToBranchShop(id); return CzgResult.success(); } + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncCategoryBySourceShop(shopId, id, sysUserId); + }); + } + } \ No newline at end of file diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdSpecController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdSpecController.java index 8c2344222..7f8791ef0 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdSpecController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdSpecController.java @@ -1,14 +1,19 @@ package com.czg.controller.admin; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.thread.ThreadUtil; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ShopProdSpecDTO; import com.czg.product.service.ShopProdSpecService; +import com.czg.product.service.ShopSyncService; import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; import com.czg.utils.AssertUtil; import com.czg.validator.ValidatorUtil; import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -26,6 +31,9 @@ import java.util.List; @RequestMapping("/admin/prod/spec") public class ShopProdSpecController { private final ShopProdSpecService shopProdSpecService; + @Resource + private ShopSyncService shopSyncService; + @GetMapping("list") @OperationLog("商品规格-列表") @@ -50,9 +58,8 @@ public class ShopProdSpecController { public CzgResult addShopProdSpec(@RequestBody ShopProdSpecDTO dto) { //效验数据 ValidatorUtil.validateEntity(dto, InsertGroup.class, DefaultGroup.class); - shopProdSpecService.addShopProdSpec(dto); - + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -62,9 +69,11 @@ public class ShopProdSpecController { public CzgResult updateShopProdSpec(@RequestBody ShopProdSpecDTO dto) { //效验数据 ValidatorUtil.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); - shopProdSpecService.updateShopProdSpec(dto); - + List affectedIdList = dto.getAffectedIdList(); + if (CollUtil.isNotEmpty(affectedIdList)) { + affectedIdList.forEach(this::asyncToBranchShop); + } return CzgResult.success(); } @@ -85,6 +94,7 @@ public class ShopProdSpecController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); shopProdSpecService.disableShopProdSpec(id); + asyncToBranchShop(id); return CzgResult.success(); } @@ -95,6 +105,7 @@ public class ShopProdSpecController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); shopProdSpecService.enableShopProdSpec(id); + asyncToBranchShop(id); return CzgResult.success(); } @@ -103,6 +114,10 @@ public class ShopProdSpecController { //@SaAdminCheckPermission("shopProductSpec:add") public CzgResult quickAddShopProdSpec(@RequestBody ShopProdSpecDTO dto) { shopProdSpecService.quickAddShopProdSpec(dto); + List affectedIdList = dto.getAffectedIdList(); + if (CollUtil.isNotEmpty(affectedIdList)) { + affectedIdList.forEach(this::asyncToBranchShop); + } return CzgResult.success(); } @@ -120,6 +135,19 @@ public class ShopProdSpecController { //@SaAdminCheckPermission("shopProductSpec:update") public CzgResult quickUpdateShopProdSpec(@RequestBody ShopProdSpecDTO dto) { shopProdSpecService.quickUpdateShopProdSpec(dto); + List affectedIdList = dto.getAffectedIdList(); + if (CollUtil.isNotEmpty(affectedIdList)) { + affectedIdList.forEach(this::asyncToBranchShop); + } return CzgResult.success(); } + + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + ThreadUtil.safeSleep(1000L); + shopSyncService.syncSpecBySourceShop(shopId, id, sysUserId); + }); + } } \ No newline at end of file diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdUnitController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdUnitController.java index 6dc647ea9..acd74e9e4 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdUnitController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopProdUnitController.java @@ -1,14 +1,18 @@ package com.czg.controller.admin; +import cn.hutool.core.thread.ThreadUtil; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ShopProdUnitDTO; import com.czg.product.service.ShopProdUnitService; +import com.czg.product.service.ShopSyncService; import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; import com.czg.utils.AssertUtil; import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -28,6 +32,9 @@ import java.util.List; public class ShopProdUnitController { private final ShopProdUnitService shopProdUnitService; + @Resource + private ShopSyncService shopSyncService; + @GetMapping("page") @OperationLog("商品单位-分页") @@ -58,9 +65,8 @@ public class ShopProdUnitController { @OperationLog("商品单位-新增") //@SaAdminCheckPermission("shopProdUnit:add") public CzgResult addShopProdUnit(@RequestBody @Validated({InsertGroup.class, DefaultGroup.class}) ShopProdUnitDTO dto) { - - shopProdUnitService.addShopProdUnit(dto); - + Long id = shopProdUnitService.addShopProdUnit(dto); + asyncToBranchShop(id); return CzgResult.success(); } @@ -68,9 +74,8 @@ public class ShopProdUnitController { @OperationLog("商品单位-修改") //@SaAdminCheckPermission("shopProdUnit:update") public CzgResult updateShopProdUnit(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ShopProdUnitDTO dto) { - shopProdUnitService.updateShopProdUnit(dto); - + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -91,6 +96,7 @@ public class ShopProdUnitController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); shopProdUnitService.disableShopProdUnit(id); + asyncToBranchShop(id); return CzgResult.success(); } @@ -101,8 +107,16 @@ public class ShopProdUnitController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); shopProdUnitService.enableShopProdUnit(id); + asyncToBranchShop(id); return CzgResult.success(); } + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncUnitBySourceShop(shopId, id, sysUserId); + }); + } } \ No newline at end of file diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopVendorController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopVendorController.java index 25350ea01..ca4d44b8c 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopVendorController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ShopVendorController.java @@ -1,8 +1,10 @@ package com.czg.controller.admin; +import cn.hutool.core.thread.ThreadUtil; import com.czg.log.annotation.OperationLog; import com.czg.product.dto.ShopVendorBillPayDTO; import com.czg.product.dto.ShopVendorDTO; +import com.czg.product.service.ShopSyncService; import com.czg.product.service.ShopVendorService; import com.czg.product.vo.ShopVendorBillPayRecordVO; import com.czg.product.vo.ShopVendorBillRecordVO; @@ -15,6 +17,7 @@ import com.czg.validator.group.DefaultGroup; import com.czg.validator.group.InsertGroup; import com.czg.validator.group.UpdateGroup; import com.mybatisflex.core.paginate.Page; +import jakarta.annotation.Resource; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -33,6 +36,8 @@ import java.util.List; @RequestMapping("/admin/product/vendor") public class ShopVendorController { private final ShopVendorService shopVendorService; + @Resource + private ShopSyncService shopSyncService; /** * 分页 @@ -77,6 +82,7 @@ public class ShopVendorController { //@SaAdminCheckPermission("shopVendor:add") public CzgResult addShopVendor(@RequestBody @Validated({InsertGroup.class, DefaultGroup.class}) ShopVendorDTO dto) { shopVendorService.addShopVendor(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } @@ -88,11 +94,13 @@ public class ShopVendorController { //@SaAdminCheckPermission("shopVendor:update") public CzgResult updateShopVendor(@RequestBody @Validated({UpdateGroup.class, DefaultGroup.class}) ShopVendorDTO dto) { shopVendorService.updateShopVendor(dto); + asyncToBranchShop(dto.getId()); return CzgResult.success(); } /** * 删除 + * * @param id 供应商id */ @DeleteMapping("{id}") @@ -102,46 +110,51 @@ public class ShopVendorController { //效验数据 AssertUtil.isNull(id, "{}不能为空", "id"); shopVendorService.deleteShopVendor(id); + asyncToBranchShop(id); return CzgResult.success(); } /** * 供应商账单统计 + * * @return 统计信息 */ @GetMapping("summary") - @OperationLog("供应商账单-统计") +// @OperationLog("供应商账单-统计") public CzgResult summary() { return CzgResult.success(shopVendorService.summary(StpKit.USER.getShopId())); } /** * 账单列表 + * * @return 账单列表 */ @GetMapping("/bill") - @OperationLog("供应商账单-列表") - public CzgResult> bill() { - return CzgResult.success(shopVendorService.billList(StpKit.USER.getShopId())); +// @OperationLog("供应商账单-列表") + public CzgResult> bill(@RequestParam(required = false) String key) { + return CzgResult.success(shopVendorService.billList(StpKit.USER.getShopId(), key)); } /** * 账单记录 + * * @return 记录list */ @GetMapping("/bill/record") - @OperationLog("供应商账单-列表") - public CzgResult> bill(@RequestParam Integer vendorId) { - return CzgResult.success(shopVendorService.billRecord(StpKit.USER.getShopId(), vendorId)); +// @OperationLog("供应商账单-列表") + public CzgResult> bill(@RequestParam Integer vendorId, @RequestParam(required = false) String key) { + return CzgResult.success(shopVendorService.billRecord(StpKit.USER.getShopId(), vendorId, key)); } /** * 账单支付 + * * @return 记录list */ @PostMapping("/bill/pay") - @OperationLog("供应商账单-付款") +// @OperationLog("供应商账单-付款") public CzgResult pay(@RequestBody @Validated ShopVendorBillPayDTO payDTO) { return CzgResult.success(shopVendorService.pay(StpKit.USER.getShopId(), payDTO)); } @@ -149,12 +162,21 @@ public class ShopVendorController { /** * 账单支付记录 + * * @return 记录list */ @GetMapping("/bill/pay/record") - @OperationLog("供应商账单-付款记录") +// @OperationLog("供应商账单-付款记录") public CzgResult> payRecord(@RequestParam Long flowId) { return CzgResult.success(shopVendorService.payRecord(StpKit.USER.getShopId(), flowId)); } + private void asyncToBranchShop(Long id) { + long shopId = StpKit.USER.getShopId(0L); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + shopSyncService.syncVendorBySourceShop(shopId, id, sysUserId); + }); + } + } diff --git a/cash-api/product-server/src/main/java/com/czg/controller/user/UProductController.java b/cash-api/product-server/src/main/java/com/czg/controller/user/UProductController.java index fca30ef4d..11cd57f5d 100644 --- a/cash-api/product-server/src/main/java/com/czg/controller/user/UProductController.java +++ b/cash-api/product-server/src/main/java/com/czg/controller/user/UProductController.java @@ -1,7 +1,7 @@ package com.czg.controller.user; +import com.czg.enums.YesNoEnum; import com.czg.product.param.ShopProductSkuParam; -import com.czg.product.service.ProdGroupService; import com.czg.product.service.UProductService; import com.czg.product.vo.ShopGroupProductVo; import com.czg.product.vo.ShopProductInfoVo; @@ -9,6 +9,7 @@ import com.czg.product.vo.ShopProductSkuInfoVo; import com.czg.product.vo.ShopProductVo; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; +import com.czg.service.RedisService; import com.czg.utils.AssertUtil; import com.czg.validator.ValidatorUtil; import com.czg.validator.group.DefaultGroup; @@ -33,7 +34,7 @@ import java.util.Map; @RequestMapping("/user/product") public class UProductController { private final UProductService uProductService; - private final ProdGroupService prodGroupService; + private final RedisService redisService; /** * 小程序点餐-热销商品列表 @@ -61,7 +62,11 @@ public class UProductController { uProductService.refreshProductStock(productStock, item.getProductList()); item.getProductList().forEach(prod -> { prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getDays(), prod.getStartTime(), prod.getEndTime())); - prod.setIsSaleTime(uProductService.calcIsSaleTime(item.getUseTime(), item.getSaleStartTime(), item.getSaleEndTime())); + prod.setIsSaleTime(uProductService.calcIsSaleTime(prod.getIsSaleTime(), item.getUseTime(), item.getSaleStartTime(), item.getSaleEndTime())); + if (item.getUseTime() == YesNoEnum.YES.value()) { + prod.setStartTime(item.getSaleStartTime()); + prod.setEndTime(item.getSaleEndTime()); + } }); }); return CzgResult.success(list); diff --git a/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java b/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java index ad5c1a2d6..e84608854 100644 --- a/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java +++ b/cash-common/cash-common-redis/src/main/java/com/czg/service/RedisService.java @@ -1,5 +1,7 @@ package com.czg.service; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONWriter; import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -598,4 +600,54 @@ public class RedisService { return redisTemplate.opsForList().rightPop(key); } + /** + * 右模糊查找key + * + * @param key 模糊匹配的key前缀 + * @return 匹配的keys + */ + public Set rightLikeKey(String key) { + return redisTemplate.keys(key + "*"); + } + + /** + * JsonString缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean setJsonStr(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, JSON.toJSONString(value, JSONWriter.Feature.WriteMapNullValue)); + return true; + } catch (Exception e) { + log.error("redis error:{}", e + ""); + return false; + } + } + + /** + * JsonString缓存获取 + * + * @param key 键 + * @return 值 + */ + public String getJsonStr(String key) { + return key == null ? null : (String) redisTemplate.opsForValue().get(key); + } + + /** + * JsonString缓存获取 + * + * @param key 键 + * @return 值 + */ + public List getJsonToBeanList(String key, Class type) { + String jsonStr = getJsonStr(key); + if (jsonStr == null) { + return null; + } + return JSON.parseArray(jsonStr, type); + } } diff --git a/cash-common/cash-common-sa-token/pom.xml b/cash-common/cash-common-sa-token/pom.xml index b0180a360..ee53baa59 100644 --- a/cash-common/cash-common-sa-token/pom.xml +++ b/cash-common/cash-common-sa-token/pom.xml @@ -28,6 +28,11 @@ cn.dev33 sa-token-spring-boot3-starter + + com.mybatis-flex + mybatis-flex-spring-boot3-starter + provided + org.apache.tomcat.embed tomcat-embed-core diff --git a/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java b/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java index 43e9728b0..722672b62 100644 --- a/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java +++ b/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java @@ -16,7 +16,9 @@ import cn.dev33.satoken.stp.StpLogic; import cn.hutool.core.util.StrUtil; import com.czg.exception.ApiNotPrintException; import com.czg.exception.CzgException; +import com.mybatisflex.core.row.DbChain; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.Map; @@ -25,6 +27,7 @@ import java.util.function.Consumer; /** * @author Administrator */ +@Slf4j @Getter public class MyStpLogic { public static final StpLogic CLIENT_LOGIC = new StpLogic("client"); @@ -53,6 +56,34 @@ public class MyStpLogic { } } + /** + * 身份切换 + * + * @param id 用户id + * @param account 账户名 + * @param shopId 店铺id + * @param shopName 店铺名称 + * @param loginType 登录类型 + * @param isAdmin 是否管理员 + */ + public void switchTo(boolean isMain, Long id, String account, Long shopId, String shopName, LoginType loginType, boolean isAdmin) { + StpLogic logic = getLogic(); + long headId = logic.getLoginIdAsLong(); + + logic.getSaTokenDao().set(splicingKeyTokenValue(logic.getTokenValue()), id.toString(), logic.getTokenTimeout()); + SaSession session = logic.getSession(); + if (session == null) { + logic.createLoginSession(id); + session = logic.getSession(); + } + Object parentId1 = session.get("headId"); + if (!isMain && parentId1 == null) { + session.set("headId", headId); + } + session.set("userId", id).set("isAdmin", isAdmin).set("isManager", loginType.equals(LoginType.MANAGER)) + .set("loginType", loginType).set("account", account).set("shopId", shopId).set("shopName", shopName); + } + /** * @param id 登录账号id * @param shopName 店铺名称 @@ -83,6 +114,7 @@ public class MyStpLogic { SaManager.getSaTokenDao().set(SaManager.getConfig().getTokenName() + ":" + token, String.valueOf(id), SaManager.getConfig().getTimeout()); } + /** * 获取当前登录账号名称 管理端为用户账号 客户端为openId * @@ -104,6 +136,16 @@ public class MyStpLogic { return shopName instanceof String s ? s : null; } + /** + * 获取主店铺id + * + * @return id + */ + public Long getHeadId() { + Object headId = getLogic().getSession().get("headId"); + return headId == null ? null : Long.parseLong(headId.toString()); + } + /** * 获取店铺id * @@ -160,6 +202,62 @@ public class MyStpLogic { return shopId == null ? defaultVal : shopId; } + /** + * 获取适用的店铺id(主分店模式使用,若全部开启同步返回主店id。若未开启同步则返回分店id) + * + * @return 主店id + */ + public Long getUsableShopId() { + Long shopId = getShopId(0L); + Long mainId = DbChain.table("tb_shop_config").select("main_id").where("id = ? and is_enable_prod_sync = 1 and is_enable_vip_sync = 1 and is_enable_cons_sync = 1", shopId).objAs(Long.class); + if (mainId != null) { + return mainId; + } + return shopId; + } + + /** + * 获取主店id + * + * @return 主店id + */ + public Long getHeadShopId() { + Long shopId = getShopId(0L); + Long mainId = DbChain.table("tb_shop_config").select("main_id").where("id = ?", shopId).objAs(Long.class); + if (mainId != null) { + return mainId; + } + return shopId; + } + + /** + * 获取主店id + * + * @param shopId 店铺id + * @return 主店id + */ + public Long getHeadShopId(Long shopId) { + Long mainId = DbChain.table("tb_shop_config").select("main_id").where("id = ?", shopId).objAs(Long.class); + if (mainId != null) { + return mainId; + } + return shopId; + } + + /** + * 是否启用同步功能 + * + * @param shopId 店铺id + * @return 主店id + */ + public boolean isEnableSync(Long shopId) { + Integer isEnableProdSync = DbChain.table("tb_shop_config").select("is_enable_prod_sync").where("id = ?", shopId).objAs(Integer.class); + if (isEnableProdSync == null) { + return false; + } + return isEnableProdSync == 1; + } + /** * 校验是否为管理端登录 */ @@ -901,11 +999,6 @@ public class MyStpLogic { } - public void switchTo(Object loginId) { - getLogic().switchTo(loginId); - } - - public void endSwitch() { getLogic().endSwitch(); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/ShopBranchDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/ShopBranchDTO.java new file mode 100644 index 000000000..3a583cbe0 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/ShopBranchDTO.java @@ -0,0 +1,58 @@ +package com.czg.account.dto; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 分店管理DTO + * @author tankaikai + * @since 2025-04-07 14:12 + */ +@Data +public class ShopBranchDTO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 分店id + */ + private Long id; + /** + * 店铺名称 + */ + private String shopName; + /** + * 店铺类型 单店--only 连锁店--chain--加盟店join (对应原来 type) + */ + private String shopType; + /** + * 账号 + */ + private String account; + /** + * 联系电话 + */ + private String phone; + /** + * 是否启用商品同步 1-是 0-否 + */ + private Integer isEnableProdSync; + /** + * 是否启用会员同步 1-是 0-否 + */ + private Integer isEnableVipSync; + /** + * 是否启用耗材同步 1-是 0-否 + */ + private Integer isEnableConsSync; + /** + * 是否允许账号登录 1-是 0-否 + */ + private Integer isAllowAccountLogin; + /** + * 备注 + */ + private String remark; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/ShopConfigDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/ShopConfigDTO.java new file mode 100644 index 000000000..9f9b884a3 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/ShopConfigDTO.java @@ -0,0 +1,81 @@ +package com.czg.account.dto; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** +* 店铺配置扩展 +* +* @author Tankaikai tankaikai@aliyun.com +* @since 1.0 2025-04-03 +*/ +@Data +public class ShopConfigDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺id + */ + private Long id; + /** + * 主店id + */ + private Long mainId; + /** + * 是否启用商品同步 1-是 0-否 + */ + private Integer isEnableProdSync; + /** + * 是否启用会员同步 1-是 0-否 + */ + private Integer isEnableVipSync; + /** + * 是否启用耗材同步 1-是 0-否 + */ + private Integer isEnableConsSync; + /** + * 是否允许账号登录 1-是 0-否 + */ + private Integer isAllowAccountLogin; + /** + * 备注 + */ + private String remark; + /** + * 是否允许会员自定义金额 1-允许 0-不允许 + */ + private Integer isCustomAmount; + /** + * 是否开启退款密码 1-启用 0-禁用 + */ + private Integer isReturnPwd; + /** + * 是否开启会员充值密码 1-启用 0-禁用 + */ + private Integer isMemberInPwd; + /** + * 是否开启会员退款密码 1-启用 0-禁用 + */ + private Integer isMemberReturnPwd; + /** + * 是否免除桌位费 1-是 0-否 + */ + private Integer isTableFee; + /** + * 是否启用会员价 1-是 0-否 + */ + private Integer isMemberPrice; + /** + * 是否允许会员余额支付 1-是 0-否 + */ + private Integer isAccountPay; + /** + * 分店数据同步方式 auto-自动同步 manual-手动同步 + */ + private String branchDataSyncMethod; + +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/SyncNoticeDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/SyncNoticeDTO.java new file mode 100644 index 000000000..37d4e8439 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/SyncNoticeDTO.java @@ -0,0 +1,64 @@ + +package com.czg.account.dto; + +import java.io.Serializable; +import java.time.LocalDateTime; +import com.alibaba.fastjson2.annotation.JSONField; +import java.io.Serial; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 实体类。 + * + * @author zs + * @since 2025-04-07 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SyncNoticeDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long id; + + /** + * 商品名称或耗材名称 + */ + private String name; + + /** + * 来源id + */ + private Long sourceId; + + /** + * 操作用户id + */ + private Long sysUserId; + + /** + * 通知类型 0 商品变动 1 耗材变动 + */ + private Integer type; + + /** + * 是否已读,1已读 + */ + private Integer isRead; + + /** + * 店铺id + */ + private Long shopId; + + /** + * 创建时间 + */ + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/pad/PadDetailDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/pad/PadDetailDTO.java index f9916d5ce..57fd03c20 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/pad/PadDetailDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/pad/PadDetailDTO.java @@ -1,6 +1,7 @@ package com.czg.account.dto.pad; import com.czg.product.entity.Product; +import com.czg.product.vo.ProductVO; import lombok.Data; import java.util.List; @@ -13,5 +14,5 @@ public class PadDetailDTO { private Long id; private Long padLayoutId; private List productIdList; - private List productList; + private List productList; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopBranchSelectDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopBranchSelectDTO.java new file mode 100644 index 000000000..568cd0d54 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopBranchSelectDTO.java @@ -0,0 +1,27 @@ +package com.czg.account.dto.shopinfo; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 下拉店铺列表DTO + * @author tankaikai + * @since 2025-04-07 13:45 + */ +@Data +public class ShopBranchSelectDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺ID + */ + private Long shopId; + /** + * 店铺名称 + */ + private String shopName; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoAddDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoAddDTO.java index 606cf3a87..d42cb6a32 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoAddDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoAddDTO.java @@ -45,4 +45,12 @@ public class ShopInfoAddDTO { private String districts; private String provinces; private String address; + /** + * 是否为主店 + */ + private Integer isHeadShop; + /** + * 主店id + */ + private Long mainId; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java index a6e7f6dd9..d5f9b6b62 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopInfoEditDTO.java @@ -87,7 +87,7 @@ public class ShopInfoEditDTO { /** * 主店id */ - private Integer mainId; + private Long mainId; /** * 店铺口号 @@ -241,4 +241,8 @@ public class ShopInfoEditDTO { * 店铺激活码 */ private String activateCode; + /** + * 是否为主店 1-是 0-否 + */ + private Integer isHeadShop; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopConfig.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopConfig.java new file mode 100644 index 000000000..7be743baa --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopConfig.java @@ -0,0 +1,85 @@ +package com.czg.account.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 店铺配置扩展 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-04-03 + */ +@Data +@Table("tb_shop_config") +public class ShopConfig implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺id + */ + @Id(keyType = KeyType.None) + private Long id; + /** + * 主店id + */ + private Long mainId; + /** + * 是否启用商品同步 1-是 0-否 + */ + private Integer isEnableProdSync; + /** + * 是否启用会员同步 1-是 0-否 + */ + private Integer isEnableVipSync; + /** + * 是否启用耗材同步 1-是 0-否 + */ + private Integer isEnableConsSync; + /** + * 是否允许账号登录 1-是 0-否 + */ + private Integer isAllowAccountLogin; + /** + * 备注 + */ + private String remark; + /** + * 是否允许会员自定义金额 1-允许 0-不允许 + */ + private Integer isCustomAmount; + /** + * 是否开启退款密码 1-启用 0-禁用 + */ + private Integer isReturnPwd; + /** + * 是否开启会员充值密码 1-启用 0-禁用 + */ + private Integer isMemberInPwd; + /** + * 是否开启会员退款密码 1-启用 0-禁用 + */ + private Integer isMemberReturnPwd; + /** + * 是否免除桌位费 1-是 0-否 + */ + private Integer isTableFee; + /** + * 是否启用会员价 1-是 0-否 + */ + private Integer isMemberPrice; + /** + * 是否允许会员余额支付 1-是 0-否 + */ + private Integer isAccountPay; + /** + * 分店数据同步方式 auto-自动同步 manual-手动同步 + */ + private String branchDataSyncMethod; +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java index 75f702ab2..bb156e531 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopInfo.java @@ -38,7 +38,7 @@ public class ShopInfo implements Serializable { /** * 主店id */ - private Integer mainId; + private Long mainId; /** * 店铺口号 @@ -90,7 +90,7 @@ public class ShopInfo implements Serializable { */ private String detail; /** - * 注册类型 + * 注册类型(经营模式) * 快餐版 先付 munchies * 餐饮版 先付/后付 restaurant */ @@ -187,46 +187,11 @@ public class ShopInfo implements Serializable { */ private String address; - /** - * 是否允许会员自定义金额 1 允许 0 不允许 - */ - private Integer isCustomAmount; - - /** - * 是否开启退款密码 1 启用 0 禁用 - */ - private Integer isReturnPwd; - - /** - * 是否开启会员充值密码 1 启用 0 禁用 - */ - private Integer isMemberInPwd; - - /** - * 是否开启会员退款密码 1 启用 0 禁用 - */ - private Integer isMemberReturnPwd; - - /** - * 是否免除桌位费 0否1是 - */ - private Integer isTableFee; - - /** - * 是否开启会员余额支付 - */ - private Integer isAccountPay; - /** * 桌位费 */ private BigDecimal tableFee; - /** - * 是否启用会员价 0否1是 - */ - private Integer isMemberPrice; - /** * 就餐模式 堂食 dine-in 外带 take-out */ @@ -271,5 +236,69 @@ public class ShopInfo implements Serializable { * 税率 */ private String taxAmount; + /** + * 是否主店 1-是 0-否 + */ + private Integer isHeadShop; + /** + * 是否启用商品同步 1-是 0-否 + */ + @Column(ignore = true) + private Integer isEnableProdSync; + /** + * 是否启用会员同步 1-是 0-否 + */ + @Column(ignore = true) + private Integer isEnableVipSync; + /** + * 是否启用耗材同步 1-是 0-否 + */ + @Column(ignore = true) + private Integer isEnableConsSync; + /** + * 是否允许账号登录 1-是 0-否 + */ + @Column(ignore = true) + private Integer isAllowAccountLogin; + /** + * 是否允许会员自定义金额 1-允许 0-不允许 + */ + @Column(ignore = true) + private Integer isCustomAmount; + /** + * 是否开启退款密码 1-启用 0-禁用 + */ + @Column(ignore = true) + private Integer isReturnPwd; + /** + * 是否开启会员充值密码 1-启用 0-禁用 + */ + @Column(ignore = true) + private Integer isMemberInPwd; + /** + * 是否开启会员退款密码 1-启用 0-禁用 + */ + @Column(ignore = true) + private Integer isMemberReturnPwd; + /** + * 是否免除桌位费 1-是 0-否 + */ + @Column(ignore = true) + private Integer isTableFee; + /** + * 是否启用会员价 1-是 0-否 + */ + @Column(ignore = true) + private Integer isMemberPrice; + /** + * 是否允许会员余额支付 1-是 0-否 + */ + @Column(ignore = true) + private Integer isAccountPay; + /** + * 主店名称 + */ + @Column(ignore = true) + private String headShopName; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopUser.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopUser.java index c74ed623d..1ca16bc44 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopUser.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/ShopUser.java @@ -125,4 +125,8 @@ public class ShopUser implements Serializable { @Column(onInsertValue = "now()", onUpdateValue = "now()") private LocalDateTime updateTime; + /** + * 已经合并过来的用户信息,jsonArray格式,[{"id":1,"shopId":2,...},{"id":1,"shopId":2,...}] + */ + private String mergedUsers; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SyncNotice.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SyncNotice.java new file mode 100644 index 000000000..3609cb97c --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SyncNotice.java @@ -0,0 +1,82 @@ +package com.czg.account.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.time.LocalDateTime; + +import java.io.Serial; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 实体类。 + * + * @author zs + * @since 2025-04-07 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("tb_sync_notice") +public class SyncNotice implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Id(keyType = KeyType.Auto) + private Long id; + + /** + * 操作用户id + */ + private Long sysUserId; + + + /** + * 是否已读,1已读 + */ + private Integer isRead; + + /** + * 店铺id + */ + private Long shopId; + /** + * 标题 数据同步/数据变动/库存预警 + */ + private String title; + /** + * 消息内容 + * { + * "title": "XX同步/变动",//商品 单位 规格 分组 耗材 耗材分组 + * "number": "XX个", + * "map": [ + * { + * "id": 1, + * "name": "" + * } + * ] + * } + * { + * "title": "XX库存不足" //商品/耗材 + * } + */ + private String content; + + private String extraJson; + + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + private LocalDateTime readTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/enums/BranchDataSyncMethodEnum.java b/cash-common/cash-common-service/src/main/java/com/czg/account/enums/BranchDataSyncMethodEnum.java new file mode 100644 index 000000000..a3d23ba27 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/enums/BranchDataSyncMethodEnum.java @@ -0,0 +1,47 @@ +package com.czg.account.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * 分店数据同步方式枚举 + * + * @author tankaikai + * @since 2025-04-03 16:53 + */ +@Getter +@RequiredArgsConstructor +public enum BranchDataSyncMethodEnum { + /** + * 实时自动同步 + */ + AUTO("auto", "实时自动同步"), + /** + * 手动同步 + */ + MANUAL("manual", "手动同步"); + + private final String value; + private final String text; + + + public static List getValues() { + return Arrays.stream(values()).map(BranchDataSyncMethodEnum::getValue).toList(); + } + + public static String getText(String value) { + BranchDataSyncMethodEnum item = Arrays.stream(values()).filter(obj -> value.equals(obj.getValue())).findFirst().orElse(null); + if (item != null) { + return item.getText(); + } + return null; + } + + public static boolean checkValue(String value) { + return getValues().contains(value); + } + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/enums/ShopTypeEnum.java b/cash-common/cash-common-service/src/main/java/com/czg/account/enums/ShopTypeEnum.java new file mode 100644 index 000000000..a000deed9 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/enums/ShopTypeEnum.java @@ -0,0 +1,48 @@ +package com.czg.account.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.List; + +/** + * 店铺经营模式枚举 + * + * @author tankaikai + * @since 2025-04-03 16:53 + */ +@Getter +@RequiredArgsConstructor +public enum ShopTypeEnum { + /** + * 单店 + */ + ONLY("only", "单店"), + /** + * 连锁店 + */ + CHAIN("chain", "连锁店"), + /** + * 加盟店 + */ + JOIN("join", "加盟店"), + ; + + private final String value; + private final String text; + + + public static List getValues() { + return Arrays.stream(values()).map(ShopTypeEnum::getValue).toList(); + } + + public static String getText(String value) { + ShopTypeEnum item = Arrays.stream(values()).filter(obj -> value.equals(obj.getValue())).findFirst().orElse(null); + if (item != null) { + return item.getText(); + } + return null; + } + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/param/ShopBranchParam.java b/cash-common/cash-common-service/src/main/java/com/czg/account/param/ShopBranchParam.java new file mode 100644 index 000000000..e9847f256 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/param/ShopBranchParam.java @@ -0,0 +1,30 @@ +package com.czg.account.param; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 分店查询入参 + * @author tankaikai + * @since 2025-04-07 18:02 + */ +@Data +public class ShopBranchParam implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 分店名称 + */ + private String branchShopName; + + /** + * 店铺ID + */ + @JSONField(serialize = false) + private Long shopId; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/AuthorizationService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/AuthorizationService.java index 14242000a..1a6663401 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/AuthorizationService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/AuthorizationService.java @@ -11,4 +11,10 @@ public interface AuthorizationService { Object getCaptcha(); LoginVO login(SysLoginDTO loginDTO, String platformType); + + /** + * 切换登录用户 + * @param sysUserId 系统用户id + */ + void switchTo(Long sysUserId); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopBranchService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopBranchService.java new file mode 100644 index 000000000..00e1eb689 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopBranchService.java @@ -0,0 +1,54 @@ +package com.czg.account.service; + +import com.czg.account.dto.ShopBranchDTO; +import com.czg.account.param.ShopBranchParam; +import com.mybatisflex.core.paginate.Page; + +/** + * 分店管理Service + * + * @author tankaikai + * @since 2025-04-07 14:09 + */ +public interface ShopBranchService { + /** + * 查询分店列表 + * + * @param param 查询入参 + * @return 分店列表 + */ + Page findPage(ShopBranchParam param); + + /** + * 设计数据同步方式 + * + * @param shopId 主店id + * @param dataSyncMethod 数据同步方式 {@link com.czg.account.enums.BranchDataSyncMethodEnum} + */ + void settingDataSyncMethod(Long shopId, String dataSyncMethod); + + /** + * 数据同步启用 + * @param branchShopId 分店id + */ + void dataSyncEnable(Long branchShopId); + + /** + * 账号启用 + * @param branchShopId 分店id + */ + void accountEnable(Long branchShopId); + + /** + * 账号禁用 + * @param branchShopId 分店id + */ + void accountDisable(Long branchShopId); + + /** + * 查询是否允许分店账号登录 + * @param branchShopId 分店id + * @return 是否允许分店账号登录 {@code true} 允许,{@code false} 不允许 + */ + boolean isAllowAccountLogin(Long branchShopId); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopConfigService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopConfigService.java new file mode 100644 index 000000000..cea58cb4e --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopConfigService.java @@ -0,0 +1,14 @@ +package com.czg.account.service; + +import com.czg.account.entity.ShopConfig; +import com.mybatisflex.core.service.IService; + +/** + * 店铺配置扩展 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-04-03 + */ +public interface ShopConfigService extends IService { + +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java index ad305df8d..554fdda5a 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java @@ -6,11 +6,13 @@ import com.czg.account.entity.ShopInfo; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; +import java.util.List; + /** * @author Administrator */ public interface ShopInfoService extends IService { - Page get(PageDTO pageDTO, String shopName, Integer status); + Page get(PageDTO pageDTO, String shopName, Integer status, Integer isHeadShop); Boolean add(ShopInfoAddDTO shopInfoAddDTO); @@ -24,4 +26,5 @@ public interface ShopInfoService extends IService { Page getSubList(String lat, String lng, float distance); + List findShopBranch(Long shopId); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopUserSyncService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopUserSyncService.java new file mode 100644 index 000000000..d31330d63 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopUserSyncService.java @@ -0,0 +1,17 @@ +package com.czg.account.service; + +/** + * 店铺用户同步Service + * @author tankaikai + * @since 2025-04-08 10:17 + */ +public interface ShopUserSyncService { + + /** + * 同步合并主分店会员信息 + * + * @param headShopId 主店id + * @param branchShopId 分店id + */ + void syncMergeShopUser(Long headShopId, Long branchShopId); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/SyncNoticeService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/SyncNoticeService.java new file mode 100644 index 000000000..d42ab8f02 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/SyncNoticeService.java @@ -0,0 +1,56 @@ +package com.czg.account.service; + +import com.czg.product.dto.SyncNoticeReadDTO; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.service.IService; +import com.czg.account.entity.SyncNotice; + +import java.util.List; + +/** + * 服务层。 + * + * @author zs + * @since 2025-04-07 + */ +public interface SyncNoticeService extends IService { + /** + * 添加消息 + * + * @param shopId 店铺id + * @param sysUserId 操作用户id + * @param name 商品/耗材名称 + * @param id 商品/耗材id + * @param type 0 商品新增 1 商品编辑 2 耗材新增 3 耗材编辑 + */ + void addNotice(Long shopId, Long sysUserId, String name, Long id, Integer type); + + /** + * + * @param shopId 店铺ID + * @param sysUserId 操作人Id + * @param title 标题 数据同步/数据变动/库存预警 + * @param content 消息内容 + * { + * "title": "XX同步/变动",//商品 单位 规格 分组 耗材 耗材分组 + * "number": "XX个", + * "map": [ + * { + * "id": 1, + * "name": "" + * } + * ] + * } + * { + * "title": "XX库存不足" //商品/耗材 + * } + * + * @param extraJson 扩展数据 + */ + void addNotice(Long shopId, Long sysUserId, String title, String content, String extraJson); + + Page pageInfo(Long shopId, String name, String startTime, String endTime, String title, Integer isRead); + + Boolean read(Long shopId, SyncNoticeReadDTO syncNoticeReadDTO); + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java index 9e149dfd8..bd0c27c1b 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/OrderInfo.java @@ -23,7 +23,6 @@ import lombok.NoArgsConstructor; * @since 2025-02-13 */ @Data - @NoArgsConstructor @AllArgsConstructor @Table("tb_order_info") @@ -128,6 +127,10 @@ public class OrderInfo implements Serializable { * 台桌名称 */ private String tableName; + /** + * 退款方式 现金退款-cash 原路退回-payBack + */ + private String refundType; /** * 订单类型- diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java index 1b6f44da3..33fb14ba6 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopOrderStatistic.java @@ -1,7 +1,6 @@ package com.czg.order.entity; import com.alibaba.fastjson2.annotation.JSONField; -import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.Table; @@ -141,7 +140,6 @@ public class ShopOrderStatistic implements Serializable { /** * 新增会员数 */ - @Column(ignore = true) private Long newMemberCount = 0L; /** * 店铺id diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java index 6dc26364b..e87bacbad 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopProdStatistic.java @@ -3,16 +3,15 @@ package com.czg.order.entity; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.Table; -import java.io.Serializable; -import java.math.BigDecimal; -import java.sql.Date; - -import java.io.Serial; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + /** * 实体类。 * diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java index 6d5312e9a..7eeb9427f 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/entity/ShopTableOrderStatistic.java @@ -3,16 +3,15 @@ package com.czg.order.entity; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.Table; -import java.io.Serializable; -import java.math.BigDecimal; -import java.sql.Date; - -import java.io.Serial; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + /** * 台桌订单统计表 实体类。 * @@ -32,8 +31,22 @@ public class ShopTableOrderStatistic implements Serializable { @Id(keyType = KeyType.Auto) private Long id; + /** + * 台桌id + */ private Long tableId; - + /** + * 台桌id + */ + private String tableCode; + /** + * 台桌名称 + */ + private String tableName; + /** + * 区域名称 + */ + private String areaName; /** * 订单数量 */ @@ -56,7 +69,7 @@ public class ShopTableOrderStatistic implements Serializable { /** * 退款数量 */ - private long refundCount; + private Long refundCount; /** * 退款金额 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryProductSaleParam.java b/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryProductSaleParam.java index 2b8a185a9..a7ae4cb24 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryProductSaleParam.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryProductSaleParam.java @@ -34,7 +34,6 @@ public class DataSummaryProductSaleParam implements Serializable { /** * 店铺id */ - @JSONField(serialize = false) private Long shopId; /** * 开始日期 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java b/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java index 3b71ed0fe..a9099adfc 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/param/DataSummaryTradeParam.java @@ -1,6 +1,5 @@ package com.czg.order.param; -import com.alibaba.fastjson2.annotation.JSONField; import com.czg.validator.group.DefaultGroup; import jakarta.validation.constraints.NotBlank; import lombok.Data; @@ -33,7 +32,6 @@ public class DataSummaryTradeParam implements Serializable { /** * 店铺id */ - @JSONField(serialize = false) private Long shopId; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java b/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java index f64ae7f87..671680549 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/param/SaleSummaryCountParam.java @@ -1,6 +1,5 @@ package com.czg.order.param; -import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; import java.io.Serial; @@ -20,7 +19,6 @@ public class SaleSummaryCountParam implements Serializable { /** * 店铺id */ - @JSONField(serialize = false) private Long shopId; /** * 商品名称 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/param/TableSummaryParam.java b/cash-common/cash-common-service/src/main/java/com/czg/order/param/TableSummaryParam.java index 54c618db8..fedbe4202 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/param/TableSummaryParam.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/param/TableSummaryParam.java @@ -1,6 +1,5 @@ package com.czg.order.param; -import com.alibaba.fastjson2.annotation.JSONField; import lombok.Data; import java.io.Serial; @@ -29,7 +28,6 @@ public class TableSummaryParam implements Serializable { /** * 店铺id */ - @JSONField(serialize = false) private Long shopId; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/DataSummaryService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/DataSummaryService.java index c1ba00493..387702ca1 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/DataSummaryService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/DataSummaryService.java @@ -18,7 +18,9 @@ import java.util.List; */ public interface DataSummaryService { - ShopOrderStatistic getTradeData(DataSummaryTradeParam param); + ShopOrderStatistic getArchiveTradeData(DataSummaryTradeParam param); + + ShopOrderStatistic getRealTimeTradeData(DataSummaryTradeParam param); Page getProductSaleRankingPage(DataSummaryProductSaleParam param); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java index 3cd54daa2..68dd4c8ab 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopOrderStatisticService.java @@ -1,7 +1,8 @@ package com.czg.order.service; -import com.mybatisflex.core.service.IService; +import cn.hutool.core.date.DateTime; import com.czg.order.entity.ShopOrderStatistic; +import com.mybatisflex.core.service.IService; /** * 服务层。 @@ -11,6 +12,6 @@ import com.czg.order.entity.ShopOrderStatistic; */ public interface ShopOrderStatisticService extends IService { - void statistic(); + void statistic(DateTime dateTime); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java index b7c27ee57..6e1b37906 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopProdStatisticService.java @@ -1,7 +1,8 @@ package com.czg.order.service; -import com.mybatisflex.core.service.IService; +import cn.hutool.core.date.DateTime; import com.czg.order.entity.ShopProdStatistic; +import com.mybatisflex.core.service.IService; /** * 服务层。 @@ -11,6 +12,6 @@ import com.czg.order.entity.ShopProdStatistic; */ public interface ShopProdStatisticService extends IService { - void statistic(); + void statistic(DateTime dateTime); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java index 350826982..15f3314bc 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/ShopTableOrderStatisticService.java @@ -1,8 +1,9 @@ package com.czg.order.service; +import cn.hutool.core.date.DateTime; +import com.czg.order.entity.ShopTableOrderStatistic; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; -import com.czg.order.entity.ShopTableOrderStatistic; import java.math.BigDecimal; @@ -25,5 +26,5 @@ public interface ShopTableOrderStatisticService extends IService total = new ArrayList<>(); - /** - * TotalVo - */ - @NoArgsConstructor - @Data - public static class TotalVo { - /** - * 实收金额 - */ - private BigDecimal actualAmount = BigDecimal.ZERO; - /** - * 优惠金额 - */ - private BigDecimal discountAmount = BigDecimal.ZERO; - /** - * 订单金额 - */ - private BigDecimal orderAmount = BigDecimal.ZERO; - /** - * 日期 - */ - private String tradeDay; - } } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryProductSaleRankingVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryProductSaleRankingVo.java index 5f3ce9942..8c9d0a1a7 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryProductSaleRankingVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/DataSummaryProductSaleRankingVo.java @@ -19,6 +19,11 @@ public class DataSummaryProductSaleRankingVo implements Serializable { @Serial private static final long serialVersionUID = 1L; + /** + * 商品名称 + */ + private Long productId; + /** * 商品名称 */ @@ -34,4 +39,14 @@ public class DataSummaryProductSaleRankingVo implements Serializable { */ private BigDecimal amount; + /** + * 退单量 + */ + private BigDecimal refundCount; + + /** + * 退单金额 + */ + private BigDecimal refundAmount; + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java index f5c1ccff7..b79f70054 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/OrderInfoVo.java @@ -71,6 +71,10 @@ public class OrderInfoVo implements Serializable { * miniapp小程序 */ private String orderType; + /** + * 退款方式 现金退款-cash 原路退回-payBack + */ + private String refundType; /** * 平台类型 pc 收银机客户端 wechat 微信小程序 alipay 支付宝小程序 admin-pc PC管理端 admin-app APP管理端 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TableSummaryInfoVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TableSummaryInfoVo.java index ccc960989..23418702f 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TableSummaryInfoVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TableSummaryInfoVo.java @@ -32,6 +32,11 @@ public class TableSummaryInfoVo implements Serializable { @ExcelIgnore @JSONField(serialize = false) private Long lineNum; + /** + * 台桌id + */ + @ExcelIgnore + private Long tableId; /** * 台桌码 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TotalVo.java b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TotalVo.java new file mode 100644 index 000000000..8b9c4741c --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/vo/TotalVo.java @@ -0,0 +1,38 @@ +package com.czg.order.vo; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 销售趋势柱状图 左下 + * @author tankaikai + * @since 2025-03-07 16:08 + */ +@NoArgsConstructor +@Data +public class TotalVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 实收金额 + */ + private BigDecimal actualAmount = BigDecimal.ZERO; + /** + * 优惠金额 + */ + private BigDecimal discountAmount = BigDecimal.ZERO; + /** + * 订单金额 + */ + private BigDecimal orderAmount = BigDecimal.ZERO; + /** + * 日期 + */ + private String tradeDay; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java index c0b0cedfe..4aa231d98 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java @@ -97,6 +97,7 @@ public class ConsStockFlowDTO implements Serializable { * 商品id */ private Long productId; + private String productName; /** * sku id */ @@ -127,4 +128,6 @@ public class ConsStockFlowDTO implements Serializable { */ private String remark; -} \ No newline at end of file + private String vendorName; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProdConsRelationDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProdConsRelationDTO.java index 3bc0f820b..419807a92 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProdConsRelationDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProdConsRelationDTO.java @@ -22,10 +22,6 @@ public class ProdConsRelationDTO implements Serializable { @Serial private static final long serialVersionUID = 1L; - /** - * id - */ - private Long id; /** * 店铺id */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdSpecDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdSpecDTO.java index 185fcdc9d..8630358de 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdSpecDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ShopProdSpecDTO.java @@ -12,6 +12,7 @@ import lombok.EqualsAndHashCode; import java.io.Serial; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.List; /** * 商品规格 @@ -81,5 +82,9 @@ public class ShopProdSpecDTO extends TreeNode implements Serial */ @JSONField(format = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; - + /** + * 受影响的规格id列表 + */ + @JSONField(serialize = false) + private List affectedIdList; } \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/SyncNoticeReadDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/SyncNoticeReadDTO.java new file mode 100644 index 000000000..481b2b17c --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/SyncNoticeReadDTO.java @@ -0,0 +1,17 @@ +package com.czg.product.dto; + +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +/** + * @author Administrator + */ +@Data +public class SyncNoticeReadDTO { + /** + * 消息id + */ + private List noticeIdList; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsGroup.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsGroup.java index b9462deed..12c4081c0 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsGroup.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsGroup.java @@ -28,6 +28,10 @@ public class ConsGroup implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 店铺id */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsInfo.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsInfo.java index 02d68632a..8fdb6eb30 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsInfo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsInfo.java @@ -29,6 +29,10 @@ public class ConsInfo implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 耗材分组id */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdConsRelation.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdConsRelation.java index c6e8a7bdd..dc029cf8d 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdConsRelation.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdConsRelation.java @@ -24,22 +24,20 @@ public class ProdConsRelation implements Serializable { @Serial private static final long serialVersionUID = 1L; - /** - * id - */ - @Id(keyType = KeyType.Auto) - private Long id; /** * 店铺id */ + @Id(keyType = KeyType.None) private Long shopId; /** * 商品id */ + @Id(keyType = KeyType.None) private Long productId; /** * 耗材id */ + @Id(keyType = KeyType.None) private Long consInfoId; /** * 单位消耗值 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdGroup.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdGroup.java index 6618ba841..a0ceb75c2 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdGroup.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdGroup.java @@ -29,6 +29,10 @@ public class ProdGroup implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 分组名称 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdSku.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdSku.java index e5be710e1..236e59984 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdSku.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ProdSku.java @@ -29,6 +29,10 @@ public class ProdSku implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 店铺id */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/Product.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/Product.java index 95f3a7390..91fdd421e 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/Product.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/Product.java @@ -30,6 +30,10 @@ public class Product implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 商品分类 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java index ecd25265f..b0d2be6c1 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdCategory.java @@ -28,6 +28,10 @@ public class ShopProdCategory implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 分类名称 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdSpec.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdSpec.java index 353ddeda7..61b796e7e 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdSpec.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdSpec.java @@ -28,6 +28,10 @@ public class ShopProdSpec implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 规格名称 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdUnit.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdUnit.java index 0dec8e2f9..3d917afe7 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdUnit.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopProdUnit.java @@ -28,6 +28,10 @@ public class ShopProdUnit implements Serializable { */ @Id(keyType = KeyType.Auto) private Long id; + /** + * 同步id + */ + private Long syncId; /** * 单位名称 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopVendor.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopVendor.java index e419707cc..4aa4297da 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopVendor.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ShopVendor.java @@ -32,6 +32,7 @@ public class ShopVendor implements Serializable { * 店铺Id */ private Long shopId; + private Long syncId; /** * 排序 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java index 259aeef19..97544bbdb 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java @@ -1,5 +1,7 @@ package com.czg.product.service; +import com.czg.product.vo.ProductVO; + import java.util.List; import java.util.Map; @@ -36,4 +38,13 @@ public interface ProductRpcService { * @param dataList 库存恢复数据 */ void orderRefundReturnStock(Long shopId, Long orderId, List> dataList); + + List listAndLowPrice(Long shopId, List productIds); + + /** + * 清除分类商品缓存 + * @param shopId 店铺id + * @param categoryId 商品分类id + */ + void cleanCategoryProduct(Long shopId, Long categoryId); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java index f6e0a5cd7..54ceaeace 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductService.java @@ -33,6 +33,19 @@ public interface ProductService extends IService { */ List getProductList(ProductDTO param); + /** + * 从缓存里面获取商品列表 + * + * @param param 查询参数 + * @return 商品列表数据 + */ + List getProductCacheList(ProductDTO param); + + /** + * 清除某个商品分类的缓存 + */ + void clearProductCache(Long... categoryIds); + /** * 获取商品详情 * @@ -127,4 +140,5 @@ public interface ProductService extends IService { * @param records 商品数据集合 */ void refreshProductStock(ProductDTO param, List records); + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdUnitService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdUnitService.java index be9b3989b..c45f856e5 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdUnitService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopProdUnitService.java @@ -25,6 +25,7 @@ public interface ShopProdUnitService extends IService { /** * 获取商品单位列表 + * * @param param 查询参数 * @return 商品单位列表数据 */ @@ -32,6 +33,7 @@ public interface ShopProdUnitService extends IService { /** * 获取商品单位详情 + * * @param id 商品单位ID * @return 商品单位详情数据 */ @@ -41,8 +43,9 @@ public interface ShopProdUnitService extends IService { * 新增商品单位 * * @param dto 商品单位数据 + * @return 新增商品单位ID */ - void addShopProdUnit(ShopProdUnitDTO dto); + Long addShopProdUnit(ShopProdUnitDTO dto); /** * 更新商品单位 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopSyncService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopSyncService.java new file mode 100644 index 000000000..f1620def1 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopSyncService.java @@ -0,0 +1,88 @@ +package com.czg.product.service; + +/** + * @author ww + * @description + */ +public interface ShopSyncService { + + /** + * 同步数据 将源店铺信息 同步到目标店铺(包括分组 分类 单位 规格 商品 SKU 耗材) + * + * @param sourceShopId 源店铺ID + * @param targetShopId 目标店铺ID + */ + void sync(Long sourceShopId, Long targetShopId, Long sysUserId); + + /** + * 同步单位(新增/修改字段/逻辑删除 不包含删除) 将源店铺的单位同步到 开了同步商品开关的子店铺 + * + * @param sourceShopId 主店ID + * @param unitId 主店单位Id + */ + void syncUnitBySourceShop(Long sourceShopId, Long unitId, Long sysUserId); + + /** + * 同步规格(新增/修改字段/逻辑删除 不包含删除) 将源店铺的规格同步到 开了同步商品开关的子店铺 + * + * @param sourceShopId 主店ID + * @param specId 主店规格Id + */ + void syncSpecBySourceShop(Long sourceShopId, Long specId, Long sysUserId); + + /** + * 同步分类(新增/修改字段/逻辑删除 不包含删除) 将源店铺的分类同步到 开了同步商品开关的子店铺 + * + * @param sourceShopId 主店ID + * @param categoryId 主店分类Id + */ + void syncCategoryBySourceShop(Long sourceShopId, Long categoryId, Long sysUserId); + + /** + * 同步商品 会同步Sku(新增/修改字段/逻辑删除 不包含删除) 将源店铺的商品同步到 开了同步商品开关的子店铺 + * + * @param sourceShopId 主店ID + * @param productId 主店商品Id + */ + void syncProductBySourceShop(Long sourceShopId, Long productId, Long sysUserId); + + /** + * 同步分组 (新增/修改字段/逻辑删除 不包含删除) 将源店铺的分组同步到 开了同步商品开关的子店铺 + * + * @param sourceShopId 主店ID + * @param groupId 主店分组Id + */ + void syncGroupBySourceShop(Long sourceShopId, Long groupId, Long sysUserId); + + /** + * 同步耗材分组 (新增/修改字段/逻辑删除 不包含删除) 将源店铺的耗材分组同步到 开了同步耗材开关的子店铺 + * + * @param sourceShopId 主店ID + * @param consGroupId 主店耗材分组Id + */ + void syncConsGroupBySourceShop(Long sourceShopId, Long consGroupId, Long sysUserId); + + /** + * 同步耗材信息(新增/修改字段/逻辑删除 不包含删除) 将源店铺的耗材信息同步到 开了同步耗材开关的子店铺 + * + * @param sourceShopId 主店ID + * @param consInfoId 主店ID + */ + void syncConsInfoBySourceShop(Long sourceShopId, Long consInfoId, Long sysUserId); + + /** + * 同步商品绑定耗材关联关系 开了同步耗材开关的子店铺 + * + * @param sourceShopId 主店ID + * @param sourceProdId 主店商品ID + */ + void syncConsProBySourceShop(Long sourceShopId, Long sourceProdId, Long sysUserId); + + /** + * 同步供应商 开了同步耗材开关的子店铺 + * + * @param sourceShopId 主店ID + * @param vendorId 供应商Id + */ + void syncVendorBySourceShop(Long sourceShopId, Long vendorId, Long sysUserId); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopVendorService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopVendorService.java index 493d86aa7..3ca516bf3 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopVendorService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ShopVendorService.java @@ -70,7 +70,7 @@ public interface ShopVendorService extends IService { * @param shopId 店铺id * @return 账单 */ - Page billList(Long shopId); + Page billList(Long shopId, String key); /** * 账单记录明细 @@ -79,7 +79,7 @@ public interface ShopVendorService extends IService { * @param vendorId 供应商id * @return 分页 */ - Page billRecord(Long shopId, Integer vendorId); + Page billRecord(Long shopId, Integer vendorId, String key); /** * 账单付款 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/UProductService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/UProductService.java index 653222761..9562eb758 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/service/UProductService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/UProductService.java @@ -78,12 +78,13 @@ public interface UProductService extends IService { /** * 分组计算是否在可售时间内 * + * @param prodIsSaleTime 商品是否可售 * @param useTime 开启时间管控 0:否;1:是 * @param startTime 起售时间 * @param endTime 停售时间 * @return 是否可售时间 1-是,0-否 */ - Integer calcIsSaleTime(Integer useTime, LocalTime startTime, LocalTime endTime); + Integer calcIsSaleTime(int prodIsSaleTime, Integer useTime, LocalTime startTime, LocalTime endTime); /** * 商品计算是否在可售时间内 diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ProductGroupVo.java b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ProductGroupVo.java index 2b98ab91e..9fd10e116 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ProductGroupVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ProductGroupVo.java @@ -40,7 +40,7 @@ public class ProductGroupVo implements Serializable { /** * 商品ID */ - private Integer proId; + private Long proId; /** * 商品名称 */ @@ -48,7 +48,7 @@ public class ProductGroupVo implements Serializable { /** * skuId */ - private Integer skuId; + private Long skuId; /** * sku名称 */ diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ProductVO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ProductVO.java new file mode 100644 index 000000000..917eadf43 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ProductVO.java @@ -0,0 +1,20 @@ +package com.czg.product.vo; + +import com.czg.product.entity.ProdSku; +import com.czg.product.entity.Product; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author Administrator + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ProductVO extends Product { + private BigDecimal lowPrice; + private List skuList; + private Integer isSaleTime; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java index 04f0a5257..9d2214134 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java @@ -67,11 +67,27 @@ public class ShopProductSkuInfoVo implements Serializable { */ private BigDecimal realSalesNumber; /** - * 是否售罄 + * 是否售罄(同isSoldStock) */ private Integer isPauseSale; /** * 商品库存 */ private Integer stockNumber; + /** + * 是否售罄(isPauseSale) + */ + private Integer isSoldStock; + /** + * 是否上架(同isGrounding) + */ + private Integer isSale; + /** + * 是否开启库存 + */ + private Integer isStock; + /** + * 是否上架(同isSale) + */ + private Integer isGrounding; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductVo.java b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductVo.java index 2a22bd09e..15ef4e9d5 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductVo.java @@ -109,4 +109,12 @@ public class ShopProductVo implements Serializable { * 销量 */ private BigDecimal salesVolume; + /** + * 店铺id + */ + private Long shopId; + /** + * 是否开启库存 + */ + private Integer isStock; } diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/constant/CacheConstant.java b/cash-common/cash-common-tools/src/main/java/com/czg/constant/CacheConstant.java index 0622fe6c0..d3c02be7c 100644 --- a/cash-common/cash-common-tools/src/main/java/com/czg/constant/CacheConstant.java +++ b/cash-common/cash-common-tools/src/main/java/com/czg/constant/CacheConstant.java @@ -27,4 +27,8 @@ public interface CacheConstant { * 点餐机PC端商品列表 */ String ADMIN_CLIENT_PRODUCT_LIST = ADMIN_CLIENT_PRODUCT_INFO + "list"; + /** + * 点餐机PC端商品列表 + */ + String SHOP_PRODUCT_STOCK = "shop:{}:product-stock:{}"; } diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/utils/PageUtil.java b/cash-common/cash-common-tools/src/main/java/com/czg/utils/PageUtil.java index 9a9851d98..e175a116c 100644 --- a/cash-common/cash-common-tools/src/main/java/com/czg/utils/PageUtil.java +++ b/cash-common/cash-common-tools/src/main/java/com/czg/utils/PageUtil.java @@ -73,9 +73,14 @@ public class PageUtil { */ public QueryWrapper buildSortQueryWrapper() { QueryWrapper queryWrapper = QueryWrapper.create(); - String orderBy = ServletUtil.getRequest().getParameter(ORDER_BY); - if (StrUtil.isNotEmpty(orderBy)) { - queryWrapper.orderBy(SqlUtil.escapeOrderBySql(orderBy)); + try { + HttpServletRequest request = ServletUtil.getRequest(); + String orderBy = request.getParameter(ORDER_BY); + if (StrUtil.isNotEmpty(orderBy)) { + queryWrapper.orderBy(SqlUtil.escapeOrderBySql(orderBy)); + } + } catch (Exception e) { + //System.out.println("排序参数异常"); } return queryWrapper; } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopConfigMapper.java b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopConfigMapper.java new file mode 100644 index 000000000..97074ef8e --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/ShopConfigMapper.java @@ -0,0 +1,22 @@ +package com.czg.service.account.mapper; + +import com.czg.account.dto.ShopBranchDTO; +import com.czg.account.entity.ShopConfig; +import com.czg.account.param.ShopBranchParam; +import com.mybatisflex.core.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 店铺配置扩展 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-04-03 + */ +@Mapper +public interface ShopConfigMapper extends BaseMapper { + + List findBranchList(ShopBranchParam param); + +} \ No newline at end of file diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/SyncNoticeMapper.java b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/SyncNoticeMapper.java new file mode 100644 index 000000000..4912daa78 --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/SyncNoticeMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.account.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.account.entity.SyncNotice; + +/** + * 映射层。 + * + * @author zs + * @since 2025-04-07 + */ +public interface SyncNoticeMapper extends BaseMapper { + +} diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/SysMenuMapper.java b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/SysMenuMapper.java index 0660db6b9..937f02423 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/mapper/SysMenuMapper.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/mapper/SysMenuMapper.java @@ -16,4 +16,5 @@ public interface SysMenuMapper extends BaseMapper { List selectByUserId(@Param("userId") Long userId, @Param("type") Integer type); + List selectByRoleId(@Param("roleId") Long roleId); } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java index d56aba815..849bc8e37 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java @@ -1,5 +1,6 @@ package com.czg.service.account.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; @@ -12,6 +13,7 @@ import com.czg.account.vo.LoginVO; import com.czg.config.RedisCst; import com.czg.enums.PlatformTypeEnum; import com.czg.enums.StatusEnum; +import com.czg.enums.YesNoEnum; import com.czg.exception.ApiNotPrintException; import com.czg.sa.MyStpLogic; import com.czg.sa.StpKit; @@ -49,6 +51,8 @@ public class AuthorizationServiceImpl implements AuthorizationService { @Resource private SysMenuMapper sysMenuMapper; @Resource + private ShopBranchService shopBranchService; + @Resource private HandoverRecordService handoverRecordService; @@ -140,7 +144,10 @@ public class AuthorizationServiceImpl implements AuthorizationService { throw new ApiNotPrintException("店铺已到期,请联系区域经理续费"); } } - + boolean isAllowAccountLogin = shopBranchService.isAllowAccountLogin(shopInfo.getId()); + if (!isAllowAccountLogin) { + throw new ApiNotPrintException("当前分店账号被禁止登录"); + } StpKit.USER.login(user.getId(), user.getAccount(), shopInfo.getId(), shopInfo.getShopName(), isStaff ? MyStpLogic.LoginType.STAFF : MyStpLogic.LoginType.MANAGER, user.getIsAdmin()); // 查询角色 List roleList = sysRoleService.getByUserId(user.getId()); @@ -148,14 +155,22 @@ public class AuthorizationServiceImpl implements AuthorizationService { if (user.getIsAdmin()) { roleNames.add("admin"); } - StpKit.USER.addRoleList(roleNames); // 权限赋予 List promissionList = sysMenuMapper.selectByUserId(user.getId(), null).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).collect(Collectors.toList()); // 加入员工权限 if (shopStaffPromissionList != null && !shopStaffPromissionList.isEmpty()) { promissionList.addAll(shopStaffPromissionList); } - + boolean isEnableSync = StpKit.USER.isEnableSync(shopInfo.getId()); + if (isEnableSync && CollUtil.contains(roleNames, "商户")) { + roleNames.remove("商户"); + roleNames.add("分店商户"); + List headShopPromissionList = sysMenuMapper.selectByRoleId(2L).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).toList(); + List branchShopPromissionList = sysMenuMapper.selectByRoleId(3L).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).toList(); + promissionList.removeAll(headShopPromissionList); + promissionList.addAll(branchShopPromissionList); + } + StpKit.USER.addRoleList(roleNames); StpKit.USER.addPermissionList(promissionList); String platformType = ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"); if (PlatformTypeEnum.PC_CLIENT.getValue().equals(platformType)) { @@ -168,6 +183,60 @@ public class AuthorizationServiceImpl implements AuthorizationService { return new LoginVO(StpKit.USER.getTokenInfo(), new ArrayList<>(), loginDTO.loginType(), shopInfo); } + @Override + public void switchTo(Long sysUserId) { + Long headId = StpKit.USER.getHeadId(); + long shopId = StpKit.USER.getLoginIdAsLong(); + ShopInfo currentInfo = shopInfoService.getById(shopId); + if (currentInfo.getIsHeadShop() != YesNoEnum.YES.value() && headId == null) { + throw new ApiNotPrintException("登录账号无权限切换"); + } + + SysUser sysUser = sysUserService.getById(sysUserId); + if (sysUser == null) { + throw new ApiNotPrintException("用户不存在"); + } + + ShopInfo shopInfo = shopInfoService.getById(sysUser.getId()); + if (shopInfo == null) { + throw new ApiNotPrintException("店铺信息不存在"); + } + + + // 主店铺切换子店铺 + if ((headId == null && !shopInfo.getMainId().equals(shopId)) || (!sysUser.getId().equals(headId) && shopInfo.getMainId() == null) || + (headId != null && !sysUserId.equals(headId) && !shopInfo.getMainId().equals(headId))) { + Long headShopId = StpKit.USER.getHeadShopId(); + Long changeHeadShopId = StpKit.USER.getHeadShopId(sysUserId); + if (!changeHeadShopId.equals(headShopId)) { + throw new ApiNotPrintException("目标店铺非登录账号所有"); + } + } + + // 查询角色 + List roleList = sysRoleService.getByUserId(sysUser.getId()); + List roleNames = roleList.stream().map(SysRole::getName).collect(Collectors.toList()); + if (sysUser.getIsAdmin()) { + roleNames.add("admin"); + } + // 权限赋予 + List promissionList = sysMenuMapper.selectByUserId(sysUser.getId(), null).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).toList(); + List newPromissionList = new ArrayList<>(promissionList); + boolean isEnableSync = StpKit.USER.isEnableSync(shopInfo.getId()); + if (isEnableSync && CollUtil.contains(roleNames, "商户")) { + roleNames.remove("商户"); + roleNames.add("分店商户"); + List headShopPromissionList = sysMenuMapper.selectByRoleId(2L).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).toList(); + List branchShopPromissionList = sysMenuMapper.selectByRoleId(3L).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).toList(); + newPromissionList.removeAll(headShopPromissionList); + newPromissionList.addAll(branchShopPromissionList); + } + StpKit.USER.addRoleList(roleNames); + StpKit.USER.switchTo(sysUser.getId().equals(headId), sysUser.getId(), sysUser.getAccount(), shopInfo.getId(), shopInfo.getShopName(), MyStpLogic.LoginType.MANAGER, sysUser.getIsAdmin()); + StpKit.USER.addPermissionList(newPromissionList); + StpKit.USER.addRoleList(roleNames); + } + @NotNull private static HandoverRecord getHandoverRecord(boolean isStaff, ShopInfo shopInfo, ShopStaff shopStaff) { HandoverRecord entity = new HandoverRecord(); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/MemberPointsServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/MemberPointsServiceImpl.java index 9f0b388a0..aea63114b 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/MemberPointsServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/MemberPointsServiceImpl.java @@ -52,7 +52,7 @@ public class MemberPointsServiceImpl extends ServiceImpl(padProductCategoryDetailMapper.selectPageByKeyAndShopId(shopId, productCategoryId))); } + /** + * 计算是否在可售时间内 + * + * @param days 星期几,例如 "Monday,Tuesday" + * @param startTime 起售时间 + * @param endTime 停售时间 + * @return 是否可售时间 1-是,0-否 + */ + public Integer calcIsSaleTime(String days, LocalTime startTime, LocalTime endTime) { + if (StrUtil.isBlank(days) || ObjUtil.isNull(startTime) || ObjUtil.isNull(endTime)) { + return YesNoEnum.NO.value(); + } + String today = getWeekDayEnName(); + List dayList = StrUtil.split(days, ","); + LocalTime now = LocalTime.now().withNano(0); + if (CollUtil.contains(dayList, today) && now.isAfter(startTime) && now.isBefore(endTime)) { + return YesNoEnum.YES.value(); + } + return YesNoEnum.NO.value(); + } + + /** + * 获取当前日期是星期几的英文名称 + * + * @return 星期几的英文名称,例如 "Monday" 或 "Friday" + */ + private String getWeekDayEnName() { + // 获取当前日期 + LocalDate currentDate = LocalDate.now(); + // 获取当前日期是星期几,返回一个 DayOfWeek 枚举类型的实例 + DayOfWeek dayOfWeek = currentDate.getDayOfWeek(); + return dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ENGLISH); + } + @Override public PadDetailDTO detail(Long shopId, Long padProductCategory) { PadProductCategory padCategory = padProductCategoryService.getOne(new QueryWrapper().eq(PadProductCategory::getShopId, shopId).eq(PadProductCategory::getId, padProductCategory)); @@ -57,10 +110,17 @@ public class PadProdServiceImpl implements PadProdService { List productIds = padProductCategoryDetailMapper.selectListByQuery(new QueryWrapper().eq(PadProductCategoryDetail::getPadProductCategoryId, padProductCategory)).stream().map(PadProductCategoryDetail::getProductId).toList(); padDetailDTO.setProductIdList(productIds); if (!productIds.isEmpty()) { - List products = productService.list(new QueryWrapper().in(Product::getId, productIds).eq(Product::getShopId, shopId)); + List products = productRpcService.listAndLowPrice(shopId, productIds); + products.parallelStream().forEach(item -> { + List skuList = prodSkuService.list(new QueryWrapper().eq(ProdSku::getProductId, item.getId())); + item.setSkuList(skuList); + item.setIsSaleTime(calcIsSaleTime(item.getDays(), item.getStartTime(), item.getEndTime())); + + }); padDetailDTO.setProductList(products); } + return padDetailDTO; } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopBranchServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopBranchServiceImpl.java new file mode 100644 index 000000000..c49f16648 --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopBranchServiceImpl.java @@ -0,0 +1,197 @@ +package com.czg.service.account.service.impl; + +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.core.util.ObjUtil; +import com.czg.account.dto.ShopBranchDTO; +import com.czg.account.entity.ShopConfig; +import com.czg.account.entity.ShopInfo; +import com.czg.account.enums.BranchDataSyncMethodEnum; +import com.czg.account.enums.ShopTypeEnum; +import com.czg.account.param.ShopBranchParam; +import com.czg.account.service.ShopBranchService; +import com.czg.account.service.ShopUserSyncService; +import com.czg.enums.YesNoEnum; +import com.czg.exception.CzgException; +import com.czg.product.service.ShopSyncService; +import com.czg.sa.StpKit; +import com.czg.service.account.mapper.ShopConfigMapper; +import com.czg.service.account.mapper.ShopInfoMapper; +import com.czg.utils.PageUtil; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 分店管理Service实现类 + * + * @author tankaikai + * @since 2025-04-07 14:20 + */ +@Slf4j +@Service +public class ShopBranchServiceImpl implements ShopBranchService { + + @Resource + private ShopConfigMapper shopConfigMapper; + @Resource + private ShopInfoMapper shopInfoMapper; + @DubboReference + private ShopSyncService shopSyncService; + @Resource + private ShopUserSyncService shopUserSyncService; + + + @Override + public Page findPage(ShopBranchParam param) { + PageHelper.startPage(PageUtil.buildPageHelp()); + List branchList = shopConfigMapper.findBranchList(param); + return PageUtil.convert(new PageInfo<>(branchList)); + } + + @Override + public void settingDataSyncMethod(Long shopId, String dataSyncMethod) { + ShopInfo shopInfo = shopInfoMapper.selectOneById(shopId); + if (shopInfo == null) { + throw new CzgException("店铺不存在"); + } + ShopConfig shopConfig = shopConfigMapper.selectOneById(shopInfo.getId()); + if (shopConfig == null) { + throw new CzgException("店铺配置信息不存在"); + } + if (ShopTypeEnum.ONLY.getValue().equals(shopInfo.getShopType())) { + throw new CzgException("单店不支持设置数据同步方式"); + } + if (ObjUtil.defaultIfNull(shopInfo.getIsHeadShop(), 0) == YesNoEnum.NO.value()) { + throw new CzgException("非主店不能设置数据同步方式"); + } + boolean contains = BranchDataSyncMethodEnum.checkValue(dataSyncMethod); + if (!contains) { + throw new CzgException("非法的数据同步方式值"); + } + shopConfig.setBranchDataSyncMethod(dataSyncMethod); + shopConfigMapper.update(shopConfig); + } + + @Override + public void dataSyncEnable(Long branchShopId) { + Long shopId = StpKit.USER.getShopId(0L); + ShopInfo shopInfo = shopInfoMapper.selectOneById(shopId); + if (shopInfo == null) { + throw new CzgException("主店铺不存在"); + } + ShopConfig shopConfig = shopConfigMapper.selectOneById(shopInfo.getId()); + if (shopConfig == null) { + throw new CzgException("主店铺配置信息不存在"); + } + if (ShopTypeEnum.ONLY.getValue().equals(shopInfo.getShopType())) { + throw new CzgException("数据错误:主店铺类型为单店"); + } + if (ObjUtil.defaultIfNull(shopInfo.getIsHeadShop(), 0) == YesNoEnum.NO.value()) { + throw new CzgException("数据错误:当前店铺不是主店"); + } + ShopInfo branchShop = shopInfoMapper.selectOneByQuery(QueryWrapper.create().eq(ShopInfo::getMainId, shopInfo.getId()).eq(ShopInfo::getId, branchShopId)); + if (branchShop == null) { + throw new CzgException("对应的分店信息不存在"); + } + if (ShopTypeEnum.ONLY.getValue().equals(branchShop.getShopType())) { + throw new CzgException("数据错误:分店店铺类型错误"); + } + ShopConfig branchConfig = shopConfigMapper.selectOneById(branchShop.getId()); + branchConfig.setIsEnableProdSync(YesNoEnum.YES.value()); + branchConfig.setIsEnableConsSync(YesNoEnum.YES.value()); + branchConfig.setIsEnableVipSync(YesNoEnum.YES.value()); + shopConfigMapper.update(branchConfig); + long sysUserId = StpKit.USER.getLoginIdAsLong(); + ThreadUtil.execAsync(() -> { + ThreadUtil.safeSleep(3000L); + log.info("开始同步,店铺id:{},分店id:{} 操作人Id:{}", shopId, branchShop.getId(), sysUserId); + // 同步商品和耗材 + shopSyncService.sync(shopId, branchShop.getId(), sysUserId); + log.info("同步结束,店铺id:{},分店id:{} 操作人Id:{}", shopId, branchShop.getId(), sysUserId); + }); + ThreadUtil.execAsync(() -> { + // 同步会员信息 + shopUserSyncService.syncMergeShopUser(shopId, branchShop.getId()); + }); + } + + @Override + public void accountEnable(Long branchShopId) { + Long shopId = StpKit.USER.getShopId(0L); + ShopInfo shopInfo = shopInfoMapper.selectOneById(shopId); + if (shopInfo == null) { + throw new CzgException("主店铺不存在"); + } + ShopConfig shopConfig = shopConfigMapper.selectOneById(shopInfo.getId()); + if (shopConfig == null) { + throw new CzgException("主店铺配置信息不存在"); + } + if (ShopTypeEnum.ONLY.getValue().equals(shopInfo.getShopType())) { + throw new CzgException("数据错误:主店铺类型为单店"); + } + if (ObjUtil.defaultIfNull(shopInfo.getIsHeadShop(), 0) == YesNoEnum.NO.value()) { + throw new CzgException("数据错误:当前店铺不是主店"); + } + ShopInfo branchShop = shopInfoMapper.selectOneByQuery(QueryWrapper.create().eq(ShopInfo::getMainId, shopInfo.getId()).eq(ShopInfo::getId, branchShopId)); + if (branchShop == null) { + throw new CzgException("对应的分店信息不存在"); + } + if (ShopTypeEnum.ONLY.getValue().equals(branchShop.getShopType())) { + throw new CzgException("数据错误:分店店铺类型错误"); + } + ShopConfig branchConfig = shopConfigMapper.selectOneById(branchShop.getId()); + branchConfig.setIsAllowAccountLogin(YesNoEnum.YES.value()); + shopConfigMapper.update(branchConfig); + } + + @Override + public void accountDisable(Long branchShopId) { + Long shopId = StpKit.USER.getShopId(0L); + ShopInfo shopInfo = shopInfoMapper.selectOneById(shopId); + if (shopInfo == null) { + throw new CzgException("主店铺不存在"); + } + ShopConfig shopConfig = shopConfigMapper.selectOneById(shopInfo.getId()); + if (shopConfig == null) { + throw new CzgException("主店铺配置信息不存在"); + } + if (ShopTypeEnum.ONLY.getValue().equals(shopInfo.getShopType())) { + throw new CzgException("数据错误:主店铺类型为单店"); + } + if (ObjUtil.defaultIfNull(shopInfo.getIsHeadShop(), 0) == YesNoEnum.NO.value()) { + throw new CzgException("数据错误:当前店铺不是主店"); + } + ShopInfo branchShop = shopInfoMapper.selectOneByQuery(QueryWrapper.create().eq(ShopInfo::getMainId, shopInfo.getId()).eq(ShopInfo::getId, branchShopId)); + if (branchShop == null) { + throw new CzgException("对应的分店信息不存在"); + } + if (ShopTypeEnum.ONLY.getValue().equals(branchShop.getShopType())) { + throw new CzgException("数据错误:分店店铺类型错误"); + } + ShopConfig branchConfig = shopConfigMapper.selectOneById(branchShop.getId()); + branchConfig.setIsAllowAccountLogin(YesNoEnum.NO.value()); + shopConfigMapper.update(branchConfig); + } + + @Override + public boolean isAllowAccountLogin(Long branchShopId) { + ShopConfig shopConfig = shopConfigMapper.selectOneById(branchShopId); + if (shopConfig == null) { + return true; + } + if (shopConfig.getMainId() == null) { + return true; + } + if (shopConfig.getIsAllowAccountLogin() == YesNoEnum.YES.value()) { + return true; + } + return false; + } +} diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopConfigServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopConfigServiceImpl.java new file mode 100644 index 000000000..eb7486eeb --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopConfigServiceImpl.java @@ -0,0 +1,40 @@ +package com.czg.service.account.service.impl; + +import com.czg.account.dto.ShopConfigDTO; +import com.czg.account.entity.ShopConfig; +import com.czg.account.service.ShopConfigService; +import com.czg.sa.StpKit; +import com.czg.service.account.mapper.ShopConfigMapper; +import com.czg.service.account.mapper.ShopInfoMapper; +import com.czg.utils.PageUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.stereotype.Service; + +/** + * 店铺配置扩展 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-04-03 + */ +@DubboService +public class ShopConfigServiceImpl extends ServiceImpl implements ShopConfigService { + + @Resource + private ShopInfoMapper shopInfoMapper; + + private QueryWrapper buildQueryWrapper(ShopConfigDTO param) { + QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper(); + /*if (StrUtil.isNotEmpty(param.getName())) { + queryWrapper.like(ShopConfig::getName, param.getName()); + }*/ + Long shopId = StpKit.USER.getLoginIdAsLong(); + queryWrapper.eq(ShopConfig::getMainId, shopId); + queryWrapper.orderBy(ShopConfig::getId, false); + return queryWrapper; + } + + +} \ No newline at end of file diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java index 8061c5aeb..768cabd35 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java @@ -7,12 +7,16 @@ import cn.hutool.crypto.SecureUtil; import com.czg.account.dto.PageDTO; import com.czg.account.dto.shopinfo.*; import com.czg.account.entity.*; +import com.czg.account.enums.BranchDataSyncMethodEnum; +import com.czg.account.enums.ShopTypeEnum; import com.czg.account.service.*; import com.czg.config.RedisCst; import com.czg.enums.StatusEnum; +import com.czg.enums.YesNoEnum; import com.czg.exception.ApiNotPrintException; import com.czg.exception.CzgException; import com.czg.resp.CzgResult; +import com.czg.sa.MyStpLogic; import com.czg.sa.StpKit; import com.czg.service.RedisService; import com.czg.service.account.mapper.ShopInfoMapper; @@ -27,6 +31,7 @@ import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.spring.service.impl.ServiceImpl; import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.cache.annotation.CacheConfig; @@ -36,6 +41,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -44,6 +50,7 @@ import java.util.stream.Collectors; /** * @author Administrator */ +@Slf4j @DubboService @CacheConfig(cacheNames = "shopInfo") public class ShopInfoServiceImpl extends ServiceImpl implements ShopInfoService { @@ -65,6 +72,8 @@ public class ShopInfoServiceImpl extends ServiceImpl i private FreeDineConfigService freeDineConfigService; @Resource private PointsBasicSettingService pointsBasicSettingService; + @Resource + private ShopConfigService shopConfigService; @DubboReference private SysParamsService sysParamsService; @@ -72,7 +81,10 @@ public class ShopInfoServiceImpl extends ServiceImpl i @Override @Cacheable(key = "#id") public ShopInfo getById(Serializable id) { - return super.getById(id); + ShopInfo shopInfo = super.getById(id); + ShopConfig shopConfig = shopConfigService.getById(shopInfo.getId()); + BeanUtil.copyProperties(shopConfig, shopInfo); + return shopInfo; } private ShopInfo getShopInfo(Long shopId) { @@ -94,7 +106,7 @@ public class ShopInfoServiceImpl extends ServiceImpl i } @Override - public Page get(PageDTO pageDTO, String shopName, Integer status) { + public Page get(PageDTO pageDTO, String shopName, Integer status, Integer isHeadShop) { QueryWrapper queryWrapper = new QueryWrapper(); if (StrUtil.isNotBlank(shopName)) { queryWrapper.like(ShopInfo::getShopName, shopName); @@ -102,8 +114,19 @@ public class ShopInfoServiceImpl extends ServiceImpl i if (status != null) { queryWrapper.eq(ShopInfo::getStatus, status); } + if (isHeadShop != null) { + queryWrapper.eq(ShopInfo::getIsHeadShop, isHeadShop); + } + List shopAllList = getMapper().selectListByQuery(query().select(ShopInfo::getId, ShopInfo::getShopName)); + Map shopKv = shopAllList.stream().collect(Collectors.toMap(ShopInfo::getId, ShopInfo::getShopName)); queryWrapper.orderBy(ShopInfo::getCreateTime, false); - return page(new Page<>(pageDTO.page(), pageDTO.size()), queryWrapper); + Page page = page(new Page<>(pageDTO.page(), pageDTO.size()), queryWrapper); + page.getRecords().forEach(shopInfo -> { + ShopConfig shopConfig = shopConfigService.getById(shopInfo.getId()); + BeanUtil.copyProperties(shopConfig, shopInfo); + shopInfo.setHeadShopName(shopKv.get(shopInfo.getMainId())); + }); + return page; } private void activateShop(ShopInfo shopInfo, String activateCode) { @@ -116,7 +139,7 @@ public class ShopInfoServiceImpl extends ServiceImpl i // 续期 if (shopInfo.getExpireTime() != null && shopInfo.getExpireTime().isAfter(LocalDateTime.now())) { shopInfo.setExpireTime(DateUtil.offsetMonth(DateUtil.date(shopInfo.getExpireTime()), merchantRegister.getPeriodMonth()).toLocalDateTime()); - }else { + } else { shopInfo.setExpireTime(DateUtil.offsetMonth(DateUtil.date(), merchantRegister.getPeriodMonth()).toLocalDateTime()); } merchantRegister.setStatus(1); @@ -127,6 +150,23 @@ public class ShopInfoServiceImpl extends ServiceImpl i @Override @Transactional(rollbackFor = Exception.class) public Boolean add(ShopInfoAddDTO shopInfoAddDTO) { + // 如果店铺类型是单店,是否主店要设为否 + if (ShopTypeEnum.ONLY.getValue().equals(shopInfoAddDTO.getShopType())) { + shopInfoAddDTO.setIsHeadShop(YesNoEnum.NO.value()); + if (shopInfoAddDTO.getMainId() != null) { + throw new CzgException("单店不允许设置主店ID"); + } + } else { + if (shopInfoAddDTO.getIsHeadShop() == null) { + throw new CzgException("加盟店/连锁店请选择是否主店"); + } + if (shopInfoAddDTO.getIsHeadShop() == YesNoEnum.NO.value() && shopInfoAddDTO.getMainId() == null) { + throw new CzgException("请选择一个店铺做为主店"); + } + if (shopInfoAddDTO.getIsHeadShop() == YesNoEnum.YES.value()) { + shopInfoAddDTO.setMainId(null); + } + } shopInfoAddDTO.setPhone(shopInfoAddDTO.getPhone().trim()); if (StrUtil.isBlank(shopInfoAddDTO.getPhone())) { throw new ApiNotPrintException("请输入手机号"); @@ -156,7 +196,50 @@ public class ShopInfoServiceImpl extends ServiceImpl i // 初始化积分霸王餐设置 freeDineConfigService.getConfig(shopInfo.getId()); pointsBasicSettingService.initInfo(shopInfo.getId()); - return updateById(shopInfo); + updateById(shopInfo); + syncSaveConfig(shopInfo, shopInfoAddDTO); + return true; + } + + /** + * 同步创建配置信息 + * + * @param shopInfo 店铺信息实体 + * @param dto 新增店铺信息DTO + */ + private void syncSaveConfig(ShopInfo shopInfo, ShopInfoAddDTO dto) { + ShopConfig shopConfig = new ShopConfig(); + shopConfig.setId(shopInfo.getId()); + shopConfig.setMainId(shopInfo.getMainId()); + shopConfig.setIsEnableProdSync(0); + shopConfig.setIsEnableVipSync(0); + shopConfig.setIsEnableConsSync(0); + shopConfig.setIsAllowAccountLogin(1); + shopConfig.setRemark(null); + shopConfig.setIsCustomAmount(0); + shopConfig.setIsReturnPwd(0); + shopConfig.setIsMemberInPwd(0); + shopConfig.setIsMemberReturnPwd(0); + shopConfig.setIsTableFee(1); + shopConfig.setIsMemberPrice(0); + shopConfig.setIsAccountPay(0); + shopConfig.setBranchDataSyncMethod(null); + if (dto.getIsHeadShop() == YesNoEnum.YES.value()) { + shopConfig.setBranchDataSyncMethod(BranchDataSyncMethodEnum.AUTO.getValue()); + } + shopConfigService.save(shopConfig); + } + + /** + * 同步修改配置信息 + * + * @param shopInfo 店铺信息实体 + * @param dto 新增店铺信息DTO + */ + private void syncUpdateConfig(ShopInfo shopInfo, ShopInfoEditDTO dto) { + ShopConfig shopConfig = shopConfigService.getById(shopInfo.getId()); + BeanUtil.copyProperties(dto, shopConfig); + shopConfigService.updateById(shopConfig); } @Override @@ -164,19 +247,40 @@ public class ShopInfoServiceImpl extends ServiceImpl i public Boolean edit(ShopInfoEditDTO shopInfoEditDTO) { ShopInfo shopInfo; if (!StpKit.USER.isAdmin()) { - shopInfo = queryChain().eq(ShopInfo::getId, StpKit.USER.getLoginIdAsLong()).one(); - }else { - shopInfo = getById(StpKit.USER.getLoginIdAsLong()); + shopInfo = queryChain().eq(ShopInfo::getId, StpKit.USER.getShopId()).one(); + } else { + shopInfo = getById(shopInfoEditDTO.getId()); } if (shopInfo == null) { throw new CzgException("店铺不存在"); } - BeanUtil.copyProperties(shopInfoEditDTO, shopInfo); - + String shopType = shopInfo.getShopType(); + Long mainId = shopInfo.getMainId(); + Integer isHeadShop = shopInfo.getIsHeadShop(); + if (StrUtil.isEmpty(shopInfoEditDTO.getShopType()) || shopType.equals(shopInfoEditDTO.getShopType())) { + // 原来是单店,现在不是单店,那么就允许修改,否则不允许修改 + } else if (ShopTypeEnum.ONLY.getValue().equals(shopType) && !ShopTypeEnum.ONLY.getValue().equals(shopInfoEditDTO.getShopType())) { + if (shopInfoEditDTO.getIsHeadShop() == null) { + throw new CzgException("加盟店/连锁店请选择是否主店"); + } + if (shopInfoEditDTO.getIsHeadShop() == YesNoEnum.NO.value() && shopInfoEditDTO.getMainId() == null) { + throw new CzgException("请选择一个店铺做为主店"); + } + if (shopInfoEditDTO.getIsHeadShop() == YesNoEnum.YES.value()) { + if (mainId != null) { + throw new CzgException("数据错误:当前店铺是非主店,不允许随意切换为主店"); + } + } + if (isHeadShop == YesNoEnum.YES.value() && shopInfoEditDTO.getIsHeadShop() == YesNoEnum.NO.value()) { + throw new CzgException("数据错误:当前店铺是主店,不允许随意切换为非主店"); + } + } else { + throw new CzgException("禁止连锁店/加盟店修改为单店"); + } if (shopInfoEditDTO.getActivateCode() != null) { activateShop(shopInfo, shopInfoEditDTO.getActivateCode()); } - + BeanUtil.copyProperties(shopInfoEditDTO, shopInfo); if (shopInfoEditDTO.getOperationPwd() != null) { String key = "%s%s:%s".formatted(RedisCst.SMS_CODE, shopInfo.getPhone(), "editShopInfoOpePwd"); Object val = redisService.get(key); @@ -188,6 +292,7 @@ public class ShopInfoServiceImpl extends ServiceImpl i redisService.del(key); } if (updateById(shopInfo)) { + syncUpdateConfig(shopInfo, shopInfoEditDTO); SysUser sysUser = sysUserService.getById(shopInfo.getId()); boolean flag = false; if (!sysUser.getNickName().equals(shopInfo.getShopName())) { @@ -218,12 +323,16 @@ public class ShopInfoServiceImpl extends ServiceImpl i if (!StpKit.USER.isAdmin() && !Objects.equals(StpKit.USER.getShopId(), shopInfo.getId())) { throw new ApiNotPrintException("店铺信息不存在"); } - + ShopConfig shopConfig = shopConfigService.getById(shopInfo.getId()); + if (shopConfig == null) { + throw new CzgException("店铺配置不存在"); + } ShopDetailDTO shopDetailDTO = BeanUtil.copyProperties(shopInfo, ShopDetailDTO.class); SysUser sysUser = sysUserService.getById(shopInfo.getId()); shopDetailDTO.setAccount(sysUser.getAccount()); CzgResult shopOrderPayBaseUrl = sysParamsService.getParamsByCode("shop_order_pay_base_url"); shopDetailDTO.setPaymentQrcode(shopOrderPayBaseUrl.getData().getParamValue() + "?shopId=" + id); + BeanUtil.copyProperties(shopConfig, shopDetailDTO); return shopDetailDTO; } @@ -238,7 +347,6 @@ public class ShopInfoServiceImpl extends ServiceImpl i throw new ApiNotPrintException("台桌状态不可用"); } ShopInfo shopInfo = getShopInfo(shopTable.getShopId()); - double distance = 0; if (StrUtil.isAllNotBlank(lat, lng, shopInfo.getLat(), shopInfo.getLng())) { // 计算距离,单位:米 @@ -264,4 +372,26 @@ public class ShopInfoServiceImpl extends ServiceImpl i PageHelper.startPage(PageUtil.buildPageHelp()); return PageUtil.convert(new PageInfo<>(mapper.getSubList(lng, lat, distance))); } + + @Override + public List findShopBranch(Long shopId) { + List list = new ArrayList<>(); + ShopInfo shopInfo = mapper.selectOneById(shopId); + ShopBranchSelectDTO head = new ShopBranchSelectDTO(); + head.setShopId(shopInfo.getId()); + head.setShopName(shopInfo.getShopName()); + list.add(head); + MyStpLogic.LoginType loginType = (MyStpLogic.LoginType) StpKit.USER.getSession().get("loginType"); + if(loginType.compareTo(MyStpLogic.LoginType.STAFF) == 0){ + return list; + } + List branchList = mapper.selectListByQuery(query().select(ShopInfo::getId, ShopInfo::getShopName).eq(ShopInfo::getMainId, shopId).orderBy(ShopInfo::getId, true)); + for (ShopInfo info : branchList) { + ShopBranchSelectDTO branch = new ShopBranchSelectDTO(); + branch.setShopId(info.getId()); + branch.setShopName(info.getShopName()); + list.add(branch); + } + return list; + } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java index bf94f7ffb..4abbd1b1f 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserServiceImpl.java @@ -9,6 +9,7 @@ import com.czg.account.entity.*; import com.czg.account.service.*; import com.czg.config.RedisCst; import com.czg.enums.ShopUserFlowBizEnum; +import com.czg.enums.YesNoEnum; import com.czg.exception.ApiNotPrintException; import com.czg.order.entity.OrderInfo; import com.czg.order.service.OrderDetailService; @@ -16,6 +17,7 @@ import com.czg.order.service.OrderInfoService; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; import com.czg.service.RedisService; +import com.czg.service.account.mapper.ShopConfigMapper; import com.czg.service.account.mapper.ShopInfoMapper; import com.czg.service.account.mapper.ShopUserMapper; import com.czg.system.entity.SysParams; @@ -67,6 +69,8 @@ public class ShopUserServiceImpl extends ServiceImpl i private ShopExtendService shopExtendService; @Resource private FreeDineConfigService freeDineConfigService; + @Resource + private ShopConfigMapper shopConfigMapper; private ShopUser getUserInfo(Long shopId, Long shopUserId) { ShopUser shopUser = queryChain().eq(ShopUser::getShopId, shopId).eq(ShopUser::getId, shopUserId).one(); @@ -79,8 +83,9 @@ public class ShopUserServiceImpl extends ServiceImpl i @Override public Page getPage(String key, Integer isVip, BigDecimal amount) { + Long shopId = StpKit.USER.getUsableShopId(); PageHelper.startPage(PageUtil.buildPageHelp()); - return PageUtil.convert(new PageInfo<>(mapper.selectPageByKeyAndIsVip(StpKit.USER.getShopId(), isVip, key, amount))); + return PageUtil.convert(new PageInfo<>(mapper.selectPageByKeyAndIsVip(shopId, isVip, key, amount))); } @Override @@ -148,6 +153,10 @@ public class ShopUserServiceImpl extends ServiceImpl i @Override public ShopUser getShopUserInfo(Long shopId, long userId) { + ShopConfig shopConfig = shopConfigMapper.selectOneById(shopId); + if (shopConfig != null && shopConfig.getIsEnableVipSync() == YesNoEnum.YES.value() && shopConfig.getMainId() != null) { + shopId = shopConfig.getMainId(); + } ShopUser shopUser = queryChain().eq(ShopUser::getShopId, shopId).eq(ShopUser::getUserId, userId).one(); if (shopUser == null) { shopUser = new ShopUser(); @@ -185,6 +194,10 @@ public class ShopUserServiceImpl extends ServiceImpl i @Override public CzgResult getCode(long userInfoId, long shopId) { + ShopConfig shopConfig = shopConfigMapper.selectOneById(shopId); + if (shopConfig != null && shopConfig.getIsEnableVipSync() == YesNoEnum.YES.value() && shopConfig.getMainId() != null) { + shopId = shopConfig.getMainId(); + } ShopUser shopUser = queryChain().eq(ShopUser::getShopId, shopId).eq(ShopUser::getUserId, userInfoId).one(); AssertUtil.isNull(shopUser, "会员信息不存在"); if (shopUser.getIsVip().equals(0)) { @@ -300,6 +313,10 @@ public class ShopUserServiceImpl extends ServiceImpl i @Override public ShopUserDetailDTO getInfo(Long shopId, long userId) { + ShopConfig shopConfig = shopConfigMapper.selectOneById(shopId); + if (shopConfig != null && shopConfig.getIsEnableVipSync() == YesNoEnum.YES.value() && shopConfig.getMainId() != null) { + shopId = shopConfig.getMainId(); + } ShopUser shopUser = getOne(new QueryWrapper().eq(ShopUser::getShopId, shopId).eq(ShopUser::getUserId, userId)); UserInfo userInfo = userInfoService.getById(userId); if (userInfo == null) { @@ -336,11 +353,11 @@ public class ShopUserServiceImpl extends ServiceImpl i @Override public ShopUser getDetail(Integer id, Integer userId) { - ShopUser shopUser = getOne(new QueryWrapper().eq(ShopUser::getShopId, StpKit.USER.getShopId()).eq(ShopUser::getId, id).eq(ShopUser::getUserId, userId)); + ShopUser shopUser = getOne(new QueryWrapper().eq(ShopUser::getShopId, StpKit.USER.getUsableShopId()).eq(ShopUser::getId, id).eq(ShopUser::getUserId, userId)); long count = shopActivateCouponRecordService.count(new QueryWrapper().eq(ShopActivateCouponRecord::getShopUserId, shopUser.getId()).eq(ShopActivateCouponRecord::getStatus, 0)); ShopUserDTO shopUserDTO = BeanUtil.copyProperties(shopUser, ShopUserDTO.class); shopUserDTO.setCouponNum(count); - shopUserDTO.setOrderNumber(orderInfoService.count(new QueryWrapper().eq(OrderInfo::getUserId, userId).eq(OrderInfo::getShopId, shopUser.getShopId()).eq(OrderInfo::getStatus, "done"))); + shopUserDTO.setOrderNumber(orderInfoService.count(new QueryWrapper().eq(OrderInfo::getUserId, userId).eq(OrderInfo::getShopId, StpKit.USER.getShopId(0L)).eq(OrderInfo::getStatus, "done"))); return shopUserDTO; } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserSyncServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserSyncServiceImpl.java new file mode 100644 index 000000000..f77192040 --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopUserSyncServiceImpl.java @@ -0,0 +1,170 @@ +package com.czg.service.account.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONWriter; +import com.czg.account.entity.ShopUser; +import com.czg.account.entity.ShopUserFlow; +import com.czg.account.service.ShopUserSyncService; +import com.czg.service.account.mapper.ShopUserMapper; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.update.UpdateChain; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 店铺用户同步Service实现类 + * + * @author tankaikai + * @since 2025-04-08 10:18 + */ +@Service +public class ShopUserSyncServiceImpl implements ShopUserSyncService { + + @Resource + private ShopUserMapper shopUserMapper; + + /** + * 同步合并主分店会员信息 + * + * @param headShopId 主店id + * @param branchShopId 分店id + */ + @Override + public synchronized void syncMergeShopUser(Long headShopId, Long branchShopId) { + // 合并前置逻辑:查询主店、分店手机号码不为空的会员信息,分店和主店手机号码进行匹配 + // 合并逻辑0:分店没有绑定手机号的会员,把shop_id改为主店shop_id,把分店会员信息jsonArray格式化存储至主店用户信息的merged_users字段中 + // 合并逻辑1:(主店、分店一致)如果手机号码一致,则把分店会员信息中的 积分、余额、消费金额、消费次数合并到主店会员信息中,把分店会员信息jsonArray格式化存储至主店用户信息的merged_users字段中,再把分店用户信息删除 + // 合并逻辑2:(主店有、分店没有)不用采取任何操作,使用主店的会员信息 + // 合并逻辑3:(主店没有、分店有)把shop_id改为主店shop_id,把分店会员信息jsonArray格式化存储至merged_users字段中 + // 合并逻辑4:当用户补充了手机号码或则修改了手机号码,则需要按照手机号码进行会员信息合并,把逻辑1,2,3重新执行一遍 + List branchShopNotPhoneUserList = shopUserMapper.selectListByQuery(QueryWrapper.create().eq(ShopUser::getShopId, branchShopId) + .and(q -> { + q.isNull(ShopUser::getPhone).or(q1 -> { + q1.eq(ShopUser::getPhone, ""); + }); + })); + // 分店没有绑定手机号的会员 + for (ShopUser shopUser : branchShopNotPhoneUserList) { + Long historyShopId = shopUser.getShopId(); + Long historyUserId = shopUser.getUserId(); + JSONObject branch = JSONObject.from(shopUser, JSONWriter.Feature.WriteMapNullValue); + JSONArray objects = new JSONArray(); + objects.add(branch); + shopUser.setShopId(headShopId); + shopUser.setMergedUsers(objects.toJSONString(JSONWriter.Feature.WriteMapNullValue)); + shopUserMapper.update(shopUser); + // 更新会员流水记录到主店 + UpdateChain.of(ShopUserFlow.class) + .set(ShopUserFlow::getShopId, headShopId) + .eq(ShopUserFlow::getShopId, historyShopId) + .eq(ShopUserFlow::getUserId, historyUserId) + .update(); + } + List headShopUserList = shopUserMapper.selectListByQuery(QueryWrapper.create().eq(ShopUser::getShopId, headShopId).isNotNull(ShopUser::getPhone)); + List branchShopUserList = shopUserMapper.selectListByQuery(QueryWrapper.create().eq(ShopUser::getShopId, branchShopId).isNotNull(ShopUser::getPhone)); + // 如果分店没有符合条件的会员,则不进行合并 + if (CollUtil.isEmpty(branchShopUserList)) { + return; + } + Map headShopUserKv = headShopUserList.stream().collect(Collectors.toMap(ShopUser::getPhone, shopUser -> shopUser)); + Map branchShopUserKv = branchShopUserList.stream().collect(Collectors.toMap(ShopUser::getPhone, shopUser -> shopUser)); + + Set headShopPhoneList = headShopUserList.stream().map(ShopUser::getPhone).collect(Collectors.toSet()); + Set branchShopPhoneList = branchShopUserList.stream().map(ShopUser::getPhone).collect(Collectors.toSet()); + + Set phoneSet = new HashSet<>(); + phoneSet.addAll(headShopPhoneList); + phoneSet.addAll(branchShopPhoneList); + + // 执行合并逻辑 + for (String phone : phoneSet) { + ShopUser headShopUser = headShopUserKv.get(phone); + ShopUser branchShopUser = branchShopUserKv.get(phone); + // 1.如果都有 + if (ObjUtil.isNotNull(headShopUser) && ObjUtil.isNotNull(branchShopUser)) { + toMergeCase1(headShopUser, branchShopUser); + // 2.如果主店有,分店没有 + } else if (ObjUtil.isNotNull(headShopUser) && ObjUtil.isNull(branchShopUser)) { + toMergeCase2(headShopUser, branchShopId); + // 3.如果主店没有,分店有 + } else if (ObjUtil.isNull(headShopUser) && ObjUtil.isNotNull(branchShopUser)) { + toMergeCase3(headShopId, branchShopUser); + } + } + } + + /** + * 合并会员信息 1.如果都有 + * + * @param headShopUser 主店会员 + * @param branchShopUser 分店会员 + */ + public void toMergeCase1(ShopUser headShopUser, ShopUser branchShopUser) { + // 合并逻辑1:(主店、分店一致)如果手机号码一致,则把分店会员信息中的 积分、余额、消费金额、消费次数合并到主店会员信息中,把分店会员信息jsonArray格式化存储至主店用户信息的merged_users字段中,再把分店用户信息删除 + headShopUser.setAccountPoints(NumberUtil.nullToZero(headShopUser.getAccountPoints()) + (NumberUtil.nullToZero(branchShopUser.getAccountPoints()))); + headShopUser.setAmount(NumberUtil.nullToZero(headShopUser.getAmount()).add(NumberUtil.nullToZero(branchShopUser.getAmount()))); + headShopUser.setConsumeCount(NumberUtil.nullToZero(headShopUser.getConsumeCount()) + (NumberUtil.nullToZero(branchShopUser.getConsumeCount()))); + headShopUser.setConsumeAmount(NumberUtil.nullToZero(headShopUser.getConsumeAmount()).add(NumberUtil.nullToZero(branchShopUser.getConsumeAmount()))); + headShopUser.setUpdateTime(LocalDateTime.now()); + String mergedUsers = StrUtil.emptyToDefault(headShopUser.getMergedUsers(), "[]"); + JSONArray objects = JSON.parseArray(mergedUsers); + objects.add(JSONObject.from(branchShopUser, JSONWriter.Feature.WriteMapNullValue)); + headShopUser.setMergedUsers(JSON.toJSONString(objects, JSONWriter.Feature.WriteMapNullValue)); + shopUserMapper.update(headShopUser); + // 更新会员流水记录到主店 + UpdateChain.of(ShopUserFlow.class) + .set(ShopUserFlow::getShopId, headShopUser.getShopId()) + .eq(ShopUserFlow::getShopId, branchShopUser.getShopId()) + .eq(ShopUserFlow::getUserId, branchShopUser.getUserId()) + .update(); + shopUserMapper.delete(branchShopUser); + } + + /** + * 合并会员信息 2.如果主店有,分店没有 + * + * @param headShopUser 主店会员 + * @param branchShopId 分店id + */ + public void toMergeCase2(ShopUser headShopUser, Long branchShopId) { + // 合并逻辑2:(主店有、分店没有)不用采取任何操作,使用主店的会员信息 + } + + /** + * 合并会员信息 3.如果主店没有,分店有 + * + * @param headShopId 主店id + * @param branchShopUser 分店会员信息 + */ + public void toMergeCase3(Long headShopId, ShopUser branchShopUser) { + // 合并逻辑3:(主店没有、分店有)把shop_id改为主店shop_id,把分店会员信息jsonArray格式化存储至merged_users字段中 + Long historyShopId = branchShopUser.getShopId(); + Long historyUserId = branchShopUser.getUserId(); + JSONObject branch = JSONObject.from(branchShopUser, JSONWriter.Feature.WriteMapNullValue); + JSONArray objects = new JSONArray(); + objects.add(branch); + branchShopUser.setShopId(headShopId); + branchShopUser.setMergedUsers(objects.toJSONString(JSONWriter.Feature.WriteMapNullValue)); + shopUserMapper.update(branchShopUser); + // 更新会员流水记录到主店 + UpdateChain.of(ShopUserFlow.class) + .set(ShopUserFlow::getShopId, headShopId) + .eq(ShopUserFlow::getShopId, historyShopId) + .eq(ShopUserFlow::getUserId, historyUserId) + .update(); + } + +} diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SyncNoticeServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SyncNoticeServiceImpl.java new file mode 100644 index 000000000..8c52b1a1c --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SyncNoticeServiceImpl.java @@ -0,0 +1,98 @@ +package com.czg.service.account.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.czg.product.dto.SyncNoticeReadDTO; +import com.czg.utils.PageUtil; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.czg.account.entity.SyncNotice; +import com.czg.account.service.SyncNoticeService; +import com.czg.service.account.mapper.SyncNoticeMapper; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 服务层实现。 + * + * @author zs + * @since 2025-04-07 + */ +@DubboService +public class SyncNoticeServiceImpl extends ServiceImpl implements SyncNoticeService { + + @Override + public void addNotice(Long shopId, Long sysUserId, String name, Long id, Integer type) { + SyncNotice syncNotice = new SyncNotice(); + syncNotice.setShopId(shopId); + syncNotice.setSysUserId(sysUserId); + String content = switch (type) { + case 0 -> "新增商品"; + case 1 -> "修改商品"; + case 2 -> "新增耗材"; + case 3 -> "修改耗材"; + default -> ""; + }; + + String json = switch (type) { + case 0, 1, 2, 3 -> StrUtil.format("{\"id\":{},\"name\":\"{}\"}", id, name); + default -> ""; + }; + + content = StrUtil.format("{}: {}, 请及时确认;", content, name); + syncNotice.setContent(content); + syncNotice.setExtraJson(json); + save(syncNotice); + } + + @Override + public void addNotice(Long shopId, Long sysUserId, String title, String content, String extraJson) { + SyncNotice syncNotice = new SyncNotice(); + syncNotice.setShopId(shopId); + syncNotice.setSysUserId(sysUserId); + syncNotice.setTitle(title); + syncNotice.setContent(content); +// syncNotice.setType(type); +// syncNotice.setExtraJson(extraJson); + save(syncNotice); + } + + + @Override + public Page pageInfo(Long shopId, String name, String startTime, String endTime, String title, Integer isRead) { + QueryWrapper queryWrapper = new QueryWrapper().eq(SyncNotice::getShopId, shopId); + if (StrUtil.isNotBlank(name)) { + queryWrapper.like(SyncNotice::getContent, name); + } + + if (StrUtil.isNotBlank(startTime)) { + queryWrapper.ge(SyncNotice::getCreateTime, startTime); + } + + if (StrUtil.isNotBlank(endTime)) { + queryWrapper.le(SyncNotice::getCreateTime, endTime); + } + queryWrapper.eq(SyncNotice::getTitle, title); + queryWrapper.eq(SyncNotice::getIsRead, isRead); + queryWrapper.orderBy(SyncNotice::getCreateTime, false); + return page(PageUtil.buildPage(), queryWrapper); + } + + @Override + public Boolean read(Long shopId, SyncNoticeReadDTO syncNoticeReadDTO) { + if (syncNoticeReadDTO.getNoticeIdList() == null || syncNoticeReadDTO.getNoticeIdList().isEmpty()) { + return updateChain().eq(SyncNotice::getShopId, shopId).set(SyncNotice::getIsRead, 1).set(SyncNotice::getReadTime, DateUtil.date().toLocalDateTime()).update(); + } + List listed = list(new QueryWrapper().eq(SyncNotice::getShopId, shopId).in(SyncNotice::getId, syncNoticeReadDTO.getNoticeIdList())); + listed.forEach(item -> { + if (item.getIsRead() == 0) { + item.setIsRead(1); + item.setReadTime(DateUtil.date().toLocalDateTime()); + } + }); + return updateBatch(listed); + } +} diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java index 85496abda..456b2157a 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java @@ -6,19 +6,22 @@ import cn.hutool.core.util.StrUtil; import com.czg.account.dto.menu.MenuAddDTO; import com.czg.account.dto.menu.MenuEditDTO; import com.czg.account.entity.SysMenu; +import com.czg.account.entity.SysUsersRoles; import com.czg.account.service.SysMenuService; import com.czg.account.vo.MenuVO; import com.czg.exception.ApiNotPrintException; import com.czg.sa.StpKit; import com.czg.service.account.mapper.SysMenuMapper; +import com.czg.service.account.mapper.SysUsersRolesMapper; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.spring.service.impl.ServiceImpl; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import java.util.Arrays; /** * 系统菜单 服务层实现。 @@ -27,11 +30,28 @@ import java.util.Arrays; @Service public class SysMenuServiceImpl extends ServiceImpl implements SysMenuService { + @Resource + private SysMenuMapper sysMenuMapper; + @Resource + private SysUsersRolesMapper sysUsersRolesMapper; + @Override public List getMenu() { long sysUserId = StpKit.USER.getLoginIdAsLong(); List allMenus = mapper.selectByUserId(sysUserId, null); + List roleList = sysUsersRolesMapper.selectListByQuery(query().select(SysUsersRoles::getRoleId).eq(SysUsersRoles::getUserId, sysUserId)); + List roleIdList = roleList.stream().map(SysUsersRoles::getRoleId).toList(); + Long shopId = StpKit.USER.getShopId(0L); + boolean isEnableSync = StpKit.USER.isEnableSync(shopId); + if (isEnableSync && roleIdList.contains(2L)) { + List headShopPromissionList = sysMenuMapper.selectByRoleId(2L); + List branchShopPromissionList = sysMenuMapper.selectByRoleId(3L); + allMenus.removeAll(headShopPromissionList); + allMenus.addAll(branchShopPromissionList); + } + List menuVos = allMenus.stream() + .distinct() .map(menu -> BeanUtil.copyProperties(menu, MenuVO.class)) .collect(Collectors.toList()); return buildMenuWithPermissions(menuVos); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java index 051cb5cce..d55b4dc5f 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java @@ -48,9 +48,9 @@ public class SysRoleServiceImpl extends ServiceImpl imp @Override public Page getList(Long shopId, PageDTO pageDTO, String key, String startTime, String endTime) { QueryWrapper queryWrapper = new QueryWrapper(); - if (!StpKit.USER.isAdmin()) { +// if (!StpKit.USER.isAdmin()) { queryWrapper.eq(SysRole::getCreateUserId, StpKit.USER.getLoginIdAsLong()); - } +// } if (StrUtil.isNotBlank(key)) { queryWrapper.and(column(SysRole::getName).like(key).or(column(SysRole::getDescription).like(key))); @@ -64,6 +64,8 @@ public class SysRoleServiceImpl extends ServiceImpl imp queryWrapper.le(SysRole::getCreateTime, DateUtil.parse(endTime)); } + queryWrapper.orderBy(SysRole::getLevel, true); + return page(new Page<>(pageDTO.page(), pageDTO.size()), queryWrapper); } diff --git a/cash-service/account-service/src/main/resources/mapper/ShopConfigMapper.xml b/cash-service/account-service/src/main/resources/mapper/ShopConfigMapper.xml new file mode 100644 index 000000000..1762e8540 --- /dev/null +++ b/cash-service/account-service/src/main/resources/mapper/ShopConfigMapper.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/cash-service/account-service/src/main/resources/mapper/SyncNoticeMapper.xml b/cash-service/account-service/src/main/resources/mapper/SyncNoticeMapper.xml new file mode 100644 index 000000000..e8cb7db00 --- /dev/null +++ b/cash-service/account-service/src/main/resources/mapper/SyncNoticeMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml b/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml index ccfccfa7b..707b09fa2 100644 --- a/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml +++ b/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml @@ -15,4 +15,7 @@ order by menu_sort desc + diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/DataSummaryServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/DataSummaryServiceImpl.java index 77e0b6587..66318191a 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/DataSummaryServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/DataSummaryServiceImpl.java @@ -14,6 +14,7 @@ import com.czg.order.service.DataSummaryService; import com.czg.order.vo.DataSummaryDateAmountVo; import com.czg.order.vo.DataSummaryPayTypeVo; import com.czg.order.vo.DataSummaryProductSaleRankingVo; +import com.czg.order.vo.TotalVo; import com.czg.service.order.mapper.OrderInfoMapper; import com.czg.service.order.mapper.ShopOrderStatisticMapper; import com.czg.service.order.mapper.ShopProdStatisticMapper; @@ -50,7 +51,18 @@ public class DataSummaryServiceImpl implements DataSummaryService { private ShopProdStatisticMapper shopProdStatisticMapper; @Override - public ShopOrderStatistic getTradeData(DataSummaryTradeParam param) { + public ShopOrderStatistic getArchiveTradeData(DataSummaryTradeParam param) { + ShopOrderStatistic shopOrderStatistic = shopOrderStatisticMapper.getTradeData(param); + if(shopOrderStatistic == null){ + shopOrderStatistic = new ShopOrderStatistic(); + } + shopOrderStatistic.setCustomerUnitPrice(shopOrderStatistic.getCustomerUnitPrice().setScale(2, java.math.RoundingMode.HALF_UP)); + shopOrderStatistic.setTableTurnoverRate(shopOrderStatistic.getTableTurnoverRate().setScale(2, java.math.RoundingMode.HALF_UP)); + return shopOrderStatistic; + } + + @Override + public ShopOrderStatistic getRealTimeTradeData(DataSummaryTradeParam param) { List funs = Arrays.asList("getPayTypeAmountCount", "getVipRechargeAmountCount", "getNewMemberCount", "getCustomerUnitPrice", "getTableTurnoverRate"); Map collect = funs.parallelStream().collect(Collectors.toMap(fun -> fun, fun -> ReflectUtil.invoke(shopOrderStatisticMapper, fun, param) @@ -63,9 +75,6 @@ public class DataSummaryServiceImpl implements DataSummaryService { ShopOrderStatistic data = new ShopOrderStatistic(); //List> list = shopOrderStatisticMapper.getPayTypeAmountCount(param); List> list = (List>) collect.get("getPayTypeAmountCount"); - if (CollUtil.isEmpty(list)) { - return data; - } Map sum = list.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("payType")), item -> Convert.toBigDecimal(item.get("amount")))); Map count = list.stream().collect(Collectors.toMap(item -> Convert.toStr(item.get("payType")), item -> Convert.toLong(item.get("count")))); data.setWechatPayAmount(sum.getOrDefault(PayEnums.WECHAT_MINI.getValue(), BigDecimal.ZERO)); @@ -106,13 +115,6 @@ public class DataSummaryServiceImpl implements DataSummaryService { data.setDiscountAmount(discountAmount); data.setDiscountCount(discountCount); return data; - - /*ShopOrderStatistic shopOrderStatistic = shopOrderStatisticMapper.getTradeData(param); - long newMemberCount = shopOrderStatisticMapper.getNewMemberCount(param); - data.setNewMemberCount(newMemberCount); - shopOrderStatistic.setCustomerUnitPrice(shopOrderStatistic.getCustomerUnitPrice().setScale(2, java.math.RoundingMode.HALF_UP)); - shopOrderStatistic.setTableTurnoverRate(shopOrderStatistic.getTableTurnoverRate().setScale(2, java.math.RoundingMode.HALF_UP)); - return shopOrderStatistic;*/ } @Override @@ -129,7 +131,7 @@ public class DataSummaryServiceImpl implements DataSummaryService { param.setBeginDate(days.getFirst() + " 00:00:00"); param.setEndDate(days.getLast() + " 23:59:59"); PageHelper.startPage(PageUtil.buildPageHelp()); - PageInfo pageInfo = new PageInfo<>(shopProdStatisticMapper.findProdRandingSummaryPage2(param)); + PageInfo pageInfo = new PageInfo<>(shopProdStatisticMapper.findProdRandingSummaryPage(param)); return PageUtil.convert(pageInfo); } @@ -138,7 +140,7 @@ public class DataSummaryServiceImpl implements DataSummaryService { LocalDate now = LocalDate.now(); LocalDate beginDate = now.plusDays(-day); DataSummaryDateAmountVo data = new DataSummaryDateAmountVo(); - List total = new ArrayList<>(); + List total = new ArrayList<>(); for (int i = 1; i <= day; i++) { String thisDay = beginDate.plusDays(i).format(DatePattern.NORM_DATE_FORMATTER); OrderInfo orderInfo = orderInfoMapper.selectOneByQuery(QueryWrapper.create() @@ -147,7 +149,7 @@ public class DataSummaryServiceImpl implements DataSummaryService { .eq(OrderInfo::getTradeDay, thisDay) .isNotNull(OrderInfo::getPaidTime) ); - DataSummaryDateAmountVo.TotalVo totalVo = new DataSummaryDateAmountVo.TotalVo(); + TotalVo totalVo = new TotalVo(); if (orderInfo != null) { totalVo.setOrderAmount(orderInfo.getOrderAmount()); totalVo.setActualAmount(orderInfo.getPayAmount()); @@ -209,4 +211,5 @@ public class DataSummaryServiceImpl implements DataSummaryService { public List getShopIdList() { return shopOrderStatisticMapper.getShopIdList(); } + } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java index 64cb593f6..a5a7e5220 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java @@ -186,6 +186,7 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService { @Override public void orderRefundCallback(JSONObject data) { + log.info(">>>>>>>>>>>>>>>>>:入参:{}", data.toJSONString()); Long orderId = data.getLong("orderId"); // 订单取消后商品库存恢复,耗材恢复,流水记录 OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java index 6069f13ab..2d48ccf27 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoServiceImpl.java @@ -4,10 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.exceptions.ValidateException; import cn.hutool.core.thread.ThreadUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.*; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO; @@ -19,6 +16,7 @@ import com.czg.entity.notify.CzgPayNotifyDTO; import com.czg.entity.notify.CzgRefundNotifyDTO; import com.czg.enums.ShopUserFlowBizEnum; import com.czg.exception.ApiNotPrintException; +import com.czg.exception.CzgException; import com.czg.exception.OrderCancelException; import com.czg.order.dto.*; import com.czg.order.entity.CashierCart; @@ -31,6 +29,9 @@ import com.czg.order.service.OrderDetailService; import com.czg.order.service.OrderInfoService; import com.czg.order.service.OrderPaymentService; import com.czg.order.vo.*; +import com.czg.product.entity.Product; +import com.czg.product.service.ProductRpcService; +import com.czg.product.service.ProductService; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; import com.czg.service.RedisService; @@ -84,6 +85,10 @@ public class OrderInfoServiceImpl extends ServiceImpl orderDetails) { for (OrderDetail detail : orderDetails) { + if (!detail.getIsTemporary().equals(1) && detail.getProductId() > 0) { + Product product = productService.getOne(QueryWrapper.create() + .eq(Product::getId, detail.getProductId()) + .eq(Product::getShopId, detail.getShopId()) + .eq(Product::getIsDel, 0) + .eq(Product::getIsStock, 1)); + if (product != null && detail.getNum().compareTo(new BigDecimal(product.getStockNumber())) > 0) { + throw new CzgException("下单失败" + product.getName() + "库存不足"); + } + } if (detail.getDiscountSaleAmount() != null && detail.getDiscountSaleAmount().compareTo(BigDecimal.ZERO) > 0) { detail.setUnitPrice(detail.getDiscountSaleAmount()); } else { @@ -1018,6 +1033,7 @@ public class OrderInfoServiceImpl extends ServiceImpl details = orderDetailService.list(QueryWrapper.create().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getPlaceNum, placeNum)); + List> dataList = new ArrayList<>(); + for (OrderDetail detail : details) { + Map data = new HashMap<>(); + data.put("shopId", shopId); + data.put("productId", detail.getProductId()); + data.put("num", NumberUtil.sub(detail.getNum(), detail.getReturnNum())); + dataList.add(data); + } orderDetailService.remove(new QueryWrapper().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getPlaceNum, placeNum)); + if (CollUtil.isNotEmpty(dataList)) { + productRpcService.orderCancelRecoverStock(shopId, orderId, dataList); + } List list = orderDetailService.queryChain().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getShopId, shopId).list(); if (CollUtil.isEmpty(list)) { updateChain() diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PayServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PayServiceImpl.java index b65d63e64..8b8fa7a9d 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PayServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/PayServiceImpl.java @@ -6,7 +6,6 @@ import cn.hutool.core.exceptions.ValidateException; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; -import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO; import com.czg.account.entity.*; @@ -43,7 +42,6 @@ import com.czg.system.service.SysParamsService; import com.czg.utils.AssertUtil; import com.czg.utils.MD5Util; import com.mybatisflex.core.query.QueryWrapper; -import com.mybatisflex.core.update.UpdateChain; import jakarta.annotation.Resource; import jakarta.validation.constraints.NotBlank; import lombok.NonNull; @@ -644,6 +642,7 @@ public class PayServiceImpl implements PayService { //总退款金额 //TODO 退款 券 未处理 if (isPay) { + orderInfo.setRefundType("cash"); //非现金退款 if (!param.isCash()) { if (orderInfo.getPayType().equals(PayEnums.VIP_PAY.getValue())) { @@ -655,7 +654,7 @@ public class PayServiceImpl implements PayService { .setType(1) .setRelationId(orderInfo.getId()) .setBizEnum(ShopUserFlowBizEnum.ORDER_REFUND); - shopUserService.updateMoney(orderInfo.getShopId(), shopUserMoneyEditDTO); + shopUserService.updateMoney(shopUser.getShopId(), shopUserMoneyEditDTO); } else if (orderInfo.getPayType().equals(PayEnums.CREDIT_PAY.getValue())) { AssertUtil.isNull(orderInfo.getCreditBuyerId(), "挂账单退款失败,未查询到挂账人"); buyerOrderService.partRefund(orderInfo.getCreditBuyerId().toString(), orderInfo.getId(), param.getRefundAmount()); @@ -667,6 +666,7 @@ public class PayServiceImpl implements PayService { refundOrder(orderInfo.getShopId(), orderInfo.getId(), orderInfo.getPayOrderId(), refPayOrderNo, StrUtil.isBlank(param.getRefundReason()) ? "退款" : param.getRefundReason(), param.getRefundAmount()); } + orderInfo.setRefundType("payBack"); } } else { orderInfo.setOrderAmount(orderInfo.getOrderAmount().subtract(param.getRefundAmount())); @@ -690,6 +690,9 @@ public class PayServiceImpl implements PayService { CzgResult refund = refund(shopId, new CzgRefundReq(refPayOrderNo, refundReason, refundAmount.multiply(MONEY_RATE).longValue(), payment.getOrderNo(), "")); if (refund.getCode() != 200 || refund.getData() == null || !"SUCCESS".equals(refund.getData().getState())) { + if (refund.getData() != null && refund.getData().getNote() != null) { + throw new CzgException(refund.getData().getNote()); + } throw new CzgException(refund.getMsg()); } else { paymentService.updateChain() diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/SaleSummaryServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/SaleSummaryServiceImpl.java index 2b2f6d6a5..e8c62aa6d 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/SaleSummaryServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/SaleSummaryServiceImpl.java @@ -27,7 +27,7 @@ public class SaleSummaryServiceImpl implements SaleSummaryService { @Override public SaleSummaryCountVo summaryCount(SaleSummaryCountParam param) { - SaleSummaryCountVo saleSummaryCount = shopProdStatisticMapper.getSaleSummaryCount2(param); + SaleSummaryCountVo saleSummaryCount = shopProdStatisticMapper.getSaleSummaryCount(param); if (saleSummaryCount == null) { saleSummaryCount = new SaleSummaryCountVo(); } @@ -37,12 +37,12 @@ public class SaleSummaryServiceImpl implements SaleSummaryService { @Override public Page summaryPage(SaleSummaryCountParam param) { PageHelper.startPage(PageUtil.buildPageHelp()); - PageInfo pageInfo = new PageInfo<>(shopProdStatisticMapper.findSaleSummaryList2(param)); + PageInfo pageInfo = new PageInfo<>(shopProdStatisticMapper.findSaleSummaryList(param)); return PageUtil.convert(pageInfo); } @Override public List summaryList(SaleSummaryCountParam param) { - return shopProdStatisticMapper.findSaleSummaryList2(param); + return shopProdStatisticMapper.findSaleSummaryList(param); } } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java index 7d59aed8a..93688ed45 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopOrderStatisticServiceImpl.java @@ -10,9 +10,9 @@ import com.czg.order.service.ShopOrderStatisticService; import com.czg.service.order.mapper.ShopOrderStatisticMapper; import com.mybatisflex.spring.service.impl.ServiceImpl; import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -23,34 +23,54 @@ import java.util.List; * @since 2025-03-07 */ @Service +@Slf4j public class ShopOrderStatisticServiceImpl extends ServiceImpl implements ShopOrderStatisticService { @Resource private DataSummaryService dataSummaryService; @Override - public void statistic() { - // 获取前一天 - DateTime yesterday = DateUtil.yesterday(); + public void statistic(DateTime dateTime) { // 获取前一天的开始时间(00:00:00) - DateTime startOfDay = DateUtil.beginOfDay(yesterday); + DateTime startOfDay = DateUtil.beginOfDay(dateTime); // 获取前一天的结束时间(23:59:59) - DateTime endOfDay = DateUtil.endOfDay(yesterday); + DateTime endOfDay = DateUtil.endOfDay(dateTime); List shopIdList = dataSummaryService.getShopIdList(); if (CollUtil.isEmpty(shopIdList)) { return; } - shopIdList.parallelStream().forEach(shopId -> { - DataSummaryTradeParam param = new DataSummaryTradeParam(); - param.setShopId(shopId); - param.setBeginDate(startOfDay.toStringDefaultTimeZone()); - param.setEndDate(endOfDay.toStringDefaultTimeZone()); - ShopOrderStatistic statistic = dataSummaryService.getTradeData(param); - statistic.setShopId(shopId); - statistic.setCreateDay(LocalDate.now()); - statistic.setUpdateTime(LocalDateTime.now()); - saveOrUpdate(statistic); - }); + List> split = CollUtil.split(shopIdList, 5); + for (List splitIdList : split) { + splitIdList.parallelStream().forEach(shopId -> { + DataSummaryTradeParam param = new DataSummaryTradeParam(); + param.setShopId(shopId); + param.setBeginDate(startOfDay.toStringDefaultTimeZone()); + param.setEndDate(endOfDay.toStringDefaultTimeZone()); + ShopOrderStatistic statistic = dataSummaryService.getRealTimeTradeData(param); + statistic.setShopId(shopId); + statistic.setCreateDay(dateTime.toLocalDateTime().toLocalDate()); + statistic.setUpdateTime(LocalDateTime.now()); + if (statistic.getNewMemberCount() != 0L) { + System.out.println("newMemberCount:" + statistic.getNewMemberCount()); + } + // 如果没有订单和退款,则不更新数据,否则会产出很多数据 + if (statistic.getSaleCount() == 0 + && statistic.getRefundCount() == 0 + && statistic.getMemberPayCount() == 0 + && statistic.getNewMemberCount() == 0 + ) { + log.info("店铺:{},{},没有要存档的订单统计数据", shopId, dateTime.toDateStr()); + } else { + ShopOrderStatistic entity = getMapper().selectOneByQuery(query().eq(ShopOrderStatistic::getShopId, shopId).eq(ShopOrderStatistic::getCreateDay, dateTime.toDateStr())); + if (entity != null) { + statistic.setId(entity.getId()); + updateById(statistic); + } else { + save(statistic); + } + } + }); + } } } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java index 5d3e9e02f..796d95387 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopProdStatisticServiceImpl.java @@ -1,35 +1,41 @@ package com.czg.service.order.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; -import com.czg.order.entity.OrderDetail; -import com.czg.order.service.OrderDetailService; +import cn.hutool.core.util.NumberUtil; +import com.czg.order.entity.ShopProdStatistic; +import com.czg.order.param.DataSummaryProductSaleParam; +import com.czg.order.service.DataSummaryService; +import com.czg.order.service.ShopProdStatisticService; +import com.czg.order.vo.DataSummaryProductSaleRankingVo; +import com.czg.service.order.mapper.ShopProdStatisticMapper; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.spring.service.impl.ServiceImpl; -import com.czg.order.entity.ShopProdStatistic; -import com.czg.order.service.ShopProdStatisticService; -import com.czg.service.order.mapper.ShopProdStatisticMapper; import jakarta.annotation.Resource; import lombok.Data; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** - * 服务层实现。 + * 服务层实现。 * * @author zs * @since 2025-03-07 */ @Service -public class ShopProdStatisticServiceImpl extends ServiceImpl implements ShopProdStatisticService{ +@Slf4j +public class ShopProdStatisticServiceImpl extends ServiceImpl implements ShopProdStatisticService { @Resource - private OrderDetailService orderDetailService; + private DataSummaryService dataSummaryService; + @Resource + private ShopProdStatisticMapper shopProdStatisticMapper; + @Data - private static class StatisticTask{ + private static class StatisticTask { private BigDecimal successCount = BigDecimal.ZERO; private BigDecimal successAmount = BigDecimal.ZERO; private BigDecimal refundCount = BigDecimal.ZERO; @@ -37,57 +43,42 @@ public class ShopProdStatisticServiceImpl extends ServiceImpl orderDetails = orderDetailService.list(new QueryWrapper() - .ge(OrderDetail::getCreateTime, startOfDay) - .le(OrderDetail::getCreateTime, endOfDay) - .ne(OrderDetail::getStatus, "wait-pay")); - - - HashMap> countInfo = new HashMap<>(); - for (OrderDetail item : orderDetails) { - Map map = countInfo.computeIfAbsent(item.getShopId(), k -> new HashMap<>()); - StatisticTask statisticTask = map.get(item.getProductId()); - if (statisticTask == null) { - map.put(item.getProductId(), statisticTask = new StatisticTask()); - } - if ("refunding".equals(item.getStatus()) || "refund".equals(item.getStatus()) || "part-refund".equals(item.getStatus())) { - statisticTask.setRefundAmount(statisticTask.getRefundAmount().add(item.getReturnAmount())); - statisticTask.setRefundCount(statisticTask.getRefundCount().add(item.getRefundNum())); - if (item.getReturnNum().compareTo(item.getNum()) < 0) { - statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount().subtract(item.getReturnAmount()))); - statisticTask.setSuccessCount(statisticTask.getSuccessCount().add(item.getNum().subtract(item.getReturnAmount()))); - } - }else { - statisticTask.setSuccessCount(statisticTask.getSuccessCount().add(item.getNum())); - statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount())); - } + DateTime endOfDay = DateUtil.endOfDay(dateTime); + List shopIdList = dataSummaryService.getShopIdList(); + if (CollUtil.isEmpty(shopIdList)) { + return; + } + List> split = CollUtil.split(shopIdList, 5); + for (List splitIdList : split) { + splitIdList.parallelStream().forEach(shopId -> { + DataSummaryProductSaleParam param = new DataSummaryProductSaleParam(); + param.setShopId(shopId); + param.setBeginDate(startOfDay.toStringDefaultTimeZone()); + param.setEndDate(endOfDay.toStringDefaultTimeZone()); + // 删除之前统计数据 + getMapper().deleteByQuery(QueryWrapper.create().eq(ShopProdStatistic::getShopId, shopId).eq(ShopProdStatistic::getCreateDay, dateTime.toDateStr())); + // 重新统计数据 + List list = shopProdStatisticMapper.findProdRandingSummaryPage2(param); + for (DataSummaryProductSaleRankingVo dto : list) { + ShopProdStatistic entity = new ShopProdStatistic(); + entity.setProdId(dto.getProductId()); + entity.setSaleCount(dto.getNumber()); + entity.setSaleAmount(dto.getAmount()); + entity.setRefundCount(dto.getRefundCount()); + entity.setRefundAmount(dto.getRefundAmount()); + entity.setShopId(shopId); + entity.setCreateDay(dateTime.toJdkDate()); + if (NumberUtil.isLessOrEqual(entity.getSaleCount(), BigDecimal.ZERO) && NumberUtil.isLessOrEqual(entity.getRefundCount(), BigDecimal.ZERO)) { + log.info("店铺:{},{},没有要存档的商品统计数据", shopId, dateTime.toDateStr()); + } else { + save(entity); + } + } + }); } - - countInfo.forEach((shopId, map) -> map.forEach((productId, statisticTask) -> { - ShopProdStatistic statistic = getOne(new QueryWrapper().eq(ShopProdStatistic::getShopId, shopId).eq(ShopProdStatistic::getCreateDay, yesterday.toSqlDate())); - if (statistic == null) { - statistic = new ShopProdStatistic(); - statistic.setShopId(shopId); - statistic.setCreateDay(yesterday.toSqlDate()); - } - statistic.setProdId(productId); - statistic.setSaleCount(statisticTask.getSuccessCount()); - statistic.setSaleAmount(statisticTask.getSuccessAmount()); - statistic.setRefundCount(statisticTask.getRefundCount()); - statistic.setRefundAmount(statisticTask.getRefundAmount()); - saveOrUpdate(statistic); - })); - - } - - } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java index ccadfb5d1..f3ac76f5a 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/ShopTableOrderStatisticServiceImpl.java @@ -1,25 +1,26 @@ package com.czg.service.order.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; -import com.czg.config.RedisCst; -import com.czg.order.entity.OrderInfo; -import com.czg.order.service.OrderInfoService; +import com.czg.order.entity.ShopTableOrderStatistic; +import com.czg.order.param.TableSummaryParam; +import com.czg.order.service.DataSummaryService; +import com.czg.order.service.ShopTableOrderStatisticService; +import com.czg.order.vo.TableSummaryInfoVo; +import com.czg.service.order.mapper.ShopTableOrderStatisticMapper; import com.czg.utils.PageUtil; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.spring.service.impl.ServiceImpl; -import com.czg.order.entity.ShopTableOrderStatistic; -import com.czg.order.service.ShopTableOrderStatisticService; -import com.czg.service.order.mapper.ShopTableOrderStatisticMapper; import jakarta.annotation.Resource; import lombok.Data; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.HashMap; import java.util.List; /** @@ -29,35 +30,38 @@ import java.util.List; * @since 2025-03-07 */ @Service -public class ShopTableOrderStatisticServiceImpl extends ServiceImpl implements ShopTableOrderStatisticService{ +@Slf4j +public class ShopTableOrderStatisticServiceImpl extends ServiceImpl implements ShopTableOrderStatisticService { @Resource - private OrderInfoService orderInfoService; + private DataSummaryService dataSummaryService; + @Resource + private ShopTableOrderStatisticMapper shopTableOrderStatisticMapper; @Override public Page summary(Long shopId, String startTime, String endTime) { Page page = PageUtil.buildPage(); - PageHelper.startPage(Math.toIntExact(page.getPageNumber()),Math.toIntExact(page.getPageSize())); + PageHelper.startPage(Math.toIntExact(page.getPageNumber()), Math.toIntExact(page.getPageSize())); return PageUtil.convert(new PageInfo<>(mapper.selectSummary(shopId, startTime, endTime))); } @Override public boolean addInfo(long shopId, long tableId, long count, BigDecimal amount) { - ShopTableOrderStatistic statistic = getOne(new QueryWrapper().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getTableId, tableId) - .eq(ShopTableOrderStatistic::getCreateDay, DateUtil.date().toDateStr())); - if (statistic == null) { - statistic = new ShopTableOrderStatistic(); - statistic.setShopId(shopId); - statistic.setTableId(tableId); - statistic.setCreateDay(DateUtil.date().toSqlDate()); - statistic.setOrderCount(count); - statistic.setOrderAmount(amount); - save(statistic); - } - return mapper.incrInfo(shopId, tableId, count, amount, DateUtil.date().toDateStr()); + ShopTableOrderStatistic statistic = getOne(new QueryWrapper().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getTableId, tableId) + .eq(ShopTableOrderStatistic::getCreateDay, DateUtil.date().toDateStr())); + if (statistic == null) { + statistic = new ShopTableOrderStatistic(); + statistic.setShopId(shopId); + statistic.setTableId(tableId); + statistic.setCreateDay(DateUtil.date().toSqlDate()); + statistic.setOrderCount(count); + statistic.setOrderAmount(amount); + save(statistic); + } + return mapper.incrInfo(shopId, tableId, count, amount, DateUtil.date().toDateStr()); } @Data - private static class StatisticTask{ + private static class StatisticTask { private long successCount = 0; private BigDecimal successAmount = BigDecimal.ZERO; private long refundCount = 0; @@ -65,53 +69,46 @@ public class ShopTableOrderStatisticServiceImpl extends ServiceImpl orderInfos = orderInfoService.list(new QueryWrapper() - .ge(OrderInfo::getCreateTime, startOfDay) - .le(OrderInfo::getCreateTime, endOfDay) - .ne(OrderInfo::getStatus, "unpaid").ne(OrderInfo::getStatus, "cancelled")); - - HashMap countInfo = new HashMap<>(); - for (OrderInfo item : orderInfos) { - StatisticTask statisticTask = countInfo.get(item.getShopId()); - if (statisticTask == null) { - countInfo.put(item.getShopId(), statisticTask = new StatisticTask()); - } - if ("refunding".equals(item.getStatus()) || "refund".equals(item.getStatus()) || "part-refund".equals(item.getStatus())) { - statisticTask.setRefundAmount(statisticTask.getRefundAmount().add(item.getRefundAmount())); - statisticTask.setRefundCount(statisticTask.getRefundCount() + 1); - if (item.getRefundAmount().compareTo(item.getPayAmount()) < 0) { - statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount().subtract(item.getRefundAmount()))); - } - }else { - statisticTask.setSuccessCount(statisticTask.getSuccessCount() + 1); - statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount())); - } + DateTime endOfDay = DateUtil.endOfDay(dateTime); + List shopIdList = dataSummaryService.getShopIdList(); + if (CollUtil.isEmpty(shopIdList)) { + return; + } + List> split = CollUtil.split(shopIdList, 5); + for (List splitIdList : split) { + splitIdList.parallelStream().forEach(shopId -> { + TableSummaryParam param = new TableSummaryParam(); + param.setShopId(shopId); + param.setBeginDate(startOfDay.toStringDefaultTimeZone()); + param.setEndDate(endOfDay.toStringDefaultTimeZone()); + // 删除之前统计数据 + getMapper().deleteByQuery(QueryWrapper.create().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getCreateDay, dateTime.toDateStr())); + // 重新统计数据 + List list = shopTableOrderStatisticMapper.findSummaryList2(param); + for (TableSummaryInfoVo dto : list) { + ShopTableOrderStatistic entity = new ShopTableOrderStatistic(); + entity.setTableId(dto.getTableId()); + entity.setTableCode(dto.getTableCode()); + entity.setTableName(dto.getTableName()); + entity.setAreaName(dto.getAreaName()); + entity.setOrderCount(dto.getOrderCount()); + entity.setOrderAmount(dto.getOrderAmount()); + entity.setRefundCount(dto.getRefundCount()); + entity.setRefundAmount(dto.getRefundAmount()); + entity.setShopId(shopId); + entity.setCreateDay(dateTime.toJdkDate()); + if (entity.getOrderCount() == 0L && entity.getRefundCount() == 0L) { + log.info("店铺:{},{},没有要存档的台桌统计数据", shopId, dateTime.toDateStr()); + } else { + save(entity); + } + } + }); } - - countInfo.forEach((shopId, statisticTask) -> { - ShopTableOrderStatistic statistic = getOne(new QueryWrapper().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getCreateDay, yesterday.toSqlDate())); - if (statistic == null) { - statistic = new ShopTableOrderStatistic(); - statistic.setShopId(shopId); - statistic.setTableId(0L); - statistic.setCreateDay(yesterday.toSqlDate()); - } - statistic.setOrderCount(statisticTask.getSuccessCount()); - statistic.setOrderAmount(statisticTask.getSuccessAmount()); - statistic.setRefundCount(statisticTask.getRefundCount()); - statistic.setRefundAmount(statisticTask.getRefundAmount()); - saveOrUpdate(statistic); - }); - } } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java index 9d0ed8551..cf43704b3 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/TableSummaryServiceImpl.java @@ -30,7 +30,7 @@ public class TableSummaryServiceImpl implements TableSummaryService { @Override public List summaryList(TableSummaryParam param) { - return shopTableOrderStatisticMapper.findSummaryList2(param); + return shopTableOrderStatisticMapper.findSummaryList(param); } @Override diff --git a/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml index e739c65bc..d09c8cbef 100644 --- a/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml +++ b/cash-service/order-service/src/main/resources/mapper/ShopOrderStatisticMapper.xml @@ -26,6 +26,7 @@ sum(recharge_amount) as recharge_amount, avg(customer_unit_price) as customer_unit_price, avg(table_turnover_rate) as table_turnover_rate, + sum(new_member_count) as new_member_count, max(update_time) as update_time from tb_shop_order_statistic where shop_id = #{shopId} diff --git a/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml b/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml index d8bd485e2..d4ebdb653 100644 --- a/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml +++ b/cash-service/order-service/src/main/resources/mapper/ShopProdStatisticMapper.xml @@ -17,7 +17,8 @@ #{day} - group by t1.prod_id + group by t1.prod_id,t2.name + order by sum(t1.sale_count) desc + diff --git a/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml b/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml index 86459c688..df12b590f 100644 --- a/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml +++ b/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml @@ -79,7 +79,7 @@ t2.member_price, t1.cover_img, t1.images, - t3.name as unit_name, + t3.name as unit_name, t1.is_sold_stock, t1.stock_number, t1.type, @@ -88,25 +88,30 @@ t1.start_time, t1.end_time, t1.is_hot, - ifnull(t2.suit_num, 1) as suit_num, + ifnull(t2.suit_num, 1) as suit_num, t1.select_spec_info, t1.group_snap, t1.pack_fee, - ifnull(t4.sales_volume, 0) as sales_volume + ifnull(t4.sales_volume, 0) as sales_volume, + t1.shop_id, + t1.is_stock from tb_product t1 - left join (select x.product_id, - x.id as sku_id, - MIN(x.sale_price) as sale_price, - x.origin_price, - x.member_price, - x.suit_num - from tb_prod_sku x - where x.is_del = 0 - and x.is_grounding = 1 - and x.shop_id = #{shopId} - group by x.product_id) t2 on t1.id = t2.product_id - left join tb_shop_prod_unit t3 on t1.unit_id = t3.id - left join (select product_id,sum(num) as sales_volume from tb_order_detail where pay_amount is not null group by product_id) t4 on t1.id = t4.product_id + left join (select x.product_id, + x.id as sku_id, + MIN(x.sale_price) as sale_price, + x.origin_price, + x.member_price, + x.suit_num + from tb_prod_sku x + where x.is_del = 0 + and x.is_grounding = 1 + and x.shop_id = #{shopId} + group by x.product_id) t2 on t1.id = t2.product_id + left join tb_shop_prod_unit t3 on t1.unit_id = t3.id + left join (select product_id, sum(num) as sales_volume + from tb_order_detail + where pay_amount is not null + group by product_id) t4 on t1.id = t4.product_id select ifnull( ROUND(ST_Distance_Sphere(POINT(b.lng, b.lat), POINT(#{lng}, #{lat})) / 1000, 2), 0) AS distance, - c.name, a.origin_price, a.sale_price, b.shop_name, b.districts, c.cover_img, b.logo, c.id, - a.real_sales_number saleNum, (round(a.sale_price / a.origin_price, 2) * 10) AS discount, + c.name, a.origin_price, a.sale_price, b.shop_name, b.districts, c.cover_img, b.logo, c.id, + a.real_sales_number saleNum, (round(a.sale_price / a.origin_price, 2) * 10) AS discount, c.id productId, a.id skuId, b.id shopId from tb_prod_sku as a left join tb_product c on c.id=a.product_id @@ -208,17 +218,44 @@ + update tb_product diff --git a/cash-service/product-service/src/main/resources/mapper/ShopVendorMapper.xml b/cash-service/product-service/src/main/resources/mapper/ShopVendorMapper.xml index ff7722c1c..b1d6389bb 100644 --- a/cash-service/product-service/src/main/resources/mapper/ShopVendorMapper.xml +++ b/cash-service/product-service/src/main/resources/mapper/ShopVendorMapper.xml @@ -22,15 +22,18 @@ WHERE shop_id = #{shopId} diff --git a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SqlScriptServiceImpl.java b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SqlScriptServiceImpl.java index 7a189c6f0..3c843357a 100644 --- a/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SqlScriptServiceImpl.java +++ b/cash-service/system-service/src/main/java/com/czg/service/system/service/impl/SqlScriptServiceImpl.java @@ -109,7 +109,7 @@ public class SqlScriptServiceImpl extends ServiceImpl sqlList = Arrays.asList(sqls.split("\\r?\\n")); + List sqlList = Arrays.asList(sqls.split(";")); for (String sql : sqlList) { if (!sql.trim().isEmpty()) { jdbcTemplate.execute(sql); diff --git a/sqls/250327/cash.sql b/sqls/250327/cash.sql deleted file mode 100644 index c5473a39b..000000000 --- a/sqls/250327/cash.sql +++ /dev/null @@ -1 +0,0 @@ -select * from tb_cashier_cart; \ No newline at end of file diff --git a/sqls/250403/cash.sql b/sqls/250403/cash.sql deleted file mode 100644 index 97f3e01b0..000000000 --- a/sqls/250403/cash.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `tb_shop_info` ADD COLUMN `is_head_shop` tinyint NULL COMMENT '是否主店 1-是 0-否'; \ No newline at end of file diff --git a/sqls/250403/tb_cons_group.sql b/sqls/250403/tb_cons_group.sql new file mode 100644 index 000000000..b8d8561ef --- /dev/null +++ b/sqls/250403/tb_cons_group.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_cons_group` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; diff --git a/sqls/250403/tb_cons_info.sql b/sqls/250403/tb_cons_info.sql new file mode 100644 index 000000000..cc6bfcb15 --- /dev/null +++ b/sqls/250403/tb_cons_info.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_cons_info` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; diff --git a/sqls/250403/tb_prod_cons_relation.sql b/sqls/250403/tb_prod_cons_relation.sql new file mode 100644 index 000000000..d427c5c1c --- /dev/null +++ b/sqls/250403/tb_prod_cons_relation.sql @@ -0,0 +1,4 @@ +ALTER TABLE `tb_prod_cons_relation` + DROP COLUMN `id`, + DROP PRIMARY KEY, + ADD PRIMARY KEY (`shop_id`, `product_id`, `cons_info_id`) USING BTREE; \ No newline at end of file diff --git a/sqls/250403/tb_prod_group.sql b/sqls/250403/tb_prod_group.sql new file mode 100644 index 000000000..cebf3f341 --- /dev/null +++ b/sqls/250403/tb_prod_group.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_prod_sku` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; diff --git a/sqls/250403/tb_prod_sku.sql b/sqls/250403/tb_prod_sku.sql new file mode 100644 index 000000000..b6cd05d22 --- /dev/null +++ b/sqls/250403/tb_prod_sku.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_product` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; diff --git a/sqls/250403/tb_product.sql b/sqls/250403/tb_product.sql new file mode 100644 index 000000000..b6cd05d22 --- /dev/null +++ b/sqls/250403/tb_product.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_product` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; diff --git a/sqls/250403/tb_shop_info.sql b/sqls/250403/tb_shop_info.sql new file mode 100644 index 000000000..e1b6af638 --- /dev/null +++ b/sqls/250403/tb_shop_info.sql @@ -0,0 +1,65 @@ +ALTER TABLE `tb_shop_info` + ADD COLUMN `is_head_shop` tinyint NULL COMMENT '是否主店 1-是 0-否'; +-- ---------------------------- +-- 更新历史数据,将创建时间在2025年4月3日之前的店铺设置为非主店 +-- ---------------------------- +update tb_shop_info +set is_head_shop = 0 +where create_time < str_to_date('2025-04-03 00:00:00', '%Y-%m-%d %H:%i:%s'); +-- ---------------------------- +-- 创建店铺配置扩展表 +-- ---------------------------- +CREATE TABLE `tb_shop_config` +( + `id` bigint NOT NULL COMMENT '店铺id', + `main_id` bigint NULL DEFAULT NULL COMMENT '主店id', + `is_enable_prod_sync` tinyint NOT NULL DEFAULT 0 COMMENT '是否启用商品同步 1-是 0-否', + `is_enable_vip_sync` tinyint NOT NULL DEFAULT 0 COMMENT '是否启用会员同步 1-是 0-否', + `is_enable_cons_sync` tinyint NOT NULL DEFAULT 0 COMMENT '是否启用耗材同步 1-是 0-否', + `is_allow_account_login` tinyint NOT NULL DEFAULT 1 COMMENT '是否允许账号登录 1-是 0-否', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `is_custom_amount` int NOT NULL DEFAULT 0 COMMENT '是否允许会员自定义金额 1-允许 0-不允许', + `is_return_pwd` int NOT NULL DEFAULT 0 COMMENT '是否开启退款密码 1-启用 0-禁用', + `is_member_in_pwd` int NOT NULL DEFAULT 0 COMMENT '是否开启会员充值密码 1-启用 0-禁用', + `is_member_return_pwd` int NOT NULL DEFAULT 0 COMMENT '是否开启会员退款密码 1-启用 0-禁用', + `is_table_fee` int NOT NULL DEFAULT 1 COMMENT '是否免除桌位费 1-是 0-否', + `is_member_price` int NOT NULL DEFAULT 0 COMMENT '是否启用会员价 1-是 0-否 ', + `is_account_pay` tinyint NOT NULL DEFAULT 0 COMMENT '是否允许会员余额支付 1-是 0-否', + `branch_data_sync_method` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '分店数据同步方式 auto-自动同步 manual-手动同步', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB + CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci COMMENT = '店铺配置扩展' + ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- 转移历史数据至【店铺配置扩展表】 +-- ---------------------------- +insert into tb_shop_config +select id, + main_id, + 0 as is_enable_prod_sync, + 0 as is_enable_vip_sync, + 0 as is_enable_cons_sync, + 1 as is_allow_account_login, + null as remark, + is_custom_amount, + is_return_pwd, + is_member_in_pwd, + is_member_return_pwd, + is_table_fee, + is_member_price, + is_account_pay, + null as branch_data_sync_method +from tb_shop_info; +-- ---------------------------- +-- 删除店铺主表是否xxx等字段,迁移至店铺配置扩展表 +-- ---------------------------- +ALTER TABLE `tb_shop_info` + DROP COLUMN `is_custom_amount`, + DROP COLUMN `is_return_pwd`, + DROP COLUMN `is_member_in_pwd`, + DROP COLUMN `is_member_return_pwd`, + DROP COLUMN `is_table_fee`, + DROP COLUMN `is_member_price`, + DROP COLUMN `is_account_pay`; \ No newline at end of file diff --git a/sqls/250403/tb_shop_prod_category.sql b/sqls/250403/tb_shop_prod_category.sql new file mode 100644 index 000000000..c370ba632 --- /dev/null +++ b/sqls/250403/tb_shop_prod_category.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_shop_prod_category` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; \ No newline at end of file diff --git a/sqls/250403/tb_shop_prod_spec.sql b/sqls/250403/tb_shop_prod_spec.sql new file mode 100644 index 000000000..e2a65204d --- /dev/null +++ b/sqls/250403/tb_shop_prod_spec.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_shop_prod_spec` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; \ No newline at end of file diff --git a/sqls/250403/tb_shop_prod_unit.sql b/sqls/250403/tb_shop_prod_unit.sql new file mode 100644 index 000000000..f0b5506ad --- /dev/null +++ b/sqls/250403/tb_shop_prod_unit.sql @@ -0,0 +1 @@ +ALTER TABLE `tb_shop_prod_unit` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`; \ No newline at end of file diff --git a/sqls/250403/tb_shop_user.sql b/sqls/250403/tb_shop_user.sql new file mode 100644 index 000000000..ec6e03ae5 --- /dev/null +++ b/sqls/250403/tb_shop_user.sql @@ -0,0 +1,5 @@ +-- ---------------------------- +-- tb_shop_user表扩展字段 +-- ---------------------------- +ALTER TABLE `tb_shop_user` + ADD COLUMN `merged_users` text NULL COMMENT '已经合并过来的用户信息,jsonArray格式,[{\"id\":1,\"shopId\":2,...},{\"id\":1,\"shopId\":2,...}]'; \ No newline at end of file diff --git a/sqls/250403/tb_shop_vendor.sql b/sqls/250403/tb_shop_vendor.sql new file mode 100644 index 000000000..4979c7f07 --- /dev/null +++ b/sqls/250403/tb_shop_vendor.sql @@ -0,0 +1,2 @@ +ALTER TABLE `tb_shop_vendor` + ADD COLUMN `sync_id` bigint NULL DEFAULT NULL COMMENT '同步Id' AFTER `id`; \ No newline at end of file diff --git a/sqls/250403/tb_sync_notice.sql b/sqls/250403/tb_sync_notice.sql new file mode 100644 index 000000000..bf02edad2 --- /dev/null +++ b/sqls/250403/tb_sync_notice.sql @@ -0,0 +1,12 @@ +CREATE TABLE `tb_sync_notice` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `shop_id` bigint DEFAULT NULL COMMENT '店铺id', + `sys_user_id` bigint DEFAULT NULL COMMENT '操作用户id', + `type` tinyint DEFAULT NULL COMMENT '通知类型 0 商品新增 1 商品编辑 2耗材新增 3耗材编辑\r\n', + `is_read` tinyint DEFAULT '0' COMMENT '是否已读,1已读', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `read_time` datetime DEFAULT NULL COMMENT '已读时间', + `content` varchar(255) DEFAULT NULL COMMENT '消息内容', + `extra_json` varchar(255) DEFAULT NULL COMMENT '拓展信息', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;