Browse Source

add: position

dev
powersir 1 year ago
parent
commit
2d1b242556
5 changed files with 381 additions and 0 deletions
  1. +1
    -0
      src/models/index.ts
  2. +21
    -0
      src/models/position.data.ts
  3. +121
    -0
      src/pages/system/post/create-position.tsx
  4. +193
    -0
      src/pages/system/post/index.tsx
  5. +45
    -0
      src/request/service/positon.ts

+ 1
- 0
src/models/index.ts View File

@@ -1,6 +1,7 @@
export * from './user.data.ts'
export * from './product.data.ts'
export * from './role.data.ts'
export * from './position.data.ts'

export interface ResponseDTO<T>{
code: number;


+ 21
- 0
src/models/position.data.ts View File

@@ -0,0 +1,21 @@
export interface PositionVO {
id?: number
name: string
code: string
sort: number
status: number
remark: string
createTime?: Date
}

export interface PositionPageReqVO extends PageParam {
code?: string
name?: string
status?: number
}

export interface PositionExportReqVO {
code?: string
name?: string
status?: number
}

+ 121
- 0
src/pages/system/post/create-position.tsx View File

@@ -0,0 +1,121 @@
import React, { useEffect, useState } from 'react'
import { Form, Input, InputNumber, Radio, Modal, Switch } from 'antd';
import positonService from '@/request/service/positon';
import { useRequest } from '@/hooks/use-request';
import type { PositionVO } from '@/models'
import { antdUtils } from '@/utils/antd';

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

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


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

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

const { runAsync: updatePostApi } = useRequest(positonService.updatePostApi, { manual: true });
const { runAsync: createPostApi } = useRequest(positonService.createPostApi, { manual: true });

const isEdit = !!data;


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

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

const save = async () => {
setSaveLoading(true);
const fieldValues = form.getFieldsValue();
const newValue = isEdit ? { ...data, ...fieldValues } : fieldValues;
const [error, { msg, code }] = isEdit ? await updatePostApi(newValue) : await createPostApi(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()}
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="code" label="岗位编码"
rules={[
{
required: true,
message: '请输入岗位编码',
},
]}
>
<Input />
</Form.Item>

<Form.Item name="sort" label="岗位顺序" >
<InputNumber min={1} max={100} />
</Form.Item>

<Form.Item name="remark" label="备注" >
<Input.TextArea showCount maxLength={100} />
</Form.Item>

<Form.Item name="status" label="状态">
<Radio.Group options={[
{ value: 0, label: "开启" },
{ value: 1, label: "关闭" }
]} optionType="default">
</Radio.Group>
</Form.Item>
</Form>
</Modal>
</>
)
}

export default PositionEditor;

+ 193
- 0
src/pages/system/post/index.tsx View File

@@ -0,0 +1,193 @@
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 { PositionVO } from '@/models'
import { antdUtils } from '@/utils/antd';
import { useRequest } from '@/hooks/use-request';
import positonService from '@/request/service/positon';
import { formatDate } from '@/utils/formatTime'
import PositionEditor from './create-position'

const MenuListPage: React.FC = () => {

const [editorVisable, seEditorVisable] = useState<boolean>(false);
const [editPosition, seEditPosition] = useState<PositionVO>();
const [dataSource, setDataSource] = useState<PositionVO[]>([]);
const [searchFrom] = Form.useForm();


const { runAsync: getPostPageApi } = useRequest(positonService.getPostPageApi, { manual: true });
const { runAsync: deletePostApi } = useRequest(positonService.deletePostApi, { manual: true });

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


const showDeleteConfirm = (menu: PositionVO) => {
antdUtils.modal?.confirm({
title: '确认要将该菜单删除吗?',
icon: <ExclamationCircleFilled />,
content: '请注意删除以后不可恢复!',
okText: '删除',
okType: 'danger',
cancelText: '取消',
onOk() {
return new Promise(async (resolve) => {
const [error, { code, msg} ] = await deletePostApi({ id: menu.id });
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<PositionVO> = [
{
title: '岗位编号',
dataIndex: 'id',
key: 'id',
align: 'center',
width: 100,
},
{
title: '岗位名称',
dataIndex: 'name',
key: 'name',
align: 'right',
width: 200,
},
{
title: '岗位编码',
dataIndex: 'code',
key: 'code',
align: 'center',
width: 150
},
{
title: '岗位顺序',
key: 'sort',
dataIndex: 'sort',
align: 'center',
},
{
title: '状态',
key: 'status',
dataIndex: 'status',
width: 100,
align: 'center',
render: (value: number) => {
return (value === 0 ? <Badge status="success" text="已开启" /> : <Badge status="error" text="已关闭" />)
}
},
{
title: '创建时间',
key: 'createTime',
dataIndex: 'createTime',
width: 200,
render: (value: number) => {
return formatDate(new Date(value), "YYYY-mm-dd HH:MM:SS")
}
},
{
title: t("QkOmYwne" /* 操作 */),
key: 'action',
render: (value: PositionVO, record) => (
<Space size="small" split={( <Divider type='vertical' />)}>
<a onClick={() => {
seEditPosition(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="code" label="岗位编码">
<Input className='w-[150px]' 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={() => {
seEditPosition(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={{ position: ['bottomRight'] }} />
</Card>
</div>
<PositionEditor
onSave={() => {
load();
seEditorVisable(false);
}}
onCancel={() => { seEditorVisable(false) }}
visible={editorVisable}
data={editPosition} />
</>
);
};

export default MenuListPage;

+ 45
- 0
src/request/service/positon.ts View File

@@ -0,0 +1,45 @@
import request from '@/request';
import { PositionExportReqVO, PositionVO, PositionPageReqVO, PageData } from '@/models';

const BASE_URL = '/admin-api/system/post';

export default {
// 查询岗位列表
getPostPageApi: (params: PositionPageReqVO) => {
//return await request.get({ url: '/system/post/page', params })
return request.get<PageData<PositionVO>>(`${BASE_URL}/page`, { params });
},

// 获取岗位精简信息列表
listSimplePostsApi: () => {
return request.get<PageData<PositionVO>>(`${BASE_URL}/list-all-simple`);
},

// 查询岗位详情
getPostApi: (id: number) => {
return request.get<PositionVO>(`${BASE_URL}/get?id=${id}`);
},

// 新增岗位
createPostApi: (data: PositionVO) => {
//return await request.post({ url: '/system/post/create', data })
return request.post<any>(`${BASE_URL}/create`, data);
},

// 修改岗位
updatePostApi: (data: PositionVO) => {
return request.put(`${BASE_URL}/update`, data)
},

// 删除岗位
deletePostApi: (id: number) => {
return request.delete(`${BASE_URL}/get?id=${id}`)
},

// 导出岗位
// exportPostApi: (params: PostExportReqVO) => {
// return request.download({ url: '/system/post/export', params })
// },

};


Loading…
Cancel
Save