|
@@ -0,0 +1,396 @@
|
|
|
+package com.slodon.b2b2c.controller.statistics.screen;
|
|
|
+
|
|
|
+import com.slodon.b2b2c.core.constant.GoodsConst;
|
|
|
+import com.slodon.b2b2c.core.constant.StoreConst;
|
|
|
+import com.slodon.b2b2c.core.controller.BaseController;
|
|
|
+import com.slodon.b2b2c.core.response.JsonResult;
|
|
|
+import com.slodon.b2b2c.core.response.PageVO;
|
|
|
+import com.slodon.b2b2c.core.response.PagerInfo;
|
|
|
+import com.slodon.b2b2c.core.response.SldResponse;
|
|
|
+import com.slodon.b2b2c.core.util.StringUtil;
|
|
|
+import com.slodon.b2b2c.core.util.WebUtil;
|
|
|
+import com.slodon.b2b2c.enums.ProvinceJson;
|
|
|
+import com.slodon.b2b2c.enums.StatsTimeType;
|
|
|
+import com.slodon.b2b2c.enums.WebSiteConstant;
|
|
|
+import com.slodon.b2b2c.goods.example.GoodsExample;
|
|
|
+import com.slodon.b2b2c.member.example.MemberExample;
|
|
|
+import com.slodon.b2b2c.member.pojo.MemberEnquiry;
|
|
|
+import com.slodon.b2b2c.model.goods.GoodsExtendModel;
|
|
|
+import com.slodon.b2b2c.model.goods.GoodsModel;
|
|
|
+import com.slodon.b2b2c.model.goods.GoodsSearchWordsModel;
|
|
|
+import com.slodon.b2b2c.model.member.MemberModel;
|
|
|
+import com.slodon.b2b2c.model.member.advich.MemberEnquiryModel;
|
|
|
+import com.slodon.b2b2c.model.seller.StoreModel;
|
|
|
+import com.slodon.b2b2c.model.statistics.StoreDayModel;
|
|
|
+import com.slodon.b2b2c.seller.dto.StoreStatisticsDTO;
|
|
|
+import com.slodon.b2b2c.seller.example.StoreExample;
|
|
|
+import com.slodon.b2b2c.statistics.example.StoreDayExample;
|
|
|
+import com.slodon.b2b2c.statistics.pojo.base.StoreBase;
|
|
|
+import com.slodon.b2b2c.util.StatsModelUtil;
|
|
|
+import com.slodon.b2b2c.vo.statistics.*;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiImplicitParam;
|
|
|
+import io.swagger.annotations.ApiImplicitParams;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.web.bind.annotation.GetMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestParam;
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+@Api(tags = "screen-大屏")
|
|
|
+@RestController
|
|
|
+@RequestMapping("v3/statistics/screen/analysis")
|
|
|
+public class ScreenAnalysisController extends BaseController {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private StatsModelUtil statsModelUtil;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MemberEnquiryModel memberEnquiryModel;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MemberModel memberModel;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private StoreModel storeModel;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private GoodsModel goodsModel;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private StoreDayModel storeDayModel;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private GoodsSearchWordsModel goodsSearchWordsModel;
|
|
|
+ @ApiOperation("流量趋势")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
|
|
|
+ @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
|
|
|
+ })
|
|
|
+ @GetMapping("flowTrend")
|
|
|
+ public JsonResult<ScreenFlowTrendVO> flowTrend(HttpServletRequest request, Date startTime, Date endTime) {
|
|
|
+ StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, true);
|
|
|
+ ScreenFlowTrendVO vo = new ScreenFlowTrendVO();
|
|
|
+
|
|
|
+ // 处理海外用户数据
|
|
|
+ List<MovableGoodsVO> overseasList = statsModelUtil.getPlatformTrendList(
|
|
|
+ timeType, startTime, endTime, WebSiteConstant.MEMBER_OVERSEA);
|
|
|
+
|
|
|
+ List<ScreenFlowTrendVO.VisitorNumVO> visitorNumList = new ArrayList<>();
|
|
|
+ List<ScreenFlowTrendVO.ViewNumVO> viewNumList = new ArrayList<>();
|
|
|
+
|
|
|
+ populateVisitorAndViewData(overseasList, visitorNumList, viewNumList);
|
|
|
+
|
|
|
+ vo.setVisitorNumList(visitorNumList);
|
|
|
+ vo.setViewNumList(viewNumList);
|
|
|
+
|
|
|
+ // 处理分销商数据
|
|
|
+ List<MovableGoodsVO> distributorList = statsModelUtil.getPlatformTrendList(
|
|
|
+ timeType, startTime, endTime, WebSiteConstant.MEMBER_DISTRIBUTOR);
|
|
|
+
|
|
|
+ List<ScreenFlowTrendVO.VisitorNumVO> visitorCNNumList = new ArrayList<>();
|
|
|
+ List<ScreenFlowTrendVO.ViewNumVO> viewNumCNList = new ArrayList<>();
|
|
|
+
|
|
|
+ populateVisitorAndViewData(distributorList, visitorCNNumList, viewNumCNList);
|
|
|
+
|
|
|
+ vo.setVisitorNumCNList(visitorCNNumList);
|
|
|
+ vo.setViewNumCNList(viewNumCNList);
|
|
|
+
|
|
|
+ return SldResponse.success(vo);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void populateVisitorAndViewData(List<MovableGoodsVO> list,
|
|
|
+ List<ScreenFlowTrendVO.VisitorNumVO> visitorList,
|
|
|
+ List<ScreenFlowTrendVO.ViewNumVO> viewList) {
|
|
|
+ if (!CollectionUtils.isEmpty(list)) {
|
|
|
+ list.forEach(trendVO -> {
|
|
|
+ // 访客数
|
|
|
+ ScreenFlowTrendVO.VisitorNumVO visitorNumVO = new ScreenFlowTrendVO.VisitorNumVO();
|
|
|
+ visitorNumVO.setStatsTime(trendVO.getStatsTime());
|
|
|
+ visitorNumVO.setVisitorNum(trendVO.getVisitorNum());
|
|
|
+ visitorList.add(visitorNumVO);
|
|
|
+
|
|
|
+ // 访问量
|
|
|
+ ScreenFlowTrendVO.ViewNumVO viewNumVO = new ScreenFlowTrendVO.ViewNumVO();
|
|
|
+ viewNumVO.setStatsTime(trendVO.getStatsTime());
|
|
|
+ viewNumVO.setViewNum(trendVO.getViewNum());
|
|
|
+ viewList.add(viewNumVO);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 询盘趋势
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param startTime
|
|
|
+ * @param endTime
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("enquiryTrend")
|
|
|
+ public JsonResult<ScreenEnquiryTrendVO> getEnquiryTrend(HttpServletRequest request, Date startTime, Date endTime) throws Exception {
|
|
|
+ ScreenEnquiryTrendVO vo = new ScreenEnquiryTrendVO();
|
|
|
+
|
|
|
+ if (startTime != null && endTime != null) {
|
|
|
+ StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, true);
|
|
|
+
|
|
|
+ // 处理海外用户询盘数据
|
|
|
+ List<MemberEnquiry> overseasList = memberEnquiryModel.getAdminEnquiryTrendList(
|
|
|
+ timeType, startTime, endTime, WebSiteConstant.MEMBER_OVERSEA);
|
|
|
+ List<ScreenEnquiryTrendVO.EnquiryNumVO> enquiryNumVOList = new ArrayList<>();
|
|
|
+ populateEnquiryData(overseasList, enquiryNumVOList);
|
|
|
+ vo.setEnquiryTrendList(enquiryNumVOList);
|
|
|
+
|
|
|
+ // 处理分销商询盘数据
|
|
|
+ List<MemberEnquiry> distributorList = memberEnquiryModel.getAdminEnquiryTrendList(
|
|
|
+ timeType, startTime, endTime, WebSiteConstant.MEMBER_DISTRIBUTOR);
|
|
|
+ List<ScreenEnquiryTrendVO.EnquiryNumVO> enquiryNumVOCNList = new ArrayList<>();
|
|
|
+ populateEnquiryData(distributorList, enquiryNumVOCNList);
|
|
|
+ vo.setEnquiryTrendCNList(enquiryNumVOCNList);
|
|
|
+ }
|
|
|
+
|
|
|
+ return SldResponse.success(vo);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void populateEnquiryData(List<MemberEnquiry> list, List<ScreenEnquiryTrendVO.EnquiryNumVO> targetList) {
|
|
|
+ if (!CollectionUtils.isEmpty(list)) {
|
|
|
+ list.forEach(memberEnquiry -> {
|
|
|
+ ScreenEnquiryTrendVO.EnquiryNumVO enquiryNumVO = new ScreenEnquiryTrendVO.EnquiryNumVO();
|
|
|
+ enquiryNumVO.setStatsTime(memberEnquiry.getEnquiryDay());
|
|
|
+ enquiryNumVO.setViewNum(memberEnquiry.getEnquiryNum());
|
|
|
+ targetList.add(enquiryNumVO);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 询盘地域分布
|
|
|
+ * @param request
|
|
|
+ * @param webSite
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("enquiryDistribution")
|
|
|
+ @ApiOperation("询盘地域分布")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "webSite", value = "站点"),
|
|
|
+ })
|
|
|
+ public JsonResult<List<ScreenEnquiryDistribution>> getEnquiryDistribution(HttpServletRequest request, @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite) {
|
|
|
+ return SldResponse.success(memberEnquiryModel.getEnquiryDistribution(webSite));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("供应链企业分布")
|
|
|
+ @GetMapping("regionDistribution")
|
|
|
+ public JsonResult<List<ProvincePercentVO>> regionDistribution(HttpServletRequest request) {
|
|
|
+ StoreExample example = new StoreExample();
|
|
|
+ example.setStateNotEquals(StoreConst.STORE_STATE_DELETE);
|
|
|
+ example.setOrderBy("storeNum DESC");
|
|
|
+ List<StoreStatisticsDTO> list = storeModel.getStoreStatisticList(example);
|
|
|
+ List<ProvincePercentVO> vos = getRegionDistributionPercent(list);
|
|
|
+ return SldResponse.success(vos);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 地域分布
|
|
|
+ *
|
|
|
+ * @param list
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<ProvincePercentVO> getRegionDistributionPercent(List<StoreStatisticsDTO> list) {
|
|
|
+ List<ProvincePercentVO> result = new ArrayList<>();
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ //查询总店铺数,用于计算各省份占比
|
|
|
+ StoreExample example = new StoreExample();
|
|
|
+ example.setStateNotEquals(StoreConst.STORE_STATE_DELETE);
|
|
|
+ int totalNum = storeModel.getStoreCount(example);
|
|
|
+ //key为省份名称,value为店铺数量
|
|
|
+ Map<String, Integer> dataMap = new HashMap<>();
|
|
|
+ for (StoreStatisticsDTO dto : list) {
|
|
|
+ String provinceCode = dto.getProvinceCode();
|
|
|
+ //如果编码为空,按未知处理
|
|
|
+ if (StringUtil.isEmpty(dto.getProvinceCode())) {
|
|
|
+ provinceCode = ProvinceJson.defaultProvinceCode;
|
|
|
+ }
|
|
|
+ //如果省份为空,按未知处理
|
|
|
+ String provinceName = ProvinceJson.provinceMap.getOrDefault(provinceCode, ProvinceJson.defaultProvinceName);
|
|
|
+ //店铺数量
|
|
|
+ Integer storeNum = dto.getStoreNum();
|
|
|
+ if (dataMap.containsKey(provinceName)) {
|
|
|
+ dataMap.put(provinceName, dataMap.get(provinceName) + storeNum);
|
|
|
+ } else {
|
|
|
+ dataMap.put(provinceName, storeNum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Map.Entry<String, Integer>> mapList = new ArrayList<>(dataMap.entrySet());
|
|
|
+ //排序
|
|
|
+ Collections.sort(mapList, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
|
|
|
+ //只取前5个省份数据
|
|
|
+ int count = 0;
|
|
|
+ int otherNum = totalNum;
|
|
|
+ for (Map.Entry<String, Integer> entry : mapList) {
|
|
|
+ if (count >= 5) {
|
|
|
+ //累加第5名之后的所有店铺数量到"其他"
|
|
|
+ otherNum -= entry.getValue();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ ProvincePercentVO vo = new ProvincePercentVO();
|
|
|
+ vo.setProvinceName(entry.getKey());
|
|
|
+ vo.setStoreNum(entry.getValue());
|
|
|
+ result.add(vo);
|
|
|
+ //数据计算
|
|
|
+ otherNum -= entry.getValue();
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+
|
|
|
+ //如果有其他省份数据,添加"其他"项
|
|
|
+ if (otherNum > 0 && mapList.size() > 5) {
|
|
|
+ ProvincePercentVO vo = new ProvincePercentVO();
|
|
|
+ vo.setProvinceName("其他");
|
|
|
+ vo.setStoreNum(otherNum);
|
|
|
+ result.add(vo);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 平台数据汇总
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("data/summary")
|
|
|
+ @ApiOperation("平台数据汇总")
|
|
|
+ public JsonResult<ScreenDataSummary> getDataSummary(HttpServletRequest request) {
|
|
|
+ ScreenDataSummary vo = new ScreenDataSummary();
|
|
|
+ MemberExample memberExample = new MemberExample();
|
|
|
+ memberExample.setWebSite(WebSiteConstant.MEMBER_OVERSEA);
|
|
|
+ vo.setMemberNum(memberModel.getMemberCount(memberExample));
|
|
|
+ memberExample.setWebSite(WebSiteConstant.MEMBER_DISTRIBUTOR);
|
|
|
+ vo.setDistributorNum(memberModel.getMemberCount(memberExample));
|
|
|
+ StoreExample storeExample = new StoreExample();
|
|
|
+ storeExample.setStateNotEquals(StoreConst.STORE_STATE_DELETE);
|
|
|
+ vo.setStoreNum(storeModel.getStoreCount(storeExample));
|
|
|
+ GoodsExample goodsExample = new GoodsExample();
|
|
|
+ goodsExample.setWebSite(WebSiteConstant.MEMBER_OVERSEA);
|
|
|
+ goodsExample.setStateNotEquals(GoodsConst.GOODS_STATE_DELETE);
|
|
|
+ vo.setProductNum(goodsModel.getGoodsCount(goodsExample));
|
|
|
+ vo.setServiceProviderNum(999);
|
|
|
+ return SldResponse.success(vo);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 会员地域分布
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("memberDistribution")
|
|
|
+ @ApiOperation("会员地域分布")
|
|
|
+ public JsonResult<List<ScreenMemberDistribution>> getMemberDistribution(HttpServletRequest request,@RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite) {
|
|
|
+ return SldResponse.success(memberModel.getMemberDistribution(webSite));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 会员新增趋势
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("memberTrend")
|
|
|
+ @ApiOperation("会员新增趋势")
|
|
|
+ public JsonResult<List<ScreenMemberTrendVO>> memberTrend(HttpServletRequest request,@RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite) {
|
|
|
+ return SldResponse.success(memberModel.getMemberTrend(webSite));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 商品新增趋势
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("goodsTrend")
|
|
|
+ @ApiOperation("商品新增趋势")
|
|
|
+ public JsonResult<List<ScreenGoodsTrendVO>> goodsTrend(HttpServletRequest request,@RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite) {
|
|
|
+ return SldResponse.success(goodsModel.getGoodsTrend(webSite));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 搜索词排行
|
|
|
+ * @param request
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @GetMapping("searchRank")
|
|
|
+ @ApiOperation("搜索词排行")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
|
|
|
+ @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
|
|
|
+ @ApiImplicitParam(name = "type", value = "排序类型;desc-降序;asc-升序;默认类型为降序"),
|
|
|
+ @ApiImplicitParam(name = "webSite", value = "站点"),
|
|
|
+ })
|
|
|
+ public JsonResult<List<String>> searchRank(HttpServletRequest request, Date startTime, Date endTime,
|
|
|
+ @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
|
|
|
+ @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
|
|
|
+ @RequestParam(value = "pageSize", required =false,defaultValue = "10") Integer pageSize,
|
|
|
+ @RequestParam(value = "current", required =false,defaultValue = "1") Integer current) {
|
|
|
+ PagerInfo pager = new PagerInfo(pageSize, current);
|
|
|
+ List<String> list = goodsSearchWordsModel.getSearchWordsRank(startTime, endTime, type, webSite, pager);
|
|
|
+ return SldResponse.success(list);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 店铺流量排行
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param startTime
|
|
|
+ * @param endTime
|
|
|
+ * @param type
|
|
|
+ * @param webSite
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ApiOperation("店铺流量排行")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
|
|
|
+ @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
|
|
|
+ @ApiImplicitParam(name = "type", value = "排序类型;desc-降序;asc-升序;默认类型为降序"),
|
|
|
+ @ApiImplicitParam(name = "sort", value = "排序:viewNum-店铺浏览量;visitorNum-店铺访客数"),
|
|
|
+ @ApiImplicitParam(name = "webSite", value = "站点"),
|
|
|
+ })
|
|
|
+ @GetMapping("storeFlowRank")
|
|
|
+ public JsonResult<PageVO<StoreReportVO>> storeFlowRank(HttpServletRequest request, Date startTime, Date endTime,
|
|
|
+ @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
|
|
|
+ @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
|
|
|
+ @RequestParam(value = "pageSize", required =false,defaultValue = "10") Integer pageSize,
|
|
|
+ @RequestParam(value = "current", required =false,defaultValue = "1") Integer current) {
|
|
|
+ PagerInfo pager = new PagerInfo(pageSize, current);
|
|
|
+ StoreDayExample example = new StoreDayExample();
|
|
|
+ example.setWebSite(webSite);
|
|
|
+ example.setStatsTimeAfter(startTime);
|
|
|
+ example.setStatsTimeBefore(endTime);
|
|
|
+ example.setOrderBy("viewNum " + type + " ,visitorNum " + type);
|
|
|
+ List<StoreBase> list = storeDayModel.getStoreList(example, pager);
|
|
|
+ List<StoreReportVO> vos = new ArrayList<>();
|
|
|
+ if (!CollectionUtils.isEmpty(list)) {
|
|
|
+ list.forEach(storeBase -> {
|
|
|
+ vos.add(new StoreReportVO(storeBase));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return SldResponse.success(new PageVO<>(vos, pager));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|