Commit 6c974505 authored by zxw's avatar zxw

SQL审核和审核策略-页面

parent a67e1751
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
ref="treeRef2"
toolbar
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="false"
:defaultExpandAll="true"
:treeData="treeDataTwo"
:fieldNames="{ key: 'selectedDeptId', title: 'label' }"
@select="handleSelect"
/>
</div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, unref } from 'vue';
import { BasicTree, TreeActionType, TreeItem } from '@/components/Tree';
import { Nullable } from '@vben/types';
import { treeDataList, treeDataListTwo } from './mock';
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
const treeDataTwo = ref<TreeItem[]>([]);
const treeRef1 = ref<Nullable<TreeActionType>>(null);
const treeRef2 = ref<Nullable<TreeActionType>>(null);
async function fetch() {
treeData.value = treeDataList;
treeDataTwo.value = treeDataListTwo;
await nextTick(() => {
getTree(treeRef1).expandAll(true);
getTree(treeRef2).expandAll(true);
});
}
function getTree(treeRef) {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
}
function handleSelect(selectedDeptId) {
emit('select', selectedDeptId[0]);
console.log('selectedDeptId:', selectedDeptId);
}
onMounted(() => {
fetch();
});
</script>
<template>
<BasicModal width="40%" v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<div style="display: flex;align-items: center;justify-content: space-between">
<div class="choseOB_title">选择审核规则</div>
</div>
<Tabs default-active-key="1" @change="changeTabs">
<Tabs.TabPane >
<div class="addDialogBG">
<a-input >
<template #prefix>
<Icon style="float: right" icon="ant-design:search-outlined" :size="20" />
</template>
</a-input>
<BasicTree
style="margin-top: 10px; background-color: #E8ECF7; height: 340px"
:treeData="treeDataTwo"
:checkable="true"
:defaultExpandAll="true"
/>
<CheckboxGroup v-model="selectedValues">
<div v-for="(item) in plainOptionsThree" :span="24" class="checkRow">
<Checkbox :value="item">{{ item }}</Checkbox>
<Icon icon="ant-design:delete-outlined" :size="25" :color="'#ED6F6F'" />
</div>
</CheckboxGroup>
<p style="margin-left: 100px; font-size: 11px">多个用户用英文逗号分隔</p>
</div>
<BasicForm @register="registerForm" />
</Tabs.TabPane>
</Tabs>
</BasicModal>
</template>
<script lang="ts" setup>
import Icon from '@/components/Icon/Icon.vue';
import { Tabs,Checkbox,CheckboxGroup } from 'ant-design-vue';
import {ref, computed, unref, reactive} from 'vue';
import {BasicModal, useModalInner} from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './mainBody.data';
import {treeDataTwo} from "./mock";
import {BasicTree} from "@/components/Tree";
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const rowId = ref('');
const selectedValues = reactive([])
const plainOptionsThree = reactive(
[
]
) ;
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 100,
baseColProps: { lg: 24, md: 24 },
schemas: formSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
// 通过id获取行详情信息
// 塞值
setFieldsValue({
...data.record,
});
}
});
const getTitle = computed(() => ('添加规则'));
function changeTabs(activeKey: any) {
console.log('activeKey',activeKey)
}
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
// TODO custom api
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="scss" scoped>
.choseOB_title{
font-weight: 600;
}
::v-deep.ant-checkbox-group{
display: grid;
}
.checkRow{
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 5px;
}
.addDialogBG{
background-color: #E8ECF7;
width: 100%;
height: 400px;
}
</style>
<template>
<BasicModal
width="40%"
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
>
<div>
<Alert style="margin-bottom: 20px; background: #fff5e9" message="批量设置将覆盖原有规则的数据库用户,请谨慎操作" type="warning" show-icon closable />
</div>
<BasicForm @register="registerForm" />
<p style="margin-left: 100px; margin-top: -20px; font-size: 11px">多个用户用英文逗号分隔</p>
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './mainBody.data';
import {Alert} from "ant-design-vue";
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const [registerForm, { setFieldsValue, updateSchema, resetFields }] = useForm({
labelWidth: 100,
baseColProps: { lg: 12, md: 24 },
schemas: formSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
const formData = {
taskId: '100',
};
// 塞值
setFieldsValue({
...formData,
});
updateSchema([
{
field: 'taskId',
},
]);
});
const getTitle = computed(() => '批量设置数据库用户');
/**确定按钮*/
async function handleSubmit() {
closeModal();
}
</script>
<template>
<BasicModal
width="50%"
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
>
<BasicForm
@register="registerForm"
>
<template #ruleContentSlot>
<div class="editor">
<CodeEditor
v-model:value="sql"
/>
</div>
</template>
</BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { computed} from 'vue';
import {ref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import {tableList} from "./mock"
import {editPublicCodeSchema} from './mainBody.data';
import { useMessage } from '@/hooks/web/useMessage';
import CodeEditor from "@/components/CodeEditor/src/CodeEditor.vue";
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
const sql = ref(tableList[0].sql);
const getTitle = computed(() => ('编辑规则'));
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const [registerForm, { setFieldsValue, resetFields }] = useForm({
labelWidth: 100,
baseColProps: { lg: 12, md: 24 },
schemas: editPublicCodeSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
setFieldsValue({
...data.record,
})
});
/**确定按钮*/
async function handleSubmit() {
createMessage.success('编辑成功');
closeModal()
}
</script>
<style scoped>
.editor {
width: 585px;
background-color: white;
height: 333px;
border: 1px solid #d9d9d9;
padding: 16px;
margin-bottom: 8px;
}
</style>
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex" >
<DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
<BasicTable
@register="registerTable"
class="w-3/4 xl:w-4/5"
:searchInfo="searchInfo"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'ant-design:form-outlined',
// label: '编辑',
onClick: editButton.bind(null, record),
},
{
icon: 'ant-design:delete-outlined',
},
]"
/>
</template>
</template>
<template #toolbar>
<a-input style="width: 170px; margin-right: auto" placeholder="输入关键字搜索" allowClear >
<template #prefix>
<Icon style="float: right" icon="ant-design:search-outlined" :size="20" />
</template>
</a-input>
<a-input style="width: 170px; margin-right: 120px" placeholder="搜索数据库用户" allowClear />
<div style="display: flex;margin-top: 10px">
<p style="width: 60px; margin-right: 10px">策略状态</p>
<Switch v-model:checked="state.checked1" />
</div>
<a-button type="primary" @click="batchSetDatabaseUsersModal">批量设置数据库用户</a-button>
<a-button type="primary">移除规则</a-button>
<a-button type="primary" @click="addRules">添加规则</a-button>
</template>
</BasicTable>
<BatchSetDatabaseUsersModal @register="DatabaseUsersModal" />
<addRulesMode @register="registerModal" />
<EditRulesModal @register="registerEditPublicCodeModal" />
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import {BasicTable, TableAction, useTable} from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import DeptTree from './DeptTree.vue';
import { ref } from 'vue';
import { tableList } from './mock';
import { columns } from './mainBody.data';
import addRulesMode from './addRulesMode.vue';
import { Switch } from 'ant-design-vue';
import {useModal} from "@/components/Modal";
import Icon from "@/components/Icon/Icon.vue";
import BatchSetDatabaseUsersModal from "./batchSetDatabaseUsersModal.vue";
import EditRulesModal from "./editRulesModal.vue";
defineOptions({ name: 'AccountManagement' });
const state = reactive({
checked1: true,
checked2: false,
});
const [registerEditPublicCodeModal, { openModal: openEditPublicCodeModal }] = useModal();
const selectedDeptId = ref<string | null>(null);
const [registerModal, { openModal }] = useModal();
const [DatabaseUsersModal, { openModal: openCreateCreateMainBodyModal }] =
useModal(); // 新建质量主体弹窗
const searchInfo = reactive<Recordable>({});
const [
registerTable,
{ },
] = useTable({
api: async (params) => {
console.log('tableList', tableList);
const response = {
pageNu: '1',
pageSize: '10',
pages: '1',
total: tableList.length,
code: '',
message: '',
data: tableList,
};
return { ...response };
},
rowKey: 'businessId',
columns,
formConfig: {
labelWidth: 10,
autoSubmitOnEnter: true,
},
rowSelection: true,
useSearchForm: false,
showIndexColumn: false,
showTableSetting: false,
bordered: true,
handleSearchInfoFn(info) {
console.log('handleSearchInfoFn', info);
return info;
},
actionColumn: {
width: 170,
title: '操作',
dataIndex: 'action',
},
});
function addRules() {
openModal(true, {
isUpdate: false,
});
}
/**编辑*/
function editButton(record) {
openEditPublicCodeModal(true,{
record:record
})
}
/**批量设置数据库用户*/
function batchSetDatabaseUsersModal() {
openCreateCreateMainBodyModal(true, {
isAdd: true,
});
}
// 处理选择节点事件
const handleSelect = (deptId) => {
selectedDeptId.value = deptId;
console.log('选择节点selectedDeptId:', deptId);
}
</script>
import {BasicColumn, FormSchema} from '@/components/Table';
export const columns: BasicColumn[] = [
{
title: '规则名称',
dataIndex: 'ruleName',
width: 150,
},
{
title: '规则描述',
dataIndex: 'ruleDescription',
width: 120,
},
{
title: '数据库用户',
dataIndex: 'databaseUser',
width: 120,
},
{
title: '规则处置',
dataIndex: 'ruleHandling',
width: 120,
},
{
title: '处置建议',
dataIndex: 'disposalSuggestions',
width: 120,
},
];
/** 添加规则表单字段*/
export const formSchema: any[] = [
{
field: 'databaseUser',
label: '数据库用户',
component: 'Input',
colProps: { lg: 24, md: 24 },
componentProps: {
placeholder: 'user001,user002',
options: [
],
},
rules: [
{
// required: true,
// message: '请选择保护动作',
},
],
},
]
/**编辑公共代码 表单4*/
export const editPublicCodeSchema: FormSchema[] = [
{
field: 'ruleName',
label: '规则名称',
component: 'Input',
componentProps: {
placeholder: '请输入规则名称',
},
colProps: { lg: 24, md: 24 },
},
{
field: 'ruleDescription',
label: '规则描述',
component: 'Input',
componentProps: {
placeholder: '请输入规则描述',
},
colProps: { lg: 24, md: 24 },
},
{
field: 'ruleHandling',
label: '规则处置',
colProps: { lg: 11, md: 11, },
component: 'Select',
componentProps: {
placeholder: '规则处置方式',
options: [
{ label: '建议优化', value: '1' },
{ label: '禁止执行', value: '2' },
{ label: 'admin', value: '3' },
],
},
},
{
field: 'sourceSystemCodeValue',
label: '处置建议',
component: 'Input',
componentProps: {
placeholder: '请输入处置建议',
},
colProps: { lg: 24, md: 24 },
},
{
field: 'sql',
label: '规则内容',
slot: 'ruleContentSlot',
},
{
field: 'databaseUser',
label: '数据库用户',
component: 'Input',
componentProps: {
placeholder: '请输入数据库用户',
},
colProps: { lg: 24, md: 24 },
},
];
import {TreeItem} from "@/components/Tree";
export const tableList: any[] = [
{
selectedDeptId: 23,
ruleName: 'has_agg',
ruleDescription: '类型不为int或者bigint时报错',
databaseUser: 'user001,user002',
ruleHandling: '建议优化',
disposalSuggestions: '',
sql:
'SELECT COUNT(*)\n' +
'FROM $(table a}\n' +
'WHERE ${column a}IS NOT NULL AND ${column a}NOT IN (${range a})',
},
{
selectedDeptId: 24,
ruleName: 'is_Param_Of_Agg',
ruleDescription: 'select * 时报错',
databaseUser: 'user001,user002',
ruleHandling: '建议优化',
disposalSuggestions: '',
sql:
'qqqqSELECT COUNT(*)\n' +
'FROM $(table a}\n' +
'WHERE ${column a}IS NOT NULL AND ${column a}NOT IN (${range a})',
},
{
selectedDeptId: 25,
ruleName: 'is_Location_Exists',
ruleDescription: '在多个改同一个表的语句出现时报错',
databaseUser: 'user001,user002',
ruleHandling: '建议优化',
disposalSuggestions: '',
sql:
'wwwwSELECT COUNT(*)\n' +
'FROM $(table a}\n' +
'WHERE ${column a}IS NOT NULL AND ${column a}NOT IN (${range a})',
},
];
export const treeDataList = [
{
label: '审核规则',
businessId: 1,
children: [
{
// {
// label: 'admin_个人工作区',
// businessId: 2,
// children: [
// { label: '个人工作区1', businessId: 6 },
// { label: '个人工作区2', businessId: 7 },
// ],
// },
// { label: '共享工作区', businessId: 3 },
// { label: '商城工作区', businessId: 4 },
// { label: '指标工作区', businessId: 5 },
}
],
},
];
export const treeDataListTwo = [
{
label: '数据连接',
selectedDeptId: 21,
children: [
{ label: 'ArgoDB-001', selectedDeptId: 23 },
{ label: 'ArgoDB-002', selectedDeptId: 24 },
{ label: 'ArgoDB-003', selectedDeptId: 25 },
{ label: 'ArgoDB-004', selectedDeptId: 26 },
{ label: 'ArgoDB-005', selectedDeptId: 27 },
],
},
];
export const treeDataTwo: TreeItem[] = [
{
title: '全部审核规则 ',
key: '0-0',
icon: 'ion:settings-outline',
children: [
{
title: '错误问题规则',
key: '0-0-1',
children: [
{
title: 'has_agg',
key: '0-0-2',
icon: 'ion:settings-outline',
},
{
title: 'is_Param_Of_Agg',
key: '0-0-3',
icon: 'ion:settings-outline',
},
{
title: 'is_Location_Exists',
key: '0-0-4',
icon: 'ion:settings-outline',
},
],
},
],
},
];
......@@ -2,14 +2,14 @@
<div class="m-4 mr-0 overflow-hidden bg-white">
<div class="m-4 mr-0 overflow-hidden bg-white" style="margin-bottom: -20px">
<BasicTree
ref="treeRef"
ref="treeRef1"
toolbar
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="true"
:defaultExpandAll="true"
:treeData="treeData"
:fieldNames="{ key: 'businessId', title: 'label' }"
:fieldNames="{ key: 'businessId', title: 'label'}"
@select="handleSelect"
/>
</div>
......@@ -19,54 +19,61 @@
</template>
</a-input>
<BasicTree
ref="treeRef"
ref="treeRef2"
toolbar
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="true"
:clickRowToExpand="false"
:defaultExpandAll="true"
:treeData="treeDataTwo"
:fieldNames="{ key: 'businessId', title: 'label' }"
:fieldNames="{ key: 'selectedDeptId', title: 'label' }"
@select="handleSelect"
/>
</div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, unref } from 'vue';
import { BasicTree, TreeActionType, TreeItem } from '@/components/Tree';
import { nextTick, onMounted, ref, unref } from 'vue';
import { BasicTree, TreeActionType, TreeItem } from '@/components/Tree';
import { Nullable } from '@vben/types';
import { treeDataList, treeDataListTwo } from './mock';
import Icon from "@/components/Icon/Icon.vue";
import { Nullable } from '@vben/types';
import { treeDataList, treeDataListTwo } from './mock';
import Icon from "@/components/Icon/Icon.vue";
defineOptions({ name: 'DeptTree' });
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
const treeDataTwo = ref<TreeItem[]>([]);
const treeRef = ref<Nullable<TreeActionType>>(null);
const treeData = ref<TreeItem[]>([]);
const treeDataTwo = ref<TreeItem[]>([]);
const treeRef1 = ref<Nullable<TreeActionType>>(null);
const treeRef2 = ref<Nullable<TreeActionType>>(null);
async function fetch() {
async function fetch() {
treeData.value = treeDataList;
treeDataTwo.value = treeDataListTwo;
await nextTick(() => {
getTree().expandAll(true);
getTree(treeRef1).expandAll(true);
getTree(treeRef2).expandAll(true);
});
}
function getTree() {
}
function getTree(treeRef) {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
}
}
function handleSelect(keys) {
emit('select', keys[0]);
}
onMounted(() => {
function handleSelect(selectedDeptId) {
emit('select', selectedDeptId[0]);
console.log('selectedDeptId:', selectedDeptId);
}
onMounted(() => {
fetch();
});
});
</script>
<template >
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex" >
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex flex-col" class="toolbar" style="width: 910px;">
<div class="toolbar" style="background: white" >
<div class="tools" >
<a-button type="primary" style="float: right; margin: 10px 15px 10px 0">保存</a-button>
</div>
</div>
<BasicForm
style="background: white"
size="middle"
:bordered="false"
:column="2"
:model="info"
@register="registerGuideModeForm"
>
<template #ruleContentSlot>
<div class="editor">
<CodeEditor v-model:value="sql" />
</div>
</template>
<template #buttonSlot>
<div class="buttonVerification">
<a-button style="margin-left: 100px; width: 80px" type="primary">检查</a-button>
<Alert style="height: 34px; margin-left: 10px; " message="检查通过" type="success" show-icon closable />
<Alert style="height: 34px; margin-left: 10px; display: none;" message="检查信息说明" type="info" show-icon closable />
<Alert style="height: 34px; margin-left: 10px; display: none;" message="检查异常" type="warning" show-icon closable />
<Alert style="height: 34px; margin-left: 10px; display: none;" message="检查错误" type="error" show-icon closable />
</div>
</template>
</BasicForm>
</PageWrapper>
</PageWrapper>
</template>
<script lang="ts" setup>
import {ref, } from 'vue';
import {PageWrapper} from "@/components/Page";
import {tableList} from "@/views/scriptDevelopment/sqlAudit/mock";
import {personSchema} from "@/views/scriptDevelopment/sqlAudit/mainBody.data";
import {BasicForm, useForm} from "@/components/Form";
import CodeEditor from "@/components/CodeEditor/src/CodeEditor.vue";
import {Alert} from "ant-design-vue";
const sql = ref(tableList[0].sql);
// 初始化 info 为一个响应式对象
const info = ref({...tableList[0]});
console.log("info数据:",info);
const [registerGuideModeForm] = useForm({
labelWidth: 100,
schemas: personSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
</script>
<style scoped>
.editor {
width: 784px;
background-color: white;
height: 333px;
border: 1px solid #d9d9d9;
padding: 16px;
margin-bottom: 8px;
}
.buttonVerification{
height: 162px;
display: flex;
}
</style>
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex" >
<DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
<BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo">
<editAuditRulesModal
style="background: #cc0000;"
class="w-3/4 xl:w-4/5"
v-if="isSpecificDeptSelected"
:deptId="selectedDeptId"
/>
<BasicTable
@register="registerTable"
class="w-3/4 xl:w-4/5"
:searchInfo="searchInfo"
v-else
>
<template #bodyCell="{ column }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'ant-design:form-outlined',
},
{
icon: 'ant-design:exclamation-circle-outlined',
},
{
icon: 'ant-design:ellipsis-outlined',
},
]"
/>
</template>
</template>
<template #toolbar>
<a-input style="width: 200px; margin-right: auto" placeholder="输入关键字搜索" allowClear />
<a-button >删除</a-button>
<a-button >移动</a-button>
<a-button type="primary">新建文件夹</a-button>
<a-button type="primary">新建文件</a-button>
</template>
</BasicTable>
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive,onMounted } from 'vue';
import { BasicTable, useTable } from '@/components/Table';
import { reactive, computed } from 'vue';
import {BasicTable, TableAction, useTable} from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import DeptTree from './DeptTree.vue';
import { ref } from 'vue';
import { tableList } from './mock';
import { columns, searchFormSchema } from './mainBody.data';
import { useRoute, onBeforeRouteLeave } from 'vue-router';
import { useFilterStore } from '@/store/modules/filterData';
import { columns } from './mainBody.data';
import EditAuditRulesModal from "@/views/scriptDevelopment/sqlAudit/editAuditRulesModal.vue";
defineOptions({ name: 'AccountManagement' });
const filterStore = useFilterStore();
const route = useRoute();
const isSpecificDeptSelected = computed(() => {
return [23, 24, 25].includes(selectedDeptId.value);
});
// 选中的部门ID
const selectedDeptId = ref<string | null>(null);
const searchInfo = reactive<Recordable>({});
const [
registerTable,
{ reload, getSearchInfo, getForm },
{ },
] = useTable({
title: '质量任务列表',
api: async (params) => {
console.log('tableList', tableList);
const response = {
......@@ -56,17 +91,16 @@ const [
},
rowKey: 'businessId',
rowSelection: true,
columns,
formConfig: {
labelWidth: 10,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
resetFunc: () => {
searchInfo.deptId = '';
},
},
useSearchForm: true,
rowSelection: true,
useSearchForm: false,
showIndexColumn: false,
showTableSetting: false,
bordered: true,
handleSearchInfoFn(info) {
......@@ -81,42 +115,13 @@ const [
});
// 处理选择节点事件
const handleSelect = (deptId) => {
selectedDeptId.value = deptId;
/** 部门树的select*/
function handleSelect(deptId = '') {
searchInfo.deptId = deptId;
reload();
console.log('选择节点selectedDeptId:', deptId);
}
onMounted(() => {
const path = route.path;
if (filterStore.getSearchParams[path]) {
if (JSON.parse(filterStore.getSearchParams[path] !== {})) {
const params = JSON.parse(filterStore.getSearchParams[path]);
console.log('11111111111111111111111111111', params);
getForm().setFieldsValue({
page: params.page,
pageSize: params.pageSize,
username: params.username,
flag: params.flag,
});
searchInfo.deptId = params.deptId;
}
}
});
onBeforeRouteLeave((to, from, next) => {
const params = Object.assign({}, getSearchInfo(), getForm().getFieldsValue());
console.log('path', from.path);
console.log('params', params);
filterStore.setSearchParams({
path: from.path,
param: {
...params,
},
});
next(); // 允许导航
});
</script>
import { BasicColumn, FormSchema } from '@/components/Table';
import {BasicColumn, FormSchema} from '@/components/Table';
export const columns: BasicColumn[] = [
{
title: '名称',
dataIndex: 'name',
width: 120,
width: 150,
sorter: true,
},
{
title: '规则描述',
dataIndex: 'ruleDescription',
width: 120,
sorter: true,
},
{
title: '规则类型',
......@@ -41,23 +40,61 @@ export const columns: BasicColumn[] = [
title: '拥有者',
dataIndex: 'owner',
width: 150,
sorter: true,
},
];
export const searchFormSchema: FormSchema[] = [
export const personSchema: FormSchema[] = [
{
field: 'name',
label: ' ',
component: 'Input',
colProps: { span: 8 },
colProps: { lg: 11, md: 11 },
label: '名称',
required: true,
},
{
field: 'ruleDescription',
label: '规则描述',
colProps: { lg: 11, md: 11 },
component: 'InputTextArea',
},
{
field: 'ruleHandling',
label: '规则处置',
colProps: { lg: 11, md: 11, },
component: 'Select',
required: true,
componentProps: {
placeholder: '输入关键字搜索',
placeholder: '规则处置方式',
options: [
{ label: '建议优化', value: '1' },
{ label: '禁止执行', value: '2' },
{ label: 'admin', value: '3' },
],
},
},
{
field: 'disposalSuggestions',
label: '处置建议',
colProps: { lg: 11, md: 11 },
component: 'InputTextArea',
required: true,
componentProps: {
placeholder: '请输入处置建议',
},
},
{
field: 'sql',
label: '规则内容',
required: true,
slot: 'ruleContentSlot',
},
{
field: 'ruleContent',
slot: 'buttonSlot',
},
];
export const tableList: any[] = [
{
businessId: 1,
selectedDeptId: 23,
name: 'has_agg',
ruleDescription: 'has_agg',
ruleType: '预置规则',
......@@ -9,10 +11,15 @@ export const tableList: any[] = [
creationTime: '2019/12/12 21:21:21',
updateTime: '2019/12/12 21:21:21',
owner: 'admin',
sql:
'sql.type = createtable\n' +
'and\n' +
'{\n'+
'sql.partitions.size * sql.buckets.size <= 10000\n'+
'}',
},
{
businessId: 2,
selectedDeptId: 24,
name: 'is_Param_Of_Agg',
ruleDescription: 'is_Param_Of_Agg',
ruleType: '自定义规则',
......@@ -20,10 +27,13 @@ export const tableList: any[] = [
creationTime: '2019/12/12 21:21:21',
updateTime: '2019/12/12 21:21:21',
owner: 'admin',
sql:
'SELECT COUNT(*)\n' +
'FROM $(table a}\n' +
'WHERE ${column a}IS NOT NULL AND ${column a}NOT IN (${range a})',
},
{
businessId: 3,
selectedDeptId: 25,
name: 'is_Location_Exists',
ruleDescription: 'is_Location_Exists',
ruleType: '自定义规则',
......@@ -31,7 +41,10 @@ export const tableList: any[] = [
creationTime: '2019/12/12 21:21:21',
updateTime: '2019/12/12 21:21:21',
owner: 'admin',
sql:
'SELECT COUNT(*)\n' +
'FROM $(table a}\n' +
'WHERE ${column a}IS NOT NULL AND ${column a}NOT IN (${range a})',
},
];
......@@ -60,17 +73,17 @@ export const treeDataList = [
export const treeDataListTwo = [
{
label: '提示规则',
businessId: 1,
selectedDeptId: 21,
children: [
],
},
{
label: '错误问题规则',
businessId: 2,
selectedDeptId: 22,
children: [
{ label: 'has_agg', businessId: 3 },
{ label: 'is_Param_Of_Agg', businessId: 4 },
{ label: 'is_Location_Exists', businessId: 5 },
{ label: 'has_agg', selectedDeptId: 23 },
{ label: 'is_Param_Of_Agg', selectedDeptId: 24 },
{ label: 'is_Location_Exists', selectedDeptId: 25 },
],
},
];
// vite.config.ts
import { defineApplicationConfig } from "file:///D:/workapace/vue_workspace/bigdatasystem1/internal/vite-config/dist/index.mjs";
var vite_config_default = defineApplicationConfig({
overrides: {
optimizeDeps: {
include: [
"echarts/core",
"echarts/charts",
"echarts/components",
"echarts/renderers",
"qrcode",
"@iconify/iconify",
"ant-design-vue/es/locale/zh_CN",
"ant-design-vue/es/locale/en_US"
]
},
server: {
proxy: {
"/basic-api": {
// target: 'http://localhost:3000',
target: "http://106.3.97.198:20062/",
// target: `http://192.168.0.9:8082/`,
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^/basic-api`), "")
// only https
// secure: false
},
"/upload": {
target: "http://localhost:3300/upload",
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^/upload`), "")
}
},
open: true,
// 项目启动后,自动打开
warmup: {
clientFiles: ["./index.html", "./src/{views,components}/*"]
}
}
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFx3b3JrYXBhY2VcXFxcdnVlX3dvcmtzcGFjZVxcXFxiaWdkYXRhc3lzdGVtMVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRDpcXFxcd29ya2FwYWNlXFxcXHZ1ZV93b3Jrc3BhY2VcXFxcYmlnZGF0YXN5c3RlbTFcXFxcdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0Q6L3dvcmthcGFjZS92dWVfd29ya3NwYWNlL2JpZ2RhdGFzeXN0ZW0xL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQXBwbGljYXRpb25Db25maWcgfSBmcm9tICdAdmJlbi92aXRlLWNvbmZpZyc7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUFwcGxpY2F0aW9uQ29uZmlnKHtcbiAgb3ZlcnJpZGVzOiB7XG4gICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICBpbmNsdWRlOiBbXG4gICAgICAgICdlY2hhcnRzL2NvcmUnLFxuICAgICAgICAnZWNoYXJ0cy9jaGFydHMnLFxuICAgICAgICAnZWNoYXJ0cy9jb21wb25lbnRzJyxcbiAgICAgICAgJ2VjaGFydHMvcmVuZGVyZXJzJyxcbiAgICAgICAgJ3FyY29kZScsXG4gICAgICAgICdAaWNvbmlmeS9pY29uaWZ5JyxcbiAgICAgICAgJ2FudC1kZXNpZ24tdnVlL2VzL2xvY2FsZS96aF9DTicsXG4gICAgICAgICdhbnQtZGVzaWduLXZ1ZS9lcy9sb2NhbGUvZW5fVVMnLFxuICAgICAgXSxcbiAgICB9LFxuICAgIHNlcnZlcjoge1xuICAgICAgcHJveHk6IHtcbiAgICAgICAgJy9iYXNpYy1hcGknOiB7XG4gICAgICAgICAgLy8gdGFyZ2V0OiAnaHR0cDovL2xvY2FsaG9zdDozMDAwJyxcbiAgICAgICAgICB0YXJnZXQ6ICdodHRwOi8vMTA2LjMuOTcuMTk4OjIwMDYyLycsXG4gICAgICAgICAgLy8gdGFyZ2V0OiBgaHR0cDovLzE5Mi4xNjguMC45OjgwODIvYCxcbiAgICAgICAgICBjaGFuZ2VPcmlnaW46IHRydWUsXG4gICAgICAgICAgd3M6IHRydWUsXG4gICAgICAgICAgcmV3cml0ZTogKHBhdGgpID0+IHBhdGgucmVwbGFjZShuZXcgUmVnRXhwKGBeL2Jhc2ljLWFwaWApLCAnJyksXG4gICAgICAgICAgLy8gb25seSBodHRwc1xuICAgICAgICAgIC8vIHNlY3VyZTogZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgJy91cGxvYWQnOiB7XG4gICAgICAgICAgdGFyZ2V0OiAnaHR0cDovL2xvY2FsaG9zdDozMzAwL3VwbG9hZCcsXG4gICAgICAgICAgY2hhbmdlT3JpZ2luOiB0cnVlLFxuICAgICAgICAgIHdzOiB0cnVlLFxuICAgICAgICAgIHJld3JpdGU6IChwYXRoKSA9PiBwYXRoLnJlcGxhY2UobmV3IFJlZ0V4cChgXi91cGxvYWRgKSwgJycpLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG9wZW46IHRydWUsIC8vIFx1OTg3OVx1NzZFRVx1NTQyRlx1NTJBOFx1NTQwRVx1RkYwQ1x1ODFFQVx1NTJBOFx1NjI1M1x1NUYwMFxuICAgICAgd2FybXVwOiB7XG4gICAgICAgIGNsaWVudEZpbGVzOiBbJy4vaW5kZXguaHRtbCcsICcuL3NyYy97dmlld3MsY29tcG9uZW50c30vKiddLFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQXFULFNBQVMsK0JBQStCO0FBRTdWLElBQU8sc0JBQVEsd0JBQXdCO0FBQUEsRUFDckMsV0FBVztBQUFBLElBQ1QsY0FBYztBQUFBLE1BQ1osU0FBUztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxJQUNBLFFBQVE7QUFBQSxNQUNOLE9BQU87QUFBQSxRQUNMLGNBQWM7QUFBQTtBQUFBLFVBRVosUUFBUTtBQUFBO0FBQUEsVUFFUixjQUFjO0FBQUEsVUFDZCxJQUFJO0FBQUEsVUFDSixTQUFTLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxPQUFPLGFBQWEsR0FBRyxFQUFFO0FBQUE7QUFBQTtBQUFBLFFBRy9EO0FBQUEsUUFDQSxXQUFXO0FBQUEsVUFDVCxRQUFRO0FBQUEsVUFDUixjQUFjO0FBQUEsVUFDZCxJQUFJO0FBQUEsVUFDSixTQUFTLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxPQUFPLFVBQVUsR0FBRyxFQUFFO0FBQUEsUUFDNUQ7QUFBQSxNQUNGO0FBQUEsTUFDQSxNQUFNO0FBQUE7QUFBQSxNQUNOLFFBQVE7QUFBQSxRQUNOLGFBQWEsQ0FBQyxnQkFBZ0IsNEJBQTRCO0FBQUEsTUFDNUQ7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
// vite.config.ts
import { defineApplicationConfig } from "file:///D:/workapace/vue_workspace/bigdatasystem1/internal/vite-config/dist/index.mjs";
var vite_config_default = defineApplicationConfig({
overrides: {
optimizeDeps: {
include: [
"echarts/core",
"echarts/charts",
"echarts/components",
"echarts/renderers",
"qrcode",
"@iconify/iconify",
"ant-design-vue/es/locale/zh_CN",
"ant-design-vue/es/locale/en_US"
]
},
server: {
proxy: {
"/basic-api": {
// target: 'http://localhost:3000',
target: "http://106.3.97.198:20062/",
// target: `http://192.168.0.9:8082/`,
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^/basic-api`), "")
// only https
// secure: false
},
"/upload": {
target: "http://localhost:3300/upload",
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^/upload`), "")
}
},
open: true,
// 项目启动后,自动打开
warmup: {
clientFiles: ["./index.html", "./src/{views,components}/*"]
}
}
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFx3b3JrYXBhY2VcXFxcdnVlX3dvcmtzcGFjZVxcXFxiaWdkYXRhc3lzdGVtMVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRDpcXFxcd29ya2FwYWNlXFxcXHZ1ZV93b3Jrc3BhY2VcXFxcYmlnZGF0YXN5c3RlbTFcXFxcdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0Q6L3dvcmthcGFjZS92dWVfd29ya3NwYWNlL2JpZ2RhdGFzeXN0ZW0xL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQXBwbGljYXRpb25Db25maWcgfSBmcm9tICdAdmJlbi92aXRlLWNvbmZpZyc7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUFwcGxpY2F0aW9uQ29uZmlnKHtcbiAgb3ZlcnJpZGVzOiB7XG4gICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICBpbmNsdWRlOiBbXG4gICAgICAgICdlY2hhcnRzL2NvcmUnLFxuICAgICAgICAnZWNoYXJ0cy9jaGFydHMnLFxuICAgICAgICAnZWNoYXJ0cy9jb21wb25lbnRzJyxcbiAgICAgICAgJ2VjaGFydHMvcmVuZGVyZXJzJyxcbiAgICAgICAgJ3FyY29kZScsXG4gICAgICAgICdAaWNvbmlmeS9pY29uaWZ5JyxcbiAgICAgICAgJ2FudC1kZXNpZ24tdnVlL2VzL2xvY2FsZS96aF9DTicsXG4gICAgICAgICdhbnQtZGVzaWduLXZ1ZS9lcy9sb2NhbGUvZW5fVVMnLFxuICAgICAgXSxcbiAgICB9LFxuICAgIHNlcnZlcjoge1xuICAgICAgcHJveHk6IHtcbiAgICAgICAgJy9iYXNpYy1hcGknOiB7XG4gICAgICAgICAgLy8gdGFyZ2V0OiAnaHR0cDovL2xvY2FsaG9zdDozMDAwJyxcbiAgICAgICAgICB0YXJnZXQ6ICdodHRwOi8vMTA2LjMuOTcuMTk4OjIwMDYyLycsXG4gICAgICAgICAgLy8gdGFyZ2V0OiBgaHR0cDovLzE5Mi4xNjguMC45OjgwODIvYCxcbiAgICAgICAgICBjaGFuZ2VPcmlnaW46IHRydWUsXG4gICAgICAgICAgd3M6IHRydWUsXG4gICAgICAgICAgcmV3cml0ZTogKHBhdGgpID0+IHBhdGgucmVwbGFjZShuZXcgUmVnRXhwKGBeL2Jhc2ljLWFwaWApLCAnJyksXG4gICAgICAgICAgLy8gb25seSBodHRwc1xuICAgICAgICAgIC8vIHNlY3VyZTogZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgJy91cGxvYWQnOiB7XG4gICAgICAgICAgdGFyZ2V0OiAnaHR0cDovL2xvY2FsaG9zdDozMzAwL3VwbG9hZCcsXG4gICAgICAgICAgY2hhbmdlT3JpZ2luOiB0cnVlLFxuICAgICAgICAgIHdzOiB0cnVlLFxuICAgICAgICAgIHJld3JpdGU6IChwYXRoKSA9PiBwYXRoLnJlcGxhY2UobmV3IFJlZ0V4cChgXi91cGxvYWRgKSwgJycpLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG9wZW46IHRydWUsIC8vIFx1OTg3OVx1NzZFRVx1NTQyRlx1NTJBOFx1NTQwRVx1RkYwQ1x1ODFFQVx1NTJBOFx1NjI1M1x1NUYwMFxuICAgICAgd2FybXVwOiB7XG4gICAgICAgIGNsaWVudEZpbGVzOiBbJy4vaW5kZXguaHRtbCcsICcuL3NyYy97dmlld3MsY29tcG9uZW50c30vKiddLFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQXFULFNBQVMsK0JBQStCO0FBRTdWLElBQU8sc0JBQVEsd0JBQXdCO0FBQUEsRUFDckMsV0FBVztBQUFBLElBQ1QsY0FBYztBQUFBLE1BQ1osU0FBUztBQUFBLFFBQ1A7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxJQUNBLFFBQVE7QUFBQSxNQUNOLE9BQU87QUFBQSxRQUNMLGNBQWM7QUFBQTtBQUFBLFVBRVosUUFBUTtBQUFBO0FBQUEsVUFFUixjQUFjO0FBQUEsVUFDZCxJQUFJO0FBQUEsVUFDSixTQUFTLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxPQUFPLGFBQWEsR0FBRyxFQUFFO0FBQUE7QUFBQTtBQUFBLFFBRy9EO0FBQUEsUUFDQSxXQUFXO0FBQUEsVUFDVCxRQUFRO0FBQUEsVUFDUixjQUFjO0FBQUEsVUFDZCxJQUFJO0FBQUEsVUFDSixTQUFTLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxPQUFPLFVBQVUsR0FBRyxFQUFFO0FBQUEsUUFDNUQ7QUFBQSxNQUNGO0FBQUEsTUFDQSxNQUFNO0FBQUE7QUFBQSxNQUNOLFFBQVE7QUFBQSxRQUNOLGFBQWEsQ0FBQyxnQkFBZ0IsNEJBQTRCO0FBQUEsTUFDNUQ7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment