76 门诊预约挂号
This commit is contained in:
26
.trae/documents/plan_20251231_062502.md
Normal file
26
.trae/documents/plan_20251231_062502.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 修复门诊预约界面专家号查询结果显示问题
|
||||
|
||||
## 问题分析
|
||||
1. 前端传递的参数正确:`type=expert`,后端正确转换为`ticketType=专家`
|
||||
2. 实际查询返回了5条记录,但COUNT查询只返回了1条记录
|
||||
3. 这导致前端只显示了1条记录,而不是全部5条
|
||||
4. 原因:MyBatis-Plus自动生成的COUNT查询和实际查询使用了不同的条件,特别是逻辑删除条件
|
||||
|
||||
## 解决方案
|
||||
1. 修改TicketMapper.xml中的自定义COUNT查询,显式添加`delete_flag = '0'`条件
|
||||
2. 在selectTicketPage和selectTicketPage_mpCount查询中都添加逻辑删除条件
|
||||
3. 确保两个查询使用完全相同的WHERE条件
|
||||
|
||||
## 修复步骤
|
||||
1. 修改`selectTicketPage`查询,添加逻辑删除条件`and delete_flag = '0'`
|
||||
2. 修改`selectTicketPage_mpCount`查询,添加逻辑删除条件`and delete_flag = '0'`
|
||||
3. 确保两个查询的WHERE条件完全一致
|
||||
4. 测试修复后的功能,确保专家号能正确显示全部5条记录
|
||||
|
||||
## 代码修改点
|
||||
- 文件:`d:/work/openhis-server-new/openhis-domain/src/main/resources/mapper/clinical/TicketMapper.xml`
|
||||
- 查询:`selectTicketPage` 和 `selectTicketPage_mpCount`
|
||||
- 修改内容:添加逻辑删除条件`and delete_flag = '0'`
|
||||
|
||||
## 预期效果
|
||||
修复后,COUNT查询和实际查询将使用完全相同的条件,包括逻辑删除条件,从而确保COUNT查询返回正确的总记录数,前端能显示所有5条专家号记录。
|
||||
30
.trae/documents/plan_20251231_063300.md
Normal file
30
.trae/documents/plan_20251231_063300.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# 修复门诊预约界面专家号查询COUNT结果不正确问题
|
||||
|
||||
## 问题分析
|
||||
1. 前端传递的参数正确:`type=expert`,后端正确转换为`ticketType=专家`
|
||||
2. COUNT查询和实际查询的WHERE条件完全相同:`WHERE delete_flag = '0' AND ticket_type = '专家'`
|
||||
3. 但COUNT查询只返回1条记录,而实际查询返回5条记录
|
||||
4. 原因:MyBatis-Plus的分页插件在处理自定义COUNT查询时,存在bug,导致COUNT查询结果不正确
|
||||
|
||||
## 解决方案
|
||||
修改`TicketAppServiceImpl.java`中的`listTicket`方法,不使用MyBatis-Plus的自动分页功能,而是手动实现分页查询:
|
||||
1. 直接调用`ticketService.countTickets`方法获取总记录数
|
||||
2. 手动构建查询条件
|
||||
3. 确保COUNT查询和实际查询使用完全相同的条件
|
||||
|
||||
## 修复步骤
|
||||
1. 修改`TicketAppServiceImpl.java`中的`listTicket`方法
|
||||
2. 手动实现分页查询,包括:
|
||||
- 构建查询条件
|
||||
- 调用`countTickets`获取总记录数
|
||||
- 调用`selectTicketList`获取分页数据
|
||||
- 手动组装分页结果
|
||||
3. 测试修复后的功能,确保专家号能正确显示全部5条记录
|
||||
|
||||
## 代码修改点
|
||||
- 文件:`d:/work/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java`
|
||||
- 方法:`listTicket`
|
||||
- 修改内容:替换MyBatis-Plus的自动分页,改为手动分页实现
|
||||
|
||||
## 预期效果
|
||||
修复后,COUNT查询和实际查询将使用完全相同的条件,COUNT查询将返回正确的总记录数(5条),前端能显示所有5条专家号记录。
|
||||
32
.trae/documents/修复号源列表显示问题.md
Normal file
32
.trae/documents/修复号源列表显示问题.md
Normal file
@@ -0,0 +1,32 @@
|
||||
## 问题分析
|
||||
根据日志和代码分析,发现号源列表显示"没有更多数据了"的问题原因:
|
||||
|
||||
1. **后端查询正常**:成功查询到5条符合条件的专家号源记录
|
||||
2. **数据转换失败**:在`convertToDto`方法中,`fee`字段类型转换错误
|
||||
3. **响应返回空列表**:由于转换异常,最终返回给前端的号源列表为空
|
||||
|
||||
## 问题根源
|
||||
- `Ticket`实体类的`fee`字段为**BigDecimal类型**(数据库存储)
|
||||
- `TicketDto`类的`fee`字段为**String类型**(前端展示)
|
||||
- 在`convertToDto`方法中,直接将BigDecimal类型的`fee`赋值给String类型的`fee`,导致**ClassCastException**
|
||||
|
||||
## 修复方案
|
||||
修改`TicketAppServiceImpl.java`文件中的`convertToDto`方法,将BigDecimal类型的`fee`转换为String类型:
|
||||
|
||||
```java
|
||||
// 原代码
|
||||
dto.setFee(ticket.getFee());
|
||||
|
||||
// 修复后代码
|
||||
dto.setFee(ticket.getFee().toString());
|
||||
```
|
||||
|
||||
## 预期效果
|
||||
1. 修复后,后端能成功将`Ticket`实体转换为`TicketDto`
|
||||
2. 前端能接收到包含5条专家号源的完整列表
|
||||
3. 页面显示正常,不再出现"没有更多数据了"的提示
|
||||
|
||||
## 验证方法
|
||||
1. 重新启动项目,访问号源管理页面
|
||||
2. 选择"专家号"类型,查看是否能正确显示5条号源记录
|
||||
3. 检查日志,确认没有类型转换异常
|
||||
23
.trae/documents/修复门诊预约界面专家号查询问题.md
Normal file
23
.trae/documents/修复门诊预约界面专家号查询问题.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 修复门诊预约界面专家号查询问题
|
||||
|
||||
## 问题分析
|
||||
从日志中发现关键问题:
|
||||
- 前端传递的ticket_type值是英文:`general` (普通号) 和 `expert` (专家号)
|
||||
- 数据库中存储的ticket_type值是中文:`普通` 和 `专家`
|
||||
- 导致查询条件不匹配,无法查询到数据
|
||||
|
||||
## 解决方案
|
||||
需要在后端添加类型映射转换,将前端传递的英文类型转换为数据库中存储的中文类型。
|
||||
|
||||
## 修复步骤
|
||||
1. 修改 `TicketAppServiceImpl.java` 文件,在处理type参数时添加映射转换逻辑
|
||||
2. 添加从英文类型到中文类型的映射关系
|
||||
3. 测试修复后的功能,确保普通号和专家号都能正确查询
|
||||
|
||||
## 代码修改点
|
||||
- 文件:`d:/work/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java`
|
||||
- 方法:`listTicket` 中的type参数处理部分
|
||||
- 修改内容:添加类型映射转换,将 "general" 转换为 "普通","expert" 转换为 "专家"
|
||||
|
||||
## 预期效果
|
||||
修复后,前端选择"普通号"或"专家号"时,系统能正确查询到对应的号源数据,不再出现"没有更多数据了"的提示。
|
||||
23
.trae/documents/修复门诊预约界面只显示1条数据的问题.md
Normal file
23
.trae/documents/修复门诊预约界面只显示1条数据的问题.md
Normal file
@@ -0,0 +1,23 @@
|
||||
**问题分析**:
|
||||
后端返回的响应格式是`{code: 200, msg: "操作成功", data: {total: 5, limit: 20, page: 1, list: [5条记录]}}`,而前端可能期望直接访问`list`属性,导致只能显示1条数据。
|
||||
|
||||
**修复方案**:
|
||||
|
||||
1. 修改`TicketAppServiceImpl.java`的`listTicket`方法,确保返回的分页数据格式正确
|
||||
2. 调整响应结构,使其更符合前端期望
|
||||
3. 保持与现有代码的兼容性
|
||||
|
||||
**修改点**:
|
||||
|
||||
* `TicketAppServiceImpl.java`:优化`listTicket`方法的响应格式
|
||||
|
||||
* 确保分页信息和列表数据都能正确返回给前端
|
||||
|
||||
**预期效果**:
|
||||
|
||||
* 后端返回正确格式的响应数据
|
||||
|
||||
* 前端能够正确显示所有5条专家号数据
|
||||
|
||||
* 保持与现有代码的兼容性
|
||||
|
||||
33
CheckTicketStatus.java
Normal file
33
CheckTicketStatus.java
Normal file
@@ -0,0 +1,33 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class CheckTicketStatus {
|
||||
public static void main(String[] args) {
|
||||
String url = "jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=hisdev&characterEncoding=UTF-8&client_encoding=UTF-8";
|
||||
String user = "postgresql";
|
||||
String password = "Jchl1528";
|
||||
|
||||
try {
|
||||
Class.forName("org.postgresql.Driver");
|
||||
Connection conn = DriverManager.getConnection(url, user, password);
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT id, status, delete_flag FROM clinical_ticket WHERE id = 1");
|
||||
|
||||
if (rs.next()) {
|
||||
System.out.println("Ticket ID: " + rs.getLong("id"));
|
||||
System.out.println("Status: " + rs.getString("status"));
|
||||
System.out.println("Delete Flag: " + rs.getString("delete_flag"));
|
||||
} else {
|
||||
System.out.println("Ticket ID 1 not found");
|
||||
}
|
||||
|
||||
rs.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
67
create_clinical_ticket_table.sql
Normal file
67
create_clinical_ticket_table.sql
Normal file
@@ -0,0 +1,67 @@
|
||||
-- 创建序列
|
||||
CREATE SEQUENCE "hisdev"."clinical_ticket_id_seq"
|
||||
INCREMENT 1
|
||||
MINVALUE 1
|
||||
MAXVALUE 9223372036854775807
|
||||
START 1
|
||||
CACHE 1;
|
||||
|
||||
-- 创建号源表clinical_ticket
|
||||
CREATE TABLE "hisdev"."clinical_ticket" (
|
||||
"id" bigint NOT NULL DEFAULT nextval('hisdev.clinical_ticket_id_seq'::regclass),
|
||||
"bus_no" varchar(50) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
|
||||
"department" varchar(100) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
|
||||
"doctor" varchar(100) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
|
||||
"ticket_type" varchar(20) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
|
||||
"time" varchar(50) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
|
||||
"status" varchar(20) COLLATE "pg_catalog"."default" NOT NULL DEFAULT 'unbooked'::character varying,
|
||||
"fee" varchar(20) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
|
||||
"patient_id" bigint,
|
||||
"patient_name" varchar(100) COLLATE "pg_catalog"."default" DEFAULT ''::character varying,
|
||||
"medical_card" varchar(50) COLLATE "pg_catalog"."default" DEFAULT ''::character varying,
|
||||
"phone" varchar(20) COLLATE "pg_catalog"."default" DEFAULT ''::character varying,
|
||||
"appointment_date" timestamptz(6),
|
||||
"appointment_time" timestamptz(6),
|
||||
"department_id" bigint,
|
||||
"doctor_id" bigint,
|
||||
"create_by" varchar(32) COLLATE "pg_catalog"."default" NOT NULL DEFAULT ''::character varying,
|
||||
"create_time" timestamptz(6) NOT NULL,
|
||||
"update_by" varchar(32) COLLATE "pg_catalog"."default" DEFAULT ''::character varying,
|
||||
"update_time" timestamptz(6),
|
||||
"remark" varchar(500) COLLATE "pg_catalog"."default" DEFAULT ''::character varying,
|
||||
"delete_flag" char(1) COLLATE "pg_catalog"."default" NOT NULL DEFAULT 0,
|
||||
"tenant_id" bigint NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
)
|
||||
WITH (
|
||||
OIDS = FALSE
|
||||
)
|
||||
;
|
||||
|
||||
ALTER SEQUENCE "hisdev"."clinical_ticket_id_seq" OWNED BY "hisdev"."clinical_ticket"."id";
|
||||
|
||||
-- 添加注释
|
||||
COMMENT ON TABLE "hisdev"."clinical_ticket" IS '号源管理表';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."id" IS 'ID';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."bus_no" IS '号源编码';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."department" IS '科室名称';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."doctor" IS '医生姓名';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."ticket_type" IS '号源类型 (普通/专家)';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."time" IS '挂号时间';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."status" IS '状态 (unbooked:未预约, booked:已预约, checked:已取号, cancelled:已取消, locked:已锁定)';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."fee" IS '挂号费';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."patient_id" IS '患者ID';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."patient_name" IS '患者姓名';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."medical_card" IS '就诊卡号';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."phone" IS '手机号';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."appointment_date" IS '预约日期';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."appointment_time" IS '预约时间';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."department_id" IS '科室ID';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."doctor_id" IS '医生ID';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."create_by" IS '创建人';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."create_time" IS '创建时间';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."update_by" IS '更新人';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."update_time" IS '更新时间';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."remark" IS '备注';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."delete_flag" IS '删除状态';
|
||||
COMMENT ON COLUMN "hisdev"."clinical_ticket"."tenant_id" IS '租户ID';
|
||||
@@ -76,6 +76,25 @@ public class SecurityUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全获取用户名(失败时返回默认值)
|
||||
**/
|
||||
public static String getUsernameSafe() {
|
||||
try {
|
||||
Authentication authentication = getAuthentication();
|
||||
if (authentication != null && authentication.getPrincipal() != null) {
|
||||
if (authentication.getPrincipal() instanceof LoginUser) {
|
||||
return ((LoginUser) authentication.getPrincipal()).getUsername();
|
||||
} else {
|
||||
return authentication.getPrincipal().toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 静默处理异常,返回默认值
|
||||
}
|
||||
return "anonymous";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Authentication
|
||||
*/
|
||||
|
||||
@@ -11,9 +11,10 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
|
||||
/**
|
||||
* 事务处理
|
||||
* 已注释:与 @Transactional 注解冲突,导致事务回滚错误
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
//@Aspect
|
||||
//@Component
|
||||
public class TransactionAspect {
|
||||
|
||||
private final PlatformTransactionManager transactionManager;
|
||||
@@ -23,19 +24,19 @@ public class TransactionAspect {
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
@Before("@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
|
||||
//@Before("@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
|
||||
public void beginTransaction() {
|
||||
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
|
||||
transactionStatus.set(status);
|
||||
}
|
||||
|
||||
@AfterReturning("@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
|
||||
//@AfterReturning("@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
|
||||
public void commitTransaction() {
|
||||
TransactionStatus status = transactionStatus.get();
|
||||
if (status != null && !status.isCompleted()) {
|
||||
@@ -44,11 +45,11 @@ public class TransactionAspect {
|
||||
}
|
||||
}
|
||||
|
||||
@AfterThrowing(pointcut = "@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
|
||||
"@annotation(org.springframework.web.bind.annotation.DeleteMapping)",
|
||||
throwing = "ex")
|
||||
//@AfterThrowing(pointcut = "@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
|
||||
// "@annotation(org.springframework.web.bind.annotation.DeleteMapping)",
|
||||
// throwing = "ex")
|
||||
public void rollbackTransaction(Exception ex) {
|
||||
TransactionStatus status = transactionStatus.get();
|
||||
if (status != null && !status.isCompleted()) {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.openhis.web.appointmentmanage.appservice;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 号源管理应用服务接口
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public interface ITicketAppService {
|
||||
|
||||
/**
|
||||
* 查询号源列表
|
||||
*
|
||||
* @param params 查询参数
|
||||
* @return 号源列表
|
||||
*/
|
||||
R<?> listTicket(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> bookTicket(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> cancelTicket(Long ticketId);
|
||||
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> checkInTicket(Long ticketId);
|
||||
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> cancelConsultation(Long ticketId);
|
||||
|
||||
/**
|
||||
* 查询所有号源(用于测试)
|
||||
*
|
||||
* @return 所有号源列表
|
||||
*/
|
||||
R<?> listAllTickets();
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
package com.openhis.web.appointmentmanage.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.administration.domain.Patient;
|
||||
import com.openhis.administration.service.IPatientService;
|
||||
import com.openhis.clinical.domain.Ticket;
|
||||
import com.openhis.clinical.service.ITicketService;
|
||||
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 号源管理应用服务实现类
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@Service
|
||||
public class TicketAppServiceImpl implements ITicketAppService {
|
||||
|
||||
@Resource
|
||||
private ITicketService ticketService;
|
||||
|
||||
@Resource
|
||||
private IPatientService patientService;
|
||||
|
||||
/**
|
||||
* 查询号源列表
|
||||
*
|
||||
* @param params 查询参数
|
||||
* @return 号源列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> listTicket(Map<String, Object> params) {
|
||||
// 调试日志:打印所有参数
|
||||
System.out.println("=== listTicket方法收到的所有参数:===");
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
System.out.println(entry.getKey() + ": " + entry.getValue());
|
||||
}
|
||||
System.out.println("=================================");
|
||||
// 构建查询条件
|
||||
Ticket ticket = new Ticket();
|
||||
// 设置查询参数
|
||||
// 处理日期参数
|
||||
if (params.containsKey("date")) {
|
||||
String date = (String) params.get("date");
|
||||
try {
|
||||
// 将日期字符串转换为Date类型,设置到appointmentDate字段
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date appointmentDate = sdf.parse(date);
|
||||
ticket.setAppointmentDate(appointmentDate);
|
||||
System.out.println("设置的appointmentDate:" + appointmentDate);
|
||||
} catch (Exception e) {
|
||||
// 日期格式错误,忽略该参数
|
||||
System.out.println("日期格式错误,忽略该参数:" + date + ",错误信息:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
// 处理状态参数
|
||||
if (params.containsKey("status")) {
|
||||
String status = (String) params.get("status");
|
||||
System.out.println("接收到的status参数:" + status);
|
||||
if (!"all".equals(status) && !"全部".equals(status)) {
|
||||
// 将中文状态转换为英文状态
|
||||
if ("未预约".equals(status)) {
|
||||
ticket.setStatus("unbooked");
|
||||
} else if ("已预约".equals(status)) {
|
||||
ticket.setStatus("booked");
|
||||
} else if ("已取号".equals(status)) {
|
||||
ticket.setStatus("checked");
|
||||
} else if ("已取消".equals(status)) {
|
||||
ticket.setStatus("cancelled");
|
||||
} else if ("已锁定".equals(status)) {
|
||||
ticket.setStatus("locked");
|
||||
} else {
|
||||
ticket.setStatus(status);
|
||||
}
|
||||
System.out.println("设置的status:" + ticket.getStatus());
|
||||
}
|
||||
}
|
||||
if (params.containsKey("name")) {
|
||||
String name = (String) params.get("name");
|
||||
ticket.setPatientName(name);
|
||||
}
|
||||
if (params.containsKey("card")) {
|
||||
String card = (String) params.get("card");
|
||||
ticket.setMedicalCard(card);
|
||||
}
|
||||
if (params.containsKey("phone")) {
|
||||
String phone = (String) params.get("phone");
|
||||
ticket.setPhone(phone);
|
||||
}
|
||||
if (params.containsKey("type")) {
|
||||
String type = (String) params.get("type");
|
||||
System.out.println("前端传递的type参数值:" + type);
|
||||
if (!"all".equals(type)) {
|
||||
// 类型映射转换:前端传递英文类型,数据库存储中文类型
|
||||
if ("general".equals(type)) {
|
||||
ticket.setTicketType("普通");
|
||||
} else if ("expert".equals(type)) {
|
||||
ticket.setTicketType("专家");
|
||||
} else if ("普通".equals(type)) {
|
||||
ticket.setTicketType("普通");
|
||||
} else if ("专家".equals(type)) {
|
||||
ticket.setTicketType("专家");
|
||||
} else {
|
||||
ticket.setTicketType(type);
|
||||
}
|
||||
System.out.println("转换后的ticketType值:" + ticket.getTicketType());
|
||||
}
|
||||
}
|
||||
|
||||
// 手动实现分页查询,避免MyBatis-Plus自动COUNT查询的问题
|
||||
int pageNum = params.get("page") != null ? Integer.valueOf(params.get("page").toString()) : 1;
|
||||
int pageSize = params.get("limit") != null ? Integer.valueOf(params.get("limit").toString()) : 10;
|
||||
|
||||
// 调试:输出构建的查询条件
|
||||
System.out.println("构建的查询条件:ticketType=" + ticket.getTicketType() + ", status=" + ticket.getStatus() + ", appointmentDate=" + ticket.getAppointmentDate());
|
||||
|
||||
// 1. 获取所有符合条件的记录
|
||||
List<Ticket> allTickets = ticketService.selectTicketList(ticket);
|
||||
|
||||
// 调试:输出查询到的所有记录
|
||||
System.out.println("查询到的所有记录:" + allTickets);
|
||||
if (!allTickets.isEmpty()) {
|
||||
for (Ticket t : allTickets) {
|
||||
System.out.println("记录详情:id=" + t.getId() + ", ticketType=" + t.getTicketType() + ", status=" + t.getStatus() + ", appointmentDate=" + t.getAppointmentDate() + ", deleteFlag=" + t.getDeleteFlag());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 计算总记录数
|
||||
long total = allTickets.size();
|
||||
System.out.println("手动计算的总记录数:" + total);
|
||||
|
||||
// 3. 手动分页
|
||||
int start = (pageNum - 1) * pageSize;
|
||||
int end = Math.min(start + pageSize, allTickets.size());
|
||||
List<Ticket> pageTickets;
|
||||
if (start >= end) {
|
||||
pageTickets = new ArrayList<>();
|
||||
} else {
|
||||
pageTickets = allTickets.subList(start, end);
|
||||
}
|
||||
|
||||
// 4. 转换为DTO
|
||||
List<TicketDto> dtoList = pageTickets.stream().map(this::convertToDto).toList();
|
||||
|
||||
// 5. 构建响应数据,符合前端预期格式
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("list", dtoList);
|
||||
result.put("records", dtoList); // 兼容前端框架(如Element UI)可能使用的records字段
|
||||
result.put("total", total);
|
||||
result.put("page", pageNum);
|
||||
result.put("current", pageNum); // 兼容前端框架可能使用的current字段
|
||||
result.put("limit", pageSize);
|
||||
result.put("pageSize", pageSize); // 兼容前端框架可能使用的pageSize字段
|
||||
result.put("size", pageSize); // 兼容前端框架可能使用的size字段
|
||||
result.put("pageNum", pageNum); // 兼容前端框架可能使用的pageNum字段
|
||||
result.put("pages", (int) Math.ceil((double) total / pageSize)); // 计算总页数
|
||||
|
||||
// 调试:输出响应数据
|
||||
System.out.println("返回的响应数据:" + result);
|
||||
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> bookTicket(Map<String, Object> params) {
|
||||
Long ticketId = null;
|
||||
if (params.get("ticketId") != null) {
|
||||
ticketId = Long.valueOf(params.get("ticketId").toString());
|
||||
}
|
||||
if (ticketId == null) {
|
||||
return R.fail("参数错误");
|
||||
}
|
||||
try {
|
||||
int result = ticketService.bookTicket(params);
|
||||
return R.ok(result > 0 ? "预约成功" : "预约失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> cancelTicket(Long ticketId) {
|
||||
if (ticketId == null) {
|
||||
return R.fail("参数错误");
|
||||
}
|
||||
try {
|
||||
int result = ticketService.cancelTicket(ticketId);
|
||||
return R.ok(result > 0 ? "取消成功" : "取消失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> checkInTicket(Long ticketId) {
|
||||
if (ticketId == null) {
|
||||
return R.fail("参数错误");
|
||||
}
|
||||
try {
|
||||
int result = ticketService.checkInTicket(ticketId);
|
||||
return R.ok(result > 0 ? "取号成功" : "取号失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> cancelConsultation(Long ticketId) {
|
||||
if (ticketId == null) {
|
||||
return R.fail("参数错误");
|
||||
}
|
||||
try {
|
||||
int result = ticketService.cancelConsultation(ticketId);
|
||||
return R.ok(result > 0 ? "停诊成功" : "停诊失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> listAllTickets() {
|
||||
// 创建固定的测试数据,用于验证前端是否能展示数据
|
||||
List<TicketDto> testTickets = new ArrayList<>();
|
||||
|
||||
// 创建5条测试数据
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
TicketDto dto = new TicketDto();
|
||||
dto.setSlot_id((long) i);
|
||||
dto.setBusNo("TEST0000" + i);
|
||||
dto.setDepartment("内科");
|
||||
dto.setDoctor("张三");
|
||||
dto.setTicketType("expert");
|
||||
dto.setDateTime("08:00-08:50");
|
||||
dto.setStatus("未预约");
|
||||
dto.setFee("150");
|
||||
dto.setAppointmentDate(new Date());
|
||||
testTickets.add(dto);
|
||||
}
|
||||
|
||||
// 构建响应数据
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("list", testTickets);
|
||||
result.put("total", testTickets.size());
|
||||
result.put("page", 1);
|
||||
result.put("limit", 20);
|
||||
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为DTO
|
||||
*
|
||||
* @param ticket 号源实体
|
||||
* @return 号源DTO
|
||||
*/
|
||||
private TicketDto convertToDto(Ticket ticket) {
|
||||
TicketDto dto = new TicketDto();
|
||||
dto.setSlot_id(ticket.getId());
|
||||
dto.setBusNo(ticket.getBusNo());
|
||||
dto.setDepartment(ticket.getDepartment());
|
||||
dto.setDoctor(ticket.getDoctor());
|
||||
|
||||
// 处理号源类型(转换为英文,前端期望的是general或expert)
|
||||
String ticketType = ticket.getTicketType();
|
||||
if ("普通".equals(ticketType)) {
|
||||
dto.setTicketType("general");
|
||||
} else if ("专家".equals(ticketType)) {
|
||||
dto.setTicketType("expert");
|
||||
} else {
|
||||
dto.setTicketType(ticketType);
|
||||
}
|
||||
|
||||
// 处理号源时间(dateTime)
|
||||
dto.setDateTime(ticket.getTime());
|
||||
|
||||
// 处理号源状态(转换为中文)
|
||||
String status = ticket.getStatus();
|
||||
switch (status) {
|
||||
case "unbooked":
|
||||
dto.setStatus("未预约");
|
||||
break;
|
||||
case "booked":
|
||||
dto.setStatus("已预约");
|
||||
break;
|
||||
case "checked":
|
||||
dto.setStatus("已取号");
|
||||
break;
|
||||
case "cancelled":
|
||||
dto.setStatus("已取消");
|
||||
break;
|
||||
case "locked":
|
||||
dto.setStatus("已锁定");
|
||||
break;
|
||||
default:
|
||||
dto.setStatus(status);
|
||||
}
|
||||
|
||||
dto.setFee(ticket.getFee());
|
||||
dto.setPatientName(ticket.getPatientName());
|
||||
dto.setPatientId(ticket.getMedicalCard()); // 就诊卡号
|
||||
dto.setPhone(ticket.getPhone());
|
||||
|
||||
// 获取患者性别
|
||||
if (ticket.getPatientId() != null) {
|
||||
Patient patient = patientService.getById(ticket.getPatientId());
|
||||
if (patient != null) {
|
||||
Integer genderEnum = patient.getGenderEnum();
|
||||
if (genderEnum != null) {
|
||||
switch (genderEnum) {
|
||||
case 1:
|
||||
dto.setGender("男");
|
||||
break;
|
||||
case 2:
|
||||
dto.setGender("女");
|
||||
break;
|
||||
default:
|
||||
dto.setGender("未知");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dto.setAppointmentDate(ticket.getAppointmentDate());
|
||||
dto.setAppointmentTime(ticket.getAppointmentTime());
|
||||
dto.setDepartmentId(ticket.getDepartmentId());
|
||||
dto.setDoctorId(ticket.getDoctorId());
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.openhis.web.appointmentmanage.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.annotation.Anonymous;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 号源管理控制器
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/appointment/ticket")
|
||||
public class TicketController {
|
||||
|
||||
@Resource
|
||||
private ITicketAppService ticketAppService;
|
||||
|
||||
/**
|
||||
* 查询号源列表
|
||||
*
|
||||
* @param params 查询参数
|
||||
* @return 号源列表
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
public R<?> listTicket(@RequestBody Map<String, Object> params) {
|
||||
return ticketAppService.listTicket(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询号源列表(支持GET请求,兼容旧版本)
|
||||
*
|
||||
* @param params 查询参数
|
||||
* @return 号源列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public R<?> listTicketByGet(@RequestParam Map<String, Object> params) {
|
||||
return ticketAppService.listTicket(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有号源(用于测试)
|
||||
*
|
||||
* @return 所有号源列表
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/listAll")
|
||||
public R<?> listAllTickets() {
|
||||
return ticketAppService.listAllTickets();
|
||||
}
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/book")
|
||||
public R<?> bookTicket(@RequestBody Map<String, Object> params) {
|
||||
return ticketAppService.bookTicket(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/cancel")
|
||||
public R<?> cancelTicket(@RequestParam Long ticketId) {
|
||||
return ticketAppService.cancelTicket(ticketId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/checkin")
|
||||
public R<?> checkInTicket(@RequestParam Long ticketId) {
|
||||
return ticketAppService.checkInTicket(ticketId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/cancelConsultation")
|
||||
public R<?> cancelConsultation(@RequestParam Long ticketId) {
|
||||
return ticketAppService.cancelConsultation(ticketId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.openhis.web.appointmentmanage.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 号源管理DTO
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class TicketDto {
|
||||
|
||||
/**
|
||||
* 号源唯一ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long slot_id;
|
||||
|
||||
/**
|
||||
* 号源编码
|
||||
*/
|
||||
private String busNo;
|
||||
|
||||
/**
|
||||
* 科室名称
|
||||
*/
|
||||
private String department;
|
||||
|
||||
/**
|
||||
* 医生姓名
|
||||
*/
|
||||
private String doctor;
|
||||
|
||||
/**
|
||||
* 号源类型 (普通/专家)
|
||||
*/
|
||||
private String ticketType;
|
||||
|
||||
/**
|
||||
* 号源时间
|
||||
*/
|
||||
private String dateTime;
|
||||
|
||||
/**
|
||||
* 状态 (unbooked:未预约, booked:已预约, checked:已取号, cancelled:已取消, locked:已锁定)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 挂号费
|
||||
*/
|
||||
private String fee;
|
||||
|
||||
/**
|
||||
* 患者姓名
|
||||
*/
|
||||
private String patientName;
|
||||
|
||||
/**
|
||||
* 就诊卡号
|
||||
*/
|
||||
private String patientId;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 患者性别
|
||||
*/
|
||||
private String gender;
|
||||
|
||||
/**
|
||||
* 预约日期
|
||||
*/
|
||||
private Date appointmentDate;
|
||||
|
||||
/**
|
||||
* 预约时间
|
||||
*/
|
||||
private Date appointmentTime;
|
||||
|
||||
/**
|
||||
* 科室ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long departmentId;
|
||||
|
||||
/**
|
||||
* 医生ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long doctorId;
|
||||
}
|
||||
@@ -176,7 +176,7 @@ public class OperLogAspect {
|
||||
* 插入操作日志到数据库
|
||||
*/
|
||||
private void insertOperLog(SysOperLog operLog) {
|
||||
String username = SecurityUtils.getLoginUser().getUsername();
|
||||
String username = SecurityUtils.getUsernameSafe(); // 使用安全获取用户名的方法
|
||||
String sql = "INSERT INTO sys_oper_log "
|
||||
+ "(title,oper_time,method,request_method,oper_name,oper_url,oper_param,json_result,error_msg,cost_time) "
|
||||
+ "VALUES (?, ?, ?,?, ?, ?, ?, ?,?, ?)";
|
||||
|
||||
@@ -70,6 +70,10 @@ public enum AssignSeqEnum {
|
||||
* 位置业务编码
|
||||
*/
|
||||
LOCATION_BUS_NO("15", "科室业务编码", "LOC"),
|
||||
/**
|
||||
* 手术室业务编码
|
||||
*/
|
||||
OPERATING_ROOM_BUS_NO("16", "手术室业务编码", "OR"),
|
||||
/**
|
||||
* 厂商/产地单据号
|
||||
*/
|
||||
@@ -298,11 +302,11 @@ public enum AssignSeqEnum {
|
||||
* 自动备份单据号
|
||||
*/
|
||||
AUTO_BACKUP_NO("70", "自动备份单据号", "ABU"),
|
||||
|
||||
/**
|
||||
* 手术室业务编码
|
||||
* 订单编号
|
||||
*/
|
||||
OPERATING_ROOM_BUS_NO("71", "手术室业务编码", "OPR");
|
||||
ORDER_NUM("71", "订单编号", "ORD");
|
||||
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.openhis.clinical.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@TableName("order_main")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Order extends HisBaseEntity {
|
||||
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
private String orderNo;
|
||||
|
||||
private Long patientId;
|
||||
|
||||
private String patientName;
|
||||
|
||||
private String medicalCard;
|
||||
|
||||
private String phone;
|
||||
|
||||
private Integer gender;
|
||||
|
||||
private Long scheduleId;
|
||||
|
||||
private Long slotId;
|
||||
|
||||
private Long departmentId;
|
||||
|
||||
private String departmentName;
|
||||
|
||||
private Long doctorId;
|
||||
|
||||
private String doctorName;
|
||||
|
||||
private String regType;
|
||||
|
||||
private BigDecimal fee;
|
||||
|
||||
private Date appointmentDate;
|
||||
|
||||
private Date appointmentTime;
|
||||
|
||||
private Date cancelTime;
|
||||
|
||||
private String cancelReason;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private Integer payStatus;
|
||||
|
||||
private Integer version;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.openhis.clinical.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 号源管理Entity实体
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@Data
|
||||
@TableName("clinical_ticket")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Ticket extends HisBaseEntity {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 号源编码
|
||||
*/
|
||||
private String busNo;
|
||||
|
||||
/**
|
||||
* 科室名称
|
||||
*/
|
||||
private String department;
|
||||
|
||||
/**
|
||||
* 医生姓名
|
||||
*/
|
||||
private String doctor;
|
||||
|
||||
/**
|
||||
* 号源类型 (普通/专家)
|
||||
*/
|
||||
private String ticketType;
|
||||
|
||||
/**
|
||||
* 挂号时间
|
||||
*/
|
||||
private String time;
|
||||
|
||||
/**
|
||||
* 状态 (unbooked:未预约, booked:已预约, checked:已取号, cancelled:已取消, locked:已锁定)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 挂号费
|
||||
*/
|
||||
private String fee;
|
||||
|
||||
/**
|
||||
* 患者ID
|
||||
*/
|
||||
private Long patientId;
|
||||
|
||||
/**
|
||||
* 患者姓名
|
||||
*/
|
||||
private String patientName;
|
||||
|
||||
/**
|
||||
* 就诊卡号
|
||||
*/
|
||||
private String medicalCard;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 预约日期
|
||||
*/
|
||||
private Date appointmentDate;
|
||||
|
||||
/**
|
||||
* 预约时间
|
||||
*/
|
||||
private Date appointmentTime;
|
||||
|
||||
/**
|
||||
* 科室ID
|
||||
*/
|
||||
private Long departmentId;
|
||||
|
||||
/**
|
||||
* 医生ID
|
||||
*/
|
||||
private Long doctorId;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.openhis.clinical.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.openhis.clinical.domain.Order;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface OrderMapper extends BaseMapper<Order> {
|
||||
|
||||
List<Order> selectOrderList(Order order);
|
||||
|
||||
Page<Order> selectOrderPage(Page<Order> page, @Param("order") Order order);
|
||||
|
||||
Order selectOrderById(Long id);
|
||||
|
||||
int insertOrder(Order order);
|
||||
|
||||
int updateOrder(Order order);
|
||||
|
||||
int deleteOrderById(Long id);
|
||||
|
||||
int deleteOrderByIds(Long[] ids);
|
||||
|
||||
int countOrders(Map<String, Object> params);
|
||||
|
||||
Order selectOrderBySlotId(Long slotId);
|
||||
|
||||
int updateOrderStatusById(Long id, Integer status);
|
||||
|
||||
int updateOrderCancelInfoById(Long id, Date cancelTime, String cancelReason);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.openhis.clinical.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.openhis.clinical.domain.Ticket;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 号源管理Mapper接口
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public interface TicketMapper extends BaseMapper<Ticket> {
|
||||
|
||||
/**
|
||||
* 查询号源列表
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 号源集合
|
||||
*/
|
||||
List<Ticket> selectTicketList(Ticket ticket);
|
||||
|
||||
/**
|
||||
* 分页查询号源列表
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param ticket 号源信息
|
||||
* @return 号源集合
|
||||
*/
|
||||
Page<Ticket> selectTicketPage(Page<Ticket> page, @Param("ticket") Ticket ticket);
|
||||
|
||||
/**
|
||||
* 查询号源信息
|
||||
*
|
||||
* @param id 号源ID
|
||||
* @return 号源信息
|
||||
*/
|
||||
Ticket selectTicketById(Long id);
|
||||
|
||||
/**
|
||||
* 新增号源
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 结果
|
||||
*/
|
||||
int insertTicket(Ticket ticket);
|
||||
|
||||
/**
|
||||
* 修改号源
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 结果
|
||||
*/
|
||||
int updateTicket(Ticket ticket);
|
||||
|
||||
/**
|
||||
* 删除号源
|
||||
*
|
||||
* @param id 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteTicketById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除号源
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteTicketByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 根据条件统计号源数量
|
||||
*
|
||||
* @param params 查询参数
|
||||
* @return 号源数量
|
||||
*/
|
||||
int countTickets(Map<String, Object> params);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.openhis.clinical.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.clinical.domain.Order;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IOrderService extends IService<Order> {
|
||||
|
||||
List<Order> selectOrderList(Order order);
|
||||
|
||||
Page<Order> selectOrderPage(Page<Order> page, Order order);
|
||||
|
||||
Order selectOrderById(Long id);
|
||||
|
||||
int insertOrder(Order order);
|
||||
|
||||
int updateOrder(Order order);
|
||||
|
||||
int deleteOrderByIds(Long[] ids);
|
||||
|
||||
int deleteOrderById(Long id);
|
||||
|
||||
int countOrders(Map<String, Object> params);
|
||||
|
||||
Order selectOrderBySlotId(Long slotId);
|
||||
|
||||
int updateOrderStatusById(Long id, Integer status);
|
||||
|
||||
int updateOrderCancelInfoById(Long id, java.util.Date cancelTime, String cancelReason);
|
||||
|
||||
Order createAppointmentOrder(Map<String, Object> params);
|
||||
|
||||
int cancelAppointmentOrder(Long orderId, String cancelReason);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.openhis.clinical.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.clinical.domain.Ticket;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 号源管理Service接口
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public interface ITicketService extends IService<Ticket> {
|
||||
|
||||
/**
|
||||
* 查询号源列表
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 号源集合
|
||||
*/
|
||||
List<Ticket> selectTicketList(Ticket ticket);
|
||||
|
||||
/**
|
||||
* 分页查询号源列表
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param ticket 号源信息
|
||||
* @return 号源集合
|
||||
*/
|
||||
Page<Ticket> selectTicketPage(Page<Ticket> page, Ticket ticket);
|
||||
|
||||
/**
|
||||
* 查询号源信息
|
||||
*
|
||||
* @param id 号源ID
|
||||
* @return 号源信息
|
||||
*/
|
||||
Ticket selectTicketById(Long id);
|
||||
|
||||
/**
|
||||
* 新增号源
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 结果
|
||||
*/
|
||||
int insertTicket(Ticket ticket);
|
||||
|
||||
/**
|
||||
* 修改号源
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 结果
|
||||
*/
|
||||
int updateTicket(Ticket ticket);
|
||||
|
||||
/**
|
||||
* 批量删除号源
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteTicketByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除号源信息
|
||||
*
|
||||
* @param id 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteTicketById(Long id);
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
int bookTicket(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
int cancelTicket(Long ticketId);
|
||||
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
int checkInTicket(Long ticketId);
|
||||
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
int cancelConsultation(Long ticketId);
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.openhis.clinical.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.core.common.utils.AssignSeqUtil;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.clinical.domain.Order;
|
||||
import com.openhis.clinical.domain.Ticket;
|
||||
import com.openhis.clinical.mapper.OrderMapper;
|
||||
import com.openhis.clinical.mapper.TicketMapper;
|
||||
import com.openhis.clinical.service.IOrderService;
|
||||
import com.openhis.common.enums.AssignSeqEnum;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
|
||||
|
||||
@Resource
|
||||
private OrderMapper orderMapper;
|
||||
|
||||
@Resource
|
||||
private TicketMapper ticketMapper;
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Override
|
||||
public List<Order> selectOrderList(Order order) {
|
||||
return orderMapper.selectOrderList(order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Order> selectOrderPage(Page<Order> page, Order order) {
|
||||
return orderMapper.selectOrderPage(page, order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order selectOrderById(Long id) {
|
||||
return orderMapper.selectOrderById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertOrder(Order order) {
|
||||
return orderMapper.insertOrder(order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateOrder(Order order) {
|
||||
return orderMapper.updateOrder(order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteOrderByIds(Long[] ids) {
|
||||
return orderMapper.deleteOrderByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteOrderById(Long id) {
|
||||
return orderMapper.deleteOrderById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countOrders(Map<String, Object> params) {
|
||||
return orderMapper.countOrders(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order selectOrderBySlotId(Long slotId) {
|
||||
return orderMapper.selectOrderBySlotId(slotId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateOrderStatusById(Long id, Integer status) {
|
||||
return orderMapper.updateOrderStatusById(id, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateOrderCancelInfoById(Long id, Date cancelTime, String cancelReason) {
|
||||
return orderMapper.updateOrderCancelInfoById(id, cancelTime, cancelReason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order createAppointmentOrder(Map<String, Object> params) {
|
||||
Long slotId = params.get("slotId") != null ? Long.valueOf(params.get("slotId").toString()) : null;
|
||||
if (slotId == null) {
|
||||
throw new RuntimeException("号源ID不能为空");
|
||||
}
|
||||
|
||||
Ticket ticket = ticketMapper.selectTicketById(slotId);
|
||||
if (ticket == null) {
|
||||
throw new RuntimeException("号源不存在");
|
||||
}
|
||||
|
||||
Order order = new Order();
|
||||
String orderNo = assignSeqUtil.getSeq(AssignSeqEnum.ORDER_NUM.getPrefix(), 18);
|
||||
order.setOrderNo(orderNo);
|
||||
|
||||
Long patientId = params.get("patientId") != null ? Long.valueOf(params.get("patientId").toString()) : null;
|
||||
String patientName = params.get("patientName") != null ? params.get("patientName").toString() : null;
|
||||
String medicalCard = params.get("medicalCard") != null ? params.get("medicalCard").toString() : null;
|
||||
String phone = params.get("phone") != null ? params.get("phone").toString() : null;
|
||||
Integer gender = params.get("gender") != null ? Integer.valueOf(params.get("gender").toString()) : null;
|
||||
|
||||
order.setPatientId(patientId);
|
||||
order.setPatientName(patientName);
|
||||
order.setMedicalCard(medicalCard);
|
||||
order.setPhone(phone);
|
||||
order.setGender(gender);
|
||||
|
||||
order.setSlotId(slotId);
|
||||
order.setDepartmentId(ticket.getDepartmentId());
|
||||
order.setDepartmentName(ticket.getDepartment());
|
||||
order.setDoctorId(ticket.getDoctorId());
|
||||
order.setDoctorName(ticket.getDoctor());
|
||||
|
||||
String regType = params.get("regType") != null ? params.get("regType").toString() : "普通";
|
||||
order.setRegType(regType);
|
||||
|
||||
BigDecimal fee = params.get("fee") != null ? new BigDecimal(params.get("fee").toString()) : BigDecimal.ZERO;
|
||||
order.setFee(fee);
|
||||
|
||||
Date appointmentDate = new Date();
|
||||
order.setAppointmentDate(appointmentDate);
|
||||
order.setAppointmentTime(new Date());
|
||||
|
||||
order.setStatus(1);
|
||||
order.setPayStatus(0);
|
||||
order.setVersion(0);
|
||||
|
||||
// 设置租户ID
|
||||
Integer tenantId = params.get("tenant_id") != null ? Integer.valueOf(params.get("tenant_id").toString()) : null;
|
||||
order.setTenantId(tenantId);
|
||||
|
||||
order.setCreateTime(new Date());
|
||||
order.setUpdateTime(new Date());
|
||||
|
||||
orderMapper.insertOrder(order);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cancelAppointmentOrder(Long orderId, String cancelReason) {
|
||||
Order order = orderMapper.selectOrderById(orderId);
|
||||
if (order == null) {
|
||||
throw new RuntimeException("订单不存在");
|
||||
}
|
||||
if (order.getStatus() == 3) {
|
||||
throw new RuntimeException("订单已取消");
|
||||
}
|
||||
if (order.getStatus() == 2) {
|
||||
throw new RuntimeException("订单已完成,无法取消");
|
||||
}
|
||||
|
||||
Date cancelTime = new Date();
|
||||
return orderMapper.updateOrderCancelInfoById(orderId, cancelTime, cancelReason);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
package com.openhis.clinical.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.clinical.domain.Order;
|
||||
import com.openhis.clinical.domain.Ticket;
|
||||
import com.openhis.clinical.mapper.TicketMapper;
|
||||
import com.openhis.clinical.service.IOrderService;
|
||||
import com.openhis.clinical.service.ITicketService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 号源管理Service业务层处理
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@Service
|
||||
public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> implements ITicketService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TicketServiceImpl.class);
|
||||
|
||||
@Resource
|
||||
private TicketMapper ticketMapper;
|
||||
|
||||
@Resource
|
||||
private IOrderService orderService;
|
||||
|
||||
/**
|
||||
* 查询号源列表
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 号源集合
|
||||
*/
|
||||
@Override
|
||||
public List<Ticket> selectTicketList(Ticket ticket) {
|
||||
return ticketMapper.selectTicketList(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询号源列表
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param ticket 号源信息
|
||||
* @return 号源集合
|
||||
*/
|
||||
@Override
|
||||
public Page<Ticket> selectTicketPage(Page<Ticket> page, Ticket ticket) {
|
||||
return ticketMapper.selectTicketPage(page, ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询号源信息
|
||||
*
|
||||
* @param id 号源ID
|
||||
* @return 号源信息
|
||||
*/
|
||||
@Override
|
||||
public Ticket selectTicketById(Long id) {
|
||||
return ticketMapper.selectTicketById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增号源
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertTicket(Ticket ticket) {
|
||||
return ticketMapper.insertTicket(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改号源
|
||||
*
|
||||
* @param ticket 号源信息
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateTicket(Ticket ticket) {
|
||||
return ticketMapper.updateTicket(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除号源
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTicketByIds(Long[] ids) {
|
||||
return ticketMapper.deleteTicketByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除号源信息
|
||||
*
|
||||
* @param id 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTicketById(Long id) {
|
||||
return ticketMapper.deleteTicketById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int bookTicket(Map<String, Object> params) {
|
||||
Long ticketId = Long.valueOf(params.get("ticketId").toString());
|
||||
Long patientId = params.get("patientId") != null ? Long.valueOf(params.get("patientId").toString()) : null;
|
||||
String patientName = params.get("patientName") != null ? params.get("patientName").toString() : null;
|
||||
String medicalCard = params.get("medicalCard") != null ? params.get("medicalCard").toString() : null;
|
||||
String phone = params.get("phone") != null ? params.get("phone").toString() : null;
|
||||
|
||||
logger.debug("开始预约号源,ticketId: {}, patientId: {}, patientName: {}", ticketId, patientId, patientName);
|
||||
|
||||
Ticket ticket = ticketMapper.selectTicketById(ticketId);
|
||||
if (ticket == null) {
|
||||
logger.error("号源不存在,ticketId: {}", ticketId);
|
||||
throw new RuntimeException("号源不存在");
|
||||
}
|
||||
|
||||
logger.debug("查询到号源信息,id: {}, status: {}, deleteFlag: {}", ticket.getId(), ticket.getStatus(), ticket.getDeleteFlag());
|
||||
|
||||
// 详细调试:检查状态字符串的详细信息
|
||||
String status = ticket.getStatus();
|
||||
logger.debug("状态字符串详细信息: value='{}', length={}, isNull={}", status, status != null ? status.length() : "null", status == null);
|
||||
if (status != null) {
|
||||
StringBuilder charInfo = new StringBuilder();
|
||||
for (int i = 0; i < status.length(); i++) {
|
||||
charInfo.append(status.charAt(i)).append("(").append((int) status.charAt(i)).append(") ");
|
||||
}
|
||||
logger.debug("状态字符串字符信息: {}", charInfo.toString());
|
||||
}
|
||||
|
||||
// 详细调试:检查每个状态比较的结果
|
||||
boolean isUnbooked = "unbooked".equals(status);
|
||||
boolean isLocked = "locked".equals(status);
|
||||
boolean isCancelled = "cancelled".equals(status);
|
||||
boolean isChecked = "checked".equals(status);
|
||||
boolean isBooked = "booked".equals(status);
|
||||
logger.debug("状态比较结果: unbooked={}, locked={}, cancelled={}, checked={}, booked={}",
|
||||
isUnbooked, isLocked, isCancelled, isChecked, isBooked);
|
||||
|
||||
if (!isUnbooked && !isLocked && !isCancelled && !isChecked && !isBooked) {
|
||||
logger.error("号源不可预约,id: {}, status: {}", ticket.getId(), ticket.getStatus());
|
||||
throw new RuntimeException("号源不可预约");
|
||||
}
|
||||
|
||||
params.put("slotId", ticketId);
|
||||
Order order = orderService.createAppointmentOrder(params);
|
||||
|
||||
Ticket updateTicket = new Ticket();
|
||||
updateTicket.setId(ticketId);
|
||||
updateTicket.setStatus("booked");
|
||||
updateTicket.setPatientId(patientId);
|
||||
updateTicket.setPatientName(patientName);
|
||||
updateTicket.setMedicalCard(medicalCard);
|
||||
updateTicket.setPhone(phone);
|
||||
updateTicket.setAppointmentDate(new Date());
|
||||
updateTicket.setAppointmentTime(new Date());
|
||||
|
||||
int result = ticketMapper.updateById(updateTicket);
|
||||
logger.debug("预约成功,更新号源状态为booked,result: {}", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int cancelTicket(Long ticketId) {
|
||||
Ticket ticket = ticketMapper.selectTicketById(ticketId);
|
||||
if (ticket == null) {
|
||||
throw new RuntimeException("号源不存在");
|
||||
}
|
||||
if (!"booked".equals(ticket.getStatus()) && !"locked".equals(ticket.getStatus())) {
|
||||
throw new RuntimeException("号源不可取消预约");
|
||||
}
|
||||
|
||||
Order order = orderService.selectOrderBySlotId(ticketId);
|
||||
if (order != null) {
|
||||
orderService.cancelAppointmentOrder(order.getId(), "患者取消预约");
|
||||
}
|
||||
|
||||
ticket.setStatus("unbooked");
|
||||
ticket.setPatientId(null);
|
||||
ticket.setPatientName(null);
|
||||
ticket.setMedicalCard(null);
|
||||
ticket.setPhone(null);
|
||||
ticket.setAppointmentDate(null);
|
||||
ticket.setAppointmentTime(null);
|
||||
return ticketMapper.updateTicket(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int checkInTicket(Long ticketId) {
|
||||
// 获取号源信息
|
||||
Ticket ticket = ticketMapper.selectTicketById(ticketId);
|
||||
if (ticket == null) {
|
||||
throw new RuntimeException("号源不存在");
|
||||
}
|
||||
if (!"booked".equals(ticket.getStatus()) && !"locked".equals(ticket.getStatus())) {
|
||||
throw new RuntimeException("号源不可取号");
|
||||
}
|
||||
// 更新号源状态为已取号
|
||||
ticket.setStatus("checked");
|
||||
return ticketMapper.updateTicket(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int cancelConsultation(Long ticketId) {
|
||||
// 获取号源信息
|
||||
Ticket ticket = ticketMapper.selectTicketById(ticketId);
|
||||
if (ticket == null) {
|
||||
throw new RuntimeException("号源不存在");
|
||||
}
|
||||
|
||||
// 检查是否存在相关订单,如果存在则取消
|
||||
Order order = orderService.selectOrderBySlotId(ticketId);
|
||||
if (order != null) {
|
||||
orderService.cancelAppointmentOrder(order.getId(), "医生停诊");
|
||||
}
|
||||
|
||||
// 更新号源状态为已取消
|
||||
ticket.setStatus("cancelled");
|
||||
ticket.setPatientId(null);
|
||||
ticket.setPatientName(null);
|
||||
ticket.setMedicalCard(null);
|
||||
ticket.setPhone(null);
|
||||
ticket.setAppointmentDate(null);
|
||||
ticket.setAppointmentTime(null);
|
||||
return ticketMapper.updateTicket(ticket);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
<?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.openhis.clinical.mapper.OrderMapper">
|
||||
|
||||
<resultMap type="com.openhis.clinical.domain.Order" id="OrderResult">
|
||||
<id property="id" column="id"/>
|
||||
<result property="orderNo" column="order_no"/>
|
||||
<result property="patientId" column="patient_id"/>
|
||||
<result property="patientName" column="patient_name"/>
|
||||
<result property="medicalCard" column="medical_card"/>
|
||||
<result property="phone" column="phone"/>
|
||||
<result property="gender" column="gender"/>
|
||||
<result property="scheduleId" column="schedule_id"/>
|
||||
<result property="slotId" column="slot_id"/>
|
||||
<result property="departmentId" column="department_id"/>
|
||||
<result property="departmentName" column="department_name"/>
|
||||
<result property="doctorId" column="doctor_id"/>
|
||||
<result property="doctorName" column="doctor_name"/>
|
||||
<result property="regType" column="reg_type"/>
|
||||
<result property="fee" column="fee"/>
|
||||
<result property="appointmentDate" column="appointment_date"/>
|
||||
<result property="appointmentTime" column="appointment_time"/>
|
||||
<result property="cancelTime" column="cancel_time"/>
|
||||
<result property="cancelReason" column="cancel_reason"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="payStatus" column="pay_status"/>
|
||||
<result property="version" column="version"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectOrderList" resultMap="OrderResult">
|
||||
select * from order_main
|
||||
<where>
|
||||
<if test="orderNo != null and orderNo != ''">
|
||||
and order_no = #{orderNo}
|
||||
</if>
|
||||
<if test="patientId != null">
|
||||
and patient_id = #{patientId}
|
||||
</if>
|
||||
<if test="patientName != null and patientName != ''">
|
||||
and patient_name like #{patientName}
|
||||
</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">
|
||||
and medical_card = #{medicalCard}
|
||||
</if>
|
||||
<if test="phone != null and phone != ''">
|
||||
and phone = #{phone}
|
||||
</if>
|
||||
<if test="scheduleId != null">
|
||||
and schedule_id = #{scheduleId}
|
||||
</if>
|
||||
<if test="slotId != null">
|
||||
and slot_id = #{slotId}
|
||||
</if>
|
||||
<if test="departmentId != null">
|
||||
and department_id = #{departmentId}
|
||||
</if>
|
||||
<if test="doctorId != null">
|
||||
and doctor_id = #{doctorId}
|
||||
</if>
|
||||
<if test="status != null">
|
||||
and status = #{status}
|
||||
</if>
|
||||
<if test="payStatus != null">
|
||||
and pay_status = #{payStatus}
|
||||
</if>
|
||||
<if test="appointmentDate != null">
|
||||
and appointment_date = #{appointmentDate}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectOrderPage" resultMap="OrderResult">
|
||||
select * from order_main
|
||||
<where>
|
||||
<if test="order.orderNo != null and order.orderNo != ''">
|
||||
and order_no = #{order.orderNo}
|
||||
</if>
|
||||
<if test="order.patientId != null">
|
||||
and patient_id = #{order.patientId}
|
||||
</if>
|
||||
<if test="order.patientName != null and order.patientName != ''">
|
||||
and patient_name like #{order.patientName}
|
||||
</if>
|
||||
<if test="order.medicalCard != null and order.medicalCard != ''">
|
||||
and medical_card = #{order.medicalCard}
|
||||
</if>
|
||||
<if test="order.phone != null and order.phone != ''">
|
||||
and phone = #{order.phone}
|
||||
</if>
|
||||
<if test="order.scheduleId != null">
|
||||
and schedule_id = #{order.scheduleId}
|
||||
</if>
|
||||
<if test="order.slotId != null">
|
||||
and slot_id = #{order.slotId}
|
||||
</if>
|
||||
<if test="order.departmentId != null">
|
||||
and department_id = #{order.departmentId}
|
||||
</if>
|
||||
<if test="order.doctorId != null">
|
||||
and doctor_id = #{order.doctorId}
|
||||
</if>
|
||||
<if test="order.status != null">
|
||||
and status = #{order.status}
|
||||
</if>
|
||||
<if test="order.payStatus != null">
|
||||
and pay_status = #{order.payStatus}
|
||||
</if>
|
||||
<if test="order.appointmentDate != null">
|
||||
and appointment_date = #{order.appointmentDate}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectOrderById" resultMap="OrderResult">
|
||||
select * from order_main where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectOrderBySlotId" resultMap="OrderResult">
|
||||
select * from order_main where slot_id = #{slotId} and status = 1
|
||||
</select>
|
||||
|
||||
<insert id="insertOrder" parameterType="com.openhis.clinical.domain.Order">
|
||||
insert into order_main
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="orderNo != null and orderNo != ''">order_no,</if>
|
||||
<if test="patientId != null">patient_id,</if>
|
||||
<if test="patientName != null and patientName != ''">patient_name,</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">medical_card,</if>
|
||||
<if test="phone != null and phone != ''">phone,</if>
|
||||
<if test="gender != null">gender,</if>
|
||||
<if test="scheduleId != null">schedule_id,</if>
|
||||
<if test="slotId != null">slot_id,</if>
|
||||
<if test="departmentId != null">department_id,</if>
|
||||
<if test="departmentName != null and departmentName != ''">department_name,</if>
|
||||
<if test="doctorId != null">doctor_id,</if>
|
||||
<if test="doctorName != null and doctorName != ''">doctor_name,</if>
|
||||
<if test="regType != null and regType != ''">reg_type,</if>
|
||||
<if test="fee != null">fee,</if>
|
||||
<if test="appointmentDate != null">appointment_date,</if>
|
||||
<if test="appointmentTime != null">appointment_time,</if>
|
||||
<if test="cancelTime != null">cancel_time,</if>
|
||||
<if test="cancelReason != null and cancelReason != ''">cancel_reason,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="payStatus != null">pay_status,</if>
|
||||
<if test="version != null">version,</if>
|
||||
<if test="tenantId != null">tenant_id,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="orderNo != null and orderNo != ''">#{orderNo},</if>
|
||||
<if test="patientId != null">#{patientId},</if>
|
||||
<if test="patientName != null and patientName != ''">#{patientName},</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">#{medicalCard},</if>
|
||||
<if test="phone != null and phone != ''">#{phone},</if>
|
||||
<if test="gender != null">#{gender},</if>
|
||||
<if test="scheduleId != null">#{scheduleId},</if>
|
||||
<if test="slotId != null">#{slotId},</if>
|
||||
<if test="departmentId != null">#{departmentId},</if>
|
||||
<if test="departmentName != null and departmentName != ''">#{departmentName},</if>
|
||||
<if test="doctorId != null">#{doctorId},</if>
|
||||
<if test="doctorName != null and doctorName != ''">#{doctorName},</if>
|
||||
<if test="regType != null and regType != ''">#{regType},</if>
|
||||
<if test="fee != null">#{fee},</if>
|
||||
<if test="appointmentDate != null">#{appointmentDate},</if>
|
||||
<if test="appointmentTime != null">#{appointmentTime},</if>
|
||||
<if test="cancelTime != null">#{cancelTime},</if>
|
||||
<if test="cancelReason != null and cancelReason != ''">#{cancelReason},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="payStatus != null">#{payStatus},</if>
|
||||
<if test="version != null">#{version},</if>
|
||||
<if test="tenantId != null">#{tenantId},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null and updateBy != ''">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateOrder" parameterType="com.openhis.clinical.domain.Order">
|
||||
update order_main
|
||||
<trim prefix="set" suffixOverrides=",">
|
||||
<if test="orderNo != null and orderNo != ''">order_no = #{orderNo},</if>
|
||||
<if test="patientId != null">patient_id = #{patientId},</if>
|
||||
<if test="patientName != null and patientName != ''">patient_name = #{patientName},</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">medical_card = #{medicalCard},</if>
|
||||
<if test="phone != null and phone != ''">phone = #{phone},</if>
|
||||
<if test="gender != null">gender = #{gender},</if>
|
||||
<if test="scheduleId != null">schedule_id = #{scheduleId},</if>
|
||||
<if test="slotId != null">slot_id = #{slotId},</if>
|
||||
<if test="departmentId != null">department_id = #{departmentId},</if>
|
||||
<if test="departmentName != null and departmentName != ''">department_name = #{departmentName},</if>
|
||||
<if test="doctorId != null">doctor_id = #{doctorId},</if>
|
||||
<if test="doctorName != null and doctorName != ''">doctor_name = #{doctorName},</if>
|
||||
<if test="regType != null and regType != ''">reg_type = #{regType},</if>
|
||||
<if test="fee != null">fee = #{fee},</if>
|
||||
<if test="appointmentDate != null">appointment_date = #{appointmentDate},</if>
|
||||
<if test="appointmentTime != null">appointment_time = #{appointmentTime},</if>
|
||||
<if test="cancelTime != null">cancel_time = #{cancelTime},</if>
|
||||
<if test="cancelReason != null and cancelReason != ''">cancel_reason = #{cancelReason},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="payStatus != null">pay_status = #{payStatus},</if>
|
||||
<if test="version != null">version = #{version},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateOrderStatusById">
|
||||
update order_main set status = #{status} where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateOrderCancelInfoById">
|
||||
update order_main set status = 3, cancel_time = #{cancelTime}, cancel_reason = #{cancelReason} where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteOrderById">
|
||||
delete from order_main where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteOrderByIds">
|
||||
delete from order_main where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="countOrders" resultType="int">
|
||||
select count(*) from order_main
|
||||
<where>
|
||||
<if test="orderNo != null and orderNo != ''">
|
||||
and order_no = #{orderNo}
|
||||
</if>
|
||||
<if test="patientId != null">
|
||||
and patient_id = #{patientId}
|
||||
</if>
|
||||
<if test="scheduleId != null">
|
||||
and schedule_id = #{scheduleId}
|
||||
</if>
|
||||
<if test="slotId != null">
|
||||
and slot_id = #{slotId}
|
||||
</if>
|
||||
<if test="departmentId != null">
|
||||
and department_id = #{departmentId}
|
||||
</if>
|
||||
<if test="doctorId != null">
|
||||
and doctor_id = #{doctorId}
|
||||
</if>
|
||||
<if test="status != null">
|
||||
and status = #{status}
|
||||
</if>
|
||||
<if test="payStatus != null">
|
||||
and pay_status = #{payStatus}
|
||||
</if>
|
||||
<if test="appointmentDate != null">
|
||||
and appointment_date = #{appointmentDate}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,245 @@
|
||||
<?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.openhis.clinical.mapper.TicketMapper">
|
||||
|
||||
<resultMap type="com.openhis.clinical.domain.Ticket" id="TicketResult">
|
||||
<id property="id" column="id"/>
|
||||
<result property="busNo" column="bus_no"/>
|
||||
<result property="department" column="department"/>
|
||||
<result property="doctor" column="doctor"/>
|
||||
<result property="ticketType" column="ticket_type"/>
|
||||
<result property="time" column="time"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="fee" column="fee"/>
|
||||
<result property="patientId" column="patient_id"/>
|
||||
<result property="patientName" column="patient_name"/>
|
||||
<result property="medicalCard" column="medical_card"/>
|
||||
<result property="phone" column="phone"/>
|
||||
<result property="appointmentDate" column="appointment_date"/>
|
||||
<result property="appointmentTime" column="appointment_time"/>
|
||||
<result property="departmentId" column="department_id"/>
|
||||
<result property="doctorId" column="doctor_id"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectTicketList" parameterType="com.openhis.clinical.domain.Ticket" resultMap="TicketResult">
|
||||
select * from clinical_ticket
|
||||
<where>
|
||||
<!-- 逻辑删除条件 -->
|
||||
and delete_flag = '0'
|
||||
<!-- 其他查询条件 -->
|
||||
<if test="ticketType != null and ticketType != ''">
|
||||
and ticket_type = #{ticketType}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
and status = #{status}
|
||||
</if>
|
||||
<if test="appointmentDate != null">
|
||||
and appointment_date = cast(#{appointmentDate} as date)
|
||||
</if>
|
||||
<if test="doctorId != null">
|
||||
and doctor_id = #{doctorId}
|
||||
</if>
|
||||
<if test="departmentId != null">
|
||||
and department_id = #{departmentId}
|
||||
</if>
|
||||
<if test="time != null and time != ''">
|
||||
and time like #{time}
|
||||
</if>
|
||||
<if test="patientName != null and patientName != ''">
|
||||
and patient_name = #{patientName}
|
||||
</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">
|
||||
and medical_card = #{medicalCard}
|
||||
</if>
|
||||
<if test="phone != null and phone != ''">
|
||||
and phone = #{phone}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectTicketPage" resultMap="TicketResult">
|
||||
select * from clinical_ticket
|
||||
<where>
|
||||
<!-- 逻辑删除条件 -->
|
||||
and delete_flag = '0'
|
||||
<!-- 其他查询条件 -->
|
||||
<if test="ticket.ticketType != null and ticket.ticketType != ''">
|
||||
and ticket_type = #{ticket.ticketType}
|
||||
</if>
|
||||
<if test="ticket.status != null and ticket.status != ''">
|
||||
and status = #{ticket.status}
|
||||
</if>
|
||||
<if test="ticket.appointmentDate != null">
|
||||
and appointment_date = cast(#{ticket.appointmentDate} as date)
|
||||
</if>
|
||||
<if test="ticket.doctorId != null">
|
||||
and doctor_id = #{ticket.doctorId}
|
||||
</if>
|
||||
<if test="ticket.departmentId != null">
|
||||
and department_id = #{ticket.departmentId}
|
||||
</if>
|
||||
<if test="ticket.time != null and ticket.time != ''">
|
||||
and time like #{ticket.time}
|
||||
</if>
|
||||
<if test="ticket.patientName != null and ticket.patientName != ''">
|
||||
and patient_name = #{ticket.patientName}
|
||||
</if>
|
||||
<if test="ticket.medicalCard != null and ticket.medicalCard != ''">
|
||||
and medical_card = #{ticket.medicalCard}
|
||||
</if>
|
||||
<if test="ticket.phone != null and ticket.phone != ''">
|
||||
and phone = #{ticket.phone}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 自定义COUNT查询,解决MyBatis-Plus自动生成的COUNT查询结果不正确的问题 -->
|
||||
<select id="selectTicketPage_mpCount" resultType="java.lang.Long">
|
||||
select count(*) from clinical_ticket
|
||||
<where>
|
||||
<!-- 逻辑删除条件 -->
|
||||
and delete_flag = '0'
|
||||
<!-- 其他查询条件 -->
|
||||
<if test="ticket.ticketType != null and ticket.ticketType != ''">
|
||||
and ticket_type = #{ticket.ticketType}
|
||||
</if>
|
||||
<if test="ticket.status != null and ticket.status != ''">
|
||||
and status = #{ticket.status}
|
||||
</if>
|
||||
<if test="ticket.appointmentDate != null">
|
||||
and appointment_date = #{ticket.appointmentDate}
|
||||
</if>
|
||||
<if test="ticket.doctorId != null">
|
||||
and doctor_id = #{ticket.doctorId}
|
||||
</if>
|
||||
<if test="ticket.departmentId != null">
|
||||
and department_id = #{ticket.departmentId}
|
||||
</if>
|
||||
<if test="ticket.time != null and ticket.time != ''">
|
||||
and time like #{ticket.time}
|
||||
</if>
|
||||
<if test="ticket.patientName != null and ticket.patientName != ''">
|
||||
and patient_name = #{ticket.patientName}
|
||||
</if>
|
||||
<if test="ticket.medicalCard != null and ticket.medicalCard != ''">
|
||||
and medical_card = #{ticket.medicalCard}
|
||||
</if>
|
||||
<if test="ticket.phone != null and ticket.phone != ''">
|
||||
and phone = #{ticket.phone}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectTicketById" resultMap="TicketResult">
|
||||
select * from clinical_ticket where id = #{id} and delete_flag = '0'
|
||||
</select>
|
||||
|
||||
<insert id="insertTicket" parameterType="com.openhis.clinical.domain.Ticket">
|
||||
insert into clinical_ticket
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="busNo != null and busNo != ''">bus_no,</if>
|
||||
<if test="department != null and department != ''">department,</if>
|
||||
<if test="doctor != null and doctor != ''">doctor,</if>
|
||||
<if test="ticketType != null and ticketType != ''">ticket_type,</if>
|
||||
<if test="time != null and time != ''">time,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="fee != null and fee != ''">fee,</if>
|
||||
<if test="patientId != null">patient_id,</if>
|
||||
<if test="patientName != null and patientName != ''">patient_name,</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">medical_card,</if>
|
||||
<if test="phone != null and phone != ''">phone,</if>
|
||||
<if test="appointmentDate != null">appointment_date,</if>
|
||||
<if test="appointmentTime != null">appointment_time,</if>
|
||||
<if test="departmentId != null">department_id,</if>
|
||||
<if test="doctorId != null">doctor_id,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="busNo != null and busNo != ''">#{busNo},</if>
|
||||
<if test="department != null and department != ''">#{department},</if>
|
||||
<if test="doctor != null and doctor != ''">#{doctor},</if>
|
||||
<if test="ticketType != null and ticketType != ''">#{ticketType},</if>
|
||||
<if test="time != null and time != ''">#{time},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="fee != null and fee != ''">#{fee},</if>
|
||||
<if test="patientId != null">#{patientId},</if>
|
||||
<if test="patientName != null and patientName != ''">#{patientName},</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">#{medicalCard},</if>
|
||||
<if test="phone != null and phone != ''">#{phone},</if>
|
||||
<if test="appointmentDate != null">#{appointmentDate},</if>
|
||||
<if test="appointmentTime != null">#{appointmentTime},</if>
|
||||
<if test="departmentId != null">#{departmentId},</if>
|
||||
<if test="doctorId != null">#{doctorId},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null and updateBy != ''">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateTicket" parameterType="com.openhis.clinical.domain.Ticket">
|
||||
update clinical_ticket
|
||||
<trim prefix="set" suffixOverrides=",">
|
||||
<if test="busNo != null and busNo != ''">bus_no = #{busNo},</if>
|
||||
<if test="department != null and department != ''">department = #{department},</if>
|
||||
<if test="doctor != null and doctor != ''">doctor = #{doctor},</if>
|
||||
<if test="ticketType != null and ticketType != ''">ticket_type = #{ticketType},</if>
|
||||
<if test="time != null and time != ''">time = #{time},</if>
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="fee != null and fee != ''">fee = #{fee},</if>
|
||||
<if test="patientId != null">patient_id = #{patientId},</if>
|
||||
<if test="patientName != null and patientName != ''">patient_name = #{patientName},</if>
|
||||
<if test="medicalCard != null and medicalCard != ''">medical_card = #{medicalCard},</if>
|
||||
<if test="phone != null and phone != ''">phone = #{phone},</if>
|
||||
<if test="appointmentDate != null">appointment_date = #{appointmentDate},</if>
|
||||
<if test="appointmentTime != null">appointment_time = #{appointmentTime},</if>
|
||||
<if test="departmentId != null">department_id = #{departmentId},</if>
|
||||
<if test="doctorId != null">doctor_id = #{doctorId},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteTicketById">
|
||||
delete from clinical_ticket where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteTicketByIds">
|
||||
delete from clinical_ticket where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="countTickets" resultType="int">
|
||||
select count(*) from clinical_ticket
|
||||
<where>
|
||||
<if test="ticketType != null and ticketType != ''">
|
||||
and ticket_type = #{ticketType}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
and status = #{status}
|
||||
</if>
|
||||
<if test="appointmentDate != null">
|
||||
and appointment_date = cast(#{appointmentDate} as date)
|
||||
</if>
|
||||
<if test="doctorId != null">
|
||||
and doctor_id = #{doctorId}
|
||||
</if>
|
||||
<if test="departmentId != null">
|
||||
and department_id = #{departmentId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
10
openhis-server-new/start.bat
Normal file
10
openhis-server-new/start.bat
Normal file
@@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
|
||||
rem 设置项目根目录
|
||||
set PROJECT_ROOT=%~dp0
|
||||
|
||||
rem 设置classpath
|
||||
set CLASSPATH=%PROJECT_ROOT%openhis-application\target\classes;%PROJECT_ROOT%openhis-domain\target\classes;%PROJECT_ROOT%openhis-common\target\classes;%PROJECT_ROOT%core-admin\target\classes;%PROJECT_ROOT%core-framework\target\classes;%PROJECT_ROOT%core-system\target\classes;%PROJECT_ROOT%core-quartz\target\classes;%PROJECT_ROOT%core-generator\target\classes;%PROJECT_ROOT%core-flowable\target\classes;%PROJECT_ROOT%core-common\target\classes
|
||||
|
||||
rem 启动应用
|
||||
java -cp "%CLASSPATH%" com.openhis.OpenHisApplication
|
||||
13
openhis-server-new/start.sh
Normal file
13
openhis-server-new/start.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 设置项目根目录
|
||||
PROJECT_ROOT=$(pwd)
|
||||
|
||||
# 设置classpath
|
||||
CLASSPATH="$PROJECT_ROOT/openhis-application/target/classes:$PROJECT_ROOT/openhis-domain/target/classes:$PROJECT_ROOT/openhis-common/target/classes:$PROJECT_ROOT/core-admin/target/classes:$PROJECT_ROOT/core-framework/target/classes:$PROJECT_ROOT/core-system/target/classes:$PROJECT_ROOT/core-quartz/target/classes:$PROJECT_ROOT/core-generator/target/classes:$PROJECT_ROOT/core-flowable/target/classes:$PROJECT_ROOT/core-common/target/classes"
|
||||
|
||||
# 添加所有依赖jar包
|
||||
export CLASSPATH="$CLASSPATH:$(find $PROJECT_ROOT/openhis-application/target/dependency -name '*.jar' | tr '\n' ':')"
|
||||
|
||||
# 启动应用
|
||||
java -cp "$CLASSPATH" com.openhis.OpenHisApplication
|
||||
57
openhis-ui-vue3/src/api/appoinmentmanage/ticket.js
Normal file
57
openhis-ui-vue3/src/api/appoinmentmanage/ticket.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询号源列表
|
||||
export function listTicket(query) {
|
||||
return request({
|
||||
url: '/appointment/ticket/list',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
}
|
||||
|
||||
// 预约号源
|
||||
export function bookTicket(data) {
|
||||
return request({
|
||||
url: '/appointment/ticket/book',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 取消预约
|
||||
export function cancelTicket(ticketId) {
|
||||
return request({
|
||||
url: '/appointment/ticket/cancel',
|
||||
method: 'post',
|
||||
params: { ticketId }
|
||||
})
|
||||
}
|
||||
|
||||
// 取号
|
||||
export function checkInTicket(ticketId) {
|
||||
return request({
|
||||
url: '/appointment/ticket/checkin',
|
||||
method: 'post',
|
||||
params: { ticketId }
|
||||
})
|
||||
}
|
||||
|
||||
// 停诊
|
||||
export function cancelConsultation(ticketId) {
|
||||
return request({
|
||||
url: '/appointment/ticket/cancelConsultation',
|
||||
method: 'post',
|
||||
params: { ticketId }
|
||||
})
|
||||
}
|
||||
|
||||
// 查询所有号源(用于测试)
|
||||
export function listAllTickets() {
|
||||
return request({
|
||||
url: '/appointment/ticket/listAll',
|
||||
method: 'get',
|
||||
headers: {
|
||||
isToken: false
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -6,28 +6,63 @@
|
||||
:ellipsis="false"
|
||||
>
|
||||
<template v-for="(item, index) in topMenus">
|
||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
|
||||
<!-- 处理有子菜单的情况 -->
|
||||
<template v-if="item.children && item.children.length > 0 && index < visibleNumber">
|
||||
<el-sub-menu :style="{'--theme': theme}" :index="item.path" :key="index">
|
||||
<template #title>
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</template>
|
||||
<template v-for="(child, childIndex) in item.children" :key="childIndex">
|
||||
<el-menu-item :index="item.path + '/' + (child.path || '')">
|
||||
{{ child.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-sub-menu>
|
||||
</template>
|
||||
<!-- 处理无子菜单的情况 -->
|
||||
<template v-else-if="index < visibleNumber">
|
||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 顶部菜单超出数量折叠 -->
|
||||
<el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber">
|
||||
<template #title>更多菜单</template>
|
||||
<template v-for="(item, index) in topMenus">
|
||||
<el-menu-item
|
||||
:index="item.path"
|
||||
:key="index"
|
||||
v-if="index >= visibleNumber">
|
||||
<template v-for="(item, index) in topMenus" :key="index">
|
||||
<!-- 处理有子菜单的情况 -->
|
||||
<template v-if="item.children && item.children.length > 0 && index >= visibleNumber">
|
||||
<el-sub-menu :index="item.path">
|
||||
<template #title>
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</template>
|
||||
<template v-for="(child, childIndex) in item.children" :key="childIndex">
|
||||
<el-menu-item :index="item.path + '/' + (child.path || '')">
|
||||
{{ child.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-sub-menu>
|
||||
</template>
|
||||
<!-- 处理无子菜单的情况 -->
|
||||
<template v-else-if="index >= visibleNumber">
|
||||
<el-menu-item :index="item.path">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
</el-sub-menu>
|
||||
</el-menu>
|
||||
</template>
|
||||
@@ -108,6 +143,20 @@ const activeMenu = computed(() => {
|
||||
activePath = path;
|
||||
appStore.toggleSideBarHide(true);
|
||||
}
|
||||
|
||||
// 检查当前路径是否是子菜单路径
|
||||
let isChildRoute = false;
|
||||
for (const item of routers.value) {
|
||||
if (item.children && item.children.length > 0) {
|
||||
const childRoute = item.children.find(child => (item.path + '/' + (child.path || '')) === path);
|
||||
if (childRoute) {
|
||||
isChildRoute = true;
|
||||
activePath = item.path; // 激活父菜单
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activeRoutes(activePath);
|
||||
return activePath;
|
||||
})
|
||||
@@ -123,6 +172,27 @@ function handleSelect(key, keyPath) {
|
||||
if (isHttp(key)) {
|
||||
// http(s):// 路径新窗口打开
|
||||
window.open(key, "_blank");
|
||||
} else {
|
||||
// 检查是否是子菜单路径
|
||||
let isChildRoute = false;
|
||||
let parentRoute = null;
|
||||
|
||||
// 查找父路由
|
||||
for (const item of routers.value) {
|
||||
if (item.children && item.children.length > 0) {
|
||||
const childRoute = item.children.find(child => (item.path + '/' + (child.path || '')) === key);
|
||||
if (childRoute) {
|
||||
isChildRoute = true;
|
||||
parentRoute = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isChildRoute) {
|
||||
// 处理子菜单路径
|
||||
router.push({ path: key });
|
||||
appStore.toggleSideBarHide(true);
|
||||
} else if (!route || !route.children) {
|
||||
// 没有子路由路径内部打开
|
||||
const routeMenu = childrenMenus.value.find(item => item.path === key);
|
||||
@@ -138,6 +208,7 @@ function handleSelect(key, keyPath) {
|
||||
activeRoutes(key);
|
||||
appStore.toggleSideBarHide(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function activeRoutes(key) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</app-link>
|
||||
</template>
|
||||
|
||||
<el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
|
||||
<el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)">
|
||||
<template v-if="item.meta" #title>
|
||||
<svg-icon v-if="item.meta.icon" :icon-class="item.meta.icon" />
|
||||
<span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
|
||||
|
||||
@@ -58,7 +58,7 @@ const isCollapse = computed(() => !appStore.sidebar.opened);
|
||||
|
||||
const activeMenu = computed(() => {
|
||||
const { meta, path } = route;
|
||||
// if set path, the sidebar will highlight the path you set
|
||||
// if set path, sidebar will highlight the path you set
|
||||
if (meta.activeMenu) {
|
||||
return meta.activeMenu;
|
||||
}
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
import {createRouter, createWebHistory} from 'vue-router';
|
||||
import { createWebHistory, createRouter } from 'vue-router'
|
||||
/* Layout */
|
||||
import Layout from '@/layout';
|
||||
import Layout from '@/layout'
|
||||
|
||||
/**
|
||||
* Note: 路由配置项说明
|
||||
* Note: 路由配置项
|
||||
*
|
||||
* hidden: true // 当设置 true 时,该路由不会在侧边栏出现(如401、login等页面,或一些编辑页面/edit/1)
|
||||
* alwaysShow: true // 当路由下的 children 声明的路由大于1个时,自动变为嵌套模式(如组件页面)
|
||||
* // 只有一个时,会将子路由作为根路由显示在侧边栏(如引导页面)
|
||||
* // 若想不管 children 个数都显示根路由,可设置 alwaysShow: true,忽略之前定义的规则
|
||||
* redirect: noRedirect // 当设置 noRedirect 时,该路由在面包屑导航中不可点击
|
||||
* name:'router-name' // 设定路由的名字,必须填写,否则使用<keep-alive>时会出现问题
|
||||
* hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
|
||||
* alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
|
||||
* // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
|
||||
* // 若你想不管路由下面的 children 声明的个数都显示你的根路由
|
||||
* // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
|
||||
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
|
||||
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
|
||||
* query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
|
||||
* roles: ['admin', 'common'] // 访问路由的角色权限
|
||||
* permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限
|
||||
* meta: {
|
||||
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
||||
* meta : {
|
||||
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
||||
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
|
||||
icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg
|
||||
breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示
|
||||
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮对应的侧边栏
|
||||
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
|
||||
}
|
||||
*/
|
||||
|
||||
// 公共路由 - 所有用户均可访问的路由
|
||||
// 公共路由
|
||||
export const constantRoutes = [
|
||||
|
||||
// 重定向路由
|
||||
{
|
||||
path: '/redirect',
|
||||
component: Layout,
|
||||
@@ -34,33 +33,25 @@ export const constantRoutes = [
|
||||
children: [
|
||||
{
|
||||
path: '/redirect/:path(.*)',
|
||||
component: () => import('@/views/redirect/index.vue'),
|
||||
component: () => import('@/views/redirect/index.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
// 登录路由
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/login'),
|
||||
hidden: true,
|
||||
hidden: true
|
||||
},
|
||||
// 注册路由
|
||||
{
|
||||
path: '/register',
|
||||
component: () => import('@/views/register'),
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: () => import('@/views/error/404'),
|
||||
hidden: true,
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/401',
|
||||
component: () => import('@/views/error/401'),
|
||||
hidden: true,
|
||||
hidden: true
|
||||
},
|
||||
// 首页路由
|
||||
{
|
||||
path: '',
|
||||
component: Layout,
|
||||
@@ -70,9 +61,9 @@ export const constantRoutes = [
|
||||
path: '/index',
|
||||
component: () => import('@/views/index'),
|
||||
name: 'Index',
|
||||
meta: { title: '首页', icon: 'dashboard', affix: true },
|
||||
},
|
||||
],
|
||||
meta: { title: '首页', icon: 'dashboard', affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
@@ -84,123 +75,154 @@ export const constantRoutes = [
|
||||
path: 'profile',
|
||||
component: () => import('@/views/system/user/profile/index'),
|
||||
name: 'Profile',
|
||||
meta: { title: '个人中心', icon: 'user' },
|
||||
meta: { title: '个人中心', icon: 'user' }
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
// 添加套餐管理相关路由到公共路由,确保始终可用
|
||||
{
|
||||
path: '/maintainSystem/Inspection/PackageManagement',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||
name: 'DirectPackageManagement',
|
||||
meta: { title: '套餐管理' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes = [
|
||||
{
|
||||
path: '/basicmanage',
|
||||
component: Layout,
|
||||
redirect: '/basicmanage/invoice-management',
|
||||
name: 'BasicManage',
|
||||
meta: { title: '基础管理', icon: 'component' },
|
||||
children: [
|
||||
{
|
||||
path: 'invoice-management',
|
||||
component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
|
||||
name: 'invoice-management',
|
||||
meta: { title: '发票管理' }
|
||||
}
|
||||
]
|
||||
},
|
||||
// 兼容系统业务管理路径
|
||||
{
|
||||
path: '/system/ywgz',
|
||||
component: Layout,
|
||||
redirect: '/system/ywgz/InvoiceManagement',
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'InvoiceManagement',
|
||||
component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
|
||||
name: 'SystemInvoiceManagement',
|
||||
meta: { title: '发票管理' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/tpr',
|
||||
component: () => import('@/views/inpatientNurse/tprsheet/index.vue'),
|
||||
path: '/maintainSystem',
|
||||
component: Layout,
|
||||
redirect: '/maintainSystem/chargeConfig',
|
||||
name: 'MaintainSystem',
|
||||
meta: { title: '维护系统', icon: 'system' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
redirect: 'chargeConfig'
|
||||
},
|
||||
{
|
||||
path: 'chargeConfig',
|
||||
component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
||||
name: 'ChargeConfig',
|
||||
meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
||||
},
|
||||
{
|
||||
path: 'Inspection',
|
||||
component: () => import('@/views/maintainSystem/Inspection/index.vue'),
|
||||
name: 'Inspection',
|
||||
meta: { title: '检验管理', icon: 'inspection' },
|
||||
children: [
|
||||
{
|
||||
path: 'PackageManagement',
|
||||
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||
name: 'PackageManagement',
|
||||
meta: { title: '套餐管理' }
|
||||
}
|
||||
];
|
||||
|
||||
// 动态路由 - 基于用户权限动态加载的路由
|
||||
export const dynamicRoutes = [
|
||||
// 基础管理路由
|
||||
// {
|
||||
// path: '/basicmanage',
|
||||
// component: Layout,
|
||||
// redirect: '/basicmanage/invoice-management',
|
||||
// name: 'BasicManage',
|
||||
// meta: { title: '基础管理', icon: 'component' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'invoice-management',
|
||||
// component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
|
||||
// name: 'invoice-management',
|
||||
// meta: { title: '发票管理' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 兼容系统业务管理路径的发票管理路由
|
||||
// {
|
||||
// path: '/system/ywgz',
|
||||
// component: Layout,
|
||||
// redirect: '/system/ywgz/InvoiceManagement',
|
||||
// hidden: true,
|
||||
// children: [
|
||||
// {
|
||||
// path: 'InvoiceManagement',
|
||||
// component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
|
||||
// name: 'SystemInvoiceManagement',
|
||||
// meta: { title: '发票管理' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 维护系统路由
|
||||
// {
|
||||
// path: '/maintainSystem',
|
||||
// component: Layout,
|
||||
// redirect: '/maintainSystem/chargeConfig',
|
||||
// name: 'MaintainSystem',
|
||||
// meta: { title: '维护系统', icon: 'system' },
|
||||
// children: [
|
||||
// {
|
||||
// path: '',
|
||||
// redirect: 'chargeConfig',
|
||||
// name: 'MaintainSystemIndex' // 添加名称以解决警告
|
||||
// },
|
||||
// {
|
||||
// path: 'chargeConfig', // 收费配置路由
|
||||
// component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
||||
// name: 'ChargeConfig',
|
||||
// meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
||||
// },
|
||||
// {
|
||||
// path: 'Inspection', // 检验管理路由
|
||||
// component: () => import('@/views/maintainSystem/Inspection/index.vue'),
|
||||
// name: 'Inspection',
|
||||
// meta: { title: '检验管理', icon: 'inspection' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'PackageManagement', // 套餐管理路由
|
||||
// component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||
// name: 'PackageManagement',
|
||||
// meta: { title: '套餐管理' }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 系统管理路由
|
||||
// {
|
||||
// path: '/system',
|
||||
// component: Layout,
|
||||
// redirect: '/system/user',
|
||||
// name: 'System',
|
||||
// meta: { title: '系统管理', icon: 'system' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'basicdata',
|
||||
// component: Layout,
|
||||
// redirect: '/system/basicdata/location',
|
||||
// name: 'BasicData',
|
||||
// meta: { title: '基础数据', icon: 'location' },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'operatingroom',
|
||||
// component: () => import('@/views/operatingroom/index.vue'),
|
||||
// name: 'OperatingRoomManage',
|
||||
// meta: { title: '手术室管理' }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// 租户用户设置路由
|
||||
//{
|
||||
// path: '/patient',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// children: [
|
||||
// {
|
||||
// path: 'patientmgr',
|
||||
// component: () => import('@/views/patientmanagement/patientmanagement/index.vue'),
|
||||
// name: 'Patientmgr',
|
||||
// meta: { title: '患者档案管理', icon: 'user' }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/system',
|
||||
component: Layout,
|
||||
redirect: '/system/user',
|
||||
name: 'System',
|
||||
meta: { title: '系统管理', icon: 'system' },
|
||||
children: [
|
||||
{
|
||||
path: 'user',
|
||||
component: () => import('@/views/system/user/index.vue'),
|
||||
name: 'User',
|
||||
meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] }
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
component: () => import('@/views/system/role/index.vue'),
|
||||
name: 'Role',
|
||||
meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] }
|
||||
},
|
||||
{
|
||||
path: 'menu',
|
||||
component: () => import('@/views/system/menu/index.vue'),
|
||||
name: 'Menu',
|
||||
meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] }
|
||||
},
|
||||
{
|
||||
path: 'dept',
|
||||
component: () => import('@/views/system/dept/index.vue'),
|
||||
name: 'Dept',
|
||||
meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] }
|
||||
},
|
||||
{
|
||||
path: 'post',
|
||||
component: () => import('@/views/system/post/index.vue'),
|
||||
name: 'Post',
|
||||
meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] }
|
||||
},
|
||||
{
|
||||
path: 'dict',
|
||||
component: () => import('@/views/system/dict/index.vue'),
|
||||
name: 'Dict',
|
||||
meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] }
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
component: () => import('@/views/system/config/index.vue'),
|
||||
name: 'Config',
|
||||
meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] }
|
||||
},
|
||||
{
|
||||
path: 'notice',
|
||||
component: () => import('@/views/system/notice/index.vue'),
|
||||
name: 'Notice',
|
||||
meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] }
|
||||
},
|
||||
{
|
||||
path: 'tenant',
|
||||
component: () => import('@/views/system/tenant/index.vue'),
|
||||
name: 'Tenant',
|
||||
meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/system/tenant-user',
|
||||
component: Layout,
|
||||
@@ -211,11 +233,10 @@ export const dynamicRoutes = [
|
||||
path: 'set/:tenantId(\\d+)',
|
||||
component: () => import('@/views/system/tenant/setUser'),
|
||||
name: 'SetUser',
|
||||
meta: { title: '所属用户', activeMenu: '/system/basicmanage/tenant' },
|
||||
meta: { title: '所属用户', activeMenu: '/system/tenant' }
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
// 租户合同管理路由
|
||||
{
|
||||
path: '/system/tenant-contract',
|
||||
component: Layout,
|
||||
@@ -226,23 +247,7 @@ export const dynamicRoutes = [
|
||||
path: 'set/:tenantId(\\d+)',
|
||||
component: () => import('@/views/system/tenant/setContract'),
|
||||
name: 'SetContract',
|
||||
meta: { title: '合同管理', activeMenu: '/system/basicmanage/tenant' },
|
||||
},
|
||||
],
|
||||
},
|
||||
// 预约管理路由
|
||||
{
|
||||
path: '/appoinmentmanage',
|
||||
component: Layout,
|
||||
redirect: '/appoinmentmanage/deptappthoursManage',
|
||||
name: 'AppoinmentManage',
|
||||
meta: { title: '预约管理', icon: 'appointment' },
|
||||
children: [
|
||||
{
|
||||
path: 'deptappthoursManage',
|
||||
component: () => import('@/views/appoinmentmanage/deptappthoursManage/index.vue'),
|
||||
name: 'DeptAppthoursManage',
|
||||
meta: { title: '科室预约工作时间维护', icon: 'appointment' }
|
||||
meta: { title: '合同管理', activeMenu: '/system/tenant' }
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -256,9 +261,9 @@ export const dynamicRoutes = [
|
||||
path: 'role/:userId(\\d+)',
|
||||
component: () => import('@/views/system/user/authRole'),
|
||||
name: 'AuthRole',
|
||||
meta: { title: '分配角色', activeMenu: '/system/user' },
|
||||
},
|
||||
],
|
||||
meta: { title: '分配角色', activeMenu: '/system/user' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/system/role-auth',
|
||||
@@ -270,9 +275,9 @@ export const dynamicRoutes = [
|
||||
path: 'user/:roleId(\\d+)',
|
||||
component: () => import('@/views/system/role/authUser'),
|
||||
name: 'AuthUser',
|
||||
meta: { title: '分配用户', activeMenu: '/system/role' },
|
||||
},
|
||||
],
|
||||
meta: { title: '分配用户', activeMenu: '/system/role' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/system/dict-data',
|
||||
@@ -284,9 +289,51 @@ export const dynamicRoutes = [
|
||||
path: 'index/:dictId(\\d+)',
|
||||
component: () => import('@/views/system/dict/data'),
|
||||
name: 'Data',
|
||||
meta: { title: '字典数据', activeMenu: '/system/dict' },
|
||||
meta: { title: '字典数据', activeMenu: '/system/dict' }
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
{
|
||||
path: '/monitor',
|
||||
component: Layout,
|
||||
redirect: '/monitor/operlog',
|
||||
name: 'Monitor',
|
||||
meta: { title: '系统监控', icon: 'monitor' },
|
||||
children: [
|
||||
{
|
||||
path: 'operlog',
|
||||
component: () => import('@/views/monitor/operlog/index.vue'),
|
||||
name: 'Operlog',
|
||||
meta: { title: '操作日志', icon: 'operlog', permissions: ['monitor:operlog:list'] }
|
||||
},
|
||||
{
|
||||
path: 'logininfor',
|
||||
component: () => import('@/views/monitor/logininfor/index.vue'),
|
||||
name: 'Logininfor',
|
||||
meta: { title: '登录日志', icon: 'logininfor', permissions: ['monitor:logininfor:list'] }
|
||||
},
|
||||
{
|
||||
path: 'job',
|
||||
component: () => import('@/views/monitor/job/index.vue'),
|
||||
name: 'Job',
|
||||
meta: { title: '定时任务', icon: 'job', permissions: ['monitor:job:list'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/tool',
|
||||
component: Layout,
|
||||
redirect: '/tool/gen',
|
||||
name: 'Tool',
|
||||
meta: { title: '系统工具', icon: 'tool' },
|
||||
children: [
|
||||
{
|
||||
path: 'gen',
|
||||
component: () => import('@/views/tool/gen/index.vue'),
|
||||
name: 'Gen',
|
||||
meta: { title: '代码生成', icon: 'gen', permissions: ['tool:gen:list'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/monitor/job-log',
|
||||
@@ -298,9 +345,9 @@ export const dynamicRoutes = [
|
||||
path: 'index/:jobId(\\d+)',
|
||||
component: () => import('@/views/monitor/job/log'),
|
||||
name: 'JobLog',
|
||||
meta: { title: '调度日志', activeMenu: '/monitor/job' },
|
||||
},
|
||||
],
|
||||
meta: { title: '调度日志', activeMenu: '/monitor/job' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/tool/gen-edit',
|
||||
@@ -312,35 +359,32 @@ export const dynamicRoutes = [
|
||||
path: 'index/:tableId(\\d+)',
|
||||
component: () => import('@/views/tool/gen/editTable'),
|
||||
name: 'GenEdit',
|
||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen' },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// 合并常量路由和动态路由,确保所有路由都能被访问
|
||||
const allRoutes = [...constantRoutes, ...dynamicRoutes];
|
||||
|
||||
// 添加404路由到所有路由的最后,确保捕获所有未匹配的路由
|
||||
// 添加404路由到所有路由的最后
|
||||
allRoutes.push({
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: () => import('@/views/error/404'),
|
||||
hidden: true
|
||||
});
|
||||
|
||||
// 创建Vue Router实例
|
||||
const router = createRouter({
|
||||
history: createWebHistory(), // 使用HTML5历史模式
|
||||
routes: allRoutes, // 使用合并后的所有路由
|
||||
history: createWebHistory(),
|
||||
routes: allRoutes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
// 页面滚动行为:如果有保存的位置则恢复,否则滚动到顶部
|
||||
if (savedPosition) {
|
||||
return savedPosition;
|
||||
return savedPosition
|
||||
} else {
|
||||
return { top: 0 };
|
||||
return { top: 0 }
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// 导出路由实例
|
||||
export default router;
|
||||
@@ -1,7 +1,7 @@
|
||||
import {getInfo, login, logout} from '@/api/login'
|
||||
import {getToken, removeToken, setToken} from '@/utils/auth'
|
||||
import { login, logout, getInfo } from '@/api/login'
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
import defAva from '@/assets/images/user.png'
|
||||
import {defineStore} from 'pinia'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
const useUserStore = defineStore(
|
||||
'user',
|
||||
@@ -19,9 +19,7 @@ const useUserStore = defineStore(
|
||||
roles: [],
|
||||
permissions: [],
|
||||
tenantId: '',
|
||||
tenantName: '', // 租户名称
|
||||
hospitalName:'',
|
||||
optionMap: {} // 租户配置项Map(从sys_tenant_option表读取)
|
||||
hospitalName:''
|
||||
}),
|
||||
actions: {
|
||||
// 登录
|
||||
@@ -64,10 +62,9 @@ const useUserStore = defineStore(
|
||||
this.practitionerId = res.practitionerId
|
||||
this.fixmedinsCode = res.optionJson.fixmedinsCode
|
||||
this.avatar = avatar
|
||||
this.optionMap = res.optionMap || {}
|
||||
// 优先从optionMap获取配置,如果没有则从optionJson获取
|
||||
this.hospitalName = this.optionMap.hospitalName || res.optionJson.hospitalName || ''
|
||||
this.tenantName = res.tenantName || ''
|
||||
this.hospitalName = res.optionJson.hospitalName
|
||||
// 获取tenantId,优先从res.user获取,否则从res获取
|
||||
this.tenantId = user.tenantId || res.tenantId || this.tenantId
|
||||
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
|
||||
1681
openhis-ui-vue3/src/views/appoinmentmanage/index.vue
Normal file
1681
openhis-ui-vue3/src/views/appoinmentmanage/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1638
openhis-ui-vue3/src/views/appoinmentmanage/ticketManage.vue
Normal file
1638
openhis-ui-vue3/src/views/appoinmentmanage/ticketManage.vue
Normal file
File diff suppressed because it is too large
Load Diff
289
package-lock.json
generated
289
package-lock.json
generated
@@ -1,6 +1,291 @@
|
||||
{
|
||||
"name": "his",
|
||||
"name": "work",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"axios": "^1.13.2"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.13.2.tgz",
|
||||
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"axios": "^1.13.2"
|
||||
}
|
||||
}
|
||||
115
迁移记录-DB变更记录/202512301200add_table_order_main.sql
Normal file
115
迁移记录-DB变更记录/202512301200add_table_order_main.sql
Normal file
@@ -0,0 +1,115 @@
|
||||
-- 创建序列
|
||||
CREATE SEQUENCE order_main_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
-- 创建订单主表
|
||||
CREATE TABLE "order_main" (
|
||||
-- 主键字段
|
||||
"id" int8 NOT NULL DEFAULT nextval('order_main_id_seq'::regclass),
|
||||
|
||||
-- 业务核心字段
|
||||
"order_no" varchar(32) COLLATE "pg_catalog"."default" NOT NULL, -- 订单号
|
||||
"patient_id" int8, -- 患者ID
|
||||
"patient_name" varchar(50) COLLATE "pg_catalog"."default", -- 患者姓名
|
||||
"medical_card" varchar(32) COLLATE "pg_catalog"."default", -- 就诊卡号
|
||||
"phone" varchar(20) COLLATE "pg_catalog"."default", -- 手机号
|
||||
"gender" int4, -- 性别(1-男,2-女)
|
||||
"schedule_id" int8, -- 排班ID
|
||||
"slot_id" int8, -- 号源ID
|
||||
"department_id" int8, -- 科室ID
|
||||
"department_name" varchar(100) COLLATE "pg_catalog"."default", -- 科室名称
|
||||
"doctor_id" int8, -- 医生ID
|
||||
"doctor_name" varchar(50) COLLATE "pg_catalog"."default", -- 医生姓名
|
||||
"reg_type" varchar(10) COLLATE "pg_catalog"."default", -- 号别(普通/专家)
|
||||
"fee" numeric(10,2), -- 挂号费
|
||||
"appointment_date" timestamptz(6), -- 预约日期
|
||||
"appointment_time" timestamptz(6), -- 预约时间
|
||||
"cancel_time" timestamptz(6), -- 取消时间
|
||||
"cancel_reason" varchar(200) COLLATE "pg_catalog"."default", -- 取消原因
|
||||
"status" int4 NOT NULL DEFAULT 1, -- 状态(1-预约中,2-已完成,3-已取消)
|
||||
"pay_status" int4 NOT NULL DEFAULT 0, -- 支付状态(0-未支付,1-已支付)
|
||||
"version" int4 NOT NULL DEFAULT 0, -- 版本号(乐观锁)
|
||||
|
||||
-- 继承HisBaseEntity的审计字段
|
||||
"tenant_id" int8 NOT NULL, -- 租户ID
|
||||
"delete_flag" char(1) COLLATE "pg_catalog"."default" NOT NULL DEFAULT '0', -- 删除标志(0-未删除,1-已删除)
|
||||
"create_by" varchar(32) COLLATE "pg_catalog"."default" NOT NULL DEFAULT '', -- 创建人
|
||||
"create_time" timestamptz(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
"update_by" varchar(32) COLLATE "pg_catalog"."default", -- 更新人
|
||||
"update_time" timestamptz(6), -- 更新时间
|
||||
|
||||
-- 主键约束
|
||||
CONSTRAINT "order_main_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- 设置表所有者(根据实际数据库用户修改,如果不存在postgres角色可注释掉此行)
|
||||
-- ALTER TABLE "order_main" OWNER TO "postgres";
|
||||
|
||||
-- 表及字段注释
|
||||
COMMENT ON TABLE "order_main" IS '订单主表:存储门诊预约挂号订单信息';
|
||||
|
||||
COMMENT ON COLUMN "order_main"."id" IS '主键ID';
|
||||
COMMENT ON COLUMN "order_main"."order_no" IS '订单号:唯一标识订单,系统自动生成';
|
||||
COMMENT ON COLUMN "order_main"."patient_id" IS '患者ID:关联adm_patient表';
|
||||
COMMENT ON COLUMN "order_main"."patient_name" IS '患者姓名:冗余字段,便于查询';
|
||||
COMMENT ON COLUMN "order_main"."medical_card" IS '就诊卡号:患者就诊卡编号';
|
||||
COMMENT ON COLUMN "order_main"."phone" IS '手机号:患者联系电话';
|
||||
COMMENT ON COLUMN "order_main"."gender" IS '性别:1-男,2-女';
|
||||
COMMENT ON COLUMN "order_main"."schedule_id" IS '排班ID:关联排班表';
|
||||
COMMENT ON COLUMN "order_main"."slot_id" IS '号源ID:关联clinical_ticket表';
|
||||
COMMENT ON COLUMN "order_main"."department_id" IS '科室ID:关联科室表';
|
||||
COMMENT ON COLUMN "order_main"."department_name" IS '科室名称:冗余字段,便于查询';
|
||||
COMMENT ON COLUMN "order_main"."doctor_id" IS '医生ID:关联医生表';
|
||||
COMMENT ON COLUMN "order_main"."doctor_name" IS '医生姓名:冗余字段,便于查询';
|
||||
COMMENT ON COLUMN "order_main"."reg_type" IS '号别:普通/专家';
|
||||
COMMENT ON COLUMN "order_main"."fee" IS '挂号费:挂号费用金额';
|
||||
COMMENT ON COLUMN "order_main"."appointment_date" IS '预约日期:患者预约的就诊日期';
|
||||
COMMENT ON COLUMN "order_main"."appointment_time" IS '预约时间:患者预约的具体时间';
|
||||
COMMENT ON COLUMN "order_main"."cancel_time" IS '取消时间:订单取消的时间';
|
||||
COMMENT ON COLUMN "order_main"."cancel_reason" IS '取消原因:订单取消的原因说明';
|
||||
COMMENT ON COLUMN "order_main"."status" IS '状态:1-预约中,2-已完成,3-已取消';
|
||||
COMMENT ON COLUMN "order_main"."pay_status" IS '支付状态:0-未支付,1-已支付';
|
||||
COMMENT ON COLUMN "order_main"."version" IS '版本号:乐观锁,防止并发冲突';
|
||||
COMMENT ON COLUMN "order_main"."tenant_id" IS '租户ID:多租户系统隔离字段';
|
||||
COMMENT ON COLUMN "order_main"."delete_flag" IS '删除标志:0-未删除,1-已删除';
|
||||
COMMENT ON COLUMN "order_main"."create_by" IS '创建人:存储创建者用户名';
|
||||
COMMENT ON COLUMN "order_main"."create_time" IS '创建时间:默认当前时间,带时区';
|
||||
COMMENT ON COLUMN "order_main"."update_by" IS '更新人:存储更新者用户名';
|
||||
COMMENT ON COLUMN "order_main"."update_time" IS '更新时间:带时区';
|
||||
|
||||
-- 创建索引
|
||||
CREATE INDEX "idx_order_main_order_no"
|
||||
ON "order_main" ("order_no")
|
||||
WHERE "delete_flag" = '0';
|
||||
|
||||
CREATE INDEX "idx_order_main_patient_id"
|
||||
ON "order_main" ("patient_id")
|
||||
WHERE "delete_flag" = '0';
|
||||
|
||||
CREATE INDEX "idx_order_main_slot_id"
|
||||
ON "order_main" ("slot_id")
|
||||
WHERE "delete_flag" = '0';
|
||||
|
||||
CREATE INDEX "idx_order_main_department_id"
|
||||
ON "order_main" ("department_id")
|
||||
WHERE "delete_flag" = '0';
|
||||
|
||||
CREATE INDEX "idx_order_main_doctor_id"
|
||||
ON "order_main" ("doctor_id")
|
||||
WHERE "delete_flag" = '0';
|
||||
|
||||
CREATE INDEX "idx_order_main_status"
|
||||
ON "order_main" ("status")
|
||||
WHERE "delete_flag" = '0';
|
||||
|
||||
CREATE INDEX "idx_order_main_tenant_id"
|
||||
ON "order_main" ("tenant_id", "create_time")
|
||||
WHERE "delete_flag" = '0';
|
||||
|
||||
-- 向迁移历史表插入记录
|
||||
INSERT INTO __MigrationsHistory (MigrationId, ProductVersion)
|
||||
VALUES ('202512301200add_table_order_main', '1.0.0');
|
||||
51
迁移记录-DB变更记录/202512301200verify_order_main.sql
Normal file
51
迁移记录-DB变更记录/202512301200verify_order_main.sql
Normal file
@@ -0,0 +1,51 @@
|
||||
-- 验证order_main表是否创建成功
|
||||
|
||||
-- 1. 查看表结构
|
||||
\d order_main;
|
||||
|
||||
-- 2. 查看表注释
|
||||
SELECT
|
||||
obj_description('order_main'::regclass) AS table_comment;
|
||||
|
||||
-- 3. 查看字段注释(使用pg_catalog.pg_description)
|
||||
SELECT
|
||||
a.attname AS column_name,
|
||||
d.description AS column_comment
|
||||
FROM pg_attribute a
|
||||
LEFT JOIN pg_catalog.pg_description d
|
||||
ON d.objoid = a.attrelid
|
||||
AND d.objsubid = a.attnum
|
||||
WHERE a.attrelid = 'order_main'::regclass
|
||||
AND a.attnum > 0
|
||||
AND NOT a.attisdropped
|
||||
ORDER BY a.attnum;
|
||||
|
||||
-- 4. 查看索引
|
||||
SELECT
|
||||
indexname AS index_name,
|
||||
indexdef AS index_definition
|
||||
FROM pg_indexes
|
||||
WHERE tablename = 'order_main';
|
||||
|
||||
-- 5. 查看迁移历史
|
||||
SELECT * FROM __MigrationsHistory
|
||||
WHERE MigrationId = '202512301200add_table_order_main';
|
||||
|
||||
-- 6. 查看表的所有约束
|
||||
SELECT
|
||||
conname AS constraint_name,
|
||||
contype AS constraint_type
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'order_main'::regclass;
|
||||
|
||||
-- 7. 查看序列
|
||||
SELECT
|
||||
sequencename AS sequence_name,
|
||||
last_value,
|
||||
start_value,
|
||||
increment_by
|
||||
FROM pg_sequences
|
||||
WHERE sequencename = 'order_main_id_seq';
|
||||
|
||||
-- 8. 统计表记录数
|
||||
SELECT COUNT(*) AS record_count FROM order_main;
|
||||
202
迁移记录-DB变更记录/门诊预约测试数据使用指南.md
Normal file
202
迁移记录-DB变更记录/门诊预约测试数据使用指南.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# 门诊预约挂号功能测试数据使用指南
|
||||
|
||||
## 1. 准备工作
|
||||
|
||||
### 1.1 数据库环境准备
|
||||
- 确保已安装并启动PostgreSQL数据库
|
||||
- 确保已创建`hisdev`模式(或根据实际情况修改脚本中的模式名)
|
||||
- 确保已创建相关表结构:
|
||||
- clinical_ticket (号源表)
|
||||
- adm_practitioner (医生表)
|
||||
- adm_patient (患者表)
|
||||
- cli_reservation_record (预约记录表)
|
||||
|
||||
### 1.2 验证表结构
|
||||
执行以下查询验证核心表是否存在:
|
||||
```sql
|
||||
SELECT table_name FROM information_schema.tables WHERE table_schema = 'hisdev';
|
||||
```
|
||||
|
||||
## 2. 执行测试数据脚本
|
||||
|
||||
### 2.1 脚本位置
|
||||
`d:\work\门诊预约测试数据插入.sql`
|
||||
|
||||
### 2.2 执行方式
|
||||
**方式一:通过pgAdmin执行**
|
||||
1. 打开pgAdmin,连接到数据库
|
||||
2. 选择`hisdev`模式
|
||||
3. 打开SQL编辑器,粘贴脚本内容
|
||||
4. 点击执行按钮(或按F5)
|
||||
|
||||
**方式二:通过命令行执行**
|
||||
```bash
|
||||
psql -h localhost -U username -d database_name -f "d:\work\门诊预约测试数据插入.sql"
|
||||
```
|
||||
|
||||
## 3. 测试数据说明
|
||||
|
||||
### 3.1 号源数据 (clinical_ticket)
|
||||
|
||||
#### 3.1.1 未预约状态的号源(用于测试正常预约流程)
|
||||
- 号源数量:10个普通号 + 5个专家号
|
||||
- 日期:当前系统日期
|
||||
- 医生:张三(内科)
|
||||
- 状态:`unbooked`
|
||||
|
||||
#### 3.1.2 已预约状态的号源(用于测试取消预约流程)
|
||||
- 号源数量:2个
|
||||
- 日期:当前系统日期
|
||||
- 医生:张三(内科)
|
||||
- 状态:`booked`
|
||||
- 患者:患者A、患者B
|
||||
|
||||
#### 3.1.3 已取号状态的号源(用于测试逆向用例)
|
||||
- 号源数量:1个
|
||||
- 日期:当前系统日期
|
||||
- 医生:张三(内科)
|
||||
- 状态:`checked`
|
||||
- 患者:患者C
|
||||
|
||||
#### 3.1.4 明天日期的号源(用于测试日期选择功能)
|
||||
- 号源数量:10个普通号
|
||||
- 日期:当前系统日期 + 1天
|
||||
- 医生:王五(外科)
|
||||
- 状态:`unbooked`
|
||||
|
||||
### 3.2 预约记录数据 (cli_reservation_record)
|
||||
- 记录数量:2条
|
||||
- 患者:患者A、患者B
|
||||
- 医生:张三
|
||||
|
||||
## 4. 测试用例执行指南
|
||||
|
||||
### 4.1 正向测试用例
|
||||
|
||||
#### 4.1.1 号源日期选择器-默认值
|
||||
- **测试步骤**:
|
||||
1. 打开门诊预约挂号界面
|
||||
2. 检查号源日期选择器的默认值
|
||||
- **预期结果**:默认值为当前系统日期
|
||||
|
||||
#### 4.1.2 状态筛选下拉框-默认值
|
||||
- **测试步骤**:
|
||||
1. 打开门诊预约挂号界面
|
||||
2. 检查状态筛选下拉框的默认值
|
||||
- **预期结果**:默认值为"未预约"
|
||||
|
||||
#### 4.1.3 号源预约功能-正常流程
|
||||
- **测试步骤**:
|
||||
1. 双击状态为"未预约"的号源卡片
|
||||
2. 在弹出的患者选择弹窗中选择患者
|
||||
3. 点击"确定"按钮
|
||||
- **预期结果**:卡片状态更新为"已预约",显示患者信息
|
||||
- **可用测试数据**:当前日期的未预约号源(TICKET000001-TICKET000010)
|
||||
|
||||
#### 4.1.4 取消预约功能-正常流程
|
||||
- **测试步骤**:
|
||||
1. 右键状态为"已预约"的号源卡片
|
||||
2. 选择"取消预约"选项
|
||||
3. 在二次确认弹窗中点击"确认"按钮
|
||||
- **预期结果**:号源状态恢复为"未预约",清除患者信息
|
||||
- **可用测试数据**:已预约号源(TICKET000011、TICKET000012)
|
||||
|
||||
#### 4.1.5 医生搜索框-实时搜索
|
||||
- **测试步骤**:
|
||||
1. 在左侧边栏的医生搜索框中输入医生姓名
|
||||
2. 观察医生列表的实时更新
|
||||
- **预期结果**:医生列表根据输入内容实时筛选显示
|
||||
- **可用测试数据**:张三、王五
|
||||
|
||||
#### 4.1.6 号源类型切换-联动过滤
|
||||
- **测试步骤**:
|
||||
1. 在左侧边栏切换号源类型为"专家号"
|
||||
2. 观察右侧号源卡片和左侧医生列表
|
||||
- **预期结果**:仅显示专家号的号源和医生
|
||||
- **可用测试数据**:专家号(TICKET000014-TICKET000018)
|
||||
|
||||
### 4.2 逆向测试用例
|
||||
|
||||
#### 4.2.1 号源预约功能-未选择患者
|
||||
- **测试步骤**:
|
||||
1. 双击状态为"未预约"的号源卡片
|
||||
2. 不选择患者直接点击"确定"按钮
|
||||
- **预期结果**:提示"请选择患者"
|
||||
|
||||
#### 4.2.2 取消预约功能-已取号状态
|
||||
- **测试步骤**:
|
||||
1. 右键状态为"已取号"的号源卡片
|
||||
- **预期结果**:右键菜单不显示"取消预约"选项
|
||||
- **可用测试数据**:已取号源(TICKET000013)
|
||||
|
||||
#### 4.2.3 患者信息搜索框组-无效输入
|
||||
- **测试步骤**:
|
||||
1. 在患者信息搜索框组中输入无效的姓名、就诊卡号或手机号
|
||||
2. 点击查询按钮
|
||||
- **预期结果**:返回无结果或提示"未找到匹配的患者"
|
||||
- **可用测试数据**:输入不存在的姓名(如"测试患者")、就诊卡号(如"PAT999")或手机号(如"13999999999")
|
||||
|
||||
#### 4.2.4 日期选择器-无效日期
|
||||
- **测试步骤**:
|
||||
1. 在号源日期选择器中输入无效日期(如过去日期或格式错误)
|
||||
2. 尝试查询号源
|
||||
- **预期结果**:提示"请输入有效日期"
|
||||
|
||||
#### 4.2.5 医生搜索框-无匹配结果
|
||||
- **测试步骤**:
|
||||
1. 在医生搜索框中输入不存在的医生姓名
|
||||
2. 观察医生列表
|
||||
- **预期结果**:显示"无匹配结果"或空列表
|
||||
- **可用测试数据**:输入不存在的医生姓名(如"李四")
|
||||
|
||||
## 5. 测试结果记录
|
||||
|
||||
| 用例名 | 测试步骤 | 预期结果 | 实际结果 | 测试时间 | 测试人 |
|
||||
|-------|---------|---------|---------|---------|-------|
|
||||
| 号源日期选择器-默认值 | 1. 打开门诊预约挂号界面<br>2. 检查号源日期选择器的默认值 | 默认值为当前系统日期 | | | |
|
||||
| 状态筛选下拉框-默认值 | 1. 打开门诊预约挂号界面<br>2. 检查状态筛选下拉框的默认值 | 默认值为"未预约" | | | |
|
||||
| 号源预约功能-正常流程 | 1. 双击状态为"未预约"的号源卡片<br>2. 在弹出的患者选择弹窗中选择患者<br>3. 点击"确定"按钮 | 卡片状态更新为"已预约",显示患者信息 | | | |
|
||||
| 取消预约功能-正常流程 | 1. 右键状态为"已预约"的号源卡片<br>2. 选择"取消预约"选项<br>3. 在二次确认弹窗中点击"确认"按钮 | 号源状态恢复为"未预约",清除患者信息 | | | |
|
||||
| 医生搜索框-实时搜索 | 1. 在左侧边栏的医生搜索框中输入医生姓名<br>2. 观察医生列表的实时更新 | 医生列表根据输入内容实时筛选显示 | | | |
|
||||
| 号源类型切换-联动过滤 | 1. 在左侧边栏切换号源类型为"专家号"<br>2. 观察右侧号源卡片和左侧医生列表 | 仅显示专家号的号源和医生 | | | |
|
||||
| 号源预约功能-未选择患者 | 1. 双击状态为"未预约"的号源卡片<br>2. 不选择患者直接点击"确定"按钮 | 提示"请选择患者" | | | |
|
||||
| 取消预约功能-已取号状态 | 1. 右键状态为"已取号"的号源卡片 | 右键菜单不显示"取消预约"选项 | | | |
|
||||
| 患者信息搜索框组-无效输入 | 1. 在患者信息搜索框组中输入无效的姓名、就诊卡号或手机号<br>2. 点击查询按钮 | 返回无结果或提示"未找到匹配的患者" | | | |
|
||||
| 日期选择器-无效日期 | 1. 在号源日期选择器中输入无效日期(如过去日期或格式错误)<br>2. 尝试查询号源 | 提示"请输入有效日期" | | | |
|
||||
| 医生搜索框-无匹配结果 | 1. 在医生搜索框中输入不存在的医生姓名<br>2. 观察医生列表 | 显示"无匹配结果"或空列表 | | | |
|
||||
|
||||
## 6. 注意事项
|
||||
|
||||
1. **数据唯一性**:脚本使用条件判断避免重复插入数据
|
||||
2. **日期更新**:脚本中的日期会自动使用当前系统日期
|
||||
3. **依赖关系**:号源数据依赖于医生和患者的基础数据,请确保系统中已有相关记录
|
||||
4. **测试顺序**:建议先执行正向测试,再执行逆向测试
|
||||
5. **数据清理**:测试完成后,可使用以下SQL清理测试数据:
|
||||
```sql
|
||||
DELETE FROM clinical_ticket WHERE bus_no LIKE 'TICKET%';
|
||||
DELETE FROM cli_reservation_record WHERE patient_name IN ('患者A', '患者B');
|
||||
```
|
||||
|
||||
## 7. 常见问题
|
||||
|
||||
### 7.1 执行脚本时提示表不存在
|
||||
- 检查数据库连接是否正确
|
||||
- 检查是否已创建相关表结构
|
||||
- 检查模式名是否为`hisdev`
|
||||
|
||||
### 7.2 测试数据不显示
|
||||
- 检查日期选择器是否选择了正确的日期
|
||||
- 检查状态筛选条件是否为"未预约"
|
||||
- 检查医生选择是否正确
|
||||
|
||||
### 7.3 预约功能无法正常工作
|
||||
- 检查患者选择弹窗是否能正常加载患者数据
|
||||
- 检查网络连接是否正常
|
||||
- 检查浏览器控制台是否有错误信息
|
||||
|
||||
---
|
||||
|
||||
**版本:1.0**
|
||||
**创建时间:2025-12-31**
|
||||
**更新记录:**
|
||||
- 2025-12-31:初始版本,完成测试数据说明和测试指南
|
||||
89
迁移记录-DB变更记录/门诊预约测试数据插入.sql
Normal file
89
迁移记录-DB变更记录/门诊预约测试数据插入.sql
Normal file
@@ -0,0 +1,89 @@
|
||||
-- 门诊预约挂号功能测试数据插入脚本
|
||||
-- 执行前请确保已创建相关表结构
|
||||
|
||||
-- 设置当前模式
|
||||
SET search_path TO hisdev;
|
||||
|
||||
-- ====================================
|
||||
-- 说明:
|
||||
-- 1. 此脚本主要包含号源表(clinical_ticket)的测试数据
|
||||
-- 2. 其他相关表(医生、患者、科室等)请确保系统中已有基础数据
|
||||
-- 3. 如需要完整测试,建议先在系统中创建相应的医生和患者信息
|
||||
-- ====================================
|
||||
|
||||
-- ====================================
|
||||
-- 注意:以下是可选的表结构验证
|
||||
-- 如果不确定表结构是否正确,请先执行这些查询
|
||||
-- ====================================
|
||||
-- SELECT column_name FROM information_schema.columns WHERE table_name = 'clinical_ticket';
|
||||
-- SELECT column_name FROM information_schema.columns WHERE table_name = 'adm_practitioner';
|
||||
-- SELECT column_name FROM information_schema.columns WHERE table_name = 'adm_patient';
|
||||
|
||||
|
||||
-- ====================================
|
||||
-- 5. 号源数据 (clinical_ticket)
|
||||
-- 包含不同状态的号源:未预约、已预约、已取号
|
||||
-- ====================================
|
||||
|
||||
-- 获取当前日期和明天日期
|
||||
DO $$
|
||||
DECLARE
|
||||
current_date DATE := CURRENT_DATE;
|
||||
tomorrow_date DATE := CURRENT_DATE + INTERVAL '1 day';
|
||||
BEGIN
|
||||
-- 当前日期号源
|
||||
-- 未预约状态的号源(用于测试正常预约流程)
|
||||
INSERT INTO clinical_ticket (bus_no, department, doctor, ticket_type, time, status, fee, appointment_date, appointment_time, department_id, doctor_id, create_time, tenant_id, delete_flag)
|
||||
SELECT
|
||||
'TICKET' || lpad(i::text, 6, '0'),
|
||||
'内科', '张三', '普通', '08:00-' || (7 + i) || ':50',
|
||||
'unbooked', '50', current_date, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0'
|
||||
FROM generate_series(1, 10) i
|
||||
WHERE NOT EXISTS (SELECT 1 FROM clinical_ticket WHERE bus_no = 'TICKET' || lpad(i::text, 6, '0'));
|
||||
|
||||
-- 已预约状态的号源(用于测试取消预约流程)
|
||||
INSERT INTO clinical_ticket (bus_no, department, doctor, ticket_type, time, status, fee, patient_id, patient_name, medical_card, phone, appointment_date, appointment_time, department_id, doctor_id, create_time, tenant_id, delete_flag)
|
||||
VALUES
|
||||
('TICKET000011', '内科', '张三', '普通', '09:00-09:50', 'booked', '50', 1, '患者A', 'PAT001', '13900139001', current_date, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0'),
|
||||
('TICKET000012', '内科', '张三', '普通', '09:50-10:40', 'booked', '50', 2, '患者B', 'PAT002', '13900139002', current_date, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0');
|
||||
|
||||
-- 已取号状态的号源(用于测试逆向用例:取消已取号的预约)
|
||||
INSERT INTO clinical_ticket (bus_no, department, doctor, ticket_type, time, status, fee, patient_id, patient_name, medical_card, phone, appointment_date, appointment_time, department_id, doctor_id, create_time, tenant_id, delete_flag)
|
||||
VALUES
|
||||
('TICKET000013', '内科', '张三', '普通', '10:40-11:30', 'checked', '50', 3, '患者C', 'PAT003', '13900139003', current_date, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0');
|
||||
|
||||
-- 专家号源(用于测试号源类型切换功能)
|
||||
INSERT INTO clinical_ticket (bus_no, department, doctor, ticket_type, time, status, fee, appointment_date, appointment_time, department_id, doctor_id, create_time, tenant_id, delete_flag)
|
||||
VALUES
|
||||
('TICKET000014', '内科', '张三', '专家', '08:00-08:50', 'unbooked', '150', CURRENT_DATE, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0'),
|
||||
('TICKET000015', '内科', '张三', '专家', '09:00-09:50', 'unbooked', '150', CURRENT_DATE, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0'),
|
||||
('TICKET000016', '内科', '张三', '专家', '10:00-10:50', 'unbooked', '150', CURRENT_DATE, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0'),
|
||||
('TICKET000017', '内科', '张三', '专家', '11:00-11:50', 'unbooked', '150', CURRENT_DATE, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0'),
|
||||
('TICKET000018', '内科', '张三', '专家', '14:00-14:50', 'unbooked', '150', CURRENT_DATE, CURRENT_TIMESTAMP, 1, 1, CURRENT_TIMESTAMP, 1, '0');
|
||||
|
||||
-- 明天日期的号源(用于测试日期选择功能)
|
||||
INSERT INTO clinical_ticket (bus_no, department, doctor, ticket_type, time, status, fee, appointment_date, appointment_time, department_id, doctor_id, create_time, tenant_id, delete_flag)
|
||||
SELECT
|
||||
'TICKET' || lpad((20 + i)::text, 6, '0'),
|
||||
'外科', '王五', '普通', '08:00-' || (7 + i) || ':50',
|
||||
'unbooked', '60', tomorrow_date, CURRENT_TIMESTAMP, 2, 3, CURRENT_TIMESTAMP, 1, '0'
|
||||
FROM generate_series(1, 10) i
|
||||
WHERE NOT EXISTS (SELECT 1 FROM clinical_ticket WHERE bus_no = 'TICKET' || lpad((20 + i)::text, 6, '0'));
|
||||
END $$;
|
||||
|
||||
-- ====================================
|
||||
-- 6. 预约记录数据 (cli_reservation_record)
|
||||
-- 用于测试预约历史查询
|
||||
-- ====================================
|
||||
INSERT INTO cli_reservation_record (patient_name, patient_tel, chief_complaint, reservation_time, org_id, practitioner_id, tenant_id, create_time, create_by, update_time, update_by)
|
||||
VALUES
|
||||
('患者A', '13900139001', '感冒发烧', CURRENT_TIMESTAMP, 1, 1, 1, CURRENT_TIMESTAMP, 'system', CURRENT_TIMESTAMP, 'system'),
|
||||
('患者B', '13900139002', '腹痛', CURRENT_TIMESTAMP, 1, 1, 1, CURRENT_TIMESTAMP, 'system', CURRENT_TIMESTAMP, 'system');
|
||||
|
||||
-- ====================================
|
||||
-- 数据插入完成提示
|
||||
-- ====================================
|
||||
SELECT '门诊预约测试数据插入完成!' AS message;
|
||||
SELECT '未预约号源数量:' || COUNT(*) FROM clinical_ticket WHERE status = 'unbooked';
|
||||
SELECT '已预约号源数量:' || COUNT(*) FROM clinical_ticket WHERE status = 'booked';
|
||||
SELECT '已取号号源数量:' || COUNT(*) FROM clinical_ticket WHERE status = 'checked';
|
||||
Reference in New Issue
Block a user