From 7c2cdcbc7f5585b96fba76a07b0e4417a09c4d7e Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 02 六月 2026 11:06:10 +0800
Subject: [PATCH] 新疆马铃薯 1.过程检验下载添加3个模版
---
src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 347 insertions(+), 0 deletions(-)
diff --git a/src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue b/src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue
new file mode 100644
index 0000000..f731d57
--- /dev/null
+++ b/src/views/officeProcessAutomation/HrManage/transfer-apply/index.vue
@@ -0,0 +1,347 @@
+<!--OA妯″潡锛氳皟宀楃敵璇�-->
+<template>
+ <div class="app-container">
+ <div class="search_form mb20">
+ <div>
+ <span class="search_title">瀹℃壒鍗曞彿锛�</span>
+ <el-input
+ v-model="searchForm.instanceNo"
+ style="width: 220px"
+ placeholder="璇疯緭鍏ュ鎵瑰崟鍙�"
+ clearable
+ @keyup.enter="onSearch"
+ />
+ <span class="search_title" style="margin-left: 12px">鐢宠浜猴細</span>
+ <el-select
+ v-model="searchForm.applicantId"
+ filterable
+ remote
+ clearable
+ reserve-keyword
+ placeholder="璇烽�夋嫨鎴栨悳绱㈢敵璇蜂汉"
+ style="width: 220px"
+ :remote-method="remoteSearchApplicant"
+ :loading="applicantSearchLoading"
+ >
+ <el-option
+ v-for="u in applicantSearchOptions"
+ :key="u.userId"
+ :label="userSelectLabel(u)"
+ :value="u.userId"
+ />
+ </el-select>
+ <el-button type="primary" style="margin-left: 10px" @click="onSearch">鎼滅储</el-button>
+ <el-button @click="resetSearch">閲嶇疆</el-button>
+ </div>
+ <div>
+ <el-button type="primary" @click="openAddWithTemplate">鏂板璋冨矖鐢宠</el-button>
+ </div>
+ </div>
+ <div class="table_list">
+ <PIMTable
+ rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="false"
+ :tableLoading="tableLoading"
+ @pagination="onPagination"
+ :total="page.total"
+ />
+ </div>
+
+ <ApprovalInstanceSubmitDialog
+ v-model="submitDialog.visible"
+ :title="submitDialogTitle"
+ :form="submitForm"
+ :rules="submitFormRules"
+ :fields="submitFormFields"
+ :active-template="activeTemplate"
+ :user-options="flowUserOptions"
+ :is-edit="isSubmitEdit"
+ :saving="submitSaving"
+ :form-ref="submitFormRef"
+ flow-attachments-only
+ @submit="onSubmit"
+ >
+ <template #before="{ form, fields }">
+ <FormPayloadFields :fields="displayTemplateFields(fields)" :form-payload="form.formPayload" />
+ <el-form-item label="鍘熷矖浣�">
+ <el-input :model-value="originalPostName" placeholder="閫夋嫨鐢宠浜哄悗鑷姩甯﹀嚭" disabled />
+ </el-form-item>
+ </template>
+ </ApprovalInstanceSubmitDialog>
+
+ <ApprovalTemplateBindDialog
+ v-model:visible="templateBindVisible"
+ :module-key="APPROVAL_MODULE_KEYS.TRANSFER"
+ skip-form-confirm
+ @confirm="onTemplateBound"
+ @closed="onTemplateBindClosed"
+ />
+
+ <ApprovalInstanceDetailDialog
+ v-model="detailDialog.visible"
+ title="璋冨矖鐢宠璇︽儏"
+ :row="detailRow"
+ @edit="openEditFromDetail"
+ />
+ </div>
+</template>
+
+<script setup>
+import { findPostOptions } from "@/api/system/post.js";
+import { userListNoPageByTenantId } from "@/api/system/user.js";
+import { ElMessage } from "element-plus";
+import { computed, onMounted, reactive, ref, watch } from "vue";
+import FormPayloadFields from "../../ApproveManage/approve-list/components/FormPayloadFields.vue";
+import ApprovalInstanceDetailDialog from "../../ApproveManage/approve-shared/components/ApprovalInstanceDetailDialog.vue";
+import ApprovalInstanceSubmitDialog from "../../ApproveManage/approve-shared/components/ApprovalInstanceSubmitDialog.vue";
+import ApprovalTemplateBindDialog from "../../ApproveManage/approve-shared/components/ApprovalTemplateBindDialog.vue";
+import { buildInstanceTableColumns } from "../../ApproveManage/approve-shared/approvalInstanceFormConfigTable.js";
+import { APPROVAL_MODULE_KEYS } from "../../ApproveManage/approve-shared/approvalModuleRegistry.js";
+import { useApprovalInstanceModule } from "../../ApproveManage/approve-shared/useApprovalInstanceModule.js";
+import { useFlowUserOptions } from "../../ApproveManage/approve-shared/useFlowUserOptions.js";
+import { SELECT_OPTION_SOURCE } from "../../ApproveManage/approve-template/selectOptionSource.js";
+
+function isOriginalPostField(field) {
+ const label = String(field?.label || "");
+ return (
+ label.includes("鍘熷矖浣�") ||
+ field?.key === "originalPost" ||
+ field?.key === "originalPostName" ||
+ field?.key === "originalPostId"
+ );
+}
+
+function displayTemplateFields(fields = []) {
+ return (fields || []).filter((f) => !isOriginalPostField(f));
+}
+
+function findApplicantTemplateField(fields = []) {
+ return (
+ fields.find((f) => String(f?.label || "").includes("鐢宠浜�")) ||
+ fields.find((f) => f?.type === "select" && f?.optionSource === SELECT_OPTION_SOURCE.USER) ||
+ null
+ );
+}
+
+const searchForm = reactive({
+ instanceNo: "",
+ applicantId: "",
+});
+
+const mod = useApprovalInstanceModule({
+ moduleKey: APPROVAL_MODULE_KEYS.TRANSFER,
+});
+
+const {
+ tableData,
+ tableLoading,
+ page,
+ detailDialog,
+ detailRow,
+ submitDialog,
+ submitForm,
+ submitFormRef,
+ submitSaving,
+ isSubmitEdit,
+ activeTemplate,
+ submitFormFields,
+ submitFormRules,
+ submitDialogTitle,
+ templateBindVisible,
+ handleQuery,
+ initModuleList,
+ pagination,
+ openAddWithTemplate,
+ onTemplateBound,
+ onTemplateBindClosed,
+ openEditFromDetail,
+ submitInstanceForm,
+ buildTableActions,
+} = mod;
+
+const { flowUserOptions, loadFlowUsers } = useFlowUserOptions();
+
+const allUsersCache = ref([]);
+const postIdToName = ref({});
+const targetPostOptions = ref([]);
+const applicantSearchLoading = ref(false);
+const applicantSearchOptions = ref([]);
+const originalPostName = ref("");
+
+const applicantTemplateField = computed(() =>
+ findApplicantTemplateField(submitForm.formFieldDefs)
+);
+
+function unwrapArray(payload) {
+ if (Array.isArray(payload)) return payload;
+ if (payload && Array.isArray(payload.data)) return payload.data;
+ if (payload && Array.isArray(payload.rows)) return payload.rows;
+ return [];
+}
+
+function isActiveUser(u) {
+ if (u.delFlag === "2" || u.delFlag === 2) return false;
+ if (u.status == null) return true;
+ return String(u.status) === "0";
+}
+
+function userSelectLabel(u) {
+ const nick = u.nickName || "";
+ const name = u.userName || "";
+ if (nick && name && nick !== name) return `${nick}锛�${name}锛塦;
+ return nick || name || `鐢ㄦ埛${u.userId ?? u.id ?? ""}`;
+}
+
+function firstPostId(user) {
+ if (!user) return undefined;
+ if (Array.isArray(user.postIds) && user.postIds.length) return user.postIds[0];
+ if (user.postId != null && user.postId !== "") return user.postId;
+ return undefined;
+}
+
+function resolveOriginalPost(user) {
+ if (!user) return { originalPostName: "" };
+ const nameStr = (user.postName ?? user.postname ?? "").toString().trim();
+ if (nameStr) return { originalPostName: nameStr };
+ if (Array.isArray(user.posts) && user.posts.length) {
+ return { originalPostName: (user.posts[0].postName ?? "").toString() || "鏈懡鍚嶅矖浣�" };
+ }
+ const pid = firstPostId(user);
+ if (pid != null && pid !== "") {
+ const n = postIdToName.value[String(pid)] || "";
+ return { originalPostName: n || "褰撳墠宀椾綅锛堟湭鍦ㄥ矖浣嶅瓧鍏镐腑锛�" };
+ }
+ return { originalPostName: "鏈垎閰嶅矖浣�" };
+}
+
+function userById(id) {
+ if (id == null || id === "") return undefined;
+ return allUsersCache.value.find((u) => String(u.userId ?? u.id) === String(id));
+}
+
+function filterUsersByQuery(query) {
+ const list = allUsersCache.value.filter((u) => isActiveUser(u));
+ const q = (query || "").trim().toLowerCase();
+ if (!q) return [...list];
+ return list.filter((u) => {
+ const nick = (u.nickName || "").toLowerCase();
+ const uname = (u.userName || "").toLowerCase();
+ const phone = (u.phonenumber || u.phone || "").toString();
+ return nick.includes(q) || uname.includes(q) || phone.includes(q);
+ });
+}
+
+async function loadUserPool() {
+ try {
+ const res = await userListNoPageByTenantId();
+ allUsersCache.value = unwrapArray(res);
+ } catch {
+ allUsersCache.value = [];
+ }
+}
+
+async function loadPostOptions() {
+ try {
+ const res = await findPostOptions();
+ const rows = res.data ?? res.rows ?? [];
+ targetPostOptions.value = Array.isArray(rows) ? rows : [];
+ } catch {
+ targetPostOptions.value = [];
+ }
+ const m = {};
+ for (const p of targetPostOptions.value) {
+ const id = p.postId ?? p.value ?? p.id;
+ if (id != null && id !== "") m[String(id)] = p.postName ?? p.label ?? "";
+ }
+ postIdToName.value = m;
+}
+
+async function remoteSearchApplicant(query) {
+ applicantSearchLoading.value = true;
+ try {
+ if (!allUsersCache.value.length) await loadUserPool();
+ applicantSearchOptions.value = filterUsersByQuery(query);
+ } finally {
+ applicantSearchLoading.value = false;
+ }
+}
+
+function syncOriginalPostFromApplicant(uid) {
+ const u = userById(uid);
+ originalPostName.value = resolveOriginalPost(u).originalPostName;
+}
+
+watch(
+ () => {
+ const key = applicantTemplateField.value?.key;
+ return key ? submitForm.formPayload[key] : undefined;
+ },
+ async (uid) => {
+ if (!applicantTemplateField.value) return;
+ if (!allUsersCache.value.length) await loadUserPool();
+ syncOriginalPostFromApplicant(uid);
+ }
+);
+
+watch(
+ () => submitDialog.visible,
+ async (v) => {
+ if (!v) return;
+ const key = applicantTemplateField.value?.key;
+ if (key && submitForm.formPayload[key]) {
+ syncOriginalPostFromApplicant(submitForm.formPayload[key]);
+ }
+ }
+);
+
+const tableColumn = buildInstanceTableColumns(tableData, buildTableActions, {
+ moduleKey: APPROVAL_MODULE_KEYS.TRANSFER,
+});
+
+function onSearch() {
+ handleQuery(searchForm);
+}
+
+async function resetSearch() {
+ searchForm.instanceNo = "";
+ searchForm.applicantId = "";
+ onSearch();
+ await remoteSearchApplicant("");
+}
+
+function onPagination(obj) {
+ pagination(obj, searchForm);
+}
+
+async function onSubmit() {
+ const ok = await submitInstanceForm({ skipValidate: true });
+ if (ok) ElMessage.success(isSubmitEdit.value ? "淇敼鎴愬姛" : "鎻愪氦鎴愬姛");
+}
+
+onMounted(async () => {
+ await Promise.all([loadUserPool(), loadPostOptions()]);
+ loadFlowUsers();
+ await remoteSearchApplicant("");
+ await initModuleList(searchForm);
+});
+</script>
+
+<style scoped>
+.mb20 {
+ margin-bottom: 20px;
+}
+.search_form {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+}
+.search_title {
+ font-size: 14px;
+ color: var(--el-text-color-regular);
+}
+</style>
--
Gitblit v1.9.3