sen
2026-02-01 93f8c736fd50a80a72d633e888e2d65904bcd7fc
ui/admin-ui3/src/views/cwgl/voucherSubjectSetting/index.vue
@@ -1,214 +1,642 @@
<template>
  <basicContainer >
    <avue-crud
        :option="option"
        :table-loading="pageF.loading"
        :data="tableData"
        :page="page"
        :permission="permissionList"
        :before-open="beforeOpen"
        v-model="form"
        ref="crudRef"
        @row-update="rowUpdate"
        @row-save="rowSave"
        @refresh-change="refreshChange"
        @row-del="rowDel"
        @search-change="searchChange"
        @search-reset="searchReset"
        @selection-change="selectionChange"
        @current-change="currentChange"
        @size-change="sizeChange"
        @on-load="onLoad"
    >
  <basicContainer>
    <el-tabs v-model="activeAccountSet" @tab-click="handleTabClick">
      <el-tab-pane label="珠海汇畅" name="0"></el-tab-pane>
      <el-tab-pane label="广珠物流贸易" name="1"></el-tab-pane>
    </el-tabs>
    <avue-crud :option="option" :table-loading="pageF.loading" :data="tableData" :page="page"
      :permission="permissionList" :before-open="beforeOpen" v-model="form" ref="crudRef" @row-update="rowUpdate"
      @row-save="rowSave" @refresh-change="refreshChange" @row-del="rowDel" @search-change="searchChange"
      @search-reset="searchReset" @selection-change="selectionChange" @current-change="currentChange"
      @size-change="sizeChange" @on-load="onLoad">
      <template #menu-left>
        <el-button
            type="success"
            icon="Edit"
            :disabled="pageF.single"
            v-hasPermi="['cwgl:voucherSubjectSetting:edit']"
            @click="handleUpdate">修改
        <el-button type="success" icon="Edit" :disabled="pageF.single" v-hasPermi="['cwgl:voucherSubjectSetting:edit']"
          @click="handleUpdate">修改
        </el-button>
        <el-button
            type="danger"
            icon="Delete"
            :disabled="pageF.multiple"
            @click="handleDelete"
            v-hasPermi="['cwgl:voucherSubjectSetting:remove']"
        >删除
        <el-button type="danger" icon="Delete" :disabled="pageF.multiple" @click="handleDelete"
          v-hasPermi="['cwgl:voucherSubjectSetting:remove']">删除
        </el-button>
        <el-button
            type="warning"
            plain
            icon="Download"
            @click="handleExport"
            v-hasPermi="['cwgl:voucherSubjectSetting:export']"
        >导出
        <el-button type="warning" plain icon="Download" @click="handleExport"
          v-hasPermi="['cwgl:voucherSubjectSetting:export']">导出
        </el-button>
      </template>
      <template #menu="{ row, index, size }">
        <el-button type="primary" text icon="Plus" @click="handleRowAdd(row)">新增子项</el-button>
      </template>
    </avue-crud>
  </basicContainer>
</template>
<script setup name="voucherSubjectSetting" lang="ts">
  import {VoucherSubjectSettingI,addVoucherSubjectSetting, delVoucherSubjectSetting, exportVoucherSubjectSetting, getVoucherSubjectSetting, listVoucherSubjectSetting, updateVoucherSubjectSetting} from "@/api/cwgl/voucherSubjectSetting";
  import useCurrentInstance from "@/utils/useCurrentInstance";
  import {computed,reactive, ref, toRefs} from "vue";
  import {PagesInterface, PageQueryInterface} from "@/utils/globalInterface";
  import {usePagePlus} from "@/hooks/usePagePlus";
  import {hasPermission} from "@/utils/permissionUtils";
import { VoucherSubjectSettingI, addVoucherSubjectSetting, delVoucherSubjectSetting, exportVoucherSubjectSetting, getVoucherSubjectSetting, listVoucherSubjectSetting, updateVoucherSubjectSetting } from "@/api/cwgl/voucherSubjectSetting";
import useCurrentInstance from "@/utils/useCurrentInstance";
import { computed, reactive, ref, toRefs } from "vue";
import { PagesInterface, PageQueryInterface } from "@/utils/globalInterface";
import { usePagePlus } from "@/hooks/usePagePlus";
import { hasPermission } from "@/utils/permissionUtils";
  const { proxy } = useCurrentInstance();
  const crudRef = ref();
const { proxy } = useCurrentInstance();
const crudRef = ref();
  const permissionList = computed(()=>{
    return {
      addBtn: hasPermission(["cwgl:voucherSubjectSetting:add"]),
      delBtn: hasPermission(["cwgl:voucherSubjectSetting:remove"]),
      editBtn: hasPermission(["cwgl:voucherSubjectSetting:edit"]),
      viewBtn: hasPermission(["cwgl:voucherSubjectSetting:query"]),
    }
  })
  const data = reactive({
    form:<VoucherSubjectSettingI>{},
    queryParams:<VoucherSubjectSettingI&PageQueryInterface>{},
    page: <PagesInterface>{
      pageSize: 10,
      total: 0,
      currentPage: 1,
const permissionList = computed(() => {
  return {
    addBtn: hasPermission(["cwgl:voucherSubjectSetting:add"]),
    delBtn: hasPermission(["cwgl:voucherSubjectSetting:remove"]),
    editBtn: hasPermission(["cwgl:voucherSubjectSetting:edit"]),
    viewBtn: hasPermission(["cwgl:voucherSubjectSetting:query"]),
  }
})
// 记录是否来自行内操作
const isFromRow = ref(false);
const activeAccountSet = ref("0");
const data = reactive({
  form: <VoucherSubjectSettingI>{},
  queryParams: <VoucherSubjectSettingI & PageQueryInterface>{
    type: "0",
    accountingItemsContains: [], // 必须初始化为数组
  },
  page: <PagesInterface>{
    pageSize: 10,
    total: 0,
    currentPage: 1,
  },
  selectionList: [],
})
const { queryParams, form, page, selectionList } = toRefs(data);
const option = ref({
  pageKey: 'VoucherSubjectSetting',
  rowKey: 'id',
  searchSpan: 5,
  labelWidth: 150,
  searchLabelWidth: 120,
  column: {
    // id: {
    //   label: '科目ID11',
    // },
    // parentId: {
    //   label: '父科目ID',
    // },
    // ancestors: {
    //   label: '祖级列表',
    //   type: 'textarea', minRows: 3, maxRows: 5,
    // },
    //   type: {
    //   label: '帐套类型',
    //   search: true,
    //   minWidth: 120,
    //   type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/sys_accounting_type',
    //   rules: [
    //     {
    //       required: true,
    //       message: "帐套类型不能为空", trigger: "change"
    //     }
    //   ],
    // },
    accountSet: {
      label: '账套',
      search: true,
      minWidth: 120,
      addDisabled: true,
      editDisabled: true,
      type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/sys_accounting_type',
      rules: [
        {
          required: true,
          message: "帐套类型不能为空", trigger: "change"
        }
      ],
    },
    selectionList:[],
  })
  const {queryParams,form,page,selectionList} = toRefs(data);
  const option = ref({
    pageKey: 'VoucherSubjectSetting',
    rowKey: 'id',
    column: {
                                id: {
          label: '科目ID',
                            },
                                parentId: {
          label: '父科目ID',
                            },
                                ancestors: {
          label: '祖级列表',
                      type: 'textarea', minRows: 3, maxRows: 5,
                            },
                                accountSet: {
          label: '账套',
                                rules: [
              {
                required: true,
                message: "账套不能为空", trigger: "blur" }
            ],                  },
                                subjectCode: {
          label: '科目代码',
                                rules: [
              {
                required: true,
                message: "科目代码不能为空", trigger: "blur" }
            ],                  },
                                subjectName: {
          label: '科目名称',
                                rules: [
              {
                required: true,
                message: "科目名称不能为空", trigger: "blur" }
            ],                  },
                                subjectType: {
          label: '科目类别',
                                rules: [
              {
                required: true,
                message: "科目类别不能为空", trigger: "change"
                 }
            ],                  },
                                enabled: {
          label: '启用',
                            },
                                balanceDirection: {
          label: '余额方向',
                                rules: [
              {
                required: true,
                message: "余额方向不能为空", trigger: "blur" }
            ],                  },
                                accountingItems: {
          label: '核算项目',
                      type: 'textarea', minRows: 3, maxRows: 5,
                            },
                                quantityAmountAccounting: {
          label: '数量金额核算',
                            },
                                cashSubject: {
          label: '现金科目',
                            },
                                bankSubject: {
          label: '银行科目',
                            },
                                cashFlowSubject: {
          label: '现金流量科目',
                            },
                                expenseName: {
          label: '费用名称',
                            },
                                mnemonicCode: {
          label: '助记码',
                            },
                                foreignCurrencyAccounting: {
          label: '外币核算',
                            },
                                unitOfMeasurement: {
          label: '计量单位',
                            },
                                orderNum: {
          label: '显示顺序',
                            },
                                status: {
          label: '状态',
                            },
                                delFlag: {
          label: '删除标志',
                            },
                                createBy: {
          label: '创建者',
                            },
                                createTime: {
          label: '创建时间',
                            },
                                updateBy: {
          label: '更新者',
                            },
                                updateTime: {
          label: '更新时间',
                            },
                                remark: {
          label: '备注',
                      type: 'textarea', minRows: 3, maxRows: 5,
                            },
          }
  })
    // parentSubjectName: {
    //   label: '上级科目名称2',
    //   minWidth: 150,
  const { tableData,pageF,rowSave,rowUpdate,rowDel,beforeOpen,searchChange,
    searchReset,selectionChange,onLoad,currentChange,sizeChange,handleDelete,handleExport,handleUpdate,refreshChange} = usePagePlus({
    form:form,
    option:option,
    queryParams:queryParams,
    idKey:'id',
    page:page.value,
    getListApi:listVoucherSubjectSetting,
    getDetailApi:getVoucherSubjectSetting,
    exportApi:exportVoucherSubjectSetting,
    deleteApi:delVoucherSubjectSetting,
    addApi:addVoucherSubjectSetting,
    updateApi:updateVoucherSubjectSetting,
    handleUpdateFunc:()=>{
    //   search: true,
    //   rules: [
    //     {
    //       required: true,
    //       message: "科目名称不能为空", trigger: "blur"
    //     }
    //   ],
    // },
    parentId: {
      label: '上级科目名称',
      prop: 'parentId',
      type: 'tree',
      hide: true,
      dicData: [],
      props: {
        label: 'fullName', // 关键点:绑定我们预处理好的全路径字段
        value: 'id'
      },
      addDisabled: true,
      editDisabled: true,
      rules: [
        { required: true, message: "上级科目不能为空", trigger: "change" }
      ]
    },
    parentSubjectCode: {
      label: '上级科目代码',
      minWidth: 150,
      disabled: true, // 设置为禁用,仅供查看
      // 如果希望在表格也显示,这里不要写 hide: true
    },
    parentSubjectCode: {
      label: '上级科目代码',
      minWidth: 150,
      search: true,
      // rules: [
      //   {
      //     required: true,
      //     message: "科目名称不能为空", trigger: "blur"
      //   }
      // ],
    },
    // parentSubjectCode: {
    //   label: '上级科目代码',
    //   minWidth: 150,
    //   display: true,
    //   hide: true,            // 在表格列中隐藏
    //   search: false,         // 在搜索栏中隐藏
    //   display: true,         // 在新增/修改弹窗中显示(默认为true)
    //   addDisabled: true,     // 新增时置灰,不可编辑
    //   editDisabled: true,    // 修改时置灰,不可编辑
    //   // readonly: true,      // 或者使用只读属性(取决于 UI 需求)
    //   // rules: [
    //   //   {
    //   //     required: true,
    //   //     message: "上级科目代码不能为空", trigger: "blur"
    //   //   }
    //   // ],
    // },
    subjectName: {
      label: '科目名称',
      minWidth: 150,
      search: true,
      rules: [
        {
          required: true,
          message: "科目名称不能为空", trigger: "blur"
        }
      ],
    },
    subjectCode: {
      label: '科目代码',
      minWidth: 150,
      search: true,
      rules: [
        {
          required: true,
          message: "科目代码不能为空", trigger: "blur"
        }
      ],
    },
    balanceDirection: {
      label: '余额方向',
      search: true,
      minWidth: 120,
      type: 'radio',
      dicUrl: '/system/dict/data/type/sys_balance_direction',
      rules: [
        {
          required: true,
          message: "余额方向不能为空", trigger: "blur"
        }
      ],
    },
    enabled: {
      label: '是否启用',
      minWidth: 120,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_whether_type',
      rules: [
        {
          required: true,
          message: "是否启用不能为空", trigger: "change"
        }
      ],
      search: true,
    },
    accountingItemsDesc: {
      label: '核算项目',
      minWidth: 150,
      addDisplay: false,
      editDisplay: false,
    },
    accountingItemsContains: {
      label: '核算项目1',
      minWidth: 150,
      search: true,
      type: 'select', // 确保类型为 select
      multiple: true, // 开启多选
      addDisplay: false,    // 在新增时隐藏
      editDisplay: false,
      hide: true,
      dataType: 'string',
      dicUrl: '/system/dict/data/type/sys_accounting_item_name',
      placeholder: '请选择核算项目(可多选)',
      props: {
        label: 'dictLabel',
        value: 'dictValue'
      }
    },
    accountingItems: {
      label: '核算项目2',
      minWidth: 150,
      type: 'select',
      multiple: true,
      dicUrl: '/system/dict/data/type/sys_accounting_item_name',
      placeholder: '请选择核算项目(可多选)',
      props: {
        label: 'dictLabel',
        value: 'dictValue'
      },
      // --- 关键修改 ---
      hide: true,           // 在表格列中隐藏
      search: false,        // 在搜索栏中隐藏
      display: true,        // 确保在弹窗表单中依然显示(默认即为 true)
      // ----------------
      minWidth: 150
    },
    subjectType: {
      label: '科目类别',
      minWidth: 150,
      minWidth: 120,
      type: 'select', dicUrl: '/system/dict/data/type/sys_subject_category',
      rules: [
        {
          required: true,
          message: "科目类别不能为空", trigger: "change"
        }
      ],
      search: true,
    },
    quantityAmountAccounting: {
      label: '数量金额核算',
      minWidth: 120,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_right_wrong',
      rules: [
        {
          required: true,
          message: "数量金额核算不能为空", trigger: "change"
        }
      ],
    },
    unitOfMeasurement: {
      label: '计量单位',
      minWidth: 150,
    },
    expenseName: {
      label: '费用名称',
      minWidth: 120,
      type: 'select', dicUrl: '/system/dict/data/type/sys_name_harge',
      rules: [
        {
          required: true,
          message: "费用名称不能为空", trigger: "change"
        }
      ],
      search: true,
    },
    mnemonicCode: {
      label: '助记码',
      minWidth: 150,
    },
    foreignCurrencyAccounting: {
      label: '外币核算',
      minWidth: 150,
      type: 'select', dicUrl: '/system/dict/data/type/sys_foreign_verification',
    },
    cashSubject: {
      label: '现金科目',
      minWidth: 150,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_right_wrong',
    },
    bankSubject: {
      label: '银行科目',
      minWidth: 150,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_right_wrong',
    },
    cashFlowSubject: {
      label: '现金流量科目',
      minWidth: 150,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_right_wrong',
    },
    contactUnit: {
      label: '往来单位',
      minWidth: 150,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_right_wrong',
    },
    department: {
      label: '部门',
      minWidth: 150,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_right_wrong',
    },
    productName: {
      label: '品名',
      minWidth: 150,
      type: 'radio', dicUrl: '/system/dict/data/type/sys_right_wrong',
    },
    // orderNum: {
    //   label: '显示顺序',
    // },
    // status: {
    //   label: '状态',
    // },
    // delFlag: {
    //   label: '删除标志',
    // },
    // createBy: {
    //   label: '创建者',
    // },
    // createTime: {
    //   label: '创建时间',
    // },
    // updateBy: {
    //   label: '更新者',
    // },
    // updateTime: {
    //   label: '更新时间',
    // },
    // remark: {
    //   label: '备注',
    //   type: 'textarea', minRows: 3, maxRows: 5,
    // },
  }
})
// sys_accounting_type
// listVoucherSubjectSetting
const { tableData, pageF, rowSave, rowUpdate, rowDel, beforeOpen, searchChange,
  searchReset, selectionChange, onLoad, currentChange, sizeChange, handleDelete, handleExport, handleUpdate, refreshChange } = usePagePlus({
    form: form,
    option: option,
    queryParams: queryParams,
    idKey: 'id',
    page: page.value,
    getListApi: listVoucherSubjectSetting,
    getDetailApi: getVoucherSubjectSetting,
    // 【关键修复点】:拦截详情接口,在数据进入 form 之前完成格式化
    getDetailApi: (id: any) => {
      return getVoucherSubjectSetting(id).then((res: any) => {
        if (res.code === 200 && res.data) {
          // 1. 处理 accountingItems 数字转数组
          if (typeof res.data.accountingItems === 'number') {
            res.data.accountingItems = decomposeAccountingItems(res.data.accountingItems);
          } else if (!res.data.accountingItems) {
            res.data.accountingItems = [];
          }
          // 2. 处理 accountingItemsContains 确保是数组
          if (!Array.isArray(res.data.accountingItemsContains)) {
            res.data.accountingItemsContains = [];
          }
        }
        return res;
      });
    },
    exportApi: exportVoucherSubjectSetting,
    deleteApi: delVoucherSubjectSetting,
    addApi: addVoucherSubjectSetting,
    updateApi: updateVoucherSubjectSetting,
    handleUpdateFunc: () => {
      isFromRow.value = true; // 修改操作也视为禁用上级科目
      crudRef.value.rowEdit(selectionList.value[0]);
    },
    handleSelectionChangeFunc:(selection:any)=>{
    handleSelectionChangeFunc: (selection: any) => {
      selectionList.value = selection;
    }
    },
    getBeginListFunc: (params = {}) => {
      let newParams = { ...params };
      newParams.type = activeAccountSet.value;
      // 处理 accountingItems 参数
      if (newParams.accountingItemsContains) {
        if (Array.isArray(newParams.accountingItemsContains)) {
          // 如果是数组,按原逻辑处理
          newParams.accountingItemsContains = newParams.accountingItemsContains.join(',');
        } else {
          // 如果是字符串,检查是否为逗号分隔的数字
          const itemsStr = String(newParams.accountingItemsContains).trim();
          if (itemsStr && itemsStr.includes(',')) {
            // 分割字符串,转换为数字并相加
            const sum = itemsStr
              .split(',')
              .map(item => parseInt(item.trim(), 10))
              .filter(num => !isNaN(num))
              .reduce((acc, curr) => acc + curr, 0);
            // 使用相加后的结果
            newParams.accountingItemsContains = sum > 0 ? sum.toString() : '';
          }
        }
      }
      queryParams.value = newParams;
      return newParams;
    },
    handleBeforeOpenFunc: (type: string) => {
      if (!option.value?.column) return;
      const codeCol = option.value.column.parentSubjectCode;
      const parentIdCol = option.value.column.parentId;
      // --- 1. 定义名称递归处理器 ---
      const formatTreeData = (list: any[], parentName = '') => {
        return list.map(item => {
          // 拼接全路径:父级名称 > 当前名称
          const currentFullName = parentName ? `${parentName} > ${item.subjectName}` : item.subjectName;
          const newItem = {
            ...item,
            fullName: currentFullName
          };
          // 如果有子节点,继续递归
          if (newItem.children && newItem.children.length > 0) {
            newItem.children = formatTreeData(newItem.children, currentFullName);
          }
          return newItem;
        });
      };
      // --- 2. 加载并处理字典数据 ---
      listVoucherSubjectSetting({ type: activeAccountSet.value }).then(res => {
        // 将扁平数据转为树结构 (proxy.handleTree 是 Ruoyi 常用工具)
        const treeData = proxy.handleTree(res.rows, "id", "parentId");
        // 执行全路径拼接
        const fullPathTree = formatTreeData(treeData);
        // 组合最终字典,加入“顶级”选项
        const fullDic = [
          {
            id: 0,
            subjectName: '顶级科目',
            fullName: '顶级科目',
            children: fullPathTree
          }
        ];
        if (parentIdCol) parentIdCol.dicData = fullDic;
        // 异步回调中再次确保代码字段显示
        if (String(form.value.parentId) === "0" || !form.value.parentId) {
          form.value.parentSubjectCode = "顶级科目代码";
        }
      });
      // --- 3. 处理不同模式下的显示逻辑 ---
      if (type !== 'add') {
        // 【修改/查看】
        if (String(form.value.parentId) === "0" || !form.value.parentId) {
          form.value.parentSubjectCode = "顶级科目代码";
        }
        if (parentIdCol) { parentIdCol.display = true; parentIdCol.disabled = true; }
        if (codeCol) { codeCol.display = true; codeCol.disabled = true; }
      } else {
        // 【新增】
        if (isFromRow.value) {
          // 行内新增子项
          if (parentIdCol) { parentIdCol.display = true; parentIdCol.disabled = true; }
          if (codeCol) { codeCol.display = true; codeCol.disabled = true; }
        } else {
          // 顶部新增 (默认是顶级科目)
          if (parentIdCol) parentIdCol.display = false;
          if (codeCol) codeCol.display = false;
          const currentSet = activeAccountSet.value;
          Object.assign(form.value, {
            id: undefined,
            parentId: 0,
            parentSubjectCode: "无",
            accountSet: currentSet,
            type: currentSet,
            accountingItems: [],
            enabled: "1"
          });
        }
      }
      // --- 4. 格式化多选字段 ---
      const fieldsToFix = ['accountingItems', 'accountingItemsContains'];
      fieldsToFix.forEach(field => {
        const val = form.value[field];
        if (typeof val === 'number') {
          form.value[field] = decomposeAccountingItems(val);
        } else if (!Array.isArray(val)) {
          form.value[field] = [];
        }
      });
      nextTick(() => {
        isFromRow.value = false;
      });
    },
    // 新增保存前的逻辑
    rowSaveBegin: (row: any, done: any, loading: any) => {
      processAccountingItems(row);
      delete row.accountingItemsContains;
      // 如果 row 对象里带了 id,新增接口可能会报错或变成修改,如果是顶部新增,确保没有 id
      if (!isFromRow.value) {
        delete row.id;
      }
      done(row); // 必须调用 done 并传入处理后的 row 才会继续请求接口
    },
    // 修改保存前的逻辑
    rowUpdateBegin: (row: any, done: any, loading: any) => {
      processAccountingItems(row);
      delete row.accountingItemsContains;
      if (row.parentSubjectCode == "顶级科目代码") {
        row.parentSubjectCode = row.subjectCode;
      }
      done(row); // 同理
    },
  })
const processAccountingItems = (row: any) => {
  if (!row.accountingItems) {
    row.accountingItems = 0;
    return;
  }
  // 1. 如果已经是数组(正常多选组件返回的结果)
  if (Array.isArray(row.accountingItems)) {
    row.accountingItems = row.accountingItems
      .map(item => parseInt(String(item), 10))
      .filter(num => !isNaN(num))
      .reduce((acc, curr) => acc + curr, 0);
  }
  // 2. 如果是逗号分隔的字符串
  else if (typeof row.accountingItems === 'string' && row.accountingItems.includes(',')) {
    row.accountingItems = row.accountingItems
      .split(',')
      .map(item => parseInt(item.trim(), 10))
      .filter(num => !isNaN(num))
      .reduce((acc, curr) => acc + curr, 0);
  }
  // 3. 如果已经是数字,保持不变
  console.log('转换后的提交值:', row.accountingItems);
};
const handleTabClick = (tab: any) => {
  const selectedTabName = tab.props.name;
  console.log("Tab点击的值:", selectedTabName);
  activeAccountSet.value = selectedTabName;
  queryParams.value.type = selectedTabName;
  const nextParams = {
    ...queryParams.value,
    type: selectedTabName
  };
  // 4. 重置分页并加载
  page.value.currentPage = 1;
  onLoad(page.value, nextParams);
}
/**
 * 拆分函数:将 3 转换为 ['1', '2']
 */
function decomposeAccountingItems(num: number): string[] {
  const result: string[] = [];
  let bit = 1;
  while (bit <= num) {
    if ((num & bit) === bit) {
      result.push(bit.toString());
    }
    bit <<= 1; // 位移运算,等同于 bit *= 2
  }
  return result;
}
/**
 * 处理行内“新增”点击
 */
const handleRowAdd = (row: any) => {
  isFromRow.value = true;
  getVoucherSubjectSetting(row.id).then((res: any) => {
    if (res.code == 200) {
      form.value = res.data;
      form.value.parentId = form.value.id;
      const num = form.value.accountingItems;
      form.value.accountingItems = decomposeAccountingItems(num);
      // 触发 Avue 的内置新增弹窗
      crudRef.value.rowAdd();
    }
  });
};
</script>