优化店铺商品及分类管理

This commit is contained in:
2024-07-27 23:07:06 +08:00
parent b9df13a916
commit d74b844ee0
12 changed files with 677 additions and 82 deletions

View File

@@ -52,6 +52,8 @@ export interface GoodsCategory {
label?: string;
// 子菜单
children?: GoodsCategory[];
// 商铺ID
merchantId?: number;
}
/**

View File

@@ -12,11 +12,12 @@
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { ref, watch, reactive } from 'vue';
import type { ValueType } from 'ant-design-vue/es/vc-cascader/Cascader';
import { listGoodsCategory } from '@/api/shop/goodsCategory';
import { toTreeData } from 'ele-admin-pro/es';
import { GoodsCategory } from '@/api/shop/goodsCategory/model';
import { FileRecordParam } from '@/api/system/file/model';
const props = withDefaults(
defineProps<{
@@ -26,6 +27,7 @@
valueField?: 'label';
type?: 'provinceCity' | 'province';
showSearch?: boolean;
merchantId?: number;
}>(),
{
showSearch: true
@@ -38,6 +40,11 @@
(e: 'load-data-done', value: GoodsCategory[]): void;
}>();
// 搜索表单
const where = reactive<GoodsCategory>({
merchantId: undefined
});
// 级联选择器数据
const regionsData = ref<GoodsCategory[]>([]);
@@ -47,7 +54,7 @@
};
const onChange = (item: any, value: ValueType) => {
console.log(item,value);
console.log(item, value);
emit('done', item, value);
};
@@ -107,7 +114,10 @@
watch(
() => props.options,
() => {
listGoodsCategory().then((data) => {
if (props.merchantId) {
where.merchantId = props.merchantId;
}
listGoodsCategory(where).then((data) => {
const list = toTreeData({
data: data?.map((d) => {
d.value = d.categoryId;

View File

@@ -45,6 +45,7 @@
</div>
</a-form-item>
<a-form-item
v-if="!merchantId"
label="选择店铺"
name="merchantId"
>
@@ -64,7 +65,7 @@
v-model:value="form.goodsName"
/>
</a-form-item>
<a-form-item label="商品分类" name="categoryId">
<a-form-item label="商品分类" name="categoryId" v-if="!merchantId">
<SelectGoodsCategory
:data="data"
placeholder="请选择商品分类"
@@ -73,6 +74,15 @@
@done="chooseGoodsCategory"
/>
</a-form-item>
<a-form-item label="菜品分类" name="categoryId" v-else>
<SelectGoodsCategory
:merchantId="merchantId"
placeholder="请选择商品分类"
style="width: 558px"
v-model:value="form.categoryId"
@done="chooseTakeawayCategory"
/>
</a-form-item>
<a-form-item label="商品卖点" name="comments">
<a-input
allow-clear
@@ -335,6 +345,9 @@
import { GoodsSpec } from "@/api/shop/goodsSpec/model";
import { generateGoodsSku, listGoodsSku } from "@/api/shop/goodsSku";
import { listGoodsSpec } from "@/api/shop/goodsSpec";
import CategorySelect from "@/views/cms/article/components/category-select.vue";
import { GoodsCategory } from "@/api/shop/goodsCategory/model";
import { listGoodsCategory } from "@/api/shop/goodsCategory";
// 是否是修改
const isUpdate = ref(false);
@@ -348,6 +361,8 @@
visible: boolean;
// 修改回显的数据
data?: Goods | null;
// 商户ID
merchantId?: number;
}>();
const emit = defineEmits<{
@@ -375,6 +390,7 @@
const files = ref<ItemType[]>([]);
const goodsSpec = ref<GoodsSpec>();
const category = ref<string[]>([]);
const takeaway = ref<GoodsCategory[]>([]);
const columns = [
{
@@ -552,11 +568,16 @@
form.merchantId = item.merchantId;
};
const chooseGoodsCategory = (item,value) => {
const chooseGoodsCategory = (item: GoodsCategory,value: any) => {
form.categoryId = value[1].value;
form.categoryParent = value[0].label;
form.categoryChildren = value[1].label;
}
const chooseTakeawayCategory = (item: GoodsCategory, value: any) => {
form.categoryParent = '店铺分类';
form.categoryChildren = value[0].label;
form.categoryId = item[0];
}
const chooseImage = (data: FileRecord) => {
images.value.push({
@@ -673,9 +694,7 @@
const editorRef = ref<InstanceType<typeof TinymceEditor> | null>(null);
const config = ref({
height: 240,
plugins: 'code preview fullscreen searchreplace save autosave link autolink image media table codesample lists advlist charmap emoticons anchor directionality pagebreak quickbars nonbreaking visualblocks visualchars wordcount',
toolbar: false,
height: 500,
images_upload_handler: (blobInfo, success, error) => {
const file = blobInfo.blob();
const formData = new FormData();
@@ -686,6 +705,44 @@
error(msg);
})
},
// 自定义文件上传(这里使用把选择的文件转成 blob 演示)
file_picker_callback: (callback: any, _value: any, meta: any) => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
// 设定文件可选类型
if (meta.filetype === 'image') {
input.setAttribute('accept', 'image/*');
} else if (meta.filetype === 'media') {
input.setAttribute('accept', 'video/*,.pdf');
}
input.onchange = () => {
const file = input.files?.[0];
if (!file) {
return;
}
if (meta.filetype === 'media') {
if (file.size / 1024 / 1024 > 200) {
editorRef.value?.alert({ content: '大小不能超过 200MB' });
return;
}
if(file.type.startsWith('application/pdf')){
uploadOss(file).then(res => {
const addPath = `<a href="${res.downloadUrl}" target="_blank">${res.name}</a>`;
content.value = content.value + addPath
})
return;
}
if (!file.type.startsWith('video/')) {
editorRef.value?.alert({ content: '只能选择视频文件' });
return;
}
uploadOss(file).then(res => {
callback(res.path)
});
}
};
input.click();
}
});
/* 粘贴图片上传服务器并插入编辑器 */
@@ -732,7 +789,8 @@
content: content.value,
files: JSON.stringify(files.value),
goodsSpec: goodsSpec.value,
goodsSkus: skuList.value
goodsSkus: skuList.value,
type: props.merchantId ? 1 : 0
};
const saveOrUpdate = isUpdate.value ? updateGoods : addGoods;
saveOrUpdate(formData)
@@ -796,6 +854,10 @@
if (props.data.content){
content.value = props.data.content;
}
// 外卖商品分类
listGoodsCategory({merchantId: props.merchantId}).then(list => {
takeaway.value = list
})
isUpdate.value = true;
} else {

View File

@@ -21,6 +21,7 @@
<SelectMerchant
:placeholder="`选择商户`"
class="input-item"
v-if="!merchantId"
v-model:value="where.merchantName"
@done="chooseMerchantId"
/>
@@ -57,6 +58,7 @@
defineProps<{
// 选中的角色
selection?: [];
merchantId?: number;
}>(),
{}
);

View File

@@ -16,6 +16,7 @@
<search
@search="reload"
:selection="selection"
:merchantId="merchantId"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@@ -69,17 +70,21 @@
</a-card>
<!-- 编辑弹窗 -->
<GoodsEdit v-model:visible="showEdit" :data="current" @done="reload" />
<GoodsEdit
v-model:visible="showEdit"
:merchantId="merchantId"
:data="current"
@done="reload"
/>
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { createVNode, ref, watch } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
@@ -94,6 +99,7 @@
} from '@/api/shop/goods';
import type { Goods, GoodsParam } from '@/api/shop/goods/model';
import { formatNumber } from 'ele-admin-pro/es';
import router from '@/router';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -106,8 +112,8 @@
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 店铺ID
const merchantId = ref<number>();
// 表格数据源
const datasource: DatasourceFunction = ({
@@ -120,6 +126,9 @@
if (filters) {
where.status = filters.status;
}
if (merchantId.value) {
where.merchantId = merchantId.value;
}
return pageGoods({
...where,
...orders,
@@ -362,11 +371,6 @@
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: Goods) => {
return {
@@ -380,7 +384,15 @@
}
};
};
query();
watch(
() => router.currentRoute.value.params.id,
(id) => {
merchantId.value = Number(id);
reload();
},
{ immediate: true }
);
</script>
<script lang="ts">

View File

@@ -0,0 +1,292 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="620"
:visible="visible"
:confirm-loading="loading"
:title="isUpdate ? '修改分类' : '新建分类'"
:body-style="{ paddingBottom: '8px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 4, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 18, sm: 20, xs: 24 } : { flex: '1' }
"
>
<a-row :gutter="16">
<a-col
v-bind="styleResponsive ? { md: 24, sm: 24, xs: 24 } : { span: 12 }"
>
<a-form-item label="分类名称" name="title">
<a-input
allow-clear
placeholder="请输入分类名称"
v-model:value="form.title"
@pressEnter="save"
/>
</a-form-item>
</a-col>
<a-col
v-bind="styleResponsive ? { md: 24, sm: 24, xs: 24 } : { span: 12 }"
>
<a-form-item label="排序号" name="sortNumber">
<a-input-number
:min="0"
:max="99999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="是否展示">
<a-switch
checked-children=""
un-checked-children=""
:checked="form.status === 0"
@update:checked="updateHideValue"
/>
</a-form-item>
<a-form-item label="分类图标" name="image" extra="尺寸180*180">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="images"
@done="chooseFile"
@del="onDeleteItem"
/>
</a-form-item>
</a-col>
</a-row>
<div style="margin-bottom: 22px">
<a-divider />
</div>
<a-form-item
label="备注"
name="comments"
:label-col="
styleResponsive ? { md: 3, sm: 4, xs: 24 } : { flex: '90px' }
"
:wrapper-col="
styleResponsive ? { md: 21, sm: 20, xs: 24 } : { flex: '1' }
"
>
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入备注信息"
v-model:value="form.comments"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { message } from 'ant-design-vue/es';
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
import { storeToRefs } from 'pinia';
import { useThemeStore } from '@/store/modules/theme';
import useFormData from '@/utils/use-form-data';
import { GoodsCategory } from '@/api/shop/goodsCategory/model';
import {
addGoodsCategory,
updateGoodsCategory
} from '@/api/shop/goodsCategory';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FileRecord } from '@/api/system/file/model';
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
// 已上传数据
const images = ref<ItemType[]>([]);
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: GoodsCategory | null;
// 上级分类id
parentId?: number;
// 商户ID
merchantId?: number;
// 全部分类数据
categoryList: GoodsCategory[];
}>();
//
const formRef = ref<FormInstance | null>(null);
// 是否是修改
const isUpdate = ref(false);
// 提交状态
const loading = ref(false);
// 表单数据
const { form, resetFields, assignFields } = useFormData<GoodsCategory>({
categoryId: undefined,
title: '',
parentId: undefined,
image: '',
status: 0,
sortNumber: 100
});
// 表单验证规则
const rules = reactive<Record<string, Rule[]>>({
title: [
{
required: true,
message: '请输入分类名称',
type: 'string',
trigger: 'blur'
}
],
sortNumber: [
{
required: true,
message: '请输入排序号',
type: 'number',
trigger: 'blur'
}
],
meta: [
{
type: 'string',
validator: async (_rule: Rule, value: string) => {
if (value) {
const msg = '请输入正确的JSON格式';
try {
const obj = JSON.parse(value);
if (typeof obj !== 'object' || obj === null) {
return Promise.reject(msg);
}
} catch (_e) {
return Promise.reject(msg);
}
}
return Promise.resolve();
},
trigger: 'blur'
}
]
});
const chooseFile = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const categoryForm = {
...form,
// menuType 对应的值与后端不一致在前端处理
// menuType: form.menuType === 2 ? 1 : 0,
parentId: form.parentId || 0,
merchantId: props.merchantId
};
const saveOrUpdate = isUpdate.value
? updateGoodsCategory
: addGoodsCategory;
saveOrUpdate(categoryForm)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
const updateHideValue = (value: boolean) => {
form.status = value ? 0 : 1;
};
watch(
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
assignFields({
...props.data,
parentId:
props.data.parentId === 0 ? undefined : props.data.parentId
});
images.value = [];
if (props.data.image) {
images.value.push({
uid: `${props.data.categoryId}`,
url: props.data.image,
status: 'done'
});
}
isUpdate.value = true;
} else {
images.value = [];
form.parentId = props.parentId;
isUpdate.value = false;
}
} else {
resetFields();
formRef.value?.clearValidate();
}
}
);
</script>
<script lang="ts">
import * as icons from '@/layout/menu-icons';
export default {
components: icons,
data() {
return {
iconData: [
{
title: '已引入的图标',
icons: Object.keys(icons)
}
]
};
}
};
</script>

View File

@@ -0,0 +1,181 @@
<!-- 搜索表单 -->
<template>
<a-space>
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<plus-outlined />
</template>
<span>新建</span>
</a-button>
<template v-if="!merchantId">
<a-button type="dashed" class="ele-btn-icon" @click="expandAll">
展开全部
</a-button>
<a-button type="dashed" class="ele-btn-icon" @click="foldAll">
折叠全部
</a-button>
</template>
<SelectMerchant
:placeholder="`选择商户`"
class="input-item"
v-if="!merchantId"
v-model:value="where.merchantName"
@done="chooseMerchantId"
/>
<!-- <SelectGoodsCategory-->
<!-- v-if="!merchantId"-->
<!-- class="input-item"-->
<!-- :placeholder="`请选择商品分类`"-->
<!-- v-model:value="where.categoryId"-->
<!-- @done="chooseGoodsCategory"-->
<!-- />-->
<a-input-search
allow-clear
placeholder="请输入关键词"
v-model:value="where.keywords"
@pressEnter="reload"
@search="reload"
/>
</a-space>
<!-- <a-space :size="10" style="flex-wrap: wrap">-->
<!-- <a-button type="primary" class="ele-btn-icon" @click="add">-->
<!-- <template #icon>-->
<!-- <PlusOutlined />-->
<!-- </template>-->
<!-- <span>添加</span>-->
<!-- </a-button>-->
<!-- <a-radio-group v-model:value="type" @change="handleSearch">-->
<!-- <a-radio-button value="出售中"-->
<!-- >出售中({{ goodsCount?.totalNum }})</a-radio-button-->
<!-- >-->
<!-- <a-radio-button value="待上架"-->
<!-- >待上架({{ goodsCount?.totalNum2 }})</a-radio-button-->
<!-- >-->
<!-- <a-radio-button value="已售罄"-->
<!-- >已售罄({{ goodsCount?.totalNum3 }})</a-radio-button-->
<!-- >-->
<!-- </a-radio-group>-->
<!-- <SelectMerchant-->
<!-- :placeholder="`选择商户`"-->
<!-- class="input-item"-->
<!-- v-if="!merchantId"-->
<!-- v-model:value="where.merchantName"-->
<!-- @done="chooseMerchantId"-->
<!-- />-->
<!-- <a-button @click="reset">重置</a-button>-->
<!-- </a-space>-->
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { ref, watch } from 'vue';
import { getCount } from '@/api/shop/goods';
import type { GoodsCount, GoodsParam } from '@/api/shop/goods/model';
import useSearch from '@/utils/use-search';
import { useRouter } from 'vue-router';
import { Merchant } from '@/api/shop/merchant/model';
import { GoodsCategory } from '@/api/shop/goodsCategory/model';
const { currentRoute } = useRouter();
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
merchantId?: number;
}>(),
{}
);
const type = ref<string>();
// 统计数据
const goodsCount = ref<GoodsCount>();
// 表单数据
const { where, resetFields } = useSearch<GoodsParam>({
goodsId: undefined,
isShow: undefined,
stock: undefined,
categoryId: undefined,
keywords: ''
});
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
(e: 'expand'): void;
(e: 'fold'): void;
}>();
const expandAll = () => {
emit('expand');
};
const foldAll = () => {
emit('fold');
};
// 新增
const add = () => {
emit('add');
};
const handleSearch = (e) => {
const text = e.target.value;
resetFields();
if (text === '出售中') {
where.isShow = 1;
}
if (text === '待上架') {
where.isShow = 0;
}
if (text === '已售罄') {
where.stock = 0;
}
emit('search', where);
};
const reload = () => {
getCount().then((data: any) => {
goodsCount.value = data;
});
emit('search', where);
};
/* 搜索 */
const chooseMerchantId = (item: Merchant) => {
where.merchantName = item.merchantName;
where.merchantId = item.merchantId;
reload();
};
const chooseGoodsCategory = (
category: GoodsCategory,
data: GoodsCategory
) => {
where.categoryName = data[1].label;
where.categoryId = data[1].value;
reload();
};
/* 重置 */
const reset = () => {
resetFields();
type.value = '';
reload();
};
// watch(
// () => props.selection,
// () => {}
// );
watch(
currentRoute,
() => {
reload();
},
{ immediate: true }
);
</script>

View File

@@ -18,28 +18,13 @@
@expand="onExpand"
>
<template #toolbar>
<a-space>
<a-button type="primary" class="ele-btn-icon" @click="openEdit()">
<template #icon>
<plus-outlined />
</template>
<span>新建</span>
</a-button>
<a-button type="dashed" class="ele-btn-icon" @click="expandAll">
展开全部
</a-button>
<a-button type="dashed" class="ele-btn-icon" @click="foldAll">
折叠全部
</a-button>
<!-- 搜索表单 -->
<a-input-search
allow-clear
v-model:value="searchText"
placeholder="请输入搜索关键词"
@search="reload"
@pressEnter="reload"
/>
</a-space>
<search
@search="reload"
:merchantId="merchantId"
@add="openEdit"
@expand="expandAll"
@fold="foldAll"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'path'">
@@ -66,9 +51,7 @@
style="margin-right: 10px"
v-if="record.image"
/>
<a @click="openPreview(`/goods/search?categoryId=${record.categoryId}`)">{{
record.title
}}</a>
{{ record.title }}
</template>
<template v-if="column.key === 'showIndex'">
<a-space @click="onShowIndex(record)">
@@ -110,19 +93,30 @@
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<!-- 商城分类编辑弹窗 -->
<category-edit
v-model:visible="showEdit"
v-if="merchantId == 0"
:data="current"
:parent-id="parentId"
:category-list="categoryData"
@done="reload"
/>
<!-- 店铺分类编辑弹窗 -->
<merchant-category-edit
v-model:visible="showEdit"
v-else
:data="current"
:parent-id="parentId"
:merchantId="merchantId"
:category-list="categoryData"
@done="reload"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ref, watch } from 'vue';
import { message } from 'ant-design-vue/es';
import {
ArrowUpOutlined,
@@ -144,6 +138,7 @@
} from 'ele-admin-pro/es';
import type { EleProTable } from 'ele-admin-pro/es';
import CategoryEdit from './components/category-edit.vue';
import MerchantCategoryEdit from './components/merchant-category-edit.vue';
import {
listGoodsCategory,
removeGoodsCategory,
@@ -155,6 +150,8 @@
} from '@/api/shop/goodsCategory/model';
import { openNew, openPreview } from '@/utils/common';
import { getSiteInfo } from '@/api/layout';
import router from '@/router';
import Search from './components/search.vue';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -251,6 +248,7 @@
const searchText = ref('');
const tenantId = ref<number>();
const domain = ref<string>();
const merchantId = ref<number>();
getSiteInfo().then((data) => {
tenantId.value = data.tenantId;
@@ -260,6 +258,9 @@
// 表格数据源
const datasource: DatasourceFunction = ({ where }) => {
where.title = searchText.value;
if (merchantId.value) {
where.merchantId = merchantId.value;
}
return listGoodsCategory({ ...where });
};
@@ -397,6 +398,15 @@
}
};
};
watch(
() => router.currentRoute.value.params.id,
(id) => {
merchantId.value = Number(id);
reload();
},
{ immediate: true }
);
</script>
<script lang="ts">

View File

@@ -10,6 +10,12 @@
<a-button class="ele-btn-icon" @click="openUrl(`/shop/index`)">
<span>店铺管理</span>
</a-button>
<a-button class="ele-btn-icon" @click="openUrl(`/shop/index`)">
<span>门店职员</span>
</a-button>
<a-button class="ele-btn-icon" @click="openUrl(`/goods/category/:id`)">
<span>商品分类</span>
</a-button>
<a-button class="ele-btn-icon" @click="openUrl(`/shop/apply`)">
<span>入驻申请</span>
</a-button>
@@ -28,6 +34,7 @@
import { watch } from 'vue';
import { openUrl } from '@/utils/common';
import router from '@/router';
import { getMerchant } from '@/api/shop/merchant';
const props = withDefaults(
defineProps<{
@@ -52,7 +59,7 @@
watch(
() => router.currentRoute,
(route) => {
console.log(route,'route');
console.log(route, 'route');
}
);
</script>

View File

@@ -30,8 +30,12 @@
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openUrl(`/shop/account/${record.merchantId}`)"
>门店用户</a
<a @click="openUrl(`/goods/category/${record.merchantId}`)"
>分类</a
>
<a-divider type="vertical" />
<a @click="openUrl(`/goods/index/${record.merchantId}`)"
>商品</a
>
<a-divider type="vertical" />
<a @click="openEdit(record)">修改</a>
@@ -55,7 +59,7 @@
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { createVNode, ref, watch } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -72,7 +76,8 @@
removeBatchMerchant
} from '@/api/shop/merchant';
import type { Merchant, MerchantParam } from '@/api/shop/merchant/model';
import { openNew, openPreview, openUrl } from '@/utils/common';
import { openUrl } from '@/utils/common';
import router from '@/router';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -85,8 +90,8 @@
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 商户ID
const merchantId = ref(0);
// 表格数据源
const datasource: DatasourceFunction = ({
@@ -169,7 +174,7 @@
{
title: '操作',
key: 'action',
width: 180,
width: 240,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -235,11 +240,6 @@
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: Merchant) => {
return {
@@ -253,7 +253,20 @@
}
};
};
query();
watch(
() => router.currentRoute.value.params.id,
(id) => {
if (id) {
if (id == ':id') {
merchantId.value = 0;
} else {
merchantId.value = Number(id);
}
}
},
{ immediate: true }
);
</script>
<script lang="ts">

View File

@@ -7,24 +7,23 @@
row-key="logId"
:columns="columns"
:datasource="datasource"
v-model:selection="selection"
:scroll="{ x: 1000 }"
:where="defaultWhere"
cache-key="userBalanceLogTable"
>
<template #toolbar>
<a-space>
<a-button
danger
type="primary"
class="ele-btn-icon"
@click="removeBatch"
>
<template #icon>
<delete-outlined />
</template>
<span>批量删除</span>
</a-button>
<!-- <a-button-->
<!-- danger-->
<!-- type="primary"-->
<!-- class="ele-btn-icon"-->
<!-- @click="removeBatch"-->
<!-- >-->
<!-- <template #icon>-->
<!-- <delete-outlined />-->
<!-- </template>-->
<!-- <span>批量删除</span>-->
<!-- </a-button>-->
<a-range-picker
v-model:value="dateRange"
value-format="YYYY-MM-DD"
@@ -36,7 +35,6 @@
placeholder="请输入关键词"
@search="reload"
@pressEnter="reload"
@close="onClose"
/>
<a-button @click="reset">重置</a-button>
</a-space>
@@ -128,13 +126,19 @@
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格列配置
const columns = ref<ColumnItem[]>([
// {
// key: 'index',
// width: 48,
// align: 'center',
// fixed: 'left',
// hideInSetting: true,
// customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
// },
{
key: 'index',
width: 48,
align: 'center',
fixed: 'left',
hideInSetting: true,
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
title: '用户ID',
dataIndex: 'userId',
width: 80,
showSorterTooltip: false
},
{
title: '用户',