Browse Source

feat(公告管理): 添加客户黑名单选择功能

yz 2 months ago
parent
commit
9852ea845d

+ 2 - 0
src/api/common/customer.js

@@ -1,3 +1,5 @@
+import request from '@/router/axios';
+
 /**
  * 获取客户列表
  * @param {Object} params - 查询参数

+ 42 - 0
src/views/announcement/index.vue

@@ -31,6 +31,39 @@
                     查看详情
                 </el-button>
             </template>
+
+            <!-- 客户黑名单字段自定义插槽 -->
+            <template slot="customerBlacklistForm" slot-scope="{value, column}">
+                <el-select
+                    v-model="form.customerBlacklist"
+                    multiple
+                    filterable
+                    remote
+                    reserve-keyword
+                    placeholder="请输入客户名称进行搜索"
+                    :remote-method="remoteSearchCustomers"
+                    :loading="customerOptionsLoading"
+                    value-key="id"
+                    @change="handleCustomerBlacklistChange"
+                    @clear="clearCustomerOptions"
+                    style="width: 100%;"
+                    clearable
+                >
+                    <el-option
+                        v-for="customer in customerBlacklistOptions"
+                        :key="customer.id"
+                        :label="getCustomerDisplayName(customer)"
+                        :value="customer"
+                    >
+                        <span style="float: left">{{ customer.Customer_NAME }}</span>
+                        <span style="float: right; color: #8492a6; font-size: 13px">
+                            {{ customer.Customer_CODE }}
+                        </span>
+                    </el-option>
+                </el-select>
+            </template>
+
+            <!-- 其他现有插槽 -->
             <template slot-scope="{row}" slot="categoryName">
                 <el-tag type="primary">{{ row.categoryName }}</el-tag>
             </template>
@@ -68,6 +101,15 @@
                             {{ getStatusLabel(currentDetail.status) }}
                         </el-tag>
                     </p>
+                    <!-- 显示客户黑名单信息 -->
+                    <p v-if="currentDetail.customerBlacklist && currentDetail.customerBlacklist.length > 0">
+                        <strong>客户黑名单:</strong>
+                        <span v-for="(customer) in currentDetail.customerBlacklist" :key="customer.id">
+                            <el-tag size="mini" style="margin-right: 4px; margin-bottom: 4px;">
+                                {{ getCustomerDisplayName(customer) }}
+                            </el-tag>
+                        </span>
+                    </p>
                 </div>
                 <div class="detail-body" v-html="currentDetail.content"></div>
             </div>

+ 122 - 6
src/views/announcement/mixins/announcementIndex.js

@@ -1,4 +1,5 @@
 import { getList, update, add, getAnnouncement, getCategoryList } from "@/api/announcement";
+import { getCustomerList } from "@/api/common/customer"; // 新增客户接口导入
 import { mapGetters } from "vuex";
 import {
     ROLE_OPTIONS,
@@ -56,7 +57,7 @@ import {
  * @property {string} orgName - 组织名称
  * @property {VisibleRolesMask} visibleRoles - 可见角色掩码(位运算:1工厂 2经销商 4零售商)
  * @property {Object|null} brandScope - 品牌范围
- * @property {Object|null} customerBlacklist - 客户黑名单
+ * @property {Array<CustomerBlacklistOption>|null} customerBlacklist - 客户黑名单
  * @property {string} remark - 备注
  * @property {string} createTime - 创建时间
  * @property {string} updateTime - 更新时间
@@ -140,6 +141,20 @@ import {
  * 公告管理混入
  * @mixin AnnouncementIndexMixin
  */
+/**
+ * 客户选项类型定义
+ * @typedef {import('@/api/common/customer').CustomerRecord} CustomerRecord
+ */
+
+/**
+ * 客户黑名单选项类型定义
+ * @typedef {Object} CustomerBlacklistOption
+ * @property {string} id - 客户ID
+ * @property {string} Customer_NAME - 客户名称
+ * @property {string} Customer_CODE - 客户编码
+ * @property {string} Customer_ShortName - 客户简称
+ */
+
 export default {
     name: 'AnnouncementIndexMixin',
 
@@ -171,6 +186,14 @@ export default {
                 { label: "经销商", value: 2 },
                 { label: "零售商", value: 4 }
             ],
+            /** @type {Array<CustomerBlacklistOption>} 客户黑名单选项列表 */
+            customerBlacklistOptions: [],
+            /**
+             * @type {Array<CustomerRecord>} 当前客户黑名单
+             */
+            currentCustomerBlacklist: [],
+            /** @type {boolean} 客户选项加载状态 */
+            customerOptionsLoading: false,
             /** @type {TableOption} 表格配置选项 */
             option: {
                 height: 'auto',
@@ -340,7 +363,7 @@ export default {
                     {
                         label: "客户黑名单",
                         prop: "customerBlacklist",
-                        type: "json",
+                        slot: true,
                         hide: true,
                         span: 24
                     }
@@ -472,6 +495,11 @@ export default {
                     ? this.calculateRolesMask(row.visibleRoles)
                     : (row.visibleRoles || 7); // 默认所有角色可见
 
+                const updateCustomerBlacklist = this.currentCustomerBlacklist.filter(customer => {
+                    const ids = row.customerBlacklist.map(customer => customer.id);
+                    return ids.includes(customer.id);
+                });
+
                 // 设置默认值
                 const formData = {
                     ...row,
@@ -479,7 +507,8 @@ export default {
                     orgCode: this.userInfo.orgCode || 'ORG_0001',
                     orgName: this.userInfo.orgName || '默认组织',
                     brandScope: row.brandScope || {},
-                    customerBlacklist: row.customerBlacklist || {},
+                    // customerBlacklist: Array.isArray(row.customerBlacklist) ? row.customerBlacklist : [],
+                    customerBlacklist: updateCustomerBlacklist,
                     remark: row.remark || '',
                     visibleRoles: rolesMask,
                     status: row.status !== undefined ? row.status : 0, // 默认草稿状态
@@ -527,11 +556,16 @@ export default {
                     row.categoryName = selectedCategory.name;
                 }
 
+                const updateCustomerBlacklist = this.currentCustomerBlacklist.filter(customer => {
+                    const ids = row.customerBlacklist.map(customer => customer.id);
+                    return ids.includes(customer.id);
+                });
                 // 确保必要字段存在
                 const formData = {
                     ...row,
                     brandScope: row.brandScope || {},
-                    customerBlacklist: row.customerBlacklist || {},
+                    // customerBlacklist: Array.isArray(row.customerBlacklist) ? row.customerBlacklist : [],
+                    customerBlacklist: updateCustomerBlacklist,
                     remark: row.remark || '',
                     visibleRoles: rolesMask
                 };
@@ -615,6 +649,17 @@ export default {
                     // 将掩码值转换为数值数组格式供表单使用
                     const roleObjects = this.parseRolesMask(formData.visibleRoles);
                     formData.visibleRoles = roleObjects.map(role => role.value);
+
+                    // 确保客户黑名单是数组格式
+                    formData.customerBlacklist = Array.isArray(formData.customerBlacklist)
+                        ? formData.customerBlacklist
+                        : [];
+
+                    // 如果有客户黑名单数据,设置到选项中以便显示
+                    if (formData.customerBlacklist.length > 0) {
+                        this.customerBlacklistOptions = [...formData.customerBlacklist];
+                    }
+
                     this.form = formData;
                 } catch (error) {
                     console.error('获取详情失败:', error);
@@ -627,9 +672,11 @@ export default {
                     orgName: this.userInfo.orgName || '',
                     visibleRoles: [], // 默认经销商
                     brandScope: {},
-                    customerBlacklist: {},
+                    customerBlacklist: [],
                     remark: ''
                 };
+                // 清空客户选项
+                this.customerBlacklistOptions = [];
             }
             done();
         },
@@ -660,6 +707,75 @@ export default {
             } finally {
                 this.loading = false;
             }
-        }
+        },
+
+        /**
+         * 远程搜索客户数据
+         * @async
+         * @param {string} query - 搜索关键词
+         * @returns {Promise<void>}
+         */
+        async remoteSearchCustomers(query) {
+            if (!query || query.trim().length < 1) {
+                this.customerBlacklistOptions = [];
+                return;
+            }
+
+            this.customerOptionsLoading = true;
+            try {
+                const response = await getCustomerList({
+                    current: 1,
+                    size: 50,
+                    customerName: query.trim()
+                });
+
+                if (response.data && response.data.success && response.data.data) {
+                    /** @type {Array<CustomerRecord>} */
+                    const customers = response.data.data.records || [];
+                    this.currentCustomerBlacklist = customers;
+
+                    this.customerBlacklistOptions = customers.map(customer => ({
+                        id: customer.id,
+                        Customer_NAME: customer.Customer_NAME,
+                        Customer_CODE: customer.Customer_CODE,
+                        Customer_ShortName: customer.Customer_ShortName
+                    }));
+                } else {
+                    this.customerBlacklistOptions = [];
+                }
+            } catch (error) {
+                console.error('获取客户列表失败:', error);
+                this.$message.error('获取客户列表失败');
+                this.customerBlacklistOptions = [];
+            } finally {
+                this.customerOptionsLoading = false;
+            }
+        },
+
+        /**
+         * 客户黑名单选择变化处理
+         * @param {Array<CustomerBlacklistOption>} selectedCustomers - 选中的客户列表
+         */
+        handleCustomerBlacklistChange(selectedCustomers) {
+            this.form.customerBlacklist = selectedCustomers || [];
+        },
+
+        /**
+         * 获取客户显示名称
+         * @param {CustomerBlacklistOption} customer - 客户对象
+         * @returns {string} 显示名称
+         */
+        getCustomerDisplayName(customer) {
+            if (!customer) return '';
+            return `${customer.Customer_NAME}(${customer.Customer_CODE})`;
+        },
+
+        /**
+         * 清空客户搜索结果
+         */
+        clearCustomerOptions() {
+            this.customerBlacklistOptions = [];
+        },
+
     }
 };