国家
This commit is contained in:
@@ -19,8 +19,8 @@ const service = axios.create({
|
|||||||
// baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换
|
// baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换
|
||||||
// baseURL: 'http://www.tougao.com/', //测试本地 记得切换
|
// baseURL: 'http://www.tougao.com/', //测试本地 记得切换
|
||||||
// baseURL: 'http://192.168.110.110/tougao/public/index.php/',
|
// baseURL: 'http://192.168.110.110/tougao/public/index.php/',
|
||||||
baseURL: '/api', //本地
|
// baseURL: '/api', //本地
|
||||||
// baseURL: '/', //正式
|
baseURL: '/', //正式
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -330,8 +330,8 @@ const en = {
|
|||||||
exportFailed: 'Export failed'
|
exportFailed: 'Export failed'
|
||||||
},
|
},
|
||||||
countryManagement: {
|
countryManagement: {
|
||||||
title: 'Country maintenance',
|
title: 'Country Management',
|
||||||
keywordPlaceholder: 'Chinese / English / code',
|
keywordPlaceholder: 'Chinese / English / Code',
|
||||||
partitionLabel: 'Partition',
|
partitionLabel: 'Partition',
|
||||||
partitionAll: 'All partitions',
|
partitionAll: 'All partitions',
|
||||||
partition1: 'Partition 1',
|
partition1: 'Partition 1',
|
||||||
@@ -1098,14 +1098,20 @@ colTitle: 'Template title',
|
|||||||
changeTemplate: 'Change Template',
|
changeTemplate: 'Change Template',
|
||||||
selectPromotionFields: 'Select Promotion Fields',
|
selectPromotionFields: 'Select Promotion Fields',
|
||||||
choosePromotionFields: 'Choose Fields',
|
choosePromotionFields: 'Choose Fields',
|
||||||
|
selectPromotionCountry: 'Select Country',
|
||||||
|
choosePromotionCountry: 'Choose Countries',
|
||||||
selectedCount: 'Selected {count}',
|
selectedCount: 'Selected {count}',
|
||||||
selectAll: 'Select All',
|
selectAll: 'Select All',
|
||||||
clearAll: 'Clear All',
|
clearAll: 'Clear All',
|
||||||
selectPromotionFieldsTip: 'Multiple selection supported; leave empty for no field restriction.',
|
selectPromotionFieldsTip: 'Multiple selection supported; leave empty for no field restriction.',
|
||||||
|
selectPromotionCountryTip: 'Multiple selection supported; leave empty for no country restriction. Uses the same API as fields until a dedicated country list is available.',
|
||||||
fieldSearchPlaceholder: 'Search promotion fields',
|
fieldSearchPlaceholder: 'Search promotion fields',
|
||||||
|
countrySearchPlaceholder: 'Search countries',
|
||||||
noFieldMatch: 'No matching fields',
|
noFieldMatch: 'No matching fields',
|
||||||
|
noCountryMatch: 'No matching countries',
|
||||||
confirm: 'Confirm',
|
confirm: 'Confirm',
|
||||||
fieldsSaved: 'Promotion fields saved',
|
fieldsSaved: 'Promotion fields saved',
|
||||||
|
countriesSaved: 'Promotion countries saved',
|
||||||
confirmAndEnable: 'Confirm and Enable',
|
confirmAndEnable: 'Confirm and Enable',
|
||||||
onlySaveConfig: 'Save configuration only',
|
onlySaveConfig: 'Save configuration only',
|
||||||
enableNowNextDay: 'Enable auto promotion now (starts next day)'
|
enableNowNextDay: 'Enable auto promotion now (starts next day)'
|
||||||
|
|||||||
@@ -1083,14 +1083,20 @@ const zh = {
|
|||||||
changeTemplate: '更换模版',
|
changeTemplate: '更换模版',
|
||||||
selectPromotionFields: '选择推广领域',
|
selectPromotionFields: '选择推广领域',
|
||||||
choosePromotionFields: '选择领域',
|
choosePromotionFields: '选择领域',
|
||||||
|
selectPromotionCountry: '选择国家',
|
||||||
|
choosePromotionCountry: '选择国家',
|
||||||
selectedCount: '已选 {count} 项',
|
selectedCount: '已选 {count} 项',
|
||||||
selectAll: '全选',
|
selectAll: '全选',
|
||||||
clearAll: '取消全选',
|
clearAll: '取消全选',
|
||||||
selectPromotionFieldsTip: '可多选;未选择则不限制推广领域。',
|
selectPromotionFieldsTip: '可多选;未选择则不限制推广领域。',
|
||||||
|
selectPromotionCountryTip: '可多选;未选择则不限制国家。与领域接口一致,后续可对接独立国家数据。',
|
||||||
fieldSearchPlaceholder: '搜索推广领域',
|
fieldSearchPlaceholder: '搜索推广领域',
|
||||||
|
countrySearchPlaceholder: '搜索国家',
|
||||||
noFieldMatch: '没有匹配的领域',
|
noFieldMatch: '没有匹配的领域',
|
||||||
|
noCountryMatch: '没有匹配的国家',
|
||||||
confirm: '确定',
|
confirm: '确定',
|
||||||
fieldsSaved: '推广领域已保存',
|
fieldsSaved: '推广领域已保存',
|
||||||
|
countriesSaved: '推广国家已保存',
|
||||||
confirmAndEnable: '确认并开启',
|
confirmAndEnable: '确认并开启',
|
||||||
onlySaveConfig: '仅保存配置',
|
onlySaveConfig: '仅保存配置',
|
||||||
enableNowNextDay: '立即激活自动推广(次日开始自动推广)'
|
enableNowNextDay: '立即激活自动推广(次日开始自动推广)'
|
||||||
|
|||||||
@@ -99,7 +99,9 @@
|
|||||||
:config="wizardConfig"
|
:config="wizardConfig"
|
||||||
:wizardStartDate.sync="wizardStartDate"
|
:wizardStartDate.sync="wizardStartDate"
|
||||||
:selectedFieldIds.sync="selectedFieldIds"
|
:selectedFieldIds.sync="selectedFieldIds"
|
||||||
|
:selectedCountryIds.sync="selectedCountryIds"
|
||||||
:availableFields="availableFields"
|
:availableFields="availableFields"
|
||||||
|
:availableCountries="availableCountries"
|
||||||
:fieldsLoading="fieldsLoading"
|
:fieldsLoading="fieldsLoading"
|
||||||
:fieldsSaving="fieldsSaving"
|
:fieldsSaving="fieldsSaving"
|
||||||
:currentJournalName="wizardJournal ? wizardJournal.title : ''"
|
:currentJournalName="wizardJournal ? wizardJournal.title : ''"
|
||||||
@@ -110,6 +112,7 @@
|
|||||||
:title="`${$t('autoPromotion.journalManage')}: ${wizardJournal ? wizardJournal.title : ''}`"
|
:title="`${$t('autoPromotion.journalManage')}: ${wizardJournal ? wizardJournal.title : ''}`"
|
||||||
@open-template-selector="openTemplateSelector"
|
@open-template-selector="openTemplateSelector"
|
||||||
@confirm-fields="savePromotionFieldsNow"
|
@confirm-fields="savePromotionFieldsNow"
|
||||||
|
@confirm-countries="savePromotionCountriesNow"
|
||||||
@cancel="showWizardDialog = false"
|
@cancel="showWizardDialog = false"
|
||||||
@confirm="saveWizardConfig"
|
@confirm="saveWizardConfig"
|
||||||
/>
|
/>
|
||||||
@@ -156,7 +159,9 @@ export default {
|
|||||||
selectedTemplateName: '',
|
selectedTemplateName: '',
|
||||||
selectedStyleName: '',
|
selectedStyleName: '',
|
||||||
selectedFieldIds: [],
|
selectedFieldIds: [],
|
||||||
|
selectedCountryIds: [],
|
||||||
availableFields: [],
|
availableFields: [],
|
||||||
|
availableCountries: [],
|
||||||
fieldsLoading: false,
|
fieldsLoading: false,
|
||||||
fieldsSaving: false,
|
fieldsSaving: false,
|
||||||
templateDialogInitialStyleId: '',
|
templateDialogInitialStyleId: '',
|
||||||
@@ -326,10 +331,33 @@ export default {
|
|||||||
if (values.length && Array.isArray(values[0])) return values[0];
|
if (values.length && Array.isArray(values[0])) return values[0];
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
/** 与 getJournalPromotionFields 返回体对齐;后端未返回时为空数组 */
|
||||||
|
parseCountryIdsFromPromotionPayload(selectedPayload) {
|
||||||
|
if (!selectedPayload || typeof selectedPayload !== 'object') return [];
|
||||||
|
const raw =
|
||||||
|
selectedPayload.country_fetch_ids != null
|
||||||
|
? selectedPayload.country_fetch_ids
|
||||||
|
: selectedPayload.country_ids != null
|
||||||
|
? selectedPayload.country_ids
|
||||||
|
: '';
|
||||||
|
if (typeof raw === 'string' && raw.trim()) {
|
||||||
|
return raw.split(',').map((s) => s.trim()).filter(Boolean).map(String);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
journalPromotionFieldsPayload(journalId) {
|
||||||
|
return {
|
||||||
|
journal_id: String(journalId),
|
||||||
|
fetch_ids: (this.selectedFieldIds || []).join(','),
|
||||||
|
country_fetch_ids: (this.selectedCountryIds || []).join(',')
|
||||||
|
};
|
||||||
|
},
|
||||||
async loadPromotionFields(journalId) {
|
async loadPromotionFields(journalId) {
|
||||||
this.fieldsLoading = true;
|
this.fieldsLoading = true;
|
||||||
this.availableFields = [];
|
this.availableFields = [];
|
||||||
|
this.availableCountries = [];
|
||||||
this.selectedFieldIds = [];
|
this.selectedFieldIds = [];
|
||||||
|
this.selectedCountryIds = [];
|
||||||
try {
|
try {
|
||||||
const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) });
|
const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) });
|
||||||
|
|
||||||
@@ -344,8 +372,10 @@ export default {
|
|||||||
const label = item.field || item.title || item.name || item.label || String(id);
|
const label = item.field || item.title || item.name || item.label || String(id);
|
||||||
return { id: String(id), label };
|
return { id: String(id), label };
|
||||||
});
|
});
|
||||||
|
this.availableCountries = this.availableFields.map((x) => ({ id: String(x.id), label: x.label }));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.availableFields = [];
|
this.availableFields = [];
|
||||||
|
this.availableCountries = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -364,10 +394,12 @@ export default {
|
|||||||
} else if (typeof selectedPayload.fetch_ids === 'string') {
|
} else if (typeof selectedPayload.fetch_ids === 'string') {
|
||||||
this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean);
|
this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
this.selectedCountryIds = this.parseCountryIdsFromPromotionPayload(selectedPayload);
|
||||||
console.log('[getJournalPromotionFields] parsed selected:', this.selectedFieldIds);
|
console.log('[getJournalPromotionFields] parsed selected:', this.selectedFieldIds);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[getJournalPromotionFields] error:', e);
|
console.error('[getJournalPromotionFields] error:', e);
|
||||||
this.selectedFieldIds = [];
|
this.selectedFieldIds = [];
|
||||||
|
this.selectedCountryIds = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fieldsLoading = false;
|
this.fieldsLoading = false;
|
||||||
@@ -376,10 +408,10 @@ export default {
|
|||||||
if (!this.wizardJournal || !this.wizardJournal.journal_id) return;
|
if (!this.wizardJournal || !this.wizardJournal.journal_id) return;
|
||||||
this.fieldsSaving = true;
|
this.fieldsSaving = true;
|
||||||
try {
|
try {
|
||||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
await this.$api.post(
|
||||||
journal_id: String(this.wizardJournal.journal_id),
|
'api/email_client/setJournalPromotionFields',
|
||||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
this.journalPromotionFieldsPayload(this.wizardJournal.journal_id)
|
||||||
});
|
);
|
||||||
this.$message.success(this.$t('autoPromotion.fieldsSaved'));
|
this.$message.success(this.$t('autoPromotion.fieldsSaved'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
||||||
@@ -387,6 +419,21 @@ export default {
|
|||||||
this.fieldsSaving = false;
|
this.fieldsSaving = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async savePromotionCountriesNow() {
|
||||||
|
if (!this.wizardJournal || !this.wizardJournal.journal_id) return;
|
||||||
|
this.fieldsSaving = true;
|
||||||
|
try {
|
||||||
|
await this.$api.post(
|
||||||
|
'api/email_client/setJournalPromotionFields',
|
||||||
|
this.journalPromotionFieldsPayload(this.wizardJournal.journal_id)
|
||||||
|
);
|
||||||
|
this.$message.success(this.$t('autoPromotion.countriesSaved'));
|
||||||
|
} catch (e) {
|
||||||
|
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
||||||
|
} finally {
|
||||||
|
this.fieldsSaving = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async handleSolicitAction(journal) {
|
async handleSolicitAction(journal) {
|
||||||
if (!this.isSolicitConfigured(journal)) {
|
if (!this.isSolicitConfigured(journal)) {
|
||||||
@@ -437,7 +484,9 @@ export default {
|
|||||||
this.selectedStyleName = s.styleName || '';
|
this.selectedStyleName = s.styleName || '';
|
||||||
this.selectedTemplateThumbHtml = `<div style="zoom:0.18; pointer-events:none; user-select:none;">${s.html || ''}</div>`;
|
this.selectedTemplateThumbHtml = `<div style="zoom:0.18; pointer-events:none; user-select:none;">${s.html || ''}</div>`;
|
||||||
this.selectedFieldIds = [];
|
this.selectedFieldIds = [];
|
||||||
|
this.selectedCountryIds = [];
|
||||||
this.availableFields = [];
|
this.availableFields = [];
|
||||||
|
this.availableCountries = [];
|
||||||
if (journal && journal.journal_id) {
|
if (journal && journal.journal_id) {
|
||||||
await this.loadPromotionFields(journal.journal_id);
|
await this.loadPromotionFields(journal.journal_id);
|
||||||
}
|
}
|
||||||
@@ -473,10 +522,10 @@ export default {
|
|||||||
start_promotion: this.wizardConfig.enabled ? '1' : '0',
|
start_promotion: this.wizardConfig.enabled ? '1' : '0',
|
||||||
user_id: userId
|
user_id: userId
|
||||||
});
|
});
|
||||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
await this.$api.post(
|
||||||
journal_id: String(this.wizardJournal.journal_id),
|
'api/email_client/setJournalPromotionFields',
|
||||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
this.journalPromotionFieldsPayload(this.wizardJournal.journal_id)
|
||||||
});
|
);
|
||||||
await this.refreshJournalByDetail(this.wizardJournal);
|
await this.refreshJournalByDetail(this.wizardJournal);
|
||||||
this.$message.success(this.$t('autoPromotion.configSaved'));
|
this.$message.success(this.$t('autoPromotion.configSaved'));
|
||||||
this.showWizardDialog = false;
|
this.showWizardDialog = false;
|
||||||
|
|||||||
@@ -41,7 +41,9 @@
|
|||||||
:config="config"
|
:config="config"
|
||||||
:wizardStartDate.sync="wizardStartDate"
|
:wizardStartDate.sync="wizardStartDate"
|
||||||
:selectedFieldIds.sync="selectedFieldIds"
|
:selectedFieldIds.sync="selectedFieldIds"
|
||||||
|
:selectedCountryIds.sync="selectedCountryIds"
|
||||||
:availableFields="availableFields"
|
:availableFields="availableFields"
|
||||||
|
:availableCountries="availableCountries"
|
||||||
:fieldsLoading="fieldsLoading"
|
:fieldsLoading="fieldsLoading"
|
||||||
:fieldsSaving="fieldsSaving"
|
:fieldsSaving="fieldsSaving"
|
||||||
:currentJournalName="currentJournalName"
|
:currentJournalName="currentJournalName"
|
||||||
@@ -52,6 +54,7 @@
|
|||||||
:title="$t('autoPromotion.title')"
|
:title="$t('autoPromotion.title')"
|
||||||
@open-template-selector="showTemplateDialog = true"
|
@open-template-selector="showTemplateDialog = true"
|
||||||
@confirm-fields="savePromotionFieldsNow"
|
@confirm-fields="savePromotionFieldsNow"
|
||||||
|
@confirm-countries="savePromotionCountriesNow"
|
||||||
@confirm="completeInitialization"
|
@confirm="completeInitialization"
|
||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -210,7 +213,9 @@
|
|||||||
:config="config"
|
:config="config"
|
||||||
:wizardStartDate.sync="wizardStartDate"
|
:wizardStartDate.sync="wizardStartDate"
|
||||||
:selectedFieldIds.sync="selectedFieldIds"
|
:selectedFieldIds.sync="selectedFieldIds"
|
||||||
|
:selectedCountryIds.sync="selectedCountryIds"
|
||||||
:availableFields="availableFields"
|
:availableFields="availableFields"
|
||||||
|
:availableCountries="availableCountries"
|
||||||
:fieldsLoading="fieldsLoading"
|
:fieldsLoading="fieldsLoading"
|
||||||
:fieldsSaving="fieldsSaving"
|
:fieldsSaving="fieldsSaving"
|
||||||
:currentJournalName="currentJournalName"
|
:currentJournalName="currentJournalName"
|
||||||
@@ -221,6 +226,7 @@
|
|||||||
:title="$t('autoPromotion.title')"
|
:title="$t('autoPromotion.title')"
|
||||||
@open-template-selector="showTemplateDialog = true"
|
@open-template-selector="showTemplateDialog = true"
|
||||||
@confirm-fields="savePromotionFieldsNow"
|
@confirm-fields="savePromotionFieldsNow"
|
||||||
|
@confirm-countries="savePromotionCountriesNow"
|
||||||
@cancel="showWizardDialog = false"
|
@cancel="showWizardDialog = false"
|
||||||
@confirm="completeInitialization"
|
@confirm="completeInitialization"
|
||||||
/>
|
/>
|
||||||
@@ -339,7 +345,9 @@ export default {
|
|||||||
templateDialogInitialTemplateId: '',
|
templateDialogInitialTemplateId: '',
|
||||||
togglingTaskId: '',
|
togglingTaskId: '',
|
||||||
selectedFieldIds: [],
|
selectedFieldIds: [],
|
||||||
|
selectedCountryIds: [],
|
||||||
availableFields: [],
|
availableFields: [],
|
||||||
|
availableCountries: [],
|
||||||
fieldsLoading: false,
|
fieldsLoading: false,
|
||||||
fieldsSaving: false,
|
fieldsSaving: false,
|
||||||
previewForm: {
|
previewForm: {
|
||||||
@@ -552,10 +560,32 @@ export default {
|
|||||||
if (values.length && Array.isArray(values[0])) return values[0];
|
if (values.length && Array.isArray(values[0])) return values[0];
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
parseCountryIdsFromPromotionPayload(selectedPayload) {
|
||||||
|
if (!selectedPayload || typeof selectedPayload !== 'object') return [];
|
||||||
|
const raw =
|
||||||
|
selectedPayload.country_fetch_ids != null
|
||||||
|
? selectedPayload.country_fetch_ids
|
||||||
|
: selectedPayload.country_ids != null
|
||||||
|
? selectedPayload.country_ids
|
||||||
|
: '';
|
||||||
|
if (typeof raw === 'string' && raw.trim()) {
|
||||||
|
return raw.split(',').map((s) => s.trim()).filter(Boolean).map(String);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
journalPromotionFieldsPayload(journalId) {
|
||||||
|
return {
|
||||||
|
journal_id: String(journalId),
|
||||||
|
fetch_ids: (this.selectedFieldIds || []).join(','),
|
||||||
|
country_fetch_ids: (this.selectedCountryIds || []).join(',')
|
||||||
|
};
|
||||||
|
},
|
||||||
async loadPromotionFields(journalId) {
|
async loadPromotionFields(journalId) {
|
||||||
this.fieldsLoading = true;
|
this.fieldsLoading = true;
|
||||||
this.availableFields = [];
|
this.availableFields = [];
|
||||||
|
this.availableCountries = [];
|
||||||
this.selectedFieldIds = [];
|
this.selectedFieldIds = [];
|
||||||
|
this.selectedCountryIds = [];
|
||||||
try {
|
try {
|
||||||
const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) });
|
const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) });
|
||||||
const availablePayload = (availableRes && availableRes.data) || availableRes || {};
|
const availablePayload = (availableRes && availableRes.data) || availableRes || {};
|
||||||
@@ -566,8 +596,10 @@ export default {
|
|||||||
const label = item.field || item.title || item.name || item.label || String(id);
|
const label = item.field || item.title || item.name || item.label || String(id);
|
||||||
return { id: String(id), label };
|
return { id: String(id), label };
|
||||||
});
|
});
|
||||||
|
this.availableCountries = this.availableFields.map((x) => ({ id: String(x.id), label: x.label }));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.availableFields = [];
|
this.availableFields = [];
|
||||||
|
this.availableCountries = [];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const selectedRes = await this.$api.post('api/email_client/getJournalPromotionFields', { journal_id: String(journalId) });
|
const selectedRes = await this.$api.post('api/email_client/getJournalPromotionFields', { journal_id: String(journalId) });
|
||||||
@@ -580,8 +612,10 @@ export default {
|
|||||||
} else if (typeof selectedPayload.fetch_ids === 'string') {
|
} else if (typeof selectedPayload.fetch_ids === 'string') {
|
||||||
this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean);
|
this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
this.selectedCountryIds = this.parseCountryIdsFromPromotionPayload(selectedPayload);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.selectedFieldIds = [];
|
this.selectedFieldIds = [];
|
||||||
|
this.selectedCountryIds = [];
|
||||||
}
|
}
|
||||||
this.fieldsLoading = false;
|
this.fieldsLoading = false;
|
||||||
},
|
},
|
||||||
@@ -589,10 +623,10 @@ export default {
|
|||||||
if (!this.selectedJournalId) return;
|
if (!this.selectedJournalId) return;
|
||||||
this.fieldsSaving = true;
|
this.fieldsSaving = true;
|
||||||
try {
|
try {
|
||||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
await this.$api.post(
|
||||||
journal_id: String(this.selectedJournalId),
|
'api/email_client/setJournalPromotionFields',
|
||||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
this.journalPromotionFieldsPayload(this.selectedJournalId)
|
||||||
});
|
);
|
||||||
this.$message.success(this.$t('autoPromotion.fieldsSaved'));
|
this.$message.success(this.$t('autoPromotion.fieldsSaved'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
||||||
@@ -600,6 +634,21 @@ export default {
|
|||||||
this.fieldsSaving = false;
|
this.fieldsSaving = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async savePromotionCountriesNow() {
|
||||||
|
if (!this.selectedJournalId) return;
|
||||||
|
this.fieldsSaving = true;
|
||||||
|
try {
|
||||||
|
await this.$api.post(
|
||||||
|
'api/email_client/setJournalPromotionFields',
|
||||||
|
this.journalPromotionFieldsPayload(this.selectedJournalId)
|
||||||
|
);
|
||||||
|
this.$message.success(this.$t('autoPromotion.countriesSaved'));
|
||||||
|
} catch (e) {
|
||||||
|
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
||||||
|
} finally {
|
||||||
|
this.fieldsSaving = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
async openWizardDialog() {
|
async openWizardDialog() {
|
||||||
this.wizardStep = 0;
|
this.wizardStep = 0;
|
||||||
if (this.config && this.config.start_date) {
|
if (this.config && this.config.start_date) {
|
||||||
@@ -704,10 +753,10 @@ export default {
|
|||||||
this.showWizardDialog = false;
|
this.showWizardDialog = false;
|
||||||
this.fetchList();
|
this.fetchList();
|
||||||
await this.$api.post(API.saveConfig, payload);
|
await this.$api.post(API.saveConfig, payload);
|
||||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
await this.$api.post(
|
||||||
journal_id: String(this.selectedJournalId || ''),
|
'api/email_client/setJournalPromotionFields',
|
||||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
this.journalPromotionFieldsPayload(this.selectedJournalId || '')
|
||||||
});
|
);
|
||||||
this.$message.success(this.$t('autoPromotionLogs.configUpdated'));
|
this.$message.success(this.$t('autoPromotionLogs.configUpdated'));
|
||||||
} finally {
|
} finally {
|
||||||
this.saving = false;
|
this.saving = false;
|
||||||
|
|||||||
@@ -17,11 +17,14 @@
|
|||||||
:selectedTemplateName="selectedTemplateName"
|
:selectedTemplateName="selectedTemplateName"
|
||||||
:selectedStyleName="selectedStyleName"
|
:selectedStyleName="selectedStyleName"
|
||||||
:availableFields="availableFields"
|
:availableFields="availableFields"
|
||||||
|
:availableCountries="availableCountries"
|
||||||
:fieldsLoading="fieldsLoading"
|
:fieldsLoading="fieldsLoading"
|
||||||
:fieldsSaving="fieldsSaving"
|
:fieldsSaving="fieldsSaving"
|
||||||
:selectedFieldIds.sync="selectedFieldIdsProxy"
|
:selectedFieldIds.sync="selectedFieldIdsProxy"
|
||||||
|
:selectedCountryIds.sync="selectedCountryIdsProxy"
|
||||||
@open-template-selector="emitOpenTemplateSelector"
|
@open-template-selector="emitOpenTemplateSelector"
|
||||||
@confirm-fields="emitConfirmFields"
|
@confirm-fields="emitConfirmFields"
|
||||||
|
@confirm-countries="emitConfirmCountries"
|
||||||
@update:wizardStartDate="onWizardStartDateUpdate"
|
@update:wizardStartDate="onWizardStartDateUpdate"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -49,11 +52,14 @@
|
|||||||
:selectedTemplateName="selectedTemplateName"
|
:selectedTemplateName="selectedTemplateName"
|
||||||
:selectedStyleName="selectedStyleName"
|
:selectedStyleName="selectedStyleName"
|
||||||
:availableFields="availableFields"
|
:availableFields="availableFields"
|
||||||
|
:availableCountries="availableCountries"
|
||||||
:fieldsLoading="fieldsLoading"
|
:fieldsLoading="fieldsLoading"
|
||||||
:fieldsSaving="fieldsSaving"
|
:fieldsSaving="fieldsSaving"
|
||||||
:selectedFieldIds.sync="selectedFieldIdsProxy"
|
:selectedFieldIds.sync="selectedFieldIdsProxy"
|
||||||
|
:selectedCountryIds.sync="selectedCountryIdsProxy"
|
||||||
@open-template-selector="emitOpenTemplateSelector"
|
@open-template-selector="emitOpenTemplateSelector"
|
||||||
@confirm-fields="emitConfirmFields"
|
@confirm-fields="emitConfirmFields"
|
||||||
|
@confirm-countries="emitConfirmCountries"
|
||||||
@update:wizardStartDate="onWizardStartDateUpdate"
|
@update:wizardStartDate="onWizardStartDateUpdate"
|
||||||
/>
|
/>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
@@ -89,9 +95,11 @@ export default {
|
|||||||
selectedStyleName: { type: String, default: '' },
|
selectedStyleName: { type: String, default: '' },
|
||||||
saving: { type: Boolean, default: false },
|
saving: { type: Boolean, default: false },
|
||||||
availableFields: { type: Array, default: () => [] },
|
availableFields: { type: Array, default: () => [] },
|
||||||
|
availableCountries: { type: Array, default: () => [] },
|
||||||
fieldsLoading: { type: Boolean, default: false },
|
fieldsLoading: { type: Boolean, default: false },
|
||||||
fieldsSaving: { type: Boolean, default: false },
|
fieldsSaving: { type: Boolean, default: false },
|
||||||
selectedFieldIds: { type: Array, default: () => [] }
|
selectedFieldIds: { type: Array, default: () => [] },
|
||||||
|
selectedCountryIds: { type: Array, default: () => [] }
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
dialogVisible: {
|
dialogVisible: {
|
||||||
@@ -118,6 +126,14 @@ export default {
|
|||||||
this.$emit('update:selectedFieldIds', val);
|
this.$emit('update:selectedFieldIds', val);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
selectedCountryIdsProxy: {
|
||||||
|
get() {
|
||||||
|
return this.selectedCountryIds;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:selectedCountryIds', val);
|
||||||
|
}
|
||||||
|
},
|
||||||
canConfirm() {
|
canConfirm() {
|
||||||
const id = this.config && this.config.defaultTemplateId != null ? String(this.config.defaultTemplateId) : '';
|
const id = this.config && this.config.defaultTemplateId != null ? String(this.config.defaultTemplateId) : '';
|
||||||
return id !== '' && id !== '0';
|
return id !== '' && id !== '0';
|
||||||
@@ -130,6 +146,9 @@ export default {
|
|||||||
emitConfirmFields() {
|
emitConfirmFields() {
|
||||||
this.$emit('confirm-fields');
|
this.$emit('confirm-fields');
|
||||||
},
|
},
|
||||||
|
emitConfirmCountries() {
|
||||||
|
this.$emit('confirm-countries');
|
||||||
|
},
|
||||||
onWizardStartDateUpdate(val) {
|
onWizardStartDateUpdate(val) {
|
||||||
// 由内容组件回传日期,继续走父组件的 .sync 链路
|
// 由内容组件回传日期,继续走父组件的 .sync 链路
|
||||||
this.wizardStartDateProxy = val;
|
this.wizardStartDateProxy = val;
|
||||||
|
|||||||
@@ -101,6 +101,33 @@
|
|||||||
|
|
||||||
<el-divider></el-divider>
|
<el-divider></el-divider>
|
||||||
|
|
||||||
|
<!-- <section class="form-section">
|
||||||
|
<h4 class="section-title">
|
||||||
|
<i class="el-icon-location-outline"></i> 3. {{ $t('autoPromotion.selectPromotionCountry') }}
|
||||||
|
<span class="selected-count">
|
||||||
|
{{ $t('autoPromotion.selectedCount', { count: selectedCountryIdsProxy.length }) }}
|
||||||
|
</span>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-edit-outline"
|
||||||
|
class="section-action-btn"
|
||||||
|
@click="countryDialogVisible = true"
|
||||||
|
>
|
||||||
|
{{ $t('autoPromotion.choosePromotionCountry') }}
|
||||||
|
</el-button>
|
||||||
|
</h4>
|
||||||
|
<div class="status-confirm-box">
|
||||||
|
<div v-if="selectedCountryTagRows.length" class="selected-tags">
|
||||||
|
<el-tag v-for="row in selectedCountryTagRows" :key="'c-' + row.id" size="mini" type="info" effect="plain">{{ row.text }}</el-tag>
|
||||||
|
</div>
|
||||||
|
<div class="field-tip">{{ $t('autoPromotion.selectPromotionCountryTip') }}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<el-divider></el-divider> -->
|
||||||
|
|
||||||
<section class="form-section">
|
<section class="form-section">
|
||||||
<h4 class="section-title">
|
<h4 class="section-title">
|
||||||
<i class="el-icon-finished"></i> 3. {{ $t('autoPromotion.confirmAndEnable') }}
|
<i class="el-icon-finished"></i> 3. {{ $t('autoPromotion.confirmAndEnable') }}
|
||||||
@@ -150,6 +177,41 @@
|
|||||||
<el-button size="small" type="primary" :loading="fieldsSaving" @click="emitConfirmFields">{{ $t('autoPromotion.confirm') }}</el-button>
|
<el-button size="small" type="primary" :loading="fieldsSaving" @click="emitConfirmFields">{{ $t('autoPromotion.confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
:title="$t('autoPromotion.selectPromotionCountry')"
|
||||||
|
:visible.sync="countryDialogVisible"
|
||||||
|
width="1200px"
|
||||||
|
append-to-body
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
>
|
||||||
|
<div class="field-dialog-toolbar">
|
||||||
|
<el-input
|
||||||
|
v-model="countrySearchText"
|
||||||
|
size="small"
|
||||||
|
clearable
|
||||||
|
class="field-search-input"
|
||||||
|
prefix-icon="el-icon-search"
|
||||||
|
:placeholder="$t('autoPromotion.countrySearchPlaceholder')"
|
||||||
|
/>
|
||||||
|
<el-button size="mini" @click="selectAllCountries">{{ $t('autoPromotion.selectAll') }}</el-button>
|
||||||
|
<el-button size="mini" @click="clearAllCountries">{{ $t('autoPromotion.clearAll') }}</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="field-dialog-body" v-loading="fieldsLoading">
|
||||||
|
<el-checkbox-group v-model="selectedCountryIdsProxy" class="field-check-group">
|
||||||
|
<el-checkbox v-for="c in sortedFilteredCountries" :key="'country-' + String(c.id)" :label="String(c.id)">
|
||||||
|
{{ c.label }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
<div v-if="!fieldsLoading && sortedFilteredCountries.length === 0" class="field-empty-tip">
|
||||||
|
{{ $t('autoPromotion.noCountryMatch') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span slot="footer">
|
||||||
|
<el-button size="small" @click="countryDialogVisible = false">{{ $t('autoPromotion.cancel') }}</el-button>
|
||||||
|
<el-button size="small" type="primary" :loading="fieldsSaving" @click="emitConfirmCountries">{{ $t('autoPromotion.confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -159,7 +221,9 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fieldSearchText: '',
|
fieldSearchText: '',
|
||||||
fieldDialogVisible: false
|
fieldDialogVisible: false,
|
||||||
|
countrySearchText: '',
|
||||||
|
countryDialogVisible: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -170,9 +234,11 @@ export default {
|
|||||||
selectedTemplateName: { type: String, default: '' },
|
selectedTemplateName: { type: String, default: '' },
|
||||||
selectedStyleName: { type: String, default: '' },
|
selectedStyleName: { type: String, default: '' },
|
||||||
availableFields: { type: Array, default: () => [] },
|
availableFields: { type: Array, default: () => [] },
|
||||||
|
availableCountries: { type: Array, default: () => [] },
|
||||||
fieldsLoading: { type: Boolean, default: false },
|
fieldsLoading: { type: Boolean, default: false },
|
||||||
fieldsSaving: { type: Boolean, default: false },
|
fieldsSaving: { type: Boolean, default: false },
|
||||||
selectedFieldIds: { type: Array, default: () => [] }
|
selectedFieldIds: { type: Array, default: () => [] },
|
||||||
|
selectedCountryIds: { type: Array, default: () => [] }
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hasSelectedTemplate() {
|
hasSelectedTemplate() {
|
||||||
@@ -190,6 +256,14 @@ export default {
|
|||||||
this.$emit('update:selectedFieldIds', val);
|
this.$emit('update:selectedFieldIds', val);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
selectedCountryIdsProxy: {
|
||||||
|
get() {
|
||||||
|
return this.selectedCountryIds;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:selectedCountryIds', val);
|
||||||
|
}
|
||||||
|
},
|
||||||
sortedFilteredFields() {
|
sortedFilteredFields() {
|
||||||
const kwRaw = String(this.fieldSearchText || '');
|
const kwRaw = String(this.fieldSearchText || '');
|
||||||
const normalize = (s) =>
|
const normalize = (s) =>
|
||||||
@@ -211,12 +285,42 @@ export default {
|
|||||||
});
|
});
|
||||||
return list.slice().sort((a, b) => String(a.label || '').localeCompare(String(b.label || '')));
|
return list.slice().sort((a, b) => String(a.label || '').localeCompare(String(b.label || '')));
|
||||||
},
|
},
|
||||||
|
sortedFilteredCountries() {
|
||||||
|
const kwRaw = String(this.countrySearchText || '');
|
||||||
|
const normalize = (s) =>
|
||||||
|
String(s || '')
|
||||||
|
.trim()
|
||||||
|
.replace(/\s+/g, ' ')
|
||||||
|
.toLowerCase();
|
||||||
|
const tokens = kwRaw
|
||||||
|
? kwRaw
|
||||||
|
.split(/[\r\n,,;;]+/g)
|
||||||
|
.map((s) => normalize(s))
|
||||||
|
.filter(Boolean)
|
||||||
|
: [];
|
||||||
|
const list = (this.availableCountries || []).filter((item) => {
|
||||||
|
if (!tokens.length) return true;
|
||||||
|
const label = normalize(item.label || '');
|
||||||
|
return tokens.some((t) => t === label);
|
||||||
|
});
|
||||||
|
return list.slice().sort((a, b) => String(a.label || '').localeCompare(String(b.label || '')));
|
||||||
|
},
|
||||||
selectedFieldLabels() {
|
selectedFieldLabels() {
|
||||||
const map = {};
|
const map = {};
|
||||||
(this.availableFields || []).forEach((i) => { map[String(i.id)] = i.label; });
|
(this.availableFields || []).forEach((i) => { map[String(i.id)] = i.label; });
|
||||||
return (this.selectedFieldIdsProxy || [])
|
return (this.selectedFieldIdsProxy || [])
|
||||||
.map((id) => map[String(id)])
|
.map((id) => map[String(id)])
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
},
|
||||||
|
selectedCountryTagRows() {
|
||||||
|
const map = {};
|
||||||
|
(this.availableCountries || []).forEach((i) => {
|
||||||
|
map[String(i.id)] = i.label;
|
||||||
|
});
|
||||||
|
return (this.selectedCountryIdsProxy || []).map((id) => ({
|
||||||
|
id: String(id),
|
||||||
|
text: map[String(id)] != null && map[String(id)] !== '' ? map[String(id)] : String(id)
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -232,6 +336,16 @@ export default {
|
|||||||
emitConfirmFields() {
|
emitConfirmFields() {
|
||||||
this.$emit('confirm-fields');
|
this.$emit('confirm-fields');
|
||||||
this.fieldDialogVisible = false;
|
this.fieldDialogVisible = false;
|
||||||
|
},
|
||||||
|
selectAllCountries() {
|
||||||
|
this.selectedCountryIdsProxy = (this.availableCountries || []).map((c) => String(c.id));
|
||||||
|
},
|
||||||
|
clearAllCountries() {
|
||||||
|
this.selectedCountryIdsProxy = [];
|
||||||
|
},
|
||||||
|
emitConfirmCountries() {
|
||||||
|
this.$emit('confirm-countries');
|
||||||
|
this.countryDialogVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user