Compare commits
24 Commits
39aa710fd3
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 633cf2c17f | |||
| 3188ca5752 | |||
| c79e4c2623 | |||
| f3c451d0a1 | |||
| a077bd57d4 | |||
| cf16c497bd | |||
| fd1ab239a9 | |||
| caf65e3113 | |||
| c18c21ff4c | |||
| ab6849c9eb | |||
| 6b555f2563 | |||
| 7645405c5b | |||
| 5bfadb9174 | |||
| e1b9d36153 | |||
| fdb8d6c934 | |||
| 22a1ac57b2 | |||
| 4d243815a6 | |||
| 882e8c9199 | |||
| a0c87f6335 | |||
| 538dde55f7 | |||
| f33e3c6f15 | |||
| 0794782505 | |||
| d37fa46b5f | |||
| 8fcc229ad8 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -57,4 +57,8 @@
|
|||||||
# 忽略设计书
|
# 忽略设计书
|
||||||
PostgreSQL/openHis_DB设计书.xlsx
|
PostgreSQL/openHis_DB设计书.xlsx
|
||||||
|
|
||||||
public.sql
|
public.sql
|
||||||
|
发版记录/2025-11-12/~$发版日志.docx
|
||||||
|
发版记录/2025-11-12/~$S-管理系统-调价管理.docx
|
||||||
|
发版记录/2025-11-12/发版日志.docx
|
||||||
|
.gitignore
|
||||||
|
|||||||
@@ -62,10 +62,10 @@
|
|||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- rabbitMQ -->
|
<!-- rabbitMQ -->
|
||||||
<dependency>
|
<!-- <dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||||
</dependency>
|
</dependency> -->
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.web.appointmentmanage.appservice;
|
package com.openhis.web.appointmentmanage.appservice;
|
||||||
|
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.openhis.administration.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||||
|
|
||||||
public interface IDoctorScheduleAppService {
|
public interface IDoctorScheduleAppService {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.appservice;
|
||||||
|
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.web.appointmentmanage.dto.SchedulePoolDto;
|
||||||
|
|
||||||
|
public interface ISchedulePoolAppService {
|
||||||
|
R<?> addSchedulePool(SchedulePoolDto schedulePoolDto);
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.appservice;
|
||||||
|
|
||||||
|
public interface IScheduleSlotAppService {
|
||||||
|
}
|
||||||
@@ -3,8 +3,8 @@ package com.openhis.web.appointmentmanage.appservice.impl;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.openhis.administration.domain.Dept;
|
import com.openhis.appointmentmanage.domain.Dept;
|
||||||
import com.openhis.administration.service.IDeptService;
|
import com.openhis.appointmentmanage.service.IDeptService;
|
||||||
import com.openhis.web.appointmentmanage.appservice.IDeptAppService;
|
import com.openhis.web.appointmentmanage.appservice.IDeptAppService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package com.openhis.web.appointmentmanage.appservice.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.openhis.administration.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||||
import com.openhis.administration.service.IDoctorScheduleService;
|
import com.openhis.appointmentmanage.service.IDoctorScheduleService;
|
||||||
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
|
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.appservice.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.appointmentmanage.domain.SchedulePool;
|
||||||
|
import com.openhis.appointmentmanage.service.ISchedulePoolService;
|
||||||
|
import com.openhis.web.appointmentmanage.appservice.ISchedulePoolAppService;
|
||||||
|
import com.openhis.web.appointmentmanage.dto.SchedulePoolDto;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SchedulePoolAppServiceImpl implements ISchedulePoolAppService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ISchedulePoolService schedulePoolService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> addSchedulePool(SchedulePoolDto schedulePoolDto) {
|
||||||
|
//12/15 实体封装过程数据关系复杂 尚未完全理清 下次继续改
|
||||||
|
if(ObjectUtil.isNull(schedulePoolDto)){
|
||||||
|
return R.fail("号源不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
SchedulePool schedulePool = new SchedulePool();
|
||||||
|
schedulePool.setHospitalId(schedulePoolDto.getHospitalId());
|
||||||
|
schedulePool.setDeptId(schedulePoolDto.getDeptId());
|
||||||
|
schedulePool.setDoctorId(schedulePoolDto.getDoctorId());
|
||||||
|
schedulePool.setDoctorName(schedulePoolDto.getDoctorName());
|
||||||
|
schedulePool.setScheduleDate(schedulePoolDto.getScheduleDate());
|
||||||
|
schedulePool.setShift(schedulePoolDto.getShift());
|
||||||
|
schedulePool.setStartTime(schedulePoolDto.getStartTime());
|
||||||
|
schedulePool.setEndTime(schedulePoolDto.getEndTime());
|
||||||
|
|
||||||
|
schedulePool.setRegType(schedulePoolDto.getRegType());
|
||||||
|
schedulePool.setFee(schedulePoolDto.getFee());
|
||||||
|
boolean save = schedulePoolService.save(schedulePool);
|
||||||
|
return R.ok(save);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.appservice.impl;
|
||||||
|
|
||||||
|
import com.openhis.web.appointmentmanage.appservice.IScheduleSlotAppService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ScheduleSlotAppServiceImpl implements IScheduleSlotAppService {
|
||||||
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
package com.openhis.web.appointmentmanage.controller;
|
package com.openhis.web.appointmentmanage.controller;
|
||||||
|
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.openhis.administration.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||||
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
|
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.websocket.server.PathParam;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/doctor-schedule")
|
@RequestMapping("/doctor-schedule")
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.appointmentmanage.domain.SchedulePool;
|
||||||
|
import com.openhis.web.appointmentmanage.appservice.ISchedulePoolAppService;
|
||||||
|
import com.openhis.web.appointmentmanage.dto.SchedulePoolDto;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/schedule-pool")
|
||||||
|
public class SchedulePoolController {
|
||||||
|
@Resource
|
||||||
|
private ISchedulePoolAppService schedulePoolAppService;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 新增号源
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
public R<?> addSchedulePool(@RequestBody SchedulePoolDto schedulePoolDto) {
|
||||||
|
return R.ok(schedulePoolAppService.addSchedulePool(schedulePoolDto));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/schedule-slot")
|
||||||
|
public class ScheduleSlotController {
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 号源池Dto
|
||||||
|
*
|
||||||
|
* @date 2025-12-12
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SchedulePoolDto {
|
||||||
|
/** id */
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
/** 业务编号 */
|
||||||
|
private String poolCode;
|
||||||
|
|
||||||
|
/** 医院ID */
|
||||||
|
private Integer hospitalId;
|
||||||
|
|
||||||
|
/** 科室ID */
|
||||||
|
private Integer deptId;
|
||||||
|
|
||||||
|
/** 医生ID */
|
||||||
|
private Integer doctorId;
|
||||||
|
|
||||||
|
/** 医生姓名 */
|
||||||
|
private String doctorName;
|
||||||
|
|
||||||
|
/** 诊室 */
|
||||||
|
private String clinicRoom;
|
||||||
|
|
||||||
|
/** 出诊日期 */
|
||||||
|
private LocalDate scheduleDate;
|
||||||
|
|
||||||
|
/** 班别 */
|
||||||
|
private String shift;
|
||||||
|
|
||||||
|
/** 开始时间 */
|
||||||
|
private LocalTime startTime;
|
||||||
|
|
||||||
|
/** 结束时间 */
|
||||||
|
private LocalTime endTime;
|
||||||
|
|
||||||
|
/** 总号量 */
|
||||||
|
private Integer totalQuota;
|
||||||
|
|
||||||
|
/** 已约 */
|
||||||
|
private Integer bookedNum;
|
||||||
|
|
||||||
|
/** 铁号数 */
|
||||||
|
private Integer lockedNum;
|
||||||
|
|
||||||
|
/** 剩余号数 */
|
||||||
|
private Integer availableNum;
|
||||||
|
|
||||||
|
/** 号别 */
|
||||||
|
private String regType;
|
||||||
|
|
||||||
|
/** 原价 (元) */
|
||||||
|
private Double fee;
|
||||||
|
|
||||||
|
/** 医保限价 (元) */
|
||||||
|
private Double insurancePrice;
|
||||||
|
|
||||||
|
/** 支持渠道 */
|
||||||
|
private String supportChannel;
|
||||||
|
|
||||||
|
/** 号源状态 */
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 停诊原因 */
|
||||||
|
private String stopReason;
|
||||||
|
|
||||||
|
/** 放号时间 */
|
||||||
|
private LocalDateTime releaseTime;
|
||||||
|
|
||||||
|
/** 截止预约时间 */
|
||||||
|
private LocalDateTime deadlineTime;
|
||||||
|
|
||||||
|
/** 乐观锁版本 */
|
||||||
|
private Integer version;
|
||||||
|
|
||||||
|
/** 操作人ID */
|
||||||
|
private Integer opUserId;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 排班ID */
|
||||||
|
private Integer scheduleId;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/** 更新时间 */
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.mapper;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface SchedulePoolAppMapper {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.mapper;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface ScheduleSlotAppMapper {
|
||||||
|
}
|
||||||
@@ -179,7 +179,7 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
|||||||
|
|
||||||
// 分页查询
|
// 分页查询
|
||||||
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage =
|
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage =
|
||||||
activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<>(pageNo, pageSize), queryWrapper);
|
activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<DiagnosisTreatmentDto>(pageNo, pageSize), queryWrapper);
|
||||||
|
|
||||||
diseaseTreatmentPage.getRecords().forEach(e -> {
|
diseaseTreatmentPage.getRecords().forEach(e -> {
|
||||||
// 医保标记枚举类回显赋值
|
// 医保标记枚举类回显赋值
|
||||||
|
|||||||
@@ -93,7 +93,14 @@
|
|||||||
T13.charge_item_ids,
|
T13.charge_item_ids,
|
||||||
T13.id AS payment_id,
|
T13.id AS payment_id,
|
||||||
ai.picture_url AS picture_url,
|
ai.picture_url AS picture_url,
|
||||||
T8.birth_date AS birth_date
|
T8.birth_date AS birth_date,
|
||||||
|
T14.create_time AS return_date,
|
||||||
|
T14.return_reason AS return_reason,
|
||||||
|
T15.name AS operator_name,
|
||||||
|
T15.id AS operator_id,
|
||||||
|
T14.display_amount AS refund_amount,
|
||||||
|
T6.contract_no AS contract_no,
|
||||||
|
T16.refund_method AS refund_method
|
||||||
FROM adm_encounter AS T1
|
FROM adm_encounter AS T1
|
||||||
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
||||||
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
||||||
|
|||||||
@@ -4,35 +4,6 @@
|
|||||||
<select id="getDiseaseTreatmentPage" parameterType="java.util.Map"
|
<select id="getDiseaseTreatmentPage" parameterType="java.util.Map"
|
||||||
resultType="com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto">
|
resultType="com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto">
|
||||||
|
|
||||||
SELECT
|
|
||||||
T3.id,
|
|
||||||
T3.category_code,
|
|
||||||
T3.bus_no,
|
|
||||||
T3.name,
|
|
||||||
T3.py_str,
|
|
||||||
T3.wb_str,
|
|
||||||
T3.type_enum,
|
|
||||||
T3.permitted_unit_code,
|
|
||||||
T3.org_id,
|
|
||||||
T3.location_id,
|
|
||||||
T3.yb_flag,
|
|
||||||
T3.yb_no,
|
|
||||||
T3.yb_match_flag,
|
|
||||||
T3.status_enum,
|
|
||||||
T3.body_site_code,
|
|
||||||
T3.specimen_code,
|
|
||||||
T3.description_text,
|
|
||||||
T3.rule_id,
|
|
||||||
T3.tenant_id,
|
|
||||||
T3.item_type_code,
|
|
||||||
T3.yb_type,
|
|
||||||
T3.retail_price,
|
|
||||||
T3.maximum_retail_price,
|
|
||||||
T3.chrgitm_lv,--医保等级
|
|
||||||
T3.children_json,--子项json
|
|
||||||
T3.pricing_flag--划价标记
|
|
||||||
FROM
|
|
||||||
(
|
|
||||||
SELECT
|
SELECT
|
||||||
T1.id,
|
T1.id,
|
||||||
T1.category_code,
|
T1.category_code,
|
||||||
@@ -57,24 +28,28 @@
|
|||||||
T2.type_code as item_type_code,
|
T2.type_code as item_type_code,
|
||||||
T2.yb_type,
|
T2.yb_type,
|
||||||
T2.price as retail_price,--零售价
|
T2.price as retail_price,--零售价
|
||||||
( SELECT T4.amount
|
T4.amount as maximum_retail_price,--最高零售价
|
||||||
FROM adm_charge_item_definition T5
|
|
||||||
LEFT JOIN adm_charge_item_def_detail T4 ON T4.definition_id = T5.id
|
|
||||||
WHERE T4.condition_code = '4'--4:限制
|
|
||||||
AND T5.instance_id = T1.id
|
|
||||||
AND T5.instance_table = 'wor_activity_definition'
|
|
||||||
) as maximum_retail_price,--最高零售价
|
|
||||||
T1.children_json,--子项json
|
T1.children_json,--子项json
|
||||||
T1.pricing_flag--划价标记
|
T1.pricing_flag--划价标记
|
||||||
FROM wor_activity_definition T1
|
FROM wor_activity_definition T1
|
||||||
LEFT JOIN adm_charge_item_definition T2 ON T1.id = T2.instance_id
|
LEFT JOIN adm_charge_item_definition T2 ON T1.id = T2.instance_id
|
||||||
|
LEFT JOIN adm_charge_item_definition T5 ON T5.instance_id = T1.id AND T5.instance_table = 'wor_activity_definition'
|
||||||
|
LEFT JOIN adm_charge_item_def_detail T4 ON T4.definition_id = T5.id AND T4.condition_code = '4'--4:限制
|
||||||
<where>
|
<where>
|
||||||
T1.delete_flag = '0'
|
T1.delete_flag = '0'
|
||||||
AND T2.instance_table = 'wor_activity_definition'
|
AND T2.instance_table = 'wor_activity_definition'
|
||||||
|
<if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
|
||||||
|
<choose>
|
||||||
|
<when test="ew.customSqlSegment.contains('tenant_id')">
|
||||||
|
${ew.customSqlSegment.replaceFirst('tenant_id', 'T1.tenant_id').replaceFirst('WHERE', 'AND')}
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
${ew.customSqlSegment.replaceFirst('WHERE', 'AND')}
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</if>
|
||||||
</where>
|
</where>
|
||||||
ORDER BY T1.bus_no DESC
|
ORDER BY T1.bus_no DESC
|
||||||
) AS T3
|
|
||||||
${ew.customSqlSegment}
|
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import Layout from '@/layout'
|
||||||
|
import router from './router'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import NProgress from 'nprogress'
|
||||||
|
import 'nprogress/nprogress.css'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { isHttp } from '@/utils/validate'
|
||||||
|
import { isRelogin } from '@/utils/request'
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
import useSettingsStore from '@/store/modules/settings'
|
||||||
|
import usePermissionStore from '@/store/modules/permission'
|
||||||
|
|
||||||
|
NProgress.configure({ showSpinner: false });
|
||||||
|
|
||||||
|
const whiteList = ['/login', '/register'];
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
NProgress.start()
|
||||||
|
if (getToken()) {
|
||||||
|
to.meta.title && useSettingsStore().setTitle(to.meta.title)
|
||||||
|
/* has token*/
|
||||||
|
if (to.path === '/login') {
|
||||||
|
next({ path: '/' })
|
||||||
|
NProgress.done()
|
||||||
|
} else if (whiteList.indexOf(to.path) !== -1) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
if (useUserStore().roles.length === 0) {
|
||||||
|
isRelogin.show = true
|
||||||
|
// 判断当前用户是否已拉取完user_info信息
|
||||||
|
useUserStore().getInfo().then(() => {
|
||||||
|
isRelogin.show = false
|
||||||
|
usePermissionStore().generateRoutes().then(accessRoutes => {
|
||||||
|
// 根据roles权限生成可访问的路由表
|
||||||
|
accessRoutes.forEach(route => {
|
||||||
|
if (!isHttp(route.path)) {
|
||||||
|
// 检查是否已经存在同名路由
|
||||||
|
if (!router.hasRoute(route.name)) {
|
||||||
|
router.addRoute(route) // 动态添加可访问路由表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
||||||
|
})
|
||||||
|
}).catch(err => {
|
||||||
|
useUserStore().logOut().then(() => {
|
||||||
|
ElMessage.error(err)
|
||||||
|
next({ path: '/' })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 没有token
|
||||||
|
if (whiteList.indexOf(to.path) !== -1) {
|
||||||
|
// 在免登录白名单,直接进入
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||||
|
NProgress.done()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.afterEach(() => {
|
||||||
|
NProgress.done()
|
||||||
|
})
|
||||||
|
|
||||||
|
const appointmentRouter = {
|
||||||
|
path: '/appointment',
|
||||||
|
component: Layout,
|
||||||
|
redirect: '/appointment/manage',
|
||||||
|
name: 'Appointment',
|
||||||
|
meta: {
|
||||||
|
title: '预约管理',
|
||||||
|
icon: 'calendar'
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'manage',
|
||||||
|
component: () => import('@/views/appointment/manage'),
|
||||||
|
name: 'AppointmentManage', // 修改名称,避免与父级重复
|
||||||
|
meta: { title: '预约管理', icon: 'list' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'setting',
|
||||||
|
component: () => import('@/views/appointment/setting'),
|
||||||
|
name: 'AppointmentSetting',
|
||||||
|
meta: { title: '预约设置', icon: 'setting' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default appointmentRouter
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.openhis.administration.service.impl;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
||||||
import com.openhis.administration.domain.Dept;
|
|
||||||
import com.openhis.administration.mapper.DeptMapper;
|
|
||||||
import com.openhis.administration.service.IDeptService;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DeptImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
package com.openhis.administration.domain;
|
package com.openhis.appointmentmanage.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 科室Entity实体
|
* 科室Entity
|
||||||
*
|
*
|
||||||
* @date 2025-12-08
|
* @date 2025-12-08
|
||||||
*/
|
*/
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.openhis.administration.domain;
|
package com.openhis.appointmentmanage.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -6,7 +6,11 @@ import lombok.experimental.Accessors;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
/**
|
||||||
|
* 医生排班Entity
|
||||||
|
*
|
||||||
|
* @date 2025-12-12
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName(value = "adm_doctor_schedule")
|
@TableName(value = "adm_doctor_schedule")
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.openhis.administration.domain;
|
package com.openhis.appointmentmanage.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -7,7 +7,11 @@ import lombok.experimental.Accessors;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
/**
|
||||||
|
* 号源池Entity
|
||||||
|
*
|
||||||
|
* @date 2025-12-12
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName(value = "adm_schedule_pool")
|
@TableName(value = "adm_schedule_pool")
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@@ -15,36 +19,84 @@ public class SchedulePool {
|
|||||||
/** id */
|
/** id */
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
|
/** 业务编号 */
|
||||||
private String poolCode;
|
private String poolCode;
|
||||||
|
|
||||||
|
/** 医院ID */
|
||||||
private Integer hospitalId;
|
private Integer hospitalId;
|
||||||
|
|
||||||
|
/** 科室ID */
|
||||||
private Integer deptId;
|
private Integer deptId;
|
||||||
|
|
||||||
|
/** 医生ID */
|
||||||
private Integer doctorId;
|
private Integer doctorId;
|
||||||
|
|
||||||
|
/** 医生姓名 */
|
||||||
private String doctorName;
|
private String doctorName;
|
||||||
|
|
||||||
|
/** 诊室 */
|
||||||
private String clinicRoom;
|
private String clinicRoom;
|
||||||
|
|
||||||
|
/** 出诊日期 */
|
||||||
private LocalDate scheduleDate;
|
private LocalDate scheduleDate;
|
||||||
|
|
||||||
|
/** 班别 */
|
||||||
private String shift;
|
private String shift;
|
||||||
|
|
||||||
/** 开始时间 */
|
/** 开始时间 */
|
||||||
private LocalTime startTime;
|
private LocalTime startTime;
|
||||||
|
|
||||||
/** 结束时间 */
|
/** 结束时间 */
|
||||||
private LocalTime endTime;
|
private LocalTime endTime;
|
||||||
/**/
|
|
||||||
|
/** 总号量 */
|
||||||
private Integer totalQuota;
|
private Integer totalQuota;
|
||||||
|
|
||||||
|
/** 已约 */
|
||||||
private Integer bookedNum;
|
private Integer bookedNum;
|
||||||
|
|
||||||
|
/** 铁号数 */
|
||||||
private Integer lockedNum;
|
private Integer lockedNum;
|
||||||
|
|
||||||
|
/** 剩余号数 */
|
||||||
private Integer availableNum;
|
private Integer availableNum;
|
||||||
|
|
||||||
|
/** 号别 */
|
||||||
private String regType;
|
private String regType;
|
||||||
|
|
||||||
|
/** 原价 (元) */
|
||||||
private Double fee;
|
private Double fee;
|
||||||
|
|
||||||
|
/** 医保限价 (元) */
|
||||||
private Double insurancePrice;
|
private Double insurancePrice;
|
||||||
|
|
||||||
|
/** 支持渠道 */
|
||||||
private String supportChannel;
|
private String supportChannel;
|
||||||
|
|
||||||
|
/** 号源状态 */
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
/** 停诊原因 */
|
||||||
private String stopReason;
|
private String stopReason;
|
||||||
|
|
||||||
|
/** 放号时间 */
|
||||||
private LocalDateTime releaseTime;
|
private LocalDateTime releaseTime;
|
||||||
|
|
||||||
|
/** 截止预约时间 */
|
||||||
private LocalDateTime deadlineTime;
|
private LocalDateTime deadlineTime;
|
||||||
|
|
||||||
|
/** 乐观锁版本 */
|
||||||
private Integer version;
|
private Integer version;
|
||||||
|
|
||||||
|
/** 操作人ID */
|
||||||
private Integer opUserId;
|
private Integer opUserId;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
/** 排班ID */
|
||||||
private Integer scheduleId;
|
private Integer scheduleId;
|
||||||
|
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.openhis.administration.domain;
|
package com.openhis.appointmentmanage.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -6,17 +6,33 @@ import lombok.experimental.Accessors;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
/**
|
||||||
|
* 号源池明细Entity
|
||||||
|
*
|
||||||
|
* @date 2025-12-12
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName(value = "adm_schedule_slot")
|
@TableName(value = "adm_schedule_slot")
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class ScheduleSlot {
|
public class ScheduleSlot {
|
||||||
|
/** 明细主键 */
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
|
/** 号源池ID */
|
||||||
private Integer poolId;
|
private Integer poolId;
|
||||||
|
|
||||||
|
/** 序号 */
|
||||||
private Integer seqNo;
|
private Integer seqNo;
|
||||||
|
|
||||||
|
/** 序号状态: 0-可用,1-已预约,2-已取消,3-已过期等 */
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
/** 预约订单ID */
|
||||||
private Integer orderId;
|
private Integer orderId;
|
||||||
|
|
||||||
|
/** 预计叫号时间 */
|
||||||
private LocalTime expectTime;
|
private LocalTime expectTime;
|
||||||
|
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.mapper;
|
package com.openhis.appointmentmanage.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.openhis.administration.domain.Dept;
|
import com.openhis.appointmentmanage.domain.Dept;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.mapper;
|
package com.openhis.appointmentmanage.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.openhis.administration.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.mapper;
|
package com.openhis.appointmentmanage.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.openhis.administration.domain.SchedulePool;
|
import com.openhis.appointmentmanage.domain.SchedulePool;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.mapper;
|
package com.openhis.appointmentmanage.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.openhis.administration.domain.ScheduleSlot;
|
import com.openhis.appointmentmanage.domain.ScheduleSlot;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.service;
|
package com.openhis.appointmentmanage.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.openhis.administration.domain.Dept;
|
import com.openhis.appointmentmanage.domain.Dept;
|
||||||
|
|
||||||
public interface IDeptService extends IService<Dept> {
|
public interface IDeptService extends IService<Dept> {
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.service;
|
package com.openhis.appointmentmanage.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.openhis.administration.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||||
|
|
||||||
public interface IDoctorScheduleService extends IService<DoctorSchedule> {
|
public interface IDoctorScheduleService extends IService<DoctorSchedule> {
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.service;
|
package com.openhis.appointmentmanage.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.openhis.administration.domain.SchedulePool;
|
import com.openhis.appointmentmanage.domain.SchedulePool;
|
||||||
|
|
||||||
public interface ISchedulePoolService extends IService<SchedulePool> {
|
public interface ISchedulePoolService extends IService<SchedulePool> {
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.openhis.administration.service;
|
package com.openhis.appointmentmanage.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.openhis.administration.domain.ScheduleSlot;
|
import com.openhis.appointmentmanage.domain.ScheduleSlot;
|
||||||
|
|
||||||
public interface IScheduleSlotService extends IService<ScheduleSlot> {
|
public interface IScheduleSlotService extends IService<ScheduleSlot> {
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.openhis.appointmentmanage.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.openhis.appointmentmanage.domain.Dept;
|
||||||
|
import com.openhis.appointmentmanage.mapper.DeptMapper;
|
||||||
|
import com.openhis.appointmentmanage.service.IDeptService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DeptImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.openhis.administration.service.impl;
|
package com.openhis.appointmentmanage.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.openhis.administration.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||||
import com.openhis.administration.mapper.DoctorScheduleMapper;
|
import com.openhis.appointmentmanage.mapper.DoctorScheduleMapper;
|
||||||
import com.openhis.administration.service.IDoctorScheduleService;
|
import com.openhis.appointmentmanage.service.IDoctorScheduleService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.openhis.administration.service.impl;
|
package com.openhis.appointmentmanage.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.openhis.administration.domain.SchedulePool;
|
import com.openhis.appointmentmanage.domain.SchedulePool;
|
||||||
import com.openhis.administration.mapper.SchedulePoolMapper;
|
import com.openhis.appointmentmanage.mapper.SchedulePoolMapper;
|
||||||
import com.openhis.administration.service.ISchedulePoolService;
|
import com.openhis.appointmentmanage.service.ISchedulePoolService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.openhis.administration.service.impl;
|
package com.openhis.appointmentmanage.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.openhis.administration.domain.ScheduleSlot;
|
import com.openhis.appointmentmanage.domain.ScheduleSlot;
|
||||||
import com.openhis.administration.mapper.ScheduleSlotMapper;
|
import com.openhis.appointmentmanage.mapper.ScheduleSlotMapper;
|
||||||
import com.openhis.administration.service.IScheduleSlotService;
|
import com.openhis.appointmentmanage.service.IScheduleSlotService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
2663
openhis-ui-vue3/package-lock.json
generated
2663
openhis-ui-vue3/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,43 +19,43 @@
|
|||||||
"url": "giturl"
|
"url": "giturl"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "2.3.1",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"@vueup/vue-quill": "1.2.0",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "10.6.1",
|
"@vueuse/core": "^11.0.0",
|
||||||
"axios": "0.27.2",
|
"axios": "^1.7.0",
|
||||||
"chart.js": "^4.5.1",
|
"chart.js": "^4.5.1",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"decimal.js": "^10.5.0",
|
"decimal.js": "^10.5.0",
|
||||||
"echarts": "^5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"element-china-area-data": "^6.1.0",
|
"element-china-area-data": "^6.1.0",
|
||||||
"element-plus": "2.9.11",
|
"element-plus": "^2.12.0",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"fuse.js": "6.6.2",
|
"fuse.js": "^7.0.0",
|
||||||
"html2pdf.js": "^0.10.3",
|
"html2pdf.js": "^0.10.3",
|
||||||
"js-cookie": "3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"jsencrypt": "3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "2.1.7",
|
"pinia": "^2.2.0",
|
||||||
"pinyin": "^4.0.0-alpha.2",
|
"pinyin": "^4.0.0-alpha.2",
|
||||||
"province-city-china": "^8.5.8",
|
"province-city-china": "^8.5.8",
|
||||||
"segmentit": "^2.0.3",
|
"segmentit": "^2.0.3",
|
||||||
"v-region": "^3.3.0",
|
"v-region": "^3.3.0",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-area-linkage": "^5.1.0",
|
"vue-area-linkage": "^5.1.0",
|
||||||
"vue-cropper": "1.1.1",
|
"vue-cropper": "^1.1.1",
|
||||||
"vue-plugin-hiprint": "^0.0.60",
|
"vue-plugin-hiprint": "^0.0.60",
|
||||||
"vue-router": "4.2.5"
|
"vue-router": "^4.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "4.5.0",
|
"@vitejs/plugin-vue": "^5.0.0",
|
||||||
"@vue/compiler-sfc": "3.3.9",
|
"@vue/compiler-sfc": "^3.5.25",
|
||||||
"sass": "1.69.5",
|
"sass": "^1.77.8",
|
||||||
"unplugin-auto-import": "0.17.1",
|
"unplugin-auto-import": "^0.19.0",
|
||||||
"unplugin-vue-setup-extend-plus": "1.0.0",
|
"unplugin-vue-setup-extend-plus": "^1.0.0",
|
||||||
"vite": "^5.0.4",
|
"vite": "^5.0.4",
|
||||||
"vite-plugin-compression": "0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-svg-icons": "2.0.1"
|
"vite-plugin-svg-icons": "^2.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,10 @@ export function logout() {
|
|||||||
|
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
export function getUserBindTenantList(username) {
|
export function getUserBindTenantList(username) {
|
||||||
|
// 确保username存在,避免构建出错误的URL
|
||||||
|
const safeUsername = username || '';
|
||||||
return request({
|
return request({
|
||||||
url: '/system/tenant/user-bind/'+username,
|
url: '/system/tenant/user-bind/' + safeUsername,
|
||||||
headers: {
|
headers: {
|
||||||
isToken: false
|
isToken: false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ export function getConfig(configId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 根据参数键名查询参数值
|
// 根据参数键名查询参数值
|
||||||
export function getConfigKey(configKey) {
|
export function getConfigKey(configKey, options = {}) {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/config/configKey/' + configKey,
|
url: '/system/config/configKey/' + configKey,
|
||||||
method: 'get'
|
method: 'get',
|
||||||
|
...options
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="editor-container">
|
||||||
<el-upload
|
<div>
|
||||||
:action="uploadUrl"
|
<el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
|
||||||
:before-upload="handleBeforeUpload"
|
:on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers" class="editor-img-uploader"
|
||||||
:on-success="handleUploadSuccess"
|
v-if="type == 'url'">
|
||||||
:on-error="handleUploadError"
|
<i ref="uploadRef" class="editor-img-uploader"></i>
|
||||||
name="file"
|
</el-upload>
|
||||||
:show-file-list="false"
|
</div>
|
||||||
:headers="headers"
|
<div class="editor">
|
||||||
class="editor-img-uploader"
|
<quill-editor ref="quillEditorRef" :content="content" @update:content="content = $event" contentType="html"
|
||||||
v-if="type == 'url'"
|
@textChange="(e) => $emit('update:modelValue', content)" :options="options" :style="styles" />
|
||||||
>
|
</div>
|
||||||
<i ref="uploadRef" class="editor-img-uploader"></i>
|
|
||||||
</el-upload>
|
|
||||||
</div>
|
|
||||||
<div class="editor">
|
|
||||||
<quill-editor
|
|
||||||
ref="quillEditorRef"
|
|
||||||
v-model:content="content"
|
|
||||||
contentType="html"
|
|
||||||
@textChange="(e) => $emit('update:modelValue', content)"
|
|
||||||
:options="options"
|
|
||||||
:style="styles"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -30,10 +18,11 @@
|
|||||||
import { QuillEditor } from "@vueup/vue-quill";
|
import { QuillEditor } from "@vueup/vue-quill";
|
||||||
import "@vueup/vue-quill/dist/vue-quill.snow.css";
|
import "@vueup/vue-quill/dist/vue-quill.snow.css";
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth";
|
||||||
|
import { ref, computed, watch, onMounted } from 'vue';
|
||||||
const { proxy } = getCurrentInstance();
|
import modal from '@/plugins/modal';
|
||||||
|
|
||||||
const quillEditorRef = ref();
|
const quillEditorRef = ref();
|
||||||
|
const uploadRef = ref();
|
||||||
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址
|
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址
|
||||||
const headers = ref({
|
const headers = ref({
|
||||||
Authorization: "Bearer " + getToken()
|
Authorization: "Bearer " + getToken()
|
||||||
@@ -115,32 +104,34 @@ watch(() => props.modelValue, (v) => {
|
|||||||
// 如果设置了上传地址则自定义图片上传事件
|
// 如果设置了上传地址则自定义图片上传事件
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.type == 'url') {
|
if (props.type == 'url') {
|
||||||
let quill = quillEditorRef.value.getQuill();
|
let quill = quillEditorRef.value?.getQuill();
|
||||||
let toolbar = quill.getModule("toolbar");
|
if (quill) {
|
||||||
toolbar.addHandler("image", (value) => {
|
let toolbar = quill.getModule("toolbar");
|
||||||
if (value) {
|
toolbar.addHandler("image", (value) => {
|
||||||
proxy.$refs.uploadRef.click();
|
if (value && uploadRef.value) {
|
||||||
} else {
|
uploadRef.value.click();
|
||||||
quill.format("image", false);
|
} else {
|
||||||
}
|
quill.format("image", false);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 上传前校检格式和大小
|
// 上传前校检格式和大小
|
||||||
function handleBeforeUpload(file) {
|
function handleBeforeUpload(file) {
|
||||||
const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
|
const type = ["image/jpeg", "image/jpg", "image/png", "image/svg+xml"];
|
||||||
const isJPG = type.includes(file.type);
|
const isJPG = type.includes(file.type);
|
||||||
//检验文件格式
|
//检验文件格式
|
||||||
if (!isJPG) {
|
if (!isJPG) {
|
||||||
proxy.$modal.msgError(`图片格式错误!`);
|
modal.msgError(`图片格式错误!`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 校检文件大小
|
// 校检文件大小
|
||||||
if (props.fileSize) {
|
if (props.fileSize) {
|
||||||
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
||||||
if (!isLt) {
|
if (!isLt) {
|
||||||
proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
|
modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,21 +143,24 @@ function handleUploadSuccess(res, file) {
|
|||||||
// 如果上传成功
|
// 如果上传成功
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
// 获取富文本实例
|
// 获取富文本实例
|
||||||
let quill = toRaw(quillEditorRef.value).getQuill();
|
let quill = quillEditorRef.value?.getQuill();
|
||||||
// 获取光标位置
|
if (quill) {
|
||||||
let length = quill.selection.savedRange.index;
|
// 获取光标位置
|
||||||
// 插入图片,res.url为服务器返回的图片链接地址
|
let range = quill.selection?.savedRange || quill.getSelection();
|
||||||
quill.insertEmbed(length, "image", import.meta.env.VITE_APP_BASE_API + res.fileName);
|
let length = range?.index || 0;
|
||||||
// 调整光标到最后
|
// 插入图片,res.url为服务器返回的图片链接地址
|
||||||
quill.setSelection(length + 1);
|
quill.insertEmbed(length, "image", import.meta.env.VITE_APP_BASE_API + res.fileName);
|
||||||
|
// 调整光标到最后
|
||||||
|
quill.setSelection(length + 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError("图片插入失败");
|
modal.msgError("图片插入失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传失败处理
|
// 上传失败处理
|
||||||
function handleUploadError() {
|
function handleUploadError() {
|
||||||
proxy.$modal.msgError("图片插入失败");
|
modal.msgError("图片插入失败");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -174,78 +168,98 @@ function handleUploadError() {
|
|||||||
.editor-img-uploader {
|
.editor-img-uploader {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.editor, .ql-toolbar {
|
|
||||||
|
.editor,
|
||||||
|
.ql-toolbar {
|
||||||
white-space: pre-wrap !important;
|
white-space: pre-wrap !important;
|
||||||
line-height: normal !important;
|
line-height: normal !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quill-img {
|
.quill-img {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-tooltip[data-mode="link"]::before {
|
.ql-snow .ql-tooltip[data-mode="link"]::before {
|
||||||
content: "请输入链接地址:";
|
content: "请输入链接地址:";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
|
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
|
||||||
border-right: 0px;
|
border-right: 0px;
|
||||||
content: "保存";
|
content: "保存";
|
||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-tooltip[data-mode="video"]::before {
|
.ql-snow .ql-tooltip[data-mode="video"]::before {
|
||||||
content: "请输入视频地址:";
|
content: "请输入视频地址:";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
|
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
||||||
content: "14px";
|
content: "14px";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
|
||||||
content: "10px";
|
content: "10px";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
|
||||||
content: "18px";
|
content: "18px";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
|
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
|
||||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
|
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
|
||||||
content: "32px";
|
content: "32px";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
|
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
|
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
|
||||||
content: "文本";
|
content: "文本";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
|
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
|
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
|
||||||
content: "标题1";
|
content: "标题1";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
|
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
|
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
|
||||||
content: "标题2";
|
content: "标题2";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
|
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
|
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
|
||||||
content: "标题3";
|
content: "标题3";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
|
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
|
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
|
||||||
content: "标题4";
|
content: "标题4";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
|
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
|
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
|
||||||
content: "标题5";
|
content: "标题5";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
|
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
|
||||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
|
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
|
||||||
content: "标题6";
|
content: "标题6";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
||||||
content: "标准字体";
|
content: "标准字体";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
|
||||||
content: "衬线字体";
|
content: "衬线字体";
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
|
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
|
||||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
|
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
|
||||||
content: "等宽字体";
|
content: "等宽字体";
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -39,7 +39,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref, computed, watch } from 'vue';
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth";
|
||||||
|
import modal from '@/plugins/modal';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: [String, Object, Array],
|
modelValue: [String, Object, Array],
|
||||||
@@ -65,7 +67,7 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const fileUpload = ref(null);
|
||||||
const emit = defineEmits();
|
const emit = defineEmits();
|
||||||
const number = ref(0);
|
const number = ref(0);
|
||||||
const uploadList = ref([]);
|
const uploadList = ref([]);
|
||||||
@@ -104,7 +106,7 @@ function handleBeforeUpload(file) {
|
|||||||
const fileExt = fileName[fileName.length - 1];
|
const fileExt = fileName[fileName.length - 1];
|
||||||
const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
|
const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
|
||||||
if (!isTypeOk) {
|
if (!isTypeOk) {
|
||||||
proxy.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`);
|
modal.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,23 +114,23 @@ function handleBeforeUpload(file) {
|
|||||||
if (props.fileSize) {
|
if (props.fileSize) {
|
||||||
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
||||||
if (!isLt) {
|
if (!isLt) {
|
||||||
proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
|
modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proxy.$modal.loading("正在上传文件,请稍候...");
|
modal.loading("正在上传文件,请稍候...");
|
||||||
number.value++;
|
number.value++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件个数超出
|
// 文件个数超出
|
||||||
function handleExceed() {
|
function handleExceed() {
|
||||||
proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
|
modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传失败
|
// 上传失败
|
||||||
function handleUploadError(err) {
|
function handleUploadError(err) {
|
||||||
proxy.$modal.msgError("上传文件失败");
|
modal.msgError("上传文件失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传成功回调
|
// 上传成功回调
|
||||||
@@ -138,9 +140,9 @@ function handleUploadSuccess(res, file) {
|
|||||||
uploadedSuccessfully();
|
uploadedSuccessfully();
|
||||||
} else {
|
} else {
|
||||||
number.value--;
|
number.value--;
|
||||||
proxy.$modal.closeLoading();
|
modal.closeLoading();
|
||||||
proxy.$modal.msgError(res.msg);
|
modal.msgError(res.msg);
|
||||||
proxy.$refs.fileUpload.handleRemove(file);
|
fileUpload.value.handleRemove(file);
|
||||||
uploadedSuccessfully();
|
uploadedSuccessfully();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,7 +160,7 @@ function uploadedSuccessfully() {
|
|||||||
uploadList.value = [];
|
uploadList.value = [];
|
||||||
number.value = 0;
|
number.value = 0;
|
||||||
emit("update:modelValue", listToString(fileList.value));
|
emit("update:modelValue", listToString(fileList.value));
|
||||||
proxy.$modal.closeLoading();
|
modal.closeLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,4 +206,4 @@ function listToString(list, separator) {
|
|||||||
.ele-upload-list__item-content-action .el-link {
|
.ele-upload-list__item-content-action .el-link {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -47,6 +47,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth";
|
||||||
|
import { ref, computed, watch, getCurrentInstance } from 'vue';
|
||||||
|
import modal from '@/plugins/modal';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: [String, Object, Array],
|
modelValue: [String, Object, Array],
|
||||||
@@ -72,7 +74,6 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
|
||||||
const emit = defineEmits();
|
const emit = defineEmits();
|
||||||
const number = ref(0);
|
const number = ref(0);
|
||||||
const uploadList = ref([]);
|
const uploadList = ref([]);
|
||||||
@@ -82,6 +83,7 @@ const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
|||||||
const uploadImgUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址
|
const uploadImgUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传的图片服务器地址
|
||||||
const headers = ref({ Authorization: "Bearer " + getToken() });
|
const headers = ref({ Authorization: "Bearer " + getToken() });
|
||||||
const fileList = ref([]);
|
const fileList = ref([]);
|
||||||
|
const imageUpload = ref(null);
|
||||||
const showTip = computed(
|
const showTip = computed(
|
||||||
() => props.isShowTip && (props.fileType || props.fileSize)
|
() => props.isShowTip && (props.fileType || props.fileSize)
|
||||||
);
|
);
|
||||||
@@ -124,7 +126,7 @@ function handleBeforeUpload(file) {
|
|||||||
isImg = file.type.indexOf("image") > -1;
|
isImg = file.type.indexOf("image") > -1;
|
||||||
}
|
}
|
||||||
if (!isImg) {
|
if (!isImg) {
|
||||||
proxy.$modal.msgError(
|
modal.msgError(
|
||||||
`文件格式不正确, 请上传${props.fileType.join("/")}图片格式文件!`
|
`文件格式不正确, 请上传${props.fileType.join("/")}图片格式文件!`
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
@@ -132,17 +134,17 @@ function handleBeforeUpload(file) {
|
|||||||
if (props.fileSize) {
|
if (props.fileSize) {
|
||||||
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
const isLt = file.size / 1024 / 1024 < props.fileSize;
|
||||||
if (!isLt) {
|
if (!isLt) {
|
||||||
proxy.$modal.msgError(`上传头像图片大小不能超过 ${props.fileSize} MB!`);
|
modal.msgError(`上传头像图片大小不能超过 ${props.fileSize} MB!`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proxy.$modal.loading("正在上传图片,请稍候...");
|
modal.loading("正在上传图片,请稍候...");
|
||||||
number.value++;
|
number.value++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件个数超出
|
// 文件个数超出
|
||||||
function handleExceed() {
|
function handleExceed() {
|
||||||
proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
|
modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传成功回调
|
// 上传成功回调
|
||||||
@@ -152,9 +154,9 @@ function handleUploadSuccess(res, file) {
|
|||||||
uploadedSuccessfully();
|
uploadedSuccessfully();
|
||||||
} else {
|
} else {
|
||||||
number.value--;
|
number.value--;
|
||||||
proxy.$modal.closeLoading();
|
modal.closeLoading();
|
||||||
proxy.$modal.msgError(res.msg);
|
modal.msgError(res.msg);
|
||||||
proxy.$refs.imageUpload.handleRemove(file);
|
imageUpload.value.handleRemove(file);
|
||||||
uploadedSuccessfully();
|
uploadedSuccessfully();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,14 +178,14 @@ function uploadedSuccessfully() {
|
|||||||
uploadList.value = [];
|
uploadList.value = [];
|
||||||
number.value = 0;
|
number.value = 0;
|
||||||
emit("update:modelValue", listToString(fileList.value));
|
emit("update:modelValue", listToString(fileList.value));
|
||||||
proxy.$modal.closeLoading();
|
modal.closeLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传失败
|
// 上传失败
|
||||||
function handleUploadError() {
|
function handleUploadError() {
|
||||||
proxy.$modal.msgError("上传图片失败");
|
modal.msgError("上传图片失败");
|
||||||
proxy.$modal.closeLoading();
|
modal.closeLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预览
|
// 预览
|
||||||
|
|||||||
@@ -29,8 +29,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref, computed, watch, onMounted, nextTick } from 'vue';
|
||||||
|
import { getCurrentInstance } from 'vue';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const selectTree = ref(null);
|
||||||
|
const treeSelect = ref(null);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
/* 配置项 */
|
/* 配置项 */
|
||||||
@@ -83,10 +86,10 @@ function initHandle() {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const selectedValue = valueId.value;
|
const selectedValue = valueId.value;
|
||||||
if(selectedValue !== null && typeof (selectedValue) !== 'undefined') {
|
if(selectedValue !== null && typeof (selectedValue) !== 'undefined') {
|
||||||
const node = proxy.$refs.selectTree.getNode(selectedValue)
|
const node = selectTree.value.getNode(selectedValue)
|
||||||
if (node) {
|
if (node) {
|
||||||
valueTitle.value = node.data[props.objMap.label]
|
valueTitle.value = node.data[props.objMap.label]
|
||||||
proxy.$refs.selectTree.setCurrentKey(selectedValue) // 设置默认选中
|
selectTree.value.setCurrentKey(selectedValue) // 设置默认选中
|
||||||
defaultExpandedKey.value = [selectedValue] // 设置默认展开
|
defaultExpandedKey.value = [selectedValue] // 设置默认展开
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -98,11 +101,11 @@ function handleNodeClick(node) {
|
|||||||
valueTitle.value = node[props.objMap.label]
|
valueTitle.value = node[props.objMap.label]
|
||||||
valueId.value = node[props.objMap.value];
|
valueId.value = node[props.objMap.value];
|
||||||
defaultExpandedKey.value = [];
|
defaultExpandedKey.value = [];
|
||||||
proxy.$refs.treeSelect.blur()
|
treeSelect.value.blur()
|
||||||
selectFilterData('')
|
selectFilterData('')
|
||||||
}
|
}
|
||||||
function selectFilterData(val) {
|
function selectFilterData(val) {
|
||||||
proxy.$refs.selectTree.filter(val)
|
selectTree.value.filter(val)
|
||||||
}
|
}
|
||||||
function filterNode(value, data) {
|
function filterNode(value, data) {
|
||||||
if (!value) return true
|
if (!value) return true
|
||||||
|
|||||||
@@ -85,6 +85,14 @@ function resolvePath(routePath, routeQuery) {
|
|||||||
if (isExternal(props.basePath)) {
|
if (isExternal(props.basePath)) {
|
||||||
return props.basePath
|
return props.basePath
|
||||||
}
|
}
|
||||||
|
// 特殊处理门诊医生站路径,确保路径正确
|
||||||
|
if (routePath === '/doctorstation' || routePath === 'doctorstation') {
|
||||||
|
if (routeQuery) {
|
||||||
|
let query = JSON.parse(routeQuery);
|
||||||
|
return { path: '/doctorstation', query: query }
|
||||||
|
}
|
||||||
|
return '/doctorstation'
|
||||||
|
}
|
||||||
if (routeQuery) {
|
if (routeQuery) {
|
||||||
let query = JSON.parse(routeQuery);
|
let query = JSON.parse(routeQuery);
|
||||||
return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
|
return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
|
||||||
|
|||||||
@@ -1,11 +1,30 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
|
|
||||||
|
// 修复 util._extend 已弃用警告(仅在 Node.js 环境中需要)
|
||||||
|
if (typeof process !== 'undefined' && process.versions && process.versions.node) {
|
||||||
|
try {
|
||||||
|
import('util').then(util => {
|
||||||
|
if (!util._extend) {
|
||||||
|
util._extend = function(destination, source) {
|
||||||
|
for (var key in source) {
|
||||||
|
if (source.hasOwnProperty(key)) {
|
||||||
|
destination[key] = source[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destination;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('util._extend 补丁加载失败:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
||||||
import 'element-plus/dist/index.css'
|
import 'element-plus/dist/index.css'
|
||||||
import locale from 'element-plus/es/locale/lang/zh-cn'
|
|
||||||
|
|
||||||
import '@/assets/styles/index.scss' // global css
|
import '@/assets/styles/index.scss' // global css
|
||||||
|
|
||||||
@@ -84,8 +103,14 @@ app.component('ImageUpload', ImageUpload)
|
|||||||
app.component('ImagePreview', ImagePreview)
|
app.component('ImagePreview', ImagePreview)
|
||||||
app.component('RightToolbar', RightToolbar)
|
app.component('RightToolbar', RightToolbar)
|
||||||
app.component('Editor', Editor)
|
app.component('Editor', Editor)
|
||||||
app.use(registerComponents)
|
// 使用element-plus 并且设置全局的大小
|
||||||
|
app.use(ElementPlus, {
|
||||||
|
locale: zhCn,
|
||||||
|
// 支持 large、default、small
|
||||||
|
size: Cookies.get('size') || 'default'
|
||||||
|
})
|
||||||
app.use(ElMessage)
|
app.use(ElMessage)
|
||||||
|
app.use(registerComponents)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(store)
|
app.use(store)
|
||||||
app.use(plugins)
|
app.use(plugins)
|
||||||
@@ -94,11 +119,5 @@ app.component('svg-icon', SvgIcon)
|
|||||||
directive(app)
|
directive(app)
|
||||||
// 全局禁止点击遮罩层关闭弹窗
|
// 全局禁止点击遮罩层关闭弹窗
|
||||||
ElDialog.props.closeOnClickModal.default = false;
|
ElDialog.props.closeOnClickModal.default = false;
|
||||||
// 使用element-plus 并且设置全局的大小
|
|
||||||
app.use(ElementPlus, {
|
|
||||||
locale: zhCn,
|
|
||||||
// 支持 large、default、small
|
|
||||||
size: Cookies.get('size') || 'default'
|
|
||||||
})
|
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
@@ -33,7 +33,10 @@ router.beforeEach((to, from, next) => {
|
|||||||
// 根据roles权限生成可访问的路由表
|
// 根据roles权限生成可访问的路由表
|
||||||
accessRoutes.forEach(route => {
|
accessRoutes.forEach(route => {
|
||||||
if (!isHttp(route.path)) {
|
if (!isHttp(route.path)) {
|
||||||
router.addRoute(route) // 动态添加可访问路由表
|
// 检查是否已经存在同名路由
|
||||||
|
if (!router.hasRoute(route.name)) {
|
||||||
|
router.addRoute(route) // 动态添加可访问路由表
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
||||||
@@ -62,4 +65,4 @@ router.beforeEach((to, from, next) => {
|
|||||||
|
|
||||||
router.afterEach(() => {
|
router.afterEach(() => {
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
})
|
})
|
||||||
@@ -3,30 +3,45 @@ import { createWebHistory, createRouter } from 'vue-router'
|
|||||||
import Layout from '@/layout'
|
import Layout from '@/layout'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: 路由配置项
|
* Note: 路由配置项说明
|
||||||
*
|
*
|
||||||
* hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
|
* hidden: true // 当设置 true 时,该路由不会在侧边栏出现(如401、login等页面,或一些编辑页面/edit/1)
|
||||||
* alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
|
* alwaysShow: true // 当路由下的 children 声明的路由大于1个时,自动变为嵌套模式(如组件页面)
|
||||||
* // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
|
* // 只有一个时,会将子路由作为根路由显示在侧边栏(如引导页面)
|
||||||
* // 若你想不管路由下面的 children 声明的个数都显示你的根路由
|
* // 若想不管 children 个数都显示根路由,可设置 alwaysShow: true,忽略之前定义的规则
|
||||||
* // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
|
* redirect: noRedirect // 当设置 noRedirect 时,该路由在面包屑导航中不可点击
|
||||||
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
|
* name:'router-name' // 设定路由的名字,必须填写,否则使用<keep-alive>时会出现问题
|
||||||
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
|
|
||||||
* query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
|
* query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
|
||||||
* roles: ['admin', 'common'] // 访问路由的角色权限
|
* roles: ['admin', 'common'] // 访问路由的角色权限
|
||||||
* permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限
|
* permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限
|
||||||
* meta : {
|
* meta: {
|
||||||
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
|
||||||
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
|
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
|
||||||
icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg
|
icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg
|
||||||
breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示
|
breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示
|
||||||
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
|
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮对应的侧边栏
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 公共路由
|
// 公共路由 - 所有用户均可访问的路由
|
||||||
export const constantRoutes = [
|
export const constantRoutes = [
|
||||||
{ path: '/appoinmentmanage', component: Layout, redirect: '/appoinmentmanage', name: 'AppoinmentManage', hidden: true, meta: { title: '预约管理', icon: 'component' }, children: [{ path: '', component: () => import('@/views/appoinmentmanage/index.vue'), name: 'AppoinmentManageIndex', meta: { title: '预约管理' } }, { path: 'doctorschedule/:deptId', component: () => import('@/views/appoinmentmanage/doctorschedule/index.vue'), name: 'DoctorSchedule', hidden: true, meta: { title: '医生排班' } }] },
|
// 门诊医生站路由
|
||||||
|
{
|
||||||
|
path: '/doctorstation',
|
||||||
|
component: Layout,
|
||||||
|
redirect: '/doctorstation',
|
||||||
|
name: 'DoctorStation',
|
||||||
|
meta: { title: '门诊医生站', icon: 'doctorstation' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: () => import('@/views/doctorstation/index.vue'),
|
||||||
|
name: 'DoctorStationIndex',
|
||||||
|
meta: { title: '门诊医生站', icon: 'doctorstation' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// 重定向路由
|
||||||
{
|
{
|
||||||
path: '/redirect',
|
path: '/redirect',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -38,21 +53,25 @@ export const constantRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 登录路由
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
component: () => import('@/views/login'),
|
component: () => import('@/views/login'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
// 注册路由
|
||||||
{
|
{
|
||||||
path: '/register',
|
path: '/register',
|
||||||
component: () => import('@/views/register'),
|
component: () => import('@/views/register'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
// 401权限不足路由
|
||||||
{
|
{
|
||||||
path: '/401',
|
path: '/401',
|
||||||
component: () => import('@/views/error/401'),
|
component: () => import('@/views/error/401'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
// 首页路由
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -66,6 +85,7 @@ export const constantRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 个人中心路由
|
||||||
{
|
{
|
||||||
path: '/user',
|
path: '/user',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -80,7 +100,7 @@ export const constantRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
// 添加套餐管理相关路由到公共路由,确保始终可用
|
// 套餐管理相关路由 - 添加到公共路由确保始终可用
|
||||||
{
|
{
|
||||||
path: '/maintainSystem/Inspection/PackageManagement',
|
path: '/maintainSystem/Inspection/PackageManagement',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -93,11 +113,26 @@ export const constantRoutes = [
|
|||||||
meta: { title: '套餐管理' }
|
meta: { title: '套餐管理' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
// 预约管理直接访问路由 - 兼容外部系统访问
|
||||||
|
{
|
||||||
|
path: '/reservationRecord2/appoinmentmanage',
|
||||||
|
component: Layout,
|
||||||
|
hidden: true,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: () => import('@/views/appoinmentmanage/clinicRoom/index.vue'),
|
||||||
|
name: 'DirectClinicRoom',
|
||||||
|
meta: { title: '门诊出诊医生诊室设置' }
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
// 动态路由,基于用户权限动态去加载
|
// 动态路由 - 基于用户权限动态加载的路由
|
||||||
export const dynamicRoutes = [
|
export const dynamicRoutes = [
|
||||||
|
// 基础管理路由
|
||||||
{
|
{
|
||||||
path: '/basicmanage',
|
path: '/basicmanage',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -113,7 +148,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
// 兼容系统业务管理路径
|
// 兼容系统业务管理路径的发票管理路由
|
||||||
{
|
{
|
||||||
path: '/system/ywgz',
|
path: '/system/ywgz',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -128,6 +163,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 维护系统路由
|
||||||
{
|
{
|
||||||
path: '/maintainSystem',
|
path: '/maintainSystem',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -137,22 +173,23 @@ export const dynamicRoutes = [
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
redirect: 'chargeConfig'
|
redirect: 'chargeConfig',
|
||||||
|
name: 'MaintainSystemIndex' // 添加名称以解决警告
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'chargeConfig',
|
path: 'chargeConfig', // 收费配置路由
|
||||||
component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
||||||
name: 'ChargeConfig',
|
name: 'ChargeConfig',
|
||||||
meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'Inspection',
|
path: 'Inspection', // 检验管理路由
|
||||||
component: () => import('@/views/maintainSystem/Inspection/index.vue'),
|
component: () => import('@/views/maintainSystem/Inspection/index.vue'),
|
||||||
name: 'Inspection',
|
name: 'Inspection',
|
||||||
meta: { title: '检验管理', icon: 'inspection' },
|
meta: { title: '检验管理', icon: 'inspection' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'PackageManagement',
|
path: 'PackageManagement', // 套餐管理路由
|
||||||
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||||
name: 'PackageManagement',
|
name: 'PackageManagement',
|
||||||
meta: { title: '套餐管理' }
|
meta: { title: '套餐管理' }
|
||||||
@@ -161,6 +198,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 系统管理路由
|
||||||
{
|
{
|
||||||
path: '/system',
|
path: '/system',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -169,61 +207,62 @@ export const dynamicRoutes = [
|
|||||||
meta: { title: '系统管理', icon: 'system' },
|
meta: { title: '系统管理', icon: 'system' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'user',
|
path: 'user', // 用户管理路由
|
||||||
component: () => import('@/views/system/user/index.vue'),
|
component: () => import('@/views/system/user/index.vue'),
|
||||||
name: 'User',
|
name: 'User',
|
||||||
meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] }
|
meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'role',
|
path: 'role', // 角色管理路由
|
||||||
component: () => import('@/views/system/role/index.vue'),
|
component: () => import('@/views/system/role/index.vue'),
|
||||||
name: 'Role',
|
name: 'Role',
|
||||||
meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] }
|
meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'menu',
|
path: 'menu', // 菜单管理路由
|
||||||
component: () => import('@/views/system/menu/index.vue'),
|
component: () => import('@/views/system/menu/index.vue'),
|
||||||
name: 'Menu',
|
name: 'Menu',
|
||||||
meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] }
|
meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dept',
|
path: 'dept', // 部门管理路由
|
||||||
component: () => import('@/views/system/dept/index.vue'),
|
component: () => import('@/views/system/dept/index.vue'),
|
||||||
name: 'Dept',
|
name: 'Dept',
|
||||||
meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] }
|
meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'post',
|
path: 'post', // 岗位管理路由
|
||||||
component: () => import('@/views/system/post/index.vue'),
|
component: () => import('@/views/system/post/index.vue'),
|
||||||
name: 'Post',
|
name: 'Post',
|
||||||
meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] }
|
meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dict',
|
path: 'dict', // 字典管理路由
|
||||||
component: () => import('@/views/system/dict/index.vue'),
|
component: () => import('@/views/system/dict/index.vue'),
|
||||||
name: 'Dict',
|
name: 'Dict',
|
||||||
meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] }
|
meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'config',
|
path: 'config', // 参数配置路由
|
||||||
component: () => import('@/views/system/config/index.vue'),
|
component: () => import('@/views/system/config/index.vue'),
|
||||||
name: 'Config',
|
name: 'Config',
|
||||||
meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] }
|
meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'notice',
|
path: 'notice', // 通知公告路由
|
||||||
component: () => import('@/views/system/notice/index.vue'),
|
component: () => import('@/views/system/notice/index.vue'),
|
||||||
name: 'Notice',
|
name: 'Notice',
|
||||||
meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] }
|
meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'tenant',
|
path: 'tenant', // 租户管理路由
|
||||||
component: () => import('@/views/system/tenant/index.vue'),
|
component: () => import('@/views/system/tenant/index.vue'),
|
||||||
name: 'Tenant',
|
name: 'Tenant',
|
||||||
meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] }
|
meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 租户用户设置路由
|
||||||
{
|
{
|
||||||
path: '/system/tenant-user',
|
path: '/system/tenant-user',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -238,6 +277,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 租户合同管理路由
|
||||||
{
|
{
|
||||||
path: '/system/tenant-contract',
|
path: '/system/tenant-contract',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -252,6 +292,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 用户角色分配路由
|
||||||
{
|
{
|
||||||
path: '/system/user-auth',
|
path: '/system/user-auth',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -266,6 +307,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 角色用户分配路由
|
||||||
{
|
{
|
||||||
path: '/system/role-auth',
|
path: '/system/role-auth',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -280,6 +322,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 字典数据路由
|
||||||
{
|
{
|
||||||
path: '/system/dict-data',
|
path: '/system/dict-data',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -294,6 +337,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 系统监控路由
|
||||||
{
|
{
|
||||||
path: '/monitor',
|
path: '/monitor',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -302,25 +346,26 @@ export const dynamicRoutes = [
|
|||||||
meta: { title: '系统监控', icon: 'monitor' },
|
meta: { title: '系统监控', icon: 'monitor' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'operlog',
|
path: 'operlog', // 操作日志路由
|
||||||
component: () => import('@/views/monitor/operlog/index.vue'),
|
component: () => import('@/views/monitor/operlog/index.vue'),
|
||||||
name: 'Operlog',
|
name: 'Operlog',
|
||||||
meta: { title: '操作日志', icon: 'operlog', permissions: ['monitor:operlog:list'] }
|
meta: { title: '操作日志', icon: 'operlog', permissions: ['monitor:operlog:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'logininfor',
|
path: 'logininfor', // 登录日志路由
|
||||||
component: () => import('@/views/monitor/logininfor/index.vue'),
|
component: () => import('@/views/monitor/logininfor/index.vue'),
|
||||||
name: 'Logininfor',
|
name: 'Logininfor',
|
||||||
meta: { title: '登录日志', icon: 'logininfor', permissions: ['monitor:logininfor:list'] }
|
meta: { title: '登录日志', icon: 'logininfor', permissions: ['monitor:logininfor:list'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'job',
|
path: 'job', // 定时任务路由
|
||||||
component: () => import('@/views/monitor/job/index.vue'),
|
component: () => import('@/views/monitor/job/index.vue'),
|
||||||
name: 'Job',
|
name: 'Job',
|
||||||
meta: { title: '定时任务', icon: 'job', permissions: ['monitor:job:list'] }
|
meta: { title: '定时任务', icon: 'job', permissions: ['monitor:job:list'] }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 系统工具路由
|
||||||
{
|
{
|
||||||
path: '/tool',
|
path: '/tool',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -329,13 +374,14 @@ export const dynamicRoutes = [
|
|||||||
meta: { title: '系统工具', icon: 'tool' },
|
meta: { title: '系统工具', icon: 'tool' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'gen',
|
path: 'gen', // 代码生成路由
|
||||||
component: () => import('@/views/tool/gen/index.vue'),
|
component: () => import('@/views/tool/gen/index.vue'),
|
||||||
name: 'Gen',
|
name: 'Gen',
|
||||||
meta: { title: '代码生成', icon: 'gen', permissions: ['tool:gen:list'] }
|
meta: { title: '代码生成', icon: 'gen', permissions: ['tool:gen:list'] }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 定时任务日志路由
|
||||||
{
|
{
|
||||||
path: '/monitor/job-log',
|
path: '/monitor/job-log',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -350,6 +396,7 @@ export const dynamicRoutes = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 代码生成编辑路由
|
||||||
{
|
{
|
||||||
path: '/tool/gen-edit',
|
path: '/tool/gen-edit',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -369,17 +416,19 @@ export const dynamicRoutes = [
|
|||||||
// 合并常量路由和动态路由,确保所有路由都能被访问
|
// 合并常量路由和动态路由,确保所有路由都能被访问
|
||||||
const allRoutes = [...constantRoutes, ...dynamicRoutes];
|
const allRoutes = [...constantRoutes, ...dynamicRoutes];
|
||||||
|
|
||||||
// 添加404路由到所有路由的最后
|
// 添加404路由到所有路由的最后,确保捕获所有未匹配的路由
|
||||||
allRoutes.push({
|
allRoutes.push({
|
||||||
path: "/:pathMatch(.*)*",
|
path: "/:pathMatch(.*)*",
|
||||||
component: () => import('@/views/error/404'),
|
component: () => import('@/views/error/404'),
|
||||||
hidden: true
|
hidden: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 创建Vue Router实例
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: createWebHistory(), // 使用HTML5历史模式
|
||||||
routes: allRoutes,
|
routes: allRoutes, // 使用合并后的所有路由
|
||||||
scrollBehavior(to, from, savedPosition) {
|
scrollBehavior(to, from, savedPosition) {
|
||||||
|
// 页面滚动行为:如果有保存的位置则恢复,否则滚动到顶部
|
||||||
if (savedPosition) {
|
if (savedPosition) {
|
||||||
return savedPosition
|
return savedPosition
|
||||||
} else {
|
} else {
|
||||||
@@ -388,4 +437,5 @@ const router = createRouter({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
// 导出路由实例
|
||||||
|
export default router;
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<!-- 跌倒/坠床评估护理记录单主容器 -->
|
||||||
<div>
|
<div>
|
||||||
<div class="business">
|
<div class="business">
|
||||||
|
<!-- 已有记录展示表格 -->
|
||||||
<el-table
|
<el-table
|
||||||
:data="tableDataSource"
|
:data="tableDataSource"
|
||||||
border
|
border
|
||||||
@@ -8,10 +10,15 @@
|
|||||||
fit
|
fit
|
||||||
:header-cell-style="{ background: '#f2f2f2', color: 'black' }"
|
:header-cell-style="{ background: '#f2f2f2', color: 'black' }"
|
||||||
>
|
>
|
||||||
|
<!-- 记录时间列 -->
|
||||||
<el-table-column prop="content.recordTime" label="记录时间" />
|
<el-table-column prop="content.recordTime" label="记录时间" />
|
||||||
|
<!-- 评估分数列 -->
|
||||||
<el-table-column prop="content.totalScore" label="评估分数" />
|
<el-table-column prop="content.totalScore" label="评估分数" />
|
||||||
|
<!-- 护理措施列 -->
|
||||||
<el-table-column prop="content.patientCareSessionsTableList" label="护理措施" />
|
<el-table-column prop="content.patientCareSessionsTableList" label="护理措施" />
|
||||||
|
<!-- 责任护士列 -->
|
||||||
<el-table-column prop="content.nurseSignature" label="责任护士" />
|
<el-table-column prop="content.nurseSignature" label="责任护士" />
|
||||||
|
<!-- 操作列:编辑和删除按钮 -->
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -36,9 +43,12 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 跌倒/坠床评估护理记录单表单区域 -->
|
||||||
<div name="跌倒/坠床评估护理记录单" class="changeMajor" style="width: 99.9%">
|
<div name="跌倒/坠床评估护理记录单" class="changeMajor" style="width: 99.9%">
|
||||||
<div>
|
<div>
|
||||||
|
<!-- 表单主体 -->
|
||||||
<el-form ref="formRef" :model="form" style="width: 99.9%">
|
<el-form ref="formRef" :model="form" style="width: 99.9%">
|
||||||
|
<!-- 标题行 -->
|
||||||
<el-form-item style="text-align: center">
|
<el-form-item style="text-align: center">
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
@@ -54,10 +64,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 日期时间选择器 -->
|
||||||
<el-form-item label="日期:" class="changeMajorFromItem" style="width: 100%">
|
<el-form-item label="日期:" class="changeMajorFromItem" style="width: 100%">
|
||||||
<el-row :span="20">
|
<el-row :span="20">
|
||||||
<el-col :span="8" style="padding-left: 0px !important">
|
<el-col :span="8" style="padding-left: 0px !important">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
<!-- 日期时间选择器 -->
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="form.ZKDATE"
|
v-model="form.ZKDATE"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
@@ -67,6 +79,7 @@
|
|||||||
style="width: 800px"
|
style="width: 800px"
|
||||||
:disabled="admissionDataForm !== undefined"
|
:disabled="admissionDataForm !== undefined"
|
||||||
/>
|
/>
|
||||||
|
<!-- 时间选择器被注释掉 -->
|
||||||
<!-- <span style="margin-left: 5px">时间:</span>
|
<!-- <span style="margin-left: 5px">时间:</span>
|
||||||
<el-time-picker
|
<el-time-picker
|
||||||
v-model="form.ZKTIME"
|
v-model="form.ZKTIME"
|
||||||
@@ -77,6 +90,7 @@
|
|||||||
/> -->
|
/> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<!-- 新增/保存按钮 -->
|
||||||
<el-col :span="5">
|
<el-col :span="5">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="!updateFlag"
|
v-if="!updateFlag"
|
||||||
@@ -100,6 +114,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 危险因素评估表格 -->
|
||||||
<el-form-item style="padding-top: 10px; margin: 0px !important">
|
<el-form-item style="padding-top: 10px; margin: 0px !important">
|
||||||
<el-table
|
<el-table
|
||||||
:data="dangerData"
|
:data="dangerData"
|
||||||
@@ -107,6 +122,7 @@
|
|||||||
:span-method="handleSpan"
|
:span-method="handleSpan"
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
>
|
||||||
|
<!-- 动态生成表格列 -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="column in dangerColumns"
|
v-for="column in dangerColumns"
|
||||||
:key="column.key"
|
:key="column.key"
|
||||||
@@ -115,6 +131,7 @@
|
|||||||
:label="column.title"
|
:label="column.title"
|
||||||
align="center"
|
align="center"
|
||||||
/>
|
/>
|
||||||
|
<!-- 选择列(复选框) -->
|
||||||
<el-table-column prop="id" label="选择" width="80" align="center">
|
<el-table-column prop="id" label="选择" width="80" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox v-model="row.checked" @change="handleDangerChange(row)" />
|
<el-checkbox v-model="row.checked" @change="handleDangerChange(row)" />
|
||||||
@@ -123,6 +140,7 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 总分显示 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
style="text-align: center; margin-bottom: 0px; padding: 0px"
|
style="text-align: center; margin-bottom: 0px; padding: 0px"
|
||||||
class="changeMajorFromItem"
|
class="changeMajorFromItem"
|
||||||
@@ -135,6 +153,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 护理措施表格 -->
|
||||||
<el-form-item style="padding-top: 10px">
|
<el-form-item style="padding-top: 10px">
|
||||||
<el-table
|
<el-table
|
||||||
:data="nursingData"
|
:data="nursingData"
|
||||||
@@ -142,6 +161,7 @@
|
|||||||
:span-method="arraySpanMethod"
|
:span-method="arraySpanMethod"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
|
<!-- 动态生成表格列 -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="column in nursingColumns"
|
v-for="column in nursingColumns"
|
||||||
:key="column.key"
|
:key="column.key"
|
||||||
@@ -150,6 +170,7 @@
|
|||||||
:label="column.title"
|
:label="column.title"
|
||||||
align="center"
|
align="center"
|
||||||
/>
|
/>
|
||||||
|
<!-- 选择列(复选框) -->
|
||||||
<el-table-column prop="id" label="选择" width="80" align="center">
|
<el-table-column prop="id" label="选择" width="80" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox v-model="row.checked" @change="handleNursingChange(row)" />
|
<el-checkbox v-model="row.checked" @change="handleNursingChange(row)" />
|
||||||
@@ -158,6 +179,7 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 护士签字输入框 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
style="text-align: center; margin-bottom: 0px; padding: 0px"
|
style="text-align: center; margin-bottom: 0px; padding: 0px"
|
||||||
class="changeMajorFromItem"
|
class="changeMajorFromItem"
|
||||||
@@ -177,6 +199,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 备注信息 -->
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-row :span="20">
|
<el-row :span="20">
|
||||||
<el-col :span="5">
|
<el-col :span="5">
|
||||||
@@ -197,22 +220,24 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
// 组件选项定义
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'FallBedFallAssessment',
|
name: '跌倒/坠床评估护理记录单',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 导入所需模块
|
||||||
import { ref, reactive, computed, onMounted } from 'vue';
|
import { ref, reactive, computed, onMounted } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
// import { webapp_ws_ajax_run, urlAddRandomNo } from '@/utils/grwebapp';
|
// 使用路由相关功能
|
||||||
// import { useRoute, useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
// 响应式数据
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
// 定义引用变量
|
||||||
const queryRef = ref();
|
const queryRef = ref();
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
|
||||||
|
// 基本数据变量
|
||||||
const wardCode = ref('');
|
const wardCode = ref('');
|
||||||
const patientId = ref('');
|
const patientId = ref('');
|
||||||
const visitId = ref('');
|
const visitId = ref('');
|
||||||
@@ -226,17 +251,18 @@ const totalScore = ref(0);
|
|||||||
const lastSubmit = ref('');
|
const lastSubmit = ref('');
|
||||||
const admissionDataForm = ref(route.params.admissionData);
|
const admissionDataForm = ref(route.params.admissionData);
|
||||||
|
|
||||||
|
// 表单数据模型
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
ZKDATE: '',
|
ZKDATE: '', // 日期
|
||||||
ZKTIME: '',
|
ZKTIME: '', // 时间
|
||||||
recordTime: '',
|
recordTime: '', // 记录时间
|
||||||
totalScore: 0,
|
totalScore: 0, // 总分
|
||||||
bedFallRiskAssessmentList: [],
|
bedFallRiskAssessmentList: [], // 跌倒风险评估列表
|
||||||
nurseSignature: '',
|
nurseSignature: '', // 护士签名
|
||||||
patientCareSessionsCheckedList: [],
|
patientCareSessionsCheckedList: [], // 护理措施选中列表
|
||||||
});
|
});
|
||||||
|
|
||||||
// 危险因素表格列
|
// 危险因素表格列配置
|
||||||
const dangerColumns = [
|
const dangerColumns = [
|
||||||
{
|
{
|
||||||
key: 'content',
|
key: 'content',
|
||||||
@@ -301,7 +327,7 @@ const dangerData = ref([
|
|||||||
{ id: '27', evalContent: '麻醉止痛剂', score: 2, checked: false },
|
{ id: '27', evalContent: '麻醉止痛剂', score: 2, checked: false },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 护理措施表格列
|
// 护理措施表格列配置
|
||||||
const nursingColumns = [
|
const nursingColumns = [
|
||||||
{
|
{
|
||||||
key: 'content',
|
key: 'content',
|
||||||
@@ -338,21 +364,21 @@ const instructions = [
|
|||||||
'3.评分≥5,高度风险,每周至少评估一次,需采取适宜的预防措施,同时填写《预防患者跌倒/坠床知情告知书》',
|
'3.评分≥5,高度风险,每周至少评估一次,需采取适宜的预防措施,同时填写《预防患者跌倒/坠床知情告知书》',
|
||||||
];
|
];
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性:计算选中的危险因素总分
|
||||||
const calculate = computed(() => {
|
const calculate = computed(() => {
|
||||||
return dangerData.value
|
return dangerData.value
|
||||||
.filter((option) => option.checked)
|
.filter((option) => option.checked)
|
||||||
.reduce((total, option) => total + option.score, 0);
|
.reduce((total, option) => total + option.score, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 计算属性:判断表单是否为空
|
||||||
const isFormEmpty = computed(() => {
|
const isFormEmpty = computed(() => {
|
||||||
return (
|
return (
|
||||||
form.ZKDATE === '' && form.ZKTIME === '' && form.recordTime === '' && form.nurseSignature === ''
|
form.ZKDATE === '' && form.ZKTIME === '' && form.recordTime === '' && form.nurseSignature === ''
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 方法 - 不再需要handleData方法,通过表单输入和按钮加载数据
|
// 危险因素选择变化处理函数
|
||||||
|
|
||||||
const handleDangerChange = (row) => {
|
const handleDangerChange = (row) => {
|
||||||
totalScore.value = calculate.value;
|
totalScore.value = calculate.value;
|
||||||
form.bedFallRiskAssessmentList = dangerData.value
|
form.bedFallRiskAssessmentList = dangerData.value
|
||||||
@@ -360,12 +386,14 @@ const handleDangerChange = (row) => {
|
|||||||
.map((item) => item.id);
|
.map((item) => item.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 护理措施选择变化处理函数
|
||||||
const handleNursingChange = (row) => {
|
const handleNursingChange = (row) => {
|
||||||
form.patientCareSessionsCheckedList = nursingData.value
|
form.patientCareSessionsCheckedList = nursingData.value
|
||||||
.filter((item) => item.checked)
|
.filter((item) => item.checked)
|
||||||
.map((item) => item.id);
|
.map((item) => item.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 初始化函数:加载模拟数据
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
// 使用模拟数据,不再调用后端API
|
// 使用模拟数据,不再调用后端API
|
||||||
try {
|
try {
|
||||||
@@ -427,6 +455,7 @@ const init = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 危险因素表格合并单元格处理函数
|
||||||
const handleSpan = ({ row, column, rowIndex, columnIndex }) => {
|
const handleSpan = ({ row, column, rowIndex, columnIndex }) => {
|
||||||
if (columnIndex === 0) {
|
if (columnIndex === 0) {
|
||||||
if (rowIndex === 0) {
|
if (rowIndex === 0) {
|
||||||
@@ -473,6 +502,7 @@ const handleSpan = ({ row, column, rowIndex, columnIndex }) => {
|
|||||||
return [1, 1];
|
return [1, 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 护理措施表格合并单元格处理函数
|
||||||
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
||||||
// 护理措施
|
// 护理措施
|
||||||
if (columnIndex === 0) {
|
if (columnIndex === 0) {
|
||||||
@@ -489,8 +519,9 @@ const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
|||||||
return [1, 1];
|
return [1, 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 提交表单处理函数
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
// 检查上次提交时间
|
// 检查上次提交时间,防止重复提交
|
||||||
if (lastSubmit.value && new Date() - lastSubmit.value < 2000) {
|
if (lastSubmit.value && new Date() - lastSubmit.value < 2000) {
|
||||||
ElMessage.error('禁止重复提交!');
|
ElMessage.error('禁止重复提交!');
|
||||||
return;
|
return;
|
||||||
@@ -562,6 +593,7 @@ const onSubmit = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 编辑记录处理函数
|
||||||
const handleUpdate = (row) => {
|
const handleUpdate = (row) => {
|
||||||
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
|
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
|
||||||
|
|
||||||
@@ -591,6 +623,7 @@ const handleUpdate = (row) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 重置表单函数
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
ZKDATE: '',
|
ZKDATE: '',
|
||||||
@@ -623,6 +656,7 @@ const reset = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 删除记录处理函数
|
||||||
const handleDelete = (row) => {
|
const handleDelete = (row) => {
|
||||||
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
|
const loginUser = JSON.parse(window.localStorage.getItem('loginUser'));
|
||||||
|
|
||||||
@@ -646,6 +680,7 @@ const handleDelete = (row) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 打印预览函数(暂未实现)
|
||||||
const dc_ajax_preview = () => {
|
const dc_ajax_preview = () => {
|
||||||
var args = {
|
var args = {
|
||||||
report: urlAddRandomNo('./grf/NurseRecord_Pressure_208.grf'),
|
report: urlAddRandomNo('./grf/NurseRecord_Pressure_208.grf'),
|
||||||
@@ -656,6 +691,7 @@ const dc_ajax_preview = () => {
|
|||||||
webapp_ws_ajax_run(args);
|
webapp_ws_ajax_run(args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 数据转换函数,用于报表打印
|
||||||
const transformData = () => {
|
const transformData = () => {
|
||||||
const jsonDate = [...tableDataSource.value];
|
const jsonDate = [...tableDataSource.value];
|
||||||
|
|
||||||
@@ -802,7 +838,7 @@ const transformData = () => {
|
|||||||
return transformedData;
|
return transformedData;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 生命周期钩子
|
// 组件挂载后执行的生命周期函数
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
try {
|
try {
|
||||||
// 安全获取用户信息
|
// 安全获取用户信息
|
||||||
@@ -831,6 +867,7 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* 页面样式定义 */
|
||||||
.business {
|
.business {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@@ -894,4 +931,10 @@ onMounted(() => {
|
|||||||
margin-bottom: 0px !important;
|
margin-bottom: 0px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
/* 备注信息列表样式 */
|
||||||
|
.instructions-list {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,17 +1,42 @@
|
|||||||
// 动态引入 template 目录下的所有 .vue 文件
|
/**
|
||||||
|
* 模板组件注册模块
|
||||||
|
* 动态引入 template 目录下的所有 .vue 文件,并将它们注册为全局组件
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 动态引入 template 目录下的所有 .vue 文件(包括中文命名的文件)
|
||||||
|
// 使用 { eager: true } 表示立即加载所有匹配的文件
|
||||||
const templates = import.meta.glob('./*.vue', { eager: true });
|
const templates = import.meta.glob('./*.vue', { eager: true });
|
||||||
|
|
||||||
|
// 存储所有加载的组件
|
||||||
const components = [];
|
const components = [];
|
||||||
|
|
||||||
// 遍历所有引入的文件
|
// 遍历所有引入的文件
|
||||||
for (const path in templates) {
|
for (const path in templates) {
|
||||||
const component = templates[path].default;
|
try {
|
||||||
components.push(component);
|
// 获取组件的默认导出
|
||||||
|
const component = templates[path].default;
|
||||||
|
|
||||||
|
// 检查组件是否有 name 属性,如果没有则跳过
|
||||||
|
if (component && component.name) {
|
||||||
|
components.push(component);
|
||||||
|
} else {
|
||||||
|
console.warn(`组件 ${path} 缺少 name 属性,将不会被注册`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`加载组件 ${path} 时出错:`, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册所有组件到 Vue 应用实例
|
||||||
|
* @param {Object} app - Vue 应用实例
|
||||||
|
*/
|
||||||
const registerComponents = (app) => {
|
const registerComponents = (app) => {
|
||||||
components.forEach((component) => {
|
components.forEach((component) => {
|
||||||
|
// 使用组件的 name 属性作为组件名称进行注册
|
||||||
app.component(component.name, component);
|
app.component(component.name, component);
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
export { components, registerComponents };
|
|
||||||
|
|
||||||
|
// 导出组件数组和注册函数
|
||||||
|
export { components, registerComponents };
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<!-- 门诊病历表单主容器 -->
|
||||||
<div class="medical-form">
|
<div class="medical-form">
|
||||||
|
<!-- 患者基本信息展示区域 -->
|
||||||
<div class="patient-name">
|
<div class="patient-name">
|
||||||
患者姓名:{{ patient?.patientName || '未知' }} 病历号:{{
|
患者姓名:{{ patient?.patientName || '未知' }} 病历号:{{
|
||||||
patient?.busNo || '未知'
|
patient?.busNo || '未知'
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 医院名称和标题 -->
|
||||||
<h2 style="text-align: center">{{ userStore.hospitalName }}</h2>
|
<h2 style="text-align: center">{{ userStore.hospitalName }}</h2>
|
||||||
<h2 style="text-align: center">门诊病历</h2>
|
<h2 style="text-align: center">门诊病历</h2>
|
||||||
|
|
||||||
<!-- 滚动内容区域 -->
|
<!-- 滚动内容区域 -->
|
||||||
<div class="form-scroll-container">
|
<div class="form-scroll-container">
|
||||||
|
<!-- Element Plus表单组件 -->
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
@@ -18,34 +22,40 @@
|
|||||||
label-align="left"
|
label-align="left"
|
||||||
class="medical-full-form"
|
class="medical-full-form"
|
||||||
>
|
>
|
||||||
|
<!-- 基础信息区域标题 -->
|
||||||
<h4 class="section-title">基础信息</h4>
|
<h4 class="section-title">基础信息</h4>
|
||||||
<!-- 1. 基础信息:单行自适应排列 -->
|
<!-- 1. 基础信息:单行自适应排列 -->
|
||||||
<el-form-item class="form-section">
|
<el-form-item class="form-section">
|
||||||
<div class="single-row-layout">
|
<div class="single-row-layout">
|
||||||
|
<!-- 身高输入项 -->
|
||||||
<el-form-item label="身高" prop="height" class="row-item">
|
<el-form-item label="身高" prop="height" class="row-item">
|
||||||
<div class="input-with-unit">
|
<div class="input-with-unit">
|
||||||
<el-input v-model="formData.height" type="text" placeholder="请输入" />
|
<el-input v-model="formData.height" type="text" placeholder="请输入" />
|
||||||
<span class="unit">cm</span>
|
<span class="unit">cm</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 体重输入项 -->
|
||||||
<el-form-item label="体重" prop="weight" class="row-item">
|
<el-form-item label="体重" prop="weight" class="row-item">
|
||||||
<div class="input-with-unit">
|
<div class="input-with-unit">
|
||||||
<el-input v-model="formData.weight" type="text" placeholder="请输入" />
|
<el-input v-model="formData.weight" type="text" placeholder="请输入" />
|
||||||
<span class="unit">kg</span>
|
<span class="unit">kg</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 体温输入项 -->
|
||||||
<el-form-item label="体温" prop="temperature" class="row-item">
|
<el-form-item label="体温" prop="temperature" class="row-item">
|
||||||
<div class="input-with-unit">
|
<div class="input-with-unit">
|
||||||
<el-input v-model="formData.temperature" type="text" placeholder="请输入" />
|
<el-input v-model="formData.temperature" type="text" placeholder="请输入" />
|
||||||
<span class="unit">℃</span>
|
<span class="unit">℃</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 脉搏输入项 -->
|
||||||
<el-form-item label="脉搏" prop="pulse" class="row-item">
|
<el-form-item label="脉搏" prop="pulse" class="row-item">
|
||||||
<div class="input-with-unit">
|
<div class="input-with-unit">
|
||||||
<el-input v-model="formData.pulse" type="text" placeholder="请输入" />
|
<el-input v-model="formData.pulse" type="text" placeholder="请输入" />
|
||||||
<span class="unit">次/分</span>
|
<span class="unit">次/分</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 发病日期选择项 -->
|
||||||
<el-form-item label="发病日期" prop="onsetDate" class="row-item">
|
<el-form-item label="发病日期" prop="onsetDate" class="row-item">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="formData.onsetDate"
|
v-model="formData.onsetDate"
|
||||||
@@ -58,10 +68,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 病史信息区域标题 -->
|
||||||
<h4 class="section-title">病史信息</h4>
|
<h4 class="section-title">病史信息</h4>
|
||||||
<!-- 2. 病史信息:单行自适应排列(新增调整) -->
|
<!-- 2. 病史信息:单行自适应排列(新增调整) -->
|
||||||
<el-form-item class="form-section">
|
<el-form-item class="form-section">
|
||||||
<div class="single-row-layout">
|
<div class="single-row-layout">
|
||||||
|
<!-- 现病史输入项 -->
|
||||||
<el-form-item label="现病史" prop="presentIllness" class="row-item history-item">
|
<el-form-item label="现病史" prop="presentIllness" class="row-item history-item">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.presentIllness"
|
v-model="formData.presentIllness"
|
||||||
@@ -70,9 +83,11 @@
|
|||||||
autosize
|
autosize
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 既往史输入项 -->
|
||||||
<el-form-item label="既往史" prop="pastIllness" class="row-item history-item">
|
<el-form-item label="既往史" prop="pastIllness" class="row-item history-item">
|
||||||
<el-input v-model="formData.pastIllness" type="textarea" placeholder="无" autosize />
|
<el-input v-model="formData.pastIllness" type="textarea" placeholder="无" autosize />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 个人史输入项 -->
|
||||||
<el-form-item label="个人史" prop="personalHistory" class="row-item history-item">
|
<el-form-item label="个人史" prop="personalHistory" class="row-item history-item">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.personalHistory"
|
v-model="formData.personalHistory"
|
||||||
@@ -81,6 +96,7 @@
|
|||||||
autosize
|
autosize
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 过敏史输入项 -->
|
||||||
<el-form-item label="过敏史" prop="allergyHistory" class="row-item history-item">
|
<el-form-item label="过敏史" prop="allergyHistory" class="row-item history-item">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.allergyHistory"
|
v-model="formData.allergyHistory"
|
||||||
@@ -89,6 +105,7 @@
|
|||||||
autosize
|
autosize
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 家族史输入项 -->
|
||||||
<el-form-item label="家族史" prop="familyHistory" class="row-item history-item">
|
<el-form-item label="家族史" prop="familyHistory" class="row-item history-item">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.familyHistory"
|
v-model="formData.familyHistory"
|
||||||
@@ -99,6 +116,8 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 主诉、查体(治疗)、处置、辅助检查区域标题 -->
|
||||||
<h4 class="section-title">主诉、查体(治疗)、处置、辅助检查</h4>
|
<h4 class="section-title">主诉、查体(治疗)、处置、辅助检查</h4>
|
||||||
<!-- 3. 主诉(必填) -->
|
<!-- 3. 主诉(必填) -->
|
||||||
<el-form-item label="主诉" prop="complaint" class="required form-item-single">
|
<el-form-item label="主诉" prop="complaint" class="required form-item-single">
|
||||||
@@ -111,6 +130,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 4. 查体、处理、辅助检查 -->
|
<!-- 4. 查体、处理、辅助检查 -->
|
||||||
|
<!-- 查体(治疗)输入项 -->
|
||||||
<el-form-item label="查体(治疗)" prop="physicalExam" class="form-item-single">
|
<el-form-item label="查体(治疗)" prop="physicalExam" class="form-item-single">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.physicalExam"
|
v-model="formData.physicalExam"
|
||||||
@@ -121,6 +141,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 处置输入项 -->
|
||||||
<el-form-item label="处置" prop="treatment" class="form-item-single">
|
<el-form-item label="处置" prop="treatment" class="form-item-single">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.treatment"
|
v-model="formData.treatment"
|
||||||
@@ -131,6 +152,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 辅助检查输入项 -->
|
||||||
<el-form-item label="辅助检查" prop="auxiliaryExam" class="form-item-single">
|
<el-form-item label="辅助检查" prop="auxiliaryExam" class="form-item-single">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.auxiliaryExam"
|
v-model="formData.auxiliaryExam"
|
||||||
@@ -146,12 +168,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
// 导入Vue相关功能和组件
|
||||||
import { reactive, ref, onBeforeMount, onMounted, watch } from 'vue';
|
import { reactive, ref, onBeforeMount, onMounted, watch } from 'vue';
|
||||||
import useUserStore from '../store/modules/user';
|
import useUserStore from '../store/modules/user';
|
||||||
import { ElInput, ElMessage, ElForm, ElFormItem } from 'element-plus';
|
import { ElInput, ElMessage, ElForm, ElFormItem } from 'element-plus';
|
||||||
import { patientInfo } from '../views/doctorstation/components/store/patient';
|
import { patientInfo } from '../views/doctorstation/components/store/patient';
|
||||||
import { pa } from 'element-plus/es/locales.mjs';
|
import { pa } from 'element-plus/es/locales.mjs';
|
||||||
|
|
||||||
|
// 定义组件选项
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'OutpatientMedicalRecord',
|
name: 'OutpatientMedicalRecord',
|
||||||
components: { ElInput, ElMessage, ElForm, ElFormItem },
|
components: { ElInput, ElMessage, ElForm, ElFormItem },
|
||||||
@@ -164,33 +188,42 @@ defineOptions({
|
|||||||
// required: true,
|
// required: true,
|
||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
// 定义组件接收的属性(目前为空)
|
||||||
const props = defineProps({});
|
const props = defineProps({});
|
||||||
|
|
||||||
|
// 定义组件触发的事件
|
||||||
const emits = defineEmits(['submitOk']);
|
const emits = defineEmits(['submitOk']);
|
||||||
|
|
||||||
// 数据初始化
|
// 数据初始化
|
||||||
|
// 获取用户store实例,用于获取医院名称等全局信息
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
// 患者信息引用,存储当前就诊患者的基本信息
|
||||||
const patient = ref(null);
|
const patient = ref(null);
|
||||||
|
// 表单引用,用于访问表单实例进行验证等操作
|
||||||
const formRef = ref(null);
|
const formRef = ref(null);
|
||||||
|
|
||||||
// 表单数据(全部字符类型)
|
// 表单数据(全部字符类型)
|
||||||
|
// 存储门诊病历表单的所有字段数据
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
height: '', // 身高
|
height: '', // 身高(cm)
|
||||||
weight: '', // 体重
|
weight: '', // 体重(kg)
|
||||||
temperature: '', // 体温
|
temperature: '', // 体温(℃)
|
||||||
pulse: '', // 脉搏
|
pulse: '', // 脉搏(次/分)
|
||||||
onsetDate: '', // 发病日期
|
onsetDate: '', // 发病日期
|
||||||
complaint: '', // 主诉(必填)
|
complaint: '', // 主诉(必填项)
|
||||||
presentIllness: '', // 现病史
|
presentIllness: '', // 现病史
|
||||||
pastIllness: '', // 既往史
|
pastIllness: '', // 既往史
|
||||||
personalHistory: '', // 个人史
|
personalHistory: '', // 个人史
|
||||||
allergyHistory: '', // 过敏史
|
allergyHistory: '', // 过敏史
|
||||||
physicalExam: '', // 查体
|
physicalExam: '', // 查体结果
|
||||||
treatment: '', // 处理
|
treatment: '', // 处理方案
|
||||||
auxiliaryExam: '', // 辅助检查
|
auxiliaryExam: '', // 辅助检查结果
|
||||||
familyHistory: '', // 家族史
|
familyHistory: '', // 家族史
|
||||||
});
|
});
|
||||||
|
|
||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
|
// 定义表单字段的验证规则,目前仅主诉为必填项
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
complaint: [
|
complaint: [
|
||||||
{
|
{
|
||||||
@@ -202,15 +235,21 @@ const rules = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 提交函数
|
// 提交函数
|
||||||
|
// 用于触发表单验证并提交数据到父组件
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
|
// 表单验证
|
||||||
formRef.value.validate((isValid) => {
|
formRef.value.validate((isValid) => {
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
|
// 触发submitOk事件,传递表单数据
|
||||||
emits('submitOk', formData);
|
emits('submitOk', formData);
|
||||||
|
// 显示成功消息
|
||||||
ElMessage.success('提交成功');
|
ElMessage.success('提交成功');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// 日期格式化工具
|
|
||||||
|
// 日期格式化工具函数
|
||||||
|
// 将Date对象格式化为 YYYY-MM-DD HH:mm 格式的字符串
|
||||||
const formatDateTime = (date) => {
|
const formatDateTime = (date) => {
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
@@ -219,17 +258,23 @@ const formatDateTime = (date) => {
|
|||||||
const minute = String(date.getMinutes()).padStart(2, '0');
|
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||||
};
|
};
|
||||||
// 表单数据赋值
|
|
||||||
|
// 表单数据赋值函数
|
||||||
|
// 用于外部组件向表单填充已有数据
|
||||||
const setFormData = (data) => {
|
const setFormData = (data) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
|
// 将传入的数据合并到表单数据中
|
||||||
Object.assign(formData, data);
|
Object.assign(formData, data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 生命周期
|
// 生命周期钩子 - 组件挂载前
|
||||||
onBeforeMount(() => {});
|
onBeforeMount(() => {});
|
||||||
|
|
||||||
|
// 生命周期钩子 - 组件挂载后
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('当前患者信息:', patientInfo);
|
console.log('当前患者信息:', patientInfo);
|
||||||
|
// 从store获取患者信息
|
||||||
patient.value = patientInfo.value;
|
patient.value = patientInfo.value;
|
||||||
// 初始化发病日期为当前时间
|
// 初始化发病日期为当前时间
|
||||||
if (!formData.onsetDate) {
|
if (!formData.onsetDate) {
|
||||||
@@ -238,6 +283,7 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 监听患者信息变化,实现联动显示
|
// 监听患者信息变化,实现联动显示
|
||||||
|
// 当patientInfo发生变化时更新本地patient引用
|
||||||
watch(
|
watch(
|
||||||
() => patientInfo.value,
|
() => patientInfo.value,
|
||||||
(newPatientInfo) => {
|
(newPatientInfo) => {
|
||||||
@@ -246,7 +292,8 @@ watch(
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
// 暴露接口
|
// 暴露接口供父组件调用
|
||||||
|
// 将formData、submit方法和setFormData方法暴露给父组件使用
|
||||||
defineExpose({ formData, submit, setFormData });
|
defineExpose({ formData, submit, setFormData });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -410,4 +457,4 @@ defineExpose({ formData, submit, setFormData });
|
|||||||
--el-input-textarea-min-height: 80px;
|
--el-input-textarea-min-height: 80px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,21 +1,50 @@
|
|||||||
|
// 导入 API 函数,用于从服务器获取带有选项列表的数据
|
||||||
import { getListWithOptionList } from '@/views/basicmanage/caseTemplatesStatistics/api';
|
import { getListWithOptionList } from '@/views/basicmanage/caseTemplatesStatistics/api';
|
||||||
|
// 导入 Vue 3 的组合式 API:onMounted(组件挂载后执行)和 ref(响应式数据)
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
// 创建响应式数据:统计选项列表,初始为空数组
|
||||||
const statisticsOptionList = ref([]);
|
const statisticsOptionList = ref([]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化统计选项列表数据
|
||||||
|
* 异步函数,通过 API 获取数据并更新到响应式变量中
|
||||||
|
*/
|
||||||
const initStatic = async () => {
|
const initStatic = async () => {
|
||||||
try {
|
try {
|
||||||
|
// 调用 API 获取数据
|
||||||
const res = await getListWithOptionList();
|
const res = await getListWithOptionList();
|
||||||
|
// 将获取到的数据赋值给响应式变量
|
||||||
statisticsOptionList.value = res.data;
|
statisticsOptionList.value = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// 错误处理:打印错误信息到控制台
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vue 3 组合式函数:用于获取和管理统计选项列表
|
||||||
|
* @returns {Object} 返回包含响应式数据和方法的对象
|
||||||
|
*/
|
||||||
export default function useOptionsList() {
|
export default function useOptionsList() {
|
||||||
initStatic();
|
// 组件挂载后自动初始化数据
|
||||||
|
onMounted(() => {
|
||||||
|
initStatic();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据代码获取对应的选项列表
|
||||||
|
* @param {string} code - 统计类型代码
|
||||||
|
* @returns {Array} 返回匹配的选项列表,如果没有匹配则返回空数组
|
||||||
|
*/
|
||||||
const getStatisticsOptionList = (code) => {
|
const getStatisticsOptionList = (code) => {
|
||||||
|
// 在统计选项列表中查找匹配代码的项,然后返回其 optionList 属性,如果没有找到则返回空数组
|
||||||
return statisticsOptionList.value.find((item) => item.code === code)?.optionList || [];
|
return statisticsOptionList.value.find((item) => item.code === code)?.optionList || [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 返回响应式数据和方法供组件使用
|
||||||
return {
|
return {
|
||||||
statisticsOptionList,
|
statisticsOptionList, // 完整的统计选项列表
|
||||||
getStatisticsOptionList,
|
getStatisticsOptionList, // 根据代码获取选项列表的方法
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
44
openhis-ui-vue3/src/template/股骨头坏死(模板1).vue
Normal file
44
openhis-ui-vue3/src/template/股骨头坏死(模板1).vue
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div class="template-content">
|
||||||
|
<div class="template-header">
|
||||||
|
<h3>股骨头坏死(模板11111111)</h3>
|
||||||
|
</div>
|
||||||
|
<div class="template-body">
|
||||||
|
<p>主诉:左侧髋部疼痛X个月,加重1周。</p>
|
||||||
|
<p>现病史:患者X个月前无明显诱因出现左侧髋部疼痛,活动后加重,休息后减轻,未予重视。1周前疼痛加重,行走困难,遂来我院就诊。</p>
|
||||||
|
<p>既往史:否认高血压、糖尿病、冠心病等慢性病史,否认手术、外伤史,否认药物过敏史。</p>
|
||||||
|
<p>体格检查:左侧髋关节压痛(+),活动受限,左下肢肌力下降。</p>
|
||||||
|
<p>辅助检查:DR示左侧股骨头坏死。</p>
|
||||||
|
<p>诊断:左侧股骨头坏死。</p>
|
||||||
|
<p>治疗方案:1. 避免负重;2. 药物治疗;3. 必要时手术治疗。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
defineOptions({
|
||||||
|
name: '股骨头坏死(模板11111111)'
|
||||||
|
})
|
||||||
|
// 可以在这里添加组件逻辑
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.template-content {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 15px;
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-header {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-body p {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
class="clinic-room-table"
|
class="clinic-room-table"
|
||||||
>
|
>
|
||||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
<el-table-column prop="id" label="ID" width="180" align="center" />
|
||||||
<el-table-column prop="roomName" label="诊室名称" width="160" align="center" show-overflow-tooltip />
|
<el-table-column prop="roomName" label="诊室名称" width="160" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="department" label="科室名称" width="160" align="center" show-overflow-tooltip />
|
<el-table-column prop="department" label="科室名称" width="160" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="building" label="诊室楼号" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="building" label="诊室楼号" width="120" align="center" show-overflow-tooltip />
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="remarks" label="备注" min-width="140" align="center" show-overflow-tooltip />
|
<el-table-column prop="remarks" label="备注" min-width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="void" label="作废" width="90" align="center">
|
<el-table-column prop="void" label="作废" width="90" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="scope.row.void ? 'danger' : 'success'">
|
<el-tag :type="scope.row.void ? 'danger' : 'success'">
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|||||||
@@ -98,10 +98,24 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="maxNumber" label="限号数量" width="80"></el-table-column>
|
<el-table-column prop="maxNumber" label="限号数量" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input
|
||||||
|
v-model="scope.row.maxNumber"
|
||||||
|
type="number"
|
||||||
|
:disabled="!isEditMode"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="record" label="号源记录" width="80">
|
<el-table-column prop="record" label="号源记录" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-icon><View /></el-icon>
|
<el-icon
|
||||||
|
@click="handleViewRecord(scope.row)"
|
||||||
|
class="record-icon"
|
||||||
|
title="查看号源记录"
|
||||||
|
>
|
||||||
|
<View />
|
||||||
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="appointmentItem" label="挂号项目" width="120">
|
<el-table-column prop="appointmentItem" label="挂号项目" width="120">
|
||||||
@@ -186,13 +200,32 @@
|
|||||||
<el-button @click="handleCancel">取消</el-button>
|
<el-button @click="handleCancel">取消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 号源记录对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="recordDialogVisible"
|
||||||
|
title="号源记录"
|
||||||
|
width="30%"
|
||||||
|
:close-on-click-modal="true"
|
||||||
|
>
|
||||||
|
<div class="appointment-records">
|
||||||
|
<div class="record-item" v-for="record in appointmentRecords" :key="record.index">
|
||||||
|
<span class="record-time">{{ record.time }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="recordDialogVisible = false">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="DoctorSchedule">
|
<script setup name="DoctorSchedule">
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed, watch } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage, ElMessageBox, ElDialog } from 'element-plus'
|
||||||
import { View } from '@element-plus/icons-vue'
|
import { View } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
// 路由和导航
|
// 路由和导航
|
||||||
@@ -264,7 +297,7 @@ const generateWeekSchedule = (startDate) => {
|
|||||||
endTime: slot.endTime,
|
endTime: slot.endTime,
|
||||||
doctorName: '',
|
doctorName: '',
|
||||||
room: '',
|
room: '',
|
||||||
maxNumber: 20,
|
maxNumber: '',
|
||||||
appointmentItem: '',
|
appointmentItem: '',
|
||||||
registrationFee: '',
|
registrationFee: '',
|
||||||
clinicItem: '',
|
clinicItem: '',
|
||||||
@@ -299,6 +332,59 @@ const handleDeleteSchedule = (row) => {
|
|||||||
ElMessage.info('删除排班功能待实现')
|
ElMessage.info('删除排班功能待实现')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 号源记录对话框相关
|
||||||
|
const recordDialogVisible = ref(false)
|
||||||
|
const currentRow = ref(null)
|
||||||
|
const appointmentRecords = ref([])
|
||||||
|
|
||||||
|
// 计算号源记录
|
||||||
|
const calculateAppointmentRecords = (row) => {
|
||||||
|
const { startTime, endTime, maxNumber } = row
|
||||||
|
|
||||||
|
// 将时间转换为分钟数
|
||||||
|
const [startHour, startMinute] = startTime.split(':').map(Number)
|
||||||
|
const [endHour, endMinute] = endTime.split(':').map(Number)
|
||||||
|
|
||||||
|
const startTotalMinutes = startHour * 60 + startMinute
|
||||||
|
const endTotalMinutes = endHour * 60 + endMinute
|
||||||
|
|
||||||
|
// 计算总时长和间隔
|
||||||
|
const totalDuration = endTotalMinutes - startTotalMinutes
|
||||||
|
const interval = Math.floor(totalDuration / maxNumber)
|
||||||
|
|
||||||
|
// 生成号源记录
|
||||||
|
const records = []
|
||||||
|
for (let i = 0; i < maxNumber; i++) {
|
||||||
|
const minutes = startTotalMinutes + i * interval
|
||||||
|
const hour = Math.floor(minutes / 60).toString().padStart(2, '0')
|
||||||
|
const minute = (minutes % 60).toString().padStart(2, '0')
|
||||||
|
records.push({
|
||||||
|
index: i + 1,
|
||||||
|
time: `${hour}:${minute}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看号源记录
|
||||||
|
const handleViewRecord = (row) => {
|
||||||
|
// 验证开始时间、结束时间和限号数量
|
||||||
|
if (!row.startTime || !row.endTime || !row.maxNumber) {
|
||||||
|
ElMessageBox.confirm('请先设置开始时间、结束时间和限号数量', '', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
type: 'warning',
|
||||||
|
showCancelButton: false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算号源记录
|
||||||
|
currentRow.value = row
|
||||||
|
appointmentRecords.value = calculateAppointmentRecords(row)
|
||||||
|
recordDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
// 保存排班
|
// 保存排班
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
ElMessage.success('排班保存成功')
|
ElMessage.success('排班保存成功')
|
||||||
@@ -316,6 +402,15 @@ const handleCancel = () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initData()
|
initData()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听路由参数变化,重新初始化数据
|
||||||
|
watch(
|
||||||
|
() => [route.params.deptId, route.query.mode],
|
||||||
|
() => {
|
||||||
|
initData()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@@ -462,9 +557,55 @@ onMounted(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.record-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #409eff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-icon:hover {
|
||||||
|
color: #66b1ff;
|
||||||
|
}
|
||||||
|
|
||||||
.bottom-buttons {
|
.bottom-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 号源记录对话框样式 */
|
||||||
|
.appointment-records {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-item {
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-time {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏数字输入框的增减按钮 */
|
||||||
|
:deep(.el-input__inner[type="number"]) {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
}
|
||||||
|
:deep(.el-input__inner[type="number"])::-webkit-outer-spin-button,
|
||||||
|
:deep(.el-input__inner[type="number"])::-webkit-inner-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="appoinmentmanage-container">
|
<div class="appoinmentmanage-container">
|
||||||
<div class="appoinmentmanage-header">
|
<div class="appoinmentmanage-header">
|
||||||
<h2 class="appoinmentmanage-title">预约管理</h2>
|
<h2 class="appoinmentmanage-title">科室名称管理</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="appoinmentmanage-content">
|
<div class="appoinmentmanage-content">
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ const templateName = ref('');
|
|||||||
// 事件
|
// 事件
|
||||||
const emits = defineEmits(['save']);
|
const emits = defineEmits(['save']);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
console.log('EMR组件初始化,proxy:', proxy);
|
||||||
|
|
||||||
// 监听表单变化
|
// 监听表单变化
|
||||||
watch(
|
watch(
|
||||||
@@ -325,18 +326,109 @@ function cancel() {
|
|||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getDetail(encounterId) {
|
getDetail(encounterId) {
|
||||||
getEmrDetail(encounterId).then((res) => {
|
console.log('开始获取病历详情,encounterId:', encounterId);
|
||||||
if (res.data) {
|
|
||||||
|
// 立即初始化form.value为空对象,确保页面有内容显示
|
||||||
|
form.value = {};
|
||||||
|
|
||||||
|
// 检查API函数是否存在
|
||||||
|
if (typeof getEmrDetail !== 'function') {
|
||||||
|
console.error('getEmrDetail函数未定义');
|
||||||
|
if (proxy) {
|
||||||
|
proxy.$modal.msgError('获取病历详情失败:API函数未定义');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加超时处理,防止请求一直挂起
|
||||||
|
const timeoutPromise = new Promise((_, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
reject(new Error('获取病历详情请求超时'));
|
||||||
|
}, 10000); // 10秒超时
|
||||||
|
});
|
||||||
|
|
||||||
|
// 使用Promise.race处理正常请求和超时
|
||||||
|
Promise.race([getEmrDetail(encounterId), timeoutPromise])
|
||||||
|
.then((res) => {
|
||||||
|
console.log('获取病历详情成功,返回完整数据:', JSON.stringify(res, null, 2));
|
||||||
|
|
||||||
|
// 检查响应是否有效
|
||||||
|
if (!res) {
|
||||||
|
console.error('API返回结果为空');
|
||||||
|
if (proxy) {
|
||||||
|
proxy.$modal.msgError('获取病历详情失败:API返回结果为空');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('res存在,类型:', typeof res);
|
||||||
|
console.log('res的属性:', Object.keys(res));
|
||||||
|
|
||||||
|
// 检查响应码
|
||||||
|
if (res.code !== 200) {
|
||||||
|
console.error('API返回错误代码:', res.code);
|
||||||
|
if (proxy) {
|
||||||
|
proxy.$modal.msgError('获取病历详情失败:' + (res.msg || '未知错误'));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查数据是否存在
|
||||||
|
if (!res.data) {
|
||||||
|
console.log('res.data为空,使用默认值');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('res.data存在,类型:', typeof res.data);
|
||||||
|
console.log('res.data的属性:', Object.keys(res.data));
|
||||||
|
|
||||||
|
// 处理contextJson
|
||||||
try {
|
try {
|
||||||
form.value = JSON.parse(res.data.contextJson) || {};
|
if (res.data.contextJson) {
|
||||||
|
console.log('contextJson存在,值:', res.data.contextJson);
|
||||||
|
console.log('contextJson类型:', typeof res.data.contextJson);
|
||||||
|
|
||||||
|
// 检查contextJson类型
|
||||||
|
if (typeof res.data.contextJson === 'string') {
|
||||||
|
// 尝试解析JSON字符串
|
||||||
|
const parsedData = JSON.parse(res.data.contextJson);
|
||||||
|
// 确保解析结果是对象
|
||||||
|
if (typeof parsedData === 'object' && parsedData !== null) {
|
||||||
|
form.value = parsedData;
|
||||||
|
console.log('解析后的病历数据:', JSON.stringify(form.value, null, 2));
|
||||||
|
} else {
|
||||||
|
form.value = {};
|
||||||
|
console.error('contextJson解析结果不是有效对象:', parsedData);
|
||||||
|
}
|
||||||
|
} else if (typeof res.data.contextJson === 'object') {
|
||||||
|
// 如果已经是对象,直接使用
|
||||||
|
form.value = res.data.contextJson;
|
||||||
|
console.log('直接使用contextJson作为对象:', JSON.stringify(form.value, null, 2));
|
||||||
|
} else {
|
||||||
|
form.value = {};
|
||||||
|
console.error('contextJson类型无效:', typeof res.data.contextJson);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('contextJson为空,使用默认值');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
form.value = {};
|
form.value = {};
|
||||||
|
console.error('病历数据解析失败:', e);
|
||||||
|
console.error('解析失败的contextJson值:', res.data.contextJson);
|
||||||
|
if (proxy) {
|
||||||
|
proxy.$modal.msgError('病历数据解析失败');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emits('save', true);
|
emits('save', true);
|
||||||
} else {
|
})
|
||||||
form.value = {};
|
.catch((error) => {
|
||||||
}
|
// 处理API调用失败或超时的情况
|
||||||
});
|
console.error('获取病历详情失败:', error);
|
||||||
|
if (proxy) {
|
||||||
|
proxy.$modal.msgError('获取病历详情失败:' + (error.message || '未知错误'));
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
addEmr
|
addEmr
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1493,6 +1493,7 @@ const { proxy } = getCurrentInstance();
|
|||||||
const inputRefs = ref({}); // 存储输入框实例,格式: { rowIndex: { fieldName: el } }
|
const inputRefs = ref({}); // 存储输入框实例,格式: { rowIndex: { fieldName: el } }
|
||||||
const requiredProps = ref([]); // 存储必填项 prop 顺序
|
const requiredProps = ref([]); // 存储必填项 prop 顺序
|
||||||
const totalAmount = ref(0);
|
const totalAmount = ref(0);
|
||||||
|
const groupMarkers = ref([]); // 存储分组标记,用于显示层级关系
|
||||||
const { method_code, unit_code, rate_code, distribution_category_code, drord_doctor_type } = proxy.useDict(
|
const { method_code, unit_code, rate_code, distribution_category_code, drord_doctor_type } = proxy.useDict(
|
||||||
'method_code',
|
'method_code',
|
||||||
'unit_code',
|
'unit_code',
|
||||||
|
|||||||
@@ -20,16 +20,16 @@
|
|||||||
<el-icon
|
<el-icon
|
||||||
class="delete-icon"
|
class="delete-icon"
|
||||||
title="删除处方单"
|
title="删除处方单"
|
||||||
@click="handleDeletePrescriptionClick(index)"
|
@click="handleDeletePrescriptionClick(pIndex)"
|
||||||
:class="{ 'disabled-icon': isPrescriptionDeletable(index) !== true }"
|
:class="{ 'disabled-icon': isPrescriptionDeletable(pIndex) !== true }"
|
||||||
style="font-size: 20px !important; margin-left: 10px; color: #f56c6c"
|
style="font-size: 20px !important; margin-left: 10px; color: #f56c6c"
|
||||||
>
|
>
|
||||||
<minus />
|
<minus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="summary">
|
<div class="summary">
|
||||||
<span class="summary-item">药品数: {{ getPrescriptionMedicineCount(index) }}种</span>
|
<span class="summary-item">药品数: {{ getPrescriptionMedicineCount(pIndex) }}种</span>
|
||||||
<span class="summary-item">总价: ¥ {{ getPrescriptionTotalPrice(index) }}</span>
|
<span class="summary-item">总价: ¥ {{ getPrescriptionTotalPrice(pIndex) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -570,7 +570,10 @@ function getList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getListInfo(addNewRow) {
|
function getListInfo(addNewRow) {
|
||||||
isAdding.value = false;
|
// 确保isAdding变量存在
|
||||||
|
if (typeof isAdding !== 'undefined') {
|
||||||
|
isAdding.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
// 确保有患者信息
|
// 确保有患者信息
|
||||||
if (!props.patientInfo || !props.patientInfo.encounterId) {
|
if (!props.patientInfo || !props.patientInfo.encounterId) {
|
||||||
@@ -580,13 +583,17 @@ function getListInfo(addNewRow) {
|
|||||||
|
|
||||||
getTcmAdviceList({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
getTcmAdviceList({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||||
if (res && res.data && Array.isArray(res.data)) {
|
if (res && res.data && Array.isArray(res.data)) {
|
||||||
prescriptionList.value = res.data.map((item) => {
|
// 清空当前处方列表
|
||||||
|
tcmPrescriptionList.value = [];
|
||||||
|
|
||||||
|
// 处理返回的数据
|
||||||
|
res.data.forEach((item) => {
|
||||||
try {
|
try {
|
||||||
// 解析contentJson获取完整的医嘱数据
|
// 解析contentJson获取完整的医嘱数据
|
||||||
const contentData = item.contentJson ? JSON.parse(item.contentJson) : {};
|
const contentData = item.contentJson ? JSON.parse(item.contentJson) : {};
|
||||||
|
|
||||||
// 合并基础信息和contentJson中的详细信息
|
// 创建一个新的处方对象
|
||||||
return {
|
const newPrescription = {
|
||||||
...item,
|
...item,
|
||||||
...contentData,
|
...contentData,
|
||||||
// 确保关键显示字段存在
|
// 确保关键显示字段存在
|
||||||
@@ -596,11 +603,14 @@ function getListInfo(addNewRow) {
|
|||||||
diagnosisName: contentData.diagnosisName || item.diagnosisName || '',
|
diagnosisName: contentData.diagnosisName || item.diagnosisName || '',
|
||||||
positionName: contentData.positionName || item.positionName || '',
|
positionName: contentData.positionName || item.positionName || '',
|
||||||
doseUnitCode_dictText: contentData.doseUnitCode_dictText || item.doseUnitCode_dictText || '',
|
doseUnitCode_dictText: contentData.doseUnitCode_dictText || item.doseUnitCode_dictText || '',
|
||||||
chineseHerbsDoseQuantity: contentData.chineseHerbsDoseQuantity || item.chineseHerbsDoseQuantity || ''
|
chineseHerbsDoseQuantity: contentData.chineseHerbsDoseQuantity || item.chineseHerbsDoseQuantity || '',
|
||||||
|
prescriptionList: [contentData]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 添加到处方列表
|
||||||
|
tcmPrescriptionList.value.push(newPrescription);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('解析医嘱数据失败:', error, '数据项:', item);
|
console.error('解析医嘱数据失败:', error, '数据项:', item);
|
||||||
return item; // 出错时返回原始数据
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -612,11 +622,11 @@ function getListInfo(addNewRow) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('获取医嘱列表失败或数据格式错误:', res);
|
console.error('获取医嘱列表失败或数据格式错误:', res);
|
||||||
prescriptionList.value = [];
|
tcmPrescriptionList.value = [];
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error('获取医嘱列表异常:', error);
|
console.error('获取医嘱列表异常:', error);
|
||||||
prescriptionList.value = [];
|
tcmPrescriptionList.value = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
tcmDiagnosisList.value = getFromDiagnosis(props.patientInfo.encounterId);
|
tcmDiagnosisList.value = getFromDiagnosis(props.patientInfo.encounterId);
|
||||||
@@ -643,7 +653,7 @@ function getDiagnosisInfo() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 默认选择第一个诊断
|
// 默认选择第一个诊断
|
||||||
if (diagnosisList.value.length > 0) {
|
if (diagnosisList.value.length > 0) {
|
||||||
const firstDiagnosis = diagnosisList.value[0];
|
const firstDiagnosis = diagnosisList.value[0];
|
||||||
tcmPrescriptionList.value.forEach((prescription) => {
|
tcmPrescriptionList.value.forEach((prescription) => {
|
||||||
@@ -769,7 +779,8 @@ function handleDeletePrescriptionClick(prescriptionIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否有已签发的药品
|
// 检查是否有已签发的药品
|
||||||
const hasChargedItems = prescriptionList.value.some(item => item.statusEnum === 2);
|
const prescription = tcmPrescriptionList.value[prescriptionIndex];
|
||||||
|
const hasChargedItems = prescription.prescriptionList.some(item => item.statusEnum === 2);
|
||||||
if (hasChargedItems) {
|
if (hasChargedItems) {
|
||||||
proxy.$modal.msgWarning('该处方单已收费,不能删除');
|
proxy.$modal.msgWarning('该处方单已收费,不能删除');
|
||||||
return;
|
return;
|
||||||
@@ -793,16 +804,18 @@ function isPrescriptionDeletable(prescriptionIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否有已签发的药品
|
// 检查是否有已签发的药品
|
||||||
const hasChargedItems = prescriptionList.value.some(item => item.statusEnum === 2);
|
const hasChargedItems = tcmPrescriptionList.value.some(item =>
|
||||||
|
item.prescriptionList && item.prescriptionList.some(med => med.statusEnum === 2)
|
||||||
|
);
|
||||||
return !hasChargedItems;
|
return !hasChargedItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算处方总价
|
// 计算处方总价
|
||||||
function getPrescriptionTotalPrice(prescriptionIndex) {
|
function getPrescriptionTotalPrice(prescriptionIndex) {
|
||||||
const prescription = prescriptionList.value[prescriptionIndex];
|
const prescription = tcmPrescriptionList.value[prescriptionIndex];
|
||||||
let totalPrice = 0;
|
let totalPrice = 0;
|
||||||
if (prescription && prescription.prescriptionDetailsList) {
|
if (prescription && prescription.prescriptionList) {
|
||||||
prescription.prescriptionDetailsList.forEach(item => {
|
prescription.prescriptionList.forEach(item => {
|
||||||
// 使用decimal.js确保精度计算
|
// 使用decimal.js确保精度计算
|
||||||
const quantity = new Decimal(item.minUnitQuantity || 0);
|
const quantity = new Decimal(item.minUnitQuantity || 0);
|
||||||
const unitPrice = new Decimal(item.unitPrice || 0);
|
const unitPrice = new Decimal(item.unitPrice || 0);
|
||||||
@@ -814,9 +827,11 @@ function getPrescriptionTotalPrice(prescriptionIndex) {
|
|||||||
|
|
||||||
// 获取处方中的药品数量
|
// 获取处方中的药品数量
|
||||||
function getPrescriptionMedicineCount(prescriptionIndex) {
|
function getPrescriptionMedicineCount(prescriptionIndex) {
|
||||||
// 这里需要根据实际的业务逻辑来计算
|
const prescription = tcmPrescriptionList.value[prescriptionIndex];
|
||||||
// 假设每个处方对应一组药品,这里简化处理
|
if (prescription && prescription.prescriptionList) {
|
||||||
return prescriptionList.value.filter(item => item.statusEnum !== 2).length;
|
return prescription.prescriptionList.length;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -959,7 +974,9 @@ function handleDelete(pIndex) {
|
|||||||
prescription.expandOrder = [];
|
prescription.expandOrder = [];
|
||||||
prescription.isAdding = false;
|
prescription.isAdding = false;
|
||||||
adviceQueryParams.value.adviceType = undefined;
|
adviceQueryParams.value.adviceType = undefined;
|
||||||
groupMarkers.value = getGroupMarkers(prescriptionList.value); // 删除行会出现组号混乱的情况,所以这里重新更新标记
|
// 删除行会出现组号混乱的情况,所以这里重新更新标记
|
||||||
|
const allPrescriptions = tcmPrescriptionList.value.flatMap(p => p.prescriptionList);
|
||||||
|
groupMarkers.value = getGroupMarkers(allPrescriptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1115,42 +1132,60 @@ function handleSaveSign(row, index) {
|
|||||||
|
|
||||||
|
|
||||||
function handleSaveBatch() {
|
function handleSaveBatch() {
|
||||||
let saveList = prescriptionList.value
|
// 收集所有需要保存的处方项目
|
||||||
.filter((item) => {
|
let saveList = [];
|
||||||
return item.statusEnum == 1;
|
|
||||||
})
|
// 遍历所有处方
|
||||||
.map((item, index) => {
|
for (const prescription of tcmPrescriptionList.value) {
|
||||||
return {
|
if (prescription.prescriptionList) {
|
||||||
...item,
|
// 检查处方是否有必填的付数
|
||||||
accountId: accountId.value,
|
if (!prescription.chineseHerbsDoseQuantity || prescription.chineseHerbsDoseQuantity == 0) {
|
||||||
conditionId: prescription.conditionId,
|
proxy.$modal.msgWarning('请输入付数');
|
||||||
encounterDiagnosisId: prescription.encounterDiagnosisId,
|
return;
|
||||||
conditionDefinitionId: prescription.conditionDefinitionId,
|
}
|
||||||
encounterId: props.patientInfo.encounterId,
|
|
||||||
patientId: props.patientInfo.patientId,
|
// 收集该处方下需要保存的项目
|
||||||
requestId: item.requestId,
|
const itemsToSave = prescription.prescriptionList
|
||||||
groupId: item.groupId ? item.groupId : timestamp.toString(),
|
.filter((item) => item.statusEnum == 1)
|
||||||
|
.map((item, index) => {
|
||||||
chineseHerbsDoseQuantity: prescription.chineseHerbsDoseQuantity,
|
return {
|
||||||
dbOpType: item.requestId ? '2' : '1',
|
...item,
|
||||||
};
|
accountId: accountId.value,
|
||||||
});
|
conditionId: prescription.conditionId,
|
||||||
|
encounterDiagnosisId: prescription.encounterDiagnosisId,
|
||||||
|
conditionDefinitionId: prescription.conditionDefinitionId,
|
||||||
|
encounterId: props.patientInfo.encounterId,
|
||||||
|
patientId: props.patientInfo.patientId,
|
||||||
|
requestId: item.requestId,
|
||||||
|
groupId: item.groupId ? item.groupId : timestamp.toString(),
|
||||||
|
chineseHerbsDoseQuantity: prescription.chineseHerbsDoseQuantity,
|
||||||
|
dbOpType: item.requestId ? '2' : '1',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将项目添加到保存列表
|
||||||
|
saveList = saveList.concat(itemsToSave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有可保存的项目
|
||||||
if (saveList.length == 0) {
|
if (saveList.length == 0) {
|
||||||
proxy.$modal.msgWarning('当前没有可保存医嘱');
|
proxy.$modal.msgWarning('当前没有可保存医嘱');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
prescription.chineseHerbsDoseQuantity == undefined ||
|
// 保存处方
|
||||||
prescription.chineseHerbsDoseQuantity == 0
|
|
||||||
) {
|
|
||||||
proxy.$modal.msgWarning('请输入付数');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
saveTcmAdvice({ adviceSaveList: saveList }).then((res) => {
|
saveTcmAdvice({ adviceSaveList: saveList }).then((res) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
proxy.$modal.msgSuccess('保存成功');
|
proxy.$modal.msgSuccess('保存成功');
|
||||||
getListInfo(true);
|
getListInfo(true);
|
||||||
prescription.nextId = 1;
|
|
||||||
|
// 重置所有处方的nextId
|
||||||
|
tcmPrescriptionList.value.forEach(prescription => {
|
||||||
|
if (prescription.nextId) {
|
||||||
|
prescription.nextId = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,43 +3,24 @@
|
|||||||
<div style="width: 15%; height: 100%; border: 1px solid #eee; border-right: 0">
|
<div style="width: 15%; height: 100%; border: 1px solid #eee; border-right: 0">
|
||||||
<div style="padding: 10px; border: 1px solid #eee; height: 50px; border-right: 0">
|
<div style="padding: 10px; border: 1px solid #eee; height: 50px; border-right: 0">
|
||||||
<span>现诊患者</span>
|
<span>现诊患者</span>
|
||||||
<el-badge
|
<el-badge :value="waitCount > 0 ? waitCount : ''" :max="10"
|
||||||
:value="waitCount > 0 ? waitCount : ''"
|
style="float: right; color: #409eff; cursor: pointer; margin-right: 10px">
|
||||||
:max="10"
|
|
||||||
style="float: right; color: #409eff; cursor: pointer; margin-right: 10px"
|
|
||||||
>
|
|
||||||
<span @click="openDrawer"> 患者队列 </span>
|
<span @click="openDrawer"> 患者队列 </span>
|
||||||
</el-badge>
|
</el-badge>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 100%; padding: 10px">
|
<div style="width: 100%; padding: 10px">
|
||||||
<el-input
|
<el-input v-model="queryParams.searchKey" placeholder="请输入患者名" clearable
|
||||||
v-model="queryParams.searchKey"
|
style="width: 100%; margin-bottom: 10px" @keyup.enter="getPatientList">
|
||||||
placeholder="请输入患者名"
|
|
||||||
clearable
|
|
||||||
style="width: 100%; margin-bottom: 10px"
|
|
||||||
@keyup.enter="getPatientList"
|
|
||||||
>
|
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-button icon="Search" @click="getPatientList" />
|
<el-button icon="Search" @click="getPatientList" />
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-date-picker
|
<el-date-picker v-model="registerTime" @change="handleTimeChange" type="daterange"
|
||||||
v-model="registerTime"
|
style="width: 100%; margin-bottom: 10px" :clearable="false" placeholder="挂号时间" format="YYYY-MM-DD"
|
||||||
@change="handleTimeChange"
|
value-format="YYYY-MM-DD" />
|
||||||
type="date"
|
|
||||||
style="width: 100%; margin-bottom: 10px"
|
|
||||||
:clearable="false"
|
|
||||||
placeholder="挂号时间"
|
|
||||||
format="YYYY-MM-DD"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
/>
|
|
||||||
<el-scrollbar height="700px">
|
<el-scrollbar height="700px">
|
||||||
<div
|
<div v-for="(item, index) in patientList" :class="item.active ? 'patient-card actived' : 'patient-card'"
|
||||||
v-for="(item, index) in patientList"
|
:key="item.id" @click="handleCardClick(item, index)">
|
||||||
:class="item.active ? 'patient-card actived' : 'patient-card'"
|
|
||||||
:key="item.id"
|
|
||||||
@click="handleCardClick(item, index)"
|
|
||||||
>
|
|
||||||
<div class="main-info-container">
|
<div class="main-info-container">
|
||||||
<!-- <el-avatar
|
<!-- <el-avatar
|
||||||
:size="30"
|
:size="30"
|
||||||
@@ -78,29 +59,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="disabled-wrapper" style="width: 85%; border: 1px solid #eee; position: relative">
|
<div class="disabled-wrapper" style="width: 85%; border: 1px solid #eee; position: relative">
|
||||||
<div style="padding: 10px; border: 1px solid #eee; height: 50px; border-left: 0">
|
<div style="padding: 10px; border: 1px solid #eee; height: 50px; border-left: 0">
|
||||||
<el-descriptions :column="5" class="patient-info-descriptions">
|
<el-descriptions :column="4">
|
||||||
<el-descriptions-item label="患者信息:" width="420">
|
<el-descriptions-item label="患者信息:" width="150">
|
||||||
{{
|
{{
|
||||||
Object.keys(patientInfo).length !== 0
|
Object.keys(patientInfo).length !== 0
|
||||||
? patientInfo.patientName +
|
? patientInfo.patientName +
|
||||||
' / ' +
|
' / ' +
|
||||||
patientInfo.age +
|
patientInfo.age +
|
||||||
' / ' +
|
' / ' +
|
||||||
patientInfo.genderEnum_enumText +
|
patientInfo.genderEnum_enumText +
|
||||||
' / ' +
|
' / ' +
|
||||||
patientInfo.contractName +
|
patientInfo.contractName
|
||||||
'/' +
|
|
||||||
patientInfo.phone
|
|
||||||
: '-'
|
: '-'
|
||||||
}}
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="挂号时间:" width="300">
|
<el-descriptions-item label="挂号时间:" width="150">
|
||||||
{{ Object.keys(patientInfo).length !== 0 ? formatDate(patientInfo.registerTime) : '-' }}
|
{{ Object.keys(patientInfo).length !== 0 ? formatDate(patientInfo.registerTime) : '-' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="医生:" width="250">
|
<el-descriptions-item label="医生:" width="150">{{
|
||||||
{{ userStore.nickName }}
|
userStore.name
|
||||||
</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="" width="300">
|
<el-descriptions-item label="" width="350">
|
||||||
|
<!-- 初诊 / 复诊 按钮 -->
|
||||||
|
<el-radio v-model="visitType" label="FIRST" :disabled="visitTypeDisabled">初诊</el-radio>
|
||||||
|
<el-radio v-model="visitType" label="FOLLOW_UP" :disabled="visitTypeDisabled">复诊</el-radio>
|
||||||
|
|
||||||
|
<!-- 原有按钮 -->
|
||||||
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
|
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
|
||||||
完诊
|
完诊
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -110,121 +94,44 @@
|
|||||||
<el-button type="primary" plain @click.stop="handleRefund(patientInfo.encounterId)">
|
<el-button type="primary" plain @click.stop="handleRefund(patientInfo.encounterId)">
|
||||||
退费
|
退费
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="primary" plain @click.stop="getEnPrescription(patientInfo.encounterId)">
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click.stop="getEnPrescription(patientInfo.encounterId)"
|
|
||||||
>
|
|
||||||
处方单
|
处方单
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="primary" plain @click.stop="openDialog = true">
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click.stop="
|
|
||||||
() => {
|
|
||||||
openDialog = true;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
办理住院
|
办理住院
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button type="primary" plain @click.stop="handleCancelEncounter">
|
||||||
|
取消接诊
|
||||||
|
</el-button>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="医生:" width="150">{{
|
|
||||||
userStore.name
|
|
||||||
}}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="" width="350">
|
|
||||||
<!-- 初诊 / 复诊 按钮 -->
|
|
||||||
<el-radio v-model="visitType" label="FIRST" :disabled="visitTypeDisabled">初诊</el-radio>
|
|
||||||
<el-radio v-model="visitType" label="FOLLOW_UP" :disabled="visitTypeDisabled">复诊</el-radio>
|
|
||||||
|
|
||||||
<!-- 原有按钮 -->
|
|
||||||
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
|
|
||||||
完诊
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" plain @click.stop="handleLeave(patientInfo.encounterId)">
|
|
||||||
暂离
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" plain @click.stop="handleRefund(patientInfo.encounterId)">
|
|
||||||
退费
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click.stop="getEnPrescription(patientInfo.encounterId)"
|
|
||||||
>
|
|
||||||
处方单
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click.stop="openDialog = true"
|
|
||||||
>
|
|
||||||
办理住院
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click.stop="handleCancelEncounter"
|
|
||||||
>
|
|
||||||
取消接诊
|
|
||||||
</el-button>
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 10px">
|
<div style="padding: 10px">
|
||||||
<el-tabs
|
<el-tabs type="card" style="width: 100%; height: 100%" v-loading="loading" v-model="activeTab"
|
||||||
type="card"
|
@tab-change="handleClick(activeTab)">
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
v-loading="loading"
|
|
||||||
v-model="activeTab"
|
|
||||||
@tab-change="handleClick(activeTab)"
|
|
||||||
>
|
|
||||||
<el-tab-pane label="门诊病历" name="hospitalizationEmr">
|
|
||||||
<hospitalizationEmr
|
|
||||||
:patientInfo="patientInfo"
|
|
||||||
:activeTab="activeTab"
|
|
||||||
@emrSaved="handleEmrSaved"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="病历" name="emr">
|
<el-tab-pane label="病历" name="emr">
|
||||||
<Emr
|
<Emr :patientInfo="patientInfo" ref="emrRef" @save="
|
||||||
:patientInfo="patientInfo"
|
(value) => {
|
||||||
ref="emrRef"
|
saveStatus = value;
|
||||||
@save="
|
}
|
||||||
(value) => {
|
" :visitType="visitType" :firstVisitDate="firstVisitDate" />
|
||||||
saveStatus = value;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:visitType="visitType"
|
|
||||||
:firstVisitDate="firstVisitDate"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="诊断" name="diagnosis">
|
<el-tab-pane label="诊断" name="diagnosis">
|
||||||
<Diagnosis
|
<Diagnosis :patientInfo="patientInfo" ref="diagnosisRef" @diagnosisSave="
|
||||||
:patientInfo="patientInfo"
|
(value) => {
|
||||||
ref="diagnosisRef"
|
saveStatus = value;
|
||||||
@diagnosisSave="
|
}
|
||||||
(value) => {
|
" />
|
||||||
saveStatus = value;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="医嘱" name="prescription">
|
<el-tab-pane label="医嘱" name="prescription">
|
||||||
<prescriptionlist
|
<prescriptionlist :patientInfo="patientInfo" ref="prescriptionRef" :activeTab="activeTab" />
|
||||||
:patientInfo="patientInfo"
|
|
||||||
ref="prescriptionRef"
|
|
||||||
:activeTab="activeTab"
|
|
||||||
:outpatientEmrSaved="outpatientEmrSaved"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="中医" name="tcm">
|
<el-tab-pane label="中医" name="tcm">
|
||||||
<tcmAdvice :patientInfo="patientInfo" ref="tcmRef" />
|
<tcmAdvice :patientInfo="patientInfo" ref="tcmRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- <el-tab-pane label="电子处方" name="eprescription">
|
<el-tab-pane label="电子处方" name="eprescription">
|
||||||
<eprescriptionlist :patientInfo="patientInfo" ref="eprescriptionRef" />
|
<eprescriptionlist :patientInfo="patientInfo" ref="eprescriptionRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
-->
|
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<div class="overlay" v-if="disabled"></div>
|
<div class="overlay" v-if="disabled"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -232,27 +139,15 @@
|
|||||||
<el-drawer v-model="drawer" title="患者队列" direction="ltr" @open="handleOpen">
|
<el-drawer v-model="drawer" title="患者队列" direction="ltr" @open="handleOpen">
|
||||||
<PatientList ref="patientDrawerRef" @toCurrent="handleReceive" />
|
<PatientList ref="patientDrawerRef" @toCurrent="handleReceive" />
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
<RefundListDialog
|
<RefundListDialog :open="openRefundListDialog" :encounterId="currentEncounterId"
|
||||||
:open="openRefundListDialog"
|
@close="openRefundListDialog = false" />
|
||||||
:encounterId="currentEncounterId"
|
<HospitalizationDialog :open="openDialog" :patientInfo="patientInfo" :encounterId="currentEncounterId"
|
||||||
@close="openRefundListDialog = false"
|
@close="openDialog = false" />
|
||||||
@refresh="() => prescriptionRef.getListInfo()"
|
<PrescriptionInfo :open="openPrescriptionDialog" :precriptionInfo="prescriptionInfo"
|
||||||
/>
|
@close="openPrescriptionDialog = false" />
|
||||||
<HospitalizationDialog
|
|
||||||
:open="openDialog"
|
|
||||||
:patientInfo="patientInfo"
|
|
||||||
:encounterId="currentEncounterId"
|
|
||||||
@close="openDialog = false"
|
|
||||||
/>
|
|
||||||
<PrescriptionInfo
|
|
||||||
:open="openPrescriptionDialog"
|
|
||||||
:precriptionInfo="prescriptionInfo"
|
|
||||||
@close="openPrescriptionDialog = false"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import hospitalizationEmr from './components/hospitalizationEmr/index.vue';
|
|
||||||
import Emr from './components/emr/emr.vue';
|
import Emr from './components/emr/emr.vue';
|
||||||
import {
|
import {
|
||||||
getList,
|
getList,
|
||||||
@@ -267,14 +162,13 @@ import RefundListDialog from './components/prescription/refundListDialog.vue';
|
|||||||
import PatientList from './components/patientList.vue';
|
import PatientList from './components/patientList.vue';
|
||||||
import Diagnosis from './components/diagnosis/diagnosis.vue';
|
import Diagnosis from './components/diagnosis/diagnosis.vue';
|
||||||
import PrescriptionInfo from './components/prescription/prescriptionInfo.vue';
|
import PrescriptionInfo from './components/prescription/prescriptionInfo.vue';
|
||||||
// import eprescriptionlist from './components/eprescriptionlist.vue';
|
import eprescriptionlist from './components/eprescriptionlist.vue';
|
||||||
import HospitalizationDialog from './components/hospitalizationDialog.vue';
|
import HospitalizationDialog from './components/hospitalizationDialog.vue';
|
||||||
import tcmAdvice from './components/tcm/tcmAdvice.vue';
|
import tcmAdvice from './components/tcm/tcmAdvice.vue';
|
||||||
import { formatDate, formatDateStr } from '@/utils/index';
|
import { formatDate, formatDateStr } from '@/utils/index';
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
import { onBeforeRouteLeave } from 'vue-router';
|
import { onBeforeRouteLeave } from 'vue-router';
|
||||||
import { updatePatientInfo } from './components/store/patient.js';
|
|
||||||
|
|
||||||
// // 监听路由离开事件
|
// // 监听路由离开事件
|
||||||
// onBeforeRouteLeave((to, from, next) => {
|
// onBeforeRouteLeave((to, from, next) => {
|
||||||
@@ -303,18 +197,15 @@ const openRefundListDialog = ref(false);
|
|||||||
const openDialog = ref(false);
|
const openDialog = ref(false);
|
||||||
const openPrescriptionDialog = ref(false);
|
const openPrescriptionDialog = ref(false);
|
||||||
const saveStatus = ref(false);
|
const saveStatus = ref(false);
|
||||||
const outpatientEmrSaved = ref(false); // 门诊病历保存状态
|
|
||||||
const currentEncounterId = ref('');
|
const currentEncounterId = ref('');
|
||||||
const emits = defineEmits(['click']);
|
const emits = defineEmits(['click']);
|
||||||
// const activeTab = ref('emr');
|
const activeTab = ref('emr');
|
||||||
const activeTab = ref('hospitalizationEmr');
|
|
||||||
|
|
||||||
const patientList = ref([]);
|
const patientList = ref([]);
|
||||||
const patientInfo = ref({});
|
const patientInfo = ref({});
|
||||||
const visitTypeDisabled = ref(false);
|
const visitTypeDisabled = ref(false);
|
||||||
|
|
||||||
const prescriptionInfo = ref([]);
|
const prescriptionInfo = ref([]);
|
||||||
const registerTime = ref(formatDate(new Date()));
|
const registerTime = ref([formatDate(new Date()), formatDate(new Date())]);
|
||||||
const patientDrawerRef = ref();
|
const patientDrawerRef = ref();
|
||||||
const prescriptionRef = ref();
|
const prescriptionRef = ref();
|
||||||
const tcmRef = ref();
|
const tcmRef = ref();
|
||||||
@@ -328,41 +219,12 @@ const firstVisitDate = ref('');
|
|||||||
const disabled = computed(() => {
|
const disabled = computed(() => {
|
||||||
return Object.keys(patientInfo.value).length === 0;
|
return Object.keys(patientInfo.value).length === 0;
|
||||||
});
|
});
|
||||||
const shortcuts = [
|
|
||||||
{
|
|
||||||
text: '今天',
|
|
||||||
value: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '昨天',
|
|
||||||
value: () => {
|
|
||||||
const date = new Date();
|
|
||||||
date.setDate(date.getDate() - 1);
|
|
||||||
return date;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '三天内',
|
|
||||||
value: () => {
|
|
||||||
const date = new Date();
|
|
||||||
date.setDate(date.getDate() - 3);
|
|
||||||
return date;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '一周内',
|
|
||||||
value: () => {
|
|
||||||
const date = new Date();
|
|
||||||
date.setDate(date.getDate() - 7);
|
|
||||||
return date;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// const eprescriptionRef = ref();
|
const eprescriptionRef = ref();
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getWaitPatient();
|
getWaitPatient();
|
||||||
});
|
});
|
||||||
|
|
||||||
getPatientList();
|
getPatientList();
|
||||||
// 获取现诊患者列表
|
// 获取现诊患者列表
|
||||||
function getPatientList() {
|
function getPatientList() {
|
||||||
@@ -380,29 +242,29 @@ function setVisitType(type) {
|
|||||||
visitType.value = type;
|
visitType.value = type;
|
||||||
}
|
}
|
||||||
function checkPatientHistory(patient) {
|
function checkPatientHistory(patient) {
|
||||||
// 重置状态
|
// 重置状态
|
||||||
visitTypeDisabled.value = false;
|
visitTypeDisabled.value = false;
|
||||||
firstVisitDate.value = '';
|
firstVisitDate.value = '';
|
||||||
|
|
||||||
// 如果患者没有身份证号,无法判断是否为初诊
|
// 如果患者没有身份证号,无法判断是否为初诊
|
||||||
if (!patient.idCard) {
|
if (!patient.idCard) {
|
||||||
// 默认设置为初诊
|
// 默认设置为初诊
|
||||||
visitType.value = 'FIRST';
|
visitType.value = 'FIRST';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询患者历史就诊记录
|
// 查询患者历史就诊记录
|
||||||
const params = {
|
const params = {
|
||||||
patientId: patient.patientId,
|
patientId: patient.patientId,
|
||||||
idCard: patient.idCard
|
idCard: patient.idCard
|
||||||
};
|
};
|
||||||
|
|
||||||
getEmrHistoryList(params).then(res => {
|
getEmrHistoryList(params).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
const records = res.data?.records || [];
|
const records = res.data?.records || [];
|
||||||
// 过滤掉当前正在进行的就诊记录(排除相同encounterId的记录)
|
// 过滤掉当前正在进行的就诊记录(排除相同encounterId的记录)
|
||||||
const historyRecords = records.filter(record => record.encounterId !== patient.encounterId);
|
const historyRecords = records.filter(record => record.encounterId !== patient.encounterId);
|
||||||
|
|
||||||
// 如果有历史记录(排除当前就诊),则为复诊
|
// 如果有历史记录(排除当前就诊),则为复诊
|
||||||
if (historyRecords.length > 0) {
|
if (historyRecords.length > 0) {
|
||||||
visitType.value = 'FOLLOW_UP';
|
visitType.value = 'FOLLOW_UP';
|
||||||
@@ -451,9 +313,9 @@ function handleClick(tab) {
|
|||||||
case 'tcm':
|
case 'tcm':
|
||||||
tcmRef.value.getDiagnosisInfo();
|
tcmRef.value.getDiagnosisInfo();
|
||||||
break;
|
break;
|
||||||
// case 'eprescription':
|
case 'eprescription':
|
||||||
// eprescriptionRef.value.getList();
|
eprescriptionRef.value.getList();
|
||||||
// break;
|
break;
|
||||||
}
|
}
|
||||||
// if (tab != 'emr') {
|
// if (tab != 'emr') {
|
||||||
// if (!saveStatus.value) {
|
// if (!saveStatus.value) {
|
||||||
@@ -471,17 +333,12 @@ function handleClick(tab) {
|
|||||||
|
|
||||||
// 查看本次就诊处方单(从医嘱Tab页获取已开立的处方单信息)
|
// 查看本次就诊处方单(从医嘱Tab页获取已开立的处方单信息)
|
||||||
function getEnPrescription(encounterId) {
|
function getEnPrescription(encounterId) {
|
||||||
getEnPrescriptionInfo({ encounterId: encounterId }).then((res) => {
|
|
||||||
console.log('处方单 res', res);
|
|
||||||
prescriptionInfo.value = res.data.records;
|
|
||||||
openPrescriptionDialog.value = true;
|
|
||||||
});
|
|
||||||
// 检查是否有选中的患者
|
// 检查是否有选中的患者
|
||||||
if (!patientInfo.value || !patientInfo.value.encounterId) {
|
if (!patientInfo.value || !patientInfo.value.encounterId) {
|
||||||
proxy.$modal.msgWarning('请先选择患者');
|
proxy.$modal.msgWarning('请先选择患者');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否在医嘱Tab页,如果不在则切换到医嘱Tab页
|
// 检查是否在医嘱Tab页,如果不在则切换到医嘱Tab页
|
||||||
if (activeTab.value !== 'prescription') {
|
if (activeTab.value !== 'prescription') {
|
||||||
activeTab.value = 'prescription';
|
activeTab.value = 'prescription';
|
||||||
@@ -547,16 +404,13 @@ function handleOpen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleCardClick(item, index) {
|
function handleCardClick(item, index) {
|
||||||
currentEncounterId.value = '';
|
currentEncounterId.value = '';
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
patientList.value.forEach((patient) => {
|
patientList.value.forEach((patient) => {
|
||||||
patient.active = patient.encounterId === item.encounterId;
|
patient.active = patient.encounterId === item.encounterId;
|
||||||
});
|
});
|
||||||
patientInfo.value = item;
|
patientInfo.value = item;
|
||||||
// 将患者信息保存到store中,供hospitalizationEmr组件使用
|
|
||||||
updatePatientInfo(item);
|
|
||||||
activeTab.value = 'hospitalizationEmr';
|
|
||||||
|
|
||||||
// 优先使用数据库中保存的初复诊值
|
// 优先使用数据库中保存的初复诊值
|
||||||
if (item.visitType) {
|
if (item.visitType) {
|
||||||
visitType.value = item.visitType;
|
visitType.value = item.visitType;
|
||||||
@@ -572,11 +426,17 @@ function handleCardClick(item, index) {
|
|||||||
}
|
}
|
||||||
activeTab.value = 'emr';
|
activeTab.value = 'emr';
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
prescriptionRef.value.getListInfo();
|
// 确保所有组件引用都已初始化
|
||||||
tcmRef.value.getListInfo();
|
if (prescriptionRef.value) prescriptionRef.value.getListInfo();
|
||||||
diagnosisRef.value.getList();
|
if (tcmRef.value) tcmRef.value.getListInfo();
|
||||||
// eprescriptionRef.value.getList();
|
if (diagnosisRef.value) diagnosisRef.value.getList();
|
||||||
emrRef.value.getDetail(item.encounterId);
|
if (eprescriptionRef.value) eprescriptionRef.value.getList();
|
||||||
|
if (emrRef.value) {
|
||||||
|
emrRef.value.getDetail(item.encounterId);
|
||||||
|
} else {
|
||||||
|
console.error('emr组件未正确初始化');
|
||||||
|
proxy.$modal.msgError('病历组件加载失败,请刷新页面重试');
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}, 200);
|
}, 200);
|
||||||
@@ -606,8 +466,8 @@ function handleFinish(encounterId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleTimeChange(value) {
|
function handleTimeChange(value) {
|
||||||
queryParams.value.registerTimeSTime = value + ' 00:00:00';
|
queryParams.value.registerTimeSTime = value[0] + ' 00:00:00';
|
||||||
queryParams.value.registerTimeETime = value + ' 23:59:59';
|
queryParams.value.registerTimeETime = value[1] + ' 23:59:59';
|
||||||
getPatientList();
|
getPatientList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,17 +480,12 @@ function handleReceive(row) {
|
|||||||
getWaitPatient();
|
getWaitPatient();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理门诊病历保存成功事件
|
|
||||||
function handleEmrSaved(isSaved) {
|
|
||||||
outpatientEmrSaved.value = isSaved;
|
|
||||||
}
|
|
||||||
|
|
||||||
function openDrawer() {
|
function openDrawer() {
|
||||||
drawer.value = true;
|
drawer.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancelEncounter(){
|
function handleCancelEncounter() {
|
||||||
proxy.$modal.confirm('您确定要取消病人本次的就诊记录吗?','提示信息',{
|
proxy.$modal.confirm('您确定要取消病人本次的就诊记录吗?', '提示信息', {
|
||||||
confirmButtonText: '是(Y)',
|
confirmButtonText: '是(Y)',
|
||||||
cancelButtonText: '否(N)',
|
cancelButtonText: '否(N)',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
@@ -643,28 +498,18 @@ function handleCancelEncounter(){
|
|||||||
getPatientList();
|
getPatientList();
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
proxy.$modal.confirm('该病人本次就诊已经有业务产生,不能取消接诊!','提示信息',{
|
proxy.$modal.confirm('该病人本次就诊已经有业务产生,不能取消接诊!', '提示信息', {
|
||||||
confirmButtonText: '是(Y)',
|
confirmButtonText: '是(Y)',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// 用户取消操作
|
// 用户取消操作
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// 患者信息
|
|
||||||
.patient-info-descriptions {
|
|
||||||
:deep(.el-descriptions__label) {
|
|
||||||
font-size: 16px !important;
|
|
||||||
}
|
|
||||||
:deep(.el-descriptions__content) {
|
|
||||||
font-size: 16px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.patient-card {
|
.patient-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -817,6 +662,7 @@ function handleCancelEncounter(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-tabs__header) {
|
:deep(.el-tabs__header) {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -826,19 +672,23 @@ function handleCancelEncounter(){
|
|||||||
:deep(.el-drawer__header) {
|
:deep(.el-drawer__header) {
|
||||||
margin-bottom: 15px !important;
|
margin-bottom: 15px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-drawer__body) {
|
:deep(.el-drawer__body) {
|
||||||
padding: 10px !important;
|
padding: 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-badge {
|
.el-badge {
|
||||||
--el-badge-padding: 6px;
|
--el-badge-padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled-wrapper .overlay {
|
.disabled-wrapper .overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 999; /* 确保覆盖在内容上方 */
|
z-index: 999;
|
||||||
|
/* 确保覆盖在内容上方 */
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -85,7 +85,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import { is } from 'core-js/core/object'
|
|
||||||
import { getCurrentInstance, onBeforeMount, onMounted, reactive,ref } from 'vue'
|
import { getCurrentInstance, onBeforeMount, onMounted, reactive,ref } from 'vue'
|
||||||
// const { proxy } = getCurrentInstance();
|
// const { proxy } = getCurrentInstance();
|
||||||
const emits = defineEmits([])
|
const emits = defineEmits([])
|
||||||
|
|||||||
@@ -219,11 +219,11 @@ function getExpirationWarningCount() {
|
|||||||
let chartInstance = null;
|
let chartInstance = null;
|
||||||
|
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
getExpirationWarningCount();
|
// getExpirationWarningCount();
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getExpirationWarningCount();
|
// getExpirationWarningCount();
|
||||||
|
|
||||||
const ctx = document.getElementById('statsChart');
|
const ctx = document.getElementById('statsChart');
|
||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
|
|||||||
@@ -3,62 +3,64 @@
|
|||||||
* @Date: 2025-09-05 22:32:17
|
* @Date: 2025-09-05 22:32:17
|
||||||
* @Description: 申请单 (检验、检查、输血、手术)
|
* @Description: 申请单 (检验、检查、输血、手术)
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="applicationForm-bottom-btn">
|
<div>
|
||||||
<el-button-group>
|
<div class="applicationForm-bottom-btn">
|
||||||
<el-button
|
<el-button-group>
|
||||||
type="primary"
|
<el-button
|
||||||
@click="showApplicationFormDialog('LaboratoryTests')"
|
type="primary"
|
||||||
:disabled="!patientInfo?.inHospitalOrgId"
|
@click="showApplicationFormDialog('LaboratoryTests')"
|
||||||
>检验</el-button
|
:disabled="!patientInfo?.inHospitalOrgId"
|
||||||
>
|
>检验</el-button
|
||||||
<el-button
|
>
|
||||||
type="primary"
|
<el-button
|
||||||
@click="showApplicationFormDialog('MedicalExaminations')"
|
type="primary"
|
||||||
:disabled="!patientInfo?.inHospitalOrgId"
|
@click="showApplicationFormDialog('MedicalExaminations')"
|
||||||
>检查</el-button
|
:disabled="!patientInfo?.inHospitalOrgId"
|
||||||
>
|
>检查</el-button
|
||||||
<el-button
|
>
|
||||||
type="primary"
|
<el-button
|
||||||
@click="showApplicationFormDialog('BloodTransfusion')"
|
type="primary"
|
||||||
:disabled="!patientInfo?.inHospitalOrgId"
|
@click="showApplicationFormDialog('BloodTransfusion')"
|
||||||
>输血</el-button
|
:disabled="!patientInfo?.inHospitalOrgId"
|
||||||
>
|
>输血</el-button
|
||||||
<el-button
|
>
|
||||||
type="primary"
|
<el-button
|
||||||
@click="showApplicationFormDialog('Surgery')"
|
type="primary"
|
||||||
:disabled="!patientInfo?.inHospitalOrgId"
|
@click="showApplicationFormDialog('Surgery')"
|
||||||
>手术</el-button
|
:disabled="!patientInfo?.inHospitalOrgId"
|
||||||
>
|
>手术</el-button
|
||||||
</el-button-group>
|
>
|
||||||
</div>
|
</el-button-group>
|
||||||
<el-dialog
|
|
||||||
v-model="applicationFormDialogVisible"
|
|
||||||
destroy-on-close
|
|
||||||
width="1000px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:title="applicationFormTitle"
|
|
||||||
@close="closeDialog"
|
|
||||||
>
|
|
||||||
<component
|
|
||||||
:is="applicationFormName"
|
|
||||||
@submitOk="submitOk"
|
|
||||||
ref="applicationFormNameRef"
|
|
||||||
></component>
|
|
||||||
<template #footer>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<el-button @click="applicationFormDialogVisible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="submitApplicationForm"> 确认 </el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<el-dialog
|
||||||
</el-dialog>
|
v-model="applicationFormDialogVisible"
|
||||||
</template>
|
destroy-on-close
|
||||||
|
width="1000px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="applicationFormTitle"
|
||||||
|
@close="closeDialog"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="applicationFormName"
|
||||||
|
@submitOk="submitOk"
|
||||||
|
ref="applicationFormNameRef"
|
||||||
|
></component>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="applicationFormDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitApplicationForm"> 确认 </el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance, onBeforeMount, onMounted, reactive, ref, computed } from 'vue';
|
import { getCurrentInstance, onBeforeMount, onMounted, reactive, ref, computed } from 'vue';
|
||||||
import BloodTransfusion from './bloodTransfusion';
|
import BloodTransfusion from './bloodTransfusion';
|
||||||
import { patientInfo } from '../../../store/patient.js';
|
import { patientInfo } from '../../../store/patient.js';
|
||||||
import Surgery from './surgery.vue';
|
import Surgery from './surgery.vue';
|
||||||
import laboratoryTests from './laboratoryTests.vue';
|
import LaboratoryTests from './laboratoryTests.vue';
|
||||||
import MedicalExaminations from './medicalExaminations.vue';
|
import MedicalExaminations from './medicalExaminations.vue';
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const emits = defineEmits([]);
|
const emits = defineEmits([]);
|
||||||
|
|||||||
@@ -234,17 +234,19 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取医疗机构列表
|
// 获取医疗机构列表
|
||||||
getUserBindTenantList().then((res) => {
|
if (loginForm.value.username) {
|
||||||
tenantOptions.value = res.data.map(item => ({
|
getUserBindTenantList(loginForm.value.username).then((res) => {
|
||||||
label: item.tenantName,
|
tenantOptions.value = res.data.map(item => ({
|
||||||
value: item.id
|
label: item.tenantName,
|
||||||
}));
|
value: item.id
|
||||||
// 如果只有一个医疗机构,自动选中
|
}));
|
||||||
if (tenantOptions.value.length === 1) {
|
// 如果只有一个医疗机构,自动选中
|
||||||
loginForm.value.tenantId = tenantOptions.value[0].value;
|
if (tenantOptions.value.length === 1) {
|
||||||
currentTenantName.value = tenantOptions.value[0].label;
|
loginForm.value.tenantId = tenantOptions.value[0].value;
|
||||||
}
|
currentTenantName.value = tenantOptions.value[0].label;
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleLogin() {
|
function handleLogin() {
|
||||||
@@ -476,7 +478,10 @@ function handleUserName(value) {
|
|||||||
//getCode();
|
//getCode();
|
||||||
getCookie();
|
getCookie();
|
||||||
|
|
||||||
getTenantList(loginForm.value.username);
|
// 只有当 username 存在时才获取租户列表
|
||||||
|
if (loginForm.value.username) {
|
||||||
|
getTenantList(loginForm.value.username);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -648,4 +653,4 @@ html, body {
|
|||||||
:deep(.el-form-item) {
|
:deep(.el-form-item) {
|
||||||
margin-bottom: 15px !important; // 减小输入框之间的距离
|
margin-bottom: 15px !important; // 减小输入框之间的距离
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -49,13 +49,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-item">
|
<div class="filter-item">
|
||||||
<label>科室:</label>
|
<label>科室:</label>
|
||||||
<select>
|
<el-tree-select
|
||||||
<option value="">请选择科室</option>
|
placeholder="请选择科室"
|
||||||
<option value="内科">内科</option>
|
:data="departments"
|
||||||
<option value="儿科">儿科</option>
|
:props="{
|
||||||
<option value="外科">外科</option>
|
value: 'name',
|
||||||
<option value="妇科">妇科</option>
|
label: 'name',
|
||||||
</select>
|
children: 'children'
|
||||||
|
}"
|
||||||
|
value-key="name"
|
||||||
|
style="width: 100%;"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-item">
|
<div class="filter-item">
|
||||||
<label>用户:</label>
|
<label>用户:</label>
|
||||||
@@ -140,9 +144,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, reactive, computed, onMounted } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
import { Edit, View, Delete } from '@element-plus/icons-vue';
|
import { Edit, View, Delete } from '@element-plus/icons-vue';
|
||||||
|
import { getLocationTree } from '@/views/charge/outpatientregistration/components/outpatientregistration';
|
||||||
|
|
||||||
// 创建路由实例
|
// 创建路由实例
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -150,6 +155,46 @@ const router = useRouter();
|
|||||||
// 侧边栏状态
|
// 侧边栏状态
|
||||||
const sidebarActive = ref(false);
|
const sidebarActive = ref(false);
|
||||||
|
|
||||||
|
// 科室数据
|
||||||
|
const departments = ref([]);
|
||||||
|
|
||||||
|
// 获取科室数据 - 与门诊挂号页面保持一致
|
||||||
|
function getDepartmentList() {
|
||||||
|
console.log('调用getLocationTree API...');
|
||||||
|
getLocationTree().then((response) => {
|
||||||
|
console.log('getLocationTree API完整返回:', response);
|
||||||
|
console.log('getLocationTree API数据结构:', JSON.stringify(response.data, null, 2));
|
||||||
|
|
||||||
|
// 检查数据结构并转换为适合el-tree-select的格式
|
||||||
|
if (Array.isArray(response.data)) {
|
||||||
|
// 直接使用数组数据
|
||||||
|
departments.value = response.data;
|
||||||
|
} else if (response.data && response.data.records) {
|
||||||
|
// 处理分页格式数据
|
||||||
|
departments.value = response.data.records;
|
||||||
|
} else if (response.data && response.data.rows) {
|
||||||
|
// 处理另一种分页格式数据
|
||||||
|
departments.value = response.data.rows;
|
||||||
|
} else {
|
||||||
|
console.error('API返回数据格式不符合预期:', response.data);
|
||||||
|
departments.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('最终科室数据:', JSON.stringify(departments.value, null, 2));
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('获取科室数据失败:', error);
|
||||||
|
departments.value = [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取科室数据 - 与门诊挂号页面保持一致,在组件初始化时直接调用
|
||||||
|
getDepartmentList();
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
onMounted(() => {
|
||||||
|
// 其他初始化逻辑
|
||||||
|
});
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const tableData = ref([
|
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: 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: '徐斌'},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -16,97 +16,147 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="挂号处理" name="tab3">
|
<el-tab-pane label="挂号处理" name="tab3">
|
||||||
<el-form ref="formRef" :model="formData" label-width="120px" class="config-form">
|
<el-form ref="formRef" :model="formData" label-width="150px" class="config-form compact-form">
|
||||||
<!-- 第一行 -->
|
<!-- 第一行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item label="病历本费用(元)" prop="medicalRecordFee" style="margin-right: 20px;">
|
<el-form-item label="病历本费用(元)" prop="medicalRecordFee">
|
||||||
<el-input v-model="formData.medicalRecordFee" style="width: 180px" />
|
<el-input-number v-model="formData.medicalRecordFee" style="width: 150px" :controls-position="'right'" :step="1" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="margin-left: 20px;">
|
<el-form-item label="" prop="medicalRecordFlag" checkbox-label>
|
||||||
<el-checkbox v-model="formData.medicalRecordFlag">病历费入账标志</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.medicalRecordFlag" style="margin-right: 8px;" />
|
||||||
|
<span>病历费入账标志</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第二行 -->
|
<!-- 第二行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item label="就诊卡费(元)" prop="patientCardFee" style="margin-right: 20px;">
|
<el-form-item label="就诊卡费(元)" prop="patientCardFee">
|
||||||
<el-input v-model="formData.patientCardFee" style="width: 180px" />
|
<el-input-number v-model="formData.patientCardFee" style="width: 150px" :controls-position="'right'" :step="1" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="margin-left: 20px;">
|
<el-form-item label="" prop="isNightShift" checkbox-label>
|
||||||
<el-checkbox v-model="formData.isNightShift">是否启用晚班</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.isNightShift" style="margin-right: 8px;" />
|
||||||
|
<span>是否启用晚班</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第三行 -->
|
<!-- 第三行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item style="margin-right: 40px;">
|
<el-form-item label="" prop="patientCardFlag" checkbox-label>
|
||||||
<el-checkbox v-model="formData.patientCardFlag">就诊卡记账标志</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.patientCardFlag" style="margin-right: 8px;" />
|
||||||
|
<span>就诊卡记账标志</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="上午接诊起始时间" prop="morningStartTime" style="width: 300px; white-space: nowrap;">
|
<el-form-item label="上午接诊起始时间" prop="morningStartTime">
|
||||||
<el-input v-model="formData.morningStartTime" style="width: 120px" />
|
<el-input v-model="formData.morningStartTime" style="width: 150px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第四行 -->
|
<!-- 第四行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item style="margin-right: 40px;">
|
<el-form-item label="" prop="autoGenerateOutpatientNo" checkbox-label>
|
||||||
<el-checkbox v-model="formData.autoGenerateOutpatientNo">自动产生门诊号</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.autoGenerateOutpatientNo" style="margin-right: 8px;" />
|
||||||
|
<span>自动产生门诊号</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="margin-right: 40px;">
|
<el-form-item label="" prop="allowModifyOutpatientNo" checkbox-label>
|
||||||
<el-checkbox v-model="formData.allowModifyOutpatientNo">建档时是否允许修改门诊号</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.allowModifyOutpatientNo" style="margin-right: 8px;" />
|
||||||
|
<span>允许修改门诊号</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第五行 -->
|
<!-- 第五行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item label="下午起始时间" prop="afternoonStartTime" style="margin-right: 40px;">
|
<el-form-item label="下午起始时间" prop="afternoonStartTime">
|
||||||
<el-input v-model="formData.afternoonStartTime" style="width: 120px" />
|
<el-input v-model="formData.afternoonStartTime" style="width: 150px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="晚上起始时间" prop="eveningStartTime">
|
<el-form-item label="晚上起始时间" prop="eveningStartTime">
|
||||||
<el-input v-model="formData.eveningStartTime" style="width: 120px" />
|
<el-input v-model="formData.eveningStartTime" style="width: 150px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第六行 -->
|
<!-- 第六行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item label="挂号有效期" prop="registrationValidity" style="margin-right: 40px;">
|
<el-form-item label="挂号有效期" prop="registrationValidity">
|
||||||
<el-input v-model="formData.registrationValidity" style="width: 120px" />
|
<el-input-number v-model="formData.registrationValidity" style="width: 150px" :controls-position="'right'" :step="1" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="挂号单据模式" prop="registrationDocumentMode">
|
<el-form-item label="挂号单据模式" prop="registrationDocumentMode">
|
||||||
<el-select v-model="formData.registrationDocumentMode" style="width: 150px">
|
<el-select v-model="formData.registrationDocumentMode" style="width: 150px">
|
||||||
<el-option label="使用发票" value="使用发票" />
|
<el-option label="使用发票" value="使用发票" />
|
||||||
<el-option label="其他模式" value="其他模式" />
|
<el-option label="普通单据" value="其他模式" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第七行 -->
|
<!-- 第七行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item style="margin-right: 40px;">
|
<el-form-item label="" prop="exemptFlag" checkbox-label>
|
||||||
<el-checkbox v-model="formData.exemptFlag">减免标志</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.exemptFlag" style="margin-right: 8px;" />
|
||||||
|
<span>减免标志</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="margin-right: 40px;">
|
<el-form-item label="" prop="consultationFlag" checkbox-label>
|
||||||
<el-checkbox v-model="formData.consultationFlag">义诊标志</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.consultationFlag" style="margin-right: 8px;" />
|
||||||
|
<span>义诊标志</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="margin-right: 40px;">
|
<el-form-item label="" prop="enableHolidayFeeFloat" checkbox-label>
|
||||||
<el-checkbox v-model="formData.enableHolidayFeeFloat">启用法定节假日挂号费浮动</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.enableHolidayFeeFloat" style="margin-right: 8px;" />
|
||||||
|
<span>节假日费浮动</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第八行 -->
|
<!-- 第八行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item label="监护人规定年龄" prop="guardianAge" style="margin-right: 40px;">
|
<el-form-item label="监护人规定年龄" prop="guardianAge">
|
||||||
<el-input v-model="formData.guardianAge" style="width: 120px" />
|
<el-input-number v-model="formData.guardianAge" style="width: 150px" :controls-position="'right'" :step="1" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item label="" prop="enableDoubleScreen" checkbox-label>
|
||||||
<el-checkbox v-model="formData.enableDoubleScreen">门诊挂号启用双屏</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.enableDoubleScreen" style="margin-right: 8px;" />
|
||||||
|
<span>挂号启用双屏</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第九行 -->
|
<!-- 第九行 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-form-item>
|
<el-form-item label="" prop="optionalRegistrationType" checkbox-label>
|
||||||
<el-checkbox v-model="formData.optionalRegistrationType">挂号类型可选择</el-checkbox>
|
<template #label>
|
||||||
|
<div class="checkbox-label-container">
|
||||||
|
<el-checkbox v-model="formData.optionalRegistrationType" style="margin-right: 8px;" />
|
||||||
|
<span>挂号类型可选择</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -132,10 +182,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive } from 'vue';
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { getConfigKey, addConfig, updateConfig } from '@/api/system/config';
|
import { listConfig, getConfigKey, addConfig, updateConfig } from '@/api/system/config';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const formRef = ref(null);
|
const formRef = ref(null);
|
||||||
@@ -164,6 +214,61 @@ const formData = reactive({
|
|||||||
isPrint: false,
|
isPrint: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 加载配置数据
|
||||||
|
const loadConfigData = async (showSuccessMessage = true) => {
|
||||||
|
try {
|
||||||
|
// 调用系统配置API获取数据,不设置configType过滤条件以获取所有配置
|
||||||
|
const response = await listConfig({ pageSize: 1000 });
|
||||||
|
|
||||||
|
// 处理响应数据,兼容不同的返回格式
|
||||||
|
let configs = [];
|
||||||
|
if (response && response.data) {
|
||||||
|
if (Array.isArray(response.data)) {
|
||||||
|
configs = response.data;
|
||||||
|
} else if (response.data.rows && Array.isArray(response.data.rows)) {
|
||||||
|
configs = response.data.rows;
|
||||||
|
} else {
|
||||||
|
console.error('返回数据格式不符合预期:', response);
|
||||||
|
}
|
||||||
|
} else if (response && response.rows && Array.isArray(response.rows)) {
|
||||||
|
configs = response.rows;
|
||||||
|
} else {
|
||||||
|
console.error('API返回空响应:', response);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('loadConfigData - 获取到的配置列表:', configs);
|
||||||
|
console.log('loadConfigData - 配置总数:', configs.length);
|
||||||
|
|
||||||
|
// 将配置数据映射到表单
|
||||||
|
if (configs && configs.length > 0) {
|
||||||
|
configs.forEach(config => {
|
||||||
|
const { configKey, configValue } = config;
|
||||||
|
|
||||||
|
// 处理布尔类型字段
|
||||||
|
if (configKey in formData) {
|
||||||
|
if (typeof formData[configKey] === 'boolean') {
|
||||||
|
formData[configKey] = configValue === '1';
|
||||||
|
} else {
|
||||||
|
formData[configKey] = configValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSuccessMessage) {
|
||||||
|
ElMessage.success('配置数据加载成功');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载配置数据失败:', error);
|
||||||
|
ElMessage.warning('无法加载配置数据,使用默认值');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载时加载数据
|
||||||
|
onMounted(() => {
|
||||||
|
loadConfigData();
|
||||||
|
});
|
||||||
|
|
||||||
// 默认按钮点击事件
|
// 默认按钮点击事件
|
||||||
const handleDefault = () => {
|
const handleDefault = () => {
|
||||||
// 重置为默认值
|
// 重置为默认值
|
||||||
@@ -225,40 +330,88 @@ const handleSave = async () => {
|
|||||||
let successCount = 0;
|
let successCount = 0;
|
||||||
let failedParams = [];
|
let failedParams = [];
|
||||||
|
|
||||||
// 调用系统配置API保存每个参数
|
try {
|
||||||
for (const config of configData) {
|
// 先获取所有配置,避免重复调用API
|
||||||
try {
|
const allConfigsResponse = await listConfig({ pageSize: 1000 });
|
||||||
// 先查询是否存在该配置
|
console.log('handleSave - listConfig返回完整结果:', JSON.stringify(allConfigsResponse));
|
||||||
const existingConfig = await getConfigKey(config.configKey, { skipErrorMsg: true });
|
|
||||||
|
// 检查返回结果结构
|
||||||
if (existingConfig.data && existingConfig.data.configId) {
|
let allConfigs = [];
|
||||||
// 如果存在则更新,保留原有数据的configId
|
if (allConfigsResponse.code === 200) {
|
||||||
await updateConfig({
|
if (allConfigsResponse.data && Array.isArray(allConfigsResponse.data)) {
|
||||||
...config,
|
allConfigs = allConfigsResponse.data;
|
||||||
configId: existingConfig.data.configId,
|
} else if (allConfigsResponse.data && allConfigsResponse.data.rows) {
|
||||||
createTime: existingConfig.data.createTime, // 保留创建时间
|
allConfigs = allConfigsResponse.data.rows;
|
||||||
remark: existingConfig.data.remark || '收费系统配置参数' // 保留或设置默认备注
|
} else if (Array.isArray(allConfigsResponse.rows)) {
|
||||||
});
|
allConfigs = allConfigsResponse.rows;
|
||||||
} else {
|
} else if (Array.isArray(allConfigsResponse)) {
|
||||||
// 如果不存在则新增,添加默认备注
|
allConfigs = allConfigsResponse;
|
||||||
await addConfig({
|
|
||||||
...config,
|
|
||||||
remark: '收费系统配置参数'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
successCount++;
|
|
||||||
} catch (paramError) {
|
|
||||||
console.error(`保存参数 ${config.configName} (${config.configKey}) 失败:`, paramError);
|
|
||||||
failedParams.push(config.configName);
|
|
||||||
// 继续处理下一个参数,不中断整体流程
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('handleSave - 最终获取到的所有配置:', allConfigs);
|
||||||
|
console.log('handleSave - 配置总数:', allConfigs.length);
|
||||||
|
|
||||||
|
// 构建配置项映射表,方便快速查找
|
||||||
|
const configMap = new Map();
|
||||||
|
allConfigs.forEach(config => {
|
||||||
|
configMap.set(config.configKey, config);
|
||||||
|
console.log('handleSave - 添加到映射表:', config.configKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用系统配置API保存每个参数
|
||||||
|
for (const config of configData) {
|
||||||
|
try {
|
||||||
|
const existingConfig = configMap.get(config.configKey);
|
||||||
|
|
||||||
|
console.log(`处理参数: ${config.configName} (${config.configKey})`);
|
||||||
|
console.log(`现有配置:`, existingConfig);
|
||||||
|
console.log(`要保存的值:`, config.configValue);
|
||||||
|
|
||||||
|
if (existingConfig && existingConfig.configId) {
|
||||||
|
// 如果存在则更新,保留原有数据的configId和创建时间
|
||||||
|
console.log(`更新参数 ${config.configKey},使用configId: ${existingConfig.configId}`);
|
||||||
|
const updateResult = await updateConfig({
|
||||||
|
...config,
|
||||||
|
configId: existingConfig.configId,
|
||||||
|
createTime: existingConfig.createTime,
|
||||||
|
remark: existingConfig.remark || '收费系统配置参数',
|
||||||
|
configType: existingConfig.configType || 'N'
|
||||||
|
});
|
||||||
|
console.log(`更新结果:`, updateResult);
|
||||||
|
} else {
|
||||||
|
// 如果不存在则新增,添加默认备注
|
||||||
|
console.log(`新增参数 ${config.configKey}`);
|
||||||
|
const addResult = await addConfig({
|
||||||
|
...config,
|
||||||
|
remark: '收费系统配置参数',
|
||||||
|
configType: 'N'
|
||||||
|
});
|
||||||
|
console.log(`新增结果:`, addResult);
|
||||||
|
}
|
||||||
|
successCount++;
|
||||||
|
} catch (paramError) {
|
||||||
|
console.error(`保存参数 ${config.configName} (${config.configKey}) 失败:`, paramError);
|
||||||
|
console.error(`错误详情:`, paramError.response || paramError);
|
||||||
|
failedParams.push(config.configName);
|
||||||
|
// 继续处理下一个参数,不中断整体流程
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取配置列表失败:', error);
|
||||||
|
ElMessage.error('获取配置列表失败,无法保存参数');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据保存结果显示相应消息
|
// 根据保存结果显示相应消息
|
||||||
if (failedParams.length === 0) {
|
if (failedParams.length === 0) {
|
||||||
ElMessage.success(`所有 ${successCount} 个参数保存成功`);
|
ElMessage.success(`保存成功`);
|
||||||
|
// 保存成功后重新加载数据,确保页面显示最新配置
|
||||||
|
loadConfigData(false); // 不显示加载成功消息
|
||||||
} else if (successCount > 0) {
|
} else if (successCount > 0) {
|
||||||
ElMessage.warning(`${successCount} 个参数保存成功,但以下 ${failedParams.length} 个参数保存失败: ${failedParams.join(', ')}`);
|
ElMessage.warning(`${successCount} 个参数保存成功,但以下 ${failedParams.length} 个参数保存失败: ${failedParams.join(', ')}`);
|
||||||
|
// 部分成功也重新加载数据
|
||||||
|
loadConfigData(false); // 不显示加载成功消息
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(`所有参数保存失败,请检查系统配置`);
|
ElMessage.error(`所有参数保存失败,请检查系统配置`);
|
||||||
}
|
}
|
||||||
@@ -300,23 +453,96 @@ const handleClose = () => {
|
|||||||
.form-row {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 15px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap; /* 禁止行内元素换行 */
|
||||||
|
overflow-x: hidden; /* 防止溢出 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-form .el-form-item {
|
.config-form .el-form-item {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
margin-right: 0;
|
margin-right: 60px; /* 增加间距 */
|
||||||
|
min-width: 350px; /* 增加最小宽度 */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0; /* 禁止压缩 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 紧凑表单样式 */
|
||||||
|
.compact-form {
|
||||||
|
label-width: 150px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compact-form .el-form-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 所有表单标签的统一样式 */
|
||||||
.config-form .el-form-item__label {
|
.config-form .el-form-item__label {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
width: 120px;
|
width: 220px !important; /* 足够宽的标签宽度 */
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 15px;
|
||||||
|
white-space: nowrap !important; /* 强制不换行 */
|
||||||
|
overflow: visible !important; /* 允许内容溢出(确保不截断) */
|
||||||
|
text-overflow: clip !important; /* 不显示省略号 */
|
||||||
|
flex-shrink: 0 !important; /* 禁止压缩 */
|
||||||
|
font-size: 14px !important; /* 统一字体大小 */
|
||||||
|
line-height: 32px !important; /* 统一行高 */
|
||||||
|
height: 32px !important; /* 统一高度 */
|
||||||
|
margin: 0 !important; /* 清除默认边距 */
|
||||||
|
padding: 0 15px 0 0 !important; /* 统一内边距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 复选框标签样式 */
|
||||||
|
.compact-form .el-form-item[checkbox-label] .el-form-item__label {
|
||||||
|
padding-right: 10px;
|
||||||
|
width: 150px !important;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.compact-form .el-form-item[checkbox-label] .el-form-item__content {
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 自定义复选框标签容器 */
|
||||||
|
.checkbox-label-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label-container span {
|
||||||
|
font-size: 14px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 空标签的样式,用于对齐 */
|
||||||
|
.config-form .el-form-item__label:empty {
|
||||||
|
width: 18px !important;
|
||||||
|
padding-right: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.config-form .el-form-item--medium .el-form-item__content {
|
.config-form .el-form-item--medium .el-form-item__content {
|
||||||
line-height: 28px;
|
line-height: 32px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-form .el-checkbox {
|
||||||
|
margin-left: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保输入框与标签对齐 */
|
||||||
|
.config-form .el-input {
|
||||||
|
height: 32px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-form .el-input__wrapper {
|
||||||
|
height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
|
|||||||
@@ -252,11 +252,11 @@ function getList() {
|
|||||||
...queryParams.value,
|
...queryParams.value,
|
||||||
flg: queryParams.value.flg == 1 ? '1' : null,
|
flg: queryParams.value.flg == 1 ? '1' : null,
|
||||||
};
|
};
|
||||||
getExpirationWarning(params).then((res) => {
|
// getExpirationWarning(params).then((res) => {
|
||||||
loading.value = false;
|
// loading.value = false;
|
||||||
purchaseinventoryList.value = res.data.records;
|
// purchaseinventoryList.value = res.data.records;
|
||||||
total.value = res.data.total;
|
// total.value = res.data.total;
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
|
|||||||
@@ -306,11 +306,12 @@ export function ybRequestFileUp(data) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function getExpirationWarning(query) {
|
export function getExpirationWarning(query) {
|
||||||
return request({
|
// return request({
|
||||||
url: '/inventory-manage/product/expiration-warning',
|
// url: '/inventory-manage/product/expiration-warning',
|
||||||
method: 'get',
|
// method: 'get',
|
||||||
params: query
|
// params: query
|
||||||
})
|
// })
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
export function getClroptins(query) {
|
export function getClroptins(query) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
25
openhis-ui-vue3/test-util-extend.js
Normal file
25
openhis-ui-vue3/test-util-extend.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// 测试util._extend是否存在
|
||||||
|
if (typeof process !== 'undefined' && process.versions && process.versions.node) {
|
||||||
|
try {
|
||||||
|
const util = require('util');
|
||||||
|
console.log('util._extend存在吗?', typeof util._extend);
|
||||||
|
if (typeof util._extend === 'function') {
|
||||||
|
console.log('util._extend是一个函数');
|
||||||
|
} else {
|
||||||
|
console.log('util._extend不是一个函数,添加兼容实现');
|
||||||
|
util._extend = function(destination, source) {
|
||||||
|
for (var key in source) {
|
||||||
|
if (source.hasOwnProperty(key)) {
|
||||||
|
destination[key] = source[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destination;
|
||||||
|
};
|
||||||
|
console.log('兼容实现添加成功');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('util模块加载失败:', e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('不在Node.js环境中');
|
||||||
|
}
|
||||||
@@ -79,4 +79,4 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Reference in New Issue
Block a user