Browse Source

add: platform shop list

dev
powersir 11 months ago
parent
commit
583d1fd46a
3 changed files with 428 additions and 3 deletions
  1. +231
    -0
      src/pages/system/shop/manage/index.tsx
  2. +194
    -0
      src/pages/system/shop/manage/shop-editor.tsx
  3. +3
    -3
      src/request/service/platform-shop.ts

+ 231
- 0
src/pages/system/shop/manage/index.tsx View File

@@ -0,0 +1,231 @@
import { Space, Table, Button, Input, Select, Divider, Tag, Card, Badge, Form } from 'antd';
import type { TableColumnsType } from 'antd';
import { t } from '@/utils/i18n';
import React, { useState, useEffect } from 'react';
import { PlusOutlined, ExclamationCircleFilled, SearchOutlined, UndoOutlined } from '@ant-design/icons';
import type { PlatformShop } from '@/models'
import { antdUtils } from '@/utils/antd';
import { useRequest } from '@/hooks/use-request';
import platformShopService from '@/request/service/platform-shop';
import { formatDate } from '@/utils/formatTime'
import ShopEditor from './shop-editor';

export default () => {

const [editorVisable, seEditorVisable] = useState<boolean>(false);
const [editData, seEditData] = useState<PlatformShop>();
const [dataSource, setDataSource] = useState<PlatformShop[]>([]);
const [searchFrom] = Form.useForm();


const { runAsync: getPageApi } = useRequest(platformShopService.getPlatformShopList, { manual: true });
const { runAsync: deleteApi } = useRequest(platformShopService.deletePlatformShop, { manual: true });

const load = async () => {
const [error, { data }] = await getPageApi(searchFrom.getFieldsValue());
if (!error) {
setDataSource(data.list);
}
};


const showDeleteConfirm = (data: PlatformShop) => {
antdUtils.modal?.confirm({
title: '确认要将该菜单删除吗?',
icon: <ExclamationCircleFilled />,
content: '请注意删除以后不可恢复!',
okText: '删除',
okType: 'danger',
cancelText: '取消',
onOk() {
return new Promise(async (resolve) => {
const [error, { code, msg }] = await deleteApi(data.platformShopId);
if (error || code !== 0) {
antdUtils.message?.open({ type: 'error', content: msg ?? '操作失败' })
} else {
antdUtils.message?.open({ type: 'success', content: '删除成功' })
}
await load();
resolve('')
}).catch(() => antdUtils.message?.open({
type: 'error',
content: '操作失败',
}));
},
onCancel() {
},
});
};

const columns: TableColumnsType<PlatformShop> = [
{
title: '名称',
dataIndex: 'shopName',
key: 'shopName',
align: 'right',
width: 100,
},
{
title: '平台',
dataIndex: 'platformId',
key: 'platformId',
align: 'center',
width: 150,
render: (value: number) => {
//TODO: get platform name by id
return "虾皮"
}
},
{
title: '商户信息',
dataIndex: 'packageId',
key: 'packageId',
align: 'center',
width: 100,
},
{
title: '店长',
dataIndex: 'shopManager',
key: 'shopManager',
align: 'center',
width: 150
},
{
title: '店员',
dataIndex: 'shopAssistantList',
key: 'shopAssistantList',
align: 'center',
width: 150
},
{
title: '客服',
dataIndex: 'shopCustomerList',
key: 'shopCustomerList',
align: 'center',
width: 150
},
{
title: '状态',
key: 'shopStatus',
dataIndex: 'shopStatus',
width: 100,
align: 'center',
render: (value: number) => {
return (value === 1 ? <Badge status="success" text="已开启" /> : <Badge status="error" text="已停用" />)
}
},
{
title: '授权状态',
dataIndex: 'tokenFlag',
key: 'tokenFlag',
align: 'center',
width: 200,
render: (value: number) => {
//1:成功, 2:失败,0:未授权
if(value === 0) {
return <Tag color='yellow'>未授权</Tag>
} else if(value === 1) {
return <Tag color='purple'>成功</Tag>
} else if(value === 2) {
return <Tag color='red'>失败</Tag>
}
return <Tag >未知状态</Tag>
}
},
{
title: '授权过期时间',
key: 'expiresTime',
dataIndex: 'expiresTime',
width: 200,
render: (value: number) => {
return formatDate(new Date(value), "YYYY-mm-dd HH:MM:SS")
}
},
{
title: t("QkOmYwne" /* 操作 */),
key: 'action',
render: (value: PlatformShop, record) => (
<Space size="small" split={(<Divider type='vertical' />)}>
<a onClick={() => {
seEditData(value);
seEditorVisable(true);
}}>
编辑
</a>
<a onClick={() => {
showDeleteConfirm(value)
}}>
删除
</a>
</Space>
),
},
];

useEffect(() => {
load();
}, []);

const onReset = () => {
searchFrom.resetFields()
load()
}

return (
<>
<div>
{/* <Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' bodyStyle={{ paddingTop: 4, paddingBottom: 4 }}>
<div className='flex justify-between content-center'>
<div className='flex justify-normal items-center'>
<Form layout='inline' form={searchFrom}>
<Form.Item name="name" label="租户名称">
<Input className='w-[150px]' placeholder='请输入名称' allowClear />
</Form.Item>
<Form.Item name="contactName" label="租户名称">
<Input className='w-[150px]' placeholder='请输入联系人' allowClear />
</Form.Item>
<Form.Item name="contactMobile" label="联系人手机">
<Input className='w-[160px]' placeholder='请输入联系人手机' allowClear />
</Form.Item>
<Form.Item className='ml-2 w-[130px]' name="status" label="状态">
<Select placeholder="请选择" allowClear >
<Select.Option value="">全部</Select.Option>
<Select.Option value="0">开启</Select.Option>
<Select.Option value="1">关闭</Select.Option>
</Select>
</Form.Item>
</Form>
<Space.Compact className="ml-5">
<Button type='primary' size='large' icon={<SearchOutlined />} onClick={load}> 搜索 </Button>
<Button type='primary' size='large' icon={<UndoOutlined />} onClick={onReset}> 重置 </Button>
</Space.Compact>
</div>
<div className="py-[4px]">
<Button className="ml-5" type='primary' size='large' icon={<PlusOutlined />} onClick={() => {
seEditData(undefined);
seEditorVisable(true);
}}> 新增租户 </Button>
</div>
</div>
</Card> */}
<Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]'>
<Table rowKey="id"
scroll={{ x: true }}
columns={columns}
dataSource={dataSource}
className='bg-transparent'
pagination={false} />
</Card>
</div>
{/* <ShopEditor
onSave={() => {
load();
seEditorVisable(false);
}}
onCancel={() => { seEditorVisable(false) }}
visible={editorVisable}
data={editData} /> */}
</>
);
};


+ 194
- 0
src/pages/system/shop/manage/shop-editor.tsx View File

@@ -0,0 +1,194 @@
import React, { useEffect, useState } from 'react'
import { Form, Input, InputNumber, Radio, Modal, Select, DatePicker } from 'antd';
import tenantService from '@/request/service/tenant';
import tenantPkgService from '@/request/service/tenant-package';
import { useRequest } from '@/hooks/use-request';
import type { TenantVO } from '@/models'
import { antdUtils } from '@/utils/antd';
import customParseFormat from 'dayjs/plugin/customParseFormat';

import dayjs from 'dayjs';
dayjs.extend(customParseFormat);


const layout = {
labelCol: { span: 4, },
wrapperCol: { span: 16 }
};

interface EditorProps {
visible: boolean;
onCancel: (flag?: boolean) => void;
onSave: (role: TenantVO) => void;
data?: TenantVO | null;
}


const TenantEditor: React.FC<EditorProps> = (props) => {

const { visible, onCancel, onSave, data } = props;

const { runAsync: updateApi } = useRequest(tenantService.updateTenantApi, { manual: true });
const { runAsync: createApi } = useRequest(tenantService.createTenantApi, { manual: true });
const { data: tenanPackages, run: getTenantPackageList } = useRequest(tenantPkgService.getTenantPackageList, { manual: true });

const isEdit = !!data;


const [saveLoading, setSaveLoading] = useState(false);
const [form] = Form.useForm();

useEffect(() => {
if (visible) {
if (data) {
form.setFieldsValue(data);
form.setFieldValue('expireTime', dayjs(data.expireTime))
}
} else {
form.resetFields();
}
}, [visible]);

useEffect(() => {
getTenantPackageList()
}, [getTenantPackageList])

const save = async () => {
setSaveLoading(true);
const fieldValues = form.getFieldsValue();
const expireTime = dayjs(form.getFieldValue('expireTime')).toDate().getTime()
const newValue = isEdit ? { ...data, ...fieldValues, expireTime } : {...fieldValues, expireTime};
const [error, { msg, code }] = isEdit ? await updateApi(newValue) : await createApi(newValue);
if (!error && code === 0) {
onSave(newValue);
} else {
antdUtils.message?.open({
type: 'error',
content: msg ?? '操作失败',
});
}
setSaveLoading(false);
}

return (
<>
<Modal
open={visible}
title="新建"
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading= {saveLoading}
destroyOnClose
>
<Form
form={form}
{...layout}
onFinish={save}
labelCol={{ flex: '0 0 100px' }}
wrapperCol={{ span: 16 }}
>
<Form.Item name="name" label="租户名称"
rules={[
{
required: true,
message: '请输入租户名称',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="packageId" label="租户套餐"
rules={[
{
required: true,
message: '请选择租户套餐',
},
]}
>
<Select placeholder="请选择租户套餐" options={tenanPackages?.data.map(item => {
return {
label: item.name,
value: item.id,
}
})}>
</Select>
</Form.Item>


<Form.Item name="contactName" label="联系人"
rules={[
{
required: true,
message: '请输入联系人',
},
]}
>
<Input />
</Form.Item>


<Form.Item name="contactMobile" label="联系电话"
rules={[
{
required: true,
message: '请输入电话号码',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="username" label="用户名称">
<Input />
</Form.Item>

<Form.Item name="password" label="用户密码">
<Input />
</Form.Item>

<Form.Item name="accountCount" label="账号额度" >
<InputNumber min={0} />
</Form.Item>

<Form.Item name="expireTime" label="过期时间"
rules={[
{
required: true,
message: '请设置过期时间',
},
]}>
<DatePicker showTime format="YYYY-MM-DD HH:mm:ss" />
</Form.Item>

<Form.Item name="domain" label="绑定域名"
rules={[
{
required: true,
message: '请输入绑定域名',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="status" label="租户状态" rules={[
{
required: true,
message: '请选择租户状态',
},
]}>
<Radio.Group options={[
{ value: 0, label: "开启" },
{ value: 1, label: "关闭" }
]} optionType="default">
</Radio.Group>
</Form.Item>
</Form>
</Modal>
</>
)
}

export default TenantEditor;

+ 3
- 3
src/request/service/platform-shop.ts View File

@@ -10,17 +10,17 @@ export default {
},

// 创建平台店铺
createRole: (data: PlatformShop) => {
createPlatformShop: (data: PlatformShop) => {
return request.post(`${BASE_URL}/create`, data);
},

// 修改平台店铺
updateRole: (data: PlatformShop) => {
updatePlatformShop: (data: PlatformShop) => {
return request.put(`${BASE_URL}/update`, data);
},

// 删除平台店铺
deleteRole: (id: number) => {
deletePlatformShop: (id: number) => {
return request.delete(`${BASE_URL}/delete?id=${id}`);
},
};

Loading…
Cancel
Save