zhengnaiwen_citu 6 mesi fa
parent
commit
78d5c7d13b

+ 2 - 1
jsconfig.json

@@ -15,5 +15,6 @@
       "dom.iterable",
       "scripthost"
     ]
-  }
+  },
+  "exclude": ["node_modules", "dist"]
 }

+ 17 - 12
src/components/AutoComponents/MTable/index.vue

@@ -14,18 +14,20 @@
       <template #append>
         <slot name="table-append"></slot>
       </template>
-      <m-table-column
-        v-for="(header, index) in headers"
-        :key="(header.prop ?? header.label) || index"
-        :item="header"
-      >
-        <template v-if="$scopedSlots[header.prop]" #[header.prop]="scope">
-          <slot :name="header.prop" v-bind="scope"></slot>
-        </template>
-        <template v-if="$scopedSlots[`${header.prop}-header`]" #[`${header.prop}-header`]>
-          <slot :name="`${header.prop}-header`"></slot>
-        </template>
-      </m-table-column>
+      <template v-for="(header, index) in headers">
+        <!-- <el-table-column v-if="['selection','index'].includes(header.type)" v-bind="header" :key="index" /> -->
+        <m-table-column
+          :key="(header.prop ?? header.label) || index"
+          :item="header"
+        >
+          <template v-if="$scopedSlots[header.prop]" #[header.prop]="scope">
+            <slot :name="header.prop" v-bind="scope"></slot>
+          </template>
+          <template v-if="$scopedSlots[`${header.prop}-header`]" #[`${header.prop}-header`]>
+            <slot :name="`${header.prop}-header`"></slot>
+          </template>
+        </m-table-column>
+      </template>
     </el-table>
     <slot></slot>
     <div class="pt-3 text-right" v-if="total">
@@ -78,6 +80,9 @@ export default {
     }
   },
   methods: {
+    getRefs () {
+      return this.$refs.table
+    },
     handleCurrentChange (val) {
       this.$emit('page-change', val)
     },

+ 5 - 0
src/styles/orangeTheme.scss

@@ -29,6 +29,11 @@
   }
 }
 
+// 复选
+.el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {
+  background-color: $theme-color;
+  border-color: $theme-color;
+}
 
 
 // 定义主题颜色(仿照 Element UI)

+ 243 - 66
src/views/salary/solution/salarySolution/salarySolutionRules.vue

@@ -1,30 +1,97 @@
 <template>
-  <m-dialog ref="dialog" :title="itemData.title + ' 规则配置'" width="1000px" @sure="onSure">
-    <el-form ref="form" :model="formQuery" v-loading="loading">
-      <m-table
-        shadow="naver"
-        :items="formQuery.items"
-        :headers="headers"
-      >
-        <template #name="scope">
-          <el-form-item
-            :prop="`items.${scope.$index}.name`"
-          >
-            {{scope.row.name}}
+  <m-dialog ref="dialog" title="规则配置" width="1000px" @sure="onSure">
+    <el-form ref="form" v-loading="loading" label-width="100px">
+      <el-form-item label="名称">
+        <el-tag color="primary">{{ itemData.title }}</el-tag>
+      </el-form-item>
+      <el-form-item label="参数">
+        <m-card shadow="never">
+          <el-form-item label="参数分类">
+            <el-select v-model="paramsActive" placeholder="请选择参数分类">
+              <el-option
+                v-for="category in categories"
+                :key="category"
+                :label="category"
+                :value="category"
+              >
+              </el-option>
+            </el-select>
           </el-form-item>
-        </template>
-        <template #value="scope">
-          <el-form-item
-            :prop="`items.${scope.$index}.value`"
-            :rules="{ required: true, message: '请填写配置数值', trigger: 'blur' }"
-          >
-            <el-input
-              v-model="formQuery.items[scope.$index].value"
-              placeholder="配置数值"
-            ></el-input>
+          <el-form-item label="参数配置" class="mt-3">
+            <template #label>
+              <span>参数配置</span>
+              <el-tooltip class="item" effect="dark" content="复选框勾选代表启用项" placement="right">
+                <span class="el-icon-info"></span>
+              </el-tooltip>
+            </template>
+            <m-table
+              shadow="never"
+              ref="table"
+              :items="paramsList"
+              :headers="headers"
+            >
+              <template #status-header>
+                <el-checkbox @change="onSelectAllChange"></el-checkbox>
+                启用
+              </template>
+              <template #status="{ row }">
+                <el-checkbox v-model="row.status" @change="onSelectChange($event, row)"></el-checkbox>
+              </template>
+              <template #header>
+                <div class="tools">
+                  <el-popover
+                    placement="top"
+                    width="500"
+                    trigger="click"
+                  >
+                    <m-table
+                      v-if="gridData.length > 0"
+                      style="border: unset"
+                      shadow="never"
+                      height="250"
+                      :items="gridData"
+                      :headers="[
+                        { label: '分类', prop: 'category' },
+                        { label: '参数名称', prop: 'name' },
+                        { label: '数值', prop: 'value', width: 100, align: 'center' }
+                      ]"
+                    ></m-table>
+                    <el-empty v-else></el-empty>
+                    <m-button slot="reference" type="orange" size="small">查看已选 {{ gridData.length }}</m-button>
+                  </el-popover>
+                </div>
+              </template>
+              <template #value="{ row }">
+                <el-input-number size="mini" v-model="row.value" placeholder="请输入数值"></el-input-number>
+              </template>
+            </m-table>
           </el-form-item>
-        </template>
-      </m-table>
+        </m-card>
+      </el-form-item>
+      <el-form-item label="计算公式">
+        <m-card shadow="never">
+          <el-tree
+            :data="formula"
+            node-key="uuid"
+            ref="formulaTreeRefs"
+            default-expand-all
+            :expand-on-click-node="false"
+          >
+            <div class="custom-tree-node" slot-scope="{ data }">
+              <el-input size="small" v-model="data.content" placeholder="描述文字"></el-input>
+              <el-button class="ml-3" size="small" @click="onInsertAfter(data)">
+                同级追加
+              </el-button>
+              <el-button class="ml-3" size="small" @click="onAppend(data)">
+                插入下一级
+              </el-button>
+              <el-button size="small" @click="onRemove(data)">
+                删除
+              </el-button>
+            </div>
+          </el-tree>
+        </m-card>
+      </el-form-item>
     </el-form>
   </m-dialog>
 </template>
@@ -33,6 +100,7 @@
 import {
   saveSolution,
   getConfigPage,
+  getConfigCateGories,
   getSolutionDetails
 } from '@/api/salary'
 
@@ -40,68 +108,177 @@ export default {
   name: 'salary-solution-rules',
   data () {
     return {
-      formQuery: {
-        items: []
-      },
+      formula: [
+        {
+          uuid: '1',
+          content: null
+        }
+      ],
       headers: [
-        { label: '参数名称', prop: 'name', align: 'right', width: '500px' },
+        { label: '启用', prop: 'status', width: 80 },
+        { label: '参数名称', prop: 'name', align: 'left' },
         { label: '数值', prop: 'value' }
       ],
       itemData: {},
       options: [],
-      loading: false
+      loading: false,
+      categories: [], // 所有分类
+      allParams: [], // 所有参数
+      paramsCategoryItems: {}, // 整合分类列表层级
+      paramsActive: null, // 已选value
+      paramsSelection: [] // 已选参数
+    }
+  },
+  computed: {
+    paramsList () {
+      if (!this.paramsCategoryItems[this.paramsActive]) {
+        return []
+      }
+      return this.paramsCategoryItems[this.paramsActive]
+    },
+    gridData () {
+      const _allParams = Object.values(this.paramsCategoryItems).flat()
+      if (_allParams.length === 0) {
+        return []
+      }
+      return this.paramsSelection.map(e => {
+        const item = _allParams.find(item => item.name === e)
+        return {
+          name: item.name,
+          value: item.value ?? 0,
+          category: item.category
+        }
+      })
     }
   },
   methods: {
-    async open (item) {
+    open (item) {
       this.itemData = item
       this.$refs.dialog.open()
       this.loading = true
-      try {
-        const { data: detail } = await getSolutionDetails({
-          performanceSolutionId: item.performanceSolutionId
-        })
-        console.log(detail)
-        const { data } = await getConfigPage({
-          size: 999,
-          current: 1
-        })
-        this.formQuery.items = data.records.map(e => {
-          return {
-            name: e.name,
-            value: detail.calculateConfigurations.find(_e => _e.name === e.name)?.value ?? e.value
+      this.$nextTick(async () => {
+        try {
+        // 获取所有分类
+          const { data: categories } = await getConfigCateGories({})
+          this.categories = categories
+          this.paramsActive = categories[0]
+          // 获取完整列表
+          const { data: allParams } = await getConfigPage({
+            size: 9999,
+            current: 1
+          })
+          this.allParams = allParams.records
+          const { data: detail } = await getSolutionDetails({
+            performanceSolutionId: item.performanceSolutionId
+          })
+          if (!detail.calculateFormulas.length) {
+            this.formula = [
+              { uuid: '1', content: null, sort: null }
+            ]
+          } else {
+            this.formula = detail.calculateFormulas
           }
+          this.paramsSelection = detail.calculateConfigurations.map(e => e.name)
+
+          // 根据分类获取参数列表
+          this.paramsCategoryItems = categories.reduce((res, key) => {
+            res[key] = allParams.records.filter(item => item.category === key).map(e => {
+              return {
+                name: e.name,
+                value: e.value ?? 0,
+                category: e.category,
+                status: this.paramsSelection.includes(e.name)
+              }
+            })
+            return res
+          }, {})
+        } catch (error) {
+          this.$message.error(error)
+        } finally {
+          this.loading = false
+        }
+      })
+    },
+    onSelectChange (val, row) {
+      if (val) {
+        this.paramsSelection.push(row.name)
+      } else {
+        this.paramsSelection = this.paramsSelection.filter(e => e !== row.name)
+      }
+    },
+    onSelectAllChange (val) {
+      if (val) {
+        this.paramsSelection = this.paramsSelection.concat(this.paramsList.map(e => e.name)).flat()
+      } else {
+        this.paramsSelection = this.paramsSelection.filter(e => !this.paramsList.map(e => e.name).includes(e))
+      }
+      this.paramsList.forEach(e => {
+        e.status = val
+      })
+    },
+    onRemove (data) {
+      this.$refs.formulaTreeRefs.remove(data)
+    },
+    onInsertAfter (data) {
+      this.$refs.formulaTreeRefs.insertAfter({
+        uuid: Date.now(),
+        content: null
+      }, data)
+    },
+    onAppend (data) {
+      this.$refs.formulaTreeRefs.append({
+        uuid: Date.now(),
+        content: null
+      }, data)
+    },
+    async onSure () {
+      if (this.paramsSelection.length === 0) {
+        this.$message.error('请选择参数')
+        return
+      }
+
+      const calculateFormulas = removeUuidFromArrayTree(this.formula)
+      function removeUuidFromArrayTree (treeArray) {
+        return treeArray.map(node => {
+        // 删除当前节点的uuid
+          const { uuid, children, ...rest } = node
+
+          // 如果有子节点,递归处理
+          const cleanedNode = { ...rest }
+          if (children && Array.isArray(children) && children.length > 0) {
+            cleanedNode.children = removeUuidFromArrayTree(children)
+          }
+          return cleanedNode
         })
+      }
+      try {
+        await saveSolution({
+          entity: {
+            performanceSolutionId: this.itemData.performanceSolutionId
+          },
+          calculateConfigurations: this.gridData,
+          calculateFormulas
+        })
+        this.$refs.dialog.close()
+        this.$emit('refresh')
+        this.$message.success('保存成功')
       } catch (error) {
         this.$message.error(error)
-      } finally {
-        this.loading = false
       }
-    },
-    onSure () {
-      this.$refs.form.validate(async valid => {
-        if (valid) {
-          const query = {
-            entity: {
-              performanceSolutionId: this.itemData.performanceSolutionId
-            },
-            calculateConfigurations: this.formQuery.items
-          }
-          try {
-            await saveSolution(query)
-            this.$refs.dialog.close()
-            this.$emit('refresh')
-            this.$message.success('保存成功')
-          } catch (error) {
-            this.$message.error(error)
-          }
-        }
-      })
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-
+::v-deep .el-tree-node__content {
+  height: 40px;
+}
+.text-gray {
+  color: grey;
+}
+.tools {
+  display: flex;
+  justify-content: flex-end;
+}
 </style>