zoo-frontend/src/pages/ZooHealth.vue
2024-06-23 02:29:41 +08:00

541 lines
17 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>
import {Delete, DocumentAdd, Document, Edit, Search, Tickets, Timer} from "@element-plus/icons-vue";
import {mapActions, mapMutations, mapState} from "vuex";
import {copy, fuzzyMatching, refreshData, sortByDateTime, splitKeyWords} from "@/utils/common.js";
import ZooHealthFormDialog from "@/components/ZooHealthFormDialog.vue";
import ZooHealthTimeline from "@/components/ZooHealthTimeline.vue";
import request, {frontendHealth, frontendHealths} from "@/utils/request.js";
export default {
name: "ZooHealth",
components: {ZooHealthTimeline, ZooHealthFormDialog},
data() {
return {
//表格分页显示的数据
pagesData: [],
pageSize: 20,//每页有多少条数据
currentPage: 1,//当前页
order: 0,//排序相关参数
// 搜索框的输入
searchInput: {
option: '',//状态0正常 1异常
keyword: ''
},
// 控制弹窗的属性
dialog: {
dialogData: {},//弹窗数据
addDialogVisible: false,//添加对话框
editDialogVisible: false,//编辑对话框
detailDialogVisible: false,//查询对话框
timelineDialogVisible: false,//时间线对话框
timelineData: []//时间线数据
},
}
},
computed: {
//图标
//region
Search() {
return Search
},
DocumentAdd() {
return DocumentAdd
},
Edit() {
return Edit
},
Delete() {
return Delete
},
Document() {
return Document
},
Tickets() {
return Tickets
},
Timer() {
return Timer
},
//endregion
...mapState(["healths", 'healthsTableData','loginUser']),
operateWidth() {
return this.loginUser.auth===2?'250':'130'
}
},
watch: {
// 搜索框存在输入,自动调用搜索(刷新数据包含搜索)
searchInput: {
deep: true,
handler(val) {
// this.search()
this.refresh();
}
},
//切换排序,刷新数据
order(){
this.refresh()
}
},
methods: {
...mapMutations(['updateHealths','updateHealthsTableData']),
// 显示详情弹窗
showDetail(data) {
console.log('显示详情', data)
//从后端获取需要查询的数据,防止数据前后不一致
request.queryHealthRequest(data.id,null).then(response => {
if (response.data.data === null) {
this.refresh();
return ElMessage({
message: '该监测记录不存在,请刷新',
type: 'warning',
})
}else {
this.dialog.dialogData = frontendHealth(response.data.data)
//显示弹窗
this.dialog.detailDialogVisible = true
}
})
},
//显示编辑弹窗
showEdit(data) {
console.log('显示编辑', data)
//从后端获取需要查询的数据,防止数据前后不一致
request.queryHealthRequest(data.id,null).then(response => {
if (response.data.data === null) {
this.refresh();
return ElMessage({
message: '该监测记录不存在,请刷新',
type: 'warning',
})
}else {
this.dialog.dialogData = frontendHealth(response.data.data)
//显示弹窗
this.dialog.editDialogVisible = true
}
})
},
edit(data) {
console.log('编辑', data)
//判断表单是否为空
if (this.isEmpty(data)) {
return;
}
//这里将数据传给后端进行数据更新
//从后端获取需要查询的数据,防止数据前后不一致
request.queryHealthRequest(data.id,null).then(response => {
if (response.data.data === null) {
this.refresh();
this.dialog.editDialogVisible = false;
return ElMessage({
message: '该监测记录不存在,请刷新',
type: 'warning',
})
}else {
request.updateHealthRequest(data).then(response => {
if (response.data.code === 1) {
//编辑成功
//刷新数据
this.refresh()
request.queryHealthRequest(null,this.dialog.dialogData.animalId).then(response => {
if (response.data.code===1){
this.dialog.timelineData = frontendHealths(response.data.data)
}
})
this.dialog.editDialogVisible = false//关闭窗口
return ElMessage({
message: '编辑成功',
type: 'success',
})
} else {
return ElMessage({
message: '编辑失败',
type: 'warning',
})
}
})
}
})
},
delete_(data) {
console.log('删除', data)
return ElMessageBox.confirm(
'该操作不可撤销,是否继续?',
'删除健康检测记录:' + data.id,
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
//进行删除操作
//从后端获取需要查询的数据,防止数据前后不一致
request.queryHealthRequest(data.id,null).then(response => {
if (response.data.data === null) {
this.refresh();
return ElMessage({
message: '该监测记录不存在,请刷新',
type: 'warning',
})
}else {
request.deleteHealthRequest(data.id).then(response => {
if (response.data.code === 1) {
//编辑成功
//刷新数据
this.refresh()
request.queryHealthRequest(null,this.dialog.dialogData.animalId).then(response => {
if (response.data.code===1){
this.dialog.timelineData = frontendHealths(response.data.data)
}
})
return ElMessage({
message: '删除成功',
type: 'success',
})
} else {
return ElMessage({
message: '删除失败',
type: 'warning',
})
}
})
}
})
}).catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
},
add(data) {
console.log('添加', data)
//验证是否为空
if (this.isEmpty(data)) {
return;
}
request.addHealthRequest(data).then(response => {
if (response.data.code === 1) {
//添加成功
//刷新数据
this.refresh()
this.dialog.addDialogVisible = false//关闭窗口
return ElMessage({
message: '添加成功',
type: 'success',
})
} else {
return ElMessage({
message: '添加失败',
type: 'warning',
})
}
})
},
//以时间线的形式查看该动物的所有档案记录
showTimeline(data) {
console.log('显示时间线记录', data)
this.dialog.dialogData = data
//从后端获取需要查询的数据
request.queryHealthRequest(null,data.animalId).then(response=>{
if (response.data.code === 1) {
this.dialog.timelineData = frontendHealths(response.data.data)
//显示弹窗
this.dialog.timelineDialogVisible = true
}
})
},
// 判断表单是否为空
isEmpty(form) {
if (!form.animalId||!form.animalName) {
//返回提示
return ElMessage({
message: '动物ID或动物名称不能为空',
type: 'warning',
})
}
},
search() {
console.log('搜索', this.searchInput)
let searchResult = []//搜索结果数组
//第一步匹配搜索选项
if (typeof this.searchInput.option === 'number') {
this.healths.forEach(e => {
if (e.state === this.searchInput.option) {
searchResult.push(copy(e))//如果符合特定权限,则添加到搜索结果
}
})
} else { //如果没有选择特定用户身份,代表所有数据都需要参加到下一轮的模糊搜索
searchResult = copy(this.healths)
}
let searchResult2 = []
let keyset = splitKeyWords(this.searchInput.keyword)//切割关键字
//第二步进行模糊搜索
searchResult.forEach(e => {
//如果该对象能匹配上所有关键字,则添加到结果
// console.log('开始进行模糊匹配,对象、关键字集合分别为',e,keyset)
let is = fuzzyMatching(e, keyset);
if (is) {
searchResult2.push(e)
}
// console.log('结束模糊匹配,结果为',e,keyset,is)
})
searchResult = searchResult2
this.updateHealthsTableData(searchResult)
// this.getPagesData()
},
//按时间排序
timeSort(val) {
//0降序
if (val === 0) {
this.updateHealthsTableData(sortByDateTime(copy(this.healthsTableData)))
return
}
//1升序
if (val === 1) {
this.updateHealthsTableData(sortByDateTime(copy(this.healthsTableData)).reverse())
return;
}
},
//分页相关方法
//region
//当前页切换时触发
handleCurrentChange(val) {
console.log('分页被切换', val)
this.currentPage = val
this.getPagesData()
},
getPagesData() {
console.log('获取分页数据')
const start = (this.currentPage - 1) * this.pageSize
const end = start + this.pageSize
this.pagesData = this.healthsTableData.slice(start, end)
},
//endregion
changeOrder(){
if (this.order===0)
this.order++
else this.order--
},
//刷新数据的方法
refresh() {
console.log('刷新数据')
//先拉取一遍数据
request.queryHealthRequest().then(response=>{
if (response.data.code===1){
this.updateHealths(frontendHealths(response.data.data))
}
//可能输入了搜索关键字,故执行一次搜索
this.search()
//排序
this.timeSort(this.order)
//获取结果的分页
this.getPagesData()
})
}
},
mounted() {
// 加载完成后拉取数据
this.refresh()
refreshData()
},
}
</script>
<template>
<div class="health-root">
<div class="select">
<div class="left" v-if="loginUser.auth===2">
<el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加记录</el-button>
</div>
<div class="right">
<el-button type="primary" :icon="Timer" @click="changeOrder" style="margin-right: 40px">按时间升 / 降序</el-button>
<el-input
v-model="searchInput.keyword"
style="width: 500px"
placeholder="搜索记录 空格隔开关键字"
>
<template #prepend>
<el-select v-model="searchInput.option" placeholder="状态" style="width: 80px">
<el-option label="不选择" value=""/>
<el-option label="正常" :value="0"/>
<el-option label="异常" :value="1"/>
</el-select>
</template>
<template #append>
<el-button :icon="Search" @click="refresh()"/>
</template>
</el-input>
</div>
</div>
<div class="table">
<el-table :data="pagesData" style="width: 100%;height: 100%" border stripe :row-style="{height: '40px'}"
:cell-style="{padding:'0'}">
<el-table-column fixed prop="id" label="监测号" width="70"/>
<el-table-column fixed prop="animalId" label="动物ID" width="70"/>
<el-table-column prop="animalName" label="动物名称" width="100"/>
<el-table-column prop="temperature" label="体温(°C)" width="80">
<template #default="scope">
<span v-if="scope.row.temperature>=35 && scope.row.temperature<=42"
style="color: #67C23A">{{ scope.row.temperature }}</span>
<span v-else style="color: #F56C6C">{{ scope.row.temperature }}</span>
</template>
</el-table-column>
<el-table-column prop="breathRate" label="呼吸频率(次/分)" width="90">
<template #default="scope">
<span v-if="scope.row.breathRate>=10 && scope.row.breathRate<=100"
style="color: #67C23A">{{ scope.row.breathRate }}</span>
<span v-else style="color: #F56C6C">{{ scope.row.breathRate }}</span>
</template>
</el-table-column>
<el-table-column prop="heartRate" label="心跳频率(次/分)" width="90">
<template #default="scope">
<span v-if="scope.row.heartRate>=10 && scope.row.heartRate<=140"
style="color: #67C23A">{{ scope.row.heartRate }}</span>
<span v-else style="color: #F56C6C">{{ scope.row.heartRate }}</span>
</template>
</el-table-column>
<el-table-column prop="bloodPressure" label="动物血压(mmHg)" width="90">
<template #default="scope">
<span v-if="scope.row.bloodPressure>=70 && scope.row.bloodPressure<=180"
style="color: #67C23A">{{ scope.row.bloodPressure }}</span>
<span v-else style="color: #F56C6C">{{ scope.row.bloodPressure }}</span>
</template>
</el-table-column>
<el-table-column prop="state" label="动物状态" width="90">
<template #default="scope">
<span v-if="scope.row.state===0" style="color: #67C23A">正常</span>
<span v-else-if="scope.row.state===1" style="color: #F56C6C">异常</span>
<span v-else>未知</span>
</template>
</el-table-column>
<el-table-column prop="date" label="记录日期" width="110"/>
<el-table-column prop="time" label="记录时间" width="90"/>
<el-table-column prop="description" label="记录描述" width="300"/>
<el-table-column fixed="right" label="操作" :width="operateWidth">
<template #default="scope">
<el-button link type="success" size="small" :icon="Tickets" @click="showTimeline(scope.row)">
追踪
</el-button>
<el-button link type="primary" size="small" :icon="Document" @click="showDetail(scope.row)">
详情
</el-button>
<el-button link type="primary" size="small" :icon="Edit" @click="showEdit(scope.row)" v-if="loginUser.auth===2">
编辑
</el-button>
<el-button link type="danger" size="small" :icon="Delete" @click="delete_(scope.row)" v-if="loginUser.auth===2">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页-->
<div class="pager relative">
<div class="center">
<el-pagination background layout="total, prev, pager, next, jumper" :total="healthsTableData.length"
:page-size="pageSize" small @current-change="handleCurrentChange"/>
</div>
</div>
</div>
<!-- 添加记录对话框-->
<el-dialog v-model="dialog.addDialogVisible" title="添加记录" width="500" align-center draggable overflow
destroy-on-close>
<ZooHealthFormDialog>
<template #default="scope">
<el-button @click="dialog.addDialogVisible = false">
取消
</el-button>
<el-button type="primary" @click="add(scope.form)">
添加
</el-button>
</template>
</ZooHealthFormDialog>
</el-dialog>
<!-- 编辑记录对话框-->
<el-dialog v-model="dialog.editDialogVisible" title="编辑记录" width="500" align-center draggable overflow
destroy-on-close>
<ZooHealthFormDialog :data="dialog.dialogData" edit>
<template #default="scope">
<el-button @click="dialog.editDialogVisible = false">
取消
</el-button>
<el-button type="primary" @click="edit(scope.form)">
修改
</el-button>
</template>
</ZooHealthFormDialog>
</el-dialog>
<!-- 查看记录对话框-->
<el-dialog v-model="dialog.detailDialogVisible" title="查询记录" width="500" align-center draggable overflow
destroy-on-close>
<ZooHealthFormDialog :data="dialog.dialogData" detail>
<template #default="scope">
<el-button @click="dialog.detailDialogVisible = false">
关闭
</el-button>
</template>
</ZooHealthFormDialog>
</el-dialog>
<!-- 查看动物所有记录-->
<el-dialog v-model="dialog.timelineDialogVisible" :title="'健康监测追踪:'+dialog.dialogData.animalId" width="600" align-center draggable overflow
destroy-on-close>
<ZooHealthTimeline :data="dialog.timelineData">
<template #operate="scope">
<el-button type="primary" link @click="showEdit(scope.health)">编辑</el-button>
<el-button type="danger" link @click="delete_(scope.health)">删除</el-button>
</template>
<template #footer>
<el-button @click="dialog.timelineDialogVisible = false">
关闭
</el-button>
</template>
</ZooHealthTimeline>
</el-dialog>
</template>
<style scoped>
</style>