瀏覽代碼

JLHWeb:前端代码更新

JohnnyChan 5 月之前
父節點
當前提交
7ee07778b8

+ 20 - 18
JLHWEB/src/components/LjDetail/components/BaseForm.vue

@@ -557,6 +557,7 @@
                                   :column="getBaseFormCol(item)"
                                   :field-names="item.fieldNames"
                                   :search-param="searchParam"
+                                  :disabled="!editable"
                                 />
                               </template>
                               <el-input
@@ -629,6 +630,7 @@
                                   :column="getBaseFormCol(item)"
                                   :field-names="item.fieldNames"
                                   :search-param="searchParam"
+                                  :disabled="!editable"
                                 />
                               </template>
                               <el-input v-else :value="formatFunc(searchParam[handleProp(item.field!)], item)" disabled />
@@ -2130,26 +2132,26 @@ const getSpan = (span: any, size: any) => {
  */
 const getBaseFormCol = (item: any) => {
   let obj: any = {};
-  if (editable.value) {
-    // console.log("getBaseFormCol item :>> ", item);
-    if (item?.basicinfo) {
-      obj = { ...item };
-      if (item.basicinfo.el) {
-        obj = { ...item, ...item.basicinfo };
-        obj.render = item.basicinfo?.render;
-      } else {
-        item.basicinfo?.render && (obj.render = item.basicinfo?.render);
-      }
-    } else if (item?.render) {
-      obj = { ...item };
-    }
-  } else {
-    if (item?.basicinfo && item.basicinfo?.render) {
-      obj = { ...item, render: item.basicinfo?.render };
-    } else if (item?.render) {
-      obj = { ...item };
+  // if (editable.value) {
+  // console.log("getBaseFormCol item :>> ", item);
+  if (item?.basicinfo) {
+    obj = { ...item };
+    if (item.basicinfo.el) {
+      obj = { ...item, ...item.basicinfo };
+      obj.render = item.basicinfo?.render;
+    } else {
+      item.basicinfo?.render && (obj.render = item.basicinfo?.render);
     }
+  } else if (item?.render) {
+    obj = { ...item };
   }
+  // } else {
+  // if (item?.basicinfo && item.basicinfo?.render) {
+  //   obj = { ...item, render: item.basicinfo?.render };
+  // } else if (item?.render) {
+  //   obj = { ...item };
+  // }
+  // }
   return obj;
 };
 

+ 3 - 3
JLHWEB/src/components/LjDetail/index.vue

@@ -179,7 +179,7 @@ console.log("Ljdetail currentLayout :>> ", currentLayout);
  */
 const FoldLayoutFilterAttr = ["width", "hidden", "lastWidth"];
 
-const emit = defineEmits(["update:orderStatus", "toPinDetail"]);
+const emit = defineEmits(["update:orderStatus", "toPinDetail", "afterMounted"]);
 
 const basicinfoFormDefaultComputed = Object.assign(DETAIL_BASICINFO_FORM_DEFINE, props.basicDefault);
 
@@ -1187,11 +1187,11 @@ onMounted(async () => {
       console.log("_mainData :>> ", _mainData.value);
       console.log("props.data :>> ", props.data);
       console.log("onMounted detail end!!!! :>> ");
-      props.afterMound && props.afterMound(_mainData.value);
+      emit("afterMounted", _mainData.value);
     });
   } else {
     console.log("onMounted detail end!!!! :>> ");
-    props.afterMound && props.afterMound(_mainData.value);
+    emit("afterMounted", _mainData.value);
   }
 });
 

+ 0 - 5
JLHWEB/src/components/LjDetail/interface/index.ts

@@ -331,11 +331,6 @@ export interface DetailProp extends aboutVxetableApiProps {
    * @description 是否fold布局
    */
   ifFoldLayout?: boolean;
-  /**
-   * @argument function
-   * @description 布局加载后,执行函数
-   */
-  afterMound?: (data: any) => void;
   /**
    * @description 是否可编辑布局
    */

+ 298 - 55
JLHWEB/src/components/LjVxeTable/index.vue

@@ -1,8 +1,10 @@
+<!-- 📚📚📚 Vxe-Table 文档: https://vxetable.cn/#/table/start/install -->
+
 <template>
   <!-- 查询表单 card -->
   <!-- <div class="table-box"> -->
   <SearchForm
-    v-if="isShowSearch"
+    v-if="ifSearch && isShowSearch"
     :search="search"
     :reset="reset"
     :columns="searchColumns"
@@ -241,7 +243,7 @@
         <slot></slot>
         <template v-for="item in tableColumns" :key="item">
           <!-- checkbox || seq || expand -->
-          <vxe-column v-bind="item" :align="item.align ?? 'center'" v-if="item?.type && TABLE_TYPE_FILTER.includes(item.type)">
+          <vxe-column v-bind="item" :align="item.align ?? 'center'" v-if="item.type && TABLE_TYPE_FILTER.includes(item.type)">
             <template #content="scope" v-if="item.type == 'expand'">
               <slot :name="item.type" v-bind="scope"></slot>
             </template>
@@ -458,6 +460,8 @@ import { pinyinFilter } from "@/utils/pinyin";
 import { TourEnum } from "@/enums/tourEnum";
 import { useTour } from "@/hooks/useTour";
 // import { onKeyStroke } from "@vueuse/core";
+import dayjs from "dayjs";
+import { onClickOutside } from "@vueuse/core";
 
 const { t } = useI18n();
 const globalStore = useGlobalStore();
@@ -508,23 +512,23 @@ const props = withDefaults(defineProps<LjVxetableProps>(), {
   layoutAttr: () => TABLE_LAYOUT_ATTR,
   layoutAttrDefine: () => TABLE_LAYOUT_ATTR_DEFINE,
   // height: "auto",
-  tableCls: "card",
+  tableCls: "card h-full",
   tableProps: {},
   extraLoading: false,
   tableEvents: {},
   toolButton: () => ["refresh", "setting", "search", "location"],
   toolButtonPower: () => [],
   autoLoadLayout: true,
-  collapseButtons: false,
+  collapseButtons: true,
   miniSearchbar: true,
   footerSumAttrs: () => [],
   searchBtnSizeExtent: () => ["xs", "sm", "md"],
   multiSelect: undefined,
   editable: false,
   autoSelectFirstAfterRefresh: false,
-  ifLoadQueryHabit: true
+  ifLoadQueryHabit: true,
+  ifSearch: true
 });
-
 /**
  * @description 是否可编辑
  */
@@ -535,9 +539,23 @@ const _defineProps = ref({
   border: true,
   showOverflow: "tooltip",
   showHeaderOverflow: true,
-  height: "",
+  height: "auto",
   minHeight: "100px",
-  rowConfig: { isCurrent: true, isHover: true, useKey: true },
+  rowConfig: {
+    isCurrent: true,
+    isHover: true,
+    useKey: true,
+    currentMethod: ({ row }: any) => {
+      if (Object.keys(props).includes("lockRow")) {
+        if (isBoolean(props?.lockRow)) {
+          return !props.lockRow;
+        } else if (isFunction(props?.lockRow)) {
+          return !props?.lockRow(row);
+        }
+      }
+      return true;
+    }
+  },
   columnConfig: { isHover: true, resizable: true },
   exportConfig: {},
   sortConfig: { trigger: "cell", multiple: true, chronological: true, defaultSort: {}, showIcon: false },
@@ -720,8 +738,6 @@ const _defineProps = ref({
 });
 
 // const propsDefine = Object.assign(_defineProps.value, props.tableProps);
-const propsDefine = defaultsDeep(props.tableProps, _defineProps.value);
-console.log("init propsDefine :>> ", propsDefine);
 
 interface RowVO {
   [key: string]: any;
@@ -751,12 +767,102 @@ const getToolButton = (type: string) => {
   return false;
 };
 
+const emit = defineEmits([
+  "afterMounted",
+  "firstMounted",
+  "layoutChange",
+  "keydownStart",
+  "keydown",
+  "keydownEnd",
+  "currentChange",
+  "radioChange",
+  "checkboxChange",
+  "checkboxAll",
+  "checkboxRangeStart",
+  "checkboxRangeChange",
+  "checkboxRangeEnd",
+  "cellClick",
+  "cellDblclick",
+  "cellMenu",
+  "cellMouseenter",
+  "cellMouseleave",
+  "cellDeleteValue",
+  "headerCellClick",
+  "headerCellDblclick",
+  "headerCellMenu",
+  "footerCellClick",
+  "footerCellDblclick",
+  "footerCellMenu",
+  "clearMerge",
+  "sortChange",
+  "clearSort",
+  "filterChange",
+  "filterVisible",
+  "clearFilter",
+  "resizableChange",
+  "toggleRowExpand",
+  "toggleTreeExpand",
+  "menuClick",
+  "cellSelected",
+  "editClosed",
+  "editActivated",
+  "editDisabled",
+  "validError",
+  "scroll",
+  "scrollBoundary",
+  "custom"
+]);
 // 表格绑定的事件
 const propsEvents = computed(() => {
   let defineEv = {
-    "resizable-change": handleResizChange,
-    "sort-change": handleSortChange,
-    "cell-selected": handleCellSelected,
+    keydownStart: (data: any) => emit("keydownStart", data),
+    keydown: (data: any) => emit("keydown", data),
+    keydownEnd: (data: any) => emit("keydownEnd", data),
+    currentChange: (data: any) => emit("currentChange", data),
+    radioChange: (data: any) => emit("radioChange", data),
+    checkboxChange: (data: any) => emit("checkboxChange", data),
+    checkboxAll: (data: any) => emit("checkboxAll", data),
+    checkboxRangeStart: (data: any) => emit("checkboxRangeStart", data),
+    checkboxRangeChange: (data: any) => emit("checkboxRangeChange", data),
+    checkboxRangeEnd: (data: any) => emit("checkboxRangeEnd", data),
+    cellClick: (data: any) => emit("cellClick", data),
+    cellDblclick: (data: any) => emit("cellDblclick", data),
+    cellMenu: (data: any) => emit("cellMenu", data),
+    cellMouseenter: (data: any) => emit("cellMouseenter", data),
+    cellMouseleave: (data: any) => emit("cellMouseleave", data),
+    cellDeleteValue: (data: any) => emit("cellDeleteValue", data),
+    headerCellClick: (data: any) => emit("headerCellClick", data),
+    headerCellDblclick: (data: any) => emit("headerCellDblclick", data),
+    headerCellMenu: (data: any) => emit("headerCellMenu", data),
+    footerCellClick: (data: any) => emit("footerCellClick", data),
+    footerCellDblclick: (data: any) => emit("footerCellDblclick", data),
+    footerCellMenu: (data: any) => emit("footerCellMenu", data),
+    clearMerge: (data: any) => emit("clearMerge", data),
+    sortChange: (data: any) => {
+      handleSortChange(data);
+      emit("sortChange", data);
+    },
+    clearSort: (data: any) => emit("clearSort", data),
+    filterChange: (data: any) => emit("filterChange", data),
+    filterVisible: (data: any) => emit("filterVisible", data),
+    clearFilter: (data: any) => emit("clearFilter", data),
+    resizableChange: (data: any) => {
+      handleResizChange(data);
+      emit("resizableChange", data);
+    },
+    toggleRowExpand: (data: any) => emit("toggleRowExpand", data),
+    toggleTreeExpand: (data: any) => emit("toggleTreeExpand", data),
+    cellSelected: (data: any) => {
+      handleCellSelected(data);
+      emit("cellSelected", data);
+    },
+    editClosed: (data: any) => emit("editClosed", data),
+    editActivated: (data: any) => emit("editActivated", data),
+    editDisabled: (data: any) => emit("editDisabled", data),
+    validError: (data: any) => emit("validError", data),
+    scroll: (data: any) => emit("scroll", data),
+    scrollBoundary: (data: any) => emit("scrollBoundary", data),
+    custom: (data: any) => emit("custom", data),
     menuClick({ menu, type, row, rowIndex, column, columnIndex, $event }: any) {
       console.log("menu :>> ", menu);
       console.log("menu row :>> ", row);
@@ -851,6 +957,8 @@ const propsEvents = computed(() => {
             column && clearSortEvent(column.field);
             break;
         }
+
+        emit("menuClick", { menu, type, row, rowIndex, column, columnIndex, $event });
       }
     }
   };
@@ -875,10 +983,10 @@ const loadDwLayout = (data: any) => {
 
   console.log("onMounted dwLayout.value :>> ", dwLayout.value);
   loadDwLayoutFunc(dwLayout.value);
-  tableColumns.value = cloneDeep(props.columns);
+  // tableColumns.value = cloneDeep(props.columns);
   console.log("数行化BF,还原个性设置 tableColumns.value :>> ", tableColumns.value);
   // 扁平化,并读取个性设置
-  flatColumns.value = flatColumnsFunc(tableColumns.value, dwFieldMap);
+  flatColumns.value = flatColumnsFunc(cloneDeep(props.columns), dwFieldMap);
   console.log("读取个性设置 flatColumns.value  loadDwLayout:>> ", flatColumns.value);
 
   initLayoutColumns();
@@ -939,6 +1047,49 @@ const TourSteps = [
 
 // 新手指导
 const { checkIfNeedGuide } = useTour(t, TourEnum.table, TourSteps);
+import { CommonDynamicSelect } from "@/api/modules/common";
+import { isNumber } from "xe-utils";
+import { isBoolean, isFunction } from "@/utils/is";
+const defaultRequest = (params: any) => {
+  let newParams: any = {};
+  params.pageNum && (newParams.pageindex = params.pageNum);
+  params.pageSize && (newParams.pagesize = params.pageSize);
+  delete params.pageNum;
+  delete params.pageSize;
+  newParams.queryParams = JSON.parse(JSON.stringify(params));
+  console.log("newParams", newParams);
+  let pkeys = Object.keys(newParams.queryParams);
+  console.log("pkeys :>> ", pkeys);
+  let flatSearchColumns = new Map<string, any>();
+  for (let searchCol of searchColumns.value) {
+    flatSearchColumns.set(searchCol.field || "", searchCol);
+  }
+  for (let pk of pkeys) {
+    console.log("pk :>> ", pk);
+    console.log("haspk", flatSearchColumns.has(pk));
+    if (flatSearchColumns.has(pk)) {
+      let searchInfo = flatSearchColumns.get(pk);
+      console.log("searchInfo :>> ", searchInfo);
+      if (searchInfo.search && searchInfo.search.props && searchInfo.search.props.type == "date") {
+        const today = dayjs(dayjs().format("YYYY-MM-DD"));
+        if (isNumber(newParams.queryParams[pk])) {
+          newParams.queryParams[pk] = today.add(newParams.queryParams[pk], "day").format("YYYY-MM-DD HH:mm:ss");
+        }
+      }
+    }
+  }
+  newParams.dsname = props.dwname;
+  return CommonDynamicSelect(newParams, newParams.dsname);
+};
+const defaultDataCallback = (data: any) => {
+  return {
+    list: data.datatable,
+    tableinfo: data.tableinfo,
+    total: data.totalcnt,
+    pageNum: data.pageindex,
+    pageSize: data.pagesize
+  };
+};
 
 // 表格操作 Hooks
 const {
@@ -955,10 +1106,10 @@ const {
   // handleCurrentChange,
   handlePageChange
 } = useTable(
-  props.requestApi,
+  props.requestApi || defaultRequest,
   props.initParam,
   props.pagination,
-  props.dataCallback,
+  props.dataCallback || defaultDataCallback,
   props.requestError,
   props.dwname,
   curPageSizes,
@@ -980,10 +1131,7 @@ const defineFooterMethod = ({ columns, data }: any) => {
       if (columnIndex === 1) {
         return data.length;
       }
-      if (
-        (!props.footerSumAttrs && column.field && column.field.indexOf("qty") > -1) ||
-        props.footerSumAttrs?.includes(column.field)
-      ) {
+      if ((column.field && column.field.indexOf("qty") > -1) || props.footerSumAttrs?.includes(column.field)) {
         let count = 0;
         data.forEach((item: any) => {
           count = floatAdd(count, isNaN(Number(item[column.field])) ? 0 : Number(item[column.field]));
@@ -994,13 +1142,45 @@ const defineFooterMethod = ({ columns, data }: any) => {
   ];
 };
 
+const propsDefine = defaultsDeep(props.tableProps, _defineProps.value);
+
 // 表格参数:init
-const tableOptions = reactive<VxeTableProps<RowVO>>({
+const tableOptions = reactive<any>({
   showFooter: typeof props.footerMethod != "boolean",
   footerMethod: typeof props.footerMethod != "boolean" ? props.footerMethod ?? defineFooterMethod : undefined,
   ...propsDefine
 });
 
+watch(
+  () => props.editable,
+  (newVal, oldVal) => {
+    tableOptions.editConfig.enabled = newVal;
+  }
+);
+console.log("init propsDefine :>> ", propsDefine);
+
+if (props?.multiSelect != undefined) {
+  tableOptions.checkboxConfig = {
+    range: true,
+    trigger: "cell",
+    highlight: true
+  };
+  tableOptions.checkboxConfig.checkField = props.multiSelect ?? "";
+
+  if (!props.columns.some(c => c.type == "checkbox")) {
+    props.columns.unshift({
+      type: "checkbox",
+      width: 50
+    });
+  }
+}
+if (props?.editable) {
+  if (tableOptions.editConfig == undefined) {
+    tableOptions.editConfig = { trigger: "click", mode: "cell" };
+  }
+  tableOptions.editConfig.enabled = props?.editable ?? false;
+}
+
 /**表格存储参数 */
 const tableprop_save = ref<dwnameSaveLayoutAttr>({
   scrollY: {},
@@ -1013,7 +1193,7 @@ const tableprop_save = ref<dwnameSaveLayoutAttr>({
 const isShowSearch = ref(true);
 
 // 是否更新数据
-const isUpdate = ref(false);
+const isUpdate = ref(0);
 
 // 表格 DOM 元素
 const tableRef = ref<VxeTableInstance>();
@@ -1086,7 +1266,8 @@ const {
   props.autoLoadLayout,
   props.dwname,
   loadLayoutCallBack,
-  flatColumnsCallBack
+  flatColumnsCallBack,
+  props?.editable
 );
 
 /**
@@ -1341,7 +1522,6 @@ const handleCellSelected = ({ row, rowIndex, $rowIndex, column, columnIndex, $co
 // };
 // provide("updateSettingColumn", fnUpdateSettingColumn);
 // const emit = defineEmits(["update:columns"]);
-const emit = defineEmits(["onMountedData"]);
 
 // const columnStreamlineFunc = (column: any, scrollParam?: any) => {
 //   let oriColumns = cloneDeep(props.columns);
@@ -1500,7 +1680,7 @@ const saveColumnsFunc = async (argColumns: any, param: any = {}, online: boolean
   console.log("arr :>> ", arr);
   // tableColumns.value = arr;
   // $table?.reloadColumn(arr);
-  // isUpdate.value = !isUpdate.value;
+  // isUpdate.value++;
   // console.log("settingConfirm tableColumns.value :>> ", tableColumns.value);
   // // 更新个性属性设置数据源
   // colSetting = cloneDeep(column);
@@ -1560,7 +1740,7 @@ const settingConfirm = async (column: any, param: any = {}, updateLocal = true,
 
     tableColumns.value = arr;
     $table?.reloadColumn(arr);
-    isUpdate.value = !isUpdate.value;
+    isUpdate.value++;
     console.log("settingConfirm tableColumns.value :>> ", tableColumns.value);
     console.log("warch project newVal settingConfirm tableprop_save.value:>> ", tableprop_save.value);
     // 更新个性属性设置数据源
@@ -1815,7 +1995,7 @@ const initLayoutColumns = () => {
 
   // tableRef.value?.reloadColumn(tableColumns.value);
   nextTick(() => {
-    isUpdate.value = !isUpdate.value;
+    isUpdate.value++;
   });
 
   // 过滤需要搜索的配置项
@@ -1852,6 +2032,22 @@ const initLayoutColumns = () => {
 
   // 排序搜索表单项
   searchColumns.value.sort((a, b) => a.search!.order! - b.search!.order!);
+  emit("layoutChange", tableColumns.value);
+};
+
+/**
+ * @description 获取表格数据后,自动执行选中第一行
+ */
+const afterGetData = () => {
+  emit("afterMounted", tableData.value);
+  if (props.autoSelectFirstAfterRefresh && tableData.value.length) {
+    nextTick(() => {
+      tableRef.value?.setCurrentRow(tableData.value[0]);
+      if (props.tableEvents && "current-change" in props.tableEvents) {
+        props.tableEvents["current-change"]({ newValue: tableData.value[0], row: tableData.value[0] });
+      }
+    });
+  }
 };
 
 // 初始化请求
@@ -1859,28 +2055,22 @@ onMounted(async () => {
   await loadLayoutFunc();
 
   initLayoutColumns();
+  console.log("onMounted .ifLoadQueryHabit :>> ", searchParam.value);
 
   if (props.requestAuto) {
     getTableList().then(() => {
-      emit("onMountedData", tableData.value);
+      emit("firstMounted", tableData.value);
       console.log("onMounted tableColumns.value :>> ", tableColumns.value);
 
       nextTick(() => {
+        // 指导
         props.toolButton.indexOf("guide") > -1 && checkIfNeedGuide();
-
-        props.afterMound && props.afterMound(tableData.value);
-        if (props.autoSelectFirstAfterRefresh && tableData.value.length) {
-          nextTick(() => {
-            tableRef.value?.setCurrentRow(tableData.value[0]);
-            if (props.tableEvents && "current-change" in props.tableEvents) {
-              props.tableEvents["current-change"]({ newValue: tableData.value[0] });
-            }
-          });
-        }
+        afterGetData();
       });
     });
   } else {
-    props.afterMound && props.afterMound(tableData.value);
+    emit("firstMounted", tableData.value);
+    afterGetData();
   }
 
   /**
@@ -1966,10 +2156,12 @@ const saveDefaultLayout = async (column: any, param: any, cb: any) => {
 /**
  * @description 主动刷新数据
  */
-const refresh = () => {
-  getTableList();
+const refresh = async () => {
+  await getTableList();
   nextTick(() => {
-    isUpdate.value = !isUpdate.value;
+    isUpdate.value++;
+
+    afterGetData();
   });
 };
 
@@ -2444,20 +2636,73 @@ const autoCloseLocation = () => {
 // 监听页面 initParam 改化,重新获取表格数据
 watch(
   () => props.initParam,
-  val => {
-    Object.assign(searchParam.value, val);
-    search();
+  async val => {
+    await search();
+    afterGetData();
   },
   { deep: true }
 );
 
+/**
+ * @description vxeTable方法封装
+ */
+const vxeTableEvents = {
+  getTableData: () => tableRef.value?.getTableData(),
+  insertAt: (records: any | any[], row?: any | -1 | 0) => tableRef.value?.insertAt(records, row),
+  setCurrentRow: (params: any) =>
+    nextTick(() => {
+      tableRef.value?.setCurrentRow(params);
+    }),
+  setRow: (rows: any, record: any) => tableRef.value?.setRow(rows, record),
+  remove: (params: any) => tableRef.value?.remove(params),
+  getCurrentRecord: () => tableRef.value?.getCurrentRecord(),
+  getCheckboxRecords: (isFull: any) => tableRef.value?.getCheckboxRecords(isFull),
+  /**
+   * @description 获取当前勾选/选中的数据,否则自动选择第一条数据
+   */
+  getCurrentRecords: () => {
+    const _records = tableRef.value?.getCheckboxRecords() ?? [];
+    const _cRecords = tableRef.value?.getCurrentRecord() ?? null;
+
+    let curRecords: any[] = [];
+    if (_records.length) {
+      // 获取勾选列表
+      curRecords = _records;
+    } else if (_cRecords) {
+      // 获取当前选中数据
+      curRecords = [_cRecords];
+    } else {
+      // 默认获取第一条记录
+      let visibleData = tableRef.value?.getTableData().visibleData;
+      if (visibleData?.length) {
+        curRecords = [visibleData[0]];
+        tableRef.value?.setCurrentRow(visibleData[0]);
+      }
+    }
+
+    return curRecords;
+  }
+};
+
+/**
+ * @description 点击表格外部,关闭编辑状态
+ */
+onClickOutside(tableRef, event => {
+  let ifEdit = tableRef.value.getEditRecord();
+
+  if (ifEdit) {
+    tableRef.value.clearEdit();
+  }
+});
+
 // 暴露给父组件的参数和方法(外部需要什么,都可以从这里暴露出去)
 defineExpose({
   element: tableRef,
+  ...vxeTableEvents,
   tableData,
-  pageable,
+  // pageable,
   searchParam,
-  searchInitParam,
+  // searchInitParam,
   tableColumns,
   getTableList,
   search,
@@ -2469,10 +2714,11 @@ defineExpose({
   openColSetting,
   // clearSelection,
   enumMap,
-  baseEnumMap
+  baseEnumMap,
   // isSelected,
   // selectedList,
   // selectedListIds
+  initLayoutColumns
 });
 </script>
 
@@ -2485,10 +2731,9 @@ defineExpose({
   .search-btn.active {
     box-shadow: $shadow-1-down-inset;
   }
-
   .table-main__tool-button {
-    margin-left: 12px;
     margin-right: 12px;
+    margin-left: 12px;
     :deep(.el-button-group) {
       .el-button:first-child {
         border-top-left-radius: 16px;
@@ -2509,9 +2754,9 @@ defineExpose({
       z-index: 5;
     }
     .more-btn {
-      transform: translateX(70%);
       // opacity: 0.68;
       transition: all ease-in-out 0.2s;
+      transform: translateX(70%);
     }
     &:hover {
       .more-btn {
@@ -2527,12 +2772,11 @@ defineExpose({
     padding-bottom: 0;
   }
 }
-
 .card + .card {
   margin-top: $space-b2;
 }
 
-/*滚动条整体部分*/
+/* 滚动条整体部分 */
 .lj-vxetable ::-webkit-scrollbar {
   width: 12px;
   height: 12px;
@@ -2560,7 +2804,6 @@ defineExpose({
     .tableheader-tabs {
       --el-tabs-header-height: 33px;
     }
-
     .table-box .table-search,
     .table-main .table-search {
       margin-bottom: 0;

+ 11 - 8
JLHWEB/src/components/LjVxeTable/interface/index.ts

@@ -333,10 +333,6 @@ export type aboutVxetableApiProps = {
    * @argument Array 打印前,获取打印数据
    */
   printDataCallback?: (data: any) => any;
-  /**
-   * @description 是否需要加载查询习惯
-   */
-  ifLoadQueryHabit?: boolean;
 };
 
 /**
@@ -486,6 +482,10 @@ export interface LjVxetableProps extends aboutVxetableApiProps {
    * @description 绑定多选的列名
    */
   multiSelect?: string;
+  /**
+   * @description 列表是否显示搜索栏
+   */
+  ifSearch?: boolean;
   /**
    * @description 表格是否可编辑
    */
@@ -495,10 +495,13 @@ export interface LjVxetableProps extends aboutVxetableApiProps {
    */
   autoSelectFirstAfterRefresh?: boolean;
   /**
-   * @argument function
-   * @description 组件加载后,执行函数
+   * @description 是否需要加载查询习惯
    */
-  afterMound?: (params: any) => void;
+  ifLoadQueryHabit?: boolean;
+  /**
+   * @description 当前行是否禁止点击
+   */
+  lockRow?: boolean | ((params: any) => boolean);
 }
 
 export type LjVxeTableInstance = Omit<InstanceType<typeof LjVxeTable>, keyof ComponentPublicInstance | keyof LjVxetableProps>;
@@ -510,7 +513,7 @@ export interface selectOption {
   /**
    * @argument string 名称
    */
-  label: string;
+  label?: string;
   /**
    * @argument string 值
    */

+ 79 - 16
JLHWEB/src/hooks/useDwLayout.tsx

@@ -32,14 +32,15 @@ export const useDwLayout = (
   autoLoadLayout: boolean = false,
   dwname?: string,
   loadLayoutCallBack?: (data: any) => any,
-  flatColumnsCallBack?: (data: any) => any
+  flatColumnsCallBack?: (data: any) => any,
+  editable?: boolean
 ) => {
   // 布局暂存数据
   const layoutStore = useLayoutStore();
   /**
    * @description 额外由后台决定的columns属性
    */
-  const onlyReadAttr = ["datatype", "enum"];
+  const onlyReadAttr = ["datatype", "enum", "pbformat", "tabsequence"];
   /**
    * @description 别名字段集合(field),由后台定义title值
    */
@@ -155,6 +156,7 @@ export const useDwLayout = (
     let _load = pick(userStyle, attr);
     // 先赋值datatype,处理并获取,默认赋值
     _load.datatype && (item.datatype = _load.datatype);
+    _load.enum && (item.enum = _load.enum);
     let _define = getDefineAttr(item, layoutAttrDefine);
 
     // 强→弱
@@ -189,13 +191,14 @@ export const useDwLayout = (
     if (item.hasOwnProperty("datatype")) {
       _define = cloneDeep(defineColumnStyle[item.datatype]);
     } else {
+      let matched = false;
       for (const key in defineColumnStyle) {
         if (key.indexOf("$") > -1 || key.indexOf("^") > -1) {
           // 正则表达式
           let reg = new RegExp(key);
           if (reg.test(item.field)) {
             _define = cloneDeep(defineColumnStyle[key]);
-
+            matched = true;
             // if (key.indexOf("date") > -1) {
             //   console.log("getDefineAttr item :>> ", item);
             //   if (item.title.indexOf("日期") > -1) {
@@ -209,6 +212,9 @@ export const useDwLayout = (
           }
         }
       }
+      if (!matched && !item.datatype && !item.enum) {
+        _define.align = "left";
+      }
     }
 
     // 弱→强 : 组件默认 + 特征默认 + 原始自定义
@@ -216,6 +222,7 @@ export const useDwLayout = (
     return defaultsDeep(item, _define, defineColumn);
   };
 
+  const _tableJson = tableJson as any;
   /**
    * @description 扁平化 初始化 columns
    * @param argColumns
@@ -225,10 +232,13 @@ export const useDwLayout = (
    */
   const flatColumnsFunc = (argColumns: ColumnProps[], dwMap: Map<KeyType, any> = new Map(), flatArr: ColumnProps[] = []) => {
     argColumns.forEach(async (col: any) => {
-      if (col?._children?.length) flatArr.push(...flatColumnsFunc(col._children, dwMap));
+      if (col._children?.length) flatArr.push(...flatColumnsFunc(col._children, dwMap));
 
       if (dwMap.size) {
         // 读取个性设置属性
+        if (!dwMap.has(col.field)) {
+          dwMap.set(col.field, {});
+        }
         let userStyle = dwMap.get(col.field) ?? undefined;
         if (userStyle && !userStyle?.limited) {
           col = loadUserStyle(col, userStyle);
@@ -276,8 +286,8 @@ export const useDwLayout = (
       } else {
         if (!["status", "woodcode", "pcode"].includes(col.field)) {
           if (col.table) {
-            Object.keys(tableJson).includes(col.table) &&
-              Object.keys(tableJson[col.table]).includes(col.field) &&
+            Object.keys(_tableJson).includes(col.table) &&
+              Object.keys(_tableJson[col.table]).includes(col.field) &&
               (col.title = t(`table.${col.table}.${col.field}`));
           } else {
             Object.keys(tableJson).includes(col.field) && (col.title = t(`table.${col.field}`));
@@ -326,17 +336,27 @@ export const useDwLayout = (
             let _keys = Object.keys(scope);
             let _data = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
             let _field = scope?.column.field ?? "";
-            switch (Number(_data[_field])) {
-              case 1:
-                return <el-checkbox class={"el-checkbox__disabled-checked"} checked={true} disabled={true} />;
-              default: // 0
-                let bool = false;
-                return <el-checkbox v-model={bool} disabled={true} />;
-            }
+            // switch (Number(_data[_field])) {
+            //   case 1:
+            //     return <el-checkbox class={"el-checkbox__disabled-checked"} checked={true} disabled={true} label="111" />;
+            //   default: // 0
+            //     let bool = false;
+            //     return <el-checkbox v-model={bool} disabled={true} label="44" />;
+            // }
+            return (
+              <>
+                <el-checkbox
+                  v-model={_data[_field]}
+                  class={{ "el-checkbox__disabled-checked": Number(_data[_field]) }}
+                  true-value={1}
+                  false-value={0}
+                  disabled={!editable}
+                />
+              </>
+            );
           };
-        }
-        /**普通:enum,数值转文本 */
-        if (item.enum && item.enum.length) {
+        } else if (item.enum && item.enum.length) {
+          /**普通:enum,数值转文本 */
           item.render = (scope: any) => {
             let _keys = Object.keys(scope);
             let _data: any = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
@@ -349,6 +369,49 @@ export const useDwLayout = (
               return _item?.label ?? "";
             }
           };
+        } else if (item?.datatype == "html") {
+          item.render = (scope: any) => {
+            let _keys = Object.keys(scope);
+            let _data = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
+            let _field = scope?.column.field ?? "";
+            let html_data = _data[_field];
+            if (html_data) {
+              // 空格替换为&nbsp;
+              html_data = html_data.replace(/ /g, "&nbsp;");
+            }
+            return <div v-html={html_data} />;
+          };
+        }
+      }
+      if (!item.editRender && !item.editColRender && item.tabsequence) {
+        console.log("item.enum :>> ", item.field, item.enum);
+        if (item.enum) {
+          item.editRender = { name: "$select", options: item.enum };
+        } else if (item.datatype == "checkbox") {
+          item.editRender = {};
+          item.editColRender = (scope: any) => {
+            const { column, row, status } = scope;
+            let _keys = Object.keys(scope);
+            let _data: any = _keys.includes("row") ? scope.row : scope;
+            let _field = scope?.column.field ?? "";
+            // if (Number(_data[_field]) == 0) {
+            //   row[_field] = 0;
+            // }
+
+            return (
+              <>
+                <el-checkbox v-model={_data[_field]} true-value={1} false-value={0} class="vxe-edit-col-middle"></el-checkbox>
+              </>
+            );
+          };
+        } else if (item.datatype == "date") {
+          item.editRender = { name: "$input", props: { type: "date" } };
+        } else if (item.datatype == "datetime") {
+          item.editRender = { name: "$input", props: { type: "datetime" } };
+        } else if (item.datatype == "number" || item.datatype == "integer") {
+          item.editRender = { name: "$input", props: { type: "number" } };
+        } else if (item.datatype == "input") {
+          item.editRender = { name: "$input", props: {} };
         }
       }
     });

+ 3 - 2
JLHWEB/src/hooks/useTable.ts

@@ -98,6 +98,7 @@ export const useTable = (
       console.log("aff  loadLayout :>> ", loadLayout);
       // 第一页的时候会执行这个回调,第二页开始没有tableinfo返回
       data?.tableinfo && loadLayoutCallBack && loadLayoutCallBack(data.tableinfo);
+      // data?.tableinfo && loadLayout && loadLayoutCallBack && loadLayoutCallBack(data.tableinfo);
 
       // state.tableData = data[reqProp];
       // 解构后台返回的分页数据 (如果有分页更新分页信息)
@@ -153,10 +154,10 @@ export const useTable = (
    * @description 表格数据查询
    * @return void
    * */
-  const search = () => {
+  const search = async () => {
     state.pageable.pageNum = 1;
     updatedTotalParam();
-    getTableList();
+    await getTableList();
   };
 
   /**

+ 1 - 2
JLHWEB/src/utils/index.ts

@@ -1261,12 +1261,11 @@ export const isFilterPrice = data => {
 /**
  * @description 计算vxetable的合并单元格
  * @param $table 表对象
- * @param data 数据
  * @param fields 计算合并的字段明
  * @returns 需要合并的单元格数组
  */
 export const autoMergeCells = ($table: any, fields: string[]) => {
-  let result = [];
+  let result: any = [];
   let columns = $table.getColumns();
   let { visibleData: data } = $table.getTableData();
   console.log("mergeCells data :>> ", columns, data);

+ 1 - 1
JLHWEB/src/views/erpapi/mattressInterface/detail.vue

@@ -6,7 +6,7 @@
     :data="[mainData]"
     v-model:order-status="orderStatus"
     :action="orderDefaultAction"
-    :after-mound="funcAfterMound"
+    @after-mounted="funcAfterMound"
     :if-layout-editable="false"
     :search-col="{ xs: 3, sm: 3, md: 3, lg: 3, xl: 3 }"
     :basic-group-col="{ xs: 3, sm: 3, md: 3, lg: 3, xl: 3 }"

+ 1 - 1
JLHWEB/src/views/quote/bednetQuote/detail.vue

@@ -8,7 +8,7 @@
     :init-param="initParams"
     v-model:order-status="orderStatus"
     :action="orderDefaultAction"
-    :after-mound="funcAfterMound"
+    @after-mounted="funcAfterMound"
     :if-layout-editable="false"
     :default-columns-value="defaultColumnsValue"
   >

+ 9 - 9
JLHWEB/src/views/quote/bednetQuote/hooks/index.tsx

@@ -821,28 +821,28 @@ export const useHooks = (t?: any, props?: any) => {
               <el-checkbox
                 v-model={scope.searchParam.if_doublespring}
                 disabled={_disabled}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 label="双簧"
                 class="mr-8"
               />
               <el-checkbox
                 v-model={scope.searchParam.if_rsorwa}
                 disabled={_disabled}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 label="胶条 包角"
                 class="mr-8"
               />
               <el-checkbox
                 v-model={scope.searchParam.if_sponge_drilling}
                 disabled={_disabled}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 label="海绵打孔"
               />
-              <el-checkbox v-model={scope.searchParam.iffork} disabled={_disabled} true-value="1" false-value="0" label="弹叉" />
-              <el-checkbox v-model={scope.searchParam.if_jb} disabled={_disabled} true-value="1" false-value="0" label="卷包" />
+              <el-checkbox v-model={scope.searchParam.iffork} disabled={_disabled} true-value={1} false-value={0} label="弹叉" />
+              <el-checkbox v-model={scope.searchParam.if_jb} disabled={_disabled} true-value={1} false-value={0} label="卷包" />
             </>
           );
         }
@@ -1498,7 +1498,7 @@ export const useHooks = (t?: any, props?: any) => {
           console.log("duo_qv_str scope :>> ", scope);
           let optionRender = [];
           scope.enum.map(item => {
-            optionRender.push(<el-option label={item.label} value={item.value} />);
+            optionRender.push(<el-option label={item.label} value={item.value + ""} />);
           });
           return (
             <>

+ 5 - 5
JLHWEB/src/views/quote/bednetQuote/index.vue

@@ -14,7 +14,8 @@
         :auto-load-layout="false"
         :search-btn-size-extent="[]"
         pagination
-        @on-mounted-data="autoMonthedData"
+        autoSelectFirstAfterRefresh
+        @first-mounted="autoMonthedData"
       >
         <!-- 表格 header 按钮 -->
         <template #tableHeader>
@@ -45,7 +46,7 @@
           :table-events="tableEventsMx"
           :auto-load-layout="false"
           :search-btn-size-extent="[]"
-          collapseButtons
+          autoSelectFirstAfterRefresh
           :request-auto="false"
         >
           <template #tableHeader>
@@ -65,7 +66,6 @@
             :table-props="tableProps"
             :auto-load-layout="false"
             :search-btn-size-extent="[]"
-            collapseButtons
             :request-auto="false"
           >
             <template #tableHeader>
@@ -200,12 +200,12 @@ const handleClickTableMx = ({ row, rowIndex, $rowIndex, column, columnIndex, $co
 // 返回绑定的事件
 const tableEvents = {
   "cell-dblclick": handleDBlClickTable,
-  "cell-click": handleClickTable
+  "current-change": handleClickTable
 };
 
 // 返回绑定的事件
 const tableEventsMx = {
-  "cell-click": handleClickTableMx
+  "current-change": handleClickTableMx
 };
 
 /**

+ 204 - 117
JLHWEB/src/views/quote/mattressQuote/detail.vue

@@ -8,7 +8,7 @@
     :init-param="initParams"
     v-model:order-status="orderStatus"
     :action="orderDefaultAction"
-    :after-mound="funcAfterMound"
+    @after-mounted="funcAfterMound"
     :if-layout-editable="false"
     :default-columns-value="defaultColumnsValue"
   >
@@ -41,7 +41,7 @@
           class="h-full flx"
           label="裥面"
           name="tabpage_8"
-          v-if="mattresstypeEnum && Number(mattresstypeEnum.if_top_side) == 1"
+          v-if="mattresstypeEnum && Number(mattresstypeEnum?.if_top_side) == 1"
         >
           <template #label>
             <template v-if="isFilterErrorBadge(fabricMxTab8)">
@@ -550,7 +550,7 @@
         :auto-load-layout="false"
         collapseButtons
         :footer-sum-attrs="['costamt']"
-        :after-mound="resetMergeCellsInner"
+        @after-mounted="resetMergeCellsInner"
       >
         <template #tableHeader v-if="orderStatus">
           <el-space wrap>
@@ -589,7 +589,7 @@
         :auto-load-layout="false"
         collapseButtons
         :footer-sum-attrs="['costamt']"
-        :after-mound="resetMergeCellsTopCotton"
+        @after-mounted="resetMergeCellsTopCotton"
       >
         <template #tableHeader v-if="orderStatus">
           <el-space wrap>
@@ -626,12 +626,13 @@
         ref="subSpecsRef"
         row-key="key"
         table-cls=""
+        :request-auto="false"
         :request-api="getData_subSpecs"
         :data-callback="dataCallbackMx"
         :init-param="initParams"
         :columns="columnsMx_subSpecs"
         :dwname="DwnameEnum.mattressQuoteSubspecs"
-        :table-props="tableProps_mx"
+        :table-props="tableProps_subSpecs"
         :table-events="tableEvents"
         :tool-button="[]"
         :auto-load-layout="false"
@@ -642,6 +643,18 @@
             <el-button type="primary" @click="toAddMx_subSpecs">{{ t("common.addText") }}</el-button>
             <el-button type="danger" @click="toDelMx_subSpecs">{{ t("common.delText") }}</el-button>
           </el-space>
+          <el-space wrap v-else-if="!LjDetailRef._mainData.parentid && Number(LjDetailRef._mainData.flag) == 1">
+            <template v-if="!editSubSpecs">
+              <el-button type="primary" @click="toEdit_subSpecs">{{ t("common.editText") }}</el-button>
+            </template>
+            <template v-else>
+              <el-button type="primary" @click="toAddMx_subSpecs">{{ t("common.addText") }}</el-button>
+              <el-button type="danger" @click="toDelMx_subSpecs">{{ t("common.delText") }}</el-button>
+              <el-divider direction="vertical" />
+              <el-button type="success" @click="toSave_subSpecs">{{ t("common.saveText") }}</el-button>
+              <el-button type="default" @click="toCancel_subSpecs">{{ t("common.cancelText") }}</el-button>
+            </template>
+          </el-space>
           <el-space wrap v-if="LjDetailRef._mainData.parentid > 0">
             <el-button type="primary" @click="gotoMainMattress">查看主规格</el-button>
           </el-space>
@@ -862,6 +875,35 @@ const tableProps_mx = ref({
   }
 });
 
+const tableProps_subSpecs = ref({
+  height: "auto",
+  align: "left",
+  // height: "",
+  minHeight: "300px",
+  editConfig: { trigger: "click", mode: "row", enabled: false, autoClear: false },
+  // exportConfig: {
+  //   filename: t("menu.saleTaskCrmDetail") + formatToDate(new Date(), "YYYY-MM-DDHH:mm:ss")
+  // }
+  keyboardConfig: {
+    isEdit: true,
+    isArrow: true,
+    isEnter: true,
+    isTab: true,
+    isDel: true,
+    isBack: true,
+    isEsc: true,
+    editMethod({ $table, row, column }) {
+      // 先清空原先的值
+      row[column.field] = "";
+      // 再激活编辑状态并输入新值
+      $table.setEditCell(row, column);
+    }
+  },
+  mouseConfig: {
+    selected: true
+  }
+});
+
 // const keyboardConfig = ref<any>({
 //   isEdit: true,
 //   isArrow: true,
@@ -1291,6 +1333,117 @@ const loadingStatus = reactive({
   save: false
 });
 
+const save = async () => {
+  console.log("save LjDetailRef.value._mainData :>> ", LjDetailRef.value._mainData);
+  console.log("save------------ :>> ", loadingStatus.save);
+  console.log("save cushionsMxData :>> ", cushionsMxData.value);
+
+  try {
+    await LjDetailRef.value.toValidateForm();
+
+    if (!(await wf_cmp_cb())) return;
+    loadingStatus.save = true;
+
+    let mattress = LjDetailRef.value._mainData;
+    mattress.mattressid = Number(mattress.mattressid ?? 0);
+    mattress.xd_flag = Number(mattress.xd_flag ?? 0);
+    console.log("bbbbbbbbbbbbbbbbbbbb mattress :>> ", mattress);
+    // mattress.if_moneyrate = Number(mattress.if_moneyrate ?? 0);
+    // mattress.if_bcp_type = Number(mattress.if_bcp_type ?? 0);
+    // mattress.if_d_chai = Number(mattress.if_d_chai ?? 0);
+    // mattress.if_m_chai = Number(mattress.if_m_chai ?? 0);
+    // mattress.if_m_wbutao_way = Number(mattress.if_m_wbutao_way ?? 0);
+    // mattress.if_n_butao = Number(mattress.if_n_butao ?? 0);
+    // mattress.if_w_butao = Number(mattress.if_w_butao ?? 0);
+    // mattress.if_z_chai = Number(mattress.if_z_chai ?? 0);
+    // mattress.if_zhedie_type = Number(mattress.if_zhedie_type ?? 0);
+
+    let mattressMx = [];
+    fabricMxTabList.value.map(t => {
+      if (t.ref) {
+        console.log("t.ref?.value :>> ", t.ref, dynamicRef(t.ref));
+        if (dynamicRef(t.ref)) {
+          let $table = dynamicRef(t.ref)?.element;
+          $table.clearEdit();
+          let { visibleData } = $table.getTableData();
+          console.log("visibleData t.ref?.value :>> ", t.ref, visibleData);
+          visibleData = visibleData.map((itm, idx) => {
+            itm.xu = idx + 1;
+            return itm;
+          });
+          mattressMx = mattressMx.concat(visibleData);
+        }
+      }
+    });
+
+    if (orderStatus.value == "copy") {
+      mattress.copy_id = mattress.mattressid;
+    }
+
+    let subspecs = [];
+    let $table_subspecs = subSpecsRef.value.element;
+    if ($table_subspecs) {
+      console.log("$table_subspecs.getTableData() :>> ", $table_subspecs.getTableData());
+      $table_subspecs.clearEdit();
+      subspecs = $table_subspecs.getTableData().visibleData;
+    }
+
+    let _param_mf = {
+      mattress,
+      mattressMx,
+      subspecs
+    };
+    try {
+      console.log("综合 _param_mf :>> ", _param_mf);
+      await SaveMattress(_param_mf)
+        .then(res => {
+          ElNotification({
+            title: "温馨提示",
+            message: t("sys.api.sueccessToSave"),
+            type: "success"
+          });
+          if (res.mattressid) {
+            console.log("tabRemove route.fullPath :>> ", route.fullPath);
+            tabRemove(route.fullPath);
+            router.push(`/mattressQuote/detail?id=${res.mattressid}&code=${res.mattresscode}`);
+          } else {
+            router.replace("/mattressQuote");
+          }
+          setTimeout(() => {
+            let _msg = res.message ?? "";
+            if (res.message || res.mxmessage?.length) {
+              let defaultNum = res.message ? 1 : 0;
+              _msg && (_msg = "1." + _msg + "<br/>");
+
+              if (res.mxmessage?.length) {
+                res.mxmessage.map((itm, idx) => {
+                  _msg += `${idx + 1 + defaultNum}. ${itm}<br/>`;
+                });
+              }
+              let _num = res.message ? 1 + res.mxmessage?.length : res.mxmessage?.length;
+              ElNotification({
+                title: `计算失败(${_num})`,
+                message: `<div style="word-wrap:break-word;word-break:break-all;">${_msg}</div>`,
+                dangerouslyUseHTMLString: true,
+                type: "warning"
+              });
+            }
+          }, 100);
+          loadingStatus.save = false;
+        })
+        .catch(error => {
+          console.log("error !! :>> ", error);
+          loadingStatus.save = false;
+        });
+    } catch (error) {
+      ElMessage.error(t("sys.api.operationFailed"));
+    }
+  } catch (e) {
+    loadingStatus.save = false;
+    console.log("buttonNew eee :>> ", e, loadingStatus.save);
+  }
+};
+
 const orderDefaultAction = [
   buttonDefault({
     label: t("common.cancelText"),
@@ -1314,117 +1467,7 @@ const orderDefaultAction = [
     icon: "iconsave-01",
     loading: () => loadingStatus.save,
     limited: () => !orderStatus.value,
-    clickFunc: async () => {
-      console.log("save LjDetailRef.value._mainData :>> ", LjDetailRef.value._mainData);
-
-      console.log("save------------ :>> ", loadingStatus.save);
-      console.log("save cushionsMxData :>> ", cushionsMxData.value);
-
-      try {
-        await LjDetailRef.value.toValidateForm();
-
-        if (!(await wf_cmp_cb())) return;
-        loadingStatus.save = true;
-
-        let mattress = LjDetailRef.value._mainData;
-        mattress.mattressid = Number(mattress.mattressid ?? 0);
-        mattress.xd_flag = Number(mattress.xd_flag ?? 0);
-        console.log("bbbbbbbbbbbbbbbbbbbb mattress :>> ", mattress);
-        // mattress.if_moneyrate = Number(mattress.if_moneyrate ?? 0);
-        // mattress.if_bcp_type = Number(mattress.if_bcp_type ?? 0);
-        // mattress.if_d_chai = Number(mattress.if_d_chai ?? 0);
-        // mattress.if_m_chai = Number(mattress.if_m_chai ?? 0);
-        // mattress.if_m_wbutao_way = Number(mattress.if_m_wbutao_way ?? 0);
-        // mattress.if_n_butao = Number(mattress.if_n_butao ?? 0);
-        // mattress.if_w_butao = Number(mattress.if_w_butao ?? 0);
-        // mattress.if_z_chai = Number(mattress.if_z_chai ?? 0);
-        // mattress.if_zhedie_type = Number(mattress.if_zhedie_type ?? 0);
-
-        let mattressMx = [];
-        fabricMxTabList.value.map(t => {
-          if (t.ref) {
-            console.log("t.ref?.value :>> ", t.ref, dynamicRef(t.ref));
-            if (dynamicRef(t.ref)) {
-              let $table = dynamicRef(t.ref)?.element;
-              $table.clearEdit();
-              let { visibleData } = $table.getTableData();
-              console.log("visibleData t.ref?.value :>> ", t.ref, visibleData);
-              visibleData = visibleData.map((itm, idx) => {
-                itm.xu = idx + 1;
-                return itm;
-              });
-              mattressMx = mattressMx.concat(visibleData);
-            }
-          }
-        });
-
-        if (orderStatus.value == "copy") {
-          mattress.copy_id = mattress.mattressid;
-        }
-
-        let subspecs = [];
-        let $table_subspecs = subSpecsRef.value.element;
-        if ($table_subspecs) {
-          console.log("$table_subspecs.getTableData() :>> ", $table_subspecs.getTableData());
-          $table_subspecs.clearEdit();
-          subspecs = $table_subspecs.getTableData().visibleData;
-        }
-
-        let _param_mf = {
-          mattress,
-          mattressMx,
-          subspecs
-        };
-        try {
-          console.log("综合 _param_mf :>> ", _param_mf);
-          await SaveMattress(_param_mf)
-            .then(res => {
-              ElNotification({
-                title: "温馨提示",
-                message: t("sys.api.sueccessToSave"),
-                type: "success"
-              });
-              if (res.mattressid) {
-                console.log("tabRemove route.fullPath :>> ", route.fullPath);
-                tabRemove(route.fullPath);
-                router.push(`/mattressQuote/detail?id=${res.mattressid}&code=${res.mattresscode}`);
-              } else {
-                router.replace("/mattressQuote");
-              }
-              setTimeout(() => {
-                let _msg = res.message ?? "";
-                if (res.message || res.mxmessage?.length) {
-                  let defaultNum = res.message ? 1 : 0;
-                  _msg && (_msg = "1." + _msg + "<br/>");
-
-                  if (res.mxmessage?.length) {
-                    res.mxmessage.map((itm, idx) => {
-                      _msg += `${idx + 1 + defaultNum}. ${itm}<br/>`;
-                    });
-                  }
-                  let _num = res.message ? 1 + res.mxmessage?.length : res.mxmessage?.length;
-                  ElNotification({
-                    title: `计算失败(${_num})`,
-                    message: `<div style="word-wrap:break-word;word-break:break-all;">${_msg}</div>`,
-                    dangerouslyUseHTMLString: true,
-                    type: "warning"
-                  });
-                }
-              }, 100);
-              loadingStatus.save = false;
-            })
-            .catch(error => {
-              console.log("error !! :>> ", error);
-              loadingStatus.save = false;
-            });
-        } catch (error) {
-          ElMessage.error(t("sys.api.operationFailed"));
-        }
-      } catch (e) {
-        loadingStatus.save = false;
-        console.log("buttonNew eee :>> ", e, loadingStatus.save);
-      }
-    }
+    clickFunc: () => save()
   }),
   buttonDefault({
     label: t("common.add"),
@@ -1444,7 +1487,7 @@ const orderDefaultAction = [
     },
     disabledTextCallBack: data => {
       if (data.parentid > 0) {
-        return "副规格无法编辑";
+        return "副规格无法编辑,请在主规格中进行";
       }
       return "";
     },
@@ -1502,6 +1545,9 @@ const orderDefaultAction = [
         if (!CheckPower(94)) {
           return `你没有【报价单-${t("common.businessOrder")}】的使用权限`;
         }
+        if (data.parentid > 0) {
+          return "副规格无法操作,请在主规格中进行";
+        }
         return "";
       },
       clickFunc: item => {
@@ -1539,6 +1585,9 @@ const orderDefaultAction = [
         if (!CheckPower(95)) {
           return `你没有【报价单-${t("common.businessOrderCancel")}】的使用权限`;
         }
+        if (data.parentid > 0) {
+          return "副规格无法操作,请在主规格中进行";
+        }
         return "";
       },
       clickFunc: item => {
@@ -1578,6 +1627,12 @@ const orderDefaultAction = [
         if (!CheckPower(73)) {
           return `你没有【报价单-${t("common.auditFinance")}】的使用权限`;
         }
+        if (data.parentid > 0) {
+          return "副规格无法操作,请在主规格中进行";
+        }
+        if (data.flag == 1) {
+          return "已审核";
+        }
         return "";
       },
       clickFunc: item => {
@@ -1615,6 +1670,12 @@ const orderDefaultAction = [
         if (!CheckPower(74)) {
           return `你没有【报价单-${t("common.withdrawAuditFinance")}】的使用权限`;
         }
+        if (data.parentid > 0) {
+          return "副规格无法操作,请在主规格中进行";
+        }
+        if (data.flag != 1) {
+          return "未审核";
+        }
         return "";
       },
       clickFunc: item => {
@@ -1791,6 +1852,7 @@ const funcAfterMound = async () => {
   } else {
     // 新增/编辑
     tableProps_mx.value.editConfig.enabled = true;
+    tableProps_subSpecs.value.editConfig.enabled = true;
 
     topCottonAddList.value = w_mattress_add_itemname_choose(4);
   }
@@ -1816,6 +1878,9 @@ const funcAfterMound = async () => {
     mxLoading.value = false;
 
     nextTick(() => {
+      console.log("detail onMounted subSpecsRef.value :>> ", subSpecsRef.value);
+      subSpecsRef.value.refresh();
+
       gotoSummy(8000);
     });
   }
@@ -2327,6 +2392,28 @@ const toDelMx_subSpecs = () => {
   }
 };
 
+/**
+ * @description 审核后,修改主副规格
+ */
+const editSubSpecs = ref(false);
+
+const toEdit_subSpecs = () => {
+  editSubSpecs.value = true;
+
+  tableProps_subSpecs.value.editConfig.enabled = true;
+};
+
+const toCancel_subSpecs = () => {
+  editSubSpecs.value = false;
+  subSpecsRef.value.refresh();
+};
+
+const toSave_subSpecs = async () => {
+  await save();
+
+  editSubSpecs.value = false;
+};
+
 const gotoMainMattress = () => {
   if (globalStore.detailBlank) {
     // 打开新的窗口

+ 72 - 49
JLHWEB/src/views/quote/mattressQuote/hooks/index.tsx

@@ -19,6 +19,7 @@ import ToastFormula from "@/components/ToastWidget/Formula/index.vue";
 import ToastHistoryPrice from "@/components/ToastWidget/HistoryPrice/index.vue";
 import { useRouter } from "vue-router";
 import { useGlobalStore } from "@/stores/modules/global";
+import { title } from "process";
 
 interface defaultState {
   /**
@@ -139,35 +140,35 @@ export const useHooks = (t?: any) => {
       {
         label: "裥面",
         name: "tabpage_8",
-        visible: () => Number(state.mattresstypeEnum.if_top_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_top_side) == 1,
         type: [0, 80, 40, 50, 60, 70, 9000],
         ref: "fabricMxTab8Ref"
       },
       {
         label: "裥底",
         name: "tabpage_9",
-        visible: () => Number(state.mattresstypeEnum.if_button_sdie) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_button_sdie) == 1,
         type: [1, 81, 41, 51, 61, 71, 9001],
         ref: "fabricMxTab9Ref"
       },
       {
         label: "裥大恻",
         name: "tabpage_10",
-        visible: () => Number(state.mattresstypeEnum.if_big_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_big_side) == 1,
         type: [2, 82, 42, 52, 62, 72, 9002],
         ref: "fabricMxTab10Ref"
       },
       {
         label: "裥小恻",
         name: "tabpage_11",
-        visible: () => Number(state.mattresstypeEnum.if_small_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_small_side) == 1,
         type: [3, 83, 43, 53, 63, 73, 9003],
         ref: "fabricMxTab11Ref"
       },
       {
         label: "裥V恻",
         name: "tabpage_12",
-        visible: () => Number(state.mattresstypeEnum.if_v_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_v_side) == 1,
         type: [4, 84, 44, 54, 64, 74, 9004],
         ref: "fabricMxTab12Ref"
       },
@@ -2821,7 +2822,26 @@ export const useHooks = (t?: any) => {
         el: "input",
         editable: ALLOW_EDIT_STATE
       },
-      treeNode: true
+      treeNode: true,
+      render: scope => {
+        return scope.row.child_count == 0 && scope.row.parentid == 0 ? (
+          scope.row.mattressname
+        ) : scope.row.parentid == 0 ? (
+          <>
+            <el-tag type="primary" effect="light" disable-transitions size="small" class="mr-4">
+              主
+            </el-tag>
+            {scope.row.mattressname}
+          </>
+        ) : (
+          <>
+            <el-tag type="warning" effect="light" disable-transitions size="small" class="mr-4">
+              副
+            </el-tag>
+            {scope.row.mattressname}
+          </>
+        );
+      }
     },
     {
       field: "flag",
@@ -2897,16 +2917,16 @@ export const useHooks = (t?: any) => {
             <>
               <el-checkbox
                 v-model={scope.searchParam.if_bcp_type}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 disabled={_disabled}
                 label="半成品"
                 class="mr-8"
               />
               <el-checkbox
                 v-model={scope.searchParam.if_zhedie_type}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 disabled={_disabled}
                 label="折叠款"
               />
@@ -2927,24 +2947,24 @@ export const useHooks = (t?: any) => {
             <>
               <el-checkbox
                 v-model={scope.searchParam.if_m_chai}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 disabled={_disabled}
                 label="面拆"
                 class="mr-8"
               />
               <el-checkbox
                 v-model={scope.searchParam.if_z_chai}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 disabled={_disabled}
                 label="中拆"
                 class="mr-8"
               />
               <el-checkbox
                 v-model={scope.searchParam.if_d_chai}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 disabled={_disabled}
                 label="底拆"
               />
@@ -2991,8 +3011,8 @@ export const useHooks = (t?: any) => {
             <>
               <el-checkbox
                 v-model={scope.searchParam.if_w_butao}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 disabled={_disabled}
                 label="顶布裥棉"
                 class="mr-8"
@@ -3021,35 +3041,35 @@ export const useHooks = (t?: any) => {
     },
     {
       field: "if_n_butao",
-      title: "内布套",
-      basicinfo: {
-        labelHidden: true,
-        render: (scope: any) => {
-          let _disabled = !ALLOW_EDIT_STATE.includes(scope.status);
-          return (
-            <>
-              <el-checkbox
-                v-model={scope.searchParam.if_n_butao}
-                true-value="1"
-                false-value="0"
-                disabled={_disabled}
-                label="内布套"
-                class="mr-8"
-              />
-            </>
-          );
-        },
-        editvisible: (scope: any) => {
-          let someone =
-            Number(scope.searchParam?.if_m_chai ?? 0) +
-            Number(scope.searchParam?.if_z_chai ?? 0) +
-            Number(scope.searchParam?.if_d_chai ?? 0);
-          if (someone > 0) {
-            return true;
-          }
-          return false;
-        }
-      }
+      title: "内布套"
+      // basicinfo: {
+      //   labelHidden: true,
+      //   render: (scope: any) => {
+      //     let _disabled = !ALLOW_EDIT_STATE.includes(scope.status);
+      //     return (
+      //       <>
+      //         <el-checkbox
+      //           v-model={scope.searchParam.if_n_butao}
+      //           true-value={1}
+      //           false-value={0}
+      //           disabled={_disabled}
+      //           label="内布套"
+      //           class="mr-8"
+      //         />
+      //       </>
+      //     );
+      //   },
+      //   editvisible: (scope: any) => {
+      //     let someone =
+      //       Number(scope.searchParam?.if_m_chai ?? 0) +
+      //       Number(scope.searchParam?.if_z_chai ?? 0) +
+      //       Number(scope.searchParam?.if_d_chai ?? 0);
+      //     if (someone > 0) {
+      //       return true;
+      //     }
+      //     return false;
+      //   }
+      // }
     },
     {
       field: "s_cover_qty",
@@ -3131,8 +3151,8 @@ export const useHooks = (t?: any) => {
             <>
               <el-checkbox
                 v-model={scope.searchParam.if_m_wbutao_way}
-                true-value="1"
-                false-value="0"
+                true-value={1}
+                false-value={0}
                 disabled={_disabled}
                 label="面料外布套做法"
                 class="mr-8"
@@ -4502,6 +4522,7 @@ export const useHooks = (t?: any) => {
   const columnsMx_subSpecs = [
     { type: "checkbox", width: 50, fixed: "left" },
     {
+      title: "床垫宽/CM",
       field: "mattress_width",
       datatype: "number",
       editRender: {
@@ -4512,6 +4533,7 @@ export const useHooks = (t?: any) => {
       }
     },
     {
+      title: "床垫长/CM",
       field: "mattress_length",
       datatype: "number",
       editRender: {
@@ -4522,6 +4544,7 @@ export const useHooks = (t?: any) => {
       }
     },
     {
+      title: "床垫高/CM",
       field: "mattress_height",
       datatype: "number",
       editRender: {

+ 1 - 0
JLHWEB/src/views/quote/mattressQuote/index.vue

@@ -173,6 +173,7 @@ const tableProps = {
     filename: t("menu.rpMsttake") + formatToDate(new Date(), "YYYY-MM-DD HH:mm:ss")
   },
   treeConfig: {
+    expandAll: true,
     transform: true,
     rowField: "mattressid",
     parentField: "parentid"

+ 1 - 1
JLHWEB/src/views/quote/semifinprodQuote/detail.vue

@@ -8,7 +8,7 @@
     :init-param="initParams"
     v-model:order-status="orderStatus"
     :action="orderDefaultAction"
-    :after-mound="funcAfterMound"
+    @after-mounted="funcAfterMound"
     :if-layout-editable="false"
   >
     <template #fabricMx>

+ 1 - 1
JLHWEB/src/views/quote/semifinprodQuote/detail2.vue

@@ -8,7 +8,7 @@
     :init-param="initParams"
     v-model:order-status="orderStatus"
     :action="orderDefaultAction"
-    :after-mound="funcAfterMound"
+    @after-mounted="funcAfterMound"
     :if-layout-editable="false"
     :search-col="{ xs: 3, sm: 3, md: 3, lg: 3, xl: 3 }"
     :basic-group-col="{ xs: 3, sm: 3, md: 3, lg: 3, xl: 3 }"

+ 5 - 5
JLHWEB/src/views/quote/semifinprodQuote/hooks/index2.tsx

@@ -223,35 +223,35 @@ export const useHooks = (t?: any) => {
       {
         label: "裥面",
         name: "tabpage_8",
-        visible: () => Number(state.mattresstypeEnum.if_top_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_top_side) == 1,
         type: [0, 80, 40, 50, 60, 70, 9000],
         billtype: 901
       },
       {
         label: "裥底",
         name: "tabpage_9",
-        visible: () => Number(state.mattresstypeEnum.if_button_sdie) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_button_sdie) == 1,
         type: [1, 81, 41, 51, 61, 71, 9001],
         billtype: 902
       },
       {
         label: "裥大恻",
         name: "tabpage_10",
-        visible: () => Number(state.mattresstypeEnum.if_big_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_big_side) == 1,
         type: [2, 82, 42, 52, 62, 72, 9002],
         billtype: 903
       },
       {
         label: "裥小恻",
         name: "tabpage_11",
-        visible: () => Number(state.mattresstypeEnum.if_small_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_small_side) == 1,
         type: [3, 83, 43, 53, 63, 73, 9003],
         billtype: 904
       },
       {
         label: "裥V恻",
         name: "tabpage_12",
-        visible: () => Number(state.mattresstypeEnum.if_v_side) == 1,
+        visible: () => Number(state.mattresstypeEnum?.if_v_side) == 1,
         type: [4, 84, 44, 54, 64, 74, 9004],
         billtype: 905
       }