feat(shopGoods): 新增商品置顶功能及批量上下架操作

- 在商品模型中新增 isTop 字段支持置顶状态(1置顶,0不置顶)
- 商品列表新增置顶列,支持列表内联切换置顶状态
- 启用排序号列排序功能,置顶列参与前端排序
- 新增单个商品上架/下架切换接口及批量上下架操作
- 优化商品列表工具栏和选中操作栏,加入批量上架、下架按钮
- 商品分类及图片列表调用 OSS 图片压缩接口处理展示图片
- 新增删除商品导入模板及图片导入模板下载链接与使用说明
- 优化图片压缩工具,新增去除 URL 中 x-oss-process 参数功能,确保调用参数生效
This commit is contained in:
2026-07-24 10:57:23 +08:00
parent 44e416525d
commit e2f6dce7a1
11 changed files with 453 additions and 107 deletions
+115 -9
View File
@@ -10,6 +10,7 @@
:columns="columns"
:datasource="datasource"
:customRow="customRow"
size="small"
v-model:selection="selection"
tool-class="ele-toolbar-form"
class="sys-org-table"
@@ -21,6 +22,8 @@
:navigationList="navigationList"
@add="openEdit"
@remove="removeBatch"
@batchUp="batchUpShelf"
@batchDown="batchDownShelf"
@batchMove="openMove"
@import="openImport"
@imageImport="openImageImport"
@@ -53,6 +56,18 @@
/></span>
</a-space>
</template>
<template v-if="column.key === 'isTop'">
<a-space @click.stop="onTop(record)">
<span
v-if="record.isTop === 1"
class="ele-text-success cursor-pointer"
><CheckOutlined
/></span>
<span v-else class="ele-text-placeholder cursor-pointer"
><CloseOutlined
/></span>
</a-space>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">已上架</a-tag>
<a-tag v-if="record.status === 1" color="orange">待上架</a-tag>
@@ -63,6 +78,19 @@
<a-space>
<a @click.stop="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a
v-if="record.status === 0"
class="ele-text-warning"
@click.stop="toggleShelf(record, 1)"
>下架</a
>
<a
v-else
class="ele-text-success"
@click.stop="toggleShelf(record, 0)"
>上架</a
>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm.stop="remove(record)"
@@ -242,6 +270,13 @@
key: 'recommend',
align: 'center'
},
{
title: '置顶',
dataIndex: 'isTop',
key: 'isTop',
align: 'center',
sorter: true
},
{
title: '状态',
dataIndex: 'status',
@@ -259,7 +294,8 @@
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
width: 120
width: 120,
sorter: true
},
{
title: '创建时间',
@@ -270,15 +306,15 @@
ellipsis: true,
width: 180,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 200,
fixed: 'right',
align: 'center',
hideInSetting: true
}
// {
// title: '操作',
// key: 'action',
// width: 180,
// fixed: 'right',
// align: 'center',
// hideInSetting: true
// }
]);
/* 搜索 */
@@ -506,6 +542,76 @@
});
};
/* 单个商品置顶/取消置顶(isTop: 1 置顶 0 不置顶) */
const onTop = (row: ShopGoods) => {
const hide = message.loading('请求中..', 0);
updateShopGoods({
...row,
isTop: row.isTop == 1 ? 0 : 1
})
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 单个商品上/下架切换(status: 0 上架 1 下架) */
const toggleShelf = (row: ShopGoods, status: number) => {
const hide = message.loading('请求中..', 0);
updateShopGoods({ ...row, status })
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量上架 */
const batchUpShelf = () => {
batchSetShelf(0, '上架');
};
/* 批量下架 */
const batchDownShelf = () => {
batchSetShelf(1, '下架');
};
/* 批量设置上下架 */
const batchSetShelf = (status: number, label: string) => {
if (!selection.value.length) {
message.error('请至少选择一条商品');
return;
}
Modal.confirm({
title: '提示',
content: `确定要批量${label}选中的 ${selection.value.length} 个商品吗?`,
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
Promise.all(selection.value.map((d) => updateShopGoods({ ...d, status })))
.then(() => {
hide();
message.success(`已批量${label} ${selection.value.length} 个商品`);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 自定义行属性 */
const customRow = (record: ShopGoods) => {
return {