扫码统计

This commit is contained in:
huzhengkao 2025-07-02 15:34:42 +08:00
parent 62abc4af7e
commit 74c4ec9175
17 changed files with 467 additions and 16 deletions

View File

@ -78,3 +78,23 @@ CREATE TABLE `domestic_drug_production_apply_info` (
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)', `is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='国产药品生产信息数据子集'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='国产药品生产信息数据子集';
CREATE TABLE `enterprise_scan_code_data` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业名称',
`social_credit_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业社会信用代码',
`enterprise_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业类型',
`total_inbound` int NOT NULL COMMENT '累计入库扫码量',
`total_outbound` int NOT NULL COMMENT '累计出库扫码量',
`week_inbound` int NOT NULL COMMENT '近一周入库扫码量',
`week_outbound` int NOT NULL COMMENT '近一周出库扫码量',
`month_inbound` int NOT NULL COMMENT '近一月入库扫码量',
`month_outbound` int NOT NULL COMMENT '近一月出库扫码量',
`scan_ratio` double(10,2) NOT NULL COMMENT '扫码比',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_name` (`name`) USING BTREE,
KEY `idx_social_credit_code` (`social_credit_code`) USING BTREE,
KEY `idx_enterprise_type` (`enterprise_type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='企业扫码统计数据';

View File

@ -4,11 +4,13 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication @SpringBootApplication
// 指定要扫描的Mapper类的包的路径 // 指定要扫描的Mapper类的包的路径
@MapperScan("com.alihealth.d2d.provtest.mapper") @MapperScan("com.alihealth.d2d.provtest.mapper")
@EnableAsync @EnableAsync
@EnableScheduling
public class ProvtestApplication { public class ProvtestApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -24,18 +24,18 @@ public class DataStatisticsController {
private IDataStatisticsService dataStatisticsService; private IDataStatisticsService dataStatisticsService;
@GetMapping("/enterprise/scanCode") // @GetMapping("/enterprise/scanCode")
public AjaxResult pageScanCode( // public AjaxResult pageScanCode(
@RequestParam(defaultValue = "1") Integer current, // @RequestParam(defaultValue = "1") Integer current,
@RequestParam(defaultValue = "10") Integer size, // @RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String name, // @RequestParam(required = false) String name,
@RequestParam(required = false) String socialCreditCode, // @RequestParam(required = false) String socialCreditCode,
@RequestParam(required = false) String type) { // @RequestParam(required = false) String type) {
//
Page<EnterpriseScanCode> page = new Page<>(current, size); // Page<EnterpriseScanCode> page = new Page<>(current, size);
Page<EnterpriseScanCode> result = dataStatisticsService.pageScanCode(page, name, socialCreditCode,type); // Page<EnterpriseScanCode> result = dataStatisticsService.pageScanCode(page, name, socialCreditCode,type);
//
return AjaxResult.success(result); // return AjaxResult.success(result);
} // }
} }

View File

@ -0,0 +1,29 @@
package com.alihealth.d2d.provtest.controller;
import com.alihealth.d2d.provtest.common.AjaxResult;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.alihealth.d2d.provtest.searcher.EnterpriseScanCodeDataSearcher;
import com.alihealth.d2d.provtest.service.IEnterpriseScanCodeDataService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
/**
* @author Jason
* @date 2025年07月01日 10:40:02
*/
@RestController
@RequestMapping("enterpriseScanCodeData")
public class EnterpriseScanCodeDataController {
@Autowired
private IEnterpriseScanCodeDataService enterpriseScanCodeDataService;
@GetMapping("/pageData")
public AjaxResult pageScanCode(@ModelAttribute EnterpriseScanCodeDataSearcher searcher) {
return AjaxResult.success(enterpriseScanCodeDataService.pageData(searcher));
}
}

View File

@ -0,0 +1,93 @@
package com.alihealth.d2d.provtest.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 企业扫码统计数据
* </p>
*
* @author Jason
* @since 2025-07-01
*/
@Getter
@Setter
@TableName("enterprise_scan_code_data")
public class EnterpriseScanCodeData implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 企业名称
*/
private String name;
/**
* 企业社会信用代码
*/
private String socialCreditCode;
/**
* 企业类型
*/
private String enterpriseType;
/**
* 累计入库扫码量
*/
private Integer totalInbound;
/**
* 累计出库扫码量
*/
private Integer totalOutbound;
/**
* 近一周入库扫码量
*/
private Integer weekInbound;
/**
* 近一周出库扫码量
*/
private Integer weekOutbound;
/**
* 近一月入库扫码量
*/
private Integer monthInbound;
/**
* 近一月出库扫码量
*/
private Integer monthOutbound;
/**
* 扫码比
*/
private Double scanRatio;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@ -13,8 +13,8 @@ import java.nio.file.Paths;
public class CodeGenerator { public class CodeGenerator {
public static void main(String[] args) { public static void main(String[] args) {
String tables="multy_sacn_code_record";// 生成多个指定表,逗号分隔 String tables="enterprise_scan_code_data";// 生成多个指定表,逗号分隔
FastAutoGenerator.create("jdbc:mysql://192.168.200.45:3306/supervisionx_trace_data", "supervision", "vtHe%$zvtHeQP") FastAutoGenerator.create("jdbc:mysql://47.109.202.121:3306/supervisionx_trace_data", "root", "TCCT3.1415926")
.globalConfig(builder -> builder .globalConfig(builder -> builder
.author("Jason") .author("Jason")
.outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java") .outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java")

View File

@ -1,7 +1,12 @@
package com.alihealth.d2d.provtest.mapper; package com.alihealth.d2d.provtest.mapper;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.alihealth.d2d.provtest.domain.PharmaceuticalTradingEnterprisesBaseInfo;
import com.alihealth.d2d.provtest.domain.vo.EnterpriseScanCode; import com.alihealth.d2d.provtest.domain.vo.EnterpriseScanCode;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/** /**
* @author Jason * @author Jason
@ -9,4 +14,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
*/ */
public interface DataStatisticsMapper { public interface DataStatisticsMapper {
Page<EnterpriseScanCode> pageScanCode(Page<EnterpriseScanCode> page, String name, String socialCreditCode, String type); Page<EnterpriseScanCode> pageScanCode(Page<EnterpriseScanCode> page, String name, String socialCreditCode, String type);
// 自定义查询加处理重复
@Select("SELECT tyshxydm, MAX(qymc) AS qymc, MAX(qylx) AS qylx FROM pharmaceutical_trading_enterprises_base_info GROUP BY tyshxydm")
List<PharmaceuticalTradingEnterprisesBaseInfo> selectDistinctEnterprises();
EnterpriseScanCodeData getDataStatistics(String tyshxydm);
} }

View File

@ -0,0 +1,18 @@
package com.alihealth.d2d.provtest.mapper;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* <p>
* 企业扫码统计数据 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-07-01
*/
public interface EnterpriseScanCodeDataMapper extends BaseMapper<EnterpriseScanCodeData> {
Page<EnterpriseScanCodeData> pageScanCode(Page<EnterpriseScanCodeData> page, String name, String socialCreditCode, String type);
}

View File

@ -0,0 +1,13 @@
package com.alihealth.d2d.provtest.searcher;
import lombok.Data;
/**
* @author Jason
* @date 2025年07月01日 10:46:47
*/
@Data
public class BaseSearcher {
private Integer current=1;
private Integer size=10;
}

View File

@ -0,0 +1,15 @@
package com.alihealth.d2d.provtest.searcher;
import lombok.Data;
/**
* @author Jason
* @date 2025年07月01日 10:44:20
*/
@Data
public class EnterpriseScanCodeDataSearcher extends BaseSearcher {
private String name;
private String socialCreditCode;
private String enterpriseType;
}

View File

@ -1,11 +1,19 @@
package com.alihealth.d2d.provtest.service; package com.alihealth.d2d.provtest.service;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.alihealth.d2d.provtest.domain.PharmaceuticalTradingEnterprisesBaseInfo;
import com.alihealth.d2d.provtest.domain.vo.EnterpriseScanCode; import com.alihealth.d2d.provtest.domain.vo.EnterpriseScanCode;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
/** /**
* 数据统计 * 数据统计
*/ */
public interface IDataStatisticsService { public interface IDataStatisticsService {
Page<EnterpriseScanCode> pageScanCode(Page<EnterpriseScanCode> page, String name, String socialCreditCode,String type); Page<EnterpriseScanCode> pageScanCode(Page<EnterpriseScanCode> page, String name, String socialCreditCode,String type);
List<PharmaceuticalTradingEnterprisesBaseInfo> selectDistinctEnterprises();
EnterpriseScanCodeData getDataStatistics(String tyshxydm);
} }

View File

@ -0,0 +1,19 @@
package com.alihealth.d2d.provtest.service;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.alihealth.d2d.provtest.searcher.EnterpriseScanCodeDataSearcher;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 企业扫码统计数据 服务类
* </p>
*
* @author Jason
* @since 2025-07-01
*/
public interface IEnterpriseScanCodeDataService extends IService<EnterpriseScanCodeData> {
Page<EnterpriseScanCodeData> pageData(EnterpriseScanCodeDataSearcher searcher);
}

View File

@ -1,5 +1,7 @@
package com.alihealth.d2d.provtest.service.impl; package com.alihealth.d2d.provtest.service.impl;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.alihealth.d2d.provtest.domain.PharmaceuticalTradingEnterprisesBaseInfo;
import com.alihealth.d2d.provtest.domain.vo.EnterpriseScanCode; import com.alihealth.d2d.provtest.domain.vo.EnterpriseScanCode;
import com.alihealth.d2d.provtest.mapper.DataStatisticsMapper; import com.alihealth.d2d.provtest.mapper.DataStatisticsMapper;
import com.alihealth.d2d.provtest.service.IDataStatisticsService; import com.alihealth.d2d.provtest.service.IDataStatisticsService;
@ -7,6 +9,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/** /**
* @author Jason * @author Jason
* @date 2025年06月13日 15:35:30 * @date 2025年06月13日 15:35:30
@ -21,4 +26,14 @@ public class DataStatisticsServiceImpl implements IDataStatisticsService {
public Page<EnterpriseScanCode> pageScanCode(Page<EnterpriseScanCode> page, String name, String socialCreditCode, String type) { public Page<EnterpriseScanCode> pageScanCode(Page<EnterpriseScanCode> page, String name, String socialCreditCode, String type) {
return dataStatisticsMapper.pageScanCode(page, name, socialCreditCode, type); return dataStatisticsMapper.pageScanCode(page, name, socialCreditCode, type);
} }
@Override
public List<PharmaceuticalTradingEnterprisesBaseInfo> selectDistinctEnterprises() {
return dataStatisticsMapper.selectDistinctEnterprises();
}
@Override
public EnterpriseScanCodeData getDataStatistics(String tyshxydm) {
return dataStatisticsMapper.getDataStatistics(tyshxydm);
}
} }

View File

@ -0,0 +1,48 @@
package com.alihealth.d2d.provtest.service.impl;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.alihealth.d2d.provtest.mapper.EnterpriseScanCodeDataMapper;
import com.alihealth.d2d.provtest.searcher.EnterpriseScanCodeDataSearcher;
import com.alihealth.d2d.provtest.service.IEnterpriseScanCodeDataService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>
* 企业扫码统计数据 服务实现类
* </p>
*
* @author Jason
* @since 2025-07-01
*/
@Service
public class EnterpriseScanCodeDataServiceImpl extends ServiceImpl<EnterpriseScanCodeDataMapper, EnterpriseScanCodeData> implements IEnterpriseScanCodeDataService {
@Autowired
private EnterpriseScanCodeDataMapper enterpriseScanCodeDataMapper;
@Override
public Page<EnterpriseScanCodeData> pageData(EnterpriseScanCodeDataSearcher searcher) {
Page<EnterpriseScanCodeData> page = new Page<>(searcher.getCurrent(), searcher.getSize());
QueryWrapper<EnterpriseScanCodeData> wrapper = new QueryWrapper<>();
// 条件构造
if (StringUtils.isNotBlank(searcher.getName())) {
wrapper.like("name", searcher.getName());
}
if (StringUtils.isNotBlank(searcher.getSocialCreditCode())) {
wrapper.eq("social_credit_code", searcher.getSocialCreditCode());
}
if (StringUtils.isNotBlank(searcher.getEnterpriseType())) {
wrapper.eq("enterprise_type", searcher.getEnterpriseType());
}
// 排序
wrapper.orderByDesc("create_time");
return enterpriseScanCodeDataMapper.selectPage(page, wrapper);
}
}

View File

@ -0,0 +1,120 @@
package com.alihealth.d2d.provtest.task;
import com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData;
import com.alihealth.d2d.provtest.domain.PharmaceuticalTradingEnterprisesBaseInfo;
import com.alihealth.d2d.provtest.service.IDataStatisticsService;
import com.alihealth.d2d.provtest.service.IEnterpriseScanCodeDataService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.sql.Wrapper;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Jason
* @date 2025年07月01日 11:52:46
*/
@Component
public class ScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
@Autowired
private IDataStatisticsService dataStatisticsService;
@Autowired
private IEnterpriseScanCodeDataService enterpriseScanCodeDataService;
// 每天凌晨00:00:00执行
@Scheduled(cron = "0 0 0 * * ?")
//@Scheduled(cron = "0 20 14 * * ?") // 每天上午14:20执行
public void taskScanCodeData() {
log.info("taskScanCodeData - 执行开始时间: {}", LocalDateTime.now());
long startTime = System.currentTimeMillis();
try {
// 执行任务
initialFullStatistics();
} finally {
long endTime = System.currentTimeMillis();
log.info("taskScanCodeData - 执行完成时间: {}", LocalDateTime.now());
log.info("任务执行耗时: {} 毫秒", endTime - startTime);
}
}
// 1.企业扫码量统计
public void initialFullStatistics() {
//查询所有企业信息
List<PharmaceuticalTradingEnterprisesBaseInfo> enterprises=dataStatisticsService.selectDistinctEnterprises();
List<EnterpriseScanCodeData> insertList=new ArrayList<>();//插入数据
List<EnterpriseScanCodeData> updateList=new ArrayList<>();//更新数据
enterprises.forEach(enterprise -> {
String socialCreditCode = enterprise.getTyshxydm();
EnterpriseScanCodeData dataExist = enterpriseScanCodeDataService.lambdaQuery()
.eq(EnterpriseScanCodeData::getSocialCreditCode, socialCreditCode)
.one();
EnterpriseScanCodeData statisticData= dataStatisticsService.getDataStatistics(enterprise.getTyshxydm());//数据统计
if(dataExist!=null){//企业存在统计数据 更新
boolean changed = false;
if (dataExist.getTotalInbound() != statisticData.getTotalInbound()) {
dataExist.setTotalInbound(statisticData.getTotalInbound());
changed = true;
}
if (dataExist.getTotalOutbound() != statisticData.getTotalOutbound()) {
dataExist.setTotalOutbound(statisticData.getTotalOutbound());
changed = true;
}
if (dataExist.getWeekInbound() != statisticData.getWeekInbound()) {
dataExist.setWeekInbound(statisticData.getWeekInbound());
changed = true;
}
if (dataExist.getWeekOutbound() != statisticData.getWeekOutbound()) {
dataExist.setWeekOutbound(statisticData.getWeekOutbound());
changed = true;
}
if (dataExist.getMonthInbound() != statisticData.getMonthInbound()) {
dataExist.setMonthInbound(statisticData.getMonthInbound());
changed = true;
}
if (dataExist.getMonthOutbound() != statisticData.getMonthOutbound()) {
dataExist.setMonthOutbound(statisticData.getMonthOutbound());
changed = true;
}
if (changed) {
dataExist.setUpdateTime(LocalDateTime.now());
updateList.add(dataExist);
}
}else{//插入数据
statisticData.setName(enterprise.getQymc());
statisticData.setSocialCreditCode(socialCreditCode);
statisticData.setEnterpriseType(enterprise.getQylx());
insertList.add(statisticData);
}
});
if(!CollectionUtils.isEmpty(insertList)){
enterpriseScanCodeDataService.saveBatch(insertList);
}
if(!CollectionUtils.isEmpty(updateList)){
enterpriseScanCodeDataService.updateBatchById(updateList);
}
log.info("企业扫码量统计完成,入库企业数统计={},更新企业数统计={}",insertList.size(),updateList.size());
}
}

View File

@ -49,5 +49,36 @@
ON sc.tyshxydm = o.tyshxydmfhjg; ON sc.tyshxydm = o.tyshxydmfhjg;
</select> </select>
<select id="getDataStatistics" resultType="com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData">
SELECT
d.total_inbound,
d.week_inbound,
d.month_inbound,
i.total_outbound,
i.week_outbound,
i.month_outbound,
CASE
WHEN i.total_outbound = 0 THEN 0
ELSE ROUND(d.total_inbound * 1.0 / i.total_outbound, 2)
END AS scan_ratio
FROM (
SELECT
COUNT(DISTINCT ypzsm) AS total_inbound,
COUNT(DISTINCT CASE WHEN shsj >= DATE_SUB(NOW(), INTERVAL 7 DAY) THEN ypzsm END) AS week_inbound,
COUNT(DISTINCT CASE WHEN shsj >= DATE_SUB(NOW(), INTERVAL 30 DAY) THEN ypzsm END) AS month_inbound
FROM drug_delivery_note_apply_info
WHERE tyshxydmshjg = #{tyshxydm}
) d
CROSS JOIN (
SELECT
COUNT(DISTINCT ypzsm) AS total_outbound,
COUNT(DISTINCT CASE WHEN fhsj >= DATE_SUB(NOW(), INTERVAL 7 DAY) THEN ypzsm END) AS week_outbound,
COUNT(DISTINCT CASE WHEN fhsj >= DATE_SUB(NOW(), INTERVAL 30 DAY) THEN ypzsm END) AS month_outbound
FROM drug_invoice_apply_info
WHERE tyshxydmfhjg = #{tyshxydm}
) i
</select>
</mapper> </mapper>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alihealth.d2d.provtest.mapper.EnterpriseScanCodeDataMapper">
<select id="pageScanCode" resultType="com.alihealth.d2d.provtest.domain.EnterpriseScanCodeData">
</select>
</mapper>