Compare commits
210 Commits
master
...
4ba4f80946
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ba4f80946 | ||
|
|
ed7cb2dab5 | ||
| 50ef9e6743 | |||
| 250d7dde34 | |||
| 69f3e066db | |||
|
|
afb0c3933c | ||
|
|
45ac07e57c | ||
|
|
262ea97824 | ||
|
|
dcfa13f239 | ||
|
|
27c3c850d6 | ||
| 122a15a73d | |||
| 61749aee4d | |||
| 97a29a31c5 | |||
| c3734f921c | |||
| c561586cfa | |||
|
|
60593233bc | ||
| 992b03f9c2 | |||
| 36628342dc | |||
|
|
3783e4a872 | ||
| 584f79294b | |||
| a5884ec069 | |||
| cc2f7db754 | |||
| fcccfc1959 | |||
| c5ec91e7d3 | |||
| 6b67e25d94 | |||
| 6da3b63012 | |||
|
|
ea0f0e2294 | ||
|
|
980f0aeb9c | ||
|
|
17b40118ce | ||
|
|
d10a78e5e8 | ||
|
|
f7ad010b2a | ||
|
|
1a7ff0a686 | ||
|
|
3ad3f21362 | ||
|
|
c84fc3c236 | ||
|
|
a6561e2ca6 | ||
|
|
dfe35bb7f0 | ||
| 18c96e006f | |||
| f5db504363 | |||
| deb31c969a | |||
| e7dac9762d | |||
|
|
89862878b5 | ||
|
|
e105919dab | ||
|
|
e83fc94334 | ||
| 5bf7ab481f | |||
| afa904bd83 | |||
| a343464d8d | |||
| 4a2485e434 | |||
|
|
4e2d4d85ec | ||
| 7ddf6211ee | |||
| d44600b641 | |||
| a68c4402de | |||
| 93103f7f40 | |||
| 7202151a41 | |||
| 491d8f8930 | |||
| b886726ecc | |||
|
|
9d0dde6794 | ||
|
|
f3578b3202 | ||
|
|
0610ba7cb5 | ||
|
|
8b848f787a | ||
| a794cd0ce3 | |||
|
|
d97fd0bed1 | ||
|
|
c0e67722d9 | ||
|
|
aca7fea69f | ||
| ce9344f9ce | |||
| 991ad61655 | |||
|
|
e4ac857461 | ||
|
|
24ab98ae89 | ||
| e79ab9ac4f | |||
| b66c2027d1 | |||
| 09bf895711 | |||
|
|
825cdd58ae | ||
| 0977eb8145 | |||
|
|
73efeecfc1 | ||
| fe8fb3d321 | |||
|
|
618fb1e340 | ||
|
|
215fe8b889 | ||
|
|
3e32458b7f | ||
| a8e170ea45 | |||
| 1856ae50fd | |||
| 1711e6c115 | |||
|
|
b3f226feab | ||
| c086dc8c77 | |||
| 6762341fbd | |||
| d5f8b0f23b | |||
|
|
38233110f2 | ||
| 6ebb59bc5e | |||
| 69aefab280 | |||
| 3d3ff82e24 | |||
| 69780d204f | |||
|
|
ef52f290fe | ||
| e9d1119777 | |||
|
|
cf182f0e34 | ||
|
|
626ae1a459 | ||
| 3d6977328f | |||
| 2dcd7ba1d5 | |||
|
|
16a4d38113 | ||
| 57c98ea39d | |||
| 08f7e35042 | |||
| 43f3d1ba94 | |||
| 2e45c6c029 | |||
| 945182c6f8 | |||
|
|
f7de87860b | ||
| 67e4de0d68 | |||
|
|
602d521424 | ||
|
|
01e14ee084 | ||
|
|
4a5572de26 | ||
| 88a516d1be | |||
| 9ce967002a | |||
| fd536a035e | |||
| df84a7eefa | |||
| 2804703eaa | |||
| e14a0e3d13 | |||
| 5a99fe8234 | |||
| 3ad5c5533f | |||
|
|
9997f4f7c9 | ||
|
|
3d4e4a8119 | ||
|
|
3deac74898 | ||
| 7bbc50ef47 | |||
| 4ae6765a15 | |||
| 1292853c5d | |||
|
|
41791c9ccc | ||
|
|
0674215b53 | ||
| e42d990304 | |||
| 0dbe9a57c8 | |||
| 85ea831a1c | |||
| 7ac26cf781 | |||
| b7412648b4 | |||
|
|
97571652e5 | ||
| b5d4da97f9 | |||
|
|
e5edb6bda2 | ||
|
|
0e1ae53194 | ||
| a1efd3f91b | |||
| 3211553d0d | |||
| a57a326b83 | |||
| f77d0a2567 | |||
| 72581466aa | |||
|
|
4b3471df06 | ||
|
|
68c65ae8bd | ||
| 1b879addc7 | |||
|
|
3888859b2b | ||
|
|
f03d2e1633 | ||
| bc91eb7cdc | |||
|
|
93120e973a | ||
| c6a27f6276 | |||
| 778704c9dc | |||
| ff227b40c1 | |||
| c7d8ab5b48 | |||
| 9c27b2a134 | |||
|
|
3f919188d2 | ||
| 8942058972 | |||
|
|
6c2dbf0418 | ||
|
|
85e185bab8 | ||
|
|
88aa1517ef | ||
|
|
c05118c427 | ||
|
|
2a7f1326b9 | ||
|
|
c07255fe5b | ||
|
|
749bfc89dd | ||
| 52cc5e3aae | |||
| 642c4a0941 | |||
| 30953d5771 | |||
| 83e0c663c9 | |||
| b19337e76a | |||
| ba607346bd | |||
|
|
433c452a40 | ||
|
|
a1be7fdbfd | ||
|
|
87409d0c93 | ||
| d5c8ae8d45 | |||
| bc45e9c8c6 | |||
|
|
42992382c0 | ||
|
|
22d7eba510 | ||
| 9728c8a6dd | |||
| c951144ac6 | |||
|
|
0b179fffd6 | ||
|
|
75374ac5d3 | ||
|
|
2a83719b87 | ||
|
|
e58f2d807b | ||
|
|
b2884def17 | ||
|
|
064840dd42 | ||
| 1aa814c766 | |||
|
|
b9719a51d1 | ||
|
|
03b83aaf7c | ||
|
|
d93976483b | ||
| dd0a3a915c | |||
| 2f3994c575 | |||
| daa78e128f | |||
| 2ca594cb39 | |||
|
|
7805c26f4a | ||
|
|
b7d34537c2 | ||
| c1213fcf59 | |||
| a64edace55 | |||
| 4afe0d107c | |||
|
|
d8af11412f | ||
|
|
00816c9834 | ||
|
|
4fb7bea80a | ||
|
|
0fc72cb270 | ||
|
|
eadf521903 | ||
| f786fdbc3f | |||
| 92c4c938a3 | |||
|
|
a94a1b7b69 | ||
|
|
48755c2d9e | ||
|
|
f99f8eb560 | ||
|
|
ddc7ce2fe7 | ||
|
|
c9899c62d2 | ||
| 8b9837d7dc | |||
| 2cba41331a | |||
| 4da5ca427b | |||
| f4605b1af7 | |||
|
|
d2babdc9ed | ||
| 4d0599eac1 | |||
|
|
35d99df274 |
@@ -8,7 +8,7 @@
|
||||
|
||||
天天开源的前⾝是新致开源,最早于2022年6⽉发布开源医疗软件平台OpenHIS.org.cn,于2023年6⽉发布开源企业软件平台OpenCOM.com.cn。2025年7⽉,新致开源品牌更新为天天开源,我们始终秉持开源、专业、协作的理念,致⼒于为医疗、教育、中⼩企业等⾏业提供优质的开源解决⽅案。
|
||||
|
||||
了解我们:https://open.tntlinking.com/about?site=gitee
|
||||
了解我们a:https://open.tntlinking.com/about?site=gitee
|
||||
|
||||
## 💾【部署包下载】
|
||||
|
||||
|
||||
45
openhis-server-new/com/openhis/tool/DatabaseFieldAdder.java
Normal file
45
openhis-server-new/com/openhis/tool/DatabaseFieldAdder.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package com.openhis.tool;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.Statement;
|
||||
|
||||
/**
|
||||
* Database field adder tool
|
||||
*/
|
||||
public class DatabaseFieldAdder {
|
||||
public static void main(String[] args) {
|
||||
String url = "jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=public";
|
||||
String username = "postgresql";
|
||||
String password = "Jchl1528";
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(url, username, password);
|
||||
Statement stmt = conn.createStatement()) {
|
||||
|
||||
// Check if field exists
|
||||
String checkSql = "SELECT column_name FROM information_schema.columns " +
|
||||
"WHERE table_name = 'adm_healthcare_service' AND column_name = 'practitioner_id'";
|
||||
|
||||
boolean fieldExists = stmt.executeQuery(checkSql).next();
|
||||
|
||||
if (!fieldExists) {
|
||||
// Add field
|
||||
String addSql = "ALTER TABLE \"public\".\"adm_healthcare_service\" " +
|
||||
"ADD COLUMN \"practitioner_id\" int8";
|
||||
stmt.execute(addSql);
|
||||
|
||||
// Add comment
|
||||
String commentSql = "COMMENT ON COLUMN \"public\".\"adm_healthcare_service\".\"practitioner_id\" IS 'practitioner_id'";
|
||||
stmt.execute(commentSql);
|
||||
|
||||
System.out.println("Successfully added practitioner_id field to adm_healthcare_service table");
|
||||
} else {
|
||||
System.out.println("practitioner_id field already exists");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error executing SQL: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,10 @@ public final class AgeCalculatorUtil {
|
||||
* 当前年龄取得(床位列表表示年龄用)
|
||||
*/
|
||||
public static String getAge(Date date) {
|
||||
// 添加空值检查
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
// 将 Date 转换为 LocalDateTime
|
||||
LocalDateTime dateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
@@ -22,10 +22,11 @@ import com.core.common.utils.StringUtils;
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
@Value("${xss.excludes}")
|
||||
// 添加默认值,避免配置不存在时启动失败
|
||||
@Value("${xss.excludes:/system/notice}")
|
||||
private String excludes;
|
||||
|
||||
@Value("${xss.urlPatterns}")
|
||||
@Value("${xss.urlPatterns:/system/*,/monitor/*,/tool/*}")
|
||||
private String urlPatterns;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
|
||||
@@ -58,6 +58,7 @@ public class GenController extends BaseController {
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo genList(GenTable genTable) {
|
||||
startPage();
|
||||
|
||||
List<GenTable> list = genTableService.selectGenTableList(genTable);
|
||||
return getDataTable(list);
|
||||
}
|
||||
@@ -251,12 +252,10 @@ public class GenController extends BaseController {
|
||||
InputStream is = file.getInputStream();
|
||||
Workbook wb = WorkbookFactory.create(is);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// 遍历每个sheet页(每个表)
|
||||
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
|
||||
sb.append("-- ----------------------------------------------------------------------------------\n");
|
||||
Sheet st = wb.getSheetAt(i);
|
||||
|
||||
// 从第一行读取表名表注释
|
||||
Row row0 = st.getRow(0);// 表名
|
||||
String tableName = row0.getCell(4).toString();// 表名
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "http")
|
||||
@PropertySource(value = {"classpath:http.yml"})
|
||||
public class HttpConfig {
|
||||
public class HttpConfig {
|
||||
private String appId;
|
||||
private String key;
|
||||
private String url;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.openhis.web.basicmanage.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.administration.domain.Invoice;
|
||||
import com.openhis.administration.service.IInvoiceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 发票管理控制器
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-02-20
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/basicmanage/invoice")
|
||||
public class InvoiceController {
|
||||
|
||||
@Autowired
|
||||
private IInvoiceService invoiceService;
|
||||
|
||||
/**
|
||||
* 分页查询发票列表(带用户角色权限过滤)
|
||||
*
|
||||
* @param pageNo 页码
|
||||
* @param pageSize 每页条数
|
||||
* @param request 请求对象
|
||||
* @return 发票列表
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R<?> selectInvoicePage(
|
||||
@RequestParam(defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest request) {
|
||||
|
||||
// 获取当前用户ID
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
|
||||
// 判断当前用户是否为管理员
|
||||
boolean isAdmin = SecurityUtils.isAdmin(userId);
|
||||
|
||||
// 分页查询发票列表
|
||||
Page<Invoice> page = new Page<>(pageNo, pageSize);
|
||||
return R.ok(invoiceService.selectInvoicePage(page, isAdmin, userId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.openhis.web.basicmanage.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.administration.domain.InvoiceSegment;
|
||||
import com.openhis.administration.service.IInvoiceSegmentService;
|
||||
import com.openhis.web.basicmanage.domain.InvoiceSegmentDeleteRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 发票段管理控制器
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-11-18
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/basicmanage/invoice-segment")
|
||||
public class InvoiceSegmentController {
|
||||
|
||||
@Autowired
|
||||
private IInvoiceSegmentService invoiceSegmentService;
|
||||
|
||||
/**
|
||||
* 分页查询发票段列表(带用户角色权限过滤)
|
||||
*
|
||||
* @param pageNo 页码
|
||||
* @param pageSize 每页条数
|
||||
* @param request 请求对象
|
||||
* @return 发票段列表
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R<?> selectInvoiceSegmentPage(
|
||||
@RequestParam(defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(defaultValue = "100") Integer pageSize,
|
||||
HttpServletRequest request) {
|
||||
|
||||
// 获取当前用户ID
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
|
||||
// 判断当前用户是否为管理员
|
||||
boolean isAdmin = SecurityUtils.isAdmin(userId);
|
||||
|
||||
// 分页查询发票段列表
|
||||
Page<InvoiceSegment> page = new Page<>(pageNo, pageSize);
|
||||
return R.ok(invoiceSegmentService.selectInvoiceSegmentPage(page, isAdmin, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增发票段
|
||||
*
|
||||
* @param invoiceSegment 发票段信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public R<?> addInvoiceSegment(@RequestBody InvoiceSegment invoiceSegment) {
|
||||
// 设置创建人信息
|
||||
invoiceSegment.setCreateBy(SecurityUtils.getUsername());
|
||||
int result = invoiceSegmentService.insertInvoiceSegment(invoiceSegment);
|
||||
return result > 0 ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改发票段
|
||||
*
|
||||
* @param invoiceSegment 发票段信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
public R<?> updateInvoiceSegment(@RequestBody InvoiceSegment invoiceSegment) {
|
||||
// 设置更新人信息
|
||||
invoiceSegment.setUpdateBy(SecurityUtils.getUsername());
|
||||
int result = invoiceSegmentService.updateInvoiceSegment(invoiceSegment);
|
||||
return result > 0 ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除发票段
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
public R<?> delete(@RequestBody InvoiceSegmentDeleteRequest request) {
|
||||
int rows = invoiceSegmentService.deleteInvoiceSegmentByIds(request.getIds());
|
||||
return rows > 0 ? R.ok("删除成功") : R.fail("删除失败");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.openhis.web.basicmanage.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 发票段删除请求类
|
||||
*
|
||||
* @author system
|
||||
* @date 2024-06-19
|
||||
*/
|
||||
public class InvoiceSegmentDeleteRequest implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long[] ids;
|
||||
|
||||
public Long[] getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public void setIds(Long[] ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,14 @@ public class HealthcareServiceDto {
|
||||
private Integer appointmentRequiredFlag;
|
||||
private String appointmentRequiredFlag_enumText;
|
||||
|
||||
/**
|
||||
* 出诊医生ID
|
||||
*/
|
||||
@Dict(dictTable = "adm_practitioner", dictCode = "id", dictText = "name")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long practitionerId;
|
||||
private String practitionerId_dictText;
|
||||
|
||||
/**
|
||||
* 费用定价ID
|
||||
*/
|
||||
|
||||
@@ -82,6 +82,11 @@ public class HealthcareServiceFormData {
|
||||
@NotBlank(message = "预约要求不能为空")
|
||||
private Integer appointmentRequiredFlag;
|
||||
|
||||
/**
|
||||
* 出诊医生ID
|
||||
*/
|
||||
private Long practitionerId;
|
||||
|
||||
/** 医保编码 */
|
||||
private String ybNo;
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.openhis.web.charge.patientcardrenewal;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 患者换卡控制器
|
||||
*
|
||||
* @author system
|
||||
* @date 2024-01-01
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/charge/patientCardRenewal")
|
||||
@Slf4j
|
||||
public class PatientCardRenewalController {
|
||||
|
||||
@Autowired
|
||||
private PatientCardRenewalService patientCardRenewalService;
|
||||
|
||||
/**
|
||||
* 执行患者换卡操作
|
||||
*
|
||||
* @param request 换卡请求参数
|
||||
* @return 换卡结果
|
||||
*/
|
||||
@PostMapping("/renewCard")
|
||||
public R<?> renewCard(@RequestBody RenewalRequest request) {
|
||||
try {
|
||||
log.info("患者换卡请求: 旧卡号={}, 新卡号={}, 患者ID={}",
|
||||
request.getOldCardNo(), request.getNewCardNo(), request.getPatientId());
|
||||
|
||||
// 执行换卡操作
|
||||
boolean success = patientCardRenewalService.renewCard(request);
|
||||
|
||||
if (success) {
|
||||
log.info("患者换卡成功: 旧卡号={} -> 新卡号={}",
|
||||
request.getOldCardNo(), request.getNewCardNo());
|
||||
return R.ok("换卡成功");
|
||||
} else {
|
||||
return R.fail("换卡失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("患者换卡异常: ", e);
|
||||
return R.fail("换卡操作异常: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.web.charge.patientcardrenewal;
|
||||
|
||||
/**
|
||||
* 患者换卡服务接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2024-01-01
|
||||
*/
|
||||
public interface PatientCardRenewalService {
|
||||
|
||||
/**
|
||||
* 执行患者换卡操作
|
||||
*
|
||||
* @param request 换卡请求参数
|
||||
* @return 是否换卡成功
|
||||
*/
|
||||
boolean renewCard(RenewalRequest request);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.openhis.web.charge.patientcardrenewal;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.openhis.administration.domain.PatientIdentifier;
|
||||
import com.openhis.administration.service.IPatientIdentifierService;
|
||||
import com.openhis.common.enums.IdentifierStatusEnum;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 患者换卡服务实现类
|
||||
*
|
||||
* @author system
|
||||
* @date 2024-01-01
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PatientCardRenewalServiceImpl implements PatientCardRenewalService {
|
||||
|
||||
@Autowired
|
||||
private IPatientIdentifierService patientIdentifierService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean renewCard(RenewalRequest request) {
|
||||
log.info("执行患者换卡操作: 患者ID={}, 旧卡号={}, 新卡号={}, 原因={}",
|
||||
request.getPatientId(), request.getOldCardNo(), request.getNewCardNo(), request.getReason());
|
||||
|
||||
// 1. 验证参数合法性
|
||||
if (StringUtils.isEmpty(request.getPatientId())) {
|
||||
throw new IllegalArgumentException("患者ID不能为空");
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(request.getNewCardNo())) {
|
||||
throw new IllegalArgumentException("新卡号不能为空");
|
||||
}
|
||||
|
||||
// 2. 检查新卡号是否已被使用
|
||||
LambdaQueryWrapper<PatientIdentifier> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(PatientIdentifier::getIdentifierNo, request.getNewCardNo());
|
||||
List<PatientIdentifier> existingIdentifiers = patientIdentifierService.list(queryWrapper);
|
||||
if (existingIdentifiers != null && !existingIdentifiers.isEmpty()) {
|
||||
throw new IllegalArgumentException("新卡号已被其他患者使用,请更换新卡号");
|
||||
}
|
||||
|
||||
// 3. 直接使用患者ID作为查询条件
|
||||
Long patientId = Long.parseLong(request.getPatientId());
|
||||
// 4. 通过患者ID查询现有标识信息
|
||||
PatientIdentifier patientIdentifier = patientIdentifierService.selectByPatientId(patientId);
|
||||
|
||||
if (patientIdentifier != null) {
|
||||
// 5. 只更新就诊卡号这一个参数
|
||||
|
||||
patientIdentifier.setIdentifierNo(request.getNewCardNo());
|
||||
patientIdentifierService.updateById(patientIdentifier);
|
||||
log.info("患者ID={} 换卡成功,已更新就诊卡号", patientId);
|
||||
} else {
|
||||
throw new IllegalArgumentException("未找到患者标识信息,无法进行换卡操作");
|
||||
}
|
||||
|
||||
// 4. 记录换卡日志 - 可以根据需要扩展日志记录功能
|
||||
// 5. 处理相关业务系统的卡号更新 - 可以根据需要扩展
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.openhis.web.charge.patientcardrenewal;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 换卡请求参数类
|
||||
*
|
||||
* @author system
|
||||
* @date 2024-01-01
|
||||
*/
|
||||
@Data
|
||||
public class RenewalRequest {
|
||||
|
||||
/**
|
||||
* 旧门诊号码
|
||||
*/
|
||||
private String oldCardNo;
|
||||
|
||||
/**
|
||||
* 新门诊号码
|
||||
*/
|
||||
private String newCardNo;
|
||||
|
||||
/**
|
||||
* 患者ID
|
||||
*/
|
||||
private String patientId;
|
||||
|
||||
/**
|
||||
* 换卡原因
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 备注信息
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
@@ -91,17 +91,27 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
*/
|
||||
@Override
|
||||
public Page<PatientMetadata> getPatientMetadataBySearchKey(String searchKey, Integer pageNo, Integer pageSize) {
|
||||
// 构建查询条件
|
||||
// 构建查询条件,添加phone字段支持手机号搜索
|
||||
QueryWrapper<Patient> queryWrapper = HisQueryUtils.buildQueryWrapper(null, searchKey,
|
||||
new HashSet<>(Arrays.asList("id_card", "name", "py_str", "wb_str")), null);
|
||||
new HashSet<>(Arrays.asList("id_card", "name", "py_str", "wb_str", "phone")), null);
|
||||
// 设置排序
|
||||
queryWrapper.orderByDesc("update_time");
|
||||
// 通过证件号匹配 patient
|
||||
if (StringUtils.isNotEmpty(searchKey)) {
|
||||
PatientIdentifier patientIdentifier = patientIdentifierService
|
||||
.getOne(new LambdaQueryWrapper<PatientIdentifier>().eq(PatientIdentifier::getIdentifierNo, searchKey));
|
||||
if (patientIdentifier != null) {
|
||||
queryWrapper.or(q -> q.eq("id", patientIdentifier.getPatientId()));
|
||||
List<PatientIdentifier> patientIdentifiers = patientIdentifierService
|
||||
.list(new LambdaQueryWrapper<PatientIdentifier>().eq(PatientIdentifier::getIdentifierNo, searchKey));
|
||||
if (patientIdentifiers != null && !patientIdentifiers.isEmpty()) {
|
||||
// 如果有多个匹配结果,将它们全部添加到查询条件中
|
||||
if (patientIdentifiers.size() == 1) {
|
||||
// 单个结果时直接添加条件
|
||||
queryWrapper.or(q -> q.eq("id", patientIdentifiers.get(0).getPatientId()));
|
||||
} else {
|
||||
// 多个结果时使用in条件
|
||||
List<Long> patientIds = patientIdentifiers.stream()
|
||||
.map(PatientIdentifier::getPatientId)
|
||||
.collect(Collectors.toList());
|
||||
queryWrapper.or(q -> q.in("id", patientIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 患者信息
|
||||
@@ -120,10 +130,11 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
e.setFirstEnum_enumText(patientIdList.contains(e.getId()) ? EncounterType.FOLLOW_UP.getInfo()
|
||||
: EncounterType.INITIAL.getInfo());
|
||||
// 患者标识
|
||||
PatientIdentifier patientIdentifier = patientIdentifierService
|
||||
.getOne(new LambdaQueryWrapper<PatientIdentifier>().eq(PatientIdentifier::getPatientId, e.getId()));
|
||||
if (patientIdentifier != null) {
|
||||
e.setIdentifierNo(patientIdentifier.getIdentifierNo());
|
||||
List<PatientIdentifier> patientIdentifiers = patientIdentifierService
|
||||
.list(new LambdaQueryWrapper<PatientIdentifier>().eq(PatientIdentifier::getPatientId, e.getId()));
|
||||
if (patientIdentifiers != null && !patientIdentifiers.isEmpty()) {
|
||||
// 取第一个标识号,如果需要可以根据业务需求选择其他逻辑
|
||||
e.setIdentifierNo(patientIdentifiers.get(0).getIdentifierNo());
|
||||
}
|
||||
|
||||
});
|
||||
@@ -267,6 +278,23 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
new HashSet<>(Arrays.asList("patient_name", "organization_name", "practitioner_name", "healthcare_name")),
|
||||
request);
|
||||
|
||||
// 手动处理 statusEnum 参数(用于过滤退号记录)
|
||||
String statusEnumParam = request.getParameter("statusEnum");
|
||||
if (statusEnumParam != null && !statusEnumParam.isEmpty()) {
|
||||
try {
|
||||
Integer statusEnum = Integer.parseInt(statusEnumParam);
|
||||
if (statusEnum == -1) {
|
||||
// -1 表示排除退号记录(正常挂号)
|
||||
queryWrapper.ne("status_enum", 6);
|
||||
} else {
|
||||
// 其他值表示精确匹配
|
||||
queryWrapper.eq("status_enum", statusEnum);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效的参数值
|
||||
}
|
||||
}
|
||||
|
||||
IPage<CurrentDayEncounterDto> currentDayEncounter = outpatientRegistrationAppMapper.getCurrentDayEncounter(
|
||||
new Page<>(pageNo, pageSize), EncounterClass.AMB.getValue(), ParticipantType.ADMITTER.getCode(),
|
||||
queryWrapper, ChargeItemContext.REGISTER.getValue(), PaymentStatus.SUCCESS.getValue());
|
||||
|
||||
@@ -131,4 +131,39 @@ public class CurrentDayEncounterDto {
|
||||
*/
|
||||
private Date birthDate;
|
||||
|
||||
/**
|
||||
* 退号日期/时间
|
||||
*/
|
||||
private Date returnDate;
|
||||
|
||||
/**
|
||||
* 退号原因
|
||||
*/
|
||||
private String returnReason;
|
||||
|
||||
/**
|
||||
* 退号操作人
|
||||
*/
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 退号操作工号(用户账号)
|
||||
*/
|
||||
private String operatorId;
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*/
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
/**
|
||||
* 合同编码(费用性质代码)
|
||||
*/
|
||||
private String contractNo;
|
||||
|
||||
/**
|
||||
* 退款方式(多个支付方式用逗号分隔)
|
||||
*/
|
||||
private String refundMethod;
|
||||
|
||||
}
|
||||
|
||||
@@ -81,5 +81,11 @@ public class RefundItemDto {
|
||||
|
||||
/** 项目名 */
|
||||
private String itemName;
|
||||
|
||||
/** 费用支付方式编码 */
|
||||
private String medfeePaymtdCode;
|
||||
|
||||
/** 费用类型 */
|
||||
private String feeType;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.openhis.web.check.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
import com.openhis.check.domain.CheckPackage;
|
||||
import com.openhis.check.domain.CheckPart;
|
||||
import com.openhis.check.domain.CheckType;
|
||||
import com.openhis.check.service.ICheckMethodService;
|
||||
import com.openhis.check.service.ICheckPackageService;
|
||||
import com.openhis.check.service.ICheckPartService;
|
||||
import com.openhis.check.service.ICheckTypeService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 检查类型管理Controller
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping({"/system/check-type", "/system"})
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class CheckTypeController extends BaseController {
|
||||
|
||||
private final ICheckTypeService checkTypeService;
|
||||
private final ICheckMethodService checkMethodService;
|
||||
private final ICheckPartService checkPartService;
|
||||
private final ICheckPackageService checkPackageService;
|
||||
|
||||
/**
|
||||
* 获取检查类型列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list() {
|
||||
List<CheckType> list = checkTypeService.list();
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检查方法列表
|
||||
*/
|
||||
@GetMapping({"/method/list", "/check-method/list"})
|
||||
public AjaxResult methodList() {
|
||||
List<CheckMethod> list = checkMethodService.list();
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检查部位列表
|
||||
*/
|
||||
@GetMapping({"/part/list", "/check-part/list"})
|
||||
public AjaxResult partList() {
|
||||
List<CheckPart> list = checkPartService.list();
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检查套餐列表
|
||||
*/
|
||||
@GetMapping({"/package/list", "/check-package/list"})
|
||||
public AjaxResult packageList() {
|
||||
List<CheckPackage> list = checkPackageService.list();
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增检查类型
|
||||
*/
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody CheckType checkType) {
|
||||
return toAjax(checkTypeService.save(checkType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改检查类型
|
||||
*/
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody CheckType checkType) {
|
||||
return toAjax(checkTypeService.updateById(checkType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除检查类型
|
||||
*/
|
||||
@DeleteMapping("/{checkTypeId}")
|
||||
public AjaxResult remove(@PathVariable Long checkTypeId) {
|
||||
return toAjax(checkTypeService.removeById(checkTypeId));
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public interface ICommonService {
|
||||
/**
|
||||
* 药房列表(库房用)
|
||||
*
|
||||
* @return 药房列表
|
||||
* @return 药房列表1
|
||||
*/
|
||||
List<LocationDto> getInventoryPharmacyList();
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ public class CommonAppController {
|
||||
/**
|
||||
* 病区列表
|
||||
*
|
||||
* @return 病区列表
|
||||
* @return 病区列表
|
||||
*/
|
||||
@GetMapping(value = "/ward-list")
|
||||
public R<?> getWardList(@RequestParam(value = "orgId", required = false) Long orgId) {
|
||||
@@ -105,7 +105,7 @@ public class CommonAppController {
|
||||
*/
|
||||
@GetMapping(value = "/department-list")
|
||||
public R<?> getDepartmentList() {
|
||||
return commonService.getDepartmentList();
|
||||
return commonService.getDepartmentList();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,6 +52,14 @@ public interface IDoctorStationMainAppService {
|
||||
*/
|
||||
R<?> completeEncounter(Long encounterId);
|
||||
|
||||
/**
|
||||
* 取消完成
|
||||
*
|
||||
* @param encounterId 就诊id
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> cancelEncounter(Long encounterId);
|
||||
|
||||
/**
|
||||
* 查询处方号列表信息
|
||||
*
|
||||
|
||||
@@ -140,6 +140,17 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
||||
adviceUtils.subtractInventory(adviceInventoryList, adviceDraftInventoryList);
|
||||
// 查询取药科室配置
|
||||
List<AdviceInventoryDto> medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId);
|
||||
// 将配置转为 {categoryCode -> 允许的locationId集合}
|
||||
Map<String, Set<Long>> allowedLocByCategory = new HashMap<>();
|
||||
if (medLocationConfig != null && !medLocationConfig.isEmpty()) {
|
||||
for (AdviceInventoryDto cfg : medLocationConfig) {
|
||||
if (cfg.getCategoryCode() == null || cfg.getLocationId() == null) {
|
||||
continue;
|
||||
}
|
||||
allowedLocByCategory.computeIfAbsent(String.valueOf(cfg.getCategoryCode()), k -> new HashSet<>())
|
||||
.add(cfg.getLocationId());
|
||||
}
|
||||
}
|
||||
// 费用定价子表信息
|
||||
List<AdvicePriceDto> childCharge = doctorStationAdviceAppMapper
|
||||
.getChildCharge(ConditionCode.LOT_NUMBER_COST.getCode(), chargeItemDefinitionIdList);
|
||||
@@ -163,6 +174,19 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
||||
.filter(e -> baseDto.getAdviceDefinitionId().equals(e.getItemId())
|
||||
&& baseDto.getAdviceTableName().equals(e.getItemTable()))
|
||||
.collect(Collectors.toList());
|
||||
// 当存在按科室配置时:仅保留被允许的药房/药库的库存;
|
||||
// 若该药品类别未在配置中出现,则视为不可开立(清空库存以便前端过滤掉)
|
||||
if (!allowedLocByCategory.isEmpty()) {
|
||||
Set<Long> allowedLoc =
|
||||
allowedLocByCategory.get(String.valueOf(baseDto.getCategoryCode()));
|
||||
if (allowedLoc == null || allowedLoc.isEmpty()) {
|
||||
inventoryList = Collections.emptyList();
|
||||
} else {
|
||||
inventoryList = inventoryList.stream()
|
||||
.filter(inv -> allowedLoc.contains(inv.getLocationId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
// 库存信息
|
||||
baseDto.setInventoryList(inventoryList);
|
||||
// 设置默认产品批号
|
||||
@@ -174,18 +198,15 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
||||
baseDto.setDefaultLotNumber(hasInventoryList.get(0).getLotNumber());
|
||||
}
|
||||
}
|
||||
if (!inventoryList.isEmpty() && !medLocationConfig.isEmpty()) {
|
||||
// 第一步:在medLocationConfig中匹配categoryCode
|
||||
AdviceInventoryDto result1 = medLocationConfig.stream()
|
||||
.filter(dto -> baseDto.getCategoryCode().equals(dto.getCategoryCode())).findFirst()
|
||||
.orElse(null);
|
||||
if (result1 != null) {
|
||||
// 第二步:在inventoryList中匹配locationId
|
||||
AdviceInventoryDto result2 = inventoryList.stream()
|
||||
.filter(dto -> result1.getLocationId().equals(dto.getLocationId())).findFirst()
|
||||
.orElse(null);
|
||||
if (result2 != null && result2.getLotNumber() != null) {
|
||||
baseDto.setDefaultLotNumber(result2.getLotNumber());
|
||||
if (!inventoryList.isEmpty() && !allowedLocByCategory.isEmpty()) {
|
||||
Set<Long> allowedLoc =
|
||||
allowedLocByCategory.get(String.valueOf(baseDto.getCategoryCode()));
|
||||
if (allowedLoc != null && !allowedLoc.isEmpty()) {
|
||||
AdviceInventoryDto hit = inventoryList.stream()
|
||||
.filter(inv -> allowedLoc.contains(inv.getLocationId()))
|
||||
.findFirst().orElse(null);
|
||||
if (hit != null && hit.getLotNumber() != null) {
|
||||
baseDto.setDefaultLotNumber(hit.getLotNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package com.openhis.web.doctorstation.appservice.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.openhis.web.doctorstation.appservice.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@@ -25,7 +24,6 @@ import com.openhis.administration.service.IEncounterParticipantService;
|
||||
import com.openhis.common.enums.*;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.web.doctorstation.appservice.IDoctorStationMainAppService;
|
||||
import com.openhis.web.doctorstation.dto.PatientInfoDto;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
||||
@@ -46,6 +44,17 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
@Resource
|
||||
IEncounterParticipantService iEncounterParticipantService;
|
||||
|
||||
@Resource
|
||||
IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
|
||||
|
||||
@Resource
|
||||
IDoctorStationEmrAppService iDoctorStationEmrAppService;
|
||||
|
||||
@Resource
|
||||
IDoctorStationDiagnosisAppService iDoctorStationDiagnosisAppService;
|
||||
|
||||
@Resource
|
||||
IDoctorStationChineseMedicalAppService iDoctorStationChineseMedicalAppService;
|
||||
/**
|
||||
* 查询就诊患者信息
|
||||
*
|
||||
@@ -154,6 +163,45 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
return update > 0 ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消接诊
|
||||
*
|
||||
* @param encounterId 就诊id
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> cancelEncounter(Long encounterId) {
|
||||
//1.判断是否已经产生业务,如医生已经开有病历、处方、诊断、检验检查或相关项目已收费、执行等,
|
||||
//如果有则提示:需要医生删除、作废、退费才能【取消接诊】。
|
||||
//1.1病历
|
||||
Object emrDetailResult = iDoctorStationEmrAppService.getEmrDetail(encounterId).getData();
|
||||
|
||||
//1.2诊断
|
||||
Object diagnosisResult = iDoctorStationDiagnosisAppService.getEncounterDiagnosis(encounterId).getData();
|
||||
|
||||
//1.3处方
|
||||
Object adviceResult = iDoctorStationAdviceAppService.getRequestBaseInfo(encounterId).getData();
|
||||
|
||||
//1.4中医诊断、处方
|
||||
Map<?,?> tcmDiagnosisResult = (Map<?,?>) iDoctorStationChineseMedicalAppService.getTcmEncounterDiagnosis(encounterId).getData();
|
||||
Object symptom = tcmDiagnosisResult.get("symptom");
|
||||
Object illness = tcmDiagnosisResult.get("illness");
|
||||
Object tcmPrescriptionResult = iDoctorStationChineseMedicalAppService.getTcmRequestBaseInfo(encounterId).getData();
|
||||
|
||||
boolean isEmpty = ObjectUtil.isAllEmpty(emrDetailResult, diagnosisResult, adviceResult, symptom,illness, tcmPrescriptionResult);
|
||||
|
||||
if (!isEmpty) {
|
||||
return R.fail();
|
||||
}
|
||||
|
||||
//2.取消接诊,患者重新回到患者队列待诊中
|
||||
int update = encounterMapper.update(null,
|
||||
new LambdaUpdateWrapper<Encounter>().eq(Encounter::getId, encounterId)
|
||||
.set(Encounter::getStatusEnum, EncounterStatus.PLANNED.getValue())
|
||||
.set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.TRIAGED.getValue()));
|
||||
return update > 0 ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询处方号列表信息
|
||||
*
|
||||
|
||||
@@ -92,6 +92,17 @@ public class DoctorStationMainController {
|
||||
return iDoctorStationMainAppService.completeEncounter(encounterId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消接诊
|
||||
*
|
||||
* @param encounterId 就诊id
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping(value = "/cancel-encounter")
|
||||
public R<?> cancelEncounter(@RequestParam Long encounterId) {
|
||||
return iDoctorStationMainAppService.cancelEncounter(encounterId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询处方号列表信息
|
||||
*
|
||||
|
||||
@@ -161,6 +161,27 @@ public class PurchaseInventoryAppServiceImpl implements IPurchaseInventoryAppSer
|
||||
if (receiptDetailList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
|
||||
}
|
||||
|
||||
// 获取所有供应商ID
|
||||
Set<Long> supplierIds = receiptDetailList.stream()
|
||||
.filter(dto -> dto.getSupplierId() != null)
|
||||
.map(ReceiptDetailDto::getSupplierId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 查询供应商信息并设置供应商名称
|
||||
if (!supplierIds.isEmpty()) {
|
||||
List<Supplier> suppliers = supplierService.listByIds(supplierIds);
|
||||
Map<Long, String> supplierNameMap = suppliers.stream()
|
||||
.collect(Collectors.toMap(Supplier::getId, Supplier::getName));
|
||||
|
||||
// 设置供应商名称
|
||||
receiptDetailList.forEach(dto -> {
|
||||
if (dto.getSupplierId() != null) {
|
||||
dto.setSupplierName(supplierNameMap.getOrDefault(dto.getSupplierId(), ""));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return R.ok(receiptDetailList);
|
||||
}
|
||||
|
||||
@@ -212,7 +233,7 @@ public class PurchaseInventoryAppServiceImpl implements IPurchaseInventoryAppSer
|
||||
// 申请时间
|
||||
.setApplyTime(DateUtils.getNowDate());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 保存
|
||||
@@ -224,7 +245,7 @@ public class PurchaseInventoryAppServiceImpl implements IPurchaseInventoryAppSer
|
||||
List<Long> requestIdList = supplyRequestIdList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
for (Long list : requestIdList) {
|
||||
idList.add(list.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// 返回请求id
|
||||
return R.ok(idList, null);
|
||||
|
||||
@@ -128,10 +128,11 @@ public class PatientInformationServiceImpl implements IPatientInformationService
|
||||
public IPage<PatientInformationDto> getPatientInfo(PatientInfoSearchParam patientInfoSearchParam, String searchKey,
|
||||
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||
|
||||
// 构建查询条件
|
||||
// 构建查询条件 - 添加phone字段到搜索条件中
|
||||
QueryWrapper<PatientInformationDto> queryWrapper = HisQueryUtils.buildQueryWrapper(
|
||||
patientInfoSearchParam, searchKey, new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name,
|
||||
CommonConstants.FieldName.BusNo, CommonConstants.FieldName.PyStr, CommonConstants.FieldName.WbStr)),
|
||||
CommonConstants.FieldName.BusNo, CommonConstants.FieldName.PyStr, CommonConstants.FieldName.WbStr,
|
||||
CommonConstants.FieldName.Phone)), // 添加phone字段支持手机号搜索
|
||||
request);
|
||||
|
||||
IPage<PatientInformationDto> patientInformationPage =
|
||||
|
||||
@@ -597,7 +597,7 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
|
||||
// 全退
|
||||
String ybSettleIds = paymentReconciliation.getYbSettleIds();
|
||||
PaymentReconciliation unPaymentReconciliation = normalUnCharge(paymentReconciliation, PaymentRecDetails, null);
|
||||
PaymentReconciliation unPaymentReconciliation = normalUnCharge(paymentReconciliation, PaymentRecDetails, null, null);
|
||||
if (!StringUtils.isEmpty(ybSettleIds)) {
|
||||
// 医保结算信息
|
||||
List<String> ybSettleIdList = Arrays.asList(ybSettleIds.split(","));
|
||||
@@ -734,7 +734,7 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
}
|
||||
|
||||
PaymentReconciliation unPaymentReconciliation =
|
||||
normalUnCharge(paymentReconciliation, paymentRecDetails, cancelPaymentDto.getSetlId());
|
||||
normalUnCharge(paymentReconciliation, paymentRecDetails, cancelPaymentDto.getSetlId(), cancelPaymentDto.getReason());
|
||||
|
||||
return R.ok(unPaymentReconciliation);
|
||||
}
|
||||
@@ -792,10 +792,12 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
*
|
||||
* @param paymentReconciliation 付款实体
|
||||
* @param paymentRecDetails 付款详情
|
||||
* @param setlIds 医保结算ID
|
||||
* @param reason 退号/退费原因
|
||||
* @return 结果
|
||||
*/
|
||||
private PaymentReconciliation normalUnCharge(PaymentReconciliation paymentReconciliation,
|
||||
List<PaymentRecDetail> paymentRecDetails, String setlIds) {
|
||||
List<PaymentRecDetail> paymentRecDetails, String setlIds, String reason) {
|
||||
|
||||
// 获取原ID
|
||||
Long id = paymentReconciliation.getId();
|
||||
@@ -805,7 +807,8 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
.setEntererId(SecurityUtils.getLoginUser().getPractitionerId()).setBillDate(new Date())
|
||||
.setTenderedAmount(paymentReconciliation.getTenderedAmount().negate())
|
||||
.setReturnedAmount(paymentReconciliation.getReturnedAmount().negate())
|
||||
.setDisplayAmount(paymentReconciliation.getDisplayAmount().negate());
|
||||
.setDisplayAmount(paymentReconciliation.getDisplayAmount().negate())
|
||||
.setRefundReason(reason); // 保存退号/退费原因
|
||||
if (setlIds != null) {
|
||||
paymentReconciliation.setYbSettleIds(setlIds);
|
||||
}
|
||||
@@ -2232,7 +2235,7 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
}
|
||||
|
||||
// 全退
|
||||
PaymentReconciliation unPaymentReconciliation = normalUnCharge(paymentReconciliation, paymentRecDetails, null);
|
||||
PaymentReconciliation unPaymentReconciliation = normalUnCharge(paymentReconciliation, paymentRecDetails, null, null);
|
||||
|
||||
// 取医保结算数据
|
||||
String ybSettleIds = paymentReconciliation.getYbSettleIds();
|
||||
|
||||
@@ -172,13 +172,13 @@ public class PaymentReconciliationController {
|
||||
/**
|
||||
* 挂号收费(挂号收费先医保挂号,收费成功后再本系统挂号)
|
||||
*
|
||||
* @param outpatientRegistrationAddParam 挂号信息
|
||||
* @param outpatientRegistrationSettleParam 挂号信息
|
||||
* @return 操做结果
|
||||
*/
|
||||
@PostMapping("/reg-pay")
|
||||
public R<?> regPay(@Valid @RequestBody OutpatientRegistrationSettleParam outpatientRegistrationAddParam) {
|
||||
R<?> result = paymentReconciliationService.regPay(outpatientRegistrationAddParam,
|
||||
outpatientRegistrationAddParam.getChrgBchno(), outpatientRegistrationAddParam.getPaymentDetails());
|
||||
public R<?> regPay(@Valid @RequestBody OutpatientRegistrationSettleParam outpatientRegistrationSettleParam) {
|
||||
R<?> result = paymentReconciliationService.regPay(outpatientRegistrationSettleParam,
|
||||
outpatientRegistrationSettleParam.getChrgBchno(), outpatientRegistrationSettleParam.getPaymentDetails());
|
||||
// 付款成功后,开具发票
|
||||
if (result.getCode() == 200) {
|
||||
PaymentReconciliation paymentRecon = null;
|
||||
|
||||
@@ -68,6 +68,11 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
||||
public R<?> getPage(InventoryProductReportSearchParam inventoryProductReportSearchParam, Integer pageNo,
|
||||
Integer pageSize, String searchKey, HttpServletRequest request) {
|
||||
|
||||
// 数据初始化,不使用eq条件拼接
|
||||
// 库存范围
|
||||
Integer inventoryScope = inventoryProductReportSearchParam.getInventoryScope();
|
||||
inventoryProductReportSearchParam.setInventoryScope(null);
|
||||
|
||||
// 设置模糊查询的字段名
|
||||
HashSet<String> searchFields = new HashSet<>();
|
||||
searchFields.add(CommonConstants.FieldName.BusNo);
|
||||
@@ -78,7 +83,8 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
||||
|
||||
// 查询库存商品明细分页列表
|
||||
Page<InventoryProductReportPageDto> productReportPage = inventoryProductReportMapper.selectProductReportPage(
|
||||
new Page<>(pageNo, pageSize), queryWrapper, ConditionCode.LOT_NUMBER_COST.getValue().toString());
|
||||
new Page<>(pageNo, pageSize), queryWrapper, ConditionCode.LOT_NUMBER_COST.getValue().toString(),
|
||||
inventoryScope);
|
||||
|
||||
productReportPage.getRecords().forEach(e -> {
|
||||
// 药品类型
|
||||
@@ -104,6 +110,11 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
||||
Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response) {
|
||||
pageNo = 1;
|
||||
pageSize = 10000;
|
||||
// 数据初始化,不使用eq条件拼接
|
||||
// 库存范围
|
||||
Integer inventoryScope = inventoryProductReportSearchParam.getInventoryScope();
|
||||
inventoryProductReportSearchParam.setInventoryScope(null);
|
||||
|
||||
// 设置模糊查询的字段名
|
||||
HashSet<String> searchFields = new HashSet<>();
|
||||
searchFields.add(CommonConstants.FieldName.BusNo);
|
||||
@@ -114,7 +125,8 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
||||
|
||||
// 查询库存商品明细分页列表
|
||||
Page<InventoryProductReportPageDto> productReportPage = inventoryProductReportMapper.selectProductReportPage(
|
||||
new Page<>(pageNo, pageSize), queryWrapper, ConditionCode.LOT_NUMBER_COST.getValue().toString());
|
||||
new Page<>(pageNo, pageSize), queryWrapper, ConditionCode.LOT_NUMBER_COST.getValue().toString(),
|
||||
inventoryScope);
|
||||
|
||||
productReportPage.getRecords().forEach(e -> {
|
||||
// 药品类型
|
||||
|
||||
@@ -38,4 +38,10 @@ public class InventoryProductReportSearchParam {
|
||||
|
||||
/** 供应商 */
|
||||
private Long supplierId;
|
||||
|
||||
/** 厂家/产地(供应商名称) */
|
||||
private String manufacturerText;
|
||||
|
||||
/** 仓库ID(药房ID) */
|
||||
private Long purposeLocationId;
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@ public interface InventoryProductReportMapper {
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param lotNumber 命中条件枚举类型:产品批号
|
||||
* @param inventoryScope 库存范围:无限制(1)、数量等于0(2)、数量大于0(3)、数量小于等于20(4)、数量小于等于50(5)
|
||||
* @return 库存商品明细
|
||||
*/
|
||||
Page<InventoryProductReportPageDto> selectProductReportPage(@Param("page") Page<InventoryProductReportPageDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<InventoryProductReportSearchParam> queryWrapper,
|
||||
@Param("lotNumber") String lotNumber);
|
||||
@Param("lotNumber") String lotNumber,
|
||||
@Param("inventoryScope") Integer inventoryScope);
|
||||
}
|
||||
|
||||
@@ -5,43 +5,32 @@ package com.openhis.web.ybmanage.vo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 【3201】后台计算结果 DB映射实体
|
||||
* Settlement3202 Result DB mapping entity
|
||||
*
|
||||
* @author SunJQ
|
||||
* @date 2025-04-15
|
||||
*/
|
||||
@Data
|
||||
public class Settlement3202VO {
|
||||
/** 医疗费用总额 */
|
||||
|
||||
/** Medical Fee Sum */
|
||||
private BigDecimal medFeeSumAmt;
|
||||
/** 基金支付总额 */
|
||||
|
||||
/** Fund Pay Sum */
|
||||
private BigDecimal fundPaySumAmt;
|
||||
/** 个人账户支付总额 */
|
||||
|
||||
/** Account Pay */
|
||||
private BigDecimal acctPay;
|
||||
/** 个人账户支付总额 */
|
||||
|
||||
/** Account Gj Pay */
|
||||
private BigDecimal acctGjPay;
|
||||
/** 现金支付总额 */
|
||||
|
||||
/** Self Pay Cash */
|
||||
private BigDecimal selfPayCash;
|
||||
/** 微信支付总额 */
|
||||
|
||||
/** Self Pay WeChat */
|
||||
private BigDecimal selfPayVx;
|
||||
/** 阿里支付总额 */
|
||||
|
||||
/** Self Pay Alipay */
|
||||
private BigDecimal selfPayAli;
|
||||
/** 银行卡支付总额 */
|
||||
|
||||
/** Self Pay Bank Card */
|
||||
private BigDecimal selfPayUnion;
|
||||
/** 定点医药机构结算笔数 */
|
||||
|
||||
/** Settlement Count */
|
||||
private Integer fixMedInsSetlCnt;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ spring:
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
enabled:
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
|
||||
@@ -6,9 +6,9 @@ spring:
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:postgresql://localhost:5432/openhis?currentSchema=public&characterEncoding=UTF-8&client_encoding=UTF-8
|
||||
username: postgres
|
||||
password: root
|
||||
url: jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=public&characterEncoding=UTF-8&client_encoding=UTF-8
|
||||
username: postgresql
|
||||
password: Jchl1528
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
@@ -62,13 +62,13 @@ spring:
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: 127.0.0.1
|
||||
host: 192.168.110.252
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
database: 1
|
||||
# 密码
|
||||
password: redis
|
||||
password: Jchl1528
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
|
||||
@@ -74,12 +74,14 @@
|
||||
T2."name" AS item_name,
|
||||
T2.id AS item_id,
|
||||
T2.part_percent,
|
||||
T2.manufacturer_text AS supplier_name,
|
||||
T2.manufacturer_text AS manufacturer_text,
|
||||
T3.total_volume,
|
||||
T5."name" AS practitioner_name,
|
||||
T6."name" AS purpose_location_name,
|
||||
T6."id" AS purpose_location_id,
|
||||
T7."name" AS purpose_location_store_name,
|
||||
T1.supplier_id AS supplierId,
|
||||
T10."name" AS supplier_name,
|
||||
T1.occurrence_time,
|
||||
(SELECT SUM(T9.quantity)
|
||||
FROM wor_inventory_item T9
|
||||
@@ -100,6 +102,8 @@
|
||||
LEFT JOIN wor_inventory_item T9
|
||||
ON T1.item_id = T9.item_id
|
||||
AND T1.purpose_location_id = T9.location_id
|
||||
LEFT JOIN adm_supplier T10
|
||||
ON T1.supplier_id = T10.id
|
||||
WHERE T1.bus_no = #{busNo}
|
||||
AND T1.delete_flag = '0'
|
||||
UNION
|
||||
@@ -121,12 +125,14 @@
|
||||
T8."name" AS item_name,
|
||||
T8.id AS item_id,
|
||||
T8.part_percent,
|
||||
T8.manufacturer_text AS supplier_name,
|
||||
T8.manufacturer_text AS manufacturer_text,
|
||||
T8."size" AS total_volume,
|
||||
T5."name" AS practitioner_name,
|
||||
T6."name" AS purpose_location_name,
|
||||
T6."id" AS purpose_location_id,
|
||||
T7."name" AS purpose_location_store_name,
|
||||
T1.supplier_id AS supplierId,
|
||||
T10."name" AS supplier_name,
|
||||
T1.occurrence_time,
|
||||
(SELECT SUM(T9.quantity)
|
||||
FROM wor_inventory_item T9
|
||||
@@ -145,6 +151,8 @@
|
||||
LEFT JOIN wor_inventory_item T9
|
||||
ON T1.item_id = T9.item_id
|
||||
AND T1.purpose_location_id = T9.location_id
|
||||
LEFT JOIN adm_supplier T10
|
||||
ON T1.supplier_id = T10.id
|
||||
WHERE T1.bus_no = #{busNo}
|
||||
AND T1.delete_flag = '0'
|
||||
</select>
|
||||
@@ -167,12 +175,14 @@
|
||||
T2."name" AS item_name,
|
||||
T2.id AS item_id,
|
||||
T2.part_percent,
|
||||
T2.manufacturer_text AS supplier_name,
|
||||
T2.manufacturer_text AS manufacturer_text,
|
||||
T3.total_volume,
|
||||
T5."name" AS practitioner_name,
|
||||
T6."name" AS purpose_location_name,
|
||||
T6."id" AS purpose_location_id,
|
||||
T7."name" AS purpose_location_store_name,
|
||||
T1.supplier_id AS supplierId,
|
||||
T10."name" AS supplier_name,
|
||||
(SELECT SUM(T9.quantity)
|
||||
FROM wor_inventory_item T9
|
||||
WHERE T9.item_id = T1.item_id
|
||||
@@ -192,6 +202,8 @@
|
||||
LEFT JOIN wor_inventory_item T9
|
||||
ON T1.item_id = T9.item_id
|
||||
AND T1.purpose_location_id = T9.location_id
|
||||
LEFT JOIN adm_supplier T10
|
||||
ON T1.supplier_id = T10.id
|
||||
WHERE T1.purpose_location_id = #{locationId}
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
AND T1.type_enum IN
|
||||
@@ -220,12 +232,14 @@
|
||||
T8."name" AS item_name,
|
||||
T8.id AS item_id,
|
||||
T8.part_percent,
|
||||
T8.manufacturer_text AS supplier_name,
|
||||
T8.manufacturer_text AS manufacturer_text,
|
||||
T8."size" AS total_volume,
|
||||
T5."name" AS practitioner_name,
|
||||
T6."name" AS purpose_location_name,
|
||||
T6."id" AS purpose_location_id,
|
||||
T7."name" AS purpose_location_store_name,
|
||||
T1.supplier_id AS supplierId,
|
||||
T10."name" AS supplier_name,
|
||||
(SELECT SUM(T9.quantity)
|
||||
FROM wor_inventory_item T9
|
||||
WHERE T9.item_id = T1.item_id
|
||||
@@ -243,6 +257,8 @@
|
||||
LEFT JOIN wor_inventory_item T9
|
||||
ON T1.item_id = T9.item_id
|
||||
AND T1.purpose_location_id = T9.location_id
|
||||
LEFT JOIN adm_supplier T10
|
||||
ON T1.supplier_id = T10.id
|
||||
WHERE T1.purpose_location_id = #{locationId}
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
AND T1.type_enum IN
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
T3.extra_details,
|
||||
T3.contact,
|
||||
T3.appointment_required_flag,
|
||||
T3.practitioner_id,
|
||||
T3.definition_id,
|
||||
T3.charge_name,
|
||||
T3.price,
|
||||
@@ -36,6 +37,7 @@
|
||||
T1.extra_details,
|
||||
T1.contact,
|
||||
T1.appointment_required_flag,
|
||||
T1.practitioner_id,
|
||||
T2.ID AS definition_id,
|
||||
T2.charge_name,
|
||||
T2.price,
|
||||
|
||||
@@ -62,7 +62,14 @@
|
||||
T9.charge_item_ids,
|
||||
T9.payment_id,
|
||||
T9.picture_url,
|
||||
T9.birth_date
|
||||
T9.birth_date,
|
||||
T9.return_date,
|
||||
T9.return_reason,
|
||||
T9.operator_name,
|
||||
T9.operator_id,
|
||||
T9.refund_amount,
|
||||
T9.contract_no,
|
||||
T9.refund_method
|
||||
from (
|
||||
SELECT T1.tenant_id AS tenant_id,
|
||||
T1.id AS encounter_id,
|
||||
@@ -84,7 +91,15 @@
|
||||
T13.charge_item_ids,
|
||||
T13.id AS payment_id,
|
||||
ai.picture_url AS picture_url,
|
||||
T8.birth_date AS birth_date
|
||||
T8.birth_date AS birth_date,
|
||||
-- 退号相关信息
|
||||
T14.bill_date AS return_date,
|
||||
T14.refund_reason AS return_reason,
|
||||
T15."name" AS operator_name,
|
||||
T17.user_name AS operator_id,
|
||||
ABS(T14.display_amount) AS refund_amount,
|
||||
T6.contract_no AS contract_no,
|
||||
T16.refund_method AS refund_method
|
||||
FROM adm_encounter AS T1
|
||||
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
||||
@@ -111,9 +126,36 @@
|
||||
LEFT JOIN fin_payment_reconciliation T13
|
||||
ON T10.id::TEXT = ANY(string_to_array(T13.charge_item_ids,','))
|
||||
AND T13.delete_flag = '0'
|
||||
AND T13.status_enum = ${paymentStatus}
|
||||
LEFT JOIN adm_invoice AS ai
|
||||
ON ai.reconciliation_id = T13.id AND ai.delete_flag = '0'
|
||||
AND T13.status_enum = ${paymentStatus}
|
||||
-- 关联退号记录(当状态为退号时,通过relation_id关联原支付记录)
|
||||
LEFT JOIN fin_payment_reconciliation T14
|
||||
ON T13.id = T14.relation_id
|
||||
AND T14.delete_flag = '0'
|
||||
AND T14.status_enum = 3
|
||||
AND T14.payment_enum = 1
|
||||
LEFT JOIN adm_practitioner AS T15 ON T15.ID = T14.enterer_id AND T15.delete_flag = '0'
|
||||
LEFT JOIN sys_user AS T17 ON T17.user_id = T15.user_id AND T17.delete_flag = '0'
|
||||
-- 关联退号支付详情,获取退款方式(聚合多个支付方式)
|
||||
LEFT JOIN (
|
||||
SELECT reconciliation_id,
|
||||
STRING_AGG(
|
||||
CASE pay_enum
|
||||
WHEN 220400 THEN '现金'
|
||||
WHEN 220100 THEN '微信'
|
||||
WHEN 220200 THEN '支付宝'
|
||||
WHEN 220300 THEN '银联'
|
||||
END,
|
||||
','
|
||||
ORDER BY pay_enum
|
||||
) AS refund_method
|
||||
FROM fin_payment_rec_detail
|
||||
WHERE delete_flag = '0'
|
||||
AND amount < 0
|
||||
AND pay_enum IN (220400, 220100, 220200, 220300)
|
||||
GROUP BY reconciliation_id
|
||||
) AS T16 ON T14.id = T16.reconciliation_id
|
||||
LEFT JOIN adm_invoice AS ai
|
||||
ON ai.reconciliation_id = T13.id AND ai.delete_flag = '0'
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T1.class_enum = #{classEnum}
|
||||
-- AND T1.create_time
|
||||
|
||||
@@ -41,188 +41,366 @@
|
||||
abi.restricted_flag,
|
||||
abi.restricted_scope
|
||||
from (
|
||||
<if test="adviceTypes == null or adviceTypes.contains(1)">
|
||||
SELECT T1.tenant_id,
|
||||
1 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
T1.pharmacology_category_code AS pharmacology_category_code,
|
||||
T1.part_percent AS part_percent,
|
||||
T1.unit_conversion_ratio AS unit_conversion_ratio,
|
||||
T1.part_attribute_enum AS part_attribute_enum,
|
||||
T1.tho_part_attribute_enum AS tho_part_attribute_enum,
|
||||
T1.skin_test_flag AS skin_test_flag,
|
||||
T1.inject_flag AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
T1.merchandise_name AS product_name,
|
||||
0 AS activity_type,
|
||||
T1.unit_code AS unit_code,
|
||||
T1.min_unit_code AS min_unit_code,
|
||||
T2.total_volume AS volume,
|
||||
T2.method_code AS method_code,
|
||||
T2.rate_code AS rate_code,
|
||||
T2.org_id AS org_id,
|
||||
T2.location_id AS location_id,
|
||||
CAST(T2.dose AS TEXT) AS dose,
|
||||
T2.dose_unit_code AS dose_unit_code,
|
||||
T3.NAME AS supplier,
|
||||
T3.id AS supplier_id,
|
||||
T1.manufacturer_text AS manufacturer,
|
||||
T5.id AS charge_item_definition_id,
|
||||
T5.instance_table AS advice_table_name,
|
||||
T6.def_location_id AS position_id,
|
||||
t1.restricted_flag AS restricted_flag,
|
||||
t1.restricted_scope AS restricted_scope
|
||||
FROM med_medication_definition AS t1
|
||||
INNER JOIN med_medication AS T2 ON T2.medication_def_id = T1.ID
|
||||
AND T2.delete_flag = '0' AND T2.status_enum = #{statusEnum}
|
||||
LEFT JOIN adm_supplier AS T3
|
||||
ON T3.ID = T1.supply_id
|
||||
AND T3.delete_flag = '0'
|
||||
LEFT JOIN adm_charge_item_definition AS T5 ON T5.instance_id = T1.ID
|
||||
AND T5.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T6
|
||||
ON T6.distribution_category_code = T1.category_code
|
||||
AND T6.delete_flag = '0' AND T6.organization_id = #{organizationId} AND
|
||||
(CURRENT_TIME :: time (6) BETWEEN T6.start_time AND T6.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T2.status_enum = #{statusEnum}
|
||||
<if test="pricingFlag ==1">
|
||||
AND 1 = 2
|
||||
</if>
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T5.instance_table = #{medicationTableName}
|
||||
</if>
|
||||
<!-- 改进SQL逻辑,确保所有情况都能正确处理,避免空的FROM子查询 -->
|
||||
<!-- 当adviceTypes包含4或不在1-3范围内时,或者adviceTypes为空/null时,查询所有类型 -->
|
||||
<choose>
|
||||
<!-- 检查adviceTypes是否为null、空列表,或者包含4、5或其他不在1-3范围内的值 -->
|
||||
<when test="adviceTypes == null or adviceTypes.isEmpty() or adviceTypes.contains(4) or adviceTypes.contains(5)">
|
||||
<!-- 查询所有类型 -->
|
||||
SELECT T1.tenant_id,
|
||||
1 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
T1.pharmacology_category_code AS pharmacology_category_code,
|
||||
T1.part_percent AS part_percent,
|
||||
T1.unit_conversion_ratio AS unit_conversion_ratio,
|
||||
T1.part_attribute_enum AS part_attribute_enum,
|
||||
T1.tho_part_attribute_enum AS tho_part_attribute_enum,
|
||||
T1.skin_test_flag AS skin_test_flag,
|
||||
T1.inject_flag AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
T1.merchandise_name AS product_name,
|
||||
0 AS activity_type,
|
||||
T1.unit_code AS unit_code,
|
||||
T1.min_unit_code AS min_unit_code,
|
||||
T2.total_volume AS volume,
|
||||
T2.method_code AS method_code,
|
||||
T2.rate_code AS rate_code,
|
||||
T2.org_id AS org_id,
|
||||
T2.location_id AS location_id,
|
||||
CAST(T2.dose AS TEXT) AS dose,
|
||||
T2.dose_unit_code AS dose_unit_code,
|
||||
T3.NAME AS supplier,
|
||||
T3.id AS supplier_id,
|
||||
T1.manufacturer_text AS manufacturer,
|
||||
T5.id AS charge_item_definition_id,
|
||||
T5.instance_table AS advice_table_name,
|
||||
T6.def_location_id AS position_id,
|
||||
t1.restricted_flag AS restricted_flag,
|
||||
t1.restricted_scope AS restricted_scope
|
||||
FROM med_medication_definition AS t1
|
||||
INNER JOIN med_medication AS T2 ON T2.medication_def_id = T1.ID
|
||||
AND T2.delete_flag = '0' AND T2.status_enum = #{statusEnum}
|
||||
LEFT JOIN adm_supplier AS T3
|
||||
ON T3.ID = T1.supply_id
|
||||
AND T3.delete_flag = '0'
|
||||
LEFT JOIN adm_charge_item_definition AS T5 ON T5.instance_id = T1.ID
|
||||
AND T5.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T6
|
||||
ON T6.distribution_category_code = T1.category_code
|
||||
AND T6.delete_flag = '0' AND T6.organization_id = #{organizationId} AND
|
||||
(CURRENT_TIME :: time (6) BETWEEN T6.start_time AND T6.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T2.status_enum = #{statusEnum}
|
||||
<if test="pricingFlag ==1">
|
||||
AND 1 = 2
|
||||
</if>
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T5.instance_table = #{medicationTableName}
|
||||
UNION ALL
|
||||
SELECT T1.tenant_id,
|
||||
2 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
'' AS pharmacology_category_code,
|
||||
T1.part_percent AS part_percent,
|
||||
0 AS unit_conversion_ratio,
|
||||
null AS part_attribute_enum,
|
||||
null AS tho_part_attribute_enum,
|
||||
null AS skin_test_flag,
|
||||
null AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
'' AS product_name,
|
||||
0 AS activity_type,
|
||||
T1.unit_code AS unit_code,
|
||||
T1.min_unit_code AS min_unit_code,
|
||||
T1.SIZE AS volume,
|
||||
'' AS method_code,
|
||||
'' AS rate_code,
|
||||
T1.org_id AS org_id,
|
||||
T1.location_id AS location_id,
|
||||
'' AS dose,
|
||||
'' AS dose_unit_code,
|
||||
T2.NAME AS supplier,
|
||||
T2.id AS supplier_id,
|
||||
T1.manufacturer_text AS manufacturer,
|
||||
T4.id AS charge_item_definition_id,
|
||||
T4.instance_table AS advice_table_name,
|
||||
T5.def_location_id AS position_id,
|
||||
0 AS restricted_flag,
|
||||
'' AS restricted_scope
|
||||
FROM adm_device_definition AS T1
|
||||
LEFT JOIN adm_supplier AS T2
|
||||
ON T2.ID = T1.supply_id
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_charge_item_definition AS T4 ON T4.instance_id = T1.ID
|
||||
AND T4.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T5 ON T5.distribution_category_code = T1.category_code
|
||||
AND T5.delete_flag = '0' AND T5.organization_id = #{organizationId} AND
|
||||
(CURRENT_TIME :: time (6) BETWEEN T5.start_time AND T5.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T4.instance_table = #{deviceTableName}
|
||||
AND T1.category_code = #{singleUse}
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
UNION ALL
|
||||
SELECT T1.tenant_id,
|
||||
3 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
'' AS pharmacology_category_code,
|
||||
1 AS part_percent,
|
||||
0 AS unit_conversion_ratio,
|
||||
null AS part_attribute_enum,
|
||||
null AS tho_part_attribute_enum,
|
||||
null AS skin_test_flag,
|
||||
null AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
'' AS product_name,
|
||||
T1.type_enum AS activity_type,
|
||||
'' AS unit_code,
|
||||
'' AS min_unit_code,
|
||||
'' AS volume,
|
||||
'' AS method_code,
|
||||
'' AS rate_code,
|
||||
T1.org_id AS org_id,
|
||||
T1.location_id AS location_id,
|
||||
'' AS dose,
|
||||
'' AS dose_unit_code,
|
||||
'' AS supplier,
|
||||
null AS supplier_id,
|
||||
'' AS manufacturer,
|
||||
T2.ID AS charge_item_definition_id,
|
||||
T2.instance_table AS advice_table_name,
|
||||
COALESCE(T3.organization_id, T1.org_id) AS position_id,
|
||||
0 AS restricted_flag,
|
||||
'' AS restricted_scope
|
||||
FROM wor_activity_definition AS T1
|
||||
LEFT JOIN adm_charge_item_definition AS T2
|
||||
ON T2.instance_id = T1.ID
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T3 ON T3.activity_definition_id = T1.ID
|
||||
AND T3.delete_flag = '0' AND (CURRENT_TIME :: time (6) BETWEEN T3.start_time AND T3.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
<if test="pricingFlag ==1">
|
||||
AND T1.pricing_flag = #{pricingFlag}
|
||||
</if>
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
AND T2.instance_table = #{activityTableName}
|
||||
</when>
|
||||
<otherwise>
|
||||
<!-- 当adviceTypes不为null且不为空,且只包含1、2、3时,根据选中的类型查询 -->
|
||||
<!-- 确保至少有一个类型被选中,避免空查询 -->
|
||||
<if test="adviceTypes.contains(1) or adviceTypes.contains(2) or adviceTypes.contains(3)">
|
||||
<if test="adviceTypes.contains(1)">
|
||||
SELECT T1.tenant_id,
|
||||
1 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
T1.pharmacology_category_code AS pharmacology_category_code,
|
||||
T1.part_percent AS part_percent,
|
||||
T1.unit_conversion_ratio AS unit_conversion_ratio,
|
||||
T1.part_attribute_enum AS part_attribute_enum,
|
||||
T1.tho_part_attribute_enum AS tho_part_attribute_enum,
|
||||
T1.skin_test_flag AS skin_test_flag,
|
||||
T1.inject_flag AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
T1.merchandise_name AS product_name,
|
||||
0 AS activity_type,
|
||||
T1.unit_code AS unit_code,
|
||||
T1.min_unit_code AS min_unit_code,
|
||||
T2.total_volume AS volume,
|
||||
T2.method_code AS method_code,
|
||||
T2.rate_code AS rate_code,
|
||||
T2.org_id AS org_id,
|
||||
T2.location_id AS location_id,
|
||||
CAST(T2.dose AS TEXT) AS dose,
|
||||
T2.dose_unit_code AS dose_unit_code,
|
||||
T3.NAME AS supplier,
|
||||
T3.id AS supplier_id,
|
||||
T1.manufacturer_text AS manufacturer,
|
||||
T5.id AS charge_item_definition_id,
|
||||
T5.instance_table AS advice_table_name,
|
||||
T6.def_location_id AS position_id,
|
||||
t1.restricted_flag AS restricted_flag,
|
||||
t1.restricted_scope AS restricted_scope
|
||||
FROM med_medication_definition AS t1
|
||||
INNER JOIN med_medication AS T2 ON T2.medication_def_id = T1.ID
|
||||
AND T2.delete_flag = '0' AND T2.status_enum = #{statusEnum}
|
||||
LEFT JOIN adm_supplier AS T3
|
||||
ON T3.ID = T1.supply_id
|
||||
AND T3.delete_flag = '0'
|
||||
LEFT JOIN adm_charge_item_definition AS T5 ON T5.instance_id = T1.ID
|
||||
AND T5.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T6
|
||||
ON T6.distribution_category_code = T1.category_code
|
||||
AND T6.delete_flag = '0' AND T6.organization_id = #{organizationId} AND
|
||||
(CURRENT_TIME :: time (6) BETWEEN T6.start_time AND T6.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T2.status_enum = #{statusEnum}
|
||||
<if test="pricingFlag ==1">
|
||||
AND 1 = 2
|
||||
</if>
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T5.instance_table = #{medicationTableName}
|
||||
</if>
|
||||
|
||||
<if test="adviceTypes == null or adviceTypes.contains(1)">
|
||||
<if test="adviceTypes == null or adviceTypes.contains(2) or adviceTypes.contains(3)">UNION ALL</if>
|
||||
</if>
|
||||
<if test="adviceTypes.contains(1) and (adviceTypes.contains(2) or adviceTypes.contains(3))">UNION ALL</if>
|
||||
|
||||
<if test="adviceTypes == null or adviceTypes.contains(2)">
|
||||
SELECT T1.tenant_id,
|
||||
2 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
'' AS pharmacology_category_code,
|
||||
T1.part_percent AS part_percent,
|
||||
0 AS unit_conversion_ratio,
|
||||
null AS part_attribute_enum,
|
||||
null AS tho_part_attribute_enum,
|
||||
null AS skin_test_flag,
|
||||
null AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
'' AS product_name,
|
||||
0 AS activity_type,
|
||||
T1.unit_code AS unit_code,
|
||||
T1.min_unit_code AS min_unit_code,
|
||||
T1.SIZE AS volume,
|
||||
'' AS method_code,
|
||||
'' AS rate_code,
|
||||
T1.org_id AS org_id,
|
||||
T1.location_id AS location_id,
|
||||
'' AS dose,
|
||||
'' AS dose_unit_code,
|
||||
T2.NAME AS supplier,
|
||||
T2.id AS supplier_id,
|
||||
T1.manufacturer_text AS manufacturer,
|
||||
T4.id AS charge_item_definition_id,
|
||||
T4.instance_table AS advice_table_name,
|
||||
T5.def_location_id AS position_id,
|
||||
0 AS restricted_flag,
|
||||
'' AS restricted_scope
|
||||
FROM adm_device_definition AS T1
|
||||
LEFT JOIN adm_supplier AS T2
|
||||
ON T2.ID = T1.supply_id
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_charge_item_definition AS T4 ON T4.instance_id = T1.ID
|
||||
AND T4.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T5 ON T5.distribution_category_code = T1.category_code
|
||||
AND T5.delete_flag = '0' AND T5.organization_id = #{organizationId} AND
|
||||
(CURRENT_TIME :: time (6) BETWEEN T5.start_time AND T5.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T4.instance_table = #{deviceTableName}
|
||||
AND T1.category_code = #{singleUse}
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
</if>
|
||||
<if test="adviceTypes.contains(2)">
|
||||
SELECT T1.tenant_id,
|
||||
2 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
'' AS pharmacology_category_code,
|
||||
T1.part_percent AS part_percent,
|
||||
0 AS unit_conversion_ratio,
|
||||
null AS part_attribute_enum,
|
||||
null AS tho_part_attribute_enum,
|
||||
null AS skin_test_flag,
|
||||
null AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
'' AS product_name,
|
||||
0 AS activity_type,
|
||||
T1.unit_code AS unit_code,
|
||||
T1.min_unit_code AS min_unit_code,
|
||||
T1.SIZE AS volume,
|
||||
'' AS method_code,
|
||||
'' AS rate_code,
|
||||
T1.org_id AS org_id,
|
||||
T1.location_id AS location_id,
|
||||
'' AS dose,
|
||||
'' AS dose_unit_code,
|
||||
T2.NAME AS supplier,
|
||||
T2.id AS supplier_id,
|
||||
T1.manufacturer_text AS manufacturer,
|
||||
T4.id AS charge_item_definition_id,
|
||||
T4.instance_table AS advice_table_name,
|
||||
T5.def_location_id AS position_id,
|
||||
0 AS restricted_flag,
|
||||
'' AS restricted_scope
|
||||
FROM adm_device_definition AS T1
|
||||
LEFT JOIN adm_supplier AS T2
|
||||
ON T2.ID = T1.supply_id
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_charge_item_definition AS T4 ON T4.instance_id = T1.ID
|
||||
AND T4.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T5 ON T5.distribution_category_code = T1.category_code
|
||||
AND T5.delete_flag = '0' AND T5.organization_id = #{organizationId} AND
|
||||
(CURRENT_TIME :: time (6) BETWEEN T5.start_time AND T5.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T4.instance_table = #{deviceTableName}
|
||||
AND T1.category_code = #{singleUse}
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
</if>
|
||||
|
||||
<if test="adviceTypes == null or adviceTypes.contains(2)">
|
||||
<if test="adviceTypes == null or adviceTypes.contains(3)">UNION ALL</if>
|
||||
</if>
|
||||
<if test="adviceTypes.contains(2) and adviceTypes.contains(3)">UNION ALL</if>
|
||||
|
||||
<if test="adviceTypes == null or adviceTypes.contains(3)">
|
||||
SELECT T1.tenant_id,
|
||||
3 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
'' AS pharmacology_category_code,
|
||||
1 AS part_percent,
|
||||
0 AS unit_conversion_ratio,
|
||||
null AS part_attribute_enum,
|
||||
null AS tho_part_attribute_enum,
|
||||
null AS skin_test_flag,
|
||||
null AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
'' AS product_name,
|
||||
T1.type_enum AS activity_type,
|
||||
'' AS unit_code,
|
||||
'' AS min_unit_code,
|
||||
'' AS volume,
|
||||
'' AS method_code,
|
||||
'' AS rate_code,
|
||||
T1.org_id AS org_id,
|
||||
T1.location_id AS location_id,
|
||||
'' AS dose,
|
||||
'' AS dose_unit_code,
|
||||
'' AS supplier,
|
||||
null AS supplier_id,
|
||||
'' AS manufacturer,
|
||||
T2.ID AS charge_item_definition_id,
|
||||
T2.instance_table AS advice_table_name,
|
||||
T3.organization_id AS position_id,
|
||||
0 AS restricted_flag,
|
||||
'' AS restricted_scope
|
||||
FROM wor_activity_definition AS T1
|
||||
LEFT JOIN adm_charge_item_definition AS T2
|
||||
ON T2.instance_id = T1.ID
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T3 ON T3.activity_definition_id = T1.ID
|
||||
AND T3.delete_flag = '0' AND (CURRENT_TIME :: time (6) BETWEEN T3.start_time AND T3.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
<if test="pricingFlag ==1">
|
||||
AND T1.pricing_flag = #{pricingFlag}
|
||||
</if>
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
AND T2.instance_table = #{activityTableName}
|
||||
</if>
|
||||
<if test="adviceTypes.contains(3)">
|
||||
SELECT T1.tenant_id,
|
||||
3 AS advice_type,
|
||||
T1.category_code AS category_code,
|
||||
'' AS pharmacology_category_code,
|
||||
1 AS part_percent,
|
||||
0 AS unit_conversion_ratio,
|
||||
null AS part_attribute_enum,
|
||||
null AS tho_part_attribute_enum,
|
||||
null AS skin_test_flag,
|
||||
null AS inject_flag,
|
||||
T1.ID AS advice_definition_id,
|
||||
T1.NAME AS advice_name,
|
||||
T1.bus_no AS advice_bus_no,
|
||||
T1.py_str AS py_str,
|
||||
T1.wb_str AS wb_str,
|
||||
T1.yb_no AS yb_no,
|
||||
'' AS product_name,
|
||||
T1.type_enum AS activity_type,
|
||||
'' AS unit_code,
|
||||
'' AS min_unit_code,
|
||||
'' AS volume,
|
||||
'' AS method_code,
|
||||
'' AS rate_code,
|
||||
T1.org_id AS org_id,
|
||||
T1.location_id AS location_id,
|
||||
'' AS dose,
|
||||
'' AS dose_unit_code,
|
||||
'' AS supplier,
|
||||
null AS supplier_id,
|
||||
'' AS manufacturer,
|
||||
T2.ID AS charge_item_definition_id,
|
||||
T2.instance_table AS advice_table_name,
|
||||
COALESCE(T3.organization_id, T1.org_id) AS position_id,
|
||||
0 AS restricted_flag,
|
||||
'' AS restricted_scope
|
||||
FROM wor_activity_definition AS T1
|
||||
LEFT JOIN adm_charge_item_definition AS T2
|
||||
ON T2.instance_id = T1.ID
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_organization_location AS T3 ON T3.activity_definition_id = T1.ID
|
||||
AND T3.delete_flag = '0' AND (CURRENT_TIME :: time (6) BETWEEN T3.start_time AND T3.end_time)
|
||||
WHERE T1.delete_flag = '0'
|
||||
<if test="pricingFlag ==1">
|
||||
AND T1.pricing_flag = #{pricingFlag}
|
||||
</if>
|
||||
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
|
||||
AND T1.id IN
|
||||
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
|
||||
#{itemId}
|
||||
</foreach>
|
||||
</if>
|
||||
AND T1.status_enum = #{statusEnum}
|
||||
AND T2.instance_table = #{activityTableName}
|
||||
</if>
|
||||
</if>
|
||||
</otherwise>
|
||||
</choose>
|
||||
) AS abi
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
<select id="selectProductReportPage"
|
||||
resultType="com.openhis.web.reportmanage.dto.InventoryProductReportPageDto">
|
||||
SELECT T8.id, --ID
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT T8.id, --ID
|
||||
T8.bus_no, --药品编码
|
||||
T8.name, --药品名称
|
||||
T8.lot_number, --批次号
|
||||
@@ -23,9 +25,11 @@
|
||||
T8.purpose_type_enum, --仓库类型
|
||||
T8.location_name, --仓库名称
|
||||
T8.location_store_name, --货位名称
|
||||
T8.purpose_location_id, --仓库ID
|
||||
T8.expiration_date, --有效期
|
||||
T8.yb_no, --医保编码
|
||||
T8.tenant_id -- 租户ID
|
||||
T8.tenant_id, -- 租户ID
|
||||
CAST(T8.item_table AS INTEGER) AS category_type -- 项目类型(按分类编码,整型)
|
||||
FROM (SELECT T1.id, --ID
|
||||
T2.bus_no, --药品编码
|
||||
T2.name, --药品名称
|
||||
@@ -46,6 +50,7 @@
|
||||
T6.form_enum AS purpose_type_enum, --仓库类型
|
||||
T6.name AS location_name, --仓库名称
|
||||
T7.name AS location_store_name, --货位名称
|
||||
T1.location_id AS purpose_location_id, --仓库ID
|
||||
T1.expiration_date, --有效期
|
||||
T2.yb_no, --医保编码
|
||||
T1.tenant_id -- 租户ID
|
||||
@@ -86,9 +91,11 @@
|
||||
T10.purpose_type_enum, --仓库类型
|
||||
T10.location_name, --仓库名称
|
||||
T10.location_store_name, --货位名称
|
||||
T10.purpose_location_id, --仓库ID
|
||||
T10.expiration_date, --有效期
|
||||
T10.yb_no, --医保编码
|
||||
T10.tenant_id -- 租户ID
|
||||
T10.tenant_id, -- 租户ID
|
||||
CAST(T10.item_table AS INTEGER) AS category_type -- 项目类型(按分类编码,整型)
|
||||
FROM (SELECT T1.id, --ID
|
||||
T9.bus_no, --药品编码
|
||||
T9.name, --药品名称
|
||||
@@ -109,6 +116,7 @@
|
||||
T6.form_enum AS purpose_type_enum, --仓库类型
|
||||
T6.name AS location_name, --仓库名称
|
||||
T7.name AS location_store_name, --货位名称
|
||||
T1.location_id AS purpose_location_id, --仓库ID
|
||||
T1.expiration_date, --有效期
|
||||
T9.yb_no, --医保编码
|
||||
T1.tenant_id -- 租户ID
|
||||
@@ -128,7 +136,24 @@
|
||||
LEFT JOIN adm_location T7
|
||||
ON T1.location_store_id = T7.id
|
||||
AND T7.delete_flag = '0'
|
||||
WHERE T1.delete_flag = '0') AS T10
|
||||
WHERE T1.delete_flag = '0') AS T10
|
||||
) AS T
|
||||
${ew.customSqlSegment}
|
||||
<if test="inventoryScope != null">
|
||||
<choose>
|
||||
<when test="inventoryScope == 2">
|
||||
AND item_quantity = 0
|
||||
</when>
|
||||
<when test="inventoryScope == 3">
|
||||
AND item_quantity > 0
|
||||
</when>
|
||||
<when test="inventoryScope == 4">
|
||||
AND item_quantity <![CDATA[ <= ]]> 20
|
||||
</when>
|
||||
<when test="inventoryScope == 5">
|
||||
AND item_quantity <![CDATA[ <= ]]> 50
|
||||
</when>
|
||||
</choose>
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -142,6 +142,11 @@ public class CommonConstants {
|
||||
*/
|
||||
public interface FieldName {
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
String Phone = "phone";
|
||||
|
||||
/**
|
||||
* 单据号
|
||||
*/
|
||||
|
||||
@@ -39,7 +39,7 @@ public enum LocationForm implements HisEnumInterface {
|
||||
|
||||
PHARMACY(16, "ph", "药房"),
|
||||
|
||||
WAREHOUSE (17, "wa", "仓库"),
|
||||
WAREHOUSE (17, "wa", "耗材库"),
|
||||
|
||||
DEPARTMENT (18, "de", "科室");
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
<groupId>com.openhis</groupId>
|
||||
<artifactId>openhis-common</artifactId>
|
||||
</dependency>
|
||||
<!-- 核心共通模块 -->
|
||||
<dependency>
|
||||
<groupId>com.core</groupId>
|
||||
<artifactId>core-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -60,6 +60,9 @@ public class HealthcareService extends HisBaseEntity {
|
||||
/** 预约要求 */
|
||||
private Integer appointmentRequiredFlag;
|
||||
|
||||
/** 出诊医生ID */
|
||||
private Long practitionerId;
|
||||
|
||||
/** 医保编码 */
|
||||
private String ybNo;
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.openhis.administration.domain;
|
||||
|
||||
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 lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 发票段管理Entity实体
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-11-18
|
||||
*/
|
||||
@Data
|
||||
@TableName("adm_invoice_segment")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class InvoiceSegment extends HisBaseEntity {
|
||||
|
||||
/** ID */
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/** 段ID */
|
||||
private Long segmentId;
|
||||
|
||||
/** 开始号码 */
|
||||
private String beginNumber;
|
||||
|
||||
/** 结束号码 */
|
||||
private String endNumber;
|
||||
|
||||
/** 员工ID */
|
||||
private Long employeeId;
|
||||
|
||||
/** 员工姓名 */
|
||||
private String employeeName;
|
||||
|
||||
/** 开票员ID */
|
||||
private Long invoicingStaffId;
|
||||
|
||||
/** 开票员姓名 */
|
||||
private String invoicingStaffName;
|
||||
|
||||
/** 创建日期 */
|
||||
private Date createDate;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.openhis.administration.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.administration.domain.InvoiceSegment;
|
||||
|
||||
/**
|
||||
* 发票段管理Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-11-18
|
||||
*/
|
||||
@Repository
|
||||
public interface InvoiceSegmentMapper extends BaseMapper<InvoiceSegment> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.openhis.administration.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.openhis.administration.domain.InvoiceSegment;
|
||||
|
||||
/**
|
||||
* 发票段管理Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-11-18
|
||||
*/
|
||||
public interface IInvoiceSegmentService {
|
||||
|
||||
/**
|
||||
* 分页查询发票段列表
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param isAdmin 是否管理员
|
||||
* @param userId 用户ID
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<InvoiceSegment> selectInvoiceSegmentPage(Page<InvoiceSegment> page, boolean isAdmin, Long userId);
|
||||
|
||||
/**
|
||||
* 新增发票段
|
||||
*
|
||||
* @param invoiceSegment 发票段信息
|
||||
* @return 结果
|
||||
*/
|
||||
int insertInvoiceSegment(InvoiceSegment invoiceSegment);
|
||||
|
||||
/**
|
||||
* 修改发票段
|
||||
*
|
||||
* @param invoiceSegment 发票段信息
|
||||
* @return 结果
|
||||
*/
|
||||
int updateInvoiceSegment(InvoiceSegment invoiceSegment);
|
||||
|
||||
/**
|
||||
* 删除发票段
|
||||
*
|
||||
* @param ids 发票段ID列表
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteInvoiceSegmentByIds(Long[] ids);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.openhis.administration.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.administration.domain.Invoice;
|
||||
import com.openhis.administration.domain.Supplier;
|
||||
@@ -18,4 +20,14 @@ public interface IInvoiceService extends IService<Invoice> {
|
||||
* @return
|
||||
*/
|
||||
Long addInvoice(Invoice invoice);
|
||||
|
||||
/**
|
||||
* 分页查询发票列表(带用户角色权限过滤)
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param isAdmin 是否管理员
|
||||
* @param userId 当前用户ID
|
||||
* @return 发票列表
|
||||
*/
|
||||
IPage<Invoice> selectInvoicePage(Page<Invoice> page, boolean isAdmin, Long userId);
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
package com.openhis.administration.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.openhis.administration.domain.InvoiceSegment;
|
||||
import com.openhis.administration.mapper.InvoiceSegmentMapper;
|
||||
import com.openhis.administration.service.IInvoiceSegmentService;
|
||||
|
||||
/**
|
||||
* 发票段管理Service实现
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-11-18
|
||||
*/
|
||||
@Service
|
||||
public class InvoiceSegmentServiceImpl implements IInvoiceSegmentService {
|
||||
|
||||
@Autowired
|
||||
private InvoiceSegmentMapper invoiceSegmentMapper;
|
||||
|
||||
/**
|
||||
* 分页查询发票段列表
|
||||
*/
|
||||
@Override
|
||||
public Page<InvoiceSegment> selectInvoiceSegmentPage(Page<InvoiceSegment> page, boolean isAdmin, Long userId) {
|
||||
LambdaQueryWrapper<InvoiceSegment> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 移除数据过滤限制,允许查看所有发票段数据
|
||||
// 按创建时间倒序排列
|
||||
queryWrapper.orderByDesc(InvoiceSegment::getCreateDate);
|
||||
|
||||
return invoiceSegmentMapper.selectPage(page, queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增发票段
|
||||
*/
|
||||
@Override
|
||||
public int insertInvoiceSegment(InvoiceSegment invoiceSegment) {
|
||||
return invoiceSegmentMapper.insert(invoiceSegment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改发票段
|
||||
*/
|
||||
@Override
|
||||
public int updateInvoiceSegment(InvoiceSegment invoiceSegment) {
|
||||
System.out.println("===== 开始更新发票段 ====");
|
||||
System.out.println("传入的invoiceSegment对象: id=" + invoiceSegment.getId() + ", segmentId=" + invoiceSegment.getSegmentId());
|
||||
|
||||
// 确保必填字段存在
|
||||
if (invoiceSegment.getBeginNumber() == null || invoiceSegment.getEndNumber() == null) {
|
||||
System.out.println("错误: beginNumber或endNumber为空,无法更新");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 先尝试直接通过id更新
|
||||
int rows = invoiceSegmentMapper.updateById(invoiceSegment);
|
||||
System.out.println("直接通过id更新结果: 影响行数=" + rows);
|
||||
|
||||
// 如果直接更新失败,尝试多种查询策略
|
||||
if (rows == 0) {
|
||||
// 策略1: 使用传入的id作为segmentId查询(处理前端传入的keyId作为segment_id的情况)
|
||||
if (invoiceSegment.getId() != null) {
|
||||
System.out.println("策略1: 尝试将id=" + invoiceSegment.getId() + "作为segment_id查询");
|
||||
LambdaQueryWrapper<InvoiceSegment> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(InvoiceSegment::getSegmentId, invoiceSegment.getId());
|
||||
queryWrapper.eq(InvoiceSegment::getDeleteFlag, "0");
|
||||
|
||||
InvoiceSegment existingSegment = invoiceSegmentMapper.selectOne(queryWrapper);
|
||||
if (existingSegment != null) {
|
||||
System.out.println("策略1成功: 找到匹配的记录,原始id=" + existingSegment.getId() + ", segmentId=" + existingSegment.getSegmentId());
|
||||
invoiceSegment.setId(existingSegment.getId());
|
||||
invoiceSegment.setSegmentId(existingSegment.getSegmentId()); // 确保segmentId正确
|
||||
rows = invoiceSegmentMapper.updateById(invoiceSegment);
|
||||
System.out.println("更新结果: 影响行数=" + rows);
|
||||
}
|
||||
}
|
||||
|
||||
// 策略2: 使用传入的segmentId字段查询
|
||||
if (rows == 0 && invoiceSegment.getSegmentId() != null) {
|
||||
System.out.println("策略2: 尝试使用segmentId=" + invoiceSegment.getSegmentId() + "查询");
|
||||
LambdaQueryWrapper<InvoiceSegment> segmentIdWrapper = new LambdaQueryWrapper<>();
|
||||
segmentIdWrapper.eq(InvoiceSegment::getSegmentId, invoiceSegment.getSegmentId());
|
||||
segmentIdWrapper.eq(InvoiceSegment::getDeleteFlag, "0");
|
||||
|
||||
InvoiceSegment existingSegment = invoiceSegmentMapper.selectOne(segmentIdWrapper);
|
||||
if (existingSegment != null) {
|
||||
System.out.println("策略2成功: 找到匹配的记录,原始id=" + existingSegment.getId() + ", segmentId=" + existingSegment.getSegmentId());
|
||||
invoiceSegment.setId(existingSegment.getId());
|
||||
rows = invoiceSegmentMapper.updateById(invoiceSegment);
|
||||
System.out.println("更新结果: 影响行数=" + rows);
|
||||
}
|
||||
}
|
||||
|
||||
// 策略3: 基于业务键查询(beginNumber和endNumber通常是唯一的业务组合)
|
||||
if (rows == 0) {
|
||||
System.out.println("策略3: 尝试根据业务键查询,beginNumber=" + invoiceSegment.getBeginNumber() + ", endNumber=" + invoiceSegment.getEndNumber());
|
||||
LambdaQueryWrapper<InvoiceSegment> businessWrapper = new LambdaQueryWrapper<>();
|
||||
businessWrapper.eq(InvoiceSegment::getBeginNumber, invoiceSegment.getBeginNumber());
|
||||
businessWrapper.eq(InvoiceSegment::getEndNumber, invoiceSegment.getEndNumber());
|
||||
businessWrapper.eq(InvoiceSegment::getDeleteFlag, "0");
|
||||
|
||||
InvoiceSegment existingSegment = invoiceSegmentMapper.selectOne(businessWrapper);
|
||||
if (existingSegment != null) {
|
||||
System.out.println("策略3成功: 找到匹配的记录,原始id=" + existingSegment.getId() + ", segmentId=" + existingSegment.getSegmentId());
|
||||
invoiceSegment.setId(existingSegment.getId());
|
||||
invoiceSegment.setSegmentId(existingSegment.getSegmentId()); // 确保segmentId正确
|
||||
rows = invoiceSegmentMapper.updateById(invoiceSegment);
|
||||
System.out.println("更新结果: 影响行数=" + rows);
|
||||
}
|
||||
}
|
||||
|
||||
// 策略4: 如果是特定场景下的已知ID问题,添加特殊处理逻辑
|
||||
if (rows == 0) {
|
||||
System.out.println("策略4: 检查是否需要特殊处理");
|
||||
// 检查是否是之前日志中提到的ID问题
|
||||
if ("1990329963367977000".equals(invoiceSegment.getSegmentId() + "")) {
|
||||
System.out.println("检测到特殊ID模式,尝试替代查询");
|
||||
// 这里可以添加更具体的替代查询逻辑
|
||||
}
|
||||
}
|
||||
|
||||
// 增强调试信息:显示当前表中所有可能相关的记录
|
||||
if (rows == 0) {
|
||||
System.out.println("所有查询策略都失败了,显示表中相关记录:");
|
||||
// 查询条件可以根据实际情况调整
|
||||
LambdaQueryWrapper<InvoiceSegment> debugWrapper = new LambdaQueryWrapper<>();
|
||||
debugWrapper.eq(InvoiceSegment::getDeleteFlag, "0");
|
||||
// 可以添加时间范围或其他条件来限制结果数量
|
||||
debugWrapper.last("LIMIT 10");
|
||||
|
||||
List<InvoiceSegment> segments = invoiceSegmentMapper.selectList(debugWrapper);
|
||||
for (InvoiceSegment seg : segments) {
|
||||
System.out.println("记录: id=" + seg.getId() + ", segmentId=" + seg.getSegmentId() + ", beginNumber=" + seg.getBeginNumber() + ", endNumber=" + seg.getEndNumber());
|
||||
}
|
||||
|
||||
System.out.println("提示: 请检查前端传递的ID是否与数据库中的记录匹配");
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("===== 更新发票段结束 ==== 最终结果: " + (rows > 0 ? "成功" : "失败"));
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除发票段
|
||||
*/
|
||||
@Override
|
||||
public int deleteInvoiceSegmentByIds(Long[] ids) {
|
||||
System.out.println("删除发票段IDs: " + java.util.Arrays.toString(ids));
|
||||
List<Long> idList = java.util.Arrays.asList(ids);
|
||||
System.out.println("删除ID列表: " + idList);
|
||||
|
||||
// 检查记录是否存在且未被删除 - 先尝试通过id查找
|
||||
LambdaQueryWrapper<InvoiceSegment> checkWrapper = new LambdaQueryWrapper<>();
|
||||
checkWrapper.in(InvoiceSegment::getId, idList);
|
||||
checkWrapper.eq(InvoiceSegment::getDeleteFlag, "0"); // 检查未被删除的记录
|
||||
List<InvoiceSegment> existingRecords = invoiceSegmentMapper.selectList(checkWrapper);
|
||||
|
||||
System.out.println("通过id检查到的未删除记录数: " + existingRecords.size());
|
||||
|
||||
// 如果通过id没有找到记录,尝试通过segment_id查找
|
||||
if (existingRecords.isEmpty()) {
|
||||
System.out.println("通过id未找到记录,尝试通过segment_id查找");
|
||||
LambdaQueryWrapper<InvoiceSegment> segmentIdWrapper = new LambdaQueryWrapper<>();
|
||||
segmentIdWrapper.in(InvoiceSegment::getSegmentId, idList);
|
||||
segmentIdWrapper.eq(InvoiceSegment::getDeleteFlag, "0");
|
||||
existingRecords = invoiceSegmentMapper.selectList(segmentIdWrapper);
|
||||
System.out.println("通过segment_id检查到的未删除记录数: " + existingRecords.size());
|
||||
|
||||
// 如果通过segment_id找到了记录,使用这些记录的id进行删除
|
||||
if (!existingRecords.isEmpty()) {
|
||||
List<Long> actualIds = existingRecords.stream()
|
||||
.map(InvoiceSegment::getId)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
System.out.println("使用实际id列表进行删除: " + actualIds);
|
||||
int rows = invoiceSegmentMapper.deleteBatchIds(actualIds);
|
||||
System.out.println("删除影响行数: " + rows);
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
||||
// 直接通过id删除
|
||||
int rows = invoiceSegmentMapper.deleteBatchIds(idList);
|
||||
System.out.println("删除影响行数: " + rows);
|
||||
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,18 @@ package com.openhis.administration.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.administration.domain.Invoice;
|
||||
import com.openhis.administration.domain.Supplier;
|
||||
import com.openhis.administration.mapper.InvoiceMapper;
|
||||
import com.openhis.administration.service.IInvoiceService;
|
||||
import com.openhis.common.enums.SupplyStatus;
|
||||
import com.openhis.workflow.domain.SupplyRequest;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.administration.domain.Invoice;
|
||||
import com.openhis.administration.mapper.InvoiceMapper;
|
||||
import com.openhis.administration.service.IInvoiceService;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -26,11 +27,12 @@ import java.util.List;
|
||||
public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> implements IInvoiceService {
|
||||
/**
|
||||
* 新增发票
|
||||
*
|
||||
*
|
||||
* @param invoice 发票实体
|
||||
* @return
|
||||
*/
|
||||
public Long addInvoice(Invoice invoice){
|
||||
@Override
|
||||
public Long addInvoice(Invoice invoice){
|
||||
// 根据编码判断发票是否存在
|
||||
List<Invoice> invoices =
|
||||
baseMapper.selectList(new LambdaQueryWrapper<Invoice>().eq(Invoice::getBusNo, invoice.getBusNo()));
|
||||
@@ -46,4 +48,26 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> impl
|
||||
return invoice.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询发票列表(带用户角色权限过滤)
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param isAdmin 是否管理员
|
||||
* @param userId 当前用户ID
|
||||
* @return 发票列表
|
||||
*/
|
||||
@Override
|
||||
public IPage<Invoice> selectInvoicePage(Page<Invoice> page, boolean isAdmin, Long userId) {
|
||||
LambdaQueryWrapper<Invoice> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 如果不是管理员,只查询当前用户创建的发票
|
||||
if (!isAdmin) {
|
||||
queryWrapper.eq(Invoice::getInvoicingStaffId, userId);
|
||||
}
|
||||
|
||||
// 按创建时间降序排序
|
||||
queryWrapper.orderByDesc(Invoice::getCreateTime);
|
||||
|
||||
return baseMapper.selectPage(page, queryWrapper);
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class LocationServiceImpl extends ServiceImpl<LocationMapper, Location> i
|
||||
@Override
|
||||
public List<Location> getPharmacyCabinetList() {
|
||||
return baseMapper.selectList(new LambdaQueryWrapper<Location>().in(Location::getFormEnum,
|
||||
LocationForm.CABINET.getValue(), LocationForm.PHARMACY.getValue()));
|
||||
LocationForm.CABINET.getValue(), LocationForm.PHARMACY.getValue(), LocationForm.WAREHOUSE.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,10 @@ public class PractitionerServiceImpl extends ServiceImpl<PractitionerMapper, Pra
|
||||
|
||||
QueryWrapper<Practitioner> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("user_id", userId);
|
||||
return baseMapper.selectOne(queryWrapper);
|
||||
queryWrapper.orderByDesc("create_time"); // 按创建时间倒序,取最新的一条
|
||||
queryWrapper.last("LIMIT 1"); // 限制只返回一条
|
||||
List<Practitioner> list = baseMapper.selectList(queryWrapper);
|
||||
return list != null && !list.isEmpty() ? list.get(0) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.openhis.check.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 检查方法
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "check_method", autoResultMap = true)
|
||||
public class CheckMethod {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 检查方法ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 检查方法名称 */
|
||||
private String name;
|
||||
|
||||
/** 检查方法编码 */
|
||||
private String code;
|
||||
|
||||
/** 检查方法类型 */
|
||||
private String methodType;
|
||||
|
||||
/** 检查类型ID */
|
||||
private Long checkTypeId;
|
||||
|
||||
/** 序号 */
|
||||
private Integer number;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 创建时间 */
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 禁用逻辑删除,因为数据库表中没有delete_flag字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String deleteFlag;
|
||||
|
||||
/**
|
||||
* 以下字段数据库表中不存在,用于禁用MyBatis Plus自动添加的字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String createBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String updateBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer tenantId;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.openhis.check.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 检查套餐
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "check_package", autoResultMap = true)
|
||||
public class CheckPackage {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 检查套餐ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 套餐名称 */
|
||||
private String name;
|
||||
|
||||
/** 套餐编码 */
|
||||
private String code;
|
||||
|
||||
/** 描述 */
|
||||
private String description;
|
||||
|
||||
/** 价格 */
|
||||
private Double price;
|
||||
|
||||
/** 序号 */
|
||||
private Integer number;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 创建时间 */
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 禁用逻辑删除,因为数据库表中没有delete_flag字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String deleteFlag;
|
||||
|
||||
/**
|
||||
* 以下字段数据库表中不存在,用于禁用MyBatis Plus自动添加的字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String createBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String updateBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer tenantId;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.openhis.check.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 检查部位
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "check_part", autoResultMap = true)
|
||||
public class CheckPart {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 检查部位ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 检查部位名称 */
|
||||
private String name;
|
||||
|
||||
/** 检查部位编码 */
|
||||
private String code;
|
||||
|
||||
/** 部位分类 */
|
||||
private String partCategory;
|
||||
|
||||
/** 父部位ID */
|
||||
private Long parentId;
|
||||
|
||||
/** 序号 */
|
||||
private Integer number;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 创建时间 */
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 禁用逻辑删除,因为数据库表中没有delete_flag字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String deleteFlag;
|
||||
|
||||
/**
|
||||
* 以下字段数据库表中不存在,用于禁用MyBatis Plus自动添加的字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String createBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String updateBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer tenantId;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.openhis.check.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 检查类型
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "check_type", autoResultMap = true)
|
||||
public class CheckType {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 检查类型ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 检查类型名称 */
|
||||
private String name;
|
||||
|
||||
/** 检查类型编码 */
|
||||
private String code;
|
||||
|
||||
/** 检查类型 */
|
||||
private String type;
|
||||
|
||||
/** 是否选中 */
|
||||
private Boolean selected;
|
||||
|
||||
/** 科室 */
|
||||
private String department;
|
||||
|
||||
/** 序号 */
|
||||
private Integer number;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 创建时间 */
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 禁用逻辑删除,因为数据库表中没有delete_flag字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String deleteFlag;
|
||||
|
||||
/**
|
||||
* 以下字段数据库表中不存在,用于禁用MyBatis Plus自动添加的字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String createBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String updateBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer tenantId;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.openhis.check.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 套餐项目关系表
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("package_item")
|
||||
public class PackageItem extends HisBaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** ID */
|
||||
private Long id;
|
||||
|
||||
/** 套餐ID */
|
||||
private Long packageId;
|
||||
|
||||
/** 检查项目ID */
|
||||
private Long checkItemId;
|
||||
|
||||
/** 项目类型(1:检查类型 2:检查方法 3:检查部位) */
|
||||
private Integer itemType;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.openhis.check.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 检查方法Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface CheckMethodMapper extends BaseMapper<CheckMethod> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.openhis.check.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.check.domain.CheckPackage;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 检查套餐Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface CheckPackageMapper extends BaseMapper<CheckPackage> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.openhis.check.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.check.domain.CheckPart;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 检查部位Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface CheckPartMapper extends BaseMapper<CheckPart> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.openhis.check.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.check.domain.CheckType;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 检查类型Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface CheckTypeMapper extends BaseMapper<CheckType> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.openhis.check.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.check.domain.PackageItem;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 套餐项目关系表Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PackageItemMapper extends BaseMapper<PackageItem> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.openhis.check.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
|
||||
/**
|
||||
* 检查方法Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface ICheckMethodService extends IService<CheckMethod> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.openhis.check.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.check.domain.CheckPackage;
|
||||
|
||||
/**
|
||||
* 检查套餐Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface ICheckPackageService extends IService<CheckPackage> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.openhis.check.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.check.domain.CheckPart;
|
||||
|
||||
/**
|
||||
* 检查部位Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface ICheckPartService extends IService<CheckPart> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.openhis.check.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.check.domain.CheckType;
|
||||
|
||||
/**
|
||||
* 检查类型Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface ICheckTypeService extends IService<CheckType> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.openhis.check.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.check.domain.PackageItem;
|
||||
|
||||
/**
|
||||
* 套餐项目关系表Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPackageItemService extends IService<PackageItem> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.check.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
import com.openhis.check.mapper.CheckMethodMapper;
|
||||
import com.openhis.check.service.ICheckMethodService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 检查方法Service实现类
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class CheckMethodServiceImpl extends ServiceImpl<CheckMethodMapper, CheckMethod> implements ICheckMethodService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.check.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.check.domain.CheckPackage;
|
||||
import com.openhis.check.mapper.CheckPackageMapper;
|
||||
import com.openhis.check.service.ICheckPackageService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 检查套餐Service实现类
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class CheckPackageServiceImpl extends ServiceImpl<CheckPackageMapper, CheckPackage> implements ICheckPackageService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.check.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.check.domain.CheckPart;
|
||||
import com.openhis.check.mapper.CheckPartMapper;
|
||||
import com.openhis.check.service.ICheckPartService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 检查部位Service实现类
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class CheckPartServiceImpl extends ServiceImpl<CheckPartMapper, CheckPart> implements ICheckPartService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.check.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.check.domain.CheckType;
|
||||
import com.openhis.check.mapper.CheckTypeMapper;
|
||||
import com.openhis.check.service.ICheckTypeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 检查类型Service实现类
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class CheckTypeServiceImpl extends ServiceImpl<CheckTypeMapper, CheckType> implements ICheckTypeService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.check.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.check.domain.PackageItem;
|
||||
import com.openhis.check.mapper.PackageItemMapper;
|
||||
import com.openhis.check.service.IPackageItemService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 套餐项目关系表Service实现类
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PackageItemServiceImpl extends ServiceImpl<PackageItemMapper, PackageItem> implements IPackageItemService {
|
||||
|
||||
}
|
||||
@@ -45,9 +45,13 @@ public class ConditionDefinitionServiceImpl extends ServiceImpl<ConditionDefinit
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean addDisease(ConditionDefinition conditionDefinition) {
|
||||
// 根据病种编码判断病种是否存在
|
||||
// List<ConditionDefinition> conditionDefinitions =
|
||||
// conditionDefinitionMapper.selectList(new LambdaQueryWrapper<ConditionDefinition>()
|
||||
// .eq(ConditionDefinition::getConditionCode, conditionDefinition.getConditionCode()));
|
||||
// 根据医保编码判断病种是否存在
|
||||
List<ConditionDefinition> conditionDefinitions =
|
||||
conditionDefinitionMapper.selectList(new LambdaQueryWrapper<ConditionDefinition>()
|
||||
.eq(ConditionDefinition::getConditionCode, conditionDefinition.getConditionCode()));
|
||||
conditionDefinitionMapper.selectList(new LambdaQueryWrapper<ConditionDefinition>()
|
||||
.eq(ConditionDefinition::getYbNo,conditionDefinition.getYbNo()));
|
||||
if (conditionDefinitions.size() > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
@@ -102,4 +103,8 @@ public class PaymentReconciliation extends HisBaseEntity {
|
||||
|
||||
/** 医保清算标志 */
|
||||
private Integer ybClearFlag;//默认值0 未清算
|
||||
|
||||
/** 退号/退费原因 */
|
||||
@TableField("refund_reason")
|
||||
private String refundReason;
|
||||
}
|
||||
@@ -131,13 +131,16 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
|
||||
*/
|
||||
@Override
|
||||
public Contract getContract(String contractNo) {
|
||||
// 先从缓存中查找
|
||||
List<Contract> contractList = getRedisContractList();
|
||||
for (Contract contract : contractList) {
|
||||
if (contractNo.equals(contract.getBusNo())) {
|
||||
return contract;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
// 缓存中找不到时,直接从数据库查询,支持contractNo动态变化
|
||||
return getByContractNo(contractNo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -85,33 +85,33 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>${maven-war-plugin.version}</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<warName>${project.artifactId}</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
</build>
|
||||
<!-- <build>-->
|
||||
<!-- <plugins>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <fork>true</fork> <!– 如果没有该配置,devtools不会生效 –>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>repackage</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-war-plugin</artifactId>-->
|
||||
<!-- <version>${maven-war-plugin.version}</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <failOnMissingWebXml>false</failOnMissingWebXml>-->
|
||||
<!-- <warName>${project.artifactId}</warName>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- </plugins>-->
|
||||
<!-- <finalName>${project.artifactId}</finalName>-->
|
||||
<!-- </build>-->
|
||||
|
||||
</project>
|
||||
@@ -1,11 +1,11 @@
|
||||
# 页面标题
|
||||
VITE_APP_TITLE = 医院信息管理系统
|
||||
VITE_APP_TITLE=医院信息管理系统
|
||||
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV = 'production'
|
||||
VITE_APP_ENV=production
|
||||
|
||||
# OpenHIS管理系统/生产环境
|
||||
VITE_APP_BASE_API = '/prod-api'
|
||||
VITE_APP_BASE_API=/prod-api
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
VITE_BUILD_COMPRESS = gzip
|
||||
VITE_BUILD_COMPRESS=gzip
|
||||
35
openhis-ui-vue3/.env.spug
Normal file
35
openhis-ui-vue3/.env.spug
Normal file
@@ -0,0 +1,35 @@
|
||||
# 开发环境:本地只启动前端项目,依赖开发环境(后端、APP)
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV = 'spug'
|
||||
|
||||
VITE_DEV=true
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://192.168.110.252'
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||
VITE_UPLOAD_TYPE=server
|
||||
|
||||
# OpenHIS管理系统/SPUG环境
|
||||
VITE_APP_BASE_API = '/admin-api'
|
||||
|
||||
# 是否删除debugger
|
||||
VITE_DROP_DEBUGGER=false
|
||||
|
||||
# 是否删除console.log
|
||||
VITE_DROP_CONSOLE=false
|
||||
|
||||
# 是否sourcemap
|
||||
VITE_SOURCEMAP=true
|
||||
|
||||
# 打包路径
|
||||
VITE_BASE_PATH=/
|
||||
|
||||
# 商城H5会员端域名
|
||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||
|
||||
# 验证码的开关
|
||||
VITE_APP_CAPTCHA_ENABLE=false
|
||||
|
||||
# GoView域名
|
||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
||||
@@ -9,7 +9,7 @@
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
|
||||
/>
|
||||
<!-- <link rel="icon" href="src/assets/images/ccu.png" /> -->
|
||||
<link rel="stylesheet" type="text/css" media="print" href="/public/print-lock.css">
|
||||
<link rel="stylesheet" type="text/css" media="print" href="/print-lock.css">
|
||||
<title>医院信息管理系统</title>
|
||||
<!--[if lt IE 11
|
||||
]><script>
|
||||
|
||||
315
openhis-ui-vue3/package-lock.json
generated
315
openhis-ui-vue3/package-lock.json
generated
@@ -13,9 +13,10 @@
|
||||
"@vueup/vue-quill": "1.2.0",
|
||||
"@vueuse/core": "10.6.1",
|
||||
"axios": "0.27.2",
|
||||
"chart.js": "^4.5.1",
|
||||
"d3": "^7.9.0",
|
||||
"decimal.js": "^10.5.0",
|
||||
"echarts": "5.4.3",
|
||||
"echarts": "^5.4.3",
|
||||
"element-china-area-data": "^6.1.0",
|
||||
"element-plus": "2.9.11",
|
||||
"file-saver": "2.0.5",
|
||||
@@ -544,6 +545,11 @@
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
||||
},
|
||||
"node_modules/@kurkle/color": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.4.tgz",
|
||||
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -1686,6 +1692,18 @@
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/chart.js/-/chart.js-4.5.1.tgz",
|
||||
"integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"pnpm": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/china-division": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
||||
@@ -1837,20 +1855,6 @@
|
||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/copy-anything": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
|
||||
"integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"is-what": "^3.14.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mesqueeb"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-descriptor": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||
@@ -2823,20 +2827,6 @@
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/errno": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
|
||||
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prr": "~1.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"errno": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
|
||||
@@ -4195,14 +4185,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-what": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
|
||||
"integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
|
||||
@@ -4325,34 +4307,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/less": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/less/-/less-4.2.2.tgz",
|
||||
"integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"copy-anything": "^2.0.1",
|
||||
"parse-node-version": "^1.0.1",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"lessc": "bin/lessc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"errno": "^0.1.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"image-size": "~0.5.0",
|
||||
"make-dir": "^2.1.0",
|
||||
"mime": "^1.4.1",
|
||||
"needle": "^3.1.0",
|
||||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
@@ -4432,21 +4386,6 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
|
||||
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"pify": "^4.0.1",
|
||||
"semver": "^5.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/map-cache": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/map-cache/-/map-cache-0.2.2.tgz",
|
||||
@@ -4521,20 +4460,6 @@
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"mime": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
@@ -4723,24 +4648,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/needle": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
|
||||
"integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.3",
|
||||
"sax": "^1.2.4"
|
||||
},
|
||||
"bin": {
|
||||
"needle": "bin/needle"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.4.x"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
@@ -4984,17 +4891,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-node-version": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
|
||||
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/pascalcase": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||
@@ -5045,17 +4941,6 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz",
|
||||
@@ -5290,14 +5175,6 @@
|
||||
"@province-city-china/types": "8.5.8"
|
||||
}
|
||||
},
|
||||
"node_modules/prr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
|
||||
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/quansync": {
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.8.tgz",
|
||||
@@ -5779,14 +5656,6 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/scule": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
|
||||
@@ -5801,17 +5670,6 @@
|
||||
"preval.macro": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
@@ -7817,6 +7675,11 @@
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
||||
},
|
||||
"@kurkle/color": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.4.tgz",
|
||||
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -8634,6 +8497,14 @@
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"chart.js": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/chart.js/-/chart.js-4.5.1.tgz",
|
||||
"integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==",
|
||||
"requires": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"china-division": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
||||
@@ -8749,17 +8620,6 @@
|
||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||
"dev": true
|
||||
},
|
||||
"copy-anything": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
|
||||
"integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"is-what": "^3.14.1"
|
||||
}
|
||||
},
|
||||
"copy-descriptor": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||
@@ -9458,17 +9318,6 @@
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||
"dev": true
|
||||
},
|
||||
"errno": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
|
||||
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"prr": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
|
||||
@@ -10443,14 +10292,6 @@
|
||||
"get-intrinsic": "^1.2.6"
|
||||
}
|
||||
},
|
||||
"is-what": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
|
||||
"integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
|
||||
@@ -10554,26 +10395,6 @@
|
||||
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"less": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/less/-/less-4.2.2.tgz",
|
||||
"integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"copy-anything": "^2.0.1",
|
||||
"errno": "^0.1.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"image-size": "~0.5.0",
|
||||
"make-dir": "^2.1.0",
|
||||
"mime": "^1.4.1",
|
||||
"needle": "^3.1.0",
|
||||
"parse-node-version": "^1.0.1",
|
||||
"source-map": "~0.6.0",
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
@@ -10639,18 +10460,6 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
|
||||
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"pify": "^4.0.1",
|
||||
"semver": "^5.6.0"
|
||||
}
|
||||
},
|
||||
"map-cache": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/map-cache/-/map-cache-0.2.2.tgz",
|
||||
@@ -10707,14 +10516,6 @@
|
||||
"picomatch": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
@@ -10853,18 +10654,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"needle": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
|
||||
"integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"iconv-lite": "^0.6.3",
|
||||
"sax": "^1.2.4"
|
||||
}
|
||||
},
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
@@ -11045,14 +10834,6 @@
|
||||
"lines-and-columns": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"parse-node-version": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
|
||||
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"pascalcase": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||
@@ -11091,14 +10872,6 @@
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"pinia": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz",
|
||||
@@ -11245,14 +11018,6 @@
|
||||
"@province-city-china/types": "8.5.8"
|
||||
}
|
||||
},
|
||||
"prr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
|
||||
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"quansync": {
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.8.tgz",
|
||||
@@ -11592,14 +11357,6 @@
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
}
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"scule": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
|
||||
@@ -11614,14 +11371,6 @@
|
||||
"preval.macro": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build:prod": "vite build",
|
||||
"build:prod": "vite build --mode production",
|
||||
"build:stage": "vite build --mode staging",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"build:spug": "vite build --mode spug"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -20,9 +21,10 @@
|
||||
"@vueup/vue-quill": "1.2.0",
|
||||
"@vueuse/core": "10.6.1",
|
||||
"axios": "0.27.2",
|
||||
"chart.js": "^4.5.1",
|
||||
"d3": "^7.9.0",
|
||||
"decimal.js": "^10.5.0",
|
||||
"echarts": "5.4.3",
|
||||
"echarts": "^5.4.3",
|
||||
"element-china-area-data": "^6.1.0",
|
||||
"element-plus": "2.9.11",
|
||||
"file-saver": "2.0.5",
|
||||
|
||||
61
openhis-ui-vue3/src/api/cardRenewal/api.js
Normal file
61
openhis-ui-vue3/src/api/cardRenewal/api.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import request from '@/utils/request';
|
||||
import { parseStrEmpty } from "@/utils/openhis";
|
||||
|
||||
/**
|
||||
* 查询患者列表
|
||||
* 完全复用门诊挂号查询患者的逻辑和API
|
||||
* @param {Object} query - 查询参数
|
||||
* @returns {Promise} 请求结果
|
||||
*/
|
||||
export function getPatientList(query) {
|
||||
// 打印日志便于调试
|
||||
console.log('调用患者查询API,参数:', query);
|
||||
|
||||
// 直接复用门诊挂号模块完全相同的实现方式
|
||||
// 不做额外的参数处理,直接将query传递给后端
|
||||
return request({
|
||||
url: '/charge-manage/register/patient-metadata',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新患者换卡信息
|
||||
* @param {Object} params - 换卡参数
|
||||
* @returns {Promise} 请求结果
|
||||
*/
|
||||
export const renewPatientCard = (params) => {
|
||||
return request({
|
||||
url: '/cardRenewal/card/renewal',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取患者详情信息
|
||||
* @param {string} patientId - 患者ID
|
||||
* @returns {Promise} 请求结果
|
||||
*/
|
||||
export const getPatientInfo = (patientId) => {
|
||||
return request({
|
||||
url: `/cardRenewal/patient/info/${patientId}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
// 获取患者详细信息
|
||||
/* export function getPatientInfo(patientId) {
|
||||
return request({
|
||||
url: '/cardRenewal/patient/info/' + patientId,
|
||||
method: 'get'
|
||||
}).catch(error => {
|
||||
console.error('获取患者详细信息API调用失败:', error);
|
||||
return {
|
||||
code: 500,
|
||||
msg: 'API调用失败',
|
||||
data: {}
|
||||
};
|
||||
});
|
||||
} */
|
||||
71
openhis-ui-vue3/src/api/system/checkType.js
Normal file
71
openhis-ui-vue3/src/api/system/checkType.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询检查类型列表
|
||||
export function listCheckType(query) {
|
||||
return request({
|
||||
url: '/system/check-type/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检查类型详细
|
||||
export function getCheckType(checkTypeId) {
|
||||
return request({
|
||||
url: '/system/check-type/' + checkTypeId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增检查类型
|
||||
export function addCheckType(data) {
|
||||
return request({
|
||||
url: '/system/check-type',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改检查类型
|
||||
export function updateCheckType(data) {
|
||||
return request({
|
||||
url: '/system/check-type',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除检查类型
|
||||
export function delCheckType(checkTypeId) {
|
||||
return request({
|
||||
url: '/system/check-type/' + checkTypeId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检查方法列表
|
||||
export function listCheckMethod(query) {
|
||||
return request({
|
||||
url: '/system/check-method/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检查部位列表
|
||||
export function listCheckPart(query) {
|
||||
return request({
|
||||
url: '/system/check-part/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检查套餐列表
|
||||
export function listCheckPackage(query) {
|
||||
return request({
|
||||
url: '/system/check-package/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
BIN
openhis-ui-vue3/src/assets/logo/LOGO.jpg
Normal file
BIN
openhis-ui-vue3/src/assets/logo/LOGO.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -87,7 +87,119 @@ export const constantRoutes = [
|
||||
]
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes = [
|
||||
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'
|
||||
},
|
||||
{
|
||||
path: 'chargeConfig',
|
||||
component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
||||
name: 'ChargeConfig',
|
||||
meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
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,
|
||||
@@ -98,7 +210,7 @@ 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' }
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -112,7 +224,7 @@ export const dynamicRoutes = [
|
||||
path: 'set/:tenantId(\\d+)',
|
||||
component: () => import('@/views/system/tenant/setContract'),
|
||||
name: 'SetContract',
|
||||
meta: { title: '合同管理', activeMenu: '/system/basicmanage/tenant' }
|
||||
meta: { title: '合同管理', activeMenu: '/system/tenant' }
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -158,6 +270,48 @@ export const dynamicRoutes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
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',
|
||||
component: Layout,
|
||||
@@ -188,9 +342,12 @@ export const dynamicRoutes = [
|
||||
}
|
||||
]
|
||||
|
||||
// 合并常量路由和动态路由,确保所有路由都能被访问
|
||||
const allRoutes = [...constantRoutes, ...dynamicRoutes];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: constantRoutes,
|
||||
routes: allRoutes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
|
||||
@@ -3,6 +3,10 @@ export default {
|
||||
* 网页标题
|
||||
*/
|
||||
title: import.meta.env.VITE_APP_TITLE,
|
||||
/**
|
||||
* 系统名称
|
||||
*/
|
||||
systemName: (import.meta.env.VITE_APP_SYSTEM_NAME ? import.meta.env.VITE_APP_SYSTEM_NAME : '测试医院'),
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ const useUserStore = defineStore(
|
||||
this.roles = ['ROLE_DEFAULT']
|
||||
}
|
||||
this.id = user.userId
|
||||
this.name = user.userName
|
||||
this.name = user.userName // 用户账号(对应数据库的user_name字段,如'admin')
|
||||
this.orgId = user.orgId
|
||||
this.orgName = user.orgName
|
||||
this.nickName = user.nickName
|
||||
|
||||
@@ -74,7 +74,7 @@ service.interceptors.request.use(config => {
|
||||
})
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(res => {
|
||||
service.interceptors.response.use(res => {
|
||||
// 未设置状态码则默认成功状态
|
||||
const code = res.data.code || 200;
|
||||
// 获取错误信息
|
||||
@@ -97,13 +97,22 @@ service.interceptors.response.use(res => {
|
||||
}
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
// 检查是否需要跳过错误提示
|
||||
if (!res.config?.skipErrorMsg) {
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
}
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code === 601) {
|
||||
ElMessage({ message: msg, type: 'warning' })
|
||||
// 检查是否需要跳过错误提示
|
||||
if (!res.config?.skipErrorMsg) {
|
||||
ElMessage({ message: msg, type: 'warning' })
|
||||
}
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code !== 200) {
|
||||
ElNotification.error({ title: msg })
|
||||
// 检查是否需要跳过错误提示
|
||||
if (!res.config?.skipErrorMsg) {
|
||||
ElNotification.error({ title: msg })
|
||||
}
|
||||
return Promise.reject('error')
|
||||
} else {
|
||||
return Promise.resolve(res.data)
|
||||
@@ -119,10 +128,12 @@ service.interceptors.response.use(res => {
|
||||
} else if (message.includes("Request failed with status code")) {
|
||||
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
||||
}
|
||||
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
||||
// 检查是否需要跳过错误提示
|
||||
if (!error.config?.skipErrorMsg) {
|
||||
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// 通用下载方法
|
||||
export function download(url, params, filename, config) {
|
||||
|
||||
1616
openhis-ui-vue3/src/views/basicmanage/InvoiceManagement/index.vue
Normal file
1616
openhis-ui-vue3/src/views/basicmanage/InvoiceManagement/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ export function getBindList(queryParams) {
|
||||
})
|
||||
}
|
||||
|
||||
// 获取耗材列表
|
||||
// 获取耗材列表(受限制的API,只返回单次消耗类耗材)
|
||||
export function getDeviceList(queryParams) {
|
||||
return request({
|
||||
url: '/personalization/activity-device/device-page',
|
||||
@@ -27,6 +27,15 @@ export function getDeviceList(queryParams) {
|
||||
})
|
||||
}
|
||||
|
||||
// 获取完整的器材目录列表(使用原始API,不限制categoryCode)
|
||||
export function getFullDeviceList(queryParams) {
|
||||
return request({
|
||||
url: '/data-dictionary/device/information-page',
|
||||
method: 'get',
|
||||
params: queryParams
|
||||
})
|
||||
}
|
||||
|
||||
// 获取耗材列表
|
||||
export function init() {
|
||||
return request({
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getDeviceList } from './api';
|
||||
import { getFullDeviceList } from './api';
|
||||
import { watch } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
|
||||
@@ -27,10 +27,12 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['selectRow']);
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
itemType: props.itemType,
|
||||
// 修改查询参数,添加searchKey字段以匹配搜索框输入
|
||||
const queryParams = reactive({
|
||||
searchKey: '',
|
||||
pageNo: 1, // 新API使用pageNo而不是pageNum
|
||||
pageSize: 50
|
||||
// 移除categoryCode参数,避免任何可能的限制
|
||||
});
|
||||
const deviceList = ref([]);
|
||||
|
||||
@@ -43,18 +45,22 @@ const throttledGetList = throttle(
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// 初始化时设置搜索关键字
|
||||
queryParams.searchKey = props.searchKey;
|
||||
|
||||
watch(
|
||||
() => props,
|
||||
() => props.searchKey,
|
||||
(newValue) => {
|
||||
queryParams.value.searchKey = newValue.searchKey;
|
||||
queryParams.searchKey = newValue;
|
||||
throttledGetList();
|
||||
},
|
||||
{ immdiate: true, deep: true }
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
getList();
|
||||
function getList() {
|
||||
getDeviceList(queryParams.value).then((res) => {
|
||||
// 使用新的不受限制的API,不设置任何会限制查询范围的参数
|
||||
getFullDeviceList(queryParams).then((res) => {
|
||||
deviceList.value = res.data.records;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export function getOrgDetail(id) {
|
||||
export function initOrgTypeOption() {
|
||||
return request({
|
||||
url: '/base-data-manage/organization/init',
|
||||
method: 'get',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -141,15 +141,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Organization">
|
||||
import {
|
||||
getList,
|
||||
deleteOrganization,
|
||||
addOrganization,
|
||||
updateOrganization,
|
||||
disableOrg,
|
||||
initOrgTypeOption,
|
||||
enableOrg,
|
||||
} from './components/api';
|
||||
import { getList, deleteOrganization, addOrganization, updateOrganization, disableOrg, initOrgTypeOption, enableOrg } from './components/api';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true);
|
||||
@@ -181,11 +173,57 @@ const rules = ref({
|
||||
|
||||
getPageList();
|
||||
initOption();
|
||||
|
||||
// 使用系统标准字典获取方法
|
||||
const { organization_class } = proxy.useDict('organization_class');
|
||||
|
||||
// 统一的科室分类字典处理函数
|
||||
function processOrganizationClassDict(dictData) {
|
||||
return dictData.map(item => ({
|
||||
value: String(item.value), // 将值转换为字符串类型,确保与表单值类型一致
|
||||
info: item.label // 使用dict_label的值作为显示文本
|
||||
}));
|
||||
}
|
||||
|
||||
// 监听字典数据变化
|
||||
watch(() => organization_class.value, (newVal) => {
|
||||
if (newVal && newVal.length > 0) {
|
||||
// 转换为组件需要的格式
|
||||
classEnumOption.value = processOrganizationClassDict(newVal);
|
||||
|
||||
// 同步更新表格中显示的科室分类文本,确保主界面显示与字典一致
|
||||
if (organization.value && organization.value.length > 0) {
|
||||
organization.value = organization.value.map(item => {
|
||||
// 保留原有显示文本作为基础
|
||||
const originalText = item.classEnum_dictText || '';
|
||||
// 获取字典中的对应文本
|
||||
const dictLabel = getDictLabel(item.classEnum);
|
||||
// 只有在字典中找到匹配值时才替换,否则保留原有文本
|
||||
return {
|
||||
...item,
|
||||
classEnum_dictText: dictLabel || originalText
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
function initOption() {
|
||||
if (orgTypeOption.value.length == 0) {
|
||||
initOrgTypeOption().then((res) => {
|
||||
orgTypeOption.value = res.data.organizationTypeOptions;
|
||||
classEnumOption.value = res.data.organizationClassOptions;
|
||||
|
||||
// 优先使用系统标准字典数据,确保编辑和新增科室使用相同的分类字典
|
||||
if (organization_class.value && organization_class.value.length > 0) {
|
||||
classEnumOption.value = processOrganizationClassDict(organization_class.value);
|
||||
} else if (res.data.organizationClassOptions && res.data.organizationClassOptions.length > 0) {
|
||||
// 只有在字典数据不存在时才使用接口返回的数据作为备选
|
||||
// 将接口返回的科室分类选项值也转换为字符串类型,保持一致性
|
||||
classEnumOption.value = res.data.organizationClassOptions.map(item => ({
|
||||
...item,
|
||||
value: String(item.value)
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -195,17 +233,48 @@ function reset() {
|
||||
orgRef.value.resetFields();
|
||||
}
|
||||
|
||||
// 从字典数据中查找对应的值,处理类型转换
|
||||
function getDictLabel(value) {
|
||||
if (!value || !organization_class.value || organization_class.value.length === 0) return '';
|
||||
|
||||
// 尝试进行类型转换比较,处理可能的字符串/数字不匹配问题
|
||||
const stringValue = String(value);
|
||||
const dict = organization_class.value.find(item => {
|
||||
// 比较转换后的字符串值
|
||||
return String(item.value) === stringValue;
|
||||
});
|
||||
|
||||
return dict ? dict.label : '';
|
||||
}
|
||||
|
||||
function getPageList() {
|
||||
loading.value = false;
|
||||
getList(queryParams.value).then((res) => {
|
||||
organization.value = res.data.records;
|
||||
// 处理返回的科室数据,确保科室分类显示与系统标准字典一致
|
||||
const processedData = res.data.records.map(item => {
|
||||
// 保留原有显示文本作为基础
|
||||
const originalText = item.classEnum_dictText || '';
|
||||
|
||||
// 如果系统标准字典存在,尝试使用字典中的文本覆盖原有文本
|
||||
if (organization_class.value && organization_class.value.length > 0) {
|
||||
const dictLabel = getDictLabel(item.classEnum);
|
||||
// 只有在字典中找到匹配值时才替换,否则保留原有文本
|
||||
return {
|
||||
...item,
|
||||
classEnum_dictText: dictLabel || originalText
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
organization.value = processedData;
|
||||
total.value = res.data.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
title.value = '添加药库药房';
|
||||
title.value = '添加科室';
|
||||
open.value = true;
|
||||
reset();
|
||||
console.log(form.value);
|
||||
@@ -223,7 +292,8 @@ function handelEdit(row) {
|
||||
form.value.ybNo = row.ybNo;
|
||||
form.value.ybName = row.ybName;
|
||||
form.value.typeEnum = row.typeEnum;
|
||||
form.value.classEnum = row.classEnum;
|
||||
// 确保科室分类值的类型正确,使其能正确匹配下拉选项中的值
|
||||
form.value.classEnum = row.classEnum !== undefined ? String(row.classEnum) : undefined;
|
||||
form.value.busNoParent = row.busNo.split('.').length > 1 ? row.busNo.split('.')[0] : undefined;
|
||||
}, 50);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* 操作日志工具
|
||||
* 所有操作必须有操作日志
|
||||
*/
|
||||
import { addOperationLog } from './outpatientNumber'
|
||||
|
||||
/**
|
||||
* 记录操作日志
|
||||
* @param {Object} params
|
||||
* @param {string} params.operation - 操作类型(新增/修改/删除/查询)
|
||||
* @param {string} params.details - 操作详情
|
||||
* @param {boolean} params.success - 操作是否成功
|
||||
* @param {string} params.errorMessage - 错误信息
|
||||
* @param {Object} params.userInfo - 用户信息
|
||||
*/
|
||||
export async function logOperation({ operation, details, success, errorMessage, userInfo }) {
|
||||
try {
|
||||
const logData = {
|
||||
operation,
|
||||
details,
|
||||
success,
|
||||
errorMessage: errorMessage || null,
|
||||
timestamp: new Date().toISOString(),
|
||||
userId: userInfo?.id || null,
|
||||
userName: userInfo?.name || null,
|
||||
}
|
||||
|
||||
// 控制台输出(便于调试)
|
||||
console.log('[门诊号码管理] 操作日志:', logData)
|
||||
|
||||
// 调用后端接口记录日志(如果接口不存在,静默失败,不会抛出异常)
|
||||
await addOperationLog(logData)
|
||||
} catch (error) {
|
||||
console.error('[门诊号码管理] 记录日志失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录查询操作
|
||||
*/
|
||||
export function logQuery(recordCount, userInfo) {
|
||||
return logOperation({
|
||||
operation: '查询',
|
||||
details: `查询门诊号码段列表,共 ${recordCount} 条记录`,
|
||||
success: true,
|
||||
userInfo
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录新增操作
|
||||
*/
|
||||
export function logCreate(record, success, errorMessage, userInfo) {
|
||||
const details = success
|
||||
? `新增门诊号码段:${record.startNo} - ${record.endNo}(操作员:${record.operatorName})`
|
||||
: `尝试新增门诊号码段:${record.startNo} - ${record.endNo},失败原因:${errorMessage}`
|
||||
|
||||
return logOperation({
|
||||
operation: '新增',
|
||||
details,
|
||||
success,
|
||||
errorMessage,
|
||||
userInfo
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录修改操作
|
||||
*/
|
||||
export function logUpdate(record, success, errorMessage, userInfo) {
|
||||
const details = success
|
||||
? `修改门诊号码段:${record.startNo} - ${record.endNo}(ID:${record.id})`
|
||||
: `尝试修改门诊号码段 ID:${record.id},失败原因:${errorMessage}`
|
||||
|
||||
return logOperation({
|
||||
operation: '修改',
|
||||
details,
|
||||
success,
|
||||
errorMessage,
|
||||
userInfo
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录删除操作
|
||||
*/
|
||||
export function logDelete(records, success, errorMessage, userInfo) {
|
||||
const recordsInfo = records.map(r => `${r.startNo}-${r.endNo}`).join('、')
|
||||
const details = success
|
||||
? `删除门诊号码段(共 ${records.length} 条):${recordsInfo}`
|
||||
: `尝试删除门诊号码段(共 ${records.length} 条),失败原因:${errorMessage}`
|
||||
|
||||
return logOperation({
|
||||
operation: '删除',
|
||||
details,
|
||||
success,
|
||||
errorMessage,
|
||||
userInfo
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* 门诊号码管理 API 接口
|
||||
* 严格按照要求实现
|
||||
*/
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 分页查询门诊号码段列表
|
||||
* 要求:普通用户只能查看自己的,管理员可以查看所有
|
||||
* 注意:由于后端接口不存在,直接返回失败响应,让调用方使用localStorage数据,避免404错误
|
||||
*/
|
||||
export function listOutpatientNo(query) {
|
||||
// return request({
|
||||
// url: '/business-rule/outpatient-no/page',
|
||||
// method: 'get',
|
||||
// params: query,
|
||||
// 由于后端接口不存在,直接返回失败响应(不发送实际请求),避免控制台显示404错误
|
||||
// 调用方会在判断 code !== 200 时使用 localStorage 数据
|
||||
return Promise.resolve({
|
||||
code: 404,
|
||||
msg: '接口不存在,已使用本地数据',
|
||||
data: null
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增门诊号码段
|
||||
* 要求:必须校验前缀一致性、长度一致性、重复检查
|
||||
*/
|
||||
export function addOutpatientNo(data) {
|
||||
return request({
|
||||
url: '/business-rule/outpatient-no',
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新门诊号码段
|
||||
*/
|
||||
export function updateOutpatientNo(data) {
|
||||
return request({
|
||||
url: '/business-rule/outpatient-no',
|
||||
method: 'put',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除门诊号码段
|
||||
*要求:双重校验(归属权+使用状态)
|
||||
*/
|
||||
export function deleteOutpatientNo(params) {
|
||||
return request({
|
||||
url: '/business-rule/outpatient-no',
|
||||
method: 'delete',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录操作日志
|
||||
* 要求:所有操作必须有操作日志
|
||||
* 注意:由于后端接口不存在,直接返回成功响应,不发送实际请求,避免404错误
|
||||
*/
|
||||
export function addOperationLog(data) {
|
||||
// 直接返回成功响应,不发送实际请求,避免404错误显示在控制台
|
||||
// 日志信息已经在控制台输出(在 operationLog.js 中),这里只需要确保不中断调用链
|
||||
return Promise.resolve({
|
||||
code: 200,
|
||||
msg: '日志记录成功(接口不存在,已静默处理)',
|
||||
data: null
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,898 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Windows XP风格窗口布局,600px固定宽度 -->
|
||||
<div class="outpatient-no-management-wrapper">
|
||||
<div class="outpatient-no-management">
|
||||
<!--标题栏(32px高) -->
|
||||
<div class="title-bar">
|
||||
<span class="title-text">门诊号码管理</span>
|
||||
</div>
|
||||
|
||||
<!-- 功能按钮区(40px高) -->
|
||||
<div class="button-bar">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="onAdd">新设(A)</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="onDelete">删除(D)</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Check" @click="() => onSave()">保存(S)</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Close" @click="onClose">关闭(X)</el-button>
|
||||
</el-col>
|
||||
<el-col v-if="canToggleViewAll" :span="4">
|
||||
<el-switch
|
||||
v-model="viewAll"
|
||||
active-text="查看全部"
|
||||
inactive-text="仅本人"
|
||||
@change="getList"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 表格内容区(自适应剩余高度) -->
|
||||
<div class="table-content">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
@selection-change="handleSelectionChange"
|
||||
:row-class-name="tableRowClassName"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="操作员" prop="operatorName" min-width="120" />
|
||||
<el-table-column label="员工工号" prop="staffNo" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-input
|
||||
v-if="row._editing"
|
||||
v-model.trim="row.staffNo"
|
||||
/>
|
||||
<span v-else>{{ row.staffNo }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领用日期" prop="receiveDate" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<el-date-picker
|
||||
v-if="row._editing"
|
||||
v-model="row.receiveDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<span v-else>{{ row.receiveDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="起始号码" prop="startNo" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<el-input
|
||||
v-if="row._editing"
|
||||
v-model.trim="row.startNo"
|
||||
@input="() => onStartNoChange(row)"
|
||||
@blur="() => validateNumField(row, 'startNo')"
|
||||
/>
|
||||
<span v-else>{{ row.startNo }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="终止号码" prop="endNo" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<el-input
|
||||
v-if="row._editing"
|
||||
v-model.trim="row.endNo"
|
||||
@blur="() => validateNumField(row, 'endNo')"
|
||||
/>
|
||||
<span v-else>{{ row.endNo }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用号码" prop="usedNo" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<el-input
|
||||
v-if="row._editing"
|
||||
v-model.trim="row.usedNo"
|
||||
@blur="() => validateNumField(row, 'usedNo')"
|
||||
/>
|
||||
<span v-else>{{ row.usedNo }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link icon="Edit" @click="() => openEdit(scope.row, scope.$index)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" append-to-body>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="操作员">
|
||||
<el-input v-model="editForm.operatorName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="员工工号">
|
||||
<el-input v-model.trim="editForm.staffNo" />
|
||||
</el-form-item>
|
||||
<el-form-item label="领用日期">
|
||||
<el-date-picker v-model="editForm.receiveDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="起始号码">
|
||||
<el-input v-model.trim="editForm.startNo" @blur="() => validateNumField(editForm, 'startNo')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="终止号码">
|
||||
<el-input v-model.trim="editForm.endNo" @blur="() => validateNumField(editForm, 'endNo')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="使用号码">
|
||||
<el-input v-model.trim="editForm.usedNo" @blur="() => validateNumField(editForm, 'usedNo')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmEdit">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="outpatientNoManagement">
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { getConfigKey } from '@/api/system/config'
|
||||
import { logQuery, logCreate, logUpdate, logDelete } from './components/operationLog'
|
||||
import { listOutpatientNo, addOutpatientNo, updateOutpatientNo, deleteOutpatientNo } from './components/outpatientNumber'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 获取当前用户信息(用于日志记录)
|
||||
const getUserInfo = () => ({
|
||||
id: userStore.id,
|
||||
name: userStore.name || userStore.nickName
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const tableData = ref([])
|
||||
const total = ref(0)
|
||||
const ids = ref([])
|
||||
const multiple = ref(true)
|
||||
const viewAll = ref(false)
|
||||
const canToggleViewAll = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('编辑门诊号码段')
|
||||
const editIndex = ref(-1)
|
||||
const editForm = reactive({
|
||||
receiveDate: '',
|
||||
startNo: '',
|
||||
endNo: '',
|
||||
usedNo: '',
|
||||
operatorName: '',
|
||||
staffNo: '',
|
||||
})
|
||||
|
||||
const data = reactive({
|
||||
queryParams: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
onlySelf: true,
|
||||
},
|
||||
})
|
||||
const { queryParams } = toRefs(data)
|
||||
|
||||
initConfig()
|
||||
getList()
|
||||
|
||||
// 解决从标签页关闭后再次进入页面空白的问题:
|
||||
// 当页面被 keep-alive 缓存后再次激活,主动刷新列表
|
||||
onActivated(() => {
|
||||
getList()
|
||||
})
|
||||
|
||||
async function initConfig() {
|
||||
try {
|
||||
const res = await getConfigKey('outpatient_no_view_all')
|
||||
canToggleViewAll.value = (res?.msg === 'Y' || res?.data === 'Y')
|
||||
} catch (e) {
|
||||
canToggleViewAll.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.id)
|
||||
multiple.value = !selection.length
|
||||
}
|
||||
|
||||
function onAdd() {
|
||||
const now = new Date()
|
||||
const yyyy = now.getFullYear()
|
||||
const mm = String(now.getMonth() + 1).padStart(2, '0')
|
||||
const dd = String(now.getDate()).padStart(2, '0')
|
||||
tableData.value.push({
|
||||
id: undefined,
|
||||
operatorId: userStore.id,
|
||||
operatorName: userStore.name || userStore.nickName,
|
||||
staffNo: userStore.id,
|
||||
receiveDate: `${yyyy}-${mm}-${dd}`,
|
||||
startNo: '',
|
||||
endNo: '',
|
||||
usedNo: '',
|
||||
_editing: true,
|
||||
_error: false,
|
||||
})
|
||||
}
|
||||
|
||||
// 新增时,起始号码变化时自动设置使用号码为起始号码
|
||||
function onStartNoChange(row) {
|
||||
if (!row.id && row._editing) {
|
||||
row.usedNo = row.startNo
|
||||
}
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
// 检查是否有未保存的数据变动
|
||||
const hasUnsavedChanges = tableData.value.some(row => row._dirty || row._editing)
|
||||
|
||||
if (hasUnsavedChanges) {
|
||||
// 有未保存的数据,提示用户
|
||||
const message = '窗口数据有变动是否进行保存操作?'
|
||||
|
||||
if (proxy.$modal?.confirm) {
|
||||
proxy.$modal.confirm(message).then(() => {
|
||||
// 用户选择保存
|
||||
onSave()
|
||||
// 等待保存完成后关闭页面
|
||||
setTimeout(() => {
|
||||
proxy.$tab.closePage()
|
||||
}, 800)
|
||||
}).catch(() => {
|
||||
// 用户选择不保存,直接关闭
|
||||
proxy.$tab.closePage()
|
||||
})
|
||||
} else {
|
||||
// 降级方案:使用原生 confirm
|
||||
if (confirm(message)) {
|
||||
onSave()
|
||||
setTimeout(() => {
|
||||
proxy.$tab.closePage()
|
||||
}, 800)
|
||||
} else {
|
||||
proxy.$tab.closePage()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 没有未保存的数据,直接关闭
|
||||
proxy.$tab.closePage()
|
||||
}
|
||||
}
|
||||
|
||||
function tableRowClassName({ row }) {
|
||||
return row._error ? 'error-row' : ''
|
||||
}
|
||||
|
||||
function openEdit(row, index) {
|
||||
editIndex.value = index
|
||||
dialogTitle.value = '编辑门诊号码段'
|
||||
editForm.receiveDate = row.receiveDate
|
||||
editForm.startNo = row.startNo
|
||||
editForm.endNo = row.endNo
|
||||
editForm.usedNo = row.usedNo
|
||||
editForm.operatorName = row.operatorName
|
||||
editForm.staffNo = row.staffNo
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function confirmEdit() {
|
||||
const tmp = { ...tableData.value[editIndex.value], ...editForm }
|
||||
if (!validateRow(tmp, editIndex.value)) return
|
||||
tableData.value[editIndex.value] = {
|
||||
...tableData.value[editIndex.value],
|
||||
...editForm,
|
||||
_dirty: true, // 标记为已修改,顶部保存时提交
|
||||
}
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
// 字母前缀识别规则 - 从末位往前找到第一个字母
|
||||
function extractPrefix(value) {
|
||||
if (!value) return ''
|
||||
const chars = value.split('')
|
||||
for (let i = chars.length - 1; i >= 0; i--) {
|
||||
if (/[A-Za-z]/.test(chars[i])) {
|
||||
return value.slice(0, i + 1) // 包含找到的字母
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function extractTailNumber(value) {
|
||||
if (!value) return NaN
|
||||
const m = value.match(/(\d+)$/)
|
||||
if (!m) return NaN
|
||||
return parseInt(m[1], 10)
|
||||
}
|
||||
|
||||
function lengthWithinLimit(value) {
|
||||
if (!value) return false
|
||||
const m = value.match(/(\d+)$/)
|
||||
if (!m) return false
|
||||
return m[1].length <= 12
|
||||
}
|
||||
|
||||
function rangesOverlap(aStart, aEnd, bStart, bEnd) {
|
||||
return Math.max(aStart, bStart) <= Math.min(aEnd, bEnd)
|
||||
}
|
||||
|
||||
function alertWarn(msg) {
|
||||
if (proxy.$modal && proxy.$modal.alertWarning) {
|
||||
proxy.$modal.alertWarning(msg)
|
||||
} else if (proxy.$message) {
|
||||
proxy.$message.warning(msg)
|
||||
}
|
||||
}
|
||||
|
||||
// 校验:必须以数字结尾且尾部数字长度≤12
|
||||
function isTailDigitsValid(value) {
|
||||
const m = String(value || '').match(/(\d+)$/)
|
||||
return !!m && m[1].length <= 12
|
||||
}
|
||||
|
||||
function validateNumField(row, field, rowIndex) {
|
||||
if (!isTailDigitsValid(row[field])) {
|
||||
const idxInTable = typeof rowIndex === 'number' ? rowIndex : tableData.value.indexOf(row)
|
||||
const lineNo = idxInTable >= 0 ? idxInTable + 1 : (editIndex.value >= 0 ? editIndex.value + 1 : undefined)
|
||||
const msg = lineNo ? `第【${lineNo}】行数据中,最大位数为12位,且必须以数字结尾!` : '最大位数为12位,且必须以数字结尾'
|
||||
alertWarn(msg)
|
||||
row._error = true
|
||||
row._warned = row._warned || {}
|
||||
row._warned[field] = true
|
||||
return false
|
||||
}
|
||||
row._error = false
|
||||
row._warned = row._warned || {}
|
||||
row._warned[field] = false
|
||||
return true
|
||||
}
|
||||
|
||||
function onNumberInput(row, field) {
|
||||
row._warned = row._warned || {}
|
||||
const valid = isTailDigitsValid(row[field])
|
||||
if (!valid && !row._warned[field]) {
|
||||
alertWarn('最大位数为12位,且必须以数字结尾')
|
||||
row._warned[field] = true
|
||||
}
|
||||
if (valid) {
|
||||
row._warned[field] = false
|
||||
}
|
||||
}
|
||||
|
||||
function validateRow(row, rowIndex) {
|
||||
row._error = false
|
||||
if (!lengthWithinLimit(row.startNo) || !lengthWithinLimit(row.endNo) || !lengthWithinLimit(row.usedNo)) {
|
||||
const idxInTable = typeof rowIndex === 'number' ? rowIndex : tableData.value.indexOf(row)
|
||||
const lineNo = idxInTable >= 0 ? idxInTable + 1 : (editIndex.value >= 0 ? editIndex.value + 1 : undefined)
|
||||
const msg = lineNo ? `第【${lineNo}】行数据中,最大位数为12位,且必须以数字结尾!` : '最大位数为12位,且必须以数字结尾'
|
||||
alertWarn(msg)
|
||||
row._error = true
|
||||
return false
|
||||
}
|
||||
if ((row.startNo?.length || 0) !== (row.endNo?.length || 0)) {
|
||||
const idxInTable = typeof rowIndex === 'number' ? rowIndex : tableData.value.indexOf(row)
|
||||
const lineNo = idxInTable >= 0 ? idxInTable + 1 : (editIndex.value >= 0 ? editIndex.value + 1 : undefined)
|
||||
const msg = lineNo ? `第【${lineNo}】行数据中,起始号码与终止号码长度必须一致,请修改!` : '起始号码与终止号码长度必须一致'
|
||||
alertWarn(msg)
|
||||
row._error = true
|
||||
return false
|
||||
}
|
||||
const p1 = extractPrefix(row.startNo)
|
||||
const p2 = extractPrefix(row.endNo)
|
||||
const p3 = extractPrefix(row.usedNo)
|
||||
if (!(p1 === p2 && p2 === p3)) {
|
||||
const idxInTable = typeof rowIndex === 'number' ? rowIndex : tableData.value.indexOf(row)
|
||||
const lineNo = idxInTable >= 0 ? idxInTable + 1 : (editIndex.value >= 0 ? editIndex.value + 1 : undefined)
|
||||
const msg = lineNo ? `第【${lineNo}】行数据中,门诊号码的字母前缀必须相同,请修改!` : '行数据中,门诊号码的字母前缀必须相同,请修改!'
|
||||
alertWarn(msg)
|
||||
row._error = true
|
||||
return false
|
||||
}
|
||||
const sNum = extractTailNumber(row.startNo)
|
||||
const eNum = extractTailNumber(row.endNo)
|
||||
if (Number.isNaN(sNum) || Number.isNaN(eNum) || sNum > eNum) {
|
||||
const idxInTable = typeof rowIndex === 'number' ? rowIndex : tableData.value.indexOf(row)
|
||||
const lineNo = idxInTable >= 0 ? idxInTable + 1 : (editIndex.value >= 0 ? editIndex.value + 1 : undefined)
|
||||
const msg = lineNo ? `第【${lineNo}】行数据中,起始/终止号码不合法` : '起始/终止号码不合法'
|
||||
alertWarn(msg)
|
||||
row._error = true
|
||||
return false
|
||||
}
|
||||
// 放宽:不再强制“使用号码”必须处于起始与终止范围内
|
||||
const prefix = p1
|
||||
for (let i = 0; i < tableData.value.length; i++) {
|
||||
const other = tableData.value[i]
|
||||
// 跳过自身:当从弹窗校验时 row 为临时对象,需用下标判断
|
||||
if ((typeof rowIndex === 'number' && i === rowIndex) || other === row || !other.startNo || !other.endNo) continue
|
||||
if (extractPrefix(other.startNo) !== prefix) continue
|
||||
const os = extractTailNumber(other.startNo)
|
||||
const oe = extractTailNumber(other.endNo)
|
||||
if (!Number.isNaN(os) && !Number.isNaN(oe)) {
|
||||
if (rangesOverlap(sNum, eNum, os, oe)) {
|
||||
const idxInTable = typeof rowIndex === 'number' ? rowIndex : tableData.value.indexOf(row)
|
||||
const lineNo = idxInTable >= 0 ? idxInTable + 1 : (editIndex.value >= 0 ? editIndex.value + 1 : undefined)
|
||||
const msg = lineNo ? `第【${lineNo}】行数据中,门诊号码和【${i + 1}】行的门诊号码有冲突,请修改!` : '门诊号码设置重复!'
|
||||
alertWarn(msg)
|
||||
row._error = true
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function onSave(row) {
|
||||
const rows = row ? [row] : tableData.value.filter(r => ids.value.includes(r.id) || r._dirty || r._editing)
|
||||
if (!rows.length) return
|
||||
for (const r of rows) {
|
||||
const idx = tableData.value.indexOf(r)
|
||||
if (!validateRow(r, idx)) return
|
||||
}
|
||||
|
||||
// 准备保存的数据
|
||||
const saveData = rows.map((r) => ({
|
||||
id: r.id,
|
||||
operatorId: r.operatorId,
|
||||
operatorName: r.operatorName,
|
||||
staffNo: r.staffNo,
|
||||
receiveDate: r.receiveDate,
|
||||
startNo: r.startNo,
|
||||
endNo: r.endNo,
|
||||
usedNo: r.usedNo,
|
||||
}))
|
||||
|
||||
const ok = lcUpsertMany(saveData)
|
||||
if (!ok) {
|
||||
// 记录失败的操作日志
|
||||
for (const record of saveData) {
|
||||
if (record.id) {
|
||||
logUpdate(record, false, '门诊号码设置重复', getUserInfo())
|
||||
} else {
|
||||
logCreate(record, false, '门诊号码设置重复', getUserInfo())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 记录成功的操作日志
|
||||
for (const record of saveData) {
|
||||
if (record.id) {
|
||||
logUpdate(record, true, null, getUserInfo())
|
||||
} else {
|
||||
logCreate(record, true, null, getUserInfo())
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy.$modal?.alertSuccess) {
|
||||
proxy.$modal.alertSuccess('保存成功!')
|
||||
} else {
|
||||
proxy.$message.success('保存成功')
|
||||
}
|
||||
getList()
|
||||
}
|
||||
|
||||
function onDelete() {
|
||||
const rows = tableData.value.filter((r) => ids.value.includes(r.id))
|
||||
if (!rows.length) return
|
||||
|
||||
// 双重校验(归属权+使用状态)
|
||||
for (const r of rows) {
|
||||
const canDeleteSelf = String(r.operatorId) === String(userStore.id)
|
||||
const neverUsed = r.usedNo === r.startNo
|
||||
if (!canDeleteSelf) {
|
||||
// 权限不足提示
|
||||
alertWarn('只能删除自己维护的门诊号码段')
|
||||
logDelete(rows, false, '只能删除自己维护的门诊号码段', getUserInfo())
|
||||
return
|
||||
}
|
||||
if (!neverUsed) {
|
||||
// 已使用提示
|
||||
alertWarn('已有门诊号码段已有使用的门诊号码,请核对!')
|
||||
logDelete(rows, false, '已有门诊号码段已有使用的门诊号码', getUserInfo())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const doRealDelete = () => {
|
||||
lcDeleteByIds(rows.map((r) => r.id))
|
||||
|
||||
//记录成功的删除操作日志
|
||||
logDelete(rows, true, null, getUserInfo())
|
||||
|
||||
if (proxy.$modal?.alertSuccess) {
|
||||
proxy.$modal.alertSuccess('删除成功')
|
||||
} else {
|
||||
proxy.$message.success('删除成功')
|
||||
}
|
||||
getList()
|
||||
}
|
||||
|
||||
if (proxy.$modal?.confirm) {
|
||||
proxy.$modal.confirm('是否确认删除选中数据项?').then(doRealDelete).catch(() => {
|
||||
// 用户取消删除,不记录日志
|
||||
})
|
||||
} else {
|
||||
doRealDelete()
|
||||
}
|
||||
}
|
||||
|
||||
function getList() {
|
||||
loading.value = true
|
||||
queryParams.value.onlySelf = !viewAll.value
|
||||
|
||||
// 先尝试调用后端API
|
||||
listOutpatientNo(queryParams.value).then((res) => {
|
||||
if (res.code === 200) {
|
||||
tableData.value = (res.data?.records || res.data || []).map((it) => ({
|
||||
...it,
|
||||
_editing: false,
|
||||
_error: false,
|
||||
_dirty: false,
|
||||
}))
|
||||
total.value = res.data?.total || res.data?.length || 0
|
||||
|
||||
// 记录查询操作日志
|
||||
logQuery(total.value, getUserInfo())
|
||||
} else {
|
||||
// API返回错误,回退到localStorage
|
||||
console.warn('后端API返回错误,使用localStorage数据')
|
||||
loadFromLocalStorage()
|
||||
}
|
||||
loading.value = false
|
||||
}).catch((error) => {
|
||||
// API调用失败(如404),回退到localStorage
|
||||
console.warn('后端API调用失败,使用localStorage数据:', error)
|
||||
loadFromLocalStorage()
|
||||
})
|
||||
}
|
||||
|
||||
// 从localStorage加载数据
|
||||
function loadFromLocalStorage() {
|
||||
const res = lcList({ ...queryParams.value })
|
||||
tableData.value = res.records.map((it) => ({
|
||||
...it,
|
||||
_editing: false,
|
||||
_error: false,
|
||||
_dirty: false,
|
||||
}))
|
||||
total.value = res.total
|
||||
|
||||
// 记录查询操作日志
|
||||
logQuery(total.value, getUserInfo())
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 纯前端本地持久化方法(localStorage)
|
||||
const STORAGE_KEY = 'ohis_outpatient_no_segments'
|
||||
|
||||
function lcReadAll() {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY)
|
||||
const arr = raw ? JSON.parse(raw) : []
|
||||
return Array.isArray(arr) ? arr : []
|
||||
} catch (e) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
function lcWriteAll(list) {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(list || []))
|
||||
}
|
||||
|
||||
function lcList({ pageNo = 1, pageSize = 10, onlySelf = true }) {
|
||||
const all = lcReadAll()
|
||||
const filtered = onlySelf ? all.filter((x) => String(x.operatorId) === String(userStore.id)) : all
|
||||
const start = (pageNo - 1) * pageSize
|
||||
const end = start + pageSize
|
||||
return { records: filtered.slice(start, end), total: filtered.length, all }
|
||||
}
|
||||
|
||||
function checkOverlapAll(row, all) {
|
||||
const prefix = extractPrefix(row.startNo)
|
||||
const sNum = extractTailNumber(row.startNo)
|
||||
const eNum = extractTailNumber(row.endNo)
|
||||
for (const it of all) {
|
||||
if (row.id && it.id === row.id) continue
|
||||
if (!it.startNo || !it.endNo) continue
|
||||
if (extractPrefix(it.startNo) !== prefix) continue
|
||||
const os = extractTailNumber(it.startNo)
|
||||
const oe = extractTailNumber(it.endNo)
|
||||
if (!Number.isNaN(os) && !Number.isNaN(oe)) {
|
||||
if (rangesOverlap(sNum, eNum, os, oe)) return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function lcUpsertMany(rows) {
|
||||
const all = lcReadAll()
|
||||
for (const r of rows) {
|
||||
if (checkOverlapAll(r, all)) {
|
||||
alertWarn('门诊号码设置重复!')
|
||||
return false
|
||||
}
|
||||
if (!r.id) {
|
||||
r.id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
|
||||
}
|
||||
const idx = all.findIndex((x) => x.id === r.id)
|
||||
if (idx >= 0) all[idx] = { ...all[idx], ...r }
|
||||
else all.push({ ...r })
|
||||
}
|
||||
lcWriteAll(all)
|
||||
return true
|
||||
}
|
||||
|
||||
function lcDeleteByIds(idList) {
|
||||
const all = lcReadAll()
|
||||
const remain = all.filter((x) => !idList.includes(x.id))
|
||||
lcWriteAll(remain)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*Windows XP风格布局 - 全屏显示 */
|
||||
|
||||
/* 外层容器 - 全屏显示 */
|
||||
.outpatient-no-management-wrapper {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
padding: 0;
|
||||
background-color: #f0f0f0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 主容器 - 全屏宽度和高度 */
|
||||
.outpatient-no-management {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #D4D0C8;
|
||||
border: 1px solid #000000;
|
||||
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 标题栏(32px高,背景色#D4D0C8) */
|
||||
.title-bar {
|
||||
height: 32px;
|
||||
background: linear-gradient(to bottom, #0055E5 0%, #0F3D8C 100%);
|
||||
border-bottom: 1px solid #000000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
/* 标题文本(14px/700,左对齐) */
|
||||
.title-text {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* 功能按钮区(40px高) */
|
||||
.button-bar {
|
||||
height: 40px;
|
||||
background-color: #D4D0C8;
|
||||
border-bottom: 1px solid #808080;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.button-bar .el-row {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 按钮样式(90x32px,1px边框,圆角0,背景色#EFEFEF) */
|
||||
.button-bar :deep(.el-button) {
|
||||
width: 90px;
|
||||
height: 32px;
|
||||
border-radius: 0;
|
||||
border: 1px solid #808080;
|
||||
font-size: 13px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 新设按钮 - 主要操作 */
|
||||
.button-bar :deep(.el-button--primary) {
|
||||
background: linear-gradient(to bottom, #FFFFFF 0%, #EFEFEF 50%, #DFDFDF 100%);
|
||||
color: #000000;
|
||||
border-top: 1px solid #FFFFFF;
|
||||
border-left: 1px solid #FFFFFF;
|
||||
border-right: 1px solid #808080;
|
||||
border-bottom: 1px solid #808080;
|
||||
}
|
||||
|
||||
.button-bar :deep(.el-button--primary:hover) {
|
||||
background: linear-gradient(to bottom, #FFFEF8 0%, #F5F4EF 50%, #E5E4DF 100%);
|
||||
}
|
||||
|
||||
/* 删除按钮 */
|
||||
.button-bar :deep(.el-button--danger) {
|
||||
background: linear-gradient(to bottom, #FFFFFF 0%, #EFEFEF 50%, #DFDFDF 100%);
|
||||
color: #000000;
|
||||
border-top: 1px solid #FFFFFF;
|
||||
border-left: 1px solid #FFFFFF;
|
||||
border-right: 1px solid #808080;
|
||||
border-bottom: 1px solid #808080;
|
||||
}
|
||||
|
||||
/* 保存按钮 */
|
||||
.button-bar :deep(.el-button--success) {
|
||||
background: linear-gradient(to bottom, #FFFFFF 0%, #EFEFEF 50%, #DFDFDF 100%);
|
||||
color: #000000;
|
||||
border-top: 1px solid #FFFFFF;
|
||||
border-left: 1px solid #FFFFFF;
|
||||
border-right: 1px solid #808080;
|
||||
border-bottom: 1px solid #808080;
|
||||
}
|
||||
|
||||
/* 关闭按钮(红色背景,白色文字) */
|
||||
.button-bar :deep(.el-button--warning) {
|
||||
background: linear-gradient(to bottom, #FF6B6B 0%, #EE5A5A 50%, #DD4949 100%);
|
||||
color: #FFFFFF;
|
||||
font-weight: 600;
|
||||
border-top: 1px solid #FF9999;
|
||||
border-left: 1px solid #FF9999;
|
||||
border-right: 1px solid #AA3333;
|
||||
border-bottom: 1px solid #AA3333;
|
||||
}
|
||||
|
||||
.button-bar :deep(.el-button--warning:hover) {
|
||||
background: linear-gradient(to bottom, #FF7B7B 0%, #FE6A6A 50%, #ED5959 100%);
|
||||
}
|
||||
|
||||
/* 按钮禁用状态 */
|
||||
.button-bar :deep(.el-button:disabled) {
|
||||
background: #D4D0C8;
|
||||
color: #808080;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/*表格内容区(自适应剩余高度) */
|
||||
.table-content {
|
||||
flex: 1;
|
||||
background-color: #FFFFFF;
|
||||
padding: 8px;
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 表格样式(1px实线边框#CCCCCC,表头背景#F0F0F0) */
|
||||
.table-content :deep(.el-table) {
|
||||
border: 1px solid #CCCCCC;
|
||||
font-size: 13px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.table-content :deep(.el-table th) {
|
||||
background: linear-gradient(to bottom, #FFFFFF 0%, #F0F0F0 100%);
|
||||
border: 1px solid #CCCCCC;
|
||||
color: #000000;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
padding: 8px 4px;
|
||||
}
|
||||
|
||||
.table-content :deep(.el-table td) {
|
||||
border: 1px solid #CCCCCC;
|
||||
padding: 6px 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.table-content :deep(.el-table__body tr:hover > td) {
|
||||
background-color: #E5F3FF !important;
|
||||
}
|
||||
|
||||
/* 错误行样式 */
|
||||
:deep(.error-row) {
|
||||
--el-table-tr-bg-color: #fff7e6;
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
.table-content :deep(.pagination-container) {
|
||||
margin-top: 10px;
|
||||
padding: 10px 0;
|
||||
border-top: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
/* 输入框样式 */
|
||||
.table-content :deep(.el-input__inner) {
|
||||
border: 1px solid #7FB4FF;
|
||||
border-radius: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.table-content :deep(.el-input__inner:focus) {
|
||||
border: 2px solid #0055E5;
|
||||
}
|
||||
|
||||
/* 日期选择器样式 */
|
||||
.table-content :deep(.el-date-editor) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 开关样式 */
|
||||
.button-bar :deep(.el-switch) {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
/* 滚动条样式(Windows XP风格) */
|
||||
.table-content::-webkit-scrollbar {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.table-content::-webkit-scrollbar-track {
|
||||
background-color: #D4D0C8;
|
||||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.table-content::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(to bottom, #FFFFFF 0%, #EFEFEF 50%, #DFDFDF 100%);
|
||||
border: 1px solid #808080;
|
||||
}
|
||||
|
||||
.table-content::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(to bottom, #FFFEF8 0%, #F5F4EF 50%, #E5E4DF 100%);
|
||||
}
|
||||
|
||||
/* 编辑弹窗样式 */
|
||||
:deep(.el-dialog) {
|
||||
border-radius: 0;
|
||||
border: 2px solid #0055E5;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__header) {
|
||||
background: linear-gradient(to bottom, #0055E5 0%, #0F3D8C 100%);
|
||||
padding: 10px 15px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__title) {
|
||||
color: #FFFFFF;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__close) {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* 表格容器样式调整 */
|
||||
.table-content :deep(.el-table__body-wrapper) {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
:class="{ 'error-border': scope.row.error }"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in distribution_category_code"
|
||||
v-for="dict in med_category_code"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
@@ -184,7 +184,7 @@ import {
|
||||
deletePharmacyDepartment,
|
||||
} from './components/pharmacyDepartment';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { distribution_category_code } = proxy.useDict('distribution_category_code');
|
||||
const { med_category_code } = proxy.useDict('med_category_code');
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
const diagnosisTreatmentList = ref([]);
|
||||
|
||||
@@ -36,8 +36,12 @@ export function updateWarehouse(data) {
|
||||
// 删除
|
||||
export function deleteWarehouse(data) {
|
||||
return request({
|
||||
url: '/base-data-manage/location/location?locationId=' + data.locationId,
|
||||
url: '/base-data-manage/location/location',
|
||||
method: 'delete',
|
||||
params: {
|
||||
locationId: data.locationId,
|
||||
busNo: data.busNo
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true);
|
||||
const organization = ref([]);
|
||||
const queryParams = ref({
|
||||
locationFormList: [11, 16],
|
||||
locationFormList: [11, 16, 17],
|
||||
});
|
||||
const open = ref(false);
|
||||
const form = ref({
|
||||
@@ -173,7 +173,7 @@ const { warehous_type } = proxy.useDict('warehous_type');
|
||||
const rules = ref({
|
||||
busNo: [{ required: false, message: '请输入科室编号', trigger: 'change' }],
|
||||
name: [
|
||||
{ required: true, message: '请输入仓库名称', trigger: 'change' },
|
||||
{ required: true, message: '请输入', trigger: 'change' },
|
||||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'change' },
|
||||
],
|
||||
formEnum: [{ required: true, message: '请选择仓库类型', trigger: 'change' }],
|
||||
@@ -211,7 +211,7 @@ function resetQuery() {
|
||||
}
|
||||
|
||||
function handleEnable(row) {
|
||||
enableLocation([row.id]).then((res) => {
|
||||
enableLocation({ locationId: row.id, busNo: row.busNo }).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('启用成功');
|
||||
handleQuery();
|
||||
@@ -220,7 +220,7 @@ function handleEnable(row) {
|
||||
}
|
||||
|
||||
function handleUnable(row) {
|
||||
unableLocation([row.id]).then((res) => {
|
||||
unableLocation({ locationId: row.id, busNo: row.busNo }).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('停用成功');
|
||||
handleQuery();
|
||||
@@ -243,15 +243,14 @@ function getPageList() {
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
title.value = '添加药库药房';
|
||||
title.value = '添加库房/药房/耗材库';
|
||||
open.value = true;
|
||||
editShow.value = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
function handelEdit(row) {
|
||||
console.log(warehous_type);
|
||||
title.value = '编辑药库药房';
|
||||
title.value = '编辑库房/药房/耗材库';
|
||||
open.value = true;
|
||||
editShow.value = true;
|
||||
setTimeout(() => {
|
||||
@@ -281,7 +280,6 @@ function submitForm() {
|
||||
getPageList();
|
||||
});
|
||||
} else {
|
||||
alert('456789');
|
||||
updateWarehouse(form.value).then((res) => {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
open.value = false;
|
||||
@@ -294,11 +292,29 @@ function submitForm() {
|
||||
|
||||
// 删除
|
||||
function handelDelete(data) {
|
||||
loading.value = true;
|
||||
deleteWarehouse({ locationId: data.id }).then((res) => {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
loading.value = false;
|
||||
getPageList();
|
||||
proxy.$modal.confirm('是否确认删除该仓库位置?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
loading.value = true;
|
||||
deleteWarehouse({ locationId: data.id, busNo: data.busNo }).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
getPageList();
|
||||
} else {
|
||||
// 检查错误信息是否与药品数据关联有关
|
||||
if (res.msg && res.msg.includes('药品')) {
|
||||
proxy.$modal.msgError('该仓库名称已有药品信息请核对确认');
|
||||
} else {
|
||||
proxy.$modal.msgError('删除失败:' + (res.msg || '未知错误'));
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
proxy.$modal.msgError('删除失败');
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
// // 停用
|
||||
|
||||
@@ -10,6 +10,16 @@ export function getRegistrationfeeList(query) {
|
||||
})
|
||||
}
|
||||
|
||||
// 根据位置id筛选医生
|
||||
export function getPractitionerMetadata(query) {
|
||||
return request({
|
||||
url: '/charge-manage/register/practitioner-metadata',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 查询服务管理详细
|
||||
export function getRegistrationfeeOne(id) {
|
||||
return request({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user