优化认证

This commit is contained in:
18796357645 2025-05-18 21:13:10 +08:00
parent 575cdb2fe1
commit f2aba12e3f
10 changed files with 240 additions and 135 deletions

View File

@ -52,7 +52,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
httpResponse.setContentType("application/json;charset=utf-8"); httpResponse.setContentType("application/json;charset=utf-8");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
String json = JsonUtils.toJsonString(new Result().error("未授权访问!")); String json = JsonUtils.toJsonString(new Result().error("待审核访问!"));
httpResponse.getWriter().print(json); httpResponse.getWriter().print(json);
return false; return false;
} }

View File

@ -1,6 +1,7 @@
package io.modules.item.dto; 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.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;
@ -65,4 +66,5 @@ public class OrderDTO implements Serializable {
private String remark; private String remark;
private DoctorsDTO doctors; private DoctorsDTO doctors;
private FrontUserEntity userDTO; private FrontUserEntity userDTO;
private AuditEntity audit;
} }

View File

@ -111,7 +111,7 @@ CREATE TABLE `tb_audit` (
`id` bigint(20) NOT NULL AUTO_INCREMENT, `id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` bigint(20) NULL DEFAULT NULL COMMENT '订单编号', `order_id` bigint(20) NULL DEFAULT NULL COMMENT '订单编号',
`item_id` bigint(20) NULL DEFAULT NULL COMMENT '申请医生', `item_id` bigint(20) NULL DEFAULT NULL COMMENT '申请医生',
`status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '未授权' COMMENT '申请状态', `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '待审核' COMMENT '申请状态',
`purpose` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '申请目的', `purpose` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '申请目的',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户编号', `user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户编号',
@ -123,8 +123,8 @@ CREATE TABLE `tb_audit` (
-- Records of tb_audit -- Records of tb_audit
-- ---------------------------- -- ----------------------------
INSERT INTO `tb_audit` VALUES (1922275723347402754, 1909838189195964418, 1, '同意授权', '12121', '2025-05-13 13:00:21', 1893836584118173697, '0x00000'); INSERT INTO `tb_audit` VALUES (1922275723347402754, 1909838189195964418, 1, '同意授权', '12121', '2025-05-13 13:00:21', 1893836584118173697, '0x00000');
INSERT INTO `tb_audit` VALUES (1922288200642674690, 1909838189195964418, 1, '未授权', '病情需要', '2025-05-13 13:49:56', 1893836584118173697, NULL); INSERT INTO `tb_audit` VALUES (1922288200642674690, 1909838189195964418, 1, '待审核', '病情需要', '2025-05-13 13:49:56', 1893836584118173697, NULL);
INSERT INTO `tb_audit` VALUES (1922288229205884929, 1922287840624590849, 1, '未授权', '病情需要', '2025-05-13 13:50:02', 1893836584118173697, NULL); INSERT INTO `tb_audit` VALUES (1922288229205884929, 1922287840624590849, 1, '待审核', '病情需要', '2025-05-13 13:50:02', 1893836584118173697, NULL);
-- ---------------------------- -- ----------------------------
-- Table structure for tb_case -- Table structure for tb_case

View File

@ -123,7 +123,7 @@ public class AuditController {
LambdaQueryWrapper<AuditEntity> lwq = new LambdaQueryWrapper<>(); LambdaQueryWrapper<AuditEntity> lwq = new LambdaQueryWrapper<>();
lwq.eq(AuditEntity::getItemId, dto.getItemId()); lwq.eq(AuditEntity::getItemId, dto.getItemId());
lwq.eq(AuditEntity::getOrderId, dto.getOrderId()); lwq.eq(AuditEntity::getOrderId, dto.getOrderId());
lwq.eq(AuditEntity::getStatus, "未授权"); lwq.eq(AuditEntity::getStatus, "待审核");
if (auditDao.exists(lwq)) { if (auditDao.exists(lwq)) {
return new Result().error("您已经申请,不能重复申请"); return new Result().error("您已经申请,不能重复申请");
} }

View File

@ -11,12 +11,14 @@ 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.DoctorsDao; import io.modules.item.dao.DoctorsDao;
import io.modules.item.dao.FrontUserDao; import io.modules.item.dao.FrontUserDao;
import io.modules.item.dao.OrderDao; 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.DoctorsEntity; import io.modules.item.entity.DoctorsEntity;
import io.modules.item.entity.FrontUserEntity; import io.modules.item.entity.FrontUserEntity;
import io.modules.item.entity.OrderEntity; import io.modules.item.entity.OrderEntity;
@ -28,6 +30,7 @@ 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.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.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.Parameters;
@ -49,8 +52,7 @@ public class OrderController {
private OrderService orderService; private OrderService orderService;
@Autowired @Autowired
private OrderDao orderDao; private AuditDao auditDao;
@Autowired @Autowired
private DoctorsService doctorsService; private DoctorsService doctorsService;
@ -89,13 +91,13 @@ public class OrderController {
return new Result<PageData<OrderDTO>>().ok(page); return new Result<PageData<OrderDTO>>().ok(page);
} }
@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);
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 -> {
Long userId = e.getUserId(); Long userId = e.getUserId();
UserDTO dto = userService.get(userId); UserDTO dto = userService.get(userId);
@ -103,9 +105,13 @@ public class OrderController {
e.setUser(dto); e.setUser(dto);
} }
//查看授权状态 //查看授权状态
LambdaQueryWrapper<AuditEntity> lwq = new LambdaQueryWrapper<>();
lwq.eq(AuditEntity::getOrderId,e.getId());
lwq.eq(AuditEntity::getItemId,itemId);
AuditEntity auditEntity = auditDao.selectOne(lwq);
if (auditEntity !=null){
e.setAudit(auditEntity);
}
return e; return e;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
return new Result<List<OrderDTO>>().ok(collect); return new Result<List<OrderDTO>>().ok(collect);

View File

@ -1,74 +1,203 @@
<template> <template>
<el-card>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-table :data="state.getList" style="width: 100%"> <el-table
:data="state.listData"
<el-table-column prop="doctors.userName" label="主治医生" align="center" /> style="width: 100%"
<el-table-column prop="oneDoctors.userName" label="申请医生" align="center" /> v-loading="state.loading"
<el-table-column prop="createTime" label="申请时间" align="center" /> border
<el-table-column prop="purpose" label="申请目的" align="center" /> stripe
<el-table-column prop="hex" label="密钥" align="center" />
<el-table-column prop="status" label="申请状态" align="center" />
<el-table-column fixed="right" label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
size="small"
@click.prevent="update(scope.row,'同意授权')"
> >
同意授权 <el-table-column
</el-button> prop="doctors.userName"
<el-button label="主治医生"
link align="center"
type="primary" width="120"
size="small" />
@click.prevent="update(scope.row,'拒绝授权')" <el-table-column
prop="oneDoctors.userName"
label="申请医生"
align="center"
width="120"
/>
<el-table-column
prop="createTime"
label="申请时间"
align="center"
width="180"
/>
<el-table-column
prop="purpose"
label="申请目的"
align="center"
width="200"
show-overflow-tooltip
/>
<el-table-column
prop="hex"
label="密钥"
align="center"
width="180"
/>
<el-table-column
prop="status"
label="申请状态"
align="center"
width="120"
> >
拒绝授权 <template #default="{ row }">
</el-button> <el-tag
:type="getStatusTagType(row.status)"
effect="plain"
>
{{ row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column
fixed="right"
label="操作"
align="center"
width="200"
>
<template #default="scope">
<el-button
type="success"
size="small"
@click="handleAction(scope.row, 'agree')"
:disabled="scope.row.status !== '待审核'"
>
同意
</el-button>
<el-button
type="danger"
size="small"
@click="handleAction(scope.row, 'reject')"
:disabled="scope.row.status !== '待审核'"
>
拒绝
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination
v-model:current-page="state.pagination.current"
v-model:page-size="state.pagination.size"
:total="state.pagination.total"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="fetchData"
@current-change="fetchData"
style="margin-top: 20px; justify-content: flex-end"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-card>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
const state = reactive({ const state = reactive({
getList:[] listData: [],
loading: false,
pagination: {
current: 1,
size: 10,
total: 0
}
}) })
function init() {
frontRequest.get("/api/audit/list",{params:{limit:999}}).then(res =>{ //
state.getList = res.data const getStatusTagType = (status) => {
const statusMap = {
'同意授权': 'success',
'拒绝授权': 'danger',
'待审核': 'warning'
}
return statusMap[status] || 'info'
}
//
const fetchData = async () => {
try {
state.loading = true
const res = await frontRequest.get("/api/audit/list", {
params: {
page: state.pagination.current,
pageSize: state.pagination.size
}
})
state.listData = res.data.list || res.data
state.pagination.total = res.data.total || res.data.length
} catch (error) {
ElMessage.error('获取数据失败')
console.error(error)
} finally {
state.loading = false
}
}
//
const handleAction = (row, action) => {
const actionMap = {
agree: '同意授权',
reject: '拒绝授权'
}
ElMessageBox.confirm(
`确定要${action === 'agree' ? '同意' : '拒绝'}该申请吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(async () => {
try {
const newStatus = actionMap[action]
await frontRequest.put("/api/audit", {
...row,
status: newStatus
})
ElMessage.success('操作成功')
fetchData()
} catch (error) {
ElMessage.error('操作失败')
console.error(error)
}
}).catch(() => {
ElMessage.info('已取消操作')
}) })
} }
onMounted(() => { onMounted(() => {
init() fetchData()
}) })
</script>
function update(data:any,status:string) { <style scoped>
console.log(data) .el-card {
data.status = status margin: 20px;
frontRequest.put("/api/audit",data).then(res =>{
state.getList = res.data
init()
})
} }
</script> .el-table {
<style scoped> margin-top: 20px;
}
.el-button + .el-button {
margin-left: 8px;
}
</style> </style>
<route lang="json"> <route lang="json">
{ {
"meta": { "meta": {
"layout": "front" "layout": "front",
"title": "申请审核管理"
} }
} }
</route> </route>

View File

@ -1,14 +1,5 @@
<template> <template>
<div class="blockchain-case-system"> <div class="blockchain-case-system">
<el-card class="box-card">
<template #header>
<div class="card-header">
<span>区块链病例管理系统</span>
</div>
</template>
<!-- 病例列表 --> <!-- 病例列表 -->
<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"/>
@ -18,7 +9,7 @@
<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.accessGranted" v-if="row.audit === null"
type="primary" type="primary"
size="small" size="small"
@click="requestAccess(row)" @click="requestAccess(row)"
@ -26,7 +17,7 @@
申请查看 申请查看
</el-button> </el-button>
<el-button <el-button
v-else v-if="row.audit?.status === '同意授权'"
type="success" type="success"
size="small" size="small"
@click="viewCase(row)" @click="viewCase(row)"
@ -36,12 +27,10 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-card>
<!-- 查看病例对话框 --> <!-- 查看病例对话框 -->
<el-dialog <el-dialog
v-model="state.dialogVisible" v-model="state.dialogVisible"
:title="`病例详情 - ${state.selectedCase?.patientName}`" :title="`病例详情 - ${state.selectedCase}`"
width="70%" width="70%"
> >
<div class="case-content"> <div class="case-content">
@ -54,7 +43,6 @@
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
<!-- 申请查看对话框 --> <!-- 申请查看对话框 -->
<el-dialog v-model="state.requestDialogVisible" title="申请查看病例" width="50%"> <el-dialog v-model="state.requestDialogVisible" title="申请查看病例" width="50%">
<el-form :model="state.requestForm" ref="formRef" label-width="100px"> <el-form :model="state.requestForm" ref="formRef" label-width="100px">
@ -125,7 +113,7 @@ import type { FormInstance } from 'element-plus'
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const user = userStore().doctorUserInfo const user = userStore().doctorUserInfo
// //
const state = reactive({ const state = reactive(<any>{
loading: false, loading: false,
caseList: [] as any[], // caseList: [] as any[], //
selectedCase: null as any, // selectedCase: null as any, //
@ -142,13 +130,11 @@ const state = reactive({
orderId: '' orderId: ''
} }
}) })
// //
const getCaseList = async () => { const getCaseList = async () => {
state.loading = true state.loading = true
try { try {
// API const res = await frontRequest.get('/api/order/list', {params: {limit: 999,itemId: user.id}})
const res = await frontRequest.get('/api/order/list',{params:{limit:999}})
state.caseList = res.data state.caseList = res.data
} catch (error) { } catch (error) {
ElMessage.error('获取病例列表失败') ElMessage.error('获取病例列表失败')
@ -185,7 +171,6 @@ const viewCase = (caseItem: any) => {
requestAccess(caseItem) requestAccess(caseItem)
return return
} }
state.selectedCase = caseItem state.selectedCase = caseItem
state.dialogVisible = true state.dialogVisible = true
} }

View File

@ -18,18 +18,17 @@
<el-tab-pane v-for="item in state.getOrderStatus" :label="item.name" :name="item.status"> <el-tab-pane v-for="item in state.getOrderStatus" :label="item.name" :name="item.status">
<el-table v-loading="loading" :data="state.getList"> <el-table v-loading="loading" :data="state.getList">
<!-- 列表结开始--> <!-- 列表结开始-->
<el-table-column prop="id" label="预约编号"/>
<el-table-column prop="userDTO.nickName" label="姓名"/> <el-table-column prop="userDTO.nickName" label="姓名" align="center"/>
<el-table-column prop="age" label="年龄"/> <el-table-column prop="age" label="年龄" align="center"/>
<el-table-column prop="sex" label="性别"> <el-table-column prop="sex" label="性别" align="center" >
<template #default="{ row }"> <template #default="{ row }">
{{ row.sex === 1? '男' : '女' }} {{ row.sex === 1? '男' : '女' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="appointmentTime" label="预约时间"/> <el-table-column prop="appointmentTime" label="预约时间" align="center"/>
<el-table-column prop="remark" label="备注"/> <el-table-column prop="remark" label="备注" align="center"/>
<el-table-column prop="tCase" label="病例内容"/>
<!--列表结束--> <!--列表结束-->
<el-table-column label="操作" align="center" > <el-table-column label="操作" align="center" >
<template #default="scope"> <template #default="scope">
@ -237,7 +236,6 @@ interface FormData {
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const loading = ref(true) const loading = ref(true)
const user = userStore().doctorUserInfo const user = userStore().doctorUserInfo
const state = reactive({ const state = reactive({
route: "api/order", route: "api/order",
content: "", content: "",

View File

@ -55,13 +55,13 @@ import { useRouter } from 'vue-router'
import { loginAdmin } from '~/api/user/adminUserApi' import { loginAdmin } from '~/api/user/adminUserApi'
import { getUuid } from '~/utils/utils' import { getUuid } from '~/utils/utils'
const router = useRouter() const router = useRouter()
const state = reactive({ const state = reactive(<any>{
captchaUrl: '', captchaUrl: '',
loginFrom: {}, loginFrom: {},
loading: false, loading: false,
login:{ login:{
username: 'admin', username: '',
password: 'admin', password: '',
hexId: 0, hexId: 0,
} }
}) })

View File

@ -3,7 +3,6 @@
<div class="module_mian"> <div class="module_mian">
<div class="module_title">患者注册帐户</div> <div class="module_title">患者注册帐户</div>
<div class="module_desc">输入手机号 & 密码</div> <div class="module_desc">输入手机号 & 密码</div>
<div class="module_m"> <div class="module_m">
<div class="module_text">头像</div> <div class="module_text">头像</div>
<image-upload @update:imageUrl="handleImageUrl" :image-url="register.profile"></image-upload> <image-upload @update:imageUrl="handleImageUrl" :image-url="register.profile"></image-upload>
@ -12,13 +11,10 @@
<div class="module_text">用户姓名</div> <div class="module_text">用户姓名</div>
<el-input type="text" placeholder="输入姓名" v-model="register.nickName" /> <el-input type="text" placeholder="输入姓名" v-model="register.nickName" />
</div> </div>
<div class="module_m"> <div class="module_m">
<div class="module_text">手机</div> <div class="module_text">账号</div>
<el-input type="text" placeholder="输入手机号" v-model.number="register.username" /> <el-input type="text" placeholder="输入号" v-model.number="register.username" />
</div> </div>
<div class="module_m"> <div class="module_m">
<div class="module_text">密码</div> <div class="module_text">密码</div>
<el-select v-model="register.role" placeholder="请选择性别"> <el-select v-model="register.role" placeholder="请选择性别">
@ -38,14 +34,6 @@
<el-input type="password" placeholder="再次输入密码" v-model="register.confirmPassword" /> <el-input type="password" placeholder="再次输入密码" v-model="register.confirmPassword" />
</div> </div>
</div> </div>
<!-- <div class="module_m">-->
<!-- <div class="module_text">验证码</div>-->
<!-- <div class="module_code">-->
<!-- <input class="module_code_input" type="text" placeholder="输入验证码" v-model="vftcode" />-->
<!-- <img class="module_code_img" src="/codeimg.png" @click="onCode">-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="module_radio"><input type="radio"/>记住密码 </div>-->
<div class="forgetpwd" @click="router.push('/login')">有账号</div> <div class="forgetpwd" @click="router.push('/login')">有账号</div>
<button class="module_button" @click="onRegister">注册</button> <button class="module_button" @click="onRegister">注册</button>
</div> </div>
@ -59,16 +47,13 @@ const register = reactive({
username: '', username: '',
password: '', password: '',
confirmPassword: '', confirmPassword: '',
captcha: '', role: null,
nickName: '', nickName: '',
profile: '' profile: ''
}) })
function handleImageUrl(path: string) { function handleImageUrl(path: string) {
register.profile = path register.profile = path
console.log(register.profile)
} }
/** /**
* 注册成功 * 注册成功