90 changed files with 2113 additions and 229 deletions
@ -0,0 +1,14 @@ |
|||||
|
package cc.hiver.core.common.constant; |
||||
|
|
||||
|
/** |
||||
|
* 订单常量类 |
||||
|
* @author 王富康 |
||||
|
* @date 2023/10/21 |
||||
|
*/ |
||||
|
public interface ProductConstant { |
||||
|
/** |
||||
|
商品状态:0:下架;1:上架:2删除 |
||||
|
*/ |
||||
|
String[] DEL_FLAG = {"0", "1", "2"}; |
||||
|
|
||||
|
} |
||||
@ -1,26 +1,67 @@ |
|||||
package cc.hiver.mall.checkstock.controller; |
package cc.hiver.mall.checkstock.controller; |
||||
|
|
||||
|
import cc.hiver.core.common.utils.ResultUtil; |
||||
import cc.hiver.core.common.vo.Result; |
import cc.hiver.core.common.vo.Result; |
||||
import cc.hiver.mall.checkstock.service.CheckStockDetailService; |
import cc.hiver.mall.checkstock.service.CheckStockDetailService; |
||||
import cc.hiver.mall.checkstock.vo.CheckStockVo; |
import cc.hiver.mall.checkstock.vo.CheckStockDetailVo; |
||||
import io.swagger.annotations.Api; |
import io.swagger.annotations.Api; |
||||
|
import io.swagger.annotations.ApiOperation; |
||||
import lombok.extern.slf4j.Slf4j; |
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.transaction.annotation.Transactional; |
import org.springframework.transaction.annotation.Transactional; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||
import org.springframework.web.bind.annotation.RestController; |
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 盘点商品明细 |
||||
|
* @author 王富康 |
||||
|
* @date 2024/3/22 |
||||
|
*/ |
||||
@Slf4j |
@Slf4j |
||||
@RestController |
@RestController |
||||
@Api(tags = "盘点商品明细接口") |
@Api(tags = "盘点商品明细接口") |
||||
@RequestMapping("/hiver/app/checkStock/") |
@RequestMapping("/hiver/app/checkStockDetail/") |
||||
@Transactional |
@Transactional |
||||
public class CheckStockDetailController { |
public class CheckStockDetailController { |
||||
|
|
||||
@Autowired |
@Autowired |
||||
private CheckStockDetailService checkStockDetailService; |
private CheckStockDetailService checkStockDetailService; |
||||
|
|
||||
public Result addCheckStockDetail(CheckStockVo checkStockVo){ |
/** |
||||
return null; |
* 增加盘点明细 |
||||
|
* |
||||
|
* @param checkStockDetailVos 商品明细 |
||||
|
* @return Result |
||||
|
* @author 王富康 |
||||
|
* @date 2024/3/17 |
||||
|
*/ |
||||
|
@RequestMapping(value = "/addCheckStockDetail", method = RequestMethod.POST) |
||||
|
@ApiOperation("盘点-新增商品详细信息") |
||||
|
public Result addCheckStockDetail(@RequestBody List<CheckStockDetailVo> checkStockDetailVos) { |
||||
|
checkStockDetailService.addCheckStockDetail(checkStockDetailVos); |
||||
|
return ResultUtil.success("新增商品信息成功!"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除盘点明细 |
||||
|
* |
||||
|
* @param id 盘点id |
||||
|
* @return Result |
||||
|
* @author 王富康 |
||||
|
* @date 2024/3/17 |
||||
|
*/ |
||||
|
@RequestMapping(value = "/deleteCheckStockDetail", method = RequestMethod.POST) |
||||
|
@ApiOperation("盘点-删除商品详细信息") |
||||
|
public Result deleteCheckStockDetail(String id) { |
||||
|
if (StringUtils.isEmpty(id)) { |
||||
|
ResultUtil.error("盘点明细id不能为空!"); |
||||
|
} |
||||
|
checkStockDetailService.deleteCheckStockDetail(id); |
||||
|
return ResultUtil.success("删除成功!"); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,9 +1,13 @@ |
|||||
package cc.hiver.mall.checkstock.mapper; |
package cc.hiver.mall.checkstock.mapper; |
||||
|
|
||||
import cc.hiver.mall.checkstock.entity.CheckStock; |
import cc.hiver.mall.checkstock.entity.CheckStock; |
||||
|
import cc.hiver.mall.checkstock.pojo.CheckStockPageQuery; |
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
import org.springframework.stereotype.Repository; |
import org.springframework.stereotype.Repository; |
||||
|
|
||||
@Repository |
@Repository |
||||
public interface CheckStockMapper extends BaseMapper<CheckStock> { |
public interface CheckStockMapper extends BaseMapper<CheckStock> { |
||||
|
Page<CheckStock> getCheckStockList(Page<CheckStock> page,@Param("deductLogPageQuery") CheckStockPageQuery checkStockPageQuery); |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,30 @@ |
|||||
|
package cc.hiver.mall.checkstock.pojo; |
||||
|
|
||||
|
import cc.hiver.core.base.HiverBasePageQuery; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
public class CheckStockPageQuery extends HiverBasePageQuery { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@ApiModelProperty(value = "店铺id") |
||||
|
private String shopId; |
||||
|
|
||||
|
@ApiModelProperty(value = "盘点id") |
||||
|
private String checkStockId; |
||||
|
|
||||
|
@ApiModelProperty(value = "开始时间") |
||||
|
private String startDate; |
||||
|
|
||||
|
@ApiModelProperty(value = "结束时间") |
||||
|
private String endDate; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品id") |
||||
|
private List<String> productIdList; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -1,7 +1,20 @@ |
|||||
package cc.hiver.mall.checkstock.service; |
package cc.hiver.mall.checkstock.service; |
||||
|
|
||||
import cc.hiver.mall.checkstock.entity.CheckStockDetail; |
import cc.hiver.mall.checkstock.entity.CheckStockDetail; |
||||
|
import cc.hiver.mall.checkstock.pojo.CheckStockPageQuery; |
||||
|
import cc.hiver.mall.checkstock.vo.CheckStockDetailVo; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
import com.baomidou.mybatisplus.extension.service.IService; |
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
public interface CheckStockDetailService extends IService<CheckStockDetail> { |
public interface CheckStockDetailService extends IService<CheckStockDetail> { |
||||
|
|
||||
|
void addCheckStockDetail(List<CheckStockDetailVo> checkStockDetailVos); |
||||
|
|
||||
|
void deleteCheckStockDetail(String id); |
||||
|
|
||||
|
List<CheckStockDetailVo> getByCheckStockDetailByCheckId(String checkStockId); |
||||
|
|
||||
|
Page<CheckStockDetailVo> getByCheckStockDetailByCheckIdOfPage(CheckStockPageQuery checkStockPageQuery); |
||||
} |
} |
||||
|
|||||
@ -1,11 +1,20 @@ |
|||||
package cc.hiver.mall.checkstock.service; |
package cc.hiver.mall.checkstock.service; |
||||
|
|
||||
import cc.hiver.mall.checkstock.entity.CheckStock; |
import cc.hiver.mall.checkstock.entity.CheckStock; |
||||
import cc.hiver.mall.checkstock.vo.CheckStockDetailVo; |
import cc.hiver.mall.checkstock.pojo.CheckStockPageQuery; |
||||
|
import cc.hiver.mall.checkstock.vo.CheckStockPageVo; |
||||
|
import cc.hiver.mall.checkstock.vo.CheckStockVo; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
import com.baomidou.mybatisplus.extension.service.IService; |
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
public interface CheckStockService extends IService<CheckStock> { |
public interface CheckStockService extends IService<CheckStock> { |
||||
void addCheckStock(List<CheckStockDetailVo> checkStockDetailVos); |
CheckStock addCheckStock(CheckStockVo checkStockVo); |
||||
|
|
||||
|
CheckStockPageVo getCheckStock(CheckStockPageQuery checkStockPageQuery); |
||||
|
|
||||
|
void submitToStock(String id); |
||||
|
|
||||
|
Page<CheckStock> getCheckStockList( CheckStockPageQuery checkStockPageQuery); |
||||
|
|
||||
|
void deleteCheckStock(String id); |
||||
} |
} |
||||
|
|||||
@ -1,11 +1,214 @@ |
|||||
package cc.hiver.mall.checkstock.service.impl; |
package cc.hiver.mall.checkstock.service.impl; |
||||
|
|
||||
|
import cc.hiver.core.common.utils.SecurityUtil; |
||||
import cc.hiver.mall.checkstock.entity.CheckStockDetail; |
import cc.hiver.mall.checkstock.entity.CheckStockDetail; |
||||
import cc.hiver.mall.checkstock.mapper.CheckStockDetailMapper; |
import cc.hiver.mall.checkstock.mapper.CheckStockDetailMapper; |
||||
|
import cc.hiver.mall.checkstock.pojo.CheckStockPageQuery; |
||||
import cc.hiver.mall.checkstock.service.CheckStockDetailService; |
import cc.hiver.mall.checkstock.service.CheckStockDetailService; |
||||
|
import cc.hiver.mall.checkstock.vo.CheckStockAttributeVo; |
||||
|
import cc.hiver.mall.checkstock.vo.CheckStockDetailVo; |
||||
|
import cc.hiver.mall.deductlog.vo.WorkerDeductLogVo; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* 盘点商品实现类 |
||||
|
* |
||||
|
* @author 王富康 |
||||
|
* @date 2024/3/22 |
||||
|
*/ |
||||
@Service |
@Service |
||||
public class CheckStockDetailServiceImpl extends ServiceImpl<CheckStockDetailMapper, CheckStockDetail> implements CheckStockDetailService { |
public class CheckStockDetailServiceImpl extends ServiceImpl<CheckStockDetailMapper, CheckStockDetail> implements CheckStockDetailService { |
||||
|
|
||||
|
@Autowired |
||||
|
private SecurityUtil securityUtil; |
||||
|
|
||||
|
@Autowired |
||||
|
private CheckStockDetailMapper checkStockDetailMapper; |
||||
|
|
||||
|
/** |
||||
|
* 添加盘点详情信息 |
||||
|
* |
||||
|
* @param checkStockDetailVos 盘点详情视图对象列表,包含需要添加的盘点细节 |
||||
|
*/ |
||||
|
@Override |
||||
|
public void addCheckStockDetail(List<CheckStockDetailVo> checkStockDetailVos) { |
||||
|
if (checkStockDetailVos == null || checkStockDetailVos.isEmpty()) { |
||||
|
return; // 处理边界条件,输入参数为空的情况
|
||||
|
} |
||||
|
|
||||
|
// 获取当前店铺ID
|
||||
|
final String shopId = securityUtil.getShopId(); |
||||
|
|
||||
|
// 初始化盘点详情列表
|
||||
|
final List<CheckStockDetail> checkStockDetailList = new ArrayList<>(); |
||||
|
for (CheckStockDetailVo checkStockDetailVo : checkStockDetailVos) { |
||||
|
// 获取商品ID和盘点ID
|
||||
|
final String productId = checkStockDetailVo.getProductId(); |
||||
|
final String checkStockId = checkStockDetailVo.getCheckStockId(); |
||||
|
try { |
||||
|
// 先根据商品ID删除原有的盘点明细
|
||||
|
checkStockDetailMapper.deleteByProductId(shopId, checkStockId, productId); |
||||
|
|
||||
|
// 遍历并新增盘点的商品明细
|
||||
|
final List<CheckStockAttributeVo> checkStockAttributeVos = checkStockDetailVo.getCheckStockAttributeVos(); |
||||
|
for (CheckStockAttributeVo checkStockAttributeVo : checkStockAttributeVos) { |
||||
|
checkStockDetailList.addAll(buildCheckStockDetailList(checkStockDetailVo, checkStockAttributeVo, shopId, checkStockId, productId)); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
// 日志记录异常,可以进行相应的异常处理逻辑
|
||||
|
log.error("添加盘点详情信息失败", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 批量插入盘点详情信息
|
||||
|
try { |
||||
|
checkStockDetailMapper.batchInsertCheckStock(checkStockDetailList); |
||||
|
} catch (Exception e) { |
||||
|
// 日志记录异常,可以进行相应的异常处理逻辑
|
||||
|
log.error("批量插入盘点详情信息失败", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建盘点详情信息列表 |
||||
|
*/ |
||||
|
private static List<CheckStockDetail> buildCheckStockDetailList(CheckStockDetailVo checkStockDetailVo, |
||||
|
CheckStockAttributeVo checkStockAttributeVo, |
||||
|
String shopId, |
||||
|
String checkStockId, |
||||
|
String productId) { |
||||
|
final List<CheckStockDetail> details = new ArrayList<>(); |
||||
|
final String attributeList = checkStockAttributeVo.getAttributeList(); |
||||
|
final Integer pdNum = checkStockAttributeVo.getPdNum(); |
||||
|
final Integer stockCount = checkStockAttributeVo.getStockCount(); |
||||
|
|
||||
|
// 可为负数
|
||||
|
final int changeCount = pdNum - stockCount; |
||||
|
|
||||
|
final CheckStockDetail checkStockDetail = new CheckStockDetail(); |
||||
|
checkStockDetail.setCheckStockId(checkStockId); |
||||
|
checkStockDetail.setShopId(shopId); |
||||
|
checkStockDetail.setProductId(productId); |
||||
|
checkStockDetail.setProductName(checkStockDetailVo.getProductName()); |
||||
|
checkStockDetail.setProductSn(checkStockDetailVo.getProductSn()); |
||||
|
checkStockDetail.setProductPicture(checkStockDetailVo.getProductPicture()); |
||||
|
checkStockDetail.setPdNum(pdNum); |
||||
|
checkStockDetail.setChangeCount(changeCount); |
||||
|
checkStockDetail.setStockCount(stockCount); |
||||
|
checkStockDetail.setAttributeList(attributeList); |
||||
|
|
||||
|
details.add(checkStockDetail); |
||||
|
return details; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public void deleteCheckStockDetail(String id) { |
||||
|
// 删除明细
|
||||
|
checkStockDetailMapper.deleteById(id); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<CheckStockDetailVo> getByCheckStockDetailByCheckId(String checkStockId) { |
||||
|
|
||||
|
// 查询明细
|
||||
|
final List<CheckStockDetail> checkStockDetailList = checkStockDetailMapper.getByCheckStockDetailByCheckId(checkStockId); |
||||
|
|
||||
|
// 封装至返回结果中
|
||||
|
final Map<String, CheckStockDetailVo> checkStockDetailVoMap = new HashMap<>(); |
||||
|
for (CheckStockDetail checkStockDetail : checkStockDetailList) { |
||||
|
final String productId = checkStockDetail.getProductId(); |
||||
|
if (checkStockDetailVoMap.containsKey(productId)) { |
||||
|
// 直接放规格即可
|
||||
|
final CheckStockAttributeVo checkStockAttributeVo = new CheckStockAttributeVo(); |
||||
|
checkStockAttributeVo.setAttributeList(checkStockDetail.getAttributeList()); |
||||
|
checkStockAttributeVo.setStockCount(checkStockDetail.getStockCount()); |
||||
|
checkStockAttributeVo.setPdNum(checkStockDetail.getPdNum()); |
||||
|
checkStockDetailVoMap.get(productId).getCheckStockAttributeVos().add(checkStockAttributeVo); |
||||
|
} else { |
||||
|
// 新增对象
|
||||
|
final CheckStockDetailVo checkStockDetailVo = new CheckStockDetailVo(); |
||||
|
checkStockDetailVo.setCheckStockId(checkStockDetail.getCheckStockId()); |
||||
|
checkStockDetailVo.setProductId(productId); |
||||
|
checkStockDetailVo.setProductName(checkStockDetail.getProductName()); |
||||
|
checkStockDetailVo.setProductPicture(checkStockDetail.getProductPicture()); |
||||
|
checkStockDetailVo.setProductSn(checkStockDetail.getProductSn()); |
||||
|
final List<CheckStockAttributeVo> checkStockAttributeVos = new ArrayList<>(); |
||||
|
final CheckStockAttributeVo checkStockAttributeVo = new CheckStockAttributeVo(); |
||||
|
checkStockAttributeVo.setAttributeList(checkStockDetail.getAttributeList()); |
||||
|
checkStockAttributeVo.setStockCount(checkStockDetail.getStockCount()); |
||||
|
checkStockAttributeVo.setPdNum(checkStockDetail.getPdNum()); |
||||
|
checkStockAttributeVos.add(checkStockAttributeVo); |
||||
|
checkStockDetailVo.setCheckStockAttributeVos(checkStockAttributeVos); |
||||
|
checkStockDetailVoMap.put(productId, checkStockDetailVo); |
||||
|
} |
||||
|
} |
||||
|
return new ArrayList<>(checkStockDetailVoMap.values()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Page<CheckStockDetailVo> getByCheckStockDetailByCheckIdOfPage(CheckStockPageQuery checkStockPageQuery) { |
||||
|
// 校验分页参数
|
||||
|
if (checkStockPageQuery.getPageNum() <= 0 || checkStockPageQuery.getPageSize() <= 0) { |
||||
|
throw new IllegalArgumentException("分页参数异常!"); |
||||
|
} |
||||
|
|
||||
|
final Page<WorkerDeductLogVo> page = new Page<>(checkStockPageQuery.getPageNum(), checkStockPageQuery.getPageSize()); |
||||
|
final Page<CheckStockDetailVo> returnData = new Page<>(); |
||||
|
try { |
||||
|
// 查询商品id集合
|
||||
|
// 查询明细,这里假设底层已经做了SQL注入等安全防护
|
||||
|
final Page<String> checkStockDetailListOfProduct = checkStockDetailMapper.getByCheckStockProductByCheckId(page, checkStockPageQuery); |
||||
|
if (checkStockDetailListOfProduct.getRecords() == null) { |
||||
|
// 避免空指针异常
|
||||
|
checkStockDetailListOfProduct.setRecords(new ArrayList<>()); |
||||
|
} |
||||
|
checkStockPageQuery.setProductIdList(checkStockDetailListOfProduct.getRecords()); |
||||
|
|
||||
|
|
||||
|
if (!checkStockPageQuery.getProductIdList().isEmpty()) { |
||||
|
final List<CheckStockDetail> checkStockDetailList = checkStockDetailMapper.getByCheckStockDetailByCheckIdOfPage(checkStockPageQuery); |
||||
|
|
||||
|
// 封装至返回结果中,使用Map和computeIfAbsent简化逻辑
|
||||
|
final Map<String, CheckStockDetailVo> checkStockDetailVoMap = checkStockDetailList.stream() |
||||
|
.collect(Collectors.toMap(CheckStockDetail::getProductId, detail -> { |
||||
|
final CheckStockDetailVo vo = new CheckStockDetailVo(); |
||||
|
vo.setCheckStockId(detail.getCheckStockId()); |
||||
|
vo.setProductId(detail.getProductId()); |
||||
|
vo.setProductName(detail.getProductName()); |
||||
|
vo.setProductPicture(detail.getProductPicture()); |
||||
|
vo.setProductSn(detail.getProductSn()); |
||||
|
vo.setCheckStockAttributeVos(new ArrayList<>()); |
||||
|
final CheckStockAttributeVo attributeVo = new CheckStockAttributeVo(); |
||||
|
attributeVo.setAttributeList(detail.getAttributeList()); |
||||
|
attributeVo.setStockCount(detail.getStockCount()); |
||||
|
attributeVo.setPdNum(detail.getPdNum()); |
||||
|
vo.getCheckStockAttributeVos().add(attributeVo); |
||||
|
return vo; |
||||
|
}, (vo1, vo2) -> { |
||||
|
vo2.getCheckStockAttributeVos().addAll(vo1.getCheckStockAttributeVos()); |
||||
|
return vo2; |
||||
|
})); |
||||
|
returnData.setCountId(checkStockDetailListOfProduct.getCountId()); |
||||
|
returnData.setCurrent(checkStockDetailListOfProduct.getCurrent()); |
||||
|
returnData.setTotal(checkStockDetailListOfProduct.getTotal()); |
||||
|
returnData.setRecords(new ArrayList<>(checkStockDetailVoMap.values())); |
||||
|
|
||||
|
} |
||||
|
return returnData; |
||||
|
} catch (Exception e) { |
||||
|
// 异常处理,建议加上更详细的日志记录
|
||||
|
throw new RuntimeException("获取盘点信息出错!", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,11 +1,17 @@ |
|||||
package cc.hiver.mall.checkstock.vo; |
package cc.hiver.mall.checkstock.vo; |
||||
|
|
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
import lombok.Data; |
import lombok.Data; |
||||
|
|
||||
@Data |
@Data |
||||
public class CheckStockAttributeVo { |
public class CheckStockAttributeVo { |
||||
|
|
||||
|
@ApiModelProperty(value = "规格") |
||||
private String attributeList; |
private String attributeList; |
||||
|
|
||||
|
@ApiModelProperty(value = "盘点的数量") |
||||
private Integer pdNum; |
private Integer pdNum; |
||||
|
|
||||
|
@ApiModelProperty(value = "盘点前库存数量") |
||||
private Integer stockCount; |
private Integer stockCount; |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,27 @@ |
|||||
|
package cc.hiver.mall.checkstock.vo; |
||||
|
|
||||
|
import cc.hiver.core.base.HiverBaseEntity; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
public class CheckStockPageVo extends HiverBaseEntity { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@ApiModelProperty(value = "盘点人姓名") |
||||
|
private String createByName; |
||||
|
|
||||
|
@ApiModelProperty(value = "店铺id") |
||||
|
private String shopId; |
||||
|
|
||||
|
@ApiModelProperty(value = "店铺名称") |
||||
|
private String shopName; |
||||
|
|
||||
|
@ApiModelProperty(value = "备注") |
||||
|
private String remark; |
||||
|
|
||||
|
private Page<CheckStockDetailVo> checkStockDetailVoList; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
package cc.hiver.mall.common.constant; |
||||
|
|
||||
|
/** |
||||
|
* 店铺常量 |
||||
|
* |
||||
|
* @author cc |
||||
|
*/ |
||||
|
public interface PurchaseConstant { |
||||
|
|
||||
|
/** |
||||
|
* 入库状态:0:待入库(未维护对应的采购价信息);1:已入库;2:ocr入库(未识别)3:ocr入库(已识别); |
||||
|
*/ |
||||
|
int[] IN_STORAGE_STATUS = {0, 1, 2, 3}; |
||||
|
|
||||
|
/** |
||||
|
* ocr识别状态 0:(未识别)1:(已识别); |
||||
|
*/ |
||||
|
int[] OCR_STATUS = {0, 1}; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
package cc.hiver.mall.config.aliocr; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
|
||||
|
@Data |
||||
|
@Configuration |
||||
|
@ConfigurationProperties(prefix = "aliyun.openapi") |
||||
|
public class AliOcrConfig { |
||||
|
private String apiKey; |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
package cc.hiver.mall.config.thread; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Data |
||||
|
@Component |
||||
|
public class ThreadConfig { |
||||
|
|
||||
|
@Value("${spring.task.execution.pool.core-size}") |
||||
|
private int corePoolSize; |
||||
|
|
||||
|
@Value("${spring.task.execution.pool.max-size}") |
||||
|
private int maxPoolSize; |
||||
|
|
||||
|
@Value("${spring.task.execution.pool.queue-capacity}") |
||||
|
private int queueCapacity; |
||||
|
|
||||
|
@Value("${spring.task.execution.pool.keep-alive}") |
||||
|
private int keepAliveSeconds; |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
package cc.hiver.mall.config.thread; |
||||
|
|
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.concurrent.ThreadPoolExecutor; |
||||
|
|
||||
|
/** |
||||
|
* 线程池bean |
||||
|
* |
||||
|
* @author 王富康 |
||||
|
* @date 2023/3/24 10:03 |
||||
|
**/ |
||||
|
@Configuration |
||||
|
@Component |
||||
|
public class ThreadPoolConfiguration { |
||||
|
|
||||
|
/** |
||||
|
* 核心线程池大小-32 |
||||
|
**/ |
||||
|
private int corePoolSize = 10; |
||||
|
/** |
||||
|
* 最大可创建的线程数-50 |
||||
|
**/ |
||||
|
private int maxPoolSize = 50; |
||||
|
/** |
||||
|
* 线程池维护线程所允许的空闲时间-60 |
||||
|
**/ |
||||
|
private int keepAliveTime = 60; |
||||
|
/** |
||||
|
* 队列最大长度-100 |
||||
|
**/ |
||||
|
private int queueCapacity = 100; |
||||
|
|
||||
|
@Bean(name = "threadPoolTaskExecutor") |
||||
|
public ThreadPoolTaskExecutor threadPoolTaskExecutor() { |
||||
|
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); |
||||
|
executor.setMaxPoolSize(maxPoolSize); |
||||
|
executor.setCorePoolSize(corePoolSize); |
||||
|
executor.setQueueCapacity(queueCapacity); |
||||
|
executor.setKeepAliveSeconds(keepAliveTime); |
||||
|
//配置线程池中的线程的名称前缀
|
||||
|
executor.setThreadNamePrefix("ocr-"); |
||||
|
// 线程池对拒绝任务(无线程可用)的处理策略
|
||||
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); |
||||
|
executor.initialize(); |
||||
|
return executor; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
package cc.hiver.mall.config.thread; |
||||
|
|
||||
|
import cc.hiver.core.common.utils.ResultUtil; |
||||
|
import cc.hiver.core.common.vo.Result; |
||||
|
import cc.hiver.mall.common.constant.PurchaseConstant; |
||||
|
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture; |
||||
|
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; |
||||
|
import cc.hiver.mall.utils.AliOcrUtil; |
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import com.alibaba.dashscope.exception.NoApiKeyException; |
||||
|
import com.alibaba.dashscope.exception.UploadFileException; |
||||
|
import lombok.Data; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.Callable; |
||||
|
|
||||
|
/** |
||||
|
* 请详细描述方法 |
||||
|
* @author 王富康 |
||||
|
* @date 2024/3/24 |
||||
|
*/ |
||||
|
@Data |
||||
|
@Slf4j |
||||
|
public class TimerThread implements Callable { |
||||
|
|
||||
|
private PurchaseOcrPictureService purchaseOcrPictureService; |
||||
|
private List<PurchaseOcrPicture> purchaseOcrPictureAddList; |
||||
|
|
||||
|
public TimerThread() { |
||||
|
} |
||||
|
|
||||
|
public TimerThread(List<PurchaseOcrPicture> purchaseOcrPictureAddList,PurchaseOcrPictureService purchaseOcrPictureService) { |
||||
|
this.purchaseOcrPictureAddList = purchaseOcrPictureAddList; |
||||
|
this.purchaseOcrPictureService = purchaseOcrPictureService; |
||||
|
} |
||||
|
/** |
||||
|
* 每个线程拿到数据后如何去处理 |
||||
|
* |
||||
|
* @return |
||||
|
*/ |
||||
|
public Result call() { |
||||
|
try { |
||||
|
log.info("当前线程名称:------------>>>>>"+Thread.currentThread().getName()); |
||||
|
for (PurchaseOcrPicture purchaseOcrPicture : purchaseOcrPictureAddList) { |
||||
|
try { |
||||
|
log.info("正在ocr识别:" + purchaseOcrPicture.getOcrPicture() + "<br/>线程池名称:"+Thread.currentThread().getName()); |
||||
|
final JSONObject jsonObject = AliOcrUtil.simpleMultiModalConversationCall(purchaseOcrPicture.getOcrPicture()); |
||||
|
// 得到处理结果之后,开始新增库存的详细信息
|
||||
|
log.info("识别结果:" + jsonObject); |
||||
|
purchaseOcrPicture.setOcrMsg(jsonObject.get("msg").toString()); |
||||
|
purchaseOcrPicture.setOcrStatus(PurchaseConstant.OCR_STATUS[1]); |
||||
|
} catch (NoApiKeyException e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} catch (UploadFileException e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
purchaseOcrPictureService.batchUpdate(purchaseOcrPictureAddList); |
||||
|
} catch (Exception e) { |
||||
|
log.error("timerThread出错,线程------>" + Thread.currentThread().getName(), e); |
||||
|
} |
||||
|
return ResultUtil.success(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
package cc.hiver.mall.pojo.vo; |
||||
|
|
||||
|
import cc.hiver.core.base.HiverBaseEntity; |
||||
|
import io.swagger.annotations.ApiModel; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
@ApiModel(value = "商品规格属性") |
||||
|
public class ProductAttributeOfAddVo extends HiverBaseEntity { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品类别ID") |
||||
|
private String categoryId; |
||||
|
|
||||
|
@ApiModelProperty(value = "属性名称") |
||||
|
private String attributeName; |
||||
|
|
||||
|
private List<ProductAttributeValueVo> productAttributeValueVoList; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
package cc.hiver.mall.pojo.vo; |
||||
|
|
||||
|
import cc.hiver.core.base.HiverBaseEntity; |
||||
|
import io.swagger.annotations.ApiModel; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
@ApiModel(value = "商品属性值表") |
||||
|
public class ProductAttributeValueVo extends HiverBaseEntity { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品属性ID") |
||||
|
private String attributeId; |
||||
|
|
||||
|
@ApiModelProperty(value = "属性值") |
||||
|
private String value; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
package cc.hiver.mall.pojo.vo; |
||||
|
|
||||
|
import io.swagger.annotations.ApiModel; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
@ApiModel(value = "类别Vo") |
||||
|
public class ProductCategoryVo implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品类别名称") |
||||
|
private String categoryName; |
||||
|
|
||||
|
@ApiModelProperty(value = "店铺id") |
||||
|
private String shopId; |
||||
|
|
||||
|
@ApiModelProperty(value = "分类列表") |
||||
|
private List<ProductAttributeOfAddVo> productAttributeOfAddVos; |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
package cc.hiver.mall.pojo.vo; |
||||
|
|
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
public class StockAttributeVo { |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品规格") |
||||
|
private String attributeList; |
||||
|
|
||||
|
@ApiModelProperty(value = "库存数") |
||||
|
private Integer stockCount; |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
package cc.hiver.mall.pojo.vo; |
||||
|
|
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
public class StockProductVo { |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品名称") |
||||
|
private String productName; |
||||
|
|
||||
|
@ApiModelProperty(value = "货号") |
||||
|
private String productSn; |
||||
|
|
||||
|
@ApiModelProperty(value = "货品图片") |
||||
|
private String productPicture; |
||||
|
|
||||
|
@ApiModelProperty(value = "条码") |
||||
|
private String barcode; |
||||
|
|
||||
|
@ApiModelProperty(value = "尾货预警") |
||||
|
private Integer tailWarn; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品总库存(某一规格库存为负数的按0计算总数)") |
||||
|
private Integer stockCount; |
||||
|
|
||||
|
@ApiModelProperty(value = "商品规格") |
||||
|
private List<StockAttributeVo> stockAttributeVoList; |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
package cc.hiver.mall.purchaseocr.controller; |
||||
|
|
||||
|
import cc.hiver.core.common.utils.ResultUtil; |
||||
|
import cc.hiver.core.common.vo.Result; |
||||
|
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; |
||||
|
import cc.hiver.mall.purchaseocr.vo.PurchaseOciPictureAddVo; |
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; |
||||
|
import com.alibaba.dashscope.exception.InputRequiredException; |
||||
|
import com.alibaba.dashscope.exception.NoApiKeyException; |
||||
|
import com.alibaba.dashscope.exception.UploadFileException; |
||||
|
import io.swagger.annotations.Api; |
||||
|
import io.swagger.annotations.ApiOperation; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Slf4j |
||||
|
@RestController |
||||
|
@Api(tags = "问题反馈接口") |
||||
|
@RequestMapping("/hiver/purchaseOcrPicture/") |
||||
|
@Transactional |
||||
|
public class PurchaseOcrPictureController { |
||||
|
|
||||
|
@Autowired |
||||
|
private PurchaseOcrPictureService purchaseOcrPictureService; |
||||
|
|
||||
|
@RequestMapping(value = "/batchSave", method = RequestMethod.POST) |
||||
|
@ApiOperation("新增或编辑OCR识别信息") |
||||
|
public Result batchSave(@RequestBody PurchaseOciPictureAddVo purchaseOciPictureAddVo) { |
||||
|
JSONObject jsonObject = purchaseOcrPictureService.batchSave(purchaseOciPictureAddVo); |
||||
|
return new ResultUtil<JSONObject>().setData(jsonObject); |
||||
|
} |
||||
|
|
||||
|
@RequestMapping(value = "/invoicingAi", method = RequestMethod.POST) |
||||
|
@ApiOperation("AI开单") |
||||
|
public Result invoicingAi(String questionMsg) throws NoApiKeyException, InputRequiredException { |
||||
|
JSONObject jsonObject = purchaseOcrPictureService.invoicingAi(questionMsg); |
||||
|
return new ResultUtil<JSONObject>().setData(jsonObject); |
||||
|
} |
||||
|
|
||||
|
@RequestMapping(value = "/multiRoundConversationCall", method = RequestMethod.POST) |
||||
|
@ApiOperation("图片识别-多轮对话") |
||||
|
public List<MultiModalConversationResult> multiRoundConversationCall(String picturePath, String firstQuestionMsg, String secondQuestionMsg) throws NoApiKeyException, InputRequiredException, UploadFileException { |
||||
|
List<MultiModalConversationResult> multiModalConversationResults = purchaseOcrPictureService.multiRoundConversationCall(picturePath,firstQuestionMsg, secondQuestionMsg); |
||||
|
return multiModalConversationResults; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
package cc.hiver.mall.purchaseocr.entity; |
||||
|
|
||||
|
import cc.hiver.core.base.HiverBaseEntity; |
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
import io.swagger.annotations.ApiModel; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* ai图片表 |
||||
|
* @author 王富康 |
||||
|
* @date 2024/3/23 |
||||
|
*/ |
||||
|
@Data |
||||
|
@ApiModel(value = "ai图片表") |
||||
|
@TableName(value = "t_purchase_ocr_picture", autoResultMap = true) |
||||
|
public class PurchaseOcrPicture extends HiverBaseEntity { |
||||
|
|
||||
|
@ApiModelProperty(value = "创建人名称") |
||||
|
private String createByName; |
||||
|
|
||||
|
@ApiModelProperty(value = "采购单id") |
||||
|
private String orderId; |
||||
|
|
||||
|
@ApiModelProperty(value = "图片路径") |
||||
|
private String ocrPicture; |
||||
|
|
||||
|
@ApiModelProperty(value = "图片顺序") |
||||
|
private String ocrPictureOrder; |
||||
|
|
||||
|
@ApiModelProperty(value = "识别标识:0:未识别;1:识别成功;2:识别失败") |
||||
|
private Integer ocrStatus; |
||||
|
|
||||
|
@ApiModelProperty(value = "识别结果") |
||||
|
private String ocrMsg; |
||||
|
|
||||
|
@ApiModelProperty(value = "店铺ID") |
||||
|
private String shopId; |
||||
|
|
||||
|
@ApiModelProperty(value = "店铺名称") |
||||
|
private String shopName; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
package cc.hiver.mall.purchaseocr.mapper; |
||||
|
|
||||
|
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture; |
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface PurchaseOcrPictureMapper extends BaseMapper<PurchaseOcrPicture> { |
||||
|
void batchSave(@Param("purchaseOcrPictureList") List<PurchaseOcrPicture> purchaseOcrPictureList); |
||||
|
|
||||
|
void batchUpdate(@Param("purchaseOcrPictureList") List<PurchaseOcrPicture> purchaseOcrPictureAddList); |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
package cc.hiver.mall.purchaseocr.service; |
||||
|
|
||||
|
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture; |
||||
|
import cc.hiver.mall.purchaseocr.vo.PurchaseOciPictureAddVo; |
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; |
||||
|
import com.alibaba.dashscope.exception.InputRequiredException; |
||||
|
import com.alibaba.dashscope.exception.NoApiKeyException; |
||||
|
import com.alibaba.dashscope.exception.UploadFileException; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface PurchaseOcrPictureService { |
||||
|
JSONObject batchSave(PurchaseOciPictureAddVo purchaseOciPictureAddVo); |
||||
|
void batchUpdate(List<PurchaseOcrPicture> purchaseOcrPictureList); |
||||
|
|
||||
|
JSONObject invoicingAi(String questionMsg) throws NoApiKeyException, InputRequiredException; |
||||
|
|
||||
|
List<MultiModalConversationResult> multiRoundConversationCall(String picturePath,String firstQuestionMsg, String secondQuestionMsg) throws NoApiKeyException, InputRequiredException, UploadFileException; |
||||
|
} |
||||
@ -0,0 +1,111 @@ |
|||||
|
package cc.hiver.mall.purchaseocr.service.impl; |
||||
|
|
||||
|
import cc.hiver.core.common.utils.SecurityUtil; |
||||
|
import cc.hiver.core.common.vo.Result; |
||||
|
import cc.hiver.mall.common.constant.PurchaseConstant; |
||||
|
import cc.hiver.mall.config.thread.TimerThread; |
||||
|
import cc.hiver.mall.entity.Purchase; |
||||
|
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture; |
||||
|
import cc.hiver.mall.purchaseocr.mapper.PurchaseOcrPictureMapper; |
||||
|
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; |
||||
|
import cc.hiver.mall.purchaseocr.vo.PurchaseOciPictureAddVo; |
||||
|
import cc.hiver.mall.service.mybatis.PurchaseService; |
||||
|
import cc.hiver.mall.utils.AliOcrUtil; |
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; |
||||
|
import com.alibaba.dashscope.exception.InputRequiredException; |
||||
|
import com.alibaba.dashscope.exception.NoApiKeyException; |
||||
|
import com.alibaba.dashscope.exception.UploadFileException; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.CompletionService; |
||||
|
import java.util.concurrent.CopyOnWriteArrayList; |
||||
|
import java.util.concurrent.ExecutorCompletionService; |
||||
|
import java.util.concurrent.Future; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService { |
||||
|
|
||||
|
@Autowired |
||||
|
private PurchaseOcrPictureMapper purchaseOcrPictureMapper; |
||||
|
|
||||
|
@Autowired |
||||
|
private SecurityUtil securityUtil; |
||||
|
|
||||
|
@Autowired |
||||
|
private PurchaseService purchaseService; |
||||
|
|
||||
|
@Autowired |
||||
|
private PurchaseOcrPictureService purchaseOcrPictureService; |
||||
|
|
||||
|
@Autowired |
||||
|
ThreadPoolTaskExecutor threadPoolTaskExecutor; |
||||
|
|
||||
|
@Override |
||||
|
public JSONObject batchSave(PurchaseOciPictureAddVo purchaseOciPictureAddVo) { |
||||
|
final JSONObject jsonObject = new JSONObject(); |
||||
|
// shopId从缓存中设置
|
||||
|
final String shopId = "wfkde"; |
||||
|
// 如果采购单位空,那么就需要新增采购单信息
|
||||
|
if (StringUtils.isEmpty(purchaseOciPictureAddVo.getOrderId())) { |
||||
|
final Purchase purchase = new Purchase(); |
||||
|
// 新增的对象会有id,将新增的id放到参数中取
|
||||
|
purchaseOciPictureAddVo.setOrderId(purchase.getId()); |
||||
|
purchase.setShopId(shopId); |
||||
|
// 设置为ocr识别(未识别)状态
|
||||
|
purchase.setInStorageStatus(PurchaseConstant.IN_STORAGE_STATUS[2]); |
||||
|
final boolean save = purchaseService.save(purchase); |
||||
|
} |
||||
|
// 然后批量新增图片
|
||||
|
final List<PurchaseOcrPicture> purchaseOcrPictureList = purchaseOciPictureAddVo.getPurchaseOcrPictureList(); |
||||
|
final CopyOnWriteArrayList<PurchaseOcrPicture> purchaseOcrPictureAddList = new CopyOnWriteArrayList<>(); |
||||
|
|
||||
|
for (PurchaseOcrPicture purchaseOcrPicture : purchaseOcrPictureList) { |
||||
|
// todo 如果前台传了id,后台会覆盖么
|
||||
|
final String id = purchaseOcrPicture.getId(); |
||||
|
final PurchaseOcrPicture oldPurchaseOcrPicture = purchaseOcrPictureMapper.selectById(id); |
||||
|
if(oldPurchaseOcrPicture ==null ){ |
||||
|
final PurchaseOcrPicture addPurchaseOcrPicture = new PurchaseOcrPicture(); |
||||
|
// 如果是修改新增的图片,需要增加图片信息
|
||||
|
addPurchaseOcrPicture.setShopId(shopId); |
||||
|
addPurchaseOcrPicture.setOcrPicture(purchaseOcrPicture.getOcrPicture()); |
||||
|
addPurchaseOcrPicture.setOrderId(purchaseOciPictureAddVo.getOrderId()); |
||||
|
addPurchaseOcrPicture.setOcrStatus(PurchaseConstant.OCR_STATUS[0]); |
||||
|
purchaseOcrPictureAddList.add(addPurchaseOcrPicture); |
||||
|
} |
||||
|
} |
||||
|
purchaseOcrPictureMapper.batchSave(purchaseOcrPictureAddList); |
||||
|
// 异步处理ocr识别
|
||||
|
try { |
||||
|
CompletionService<CopyOnWriteArrayList<PurchaseOcrPicture>> service = new ExecutorCompletionService<>(threadPoolTaskExecutor); |
||||
|
TimerThread timerThread = new TimerThread(purchaseOcrPictureAddList,purchaseOcrPictureService); |
||||
|
// 这里可以使用线程池,也可以使用CompletionService处理,运行任务需要是callable的,需要最终结果。
|
||||
|
final Future<Result> submit = service.submit(timerThread); |
||||
|
} catch (Exception e) { |
||||
|
log.error("异步处理ocr识别失败", e); |
||||
|
} |
||||
|
jsonObject.set("msg", "success"); |
||||
|
return jsonObject; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void batchUpdate(List<PurchaseOcrPicture> purchaseOcrPictureList) { |
||||
|
purchaseOcrPictureMapper.batchUpdate(purchaseOcrPictureList); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public JSONObject invoicingAi(String questionMsg) throws NoApiKeyException, InputRequiredException { |
||||
|
return AliOcrUtil.callWithMessage(questionMsg); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<MultiModalConversationResult> multiRoundConversationCall(String picturePath,String firstQuestionMsg, String secondQuestionMsg) throws NoApiKeyException, InputRequiredException, UploadFileException { |
||||
|
return AliOcrUtil.multiRoundConversationCall(picturePath,firstQuestionMsg,secondQuestionMsg); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
package cc.hiver.mall.purchaseocr.vo; |
||||
|
|
||||
|
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
public class PurchaseOciPictureAddVo { |
||||
|
|
||||
|
@ApiModelProperty(value = "采购单id") |
||||
|
private String orderId; |
||||
|
|
||||
|
@ApiModelProperty(value = "Oci图片信息") |
||||
|
private List<PurchaseOcrPicture> purchaseOcrPictureList; |
||||
|
} |
||||
@ -1,7 +1,9 @@ |
|||||
package cc.hiver.mall.service.mybatis; |
package cc.hiver.mall.service.mybatis; |
||||
|
|
||||
import cc.hiver.mall.entity.ProductCategory; |
import cc.hiver.mall.entity.ProductCategory; |
||||
|
import cc.hiver.mall.pojo.vo.ProductCategoryVo; |
||||
import com.baomidou.mybatisplus.extension.service.IService; |
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
|
||||
public interface ProductCategoryService extends IService<ProductCategory> { |
public interface ProductCategoryService extends IService<ProductCategory> { |
||||
|
boolean batchSaveCategoryAndAttribute(ProductCategoryVo productCategoryVo); |
||||
} |
} |
||||
|
|||||
@ -1,11 +1,84 @@ |
|||||
package cc.hiver.mall.serviceimpl.mybatis; |
package cc.hiver.mall.serviceimpl.mybatis; |
||||
|
|
||||
|
import cc.hiver.core.common.utils.SecurityUtil; |
||||
import cc.hiver.mall.dao.mapper.ProductCategoryMapper; |
import cc.hiver.mall.dao.mapper.ProductCategoryMapper; |
||||
|
import cc.hiver.mall.entity.ProductAttribute; |
||||
|
import cc.hiver.mall.entity.ProductAttributeValue; |
||||
import cc.hiver.mall.entity.ProductCategory; |
import cc.hiver.mall.entity.ProductCategory; |
||||
|
import cc.hiver.mall.pojo.vo.ProductAttributeOfAddVo; |
||||
|
import cc.hiver.mall.pojo.vo.ProductAttributeValueVo; |
||||
|
import cc.hiver.mall.pojo.vo.ProductCategoryVo; |
||||
|
import cc.hiver.mall.service.mybatis.ProductAttributeService; |
||||
|
import cc.hiver.mall.service.mybatis.ProductAttributeValueService; |
||||
import cc.hiver.mall.service.mybatis.ProductCategoryService; |
import cc.hiver.mall.service.mybatis.ProductCategoryService; |
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Slf4j |
||||
@Service |
@Service |
||||
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements ProductCategoryService { |
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements ProductCategoryService { |
||||
|
|
||||
|
@Autowired |
||||
|
private SecurityUtil securityUtil; |
||||
|
|
||||
|
@Autowired |
||||
|
private ProductCategoryMapper productCategoryMapper; |
||||
|
|
||||
|
@Autowired |
||||
|
private ProductAttributeService productAttributeService; |
||||
|
|
||||
|
@Autowired |
||||
|
private ProductAttributeValueService productAttributeValueService; |
||||
|
|
||||
|
@Transactional(rollbackFor = Exception.class) |
||||
|
@Override |
||||
|
public boolean batchSaveCategoryAndAttribute(ProductCategoryVo productCategoryVo) { |
||||
|
|
||||
|
try { |
||||
|
// 新增类别信息
|
||||
|
final ProductCategory productCategory = new ProductCategory(); |
||||
|
final String shopId = securityUtil.getShopId(); |
||||
|
productCategory.setShopId(shopId); |
||||
|
productCategory.setCategoryName(productCategoryVo.getCategoryName()); |
||||
|
productCategoryMapper.insert(productCategory); |
||||
|
|
||||
|
// 新增类别
|
||||
|
final List<ProductAttributeOfAddVo> productAttributeOfAddVos = productCategoryVo.getProductAttributeOfAddVos(); |
||||
|
// 需要新增的类别集合
|
||||
|
final List<ProductAttribute> productAttributes = new ArrayList<>(); |
||||
|
// 需要新增的属性值集合
|
||||
|
final List<ProductAttributeValue> productAttributeValues = new ArrayList<>(); |
||||
|
for (ProductAttributeOfAddVo productAttributeOfAddVo : productAttributeOfAddVos) { |
||||
|
final ProductAttribute productAttribute = new ProductAttribute(); |
||||
|
productAttribute.setCategoryId(productCategory.getId()); |
||||
|
productAttribute.setAttributeName(productAttributeOfAddVo.getAttributeName()); |
||||
|
productAttributes.add(productAttribute); |
||||
|
final List<ProductAttributeValueVo> productAttributeValueVoList = productAttributeOfAddVo.getProductAttributeValueVoList(); |
||||
|
for (ProductAttributeValueVo productAttributeValueVo : productAttributeValueVoList) { |
||||
|
final ProductAttributeValue productAttributeValue = new ProductAttributeValue(); |
||||
|
productAttributeValue.setAttributeId(productAttribute.getId()); |
||||
|
productAttributeValue.setValue(productAttributeValueVo.getValue()); |
||||
|
productAttributeValues.add(productAttributeValue); |
||||
|
} |
||||
|
} |
||||
|
// 批量插入分类
|
||||
|
if (!productAttributes.isEmpty()) { |
||||
|
productAttributeService.saveBatch(productAttributes, productAttributes.size()); |
||||
|
} |
||||
|
//批量插入属性值
|
||||
|
if (!productAttributeValues.isEmpty()) { |
||||
|
productAttributeValueService.saveBatch(productAttributeValues, productAttributeValues.size()); |
||||
|
} |
||||
|
return true; |
||||
|
} catch (Exception e) { |
||||
|
log.error(e.getMessage(), e); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,208 @@ |
|||||
|
package cc.hiver.mall.utils;// Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
|
|
||||
|
import cc.hiver.mall.config.aliocr.AliOcrConfig; |
||||
|
import cn.hutool.core.date.StopWatch; |
||||
|
import cn.hutool.json.JSONObject; |
||||
|
import com.alibaba.dashscope.aigc.generation.Generation; |
||||
|
import com.alibaba.dashscope.aigc.generation.GenerationParam; |
||||
|
import com.alibaba.dashscope.aigc.generation.GenerationResult; |
||||
|
import com.alibaba.dashscope.aigc.generation.models.QwenParam; |
||||
|
import com.alibaba.dashscope.aigc.multimodalconversation.*; |
||||
|
import com.alibaba.dashscope.common.Message; |
||||
|
import com.alibaba.dashscope.common.MessageManager; |
||||
|
import com.alibaba.dashscope.common.MultiModalMessage; |
||||
|
import com.alibaba.dashscope.common.Role; |
||||
|
import com.alibaba.dashscope.exception.ApiException; |
||||
|
import com.alibaba.dashscope.exception.InputRequiredException; |
||||
|
import com.alibaba.dashscope.exception.NoApiKeyException; |
||||
|
import com.alibaba.dashscope.exception.UploadFileException; |
||||
|
import com.alibaba.dashscope.utils.Constants; |
||||
|
import com.alibaba.dashscope.utils.JsonUtils; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Component |
||||
|
public class AliOcrUtil { |
||||
|
|
||||
|
@Autowired |
||||
|
private static AliOcrConfig aliOcrConfig; |
||||
|
|
||||
|
/** |
||||
|
* 图片识别 |
||||
|
* @author 王富康 |
||||
|
* @date 2024/3/24 |
||||
|
* @param picturePath |
||||
|
* @return JSONObject |
||||
|
*/ |
||||
|
public static JSONObject simpleMultiModalConversationCall(String picturePath) |
||||
|
throws ApiException, NoApiKeyException, UploadFileException { |
||||
|
final JSONObject jsonObject = new JSONObject(); |
||||
|
final StopWatch stopWatch = new StopWatch("Ai回答计时"); |
||||
|
Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; |
||||
|
final MultiModalConversation conv = new MultiModalConversation(); |
||||
|
final MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue()) |
||||
|
.content(Arrays.asList(Collections.singletonMap("image", picturePath), |
||||
|
Collections.singletonMap("text", "这是一个入库小票,请帮我把图片中所有内容封装为json,必须一次性列出所有json数据,json格式为:{ \"productSn\": \"货号\", \"productName\": \"商品名称\",\"price\": \"单价\", \"productCount\": \"数量\", \"attributeList\": \"{\"颜色\":\"红色\",\"尺码\":\"均码\"}\" }"))).build(); |
||||
|
stopWatch.start("开始回答:"); |
||||
|
final MultiModalConversationParam param = MultiModalConversationParam.builder() |
||||
|
.model("qwen-vl-max") |
||||
|
.message(userMessage) |
||||
|
.temperature(1F) |
||||
|
.topP(0.1) |
||||
|
.topK(1) |
||||
|
.seed(500) |
||||
|
.build(); |
||||
|
final MultiModalConversationResult result = conv.call(param); |
||||
|
stopWatch.stop(); |
||||
|
log.info(String.valueOf(result)); |
||||
|
log.info(stopWatch.prettyPrint()); |
||||
|
final Map<String, Object> stringObjectMap = result.getOutput().getChoices().get(0).getMessage().getContent().get(0); |
||||
|
jsonObject.set("msg", stringObjectMap); |
||||
|
return jsonObject; |
||||
|
} |
||||
|
|
||||
|
public static List<MultiModalConversationResult> multiRoundConversationCall(String picturePath,String firstQuestionMsg,String secondQuestionMsg) throws ApiException, NoApiKeyException, UploadFileException { |
||||
|
final StopWatch stopWatch = new StopWatch("Ai回答计时"); |
||||
|
Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; |
||||
|
List<MultiModalConversationResult> multiModalConversationResults = new ArrayList<>(); |
||||
|
final MultiModalConversation conv = new MultiModalConversation(); |
||||
|
final MultiModalMessageItemText systemText = new MultiModalMessageItemText("You are a helpful assistant."); |
||||
|
final MultiModalConversationMessage systemMessage = MultiModalConversationMessage.builder() |
||||
|
.role(Role.SYSTEM.getValue()).content(Collections.singletonList(systemText)).build(); |
||||
|
final MultiModalMessageItemImage userImage = new MultiModalMessageItemImage(picturePath); |
||||
|
// "这是一个入库小票,请帮我把图片中所有内容封装为json,必须一次性列出所有json数据,json格式为:{ \"productSn\": \"货号\", \"productName\": \"商品名称\",\"price\": \"单价\", \"productCount\": \"数量\", \"attributeList\": \"{\"颜色\":\"红色\",\"尺码\":\"均码\"}\" }"
|
||||
|
MultiModalMessageItemText userText = new MultiModalMessageItemText(firstQuestionMsg); |
||||
|
final MultiModalConversationMessage userMessage = |
||||
|
MultiModalConversationMessage.builder().role(Role.USER.getValue()) |
||||
|
.content(Arrays.asList(userImage, userText)).build(); |
||||
|
final List<MultiModalConversationMessage> messages = new ArrayList<>(); |
||||
|
messages.add(systemMessage); |
||||
|
messages.add(userMessage); |
||||
|
final MultiModalConversationParam param = MultiModalConversationParam.builder() |
||||
|
.model("qwen-vl-max") |
||||
|
.messages(messages) |
||||
|
.temperature(1F) |
||||
|
.topP(0.1) |
||||
|
.topK(1) |
||||
|
.seed(500) |
||||
|
.build(); |
||||
|
stopWatch.start("一轮会话"); |
||||
|
MultiModalConversationResult result = conv.call(param); |
||||
|
stopWatch.stop(); |
||||
|
multiModalConversationResults.add(result); |
||||
|
System.out.println(result); |
||||
|
// 我会在这里对结果进行解析,然后,判断要不要走第二次回话
|
||||
|
if(StringUtils.isNotEmpty(secondQuestionMsg)){ |
||||
|
|
||||
|
final MultiModalMessageItemText assistentText = new MultiModalMessageItemText( |
||||
|
result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString()); |
||||
|
final MultiModalConversationMessage assistentMessage = MultiModalConversationMessage.builder() |
||||
|
.role(Role.ASSISTANT.getValue()).content(Collections.singletonList(assistentText)).build(); |
||||
|
messages.add(assistentMessage); |
||||
|
userText = new MultiModalMessageItemText(secondQuestionMsg); |
||||
|
messages.add(MultiModalConversationMessage.builder().role(Role.USER.getValue()) |
||||
|
.content(Collections.singletonList(userText)).build()); |
||||
|
param.setMessages(new ArrayList<Object>(messages)); |
||||
|
stopWatch.start("二轮会话"); |
||||
|
result = conv.call(param); |
||||
|
multiModalConversationResults.add(result); |
||||
|
stopWatch.stop(); |
||||
|
System.out.print(result); |
||||
|
log.info(stopWatch.prettyPrint()); |
||||
|
} |
||||
|
return multiModalConversationResults; |
||||
|
} |
||||
|
|
||||
|
public static JSONObject callWithMessage(String questionMsg) |
||||
|
throws NoApiKeyException, ApiException, InputRequiredException { |
||||
|
final JSONObject jsonObject = new JSONObject(); |
||||
|
Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; |
||||
|
final StopWatch stopWatch = new StopWatch("Ai回答计时"); |
||||
|
final Generation gen = new Generation(); |
||||
|
final MessageManager msgManager = new MessageManager(10); |
||||
|
final Message systemMsg = |
||||
|
Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build(); |
||||
|
final Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build(); |
||||
|
msgManager.add(systemMsg); |
||||
|
msgManager.add(userMsg); |
||||
|
stopWatch.start("开始回答"); |
||||
|
final QwenParam param = |
||||
|
QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get()) |
||||
|
.resultFormat(QwenParam.ResultFormat.MESSAGE) |
||||
|
.temperature(1F) |
||||
|
.topP(0.1) |
||||
|
.topK(1) |
||||
|
.seed(500) |
||||
|
.build(); |
||||
|
final GenerationResult result = gen.call(param); |
||||
|
stopWatch.stop(); |
||||
|
log.info(stopWatch.prettyPrint()); |
||||
|
System.out.println(result); |
||||
|
jsonObject.set("msg", result.getOutput().getChoices().get(0).getMessage().getContent()); |
||||
|
return jsonObject; |
||||
|
} |
||||
|
|
||||
|
public static void callWithMessageOfMany(String questionMsg,int count) |
||||
|
throws NoApiKeyException, ApiException, InputRequiredException { |
||||
|
final Generation gen = new Generation(); |
||||
|
Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; |
||||
|
final Message systemMsg = |
||||
|
Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build(); |
||||
|
Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build(); |
||||
|
final List<Message> messages = new ArrayList<>(); |
||||
|
messages.add(systemMsg); |
||||
|
messages.add(userMsg); |
||||
|
final GenerationParam param = |
||||
|
GenerationParam.builder().model(Generation.Models.QWEN_PLUS).messages(messages) |
||||
|
.resultFormat(GenerationParam.ResultFormat.MESSAGE) |
||||
|
.topP(0.8) |
||||
|
.build(); |
||||
|
GenerationResult result = gen.call(param); |
||||
|
System.out.println(result); |
||||
|
// 添加assistant返回到messages列表,user/assistant消息必须交替出现
|
||||
|
messages.add(result.getOutput().getChoices().get(0).getMessage()); |
||||
|
// new message
|
||||
|
userMsg = Message.builder().role(Role.USER.getValue()).content("请全部返回").build(); |
||||
|
messages.add(userMsg); |
||||
|
result = gen.call(param); |
||||
|
System.out.println(result); |
||||
|
System.out.println(JsonUtils.toJson(result)); |
||||
|
} |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
try { |
||||
|
/*final String questionMsg = "货号87654321,S码黑色30件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654322,S码粉红色40件,M码儿,玫瑰色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654323,S码奶奶灰50件,M码儿,绿色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654324,S码卡其色60件,M码儿,王浩伟色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654325,S码天空蓝70件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654326,S码所有颜色80件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654327,S码黑色30件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654328,S码粉红色40件,M码儿,玫瑰色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654329,S码奶奶灰50件,M码儿,绿色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654330,S码卡其色60件,M码儿,王浩伟色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654331,S码天空蓝70件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654332,S码所有颜色80件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654333,S码黑色30件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654334,S码粉红色40件,M码儿,玫瑰色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654335,S码奶奶灰50件,M码儿,绿色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654336,S码卡其色60件,M码儿,王浩伟色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654337,S码天空蓝70件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654338,S码天空蓝70件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654339,S码天空蓝70件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。\n" + |
||||
|
"货号87654340,S码天空蓝70件,M码儿,白色50件儿,XL码儿,天蓝色50件儿。 \n" + |
||||
|
"这是客户要货信息,请帮我把所有内容封装为json,必须一次性列出所有json数据,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": \"[{\"颜色\":\"红色\",\"尺码\":\"均码\",\"productCount\": \"数量\"}]\" }]"; |
||||
|
callWithMessage(questionMsg);*/ |
||||
|
|
||||
|
// multiRoundConversationCall("https://jewel-shop.oss-cn-beijing.aliyuncs.com/abcbafd10e1b40c082bc1fb271b08da1.jpg");
|
||||
|
}catch (Exception e){ |
||||
|
log.error(e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,106 @@ |
|||||
|
<?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="cc.hiver.mall.purchaseocr.mapper.PurchaseOcrPictureMapper"> |
||||
|
<resultMap id="BaseResultMap" type="cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture"> |
||||
|
<id column="id" jdbcType="VARCHAR" property="id" /> |
||||
|
<result column="create_by" jdbcType="VARCHAR" property="createBy" /> |
||||
|
<result column="create_by_name" jdbcType="VARCHAR" property="createByName" /> |
||||
|
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> |
||||
|
<result column="del_flag" jdbcType="INTEGER" property="delFlag" /> |
||||
|
<result column="update_by" jdbcType="VARCHAR" property="updateBy" /> |
||||
|
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /> |
||||
|
<result column="order_id" jdbcType="VARCHAR" property="orderId" /> |
||||
|
<result column="ocr_picture" jdbcType="VARCHAR" property="ocrPicture" /> |
||||
|
<result column="ocr_picture_order" jdbcType="INTEGER" property="ocrPictureOrder" /> |
||||
|
<result column="ocr_status" jdbcType="INTEGER" property="ocrstatus" /> |
||||
|
<result column="ocr_msg" jdbcType="VARCHAR" property="ocrMsg" /> |
||||
|
<result column="shop_id" jdbcType="VARCHAR" property="shopId" /> |
||||
|
<result column="shop_name" jdbcType="VARCHAR" property="shopName" /> |
||||
|
</resultMap> |
||||
|
<sql id="Example_Where_Clause"> |
||||
|
<where> |
||||
|
<foreach collection="oredCriteria" item="criteria" separator="or"> |
||||
|
<if test="criteria.valid"> |
||||
|
<trim prefix="(" prefixOverrides="and" suffix=")"> |
||||
|
<foreach collection="criteria.criteria" item="criterion"> |
||||
|
<choose> |
||||
|
<when test="criterion.noValue"> |
||||
|
and ${criterion.condition} |
||||
|
</when> |
||||
|
<when test="criterion.singleValue"> |
||||
|
and ${criterion.condition} #{criterion.value} |
||||
|
</when> |
||||
|
<when test="criterion.betweenValue"> |
||||
|
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} |
||||
|
</when> |
||||
|
<when test="criterion.listValue"> |
||||
|
and ${criterion.condition} |
||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" |
||||
|
separator=","> |
||||
|
#{listItem} |
||||
|
</foreach> |
||||
|
</when> |
||||
|
</choose> |
||||
|
</foreach> |
||||
|
</trim> |
||||
|
</if> |
||||
|
</foreach> |
||||
|
</where> |
||||
|
</sql> |
||||
|
<sql id="Update_By_Example_Where_Clause"> |
||||
|
<where> |
||||
|
<foreach collection="example.oredCriteria" item="criteria" separator="or"> |
||||
|
<if test="criteria.valid"> |
||||
|
<trim prefix="(" prefixOverrides="and" suffix=")"> |
||||
|
<foreach collection="criteria.criteria" item="criterion"> |
||||
|
<choose> |
||||
|
<when test="criterion.noValue"> |
||||
|
and ${criterion.condition} |
||||
|
</when> |
||||
|
<when test="criterion.singleValue"> |
||||
|
and ${criterion.condition} #{criterion.value} |
||||
|
</when> |
||||
|
<when test="criterion.betweenValue"> |
||||
|
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} |
||||
|
</when> |
||||
|
<when test="criterion.listValue"> |
||||
|
and ${criterion.condition} |
||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" |
||||
|
separator=","> |
||||
|
#{listItem} |
||||
|
</foreach> |
||||
|
</when> |
||||
|
</choose> |
||||
|
</foreach> |
||||
|
</trim> |
||||
|
</if> |
||||
|
</foreach> |
||||
|
</where> |
||||
|
</sql> |
||||
|
<sql id="Base_Column_List"> |
||||
|
id, create_by, create_by_name, create_time, del_flag, update_by, update_time, order_id, ocr_picture, |
||||
|
ocr_picture_order, ocr_status, ocr_msg, shop_id, shop_name |
||||
|
|
||||
|
</sql> |
||||
|
|
||||
|
<insert id="batchSave" parameterType="java.util.List"> |
||||
|
insert into t_purchase_ocr_picture (id, create_by, create_by_name, create_time, del_flag, update_by, update_time, order_id, ocr_picture, |
||||
|
ocr_picture_order, ocr_status, ocr_msg, shop_id, shop_name) values |
||||
|
<foreach item="purchaseOcrPicture" collection="purchaseOcrPictureList" index="index" separator=","> |
||||
|
(#{purchaseOcrPicture.id,jdbcType=VARCHAR},#{purchaseOcrPicture.createBy,jdbcType=VARCHAR}, |
||||
|
#{purchaseOcrPicture.createByName,jdbcType=VARCHAR},#{purchaseOcrPicture.createTime,jdbcType=TIMESTAMP}, |
||||
|
#{purchaseOcrPicture.delFlag,jdbcType=INTEGER},#{purchaseOcrPicture.updateBy,jdbcType=VARCHAR}, |
||||
|
#{purchaseOcrPicture.updateTime,jdbcType=TIMESTAMP},#{purchaseOcrPicture.orderId,jdbcType=VARCHAR}, |
||||
|
#{purchaseOcrPicture.ocrPicture,jdbcType=VARCHAR},#{purchaseOcrPicture.ocrPictureOrder,jdbcType=INTEGER}, |
||||
|
#{purchaseOcrPicture.ocrStatus,jdbcType=INTEGER},#{purchaseOcrPicture.ocrMsg,jdbcType=VARCHAR}, |
||||
|
#{purchaseOcrPicture.shopId,jdbcType=VARCHAR},#{purchaseOcrPicture.shopName,jdbcType=VARCHAR}) |
||||
|
</foreach> |
||||
|
|
||||
|
</insert> |
||||
|
|
||||
|
<update id="batchUpdate"> |
||||
|
<foreach collection="purchaseOcrPictureList" item="item" separator=";" open="" close=""> |
||||
|
UPDATE t_purchase_ocr_picture SET ocr_msg = #{item.ocrMsg} , ocr_status = #{item.ocrStatus} WHERE id = #{item.id} |
||||
|
</foreach> |
||||
|
</update> |
||||
|
</mapper> |
||||
Loading…
Reference in new issue