编写健康监测界面

This commit is contained in:
bicey 2024-05-23 01:02:29 +08:00
parent 7bbc333e76
commit 384e599ccc
15 changed files with 751 additions and 78 deletions

View File

@ -106,7 +106,7 @@
## 饲养管理 ## 饲养管理
--- ---
需要后端创建一个表,为了节省时间不需要设置外键什么的,参考如下 需要后端创建一个饲养计划表,为了节省时间不需要设置外键什么的,参考如下
``` ```
breedingPlan: { breedingPlan: {
id: '',//int 饲养计划id id: '',//int 饲养计划id
@ -146,9 +146,9 @@ breedingPlan: {
## 档案管理 ## 档案管理
--- ---
需要后端创建一个档案表,参考属性如下 需要后端创建一个档案记录表,参考属性如下
``` ```
let archive:{ archive:{
id: 1,//int 档案号 id: 1,//int 档案号
animalId: 1,//int 该档案记录的动物id animalId: 1,//int 该档案记录的动物id
animalName: 'animal1',//字符 该档案记录的动物名称 animalName: 'animal1',//字符 该档案记录的动物名称
@ -184,6 +184,42 @@ let archive:{
## 健康检测 ## 健康检测
--- ---
需要后端创建一个健康检测记录表,参考属性如下
```
health: {
id: 1,//int 健康检测数据号
animalId: 1,//int 记录的动物id
animalName: 'animal',//字符 记录的动物名称
state: 0,//int 动物状态 0正常1异常
temperature:36.5,//double 体温
breathRate:15,//int 呼吸频率
heartRate:72,//int 心跳频率
bloodPressure:90,//int // 血压
date: '2024-06-01',//字符 记录日期
time: '18:00:00',//字符,记录时间
description: '无异常',//字符 检测的描述,比如动物的症状
},
```
### 健康数据查询
前端提供档健康检测数据号、动物id、或者不提供
当提供健康检测数据号时,返回符合的一条档案
当提供动物id时返回符合动物id的多条健康检测数据
当不提供时,返回所有健康检测数据
### 健康数据删除
前端提供健康检测数据号,后端删除并返回结果
### 健康数据添加
前端提供健康检测数据对象,后端进行添加
### 健康数据修改
前端提供健康检测数据对象,后端进行修改
## 统计分析 ## 统计分析
--- ---

View File

@ -63,10 +63,10 @@ export default {
<el-input v-model="form.species" placeholder="动物种类" :disabled="detail"/> <el-input v-model="form.species" placeholder="动物种类" :disabled="detail"/>
</el-form-item> </el-form-item>
<el-form-item label="动物体重KG"> <el-form-item label="动物体重KG">
<el-input-number v-model="form.weight" :precision="2" :step="0.1" :min="0" :disabled="detail"/> <el-input-number v-model.number="form.weight" :precision="2" :step="0.1" :min="0" :disabled="detail"/>
</el-form-item> </el-form-item>
<el-form-item label="动物身高M"> <el-form-item label="动物身高M">
<el-input-number v-model="form.height" :precision="2" :step="0.1" :min="0" :disabled="detail"/> <el-input-number v-model.number="form.height" :precision="2" :step="0.1" :min="0" :disabled="detail"/>
</el-form-item> </el-form-item>
<el-form-item label="动物状态"> <el-form-item label="动物状态">
<el-radio-group v-model="form.state" :disabled="detail"> <el-radio-group v-model="form.state" :disabled="detail">

View File

@ -46,8 +46,8 @@ export default {
<template> <template>
<el-form label-width="auto"> <el-form label-width="auto">
<el-form-item label="档案号"> <el-form-item label="生命周期记录号">
<el-input v-model.number="form.id" type="number" placeholder="记录号" :disabled="edit || detail"/> <el-input v-model.number="form.id" type="number" placeholder="生命周期记录号" :disabled="edit || detail"/>
</el-form-item> </el-form-item>
<el-form-item label="记录的动物ID"> <el-form-item label="记录的动物ID">
<el-input v-model.number="form.animalId" type="number" placeholder="记录的动物ID" :disabled="detail"/> <el-input v-model.number="form.animalId" type="number" placeholder="记录的动物ID" :disabled="detail"/>

View File

@ -106,8 +106,8 @@ export default {
<template #label> <template #label>
状态 状态
</template> </template>
<span v-if="a.state===0" style="color: green">正常</span> <span v-if="a.state===0" style="color: #67C23A">正常</span>
<span v-else-if="a.state===1" style="color: red">异常</span> <span v-else-if="a.state===1" style="color: #F56C6C">异常</span>
<span v-else>未知</span> <span v-else>未知</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item> <el-descriptions-item>

View File

@ -67,7 +67,7 @@ export default {
<span>兽医</span> <span>兽医</span>
</template> </template>
<el-menu-item index="/panel/archive" @click="toPath('/panel/archive')">动物档案</el-menu-item> <el-menu-item index="/panel/archive" @click="toPath('/panel/archive')">动物档案</el-menu-item>
<el-menu-item index="3-2">健康检测</el-menu-item> <el-menu-item index="/panel/health" @click="toPath('/panel/health')">健康检测</el-menu-item>
</el-sub-menu> </el-sub-menu>
</el-menu> </el-menu>
</el-col> </el-col>

View File

@ -1,11 +1,106 @@
<script> <script>
import {copy} from "@/utils/common.js";
export default { export default {
name: "ZooHealthFormDialog" name: "ZooHealthFormDialog",
data() {
return {
form: {
id: null,//int
animalId: null,//int id
animalName: '',//
state: 0,//int 01
temperature:0,//double
breathRate:0,//int
heartRate:0,//int
bloodPressure:0,//int //
date: '',//
time: '',//
description: '',//
},
}
},
props: {
data: {
type: Object,
},
detail: {
type: Boolean,
default: false
},
edit: {
type: Boolean,
default: false
}
},
mounted() {
//
if (this.data) {
this.form = copy(this.data)
}
},
beforeUnmount() {
console.log('ZooHealthFormDialog-beforeUnmount', this);
}
} }
</script> </script>
<template> <template>
<el-form label-width="auto">
<el-form-item label="健康监测记录号">
<el-input v-model.number="form.id" type="number" placeholder="健康监测记录号" :disabled="edit || detail"/>
</el-form-item>
<el-form-item label="记录的动物ID">
<el-input v-model.number="form.animalId" type="number" placeholder="记录的动物ID" :disabled="detail"/>
</el-form-item>
<el-form-item label="记录的动物名">
<el-input v-model="form.animalName" placeholder="记录的动物名" :disabled="detail"/>
</el-form-item>
<el-form-item label="动物体温°C">
<el-input-number v-model.number="form.temperature" :precision="1" :step="0.1" :min="0" :disabled="detail"/>
</el-form-item>
<el-form-item label="呼吸频率(次/分钟)">
<el-input-number v-model.number="form.breathRate" :min="0" :disabled="detail"/>
</el-form-item>
<el-form-item label="心跳频率(次/分钟)">
<el-input-number v-model.number="form.heartRate" :min="0" :disabled="detail"/>
</el-form-item>
<el-form-item label="动物血压mmHg">
<el-input-number v-model.number="form.bloodPressure" :min="0" :disabled="detail"/>
</el-form-item>
<el-form-item label="动物状态">
<el-radio-group v-model="form.state" :disabled="detail">
<el-radio :value="0">正常</el-radio>
<el-radio :value="1">异常</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="记录日期">
<el-date-picker
v-model="form.date"
type="date"
placeholder="选择日期"
value-format="YYYY-MM-DD"
:disabled="detail"
/>
</el-form-item>
<el-form-item label="记录时间">
<el-time-picker v-model="form.time" type="time" placeholder="选择时间" value-format="HH:mm:ss"
:disabled="detail"/>
</el-form-item>
<el-form-item label="记录描述">
<el-input
v-model="form.description"
:rows="4"
type="textarea"
placeholder="记录描述"
resize="none"
:disabled="detail"
/>
</el-form-item>
<div class="right">
<slot :form="form"></slot>
</div>
</el-form>
</template> </template>
<style scoped> <style scoped>

View File

@ -118,6 +118,7 @@ export default {
// //
this.getAnimals() this.getAnimals()
this.search()
// //
this.dialog.editDialogVisible = false this.dialog.editDialogVisible = false
@ -139,6 +140,7 @@ export default {
// //
this.getAnimals() this.getAnimals()
this.search()
// //
ElMessage({ ElMessage({
@ -177,12 +179,14 @@ export default {
} }
// //
this.getAnimals() this.getAnimals()
this.search()
this.dialog.addDialogVisible = false// this.dialog.addDialogVisible = false//
}, },
//线 //线
showArchives(data) { showTimeline(data) {
console.log('显示档案', data) console.log('显示时间线记录', data)
// //
// //
@ -193,7 +197,7 @@ export default {
// //
this.archives.forEach(e=>{ this.archives.forEach(e=>{
if (e.animalId === data.id) { if (e.animalId === data.id) {
this.dialog.timelineData.push(e) this.dialog.timelineData.push(copy(e))
} }
}) })
@ -272,7 +276,7 @@ export default {
</script> </script>
<template> <template>
<div class="animals-root"> <div class="animal-root">
<div class="select"> <div class="select">
<div class="left"> <div class="left">
<el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加动物</el-button> <el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加动物</el-button>
@ -308,8 +312,8 @@ export default {
<el-table-column prop="height" label="动物身高M" width="130"/> <el-table-column prop="height" label="动物身高M" width="130"/>
<el-table-column prop="state" label="动物状态" width="90"> <el-table-column prop="state" label="动物状态" width="90">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.state===0" style="color: green">正常</span> <span v-if="scope.row.state===0" style="color: #67C23A">正常</span>
<span v-else-if="scope.row.state===1" style="color: red">异常</span> <span v-else-if="scope.row.state===1" style="color: #F56C6C">异常</span>
<span v-else>未知</span> <span v-else>未知</span>
</template> </template>
</el-table-column> </el-table-column>
@ -317,14 +321,14 @@ export default {
<el-table-column prop="roleId" label="饲养员ID" width="120"/> <el-table-column prop="roleId" label="饲养员ID" width="120"/>
<el-table-column prop="color" label="动物颜色" width="150"> <el-table-column prop="color" label="动物颜色" width="150">
<template #default="scope"> <template #default="scope">
{{ scope.row.color }}
<el-color-picker v-model="scope.row.color" disabled/> <el-color-picker v-model="scope.row.color" disabled/>
{{ scope.row.color }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="features" label="动物特征" width="200"/> <el-table-column prop="features" label="动物特征" width="200"/>
<el-table-column fixed="right" label="操作" width="250"> <el-table-column fixed="right" label="操作" width="250">
<template #default="scope"> <template #default="scope">
<el-button link type="success" size="small" :icon="Tickets" @click="showArchives(scope.row)"> <el-button link type="success" size="small" :icon="Tickets" @click="showTimeline(scope.row)">
档案 档案
</el-button> </el-button>
<el-button link type="primary" size="small" :icon="Document" @click="showDetail(scope.row)"> <el-button link type="primary" size="small" :icon="Document" @click="showDetail(scope.row)">

View File

@ -70,7 +70,6 @@ export default {
} }
}, },
methods: { methods: {
sortByDateTime,
...mapActions(["getArchives"]), ...mapActions(["getArchives"]),
...mapMutations(['updateArchivesTableData']), ...mapMutations(['updateArchivesTableData']),
@ -123,6 +122,7 @@ export default {
// //
this.getArchives() this.getArchives()
this.search()
// //
this.dialog.editDialogVisible = false this.dialog.editDialogVisible = false
@ -144,6 +144,7 @@ export default {
// //
this.getArchives() this.getArchives()
this.search()
// //
ElMessage({ ElMessage({
@ -182,12 +183,14 @@ export default {
} }
// //
this.getArchives() this.getArchives()
this.search()
this.dialog.addDialogVisible = false// this.dialog.addDialogVisible = false//
}, },
//线 //线
showArchives(data) { showTimeline(data) {
console.log('显示档案', data) console.log('显示时间线记录', data)
// //
// //
@ -198,7 +201,7 @@ export default {
// //
this.archives.forEach(e=>{ this.archives.forEach(e=>{
if (e.animalId === data.animalId) { if (e.animalId === data.animalId) {
this.dialog.timelineData.push(e) this.dialog.timelineData.push(copy(e))
} }
}) })
@ -298,7 +301,7 @@ export default {
</script> </script>
<template> <template>
<div class="animals-root"> <div class="archive-root">
<div class="select"> <div class="select">
<div class="left"> <div class="left">
<el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加记录</el-button> <el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加记录</el-button>
@ -326,14 +329,14 @@ export default {
<div class="table"> <div class="table">
<el-table :data="pagesData" style="width: 100%;height: 100%" border stripe :row-style="{height: '40px'}" :cell-style="{padding:'0'}"> <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="100"/> <el-table-column fixed prop="id" label="生命周期记录号" width="100"/>
<el-table-column fixed prop="animalId" label="记录的动物ID" width="120"/> <el-table-column fixed prop="animalId" label="记录的动物ID" width="120"/>
<el-table-column prop="animalName" label="记录的动物名" width="110"/> <el-table-column prop="animalName" label="记录的动物名" width="110"/>
<el-table-column prop="phase" label="生命阶段" width="90"/> <el-table-column prop="phase" label="生命阶段" width="90"/>
<el-table-column prop="state" label="动物状态" width="90"> <el-table-column prop="state" label="动物状态" width="90">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.state===0" style="color: green">正常</span> <span v-if="scope.row.state===0" style="color: #67C23A">正常</span>
<span v-else-if="scope.row.state===1" style="color: red">异常</span> <span v-else-if="scope.row.state===1" style="color: #F56C6C">异常</span>
<span v-else>未知</span> <span v-else>未知</span>
</template> </template>
</el-table-column> </el-table-column>
@ -344,7 +347,7 @@ export default {
<el-table-column prop="description" label="记录描述" width="300"/> <el-table-column prop="description" label="记录描述" width="300"/>
<el-table-column fixed="right" label="操作" width="250"> <el-table-column fixed="right" label="操作" width="250">
<template #default="scope"> <template #default="scope">
<el-button link type="success" size="small" :icon="Tickets" @click="showArchives(scope.row)"> <el-button link type="success" size="small" :icon="Tickets" @click="showTimeline(scope.row)">
档案 档案
</el-button> </el-button>
<el-button link type="primary" size="small" :icon="Document" @click="showDetail(scope.row)"> <el-button link type="primary" size="small" :icon="Document" @click="showDetail(scope.row)">
@ -412,7 +415,7 @@ export default {
</el-dialog> </el-dialog>
<!--查看动物所有记录--> <!--查看动物所有记录-->
<el-dialog v-model="dialog.timelineDialogVisible" :title="'动物档案:'+dialog.dialogData.animalId" width="600" align-center draggable overflow <el-dialog v-model="dialog.timelineDialogVisible" :title="'生命周期档案:'+dialog.dialogData.animalId" width="600" align-center draggable overflow
destroy-on-close> destroy-on-close>
<ZooArchiveTimeline :data="dialog.timelineData"> <ZooArchiveTimeline :data="dialog.timelineData">
<template #operate="scope"> <template #operate="scope">

View File

@ -112,6 +112,7 @@ export default {
// //
this.getBreedingPlans() this.getBreedingPlans()
this.search()
// //
this.dialog.editDialogVisible = false this.dialog.editDialogVisible = false
@ -133,6 +134,7 @@ export default {
// //
this.getBreedingPlans() this.getBreedingPlans()
this.search()
// //
ElMessage({ ElMessage({
@ -171,6 +173,8 @@ export default {
} }
// //
this.getBreedingPlans() this.getBreedingPlans()
this.search()
this.dialog.addDialogVisible = false// this.dialog.addDialogVisible = false//
}, },
@ -246,7 +250,7 @@ export default {
</script> </script>
<template> <template>
<div class="animals-root"> <div class="breeding-root">
<div class="select"> <div class="select">
<div class="left"> <div class="left">
<el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加饲养计划</el-button> <el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加饲养计划</el-button>
@ -281,8 +285,8 @@ export default {
<el-table-column prop="phase" label="生命阶段" width="90"/> <el-table-column prop="phase" label="生命阶段" width="90"/>
<el-table-column prop="state" label="动物状态" width="90"> <el-table-column prop="state" label="动物状态" width="90">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.state===0" style="color: green">正常</span> <span v-if="scope.row.state===0" style="color: #67C23A">正常</span>
<span v-else-if="scope.row.state===1" style="color: red">异常</span> <span v-else-if="scope.row.state===1" style="color: #F56C6C">异常</span>
<span v-else>未知</span> <span v-else>未知</span>
</template> </template>
</el-table-column> </el-table-column>

View File

@ -1,11 +1,456 @@
<script> <script>
import {Delete, DocumentAdd, Document, Edit, Search, Tickets, Timer} from "@element-plus/icons-vue";
import {mapActions,mapMutations,mapState} from "vuex";
import {copy, fuzzyMatching, sortByDateTime, splitKeyWords} from "@/utils/common.js";
import ZooHealthFormDialog from "@/components/ZooHealthFormDialog.vue";
import ZooHealthTimeline from "@/components/ZooHealthTimeline.vue";
export default { export default {
name: "ZooHealth" name: "ZooHealth",
components: {ZooHealthTimeline, ZooHealthFormDialog},
data() {
return {
//
pagesData: [],
pageSize: 20,//
currentPage: 1,//
order:1,//
//
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'])
},
watch: {
//
searchInput: {
deep: true,
handler(val) {
this.search();
}
}
},
methods: {
...mapActions(["getHealths"]),
...mapMutations(['updateHealthsTableData']),
//
showDetail(data) {
console.log('显示详情', data)
//
//
this.dialog.dialogData = this.healths.find(e => e.id === data.id)
//
this.dialog.detailDialogVisible = true
},
//
showEdit(data) {
console.log('显示编辑', data)
//
//
this.dialog.dialogData = this.healths.find(e => e.id === data.id)
//
this.dialog.editDialogVisible = true
},
edit(data) {
console.log('编辑', data)
//
return this.isEmpty(data);
//
//
if (false) {
return ElMessage({
message: '编辑失败',
type: 'warning',
})
}
//
if (false) {
return ElMessage({
message: '编辑成功',
type: 'success',
})
}
//
this.getHealths()
this.search()
//
this.dialog.editDialogVisible = false
},
delete_(data) {
console.log('删除', data)
return ElMessageBox.confirm(
'该操作不可撤销,是否继续?',
'删除健康检测记录:' +data.id,
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
//
//
this.getHealths()
this.search()
//
ElMessage({
type: 'success',
message: '删除成功',
})
}).catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
},
add(data) {
console.log('添加', data)
//
return this.isEmpty(data);
//
//
if (false) {
return ElMessage({
message: '该记录已存在',
type: 'warning',
})
}
//
if (false) {
return ElMessage({
message: '添加成功',
type: 'success',
})
}
//
this.getHealths()
this.search()
this.dialog.addDialogVisible = false//
},
//线
showTimeline(data) {
console.log('显示时间线记录', data)
//
//
this.dialog.dialogData = this.healths.find(e => e.id === data.id)
this.dialog.timelineData = []
//
//
this.healths.forEach(e=>{
if (e.animalId === data.animalId) {
this.dialog.timelineData.push(copy(e))
}
})
//
this.dialog.timelineDialogVisible = true
},
//
isEmpty(form) {
if (!form.animalId) {
//
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(){
//
if (this.order===0){
this.order++
this.updateHealthsTableData(sortByDateTime(copy(this.healthsTableData)))
this.getPagesData()
return
}
//
if (this.order===1){
this.order--
this.updateHealthsTableData(sortByDateTime(copy(this.healthsTableData)).reverse())
this.getPagesData()
}
},
//
//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
},
mounted() {
//
this.getHealths()
//
this.getPagesData()
console.log()
},
} }
</script> </script>
<template> <template>
<div class="health-root">
<div class="select">
<div class="left">
<el-button type="primary" :icon="DocumentAdd" @click="dialog.addDialogVisible = true">添加记录</el-button>
</div>
<div class="right">
<el-button type="primary" :icon="Timer" @click="timeSort" 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="search()"/>
</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="100"/>
<el-table-column fixed prop="animalId" label="记录的动物ID" width="120"/>
<el-table-column prop="animalName" label="记录的动物名" width="110"/>
<el-table-column prop="temperature" label="体温°C" width="110">
<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="110">
<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="110">
<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="110">
<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="250">
<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)">
编辑
</el-button>
<el-button link type="danger" size="small" :icon="Delete" @click="delete_(scope.row)">
删除
</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>
<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.archive)">编辑</el-button>-->
<!-- <el-button type="danger" link @click="delete_(scope.archive)">删除</el-button>-->
<!-- </template>-->
<!-- <template #footer>-->
<!-- <el-button @click="dialog.timelineDialogVisible = false">-->
<!-- 关闭-->
<!-- </el-button>-->
<!-- </template>-->
<!-- </ZooHealthTimeline>-->
<!-- </el-dialog>-->
</template> </template>
<style scoped> <style scoped>

View File

@ -116,6 +116,7 @@ export default {
// //
this.getUsers() this.getUsers()
this.search()
// //
this.dialog.editDialogVisible = false this.dialog.editDialogVisible = false
@ -137,6 +138,7 @@ export default {
// //
this.getUsers() this.getUsers()
this.search()
// //
ElMessage({ ElMessage({
@ -176,6 +178,8 @@ export default {
// //
this.getUsers() this.getUsers()
this.search()
this.dialog.addDialogVisible = false// this.dialog.addDialogVisible = false//
}, },
@ -250,7 +254,7 @@ export default {
</script> </script>
<template> <template>
<div id="users-root"> <div id="user-root">
<!-- 头部--> <!-- 头部-->
<div class="select"> <div class="select">
<div class="left"> <div class="left">
@ -289,9 +293,9 @@ export default {
</el-table-column> </el-table-column>
<el-table-column prop="auth" label="身份" width="700"> <el-table-column prop="auth" label="身份" width="700">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.auth===0" style="color: blue">管理员</span> <span v-if="scope.row.auth===0" style="color: #409EFF">管理员</span>
<span v-else-if="scope.row.auth===1" style="color: green">饲养员</span> <span v-else-if="scope.row.auth===1" style="color: #67C23A">饲养员</span>
<span v-else-if="scope.row.auth===2" style="color: orange">兽医</span> <span v-else-if="scope.row.auth===2" style="color: #E6A23C">兽医</span>
<span v-else>未知</span> <span v-else>未知</span>
</template> </template>
</el-table-column> </el-table-column>

View File

@ -1,11 +1,17 @@
<script> <script>
import {mapMutations} from "vuex"; import {mapMutations} from "vuex";
import {generateAnimals, generateArchives, generateBreedingPlans, generateUsers} from "@/utils/common.js"; import {
generateAnimals,
generateArchives,
generateBreedingPlans,
generateHealths,
generateUsers
} from "@/utils/common.js";
export default { export default {
name: "ZooData", name: "ZooData",
methods: { methods: {
...mapMutations(['updateUsers', 'updateAnimals', 'updateBreedingPlans', 'updateArchives']), ...mapMutations(['updateUsers', 'updateAnimals', 'updateBreedingPlans', 'updateArchives','updateHealths']),
usersData() { usersData() {
this.updateUsers(generateUsers()) this.updateUsers(generateUsers())
return ElMessage({ return ElMessage({
@ -33,6 +39,13 @@ export default {
message: '成功', message: '成功',
type: 'success', type: 'success',
}) })
},
healthData() {
this.updateHealths(generateHealths())
return ElMessage({
message: '成功',
type: 'success',
})
} }
} }
} }
@ -43,6 +56,7 @@ export default {
<el-button type="primary" @click="animalsData">生成动物信息</el-button> <el-button type="primary" @click="animalsData">生成动物信息</el-button>
<el-button type="primary" @click="breedingPlansData">生成饲养计划信息</el-button> <el-button type="primary" @click="breedingPlansData">生成饲养计划信息</el-button>
<el-button type="primary" @click="archiveData">生成档案信息</el-button> <el-button type="primary" @click="archiveData">生成档案信息</el-button>
<el-button type="primary" @click="healthData">生成健康监测信息</el-button>
<el-button type="primary" @click="$router.push('/login')">跳转登录</el-button> <el-button type="primary" @click="$router.push('/login')">跳转登录</el-button>
</template> </template>

View File

@ -10,6 +10,7 @@ import store from "@/store/index.js";
import ZooBreeding from "@/pages/ZooBreeding.vue"; import ZooBreeding from "@/pages/ZooBreeding.vue";
import ZooArchive from "@/pages/ZooArchive.vue"; import ZooArchive from "@/pages/ZooArchive.vue";
import ZooData from "@/pages/data.vue"; import ZooData from "@/pages/data.vue";
import ZooHealth from "@/pages/ZooHealth.vue";
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(), history: createWebHashHistory(),
@ -55,6 +56,10 @@ const router = createRouter({
{ {
path:'archive', path:'archive',
component:ZooArchive, component:ZooArchive,
},
{
path:'health',
component:ZooHealth,
} }
] ]
}, },

View File

@ -38,6 +38,13 @@ const actions = {
// 通过后端获取数据 // 通过后端获取数据
// context.commit('updateArchives', generateArchives()) // context.commit('updateArchives', generateArchives())
context.commit('updateArchives',context.state.archives); context.commit('updateArchives',context.state.archives);
},
//获取监控检测数据
getHealths(context) {
// 通过后端获取数据
// context.commit('updateHealths', generateHealths())
context.commit('updateHealths',context.state.healths);
} }
} }
@ -88,6 +95,17 @@ const mutations = {
}, },
updateArchivesTableData(state, value) { updateArchivesTableData(state, value) {
state.archivesTableData = value state.archivesTableData = value
},
//更新健康检测
updateHealths(state, value) {
state.healths = value
//复制一份给前端表格展示,不轻易修改源数据
state.healthsTableData = copy(state.healths)
},
updateHealthsTableData(state, value) {
state.healthsTableData = value
} }
} }
@ -118,6 +136,9 @@ const state = {
//动物档案 //动物档案
archives:[], archives:[],
archivesTableData:[],//动物档案表格数据 archivesTableData:[],//动物档案表格数据
//健康检测
healths:[],
healthsTableData:[],//健康检测表格数据
} }
export default createStore({ export default createStore({

View File

@ -15,14 +15,13 @@ export function generateUsers() {
auth: a, auth: a,
} }
users.push(user) users.push(user)
if (a===1) { if (a === 1) {
keeper.push(user) keeper.push(user)
} } else if (a === 2) {
else if (a===2) {
veterinary.push(user) veterinary.push(user)
} }
} }
console.log('用户',users,keeper,veterinary) console.log('用户', users, keeper, veterinary)
return users return users
} }
@ -50,18 +49,18 @@ export function generateAnimals() {
id: i, id: i,
name: 'animal' + (i + 1), name: 'animal' + (i + 1),
sex: Math.floor(Math.random() * 2) === 0 ? '雌性' : '雄性', sex: Math.floor(Math.random() * 2) === 0 ? '雌性' : '雄性',
species: '种类'+Math.ceil(Math.random() * 20).toString(),//种类 species: '种类' + Math.ceil(Math.random() * 20).toString(),//种类
weight: Number((Math.random() * 2000).toFixed(2)), weight: Number((Math.random() * 2000).toFixed(2)),
height: Number((Math.random() * 10).toFixed(2)), height: Number((Math.random() * 10).toFixed(2)),
state: generateState(),//状态0正常 1异常 state: generateState(),//状态0正常 1异常
roleId: generateKeeperId(),//饲养员id roleId: generateKeeperId(),//饲养员id
color: generateNewColor(),//颜色 color: generateNewColor(),//颜色
features: 'test animal' + (i + 1)+' features',//特征 features: 'test animal' + (i + 1) + ' features',//特征
phase: generatePhase() phase: generatePhase()
} }
animals.push(animal) animals.push(animal)
} }
console.log('动物',animals) console.log('动物', animals)
return animals return animals
} }
@ -84,6 +83,7 @@ function generateKeeperId() {
const n = Math.floor(Math.random() * keeper.length); const n = Math.floor(Math.random() * keeper.length);
return keeper[n].id return keeper[n].id
} }
//endregion //endregion
//生成已有的兽医id //生成已有的兽医id
@ -94,24 +94,27 @@ function generateVeterinaryId() {
const n = Math.floor(Math.random() * veterinary.length); const n = Math.floor(Math.random() * veterinary.length);
return veterinary[n].id return veterinary[n].id
} }
//endregion //endregion
//生成颜色 //生成颜色
//region //region
const hexCharacters = [0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F"] const hexCharacters = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"]
function getCharacter(index) { function getCharacter(index) {
return hexCharacters[index] return hexCharacters[index]
} }
function generateNewColor() { function generateNewColor() {
let hexColorRep = "#" let hexColorRep = "#"
for (let index = 0; index < 6; index++){ for (let index = 0; index < 6; index++) {
const randomPosition = Math.floor ( Math.random() * hexCharacters.length ) const randomPosition = Math.floor(Math.random() * hexCharacters.length)
hexColorRep += getCharacter( randomPosition ) hexColorRep += getCharacter(randomPosition)
} }
return hexColorRep return hexColorRep
} }
//endregion //endregion
// id: '',//int 饲养计划id // id: '',//int 饲养计划id
@ -130,40 +133,40 @@ export function generateBreedingPlans() {
const n = 20; const n = 20;
for (let i = 0; i < n; i++) { for (let i = 0; i < n; i++) {
//分别生成2种性别的 //分别生成2种性别的
for (let j = 0; j<2;j++){ for (let j = 0; j < 2; j++) {
//分别生成4种生命阶段的 //分别生成4种生命阶段的
for (let k=0; k<4;k++){ for (let k = 0; k < 4; k++) {
//分别生成2种状态的 //分别生成2种状态的
for (let l=0; l<2;l++){ for (let l = 0; l < 2; l++) {
let breedingPlan = { let breedingPlan = {
id: i+''+j+''+k+''+l, id: i + '' + j + '' + k + '' + l,
name: 'breeding' + (i + 1), name: 'breeding' + (i + 1),
species: '种类'+i.toString(), species: '种类' + i.toString(),
sex: j === 0 ? '雌性' : '雄性', sex: j === 0 ? '雌性' : '雄性',
phase: k===0?'幼年期':k===1?'成长期':k===2?'成年期':'老年期', phase: k === 0 ? '幼年期' : k === 1 ? '成长期' : k === 2 ? '成年期' : '老年期',
state: l, state: l,
roleId: generateKeeperId(), roleId: generateKeeperId(),
description: 'test breeding'+i+''+j+''+k+''+l+' description', description: 'test breeding' + i + '' + j + '' + k + '' + l + ' description',
} }
breedingPlans.push(breedingPlan) breedingPlans.push(breedingPlan)
} }
} }
} }
} }
console.log('饲养计划',breedingPlans) console.log('饲养计划', breedingPlans)
return breedingPlans return breedingPlans
} }
//生成动物生命阶段1幼年2成长6成年1老年 //生成动物生命阶段1幼年2成长6成年1老年
function generatePhase() { function generatePhase() {
const phase = Math.floor(Math.random() * 100) const phase = Math.floor(Math.random() * 100)
if (phase <10) if (phase < 10)
return '幼年期' return '幼年期'
if (phase <30) if (phase < 30)
return '成长期' return '成长期'
if (phase <90) if (phase < 90)
return '成年期' return '成年期'
if (phase <100) if (phase < 100)
return '老年期' return '老年期'
} }
@ -171,45 +174,84 @@ function generatePhase() {
export function generateArchives() { export function generateArchives() {
const archives = [] const archives = []
let aid=0
store.state.animals.forEach(e => { store.state.animals.forEach(e => {
//分为四个周期的档案 //分为四个周期的档案
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
let n; let n;
if (i===0){ if (i === 0) {
//幼年期5-10条档案 //幼年期5-10条档案
n = Math.floor(Math.random() * 5)+5 n = Math.floor(Math.random() * 5) + 5
}else if (i===1){ } else if (i === 1) {
//成长期10-20条档案 //成长期10-20条档案
n = Math.floor(Math.random() * 10)+10 n = Math.floor(Math.random() * 10) + 10
}else if (i===2){ } else if (i === 2) {
//成年期30-60条档案 //成年期30-60条档案
n = Math.floor(Math.random() * 30)+30 n = Math.floor(Math.random() * 30) + 30
}else{ } else {
//老年期5-10条档案 //老年期5-10条档案
n = Math.floor(Math.random() * 5)+5 n = Math.floor(Math.random() * 5) + 5
} }
for (let j = 0; j<n;j++) { for (let j = 0; j < n; j++) {
let archive = { let archive = {
id: i+''+j,//档案号 id: aid,//档案号
animalId: e.id,//该档案记录的动物id animalId: e.id,//该档案记录的动物id
animalName: e.name,//该档案记录的动物名称 animalName: e.name,//该档案记录的动物名称
phase: i===0?'幼年期':i===1?'成长期':i===2?'成年期':'老年期', phase: i === 0 ? '幼年期' : i === 1 ? '成长期' : i === 2 ? '成年期' : '老年期',
state: generateState(), state: generateState(),
type: generateType(), type: generateType(),
date: '202'+i+'-' + Math.ceil(Math.random() * 11).toString().padStart(2, '0') + '-' + Math.ceil(Math.random() * 30).toString().padStart(2, '0'),//字符 档案记录日期 date: '202' + i + '-' + Math.ceil(Math.random() * 11).toString().padStart(2, '0') + '-' + Math.ceil(Math.random() * 30).toString().padStart(2, '0'),//字符 档案记录日期
time: Math.floor(Math.random() * 24).toString().padStart(2, '0') + ':' + Math.floor(Math.random() * 60).toString().padStart(2, '0') + ':' + Math.floor(Math.random() * 60).toString().padStart(2, '0'),//记录时间 time: Math.floor(Math.random() * 24).toString().padStart(2, '0') + ':' + Math.floor(Math.random() * 60).toString().padStart(2, '0') + ':' + Math.floor(Math.random() * 60).toString().padStart(2, '0'),//记录时间
roleId: generateVeterinaryId(),//负责录入档案的人的id身份不限 roleId: generateVeterinaryId(),//负责录入档案的人的id身份不限
description: 'test archive'+i+''+j+' description', description: 'test archive' + i + '' + j + ' description',
} }
archives.push(archive) archives.push(archive)
//同时获取一条健康记录
let health = {
id: aid,//int 健康检测数据号
animalId: archive.animalId,//int 记录的动物id
animalName: archive.animalName,//字符 记录的动物名称
state: archive.state,//int 动物状态 0正常1异常
temperature: Number((35 + Math.random() * 7).toFixed(1)),//double 体温
breathRate: Math.floor(Math.random() * 90) + 10 ,//int 呼吸频率
heartRate: Math.floor(Math.random() * 130) + 10,//int 心跳频率
bloodPressure: Math.floor(Math.random() * 110) + 70,//int // 血压
date: archive.date,//字符 记录日期
time: archive.time,//字符,记录时间
description: 'test health' + i + '' + j + ' description',//字符 检测的描述,比如动物的症状
} }
//异常的记录要修改一下监测数据
if (health.state===1){
health.temperature += Math.random()*2>1?
Number((Math.random()*health.temperature).toFixed(1)):
-Number((Math.random()*health.temperature).toFixed(1))
health.temperature = Number(health.temperature.toFixed(1))
health.breathRate += Math.random()*2>1?
Math.floor(Math.random()*health.breathRate):-Math.floor(Math.random()*health.breathRate)
health.heartRate += health.heartRate += Math.random()*2>1?
Math.floor(Math.random()*health.heartRate):-Math.floor(Math.random()*health.heartRate)
health.bloodPressure += health.bloodPressure += Math.random()*2>1?
Math.floor(Math.random()*health.bloodPressure):-Math.floor(Math.random()*health.bloodPressure)
} }
healths.push(health)
aid++
}
}
}) })
console.log('档案',archives) console.log('档案', archives)
return archives return archives
} }
const healths = []
export function generateHealths() {
console.log('健康记录', healths)
return healths
}
function generateType() { function generateType() {
//疫苗接种1疾病治疗1日常饲养8 //疫苗接种1疾病治疗1日常饲养8
const type = Math.floor(Math.random() * 100) const type = Math.floor(Math.random() * 100)