update 完成计算测试

This commit is contained in:
LittleBoy 2024-12-29 17:18:33 +08:00
parent 392f92b204
commit 83d035180f
6 changed files with 310 additions and 37 deletions

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { ConfigProvider } from 'ant-design-vue'
import { ConfigProvider,App } from 'ant-design-vue'
import PageLoading from "@/components/page-loading/index.vue";
import { useUserStore } from "@/service/user-store.ts";
import Login from "@/components/login/index.vue";
@ -18,7 +18,9 @@ const themeConfig = {
<Login v-if="store.userInit && (!store.userInfo || store.userInfo.id < 1)" />
<template v-if="store.userInit">
<ConfigProvider :theme="themeConfig">
<router-view />
<App>
<router-view />
</App>
</ConfigProvider>
</template>
</div>

View File

@ -64,9 +64,13 @@ onUnmounted(() => {
})
</script>
<style>
.tiptap .is-empty{
.ProseMirror-trailingBreak{
display: none;
.tiptap {
}
.tiptap{
p{
.ProseMirror-trailingBreak{
display: none;
}
}
}
.tiptap p.is-editor-empty:first-child::before {

View File

@ -0,0 +1,156 @@
<template>
<Modal :open="visible" width="600px" @cancel="visible = false" :maskClosable="false" :closable="false"
title="设置测试数据">
<div class="setting-container">
<div class="grid list-container grid-cols-2 gap-4 py-2 max-h-[400px] overflow-auto">
<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 max-h-[400px] overflow-auto">
<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 max-h-[400px] overflow-auto">
<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>
<template #footer>
<div class="flex justify-center">
<Button key="submit" type="primary" @click="handleOk">确定</Button>
</div>
</template>
</Modal>
</template>
<script setup lang="ts">
import {Input, Modal, Button, Tabs, TabPane} from 'ant-design-vue'
import {defineComponent, onMounted, ref, watch} from "vue";
import {inputProducts} from "@/pages/result/test/data-input.ts";
type InputValuesType = {
[key: string]: number;
}
type SettingItem = {
title: string;
value: number | string;
key: string;
placeholder: string;
type: string;
unit: string;
}
const inputValues = defineModel('inputValues')
const commonValues = ref({
weight: '',
niaosu: '',
})
const visible = defineModel('visible', {type: Boolean})
defineComponent({
name: 'InputSetting'
})
const settingList = ref<SettingItem[]>([])
onMounted(() => {
const storeValues = (() => {
const content = localStorage.getItem('yy_input_setting')
try {
if (!content) {
return null;
}
return JSON.parse(content)
} catch (e) {
}
return null;
})();
if (storeValues && Object.keys(storeValues).length > 0) {
inputValues.value = storeValues
commonValues.value = {
weight: storeValues['weight'] && storeValues['weight'] !== 0 ? storeValues['weight'] : '',
niaosu: storeValues['niaosu'] && storeValues['niaosu'] !== 0 ? storeValues['niaosu'] : '',
}
}
const setting: SettingItem[] = []
inputProducts.forEach(it => {
setting.push({
title: it.name,
key: it.key,
value: storeValues && storeValues[it.key] !== 0 ? storeValues[it.key] : '',
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: storeValues && storeValues[it.addition.key] !== 0 ? storeValues[it.addition.key] : '',
placeholder: it.addition.placeholder, // + (it.unit?`(${it.unit})`:'')
type: it.type,
unit: it.addition.unit,
})
}
})
settingList.value = setting
})
function handleOk() {
const values: InputValuesType = {
weight: Number(commonValues.value.weight || '0'),
niaosu: Number(commonValues.value.niaosu || '0'),
}
settingList.value.forEach(it => {
values[it.key] = it.value ? Number(it.value) : 0
})
localStorage.setItem('yy_input_setting', JSON.stringify(values))
visible.value = false
inputValues.value = values;
}
</script>
<style scoped>
.list-container {
margin-right: -4px;
padding-right: 4px;
}
.setting-container {
.input {
@apply w-full border rounded mt-1 flex items-center;
}
input {
@apply flex-1 outline-0 block ml-2 py-1 mr-1;
}
.unit {
@apply px-2 py-1 bg-gray-200 block h-full;
}
}
</style>

View File

@ -1,25 +1,34 @@
<template>
<div class="result-container">
<PageHeader title="输出指标编辑" description="*输出指标: 使用输入参数进行计算,可对指标进行编辑操作。">
<Button :icon="h(SaveOutlined)" :loading="loading" type="primary" @click="save">保存</Button>
<Space>
<Button :icon="h(SettingOutlined)" :loading="loading" type="info" @click="settingVisible=true">
设置输入数据
</Button>
<Button :icon="h(SaveOutlined)" :loading="loading" type="primary" @click="save">保存</Button>
</Space>
</PageHeader>
</div>
<div class="result-calc-expression-list-container overflow-auto grid grid-cols-1 gap-4"
style="max-height: calc(100vh - 240px);margin-right:-5px;padding-right:5px;">
<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=" text-base font-bold">
<span>{{ item.title }}</span>
<!-- <span>{{ parseExpression(item.expression) }}</span>-->
<InputSetting v-model:input-values="inputValues" v-model:visible="settingVisible"/>
<div class="result-calc-expression-list-container">
<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;">
<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=" text-base font-bold">
<span>{{ item.title }}</span>
<!-- <span>{{ parseExpression(item.expression) }}</span>-->
</div>
<div class="action">
<Button :icon="h(CodeOutlined)" type="text" @click="testExpression(item)">测试公式</Button>
</div>
</div>
<div class="action">
<Button :icon="h(CodeOutlined)" type="primary" @click="testExpression(item)">测试</Button>
<div class="result-item-expression mt-3">
<Tiptap v-model="item.expression"
class="w-full bg-white rounded outline-none p-3 bg-none resize-none"
:placeholder="`请输入&nbsp;${item.title}&nbsp;的计算公式`"/>
</div>
</div>
<div class="result-item-expression mt-3">
<Tiptap v-model="item.expression" class="w-full bg-white rounded outline-none p-3 bg-none resize-none"
:placeholder="`请输入&nbsp;${item.title}&nbsp;的计算公式`"/>
</div>
</div>
</div>
<!-- <div class="hidden">
@ -29,9 +38,9 @@
</div> -->
</template>
<script setup lang="ts">
import {message,Button} from "ant-design-vue";
import {Button, Space,App } from "ant-design-vue";
import {h, ref} from "vue";
import { CodeOutlined, SaveOutlined } from '@ant-design/icons-vue';
import {CodeOutlined, SaveOutlined, SettingOutlined} from '@ant-design/icons-vue';
import {expressionList, saveExpression} from "@/service/api/result";
@ -41,11 +50,16 @@ import Tiptap from "@/components/editor/tiptap.vue";
import useRequest from "@/service/useRequest";
import input from "./test/data-input.ts"
import {getAllProduct} from "@/service/use-result-vars.ts";
import InputSetting from "@/pages/result/components/input-setting.vue";
const {notification,message,modal} = App.useApp()
const ResultExpressionList = ref<ResultExpression[]>([]);
const inputValues = ref<{
[key: string]: number
}>()
const settingVisible = ref(false)
expressionList().then((res) => {
console.log(res)
ResultExpressionList.value = res.list;
});
const productValues = getAllProduct();
@ -55,18 +69,31 @@ const {loading, run: save} = useRequest(() => saveExpression(ResultExpressionLis
message.success("保存成功");
}
})
function runCode(expression:string,vars: any){
return new Function('vars',`with(vars) { return ${expression};}`)(vars)
function runCode(expression: string, vars: any) {
return new Function('vars', `with(vars) { return ${expression};}`)(vars)
}
function testExpression(item: ResultExpression) {
const expression = parseExpression(item.expression);
const result = runCode(expression,{
...(productValues.value),
input,
})
try{
const expression = parseExpression(item.expression);
const result = runCode(expression, {
...(productValues.value),
input:inputValues.value,
})
console.log('result',result)
// console.log('result', result,expression,inputValues.value)
notification.info({
message:'提示',
description:`${item.title}${result}`,
duration:2
})
}catch (e){
modal.warning({
title:'测试公式失败',
content:`错误详情:${e.message}`
})
}
// console.log('expression =>', expression,input,productValues.value)
}
@ -93,10 +120,33 @@ function parseExpression(str: string) {
.result-item-expression {
.tiptap {
@apply outline-none min-h-[40px];
line-height: 26px;
:first-child {
margin-top: 0;
}
}
}
.content-shadow {
@apply absolute inset-x-0 h-3 z-[10];
content: ' ';
pointer-events: none; /* 防止遮罩层影响滚动 */
}
.result-calc-expression-list-container {
@apply relative;
.result-expressions-inner {
@apply py-2;
}
&:before {
@apply content-shadow top-0;
background: linear-gradient(to top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
}
&:after {
@apply content-shadow bottom-0;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
}
}
</style>

View File

@ -1,8 +1,69 @@
export const inputProducts = [
// 肠内制剂
{ name: '瑞能', key: 'ruineng', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '瑞代', key: 'ruidai', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '瑞先', key: 'ruixian', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '瑞高', key: 'ruigao', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '瑞素', key: 'ruisu', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '能全力', key: 'nengquanli', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '康全力', key: 'kangquanli', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '康全甘', key: 'kangquangan', placeholder: '入液量ml', unit: 'ml', type: 'gut' }, // 新增
{ name: '百普力', key: 'baipuli', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '爱伦多', key: 'ailunduo', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '维沃', key: 'weiwo', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
// 新增 230409
{ name: '佳维体', key: 'jiaweiti', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '伊力佳', key: 'yilijia', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '瑞易西', key: 'ruiyixi', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '能全素', key: 'nengquansu', placeholder: '入量(勺)', unit: 'ml', type: 'gut', addition: { key: 'nengquansu_ruye', placeholder: '入液量ml' } },
{ name: '安素', key: 'ansu', placeholder: '入量(勺)', unit: '勺', type: 'gut', addition: { key: 'ansu_ruye', placeholder: '入液量ml' } },
{ name: '全安素', key: 'quanansu', placeholder: '入量(勺)', unit: '勺', type: 'gut', addition: { key: 'quanansu_ruye', placeholder: '入液量ml' } },
// 新增 230409
{ name: '益力佳', key: 'yilijia100', placeholder: '入量(勺)', unit: 'ml', type: 'gut', addition: { key: 'yilijia100_ruye', placeholder: '入液量ml' } },
// o water
{ name: '乳清蛋白量(g)', key: 'ruqingdanbailiang', placeholder: '入量g', unit: 'g', type: 'gut', addition: { key: 'ruqingdanbailiang_ruye', placeholder: '入液量ml' } },
// { name: '雀巢Beneprotein', key: 'quecaoBeneprotein', placeholder: '入量g',unit:'g',type: 'gut' },
{ name: '瑞安吉', key: 'ruianji', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
// 静脉制剂
// { name: '卡文1440ml', key: 'kawen1440', placeholder: '入液量ml', unit:'ml', type: 'vein' },
// { name: '卡文1920ml', key: 'kawen1920', placeholder: '入液量ml', unit:'ml', type: 'vein' },
// 新增 230409
{ name: '水', key: 'shui', placeholder: '入液量ml', unit: 'ml', type: 'gut' },
{ name: '全营达', key: 'quanyingda', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '力卡文', key: 'likawen', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '乐凡命8.5%', key: 'lefanming85', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '乐凡命11.4%', key: 'lefanming114', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '其他氨基酸', key: 'anjisuan', placeholder: '入液量ml', unit: 'ml', type: 'vein', addition: { key: 'anjisuan_ruye', placeholder: '', unit: '%', } },
{ name: '力太', key: 'litai', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '力能', key: 'lineng', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '力文', key: 'liwen', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '尤文', key: 'youwen', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '英脱利匹特20%', key: 'yingtuolipite20', placeholder: '入液量ml', unit: 'ml', type: 'vein' },// 新增
{ name: '英脱利匹特30%', key: 'yingtuolipite30', placeholder: '入液量ml', unit: 'ml', type: 'vein' },// 新增
{ name: '5%葡萄糖氯化钠', key: 'putaotangluhuana5', placeholder: '入液量ml', unit: 'ml', type: 'vein' },// 新增
{ name: '5%葡萄糖', key: 'putaotang5', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '10%葡萄糖', key: 'putaotang10', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '50%葡萄糖', key: 'putaotang50', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '0.9%氯化钠', key: 'luhuana09', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '10%氯化钠', key: 'luhuana10', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '格列福斯', key: 'geliefusi', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
{ name: '氯化钾', key: 'luhuajia', placeholder: '入液量ml', unit: 'ml', type: 'vein' },
// { name: '其他液体', key: 'qitayeti', placeholder: '入液量ml', unit:'ml', type: 'vein' }, // 新增
{ name: '白蛋白', key: 'baidanbai', placeholder: '入液量g', unit: 'ml', type: 'vein' }, // 新增
];
export default {
"weight": 50,
"niaosu": 10,
"ruineng": 1,
"ruidai": 1,
"weight": 0,
"niaosu": 0,
"ruineng": 0,
"ruidai": 0,
"ruixian": 0,
"ruigao": 0,
"ruisu": 0,

View File

@ -42,13 +42,13 @@
}
::-webkit-scrollbar-thumb {
background: #4096ff80;
background: #2ec7a5;
height: 10px;
border-radius: 5px
}
::-webkit-scrollbar-thumb:hover {
background: #4096ff;
background: #279b83;
cursor: pointer
}