feat(web-admin): allow ProductSelector to restrict by product ids
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
f18442be2e
commit
bbab39e6b7
1 file changed
+59
-2
@@ -21,7 +21,12 @@
|
||||
@search="handleQuickSearch"
|
||||
@clear="handleQuickSearchClear"
|
||||
/>
|
||||
<el-button class="btn-main" type="primary" @click="handleAddProduct">
|
||||
<el-button
|
||||
v-if="!isRestrictedMode"
|
||||
class="btn-main"
|
||||
type="primary"
|
||||
@click="handleAddProduct"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>新增
|
||||
</el-button>
|
||||
<el-button
|
||||
@@ -166,7 +171,7 @@
|
||||
</ListTable>
|
||||
|
||||
<ListPagination
|
||||
v-show="total > 0"
|
||||
v-show="total > 0 && !isRestrictedMode"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@@ -225,6 +230,7 @@
|
||||
import PlProductNameHazardCell from '@/components/business/pl-product-name-hazard-cell/index.vue'
|
||||
import {
|
||||
fetchCategoryTree,
|
||||
fetchProductDetail,
|
||||
fetchProductList,
|
||||
type ProductAliasItem,
|
||||
type ProductBrandItem
|
||||
@@ -258,6 +264,8 @@
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
supplierId?: string | number
|
||||
/** 非空时仅展示这些产品(按 id 拉详情,避免分页漏选) */
|
||||
allowedProductIds?: string[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -271,12 +279,20 @@
|
||||
const formDialogVisible = ref(false)
|
||||
const formProductId = ref<string | null>(null)
|
||||
const pendingSelectId = ref<string | null>(null)
|
||||
/** 限制模式下打开弹窗后「无产品」提示只打一次 */
|
||||
let emptyAllowedWarnedOnOpen = false
|
||||
|
||||
const normalizedAllowedIds = computed(() =>
|
||||
(props.allowedProductIds || []).map((id) => String(id).trim()).filter(Boolean)
|
||||
)
|
||||
const isRestrictedMode = computed(() => normalizedAllowedIds.value.length > 0)
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(val) => {
|
||||
dialogVisible.value = val
|
||||
if (val) {
|
||||
emptyAllowedWarnedOnOpen = false
|
||||
quickSearchKeyword.value = ''
|
||||
queryParams.value.pageNum = 1
|
||||
getList()
|
||||
@@ -316,9 +332,50 @@
|
||||
return names.length ? names.join('、') : '-'
|
||||
}
|
||||
|
||||
function matchesQuickKeyword(product: ProductVO, keyword: string) {
|
||||
const kw = keyword.toLowerCase()
|
||||
const name = String(product.productName || '').toLowerCase()
|
||||
const model = String(product.model || '').toLowerCase()
|
||||
return name.includes(kw) || model.includes(kw)
|
||||
}
|
||||
|
||||
/** 按允许的产品 id 并行拉详情,避免分页目录漏选 */
|
||||
const getRestrictedList = async () => {
|
||||
const ids = normalizedAllowedIds.value
|
||||
const results = await Promise.all(
|
||||
ids.map(async (id) => {
|
||||
try {
|
||||
const res: any = await fetchProductDetail({ id })
|
||||
const data = res?.data ?? res
|
||||
return data?.id != null ? (data as ProductVO) : null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
})
|
||||
)
|
||||
const fetched = results.filter((p): p is ProductVO => p != null)
|
||||
if (!fetched.length && !emptyAllowedWarnedOnOpen) {
|
||||
emptyAllowedWarnedOnOpen = true
|
||||
ElMessage.warning('所选合同暂无产品明细')
|
||||
}
|
||||
const keyword = quickSearchKeyword.value?.trim()
|
||||
const list = keyword ? fetched.filter((p) => matchesQuickKeyword(p, keyword)) : fetched
|
||||
productList.value = list
|
||||
total.value = list.length
|
||||
if (categoryTree.value.length > 0) {
|
||||
resolveCategoryNames()
|
||||
}
|
||||
await nextTick()
|
||||
await selectPendingRow()
|
||||
}
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
if (isRestrictedMode.value) {
|
||||
await getRestrictedList()
|
||||
return
|
||||
}
|
||||
const keyword = quickSearchKeyword.value?.trim()
|
||||
const res = await fetchProductList({
|
||||
page: queryParams.value.pageNum,
|
||||
|
||||
Reference in new issue
Block a user