fix: improve commodity country selection

This commit is contained in:
zhx 2026-06-25 11:15:59 +08:00
parent 0083dbb1cf
commit 70c5e362c9
2 changed files with 106 additions and 13 deletions

View File

@ -21,7 +21,7 @@
<div class="flex-l">{{ regionName }}</div> <div class="flex-l">{{ regionName }}</div>
</el-form-item> </el-form-item>
<el-form-item v-if="!isUpdate" label="支持国家" prop="payCountryIds"> <el-form-item v-if="!isUpdate" label="支持国家" prop="payCountryIds">
<el-select v-model="form.payCountryIds" multiple filterable collapse-tags style="width:100%" placeholder="请选择支持国家"> <el-select v-model="form.payCountryIds" multiple filterable collapse-tags style="width:100%" placeholder="请选择支持国家" @change="handlePayCountryIdsChange">
<el-option <el-option
v-for="item in countryList" v-for="item in countryList"
:key="getPayCountryId(item)" :key="getPayCountryId(item)"
@ -157,7 +157,9 @@ export default {
associateLoading: false, associateLoading: false,
supportAmounts: [], supportAmounts: [],
computedAmount: '', computedAmount: '',
amountUsd: '' amountUsd: '',
lastPayCountryIds: [],
syncingPayCountryIds: false
} }
}, },
computed: { computed: {
@ -212,6 +214,7 @@ export default {
if (!this.form.payCountryIds || this.form.payCountryIds.length === 0) { if (!this.form.payCountryIds || this.form.payCountryIds.length === 0) {
this.$set(this.form, 'payCountryIds', this.form.payCountryId ? [this.form.payCountryId] : []) this.$set(this.form, 'payCountryIds', this.form.payCountryId ? [this.form.payCountryId] : [])
} }
this.syncPayCountryIdsBySameName(this.form.payCountryIds || [])
if (!this.form.awardContent && this.form.awardContent !== 0) { if (!this.form.awardContent && this.form.awardContent !== 0) {
this.$set(this.form, 'awardContent', '0') this.$set(this.form, 'awardContent', '0')
} }
@ -256,6 +259,82 @@ export default {
const country = this.getCountryBase(item) const country = this.getCountryBase(item)
return country.nationalFlag || country.icon || item.nationalFlag || item.countryNationalFlag || item.payCountryNationalFlag || item.icon || '' return country.nationalFlag || country.icon || item.nationalFlag || item.countryNationalFlag || item.payCountryNationalFlag || item.icon || ''
}, },
handlePayCountryIdsChange(value) {
if (this.syncingPayCountryIds) {
return
}
const currentIds = this.normalizeCountryIds(value)
const lastIds = this.normalizeCountryIds(this.lastPayCountryIds)
const addedIds = currentIds.filter(id => !lastIds.includes(id))
const removedIds = lastIds.filter(id => !currentIds.includes(id))
let nextIds = currentIds.slice()
addedIds.forEach(id => {
nextIds = this.mergeCountryIds(nextIds, this.sameNameCountryIds(id))
})
removedIds.forEach(id => {
const removeIds = this.sameNameCountryIds(id)
nextIds = nextIds.filter(nextId => !removeIds.includes(String(nextId)))
})
this.syncPayCountryIdsBySameName(nextIds)
},
syncPayCountryIdsBySameName(value) {
const normalizedIds = this.normalizeCountryIds(value)
const expandedIds = normalizedIds.reduce((result, id) => {
return this.mergeCountryIds(result, this.sameNameCountryIds(id))
}, normalizedIds.slice())
const nextValues = this.countryIdValues(expandedIds)
this.lastPayCountryIds = this.normalizeCountryIds(nextValues)
if (this.sameCountryIdList(this.normalizeCountryIds(this.form.payCountryIds), this.lastPayCountryIds)) {
return
}
this.syncingPayCountryIds = true
this.$set(this.form, 'payCountryIds', nextValues)
this.$nextTick(() => {
this.syncingPayCountryIds = false
})
},
normalizeCountryIds(value) {
return (Array.isArray(value) ? value : []).map(item => String(item)).filter(Boolean)
},
mergeCountryIds(sourceIds, appendIds) {
const result = this.normalizeCountryIds(sourceIds)
appendIds.forEach(id => {
id = String(id)
if (id && !result.includes(id)) {
result.push(id)
}
})
return result
},
sameNameCountryIds(payCountryId) {
const selected = this.countryList.find(item => String(this.getPayCountryId(item)) === String(payCountryId))
if (!selected) {
return [String(payCountryId)]
}
const selectedName = this.countryNameKey(selected)
if (!selectedName) {
return [String(payCountryId)]
}
return this.countryList
.filter(item => this.countryNameKey(item) === selectedName)
.map(item => String(this.getPayCountryId(item)))
.filter(Boolean)
},
countryNameKey(item) {
return String(this.getCountryName(item) || '').trim().toLowerCase()
},
countryIdValues(countryIds) {
const normalizedIds = this.normalizeCountryIds(countryIds)
return normalizedIds.map(id => {
const option = this.countryList.find(item => String(this.getPayCountryId(item)) === id)
return option ? this.getPayCountryId(option) : id
})
},
sameCountryIdList(left, right) {
left = this.normalizeCountryIds(left)
right = this.normalizeCountryIds(right)
return left.length === right.length && left.every((id, index) => id === right[index])
},
changeAmount(val) { changeAmount(val) {
if (!val || !validPositiveNumberPointTwo(val)) { if (!val || !validPositiveNumberPointTwo(val)) {
this.supportAmounts = [] this.supportAmounts = []

View File

@ -34,6 +34,7 @@
style="width: 200px" style="width: 200px"
class="filter-item" class="filter-item"
clearable clearable
filterable
@change="changeCountry" @change="changeCountry"
> >
<el-option <el-option
@ -210,6 +211,7 @@ export default {
listLoading: false, listLoading: false,
countryList: [], countryList: [],
allCountryList: [], allCountryList: [],
allCountryListLoadingPromise: null,
loadingCountry: false, loadingCountry: false,
loading: false loading: false
} }
@ -274,37 +276,46 @@ export default {
loadOpenCountry(regionId) { loadOpenCountry(regionId) {
const that = this const that = this
that.loadingCountry = true that.loadingCountry = true
const request = regionId ? listPayOpenCountryByRegionId(regionId) : that.loadAllOpenCountry() const request = regionId ? that.loadRegionCountryList(regionId) : that.loadAllCountryList(true)
request.then(res => { request.then(res => {
const countryList = that.normalizeList(res.body) const countryList = that.normalizeList(res)
if (countryList.length > 0 || !regionId) { if (countryList.length > 0 || !regionId) {
that.loadingCountry = false that.loadingCountry = false
that.applyCountryList(countryList) that.applyCountryList(countryList)
return return
} }
that.loadAllOpenCountry().then(fallbackRes => { that.loadAllCountryList(true).then(fallbackList => {
that.loadingCountry = false that.loadingCountry = false
that.applyCountryList(that.normalizeList(fallbackRes.body)) that.applyCountryList(that.normalizeList(fallbackList))
}).catch(er => { }).catch(er => {
that.loadingCountry = false that.loadingCountry = false
console.error(er) console.error(er)
}) })
}).catch(er => { }).catch(er => {
console.error(er) console.error(er)
that.loadAllOpenCountry().then(fallbackRes => { that.loadAllCountryList(true).then(fallbackList => {
that.loadingCountry = false that.loadingCountry = false
that.applyCountryList(that.normalizeList(fallbackRes.body)) that.applyCountryList(that.normalizeList(fallbackList))
}).catch(fallbackErr => { }).catch(fallbackErr => {
that.loadingCountry = false that.loadingCountry = false
console.error(fallbackErr) console.error(fallbackErr)
}) })
}) })
}, },
loadAllOpenCountry(cursor = 1, limit = 500) { loadRegionCountryList(regionId) {
return listPayOpenCountryByRegionId(regionId).then(res => this.normalizeList(res.body))
},
loadAllOpenCountry(cursor = 1, limit = 200) {
return pagePayOpenCounty({ cursor, limit }) return pagePayOpenCounty({ cursor, limit })
}, },
loadAllCountryList() { loadAllCountryList(force = false) {
const limit = 500 if (!force && this.allCountryList.length > 0) {
return Promise.resolve(this.allCountryList)
}
if (!force && this.allCountryListLoadingPromise) {
return this.allCountryListLoadingPromise
}
const limit = 200
const loadPage = (cursor, countryList) => { const loadPage = (cursor, countryList) => {
return this.loadAllOpenCountry(cursor, limit).then(res => { return this.loadAllOpenCountry(cursor, limit).then(res => {
const body = res.body || {} const body = res.body || {}
@ -317,7 +328,10 @@ export default {
return this.allCountryList return this.allCountryList
}) })
} }
return loadPage(1, []) this.allCountryListLoadingPromise = loadPage(1, []).finally(() => {
this.allCountryListLoadingPromise = null
})
return this.allCountryListLoadingPromise
}, },
applyCountryList(countryList) { applyCountryList(countryList) {
this.countryList = countryList this.countryList = countryList
@ -458,7 +472,7 @@ export default {
if (!payCountryId) { if (!payCountryId) {
return null return null
} }
return this.countryList.find(item => String(this.getPayCountryId(item)) === String(payCountryId)) return this.countryList.concat(this.allCountryList).find(item => String(this.getPayCountryId(item)) === String(payCountryId))
}, },
getCommodityCountrySource(row) { getCommodityCountrySource(row) {
const payCountryId = row && row.payCountryId ? row.payCountryId : this.listQuery.payCountryId const payCountryId = row && row.payCountryId ? row.payCountryId : this.listQuery.payCountryId