JM-admin/src/view/hospital/index.vue
2024-03-21 20:27:46 +08:00

646 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
// 引入依赖
import api from '@/api/hospital'
// import capi from '@/api/course'
import custom from '@/utils/custom'
import { formatDate } from '@/utils/format'
import _ from 'lodash'
// import { toSQLLine } from '@/utils/stringFun'
// import WarningBar from '@/components/warningBar/warningBar.vue'
import ckEditor from '@/components/richText/ckEditor5.vue'
import { ref, onMounted, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
const path = ref(import.meta.env.VITE_BASE_API)
import { useUserStore } from '@/pinia/modules/user'
const userStore = useUserStore()
// 变量
const typeList = custom.getExercisesTypeList()
const queryParams = ref({
page: 1,
pageSize: 10,
// name: '',
// type: '',
// subject: ''
})
// const subjectParams = ref({
// page: 1,
// pageSize: 100,
// })
const tableData = ref([])
// const subjectList = ref([])
const deleteVisible = ref(false)
const question_ids = ref([])
const total = ref(0)
const dialogFormVisible = ref(false)
const dialogTitle = ref('')
const form = ref({})
const rules = ref({
name: [{ required: true, message: '请输入标题', trigger: 'blur' }],
addr: [{ required: true, message: '请输入地址', trigger: 'blur' }],
phone: [{ required: true, message: '请输入电话', trigger: 'blur' }],
})
// const question_id = ref(0)
// const content = ref(null)
// const options = ref([]) // 答案选项数组
const question_form = ref({
options: [],
answer: '',
title: ''
})
const apiForm = ref(null)
const note_list = ref([
// {
// content: '',
// notes_time: ''
// }
])
const time_options = ref([
'手术前',
'手术中',
'手术后'
])
const todo_list = ref([])
// 生命周期
onMounted(() => {
getHospitalList()
// getSubject()
})
// 方法
async function getHospitalList() {
const res = await api.getHospitalList(queryParams.value)
if (res.code === 0) {
tableData.value = res.data.list
// console.log(tableData.value)
total.value = res.data.total
}
}
// async function getSubject() { // 获取课程分类
// const res = await capi.getSubjectList(subjectParams.value)
// if (res.code === 0) {
// subjectList.value = custom.getStdSubject(res.data.records)
// }
// }
function onSubmit() {
getHospitalList()
}
const onReset = () => {
queryParams.value = {
page: 1,
pageSize: 10,
name: '',
// status: '',
// subject: ''
}
}
function openDialog(type) {
dialogFormVisible.value = true
// let params = {}
switch (type) {
case 'add':
dialogTitle.value = '新增医院'
// form.value = {}
break
case 'edit':
// params.question_id = question_id.value
dialogTitle.value = '编辑医院信息'
break
}
// router.push({name:'addCourse',params})
}
async function onDelete() {
const ids = question_ids.value.map(item => item.question_id)
const res = await api.delExercises({ question_ids: ids })
if (res.code === 0) {
ElMessage({
type: 'success',
message: res.msg
})
deleteVisible.value = false
getHospitalList()
}
}
const handleSelectionChange = (val) => {
question_ids.value = val
}
function editFunc(row) {
form.value = _.cloneDeep(row)
// console.log(form.value)
// 提醒时间用逗号分隔为数组
todo_list.value = _.cloneDeep(form.value.todos)
for (const item of todo_list.value) {
item.remindTime = item.remindTime.split(',')
}
note_list.value = form.value.notes
openDialog('edit')
}
function deleteFunc(row) {
ElMessageBox.confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async() => {
const res = await api.deleteFunc({
id: row.ID
})
if (res.code === 0) {
ElMessage({
type: 'success',
message: '删除成功!'
})
getHospitalList()
}
}, () => {
})
}
function handleCurrentChange(val) {
queryParams.value.page = val
getHospitalList()
}
function handleSizeChange(val) {
queryParams.value.pageSize = val
getHospitalList()
}
function closeDialog() {
dialogFormVisible.value = false
todo_list.value = []
note_list.value = []
form.value = {}
resetForm()
}
async function enterDialog() { // 提交
await apiForm.value.validate(async(valid, fields) => {
if (valid) {
console.log('submit!')
let func_name = 'addHospital'
if (form.value.ID) { // 编辑
func_name = 'editHospital'
}
form.value.todos = _.cloneDeep(todo_list.value)
// 提醒时间用逗号分隔
for (const item of form.value.todos) {
if (Array.isArray(item.remindTime)) {
item.remindTime = item.remindTime.join(',')
}
}
// 新参数
for (const item of note_list.value) {
for (let i = 0; i < time_options.value.length; i++) {
// eslint-disable-next-line no-empty
if (item.notes_time === time_options.value[i]) {
item.notes_time_num = i + 1
}
}
}
form.value.notes = note_list.value
// console.log(form.value);return
const res = await api[func_name](form.value)
if (res.code === 0) {
ElMessage({
type: 'success',
message: res.msg
})
getHospitalList()
closeDialog()
}
} else {
// console.log('error submit!', fields)
}
})
}
const resetForm = () => {
apiForm.value.resetFields()
}
function addRowFunc(type, child_index = null) {
// {
// content: '',
// notes_time: ''
// }
if (type === 1) { // 注意事项
note_list.value.push({
content: '',
notes_time: ''
})
} else { // 待办事项
if (child_index != null) {
todo_list.value[child_index].remindTime.push(0)
} else {
todo_list.value.push({
content: '',
remindPeriod: 0,
frequency: '', // 用药频率
remindTime: []
})
}
}
}
function del_ro_func(i, type, child_index = null) {
if (type === 1) {
note_list.value.splice(i, 1)
} else {
if (child_index != null) {
todo_list.value[i].remindTime.splice(child_index, 1)
} else {
todo_list.value.splice(i, 1)
}
}
}
// 图片上传
const uploading_form = reactive({
uploading: false,
progressStatus: 'info',
percentage: 0, // 进度条
})
function init_uploading() {
uploading_form.uploading = false
uploading_form.progressStatus = 'info'
uploading_form.percentage = 0
}
function handleAvatarSuccess(res) {
console.log('res is ====', res)
note_list.value[note_list_item_index.value].content = res.data.file.url
uploading_form.progressStatus = 'info'
uploading_form.percentage = 100
setTimeout(() => {
init_uploading()
}, 500)
}
function beforeAvatarUpload(file) {
init_uploading()
uploading_form.uploading = true
const isLt05M = file.size / 1024 / 1024 < 20
const isJPG = file.type.indexOf('image/') === -1
if (isJPG) {
uploading_form.uploading = false
uploading_form.progressStatus = 'warning'
ElMessage.error('文件格式错误,请上传图片类型,如JPGPNG后缀的文件')
}
if (!isLt05M) {
uploading_form.uploading = false
uploading_form.progressStatus = 'warning'
ElMessage.error('上传头像图片大小不能超过 2M!')
}
const interval = Math.random(100) * 100
console.log('interval is ====', interval)
setInterval(() => {
if (uploading_form.percentage < interval) {
uploading_form.percentage += 1
}
}, 10)
return !isJPG && isLt05M
}
const note_list_item_index = ref(0)
function beforeUploadImg(i) {
note_list_item_index.value = i
}
</script>
<template>
<div>
<!-- 搜索框-->
<div class="gva-search-box">
<el-form ref="searchForm" :inline="true" :model="queryParams">
<el-form-item label="医院名称">
<el-input v-model="queryParams.name" placeholder="根据医院名称进行查询" />
</el-form-item>
<!-- <el-form-item label="课程分类">
<el-select v-model="queryParams.subject" clearable placeholder="请选择">
<el-option v-for="item in subjectList" :key="item.id" :label="item.name" :value="item.name" />
</el-select>
</el-form-item>
<el-form-item label="题型">
<el-select v-model="queryParams.type" clearable placeholder="请选择">
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item> -->
<el-form-item>
<el-button size="small" type="primary" icon="search" @click="onSubmit">查询</el-button>
<el-button size="small" icon="refresh" @click="onReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 表格数据-->
<div class="gva-table-box">
<!-- 批量操作-->
<div class="gva-btn-list">
<el-button size="small" type="primary" icon="plus" @click="openDialog('add')">新增</el-button>
<el-popover v-model="deleteVisible" placement="top" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin-top: 8px;">
<el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button>
<el-button size="small" type="primary" @click="onDelete">确定</el-button>
</div>
<!-- <template #reference>
<el-button
icon="delete"
size="small"
type="danger"
:disabled="!question_ids.length"
style="margin-left: 10px;"
@click="deleteVisible = true"
>删除</el-button>
</template> -->
</el-popover>
</div>
<!-- 数据列表-->
<el-table :data="tableData" @selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" /> -->
<el-table-column align="left" label="ID" min-width="60" prop="ID" sortable="custom" />
<el-table-column align="left" label="医院名称" min-width="150" prop="name">
<!-- <template #default="scope">
{{ custom.getExercisesTypeName(scope.row.type) }}
</template> -->
</el-table-column>
<el-table-column align="left" label="医院地址" min-width="150">
<template #default="scope">
<div class="show-content text-ellipsis-1">{{ scope.row.addr }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="注意事项" min-width="150">
<template #default="scope">
<div>{{ scope.row.notes.length }}项</div>
</template>
</el-table-column>
<el-table-column align="center" label="待办事项" min-width="150">
<template #default="scope">
<div>{{ scope.row.todos.length }}项</div>
</template>
</el-table-column>
<el-table-column align="left" label="联系电话" min-width="150" prop="phone" />
<!-- <el-table-column align="left" label="创建者" min-width="150" prop="teacher_id" /> -->
<el-table-column align="left" label="创建时间" min-width="200">
<template #default="scope">
{{ formatDate(scope.row.CreatedAt) }}
</template>
</el-table-column>
<el-table-column align="left" fixed="right" label="操作" width="200">
<template #default="scope">
<el-button icon="edit" size="small" type="primary" link @click="editFunc(scope.row)">编辑</el-button>
<el-button icon="delete" size="small" type="danger" link @click="deleteFunc(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="gva-pagination">
<el-pagination
:current-page="queryParams.page"
:page-size="queryParams.pageSize"
:page-sizes="[10, 30, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@current-change="handleCurrentChange"
@size-change="handleSizeChange" />
</div>
</div>
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle">
<el-form ref="apiForm" :model="form" :rules="rules" label-width="80px">
<el-form-item required label="医院名称" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item required label="医院地址" prop="addr">
<el-input v-model="form.addr" />
</el-form-item>
<el-form-item required label="联系电话" prop="phone">
<el-input v-model="form.phone" />
</el-form-item>
<el-form-item label="注意事项" prop="notes">
<div class="item-card-box" style="flex:1">
<div v-for="(item, i) in note_list" :key="i" class="item-card">
<div class="del-row-btn" @click="del_ro_func(i,1)">
<el-icon>
<Close />
</el-icon>
</div>
<div class="ic-left">{{ i + 1 }} . </div>
<div class="ic-right">
<div class="ic-right-row">
<div class="icr-left">注意事项</div>
<div class="icr-right">
<!-- <el-input autosize type="textarea" v-model="item.content" /> -->
<el-upload
class="avatar-uploader"
:action="`${path}/fileUploadAndDownload/upload`"
:headers="{ 'x-token': userStore.token }"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
@click="beforeUploadImg(i)">
<div v-if="uploading_form.uploading" class="progress-box">
<el-progress
class="progress-item"
:percentage="uploading_form.percentage"
:status="uploading_form.progressStatus" />
</div>
<img v-if="item.content" :src="item.content" class="img-container">
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
</div>
</div>
<div class="ic-right-row">
<div class="icr-left">注意时间</div>
<div class="icr-right">
<el-select v-model="item.notes_time" class="m-2" placeholder="选择注意时间" size="large">
<el-option v-for="(item2, i) in time_options" :key="i" :label="item2" :value="item2" />
</el-select>
</div>
</div>
</div>
</div>
<div class="add-row-btn" style="text-align: center;cursor: pointer;" @click="addRowFunc(1)">
<el-icon>
<Plus />
</el-icon>
</div>
</div>
</el-form-item>
<el-form-item label="待办事项" prop="notes">
<div class="item-card-box" style="flex:1">
<div v-for="(item, i) in todo_list" :key="i" class="item-card">
<div class="del-row-btn" @click="del_ro_func(i,2)">
<el-icon>
<Close />
</el-icon>
</div>
<div class="ic-left">{{ i + 1 }} . </div>
<div class="ic-right">
<div class="ic-right-row">
<div class="icr-left">待办事项</div>
<div class="icr-right">
<el-input v-model="item.content" placeholder="请输入事项内容" autosize type="textarea" />
</div>
</div>
<div class="ic-right-row">
<div class="icr-left">用药频率</div>
<div class="icr-right">
<el-input v-model="item.frequency" placeholder="比如一天3次 一天4次" autosize type="textarea" />
</div>
</div>
<div class="ic-right-row">
<div class="icr-left">待办状态</div>
<div class="icr-right" style="display: flex;">
<el-select v-model="item.remindPeriod" placeholder="请选择待办状态">
<el-option label="手术前" :value="0" />
<el-option label="手术后" :value="1" />
</el-select>
<el-input v-model="item.remindDay" style="margin-left: 10px;" placeholder="填写提醒日期例如3-44-8" />
<div style="padding-left: 10px;">天</div>
</div>
</div>
<div class="ic-right-row ic-right-row2">
<div class="icr-left">提醒时间</div>
<div class="icr-right">
<div v-for="(item_l, il) in item.remindTime" :key="il" class="loop_card">
<el-time-picker
v-model="item.remindTime[il]"
value-format="HH:mm"
placeholder="请选择时间"
style="width: 100%;position: relative;" />
<div class="del-row-btn" @click="del_ro_func(i, 2, il)">
<el-icon>
<Close />
</el-icon>
</div>
</div>
<div class="add-row-btn" style="text-align: center;cursor: pointer;" @click="addRowFunc(2,i)">
<el-icon>
<Plus />
</el-icon>
</div>
</div>
</div>
</div>
</div>
<div class="add-row-btn" style="text-align: center;cursor: pointer;" @click="addRowFunc(2)">
<el-icon>
<Plus />
</el-icon>
</div>
</div>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button size="small" @click="closeDialog">取 消</el-button>
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<style scoped lang="scss">
.loop_card{
margin-bottom: 10px;
position: relative;
.del-row-btn{
right: 0;
}
}
.ic-right-row2{
align-items: unset !important;
}
.progress-box{
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
background: #0000001c;
justify-content: center;
// z-index: 100;
.progress-item{
width: 90%;
:deep(.el-progress__text) {
min-width: 10px;
}
}
}
.img-container {
width: 200px;
height: 150px;
}
.add-row-btn:hover{
background-color: rgb(244, 244, 244);
}
.item-card{
display: flex;
flex: 1;
padding: 10px;
border: 1px solid #dcdfe6;
border-radius: 10px;
margin-bottom: 10px;
position: relative;
// padding-right: 30px;
.del-row-btn{
position: absolute;
cursor: pointer;
width: 18px;
height: 18px;
background: #cecece;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
right: -7px;
top: -7px;
z-index: 10;
}
.ic-left{
padding-right: 10px;
}
.ic-right{
flex: 1;
.ic-right-row{
display: flex;
align-items: center;
padding-bottom: 10px;
.ic-right-row:last-child{
padding-bottom: 0px;
}
.icr-left{
margin-right: 10px;
}
.icr-right{
flex: 1;
}
}
}
}
.option-item {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.text-ellipsis-1{ /*超出部分省略号 单行*/
overflow:hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 1;
display: -webkit-box;
-webkit-box-orient: vertical;
/* min-height: 38rpx; */
}
.button-box {
padding: 10px 20px;
.el-button {
float: right;
}
}
.warning {
color: #dc143c;
}
.lbt-thumb{
width: 100px;
height: 50px;
}
</style>