监控管理

main
徐景良 1 month ago
parent 8f77ef476a
commit 065ef2eb68

@ -0,0 +1,60 @@
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:showCancelBtn="false"
:showOkBtn="false"
width="60%"
title="查看账号"
>
<BasicTable @register="registerTable" :searchInfo="searchInfo" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { loadByRole } from '@/api/demo/system';
import { BasicTable, useTable } from '@/components/Table';
defineOptions({ name: 'DeptModal' });
const emit = defineEmits(['success', 'register']);
const rowId = ref('');
const searchInfo = reactive<Recordable>({});
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false });
rowId.value = data.record.id;
searchInfo.roleId = rowId.value;
reload();
});
//
const [registerTable, { reload }] = useTable({
canResize: true,
resizeHeightOffset: 150,
api: loadByRole,
columns: [
{
title: '用户名',
dataIndex: 'account',
},
{
title: '昵称',
dataIndex: 'name',
},
],
rowKey: 'id',
showTableSetting: false,
handleSearchInfoFn(info) {
return info;
},
});
onMounted(() => {});
</script>
<style scoped>
.select-account {
display: flex;
height: 100%;
}
</style>

@ -0,0 +1,173 @@
<template>
<div>
<BasicModal v-bind="$attrs" @register="registerModal" title="分配菜单" @ok="handleSubmit">
<template #insertFooter>
<a-button type="primary" @click="upBtn" :disabled="loading" v-if="step == 2"
>上一步</a-button
>
</template>
<BasicTree
ref="asyncExpandTreeRef"
title="菜单树"
toolbar
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="false"
:treeData="treeData"
:fieldNames="{ key: 'id', title: 'name' }"
:defaultExpandAll="true"
:checkable="true"
:checkStrictly="true"
@check="handleSelect"
v-if="step == 1"
/>
<BasicTree
ref="asyncBtnExpandTreeRef"
title="按钮树"
toolbar
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="false"
:treeData="btnData"
:fieldNames="{ key: 'id', title: 'name', children: 'elements' }"
:defaultExpandAll="true"
:checkable="true"
:checkStrictly="true"
@check="handleBntSelect"
v-else
/>
</BasicModal>
</div>
</template>
<script lang="ts" setup>
import { ref, unref, onMounted, nextTick } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicTree, TreeItem, TreeActionType } from '@/components/Tree';
import { getMenuList } from '@/api/sys/menu';
import { assignModule, loadForRole } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
defineOptions({ name: 'ModulesModal' });
const emit = defineEmits(['success', 'register', 'select']);
const treeData = ref<TreeItem[]>([]);
const btnData = ref<any[]>([]);
const step = ref(1);
interface dataType {
moduleIds?: any;
elementIds?: any;
}
const checkData: dataType = {};
const asyncExpandTreeRef = ref<Nullable<TreeActionType>>(null);
const asyncBtnExpandTreeRef = ref<Nullable<TreeActionType>>(null);
const { createMessage } = useMessage();
function upBtn() {
step.value = 1;
getMenusForRol(rowId.value);
}
function treeIterator(tree) {
tree.forEach((node) => {
node.name = node.item.name;
node.id = node.item.id;
node.elements = node.item.elements;
node.children && treeIterator(node.children);
});
}
function btnIterator(moduleId, tree) {
tree.forEach((node) => {
if (moduleId == node.item.id) {
btnData.value.push({
name: node.item.name,
id: node.item.id,
elements: node.item.elements,
disabled: true,
});
}
node.children && btnIterator(moduleId, node.children);
});
}
async function fetch() {
step.value = 1;
const data = (await getMenuList()) as unknown as TreeItem[];
treeIterator(data);
treeData.value = await data;
//
nextTick(() => {
unref(asyncExpandTreeRef)?.expandAll(true);
unref(asyncBtnExpandTreeRef)?.expandAll(true);
});
}
let moduleIds = ref([]);
let elementIds = ref([]);
async function getMenusForRol(id) {
var menusForRol = await loadForRole({
roleId: id,
});
// var forRole = await loadForRole()
btnData.value = [];
menusForRol.moduleIds.forEach((element) => {
btnIterator(element, treeData.value);
});
unref(asyncExpandTreeRef)?.setCheckedKeys(menusForRol.moduleIds);
checkData.moduleIds = menusForRol.moduleIds;
checkData.elementIds = menusForRol.elementIds;
unref(asyncBtnExpandTreeRef)?.setCheckedKeys(checkData.elementIds);
moduleIds.value = menusForRol.moduleIds;
elementIds.value = menusForRol.elementIds;
}
function handleSelect(checkedKeys, e: { checked: boolean; checkedNodes; node; event }) {
const list = e.checkedNodes;
moduleIds.value = [];
list.forEach((element: any) => {
element.disabled = true;
element.name = element.item.name;
element.children = [];
moduleIds.value.push(element.item.id);
});
btnData.value = list;
}
function handleBntSelect(checkedKeys, e: { checked: boolean; checkedNodes; node; event }) {
const list = e.checkedNodes;
elementIds.value = [];
list.forEach((element: any) => {
elementIds.value.push(element.id);
});
}
onMounted(() => {
fetch();
});
const rowId = ref('');
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
rowId.value = data.record.id;
step.value = 1;
getMenusForRol(rowId.value);
setModalProps({ confirmLoading: false });
});
async function handleSubmit() {
try {
if (step.value == 1) {
step.value = 2;
setTimeout(() => {
unref(asyncBtnExpandTreeRef)?.setCheckedKeys(checkData.elementIds);
}, 10);
} else {
var query = {
roleId: rowId.value,
moduleIds: moduleIds.value,
elementIds: elementIds.value,
};
const data = await assignModule(query);
if (data) {
setModalProps({ confirmLoading: true });
closeModal();
emit('success');
return createMessage.success('成功');
} else {
return createMessage.error('失败');
}
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

@ -0,0 +1,73 @@
<template>
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
showFooter
:title="getTitle"
width="500px"
@ok="handleSubmit"
>
<!-- <BasicForm @register="registerForm">
<template #menu="{ model, field }">
<BasicTree
v-model:value="model[field]"
:treeData="treeData"
:fieldNames="{ title: 'menuName', key: 'id' }"
checkable
toolbar
title="菜单分配"
/>
</template>
</BasicForm> -->
</BasicDrawer>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './role.data';
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
import { BasicTree, TreeItem } from '@/components/Tree';
// import { getMenuList } from '@/api/demo/system';
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const treeData = ref<TreeItem[]>([]);
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 90,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
});
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
// resetFields();
// setDrawerProps({ confirmLoading: false });
// // setFieldsValuetreeDataTreekey not exist
// // if (unref(treeData).length === 0) {
// // treeData.value = (await getMenuList()) as any as TreeItem[];
// // }
// isUpdate.value = !!data?.isUpdate;
// if (unref(isUpdate)) {
// setFieldsValue({
// ...data.record,
// });
// }
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
async function handleSubmit() {
try {
const values = await validate();
setDrawerProps({ confirmLoading: true });
// TODO custom api
closeDrawer();
emit('success');
} finally {
setDrawerProps({ confirmLoading: false });
}
}
</script>

@ -0,0 +1,75 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './role.data';
import { addRole, updateRole } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
defineOptions({ name: 'DeptModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
setFieldsValue({
...data.record,
});
}
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
async function handleSubmit() {
try {
const values = await validate();
let query = values;
//
if (!unref(isUpdate)) {
const data = await addRole(query);
if (data) {
setModalProps({ confirmLoading: true });
// TODO custom api
closeModal();
emit('success');
return createMessage.success('新增成功');
} else {
return createMessage.error('新增失败');
}
} else {
const data = await updateRole(query);
if (data) {
setModalProps({ confirmLoading: true });
// TODO custom api
closeModal();
emit('success');
return createMessage.success('编辑成功');
} else {
return createMessage.error('编辑失败');
}
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,6 @@
export { default as AccountModal } from './AccountModal.vue';
export { default as ModulesModal } from './ModulesModal.vue';
export { default as RoleDrawer } from './RoleDrawer.vue';
export { default as RoleModal } from './RoleModal.vue';

@ -0,0 +1,83 @@
import { BasicColumn, FormSchema } from '@/components/Table';
import { h } from 'vue';
import { Switch,Tag } from 'ant-design-vue';
import { setRoleStatus } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
type CheckedType = boolean | string | number;
export const columns: BasicColumn[] = [
{
title: '监控编号',
dataIndex: 'jkdgbidzlkjg',
width:80,
},
{
title: '可见光监控',
dataIndex: 'jkdmckjg',
width: 100,
}, {
title: '热成像监控',
dataIndex: 'jkdmcrcx',
width: 100,
},
{
title: '监控类型',
dataIndex: 'jklx',
width: 80,
customRender: ({ record }) => {
return "高空瞭望";
},
},{
title: '所属县区',
dataIndex: 'qx',
width:80,
},
{
title: '位置',
dataIndex: 'jd',
width: 80,
customRender: ({ record }) => {
return record.jd+" , "+record.wd;
},
},
];
export const searchFormSchema: FormSchema[] = [
{
field: 'key',
label: '关键字',
component: 'Input',
colProps: { span: 8 },
},
];
export const formSchema: FormSchema[] = [
{
field: 'id',
label: '角色名称',
required: true,
component: 'Input',
ifShow:false,
},
{
field: 'name',
label: '角色名称',
required: true,
component: 'Input',
},
{
field: 'status',
label: '状态',
component: 'RadioButtonGroup',
defaultValue: 0,
componentProps: {
options: [
{ label: '启用', value: 0},
{ label: '停用', value: 1 },
],
},
},
];

@ -0,0 +1,66 @@
// vite.config.ts
import { defineApplicationConfig } from "file:///E:/projects/%E8%B4%A2%E6%BA%90%E7%B3%BB%E7%BB%9F/CaiYuanYiTiHua/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",
"@/../lib/vform/designer.umd.js"
]
},
build: {
/* 其他build生产打包配置省略 */
//...
target: "esnext",
commonjsOptions: {
include: /node_modules|lib/
//这里记得把lib目录加进来否则生产打包会报错
}
},
server: {
proxy: {
"/basic-api": {
target: "http://localhost:3000",
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`), "")
}
},
warmup: {
clientFiles: ["./index.html", "./src/{views,components}/*"]
}
},
define: {
"process.env": {
BASE_URL: "/"
}
},
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true
}
}
},
plugins: []
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJFOlxcXFxwcm9qZWN0c1xcXFxcdThEMjJcdTZFOTBcdTdDRkJcdTdFREZcXFxcQ2FpWXVhbllpVGlIdWFcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkU6XFxcXHByb2plY3RzXFxcXFx1OEQyMlx1NkU5MFx1N0NGQlx1N0VERlxcXFxDYWlZdWFuWWlUaUh1YVxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRTovcHJvamVjdHMvJUU4JUI0JUEyJUU2JUJBJTkwJUU3JUIzJUJCJUU3JUJCJTlGL0NhaVl1YW5ZaVRpSHVhL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQXBwbGljYXRpb25Db25maWcgfSBmcm9tICdAdmJlbi92aXRlLWNvbmZpZyc7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUFwcGxpY2F0aW9uQ29uZmlnKHtcbiAgb3ZlcnJpZGVzOiB7XG4gICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICBpbmNsdWRlOiBbXG4gICAgICAgICdlY2hhcnRzL2NvcmUnLFxuICAgICAgICAnZWNoYXJ0cy9jaGFydHMnLFxuICAgICAgICAnZWNoYXJ0cy9jb21wb25lbnRzJyxcbiAgICAgICAgJ2VjaGFydHMvcmVuZGVyZXJzJyxcbiAgICAgICAgJ3FyY29kZScsXG4gICAgICAgICdAaWNvbmlmeS9pY29uaWZ5JyxcbiAgICAgICAgJ2FudC1kZXNpZ24tdnVlL2VzL2xvY2FsZS96aF9DTicsXG4gICAgICAgICdhbnQtZGVzaWduLXZ1ZS9lcy9sb2NhbGUvZW5fVVMnLFxuICAgICAgICAnQC8uLi9saWIvdmZvcm0vZGVzaWduZXIudW1kLmpzJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICBidWlsZDoge1xuICAgICAgLyogXHU1MTc2XHU0RUQ2YnVpbGRcdTc1MUZcdTRFQTdcdTYyNTNcdTUzMDVcdTkxNERcdTdGNkVcdTc3MDFcdTc1NjUgKi9cbiAgICAgIC8vLi4uXG4gICAgICB0YXJnZXQ6ICdlc25leHQnLFxuICAgICAgY29tbW9uanNPcHRpb25zOiB7XG4gICAgICAgIGluY2x1ZGU6IC9ub2RlX21vZHVsZXN8bGliLywgLy9cdThGRDlcdTkxQ0NcdThCQjBcdTVGOTdcdTYyOEFsaWJcdTc2RUVcdTVGNTVcdTUyQTBcdThGREJcdTY3NjVcdUZGMENcdTU0MjZcdTUyMTlcdTc1MUZcdTRFQTdcdTYyNTNcdTUzMDVcdTRGMUFcdTYyQTVcdTk1MTlcdUZGMDFcdUZGMDFcbiAgICAgIH0sXG4gICAgfSxcbiAgICBzZXJ2ZXI6IHtcbiAgICAgIHByb3h5OiB7XG4gICAgICAgICcvYmFzaWMtYXBpJzoge1xuICAgICAgICAgIHRhcmdldDogJ2h0dHA6Ly9sb2NhbGhvc3Q6MzAwMCcsXG4gICAgICAgICAgY2hhbmdlT3JpZ2luOiB0cnVlLFxuICAgICAgICAgIHdzOiB0cnVlLFxuICAgICAgICAgIHJld3JpdGU6IChwYXRoKSA9PiBwYXRoLnJlcGxhY2UobmV3IFJlZ0V4cChgXi9iYXNpYy1hcGlgKSwgJycpLFxuICAgICAgICAgIC8vIG9ubHkgaHR0cHNcbiAgICAgICAgICAvLyBzZWN1cmU6IGZhbHNlXG4gICAgICAgIH0sXG4gICAgICAgICcvdXBsb2FkJzoge1xuICAgICAgICAgIHRhcmdldDogJ2h0dHA6Ly9sb2NhbGhvc3Q6MzMwMC91cGxvYWQnLFxuICAgICAgICAgIGNoYW5nZU9yaWdpbjogdHJ1ZSxcbiAgICAgICAgICB3czogdHJ1ZSxcbiAgICAgICAgICByZXdyaXRlOiAocGF0aCkgPT4gcGF0aC5yZXBsYWNlKG5ldyBSZWdFeHAoYF4vdXBsb2FkYCksICcnKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB3YXJtdXA6IHtcbiAgICAgICAgY2xpZW50RmlsZXM6IFsnLi9pbmRleC5odG1sJywgJy4vc3JjL3t2aWV3cyxjb21wb25lbnRzfS8qJ10sXG4gICAgICB9LFxuICAgIH0sXG4gICAgZGVmaW5lOiB7XG4gICAgICAncHJvY2Vzcy5lbnYnOiB7XG4gICAgICAgIEJBU0VfVVJMOiAnLycsXG4gICAgICB9LFxuICAgIH0sXG4gICAgY3NzOiB7XG4gICAgICBwcmVwcm9jZXNzb3JPcHRpb25zOiB7XG4gICAgICAgIGxlc3M6IHtcbiAgICAgICAgICBqYXZhc2NyaXB0RW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBwbHVnaW5zOiBbXSxcbiAgfSxcbn0pO1xuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUF1VCxTQUFTLCtCQUErQjtBQUUvVixJQUFPLHNCQUFRLHdCQUF3QjtBQUFBLEVBQ3JDLFdBQVc7QUFBQSxJQUNULGNBQWM7QUFBQSxNQUNaLFNBQVM7QUFBQSxRQUNQO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLElBQ0EsT0FBTztBQUFBO0FBQUE7QUFBQSxNQUdMLFFBQVE7QUFBQSxNQUNSLGlCQUFpQjtBQUFBLFFBQ2YsU0FBUztBQUFBO0FBQUEsTUFDWDtBQUFBLElBQ0Y7QUFBQSxJQUNBLFFBQVE7QUFBQSxNQUNOLE9BQU87QUFBQSxRQUNMLGNBQWM7QUFBQSxVQUNaLFFBQVE7QUFBQSxVQUNSLGNBQWM7QUFBQSxVQUNkLElBQUk7QUFBQSxVQUNKLFNBQVMsQ0FBQyxTQUFTLEtBQUssUUFBUSxJQUFJLE9BQU8sYUFBYSxHQUFHLEVBQUU7QUFBQTtBQUFBO0FBQUEsUUFHL0Q7QUFBQSxRQUNBLFdBQVc7QUFBQSxVQUNULFFBQVE7QUFBQSxVQUNSLGNBQWM7QUFBQSxVQUNkLElBQUk7QUFBQSxVQUNKLFNBQVMsQ0FBQyxTQUFTLEtBQUssUUFBUSxJQUFJLE9BQU8sVUFBVSxHQUFHLEVBQUU7QUFBQSxRQUM1RDtBQUFBLE1BQ0Y7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNOLGFBQWEsQ0FBQyxnQkFBZ0IsNEJBQTRCO0FBQUEsTUFDNUQ7QUFBQSxJQUNGO0FBQUEsSUFDQSxRQUFRO0FBQUEsTUFDTixlQUFlO0FBQUEsUUFDYixVQUFVO0FBQUEsTUFDWjtBQUFBLElBQ0Y7QUFBQSxJQUNBLEtBQUs7QUFBQSxNQUNILHFCQUFxQjtBQUFBLFFBQ25CLE1BQU07QUFBQSxVQUNKLG1CQUFtQjtBQUFBLFFBQ3JCO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxJQUNBLFNBQVMsQ0FBQztBQUFBLEVBQ1o7QUFDRixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo=
Loading…
Cancel
Save