Compare commits
174 Commits
wangjunpin
...
18c96e006f
| Author | SHA1 | Date | |
|---|---|---|---|
| 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⽉,新致开源品牌更新为天天开源,我们始终秉持开源、专业、协作的理念,致⼒于为医疗、教育、中⼩企业等⾏业提供优质的开源解决⽅案。
|
天天开源的前⾝是新致开源,最早于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
|
||||||
|
|
||||||
## 💾【部署包下载】
|
## 💾【部署包下载】
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ public final class AgeCalculatorUtil {
|
|||||||
* 当前年龄取得(床位列表表示年龄用)
|
* 当前年龄取得(床位列表表示年龄用)
|
||||||
*/
|
*/
|
||||||
public static String getAge(Date date) {
|
public static String getAge(Date date) {
|
||||||
|
// 添加空值检查
|
||||||
|
if (date == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
// 将 Date 转换为 LocalDateTime
|
// 将 Date 转换为 LocalDateTime
|
||||||
LocalDateTime dateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
LocalDateTime dateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|||||||
@@ -22,10 +22,11 @@ import com.core.common.utils.StringUtils;
|
|||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class FilterConfig {
|
public class FilterConfig {
|
||||||
@Value("${xss.excludes}")
|
// 添加默认值,避免配置不存在时启动失败
|
||||||
|
@Value("${xss.excludes:/system/notice}")
|
||||||
private String excludes;
|
private String excludes;
|
||||||
|
|
||||||
@Value("${xss.urlPatterns}")
|
@Value("${xss.urlPatterns:/system/*,/monitor/*,/tool/*}")
|
||||||
private String urlPatterns;
|
private String urlPatterns;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public class GenController extends BaseController {
|
|||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo genList(GenTable genTable) {
|
public TableDataInfo genList(GenTable genTable) {
|
||||||
startPage();
|
startPage();
|
||||||
|
|
||||||
List<GenTable> list = genTableService.selectGenTableList(genTable);
|
List<GenTable> list = genTableService.selectGenTableList(genTable);
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,71 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 患者换卡服务实现类
|
||||||
|
*
|
||||||
|
* @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());
|
||||||
|
PatientIdentifier existingIdentifier = patientIdentifierService.getOne(queryWrapper);
|
||||||
|
if (existingIdentifier != null) {
|
||||||
|
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,9 +91,9 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Page<PatientMetadata> getPatientMetadataBySearchKey(String searchKey, Integer pageNo, Integer pageSize) {
|
public Page<PatientMetadata> getPatientMetadataBySearchKey(String searchKey, Integer pageNo, Integer pageSize) {
|
||||||
// 构建查询条件
|
// 构建查询条件,添加phone字段支持手机号搜索
|
||||||
QueryWrapper<Patient> queryWrapper = HisQueryUtils.buildQueryWrapper(null, searchKey,
|
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");
|
queryWrapper.orderByDesc("update_time");
|
||||||
// 通过证件号匹配 patient
|
// 通过证件号匹配 patient
|
||||||
@@ -267,6 +267,23 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
|||||||
new HashSet<>(Arrays.asList("patient_name", "organization_name", "practitioner_name", "healthcare_name")),
|
new HashSet<>(Arrays.asList("patient_name", "organization_name", "practitioner_name", "healthcare_name")),
|
||||||
request);
|
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(
|
IPage<CurrentDayEncounterDto> currentDayEncounter = outpatientRegistrationAppMapper.getCurrentDayEncounter(
|
||||||
new Page<>(pageNo, pageSize), EncounterClass.AMB.getValue(), ParticipantType.ADMITTER.getCode(),
|
new Page<>(pageNo, pageSize), EncounterClass.AMB.getValue(), ParticipantType.ADMITTER.getCode(),
|
||||||
queryWrapper, ChargeItemContext.REGISTER.getValue(), PaymentStatus.SUCCESS.getValue());
|
queryWrapper, ChargeItemContext.REGISTER.getValue(), PaymentStatus.SUCCESS.getValue());
|
||||||
|
|||||||
@@ -131,4 +131,40 @@ public class CurrentDayEncounterDto {
|
|||||||
*/
|
*/
|
||||||
private Date birthDate;
|
private Date birthDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退号日期/时间
|
||||||
|
*/
|
||||||
|
private Date returnDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退号原因
|
||||||
|
*/
|
||||||
|
private String returnReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退号操作人
|
||||||
|
*/
|
||||||
|
private String operatorName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退号操作工号
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合同编码(费用性质代码)
|
||||||
|
*/
|
||||||
|
private String contractNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款方式(多个支付方式用逗号分隔)
|
||||||
|
*/
|
||||||
|
private String refundMethod;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,4 +82,10 @@ public class RefundItemDto {
|
|||||||
/** 项目名 */
|
/** 项目名 */
|
||||||
private String itemName;
|
private String itemName;
|
||||||
|
|
||||||
|
/** 费用支付方式编码 */
|
||||||
|
private String medfeePaymtdCode;
|
||||||
|
|
||||||
|
/** 费用类型 */
|
||||||
|
private String feeType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public interface ICommonService {
|
|||||||
/**
|
/**
|
||||||
* 药房列表(库房用)
|
* 药房列表(库房用)
|
||||||
*
|
*
|
||||||
* @return 药房列表
|
* @return 药房列表1
|
||||||
*/
|
*/
|
||||||
List<LocationDto> getInventoryPharmacyList();
|
List<LocationDto> getInventoryPharmacyList();
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,14 @@ public interface IDoctorStationMainAppService {
|
|||||||
*/
|
*/
|
||||||
R<?> completeEncounter(Long encounterId);
|
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);
|
adviceUtils.subtractInventory(adviceInventoryList, adviceDraftInventoryList);
|
||||||
// 查询取药科室配置
|
// 查询取药科室配置
|
||||||
List<AdviceInventoryDto> medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId);
|
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
|
List<AdvicePriceDto> childCharge = doctorStationAdviceAppMapper
|
||||||
.getChildCharge(ConditionCode.LOT_NUMBER_COST.getCode(), chargeItemDefinitionIdList);
|
.getChildCharge(ConditionCode.LOT_NUMBER_COST.getCode(), chargeItemDefinitionIdList);
|
||||||
@@ -163,6 +174,19 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
.filter(e -> baseDto.getAdviceDefinitionId().equals(e.getItemId())
|
.filter(e -> baseDto.getAdviceDefinitionId().equals(e.getItemId())
|
||||||
&& baseDto.getAdviceTableName().equals(e.getItemTable()))
|
&& baseDto.getAdviceTableName().equals(e.getItemTable()))
|
||||||
.collect(Collectors.toList());
|
.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);
|
baseDto.setInventoryList(inventoryList);
|
||||||
// 设置默认产品批号
|
// 设置默认产品批号
|
||||||
@@ -174,18 +198,15 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
baseDto.setDefaultLotNumber(hasInventoryList.get(0).getLotNumber());
|
baseDto.setDefaultLotNumber(hasInventoryList.get(0).getLotNumber());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!inventoryList.isEmpty() && !medLocationConfig.isEmpty()) {
|
if (!inventoryList.isEmpty() && !allowedLocByCategory.isEmpty()) {
|
||||||
// 第一步:在medLocationConfig中匹配categoryCode
|
Set<Long> allowedLoc =
|
||||||
AdviceInventoryDto result1 = medLocationConfig.stream()
|
allowedLocByCategory.get(String.valueOf(baseDto.getCategoryCode()));
|
||||||
.filter(dto -> baseDto.getCategoryCode().equals(dto.getCategoryCode())).findFirst()
|
if (allowedLoc != null && !allowedLoc.isEmpty()) {
|
||||||
.orElse(null);
|
AdviceInventoryDto hit = inventoryList.stream()
|
||||||
if (result1 != null) {
|
.filter(inv -> allowedLoc.contains(inv.getLocationId()))
|
||||||
// 第二步:在inventoryList中匹配locationId
|
.findFirst().orElse(null);
|
||||||
AdviceInventoryDto result2 = inventoryList.stream()
|
if (hit != null && hit.getLotNumber() != null) {
|
||||||
.filter(dto -> result1.getLocationId().equals(dto.getLocationId())).findFirst()
|
baseDto.setDefaultLotNumber(hit.getLotNumber());
|
||||||
.orElse(null);
|
|
||||||
if (result2 != null && result2.getLotNumber() != null) {
|
|
||||||
baseDto.setDefaultLotNumber(result2.getLotNumber());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
package com.openhis.web.doctorstation.appservice.impl;
|
package com.openhis.web.doctorstation.appservice.impl;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.openhis.web.doctorstation.appservice.*;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
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.enums.*;
|
||||||
import com.openhis.common.utils.EnumUtils;
|
import com.openhis.common.utils.EnumUtils;
|
||||||
import com.openhis.common.utils.HisQueryUtils;
|
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.PatientInfoDto;
|
||||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
||||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
||||||
@@ -46,6 +44,17 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
@Resource
|
@Resource
|
||||||
IEncounterParticipantService iEncounterParticipantService;
|
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();
|
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);
|
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()) {
|
if (receiptDetailList.isEmpty()) {
|
||||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
|
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);
|
return R.ok(receiptDetailList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,10 +128,11 @@ public class PatientInformationServiceImpl implements IPatientInformationService
|
|||||||
public IPage<PatientInformationDto> getPatientInfo(PatientInfoSearchParam patientInfoSearchParam, String searchKey,
|
public IPage<PatientInformationDto> getPatientInfo(PatientInfoSearchParam patientInfoSearchParam, String searchKey,
|
||||||
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件 - 添加phone字段到搜索条件中
|
||||||
QueryWrapper<PatientInformationDto> queryWrapper = HisQueryUtils.buildQueryWrapper(
|
QueryWrapper<PatientInformationDto> queryWrapper = HisQueryUtils.buildQueryWrapper(
|
||||||
patientInfoSearchParam, searchKey, new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name,
|
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);
|
request);
|
||||||
|
|
||||||
IPage<PatientInformationDto> patientInformationPage =
|
IPage<PatientInformationDto> patientInformationPage =
|
||||||
|
|||||||
@@ -597,7 +597,7 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
|
|
||||||
// 全退
|
// 全退
|
||||||
String ybSettleIds = paymentReconciliation.getYbSettleIds();
|
String ybSettleIds = paymentReconciliation.getYbSettleIds();
|
||||||
PaymentReconciliation unPaymentReconciliation = normalUnCharge(paymentReconciliation, PaymentRecDetails, null);
|
PaymentReconciliation unPaymentReconciliation = normalUnCharge(paymentReconciliation, PaymentRecDetails, null, null);
|
||||||
if (!StringUtils.isEmpty(ybSettleIds)) {
|
if (!StringUtils.isEmpty(ybSettleIds)) {
|
||||||
// 医保结算信息
|
// 医保结算信息
|
||||||
List<String> ybSettleIdList = Arrays.asList(ybSettleIds.split(","));
|
List<String> ybSettleIdList = Arrays.asList(ybSettleIds.split(","));
|
||||||
@@ -734,7 +734,7 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PaymentReconciliation unPaymentReconciliation =
|
PaymentReconciliation unPaymentReconciliation =
|
||||||
normalUnCharge(paymentReconciliation, paymentRecDetails, cancelPaymentDto.getSetlId());
|
normalUnCharge(paymentReconciliation, paymentRecDetails, cancelPaymentDto.getSetlId(), cancelPaymentDto.getReason());
|
||||||
|
|
||||||
return R.ok(unPaymentReconciliation);
|
return R.ok(unPaymentReconciliation);
|
||||||
}
|
}
|
||||||
@@ -792,10 +792,12 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
*
|
*
|
||||||
* @param paymentReconciliation 付款实体
|
* @param paymentReconciliation 付款实体
|
||||||
* @param paymentRecDetails 付款详情
|
* @param paymentRecDetails 付款详情
|
||||||
|
* @param setlIds 医保结算ID
|
||||||
|
* @param reason 退号/退费原因
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
private PaymentReconciliation normalUnCharge(PaymentReconciliation paymentReconciliation,
|
private PaymentReconciliation normalUnCharge(PaymentReconciliation paymentReconciliation,
|
||||||
List<PaymentRecDetail> paymentRecDetails, String setlIds) {
|
List<PaymentRecDetail> paymentRecDetails, String setlIds, String reason) {
|
||||||
|
|
||||||
// 获取原ID
|
// 获取原ID
|
||||||
Long id = paymentReconciliation.getId();
|
Long id = paymentReconciliation.getId();
|
||||||
@@ -805,7 +807,8 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
.setEntererId(SecurityUtils.getLoginUser().getPractitionerId()).setBillDate(new Date())
|
.setEntererId(SecurityUtils.getLoginUser().getPractitionerId()).setBillDate(new Date())
|
||||||
.setTenderedAmount(paymentReconciliation.getTenderedAmount().negate())
|
.setTenderedAmount(paymentReconciliation.getTenderedAmount().negate())
|
||||||
.setReturnedAmount(paymentReconciliation.getReturnedAmount().negate())
|
.setReturnedAmount(paymentReconciliation.getReturnedAmount().negate())
|
||||||
.setDisplayAmount(paymentReconciliation.getDisplayAmount().negate());
|
.setDisplayAmount(paymentReconciliation.getDisplayAmount().negate())
|
||||||
|
.setRefundReason(reason); // 保存退号/退费原因
|
||||||
if (setlIds != null) {
|
if (setlIds != null) {
|
||||||
paymentReconciliation.setYbSettleIds(setlIds);
|
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();
|
String ybSettleIds = paymentReconciliation.getYbSettleIds();
|
||||||
|
|||||||
@@ -172,13 +172,13 @@ public class PaymentReconciliationController {
|
|||||||
/**
|
/**
|
||||||
* 挂号收费(挂号收费先医保挂号,收费成功后再本系统挂号)
|
* 挂号收费(挂号收费先医保挂号,收费成功后再本系统挂号)
|
||||||
*
|
*
|
||||||
* @param outpatientRegistrationAddParam 挂号信息
|
* @param outpatientRegistrationSettleParam 挂号信息
|
||||||
* @return 操做结果
|
* @return 操做结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/reg-pay")
|
@PostMapping("/reg-pay")
|
||||||
public R<?> regPay(@Valid @RequestBody OutpatientRegistrationSettleParam outpatientRegistrationAddParam) {
|
public R<?> regPay(@Valid @RequestBody OutpatientRegistrationSettleParam outpatientRegistrationSettleParam) {
|
||||||
R<?> result = paymentReconciliationService.regPay(outpatientRegistrationAddParam,
|
R<?> result = paymentReconciliationService.regPay(outpatientRegistrationSettleParam,
|
||||||
outpatientRegistrationAddParam.getChrgBchno(), outpatientRegistrationAddParam.getPaymentDetails());
|
outpatientRegistrationSettleParam.getChrgBchno(), outpatientRegistrationSettleParam.getPaymentDetails());
|
||||||
// 付款成功后,开具发票
|
// 付款成功后,开具发票
|
||||||
if (result.getCode() == 200) {
|
if (result.getCode() == 200) {
|
||||||
PaymentReconciliation paymentRecon = null;
|
PaymentReconciliation paymentRecon = null;
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
|||||||
public R<?> getPage(InventoryProductReportSearchParam inventoryProductReportSearchParam, Integer pageNo,
|
public R<?> getPage(InventoryProductReportSearchParam inventoryProductReportSearchParam, Integer pageNo,
|
||||||
Integer pageSize, String searchKey, HttpServletRequest request) {
|
Integer pageSize, String searchKey, HttpServletRequest request) {
|
||||||
|
|
||||||
|
// 数据初始化,不使用eq条件拼接
|
||||||
|
// 库存范围
|
||||||
|
Integer inventoryScope = inventoryProductReportSearchParam.getInventoryScope();
|
||||||
|
inventoryProductReportSearchParam.setInventoryScope(null);
|
||||||
|
|
||||||
// 设置模糊查询的字段名
|
// 设置模糊查询的字段名
|
||||||
HashSet<String> searchFields = new HashSet<>();
|
HashSet<String> searchFields = new HashSet<>();
|
||||||
searchFields.add(CommonConstants.FieldName.BusNo);
|
searchFields.add(CommonConstants.FieldName.BusNo);
|
||||||
@@ -78,7 +83,8 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
|||||||
|
|
||||||
// 查询库存商品明细分页列表
|
// 查询库存商品明细分页列表
|
||||||
Page<InventoryProductReportPageDto> productReportPage = inventoryProductReportMapper.selectProductReportPage(
|
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 -> {
|
productReportPage.getRecords().forEach(e -> {
|
||||||
// 药品类型
|
// 药品类型
|
||||||
@@ -104,6 +110,11 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
|||||||
Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response) {
|
Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response) {
|
||||||
pageNo = 1;
|
pageNo = 1;
|
||||||
pageSize = 10000;
|
pageSize = 10000;
|
||||||
|
// 数据初始化,不使用eq条件拼接
|
||||||
|
// 库存范围
|
||||||
|
Integer inventoryScope = inventoryProductReportSearchParam.getInventoryScope();
|
||||||
|
inventoryProductReportSearchParam.setInventoryScope(null);
|
||||||
|
|
||||||
// 设置模糊查询的字段名
|
// 设置模糊查询的字段名
|
||||||
HashSet<String> searchFields = new HashSet<>();
|
HashSet<String> searchFields = new HashSet<>();
|
||||||
searchFields.add(CommonConstants.FieldName.BusNo);
|
searchFields.add(CommonConstants.FieldName.BusNo);
|
||||||
@@ -114,7 +125,8 @@ public class InventoryProductReportAppServiceImpl implements IInventoryProductRe
|
|||||||
|
|
||||||
// 查询库存商品明细分页列表
|
// 查询库存商品明细分页列表
|
||||||
Page<InventoryProductReportPageDto> productReportPage = inventoryProductReportMapper.selectProductReportPage(
|
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 -> {
|
productReportPage.getRecords().forEach(e -> {
|
||||||
// 药品类型
|
// 药品类型
|
||||||
|
|||||||
@@ -38,4 +38,10 @@ public class InventoryProductReportSearchParam {
|
|||||||
|
|
||||||
/** 供应商 */
|
/** 供应商 */
|
||||||
private Long supplierId;
|
private Long supplierId;
|
||||||
|
|
||||||
|
/** 厂家/产地(供应商名称) */
|
||||||
|
private String manufacturerText;
|
||||||
|
|
||||||
|
/** 仓库ID(药房ID) */
|
||||||
|
private Long purposeLocationId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,11 @@ public interface InventoryProductReportMapper {
|
|||||||
* @param page 分页
|
* @param page 分页
|
||||||
* @param queryWrapper 查询条件
|
* @param queryWrapper 查询条件
|
||||||
* @param lotNumber 命中条件枚举类型:产品批号
|
* @param lotNumber 命中条件枚举类型:产品批号
|
||||||
|
* @param inventoryScope 库存范围:无限制(1)、数量等于0(2)、数量大于0(3)、数量小于等于20(4)、数量小于等于50(5)
|
||||||
* @return 库存商品明细
|
* @return 库存商品明细
|
||||||
*/
|
*/
|
||||||
Page<InventoryProductReportPageDto> selectProductReportPage(@Param("page") Page<InventoryProductReportPageDto> page,
|
Page<InventoryProductReportPageDto> selectProductReportPage(@Param("page") Page<InventoryProductReportPageDto> page,
|
||||||
@Param(Constants.WRAPPER) QueryWrapper<InventoryProductReportSearchParam> queryWrapper,
|
@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 java.math.BigDecimal;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【3201】后台计算结果 DB映射实体
|
* Settlement3202 Result DB mapping entity
|
||||||
*
|
*
|
||||||
* @author SunJQ
|
* @author SunJQ
|
||||||
* @date 2025-04-15
|
* @date 2025-04-15
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class Settlement3202VO {
|
public class Settlement3202VO {
|
||||||
/** 医疗费用总额 */
|
/** Medical Fee Sum */
|
||||||
|
|
||||||
private BigDecimal medFeeSumAmt;
|
private BigDecimal medFeeSumAmt;
|
||||||
/** 基金支付总额 */
|
/** Fund Pay Sum */
|
||||||
|
|
||||||
private BigDecimal fundPaySumAmt;
|
private BigDecimal fundPaySumAmt;
|
||||||
/** 个人账户支付总额 */
|
/** Account Pay */
|
||||||
|
|
||||||
private BigDecimal acctPay;
|
private BigDecimal acctPay;
|
||||||
/** 个人账户支付总额 */
|
/** Account Gj Pay */
|
||||||
|
|
||||||
private BigDecimal acctGjPay;
|
private BigDecimal acctGjPay;
|
||||||
/** 现金支付总额 */
|
/** Self Pay Cash */
|
||||||
|
|
||||||
private BigDecimal selfPayCash;
|
private BigDecimal selfPayCash;
|
||||||
/** 微信支付总额 */
|
/** Self Pay WeChat */
|
||||||
|
|
||||||
private BigDecimal selfPayVx;
|
private BigDecimal selfPayVx;
|
||||||
/** 阿里支付总额 */
|
/** Self Pay Alipay */
|
||||||
|
|
||||||
private BigDecimal selfPayAli;
|
private BigDecimal selfPayAli;
|
||||||
/** 银行卡支付总额 */
|
/** Self Pay Bank Card */
|
||||||
|
|
||||||
private BigDecimal selfPayUnion;
|
private BigDecimal selfPayUnion;
|
||||||
/** 定点医药机构结算笔数 */
|
/** Settlement Count */
|
||||||
|
|
||||||
private Integer fixMedInsSetlCnt;
|
private Integer fixMedInsSetlCnt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ spring:
|
|||||||
# 从库数据源
|
# 从库数据源
|
||||||
slave:
|
slave:
|
||||||
# 从数据源开关/默认关闭
|
# 从数据源开关/默认关闭
|
||||||
enabled: false
|
enabled:
|
||||||
url:
|
url:
|
||||||
username:
|
username:
|
||||||
password:
|
password:
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:postgresql://localhost:5432/openhis?currentSchema=public&characterEncoding=UTF-8&client_encoding=UTF-8
|
url: jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=public&characterEncoding=UTF-8&client_encoding=UTF-8
|
||||||
username: postgres
|
username: postgresql
|
||||||
password: root
|
password: Jchl1528
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
slave:
|
slave:
|
||||||
# 从数据源开关/默认关闭
|
# 从数据源开关/默认关闭
|
||||||
@@ -62,13 +62,13 @@ spring:
|
|||||||
# redis 配置
|
# redis 配置
|
||||||
redis:
|
redis:
|
||||||
# 地址
|
# 地址
|
||||||
host: 127.0.0.1
|
host: 192.168.110.252
|
||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 6379
|
port: 6379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 1
|
database: 1
|
||||||
# 密码
|
# 密码
|
||||||
password: redis
|
password: Jchl1528
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
lettuce:
|
lettuce:
|
||||||
|
|||||||
@@ -74,12 +74,14 @@
|
|||||||
T2."name" AS item_name,
|
T2."name" AS item_name,
|
||||||
T2.id AS item_id,
|
T2.id AS item_id,
|
||||||
T2.part_percent,
|
T2.part_percent,
|
||||||
T2.manufacturer_text AS supplier_name,
|
T2.manufacturer_text AS manufacturer_text,
|
||||||
T3.total_volume,
|
T3.total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
T1.occurrence_time,
|
T1.occurrence_time,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
@@ -100,6 +102,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_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}
|
WHERE T1.bus_no = #{busNo}
|
||||||
AND T1.delete_flag = '0'
|
AND T1.delete_flag = '0'
|
||||||
UNION
|
UNION
|
||||||
@@ -121,12 +125,14 @@
|
|||||||
T8."name" AS item_name,
|
T8."name" AS item_name,
|
||||||
T8.id AS item_id,
|
T8.id AS item_id,
|
||||||
T8.part_percent,
|
T8.part_percent,
|
||||||
T8.manufacturer_text AS supplier_name,
|
T8.manufacturer_text AS manufacturer_text,
|
||||||
T8."size" AS total_volume,
|
T8."size" AS total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
T1.occurrence_time,
|
T1.occurrence_time,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
@@ -145,6 +151,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_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}
|
WHERE T1.bus_no = #{busNo}
|
||||||
AND T1.delete_flag = '0'
|
AND T1.delete_flag = '0'
|
||||||
</select>
|
</select>
|
||||||
@@ -167,12 +175,14 @@
|
|||||||
T2."name" AS item_name,
|
T2."name" AS item_name,
|
||||||
T2.id AS item_id,
|
T2.id AS item_id,
|
||||||
T2.part_percent,
|
T2.part_percent,
|
||||||
T2.manufacturer_text AS supplier_name,
|
T2.manufacturer_text AS manufacturer_text,
|
||||||
T3.total_volume,
|
T3.total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
WHERE T9.item_id = T1.item_id
|
WHERE T9.item_id = T1.item_id
|
||||||
@@ -192,6 +202,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_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}
|
WHERE T1.purpose_location_id = #{locationId}
|
||||||
AND T1.status_enum = #{statusEnum}
|
AND T1.status_enum = #{statusEnum}
|
||||||
AND T1.type_enum IN
|
AND T1.type_enum IN
|
||||||
@@ -220,12 +232,14 @@
|
|||||||
T8."name" AS item_name,
|
T8."name" AS item_name,
|
||||||
T8.id AS item_id,
|
T8.id AS item_id,
|
||||||
T8.part_percent,
|
T8.part_percent,
|
||||||
T8.manufacturer_text AS supplier_name,
|
T8.manufacturer_text AS manufacturer_text,
|
||||||
T8."size" AS total_volume,
|
T8."size" AS total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
WHERE T9.item_id = T1.item_id
|
WHERE T9.item_id = T1.item_id
|
||||||
@@ -243,6 +257,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_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}
|
WHERE T1.purpose_location_id = #{locationId}
|
||||||
AND T1.status_enum = #{statusEnum}
|
AND T1.status_enum = #{statusEnum}
|
||||||
AND T1.type_enum IN
|
AND T1.type_enum IN
|
||||||
|
|||||||
@@ -62,7 +62,14 @@
|
|||||||
T9.charge_item_ids,
|
T9.charge_item_ids,
|
||||||
T9.payment_id,
|
T9.payment_id,
|
||||||
T9.picture_url,
|
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 (
|
from (
|
||||||
SELECT T1.tenant_id AS tenant_id,
|
SELECT T1.tenant_id AS tenant_id,
|
||||||
T1.id AS encounter_id,
|
T1.id AS encounter_id,
|
||||||
@@ -84,7 +91,15 @@
|
|||||||
T13.charge_item_ids,
|
T13.charge_item_ids,
|
||||||
T13.id AS payment_id,
|
T13.id AS payment_id,
|
||||||
ai.picture_url AS picture_url,
|
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,
|
||||||
|
T14.enterer_id 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
|
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_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'
|
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
||||||
@@ -112,6 +127,32 @@
|
|||||||
ON T10.id::TEXT = ANY(string_to_array(T13.charge_item_ids,','))
|
ON T10.id::TEXT = ANY(string_to_array(T13.charge_item_ids,','))
|
||||||
AND T13.delete_flag = '0'
|
AND T13.delete_flag = '0'
|
||||||
AND T13.status_enum = ${paymentStatus}
|
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 (
|
||||||
|
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
|
LEFT JOIN adm_invoice AS ai
|
||||||
ON ai.reconciliation_id = T13.id AND ai.delete_flag = '0'
|
ON ai.reconciliation_id = T13.id AND ai.delete_flag = '0'
|
||||||
WHERE T1.delete_flag = '0'
|
WHERE T1.delete_flag = '0'
|
||||||
|
|||||||
@@ -41,7 +41,186 @@
|
|||||||
abi.restricted_flag,
|
abi.restricted_flag,
|
||||||
abi.restricted_scope
|
abi.restricted_scope
|
||||||
from (
|
from (
|
||||||
<if test="adviceTypes == null or adviceTypes.contains(1)">
|
<!-- 改进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,
|
SELECT T1.tenant_id,
|
||||||
1 AS advice_type,
|
1 AS advice_type,
|
||||||
T1.category_code AS category_code,
|
T1.category_code AS category_code,
|
||||||
@@ -103,11 +282,9 @@
|
|||||||
AND T5.instance_table = #{medicationTableName}
|
AND T5.instance_table = #{medicationTableName}
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
<if test="adviceTypes == null or adviceTypes.contains(1)">
|
<if test="adviceTypes.contains(1) and (adviceTypes.contains(2) or adviceTypes.contains(3))">UNION ALL</if>
|
||||||
<if test="adviceTypes == null or adviceTypes.contains(2) or adviceTypes.contains(3)">UNION ALL</if>
|
|
||||||
</if>
|
|
||||||
|
|
||||||
<if test="adviceTypes == null or adviceTypes.contains(2)">
|
<if test="adviceTypes.contains(2)">
|
||||||
SELECT T1.tenant_id,
|
SELECT T1.tenant_id,
|
||||||
2 AS advice_type,
|
2 AS advice_type,
|
||||||
T1.category_code AS category_code,
|
T1.category_code AS category_code,
|
||||||
@@ -164,11 +341,9 @@
|
|||||||
AND T1.status_enum = #{statusEnum}
|
AND T1.status_enum = #{statusEnum}
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
<if test="adviceTypes == null or adviceTypes.contains(2)">
|
<if test="adviceTypes.contains(2) and adviceTypes.contains(3)">UNION ALL</if>
|
||||||
<if test="adviceTypes == null or adviceTypes.contains(3)">UNION ALL</if>
|
|
||||||
</if>
|
|
||||||
|
|
||||||
<if test="adviceTypes == null or adviceTypes.contains(3)">
|
<if test="adviceTypes.contains(3)">
|
||||||
SELECT T1.tenant_id,
|
SELECT T1.tenant_id,
|
||||||
3 AS advice_type,
|
3 AS advice_type,
|
||||||
T1.category_code AS category_code,
|
T1.category_code AS category_code,
|
||||||
@@ -201,7 +376,7 @@
|
|||||||
'' AS manufacturer,
|
'' AS manufacturer,
|
||||||
T2.ID AS charge_item_definition_id,
|
T2.ID AS charge_item_definition_id,
|
||||||
T2.instance_table AS advice_table_name,
|
T2.instance_table AS advice_table_name,
|
||||||
T3.organization_id AS position_id,
|
COALESCE(T3.organization_id, T1.org_id) AS position_id,
|
||||||
0 AS restricted_flag,
|
0 AS restricted_flag,
|
||||||
'' AS restricted_scope
|
'' AS restricted_scope
|
||||||
FROM wor_activity_definition AS T1
|
FROM wor_activity_definition AS T1
|
||||||
@@ -223,6 +398,9 @@
|
|||||||
AND T1.status_enum = #{statusEnum}
|
AND T1.status_enum = #{statusEnum}
|
||||||
AND T2.instance_table = #{activityTableName}
|
AND T2.instance_table = #{activityTableName}
|
||||||
</if>
|
</if>
|
||||||
|
</if>
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
) AS abi
|
) AS abi
|
||||||
${ew.customSqlSegment}
|
${ew.customSqlSegment}
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
<select id="selectProductReportPage"
|
<select id="selectProductReportPage"
|
||||||
resultType="com.openhis.web.reportmanage.dto.InventoryProductReportPageDto">
|
resultType="com.openhis.web.reportmanage.dto.InventoryProductReportPageDto">
|
||||||
|
SELECT *
|
||||||
|
FROM (
|
||||||
SELECT T8.id, --ID
|
SELECT T8.id, --ID
|
||||||
T8.bus_no, --药品编码
|
T8.bus_no, --药品编码
|
||||||
T8.name, --药品名称
|
T8.name, --药品名称
|
||||||
@@ -23,9 +25,11 @@
|
|||||||
T8.purpose_type_enum, --仓库类型
|
T8.purpose_type_enum, --仓库类型
|
||||||
T8.location_name, --仓库名称
|
T8.location_name, --仓库名称
|
||||||
T8.location_store_name, --货位名称
|
T8.location_store_name, --货位名称
|
||||||
|
T8.purpose_location_id, --仓库ID
|
||||||
T8.expiration_date, --有效期
|
T8.expiration_date, --有效期
|
||||||
T8.yb_no, --医保编码
|
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
|
FROM (SELECT T1.id, --ID
|
||||||
T2.bus_no, --药品编码
|
T2.bus_no, --药品编码
|
||||||
T2.name, --药品名称
|
T2.name, --药品名称
|
||||||
@@ -46,6 +50,7 @@
|
|||||||
T6.form_enum AS purpose_type_enum, --仓库类型
|
T6.form_enum AS purpose_type_enum, --仓库类型
|
||||||
T6.name AS location_name, --仓库名称
|
T6.name AS location_name, --仓库名称
|
||||||
T7.name AS location_store_name, --货位名称
|
T7.name AS location_store_name, --货位名称
|
||||||
|
T1.location_id AS purpose_location_id, --仓库ID
|
||||||
T1.expiration_date, --有效期
|
T1.expiration_date, --有效期
|
||||||
T2.yb_no, --医保编码
|
T2.yb_no, --医保编码
|
||||||
T1.tenant_id -- 租户ID
|
T1.tenant_id -- 租户ID
|
||||||
@@ -86,9 +91,11 @@
|
|||||||
T10.purpose_type_enum, --仓库类型
|
T10.purpose_type_enum, --仓库类型
|
||||||
T10.location_name, --仓库名称
|
T10.location_name, --仓库名称
|
||||||
T10.location_store_name, --货位名称
|
T10.location_store_name, --货位名称
|
||||||
|
T10.purpose_location_id, --仓库ID
|
||||||
T10.expiration_date, --有效期
|
T10.expiration_date, --有效期
|
||||||
T10.yb_no, --医保编码
|
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
|
FROM (SELECT T1.id, --ID
|
||||||
T9.bus_no, --药品编码
|
T9.bus_no, --药品编码
|
||||||
T9.name, --药品名称
|
T9.name, --药品名称
|
||||||
@@ -109,6 +116,7 @@
|
|||||||
T6.form_enum AS purpose_type_enum, --仓库类型
|
T6.form_enum AS purpose_type_enum, --仓库类型
|
||||||
T6.name AS location_name, --仓库名称
|
T6.name AS location_name, --仓库名称
|
||||||
T7.name AS location_store_name, --货位名称
|
T7.name AS location_store_name, --货位名称
|
||||||
|
T1.location_id AS purpose_location_id, --仓库ID
|
||||||
T1.expiration_date, --有效期
|
T1.expiration_date, --有效期
|
||||||
T9.yb_no, --医保编码
|
T9.yb_no, --医保编码
|
||||||
T1.tenant_id -- 租户ID
|
T1.tenant_id -- 租户ID
|
||||||
@@ -129,6 +137,23 @@
|
|||||||
ON T1.location_store_id = T7.id
|
ON T1.location_store_id = T7.id
|
||||||
AND T7.delete_flag = '0'
|
AND T7.delete_flag = '0'
|
||||||
WHERE T1.delete_flag = '0') AS T10
|
WHERE T1.delete_flag = '0') AS T10
|
||||||
|
) AS T
|
||||||
${ew.customSqlSegment}
|
${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>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -142,6 +142,11 @@ public class CommonConstants {
|
|||||||
*/
|
*/
|
||||||
public interface FieldName {
|
public interface FieldName {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
String Phone = "phone";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单据号
|
* 单据号
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public enum LocationForm implements HisEnumInterface {
|
|||||||
|
|
||||||
PHARMACY(16, "ph", "药房"),
|
PHARMACY(16, "ph", "药房"),
|
||||||
|
|
||||||
WAREHOUSE (17, "wa", "仓库"),
|
WAREHOUSE (17, "wa", "耗材库"),
|
||||||
|
|
||||||
DEPARTMENT (18, "de", "科室");
|
DEPARTMENT (18, "de", "科室");
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,11 @@
|
|||||||
<groupId>com.openhis</groupId>
|
<groupId>com.openhis</groupId>
|
||||||
<artifactId>openhis-common</artifactId>
|
<artifactId>openhis-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- 核心共通模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.core</groupId>
|
||||||
|
<artifactId>core-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|||||||
@@ -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;
|
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.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.openhis.administration.domain.Invoice;
|
import com.openhis.administration.domain.Invoice;
|
||||||
import com.openhis.administration.domain.Supplier;
|
import com.openhis.administration.domain.Supplier;
|
||||||
@@ -18,4 +20,14 @@ public interface IInvoiceService extends IService<Invoice> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Long addInvoice(Invoice invoice);
|
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.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
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.core.common.utils.SecurityUtils;
|
||||||
|
import com.openhis.administration.domain.Invoice;
|
||||||
import com.openhis.administration.domain.Supplier;
|
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.common.enums.SupplyStatus;
|
||||||
import com.openhis.workflow.domain.SupplyRequest;
|
import com.openhis.workflow.domain.SupplyRequest;
|
||||||
import org.springframework.stereotype.Service;
|
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.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> impl
|
|||||||
* @param invoice 发票实体
|
* @param invoice 发票实体
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Long addInvoice(Invoice invoice){
|
public Long addInvoice(Invoice invoice){
|
||||||
// 根据编码判断发票是否存在
|
// 根据编码判断发票是否存在
|
||||||
List<Invoice> invoices =
|
List<Invoice> invoices =
|
||||||
@@ -46,4 +48,26 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> impl
|
|||||||
return invoice.getId();
|
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
|
@Override
|
||||||
public List<Location> getPharmacyCabinetList() {
|
public List<Location> getPharmacyCabinetList() {
|
||||||
return baseMapper.selectList(new LambdaQueryWrapper<Location>().in(Location::getFormEnum,
|
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<Practitioner> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("user_id", userId);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -45,9 +45,13 @@ public class ConditionDefinitionServiceImpl extends ServiceImpl<ConditionDefinit
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean addDisease(ConditionDefinition conditionDefinition) {
|
public boolean addDisease(ConditionDefinition conditionDefinition) {
|
||||||
// 根据病种编码判断病种是否存在
|
// 根据病种编码判断病种是否存在
|
||||||
|
// List<ConditionDefinition> conditionDefinitions =
|
||||||
|
// conditionDefinitionMapper.selectList(new LambdaQueryWrapper<ConditionDefinition>()
|
||||||
|
// .eq(ConditionDefinition::getConditionCode, conditionDefinition.getConditionCode()));
|
||||||
|
// 根据医保编码判断病种是否存在
|
||||||
List<ConditionDefinition> conditionDefinitions =
|
List<ConditionDefinition> conditionDefinitions =
|
||||||
conditionDefinitionMapper.selectList(new LambdaQueryWrapper<ConditionDefinition>()
|
conditionDefinitionMapper.selectList(new LambdaQueryWrapper<ConditionDefinition>()
|
||||||
.eq(ConditionDefinition::getConditionCode, conditionDefinition.getConditionCode()));
|
.eq(ConditionDefinition::getYbNo,conditionDefinition.getYbNo()));
|
||||||
if (conditionDefinitions.size() > 0) {
|
if (conditionDefinitions.size() > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.math.BigDecimal;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.core.common.core.domain.HisBaseEntity;
|
import com.core.common.core.domain.HisBaseEntity;
|
||||||
@@ -102,4 +103,8 @@ public class PaymentReconciliation extends HisBaseEntity {
|
|||||||
|
|
||||||
/** 医保清算标志 */
|
/** 医保清算标志 */
|
||||||
private Integer ybClearFlag;//默认值0 未清算
|
private Integer ybClearFlag;//默认值0 未清算
|
||||||
|
|
||||||
|
/** 退号/退费原因 */
|
||||||
|
@TableField("refund_reason")
|
||||||
|
private String refundReason;
|
||||||
}
|
}
|
||||||
@@ -131,13 +131,16 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Contract getContract(String contractNo) {
|
public Contract getContract(String contractNo) {
|
||||||
|
// 先从缓存中查找
|
||||||
List<Contract> contractList = getRedisContractList();
|
List<Contract> contractList = getRedisContractList();
|
||||||
for (Contract contract : contractList) {
|
for (Contract contract : contractList) {
|
||||||
if (contractNo.equals(contract.getBusNo())) {
|
if (contractNo.equals(contract.getBusNo())) {
|
||||||
return contract;
|
return contract;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
// 缓存中找不到时,直接从数据库查询,支持contractNo动态变化
|
||||||
|
return getByContractNo(contractNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -85,33 +85,33 @@
|
|||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<!-- <build>-->
|
||||||
<plugins>
|
<!-- <plugins>-->
|
||||||
<plugin>
|
<!-- <plugin>-->
|
||||||
<groupId>org.springframework.boot</groupId>
|
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||||
<configuration>
|
<!-- <configuration>-->
|
||||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
<!-- <fork>true</fork> <!– 如果没有该配置,devtools不会生效 –>-->
|
||||||
</configuration>
|
<!-- </configuration>-->
|
||||||
<executions>
|
<!-- <executions>-->
|
||||||
<execution>
|
<!-- <execution>-->
|
||||||
<goals>
|
<!-- <goals>-->
|
||||||
<goal>repackage</goal>
|
<!-- <goal>repackage</goal>-->
|
||||||
</goals>
|
<!-- </goals>-->
|
||||||
</execution>
|
<!-- </execution>-->
|
||||||
</executions>
|
<!-- </executions>-->
|
||||||
</plugin>
|
<!-- </plugin>-->
|
||||||
<plugin>
|
<!-- <plugin>-->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
<!-- <artifactId>maven-war-plugin</artifactId>-->
|
||||||
<version>${maven-war-plugin.version}</version>
|
<!-- <version>${maven-war-plugin.version}</version>-->
|
||||||
<configuration>
|
<!-- <configuration>-->
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
<!-- <failOnMissingWebXml>false</failOnMissingWebXml>-->
|
||||||
<warName>${project.artifactId}</warName>
|
<!-- <warName>${project.artifactId}</warName>-->
|
||||||
</configuration>
|
<!-- </configuration>-->
|
||||||
</plugin>
|
<!-- </plugin>-->
|
||||||
</plugins>
|
<!-- </plugins>-->
|
||||||
<finalName>${project.artifactId}</finalName>
|
<!-- <finalName>${project.artifactId}</finalName>-->
|
||||||
</build>
|
<!-- </build>-->
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VITE_APP_TITLE = 医院信息管理系统
|
VITE_APP_TITLE=医院信息管理系统
|
||||||
|
|
||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
VITE_APP_ENV = 'production'
|
VITE_APP_ENV=production
|
||||||
|
|
||||||
# OpenHIS管理系统/生产环境
|
# OpenHIS管理系统/生产环境
|
||||||
VITE_APP_BASE_API = '/prod-api'
|
VITE_APP_BASE_API=/prod-api
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 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"
|
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
|
||||||
/>
|
/>
|
||||||
<!-- <link rel="icon" href="src/assets/images/ccu.png" /> -->
|
<!-- <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>
|
<title>医院信息管理系统</title>
|
||||||
<!--[if lt IE 11
|
<!--[if lt IE 11
|
||||||
]><script>
|
]><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",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "10.6.1",
|
"@vueuse/core": "10.6.1",
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
|
"chart.js": "^4.5.1",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"decimal.js": "^10.5.0",
|
"decimal.js": "^10.5.0",
|
||||||
"echarts": "5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"element-china-area-data": "^6.1.0",
|
"element-china-area-data": "^6.1.0",
|
||||||
"element-plus": "2.9.11",
|
"element-plus": "2.9.11",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
@@ -544,6 +545,11 @@
|
|||||||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
"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": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"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"
|
"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": {
|
"node_modules/china-division": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
||||||
@@ -1837,20 +1855,6 @@
|
|||||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/copy-descriptor": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||||
@@ -2823,20 +2827,6 @@
|
|||||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/error-ex": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
|
"resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
|
||||||
@@ -4195,14 +4185,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"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": {
|
"node_modules/is-windows": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
|
||||||
@@ -4325,34 +4307,6 @@
|
|||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"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"
|
"@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": {
|
"node_modules/map-cache": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmmirror.com/map-cache/-/map-cache-0.2.2.tgz",
|
"resolved": "https://registry.npmmirror.com/map-cache/-/map-cache-0.2.2.tgz",
|
||||||
@@ -4521,20 +4460,6 @@
|
|||||||
"node": ">=8.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": {
|
"node_modules/mime-db": {
|
||||||
"version": "1.52.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
@@ -4723,24 +4648,6 @@
|
|||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/normalize-path": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
@@ -4984,17 +4891,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/pascalcase": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/pascalcase/-/pascalcase-0.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||||
@@ -5045,17 +4941,6 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"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": {
|
"node_modules/pinia": {
|
||||||
"version": "2.1.7",
|
"version": "2.1.7",
|
||||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz",
|
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz",
|
||||||
@@ -5290,14 +5175,6 @@
|
|||||||
"@province-city-china/types": "8.5.8"
|
"@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": {
|
"node_modules/quansync": {
|
||||||
"version": "0.2.8",
|
"version": "0.2.8",
|
||||||
"resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.8.tgz",
|
"resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.8.tgz",
|
||||||
@@ -5779,14 +5656,6 @@
|
|||||||
"node": ">=14.0.0"
|
"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": {
|
"node_modules/scule": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
|
||||||
@@ -5801,17 +5670,6 @@
|
|||||||
"preval.macro": "^4.0.0"
|
"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": {
|
"node_modules/set-function-length": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
|
"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",
|
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
"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": {
|
"@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@@ -8634,6 +8497,14 @@
|
|||||||
"supports-color": "^7.1.0"
|
"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": {
|
"china-division": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
||||||
@@ -8749,17 +8620,6 @@
|
|||||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||||
"dev": true
|
"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": {
|
"copy-descriptor": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||||
@@ -9458,17 +9318,6 @@
|
|||||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||||
"dev": true
|
"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": {
|
"error-ex": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
|
"resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
|
||||||
@@ -10443,14 +10292,6 @@
|
|||||||
"get-intrinsic": "^1.2.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": {
|
"is-windows": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
|
||||||
@@ -10554,26 +10395,6 @@
|
|||||||
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
|
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
|
||||||
"dev": true
|
"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": {
|
"lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"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"
|
"@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": {
|
"map-cache": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmmirror.com/map-cache/-/map-cache-0.2.2.tgz",
|
"resolved": "https://registry.npmmirror.com/map-cache/-/map-cache-0.2.2.tgz",
|
||||||
@@ -10707,14 +10516,6 @@
|
|||||||
"picomatch": "^2.3.1"
|
"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": {
|
"mime-db": {
|
||||||
"version": "1.52.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
"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": {
|
"normalize-path": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
@@ -11045,14 +10834,6 @@
|
|||||||
"lines-and-columns": "^1.1.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": {
|
"pascalcase": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/pascalcase/-/pascalcase-0.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||||
@@ -11091,14 +10872,6 @@
|
|||||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
"dev": true
|
"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": {
|
"pinia": {
|
||||||
"version": "2.1.7",
|
"version": "2.1.7",
|
||||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz",
|
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz",
|
||||||
@@ -11245,14 +11018,6 @@
|
|||||||
"@province-city-china/types": "8.5.8"
|
"@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": {
|
"quansync": {
|
||||||
"version": "0.2.8",
|
"version": "0.2.8",
|
||||||
"resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.8.tgz",
|
"resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.8.tgz",
|
||||||
@@ -11592,14 +11357,6 @@
|
|||||||
"source-map-js": ">=0.6.2 <2.0.0"
|
"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": {
|
"scule": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
|
||||||
@@ -11614,14 +11371,6 @@
|
|||||||
"preval.macro": "^4.0.0"
|
"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": {
|
"set-function-length": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
|
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build:prod": "vite build",
|
"build:prod": "vite build --mode production",
|
||||||
"build:stage": "vite build --mode staging",
|
"build:stage": "vite build --mode staging",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"build:spug": "vite build --mode spug"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -20,9 +21,10 @@
|
|||||||
"@vueup/vue-quill": "1.2.0",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "10.6.1",
|
"@vueuse/core": "10.6.1",
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
|
"chart.js": "^4.5.1",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"decimal.js": "^10.5.0",
|
"decimal.js": "^10.5.0",
|
||||||
"echarts": "5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"element-china-area-data": "^6.1.0",
|
"element-china-area-data": "^6.1.0",
|
||||||
"element-plus": "2.9.11",
|
"element-plus": "2.9.11",
|
||||||
"file-saver": "2.0.5",
|
"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: {}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} */
|
||||||
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',
|
path: '/system/tenant-user',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -98,7 +210,7 @@ export const dynamicRoutes = [
|
|||||||
path: 'set/:tenantId(\\d+)',
|
path: 'set/:tenantId(\\d+)',
|
||||||
component: () => import('@/views/system/tenant/setUser'),
|
component: () => import('@/views/system/tenant/setUser'),
|
||||||
name: '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+)',
|
path: 'set/:tenantId(\\d+)',
|
||||||
component: () => import('@/views/system/tenant/setContract'),
|
component: () => import('@/views/system/tenant/setContract'),
|
||||||
name: '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',
|
path: '/monitor/job-log',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -188,9 +342,12 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// 合并常量路由和动态路由,确保所有路由都能被访问
|
||||||
|
const allRoutes = [...constantRoutes, ...dynamicRoutes];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: createWebHistory(),
|
||||||
routes: constantRoutes,
|
routes: allRoutes,
|
||||||
scrollBehavior(to, from, savedPosition) {
|
scrollBehavior(to, from, savedPosition) {
|
||||||
if (savedPosition) {
|
if (savedPosition) {
|
||||||
return savedPosition
|
return savedPosition
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ export default {
|
|||||||
* 网页标题
|
* 网页标题
|
||||||
*/
|
*/
|
||||||
title: import.meta.env.VITE_APP_TITLE,
|
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
|
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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;
|
const code = res.data.code || 200;
|
||||||
// 获取错误信息
|
// 获取错误信息
|
||||||
@@ -97,13 +97,22 @@ service.interceptors.response.use(res => {
|
|||||||
}
|
}
|
||||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||||
} else if (code === 500) {
|
} else if (code === 500) {
|
||||||
|
// 检查是否需要跳过错误提示
|
||||||
|
if (!res.config?.skipErrorMsg) {
|
||||||
ElMessage({ message: msg, type: 'error' })
|
ElMessage({ message: msg, type: 'error' })
|
||||||
|
}
|
||||||
return Promise.reject(new Error(msg))
|
return Promise.reject(new Error(msg))
|
||||||
} else if (code === 601) {
|
} else if (code === 601) {
|
||||||
|
// 检查是否需要跳过错误提示
|
||||||
|
if (!res.config?.skipErrorMsg) {
|
||||||
ElMessage({ message: msg, type: 'warning' })
|
ElMessage({ message: msg, type: 'warning' })
|
||||||
|
}
|
||||||
return Promise.reject(new Error(msg))
|
return Promise.reject(new Error(msg))
|
||||||
} else if (code !== 200) {
|
} else if (code !== 200) {
|
||||||
|
// 检查是否需要跳过错误提示
|
||||||
|
if (!res.config?.skipErrorMsg) {
|
||||||
ElNotification.error({ title: msg })
|
ElNotification.error({ title: msg })
|
||||||
|
}
|
||||||
return Promise.reject('error')
|
return Promise.reject('error')
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve(res.data)
|
return Promise.resolve(res.data)
|
||||||
@@ -119,10 +128,12 @@ service.interceptors.response.use(res => {
|
|||||||
} else if (message.includes("Request failed with status code")) {
|
} else if (message.includes("Request failed with status code")) {
|
||||||
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
||||||
}
|
}
|
||||||
|
// 检查是否需要跳过错误提示
|
||||||
|
if (!error.config?.skipErrorMsg) {
|
||||||
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
||||||
return Promise.reject(error)
|
|
||||||
}
|
}
|
||||||
)
|
return Promise.reject(error)
|
||||||
|
})
|
||||||
|
|
||||||
// 通用下载方法
|
// 通用下载方法
|
||||||
export function download(url, params, filename, config) {
|
export function download(url, params, filename, config) {
|
||||||
|
|||||||
1626
openhis-ui-vue3/src/views/basicmanage/InvoiceManagement/index.vue
Normal file
1626
openhis-ui-vue3/src/views/basicmanage/InvoiceManagement/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@ export function getOrgDetail(id) {
|
|||||||
export function initOrgTypeOption() {
|
export function initOrgTypeOption() {
|
||||||
return request({
|
return request({
|
||||||
url: '/base-data-manage/organization/init',
|
url: '/base-data-manage/organization/init',
|
||||||
method: 'get',
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,15 +141,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="Organization">
|
<script setup name="Organization">
|
||||||
import {
|
import { getList, deleteOrganization, addOrganization, updateOrganization, disableOrg, initOrgTypeOption, enableOrg } from './components/api';
|
||||||
getList,
|
|
||||||
deleteOrganization,
|
|
||||||
addOrganization,
|
|
||||||
updateOrganization,
|
|
||||||
disableOrg,
|
|
||||||
initOrgTypeOption,
|
|
||||||
enableOrg,
|
|
||||||
} from './components/api';
|
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
@@ -181,11 +173,57 @@ const rules = ref({
|
|||||||
|
|
||||||
getPageList();
|
getPageList();
|
||||||
initOption();
|
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() {
|
function initOption() {
|
||||||
if (orgTypeOption.value.length == 0) {
|
if (orgTypeOption.value.length == 0) {
|
||||||
initOrgTypeOption().then((res) => {
|
initOrgTypeOption().then((res) => {
|
||||||
orgTypeOption.value = res.data.organizationTypeOptions;
|
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();
|
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() {
|
function getPageList() {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
getList(queryParams.value).then((res) => {
|
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;
|
total.value = res.data.total;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
title.value = '添加药库药房';
|
title.value = '添加科室';
|
||||||
open.value = true;
|
open.value = true;
|
||||||
reset();
|
reset();
|
||||||
console.log(form.value);
|
console.log(form.value);
|
||||||
@@ -223,7 +292,8 @@ function handelEdit(row) {
|
|||||||
form.value.ybNo = row.ybNo;
|
form.value.ybNo = row.ybNo;
|
||||||
form.value.ybName = row.ybName;
|
form.value.ybName = row.ybName;
|
||||||
form.value.typeEnum = row.typeEnum;
|
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;
|
form.value.busNoParent = row.busNo.split('.').length > 1 ? row.busNo.split('.')[0] : undefined;
|
||||||
}, 50);
|
}, 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,863 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 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>
|
||||||
|
</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() {
|
||||||
|
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 }"
|
:class="{ 'error-border': scope.row.error }"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in distribution_category_code"
|
v-for="dict in med_category_code"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
@@ -184,7 +184,7 @@ import {
|
|||||||
deletePharmacyDepartment,
|
deletePharmacyDepartment,
|
||||||
} from './components/pharmacyDepartment';
|
} from './components/pharmacyDepartment';
|
||||||
const { proxy } = getCurrentInstance();
|
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';
|
import { nextTick } from 'vue';
|
||||||
|
|
||||||
const diagnosisTreatmentList = ref([]);
|
const diagnosisTreatmentList = ref([]);
|
||||||
|
|||||||
@@ -36,8 +36,12 @@ export function updateWarehouse(data) {
|
|||||||
// 删除
|
// 删除
|
||||||
export function deleteWarehouse(data) {
|
export function deleteWarehouse(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/base-data-manage/location/location?locationId=' + data.locationId,
|
url: '/base-data-manage/location/location',
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
|
params: {
|
||||||
|
locationId: data.locationId,
|
||||||
|
busNo: data.busNo
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ const { proxy } = getCurrentInstance();
|
|||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const organization = ref([]);
|
const organization = ref([]);
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
locationFormList: [11, 16],
|
locationFormList: [11, 16, 17],
|
||||||
});
|
});
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const form = ref({
|
const form = ref({
|
||||||
@@ -173,7 +173,7 @@ const { warehous_type } = proxy.useDict('warehous_type');
|
|||||||
const rules = ref({
|
const rules = ref({
|
||||||
busNo: [{ required: false, message: '请输入科室编号', trigger: 'change' }],
|
busNo: [{ required: false, message: '请输入科室编号', trigger: 'change' }],
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '请输入仓库名称', trigger: 'change' },
|
{ required: true, message: '请输入', trigger: 'change' },
|
||||||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'change' },
|
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'change' },
|
||||||
],
|
],
|
||||||
formEnum: [{ required: true, message: '请选择仓库类型', trigger: 'change' }],
|
formEnum: [{ required: true, message: '请选择仓库类型', trigger: 'change' }],
|
||||||
@@ -211,7 +211,7 @@ function resetQuery() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleEnable(row) {
|
function handleEnable(row) {
|
||||||
enableLocation([row.id]).then((res) => {
|
enableLocation({ locationId: row.id, busNo: row.busNo }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess('启用成功');
|
proxy.$modal.msgSuccess('启用成功');
|
||||||
handleQuery();
|
handleQuery();
|
||||||
@@ -220,7 +220,7 @@ function handleEnable(row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleUnable(row) {
|
function handleUnable(row) {
|
||||||
unableLocation([row.id]).then((res) => {
|
unableLocation({ locationId: row.id, busNo: row.busNo }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess('停用成功');
|
proxy.$modal.msgSuccess('停用成功');
|
||||||
handleQuery();
|
handleQuery();
|
||||||
@@ -243,15 +243,14 @@ function getPageList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
title.value = '添加药库药房';
|
title.value = '添加库房/药房/耗材库';
|
||||||
open.value = true;
|
open.value = true;
|
||||||
editShow.value = false;
|
editShow.value = false;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handelEdit(row) {
|
function handelEdit(row) {
|
||||||
console.log(warehous_type);
|
title.value = '编辑库房/药房/耗材库';
|
||||||
title.value = '编辑药库药房';
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
editShow.value = true;
|
editShow.value = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -281,7 +280,6 @@ function submitForm() {
|
|||||||
getPageList();
|
getPageList();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
alert('456789');
|
|
||||||
updateWarehouse(form.value).then((res) => {
|
updateWarehouse(form.value).then((res) => {
|
||||||
proxy.$modal.msgSuccess('操作成功');
|
proxy.$modal.msgSuccess('操作成功');
|
||||||
open.value = false;
|
open.value = false;
|
||||||
@@ -294,11 +292,29 @@ function submitForm() {
|
|||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
function handelDelete(data) {
|
function handelDelete(data) {
|
||||||
|
proxy.$modal.confirm('是否确认删除该仓库位置?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
deleteWarehouse({ locationId: data.id }).then((res) => {
|
deleteWarehouse({ locationId: data.id, busNo: data.busNo }).then((res) => {
|
||||||
proxy.$modal.msgSuccess('操作成功');
|
if (res.code === 200) {
|
||||||
loading.value = false;
|
proxy.$modal.msgSuccess('删除成功');
|
||||||
getPageList();
|
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) {
|
export function getRegistrationfeeOne(id) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@@ -228,6 +228,7 @@
|
|||||||
placeholder="请选择提供部门"
|
placeholder="请选择提供部门"
|
||||||
check-strictly
|
check-strictly
|
||||||
clearable
|
clearable
|
||||||
|
@change="handleDeptChange"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -279,6 +280,25 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="医生:" prop="practitionerId">
|
||||||
|
<el-select
|
||||||
|
v-model="form.practitionerId"
|
||||||
|
placeholder="医生"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
@change="setInfo"
|
||||||
|
ref="doctorRef"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="doctor in doctorList"
|
||||||
|
:key="doctor.id"
|
||||||
|
:label="`${doctor.name}${doctor.qualification ? ' - '+doctor.qualification : ''}${doctor.department ? ' - '+doctor.department : ''}`"
|
||||||
|
:value="doctor.id"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="title">费用管理</div>
|
<div class="title">费用管理</div>
|
||||||
<el-row>
|
<el-row>
|
||||||
@@ -368,28 +388,13 @@ import {
|
|||||||
locationTreeSelect,
|
locationTreeSelect,
|
||||||
delRegistrationfee,
|
delRegistrationfee,
|
||||||
getInitOption,
|
getInitOption,
|
||||||
|
getPractitionerMetadata,
|
||||||
} from './components/registrationfee';
|
} from './components/registrationfee';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { proxy } = getCurrentInstance();
|
|
||||||
const registrationfeeRef = ref(null); // 初始化 ref
|
const registrationfeeRef = ref(null); // 初始化 ref
|
||||||
const {
|
const { proxy } = getCurrentInstance();
|
||||||
adm_location,
|
const { adm_location, category_code, service_type_code, specialty_code, med_chrgitm_type, fin_type_code, yb_type,} = proxy.useDict( 'adm_location', 'category_code', 'service_type_code', 'specialty_code', 'med_chrgitm_type', 'fin_type_code', 'yb_type');
|
||||||
category_code,
|
|
||||||
service_type_code,
|
|
||||||
specialty_code,
|
|
||||||
med_chrgitm_type,
|
|
||||||
fin_type_code,
|
|
||||||
yb_type,
|
|
||||||
} = proxy.useDict(
|
|
||||||
'adm_location',
|
|
||||||
'category_code',
|
|
||||||
'service_type_code',
|
|
||||||
'specialty_code',
|
|
||||||
'med_chrgitm_type',
|
|
||||||
'fin_type_code',
|
|
||||||
'yb_type'
|
|
||||||
);
|
|
||||||
|
|
||||||
const registrationfeeList = ref([]);
|
const registrationfeeList = ref([]);
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
@@ -403,12 +408,19 @@ const total = ref(0);
|
|||||||
const title = ref('');
|
const title = ref('');
|
||||||
const activeFlagOptions = ref(undefined);
|
const activeFlagOptions = ref(undefined);
|
||||||
const appointmentRequiredFlagOptions = ref(undefined);
|
const appointmentRequiredFlagOptions = ref(undefined);
|
||||||
|
const doctorList = ref([]);
|
||||||
const deptOptions = ref(undefined); // 部门树选项
|
const deptOptions = ref(undefined); // 部门树选项
|
||||||
const locationOptions = ref(undefined); // 地点树选项
|
const locationOptions = ref(undefined); // 地点树选项
|
||||||
|
|
||||||
// 是否停用
|
// 是否停用
|
||||||
const statusFlagOptions = ref(undefined);
|
const statusFlagOptions = ref(undefined);
|
||||||
|
|
||||||
|
// 获取选中的医生信息
|
||||||
|
const getSelectedDoctorInfo = computed(() => {
|
||||||
|
if (!form.value.practitionerId) return null;
|
||||||
|
return doctorList.value.find(doctor => doctor.id === form.value.practitionerId) || null;
|
||||||
|
});
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
form: {},
|
form: {},
|
||||||
queryParams: {
|
queryParams: {
|
||||||
@@ -427,7 +439,7 @@ const data = reactive({
|
|||||||
// locationId: [{ required: true, message: "地点不能为空", trigger: "blur" }],
|
// locationId: [{ required: true, message: "地点不能为空", trigger: "blur" }],
|
||||||
name: [{ required: true, message: '服务名称不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '服务名称不能为空', trigger: 'blur' }],
|
||||||
contact: [{ required: true, message: '联系人电话不能为空', trigger: 'blur' }],
|
contact: [{ required: true, message: '联系人电话不能为空', trigger: 'blur' }],
|
||||||
appointmentRequiredFlag: [{ required: true, message: '预约要求不能为空', trigger: 'blur' }],
|
practitionerId: [{ required: true, message: '医生不能为空', trigger: 'blur' }],
|
||||||
activeFlag: [{ required: true, message: '活动标识不能为空', trigger: 'blur' }],
|
activeFlag: [{ required: true, message: '活动标识不能为空', trigger: 'blur' }],
|
||||||
chargeName: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
|
chargeName: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
|
||||||
description: [{ required: true, message: '描述不能为空', trigger: 'blur' }],
|
description: [{ required: true, message: '描述不能为空', trigger: 'blur' }],
|
||||||
@@ -452,6 +464,10 @@ function getRegistrationfeeTypeList() {
|
|||||||
console.log(response, 'response');
|
console.log(response, 'response');
|
||||||
activeFlagOptions.value = response.data.activeFlagOptions; // 活动标记
|
activeFlagOptions.value = response.data.activeFlagOptions; // 活动标记
|
||||||
appointmentRequiredFlagOptions.value = response.data.appointmentRequiredFlagOptions; // 预约必填标记
|
appointmentRequiredFlagOptions.value = response.data.appointmentRequiredFlagOptions; // 预约必填标记
|
||||||
|
// 获取医生列表
|
||||||
|
if (response.data.doctorList) {
|
||||||
|
doctorList.value = response.data.doctorList;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,9 +547,60 @@ function reset() {
|
|||||||
ybType: undefined,
|
ybType: undefined,
|
||||||
title: undefined,
|
title: undefined,
|
||||||
comment: undefined,
|
comment: undefined,
|
||||||
|
practitionerId: undefined,
|
||||||
|
doctorName: undefined
|
||||||
};
|
};
|
||||||
proxy.resetForm('registrationfeeRef');
|
proxy.resetForm('registrationfeeRef');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 设置医生信息 */
|
||||||
|
function setInfo() {
|
||||||
|
const doctor = doctorList.value.find(item => item.id === form.value.practitionerId);
|
||||||
|
if (doctor) {
|
||||||
|
form.value.doctorName = doctor.name;
|
||||||
|
} else {
|
||||||
|
form.value.doctorName = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 科室变化时,加载对应医生 */
|
||||||
|
function handleDeptChange(orgId) {
|
||||||
|
if (!orgId) {
|
||||||
|
doctorList.value = []; // 清空医生
|
||||||
|
form.value.practitionerId = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用接口获取该科室下的医生
|
||||||
|
getPractitionerByOrgId(orgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据科室ID获取医生列表 */
|
||||||
|
function getPractitionerByOrgId(orgId) {
|
||||||
|
// 假设你已有类似 outpatientregistration 中的 getPractitionerMetadata 接口
|
||||||
|
// 如果 registrationfee/components/registrationfee.js 中没有,需要补充或复用
|
||||||
|
getPractitionerMetadata({ orgId }).then((response) => {
|
||||||
|
doctorList.value = response.data.records || [];
|
||||||
|
// 如果当前选中的医生不在新列表中,清空选择
|
||||||
|
if (form.value.practitionerId && !doctorList.value.some(d => d.id === form.value.practitionerId)) {
|
||||||
|
form.value.practitionerId = null;
|
||||||
|
form.value.doctorName = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果医生列表不为空且没有选中的医生,默认选中第一个医生
|
||||||
|
if (doctorList.value.length > 0 && !form.value.practitionerId) {
|
||||||
|
form.value.practitionerId = doctorList.value[0].id;
|
||||||
|
form.value.doctorName = doctorList.value[0].name;
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
doctorList.value = [];
|
||||||
|
form.value.practitionerId = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** 取消按钮 */
|
/** 取消按钮 */
|
||||||
function cancel() {
|
function cancel() {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
@@ -555,6 +622,11 @@ function handleUpdate(row) {
|
|||||||
form.value.cwTypeCode = '1011';
|
form.value.cwTypeCode = '1011';
|
||||||
open.value = true;
|
open.value = true;
|
||||||
title.value = '编辑';
|
title.value = '编辑';
|
||||||
|
|
||||||
|
// 当编辑时,如果有科室ID,自动加载对应科室的医生
|
||||||
|
if (form.value.offeredOrgId) {
|
||||||
|
getPractitionerByOrgId(form.value.offeredOrgId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
@@ -639,6 +711,11 @@ function handleView(row) {
|
|||||||
getRegistrationfeeOne(row.id).then((response) => {
|
getRegistrationfeeOne(row.id).then((response) => {
|
||||||
console.log(response, 'responsebbbb', row.id);
|
console.log(response, 'responsebbbb', row.id);
|
||||||
form.value = response.data;
|
form.value = response.data;
|
||||||
|
|
||||||
|
// 当查看详情时,如果有科室ID,自动加载对应科室的医生
|
||||||
|
if (form.value.offeredOrgId) {
|
||||||
|
getPractitionerByOrgId(form.value.offeredOrgId);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,4 +843,25 @@ init();
|
|||||||
font-size: large;
|
font-size: large;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 医生信息显示样式 */
|
||||||
|
.selected-info {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 16px;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:first-child {
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -496,11 +496,12 @@ function getDeptTree() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 查询地点下拉树结构 */
|
/** 查询地点下拉树结构 */
|
||||||
function getLocationTree() {
|
const getLocationTree = () => {
|
||||||
locationTreeSelect({ formList: '11,16' }).then((response) => {
|
locationTreeSelect({ formList: '11,16,17' }).then((res) => {
|
||||||
console.log(response, 'response查询部门下拉树结构');
|
if (res.data && res.data.records) {
|
||||||
locationOptions.value = response.data.records;
|
locationOptions.value = res.data.records
|
||||||
});
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 显示弹框
|
// 显示弹框
|
||||||
function edit() {
|
function edit() {
|
||||||
|
|||||||
@@ -86,75 +86,74 @@
|
|||||||
</el-col> -->
|
</el-col> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="diseaseList" @selection-change="handleSelectionChange">
|
<!-- 添加外层滚动容器,确保表格可以水平滚动 -->
|
||||||
|
<div class="table-scroll-container">
|
||||||
|
<!-- 移除style="width: 100%",让Element UI表格根据内容自动调整 -->
|
||||||
|
<el-table v-loading="loading" :data="diseaseList" @selection-change="handleSelectionChange" border resizable>
|
||||||
<el-table-column type="selection" width="50" align="center" />
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
<el-table-column label="编码" align="center" key="conditionCode" prop="conditionCode" />
|
<!-- 使用prop属性并设置合适的最小宽度,启用列宽调整 -->
|
||||||
|
<el-table-column label="编码" align="center" prop="conditionCode" min-width="150" />
|
||||||
|
<!-- 名称列使用标准配置 -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="名称"
|
label="名称"
|
||||||
align="center"
|
align="center"
|
||||||
key="name"
|
|
||||||
prop="name"
|
prop="name"
|
||||||
:show-overflow-tooltip="true"
|
min-width="280"
|
||||||
/>
|
/>
|
||||||
|
<!-- 其他列使用标准配置 -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="疾病分类"
|
label="疾病分类"
|
||||||
align="center"
|
align="center"
|
||||||
key="sourceEnum_enumText"
|
|
||||||
prop="sourceEnum_enumText"
|
prop="sourceEnum_enumText"
|
||||||
:show-overflow-tooltip="true"
|
min-width="180"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="拼音助记码"
|
label="拼音助记码"
|
||||||
align="center"
|
align="center"
|
||||||
key="pyStr"
|
|
||||||
prop="pyStr"
|
prop="pyStr"
|
||||||
:show-overflow-tooltip="true"
|
min-width="220"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="类型"
|
label="类型"
|
||||||
align="center"
|
align="center"
|
||||||
key="typeCode_dictText"
|
|
||||||
prop="typeCode_dictText"
|
prop="typeCode_dictText"
|
||||||
:show-overflow-tooltip="true"
|
min-width="120"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="医保编码 "
|
label="医保编码"
|
||||||
align="center"
|
align="center"
|
||||||
key="ybNo"
|
|
||||||
prop="ybNo"
|
prop="ybNo"
|
||||||
:show-overflow-tooltip="true"
|
min-width="180"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="医保标记"
|
label="医保标记"
|
||||||
align="center"
|
align="center"
|
||||||
key="ybMatchFlag"
|
|
||||||
prop="ybMatchFlag_enumText"
|
prop="ybMatchFlag_enumText"
|
||||||
|
min-width="150"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="医保对码标志"
|
label="医保对码标志"
|
||||||
align="center"
|
align="center"
|
||||||
key="ybMatchFlag"
|
|
||||||
prop="ybMatchFlag_enumText"
|
prop="ybMatchFlag_enumText"
|
||||||
|
min-width="150"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="状态"
|
label="状态"
|
||||||
align="center"
|
align="center"
|
||||||
key="statusEnum_enumText"
|
|
||||||
prop="statusEnum_enumText"
|
prop="statusEnum_enumText"
|
||||||
width="160"
|
min-width="150"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="描述"
|
label="描述"
|
||||||
align="center"
|
align="center"
|
||||||
key="description"
|
|
||||||
prop="description"
|
prop="description"
|
||||||
width="160"
|
min-width="250"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="操作"
|
label="操作"
|
||||||
align="center"
|
align="center"
|
||||||
width="150"
|
min-width="120"
|
||||||
class-name="small-padding fixed-width"
|
class-name="small-padding"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
|
||||||
@@ -163,6 +162,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
</div>
|
||||||
<pagination
|
<pagination
|
||||||
v-show="total > 0"
|
v-show="total > 0"
|
||||||
:total="total"
|
:total="total"
|
||||||
@@ -504,4 +504,40 @@ getList();
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
/* 表格外层滚动容器,确保表格整体可以水平滚动 */
|
||||||
|
.table-scroll-container {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格样式调整,移除默认的最大宽度限制 */
|
||||||
|
.table-scroll-container >>> .el-table {
|
||||||
|
min-width: 100%;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 表格外层容器的滚动条样式 */
|
||||||
|
.table-scroll-container::-webkit-scrollbar {
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-scroll-container::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(0, 120, 215, 0.7);
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-scroll-container::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: rgba(0, 120, 215, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-scroll-container::-webkit-scrollbar-track {
|
||||||
|
background: rgba(0, 0, 0, 0.15);
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 2px solid rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -854,8 +854,10 @@ function edit() {
|
|||||||
statusRestrictedOptions.value = props.statusRestrictedOptions;
|
statusRestrictedOptions.value = props.statusRestrictedOptions;
|
||||||
partAttributeEnumOptions.value = props.partAttributeEnumOptions;
|
partAttributeEnumOptions.value = props.partAttributeEnumOptions;
|
||||||
tempOrderSplitPropertyOptions.value = props.tempOrderSplitPropertyOptions;
|
tempOrderSplitPropertyOptions.value = props.tempOrderSplitPropertyOptions;
|
||||||
antibioticForm.value.antibioticCode = form.value.antibioticCode;
|
// 当后端返回null或'3'时,设置为undefined使select显示为空
|
||||||
antibioticForm.value.restrictedEnum = form.value.restrictedEnum;
|
antibioticForm.value.antibioticCode = form.value.antibioticCode === null || form.value.antibioticCode === '3' ? undefined : form.value.antibioticCode;
|
||||||
|
// 当后端返回null、'4'或4时,设置为undefined使select显示为空
|
||||||
|
antibioticForm.value.restrictedEnum = form.value.restrictedEnum === null || form.value.restrictedEnum === '4' || form.value.restrictedEnum === 4 ? undefined : form.value.restrictedEnum;
|
||||||
antibioticForm.value.dose = form.value.dose;
|
antibioticForm.value.dose = form.value.dose;
|
||||||
antibioticForm.value.maxUnit = form.value.maxUnit;
|
antibioticForm.value.maxUnit = form.value.maxUnit;
|
||||||
antibioticForm.value.minRateCode = form.value.maxRateCode;
|
antibioticForm.value.minRateCode = form.value.maxRateCode;
|
||||||
@@ -970,8 +972,9 @@ function submitForm() {
|
|||||||
proxy.$refs['medicationRef'].validate((valid) => {
|
proxy.$refs['medicationRef'].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (form.value.activeFlag == true) {
|
if (form.value.activeFlag == true) {
|
||||||
form.value.antibioticCode = antibioticForm.value.antibioticCode;
|
// 当用户清空选择时,抗生素分类设置为'3',权限级别设置为'4'
|
||||||
form.value.restrictedEnum = antibioticForm.value.restrictedEnum;
|
form.value.antibioticCode = antibioticForm.value.antibioticCode === undefined ? '3' : antibioticForm.value.antibioticCode;
|
||||||
|
form.value.restrictedEnum = antibioticForm.value.restrictedEnum === undefined ? '4' : antibioticForm.value.restrictedEnum;
|
||||||
// form.value.dose = antibioticForm.value.dose;
|
// form.value.dose = antibioticForm.value.dose;
|
||||||
// form.value.maxUnit = antibioticForm.value.maxUnit;
|
// form.value.maxUnit = antibioticForm.value.maxUnit;
|
||||||
form.value.minRateCode = antibioticForm.value.minRateCode;
|
form.value.minRateCode = antibioticForm.value.minRateCode;
|
||||||
|
|||||||
@@ -182,6 +182,8 @@
|
|||||||
:paymentId="paymentId"
|
:paymentId="paymentId"
|
||||||
:details="details"
|
:details="details"
|
||||||
:chargedItems="chargedItems"
|
:chargedItems="chargedItems"
|
||||||
|
:feeType="patientInfo.medfeePaymtdCode"
|
||||||
|
:medfee_paymtd_code="medfee_paymtd_code"
|
||||||
@refresh="getPatientList"
|
@refresh="getPatientList"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -203,11 +205,13 @@ import useUserStore from '@/store/modules/user';
|
|||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const { medfee_paymtd_code } = proxy.useDict('medfee_paymtd_code');
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
statusEnum: 1,
|
statusEnum: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalAmounts = ref(0);
|
const totalAmounts = ref(0);
|
||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
const patientList = ref([]);
|
const patientList = ref([]);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<el-text size="large" style="display: block; margin-bottom: 15px">
|
<el-text size="large" style="display: block; margin-bottom: 15px">
|
||||||
退费日期:{{ currentDate }}
|
退费日期:{{ currentDate }}
|
||||||
</el-text>
|
</el-text>
|
||||||
<el-text size="large">费用性质:{{ '自费' }}</el-text>
|
<el-text size="large">费用性质:{{ getFeeTypeText }}</el-text>
|
||||||
<div class="amount-row">
|
<div class="amount-row">
|
||||||
<el-text size="large">应退金额:</el-text>
|
<el-text size="large">应退金额:</el-text>
|
||||||
<el-text size="large" type="primary" class="amount">
|
<el-text size="large" type="primary" class="amount">
|
||||||
@@ -160,6 +160,14 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
|
medfee_paymtd_code: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
feeType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
@@ -324,6 +332,23 @@ const returnedAmount = computed(() => {
|
|||||||
function close() {
|
function close() {
|
||||||
emit('close');
|
emit('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取费用性质文本
|
||||||
|
const getFeeTypeText = computed(() => {
|
||||||
|
if (!props.medfee_paymtd_code || !Array.isArray(props.medfee_paymtd_code)) {
|
||||||
|
return '自费';
|
||||||
|
}
|
||||||
|
// 如果有feeType,根据feeType查找对应的文本
|
||||||
|
if (props.feeType) {
|
||||||
|
const dict = props.medfee_paymtd_code.find(item => item.value === props.feeType);
|
||||||
|
return dict ? dict.label : '自费';
|
||||||
|
}
|
||||||
|
// 如果只有一个选项,直接返回第一个选项的文本
|
||||||
|
if (props.medfee_paymtd_code.length === 1) {
|
||||||
|
return props.medfee_paymtd_code[0].label || '自费';
|
||||||
|
}
|
||||||
|
return '自费';
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -178,6 +178,8 @@
|
|||||||
:paymentId="paymentId"
|
:paymentId="paymentId"
|
||||||
:chargeItemIds="chargeItemIdList"
|
:chargeItemIds="chargeItemIdList"
|
||||||
:details="details"
|
:details="details"
|
||||||
|
:medfee_paymtd_code="medfee_paymtd_code"
|
||||||
|
:feeType="patientInfo.medfeePaymtdCode"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -197,6 +199,8 @@ import RefundDialog from './components/refundDialog.vue';
|
|||||||
import Decimal from 'decimal.js';
|
import Decimal from 'decimal.js';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
// 获取费用性质字典
|
||||||
|
const { medfee_paymtd_code } = proxy.useDict('medfee_paymtd_code');
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<el-text size="large" style="display: block; margin-bottom: 15px">
|
<el-text size="large" style="display: block; margin-bottom: 15px">
|
||||||
收费日期:{{ currentDate }}
|
收费日期:{{ currentDate }}
|
||||||
</el-text>
|
</el-text>
|
||||||
<el-text size="large">费用性质:{{ '自费' }}</el-text>
|
<el-text size="large">费用性质:{{ getFeeTypeText }}</el-text>
|
||||||
<div class="amount-row">
|
<div class="amount-row">
|
||||||
<el-text size="large">应收金额:</el-text>
|
<el-text size="large">应收金额:</el-text>
|
||||||
<el-text size="large" type="primary" class="amount">
|
<el-text size="large" type="primary" class="amount">
|
||||||
@@ -97,6 +97,23 @@ import { computed, watch, reactive, ref, getCurrentInstance, nextTick } from 'vu
|
|||||||
import { Delete } from '@element-plus/icons-vue';
|
import { Delete } from '@element-plus/icons-vue';
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
// 获取费用性质文本
|
||||||
|
const getFeeTypeText = computed(() => {
|
||||||
|
if (!props.medfee_paymtd_code || !Array.isArray(props.medfee_paymtd_code)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
// 如果有feeType,根据feeType查找对应的文本
|
||||||
|
if (props.feeType) {
|
||||||
|
const dict = props.medfee_paymtd_code.find(item => item.value === props.feeType);
|
||||||
|
return dict ? dict.label : '';
|
||||||
|
}
|
||||||
|
// 如果只有一个选项,直接返回第一个选项的文本
|
||||||
|
if (props.medfee_paymtd_code.length === 1) {
|
||||||
|
return props.medfee_paymtd_code[0].label || '';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
open: {
|
open: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -130,6 +147,14 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
|
medfee_paymtd_code: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
feeType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
@@ -271,19 +296,17 @@ function submit() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dialogLoading.value = true;
|
dialogLoading.value = true;
|
||||||
|
// 根据费用性质动态设置合同编号
|
||||||
|
if (props.transformedData && props.transformedData.accountFormData) {
|
||||||
|
// 直接使用传入的feeType作为contractNo
|
||||||
|
// 如果feeType存在就使用,否则使用patientInfo中的medfeePaymtdCode,最后默认使用'0000'
|
||||||
|
props.transformedData.accountFormData.contractNo = props.feeType || props.patientInfo?.medfeePaymtdCode || '0000';
|
||||||
|
}
|
||||||
savePayment({
|
savePayment({
|
||||||
// paymentEnum: 0,
|
|
||||||
// kindEnum: 1,
|
|
||||||
// patientId: props.patientInfo.patientId,
|
|
||||||
// encounterId: props.patientInfo.encounterId,
|
|
||||||
// chargeItemIds: props.chargeItemIds,
|
|
||||||
outpatientRegistrationAddParam: props.transformedData,
|
outpatientRegistrationAddParam: props.transformedData,
|
||||||
chrgBchno: props.chrgBchno,
|
chrgBchno: props.chrgBchno,
|
||||||
busNo: props.registerBusNo,
|
busNo: props.registerBusNo,
|
||||||
paymentDetails: formData.selfPay,
|
paymentDetails: formData.selfPay,
|
||||||
// ybFlag: '0',
|
|
||||||
// eleFlag: '0',
|
|
||||||
// returnedAmount: parseFloat(returnedAmount.value),
|
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
|
|||||||
@@ -214,3 +214,30 @@ export function gerPreInfo(userMaessage) {
|
|||||||
params: userMaessage
|
params: userMaessage
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据就诊卡号查询挂号记录
|
||||||
|
* 注意:此接口可能不存在,实际使用getOutpatientRegistrationCurrent接口
|
||||||
|
* 保留此函数以便将来使用,目前使用getOutpatientRegistrationCurrent替代
|
||||||
|
*/
|
||||||
|
export function getRegistrationByCardNo(query) {
|
||||||
|
// 如果后端提供了专门的接口,可以取消注释使用
|
||||||
|
// return request({
|
||||||
|
// url: '/charge-manage/register/encounter-by-card',
|
||||||
|
// method: 'get',
|
||||||
|
// params: query
|
||||||
|
// })
|
||||||
|
// 暂时使用现有的接口
|
||||||
|
return getOutpatientRegistrationCurrent(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 补打挂号
|
||||||
|
*/
|
||||||
|
export function reprintRegistration(data) {
|
||||||
|
return request({
|
||||||
|
url: '/charge-manage/register/reprint',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,48 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- <div class="app-container"> -->
|
<!-- <div class="app-container"> -->
|
||||||
<!-- 添加或修改对话框 -->
|
<!-- 添加或修改对话框 -->
|
||||||
<el-dialog :title="title" v-model="visible" width="980px" append-to-body>
|
<el-dialog :title="title" v-model="visible" width="1020px" append-to-body>
|
||||||
<el-form ref="patientRef" :model="form" :rules="rules" label-width="100px">
|
<el-form ref="patientRef" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||||
<el-row>
|
<!-- 第一行:姓名、民族、性别 -->
|
||||||
|
<el-row :gutter="10">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="姓名" prop="name">
|
<el-form-item label="姓名" prop="name" label-width="80px">
|
||||||
<el-input v-model="form.name" clearable :disabled="isViewMode" />
|
<el-input v-model="form.name" clearable :disabled="isViewMode" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="性别" prop="genderEnum">
|
<el-form-item label="民族" prop="nationalityCode" label-width="80px">
|
||||||
<el-radio-group v-model="form.genderEnum" :disabled="isViewMode">
|
|
||||||
<el-radio
|
|
||||||
v-for="item in administrativegenderList"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.value"
|
|
||||||
>
|
|
||||||
{{ item.info }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<!-- <el-col :span="8">
|
|
||||||
<el-form-item label="活动标识" prop="tempFlag">
|
|
||||||
<el-radio-group v-model="form.tempFlag" :disabled="isViewMode">
|
|
||||||
<el-radio v-for="dict in patient_temp_flag" :key="dict.value" :label="dict.value">
|
|
||||||
{{ dict.label }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col> -->
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="联系方式" prop="phone">
|
|
||||||
<el-input v-model="form.phone" clearable :disabled="isViewMode" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="证件号码" prop="idCard">
|
|
||||||
<el-input v-model="form.idCard" clearable :disabled="isViewMode" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="民族" prop="nationalityCode">
|
|
||||||
<el-select v-model="form.nationalityCode" clearable filterable :disabled="isViewMode">
|
<el-select v-model="form.nationalityCode" clearable filterable :disabled="isViewMode">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in nationality_code"
|
v-for="item in nationality_code"
|
||||||
@@ -54,10 +23,22 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="卡类别" prop="typeCode">
|
<el-form-item label="性别" prop="genderEnum" label-width="80px">
|
||||||
|
<el-radio-group v-model="form.genderEnum" :disabled="isViewMode">
|
||||||
|
<el-radio :label="0">男性</el-radio>
|
||||||
|
<el-radio :label="1">女性</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第二行:证件类别、证件号码、*年龄 -->
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="证件类别" prop="typeCode" label-width="80px">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.typeCode"
|
v-model="form.typeCode"
|
||||||
placeholder="卡类别"
|
placeholder="就诊卡"
|
||||||
clearable
|
clearable
|
||||||
:disabled="isViewMode"
|
:disabled="isViewMode"
|
||||||
>
|
>
|
||||||
@@ -71,15 +52,36 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="就诊卡号" prop="identifierNo">
|
<el-form-item label="证件号码" prop="idCard" label-width="80px">
|
||||||
<el-input v-model="form.identifierNo" clearable :disabled="isViewMode" />
|
<el-input v-model="form.idCard" clearable :disabled="isViewMode" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="国家编码" prop="countryCode">
|
<el-form-item label="年龄" prop="age" label-width="80px">
|
||||||
|
<el-input
|
||||||
|
v-model="form.age"
|
||||||
|
:disabled="isViewMode"
|
||||||
|
@input="handleAgeInput"
|
||||||
|
placeholder="请输入龄"
|
||||||
|
>
|
||||||
|
<template #suffix>岁</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第三行:国家编码、*联系方式、工作单位 -->
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="国家编码" prop="countryCode" label-width="80px">
|
||||||
<el-input v-model="form.countryCode" clearable :disabled="isViewMode" />
|
<el-input v-model="form.countryCode" clearable :disabled="isViewMode" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="联系方式" prop="phone" label-width="80px">
|
||||||
|
<el-input v-model="form.phone" clearable :disabled="isViewMode" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="出生日期" prop="birthDate">
|
<el-form-item label="出生日期" prop="birthDate">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
@@ -94,12 +96,14 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<!-- <el-col :span="6">
|
|
||||||
<el-form-item label="年龄" prop="age">
|
<!-- 第三行:就诊卡号、国家编码、出生日期 -->
|
||||||
<el-input v-model="form.age" clearable :disabled="isViewMode"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col> -->
|
|
||||||
<el-row>
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="就诊卡号" prop="identifierNo">
|
||||||
|
<el-input v-model="form.identifierNo" clearable :disabled="isViewMode" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="职业" prop="prfsEnum">
|
<el-form-item label="职业" prop="prfsEnum">
|
||||||
<el-select v-model="form.prfsEnum" placeholder="职业" clearable :disabled="isViewMode">
|
<el-select v-model="form.prfsEnum" placeholder="职业" clearable :disabled="isViewMode">
|
||||||
@@ -117,48 +121,8 @@
|
|||||||
<el-input v-model="form.workCompany" clearable :disabled="isViewMode" />
|
<el-input v-model="form.workCompany" clearable :disabled="isViewMode" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="年龄" prop="age">
|
|
||||||
<el-input
|
|
||||||
v-model="form.age"
|
|
||||||
:disabled="isViewMode"
|
|
||||||
@input="handleAgeInput"
|
|
||||||
placeholder="请输入年龄"
|
|
||||||
>
|
|
||||||
<template #suffix>岁</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="联系人" prop="linkName">
|
|
||||||
<el-input v-model="form.linkName" clearable :disabled="isViewMode" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="联系人关系" prop="linkRelationCode">
|
|
||||||
<el-select
|
|
||||||
v-model="form.linkRelationCode"
|
|
||||||
placeholder="联系人关系"
|
|
||||||
clearable
|
|
||||||
:disabled="isViewMode"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in familyrelationshiptypeList"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.info"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="联系人电话" prop="linkRelationCode">
|
|
||||||
<el-input v-model="form.linkTelcom" clearable :disabled="isViewMode" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<!-- 地址选择、详细地址 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="地址选择" prop="addressSelect">
|
<el-form-item label="地址选择" prop="addressSelect">
|
||||||
@@ -176,12 +140,14 @@
|
|||||||
</el-cascader>
|
</el-cascader>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="16">
|
||||||
<el-form-item label="详细地址" prop="address">
|
<el-form-item label="详细地址" prop="address">
|
||||||
<el-input v-model="form.address" clearable :disabled="isViewMode" />
|
<el-input v-model="form.address" clearable :disabled="isViewMode" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第六行:血型ABO、血型RH -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="血型ABO" prop="bloodAbo">
|
<el-form-item label="血型ABO" prop="bloodAbo">
|
||||||
@@ -213,6 +179,8 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第七行:婚姻状态、死亡时间 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="婚姻状态" prop="maritalStatusEnum">
|
<el-form-item label="婚姻状态" prop="maritalStatusEnum">
|
||||||
@@ -231,7 +199,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="16">
|
||||||
<el-form-item label="死亡时间" prop="deceasedDate">
|
<el-form-item label="死亡时间" prop="deceasedDate">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="form.deceasedDate"
|
v-model="form.deceasedDate"
|
||||||
@@ -244,6 +212,59 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第八行:监护人、监护人关系、监护人电话 -->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="监护人" prop="guardianName">
|
||||||
|
<el-input v-model="form.guardianName" clearable :disabled="isViewMode" placeholder="请输入监护人" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="监护人关系" prop="guardianRelation">
|
||||||
|
<el-select v-model="form.guardianRelation" placeholder="监护人关系" clearable :disabled="isViewMode">
|
||||||
|
<el-option
|
||||||
|
v-for="item in familyrelationshiptypeList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.info"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="监护人电话" prop="guardianPhone">
|
||||||
|
<el-input v-model="form.guardianPhone" clearable :disabled="isViewMode" placeholder="请输入监护人电话" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第九行:监护人证件类型、监护人证件号码 -->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="监护人证件类型" prop="guardianIdType">
|
||||||
|
<el-select v-model="form.guardianIdType" placeholder="请选择" clearable :disabled="isViewMode">
|
||||||
|
<el-option label="身份证" value="id_card" />
|
||||||
|
<el-option label="护照" value="passport" />
|
||||||
|
<el-option label="其他" value="other" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item label="监护人证件号码" prop="guardianIdNo">
|
||||||
|
<el-input v-model="form.guardianIdNo" clearable :disabled="isViewMode" placeholder="请输入监护人证件号码" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第十行:监护人地址 -->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="监护人地址" prop="guardianAddress">
|
||||||
|
<el-input v-model="form.guardianAddress" clearable :disabled="isViewMode" placeholder="请输入监护人详细地址" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
@@ -361,6 +382,23 @@ const validateIdCard = (rule, value, callback) => {
|
|||||||
callback(); // 校验通过
|
callback(); // 校验通过
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监护人信息条件验证函数
|
||||||
|
const validateGuardianInfo = (rule, value, callback) => {
|
||||||
|
// 只有当年龄小于18岁时才验证监护人信息
|
||||||
|
if (form.value.age) {
|
||||||
|
// 提取年龄数字部分
|
||||||
|
const ageMatch = form.value.age.toString().match(/\d+/);
|
||||||
|
if (ageMatch) {
|
||||||
|
const age = parseInt(ageMatch[0]);
|
||||||
|
// 如果年龄小于18岁,监护人信息必须填写
|
||||||
|
if (age < 18 && !value) {
|
||||||
|
return callback(new Error('年龄小于18岁的患者必须填写监护人信息'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 18岁及以上患者或年龄未填写时,跳过验证
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
isViewMode: false,
|
isViewMode: false,
|
||||||
@@ -378,11 +416,16 @@ const data = reactive({
|
|||||||
phone: [{ required: true, message: '联系方式不能为空', trigger: 'change' }],
|
phone: [{ required: true, message: '联系方式不能为空', trigger: 'change' }],
|
||||||
identifierNo: [{ required: true, message: '就诊卡号不能为空', trigger: 'change' }],
|
identifierNo: [{ required: true, message: '就诊卡号不能为空', trigger: 'change' }],
|
||||||
idCard: [
|
idCard: [
|
||||||
{ required: true, message: '证件号码不能为空', trigger: 'change' },
|
{ required: false, message: '证件号码不能为空', trigger: 'change' },
|
||||||
{ validator: validateIdCard, trigger: 'blur' },
|
{ validator: validateIdCard, trigger: 'blur' },
|
||||||
{ validator: validateUniquePatient, trigger: 'blur' }
|
{ validator: validateUniquePatient, trigger: 'blur' }
|
||||||
],
|
],
|
||||||
birthDate: [{ required: false, message: '请选择出生日期', trigger: 'change' }],
|
birthDate: [{ required: false, message: '请选择出生日期', trigger: 'change' }],
|
||||||
|
// 监护人信息条件验证规则
|
||||||
|
guardianName: [{ validator: validateGuardianInfo, trigger: 'blur' }],
|
||||||
|
guardianRelation: [{ validator: validateGuardianInfo, trigger: 'blur' }],
|
||||||
|
guardianPhone: [{ validator: validateGuardianInfo, trigger: 'blur' }],
|
||||||
|
guardianIdNo: [{ validator: validateGuardianInfo, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -572,13 +615,16 @@ function submitForm() {
|
|||||||
form.value.idCard.toString().substring(12, 14);
|
form.value.idCard.toString().substring(12, 14);
|
||||||
console.log(form.value.birthDate, 123);
|
console.log(form.value.birthDate, 123);
|
||||||
}
|
}
|
||||||
|
// 进行表单验证
|
||||||
proxy.$refs['patientRef'].validate((valid) => {
|
proxy.$refs['patientRef'].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
// 使用
|
// 提交表单前的处理
|
||||||
if (!form.value.identifierNo) {
|
if (!form.value.identifierNo) {
|
||||||
form.value.typeCode = undefined;
|
form.value.typeCode = undefined;
|
||||||
}
|
}
|
||||||
form.value.address = getAddress(form);
|
form.value.address = getAddress(form);
|
||||||
|
|
||||||
|
// 提交新增患者请求
|
||||||
addPatient(form.value).then((response) => {
|
addPatient(form.value).then((response) => {
|
||||||
proxy.$modal.msgSuccess('新增成功');
|
proxy.$modal.msgSuccess('新增成功');
|
||||||
getPatientInfo(response.data.idCard);
|
getPatientInfo(response.data.idCard);
|
||||||
@@ -624,4 +670,12 @@ defineExpose({
|
|||||||
line-height: 1.2; /* 调整行间距 */
|
line-height: 1.2; /* 调整行间距 */
|
||||||
margin-bottom: 4px; /* 调整 label 和输入框之间的间距 */
|
margin-bottom: 4px; /* 调整 label 和输入框之间的间距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 防止表单标签换行 */
|
||||||
|
:deep(.el-form-item__label) {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: visible;
|
||||||
|
text-overflow: clip;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<el-text size="large" style="display: block; margin-bottom: 15px">
|
<el-text size="large" style="display: block; margin-bottom: 15px">
|
||||||
退费日期:{{ currentDate }}
|
退费日期:{{ currentDate }}
|
||||||
</el-text>
|
</el-text>
|
||||||
<el-text size="large">费用性质:{{ '自费' }}</el-text>
|
<el-text size="large">费用性质:{{ getFeeTypeText }}</el-text>
|
||||||
<div class="amount-row">
|
<div class="amount-row">
|
||||||
<el-text size="large">应退金额:</el-text>
|
<el-text size="large">应退金额:</el-text>
|
||||||
<el-text size="large" type="primary" class="amount">
|
<el-text size="large" type="primary" class="amount">
|
||||||
@@ -111,6 +111,24 @@
|
|||||||
import { cancelRegister } from './outpatientregistration';
|
import { cancelRegister } from './outpatientregistration';
|
||||||
import { computed, watch, reactive, ref, getCurrentInstance } from 'vue';
|
import { computed, watch, reactive, ref, getCurrentInstance } from 'vue';
|
||||||
import { Delete } from '@element-plus/icons-vue';
|
import { Delete } from '@element-plus/icons-vue';
|
||||||
|
import useUserStore from '@/store/modules/user';
|
||||||
|
import { formatDateStr } from '@/utils/index';
|
||||||
|
|
||||||
|
// 获取费用性质文本
|
||||||
|
const getFeeTypeText = computed(() => {
|
||||||
|
// 优先使用从挂号记录传递过来的费用性质名称
|
||||||
|
if (props.contractName) {
|
||||||
|
return props.contractName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有传递名称,则根据费用性质代码查找
|
||||||
|
if (props.feeType && props.medfee_paymtd_code && Array.isArray(props.medfee_paymtd_code)) {
|
||||||
|
const dictItem = props.medfee_paymtd_code.find(item => item.value === props.feeType);
|
||||||
|
return dictItem ? dictItem.label : '自费';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '自费'; // 默认值
|
||||||
|
});
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
open: {
|
open: {
|
||||||
@@ -135,10 +153,27 @@ const props = defineProps({
|
|||||||
type: [],
|
type: [],
|
||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
|
medfee_paymtd_code: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
feeType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
contractName: {
|
||||||
|
type: String,
|
||||||
|
default: '', // 新增:接收费用性质名称
|
||||||
|
},
|
||||||
|
registerInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}), // 原挂号记录信息
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const reason = ref('');
|
const reason = ref('');
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
totalAmount: 0,
|
totalAmount: 0,
|
||||||
@@ -167,6 +202,17 @@ function submit() {
|
|||||||
proxy.$modal.msgError('请输入正确的金额');
|
proxy.$modal.msgError('请输入正确的金额');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取当前时间作为退号操作日期
|
||||||
|
const returnDate = formatDateStr(new Date(), 'YYYY-MM-DD HH:mm:ss');
|
||||||
|
|
||||||
|
// 获取当前用户信息作为操作工号
|
||||||
|
const operatorId = userStore.id || userStore.name || '';
|
||||||
|
const operatorName = userStore.name || userStore.nickName || '';
|
||||||
|
|
||||||
|
// 计算退款总金额
|
||||||
|
const refundAmount = formData.selfPay.reduce((sum, item) => sum + (Number(item.amount) || 0), 0);
|
||||||
|
|
||||||
cancelRegister({
|
cancelRegister({
|
||||||
paymentEnum: 0,
|
paymentEnum: 0,
|
||||||
kindEnum: 1,
|
kindEnum: 1,
|
||||||
@@ -178,6 +224,18 @@ function submit() {
|
|||||||
reason: reason.value,
|
reason: reason.value,
|
||||||
ybFlag: '1',
|
ybFlag: '1',
|
||||||
eleFlag: '0',
|
eleFlag: '0',
|
||||||
|
// 退号操作记录信息
|
||||||
|
returnDate: returnDate, // 退号操作日期
|
||||||
|
operatorId: operatorId, // 退号操作工号(用户ID)
|
||||||
|
operatorName: operatorName, // 退号操作人姓名
|
||||||
|
refundAmount: refundAmount, // 退款金额
|
||||||
|
// 原挂号信息
|
||||||
|
registerTime: props.registerInfo?.registerTime || '', // 原挂号时间
|
||||||
|
registerAmount: props.registerInfo?.totalPrice || props.totalAmount, // 原挂号金额
|
||||||
|
// 患者信息
|
||||||
|
patientName: props.registerInfo?.patientName || '', // 患者姓名
|
||||||
|
patientAge: props.registerInfo?.age || '', // 患者年龄
|
||||||
|
patientGender: props.registerInfo?.genderEnum_enumText || '', // 患者性别
|
||||||
// returnedAmount: parseFloat(returnedAmount.value),
|
// returnedAmount: parseFloat(returnedAmount.value),
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
|
|||||||
@@ -0,0 +1,400 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog title="补打挂号" v-model="dialogVisible" width="900px" append-to-body destroy-on-close>
|
||||||
|
<div v-loading="loading">
|
||||||
|
<!-- 搜索区域 -->
|
||||||
|
<el-form :model="searchForm" :inline="true" style="margin-bottom: 20px">
|
||||||
|
<el-form-item label="就诊卡号:">
|
||||||
|
<el-input
|
||||||
|
v-model="searchForm.cardNo"
|
||||||
|
placeholder="请输入就诊卡号"
|
||||||
|
style="width: 240px"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleSearch"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<el-button icon="Search" @click="handleSearch" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 挂号记录列表 -->
|
||||||
|
<el-table
|
||||||
|
v-if="registrationList.length > 0"
|
||||||
|
:data="registrationList"
|
||||||
|
border
|
||||||
|
max-height="300"
|
||||||
|
highlight-current-row
|
||||||
|
@row-click="handleRowClick"
|
||||||
|
style="margin-bottom: 20px"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
|
<el-table-column label="患者姓名" prop="patientName" width="120" align="center" />
|
||||||
|
<el-table-column label="就诊卡号" prop="identifierNo" width="150" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<!-- 优化就诊卡号显示,尝试多种可能的字段 -->
|
||||||
|
{{ getCardNoDisplay(scope.row) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="就诊科室" prop="organizationName" align="center" />
|
||||||
|
<el-table-column label="医生" prop="practitionerName" width="120" align="center" />
|
||||||
|
<el-table-column label="挂号费" prop="price" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ (scope.row.price || scope.row.registrationFee) ? parseFloat(scope.row.price || scope.row.registrationFee).toFixed(2) + ' 元' : '0.00 元' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="诊疗费" prop="activityPrice" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ (scope.row.activityPrice || scope.row.diagnosisFee) ? parseFloat(scope.row.activityPrice || scope.row.diagnosisFee).toFixed(2) + ' 元' : '0.00 元' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="总金额" prop="totalPrice" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.totalPrice ? scope.row.totalPrice.toFixed(2) + ' 元' : '0.00 元' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="挂号时间" prop="registerTime" width="180" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.registerTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<el-empty v-if="!loading && registrationList.length === 0 && hasSearched" description="未找到挂号记录" />
|
||||||
|
|
||||||
|
<!-- 补打挂号表单 -->
|
||||||
|
<el-divider>补打信息</el-divider>
|
||||||
|
<el-form :model="form" :rules="rules" ref="reprintFormRef" label-width="120px">
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="就诊卡号:" prop="cardNo">
|
||||||
|
<el-input v-model="form.cardNo" placeholder="就诊卡号" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="姓名:" prop="name">
|
||||||
|
<el-input v-model="form.name" placeholder="姓名" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="就诊科室:" prop="organizationName">
|
||||||
|
<el-input v-model="form.organizationName" placeholder="就诊科室" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="医生:" prop="practitionerName">
|
||||||
|
<el-input v-model="form.practitionerName" placeholder="医生" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="挂号费:" prop="price">
|
||||||
|
<el-input v-model="form.price" placeholder="挂号费" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="诊疗费:" prop="activityPrice">
|
||||||
|
<el-input v-model="form.activityPrice" placeholder="诊疗费" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="总金额:" prop="totalPrice">
|
||||||
|
<el-input v-model="form.totalPrice" placeholder="总金额" :disabled="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="就诊时间:" prop="visitTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.visitTime"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="就诊时间"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
style="width: 100%"
|
||||||
|
:disabled="true"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleSubmit" :disabled="loading || !form.cardNo">确 定</el-button>
|
||||||
|
<el-button @click="handleCancel" :disabled="loading">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, getCurrentInstance, watch } from 'vue';
|
||||||
|
import { getOutpatientRegistrationCurrent, getOutpatientRegistrationList, reprintRegistration } from './outpatientregistration';
|
||||||
|
import { parseTime } from '@/utils/his';
|
||||||
|
import { formatDateStr } from '@/utils/index';
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
const hasSearched = ref(false);
|
||||||
|
const registrationList = ref([]);
|
||||||
|
const reprintFormRef = ref(null);
|
||||||
|
|
||||||
|
const searchForm = reactive({
|
||||||
|
cardNo: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
cardNo: '',
|
||||||
|
name: '',
|
||||||
|
organizationName: '',
|
||||||
|
practitionerName: '',
|
||||||
|
price: '',
|
||||||
|
activityPrice: '',
|
||||||
|
totalPrice: '',
|
||||||
|
visitTime: '',
|
||||||
|
encounterId: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
cardNo: [{ required: true, message: '就诊卡号不能为空', trigger: 'blur' }],
|
||||||
|
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
||||||
|
organizationName: [{ required: true, message: '就诊科室不能为空', trigger: 'blur' }],
|
||||||
|
practitionerName: [{ required: true, message: '医生不能为空', trigger: 'blur' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听open属性变化
|
||||||
|
watch(
|
||||||
|
() => props.open,
|
||||||
|
(newVal) => {
|
||||||
|
dialogVisible.value = newVal;
|
||||||
|
if (newVal) {
|
||||||
|
// 打开对话框时重置表单
|
||||||
|
resetForm();
|
||||||
|
resetSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听dialogVisible变化,同步到父组件
|
||||||
|
watch(dialogVisible, (newVal) => {
|
||||||
|
if (!newVal) {
|
||||||
|
emit('close');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取就诊卡号用于显示
|
||||||
|
function getCardNoDisplay(row) {
|
||||||
|
// 调试信息,打印所有可能的卡号字段
|
||||||
|
console.log('解析卡号字段:', {
|
||||||
|
identifierNo: row.identifierNo,
|
||||||
|
cardNo: row.cardNo,
|
||||||
|
patientId: row.patientId,
|
||||||
|
encounterNo: row.encounterNo,
|
||||||
|
visitNo: row.visitNo,
|
||||||
|
patient: row.patient ? {
|
||||||
|
identifierNo: row.patient.identifierNo,
|
||||||
|
cardNo: row.patient.cardNo
|
||||||
|
} : null
|
||||||
|
});
|
||||||
|
|
||||||
|
// 尝试所有可能的卡号字段
|
||||||
|
const cardNo =
|
||||||
|
row.identifierNo ||
|
||||||
|
row.cardNo ||
|
||||||
|
(row.patient && (row.patient.identifierNo || row.patient.cardNo)) ||
|
||||||
|
row.encounterNo ||
|
||||||
|
row.visitNo ||
|
||||||
|
'-';
|
||||||
|
|
||||||
|
return cardNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索挂号记录
|
||||||
|
async function handleSearch() {
|
||||||
|
if (!searchForm.cardNo) {
|
||||||
|
proxy.$modal.msgWarning('请输入就诊卡号');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
hasSearched.value = true;
|
||||||
|
registrationList.value = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 简化搜索逻辑,直接使用就诊卡号作为searchKey查询
|
||||||
|
const endDate = new Date();
|
||||||
|
const startDate = new Date();
|
||||||
|
startDate.setFullYear(startDate.getFullYear() - 1);
|
||||||
|
|
||||||
|
const queryParams = {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
registerTimeSTime: formatDateStr(startDate, 'YYYY-MM-DD') + ' 00:00:00',
|
||||||
|
registerTimeETime: formatDateStr(endDate, 'YYYY-MM-DD') + ' 23:59:59',
|
||||||
|
searchKey: searchForm.cardNo // 直接使用就诊卡号作为搜索关键字
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('搜索参数:', queryParams);
|
||||||
|
|
||||||
|
// 调用API查询挂号记录
|
||||||
|
const response = await getOutpatientRegistrationCurrent(queryParams);
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
let records = response.data.records || response.data || [];
|
||||||
|
|
||||||
|
console.log('查询到的挂号记录数量:', records.length);
|
||||||
|
|
||||||
|
// 记录原始数据用于调试
|
||||||
|
if (records.length > 0) {
|
||||||
|
console.log('查询到的记录详情:', records.map(r => ({
|
||||||
|
id: r.id || r.encounterId,
|
||||||
|
identifierNo: r.identifierNo,
|
||||||
|
cardNo: r.cardNo,
|
||||||
|
patientName: r.patientName || r.name,
|
||||||
|
patient: r.patient
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示所有查询到的记录,不进行严格过滤
|
||||||
|
registrationList.value = records;
|
||||||
|
|
||||||
|
if (records.length === 0) {
|
||||||
|
proxy.$modal.msgWarning('未查询到相关挂号记录,请检查就诊卡号是否正确');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
proxy.$modal.msgWarning('查询失败: ' + (response.msg || '接口返回异常'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('查询挂号记录异常:', error);
|
||||||
|
proxy.$modal.msgError('查询出错: ' + (error.message || '网络异常'));
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击表格行,自动填充表单
|
||||||
|
function handleRowClick(row) {
|
||||||
|
console.log('点击的记录:', row);
|
||||||
|
|
||||||
|
// 使用getCardNoDisplay函数获取就诊卡号,确保与表格显示一致
|
||||||
|
const cardNo = getCardNoDisplay(row);
|
||||||
|
form.cardNo = cardNo !== '-' ? cardNo : '';
|
||||||
|
|
||||||
|
// 其他表单字段填充
|
||||||
|
form.name = row.patientName || row.name || (row.patient ? row.patient.name : '') || '';
|
||||||
|
form.organizationName = row.organizationName || '';
|
||||||
|
form.practitionerName = row.practitionerName || '';
|
||||||
|
|
||||||
|
// 价格相关字段
|
||||||
|
form.price = row.price ? parseFloat(row.price).toFixed(2) : (row.registrationFee ? parseFloat(row.registrationFee).toFixed(2) : '0.00');
|
||||||
|
form.activityPrice = row.activityPrice ? parseFloat(row.activityPrice).toFixed(2) : (row.diagnosisFee ? parseFloat(row.diagnosisFee).toFixed(2) : '0.00');
|
||||||
|
form.totalPrice = row.totalPrice ? parseFloat(row.totalPrice).toFixed(2) : '0.00';
|
||||||
|
|
||||||
|
// 就诊时间设置为当前时间
|
||||||
|
const now = new Date();
|
||||||
|
form.visitTime = formatDateTime(now);
|
||||||
|
form.encounterId = row.encounterId || row.id || '';
|
||||||
|
|
||||||
|
console.log('填充的表单数据:', form);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化日期时间
|
||||||
|
function formatDateTime(date) {
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交补打挂号
|
||||||
|
function handleSubmit() {
|
||||||
|
reprintFormRef.value.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true;
|
||||||
|
const submitData = {
|
||||||
|
encounterId: form.encounterId,
|
||||||
|
cardNo: form.cardNo,
|
||||||
|
name: form.name,
|
||||||
|
organizationName: form.organizationName,
|
||||||
|
practitionerName: form.practitionerName,
|
||||||
|
price: parseFloat(form.price),
|
||||||
|
activityPrice: parseFloat(form.activityPrice),
|
||||||
|
totalPrice: parseFloat(form.totalPrice),
|
||||||
|
visitTime: form.visitTime,
|
||||||
|
};
|
||||||
|
reprintRegistration(submitData)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
proxy.$modal.msgSuccess('补打挂号成功');
|
||||||
|
emit('close', 'success');
|
||||||
|
dialogVisible.value = false;
|
||||||
|
} else {
|
||||||
|
proxy.$modal.msgError(res.msg || '补打挂号失败');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('补打挂号失败:', error);
|
||||||
|
proxy.$modal.msgError('补打挂号失败');
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
function handleCancel() {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
function resetForm() {
|
||||||
|
Object.assign(form, {
|
||||||
|
cardNo: '',
|
||||||
|
name: '',
|
||||||
|
organizationName: '',
|
||||||
|
practitionerName: '',
|
||||||
|
price: '',
|
||||||
|
activityPrice: '',
|
||||||
|
totalPrice: '',
|
||||||
|
visitTime: '',
|
||||||
|
encounterId: '',
|
||||||
|
});
|
||||||
|
if (reprintFormRef.value) {
|
||||||
|
reprintFormRef.value.clearValidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置搜索
|
||||||
|
function resetSearch() {
|
||||||
|
searchForm.cardNo = '';
|
||||||
|
registrationList.value = [];
|
||||||
|
hasSearched.value = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dialog-footer {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -3,7 +3,22 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24" class="card-box">
|
<el-col :span="24" class="card-box">
|
||||||
<el-card>
|
<el-card>
|
||||||
<template #header> <span style="vertical-align: middle">门诊挂号</span></template>
|
<template #header>
|
||||||
|
<div style="display: flex; align-items: center; justify-content: space-between; width: 100%">
|
||||||
|
<span style="vertical-align: middle; font-size: 16px; font-weight: bold;">门诊挂号</span>
|
||||||
|
<div class="header-buttons">
|
||||||
|
<el-button type="primary" icon="Document" @click="goToPatientRecord" size="small">档案</el-button>
|
||||||
|
<el-button type="primary" icon="Plus" @click="handleAddPatient" size="small">新建</el-button>
|
||||||
|
<el-button type="primary" plain icon="Search" @click="handleSearch" size="small">查询</el-button>
|
||||||
|
<el-button type="primary" plain @click="handleReadCard('01')" size="small">电子凭证</el-button>
|
||||||
|
<el-button type="primary" plain @click="handleReadCard('02')" size="small" :disabled="true">身份证</el-button>
|
||||||
|
<el-button type="primary" plain @click="handleReadCard('03')" size="small">医保卡</el-button>
|
||||||
|
<el-button type="warning" plain icon="CircleClose" @click="handleClear" size="small">清空</el-button>
|
||||||
|
<el-button type="primary" icon="Plus" @click="handleAdd" size="small">保存挂号</el-button>
|
||||||
|
<el-button type="success" icon="Printer" @click="handleReprint" size="small">补打挂号</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<el-form :model="form" :rules="rules" ref="outpatientRegistrationRef" label-width="110px">
|
<el-form :model="form" :rules="rules" ref="outpatientRegistrationRef" label-width="110px">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="5">
|
<el-col :span="5">
|
||||||
@@ -28,44 +43,6 @@
|
|||||||
</el-popover>
|
</el-popover>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" style="padding: 0">
|
|
||||||
<el-button type="primary" icon="Plus" @click="handleAddPatient" style="width: 65px">
|
|
||||||
新建
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="Search"
|
|
||||||
@click="handleSearch"
|
|
||||||
style="width: 65px"
|
|
||||||
>
|
|
||||||
查询
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleReadCard('01')" style="width: 65px">
|
|
||||||
电子凭证
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click="handleReadCard('02')"
|
|
||||||
style="width: 65px"
|
|
||||||
:disabled="true"
|
|
||||||
>
|
|
||||||
身份证
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" plain @click="handleReadCard('03')" style="width: 65px">
|
|
||||||
医保卡
|
|
||||||
</el-button>
|
|
||||||
<!-- <el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click="handleReadCard('99')"
|
|
||||||
style="width: 65px"
|
|
||||||
:disabled="true"
|
|
||||||
>
|
|
||||||
学生卡
|
|
||||||
</el-button> -->
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="5">
|
<el-col :span="5">
|
||||||
<el-form-item label="姓名:" prop="name">
|
<el-form-item label="姓名:" prop="name">
|
||||||
<el-input v-model="form.name" placeholder="姓名" :disabled="true" />
|
<el-input v-model="form.name" placeholder="姓名" :disabled="true" />
|
||||||
@@ -162,10 +139,10 @@
|
|||||||
ref="contractNameRef"
|
ref="contractNameRef"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in contractList"
|
v-for="dict in medfee_paymtd_code"
|
||||||
:key="item.busNo"
|
:key="dict.value"
|
||||||
:label="item.contractName"
|
:label="dict.label"
|
||||||
:value="item.busNo"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -350,33 +327,12 @@
|
|||||||
<el-input v-model="form.totalPrice" placeholder="" :disabled="true" />
|
<el-input v-model="form.totalPrice" placeholder="" :disabled="true" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" style="text-align: right">
|
</el-row>
|
||||||
<el-button type="warning" plain icon="CircleClose" @click="handleClear"
|
<el-row :gutter="24" justify="end">
|
||||||
>清空</el-button
|
<el-col :span="5" style="text-align: right">
|
||||||
>
|
<!-- 功能按钮已移至标题区域 -->
|
||||||
<el-button type="primary" plain icon="Plus" @click="handleAdd">保存挂号</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<!-- <el-row :gutter="24" justify="end">
|
|
||||||
<el-col :span="5" style="text-align: right">
|
|
||||||
<el-button
|
|
||||||
type="warning"
|
|
||||||
plain
|
|
||||||
icon="CircleClose"
|
|
||||||
@click="handleClear"
|
|
||||||
v-hasPermi="['system:user:export']"
|
|
||||||
>清空</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="Plus"
|
|
||||||
@click="handleAdd"
|
|
||||||
v-hasPermi="['system:user:add']"
|
|
||||||
>添加</el-button
|
|
||||||
>
|
|
||||||
</el-col>
|
|
||||||
</el-row> -->
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -385,7 +341,14 @@
|
|||||||
<el-col :span="24" class="card-box">
|
<el-col :span="24" class="card-box">
|
||||||
<el-card>
|
<el-card>
|
||||||
<template #header>
|
<template #header>
|
||||||
|
<div style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
<span style="vertical-align: middle">当日已挂号</span>
|
<span style="vertical-align: middle">当日已挂号</span>
|
||||||
|
<el-radio-group v-model="queryType" @change="handleQueryTypeChange" size="small">
|
||||||
|
<el-radio-button label="all">全部</el-radio-button>
|
||||||
|
<el-radio-button label="normal">正常挂号</el-radio-button>
|
||||||
|
<el-radio-button label="returned">退号记录</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.searchKey"
|
v-model="queryParams.searchKey"
|
||||||
@@ -441,7 +404,7 @@
|
|||||||
/>
|
/>
|
||||||
<el-table-column label="年龄" align="center" key="age" prop="age" width="120">
|
<el-table-column label="年龄" align="center" key="age" prop="age" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ scope.row.age ? `${scope.row.age}岁` : '-' }}
|
{{ scope.row.age ? `${scope.row.age}` : '-' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@@ -482,7 +445,8 @@
|
|||||||
align="center"
|
align="center"
|
||||||
key="contractName"
|
key="contractName"
|
||||||
prop="contractName"
|
prop="contractName"
|
||||||
/>
|
>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="挂号金额" align="center" key="totalPrice" prop="totalPrice">
|
<el-table-column label="挂号金额" align="center" key="totalPrice" prop="totalPrice">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span>
|
<span>
|
||||||
@@ -544,28 +508,98 @@
|
|||||||
<span>{{ parseTime(scope.row.registerTime) }}</span>
|
<span>{{ parseTime(scope.row.registerTime) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" key="registerTime" prop="registerTime">
|
<!-- 退号记录相关列 -->
|
||||||
|
<el-table-column
|
||||||
|
v-if="queryType === 'returned'"
|
||||||
|
label="退号日期/时间"
|
||||||
|
align="center"
|
||||||
|
key="returnDate"
|
||||||
|
prop="returnDate"
|
||||||
|
width="180"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.returnDate ? parseTime(scope.row.returnDate) : '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-if="queryType === 'returned'"
|
||||||
|
label="退号原因"
|
||||||
|
align="center"
|
||||||
|
key="returnReason"
|
||||||
|
prop="returnReason"
|
||||||
|
width="200"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.returnReason || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-if="queryType === 'returned'"
|
||||||
|
label="退号操作人"
|
||||||
|
align="center"
|
||||||
|
key="operatorName"
|
||||||
|
prop="operatorName"
|
||||||
|
width="120"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.operatorName || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-if="queryType === 'returned'"
|
||||||
|
label="退号操作工号"
|
||||||
|
align="center"
|
||||||
|
key="operatorId"
|
||||||
|
prop="operatorId"
|
||||||
|
width="120"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.operatorId || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-if="queryType === 'returned'"
|
||||||
|
label="退款金额"
|
||||||
|
align="center"
|
||||||
|
key="refundAmount"
|
||||||
|
prop="refundAmount"
|
||||||
|
width="120"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.refundAmount ? scope.row.refundAmount.toFixed(2) + ' 元' : '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-if="queryType === 'returned'"
|
||||||
|
label="退款方式"
|
||||||
|
align="center"
|
||||||
|
key="refundMethod"
|
||||||
|
prop="refundMethod"
|
||||||
|
width="150"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ scope.row.refundMethod || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 操作列:只在全部和正常挂号标签页显示,退号记录标签页不显示 -->
|
||||||
|
<el-table-column
|
||||||
|
v-if="queryType !== 'returned'"
|
||||||
|
label="操作"
|
||||||
|
align="center"
|
||||||
|
width="120"
|
||||||
|
fixed="right"
|
||||||
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- <el-tooltip
|
|
||||||
:content="
|
|
||||||
scope.row.statusEnum == 6
|
|
||||||
? '已退号'
|
|
||||||
: scope.row.statusEnum == 2
|
|
||||||
? '已接诊,不允许退号'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
placement="top"
|
|
||||||
:disabled="scope.row.statusEnum != 6"
|
|
||||||
> -->
|
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
|
:disabled="scope.row.statusEnum === 6 || scope.row.statusEnum !== 1"
|
||||||
|
:title="getReturnTooltip(scope.row)"
|
||||||
@click="handleReturn(scope.row)"
|
@click="handleReturn(scope.row)"
|
||||||
:disabled="scope.row.statusEnum == 6"
|
|
||||||
>
|
>
|
||||||
退号
|
退号
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- </el-tooltip> -->
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -597,6 +631,8 @@
|
|||||||
:transformedData="transformedData"
|
:transformedData="transformedData"
|
||||||
:chrgBchno="chrgBchno"
|
:chrgBchno="chrgBchno"
|
||||||
:registerBusNo="registerBusNo"
|
:registerBusNo="registerBusNo"
|
||||||
|
:feeType="(patientInfo && patientInfo.medfeePaymtdCode) || (form && form.value && form.value.contractNo) || ''"
|
||||||
|
:medfee_paymtd_code="medfee_paymtd_code"
|
||||||
/>
|
/>
|
||||||
<RefundDialog
|
<RefundDialog
|
||||||
:open="openRefundDialog"
|
:open="openRefundDialog"
|
||||||
@@ -613,6 +649,21 @@
|
|||||||
:patientInfo="patientInfo"
|
:patientInfo="patientInfo"
|
||||||
:paymentId="paymentId"
|
:paymentId="paymentId"
|
||||||
:chargeItemIds="chargeItemIdList"
|
:chargeItemIds="chargeItemIdList"
|
||||||
|
:feeType="patientInfo.medfeePaymtdCode || ''"
|
||||||
|
:contractName="patientInfo.contractName || ''"
|
||||||
|
:medfee_paymtd_code="medfee_paymtd_code"
|
||||||
|
:registerInfo="registerInfo"
|
||||||
|
/>
|
||||||
|
<ReprintDialog
|
||||||
|
:open="openReprintDialog"
|
||||||
|
@close="
|
||||||
|
(value) => {
|
||||||
|
if (value == 'success') {
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
openReprintDialog = false;
|
||||||
|
}
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -637,21 +688,29 @@ import { invokeYbPlugin } from '@/api/public';
|
|||||||
import patientInfoDialog from './components/patientInfoDialog';
|
import patientInfoDialog from './components/patientInfoDialog';
|
||||||
import PatientAddDialog from './components/patientAddDialog';
|
import PatientAddDialog from './components/patientAddDialog';
|
||||||
import patientList from './components/patientList';
|
import patientList from './components/patientList';
|
||||||
import { nextTick, ref } from 'vue';
|
import { nextTick, ref, onMounted, onUnmounted } from 'vue';
|
||||||
import ChargeDialog from './components/chargeDialog.vue';
|
import ChargeDialog from './components/chargeDialog.vue';
|
||||||
import RefundDialog from './components/refundDialog.vue';
|
import RefundDialog from './components/refundDialog.vue';
|
||||||
|
import ReprintDialog from './components/reprintDialog.vue';
|
||||||
import { handleColor } from '@/utils/his';
|
import { handleColor } from '@/utils/his';
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
import { formatDate, formatDateStr } from '@/utils/index';
|
import { formatDate, formatDateStr } from '@/utils/index';
|
||||||
|
|
||||||
const patientInfo = ref({});
|
const patientInfo = ref({});
|
||||||
|
|
||||||
|
// 跳转到患者档案管理页面
|
||||||
|
const goToPatientRecord = () => {
|
||||||
|
// 使用Vue Router进行路由导航,在当前页面打开新的路由层级
|
||||||
|
router.push('/system/basicmanage/patientmanagement');
|
||||||
|
};
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { sys_normal_disable, sys_user_sex, med_chrgitm_type } = proxy.useDict(
|
const { sys_normal_disable, sys_user_sex, med_chrgitm_type,medfee_paymtd_code } = proxy.useDict(
|
||||||
'sys_normal_disable',
|
'sys_normal_disable',
|
||||||
'sys_user_sex',
|
'sys_user_sex',
|
||||||
'med_chrgitm_type'
|
'med_chrgitm_type',
|
||||||
|
'medfee_paymtd_code'
|
||||||
);
|
);
|
||||||
|
|
||||||
const outpatientRegistrationList = ref([]);
|
const outpatientRegistrationList = ref([]);
|
||||||
@@ -681,11 +740,14 @@ const doctorRef = ref(null);
|
|||||||
const ybTypeRef = ref(null);
|
const ybTypeRef = ref(null);
|
||||||
const openDialog = ref(false);
|
const openDialog = ref(false);
|
||||||
const openRefundDialog = ref(false);
|
const openRefundDialog = ref(false);
|
||||||
|
const openReprintDialog = ref(false);
|
||||||
const totalAmount = ref(0);
|
const totalAmount = ref(0);
|
||||||
const chargeItemIdList = ref([]);
|
const chargeItemIdList = ref([]);
|
||||||
const chrgBchnoList = ref([]);
|
const chrgBchnoList = ref([]);
|
||||||
const paymentId = ref('');
|
const paymentId = ref('');
|
||||||
const loadingText = ref('');
|
const loadingText = ref('');
|
||||||
|
const registerInfo = ref({}); // 原挂号记录信息
|
||||||
|
const queryType = ref('all'); // 查询类型:all-全部, normal-正常挂号, returned-退号记录
|
||||||
|
|
||||||
// 使用 ref 定义查询所得用户信息数据
|
// 使用 ref 定义查询所得用户信息数据
|
||||||
const patientInfoList = ref(undefined);
|
const patientInfoList = ref(undefined);
|
||||||
@@ -793,6 +855,15 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
const { queryParams, form, rules } = toRefs(data);
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/** 根据contractNo获取费用性质名称 */
|
||||||
|
function getFeeTypeName(contractNo) {
|
||||||
|
if (!contractNo || !medfee_paymtd_code || !Array.isArray(medfee_paymtd_code)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const dictItem = medfee_paymtd_code.find(item => item.value === contractNo);
|
||||||
|
return dictItem ? dictItem.label : '';
|
||||||
|
}
|
||||||
|
|
||||||
/** 初期所用数据查询 */
|
/** 初期所用数据查询 */
|
||||||
function getInitData() {
|
function getInitData() {
|
||||||
getInit().then((response) => {
|
getInit().then((response) => {
|
||||||
@@ -1009,6 +1080,12 @@ function getList() {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
outpatientRegistrationList.value = res.data.records;
|
outpatientRegistrationList.value = res.data.records;
|
||||||
total.value = res.data.total;
|
total.value = res.data.total;
|
||||||
|
|
||||||
|
// 调试:查看返回的数据结构(仅退号记录查询时)
|
||||||
|
if (queryType.value === 'returned' && res.data.records && res.data.records.length > 0) {
|
||||||
|
console.log('退号记录数据结构:', res.data.records[0]);
|
||||||
|
console.log('所有字段:', Object.keys(res.data.records[0]));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1090,11 +1167,38 @@ function handleClear() {
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 查询类型切换 */
|
||||||
|
function handleQueryTypeChange() {
|
||||||
|
queryParams.value.pageNo = 1;
|
||||||
|
// 根据查询类型设置状态筛选
|
||||||
|
if (queryType.value === 'returned') {
|
||||||
|
// 查询退号记录(状态为6)
|
||||||
|
queryParams.value.statusEnum = 6;
|
||||||
|
} else if (queryType.value === 'normal') {
|
||||||
|
// 查询正常挂号(排除退号状态)
|
||||||
|
queryParams.value.statusEnum = -1; // 使用特殊值表示排除退号记录
|
||||||
|
} else {
|
||||||
|
// 查询全部
|
||||||
|
queryParams.value.statusEnum = undefined;
|
||||||
|
}
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
queryParams.value.pageNo = 1;
|
queryParams.value.pageNo = 1;
|
||||||
queryParams.value.registerTimeSTime = dateRange.value[0] + ' 00:00:00';
|
queryParams.value.registerTimeSTime = dateRange.value[0] + ' 00:00:00';
|
||||||
queryParams.value.registerTimeETime = dateRange.value[1] + ' 23:59:59';
|
queryParams.value.registerTimeETime = dateRange.value[1] + ' 23:59:59';
|
||||||
|
// 根据查询类型设置状态筛选
|
||||||
|
if (queryType.value === 'returned') {
|
||||||
|
queryParams.value.statusEnum = 6; // 退号状态
|
||||||
|
} else if (queryType.value === 'normal') {
|
||||||
|
// 正常挂号,排除退号记录
|
||||||
|
queryParams.value.statusEnum = -1; // 使用特殊值表示排除退号记录
|
||||||
|
} else {
|
||||||
|
// 全部
|
||||||
|
queryParams.value.statusEnum = undefined;
|
||||||
|
}
|
||||||
getList();
|
getList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1142,6 +1246,7 @@ function handleAdd() {
|
|||||||
console.log(transformedData, 'transformedData门诊挂号');
|
console.log(transformedData, 'transformedData门诊挂号');
|
||||||
chargeItemIdList.value = [];
|
chargeItemIdList.value = [];
|
||||||
patientInfo.value.patientId = form.value.patientId;
|
patientInfo.value.patientId = form.value.patientId;
|
||||||
|
patientInfo.value.medfeePaymtdCode = form.value.contractNo; // 设置费用性质
|
||||||
proxy.$refs['outpatientRegistrationRef'].validate((valid) => {
|
proxy.$refs['outpatientRegistrationRef'].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
readCardLoading.value = true;
|
readCardLoading.value = true;
|
||||||
@@ -1152,7 +1257,10 @@ function handleAdd() {
|
|||||||
addOutpatientRegistration(transformedData.value)
|
addOutpatientRegistration(transformedData.value)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
// proxy.$modal.msgSuccess('挂号成功');
|
console.log('挂号成功,返回数据:', res.data);
|
||||||
|
// 立即刷新列表,确保挂号信息显示在当日已挂号列表中
|
||||||
|
getList();
|
||||||
|
|
||||||
chrgBchno.value = res.data.chrgBchno;
|
chrgBchno.value = res.data.chrgBchno;
|
||||||
registerBusNo.value = res.data.busNo;
|
registerBusNo.value = res.data.busNo;
|
||||||
totalAmount.value = res.data.psnCashPay;
|
totalAmount.value = res.data.psnCashPay;
|
||||||
@@ -1207,14 +1315,47 @@ function handleSearchPatient(value) {
|
|||||||
patientSearchKey.value = value;
|
patientSearchKey.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getReturnTooltip(row) {
|
||||||
|
if (!row) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (row.statusEnum == 6) {
|
||||||
|
return '已退号';
|
||||||
|
}
|
||||||
|
if (row.statusEnum != 1) {
|
||||||
|
return '该患者医生已接诊,不能退号!';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
function handleReturn(row) {
|
function handleReturn(row) {
|
||||||
|
if (row.statusEnum != 1) {
|
||||||
|
proxy.$modal.msgError('该患者医生已接诊,不能退号!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
openRefundDialog.value = true;
|
openRefundDialog.value = true;
|
||||||
patientInfo.value.patientId = row.patientId;
|
patientInfo.value.patientId = row.patientId;
|
||||||
patientInfo.value.encounterId = row.encounterId;
|
patientInfo.value.encounterId = row.encounterId;
|
||||||
totalAmount.value = row.totalPrice;
|
totalAmount.value = row.totalPrice;
|
||||||
chargeItemIdList.value = row.chargeItemIds.split(',');
|
chargeItemIdList.value = row.chargeItemIds.split(',');
|
||||||
paymentId.value = row.paymentId;
|
paymentId.value = row.paymentId;
|
||||||
console.log(paymentId.value);
|
// 从挂号记录中获取正确的费用性质
|
||||||
|
patientInfo.value.medfeePaymtdCode = row.contractNo; // 使用挂号记录中的费用性质代码
|
||||||
|
patientInfo.value.contractName = row.contractName; // 保存费用性质名称用于显示
|
||||||
|
|
||||||
|
// 保存完整的原挂号记录信息,用于退号记录
|
||||||
|
registerInfo.value = {
|
||||||
|
...row, // 保存完整的挂号记录
|
||||||
|
patientName: row.patientName,
|
||||||
|
age: row.age,
|
||||||
|
genderEnum_enumText: row.genderEnum_enumText,
|
||||||
|
registerTime: row.registerTime,
|
||||||
|
totalPrice: row.totalPrice,
|
||||||
|
encounterId: row.encounterId,
|
||||||
|
patientId: row.patientId,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('退号费用性质:', row.contractNo, row.contractName);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleReturnRegister() {
|
function handleReturnRegister() {
|
||||||
@@ -1226,6 +1367,11 @@ function handleReturnRegister() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 打开补打挂号对话框 */
|
||||||
|
function handleReprint() {
|
||||||
|
openReprintDialog.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 点击患者列表给表单赋值
|
* 点击患者列表给表单赋值
|
||||||
*/
|
*/
|
||||||
@@ -1323,4 +1469,10 @@ getLocationInfo();
|
|||||||
margin-bottom: 0; /* 去掉默认的 margin-bottom */
|
margin-bottom: 0; /* 去掉默认的 margin-bottom */
|
||||||
margin-left: 8px; /* 图标和下拉选之间的间距 */
|
margin-left: 8px; /* 图标和下拉选之间的间距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 标题区域按钮样式 */
|
||||||
|
.header-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行患者换卡操作
|
||||||
|
* @param {Object} params - 换卡参数
|
||||||
|
* @param {string} params.oldCardNo - 旧门诊号码
|
||||||
|
* @param {string} params.newCardNo - 新门诊号码
|
||||||
|
* @param {string} params.patientId - 患者ID
|
||||||
|
* @param {string} params.reason - 换卡原因
|
||||||
|
* @param {string} params.remark - 备注信息
|
||||||
|
* @returns {Promise} 请求结果
|
||||||
|
*/
|
||||||
|
export const doCardRenewal = (params) => {
|
||||||
|
return request({
|
||||||
|
url: '/charge/patientCardRenewal/renewCard',
|
||||||
|
method: 'post',
|
||||||
|
data: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询患者信息 - 复用门诊挂号的API
|
||||||
|
* @param {Object} params - 查询参数
|
||||||
|
* @param {string} params.searchKey - 搜索关键字(姓名、身份证号、手机号等)
|
||||||
|
* @param {number} params.pageNo - 当前页码
|
||||||
|
* @param {number} params.pageSize - 每页大小
|
||||||
|
* @returns {Promise} 请求结果
|
||||||
|
*/
|
||||||
|
export const getPatientList = (params) => {
|
||||||
|
// 构建searchKey参数,将姓名、身份证号、手机号组合成一个搜索关键字
|
||||||
|
const searchKey = params.patientName || params.idCard || params.phoneNumber || '';
|
||||||
|
|
||||||
|
return request({
|
||||||
|
url: '/charge-manage/register/patient-metadata',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
searchKey: searchKey,
|
||||||
|
pageNo: params.pageNo || 1,
|
||||||
|
pageSize: params.pageSize || 10
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
765
openhis-ui-vue3/src/views/charge/patientCardRenewal/index.vue
Normal file
765
openhis-ui-vue3/src/views/charge/patientCardRenewal/index.vue
Normal file
@@ -0,0 +1,765 @@
|
|||||||
|
<template>
|
||||||
|
<div class="card-renewal-container">
|
||||||
|
<!-- 标题栏 -->
|
||||||
|
<div class="title-bar">
|
||||||
|
<h2>换卡处理</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 按钮栏 - 修改为水平排放 -->
|
||||||
|
<div class="button-bar">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
@click="handlePatientSearch"
|
||||||
|
:loading="loading"
|
||||||
|
icon="el-icon-search"
|
||||||
|
style="min-width: 140px;"
|
||||||
|
>
|
||||||
|
病人查询(Q)
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
size="large"
|
||||||
|
@click="handleConfirm"
|
||||||
|
:loading="loading"
|
||||||
|
:disabled="!patientInfo"
|
||||||
|
style="min-width: 140px;"
|
||||||
|
>
|
||||||
|
确定 (O)
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
size="large"
|
||||||
|
@click="handleClose"
|
||||||
|
:disabled="loading"
|
||||||
|
style="min-width: 140px;"
|
||||||
|
>
|
||||||
|
关闭 (C)
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 查询条件 -->
|
||||||
|
<div class="search-section">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="input-item">
|
||||||
|
<label>病人姓名:</label>
|
||||||
|
<el-input
|
||||||
|
v-model="searchForm.patientName"
|
||||||
|
placeholder="请输入"
|
||||||
|
@keyup.enter="handlePatientSearch"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="input-item">
|
||||||
|
<label>身份证号码:</label>
|
||||||
|
<el-input
|
||||||
|
v-model="searchForm.idCard"
|
||||||
|
placeholder="请输入"
|
||||||
|
@keyup.enter="handlePatientSearch"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="input-item">
|
||||||
|
<label>手机号码:</label>
|
||||||
|
<el-input
|
||||||
|
v-model="searchForm.phoneNumber"
|
||||||
|
placeholder="请输入"
|
||||||
|
@keyup.enter="handlePatientSearch"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 患者信息显示 -->
|
||||||
|
<div class="patient-info-section">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="info-item">
|
||||||
|
<label>门诊号码</label>
|
||||||
|
<div class="info-value">{{ patientInfo?.outpatientNo || '' }}</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="info-item">
|
||||||
|
<label>病人姓名</label>
|
||||||
|
<div class="info-value">{{ patientInfo?.patientName || '' }}</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="info-item">
|
||||||
|
<label>身份证号码</label>
|
||||||
|
<div class="info-value">{{ patientInfo?.idCard || '' }}</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20" style="margin-top: 15px;">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="info-item">
|
||||||
|
<label>手机号码</label>
|
||||||
|
<div class="info-value">{{ patientInfo?.phoneNumber || '' }}</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="info-item">
|
||||||
|
<label>性别</label>
|
||||||
|
<div class="info-value">{{ patientInfo?.gender || '' }}</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="info-item">
|
||||||
|
<label>年龄</label>
|
||||||
|
<div class="info-value">{{ patientInfo?.age || '' }}</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 新门诊号码输入 -->
|
||||||
|
<div class="new-number-section">
|
||||||
|
<div class="input-item">
|
||||||
|
<label>新门诊号码:</label>
|
||||||
|
<el-input
|
||||||
|
v-model="renewalForm.newOutpatientNo"
|
||||||
|
placeholder="请输入新门诊号码"
|
||||||
|
@keyup.enter="handleConfirm"
|
||||||
|
style="width: 250px;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 按钮区域已移除 -->
|
||||||
|
|
||||||
|
<!-- 患者列表对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="showPatientList"
|
||||||
|
:title="null"
|
||||||
|
width="800px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
class="custom-patient-dialog"
|
||||||
|
>
|
||||||
|
<!-- 自定义标题栏和按钮区域 -->
|
||||||
|
<template #header>
|
||||||
|
<div style="width: 100%; background-color: #e6f4ff;">
|
||||||
|
<!-- 标题行 -->
|
||||||
|
<div style="display: flex; justify-content: flex-start; align-items: center; padding: 10px 20px;">
|
||||||
|
<h3 style="margin: 0; font-size: 16px; font-weight: 500; color: #303133;">病人档案查询</h3>
|
||||||
|
</div>
|
||||||
|
<!-- 按钮行 -->
|
||||||
|
<div style="display: flex; justify-content: flex-start; gap: 10px; padding: 10px 20px; background-color: #e6f4ff;">
|
||||||
|
<el-button type="primary" @click="confirmSelectPatient" style="background-color: #409eff; border-color: #409eff; padding: 8px 16px; font-size: 14px;">确认(Q)</el-button>
|
||||||
|
<el-button @click="showPatientList = false; selectedPatient = null" style="background-color: #f56c6c; border-color: #f56c6c; color: white; padding: 8px 16px; font-size: 14px;">关闭(C)</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
:data="patientList"
|
||||||
|
style="width: 100%"
|
||||||
|
@row-click="selectPatient"
|
||||||
|
:row-key="row => row.identifierNo || row.patientId || row.cardNo"
|
||||||
|
:current-row-key="selectedPatient?.identifierNo || selectedPatient?.patientId || selectedPatient?.cardNo"
|
||||||
|
highlight-current-row
|
||||||
|
>
|
||||||
|
<el-table-column label="序号" width="60" type="index">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="病人姓名" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.patientName || scope.row.name || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="门诊号码" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.identifierNo || scope.row.cardNo || scope.row.card_number || scope.row.就诊卡号 || scope.row.outpatientNumber || scope.row.outpatientNo || scope.row.门诊号码 || scope.row.卡号 || scope.row.card || scope.row.patientNo || scope.row.patient_id || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="身份证号码" width="200">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.idCard || scope.row.id_card || scope.row.idNo || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="手机号码" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.phoneNumber || scope.row.phone || scope.row.mobile || scope.row.mobilePhone || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.genderEnum_enumText || scope.row.gender || scope.row.sex || scope.row.性别 || scope.row.xb || scope.row.sexCode || scope.row.GENDER || scope.row.SEX || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="年龄" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.age || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出生年月" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ formatDate(scope.row.birthDate || scope.row.birthday || scope.row.出生日期) || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<div style="margin-top: 15px; display: flex; justify-content: flex-end;">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="currentPage"
|
||||||
|
v-model:page-size="pageSize"
|
||||||
|
:page-sizes="[5, 10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 移除底部按钮 -->
|
||||||
|
<template #footer>
|
||||||
|
<span></span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 换卡成功提示 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="renewalSuccessVisible"
|
||||||
|
title="换卡成功"
|
||||||
|
width="400px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
>
|
||||||
|
<div style="text-align: center; padding: 20px;">
|
||||||
|
<div class="success-icon">✓</div>
|
||||||
|
<p style="margin-top: 15px; font-size: 16px;">患者换卡操作已成功完成!</p>
|
||||||
|
<p style="margin-top: 10px;">新门诊号码:{{ renewalForm.newOutpatientNo }}</p>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="renewalSuccessVisible = false; resetForm">确定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, onUnmounted, getCurrentInstance } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { doCardRenewal, getPatientList } from './components/api.js';
|
||||||
|
|
||||||
|
// 获取路由实例
|
||||||
|
const router = useRouter();
|
||||||
|
// 获取当前组件实例以访问全局属性
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const searchForm = reactive({
|
||||||
|
patientName: '',
|
||||||
|
idCard: '',
|
||||||
|
phoneNumber: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 患者信息
|
||||||
|
const patientInfo = ref(null)
|
||||||
|
|
||||||
|
// 患者列表
|
||||||
|
const patientList = ref([])
|
||||||
|
const showPatientList = ref(false)
|
||||||
|
const selectedPatient = ref(null)
|
||||||
|
// 分页相关状态
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const pageSize = ref(5)
|
||||||
|
const total = ref(0)
|
||||||
|
|
||||||
|
// 换卡表单
|
||||||
|
const renewalForm = reactive({
|
||||||
|
newOutpatientNo: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 成功弹窗显示状态
|
||||||
|
const renewalSuccessVisible = ref(false)
|
||||||
|
|
||||||
|
// 分页大小变化处理
|
||||||
|
const handleSizeChange = (newSize) => {
|
||||||
|
pageSize.value = newSize
|
||||||
|
currentPage.value = 1 // 重置为第一页
|
||||||
|
selectedPatient.value = null // 切换分页时重置选中状态
|
||||||
|
if (showPatientList.value) {
|
||||||
|
handlePatientSearch() // 重新查询
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前页码变化处理
|
||||||
|
const handleCurrentChange = (newPage) => {
|
||||||
|
currentPage.value = newPage
|
||||||
|
selectedPatient.value = null // 切换分页时重置选中状态
|
||||||
|
if (showPatientList.value) {
|
||||||
|
handlePatientSearch() // 重新查询
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询患者信息
|
||||||
|
const handlePatientSearch = async () => {
|
||||||
|
// 检查是否至少填写了一个查询条件
|
||||||
|
if (!searchForm.patientName && !searchForm.idCard && !searchForm.phoneNumber) {
|
||||||
|
ElMessage.warning('请至少输入一个查询条件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
// 构建查询参数,包含分页信息
|
||||||
|
const queryParams = {
|
||||||
|
patientName: searchForm.patientName || '',
|
||||||
|
idCard: searchForm.idCard || '',
|
||||||
|
phoneNumber: searchForm.phoneNumber || '',
|
||||||
|
pageNo: currentPage.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用复用的门诊挂号API获取患者列表
|
||||||
|
const response = await getPatientList(queryParams)
|
||||||
|
|
||||||
|
if (response && response.code === 200) {
|
||||||
|
// 检查是否有查询结果
|
||||||
|
if (response.data && response.data.records && response.data.records.length > 0) {
|
||||||
|
// 更新总条数
|
||||||
|
total.value = response.data.total || 0
|
||||||
|
selectedPatient.value = null // 查询时重置选中状态
|
||||||
|
|
||||||
|
// 如果只有一条记录且是第一页,自动选中
|
||||||
|
if (response.data.records.length === 1 && currentPage.value === 1) {
|
||||||
|
const patient = response.data.records[0]
|
||||||
|
// 确保patient对象中同时包含id和patientId字段
|
||||||
|
if (patient.id && !patient.patientId) {
|
||||||
|
patient.patientId = patient.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置为选中状态,但不自动确认
|
||||||
|
selectedPatient.value = patient
|
||||||
|
ElMessage.warning('已自动选中唯一患者,请点击确定')
|
||||||
|
} else {
|
||||||
|
// 如果有多条记录或不是第一页,显示患者列表供选择
|
||||||
|
// 确保每条患者记录都包含patientId字段,优先使用id字段
|
||||||
|
patientList.value = response.data.records.map(patient => ({
|
||||||
|
...patient,
|
||||||
|
patientId: patient.patientId || patient.id
|
||||||
|
}))
|
||||||
|
showPatientList.value = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 无数据时重置总条数
|
||||||
|
total.value = 0
|
||||||
|
ElMessage.warning('未查询到患者信息')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('查询失败:' + (response?.msg || '未知错误'))
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
// 使用公共错误处理函数处理错误信息
|
||||||
|
const errorMessage = processErrorMessage(error, '查询失败,请稍后重试');
|
||||||
|
ElMessage.error(errorMessage);
|
||||||
|
// 可以在这里添加错误监控或日志记录
|
||||||
|
console.error('患者查询错误:', error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确定换卡
|
||||||
|
const handleConfirm = async () => {
|
||||||
|
if (!patientInfo.value) {
|
||||||
|
ElMessage.warning('请先查询患者信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!renewalForm.newOutpatientNo) {
|
||||||
|
ElMessage.warning('请输入新门诊号码')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renewalForm.newOutpatientNo === patientInfo.value.outpatientNo) {
|
||||||
|
ElMessage.warning('新门诊号码不能与原号码相同')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
// 构建换卡请求参数,注意参数名称与API接口保持一致
|
||||||
|
const params = {
|
||||||
|
oldCardNo: patientInfo.value.outpatientNo,
|
||||||
|
newCardNo: renewalForm.newOutpatientNo,
|
||||||
|
patientId: patientInfo.value.patientId,
|
||||||
|
reason: '患者换卡',
|
||||||
|
remark: `从${patientInfo.value.outpatientNo}更换到${renewalForm.newOutpatientNo}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用真实的换卡接口
|
||||||
|
const res = await doCardRenewal(params)
|
||||||
|
|
||||||
|
if (res && res.code === 200) {
|
||||||
|
renewalSuccessVisible.value = true
|
||||||
|
// 更新患者信息中的门诊号码为新号码
|
||||||
|
if (patientInfo.value) {
|
||||||
|
patientInfo.value.outpatientNo = renewalForm.newOutpatientNo
|
||||||
|
}
|
||||||
|
ElMessage.success('换卡成功!')
|
||||||
|
} else {
|
||||||
|
ElMessage.error('换卡失败:' + (res?.msg || '未知错误'))
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('换卡失败,卡号已存在')
|
||||||
|
// 可以在这里添加错误监控或日志记录
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭窗口,同时关闭标签页并返回上一级页面
|
||||||
|
const handleClose = () => {
|
||||||
|
// 显示确认对话框
|
||||||
|
ElMessageBox.confirm('确定要关闭此页面吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
// 用户确认后,使用全局$tab对象关闭当前标签页
|
||||||
|
if (proxy && proxy.$tab) {
|
||||||
|
proxy.$tab.closePage()
|
||||||
|
} else {
|
||||||
|
// 降级处理:如果$tab不可用,仍然使用router.back()
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消操作,不执行任何操作
|
||||||
|
// 可以选择显示一个提示消息
|
||||||
|
ElMessage.info('已取消关闭操作')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 键盘事件处理
|
||||||
|
const handleKeydown = (event) => {
|
||||||
|
// 只有在患者列表对话框显示时才处理对话框快捷键
|
||||||
|
if (showPatientList.value) {
|
||||||
|
// 忽略在输入框中按下的按键
|
||||||
|
if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = event.key.toLowerCase()
|
||||||
|
if (key === 'q') {
|
||||||
|
event.preventDefault()
|
||||||
|
confirmSelectPatient()
|
||||||
|
} else if (key === 'c') {
|
||||||
|
event.preventDefault()
|
||||||
|
showPatientList.value = false
|
||||||
|
selectedPatient.value = null
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alt + Q 查询
|
||||||
|
if (event.altKey && event.key.toLowerCase() === 'q') {
|
||||||
|
event.preventDefault()
|
||||||
|
handlePatientSearch()
|
||||||
|
}
|
||||||
|
// Alt + O 确定
|
||||||
|
if (event.altKey && event.key.toLowerCase() === 'o') {
|
||||||
|
event.preventDefault()
|
||||||
|
handleConfirm()
|
||||||
|
}
|
||||||
|
// Alt + C 关闭
|
||||||
|
if (event.altKey && event.key.toLowerCase() === 'c') {
|
||||||
|
event.preventDefault()
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件挂载时添加键盘事件监听
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener('keydown', handleKeydown)
|
||||||
|
|
||||||
|
// 设置默认患者数据,方便用户直接进行换卡操作
|
||||||
|
patientInfo.value = {
|
||||||
|
outpatientNo: '20231001001',
|
||||||
|
patientName: '张三',
|
||||||
|
idCard: '110101199001011234',
|
||||||
|
phoneNumber: '13800138000',
|
||||||
|
gender: '男',
|
||||||
|
age: '33岁',
|
||||||
|
patientId: '1001'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 组件卸载时移除键盘事件监听
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener('keydown', handleKeydown)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 移除了调试功能
|
||||||
|
|
||||||
|
// 选择患者(仅设置选中状态)
|
||||||
|
const selectPatient = (row) => {
|
||||||
|
selectedPatient.value = row
|
||||||
|
ElMessage.warning('已选择患者,请点击确定')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认选择患者
|
||||||
|
const confirmSelectPatient = () => {
|
||||||
|
if (!selectedPatient.value) {
|
||||||
|
ElMessage.warning('请先选择患者')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const row = selectedPatient.value
|
||||||
|
// 获取门诊号码,优先使用identifierNo
|
||||||
|
const outpatientNo = row.identifierNo || row.cardNo || row.card_number || row.就诊卡号 || row.outpatientNumber || row.outpatientNo || row.门诊号码 || row.卡号 || row.card || row.patientNo || row.patient_id;
|
||||||
|
// 获取性别,优先使用genderEnum_enumText
|
||||||
|
const gender = row.genderEnum_enumText || row.gender || row.sex || row.性别 || row.xb || row.sexCode || row.GENDER || row.SEX;
|
||||||
|
|
||||||
|
patientInfo.value = {
|
||||||
|
outpatientNo: outpatientNo,
|
||||||
|
patientName: row.patientName || row.name,
|
||||||
|
idCard: row.idCard || row.id_card || row.idNo,
|
||||||
|
phoneNumber: row.phoneNumber || row.phone || row.mobile || row.mobilePhone,
|
||||||
|
gender: gender,
|
||||||
|
age: row.age,
|
||||||
|
patientId: row.patientId || row.id || outpatientNo
|
||||||
|
}
|
||||||
|
|
||||||
|
showPatientList.value = false
|
||||||
|
ElMessage.success('已选择患者:' + (row.patientName || row.name))
|
||||||
|
// 重置选中状态
|
||||||
|
selectedPatient.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
const resetForm = () => {
|
||||||
|
searchForm.patientName = ''
|
||||||
|
searchForm.idCard = ''
|
||||||
|
searchForm.phoneNumber = ''
|
||||||
|
patientInfo.value = null
|
||||||
|
patientList.value = []
|
||||||
|
showPatientList.value = false
|
||||||
|
selectedPatient.value = null
|
||||||
|
renewalForm.newOutpatientNo = ''
|
||||||
|
// 重置分页状态
|
||||||
|
currentPage.value = 1
|
||||||
|
pageSize.value = 5
|
||||||
|
total.value = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化日期为YYYY-MM-DD格式
|
||||||
|
const formatDate = (date) => {
|
||||||
|
if (!date) return ''
|
||||||
|
// 如果已经是YYYY-MM-DD格式,直接返回
|
||||||
|
if (typeof date === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
// 处理日期对象或其他格式
|
||||||
|
const d = new Date(date)
|
||||||
|
if (isNaN(d.getTime())) return ''
|
||||||
|
const year = d.getFullYear()
|
||||||
|
const month = String(d.getMonth() + 1).padStart(2, '0')
|
||||||
|
const day = String(d.getDate()).padStart(2, '0')
|
||||||
|
return `${year}-${month}-${day}`
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 自定义对话框样式 */
|
||||||
|
.custom-patient-dialog .el-dialog__header {
|
||||||
|
padding: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏默认的header样式 */
|
||||||
|
.custom-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-patient-dialog .el-dialog__body {
|
||||||
|
padding: 0;
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏默认底部区域 */
|
||||||
|
.custom-patient-dialog .el-dialog__footer {
|
||||||
|
padding: 0;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer .el-button {
|
||||||
|
min-width: 80px;
|
||||||
|
background-color: #f56c6c;
|
||||||
|
border-color: #f56c6c;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格样式 */
|
||||||
|
.el-dialog__body {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table th {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table td {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格样式优化 */
|
||||||
|
.el-table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table th {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table td {
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table tr:hover > td {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table--striped .el-table__body tr:nth-child(2n) {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分页样式优化 */
|
||||||
|
.el-pagination {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-top: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-renewal-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar {
|
||||||
|
background: #409eff;
|
||||||
|
color: white;
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin: -10px -10px 15px -10px;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-bar {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-bar .el-button {
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-bar .el-button:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-item {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-item label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patient-info-section {
|
||||||
|
background: #f5f7fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item label {
|
||||||
|
display: block;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-number-section {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: #67c23a;
|
||||||
|
color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
342
openhis-ui-vue3/src/views/charge/patientSearch/PatientSearch.vue
Normal file
342
openhis-ui-vue3/src/views/charge/patientSearch/PatientSearch.vue
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
<template>
|
||||||
|
<div class="patient-search-container">
|
||||||
|
<!-- 标题栏 -->
|
||||||
|
<div class="title-bar">
|
||||||
|
<h2>病人档案查询</h2>
|
||||||
|
<div class="button-bar">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="handleQuery"
|
||||||
|
:loading="loading"
|
||||||
|
size="large"
|
||||||
|
icon="el-icon-check"
|
||||||
|
>
|
||||||
|
确认(Q)
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
@click="handleClose"
|
||||||
|
size="large"
|
||||||
|
icon="el-icon-close"
|
||||||
|
>
|
||||||
|
关闭(C)
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 查询表单 -->
|
||||||
|
<div class="search-form">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="form-item">
|
||||||
|
<label>病人姓名:</label>
|
||||||
|
<el-input
|
||||||
|
v-model="searchForm.patientName"
|
||||||
|
placeholder="请输入病人姓名"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="form-item">
|
||||||
|
<label>身份证号码:</label>
|
||||||
|
<el-input
|
||||||
|
v-model="searchForm.idCard"
|
||||||
|
placeholder="请输入身份证号码"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<div class="form-item">
|
||||||
|
<label>手机号码:</label>
|
||||||
|
<el-input
|
||||||
|
v-model="searchForm.phoneNumber"
|
||||||
|
placeholder="请输入手机号码"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 查询结果表格 -->
|
||||||
|
<div class="result-table">
|
||||||
|
<el-table
|
||||||
|
:data="patientList"
|
||||||
|
style="width: 100%"
|
||||||
|
stripe
|
||||||
|
@row-click="handleRowClick"
|
||||||
|
highlight-current-row
|
||||||
|
row-key="id"
|
||||||
|
:current-row-key="selectedPatient?.id"
|
||||||
|
>
|
||||||
|
<el-table-column label="序号" type="index" width="80" align="center">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="病人姓名" width="120" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.patientName }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="门诊号码" width="150" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.outpatientNo || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="身份证号码" width="200" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.idCard || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="手机号码" width="120" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.phoneNumber || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" width="80" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.gender }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="年龄" width="80" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.age }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出生年月" width="120" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.birthDate }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, onUnmounted, computed, watch } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { getOutpatientRegistrationList } from '../outpatientregistration/components/outpatientregistration'
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const searchForm = reactive({
|
||||||
|
patientName: '',
|
||||||
|
idCard: '',
|
||||||
|
phoneNumber: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 患者列表
|
||||||
|
const patientList = ref([])
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// API调用相关变量
|
||||||
|
const queryParams = ref({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 50
|
||||||
|
})
|
||||||
|
|
||||||
|
// 当前选中的患者
|
||||||
|
const selectedPatient = ref(null)
|
||||||
|
|
||||||
|
// 定义事件
|
||||||
|
const emit = defineEmits(['selectPatient', 'close'])
|
||||||
|
|
||||||
|
// 计算搜索关键字,合并三个字段为一个searchKey
|
||||||
|
const searchKey = computed(() => {
|
||||||
|
return searchForm.patientName || searchForm.idCard || searchForm.phoneNumber
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听搜索关键字变化,自动查询
|
||||||
|
watch(searchKey, (newValue) => {
|
||||||
|
// 当搜索关键字变化时,延迟查询,避免频繁请求
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
if (newValue) {
|
||||||
|
queryParams.value.searchKey = newValue
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
}, 300)
|
||||||
|
return () => clearTimeout(timer)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理行点击
|
||||||
|
const handleRowClick = (row) => {
|
||||||
|
selectedPatient.value = row
|
||||||
|
ElMessage.success(`已选择患者:${row.patientName}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询患者信息和确认选择
|
||||||
|
const handleQuery = async () => {
|
||||||
|
// 如果已经选中了患者,则确认选择
|
||||||
|
if (selectedPatient.value) {
|
||||||
|
// 发射选择患者事件
|
||||||
|
emit('selectPatient', selectedPatient.value)
|
||||||
|
ElMessage.success(`已确认选择患者:${selectedPatient.value.patientName}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否至少填写了一个查询条件
|
||||||
|
if (!searchKey.value) {
|
||||||
|
ElMessage.warning('请至少输入一个查询条件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
// 调用门诊挂号的API获取患者列表
|
||||||
|
const response = await getOutpatientRegistrationList(queryParams.value)
|
||||||
|
|
||||||
|
if (response.data && response.data.records) {
|
||||||
|
// 映射字段,使其与表格展示需求匹配
|
||||||
|
patientList.value = response.data.records.map(record => ({
|
||||||
|
id: record.id,
|
||||||
|
patientName: record.name,
|
||||||
|
outpatientNo: record.identifierNo,
|
||||||
|
idCard: record.idCard,
|
||||||
|
phoneNumber: record.phone,
|
||||||
|
gender: record.genderEnum_enumText || '-',
|
||||||
|
age: record.age || '-',
|
||||||
|
birthDate: record.birthDate || '-' // 如果后端没有提供,需要计算或显示为'-'
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (patientList.value.length === 0) {
|
||||||
|
ElMessage.warning('未找到符合条件的患者信息')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ElMessage.error('查询失败')
|
||||||
|
patientList.value = []
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('查询失败,请稍后重试')
|
||||||
|
console.error('查询失败:', error)
|
||||||
|
patientList.value = []
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭窗口
|
||||||
|
const handleClose = () => {
|
||||||
|
// 发射关闭事件
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 键盘事件处理
|
||||||
|
const handleKeydown = (event) => {
|
||||||
|
// Alt + Q 查询
|
||||||
|
if (event.altKey && event.key.toLowerCase() === 'q') {
|
||||||
|
event.preventDefault()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
// Alt + C 关闭
|
||||||
|
if (event.altKey && event.key.toLowerCase() === 'c') {
|
||||||
|
event.preventDefault()
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件挂载时添加键盘事件监听
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener('keydown', handleKeydown)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 组件卸载时移除键盘事件监听
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener('keydown', handleKeydown)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.patient-search-container {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #b3d4ff;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar {
|
||||||
|
background-color: #d6e9ff;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-bottom: 1px solid #b3d4ff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-bar h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-bar {
|
||||||
|
padding: 10px 20px;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-bar .el-button {
|
||||||
|
padding: 12px 24px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid #dcdfe6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item .el-input {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-table {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table {
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table th {
|
||||||
|
background-color: #f2f6fc;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
border-bottom: 1px solid #e6e8eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table td {
|
||||||
|
padding: 10px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table--striped .el-table__body tr:nth-child(2n) {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table__row:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
48
openhis-ui-vue3/src/views/charge/patientSearch/api.js
Normal file
48
openhis-ui-vue3/src/views/charge/patientSearch/api.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取门诊患者信息列表
|
||||||
|
* 复用门诊挂号的API来查询患者信息
|
||||||
|
*/
|
||||||
|
export const getOutpatientRegistrationList = (params) => {
|
||||||
|
// 调用门诊挂号的API获取患者信息
|
||||||
|
return request({
|
||||||
|
url: '/api/outpatient/registration/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取患者详情
|
||||||
|
*/
|
||||||
|
export const getPatientById = (id) => {
|
||||||
|
return request({
|
||||||
|
url: `/api/outpatient/registration/${id}`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据条件查询患者信息
|
||||||
|
* 复用门诊挂号API进行查询
|
||||||
|
*/
|
||||||
|
export const getPatientList = (params) => {
|
||||||
|
// 复用门诊挂号的API
|
||||||
|
return request({
|
||||||
|
url: '/api/outpatient/registration/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据门诊号码获取患者详细信息
|
||||||
|
*/
|
||||||
|
export const getPatientByOutpatientNo = (outpatientNo) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/outpatient/registration/list',
|
||||||
|
method: 'get',
|
||||||
|
params: { identifierNo: outpatientNo }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -61,13 +61,13 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
import { getAdviceBaseInfo } from './api';
|
import { getAdviceBaseInfo, getDeviceList } from './api';
|
||||||
import { throttle } from 'lodash-es';
|
import { throttle } from 'lodash-es';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
adviceQueryParams: {
|
adviceQueryParams: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: '',
|
required: true
|
||||||
},
|
},
|
||||||
patientInfo: {
|
patientInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -97,39 +97,29 @@ const throttledGetList = throttle(
|
|||||||
watch(
|
watch(
|
||||||
() => props.adviceQueryParams,
|
() => props.adviceQueryParams,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
queryParams.value.searchKey = newValue.searchKey;
|
// 直接更新查询参数
|
||||||
// queryParams.value.adviceType = newValue.adviceType;
|
queryParams.value.searchKey = newValue.searchKey || '';
|
||||||
if (newValue.adviceType) {
|
|
||||||
queryParams.value.adviceTypes = [newValue.adviceType].join(',');
|
// 处理类型筛选
|
||||||
|
if (newValue.adviceType !== undefined && newValue.adviceType !== null && newValue.adviceType !== '') {
|
||||||
|
// 单个类型
|
||||||
|
queryParams.value.adviceTypes = newValue.adviceType.toString();
|
||||||
} else {
|
} else {
|
||||||
|
// 全部类型
|
||||||
queryParams.value.adviceTypes = '1,2,3';
|
queryParams.value.adviceTypes = '1,2,3';
|
||||||
}
|
}
|
||||||
throttledGetList();
|
|
||||||
},
|
|
||||||
{ deep: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
getList();
|
// 设置categoryCode筛选条件(用于筛选西药和中成药)
|
||||||
function getList() {
|
if (newValue.categoryCode) {
|
||||||
queryParams.value.organizationId = props.patientInfo.orgId;
|
queryParams.value.categoryCode = newValue.categoryCode;
|
||||||
getAdviceBaseInfo(queryParams.value).then((res) => {
|
|
||||||
console.log('ssssssssss', res.data.records);
|
|
||||||
if (res.data.records.length > 0) {
|
|
||||||
adviceBaseList.value = res.data.records.filter((item) => {
|
|
||||||
if (item.adviceType == 1 || item.adviceType == 2) {
|
|
||||||
return handleQuantity(item) != 0;
|
|
||||||
} else {
|
} else {
|
||||||
return true;
|
queryParams.value.categoryCode = undefined;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
total.value = res.data.total;
|
getList();
|
||||||
nextTick(() => {
|
},
|
||||||
currentIndex.value = 0;
|
{ deep: true, immediate: true }
|
||||||
adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
|
);
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 从priceList列表中获取价格
|
// 从priceList列表中获取价格
|
||||||
function getPriceFromInventory(row) {
|
function getPriceFromInventory(row) {
|
||||||
if (row.priceList && row.priceList.length > 0) {
|
if (row.priceList && row.priceList.length > 0) {
|
||||||
@@ -138,6 +128,119 @@ function getPriceFromInventory(row) {
|
|||||||
}
|
}
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
|
function getList() {
|
||||||
|
queryParams.value.organizationId = props.patientInfo.orgId;
|
||||||
|
|
||||||
|
// 判断是否是耗材类型(adviceType = 2 表示耗材)
|
||||||
|
const isConsumables = queryParams.value.adviceTypes === '2' || queryParams.value.adviceTypes === 2;
|
||||||
|
|
||||||
|
if (isConsumables) {
|
||||||
|
// 调用耗材目录接口
|
||||||
|
const deviceQueryParams = {
|
||||||
|
pageNo: queryParams.value.pageNum || 1,
|
||||||
|
pageSize: queryParams.value.pageSize || 100,
|
||||||
|
searchKey: queryParams.value.searchKey || '',
|
||||||
|
statusEnum: 2, // 只查询启用状态的耗材
|
||||||
|
};
|
||||||
|
|
||||||
|
getDeviceList(deviceQueryParams).then((res) => {
|
||||||
|
if (res.data && res.data.records && res.data.records.length > 0) {
|
||||||
|
// 将耗材目录数据转换为医嘱基础信息格式
|
||||||
|
const convertedRecords = res.data.records.map((item) => {
|
||||||
|
return {
|
||||||
|
adviceName: item.name || item.busNo, // 器材名称
|
||||||
|
adviceType: 2, // 耗材类型(后端接口中耗材的adviceType是2,但前端显示为4)
|
||||||
|
unitCode: item.unitCode || '', // 包装单位
|
||||||
|
unitCode_dictText: item.unitCode_dictText || '',
|
||||||
|
minUnitCode: item.minUnitCode || item.unitCode || '',
|
||||||
|
minUnitCode_dictText: item.minUnitCode_dictText || item.unitCode_dictText || '',
|
||||||
|
volume: item.size || item.totalVolume || '', // 规格
|
||||||
|
partPercent: item.partPercent || 1, // 拆零比
|
||||||
|
priceList: item.price ? [{ price: item.price }] : (item.retailPrice ? [{ price: item.retailPrice }] : []),
|
||||||
|
inventoryList: [], // 耗材可能没有库存列表,需要根据实际情况处理
|
||||||
|
adviceDefinitionId: item.id,
|
||||||
|
chargeItemDefinitionId: item.id,
|
||||||
|
positionId: item.locationId,
|
||||||
|
positionName: item.locationId_dictText || '',
|
||||||
|
// 其他可能需要的字段
|
||||||
|
dose: 0,
|
||||||
|
doseUnitCode: item.minUnitCode || item.unitCode || '',
|
||||||
|
doseUnitCode_dictText: item.minUnitCode_dictText || item.unitCode_dictText || '',
|
||||||
|
injectFlag: 0,
|
||||||
|
injectFlag_enumText: '否',
|
||||||
|
skinTestFlag: 0,
|
||||||
|
skinTestFlag_enumText: '否',
|
||||||
|
categoryCode: item.categoryCode || '',
|
||||||
|
// 耗材特有字段
|
||||||
|
deviceId: item.id, // 耗材ID
|
||||||
|
deviceName: item.name, // 耗材名称
|
||||||
|
// 保留原始数据以便后续使用
|
||||||
|
...item,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
adviceBaseList.value = convertedRecords;
|
||||||
|
total.value = res.data.total || convertedRecords.length;
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
currentIndex.value = 0;
|
||||||
|
if (adviceBaseList.value.length > 0) {
|
||||||
|
adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
adviceBaseList.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('获取耗材目录数据失败:', error);
|
||||||
|
adviceBaseList.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 调用医嘱基础信息接口(药品、诊疗等)
|
||||||
|
getAdviceBaseInfo(queryParams.value).then((res) => {
|
||||||
|
if (res.data.records && res.data.records.length > 0) {
|
||||||
|
let filteredRecords = res.data.records.filter((item) => {
|
||||||
|
// 后端已经根据adviceTypes参数进行了筛选,这里只需要进行前端补充筛选
|
||||||
|
|
||||||
|
// 过滤库存(药品和耗材需要检查库存,诊疗不需要检查库存)
|
||||||
|
if (item.adviceType == 1 || item.adviceType == 2) {
|
||||||
|
if (handleQuantity(item) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果设置了categoryCode筛选条件,进行筛选(用于区分西药和中成药)
|
||||||
|
// categoryCode = '1' 表示中成药,categoryCode = '2' 表示西药
|
||||||
|
// 注意:只有药品类型(adviceType=1)才需要根据categoryCode筛选
|
||||||
|
if (queryParams.value.categoryCode && item.adviceType == 1) {
|
||||||
|
// 只筛选药品类型
|
||||||
|
if (item.categoryCode != queryParams.value.categoryCode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
adviceBaseList.value = filteredRecords;
|
||||||
|
total.value = res.data.total;
|
||||||
|
nextTick(() => {
|
||||||
|
currentIndex.value = 0;
|
||||||
|
if (adviceBaseList.value.length > 0) {
|
||||||
|
adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
adviceBaseList.value = [];
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('获取数据失败:', error);
|
||||||
|
adviceBaseList.value = [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
// 处理键盘事件
|
// 处理键盘事件
|
||||||
const handleKeyDown = (event) => {
|
const handleKeyDown = (event) => {
|
||||||
const key = event.key;
|
const key = event.key;
|
||||||
|
|||||||
@@ -63,6 +63,17 @@ export function completeEncounter(encounterId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消接诊
|
||||||
|
*/
|
||||||
|
export function cancelEncounter(encounterId, config = {}) {
|
||||||
|
return request({
|
||||||
|
url: '/doctor-station/main/cancel-encounter?encounterId=' + encounterId,
|
||||||
|
method: 'get',
|
||||||
|
...config
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存病历
|
* 保存病历
|
||||||
*/
|
*/
|
||||||
@@ -212,6 +223,17 @@ export function getAdviceBaseInfo(queryParams) {
|
|||||||
params: queryParams
|
params: queryParams
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取耗材目录列表
|
||||||
|
*/
|
||||||
|
export function getDeviceList(queryParams) {
|
||||||
|
return request({
|
||||||
|
url: '/data-dictionary/device/information-page',
|
||||||
|
method: 'get',
|
||||||
|
params: queryParams
|
||||||
|
})
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 保存处方(单条)
|
* 保存处方(单条)
|
||||||
*/
|
*/
|
||||||
@@ -239,7 +261,8 @@ export function singOut(data) {
|
|||||||
return request({
|
return request({
|
||||||
url: '/doctor-station/advice/sign-off',
|
url: '/doctor-station/advice/sign-off',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data,
|
||||||
|
skipErrorMsg: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
>
|
>
|
||||||
<el-select v-model="scope.row.medTypeCode" placeholder=" " style="width: 150px">
|
<el-select v-model="scope.row.medTypeCode" placeholder=" " style="width: 150px">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in med_type"
|
v-for="item in diag_type"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
@@ -235,7 +235,7 @@ const props = defineProps({
|
|||||||
const emits = defineEmits(['diagnosisSave']);
|
const emits = defineEmits(['diagnosisSave']);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const { med_type } = proxy.useDict('med_type');
|
const { diag_type } = proxy.useDict('diag_type');
|
||||||
const rules = ref({
|
const rules = ref({
|
||||||
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
||||||
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
||||||
@@ -275,6 +275,10 @@ function getList() {
|
|||||||
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN')
|
diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN')
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// 获取诊断列表后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
console.log(form.value.diagnosisList);
|
console.log(form.value.diagnosisList);
|
||||||
}
|
}
|
||||||
@@ -320,6 +324,11 @@ function handleImport() {
|
|||||||
// 获取患者慢性病信息
|
// 获取患者慢性病信息
|
||||||
getChronicDisease({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
getChronicDisease({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||||
if (res.data && res.data.length > 0) {
|
if (res.data && res.data.length > 0) {
|
||||||
|
// 计算现有最大排序号
|
||||||
|
const maxSortNo = form.value.diagnosisList.length > 0
|
||||||
|
? Math.max(...form.value.diagnosisList.map(item => item.diagSrtNo || 0))
|
||||||
|
: 0;
|
||||||
|
|
||||||
res.data.forEach((item, index) => {
|
res.data.forEach((item, index) => {
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
...item,
|
...item,
|
||||||
@@ -327,7 +336,7 @@ function handleImport() {
|
|||||||
medTypeCode: '140104',
|
medTypeCode: '140104',
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
definitionId: item.id,
|
definitionId: item.id,
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: maxSortNo + index + 1,
|
||||||
iptDiseTypeCode: 2,
|
iptDiseTypeCode: 2,
|
||||||
diagnosisDesc: '',
|
diagnosisDesc: '',
|
||||||
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
@@ -335,6 +344,10 @@ function handleImport() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 导入完成后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
emits('diagnosisSave', false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -417,17 +430,26 @@ function handleAddDiagnosis() {
|
|||||||
proxy.$modal.msgWarning('请先填写病历');
|
proxy.$modal.msgWarning('请先填写病历');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 计算现有最大排序号
|
||||||
|
const maxSortNo = form.value.diagnosisList.length > 0
|
||||||
|
? Math.max(...form.value.diagnosisList.map(item => item.diagSrtNo || 0))
|
||||||
|
: 0;
|
||||||
|
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
showPopover: false,
|
showPopover: false,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
medTypeCode: '11',
|
medTypeCode: '初诊诊断',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: maxSortNo + 1,
|
||||||
iptDiseTypeCode: 2,
|
iptDiseTypeCode: 2,
|
||||||
diagnosisDesc: '',
|
diagnosisDesc: '',
|
||||||
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: new Date().toLocaleString('zh-CN')
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
}
|
}
|
||||||
@@ -445,12 +467,17 @@ function handleAddTcmDiagonsis() {
|
|||||||
*/
|
*/
|
||||||
function handleDeleteDiagnosis(row, index) {
|
function handleDeleteDiagnosis(row, index) {
|
||||||
if (row.conditionId) {
|
if (row.conditionId) {
|
||||||
delEncounterDiagnosis(row.conditionId).then(() => {
|
delEncounterDiagnosis(row.conditionId).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
proxy.$modal.msgSuccess('删除成功');
|
||||||
getList();
|
getList();
|
||||||
getTree();
|
getTree();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
form.value.diagnosisList.splice(index, 1);
|
form.value.diagnosisList.splice(index, 1);
|
||||||
|
// 删除后不重新计算排序号,保持用户设置的排序不变
|
||||||
|
emits('diagnosisSave', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,7 +485,6 @@ function handleMaindise(value, index) {
|
|||||||
if (value == 1) {
|
if (value == 1) {
|
||||||
let flag = 0;
|
let flag = 0;
|
||||||
form.value.diagnosisList.forEach((item) => {
|
form.value.diagnosisList.forEach((item) => {
|
||||||
console.log(item);
|
|
||||||
if (item.maindiseFlag == 1) {
|
if (item.maindiseFlag == 1) {
|
||||||
flag++;
|
flag++;
|
||||||
}
|
}
|
||||||
@@ -482,6 +508,9 @@ function handleSaveDiagnosis() {
|
|||||||
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
||||||
proxy.$modal.msgWarning('至少添加一条主诊断');
|
proxy.$modal.msgWarning('至少添加一条主诊断');
|
||||||
} else {
|
} else {
|
||||||
|
// 保存前按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
saveDiagnosis({
|
saveDiagnosis({
|
||||||
patientId: props.patientInfo.patientId,
|
patientId: props.patientInfo.patientId,
|
||||||
encounterId: props.patientInfo.encounterId,
|
encounterId: props.patientInfo.encounterId,
|
||||||
@@ -491,7 +520,7 @@ function handleSaveDiagnosis() {
|
|||||||
getTree();
|
getTree();
|
||||||
getList();
|
getList();
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
proxy.$modal.msgSuccess('诊断已保存');
|
proxy.$modal.msgSuccess('诊断已保存并按排序号排序');
|
||||||
//食源性疾病病例数据智能采集 ---START---
|
//食源性疾病病例数据智能采集 ---START---
|
||||||
isFoodDiseasesNew({
|
isFoodDiseasesNew({
|
||||||
encounterId: props.patientInfo.encounterId,
|
encounterId: props.patientInfo.encounterId,
|
||||||
@@ -566,16 +595,26 @@ function handleNodeClick(data) {
|
|||||||
proxy.$modal.msgWarning('该诊断项已存在');
|
proxy.$modal.msgWarning('该诊断项已存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算现有最大排序号
|
||||||
|
const maxSortNo = form.value.diagnosisList.length > 0
|
||||||
|
? Math.max(...form.value.diagnosisList.map(item => item.diagSrtNo || 0))
|
||||||
|
: 0;
|
||||||
|
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
ybNo: data.ybNo,
|
ybNo: data.ybNo,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
medTypeCode: '11',
|
medTypeCode: '11',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: maxSortNo + 1,
|
||||||
definitionId: data.definitionId,
|
definitionId: data.definitionId,
|
||||||
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: new Date().toLocaleString('zh-CN')
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,174 +10,125 @@
|
|||||||
<el-button type="primary" plain @click="handleEmrHistory()" style="margin-left: 20px">
|
<el-button type="primary" plain @click="handleEmrHistory()" style="margin-left: 20px">
|
||||||
历史病历
|
历史病历
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button type="primary" plain @click="handleReceive()" style="margin-left: 20px">
|
<!-- 可选:添加打印按钮 -->
|
||||||
|
<!-- <el-button type="primary" plain @click="printEmr" style="margin-left: 20px">
|
||||||
打印病历
|
打印病历
|
||||||
</el-button> -->
|
</el-button> -->
|
||||||
</div>
|
</div>
|
||||||
<div style="max-height: 650px; overflow-y: auto; overflow-x: hidden">
|
|
||||||
|
<div
|
||||||
|
ref="printArea"
|
||||||
|
style="max-height: 650px; overflow-y: auto; overflow-x: hidden; font-family: 'SimSun', '宋体', sans-serif;"
|
||||||
|
>
|
||||||
|
<!-- 标题 -->
|
||||||
<div style="text-align: center; font-size: 18px; font-weight: bold; margin-bottom: 10px;">
|
<div style="text-align: center; font-size: 18px; font-weight: bold; margin-bottom: 10px;">
|
||||||
{{ visitType === 'FIRST' ? '门诊初诊病历' : '门诊复诊病历' }}
|
{{ visitType === 'FIRST' ? '门诊初诊病历' : '门诊复诊病历' }}
|
||||||
</div>
|
</div>
|
||||||
<el-form ref="emrRef" :model="form" :rules="rules" label-width="80px">
|
|
||||||
<el-row :gutter="4">
|
<!-- 患者基本信息 -->
|
||||||
<el-col :span="4">
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
<el-form-item label="就诊卡号" prop="patientId" style="width: 100%">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-input placeholder="" v-model="patientInfo.patientId" class="input-with-bottom-border"/>
|
<strong>就诊卡号:</strong> {{ patientInfo.patientId || '' }}
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-col :span="4">
|
<strong>姓名:</strong> {{ patientInfo.patientName || '' }}
|
||||||
<el-form-item label="姓名" prop="patientName" style="width: 100%">
|
</div>
|
||||||
<el-input placeholder="" v-model="patientInfo.patientName" class="input-with-bottom-border"/>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>性别:</strong> {{ patientInfo.genderEnum_enumText || '' }}
|
||||||
</el-col>
|
</div>
|
||||||
<el-col :span="4">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-form-item label="性别" prop="genderEnum_enumText" style="width: 100%">
|
<strong>年龄:</strong> {{ patientInfo.age || '' }}
|
||||||
<el-input placeholder="" v-model="patientInfo.genderEnum_enumText" class="input-with-bottom-border"/>
|
</div>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
|
||||||
<el-col :span="4">
|
<!-- 就诊信息 -->
|
||||||
<el-form-item label="年龄" prop="age" style="width: 100%">
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
<el-input placeholder="" v-model="patientInfo.age" class="input-with-bottom-border"/>
|
<div style="flex: 1; min-width: 200px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>就诊日期:</strong> {{ currentVisitDate }}
|
||||||
</el-col>
|
</div>
|
||||||
<el-col :span="4">
|
<div style="flex: 1; min-width: 200px; font-size: 14px; line-height: 24px;">
|
||||||
<el-form-item label="就诊日期" prop="currentVisitDate" style="width: 100%">
|
<strong>就诊科室:</strong> {{ patientInfo.organizationName || '' }}
|
||||||
<el-input placeholder="" v-model="currentVisitDate" class="input-with-bottom-border"/>
|
</div>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
|
||||||
<el-col :span="4">
|
<!-- 生命体征 -->
|
||||||
<el-form-item label="就诊科室" prop="organizationName" style="width: 100%">
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
<el-input placeholder="" v-model="patientInfo.organizationName" class="input-with-bottom-border"/>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>身高:</strong>
|
||||||
</el-col>
|
<el-input
|
||||||
</el-row>
|
v-model="form.height"
|
||||||
<el-row :gutter="24">
|
style="width: 80px; margin-left: 5px;"
|
||||||
<el-col :span="6">
|
/> cm
|
||||||
<el-form-item label="身高" prop="height" style="width: 100%">
|
</div>
|
||||||
<el-input placeholder="" v-model="form.height" class="input-with-bottom-border">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<template #suffix>cm</template>
|
<strong>体重:</strong>
|
||||||
</el-input>
|
<el-input
|
||||||
</el-form-item>
|
v-model="form.weight"
|
||||||
</el-col>
|
style="width: 80px; margin-left: 5px;"
|
||||||
<el-col :span="6">
|
/> kg
|
||||||
<el-form-item label="体重" prop="weight" style="width: 100%">
|
</div>
|
||||||
<el-input placeholder="" v-model="form.weight" class="input-with-bottom-border">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<template #suffix>kg</template>
|
<strong>体温:</strong>
|
||||||
</el-input>
|
<el-input
|
||||||
</el-form-item>
|
v-model="form.temperature"
|
||||||
</el-col>
|
style="width: 80px; margin-left: 5px;"
|
||||||
<el-col :span="6">
|
:step="0.1"
|
||||||
<el-form-item label="体温" prop="temperature" style="width: 100%">
|
/> ℃
|
||||||
<el-input placeholder="" v-model="form.temperature" class="input-with-bottom-border">
|
</div>
|
||||||
<template #suffix>℃</template>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
</el-input>
|
<strong>脉搏:</strong>
|
||||||
</el-form-item>
|
<el-input
|
||||||
</el-col>
|
v-model="form.pulse"
|
||||||
<el-col :span="6">
|
style="width: 80px; margin-left: 5px;"
|
||||||
<el-form-item label="脉搏" prop="pulse" style="width: 100%">
|
/> 次/分
|
||||||
<el-input placeholder="" v-model="form.pulse" class="input-with-bottom-border">
|
</div>
|
||||||
<template #suffix>次/分</template>
|
</div>
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
<!-- 主诉 + 发病日期 -->
|
||||||
</el-col>
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
</el-row>
|
<div style="flex: 1; min-width: 300px; font-size: 14px; line-height: 24px;">
|
||||||
<el-row :gutter="24">
|
<strong>主诉:</strong>
|
||||||
<!-- <el-col :span="6">
|
<el-input
|
||||||
<el-form-item
|
v-model="form.chiefComplaint"
|
||||||
label="血糖"
|
style="width: calc(100% - 50px); margin-left: 5px;"
|
||||||
prop="chiefComplaint"
|
/>
|
||||||
style="width: 100%"
|
</div>
|
||||||
>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
<strong>发病日期:</strong>
|
||||||
<template #suffix></template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item
|
|
||||||
label="血糖"
|
|
||||||
prop="chiefComplaint"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
|
||||||
<template #suffix>mmol/L</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item
|
|
||||||
label="收缩压"
|
|
||||||
prop="chiefComplaint"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
|
||||||
<template #suffix>mmHg</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item
|
|
||||||
label="舒张压"
|
|
||||||
prop="chiefComplaint"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
|
||||||
<template #suffix>mmHg</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col> -->
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="24">
|
|
||||||
<el-col :span="18">
|
|
||||||
<el-form-item label="主诉" prop="chiefComplaint">
|
|
||||||
<el-input v-model="form.chiefComplaint" type="textarea" :rows="1" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item label="发病日期" prop="onsetDate">
|
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="form.onsetDate"
|
v-model="form.onsetDate"
|
||||||
type="date"
|
type="date"
|
||||||
size="default"
|
style="width: calc(100% - 80px); margin-left: 5px;"
|
||||||
style="width: 100% !important"
|
value-format="YYYY-MM-DD"
|
||||||
placement="bottom"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-form-item label="现病史" prop="currentIllnessHistory">
|
<!-- 多行文本字段 -->
|
||||||
<el-input v-model="form.currentIllnessHistory" type="textarea" :rows="2" placeholder="" />
|
<div v-for="field in textFieldList" :key="field.key" style="padding: 10px 0;">
|
||||||
</el-form-item>
|
<div style="font-size: 14px; margin-bottom: 5px;">
|
||||||
<el-form-item label="既往史" prop="pastMedicalHistory">
|
<strong>{{ field.label }}:</strong>
|
||||||
<el-input v-model="form.pastMedicalHistory" type="textarea" :rows="2" placeholder="" />
|
</div>
|
||||||
</el-form-item>
|
<el-input
|
||||||
<el-form-item label="个人史" prop="menstrualHistory">
|
v-model="form[field.key]"
|
||||||
<el-input v-model="form.menstrualHistory" type="textarea" :rows="2" placeholder="" />
|
type="textarea"
|
||||||
</el-form-item>
|
:rows="4"
|
||||||
<el-form-item label="过敏史" prop="allergyHistory">
|
style="width: 100%; font-size: 14px; line-height: 1.5;"
|
||||||
<el-input v-model="form.allergyHistory" type="textarea" :rows="2" placeholder="" />
|
/>
|
||||||
</el-form-item>
|
</div>
|
||||||
<el-form-item label="查体" prop="physicalExamination">
|
|
||||||
<el-input v-model="form.physicalExamination" type="textarea" :rows="2" placeholder="" />
|
<!-- 弹窗 -->
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="处理" prop="treatment">
|
|
||||||
<el-input v-model="form.treatment" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="辅助检查" prop="auxiliaryExamination">
|
|
||||||
<el-input v-model="form.auxiliaryExamination" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="emrTitle"
|
:title="emrTitle"
|
||||||
v-model="openEmrTemplate"
|
v-model="openEmrTemplate"
|
||||||
:width="showDialog == 'emrHistory'?'800px':'600px'"
|
:width="showDialog === 'emrHistory' ? '800px' : '600px'"
|
||||||
append-to-body
|
append-to-body
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
>
|
>
|
||||||
<emrTemplate v-if="showDialog == 'emrTemplate'" @selectRow="templateSelect" />
|
<emrTemplate v-if="showDialog === 'emrTemplate'" @selectRow="templateSelect" />
|
||||||
<emrhistory v-if="showDialog == 'emrHistory'" @selectRow="emrHistorySelect" />
|
<emrhistory v-if="showDialog === 'emrHistory'" @selectRow="emrHistorySelect" />
|
||||||
<div v-if="showDialog == 'saveTemplate'">
|
<div v-if="showDialog === 'saveTemplate'">
|
||||||
<span> 模板名称: </span>
|
<span>模板名称:</span>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="templateName"
|
v-model="templateName"
|
||||||
style="width: 260px; margin-top: 10px; margin-right: 20px"
|
style="width: 260px; margin-top: 10px; margin-right: 20px"
|
||||||
@@ -203,91 +154,114 @@ import { saveEmr, getEmrDetail, saveEmrTemplate } from '../api';
|
|||||||
import emrTemplate from '../emr/emrtemplate.vue';
|
import emrTemplate from '../emr/emrtemplate.vue';
|
||||||
import emrhistory from '../emr/emrhistory.vue';
|
import emrhistory from '../emr/emrhistory.vue';
|
||||||
|
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, watch, getCurrentInstance } from 'vue';
|
||||||
|
import { formatDate as formatDateUtil } from '@/utils/index';
|
||||||
|
|
||||||
// 2. 当前就诊日期(默认为当前时间)
|
// Props
|
||||||
const currentVisitDate = computed(() => {
|
|
||||||
return new Date().toLocaleString('zh-CN', {
|
|
||||||
year: 'numeric',
|
|
||||||
month: '2-digit',
|
|
||||||
day: '2-digit',
|
|
||||||
hour: '2-digit',
|
|
||||||
minute: '2-digit',
|
|
||||||
second: '2-digit',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = ref({});
|
|
||||||
const emrTitle = ref('');
|
|
||||||
const radio = ref(1);
|
|
||||||
const rules = ref({
|
|
||||||
chiefComplaint: [{ required: true, message: '请输入主诉', trigger: 'blur' }],
|
|
||||||
});
|
|
||||||
const emits = defineEmits(['save']);
|
|
||||||
const { proxy } = getCurrentInstance();
|
|
||||||
const showDialog = ref('');
|
|
||||||
const openEmrTemplate = ref(false);
|
|
||||||
const templateName = ref('');
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
patientInfo: {
|
patientInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
visitType: { // ✅ 接收父组件传来的值
|
visitType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
firstVisitDate: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Computed: 当前就诊日期
|
||||||
|
const currentVisitDate = computed(() => {
|
||||||
|
if (props.visitType === 'FOLLOW_UP' && props.firstVisitDate) {
|
||||||
|
return props.firstVisitDate;
|
||||||
|
}
|
||||||
|
return formatDateUtil(props.patientInfo?.registerTime || new Date());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = ref({
|
||||||
|
height: '',
|
||||||
|
weight: '',
|
||||||
|
temperature: '',
|
||||||
|
pulse: '',
|
||||||
|
chiefComplaint: '',
|
||||||
|
onsetDate: '',
|
||||||
|
currentIllnessHistory: '',
|
||||||
|
pastMedicalHistory: '',
|
||||||
|
menstrualHistory: '',
|
||||||
|
allergyHistory: '',
|
||||||
|
physicalExamination: '',
|
||||||
|
treatment: '',
|
||||||
|
auxiliaryExamination: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 文本字段配置(用于循环渲染)
|
||||||
|
const textFieldList = [
|
||||||
|
{ key: 'currentIllnessHistory', label: '现病史' },
|
||||||
|
{ key: 'pastMedicalHistory', label: '既往史' },
|
||||||
|
{ key: 'menstrualHistory', label: '个人史' },
|
||||||
|
{ key: 'allergyHistory', label: '过敏史' },
|
||||||
|
{ key: 'physicalExamination', label: '查体' },
|
||||||
|
{ key: 'treatment', label: '处理' },
|
||||||
|
{ key: 'auxiliaryExamination', label: '辅助检查' },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 弹窗控制
|
||||||
|
const emrTitle = ref('');
|
||||||
|
const radio = ref(1);
|
||||||
|
const showDialog = ref('');
|
||||||
|
const openEmrTemplate = ref(false);
|
||||||
|
const templateName = ref('');
|
||||||
|
|
||||||
|
// 事件
|
||||||
|
const emits = defineEmits(['save']);
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
// 监听表单变化
|
||||||
watch(
|
watch(
|
||||||
() => form.value,
|
() => form.value,
|
||||||
() => {
|
() => {
|
||||||
// 如果表单数据有变化,通知父组件保存
|
|
||||||
emits('save', false);
|
emits('save', false);
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
// 格式化日期(用于 onsetDate)
|
||||||
* 保存病历
|
function formatDate(date) {
|
||||||
*/
|
if (!date) return '';
|
||||||
|
return formatDateUtil(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存病历
|
||||||
function addEmr() {
|
function addEmr() {
|
||||||
proxy.$refs['emrRef'].validate((valid) => {
|
// 简单校验主诉
|
||||||
if (valid) {
|
if (!form.value.chiefComplaint) {
|
||||||
|
proxy.$message.warning('请输入主诉');
|
||||||
|
return;
|
||||||
|
}
|
||||||
saveEmr({
|
saveEmr({
|
||||||
patientId: props.patientInfo.patientId,
|
patientId: props.patientInfo.patientId,
|
||||||
encounterId: props.patientInfo.encounterId,
|
encounterId: props.patientInfo.encounterId,
|
||||||
contextJson: form.value,
|
contextJson: form.value,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code === 200) {
|
||||||
proxy.$modal.msgSuccess('病历已保存');
|
proxy.$modal.msgSuccess('病历已保存');
|
||||||
emits('save', true);
|
emits('save', true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 病历模板
|
// 打开模板
|
||||||
*/
|
|
||||||
function handleEmrTemplate() {
|
function handleEmrTemplate() {
|
||||||
emrTitle.value = '病历模板';
|
emrTitle.value = '病历模板';
|
||||||
showDialog.value = 'emrTemplate';
|
showDialog.value = 'emrTemplate';
|
||||||
openEmrTemplate.value = true;
|
openEmrTemplate.value = true;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 选择病历模板
|
// 打开历史
|
||||||
*/
|
|
||||||
function templateSelect(row) {
|
|
||||||
form.value = row;
|
|
||||||
}
|
|
||||||
function emrHistorySelect(row) {
|
|
||||||
form.value = row;
|
|
||||||
openEmrTemplate.value = false;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 历史病历
|
|
||||||
*/
|
|
||||||
function handleEmrHistory() {
|
function handleEmrHistory() {
|
||||||
emrTitle.value = '历史病历';
|
emrTitle.value = '历史病历';
|
||||||
showDialog.value = 'emrHistory';
|
showDialog.value = 'emrHistory';
|
||||||
@@ -295,55 +269,93 @@ function handleEmrHistory() {
|
|||||||
sessionStorage.setItem('patientId', props.patientInfo.patientId);
|
sessionStorage.setItem('patientId', props.patientInfo.patientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDetail(encounterId) {
|
// 保存为模板
|
||||||
getEmrDetail(encounterId).then((res) => {
|
|
||||||
if (res.data) {
|
|
||||||
form.value = JSON.parse(res.data.contextJson);
|
|
||||||
// 提交父组件刷新保存装填
|
|
||||||
emits('save', true);
|
|
||||||
} else {
|
|
||||||
form.value = {};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存病历模板
|
|
||||||
*/
|
|
||||||
function handleSaveTemplate() {
|
function handleSaveTemplate() {
|
||||||
emrTitle.value = '保存模板';
|
emrTitle.value = '保存模板';
|
||||||
showDialog.value = 'saveTemplate';
|
showDialog.value = 'saveTemplate';
|
||||||
openEmrTemplate.value = true;
|
openEmrTemplate.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 选择模板/历史
|
||||||
* 弹窗确认操作,包括保存病历模板/选择病历模板/选择历史病历
|
function templateSelect(row) {
|
||||||
*/
|
form.value = { ...row };
|
||||||
|
openEmrTemplate.value = false;
|
||||||
|
}
|
||||||
|
function emrHistorySelect(row) {
|
||||||
|
form.value = { ...row };
|
||||||
|
openEmrTemplate.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 弹窗确认
|
||||||
function submit() {
|
function submit() {
|
||||||
switch (showDialog.value) {
|
if (showDialog.value === 'saveTemplate') {
|
||||||
case 'saveTemplate':
|
if (!templateName.value.trim()) {
|
||||||
|
proxy.$message.warning('请输入模板名称');
|
||||||
|
return;
|
||||||
|
}
|
||||||
saveEmrTemplate({
|
saveEmrTemplate({
|
||||||
templateName: templateName.value,
|
templateName: templateName.value,
|
||||||
useScopeCode: radio.value,
|
useScopeCode: radio.value,
|
||||||
contextJson: form.value,
|
contextJson: form.value,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code === 200) {
|
||||||
openEmrTemplate.value = false;
|
openEmrTemplate.value = false;
|
||||||
proxy.$modal.msgSuccess('保存成功');
|
proxy.$modal.msgSuccess('保存成功');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
} else {
|
||||||
case 'emrTemplate':
|
|
||||||
openEmrTemplate.value = false;
|
openEmrTemplate.value = false;
|
||||||
break;
|
|
||||||
case 'emrHistory':
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancel() {
|
function cancel() {
|
||||||
openEmrTemplate.value = false;
|
openEmrTemplate.value = false;
|
||||||
// openDiagnosis.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ getDetail, addEmr });
|
// 可选:打印功能
|
||||||
|
// function printEmr() {
|
||||||
|
// const printContent = proxy.$refs.printArea.innerHTML;
|
||||||
|
// const originalContent = document.body.innerHTML;
|
||||||
|
// document.body.innerHTML = printContent;
|
||||||
|
// window.print();
|
||||||
|
// document.body.innerHTML = originalContent;
|
||||||
|
// window.location.reload(); // 恢复组件状态
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
getDetail(encounterId) {
|
||||||
|
getEmrDetail(encounterId).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
try {
|
||||||
|
form.value = JSON.parse(res.data.contextJson) || {};
|
||||||
|
} catch (e) {
|
||||||
|
form.value = {};
|
||||||
|
}
|
||||||
|
emits('save', true);
|
||||||
|
} else {
|
||||||
|
form.value = {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addEmr
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 可选:增强打印样式 */
|
||||||
|
@media print {
|
||||||
|
body * {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
#printArea, #printArea * {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
#printArea {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -10,23 +10,15 @@
|
|||||||
<el-table
|
<el-table
|
||||||
ref="emrHistoryRef"
|
ref="emrHistoryRef"
|
||||||
:data="emrHistory"
|
:data="emrHistory"
|
||||||
row-key="patientId"
|
row-key="id"
|
||||||
highlight-current-row
|
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
<!-- @cell-click="clickRow" -->
|
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column label="主诉" align="left" prop="name" :show-overflow-tooltip="true"/>
|
<el-table-column label="主诉" align="left" prop="name" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="时间" align="center" prop="createTime" width="180" :show-overflow-tooltip="true"/>
|
<el-table-column label="时间" align="center" prop="createTime" width="180" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="操作" align="center" width="80">
|
<el-table-column label="操作" align="center" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- <el-button
|
<el-button link type="primary" @click.stop="clickRow(scope.row)">复用</el-button>
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click.stop="handelDetail(scope.row)"
|
|
||||||
>详情
|
|
||||||
</el-button> -->
|
|
||||||
<el-button link type="primary" @click.stop="clickRow(scope.row)">复用 </el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -43,6 +35,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { formatDate, formatDateymd } from '@/utils/index';
|
import { formatDate, formatDateymd } from '@/utils/index';
|
||||||
import { getEmrHistoryList } from '../api';
|
import { getEmrHistoryList } from '../api';
|
||||||
|
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -51,13 +44,19 @@ const queryParams = ref({
|
|||||||
const selectRow = ref({});
|
const selectRow = ref({});
|
||||||
const emrHistory = ref([]);
|
const emrHistory = ref([]);
|
||||||
const emits = defineEmits(['selectRow']);
|
const emits = defineEmits(['selectRow']);
|
||||||
|
const emrHistoryRef = ref(null);
|
||||||
|
const selectedRows = ref([]);
|
||||||
|
|
||||||
|
const total = ref(0);
|
||||||
|
|
||||||
getList();
|
getList();
|
||||||
|
|
||||||
function getList() {
|
function getList() {
|
||||||
if (sessionStorage.getItem('patientId')) {
|
if (sessionStorage.getItem('patientId')) {
|
||||||
queryParams.value.patientId = sessionStorage.getItem('patientId');
|
queryParams.value.patientId = sessionStorage.getItem('patientId');
|
||||||
getEmrHistoryList(queryParams.value).then((res) => {
|
getEmrHistoryList(queryParams.value).then((res) => {
|
||||||
emrHistory.value = res.data.records;
|
emrHistory.value = res.data.records;
|
||||||
|
total.value = res.data.total;
|
||||||
emrHistory.value.map((k) => {
|
emrHistory.value.map((k) => {
|
||||||
k.name = JSON.parse(k.contextJson).chiefComplaint;
|
k.name = JSON.parse(k.contextJson).chiefComplaint;
|
||||||
k.createTime = formatDate(k.createTime);
|
k.createTime = formatDate(k.createTime);
|
||||||
@@ -66,6 +65,12 @@ function getList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSelectionChange(selection) {
|
||||||
|
// 直接更新选中行数据,不干涉表格UI状态
|
||||||
|
// 这样可以允许用户使用全选框功能
|
||||||
|
selectedRows.value = selection;
|
||||||
|
}
|
||||||
|
|
||||||
function clickRow(row) {
|
function clickRow(row) {
|
||||||
selectRow.value = JSON.parse(row.contextJson);
|
selectRow.value = JSON.parse(row.contextJson);
|
||||||
emits('selectRow', selectRow.value);
|
emits('selectRow', selectRow.value);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const props = defineProps({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// getList();
|
getList();
|
||||||
function getList() {
|
function getList() {
|
||||||
queryParams.value.useScopeCode = 1;
|
queryParams.value.useScopeCode = 1;
|
||||||
getEmrTemplateList(queryParams.value).then((res) => {
|
getEmrTemplateList(queryParams.value).then((res) => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -13,10 +13,19 @@
|
|||||||
>
|
>
|
||||||
<plus />
|
<plus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
<el-icon
|
||||||
|
class="delete-icon"
|
||||||
|
title="删除处方单"
|
||||||
|
@click="handleDeletePrescriptionClick(index)"
|
||||||
|
:class="{ 'disabled-icon': isPrescriptionDeletable(index) !== true }"
|
||||||
|
style="font-size: 20px !important; margin-left: 10px; color: #f56c6c"
|
||||||
|
>
|
||||||
|
<minus />
|
||||||
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="summary">
|
<div class="summary">
|
||||||
<span class="summary-item">药品数: {{ '1' }}种</span>
|
<span class="summary-item">药品数: {{ getPrescriptionMedicineCount(index) }}种</span>
|
||||||
<span class="summary-item">总价: ¥ {{ 100 }}</span>
|
<span class="summary-item">总价: ¥ {{ getPrescriptionTotalPrice(index) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -660,6 +669,51 @@ function addNewPrescription(){
|
|||||||
tcmPrescriptionList.value.push({})
|
tcmPrescriptionList.value.push({})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 删除处方单
|
||||||
|
function handleDeletePrescriptionClick(prescriptionIndex) {
|
||||||
|
if (!isPrescriptionDeletable(prescriptionIndex)) {
|
||||||
|
const medicineCount = getPrescriptionMedicineCount(prescriptionIndex);
|
||||||
|
if (medicineCount > 0) {
|
||||||
|
proxy.$modal.msgWarning('该处方单还有药品,请先删除所有药品后再删除处方单');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有已签发的药品
|
||||||
|
const hasChargedItems = prescriptionList.value.some(item => item.statusEnum === 2);
|
||||||
|
if (hasChargedItems) {
|
||||||
|
proxy.$modal.msgWarning('该处方单已收费,不能删除');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认删除
|
||||||
|
proxy.$modal.confirm('确定要删除这个处方单吗?').then(() => {
|
||||||
|
tcmPrescriptionList.value.splice(prescriptionIndex, 1);
|
||||||
|
proxy.$modal.msgSuccess('处方单删除成功');
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查处方是否可删除
|
||||||
|
function isPrescriptionDeletable(prescriptionIndex) {
|
||||||
|
const medicineCount = getPrescriptionMedicineCount(prescriptionIndex);
|
||||||
|
if (medicineCount > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有已签发的药品
|
||||||
|
const hasChargedItems = prescriptionList.value.some(item => item.statusEnum === 2);
|
||||||
|
return !hasChargedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取处方中的药品数量
|
||||||
|
function getPrescriptionMedicineCount(prescriptionIndex) {
|
||||||
|
// 这里需要根据实际的业务逻辑来计算
|
||||||
|
// 假设每个处方对应一组药品,这里简化处理
|
||||||
|
return prescriptionList.value.filter(item => item.statusEnum !== 2).length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择药品回调
|
* 选择药品回调
|
||||||
*/
|
*/
|
||||||
@@ -801,6 +855,37 @@ function handleDelete() {
|
|||||||
groupMarkers.value = getGroupMarkers(prescriptionList.value); // 删除行会出现组号混乱的情况,所以这里重新更新标记
|
groupMarkers.value = getGroupMarkers(prescriptionList.value); // 删除行会出现组号混乱的情况,所以这里重新更新标记
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断处方单是否可删除
|
||||||
|
function isPrescriptionDeletable(prescriptionIndex) {
|
||||||
|
// 条件1:处方单没有药品
|
||||||
|
const medicineCount = getPrescriptionMedicineCount(prescriptionIndex);
|
||||||
|
if (medicineCount > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 条件2:处方单未收费(已签发的处方不能删除)
|
||||||
|
// 检查是否有已签发的药品(statusEnum == 2 表示已签发)
|
||||||
|
const hasChargedItems = prescriptionList.value.some(item => item.statusEnum === 2);
|
||||||
|
if (hasChargedItems) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除处方单
|
||||||
|
function handleDeletePrescriptionClick(prescriptionIndex) {
|
||||||
|
if (!isPrescriptionDeletable(prescriptionIndex)) {
|
||||||
|
proxy.$modal.msgWarning('该处方单不可删除');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy.$modal.confirm('确认删除该处方单吗?').then(() => {
|
||||||
|
tcmPrescriptionList.value.splice(prescriptionIndex, 1);
|
||||||
|
proxy.$modal.msgSuccess('删除成功');
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
function handleNumberClick(item, index) {
|
function handleNumberClick(item, index) {
|
||||||
prescriptionList.value[index].unitPrice = item.price;
|
prescriptionList.value[index].unitPrice = item.price;
|
||||||
// prescriptionList.value[index].lotNumber = item.lotNumber;
|
// prescriptionList.value[index].lotNumber = item.lotNumber;
|
||||||
@@ -1599,6 +1684,90 @@ function validateGroups(saveList) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// 获取处方单药品数量
|
||||||
|
function getPrescriptionMedicineCount(prescriptionIndex) {
|
||||||
|
// 这里需要根据实际数据结构来判断,暂时返回0
|
||||||
|
// TODO: 根据处方单索引获取对应的药品数量
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取处方单总价
|
||||||
|
function getPrescriptionTotalPrice(prescriptionIndex) {
|
||||||
|
// 这里需要根据实际数据结构来判断,暂时返回0
|
||||||
|
// TODO: 根据处方单索引获取对应的总价
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断处方单是否可删除
|
||||||
|
function isPrescriptionDeletable(prescriptionIndex) {
|
||||||
|
// 条件1:处方单没有药品
|
||||||
|
const medicineCount = getPrescriptionMedicineCount(prescriptionIndex);
|
||||||
|
if (medicineCount > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 条件2:处方单未收费(这里需要根据实际收费状态字段判断)
|
||||||
|
// TODO: 根据实际的收费状态字段来判断
|
||||||
|
// const isCharged = checkPrescriptionCharged(prescriptionIndex);
|
||||||
|
// if (isCharged) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除处方单
|
||||||
|
function handleDeletePrescriptionClick(prescriptionIndex) {
|
||||||
|
if (!isPrescriptionDeletable(prescriptionIndex)) {
|
||||||
|
const medicineCount = getPrescriptionMedicineCount(prescriptionIndex);
|
||||||
|
if (medicineCount > 0) {
|
||||||
|
proxy.$modal.msgWarning('该处方单还有药品,请先删除所有药品后再删除处方单');
|
||||||
|
} else {
|
||||||
|
proxy.$modal.msgWarning('该处方单已收费,不能删除');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认删除
|
||||||
|
proxy.$modal.confirm('确定要删除这个处方单吗?').then(() => {
|
||||||
|
tcmPrescriptionList.value.splice(prescriptionIndex, 1);
|
||||||
|
proxy.$modal.msgSuccess('处方单删除成功');
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取处方单药品数量
|
||||||
|
function getPrescriptionMedicineCount(prescriptionIndex) {
|
||||||
|
// 目前所有药品都在 prescriptionList 中,暂时返回总数量
|
||||||
|
// TODO: 将来需要按处方单分组药品
|
||||||
|
return prescriptionList.value.filter(item => item.statusEnum !== 2).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取处方单总价
|
||||||
|
function getPrescriptionTotalPrice(prescriptionIndex) {
|
||||||
|
// 目前所有药品都在 prescriptionList 中,暂时返回总价
|
||||||
|
// TODO: 将来需要按处方单分组计算总价
|
||||||
|
return prescriptionList.value
|
||||||
|
.filter(item => item.statusEnum !== 2)
|
||||||
|
.reduce((total, item) => total + (Number(item.totalPrice) || 0), 0)
|
||||||
|
.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断处方单是否可删除
|
||||||
|
function isPrescriptionDeletable(prescriptionIndex) {
|
||||||
|
// 条件1:处方单没有药品
|
||||||
|
const medicineCount = getPrescriptionMedicineCount(prescriptionIndex);
|
||||||
|
if (medicineCount > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 条件2:处方单未收费(这里需要根据实际收费状态字段判断)
|
||||||
|
// TODO: 根据实际的收费状态字段来判断
|
||||||
|
// 暂时返回true,等有收费状态字段后再完善
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({ getListInfo, getDiagnosisInfo });
|
defineExpose({ getListInfo, getDiagnosisInfo });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -1711,4 +1880,25 @@ defineExpose({ getListInfo, getDiagnosisInfo });
|
|||||||
.add-icon:hover {
|
.add-icon:hover {
|
||||||
background-color: #ecf5ff;
|
background-color: #ecf5ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.delete-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 4px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-icon:hover {
|
||||||
|
background-color: #fef0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-icon.disabled-icon {
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: #c0c4cc !important;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-icon.disabled-icon:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -100,8 +100,8 @@
|
|||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="" width="350">
|
<el-descriptions-item label="" width="350">
|
||||||
<!-- 初诊 / 复诊 按钮 -->
|
<!-- 初诊 / 复诊 按钮 -->
|
||||||
<el-radio v-model="visitType" label="FIRST">初诊</el-radio>
|
<el-radio v-model="visitType" label="FIRST" :disabled="visitTypeDisabled">初诊</el-radio>
|
||||||
<el-radio v-model="visitType" label="FOLLOW_UP">复诊</el-radio>
|
<el-radio v-model="visitType" label="FOLLOW_UP" :disabled="visitTypeDisabled">复诊</el-radio>
|
||||||
|
|
||||||
<!-- 原有按钮 -->
|
<!-- 原有按钮 -->
|
||||||
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
|
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
|
||||||
@@ -127,6 +127,13 @@
|
|||||||
>
|
>
|
||||||
办理住院
|
办理住院
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click.stop="handleCancelEncounter"
|
||||||
|
>
|
||||||
|
取消接诊
|
||||||
|
</el-button>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
@@ -148,6 +155,7 @@
|
|||||||
}
|
}
|
||||||
"
|
"
|
||||||
:visitType="visitType"
|
:visitType="visitType"
|
||||||
|
:firstVisitDate="firstVisitDate"
|
||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="诊断" name="diagnosis">
|
<el-tab-pane label="诊断" name="diagnosis">
|
||||||
@@ -206,6 +214,7 @@ import {
|
|||||||
leaveEncounter,
|
leaveEncounter,
|
||||||
completeEncounter,
|
completeEncounter,
|
||||||
getEnPrescriptionInfo,
|
getEnPrescriptionInfo,
|
||||||
|
cancelEncounter,
|
||||||
getEmrHistoryList
|
getEmrHistoryList
|
||||||
} from './components/api.js';
|
} from './components/api.js';
|
||||||
import prescriptionlist from './components/prescription/prescriptionlist.vue';
|
import prescriptionlist from './components/prescription/prescriptionlist.vue';
|
||||||
@@ -253,6 +262,8 @@ const emits = defineEmits(['click']);
|
|||||||
const activeTab = ref('emr');
|
const activeTab = ref('emr');
|
||||||
const patientList = ref([]);
|
const patientList = ref([]);
|
||||||
const patientInfo = ref({});
|
const patientInfo = ref({});
|
||||||
|
const visitTypeDisabled = ref(false);
|
||||||
|
|
||||||
const prescriptionInfo = ref([]);
|
const prescriptionInfo = ref([]);
|
||||||
const registerTime = ref([formatDate(new Date()), formatDate(new Date())]);
|
const registerTime = ref([formatDate(new Date()), formatDate(new Date())]);
|
||||||
const patientDrawerRef = ref();
|
const patientDrawerRef = ref();
|
||||||
@@ -264,6 +275,7 @@ const waitCount = ref(0);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const visitType = ref('');
|
const visitType = ref('');
|
||||||
|
const firstVisitDate = ref('');
|
||||||
const disabled = computed(() => {
|
const disabled = computed(() => {
|
||||||
return Object.keys(patientInfo.value).length === 0;
|
return Object.keys(patientInfo.value).length === 0;
|
||||||
});
|
});
|
||||||
@@ -290,6 +302,10 @@ function setVisitType(type) {
|
|||||||
visitType.value = type;
|
visitType.value = type;
|
||||||
}
|
}
|
||||||
function checkPatientHistory(patient) {
|
function checkPatientHistory(patient) {
|
||||||
|
// 重置状态
|
||||||
|
visitTypeDisabled.value = false;
|
||||||
|
firstVisitDate.value = '';
|
||||||
|
|
||||||
// 如果患者没有身份证号,无法判断是否为初诊
|
// 如果患者没有身份证号,无法判断是否为初诊
|
||||||
if (!patient.idCard) {
|
if (!patient.idCard) {
|
||||||
// 默认设置为初诊
|
// 默认设置为初诊
|
||||||
@@ -297,6 +313,16 @@ function checkPatientHistory(patient) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // 如果当前就诊已经有明确的初复诊标识,则使用该标识
|
||||||
|
// if (patient.visitType) {
|
||||||
|
// visitType.value = patient.visitType;
|
||||||
|
// // 如果是已完诊的记录,禁用修改
|
||||||
|
// if (patient.statusEnum && patient.statusEnum !== 2) { // 假设2是就诊中状态
|
||||||
|
// visitTypeDisabled.value = true;
|
||||||
|
// }
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
// 查询患者历史就诊记录
|
// 查询患者历史就诊记录
|
||||||
const params = {
|
const params = {
|
||||||
patientId: patient.patientId,
|
patientId: patient.patientId,
|
||||||
@@ -305,20 +331,31 @@ function checkPatientHistory(patient) {
|
|||||||
|
|
||||||
getEmrHistoryList(params).then(res => {
|
getEmrHistoryList(params).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
const records = res.data?.records || [];
|
||||||
// 如果有历史记录,则为复诊
|
// 如果有历史记录,则为复诊
|
||||||
if (res.data && res.data.total > 0) {
|
if (res.data && res.data.total > 0) {
|
||||||
visitType.value = 'FOLLOW_UP';
|
visitType.value = 'FOLLOW_UP';
|
||||||
|
// 计算最早一次病历创建时间作为初诊日期
|
||||||
|
const earliest = records.reduce((min, cur) => {
|
||||||
|
const ct = new Date(cur.createTime).getTime();
|
||||||
|
return ct < min ? ct : min;
|
||||||
|
}, new Date(records[0].createTime).getTime());
|
||||||
|
// 使用统一格式化
|
||||||
|
firstVisitDate.value = formatDate(earliest);
|
||||||
} else {
|
} else {
|
||||||
// 如果没有历史记录,则为初诊
|
// 如果没有历史记录,则为初诊
|
||||||
visitType.value = 'FIRST';
|
visitType.value = 'FIRST';
|
||||||
|
firstVisitDate.value = '';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 请求失败,默认设置为初诊
|
// 请求失败,默认设置为初诊
|
||||||
visitType.value = 'FIRST';
|
visitType.value = 'FIRST';
|
||||||
|
firstVisitDate.value = '';
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// 异常情况,默认设置为初诊
|
// 异常情况,默认设置为初诊
|
||||||
visitType.value = 'FIRST';
|
visitType.value = 'FIRST';
|
||||||
|
firstVisitDate.value = '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getWaitPatient() {
|
function getWaitPatient() {
|
||||||
@@ -380,19 +417,25 @@ function handleOpen() {
|
|||||||
|
|
||||||
function handleCardClick(item, index) {
|
function handleCardClick(item, index) {
|
||||||
currentEncounterId.value = '';
|
currentEncounterId.value = '';
|
||||||
// if (item.active) {
|
|
||||||
// patientList.value[index].active = false;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
patientList.value.forEach((patient) => {
|
patientList.value.forEach((patient) => {
|
||||||
patient.active = patient.encounterId === item.encounterId;
|
patient.active = patient.encounterId === item.encounterId;
|
||||||
});
|
});
|
||||||
patientInfo.value = item;
|
patientInfo.value = item;
|
||||||
|
|
||||||
// 检查患者历史记录以确定初诊/复诊
|
// 优先使用数据库中保存的初复诊值
|
||||||
|
if (item.visitType) {
|
||||||
|
visitType.value = item.visitType;
|
||||||
|
// 已完诊的记录禁用修改
|
||||||
|
visitTypeDisabled.value = item.statusEnum !== 2;
|
||||||
|
// 如果有初诊日期也从数据库获取
|
||||||
|
if (item.firstVisitDate) {
|
||||||
|
firstVisitDate.value = item.firstVisitDate;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 对于没有初复诊记录的患者,才使用原有的判断逻辑
|
||||||
checkPatientHistory(item);
|
checkPatientHistory(item);
|
||||||
|
}
|
||||||
activeTab.value = 'emr';
|
activeTab.value = 'emr';
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
prescriptionRef.value.getListInfo();
|
prescriptionRef.value.getListInfo();
|
||||||
@@ -421,6 +464,8 @@ function handleFinish(encounterId) {
|
|||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess('操作成功');
|
proxy.$modal.msgSuccess('操作成功');
|
||||||
patientInfo.value = {};
|
patientInfo.value = {};
|
||||||
|
visitType.value = ''; // 重置初复诊标识
|
||||||
|
visitTypeDisabled.value = false; // 重置禁用状态
|
||||||
getPatientList();
|
getPatientList();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -434,7 +479,6 @@ function handleTimeChange(value) {
|
|||||||
|
|
||||||
// 接诊回调
|
// 接诊回调
|
||||||
function handleReceive(row) {
|
function handleReceive(row) {
|
||||||
// patientInfo.value = row;
|
|
||||||
handleCardClick(row);
|
handleCardClick(row);
|
||||||
currentEncounterId.value = row.encounterId;
|
currentEncounterId.value = row.encounterId;
|
||||||
drawer.value = false;
|
drawer.value = false;
|
||||||
@@ -445,6 +489,30 @@ function handleReceive(row) {
|
|||||||
function openDrawer() {
|
function openDrawer() {
|
||||||
drawer.value = true;
|
drawer.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCancelEncounter(){
|
||||||
|
proxy.$modal.confirm('您确定要取消病人本次的就诊记录吗?','提示信息',{
|
||||||
|
confirmButtonText: '是(Y)',
|
||||||
|
cancelButtonText: '否(N)',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
//调用取消接诊API,添加skipGlobalError配置跳过全局错误提示
|
||||||
|
cancelEncounter(patientInfo.value.encounterId, { skipErrorMsg: true }).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
proxy.$modal.msgSuccess('取消接诊成功');
|
||||||
|
patientInfo.value = {};
|
||||||
|
getPatientList();
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
proxy.$modal.confirm('该病人本次就诊已经有业务产生,不能取消接诊!','提示信息',{
|
||||||
|
confirmButtonText: '是(Y)',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消操作
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<div class="patient-record-query">
|
||||||
|
<h1>患者记录查询</h1>
|
||||||
|
<!-- 患者记录查询组件内容 -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'PatientRecordQuery',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 组件数据
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 组件方法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.patient-record-query {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- <el-col :span="6">
|
<!-- <el-col :span="6">
|
||||||
<el-form-item label="活动标识" prop="tempFlag">
|
<el-form-item label="" prop="tempFlag">
|
||||||
<el-radio-group v-model="form.tempFlag" :disabled="isViewMode">
|
<el-radio-group v-model="form.tempFlag" :disabled="isViewMode">
|
||||||
<el-radio v-for="dict in patient_temp_flag" :key="dict.value" :label="dict.value">
|
<el-radio v-for="dict in patient_temp_flag" :key="dict.value" :label="dict.value">
|
||||||
{{ dict.label }}
|
{{ dict.label }}
|
||||||
|
|||||||
@@ -1,106 +1,457 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="dashboard-container">
|
||||||
<div class="awaitingBtn">
|
<!-- 顶部导航栏 -->
|
||||||
<el-button @click="awaitingMedicineBtn">效期预警 <span>{{total}}</span></el-button>
|
<header class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<span class="logo-text">医院信息管理系统</span>
|
||||||
|
</div>
|
||||||
|
<div class="header-right">
|
||||||
|
<div class="notification-badge">
|
||||||
|
<i class="header-icon">🔔</i>
|
||||||
|
<span class="badge">2</span>
|
||||||
|
</div>
|
||||||
|
<i class="header-icon">⚙️</i>
|
||||||
|
<div class="user-info">
|
||||||
|
<span class="user-avatar">👤</span>
|
||||||
|
<span>用户</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- 主体内容 -->
|
||||||
|
<div class="main-content">
|
||||||
|
<!-- 左侧导航栏 -->
|
||||||
|
<nav class="sidebar">
|
||||||
|
<div class="menu-item active">
|
||||||
|
<span class="menu-icon">📊</span>
|
||||||
|
<span>仪表盘</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">👥</span>
|
||||||
|
<span>患者管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">💉</span>
|
||||||
|
<span>预约管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">🏥</span>
|
||||||
|
<span>门诊管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">⚕️</span>
|
||||||
|
<span>住院管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">💊</span>
|
||||||
|
<span>药房管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">📋</span>
|
||||||
|
<span>报表统计</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">⚙️</span>
|
||||||
|
<span>系统设置</span>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- 主内容区 -->
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="awaitingBtn">
|
||||||
|
<el-button @click="awaitingMedicineBtn">效期预警 <span>{{ total }}</span></el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 class="section-title">仪表盘</h1>
|
||||||
|
|
||||||
|
<!-- 关键指标卡片 -->
|
||||||
|
<div class="dashboard-grid">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">今日预约量</div>
|
||||||
|
<div class="card-value">126</div>
|
||||||
|
<div class="card-stats">
|
||||||
|
<span class="stats-icon">↑</span>
|
||||||
|
<span>12% 较昨日</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">门诊量统计</div>
|
||||||
|
<div class="card-value">342</div>
|
||||||
|
<div class="card-stats">
|
||||||
|
<span class="stats-icon">↑</span>
|
||||||
|
<span>8% 较上周</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">住院患者数</div>
|
||||||
|
<div class="card-value">78</div>
|
||||||
|
<div class="card-stats down">
|
||||||
|
<span class="stats-icon">↓</span>
|
||||||
|
<span>5% 较上周</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">药品库存预警</div>
|
||||||
|
<div class="card-value">8</div>
|
||||||
|
<div class="card-stats">
|
||||||
|
<span class="stats-icon">!</span>
|
||||||
|
<span>需要立即处理</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 图表展示区 -->
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="statsChart"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 重要通知和待办事项 -->
|
||||||
|
<div class="bottom-content">
|
||||||
|
<div class="notification-container">
|
||||||
|
<div class="notification-title">重要通知</div>
|
||||||
|
<ul class="notification-list">
|
||||||
|
<li class="notification-item">系统将于周六凌晨2:00进行维护升级</li>
|
||||||
|
<li class="notification-item">新的门诊排班系统已上线,请尽快熟悉</li>
|
||||||
|
<li class="notification-item">三季度医疗质量分析报告已发布</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="todo-container">
|
||||||
|
<div class="todo-title">待办事项</div>
|
||||||
|
<ul class="todo-list">
|
||||||
|
<li class="todo-item">
|
||||||
|
<span>未完成预约</span>
|
||||||
|
<span class="todo-count">12个</span>
|
||||||
|
</li>
|
||||||
|
<li class="todo-item">
|
||||||
|
<span>待处理检查结果</span>
|
||||||
|
<span class="todo-count">7份</span>
|
||||||
|
</li>
|
||||||
|
<li class="todo-item">
|
||||||
|
<span>待开处方</span>
|
||||||
|
<span class="todo-count">3张</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<button class="btn btn-primary">查看详情</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 患者列表 -->
|
||||||
|
<h2 class="section-title">最近患者</h2>
|
||||||
|
<div class="table-container">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>患者姓名</th>
|
||||||
|
<th>病历号</th>
|
||||||
|
<th>年龄</th>
|
||||||
|
<th>最后就诊时间</th>
|
||||||
|
<th>状态</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>张明</td>
|
||||||
|
<td>HN2023001</td>
|
||||||
|
<td>45</td>
|
||||||
|
<td>2023-10-20 09:30</td>
|
||||||
|
<td><span style="color: #67c23a;">已完成</span></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-outline">详情</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>李红</td>
|
||||||
|
<td>HN2023002</td>
|
||||||
|
<td>32</td>
|
||||||
|
<td>2023-10-20 10:15</td>
|
||||||
|
<td><span style="color: #ff9800;">待检查</span></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-outline">详情</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>王建军</td>
|
||||||
|
<td>HN2023003</td>
|
||||||
|
<td>68</td>
|
||||||
|
<td>2023-10-19 14:20</td>
|
||||||
|
<td><span style="color: #d45d79;">住院中</span></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-outline">详情</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="logo"> -->
|
|
||||||
<!-- <img src="/src/assets/images/jlau.jpg" /> -->
|
|
||||||
<!-- </div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="Index">
|
<script setup name="Index">
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import Chart from 'chart.js/auto';
|
||||||
import {
|
import {
|
||||||
getExpirationWarning,
|
getExpirationWarning,
|
||||||
} from "./medicationmanagement/statisticalManagement/statisticalManagent";
|
} from "./medicationmanagement/statisticalManagement/statisticalManagent";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const version = ref('3.8.7');
|
const total = ref(0);
|
||||||
const total = ref(0)
|
|
||||||
function awaitingMedicineBtn(){
|
function awaitingMedicineBtn() {
|
||||||
router.push({ path: '/medicationmanagement/statisticalManagement/earlyWarning' })
|
router.push({ path: '/medicationmanagement/statisticalManagement/earlyWarning' });
|
||||||
}
|
}
|
||||||
function goTarget(url) {
|
|
||||||
window.open(url, '__blank');
|
function getExpirationWarningCount() {
|
||||||
}
|
getExpirationWarning({ pageNo: 1, pageSize: 10 }).then((res) => {
|
||||||
function getExpirationWarningCount(){
|
total.value = res.data.total || 0;
|
||||||
getExpirationWarning({pageNo: 1,pageSize: 10}).then((res) => {
|
}).catch((err) => {
|
||||||
total.value = res.data.total||0
|
console.error('获取效期预警数量失败:', err);
|
||||||
|
total.value = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getExpirationWarningCount()
|
|
||||||
|
let chartInstance = null;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getExpirationWarningCount();
|
||||||
|
|
||||||
|
const ctx = document.getElementById('statsChart');
|
||||||
|
if (!ctx) return;
|
||||||
|
|
||||||
|
// 销毁已有实例
|
||||||
|
if (chartInstance) {
|
||||||
|
chartInstance.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟数据:近7天门诊量与预约量
|
||||||
|
const labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
||||||
|
const outpatientData = [310, 335, 305, 345, 370, 270, 210]; // 门诊量(柱状图)
|
||||||
|
const appointmentData = [100, 120, 110, 130, 140, 90, 70]; // 预约量(折线图)
|
||||||
|
|
||||||
|
chartInstance = new Chart(ctx.getContext('2d'), {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: '门诊量',
|
||||||
|
data: outpatientData,
|
||||||
|
backgroundColor: '#91c8e5',
|
||||||
|
borderColor: '#66a8cc',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderSkipped: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '预约量',
|
||||||
|
data: appointmentData,
|
||||||
|
type: 'line',
|
||||||
|
borderColor: '#f56c6c',
|
||||||
|
backgroundColor: 'rgba(245, 108, 108, 0.1)',
|
||||||
|
borderWidth: 2,
|
||||||
|
pointBackgroundColor: '#f56c6c',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointBorderWidth: 2,
|
||||||
|
pointRadius: 4,
|
||||||
|
fill: true,
|
||||||
|
tension: 0.3,
|
||||||
|
lineTension: 0.3,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: 'top',
|
||||||
|
labels: {
|
||||||
|
font: {
|
||||||
|
size: 12,
|
||||||
|
weight: 'bold'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
||||||
|
titleFont: {
|
||||||
|
size: 13
|
||||||
|
},
|
||||||
|
bodyFont: {
|
||||||
|
size: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
font: {
|
||||||
|
size: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
max: 400,
|
||||||
|
stepSize: 50,
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(0, 0, 0, 0.05)'
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
font: {
|
||||||
|
size: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.home {
|
.dashboard-container {
|
||||||
blockquote {
|
|
||||||
padding: 10px 20px;
|
|
||||||
margin: 0 0 20px;
|
|
||||||
font-size: 17.5px;
|
|
||||||
border-left: 5px solid #eee;
|
|
||||||
}
|
|
||||||
hr {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border: 0;
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
}
|
|
||||||
.col-item {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
font-family: 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #676a6c;
|
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 10px;
|
|
||||||
|
|
||||||
b {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.update-log {
|
|
||||||
ol {
|
|
||||||
display: block;
|
|
||||||
list-style-type: decimal;
|
|
||||||
margin-block-start: 1em;
|
|
||||||
margin-block-end: 1em;
|
|
||||||
margin-inline-start: 0;
|
|
||||||
margin-inline-end: 0;
|
|
||||||
padding-inline-start: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center; /* 水平居中 */
|
flex-direction: column;
|
||||||
align-items: center; /* 垂直居中 */
|
height: 100vh;
|
||||||
height: 70vh; /* 确保容器高度至少为视口高度 */
|
background-color: #f5f7fa;
|
||||||
width: 100%;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
.awaitingBtn{
|
|
||||||
|
.header {
|
||||||
|
height: 60px;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 24px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #166773;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-badge {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #ff4d4f;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 10px;
|
||||||
|
min-width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 200px;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:hover {
|
||||||
|
background-color: #f0f9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item.active {
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
border-left-color: #1890ff;
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
margin-right: 12px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.awaitingBtn {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
.el-button{
|
.el-button{
|
||||||
border: 1px #166773 solid;
|
border: 1px #166773 solid;
|
||||||
span{
|
span{
|
||||||
@@ -108,6 +459,7 @@ getExpirationWarningCount()
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:hover{
|
.el-button:hover{
|
||||||
border: 1px #166773 solid;
|
border: 1px #166773 solid;
|
||||||
color: #166773;
|
color: #166773;
|
||||||
@@ -116,15 +468,204 @@ getExpirationWarningCount()
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
position: absolute;
|
|
||||||
top:20px;
|
|
||||||
left: 20px;
|
|
||||||
}
|
}
|
||||||
.logo {
|
|
||||||
width: 1000px;
|
.section-title {
|
||||||
margin: 0 auto;
|
font-size: 24px;
|
||||||
background: url(../assets/images/logo_bg.jpg) no-repeat right bottom;
|
margin-bottom: 20px;
|
||||||
overflow: hidden;
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-value {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-stats {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-stats.down {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
height: 300px;
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-container,
|
||||||
|
.todo-container {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-title,
|
||||||
|
.todo-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-item {
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo-count {
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 12px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #40a9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline:hover {
|
||||||
|
border-color: #c6e2ff;
|
||||||
|
color: #40a9ff;
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.bottom-content {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,18 @@ export function delEncounterDiagnosis(conditionId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是食源性诊断
|
||||||
|
*/
|
||||||
|
export function isFoodDiseasesNew(params) {
|
||||||
|
return request({
|
||||||
|
url: '/external-integration/foodborne-acquisition/is-food-diseases-new',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取中医诊断
|
* 获取中医诊断
|
||||||
*/
|
*/
|
||||||
@@ -230,6 +242,15 @@ export function getOrgTree() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getEmrDetail(encounterId) {
|
||||||
|
return request({
|
||||||
|
url: '/doctor-station/emr/emr-detail?encounterId=' + encounterId,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组合/拆组
|
* 组合/拆组
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,19 +2,17 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="4" :xs="24">
|
<el-col :span="4" :xs="24">
|
||||||
<div style="height: 44px; display: flex; align-items: center; flex: none">
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="diagnosis"
|
v-model="diagnosis"
|
||||||
placeholder="诊断名称"
|
placeholder="诊断名称"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%; margin-bottom: 10px"
|
||||||
@keyup.enter="queryDiagnosisUse"
|
@keyup.enter="queryDiagnosisUse"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-button icon="Search" @click="queryDiagnosisUse" />
|
<el-button icon="Search" @click="queryDiagnosisUse" />
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
|
||||||
<el-tree
|
<el-tree
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
:data="tree"
|
:data="tree"
|
||||||
@@ -68,16 +66,21 @@
|
|||||||
</el-tree>
|
</el-tree>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="20" :xs="24">
|
<el-col :span="20" :xs="24">
|
||||||
<div style="height: 44px; display: flex; align-items: center; flex: none">
|
<div style="margin-bottom: 10px">
|
||||||
<el-button type="primary" plain @click="handleAddDiagnosis()"> 新增诊断 </el-button>
|
<el-button type="primary" plain @click="handleAddDiagnosis()"> 新增诊断 </el-button>
|
||||||
<el-button type="primary" plain @click="handleSaveDiagnosis()"> 保存诊断 </el-button>
|
<el-button type="primary" plain @click="handleSaveDiagnosis()"> 保存诊断 </el-button>
|
||||||
<el-button type="primary" plain @click="handleAddTcmDiagonsis()"> 中医诊断 </el-button>
|
<el-button type="primary" plain @click="handleAddTcmDiagonsis()"> 中医诊断 </el-button>
|
||||||
<el-button type="primary" plain @click="handleImport()"> 导入慢性病诊断 </el-button>
|
<el-button type="primary" plain @click="handleImport()"> 导入慢性病诊断 </el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form :model="form" :rules="rules" ref="formRef">
|
<el-form :model="form" :rules="rules" ref="formRef">
|
||||||
<el-table ref="diagnosisTableRef" :data="form.diagnosisList" height="650">
|
<el-table ref="diagnosisTableRef" :data="form.diagnosisList" height="650">
|
||||||
<el-table-column label="序号" type="index" width="50" />
|
<el-table-column label="序号" width="50" >
|
||||||
<el-table-column label="诊断排序" align="center" prop="diagSrtNo" width="180">
|
<template #default="scope">
|
||||||
|
{{ scope.$index + 1 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="诊断排序" align="center" prop="diagSrtNo" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:prop="`diagnosisList.${scope.$index}.diagSrtNo`"
|
:prop="`diagnosisList.${scope.$index}.diagSrtNo`"
|
||||||
@@ -136,9 +139,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="医保码" align="center" prop="ybNo" width="180" />
|
|
||||||
<el-table-column label="诊断类型" align="center" prop="maindiseFlag">
|
<el-table-column label="诊断医生" align="center" prop="diagnosisDoctor" width="120" />
|
||||||
|
<el-table-column label="诊断时间" align="center" prop="diagnosisTime" width="150" />
|
||||||
|
<el-table-column label="诊断代码" align="center" prop="ybNo" width="180" />
|
||||||
|
<el-table-column label="诊断类型" align="center" prop="maindiseFlag" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
<div style="display:flex;flex-direction:column;align-items:center;gap:5px;">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
label="主诊断"
|
label="主诊断"
|
||||||
:trueLabel="1"
|
:trueLabel="1"
|
||||||
@@ -151,7 +158,7 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="scope.row.verificationStatusEnum"
|
v-model="scope.row.verificationStatusEnum"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
style="width: 40%; padding-bottom: 5px; padding-left: 10px"
|
style="width: 100%; padding-bottom: 5px; padding-left: 10px"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
@@ -161,6 +168,7 @@
|
|||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" width="130">
|
<el-table-column label="操作" align="center" width="130">
|
||||||
@@ -185,28 +193,30 @@
|
|||||||
/>
|
/>
|
||||||
<AddDiagnosisDialog
|
<AddDiagnosisDialog
|
||||||
:openAddDiagnosisDialog="openAddDiagnosisDialog"
|
:openAddDiagnosisDialog="openAddDiagnosisDialog"
|
||||||
:patientInfo="patientInfo"
|
:patientInfo="props.patientInfo"
|
||||||
@close="closeDiagnosisDialog"
|
@close="closeDiagnosisDialog"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance } from 'vue';
|
import { getCurrentInstance, nextTick } from 'vue'; // 添加 nextTick 导入
|
||||||
|
import useUserStore from '@/store/modules/user';
|
||||||
import {
|
import {
|
||||||
getConditionDefinitionInfo,
|
getConditionDefinitionInfo,
|
||||||
saveDiagnosis,
|
saveDiagnosis,
|
||||||
diagnosisInit,
|
diagnosisInit,
|
||||||
deleteDiagnosisBind,
|
deleteDiagnosisBind,
|
||||||
getEncounterDiagnosis,
|
getEncounterDiagnosis,
|
||||||
|
getEmrDetail,
|
||||||
getChronicDisease,
|
getChronicDisease,
|
||||||
getTcmDiagnosis,
|
getTcmDiagnosis,
|
||||||
delEncounterDiagnosis,
|
delEncounterDiagnosis,
|
||||||
|
isFoodDiseasesNew,
|
||||||
} from '../api';
|
} from '../api';
|
||||||
import diagnosisdialog from '../diagnosis/diagnosisdialog.vue';
|
import diagnosisdialog from '../diagnosis/diagnosisdialog.vue';
|
||||||
import AddDiagnosisDialog from './addDiagnosisDialog.vue';
|
import AddDiagnosisDialog from './addDiagnosisDialog.vue';
|
||||||
import diagnosislist from '../diagnosis/diagnosislist.vue';
|
import diagnosislist from '../diagnosis/diagnosislist.vue';
|
||||||
import { patientInfo } from '../../store/patient.js';
|
|
||||||
// const diagnosisList = ref([]);
|
// const diagnosisList = ref([]);
|
||||||
const allowAdd = ref(false);
|
const allowAdd = ref(false);
|
||||||
const tree = ref([]);
|
const tree = ref([]);
|
||||||
@@ -228,50 +238,93 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const emits = defineEmits(['diagnosisSave']);
|
const emits = defineEmits(['diagnosisSave']);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
const userStore = useUserStore();
|
||||||
const { med_type } = proxy.useDict('med_type');
|
const { med_type } = proxy.useDict('med_type');
|
||||||
const rules = ref({
|
const rules = ref({
|
||||||
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
||||||
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
||||||
diagSrtNo: [{ required: true, message: '请输入诊断序号', trigger: 'change' }],
|
diagSrtNo: [{ required: true, message: '请输入诊断序号', trigger: 'change' }],
|
||||||
});
|
});
|
||||||
|
const isSaving = ref(false);
|
||||||
watch(
|
watch(
|
||||||
() => form.value.diagnosisList,
|
() => form.value.diagnosisList,
|
||||||
() => {
|
() => {
|
||||||
|
// 如果正在保存,则不触发更新事件
|
||||||
|
if (!isSaving.value) {
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
// function getDetail(encounterId) {
|
function getDetail(encounterId) {
|
||||||
// getEmrDetail(encounterId).then((res) => {
|
if (!encounterId) {
|
||||||
// allowAdd.value = res.data ? true : false;
|
console.warn('未提供有效的就诊ID,无法获取病历详情');
|
||||||
// });
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
getEmrDetail(encounterId).then((res) => {
|
||||||
|
allowAdd.value = res.data ? true : false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getList() {
|
function getList() {
|
||||||
getEncounterDiagnosis(patientInfo.value.encounterId).then((res) => {
|
if (!props.patientInfo || !props.patientInfo.encounterId) {
|
||||||
|
console.warn('患者就诊信息不完整,无法获取诊断数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
form.value.diagnosisList = res.data;
|
// 为每个诊断项添加默认的诊断医生和时间(如果不存在)
|
||||||
|
const diagnosisList = res.data.map(item => ({
|
||||||
|
...item,
|
||||||
|
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN')
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 对获取的数据进行排序
|
||||||
|
diagnosisList.sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
|
|
||||||
|
form.value.diagnosisList = diagnosisList;
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
console.log(form.value.diagnosisList);
|
console.log(form.value.diagnosisList);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
getTcmDiagnosis({ encounterId: patientInfo.value.encounterId }).then((res) => {
|
|
||||||
|
getTcmDiagnosis({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
if (res.data.illness.length > 0) {
|
if (res.data.illness && res.data.illness.length > 0 && res.data.symptom) {
|
||||||
|
const newList = [];
|
||||||
res.data.illness.forEach((item, index) => {
|
res.data.illness.forEach((item, index) => {
|
||||||
form.value.diagnosisList.push({
|
newList.push({
|
||||||
name: item.name + '-' + res.data.symptom[index].name,
|
name: item.name + '-' + (res.data.symptom[index]?.name || ''),
|
||||||
ybNo: item.ybNo,
|
ybNo: item.ybNo,
|
||||||
medTypeCode: item.medTypeCode,
|
medTypeCode: item.medTypeCode,
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 将新数据添加到现有列表中
|
||||||
|
form.value.diagnosisList.push(...newList);
|
||||||
|
|
||||||
|
// 重新排序整个列表
|
||||||
|
form.value.diagnosisList.sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
console.log(form.value.diagnosisList);
|
console.log(form.value.diagnosisList);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
getTree();
|
getTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,10 +338,15 @@ function init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleImport() {
|
function handleImport() {
|
||||||
if (patientInfo.value.contractName != '自费') {
|
if (!props.patientInfo || !props.patientInfo.encounterId) {
|
||||||
|
console.warn('患者就诊信息不完整,无法导入慢性病信息');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.patientInfo.contractName != '自费') {
|
||||||
// 获取患者慢性病信息
|
// 获取患者慢性病信息
|
||||||
getChronicDisease({ encounterId: patientInfo.value.encounterId }).then((res) => {
|
getChronicDisease({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||||
if (res.data.length > 0) {
|
if (res.data && res.data.length > 0) {
|
||||||
res.data.forEach((item, index) => {
|
res.data.forEach((item, index) => {
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
...item,
|
...item,
|
||||||
@@ -297,6 +355,10 @@ function handleImport() {
|
|||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
definitionId: item.id,
|
definitionId: item.id,
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: form.value.diagnosisList.length + 1,
|
||||||
|
iptDiseTypeCode: 2,
|
||||||
|
diagnosisDesc: '',
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -340,7 +402,8 @@ const filterNode = (value, data) => {
|
|||||||
* 获取诊断树列表
|
* 获取诊断树列表
|
||||||
*/
|
*/
|
||||||
function getTree() {
|
function getTree() {
|
||||||
getConditionDefinitionInfo(patientInfo.value ? patientInfo.value.patientId : '').then((res) => {
|
const patientId = props.patientInfo?.patientId || '';
|
||||||
|
getConditionDefinitionInfo(patientId).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
let list = [];
|
let list = [];
|
||||||
list = res.data.patientHistoryList;
|
list = res.data.patientHistoryList;
|
||||||
@@ -377,14 +440,20 @@ function getTree() {
|
|||||||
function handleAddDiagnosis() {
|
function handleAddDiagnosis() {
|
||||||
proxy.$refs.formRef.validate((valid) => {
|
proxy.$refs.formRef.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
if (!allowAdd.value) {
|
||||||
|
proxy.$modal.msgWarning('请先填写病历');
|
||||||
|
return;
|
||||||
|
}
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
showPopover: false,
|
showPopover: false,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
medTypeCode: '21',
|
medTypeCode: '11',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: form.value.diagnosisList.length + 1,
|
||||||
iptDiseTypeCode: 31,
|
iptDiseTypeCode: 2,
|
||||||
diagnosisDesc: '',
|
diagnosisDesc: '',
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
@@ -398,13 +467,31 @@ function handleAddTcmDiagonsis() {
|
|||||||
openAddDiagnosisDialog.value = true;
|
openAddDiagnosisDialog.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除诊断
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* 删除诊断
|
* 删除诊断
|
||||||
*/
|
*/
|
||||||
function handleDeleteDiagnosis(row, index) {
|
function handleDeleteDiagnosis(row, index) {
|
||||||
if (row.conditionId) {
|
if (row.conditionId) {
|
||||||
delEncounterDiagnosis(row.conditionId).then(() => {
|
delEncounterDiagnosis(row.conditionId).then(() => {
|
||||||
getList();
|
// 不要立即调用getList(),而是从当前列表中移除
|
||||||
|
form.value.diagnosisList.splice(index, 1);
|
||||||
|
// 重新排序剩余的项目
|
||||||
|
const sortedList = [...form.value.diagnosisList].sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重新分配连续的序号
|
||||||
|
sortedList.forEach((item, idx) => {
|
||||||
|
item.diagSrtNo = idx + 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新列表
|
||||||
|
form.value.diagnosisList = sortedList.map(item => ({ ...item }));
|
||||||
getTree();
|
getTree();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -428,35 +515,72 @@ function handleMaindise(value, index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存诊断
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 保存诊断
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 保存诊断
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* 保存诊断
|
* 保存诊断
|
||||||
*/
|
*/
|
||||||
function handleSaveDiagnosis() {
|
function handleSaveDiagnosis() {
|
||||||
proxy.$refs.formRef.validate((valid) => {
|
proxy.$refs.formRef.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (form.value.diagnosisList.length == 0) {
|
if (form.value.diagnosisList.length === 0) {
|
||||||
proxy.$modal.msgWarning('诊断不能为空');
|
proxy.$modal.msgWarning('诊断不能为空');
|
||||||
return false;
|
return;
|
||||||
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
||||||
proxy.$modal.msgWarning('至少添加一条主诊断');
|
proxy.$modal.msgWarning('至少添加一条主诊断');
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置保存标志,避免触发watch监听器
|
||||||
|
isSaving.value = true;
|
||||||
|
|
||||||
|
// 步骤1:深拷贝并按 diagSrtNo 排序
|
||||||
|
const sortedList = [...form.value.diagnosisList].sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 步骤2:重新分配连续的序号(从1开始)
|
||||||
|
sortedList.forEach((item, index) => {
|
||||||
|
item.diagSrtNo = index + 1; // 这里是关键!把“诊断排序”改成新顺序
|
||||||
|
});
|
||||||
|
|
||||||
|
// 步骤3:提交排序后的数据
|
||||||
saveDiagnosis({
|
saveDiagnosis({
|
||||||
patientId: patientInfo.value.patientId,
|
patientId: props.patientInfo.patientId,
|
||||||
encounterId: patientInfo.value.encounterId,
|
encounterId: props.patientInfo.encounterId,
|
||||||
diagnosisChildList: form.value.diagnosisList,
|
diagnosisChildList: sortedList,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code === 200) {
|
||||||
getTree();
|
// 步骤4:更新本地数据,使用全新对象防止响应式问题
|
||||||
getList();
|
form.value.diagnosisList = sortedList.map(item => ({ ...item }));
|
||||||
|
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
proxy.$modal.msgSuccess('诊断已保存');
|
proxy.$modal.msgSuccess('诊断已保存');
|
||||||
|
|
||||||
|
// 食源性疾病逻辑
|
||||||
|
isFoodDiseasesNew({ encounterId: props.patientInfo.encounterId }).then((res2) => {
|
||||||
|
if (res2.code === 20 && res2.data) {
|
||||||
|
window.open(res2.data, '_blank');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
isSaving.value = false;
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭诊断弹窗
|
* 关闭诊断弹窗
|
||||||
*/
|
*/
|
||||||
@@ -519,12 +643,15 @@ function handleNodeClick(data) {
|
|||||||
medTypeCode: '11',
|
medTypeCode: '11',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: form.value.diagnosisList.length + 1,
|
||||||
definitionId: data.definitionId,
|
definitionId: data.definitionId,
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defineExpose({ getList, handleSaveDiagnosis });
|
|
||||||
|
defineExpose({ getList, getDetail, handleSaveDiagnosis });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -543,3 +670,4 @@ defineExpose({ getList, handleSaveDiagnosis });
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user