feat:(REQ-3282) 提供统一的productApi

This commit is contained in:
李龙 2025-01-13 14:42:56 +08:00
parent 1f73699ac9
commit c650ed3e10
8 changed files with 356 additions and 2 deletions

View File

@ -0,0 +1,17 @@
package cn.axzo.tyr.feign.api;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.tyr.feign.req.PageProductReq;
import cn.axzo.tyr.feign.resp.ProductResp;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
public interface ProductApi {
@PostMapping("/api/product/page")
ApiResult<PageResp<ProductResp>> page(@RequestBody @Validated PageProductReq req);
}

View File

@ -0,0 +1,50 @@
package cn.axzo.tyr.feign.req;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.IPageReq;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Max;
import java.util.List;
import java.util.Set;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PageProductReq implements IPageReq {
@CriteriaField(ignore = true)
private Integer page;
/**
* 最大值1000
*/
@CriteriaField(ignore = true)
@Max(value = 1000, message = "pageSize最大值为1000")
private Integer pageSize;
/**
* 排序使用示例createTime__DESC
*/
@CriteriaField(ignore = true)
private List<String> sort;
/**
* 工作台类型
*/
@CriteriaField(field = "dictWorkspaceTypeId", operator = Operator.IN)
private Set<Long> dictWorkspaceTypeIdS;
/**
* 产品默认授权方式
* 1:创建工作台
* 2:资质认证
*/
@CriteriaField(field = "authType", operator = Operator.IN)
private Set<Integer> authTypes;
}

View File

@ -0,0 +1,174 @@
package cn.axzo.tyr.feign.resp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductResp {
private Long id;
private Date createAt;
private Date updateAt;
private Long isDelete;
/**
* 产品 icon
*/
private String icon;
/**
* 产品板块名字
*/
private String productName;
/**
* 产品板块名字
*/
private Integer productType;
/**
* 基础产品与否 0:基础产品 1:普通产品
*/
private Integer commonProduct;
/**
* 产品所属工作台字典 ID
*/
private Long dictWorkspaceTypeId;
/**
* 产品所属工作台字典 Code
*/
private String dictWorkspaceTypeCode;
/**
* 产品状态
*/
private Integer status;
/**
* 产品板块备注
*/
private String remark;
/**
* 产品默认授权方式
* 1:创建工作台
* 2:资质认证
*/
private Integer authType;
/**
* 资质序列/单位类型(数组多选逗号隔开1,2,3,4,5)
* cn.axzo.basics.common.constant.enums.OrganizationalUnitTypeEnum
*/
private String ouType;
/**
* 创建人
*/
private Long createBy;
/**
* 修改人
*/
private Long updateBy;
/**
* 产品类型
* PRODUCT_VERSION:产品版本类型ADD_VALUE_SERVICE:增值服务类型
* GENERAL_SERVICE:通用产品类型HARD_WARE:硬件产品类型
*/
private String category;
/**
* 版本升级序列(数字越小版本越低不能降级只能升级) <企业项目产品>
*/
private Integer version;
/**
* 人数上限 <企业项目产品>
*/
private Integer maxPersonCount;
/**
* 最大项目数 <企业产品>
*/
private Integer maxWorkspaceCount;
/**
* 价格(单位)
*/
private Long price;
/**
* 产品详情 jsonList(skuNameSKU名称model规格型号count数量unit单位)
*/
private List<Sku> skus;
/**
* 素材<仅硬件产品支持>json类型
* ({"miages":List<String>,"videos":List<String>,"detailImages":List<String>})
*/
private Material material;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Sku {
/**
* SKU名称
*/
private String skuName;
/**
* 规格型号
*/
private String model;
/**
* 数量
*/
private Integer count;
/**
* 单位
*/
private String unit;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Material {
/**
* 图片
*/
private List<String> images;
/**
* 视频
*/
private List<String> videos;
/**
* 详情大图
*/
private List<String> detailImages;
}
}

View File

@ -0,0 +1,24 @@
package cn.axzo.tyr.server.controller.v2;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.tyr.feign.api.ProductApi;
import cn.axzo.tyr.feign.req.PageProductReq;
import cn.axzo.tyr.feign.resp.ProductResp;
import cn.axzo.tyr.server.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class ProductV2Controller implements ProductApi {
@Autowired
private ProductService productService;
@Override
public ApiResult<PageResp<ProductResp>> page(PageProductReq req) {
return ApiResult.success(productService.pageV2(req));
}
}

View File

@ -1,6 +1,7 @@
package cn.axzo.tyr.server.service;
import cn.axzo.basics.common.page.PageResult;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.framework.domain.web.result.ApiPageResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.tyr.client.model.product.ProductAddReq;
@ -15,7 +16,10 @@ import cn.axzo.tyr.client.model.req.UpdateProductStatusReq;
import cn.axzo.tyr.client.model.res.GovernmentTerminalResp;
import cn.axzo.tyr.client.model.res.SaasProductResp;
import cn.axzo.tyr.client.model.res.WorkspaceProductResp;
import cn.axzo.tyr.feign.req.PageProductReq;
import cn.axzo.tyr.feign.resp.ProductResp;
import cn.axzo.tyr.server.repository.entity.ProductModule;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
@ -25,7 +29,7 @@ import java.util.List;
* @author wangli
* @since 2023/9/7 14:21
*/
public interface ProductService {
public interface ProductService extends IService<ProductModule> {
ApiResult<List<ProductVO>> list(ProductSearchListReq req);
@ -61,4 +65,6 @@ public interface ProductService {
* @param req
*/
Long productModuleCreate(SaasProductSaveOrUpdateReq req);
PageResp<ProductResp> pageV2(PageProductReq req);
}

View File

@ -5,9 +5,12 @@ import cn.axzo.basics.common.page.PageResult;
import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.basics.profiles.api.UserProfileServiceApi;
import cn.axzo.basics.profiles.dto.basic.PersonProfileDto;
import cn.axzo.foundation.dao.support.converter.PageConverter;
import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper;
import cn.axzo.framework.domain.page.PageResp;
import cn.axzo.framework.domain.web.result.ApiPageResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import cn.axzo.pudge.core.service.ServiceException;
import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum;
@ -32,6 +35,8 @@ import cn.axzo.tyr.client.model.req.UpdateProductStatusReq;
import cn.axzo.tyr.client.model.res.GovernmentTerminalResp;
import cn.axzo.tyr.client.model.res.SaasProductResp;
import cn.axzo.tyr.client.model.res.WorkspaceProductResp;
import cn.axzo.tyr.feign.req.PageProductReq;
import cn.axzo.tyr.feign.resp.ProductResp;
import cn.axzo.tyr.server.model.RelationOperateLogProductBindResourceDO;
import cn.axzo.tyr.server.repository.dao.ProductModuleDao;
import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao;
@ -39,6 +44,7 @@ import cn.axzo.tyr.server.repository.entity.ProductModule;
import cn.axzo.tyr.server.repository.entity.SaasFeatureResource;
import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelationOperateLog;
import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation;
import cn.axzo.tyr.server.repository.mapper.ProductModuleMapper;
import cn.axzo.tyr.server.service.ProductFeatureRelationService;
import cn.axzo.tyr.server.service.ProductService;
import cn.axzo.tyr.server.service.SaasBasicDictService;
@ -50,8 +56,10 @@ import cn.azxo.framework.common.constatns.Constants;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
@ -82,7 +90,7 @@ import java.util.stream.Collectors;
@Slf4j
@RequiredArgsConstructor
@Service
public class ProductServiceImpl implements ProductService {
public class ProductServiceImpl extends ServiceImpl<ProductModuleMapper, ProductModule> implements ProductService {
/** 政务端前缀 **/
private static final String PREFIX_TERMINAL_GA = "NT_PC_GA_";
@ -643,4 +651,18 @@ public class ProductServiceImpl implements ProductService {
productModuleDao.save(product);
return product;
}
@Override
public cn.axzo.foundation.page.PageResp<ProductResp> pageV2(PageProductReq req) {
QueryWrapper<ProductModule> wrapper = QueryWrapperHelper.fromBean(req, ProductModule.class);
wrapper.eq("is_delete", 0);
IPage<ProductModule> page = this.page(PageConverter.toMybatis(req, ProductModule.class), wrapper);
return PageConverter.toResp(page, this::from);
}
private ProductResp from(ProductModule productModule) {
return JSON.parseObject(JSON.toJSONString(productModule), ProductResp.class);
}
}

View File

@ -0,0 +1,51 @@
package cn.axzo.tyr.server.service.impl;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.tyr.base.BaseTest;
import cn.axzo.tyr.base.MysqlDataLoader;
import cn.axzo.tyr.feign.req.PageProductReq;
import cn.axzo.tyr.feign.resp.ProductResp;
import cn.axzo.tyr.server.service.ProductService;
import cn.hutool.db.Page;
import org.apache.commons.compress.utils.Sets;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.*;
class ProductServiceImplTest extends BaseTest {
@Autowired
private MysqlDataLoader mysqlDataLoader;
@Autowired
private ProductService productService;
@BeforeEach
@Override
public void setup() {
super.setup();
mysqlDataLoader.loadFromClassName(getClass().getSimpleName());
}
@Test
void pageV2() {
PageResp<ProductResp> resp = productService.pageV2(PageProductReq.builder()
.build());
Assertions.assertEquals(resp.getData().size(), 2);
resp = productService.pageV2(PageProductReq.builder()
.dictWorkspaceTypeIdS(Sets.newHashSet(1L))
.build());
Assertions.assertEquals(resp.getData().size(), 1);
resp = productService.pageV2(PageProductReq.builder()
.authTypes(Sets.newHashSet(1))
.build());
Assertions.assertEquals(resp.getData().size(), 2);
}
}

View File

@ -0,0 +1,10 @@
#-->DEFAULT
INSERT INTO product_module (id, icon, product_type, product_name, dict_workspace_type_id, dict_workspace_type_code, status, common_product, remark, auth_type, ou_type, is_delete, create_by, create_at, update_at, update_by, category, version, max_person_count, max_workspace_count, price, skus, material)
VALUES (1, 'https://axzo-public.oss-cn-chengdu.aliyuncs.com/oms/test/1695189976949-Snipaste_09-15 16-36.png', 1, '企业基础-自动授权', 1, '1', 1, 1, '', 1, null, 0, 0, '2022-08-17 19:46:11', '2025-01-13 14:19:46', 9000399458, 'GENERAL_SERVICE', 0, 0, 0, 0, null, null);
INSERT INTO product_module (id, icon, product_type, product_name, dict_workspace_type_id, dict_workspace_type_code, status, common_product, remark, auth_type, ou_type, is_delete, create_by, create_at, update_at, update_by, category, version, max_person_count, max_workspace_count, price, skus, material)
VALUES (2, 'https://axzo-public.oss-cn-chengdu.aliyuncs.com/oms/test/1695286111017-Snipaste_09-13 16-24.png', 2, '项目基础', 2, '2', 1, 1, '', 1, null, 0, 0, '2022-08-17 19:46:11', '2024-12-25 13:39:12', 9000400021, 'GENERAL_SERVICE', 0, 0, 0, 0, null, null);
#-->ProductServiceImplTest.sql