2023-11

2023-11

1.完成一个页面的开发

本周任务

  1. 熟悉 vue3 若依基础框架
  2. 会使用 3h1 和 vben admin antd 组件库的用法
  3. 新增路由 封装API 调用接口 页面渲染 curd
  4. 二级页面 Modal

1.index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<template>
<div>
<!--BasicTable 表格-->
<BasicTable @register="registerTable">
<!-- 新增岗位 -->
<template #toolbar>
<a-button type="primary" @click="handleCreate"> 新增岗位 </a-button>
</template>
<template #bodyCell="{ column, record }">
<!--v-if="column.dataIndex === 'action'" 判断当前列是否是操作列-->
<template v-if="column.dataIndex === 'action'">
<TableAction
:actions="[
{
label: '修改',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
popConfirm: {
title: '确定要删除吗?',
confirm: handleDelete.bind(null, record),
},
},
]"
/></template>
</template>
</BasicTable>
<!--弹窗-->
<ceshiModel @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup>
import { BasicTable, useTable, TableAction, useModal } from '3h1-ui';
import componentSetting from '@/settings/componentSetting';
import { columns, searchFormSchema } from './ceshi.data';
import ceshiModel from './ceshiModel.vue';
// 提示框
import { useMessage } from '@shy-plugins/use';
// 导入接口
import * as ceshiApi from '@/api/system/post';
//import { usePermission } from '@/hooks/web/usePermission'; 权限
//const { hasPermission } = usePermission();

const {
table: { fetchSetting },
} = componentSetting;

// model
const [registerModal, { openModal }] = useModal();

// 提示框
const { createMessage } = useMessage();

const [registerTable, { reload }] = useTable({
columns, // 表单列信息 BasicColumn[]
/*api: () => {
return new Promise((resolve) => {
resolve([
{ id: 1, name: '测试1', sort: 1, status: 1 },
{ id: 2, name: '测试2', sort: 2, status: 0 },
{ id: 3, name: '测试3', sort: 3, status: 0 },
{ id: 4, name: '测试4', sort: 4, status: 1 },
{ id: 5, name: '测试5', sort: 5, status: 1 },
]);
});
},*/
api: ceshiApi.getPostPageApi,
formConfig: {
// 表单配置
schemas: searchFormSchema, // 表单配置
},
rowSelection: { type: 'checkbox' }, // 选择列配置
clickToRowSelect: false, // 点击行是否选中 checkbox 或者 radio。需要开启
rowKey: 'id', // 根据唯一的 rowKey 更新指定行的数据
useSearchForm: true, // 使用搜索表单
pagination: true, // 分页信息配置,为 false 不显示分页
// handleSearchInfoFn: (data) => {
// console.log('sousuo*****',data)
//},
actionColumn: {
// 表格右侧操作列配置 BasicColumn
width: 200,
title: '操作',
dataIndex: 'action',
},
fetchSetting, // 接口请求配置,可以配置请求的字段和响应的字段名
});

// 点击新增添加的逻辑
function handleCreate() {
openModal(true, {
isUpdate: false,
});
}

// 删除操作
async function handleDelete(record: Recordable) {
// 调用删除接口
await ceshiApi.deletePostApi(record.id);
createMessage.success('删除成功');
reload();
}

// 修改
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
});
}

function handleSuccess() {
createMessage.success('操作成功');
reload();
}
</script>

2.Modal.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<template>
<!-- v-bind="$attrs"用于将弹窗组件的 attribute 传入 BasicModal 组件 -->
<BasicModal
v-bind="$attrs"
width="800px"
title="新增"
@register="registerModal"
@ok="handleSubmit"
>
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup name="ceshiModel">
import { BasicModal, BasicForm, useForm, useModalInner } from '3h1-ui';
import { formSchema } from './ceshi.data';
import * as ceshiApi from '@/api/system/post';

const emit = defineEmits(['success', 'register']);

// 控制组件的显示与隐藏
const isUpdate = ref(true);

// 行id
const rowId = ref<number>();

// useForm 表单配置对象 registerForm:表单对象 setFieldsValue:设置表单字段的值。resetFields:重置表单字段的值。validate:表单验证方法
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 100, // 标签宽度
baseColProps: { span: 12 }, // 基础列属性,用于设置列的宽度
schemas: formSchema, // 表单数据结构
showActionButtonGroup: false, // 是否显示操作按钮组,默认为 false
actionColOptions: {
// 操作列选项,用于设置操作列的宽度,这里设置为 span 为 23。
span: 23,
},
});

// useModalInner(callback) 用于操作独立组件
// 回调函数用于接收 openModal 第二个参数传递的值 是个对象
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false }); // setModalProps 方法将确认按钮的加载状态设置为 false
//
isUpdate.value = data?.isUpdate;

if (unref(isUpdate)) {
rowId.value = data.record.id;
// 数据回显
setFieldsValue({
...data.record,
});
}
});

// const getTitle = computed(() => (unref(isUpdate) ? '修改岗位' : '添加岗位'));

// 点击确定回调
async function handleSubmit() {
try {
// 表单校验
const values = await validate();
// 设置模态框的属性,将 confirmLoading 属性设置为 true,表示正在提交数据,需要显示加载动画。
setModalProps({ confirmLoading: true });
// TODO custom api
// 根据 isUpdate 变量的值判断是更新还是创建操作
// 如果 isUpdate 为真,则执行更新操作;否则执行创建操作。
if (unref(isUpdate)) {
values.id = rowId.value;
await ceshiApi.updatePostApi(values);
} else {
await ceshiApi.createPostApi(values);
}
// 关闭模态框
closeModal();
// 触发自定义事件 success,通知父组件表单提交成功
emit('success');
} finally {
// 表示提交数据完成,取消加载动画。
setModalProps({ confirmLoading: false });
}
}
</script>

3.data.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { BasicColumn, FormSchema } from '@/components/Table';

import { formatToDateTime } from '@shy-plugins/utils';

import { Tag } from 'ant-design-vue';
// 表格
export const columns: BasicColumn[] = [
{
title: '岗位编号',
dataIndex: 'id',
},
{
title: '岗位编码',
dataIndex: 'code',
width: 180,
},
{
title: '岗位名称',
dataIndex: 'name',
},
{
title: '岗位排序',
dataIndex: 'sort',
},
{
title: '状态',
dataIndex: 'status',
width: 160,
customRender: ({ record }) => {
const status = record.status;
const enable = ~~status === 0;
const color = enable ? 'green' : 'red';
const text = enable ? '启用' : '停用';
return h(Tag, { color: color }, () => text);
},
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180,
customRender: ({ text }) => {
return formatToDateTime(text);
},
},
];

// search 搜索框
export const searchFormSchema: FormSchema[] = [
{
field: 'code',
label: '岗位编码',
component: 'Input',
colProps: { span: 8 },
},
{
field: 'name',
label: '岗位名称',
component: 'Input',
colProps: { span: 8 },
},
{
field: 'status',
label: '状态',
component: 'Select',
componentProps: {
options: [
{ label: '启用', value: '0' },
{ label: '停用', value: '1' },
],
},
colProps: { span: 8 },
},
];

// 弹窗

export const formSchema: FormSchema[] = [
{ field: 'name', label: '岗位名称', component: 'Input', required: true },
{
field: 'code',
label: '岗位编码',
required: true,
component: 'Input',
},
{
field: 'sort',
label: '岗位顺序',
component: 'InputNumber',
required: true,
componentProps: {
min: 0,
},
},
{
field: 'status',
label: '岗位状态',
component: 'RadioButtonGroup',
defaultValue: 0,
componentProps: {
options: [
{ label: '启用', value: 0 },
{ label: '停用', value: 1 },
],
},
required: true,
},
{ field: 'remark', label: '备注', component: 'InputTextArea' },
];

4.封装 api

api/system/post/index.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { defHttp } from '@/utils/http/axios';

export interface PostVO {
id?: number;
name: string;
code: string;
sort: number;
status: number;
remark: string;
createTime?: Date;
}

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

export interface PostExportReqVO {
code?: string;
name?: string;
status?: number;
}

// 查询岗位列表
export const getPostPageApi = (params: PostPageReqVO) => {
return defHttp.get<PageResult<PostVO>>({ url: '/system/post/page', params });
};

// 获取岗位精简信息列表
export const listSimplePostsApi = () => {
return defHttp.get({ url: '/system/post/list-all-simple' });
};

// 查询岗位详情
export const getPostApi = (id: number) => {
return defHttp.get({ url: '/system/post/get?id=' + id });
};

// 新增岗位
export const createPostApi = (data: PostVO) => {
return defHttp.post({ url: '/system/post/create', data });
};

// 修改岗位
export const updatePostApi = (data: PostVO) => {
return defHttp.post({ url: '/system/post/update', data });
};

// 删除岗位
export const deletePostApi = (id: number) => {
return defHttp.post({ url: '/system/post/delete?id=' + id });
};

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