diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/dto/HomeStatisticsDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/dto/HomeStatisticsDto.java index 36a7b79b7..9e8b35173 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/dto/HomeStatisticsDto.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/dto/HomeStatisticsDto.java @@ -39,6 +39,16 @@ public class HomeStatisticsDto { * 相对前日变化百分比 */ private Double revenueTrend; + + /** + * 今日收入金额(数值,单位:元) + */ + private java.math.BigDecimal todayRevenueAmount; + + /** + * 昨日收入金额(数值,单位:元) + */ + private java.math.BigDecimal yesterdayRevenueAmount; /** * 今日预约数量 @@ -69,4 +79,19 @@ public class HomeStatisticsDto { * 待写病历数量 */ private Integer pendingEmr; -} + + /** + * 今日处方数量 + */ + private Integer todayPrescriptions; + + /** + * 昨日处方数量 + */ + private Integer yesterdayPrescriptions; + + /** + * 处方相对前日变化百分比 + */ + private Double prescriptionTrend; +} \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/service/impl/HomeStatisticsServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/service/impl/HomeStatisticsServiceImpl.java index c46a6c878..acc67f090 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/service/impl/HomeStatisticsServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/service/impl/HomeStatisticsServiceImpl.java @@ -13,7 +13,16 @@ import com.openhis.administration.service.IPatientService; import com.openhis.administration.service.IPractitionerService; import com.openhis.common.enums.ParticipantType; import com.openhis.web.dto.HomeStatisticsDto; +import com.openhis.financial.domain.PaymentReconciliation; +import com.openhis.financial.service.IPaymentReconciliationService; +import com.openhis.medication.domain.MedicationRequest; +import com.openhis.medication.service.IMedicationRequestService; +import com.openhis.common.enums.PaymentStatus; import com.openhis.web.service.IHomeStatisticsService; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; import com.openhis.web.patientmanage.mapper.PatientManageMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -46,6 +55,12 @@ public class HomeStatisticsServiceImpl implements IHomeStatisticsService { @Autowired private IPatientService patientService; + @Autowired + private IPaymentReconciliationService paymentReconciliationService; + + @Autowired + private IMedicationRequestService medicationRequestService; + /** * 获取首页统计数据 * @@ -105,18 +120,108 @@ public class HomeStatisticsServiceImpl implements IHomeStatisticsService { double patientTrend = calculateTrend(totalPatients, yesterdayPatients); statistics.setPatientTrend(patientTrend); - // 今日收入和预约等其他统计(暂时设为0,后续从相应表查询) - statistics.setTodayRevenue("¥ 0"); - statistics.setYesterdayRevenue("¥ 0"); - statistics.setRevenueTrend(0.0); + // 查询今日收入 + BigDecimal todayRevenue = queryRevenueByDate(new Date()); + BigDecimal yesterdayRevenue = queryRevenueByDate(getYesterday()); + java.text.DecimalFormat df = new java.text.DecimalFormat("#,##0.00"); + statistics.setTodayRevenue("¥ " + df.format(todayRevenue)); + statistics.setYesterdayRevenue("¥ " + df.format(yesterdayRevenue)); + statistics.setTodayRevenueAmount(todayRevenue); + statistics.setYesterdayRevenueAmount(yesterdayRevenue); + statistics.setRevenueTrend(calculateTrend(todayRevenue.doubleValue(), yesterdayRevenue.doubleValue())); + + // 今日预约和待审核(暂时设为0,后续实现) statistics.setTodayAppointments(0); statistics.setYesterdayAppointments(0); statistics.setAppointmentTrend(0.0); statistics.setPendingApprovals(0); + + // 查询今日处方数量 + int todayPrescriptions = queryPrescriptionCountByDate(new Date(), practitioner); + int yesterdayPrescriptions = queryPrescriptionCountByDate(getYesterday(), practitioner); + statistics.setTodayPrescriptions(todayPrescriptions); + statistics.setYesterdayPrescriptions(yesterdayPrescriptions); + statistics.setPrescriptionTrend(calculateTrend(todayPrescriptions, yesterdayPrescriptions)); + return statistics; } + /** + * 查询指定日期的处方数量 + * + * @param date 日期 + * @param practitioner 当前医生(null 则查全部) + * @return 处方数量 + */ + private int queryPrescriptionCountByDate(Date date, Practitioner practitioner) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + Date dayStart = cal.getTime(); + + cal.add(Calendar.DAY_OF_MONTH, 1); + Date dayEnd = cal.getTime(); + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.ge(MedicationRequest::getCreateTime, dayStart) + .lt(MedicationRequest::getCreateTime, dayEnd) + .eq(MedicationRequest::getDeleteFlag, "0"); + + // 如果是医生角色,只统计自己开的处方 + if (practitioner != null) { + query.eq(MedicationRequest::getPractitionerId, practitioner.getId()); + } + + return (int) medicationRequestService.count(query); + } + + /** + * 查询指定日期的收款总额(状态为支付成功且未全部退款) + * + * @param date 日期 + * @return 收款总额 + */ + private BigDecimal queryRevenueByDate(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + Date dayStart = cal.getTime(); + + cal.add(Calendar.DAY_OF_MONTH, 1); + Date dayEnd = cal.getTime(); + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.ge(PaymentReconciliation::getBillDate, dayStart) + .lt(PaymentReconciliation::getBillDate, dayEnd) + .eq(PaymentReconciliation::getStatusEnum, PaymentStatus.SUCCESS.getValue()) + .eq(PaymentReconciliation::getDeleteFlag, "0") + .select(PaymentReconciliation::getDisplayAmount); + + java.util.List list = paymentReconciliationService.list(query); + if (list == null || list.isEmpty()) { + return BigDecimal.ZERO; + } + return list.stream() + .map(p -> p.getDisplayAmount() != null ? p.getDisplayAmount() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + /** + * 获取昨天的日期 + */ + private Date getYesterday() { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, -1); + return cal.getTime(); + } + /** * 计算相对前日的百分比变化 * diff --git a/openhis-server-new/openhis-application/src/main/resources/application-dev.yml.bak b/openhis-server-new/openhis-application/src/main/resources/application-dev.yml.bak new file mode 100644 index 000000000..bf984f0d4 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/resources/application-dev.yml.bak @@ -0,0 +1,93 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: org.postgresql.Driver + druid: + # 主库数据源 + master: + url: jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=hisdev&characterEncoding=UTF-8&client_encoding=UTF-8 + username: postgresql + password: Jchl1528 # 请替换为实际的数据库密码 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: true # 改为true以确保连接有效 + testOnReturn: false + # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 + filters: stat,wall,slf4j + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: openhis + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: 192.168.110.252 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 1 + # 密码 + password: Jchl1528 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +# 服务器配置 +server: + # 服务器的HTTP端口,默认为18080 + port: 18080 + servlet: + # 应用的访问路径 + context-path: /openhis \ No newline at end of file diff --git a/openhis-ui-vue3/package.json b/openhis-ui-vue3/package.json index e17550cdd..c083609d4 100755 --- a/openhis-ui-vue3/package.json +++ b/openhis-ui-vue3/package.json @@ -64,7 +64,9 @@ "vue-area-linkage": "^5.1.0", "vue-cropper": "^1.1.1", "vue-plugin-hiprint": "^0.0.19", - "vue-router": "^4.3.0" + "vue-router": "^4.3.0", + "vxe-table": "^4.19.6", + "xe-utils": "^3.9.1" }, "devDependencies": { "@playwright/test": "^1.58.2", diff --git a/openhis-ui-vue3/src/main.js b/openhis-ui-vue3/src/main.js index 81bb708c8..a67fbed70 100755 --- a/openhis-ui-vue3/src/main.js +++ b/openhis-ui-vue3/src/main.js @@ -1,5 +1,7 @@ import {createApp} from 'vue'; +import VxeUIAll from 'vxe-table'; +import 'vxe-table/lib/style.css'; import Cookies from 'js-cookie'; // 导入 hiprint 并挂载到全局 window 对象 @@ -122,6 +124,7 @@ directive(app); // 全局禁止点击遮罩层关闭弹窗 ElDialog.props.closeOnClickModal.default = false; // 使用element-plus 并且设置全局的大小 +app.use(VxeUIAll); app.use(ElementPlus, { locale: zhCn, // 支持 large、default、small diff --git a/openhis-ui-vue3/src/views/index.vue b/openhis-ui-vue3/src/views/index.vue index a5b96c628..6bcdf01b2 100755 --- a/openhis-ui-vue3/src/views/index.vue +++ b/openhis-ui-vue3/src/views/index.vue @@ -1,7 +1,11 @@ - - - + {{ scope.row.busNo ? scope.row.busNo : '-' }} - + - {{ scope.row.volume ? scope.row.volume : '-' }} - - + {{ scope.row.originBuyingPrice ? scope.row.originBuyingPrice : '-' }} - - + - - + {{ scope.row.originRetailPrice ? scope.row.originRetailPrice : '-' }} - - + - - + - - + + - - - - - + {{ scope.row.busNo ? scope.row.busNo : '-' }} - - + {{ scope.row.volume ? scope.row.volume : '-' }} - - + {{ scope.row.originBuyingPrice ? scope.row.originBuyingPrice : '-' }} - - + - - + {{ scope.row.originRetailPrice ? scope.row.originRetailPrice : '-' }} - - + - - + - - + + - - - - - + {{ scope.row.busNo ? scope.row.busNo : '-' }} - + - {{ scope.row.originRetailPrice ? scope.row.originRetailPrice : '-' }} - - + - - + - - + + - - - - - + {{ scope.row.name }} - - + {{ scope.row.originRetailPrice ? scope.row.originRetailPrice : '-' }} - - + - - + - - + +