|
@@ -17,17 +17,18 @@
|
|
|
* @typedef {import('@/api/types/announcement').NoticeFormData} NoticeFormData
|
|
|
*/
|
|
|
|
|
|
-import {
|
|
|
- getAnnouncement,
|
|
|
- add as addAnnouncement,
|
|
|
- update as updateAnnouncement
|
|
|
+import {
|
|
|
+ getAnnouncement,
|
|
|
+ add as addAnnouncement,
|
|
|
+ update as updateAnnouncement
|
|
|
} from '@/api/announcement';
|
|
|
import { getCategoryList } from '@/api/announcement/category';
|
|
|
-import {
|
|
|
- ROLE_OPTIONS,
|
|
|
- STATUS_OPTIONS,
|
|
|
- calculateRolesMask,
|
|
|
- parseRolesMask
|
|
|
+import { getCustomerList } from '@/api/common/index';
|
|
|
+import {
|
|
|
+ ROLE_OPTIONS,
|
|
|
+ STATUS_OPTIONS,
|
|
|
+ calculateRolesMask,
|
|
|
+ parseRolesMask
|
|
|
} from '@/views/announcement/constants';
|
|
|
|
|
|
|
|
@@ -252,6 +253,8 @@ export default {
|
|
|
brandOptions: [],
|
|
|
/** @type {boolean} 品牌选项加载状态 */
|
|
|
brandLoading: false,
|
|
|
+ /** @type {Array<number>} 选中的客户ID数组 */
|
|
|
+ selectedCustomerIds: [],
|
|
|
/** 表单验证规则 */
|
|
|
formRules: {
|
|
|
title: [
|
|
@@ -380,6 +383,19 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
immediate: true
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 监听客户黑名单变化,同步selectedCustomerIds
|
|
|
+ */
|
|
|
+ 'formData.customerBlacklist': {
|
|
|
+ handler(newVal) {
|
|
|
+ if (Array.isArray(newVal)) {
|
|
|
+ this.selectedCustomerIds = newVal.map(item => item.ID || item.id).filter(id => id != null);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ immediate: true
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -392,7 +408,7 @@ export default {
|
|
|
* @this {AnnouncementFormMixinComponent & Vue}
|
|
|
*/
|
|
|
apiToFormModel: dataConverter.apiToFormModel,
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 表单模型转换为API数据
|
|
|
* @param {AnnouncementFormModel} formModel 表单模型
|
|
@@ -400,7 +416,7 @@ export default {
|
|
|
* @this {AnnouncementFormMixinComponent & Vue}
|
|
|
*/
|
|
|
formModelToApi: dataConverter.formModelToApi,
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 解析角色掩码
|
|
|
* @param {string | number} rolesMask 角色掩码
|
|
@@ -408,7 +424,7 @@ export default {
|
|
|
* @this {AnnouncementFormMixinComponent & Vue}
|
|
|
*/
|
|
|
parseVisibleRoles: dataConverter.parseVisibleRoles.bind(dataConverter),
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 计算角色掩码
|
|
|
* @param {Array<RoleType>} roles 角色类型数组
|
|
@@ -416,7 +432,7 @@ export default {
|
|
|
* @this {AnnouncementFormMixinComponent & Vue}
|
|
|
*/
|
|
|
calculateRolesMask: dataConverter.calculateRolesMask.bind(dataConverter),
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 客户黑名单字符串化
|
|
|
* @param {Array<CustomerBlacklistItem>} customerBlacklist 客户黑名单
|
|
@@ -424,7 +440,7 @@ export default {
|
|
|
* @this {AnnouncementFormMixinComponent & Vue}
|
|
|
*/
|
|
|
stringifyCustomerBlacklist: dataConverter.stringifyCustomerBlacklist,
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 品牌范围字符串化
|
|
|
* @param {Array<BrandScopeItem>} brandScope 品牌范围
|
|
@@ -447,7 +463,7 @@ export default {
|
|
|
*/
|
|
|
async initFormData() {
|
|
|
this.formData = this.createInitialFormData();
|
|
|
-
|
|
|
+
|
|
|
if (this.editData) {
|
|
|
// 优先使用传入的编辑数据
|
|
|
this.formData = dataConverter.apiToFormModel(this.editData);
|
|
@@ -595,7 +611,7 @@ export default {
|
|
|
*/
|
|
|
async loadAnnouncementDetail() {
|
|
|
if (!this.announcementId) return;
|
|
|
-
|
|
|
+
|
|
|
try {
|
|
|
this.formLoading = true;
|
|
|
const response = await getAnnouncement(this.announcementId);
|
|
@@ -652,14 +668,14 @@ export default {
|
|
|
if (!isValid) return;
|
|
|
|
|
|
this.saveLoading = true;
|
|
|
-
|
|
|
+
|
|
|
// 转换数据格式
|
|
|
/** @type {NoticeFormData} */
|
|
|
const submitData = dataConverter.formModelToApi(this.formData);
|
|
|
-
|
|
|
+
|
|
|
// 提交数据
|
|
|
const response = await this.submitAnnouncementData(submitData);
|
|
|
-
|
|
|
+
|
|
|
if (response.data && response.data.success) {
|
|
|
this.$message.success(this.isEdit ? '更新成功' : '创建成功');
|
|
|
this.$emit('submit-success', this.formData);
|
|
@@ -683,6 +699,7 @@ export default {
|
|
|
handleReset() {
|
|
|
this.formData = this.createInitialFormData();
|
|
|
this.customerOptions = [];
|
|
|
+ this.selectedCustomerIds = [];
|
|
|
this.brandOptions = [];
|
|
|
this.$emit('reset');
|
|
|
},
|
|
@@ -736,17 +753,33 @@ export default {
|
|
|
* @this {AnnouncementFormMixinComponent & Vue}
|
|
|
*/
|
|
|
async remoteSearchCustomers(query) {
|
|
|
- if (!query || query.length < 2) {
|
|
|
+ if (!query || query.length < 1) {
|
|
|
this.customerOptions = [];
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
this.customerLoading = true;
|
|
|
- // TODO: 实现客户搜索API调用
|
|
|
- this.customerOptions = [];
|
|
|
+ const response = await getCustomerList(1, 20, {
|
|
|
+ customerName: query.trim()
|
|
|
+ });
|
|
|
+
|
|
|
+ if (response?.data?.success && response.data.data?.records) {
|
|
|
+ this.customerOptions = response.data.data.records.map(customer => ({
|
|
|
+ value: customer.Customer_ID,
|
|
|
+ label: customer.Customer_NAME,
|
|
|
+ Customer_NAME: customer.Customer_NAME,
|
|
|
+ Customer_CODE: customer.Customer_CODE
|
|
|
+ }));
|
|
|
+ } else {
|
|
|
+ this.customerOptions = [];
|
|
|
+ const errorMsg = response?.data?.msg || '搜索客户失败';
|
|
|
+ this.$message.warning(errorMsg);
|
|
|
+ }
|
|
|
} catch (error) {
|
|
|
console.error('搜索客户失败:', error);
|
|
|
+ this.$message.error('网络错误,搜索客户失败');
|
|
|
+ this.customerOptions = [];
|
|
|
} finally {
|
|
|
this.customerLoading = false;
|
|
|
}
|
|
@@ -777,20 +810,18 @@ export default {
|
|
|
|
|
|
/**
|
|
|
* 处理客户黑名单变化
|
|
|
- * @param {Array<CustomerOption>} selectedCustomers 选中的客户
|
|
|
+ * @param {Array<number>} selectedCustomerIds 选中的客户ID数组
|
|
|
* @this {AnnouncementFormMixinComponent & Vue}
|
|
|
*/
|
|
|
- handleCustomerBlacklistChange(selectedCustomers) {
|
|
|
+ handleCustomerBlacklistChange(selectedCustomerIds) {
|
|
|
+ this.selectedCustomerIds = selectedCustomerIds;
|
|
|
/** @type {Array<CustomerBlacklistItem>} */
|
|
|
- this.formData.customerBlacklist = selectedCustomers.map(customer => {
|
|
|
- // 从label中提取客户代码
|
|
|
- const codeMatch = customer.label ? customer.label.match(/\(([^)]+)\)$/) : null;
|
|
|
- const code = codeMatch ? codeMatch[1] : customer.Customer_CODE || '';
|
|
|
-
|
|
|
+ this.formData.customerBlacklist = selectedCustomerIds.map(customerId => {
|
|
|
+ const customer = this.customerOptions.find(option => option.value === customerId);
|
|
|
return {
|
|
|
- id: typeof customer.value === 'number' ? customer.value : parseInt(String(customer.value), 10),
|
|
|
- Customer_NAME: customer.Customer_NAME || (customer.label ? customer.label.replace(/\([^)]+\)$/, '').trim() : ''),
|
|
|
- Customer_CODE: code
|
|
|
+ ID: customerId,
|
|
|
+ NAME: customer?.Customer_NAME || '',
|
|
|
+ CODE: customer?.Customer_CODE || ''
|
|
|
};
|
|
|
});
|
|
|
},
|
|
@@ -806,7 +837,7 @@ export default {
|
|
|
// 从label中提取品牌代码
|
|
|
const codeMatch = brand.label ? brand.label.match(/\(([^)]+)\)$/) : null;
|
|
|
const code = codeMatch ? codeMatch[1] : brand.code || '';
|
|
|
-
|
|
|
+
|
|
|
return {
|
|
|
id: String(brand.value),
|
|
|
name: brand.name || (brand.label ? brand.label.replace(/\([^)]+\)$/, '').trim() : ''),
|
|
@@ -821,6 +852,8 @@ export default {
|
|
|
*/
|
|
|
clearCustomerOptions() {
|
|
|
this.customerOptions = [];
|
|
|
+ this.selectedCustomerIds = [];
|
|
|
+ this.formData.customerBlacklist = [];
|
|
|
},
|
|
|
|
|
|
/**
|
|
@@ -831,4 +864,4 @@ export default {
|
|
|
this.brandOptions = [];
|
|
|
}
|
|
|
}
|
|
|
-};
|
|
|
+};
|