From b44addf784a1638bac1102799ed415645a373a55 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期四, 21 五月 2026 14:29:30 +0800
Subject: [PATCH] 转正申请/调岗申请/工作交接/请假申请/加班申请页面画页面,接口联调和web端保持一致 日报

---
 src/pages/oa/ApproveManage/approve-list/template-select.vue |  146 ++++++++++++++++++++++++++++++++++++------------
 1 files changed, 108 insertions(+), 38 deletions(-)

diff --git a/src/pages/oa/ApproveManage/approve-list/template-select.vue b/src/pages/oa/ApproveManage/approve-list/template-select.vue
index 628483b..073b556 100644
--- a/src/pages/oa/ApproveManage/approve-list/template-select.vue
+++ b/src/pages/oa/ApproveManage/approve-list/template-select.vue
@@ -5,10 +5,10 @@
 -->
 <template>
   <view class="template-select-page sales-account">
-    <PageHeader title="閫夋嫨瀹℃壒妯℃澘"
+    <PageHeader :title="pageHeaderTitle"
                 @back="goBack" />
 
-    <view v-if="typeOptions.length"
+    <view v-if="typeOptions.length && !moduleKey"
           class="step-section">
       <view class="tabs-wrap">
         <up-tabs :list="tabList"
@@ -16,6 +16,11 @@
                  line-color="#2979ff"
                  @click="onTabClick" />
       </view>
+    </view>
+
+    <view v-if="useAllTemplatesFallback && allTemplates.length"
+          class="fallback-hint">
+      <text>褰撳墠绫诲瀷涓嬫棤鍖归厤妯℃澘锛屽凡鏄剧ず鍏ㄩ儴 {{ allTemplates.length }} 涓彲鐢ㄦā鏉�</text>
     </view>
 
     <view class="search-section">
@@ -41,11 +46,6 @@
             class="loading-wrap">
         <up-loading-icon mode="circle" />
         <text class="loading-text">鍔犺浇涓�...</text>
-      </view>
-      <view v-else-if="!typeOptions.length"
-            class="empty-wrap">
-        <up-empty mode="list"
-                  text="鏈幏鍙栧埌瀹℃壒绫诲瀷" />
       </view>
       <view v-else-if="displayList.length"
             class="ledger-list">
@@ -95,17 +95,25 @@
   import { computed, ref } from "vue";
   import { onLoad } from "@dcloudio/uni-app";
   import PageHeader from "@/components/PageHeader.vue";
-  import { listApprovalTemplateByType } from "@/api/oa/approvalTemplate.js";
   import { OA_NAV } from "@/config/oaPaths.js";
   import {
     buildTypeLabelMap,
-    CUSTOM_TEMPLATE_LIST_TYPE,
     fetchApprovalTemplateTypes,
+    buildTypeOptionsFromTemplates,
+    FALLBACK_BUSINESS_TYPE_OPTIONS,
+    fetchEnabledApprovalTemplates,
     filterTemplatesByBusinessType,
+    filterTemplatesByBusinessTypes,
     getBusinessTypeLabel,
-    getDefaultTypeTabIndex,
+    pickTabIndexWithTemplates,
   } from "../../_utils/approvalTemplateType.js";
+  import {
+    getApprovalModuleConfig,
+    getModuleMatchingBusinessTypes,
+    resolveModuleBusinessType,
+  } from "../../_utils/approvalModuleRegistry.js";
 
+  const moduleKey = ref("");
   const typeOptions = ref([]);
   const typeLabelMap = ref({});
   /** 鍏ㄩ儴鑷畾涔夊凡鍚敤妯℃澘锛坙ist/1 涓�娆℃媺鍙栵級 */
@@ -118,9 +126,45 @@
     typeOptions.value.map(opt => ({ name: opt.name }))
   );
 
+  const moduleConfig = computed(() =>
+    moduleKey.value ? getApprovalModuleConfig(moduleKey.value) : null
+  );
+
+  const pageHeaderTitle = computed(() => {
+    if (moduleConfig.value?.label) {
+      return `閫夋嫨${moduleConfig.value.label}妯℃澘`;
+    }
+    return "閫夋嫨瀹℃壒妯℃澘";
+  });
+
+  const moduleBusinessTypes = computed(() => {
+    if (!moduleKey.value) return [];
+    return getModuleMatchingBusinessTypes(moduleKey.value, typeOptions.value);
+  });
+
   const currentTypeOption = computed(() => typeOptions.value[activeTab.value]);
 
+  /** 鏃� moduleKey 涓斿綋鍓� Tab 绛涗笉鍒版椂锛屽睍绀哄叏閮ㄦā鏉块伩鍏嶃�屾湁鏁版嵁鍗寸┖鐧姐�� */
+  const useAllTemplatesFallback = computed(() => {
+    if (moduleKey.value) return false;
+    if (!allTemplates.value.length) return false;
+    const businessType = currentTypeOption.value?.value;
+    if (businessType == null || businessType === "") return true;
+    return filterTemplatesByBusinessType(allTemplates.value, businessType).length === 0;
+  });
+
   const currentSource = computed(() => {
+    if (moduleKey.value && moduleBusinessTypes.value.length) {
+      const filtered = filterTemplatesByBusinessTypes(
+        allTemplates.value,
+        moduleBusinessTypes.value
+      );
+      if (filtered.length) return filtered;
+      return allTemplates.value;
+    }
+    if (useAllTemplatesFallback.value) {
+      return allTemplates.value;
+    }
     const businessType = currentTypeOption.value?.value;
     return filterTemplatesByBusinessType(allTemplates.value, businessType);
   });
@@ -134,8 +178,17 @@
   });
 
   const emptyText = computed(() => {
+    if (allTemplates.value.length === 0) {
+      return "鏆傛棤宸插惎鐢ㄧ殑瀹℃壒妯℃澘锛岃鍏堝湪銆屽鎵规ā鏉裤�嶄腑鍒涘缓骞跺惎鐢�";
+    }
+    if (moduleConfig.value?.label) {
+      return `鏆傛棤${moduleConfig.value.label}鍙敤妯℃澘`;
+    }
+    if (useAllTemplatesFallback.value) {
+      return "褰撳墠绫诲瀷涓嬫棤鍖归厤妯℃澘";
+    }
     const typeName = currentTypeOption.value?.name || "璇ュ鎵圭被鍨�";
-    return `鏆傛棤${typeName}涓嬬殑妯℃澘`;
+    return `鏆傛棤${typeName}涓嬬殑妯℃澘锛堝彲鍒囨崲涓婃柟绫诲瀷锛塦;
   });
 
   const businessTypeText = type =>
@@ -160,41 +213,46 @@
     return count != null ? `${count} 涓猔 : "-";
   };
 
-  const normalizeList = data => {
-    const list = Array.isArray(data)
-      ? data
-      : Array.isArray(data?.records)
-        ? data.records
-        : [];
-    return list.filter(item => String(item?.enabled ?? "1") === "1");
-  };
-
-  const loadCustomTemplates = () =>
-    listApprovalTemplateByType(CUSTOM_TEMPLATE_LIST_TYPE)
-      .then(res => {
-        allTemplates.value = normalizeList(res?.data);
-      })
-      .catch(() => {
-        allTemplates.value = [];
-        uni.showToast({ title: "鍔犺浇妯℃澘鍒楄〃澶辫触", icon: "none" });
-      });
-
   const initPage = async () => {
     loading.value = true;
     keyword.value = "";
     allTemplates.value = [];
     try {
-      const [opts] = await Promise.all([
+      const [opts, templates] = await Promise.all([
         fetchApprovalTemplateTypes(),
-        loadCustomTemplates(),
+        fetchEnabledApprovalTemplates(),
       ]);
-      typeOptions.value = opts;
-      typeLabelMap.value = buildTypeLabelMap(opts);
-      activeTab.value = getDefaultTypeTabIndex(opts);
+      let resolvedOpts = opts?.length ? opts : buildTypeOptionsFromTemplates(templates);
+      if (!resolvedOpts.length) {
+        resolvedOpts = [...FALLBACK_BUSINESS_TYPE_OPTIONS];
+      }
+      typeOptions.value = resolvedOpts;
+      typeLabelMap.value = buildTypeLabelMap(resolvedOpts);
+      allTemplates.value = templates;
+
+      if (!templates.length) {
+        uni.showToast({
+          title: "鏈幏鍙栧埌宸插惎鐢ㄦā鏉�",
+          icon: "none",
+          duration: 2500,
+        });
+      }
+
+      if (moduleKey.value) {
+        const resolved = resolveModuleBusinessType(moduleKey.value, opts);
+        const idx = opts.findIndex(
+          opt => String(opt.value) === String(resolved)
+        );
+        activeTab.value =
+          idx >= 0 ? idx : pickTabIndexWithTemplates(resolvedOpts, templates);
+      } else {
+        activeTab.value = pickTabIndexWithTemplates(resolvedOpts, templates);
+      }
     } catch {
       typeOptions.value = [];
       typeLabelMap.value = {};
-      uni.showToast({ title: "鑾峰彇瀹℃壒绫诲瀷澶辫触", icon: "none" });
+      allTemplates.value = [];
+      uni.showToast({ title: "鍔犺浇妯℃澘澶辫触", icon: "none" });
     } finally {
       loading.value = false;
     }
@@ -215,12 +273,14 @@
       uni.showToast({ title: "璇ユā鏉垮凡鍋滅敤", icon: "none" });
       return;
     }
+    const base = `${OA_NAV.approveListApply}?templateId=${item.id}`;
     uni.navigateTo({
-      url: `${OA_NAV.approveListApply}?templateId=${item.id}`,
+      url: moduleKey.value ? `${base}&moduleKey=${moduleKey.value}` : base,
     });
   };
 
-  onLoad(() => {
+  onLoad(options => {
+    moduleKey.value = options?.moduleKey || "";
     initPage();
   });
 </script>
@@ -234,6 +294,16 @@
     min-height: 100vh;
   }
 
+  .fallback-hint {
+    margin: 8px 12px 0;
+    padding: 8px 12px;
+    font-size: 12px;
+    color: #e6a23c;
+    background: #fdf6ec;
+    border-radius: 6px;
+    line-height: 1.5;
+  }
+
   .step-section {
     background: #fff;
     border-bottom: 1px solid #f0f0f0;

--
Gitblit v1.9.3