feat: 接入新参数:套餐分配生效条件选择,资产详情前代后代换货标识
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m0s

This commit is contained in:
luo
2026-07-23 17:06:05 +08:00
parent d7c2c146fe
commit 5e15127a89
16 changed files with 230 additions and 56 deletions

View File

@@ -77,7 +77,7 @@ export interface BatchUpdateAssetRealnamePolicyRequest {
// 换货关联资产
export interface AssetExchangeTraceAsset {
asset_type: AssetType
asset_type: string
asset_id: number | null
identifier: string
exchange_no: string

View File

@@ -787,6 +787,7 @@
(e: 'updateBindingCardRealnameStatus', payload: { card: BindingCard }): void
(e: 'navigateToCard', iccid: string): void
(e: 'navigateToDevice', deviceNo: string): void
(e: 'navigateToAsset', identifier: string): void
(e: 'viewSyncTrail'): void
}
@@ -868,13 +869,7 @@
const handleNavigateToExchangeAsset = (asset: AssetExchangeTraceAsset) => {
if (!asset.can_view) return
if (asset.asset_type === 'card') {
emit('navigateToCard', asset.identifier)
return
}
emit('navigateToDevice', asset.identifier)
emit('navigateToAsset', asset.identifier)
}
// 复制ICCID

View File

@@ -41,6 +41,7 @@
@enable-binding-card="handleEnableBindingCard"
@disable-binding-card="handleDisableBindingCard"
@update-binding-card-realname-status="handleUpdateBindingCardRealnameStatus"
@navigate-to-asset="handleNavigateToAsset"
@navigate-to-card="handleNavigateToCard"
@navigate-to-device="handleNavigateToDevice"
@view-sync-trail="handleViewSyncTrail"
@@ -748,6 +749,13 @@
await handleSearch({ identifier: iccid })
}
/**
* 跳转到任意资产信息
*/
const handleNavigateToAsset = async (identifier: string) => {
await handleSearch({ identifier })
}
/**
* 跳转到绑定设备信息
*/

View File

@@ -50,14 +50,6 @@
@closed="handleCloseCreateDialog"
>
<ElForm ref="createFormRef" :model="createForm" :rules="createRules" label-width="120px">
<ElAlert
v-if="createFailureMessage"
:title="createFailureMessage"
type="error"
:closable="false"
show-icon
style="margin-bottom: 18px"
/>
<ElFormItem label="流程类型" prop="flow_type">
<ElSelect
v-model="createForm.flow_type"
@@ -129,6 +121,7 @@
placeholder="请输入ICCID搜索"
:remote-method="searchOldIotCards"
:loading="oldCardSearchLoading"
no-data-text="暂无可用的旧资产"
style="width: 100%"
clearable
@change="handleOldIdentifierChange"
@@ -161,6 +154,7 @@
placeholder="请输入虚拟号或IMEI搜索"
:remote-method="searchOldDevices"
:loading="oldDeviceSearchLoading"
no-data-text="暂无可用的旧资产"
style="width: 100%"
clearable
@change="handleOldIdentifierChange"
@@ -196,6 +190,7 @@
placeholder="请输入ICCID搜索"
:remote-method="searchNewIotCards"
:loading="newCardSearchLoading"
no-data-text="暂无同店铺可用的新资产"
style="width: 100%"
clearable
>
@@ -227,6 +222,7 @@
placeholder="请输入虚拟号或IMEI搜索"
:remote-method="searchNewDevices"
:loading="newDeviceSearchLoading"
no-data-text="暂无同店铺可用的新资产"
style="width: 100%"
clearable
>
@@ -298,6 +294,7 @@
placeholder="请输入ICCID搜索"
:remote-method="searchShipNewIotCards"
:loading="newCardSearchLoading"
no-data-text="暂无可用的新资产"
style="width: 100%"
clearable
>
@@ -329,6 +326,7 @@
placeholder="请输入虚拟号或IMEI搜索"
:remote-method="searchShipNewDevices"
:loading="newDeviceSearchLoading"
no-data-text="暂无可用的新资产"
style="width: 100%"
clearable
>
@@ -384,7 +382,7 @@
import { ExchangeService, CardService, DeviceService } from '@/api/modules'
import type { ExchangeResponse } from '@/api/modules/exchange'
import type { StandaloneIotCard, Device } from '@/types/api'
import { ElAlert, ElMessage, ElTag, ElButton, ElMessageBox, ElSwitch } from 'element-plus'
import { ElMessage, ElTag, ElButton, ElMessageBox, ElSwitch } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import type { SearchFormItem } from '@/types'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
@@ -409,7 +407,6 @@
const shipFormRef = ref<FormInstance>()
const createDialogVisible = ref(false)
const createLoading = ref(false)
const createFailureMessage = ref('')
const tableRef = ref()
const createFormRef = ref<FormInstance>()
@@ -519,8 +516,7 @@
const getShopDisplayName = (option?: ShopSelectableOption | null) => {
if (!option) return ''
if (option.shop_name) return option.shop_name
if (option.shop_id === null || option.shop_id === 0) return '平台'
return ''
return '库存'
}
const createSelectedOldAsset = computed<ShopSelectableOption | null>(() => {
@@ -582,6 +578,13 @@
const createOldAssetShopDisplay = computed(() => getShopDisplayName(createSelectedOldAsset.value))
const getCreateOldAssetShopId = () => {
const shopId = createSelectedOldAsset.value?.shop_id
if (typeof shopId === 'number') return shopId
if (shopId === null) return 0
return undefined
}
const createDirectInheritedShopHint = computed(() => {
const shopName = getShopDisplayName(createSelectedNewAsset.value)
return shopName ? `换货完成后将归属:${shopName}` : ''
@@ -895,7 +898,6 @@
// 显示创建对话框
const showCreateDialog = () => {
createFailureMessage.value = ''
createDialogVisible.value = true
}
@@ -908,7 +910,6 @@
// 流程类型变更
const handleFlowTypeChange = async () => {
createFailureMessage.value = ''
// 清空新资产标识符和数据迁移选项
createForm.new_identifier = ''
createForm.migrate_data = false
@@ -928,7 +929,6 @@
// 旧资产类型变更
const handleOldAssetTypeChange = async () => {
createFailureMessage.value = ''
// 清空旧资产标识符
createForm.old_identifier = ''
oldIotCardOptions.value = []
@@ -945,20 +945,32 @@
if (createForm.old_asset_type === 'iot_card') {
await loadDefaultIotCards()
// 如果是直接换货,也加载新资产列表
if (createForm.flow_type === 'direct') {
if (createForm.flow_type === 'direct' && createForm.old_identifier) {
await loadDefaultNewIotCards()
}
} else if (createForm.old_asset_type === 'device') {
await loadDefaultDevices()
// 如果是直接换货,也加载新资产列表
if (createForm.flow_type === 'direct') {
if (createForm.flow_type === 'direct' && createForm.old_identifier) {
await loadDefaultNewDevices()
}
}
}
const handleOldIdentifierChange = () => {
createFailureMessage.value = ''
const handleOldIdentifierChange = async () => {
createFormRef.value?.clearValidate('old_identifier')
createForm.new_identifier = ''
newIotCardOptions.value = []
newDeviceOptions.value = []
createFormRef.value?.clearValidate('new_identifier')
if (createForm.flow_type !== 'direct' || !createForm.old_identifier) return
if (createForm.old_asset_type === 'iot_card') {
await loadDefaultNewIotCards()
} else if (createForm.old_asset_type === 'device') {
await loadDefaultNewDevices()
}
}
const refreshExchangeDetail = async (id: number) => {
@@ -980,6 +992,7 @@
try {
const res = await CardService.getStandaloneIotCards({
is_standalone: true,
status: 1,
page: 1,
page_size: 10
})
@@ -1002,6 +1015,7 @@
oldDeviceSearchLoading.value = true
try {
const res = await DeviceService.getDevices({
status: 1,
page: 1,
page_size: 10
})
@@ -1031,6 +1045,7 @@
try {
const res = await CardService.getStandaloneIotCards({
is_standalone: true,
status: 1,
keyword: query,
page: 1,
page_size: 20
@@ -1060,6 +1075,7 @@
oldDeviceSearchLoading.value = true
try {
const res = await DeviceService.getDevices({
status: 1,
keyword: query,
page: 1,
page_size: 20
@@ -1086,10 +1102,19 @@
return
}
const shopId = getCreateOldAssetShopId()
if (shopId === undefined) {
newIotCardOptions.value = []
ElMessage.warning('请先选择旧资产')
return
}
newCardSearchLoading.value = true
try {
const res = await CardService.getStandaloneIotCards({
is_standalone: true,
status: 1,
shop_id: shopId,
keyword: query,
page: 1,
page_size: 20
@@ -1139,10 +1164,18 @@
// 加载默认新IoT卡列表
const loadDefaultNewIotCards = async () => {
const shopId = getCreateOldAssetShopId()
if (shopId === undefined) {
newIotCardOptions.value = []
return
}
newCardSearchLoading.value = true
try {
const res = await CardService.getStandaloneIotCards({
is_standalone: true,
status: 1,
shop_id: shopId,
page: 1,
page_size: 10
})
@@ -1185,9 +1218,18 @@
return
}
const shopId = getCreateOldAssetShopId()
if (shopId === undefined) {
newDeviceOptions.value = []
ElMessage.warning('请先选择旧资产')
return
}
newDeviceSearchLoading.value = true
try {
const res = await DeviceService.getDevices({
status: 1,
shop_id: shopId,
keyword: query,
page: 1,
page_size: 20
@@ -1236,9 +1278,17 @@
// 加载默认新设备列表
const loadDefaultNewDevices = async () => {
const shopId = getCreateOldAssetShopId()
if (shopId === undefined) {
newDeviceOptions.value = []
return
}
newDeviceSearchLoading.value = true
try {
const res = await DeviceService.getDevices({
status: 1,
shop_id: shopId,
page: 1,
page_size: 10
})
@@ -1277,7 +1327,6 @@
createFormRef.value?.validate(async (valid) => {
if (!valid || createLoading.value) return
createFailureMessage.value = ''
createLoading.value = true
try {
const exchangeReason =
@@ -1299,9 +1348,7 @@
requestData.migrate_data = createForm.migrate_data
}
const res = await ExchangeService.createExchange(requestData, {
requestOptions: { errorMessageMode: 'none' }
})
const res = await ExchangeService.createExchange(requestData)
if (res.code === 0) {
ElMessage.success('换货单创建成功')
createDialogVisible.value = false
@@ -1309,9 +1356,9 @@
return
}
createFailureMessage.value = res.msg || '换货单创建失败'
ElMessage.error(res.msg || '换货单创建失败')
} catch (error: any) {
createFailureMessage.value = error?.response?.data?.msg || '换货单创建失败'
console.error('创建换货单失败:', error)
} finally {
createLoading.value = false
}
@@ -1320,7 +1367,6 @@
// 关闭创建对话框
const handleCloseCreateDialog = () => {
createFailureMessage.value = ''
createFormRef.value?.resetFields()
// 清空搜索选项
oldIotCardOptions.value = []