Bladeren bron

feat(web-admin): add quote approver setting page and route

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 3 maanden geleden
bovenliggende
commit
209f5cb7a8
2 gewijzigde bestanden met toevoegingen van 155 en 0 verwijderingen
  1. 11 0
      web-admin/src/router/modules/sqxp.ts
  2. 144 0
      web-admin/src/views/crm/quote/approver-setting/index.vue

+ 11 - 0
web-admin/src/router/modules/sqxp.ts

@@ -360,6 +360,17 @@ export const sqxpAdminRoutes: AppRouteRecord[] = [
         component: '/crm/quote/index',
         meta: { title: '报价单管理', keepAlive: true, menuCode: 'crm:quote:list' }
       },
+      {
+        id: 'CRM3000000000000000000000000015',
+        name: 'CrmQuoteApproverSetting',
+        path: 'quote-approver-setting',
+        component: '/crm/quote/approver-setting/index',
+        meta: {
+          title: '报价单审批人设置',
+          keepAlive: true,
+          menuCode: 'crm:quote:approverSetting'
+        }
+      },
       {
         id: 'CRM3000000000000000000000000011',
         name: 'CrmQuoteForm',

+ 144 - 0
web-admin/src/views/crm/quote/approver-setting/index.vue

@@ -0,0 +1,144 @@
+<template>
+  <div class="page-container">
+    <section class="panel">
+      <div class="panel-top">
+        <h2 class="title-bar-heading">报价单审批人设置</h2>
+      </div>
+      <div class="panel-body quote-approver-setting-body">
+        <el-form ref="formRef" :model="form" label-position="top" class="crm-dialog-form">
+          <div class="form-grid-2">
+            <el-form-item class="form-col-span-2">
+              <template #label>
+                默认审批人<span class="form-label-tip">支持多人,按选择顺序依次审批</span>
+              </template>
+              <el-select
+                v-model="form.approverIds"
+                multiple
+                filterable
+                placeholder="请选择审批人"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="user in userList"
+                  :key="user.userId"
+                  :label="formatApproverOptionLabel(user)"
+                  :value="user.userId"
+                />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="状态">
+              <el-radio-group v-model="form.status">
+                <el-radio value="0">启用</el-radio>
+                <el-radio value="1">停用</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </div>
+        </el-form>
+        <div class="quote-approver-setting-actions">
+          <el-button class="btn-ghost" :loading="loading" @click="loadSetting">
+            <el-icon><RefreshLeft /></el-icon>重置
+          </el-button>
+          <el-button class="btn-main" type="primary" :loading="saving" @click="handleSave">
+            <el-icon><Check /></el-icon>保存设置
+          </el-button>
+        </div>
+      </div>
+    </section>
+  </div>
+</template>
+
+<script setup lang="ts" name="CrmQuoteApproverSetting">
+  import { RefreshLeft, Check } from '@element-plus/icons-vue'
+  import { fetchUserOptions } from '@/api/admin'
+  import { getQuoteApproverSetting, saveQuoteApproverSetting } from '@/api/crm/quote'
+  import type { QuoteApproverSettingForm } from '@/api/crm/quote/types'
+  import { $modal } from '@/utils/modal'
+
+  interface UserOption {
+    userId: string | number
+    nickName: string
+    userName: string
+  }
+
+  const formRef = ref()
+  const loading = ref(false)
+  const saving = ref(false)
+  const userList = ref<UserOption[]>([])
+
+  const form = ref<QuoteApproverSettingForm>({
+    approverIds: [],
+    status: '0'
+  })
+
+  const formatApproverOptionLabel = (user: { nickName?: string; userName?: string }) => {
+    const nick = (user.nickName || '').trim()
+    const account = (user.userName || '').trim()
+    if (nick && account) return `${nick}(${account})`
+    return nick || account
+  }
+
+  const loadUserList = async () => {
+    try {
+      const res = await fetchUserOptions()
+      const options = (res as any)?.data ?? res ?? []
+      userList.value = (Array.isArray(options) ? options : []).map((item: any) => ({
+        userId: item.value ?? item.userId ?? item.id,
+        nickName: item.nickName ?? item.label ?? item.userName ?? '',
+        userName: item.userNo ?? item.user_no ?? item.userName ?? ''
+      }))
+    } catch (error) {
+      console.error('加载用户列表失败:', error)
+      userList.value = []
+    }
+  }
+
+  const loadSetting = async () => {
+    loading.value = true
+    try {
+      const { data } = await getQuoteApproverSetting()
+      form.value = {
+        approverIds: (data.approverIds || []).map(String),
+        status: (data.status === '1' ? '1' : '0') as '0' | '1'
+      }
+    } catch (error: any) {
+      console.error('加载审批人设置失败:', error)
+      $modal.msgError(error?.msg || '加载审批人设置失败,请稍后重试')
+    } finally {
+      loading.value = false
+    }
+  }
+
+  const handleSave = async () => {
+    saving.value = true
+    try {
+      await saveQuoteApproverSetting({
+        approverIds: form.value.approverIds || [],
+        status: form.value.status
+      })
+      $modal.msgSuccess('保存成功')
+      await loadSetting()
+    } catch (error: any) {
+      console.error('保存审批人设置失败:', error)
+      $modal.msgError(error?.msg || '保存失败,请稍后重试')
+    } finally {
+      saving.value = false
+    }
+  }
+
+  onMounted(async () => {
+    await Promise.all([loadUserList(), loadSetting()])
+  })
+</script>
+
+<style scoped lang="scss">
+  .quote-approver-setting-body {
+    padding: 16px 20px 24px;
+  }
+
+  .quote-approver-setting-actions {
+    display: flex;
+    justify-content: flex-end;
+    gap: 8px;
+    margin-top: 16px;
+  }
+</style>