feat: 产品中心

This commit is contained in:
曹鹏飞 2025-05-28 17:24:44 +08:00
parent 233c8ae24b
commit 505a30c4d7
18 changed files with 306 additions and 91 deletions

View File

@ -1,11 +1,8 @@
package com.nflg.mobilebroken.admin.controller;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.pojo.ApiResult;
import com.nflg.mobilebroken.common.pojo.PageData;
import com.nflg.mobilebroken.common.pojo.request.ProductPartAddRequest;
import com.nflg.mobilebroken.common.pojo.request.ProductPartSearchRequest;
import com.nflg.mobilebroken.common.pojo.request.ProductPartUpdateRequest;
import com.nflg.mobilebroken.common.pojo.request.*;
import com.nflg.mobilebroken.common.pojo.vo.ProductPartInfoVO;
import com.nflg.mobilebroken.common.pojo.vo.ProductPartSearchVO;
import com.nflg.mobilebroken.repository.service.IProductPartService;
@ -47,6 +44,36 @@ public class ProductPartController extends ControllerBase {
return ApiResult.success();
}
/**
* 启用/禁用部件
* @param request 请求参数
*/
@PostMapping("/enable")
public ApiResult<Void> enable(@Valid @RequestBody EnableRequest request){
productPartService.enable(request);
return ApiResult.success();
}
/**
* 删除部件
* @param request 请求参数
*/
@PostMapping("/delete")
public ApiResult<Void> delete(@Valid @RequestBody BatchDeleteRequest request){
productPartService.delete(request);
return ApiResult.success();
}
/**
* 发布或者取消发布部件
* @param request 请求参数
*/
@PostMapping("/publish")
public ApiResult<Void> publish(@Valid @RequestBody ProductPublishRequest request){
productPartService.publish(request);
return ApiResult.success();
}
/**
* 获取部件列表
* @param request 请求参数
@ -62,6 +89,6 @@ public class ProductPartController extends ControllerBase {
*/
@GetMapping("/getInfo")
public ApiResult<ProductPartInfoVO> getModelInfo(@Valid @RequestParam @NotNull Integer partId) {
return ApiResult.success(productPartService.getInfo(partId, Constant.DEFAULT_LANGUAGE_CODE));
return ApiResult.success(productPartService.getInfo(partId));
}
}

View File

@ -2,23 +2,29 @@ package com.nflg.mobilebroken.common.pojo.request;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
public class ProductPartAddRequest {
/**
* 物料变化
* 物料编号
*/
@NotBlank
private String materialNo;
/**
* 类别属性字典项id
*/
@NotNull
private Integer attrId;
/**
* 多语言数据
*/
@NotEmpty
private List<ProductPartInfoAddRequest> items;
/**
* 参数
*/
private List<ProductParamsAddRequest> params;
}

View File

@ -31,7 +31,17 @@ public class ProductPartInfoAddRequest {
private String desc;
/**
* 视频或者图片地址
* 图片地址
*/
private String url;
private String image;
/**
* 视频地址
*/
private String video;
/**
* 类型0-视频1图片
*/
private Integer type;
}

View File

@ -7,11 +7,31 @@ import java.time.LocalDate;
@Data
public class ProductPartSearchRequest extends PageRequest {
/**
* 物料编号
*/
private String materialNo;
/**
* 名称
*/
private String name;
/**
* 类别属性字典项id
*/
private Integer attrId;
/**
* 是否启用
*/
private Boolean enable;
/**
* 发布状态0未发布1-已发布2-已废弃
*/
private Integer state;
/**
* 起始时间
*/

View File

@ -1,5 +1,6 @@
package com.nflg.mobilebroken.common.pojo.vo;
import com.nflg.mobilebroken.common.pojo.request.ProductPartInfoAddRequest;
import lombok.Data;
import java.util.List;
@ -20,17 +21,17 @@ public class ProductPartInfoVO {
private String materialNo;
/**
* 描述
* 类别属性字典项id
*/
private String desc;
private Integer attrId;
/**
* 图片
* 类别属性
*/
private String url;
private Integer attrName;
/**
* 参数
*
*/
private List<ProductParamsVO> params;
private List<ProductPartInfoAddRequest> items;
}

View File

@ -19,6 +19,36 @@ public class ProductPartSearchVO {
*/
private String materialNo;
/**
* 类别属性字典项id
*/
private Integer attrId;
/**
* 类别属性
*/
private Integer attrName;
/**
* 是否启用
*/
private Boolean enable;
/**
* 发布状态0未发布1-已发布2-已废弃
*/
private Integer state;
/**
* 发布人
*/
private String publishBy;
/**
* 发布时间
*/
private LocalDateTime publishTime;
/**
* 创建人
*/

View File

@ -72,14 +72,14 @@ public class DataController extends BaseController{
return ApiResult.success(productModelService.get(typeId,MultilingualUtil.getLanguage()));
}
/**
* 获取产品机型详情
* @param modelId 产品机型id
*/
@GetMapping("/getModelInfo")
public ApiResult<ProductModelInfoVO> getModelInfo(@Valid @RequestParam @NotNull Integer modelId){
return ApiResult.success(productModelService.getInfo(modelId,MultilingualUtil.getLanguage()));
}
// /**
// * 获取产品机型详情
// * @param modelId 产品机型id
// */
// @GetMapping("/getModelInfo")
// public ApiResult<ProductModelInfoVO> getModelInfo(@Valid @RequestParam @NotNull Integer modelId){
// return ApiResult.success(productModelService.getInfo(modelId,MultilingualUtil.getLanguage()));
// }
/**
* 获取产品机型参数列表

View File

@ -33,6 +33,36 @@ public class ProductPart implements Serializable {
*/
private String materialNo;
/**
* 名称
*/
private String name;
/**
* 类别属性字典项id
*/
private Integer attrId;
/**
* 是否启用
*/
private Boolean enable;
/**
* 发布状态0未发布1-已发布2-已废弃
*/
private Integer state;
/**
* 发布人
*/
private String publishBy;
/**
* 发布时间
*/
private LocalDateTime publishTime;
/**
* 创建人
*/

View File

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
@ -43,33 +42,23 @@ public class ProductPartInfo implements Serializable {
*/
private String name;
/**
* 类型0-视频1图片
*/
private Integer type;
/**
* 图片地址
*/
private String image;
/**
* 视频地址
*/
private String video;
/**
* 部件介绍
*/
private String desc;
/**
* 视频或者图片地址
*/
private String url;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@ -1,8 +1,11 @@
package com.nflg.mobilebroken.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nflg.mobilebroken.common.pojo.request.ProductPartInfoAddRequest;
import com.nflg.mobilebroken.repository.entity.ProductPartInfo;
import java.util.List;
/**
* <p>
* 产品中心-部件详情 Mapper 接口
@ -13,4 +16,5 @@ import com.nflg.mobilebroken.repository.entity.ProductPartInfo;
*/
public interface ProductPartInfoMapper extends BaseMapper<ProductPartInfo> {
List<ProductPartInfoAddRequest> getInfo(Integer partId);
}

View File

@ -20,5 +20,5 @@ public interface ProductPartMapper extends BaseMapper<ProductPart> {
PageData<ProductPartSearchVO> getList(ProductPartSearchRequest request, Page<?> page);
ProductPartInfoVO getInfo(Integer partId, String language);
ProductPartInfoVO getInfo(Integer partId);
}

View File

@ -3,7 +3,6 @@ package com.nflg.mobilebroken.repository.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.mobilebroken.common.pojo.request.ProductPartInfoAddRequest;
import com.nflg.mobilebroken.repository.entity.ProductPartInfo;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@ -19,6 +18,7 @@ public interface IProductPartInfoService extends IService<ProductPartInfo> {
void add(Integer partId, List<ProductPartInfoAddRequest> items);
@Transactional
void update(List<ProductPartInfoAddRequest> items);
List<ProductPartInfoAddRequest> getInfo(Integer partId);
}

View File

@ -2,9 +2,7 @@ package com.nflg.mobilebroken.repository.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.mobilebroken.common.pojo.PageData;
import com.nflg.mobilebroken.common.pojo.request.ProductPartAddRequest;
import com.nflg.mobilebroken.common.pojo.request.ProductPartSearchRequest;
import com.nflg.mobilebroken.common.pojo.request.ProductPartUpdateRequest;
import com.nflg.mobilebroken.common.pojo.request.*;
import com.nflg.mobilebroken.common.pojo.vo.ProductPartInfoVO;
import com.nflg.mobilebroken.common.pojo.vo.ProductPartSearchVO;
import com.nflg.mobilebroken.repository.entity.ProductPart;
@ -28,5 +26,11 @@ public interface IProductPartService extends IService<ProductPart> {
PageData<ProductPartSearchVO> getList(ProductPartSearchRequest request);
ProductPartInfoVO getInfo(@Valid @NotNull Integer partId, String language);
ProductPartInfoVO getInfo(@Valid @NotNull Integer partId);
void enable(@Valid EnableRequest request);
void delete(@Valid BatchDeleteRequest request);
void publish(@Valid ProductPublishRequest request);
}

View File

@ -3,14 +3,12 @@ package com.nflg.mobilebroken.repository.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.mobilebroken.common.pojo.request.ProductModelVideoItemAddRequest;
import com.nflg.mobilebroken.common.util.AdminUserUtil;
import com.nflg.mobilebroken.repository.entity.ProductModelVideoItem;
import com.nflg.mobilebroken.repository.mapper.ProductModelVideoItemMapper;
import com.nflg.mobilebroken.repository.service.IProductModelVideoItemService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@ -37,8 +35,6 @@ public class ProductModelVideoItemServiceImpl extends ServiceImpl<ProductModelVi
.setVideo(it.getVideo())
.setContent(it.getContent())
.setImage(it.getImage())
.setCreateBy(AdminUserUtil.getUserName())
.setCreateTime(LocalDateTime.now())
)
.collect(Collectors.toList())
);

View File

@ -3,14 +3,12 @@ package com.nflg.mobilebroken.repository.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.mobilebroken.common.pojo.request.ProductPartInfoAddRequest;
import com.nflg.mobilebroken.common.util.AdminUserUtil;
import com.nflg.mobilebroken.repository.entity.ProductPartInfo;
import com.nflg.mobilebroken.repository.mapper.ProductPartInfoMapper;
import com.nflg.mobilebroken.repository.service.IProductPartInfoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@ -36,9 +34,9 @@ public class ProductPartInfoServiceImpl extends ServiceImpl<ProductPartInfoMappe
.setLanguageCode(it.getLanguageCode())
.setName(it.getName())
.setDesc(it.getDesc())
.setUrl(it.getUrl())
.setCreateBy(AdminUserUtil.getUserName())
.setCreateTime(LocalDateTime.now())
.setImage(it.getImage())
.setVideo(it.getVideo())
.setType(it.getType())
)
.collect(Collectors.toList())
);
@ -54,12 +52,17 @@ public class ProductPartInfoServiceImpl extends ServiceImpl<ProductPartInfoMappe
.map(it -> new ProductPartInfo()
.setName(it.getName())
.setDesc(it.getDesc())
.setUrl(it.getUrl())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now())
.setImage(it.getImage())
.setVideo(it.getVideo())
.setType(it.getType())
)
.collect(Collectors.toList())
);
}
}
@Override
public List<ProductPartInfoAddRequest> getInfo(Integer partId) {
return baseMapper.getInfo(partId);
}
}

View File

@ -1,14 +1,16 @@
package com.nflg.mobilebroken.repository.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.constant.PublishState;
import com.nflg.mobilebroken.common.pojo.PageData;
import com.nflg.mobilebroken.common.pojo.request.ProductPartAddRequest;
import com.nflg.mobilebroken.common.pojo.request.ProductPartSearchRequest;
import com.nflg.mobilebroken.common.pojo.request.ProductPartUpdateRequest;
import com.nflg.mobilebroken.common.pojo.request.*;
import com.nflg.mobilebroken.common.pojo.vo.ProductPartInfoVO;
import com.nflg.mobilebroken.common.pojo.vo.ProductPartSearchVO;
import com.nflg.mobilebroken.common.util.AdminUserUtil;
import com.nflg.mobilebroken.common.util.VUtils;
import com.nflg.mobilebroken.repository.entity.ProductPart;
import com.nflg.mobilebroken.repository.mapper.ProductPartMapper;
import com.nflg.mobilebroken.repository.service.IProductPartInfoService;
@ -41,25 +43,37 @@ public class ProductPartServiceImpl extends ServiceImpl<ProductPartMapper, Produ
@Transactional
@Override
public void add(ProductPartAddRequest request) {
ProductPartInfoAddRequest cn=request.getItems().stream()
.filter(it-> StrUtil.equals(it.getLanguageCode(), Constant.DEFAULT_LANGUAGE_CODE))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(cn)).throwMessage("必须包含中文数据");
ProductPart part = new ProductPart()
.setMaterialNo(request.getMaterialNo())
.setName(cn.getName())
.setAttrId(request.getAttrId())
.setCreateBy(AdminUserUtil.getUserName())
.setCreateTime(LocalDateTime.now());
save(part);
productPartInfoService.add(part.getId(), request.getItems());
productPartParamsService.add(part.getId(), request.getParams());
}
@Transactional
@Override
public void update(ProductPartUpdateRequest request) {
ProductPartInfoAddRequest cn=request.getItems().stream()
.filter(it-> StrUtil.equals(it.getLanguageCode(), Constant.DEFAULT_LANGUAGE_CODE))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(cn)).throwMessage("必须包含中文数据");
lambdaUpdate()
.set(ProductPart::getMaterialNo, request.getMaterialNo())
.set(ProductPart::getAttrId, request.getAttrId())
.set(ProductPart::getName, cn.getName())
.set(ProductPart::getUpdateBy, AdminUserUtil.getUserName())
.set(ProductPart::getUpdateTime, LocalDateTime.now())
.update();
productPartInfoService.update(request.getItems());
productPartParamsService.update(request.getParams());
}
@Override
@ -68,11 +82,77 @@ public class ProductPartServiceImpl extends ServiceImpl<ProductPartMapper, Produ
}
@Override
public ProductPartInfoVO getInfo(Integer partId, String language) {
ProductPartInfoVO part = baseMapper.getInfo(partId, language);
if (Objects.nonNull(part)) {
part.setParams(productPartParamsService.getInfo(partId, language));
}
public ProductPartInfoVO getInfo(Integer partId) {
ProductPartInfoVO part = baseMapper.getInfo(partId);
part.setItems(productPartInfoService.getInfo(partId));
return part;
}
@Override
public void enable(EnableRequest request) {
ProductPart info=getById(request.getId());
VUtils.trueThrowBusinessError(Objects.isNull(info)).throwMessage("无效的数据");
if (request.getEnable()){
//启用
if (Objects.equals(info.getState(), PublishState.Published.getState())){
VUtils.trueThrowBusinessError(lambdaQuery()
.eq(ProductPart::getMaterialNo,info.getMaterialNo())
.eq(ProductPart::getState,PublishState.Published.getState())
.exists())
.throwMessage("已有状态为已发布的数据");
info.setState(PublishState.Published.getState());
info.setPublishBy(AdminUserUtil.getUserName());
info.setPublishTime(LocalDateTime.now());
updateById(info);
}
}else {
//禁用
VUtils.trueThrowBusinessError(Objects.equals(info.getState(),PublishState.Published.getState()))
.throwMessage("不能禁用已发布的数据");
info.setEnable(false);
info.setUpdateBy(AdminUserUtil.getUserName());
info.setUpdateTime(LocalDateTime.now());
updateById(info);
}
}
@Override
public void delete(BatchDeleteRequest request) {
VUtils.trueThrowBusinessError(lambdaQuery()
.in(ProductPart::getId, request.getIds())
.eq(ProductPart::getState, PublishState.Published.getState())
.exists())
.throwMessage("禁止删除已发布的数据");
removeByIds(request.getIds());
}
@Override
public void publish(ProductPublishRequest request) {
ProductPart info = getById(request.getId());
VUtils.trueThrowBusinessError(Objects.isNull(info)).throwMessage("无效的数据");
VUtils.trueThrowBusinessError(Objects.equals(info.getState(), request.getState()))
.throwMessage("请勿重复操作");
if (Objects.equals(request.getState(), PublishState.Published.getState())) {
info.setState(PublishState.Published.getState());
info.setPublishBy(AdminUserUtil.getUserName());
info.setPublishTime(LocalDateTime.now());
lambdaUpdate()
.set(ProductPart::getState, PublishState.Obsolete.getState())
.eq(ProductPart::getMaterialNo, info.getMaterialNo())
.eq(ProductPart::getState, PublishState.Published.getState())
.update();
} else {
ProductPart obsolete = lambdaQuery()
.eq(ProductPart::getMaterialNo, info.getMaterialNo())
.eq(ProductPart::getState, PublishState.Obsolete.getState())
.orderByDesc(ProductPart::getPublishTime)
.last("Limit 1")
.one();
VUtils.trueThrowBusinessError(Objects.isNull(obsolete)).throwMessage("不能取消该发布");
info.setState(PublishState.Obsolete.getState());
obsolete.setState(PublishState.Published.getState());
updateById(obsolete);
}
updateById(info);
}
}

View File

@ -2,4 +2,7 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nflg.mobilebroken.repository.mapper.ProductPartInfoMapper">
<select id="getInfo" resultType="com.nflg.mobilebroken.common.pojo.request.ProductPartInfoAddRequest">
select * from product_part_info where part_id = #{partId}
</select>
</mapper>

View File

@ -3,27 +3,39 @@
<mapper namespace="com.nflg.mobilebroken.repository.mapper.ProductPartMapper">
<select id="getList" resultType="com.nflg.mobilebroken.common.pojo.vo.ProductPartSearchVO">
SELECT pp.*,ppi.`name`
SELECT pp.*,di.name as 'attrName'
FROM product_part pp
LEFT JOIN product_part_info ppi ON ppi.part_id=pp.id AND ppi.language_code='cn'
LEFT JOIN dictionary_item di on pp.attr_id=di.id
<where>
<if test="request.name!=null and request.name!=''">
AND ppi.`name` LIKE CONCAT('%', #{request.name}, '%')
<if test="request.state!=null">
AND pp.`state`=#{request.state}
</if>
<if test="request.enable!=null">
AND pp.`enable`=#{request.enable}
</if>
<if test="request.attrId!=null">
AND pp.attr_id=#{request.attrId}
</if>
<if test="request.startTime!=null">
AND pp.create_time>=#{request.startTime}
AND pp.publish_time>=#{request.startTime}
</if>
<if test="request.endTime!=null">
AND pp.create_time&lt;=#{request.endTime}
AND pp.publish_time&lt;=#{request.endTime}
</if>
<if test="request.materialNo!=null and request.materialNo!=''">
AND pp.material_no LIKE CONCAT('%', #{request.materialNo}, '%')
</if>
<if test="request.name!=null and request.name!=''">
AND pp.`name` LIKE CONCAT('%', #{request.name}, '%')
</if>
</where>
ORDER BY pp.id DESC;
ORDER BY pp.state,pp.publish_time DESC,pp.id DESC;
</select>
<select id="getInfo" resultType="com.nflg.mobilebroken.common.pojo.vo.ProductPartInfoVO">
SELECT pp.*,ppi.`name`
SELECT pp.*,di.`name` as 'attrName'
FROM product_part pp
LEFT JOIN product_part_info ppi ON ppi.part_id=pp.id AND ppi.language_code=#{language}
LEFT JOIN dictionary_item di on pp.attr_id=di.id
WHERE pp.id=#{partId}
</select>
</mapper>