机构管理
This commit is contained in:
parent
ba6f263ff9
commit
a1ca3b9cac
|
@ -0,0 +1,39 @@
|
||||||
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
|
||||||
|
enum Api {
|
||||||
|
queryTreeSync = '/admin/institutionArea/queryTreeSync',
|
||||||
|
searchBy = '/admin/institutionArea/searchBy',
|
||||||
|
add = '/admin/institutionArea/add',
|
||||||
|
edit = '/admin/institutionArea/edit',
|
||||||
|
delete = '/admin/institutionArea/delete',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取机构树列表
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const queryTreeSync = (params?) => defHttp.get({ url: Api.queryTreeSync, params });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据关键字搜索机构
|
||||||
|
*/
|
||||||
|
export const searchByKeywords = (params) => defHttp.get({ url: Api.searchBy, params });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存或者更新机构
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export const saveOrUpdateInst = (params, isUpdate) => {
|
||||||
|
let url = isUpdate ? Api.edit : Api.add;
|
||||||
|
return defHttp.post({ url: url, params });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除机构
|
||||||
|
*/
|
||||||
|
export const deleteInst = (params,handleSuccess) => {
|
||||||
|
return defHttp.post({ url: Api.delete, params }, { joinParamsToUrl: true }).then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,73 @@
|
||||||
|
import { FormSchema } from '/@/components/Form';
|
||||||
|
|
||||||
|
// 部门基础表单
|
||||||
|
export function useBasicFormSchema() {
|
||||||
|
const basicFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'instName',
|
||||||
|
label: '名称',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入机构/区域名称',
|
||||||
|
},
|
||||||
|
rules: [{ required: true, message: '名称不能为空' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'parentId',
|
||||||
|
label: '上级',
|
||||||
|
component: 'TreeSelect',
|
||||||
|
componentProps: {
|
||||||
|
treeData: [],
|
||||||
|
placeholder: '无',
|
||||||
|
dropdownStyle: { maxHeight: '200px', overflow: 'auto' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'orgCode',
|
||||||
|
label: '编码',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入编码',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'orgCategory',
|
||||||
|
label: '类型',
|
||||||
|
component: 'RadioButtonGroup',
|
||||||
|
componentProps: { options: [] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'instOrder',
|
||||||
|
label: '排序',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'mobile',
|
||||||
|
label: '电话',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入电话',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'address',
|
||||||
|
label: '地址',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入地址',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return { basicFormSchema };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 机构类型选项
|
||||||
|
export const orgCategoryOptions = {
|
||||||
|
// 一级部门
|
||||||
|
root: [{ value: '1', label: '机构' }],
|
||||||
|
// 子级部门
|
||||||
|
child: [
|
||||||
|
{ value: '2', label: '区域' },
|
||||||
|
],
|
||||||
|
};
|
|
@ -0,0 +1,119 @@
|
||||||
|
<template>
|
||||||
|
<BasicDrawer
|
||||||
|
v-bind="$attrs"
|
||||||
|
@register="registerDrawer"
|
||||||
|
:title="getTitle"
|
||||||
|
:width="adaptiveWidth"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
:showFooter="showFooter"
|
||||||
|
destroyOnClose
|
||||||
|
>
|
||||||
|
<BasicForm @register="registerForm" />
|
||||||
|
</BasicDrawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { defineComponent, ref, computed, unref, useAttrs } from 'vue';
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||||
|
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||||
|
import { getTenantId } from "/@/utils/auth";
|
||||||
|
import { useBasicFormSchema, orgCategoryOptions } from "../InstitutionArea.data";
|
||||||
|
import { saveOrUpdateInst} from "../InstitutionArea.api";
|
||||||
|
|
||||||
|
// 声明Emits
|
||||||
|
const emit = defineEmits(['success', 'register']);
|
||||||
|
const props = defineProps({
|
||||||
|
rootTreeData: { type: Array, default: () => [] },
|
||||||
|
});
|
||||||
|
const attrs = useAttrs();
|
||||||
|
const isUpdate = ref(true);
|
||||||
|
const isChild = ref(true);
|
||||||
|
const rowId = ref('');
|
||||||
|
let isFormDepartUser = false;
|
||||||
|
//表单配置
|
||||||
|
const [registerForm, { setProps, resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
||||||
|
labelWidth: 90,
|
||||||
|
schemas: useBasicFormSchema().basicFormSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
});
|
||||||
|
const showFooter = ref(true);
|
||||||
|
//表单赋值
|
||||||
|
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||||
|
await resetFields();
|
||||||
|
showFooter.value = data?.showFooter ?? true;
|
||||||
|
setDrawerProps({ confirmLoading: false, showFooter: showFooter.value });
|
||||||
|
// 当前是否为添加子级
|
||||||
|
isChild.value = unref(data?.isChild);
|
||||||
|
let categoryOptions = isChild.value ? orgCategoryOptions.child : orgCategoryOptions.root;
|
||||||
|
console.log(props.rootTreeData);
|
||||||
|
// 隐藏不需要展示的字段
|
||||||
|
updateSchema([
|
||||||
|
{
|
||||||
|
field: 'parentId',
|
||||||
|
show: isChild.value,
|
||||||
|
componentProps: {
|
||||||
|
// 如果是添加子部门,就禁用该字段
|
||||||
|
disabled: isChild.value,
|
||||||
|
treeData: props.rootTreeData,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'orgCode',
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'orgCategory',
|
||||||
|
componentProps: { options: categoryOptions },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
let record = unref(data?.record);
|
||||||
|
if (typeof record !== 'object') {
|
||||||
|
record = {};
|
||||||
|
}
|
||||||
|
// 赋默认值
|
||||||
|
record = Object.assign(
|
||||||
|
{
|
||||||
|
departOrder: 0,
|
||||||
|
orgCategory: categoryOptions[0].value,
|
||||||
|
},
|
||||||
|
record
|
||||||
|
);
|
||||||
|
console.log(record);
|
||||||
|
await setFieldsValue({ ...record });
|
||||||
|
isUpdate.value = !!data?.isUpdate;
|
||||||
|
// 隐藏底部时禁用整个表单
|
||||||
|
setProps({ disabled: !showFooter.value });
|
||||||
|
});
|
||||||
|
//获取标题
|
||||||
|
const getTitle = computed(() => {
|
||||||
|
let title = '机构';
|
||||||
|
if(isChild.value){
|
||||||
|
title = '区域';
|
||||||
|
}
|
||||||
|
if (!unref(isUpdate)) {
|
||||||
|
return '新增'+title;
|
||||||
|
} else {
|
||||||
|
return unref(showFooter) ? '编辑'+title : title+'详情';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||||
|
|
||||||
|
//提交事件
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
let values = await validate();
|
||||||
|
setDrawerProps({ confirmLoading: true });
|
||||||
|
let params = values;
|
||||||
|
let isUpdateVal = unref(isUpdate);
|
||||||
|
await saveOrUpdateInst(params,isUpdateVal);
|
||||||
|
//关闭弹窗
|
||||||
|
closeDrawer();
|
||||||
|
//刷新列表
|
||||||
|
emit('success');
|
||||||
|
} finally {
|
||||||
|
setDrawerProps({ confirmLoading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,117 @@
|
||||||
|
<template>
|
||||||
|
<a-spin :spinning="loading">
|
||||||
|
<BasicForm @register="registerForm" />
|
||||||
|
<div class="j-box-bottom-button offset-20" style="margin-top: 30px">
|
||||||
|
<div class="j-box-bottom-button-float">
|
||||||
|
<a-button preIcon="ant-design:sync-outlined" @click="onReset">重置</a-button>
|
||||||
|
<a-button type="primary" preIcon="ant-design:save-filled" @click="onSubmit">保存</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
import { saveOrUpdateInst } from '../InstitutionArea.api';
|
||||||
|
import { useBasicFormSchema, orgCategoryOptions } from '../InstitutionArea.data';
|
||||||
|
const emit = defineEmits(['success']);
|
||||||
|
const props = defineProps({
|
||||||
|
data: { type: Object, default: () => ({}) },
|
||||||
|
rootTreeData: { type: Array, default: () => [] },
|
||||||
|
});
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
// 当前是否是更新模式
|
||||||
|
const isUpdate = ref<boolean>(true);
|
||||||
|
// 当前的弹窗数据
|
||||||
|
const model = ref<object>({});
|
||||||
|
|
||||||
|
//注册表单
|
||||||
|
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
||||||
|
schemas: useBasicFormSchema().basicFormSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const categoryOptions = computed(() => {
|
||||||
|
if (!!props?.data?.parentId) {
|
||||||
|
return orgCategoryOptions.child;
|
||||||
|
} else {
|
||||||
|
return orgCategoryOptions.root;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 禁用字段
|
||||||
|
updateSchema([
|
||||||
|
{ field: 'parentId', componentProps: { disabled: true } },
|
||||||
|
{ field: 'orgCode', componentProps: { disabled: true } },
|
||||||
|
]);
|
||||||
|
// data 变化,重填表单
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
async () => {
|
||||||
|
let record = unref(props.data);
|
||||||
|
if (typeof record !== 'object') {
|
||||||
|
record = {};
|
||||||
|
}
|
||||||
|
model.value = record;
|
||||||
|
await resetFields();
|
||||||
|
await setFieldsValue({ ...record });
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
);
|
||||||
|
// 更新 父部门 选项
|
||||||
|
watch(
|
||||||
|
() => props.rootTreeData,
|
||||||
|
async () => {
|
||||||
|
updateSchema([
|
||||||
|
{
|
||||||
|
field: 'parentId',
|
||||||
|
componentProps: { treeData: props.rootTreeData },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
);
|
||||||
|
// 监听并更改 orgCategory options
|
||||||
|
watch(
|
||||||
|
categoryOptions,
|
||||||
|
async () => {
|
||||||
|
updateSchema([
|
||||||
|
{
|
||||||
|
field: 'orgCategory',
|
||||||
|
componentProps: { options: categoryOptions.value },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
async function onReset() {
|
||||||
|
await resetFields();
|
||||||
|
await setFieldsValue({ ...model.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交事件
|
||||||
|
async function onSubmit() {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
let values = await validate();
|
||||||
|
values = Object.assign({}, model.value, values);
|
||||||
|
//提交表单
|
||||||
|
await saveOrUpdateInst(values, isUpdate.value);
|
||||||
|
//刷新列表
|
||||||
|
emit('success');
|
||||||
|
Object.assign(model.value, values);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,287 @@
|
||||||
|
<template>
|
||||||
|
<a-card :bordered="false" style="height: 100%">
|
||||||
|
<a-spin :spinning="syncoading">
|
||||||
|
<div class="j-table-operator" style="width: 100%">
|
||||||
|
<a-button preIcon="ant-design:sync-outlined" @click="loadRootTreeData">刷新</a-button>
|
||||||
|
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleAdd">新增</a-button>
|
||||||
|
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleAddChild()">新增下级</a-button>
|
||||||
|
</div>
|
||||||
|
<a-spin :spinning="loading">
|
||||||
|
<a-input-search placeholder="按名称搜索…" style="margin-bottom: 10px" @search="onSearch" />
|
||||||
|
<!--分组树-->
|
||||||
|
<template v-if="treeData.length > 0">
|
||||||
|
<a-tree
|
||||||
|
v-if="!treeReloading"
|
||||||
|
:clickRowToExpand="false"
|
||||||
|
:treeData="treeData"
|
||||||
|
:selectedKeys="selectedKeys"
|
||||||
|
:checkStrictly="checkStrictly"
|
||||||
|
:load-data="loadChildrenTreeData"
|
||||||
|
:checkedKeys="checkedKeys"
|
||||||
|
v-model:expandedKeys="expandedKeys"
|
||||||
|
@select="onSelect"
|
||||||
|
>
|
||||||
|
<template #title="{ key: treeKey, title, dataRef }">
|
||||||
|
<a-dropdown :trigger="['contextmenu']">
|
||||||
|
<span>{{ title }}</span>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu @click="">
|
||||||
|
<a-menu-item key="1" @click="handleAddChild(dataRef)">添加子级</a-menu-item>
|
||||||
|
<a-menu-item key="2" @click="handleDeleteNode(dataRef)">
|
||||||
|
<span style="color: red">删除</span>
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
|
</template>
|
||||||
|
<a-empty v-else description="暂无数据" />
|
||||||
|
</a-spin>
|
||||||
|
</a-spin>
|
||||||
|
</a-card>
|
||||||
|
<!-- 表单分组 -->
|
||||||
|
<InstitutionAreaDrawer :rootTreeData="treeData" @register="registerDrawer" @success="handleSuccess" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {createVNode, nextTick, ref} from 'vue';
|
||||||
|
import { useModal } from '/@/components/Modal';
|
||||||
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
import { useMethods } from '/@/hooks/system/useMethods';
|
||||||
|
import {useDrawer} from "@/components/Drawer";
|
||||||
|
import {Modal} from "ant-design-vue";
|
||||||
|
import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
|
||||||
|
import InstitutionAreaDrawer from './InstitutionAreaDrawer.vue';
|
||||||
|
import {queryTreeSync,searchByKeywords,deleteInst} from '../InstitutionArea.api';
|
||||||
|
const { createMessage } = useMessage();
|
||||||
|
const emit = defineEmits(['select', 'rootTreeData']);
|
||||||
|
const syncoading = ref<boolean>(false);
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
// 分组树列表数据
|
||||||
|
const treeData = ref<any[]>([]);
|
||||||
|
// 当前选中的项
|
||||||
|
const checkedKeys = ref<any[]>([]);
|
||||||
|
// 当前展开的项
|
||||||
|
const expandedKeys = ref<any[]>([]);
|
||||||
|
// 当前选中的项
|
||||||
|
const selectedKeys = ref<any[]>([]);
|
||||||
|
// 树组件重新加载
|
||||||
|
const treeReloading = ref<boolean>(false);
|
||||||
|
// 树父子是否关联
|
||||||
|
const checkStrictly = ref<boolean>(true);
|
||||||
|
// 当前选中的区域
|
||||||
|
const currentInst = ref<any>(null);
|
||||||
|
//注册drawer
|
||||||
|
const [registerDrawer, { openDrawer : openDrawer }] = useDrawer();
|
||||||
|
// 搜索关键字
|
||||||
|
const searchKeyword = ref('');
|
||||||
|
|
||||||
|
// 加载顶级分组信息
|
||||||
|
async function loadRootTreeData() {
|
||||||
|
searchKeyword.value = "";
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
treeData.value = [];
|
||||||
|
const result = await queryTreeSync();
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
treeData.value = result;
|
||||||
|
}
|
||||||
|
if (expandedKeys.value.length === 0) {
|
||||||
|
autoExpandParentNode();
|
||||||
|
} else {
|
||||||
|
if (selectedKeys.value.length === 0) {
|
||||||
|
let item = treeData.value[0];
|
||||||
|
if (item) {
|
||||||
|
// 默认选中第一个
|
||||||
|
setSelectedKey(item.id, item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit('select', currentInst.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit('rootTreeData', treeData.value);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
syncoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadRootTreeData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载子级分组信息
|
||||||
|
*/
|
||||||
|
async function loadChildrenTreeData(treeNode) {
|
||||||
|
try {
|
||||||
|
const result = await queryTreeSync({
|
||||||
|
pid: treeNode.dataRef.id,
|
||||||
|
});
|
||||||
|
if (result.length == 0) {
|
||||||
|
treeNode.dataRef.isLeaf = true;
|
||||||
|
} else {
|
||||||
|
treeNode.dataRef.children = result;
|
||||||
|
if (expandedKeys.value.length > 0) {
|
||||||
|
// 判断获取的子级是否有当前展开的项
|
||||||
|
let subKeys: any[] = [];
|
||||||
|
for (let key of expandedKeys.value) {
|
||||||
|
if (result.findIndex((item) => item.id === key) !== -1) {
|
||||||
|
subKeys.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (subKeys.length > 0) {
|
||||||
|
expandedKeys.value = [...expandedKeys.value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
treeData.value = [...treeData.value];
|
||||||
|
emit('rootTreeData', treeData.value);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动展开父节点,只展开一级
|
||||||
|
*/
|
||||||
|
function autoExpandParentNode() {
|
||||||
|
let item = treeData.value[0];
|
||||||
|
if (item) {
|
||||||
|
if (!item.isLeaf) {
|
||||||
|
expandedKeys.value = [item.key];
|
||||||
|
}
|
||||||
|
// 默认选中第一个
|
||||||
|
setSelectedKey(item.id, item);
|
||||||
|
reloadTree();
|
||||||
|
} else {
|
||||||
|
emit('select', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新加载树组件,防止无法默认展开数据
|
||||||
|
*/
|
||||||
|
async function reloadTree() {
|
||||||
|
await nextTick();
|
||||||
|
treeReloading.value = true;
|
||||||
|
await nextTick();
|
||||||
|
treeReloading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置当前选中的行
|
||||||
|
*/
|
||||||
|
function setSelectedKey(key: string, data?: object) {
|
||||||
|
selectedKeys.value = [key];
|
||||||
|
if (data) {
|
||||||
|
currentInst.value = data;
|
||||||
|
emit('select', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 树选择事件
|
||||||
|
*/
|
||||||
|
function onSelect(selKeys, event) {
|
||||||
|
if (selKeys.length > 0 && selectedKeys.value[0] !== selKeys[0]) {
|
||||||
|
setSelectedKey(selKeys[0], event.selectedNodes[0]);
|
||||||
|
} else {
|
||||||
|
// 这样可以防止用户取消选择
|
||||||
|
setSelectedKey(selectedKeys.value[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增
|
||||||
|
*/
|
||||||
|
function handleAdd() {
|
||||||
|
openDrawer(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
isChild: false,
|
||||||
|
showFooter: true,
|
||||||
|
tenantSaas: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加子级
|
||||||
|
*/
|
||||||
|
function handleAddChild(data = currentInst.value){
|
||||||
|
if (data == null) {
|
||||||
|
createMessage.warning('请先选择一个节点');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(data);
|
||||||
|
const record = { parentId: data.id };
|
||||||
|
openDrawer(true, {
|
||||||
|
record,
|
||||||
|
isUpdate: false,
|
||||||
|
isChild: true,
|
||||||
|
showFooter: true,
|
||||||
|
tenantSaas: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*删除节点
|
||||||
|
*/
|
||||||
|
function handleDeleteNode(data = currentInst.value){
|
||||||
|
if (data == null) {
|
||||||
|
createMessage.warning('请先选择一个节点');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let title = "";
|
||||||
|
if(data.orgCategory == "1"){
|
||||||
|
title = "机构";
|
||||||
|
}else{
|
||||||
|
title = "区域";
|
||||||
|
}
|
||||||
|
Modal.confirm({
|
||||||
|
title: "删除"+title,
|
||||||
|
width: '500px',
|
||||||
|
icon: createVNode(ExclamationCircleOutlined),
|
||||||
|
content: createVNode('div', { style: 'color:red;' }, title+'删除后,该'+title+'下的所有关联将被移除,确定要删除该'+title+'吗?'),
|
||||||
|
okText: '确定',
|
||||||
|
onOk() {
|
||||||
|
deleteInst(data, handleSuccess);
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
},
|
||||||
|
class: 'test',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索事件
|
||||||
|
async function onSearch(value: string) {
|
||||||
|
if (value) {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
treeData.value = [];
|
||||||
|
let result = await searchByKeywords({ keyWord: value });
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
treeData.value = result;
|
||||||
|
}
|
||||||
|
autoExpandParentNode();
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadRootTreeData();
|
||||||
|
}
|
||||||
|
searchKeyword.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSuccess(){
|
||||||
|
loadRootTreeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
loadRootTreeData,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,63 @@
|
||||||
|
<template>
|
||||||
|
<a-row class="p-2" type="flex" :gutter="10">
|
||||||
|
<a-col :xl="12" :lg="24" :md="24" style="margin-bottom: 10px">
|
||||||
|
<InstitutionAreaLeftTree ref="leftTree" @select="onTreeSelect" @rootTreeData="onRootTreeData" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :xl="12" :lg="24" :md="24" style="margin-bottom: 10px">
|
||||||
|
<div style="height: 100%;" class="form-content">
|
||||||
|
<a-tabs v-show="nodeData != null" defaultActiveKey="base-info">
|
||||||
|
<a-tab-pane tab="基本信息" key="base-info" forceRender style="position: relative">
|
||||||
|
<div style="padding: 20px">
|
||||||
|
<InstitutionAreaForm :data="nodeData" :rootTreeData="rootTreeData" @success="onSuccess" />
|
||||||
|
</div>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
<div v-show="nodeData == null" style="padding-top: 40px">
|
||||||
|
<a-empty description="请选择区域" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" name="iot-nuIotRegionInfo" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
|
import InstitutionAreaLeftTree from './components/InstitutionAreaLeftTree.vue'
|
||||||
|
import InstitutionAreaForm from './components/InstitutionAreaForm.vue';
|
||||||
|
|
||||||
|
// 给子组件定义一个ref变量
|
||||||
|
const leftTree = ref();
|
||||||
|
// 当前选中的区域信息
|
||||||
|
const nodeData = ref({});
|
||||||
|
const rootTreeData = ref<any[]>([]);
|
||||||
|
// 左侧树选择后触发
|
||||||
|
function onTreeSelect(data) {
|
||||||
|
nodeData.value = data;
|
||||||
|
}
|
||||||
|
// 左侧树rootTreeData触发
|
||||||
|
function onRootTreeData(data) {
|
||||||
|
rootTreeData.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSuccess() {
|
||||||
|
leftTree.value.loadRootTreeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
.p-2{
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content{
|
||||||
|
background-color: #ffffff;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-nav ){
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -157,7 +157,7 @@
|
||||||
import { getValueType } from '/@/utils';
|
import { getValueType } from '/@/utils';
|
||||||
import { Form } from 'ant-design-vue';
|
import { Form } from 'ant-design-vue';
|
||||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
||||||
import { getVideoParams,setVideoParams } from "@/views/iot/tplink/camera/camera.api";
|
import { getVideoParams,setVideoParams } from "../camera.api";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
getTamperNotif,
|
getTamperNotif,
|
||||||
setTamperNotif,
|
setTamperNotif,
|
||||||
testAudio
|
testAudio
|
||||||
} from "@/views/iot/tplink/camera/camera.api";
|
} from "../camera.api";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
|
|
|
@ -216,7 +216,7 @@ import {
|
||||||
setImageCommon,
|
setImageCommon,
|
||||||
configRecovery,
|
configRecovery,
|
||||||
getPreviewUrl,
|
getPreviewUrl,
|
||||||
} from "@/views/iot/tplink/camera/camera.api";
|
} from "../camera.api";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
|
|
|
@ -19,13 +19,12 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {defineComponent, ref, computed, unref, useAttrs, createVNode, h} from 'vue';
|
import {defineComponent, ref, computed, unref, useAttrs, createVNode, h} from 'vue';
|
||||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
import { formSchema } from "@/views/iot/tplink/camera/camera.data";
|
|
||||||
import { update,rebootDevice } from '@/views/iot/tplink/camera/camera.api';
|
|
||||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||||
import { getTenantId } from "/@/utils/auth";
|
|
||||||
import {Modal} from "ant-design-vue";
|
import {Modal} from "ant-design-vue";
|
||||||
import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
|
import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
|
||||||
|
import { formSchema } from "../camera.data";
|
||||||
|
import { update,rebootDevice } from '../camera.api';
|
||||||
|
|
||||||
// 声明Emits
|
// 声明Emits
|
||||||
const emit = defineEmits(['success', 'register']);
|
const emit = defineEmits(['success', 'register']);
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
import {ref, reactive, createVNode, h, onMounted, watch, unref} from 'vue';
|
import {ref, reactive, createVNode, h, onMounted, watch, unref} from 'vue';
|
||||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||||
import { useListPage } from '/@/hooks/system/useListPage';
|
import { useListPage } from '/@/hooks/system/useListPage';
|
||||||
import { columns, searchFormSchema } from '@/views/iot/tplink/camera/camera.data';
|
import { columns, searchFormSchema } from '../camera.data';
|
||||||
import { list } from '@/views/iot/tplink/camera/camera.api';
|
import { list } from '../camera.api';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { useDrawer } from "@/components/Drawer";
|
import { useDrawer } from "@/components/Drawer";
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { useMethods } from '/@/hooks/system/useMethods';
|
import { useMethods } from '/@/hooks/system/useMethods';
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
import { queryProjectTreeSync, queryRegionTreeSync, syncProject, syncRegion } from '@/views/iot/tplink/camera/camera.api';
|
import { queryProjectTreeSync, queryRegionTreeSync, syncProject, syncRegion } from '../camera.api';
|
||||||
|
|
||||||
const emit = defineEmits(['select', 'rootTreeData']);
|
const emit = defineEmits(['select', 'rootTreeData']);
|
||||||
const syncoading = ref<boolean>(false);
|
const syncoading = ref<boolean>(false);
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
import {
|
import {
|
||||||
getAlarmInfo, setAlarmInfo,
|
getAlarmInfo, setAlarmInfo,
|
||||||
getAlarmPlan, setAlarmPlan,
|
getAlarmPlan, setAlarmPlan,
|
||||||
} from "@/views/iot/tplink/camera/camera.api";
|
} from "../camera.api";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { getValueType } from '/@/utils';
|
import { getValueType } from '/@/utils';
|
||||||
import { Form } from 'ant-design-vue';
|
import { Form } from 'ant-design-vue';
|
||||||
import { getMultitransUrl } from "@/views/iot/tplink/camera/camera.api";
|
import { getMultitransUrl } from "../camera.api";
|
||||||
|
|
||||||
const TumsPlayer = window['tums-player'].default;
|
const TumsPlayer = window['tums-player'].default;
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
getOsd,
|
getOsd,
|
||||||
setOsd,
|
setOsd,
|
||||||
getPreviewUrl
|
getPreviewUrl
|
||||||
} from "@/views/iot/tplink/camera/camera.api";
|
} from "../camera.api";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
|
|
|
@ -123,8 +123,8 @@
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import type { TabsProps } from 'ant-design-vue';
|
import type { TabsProps } from 'ant-design-vue';
|
||||||
import { useListPage } from "@/hooks/system/useListPage";
|
import { useListPage } from "@/hooks/system/useListPage";
|
||||||
import { getImageCommon,setImageCommon } from "@/views/iot/tplink/camera/camera.api";
|
import { getImageCommon,setImageCommon } from "../camera.api";
|
||||||
import { recordingColumns,searchRecording } from "@/views/iot/tplink/camera/camera.data";
|
import { recordingColumns,searchRecording } from "../camera.data";
|
||||||
import CameraCommonForm from './CameraCommonForm.vue';//画面公共信息
|
import CameraCommonForm from './CameraCommonForm.vue';//画面公共信息
|
||||||
import CameraOsdForm from './CameraOsdForm.vue';//OSD信息
|
import CameraOsdForm from './CameraOsdForm.vue';//OSD信息
|
||||||
import CameraBitrateForm from './CameraBitrateForm.vue';//码流参数
|
import CameraBitrateForm from './CameraBitrateForm.vue';//码流参数
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
import {
|
import {
|
||||||
getPlaybackUrlList,
|
getPlaybackUrlList,
|
||||||
deletePlaybackChn
|
deletePlaybackChn
|
||||||
} from "@/views/iot/tplink/camera/camera.api";
|
} from "../camera.api";
|
||||||
|
|
||||||
const TumsPlayer = window['tums-player'].default;
|
const TumsPlayer = window['tums-player'].default;
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
getPreviewUrl,
|
getPreviewUrl,
|
||||||
setImageCommon,
|
setImageCommon,
|
||||||
testAudio
|
testAudio
|
||||||
} from "@/views/iot/tplink/camera/camera.api";
|
} from "../camera.api";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
formDisabled: { type: Boolean, default: false },
|
formDisabled: { type: Boolean, default: false },
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
import {ref, reactive, createVNode, h, onMounted, watch, unref} from 'vue';
|
import {ref, reactive, createVNode, h, onMounted, watch, unref} from 'vue';
|
||||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||||
import { useListPage } from '/@/hooks/system/useListPage';
|
import { useListPage } from '/@/hooks/system/useListPage';
|
||||||
import { recordingColumns,searchRecording } from '@/views/iot/tplink/camera/camera.data';
|
|
||||||
import { searchVideo } from '@/views/iot/tplink/camera/camera.api';
|
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { useDrawer } from "@/components/Drawer";
|
import { useDrawer } from "@/components/Drawer";
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { recordingColumns,searchRecording } from '../camera.data';
|
||||||
|
import { searchVideo } from '../camera.api';
|
||||||
import CameraPlaybackModal from './CameraPlaybackModal.vue';//普通回放
|
import CameraPlaybackModal from './CameraPlaybackModal.vue';//普通回放
|
||||||
import CameraMultitransModal from './CameraMultitransModal.vue';//Multitrans模式回放
|
import CameraMultitransModal from './CameraMultitransModal.vue';//Multitrans模式回放
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
import {
|
import {
|
||||||
getAlarmInfo, setAlarmInfo,
|
getAlarmInfo, setAlarmInfo,
|
||||||
getAlarmPlan, setAlarmPlan,
|
getAlarmPlan, setAlarmPlan,
|
||||||
} from "@/views/iot/tplink/camera/camera.api";
|
} from "../camera.api";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
|
|
|
@ -65,7 +65,7 @@ import {
|
||||||
import { getValueType } from '/@/utils';
|
import { getValueType } from '/@/utils';
|
||||||
import { Form } from 'ant-design-vue';
|
import { Form } from 'ant-design-vue';
|
||||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
||||||
import {uploadToServer,stopUploadToServer,getUploadToServerProcess} from "@/views/iot/tplink/camera/camera.api";
|
import {uploadToServer,stopUploadToServer,getUploadToServerProcess} from "../camera.api";
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import CameraLeftTree from './components/CameraLeftTree.vue'
|
import CameraLeftTree from './components/CameraLeftTree.vue'
|
||||||
import CameraInfoList from "@/views/iot/tplink/camera/components/CameraInfoList.vue";
|
import CameraInfoList from './components/CameraInfoList.vue';
|
||||||
|
|
||||||
// 给子组件定义一个ref变量
|
// 给子组件定义一个ref变量
|
||||||
const leftTree = ref();
|
const leftTree = ref();
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
||||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
import { saveOrUpdateProject } from '@/views/iot/tplink/project/ProjectInfo.api';
|
import { saveOrUpdateProject } from '../ProjectInfo.api';
|
||||||
import { formSchema } from '@/views/iot/tplink/project/ProjectInfo.data';
|
import { formSchema } from '../ProjectInfo.data';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
queryArea,
|
queryArea,
|
||||||
queryRegionTreeSync,
|
queryRegionTreeSync,
|
||||||
saveOrUpdateRegion
|
saveOrUpdateRegion
|
||||||
} from '@/views/iot/tplink/region/RegionInfo.api';
|
} from '../RegionInfo.api';
|
||||||
import { formSchema } from '@/views/iot/tplink/region/RegionInfo.data';
|
import { formSchema } from '../RegionInfo.data';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import {propTypes} from "@/utils/propTypes";
|
import {propTypes} from "@/utils/propTypes";
|
||||||
|
|
|
@ -25,11 +25,10 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineComponent, ref, computed, unref, useAttrs } from 'vue';
|
import { defineComponent, ref, computed, unref, useAttrs } from 'vue';
|
||||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
import { formSchema } from "@/views/iot/tplink/region/RegionInfo.data";
|
|
||||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||||
import { getTenantId } from "/@/utils/auth";
|
import { formSchema } from "../RegionInfo.data";
|
||||||
import {queryArea, saveOrUpdateRegion} from "@/views/iot/tplink/region/RegionInfo.api";
|
import {queryArea, saveOrUpdateRegion} from "../RegionInfo.api";
|
||||||
|
|
||||||
// 声明Emits
|
// 声明Emits
|
||||||
const emit = defineEmits(['success', 'register']);
|
const emit = defineEmits(['success', 'register']);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<a-spin :spinning="loading">
|
<a-spin :spinning="loading">
|
||||||
<a-input-search placeholder="按名称搜索…" style="margin-bottom: 10px" @search="onSearch" />
|
<!-- <a-input-search placeholder="按名称搜索…" style="margin-bottom: 10px" @search="onSearch" />-->
|
||||||
<!--分组树-->
|
<!--分组树-->
|
||||||
<template v-if="treeData.length > 0">
|
<template v-if="treeData.length > 0">
|
||||||
<a-tree
|
<a-tree
|
||||||
|
@ -54,15 +54,15 @@ import {createVNode, nextTick, ref} from 'vue';
|
||||||
import { useModal } from '/@/components/Modal';
|
import { useModal } from '/@/components/Modal';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { useMethods } from '/@/hooks/system/useMethods';
|
import { useMethods } from '/@/hooks/system/useMethods';
|
||||||
|
import {
|
||||||
|
deleteRegion,
|
||||||
|
queryProjectTreeSync,
|
||||||
|
queryRegionTreeSync,
|
||||||
|
syncProject,
|
||||||
|
syncRegion,
|
||||||
|
syncRegionChildren
|
||||||
|
} from '../RegionInfo.api';
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
import {
|
|
||||||
deleteRegion,
|
|
||||||
queryProjectTreeSync,
|
|
||||||
queryRegionTreeSync,
|
|
||||||
syncProject,
|
|
||||||
syncRegion,
|
|
||||||
syncRegionChildren
|
|
||||||
} from '@/views/iot/tplink/region/RegionInfo.api';
|
|
||||||
import {useDrawer} from "@/components/Drawer";
|
import {useDrawer} from "@/components/Drawer";
|
||||||
import ProjectInfoDrawer from '@/views/iot/tplink/project/components/ProjectInfoDrawer.vue';
|
import ProjectInfoDrawer from '@/views/iot/tplink/project/components/ProjectInfoDrawer.vue';
|
||||||
import RegionInfoDrawer from './RegionInfoDrawer.vue';
|
import RegionInfoDrawer from './RegionInfoDrawer.vue';
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<div v-show="nodeData == null" style="padding-top: 40px">
|
<div v-show="nodeData == null" style="padding-top: 40px">
|
||||||
<a-empty description="请选择区域" />
|
<a-empty description="请选择分组" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -27,8 +27,8 @@
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import RegionLeftTree from './components/RegionLeftTree.vue'
|
import RegionLeftTree from './components/RegionLeftTree.vue'
|
||||||
import RegionForm from "@/views/iot/tplink/region/components/RegionForm.vue";
|
import RegionForm from './components/RegionForm.vue';
|
||||||
import ProjectForm from "@/views/iot/tplink/project/components/ProjectForm.vue";
|
import ProjectForm from '@/views/iot/tplink/project/components/ProjectForm.vue';
|
||||||
|
|
||||||
// 给子组件定义一个ref变量
|
// 给子组件定义一个ref变量
|
||||||
const leftTree = ref();
|
const leftTree = ref();
|
||||||
|
|
Loading…
Reference in New Issue