Pārlūkot izejas kodu

基本完成页面编辑配置,准备引入 npm install monaco-editor

xiaochan 2 gadi atpakaļ
vecāks
revīzija
bdf352afed

+ 169 - 38
src/components/query-components/XcQuery.vue

@@ -2,28 +2,45 @@
   <el-form ref=formRef
            :rules="rules"
            :model="props.testJson.queryParam"
-           :inline="testJson.inline || true">
-    <el-form-item :label="value.label"
-                  :prop="value.key"
-                  @click="itemClick(value,key)"
-                  v-for="(value,key) in testJson.header">
-      <component
-          v-model="testJson.queryParam[value.key]"
-          v-bind="value.bind"
-          :remote-method="(val)=> {remoteMethod(val,value)}"
-          :style="{width: value.width + 'px' }"
-          :is="el[value.name]">
-        <template v-if="value.selectData && value.name ==='ElSelect'">
-          <el-option :label="select.label"
-                     :value="select.value"
-                     v-for="select in value.selectData"/>
-        </template>
-        <template v-if="value.text">
-          {{ value.text }}
-        </template>
-
-      </component>
-    </el-form-item>
+           :inline="testJson.formConfig.inline || true">
+    <div v-for="(value,key) in testJson.header"
+         style="display:inline-block;"
+         @click="itemClick(value,key)"
+         :class="formItemClass(key)">
+      <div v-if="props.currentIndex === key" class="tool">
+        <div class="tool_item" @click="upClick(key)">
+          <el-icon>
+            <ArrowLeft/>
+          </el-icon>
+        </div>
+        <div class="tool_item" @click="downClick(key)">
+          <el-icon>
+            <ArrowRight/>
+          </el-icon>
+        </div>
+        <div class="tool_item" @click="delClick(key)">
+          <el-icon>
+            <DeleteFilled/>
+          </el-icon>
+        </div>
+      </div>
+      <el-form-item :label="value.label"
+                    :prop="value.key">
+        <component
+            v-model="testJson.queryParam[value.key]"
+            v-bind="value.bind"
+            :is="el[value.name]">
+          <template v-if="value.selectData && value.name ==='ElSelect'">
+            <el-option :label="select.label"
+                       :value="select.value"
+                       v-for="select in value.selectData"/>
+          </template>
+          <template v-if="value.text">
+            {{ value.text }}
+          </template>
+        </component>
+      </el-form-item>
+    </div>
     <el-form-item>
       <el-button icon="Search" type="primary" @click="submit">查询</el-button>
       <el-button icon="RefreshLeft" @click="formReset">重置</el-button>
@@ -34,19 +51,25 @@
 <script setup lang="ts">
 import * as el from "element-plus";
 import {FormInstance, FormRules} from "element-plus";
-import {onMounted, ref} from 'vue'
+import {nextTick, onMounted, ref, watch} from 'vue'
 import XEUtils from 'xe-utils'
 import {componentType, headerType} from "./page-help-type";
 import {useVModel} from "@vueuse/core";
-import {watch} from "@vue/runtime-core";
-import {callAxios} from "../../components/query-components/page-help";
-
+import {getFormatDatetime, currentAndAFewDaysAgo, getDateRangeFormatDate} from '../../utils/date'
+import moment from 'moment'
+import axios from "axios";
 
 const props = defineProps<{
-  testJson: componentType
+  testJson: componentType,
+  currentIndex: number
 }>()
 
-const emits = defineEmits(['submit', 'itemClick'])
+const emits = defineEmits([
+  'submit',
+  'itemClick',
+  'update:currentIndex',
+  'delClick'
+])
 
 const formRef = ref<FormInstance | null>(null)
 const paramType = new Map<string, any>()
@@ -57,10 +80,7 @@ const queryParam = ref({})
 let tempQuerySql = ''
 
 const testJson = useVModel(props, 'testJson', emits)
-
-watch(() => testJson.value, async () => {
-  intiRules()
-}, {deep: true})
+const propsCurrentIndex = useVModel(props, 'currentIndex', emits)
 
 function replaceTheContent(str) {
   if (!str) return
@@ -120,12 +140,46 @@ const submit = async () => {
     tempQuerySql = testJson.value.querySql
     countIfTags(tempQuerySql)
   }
+
+  let tempData = {}
+
+  testJson.value.header.forEach((item) => {
+    if (isDateRange(item)) {
+      let {startTime, endTime} = getDateRangeFormatDate(testJson.value.queryParam[item.key])
+      tempData[item.dataRange.startAlias] = startTime
+      tempData[item.dataRange.endAlias] = endTime
+    } else {
+      tempData[item.key] = testJson.value.queryParam[item.key]
+    }
+  })
+
+  console.log('查询条件', tempData)
   emits('submit', testJson.value.queryParam)
 }
 
+const isDateRange = (item: headerType) => {
+  return item.name === 'ElDatePicker' && item.bind.type && item.bind.type === 'daterange'
+}
+
+
 const dataReset = () => {
-  headerFor((item, key) => {
-    testJson.value.queryParam[item.key] = item.defaultValue
+  headerFor(async (item, key) => {
+    if (isDateRange(item)) {
+      switch (item.dataRange.defaultValue) {
+        case '1':
+          let temp = getFormatDatetime(new Date, item.bind.valueFormat)
+          testJson.value.queryParam[item.key] = [temp, temp]
+          break;
+        case '2':
+          testJson.value.queryParam[item.key] = await currentAndAFewDaysAgo(item.dataRange.minusDays, item.bind.valueFormat)
+          break
+        case '3':
+          testJson.value.queryParam[item.key] = [moment().startOf('month').format('YYYY-MM-DD'), moment().endOf('month').format('YYYY-MM-DD')]
+          break;
+      }
+    } else {
+      testJson.value.queryParam[item.key] = item.defaultValue
+    }
   })
 }
 
@@ -153,17 +207,94 @@ const itemClick = (data, key) => {
   emits('itemClick', data, key)
 }
 
-const remoteMethod = async (val, key: headerType) => {
-  let {networkRequests} = key
-  if (networkRequests && networkRequests.url) {
-    key.bind.options = await callAxios(testJson.value, key, val)
+const formItemClass = (index) => {
+  if (index === props.currentIndex) {
+    return 'activation_item'
+  }
+}
+
+const upClick = (key) => {
+  if (key === 0) return
+  swapItems(testJson.value.header, key, key - 1)
+  propsCurrentIndex.value = key - 1
+}
+
+const swapItems = (arr, currentIndex, newIndex) => {
+  arr[currentIndex] = arr.splice(newIndex, 1, arr[currentIndex])[0]
+  return arr
+}
+
+const downClick = (key) => {
+  if (key === testJson.value.header.length - 1) return
+  swapItems(testJson.value.header, key, key + 1)
+  propsCurrentIndex.value = key + 1
+}
+
+const delClick = async (key) => {
+  await emits('delClick')
+  await nextTick()
+  testJson.value.header.splice(key, 1)
+  propsCurrentIndex.value = -1
+}
+
+const initAttribute = () => {
+  let data = {
+    pageJson: testJson.value,
+    axios: axios
   }
+
+  headerFor((item) => {
+    if (item.bind) {
+      for (const key in item.bind) {
+        if (key.startsWith("_")) {
+          let tempKey = key.substr(1);
+          item.bind[tempKey] = (val) => {
+            let func = new Function('value', 'data', '...val', "return " + item.bind[key])
+            func()(item, data, val)
+          }
+        }
+      }
+    }
+  })
 }
 
+watch(() => testJson.value.header.length, () => {
+  dataReset()
+  intiRules()
+  initAttribute()
+}, {deep: true})
+
 onMounted(() => {
   dataReset()
   intiRules()
+  initAttribute()
   console.log(el)
 })
 
 </script>
+
+<style lang="scss">
+.activation_item {
+  border: 1px solid #000;
+  position: relative;
+  display: inline-block;
+}
+
+.tool {
+  width: inherit;
+  height: inherit;
+  z-index: 99;
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  display: flex;
+
+  div {
+    padding: 0 5px;
+    border: 1px solid #0000fa;
+    display: flex;
+    align-items: center;
+    cursor: pointer;
+  }
+}
+</style>

+ 25 - 3
src/components/query-components/page-help-type.ts

@@ -22,7 +22,11 @@ export interface headerType {
     key: string,
     // el 组件的名称
     name: string
-    bind?: any,
+    bind?: any | {
+        style: {
+            width?: string
+        }
+    },
     // 在 el 的组件中文本值
     text?: string
     // el-from 中的 label
@@ -37,13 +41,31 @@ export interface headerType {
     rules?: Arrayable<FormItemRule>
     width?: number
     networkRequests?: networkRequests
+    // 初始化就执行的代码
+    init?: string
+    // 日期附加信息
+    dataRange?: {
+        startAlias: string,
+        endAlias: string
+        defaultValue: string
+        minusDays?: number
+    },
+}
+
+interface formConfig {
+    inline?: boolean,
+    labelPosition?: 'left' | 'right' | 'top'
+    labelWidth?: number
+    labelSuffix?: string,
 }
 
 export interface componentType {
     header: headerType[]
     querySql: string,
-    inline?: boolean
-    queryParam: any
+    queryParam: any,
+    formConfig: formConfig,
+    // 点击提交时候触发的值
+    submitEvent?: string,
 }
 
 

+ 91 - 36
src/components/query-components/page-help.ts

@@ -1,4 +1,4 @@
-import {componentType, elComponentType, headerType, networkRequests} from "./page-help-type";
+import {componentType, elComponentType, headerType} from "./page-help-type";
 import axios from "axios";
 
 export const collapseData: {
@@ -17,6 +17,11 @@ export const collapseData: {
                 keyType: "string",
                 defaultValue: '',
                 required: false,
+                bind: {
+                    style: {
+                        width: null
+                    },
+                },
             },
             {
                 key: '',
@@ -25,6 +30,11 @@ export const collapseData: {
                 keyType: 'number',
                 defaultValue: 0,
                 required: false,
+                bind: {
+                    style: {
+                        width: null
+                    },
+                }
             }
         ]
     }, {
@@ -39,7 +49,11 @@ export const collapseData: {
                 defaultValue: '',
                 required: false,
                 selectData: [],
-                bind: {}
+                bind: {
+                    style: {
+                        width: null
+                    },
+                },
             },
             {
                 key: '',
@@ -49,10 +63,44 @@ export const collapseData: {
                 defaultValue: '',
                 required: false,
                 bind: {
+                    style: {
+                        width: null
+                    },
                     options: [],
                     remote: true,
                     filterable: true,
+                    _remoteMethod: `async function (value, data, ...val) {
+                        let {pageJson, axios} = data
+                        value.bind.loading = true
+                        let tempData = {}
+                        let net = value.networkRequests
+
+                        net.params.forEach(item => {
+                            if (item.queryValue) {
+                                tempData[item.queryName] = pageJson.queryParam[item.queryValue]
+                            } else {
+                                tempData[item.queryName] = val[0]
+                            }
+                        })
+
+                        try {
+                            let res = await axios({
+                                method: net.method,
+                                url: net.url,
+                                params: tempData,
+                                data: tempData
+                            })
+
+                            let a = new Function('res', 'return res.' + net.returnsVolumeResolutionDetail)
+                            value.bind.options = a(res)
+                        } catch (e) {
+                            value.bind.options = []
+                        }
+                            
+                        value.bind.loading = false
+                    }`
                 },
+                // f64e8d769e5149fe88ce5dbb84326235
                 networkRequests: {
                     method: 'get',
                     url: '/bdp/dataservice/api/f64e8d769e5149fe88ce5dbb84326235',
@@ -62,6 +110,37 @@ export const collapseData: {
                 }
             }
         ]
+    }, {
+        title: '日期',
+        name: '3',
+        children: [
+            {
+                key: '',
+                name: 'ElDatePicker',
+                label: '日期范围选择',
+                keyType: 'string',
+                defaultValue: '',
+                required: false,
+                bind: {
+                    style: {
+                        width: null
+                    },
+                    type: "daterange",
+                    rangeSeparator: "至",
+                    startPlaceholder: "开始时间",
+                    endPlaceholder: "结束时间",
+                    valueFormat: "YYYY-MM-DD",
+                    format: "YYYY-MM-DD",
+                    clearable: true,
+                },
+                dataRange: {
+                    startAlias: 'startTime',
+                    endAlias: 'endTime',
+                    defaultValue: '',
+                    minusDays: 0
+                }
+            }
+        ]
     }
 ]
 
@@ -174,6 +253,16 @@ export const elComponent: elComponentType = {
             url: '',
             requestInterfaced: '创智中台',
         }
+    },
+    ElDatePicker: {
+        bind: {
+            clearable: {
+                label: '可删',
+                renderName: 'boolean',
+                defaultValue: false,
+            }
+        },
+
     }
 }
 
@@ -186,37 +275,3 @@ export function generateRandomString(length): string {
     }
     return result;
 }
-
-export async function callAxios(data: componentType, currentFunc: headerType, query = '') {
-    let tempData = {}
-
-    let net = currentFunc.networkRequests
-
-    net.params.forEach(item => {
-        if (item.queryValue) {
-            tempData[item.queryName] = data.queryParam[item.queryValue]
-        } else {
-            tempData[item.queryName] = query
-        }
-    })
-
-
-    let res
-    try {
-        res = await axios({
-            method: net.method,
-            url: net.url,
-            params: tempData
-        })
-    } catch {
-        return []
-    }
-
-    let a = new Function('res', 'return res.' + net.returnsVolumeResolutionDetail)
-    return a(res)
-}
-
-
-
-
-

+ 2 - 0
src/components/zhu-yuan-yi-sheng/yi-zhu-lu-ru/yz-edit/YzEditor.vue

@@ -528,8 +528,10 @@ const jiSuanLingLiang = async (val) => {
     return;
   }
   let drugQuanA = Math.ceil(Dig.division(val, jiLiangValue.value))
+  console.log('领量', drugQuanA, Dig.division(val, jiLiangValue.value))
   if (yiZhuData.value.serial === '99') {
     drugQuanA = Math.ceil(Dig.division(drugQuanA, yiZhuData.value.packSize))
+    console.log('大包装 %o ,除以%o,包装规格%o', drugQuanA, Dig.division(drugQuanA, yiZhuData.value.packSize), yiZhuData.value.packSize)
   }
   yiZhuData.value.drugQuan = drugQuanA;
 }

+ 32 - 11
src/views/utilities/page-editor-help/PageEditorHelp.vue

@@ -4,39 +4,49 @@ import {collapseData, generateRandomString} from "../../../components/query-comp
 import XcQuery from "../../../components/query-components/XcQuery.vue";
 import {componentType, headerType} from "../../../components/query-components/page-help-type";
 import PageEditotInfo from "./PageEditotInfo.vue";
+import {clone} from "xe-utils";
+import PageForm from "@/views/utilities/page-editor-help/PageForm.vue";
 
 
-const activeNames = ref(['1', '2'])
+const activeNames = ref(['1', '2', '3'])
 const infoRef = ref()
+const tabs = ref('form')
 
 const addEl = (val: headerType) => {
+
   let key = generateRandomString(5)
   let data = val
   if (!val.bind) {
     data['bind'] = {}
   }
   data.key = key
-  pageJson.value.header.push(data)
+
+  pageJson.value.header.push(clone(data, true))
   pageJson.value.queryParam[key] = val.defaultValue
 }
 
 const pageJson = ref<componentType>({
   header: [],
   querySql: "",
-  queryParam: {}
+  queryParam: {},
+  formConfig: {
+    inline: true
+  },
+  submitEvent: null
 })
 
-const theCurrentComponent = ref('')
+const theCurrentComponent = ref(-1)
 const itemClick = (data: headerType, index) => {
   infoRef.value.editComp(data)
   theCurrentComponent.value = index
 }
 
 onMounted(() => {
-  addEl(collapseData[0].children[0])
-  addEl(collapseData[0].children[1])
-  addEl(collapseData[1].children[0])
+  // addEl(collapseData[0].children[0])
+  // addEl(collapseData[0].children[1])
+  // addEl(collapseData[1].children[0])
   addEl(collapseData[1].children[1])
+  addEl(collapseData[2].children[0])
 })
 
 </script>
@@ -65,12 +75,23 @@ onMounted(() => {
         <template #default="{ height, width }">
           <div style="display: flex; overflow-y: auto" :style="{height: height -50 +'px'}">
             <div style="flex: 1; box-sizing: border-box">
-              <xc-query v-model:testJson="pageJson" @item-click="itemClick"/>
+              <xc-query v-model:testJson="pageJson"
+                        @delClick="infoRef.setShow(false)"
+                        v-model:current-index="theCurrentComponent"
+                        @item-click="itemClick"/>
             </div>
             <div class="right_box">
-              <page-editot-info ref="infoRef"
-                                :page-json="pageJson"
-                                v-model:data="pageJson.header[theCurrentComponent]"/>
+              <el-tabs v-model="tabs">
+                <el-tab-pane label="组件配置" name="subassembly">
+                  <page-editot-info ref="infoRef"
+                                    :page-json="pageJson"
+                                    v-model:data="pageJson.header[theCurrentComponent]"/>
+                </el-tab-pane>
+                <el-tab-pane label="表单配置" name="form">
+                  <page-form :page-json="pageJson"/>
+                </el-tab-pane>
+              </el-tabs>
+
             </div>
           </div>
         </template>

+ 70 - 35
src/views/utilities/page-editor-help/PageEditotInfo.vue

@@ -1,11 +1,12 @@
 <script setup lang="ts">
 import {defineExpose, ref, h} from 'vue'
-import {callAxios, elComponent} from "../../../components/query-components/page-help";
+import {elComponent} from "../../../components/query-components/page-help";
 import {useVModel} from "@vueuse/core";
 import {bindType, componentType, CompType, headerType} from "../../../components/query-components/page-help-type";
 import XEUtils from "xe-utils";
 import {ElInput, ElOption, ElSelect, ElSwitch} from 'element-plus'
 import * as el from 'element-plus'
+import XcElOption from "../../../components/xiao-chan/xc-el-option/XcElOption.vue";
 
 const props = defineProps<{
   data: headerType,
@@ -26,6 +27,10 @@ const editComp = (data: headerType) => {
   show.value = true
 }
 
+const setShow = (val) => {
+  show.value = val
+}
+
 
 const selectRender = (data: bindType, key) => {
   let optionList = [];
@@ -88,6 +93,10 @@ const isSelectV2 = () => {
   return dataVal.value['name'] === 'ElSelectV2'
 }
 
+const isDateRange = () => {
+  return dataVal.value.name === 'ElDatePicker' && dataVal.value.bind.type === 'daterange'
+}
+
 const addSelectData = () => {
   dataVal.value['selectData'].push({
     value: '',
@@ -107,11 +116,6 @@ const interfaceDisplay = ref({
   data: []
 })
 
-const callTheInterface = async () => {
-  interfaceDisplay.value.dialog = true
-  interfaceDisplay.value.data = await callAxios(props.pageJson, dataVal.value)
-}
-
 const clearSelectData = () => {
   if (dataVal.value['bind'].multiple) {
     dataVal.value['defaultValue'] = []
@@ -147,9 +151,16 @@ const changeInterFaced = (val) => {
   dataVal.value.networkRequests.returnsVolumeResolutionDetail = interFaced[val]()
 }
 
+const dateDefaultValue = [
+  {code: '1', name: '当前'},
+  {code: '2', name: '几天前'},
+  {code: '3', name: '本月'},
+]
+
 
 defineExpose({
-  editComp
+  editComp,
+  setShow
 })
 
 </script>
@@ -164,41 +175,39 @@ defineExpose({
     </div>
   </el-dialog>
 
-  <el-form label-width="80px">
+  <el-form label-width="80px" v-if="show">
 
-    <template v-if="show">
-      <el-divider content-position="center">
-        基本设置
-      </el-divider>
+    <el-divider content-position="center">
+      基本设置
+    </el-divider>
 
-      <el-form-item label="唯一名称 ">
-        <el-input v-model="dataVal.key"/>
-      </el-form-item>
+    <el-form-item label="唯一名称 ">
+      <el-input v-model="dataVal.key"/>
+    </el-form-item>
 
-      <el-form-item label="前缀">
-        <el-input v-model="dataVal['label']"/>
-      </el-form-item>
+    <el-form-item label="前缀">
+      <el-input v-model="dataVal['label']"/>
+    </el-form-item>
 
-      <el-form-item label="默认值"
-                    v-if="!isSelect() && !isSelectV2()">
-        <el-input
-            v-model="dataVal.defaultValue"
-            v-if="XEUtils.isString(dataVal.defaultValue)"
-        />
-        <el-input-number v-model="dataVal.defaultValue"
-                         v-if="XEUtils.isNumber(dataVal.defaultValue)"/>
+    <el-form-item label="默认值"
+                  v-if="!isSelect() && !isSelectV2() && !isDateRange()">
+      <el-input
+          v-model="dataVal.defaultValue"
+          v-if="XEUtils.isString(dataVal.defaultValue)"
+      />
+      <el-input-number v-model="dataVal.defaultValue"
+                       v-if="XEUtils.isNumber(dataVal.defaultValue)"/>
 
-      </el-form-item>
+    </el-form-item>
 
-      <el-form-item label="必填">
-        <el-switch v-model="dataVal.required"/>
-      </el-form-item>
+    <el-form-item label="必填">
+      <el-switch v-model="dataVal.required"/>
+    </el-form-item>
 
-      <el-form-item label="宽度:">
-        <el-input-number v-model="dataVal.width"/>
-      </el-form-item>
+    <el-form-item label="宽度:">
+      <el-input v-model="dataVal.bind.style.width"/>
+    </el-form-item>
 
-    </template>
 
     <template v-if="comp.bind">
       <el-divider content-position="center">
@@ -289,11 +298,37 @@ defineExpose({
 
           <div style="  margin-top:5px">
             <el-button text type="primary" @click="addNetParams">新增</el-button>
-            <el-button text type="primary" @click="callTheInterface">测试调用</el-button>
           </div>
         </el-form-item>
 
       </template>
+
+      <template v-if="isDateRange()">
+        <el-divider content-position="center">
+          其他
+        </el-divider>
+
+        <el-form-item label="默认值">
+          <el-select v-model="dataVal.dataRange.defaultValue" :clearable="true">
+            <xc-el-option :data="dateDefaultValue"/>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="开始别名">
+          <el-input v-model="dataVal.dataRange.startAlias"/>
+        </el-form-item>
+
+        <el-form-item label="结束别名">
+          <el-input v-model="dataVal.dataRange.endAlias"/>
+        </el-form-item>
+
+        <el-form-item label="几天前" v-if="dataVal.dataRange.defaultValue === '2'">
+          <el-input-number v-model="dataVal.dataRange.minusDays"/>
+        </el-form-item>
+
+      </template>
+
+
     </template>
   </el-form>
 </template>

+ 27 - 0
src/views/utilities/page-editor-help/PageForm.vue

@@ -0,0 +1,27 @@
+<script setup lang="ts">
+import {defineProps, ref} from 'vue'
+import {componentType} from "../../../components/query-components/page-help-type";
+
+const props = defineProps<{
+  pageJson: componentType
+}>()
+
+const collapse = ref(['1'])
+
+</script>
+
+<template>
+  <el-form label-width="150px" label-position="left">
+    <el-collapse v-model="collapse"  >
+      <el-collapse-item title="事件属性" name="1">
+        <el-form-item label="提交事件">
+          <el-button type="info" icon="Edit" round plain>编写代码</el-button>
+        </el-form-item>
+      </el-collapse-item>
+    </el-collapse>
+  </el-form>
+</template>
+
+<style lang="scss">
+
+</style>