| @@ -18,9 +18,9 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl | |||
| import springfox.documentation.builders.ApiInfoBuilder; | |||
| import springfox.documentation.builders.PathSelectors; | |||
| 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.service.contexts.SecurityContext; | |||
| import springfox.documentation.spring.web.paths.RelativePathProvider; | |||
| import springfox.documentation.spring.web.plugins.Docket; | |||
| import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||
| @@ -28,6 +28,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||
| import javax.servlet.ServletContext; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Collections; | |||
| import java.util.List; | |||
| @Configuration | |||
| @@ -92,7 +93,9 @@ public class SwaggerConfiguration { | |||
| Predicates.or(basePath) | |||
| ) | |||
| ) | |||
| .build(); | |||
| .build() | |||
| .securitySchemes(Collections.singletonList(securitySchema())) | |||
| .securityContexts(Collections.singletonList(securityContext())); | |||
| // .groupName("a") | |||
| // .pathMapping("/B"); | |||
| } | |||
| @@ -109,6 +112,44 @@ public class SwaggerConfiguration { | |||
| .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 | |||
| // public void addViewControllers(ViewControllerRegistry registry) { | |||
| // String prePath = swaggerProperties.getPrePath(); | |||
| @@ -1,6 +1,7 @@ | |||
| package com.iformall.config; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| import java.util.ArrayList; | |||
| @@ -61,6 +62,10 @@ public class SwaggerProperties { | |||
| * 联系人信息 | |||
| */ | |||
| private Contact contact = new Contact(); | |||
| /** | |||
| * 全局统一鉴权配置 | |||
| **/ | |||
| private Authorization authorization = new Authorization(); | |||
| @Data | |||
| public static class Contact { | |||
| @@ -76,6 +81,43 @@ public class SwaggerProperties { | |||
| * 联系人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-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: | |||
| name: 张三 | |||
| 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.WxCUserBasicInfoVo; | |||
| import com.iformall.domain.vo.cockpit.CountUserGenderVO; | |||
| import com.iformall.domain.vo.cockpit.MonthDataMapping; | |||
| import org.apache.ibatis.annotations.Param; | |||
| import java.util.List; | |||
| @@ -83,5 +84,14 @@ public interface WxCUserBasicInfoMapper extends CommonMapper<WxCUserBasicInfo, S | |||
| * @return {@link Integer} | |||
| */ | |||
| 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.po.WxUserVisit; | |||
| import com.iformall.domain.vo.TouchUsersReportVo; | |||
| import com.iformall.domain.vo.cockpit.MonthDataMapping; | |||
| import org.apache.ibatis.annotations.Param; | |||
| import java.util.List; | |||
| @@ -17,4 +19,12 @@ public interface WxUserVisitMapper extends CommonMapper<WxUserVisit, Long> { | |||
| List<TouchUsersReportVo> touchUsersReportData(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 | |||
| */ | |||
| public interface CockpitScreenService { | |||
| /** | |||
| * 统计会员性别信息 | |||
| * | |||
| * @param tenantInfo | |||
| * @return {@link CountUserGenderVO} | |||
| */ | |||
| CountUserGenderVO countUserGender(TenantEntity tenantInfo); | |||
| /** | |||
| * 统计商铺租赁信息 | |||
| * | |||
| * @param tenantInfo | |||
| * @return {@link CountShopVO} | |||
| */ | |||
| CountShopVO countShop(TenantEntity tenantInfo); | |||
| /** | |||
| * 统计会员数量信息 | |||
| * | |||
| * @param tenantInfo | |||
| * @param years | |||
| * @return {@link List}<{@link CountMonthVO}> | |||
| */ | |||
| 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); | |||
| } | |||
| @@ -4,14 +4,12 @@ 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.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.EnumUserGender; | |||
| import com.iformall.mapper.WxCUserBasicInfoMapper; | |||
| import com.iformall.mapper.WxShopMapper; | |||
| import com.iformall.mapper.WxUserVisitMapper; | |||
| import com.iformall.service.CockpitScreenService; | |||
| import com.iformall.service.WxCUserBasicInfoService; | |||
| import com.iformall.service.WxMallService; | |||
| @@ -34,14 +32,14 @@ import java.util.stream.Collectors; | |||
| @Service | |||
| public class CockpitScreenServiceImpl implements CockpitScreenService { | |||
| @Autowired | |||
| private WxCUserBasicInfoService cUserBasicInfoService; | |||
| @Autowired | |||
| private WxCUserBasicInfoMapper cUserBasicInfoMapper; | |||
| @Autowired | |||
| private WxMallService wxMallService; | |||
| @Autowired | |||
| private WxShopMapper wxShopMapper; | |||
| @Autowired | |||
| private WxUserVisitMapper wxUserVisitMapper; | |||
| @Override | |||
| public CountUserGenderVO countUserGender(TenantEntity tenantEntity) { | |||
| @@ -106,20 +104,25 @@ public class CockpitScreenServiceImpl implements CockpitScreenService { | |||
| } | |||
| 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; | |||
| } | |||
| @@ -128,6 +131,27 @@ public class CockpitScreenServiceImpl implements CockpitScreenService { | |||
| if (CollectionUtils.isEmpty(years)) { | |||
| 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) { | |||
| if (month < 10) { | |||
| return "0" + String.valueOf(month); | |||
| return "0" + month; | |||
| } else { | |||
| return String.valueOf(month); | |||
| } | |||
| @@ -581,6 +581,21 @@ | |||
| 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} | |||
| </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"> | |||
| @@ -164,5 +164,20 @@ | |||
| and day_date <= #{endTime} | |||
| </if> | |||
| </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> | |||