feat: 关系配置

This commit is contained in:
easy 2023-02-08 18:12:27 +08:00
parent 3b799e53d7
commit 37c8110ddc
4 changed files with 431 additions and 0 deletions

View File

@ -0,0 +1,13 @@
import server from '@/utils/request';
// 获取关系配置列表
export const getRelationshipList_api = (data: object) => server.post(`/relation/_query/`, data);
// 获取关联方列表
export const getObjectList_api = () => server.get(`/relation/types`);
// 新增关系
export const addRelation_api = (data: object) => server.post(`/relation`, data);
// 保存关系
export const editRelation_api = (data: object) => server.patch(`/relation`, data);
// 删除关系
export const delRelation_api = (id: string) => server.remove(`/relation/${id}`);

View File

@ -0,0 +1,18 @@
import BaseService from '@/utils/BaseService';
import { request } from 'umi';
import SystemConst from '@/utils/const';
class Service extends BaseService<ReationItem> {
getTypes = () =>
request(`/${SystemConst.API_BASE}/relation/types`, {
method: 'GET',
});
validator = (params: any) =>
request(`/${SystemConst.API_BASE}/relation/_validate?`, {
method: 'GET',
params,
});
}
export default Service;

View File

@ -0,0 +1,217 @@
<template>
<a-modal
v-model:visible="dialog.visible"
:title="dialog.title"
:maskClosable="false"
width="675px"
@ok="dialog.handleOk"
class="edit-dialog-container"
>
<a-form ref="formRef" :model="form.data" layout="vertical">
<a-form-item
label="名称"
name="name"
:rules="[
{ required: true, message: '请输入名称' },
{ max: 64, message: '最多可输入64个字符' },
]"
>
<a-input
v-model:value="form.data.name"
placeholder="请输入名称"
:maxlength="64"
/>
</a-form-item>
<a-form-item
name="relation"
label="标识"
:rules="[
{ required: true, message: '请输入标识' },
{ max: 64, message: '最多可输入64个字符' },
{ validator: form.rules.checkRelation, trigger: 'change' },
]"
>
<a-input
v-model:value="form.data.relation"
placeholder="请输入标识"
:maxlength="64"
:disabled="!!form.data.id"
/>
</a-form-item>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item
name="objectType"
label="关联方"
:rules="[{ required: true, message: '请选择关联方' }]"
>
<a-select
v-model:value="form.data.objectType"
:disabled="!!form.data.id"
>
<a-select-option
v-for="item in form.objectList"
:value="item.id"
>{{ item.name }}</a-select-option
>
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item
name="targetType"
label="标识"
:rules="[{ required: true, message: '请选择被关联方' }]"
>
<a-select
v-model:value="form.data.targetType"
:disabled="!!form.data.id"
>
<a-select-option
v-for="item in form.targetList"
:value="item.id"
>{{ item.name }}</a-select-option
>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item
name="description"
label="说明"
:rules="[{ max: 200, message: '最多可输入200个字符' }]"
>
<a-textarea
v-model:value="form.data.description"
placeholder="请输入说明"
show-count
:maxlength="200"
/>
</a-form-item>
</a-form>
<template #footer>
<a-button key="back" @click="dialog.visible = false">取消</a-button>
<a-button
key="submit"
type="primary"
:loading="form.loading"
@click="dialog.handleOk"
>确定</a-button
>
</template>
</a-modal>
</template>
<script setup lang="ts">
import { FormInstance, message } from 'ant-design-vue';
import { Rule } from 'ant-design-vue/es/form';
import {
getObjectList_api,
addRelation_api,
editRelation_api,
} from '@/api/system/relationship';
const emits = defineEmits(['refresh']);
//
const dialog = reactive({
title: '',
visible: false,
handleOk: () => {
formRef.value?.validate().then(() => {
form.submit();
});
},
//
changeVisible: (status: boolean, defaultForm: formType) => {
dialog.title = defaultForm.id ? '编辑' : '新增';
form.data = { ...defaultForm };
dialog.visible = status;
nextTick(() => {
formRef.value?.clearValidate();
});
},
});
//
const initForm: formType = {
name: '',
relation: '',
objectType: '',
targetType: '',
description: '',
};
const formRef = ref<FormInstance>();
const form = reactive({
loading: false,
data: {} as formType,
rules: {
checkRelation: (_rule: Rule, value: string): any => {
if (!value) return '';
const reg = new RegExp('^[0-9a-zA-Z_\\\\-]+$');
if (reg.test(value)) return Promise.resolve();
else
return Promise.reject(
'标识只能由数字、字母、下划线、中划线组成',
);
},
},
objectList: [] as any[],
targetList: [] as any[],
getObjectList: () => {
getObjectList_api().then((resp: any) => {
form.objectList = resp.result;
});
},
submit: () => {
formRef.value?.validate().then(() => {
const params = {
...form.data,
objectTypeName: form.objectList.find(
(item) => item.id === form.data.objectType,
).name,
targetTypeName: form.targetList.find(
(item) => item.id === form.data.targetType,
).name,
};
const api =
dialog.title === '编辑'
? editRelation_api
: addRelation_api;
api(params).then((resp: any) => {
if (resp.status === 200) {
message.success('操作成功');
emits('refresh');
dialog.visible = false;
}
});
});
},
});
form.getObjectList();
watch(
() => form.data.objectType,
(n) => {
form.targetList = n === 'device' ? [{ id: 'user', name: '用户' }] : [];
},
);
//
defineExpose({
openDialog: dialog.changeVisible,
});
type formType = {
name: string;
relation: string;
objectType: string;
targetType: string;
description: string;
id?: string;
};
</script>
<style scoped></style>

View File

@ -0,0 +1,183 @@
<template>
<div class="relationship-container">
<Search :columns="query.columns" @search="query.search" />
<JTable
ref="tableRef"
:columns="table.columns"
:request="getRelationshipList_api"
model="TABLE"
:params="query.params"
:defaultParams="{ sorts: [{ name: 'createTime', order: 'desc' }] }"
>
<template #headerTitle>
<a-button
type="primary"
@click="table.openDialog(undefined)"
style="margin-right: 10px"
><plus-outlined />新增</a-button
>
</template>
<template #action="slotProps">
<a-space :size="16">
<a-tooltip>
<template #title>编辑</template>
<a-button
style="padding: 0"
type="link"
@click="table.openDialog(slotProps)"
>
<edit-outlined />
</a-button>
</a-tooltip>
<a-popconfirm
title="确认删除"
ok-text="确定"
cancel-text="取消"
@confirm="table.clickDel(slotProps)"
>
<a-tooltip>
<template #title>删除</template>
<a-button style="padding: 0" type="link">
<delete-outlined />
</a-button>
</a-tooltip>
</a-popconfirm>
</a-space>
</template>
</JTable>
<EditDialog ref="editDialogRef" @refresh="table.refresh" />
</div>
</template>
<script setup lang="ts" name="Relationship">
import { getRelationshipList_api, delRelation_api } from '@/api/system/relationship';
import { message } from 'ant-design-vue';
import EditDialog from './components/EditDialog.vue';
import {
EditOutlined,
DeleteOutlined,
PlusOutlined,
} from '@ant-design/icons-vue';
const query = {
columns: [
{
title: '名称',
dataIndex: 'name',
key: 'name',
ellipsis: true,
fixed: 'left',
search: {
type: 'string',
},
},
{
title: '关联方',
dataIndex: 'objectTypeName',
key: 'objectTypeName',
ellipsis: true,
fixed: 'left',
search: {
type: 'select',
options: [
{
label: '启用',
value: 1,
},
{
label: '禁用',
value: 0,
},
],
},
},
{
title: '被关联方',
dataIndex: 'targetType',
key: 'targetType',
ellipsis: true,
fixed: 'left',
search: {
type: 'select',
options: [
{
label: '用户',
value: 'user',
},
],
},
},
{
title: '说明',
dataIndex: 'description',
key: 'description',
ellipsis: true,
fixed: 'left',
search: {
type: 'string',
},
},
],
params: {},
search: (params: object) => {
query.params = params;
},
};
const editDialogRef = ref(); //
const tableRef = ref<Record<string, any>>({}); //
const table = {
columns: [
{
title: '名称',
dataIndex: 'name',
key: 'name',
},
{
title: '关联方',
dataIndex: 'objectTypeName',
key: 'objectTypeName',
},
{
title: '被关联方',
dataIndex: 'targetTypeName',
key: 'targetTypeName',
},
{
title: '说明',
dataIndex: 'description',
key: 'description',
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
scopedSlots: true,
},
],
//
openDialog: (row: object | undefined = {}) => {
editDialogRef.value.openDialog(true, row)
},
//
clickDel: (row: any) => {
delRelation_api(row.id).then((resp: any) => {
if (resp.status === 200) {
tableRef.value?.reload();
message.success('操作成功!');
}
});
},
//
refresh: () => {
tableRef.value.reload();
},
};
</script>
<style lang="less" scoped>
.relationship-container {
padding:24px ;
}
</style>