ソースを参照

feat(forecast-audit): 添加审批弹窗并重构审批逻辑

yz 1 ヶ月 前
コミット
559b5a8f56

+ 1 - 1
src/api/forecast/index.js

@@ -76,7 +76,7 @@ export const addForecast = async (data) => {
 
 /**
  * 修改预测申报
- * @param {ForecastForm} data - 预测申报表单数据(必须包含id)
+ * @param {import('./types').ForecastFormUpdateModel} data - 预测申报表单数据(必须包含id)
  * @returns {Promise<ForecastOperationResponse>} 修改结果响应
  * @description 更新现有的经销商销售预测申报记录,只有未审批状态的记录可以修改
  * @example

+ 2 - 0
src/api/forecast/types.d.ts

@@ -44,6 +44,8 @@ export interface ForecastForm {
   approvalComment?: string
 }
 
+export type ForecastFormUpdateModel = Pick<ForecastForm, 'id'> & Partial<Omit<ForecastForm, 'id'>>;
+
 // 预测申报记录
 export interface ForecastRecord extends ForecastForm {
   id: string

+ 1 - 1
src/store/modules/user.js

@@ -91,7 +91,7 @@ const user = {
       return new Promise((resolve, reject) => {
         loginByUsername(userInfo.tenantId, userInfo.deptId, userInfo.roleId, userInfo.username, md5(userInfo.password), userInfo.type, userInfo.key, userInfo.code).then(res => {
           const data = res.data;
-          console.log('用户登录返回数据:', data);
+          console.log('用户登录返回数据:', JSON.stringify(data));
           localStorage.setItem('roleName', data.role_name);
           if (data.error_description) {
             Message({

+ 58 - 0
src/types/global.d.ts

@@ -158,6 +158,64 @@ declare global {
     page?: boolean;
     [key: string]: any;
   }
+
+  // 用户信息类型
+  interface UserInfo {
+    /** 访问令牌 */
+    access_token?: string;
+    /** 令牌类型 */
+    token_type?: string;
+    /** 刷新令牌 */
+    refresh_token?: string;
+    /** 过期时间(秒) */
+    expires_in?: number;
+    /** 权限范围 */
+    scope?: string;
+    /** 租户ID */
+    tenant_id?: string;
+    /** 用户名 */
+    user_name?: string;
+    /** 部门父级ID */
+    dept_pid?: string;
+    /** 真实姓名 */
+    real_name?: string;
+    /** 头像 */
+    avatar?: string;
+    /** 公司名称 */
+    corp_name?: string;
+    /** 客户端ID */
+    client_id?: string;
+    /** 角色名称 */
+    role_name?: string;
+    /** 许可证信息 */
+    license?: string;
+    /** 岗位ID(多个用逗号分隔) */
+    post_id?: string;
+    /** 用户ID */
+    user_id?: string;
+    /** 角色ID */
+    role_id?: string;
+    /** 昵称 */
+    nick_name?: string;
+    /** 公司地址 */
+    corp_address?: string;
+    /** OAuth ID */
+    oauth_id?: string;
+    /** 详细信息 */
+    detail?: {
+      /** 类型 */
+      type?: string;
+      [key: string]: any;
+    };
+    /** 部门ID */
+    dept_id?: string;
+    /** 公司ID */
+    corp_id?: string | null;
+    /** 账户名 */
+    account?: string;
+    /** JWT ID */
+    jti?: string;
+  }
 }
 
 export {};

+ 25 - 48
src/views/forecast-audit/auditIndex.js

@@ -1,4 +1,4 @@
-import { getForecastList, approveForecast, updateForecast } from '@/api/forecast'
+import { getForecastList, updateForecast } from '@/api/forecast'
 import { mapGetters } from 'vuex'
 import {
   APPROVAL_STATUS,
@@ -12,7 +12,7 @@ import {
 import { dateFormat } from '@/util/date'
 
 /**
- * @typedef {import('@/api/forecast/types').ForecastRecord} ForecastRecord
+ * @typedef {import('./types').ForecastRecord} ForecastRecord
  * @typedef {import('./types').PageConfig} PageConfig
  * @typedef {import('./types').ApprovalFormData} ApprovalFormData
  * @typedef {import('./types').PermissionConfig} PermissionConfig
@@ -54,8 +54,7 @@ export default {
       /** @type {ApprovalFormData} 审批表单数据 */
       approvalForm: {
         id: null,
-        isApprove: true,
-        comment: ''
+        isApprove: true
       },
       option: {
         height: 'auto',
@@ -210,29 +209,12 @@ export default {
             overHidden: true
           }
         ]
-      },
-      /** @type {Record<string, Array<ValidationRule>>} 审批表单验证规则 */
-      approvalFormRules: {
-        approvalComment: [
-          {
-            validator: (rule, value, callback) => {
-              if (!this.approvalForm.isApprove && (!value || value.trim() === '')) {
-                callback(new Error('拒绝审批时必须填写拒绝原因'))
-              } else if (value && value.length > 500) {
-                callback(new Error('审批意见不能超过500个字符'))
-              } else {
-                callback()
-              }
-            },
-            trigger: 'blur'
-          }
-        ]
       }
     }
   },
 
   computed: {
-    ...mapGetters(['permission']),
+    ...mapGetters(['permission', 'userInfo']),
 
     /**
      * 权限列表
@@ -269,7 +251,7 @@ export default {
   methods: {
     /**
      * 获取审批状态标签
-     * @param {import('@/constants/forecast').ApprovalStatus} status - 审批状态值
+     * @param {import('@/constants').ApprovalStatus} status - 审批状态值
      * @returns {string} 状态标签文本
      */
     getApprovalStatusLabel(status) {
@@ -278,7 +260,7 @@ export default {
 
     /**
      * 获取审批状态类型
-     * @param {import('@/constants/forecast').ApprovalStatus} status - 审批状态值
+     * @param {import('@/constants').ApprovalStatus} status - 审批状态值
      * @returns {string} 状态类型
      */
     getApprovalStatusType(status) {
@@ -292,7 +274,7 @@ export default {
      * @returns {boolean} 是否可以审批通过
      */
     canApprove(row) {
-      return canApprove(row.approvalStatus || 0)
+      return canApprove(row.approvalStatus || APPROVAL_STATUS.PENDING)
     },
 
     /**
@@ -302,7 +284,7 @@ export default {
      * @returns {boolean} 是否可以审批拒绝
      */
     canReject(row) {
-      return canReject(row.approvalStatus || 0)
+      return canReject(row.approvalStatus || APPROVAL_STATUS.PENDING)
     },
 
     /**
@@ -410,9 +392,8 @@ export default {
      */
     performApproval(record, isApprove) {
       this.approvalForm = {
-        id: Number(record.id),
-        isApprove: isApprove,
-        comment: ''
+        id: record.id,
+        isApprove: isApprove
       }
       this.approvalDialogVisible = true
     },
@@ -423,25 +404,22 @@ export default {
      * @returns {void}
      */
     submitApproval() {
-      /** @type {any} */ (this.$refs.approvalFormRef).validate(/** @param {boolean} valid */ (valid) => {
-        if (valid) {
-          this.submitting = true
-          const approvalData = {
-              id: Number(this.approvalForm.id),
-              approvalStatus: this.approvalForm.isApprove ? APPROVAL_STATUS.APPROVED : APPROVAL_STATUS.REJECTED,
-              approvalComment: this.approvalForm.comment
-            }
+      this.submitting = true
+      const approvalData = {
+        id: this.approvalForm.id,
+        approvalStatus: this.approvalForm.isApprove ? APPROVAL_STATUS.APPROVED : APPROVAL_STATUS.REJECTED,
+        approved_by: this.userInfo.user_id || 0,
+        approved_name: this.userInfo.user_name || '',
+      }
 
-          approveForecast(approvalData).then(() => {
-            this.$message.success('审批操作成功')
-            this.approvalDialogVisible = false
-            this.onLoad(this.page)
-          }).catch(() => {
-            this.$message.error('审批操作失败')
-          }).finally(() => {
-            this.submitting = false
-          })
-        }
+      updateForecast(approvalData).then(() => {
+        this.$message.success('审批操作成功')
+        this.approvalDialogVisible = false
+        this.onLoad(this.page)
+      }).catch(() => {
+        this.$message.error('审批操作失败')
+      }).finally(() => {
+        this.submitting = false
       })
     },
 
@@ -455,7 +433,6 @@ export default {
        this.approvalForm = {
          id: null,
          isApprove: true,
-         comment: ''
        }
      },
 

+ 19 - 0
src/views/forecast-audit/index.scss

@@ -2,6 +2,25 @@
  * 销售预测审核页面样式
  */
 
+// 审批信息样式
+.approval-info {
+  padding: 20px 0;
+  text-align: center;
+  
+  p {
+    margin: 0;
+    font-size: 16px;
+    color: #606266;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    
+    i {
+      font-size: 18px;
+    }
+  }
+}
+
 // 详情表单样式
 .forecast-detail-form {
   .el-form-item {

+ 31 - 0
src/views/forecast-audit/index.vue

@@ -214,6 +214,37 @@
         </el-button>
       </span>
     </el-dialog>
+
+    <!-- 审批弹窗 -->
+    <el-dialog
+      :title="approvalDialogTitle"
+      :visible.sync="approvalDialogVisible"
+      width="600px"
+      :close-on-click-modal="false"
+      append-to-body
+    >
+      <div class="approval-info">
+        <p v-if="approvalForm.isApprove">
+          <i class="el-icon-success" style="color: #67C23A; margin-right: 8px;"></i>
+          确认通过此预测申报?
+        </p>
+        <p v-else>
+          <i class="el-icon-error" style="color: #F56C6C; margin-right: 8px;"></i>
+          确认拒绝此预测申报?
+        </p>
+      </div>
+      
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="cancelApproval">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitApproval"
+          :loading="submitting"
+        >
+          确 定
+        </el-button>
+      </span>
+    </el-dialog>
   </basic-container>
 </template>
 

+ 72 - 9
src/views/forecast-audit/types.d.ts

@@ -1,6 +1,55 @@
 // 销售预测审核页面类型定义
 
-import { ForecastRecord } from '@/api/forecast/types'
+import { ApprovalStatus } from "@/constants"
+import { ForecastRecord } from "@/api/forecast"
+
+export interface ForecastRecord extends ForecastRecord {
+  /** 审批状态 */
+  approvalStatus: ApprovalStatus
+}
+
+
+/**
+ * Avue表格配置类型
+ */
+export interface AvueCrudOption {
+  /** 表格高度 */
+  height: string
+  /** 计算高度 */
+  calcHeight: number
+  /** 显示搜索 */
+  searchShow: boolean
+  /** 搜索菜单跨度 */
+  searchMenuSpan: number
+  /** 边框 */
+  border: boolean
+  /** 索引 */
+  index: boolean
+  /** 查看按钮 */
+  viewBtn: boolean
+  /** 选择 */
+  selection: boolean
+  /** 添加按钮 */
+  addBtn: boolean
+  /** 编辑按钮 */
+  editBtn: boolean
+  /** 删除按钮 */
+  delBtn: boolean
+  /** Excel按钮 */
+  excelBtn: boolean
+  /** 列按钮 */
+  columnBtn: boolean
+  /** 刷新按钮 */
+  refreshBtn: boolean
+  /** 弹窗点击模态 */
+  dialogClickModal: boolean
+  /** 菜单 */
+  menu: boolean
+  /** 菜单宽度 */
+  menuWidth: number
+  /** 列配置 */
+  column: Array<any>
+}
 
 /**
  * 分页配置类型定义
@@ -15,15 +64,13 @@ export interface PageConfig {
 }
 
 /**
- * 审批表单数据类型定义
+ * 审批表单数据接口
  */
 export interface ApprovalFormData {
   /** 记录ID */
-  id: number | null
-  /** 是否通过审批 */
+  id: string | null
+  /** 是否通过审批 */
   isApprove: boolean
-  /** 审批意见 */
-  comment: string
 }
 
 /**
@@ -64,18 +111,34 @@ export interface ForecastAuditComponentData {
   detailForm: Record<string, any>
   /** 表格配置 */
   option: AvueCrudOption
-  /** 审批表单验证规则 */
-  approvalFormRules: Record<string, Array<ValidationRule>>
   /** 审批表单数据 */
   approvalForm: ApprovalFormData
 }
 
+
+
+/**
+ * Vue消息提示类型
+ */
+export interface MessageInstance {
+  success(message: string): void
+  error(message: string): void
+  warning(message: string): void
+  info(message: string): void
+}
+
 /**
  * 销售预测审核页面组件类型
  */
 export interface ForecastAuditComponent extends ForecastAuditComponentData {
+  /** 用户信息 */
+  userInfo: UserInfo
+  /** 消息提示 */
+  $message: MessageInstance
+  /** 确认对话框 */
+  $confirm(message: string, title: string, options?: any): Promise<any>
   /** 加载数据方法 */
   onLoad(page: PageConfig, params?: Record<string, any>): void
   /** 执行审批操作方法 */
   performApproval(row: ForecastRecord, isApprove: boolean): void
-}
+}