优化认证

This commit is contained in:
18796357645 2025-05-18 23:08:33 +08:00
parent 951421c70f
commit e0d6211dce
15 changed files with 329 additions and 219 deletions

View File

@ -1,6 +1,7 @@
package io.modules.item.dto; package io.modules.item.dto;
import io.modules.item.entity.DoctorsEntity; import io.modules.item.entity.DoctorsEntity;
import io.modules.item.entity.OrderEntity;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.SchemaProperty; import io.swagger.v3.oas.annotations.media.SchemaProperty;
import lombok.Data; import lombok.Data;
@ -11,9 +12,6 @@ import java.util.Date;
/** /**
* 授权表 * 授权表
*
* @author Mark #
* @since 1.0.0 2025-05-13
*/ */
@Data @Data
@Schema(name = "授权表") @Schema(name = "授权表")
@ -40,5 +38,5 @@ public class AuditDTO implements Serializable {
private DoctorsEntity doctors; private DoctorsEntity doctors;
private DoctorsEntity oneDoctors; private DoctorsEntity oneDoctors;
private OrderEntity orderEntity;
} }

View File

@ -1,5 +1,6 @@
package io.modules.item.dto; package io.modules.item.dto;
import io.modules.item.entity.CaseEntity;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.SchemaProperty; import io.swagger.v3.oas.annotations.media.SchemaProperty;
import lombok.Data; import lombok.Data;
@ -55,4 +56,5 @@ public class CaseDTO implements Serializable {
@SchemaProperty(name = "用户名") @SchemaProperty(name = "用户名")
private String username; private String username;
} }

View File

@ -2,6 +2,7 @@ package io.modules.item.dto;
import io.modules.item.dao.FrontUserDao; import io.modules.item.dao.FrontUserDao;
import io.modules.item.entity.AuditEntity; import io.modules.item.entity.AuditEntity;
import io.modules.item.entity.CaseEntity;
import io.modules.item.entity.FrontUserEntity; import io.modules.item.entity.FrontUserEntity;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.SchemaProperty; import io.swagger.v3.oas.annotations.media.SchemaProperty;
@ -62,9 +63,16 @@ public class OrderDTO implements Serializable {
//订单编号 //订单编号
private Long orderId; private Long orderId;
private String scoreContent; private String scoreContent;
private String remark; private String remark;
private DoctorsDTO doctors; private DoctorsDTO doctors;
private FrontUserEntity userDTO; private FrontUserEntity userDTO;
private AuditEntity audit;
private AuditEntity auditEntity;
private CaseEntity caseEntity ;
} }

View File

@ -7,9 +7,6 @@ import java.util.Date;
/** /**
* 授权表 * 授权表
*
* @author Mark #
* @since 1.0.0 2025-05-13
*/ */
@Data @Data
@TableName("tb_audit") @TableName("tb_audit")

View File

@ -12,7 +12,6 @@ import java.util.Date;
@Data @Data
@TableName("tb_order") @TableName("tb_order")
public class OrderEntity { public class OrderEntity {
/** /**
* 订单编号 * 订单编号
*/ */
@ -22,6 +21,7 @@ public class OrderEntity {
*/ */
private Long userId; private Long userId;
private String paymentMethod; private String paymentMethod;
/** /**
@ -57,7 +57,6 @@ public class OrderEntity {
*/ */
private String content; private String content;
//评价内容 //评价内容
private String scoreContent; private String scoreContent;
//备注 //备注
@ -71,6 +70,4 @@ public class OrderEntity {
* 订单创建时间 * 订单创建时间
*/ */
private Date createdTime; private Date createdTime;
} }

View File

@ -37,9 +37,6 @@ import java.util.stream.Collectors;
/** /**
* 授权表 * 授权表
*
* @author Mark #
* @since 1.0.0 2025-05-13
*/ */
@RestController @RestController
@RequestMapping("api/audit") @RequestMapping("api/audit")
@ -74,6 +71,16 @@ public class AuditController {
}) })
public Result<PageData<AuditDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) { public Result<PageData<AuditDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
PageData<AuditDTO> page = auditService.page(params); PageData<AuditDTO> page = auditService.page(params);
List<AuditDTO> collect = page.getList().stream().map(e -> {
//查询订单信息
OrderEntity orderEntity = orderDao.selectById(e.getOrderId());
e.setOrderEntity(orderEntity);
return e;
}).collect(Collectors.toList());
page.setList(collect);
return new Result<PageData<AuditDTO>>().ok(page); return new Result<PageData<AuditDTO>>().ok(page);
} }

View File

@ -1,6 +1,7 @@
package io.controller; package io.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.common.constant.Constant; import io.common.constant.Constant;
import io.common.page.PageData; import io.common.page.PageData;
import io.common.utils.Result; import io.common.utils.Result;
@ -9,8 +10,11 @@ import io.common.validator.ValidatorUtils;
import io.common.validator.group.AddGroup; import io.common.validator.group.AddGroup;
import io.common.validator.group.DefaultGroup; import io.common.validator.group.DefaultGroup;
import io.common.validator.group.UpdateGroup; import io.common.validator.group.UpdateGroup;
import io.entity.OrderEntity;
import io.modules.item.dao.CaseDao;
import io.modules.item.dto.CaseDTO; import io.modules.item.dto.CaseDTO;
import io.modules.item.dto.OrderDTO; import io.modules.item.dto.OrderDTO;
import io.modules.item.entity.CaseEntity;
import io.modules.item.service.CaseService; import io.modules.item.service.CaseService;
import io.modules.item.service.OrderService; import io.modules.item.service.OrderService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -28,9 +32,7 @@ import java.util.Map;
/** /**
* 病例表 * 病例表
*
* @author Mark #
* @since 1.0.0 2025-05-13
*/ */
@RestController @RestController
@RequestMapping("/api/case") @RequestMapping("/api/case")
@ -40,6 +42,9 @@ public class CaseController {
@Autowired @Autowired
private CaseService caseService; private CaseService caseService;
@Autowired
private CaseDao caseDao;
@Autowired @Autowired
private OrderService orderService; private OrderService orderService;
@ -51,21 +56,25 @@ public class CaseController {
@Parameter(name = Constant.ORDER_FIELD, description = "排序字段", in = ParameterIn.QUERY, ref="String") , @Parameter(name = Constant.ORDER_FIELD, description = "排序字段", in = ParameterIn.QUERY, ref="String") ,
@Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)", in = ParameterIn.QUERY, ref="String") @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)", in = ParameterIn.QUERY, ref="String")
}) })
public Result<PageData<CaseDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params){ public Result<PageData<CaseDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params){
PageData<CaseDTO> page = caseService.page(params); PageData<CaseDTO> page = caseService.page(params);
return new Result<PageData<CaseDTO>>().ok(page); return new Result<PageData<CaseDTO>>().ok(page);
} }
@GetMapping("{id}") @PostMapping("getCase")
@Operation(summary = "信息") @Operation(summary = "信息")
public Result<CaseEntity> get(@RequestBody CaseDTO dto){
public Result<CaseDTO> get(@PathVariable("id") Long id){ //通过订单查看病例
CaseDTO data = caseService.get(id); LambdaQueryWrapper<CaseEntity> lwq = new LambdaQueryWrapper<>();
return new Result<CaseDTO>().ok(data); lwq.eq(CaseEntity::getOrderId,dto.getOrderId());
lwq.eq(CaseEntity::getItemId,dto.getItemId());
CaseEntity caseEntity = caseDao.selectOne(lwq);
return new Result<CaseEntity>().ok(caseEntity);
} }
@PostMapping @PostMapping
@Operation(summary = "保存") @Operation(summary = "保存")
public Result save(@RequestBody CaseDTO dto){ public Result save(@RequestBody CaseDTO dto){

View File

@ -1,6 +1,7 @@
package io.controller; package io.controller;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.annotation.Login; import io.annotation.Login;
import io.common.constant.Constant; import io.common.constant.Constant;
@ -11,23 +12,20 @@ import io.common.validator.ValidatorUtils;
import io.common.validator.group.AddGroup; import io.common.validator.group.AddGroup;
import io.common.validator.group.DefaultGroup; import io.common.validator.group.DefaultGroup;
import io.common.validator.group.UpdateGroup; import io.common.validator.group.UpdateGroup;
import io.modules.item.dao.AuditDao; import io.modules.item.dao.*;
import io.modules.item.dao.DoctorsDao; import io.modules.item.dto.CaseDTO;
import io.modules.item.dao.FrontUserDao;
import io.modules.item.dao.OrderDao;
import io.modules.item.dto.DoctorsDTO; import io.modules.item.dto.DoctorsDTO;
import io.modules.item.dto.OrderDTO; import io.modules.item.dto.OrderDTO;
import io.modules.item.dto.UserDTO; import io.modules.item.dto.UserDTO;
import io.modules.item.entity.AuditEntity; import io.modules.item.entity.*;
import io.modules.item.entity.DoctorsEntity; import io.modules.item.service.CaseService;
import io.modules.item.entity.FrontUserEntity;
import io.modules.item.entity.OrderEntity;
import io.modules.item.service.DoctorsService; import io.modules.item.service.DoctorsService;
import io.modules.item.service.OrderService; import io.modules.item.service.OrderService;
import io.modules.item.service.UserService; import io.modules.item.service.UserService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.NumberUtils; import org.springframework.util.NumberUtils;
@ -37,6 +35,7 @@ import io.swagger.v3.oas.annotations.Parameters;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -51,6 +50,10 @@ public class OrderController {
@Autowired @Autowired
private OrderService orderService; private OrderService orderService;
@Autowired
private CaseDao caseDao;
@Autowired @Autowired
private AuditDao auditDao; private AuditDao auditDao;
@ -85,6 +88,17 @@ public class OrderController {
doctorsDTO.setImg(uploadUrl + doctorsDTO.getImg()); doctorsDTO.setImg(uploadUrl + doctorsDTO.getImg());
e.setDoctors(doctorsDTO); e.setDoctors(doctorsDTO);
} }
//如果不是预约
if (e.getOrderStatus() != 0){
LambdaQueryWrapper<CaseEntity> lwq = new LambdaQueryWrapper<>();
lwq.eq(CaseEntity::getOrderId,e.getId());
CaseEntity caseEntity = caseDao.selectOne(lwq);
e.setCaseEntity(caseEntity);
}
return e; return e;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
page.setList(collect); page.setList(collect);
@ -94,8 +108,6 @@ public class OrderController {
@GetMapping("list") @GetMapping("list")
public Result<List<OrderDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) { public Result<List<OrderDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
Long itemId = NumberUtils.parseNumber(params.get("itemId").toString(), Long.class); Long itemId = NumberUtils.parseNumber(params.get("itemId").toString(), Long.class);
System.out.println(itemId);
//分页 //分页
List<OrderDTO> page = orderService.list(params); List<OrderDTO> page = orderService.list(params);
List<OrderDTO> collect = page.stream().map(e -> { List<OrderDTO> collect = page.stream().map(e -> {
@ -104,13 +116,18 @@ public class OrderController {
if (dto != null) { if (dto != null) {
e.setUser(dto); e.setUser(dto);
} }
//病例
// caseService.get()
//查看授权状态 //查看授权状态
LambdaQueryWrapper<AuditEntity> lwq = new LambdaQueryWrapper<>(); LambdaQueryWrapper<AuditEntity> lwq = new LambdaQueryWrapper<>();
lwq.eq(AuditEntity::getOrderId,e.getId()); lwq.eq(AuditEntity::getOrderId,e.getId());
lwq.eq(AuditEntity::getItemId,itemId); lwq.eq(AuditEntity::getItemId,itemId);
AuditEntity auditEntity = auditDao.selectOne(lwq); AuditEntity auditEntity = auditDao.selectOne(lwq);
if (auditEntity !=null){ if (auditEntity !=null){
e.setAudit(auditEntity); e.setAuditEntity(auditEntity);
} }
return e; return e;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@ -135,6 +152,17 @@ public class OrderController {
e.setDoctors(doctorsDTO); e.setDoctors(doctorsDTO);
} }
//如果不是预约
if (e.getOrderStatus() != 0){
LambdaQueryWrapper<CaseEntity> lwq = new LambdaQueryWrapper<>();
lwq.eq(CaseEntity::getOrderId,e.getId());
CaseEntity caseEntity = caseDao.selectOne(lwq);
e.setCaseEntity(caseEntity);
}
FrontUserEntity frontUserEntity = frontUserDao.selectById(e.getUserId()); FrontUserEntity frontUserEntity = frontUserDao.selectById(e.getUserId());
if (frontUserEntity != null) { if (frontUserEntity != null) {
e.setUserDTO(frontUserEntity); e.setUserDTO(frontUserEntity);
@ -160,7 +188,10 @@ public class OrderController {
public Result save(@RequestBody OrderDTO dto, @Parameter(hidden = true) @RequestAttribute("userId") Long userId) { public Result save(@RequestBody OrderDTO dto, @Parameter(hidden = true) @RequestAttribute("userId") Long userId) {
//效验数据 //效验数据
ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
long orderId = IdUtil.getSnowflake(1, 1).nextId();
dto.setUserId(userId); dto.setUserId(userId);
//生成订单编号
dto.setOrderId(orderId);
orderService.save(dto); orderService.save(dto);
return new Result(); return new Result();
} }

View File

@ -53,6 +53,11 @@
<el-form-item label="医生联系电话"> <el-form-item label="医生联系电话">
<el-input disabled v-model="state.buyForm.phone" /> <el-input disabled v-model="state.buyForm.phone" />
</el-form-item> </el-form-item>
<el-form-item label="年龄">
<el-input v-model="state.buyForm.age" placeholder="请输入年龄" />
</el-form-item>
<el-form-item label="预约时间" <el-form-item label="预约时间"
prop="appointmentTime" prop="appointmentTime"
:rules="[ :rules="[

View File

@ -1,111 +1,15 @@
<template> <template>
<el-row>
<el-col :span="24">
<el-card>
<template #header>
<div class="card-header">
<span>平台情况</span>
</div>
</template>
<el-row :gutter="20">
<el-col v-for="item in state.list" :span="12" :key="item.name">
<div class="list-box">
<p class="first-p">{{ item.name }}</p>
<p class="second-p">
<span>{{ item.value }}</span>{{ item.tag }}
</p>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const state = reactive(<any>{
list: [],
row: []
});
//
onMounted(() => {
adminRequest.get("/sys/item/query").then(res => {
state.list = res.data;
});
});
const chartData = ref({
columns: ['date', 'sales'],
rows: [
{ date: '2021-01-01', sales: 100 },
{ date: '2021-02-01', sales: 200 },
{ date: '2021-03-01', sales: 150 },
{ date: '2021-04-01', sales: 220 },
{ date: '2021-05-01', sales: 180 }
]
});
//
const chartSettings = ref({
xAxis: {
type: 'category',
name: '日期'
},
yAxis: {
type: 'value',
name: '销售量'
},
title: {
text: '销售趋势'
},
tooltip: {
trigger: 'axis'
}
});
</script> </script>
<style scoped> <style scoped>
.chart {
height: 400px;
}
.list-box {
width: 100%;
height: 150px;
border-radius: 10px;
background-image: url('/a1.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.first-p {
color: white;
padding-bottom: 0.5vw;
font-size: 1.5vw;
text-align: center;
padding-top: 30px;
}
.second-p {
color: white;
display: flex;
margin-bottom: 5px;
font-size: 1.4vw;
align-items: center;
justify-content: center;
span {
margin-right: 0.3vw;
font-size: 2vw;
}
}
</style> </style>
<route lang="json"> <route lang="json">
{ {

View File

@ -1,15 +1,18 @@
<template> <template>
<div class="blockchain-case-system"> <div class="blockchain-case-system">
<el-tabs v-model="state.activeName" class="demo-tabs">
<el-tab-pane label="患者病例" name="first">
<!-- 病例列表 --> <!-- 病例列表 -->
<el-table :data="state.caseList" v-loading="state.loading" style="width: 100%"> <el-table :data="state.caseList" v-loading="state.loading" style="width: 100%">
<el-table-column prop="id" label="病例ID" align="center"/> <el-table-column prop="id" label="病例ID" align="center"/>
<el-table-column prop="user.nickName" label="患者姓名" align="center"/> <el-table-column prop="user.nickName" label="患者姓名" align="center"/>
<el-table-column prop="createdTime" label="预约时间" align="center"/> <el-table-column prop="createdTime" label="预约时间" align="center"/>
<el-table-column prop="amount" label="预约金额" align="center"/> <el-table-column prop="amount" label="预约金额" align="center"/>
<el-table-column prop="amount" label="预约金额" align="center"/>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template #default="{row}"> <template #default="{row}">
<el-button <el-button
v-if="row.audit === null"
type="primary" type="primary"
size="small" size="small"
@click="requestAccess(row)" @click="requestAccess(row)"
@ -27,19 +30,70 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-tab-pane>
<el-tab-pane label="申请记录" name="second">
<el-table :data="state.log" style="width: 100%">
<el-table-column prop="orderId" label="病例ID" align="center"/>
<el-table-column prop="createTime" label="申请时间" align="center"/>
<el-table-column prop="purpose" label="申请目的" align="center"/>
<el-table-column prop="status" label="状态" align="center"/>
<el-table-column label="操作" align="center">
<template #default="{row}">
<el-button
v-if="row.status === '同意授权'"
type="success"
size="small"
@click="viewCase(row)"
>
查看病例
</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<!-- 查看病例对话框 --> <!-- 查看病例对话框 -->
<el-dialog <el-dialog
v-model="state.dialogVisible" v-model="state.dialogVisible"
:title="`病例详情 - ${state.selectedCase}`" :title="`病例详情 `"
width="70%" width="70%"
> >
<div class="case-content"> <div class="case-detail-container">
<h3>诊断结果: {{ state.selectedCase?.diagnosis }}</h3> <!-- 病例基本信息 -->
<div class="case-details"> <div class="section">
<!-- 这里显示实际的病例内容 --> <h3 class="section-title">病例内容</h3>
<p>这是一份加密存储的区块链病例只有获得授权的医生可以查看完整内容</p> <div class="section-content" v-html="state.case.content"></div>
<p>病例ID: {{ state.selectedCase?.id }}</p> </div>
<p>区块链哈希: 0x8923a7b8c5d6e4f2a1b9c8d7e6f5a4b3c2d1e0f</p> <!-- 诊断结果 -->
<div class="section" v-if="state.case.diagnosis">
<h3 class="section-title">诊断结果</h3>
<div class="section-content">{{ state.case.diagnosis }}</div>
</div>
<!-- 开具药品 -->
<div class="section" v-if="state.case.medicines && medicinesList.length">
<h3 class="section-title">开具药品</h3>
<el-table :data="medicinesList" border size="small" class="medicine-table">
<el-table-column prop="medicineName" label="药品名称" width="180"></el-table-column>
<el-table-column prop="usage" label="用量"></el-table-column>
<el-table-column prop="unitPrice" label="单价" align="right">
<template #default="{row}">
¥{{ row.unitPrice.toFixed(2) }}
</template>
</el-table-column>
<el-table-column prop="quantity" label="数量" align="center"></el-table-column>
<el-table-column label="小计" align="right">
<template #default="{row}">
¥{{ (row.unitPrice * row.quantity).toFixed(2) }}
</template>
</el-table-column>
</el-table>
</div>
<!-- 药品医嘱 -->
<div class="section" v-if="state.case.medicalAdvice">
<h3 class="section-title">医嘱说明</h3>
<div class="section-content">{{ state.case.medicalAdvice }}</div>
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
@ -76,7 +130,6 @@
<el-button type="primary" @click="submitRequest" :loading="state.loading">提交申请</el-button> <el-button type="primary" @click="submitRequest" :loading="state.loading">提交申请</el-button>
</template> </template>
</el-dialog> </el-dialog>
<!-- 患者授权对话框 --> <!-- 患者授权对话框 -->
<el-dialog v-model="state.authDialogVisible" title="授权查看病例" width="50%"> <el-dialog v-model="state.authDialogVisible" title="授权查看病例" width="50%">
<el-form :model="state.authForm" label-width="100px"> <el-form :model="state.authForm" label-width="100px">
@ -114,7 +167,9 @@ const formRef = ref<FormInstance>()
const user = userStore().doctorUserInfo const user = userStore().doctorUserInfo
// //
const state = reactive(<any>{ const state = reactive(<any>{
activeName: "first",
loading: false, loading: false,
case: {}, //
caseList: [] as any[], // caseList: [] as any[], //
selectedCase: null as any, // selectedCase: null as any, //
dialogVisible: false, // dialogVisible: false, //
@ -128,9 +183,10 @@ const state = reactive(<any>{
authForm: { authForm: {
privateKey: '', privateKey: '',
orderId: '' orderId: ''
} },
log: []
}) })
//
const getCaseList = async () => { const getCaseList = async () => {
state.loading = true state.loading = true
try { try {
@ -142,7 +198,15 @@ const getCaseList = async () => {
state.loading = false state.loading = false
} }
} }
// 使 Composition API
const medicinesList = computed(() => {
if (!state.case.medicines) return [];
try {
return JSON.parse(state.case.medicines);
} catch (e) {
return [];
}
});
// //
const requestAccess = (caseItem: any) => { const requestAccess = (caseItem: any) => {
state.selectedCase = caseItem.user state.selectedCase = caseItem.user
@ -167,12 +231,10 @@ const submitRequest = async () => {
// //
const viewCase = (caseItem: any) => { const viewCase = (caseItem: any) => {
if (caseItem.encrypted && !caseItem.accessGranted) { frontRequest.post(`/api/case/getCase`, {orderId: caseItem.orderId, itemId: user.id}).then(res => {
requestAccess(caseItem) state.case = res.data
return
}
state.selectedCase = caseItem
state.dialogVisible = true state.dialogVisible = true
})
} }
// //
@ -199,12 +261,48 @@ const submitAuth = async () => {
} }
} }
function init() {
frontRequest.get(`/api/audit/page?limit=9999&itemId=${user.id}`).then(res => {
state.log = res.data.list
})
}
// //
onMounted(() => { onMounted(() => {
getCaseList() getCaseList()
init()
}) })
</script> </script>
<style scoped> <style scoped>
.case-detail-container {
padding: 0 10px;
}
.section {
margin-bottom: 20px;
}
.section-title {
color: #409EFF;
font-size: 16px;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #eee;
}
.section-content {
padding: 0 10px;
line-height: 1.6;
}
.medicine-table {
margin-top: 10px;
width: 100%;
}
.blockchain-case-system { .blockchain-case-system {
padding: 20px; padding: 20px;
} }

View File

@ -71,7 +71,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="姓名" prop="nickName"> <el-form-item label="姓名" prop="nickName">
<el-input disabled v-model="state.formData.nickName"/> <el-input v-model="state.formData.nickName"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
@ -213,15 +213,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance, TabsPaneContext } from 'element-plus' import type { FormInstance, TabsPaneContext } from 'element-plus'
interface Medicine {
id: number
medicineName: string
specification: string
unitPrice: number
stockQuantity: number
quantity: number
usage: string
}
interface FormData { interface FormData {
id?: string id?: string
nickName?: string nickName?: string
@ -229,7 +221,7 @@ interface FormData {
content?: string content?: string
diagnosis?: string diagnosis?: string
medicalAdvice?: string medicalAdvice?: string
medicines?: Medicine[] medicines?: any[]
medicineId?: number | null medicineId?: number | null
orderStatus?: number orderStatus?: number
} }
@ -247,7 +239,7 @@ const state = reactive({
dialogVisible: false, dialogVisible: false,
dialogVisibleView: false, dialogVisibleView: false,
getList: [] as any[], // getList: [] as any[], //
medicineOptions: [] as Medicine[], medicineOptions: [] as any[],
medicineLoading: false, medicineLoading: false,
totalMedicinePrice: 0, totalMedicinePrice: 0,
query: { query: {
@ -311,7 +303,6 @@ const edit = async (row: any) => {
medicines: res.data.medicines || [], medicines: res.data.medicines || [],
medicineId: null medicineId: null
} }
// //
calculateTotal() calculateTotal()
state.dialogVisible = true state.dialogVisible = true
@ -330,7 +321,6 @@ const handleMedicineSelect = (id: number) => {
// //
const addMedicine = async () => { const addMedicine = async () => {
if (!state.formData.medicineId) return if (!state.formData.medicineId) return
try { try {
// //
const res = await frontRequest.get(`/api/management/${state.formData.medicineId}`) const res = await frontRequest.get(`/api/management/${state.formData.medicineId}`)
@ -354,6 +344,10 @@ const addMedicine = async () => {
quantity: 1, quantity: 1,
usage: '一日三次,每次一片' // usage: '一日三次,每次一片' //
}) })
console.log(state.formData.medicines)
state.formData.medicineId = null state.formData.medicineId = null
state.medicineOptions = [] state.medicineOptions = []
calculateTotal() calculateTotal()
@ -414,32 +408,16 @@ const saveTransaction = async (formEl: FormInstance | undefined) => {
try { try {
const isValid = await formEl.validate() const isValid = await formEl.validate()
if (!isValid) return if (!isValid) return
// //
const submitData = { const submitData = {
price:state.totalMedicinePrice, price:state.totalMedicinePrice,
...state.formData, ...state.formData,
// //
medicines: JSON.stringify( medicines: JSON.stringify(state.formData.medicines)
state.formData.medicines?.map(med => ({
id: med.id,
quantity: med.quantity,
usage: med.usage
})) || []
)
} }
if (state.formData.id) { if (state.formData.id) {
console.log(submitData)
submitData.orderId = submitData.id submitData.orderId = submitData.id
delete submitData.id delete submitData.id
await frontRequest.post(`/api/case`, submitData)
//
// await frontRequest.put(`${state.route}`, submitData)
ElMessage.success("提交成功")
} else {
//
await frontRequest.post(`/api/case`, submitData) await frontRequest.post(`/api/case`, submitData)
ElMessage.success("提交成功") ElMessage.success("提交成功")
} }

View File

@ -52,7 +52,7 @@ const init = () => {
// Navigate to movie details page // Navigate to movie details page
const to = (id: number) => { const to = (id: number) => {
router.push(`/info/${id}`) router.push(`/list/${id}`)
} }
// Fetch data on component mount // Fetch data on component mount

View File

@ -47,7 +47,7 @@ onMounted(() => {
* 跳转 * 跳转
*/ */
const to = () => { const to = () => {
router.push(`/info/${itemId}`) router.push(`/list/${itemId}`)
} }
</script> </script>
<style scoped> <style scoped>

View File

@ -35,7 +35,7 @@
<el-button v-if="scope.row.orderStatus === 4 ||scope.row.orderStatus === 0" @click="clean(scope.row,2)" type="warning" size="small">取消</el-button> <el-button v-if="scope.row.orderStatus === 4 ||scope.row.orderStatus === 0" @click="clean(scope.row,2)" type="warning" size="small">取消</el-button>
<el-button v-if="scope.row.orderStatus === 4 ||scope.row.orderStatus === 0" @click="to(scope.row.doctors.id)" type="success" size="small">立即沟通</el-button> <el-button v-if="scope.row.orderStatus === 4 ||scope.row.orderStatus === 0" @click="to(scope.row.doctors.id)" type="success" size="small">立即沟通</el-button>
<el-button v-if="scope.row.orderStatus === 2" @click="del(scope.row.id)" type="danger" size="small">删除</el-button> <el-button v-if="scope.row.orderStatus === 2" @click="del(scope.row.id)" type="danger" size="small">删除</el-button>
<el-button v-if="scope.row.orderStatus === 1 ||scope.row.orderStatus === 3 " @click="view(scope.row.content)" type="success" size="small">病例</el-button> <el-button v-if="scope.row.orderStatus === 1 ||scope.row.orderStatus === 3 " @click="view(scope.row.caseEntity)" type="success" size="small">病例</el-button>
<el-button v-if="scope.row.orderStatus === 1" @click="clean(scope.row,3)" type="success" size="small">评价医生</el-button> <el-button v-if="scope.row.orderStatus === 1" @click="clean(scope.row,3)" type="success" size="small">评价医生</el-button>
<el-button v-if="scope.row.orderStatus === 2" @click="clean(scope.row,0)" type="danger" size="small">恢复</el-button> <el-button v-if="scope.row.orderStatus === 2" @click="clean(scope.row,0)" type="danger" size="small">恢复</el-button>
</template> </template>
@ -46,11 +46,53 @@
</el-table> </el-table>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-dialog v-model="state.dialogVisibleView" title="查看病例" width="50%"> <el-dialog
<div v-html="state.content"></div> v-model="state.dialogVisibleView"
<div slot="footer" class="dialog-footer"> title="病例详情"
<el-button @click="state.dialogVisibleView = false">确定</el-button> width="60%"
:close-on-click-modal="false"
>
<div class="case-detail-container">
<!-- 病例基本信息 -->
<div class="section">
<h3 class="section-title">病例内容</h3>
<div class="section-content" v-html="state.case.content"></div>
</div> </div>
<!-- 诊断结果 -->
<div class="section" v-if="state.case.diagnosis">
<h3 class="section-title">诊断结果</h3>
<div class="section-content">{{ state.case.diagnosis }}</div>
</div>
<!-- 开具药品 -->
<div class="section" v-if="state.case.medicines && medicinesList.length">
<h3 class="section-title">开具药品</h3>
<el-table :data="medicinesList" border size="small" class="medicine-table">
<el-table-column prop="medicineName" label="药品名称" width="180"></el-table-column>
<el-table-column prop="usage" label="用量"></el-table-column>
<el-table-column prop="unitPrice" label="单价" align="right">
<template #default="{row}">
¥{{ row.unitPrice.toFixed(2) }}
</template>
</el-table-column>
<el-table-column prop="quantity" label="数量" align="center"></el-table-column>
<el-table-column label="小计" align="right">
<template #default="{row}">
¥{{ (row.unitPrice * row.quantity).toFixed(2) }}
</template>
</el-table-column>
</el-table>
</div>
<!-- 药品医嘱 -->
<div class="section" v-if="state.case.medicalAdvice">
<h3 class="section-title">医嘱说明</h3>
<div class="section-content">{{ state.case.medicalAdvice }}</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="state.dialogVisibleView = false">确定</el-button>
</div>
</template>
</el-dialog> </el-dialog>
<el-dialog v-model="state.dialogVisibleScore" title="评价医生" width="30%"> <el-dialog v-model="state.dialogVisibleScore" title="评价医生" width="30%">
<el-form :model="state.scoreFrom" label-width="auto" style="max-width: 600px"> <el-form :model="state.scoreFrom" label-width="auto" style="max-width: 600px">
@ -79,7 +121,7 @@ const router = useRouter()
const state = reactive({ const state = reactive({
dialogVisibleView:false, dialogVisibleView:false,
dialogVisibleScore:false, dialogVisibleScore:false,
content:"", case: {},
getOrderStatus: [ getOrderStatus: [
{ name: '已预约', status: 0 }, { name: '已预约', status: 0 },
{ name: '已完成', status: 1 }, { name: '已完成', status: 1 },
@ -95,6 +137,16 @@ const state = reactive({
scoreFrom:{} scoreFrom:{}
}) })
// 使 Composition API
const medicinesList = computed(() => {
if (!state.case.medicines) return [];
try {
return JSON.parse(state.case.medicines);
} catch (e) {
return [];
}
});
// //
function pay(data:any) { function pay(data:any) {
frontRequest.delete(`/api/order/${data.id}`).then(() => {}) frontRequest.delete(`/api/order/${data.id}`).then(() => {})
@ -139,7 +191,7 @@ const clean = (data:any,status:number) => {
} }
function view(path: string) { function view(path: string) {
state.dialogVisibleView = true state.dialogVisibleView = true
state.content = path state.case = path
} }
const handleClick = (tab: TabsPaneContext, event: Event) => { const handleClick = (tab: TabsPaneContext, event: Event) => {
// tab name // tab name
@ -165,7 +217,31 @@ onMounted(() => {
<style scoped> <style scoped>
.case-detail-container {
padding: 0 10px;
}
.section {
margin-bottom: 20px;
}
.section-title {
color: #409EFF;
font-size: 16px;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #eee;
}
.section-content {
padding: 0 10px;
line-height: 1.6;
}
.medicine-table {
margin-top: 10px;
width: 100%;
}
</style> </style>
<route lang="json"> <route lang="json">
{ {