多店铺需求

This commit is contained in:
Tankaikai 2025-04-07 15:16:36 +08:00
parent 982aab3108
commit ed1bd44f6a
12 changed files with 463 additions and 7 deletions

View File

@ -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<Page<ShopBranchDTO>> getBranchPage() {
Long shopId = StpKit.USER.getShopId(0L);
Page<ShopBranchDTO> data = shopBranchService.findPage(shopId);
return CzgResult.success(data);
}
/**
* 设置数据同步方式
*
* @param dataSyncMethod 数据同步方式 auto-实时自动同步 manual-手动同步
*/
@PostMapping("/setting/dataSyncMethod")
@OperationLog("分店管理-设置数据同步方式")
public CzgResult<Void> settingDataSyncMethod(@RequestParam String dataSyncMethod) {
Long shopId = StpKit.USER.getShopId(0L);
shopBranchService.settingDataSyncMethod(shopId, dataSyncMethod);
CzgResult<Void> ret = CzgResult.success();
ret.setMsg("设置成功,数据正在后台同步中...");
return ret;
}
/**
* 同步启用
*
* @param branchShopId 分店id
*/
@PostMapping("/data/sync/enable")
@OperationLog("分店管理-同步启用")
public CzgResult<Void> dataSyncEnable(@RequestParam Long branchShopId) {
shopBranchService.dataSyncEnable(branchShopId);
return CzgResult.success();
}
/**
* 账号启用
*
* @param branchShopId 分店id
*/
@PostMapping("/account/enable")
@OperationLog("分店管理-账号启用")
public CzgResult<Void> accountEnable(@RequestParam Long branchShopId) {
shopBranchService.accountEnable(branchShopId);
return CzgResult.success();
}
/**
* 账号禁用
*
* @param branchShopId 分店id
*/
@PostMapping("/account/disable")
@OperationLog("分店管理-账号禁用")
public CzgResult<Void> accountDisable(@RequestParam Long branchShopId) {
shopBranchService.accountDisable(branchShopId);
return CzgResult.success();
}
}

View File

@ -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<List<ShopBranchSelectDTO>> findShopBranch() {
Long shopId = StpKit.USER.getShopId(0L);
List<ShopBranchSelectDTO> data = shopInfoService.findShopBranch(shopId);
return CzgResult.success(data);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -40,4 +40,8 @@ public enum BranchDataSyncMethodEnum {
return null;
}
public static boolean checkValue(String value) {
return getValues().contains(value);
}
}

View File

@ -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<ShopBranchDTO> 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);
}

View File

@ -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<ShopInfo> {
Page<ShopInfoSubVO> getSubList(String lat, String lng, float distance);
List<ShopBranchSelectDTO> findShopBranch(Long shopId);
}

View File

@ -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<ShopConfig> {
List<ShopBranchDTO> findBranchList(@Param("shopId") Long shopId);
}

View File

@ -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<SysRole> roleList = sysRoleService.getByUserId(user.getId());

View File

@ -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<ShopBranchDTO> findPage(Long shopId) {
PageHelper.startPage(PageUtil.buildPageHelp());
List<ShopBranchDTO> 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;
}
}

View File

@ -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<ShopInfoMapper, ShopInfo> i
PageHelper.startPage(PageUtil.buildPageHelp());
return PageUtil.convert(new PageInfo<>(mapper.getSubList(lng, lat, distance)));
}
@Override
public List<ShopBranchSelectDTO> findShopBranch(Long shopId) {
List<ShopBranchSelectDTO> list = new ArrayList<>();
ShopInfo shopInfo = mapper.selectOneById(shopId);
ShopBranchSelectDTO head = new ShopBranchSelectDTO();
head.setShopId(shopInfo.getId());
head.setShopName(shopInfo.getShopName());
list.add(head);
List<ShopInfo> 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;
}
}

View File

@ -3,4 +3,14 @@
<mapper namespace="com.czg.service.account.mapper.ShopConfigMapper">
<select id="findBranchList" resultType="com.czg.account.dto.ShopBranchDTO">
select t1.*,
t2.shop_name,
t2.phone,
t3.account
from tb_shop_config t1
left join tb_shop_info t2 on t1.id = t2.id
left join sys_user t3 on t1.id = t3.id
where t1.main_id = #{shopId}
</select>
</mapper>