فهرست منبع

JLHWEB: 床垫报价界面代码更新

JohnnyChan 8 ماه پیش
والد
کامیت
2fda035294
25فایلهای تغییر یافته به همراه1719 افزوده شده و 393 حذف شده
  1. 109 101
      JLHWEB/src/api/interface/index.ts
  2. 4 0
      JLHWEB/src/api/modules/common.ts
  3. 201 184
      JLHWEB/src/components/LjDetail/components/BaseForm.vue
  4. 10 9
      JLHWEB/src/components/LjDetail/components/BasicInfoSelect.vue
  5. 9 9
      JLHWEB/src/components/LjDetail/components/ButtonGroup.vue
  6. 2 1
      JLHWEB/src/components/LjDetail/index.vue
  7. 1 1
      JLHWEB/src/components/LjDetail/interface/index.ts
  8. 1 1
      JLHWEB/src/components/LjVxeTable/components/FilterExtend.vue
  9. 1 0
      JLHWEB/src/components/LjVxeTable/components/TableColumn.vue
  10. 1 1
      JLHWEB/src/components/LjVxeTable/index.vue
  11. 5 5
      JLHWEB/src/components/LjVxeTable/interface/index.ts
  12. 142 0
      JLHWEB/src/components/ToastWidget/Formula/components/Item.vue
  13. 257 0
      JLHWEB/src/components/ToastWidget/Formula/index.vue
  14. 17 1
      JLHWEB/src/enums/dwnameEnum.ts
  15. 10 1
      JLHWEB/src/languages/modules/zh-cn/business.json
  16. 1 1
      JLHWEB/src/languages/modules/zh-cn/common.json
  17. 5 1
      JLHWEB/src/languages/modules/zh-cn/table.json
  18. 2 2
      JLHWEB/src/stores/modules/layoutLocal.ts
  19. 6 5
      JLHWEB/src/stores/modules/user.ts
  20. 3 0
      JLHWEB/src/styles/common.scss
  21. 96 0
      JLHWEB/src/utils/index.ts
  22. 482 51
      JLHWEB/src/views/quote/mattressQuote/detail.vue
  23. 343 7
      JLHWEB/src/views/quote/mattressQuote/hooks/index.tsx
  24. 5 6
      JLHWEB/src/views/saleprice/dept/hooks/index.tsx
  25. 6 6
      JLHWEB/src/views/saleprice/pricelist/hooks/index.tsx

+ 109 - 101
JLHWEB/src/api/interface/index.ts

@@ -146,6 +146,7 @@ export namespace Login {
      * @argument 可用权限列表
      */
     rsltFunids?: number[];
+    usermode: number;
   }
   export interface ReqL1APPUserInfo {
     /**
@@ -182,98 +183,99 @@ export namespace Login {
      * @argument 部门ID
      */
     deptid?: number;
-    /**
-     * @argument UUID
-     */
-    uuid?: string;
-    /**
-     * @argument 极光推送ID
-     */
-    ajpushid?: string;
-    /**
-     * @argument 可用权限列表
-     */
-    rsltFunids?: number[];
-    /**
-     * @argument 系统选项列表
-     */
-    optionList?: sys_option[];
-    /**
-     * @argument 存在新结构MtrlConfigStr,但没开始用
-     */
-    statusname?: string;
-    woodcodename?: string;
-    pcodename?: string;
-    zxmtrlmodename?: string;
-    usermtrlmodename?: string;
-    mtrlsectypename?: string;
-    outrepstrTips?: string;
-    outrepcode?: string;
-    dollarRate?: number;
-    dollarMoneyid?: number;
-    gw_inuse?: number | null;
-    gw_power1?: number | null;
-    gw_power3?: number | null;
-    ifnotin?: number | null;
-    phoneNumber?: string;
-    phoneUUID?: string;
-    /**
-     * @argument 公告栏列表
-     */
-    postList?: u_sys_post[];
-    powerWrkgrp?: u_sc_workgroup[];
-    /**
-     * @argument 该客户是否金龙恒
-     */
-    isJLH?: boolean;
-    /**
-     * @argument 商品所有类别
-     */
-    mtrltypeAllList?: Set<string>;
-    /**
-     * @argument 商品主要类别
-     */
-    mtrltypeList?: string[];
-    /**
-     * @argument 畅销类别
-     */
-    saletypeList?: string[];
-    /**
-     * @argument 产品系列
-     */
-    bandList?: string[];
-    /**
-     * @argument 单据塔头
-     */
-    billcodeList?: u_billcode[];
-    /**
-     * @argument 分账套权限
-     */
-    companyList?: u_company[];
-    /**
-     * @argument 分部权限
-     */
-    scstr?: string;
-    /**
-     * @argument 物料分类
-     */
-    mtrltypestr?: string;
-    /**
-     * @argument 仓库权限-查询
-     */
-    storagestr?: string;
-    /**
-     * @argument 仓库权限-新增
-     */
-    storagestr_new?: string;
-    /**
-     * @argument 仓库权限-审核
-     */
-    storagestr_audit?: string;
-    /**
-     * @argument 出纳账号
-     */
-    accountsidstr?: string;
+    usermode?: number;
+    // /**
+    //  * @argument UUID
+    //  */
+    // uuid?: string;
+    // /**
+    //  * @argument 极光推送ID
+    //  */
+    // ajpushid?: string;
+    // /**
+    //  * @argument 可用权限列表
+    //  */
+    // rsltFunids?: number[];
+    // /**
+    //  * @argument 系统选项列表
+    //  */
+    // optionList?: sys_option[];
+    // /**
+    //  * @argument 存在新结构MtrlConfigStr,但没开始用
+    //  */
+    // statusname?: string;
+    // woodcodename?: string;
+    // pcodename?: string;
+    // zxmtrlmodename?: string;
+    // usermtrlmodename?: string;
+    // mtrlsectypename?: string;
+    // outrepstrTips?: string;
+    // outrepcode?: string;
+    // dollarRate?: number;
+    // dollarMoneyid?: number;
+    // gw_inuse?: number | null;
+    // gw_power1?: number | null;
+    // gw_power3?: number | null;
+    // ifnotin?: number | null;
+    // phoneNumber?: string;
+    // phoneUUID?: string;
+    // /**
+    //  * @argument 公告栏列表
+    //  */
+    // postList?: u_sys_post[];
+    // powerWrkgrp?: u_sc_workgroup[];
+    // /**
+    //  * @argument 该客户是否金龙恒
+    //  */
+    // isJLH?: boolean;
+    // /**
+    //  * @argument 商品所有类别
+    //  */
+    // mtrltypeAllList?: Set<string>;
+    // /**
+    //  * @argument 商品主要类别
+    //  */
+    // mtrltypeList?: string[];
+    // /**
+    //  * @argument 畅销类别
+    //  */
+    // saletypeList?: string[];
+    // /**
+    //  * @argument 产品系列
+    //  */
+    // bandList?: string[];
+    // /**
+    //  * @argument 单据塔头
+    //  */
+    // billcodeList?: u_billcode[];
+    // /**
+    //  * @argument 分账套权限
+    //  */
+    // companyList?: u_company[];
+    // /**
+    //  * @argument 分部权限
+    //  */
+    // scstr?: string;
+    // /**
+    //  * @argument 物料分类
+    //  */
+    // mtrltypestr?: string;
+    // /**
+    //  * @argument 仓库权限-查询
+    //  */
+    // storagestr?: string;
+    // /**
+    //  * @argument 仓库权限-新增
+    //  */
+    // storagestr_new?: string;
+    // /**
+    //  * @argument 仓库权限-审核
+    //  */
+    // storagestr_audit?: string;
+    // /**
+    //  * @argument 出纳账号
+    //  */
+    // accountsidstr?: string;
   }
 }
 
@@ -989,6 +991,18 @@ export namespace GenericApi {
      */
     reJob: any;
   }
+  export interface ReqFormulaCompute {
+    /**
+     * @description 计算公式
+     */
+    formulas: any[];
+  }
+  export interface ResFormulaCompute {
+    /**
+     * @description 返回的结果
+     */
+    values: number[];
+  }
 }
 
 export namespace FileApi {
@@ -1067,23 +1081,17 @@ export namespace SalePrice {
     dept: any;
   }
 
-  export interface ResSaveDept {
-
-  }
+  export interface ResSaveDept {}
 
   export interface ReqDeleteDept {
     list: any[];
   }
 
-  export interface ResDeleteDept {
-    
-  }
+  export interface ResDeleteDept {}
 
   export interface ReqSaveProfitrate {
     list: any[];
   }
 
-  export interface ResSaveProfitrate {
-
-  }
+  export interface ResSaveProfitrate {}
 }

+ 4 - 0
JLHWEB/src/api/modules/common.ts

@@ -66,3 +66,7 @@ export const DownloadCacheFile = (params: FileApi.ReqCacheFile) => {
 export const UploadFile = (params: FileApi.ReqUploadFile) => {
   return http.post(PORT1 + `/UploadL1File`, params);
 };
+
+export const GetFormulaCompute = (params: GenericApi.ReqFormulaCompute) => {
+  return http.post<GenericApi.ResFormulaCompute>(PORT1 + `/GetFormulaCompute`, params);
+};

+ 201 - 184
JLHWEB/src/components/LjDetail/components/BaseForm.vue

@@ -357,18 +357,10 @@
                           :icon="WarningFilled"
                           icon-color="#626AEF"
                           :title="$t('common.table.delGroupTips')"
-                          :disabled="!element.label"
                           @confirm="toDelGroup(element)"
                         >
                           <template #reference>
-                            <el-button
-                              size="small"
-                              type="danger"
-                              plain
-                              circle
-                              :icon="Delete"
-                              :disabled="!element.label"
-                            ></el-button>
+                            <el-button size="small" type="danger" plain circle :icon="Delete"></el-button>
                           </template>
                         </el-popconfirm>
                       </div>
@@ -465,175 +457,176 @@
               </draggable>
             </template>
             <template v-else>
-              <GridItem
-                class="detail__info-group"
-                v-for="(groupItem, groupIdx) in groupFlatColumns"
-                :key="groupIdx"
-                :span="Number(groupItem.span ?? searchCol[breakPoint])"
-                :row="groupItem.row ?? 1"
-                :index="groupIdx"
-              >
-                <el-skeleton animated :loading="loading" class="mb-8" v-if="groupItem.label">
-                  <template #template><el-skeleton-item variant="h3" style="height: 24px; vertical-align: middle" /></template>
-                  <div class="group-header flx">
-                    <div
-                      class="title flx-1 flx-start"
-                      @click="!settingStatus && (groupItem.collapsed = !groupItem.collapsed)"
-                      :class="{
-                        'has-hidden': hideGroup(groupItem.list).length > 0 && !settingStatus,
-                        'text-h4-m': tableSize == '',
-                        'text-h5-m': tableSize == 'medium',
-                        'text-body-m': tableSize == 'mini'
-                      }"
-                    >
-                      <span class="header-title">
-                        {{ groupItem.label ? groupItem.label : $t("common.notGrouped") }}
-                      </span>
-                      <template v-if="hideGroup(groupItem.list).length > 0 && !settingStatus">
-                        <el-text type="primary" link class="search-isOpen ml-8">
-                          {{ groupItem.collapsed ? $t("common.table.expand") : $t("common.table.putAway") }}
-                          <el-icon class="el-icon--right">
-                            <component :is="groupItem.collapsed ? ArrowDown : ArrowUp"></component>
-                          </el-icon>
-                        </el-text>
-                      </template>
-                    </div>
-                    <div class="flx-shrink">
-                      <slot :name="'group-header-' + groupIdx"> </slot>
-                    </div>
-                  </div>
-                </el-skeleton>
-
-                <Grid
-                  class="detail__info-group-list"
-                  :collapsed="collapsed"
-                  :gap="[16, 2]"
-                  :cols="getSpan(groupItem.span, breakPoint)"
-                  :setting="settingStatus"
+              <template v-for="(groupItem, groupIdx) in groupFlatColumns" :key="groupIdx">
+                <GridItem
+                  class="detail__info-group"
+                  v-if="getVisibleLength(groupItem)"
+                  :span="Number(groupItem.span ?? searchCol[breakPoint])"
+                  :row="groupItem.row ?? 1"
+                  :index="groupIdx"
                 >
-                  <template #default>
-                    <template v-for="(item, index) in showGroup(groupItem.list)" :key="item.field">
-                      <GridItem
-                        v-if="!item?.basicinfo?.disabled"
-                        v-bind="getResponsive(item)"
-                        :index="index"
-                        :row="item.basicinfo?.row ?? 1"
+                  <el-skeleton animated :loading="loading" class="mb-8" v-if="groupItem.label">
+                    <template #template><el-skeleton-item variant="h3" style="height: 24px; vertical-align: middle" /></template>
+                    <div class="group-header flx">
+                      <div
+                        class="title flx-1 flx-start"
+                        @click="!settingStatus && (groupItem.collapsed = !groupItem.collapsed)"
+                        :class="{
+                          'has-hidden': hideGroup(groupItem.list).length > 0 && !settingStatus,
+                          'text-h4-m': tableSize == '',
+                          'text-h5-m': tableSize == 'medium',
+                          'text-body-m': tableSize == 'mini'
+                        }"
                       >
-                        <!-- :class="{'to-search': editable && ![undefined, ''].includes(searchParam[item.basicinfo?.key ?? handleProp(item.field!)])}" -->
-                        <!-- :required="item.basicinfo?.required ?? false" -->
-                        <el-skeleton
-                          animated
-                          :loading="typeof searchParam[handleProp(item.field!)]  == 'undefined' && loading"
-                          class="mr-12"
+                        <span class="header-title">
+                          {{ groupItem.label ? groupItem.label : $t("common.notGrouped") }}
+                        </span>
+                        <template v-if="hideGroup(groupItem.list).length > 0 && !settingStatus">
+                          <el-text type="primary" link class="search-isOpen ml-8">
+                            {{ groupItem.collapsed ? $t("common.table.expand") : $t("common.table.putAway") }}
+                            <el-icon class="el-icon--right">
+                              <component :is="groupItem.collapsed ? ArrowDown : ArrowUp"></component>
+                            </el-icon>
+                          </el-text>
+                        </template>
+                      </div>
+                      <div class="flx-shrink">
+                        <slot :name="'group-header-' + groupIdx"> </slot>
+                      </div>
+                    </div>
+                  </el-skeleton>
+
+                  <Grid
+                    class="detail__info-group-list"
+                    :collapsed="collapsed"
+                    :gap="[16, 2]"
+                    :cols="getSpan(groupItem.span, breakPoint)"
+                    :setting="settingStatus"
+                  >
+                    <template #default>
+                      <template v-for="(item, index) in showGroup(groupItem.list)" :key="item.field">
+                        <GridItem
+                          v-if="!item?.basicinfo?.disabled"
+                          v-bind="getResponsive(item)"
+                          :index="index"
+                          :row="item.basicinfo?.row ?? 1"
+                        >
+                          <!-- :class="{'to-search': editable && ![undefined, ''].includes(searchParam[item.basicinfo?.key ?? handleProp(item.field!)])}" -->
+                          <!-- :required="item.basicinfo?.required ?? false" -->
+                          <el-skeleton
+                            animated
+                            :loading="typeof searchParam[handleProp(item.field!)]  == 'undefined' && loading"
+                            class="mr-12"
+                          >
+                            <template #template
+                              ><el-skeleton-item variant="h3" style="height: 30px; vertical-align: middle"
+                            /></template>
+                            <el-form-item
+                              :title="filterTitle(item)"
+                              :prop="item.basicinfo?.key ?? handleProp(item.field!)"
+                              :rules="item.rules"
+                              :class="{
+                                'is-label-top': publicAttr.labelPosition == 'top',
+                                'is-editable': getIfCanEditable(item)
+                              }"
+                              :data-field="item.field"
+                            >
+                              <template #label>
+                                <span class="text-ellipsis-two">
+                                  {{ filterTitle(item) }}
+                                </span>
+                              </template>
+                              <template
+                                v-if="
+                                  (getIfCanEditable(item) && item.basicinfo?.editable.includes(orderStatus)) ||
+                                  (item?.basicinfo && item.basicinfo?.render) ||
+                                  item?.render
+                                "
+                              >
+                                <BaseFormItem
+                                  :field="item.field"
+                                  :column="getBaseFormCol(item)"
+                                  :field-names="item.fieldNames"
+                                  :search-param="searchParam"
+                                />
+                              </template>
+                              <el-input
+                                v-else
+                                :value="formatFunc(searchParam[handleProp(item.field!)], item)"
+                                disabled
+                                v-bind="{ ...item.basicinfo.props, ...cpBasicinfoAttr(item) }"
+                              />
+                            </el-form-item>
+                          </el-skeleton>
+                        </GridItem>
+                      </template>
+
+                      <template v-if="!groupItem.collapsed">
+                        <GridItem
+                          v-if="hideGroup(groupItem.list).length > 0"
+                          :span="getSpan(groupItem.span, breakPoint)"
+                          :row="groupItem.row ?? 1"
+                        >
+                          <el-divider content-position="left">
+                            <span class="text-disable">隐藏字段</span>
+                          </el-divider>
+                        </GridItem>
+
+                        <GridItem
+                          v-for="(item, index) in hideGroup(groupItem.list)"
+                          :key="item.field"
+                          :row="item.basicinfo?.row ?? 1"
+                          v-bind="getResponsive(item)"
+                          :index="index"
                         >
-                          <template #template
-                            ><el-skeleton-item variant="h3" style="height: 30px; vertical-align: middle"
-                          /></template>
+                          <!-- :class="{'to-search': editable && ![undefined, ''].includes(searchParam[item.basicinfo?.key ?? handleProp(item.field!)])}" -->
                           <el-form-item
                             :title="filterTitle(item)"
                             :prop="item.basicinfo?.key ?? handleProp(item.field!)"
                             :rules="item.rules"
+                            :required="item.basicinfo?.required ?? false"
                             :class="{
                               'is-label-top': publicAttr.labelPosition == 'top',
                               'is-editable': getIfCanEditable(item)
                             }"
-                            :data-field="item.field"
                           >
                             <template #label>
                               <span class="text-ellipsis-two">
                                 {{ filterTitle(item) }}
                               </span>
                             </template>
-                            <template
-                              v-if="
-                                (getIfCanEditable(item) && item.basicinfo?.editable.includes(orderStatus)) ||
-                                (item?.basicinfo && item.basicinfo?.render) ||
-                                item?.render
-                              "
+                            <el-skeleton
+                              animated
+                              :loading="typeof searchParam[handleProp(item.field!)]  == 'undefined' && loading"
+                              class="mr-12"
                             >
-                              <BaseFormItem
-                                :field="item.field"
-                                :column="getBaseFormCol(item)"
-                                :field-names="item.fieldNames"
-                                :search-param="searchParam"
-                              />
-                            </template>
-                            <el-input
-                              v-else
-                              :value="formatFunc(searchParam[handleProp(item.field!)], item)"
-                              disabled
-                              v-bind="{ ...item.basicinfo.props, ...cpBasicinfoAttr(item) }"
-                            />
+                              <template #template
+                                ><el-skeleton-item variant="h3" style="height: 30px; vertical-align: middle"
+                              /></template>
+
+                              <template
+                                v-if="
+                                  (getIfCanEditable(item) && item.basicinfo?.editable.includes(orderStatus)) ||
+                                  (item?.basicinfo && item.basicinfo?.render) ||
+                                  item?.render
+                                "
+                              >
+                                <BaseFormItem
+                                  :field="item.field"
+                                  :column="getBaseFormCol(item)"
+                                  :field-names="item.fieldNames"
+                                  :search-param="searchParam"
+                                />
+                              </template>
+                              <el-input v-else :value="formatFunc(searchParam[handleProp(item.field!)], item)" disabled />
+                            </el-skeleton>
                           </el-form-item>
-                        </el-skeleton>
-                      </GridItem>
-                    </template>
-
-                    <template v-if="!groupItem.collapsed">
-                      <GridItem
-                        v-if="hideGroup(groupItem.list).length > 0"
-                        :span="getSpan(groupItem.span, breakPoint)"
-                        :row="groupItem.row ?? 1"
-                      >
-                        <el-divider content-position="left">
-                          <span class="text-disable">隐藏字段</span>
-                        </el-divider>
-                      </GridItem>
-
-                      <GridItem
-                        v-for="(item, index) in hideGroup(groupItem.list)"
-                        :key="item.field"
-                        :row="item.basicinfo?.row ?? 1"
-                        v-bind="getResponsive(item)"
-                        :index="index"
-                      >
-                        <!-- :class="{'to-search': editable && ![undefined, ''].includes(searchParam[item.basicinfo?.key ?? handleProp(item.field!)])}" -->
-                        <el-form-item
-                          :title="filterTitle(item)"
-                          :prop="item.basicinfo?.key ?? handleProp(item.field!)"
-                          :rules="item.rules"
-                          :required="item.basicinfo?.required ?? false"
-                          :class="{
-                            'is-label-top': publicAttr.labelPosition == 'top',
-                            'is-editable': getIfCanEditable(item)
-                          }"
-                        >
-                          <template #label>
-                            <span class="text-ellipsis-two">
-                              {{ filterTitle(item) }}
-                            </span>
-                          </template>
-                          <el-skeleton
-                            animated
-                            :loading="typeof searchParam[handleProp(item.field!)]  == 'undefined' && loading"
-                            class="mr-12"
-                          >
-                            <template #template
-                              ><el-skeleton-item variant="h3" style="height: 30px; vertical-align: middle"
-                            /></template>
-
-                            <template
-                              v-if="
-                                (getIfCanEditable(item) && item.basicinfo?.editable.includes(orderStatus)) ||
-                                (item?.basicinfo && item.basicinfo?.render) ||
-                                item?.render
-                              "
-                            >
-                              <BaseFormItem
-                                :field="item.field"
-                                :column="getBaseFormCol(item)"
-                                :field-names="item.fieldNames"
-                                :search-param="searchParam"
-                              />
-                            </template>
-                            <el-input v-else :value="formatFunc(searchParam[handleProp(item.field!)], item)" disabled />
-                          </el-skeleton>
-                        </el-form-item>
-                      </GridItem>
+                        </GridItem>
+                      </template>
                     </template>
-                  </template>
-                </Grid>
-              </GridItem>
+                  </Grid>
+                </GridItem>
+              </template>
             </template>
           </template>
         </Grid>
@@ -795,11 +788,10 @@
               :icon="WarningFilled"
               icon-color="#626AEF"
               :title="$t('common.table.delGroupTips')"
-              :disabled="!curGroup.label"
               @confirm="menuItemClick('DeleteGroup', () => toDelGroup(curGroup))"
             >
               <template #reference>
-                <el-button type="danger" text plain :icon="Delete" :disabled="!curGroup.label"></el-button>
+                <el-button type="danger" text plain :icon="Delete"></el-button>
               </template>
             </el-popconfirm>
           </el-button-group>
@@ -892,6 +884,7 @@ import BasicInfoSelect from "./BasicInfoSelect.vue";
 import LjFloatingMenu from "@/components/LjFloatingMenu/index.vue";
 import { useMagicKeys, whenever } from "@vueuse/core";
 import { classNameIncludes } from "@/utils/index";
+import tableJson from "@/languages/modules/zh-cn/table.json";
 
 interface GroupBasicProps {
   label?: string;
@@ -1778,9 +1771,24 @@ const getInfoBaseForm = (data: any) => {
  * @description 过滤转换失败的标题
  * @param col column
  */
-const filterTitle = (col: any) => {
-  let _title = col?.table ? t(`table.${col?.table}.${col?.field}`) : col.title;
-  return _title && _title.indexOf("table") > -1 ? col.title : _title;
+const filterTitle = (item: any) => {
+  let _title = item.title;
+  let _tableJson: any = tableJson;
+  if (item.basicinfo?.labelHidden) {
+    return "";
+  }
+  if (Object.keys(_tableJson).includes(item.table)) {
+    if (item.basicinfo?.titleKey) {
+      Object.keys(_tableJson[item.table]).includes(item.basicinfo?.titleKey) &&
+        (_title = t(`table.${item.table}.${item.basicinfo?.titleKey}`));
+    } else if (item.basicinfo?.key) {
+      Object.keys(_tableJson[item.table]).includes(item.basicinfo?.key) &&
+        (_title = t(`table.${item.table}.${item.basicinfo?.key}`));
+    } else {
+      Object.keys(_tableJson[item.table]).includes(item.field) && (_title = t(`table.${item.table}.${item.field}`));
+    }
+  }
+  return _title;
 };
 
 watch(
@@ -1796,7 +1804,7 @@ watch(
 
     groupFlatColumns.value = getInfoBaseForm(val);
 
-    console.log(" watch onMounted groupFlatColumns.value :>> ", groupFlatColumns.value);
+    console.log(" watch onMounted groupFlatColumns.value :>> ", groupFlatColumns.value, val);
   },
   { deep: true, immediate: true }
 );
@@ -2032,31 +2040,36 @@ const toAddGroup = () => {
  * @description 删除属性分组
  */
 const toDelGroup = (element: any) => {
-  let _index = groupFlatColumns.value.findIndex((item: any) => item.label == element.label);
+  // let _index = groupFlatColumns.value.findIndex((item: any) => item.label == element.label);
 
-  let cols = cloneDeep(element.list);
-  cols.forEach((col: any) => {
-    col.basicinfo.group = "";
-  });
+  // let cols = cloneDeep(element.list);
+  // cols.forEach((col: any) => {
+  //   col.basicinfo.group = "";
+  //   col.basicinfo.visible = false;
+  // });
 
-  let hasConcat = false;
+  // let hasConcat = false;
   groupFlatColumns.value.forEach((item: any) => {
-    if (item.label == "") {
-      item.list = item.list.concat(cols);
-      hasConcat = true;
+    if (item.label == element.label) {
+      // item.list = item.list.concat(cols);
+      item.list.forEach((col: any) => {
+        col.basicinfo.group = "";
+        col.basicinfo.visible = false;
+      });
+      // hasConcat = true;
     }
   });
-  groupFlatColumns.value.splice(_index, 1);
-
-  if (!hasConcat) {
-    groupFlatColumns.value.push({
-      label: "",
-      list: cols,
-      collapsed: true,
-      edit: false
-      // span: props.searchCol[breakPoint.value]
-    });
-  }
+  // groupFlatColumns.value.splice(_index, 1);
+
+  // if (!hasConcat) {
+  //   groupFlatColumns.value.push({
+  //     label: "",
+  //     list: cols,
+  //     collapsed: true,
+  //     edit: false
+  //     // span: props.searchCol[breakPoint.value]
+  //   });
+  // }
 };
 
 /**
@@ -2269,6 +2282,10 @@ const cpBasicinfoAttr = (item: any) => {
   return attr;
 };
 
+const getVisibleLength = (data: any) => {
+  return data.list.filter((item: any) => item.basicinfo.visible).length;
+};
+
 defineExpose({
   element: formRef,
   refresh

+ 10 - 9
JLHWEB/src/components/LjDetail/components/BasicInfoSelect.vue

@@ -640,7 +640,8 @@ const classNamesToCheck = [
   "setting-grid-item",
   // "el-input__inner", // 搜索输入框
   "hidden-btn", // 字段隐藏按钮
-  "select-match" // 搜索输入框
+  "select-match", // 搜索输入框,
+  "el-drawer__footer" // 底部控制栏
 ];
 /**
  * @description 初始化拖拽
@@ -658,14 +659,14 @@ const initDragSelect = () => {
       console.log(element.target);
       console.log(element.target.parentNode);
       console.log(element.target.parentNode.parentNode);
-      // if (element && element.target) {
-      //   let includesResult = classNameIncludes(element.target, classNamesToCheck);
-      //   console.log("element.target.className :>> ", element.target.className);
-      //   console.log("element.target. includesResult :>> ", includesResult);
-      //   if (includesResult) {
-      //     drag.value.break();
-      //   }
-      // }
+      if (element && element.target) {
+        let includesResult = classNameIncludes(element.target, classNamesToCheck);
+        console.log("element.target.className :>> ", element.target.className);
+        console.log("element.target. includesResult :>> ", includesResult);
+        if (includesResult) {
+          columnsDrag.value.break();
+        }
+      }
       // console.log("onDragStart selectColumn.value :>> ", JSON.stringify(selectColumn.value), drag.value.getSelection());
     },
     // onElementSelect(el: any) {

+ 9 - 9
JLHWEB/src/components/LjDetail/components/ButtonGroup.vue

@@ -98,7 +98,7 @@ const getNotLimited = (data: any) => {
 };
 
 const getIconSlot = (item: any) => {
-  console.log("item , item.icon, typeof item.icon :>> ", JSON.stringify(item), item.icon, typeof item.icon);
+  // console.log("item , item.icon, typeof item.icon :>> ", JSON.stringify(item), item.icon, typeof item.icon);
   let iconRender = {};
   switch (typeof item.icon) {
     case "function":
@@ -122,7 +122,7 @@ const getIconSlot = (item: any) => {
  * @description 按钮组渲染
  */
 const buttonItemRender = (item: any) => {
-  console.log("buttonItemRender item :>> ", item);
+  // console.log("buttonItemRender item :>> ", item);
   if (!item) return;
   let iconRender = getIconSlot(item);
   let _item = cloneDeep(item);
@@ -192,7 +192,7 @@ const buttonItemRender = (item: any) => {
  */
 const buttonsMenuRender = (item: any) => {
   if (!item) return;
-  console.log("buttonsMenuRender item :>> ", item);
+  // console.log("buttonsMenuRender item :>> ", item);
   let iconRender = getIconSlot(item);
   let _item = cloneDeep(item);
   typeof _item.icon == "string" && delete _item.icon;
@@ -364,17 +364,17 @@ const bottonDropdownRender = (item: any, placement?: string) => {
 const RenderButtonGroup = () => {
   let btnListRender: any = [];
   let menuListRender: any = [];
-  console.log("rProp.buttons :>> ", props.buttons);
+  // console.log("rProp.buttons :>> ", props.buttons);
 
   let butttons = [];
 
   if (props.buttons?.length) {
-    console.log("innerwidth.value :>> ", innerwidth.value);
+    // console.log("innerwidth.value :>> ", innerwidth.value);
     let keyIndex = Math.floor(innerwidth.value / itemWidth) - 1;
     // butttons = props.buttons.filter((item: any) => !item?.limited);
     butttons = getNotLimited(props.buttons);
 
-    console.log("keyIndex :>> ", keyIndex, butttons.length, innerwidth.value, butttons);
+    // console.log("keyIndex :>> ", keyIndex, butttons.length, innerwidth.value, butttons);
     btnListRender = butttons.map((item: any, index: number) => {
       console.log("index, keyIndex, item :>> ", index, keyIndex, item);
       if (index + 1 > keyIndex) return;
@@ -390,7 +390,7 @@ const RenderButtonGroup = () => {
       }
     });
     btnListRender = btnListRender.filter((item: any) => item);
-    console.log("RenderButtonGroup btnListRender :>> ", btnListRender);
+    // console.log("RenderButtonGroup btnListRender :>> ", btnListRender);
 
     if (btnListRender.length < butttons?.length) {
       let dropdownRender = butttons.map((item: any, index: number) => {
@@ -456,8 +456,8 @@ const RenderButtonGroup = () => {
     }
   }
 
-  console.log("btnListRender :>> ", btnListRender);
-  console.log("menuListRender :>> ", menuListRender);
+  // console.log("btnListRender :>> ", btnListRender);
+  // console.log("menuListRender :>> ", menuListRender);
   return (
     <>
       <el-button-group class="detail-menu__btn-group">{btnListRender}</el-button-group>

+ 2 - 1
JLHWEB/src/components/LjDetail/index.vue

@@ -1520,7 +1520,8 @@ const RenderTabs = (rProps: DetailProp) => {
 
     tabRender = rProps.mould.map((item: detailModelItemProp) => {
       // console.log("tasItemRender item :>> ", item);
-      if (item?.limited) return;
+      let _limited = isFunction(item?.limited) ? item.limited(_mainData.value) : item?.limited ?? false;
+      if (_limited) return;
       if (!item.isHidden) {
         if (slots[item.id]) {
           return tasItemRender(item, () => {

+ 1 - 1
JLHWEB/src/components/LjDetail/interface/index.ts

@@ -33,7 +33,7 @@ export interface detailModelItemProp extends requestApiProps {
   /**
    * @augments boolean 是否限制显示
    */
-  limited?: boolean;
+  limited?: boolean | ((params?: any) => boolean);
 }
 
 /**

+ 1 - 1
JLHWEB/src/components/LjVxeTable/components/FilterExtend.vue

@@ -272,7 +272,7 @@ const tableData = reactive({
 
 const getEnumValue = (val: any) => {
   let msg = val;
-  console.log("getEnumValue props.params.enum, props.params :>> ", props.params.enum, props.params);
+  // console.log("getEnumValue props.params.enum, props.params :>> ", props.params.enum, props.params);
   if (props.params.hasOwnProperty("enum") && isArray(props.params.enum) && props.params.enum.length) {
     let itm =
       props.params.enum.find((item: CaseItem) => {

+ 1 - 0
JLHWEB/src/components/LjVxeTable/components/TableColumn.vue

@@ -32,6 +32,7 @@ const getTagType = (item: ColumnProps, scope: RenderScope<any>) => {
 
 const RenderTableColumn: any = (item: ColumnProps) => {
   let enumData = enumMap.value.get(item.field) ?? [];
+  // console.log("RenderTableColumn enumData :>> ", enumData, enumMap.value, item.field);
 
   // 排序图标
   let sortRender: any = null;

+ 1 - 1
JLHWEB/src/components/LjVxeTable/index.vue

@@ -189,7 +189,7 @@
       :style="{ minHeight: propsDefine?.minHeight }"
     >
       <el-dropdown
-        v-if="collapseButtons"
+        v-if="collapseButtons && (defaultSort.length || toolButton.length)"
         class="collapse-buttons__group"
         placement="bottom-end"
         trigger="click"

+ 5 - 5
JLHWEB/src/components/LjVxeTable/interface/index.ts

@@ -97,7 +97,11 @@ export type SearchProps = {
    */
   labelWidth?: string | number;
   /**
-   * @description 是否可视, 默认:true
+   * @description 是否隐藏标签,默认:false
+   */
+  labelHidden?: boolean;
+  /**
+   * @description 是否可视, 默认:true, false:禁止渲染详情页模式中的单元格
    */
   visible?: boolean;
   /**
@@ -136,10 +140,6 @@ export interface basicinfoProps extends SearchProps {
    * @argument number 占用的行数,默认为1列
    */
   row?: number;
-  /**
-   * @description 是否禁止渲染详情页模式中的单元格
-   */
-  disabled?: boolean;
 }
 
 export type FieldNamesProps = {

+ 142 - 0
JLHWEB/src/components/ToastWidget/Formula/components/Item.vue

@@ -0,0 +1,142 @@
+<template>
+  <RenderFormulaItem />
+</template>
+
+<script setup lang="tsx" name="LjToastFormulaItem">
+import type { formulasProp } from "../index.vue";
+import { ElScrollbar } from "element-plus";
+
+interface itemProps {
+  data: any;
+  /**
+   * @description 计算公式列表
+   */
+  formulas: formulasProp[];
+  /**
+   * @description 字段对照表
+   */
+  fields: formulasProp[];
+  dataValue: any;
+}
+
+const props = defineProps<itemProps>();
+
+const funcFormulaToArray = (formula: string) => {
+  let result = [];
+  let lastIndex = 0;
+  let fArr = formula.match(/\[(.*?)\]/g); //匹配方括号及其内容。
+
+  fArr.forEach((match, index) => {
+    let start = formula.indexOf(match, lastIndex);
+    let end = start + match.length;
+
+    // 添加匹配前的部分
+    result.push(formula.slice(lastIndex, start));
+
+    // 添加匹配到的内容
+    result.push(match);
+
+    // 更新 lastIndex
+    lastIndex = end;
+  });
+
+  // 添加最后一部分
+  result.push(formula.slice(lastIndex));
+
+  return result.filter(t => t);
+};
+
+const RenderVariable = (data: any) => {
+  console.log("RenderVariable data :>> ", data);
+
+  let fieldId = data.slice(1, -1); // 去掉方括号
+  let fieldName = data.slice(1, -1); // 去掉方括号
+
+  console.log("fieldName,  :>> ", fieldName, props.dataValue);
+
+  let sumVal = props.formulas.find(f => {
+    if (f.field === fieldName) {
+      fieldName = f.label;
+      return f;
+    } else if (f.label === fieldName) {
+      fieldId = f.field;
+      return f;
+    }
+  });
+  !sumVal &&
+    (sumVal = props.fields.find(f => {
+      if (f.field === fieldName) {
+        fieldName = f.label;
+        return f;
+      } else if (f.label === fieldName) {
+        fieldId = f.field;
+        return f;
+      }
+    }));
+
+  console.log("RenderVariable sumVal :>> ", sumVal);
+  let _value = Object.keys(props.dataValue).includes(fieldId) ? Math.round(props.dataValue[fieldId] * 100) / 100 : "缺失";
+  return (
+    <>
+      <div class="flx-col flx-end formula-wrapper__item">
+        <span class="label text-secondary-text text-body-c">{fieldName}</span>
+        <span class="value text-primary-text text-h5-b">{_value}</span>
+      </div>
+    </>
+  );
+};
+
+const RenderFormulaItem = () => {
+  let fArr = funcFormulaToArray(props.data.formula);
+  console.log("fArr: --", fArr);
+  if (fArr.length > 0) {
+    return (
+      <>
+        {/* <ElScrollbar> */}
+        <div class="formula-wrapper flx-start-end">
+          {fArr.map((t, i) => {
+            if (t.indexOf("[") === 0) {
+              return <div>{RenderVariable(t)}</div>;
+            } else {
+              let _t = t.replace(/\*/g, "x");
+              return <span class="text-h5-r ">{_t}</span>;
+            }
+          })}
+        </div>
+        {/* </ElScrollbar> */}
+      </>
+    );
+  }
+};
+</script>
+
+<style lang="scss">
+.formula-wrapper {
+  // width: 400px;
+
+  // display: table;
+  width: max-content;
+  user-select: none;
+  & > * {
+    display: table-cell;
+    margin-left: 4px;
+  }
+
+  &__item {
+    display: flex;
+    & + & {
+      margin-left: 4px;
+    }
+
+    .value {
+      color: $color-primary-600;
+    }
+
+    &:hover {
+      .label {
+        color: $color-primary-400;
+      }
+    }
+  }
+}
+</style>

+ 257 - 0
JLHWEB/src/components/ToastWidget/Formula/index.vue

@@ -0,0 +1,257 @@
+<template>
+  <div class="lj-toast-oa-flow flx-col w-full">
+    <header class="flx">
+      <span class="flx-1 text-h5-b">{{ t("business.detail.summaryOfQuote") }}</span>
+      <div>
+        <el-button v-if="!hideClose" circle text :icon="Refresh" @click="emit('refresh')"></el-button>
+        <el-button v-if="!hideClose" circle text :icon="CloseBold" @click="emit('close-toast')"></el-button>
+      </div>
+    </header>
+    <main class="w-full">
+      <div class="flx-end summary-box" v-for="item in formulas" :key="item.field">
+        <div class="flx-1 enter-x overflow-auto" v-if="ifShow" style="max-width: 450px">
+          <FormulaItem :data="item" :formulas="formulas" :dataValue="data" :fields="fields" />
+        </div>
+        <div
+          class="summary-box__summy"
+          :class="ifShow ? 'flx-shrink is-show' : 'flx-1'"
+          :style="{ width: ifShow ? '90px' : 'unset' }"
+        >
+          <div class="summary-box_item" :class="ifShow ? 'flx-col' : 'flx'">
+            <div class="flx-1 text-secondary-text text-body-c" :class="{ 'text-right': ifShow }">
+              {{ item.label }}
+            </div>
+            <div class="flx-shrink ml-8 text-right text-h5-b">
+              {{ data[item.field] }}
+            </div>
+          </div>
+        </div>
+      </div>
+    </main>
+    <footer class="flx">
+      <el-button type="primary" class="flx-1" @click="handleToggleShow">{{
+        ifShow ? t("common.table.putAway") : t("common.showFormula")
+      }}</el-button>
+    </footer>
+  </div>
+</template>
+
+<script setup lang="ts" name="LjToastFormula">
+import { ref, onMounted, computed, watch } from "vue";
+import { useDesign } from "@/hooks/useDesign";
+import { CommonDynamicSelect, GetFormulaCompute } from "@/api/modules/common";
+import { useUserStore } from "@/stores/modules/user";
+import { useOaFlow } from "@/components/LjOaFlow/hooks/index";
+import { CloseBold, Refresh } from "@element-plus/icons-vue";
+import FormulaItem from "./components/Item.vue";
+
+export interface formulasProp {
+  /**
+   * @description 属性名称
+   */
+  label?: string;
+  /**
+   * @description 属性id
+   */
+  field: string;
+  /**
+   * @description 属性计算方法
+   */
+  formula?: string;
+  /**
+   * @argument 权限验证
+   */
+  power?: number | ((params?: any) => boolean);
+}
+
+// 接收父组件参数并设置默认值
+interface LjOaFlowProps {
+  /**
+   * @description i18n
+   */
+  t: any;
+  /**
+   * @description 类型ID
+   */
+  powerid: number;
+  /**
+   * @description 分部id
+   */
+  scid?: any;
+  /**
+   * @description 单据id
+   */
+  billid?: any;
+  /**
+   * @argument boolean 是否自动执行请求 api ==> 非必传(默认为true)
+   */
+  requestAuto?: boolean;
+  /**
+   * @description 状态enum
+   */
+  statusEnum?: any;
+  data?: any;
+  /**
+   * @description 是否隐藏关闭按钮
+   */
+  hideClose?: boolean;
+  /**
+   * @description 计算公式列表
+   */
+  formulas: formulasProp[];
+  /**
+   * @description 字段对照表
+   */
+  fields: formulasProp[];
+  showFormula?: boolean;
+}
+const props = withDefaults(defineProps<LjOaFlowProps>(), {
+  requestAuto: true,
+  hideClose: false,
+  data: () => {}
+  // showFooter: true
+});
+const emit = defineEmits(["close-toast", "toggle-formula", "refresh"]);
+const ifShow = ref(false);
+
+// const { t } = useI18n();
+const { userInfo } = useUserStore();
+// const { prefixCls } = useDesign("toast-oa-flow");
+
+const { itemData, oaFlowList, tabsValue, currentOaflow, oaDocStatus, isCurEmp, handleOpenBox, getOaFlowList } = useOaFlow(
+  props.powerid
+);
+
+// watch(
+//   [() => props.scid, () => props.billid],
+//   (val: any) => {
+//     console.log("watch oaflow val :>> ", val);
+//     getOaFlowList(val[0], val[1]).then(() => {
+//       if (oaFlowList.value.length > 0) {
+//         let _index: any = tabsValue.value ?? 0;
+//         console.log("onMounted oaFlowList.value :>> ", oaFlowList.value);
+//         console.log("onMounted _index :>> ", _index);
+//         let { docid } = oaFlowList.value[_index];
+//         getOaFlowItem(docid);
+//       }
+//     });
+//   },
+//   {}
+// );
+
+const getOaFlowItem = async (docid: number) => {
+  // 流转状况
+  let { datatable } = await CommonDynamicSelect({
+    dsname: "web_oa_flow_status_view_bill",
+    queryparams: {
+      docid: docid
+    }
+  });
+  console.log("getOaFlowItem datatable :>> ", datatable);
+  itemData.value = datatable;
+
+  console.log("currentOaflow :>> ", currentOaflow.value);
+
+  // if (currentOaflow.value) {
+  //   let _data = currentOaflow.value;
+  //   toast(
+  //     {
+  //       component: ToastErrCopy,
+  //       props: {
+  //         type: "info",
+  //         title: "待你审批",
+  //         message: _data.doctitle + "<br/>" + _data.flowstepname + ":" + _data.flowinfo,
+  //         actions: [
+  //           {
+  //             label: t("common.agree"),
+  //             value: 1,
+  //             props: {
+  //               type: "success"
+  //             }
+  //           },
+  //           {
+  //             label: t("common.oppose"),
+  //             value: 0,
+  //             props: {
+  //               type: "danger"
+  //             }
+  //           }
+  //         ]
+  //       },
+  //       listeners: {
+  //         actionClick: (data: any) => {
+  //           console.log("data :>> ", data);
+  //           if (data.value) {
+  //             // agree
+  //             handleOpenBox(true);
+  //           } else {
+  //             // oppose
+  //             handleOpenBox(false);
+  //           }
+  //         }
+  //       }
+  //     },
+  //     {
+  //       position: POSITION.BOTTOM_RIGHT,
+  //       icon: false,
+  //       timeout: 0,
+  //       closeButton: false,
+  //       toastClassName: "longjoe-toast"
+  //     }
+  //   );
+  // }
+};
+const handleClickTabs = () => {
+  console.log(tabsValue.value);
+  // console.log("handleClickTabs pane :>> ", pane);
+  let _index: any = tabsValue.value ?? 0;
+  console.log("oaFlowList.value :>> ", oaFlowList.value);
+  console.log("_index :>> ", _index);
+  let { docid } = oaFlowList.value[_index];
+  getOaFlowItem(docid);
+};
+
+onMounted(async () => {
+  console.log("onMounted props.data 初始化:>> ", props.data);
+  ifShow.value = props.showFormula;
+});
+
+const handleToggleShow = () => {
+  ifShow.value = !ifShow.value;
+  emit("toggle-formula", ifShow.value);
+};
+</script>
+
+<style lang="scss" scoped>
+.lj-toast-oa-flow {
+  width: 240px;
+
+  :deep(.el-tabs__header) {
+    margin-bottom: 0;
+  }
+}
+
+.summary-box {
+  & + & {
+    margin-top: 8px;
+  }
+
+  &:hover {
+    background: $color-primary-000;
+    // border-radius: 8px;
+  }
+  &__summy {
+    &.is-show {
+      position: relative;
+      margin-left: 12px;
+      &:before {
+        content: "=";
+        position: absolute;
+        left: 0;
+        bottom: 5px;
+        margin: auto;
+      }
+    }
+  }
+}
+</style>

+ 17 - 1
JLHWEB/src/enums/dwnameEnum.ts

@@ -21,7 +21,23 @@ export enum DwnameEnum {
   /**
    * @description 床垫报价明细
    */
-  mattressQuoteMx = "u_mattress_mx",
+  mattressQuoteMx = "u_mattress_mx_mtrl",
+  /**
+   * @description 床垫报价明细_床网
+   */
+  mattressQuoteMxBednet = "u_mattress_mx_mtrl__bednet",
+  /**
+   * @description 床垫报价明细_垫层
+   */
+  mattressQuoteMxCushions = "u_mattress_mx_mtrl__dianceng",
+  /**
+   * @description 床垫报价明细_辅料
+   */
+  mattressQuoteMxAccessories = "u_mattress_mx_mtrl__no",
+  /**
+   * @description 床垫报价明细_辅料
+   */
+  mattressQuoteMxInnerClothLayer = "u_mattress_mx_mtrl__neibutao",
   /**
    * @description 工厂利润率
    */

+ 10 - 1
JLHWEB/src/languages/modules/zh-cn/business.json

@@ -420,6 +420,15 @@
     "edittingQuit": "正在编辑中,退出将放弃修改",
     "successToEdit": "成功修改用户信息",
     "successToAdd": "成功新增用户",
-    "delConfirm": "确定要删除用户:"
+    "delConfirm": "确定要删除用户:",
+    "formula": "计算公式",
+    "summaryOfQuote": "报价汇总",
+    "fabric": "面料",
+    "bednet": "床网",
+    "cushions": "垫层",
+    "accessories": "辅料",
+    "packag": "包装",
+    "innerClothLayer": "内布层",
+    "topCotton": "顶布裥棉"
   }
 }

+ 1 - 1
JLHWEB/src/languages/modules/zh-cn/common.json

@@ -112,7 +112,7 @@
     "checkbox": "复选框",
     "datePickerTips": "选择日期筛选",
     "delDetail": "删明细",
-    "delGroupTips": "删除后,该分组下的数据将移动到\"其他信息\"",
+    "delGroupTips": "删除后,该分组下的字段数据将隐藏",
     "detail": "明细",
     "details": "明细列表",
     "downloadBtn": "导出数据",

+ 5 - 1
JLHWEB/src/languages/modules/zh-cn/table.json

@@ -1542,6 +1542,10 @@
     "status": "状态",
     "flag": "财务审核",
     "mattressname": "床垫名称",
-    "searchKw": "关键字"
+    "searchKw": "关键字",
+    "foreign_cost": "外币价",
+    "bi_foreign_cost": "报价金额",
+    "nottax_dept_cost": "部门不含税价",
+    "bi_nottax_dept_cost": "财务底价"
   }
 }

+ 2 - 2
JLHWEB/src/stores/modules/layoutLocal.ts

@@ -36,9 +36,9 @@ export const useLayoutLocalStore = defineStore({
       const { userInfo } = useUserStore();
       console.log("userInfo.userid :>> ", userInfo.empid);
       console.log("this.dwlayout :>> ", this.dwlayout);
-      let dwIdx = this.dwlayout.findIndex(item => item.empid == userInfo.empid && item.account == userInfo.account);
+      let dwIdx = this.dwlayout.findIndex(item => item.empid == userInfo.empid);
       console.log("dwIdx :>> ", dwIdx);
-      let userLayout = { empid: userInfo.empid ?? 0, account: userInfo.account ?? "", layoutList: <any>[] };
+      let userLayout = { empid: userInfo.empid ?? 0, layoutList: <any>[] };
       if (dwIdx > -1) {
         userLayout = this.dwlayout[dwIdx];
         console.log("findUserLayoutuserLayout userLayout:>> ", userLayout);

+ 6 - 5
JLHWEB/src/stores/modules/user.ts

@@ -83,9 +83,10 @@ export const useUserStore = defineStore({
         }
 
         this.setUserInfo(data);
-        this.userInfo.usercode = data.usercode;
-        this.userInfo.username = data.username;
-        this.userInfo.empid = data.empid;
+        // this.userInfo.usercode = data.usercode;
+        // this.userInfo.username = data.username;
+        // this.userInfo.empid = data.empid;
+        // this.userInfo.usermode = data.usermode;
         // if (!data.ifERPUser) {
         //   let _comInfo = {
         //     comid: data.comid,
@@ -255,9 +256,9 @@ export const useUserStore = defineStore({
      * @description 获取账套信息
      */
     async getToken() {
-      this.accounts = [];
+      // this.accounts = [];
       const data = await getTokenApi();
-      this.accounts = data.accounts ?? [];
+      // this.accounts = data.accounts ?? [];
     },
     async getUserInfo() {
       console.time("getUserInfo,用时间");

+ 3 - 0
JLHWEB/src/styles/common.scss

@@ -275,6 +275,9 @@
 .text-center {
   text-align: center;
 }
+.text-right {
+  text-align: right;
+}
 .text-ellipsis-one {
   white-space: nowrap;
   overflow: hidden;

+ 96 - 0
JLHWEB/src/utils/index.ts

@@ -4,6 +4,8 @@ import XEUtils from "xe-utils";
 import { cloneDeep, pick, get } from "lodash-es";
 import dayjs from "dayjs";
 import { useAuthButtons } from "@/hooks/useAuthButtons";
+import { GetFormulaCompute } from "@/api/modules/common";
+import { ElMessage } from "element-plus";
 
 import type { Menu } from "@/typings/global";
 
@@ -1097,3 +1099,97 @@ const formatTime = function (time: string | number, option: string, ifshort: boo
     return parseTime(time, option);
   }
 };
+
+const funcGetFormulaValue = (item, tgList, fieldList, valueList) => {
+  let _paras = item?.formula
+    .replace(/【/g, "[")
+    .replace(/】/g, "]")
+    .match(/\[([^\]]*)\]/g);
+  let resultFormula = item?.formula;
+
+  _paras.forEach(part => {
+    // console.log(part);
+    let fieldName = part.slice(1, -1); // 去掉方括号
+    // console.log(fieldName);
+    let sumVal = tgList.find(f => {
+      if (f.field === fieldName) {
+        return f;
+      } else if (f.label === fieldName) {
+        fieldName = f.field;
+        return f;
+      }
+    });
+    !sumVal &&
+      (sumVal = fieldList.find(f => {
+        if (f.field === fieldName) {
+          return f;
+        } else if (f.label === fieldName) {
+          fieldName = f.field;
+          return f;
+        }
+      }));
+
+    if (sumVal) {
+      let res = valueList[fieldName];
+      let _formula;
+      if (sumVal?.formula) {
+        _formula = sumVal.formula.replace(part, `${valueList[fieldName]}`);
+      }
+      // console.log(fieldName, _formula, sumVal);
+      if (_formula && _formula.indexOf("[") > -1) {
+        let _res = formulaPartsFormula([{ formula: _formula }], fieldList, valueList, tgList);
+        res = `(${_res[0]})`;
+      }
+      if (typeof res === "undefined") {
+        ElMessage.warning("接口未提供数据,请检查:" + fieldName);
+        console.error("接口未提供数据,请检查:" + fieldName);
+        return;
+      }
+      resultFormula = resultFormula.replace(part, res);
+    } else {
+      resultFormula = resultFormula.replace(part, `${valueList[fieldName]}`);
+    }
+  });
+  return resultFormula;
+};
+
+const formulaPartsFormula = (formulaList, fieldList, valueList, tgList = formulaList) => {
+  let result = [];
+  formulaList.map((item, index) => {
+    if (item?.formula) {
+      let res = funcGetFormulaValue(item, tgList, fieldList, valueList);
+      result.push(res);
+    }
+  });
+  return result;
+};
+
+/**
+ * @description 公式计算
+ * @param formulaList 公式列表 [{field: 'a', formula: '[b] + [c]'}]
+ * @param fieldList 字段列表 [{field: 'a', label: '字段A'}, {field: 'a', formula: '[b] + [c]'}]
+ * @param valueList 值列表 {a: 1, b: 2, c: 3}
+ * @returns {number[]} 计算结果 [1]
+ */
+export const calculateFormula = async (formulaList, fieldList, valueList) => {
+  let resultFormula: any[] = formulaPartsFormula(formulaList, fieldList, valueList);
+
+  console.log("resultFormula: ", resultFormula);
+  try {
+    let res = await GetFormulaCompute({
+      formulas: resultFormula
+    });
+    if (res.values.length == 0) return [];
+    let result = formulaList.map((item, index) => {
+      let _res = res.values[index] ?? 0;
+      return {
+        ...item,
+        value: _res
+      };
+    });
+    return result;
+  } catch (error) {
+    console.error("Formula evaluation error:", error);
+    return [];
+  }
+};

+ 482 - 51
JLHWEB/src/views/quote/mattressQuote/detail.vue

@@ -3,32 +3,109 @@
     name="rpMustPayCrmDetail"
     ref="LjDetailRef"
     v-bind="detailProps"
-    :data="mainData"
     :request-api="getData"
     :data-callback="dataCallback"
     :init-param="initParams"
     v-model:order-status="orderStatus"
     :action="orderStatus ? orderEditAction : orderDefaultAction"
+    :after-mound="funcAfterMound"
   >
     <!-- @to-pin-detail="emit('toPinDetail')" -->
-    <template #rpMustPayMxList>
+    <template #fabricMx>
+      <el-tabs v-model="fabricMxTabs" type="card" @tab-click="handleFabricMxTabsClick">
+        <template v-for="item in fabricMxTabList">
+          <el-tab-pane :label="item.label" :name="item.name" :key="item.name" v-if="item.visible()"></el-tab-pane>
+        </template>
+      </el-tabs>
       <LjVxeTable
-        ref="rpMustPayMxList"
+        ref="fabricMxRef"
         row-key="key"
         table-cls=""
-        :request-api="getData_mx"
-        :data-callback="dataCallback"
-        :init-param="initParams"
+        :data="fabricMxData"
         :columns="columnsMx"
         :dwname="DwnameEnum.mattressQuoteMx"
         :table-props="tableProps_mx"
+        :tool-button="[]"
+        :auto-load-layout="false"
+        collapseButtons
+      >
+      </LjVxeTable>
+    </template>
+    <template #bednetMx>
+      <LjVxeTable
+        ref="bednetMxRef"
+        row-key="key"
+        table-cls=""
+        :request-api="getData_bednet"
+        :data-callback="dataCallback"
+        :init-param="initParams"
+        :columns="columnsMxBednet"
+        :dwname="DwnameEnum.mattressQuoteMxBednet"
+        :table-props="tableProps_mx"
         :tool-button="['export', 'refresh', 'setting']"
         :auto-load-layout="false"
-        pagination
+        collapseButtons
+      >
+      </LjVxeTable>
+    </template>
+    <template #cushionsMx>
+      <LjVxeTable
+        ref="cushionsMxRef"
+        row-key="key"
+        table-cls=""
+        :request-api="getData_cushions"
+        :data-callback="dataCallback"
+        :init-param="initParams"
+        :columns="columnsMxCushions"
+        :dwname="DwnameEnum.mattressQuoteMxCushions"
+        :table-props="tableProps_mx"
+        :tool-button="['export', 'refresh', 'setting']"
+        :auto-load-layout="false"
+        collapseButtons
+      >
+      </LjVxeTable>
+    </template>
+    <template #accessoriesMx>
+      <LjVxeTable
+        ref="accessoriesMxRef"
+        row-key="key"
+        table-cls=""
+        :request-api="getData_accessories"
+        :data-callback="dataCallback"
+        :init-param="initParams"
+        :columns="columnsMxAccessories"
+        :dwname="DwnameEnum.mattressQuoteMxAccessories"
+        :table-props="tableProps_mx"
+        :tool-button="['export', 'refresh', 'setting']"
+        :auto-load-layout="false"
+        collapseButtons
+      >
+      </LjVxeTable>
+    </template>
+    <template #innerClothLayerMx>
+      <LjVxeTable
+        ref="innerClothLayerMxRef"
+        row-key="key"
+        table-cls=""
+        :request-api="getData_innerClothLayer"
+        :data-callback="dataCallback"
+        :init-param="initParams"
+        :columns="columnsMxInnerClothLayer"
+        :dwname="DwnameEnum.mattressQuoteMxInnerClothLayer"
+        :table-props="tableProps_mx"
+        :tool-button="['export', 'refresh', 'setting']"
+        :auto-load-layout="false"
+        collapseButtons
       >
       </LjVxeTable>
     </template>
   </LjDetail>
+
+  <el-button v-if="ifAfterMound" class="btn-floating pl-8 pr-8 pt-15 pb-15 h-auto" round v-draggable-btn="oaFlowFloadProp">
+    <span class="text-vertical">
+      {{ $t("business.detail.formula") }}
+    </span>
+  </el-button>
 </template>
 
 <script setup lang="ts" name="mattressQuoteDetail">
@@ -42,13 +119,17 @@ import { useAuthButtons } from "@/hooks/useAuthButtons";
 import LjVxeTable from "@/components/LjVxeTable/index.vue";
 import { cloneDeep } from "lodash-es";
 import { useRoute, useRouter } from "vue-router";
-import { CommonDynamicSelect } from "@/api/modules/common";
+import { CommonDynamicSelect, GetFormulaCompute } from "@/api/modules/common";
+import ToastFormula from "@/components/ToastWidget/Formula/index.vue";
+import { TYPE, useToast, POSITION } from "vue-toastification";
+import { ElMessage } from "element-plus";
+import { calculateFormula } from "@/utils/index";
 
 interface detailProp {
   /**
    * @argument any 页面数据
    */
-  data?: any;
+  data1?: any;
   /**
    * @argument string 请求数据的api ==> 非必传
    */
@@ -66,35 +147,189 @@ interface detailProp {
 const props = withDefaults(defineProps<detailProp>(), {});
 const { t } = useI18n();
 const route = useRoute();
-const { columns, columnsMx } = useHooks(t);
+const {
+  columns,
+  columnsMx,
+  columnsMxBednet,
+  columnsMxCushions,
+  columnsMxAccessories,
+  columnsMxInnerClothLayer,
+  LjDetailRef,
+  summaryData,
+  fieldParams
+} = useHooks(t);
 const { CheckPower, CheckOption, buttonNew, buttonDefault } = useAuthButtons(t);
+const toast = useToast();
 
+const showFormula = ref(false);
 const initParams = ref({ arg_mattressid: 0 });
-const mainData = ref([]);
 const orderStatus = ref("");
+// const mainData = ref([]);
+
+/**
+ * @description tab 面料
+ * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+ */
+const fabricMxData = ref([]);
+const fabricMxResData = ref();
+const fabricMxRef = ref();
+const fabricMxTabs = ref("fabricMx");
+const fabricMxTabList = ref([
+  {
+    label: "裥面",
+    name: "tabpage_8",
+    visible: () => Number(mattresstypeEnum.value.if_top_side) == 1,
+    type: [0, 80, 40, 50, 60, 70, 9000]
+  },
+  {
+    label: "裥底",
+    name: "tabpage_9",
+    visible: () => Number(mattresstypeEnum.value.if_button_sdie) == 1,
+    type: [1, 81, 41, 51, 61, 71, 9001]
+  },
+  {
+    label: "裥大恻",
+    name: "tabpage_10",
+    visible: () => Number(mattresstypeEnum.value.if_big_side) == 1,
+    type: [2, 82, 42, 52, 62, 72, 9002]
+  },
+  {
+    label: "裥小恻",
+    name: "tabpage_11",
+    visible: () => Number(mattresstypeEnum.value.if_small_side) == 1,
+    type: [3, 83, 43, 53, 63, 73, 9003]
+  },
+  {
+    label: "裥V恻",
+    name: "tabpage_12",
+    visible: () => Number(mattresstypeEnum.value.if_v_side) == 1,
+    type: [4, 84, 44, 54, 64, 74, 9004]
+  },
+  {
+    label: "拉手刺绣及其他工艺",
+    name: "tabpage_13",
+    visible: () => true,
+    type: [
+      0, 80, 40, 50, 60, 70, 1, 81, 41, 51, 61, 71, 2, 82, 42, 52, 62, 72, 3, 83, 43, 53, 63, 73, 4, 84, 44, 54, 64, 74, 9000,
+      9001, 9002, 9003, 9004, 9005, 9006
+    ]
+  }
+]);
+const mattresstypeEnum = ref<any>({});
+
+const getData_mx = (params: any) => {
+  console.log("getData params :>> ", params);
+  let newParams: any = {};
+  params.pageNum && (newParams.pageindex = params.pageNum);
+  params.pageSize && (newParams.pagesize = params.pageSize);
+  delete params.pageNum;
+  delete params.pageSize;
+  newParams.queryParams = params;
+  console.log("params :>> ", params);
+  newParams.dsname = "web_mattress_mx";
+  return CommonDynamicSelect(newParams, DwnameEnum.mattressQuoteMx);
+  // return [];
+};
+/**↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
+
+/**
+ * @description tab 床网
+ * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+ */
+
+const getData_cushions = (params: any) => {
+  console.log("getData params :>> ", params);
+  let newParams: any = {};
+  params.pageNum && (newParams.pageindex = params.pageNum);
+  params.pageSize && (newParams.pagesize = params.pageSize);
+  delete params.pageNum;
+  delete params.pageSize;
+  newParams.queryParams = params;
+  console.log("params :>> ", params);
+  newParams.dsname = "web_mattress_mx_dianceng";
+  return CommonDynamicSelect(newParams, DwnameEnum.mattressQuoteMxBednet);
+};
+/**↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
+
+/**
+ * @description tab 垫层
+ * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+ */
+
+const getData_accessories = (params: any) => {
+  console.log("getData params :>> ", params);
+  let newParams: any = {};
+  params.pageNum && (newParams.pageindex = params.pageNum);
+  params.pageSize && (newParams.pagesize = params.pageSize);
+  delete params.pageNum;
+  delete params.pageSize;
+  newParams.queryParams = params;
+  console.log("params :>> ", params);
+  newParams.dsname = "web_mattress_mx_no";
+  return CommonDynamicSelect(newParams, DwnameEnum.mattressQuoteMxCushions);
+};
+/**↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
+
+/**
+ * @description tab 辅料
+ * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+ */
+
+const getData_bednet = (params: any) => {
+  console.log("getData params :>> ", params);
+  let newParams: any = {};
+  params.pageNum && (newParams.pageindex = params.pageNum);
+  params.pageSize && (newParams.pagesize = params.pageSize);
+  delete params.pageNum;
+  delete params.pageSize;
+  newParams.queryParams = params;
+  console.log("params :>> ", params);
+  newParams.dsname = "web_mattress_mx_bednet";
+  return CommonDynamicSelect(newParams, DwnameEnum.mattressQuoteMxAccessories);
+};
+/**↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
+
+/**
+ * @description tab 内布套
+ * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+ */
+
+const getData_innerClothLayer = (params: any) => {
+  console.log("getData params :>> ", params);
+  let newParams: any = {};
+  params.pageNum && (newParams.pageindex = params.pageNum);
+  params.pageSize && (newParams.pagesize = params.pageSize);
+  delete params.pageNum;
+  delete params.pageSize;
+  newParams.queryParams = params;
+  console.log("params :>> ", params);
+  newParams.dsname = "web_mattress_mx_neibutao";
+  return CommonDynamicSelect(newParams, DwnameEnum.mattressQuoteMxInnerClothLayer);
+};
+/**↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
 
 const detailProps = reactive<DetailProp>({
   dwname: DwnameEnum.mattressQuote,
   columns: columns,
   // headerstatus: ["status", "ifamt_ok"],
   basicDefault: {
-    basicGroup: [
-      {
-        label: "单据信息",
-        span: 1
-      },
-      {
-        label: "床垫信息",
-        span: 1
-      },
-      {
-        label: "报价信息",
-        span: 1
-      },
-      {
-        label: ""
-      }
-    ]
+    // basicGroup: [
+    //   {
+    //     label: "单据信息",
+    //     span: 1
+    //   },
+    //   {
+    //     label: "床垫信息",
+    //     span: 1
+    //   },
+    //   {
+    //     label: "报价信息",
+    //     span: 1
+    //   },
+    //   {
+    //     label: ""
+    //   }
+    // ]
   },
   header: {
     fieldNames: {
@@ -103,23 +338,68 @@ const detailProps = reactive<DetailProp>({
       name: "name"
     },
     // icon: "iconclipboard",
-    tabsProp: {
-      scrollspy: true,
-      sticky: true
-    }
+    // tabsProp: {
+    //   scrollspy: true,
+    //   sticky: true
+    // }
+    floatbtn: [
+      {
+        id: "oaFlow",
+        originLeft: 100,
+        originTop: 50
+      }
+    ]
   },
   mould: [
     {
-      id: "rpMustPayMxList",
+      id: "fabricMx",
+      type: "table",
+      label: t("business.detail.fabric")
+    },
+    {
+      id: "bednetMx",
+      type: "table",
+      label: t("business.detail.bednet")
+    },
+    {
+      id: "cushionsMx",
+      type: "table",
+      label: t("business.detail.cushions")
+    },
+    {
+      id: "accessoriesMx",
+      type: "table",
+      label: t("business.detail.accessories")
+    },
+    {
+      id: "packagMx",
+      type: "table",
+      label: t("business.detail.packag")
+    },
+    {
+      id: "innerClothLayerMx",
+      type: "table",
+      label: t("business.detail.innerClothLayer")
+      // limited: (params: any) => {
+      //   if (!params) return true;
+      //   return params?.if_n_butao == "0";
+      // }
+    },
+    {
+      id: "topCottonMx",
       type: "table",
-      label: t("business.takePay.mustPayMx")
+      label: t("business.detail.topCotton"),
+      limited: (params: any) => {
+        if (!params) return true;
+        return params?.if_w_butao == "0";
+      }
     }
   ]
 });
 
 const tableProps_mx = {
-  // height: "auto",
-  height: "",
+  height: "auto",
+  // height: "",
   minHeight: "300px",
   editConfig: { trigger: "click", mode: "cell" }
   // exportConfig: {
@@ -141,20 +421,6 @@ const getData = (params: any) => {
   // return [];
 };
 
-const getData_mx = (params: any) => {
-  console.log("getData params :>> ", params);
-  let newParams: any = {};
-  params.pageNum && (newParams.pageindex = params.pageNum);
-  params.pageSize && (newParams.pagesize = params.pageSize);
-  delete params.pageNum;
-  delete params.pageSize;
-  newParams.queryParams = params;
-  console.log("params :>> ", params);
-  newParams.dsname = "web_mattress_mx";
-  return CommonDynamicSelect(newParams, DwnameEnum.mattressQuoteMx);
-  // return [];
-};
-
 const dataCallback = (data: any) => {
   console.log("dataCallback data :>> ", data);
   return {
@@ -207,7 +473,7 @@ onMounted(async () => {
   if (route.query?.id) {
     // 赋值主表数据
     // mainData.value = res.datatable.length ? res.datatable[0] : {};
-    console.log("mainData.value :>> ", mainData.value);
+    // console.log("mainData.value :>> ", mainData.value);
     // 刷新数据
     initParams.value.arg_mattressid = Number(route.query?.id);
     console.log("detail onMounted initParams.value :>> ", initParams.value);
@@ -216,6 +482,171 @@ onMounted(async () => {
     //   mainData.value = props.data;
   }
 });
+
+const gotoOaFlow = async (timeout = 0) => {
+  console.log("LjDetailRef.value.mainData :>> ", LjDetailRef.value._mainData, summaryData.value);
+  let result = await calculateFormula(summaryData.value, fieldParams.value, LjDetailRef.value._mainData);
+  if (result.length) {
+    let _data = cloneDeep(LjDetailRef.value._mainData);
+    result.map((t, i) => {
+      _data[t.field] = t.value;
+    });
+    console.log("_data :>> ", _data, result);
+    toast.clear();
+    toast(
+      {
+        component: ToastFormula,
+        props: {
+          t: t,
+          formulas: summaryData.value,
+          data: _data,
+          fields: fieldParams.value,
+          showFormula: showFormula.value
+        },
+        listeners: {
+          toggleFormula: (data: any) => {
+            showFormula.value = data;
+            console.log("showFormula.value :>> ", showFormula.value);
+          },
+          refresh: () => {
+            gotoOaFlow();
+          }
+        }
+      },
+      {
+        position: POSITION.BOTTOM_RIGHT,
+        icon: false,
+        timeout: timeout,
+        closeButton: false,
+        toastClassName: "longjoe-toast"
+      }
+    );
+  } else {
+    ElMessage.error("计算公式有误");
+  }
+};
+
+/**
+ * @description 流转状况悬浮按钮参数
+ */
+const oaFlowFloadProp = ref<any>({
+  id: "oaFlow",
+  click: gotoOaFlow
+});
+
+/**
+ * @description 详情页是否加载完成
+ */
+const ifAfterMound = ref(false);
+/**
+ * @description 页面数据加载完成
+ */
+const funcAfterMound = async () => {
+  console.log("onMounted detail sale start!!!! :>> ");
+  // console.log("LjDetailRef.value.currentMould :>> ", LjDetailRef.value.currentMould);
+  // console.log(
+  //   "Boolean(Number(CheckOption(sysOptionEnum.sys_option_043))) :>> ",
+  //   Boolean(Number(CheckOption(sysOptionEnum.sys_option_043)))
+  // );
+  // // 流转状况
+  // if (Boolean(Number(CheckOption(sysOptionEnum.sys_option_043))) && LjDetailRef.value.currentMould.header.floatbtn) {
+  let _oaflowbtn = LjDetailRef.value.currentMould.header.floatbtn.find((itm: any) => itm.id == "oaFlow");
+  if (_oaflowbtn) {
+    _oaflowbtn.originLeft && (oaFlowFloadProp.value.originLeft = _oaflowbtn.originLeft);
+    _oaflowbtn.originTop && (oaFlowFloadProp.value.originTop = _oaflowbtn.originTop);
+  }
+  // oaFlowFloadProp.value.change = LjDetailRef.value.toSetFloatBtnChange;
+
+  //   if (!ALLOW_EDIT_STATE.includes(orderStatus.value)) {
+  //     // 非新增、修改时执行
+  //     getOaFlowList(initParams.value.scid, initParams.value.taskid).then(() => {
+  //       if (oaFlowList.value.length) {
+  //         gotoOaFlow();
+  //       }
+  //     });
+  //   }
+  // }
+
+  // if (ALLOW_EDIT_STATE.includes(orderStatus.value)) {
+  //   saleTaskMx_tableProps.value.editConfig.enabled = true;
+  // }
+  // if (orderStatus.value == "new") {
+  //   nextTick(async () => {
+  //     console.log("SaletaskmxListRef.value onmound new:>> ", SaletaskmxListRef.value);
+  //     if (SaletaskmxListRef.value) {
+  //       const $table = SaletaskmxListRef.value.element;
+  //       if ($table) {
+  //         const record = {};
+  //         const { row: newRow } = await $table.insertAt(record, null);
+  //         await $table.setEditCell(newRow, "mtrlcode");
+  //         console.log("onMounted saletask finish :>> ", $table);
+  //       }
+  //     }
+  //   });
+  // }
+  if (!orderStatus.value) {
+    gotoOaFlow(8000);
+  }
+  ifAfterMound.value = true;
+
+  console.log("onMounted detail sale start LjDetailRef.value.mainData :>> ", LjDetailRef.value);
+
+  const { enumMap, _mainData } = LjDetailRef.value;
+  console.log("enumMap :>> ", enumMap, _mainData);
+  mattresstypeEnum.value = enumMap.get("mattresstypeid").find(t => t.value == _mainData.mattresstypeid);
+  console.log("mattresstypeEnum :>> ", mattresstypeEnum);
+
+  let itmshow = fabricMxTabList.value.find(t => t.visible());
+  fabricMxTabs.value = itmshow.name;
+
+  let res = await getData_mx(initParams.value);
+  fabricMxResData.value = dataCallback(res);
+  console.log("fabricMxRef.value :>> ", fabricMxRef.value);
+  funcGetFabricMxShowData(itmshow.name);
+  console.log("funcAfterMound resData :>> ", fabricMxData.value);
+};
+
+const funcGetFabricMxShowData = (tabname: string) => {
+  let item = fabricMxTabList.value.find(t => t.name == tabname);
+
+  fabricMxData.value = fabricMxResData.value.list.filter(t => item.type.includes(Number(t.formulakind)));
+  fabricMxRef.value.refresh();
+};
+
+const handleFabricMxTabsClick = (pane: any, val: any) => {
+  console.log("handleFabricMxTabsClick pane :>> ", pane.paneName);
+  console.log("handleFabricMxTabsClick val :>> ", val);
+  const $table = fabricMxRef.value.element;
+  const column = $table.getColumnByField("formulakind");
+  console.log("column :>> ", column);
+  console.log("column.filters :>> ", column.filters);
+  console.log("props.enum :>> ", column.filterRender.props.enum);
+
+  funcGetFabricMxShowData(pane.paneName);
+
+  // switch (pane.paneName) {
+  //   case 'tabpage_8':
+  //   LjDetailRef.value.element.setFilter('formulakind', )
+  //     break;
+  //   case 'tabpage_9':
+
+  //     break;
+  //   case 'tabpage_10':
+
+  //     break;
+  //   case 'tabpage_11':
+
+  //     break;
+  //   case 'tabpage_12':
+
+  //     break;
+  //   case 'tabpage_13':
+
+  //     break;
+  //   default:
+  //     break;
+  // }
+};
 </script>
 
 <style lang="scss">

+ 343 - 7
JLHWEB/src/views/quote/mattressQuote/hooks/index.tsx

@@ -2,12 +2,15 @@ import { ref, reactive, computed, toRefs } from "vue";
 import { Table } from "@/hooks/interface";
 import { ColumnProps } from "@/components/LjVxeTable/interface";
 import { ALLOW_EDIT_STATE } from "@/config/index";
+import { CommonDynamicSelect } from "@/api/modules/common";
+import { useUserStore } from "@/stores/modules/user";
 
 interface defaultState {
   /**
    * @description 单据当前状态
    */
   orderStatus: string;
+  LjDetailRef: any;
 }
 /**
  * @description 表格多选数据操作
@@ -15,11 +18,27 @@ interface defaultState {
  * */
 export const useHooks = (t?: any) => {
   const state = reactive<defaultState>({
-    orderStatus: ""
+    orderStatus: "",
+    LjDetailRef: ""
   });
 
-  const fnMoneyrateChange = (val: any) => {
-    console.log("fnMoneyrateChange val :>> ", val);
+  const funcMoneyrateChange = async (val: any, data) => {
+    let newParams = {
+      dsname: "_Mapper_deptid",
+      queryparams: {
+        arg_deptid: data.deptid
+      }
+    };
+    let res = await CommonDynamicSelect(newParams);
+
+    let _discount = 1;
+    let _moneyrate = 1;
+    if (res.datatable?.length > 0) {
+      _discount = res.datatable[0].discount;
+      _moneyrate = res.datatable[0].moneyrate;
+    }
+    data.moneyrate = _moneyrate;
+    data.discount = _discount;
   };
 
   // 表格配置项
@@ -128,7 +147,7 @@ export const useHooks = (t?: any) => {
               v-model={scope.searchParam.if_moneyrate}
               v-slots={slotprefix}
               class="select-text-right"
-              onChange={fnMoneyrateChange}
+              onChange={val => funcMoneyrateChange(val, scope.searchParam)}
             >
               {optionRender}
             </el-select>
@@ -141,16 +160,333 @@ export const useHooks = (t?: any) => {
       table: "u_mattress",
       title: "外币价",
       basicinfo: {
-        titleKey: "foreign_cost"
+        titleKey: "bi_foreign_cost"
+      }
+    },
+    {
+      field: "nottax_dept_cost",
+      table: "u_mattress",
+      title: "部门不含税价",
+      basicinfo: {
+        titleKey: "bi_nottax_dept_cost"
+      }
+    },
+    {
+      field: "if_bcp_type",
+      title: "半成品",
+      basicinfo: {
+        labelHidden: true,
+        render: (scope: any) => {
+          return (
+            <>
+              <el-checkbox v-model={scope.searchParam.if_bcp_type} label="半成品" class="mr-8" />
+              <el-checkbox v-model={scope.searchParam.if_zhedie_type} label="折叠款" />
+            </>
+          );
+        }
+      }
+    },
+    {
+      field: "if_m_chai",
+      title: "面拆",
+      basicinfo: {
+        labelHidden: true,
+        render: (scope: any) => {
+          return (
+            <>
+              <el-checkbox v-model={scope.searchParam.if_m_chai} label="面拆" class="mr-8" />
+              <el-checkbox v-model={scope.searchParam.if_z_chai} label="中拆" class="mr-8" />
+              <el-checkbox v-model={scope.searchParam.if_d_chai} label="底拆" />
+            </>
+          );
+        }
       }
     }
   ];
 
-  const columnsMx: ColumnProps<any>[] = [];
+  const columnsMx: ColumnProps<any>[] = [
+    { title: "#", type: "seq", fixed: "left", width: 80 },
+    {
+      title: "计算成功?",
+      field: "if_success",
+      datatype: "checkbox"
+    },
+    {
+      title: "+",
+      field: "addmx",
+      width: 80
+    },
+    {
+      title: "-",
+      field: "delmx",
+      width: 80
+    },
+    {
+      title: "位置",
+      field: "chastr"
+    },
+    {
+      title: "公式名",
+      field: "formulakind",
+      table: "u_mattress_formula"
+    },
+    {
+      title: "按物料?",
+      field: "if_mtrl",
+      table: "u_mattress_formula"
+    },
+    {
+      title: "厚度cm",
+      field: "thickness"
+    },
+    {
+      title: "物料",
+      field: "mtrlid"
+    },
+    {
+      title: "数量/长度",
+      field: "qty"
+    },
+    {
+      title: "物料单价",
+      field: "price"
+    },
+    {
+      title: "单位",
+      field: "priceunit"
+    },
+    {
+      title: "收缩率",
+      field: "shrinkage"
+    },
+    {
+      title: "克重",
+      field: "gram_weight"
+    },
+    {
+      title: "幅宽",
+      field: "cloth_width"
+    },
+    {
+      title: "固定厚度?",
+      field: "if_inputqty"
+    },
+    {
+      title: "按面积单价?",
+      field: "if_areaprice"
+    },
+    {
+      title: "成本金额",
+      field: "costamt"
+    },
+    {
+      title: "金额文本公式",
+      field: "formula"
+    },
+    {
+      title: "金额数字公式",
+      field: "replace_formula"
+    },
+    {
+      title: "清单用量",
+      field: "useqty"
+    },
+    {
+      title: "用量文本公式",
+      field: "useformula"
+    },
+    {
+      title: "用量数字公式",
+      field: "replace_useformula"
+    },
+    {
+      title: "工艺填写说明",
+      field: "gydscrp"
+    }
+  ];
+
+  const summaryData = ref<any>([
+    {
+      label: "总成本",
+      field: "total_cost",
+      formula:
+        "if([折叠款] = 1, ([总材料成本]*[大小单]+[款式费用]+[边带费用]+[额外费用]+[制造费用]) * 2, [总材料成本]*[大小单]+[款式费用]+[边带费用]+[额外费用]+[制造费用])",
+      power: () => {
+        const { userInfo } = useUserStore();
+        if (userInfo.empid != 0 && userInfo.usermode != 0) {
+          return false;
+        } else {
+          return true;
+        }
+      }
+    },
+    {
+      label: "不含税出厂价",
+      field: "nottax_factory_cost",
+      formula: "[总成本] * ([工厂利润率] + [利润率点数] + [布套点数] + [拆装点数] + [海绵点数]) * [管理费点]"
+    },
+    {
+      label: "部门售价",
+      field: "nottax_dept_cost",
+      formula: "[dijia_cost] / (1 - ([佣金点数] - 1)) * [额外点数] + [fob]"
+    },
+    {
+      label: "税金",
+      field: "taxes",
+      formula: "([部门售价] * ([税率] - 1)) + [佣金] * 0.05"
+    },
+    {
+      label: "部门含税价",
+      field: "dept_cost",
+      formula: "([部门售价] + [佣金] * 0.06) * [税率] * if([fob] = 0, 1, [折扣率])"
+    },
+    {
+      label: "外币价",
+      field: "foreign_cost",
+      formula: "if([汇率] <> 0, [部门含税价] / [汇率], 0)"
+    },
+    {
+      label: "底价 ",
+      field: "dijia_cost_cp",
+      formula: "if(([dept_profitrate] + [dept_profitrate_rangli] / 100) <> 0, [dijia_cost] ,0 )"
+    },
+    {
+      label: "佣金",
+      field: "commission_cp",
+      formula: "[dijia_cost] / (1 - ([佣金点数] - 1 )) - [dijia_cost]"
+    },
+    {
+      label: "FOB",
+      field: "fob",
+      formula: "[fob]"
+    }
+  ]);
+
+  const fieldParams = ref<any>([
+    {
+      label: "总成本",
+      field: "total_cost"
+    },
+    {
+      label: "不含税出厂价",
+      field: "nottax_factory_cost"
+    },
+    {
+      label: "部门售价",
+      field: "nottax_dept_cost"
+    },
+    {
+      label: "税金",
+      field: "taxes"
+    },
+    {
+      label: "部门含税价",
+      field: "dept_cost"
+    },
+    {
+      label: "外币价",
+      field: "foreign_cost"
+    },
+    {
+      label: "总材料成本",
+      field: "total_material_cost"
+    },
+    {
+      label: "大小单",
+      field: "dannum_rate"
+    },
+    {
+      label: "款式费用",
+      field: "hrcost"
+    },
+    {
+      label: "边带费用",
+      field: "biandaicost"
+    },
+    {
+      label: "额外费用",
+      field: "extras_cost"
+    },
+    {
+      label: "制造费用",
+      field: "zhizao_amt"
+    },
+    {
+      label: "折叠款",
+      field: "if_zhedie_type"
+    },
+    {
+      label: "管理费点",
+      field: "guanli_rate"
+    },
+    {
+      label: "工厂利润率",
+      field: "profitrate"
+    },
+    {
+      label: "利润率点数",
+      field: "profitrate_point"
+    },
+    {
+      label: "布套点数",
+      field: "butao_point"
+    },
+    {
+      label: "拆装点数",
+      field: "chaizhuang_point"
+    },
+    {
+      label: "海绵点数",
+      field: "haimian_point"
+    },
+    {
+      label: "部门利润率",
+      field: "dept_profitrate"
+    },
+    {
+      label: "部门让利点",
+      field: "dept_profitrate_rangli"
+    },
+    {
+      label: "额外点数",
+      field: "other_rate"
+    },
+    {
+      label: "佣金点数",
+      field: "commission"
+    },
+    {
+      label: "税率",
+      field: "taxrate"
+    },
+    {
+      label: "折扣率",
+      field: "discount"
+    },
+    {
+      label: "汇率",
+      field: "moneyrate"
+    },
+    {
+      label: "底价",
+      field: "dijia_cost"
+    }
+  ]);
+
+  const columnsMxBednet: ColumnProps<any>[] = [];
+  const columnsMxCushions: ColumnProps<any>[] = [];
+  const columnsMxAccessories: ColumnProps<any>[] = [];
+  const columnsMxInnerClothLayer: ColumnProps<any>[] = [];
 
   return {
     ...toRefs(state),
     columns,
-    columnsMx
+    columnsMx,
+    columnsMxBednet,
+    columnsMxCushions,
+    columnsMxAccessories,
+    columnsMxInnerClothLayer,
+    summaryData,
+    fieldParams
   };
 };

+ 5 - 6
JLHWEB/src/views/saleprice/dept/hooks/index.tsx

@@ -107,7 +107,6 @@ export const useHooks = (t?: any) => {
       field: "if_rate_auto",
       title: "是否自动读取汇率",
       datatype: "checkbox",
-      editHidden: true,
       basicinfo: {
         el: "switch",
         editable: ALLOW_EDIT_STATE
@@ -117,35 +116,35 @@ export const useHooks = (t?: any) => {
       field: "createtime",
       title: "建立时间",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "modemp",
       title: "修改人",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "moddate",
       title: "修改时间",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "auditemp",
       title: "审核人",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "audidate",
       title: "审核时间",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {

+ 6 - 6
JLHWEB/src/views/saleprice/pricelist/hooks/index.tsx

@@ -45,7 +45,7 @@ export const useHooks = (t?: any) => {
       field: "createtime",
       title: "建立时间",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
@@ -53,35 +53,35 @@ export const useHooks = (t?: any) => {
       title: "审核",
       datatype: "checkbox",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "modemp",
       title: "修改人",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "moddate",
       title: "修改时间",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "auditemp",
       title: "审核人",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     },
     {
       field: "audidate",
       title: "审核时间",
       basicinfo: {
-        disabled: true
+        visible: false
       }
     }
   ];