Yue 2 лет назад
Родитель
Сommit
6e7f11e074

+ 3 - 0
UI/VA.Vue_V1.0/.eslintrc-auto-import.json

@@ -5,6 +5,9 @@
     "ComponentPublicInstance": true,
     "ComputedRef": true,
     "EffectScope": true,
+    "ElInput": true,
+    "ElSelect": true,
+    "ElTreeSelect": true,
     "InjectionKey": true,
     "JwtService": true,
     "LayoutService": true,

+ 3 - 6
UI/VA.Vue_V1.0/src/components/dict/DictSelect.vue

@@ -7,6 +7,7 @@ const props = withDefaults(
     dictType: string
     placeholder?: string
     type?: "select" | "checkbox" | "radio"
+    listeners?: any
   }>(),
   {
     placeholder: "请选择",
@@ -28,12 +29,6 @@ function onChange(v: any) {
 
 function getData() {
   return appStore.dictStore.getDict(props.dictType)
-  // return new Promise((r) => {
-  //   appStore.dictStore.getDict(props.dictType).then((res: any) => {
-  //     console.log("---", res)
-  //     r(res)
-  //   })
-  // })
 }
 </script>
 <template>
@@ -44,5 +39,7 @@ function getData() {
     :need-formate="false"
     :placeholder="placeholder"
     @change="onChange"
+    :listeners="listeners"
+    v-bind="$attrs"
   ></vb-select>
 </template>

+ 160 - 43
UI/VA.Vue_V1.0/src/components/form/VbFormItem.vue

@@ -22,8 +22,11 @@ const props = withDefaults(
 )
 const emits = defineEmits<{ (e: "update:data", v: any): void }>()
 const { item } = toRefs(props)
-const itemDataOptions = computed(() => {
-  return item.value.data
+const itemId = computed(() => {
+  return typeof item.value.id == "function" ? item.value.id() : item.value.id
+})
+const itemData = computed(() => {
+  return typeof item.value.data == "function" ? item.value.data() : item.value.data
 })
 const isShow = computed(() => {
   if (props.item.show == undefined) {
@@ -76,7 +79,13 @@ const getRules = (item: VbFormItem): Array<FormItemRule> => {
   return _rules
 }
 function checkComponent(name: string) {
-  return (props.item.component as any).name == name
+  // if (!props.item?.component && name == "I") {
+  //   return true
+  // }
+  const component = props.item?.component || "I"
+  return typeof component == "string"
+    ? component.toLocaleUpperCase() == name.toLocaleUpperCase()
+    : (component as any).name == name
 }
 function isDisable(item: any) {
   if (typeof item.disabled == "function") {
@@ -106,60 +115,168 @@ onMounted(() => {
       "
       v-bind="item.itemProps"
     >
-      <slot v-if="item.component === 'slot'" :name="item.field"></slot>
-      <div v-else-if="item.component === 'innerText'" :class="item.class" :style="item.style">
+      <slot v-if="checkComponent('slot')" :name="item.field"></slot>
+      <div
+        v-else-if="checkComponent('text') || checkComponent('innerText')"
+        :id="itemId"
+        :class="item.class"
+        :style="item.style"
+      >
         {{ item.innerText || data[item.field] }}
       </div>
+      <template v-else-if="checkComponent('I') || checkComponent('ElInput')">
+        <el-input
+          v-model="data[item.field]"
+          :id="itemId"
+          :required="item.required"
+          :type="item.type || 'text'"
+          :class="item.class"
+          :style="item.style"
+          :placeholder="item.placeholder ?? item.label"
+          :size="item.size"
+          v-bind="item.props"
+          v-on="item.listeners"
+        ></el-input>
+      </template>
+      <template v-else-if="checkComponent('VS') || checkComponent('VbSelect')">
+        <vb-select
+          v-model="data[item.field]"
+          :id="itemId"
+          :type="((item.type  || 'select') as any)"
+          :required="item.required"
+          :class="item.class"
+          :style="item.style"
+          :placeholder="item.placeholder ?? item.label"
+          :size="item.size"
+          :data="itemData"
+          v-bind="item.props"
+          v-on="item.listeners"
+        ></vb-select>
+      </template>
+      <template v-else-if="checkComponent('Dict') || checkComponent('DictSelect')">
+        <dict-select
+          v-model="data[item.field]"
+          :id="itemId"
+          :dictType="item.props?.dictType || ''"
+          :type="((item.type  || 'select') as any)"
+          :required="item.required"
+          :class="item.class"
+          :style="item.style"
+          :placeholder="item.placeholder ?? item.label"
+          :size="item.size"
+          v-bind="item.props"
+          v-on="item.listeners"
+        ></dict-select>
+      </template>
+      <template v-else-if="checkComponent('S') || checkComponent('ElSelect')">
+        <el-select
+          v-model="data[item.field]"
+          :id="itemId"
+          :required="item.required"
+          :class="item.class"
+          :style="item.style"
+          :placeholder="item.placeholder ?? item.label"
+          :size="item.size"
+          v-bind="item.props"
+          v-on="item.listeners"
+        >
+          <el-option
+            v-for="(select, selectIndex) in itemData"
+            :key="selectIndex"
+            :value="select.value"
+            :label="select.label"
+            :class="select.class"
+            :disabled="isDisable(select)"
+            :style="select.style"
+          ></el-option>
+        </el-select>
+      </template>
+      <template v-else-if="checkComponent('R') || checkComponent('ElRadioGroup')">
+        <el-radio-group
+          v-model="data[item.field]"
+          :id="itemId"
+          :required="item.required"
+          :class="item.class"
+          :style="item.style"
+          :size="item.size"
+          v-bind="item.props"
+          v-on="item.listeners"
+        >
+          <el-radio
+            v-for="(radio, radioIndex) in itemData"
+            :key="radioIndex"
+            :label="radio.value"
+            :class="radio.class"
+            :style="radio.style"
+            :disabled="isDisable(radio)"
+          >
+            {{ radio.label }}
+          </el-radio>
+        </el-radio-group>
+      </template>
+      <template v-else-if="checkComponent('C') || checkComponent('ElCheckboxGroup')">
+        <el-checkbox-group
+          v-model="data[item.field]"
+          :id="itemId"
+          :required="item.required"
+          :class="item.class"
+          :style="item.style"
+          :size="item.size"
+          v-bind="item.props"
+          v-on="item.listeners"
+        >
+          <el-checkbox
+            v-for="(checkbox, checkboxIndex) in itemData"
+            :key="checkboxIndex"
+            :label="checkbox.value"
+            :class="checkbox.class"
+            :style="checkbox.style"
+            :disabled="isDisable(checkbox)"
+          >
+            {{ checkbox.label }}
+          </el-checkbox>
+        </el-checkbox-group>
+      </template>
+      <template v-else-if="checkComponent('D') || checkComponent('ElDatePicker')">
+        <el-date-picker
+          v-model="data[item.field]"
+          :id="itemId"
+          :required="item.required"
+          :class="item.class"
+          :style="item.style"
+          :size="item.size"
+          v-bind="item.props"
+          v-on="item.listeners"
+        ></el-date-picker>
+      </template>
+      <template v-else-if="checkComponent('VST') || checkComponent('VbSelectTree')">
+        <vb-select-tree
+          v-model="data[item.field]"
+          :id="itemId"
+          :required="item.required"
+          :data="itemData"
+          :placeholder="item.placeholder ?? item.label"
+          :class="item.class"
+          :style="item.style"
+          :size="item.size"
+          v-bind="item.props"
+          v-on="item.listeners"
+        ></vb-select-tree>
+      </template>
       <template v-else>
         <component
           :is="item.component"
           v-model="data[item.field]"
           v-model:value="data[item.field]"
+          :id="itemId"
           :required="item.required"
-          :type="item.type || 'text'"
           :class="item.class"
           :style="item.style"
           :size="item.size"
           :placeholder="item.placeholder ?? item.label"
           v-bind="item.props"
           v-on="item.listeners"
-        >
-          <template v-if="checkComponent('ElSelect')">
-            <el-option
-              v-for="(select, selectIndex) in itemDataOptions"
-              :key="selectIndex"
-              :value="select.value"
-              :label="select.label"
-              :class="select.class"
-              :disabled="isDisable(select)"
-              :style="select.style"
-            ></el-option>
-          </template>
-          <template v-else-if="checkComponent('ElRadioGroup')">
-            <el-radio
-              v-for="(radio, radioIndex) in itemDataOptions"
-              :key="radioIndex"
-              :label="radio.value"
-              :class="radio.class"
-              :style="radio.style"
-              :disabled="isDisable(radio)"
-            >
-              {{ radio.label }}
-            </el-radio>
-          </template>
-          <template v-else-if="checkComponent('ElCheckboxGroup')">
-            <el-checkbox
-              v-for="(checkbox, checkboxIndex) in itemDataOptions"
-              :key="checkboxIndex"
-              :label="checkbox.value"
-              :class="checkbox.class"
-              :style="checkbox.style"
-              :disabled="isDisable(checkbox)"
-            >
-              {{ checkbox.label }}
-            </el-checkbox>
-          </template>
-        </component>
+        ></component>
       </template>
     </el-form-item>
   </el-col>

+ 38 - 11
UI/VA.Vue_V1.0/src/components/form/models.ts

@@ -2,6 +2,7 @@ import type { Component } from "vue"
 import type { FormItemRule } from "element-plus/es/components/form/src/types"
 
 export type VbFormItem = {
+  id?: string | (() => string)
   field: string
   label?: string
   show?: boolean | ((v?: any) => boolean)
@@ -11,7 +12,25 @@ export type VbFormItem = {
   itemStyle?: string
   style?: string
   type?: string
-  component?: "slot" | "innerText" | Component //支持 slot、innerText、string 时就是指组件名
+  component?:
+    | "slot"
+    | "Slot"
+    | "innerText"
+    | "text" //innerText
+    | "VbSelect"
+    | "VS" //VbSelect
+    | "VbSelect"
+    | "Dict" //DictSelect
+    | "DictSelect"
+    | "VS" //VbSelect
+    | "VbSelectTree"
+    | "VST" //VbSelectTree
+    | "I" //ElInput
+    | "S" //ElSelect
+    | "C" //ElCheckboxGroup
+    | "R" //ElRadioGroup
+    | "D" //ElDatePicker
+    | Component
   innerText?: string //component 为 innerText 时,优先显示的文本,否则会显示当前的字段值
   span?: number
   labelWidth?: number
@@ -19,16 +38,24 @@ export type VbFormItem = {
   placeholder?: string
   rules?: Array<string | Array<FormItemRule> | FormItemRule> //全局规则的KEY 或 自定义的规则
   ruleFormat?: Array<Array<string | number> | undefined> //数组索引对应rules顺序,对应的rule是自定义的(或者没有format数据)要填undefined  eg: [[0,1],undfiend,["名称"]]
-  data?: Array<{
-    label: string
-    value: string | number
-    class?: string
-    style?: string
-    disabled?: boolean | ((v: any) => boolean)
-  }>
-  itemProps?: object // 注入到 el-form-item 的属性
-  props?: object // 当 component 为渲染组件时,注入到渲染组件当中的属性
-  listeners?: object // 当 component 为渲染组件时,注入到渲染组件当中的事件
+  data?:
+    | Array<{
+        label: string
+        value: string | number
+        class?: string
+        style?: string
+        disabled?: boolean | ((v: any) => boolean)
+      }>
+    | (() => Array<{
+        label: string
+        value: string | number
+        class?: string
+        style?: string
+        disabled?: string | ((v: any) => boolean)
+      }>)
+  itemProps?: any // 注入到 el-form-item 的属性
+  props?: any // 当 component 为渲染组件时,注入到渲染组件当中的属性
+  listeners?: any // 当 component 为渲染组件时,注入到渲染组件当中的事件
 }
 
 export type VbFormRowItem = {

+ 0 - 262
UI/VA.Vue_V1.0/src/components/select/DySearchSelect.vue

@@ -1,262 +0,0 @@
-<script setup lang="ts">
-import type { AxiosRequestConfig } from "axios"
-import Rs from "@/core/services/RequestService"
-export interface SelectOptionProp {
-  key: string | number
-  value: string | number
-  label?: string | number //若不设置则默认与value相同
-  disabled?: boolean
-}
-export interface SelectProp {
-  value: string | number | Array<string> | Array<number>
-  name?: string
-  url?: string
-  method?: string
-  configs?: AxiosRequestConfig
-  formatFunction?: (data: any) => SelectOptionProp
-  staticOptions?: Array<SelectOptionProp>
-  data?: Array<any>
-  placeholder?: string
-  disabled?: boolean
-  isSearch?: boolean
-  autocomplete?: string
-  size?: "large" | "default" | "small" //输入框尺寸
-  effect?: "dark " | "light" //Tooltip 主题,内置了 dark / light 两种
-  clearable?: boolean //是否可以清空选项
-  clearIcon?: string //是否可以清空选项
-  multiple?: boolean //是否多选
-  multipleLimit?: number //为0时不限制
-  placement?:
-    | "top"
-    | "top-start"
-    | "top-end"
-    | "bottom"
-    | "bottom-start"
-    | "bottom-end"
-    | "left"
-    | "left-start"
-    | "left-end"
-    | "right"
-    | "right-start"
-    | "right-end" //下拉框出现的位置
-  filterable?: boolean //Select 组件是否可筛选
-  filterMethod?: (v: string, o: Array<SelectOptionProp>) => any //自定义筛选方法
-  remote?: boolean //其中的选项是否从服务器远程加载
-  remoteShowSuffix?: boolean //远程搜索方法显示后缀图标
-  remoteMethod?: (v: string, o: Array<SelectOptionProp>) => any //远程搜索方法显示后缀图标
-  formatRemoteData?: (v: any) => any
-  loading?: boolean //是否正在从远程获取数据
-  loadingText?: string //从服务器加载内容时显示的文本
-  noMatchText?: string //搜索条件无匹配时显示的文字,也可以使用 empty 插槽设置
-  noDataText?: string //搜索条件无匹配时显示的文字,也可以使用 empty 插槽设置
-  popperClass?: string //选择器下拉菜单的自定义类名
-  suffixIcon?: string //后缀图标组件
-  reserveKeyword?: boolean //当 multiple 和 filter被设置为 true 时,是否在选中一个选项后保留当前的搜索关键词
-  defaultFirstOption?: boolean //是否在输入框按下回车时,选择第一个匹配项。 需配合 filterable 或 remote 使用
-  popperAppendToBody?: boolean //是否将弹出框插入至 body 元素 当弹出框的位置出现问题时,你可以尝试将该属性设置为false
-  teleported?: boolean //该下拉菜单是否使用teleport插入body元素
-  persistent?: boolean //当下拉选择器未被激活并且persistent设置为false,选择器会被删除。
-  automatiDropdown?: boolean //对于不可过滤的 Select 组件,此属性决定是否在输入框获得焦点后自动弹出选项菜单
-  fitInputWidth?: boolean //下拉框的宽度是否与输入框相同
-  validateEvent?: boolean //是否触发表单验证
-}
-const props = withDefaults(defineProps<SelectProp>(), {
-  value: "",
-  url: "",
-  method: "get",
-  configs: undefined,
-  multiple: false,
-  multipleLimit: 0,
-  filterable: false,
-  remote: false,
-  formatRemoteData: (v: any) => {
-    return v
-  },
-  loading: false,
-  loadingText: "加载中...",
-  noMatchText: "没有匹配项",
-  noDataText: "未查询到数据",
-  isSearch: false,
-  disabled: false,
-  clearable: false,
-  clearIcon: "CircleClose",
-  effect: "light",
-  size: "default",
-  placement: "bottom-start",
-  autocomplete: "off",
-  placeholder: "请选择",
-  popperClass: "",
-  suffixIcon: "ArrowDown",
-  defaultFirstOption: false,
-  reserveKeyword: true,
-  popperAppendToBody: true,
-  teleported: true,
-  persistent: true,
-  automatiDropdown: false,
-  fitInputWidth: false,
-  validateEvent: false,
-})
-const emits = defineEmits<{
-  (e: "update:value", v: string | number | Array<string> | Array<number>): void
-  (e: "change", v: string | number | Array<string> | Array<number>): void
-  (e: "visible-change", v: boolean): void //下拉框出现/隐藏时触发 出现则为 true,隐藏则为 false
-  (e: "remove-tag", v: string | number | Array<string> | Array<number>): void
-  (e: "clear"): void
-  (e: "blur", v: FocusEvent): void
-  (e: "focus", v: FocusEvent): void
-}>()
-const { value, url } = toRefs(props)
-const loading = ref(props.loading)
-const remote = ref(props.remote)
-const filterable = ref(props.filterable)
-const _staticOptions = ref<Array<SelectOptionProp>>()
-const options = ref<Array<SelectOptionProp>>(_staticOptions.value ?? [])
-
-let remoteFunction: (v: string) => void
-
-function init() {
-  _staticOptions.value = Object.assign([], props.staticOptions || [], formatSelectData(props.data) ?? [])
-  if (props.remoteMethod) {
-    filterable.value = true
-    remote.value = true
-    remoteFunction = (v: string) => {
-      props.remoteMethod && props.remoteMethod(v, options.value)
-      loading.value = false
-    }
-  } else if (props.url) {
-    filterable.value = true
-    remote.value = true
-    const configs = Object.assign({}, { url: url.value, method: props.method, successAlert: false }, props.configs)
-
-    remoteFunction = (query: string) => {
-      options.value = Object.assign([], _staticOptions.value ?? [])
-      console.log("======>", options.value, "=", _staticOptions.value)
-
-      if (!props.isSearch || query) {
-        loading.value = true
-        Rs.request(configs).then((res: any) => {
-          processData(res.data)
-        })
-        // if (props.method.toLowerCase() == "get") {
-        //   Rs.get(configs).then((res: any) => {
-        //     processData(res.data)
-        //   })
-        // } else if (props.method.toLowerCase() == "post") {
-        //   Rs.get(configs).then((res: any) => {
-        //     processData(res.data)
-        //   })
-        // }
-      }
-      function processData(data: any) {
-        let result = formatSelectData(data)
-        if (query) {
-          result = result.filter((v: SelectOptionProp) => {
-            return (
-              (v.label as string).toLowerCase().includes(query.toLowerCase()) ||
-              (v.value as string).toLowerCase().includes(query.toLowerCase())
-            )
-          })
-        }
-        options.value.push(...result)
-        loading.value = false
-      }
-    }
-  }
-}
-
-function formatSelectData(v: any) {
-  const result: Array<SelectOptionProp> = []
-  const data = props.formatRemoteData && typeof props.formatRemoteData == "function" ? props.formatRemoteData(v) : v
-  if (data && data.length) {
-    data.forEach((v: any) => {
-      let item = {} as SelectOptionProp
-      if (props.formatFunction) {
-        item = props.formatFunction(v)
-      } else {
-        item = Object.assign({}, v)
-        if ("value" in v) {
-          item.key = v.value + ""
-          item.value = v.value + ""
-        } else if ("code" in v) {
-          item.key = v.code + ""
-          item.value = v.code + ""
-        }
-        if ("label" in v) {
-          item.label = v.label + ""
-        } else if ("name" in v) {
-          item.label = v.name + ""
-        } else if ("title" in v) {
-          item.label = v.title + ""
-        }
-      }
-      result.push(item)
-    })
-  }
-
-  return result
-}
-function onChange(val: string | number | Array<string> | Array<number>) {
-  emits("update:value", val)
-  emits("change", val)
-}
-function onRemoveTag(val: string | number | Array<string> | Array<number>) {
-  emits("remove-tag", val)
-}
-function onVisibleChange(val: boolean) {
-  //下拉框出现/隐藏时触发 出现则为 true,隐藏则为 false
-  emits("visible-change", val)
-}
-function onBlur(v: FocusEvent) {
-  emits("blur", v)
-}
-function onFocus(v: FocusEvent) {
-  emits("focus", v)
-}
-function onClear() {
-  emits("clear")
-}
-onMounted(() => {
-  init()
-})
-</script>
-<template>
-  <el-select
-    v-model="value"
-    :placeholder="placeholder"
-    :disabled="disabled"
-    :multiple="multiple"
-    :multiple-limit="multipleLimit"
-    :clearable="clearable"
-    :clear-icon="clearIcon"
-    :suffix-icon="suffixIcon"
-    :popper-class="popperClass"
-    :autocomplete="autocomplete"
-    :size="size"
-    :effect="effect"
-    :placement="placement"
-    :filterable="filterable"
-    :remote="remote"
-    :remote-method="remoteFunction"
-    :remote-show-suffix="remoteShowSuffix"
-    :loading="loading"
-    :loading-text="loadingText"
-    :no-match-text="noMatchText"
-    :no-data-text="noDataText"
-    :default-first-option="defaultFirstOption"
-    :popper-append-to-body="popperAppendToBody"
-    :reserve-keyword="reserveKeyword"
-    :teleported="teleported"
-    :persistent="persistent"
-    :automati-dropdown="automatiDropdown"
-    :fit-input-width="fitInputWidth"
-    :validate-event="validateEvent"
-    @change="onChange"
-    @remove-tag="onRemoveTag"
-    @visible-change="onVisibleChange"
-    @blur="onBlur"
-    @focus="onFocus"
-    @clear="onClear"
-  >
-    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
-  </el-select>
-</template>

+ 0 - 227
UI/VA.Vue_V1.0/src/components/select/DySelect.vue

@@ -1,227 +0,0 @@
-<script setup lang="ts">
-import type { AxiosRequestConfig } from "axios"
-import Rs from "@/core/services/RequestService"
-export interface SelectOptionProp {
-  key: string | number
-  value: string | number
-  label?: string | number //若不设置则默认与value相同
-  disabled?: boolean
-}
-export interface SelectProp {
-  value: string | number | Array<string> | Array<number>
-  id: string
-  name?: string
-  url?: string
-  dataFun?: () => Promise<any>
-  method?: string
-  configs?: AxiosRequestConfig
-  formatRemoteData?: (v: any) => any
-  formatFunction?: (data: any) => SelectOptionProp
-  staticOptions?: Array<SelectOptionProp>
-  data?: Array<any>
-  placeholder?: string
-  disabled?: boolean
-  autocomplete?: string
-  size?: "large" | "default" | "small" //输入框尺寸
-  effect?: "dark " | "light" //Tooltip 主题,内置了 dark / light 两种
-  clearable?: boolean //是否可以清空选项
-  clearIcon?: string //是否可以清空选项
-  multiple?: boolean //是否多选
-  multipleLimit?: number //为0时不限制
-  placement?:
-    | "top"
-    | "top-start"
-    | "top-end"
-    | "bottom"
-    | "bottom-start"
-    | "bottom-end"
-    | "left"
-    | "left-start"
-    | "left-end"
-    | "right"
-    | "right-start"
-    | "right-end" //下拉框出现的位置
-  popperClass?: string //选择器下拉菜单的自定义类名
-  suffixIcon?: string //后缀图标组件
-  reserveKeyword?: boolean //当 multiple 和 filter被设置为 true 时,是否在选中一个选项后保留当前的搜索关键词
-  defaultFirstOption?: boolean //是否在输入框按下回车时,选择第一个匹配项。 需配合 filterable 或 remote 使用
-  popperAppendToBody?: boolean //是否将弹出框插入至 body 元素 当弹出框的位置出现问题时,你可以尝试将该属性设置为false
-  teleported?: boolean //该下拉菜单是否使用teleport插入body元素
-  persistent?: boolean //当下拉选择器未被激活并且persistent设置为false,选择器会被删除。
-  automatiDropdown?: boolean //对于不可过滤的 Select 组件,此属性决定是否在输入框获得焦点后自动弹出选项菜单
-  fitInputWidth?: boolean //下拉框的宽度是否与输入框相同
-  validateEvent?: boolean //是否触发表单验证
-}
-const props = withDefaults(defineProps<SelectProp>(), {
-  value: "",
-  id: "",
-  url: "",
-  method: "get",
-  configs: undefined,
-  multiple: false,
-  multipleLimit: 0,
-  formatRemoteData: (v: any) => {
-    return v
-  },
-  disabled: false,
-  clearable: true,
-  //clearIcon: "CircleClose",
-  effect: "light",
-  size: "default",
-  placement: "bottom-start",
-  autocomplete: "off",
-  placeholder: "请选择",
-  popperClass: "",
-  defaultFirstOption: false,
-  reserveKeyword: true,
-  popperAppendToBody: true,
-  teleported: true,
-  persistent: true,
-  automatiDropdown: false,
-  fitInputWidth: false,
-  validateEvent: false,
-})
-const emits = defineEmits<{
-  (e: "update:value", v: string | number | Array<string> | Array<number>): void
-  (e: "change", v: string | number | Array<string> | Array<number>): void
-  (e: "visible-change", v: boolean): void //下拉框出现/隐藏时触发 出现则为 true,隐藏则为 false
-  (e: "remove-tag", v: string | number | Array<string> | Array<number>): void
-  (e: "clear"): void
-  (e: "blur", v: FocusEvent): void
-  (e: "focus", v: FocusEvent): void
-}>()
-const { value, url, data: dataOptions } = toRefs(props)
-const _staticOptions = ref<Array<SelectOptionProp>>()
-const options = ref<Array<SelectOptionProp>>(_staticOptions.value ?? [])
-function loadData() {
-  options.value = Object.assign([], _staticOptions.value ?? [])
-
-  if (dataOptions) {
-    const result = formatSelectData(dataOptions)
-    options.value.push(...result)
-  }
-  if (props.url) {
-    const configs = Object.assign({}, { url: url.value, method: props.method, successAlert: false }, props.configs)
-    Rs.request(configs).then((res: any) => {
-      processData(res.data)
-    })
-    // if (props.method.toLowerCase() == "get") {
-    //   Rs.get(configs).then((res: any) => {
-    //     processData(res.data)
-    //   })
-    // } else if (props.method.toLowerCase() == "post") {
-    //   Rs.post(configs).then((res: any) => {
-    //     processData(res.data)
-    //   })
-    // }
-  } else if (props.dataFun) {
-    props.dataFun().then((res) => {
-      processData(res.data)
-    })
-  }
-  function processData(data: any) {
-    data = props.formatRemoteData && typeof props.formatRemoteData == "function" ? props.formatRemoteData(data) : data
-    const result = formatSelectData(data)
-    options.value.push(...result)
-  }
-}
-function init() {
-  _staticOptions.value = Object.assign([], props.staticOptions || [], formatSelectData(dataOptions) ?? [])
-  loadData()
-}
-
-function formatSelectData(data: any) {
-  const result: Array<SelectOptionProp> = []
-
-  if (data && data.length) {
-    data.forEach((v: any) => {
-      let item = {} as SelectOptionProp
-      if (props.formatFunction) {
-        item = props.formatFunction(v)
-      } else {
-        item = Object.assign({}, v)
-        if ("value" in v) {
-          item.key = v.value + ""
-          item.value = v.value + ""
-        } else if ("code" in v) {
-          item.key = v.code + ""
-          item.value = v.code + ""
-        }
-        if ("label" in v) {
-          item.label = v.label + ""
-        } else if ("name" in v) {
-          item.label = v.name + ""
-        } else if ("title" in v) {
-          item.label = v.title + ""
-        }
-      }
-      result.push(item)
-    })
-  }
-
-  return result
-}
-function onChange(val: string | number | Array<string> | Array<number>) {
-  emits("update:value", val)
-  emits("change", val)
-}
-function onRemoveTag(val: string | number | Array<string> | Array<number>) {
-  emits("remove-tag", val)
-}
-function onVisibleChange(val: boolean) {
-  //下拉框出现/隐藏时触发 出现则为 true,隐藏则为 false
-  emits("visible-change", val)
-}
-function onBlur(v: FocusEvent) {
-  emits("blur", v)
-}
-function onFocus(v: FocusEvent) {
-  emits("focus", v)
-}
-function onClear() {
-  emits("clear")
-}
-onMounted(() => {
-  init()
-})
-watch(() => props.id, init)
-function load() {
-  init()
-}
-defineExpose({ load })
-</script>
-<template>
-  <el-select
-    v-model="value"
-    :placeholder="placeholder"
-    :disabled="disabled"
-    :multiple="multiple"
-    :multiple-limit="multipleLimit"
-    :clearable="clearable"
-    :clear-icon="clearIcon"
-    :suffix-icon="suffixIcon"
-    :popper-class="popperClass"
-    :autocomplete="autocomplete"
-    :size="size"
-    :effect="effect"
-    :placement="placement"
-    :filterable="false"
-    :remote="false"
-    :default-first-option="defaultFirstOption"
-    :popper-append-to-body="popperAppendToBody"
-    :reserve-keyword="reserveKeyword"
-    :teleported="teleported"
-    :persistent="persistent"
-    :automati-dropdown="automatiDropdown"
-    :fit-input-width="fitInputWidth"
-    :validate-event="validateEvent"
-    @change="onChange"
-    @remove-tag="onRemoveTag"
-    @visible-change="onVisibleChange"
-    @blur="onBlur"
-    @focus="onFocus"
-    @clear="onClear"
-  >
-    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
-  </el-select>
-</template>

+ 0 - 96
UI/VA.Vue_V1.0/src/components/select/DynamicTreeSelect.vue

@@ -1,96 +0,0 @@
-<script setup lang="ts">
-import type { AxiosRequestConfig } from "axios"
-import Rs from "@/core/services/RequestService"
-const props = withDefaults(
-  defineProps<{
-    url?: string
-    dataFun?: () => Promise<any>
-    configs?: AxiosRequestConfig
-    method?: string
-    class?: string
-    placeholder?: string
-    value?: Array<string> | string
-    expandedKeys?: Array<string>
-    expandAll?: boolean
-    disabled?: boolean
-    selectFirst?: boolean
-    dropdownStyle?: object
-  }>(),
-  {
-    method: "get",
-    class: "full-input",
-    placeholder: "请选择",
-    expandAll: true,
-    disabled: false,
-    selectFirst: false,
-    value: () => {
-      return []
-    },
-    dropdownStyle: () => {
-      return { maxHeight: "400px", overflow: "auto" }
-    },
-  }
-)
-const emits = defineEmits<{
-  (e: "update:value", v: string | Array<string>): void
-  (e: "change", v: string | Array<string>): void
-  (e: "onSelectFirst", v: string): void
-  (e: "selectRenderComplete", v: Array<any>): void
-}>()
-const list = ref<Array<any>>([])
-const search = () => {
-  const configs = Object.assign(
-    {},
-    { url: props.url, method: props.method, successAlert: false } as AxiosRequestConfig,
-    props.configs || {}
-  )
-  Rs.request(configs).then((res: any) => {
-    list.value = [
-      {
-        label: "根",
-        value: "0",
-        key: "0",
-        children: compilerRows(res.data),
-      },
-    ]
-    list.value.length > 0 && props.selectFirst && emits("onSelectFirst", (list.value[0] as any).key)
-    emits("selectRenderComplete", list.value)
-  })
-}
-function onChange(value: string | Array<string>) {
-  emits("update:value", value)
-  emits("change", value)
-}
-const compilerRows = (arr: any) => {
-  const result: any = []
-  arr.forEach((item: any) => {
-    const newItem: any = {
-      label: item.name + "",
-      value: item.id + "",
-      key: item.id + "",
-    }
-    if ("children" in item && item.children && Array.isArray(item.children)) {
-      newItem.children = compilerRows(item.children.map((one: any) => ({ ...one })))
-    }
-    result.push(newItem)
-  })
-
-  return result
-}
-onMounted(search)
-</script>
-
-<template>
-  <div>
-    <a-tree-select
-      :class="props.class"
-      :dropdownStyle="dropdownStyle"
-      :treeData="list"
-      :placeholder="placeholder"
-      :treeDefaultExpandAll="expandAll"
-      :treeDefaultExpandedKeys="expandedKeys"
-      :value="value"
-      @change="onChange"
-    ></a-tree-select>
-  </div>
-</template>

+ 78 - 15
UI/VA.Vue_V1.0/src/components/select/VbSelect.vue

@@ -2,16 +2,29 @@
 const props = withDefaults(
   defineProps<{
     modelValue?: any
+    id?: string //id变化后重新加载树
     data?: any
     dataFun?: () => Promise<any>
     url?: string
     method?: string
     config?: any
-    props?: { label?: string; value?: string; class?: string; style?: string }
-    dataMapFun?: (v: any) => { label: string; value: string; class?: string; style?: string }
+    props?: {
+      label?: string
+      value?: string
+      class?: string
+      style?: string
+      disabled?: string | ((v?: any) => boolean)
+    }
+    dataMapFun?: (v: any) => {
+      label: string
+      value: string
+      class?: string
+      style?: string
+      disabled?: boolean
+    }
     needFormate?: boolean
     placeholder?: string
-    listeners?: Array<any>
+    listeners?: any
     type?: "select" | "checkbox" | "radio"
   }>(),
   {
@@ -26,8 +39,14 @@ const emits = defineEmits<{
   (e: "change", v: any): any
 }>()
 const { modelValue } = toRefs(props)
-const options = ref<any>([])
-
+const _data = ref<any>([])
+const options = computed(() => {
+  if (props.dataFun || props.url) {
+    return _data.value
+  }
+  formatData(typeof props.data == "function" ? props.data() : props.data)
+  return _data.value
+})
 function onChange(v: any) {
   emits("update:modelValue", v)
   emits("change", v)
@@ -41,25 +60,29 @@ function onChange2(v: Array<any>) {
 
 function formatData(data: Array<any>) {
   if (!props.needFormate) {
-    options.value = data
+    _data.value = data
   } else {
     if (props.dataMapFun) {
-      options.value =
+      _data.value =
         data?.map((v: any) => {
           return props.dataMapFun ? props.dataMapFun(v) : v
         }) || []
     } else if (props.props) {
-      options.value =
+      _data.value =
         data?.map((v: any) => {
           return {
             label: v[props.props?.label ?? "label"],
             value: v[props.props?.value ?? "value"],
             class: v[props.props?.class ?? "class"],
             style: v[props.props?.style ?? "style"],
+            disabled:
+              typeof props.props?.disabled == "function"
+                ? props.props?.disabled(v)
+                : v[props.props?.disabled ?? "disabled"],
           }
         }) || []
     } else {
-      options.value = data
+      _data.value = data
     }
   }
 }
@@ -74,13 +97,13 @@ function load() {
       formatData(res.data)
     })
   } else {
-    formatData(props.data)
+    formatData(typeof props.data == "function" ? props.data() : props.data)
   }
 }
 function init() {
   load()
 }
-
+watch(() => props.id, init)
 onMounted(() => {
   init()
 })
@@ -88,26 +111,55 @@ onMounted(() => {
 <template>
   <template v-if="type == 'checkbox'">
     <el-checkbox-group
+      :id="id"
       v-model="modelValue"
       :placeholder="placeholder"
       @change="onChange2"
       v-bind="$attrs"
       v-on="listeners"
     >
-      <el-checkbox v-for="(v, i) in options" :label="v.value" :key="i" :class="v.class" :style="v.style">
+      <el-checkbox
+        v-for="(v, i) in options"
+        :label="v.value"
+        :key="i"
+        :class="v.class"
+        :style="v.style"
+        :disabled="v.disabled"
+      >
         {{ v.label }}
       </el-checkbox>
     </el-checkbox-group>
   </template>
   <template v-else-if="type == 'radio'">
-    <el-radio-group v-model="modelValue" :placeholder="placeholder" @change="onChange" v-bind="$attrs" v-on="listeners">
-      <el-radio v-for="(v, i) in options" :label="v.value" :key="i" :class="v.class" :style="v.style">
+    <el-radio-group
+      :id="id"
+      v-model="modelValue"
+      :placeholder="placeholder"
+      @change="onChange"
+      v-bind="$attrs"
+      v-on="listeners"
+    >
+      <el-radio
+        v-for="(v, i) in options"
+        :label="v.value"
+        :key="i"
+        :class="v.class"
+        :style="v.style"
+        :disabled="v.disabled"
+      >
         {{ v.label }}
       </el-radio>
     </el-radio-group>
   </template>
   <template v-else>
-    <el-select v-model="modelValue" :placeholder="placeholder" @change="onChange" v-bind="$attrs" v-on="listeners">
+    <el-select
+      v-model="modelValue"
+      :id="id"
+      :placeholder="placeholder"
+      @change="onChange"
+      v-bind="$attrs"
+      v-on="listeners"
+    >
       <el-option
         v-for="(v, i) in options"
         :label="v.label"
@@ -115,7 +167,18 @@ onMounted(() => {
         :key="i"
         :class="v.class"
         :style="v.style"
+        :disabled="v.disabled"
       ></el-option>
     </el-select>
   </template>
 </template>
+<style lang="scss" scoped>
+:deep(.el-select-dropdown__list) {
+  .el-select-dropdown__item {
+    &.hover {
+      color: var(--bs-primary);
+      background: var(--bs-primary-light);
+    }
+  }
+}
+</style>

+ 71 - 49
UI/VA.Vue_V1.0/src/components/select/DySelectTree.vue → UI/VA.Vue_V1.0/src/components/select/VbSelectTree.vue

@@ -10,12 +10,12 @@ interface TreeOption {
 }
 const props = withDefaults(
   defineProps<{
-    value: string | number | Array<string | number> | null | undefined
+    modelValue: string | number | Array<string | number> | null | undefined
     id?: string //id变化后重新加载树
     name?: string
     url?: string
     dataFun?: () => Promise<any>
-    data?: Array<any>
+    data?: Array<any> | (() => Array<any>)
     method?: string
     configs?: AxiosRequestConfig
     multiple?: boolean
@@ -29,22 +29,23 @@ const props = withDefaults(
     // "LEAF_PRIORITY"- 如果选中分支节点,则该节点本身及其分支后代将从数组中排除,但其叶子代将被包括在内value
     // "ALL_WITH_INDETERMINATE"- 任何被选中的节点都将包含在数组中,加上不确定的节点value (默认值)
     valueConsistsOf?: "ALL" | "BRANCH_PRIORITY" | "LEAF_PRIORITY" | "ALL_WITH_INDETERMINATE"
-    expandedKeys?: Array<string>
     defaultExpandLevel?: number
     placeholder?: string
     loadingText?: string
     staticOptions?: Array<TreeOption>
     dataFormatFunction?: (data: any) => TreeOption
-    optionMap?: {
+    props?: {
       id: string
       label: string
       children: string
     }
+    listeners?: any
   }>(),
   {
+    data: () => [],
     multiple: false,
-    flat: false,
-    clearable: false,
+    flat: true,
+    clearable: true,
     searchable: false,
     method: "get",
     sortValueBy: "LEVEL",
@@ -52,46 +53,52 @@ const props = withDefaults(
     staticOptions: () => {
       return [] as Array<TreeOption>
     },
-    optionMap: () => {
+    props: () => {
       return {
         id: "id",
         label: "label",
         children: "children",
       }
     },
-
+    defaultExpandLevel: 1,
     placeholder: "请选择...",
     loadingText: "加载中,请稍后...",
   }
 )
 const emits = defineEmits<{
-  (e: "update:value", v: string | number | Array<string | number> | null | undefined): void
+  (e: "update:modelValue", v: string | number | Array<string | number> | null | undefined): void
   (e: "select", v: any): void
   (e: "deselect", v: any): void
 }>()
-const { staticOptions, data: dataOptions, value, id } = toRefs(props)
-const options = ref<Array<TreeOption>>(Object.assign([], staticOptions.value ?? []))
-
+const { staticOptions, data: dataOptions, modelValue, id } = toRefs(props)
+const _data = ref<Array<TreeOption>>(Object.assign([], staticOptions.value ?? []))
+const options = computed(() => {
+  if (props.dataFun || props.url) {
+    return _data.value
+  }
+  return formatDatas(typeof props.data == "function" ? props.data() : props.data)
+})
+function formatDatas(data: Array<any>) {
+  const list: any = []
+  data.forEach((v: any) => {
+    list.push(formatData(v))
+  })
+  return list
+}
 function formatData(data: any) {
   if (props.dataFormatFunction) {
     return props.dataFormatFunction(data)
   } else {
     const item = {} as TreeOption
-    if (props.optionMap.id in data) {
-      item.id = data[props.optionMap.id]
-    }
-    if (props.optionMap.label in data) {
-      item.label = data[props.optionMap.label]
-    }
-    if (props.optionMap.children in data) {
-      const childrenItem = [] as Array<TreeOption>
-      const children = data[props.optionMap.children]
-      children?.forEach((v: any) => {
-        childrenItem.push(formatData(v))
-      })
-      if (childrenItem.length) {
-        item.children = childrenItem
-      }
+    item.id = data[props.props.id ?? "id"]
+    item.label = data[props.props.label ?? "label"]
+    const childrenItem = [] as Array<TreeOption>
+    const children = data[props.props.children ?? "children"]
+    children?.forEach((v: any) => {
+      childrenItem.push(formatData(v))
+    })
+    if (childrenItem.length) {
+      item.children = childrenItem
     }
     return item
   }
@@ -99,51 +106,53 @@ function formatData(data: any) {
 
 function load() {
   if (dataOptions?.value) {
-    console.log("dataOptions", dataOptions)
-    dataOptions.value.map((v) => {
+    dataOptions.value = (typeof props.data == "function" ? props.data() : props.data).map((v) => {
       return formatData(v)
     })
   }
-  options.value = Object.assign([], staticOptions.value ?? [], dataOptions?.value ?? [])
+  _data.value = Object.assign([], staticOptions.value ?? [], dataOptions?.value ?? [])
   if (props.url) {
     const configs = Object.assign({}, { url: props.url, method: props.method, successAlert: false }, props.configs)
     Rs.request(configs).then((res: any) => {
       processData(res.data)
     })
-    // if (props.method.toLowerCase() == "get") {
-    //   Rs.get(configs).then((res: any) => {
-    //     processData(res.data)
-    //   })
-    // } else if (props.method.toLowerCase() == "post") {
-    //   Rs.post(configs).then((res: any) => {
-    //     processData(res.data)
-    //   })
-    // }
   } else if (props.dataFun) {
     props.dataFun().then((res) => {
-      console.log("deptOptions.value3", res)
       processData(res?.data || res)
     })
   }
   function processData(data: any) {
-    console.log("deptOptions.value4", data)
     data.forEach((v: any) => {
       const item = formatData(v)
-      options.value.push(item)
+      _data.value.push(item)
     })
 
-    if (!value.value) {
-      const val = props.multiple ? [options.value[0].id] : options.value[0].id
-      emits("update:value", val)
+    if (!modelValue.value) {
+      const val = props.multiple ? [_data.value[0].id] : _data.value[0].id
+      emits("update:modelValue", val)
     }
   }
 }
 
 function onSelect(data: any) {
-  emits("deselect", data)
+  let val = modelValue.value as any
+  if (props.multiple) {
+    val.push(data.id)
+  } else {
+    val = data.id
+  }
+  emits("update:modelValue", val)
+  emits("select", data)
 }
 function onDeselect(data: any) {
-  emits("select", data)
+  let val = modelValue.value as any
+  if (props.multiple) {
+    val.splice(val.indexOf(data.id), 1)
+  } else {
+    val = undefined
+  }
+  emits("update:modelValue", val)
+  emits("deselect", data)
 }
 watch(() => props.id, init)
 onMounted(init)
@@ -154,7 +163,7 @@ defineExpose({ load })
 </script>
 <template>
   <tree-select
-    v-model="value"
+    v-model="modelValue"
     :id="id"
     :placeholder="placeholder"
     :loadingText="loadingText"
@@ -167,8 +176,21 @@ defineExpose({ load })
     :flat="flat"
     :sort-value-by="sortValueBy"
     :value-consists-of="valueConsistsOf"
-    v-bind="$attrs"
     @select="onSelect"
     @deselect="onDeselect"
+    v-bind="$attrs"
+    v-on="listeners"
   />
 </template>
+<style lang="scss" scoped>
+:deep(.vue-treeselect__list) {
+  .vue-treeselect__option--highlight {
+    color: var(--bs-primary);
+    background: var(--bs-primary-light);
+  }
+  .vue-treeselect__option--selected {
+    color: #fff;
+    background: var(--bs-primary);
+  }
+}
+</style>

+ 26 - 41
UI/VA.Vue_V1.0/src/views/system/user/index.vue

@@ -1,8 +1,6 @@
 <script setup lang="ts" name="User">
 import apis from "@/api"
-import { ElDatePicker, ElInput, ElSelect, ElTreeSelect } from "element-plus"
 import type { VbFormItem } from "@/components/form/models"
-import DictSelect from "@/components/dict/DictSelect.vue"
 import AuthRole from "./_authRole.vue"
 import { permissionNames } from "@/core/services/PermissionNames"
 import message from "@/core/utils/message"
@@ -12,14 +10,9 @@ const deptOptions = ref<any>()
 function loadDept() {
   apis.system.userApi.deptTreeSelect().then((res) => {
     deptOptions.value = res.data
-    const item = formItems.value.find((v) => {
-      return v.field == "deptId"
-    })
-    if (item && item.props) {
-      item.props.data = res.data
-    }
   })
 }
+
 const tableRef = ref()
 const tableOpts = reactive({
   permission: permissionNames.SystemUser,
@@ -46,7 +39,7 @@ const tableOpts = reactive({
       label: "用户名称",
       placeholder: "请输入用户名称",
       required: false,
-      component: ElInput,
+      component: "i",
       listeners: {
         keyup: (e: KeyboardEvent) => {
           if (e.code == "Enter") {
@@ -61,7 +54,7 @@ const tableOpts = reactive({
       label: "手机号码",
       placeholder: "请输入手机号码",
       required: false,
-      component: ElInput,
+      component: "I",
       listeners: {
         keyup: (e: KeyboardEvent) => {
           if (e.code == "Enter") {
@@ -75,7 +68,7 @@ const tableOpts = reactive({
       field: "status",
       label: "用户状态",
       required: false,
-      component: DictSelect,
+      component: "Dict",
       span: 5,
       props: {
         placeholder: "请选择用户状态",
@@ -87,7 +80,7 @@ const tableOpts = reactive({
       label: "创建时间",
       placeholder: "请选择创建时间",
       required: false,
-      component: ElDatePicker,
+      component: "d",
       span: 6,
       props: {
         placeholder: "请选择创建时间",
@@ -129,6 +122,9 @@ function resetQuery() {
   queryParams.value.deptId = undefined
   deptTreeRef.value.setCurrentKey(null)
 }
+
+const userPosts = ref([])
+const userRoles = ref([])
 const modalRef = ref()
 const modalOpts = reactive({
   title: "用户",
@@ -138,7 +134,7 @@ const modalOpts = reactive({
       label: "用户昵称",
       placeholder: "请输入用户昵称",
       required: true,
-      component: ElInput,
+      component: "i",
       span: 12,
     },
     {
@@ -146,13 +142,11 @@ const modalOpts = reactive({
       label: "归属部门",
       class: "w-100",
       required: true,
-      component: ElTreeSelect,
+      data: () => deptOptions.value,
+      component: "vst",
       props: {
-        data: [],
+        //dataFun: loadDept,
         placeholder: "请选择归属部门",
-        props: { value: "id", label: "label", children: "children" },
-        valueKey: "id",
-        checkStrictly: true,
       },
       span: 12,
     },
@@ -161,7 +155,7 @@ const modalOpts = reactive({
       label: "手机号码",
       placeholder: "请输入手机号码",
       required: true,
-      component: ElInput,
+      component: "i",
       props: {
         maxlength: 11,
       },
@@ -172,7 +166,7 @@ const modalOpts = reactive({
       label: "邮箱",
       placeholder: "请输入邮箱",
       required: true,
-      component: ElInput,
+      component: "i",
       rules: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
       props: {
         maxlength: 11,
@@ -185,7 +179,6 @@ const modalOpts = reactive({
       placeholder: "请输入用户名称",
       required: true,
       rules: [{ min: 2, max: 20, message: "用户名称长度必须介于 2 和 20 之间", trigger: "blur" }],
-      component: ElInput,
       span: 12,
     },
     {
@@ -195,15 +188,13 @@ const modalOpts = reactive({
       placeholder: "请输入用户密码",
       required: false,
       rules: [{ min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" }],
-
-      component: ElInput,
       span: 12,
     },
     {
       field: "sex",
       label: "用户性别",
       class: "w-100",
-      component: DictSelect,
+      component: "dict",
       props: {
         placeholder: "请选择用户性别",
         dictType: "sys_user_sex",
@@ -214,7 +205,7 @@ const modalOpts = reactive({
       field: "status",
       label: "用户状态",
       class: "w-100",
-      component: DictSelect,
+      component: "dict",
       props: {
         placeholder: "请选择用户状态",
         dictType: "sys_normal_disable",
@@ -225,22 +216,24 @@ const modalOpts = reactive({
       field: "postIds",
       label: "用户岗位",
       class: "w-100",
-      component: ElSelect,
-      data: [],
+      component: "vs",
+      data: () => userPosts.value,
       placeholder: "请选择用户岗位",
       span: 12,
       props: {
-        multiple: true,
+        //multiple: true,
       },
     },
     {
       field: "roleIds",
+      //id: () => role_id.value,
       label: "用户角色",
       class: "w-100",
       placeholder: "请选择用户角色",
-      data: [],
-      component: ElSelect,
+      data: () => userRoles.value,
+      component: "vs",
       props: {
+        //dataFun: loadUserRole,
         multiple: true,
       },
       span: 12,
@@ -251,7 +244,7 @@ const modalOpts = reactive({
       type: "textarea",
       placeholder: "请输入备注内容",
       required: false,
-      component: ElInput,
+      component: "i",
       span: 24,
     },
   ],
@@ -301,22 +294,14 @@ function handleUpdate(row: any) {
   })
 }
 function setOptions(data: any) {
-  ;(
-    formItems.value.find((v) => {
-      return v.field == "postIds"
-    }) as VbFormItem
-  ).data = data.posts.map((v: any) => {
+  userPosts.value = data.posts.map((v: any) => {
     return {
       label: v.postName,
       value: v.postId,
       disabled: v.status == 1,
     }
   })
-  ;(
-    formItems.value.find((v) => {
-      return v.field == "roleIds"
-    }) as VbFormItem
-  ).data = data.roles.map((v: any) => {
+  userRoles.value = data.roles.map((v: any) => {
     return {
       label: v.roleName,
       value: v.roleId,

+ 18 - 8
UI/VA.Vue_V1.0/vite.config.ts

@@ -32,12 +32,18 @@ export default defineConfig(({ mode, command }) => {
       //设为 true 时若端口已被占用则会直接退出,而不是尝试下一个可用端口
       strictPort: true,
       open: true,
+      // proxy: {
+      //   "/dev-api": {
+      //     target: "http://localhost:6060",
+      //     changeOrigin: true,
+      //     rewrite: (p) => p.replace(/^\/dev-api/, ""),
+      //   },
+      // },
       proxy: {
-        // https://cn.vitejs.dev/config/#server-proxy
         "/dev-api": {
-          target: "http://localhost:6060",
+          target: "http://shvber.com:6066",
           changeOrigin: true,
-          rewrite: (p) => p.replace(/^\/dev-api/, ""),
+          rewrite: (p) => p.replace(/^\/dev-api/, "/prod-api"),
         },
       },
     },
@@ -50,14 +56,18 @@ export default defineConfig(({ mode, command }) => {
       //设为 true 时若端口已被占用则会直接退出,而不是尝试下一个可用端口
       strictPort: true,
       open: true,
+      // proxy: {
+      //   "/prod-api": {
+      //     target: "http://localhost:6060",
+      //     changeOrigin: true,
+      //     rewrite: (p) => p.replace(/^\/prod-api/, ""),
+      //   },
+      // },
       proxy: {
-        // https://cn.vitejs.dev/config/#server-proxy
         "/prod-api": {
-          target: "http://localhost:6060",
-          //target: "http://shvber.com:6066",
+          target: "http://shvber.com:6066",
           changeOrigin: true,
-          rewrite: (p) => p.replace(/^\/prod-api/, ""),
-          //rewrite: (p) => p.replace(/^\/prod-api/, "/prod-api"),
+          rewrite: (p) => p.replace(/^\/prod-api/, "/prod-api"),
         },
       },
     },

+ 3 - 0
UI/VA.Vue_V1.0/vite/auto-import/auto-import.d.ts

@@ -6,6 +6,9 @@ export {}
 declare global {
   const ApiService: typeof import('../../src/core/services/ApiService')['default']
   const EffectScope: typeof import('vue')['EffectScope']
+  const ElInput: typeof import('element-plus/es')['ElInput']
+  const ElSelect: typeof import('element-plus/es')['ElSelect']
+  const ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
   const JwtService: typeof import('../../src/core/services/JwtService')['default']
   const LayoutService: typeof import('../../src/core/services/LayoutService')['default']
   const PermissionNames: typeof import('../../src/core/services/PermissionNames')['default']

+ 2 - 0
UI/VA.Vue_V1.0/vite/auto-import/components.d.ts

@@ -24,6 +24,7 @@ declare module '@vue/runtime-core' {
     ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
     ElCol: typeof import('element-plus/es')['ElCol']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
+    ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
@@ -75,6 +76,7 @@ declare module '@vue/runtime-core' {
     VbImagePreview: typeof import('./../../src/components/upload/VbImagePreview.vue')['default']
     VbModal: typeof import('./../../src/components/modal/VbModal.vue')['default']
     VbSelect: typeof import('./../../src/components/select/VbSelect.vue')['default']
+    VbSelectTree: typeof import('./../../src/components/select/VbSelectTree.vue')['default']
     VbSymbol: typeof import('./../../src/components/symbol/VbSymbol.vue')['default']
     VbTag: typeof import('./../../src/components/tag/VbTag.vue')['default']
     VbTooltip: typeof import('./../../src/components/tooltip/VbTooltip.vue')['default']