拼团商品

This commit is contained in:
2025-12-16 09:53:39 +08:00
parent 92d507dea3
commit e9551fe3b9
22 changed files with 462 additions and 97 deletions

View File

@@ -0,0 +1,62 @@
package com.czg.controller.admin;
import com.czg.annotation.SaAdminCheckPermission;
import com.czg.market.dto.GbWareDTO;
import com.czg.market.dto.GbWareQueryParamDTO;
import com.czg.market.entity.GbWare;
import com.czg.market.service.GbWareService;
import com.czg.resp.CzgResult;
import com.czg.sa.StpKit;
import com.czg.utils.AssertUtil;
import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 拼团商品
*
* @author ww
*/
@Slf4j
@RestController
@RequestMapping("/admin/ware")
public class GbWareController {
@Resource
private GbWareService wareService;
@GetMapping("/getGbWarePage")
@SaAdminCheckPermission(parentName = "拼团商品", value = "ware:info:list", name = "拼团商品-列表")
public CzgResult<Page<GbWare>> getGbWarePage(GbWareQueryParamDTO param) {
return CzgResult.success(wareService.getGbWarePage(param, StpKit.USER.getShopId()));
}
@PostMapping("/addGbWare")
@SaAdminCheckPermission(parentName = "拼团商品", value = "ware:info:add", name = "拼团商品-新增")
public CzgResult<Boolean> addGbWare(@RequestBody @Validated GbWareDTO param) {
return CzgResult.success(wareService.addGbWare(param));
}
@PostMapping("/editOnlineStatus")
@SaAdminCheckPermission(parentName = "拼团商品", value = "ware:info:up", name = "拼团商品-修改")
public CzgResult<Boolean> editGbWareOnlineStatus(@RequestBody GbWareDTO param) {
AssertUtil.isNull(param.getId(), "操作失败,请选择商品");
AssertUtil.isNull(param.getOnlineStatus(), "操作失败,请选择商品状态");
return CzgResult.success(wareService.editGbWareOnlineStatus(param.getId(), param.getOnlineStatus()));
}
@PostMapping("/updateGbWareById")
@SaAdminCheckPermission(parentName = "拼团商品", value = "ware:info:up", name = "拼团商品-修改")
public CzgResult<Boolean> updateGbWareById(@RequestBody @Validated GbWareDTO param) {
return CzgResult.success(wareService.updateGbWareById(param));
}
@DeleteMapping("/deleteGbWare/{id}")
@SaAdminCheckPermission(parentName = "拼团商品", value = "ware:info:del", name = "拼团商品-删除")
public CzgResult<Boolean> deleteGbWare(@PathVariable("id") Long id) {
AssertUtil.isNull(id, "操作失败,请选择商品");
return CzgResult.success(wareService.deleteGbWare(id));
}
}

View File

@@ -51,7 +51,7 @@ public class OTimeTask {
QueryWrapper cartUpdateWrapper = new QueryWrapper();
cartUpdateWrapper.lt(CashierCart::getCreateTime, DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd HH:mm:ss"))
.and(wrapper -> {
wrapper.isNull(CashierCart::getUpdateTime).or(CashierCart::getUpdateTime).lt(DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd HH:mm:ss"));
wrapper.isNull(CashierCart::getUpdateTime).or(CashierCart::getUpdateTime).lt(DateUtil.format(DateUtil.lastWeek(), "yyyy-MM-dd HH:mm:ss"));
});
cartService.remove(cartUpdateWrapper);
}

View File

@@ -0,0 +1,101 @@
package com.czg.market.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 拼团商品 实体类。
*
* @author ww
* @since 2025-12-15
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class GbWareDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 自增主键
*/
private Long id;
/**
* only-仅本店 all全部 /custom 指定
*/
@NotBlank(message = "可用门店不能为空")
private String useShopType;
/**
* 可用门店指定门店时存储门店ID逗号分隔
*/
private String useShops;
/**
* 商品名称
*/
@NotBlank(message = "商品名称不能为空")
private String wareName;
/**
* 商品描述
*/
private String wareDetail;
/**
* 商品图片(多个用逗号分隔)
*/
@NotBlank(message = "商品图片不能为空")
private String wareImgs;
/**
* 原价
*/
@NotNull(message = "原价不能为空")
private BigDecimal originalPrice;
/**
* 拼团价
*/
@NotNull(message = "拼团价不能为空")
private BigDecimal groupPrice;
/**
* 成团人数 最小为1
*/
@NotNull(message = "成团人数不能为空")
private Integer groupPeopleNum;
/**
* 成团期限小时不低于1小时最大72小时
*/
@NotNull(message = "成团期限不能为空")
private Integer groupTimeoutHour;
/**
* 限购数量(每人最多购买次数) -10086
*/
private Integer limitBuyNum;
/**
* 上架状态0下架 1上架
*/
private Integer onlineStatus;
/**
* 商品详情图片(多个用逗号分隔)
*/
private String wareCommentImgs;
}

View File

@@ -0,0 +1,30 @@
package com.czg.market.dto;
import com.czg.TimeQueryParam;
import com.czg.utils.CzgStrUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 拼团商品查询参数
* @author ww
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class GbWareQueryParamDTO extends TimeQueryParam {
/**
* 商品名称 模糊查询
*/
private String wareName;
/**
* 上架状态0下架 1上架
*/
private Boolean onlineStatus;
public String getWareName() {
return CzgStrUtils.getStrOrNull(wareName);
}
}

View File

@@ -0,0 +1,124 @@
package com.czg.market.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.math.BigDecimal;
import java.time.LocalDateTime;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 拼团商品 实体类。
*
* @author ww
* @since 2025-12-15
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table("gb_ware")
public class GbWare implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 自增主键
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 店铺ID
*/
private Long shopId;
/**
* only-仅本店 all全部 /custom 指定
*/
private String useShopType;
/**
* 可用门店指定门店时存储门店ID逗号分隔
*/
private String useShops;
/**
* 商品名称
*/
private String wareName;
/**
* 商品描述
*/
private String wareDetail;
/**
* 商品图片(多个用逗号分隔)
*/
private String wareImgs;
/**
* 原价
*/
private BigDecimal originalPrice;
/**
* 拼团价
*/
private BigDecimal groupPrice;
/**
* 成团人数 最小为1
*/
private Integer groupPeopleNum;
/**
* 成团期限小时不低于1小时最大72小时
*/
private Integer groupTimeoutHour;
/**
* 限购数量(每人最多购买次数) -10086
*/
private Integer limitBuyNum;
/**
* 上架状态0下架 1上架
*/
private Integer onlineStatus;
/**
* 商品详情图片(多个用逗号分隔)
*/
private String wareCommentImgs;
/**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
/**
* 更新时间
*/
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
/**
* 0否1是
*/
@Column(isLogicDelete = true)
private Boolean isDel;
}

View File

@@ -0,0 +1,30 @@
package com.czg.market.service;
import com.czg.market.dto.GbWareDTO;
import com.czg.market.dto.GbWareQueryParamDTO;
import com.czg.market.entity.GbWare;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
/**
* 拼团商品 服务层。
*
* @author ww
* @since 2025-12-15
*/
public interface GbWareService extends IService<GbWare> {
//拼团 活动 注意分店 主店的 问题
Page<GbWare> getGbWarePage(GbWareQueryParamDTO param, Long shopId);
//添加
boolean addGbWare(GbWareDTO param);
//修改 上架状态可修改
boolean editGbWareOnlineStatus(Long id, Integer onlineStatus);
//修改 下架状态可修改
boolean updateGbWareById(GbWareDTO param);
//删除 下架状态可删除
boolean deleteGbWare(Long id);
}

View File

@@ -0,0 +1,14 @@
package com.czg.service.market.mapper;
import com.mybatisflex.core.BaseMapper;
import com.czg.market.entity.GbWare;
/**
* 拼团商品 映射层。
*
* @author ww
* @since 2025-12-15
*/
public interface GbWareMapper extends BaseMapper<GbWare> {
}

View File

@@ -0,0 +1,93 @@
package com.czg.service.market.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.czg.account.service.ShopInfoService;
import com.czg.exception.CzgException;
import com.czg.market.dto.GbWareDTO;
import com.czg.market.dto.GbWareQueryParamDTO;
import com.czg.market.entity.GbWare;
import com.czg.market.service.GbWareService;
import com.czg.sa.StpKit;
import com.czg.service.market.mapper.GbWareMapper;
import com.czg.utils.AssertUtil;
import com.czg.utils.CzgStrUtils;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
/**
* 拼团商品 服务层实现。
*
* @author ww
* @since 2025-12-15
*/
@Service
public class GbWareServiceImpl extends ServiceImpl<GbWareMapper, GbWare> implements GbWareService {
@DubboReference
private ShopInfoService shopInfoService;
@Override
public Page<GbWare> getGbWarePage(GbWareQueryParamDTO param, Long shopId) {
Long mainShopId = shopInfoService.getMainIdByShopId(shopId);
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq(GbWare::getShopId, mainShopId)
.eq(GbWare::getIsDel, 0)
.eq(GbWare::getOnlineStatus, param.getOnlineStatus())
.like(GbWare::getWareName, CzgStrUtils.getStrOrNull(param.getWareName()))
.between(GbWare::getCreateTime, param.getStartTime(), param.getEndTime())
.orderBy(GbWare::getCreateTime).desc();
queryWrapper.and(q -> {
q.eq(GbWare::getUseShopType, "all").or(q1 -> {
q1.eq(GbWare::getUseShopType, "only").eq(GbWare::getShopId, shopId);
}).or(q2 -> {
q2.eq(GbWare::getUseShopType, "custom").and(q3 -> {
q3.eq(GbWare::getShopId, shopId).or("FIND_IN_SET( " + shopId + ", use_shops ) > 0");
});
});
});
return page(Page.of(param.getPage(), param.getSize()), queryWrapper);
}
@Override
public boolean addGbWare(GbWareDTO param) {
if ("custom".equals(param.getUseShopType())) {
AssertUtil.isBlank(param.getUseShops(), "请配置可用门店");
}
GbWare gbWare = BeanUtil.toBean(param, GbWare.class);
return save(gbWare);
}
@Override
public boolean editGbWareOnlineStatus(Long id, Integer onlineStatus) {
GbWare gbWare = new GbWare();
gbWare.setOnlineStatus(onlineStatus);
return update(gbWare, query().eq(GbWare::getId, id).eq(GbWare::getShopId, StpKit.USER.getShopId()));
}
@Override
public boolean updateGbWareById(GbWareDTO param) {
checkStatus(param.getId());
if ("custom".equals(param.getUseShopType())) {
AssertUtil.isBlank(param.getUseShops(), "请配置可用门店");
}
GbWare gbWare = BeanUtil.toBean(param, GbWare.class);
return updateById(gbWare);
}
@Override
public boolean deleteGbWare(Long id) {
checkStatus(id);
return remove(query().eq(GbWare::getId, id).eq(GbWare::getShopId, StpKit.USER.getShopId()));
}
private void checkStatus(Long id) {
GbWare ware = getById(id);
if (ware.getOnlineStatus() == 1) {
throw new CzgException("操作失败,请下架后,重试");
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czg.service.market.mapper.GbWareMapper">
</mapper>

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_cons_group` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_cons_info` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1,4 +0,0 @@
ALTER TABLE `tb_prod_cons_relation`
DROP COLUMN `id`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`shop_id`, `product_id`, `cons_info_id`) USING BTREE;

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_prod_group` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_prod_sku` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_product` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1,65 +0,0 @@
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`;

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_shop_prod_category` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_shop_prod_spec` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1 +0,0 @@
ALTER TABLE `tb_shop_prod_unit` ADD COLUMN `sync_id` bigint NULL COMMENT '同步ID' AFTER `id`;

View File

@@ -1,5 +0,0 @@
-- ----------------------------
-- tb_shop_user表扩展字段
-- ----------------------------
ALTER TABLE `tb_shop_user`
ADD COLUMN `merged_users` text NULL COMMENT '已经合并过来的用户信息jsonArray格式,[{\"id\":1,\"shopId\":2,...},{\"id\":1,\"shopId\":2,...}]';

View File

@@ -1,2 +0,0 @@
ALTER TABLE `tb_shop_vendor`
ADD COLUMN `sync_id` bigint NULL DEFAULT NULL COMMENT '同步Id' AFTER `id`;

View File

@@ -1,12 +0,0 @@
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;