思迅数据库配置问题和商品查询条件新增

This commit is contained in:
liyj 2025-06-28 11:26:54 +08:00
parent 2fc80bd8bf
commit 4297f0cb59
14 changed files with 146 additions and 42 deletions

View File

@ -172,7 +172,7 @@ public class ShopProductBase implements Serializable{
private BigDecimal shop_weight;
@ApiModelProperty("是否特价商品,0否1是")
private String is_special;
private String is_special="0";
@ApiModelProperty(value = "单价")
@TableField(updateStrategy=NOT_EMPTY)

View File

@ -210,4 +210,6 @@ public class ShopProductIndex implements Serializable {
@ApiModelProperty(value = "乐观锁")
private Integer version;
@ApiModelProperty("是否特价商品,0否1是")
private String is_special="0";
}

View File

@ -43,6 +43,10 @@ public class ProductMapping implements Serializable {
@NotNull(message="店铺编号不能为空")
private Integer storeId;
@TableField(value ="store_name",updateStrategy=NOT_EMPTY)
@ApiModelProperty(value = "店铺名称")
private String storeName;
@TableField(value ="spec_value",updateStrategy=NOT_EMPTY)
@ApiModelProperty("规格数据")
@NotNull(message="规格数据不能为空")

View File

@ -1,9 +1,6 @@
package com.suisung.mall.common.modules.sync;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ -11,6 +8,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
@ -27,74 +26,96 @@ public class StoreDbConfig implements Serializable {
@ApiModelProperty(value = "主键ID")
private Long id;
@TableField("store_id")
@TableField(value = "store_id",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "店铺ID")
@NotBlank(message = "店铺ID不能为空")
private String storeId;
@TableField("db_type")
@TableField(value = "store_name",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "店铺名称")
private String storeName;
@TableField(value = "db_type",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "数据库类型(mysql/oracle/sqlserver等)")
@NotBlank(message = "数据库类型不能为空")
private String dbType = "sqlserver";
@TableField("db_name")
@TableField(value = "db_name",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "数据库名称")
@NotBlank(message = "数据库名称不能为空")
private String dbName;
@TableField("db_ip")
@TableField(value = "db_ip",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "数据库IP地址")
@NotBlank(message = "数据库IP地址不能为空")
private String dbIp;
@TableField("db_port")
@TableField(value = "db_port",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "数据库端口")
@NotNull(message = "数据库端口不能为空")
private Integer dbPort = 3306;
@TableField("db_username")
@TableField(value = "db_username",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "数据库用户名")
@NotBlank(message = "数据库用户名不能为空")
private String dbUsername;
@TableField("db_password")
@TableField(value = "db_password",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "数据库密码(建议加密存储)")
@NotBlank(message = "数据库密码不能为空")
private String dbPassword;
@TableField("has_internet")
@TableField(value = "has_internet",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "是否有外网访问(0:无,1:有)")
@NotBlank(message = "是否有外网访问不能为空")
private String hasInternet;
@TableField("sync_mode")
@TableField(value = "sync_mode",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "同步模式(1:定时同步,2:间隔同步)")
@NotBlank(message = "同步模式不能为空")
private String syncMode;
@TableField("has_start")
@TableField(value = "has_start",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "是否启用(0:否,1:是)")
@NotBlank(message = "是否启用不能为空")
private String hasStart;
@TableField("cron_expression")
@TableField(value = "cron_expression",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "定时同步的cron表达式")
@NotBlank(message = "定时同步的cron表达式不能为空")
private String cronExpression;
@TableField("category_name")
@TableField(value = "category_name",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "商品分类")
private String categoryName;
@TableField("create_time")
@TableField(value = "create_time",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@TableField("update_time")
@TableField(value = "update_time",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@TableField("remark")
@TableField(value = "remark",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "备注信息")
private String remark;
@TableField("refresh_time")
@TableField(value = "refresh_time",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "刷新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date refreshTime;
@TableField("is_two_sync")
@TableField(value = "is_two_sync",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "是否双向同步(0:否,1:是)")
@NotBlank(message = "是否双向同步不能为空")
private String isTowSync="1";
@TableField(value = "is_negative_allowed",updateStrategy = FieldStrategy.NOT_EMPTY)
@ApiModelProperty(value = "是否允许负库存售卖(0:否,1:是),允许会自动把0以下(包括0)库存变为99")
@NotBlank(message = "是否允许负库存售卖不能为空")
private String isNegativeAllowed="1";
}

View File

@ -16,4 +16,14 @@ public class WebConfig implements WebMvcConfigurer {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 对所有路径应用CORS配置
.allowedOrigins("*") // 允许的源
.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的方法
.allowedHeaders("*") // 允许的头部
.allowCredentials(true) // 是否发送cookies等信息
.maxAge(3600); // 预检请求的有效期
}
}

View File

@ -2835,6 +2835,14 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
cond_row.ne("product_src_id", 0);
}
if (product_state_id != null) {
cond_row.eq("product_state_id", product_state_id);
}
String is_special = getParameter("is_special");
if (is_special != null) {
cond_row.eq("is_special", is_special);
}
boolean supplier_market_flag = ObjectUtil.equal(store_type, 2) && ObjectUtil.equal(product_fx_enable, 1);
if (!getCurrentUser().isPlatform()) {

View File

@ -1,5 +1,6 @@
package com.suisung.mall.shop.sync.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@ -8,10 +9,12 @@ import com.google.gson.reflect.TypeToken;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.api.IErrorCode;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.modules.store.ShopStoreBase;
import com.suisung.mall.common.modules.sync.ProductMapping;
import com.suisung.mall.common.pojo.res.ThirdApiRes;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.common.utils.ContextUtil;
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
import com.suisung.mall.shop.sync.exelModel.ImportResult;
import com.suisung.mall.shop.sync.service.ProductMappingService;
import com.suisung.mall.shop.sync.service.SyncThirdDataService;
@ -32,6 +35,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/admin/shop/shop-sync-productMapper")
@ -48,6 +52,9 @@ public class ProductMappingController extends BaseControllerImpl {
@Resource
private SyncThirdDataService syncThirdDataService;
@Autowired
private ShopStoreBaseService shopStoreBaseService;
/**
* 分页列表查询
* @param pageNum
@ -89,6 +96,12 @@ public class ProductMappingController extends BaseControllerImpl {
if(result.hasErrors()) {
return CommonResult.failed(Objects.requireNonNull(result.getFieldError()).getDefaultMessage());
}
Integer storeId=productMapping.getStoreId();
ShopStoreBase shopStoreBase= shopStoreBaseService.get(storeId);
if(shopStoreBase==null){
return CommonResult.failed("新增失败:店铺不存在");
}
productMapping.setStoreName(shopStoreBase.getStore_name());
return productMappingService.saveProductMapping(productMapping);
}
@ -105,8 +118,18 @@ public class ProductMappingController extends BaseControllerImpl {
}
Gson gson = new Gson();
List<ProductMapping> productMappings= gson.fromJson(jsonProductMappings.toString(),new TypeToken<List<ProductMapping>>(){}.getType());
productMappingService.saveBatch(productMappings,productMappings.size());
return CommonResult.success(true);
if(CollectionUtil.isNotEmpty(productMappings)){
Integer storeId=productMappings.get(0).getStoreId();
ShopStoreBase shopStoreBase= shopStoreBaseService.get(storeId);
if(shopStoreBase==null){
return CommonResult.failed("店铺不存在");
}
List<ProductMapping> productMappingList= productMappings.stream().peek(productMapping -> productMapping.setStoreName(shopStoreBase.getStore_name())).collect(Collectors.toList());
productMappingService.saveBatch(productMappingList,productMappingList.size());
return CommonResult.success(true);
}
return CommonResult.failed("数据不能为空");
}
/**
@ -121,6 +144,12 @@ public class ProductMappingController extends BaseControllerImpl {
return CommonResult.failed("缺少必要参数");
}
if(ObjectUtil.isNotEmpty(productMappingService.getById(productMapping.getId()))) {
Integer storeId=productMapping.getStoreId();
ShopStoreBase shopStoreBase= shopStoreBaseService.get(storeId);
if(shopStoreBase==null){
return CommonResult.failed("更新失败:店铺不存在");
}
productMapping.setStoreName(shopStoreBase.getStore_name());
if(productMappingService.saveOrUpdate(productMapping)){
return CommonResult.success(true);
}

View File

@ -21,6 +21,8 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* <p>
* 页面导航表 前端控制器
@ -73,7 +75,7 @@ public class StoreDbConfigController extends BaseControllerImpl {
*/
@ApiOperation(value = "新增-店铺数据库连接配置", notes = "新增-店铺数据库连接配置")
@RequestMapping(value = "/saveStoreDbConfig", method = RequestMethod.POST)
public CommonResult saveStoreDbConfig(@RequestBody StoreDbConfig storeDbConfig) {
public CommonResult saveStoreDbConfig(@RequestBody @Valid StoreDbConfig storeDbConfig) {
return storeDbConfigService.addStoreDbConfig(storeDbConfig);
}
@ -84,7 +86,7 @@ public class StoreDbConfigController extends BaseControllerImpl {
*/
@ApiOperation(value = "更新-店铺数据库连接配置", notes = "更新-店铺数据库连接配置")
@RequestMapping(value = "/udpateStoreDbConfig", method = RequestMethod.PUT)
public CommonResult udpateStoreDbConfig(@RequestBody StoreDbConfig storeDbConfig) {
public CommonResult udpateStoreDbConfig(@RequestBody @Valid StoreDbConfig storeDbConfig) {
return storeDbConfigService.updateStoreDbConfig(storeDbConfig);
}

View File

@ -14,16 +14,19 @@ public class ProductMappingExcel {
@ExcelProperty(value = "店铺编号", index = 1)
private Integer storeId;
@ExcelProperty(value = "规格数据", index = 2)
@ExcelProperty(value = "店铺名称", index = 2)
private String storeName;
@ExcelProperty(value = "规格数据", index = 3)
private BigDecimal specValue;
@ExcelProperty(value = "规格单位", index = 3)
@ExcelProperty(value = "规格单位", index = 4)
private String specUnit;
@ExcelProperty(value = "商品描述", index = 4)
@ExcelProperty(value = "商品描述", index = 5)
private String description;
@ExcelProperty(value = "排序值", index = 5)
@ExcelProperty(value = "排序值", index = 6)
private Integer sortOrder;
// 转换为实体对象
@ -31,6 +34,7 @@ public class ProductMappingExcel {
ProductMapping entity = new ProductMapping();
entity.setProductName(this.productName);
entity.setStoreId(this.storeId);
entity.setStoreName(this.storeName);
entity.setSpecValue(this.specValue);
entity.setSpecUnit(this.specUnit);
entity.setDescription(this.description);
@ -43,6 +47,7 @@ public class ProductMappingExcel {
ProductMappingExcel excel = new ProductMappingExcel();
excel.setProductName(entity.getProductName());
excel.setStoreId(entity.getStoreId());
excel.setStoreName(entity.getStoreName());
excel.setSpecValue(entity.getSpecValue());
excel.setSpecUnit(entity.getSpecUnit());
excel.setDescription(entity.getDescription());

View File

@ -94,15 +94,16 @@ public class StoreDbConfigServiceImpl extends BaseServiceImpl<StoreDbConfigMappe
if(null!=storeDbConfig.getId()){
queryWrapper.eq("id", storeDbConfig.getId());
}
queryWrapper.eq("has_start",DicEnum.YESORNO_1.getCode());
//queryWrapper.eq("has_start",DicEnum.YESORNO_1.getCode());
if(null!=this.getOne(queryWrapper)){
return CommonResult.failed("店铺已存在有效配置,不能重复添加");
return CommonResult.failed("店铺已存在配置,不能重复添加");
}
ShopStoreBase shopStoreBase=shopStoreBaseService.get(Convert.toInt(storeId));
if(shopStoreBase==null){
return CommonResult.failed("店铺数据库连接配置新增失败:失败原因是店铺不存在");
}
storeDbConfig.setStoreId(storeId);
storeDbConfig.setStoreName(shopStoreBase.getStore_name());
if(!this.save(storeDbConfig)){
return CommonResult.failed("店铺数据库连接配置新增失败");
}
@ -124,6 +125,7 @@ public class StoreDbConfigServiceImpl extends BaseServiceImpl<StoreDbConfigMappe
return CommonResult.failed("店铺数据库连接配置新增失败:失败原因是店铺不存在");
}
storeDbConfig.setStoreId(storeId);
storeDbConfig.setStoreName(shopStoreBase.getStore_name());
if(!this.updateById(storeDbConfig)){
return CommonResult.failed("店铺数据库连接配置更新失败");
}

View File

@ -553,7 +553,7 @@ public abstract class SyncBaseThirdSxAbstract{
* @param storeId
* @return
*/
public int baseSaveOrUpdateGoodsBatch(JSONArray goodsListJSON,String storeId){
public int baseSaveOrUpdateGoodsBatch(JSONArray goodsListJSON,String storeId,String isNegativeAllowed){
AtomicInteger resultCount = new AtomicInteger();
Map categoryMap= productCategoryService.getCategoryListByStoreId(storeId);//热数据加载
List<ShopProductBase> shopProductBaseList=new ArrayList<>();
@ -600,16 +600,27 @@ public abstract class SyncBaseThirdSxAbstract{
shopProductBase.setProduct_from(1005);// 商品来源(ENUM):1000-发布;1001-天猫;1002-淘宝;1003-阿里巴巴;1004-京东;1005-思迅;
shopProductBase.setProduct_add_time(currentDate.getTime());
shopProductBase.setProduct_unit_price(BigDecimal.valueOf(jsonObj.getDouble("retail_price")));
shopProductBase.setIs_special(jsonObj.getStr("isSpecial"));//是否特价商品
String isSpecial=jsonObj.getStr("isSpecial");
if(ObjectUtil.equals(isSpecial,DicEnum.YESORNO_0.getCode())||ObjectUtil.equals(isSpecial,DicEnum.YESORNO_1.getCode())){
shopProductBase.setIs_special(isSpecial);//是否特价商品 特价商品需要手动上架 todo 是否要开发定时上架功能
}else {
if(productName.contains("特价")){
shopProductBase.setIs_special(DicEnum.YESORNO_1.getCode());//是否特价商品 特价商品需要手动上架 todo 是否要开发定时上架功能
}
}
BigDecimal stock= jsonObj.getBigDecimal("stock");//库存
if(ObjectUtil.equals(isNegativeAllowed,DicEnum.YESORNO_1)&&stock.compareTo(BigDecimal.ZERO)<=0){//允许负库存每次都加满就是一直有售卖
stock=new BigDecimal("99");
}
//商品总量
if(ObjectUtil.isNotEmpty(jsonObj.getStr("unit"))&&ObjectUtil.isNotEmpty(jsonObj.getStr("stock"))
&& "KG,kg,公斤".contains(jsonObj.getStr("unit"))){
shopProductBase.setShop_weight(jsonObj.getBigDecimal("stock"));
shopProductBase.setShop_weight(stock);
shopProductBase.setUnit_name(jsonObj.getStr("unit"));
shopProductBase.setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF_UNCHECK);
shopProductBase.setUnit_price(BigDecimal.valueOf(jsonObj.getDouble("retail_price")));
}else {
shopProductBase.setShop_weight(jsonObj.getBigDecimal("stock"));
shopProductBase.setShop_weight(stock);
shopProductBase.setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF);//默认是下架
shopProductBase.setUnit_price(BigDecimal.valueOf(jsonObj.getDouble("retail_price")));
}
@ -637,7 +648,7 @@ public abstract class SyncBaseThirdSxAbstract{
shopProductIndex.setVoucher_activity_id("");
shopProductIndex.setCoupon_type_id(0);// product_assist_data // 辅助属性值列(DOT)
shopProductIndex.setProduct_transport_id(String.valueOf(StateCode.DELIVERY_TYPE_SAME_CITY));
shopProductIndex.setIs_special(shopProductBase.getIs_special());
if(categoryId!=0){
Integer typeId = (Integer) categoryMap.get(categoryId.toString());
if (ObjectUtil.isNotEmpty(typeId)) {

View File

@ -522,7 +522,6 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
//upLoadZipToOss(newFolders.get(0));//上传文件到cos
dowloadAndUnZip(newFolders.get(0));//读取cos文件回本地
syncPrimaryKey();
shopNumberSeqService.clearKey();
shopBaseProductCategoryService.clearCategoryCache(storeId);
@ -534,8 +533,12 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
List<String> failFolders = new ArrayList<>();
List<String> failMessage = new ArrayList<>();
shopBaseProductCategoryService.getCategoryListByStoreId(storeId);
QueryWrapper<StoreDbConfig> storeDbConfigQueryWrapper = new QueryWrapper<>();
storeDbConfigQueryWrapper.eq("store_id", storeId);
StoreDbConfig storeDbConfig = storeDbConfigService.getOne(storeDbConfigQueryWrapper);
for (int i = 0; i < newFolders.size(); i++) {
final int taskId = i;
final String isNegativeAllowed=storeDbConfig.getIsNegativeAllowed();
threadNum.incrementAndGet();
futures.add(executor.submit(() -> {
int count = 0;//失败重试机制当失败重试一次再次失败则记录到数据库中
@ -545,7 +548,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
String fileName = "good_" + (taskId + 1) + ".txt";
JSONArray jsonArray = new ThreadFileUtils().processFolder(taskName, newFolders.get(taskId));
try {
baseSaveOrUpdateGoodsBatch(jsonArray, storeId);
baseSaveOrUpdateGoodsBatch(jsonArray, storeId,isNegativeAllowed);
success.getAndIncrement();
threadNum.decrementAndGet();
return "成功" + taskId;
@ -601,9 +604,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
logger.info("同步商品数据执行结束");
//更新当前的获取时间用户客户端获取
try {
QueryWrapper<StoreDbConfig> storeDbConfigQueryWrapper = new QueryWrapper<>();
storeDbConfigQueryWrapper.eq("store_id", storeId);
StoreDbConfig storeDbConfig = storeDbConfigService.getOne(storeDbConfigQueryWrapper);
if (ObjectUtil.isNotEmpty(storeDbConfig)) {
storeDbConfig.setRefreshTime(date);
storeDbConfigService.saveOrUpdate(storeDbConfig);

View File

@ -0,0 +1,2 @@
alter table shop_product_index add column `is_special` varchar(2) NOT NULL DEFAULT '0' COMMENT '是否特价商品,0否1是';
alter table shop_product_index add index `is_special` (`is_special`) USING BTREE;

View File

@ -0,0 +1,7 @@
alter table store_db_config add is_negative_allowed char(1) NOT NULL DEFAULT 1 COMMENT '是否允许负库存售卖(0:否,1:是),允许会自动把0以下(包括0)库存变为99';
alter table store_db_config add store_name varchar(64) NOT NULL COMMENT '店铺名称';
alter table product_mapping add store_name varchar(64) NOT NULL COMMENT '店铺名称';
alter table product_mapping add index `is_store_name` (`store_name`) USING BTREE;