Browse Source

refactor(发票): 重构发票类型和状态管理逻辑

yz 3 weeks ago
parent
commit
b9334f9987
3 changed files with 219 additions and 54 deletions
  1. 30 19
      src/api/order/invoice.js
  2. 147 0
      src/views/order/invoice/constants.js
  3. 42 35
      src/views/order/invoice/index.vue

+ 30 - 19
src/api/order/invoice.js

@@ -1,4 +1,15 @@
 import request from '@/router/axios'
+import { INVOICE_TYPES, INVOICE_STATUS } from '@/views/order/invoice/constants'
+
+/**
+ * 发票类型联合类型
+ * @typedef {'NORMAL'|'SPECIAL'} InvoiceType
+ */
+
+/**
+ * 发票状态联合类型
+ * @typedef {0|1|2|3} InvoiceStatus
+ */
 
 /**
  * 发票查询参数类型定义
@@ -7,9 +18,9 @@ import request from '@/router/axios'
  * @property {string} [invoiceId] - 发票ID
  * @property {string} [invoiceNo] - 发票号码
  * @property {string} [customerName] - 客户名称
- * @property {string} [invoiceStatus] - 开票状态
- * @property {string} [startDate] - 开始日期
- * @property {string} [endDate] - 结束日期
+ * @property {InvoiceStatus} [invoiceStatus] - 开票状态 0-待开票 1-已开票 2-已红冲 3-已作废
+ * @property {string} [startDate] - 开始日期 格式:YYYY-MM-DD
+ * @property {string} [endDate] - 结束日期 格式:YYYY-MM-DD
  */
 
 /**
@@ -25,14 +36,14 @@ import request from '@/router/axios'
  * @property {string} customerName - 客户名称
  * @property {string} taxNo - 税号
  * @property {string} invoiceTitle - 发票抬头
- * @property {string} amount - 金额
- * @property {string} taxAmount - 税额
- * @property {string} totalAmount - 总金额
- * @property {string} invoiceType - 发票类型
- * @property {number} invoiceStatus - 开票状态 0-未开票 1-已开票 2-部分开票
- * @property {string} invoiceDate - 开票日期
- * @property {string} createTime - 创建时间
- * @property {string} updateTime - 更新时间
+ * @property {string} amount - 金额(字符串格式的数字)
+ * @property {string} taxAmount - 税额(字符串格式的数字)
+ * @property {string} totalAmount - 总金额(字符串格式的数字)
+ * @property {InvoiceType} invoiceType - 发票类型 NORMAL-普票 SPECIAL-专票
+ * @property {InvoiceStatus} invoiceStatus - 开票状态 0-待开票 1-已开票 2-已红冲 3-已作废
+ * @property {string} invoiceDate - 开票日期 格式:YYYY-MM-DD
+ * @property {string} createTime - 创建时间 格式:YYYY-MM-DD HH:mm:ss
+ * @property {string} updateTime - 更新时间 格式:YYYY-MM-DD HH:mm:ss
  */
 
 /**
@@ -48,12 +59,12 @@ import request from '@/router/axios'
  * @property {string} customerName - 客户名称
  * @property {string} taxNo - 税号
  * @property {string} invoiceTitle - 发票抬头
- * @property {string} amount - 金额
- * @property {string} taxAmount - 税额
- * @property {string} totalAmount - 总金额
- * @property {string} invoiceType - 发票类型
- * @property {number} invoiceStatus - 开票状态
- * @property {string} invoiceDate - 开票日期
+ * @property {string} amount - 金额(字符串格式的数字)
+ * @property {string} taxAmount - 税额(字符串格式的数字)
+ * @property {string} totalAmount - 总金额(字符串格式的数字)
+ * @property {InvoiceType} invoiceType - 发票类型 NORMAL-普票 SPECIAL-专票
+ * @property {InvoiceStatus} invoiceStatus - 开票状态 0-待开票 1-已开票 2-已红冲 3-已作废
+ * @property {string} invoiceDate - 开票日期 格式:YYYY-MM-DD
  */
 
 /**
@@ -155,10 +166,10 @@ export const getDetail = (id) => {
 /**
  * 批量更新发票状态
  * @param {string[]} ids - 发票ID数组
- * @param {number} status - 新状态
+ * @param {InvoiceStatus} status - 新状态 0-待开票 1-已开票 2-已红冲 3-已作废
  * @returns {Promise<ApiResponse<boolean>>} 更新结果
  */
-export const updateStatus = (ids, status) => {
+export const updateStatus = async (ids, status) => {
   return request({
     url: '/api/blade-factory/api/factory/order-invoice/status',
     method: 'put',

+ 147 - 0
src/views/order/invoice/constants.js

@@ -0,0 +1,147 @@
+/**
+ * 发票类型枚举
+ * @readonly
+ * @enum {string}
+ */
+export const INVOICE_TYPES = {
+  /** 普通发票 */
+  NORMAL: 'NORMAL',
+  /** 专用发票 */
+  SPECIAL: 'SPECIAL'
+}
+
+/**
+ * 发票状态枚举
+ * @readonly
+ * @enum {number}
+ */
+export const INVOICE_STATUS = {
+  /** 待开票 */
+  PENDING: 0,
+  /** 已开票 */
+  INVOICED: 1,
+  /** 已红冲 */
+  RED_FLUSHED: 2,
+  /** 已作废 */
+  VOIDED: 3
+}
+
+/**
+ * 发票类型标签映射
+ * @readonly
+ * @type {Record<string, string>}
+ */
+export const INVOICE_TYPE_LABELS = {
+  [INVOICE_TYPES.NORMAL]: '普通发票',
+  [INVOICE_TYPES.SPECIAL]: '专用发票'
+}
+
+/**
+ * 发票状态标签映射
+ * @readonly
+ * @type {Record<number, string>}
+ */
+export const INVOICE_STATUS_LABELS = {
+  [INVOICE_STATUS.PENDING]: '待开票',
+  [INVOICE_STATUS.INVOICED]: '已开票',
+  [INVOICE_STATUS.RED_FLUSHED]: '已红冲',
+  [INVOICE_STATUS.VOIDED]: '已作废'
+}
+
+/**
+ * 发票类型标签类型映射(用于Element UI标签样式)
+ * @readonly
+ * @type {Record<string, string>}
+ */
+export const INVOICE_TYPE_TAG_TYPES = {
+  [INVOICE_TYPES.NORMAL]: 'info',
+  [INVOICE_TYPES.SPECIAL]: 'success'
+}
+
+/**
+ * 发票状态标签类型映射(用于Element UI标签样式)
+ * @readonly
+ * @type {Record<number, string>}
+ */
+export const INVOICE_STATUS_TAG_TYPES = {
+  [INVOICE_STATUS.PENDING]: 'warning',
+  [INVOICE_STATUS.INVOICED]: 'success',
+  [INVOICE_STATUS.RED_FLUSHED]: 'danger',
+  [INVOICE_STATUS.VOIDED]: 'info'
+}
+
+/**
+ * 发票类型选项数组(用于下拉选择)
+ * @readonly
+ * @type {Array<{label: string, value: string}>}
+ */
+export const INVOICE_TYPE_OPTIONS = [
+  { label: INVOICE_TYPE_LABELS[INVOICE_TYPES.NORMAL], value: INVOICE_TYPES.NORMAL },
+  { label: INVOICE_TYPE_LABELS[INVOICE_TYPES.SPECIAL], value: INVOICE_TYPES.SPECIAL }
+]
+
+/**
+ * 发票状态选项数组(用于下拉选择)
+ * @readonly
+ * @type {Array<{label: string, value: number}>}
+ */
+export const INVOICE_STATUS_OPTIONS = [
+  { label: INVOICE_STATUS_LABELS[INVOICE_STATUS.PENDING], value: INVOICE_STATUS.PENDING },
+  { label: INVOICE_STATUS_LABELS[INVOICE_STATUS.INVOICED], value: INVOICE_STATUS.INVOICED },
+  { label: INVOICE_STATUS_LABELS[INVOICE_STATUS.RED_FLUSHED], value: INVOICE_STATUS.RED_FLUSHED },
+  { label: INVOICE_STATUS_LABELS[INVOICE_STATUS.VOIDED], value: INVOICE_STATUS.VOIDED }
+]
+
+/**
+ * 获取发票类型标签文本
+ * @param {string} type - 发票类型
+ * @returns {string} 标签文本
+ */
+export const getInvoiceTypeLabel = (type) => {
+  return INVOICE_TYPE_LABELS[type] || '未知类型'
+}
+
+/**
+ * 获取发票类型标签样式
+ * @param {string} type - 发票类型
+ * @returns {string} 标签样式类型
+ */
+export const getInvoiceTypeTagType = (type) => {
+  return INVOICE_TYPE_TAG_TYPES[type] || 'info'
+}
+
+/**
+ * 获取发票状态标签文本
+ * @param {number} status - 发票状态
+ * @returns {string} 标签文本
+ */
+export const getInvoiceStatusLabel = (status) => {
+  return INVOICE_STATUS_LABELS[status] || '未知状态'
+}
+
+/**
+ * 获取发票状态标签样式
+ * @param {number} status - 发票状态
+ * @returns {string} 标签样式类型
+ */
+export const getInvoiceStatusTagType = (status) => {
+  return INVOICE_STATUS_TAG_TYPES[status] || 'info'
+}
+
+/**
+ * 验证发票类型是否有效
+ * @param {string} type - 发票类型
+ * @returns {boolean} 是否有效
+ */
+export const isValidInvoiceType = (type) => {
+  return Object.values(INVOICE_TYPES).includes(type)
+}
+
+/**
+ * 验证发票状态是否有效
+ * @param {number} status - 发票状态
+ * @returns {boolean} 是否有效
+ */
+export const isValidInvoiceStatus = (status) => {
+  return Object.values(INVOICE_STATUS).includes(status)
+}

+ 42 - 35
src/views/order/invoice/index.vue

@@ -54,14 +54,14 @@
       </template>
 
       <template slot-scope="{row}" slot="invoiceStatus">
-        <el-tag :type="getInvoiceStatusType(row.invoiceStatus)">
-          {{ getInvoiceStatusText(row.invoiceStatus) }}
+        <el-tag :type="getInvoiceStatusTagType(row.invoiceStatus)">
+          {{ getInvoiceStatusLabel(row.invoiceStatus) }}
         </el-tag>
       </template>
 
       <template slot-scope="{row}" slot="invoiceType">
-        <el-tag :type="row.invoiceType === 'SPECIAL' ? 'success' : 'info'">
-          {{ row.invoiceType === 'SPECIAL' ? '专用发票' : '普通发票' }}
+        <el-tag :type="getInvoiceTypeTagType(row.invoiceType)">
+          {{ getInvoiceTypeLabel(row.invoiceType) }}
         </el-tag>
       </template>
 
@@ -83,6 +83,16 @@
 <script>
 import { getList, add, update, remove, getDetail, updateStatus } from '@/api/order/invoice'
 import { mapGetters } from 'vuex'
+import {
+  INVOICE_TYPES,
+  INVOICE_STATUS,
+  INVOICE_TYPE_OPTIONS,
+  INVOICE_STATUS_OPTIONS,
+  getInvoiceTypeLabel,
+  getInvoiceTypeTagType,
+  getInvoiceStatusLabel,
+  getInvoiceStatusTagType
+} from './constants'
 
 /**
  * 发票查询参数类型定义
@@ -311,10 +321,9 @@ export default {
             prop: 'invoiceType',
             slot: true,
             type: 'select',
-            dicData: [
-              { label: '普通发票', value: 'NORMAL' },
-              { label: '专用发票', value: 'SPECIAL' }
-            ],
+            search: true,
+            width: 120,
+            dicData: INVOICE_TYPE_OPTIONS,
             rules: [
               {
                 required: true,
@@ -329,11 +338,7 @@ export default {
             slot: true,
             search: true,
             type: 'select',
-            dicData: [
-              { label: '未开票', value: 0 },
-              { label: '已开票', value: 1 },
-              { label: '部分开票', value: 2 }
-            ],
+            dicData: INVOICE_STATUS_OPTIONS,
             rules: [
               {
                 required: true,
@@ -408,32 +413,34 @@ export default {
 
   methods: {
     /**
-     * 获取发票状态对应的标签类型
+     * 获取发票类型标签文本
+     * @param {string} type - 发票类型
+     * @returns {string} 标签文本
+     */
+    getInvoiceTypeLabel,
+
+    /**
+     * 获取发票类型标签样式
+     * @param {string} type - 发票类型
+     * @returns {string} 标签样式类型
+     */
+    getInvoiceTypeTagType,
+
+    /**
+     * 获取发票状态标签文本
      * @param {number} status - 发票状态
-     * @returns {string} 标签类型
+     * @returns {string} 标签文本
      */
-    getInvoiceStatusType(status) {
-      const statusMap = {
-        0: 'danger',   // 未开票
-        1: 'success',  // 已开票
-        2: 'warning'   // 部分开票
-      }
-      return statusMap[status] || 'info'
-    },
+    getInvoiceStatusLabel,
 
     /**
-     * 获取发票状态文本
+     * 获取发票状态标签样式
      * @param {number} status - 发票状态
-     * @returns {string} 状态文本
+     * @returns {string} 标签样式类型
      */
-    getInvoiceStatusText(status) {
-      const statusMap = {
-        0: '未开票',
-        1: '已开票',
-        2: '部分开票'
-      }
-      return statusMap[status] || '未知状态'
-    },
+    getInvoiceStatusTagType,
+
+
 
     /**
      * 格式化金额显示
@@ -493,7 +500,7 @@ export default {
         return
       }
 
-      const statusText = this.getInvoiceStatusText(status)
+      const statusText = getInvoiceStatusLabel(status)
       
       try {
         await this.$confirm(`确定将选中的发票状态更新为"${statusText}"吗?`, '提示', {
@@ -507,7 +514,7 @@ export default {
         
         if (res.data.success) {
           this.$message.success('状态更新成功')
-          this.onLoad(this.page)
+          await this.onLoad(this.page)
         } else {
           this.$message.error(res.data.msg || '状态更新失败')
         }