医生管理新建,列表

This commit is contained in:
zhaoyz 2024-04-10 19:07:22 +08:00
parent 03c27fd31b
commit 628244785b
14 changed files with 420 additions and 372 deletions

View File

@ -1,77 +0,0 @@
/*
//统一管理咱们项目用户相关的接口
import request from '@/utils/request'
import type {
loginFormData,
loginResponseData,
userInfoReponseData,
} from './type'
//项目用户相关的请求地址
enum API {
LOGIN_URL = '/admin/acl/index/login',
USERINFO_URL = '/admin/acl/index/info',
LOGOUT_URL = '/admin/acl/index/logout',
}
//登录接口
export const reqLogin = (data: loginFormData) =>
request.post<any, loginResponseData>(API.LOGIN_URL, data)
//获取用户信息
export const reqUserInfo = () =>
request.get<any, userInfoReponseData>(API.USERINFO_URL)
//退出登录
export const reqLogout = () => request.post<any, any>(API.LOGOUT_URL)
*/
import request, {getData} from "@/utils/request";
const userInfoUrl = '/admin/user/info'
const editUserUrl = '/admin/user/edit'
const editPasswordUrl = '/admin/user/password'
const userPageUrl = '/admin/user/page'
export function getUserInfo() {
return new Promise(resolve => {
getData(userInfoUrl).then((data: any) => {
resolve(data.data)
})
})
}
export function updateUserInfo(data: any) {
return new Promise(resolve => {
request.request({
url: editUserUrl,
method: 'put',
data
}).then((res: any) => {
resolve(res.data)
})
})
}
export function editPassword(data: any) {
return new Promise(resolve => {
request.request({
url: editPasswordUrl,
method: "PUT",
data
}).then((res: any) => {
resolve(res.data)
}).catch(err => {
resolve(err)
})
})
}
export function userPage(data: any) {
return new Promise(resolve => {
getData(userPageUrl, data).then((res: any) => {
resolve(res.data)
}).catch(err => {
console.log(err)
})
})
}

View File

@ -1,31 +0,0 @@
/*
//定义用户相关数据的ts类型
//用户登录接口携带参数的ts类型
export interface loginFormData {
username: string
password: string
}
//定义全部接口返回数据都拥有ts类型
export interface ResponseData {
code: number
message: string
ok: boolean
}
//定义登录接口返回数据类型
export interface loginResponseData extends ResponseData {
data: string
}
//定义获取用户信息返回数据类型
export interface userInfoReponseData extends ResponseData {
data: {
routes: string[]
buttons: string[]
roles: string[]
name: string
avatar: string
}
}
*/

13
src/api/role.ts Normal file
View File

@ -0,0 +1,13 @@
import {getData} from "@/utils/request";
const getRoleListUrl = '/admin/role/list'
export function getRoleList() {
return new Promise((resolve, reject) => {
getData(getRoleListUrl).then((res: any) => {
resolve(res.data)
}).catch(error => {
reject(error)
})
})
}

65
src/api/user.ts Normal file
View File

@ -0,0 +1,65 @@
import request, {CommonHeaderEnum, getData, postData} from "@/utils/request";
const userInfoUrl = '/admin/user/info'
const editUserUrl = '/admin/user/edit'
const editPasswordUrl = '/admin/user/password'
const userPageUrl = '/admin/user/page'
const addUserUrl = '/admin/user'
export function getUserInfo() {
return new Promise(resolve => {
getData(userInfoUrl).then((data: any) => {
resolve(data.data)
})
})
}
export function updateUserInfo(data: any) {
return new Promise(resolve => {
request.request({
url: editUserUrl,
method: 'put',
data
}).then((res: any) => {
resolve(res.data)
})
})
}
export function editPassword(data: any) {
return new Promise(resolve => {
request.request({
url: editPasswordUrl,
method: "PUT",
data
}).then((res: any) => {
resolve(res.data)
}).catch(err => {
resolve(err)
})
})
}
export function userPage(data: any) {
return new Promise(resolve => {
getData(userPageUrl, data).then((res: any) => {
resolve(res.data)
}).catch(err => {
console.log(err)
})
})
}
export function addUser(data: any) {
return new Promise((resolve, reject) => {
postData(addUserUrl, data).then((res: any) => {
resolve(res.data)
}).catch(error => {
reject(error)
})
})
}

View File

@ -7,10 +7,7 @@
<script lang='ts' setup> <script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue' import { onMounted, reactive, ref, toRefs, watch } from 'vue'
interface Props { const props = withDefaults(defineProps(), {
total: number
}
const props = withDefaults(defineProps<Props>(), {
total: () => 0 total: () => 0
}) })

View File

@ -55,7 +55,7 @@ import {onMounted, reactive, ref, toRefs, watch} from 'vue'
import {ElMessage} from 'element-plus' import {ElMessage} from 'element-plus'
import type {UploadProps} from 'element-plus' import type {UploadProps} from 'element-plus'
import {useLoginStore} from '@/stores/user-info-store' import {useLoginStore} from '@/stores/user-info-store'
import {editPassword, getUserInfo, updateUserInfo} from "@/api/acl/user"; import {editPassword, getUserInfo, updateUserInfo} from "@/api/user";
import {handleHttpUpload} from "@/api/file-upload"; import {handleHttpUpload} from "@/api/file-upload";
const emit = defineEmits(['close']) const emit = defineEmits(['close'])

View File

@ -7,7 +7,7 @@ import * as CryptoJS from 'crypto-js';
export function encryption(src: string, keyWord: string) { export function encryption(src: string, keyWord: string) {
const key = CryptoJS.enc.Utf8.parse(keyWord); const key = CryptoJS.enc.Utf8.parse(keyWord);
// 加密 // 加密
var encrypted = CryptoJS.AES.encrypt(src, key, { let encrypted = CryptoJS.AES.encrypt(src, key, {
iv: key, iv: key,
mode: CryptoJS.mode.CFB, mode: CryptoJS.mode.CFB,
padding: CryptoJS.pad.NoPadding, padding: CryptoJS.pad.NoPadding,
@ -23,7 +23,7 @@ export function encryption(src: string, keyWord: string) {
export function decryption(src: string, keyWord: string) { export function decryption(src: string, keyWord: string) {
const key = CryptoJS.enc.Utf8.parse(keyWord); const key = CryptoJS.enc.Utf8.parse(keyWord);
// 解密逻辑 // 解密逻辑
var decryptd = CryptoJS.AES.decrypt(src, key, { let decryptd = CryptoJS.AES.decrypt(src, key, {
iv: key, iv: key,
mode: CryptoJS.mode.CFB, mode: CryptoJS.mode.CFB,
padding: CryptoJS.pad.NoPadding, padding: CryptoJS.pad.NoPadding,

View File

@ -22,6 +22,9 @@ const axiosInstance = axios.create({
baseURL: BASE_URL baseURL: BASE_URL
}); });
/**
* @deprecated
*/
export const get = (url: any, params: any, success: any) => { export const get = (url: any, params: any, success: any) => {
axiosInstance.get(url, params) axiosInstance.get(url, params)
.then(res => { .then(res => {
@ -31,6 +34,10 @@ export const get = (url: any, params: any, success: any) => {
success(err); success(err);
}); });
}; };
/**
* @deprecated
*/
export const post = (url: any, params: any, success: any) => { export const post = (url: any, params: any, success: any) => {
axiosInstance.post(url, params) axiosInstance.post(url, params)
.then(res => { .then(res => {
@ -40,6 +47,7 @@ export const post = (url: any, params: any, success: any) => {
success(err); success(err);
}); });
}; };
export const getMapJson = (name: string) => { export const getMapJson = (name: string) => {
return axiosInstance.post(BASE_URL+'/static/json/' + name) return axiosInstance.post(BASE_URL+'/static/json/' + name)
} }

View File

@ -69,7 +69,7 @@ import {getHospitalsData} from '@/static-data/core'
import userInfoForm from '@/components/user-info.vue' import userInfoForm from '@/components/user-info.vue'
import {wsApi} from "@/api/ws"; import {wsApi} from "@/api/ws";
import {Session} from "@/utils/storage"; import {Session} from "@/utils/storage";
import {logout} from "@/api/acl/login"; import {logout} from "@/api/login";
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()

View File

@ -134,7 +134,7 @@ import {useLoginStore} from '@/stores/user-info-store'
import {getPhoneAreasData} from '@/static-data/core' import {getPhoneAreasData} from '@/static-data/core'
import {v4} from "uuid"; import {v4} from "uuid";
import SliderVerify from "@/components/SliderVerify/index.vue"; import SliderVerify from "@/components/SliderVerify/index.vue";
import * as loginApi from "@/api/acl/login"; import * as loginApi from "@/api/login";
import {Session} from "@/utils/storage"; import {Session} from "@/utils/storage";
import * as hospitalApi from "@/api/hospital"; import * as hospitalApi from "@/api/hospital";
@ -356,11 +356,11 @@ function sliderSuccess() {
randomStr: v4() randomStr: v4()
}).then((data: any) => { }).then((data: any) => {
sliderVConf.value.isShowSelf = false sliderVConf.value.isShowSelf = false
if (data.code == 1) { if (data.code == 1 || data.error) {
ElMessage.error(data.msg) ElMessage.error(data.msg ? data.msg : data.error)
loading.value = false loading.value = false
} else { } else {
// token // token
Session.set('token', data.access_token); Session.set('token', data.access_token);
Session.set('refresh_token', data.refresh_token); Session.set('refresh_token', data.refresh_token);
console.log(data) console.log(data)

View File

@ -1,70 +1,79 @@
<template> <template>
<div class="table-page"> <div class="table-page">
<div class="search-part" v-show="isSearch"> <div class="search-part" v-show="isSearch">
<div class="search-cell"> <div class="search-cell">
<span class="label">用户名</span> <span class="label">用户名</span>
<el-input v-model="queryParams.userName" placeholder="请输入用户名"></el-input> <el-input v-model="queryParams.userName" placeholder="请输入用户名"></el-input>
</div> </div>
<el-button type="primary" icon="Search" @click="queryData(queryParams)">查询</el-button> <el-button type="primary" icon="Search" @click="queryData(queryParams)">查询</el-button>
<el-button icon="Refresh" @click="queryData()">重置</el-button> <el-button icon="Refresh" @click="queryData()">重置</el-button>
</div> </div>
<div class="button-part" style="justify-content: space-between;"> <div class="button-part" style="justify-content: space-between;">
<div> <div>
<el-button type="primary" icon="FirstAidKit" @click="addData">新增</el-button> <el-button type="primary" icon="FirstAidKit" @click="addData">新增</el-button>
<el-button icon="FirstAidKit" @click="importData">导入</el-button> <el-button icon="FirstAidKit" @click="importData">导入</el-button>
<el-button icon="Delete" @click="removeData()">删除</el-button> <el-button icon="Delete" @click="removeData()">删除</el-button>
</div> </div>
<TableAbility @searchBtn="isSearch = !isSearch" @refreshBtn="queryData()" <TableAbility @searchBtn="isSearch = !isSearch" @refreshBtn="queryData()"
@downloadBtn="exportData('医生数据', tableData)"></TableAbility> @downloadBtn="exportData('医生数据', tableData)"></TableAbility>
</div> </div>
<div class="table-part"> <div class="table-part">
<el-table ref="tableRef" v-loading="loading" :data="tableData" height="100%" border show-overflow-tooltip <el-table ref="tableRef" v-loading="loading" :data="tableData" height="100%" border show-overflow-tooltip
:row-class-name="({ row }: any) => !row.enable && 'disable'" @row-click="tableRowClick"> :row-class-name="({ row }: any) => row.lockFlag == 1 && 'disable'" @row-click="tableRowClick">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55"/>
<el-table-column type="index" label="#" width="55" align="center" /> <el-table-column type="index" label="#" width="55" align="center"/>
<el-table-column property="name" label="姓名" width="120" align="center" /> <el-table-column property="name" label="姓名" width="120" align="center"/>
<el-table-column label="手机号" width="220" align="center"> <el-table-column label="手机号" width="220" align="center">
<template #default="scope">{{ scope.row.phone.slice(0, 3) + '****' + scope.row.phone.slice(7) <template #default="scope">{{
}}</template> scope.row.phone.slice(0, 3) + '****' + scope.row.phone.slice(7)
</el-table-column> }}
<el-table-column property="role" label="角色" width="220" align="center" /> </template>
<el-table-column label="启用" width="120" align="center"> </el-table-column>
<template #default="scope"> <el-table-column label="角色" width="220" align="center">
<span @click.stop><el-switch v-model="scope.row.enable" @change="enableChange(scope.row)" /></span> <template #default="scope">
</template> <span v-for="(item, index) in scope.row.roleList" :key="index">
</el-table-column> {{ item.roleName }} {{ (scope.row.roleList.length - 1) == index ? '' : '' }}
<el-table-column label="操作" align="center"> </span>
<template #default="scope"> </template>
</el-table-column>
<el-table-column label="锁定" width="120" align="center">
<template #default="scope">
<span @click.stop><el-switch v-model="scope.row.lockFlag" @change="enableChange(scope.row)"/></span>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<span @click.stop> <span @click.stop>
<el-button link icon="RefreshLeft" @click="resetPassword(scope.row)" <el-button link icon="RefreshLeft" @click="resetPassword(scope.row)"
:disabled="!scope.row.enable">密码</el-button> :disabled="!scope.row.lockFlag">密码</el-button>
<el-button link icon="EditPen" @click="editData(scope.row)" <el-button link icon="EditPen" @click="editData(scope.row)"
:disabled="!scope.row.enable">修改</el-button> :disabled="!scope.row.lockFlag">修改</el-button>
<el-button link icon="Delete" @click="removeData(scope.row)" <el-button link icon="Delete" @click="removeData(scope.row)"
:disabled="!scope.row.enable">删除</el-button> :disabled="!scope.row.lockFlag">删除</el-button>
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<div class="pagination-part"> <div class="pagination-part">
<CommonPagination :total="100" @paginationChange="paginationChange" /> <CommonPagination :total="total" @paginationChange="paginationChange"/>
</div> </div>
</div> </div>
<el-dialog v-model="isFormDialog" :title="formDialogTitle" width="750px"> <el-dialog v-model="isFormDialog" :title="formDialogTitle" width="750px">
<DoctorForm ref="doctorFormRef" :type="formDialogTitle === '添加' ? 'add' : 'edit'" @close="isFormDialog = false" @save="doctorFormSave" /> <DoctorForm ref="doctorFormRef" :type="formDialogTitle === '添加' ? 'add' : 'edit'" @close="isFormDialog = false"
</el-dialog> @save="doctorFormSave"/>
<ImportDialog ref="importDialogRef" title="用户导入" templateUrl="#" importUrl="#" /> </el-dialog>
<ImportDialog ref="importDialogRef" title="用户导入" templateUrl="#" importUrl="#"/>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue' import {onMounted, reactive, ref, toRefs, watch} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import {ElMessage, ElMessageBox} from 'element-plus'
import { tableRemoveRow, exportData } from '@/utils/table-util' import {tableRemoveRow, exportData} from '@/utils/table-util'
import CommonPagination from '@/components/common-pagination.vue' import CommonPagination from '@/components/common-pagination.vue'
import DoctorForm from './form/doctor-form.vue' import DoctorForm from './form/doctor-form.vue'
import ImportDialog from '@/components/import-dialog.vue' import ImportDialog from '@/components/import-dialog.vue'
import {userPage} from "@/api/acl/user"; import {userPage} from "@/api/user";
const tableRef = ref() const tableRef = ref()
const doctorFormRef = ref() const doctorFormRef = ref()
@ -74,98 +83,92 @@ const loading = ref(true)
const isFormDialog = ref(false) const isFormDialog = ref(false)
const formDialogTitle = ref('') const formDialogTitle = ref('')
const queryParams = ref({ const queryParams = ref({
userName: '' userName: ''
} as any) } as any)
const tableData = ref([] as any) const tableData = ref([] as any)
let current = 0; let current = 0
const size = 10; let size = 10
const total = ref(0)
queryData() queryData()
function queryData(e?: any) { function queryData(e?: any) {
loading.value = true loading.value = true
if(e?.userName) { userPage({
tableData.value = tableData.value.filter((item: any) => item.name.indexOf(e.userName) !== -1) current,
loading.value = false size,
return name: queryParams.value.userName
}else{ }).then((res: any) => {
queryParams.value = {} loading.value = false
tableData.value = [] total.value = res.data.total
setTimeout(() => { tableData.value = res.data.records
while (tableData.value.length < 10) { if (current < total.value) {
tableData.value.push({ current += size
id: tableData.value.length + 1, }
userName: 'cscs', console.log(res)
name: '测试' + tableData.value.length, }).catch(error => {
phone: '12312345678', loading.value = false
role: '高级管理员', })
enable: true,
})
}
loading.value = false
}, 200);
}
userPage({
current,
size,
name: queryParams.value.userName
})
} }
const addData = () => { const addData = () => {
isFormDialog.value = true isFormDialog.value = true
formDialogTitle.value = '添加' formDialogTitle.value = '添加'
setTimeout(() => { setTimeout(() => {
doctorFormRef.value.resetData() doctorFormRef.value.resetData()
}, 0) }, 0)
} }
const importData = () => { const importData = () => {
setTimeout(() => { setTimeout(() => {
importDialogRef.value.open() importDialogRef.value.open()
}, 0); }, 0);
} }
const removeData = (e?: any) => { const removeData = (e?: any) => {
const selectRow = e || tableRef.value.getSelectionRows() const selectRow = e || tableRef.value.getSelectionRows()
tableRemoveRow({ data: selectRow }, (res: boolean) => { tableRemoveRow({data: selectRow}, (res: boolean) => {
if (res) { if (res) {
const index = tableData.value.findIndex((item: any) => item === selectRow) const index = tableData.value.findIndex((item: any) => item === selectRow)
tableData.value.splice(index, 1) tableData.value.splice(index, 1)
// console.log('', selectRow, index) // console.log('', selectRow, index)
} }
}) })
} }
const enableChange = (e: any) => { const enableChange = (e: any) => {
ElMessage.success(e.enable ? '启用成功' : '禁用成功') if (e.lockFlag == 0) {
} else {}
ElMessage.success(e.lockFlag ? '启用成功' : '禁用成功')
} }
const resetPassword = (e: any) => { const resetPassword = (e: any) => {
ElMessageBox.confirm('是否确定要重置密码?', '系统提醒', { type: 'warning', draggable: true }).then(() => { ElMessageBox.confirm('是否确定要重置密码?', '系统提醒', {type: 'warning', draggable: true}).then(() => {
ElMessage.success('重置成功!') ElMessage.success('重置成功!')
}).catch(() => { }) }).catch(() => {
})
} }
const editData = (e: any) => { const editData = (e: any) => {
isFormDialog.value = true isFormDialog.value = true
formDialogTitle.value = '修改' formDialogTitle.value = '修改'
setTimeout(() => { setTimeout(() => {
doctorFormRef.value.resetData() doctorFormRef.value.resetData()
doctorFormRef.value.formData = JSON.parse(JSON.stringify(e)) doctorFormRef.value.formData = JSON.parse(JSON.stringify(e))
}, 0) }, 0)
} }
const tableRowClick = (row: any) => { const tableRowClick = (row: any) => {
tableRef.value.toggleRowSelection(row) tableRef.value.toggleRowSelection(row)
} }
const doctorFormSave = (data: any, type: string) => { const doctorFormSave = (data: any, type: string) => {
if(type === 'add') { if (type === 'add') {
tableData.value.unshift(Object.assign({}, data)) tableData.value.unshift(Object.assign({}, data))
}else { } else {
tableData.value.forEach((item: any) => { tableData.value.forEach((item: any) => {
if(item.id === data.id) { if (item.id === data.id) {
Object.assign(item, data) Object.assign(item, data)
} }
}) })
} }
// console.log(data, type)
} }
const paginationChange = (page: number, size: number) => { const paginationChange = (page: number, size: number) => {
console.log(page, size)
} }
</script> </script>

View File

@ -1,158 +1,188 @@
<template> <template>
<el-form ref="formRef" :model="formData" :rules="rules" label-width="80"> <el-form ref="formRef" :model="formData" :rules="rules" label-width="80">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="用户名" prop="userName"> <el-form-item label="用户名" prop="username">
<el-input v-model="formData.userName" placeholder="请输入用户名" :disabled="type === 'edit'"></el-input> <el-input v-model="formData.username" placeholder="请输入用户名"
</el-form-item> :disabled="type === 'edit'"></el-input>
</el-col> </el-form-item>
<el-col :span="12"> </el-col>
<el-form-item label="姓名" prop="name"> <el-col :span="12">
<el-input v-model="formData.name" placeholder="请输入姓名"></el-input> <el-form-item label="姓名" prop="name">
</el-form-item> <el-input v-model="formData.name" placeholder="请输入姓名"></el-input>
</el-col> </el-form-item>
</el-row> </el-col>
<el-row> </el-row>
<el-col :span="12"> <el-row>
<el-form-item label="角色" prop="role"> <el-col :span="12">
<el-select v-model="formData.role" placeholder="请选择角色"> <el-form-item label="角色" prop="role">
<el-option v-for="item in roleOption" :key="item.value" :label="item.label" :value="item.value" /> <el-select v-model="formData.role" placeholder="请选择角色" multiple>
</el-select> <el-option v-for="item in roleOption" :key="item.roleId" :label="item.roleName"
</el-form-item> :value="item.roleId"/>
</el-col> </el-select>
<el-col :span="12"> </el-form-item>
<el-form-item label="邮箱" prop="mailbox"> </el-col>
<el-input v-model="formData.mailbox" placeholder="请输入邮箱"></el-input> <el-col :span="12">
</el-form-item> <el-form-item label="邮箱" prop="email">
</el-col> <el-input v-model="formData.email" placeholder="请输入邮箱"></el-input>
</el-row> </el-form-item>
<el-row> </el-col>
<el-col :span="12"> </el-row>
<el-form-item label="电话" prop="phone"> <el-row>
<el-input v-model="formData.phone" placeholder="请输入电话"></el-input> <el-col :span="12">
</el-form-item> <el-form-item label="电话" prop="phone">
</el-col> <el-input v-model="formData.phone" placeholder="请输入电话"></el-input>
<el-col :span="12"> </el-form-item>
<el-form-item label="启用" prop="enable"> </el-col>
<el-radio-group v-model="formData.enable"> <el-col :span="12">
<el-radio :label="true" border>有效</el-radio> <el-form-item label="启用" prop="lockFlag">
<el-radio :label="false" border>禁用</el-radio> <el-radio-group v-model="formData.lockFlag">
</el-radio-group> <el-radio :label="'0'" border>有效</el-radio>
</el-form-item> <el-radio :label="'1'" border>禁用</el-radio>
</el-col> </el-radio-group>
</el-row> </el-form-item>
</el-col>
</el-row>
<el-row v-if="type === 'edit'">
<el-col :span="12">
<el-form-item label="密码" prop="password">
<el-input v-model="formData.password" placeholder="请输入密码"
:disabled="type === 'edit'"></el-input>
</el-form-item>
</el-col>
</el-row>
<div style="text-align: right;padding-top: 80px;"> <div style="text-align: right;padding-top: 80px;">
<el-button class="f18" @click="close">取消</el-button> <el-button class="f18" @click="close">取消</el-button>
<el-button class="f18" type="primary" @click="saveData">确认</el-button> <el-button class="f18" type="primary" @click="saveData">确认</el-button>
</div> </div>
</el-form> </el-form>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue' import {onMounted, reactive, ref, toRefs, watch} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import {ElMessage, ElMessageBox} from 'element-plus'
import {getRoleList} from "@/api/role";
import {addUser} from "@/api/user";
const emit = defineEmits(['close', 'save']) const emit = defineEmits(['close', 'save'])
const props = defineProps({ const props = defineProps({
type: String type: String
}) })
const roleOption = [ const roleOption = ref<any>([])
{ label: '普通用户', value: '普通用户' },
{ label: '中级管理员', value: '中级管理员' },
{ label: '高级管理员', value: '高级管理员' },
]
const validatorPhone = (rule: any, value: any, callback: any) => { const validatorPhone = (rule: any, value: any, callback: any) => {
var isPhone = /^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/; var isPhone = /^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
if (value.indexOf('****') >= 0) { if (value.indexOf('****') >= 0) {
return callback().trim(); return callback().trim();
} }
if (!isPhone.test(value)) { if (!isPhone.test(value)) {
callback(new Error('请输入合法手机号')); callback(new Error('请输入合法手机号'));
} else { } else {
callback(); callback();
} }
} }
const rules = reactive({ const rules = reactive({
userName: [ username: [
{ required: true, message: '请输入用户名', trigger: ['blur', 'change'] }, {required: true, message: '请输入用户名', trigger: ['blur', 'change']},
], ],
name: [ name: [
{ required: true, message: '请输入姓名', trigger: ['blur', 'change'] }, {required: true, message: '请输入姓名', trigger: ['blur', 'change']},
], ],
role: [ role: [
{ required: true, message: '请选择角色', trigger: ['blur', 'change'] }, {required: true, message: '请选择角色', trigger: ['blur', 'change']},
], ],
phone: [ phone: [
{ required: true, validator:validatorPhone, trigger: ['blur', 'change'] }, {required: true, validator: validatorPhone, trigger: ['blur', 'change']},
], ],
password: [
{required: true, message: '请输入密码', trigger: ['blur', 'change']},
]
}) })
const formRef = ref() const formRef = ref()
const formData = ref({ const formData = ref({
id: '', id: '',
userName: '', username: '',
name: '', name: '',
role: '', role: '',
mailbox: '', email: '',
phone: '', phone: '',
enable: true, password: '',
lockFlag: '0',
} as any) } as any)
onMounted(() => { onMounted(() => {
resetData() resetData()
})
getRoleList().then((res: any) => {
if (res && res.code == 0) {
roleOption.value = res.data
} else {
ElMessage.error('角色列表获取失败')
}
console.log(res)
}) })
defineExpose({ defineExpose({
formData, formData,
resetData, resetData,
}) })
function close() { function close() {
emit('close') emit('close')
} }
function resetData() { function resetData() {
formRef.value.resetFields() getRoleList()
formData.value = { formRef.value.resetFields()
id: '', formData.value = {
userName: '', id: '',
name: '', username: '',
role: '', name: '',
mailbox: '', role: '',
phone: '', email: '',
enable: true, phone: '',
} password: '',
lockFlag: '0',
}
} }
const saveData = async () => { const saveData = async () => {
await formRef.value.validate((valid: any, fields: any) => { await formRef.value.validate((valid: any, fields: any) => {
if (valid) { if (valid) {
ElMessage.success('保存成功!') addUser(formData.value).then((data: any) => {
emit('save', formData.value, props.type) console.log(data)
close() })
} else { ElMessage.success('保存成功!')
// console.log('error submit!', fields) emit('save', formData.value, props.type)
} console.log(formData.value)
}) close()
} else {
// console.log('error submit!', fields)
}
})
} }
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
:deep(.el-form-item) { :deep(.el-form-item) {
.el-form-item__label { .el-form-item__label {
display: block; display: block;
text-align: justify; text-align: justify;
text-align-last: justify; text-align-last: justify;
padding: 0 10px 0 20px; padding: 0 10px 0 20px;
&:before {
display: none; &:before {
} display: none;
} }
}
} }
</style> </style>

View File

@ -3,33 +3,33 @@
<div class="header-box"> <div class="header-box">
<div class="thumbnail" @click="viewThumbnail"> <div class="thumbnail" @click="viewThumbnail">
<el-icon> <el-icon>
<Menu /> <Menu/>
</el-icon> </el-icon>
<span>缩略图</span> <span>缩略图</span>
</div> </div>
<div class="task-btn-item" v-for="(item, index) in remoteTask" :key="'task-' + index" <div class="task-btn-item" v-for="(item, index) in remoteTask" :key="'task-' + index"
:class="{ 'connecting': item.patientName || item.patientCode, 'alarm': item.dataAlarm }" :class="{ 'connecting': item.patientName || item.patientCode, 'alarm': item.dataAlarm }"
@click="editTask(item, index)" @dblclick="toRemoteControl(item, index)"> @click="editTask(item, index)" @dblclick="toRemoteControl(item, index)">
<span>{{ item.title || ('新建任务' + (index + 1)) }}</span> <span>{{ item.title || ('新建任务' + (index + 1)) }}</span>
</div> </div>
</div> </div>
<div class="content-box"> <div class="content-box">
<div class="remote-box"> <div class="remote-box">
<RemotePart ref="remotePartRef" @addLogAfter="addLogAfter" @breakRemote="breakRemote" /> <RemotePart ref="remotePartRef" @addLogAfter="addLogAfter" @breakRemote="breakRemote"/>
</div> </div>
<div class="message-box"> <div class="message-box">
<MessagePart ref="messagePartRef" /> <MessagePart ref="messagePartRef"/>
</div> </div>
</div> </div>
</div> </div>
<RemoteDialog ref="remoteDialogRef" @confirmRemote="confirmRemote" @errorRemote="errorRemote" /> <RemoteDialog ref="remoteDialogRef" @confirmRemote="confirmRemote" @errorRemote="errorRemote"/>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue' import {onMounted, reactive, ref, toRefs, watch} from 'vue'
import { useRouter } from 'vue-router' import {useRouter} from 'vue-router'
import { useRemoteStore } from '@/stores/remote-info-store' import {useRemoteStore} from '@/stores/remote-info-store'
import type { RemoteItem } from '@/utils/public-interface' import type {RemoteItem} from '@/utils/public-interface'
import RemoteDialog from './part/remote-dialog.vue' import RemoteDialog from './part/remote-dialog.vue'
import RemotePart from './part/remote-part.vue' import RemotePart from './part/remote-part.vue'
import MessagePart from './part/message-part.vue' import MessagePart from './part/message-part.vue'
@ -57,6 +57,7 @@ function resetRemoteTaskItem(e: RemoteItem) {
index: e.index, index: e.index,
}) })
} }
function initRemoteTask() { function initRemoteTask() {
remoteTask.value = remoteStore.remoteTasks remoteTask.value = remoteStore.remoteTasks
if (remoteTask.value.length < 1) { if (remoteTask.value.length < 1) {
@ -82,7 +83,7 @@ function initRemoteTask() {
} }
remoteStore.setRemoteTasks(remoteTask.value) remoteStore.setRemoteTasks(remoteTask.value)
if (!remoteStore.currentRemote.index) { if (!remoteStore.currentRemote.index) {
remoteStore.$patch({ currentRemote: remoteTask.value[0] }) remoteStore.$patch({currentRemote: remoteTask.value[0]})
} }
} }
} }
@ -189,6 +190,45 @@ function disconnectSurgeryData(username: string, db: string) {
const account = "admin"; const account = "admin";
surgeryClient.unsubscribe("/topic/user/" + account + ":" + db + "/surgeryData"); surgeryClient.unsubscribe("/topic/user/" + account + ":" + db + "/surgeryData");
} }
const chatClient = new Client({
brokerURL: 'ws://localhost:5173/socket.io/admin/rax/chat',
connectHeaders: {
token: Session.get('token')
},
reconnectDelay: 5000,
heartbeatIncoming: 60000,
heartbeatOutgoing: 60000
})
chatClient.activate()
const patientName = '111'
const idNum = '111'
const date = '20230505'
function sendChatMessage() {
const message = {
patientName: patientName,
idNum: idNum,
date: date,
msg: '测试消息'
}
chatClient.publish({
destination: '/front/sendMessage',
headers: {
token: Session.get('token')
},
body: JSON.stringify(message)
})
}
chatClient.onConnect = () => {
chatClient.subscribe('/topic/user/' + patientName + idNum + date + '/chatroomMessage', (data: any) => {
console.log(data)
})
}
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
@ -230,7 +270,7 @@ function disconnectSurgeryData(username: string, db: string) {
font-size: 1.4em; font-size: 1.4em;
} }
&>span { & > span {
display: none; display: none;
margin-left: 5px; margin-left: 5px;
line-height: 1; line-height: 1;
@ -241,7 +281,7 @@ function disconnectSurgeryData(username: string, db: string) {
width: 160px; width: 160px;
transition: all .3s; transition: all .3s;
&>span { & > span {
display: block; display: block;
} }
} }