update 更新编辑器;完成动态代码测试
This commit is contained in:
parent
f0a1b687b7
commit
a2e27103a4
@ -12,6 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tiptap/core": "^2.10.4",
|
"@tiptap/core": "^2.10.4",
|
||||||
"@tiptap/pm": "^2.10.4",
|
"@tiptap/pm": "^2.10.4",
|
||||||
|
"@tiptap/suggestion": "^2.10.4",
|
||||||
"@tiptap/vue-3": "^2.10.4",
|
"@tiptap/vue-3": "^2.10.4",
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
|
@ -4,7 +4,6 @@ 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()
|
||||||
|
|
||||||
|
@ -35,10 +35,8 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.icon-loading{
|
.icon-loading{
|
||||||
display: inline-block;
|
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
animation: loading-360 linear 1s infinite;
|
animation: loading-360 linear 1s infinite;
|
||||||
vertical-align: middle;
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -6,6 +6,7 @@ const props = defineProps<{
|
|||||||
block?: boolean;
|
block?: boolean;
|
||||||
shape?: 'default' | 'circle' | 'round';
|
shape?: 'default' | 'circle' | 'round';
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
|
icon?:import("vue-types").VueTypeValidableDef<any>
|
||||||
}>()
|
}>()
|
||||||
const btnClass = {
|
const btnClass = {
|
||||||
'btn-primary': props.type == 'primary',
|
'btn-primary': props.type == 'primary',
|
||||||
@ -20,6 +21,7 @@ const btnClass = {
|
|||||||
<template>
|
<template>
|
||||||
<button class="btn" :class="btnClass">
|
<button class="btn" :class="btnClass">
|
||||||
<span v-if="props.loading" class="icon-loading"></span>
|
<span v-if="props.loading" class="icon-loading"></span>
|
||||||
|
<template v-else-if="!!props.icon" ><props.icon /></template>
|
||||||
<span><slot/></span>
|
<span><slot/></span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
17
src/components/editor/test.vue
Normal file
17
src/components/editor/test.vue
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bg-blue-500 p-2 rounded">
|
||||||
|
<textarea ref="txtBox" class="w-full block rounded outline-none"></textarea>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {onMounted, ref} from "vue";
|
||||||
|
|
||||||
|
const txtBox = ref<HTMLTextAreaElement>();
|
||||||
|
const content = defineModel<string>()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
txtBox.value?.addEventListener('input', () => {
|
||||||
|
content.value = txtBox.value?.value || ''
|
||||||
|
}, false)
|
||||||
|
})
|
||||||
|
</script>
|
@ -1,36 +1,61 @@
|
|||||||
<template>
|
<template>
|
||||||
<EditorContent :editor="editor" />
|
<EditorContent :editor="editor"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
import {Editor, EditorContent} from '@tiptap/vue-3'
|
||||||
import { extensions, Placeholder } from './tiptap'
|
import {extensions, Mention, Placeholder} from './tiptap'
|
||||||
import { watch, onMounted, onUnmounted } from 'vue'
|
import {watch, onMounted, onUnmounted} from 'vue'
|
||||||
|
import vars from "@/pages/result/vars.ts";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Tiptap',
|
name: 'Tiptap',
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const model = defineModel<string>()
|
const model = defineModel<string>()
|
||||||
|
|
||||||
const editor = new Editor({
|
const editor = new Editor({
|
||||||
content: ``,
|
content: ``,
|
||||||
// extensions: [StarterKit],
|
|
||||||
extensions: [
|
extensions: [
|
||||||
...extensions,
|
...extensions,
|
||||||
|
Mention.configure({
|
||||||
|
HTMLAttributes: {
|
||||||
|
class: 'result-var',
|
||||||
|
},
|
||||||
|
suggestion: vars
|
||||||
|
}),
|
||||||
|
|
||||||
Placeholder.configure({
|
Placeholder.configure({
|
||||||
placeholder: props.placeholder || '请输入内容',
|
placeholder: props.placeholder || '请输入内容',
|
||||||
})
|
}),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
function getMergeContent(){
|
||||||
|
const content = editor.getJSON()
|
||||||
|
const mergedContentList:ExpressionValue[] = [];
|
||||||
|
content.content?.forEach(it=>{
|
||||||
|
if(it.type == "paragraph" && it.content?.length > 0){
|
||||||
|
mergedContentList.push(it)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(content.content?.length > mergedContentList.length){
|
||||||
|
content.content = mergedContentList;
|
||||||
|
// 更新新内容
|
||||||
|
editor.commands.setContent(content)
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (model.value) editor.commands.setContent(model.value)
|
if (model.value?.trim().length > 0) editor.commands.setContent(JSON.parse(model.value))
|
||||||
editor.on('update', () => {
|
editor.on('update', () => {
|
||||||
model.value = editor.getText()
|
model.value = JSON.stringify(getMergeContent())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
watch(model, (newValue) => {
|
watch(()=>model, (newValue) => {
|
||||||
editor.commands.setContent(newValue || '')
|
editor.commands.setContent(newValue || '')
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -39,11 +64,26 @@ onUnmounted(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
.tiptap .is-empty{
|
||||||
|
.ProseMirror-trailingBreak{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
.tiptap p.is-editor-empty:first-child::before {
|
.tiptap p.is-editor-empty:first-child::before {
|
||||||
|
display: block;
|
||||||
color: #adb5bd;
|
color: #adb5bd;
|
||||||
content: attr(data-placeholder);
|
content: attr(data-placeholder);
|
||||||
float: left;
|
float: left;
|
||||||
height: 0;
|
height: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tiptap .result-var {
|
||||||
|
background-color: #3574f0;
|
||||||
|
border-radius: 3px;
|
||||||
|
-webkit-box-decoration-break: clone;
|
||||||
|
box-decoration-break: clone;
|
||||||
|
color: white;
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -5,15 +5,7 @@ import Suggestion, { SuggestionOptions } from '@tiptap/suggestion'
|
|||||||
|
|
||||||
// See `addAttributes` below
|
// See `addAttributes` below
|
||||||
export interface MentionNodeAttrs {
|
export interface MentionNodeAttrs {
|
||||||
/**
|
|
||||||
* The identifier for the selected item that was mentioned, stored as a `data-id`
|
|
||||||
* attribute.
|
|
||||||
*/
|
|
||||||
id: string | null;
|
id: string | null;
|
||||||
/**
|
|
||||||
* The label to be rendered by the editor as the displayed text for this mentioned
|
|
||||||
* item, if provided. Stored as a `data-label` attribute. See `renderLabel`.
|
|
||||||
*/
|
|
||||||
label?: string | null;
|
label?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,13 +128,9 @@ export const Mention = Node.create<MentionOptions>({
|
|||||||
},
|
},
|
||||||
|
|
||||||
group: 'inline',
|
group: 'inline',
|
||||||
|
|
||||||
inline: true,
|
inline: true,
|
||||||
|
|
||||||
selectable: false,
|
selectable: false,
|
||||||
|
|
||||||
atom: true,
|
atom: true,
|
||||||
|
|
||||||
addAttributes() {
|
addAttributes() {
|
||||||
return {
|
return {
|
||||||
id: {
|
id: {
|
||||||
@ -174,7 +162,6 @@ export const Mention = Node.create<MentionOptions>({
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
parseHTML() {
|
parseHTML() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -182,7 +169,6 @@ export const Mention = Node.create<MentionOptions>({
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
renderHTML({ node, HTMLAttributes }) {
|
renderHTML({ node, HTMLAttributes }) {
|
||||||
if (this.options.renderLabel !== undefined) {
|
if (this.options.renderLabel !== undefined) {
|
||||||
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
|
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
|
@ -2,6 +2,7 @@ import { Text } from './ext-text.ts'
|
|||||||
import { Paragraph } from './ext-paragraph.ts'
|
import { Paragraph } from './ext-paragraph.ts'
|
||||||
import { Document } from './ext-document.ts'
|
import { Document } from './ext-document.ts'
|
||||||
export {Placeholder } from './ext-placeholder.ts'
|
export {Placeholder } from './ext-placeholder.ts'
|
||||||
|
export {Mention} from './ext-mention.ts'
|
||||||
|
|
||||||
|
|
||||||
// export
|
// export
|
||||||
|
12
src/pages/T.vue
Normal file
12
src/pages/T.vue
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TestRef v-model="testrv"/>
|
||||||
|
<div>{{ testrv }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import TestRef from "@/components/editor/test.vue";
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
|
const testrv = ref('')
|
||||||
|
</script>
|
@ -1,50 +1,92 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="result-container">
|
<div class="result-container">
|
||||||
<PageHeader title="输出指标编辑" description="*输出指标: 使用输入参数进行计算,可对指标进行编辑操作。">
|
<PageHeader title="输出指标编辑" description="*输出指标: 使用输入参数进行计算,可对指标进行编辑操作。">
|
||||||
<Button :loading="loading" type="primary" @click="save">保存</Button>
|
<Button :icon="h(SaveOutlined)" :loading="loading" type="primary" @click="save">保存</Button>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
</div>
|
</div>
|
||||||
<div class="result-calc-expression-list-container overflow-auto grid grid-cols-2 gap-4"
|
<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;">
|
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 bg-gray-100 p-3 rounded" v-for="item in ResultExpressionList" :key="item.key">
|
||||||
<div class="result-item-title text-base font-bold">{{ item.title }}</div>
|
<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="primary" @click="testExpression(item)">测试</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="result-item-expression mt-3">
|
<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"
|
<Tiptap v-model="item.expression" class="w-full bg-white rounded outline-none p-3 bg-none resize-none"
|
||||||
:placeholder="`请输入 ${item.title} 的计算公式`" />
|
:placeholder="`请输入 ${item.title} 的计算公式`"/>
|
||||||
<!-- <textarea class="w-full h-[66px] rounded outline-none p-3 bg-none resize-none" v-model="item.expression"
|
|
||||||
:placeholder="`请输入${item.title}计算公式`" /> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="hidden">
|
<!-- <div class="hidden">
|
||||||
<DataField />
|
<DataField />
|
||||||
<Button type="primary" @click="showMessage">test</Button>
|
<Button type="primary" @click="showMessage">test</Button>
|
||||||
<p>输出计算</p>
|
<p>输出计算</p>
|
||||||
</div> -->
|
</div> -->
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import {message,Button} from "ant-design-vue";
|
||||||
|
import {h, ref} from "vue";
|
||||||
|
import { CodeOutlined, SaveOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
import { message } from "ant-design-vue";
|
import {expressionList, saveExpression} from "@/service/api/result";
|
||||||
import { ref } from "vue";
|
|
||||||
|
|
||||||
import { expressionList, saveExpression } from "@/service/api/result";
|
|
||||||
|
|
||||||
import PageHeader from "@/components/page-header.vue";
|
import PageHeader from "@/components/page-header.vue";
|
||||||
import Tiptap from "@/components/editor/tiptap.vue";
|
import Tiptap from "@/components/editor/tiptap.vue";
|
||||||
import Button from "@/components/button/button.vue";
|
// import Button from "@/components/button/button.vue";
|
||||||
import useRequest from "@/service/useRequest";
|
import useRequest from "@/service/useRequest";
|
||||||
|
import input from "./test/data-input.ts"
|
||||||
|
import {getAllProduct} from "@/service/use-result-vars.ts";
|
||||||
|
|
||||||
const ResultExpressionList = ref<ResultExpression[]>([]);
|
const ResultExpressionList = ref<ResultExpression[]>([]);
|
||||||
|
|
||||||
expressionList().then((res) => {
|
expressionList().then((res) => {
|
||||||
|
console.log(res)
|
||||||
ResultExpressionList.value = res.list;
|
ResultExpressionList.value = res.list;
|
||||||
});
|
});
|
||||||
const {loading,run:save} = useRequest(()=> saveExpression(ResultExpressionList.value),{
|
const productValues = getAllProduct();
|
||||||
|
const {loading, run: save} = useRequest(() => saveExpression(ResultExpressionList.value), {
|
||||||
manual: true,
|
manual: true,
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
message.success("保存成功");
|
message.success("保存成功");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('result',result)
|
||||||
|
// console.log('expression =>', expression,input,productValues.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseExpression(str: string) {
|
||||||
|
if (!str) return;
|
||||||
|
const doc = JSON.parse(str) as TiptapContentValue;
|
||||||
|
if (!doc.content || doc.content.length == 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const expressionList = doc.content[0].content;
|
||||||
|
if (!expressionList) return '';
|
||||||
|
const expression = expressionList.map(item => {
|
||||||
|
if (item.type == 'text') {
|
||||||
|
return item.text;
|
||||||
|
}
|
||||||
|
return item.attrs.id
|
||||||
|
}).join('');
|
||||||
|
return expression;
|
||||||
|
// console.log(JSON.stringify({content:doc.content[0].content}))
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -57,27 +99,4 @@ const {loading,run:save} = useRequest(()=> saveExpression(ResultExpressionList.v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
// .result-calc-expression-list-container {}
|
|
||||||
|
|
||||||
// .result-item {
|
|
||||||
// display: flex;
|
|
||||||
// flex-direction: column;
|
|
||||||
// margin-bottom: 20px;
|
|
||||||
|
|
||||||
|
|
||||||
// .result-item-title {
|
|
||||||
// font-size: 14px;
|
|
||||||
// font-weight: 500;
|
|
||||||
// color: #333333;
|
|
||||||
// margin-bottom: 10px;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .result-item-expression {}
|
|
||||||
|
|
||||||
// textarea {
|
|
||||||
// width: 100%;
|
|
||||||
// height: 40px;
|
|
||||||
// outline: none;
|
|
||||||
// }
|
|
||||||
// }</style>
|
|
50
src/pages/result/test/data-input.ts
Normal file
50
src/pages/result/test/data-input.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
export default {
|
||||||
|
"weight": 50,
|
||||||
|
"niaosu": 10,
|
||||||
|
"ruineng": 1,
|
||||||
|
"ruidai": 1,
|
||||||
|
"ruixian": 0,
|
||||||
|
"ruigao": 0,
|
||||||
|
"ruisu": 0,
|
||||||
|
"nengquanli": 0,
|
||||||
|
"kangquanli": 0,
|
||||||
|
"kangquangan": 0,
|
||||||
|
"baipuli": 0,
|
||||||
|
"ailunduo": 0,
|
||||||
|
"weiwo": 0,
|
||||||
|
"jiaweiti": 0,
|
||||||
|
"yilijia": 0,
|
||||||
|
"ruiyixi": 0,
|
||||||
|
"nengquansu": 0,
|
||||||
|
"ansu": 0,
|
||||||
|
"quanansu": 0,
|
||||||
|
"yilijia100": 0,
|
||||||
|
"shui": 0,
|
||||||
|
"anjisuan_ruye": 0,
|
||||||
|
"yilijia100_ruye": 0,
|
||||||
|
"quanansu_ruye": 0,
|
||||||
|
"ansu_ruye": 0,
|
||||||
|
"nengquansu_ruye": 0,
|
||||||
|
"ruqingdanbailiang": 0,
|
||||||
|
"ruianji": 0,
|
||||||
|
"quanyingda": 0,
|
||||||
|
"likawen": 0,
|
||||||
|
"lefanming85": 0,
|
||||||
|
"lefanming114": 0,
|
||||||
|
"anjisuan": 0,
|
||||||
|
"litai": 0,
|
||||||
|
"lineng": 0,
|
||||||
|
"liwen": 0,
|
||||||
|
"youwen": 0,
|
||||||
|
"yingtuolipite20": 0,
|
||||||
|
"yingtuolipite30": 0,
|
||||||
|
"putaotangluhuana5": 0,
|
||||||
|
"putaotang5": 0,
|
||||||
|
"putaotang10": 0,
|
||||||
|
"putaotang50": 0,
|
||||||
|
"luhuana09": 0,
|
||||||
|
"luhuana10": 0,
|
||||||
|
"geliefusi": 0,
|
||||||
|
"luhuajia": 0,
|
||||||
|
"baidanbai": 0
|
||||||
|
}
|
718
src/pages/result/test/parser.js
Normal file
718
src/pages/result/test/parser.js
Normal file
@ -0,0 +1,718 @@
|
|||||||
|
/*
|
||||||
|
* Generated by PEG.js 0.10.0.
|
||||||
|
*
|
||||||
|
* http://pegjs.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function peg$subclass(child, parent) {
|
||||||
|
function ctor() { this.constructor = child; }
|
||||||
|
ctor.prototype = parent.prototype;
|
||||||
|
child.prototype = new ctor();
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$SyntaxError(message, expected, found, location) {
|
||||||
|
this.message = message;
|
||||||
|
this.expected = expected;
|
||||||
|
this.found = found;
|
||||||
|
this.location = location;
|
||||||
|
this.name = "SyntaxError";
|
||||||
|
|
||||||
|
if (typeof Error.captureStackTrace === "function") {
|
||||||
|
Error.captureStackTrace(this, peg$SyntaxError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
peg$subclass(peg$SyntaxError, Error);
|
||||||
|
|
||||||
|
peg$SyntaxError.buildMessage = function(expected, found) {
|
||||||
|
var DESCRIBE_EXPECTATION_FNS = {
|
||||||
|
literal: function(expectation) {
|
||||||
|
return "\"" + literalEscape(expectation.text) + "\"";
|
||||||
|
},
|
||||||
|
|
||||||
|
"class": function(expectation) {
|
||||||
|
var escapedParts = "",
|
||||||
|
i;
|
||||||
|
|
||||||
|
for (i = 0; i < expectation.parts.length; i++) {
|
||||||
|
escapedParts += expectation.parts[i] instanceof Array
|
||||||
|
? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])
|
||||||
|
: classEscape(expectation.parts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
|
||||||
|
},
|
||||||
|
|
||||||
|
any: function(expectation) {
|
||||||
|
return "any character";
|
||||||
|
},
|
||||||
|
|
||||||
|
end: function(expectation) {
|
||||||
|
return "end of input";
|
||||||
|
},
|
||||||
|
|
||||||
|
other: function(expectation) {
|
||||||
|
return expectation.description;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function hex(ch) {
|
||||||
|
return ch.charCodeAt(0).toString(16).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function literalEscape(s) {
|
||||||
|
return s
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\0/g, '\\0')
|
||||||
|
.replace(/\t/g, '\\t')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
|
||||||
|
.replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
|
||||||
|
}
|
||||||
|
|
||||||
|
function classEscape(s) {
|
||||||
|
return s
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/\]/g, '\\]')
|
||||||
|
.replace(/\^/g, '\\^')
|
||||||
|
.replace(/-/g, '\\-')
|
||||||
|
.replace(/\0/g, '\\0')
|
||||||
|
.replace(/\t/g, '\\t')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
|
||||||
|
.replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
|
||||||
|
}
|
||||||
|
|
||||||
|
function describeExpectation(expectation) {
|
||||||
|
return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
|
||||||
|
}
|
||||||
|
|
||||||
|
function describeExpected(expected) {
|
||||||
|
var descriptions = new Array(expected.length),
|
||||||
|
i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < expected.length; i++) {
|
||||||
|
descriptions[i] = describeExpectation(expected[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptions.sort();
|
||||||
|
|
||||||
|
if (descriptions.length > 0) {
|
||||||
|
for (i = 1, j = 1; i < descriptions.length; i++) {
|
||||||
|
if (descriptions[i - 1] !== descriptions[i]) {
|
||||||
|
descriptions[j] = descriptions[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
descriptions.length = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (descriptions.length) {
|
||||||
|
case 1:
|
||||||
|
return descriptions[0];
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return descriptions[0] + " or " + descriptions[1];
|
||||||
|
|
||||||
|
default:
|
||||||
|
return descriptions.slice(0, -1).join(", ")
|
||||||
|
+ ", or "
|
||||||
|
+ descriptions[descriptions.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function describeFound(found) {
|
||||||
|
return found ? "\"" + literalEscape(found) + "\"" : "end of input";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
|
||||||
|
};
|
||||||
|
|
||||||
|
function peg$parse(input, options) {
|
||||||
|
options = options !== void 0 ? options : {};
|
||||||
|
|
||||||
|
var peg$FAILED = {},
|
||||||
|
|
||||||
|
peg$startRuleFunctions = { start: peg$parsestart },
|
||||||
|
peg$startRuleFunction = peg$parsestart,
|
||||||
|
|
||||||
|
peg$c0 = "+",
|
||||||
|
peg$c1 = peg$literalExpectation("+", false),
|
||||||
|
peg$c2 = "-",
|
||||||
|
peg$c3 = peg$literalExpectation("-", false),
|
||||||
|
peg$c4 = function(left, op, right) {
|
||||||
|
return op === "+" ? left + right : left - right;
|
||||||
|
},
|
||||||
|
peg$c5 = "*",
|
||||||
|
peg$c6 = peg$literalExpectation("*", false),
|
||||||
|
peg$c7 = "/",
|
||||||
|
peg$c8 = peg$literalExpectation("/", false),
|
||||||
|
peg$c9 = function(left, op, right) {
|
||||||
|
return op === "*" ? left * right : left / right;
|
||||||
|
},
|
||||||
|
peg$c10 = "(",
|
||||||
|
peg$c11 = peg$literalExpectation("(", false),
|
||||||
|
peg$c12 = ")",
|
||||||
|
peg$c13 = peg$literalExpectation(")", false),
|
||||||
|
peg$c14 = function(expr) { return expr; },
|
||||||
|
peg$c15 = function() { return -factor; },
|
||||||
|
peg$c16 = /^[a-zA-Z_]/,
|
||||||
|
peg$c17 = peg$classExpectation([["a", "z"], ["A", "Z"], "_"], false, false),
|
||||||
|
peg$c18 = /^[a-zA-Z0-9_]/,
|
||||||
|
peg$c19 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_"], false, false),
|
||||||
|
peg$c20 = function(name) { return vars[name.join("")] || 0; },
|
||||||
|
peg$c21 = /^[0-9]/,
|
||||||
|
peg$c22 = peg$classExpectation([["0", "9"]], false, false),
|
||||||
|
peg$c23 = ".",
|
||||||
|
peg$c24 = peg$literalExpectation(".", false),
|
||||||
|
peg$c25 = function() { return parseFloat(text()); },
|
||||||
|
peg$c26 = /^[ \t\r\n]/,
|
||||||
|
peg$c27 = peg$classExpectation([" ", "\t", "\r", "\n"], false, false),
|
||||||
|
|
||||||
|
peg$currPos = 0,
|
||||||
|
peg$savedPos = 0,
|
||||||
|
peg$posDetailsCache = [{ line: 1, column: 1 }],
|
||||||
|
peg$maxFailPos = 0,
|
||||||
|
peg$maxFailExpected = [],
|
||||||
|
peg$silentFails = 0,
|
||||||
|
|
||||||
|
peg$result;
|
||||||
|
|
||||||
|
if ("startRule" in options) {
|
||||||
|
if (!(options.startRule in peg$startRuleFunctions)) {
|
||||||
|
throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
|
||||||
|
}
|
||||||
|
|
||||||
|
function text() {
|
||||||
|
return input.substring(peg$savedPos, peg$currPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
function location() {
|
||||||
|
return peg$computeLocation(peg$savedPos, peg$currPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expected(description, location) {
|
||||||
|
location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
|
||||||
|
|
||||||
|
throw peg$buildStructuredError(
|
||||||
|
[peg$otherExpectation(description)],
|
||||||
|
input.substring(peg$savedPos, peg$currPos),
|
||||||
|
location
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(message, location) {
|
||||||
|
location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
|
||||||
|
|
||||||
|
throw peg$buildSimpleError(message, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$literalExpectation(text, ignoreCase) {
|
||||||
|
return { type: "literal", text: text, ignoreCase: ignoreCase };
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$classExpectation(parts, inverted, ignoreCase) {
|
||||||
|
return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$anyExpectation() {
|
||||||
|
return { type: "any" };
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$endExpectation() {
|
||||||
|
return { type: "end" };
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$otherExpectation(description) {
|
||||||
|
return { type: "other", description: description };
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$computePosDetails(pos) {
|
||||||
|
var details = peg$posDetailsCache[pos], p;
|
||||||
|
|
||||||
|
if (details) {
|
||||||
|
return details;
|
||||||
|
} else {
|
||||||
|
p = pos - 1;
|
||||||
|
while (!peg$posDetailsCache[p]) {
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
|
||||||
|
details = peg$posDetailsCache[p];
|
||||||
|
details = {
|
||||||
|
line: details.line,
|
||||||
|
column: details.column
|
||||||
|
};
|
||||||
|
|
||||||
|
while (p < pos) {
|
||||||
|
if (input.charCodeAt(p) === 10) {
|
||||||
|
details.line++;
|
||||||
|
details.column = 1;
|
||||||
|
} else {
|
||||||
|
details.column++;
|
||||||
|
}
|
||||||
|
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
peg$posDetailsCache[pos] = details;
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$computeLocation(startPos, endPos) {
|
||||||
|
var startPosDetails = peg$computePosDetails(startPos),
|
||||||
|
endPosDetails = peg$computePosDetails(endPos);
|
||||||
|
|
||||||
|
return {
|
||||||
|
start: {
|
||||||
|
offset: startPos,
|
||||||
|
line: startPosDetails.line,
|
||||||
|
column: startPosDetails.column
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
offset: endPos,
|
||||||
|
line: endPosDetails.line,
|
||||||
|
column: endPosDetails.column
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$fail(expected) {
|
||||||
|
if (peg$currPos < peg$maxFailPos) { return; }
|
||||||
|
|
||||||
|
if (peg$currPos > peg$maxFailPos) {
|
||||||
|
peg$maxFailPos = peg$currPos;
|
||||||
|
peg$maxFailExpected = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
peg$maxFailExpected.push(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$buildSimpleError(message, location) {
|
||||||
|
return new peg$SyntaxError(message, null, null, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$buildStructuredError(expected, found, location) {
|
||||||
|
return new peg$SyntaxError(
|
||||||
|
peg$SyntaxError.buildMessage(expected, found),
|
||||||
|
expected,
|
||||||
|
found,
|
||||||
|
location
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$parsestart() {
|
||||||
|
var s0;
|
||||||
|
|
||||||
|
s0 = peg$parseexpression();
|
||||||
|
|
||||||
|
return s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$parseexpression() {
|
||||||
|
var s0, s1, s2, s3, s4, s5;
|
||||||
|
|
||||||
|
s0 = peg$currPos;
|
||||||
|
s1 = peg$parseterm();
|
||||||
|
if (s1 !== peg$FAILED) {
|
||||||
|
s2 = peg$parse_();
|
||||||
|
if (s2 !== peg$FAILED) {
|
||||||
|
if (input.charCodeAt(peg$currPos) === 43) {
|
||||||
|
s3 = peg$c0;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c1); }
|
||||||
|
}
|
||||||
|
if (s3 === peg$FAILED) {
|
||||||
|
if (input.charCodeAt(peg$currPos) === 45) {
|
||||||
|
s3 = peg$c2;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c3); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s3 !== peg$FAILED) {
|
||||||
|
s4 = peg$parse_();
|
||||||
|
if (s4 !== peg$FAILED) {
|
||||||
|
s5 = peg$parseexpression();
|
||||||
|
if (s5 !== peg$FAILED) {
|
||||||
|
peg$savedPos = s0;
|
||||||
|
s1 = peg$c4(s1, s3, s5);
|
||||||
|
s0 = s1;
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
if (s0 === peg$FAILED) {
|
||||||
|
s0 = peg$parseterm();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$parseterm() {
|
||||||
|
var s0, s1, s2, s3, s4, s5;
|
||||||
|
|
||||||
|
s0 = peg$currPos;
|
||||||
|
s1 = peg$parsefactor();
|
||||||
|
if (s1 !== peg$FAILED) {
|
||||||
|
s2 = peg$parse_();
|
||||||
|
if (s2 !== peg$FAILED) {
|
||||||
|
if (input.charCodeAt(peg$currPos) === 42) {
|
||||||
|
s3 = peg$c5;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c6); }
|
||||||
|
}
|
||||||
|
if (s3 === peg$FAILED) {
|
||||||
|
if (input.charCodeAt(peg$currPos) === 47) {
|
||||||
|
s3 = peg$c7;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c8); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s3 !== peg$FAILED) {
|
||||||
|
s4 = peg$parse_();
|
||||||
|
if (s4 !== peg$FAILED) {
|
||||||
|
s5 = peg$parseterm();
|
||||||
|
if (s5 !== peg$FAILED) {
|
||||||
|
peg$savedPos = s0;
|
||||||
|
s1 = peg$c9(s1, s3, s5);
|
||||||
|
s0 = s1;
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
if (s0 === peg$FAILED) {
|
||||||
|
s0 = peg$parsefactor();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$parsefactor() {
|
||||||
|
var s0, s1, s2, s3, s4, s5;
|
||||||
|
|
||||||
|
s0 = peg$currPos;
|
||||||
|
if (input.charCodeAt(peg$currPos) === 40) {
|
||||||
|
s1 = peg$c10;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s1 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c11); }
|
||||||
|
}
|
||||||
|
if (s1 !== peg$FAILED) {
|
||||||
|
s2 = peg$parse_();
|
||||||
|
if (s2 !== peg$FAILED) {
|
||||||
|
s3 = peg$parseexpression();
|
||||||
|
if (s3 !== peg$FAILED) {
|
||||||
|
s4 = peg$parse_();
|
||||||
|
if (s4 !== peg$FAILED) {
|
||||||
|
if (input.charCodeAt(peg$currPos) === 41) {
|
||||||
|
s5 = peg$c12;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s5 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c13); }
|
||||||
|
}
|
||||||
|
if (s5 !== peg$FAILED) {
|
||||||
|
peg$savedPos = s0;
|
||||||
|
s1 = peg$c14(s3);
|
||||||
|
s0 = s1;
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
if (s0 === peg$FAILED) {
|
||||||
|
s0 = peg$currPos;
|
||||||
|
if (input.charCodeAt(peg$currPos) === 45) {
|
||||||
|
s1 = peg$c2;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s1 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c3); }
|
||||||
|
}
|
||||||
|
if (s1 !== peg$FAILED) {
|
||||||
|
s2 = peg$parsefactor();
|
||||||
|
if (s2 !== peg$FAILED) {
|
||||||
|
peg$savedPos = s0;
|
||||||
|
s1 = peg$c15();
|
||||||
|
s0 = s1;
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
if (s0 === peg$FAILED) {
|
||||||
|
s0 = peg$parsevariable();
|
||||||
|
if (s0 === peg$FAILED) {
|
||||||
|
s0 = peg$parsenumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$parsevariable() {
|
||||||
|
var s0, s1, s2, s3;
|
||||||
|
|
||||||
|
s0 = peg$currPos;
|
||||||
|
if (peg$c16.test(input.charAt(peg$currPos))) {
|
||||||
|
s1 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s1 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c17); }
|
||||||
|
}
|
||||||
|
if (s1 !== peg$FAILED) {
|
||||||
|
s2 = [];
|
||||||
|
if (peg$c18.test(input.charAt(peg$currPos))) {
|
||||||
|
s3 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c19); }
|
||||||
|
}
|
||||||
|
while (s3 !== peg$FAILED) {
|
||||||
|
s2.push(s3);
|
||||||
|
if (peg$c18.test(input.charAt(peg$currPos))) {
|
||||||
|
s3 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c19); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s2 !== peg$FAILED) {
|
||||||
|
peg$savedPos = s0;
|
||||||
|
s1 = peg$c20(s1);
|
||||||
|
s0 = s1;
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$parsenumber() {
|
||||||
|
var s0, s1, s2, s3, s4, s5, s6;
|
||||||
|
|
||||||
|
s0 = peg$currPos;
|
||||||
|
if (input.charCodeAt(peg$currPos) === 45) {
|
||||||
|
s1 = peg$c2;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s1 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c3); }
|
||||||
|
}
|
||||||
|
if (s1 === peg$FAILED) {
|
||||||
|
s1 = null;
|
||||||
|
}
|
||||||
|
if (s1 !== peg$FAILED) {
|
||||||
|
s2 = [];
|
||||||
|
if (peg$c21.test(input.charAt(peg$currPos))) {
|
||||||
|
s3 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c22); }
|
||||||
|
}
|
||||||
|
if (s3 !== peg$FAILED) {
|
||||||
|
while (s3 !== peg$FAILED) {
|
||||||
|
s2.push(s3);
|
||||||
|
if (peg$c21.test(input.charAt(peg$currPos))) {
|
||||||
|
s3 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c22); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s2 = peg$FAILED;
|
||||||
|
}
|
||||||
|
if (s2 !== peg$FAILED) {
|
||||||
|
s3 = peg$currPos;
|
||||||
|
if (input.charCodeAt(peg$currPos) === 46) {
|
||||||
|
s4 = peg$c23;
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s4 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c24); }
|
||||||
|
}
|
||||||
|
if (s4 !== peg$FAILED) {
|
||||||
|
s5 = [];
|
||||||
|
if (peg$c21.test(input.charAt(peg$currPos))) {
|
||||||
|
s6 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s6 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c22); }
|
||||||
|
}
|
||||||
|
if (s6 !== peg$FAILED) {
|
||||||
|
while (s6 !== peg$FAILED) {
|
||||||
|
s5.push(s6);
|
||||||
|
if (peg$c21.test(input.charAt(peg$currPos))) {
|
||||||
|
s6 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s6 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c22); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s5 = peg$FAILED;
|
||||||
|
}
|
||||||
|
if (s5 !== peg$FAILED) {
|
||||||
|
s4 = [s4, s5];
|
||||||
|
s3 = s4;
|
||||||
|
} else {
|
||||||
|
peg$currPos = s3;
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s3;
|
||||||
|
s3 = peg$FAILED;
|
||||||
|
}
|
||||||
|
if (s3 === peg$FAILED) {
|
||||||
|
s3 = null;
|
||||||
|
}
|
||||||
|
if (s3 !== peg$FAILED) {
|
||||||
|
peg$savedPos = s0;
|
||||||
|
s1 = peg$c25();
|
||||||
|
s0 = s1;
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
peg$currPos = s0;
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function peg$parse_() {
|
||||||
|
var s0, s1;
|
||||||
|
|
||||||
|
s0 = [];
|
||||||
|
if (peg$c26.test(input.charAt(peg$currPos))) {
|
||||||
|
s1 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s1 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c27); }
|
||||||
|
}
|
||||||
|
while (s1 !== peg$FAILED) {
|
||||||
|
s0.push(s1);
|
||||||
|
if (peg$c26.test(input.charAt(peg$currPos))) {
|
||||||
|
s1 = input.charAt(peg$currPos);
|
||||||
|
peg$currPos++;
|
||||||
|
} else {
|
||||||
|
s1 = peg$FAILED;
|
||||||
|
if (peg$silentFails === 0) { peg$fail(peg$c27); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
peg$result = peg$startRuleFunction();
|
||||||
|
|
||||||
|
if (peg$result !== peg$FAILED && peg$currPos === input.length) {
|
||||||
|
return peg$result;
|
||||||
|
} else {
|
||||||
|
if (peg$result !== peg$FAILED && peg$currPos < input.length) {
|
||||||
|
peg$fail(peg$endExpectation());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw peg$buildStructuredError(
|
||||||
|
peg$maxFailExpected,
|
||||||
|
peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
|
||||||
|
peg$maxFailPos < input.length
|
||||||
|
? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
|
||||||
|
: peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
SyntaxError: peg$SyntaxError,
|
||||||
|
parse: peg$parse
|
||||||
|
};
|
121
src/pages/result/var.vue
Normal file
121
src/pages/result/var.vue
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<div class="dropdown-menu-list" v-if="items.length">
|
||||||
|
<div
|
||||||
|
class="dropdown-item"
|
||||||
|
:class="{ 'is-selected': index === selectedIndex }"
|
||||||
|
v-for="(item, index) in varList"
|
||||||
|
:key="index"
|
||||||
|
@click="selectItem(index)"
|
||||||
|
>
|
||||||
|
<div class="label"> {{ item.text }}</div>
|
||||||
|
<span class="value">{{item.value}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="not-exists" v-else>
|
||||||
|
<span>数据指标不存在</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {getProductValue} from "@/service/use-result-vars.js";
|
||||||
|
import {watch, ref} from "vue";
|
||||||
|
|
||||||
|
const productList = getProductValue();
|
||||||
|
const varList = ref<ResultVarItem[] >([])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
items: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
query:{
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
command: {
|
||||||
|
type: Function,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const selectedIndex = ref(0)
|
||||||
|
|
||||||
|
watch(()=>props.query, () => {
|
||||||
|
selectedIndex.value = 0;
|
||||||
|
if(props.query){
|
||||||
|
varList.value = productList.value.filter(item => (
|
||||||
|
item.value.includes(props.query) || item.label.includes(props.query) || item.text.includes(props.query)
|
||||||
|
)).filter((_,index)=> index < 10)
|
||||||
|
}else{
|
||||||
|
varList.value = productList.value.filter((_,index)=> index < 10)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const upHandler = () => {
|
||||||
|
selectedIndex.value = ((selectedIndex.value + varList.value.length) - 1) % varList.value.length
|
||||||
|
}
|
||||||
|
const downHandler = () => {
|
||||||
|
selectedIndex.value = (selectedIndex.value + 1) % varList.value.length
|
||||||
|
}
|
||||||
|
const enterHandler = () => {
|
||||||
|
selectItem(selectedIndex.value)
|
||||||
|
}
|
||||||
|
const selectItem = (index) => {
|
||||||
|
const item = varList.value[index]
|
||||||
|
if (item) {
|
||||||
|
props.command({id: item.value, label: item.text || item.label})
|
||||||
|
}
|
||||||
|
// selectedIndex.value = index
|
||||||
|
}
|
||||||
|
const onKeyDown = ({event}: { event: { key: string } }) => {
|
||||||
|
if (event.key === 'ArrowUp') {
|
||||||
|
upHandler()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.key === 'ArrowDown') {
|
||||||
|
downHandler()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
enterHandler()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defineExpose({onKeyDown})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* Dropdown menu */
|
||||||
|
.dropdown-menu-list{}
|
||||||
|
.dropdown-menu-list{}
|
||||||
|
.dropdown-menu {
|
||||||
|
@apply bg-white relative overflow-auto flex flex-col shadow rounded border border-gray-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item {
|
||||||
|
@apply w-full p-2 gap-2 bg-transparent flex items-center cursor-pointer justify-between;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:hover.is-selected {
|
||||||
|
@apply bg-gray-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-selected {
|
||||||
|
@apply bg-gray-100;
|
||||||
|
}
|
||||||
|
.label{
|
||||||
|
@apply text-gray-800;
|
||||||
|
}
|
||||||
|
.value{
|
||||||
|
@apply text-gray-300 text-sm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-exists {
|
||||||
|
@apply p-2;
|
||||||
|
}
|
||||||
|
</style>
|
64
src/pages/result/vars.ts
Normal file
64
src/pages/result/vars.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import {VueRenderer} from '@tiptap/vue-3'
|
||||||
|
import tippy from 'tippy.js'
|
||||||
|
|
||||||
|
import vars from './var.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
items: ({query}) => {
|
||||||
|
return ['1,2,3']
|
||||||
|
},
|
||||||
|
|
||||||
|
render: () => {
|
||||||
|
let component
|
||||||
|
let popup
|
||||||
|
|
||||||
|
return {
|
||||||
|
onStart: props => {
|
||||||
|
component = new VueRenderer(vars, {
|
||||||
|
props,
|
||||||
|
editor: props.editor,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!props.clientRect) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
popup = tippy('body', {
|
||||||
|
getReferenceClientRect: props.clientRect,
|
||||||
|
appendTo: () => document.body,
|
||||||
|
content: component.element,
|
||||||
|
showOnCreate: true,
|
||||||
|
interactive: true,
|
||||||
|
trigger: 'manual',
|
||||||
|
placement: 'bottom-start',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onUpdate(props) {
|
||||||
|
component.updateProps(props)
|
||||||
|
|
||||||
|
if (!props.clientRect) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
popup[0].setProps({
|
||||||
|
getReferenceClientRect: props.clientRect,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onKeyDown(props) {
|
||||||
|
if (props.event.key === 'Escape') {
|
||||||
|
popup[0].hide()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 将查询字符透传给组件
|
||||||
|
return component.ref?.onKeyDown?.(props)
|
||||||
|
},
|
||||||
|
|
||||||
|
onExit() {
|
||||||
|
popup[0]?.destroy?.()
|
||||||
|
component?.destroy?.()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
@ -31,6 +31,15 @@ export const routes:RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
component: () => import('./pages/result/index.vue')
|
component: () => import('./pages/result/index.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'ttt',
|
||||||
|
name: 'ttt',
|
||||||
|
meta: {
|
||||||
|
title: '输出计算',
|
||||||
|
icon:'icon-calculator'
|
||||||
|
},
|
||||||
|
component: () => import('./pages/T.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'product-data',
|
path: 'product-data',
|
||||||
name: 'product',
|
name: 'product',
|
||||||
|
@ -1,19 +1,6 @@
|
|||||||
import { sleep } from "@/core/sleep";
|
import { sleep } from "@/core/sleep";
|
||||||
import { post } from "./request";
|
import { post } from "./request";
|
||||||
|
|
||||||
export const ProductCols = [
|
|
||||||
{ id: 1, name: "能量密度", alias: "power" },
|
|
||||||
{ id: 2, name: "蛋白Pro", alias: "protein" },
|
|
||||||
{ id: 3, name: "Glu", alias: "glu" },
|
|
||||||
{ id: 4, name: "Fat", alias: "fat" },
|
|
||||||
{ id: 5, name: "纤维素", alias: "cellulose" },
|
|
||||||
{ id: 6, name: "Na", alias: "na" },
|
|
||||||
{ id: 7, name: "K", alias: "k" },
|
|
||||||
{ id: 8, name: "Ca", alias: "ca" },
|
|
||||||
{ id: 9, name: "P", alias: "p" },
|
|
||||||
{ id: 10, name: "Mg", alias: "mg" },
|
|
||||||
];
|
|
||||||
|
|
||||||
export async function expressionList() {
|
export async function expressionList() {
|
||||||
await sleep(200);
|
await sleep(200);
|
||||||
return await post<DataList<ResultExpression>>(`/result/expression/all`);
|
return await post<DataList<ResultExpression>>(`/result/expression/all`);
|
||||||
|
256
src/service/use-result-vars.ts
Normal file
256
src/service/use-result-vars.ts
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
import {getList} from "@/service/api/product.ts";
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
|
type InputValue = {
|
||||||
|
name: string;
|
||||||
|
key: string;
|
||||||
|
unit?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
type?: string;
|
||||||
|
addition?: {
|
||||||
|
key: string
|
||||||
|
placeholder: string
|
||||||
|
unit?: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"weight": 50,
|
||||||
|
"niaosu": 12,
|
||||||
|
"ruineng": 10,
|
||||||
|
"ruidai": 0,
|
||||||
|
"ruixian": 0,
|
||||||
|
"ruigao": 0,
|
||||||
|
"ruisu": 0,
|
||||||
|
"nengquanli": 0,
|
||||||
|
"kangquanli": 0,
|
||||||
|
"kangquangan": 0,
|
||||||
|
"baipuli": 0,
|
||||||
|
"ailunduo": 0,
|
||||||
|
"weiwo": 0,
|
||||||
|
"jiaweiti": 0,
|
||||||
|
"yilijia": 0,
|
||||||
|
"ruiyixi": 0,
|
||||||
|
"nengquansu": 0,
|
||||||
|
"ansu": 0,
|
||||||
|
"quanansu": 0,
|
||||||
|
"yilijia100": 0,
|
||||||
|
"shui": 0,
|
||||||
|
"anjisuan_ruye": 0,
|
||||||
|
"yilijia100_ruye": 0,
|
||||||
|
"quanansu_ruye": 0,
|
||||||
|
"ansu_ruye": 0,
|
||||||
|
"nengquansu_ruye": 0,
|
||||||
|
"ruqingdanbailiang": 0,
|
||||||
|
"ruianji": 0,
|
||||||
|
"quanyingda": 0,
|
||||||
|
"likawen": 0,
|
||||||
|
"lefanming85": 0,
|
||||||
|
"lefanming114": 0,
|
||||||
|
"anjisuan": 0,
|
||||||
|
"litai": 0,
|
||||||
|
"lineng": 0,
|
||||||
|
"liwen": 0,
|
||||||
|
"youwen": 0,
|
||||||
|
"yingtuolipite20": 0,
|
||||||
|
"yingtuolipite30": 0,
|
||||||
|
"putaotangluhuana5": 0,
|
||||||
|
"putaotang5": 0,
|
||||||
|
"putaotang10": 0,
|
||||||
|
"putaotang50": 0,
|
||||||
|
"luhuana09": 0,
|
||||||
|
"luhuana10": 0,
|
||||||
|
"geliefusi": 0,
|
||||||
|
"luhuajia": 0,
|
||||||
|
"baidanbai": 0
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
const inputList: InputValue[] = [
|
||||||
|
{name: '体重', key: 'weight',},
|
||||||
|
{name: '24h尿素', key: 'niaosu',},
|
||||||
|
// 肠内制剂
|
||||||
|
{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 function getInputValue() {
|
||||||
|
const list: ResultVarItem[] = [];
|
||||||
|
inputList.forEach(item => {
|
||||||
|
|
||||||
|
if (item.addition) {
|
||||||
|
const additionExt = item.addition.placeholder || item.addition.unit
|
||||||
|
list.push({
|
||||||
|
label: `${item.name}${additionExt ? '-' + additionExt : ''}`,
|
||||||
|
text: `${item.name}${additionExt ? '-' + additionExt : ''}`,
|
||||||
|
value: `input.${item.addition.key}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const ext = item.placeholder || item.unit
|
||||||
|
list.push({
|
||||||
|
label: `${item.name}${ext ? '-' + ext : ''}`,
|
||||||
|
text: `${item.name}${ext ? '-' + ext : ''}`,
|
||||||
|
value: `input.${item.key}`,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
const ValueKeys = [
|
||||||
|
'power',
|
||||||
|
'protein',
|
||||||
|
'glu',
|
||||||
|
'fat',
|
||||||
|
'cellulose',
|
||||||
|
'na',
|
||||||
|
'k',
|
||||||
|
'ca',
|
||||||
|
'p',
|
||||||
|
'mg',
|
||||||
|
]
|
||||||
|
|
||||||
|
export function getAllProduct() {
|
||||||
|
const list = ref<{
|
||||||
|
[key: string]: ProductInfoModel
|
||||||
|
}>([])
|
||||||
|
getList({
|
||||||
|
page: 1,
|
||||||
|
limit: 10000
|
||||||
|
}).then(res => {
|
||||||
|
const data: {
|
||||||
|
[key: string]: ProductInfoModel
|
||||||
|
} = {}
|
||||||
|
res.list.forEach(it => {
|
||||||
|
data[it.alias] = it;
|
||||||
|
})
|
||||||
|
list.value = data
|
||||||
|
});
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProductValue() {
|
||||||
|
const list = ref<ResultVarItem[]>(getInputValue())
|
||||||
|
|
||||||
|
getList({
|
||||||
|
page: 1,
|
||||||
|
limit: 10000
|
||||||
|
}).then(res => {
|
||||||
|
const _list: ResultVarItem[] = [];
|
||||||
|
res.list.forEach(it => {
|
||||||
|
ValueKeys.forEach(key => {
|
||||||
|
const label = `${it.name}-${key}`
|
||||||
|
_list.push({
|
||||||
|
label,
|
||||||
|
value: `${it.alias}.${key}`,
|
||||||
|
text: label,
|
||||||
|
})
|
||||||
|
// _list.push({
|
||||||
|
// label: `${it.name}.${key}`,
|
||||||
|
// value: `${it.alias}.${key}`,
|
||||||
|
// text: label,
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
list.value = [
|
||||||
|
...list.value,
|
||||||
|
..._list,
|
||||||
|
];
|
||||||
|
})
|
||||||
|
return list;
|
||||||
|
}
|
@ -62,7 +62,6 @@ export const useUserStore = defineStore('counter', () => {
|
|||||||
console.log('401 show login')
|
console.log('401 show login')
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
console.log('onMounted inited')
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
userInit.value = true
|
userInit.value = true
|
||||||
}, 500)
|
}, 500)
|
||||||
|
23
src/types/product.d.ts
vendored
23
src/types/product.d.ts
vendored
@ -34,4 +34,25 @@ declare type ResultExpression = {
|
|||||||
created_at: Date | string;
|
created_at: Date | string;
|
||||||
updated_at: Date | string;
|
updated_at: Date | string;
|
||||||
status: number;
|
status: number;
|
||||||
}
|
}
|
||||||
|
declare type ResultVarItem = {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
text?: string;
|
||||||
|
}
|
||||||
|
declare type TiptapContentValue = {
|
||||||
|
type:string;
|
||||||
|
content: {
|
||||||
|
type:string;
|
||||||
|
content: ExpressionValue[];
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExpressionValue {
|
||||||
|
type: 'text'|'mention';
|
||||||
|
attrs: {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
@ -509,6 +509,11 @@
|
|||||||
prosemirror-transform "^1.10.2"
|
prosemirror-transform "^1.10.2"
|
||||||
prosemirror-view "^1.37.0"
|
prosemirror-view "^1.37.0"
|
||||||
|
|
||||||
|
"@tiptap/suggestion@^2.10.4":
|
||||||
|
version "2.10.4"
|
||||||
|
resolved "https://registry.npmmirror.com/@tiptap/suggestion/-/suggestion-2.10.4.tgz#732320b65bc55bcc2a33a8f32072f9478ffb7436"
|
||||||
|
integrity sha512-7Bzcn1REA7OmVRxiMF2kVK9EhosXotdLAGaEvSbn4zQtHCJG0tREuYvPy53LGzVuPkBDR6Pf6sp1QbGvSne/8g==
|
||||||
|
|
||||||
"@tiptap/vue-3@^2.10.4":
|
"@tiptap/vue-3@^2.10.4":
|
||||||
version "2.10.4"
|
version "2.10.4"
|
||||||
resolved "https://registry.npmmirror.com/@tiptap/vue-3/-/vue-3-2.10.4.tgz#9d44e4191d6e512673e44f760aceb909dd568132"
|
resolved "https://registry.npmmirror.com/@tiptap/vue-3/-/vue-3-2.10.4.tgz#9d44e4191d6e512673e44f760aceb909dd568132"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user