| @@ -18,9 +18,9 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl | |||||
| import springfox.documentation.builders.ApiInfoBuilder; | import springfox.documentation.builders.ApiInfoBuilder; | ||||
| import springfox.documentation.builders.PathSelectors; | import springfox.documentation.builders.PathSelectors; | ||||
| import springfox.documentation.builders.RequestHandlerSelectors; | import springfox.documentation.builders.RequestHandlerSelectors; | ||||
| import springfox.documentation.service.ApiInfo; | |||||
| import springfox.documentation.service.Contact; | |||||
| import springfox.documentation.service.*; | |||||
| import springfox.documentation.spi.DocumentationType; | import springfox.documentation.spi.DocumentationType; | ||||
| import springfox.documentation.spi.service.contexts.SecurityContext; | |||||
| import springfox.documentation.spring.web.paths.RelativePathProvider; | import springfox.documentation.spring.web.paths.RelativePathProvider; | ||||
| import springfox.documentation.spring.web.plugins.Docket; | import springfox.documentation.spring.web.plugins.Docket; | ||||
| import springfox.documentation.swagger2.annotations.EnableSwagger2; | import springfox.documentation.swagger2.annotations.EnableSwagger2; | ||||
| @@ -28,6 +28,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||||
| import javax.servlet.ServletContext; | import javax.servlet.ServletContext; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.Arrays; | import java.util.Arrays; | ||||
| import java.util.Collections; | |||||
| import java.util.List; | import java.util.List; | ||||
| @Configuration | @Configuration | ||||
| @@ -92,7 +93,9 @@ public class SwaggerConfiguration { | |||||
| Predicates.or(basePath) | Predicates.or(basePath) | ||||
| ) | ) | ||||
| ) | ) | ||||
| .build(); | |||||
| .build() | |||||
| .securitySchemes(Collections.singletonList(securitySchema())) | |||||
| .securityContexts(Collections.singletonList(securityContext())); | |||||
| // .groupName("a") | // .groupName("a") | ||||
| // .pathMapping("/B"); | // .pathMapping("/B"); | ||||
| } | } | ||||
| @@ -109,6 +112,44 @@ public class SwaggerConfiguration { | |||||
| .build(); | .build(); | ||||
| } | } | ||||
| /** | |||||
| * 配置默认的全局鉴权策略的开关,通过正则表达式进行匹配;默认匹配所有URL | |||||
| * | |||||
| * @return | |||||
| */ | |||||
| private SecurityContext securityContext() { | |||||
| return SecurityContext.builder() | |||||
| .securityReferences(defaultAuth()) | |||||
| .forPaths(PathSelectors.regex(swaggerProperties.getAuthorization().getAuthRegex())) | |||||
| .build(); | |||||
| } | |||||
| /** | |||||
| * 默认的全局鉴权策略 | |||||
| * | |||||
| * @return | |||||
| */ | |||||
| private List<SecurityReference> defaultAuth() { | |||||
| ArrayList<AuthorizationScope> authorizationScopeList = new ArrayList<>(); | |||||
| swaggerProperties.getAuthorization().getAuthorizationScopeList().forEach(authorizationScope -> | |||||
| authorizationScopeList.add(new AuthorizationScope(authorizationScope.getScope(), authorizationScope.getDescription())) | |||||
| ); | |||||
| AuthorizationScope[] authorizationScopes = new AuthorizationScope[authorizationScopeList.size()]; | |||||
| return Collections.singletonList(SecurityReference.builder() | |||||
| .reference(swaggerProperties.getAuthorization().getName()) | |||||
| .scopes(authorizationScopeList.toArray(authorizationScopes)) | |||||
| .build()); | |||||
| } | |||||
| private OAuth securitySchema() { | |||||
| ArrayList<AuthorizationScope> authorizationScopeList = new ArrayList<>(); | |||||
| swaggerProperties.getAuthorization().getAuthorizationScopeList().forEach(authorizationScope -> authorizationScopeList.add(new AuthorizationScope(authorizationScope.getScope(), authorizationScope.getDescription()))); | |||||
| ArrayList<GrantType> grantTypes = new ArrayList<>(); | |||||
| swaggerProperties.getAuthorization().getTokenUrlList().forEach(tokenUrl -> grantTypes.add(new ResourceOwnerPasswordCredentialsGrant(tokenUrl))); | |||||
| return new OAuth(swaggerProperties.getAuthorization().getName(), authorizationScopeList, grantTypes); | |||||
| } | |||||
| // @Override | // @Override | ||||
| // public void addViewControllers(ViewControllerRegistry registry) { | // public void addViewControllers(ViewControllerRegistry registry) { | ||||
| // String prePath = swaggerProperties.getPrePath(); | // String prePath = swaggerProperties.getPrePath(); | ||||
| @@ -1,6 +1,7 @@ | |||||
| package com.iformall.config; | package com.iformall.config; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | |||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| @@ -61,6 +62,10 @@ public class SwaggerProperties { | |||||
| * 联系人信息 | * 联系人信息 | ||||
| */ | */ | ||||
| private Contact contact = new Contact(); | private Contact contact = new Contact(); | ||||
| /** | |||||
| * 全局统一鉴权配置 | |||||
| **/ | |||||
| private Authorization authorization = new Authorization(); | |||||
| @Data | @Data | ||||
| public static class Contact { | public static class Contact { | ||||
| @@ -76,6 +81,43 @@ public class SwaggerProperties { | |||||
| * 联系人email | * 联系人email | ||||
| **/ | **/ | ||||
| private String email = ""; | private String email = ""; | ||||
| } | |||||
| @Data | |||||
| @NoArgsConstructor | |||||
| public static class Authorization { | |||||
| /** | |||||
| * 鉴权策略ID,需要和SecurityReferences ID保持一致 | |||||
| */ | |||||
| private String name = ""; | |||||
| /** | |||||
| * 需要开启鉴权URL的正则 | |||||
| */ | |||||
| private String authRegex = "^.*$"; | |||||
| /** | |||||
| * 鉴权作用域列表 | |||||
| */ | |||||
| private List<AuthorizationScope> authorizationScopeList = new ArrayList<>(); | |||||
| private List<String> tokenUrlList = new ArrayList<>(); | |||||
| } | |||||
| @Data | |||||
| @NoArgsConstructor | |||||
| public static class AuthorizationScope { | |||||
| /** | |||||
| * 作用域名称 | |||||
| */ | |||||
| private String scope = ""; | |||||
| /** | |||||
| * 作用域描述 | |||||
| */ | |||||
| private String description = ""; | |||||
| } | } | ||||
| } | } | ||||
| @@ -216,7 +216,7 @@ swagger: | |||||
| license: Apache | license: Apache | ||||
| license-url: https://admintest.malls.iformall.com | license-url: https://admintest.malls.iformall.com | ||||
| terms-of-service-url: https://admintest.malls.iformall.com | terms-of-service-url: https://admintest.malls.iformall.com | ||||
| host: https://admintest.malls.iformall.com | |||||
| host: localhost:9000 | |||||
| contact: | contact: | ||||
| name: 张三 | name: 张三 | ||||
| url: https://admintest.malls.iformall.com | url: https://admintest.malls.iformall.com | ||||
| @@ -0,0 +1,14 @@ | |||||
| package com.iformall.domain.vo.cockpit; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| @ApiModel(value = "每月统计数量") | |||||
| @Data | |||||
| public class MonthDataMapping { | |||||
| @ApiModelProperty(value = "某年某月") | |||||
| private String name; | |||||
| @ApiModelProperty(value = "数量") | |||||
| private Integer count; | |||||
| } | |||||
| @@ -8,6 +8,7 @@ import com.iformall.domain.vo.CUserBaseVo; | |||||
| import com.iformall.domain.vo.UserCountVo; | import com.iformall.domain.vo.UserCountVo; | ||||
| import com.iformall.domain.vo.WxCUserBasicInfoVo; | import com.iformall.domain.vo.WxCUserBasicInfoVo; | ||||
| import com.iformall.domain.vo.cockpit.CountUserGenderVO; | import com.iformall.domain.vo.cockpit.CountUserGenderVO; | ||||
| import com.iformall.domain.vo.cockpit.MonthDataMapping; | |||||
| import org.apache.ibatis.annotations.Param; | import org.apache.ibatis.annotations.Param; | ||||
| import java.util.List; | import java.util.List; | ||||
| @@ -83,5 +84,14 @@ public interface WxCUserBasicInfoMapper extends CommonMapper<WxCUserBasicInfo, S | |||||
| * @return {@link Integer} | * @return {@link Integer} | ||||
| */ | */ | ||||
| Integer countUserByMonth(@Param("finalTenantId") String finalTenantId, @Param("year") Integer year, @Param("month") Integer month); | Integer countUserByMonth(@Param("finalTenantId") String finalTenantId, @Param("year") Integer year, @Param("month") Integer month); | ||||
| /** | |||||
| * 统计某年某月的用户数量 | |||||
| * | |||||
| * @param finalTenantId | |||||
| * @param years | |||||
| * @return {@link List}<{@link MonthDataMapping}> | |||||
| */ | |||||
| List<MonthDataMapping> groupByDate(@Param("finalTenantId") String finalTenantId, @Param("years") List<Integer> years); | |||||
| } | } | ||||
| @@ -4,6 +4,8 @@ import com.iformall.common.CommonMapper; | |||||
| import com.iformall.domain.dto.MarkingCouponDataReportDto; | import com.iformall.domain.dto.MarkingCouponDataReportDto; | ||||
| import com.iformall.domain.po.WxUserVisit; | import com.iformall.domain.po.WxUserVisit; | ||||
| import com.iformall.domain.vo.TouchUsersReportVo; | import com.iformall.domain.vo.TouchUsersReportVo; | ||||
| import com.iformall.domain.vo.cockpit.MonthDataMapping; | |||||
| import org.apache.ibatis.annotations.Param; | |||||
| import java.util.List; | import java.util.List; | ||||
| @@ -17,4 +19,12 @@ public interface WxUserVisitMapper extends CommonMapper<WxUserVisit, Long> { | |||||
| List<TouchUsersReportVo> touchUsersReportData(WxUserVisit record); | List<TouchUsersReportVo> touchUsersReportData(WxUserVisit record); | ||||
| Long queryVisitUv(WxUserVisit record); | Long queryVisitUv(WxUserVisit record); | ||||
| /** | |||||
| * 统计某年某月的uv数量 | |||||
| * @param finalTenantId | |||||
| * @param years | |||||
| * @return {@link List}<{@link MonthDataMapping}> | |||||
| */ | |||||
| List<MonthDataMapping> groupByDate(@Param("finalTenantId") String finalTenantId, @Param("years") List<Integer> years); | |||||
| } | } | ||||
| @@ -14,11 +14,37 @@ import java.util.List; | |||||
| * @date 2023-09-20 | * @date 2023-09-20 | ||||
| */ | */ | ||||
| public interface CockpitScreenService { | public interface CockpitScreenService { | ||||
| /** | |||||
| * 统计会员性别信息 | |||||
| * | |||||
| * @param tenantInfo | |||||
| * @return {@link CountUserGenderVO} | |||||
| */ | |||||
| CountUserGenderVO countUserGender(TenantEntity tenantInfo); | CountUserGenderVO countUserGender(TenantEntity tenantInfo); | ||||
| /** | |||||
| * 统计商铺租赁信息 | |||||
| * | |||||
| * @param tenantInfo | |||||
| * @return {@link CountShopVO} | |||||
| */ | |||||
| CountShopVO countShop(TenantEntity tenantInfo); | CountShopVO countShop(TenantEntity tenantInfo); | ||||
| /** | |||||
| * 统计会员数量信息 | |||||
| * | |||||
| * @param tenantInfo | |||||
| * @param years | |||||
| * @return {@link List}<{@link CountMonthVO}> | |||||
| */ | |||||
| List<CountMonthVO> countUser(TenantEntity tenantInfo, List<Integer> years); | List<CountMonthVO> countUser(TenantEntity tenantInfo, List<Integer> years); | ||||
| /** | |||||
| * 统计触达用户信息(uv) | |||||
| * | |||||
| * @param tenantInfo | |||||
| * @param years | |||||
| * @return {@link List}<{@link CountMonthVO}> | |||||
| */ | |||||
| List<CountMonthVO> countReachUser(TenantEntity tenantInfo, List<Integer> years); | List<CountMonthVO> countReachUser(TenantEntity tenantInfo, List<Integer> years); | ||||
| } | } | ||||
| @@ -4,14 +4,12 @@ import com.iformall.common.CommonConstant; | |||||
| import com.iformall.domain.dto.cockpit.CountShopByStatusDTO; | import com.iformall.domain.dto.cockpit.CountShopByStatusDTO; | ||||
| import com.iformall.domain.dto.cockpit.CountUserByGenderDTO; | import com.iformall.domain.dto.cockpit.CountUserByGenderDTO; | ||||
| import com.iformall.domain.po.base.TenantEntity; | import com.iformall.domain.po.base.TenantEntity; | ||||
| import com.iformall.domain.vo.cockpit.CountMonthVO; | |||||
| import com.iformall.domain.vo.cockpit.CountShopVO; | |||||
| import com.iformall.domain.vo.cockpit.CountUserGenderVO; | |||||
| import com.iformall.domain.vo.cockpit.MonthDataVO; | |||||
| import com.iformall.domain.vo.cockpit.*; | |||||
| import com.iformall.enums.EnumShopStatus; | import com.iformall.enums.EnumShopStatus; | ||||
| import com.iformall.enums.EnumUserGender; | import com.iformall.enums.EnumUserGender; | ||||
| import com.iformall.mapper.WxCUserBasicInfoMapper; | import com.iformall.mapper.WxCUserBasicInfoMapper; | ||||
| import com.iformall.mapper.WxShopMapper; | import com.iformall.mapper.WxShopMapper; | ||||
| import com.iformall.mapper.WxUserVisitMapper; | |||||
| import com.iformall.service.CockpitScreenService; | import com.iformall.service.CockpitScreenService; | ||||
| import com.iformall.service.WxCUserBasicInfoService; | import com.iformall.service.WxCUserBasicInfoService; | ||||
| import com.iformall.service.WxMallService; | import com.iformall.service.WxMallService; | ||||
| @@ -34,14 +32,14 @@ import java.util.stream.Collectors; | |||||
| @Service | @Service | ||||
| public class CockpitScreenServiceImpl implements CockpitScreenService { | public class CockpitScreenServiceImpl implements CockpitScreenService { | ||||
| @Autowired | |||||
| private WxCUserBasicInfoService cUserBasicInfoService; | |||||
| @Autowired | @Autowired | ||||
| private WxCUserBasicInfoMapper cUserBasicInfoMapper; | private WxCUserBasicInfoMapper cUserBasicInfoMapper; | ||||
| @Autowired | @Autowired | ||||
| private WxMallService wxMallService; | private WxMallService wxMallService; | ||||
| @Autowired | @Autowired | ||||
| private WxShopMapper wxShopMapper; | private WxShopMapper wxShopMapper; | ||||
| @Autowired | |||||
| private WxUserVisitMapper wxUserVisitMapper; | |||||
| @Override | @Override | ||||
| public CountUserGenderVO countUserGender(TenantEntity tenantEntity) { | public CountUserGenderVO countUserGender(TenantEntity tenantEntity) { | ||||
| @@ -106,20 +104,25 @@ public class CockpitScreenServiceImpl implements CockpitScreenService { | |||||
| } | } | ||||
| List<CountMonthVO> result = new ArrayList<>(); | List<CountMonthVO> result = new ArrayList<>(); | ||||
| years.forEach(year -> { | |||||
| CountMonthVO countMonthVO = new CountMonthVO(); | |||||
| List<MonthDataVO> vos = new ArrayList<>(); | |||||
| for (int i = 0; i < 12; i++) { | |||||
| MonthDataVO vo = new MonthDataVO(); | |||||
| vo.setMonth(i + 1); | |||||
| Integer count = cUserBasicInfoMapper.countUserByMonth(tenantInfo.getFinalTenantId(), year, i + 1); | |||||
| vo.setCount(count); | |||||
| vos.add(vo); | |||||
| List<MonthDataMapping> mappings = cUserBasicInfoMapper.groupByDate(tenantInfo.getFinalTenantId(), years); | |||||
| Map<String, Integer> mappingMap = mappings.stream().collect(Collectors.toMap(MonthDataMapping::getName, MonthDataMapping::getCount)); | |||||
| for (int i = 0; i < years.size(); i++) { | |||||
| CountMonthVO vo = new CountMonthVO(); | |||||
| List<MonthDataVO> months = new ArrayList<>(); | |||||
| for (int j = 0; j < 12; j++) { | |||||
| MonthDataVO month = new MonthDataVO(); | |||||
| month.setMonth(j + 1); | |||||
| Integer count = mappingMap.get(years.get(i) + "-" + DateUtils.getMonthStr(j + 1)); | |||||
| count = count != null ? count : 0; | |||||
| month.setCount(count); | |||||
| months.add(month); | |||||
| } | } | ||||
| countMonthVO.setYear(year); | |||||
| countMonthVO.setMonths(vos); | |||||
| result.add(countMonthVO); | |||||
| }); | |||||
| vo.setYear(years.get(i)); | |||||
| vo.setMonths(months); | |||||
| result.add(vo); | |||||
| } | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -128,6 +131,27 @@ public class CockpitScreenServiceImpl implements CockpitScreenService { | |||||
| if (CollectionUtils.isEmpty(years)) { | if (CollectionUtils.isEmpty(years)) { | ||||
| years.add(DateUtils.getYear(new Date())); | years.add(DateUtils.getYear(new Date())); | ||||
| } | } | ||||
| return null; | |||||
| List<CountMonthVO> result = new ArrayList<>(); | |||||
| List<MonthDataMapping> mappings = wxUserVisitMapper.groupByDate(tenantInfo.getFinalTenantId(), years); | |||||
| Map<String, Integer> mappingMap = mappings.stream().collect(Collectors.toMap(MonthDataMapping::getName, MonthDataMapping::getCount)); | |||||
| for (int i = 0; i < years.size(); i++) { | |||||
| CountMonthVO vo = new CountMonthVO(); | |||||
| List<MonthDataVO> months = new ArrayList<>(); | |||||
| for (int j = 0; j < 12; j++) { | |||||
| MonthDataVO month = new MonthDataVO(); | |||||
| month.setMonth(j + 1); | |||||
| Integer count = mappingMap.get(years.get(i) + "-" + DateUtils.getMonthStr(j + 1)); | |||||
| count = count != null ? count : 0; | |||||
| month.setCount(count); | |||||
| months.add(month); | |||||
| } | |||||
| vo.setYear(years.get(i)); | |||||
| vo.setMonths(months); | |||||
| result.add(vo); | |||||
| } | |||||
| return result; | |||||
| } | } | ||||
| } | } | ||||
| @@ -993,7 +993,7 @@ public class DateUtils { | |||||
| public static String getMonthStr(int month) { | public static String getMonthStr(int month) { | ||||
| if (month < 10) { | if (month < 10) { | ||||
| return "0" + String.valueOf(month); | |||||
| return "0" + month; | |||||
| } else { | } else { | ||||
| return String.valueOf(month); | return String.valueOf(month); | ||||
| } | } | ||||
| @@ -581,6 +581,21 @@ | |||||
| FROM wx_c_user_basic_info | FROM wx_c_user_basic_info | ||||
| WHERE final_tenant_id = #{finalTenantId} AND DATE_FORMAT(create_date, '%Y') = #{year} AND DATE_FORMAT(create_date, '%m') = #{month} | WHERE final_tenant_id = #{finalTenantId} AND DATE_FORMAT(create_date, '%Y') = #{year} AND DATE_FORMAT(create_date, '%m') = #{month} | ||||
| </select> | </select> | ||||
| <select id="groupByDate" resultType="com.iformall.domain.vo.cockpit.MonthDataMapping"> | |||||
| SELECT | |||||
| DATE_FORMAT( create_date, '%Y-%m' ) AS `name`, | |||||
| COUNT( id ) AS `count` | |||||
| FROM | |||||
| wx_c_user_basic_info | |||||
| WHERE | |||||
| final_tenant_id = #{finalTenantId} | |||||
| AND DATE_FORMAT( create_date, '%Y' ) IN | |||||
| <foreach collection="years" item="year" open="(" separator="," close=")"> | |||||
| #{year} | |||||
| </foreach> | |||||
| GROUP BY | |||||
| DATE_FORMAT( create_date, '%Y-%m' ) | |||||
| </select> | |||||
| <update id="incActRecordById" parameterType="java.util.HashMap"> | <update id="incActRecordById" parameterType="java.util.HashMap"> | ||||
| @@ -164,5 +164,20 @@ | |||||
| and day_date <= #{endTime} | and day_date <= #{endTime} | ||||
| </if> | </if> | ||||
| </select> | </select> | ||||
| <select id="groupByDate" resultType="com.iformall.domain.vo.cockpit.MonthDataMapping"> | |||||
| SELECT | |||||
| DATE_FORMAT( day_date, '%Y-%m' ) AS `name`, | |||||
| IFNULL( sum( visit_uv ), 0 ) AS count | |||||
| FROM | |||||
| wx_user_visit | |||||
| WHERE | |||||
| tenant_id = #{finalTenantId} | |||||
| AND DATE_FORMAT( create_date, '%Y' ) IN | |||||
| <foreach collection="years" item="year" open="(" separator="," close=")"> | |||||
| #{year} | |||||
| </foreach> | |||||
| GROUP BY | |||||
| `name` | |||||
| </select> | |||||
| </mapper> | </mapper> | ||||