|
|
@@ -1,16 +1,24 @@
|
|
|
<script setup lang="tsx">
|
|
|
import { nextTick, ref, useTemplateRef } from 'vue';
|
|
|
-import { NButton, NImage } from 'naive-ui';
|
|
|
-import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
|
|
|
-import { fetchGetAllStoreList, fetchGetDeskCategoryList, fetchUpdateCategory } from '@/service/api/goods/desk-category';
|
|
|
+import { NButton, NImage, NTag } from 'naive-ui';
|
|
|
+import {
|
|
|
+ fetchGategoryImport,
|
|
|
+ fetchGetAllStoreList,
|
|
|
+ fetchGetDeskCategoryList,
|
|
|
+ fetchGetFailLogList,
|
|
|
+ fetchUpdateCategory
|
|
|
+} from '@/service/api/goods/desk-category';
|
|
|
import { fetchGetAllTagList } from '@/service/api/goods/tag';
|
|
|
import { useAppStore } from '@/store/modules/app';
|
|
|
import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
|
|
|
import { useForm } from '@/components/zt/Form/hooks/useForm';
|
|
|
-import RelatedGoodsModal from './components/related-goods-modal.vue';
|
|
|
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
|
|
|
+import SVGIcon from '@/components/custom/svg-icon.vue';
|
|
|
+import RelatedGoods from './components/related-goods.vue';
|
|
|
const appStore = useAppStore();
|
|
|
const deskData = ref<Api.goods.ShopCategory[]>([]);
|
|
|
const loading = ref(false);
|
|
|
+const failData = ref<Api.goods.ShopCategoryLogVO[]>();
|
|
|
const relatedGoodsModalRef = useTemplateRef('relatedGoodsModalRef');
|
|
|
const [registerSearchForm, { getFieldsValue: getSearchForm, setFieldsValue }] = useForm({
|
|
|
schemas: [
|
|
|
@@ -47,8 +55,8 @@ const [registerSearchForm, { getFieldsValue: getSearchForm, setFieldsValue }] =
|
|
|
},
|
|
|
collapsedRows: 1
|
|
|
});
|
|
|
-// const importTemplateRef = useTemplateRef('importTemplateRef');
|
|
|
-const tableColumns: NaiveUI.TableColumn<InternalRowData>[] = [
|
|
|
+const importTemplateRef = useTemplateRef('importTemplateRef');
|
|
|
+const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
|
|
|
{
|
|
|
title: '分类名称',
|
|
|
key: 'name'
|
|
|
@@ -56,18 +64,23 @@ const tableColumns: NaiveUI.TableColumn<InternalRowData>[] = [
|
|
|
{
|
|
|
title: '分类图标',
|
|
|
key: 'icon',
|
|
|
- render(rowData) {
|
|
|
- const row = rowData as Api.goods.ShopCategory;
|
|
|
+ render(row) {
|
|
|
return <NImage src={row.icon} class="h-[40px] w-[40px]" />;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
title: '关联商品',
|
|
|
- key: 'icon'
|
|
|
+ key: 'prodCount',
|
|
|
+ render: row => {
|
|
|
+ return row.level == 3 ? `${row.prodCount}个商品` : '';
|
|
|
+ }
|
|
|
},
|
|
|
{
|
|
|
title: '标签',
|
|
|
- key: 'labelName'
|
|
|
+ key: 'labelName',
|
|
|
+ render: row => {
|
|
|
+ return row.labelName ? <NTag> {row.labelName} </NTag> : '';
|
|
|
+ }
|
|
|
},
|
|
|
{
|
|
|
title: '排序',
|
|
|
@@ -80,13 +93,18 @@ const tableColumns: NaiveUI.TableColumn<InternalRowData>[] = [
|
|
|
align: 'center',
|
|
|
render: row => (
|
|
|
<div class="flex-center gap-8px">
|
|
|
- {row.level == 1 && (
|
|
|
+ {
|
|
|
<NButton type="primary" size="small" quaternary onClick={() => edit(row)}>
|
|
|
编辑
|
|
|
</NButton>
|
|
|
- )}
|
|
|
- {row.level == 2 && (
|
|
|
- <NButton type="primary" size="small" quaternary onClick={() => handleClick()}>
|
|
|
+ }
|
|
|
+ {row.level == 3 && (
|
|
|
+ <NButton
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ quaternary
|
|
|
+ onClick={() => relatedGoodsModalRef.value?.handleOpenModal(row)}
|
|
|
+ >
|
|
|
关联商品
|
|
|
</NButton>
|
|
|
)}
|
|
|
@@ -110,6 +128,7 @@ const [
|
|
|
formConfig: {
|
|
|
schemas: [
|
|
|
{ label: '', field: 'id', show: false, component: 'NInput' },
|
|
|
+ { label: '', field: 'level', show: false, component: 'NInput' },
|
|
|
{
|
|
|
label: '分类名称',
|
|
|
field: 'name',
|
|
|
@@ -140,6 +159,9 @@ const [
|
|
|
// api: fetchGetTagList,
|
|
|
labelFeild: 'name',
|
|
|
valueFeild: 'id'
|
|
|
+ },
|
|
|
+ ifShow({ model }) {
|
|
|
+ return model.level == 1;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
@@ -162,13 +184,85 @@ const [
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
-// async function handleSubmit(file: File) {
|
|
|
-// const { error } = await fetchGategoryImport(file);
|
|
|
-// if (!error) {
|
|
|
-// importTemplateRef.value?.closeModal();
|
|
|
-// }
|
|
|
-// importTemplateRef.value?.setSubLoading(false);
|
|
|
-// }
|
|
|
+const failColumns: NaiveUI.TableColumn<Api.goods.ShopCategoryLogVO>[] = [
|
|
|
+ {
|
|
|
+ key: 'index',
|
|
|
+ title: '序号',
|
|
|
+ align: 'center',
|
|
|
+ render(_, rowIndex) {
|
|
|
+ return rowIndex + 1;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'taskName',
|
|
|
+ title: '任务名称',
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'createTime',
|
|
|
+ title: '时间',
|
|
|
+ align: 'center',
|
|
|
+ render(row) {
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <div>创建时间:{row.createTime}</div>
|
|
|
+ <div>完成时间:{row.createTime}</div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'totalUserCount',
|
|
|
+ title: '操作人',
|
|
|
+ align: 'center',
|
|
|
+ render(row) {
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <div>{row.createByRole}</div>
|
|
|
+ <div>({row.createByName})</div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'successStatus',
|
|
|
+ title: '状态',
|
|
|
+ align: 'center',
|
|
|
+ width: 240,
|
|
|
+ render(row) {
|
|
|
+ return (
|
|
|
+ <div class={'flex items-center'}>
|
|
|
+ 共{Number(row.successStatus) + Number(row.failureStatus)}条,成功:{row.successStatus},
|
|
|
+ <span class={'flex items-center text-red-500'}>
|
|
|
+ 失败:
|
|
|
+ {row.failureStatus}
|
|
|
+ {row.failureStatus != 0 && (
|
|
|
+ <div onClick={() => hanleExportFailure(row.taskCode)}>
|
|
|
+ <SVGIcon
|
|
|
+ icon={'tdesign:download'}
|
|
|
+ class={'ml-1 cursor-pointer text-20px'}
|
|
|
+ style={'color:var(--n-color)'}
|
|
|
+ ></SVGIcon>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+];
|
|
|
+const [registerModalFail, { openModal: openModalFail, setModalLoading }] = useModal({
|
|
|
+ title: '导入分类',
|
|
|
+ isShowHeaderText: false,
|
|
|
+ showFooter: false
|
|
|
+});
|
|
|
+async function handleSubmit(file: File) {
|
|
|
+ const { error } = await fetchGategoryImport(file);
|
|
|
+ if (!error) {
|
|
|
+ importTemplateRef.value?.closeModal();
|
|
|
+ }
|
|
|
+ importTemplateRef.value?.setSubLoading(false);
|
|
|
+}
|
|
|
function edit(row: Recordable) {
|
|
|
openModalForm(row);
|
|
|
setModalFormValue({ ...row, label: row.label });
|
|
|
@@ -178,6 +272,7 @@ async function getData() {
|
|
|
const { data, error } = await fetchGetDeskCategoryList(getSearchForm());
|
|
|
if (!error) {
|
|
|
deskData.value = buildTree(data).sort((a, b) => b.num - a.num);
|
|
|
+ console.log(deskData.value);
|
|
|
}
|
|
|
}
|
|
|
async function handleSubmitForm() {
|
|
|
@@ -188,12 +283,25 @@ async function handleSubmitForm() {
|
|
|
getData();
|
|
|
}
|
|
|
}
|
|
|
-function handleClick() {
|
|
|
- relatedGoodsModalRef.value?.openModal();
|
|
|
+
|
|
|
+function handleOpen() {
|
|
|
+ importTemplateRef.value?.openModal();
|
|
|
+}
|
|
|
+async function handleOpenFaileModal() {
|
|
|
+ openModalFail();
|
|
|
+ setModalLoading(true);
|
|
|
+ const { data: failList, error } = await fetchGetFailLogList();
|
|
|
+ if (!error) {
|
|
|
+ failData.value = failList;
|
|
|
+ }
|
|
|
+ setModalLoading(false);
|
|
|
+}
|
|
|
+function hanleExportFailure(taskCode: string) {
|
|
|
+ window.open(
|
|
|
+ `${import.meta.env.VITE_SERVICE_BASE_URL}/platform/shopCategoryLog/export?taskCode=${taskCode}`,
|
|
|
+ '_blank'
|
|
|
+ );
|
|
|
}
|
|
|
-// function handleOpen() {
|
|
|
-// importTemplateRef.value?.openModal();
|
|
|
-// }
|
|
|
interface BuildTreeOptions {
|
|
|
idKey?: string;
|
|
|
pidKey?: string;
|
|
|
@@ -251,16 +359,20 @@ function buildTree<T>(items: T[], options: BuildTreeOptions = {}): T[] {
|
|
|
<NCard title="前台类目" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
|
|
<template #header-extra>
|
|
|
<TableHeaderOperation :loading="loading" @refresh="getData">
|
|
|
- <!--
|
|
|
- <template #prefix>
|
|
|
+ <template #prefix>
|
|
|
<NButton size="small" @click="handleOpen">
|
|
|
<template #icon>
|
|
|
<icon-file-icons:microsoft-excel class="text-icon"></icon-file-icons:microsoft-excel>
|
|
|
</template>
|
|
|
Excel导入分类
|
|
|
</NButton>
|
|
|
+ <NButton size="small" @click="handleOpenFaileModal">
|
|
|
+ <template #icon>
|
|
|
+ <icon-file-icons:microsoft-excel class="text-icon"></icon-file-icons:microsoft-excel>
|
|
|
+ </template>
|
|
|
+ 导入记录
|
|
|
+ </NButton>
|
|
|
</template>
|
|
|
--->
|
|
|
</TableHeaderOperation>
|
|
|
</template>
|
|
|
<NDataTable
|
|
|
@@ -275,17 +387,19 @@ function buildTree<T>(items: T[], options: BuildTreeOptions = {}): T[] {
|
|
|
class="sm:h-full"
|
|
|
/>
|
|
|
</NCard>
|
|
|
- <!--
|
|
|
- <ZImportTemplate
|
|
|
+ <BasicModal @register="registerModalFail">
|
|
|
+ <NDataTable :columns="failColumns" :data="failData" size="small" remote class="sm:h-full" />
|
|
|
+ </BasicModal>
|
|
|
+ <ZImportTemplate
|
|
|
ref="importTemplateRef"
|
|
|
url="/platform/shopCategory/exportTemplate"
|
|
|
template-text="店内分类导入模版.xlsx"
|
|
|
modal-text="Excel导入分类"
|
|
|
@submit="handleSubmit"
|
|
|
></ZImportTemplate>
|
|
|
--->
|
|
|
+
|
|
|
<BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmitForm"></BasicModelForm>
|
|
|
- <RelatedGoodsModal ref="relatedGoodsModalRef"></RelatedGoodsModal>
|
|
|
+ <RelatedGoods ref="relatedGoodsModalRef" @refresh="getData"></RelatedGoods>
|
|
|
</LayoutTable>
|
|
|
</template>
|
|
|
|