Compare commits
23 Commits
f7f2f98bbe
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 46c9787216 | |||
| e0a768de2e | |||
| fc7f931728 | |||
|
|
3ccb970a09 | ||
|
|
8a9a622aeb | ||
|
|
29e7f0937b | ||
| 029d534b3c | |||
|
|
213723b220 | ||
|
|
c636e77fd0 | ||
|
|
7407562ec5 | ||
|
|
b3c27ec789 | ||
|
|
601ae40666 | ||
| 3dda5ce72d | |||
|
|
99d4c28b95 | ||
|
|
0e70de6de7 | ||
| 72eb1088df | |||
| a853c16854 | |||
| 73a349f98a | |||
| 5fb7a3f488 | |||
| a8eb7d5697 | |||
| eb3b142ce4 | |||
| 9f6a39ba30 | |||
|
|
6fbdddf0ee |
39
TestDeleteInspectionType.java
Normal file
39
TestDeleteInspectionType.java
Normal file
@@ -0,0 +1,39 @@
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class TestDeleteInspectionType {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// 测试删除ID为1的检验类型
|
||||
long inspectionTypeId = 1;
|
||||
URL url = new URL("http://localhost:8080/system/inspection-type/" + inspectionTypeId);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("DELETE");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("Accept", "application/json");
|
||||
|
||||
// 发送请求
|
||||
int responseCode = connection.getResponseCode();
|
||||
System.out.println("响应代码: " + responseCode);
|
||||
|
||||
// 读取响应
|
||||
Scanner scanner;
|
||||
if (responseCode >= 200 && responseCode < 300) {
|
||||
scanner = new Scanner(connection.getInputStream());
|
||||
} else {
|
||||
scanner = new Scanner(connection.getErrorStream());
|
||||
}
|
||||
|
||||
String response = scanner.useDelimiter("\\A").next();
|
||||
System.out.println("响应内容: " + response);
|
||||
|
||||
scanner.close();
|
||||
connection.disconnect();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
27
add_organization_fields.sql
Normal file
27
add_organization_fields.sql
Normal file
@@ -0,0 +1,27 @@
|
||||
-- 向adm_organization表添加缺失字段的SQL脚本
|
||||
|
||||
-- 添加register_flag字段(对应registerFlag属性)
|
||||
ALTER TABLE "adm_organization"
|
||||
ADD COLUMN "register_flag" int4;
|
||||
|
||||
-- 添加location字段
|
||||
ALTER TABLE "adm_organization"
|
||||
ADD COLUMN "location" varchar(255);
|
||||
|
||||
-- 添加intro字段
|
||||
ALTER TABLE "adm_organization"
|
||||
ADD COLUMN "intro" varchar(1000);
|
||||
|
||||
-- 添加remark字段
|
||||
ALTER TABLE "adm_organization"
|
||||
ADD COLUMN "remark" varchar(1000);
|
||||
|
||||
-- 添加字段注释
|
||||
COMMENT ON COLUMN "adm_organization"."register_flag" IS '挂号标志';
|
||||
COMMENT ON COLUMN "adm_organization"."location" IS '科室位置';
|
||||
COMMENT ON COLUMN "adm_organization"."intro" IS '科室简介';
|
||||
COMMENT ON COLUMN "adm_organization"."remark" IS '备注';
|
||||
|
||||
-- 设置register_flag默认值为0(不允许挂号)
|
||||
ALTER TABLE "adm_organization"
|
||||
ALTER COLUMN "register_flag" SET DEFAULT 0;
|
||||
@@ -100,7 +100,18 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
@Override
|
||||
public R<?> getOrgInfo(Long orgId) {
|
||||
Organization organization = organizationService.getById(orgId);
|
||||
return R.ok(organization, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"机构信息查询"}));
|
||||
if (organization == null) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, new Object[] {"机构信息"}));
|
||||
}
|
||||
|
||||
// 转换为DTO对象,确保数据格式一致
|
||||
OrganizationDto organizationDto = new OrganizationDto();
|
||||
BeanUtils.copyProperties(organization, organizationDto);
|
||||
organizationDto.setTypeEnum_dictText(EnumUtils.getInfoByValue(OrganizationType.class, organizationDto.getTypeEnum()));
|
||||
organizationDto.setClassEnum_dictText(EnumUtils.getInfoByValue(OrganizationClass.class, organizationDto.getClassEnum()));
|
||||
organizationDto.setActiveFlag_dictText(EnumUtils.getInfoByValue(AccountStatus.class, organizationDto.getActiveFlag()));
|
||||
|
||||
return R.ok(organizationDto, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"机构信息查询"}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,4 +60,16 @@ public class OrganizationDto {
|
||||
|
||||
/** 子集合 */
|
||||
private List<OrganizationDto> children = new ArrayList<>();
|
||||
|
||||
/** 挂号科室标记 */
|
||||
private Integer registerFlag;
|
||||
|
||||
/** 科室位置 */
|
||||
private String location;
|
||||
|
||||
/** 科室简介 */
|
||||
private String intro;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@ package com.openhis.web.check.appservice;
|
||||
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.check.dto.CheckMethodDto;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
import io.swagger.models.auth.In;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 检查方法Service接口
|
||||
@@ -14,11 +17,13 @@ public interface ICheckMethodAppService{
|
||||
|
||||
R<?> getCheckMethodList();
|
||||
|
||||
R<?> addCheckMethod(CheckMethodDto checkMethodDto);
|
||||
R<?> addCheckMethod(CheckMethod checkMethod);
|
||||
|
||||
R<?> updateCheckMethod(CheckMethodDto checkPartDto);
|
||||
R<?> updateCheckMethod(CheckMethod checkPart);
|
||||
|
||||
R<?> removeCheckMethod(Long code);
|
||||
R<?> removeCheckMethod(Integer checkMethodId);
|
||||
|
||||
R<?> searchCheckMethodList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
||||
|
||||
R<?> exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
package com.openhis.web.check.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.check.dto.CheckPartDto;
|
||||
import com.openhis.check.domain.CheckPart;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public interface ICheckPartAppService {
|
||||
R<?> getCheckPartList();
|
||||
|
||||
R<?> addCheckPart(CheckPartDto checkPartDto);
|
||||
R<?> addCheckPart(CheckPart checkPart);
|
||||
|
||||
R<?> removeCheckPart(Long code);
|
||||
R<?> removeCheckPart(Integer checkPartId);
|
||||
|
||||
R<?> updateCheckPart(CheckPartDto checkMethodDto);
|
||||
R<?> updateCheckPart(CheckPart checkPart);
|
||||
|
||||
R<?> searchCheckPartList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
||||
|
||||
R<?> exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.openhis.web.check.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.check.domain.LisGroupInfo;
|
||||
|
||||
public interface ILisGroupInfoAppService {
|
||||
R<?> getLisGroupInfoList();
|
||||
|
||||
R<?> add(LisGroupInfo lisGroupInfo);
|
||||
|
||||
R<?> update(LisGroupInfo lisGroupInfo);
|
||||
|
||||
R<?> delete(Integer lisGroupInfoId);
|
||||
}
|
||||
@@ -2,17 +2,20 @@ package com.openhis.web.check.appservice.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
import com.openhis.check.service.ICheckMethodService;
|
||||
import com.openhis.web.check.appservice.ICheckMethodAppService;
|
||||
import com.openhis.web.check.dto.CheckMethodDto;
|
||||
import com.openhis.web.reportmanage.utils.ExcelFillerUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -28,65 +31,99 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> addCheckMethod(CheckMethodDto checkMethodDto) {
|
||||
//1.参数校验
|
||||
if(ObjectUtil.isEmpty(checkMethodDto.getName())){
|
||||
return R.fail("检查方法名称不能为空");
|
||||
public R<?> searchCheckMethodList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName) {
|
||||
LambdaQueryWrapper<CheckMethod> wrapper = new LambdaQueryWrapper<>();
|
||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||
wrapper.eq(CheckMethod::getCheckType, checkType);
|
||||
}
|
||||
if(ObjectUtil.isEmpty(checkMethodDto.getCheckType())){
|
||||
return R.fail("检查类型不能为空");
|
||||
if (name != null && ObjectUtil.isNotEmpty(name)) {
|
||||
wrapper.like(CheckMethod::getName, name);
|
||||
}
|
||||
if(ObjectUtil.isEmpty(checkMethodDto.getCode())){
|
||||
return R.fail("代码不能为空");
|
||||
if (packageName != null && ObjectUtil.isNotEmpty(packageName)) {
|
||||
wrapper.eq(CheckMethod::getPackageName, packageName);
|
||||
}
|
||||
//2.判断是否有重复
|
||||
LambdaQueryWrapper<CheckMethod> wrapper = new LambdaQueryWrapper<CheckMethod>()
|
||||
.eq(CheckMethod::getName, checkMethodDto.getName())
|
||||
.eq(CheckMethod::getCheckType, checkMethodDto.getCheckType())
|
||||
.eq(CheckMethod::getCode, checkMethodDto.getCode());
|
||||
if (checkMethodService.getOne(wrapper) != null){
|
||||
return R.fail("检查方法已存在");
|
||||
List<CheckMethod> list = checkMethodService.list(wrapper);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
//3.封装实体检查方法
|
||||
CheckMethod checkMethod = new CheckMethod();
|
||||
checkMethod.setName(checkMethodDto.getName());
|
||||
checkMethod.setCheckType(checkMethodDto.getCheckType());
|
||||
checkMethod.setCode(checkMethodDto.getCode());
|
||||
checkMethod.setPackageName(checkMethodDto.getPackageName());
|
||||
checkMethod.setExposureNum(checkMethodDto.getExposureNum());
|
||||
checkMethod.setOrderNum(checkMethodDto.getOrderNum());
|
||||
checkMethod.setRemark(checkMethodDto.getRemark());
|
||||
//4.保存添加
|
||||
@Override
|
||||
public R<?> addCheckMethod(CheckMethod checkMethod) {
|
||||
//1.数据校验
|
||||
if (ObjectUtil.isEmpty(checkMethod.getName())) {
|
||||
return R.fail("检查方法名称不能为空!");
|
||||
}
|
||||
if (ObjectUtil.isEmpty(checkMethod.getCode())) {
|
||||
return R.fail("检查方法代码不能为空!");
|
||||
}
|
||||
if (ObjectUtil.isEmpty(checkMethod.getCheckType())) {
|
||||
return R.fail("检查方法的检查类型不能为空!");
|
||||
}
|
||||
//2.保存
|
||||
boolean save = checkMethodService.save(checkMethod);
|
||||
return R.ok();
|
||||
return R.ok(save);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> updateCheckMethod(CheckMethodDto checkMethodDto) {
|
||||
//1.参数校验
|
||||
if(ObjectUtil.isEmpty(checkMethodDto.getName())){
|
||||
return R.fail("检查方法名称不能为空");
|
||||
public R<?> updateCheckMethod(CheckMethod checkMethod) {
|
||||
//1.数据校验
|
||||
if (ObjectUtil.isEmpty(checkMethod.getName())) {
|
||||
return R.fail("检查方法名称不能为空!");
|
||||
}
|
||||
if(ObjectUtil.isEmpty(checkMethodDto.getCheckType())){
|
||||
return R.fail("检查类型不能为空");
|
||||
if (ObjectUtil.isEmpty(checkMethod.getCode())) {
|
||||
return R.fail("检查方法代码不能为空!");
|
||||
}
|
||||
if(ObjectUtil.isEmpty(checkMethodDto.getCode())){
|
||||
return R.fail("代码不能为空");
|
||||
if (ObjectUtil.isEmpty(checkMethod.getCheckType())) {
|
||||
return R.fail("检查方法的检查类型不能为空!");
|
||||
}
|
||||
//2.
|
||||
return R.ok();
|
||||
//2.更新
|
||||
boolean b = checkMethodService.updateById(checkMethod);
|
||||
return R.ok(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> removeCheckMethod(Long code) {
|
||||
if (ObjectUtil.isEmpty(code)){
|
||||
return R.fail("检查方法代码不能为空");
|
||||
}
|
||||
LambdaQueryWrapper<CheckMethod> wrapper = new LambdaQueryWrapper<CheckMethod>().eq(CheckMethod::getCode, code);
|
||||
boolean remove = checkMethodService.remove(wrapper);
|
||||
public R<?> removeCheckMethod(Integer checkMethodId) {
|
||||
boolean remove = checkMethodService.removeById(checkMethodId);
|
||||
return R.ok(remove);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||
LambdaQueryWrapper<CheckMethod> wrapper = new LambdaQueryWrapper<>();
|
||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||
wrapper.eq(CheckMethod::getCheckType, checkType);
|
||||
}
|
||||
if (name != null && ObjectUtil.isNotEmpty(name)) {
|
||||
wrapper.like(CheckMethod::getName, name);
|
||||
}
|
||||
if (packageName != null && ObjectUtil.isNotEmpty(packageName)) {
|
||||
wrapper.eq(CheckMethod::getPackageName, packageName);
|
||||
}
|
||||
List<CheckMethod> list = checkMethodService.list(wrapper);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return R.fail("导出Excel失败,无数据。");
|
||||
}
|
||||
|
||||
try {
|
||||
// 准备表头(key对应实体的字段名)
|
||||
Map<String, String> headers = new LinkedHashMap<>();
|
||||
headers.put("checkType", "检查类型");
|
||||
headers.put("code", "方法代码");
|
||||
headers.put("name", "方法名称");
|
||||
headers.put("packageName", "套餐名称");
|
||||
headers.put("exposureNum", "曝光次数");
|
||||
headers.put("orderNum", "序号");
|
||||
headers.put("remark", "备注");
|
||||
|
||||
// 文件名,只传文字部分
|
||||
String excelName = "检查方法列表";
|
||||
// 导出到Excel
|
||||
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
||||
} catch (IOException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
return R.fail("导出Excel失败:" + e.getMessage());
|
||||
}
|
||||
|
||||
return R.ok(null, "导出Excel成功");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,16 @@ import com.core.common.core.domain.R;
|
||||
import com.openhis.check.domain.CheckPart;
|
||||
import com.openhis.check.service.ICheckPartService;
|
||||
import com.openhis.web.check.appservice.ICheckPartAppService;
|
||||
import com.openhis.web.check.dto.CheckPartDto;
|
||||
import com.openhis.web.reportmanage.utils.ExcelFillerUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@Service
|
||||
@Slf4j
|
||||
public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
||||
@@ -24,54 +28,82 @@ public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> addCheckPart(CheckPartDto checkPartDto) {
|
||||
//数据检验
|
||||
if(ObjectUtil.isEmpty(checkPartDto.getName())){
|
||||
return R.fail("检查项目名称不能为空");
|
||||
public R<?> searchCheckPartList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName) {
|
||||
LambdaQueryWrapper<CheckPart> wrapper = new LambdaQueryWrapper<>();
|
||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||
wrapper.eq(CheckPart::getCheckType, checkType);
|
||||
}
|
||||
if(ObjectUtil.isEmpty(checkPartDto.getCode())){
|
||||
return R.fail("检查项目代码不能为空");
|
||||
if (name != null && ObjectUtil.isNotEmpty(name)) {
|
||||
wrapper.like(CheckPart::getName, name);
|
||||
}
|
||||
if(ObjectUtil.isEmpty(checkPartDto.getCheckType())){
|
||||
return R.fail("检查项目类型不能为空");
|
||||
if (packageName != null && ObjectUtil.isNotEmpty(packageName)) {
|
||||
wrapper.eq(CheckPart::getPackageName, packageName);
|
||||
}
|
||||
//唯一性检验
|
||||
LambdaQueryWrapper<CheckPart> wrapper = new LambdaQueryWrapper<CheckPart>()
|
||||
.eq(CheckPart::getName, checkPartDto.getName())
|
||||
.eq(CheckPart::getCode, checkPartDto.getCode())
|
||||
.eq(CheckPart::getCheckType, checkPartDto.getCheckType());
|
||||
if (checkPartService.getOne(wrapper) != null){
|
||||
return R.fail("检查部位已存在");
|
||||
}
|
||||
//封装数据
|
||||
CheckPart checkPart = new CheckPart();
|
||||
checkPart.setName(checkPartDto.getName());
|
||||
checkPart.setCode(checkPartDto.getCode());
|
||||
checkPart.setCheckType(checkPartDto.getCheckType());
|
||||
checkPart.setExposureNum(checkPartDto.getExposureNum());
|
||||
checkPart.setPackageName(checkPartDto.getPackageName());
|
||||
checkPart.setPrice(checkPartDto.getPrice());
|
||||
checkPart.setNumber(checkPartDto.getNumber());
|
||||
checkPart.setServiceScope(checkPartDto.getServiceScope());
|
||||
checkPart.setSubType(checkPartDto.getSubType());
|
||||
checkPart.setRemark(checkPartDto.getRemark());
|
||||
//保存
|
||||
checkPartService.save(checkPart);
|
||||
return R.ok();
|
||||
List<CheckPart> list = checkPartService.list(wrapper);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> removeCheckPart(Long code) {
|
||||
if (ObjectUtil.isEmpty(code)){
|
||||
return R.fail("检查项目代码不能为空");
|
||||
public R<?> addCheckPart(CheckPart checkPart) {
|
||||
//数据检验
|
||||
|
||||
//保存
|
||||
boolean save = checkPartService.save(checkPart);
|
||||
return R.ok(save);
|
||||
}
|
||||
LambdaQueryWrapper<CheckPart> wrapper = new LambdaQueryWrapper<CheckPart>().eq(CheckPart::getCode, code);
|
||||
boolean remove = checkPartService.remove(wrapper);
|
||||
|
||||
@Override
|
||||
public R<?> removeCheckPart(Integer checkPartId) {
|
||||
boolean remove = checkPartService.removeById(checkPartId);
|
||||
return R.ok(remove);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> updateCheckPart(CheckPartDto checkPartDto) {
|
||||
return R.ok();
|
||||
public R<?> updateCheckPart(CheckPart checkPart) {
|
||||
boolean b = checkPartService.updateById(checkPart);
|
||||
return R.ok(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||
LambdaQueryWrapper<CheckPart> wrapper = new LambdaQueryWrapper<>();
|
||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||
wrapper.eq(CheckPart::getCheckType, checkType);
|
||||
}
|
||||
if (name != null && ObjectUtil.isNotEmpty(name)) {
|
||||
wrapper.like(CheckPart::getName, name);
|
||||
}
|
||||
if (packageName != null && ObjectUtil.isNotEmpty(packageName)) {
|
||||
wrapper.eq(CheckPart::getPackageName, packageName);
|
||||
}
|
||||
List<CheckPart> list = checkPartService.list(wrapper);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return R.fail("导出Excel失败,无数据。");
|
||||
}
|
||||
|
||||
try {
|
||||
// 准备表头(key对应实体的字段名)
|
||||
Map<String, String> headers = new LinkedHashMap<>();
|
||||
headers.put("checkType", "检查类型");
|
||||
headers.put("code", "部位代码");
|
||||
headers.put("name", "部位名称");
|
||||
headers.put("packageName", "套餐名称");
|
||||
headers.put("exposureNum", "曝光次数");
|
||||
headers.put("price", "金额");
|
||||
headers.put("number", "序号");
|
||||
headers.put("serviceScope", "服务范围");
|
||||
headers.put("subType", "下级医技类型");
|
||||
headers.put("remark", "备注");
|
||||
|
||||
// 文件名,只传文字部分
|
||||
String excelName = "检查部位列表";
|
||||
// 导出到Excel
|
||||
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
||||
} catch (IOException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
return R.fail("导出Excel失败:" + e.getMessage());
|
||||
}
|
||||
return R.ok(null, "导出Excel成功");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.openhis.web.check.appservice.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.check.domain.LisGroupInfo;
|
||||
import com.openhis.check.service.ILisGroupInfoService;
|
||||
import com.openhis.web.check.appservice.ILisGroupInfoAppService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LisGroupInfoAppServiceImpl implements ILisGroupInfoAppService {
|
||||
@Resource
|
||||
private ILisGroupInfoService lisGroupInfoService;
|
||||
@Override
|
||||
public R<?> getLisGroupInfoList() {
|
||||
List<LisGroupInfo> list = lisGroupInfoService.list();
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> add(LisGroupInfo lisGroupInfo) {
|
||||
if (ObjectUtil.isEmpty(lisGroupInfo)) {
|
||||
return R.fail("信息不能为空");
|
||||
}
|
||||
boolean save = lisGroupInfoService.save(lisGroupInfo);
|
||||
return R.ok(save);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> update(LisGroupInfo lisGroupInfo) {
|
||||
if (ObjectUtil.isEmpty(lisGroupInfo)) {
|
||||
return R.fail("信息不能为空");
|
||||
}
|
||||
boolean update = lisGroupInfoService.updateById(lisGroupInfo);
|
||||
return R.ok( update);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> delete(Integer lisGroupInfoId) {
|
||||
boolean b = lisGroupInfoService.removeById(lisGroupInfoId);
|
||||
return R.ok(b);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.openhis.web.check.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
import com.openhis.web.check.appservice.ICheckMethodAppService;
|
||||
import com.openhis.web.check.dto.CheckMethodDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
@RestController
|
||||
@@ -18,29 +19,43 @@ public class CheckMethodController {
|
||||
|
||||
/*
|
||||
* 获取检查方法
|
||||
* @Param检查方法 此处参数注释有问题,完全是按照需求给的图来注释的
|
||||
* @Param 此处参数注释有问题,完全是按照需求给的图来注释的
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public R<?> getCheckMethodList(){
|
||||
return R.ok(checkMethodAppService.getCheckMethodList());
|
||||
}
|
||||
|
||||
/*
|
||||
* 条件查询检查方法
|
||||
* @Para
|
||||
* */
|
||||
@GetMapping("/search")
|
||||
public R<?> searchCheckMethodList(
|
||||
@RequestParam(required = false) Integer pageNo,
|
||||
@RequestParam(required = false) Integer pageSize,
|
||||
@RequestParam(required = false) String checkType,
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String packageName) {
|
||||
return R.ok(checkMethodAppService.searchCheckMethodList(pageNo,pageSize,checkType,name,packageName));
|
||||
}
|
||||
|
||||
/*
|
||||
* 新增检查方法
|
||||
* @Param
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public R<?> addCheckMethod(@RequestBody CheckMethodDto checkMethodDto){
|
||||
return R.ok(checkMethodAppService.addCheckMethod(checkMethodDto));
|
||||
public R<?> addCheckMethod(@RequestBody CheckMethod checkMethod){
|
||||
return R.ok(checkMethodAppService.addCheckMethod(checkMethod));
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除检查方法
|
||||
* @Param code代码
|
||||
*/
|
||||
@DeleteMapping("/delete/{code}")
|
||||
public R<?> deleteCheckMethod(@PathVariable Long code){
|
||||
return R.ok(checkMethodAppService.removeCheckMethod(code));
|
||||
@DeleteMapping("/delete/{checkMethodId}")
|
||||
public R<?> deleteCheckMethod(@PathVariable Integer checkMethodId){
|
||||
return R.ok(checkMethodAppService.removeCheckMethod(checkMethodId));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -48,7 +63,20 @@ public class CheckMethodController {
|
||||
* @Param
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
public R<?> updateCheckMethod(@RequestBody CheckMethodDto checkMethodDto){
|
||||
return R.ok(checkMethodAppService.updateCheckMethod(checkMethodDto));
|
||||
public R<?> updateCheckMethod(@RequestBody CheckMethod checkMethod){
|
||||
return R.ok(checkMethodAppService.updateCheckMethod(checkMethod));
|
||||
}
|
||||
|
||||
/*
|
||||
* 导出检查方法列表
|
||||
* @Param
|
||||
*/
|
||||
@GetMapping("/export")
|
||||
public void exportCheckMethod(
|
||||
@RequestParam(required = false) String checkType,
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String packageName,
|
||||
HttpServletResponse response) {
|
||||
checkMethodAppService.exportCheckMethod(checkType, name, packageName, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.openhis.web.check.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.check.domain.CheckPart;
|
||||
import com.openhis.web.check.appservice.ICheckPartAppService;
|
||||
import com.openhis.web.check.dto.CheckPartDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@@ -24,22 +25,35 @@ public class CheckPartController {
|
||||
return R.ok(checkPartAppService.getCheckPartList());
|
||||
}
|
||||
|
||||
/*
|
||||
* 条件搜索检查部位
|
||||
* @Param
|
||||
* */
|
||||
@GetMapping("/search")
|
||||
public R<?> searchCheckPartList(@RequestParam(required = false) Integer pageNo,
|
||||
@RequestParam(required = false) Integer pageSize,
|
||||
@RequestParam(required = false) String checkType,
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String packageName){
|
||||
return R.ok(checkPartAppService.searchCheckPartList(pageNo,pageSize,checkType,name,packageName));
|
||||
}
|
||||
|
||||
/*
|
||||
* 新增检查部位
|
||||
* @Param
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public R<?> addCheckPart(@RequestBody CheckPartDto checkPartDto){
|
||||
return R.ok(checkPartAppService.addCheckPart(checkPartDto));
|
||||
public R<?> addCheckPart(@RequestBody CheckPart checkPart){
|
||||
return R.ok(checkPartAppService.addCheckPart(checkPart));
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除检查部位
|
||||
* @Param code代码
|
||||
*/
|
||||
@DeleteMapping("/delete/{code}")
|
||||
public R<?> deleteCheckPart(@PathVariable Long code){
|
||||
return R.ok(checkPartAppService.removeCheckPart(code));
|
||||
@DeleteMapping("/delete/{checkPartId}")
|
||||
public R<?> deleteCheckPart(@PathVariable Integer checkPartId){
|
||||
return R.ok(checkPartAppService.removeCheckPart(checkPartId));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -47,7 +61,20 @@ public class CheckPartController {
|
||||
* @Param
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
public R<?> updateCheckPart(@RequestBody CheckPartDto checkPartDto){
|
||||
return R.ok(checkPartAppService.updateCheckPart(checkPartDto));
|
||||
public R<?> updateCheckPart(@RequestBody CheckPart checkPart){
|
||||
return R.ok(checkPartAppService.updateCheckPart(checkPart));
|
||||
}
|
||||
|
||||
/*
|
||||
* 导出检查部位列表
|
||||
* @Param
|
||||
*/
|
||||
@GetMapping("/export")
|
||||
public void exportCheckPart(
|
||||
@RequestParam(required = false) String checkType,
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String packageName,
|
||||
HttpServletResponse response) {
|
||||
checkPartAppService.exportCheckPart(checkType, name, packageName, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.openhis.web.check.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.check.appservice.ILisGroupInfoAppService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.openhis.check.domain.LisGroupInfo;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/check/lisGroupInfo")
|
||||
public class LisGroupInfoController {
|
||||
@Resource
|
||||
private ILisGroupInfoAppService lisGroupInfoAppService;
|
||||
|
||||
/*
|
||||
*
|
||||
* 获取Lis分组信息
|
||||
*
|
||||
* */
|
||||
@GetMapping("/list")
|
||||
public R<?> getLisGroupInfoList(){
|
||||
return R.ok(lisGroupInfoAppService.getLisGroupInfoList());
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* 新增Lis分组信息
|
||||
*
|
||||
* */
|
||||
@PostMapping("/add")
|
||||
public R<?> addLisGroupInfo(@RequestBody LisGroupInfo lisGroupInfo){
|
||||
return R.ok(lisGroupInfoAppService.add(lisGroupInfo));
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* 修改Lis分组信息
|
||||
*
|
||||
* */
|
||||
@PutMapping("/update")
|
||||
public R<?> updateLisGroupInfo(@RequestBody LisGroupInfo lisGroupInfo){
|
||||
return R.ok(lisGroupInfoAppService.update(lisGroupInfo));
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* 删除Lis分组信息
|
||||
*
|
||||
* */
|
||||
@DeleteMapping("/{lisGroupInfoId}")
|
||||
public R<?> deleteLisGroupInfo(@PathVariable Integer lisGroupInfoId){
|
||||
return R.ok(lisGroupInfoAppService.delete(lisGroupInfoId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.openhis.web.check.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface LisGroupInfoAppMapper {
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.openhis.web.lab.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
import com.openhis.lab.service.IInspectionTypeService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 检验类型管理Controller
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-09
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/inspection-type")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class InspectionTypeController extends BaseController {
|
||||
|
||||
// 辅助方法:将字节数组转换为十六进制字符串
|
||||
private static String bytesToHex(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
sb.append(String.format("%02X ", b));
|
||||
}
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
private final IInspectionTypeService inspectionTypeService;
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
|
||||
/**
|
||||
* 获取检验类型列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(InspectionType inspectionType) {
|
||||
// 使用Wrapper构建查询条件,确保order字段被正确处理
|
||||
QueryWrapper<InspectionType> queryWrapper = new QueryWrapper<>(inspectionType);
|
||||
List<InspectionType> list = inspectionTypeService.list(queryWrapper);
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检验类型详细
|
||||
*/
|
||||
@GetMapping("/{inspectionTypeId}")
|
||||
public AjaxResult getInfo(@PathVariable Long inspectionTypeId) {
|
||||
return AjaxResult.success(inspectionTypeService.getById(inspectionTypeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增检验类型
|
||||
*/
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody InspectionType inspectionType) {
|
||||
// 确保新增时ID为null,强制使用数据库自增序列
|
||||
inspectionType.setId(null);
|
||||
|
||||
// 去除code字段的前后空格,确保唯一性验证准确
|
||||
if (inspectionType.getCode() != null) {
|
||||
inspectionType.setCode(inspectionType.getCode().trim());
|
||||
}
|
||||
|
||||
// 验证code字段是否唯一
|
||||
QueryWrapper<InspectionType> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("code", inspectionType.getCode());
|
||||
|
||||
// 输出调试信息
|
||||
System.out.println("检查编码唯一性:code=" + inspectionType.getCode() + ", 长度=" + inspectionType.getCode().length());
|
||||
System.out.println("code的十六进制表示:" + bytesToHex(inspectionType.getCode().getBytes()));
|
||||
|
||||
// 直接查询具体记录,而不仅仅是计数
|
||||
List<InspectionType> existingRecords = inspectionTypeService.list(queryWrapper);
|
||||
System.out.println("数据库中存在的记录数:" + existingRecords.size());
|
||||
for (InspectionType record : existingRecords) {
|
||||
System.out.println("已存在记录:id=" + record.getId() + ", code=" + record.getCode() + ", code长度=" + record.getCode().length() + ", code十六进制=" + bytesToHex(record.getCode().getBytes()));
|
||||
}
|
||||
|
||||
if (!existingRecords.isEmpty()) {
|
||||
return AjaxResult.error("检验类型编码已存在");
|
||||
}
|
||||
|
||||
// 保存前再次验证
|
||||
System.out.println("准备保存数据:" + inspectionType);
|
||||
|
||||
try {
|
||||
// 使用事务确保一致性
|
||||
return transactionTemplate.execute(status -> {
|
||||
// 再次检查,防止并发问题
|
||||
QueryWrapper<InspectionType> checkWrapper = new QueryWrapper<>();
|
||||
checkWrapper.eq("code", inspectionType.getCode());
|
||||
List<InspectionType> finalCheck = inspectionTypeService.list(checkWrapper);
|
||||
if (!finalCheck.isEmpty()) {
|
||||
return AjaxResult.error("检验类型编码已存在");
|
||||
}
|
||||
|
||||
boolean result = inspectionTypeService.save(inspectionType);
|
||||
System.out.println("保存结果:" + result);
|
||||
return toAjax(result);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
System.out.println("保存失败,错误信息:" + e.getMessage());
|
||||
|
||||
// 捕获唯一性约束冲突异常
|
||||
if (e.getMessage().contains("uk_inspection_type_code") ||
|
||||
e.getMessage().contains("duplicate key value") ||
|
||||
e.getMessage().contains("检验类型编码已存在")) {
|
||||
return AjaxResult.error("检验类型编码已存在");
|
||||
}
|
||||
|
||||
return AjaxResult.error("保存失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改检验类型
|
||||
*/
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody InspectionType inspectionType) {
|
||||
// 去除code字段的前后空格,确保唯一性验证准确
|
||||
if (inspectionType.getCode() != null) {
|
||||
inspectionType.setCode(inspectionType.getCode().trim());
|
||||
}
|
||||
|
||||
// 验证code字段是否唯一(排除自身)
|
||||
QueryWrapper<InspectionType> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("code", inspectionType.getCode())
|
||||
.ne("id", inspectionType.getId());
|
||||
if (inspectionTypeService.count(queryWrapper) > 0) {
|
||||
return AjaxResult.error("检验类型编码已存在");
|
||||
}
|
||||
|
||||
try {
|
||||
boolean result = inspectionTypeService.updateById(inspectionType);
|
||||
return toAjax(result);
|
||||
} catch (Exception e) {
|
||||
// 捕获唯一性约束冲突异常
|
||||
if (e.getMessage().contains("uk_inspection_type_code") ||
|
||||
e.getMessage().contains("duplicate key value") ||
|
||||
e.getMessage().contains("检验类型编码已存在")) {
|
||||
return AjaxResult.error("检验类型编码已存在");
|
||||
}
|
||||
|
||||
return AjaxResult.error("更新失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除检验类型
|
||||
*/
|
||||
@DeleteMapping("/{inspectionTypeId}")
|
||||
public AjaxResult remove(@PathVariable Long inspectionTypeId) {
|
||||
log.info("删除检验类型,ID: {}", inspectionTypeId);
|
||||
try {
|
||||
// 检查记录是否存在
|
||||
InspectionType existing = inspectionTypeService.getById(inspectionTypeId);
|
||||
log.info("删除前检查记录是否存在: {}", existing != null);
|
||||
|
||||
if (existing == null) {
|
||||
log.warn("删除失败:检验类型ID: {} 不存在", inspectionTypeId);
|
||||
return AjaxResult.error("删除失败: 记录不存在");
|
||||
}
|
||||
|
||||
// 使用MyBatis Plus的removeById方法执行逻辑删除
|
||||
boolean result = inspectionTypeService.removeById(inspectionTypeId);
|
||||
log.info("逻辑删除检验类型结果: {}", result);
|
||||
|
||||
AjaxResult response = toAjax(result);
|
||||
log.info("删除响应: {}", response);
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("删除检验类型失败,ID: {}, 错误: {}", inspectionTypeId, e.getMessage(), e);
|
||||
return AjaxResult.error("删除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 测试删除接口,直接返回成功
|
||||
@DeleteMapping("/test-delete/{id}")
|
||||
public AjaxResult testDelete(@PathVariable Long id) {
|
||||
log.info("测试删除接口,ID: {}", id);
|
||||
return AjaxResult.success("测试删除成功");
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,11 @@ mybatis-plus:
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 加载全局的配置文件
|
||||
configLocation: classpath:mybatis/mybatis-config.xml
|
||||
global-config:
|
||||
db-config:
|
||||
logic-delete-field: validFlag # 全局逻辑删除的实体字段名
|
||||
logic-delete-value: 0 # 逻辑已删除值(默认为 1)
|
||||
logic-not-delete-value: 1 # 逻辑未删除值(默认为 0)
|
||||
|
||||
# PageHelper分页插件
|
||||
pagehelper:
|
||||
|
||||
@@ -77,4 +77,16 @@ public class Organization extends HisBaseEntity {
|
||||
|
||||
/** 默认挂号医生 */
|
||||
private Long defDoctorId;
|
||||
|
||||
/** 挂号科室标记 */
|
||||
private Integer registerFlag;
|
||||
|
||||
/** 科室位置 */
|
||||
private String location;
|
||||
|
||||
/** 科室简介 */
|
||||
private String intro;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.openhis.check.domain;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
@@ -26,7 +25,7 @@ public class CheckMethod {
|
||||
* 检查方法ID
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Integer id;
|
||||
|
||||
/* 检查类型 */
|
||||
private String checkType;
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.openhis.check.domain;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
@@ -24,7 +23,7 @@ public class CheckPart {
|
||||
|
||||
/** 检查部位ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Integer id;
|
||||
|
||||
/** 检查部位名称 */
|
||||
private String name;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.openhis.check.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "lis_group_info",autoResultMap = true)
|
||||
public class LisGroupInfo {
|
||||
|
||||
/** id */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/** 卫生机构 */
|
||||
private String hospital;
|
||||
|
||||
/** 创建日期 */
|
||||
private LocalDate date;
|
||||
|
||||
/** LIS分组名称 */
|
||||
private String groupName;
|
||||
|
||||
/** 采血管类型 */
|
||||
private String tube;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 创建时间 */
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.openhis.check.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.check.domain.LisGroupInfo;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface LisGroupInfoMapper extends BaseMapper<LisGroupInfo> {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.openhis.check.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.check.domain.LisGroupInfo;
|
||||
public interface ILisGroupInfoService extends IService<LisGroupInfo>{
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.openhis.check.service.impl;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.check.mapper.LisGroupInfoMapper;
|
||||
import com.openhis.check.domain.LisGroupInfo;
|
||||
import com.openhis.check.service.ILisGroupInfoService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class LisGroupInfoServiceImpl extends ServiceImpl<LisGroupInfoMapper,LisGroupInfo> implements ILisGroupInfoService{
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.openhis.lab.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 检验类型
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-09
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "inspection_type", autoResultMap = true)
|
||||
public class InspectionType {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 检验类型编码 */
|
||||
private String code;
|
||||
|
||||
/** 检验类型名称 */
|
||||
private String name;
|
||||
|
||||
/** 所属科室 */
|
||||
private String department;
|
||||
|
||||
/** 排序 */
|
||||
@TableField("\"order\"")
|
||||
private Integer sortOrder;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 有效标志(1:有效,0:无效) */
|
||||
@TableField("valid_flag")
|
||||
@TableLogic(value = "1", delval = "0")
|
||||
private Integer validFlag;
|
||||
|
||||
/** 创建时间 */
|
||||
@TableField("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
/** 更新时间 */
|
||||
@TableField("updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
/** 版本号 */
|
||||
private Integer version;
|
||||
|
||||
/**
|
||||
* 以下字段数据库表中不存在,用于禁用MyBatis Plus自动添加的字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String createBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String updateBy;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer tenantId;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.openhis.lab.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 检验类型Mapper接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-09
|
||||
*/
|
||||
@Repository
|
||||
public interface InspectionTypeMapper extends BaseMapper<InspectionType> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.openhis.lab.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
|
||||
/**
|
||||
* 检验类型Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-09
|
||||
*/
|
||||
public interface IInspectionTypeService extends IService<InspectionType> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.lab.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
import com.openhis.lab.mapper.InspectionTypeMapper;
|
||||
import com.openhis.lab.service.IInspectionTypeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 检验类型Service实现类
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-09
|
||||
*/
|
||||
@Service
|
||||
public class InspectionTypeServiceImpl extends ServiceImpl<InspectionTypeMapper, InspectionType> implements IInspectionTypeService {
|
||||
|
||||
}
|
||||
@@ -4,4 +4,14 @@
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.openhis.administration.mapper.OrganizationMapper">
|
||||
|
||||
<!-- 自定义selectById方法,确保包含所有字段,包括新增字段 -->
|
||||
<select id="selectById" parameterType="java.lang.Long" resultType="com.openhis.administration.domain.Organization">
|
||||
SELECT id, bus_no, name, active_flag, type_enum, class_enum, py_str, wb_str,
|
||||
yb_no, yb_name, caty, display_order, medins_id, medins_admdvs,
|
||||
medins_type, medins_lv, def_doctor_id, create_by, create_time,
|
||||
update_by, update_time, tenant_id, delete_flag,
|
||||
register_flag, location, intro, remark
|
||||
FROM adm_organization
|
||||
WHERE id = #{id} AND delete_flag = '0'
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -2,13 +2,13 @@
|
||||
VITE_APP_TITLE=医院信息管理系统
|
||||
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV=production
|
||||
VITE_APP_ENV= 'prod'
|
||||
|
||||
# OpenHIS管理系统/生产环境
|
||||
VITE_APP_BASE_API=/prd-api
|
||||
VITE_APP_BASE_API= '/prd-api'
|
||||
|
||||
# 租户ID配置
|
||||
VITE_APP_TENANT_ID=1
|
||||
VITE_APP_TENANT_ID= '1'
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
VITE_BUILD_COMPRESS=gzip
|
||||
VITE_BUILD_COMPRESS = gzip
|
||||
@@ -5,6 +5,7 @@ VITE_APP_TITLE = 医院信息管理系统
|
||||
VITE_APP_ENV = 'test'
|
||||
|
||||
# OpenHIS管理系统/测试环境
|
||||
|
||||
VITE_APP_BASE_API = '/test-api'
|
||||
|
||||
# 租户ID配置
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* @Author: yangbo@bjgoodwill.com
|
||||
* @Date: 2024-10-14 09:52:54
|
||||
* @Description:
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build:prd": "vite build --mode prd",
|
||||
"dev": "vite --mode dev",
|
||||
"build:prod": "vite build --mode prod",
|
||||
"build:stage": "vite build --mode staging",
|
||||
"build:test": "vite build --mode test",
|
||||
"build:dev": "vite build --mode dev",
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询检验类型列表
|
||||
export function listInspectionType(query) {
|
||||
return request({
|
||||
url: '/system/inspection-type/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检验类型详细
|
||||
export function getInspectionType(inspectionTypeId) {
|
||||
return request({
|
||||
url: `/system/inspection-type/${inspectionTypeId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增检验类型
|
||||
export function addInspectionType(data) {
|
||||
return request({
|
||||
url: '/system/inspection-type',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改检验类型
|
||||
export function updateInspectionType(data) {
|
||||
return request({
|
||||
url: '/system/inspection-type',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除检验类型
|
||||
export function delInspectionType(inspectionTypeId) {
|
||||
return request({
|
||||
url: `/system/inspection-type/${inspectionTypeId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -46,21 +46,112 @@ export function delCheckType(checkTypeId) {
|
||||
// 查询检查方法列表
|
||||
export function listCheckMethod(query) {
|
||||
return request({
|
||||
url: '/system/check-method/list',
|
||||
url: '/check/method/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 搜索检查方法列表
|
||||
export function searchCheckMethod(query) {
|
||||
return request({
|
||||
url: '/check/method/search',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 新增检查方法
|
||||
export function addCheckMethod(data) {
|
||||
return request({
|
||||
url: '/check/method/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改检查方法
|
||||
export function updateCheckMethod(data) {
|
||||
return request({
|
||||
url: '/check/method/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除检查方法
|
||||
export function delCheckMethod(checkMethodId) {
|
||||
return request({
|
||||
url: '/check/method/delete/' + checkMethodId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出检查方法
|
||||
export function exportCheckMethod(query) {
|
||||
return request({
|
||||
url: '/check/method/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出检查部位
|
||||
export function exportCheckPart(query) {
|
||||
return request({
|
||||
url: '/check/part/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检查部位列表
|
||||
export function listCheckPart(query) {
|
||||
return request({
|
||||
url: '/system/check-part/list',
|
||||
url: '/check/part/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 搜索检查部位列表
|
||||
export function searchCheckPart(query) {
|
||||
return request({
|
||||
url: '/check/part/search',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 新增检查部位
|
||||
export function addCheckPart(data) {
|
||||
return request({
|
||||
url: '/check/part/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除检查部位
|
||||
export function delCheckPart(checkPartId) {
|
||||
return request({
|
||||
url: '/check/part/delete/' + checkPartId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新检查部位
|
||||
export function updateCheckPart(data) {
|
||||
return request({
|
||||
url: '/check/part/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检查套餐列表
|
||||
export function listCheckPackage(query) {
|
||||
return request({
|
||||
@@ -103,3 +194,46 @@ export function delCheckPackage(id) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询LIS分组列表
|
||||
export function listLisGroup(query) {
|
||||
return request({
|
||||
url: '/check/lisGroupInfo/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 根据ID查询LIS分组详情
|
||||
export function getLisGroup(id) {
|
||||
return request({
|
||||
url: `/check/lisGroupInfo/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增LIS分组
|
||||
export function addLisGroup(data) {
|
||||
return request({
|
||||
url: '/check/lisGroupInfo/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改LIS分组
|
||||
export function updateLisGroup(data) {
|
||||
return request({
|
||||
url: '/check/lisGroupInfo/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除LIS分组
|
||||
export function delLisGroup(id) {
|
||||
return request({
|
||||
url: `/check/lisGroupInfo/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
44
openhis-ui-vue3/src/api/system/inspectionType.js
Normal file
44
openhis-ui-vue3/src/api/system/inspectionType.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询检验类型列表
|
||||
export function listInspectionType(query) {
|
||||
return request({
|
||||
url: '/system/inspection-type/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询检验类型详细
|
||||
export function getInspectionType(inspectionTypeId) {
|
||||
return request({
|
||||
url: '/system/inspection-type/' + inspectionTypeId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增检验类型
|
||||
export function addInspectionType(data) {
|
||||
return request({
|
||||
url: '/system/inspection-type',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改检验类型
|
||||
export function updateInspectionType(data) {
|
||||
return request({
|
||||
url: '/system/inspection-type',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除检验类型
|
||||
export function delInspectionType(inspectionTypeId) {
|
||||
return request({
|
||||
url: '/system/inspection-type/' + inspectionTypeId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -47,11 +47,6 @@ export const constantRoutes = [
|
||||
component: () => import('@/views/register'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: () => import('@/views/error/404'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/401',
|
||||
component: () => import('@/views/error/401'),
|
||||
@@ -83,6 +78,20 @@ export const constantRoutes = [
|
||||
meta: { title: '个人中心', icon: 'user' }
|
||||
}
|
||||
]
|
||||
},
|
||||
// 添加套餐管理相关路由到公共路由,确保始终可用
|
||||
{
|
||||
path: '/maintainSystem/Inspection/PackageManagement',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||
name: 'DirectPackageManagement',
|
||||
meta: { title: '套餐管理' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -134,6 +143,20 @@ export const constantRoutes = [
|
||||
component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
||||
name: 'ChargeConfig',
|
||||
meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
||||
},
|
||||
{
|
||||
path: 'Inspection',
|
||||
component: () => import('@/views/maintainSystem/Inspection/index.vue'),
|
||||
name: 'Inspection',
|
||||
meta: { title: '检验管理', icon: 'inspection' },
|
||||
children: [
|
||||
{
|
||||
path: 'PackageManagement',
|
||||
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||
name: 'PackageManagement',
|
||||
meta: { title: '套餐管理' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -345,6 +368,13 @@ export const constantRoutes = [
|
||||
// 合并常量路由和动态路由,确保所有路由都能被访问
|
||||
const allRoutes = [...constantRoutes, ...dynamicRoutes];
|
||||
|
||||
// 添加404路由到所有路由的最后
|
||||
allRoutes.push({
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: () => import('@/views/error/404'),
|
||||
hidden: true
|
||||
});
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: allRoutes,
|
||||
|
||||
@@ -123,6 +123,9 @@ export function filterDynamicRoutes(routes) {
|
||||
if (auth.hasRoleOr(route.roles)) {
|
||||
res.push(route)
|
||||
}
|
||||
} else {
|
||||
// 如果没有权限设置,默认允许访问
|
||||
res.push(route)
|
||||
}
|
||||
})
|
||||
return res
|
||||
|
||||
@@ -33,8 +33,9 @@ export function deleteOrganization(orgIds) {
|
||||
|
||||
export function getOrgDetail(id) {
|
||||
return request({
|
||||
url: '/base-data-manage/organization/organization?orgId=' + id,
|
||||
url: '/base-data-manage/organization/organization-getById',
|
||||
method: 'get',
|
||||
params: { orgId: id }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,14 @@
|
||||
<el-table-column label="科室分类" align="center" prop="classEnum_dictText" />
|
||||
<el-table-column label="医保码" align="center" prop="ybNo" />
|
||||
<el-table-column label="医保名称" align="center" prop="ybName" />
|
||||
<el-table-column label="挂号科室" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.registerFlag ? '是' : '否' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="科室位置" align="center" prop="location" show-overflow-tooltip />
|
||||
<el-table-column label="科室简介" align="center" prop="intro" show-overflow-tooltip />
|
||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||
<el-table-column label="状态" align="center" prop="activeFlag_dictText" />
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
@@ -129,6 +137,35 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-form-item label="挂号科室" prop="registerFlag">
|
||||
<el-radio-group v-model="form.registerFlag" size="large">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="科室位置" prop="location">
|
||||
<el-input v-model="form.location" placeholder="请输入科室位置" maxlength="100" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item label="科室简介" prop="intro">
|
||||
<el-input
|
||||
v-model="form.intro"
|
||||
type="textarea"
|
||||
placeholder="请输入科室简介"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
:rows="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
placeholder="请输入备注信息"
|
||||
maxlength="1000"
|
||||
show-word-limit
|
||||
:rows="3"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
@@ -141,7 +178,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Organization">
|
||||
import { getList, deleteOrganization, addOrganization, updateOrganization, disableOrg, initOrgTypeOption, enableOrg } from './components/api';
|
||||
import { getList, deleteOrganization, addOrganization, updateOrganization, disableOrg, initOrgTypeOption, enableOrg, getOrgDetail } from './components/api';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const loading = ref(true);
|
||||
@@ -154,6 +191,10 @@ const form = ref({
|
||||
name: undefined,
|
||||
typeEnum: undefined,
|
||||
busNoParent: undefined,
|
||||
registerFlag: false, // 挂号科室标记
|
||||
location: undefined, // 科室位置
|
||||
intro: undefined, // 科室简介
|
||||
remark: undefined, // 备注
|
||||
});
|
||||
const orgTableRef = ref();
|
||||
const orgRef = ref();
|
||||
@@ -169,6 +210,10 @@ const rules = ref({
|
||||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'change' },
|
||||
],
|
||||
typeEnum: [{ required: true, message: '请选择科室类型', trigger: 'change' }],
|
||||
// 新增字段验证规则
|
||||
location: [{ required: false, message: '请输入科室位置', trigger: 'blur' }],
|
||||
intro: [{ required: false, message: '请输入科室简介', trigger: 'blur' }],
|
||||
remark: [{ required: false, message: '请输入备注信息', trigger: 'blur' }],
|
||||
});
|
||||
|
||||
getPageList();
|
||||
@@ -230,6 +275,10 @@ function initOption() {
|
||||
|
||||
function reset() {
|
||||
form.value.id = undefined;
|
||||
form.value.registerFlag = false;
|
||||
form.value.location = undefined;
|
||||
form.value.intro = undefined;
|
||||
form.value.remark = undefined;
|
||||
orgRef.value.resetFields();
|
||||
}
|
||||
|
||||
@@ -248,7 +297,7 @@ function getDictLabel(value) {
|
||||
}
|
||||
|
||||
function getPageList() {
|
||||
loading.value = false;
|
||||
loading.value = true;
|
||||
getList(queryParams.value).then((res) => {
|
||||
// 处理返回的科室数据,确保科室分类显示与系统标准字典一致
|
||||
const processedData = res.data.records.map(item => {
|
||||
@@ -269,6 +318,12 @@ function getPageList() {
|
||||
|
||||
organization.value = processedData;
|
||||
total.value = res.data.total;
|
||||
}).catch(error => {
|
||||
console.error('获取科室列表失败:', error);
|
||||
proxy.$modal.msgError('获取科室列表失败,请稍后重试');
|
||||
organization.value = [];
|
||||
total.value = 0;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
@@ -285,17 +340,29 @@ function handelEdit(row) {
|
||||
|
||||
title.value = '编辑科室';
|
||||
open.value = true;
|
||||
setTimeout(() => {
|
||||
form.value.id = row.id;
|
||||
form.value.busNo = row.busNo;
|
||||
form.value.name = row.name;
|
||||
form.value.ybNo = row.ybNo;
|
||||
form.value.ybName = row.ybName;
|
||||
form.value.typeEnum = row.typeEnum;
|
||||
|
||||
// 调用后端API获取完整的科室信息,确保包含所有字段
|
||||
getOrgDetail(row.id).then(res => {
|
||||
if (res.code === 200) {
|
||||
const orgInfo = res.data;
|
||||
form.value.id = orgInfo.id;
|
||||
form.value.busNo = orgInfo.busNo;
|
||||
form.value.name = orgInfo.name;
|
||||
form.value.ybNo = orgInfo.ybNo;
|
||||
form.value.ybName = orgInfo.ybName;
|
||||
form.value.typeEnum = orgInfo.typeEnum;
|
||||
// 确保科室分类值的类型正确,使其能正确匹配下拉选项中的值
|
||||
form.value.classEnum = row.classEnum !== undefined ? String(row.classEnum) : undefined;
|
||||
form.value.busNoParent = row.busNo.split('.').length > 1 ? row.busNo.split('.')[0] : undefined;
|
||||
}, 50);
|
||||
form.value.classEnum = orgInfo.classEnum !== undefined ? String(orgInfo.classEnum) : undefined;
|
||||
form.value.busNoParent = orgInfo.busNo.split('.').length > 1 ? orgInfo.busNo.split('.')[0] : undefined;
|
||||
form.value.registerFlag = !!orgInfo.registerFlag;
|
||||
form.value.location = orgInfo.location;
|
||||
form.value.intro = orgInfo.intro;
|
||||
form.value.remark = orgInfo.remark;
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('获取科室信息失败:', error);
|
||||
proxy.$modal.msgError('获取科室信息失败');
|
||||
});
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
@@ -308,20 +375,43 @@ function cancel() {
|
||||
function submitForm() {
|
||||
proxy.$refs['orgRef'].validate((valid) => {
|
||||
if (valid) {
|
||||
// 创建表单数据副本,避免直接修改原始form对象
|
||||
const formData = { ...form.value };
|
||||
// 确保registerFlag从布尔值转换为整数(true=1, false=0)
|
||||
formData.registerFlag = Number(formData.registerFlag ? 1 : 0);
|
||||
|
||||
// 确保classEnum字段有值(数据库必填)
|
||||
// 如果未定义,设置默认值1
|
||||
if (formData.classEnum === undefined || formData.classEnum === null || formData.classEnum === '') {
|
||||
formData.classEnum = 1;
|
||||
}
|
||||
|
||||
// 确保classEnum为数字类型
|
||||
formData.classEnum = Number(formData.classEnum);
|
||||
|
||||
// 验证提交数据
|
||||
console.log('提交的数据:', formData);
|
||||
|
||||
if (form.value.id == undefined) {
|
||||
if (form.value.busNoParent) {
|
||||
form.value.busNo = form.value.busNoParent;
|
||||
formData.busNo = form.value.busNoParent;
|
||||
}
|
||||
addOrganization(form.value).then((res) => {
|
||||
addOrganization(formData).then((res) => {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
open.value = false;
|
||||
getPageList();
|
||||
}).catch(error => {
|
||||
console.error('添加科室失败:', error);
|
||||
proxy.$modal.msgError('添加科室失败,请稍后重试');
|
||||
});
|
||||
} else {
|
||||
updateOrganization(form.value).then((res) => {
|
||||
updateOrganization(formData).then((res) => {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
open.value = false;
|
||||
getPageList();
|
||||
}).catch(error => {
|
||||
console.error('更新科室失败:', error);
|
||||
proxy.$modal.msgError('更新科室失败,请稍后重试');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -340,8 +430,12 @@ function handleDelete() {
|
||||
loading.value = true;
|
||||
deleteOrganization(selectRowIds.value.join(',')).then((res) => {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
loading.value = false;
|
||||
getPageList();
|
||||
}).catch(error => {
|
||||
console.error('删除科室失败:', error);
|
||||
proxy.$modal.msgError('删除科室失败,请稍后重试');
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
// 停用
|
||||
@@ -349,6 +443,9 @@ function handleDisabled(id) {
|
||||
disableOrg(id).then((res) => {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
getPageList();
|
||||
}).catch(error => {
|
||||
console.error('停用科室失败:', error);
|
||||
proxy.$modal.msgError('停用科室失败,请稍后重试');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -357,6 +454,9 @@ function handelEnable(id) {
|
||||
enableOrg(id).then((res) => {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
getPageList();
|
||||
}).catch(error => {
|
||||
console.error('启用科室失败:', error);
|
||||
proxy.$modal.msgError('启用科室失败,请稍后重试');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,643 @@
|
||||
<template>
|
||||
<div class="package-management">
|
||||
<!-- 左侧导航栏 -->
|
||||
<nav class="sidebar" :class="{ active: sidebarActive }">
|
||||
<div class="sidebar-item" @click="navigateToTab(0)">检验类型</div>
|
||||
<div class="sidebar-item" @click="navigateToTab(1)">检验项目</div>
|
||||
<div class="sidebar-item active" @click="navigateToTab(2)">套餐设置</div>
|
||||
</nav>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<main class="content">
|
||||
<!-- 导航切换按钮(响应式) -->
|
||||
<div class="menu-toggle" @click="toggleSidebar">
|
||||
<i class="fas fa-bars"></i>
|
||||
</div>
|
||||
|
||||
<!-- 查询过滤区域 -->
|
||||
<section class="filter-bar">
|
||||
<div class="filter-item">
|
||||
<label>日期:</label>
|
||||
<input type="date" v-model="searchParams.startDate" placeholder="开始日期">
|
||||
<span>至</span>
|
||||
<input type="date" v-model="searchParams.endDate" placeholder="结束日期">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>卫生机构:</label>
|
||||
<select>
|
||||
<option>演示医院</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>套餐名称:</label>
|
||||
<input type="text" v-model="searchParams.packageName" placeholder="套餐名称">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>套餐级别:</label>
|
||||
<select v-model="searchParams.packageLevel">
|
||||
<option value="">请选择套餐级别</option>
|
||||
<option value="全院套餐">全院套餐</option>
|
||||
<option value="科室套餐">科室套餐</option>
|
||||
<option value="个人套餐">个人套餐</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>套餐类别:</label>
|
||||
<select>
|
||||
<option>检验套餐</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>科室:</label>
|
||||
<select>
|
||||
<option value="">请选择科室</option>
|
||||
<option value="内科">内科</option>
|
||||
<option value="儿科">儿科</option>
|
||||
<option value="外科">外科</option>
|
||||
<option value="妇科">妇科</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<label>用户:</label>
|
||||
<select></select>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮组 -->
|
||||
<div class="button-group">
|
||||
<button class="btn btn-search" @click="handleSearch"><i class="fas fa-search" style="margin-right: 6px;"></i>查询</button>
|
||||
<button class="btn btn-reset" @click="handleReset"><i class="fas fa-redo" style="margin-right: 6px;"></i>重置</button>
|
||||
<button class="btn btn-primary" @click="handleAdd"><i class="fas fa-plus" style="margin-right: 6px;"></i>新增</button>
|
||||
<button class="btn btn-export" @click="handleExport"><i class="fas fa-download" style="margin-right: 6px;"></i>导出</button>
|
||||
<button class="btn btn-copy" @click="returnToPackageSetup"><i class="fas fa-arrow-left" style="margin-right: 6px;"></i>返回</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<section class="table-container">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>卫生机构</th>
|
||||
<th>日期</th>
|
||||
<th>套餐名称</th>
|
||||
<th>套餐类别</th>
|
||||
<th>套餐级别</th>
|
||||
<th>科室</th>
|
||||
<th>用户</th>
|
||||
<th class="text-right">金额</th>
|
||||
<th class="text-right">服务费</th>
|
||||
<th class="text-right">总金额</th>
|
||||
<th>组合套餐</th>
|
||||
<th>显示套餐名</th>
|
||||
<th>启用标志</th>
|
||||
<th>操作人</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in filteredData" :key="item.id">
|
||||
<td>{{ item.id }}</td>
|
||||
<td>{{ item.hospital }}</td>
|
||||
<td>{{ item.date }}</td>
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ item.type }}</td>
|
||||
<td>{{ item.level }}</td>
|
||||
<td>{{ item.dept || '-' }}</td>
|
||||
<td>{{ item.user || '-' }}</td>
|
||||
<td class="text-right">{{ item.amount.toFixed(2) }}</td>
|
||||
<td class="text-right">{{ item.fee.toFixed(2) }}</td>
|
||||
<td class="text-right">{{ item.total.toFixed(2) }}</td>
|
||||
<td><span class="status-tag" :class="item.combined === '是' ? 'status-no' : 'status-yes'">{{ item.combined }}</span></td>
|
||||
<td><span class="status-tag" :class="item.display === '是' ? 'status-yes' : 'status-no'">{{ item.display }}</span></td>
|
||||
<td><span class="status-tag" :class="item.enabled === '是' ? 'status-yes' : 'status-no'">{{ item.enabled }}</span></td>
|
||||
<td>{{ item.operator }}</td>
|
||||
<td>
|
||||
<div class="action-icons">
|
||||
<el-button type="text" @click="handleEdit(item)"><el-icon><Edit /></el-icon></el-button>
|
||||
<el-button type="text" @click="handleView(item)"><el-icon><View /></el-icon></el-button>
|
||||
<el-button type="text" @click="handleDelete(item)"><el-icon><Delete /></el-icon></el-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<div class="pagination">
|
||||
<button class="page-btn"><</button>
|
||||
<button class="page-btn active">1</button>
|
||||
<button class="page-btn">2</button>
|
||||
<button class="page-btn">3</button>
|
||||
<button class="page-btn">...</button>
|
||||
<button class="page-btn">10</button>
|
||||
<button class="page-btn">></button>
|
||||
<div class="total-count">总数:{{ filteredData.length }}</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Edit, View, Delete } from '@element-plus/icons-vue';
|
||||
|
||||
// 创建路由实例
|
||||
const router = useRouter();
|
||||
|
||||
// 侧边栏状态
|
||||
const sidebarActive = ref(false);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{id: 2348, hospital: '演示医院', date: '2025-11-17', name: '血脂333', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 40.00, fee: 0.00, total: 40.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
|
||||
{id: 2341, hospital: '演示医院', date: '2025-10-31', name: '病理检测', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 50.00, fee: 0.00, total: 50.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
|
||||
{id: 2340, hospital: '演示医院', date: '2025-10-31', name: '肝功能', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 31.00, fee: 0.00, total: 31.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
|
||||
{id: 2339, hospital: '演示医院', date: '2025-10-31', name: '风湿', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 119.00, fee: 0.00, total: 119.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
|
||||
{id: 2338, hospital: '演示医院', date: '2025-10-31', name: '尿常规', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 1.00, fee: 0.00, total: 1.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
|
||||
{id: 2297, hospital: '演示医院', date: '2025-04-30', name: '测试', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 241.00, fee: 0.00, total: 241.00, combined: '否', display: '是', enabled: '否', operator: '徐斌'},
|
||||
]);
|
||||
|
||||
// 获取当前日期的函数,格式为YYYY-MM-DD
|
||||
function getCurrentDate() {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
// 搜索参数
|
||||
const searchParams = ref({
|
||||
startDate: getCurrentDate(),
|
||||
endDate: getCurrentDate(),
|
||||
packageName: '',
|
||||
packageLevel: ''
|
||||
});
|
||||
|
||||
// 过滤后的数据
|
||||
const filteredData = computed(() => {
|
||||
return tableData.value.filter(item => {
|
||||
// 日期筛选
|
||||
if (searchParams.value.startDate && item.date < searchParams.value.startDate) return false;
|
||||
if (searchParams.value.endDate && item.date > searchParams.value.endDate) return false;
|
||||
|
||||
// 套餐名称筛选
|
||||
if (searchParams.value.packageName && !item.name.toLowerCase().includes(searchParams.value.packageName.toLowerCase())) return false;
|
||||
|
||||
// 套餐级别筛选
|
||||
if (searchParams.value.packageLevel && item.level !== searchParams.value.packageLevel) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
// 返回套餐设置主界面
|
||||
function returnToPackageSetup() {
|
||||
router.push('/maintainSystem/Inspection?tab=2');
|
||||
}
|
||||
|
||||
// 导航到指定标签页
|
||||
function navigateToTab(tabIndex) {
|
||||
router.push(`/maintainSystem/Inspection?tab=${tabIndex}`);
|
||||
}
|
||||
|
||||
// 切换侧边栏
|
||||
function toggleSidebar() {
|
||||
sidebarActive.value = !sidebarActive.value;
|
||||
}
|
||||
|
||||
// 处理查询
|
||||
function handleSearch() {
|
||||
// 过滤逻辑已在computed属性中实现
|
||||
}
|
||||
|
||||
// 处理重置
|
||||
function handleReset() {
|
||||
searchParams.value = {
|
||||
startDate: getCurrentDate(),
|
||||
endDate: getCurrentDate(),
|
||||
packageName: '',
|
||||
packageLevel: ''
|
||||
};
|
||||
}
|
||||
|
||||
// 处理新增
|
||||
function handleAdd() {
|
||||
router.push('/maintainSystem/Inspection?tab=2');
|
||||
}
|
||||
|
||||
// 处理编辑
|
||||
function handleEdit(item) {
|
||||
alert(`准备编辑套餐:${item.name}\n数据已加载至编辑表单(套餐设置主界面)`);
|
||||
}
|
||||
|
||||
// 处理查看
|
||||
function handleView(item) {
|
||||
alert(`准备查看套餐:${item.name}\n数据已加载至查看表单(套餐设置主界面)`);
|
||||
}
|
||||
|
||||
// 处理删除
|
||||
function handleDelete(item) {
|
||||
if (confirm(`确定要删除套餐 "${item.name}" 吗?`)) {
|
||||
const index = tableData.value.findIndex(i => i.id === item.id);
|
||||
if (index !== -1) {
|
||||
tableData.value.splice(index, 1);
|
||||
alert(`套餐 "${item.name}" 已删除`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理导出
|
||||
function handleExport() {
|
||||
// 获取当前筛选后的数据
|
||||
const dataToExport = filteredData.value;
|
||||
|
||||
// 转换为CSV格式
|
||||
const csvContent = convertToCSV(dataToExport);
|
||||
|
||||
// 创建下载链接
|
||||
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.setAttribute('href', url);
|
||||
link.setAttribute('download', `套餐数据_${new Date().toISOString().slice(0,10)}.csv`);
|
||||
link.style.visibility = 'hidden';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
// 将数据转换为CSV格式的函数
|
||||
function convertToCSV(data) {
|
||||
if (data.length === 0) return '';
|
||||
|
||||
// 获取表头
|
||||
const headers = Object.keys(data[0]);
|
||||
|
||||
// 构建CSV内容
|
||||
let csv = headers.join(',') + '\n';
|
||||
|
||||
// 添加数据行
|
||||
data.forEach(row => {
|
||||
const values = headers.map(header => {
|
||||
// 处理可能包含逗号的值
|
||||
const value = row[header] === null || row[header] === undefined ? '' : row[header];
|
||||
return `"${value.toString().replace(/"/g, '""')}"`;
|
||||
});
|
||||
csv += values.join(',') + '\n';
|
||||
});
|
||||
|
||||
return csv;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--background: #FFFFFF;
|
||||
--primary: #5C8DFF;
|
||||
--primary-hover: #7DA3FF;
|
||||
--text-primary: #333333;
|
||||
--text-secondary: #666666;
|
||||
--text-disabled: #CCCCCC;
|
||||
--danger: #FF6B6B;
|
||||
--border: #E0E0E0;
|
||||
--header-bg: #F5F5F5;
|
||||
--row-hover: #FAFAFA;
|
||||
--table-border: #E8E8E8;
|
||||
--sidebar-width: 200px;
|
||||
--content-padding: 24px;
|
||||
--secondary: #8E8E93;
|
||||
--secondary-hover: #A7A7AB;
|
||||
--success: #4CAF50;
|
||||
--info: #2196F3;
|
||||
--btn-search: #6c757d;
|
||||
--btn-reset: #17a2b8;
|
||||
--btn-add: #28a745;
|
||||
--btn-export: #17a2b8;
|
||||
--btn-copy: #6c757d;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
|
||||
/* 移除body样式,避免影响其他页面 */
|
||||
|
||||
.package-management {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
background-color: var(--background);
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 左侧导航栏 */
|
||||
.sidebar {
|
||||
width: var(--sidebar-width);
|
||||
background-color: var(--background);
|
||||
border-right: 1px solid var(--border);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar-item {
|
||||
padding: 16px 24px;
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sidebar-item:hover {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
.sidebar-item.active {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 主内容区域 */
|
||||
.content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 查询过滤栏 */
|
||||
.filter-bar {
|
||||
padding: 16px var(--content-padding);
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.filter-item label {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
input, select {
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--border);
|
||||
padding: 0 8px;
|
||||
font-size: 14px;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
input:focus, select:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.btn {
|
||||
padding: 6px 16px;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
height: 36px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
border: none;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
border: 1px solid var(--primary);
|
||||
box-shadow: 0 2px 4px rgba(92, 141, 255, 0.2);
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
background-color: #F5F7FA;
|
||||
color: var(--secondary);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
background-color: var(--btn-search);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-reset {
|
||||
background-color: var(--btn-reset);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-export {
|
||||
background-color: var(--btn-export);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-copy {
|
||||
background-color: var(--btn-copy);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-text:hover {
|
||||
background-color: #EBEEF2;
|
||||
color: var(--text-primary);
|
||||
border-color: var(--secondary-hover);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background-color: var(--danger);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--primary-hover);
|
||||
border-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-left: auto;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* 表格区域 */
|
||||
.table-container {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 0 var(--content-padding) var(--content-padding);
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--table-border);
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: var(--header-bg);
|
||||
font-weight: 500;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background-color: var(--row-hover);
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* 状态标签 */
|
||||
.status-tag {
|
||||
padding: 0 8px;
|
||||
border-radius: 2px;
|
||||
font-size: 12px;
|
||||
height: 20px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.status-yes {
|
||||
background-color: #f6ffed;
|
||||
border: 1px solid #b7eb8f;
|
||||
color: #389e0d;
|
||||
}
|
||||
|
||||
.status-no {
|
||||
background-color: #fff2f0;
|
||||
border: 1px solid #ffccc7;
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
/* 操作图标 */
|
||||
.action-icons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.action-icons .el-button {
|
||||
color: var(--danger);
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action-icons .el-button:hover {
|
||||
background-color: #fff2f0;
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 16px 0;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.page-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--border);
|
||||
background-color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.page-btn.active {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.total-count {
|
||||
margin-left: 16px;
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 1200px) {
|
||||
.sidebar {
|
||||
transform: translateX(calc(-1 * var(--sidebar-width)));
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.active {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
z-index: 101;
|
||||
cursor: pointer;
|
||||
background: white;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
padding-top: 64px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
/* 移除未使用的图标样式 */
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
/* 移除自动生成的未使用样式 */
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -135,6 +135,7 @@
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { getConfigKey, addConfig, updateConfig } from '@/api/system/config';
|
||||
|
||||
const router = useRouter();
|
||||
const formRef = ref(null);
|
||||
@@ -198,46 +199,72 @@ const handleSave = async () => {
|
||||
await formRef.value.validate();
|
||||
}
|
||||
|
||||
// 将表单数据转换为系统配置格式
|
||||
// 将表单数据转换为系统配置格式,并添加必要的默认值
|
||||
const configData = [
|
||||
{ configKey: 'medicalRecordFee', configValue: formData.medicalRecordFee, configName: '病历本费用' },
|
||||
{ configKey: 'patientCardFee', configValue: formData.patientCardFee, configName: '就诊卡费' },
|
||||
{ configKey: 'medicalRecordFlag', configValue: formData.medicalRecordFlag ? '1' : '0', configName: '病历费入账标志' },
|
||||
{ configKey: 'isNightShift', configValue: formData.isNightShift ? '1' : '0', configName: '是否启用晚班' },
|
||||
{ configKey: 'patientCardFlag', configValue: formData.patientCardFlag ? '1' : '0', configName: '就诊卡记账标志' },
|
||||
{ configKey: 'morningStartTime', configValue: formData.morningStartTime, configName: '上午接诊起始时间' },
|
||||
{ configKey: 'autoGenerateOutpatientNo', configValue: formData.autoGenerateOutpatientNo ? '1' : '0', configName: '自动产生门诊号' },
|
||||
{ configKey: 'allowModifyOutpatientNo', configValue: formData.allowModifyOutpatientNo ? '1' : '0', configName: '建档时是否允许修改门诊号' },
|
||||
{ configKey: 'afternoonStartTime', configValue: formData.afternoonStartTime, configName: '下午起始时间' },
|
||||
{ configKey: 'eveningStartTime', configValue: formData.eveningStartTime, configName: '晚上起始时间' },
|
||||
{ configKey: 'registrationValidity', configValue: formData.registrationValidity, configName: '挂号有效期' },
|
||||
{ configKey: 'registrationDocumentMode', configValue: formData.registrationDocumentMode, configName: '挂号单据模式' },
|
||||
{ configKey: 'exemptFlag', configValue: formData.exemptFlag ? '1' : '0', configName: '减免标志' },
|
||||
{ configKey: 'consultationFlag', configValue: formData.consultationFlag ? '1' : '0', configName: '义诊标志' },
|
||||
{ configKey: 'enableHolidayFeeFloat', configValue: formData.enableHolidayFeeFloat ? '1' : '0', configName: '启用法定节假日挂号费浮动' },
|
||||
{ configKey: 'guardianAge', configValue: formData.guardianAge, configName: '监护人规定年龄' },
|
||||
{ configKey: 'enableDoubleScreen', configValue: formData.enableDoubleScreen ? '1' : '0', configName: '门诊挂号启用双屏' },
|
||||
{ configKey: 'optionalRegistrationType', configValue: formData.optionalRegistrationType ? '1' : '0', configName: '挂号类型可选择' },
|
||||
{ configKey: 'isPrint', configValue: formData.isPrint ? '1' : '0', configName: '是否打印挂号单' },
|
||||
{ configKey: 'medicalRecordFee', configValue: formData.medicalRecordFee, configName: '病历本费用', configType: 'Y' },
|
||||
{ configKey: 'patientCardFee', configValue: formData.patientCardFee, configName: '就诊卡费', configType: 'Y' },
|
||||
{ configKey: 'medicalRecordFlag', configValue: formData.medicalRecordFlag ? '1' : '0', configName: '病历费入账标志', configType: 'Y' },
|
||||
{ configKey: 'isNightShift', configValue: formData.isNightShift ? '1' : '0', configName: '是否启用晚班', configType: 'Y' },
|
||||
{ configKey: 'patientCardFlag', configValue: formData.patientCardFlag ? '1' : '0', configName: '就诊卡记账标志', configType: 'Y' },
|
||||
{ configKey: 'morningStartTime', configValue: formData.morningStartTime, configName: '上午接诊起始时间', configType: 'Y' },
|
||||
{ configKey: 'autoGenerateOutpatientNo', configValue: formData.autoGenerateOutpatientNo ? '1' : '0', configName: '自动产生门诊号', configType: 'Y' },
|
||||
{ configKey: 'allowModifyOutpatientNo', configValue: formData.allowModifyOutpatientNo ? '1' : '0', configName: '建档时是否允许修改门诊号', configType: 'Y' },
|
||||
{ configKey: 'afternoonStartTime', configValue: formData.afternoonStartTime, configName: '下午起始时间', configType: 'Y' },
|
||||
{ configKey: 'eveningStartTime', configValue: formData.eveningStartTime, configName: '晚上起始时间', configType: 'Y' },
|
||||
{ configKey: 'registrationValidity', configValue: formData.registrationValidity, configName: '挂号有效期', configType: 'Y' },
|
||||
{ configKey: 'registrationDocumentMode', configValue: formData.registrationDocumentMode, configName: '挂号单据模式', configType: 'Y' },
|
||||
{ configKey: 'exemptFlag', configValue: formData.exemptFlag ? '1' : '0', configName: '减免标志', configType: 'Y' },
|
||||
{ configKey: 'consultationFlag', configValue: formData.consultationFlag ? '1' : '0', configName: '义诊标志', configType: 'Y' },
|
||||
{ configKey: 'enableHolidayFeeFloat', configValue: formData.enableHolidayFeeFloat ? '1' : '0', configName: '启用法定节假日挂号费浮动', configType: 'Y' },
|
||||
{ configKey: 'guardianAge', configValue: formData.guardianAge, configName: '监护人规定年龄', configType: 'Y' },
|
||||
{ configKey: 'enableDoubleScreen', configValue: formData.enableDoubleScreen ? '1' : '0', configName: '门诊挂号启用双屏', configType: 'Y' },
|
||||
{ configKey: 'optionalRegistrationType', configValue: formData.optionalRegistrationType ? '1' : '0', configName: '挂号类型可选择', configType: 'Y' },
|
||||
{ configKey: 'isPrint', configValue: formData.isPrint ? '1' : '0', configName: '是否打印挂号单', configType: 'Y' },
|
||||
];
|
||||
|
||||
let successCount = 0;
|
||||
let failedParams = [];
|
||||
|
||||
// 调用系统配置API保存每个参数
|
||||
for (const config of configData) {
|
||||
try {
|
||||
// 先查询是否存在该配置
|
||||
const existingConfig = await getConfigKey(config.configKey);
|
||||
if (existingConfig.data) {
|
||||
// 如果存在则更新
|
||||
await updateConfig({ ...config, configId: existingConfig.data.configId });
|
||||
const existingConfig = await getConfigKey(config.configKey, { skipErrorMsg: true });
|
||||
|
||||
if (existingConfig.data && existingConfig.data.configId) {
|
||||
// 如果存在则更新,保留原有数据的configId
|
||||
await updateConfig({
|
||||
...config,
|
||||
configId: existingConfig.data.configId,
|
||||
createTime: existingConfig.data.createTime, // 保留创建时间
|
||||
remark: existingConfig.data.remark || '收费系统配置参数' // 保留或设置默认备注
|
||||
});
|
||||
} else {
|
||||
// 如果不存在则新增
|
||||
await addConfig(config);
|
||||
// 如果不存在则新增,添加默认备注
|
||||
await addConfig({
|
||||
...config,
|
||||
remark: '收费系统配置参数'
|
||||
});
|
||||
}
|
||||
successCount++;
|
||||
} catch (paramError) {
|
||||
console.error(`保存参数 ${config.configName} (${config.configKey}) 失败:`, paramError);
|
||||
failedParams.push(config.configName);
|
||||
// 继续处理下一个参数,不中断整体流程
|
||||
}
|
||||
}
|
||||
|
||||
ElMessage.success('保存成功');
|
||||
// 根据保存结果显示相应消息
|
||||
if (failedParams.length === 0) {
|
||||
ElMessage.success(`所有 ${successCount} 个参数保存成功`);
|
||||
} else if (successCount > 0) {
|
||||
ElMessage.warning(`${successCount} 个参数保存成功,但以下 ${failedParams.length} 个参数保存失败: ${failedParams.join(', ')}`);
|
||||
} else {
|
||||
ElMessage.error(`所有参数保存失败,请检查系统配置`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error);
|
||||
ElMessage.error('保存失败,请重试');
|
||||
console.error('保存过程中发生错误:', error);
|
||||
ElMessage.error('保存操作异常,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
v-for="(item, index) in tableData"
|
||||
:key="index"
|
||||
:class="{ 'editing-row': item.editing, 'child-row': item.row.includes('.') }"
|
||||
@click="handleRowClick(item)"
|
||||
@click="handleEdit(index)"
|
||||
>
|
||||
<td>{{ item.row }}</td>
|
||||
<td>
|
||||
@@ -198,15 +198,12 @@
|
||||
<template v-else-if="activeMenu === '检查方法'">
|
||||
<div class="header">
|
||||
<h1>{{ activeMenu }}管理</h1>
|
||||
<div class="header-actions">
|
||||
<button class="btn btn-add-new" @click="handleAddNewRow">+
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-bar">
|
||||
<div class="search-bar search-bar-method">
|
||||
<div class="search-filters">
|
||||
<div class="search-item">
|
||||
<label>检查类型</label>
|
||||
<el-select v-model="searchParams.checkMethod" placeholder="选择检查方类型" style="width: 150px">
|
||||
<el-select v-model="searchParamsMethod.checkType" placeholder="选择检查类型" style="width: 150px">
|
||||
<el-option
|
||||
v-for="type in checkTypes"
|
||||
:key="type"
|
||||
@@ -218,20 +215,21 @@
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<label>名称</label>
|
||||
<el-input placeholder="名称/编码" v-model="searchParams.name" />
|
||||
<el-input placeholder="名称/编码" v-model="searchParamsMethod.name" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<label>费用套餐</label>
|
||||
<el-select v-model="searchParams.packageId" placeholder="选择使用套餐" style="width: 150px">
|
||||
<el-select v-model="searchParamsMethod.packageName" placeholder="选择使用套餐" style="width: 150px">
|
||||
<el-option
|
||||
v-for="pkg in checkPackages"
|
||||
:key="pkg.id"
|
||||
:label="pkg.name"
|
||||
:value="pkg.id"
|
||||
:value="pkg.name"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-actions">
|
||||
<el-button type="primary" :style="{ backgroundColor: hoverAddButton ? '#8a49e0' : '#722ED1', borderColor: hoverAddButton ? '#8a49e0' : '#722ED1' }" @mouseenter="hoverAddButton = true" @mouseleave="hoverAddButton = false" @click="handleAddNewRow">新增</el-button>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
@@ -257,10 +255,10 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(item, index) in tableData"
|
||||
v-for="(item, index) in checkMethodData"
|
||||
:key="index"
|
||||
:class="{ 'editing-row': item.editing }"
|
||||
@click="handleRowClick(item)"
|
||||
@click=""
|
||||
>
|
||||
<td>{{ item.row }}</td>
|
||||
<td>
|
||||
@@ -321,6 +319,9 @@
|
||||
</template>
|
||||
</td>
|
||||
<td class="actions">
|
||||
<button class="btn btn-edit" @click.stop="handleEdit(index)">
|
||||
✏️
|
||||
</button>
|
||||
<button class="btn btn-confirm" @click.stop="handleConfirm(index)">
|
||||
✓
|
||||
</button>
|
||||
@@ -338,15 +339,11 @@
|
||||
<template v-else-if="activeMenu === '检查部位'">
|
||||
<div class="header">
|
||||
<h1>{{ activeMenu }}管理</h1>
|
||||
<div class="header-actions">
|
||||
<button class="btn btn-add-new" @click="handleAddNewRow">+
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-bar">
|
||||
<div class="search-bar search-bar-part">
|
||||
<div class="search-item">
|
||||
<label>检查类型</label>
|
||||
<el-select v-model="searchParams.checkType" placeholder="选择检查类型" style="width: 150px">
|
||||
<el-select v-model="searchParamsPart.checkType" placeholder="选择检查类型" style="width: 150px">
|
||||
<el-option
|
||||
v-for="type in checkTypes"
|
||||
:key="type"
|
||||
@@ -358,11 +355,11 @@
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<label>名称</label>
|
||||
<el-input placeholder="名称/编码" v-model="searchParams.name" />
|
||||
<el-input placeholder="名称/编码" v-model="searchParamsPart.name" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<label>费用套餐</label>
|
||||
<el-input placeholder="费用套餐" v-model="searchParams.packageName" />
|
||||
<el-input placeholder="费用套餐" v-model="searchParamsPart.packageName" />
|
||||
</div>
|
||||
|
||||
<div class="search-actions">
|
||||
@@ -379,12 +376,12 @@
|
||||
<tr>
|
||||
<th style="width: 50px;">行</th>
|
||||
<th style="width: 100px;">*编码</th>
|
||||
<th style="width: 150px;">*名称</th>
|
||||
<th style="width: 100px;">*名称</th>
|
||||
<th style="width: 120px;">检查类型</th>
|
||||
<th style="width: 100px;">曝光次数</th>
|
||||
<th style="width: 80px;">曝光次数</th>
|
||||
<th style="width: 120px;">费用套餐</th>
|
||||
<th style="width: 100px;">金额</th>
|
||||
<th style="width: 80px;">序号</th>
|
||||
<th style="width: 80px;">金额</th>
|
||||
<th style="width: 50px;">序号</th>
|
||||
<th style="width: 120px;">服务范围</th>
|
||||
<th style="width: 120px;">下级医技类型</th>
|
||||
<th style="width: 150px;">备注</th>
|
||||
@@ -393,10 +390,10 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(item, index) in tableData"
|
||||
v-for="(item, index) in checkPartData"
|
||||
:key="index"
|
||||
:class="{ 'editing-row': item.editing }"
|
||||
@click="handleRowClick(item)"
|
||||
@click=""
|
||||
>
|
||||
<td>{{ item.row }}</td>
|
||||
<td>
|
||||
@@ -480,6 +477,9 @@
|
||||
</template>
|
||||
</td>
|
||||
<td class="actions">
|
||||
<button class="btn btn-edit" @click.stop="handleEdit(index)">
|
||||
✏️
|
||||
</button>
|
||||
<button class="btn btn-confirm" @click.stop="handleConfirm(index)">
|
||||
✓
|
||||
</button>
|
||||
@@ -503,10 +503,10 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { getDicts } from '@/api/system/dict/data';
|
||||
import { listCheckType, listCheckMethod, listCheckPart, listCheckPackage, addCheckType, updateCheckType, delCheckType } from '@/api/system/checkType';
|
||||
import { listCheckType, listCheckMethod, listCheckPart, listCheckPackage, searchCheckMethod, searchCheckPart, addCheckType, updateCheckType, delCheckType, addCheckMethod, updateCheckMethod, delCheckMethod, addCheckPart, updateCheckPart, delCheckPart, exportCheckMethod, exportCheckPart } from '@/api/system/checkType';
|
||||
import PackageSettings from './components/PackageSettings.vue';
|
||||
import PackageManagement from './components/PackageManagement.vue';
|
||||
|
||||
@@ -528,19 +528,55 @@ const checkParts = ref([]);
|
||||
const checkPackages = ref([]);
|
||||
const departments = ref([]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = reactive([]);
|
||||
// 表格数据 - 为每个菜单创建独立的数据存储
|
||||
const checkTypeData = reactive([]);
|
||||
const checkMethodData = reactive([]);
|
||||
const checkPartData = reactive([]);
|
||||
const packageData = reactive([]);
|
||||
|
||||
// 搜索条件
|
||||
const searchParams = reactive({
|
||||
checkMethod: '',
|
||||
name: '',
|
||||
packageId: '',
|
||||
packageName: '',
|
||||
// 当前显示的表格数据
|
||||
const tableData = computed(() => {
|
||||
switch(activeMenu.value) {
|
||||
case '检查类型':
|
||||
return checkTypeData;
|
||||
case '检查方法':
|
||||
return checkMethodData;
|
||||
case '检查部位':
|
||||
return checkPartData;
|
||||
case '套餐设置':
|
||||
return packageData;
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
// 搜索条件 - 为每个菜单创建独立的搜索参数
|
||||
const searchParamsType = reactive({});
|
||||
const searchParamsMethod = reactive({
|
||||
checkType: '',
|
||||
checkPartCode: '',
|
||||
checkPartName: '',
|
||||
visible: ''
|
||||
name: '',
|
||||
packageName: ''
|
||||
});
|
||||
const searchParamsPart = reactive({
|
||||
checkType: '',
|
||||
name: '',
|
||||
packageName: ''
|
||||
});
|
||||
|
||||
// 获取当前菜单对应的搜索参数
|
||||
const currentSearchParams = computed(() => {
|
||||
switch(activeMenu.value) {
|
||||
case '检查类型':
|
||||
return searchParamsType;
|
||||
case '检查方法':
|
||||
return searchParamsMethod;
|
||||
case '检查部位':
|
||||
return searchParamsPart;
|
||||
case '套餐设置':
|
||||
return searchParamsMethod; // 套餐设置可能共享检查方法的搜索参数
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
});
|
||||
|
||||
// 按钮悬停状态
|
||||
@@ -564,10 +600,10 @@ onMounted(async () => {
|
||||
// 获取所有不重复的检查类型值
|
||||
checkTypes.value = [...new Set(types.map(item => item.type))];
|
||||
|
||||
// 构建表格数据
|
||||
tableData.splice(0, tableData.length);
|
||||
// 构建检查类型表格数据
|
||||
checkTypeData.splice(0, checkTypeData.length);
|
||||
types.forEach((item, index) => {
|
||||
tableData.push({
|
||||
checkTypeData.push({
|
||||
id: item.id, // 保存id字段,用于判断是新增还是修改
|
||||
row: (index + 1).toString(),
|
||||
code: item.code,
|
||||
@@ -585,19 +621,28 @@ onMounted(async () => {
|
||||
// 获取检查方法数据
|
||||
const methodResponse = await listCheckMethod();
|
||||
if (methodResponse && methodResponse.data) {
|
||||
checkMethods.value = methodResponse.data;
|
||||
// 确保data是数组类型
|
||||
checkMethods.value = Array.isArray(methodResponse.data) ? methodResponse.data : [];
|
||||
} else {
|
||||
checkMethods.value = [];
|
||||
}
|
||||
|
||||
// 获取检查部位数据
|
||||
const partResponse = await listCheckPart();
|
||||
if (partResponse && partResponse.data) {
|
||||
checkParts.value = partResponse.data;
|
||||
// 确保data是数组类型
|
||||
checkParts.value = Array.isArray(partResponse.data) ? partResponse.data : [];
|
||||
} else {
|
||||
checkParts.value = [];
|
||||
}
|
||||
|
||||
// 获取检查套餐数据
|
||||
const packageResponse = await listCheckPackage();
|
||||
if (packageResponse && packageResponse.data) {
|
||||
checkPackages.value = packageResponse.data;
|
||||
// 确保data是数组类型
|
||||
checkPackages.value = Array.isArray(packageResponse.data) ? packageResponse.data : [];
|
||||
} else {
|
||||
checkPackages.value = [];
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
@@ -660,18 +705,22 @@ function handleSaveSuccess() {
|
||||
// 根据菜单加载对应数据
|
||||
async function loadMenuData(menu) {
|
||||
try {
|
||||
tableData.splice(0, tableData.length);
|
||||
|
||||
switch(menu) {
|
||||
case '检查类型':
|
||||
// 清空检查类型数据
|
||||
checkTypeData.splice(0, checkTypeData.length);
|
||||
|
||||
const typeResponse = await listCheckType();
|
||||
if (typeResponse && typeResponse.data) {
|
||||
// 获取所有不重复的检查类型值
|
||||
checkTypes.value = [...new Set(typeResponse.data.map(item => item.type))];
|
||||
// 确保data是数组类型
|
||||
const typeData = Array.isArray(typeResponse.data) ? typeResponse.data : [];
|
||||
|
||||
typeResponse.data.forEach((item, index) => {
|
||||
// 获取所有不重复的检查类型值
|
||||
checkTypes.value = [...new Set(typeData.map(item => item.type))];
|
||||
|
||||
typeData.forEach((item, index) => {
|
||||
// 直接使用数据库中的department值,不进行转换
|
||||
tableData.push({
|
||||
checkTypeData.push({
|
||||
id: item.id, // 保存id字段,用于判断是新增还是修改
|
||||
row: (index + 1).toString(),
|
||||
code: item.code,
|
||||
@@ -688,10 +737,38 @@ async function loadMenuData(menu) {
|
||||
break;
|
||||
|
||||
case '检查方法':
|
||||
const methodResponse = await listCheckMethod();
|
||||
if (methodResponse && methodResponse.data) {
|
||||
methodResponse.data.forEach((item, index) => {
|
||||
tableData.push({
|
||||
// 清空检查方法数据
|
||||
checkMethodData.splice(0, checkMethodData.length);
|
||||
|
||||
// 构建检查方法的搜索参数
|
||||
const methodParams = {
|
||||
pageNo: 1,
|
||||
pageSize: 100, // 默认获取100条数据,可以根据需要调整
|
||||
checkType: searchParamsMethod.checkType,
|
||||
name: searchParamsMethod.name,
|
||||
packageName: searchParamsMethod.packageName
|
||||
};
|
||||
try {
|
||||
const methodResponse = await searchCheckMethod(methodParams);
|
||||
|
||||
// 确保data是数组,适配不同的后端返回格式
|
||||
let methodData = [];
|
||||
if (methodResponse) {
|
||||
if (Array.isArray(methodResponse)) {
|
||||
methodData = methodResponse;
|
||||
} else if (methodResponse.data && Array.isArray(methodResponse.data)) {
|
||||
methodData = methodResponse.data;
|
||||
} else if (methodResponse.data && methodResponse.data.data && Array.isArray(methodResponse.data.data)) {
|
||||
methodData = methodResponse.data.data;
|
||||
} else if (methodResponse.data && methodResponse.data.records) {
|
||||
methodData = methodResponse.data.records;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组数据
|
||||
if (methodData.length > 0) {
|
||||
methodData.forEach((item, index) => {
|
||||
checkMethodData.push({
|
||||
id: item.id, // 保存id字段,用于判断是新增还是修改
|
||||
row: (index + 1).toString(),
|
||||
code: item.code,
|
||||
@@ -704,22 +781,47 @@ async function loadMenuData(menu) {
|
||||
actions: true
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ElMessage.warning('未获取到检查方法数据');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(`加载检查方法数据失败: ${error.message || '未知错误'}`);
|
||||
}
|
||||
break;
|
||||
|
||||
case '检查部位':
|
||||
// 清空检查部位数据
|
||||
checkPartData.splice(0, checkPartData.length);
|
||||
|
||||
// 构建检查部位的搜索参数
|
||||
const partSearchParams = {
|
||||
code: searchParams.checkPartCode,
|
||||
name: searchParams.name,
|
||||
checkType: searchParams.checkType,
|
||||
packageName: searchParams.packageName,
|
||||
visible: searchParams.visible
|
||||
const partParams = {
|
||||
pageNo: 1,
|
||||
pageSize: 100, // 默认获取100条数据,可以根据需要调整
|
||||
checkType: searchParamsPart.checkType,
|
||||
name: searchParamsPart.name,
|
||||
packageName: searchParamsPart.packageName
|
||||
};
|
||||
const partResponse = await listCheckPart(partSearchParams);
|
||||
if (partResponse && partResponse.data) {
|
||||
partResponse.data.forEach((item, index) => {
|
||||
tableData.push({
|
||||
try {
|
||||
const partResponse = await searchCheckPart(partParams);
|
||||
|
||||
// 确保data是数组,适配不同的后端返回格式
|
||||
let partData = [];
|
||||
if (partResponse) {
|
||||
if (Array.isArray(partResponse)) {
|
||||
partData = partResponse;
|
||||
} else if (partResponse.data && Array.isArray(partResponse.data)) {
|
||||
partData = partResponse.data;
|
||||
} else if (partResponse.data && partResponse.data.data && Array.isArray(partResponse.data.data)) {
|
||||
partData = partResponse.data.data;
|
||||
} else if (partResponse.data && partResponse.data.records) {
|
||||
partData = partResponse.data.records;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组数据
|
||||
if (partData.length > 0) {
|
||||
partData.forEach((item, index) => {
|
||||
checkPartData.push({
|
||||
id: item.id, // 保存id字段,用于判断是新增还是修改
|
||||
row: (index + 1).toString(),
|
||||
code: item.code,
|
||||
@@ -735,6 +837,11 @@ async function loadMenuData(menu) {
|
||||
actions: true
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ElMessage.warning('未获取到检查部位数据');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(`加载检查部位数据失败: ${error.message || '未知错误'}`);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -750,54 +857,159 @@ async function loadMenuData(menu) {
|
||||
}
|
||||
}
|
||||
|
||||
// 处理行点击,进入编辑状态
|
||||
function handleRowClick(item) {
|
||||
if (!item.editing) {
|
||||
// 处理编辑按钮点击
|
||||
function handleEdit(index) {
|
||||
const item = tableData[index];
|
||||
item.editing = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理确认按钮点击
|
||||
async function handleConfirm(index) {
|
||||
const item = tableData[index];
|
||||
try {
|
||||
// 根据是否有id判断是新增还是修改
|
||||
// 根据当前激活的菜单调用不同的API
|
||||
if (activeMenu.value === '检查方法') {
|
||||
// 检查方法的保存逻辑
|
||||
if (item.id) {
|
||||
// 修改操作
|
||||
await updateCheckType(item);
|
||||
// 修改操作:只传递必要字段
|
||||
const updateData = {
|
||||
id: item.id,
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
checkType: item.checkType,
|
||||
packageName: item.packageName,
|
||||
exposureNum: item.exposureNum,
|
||||
orderNum: item.orderNum,
|
||||
remark: item.remark
|
||||
};
|
||||
await updateCheckMethod(updateData);
|
||||
} else {
|
||||
// 新增操作
|
||||
const newItem = await addCheckType(item);
|
||||
// 新增操作:只传递必要字段
|
||||
const addData = {
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
checkType: item.checkType,
|
||||
packageName: item.packageName,
|
||||
exposureNum: item.exposureNum,
|
||||
orderNum: item.orderNum,
|
||||
remark: item.remark
|
||||
};
|
||||
console.log('准备新增检查方法:', addData);
|
||||
const newItem = await addCheckMethod(addData);
|
||||
console.log('新增检查方法返回结果:', newItem);
|
||||
// 将新增的id赋值给本地数据
|
||||
item.id = newItem.id;
|
||||
}
|
||||
} else if (activeMenu.value === '检查部位') {
|
||||
// 检查部位的保存逻辑
|
||||
if (item.id) {
|
||||
// 修改操作:只传递必要字段
|
||||
const updateData = {
|
||||
id: item.id,
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
checkType: item.checkType,
|
||||
exposureNum: item.exposureNum,
|
||||
packageName: item.packageName,
|
||||
price: item.price,
|
||||
number: item.number,
|
||||
serviceScope: item.serviceScope,
|
||||
subType: item.subType,
|
||||
remark: item.remark
|
||||
};
|
||||
await updateCheckPart(updateData);
|
||||
} else {
|
||||
// 新增操作:只传递必要字段
|
||||
const addData = {
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
checkType: item.checkType,
|
||||
exposureNum: item.exposureNum,
|
||||
packageName: item.packageName,
|
||||
price: item.price,
|
||||
number: item.number,
|
||||
serviceScope: item.serviceScope,
|
||||
subType: item.subType,
|
||||
remark: item.remark
|
||||
};
|
||||
console.log('准备新增检查部位:', addData);
|
||||
const newItem = await addCheckPart(addData);
|
||||
console.log('新增检查部位返回结果:', newItem);
|
||||
// 将新增的id赋值给本地数据
|
||||
item.id = newItem.id;
|
||||
}
|
||||
} else {
|
||||
// 检查类型的保存逻辑
|
||||
if (item.id) {
|
||||
// 修改操作:只传递必要字段
|
||||
const updateData = {
|
||||
id: item.id,
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
type: item.type,
|
||||
selected: item.selected,
|
||||
department: item.department,
|
||||
number: item.number,
|
||||
remark: item.remark
|
||||
};
|
||||
await updateCheckType(updateData);
|
||||
} else {
|
||||
// 新增操作:只传递必要字段
|
||||
const addData = {
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
type: item.type,
|
||||
selected: item.selected,
|
||||
department: item.department,
|
||||
number: item.number,
|
||||
remark: item.remark
|
||||
};
|
||||
console.log('准备新增检查类型:', addData);
|
||||
const newItem = await addCheckType(addData);
|
||||
console.log('新增检查类型返回结果:', newItem);
|
||||
// 将新增的id赋值给本地数据
|
||||
item.id = newItem.id;
|
||||
}
|
||||
}
|
||||
// 退出编辑状态
|
||||
tableData[index].editing = false;
|
||||
// 显示保存成功提示
|
||||
alert(`第 ${item.row} 行数据已保存`);
|
||||
ElMessage.success(`第 ${item.row} 行数据已保存`);
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error);
|
||||
alert('保存失败,请稍后重试');
|
||||
console.error('保存失败,错误信息:', error);
|
||||
console.error('保存失败,错误详情:', error.response ? error.response.data : error);
|
||||
ElMessage.error('保存失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
|
||||
// 处理删除按钮点击
|
||||
async function handleDelete(index) {
|
||||
if (confirm('确定要删除这一行吗?')) {
|
||||
ElMessageBox.confirm('确定要删除这一行吗?', '系统提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
const item = tableData[index];
|
||||
try {
|
||||
// 如果有id,调用API删除数据库中的数据
|
||||
if (item.id) {
|
||||
if (activeMenu.value === '检查方法') {
|
||||
await delCheckMethod(item.id);
|
||||
} else if (activeMenu.value === '检查部位') {
|
||||
await delCheckPart(item.id);
|
||||
} else {
|
||||
await delCheckType(item.id);
|
||||
}
|
||||
}
|
||||
// 从数组中删除该行数据
|
||||
tableData.splice(index, 1);
|
||||
alert('删除成功!');
|
||||
ElMessage.success('删除成功!');
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error);
|
||||
alert('删除失败,请稍后重试');
|
||||
}
|
||||
ElMessage.error('删除失败,请稍后重试');
|
||||
}
|
||||
}).catch(() => {
|
||||
// 用户取消删除操作
|
||||
});
|
||||
}
|
||||
|
||||
// 处理添加新行按钮点击
|
||||
@@ -834,10 +1046,10 @@ function handleAddNewRow() {
|
||||
row: String(maxRowNum + 1),
|
||||
code: '',
|
||||
name: '',
|
||||
type: '',
|
||||
department: '',
|
||||
amount: '0.00',
|
||||
number: '999999',
|
||||
checkType: '',
|
||||
packageName: '',
|
||||
exposureNum: 0,
|
||||
orderNum: 0,
|
||||
remark: '',
|
||||
editing: true, // 新行默认进入编辑状态
|
||||
isNew: true, // 标记为新增行
|
||||
@@ -903,29 +1115,153 @@ function handleAdd(index) {
|
||||
}
|
||||
|
||||
// 处理搜索功能
|
||||
function handleSearch() {
|
||||
console.log('搜索条件:', searchParams);
|
||||
// 这里可以根据activeMenu和searchParams实现不同的搜索逻辑
|
||||
ElMessage.info(`正在搜索${activeMenu.value}数据...`);
|
||||
async function handleSearch() {
|
||||
try {
|
||||
console.log('搜索条件:', currentSearchParams.value);
|
||||
// ElMessage.info(`正在搜索${activeMenu.value}数据...`);
|
||||
|
||||
// 模拟搜索延迟
|
||||
setTimeout(() => {
|
||||
// 根据activeMenu执行相应的搜索逻辑
|
||||
loadMenuData(activeMenu.value);
|
||||
}, 300);
|
||||
switch(activeMenu.value) {
|
||||
case '检查方法':
|
||||
// 清空检查方法数据
|
||||
checkMethodData.splice(0, checkMethodData.length);
|
||||
|
||||
// 构建检查方法的搜索参数
|
||||
const methodParams = {
|
||||
pageNo: 1,
|
||||
pageSize: 100, // 默认获取100条数据,可以根据需要调整
|
||||
checkType: searchParamsMethod.checkType,
|
||||
name: searchParamsMethod.name,
|
||||
packageName: searchParamsMethod.packageName
|
||||
};
|
||||
|
||||
const methodResponse = await searchCheckMethod(methodParams);
|
||||
|
||||
// 确保data是数组,适配不同的后端返回格式
|
||||
let methodData = [];
|
||||
if (methodResponse) {
|
||||
if (Array.isArray(methodResponse)) {
|
||||
methodData = methodResponse;
|
||||
} else if (methodResponse.data && Array.isArray(methodResponse.data)) {
|
||||
methodData = methodResponse.data;
|
||||
} else if (methodResponse.data && methodResponse.data.data && Array.isArray(methodResponse.data.data)) {
|
||||
methodData = methodResponse.data.data;
|
||||
} else if (methodResponse.data && methodResponse.data.records) {
|
||||
methodData = methodResponse.data.records;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组数据
|
||||
if (methodData.length > 0) {
|
||||
methodData.forEach((item, index) => {
|
||||
checkMethodData.push({
|
||||
id: item.id, // 保存id字段,用于判断是新增还是修改
|
||||
row: (index + 1).toString(),
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
checkType: item.checkType || '',
|
||||
packageName: item.packageName || '',
|
||||
exposureNum: item.exposureNum || 0,
|
||||
orderNum: item.orderNum || 0,
|
||||
remark: item.remark || '',
|
||||
actions: true
|
||||
});
|
||||
});
|
||||
ElMessage.success(`搜索到${methodData.length}条检查方法数据`);
|
||||
} else {
|
||||
ElMessage.warning('未搜索到检查方法数据');
|
||||
}
|
||||
break;
|
||||
|
||||
case '检查部位':
|
||||
// 清空检查部位数据
|
||||
checkPartData.splice(0, checkPartData.length);
|
||||
|
||||
// 构建检查部位的搜索参数
|
||||
const partParams = {
|
||||
pageNo: 1,
|
||||
pageSize: 100, // 默认获取100条数据,可以根据需要调整
|
||||
checkType: searchParamsPart.checkType,
|
||||
name: searchParamsPart.name,
|
||||
packageName: searchParamsPart.packageName
|
||||
};
|
||||
|
||||
const partResponse = await searchCheckPart(partParams);
|
||||
|
||||
// 确保data是数组,适配不同的后端返回格式
|
||||
let partData = [];
|
||||
if (partResponse) {
|
||||
if (Array.isArray(partResponse)) {
|
||||
partData = partResponse;
|
||||
} else if (partResponse.data && Array.isArray(partResponse.data)) {
|
||||
partData = partResponse.data;
|
||||
} else if (partResponse.data && partResponse.data.data && Array.isArray(partResponse.data.data)) {
|
||||
partData = partResponse.data.data;
|
||||
} else if (partResponse.data && partResponse.data.records) {
|
||||
partData = partResponse.data.records;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组数据
|
||||
if (partData.length > 0) {
|
||||
partData.forEach((item, index) => {
|
||||
checkPartData.push({
|
||||
id: item.id, // 保存id字段,用于判断是新增还是修改
|
||||
row: (index + 1).toString(),
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
checkType: item.checkType || '',
|
||||
exposureNum: item.exposureNum || 0,
|
||||
packageName: item.packageName || '',
|
||||
price: item.price || 0,
|
||||
number: item.number || '999999',
|
||||
serviceScope: item.serviceScope || '',
|
||||
subType: item.subType || '',
|
||||
remark: item.remark || '',
|
||||
actions: true
|
||||
});
|
||||
});
|
||||
ElMessage.success(`搜索到${partData.length}条检查部位数据`);
|
||||
} else {
|
||||
ElMessage.warning('未搜索到检查部位数据');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// 其他菜单使用原有的加载逻辑
|
||||
await loadMenuData(activeMenu.value);
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索失败:', error);
|
||||
ElMessage.error(`搜索${activeMenu.value}数据失败: ${error.message || '未知错误'}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理重置功能
|
||||
function handleReset() {
|
||||
// 重置所有搜索条件
|
||||
searchParams.checkMethod = '';
|
||||
searchParams.name = '';
|
||||
searchParams.packageId = '';
|
||||
searchParams.packageName = '';
|
||||
searchParams.checkType = '';
|
||||
searchParams.checkPartCode = '';
|
||||
searchParams.checkPartName = '';
|
||||
searchParams.visible = '';
|
||||
// 根据当前活动菜单重置对应的搜索条件
|
||||
switch(activeMenu.value) {
|
||||
case '检查类型':
|
||||
for (const key in searchParamsType) {
|
||||
searchParamsType[key] = '';
|
||||
}
|
||||
break;
|
||||
|
||||
case '检查方法':
|
||||
searchParamsMethod.checkType = '';
|
||||
searchParamsMethod.name = '';
|
||||
searchParamsMethod.packageName = '';
|
||||
break;
|
||||
|
||||
case '检查部位':
|
||||
searchParamsPart.checkType = '';
|
||||
searchParamsPart.name = '';
|
||||
searchParamsPart.packageName = '';
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ElMessage.info('搜索条件已重置');
|
||||
}
|
||||
@@ -933,10 +1269,51 @@ function handleReset() {
|
||||
// 处理导出表格功能
|
||||
function handleExport() {
|
||||
console.log('导出表格:', activeMenu.value);
|
||||
ElMessage.success(`正在导出${activeMenu.value}数据,请稍候...`);
|
||||
|
||||
// 这里可以实现实际的导出逻辑
|
||||
// 例如调用API或使用前端库生成Excel文件
|
||||
if (activeMenu.value === '检查方法') {
|
||||
// 调用检查方法导出API
|
||||
exportCheckMethod(searchParamsMethod).then(blobData => {
|
||||
// 直接使用blobData创建下载链接,因为response拦截器已经返回了res.data
|
||||
const blob = new Blob([blobData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
// 设置文件名
|
||||
link.setAttribute('download', `检查方法数据_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
// 清理
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
ElMessage.success('检查方法数据导出成功');
|
||||
}).catch(error => {
|
||||
console.error('导出检查方法数据失败:', error);
|
||||
ElMessage.error('导出检查方法数据失败');
|
||||
});
|
||||
} else if (activeMenu.value === '检查部位') {
|
||||
// 调用检查部位导出API
|
||||
exportCheckPart(searchParamsPart).then(blobData => {
|
||||
// 直接使用blobData创建下载链接,因为response拦截器已经返回了res.data
|
||||
const blob = new Blob([blobData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
// 设置文件名
|
||||
link.setAttribute('download', `检查部位数据_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
// 清理
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
ElMessage.success('检查部位数据导出成功');
|
||||
}).catch(error => {
|
||||
console.error('导出检查部位数据失败:', error);
|
||||
ElMessage.error('导出检查部位数据失败');
|
||||
});
|
||||
} else {
|
||||
// 其他菜单的导出逻辑可以在这里扩展
|
||||
ElMessage.warning('该功能尚未实现');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1039,6 +1416,26 @@ select {
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* 检查方法搜索栏特定样式 */
|
||||
.search-bar-method {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.search-bar-method .search-filters {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-bar-method .search-actions {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.search-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1148,7 +1545,7 @@ th {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #D9D9D9;
|
||||
}
|
||||
|
||||
@@ -1159,13 +1556,16 @@ td {
|
||||
font-weight: 400;
|
||||
line-height: 24px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@@ -1180,6 +1580,18 @@ td {
|
||||
transition: all 0.2s ease;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
background-color: #66b1ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-delete {
|
||||
background-color: #FF4D4F;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
z-index: 20;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.btn-confirm {
|
||||
@@ -1187,6 +1599,12 @@ td {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-edit {
|
||||
background-color: #FFC107;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-add {
|
||||
background-color: #1890FF;
|
||||
color: white;
|
||||
|
||||
999
openhis-ui-vue3/src/views/maintainSystem/lisGroup/index.vue
Normal file
999
openhis-ui-vue3/src/views/maintainSystem/lisGroup/index.vue
Normal file
@@ -0,0 +1,999 @@
|
||||
<template>
|
||||
<div class="lis-group-maintain">
|
||||
|
||||
<!-- 标题区域 -->
|
||||
<div class="header">
|
||||
<h2>LIS分组维护</h2>
|
||||
</div>
|
||||
|
||||
<!-- 表格展示区域 -->
|
||||
<div class="table-container">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50px;">行</th>
|
||||
<th style="width: 150px;">卫生机构</th>
|
||||
<th style="width: 150px;">日期</th>
|
||||
<th style="width: 200px;">LIS分组名称</th>
|
||||
<th style="width: 120px;">采血管</th>
|
||||
<th style="width: 300px;">备注</th>
|
||||
<th style="width: 150px;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.id || index"
|
||||
:class="{ 'editing-row': item.editing }"
|
||||
>
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>
|
||||
<template v-if="item.editing">
|
||||
<input
|
||||
type="text"
|
||||
v-model="item.healthInstitution"
|
||||
placeholder="请输入卫生机构"
|
||||
:class="{ 'error-input': item.errors?.healthInstitution }"
|
||||
>
|
||||
<span v-if="item.errors?.healthInstitution" class="error-message">{{ item.errors.healthInstitution }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ item.healthInstitution }}
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
<template v-if="item.editing">
|
||||
<input type="text" v-model="item.date" disabled>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ item.date }}
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
<template v-if="item.editing">
|
||||
<input
|
||||
type="text"
|
||||
v-model="item.lisGroupName"
|
||||
placeholder="请输入分组名称"
|
||||
:class="{ 'error-input': item.errors?.lisGroupName }"
|
||||
>
|
||||
<span v-if="item.errors?.lisGroupName" class="error-message">{{ item.errors.lisGroupName }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ item.lisGroupName }}
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
<template v-if="item.editing">
|
||||
<select
|
||||
v-model="item.bloodCollectionTube"
|
||||
:class="{ 'error-input': item.errors?.bloodCollectionTube }"
|
||||
>
|
||||
<option value="">请选择采血管</option>
|
||||
<option v-for="tube in bloodTubeOptions" :key="tube" :value="tube">
|
||||
{{ tube }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="item.errors?.bloodCollectionTube" class="error-message">{{ item.errors.bloodCollectionTube }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ item.bloodCollectionTube }}
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
<template v-if="item.editing">
|
||||
<input type="text" v-model="item.remark" placeholder="请输入备注信息">
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ item.remark || '' }}
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
<div class="actions">
|
||||
<template v-if="!item.editing">
|
||||
<button class="btn btn-edit" @click="startEdit(item)">✏️</button>
|
||||
<button class="btn btn-primary" @click="addRow">+</button>
|
||||
<button class="btn btn-delete" @click="deleteRow(index)">🗑</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button class="btn btn-confirm" @click="confirmEdit(item)">√</button>
|
||||
<button class="btn btn-cancel" @click="cancelEdit(item)">×</button>
|
||||
</template>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 分页区域 -->
|
||||
<div class="pagination">
|
||||
<button class="pagination-btn">‹</button>
|
||||
<span>1</span>
|
||||
<button class="pagination-btn">›</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { listLisGroup, addLisGroup, updateLisGroup, delLisGroup } from '@/api/system/checkType'
|
||||
import { getDicts } from "@/api/system/dict/data";
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'LisGroupMaintain',
|
||||
setup() {
|
||||
// 加载状态
|
||||
const loading = ref(false)
|
||||
|
||||
// 采血管选项
|
||||
const bloodTubeOptions = ref([]);
|
||||
|
||||
// 加载采血管颜色字典数据
|
||||
const loadBloodTubeDict = async () => {
|
||||
try {
|
||||
const response = await getDicts('test_the_color_of_the_blood_collection_tube');
|
||||
if (response.code === 200 && response.data) {
|
||||
// 根据实际返回数据格式调整
|
||||
bloodTubeOptions.value = response.data.map(item => item.label || item.dictLabel);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取采血管颜色字典失败:', error);
|
||||
// 如果字典获取失败,使用默认选项作为备选
|
||||
bloodTubeOptions.value = ['黄管', '紫管', '蓝管'];
|
||||
}
|
||||
};
|
||||
|
||||
// 分页相关数据
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const totalItems = ref(2) // 总数据量,实际应用中应该从后端获取
|
||||
|
||||
// 总页数
|
||||
const totalPages = computed(() => {
|
||||
return Math.ceil(totalItems.value / pageSize.value)
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = reactive([])
|
||||
|
||||
// 获取当前日期
|
||||
const getCurrentDate = () => {
|
||||
const date = new Date()
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
// 加载LIS分组数据
|
||||
const loadLisGroups = async () => {
|
||||
// 确保采血管字典数据已加载
|
||||
if (bloodTubeOptions.value.length === 0) {
|
||||
await loadBloodTubeDict();
|
||||
}
|
||||
try {
|
||||
loading.value = true
|
||||
|
||||
// 构建查询参数
|
||||
const query = {
|
||||
pageNum: currentPage.value,
|
||||
pageSize: pageSize.value
|
||||
}
|
||||
|
||||
console.log('准备调用接口,查询参数:', query)
|
||||
|
||||
// 调用接口获取数据
|
||||
// 注意:根据checkType.js中的定义,这个接口使用GET方法和params参数
|
||||
const response = await listLisGroup(query)
|
||||
|
||||
console.log('接口返回结果类型:', typeof response)
|
||||
console.log('接口返回结果:', response)
|
||||
console.log('响应是否包含code字段:', response && 'code' in response)
|
||||
console.log('响应是否包含data字段:', response && 'data' in response)
|
||||
|
||||
// 清空现有数据
|
||||
tableData.splice(0, tableData.length)
|
||||
totalItems.value = 0
|
||||
|
||||
// 适配可能的不同响应格式
|
||||
let items = []
|
||||
let total = 0
|
||||
|
||||
// 检查响应是否存在
|
||||
if (response) {
|
||||
// 处理标准响应格式
|
||||
if (typeof response === 'object') {
|
||||
// 检查是否是标准API响应格式 {code, data, msg}
|
||||
if ('code' in response) {
|
||||
console.log('响应包含code字段:', response.code)
|
||||
|
||||
// 成功状态码处理
|
||||
if (response.code === 200 || response.code === '200' || response.code === 0) {
|
||||
console.log('响应状态码为成功状态')
|
||||
|
||||
// 检查data字段
|
||||
if ('data' in response) {
|
||||
console.log('响应包含data字段,数据类型:', typeof response.data)
|
||||
|
||||
// 格式1: {data: {rows: [], total: number}}
|
||||
if (response.data && typeof response.data === 'object') {
|
||||
// 处理双重嵌套格式 {data: {code, msg, data: []}}
|
||||
if (response.data.data && (Array.isArray(response.data.data) || typeof response.data.data === 'object')) {
|
||||
console.log('匹配到格式: 双重嵌套 data.data');
|
||||
|
||||
// 如果data.data是数组,直接使用
|
||||
if (Array.isArray(response.data.data)) {
|
||||
items = response.data.data;
|
||||
total = items.length;
|
||||
console.log('双重嵌套格式1: data.data是数组,数据量:', items.length);
|
||||
}
|
||||
// 如果data.data是对象,检查是否有rows字段
|
||||
else if (Array.isArray(response.data.data.rows)) {
|
||||
items = response.data.data.rows;
|
||||
total = response.data.data.total !== undefined ? response.data.data.total : items.length;
|
||||
console.log('双重嵌套格式2: data.data包含rows,数据量:', items.length, ',总数:', total);
|
||||
}
|
||||
}
|
||||
// 标准格式检查
|
||||
else if (Array.isArray(response.data.rows)) {
|
||||
items = response.data.rows
|
||||
total = response.data.total !== undefined ? response.data.total : items.length
|
||||
console.log('匹配到格式1: response.data.rows,数据量:', items.length, ',总数:', total)
|
||||
}
|
||||
// 格式2: {data: []}
|
||||
else if (Array.isArray(response.data)) {
|
||||
items = response.data
|
||||
total = items.length
|
||||
console.log('匹配到格式2: response.data直接是数组,数据量:', items.length)
|
||||
}
|
||||
// 检查是否有其他可能的格式
|
||||
else {
|
||||
console.log('响应data不是预期格式,详细数据:', response.data)
|
||||
// 尝试将整个data对象作为单个条目处理(有些API可能直接返回单个对象)
|
||||
if (response.data) {
|
||||
items = [response.data]
|
||||
total = 1
|
||||
console.log('尝试将整个data对象作为单个条目处理')
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('响应不包含data字段')
|
||||
}
|
||||
} else {
|
||||
// 非成功状态码
|
||||
const errorMsg = response.msg || response.message || `请求失败,状态码: ${response.code}`
|
||||
console.error('请求失败:', errorMsg)
|
||||
showMessage(errorMsg, 'error')
|
||||
}
|
||||
}
|
||||
// 格式3: 响应本身是一个对象但没有code字段,可能是单个记录
|
||||
else if (!Array.isArray(response)) {
|
||||
console.log('响应是对象但没有code字段,尝试作为单个记录处理')
|
||||
items = [response]
|
||||
total = 1
|
||||
}
|
||||
}
|
||||
|
||||
// 格式4: 响应本身是数组
|
||||
if (Array.isArray(response)) {
|
||||
items = response
|
||||
total = items.length
|
||||
console.log('匹配到格式4: 响应本身是数组,数据量:', items.length)
|
||||
}
|
||||
|
||||
// 记录最终解析到的数据量
|
||||
console.log('最终解析到的数据量:', items.length, ',总数:', total)
|
||||
} else {
|
||||
console.error('接口返回空数据')
|
||||
showMessage('获取LIS分组数据失败:服务器返回空响应', 'error')
|
||||
}
|
||||
|
||||
// 处理获取到的数据
|
||||
if (items && items.length > 0) {
|
||||
// 处理每条数据,确保字段正确映射
|
||||
items.forEach((item, index) => {
|
||||
// 确保item是对象类型
|
||||
if (typeof item === 'object' && item !== null) {
|
||||
console.log(`处理记录 ${index + 1} 原始数据:`, item);
|
||||
|
||||
// 创建格式化后的对象,确保字段存在
|
||||
// 根据网络响应截图更正字段映射关系
|
||||
const formattedItem = {
|
||||
id: item.id || `temp_${Date.now()}_${index}`, // 确保有ID
|
||||
// 更正字段映射:hospital -> healthInstitution
|
||||
healthInstitution: item.hospital || item.org || item.healthInstitution || '',
|
||||
// 优先使用date字段
|
||||
date: item.date || item.createTime || item.createDate || '',
|
||||
// 更正字段映射:groupName -> lisGroupName
|
||||
lisGroupName: item.groupName || item.name || item.lisGroupName || '',
|
||||
// 更正字段映射:tube -> bloodCollectionTube
|
||||
bloodCollectionTube: item.tube || item.property || item.bloodCollectionTube || item.bloodTube || '',
|
||||
remark: item.remark || item.note || '',
|
||||
editing: false,
|
||||
// 保留原始对象的所有其他属性
|
||||
...item
|
||||
};
|
||||
|
||||
tableData.push(formattedItem);
|
||||
console.log(`处理记录 ${index + 1} 格式化后数据:`, {
|
||||
id: formattedItem.id,
|
||||
healthInstitution: formattedItem.healthInstitution,
|
||||
date: formattedItem.date,
|
||||
lisGroupName: formattedItem.lisGroupName,
|
||||
bloodCollectionTube: formattedItem.bloodCollectionTube,
|
||||
remark: formattedItem.remark
|
||||
});
|
||||
} else {
|
||||
console.warn(`记录 ${index + 1} 不是有效对象,跳过处理:`, item);
|
||||
}
|
||||
});
|
||||
|
||||
totalItems.value = total;
|
||||
console.log('数据加载完成,表格显示', tableData.length, '条记录,总数:', totalItems.value);
|
||||
} else {
|
||||
console.log('未获取到有效数据,表格为空');
|
||||
}
|
||||
} catch (error) {
|
||||
// 详细的错误信息记录
|
||||
console.error('加载LIS分组数据异常:', error)
|
||||
|
||||
// 提取更详细的错误信息
|
||||
let errorMessage = '加载LIS分组数据失败,请稍后重试'
|
||||
|
||||
if (error.response) {
|
||||
// 服务器响应了,但状态码不是2xx
|
||||
console.error('HTTP错误状态:', error.response.status)
|
||||
console.error('HTTP错误响应体:', error.response.data)
|
||||
|
||||
if (error.response.data) {
|
||||
errorMessage = error.response.data.msg ||
|
||||
error.response.data.message ||
|
||||
error.response.data.error ||
|
||||
`服务器错误 (${error.response.status})`
|
||||
} else {
|
||||
errorMessage = `服务器错误 (${error.response.status})`
|
||||
}
|
||||
|
||||
// 额外记录响应体详情便于调试
|
||||
if (typeof error.response.data === 'object') {
|
||||
console.error('响应体详细结构:', JSON.stringify(error.response.data, null, 2))
|
||||
}
|
||||
} else if (error.request) {
|
||||
// 请求已发出,但未收到响应
|
||||
console.error('请求已发送但未收到响应:', error.request)
|
||||
errorMessage = '网络错误,服务器未响应,请检查网络连接'
|
||||
} else if (error.message) {
|
||||
// 请求配置出错
|
||||
console.error('请求配置错误:', error.message)
|
||||
errorMessage = error.message
|
||||
} else {
|
||||
console.error('未知错误类型:', typeof error)
|
||||
}
|
||||
|
||||
// 显示错误信息
|
||||
showMessage(errorMessage, 'error')
|
||||
|
||||
// 确保表格状态正确
|
||||
console.log('异常处理后表格状态:', {
|
||||
tableDataLength: tableData.length,
|
||||
totalItems: totalItems.value,
|
||||
currentPage: currentPage.value
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
console.log('数据加载操作完成,loading状态已更新为false')
|
||||
console.log('最终表格数据量:', tableData.length, ',总数:', totalItems.value)
|
||||
}
|
||||
}
|
||||
|
||||
// 开始编辑
|
||||
const startEdit = (item) => {
|
||||
// 存储原始数据,用于取消操作
|
||||
item.originalData = { ...item }
|
||||
item.editing = true
|
||||
}
|
||||
|
||||
// 验证数据
|
||||
const validateData = (item) => {
|
||||
const errors = {}
|
||||
|
||||
// 清除之前的错误信息
|
||||
delete item.errors
|
||||
|
||||
// 验证卫生机构
|
||||
if (!item.healthInstitution || item.healthInstitution.trim() === '') {
|
||||
errors.healthInstitution = '卫生机构不能为空'
|
||||
} else if (item.healthInstitution.length > 100) {
|
||||
errors.healthInstitution = '卫生机构名称不能超过100个字符'
|
||||
}
|
||||
|
||||
// 验证LIS分组名称
|
||||
if (!item.lisGroupName || item.lisGroupName.trim() === '') {
|
||||
errors.lisGroupName = 'LIS分组名称不能为空'
|
||||
} else if (item.lisGroupName.length > 50) {
|
||||
errors.lisGroupName = 'LIS分组名称不能超过50个字符'
|
||||
}
|
||||
|
||||
// 验证采血管
|
||||
if (!item.bloodCollectionTube) {
|
||||
errors.bloodCollectionTube = '请选择采血管'
|
||||
}
|
||||
|
||||
// 验证备注长度
|
||||
if (item.remark && item.remark.length > 200) {
|
||||
errors.remark = '备注信息不能超过200个字符'
|
||||
}
|
||||
|
||||
if (Object.keys(errors).length > 0) {
|
||||
item.errors = errors
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 显示提示信息
|
||||
const showMessage = (message, type = 'success') => {
|
||||
// 在实际项目中,这里可以使用Element Plus或其他UI库的消息组件
|
||||
// 这里为了简单起见,使用浏览器的alert,但添加了类型标识
|
||||
if (type === 'error') {
|
||||
console.error(message)
|
||||
alert(`错误: ${message}`)
|
||||
} else {
|
||||
console.log(message)
|
||||
// 可以使用更友好的提示方式,这里暂时注释掉alert以避免频繁弹窗
|
||||
// alert(message)
|
||||
}
|
||||
}
|
||||
|
||||
// 确认编辑
|
||||
const confirmEdit = async (item) => {
|
||||
// 验证数据
|
||||
if (!validateData(item)) {
|
||||
showMessage('请检查并修正错误信息', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否有重复的分组名称(在同一个卫生机构内)
|
||||
const duplicate = tableData.find(data =>
|
||||
data.id !== item.id &&
|
||||
data.healthInstitution === item.healthInstitution &&
|
||||
data.lisGroupName === item.lisGroupName
|
||||
)
|
||||
|
||||
if (duplicate) {
|
||||
if (!item.errors) item.errors = {}
|
||||
item.errors.lisGroupName = '该分组名称已存在'
|
||||
showMessage('分组名称重复,请修改', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
|
||||
// 准备提交数据(使用后端期望的字段名)
|
||||
const submitData = {
|
||||
id: item.id,
|
||||
hospital: item.healthInstitution, // 前端字段映射到后端字段
|
||||
date: item.date,
|
||||
groupName: item.lisGroupName, // 前端字段映射到后端字段
|
||||
tube: item.bloodCollectionTube, // 前端字段映射到后端字段
|
||||
remark: item.remark
|
||||
}
|
||||
|
||||
let response
|
||||
// 判断是新增还是修改
|
||||
if (item.isNew) {
|
||||
// 新增
|
||||
response = await addLisGroup(submitData)
|
||||
} else {
|
||||
// 修改
|
||||
response = await updateLisGroup(submitData)
|
||||
}
|
||||
|
||||
// 处理响应
|
||||
if (response.code === 200) {
|
||||
// 保存编辑
|
||||
item.editing = false
|
||||
delete item.originalData
|
||||
delete item.errors
|
||||
|
||||
// 先检查是否是新增记录,再删除isNew属性
|
||||
const isNewRecord = item.isNew
|
||||
delete item.isNew
|
||||
|
||||
showMessage('保存成功')
|
||||
|
||||
// 如果是新增,重新加载数据以确保数据一致性
|
||||
if (isNewRecord) {
|
||||
loadLisGroups()
|
||||
}
|
||||
} else {
|
||||
showMessage(`保存失败: ${response.msg || '未知错误'}`, 'error')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存LIS分组数据失败:', error)
|
||||
showMessage(`保存失败: ${error.message || '未知错误'}`, 'error')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 取消编辑
|
||||
const cancelEdit = (item) => {
|
||||
try {
|
||||
if (item.isNew) {
|
||||
// 如果是新增的行,从数组中移除
|
||||
const index = tableData.findIndex(row => row.id === item.id)
|
||||
if (index > -1) {
|
||||
tableData.splice(index, 1)
|
||||
// 更新总数
|
||||
if (totalItems.value > 0) {
|
||||
totalItems.value--
|
||||
}
|
||||
}
|
||||
} else if (item.originalData) {
|
||||
// 恢复原始数据
|
||||
Object.assign(item, item.originalData)
|
||||
delete item.originalData
|
||||
item.editing = false
|
||||
} else {
|
||||
item.editing = false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('取消编辑失败:', error)
|
||||
showMessage('取消编辑失败', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新行
|
||||
const addRow = () => {
|
||||
// 检查是否已有正在编辑的行
|
||||
const editingRow = tableData.find(item => item.editing)
|
||||
if (editingRow) {
|
||||
showMessage('请先完成当前行的编辑', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
const newId = String(Math.max(...tableData.map(item => parseInt(item.id) || 0), 0) + 1)
|
||||
tableData.push({
|
||||
id: newId,
|
||||
healthInstitution: '', // 空默认值
|
||||
date: getCurrentDate(), // 默认当前系统时间
|
||||
lisGroupName: '',
|
||||
bloodCollectionTube: '',
|
||||
remark: '',
|
||||
editing: true,
|
||||
errors: null,
|
||||
isNew: true // 标记为新记录
|
||||
})
|
||||
|
||||
showMessage('请填写新记录信息')
|
||||
}
|
||||
|
||||
// 删除行
|
||||
const deleteRow = async (index) => {
|
||||
const item = tableData[index]
|
||||
// 检查是否正在编辑
|
||||
if (item.editing) {
|
||||
showMessage('请先完成或取消编辑', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
if (confirm(`确定要删除"${item.lisGroupName}"这条记录吗?`)) {
|
||||
try {
|
||||
loading.value = true
|
||||
|
||||
// 如果是新添加的记录,直接从数组中移除
|
||||
if (item.isNew) {
|
||||
tableData.splice(index, 1)
|
||||
showMessage('删除成功')
|
||||
totalItems.value--
|
||||
} else {
|
||||
// 调用API删除
|
||||
const response = await delLisGroup(item.id)
|
||||
|
||||
if (response.code === 200) {
|
||||
tableData.splice(index, 1)
|
||||
showMessage('删除成功')
|
||||
|
||||
// 更新总数
|
||||
totalItems.value--
|
||||
} else {
|
||||
showMessage(`删除失败: ${response.msg || '未知错误'}`, 'error')
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除LIS分组数据失败:', error)
|
||||
showMessage(`删除失败: ${error.message || '未知错误'}`, 'error')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页方法
|
||||
const prevPage = () => {
|
||||
if (currentPage.value > 1) {
|
||||
currentPage.value--
|
||||
// 调用加载数据方法
|
||||
loadLisGroups()
|
||||
}
|
||||
}
|
||||
|
||||
const nextPage = () => {
|
||||
if (currentPage.value < totalPages.value) {
|
||||
currentPage.value++
|
||||
// 调用加载数据方法
|
||||
loadLisGroups()
|
||||
}
|
||||
}
|
||||
|
||||
const goToPage = (page) => {
|
||||
if (page >= 1 && page <= totalPages.value) {
|
||||
currentPage.value = page
|
||||
// 调用加载数据方法
|
||||
loadLisGroups()
|
||||
}
|
||||
}
|
||||
|
||||
// 组件挂载时加载数据
|
||||
onMounted(() => {
|
||||
// 加载采血管字典数据
|
||||
loadBloodTubeDict();
|
||||
// 加载表格数据
|
||||
loadLisGroups()
|
||||
})
|
||||
|
||||
return {
|
||||
tableData,
|
||||
bloodTubeOptions,
|
||||
startEdit,
|
||||
confirmEdit,
|
||||
cancelEdit,
|
||||
addRow,
|
||||
deleteRow,
|
||||
currentPage,
|
||||
totalPages,
|
||||
prevPage,
|
||||
nextPage,
|
||||
goToPage,
|
||||
loading
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.lis-group-maintain {
|
||||
padding: 20px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 56px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
margin-bottom: 20px;
|
||||
overflow-x: auto;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.data-table th,
|
||||
.data-table td {
|
||||
padding: 12px;
|
||||
border: 1px solid #e8e8e8;
|
||||
word-break: break-all;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
background-color: #fafafa;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.editing-row {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
.actions {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.pagination-section {
|
||||
height: 48px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 16px 0;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.pagination span {
|
||||
font-size: 14px;
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.pagination-btn {
|
||||
background: none;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 4px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.pagination-btn:hover {
|
||||
border-color: #1890FF;
|
||||
color: #1890FF;
|
||||
}
|
||||
|
||||
.pagination-btn:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.pagination-number.active {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.pagination-number.active:hover {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
margin-right: 5px;
|
||||
border: 1px solid #d9d9d9;
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: #40a9ff;
|
||||
color: #40a9ff;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-confirm {
|
||||
background-color: #52c41a;
|
||||
color: #fff;
|
||||
border-color: #52c41a;
|
||||
}
|
||||
|
||||
.btn-confirm:hover {
|
||||
background-color: #73d13d;
|
||||
border-color: #73d13d;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
|
||||
.btn-edit {
|
||||
background-color: #faad14;
|
||||
color: #fff;
|
||||
border-color: #faad14;
|
||||
}
|
||||
|
||||
.btn-edit:hover {
|
||||
background-color: #ffc53d;
|
||||
border-color: #ffc53d;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-delete {
|
||||
background-color: #ff4d4f;
|
||||
color: #fff;
|
||||
border-color: #ff4d4f;
|
||||
}
|
||||
|
||||
.btn-delete:hover {
|
||||
background-color: #ff7875;
|
||||
border-color: #ff7875;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
input, select {
|
||||
width: 100%;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input:disabled {
|
||||
background-color: #f5f5f5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* 错误状态样式 */
|
||||
.error-input {
|
||||
border-color: #ff4d4f !important;
|
||||
}
|
||||
|
||||
.error-input:focus {
|
||||
border-color: #ff4d4f !important;
|
||||
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2) !important;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #ff4d4f;
|
||||
margin-top: 2px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 错误提示区域样式 */
|
||||
.error-message-container {
|
||||
padding: 12px 16px;
|
||||
background-color: #fff2f0;
|
||||
border: 1px solid #ffccc7;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: #ff4d4f;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 加载状态样式 */
|
||||
.loading-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* 确保页面容器相对定位,使加载遮罩正常工作 */
|
||||
.lis-group-maintain {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.data-table th,
|
||||
.data-table td {
|
||||
padding: 12px 8px;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
background-color: #fafafa;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.lis-group-maintain {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
font-size: 12px;
|
||||
min-width: 600px; /* 确保表格在小屏幕上可以横向滚动 */
|
||||
}
|
||||
|
||||
.data-table th,
|
||||
.data-table td {
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 11px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.pagination-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 平滑过渡效果 */
|
||||
.btn,
|
||||
.pagination-btn,
|
||||
.editing-row {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* 美化输入框和选择框的焦点样式 */
|
||||
input:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: #40a9ff;
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
</style>
|
||||
@@ -3,14 +3,14 @@
|
||||
* @Date: 2025-04-09 09:33:35
|
||||
* @Description:
|
||||
*/
|
||||
import {defineConfig, loadEnv} from 'vite';
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
import path from 'path';
|
||||
import createVitePlugins from './vite/plugins';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig (({mode, command}) => {
|
||||
const env = loadEnv (mode, process.cwd ());
|
||||
const {VITE_APP_ENV} = env;
|
||||
export default defineConfig(({ mode, command }) => {
|
||||
const env = loadEnv(mode, process.cwd());
|
||||
const { VITE_APP_ENV } = env;
|
||||
return {
|
||||
// define: {
|
||||
// // enable hydration mismatch details in production build
|
||||
@@ -19,15 +19,15 @@ export default defineConfig (({mode, command}) => {
|
||||
// 部署生产环境和开发环境下的URL。
|
||||
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
|
||||
// 例如 https://www.openHIS.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.openhis.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||
base: VITE_APP_ENV === 'production' ? '/' : '/',
|
||||
plugins: createVitePlugins (env, command === 'build'),
|
||||
base: VITE_APP_ENV === 'prod' ? '/' : '/',
|
||||
plugins: createVitePlugins(env, command === 'build'),
|
||||
resolve: {
|
||||
// https://cn.vitejs.dev/config/#resolve-alias
|
||||
alias: {
|
||||
// 设置路径
|
||||
'~': path.resolve (__dirname, './'),
|
||||
'~': path.resolve(__dirname, './'),
|
||||
// 设置别名
|
||||
'@': path.resolve (__dirname, './src'),
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
},
|
||||
// https://cn.vitejs.dev/config/#resolve-extensions
|
||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
|
||||
@@ -41,27 +41,23 @@ export default defineConfig (({mode, command}) => {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
'/dev-api': {
|
||||
target: 'http://localhost:18080/openhis',
|
||||
// target: 'http://192.168.31.30:18080/openhis', // zwh
|
||||
// target: 'http://192.168.31.50:18080/openhis', // wh
|
||||
// target: 'http://192.168.31.190:18080/openhis', // yangmo
|
||||
// target: 'http://60.188.247.175:18080/openhis',// 公网
|
||||
changeOrigin: true,
|
||||
rewrite: p => p.replace (/^\/dev-api/, ''),
|
||||
rewrite: p => p.replace(/^\/dev-api/, ''),
|
||||
},
|
||||
'/ybplugin':{
|
||||
'/ybplugin': {
|
||||
target: 'http://localhost:5000',
|
||||
changeOrigin: true,
|
||||
rewrite: p => p.replace (/^\/ybplugin/, ''),
|
||||
rewrite: p => p.replace(/^\/ybplugin/, ''),
|
||||
},
|
||||
'/prod-api': {
|
||||
target: 'http://localhost:18080/openhis',
|
||||
'/prd-api': {
|
||||
target: 'http://localhost:18082/openhis',
|
||||
changeOrigin: true,
|
||||
rewrite: p => p.replace (/^\/prod-api/, ''),
|
||||
rewrite: p => p.replace(/^\/prd-api/, ''),
|
||||
},
|
||||
'/test-api': {
|
||||
target: 'http://localhost:18080/openhis',
|
||||
target: 'http://localhost:18081/openhis',
|
||||
changeOrigin: true,
|
||||
rewrite: p => p.replace (/^\/test-api/, ''),
|
||||
rewrite: p => p.replace(/^\/test-api/, ''),
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -74,7 +70,7 @@ export default defineConfig (({mode, command}) => {
|
||||
AtRule: {
|
||||
charset: atRule => {
|
||||
if (atRule.name === 'charset') {
|
||||
atRule.remove ();
|
||||
atRule.remove();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user