2021-11-16日完成任务:中医体质辨识设计与实现
大致流程说明(以后会适当修改):会员进行预约过后,当天前往医院体检时,会被附带填一个中医体质测评,在体检完成后,同时将测评交给健康管理师,健康管理师将体检单进行上传,同时通过查看中医测评报告,分析中医测评报告,在后台将该会员的中医测评结果进行编辑保存,最后再将体检信息与中医测评报告进行总结,并在会员的评估页面,更新评估结果,如果之后有其他健康管理师发现有其他不一样的内容的话,可以进行修改评估结果,
大致流程说明(以后会适当修改):
会员进行预约过后,当天前往医院体检时,会被附带填一个中医体质测评,在体检完成后,同时将测评交给健康管理师,健康管理师将体检单进行上传,同时通过查看中医测评报告,分析中医测评报告,在后台将该会员的中医测评结果进行编辑保存,最后再将体检信息与中医测评报告进行总结,并在会员的评估页面,更新评估结果,如果之后有其他健康管理师发现有其他不一样的内容的话,可以进行修改评估结果,但是评估时间将会变为最新修改时的日期,如下:
中医体质辨识
前期准备
新建数据表
新建poji实体类
import java.io.Serializable;
import java.sql.Date;
/**
* 健康评估专用pojo实体类
* @author Marston
* @date 2021/11/14
*/
public class Assess implements Serializable {
private Integer id;//主键id
private Integer memberId;//会员id
private String fileNumber;//档案号
private String name;//会员姓名
private Date assessDate;//评估日期
private String calmQuality;//平和质
private String qiDeficiencyQuality;//气虚质
private String YangDeficiencyQuality;//阳虚质
private String YinDeficiencyQuality;//阴虚质
private String phlegmDampnessQuality;//痰湿质
private String dampHeatQuality;//湿热质
private String bloodStasisQuality;//血瘀质
private String qiStagnationQuality;//气郁质
private String specialIntrinsicQuality;//特禀质
页面显示
前台页面
all-medical-list.html
<el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row>
<el-table-column type="index" align="center" label="序号"></el-table-column>
<el-table-column prop="fileNumber" label="档案号" align="center"></el-table-column>
<el-table-column prop="name" label="姓名" align="center"></el-table-column>
<el-table-column prop="assessDate" label="评估日期" align="center"></el-table-column>
<el-table-column prop="calmQuality" label="平和质" align="center"></el-table-column>
<el-table-column prop="qiDeficiencyQuality" label="气虚质" align="center"></el-table-column>
<el-table-column prop="YangDeficiencyQuality" label="阳虚质" align="center"></el-table-column>
<el-table-column prop="YinDeficiencyQuality" label="阴虚质" align="center"></el-table-column>
<el-table-column prop="phlegmDampnessQuality" label="痰湿质" align="center"></el-table-column>
<el-table-column prop="dampHeatQuality" label="湿热质" align="center"></el-table-column>
<el-table-column prop="bloodStasisQuality" label="血瘀质" align="center"></el-table-column>
<el-table-column prop="qiStagnationQuality" label="气郁质" align="center"></el-table-column>
<el-table-column prop="specialIntrinsicQuality " label="特禀质" align="center"></el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<!-- 通过scop.row拿取当前这条列的数据,对应与这条列的json对象-->
<a type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</a>
<a size="mini" type="danger" @click="handleDelete(scope.row)">删除</a>
</template>
</el-table-column>
</el-table>
//为查询按钮独立的设置一个查询方法,因为之前的查询会导致在不是首页查询时,查询不到所有的内容
_findPage(){
this.pagination.currentPage = 1;
this.findPage();
},
//分页查询
findPage() {
//封装请求参数数据(页码、每页显示的条数、查询条件),进行传送queryPageBean
var param = {
currentPage: this.pagination.currentPage,
pageSize: this.pagination.pageSize,
queryString: this.pagination.queryString
};
console.log(param);
//发送ajax请求,提交分页相关请求参数(页码、每页显示的条数、查询条件)
axios.post("/assess/findPage.do",param).then((res)=>{
//解析controller响应回的数据,为模型数据赋值
this.pagination.total = res.data.total;//总记录数
this.dataList = res.data.rows;//返回的数据集合
}).catch((r)=>{
this.showMessage(r);
});
},
后台页面
AssessController
//中医体质检测分页查询功能
// @PreAuthorize("hasAuthority('CHECKITEM_QUERY')")//权限校验
@RequestMapping("/findPage")//使其那个被访问到
public PageResult findPage(@RequestBody QueryPageBean queryPageBean){
PageResult pageResult = assessService.pageQuery(queryPageBean);
System.out.println(pageResult.toString());
System.out.println(queryPageBean.toString());
return pageResult;//框架会将这个对象自动转换为JSON数据,响应回页面
}
AssessService
@Override
public PageResult pageQuery(QueryPageBean queryPageBean) {
Integer currentPage = queryPageBean.getCurrentPage();//获取当前页面
Integer pageSize = queryPageBean.getPageSize();//要查询的数据,每页的记录数
String queryString = queryPageBean.getQueryString();//过滤条件/查询条件
//完成分页查询,基于mybatis框架提供的分页助手插件完成,现在不需要写sql语句(使用limit)
//现在只需要写limit前面的内容就可以了,limit之后的内容会自动追加
PageHelper.startPage(currentPage,pageSize);//不需要返回值,这个原理是使用线程实现的
//调用dao继续数据的操作
Page<OrderList> page = orderDao.selectByCondition(queryString);
int total = (int) page.getTotal();
List<OrderList> rows = page.getResult();
//查询assess表中的数据,进行分页查询
Page<Assess> assessesPage = assessDao.selectByCondition(queryString);
int assessTotal = (int) assessesPage.getTotal();
List<Assess> assessRows = assessesPage.getResult();
//如果通过查询t_assess表中,没有数据的话,证明当前表还没有将t_order表中的数据进行读写到t_assess表
//这时候就需要去进行插入操作
System.out.println("判断语句外面执行!");
System.out.println("assessTotal:"+assessTotal);
System.out.println("total:"+total);
System.out.println("assessRows的size:"+assessRows.size());
System.out.println("assessTotal==0:"+ (assessTotal==0));
System.out.println("assessTotal<total:"+(assessTotal<total));
System.out.println("assessRows == null:"+(assessRows == null));
if (assessRows == null){
for (int i = 0; i < total; i++) {
System.out.println("if判断语句最终执行!");
OrderList orderList = rows.get(i);
Integer orderId = orderList.getId();
String name = orderList.getName();
String fileNumber = orderList.getFileNumber();//获取档案号
Integer memberId = orderDao.findMemberIdByOrderId(orderId);//通过订单的id获取会员Id
// String name = memberDao.findNameByMemberId(memberId);//通过会员Id获取会员姓名
Assess assess = new Assess(memberId,fileNumber,name);
//因为页面首先需要进行回显数据,所以的话必须返回一个list集合保证页面出现这条数据
assessRows.add(assess);
//在回显的同时需要将数据进行插入数据表t_assess中
assessDao.add(assess);
}
}else if (assessRows.size()<total){
for (int i = (int) assessTotal; i<total; i++){
System.out.println("elseif判断语句最终执行!");
OrderList orderList = rows.get(i);
Integer orderId = orderList.getId();
String name = orderList.getName();
String fileNumber = orderList.getFileNumber();//获取档案号
Integer memberId = orderDao.findMemberIdByOrderId(orderId);//通过订单的id获取会员Id
// String name = memberDao.findNameByMemberId(memberId);//通过会员Id获取会员姓名
Assess assess = new Assess(memberId,fileNumber,name);
//因为页面首先需要进行回显数据,所以的话必须返回一个list集合保证页面出现这条数据
assessRows.add(assess);
//在回显的同时需要将数据进行插入数据表t_assess中
assessDao.add(assess);
}
}
System.out.println("判断语句结束执行!");
//将数据进行返回
return new PageResult((long) total,assessRows);
}
编辑功能
前台页面
all-medical-list.html
<!-- 编辑标签弹层 -->
<div class="add-form">
<el-dialog title="编辑评估信息" :visible.sync="dialogFormVisible4Edit">
<el-form ref="dataEditForm" :model="formData" label-position="right" label-width="100px">
<er-row>
<er-col :span="12">
<el-form-item label="评估日期">
<el-date-picker type="date" v-model="formData.assessDate" ></el-date-picker>
</el-form-item>
</er-col>
<er-col :span="12">
<el-form-item label="档案号:" prope="fileNumber">
{{this.formData.fileNumber}}
</el-form-item>
</er-col>
</er-row>
<el-row>
<el-col :span="12">
<el-form-item label="姓名:" prop="name">
{{this.formData.name}}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="特禀质">
<el-select v-model="formData.specialIntrinsicQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="平和质">
<el-select v-model="formData.calmQuality">
<el-option label="是" value="是"></el-option>
<el-option label="基本是" value="基本是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="气虚质">
<el-select v-model="formData.qiDeficiencyQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="阳虚质">
<el-select v-model="formData.yangDeficiencyQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="阴虚质">
<el-select v-model="formData.yinDeficiencyQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="痰湿质">
<el-select v-model="formData.phlegmDampnessQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="湿热质">
<el-select v-model="formData.dampHeatQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="血瘀质">
<el-select v-model="formData.bloodStasisQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="气郁质">
<el-select v-model="formData.qiStagnationQuality">
<el-option label="是" value="是"></el-option>
<el-option label="倾向是" value="倾向是"></el-option>
<el-option label="否" value="否"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible4Edit = false">取消</el-button>
<el-button type="primary" @click="handleEdit()">确定</el-button>
</div>
</el-dialog>
</div>
handleEdit() {
//表单校验
// this.$refs['dataEditForm'].validate((valid)=>{
// if (valid){
//
// }else {
// //表单数据校验不通过
// this.$message.error("表单数据校验失败!");
// return false//保证后面的代码不执行
// }
// });
//表单校验通过,可以提交数据
axios.post("/assess/edit.do",this.formData).then((res)=>{
if (res.data.flag){
//controller操作成功
this.$message({
type:'success',
message:res.data.message
});
}else {
//执行失败
this.$message.error(res.data.message);
}
}).finally(()=>{
//finally不管成功还是失败都要调用分页查询方法
this.findPage();
//隐藏编辑窗口
this.dialogFormVisible4Edit = false;
});
},
// 弹出编辑窗口
handleUpdate(row) {
console.log(row);
//弹出编辑窗口
this.dialogFormVisible4Edit = true;
// alert(row.id)
//回显数据,通过发送ajax请求根据id查询当前检查项数据,进行回显
axios.get("/assess/findById.do?id="+row.id).then((res)=>{
//判断这个controller是否执行成功
if (res.data.flag){
//进行回显,基于vue的数据绑定实现,可以查看上面的内容可以发现都是双向绑定formData内容的
this.formData = res.data.data;
}else {
//查询失败,弹出提示
this.$message.error(res.data.message);
}
}).catch((r)=>{
this.showMessage(r);
});
},
后台页面
AssessController
/根据id查询检查项
@RequestMapping("/findById")//使其那个被访问到
public Result findById(Integer id){
//使用try。。catch。。进行成功还是失败判断
try{
// System.out.println(checkItem.toString());
Assess assess = assessService.findById(id);//如果调用失败就进入catch,没有失败就
//证明成功
return new Result(true, MessageConstant.QUERY_ASSESSS_SUCCESS,assess);
}catch (Exception e){
//证明调用失败
e.printStackTrace();
return new Result(false, MessageConstant.QUERY_ASSESS_FAIL);
}
}
//编辑检查项
// @PreAuthorize("hasAuthority('CHECKITEM_EDIT')")//权限校验
@RequestMapping("/edit")//使其那个被访问到
public Result edit(@RequestBody Assess assess){
//使用try。。catch。。进行成功还是失败判断
try{
System.out.println(assess.toString());
assessService.edit(assess);//如果调用失败就进入catch,没有失败就
}catch (Exception e){
//证明调用失败
e.printStackTrace();
return new Result(false, MessageConstant.EDIT_ASSESS_FAIL);
}
//证明成功
return new Result(true, MessageConstant.EDIT_ASSESSS_SUCCESS);
}
AssessService
@Override
public Assess findById(Integer id) {
return assessDao.findById(id);
}
@Override
public void edit(Assess assess) throws Exception {
// Date d = new Date();
// String dString = DateUtils.parseDate2String(d);
//
// java.sql.Date sqlDate = new java.sql.Date(d.getTime());
// assess.setAssessDate(new Date());
// System.out.println(sqlDate);
assessDao.edit(assess);
}
删除当前用户的报告信息
前台页面
all-medical-list.html
// 删除
handleDelete(row) {//row其实是一个json对象,json对象中的数据为{"age":"0-100","attention":"无","code":"0007","id":34,"name":"裸视力(左)","price":5.0,"remark":"裸视力(左)","sex":"0","type":"1"}
console.log(row);
// alert(row.id);
this.$confirm("你确定要删除当前评估结果吗?","提示",{
type: 'warning'
}).then(()=>{
// alert("点击了确定按钮");
//用户点击确认按钮,发送ajax请求,将检查项提交到Controller进行处理
axios.get("/assess/delete.do?id="+row.id).then((res)=>{
//判断是否执行成功
if (res.data.flag){
//执行成功
//弹出成功提示信息
this.$message({
type:'success',
message:res.data.message
});
//重新进行分页查询
// this.findPage();
}else {
//执行失败
this.$message.error(res.data.message);
}
//重新进行分页查询
// this.findPage();
}).catch((r)=>{
this.showMessage(r);
});
}).catch(()=>{
// alert("点击了取消按钮");
this.$message({
type:'info',
message:'操作已取消'
});
});
}
后台页面
AssessController
//删除新检查项目
// @PreAuthorize("hasAuthority('CHECKITEM_DELETE')")//权限校验
@RequestMapping("/delete")//使其那个被访问到
public Result delete(Integer id){
//使用try。。catch。。进行成功还是失败判断
try{
System.out.println(id);
assessService.deleteById(id);//如果调用失败就进入catch,没有失败就
}catch (Exception e){
//证明调用失败
e.printStackTrace();
return new Result(false, MessageConstant.DELETE_ASSESS_FAIL);
}
//证明删除成功
return new Result(true, MessageConstant.DELETE_ASSESSS_SUCCESS);
}
AssessService
@Override
public void deleteById(Integer id) {
assessDao.deleteById(id);
}
Bug解决
因为我在进行分页查询的时候会自动调用一次findPage方法,即上面的页面显示这个方法。过后,我在进行预约表与评估表的匹配时,由于这次又会进行调用一次上面的findPage方法(即上面的页面显示这个方法),这样就导致了二者进行了两次查询,在同一时间内容,所以产生了线程冲突问题,
后果便是最后每次删除时,都会将少的数据进行两次查询和添加进数据库,出现了重复的结果
出现该结果主要是因为,我分页查询的方法与验证的方法是在同一个service的实现类里面,所以间接造成了多线程的出现,让数据不准确
中医辨识体质的评估标准
分数计算公式
原始分=各个条目的分值相加。
转化分数=[ (原始分目数) / (条目数x4) ] x100
判定标准
平和质为正常体质,其他8种体质为偏颇体质。判定标准见下表。
也就是说除了平和质的判定不一样,其他八种的判定标准是一样的
比如:
示例1:
某人各体质类型转化分如一:
平和质75分,
气虚质56分,
阳虚质27分,
阴虚质25分,
痰湿质12分,
湿热质15分,
血瘀质20分,
气郁质18分,
特稟质10分。
根据判定标准,虽然平和质转化分≥60分,但其他8种体质转化分并未全部< 40分,中气虚质转化分40分,故此人不能判定为平和质,应判定为是气虚质。
示例2:
某人各体质类型转化分如下:
平和质75分,
气虚质16分,
阳虚质27分,
阴虚质25分,
痰湿质32分,
湿热质25分,
血瘀质10分,
气郁质18分,
特禀质10分。
根据判定标准,
平质转化分≥60分,且其他8种体质转化分均<40分,可判定为基本是平和质,
同时,痰湿质转化分在30~39之间,可判定为痰湿质倾向,故此人最终体质判定结果基本是平和质,有痰湿质倾向。
用户进行自我体检判断的表格
1.阳虚质
2.阴虚质
3.气虚质
4.痰湿质
5.湿热质
6.血瘀质
7.特禀质
8.气郁质
9.平和质
注意
注:标有*的条目需先逆向计分,
即: 1→5,2→4, 3- →3, 4- →2,5→1,再用公式转化分。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)