国家
This commit is contained in:
@@ -19,8 +19,8 @@ const service = axios.create({
|
||||
// baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换
|
||||
// baseURL: 'http://www.tougao.com/', //测试本地 记得切换
|
||||
// baseURL: 'http://192.168.110.110/tougao/public/index.php/',
|
||||
baseURL: '/api', //本地
|
||||
// baseURL: '/', //正式
|
||||
// baseURL: '/api', //本地
|
||||
baseURL: '/', //正式
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -330,8 +330,8 @@ const en = {
|
||||
exportFailed: 'Export failed'
|
||||
},
|
||||
countryManagement: {
|
||||
title: 'Country maintenance',
|
||||
keywordPlaceholder: 'Chinese / English / code',
|
||||
title: 'Country Management',
|
||||
keywordPlaceholder: 'Chinese / English / Code',
|
||||
partitionLabel: 'Partition',
|
||||
partitionAll: 'All partitions',
|
||||
partition1: 'Partition 1',
|
||||
@@ -1098,14 +1098,20 @@ colTitle: 'Template title',
|
||||
changeTemplate: 'Change Template',
|
||||
selectPromotionFields: 'Select Promotion Fields',
|
||||
choosePromotionFields: 'Choose Fields',
|
||||
selectPromotionCountry: 'Select Country',
|
||||
choosePromotionCountry: 'Choose Countries',
|
||||
selectedCount: 'Selected {count}',
|
||||
selectAll: 'Select All',
|
||||
clearAll: 'Clear All',
|
||||
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',
|
||||
countrySearchPlaceholder: 'Search countries',
|
||||
noFieldMatch: 'No matching fields',
|
||||
noCountryMatch: 'No matching countries',
|
||||
confirm: 'Confirm',
|
||||
fieldsSaved: 'Promotion fields saved',
|
||||
countriesSaved: 'Promotion countries saved',
|
||||
confirmAndEnable: 'Confirm and Enable',
|
||||
onlySaveConfig: 'Save configuration only',
|
||||
enableNowNextDay: 'Enable auto promotion now (starts next day)'
|
||||
|
||||
@@ -1083,14 +1083,20 @@ const zh = {
|
||||
changeTemplate: '更换模版',
|
||||
selectPromotionFields: '选择推广领域',
|
||||
choosePromotionFields: '选择领域',
|
||||
selectPromotionCountry: '选择国家',
|
||||
choosePromotionCountry: '选择国家',
|
||||
selectedCount: '已选 {count} 项',
|
||||
selectAll: '全选',
|
||||
clearAll: '取消全选',
|
||||
selectPromotionFieldsTip: '可多选;未选择则不限制推广领域。',
|
||||
selectPromotionCountryTip: '可多选;未选择则不限制国家。与领域接口一致,后续可对接独立国家数据。',
|
||||
fieldSearchPlaceholder: '搜索推广领域',
|
||||
countrySearchPlaceholder: '搜索国家',
|
||||
noFieldMatch: '没有匹配的领域',
|
||||
noCountryMatch: '没有匹配的国家',
|
||||
confirm: '确定',
|
||||
fieldsSaved: '推广领域已保存',
|
||||
countriesSaved: '推广国家已保存',
|
||||
confirmAndEnable: '确认并开启',
|
||||
onlySaveConfig: '仅保存配置',
|
||||
enableNowNextDay: '立即激活自动推广(次日开始自动推广)'
|
||||
|
||||
@@ -99,7 +99,9 @@
|
||||
:config="wizardConfig"
|
||||
:wizardStartDate.sync="wizardStartDate"
|
||||
:selectedFieldIds.sync="selectedFieldIds"
|
||||
:selectedCountryIds.sync="selectedCountryIds"
|
||||
:availableFields="availableFields"
|
||||
:availableCountries="availableCountries"
|
||||
:fieldsLoading="fieldsLoading"
|
||||
:fieldsSaving="fieldsSaving"
|
||||
:currentJournalName="wizardJournal ? wizardJournal.title : ''"
|
||||
@@ -110,6 +112,7 @@
|
||||
:title="`${$t('autoPromotion.journalManage')}: ${wizardJournal ? wizardJournal.title : ''}`"
|
||||
@open-template-selector="openTemplateSelector"
|
||||
@confirm-fields="savePromotionFieldsNow"
|
||||
@confirm-countries="savePromotionCountriesNow"
|
||||
@cancel="showWizardDialog = false"
|
||||
@confirm="saveWizardConfig"
|
||||
/>
|
||||
@@ -156,7 +159,9 @@ export default {
|
||||
selectedTemplateName: '',
|
||||
selectedStyleName: '',
|
||||
selectedFieldIds: [],
|
||||
selectedCountryIds: [],
|
||||
availableFields: [],
|
||||
availableCountries: [],
|
||||
fieldsLoading: false,
|
||||
fieldsSaving: false,
|
||||
templateDialogInitialStyleId: '',
|
||||
@@ -326,10 +331,33 @@ export default {
|
||||
if (values.length && Array.isArray(values[0])) return values[0];
|
||||
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) {
|
||||
this.fieldsLoading = true;
|
||||
this.availableFields = [];
|
||||
this.availableCountries = [];
|
||||
this.selectedFieldIds = [];
|
||||
this.selectedCountryIds = [];
|
||||
try {
|
||||
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);
|
||||
return { id: String(id), label };
|
||||
});
|
||||
this.availableCountries = this.availableFields.map((x) => ({ id: String(x.id), label: x.label }));
|
||||
} catch (e) {
|
||||
this.availableFields = [];
|
||||
this.availableCountries = [];
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -364,10 +394,12 @@ export default {
|
||||
} else if (typeof selectedPayload.fetch_ids === 'string') {
|
||||
this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean);
|
||||
}
|
||||
this.selectedCountryIds = this.parseCountryIdsFromPromotionPayload(selectedPayload);
|
||||
console.log('[getJournalPromotionFields] parsed selected:', this.selectedFieldIds);
|
||||
} catch (e) {
|
||||
console.error('[getJournalPromotionFields] error:', e);
|
||||
this.selectedFieldIds = [];
|
||||
this.selectedCountryIds = [];
|
||||
}
|
||||
|
||||
this.fieldsLoading = false;
|
||||
@@ -376,10 +408,10 @@ export default {
|
||||
if (!this.wizardJournal || !this.wizardJournal.journal_id) return;
|
||||
this.fieldsSaving = true;
|
||||
try {
|
||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
||||
journal_id: String(this.wizardJournal.journal_id),
|
||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
||||
});
|
||||
await this.$api.post(
|
||||
'api/email_client/setJournalPromotionFields',
|
||||
this.journalPromotionFieldsPayload(this.wizardJournal.journal_id)
|
||||
);
|
||||
this.$message.success(this.$t('autoPromotion.fieldsSaved'));
|
||||
} catch (e) {
|
||||
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
||||
@@ -387,6 +419,21 @@ export default {
|
||||
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) {
|
||||
if (!this.isSolicitConfigured(journal)) {
|
||||
@@ -437,7 +484,9 @@ export default {
|
||||
this.selectedStyleName = s.styleName || '';
|
||||
this.selectedTemplateThumbHtml = `<div style="zoom:0.18; pointer-events:none; user-select:none;">${s.html || ''}</div>`;
|
||||
this.selectedFieldIds = [];
|
||||
this.selectedCountryIds = [];
|
||||
this.availableFields = [];
|
||||
this.availableCountries = [];
|
||||
if (journal && journal.journal_id) {
|
||||
await this.loadPromotionFields(journal.journal_id);
|
||||
}
|
||||
@@ -473,10 +522,10 @@ export default {
|
||||
start_promotion: this.wizardConfig.enabled ? '1' : '0',
|
||||
user_id: userId
|
||||
});
|
||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
||||
journal_id: String(this.wizardJournal.journal_id),
|
||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
||||
});
|
||||
await this.$api.post(
|
||||
'api/email_client/setJournalPromotionFields',
|
||||
this.journalPromotionFieldsPayload(this.wizardJournal.journal_id)
|
||||
);
|
||||
await this.refreshJournalByDetail(this.wizardJournal);
|
||||
this.$message.success(this.$t('autoPromotion.configSaved'));
|
||||
this.showWizardDialog = false;
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
:config="config"
|
||||
:wizardStartDate.sync="wizardStartDate"
|
||||
:selectedFieldIds.sync="selectedFieldIds"
|
||||
:selectedCountryIds.sync="selectedCountryIds"
|
||||
:availableFields="availableFields"
|
||||
:availableCountries="availableCountries"
|
||||
:fieldsLoading="fieldsLoading"
|
||||
:fieldsSaving="fieldsSaving"
|
||||
:currentJournalName="currentJournalName"
|
||||
@@ -52,6 +54,7 @@
|
||||
:title="$t('autoPromotion.title')"
|
||||
@open-template-selector="showTemplateDialog = true"
|
||||
@confirm-fields="savePromotionFieldsNow"
|
||||
@confirm-countries="savePromotionCountriesNow"
|
||||
@confirm="completeInitialization"
|
||||
/>
|
||||
</el-card>
|
||||
@@ -210,7 +213,9 @@
|
||||
:config="config"
|
||||
:wizardStartDate.sync="wizardStartDate"
|
||||
:selectedFieldIds.sync="selectedFieldIds"
|
||||
:selectedCountryIds.sync="selectedCountryIds"
|
||||
:availableFields="availableFields"
|
||||
:availableCountries="availableCountries"
|
||||
:fieldsLoading="fieldsLoading"
|
||||
:fieldsSaving="fieldsSaving"
|
||||
:currentJournalName="currentJournalName"
|
||||
@@ -221,6 +226,7 @@
|
||||
:title="$t('autoPromotion.title')"
|
||||
@open-template-selector="showTemplateDialog = true"
|
||||
@confirm-fields="savePromotionFieldsNow"
|
||||
@confirm-countries="savePromotionCountriesNow"
|
||||
@cancel="showWizardDialog = false"
|
||||
@confirm="completeInitialization"
|
||||
/>
|
||||
@@ -339,7 +345,9 @@ export default {
|
||||
templateDialogInitialTemplateId: '',
|
||||
togglingTaskId: '',
|
||||
selectedFieldIds: [],
|
||||
selectedCountryIds: [],
|
||||
availableFields: [],
|
||||
availableCountries: [],
|
||||
fieldsLoading: false,
|
||||
fieldsSaving: false,
|
||||
previewForm: {
|
||||
@@ -552,10 +560,32 @@ export default {
|
||||
if (values.length && Array.isArray(values[0])) return values[0];
|
||||
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) {
|
||||
this.fieldsLoading = true;
|
||||
this.availableFields = [];
|
||||
this.availableCountries = [];
|
||||
this.selectedFieldIds = [];
|
||||
this.selectedCountryIds = [];
|
||||
try {
|
||||
const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) });
|
||||
const availablePayload = (availableRes && availableRes.data) || availableRes || {};
|
||||
@@ -566,8 +596,10 @@ export default {
|
||||
const label = item.field || item.title || item.name || item.label || String(id);
|
||||
return { id: String(id), label };
|
||||
});
|
||||
this.availableCountries = this.availableFields.map((x) => ({ id: String(x.id), label: x.label }));
|
||||
} catch (e) {
|
||||
this.availableFields = [];
|
||||
this.availableCountries = [];
|
||||
}
|
||||
try {
|
||||
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') {
|
||||
this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean);
|
||||
}
|
||||
this.selectedCountryIds = this.parseCountryIdsFromPromotionPayload(selectedPayload);
|
||||
} catch (e) {
|
||||
this.selectedFieldIds = [];
|
||||
this.selectedCountryIds = [];
|
||||
}
|
||||
this.fieldsLoading = false;
|
||||
},
|
||||
@@ -589,10 +623,10 @@ export default {
|
||||
if (!this.selectedJournalId) return;
|
||||
this.fieldsSaving = true;
|
||||
try {
|
||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
||||
journal_id: String(this.selectedJournalId),
|
||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
||||
});
|
||||
await this.$api.post(
|
||||
'api/email_client/setJournalPromotionFields',
|
||||
this.journalPromotionFieldsPayload(this.selectedJournalId)
|
||||
);
|
||||
this.$message.success(this.$t('autoPromotion.fieldsSaved'));
|
||||
} catch (e) {
|
||||
this.$message.error(this.$t('autoPromotion.saveFailed'));
|
||||
@@ -600,6 +634,21 @@ export default {
|
||||
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() {
|
||||
this.wizardStep = 0;
|
||||
if (this.config && this.config.start_date) {
|
||||
@@ -704,10 +753,10 @@ export default {
|
||||
this.showWizardDialog = false;
|
||||
this.fetchList();
|
||||
await this.$api.post(API.saveConfig, payload);
|
||||
await this.$api.post('api/email_client/setJournalPromotionFields', {
|
||||
journal_id: String(this.selectedJournalId || ''),
|
||||
fetch_ids: (this.selectedFieldIds || []).join(',')
|
||||
});
|
||||
await this.$api.post(
|
||||
'api/email_client/setJournalPromotionFields',
|
||||
this.journalPromotionFieldsPayload(this.selectedJournalId || '')
|
||||
);
|
||||
this.$message.success(this.$t('autoPromotionLogs.configUpdated'));
|
||||
} finally {
|
||||
this.saving = false;
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
:selectedTemplateName="selectedTemplateName"
|
||||
:selectedStyleName="selectedStyleName"
|
||||
:availableFields="availableFields"
|
||||
:availableCountries="availableCountries"
|
||||
:fieldsLoading="fieldsLoading"
|
||||
:fieldsSaving="fieldsSaving"
|
||||
:selectedFieldIds.sync="selectedFieldIdsProxy"
|
||||
:selectedCountryIds.sync="selectedCountryIdsProxy"
|
||||
@open-template-selector="emitOpenTemplateSelector"
|
||||
@confirm-fields="emitConfirmFields"
|
||||
@confirm-countries="emitConfirmCountries"
|
||||
@update:wizardStartDate="onWizardStartDateUpdate"
|
||||
/>
|
||||
|
||||
@@ -49,11 +52,14 @@
|
||||
:selectedTemplateName="selectedTemplateName"
|
||||
:selectedStyleName="selectedStyleName"
|
||||
:availableFields="availableFields"
|
||||
:availableCountries="availableCountries"
|
||||
:fieldsLoading="fieldsLoading"
|
||||
:fieldsSaving="fieldsSaving"
|
||||
:selectedFieldIds.sync="selectedFieldIdsProxy"
|
||||
:selectedCountryIds.sync="selectedCountryIdsProxy"
|
||||
@open-template-selector="emitOpenTemplateSelector"
|
||||
@confirm-fields="emitConfirmFields"
|
||||
@confirm-countries="emitConfirmCountries"
|
||||
@update:wizardStartDate="onWizardStartDateUpdate"
|
||||
/>
|
||||
<div class="dialog-footer">
|
||||
@@ -89,9 +95,11 @@ export default {
|
||||
selectedStyleName: { type: String, default: '' },
|
||||
saving: { type: Boolean, default: false },
|
||||
availableFields: { type: Array, default: () => [] },
|
||||
availableCountries: { type: Array, default: () => [] },
|
||||
fieldsLoading: { type: Boolean, default: false },
|
||||
fieldsSaving: { type: Boolean, default: false },
|
||||
selectedFieldIds: { type: Array, default: () => [] }
|
||||
selectedFieldIds: { type: Array, default: () => [] },
|
||||
selectedCountryIds: { type: Array, default: () => [] }
|
||||
},
|
||||
computed: {
|
||||
dialogVisible: {
|
||||
@@ -118,6 +126,14 @@ export default {
|
||||
this.$emit('update:selectedFieldIds', val);
|
||||
}
|
||||
},
|
||||
selectedCountryIdsProxy: {
|
||||
get() {
|
||||
return this.selectedCountryIds;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:selectedCountryIds', val);
|
||||
}
|
||||
},
|
||||
canConfirm() {
|
||||
const id = this.config && this.config.defaultTemplateId != null ? String(this.config.defaultTemplateId) : '';
|
||||
return id !== '' && id !== '0';
|
||||
@@ -130,6 +146,9 @@ export default {
|
||||
emitConfirmFields() {
|
||||
this.$emit('confirm-fields');
|
||||
},
|
||||
emitConfirmCountries() {
|
||||
this.$emit('confirm-countries');
|
||||
},
|
||||
onWizardStartDateUpdate(val) {
|
||||
// 由内容组件回传日期,继续走父组件的 .sync 链路
|
||||
this.wizardStartDateProxy = val;
|
||||
|
||||
@@ -101,6 +101,33 @@
|
||||
|
||||
<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">
|
||||
<h4 class="section-title">
|
||||
<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>
|
||||
</span>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
@@ -159,7 +221,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
fieldSearchText: '',
|
||||
fieldDialogVisible: false
|
||||
fieldDialogVisible: false,
|
||||
countrySearchText: '',
|
||||
countryDialogVisible: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
@@ -170,9 +234,11 @@ export default {
|
||||
selectedTemplateName: { type: String, default: '' },
|
||||
selectedStyleName: { type: String, default: '' },
|
||||
availableFields: { type: Array, default: () => [] },
|
||||
availableCountries: { type: Array, default: () => [] },
|
||||
fieldsLoading: { type: Boolean, default: false },
|
||||
fieldsSaving: { type: Boolean, default: false },
|
||||
selectedFieldIds: { type: Array, default: () => [] }
|
||||
selectedFieldIds: { type: Array, default: () => [] },
|
||||
selectedCountryIds: { type: Array, default: () => [] }
|
||||
},
|
||||
computed: {
|
||||
hasSelectedTemplate() {
|
||||
@@ -190,6 +256,14 @@ export default {
|
||||
this.$emit('update:selectedFieldIds', val);
|
||||
}
|
||||
},
|
||||
selectedCountryIdsProxy: {
|
||||
get() {
|
||||
return this.selectedCountryIds;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:selectedCountryIds', val);
|
||||
}
|
||||
},
|
||||
sortedFilteredFields() {
|
||||
const kwRaw = String(this.fieldSearchText || '');
|
||||
const normalize = (s) =>
|
||||
@@ -211,12 +285,42 @@ export default {
|
||||
});
|
||||
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() {
|
||||
const map = {};
|
||||
(this.availableFields || []).forEach((i) => { map[String(i.id)] = i.label; });
|
||||
return (this.selectedFieldIdsProxy || [])
|
||||
.map((id) => map[String(id)])
|
||||
.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: {
|
||||
@@ -232,6 +336,16 @@ export default {
|
||||
emitConfirmFields() {
|
||||
this.$emit('confirm-fields');
|
||||
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