fix: 取消关联,居左,店铺列表
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 2m53s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 2m53s
This commit is contained in:
@@ -77,14 +77,13 @@
|
||||
<span style="font-weight: bold; color: #409eff">{{ selectedDevices.length }}</span> 台
|
||||
</ElFormItem>
|
||||
<ElFormItem label="店铺" prop="target_shop_id">
|
||||
<ElTreeSelect
|
||||
<ElCascader
|
||||
v-model="allocateForm.target_shop_id"
|
||||
:data="shopTreeData"
|
||||
:props="{ label: 'shop_name', value: 'id', children: 'children' }"
|
||||
:options="shopCascadeOptions"
|
||||
:props="shopCascadeProps"
|
||||
placeholder="请选择目标店铺"
|
||||
clearable
|
||||
filterable
|
||||
check-strictly
|
||||
style="width: 100%"
|
||||
/>
|
||||
</ElFormItem>
|
||||
@@ -222,7 +221,6 @@
|
||||
:loading="seriesLoading"
|
||||
clearable
|
||||
>
|
||||
<ElOption label="清除关联" :value="0" />
|
||||
<ElOption
|
||||
v-for="series in packageSeriesList"
|
||||
:key="series.id"
|
||||
@@ -572,15 +570,7 @@
|
||||
PackageSeriesService,
|
||||
AssetService
|
||||
} from '@/api/modules'
|
||||
import {
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElTag,
|
||||
ElIcon,
|
||||
ElTreeSelect,
|
||||
ElRadioGroup,
|
||||
ElRadio
|
||||
} from 'element-plus'
|
||||
import { ElMessage, ElMessageBox, ElTag, ElIcon, ElRadioGroup, ElRadio } from 'element-plus'
|
||||
import { Loading } from '@element-plus/icons-vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import type {
|
||||
@@ -610,7 +600,35 @@
|
||||
const allocateDialogVisible = ref(false)
|
||||
const recallDialogVisible = ref(false)
|
||||
const selectedDevices = ref<Device[]>([])
|
||||
const shopTreeData = ref<any[]>([])
|
||||
const shopCascadeOptions = ref<any[]>([])
|
||||
const shopCascadeProps = {
|
||||
lazy: true,
|
||||
checkStrictly: true,
|
||||
lazyLoad: async (node: any, resolve: any) => {
|
||||
const { level, value } = node
|
||||
const parentId = level === 0 ? undefined : value
|
||||
|
||||
try {
|
||||
const res = await ShopService.getShopsCascade({ parent_id: parentId })
|
||||
if (res.code === 0) {
|
||||
const nodes = (res.data || []).map((item: any) => ({
|
||||
value: item.id,
|
||||
label: item.shop_name,
|
||||
leaf: !item.has_children
|
||||
}))
|
||||
resolve(nodes)
|
||||
} else {
|
||||
resolve([])
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载店铺级联数据失败:', error)
|
||||
resolve([])
|
||||
}
|
||||
},
|
||||
value: 'value',
|
||||
label: 'label',
|
||||
children: 'children'
|
||||
}
|
||||
const allocateResult = ref<AllocateDevicesResponse | null>(null)
|
||||
const recallResult = ref<RecallDevicesResponse | null>(null)
|
||||
|
||||
@@ -1146,7 +1164,6 @@
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
loadShopTree()
|
||||
})
|
||||
|
||||
// 当页面被 keep-alive 激活时自动刷新数据
|
||||
@@ -1154,49 +1171,6 @@
|
||||
getTableData()
|
||||
})
|
||||
|
||||
// 加载店铺树形数据
|
||||
const loadShopTree = async () => {
|
||||
try {
|
||||
const res = await ShopService.getShops({
|
||||
page: 1,
|
||||
page_size: 9999, // 获取所有数据用于构建树形结构
|
||||
status: 1 // 只获取启用的店铺
|
||||
})
|
||||
if (res.code === 0) {
|
||||
shopTreeData.value = buildShopTree(res.data.items || [])
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取店铺列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 构建店铺树形结构
|
||||
const buildShopTree = (shops: any[]) => {
|
||||
const map = new Map<number, any>()
|
||||
const tree: any[] = []
|
||||
|
||||
// 先将所有项放入 map
|
||||
shops.forEach((shop) => {
|
||||
map.set(shop.id, { ...shop, children: [] })
|
||||
})
|
||||
|
||||
// 构建树形结构
|
||||
shops.forEach((shop) => {
|
||||
const node = map.get(shop.id)!
|
||||
if (shop.parent_id && map.has(shop.parent_id)) {
|
||||
// 有父节点,添加到父节点的 children 中
|
||||
const parent = map.get(shop.parent_id)!
|
||||
if (!parent.children) parent.children = []
|
||||
parent.children.push(node)
|
||||
} else {
|
||||
// 没有父节点或父节点不存在,作为根节点
|
||||
tree.push(node)
|
||||
}
|
||||
})
|
||||
|
||||
return tree
|
||||
}
|
||||
|
||||
// 获取设备列表
|
||||
const getTableData = async () => {
|
||||
loading.value = true
|
||||
@@ -1278,7 +1252,43 @@
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消删除
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
|
||||
// 清除设备套餐系列绑定
|
||||
const handleClearDeviceSeries = async (deviceNo: string) => {
|
||||
const device = deviceList.value.find((d) => d.virtual_no === deviceNo)
|
||||
if (!device) {
|
||||
ElMessage.error('未找到该设备')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessageBox.confirm(`确定要清除设备 ${deviceNo} 的套餐系列关联吗?`, '确认清除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
const res = await DeviceService.batchSetDeviceSeriesBinding({
|
||||
device_ids: [device.id],
|
||||
series_id: 0
|
||||
})
|
||||
if (res.code === 0) {
|
||||
if (res.data.fail_count === 0) {
|
||||
ElMessage.success('清除关联成功')
|
||||
} else {
|
||||
ElMessage.warning(`部分失败:${res.data.failed_items?.[0]?.reason || '未知原因'}`)
|
||||
}
|
||||
await getTableData()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('清除关联失败:', error)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1534,6 +1544,9 @@
|
||||
case 'delete':
|
||||
await handleDeleteDeviceByNo(deviceNo)
|
||||
break
|
||||
case 'clear-series':
|
||||
await handleClearDeviceSeries(deviceNo)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1794,6 +1807,14 @@
|
||||
})
|
||||
}
|
||||
|
||||
if (hasAuth('device:clear_series')) {
|
||||
moreActions.push({
|
||||
label: '清除关联',
|
||||
handler: () => handleDeviceOperation('clear-series', row.virtual_no, row),
|
||||
type: 'primary'
|
||||
})
|
||||
}
|
||||
|
||||
// if (hasAuth('device:manual_deactivate')) {
|
||||
// moreActions.push({
|
||||
// label: '手动停用',
|
||||
|
||||
@@ -94,24 +94,15 @@
|
||||
label-width="120px"
|
||||
>
|
||||
<ElFormItem label="店铺" prop="to_shop_id">
|
||||
<ElSelect
|
||||
<ElCascader
|
||||
v-model="allocateForm.to_shop_id"
|
||||
placeholder="请选择或搜索目标店铺"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="searchTargetShops"
|
||||
:loading="targetShopLoading"
|
||||
:options="shopCascadeOptions"
|
||||
:props="shopCascadeProps"
|
||||
placeholder="请选择目标店铺"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="shop in targetShopList"
|
||||
:key="shop.id"
|
||||
:label="shop.shop_name"
|
||||
:value="shop.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="选卡方式" prop="selection_type">
|
||||
<ElRadioGroup v-model="allocateForm.selection_type">
|
||||
@@ -342,7 +333,6 @@
|
||||
:loading="seriesLoading"
|
||||
clearable
|
||||
>
|
||||
<ElOption label="清除关联" :value="0" />
|
||||
<ElOption
|
||||
v-for="series in packageSeriesList"
|
||||
:key="series.id"
|
||||
@@ -650,8 +640,35 @@
|
||||
const moreMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
|
||||
|
||||
// 店铺相关
|
||||
const targetShopLoading = ref(false)
|
||||
const targetShopList = ref<any[]>([])
|
||||
const shopCascadeOptions = ref<any[]>([])
|
||||
const shopCascadeProps = {
|
||||
lazy: true,
|
||||
checkStrictly: true,
|
||||
lazyLoad: async (node: any, resolve: any) => {
|
||||
const { level, value } = node
|
||||
const parentId = level === 0 ? undefined : value
|
||||
|
||||
try {
|
||||
const res = await ShopService.getShopsCascade({ parent_id: parentId })
|
||||
if (res.code === 0) {
|
||||
const nodes = (res.data || []).map((item: any) => ({
|
||||
value: item.id,
|
||||
label: item.shop_name,
|
||||
leaf: !item.has_children
|
||||
}))
|
||||
resolve(nodes)
|
||||
} else {
|
||||
resolve([])
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载店铺级联数据失败:', error)
|
||||
resolve([])
|
||||
}
|
||||
},
|
||||
value: 'value',
|
||||
label: 'label',
|
||||
children: 'children'
|
||||
}
|
||||
|
||||
// 搜索表单初始值
|
||||
const initialSearchState: {
|
||||
@@ -1213,33 +1230,6 @@
|
||||
selectedCards.value = selection
|
||||
}
|
||||
|
||||
// 加载目标店铺列表
|
||||
const loadTargetShops = async (shopName?: string) => {
|
||||
targetShopLoading.value = true
|
||||
try {
|
||||
const params: any = {
|
||||
page: 1,
|
||||
page_size: 20
|
||||
}
|
||||
if (shopName) {
|
||||
params.shop_name = shopName
|
||||
}
|
||||
const res = await ShopService.getShops(params)
|
||||
if (res.code === 0) {
|
||||
targetShopList.value = res.data.items || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取目标店铺列表失败:', error)
|
||||
} finally {
|
||||
targetShopLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索目标店铺
|
||||
const searchTargetShops = async (query: string) => {
|
||||
await loadTargetShops(query || undefined)
|
||||
}
|
||||
|
||||
// 显示批量分配对话框
|
||||
const showAllocateDialog = () => {
|
||||
if (selectedCards.value.length === 0) {
|
||||
@@ -1258,8 +1248,6 @@
|
||||
batch_no: '',
|
||||
remark: ''
|
||||
})
|
||||
// 加载默认店铺列表
|
||||
loadTargetShops()
|
||||
if (allocateFormRef.value) {
|
||||
allocateFormRef.value.resetFields()
|
||||
}
|
||||
@@ -1536,6 +1524,13 @@
|
||||
})
|
||||
}
|
||||
|
||||
if (hasAuth('iot_card:clear_series')) {
|
||||
items.push({
|
||||
key: 'clearSeries',
|
||||
label: '清除关联'
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
@@ -1565,9 +1560,52 @@
|
||||
case 'changePackage':
|
||||
changePackage()
|
||||
break
|
||||
case 'clearSeries':
|
||||
handleClearCardSeries()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 清除卡套餐系列绑定
|
||||
const handleClearCardSeries = async () => {
|
||||
if (selectedCards.value.length === 0) {
|
||||
ElMessage.warning('请先选择要清除关联的卡')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessageBox.confirm(
|
||||
`确定要清除所选 ${selectedCards.value.length} 张卡的套餐系列关联吗?`,
|
||||
'确认清除',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
try {
|
||||
const res = await CardService.batchSetCardSeriesBinding({
|
||||
iccids: selectedCards.value.map((card) => card.iccid),
|
||||
series_id: 0
|
||||
})
|
||||
if (res.code === 0) {
|
||||
if (res.data.fail_count === 0) {
|
||||
ElMessage.success('清除关联成功')
|
||||
} else {
|
||||
ElMessage.warning(`部分失败:${res.data.failed_items?.[0]?.reason || '未知原因'}`)
|
||||
}
|
||||
selectedCards.value = []
|
||||
await getTableData()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('清除关联失败:', error)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
|
||||
// 网卡分销 - 正在开发中
|
||||
const cardDistribution = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
:close-on-click-modal="false"
|
||||
@closed="handleDialogClosed"
|
||||
>
|
||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="165px">
|
||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :span="24">
|
||||
<ElFormItem label="套餐编码" prop="package_code">
|
||||
|
||||
Reference in New Issue
Block a user