diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/datatower/CockpitScreenController.java b/mallinkAdmin/src/main/java/com/iformall/controller/datatower/CockpitScreenController.java new file mode 100644 index 000000000..8b554ba55 --- /dev/null +++ b/mallinkAdmin/src/main/java/com/iformall/controller/datatower/CockpitScreenController.java @@ -0,0 +1,35 @@ +package com.iformall.controller.datatower; + +import com.iformall.annotation.TenantIgnore; +import com.iformall.common.ResultData; +import com.iformall.controller.base.BaseController; +import com.iformall.service.CockpitScreenService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Api(description = "驾驶舱大屏") +@RestController +@RequestMapping("cockpitscreen") +public class CockpitScreenController extends BaseController { + + @Autowired + private CockpitScreenService cockpitScreenService; + + @TenantIgnore + @ApiOperation("驾驶舱大屏-统计会员性别") + @GetMapping("/countUserGender") + public ResultData countUserGender() { + return new ResultData(cockpitScreenService.countUserGender(getTenantInfo())); + } + + @TenantIgnore + @ApiOperation("驾驶舱大屏-统计商铺") + @GetMapping("/countShop") + public ResultData countShop() { + return new ResultData(cockpitScreenService.countShop(getTenantInfo())); + } +} diff --git a/mallinkService/src/main/java/com/iformall/common/CommonConstant.java b/mallinkService/src/main/java/com/iformall/common/CommonConstant.java new file mode 100644 index 000000000..83e28d0a3 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/common/CommonConstant.java @@ -0,0 +1,16 @@ +package com.iformall.common; + +/** + * 公用常量 + * + * @author xmzhao71 + * @date 2023-09-20 + */ +public interface CommonConstant { + /** + * 保留小数位(符合语义的使用) + */ + int SCALE_2 = 2; + int SCALE_3 = 3; + int SCALE_4 = 4; +} diff --git a/mallinkService/src/main/java/com/iformall/domain/dto/cockpit/CountShopByStatusDTO.java b/mallinkService/src/main/java/com/iformall/domain/dto/cockpit/CountShopByStatusDTO.java new file mode 100644 index 000000000..00c9e56a6 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/dto/cockpit/CountShopByStatusDTO.java @@ -0,0 +1,15 @@ +package com.iformall.domain.dto.cockpit; + +import com.iformall.domain.vo.cockpit.CountShopVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@ApiModel(value = "根据状态统计商铺数量") +@Data +public class CountShopByStatusDTO { + @ApiModelProperty(value = "商铺状态") + private Integer status; + @ApiModelProperty(value = "商铺数量") + private Integer shopCount; +} diff --git a/mallinkService/src/main/java/com/iformall/domain/dto/cockpit/CountUserByGenderDTO.java b/mallinkService/src/main/java/com/iformall/domain/dto/cockpit/CountUserByGenderDTO.java new file mode 100644 index 000000000..9423c08ed --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/dto/cockpit/CountUserByGenderDTO.java @@ -0,0 +1,37 @@ +package com.iformall.domain.dto.cockpit; + +import com.iformall.domain.vo.cockpit.CountUserGenderVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@ApiModel(value = "根据性别统计会员数量") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CountUserByGenderDTO { + @ApiModelProperty(value = "用户性别") + private Integer gender; + @ApiModelProperty(value = "用户数量") + private Integer userCount; + + public static CountUserGenderVO.CountUserGenderDetailVO mapping(CountUserByGenderDTO dto) { + CountUserGenderVO.CountUserGenderDetailVO vo = new CountUserGenderVO.CountUserGenderDetailVO(); + vo.setGender(dto.getGender()); + vo.setUserCount(dto.getUserCount()); + return vo; + } + + private static String acquireGender(Integer gender) { + switch (gender) { + case 1: + return "男"; + case 2: + return "女"; + default: + return "不详"; + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/domain/vo/cockpit/CountShopVO.java b/mallinkService/src/main/java/com/iformall/domain/vo/cockpit/CountShopVO.java new file mode 100644 index 000000000..ed670be1c --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/vo/cockpit/CountShopVO.java @@ -0,0 +1,22 @@ +package com.iformall.domain.vo.cockpit; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@ApiModel(value = "商铺统计返回数据") +@Data +public class CountShopVO { + @ApiModelProperty(value = "总的商铺数量") + private Integer totalShopCount; + @ApiModelProperty(value = "出租的商铺数量") + private Integer rentedShopCount; + @ApiModelProperty(value = "出租的商铺数量比例") + private BigDecimal rentedShopCountRatio; + @ApiModelProperty(value = "未出租的商铺数量") + private Integer unRentedShopCount; + @ApiModelProperty(value = "未出租的商铺数量比例") + private BigDecimal unRentedShopCountRatio; +} diff --git a/mallinkService/src/main/java/com/iformall/domain/vo/cockpit/CountUserGenderVO.java b/mallinkService/src/main/java/com/iformall/domain/vo/cockpit/CountUserGenderVO.java new file mode 100644 index 000000000..bbffa4eac --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/vo/cockpit/CountUserGenderVO.java @@ -0,0 +1,29 @@ +package com.iformall.domain.vo.cockpit; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@ApiModel(value = "会员性别统计返回数据") +@Data +public class CountUserGenderVO { + + @ApiModelProperty(value = "总的会员数量") + private Integer totalUserCount; + @ApiModelProperty(value = "会员数量详情") + private List userGenderDetails; + + @ApiModel(value = "会员性别统计详情返回数据") + @Data + public static class CountUserGenderDetailVO { + @ApiModelProperty(value = "性别:0:不详 1:男 2:女") + private Integer gender; + @ApiModelProperty(value = "每个性别的数量") + private Integer userCount; + @ApiModelProperty(value = "每个性别的比例") + private BigDecimal userCountRatio; + } +} diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumUserGender.java b/mallinkService/src/main/java/com/iformall/enums/EnumUserGender.java new file mode 100644 index 000000000..5065779ea --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/enums/EnumUserGender.java @@ -0,0 +1,40 @@ +package com.iformall.enums; + +/** + * 用户性别枚举 + * + * @author xmzhao71 + * @date 2023-09-20 + */ +public enum EnumUserGender { + + GENDER_UNKNOWN(0, "不详"), + GENDER_MALE(1, "男"), + GENDER_FEMALE(2, "女"), + ; + + public static EnumUserGender getEnum(Integer code) { + for (EnumUserGender value : values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return null; + } + + private Integer code; + private String desc; + + EnumUserGender(Integer code, String desc) { + this.code = code; + this.desc = desc; + } + + public Integer getCode() { + return code; + } + + public String getDesc() { + return desc; + } +} diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxCUserBasicInfoMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxCUserBasicInfoMapper.java index 4fbde6784..019eed224 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/WxCUserBasicInfoMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/WxCUserBasicInfoMapper.java @@ -2,10 +2,12 @@ package com.iformall.mapper; import com.iformall.common.CommonMapper; import com.iformall.domain.dto.WxCUserBasicInfoDto; +import com.iformall.domain.dto.cockpit.CountUserByGenderDTO; import com.iformall.domain.po.WxCUserBasicInfo; import com.iformall.domain.vo.CUserBaseVo; import com.iformall.domain.vo.UserCountVo; import com.iformall.domain.vo.WxCUserBasicInfoVo; +import com.iformall.domain.vo.cockpit.CountUserGenderVO; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -64,5 +66,12 @@ public interface WxCUserBasicInfoMapper extends CommonMapper findIdByFilter(WxCUserBasicInfoDto wxCUserBasicInfoDto); long getTotalCreditAmount(@Param("tenantId")String tenantId, @Param("finalTenantId")String finalTenantId); + + /** + * 通过性别统计用户 + * + * @param finalTenantId + */ + List countUserByGender(@Param("finalTenantId") String finalTenantId); } diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxShopMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxShopMapper.java index fc91eba9b..410d7f7ff 100644 --- a/mallinkService/src/main/java/com/iformall/mapper/WxShopMapper.java +++ b/mallinkService/src/main/java/com/iformall/mapper/WxShopMapper.java @@ -1,6 +1,7 @@ package com.iformall.mapper; import com.iformall.common.CommonMapper; +import com.iformall.domain.dto.cockpit.CountShopByStatusDTO; import com.iformall.domain.po.WxShop; import com.iformall.domain.vo.WxShopVo; import org.apache.ibatis.annotations.Param; @@ -47,4 +48,6 @@ public interface WxShopMapper extends CommonMapper { List newFindShopVoList(@Param("tenantId")String tenantId, @Param("shopIds")List shopIds); long findCount(WxShop wxShop); + + List countShopByStatus(@Param("tenantIds") List tenantIds); } diff --git a/mallinkService/src/main/java/com/iformall/service/CockpitScreenService.java b/mallinkService/src/main/java/com/iformall/service/CockpitScreenService.java new file mode 100644 index 000000000..c59c141e4 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/CockpitScreenService.java @@ -0,0 +1,17 @@ +package com.iformall.service; + +import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.vo.cockpit.CountShopVO; +import com.iformall.domain.vo.cockpit.CountUserGenderVO; + +/** + * 驾驶舱大屏服务 + * + * @author xmzhao71 + * @date 2023-09-20 + */ +public interface CockpitScreenService { + CountUserGenderVO countUserGender(TenantEntity tenantInfo); + + CountShopVO countShop(TenantEntity tenantInfo); +} diff --git a/mallinkService/src/main/java/com/iformall/service/impl/CockpitScreenServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/CockpitScreenServiceImpl.java new file mode 100644 index 000000000..283da3f53 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/impl/CockpitScreenServiceImpl.java @@ -0,0 +1,99 @@ +package com.iformall.service.impl; + +import com.iformall.common.CommonConstant; +import com.iformall.domain.dto.cockpit.CountShopByStatusDTO; +import com.iformall.domain.dto.cockpit.CountUserByGenderDTO; +import com.iformall.domain.po.base.TenantEntity; +import com.iformall.domain.vo.cockpit.CountShopVO; +import com.iformall.domain.vo.cockpit.CountUserGenderVO; +import com.iformall.enums.EnumShopStatus; +import com.iformall.enums.EnumUserGender; +import com.iformall.mapper.WxCUserBasicInfoMapper; +import com.iformall.mapper.WxShopMapper; +import com.iformall.service.CockpitScreenService; +import com.iformall.service.WxCUserBasicInfoService; +import com.iformall.service.WxMallService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 驾驶舱大屏服务 + * + * @author xmzhao71 + * @date 2023-09-20 + */ +@Service +public class CockpitScreenServiceImpl implements CockpitScreenService { + + @Autowired + private WxCUserBasicInfoService cUserBasicInfoService; + @Autowired + private WxCUserBasicInfoMapper cUserBasicInfoMapper; + @Autowired + private WxMallService wxMallService; + @Autowired + private WxShopMapper wxShopMapper; + + @Override + public CountUserGenderVO countUserGender(TenantEntity tenantEntity) { + CountUserGenderVO result = new CountUserGenderVO(); + List dtos = cUserBasicInfoMapper.countUserByGender(tenantEntity.getFinalTenantId()); + List totalGenders = dtos.stream().filter(x -> + x.getGender() != null && (x.getGender().equals(EnumUserGender.GENDER_MALE.getCode()) || x.getGender().equals(EnumUserGender.GENDER_FEMALE.getCode())) + ).collect(Collectors.toList()); + Integer unknownGender = dtos.stream().filter(x -> + x.getGender() == null || x.getGender().equals(EnumUserGender.GENDER_UNKNOWN.getCode()) + ).map(CountUserByGenderDTO::getUserCount).reduce(Integer::sum).orElse(0); + totalGenders.add(new CountUserByGenderDTO(EnumUserGender.GENDER_UNKNOWN.getCode(), unknownGender)); + + Integer totalUserCount = totalGenders.stream().map(CountUserByGenderDTO::getUserCount).reduce(Integer::sum).orElse(0); + result.setTotalUserCount(totalUserCount); + + List vos = totalGenders.stream().map(x -> { + CountUserGenderVO.CountUserGenderDetailVO vo = CountUserByGenderDTO.mapping(x); + BigDecimal userCountRatio = BigDecimal.valueOf(x.getUserCount()).divide(BigDecimal.valueOf(totalUserCount), CommonConstant.SCALE_4, RoundingMode.HALF_UP); + vo.setUserCountRatio(userCountRatio); + return vo; + }).collect(Collectors.toList()); + + BigDecimal genderRatio = vos.stream().filter(x -> !EnumUserGender.GENDER_UNKNOWN.getCode().equals(x.getGender())).map(CountUserGenderVO.CountUserGenderDetailVO::getUserCountRatio).reduce(BigDecimal::add).orElse(BigDecimal.ZERO); + vos = vos.stream().map(x -> { + if (EnumUserGender.GENDER_UNKNOWN.getCode().equals(x.getGender())) { + x.setUserCountRatio(BigDecimal.ONE.subtract(genderRatio)); + } + return x; + }).collect(Collectors.toList()); + + result.setUserGenderDetails(vos); + return result; + } + + @Override + public CountShopVO countShop(TenantEntity tenantInfo) { + CountShopVO result = new CountShopVO(); + List tenantInfos = wxMallService.getTenantEntitys(tenantInfo); + List tenantIds = tenantInfos.stream().map(TenantEntity::getTenantId).collect(Collectors.toList()); + List dtos = wxShopMapper.countShopByStatus(tenantIds); + Map shopMap = dtos.stream().collect(Collectors.toMap(CountShopByStatusDTO::getStatus, CountShopByStatusDTO::getShopCount)); + + Integer totalShopCount = dtos.stream().map(CountShopByStatusDTO::getShopCount).reduce(Integer::sum).orElse(0); + result.setTotalShopCount(totalShopCount); + + Integer rentedShopCount = shopMap.get(EnumShopStatus.RENT.getCode()); + Integer unRentedShopCount = shopMap.get(EnumShopStatus.NOT_RENT.getCode()); + result.setRentedShopCount(rentedShopCount); + result.setUnRentedShopCount(unRentedShopCount); + + BigDecimal rentedShopCountRatio = BigDecimal.valueOf(rentedShopCount).divide(BigDecimal.valueOf(totalShopCount), CommonConstant.SCALE_4, RoundingMode.HALF_UP); + result.setRentedShopCountRatio(rentedShopCountRatio); + result.setUnRentedShopCountRatio(BigDecimal.ONE.subtract(rentedShopCountRatio)); + return result; + } +} diff --git a/mallinkService/src/main/resources/mapper/WxCUserBasicInfoMapper.xml b/mallinkService/src/main/resources/mapper/WxCUserBasicInfoMapper.xml index da88c1ac8..5499048cf 100644 --- a/mallinkService/src/main/resources/mapper/WxCUserBasicInfoMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCUserBasicInfoMapper.xml @@ -570,6 +570,12 @@ and wcubi.`tenant_id` like concat('%,', #{tenantId},',%') + diff --git a/mallinkService/src/main/resources/mapper/WxShopMapper.xml b/mallinkService/src/main/resources/mapper/WxShopMapper.xml index 52648fc7d..8c36b5965 100644 --- a/mallinkService/src/main/resources/mapper/WxShopMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxShopMapper.xml @@ -619,4 +619,17 @@ + +