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 00000000..95f1ca7b --- /dev/null +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopBranchController.java @@ -0,0 +1,87 @@ +package com.czg.controller.admin; + +import com.czg.account.dto.ShopBranchDTO; +import com.czg.account.service.ShopBranchService; +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; + + /** + * 分店列表 + */ + @GetMapping("page") + @OperationLog("分店管理-分页") + public CzgResult> getBranchPage() { + Long shopId = StpKit.USER.getShopId(0L); + Page data = shopBranchService.findPage(shopId); + 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); + CzgResult ret = CzgResult.success(); + ret.setMsg("设置成功,数据正在后台同步中..."); + return ret; + } + + /** + * 同步启用 + * + * @param branchShopId 分店id + */ + @PostMapping("/data/sync/enable") + @OperationLog("分店管理-同步启用") + public CzgResult dataSyncEnable(@RequestParam Long branchShopId) { + shopBranchService.dataSyncEnable(branchShopId); + return CzgResult.success(); + } + + /** + * 账号启用 + * + * @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(); + } +} 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 dde3b078..560ad492 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,6 +1,7 @@ package com.czg.controller.admin; 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; @@ -15,6 +16,8 @@ import com.mybatisflex.core.query.QueryWrapper; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** * 店铺管理 * @@ -85,4 +88,14 @@ public class ShopInfoController { return CzgResult.success(shopInfoService.remove(new QueryWrapper().eq(ShopInfo::getId, id))); } + /** + * 店铺分店列表(下拉展示主店和分店使用,默认第一个是主店,其余是分店) + */ + @GetMapping("branchList") + public CzgResult> findShopBranch() { + Long shopId = StpKit.USER.getShopId(0L); + List data = shopInfoService.findShopBranch(shopId); + return CzgResult.success(data); + } + } 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 00000000..465cedae --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/ShopBranchDTO.java @@ -0,0 +1,54 @@ +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; + /** + * 账号 + */ + 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/shopinfo/ShopBranchSelectDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/shopinfo/ShopBranchSelectDTO.java new file mode 100644 index 00000000..568cd0d5 --- /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/enums/BranchDataSyncMethodEnum.java b/cash-common/cash-common-service/src/main/java/com/czg/account/enums/BranchDataSyncMethodEnum.java index 4446f5ed..a3d23ba2 100644 --- 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 @@ -40,4 +40,8 @@ public enum BranchDataSyncMethodEnum { 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/service/ShopBranchService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopBranchService.java new file mode 100644 index 00000000..9c178a2b --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopBranchService.java @@ -0,0 +1,53 @@ +package com.czg.account.service; + +import com.czg.account.dto.ShopBranchDTO; +import com.mybatisflex.core.paginate.Page; + +/** + * 分店管理Service + * + * @author tankaikai + * @since 2025-04-07 14:09 + */ +public interface ShopBranchService { + /** + * 查询分店列表 + * + * @param shopId 主店id + * @return 分店列表 + */ + Page findPage(Long shopId); + + /** + * 设计数据同步方式 + * + * @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/ShopInfoService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopInfoService.java index a3da06d2..554fdda5 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,6 +6,8 @@ import com.czg.account.entity.ShopInfo; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; +import java.util.List; + /** * @author Administrator */ @@ -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-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 index e428e6dd..26719074 100644 --- 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 @@ -1,16 +1,22 @@ package com.czg.service.account.mapper; +import com.czg.account.dto.ShopBranchDTO; import com.czg.account.entity.ShopConfig; import com.mybatisflex.core.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** -* 店铺配置扩展 -* -* @author Tankaikai tankaikai@aliyun.com -* @since 1.0 2025-04-03 -*/ + * 店铺配置扩展 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-04-03 + */ @Mapper public interface ShopConfigMapper extends BaseMapper { - + + List findBranchList(@Param("shopId") Long shopId); + } \ No newline at end of file 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 d56aba81..624b23fb 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 @@ -49,6 +49,8 @@ public class AuthorizationServiceImpl implements AuthorizationService { @Resource private SysMenuMapper sysMenuMapper; @Resource + private ShopBranchService shopBranchService; + @Resource private HandoverRecordService handoverRecordService; @@ -140,7 +142,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()); 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 00000000..b3f804aa --- /dev/null +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopBranchServiceImpl.java @@ -0,0 +1,175 @@ +package com.czg.service.account.service.impl; + +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.service.ShopBranchService; +import com.czg.enums.YesNoEnum; +import com.czg.exception.CzgException; +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 org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 分店管理Service实现类 + * + * @author tankaikai + * @since 2025-04-07 14:20 + */ +@Service +public class ShopBranchServiceImpl implements ShopBranchService { + + @Resource + private ShopConfigMapper shopConfigMapper; + + @Resource + private ShopInfoMapper shopInfoMapper; + + @Override + public Page findPage(Long shopId) { + PageHelper.startPage(PageUtil.buildPageHelp()); + List branchList = shopConfigMapper.findBranchList(shopId); + 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); + // TODO 异步事务同步商品数据、会员数据、耗材数据 + } + + @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/ShopInfoServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopInfoServiceImpl.java index 2696ad3d..e48db198 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 @@ -40,6 +40,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; @@ -352,4 +353,22 @@ 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); + 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(); + head.setShopId(info.getId()); + head.setShopName(info.getShopName()); + list.add(branch); + } + return list; + } } diff --git a/cash-service/account-service/src/main/resources/mapper/ShopConfigMapper.xml b/cash-service/account-service/src/main/resources/mapper/ShopConfigMapper.xml index 16bdbac8..8cdf3252 100644 --- a/cash-service/account-service/src/main/resources/mapper/ShopConfigMapper.xml +++ b/cash-service/account-service/src/main/resources/mapper/ShopConfigMapper.xml @@ -3,4 +3,14 @@ + \ No newline at end of file