添加匿名计算测试页面
This commit is contained in:
parent
702fc4ba0d
commit
19fc116f73
@ -1,11 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ConfigProvider,App } from 'ant-design-vue'
|
import { ConfigProvider,App } from 'ant-design-vue'
|
||||||
|
import {useRoute} from "vue-router"
|
||||||
import PageLoading from "@/components/page-loading/index.vue";
|
import PageLoading from "@/components/page-loading/index.vue";
|
||||||
import { useUserStore } from "@/service/user-store.ts";
|
import { useUserStore } from "@/service/user-store.ts";
|
||||||
import Login from "@/components/login/index.vue";
|
import Login from "@/components/login/index.vue";
|
||||||
|
|
||||||
// 登录相关
|
// 登录相关
|
||||||
const store = useUserStore()
|
const store = useUserStore()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
|
||||||
const themeConfig = {
|
const themeConfig = {
|
||||||
token: { colorPrimary: '#2EC7A5', },
|
token: { colorPrimary: '#2EC7A5', },
|
||||||
@ -15,7 +18,7 @@ const themeConfig = {
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<PageLoading :class="{ hideLoading: store.userInit }" />
|
<PageLoading :class="{ hideLoading: store.userInit }" />
|
||||||
<Login v-if="store.userInit && (!store.userInfo || store.userInfo.id < 1)" />
|
<Login v-if="store.userInit && (!store.userInfo || store.userInfo.id < 1) && route.name != 'calc'" />
|
||||||
<template v-if="store.userInit">
|
<template v-if="store.userInit">
|
||||||
<ConfigProvider :theme="themeConfig">
|
<ConfigProvider :theme="themeConfig">
|
||||||
<App>
|
<App>
|
||||||
|
177
src/components/calc/index.vue
Normal file
177
src/components/calc/index.vue
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
<template>
|
||||||
|
<div class="calc-container">
|
||||||
|
<div class="setting-container">
|
||||||
|
<div class="grid list-container grid-cols-2 gap-4 py-2">
|
||||||
|
<div class="input-item">
|
||||||
|
<div class="title">体重</div>
|
||||||
|
<div class="input">
|
||||||
|
<input type="number" v-model="commonValues.weight" placeholder="单位(kg)"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-item">
|
||||||
|
<div class="title">24h尿素</div>
|
||||||
|
<div class="input">
|
||||||
|
<input type="number" v-model="commonValues.niaosu" placeholder="单位(mmol)"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Tabs>
|
||||||
|
<TabPane key="gut" tab="肠内制剂">
|
||||||
|
<div class="grid list-container grid-cols-2 gap-4 py-2 setting-input-scroller">
|
||||||
|
<div class="input-item" v-for="(it,key) in settingList.filter(s=>s.type=='gut')" :key="key">
|
||||||
|
<div class="title">{{ it.title }}</div>
|
||||||
|
<div class="input">
|
||||||
|
<input type="number" v-model="it.value" :placeholder="it.placeholder"/>
|
||||||
|
<span class="unit">{{ it.unit }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
<TabPane key="vein" tab="静脉制剂">
|
||||||
|
<div class="grid list-container grid-cols-2 gap-4 py-2 setting-input-scroller">
|
||||||
|
<div class="input-item" v-for="(it,key) in settingList.filter(s=>s.type=='vein')" :key="key">
|
||||||
|
<div class="title">{{ it.title }}</div>
|
||||||
|
<div class="input">
|
||||||
|
<input type="number" v-model="it.value" :placeholder="it.placeholder"/>
|
||||||
|
<span class="unit">{{ it.unit }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TabPane>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
<div class="text-center py-4">
|
||||||
|
<Button type="primary" @click="calcResult">测试计算</Button>
|
||||||
|
</div>
|
||||||
|
<ResultModal v-model:result="testResultValue" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {onMounted,defineComponent, ref} from "vue";
|
||||||
|
import {TabPane, Tabs, Button, Modal} from "ant-design-vue";
|
||||||
|
import {inputProducts} from "@/pages/result/test/data-input.ts";
|
||||||
|
import ResultModal from "@/pages/result/components/result-modal.vue";
|
||||||
|
import {expressionList} from "@/service/api/result.ts";
|
||||||
|
import {parseExpression} from "@/core/string.ts";
|
||||||
|
import {getAllProduct} from "@/service/use-result-vars.ts";
|
||||||
|
const commonValues = ref({
|
||||||
|
weight: '',
|
||||||
|
niaosu: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
defineComponent({
|
||||||
|
name: 'Calculation'
|
||||||
|
})
|
||||||
|
const ResultExpressionList = ref<ResultExpression[]>([]);
|
||||||
|
const settingList = ref<SettingItem[]>([])
|
||||||
|
const testResultValue = ref<ResultItem[]>([])
|
||||||
|
const productValues = getAllProduct();
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
expressionList().then((res) => {
|
||||||
|
ResultExpressionList.value = res.list;
|
||||||
|
});
|
||||||
|
const setting: SettingItem[] = []
|
||||||
|
inputProducts.forEach(it => {
|
||||||
|
setting.push({
|
||||||
|
title: it.name,
|
||||||
|
key: it.key,
|
||||||
|
value: '',
|
||||||
|
placeholder: it.placeholder, // + (it.unit?`(${it.unit})`:'')
|
||||||
|
type: it.type,
|
||||||
|
unit: it.unit,
|
||||||
|
})
|
||||||
|
if (it.addition) {
|
||||||
|
setting.push({
|
||||||
|
title: it.name,
|
||||||
|
key: it.addition.key,
|
||||||
|
value: '',
|
||||||
|
placeholder: it.addition.placeholder, // + (it.unit?`(${it.unit})`:'')
|
||||||
|
type: it.type,
|
||||||
|
unit: it.addition.unit,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
settingList.value = setting
|
||||||
|
})
|
||||||
|
function runCode(expression: string, vars: any) {
|
||||||
|
return new Function('vars', `with(vars) { return ${expression};}`)(vars)
|
||||||
|
}
|
||||||
|
function getResultValues(){
|
||||||
|
// 结果集
|
||||||
|
const result:{
|
||||||
|
[key: string]: number
|
||||||
|
} = {};
|
||||||
|
const inputs: { [key: string]: number }= {
|
||||||
|
...commonValues.value,
|
||||||
|
}
|
||||||
|
settingList.value.forEach(it=>{
|
||||||
|
inputs[it.key] = it.value ? Number(it.value) : 0
|
||||||
|
})
|
||||||
|
ResultExpressionList.value.forEach(it=>{
|
||||||
|
const expression = parseExpression(it.expression);
|
||||||
|
if(expression.length == 0) return;
|
||||||
|
try{
|
||||||
|
const value = runCode(expression, {
|
||||||
|
...(productValues.value),
|
||||||
|
...result,
|
||||||
|
input: inputs,
|
||||||
|
})
|
||||||
|
result[it.key] = value;
|
||||||
|
}catch (e) {
|
||||||
|
Modal.warning({
|
||||||
|
title: '提示',
|
||||||
|
content: `计算出错:${e.message}`
|
||||||
|
})
|
||||||
|
console.error('getResultValues',e,expression)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcResult(){
|
||||||
|
const result = getResultValues();
|
||||||
|
console.log('result',result)
|
||||||
|
const resultList:ResultItem[] = [];
|
||||||
|
ResultExpressionList.value.forEach(it=>{
|
||||||
|
resultList.push({
|
||||||
|
title:it.title,
|
||||||
|
key:it.key,
|
||||||
|
value: result[it.key] || 0
|
||||||
|
})
|
||||||
|
})
|
||||||
|
console.log(resultList);
|
||||||
|
testResultValue.value = resultList;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.calc-container{
|
||||||
|
max-width: 90%;
|
||||||
|
margin: auto;
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
.list-container {
|
||||||
|
margin-right: -4px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
.setting-input-scroller {
|
||||||
|
max-height: calc(100vh - 200px);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container {
|
||||||
|
.input {
|
||||||
|
@apply w-full relative border rounded mt-1 flex items-center bg-white overflow-hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
@apply flex-1 outline-0 block ml-2 py-1 mr-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
@apply absolute inset-y-0 right-0 px-2 py-1 bg-gray-100 block h-full text-center;
|
||||||
|
min-width: 34px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -135,7 +135,7 @@ const handleSubmit = () => {
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
color: red;
|
color: red;
|
||||||
text-align: left;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-item {
|
.form-item {
|
||||||
|
@ -8,4 +8,25 @@ export function getMd5(str: string) {
|
|||||||
export function formatDatetime(date: Date | string | number, format = 'YYYY-MM-DD HH:mm:ss') {
|
export function formatDatetime(date: Date | string | number, format = 'YYYY-MM-DD HH:mm:ss') {
|
||||||
if (!date) return date;
|
if (!date) return date;
|
||||||
return dayjs(date).format(format);
|
return dayjs(date).format(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseExpression(str: string) {
|
||||||
|
if (!str) return '';
|
||||||
|
const doc = JSON.parse(str) as TiptapContentValue;
|
||||||
|
if (!doc.content || doc.content.length == 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const expList: string[] = [];
|
||||||
|
doc.content.forEach(p=>{
|
||||||
|
const expressionList = p.content;
|
||||||
|
if (!expressionList) return;
|
||||||
|
const expression = expressionList.map(item => {
|
||||||
|
if (item.type == 'text') {
|
||||||
|
return item.text;
|
||||||
|
}
|
||||||
|
return item.attrs.id
|
||||||
|
}).join('');
|
||||||
|
expList.push(expression);
|
||||||
|
})
|
||||||
|
return expList.join('');
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineModel, reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
import { Modal, Form, Input, Space, Button, Select, SelectOption } from 'ant-design-vue';
|
import { Modal, Form, Input, Space, Button, Select, SelectOption } from 'ant-design-vue';
|
||||||
import useRequest from '@/service/useRequest';
|
import useRequest from '@/service/useRequest';
|
||||||
import { saveProduct } from '@/service/api/product';
|
import { saveProduct } from '@/service/api/product';
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
title="测试结果"
|
title="测试结果"
|
||||||
:footer="false"
|
:footer="false"
|
||||||
>
|
>
|
||||||
<div class="grid result-list grid-cols-2 gap-4">
|
<div class="grid result-list grid-cols-1 md:grid-cols-2 gap-2">
|
||||||
<div class="flex result-item" v-for="(it,index) in result" :key="index">
|
<div class="flex result-item" v-for="(it,index) in result" :key="index">
|
||||||
<div class="title">{{it.title}}:</div>
|
<div class="title">{{it.title}}:</div>
|
||||||
<div class="value">{{getValue(it)}}</div>
|
<div class="value">{{getValue(it)}}</div>
|
||||||
@ -59,7 +59,11 @@ function getValue(item:ResultItem){
|
|||||||
return Math.floor(item.value)
|
return Math.floor(item.value)
|
||||||
}
|
}
|
||||||
if(!percentKeys.includes(item.key)){
|
if(!percentKeys.includes(item.key)){
|
||||||
return toFixed(item.value, 3)
|
const value = toFixed(item.value, 3);
|
||||||
|
if(item.key == 'shijireka'){
|
||||||
|
return Math.round(value);
|
||||||
|
}
|
||||||
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
const v = item.value * 100;
|
const v = item.value * 100;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<InputSetting v-model:input-values="inputValues" v-model:visible="settingVisible"/>
|
<InputSetting v-model:input-values="inputValues" v-model:visible="settingVisible"/>
|
||||||
<div class="result-calc-expression-list-container">
|
<div class="result-calc-expression-list-container">
|
||||||
<div class="result-expressions-inner overflow-auto grid grid-cols-1 gap-4"
|
<div class="result-expressions-inner overflow-auto grid grid-cols-1 gap-4"
|
||||||
style="max-height: calc(100vh - 240px);margin-right:-5px;padding-right:5px;">
|
style="max-height: calc(100vh - 240px);margin-right:-7px;padding-right:7px;">
|
||||||
<div class="result-item bg-gray-100 p-3 rounded" v-for="item in ResultExpressionList" :key="item.key">
|
<div class="result-item bg-gray-100 p-3 rounded" v-for="item in ResultExpressionList" :key="item.key">
|
||||||
<div class="result-item-title flex justify-between">
|
<div class="result-item-title flex justify-between">
|
||||||
<div class=" text-base">
|
<div class=" text-base">
|
||||||
@ -62,6 +62,7 @@ import useRequest from "@/service/useRequest";
|
|||||||
import {getAllProduct} from "@/service/use-result-vars.ts";
|
import {getAllProduct} from "@/service/use-result-vars.ts";
|
||||||
import InputSetting from "@/pages/result/components/input-setting.vue";
|
import InputSetting from "@/pages/result/components/input-setting.vue";
|
||||||
import ResultModal from "./components/result-modal.vue";
|
import ResultModal from "./components/result-modal.vue";
|
||||||
|
import {parseExpression} from "@/core/string.ts";
|
||||||
|
|
||||||
const {notification, message, modal} = App.useApp()
|
const {notification, message, modal} = App.useApp()
|
||||||
const ResultExpressionList = ref<ResultExpression[]>([]);
|
const ResultExpressionList = ref<ResultExpression[]>([]);
|
||||||
@ -86,6 +87,14 @@ function runCode(expression: string, vars: any) {
|
|||||||
return new Function('vars', `with(vars) { return ${expression};}`)(vars)
|
return new Function('vars', `with(vars) { return ${expression};}`)(vars)
|
||||||
}
|
}
|
||||||
function showAllResult(){
|
function showAllResult(){
|
||||||
|
if(!inputValues.value){
|
||||||
|
console.log('inputValues',inputValues.value)
|
||||||
|
modal.warning({
|
||||||
|
title: '提示',
|
||||||
|
content: `请先设置输入数据`
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
const result = getResultValues();
|
const result = getResultValues();
|
||||||
const resultList:ResultItem[] = [];
|
const resultList:ResultItem[] = [];
|
||||||
ResultExpressionList.value.forEach(it=>{
|
ResultExpressionList.value.forEach(it=>{
|
||||||
@ -122,6 +131,14 @@ function getResultValues(){
|
|||||||
|
|
||||||
|
|
||||||
function testExpression(item: ResultExpression) {
|
function testExpression(item: ResultExpression) {
|
||||||
|
if(!inputValues.value){
|
||||||
|
console.log('inputValues',inputValues.value)
|
||||||
|
modal.warning({
|
||||||
|
title: '提示',
|
||||||
|
content: `请先设置输入数据`
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
const expression = parseExpression(item.expression);
|
const expression = parseExpression(item.expression);
|
||||||
try {
|
try {
|
||||||
const result = getResultValues()
|
const result = getResultValues()
|
||||||
@ -146,26 +163,6 @@ function testExpression(item: ResultExpression) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseExpression(str: string) {
|
|
||||||
if (!str) return '';
|
|
||||||
const doc = JSON.parse(str) as TiptapContentValue;
|
|
||||||
if (!doc.content || doc.content.length == 0) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const expList: string[] = [];
|
|
||||||
doc.content.forEach(p=>{
|
|
||||||
const expressionList = p.content;
|
|
||||||
if (!expressionList) return;
|
|
||||||
const expression = expressionList.map(item => {
|
|
||||||
if (item.type == 'text') {
|
|
||||||
return item.text;
|
|
||||||
}
|
|
||||||
return item.attrs.id
|
|
||||||
}).join('');
|
|
||||||
expList.push(expression);
|
|
||||||
})
|
|
||||||
return expList.join('');
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@ -64,16 +64,16 @@ export const routes:RouteRecordRaw[] = [
|
|||||||
export const router = createRouter({
|
export const router = createRouter({
|
||||||
routes: [
|
routes: [
|
||||||
// 路由配置
|
// 路由配置
|
||||||
|
{
|
||||||
|
path: '/calc',
|
||||||
|
name: 'calc',
|
||||||
|
component: () => import('./components/calc/index.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: () => import('./pages/Layout.vue'),
|
component: () => import('./pages/Layout.vue'),
|
||||||
children: routes
|
children: routes
|
||||||
},
|
}
|
||||||
// {
|
|
||||||
// path: '/login',
|
|
||||||
// name: 'login',
|
|
||||||
// component: () => import('./pages/login.vue')
|
|
||||||
// }
|
|
||||||
],
|
],
|
||||||
history: createWebHashHistory()
|
history: createWebHashHistory()
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user