Compare commits

12 Commits

Author SHA1 Message Date
xuziqiang
9316629faa fix: 登录校验调整 2024-07-05 18:19:03 +08:00
xuziqiang
c7bbc1f003 fix: 角色新增同级 2024-07-05 17:36:24 +08:00
xuziqiang
da80693704 fix: bug修改 2024-07-05 17:29:34 +08:00
xuziqiang
40d93e74aa fix: bug修改 2024-07-05 17:26:31 +08:00
xuziqiang
b2a200486f fix: hx-op路由调整 2024-07-05 14:12:53 +08:00
xuziqiang
228f420bd4 fix: 项目图标调整 2024-07-05 13:51:28 +08:00
xuziqiang
78d49ff16e fix: 设备联调 2024-07-05 12:04:17 +08:00
xuziqiang
4bbb5c5133 fix: 组件调整 2024-07-04 11:19:38 +08:00
xuziqiang
d294c3f07a feat: 设备台账联调 2024-07-03 18:08:02 +08:00
xuziqiang
fba16c75b9 feat: 设备台账联调 2024-07-03 18:07:52 +08:00
xuziqiang
e5cd75c845 feat: 设备台账联调 2024-07-03 17:58:39 +08:00
xuziqiang
be09e531b9 fix:调整路由 2024-07-03 10:50:16 +08:00
30 changed files with 818 additions and 458 deletions

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/projectIcon.svg" />
<meta name="referrer" content="never" /> <meta name="referrer" content="never" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <script type="text/javascript"> <!-- <script type="text/javascript">

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36">
<g id="组_23402" data-name="组 23402" transform="translate(-959.12 -738.12)">
<rect id="矩形_16530" data-name="矩形 16530" width="36" height="36" transform="translate(959.12 738.12)" fill="none"/>
<g id="组_23400" data-name="组 23400" transform="translate(960.956 739.956)">
<path id="路径_30576" data-name="路径 30576" d="M207.674,163.872v-9.284a2.553,2.553,0,0,0-1.179-2.063l-8.056-4.634a2.417,2.417,0,0,0-2.358,0l-8.023,4.65a2.38,2.38,0,0,0-1.179,2.063v9.333A2.553,2.553,0,0,0,188.059,166l8.056,4.585a2.417,2.417,0,0,0,2.358,0l8.056-4.634A2.331,2.331,0,0,0,207.674,163.872Z" transform="translate(-181.117 -142.881)" fill="#4388fb" opacity="0.2"/>
<path id="路径_30577" data-name="路径 30577" d="M265.893,314.283h-2.718l-.884-2.653h-4.224l-.884,2.653h-2.718l4.224-11.625h2.9Zm-4.093-4.617-1.326-4.044a9.365,9.365,0,0,1-.2-1.015h-.065a5.831,5.831,0,0,1-.2,1.015l-1.326,4.044Zm8.072-7.073v11.625h-2.456V302.592Z" transform="translate(-246.539 -292.932)" fill="#4388fb"/>
<path id="路径_30578" data-name="路径 30578" d="M36.685,20.095a.9.9,0,0,0-.884.884v2.472a1.535,1.535,0,0,1-.77,1.294L23.7,31.262a1.422,1.422,0,0,1-1.523,0l-11.33-6.517a1.456,1.456,0,0,1-.77-1.294V20.177a2.409,2.409,0,0,0-1-4.6,2.425,2.425,0,0,0-2.423,2.407,2.391,2.391,0,0,0,1.637,2.276v3.176a3.268,3.268,0,0,0,1.637,2.816l11.33,6.582a3.244,3.244,0,0,0,1.637.409,3.471,3.471,0,0,0,1.637-.475l11.281-6.517a3.268,3.268,0,0,0,1.637-2.816V20.963A.76.76,0,0,0,36.685,20.095Zm.884-6.942V10.287a3.268,3.268,0,0,0-1.637-2.816L24.585.954a3.284,3.284,0,0,0-3.291,0L9.947,7.471A3.268,3.268,0,0,0,8.31,10.287v2.227a.884.884,0,1,0,1.768,0V10.287a1.535,1.535,0,0,1,.77-1.294l11.33-6.517a1.422,1.422,0,0,1,1.523,0L34.982,9.059a1.456,1.456,0,0,1,.77,1.294v2.734a2.4,2.4,0,1,0,1.817.065Z" transform="translate(-6.656 -0.512)" fill="#4388fb"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,11 @@
import { BASE_URL } from './index';
export enum device {
queryDeviceTree = `${BASE_URL}/deviceInfo/queryDeviceTree`, // 左侧树
queryDevicePage = `${BASE_URL}/deviceInfo/queryDevicePage`, // 列表
dropArea = `${BASE_URL}/deviceInfo/dropArea`, // 查询下拉区域
}
export enum group {
queryDeviceGroupTree = `${BASE_URL}/deviceGroup/queryDeviceGroupTree`, // 左侧树
creatOrUpdate = `${BASE_URL}/deviceGroup/creatOrUpdate`, // 左侧树节点新增编辑
}

View File

@@ -4,3 +4,6 @@
export const apiModule = { export const apiModule = {
parking: ['User', 'CurrentUser', 'Organizational'], parking: ['User', 'CurrentUser', 'Organizational'],
}; };
export const BASE_URL = '/carbon-smart';
export const dict = `${BASE_URL}/client/dict/listByKey`;

View File

@@ -1,4 +1,5 @@
const BASE_URL = '/carbon-smart'; import { BASE_URL } from './index';
export enum permission { export enum permission {
add = `${BASE_URL}/admin/permission/save`, add = `${BASE_URL}/admin/permission/save`,
queryOrgPermission = `${BASE_URL}/api/dept/queryOrgPermission`, queryOrgPermission = `${BASE_URL}/api/dept/queryOrgPermission`,

View File

@@ -0,0 +1,88 @@
<template>
<ns-modal
ref="modalRef"
v-bind="extraModalConfig"
destroyOnClose
v-model:visible="visible"
:title="title"
:okButtonProps="buttonProps"
@ok="handleOk">
<ns-form ref="formRef" :schemas="schemas" :model="formData" formLayout="formVertical" />
</ns-modal>
</template>
<script lang="ts" setup>
import { computed, ref, toRefs, watch } from 'vue';
import { HttpRequestConfig, NsMessage, useApi } from '/nerv-lib/saas';
import { useRoute } from 'vue-router';
type Props = {
title?: string;
schemas: Array<any>;
api: string | object | Function;
data?: object;
extraModalConfig?: object;
};
const route = useRoute();
const { httpRequest } = useApi();
const props = withDefaults(defineProps<Props>(), {
title: '新增',
});
const { schemas } = toRefs(props);
const formData = ref();
watch(
() => props?.data,
(val) => {
formData.value = val;
},
{
immediate: true,
deep: true,
},
);
const modalRef = ref();
const formRef = ref();
const visible = ref(false);
const validateResult = computed(() => {
return !formRef.value?.validateResult;
});
const toggle = () => {
visible.value = !visible.value;
};
const setLoading = (loading = true) => {
buttonProps.value.loading = loading;
};
const handleOk = () => {
setLoading(true);
formRef.value
.triggerSubmit()
.then((data: any) => {
const { api } = props;
const requestConfig: HttpRequestConfig = { method: 'POST' };
const { params } = route;
httpRequest({ api, params: data, pathParams: params, requestConfig })
.then(() => {
NsMessage.success('操作成功', 1, () => {
toggle();
});
})
.finally(() => {
setLoading(false);
});
})
.catch(() => {});
};
const buttonProps = ref({
disabled: validateResult,
loading: false,
});
defineExpose({
toggle,
});
</script>
<style lang="less"></style>

View File

@@ -19,7 +19,7 @@ export const appConfig = {
projectType: 'web', projectType: 'web',
baseApi: '/api', baseApi: '/api',
projectName: '济阳站_AI智能BAS系统', projectName: '济阳站_AI智能BAS系统',
enablePermissions: true, enablePermissions: false,
// themeColor: '#eee', // themeColor: '#eee',
siderPosition: 'left', siderPosition: 'left',
baseHeader: '/parkingManage', baseHeader: '/parkingManage',
@@ -92,6 +92,7 @@ export const appConfig = {
permissionVos: 'permissionVos', permissionVos: 'permissionVos',
}); });
sessionStorage.setItem('ORGID', info.orgId); sessionStorage.setItem('ORGID', info.orgId);
selectDefaultValue.value = info.orgId;
return { data: { ...trD } }; return { data: { ...trD } };
}); });
}, },

View File

@@ -7,8 +7,6 @@ import type { App, Directive, DirectiveBinding } from 'vue';
import { authorizationService } from '/nerv-lib/saas/store/modules/authorization-service'; import { authorizationService } from '/nerv-lib/saas/store/modules/authorization-service';
function isAuth(el: Element, binding: any) { function isAuth(el: Element, binding: any) {
console.log(el, binding);
const { checkPermission, checkAllPermission, checkPermissionRouter } = authorizationService(); const { checkPermission, checkAllPermission, checkPermissionRouter } = authorizationService();
const { value, modifiers } = binding; const { value, modifiers } = binding;

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="11.0960693359375" height="11.361328125" viewBox="0 0 11.0960693359375 11.361328125" fill="none">
<path d="M5.97288 0.0889032L10.8515 3.28616C11.0042 3.38656 11.0961 3.55643 11.0961 3.73899L11.0961 10.8194C11.096 11.1182 10.8536 11.3604 10.5548 11.3604L0.541595 11.3604C0.242524 11.3606 1.90735e-06 11.1182 0 10.8191L0 3.74666C0 3.56014 0.0961657 3.38656 0.254683 3.28776L5.38954 0.0820341C5.56864 -0.0296883 5.79635 -0.02711 5.97288 0.0886391L5.97288 0.0889032ZM7.84865 7.26703L6.76599 7.26703C6.31761 7.26703 5.95412 7.63051 5.95412 8.07889L5.95412 9.18401C5.95412 9.63239 6.31761 9.99588 6.76599 9.99588L7.84838 9.99588C8.29677 9.99588 8.66025 9.63239 8.66025 9.18401L8.66025 8.07916C8.66025 7.63078 8.29677 7.2673 7.84838 7.2673L7.84865 7.26703ZM7.84865 3.71945L6.76599 3.71945C6.31761 3.71945 5.95412 4.08293 5.95412 4.53131L5.95412 5.63643C5.95412 6.08481 6.31761 6.4483 6.76599 6.4483L7.84838 6.4483C8.29677 6.4483 8.66025 6.08481 8.66025 5.63643L8.66025 4.53131C8.66025 4.08293 8.29677 3.71945 7.84838 3.71945L7.84865 3.71945Z" fill="#4388FB" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -10,53 +10,26 @@ const organizationManage = {
name: 'UserManage', name: 'UserManage',
meta: { title: '用户管理', hideChildren: true, icon: 'zuzhiguanli' }, meta: { title: '用户管理', hideChildren: true, icon: 'zuzhiguanli' },
component: Base, component: Base,
redirect: { name: 'userManageIndex' }, redirect: { name: 'UserManageIndex' },
children: [ children: [
{ {
path: 'index', path: 'index',
name: 'userManageIndex', name: 'UserManageIndex',
component: () => import('/@/view/organizationManage/usermanage/index.vue'), component: () => import('/@/view/organizationManage/usermanage/index.vue'),
meta: { meta: {
title: '用户管理', title: '用户管理',
keepAlive: true, keepAlive: true,
operates: [ operates: [
{ title: '新增', code: 'userAdd' }, { title: '新增', code: 'userAdd' },
{ { title: '导入', code: 'userImport' },
title: '导入', { title: '模板下载', code: 'userTemDownload' },
code: 'userImport', { title: '导出', code: 'userExports' },
}, { title: '批量删除', code: 'userBatchDel' },
{ { title: '编辑', code: 'userEdit' },
title: '模板下载', { title: '冻结', code: 'userFrozen' },
code: 'userTemDownload', { title: '解冻', code: 'userUnFrozen' },
}, { title: '重置密码', code: 'userCodeReset' },
{ { title: '删除', code: 'userDelete' },
title: '导出',
code: 'userExports',
},
{
title: '批量删除',
code: 'userBatchDel',
},
{
title: '编辑',
code: 'userEdit',
},
{
title: '冻结',
code: 'userFrozen',
},
{
title: '解冻',
code: 'userUnFrozen',
},
{
title: '重置密码',
code: 'userCodeReset',
},
{
title: '删除',
code: 'userDelete',
},
], ],
// backApi: [], // backApi: [],
}, },

View File

@@ -2,6 +2,8 @@ import { dateUtil } from '/nerv-lib/util/date-util';
import data from './mock.json'; import data from './mock.json';
import { http } from '/nerv-lib/util'; import { http } from '/nerv-lib/util';
import { ref } from 'vue'; import { ref } from 'vue';
import { group } from '/@/api/deviceManage';
import { dict } from '/@/api';
const tableKeyMap = [ const tableKeyMap = [
{ {
title: '来源企业', title: '来源企业',
@@ -57,49 +59,105 @@ const doWnload = (url) => {
}; };
const mockData = ref(data.listData); const mockData = ref(data.listData);
export const treeConfig = { export const formSchema = [
{
field: 'isCreate',
component: 'NsInput',
show: false,
},
{
field: 'orgId',
component: 'NsInput',
show: false,
},
{
field: 'isCreatSon',
component: 'NsInput',
show: false,
},
{
label: '节点名称',
field: 'pointName',
component: 'NsInput',
componentProps: {
placeholder: '请输入节点名称(必填)',
},
rules: [
{
required: true,
message: '请输入节点名称',
},
],
},
{
label: '节点类型',
field: 'pointType',
component: 'NsSelectApi',
componentProps: {
placeholder: '请选择节点类型(必填)',
api: dict,
params: { dicKey: 'COUNT_POINT' },
immediate: true,
resultField: 'data.COUNT_POINT',
labelField: 'cnValue',
valueField: 'cnValue',
},
rules: [
{
required: true,
message: '请输入节点类型',
},
],
},
];
export const treeConfig = (orgId) => {
return {
defaultExpandAll: true, defaultExpandAll: true,
header: { header: {
icon: 'orgLink', icon: 'orgLink',
title: '能耗分组', title: '能耗分组',
}, },
params: { orgId },
api: () => { api: group.queryDeviceGroupTree,
return new Promise((resolve) => { // api: () => {
setTimeout(() => { // return new Promise((resolve) => {
resolve(data); // setTimeout(() => {
}, 100); // resolve({ data: [{ title: '全部', key: 'all', children: data.data }] });
}); // }, 100);
// });
// },
transform: (data) => {
return [{ title: '全部', key: 'all', selectable: false, children: data }];
}, },
formConfig: { formConfig: {
schemas: [ schemas: [
{ {
field: 'type', field: 'energyType',
label: '', label: '',
component: 'NsSelect', component: 'NsSelectApi',
autoSubmit: true, autoSubmit: true,
defaultValue: 1,
componentProps: { componentProps: {
options: [ api: dict,
{ label: '碳排', value: 1 }, params: { dicKey: 'ENERGY_TYPE' },
{ label: '用电量', value: 2 }, immediate: true,
{ label: '用水量', value: 3 }, resultField: 'data.ENERGY_TYPE',
{ label: '燃气量', value: 4 }, labelField: 'cnValue',
{ label: '供热量', value: 5 }, valueField: 'cnValue',
], placeholder: '请选择能耗种类',
}, },
}, },
{ {
field: 'name', field: 'pointName',
label: '', label: '',
component: 'NsInput', component: 'NsInput',
autoSubmit: true, autoSubmit: true,
componentProps: { componentProps: {
placeholder: '请输入', placeholder: '请输入节点名称',
}, },
}, },
], ],
}, },
};
}; };
export const tableConfig = (el, elGroup, elFormula) => { export const tableConfig = (el, elGroup, elFormula) => {
return { return {

View File

@@ -2,29 +2,113 @@
<editDrawer ref="editDrawerRef" /> <editDrawer ref="editDrawerRef" />
<editGroup ref="editGroupRef" /> <editGroup ref="editGroupRef" />
<editFormula ref="editFormulaRef" /> <editFormula ref="editFormulaRef" />
<!-- <ns-modal ref="modalRef" title="新增" v-model:visible="visible">
<ns-form ref="formRef" :schemas="formSchema" :model="formData" formLayout="formVertical" />
</ns-modal> -->
<NsModalFrom ref="modalFormRef" v-bind="nsModalFormConfig" />
<div class="groupContainer"> <div class="groupContainer">
<div class="tree"> <div class="tree">
<ns-tree-api v-bind="treeConfig" @select="handleSelect" /> <ns-tree-api v-bind="tConfig" @select="handleSelect">
<template #title="data">
<div class="treeRow">
<span>{{ data.title }}</span>
<a-dropdown>
<ns-icon name="actionMore" size="14" class="actionMore" />
<template #overlay>
<a-menu>
<a-menu-item
v-for="(item, index) in actionList"
:key="index"
@click="item.func(data)">
<span>{{ item.title }}</span>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</template>
</ns-tree-api>
</div> </div>
<ns-view-list-table v-show="defaultType" class="table" v-bind="config" /> <ns-view-list-table v-show="defaultType" class="table" v-bind="config" />
<ns-view-list-table v-show="!defaultType" class="table" v-bind="configCal" /> <ns-view-list-table v-show="!defaultType" class="table" v-bind="configCal" />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { createVNode, onMounted, ref } from 'vue'; import { createVNode, nextTick, onMounted, ref } from 'vue';
import { tableConfig, treeConfig, tableConfigCal } from './config'; import { tableConfig, treeConfig, tableConfigCal, formSchema } from './config';
import { useParams } from '/nerv-lib/use'; import { useParams } from '/nerv-lib/use';
import editDrawer from './edit.vue'; import editDrawer from './edit.vue';
import editGroup from './editGroup.vue'; import editGroup from './editGroup.vue';
import editFormula from './editFormula.vue'; import editFormula from './editFormula.vue';
import { NsMessage, NsModal } from '/nerv-lib/component';
import NsModalFrom from '/@/components/ns-modal-form.vue';
import { group } from '/@/api/deviceManage';
type opType = 'up' | 'down';
const { getParams } = useParams(); const { getParams } = useParams();
const modalFormRef = ref();
const editDrawerRef = ref(); const editDrawerRef = ref();
const editGroupRef = ref(); const editGroupRef = ref();
const editFormulaRef = ref(); const editFormulaRef = ref();
const defaultType = ref(true); const defaultType = ref(true);
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
const config = tableConfig(editDrawerRef, editGroupRef, editFormulaRef); const config = tableConfig(editDrawerRef, editGroupRef, editFormulaRef);
const configCal = tableConfigCal(editDrawerRef, editGroupRef, editFormulaRef); const configCal = tableConfigCal(editDrawerRef, editGroupRef, editFormulaRef);
const tConfig = treeConfig(result);
const nsModalFormConfig = ref({
api: group.creatOrUpdate,
data: {},
title: '新增',
schemas: formSchema,
extraModalConfig: {
bodyStyle: { paddingBottom: 0 },
},
});
nextTick(() => {
console.log(modalFormRef.value, 'modal');
});
const addNodeSon = (data) => {
console.log(data);
nsModalFormConfig.value.title = '新增';
nsModalFormConfig.value.data = {
pointName: '新增',
isCreate: true,
isCreatSon: false,
orgId: result,
};
modalFormRef.value?.toggle();
};
const editNode = (data) => {
console.log(data);
nsModalFormConfig.value.title = '编辑';
nsModalFormConfig.value.data = { pointName: 123 };
modalFormRef.value?.toggle();
data.value = { pointName: 'qwe' };
};
const moveNode = (data, type: opType) => {
console.log(data);
};
const deleteNode = (a) => {
NsModal.confirm({
content: '确定删除吗?',
onOk: () => {
console.log(a);
},
});
};
const filterAction = (data) => {};
const actionList = [
{ title: '新增子节点', key: 'addNodeSon', func: (data) => addNodeSon(data) },
{ title: '编辑', key: 'editNode', func: (data) => editNode(data) },
{ title: '上移', key: 'moveUp', func: (data) => moveNode(data, 'up') },
{ title: '下移', key: 'moveDown', func: (data) => moveNode(data, 'down') },
{ title: '删除', key: 'deleteNode', func: (data) => deleteNode(data) },
];
const handleSelect = () => { const handleSelect = () => {
defaultType.value = !defaultType.value; defaultType.value = !defaultType.value;
}; };
@@ -55,4 +139,21 @@
min-width: 0; min-width: 0;
} }
} }
.actionMore {
display: none;
}
:deep(.ant-tree-node-content-wrapper) {
&:hover {
.actionMore {
display: block;
}
}
}
.treeRow {
display: flex;
justify-content: space-between;
align-items: center;
}
</style> </style>

View File

@@ -1,142 +1,195 @@
import { dateUtil } from '/nerv-lib/util/date-util'; import { dateUtil } from '/nerv-lib/util/date-util';
import data from './mock.json'; import { device } from '/@/api/deviceManage';
export const tableConfig = { import { ref } from 'vue';
title: '设备台账', import { http } from '/nerv-lib/util';
// api: '/carbon_emission/device/getDeviceList',
value: data.dataSource, export const tableConfig = (orgId) => {
return ref({
title: '设备信息',
api: device.queryDevicePage,
params: { orgId },
treeConfig: { treeConfig: {
header: { header: {
icon: 'orgLink', icon: 'deviceType',
title: '设备类别', title: '设备类别',
}, },
params: { orgId },
dynamicParams: 'code',
defaultExpandAll: true, defaultExpandAll: true,
api: () => { api: device.queryDeviceTree,
return new Promise((resolve) => { fieldNames: { title: 'deviceType', key: 'code' },
setTimeout(() => {
resolve(data);
}, 100);
});
},
formConfig: { formConfig: {
schemas: [ schemas: [
{ {
field: 'name', field: 'deviceType',
label: '设备名称', label: '设备名称',
component: 'NsInput', component: 'NsInput',
autoSubmit: true, autoSubmit: true,
componentProps: { componentProps: {
placeholder: '请输入', placeholder: '请输入设备类型',
}, },
}, },
], ],
}, },
}, },
params: {
page: 0,
pageSize: 10,
},
rowSelection: null, rowSelection: null,
columns: [ columns: [
{ {
title: '设备名称', title: '设备名称',
dataIndex: 'id', dataIndex: 'deviceName',
}, },
{ {
title: '设备型号', title: '设备型号',
dataIndex: 'deviceCode', dataIndex: 'deviceModel',
}, },
{ {
title: 'SN码', title: 'SN码',
dataIndex: 'deviceName', dataIndex: 'snCode',
textNumber: 8, textNumber: 5,
textEllipsis: true, textEllipsis: true,
}, },
{ {
title: '设备一级区域', title: '设备一级区域',
dataIndex: 'position', dataIndex: 'device1Area',
textNumber: 5,
textEllipsis: true,
}, },
{ {
title: '设备二级区域', title: '设备二级区域',
dataIndex: 'position', dataIndex: 'device2Area',
textNumber: 5,
textEllipsis: true,
}, },
{ {
title: '设备详细位置', title: '设备详细位置',
dataIndex: 'position', dataIndex: 'deviceAddress',
textNumber: 5,
textEllipsis: true,
}, },
{ {
title: '设备规格', title: '设备规格',
dataIndex: 'position', dataIndex: 'deviceTp',
textNumber: 4,
}, },
{ {
title: '设备厂商纳税人识别号', title: '设备厂商纳税人识别号',
dataIndex: 'position', dataIndex: 'deviceRatepay',
textNumber: 8,
textEllipsis: true,
},
{
title: '设备厂商',
textNumber: 4,
dataIndex: 'manufacturer',
}, },
{ {
title: '厂商联系人', title: '厂商联系人',
dataIndex: 'position', dataIndex: 'contactPerson',
}, },
{ {
title: '设备描述', title: '设备描述',
dataIndex: 'position', dataIndex: 'deviceDesc',
textNumber: 5,
textEllipsis: true,
}, },
{ {
title: 'IP地址', title: 'IP地址',
dataIndex: 'position', dataIndex: 'ipAddress',
}, },
{ {
title: '生产日期', title: '生产日期',
dataIndex: 'position', dataIndex: 'manufactureDate',
}, },
{ {
title: '采购日期', title: '采购日期',
dataIndex: 'position', dataIndex: 'purchaseDate',
}, },
{ {
title: '启用日期', title: '启用日期',
dataIndex: 'position', dataIndex: 'startDate',
}, },
{ {
title: '设备成本(元)', title: '设备成本(元)',
dataIndex: 'position', dataIndex: 'equipmentCost',
textNumber: 6,
}, },
{ {
title: '使用期限', title: '使用期限',
dataIndex: 'position', dataIndex: 'usagePeriod',
textNumber: 4,
customRender: ({ value }) => `${value}`,
}, },
{ {
title: '额定功率', title: '额定功率',
dataIndex: 'position', dataIndex: 'ratedPower',
textNumber: 4,
// customRender: ({ value }) => `${value}年`,
}, },
{ {
title: '特殊参数', title: '特殊参数',
dataIndex: 'position', textNumber: 4,
dataIndex: 'specialParameters',
}, },
], ],
formConfig: { formConfig: {
schemas: [ schemas: [
{ {
field: 'name', field: 'deviceName',
label: '设备名称', label: '设备名称',
component: 'NsInput', component: 'NsInput',
componentProps: { componentProps: {
placeholder: '请输入', placeholder: '请输入设备名称',
}, },
}, },
{ {
field: 'provider', field: 'areas',
label: '设备区域',
component: 'NsCascader',
format: (record) => {
console.log(record);
return record?.reduce(
(pre, cur) => {
const len = cur?.length - 1;
pre[len].push(cur[len]);
return pre;
},
[[], []],
);
},
fieldMap: ['area1', 'area2'],
componentProps: {
placeholder: '请选择设备区域',
multiple: true,
loadData: (selectedOptions, options) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
if (!selectedOptions.length) {
http.post(device.dropArea, { orgId }).then((res) => {
options.value = res.data?.map((item) => {
return { label: item, value: item, children: [], isLeaf: false };
});
});
}
const value = targetOption?.value;
if (targetOption) {
targetOption.loading = true;
http.post(device.dropArea, { device1Area: value, orgId }).then((res) => {
targetOption.loading = false;
targetOption.children = res.data?.map((item) => {
return { label: item, value: item, children: [], isLeaf: true };
});
});
}
},
},
},
{
field: 'manufacturer',
label: '设备厂商', label: '设备厂商',
component: 'NsInput', component: 'NsInput',
componentProps: { componentProps: {
placeholder: '请输入', placeholder: '请输入设备厂商',
},
},
{
field: 'payWay',
label: '设备区域',
component: 'NsSelect',
componentProps: {
placeholder: '请选择',
options: [ options: [
{ {
label: '全部', label: '全部',
@@ -149,27 +202,30 @@ export const tableConfig = {
field: 'createTime', field: 'createTime',
label: '生产日期', label: '生产日期',
component: 'NsRangePicker', component: 'NsRangePicker',
fieldMap: ['queryStartDate', 'queryEndDate'], fieldMap: ['manufactureBeginDate', 'manufactureEndDate'],
componentProps: { componentProps: {
valueFormat: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD',
placeholder: ['设备生产开始日期', '设备生产结束日期'],
}, },
}, },
{ {
field: 'createTime1', field: 'createTime1',
label: '采购日期', label: '采购日期',
component: 'NsRangePicker', component: 'NsRangePicker',
fieldMap: ['queryStartDate', 'queryEndDate'], fieldMap: ['purchaseBeginDate', 'purchaseEndDate'],
componentProps: { componentProps: {
valueFormat: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD',
placeholder: ['设备采购开始日期', '设备采购结束日期'],
}, },
}, },
{ {
field: 'createTime2', field: 'createTime2',
label: '启用日期', label: '启用日期',
component: 'NsRangePicker', component: 'NsRangePicker',
fieldMap: ['queryStartDate', 'queryEndDate'], fieldMap: ['startBeginDate', 'startEndDate'],
componentProps: { componentProps: {
valueFormat: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD',
placeholder: ['设备启用开始日期', '设备启用结束日期'],
}, },
}, },
], ],
@@ -177,4 +233,5 @@ export const tableConfig = {
}, },
// pagination: { pageSizeOptions: false }, // pagination: { pageSizeOptions: false },
rowKey: 'uuid', rowKey: 'uuid',
});
}; };

View File

@@ -1,8 +1,14 @@
<template> <template>
<ns-view-list-table v-bind="tableConfig" /> <ns-view-list-table v-bind="config" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { tableConfig } from './config'; import { tableConfig } from './config';
import { computed, nextTick, ref } from 'vue';
const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result;
const config = tableConfig(orgId.value);
defineOptions({ defineOptions({
name: 'LedgerIndex', // 与页面路由name一致缓存才可生效 name: 'LedgerIndex', // 与页面路由name一致缓存才可生效
}); });

View File

@@ -131,6 +131,7 @@ export const formConfig2 = (disabled2: Boolean) => {
label: '是否部门领导', label: '是否部门领导',
field: 'isLeader', field: 'isLeader',
component: 'NsRadioGroup', component: 'NsRadioGroup',
defaultValue: 1,
componentProps: { componentProps: {
disabled: disabled2, disabled: disabled2,
radioType: 'radio', radioType: 'radio',

View File

@@ -65,10 +65,10 @@
</a-tabs> </a-tabs>
<a-space v-if="activeKey === 1 || deptPermissionTreeData?.length"> <a-space v-if="activeKey === 1 || deptPermissionTreeData?.length">
<ns-button type="primary" @click="CancelApartment">取消 </ns-button> <ns-button type="primary" @click="CancelApartment">取消 </ns-button>
<ns-button v-show="disabled" type="primary" @click="pipe(deptEdit, true, false)"> <ns-button v-if="disabled" type="primary" @click="pipe(deptEdit, true, false)">
编辑 编辑
</ns-button> </ns-button>
<ns-button v-show="!disabled" type="primary" @click="deptSure">确定</ns-button> <ns-button v-else type="primary" @click="deptSure">确定</ns-button>
</a-space> </a-space>
</div> </div>
</a-col> </a-col>
@@ -79,11 +79,11 @@
<a-row> <a-row>
<a-col :span="8" class="tree"> <a-col :span="8" class="tree">
<a-space wrap style="margin-bottom: 16px; justify-content: flex-start"> <a-space wrap style="margin-bottom: 16px; justify-content: flex-start">
<ns-button v-auth="'userAdd'" type="primary" @click="rolePipe(addUser, true)"> <!-- <ns-button v-auth="'userAdd'" type="primary" @click="rolePipe(addUser, true)">
新增角色 新增角色
</ns-button> </ns-button>
<ns-button type="primary" @click="rolePipe(addUserSon)">新增子角色</ns-button> <ns-button type="primary" @click="rolePipe(addUserSon)">新增子角色</ns-button>
<ns-button type="primary" @click="rolePipe(deleteUser)"> 删除 </ns-button> <ns-button type="primary" @click="rolePipe(deleteUser)"> 删除 </ns-button> -->
</a-space> </a-space>
<a-tree <a-tree
v-if="roleTreeData.length" v-if="roleTreeData.length"
@@ -95,19 +95,19 @@
<template #title="data"> <template #title="data">
<div style="display: flex; justify-content: space-between; align-items: center"> <div style="display: flex; justify-content: space-between; align-items: center">
<span> {{ data.zhName }}</span> <span> {{ data.zhName }}</span>
<!-- <a-dropdown> <a-dropdown>
<ns-icon name="actionMore" size="14" class="actionMore" /> <ns-icon name="actionMore" size="14" class="actionMore" />
<template #overlay> <template #overlay>
<a-menu> <a-menu>
<a-menu-item <a-menu-item
v-for="(action, index) in dropRoleActions" v-for="(action, index) in filterAction(data, dropRoleActions, 'addUser')"
:key="index" :key="index"
@click="action.func(data)"> @click="action.func(data)">
<span>{{ action.title }}</span> <span>{{ action.title }}</span>
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</template> </template>
</a-dropdown> --> </a-dropdown>
</div> </div>
</template> </template>
</a-tree> </a-tree>
@@ -139,20 +139,16 @@
<a-empty style="margin-top: 120px" v-else /> <a-empty style="margin-top: 120px" v-else />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
<a-space> <a-space v-if="roleActiveKey === 1 || rolePermissionTreeData?.length">
<ns-button type="primary" @click="CancelUser">取消</ns-button> <ns-button type="primary" @click="CancelUser">取消</ns-button>
<ns-button <ns-button
v-show="roleDisabled" v-if="roleDisabled"
:disabled="!roleTreeData?.length" :disabled="!roleTreeData?.length"
type="primary" type="primary"
@click="rolePipe(roleEdit, false, false)"> @click="rolePipe(roleEdit, false, false)">
编辑 编辑
</ns-button> </ns-button>
<ns-button <ns-button v-else :disabled="!roleTreeData?.length" type="primary" @click="roleSure">
v-show="!roleDisabled"
:disabled="!roleTreeData?.length"
type="primary"
@click="roleSure">
确定 确定
</ns-button> </ns-button>
</a-space> </a-space>
@@ -167,7 +163,7 @@
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 { http } from '/nerv-lib/util/http'; import { http } from '/nerv-lib/util/http';
import { cloneDeep, get } from 'lodash-es'; import { cloneDeep, get, isEmpty } from 'lodash-es';
import { formConfig, formConfig2 } from './config'; import { formConfig, formConfig2 } from './config';
import { department } from '/@/api/origanizemanage'; import { department } from '/@/api/origanizemanage';
import { permission } from '/@/api/origanizemanage'; import { permission } from '/@/api/origanizemanage';
@@ -180,7 +176,7 @@
const formRef = ref(); const formRef = ref();
const formRoleRef = ref(); const formRoleRef = ref();
let formData = ref({}); let formData = ref({});
let roleFormData = ref({}); let roleFormData = ref({ isLeader: 1 });
const activeKey = ref(1); const activeKey = ref(1);
const roleActiveKey = ref(1); const roleActiveKey = ref(1);
const disabled = ref(true); const disabled = ref(true);
@@ -224,7 +220,7 @@
/**操作拦截 */ /**操作拦截 */
const pipe = (func: Function, flag = false, toggle = true) => { const pipe = (func: Function, flag = false, toggle = true) => {
if (toggle) activeKey.value = 1; // if (toggle) activeKey.value = 1;
if (flag) { if (flag) {
// 只有部门的操作 // 只有部门的操作
if (selectRef.value?.hasOwnProperty('orgInfo') || !selectRef.value?.deptInfo) { if (selectRef.value?.hasOwnProperty('orgInfo') || !selectRef.value?.deptInfo) {
@@ -243,13 +239,15 @@
const rolePipe = (func: Function, linkDept = false, toggle = true) => { const rolePipe = (func: Function, linkDept = false, toggle = true) => {
console.log(selectRoleRef.value); console.log(selectRoleRef.value);
if (toggle) roleActiveKey.value = 1; // if (toggle) roleActiveKey.value = 1;
// 需要先选择部门 // 需要先选择部门
if ((linkDept && !selectRef.value?.deptInfo) || selectRef.value?.hasOwnProperty('own')) { if ((linkDept && !selectRef.value?.deptInfo) || selectRef.value?.hasOwnProperty('own')) {
NsMessage.error('请先选择相关部门'); NsMessage.error('请先选择相关部门');
return; return;
} }
if (!linkDept && !selectRoleRef.value) { console.log(123);
if (!linkDept && isEmpty(selectRoleRef.value)) {
NsMessage.error('请先选择相关角色'); NsMessage.error('请先选择相关角色');
return; return;
} }
@@ -302,6 +300,7 @@
item['deptInfo'] = item.orgInfo; item['deptInfo'] = item.orgInfo;
item['deptInfo']['deptName'] = item?.orgInfo?.orgName; item['deptInfo']['deptName'] = item?.orgInfo?.orgName;
item['own'] = !index; item['own'] = !index;
item['selectable'] = false;
item['children'] = item.deptTrees; item['children'] = item.deptTrees;
return item; return item;
}); });
@@ -325,7 +324,7 @@
// 获取角色树 // 获取角色树
const getUserTree = (params = { deptId: selectRef.value?.deptInfo?.deptId }) => { const getUserTree = (params = { deptId: selectRef.value?.deptInfo?.deptId }) => {
return http.post(department.queryRoleTree, params).then((res) => { return http.post(department.queryRoleTree, params).then((res) => {
roleTreeData.value = res.data; roleTreeData.value = [{ zhName: '全部', selectable: false, orgInfo: {}, children: res.data }];
}); });
}; };
// 根据依赖刷新角色树 // 根据依赖刷新角色树
@@ -334,12 +333,12 @@
getUserTree().then(() => { getUserTree().then(() => {
if (!roleTreeData.value?.length) { if (!roleTreeData.value?.length) {
selectRoleRef.value = {}; selectRoleRef.value = {};
roleFormData.value = {}; roleFormData.value = { isLeader: 1 };
} }
const info = { const info = {
node: { key: '0-0', dataRef: { ...roleTreeData.value[0] } }, node: { key: '0-0-0', dataRef: { ...roleTreeData.value[0].children[0] } },
}; };
SelectUserTree(['0-0'], info); SelectUserTree([''], info);
}); });
} }
}); });
@@ -351,8 +350,10 @@
callback: null, callback: null,
}; };
// 添加部门
const addApartment = (data) => { const addApartment = (data) => {
const { deptInfo } = data; const { deptInfo } = data;
activeKey.value = 1;
disabled.value = false; disabled.value = false;
opMap.type = 'addDept'; opMap.type = 'addDept';
@@ -369,23 +370,17 @@
orgId: deptInfo?.orgId, orgId: deptInfo?.orgId,
sourceOrgId, sourceOrgId,
projectId, projectId,
pdeptId: deptInfo.pdeptId || '',
orgName, orgName,
}); });
}); });
}; };
}; };
const getParent = (data) => { // 添加子部门
if (data?.parent) {
getParent(data.parent);
} else {
data;
}
};
const addApartmentSon = (data) => { const addApartmentSon = (data) => {
const { deptInfo } = data; const { deptInfo } = data;
activeKey.value = 1;
disabled.value = false; disabled.value = false;
opMap.type = 'addson'; opMap.type = 'addson';
formData.value = {}; formData.value = {};
@@ -407,10 +402,11 @@
}; };
}; };
const addUser = () => { const addUser = (data) => {
roleDisabled.value = false; roleDisabled.value = false;
opMap.type = 'addUser'; opMap.type = 'addUser';
roleFormData.value = {}; roleFormData.value = { isLeader: 1 };
roleActiveKey.value = 1;
opMap.fuc = (params) => { opMap.fuc = (params) => {
delete params.roleId; delete params.roleId;
return formRoleRef.value.triggerSubmit().then(() => { return formRoleRef.value.triggerSubmit().then(() => {
@@ -418,6 +414,7 @@
...params, ...params,
orgId, orgId,
projectId, projectId,
proleId: data.proleId || '',
deptId: selectRef.value.deptInfo.deptId, deptId: selectRef.value.deptInfo.deptId,
deptName: selectRef.value.deptInfo.deptName, deptName: selectRef.value.deptInfo.deptName,
}); });
@@ -425,10 +422,11 @@
}; };
}; };
const addUserSon = () => { const addUserSon = (data) => {
roleDisabled.value = false; roleDisabled.value = false;
opMap.type = 'addUserSon'; opMap.type = 'addUserSon';
roleFormData.value = {}; roleActiveKey.value = 1;
roleFormData.value = { isLeader: 1 };
opMap.fuc = (params) => { opMap.fuc = (params) => {
delete params.roleId; delete params.roleId;
return formRoleRef.value.triggerSubmit().then(() => { return formRoleRef.value.triggerSubmit().then(() => {
@@ -436,7 +434,7 @@
...params, ...params,
orgId, orgId,
projectId, projectId,
proleId: selectRoleRef.value.roleId, proleId: data.roleId,
deptId: selectRef.value.deptInfo.deptId, deptId: selectRef.value.deptInfo.deptId,
deptName: selectRef.value.deptInfo.deptName, deptName: selectRef.value.deptInfo.deptName,
}); });
@@ -444,8 +442,6 @@
}; };
}; };
const deleteDept = (data) => { const deleteDept = (data) => {
console.log(data);
// 删除逻辑 // 删除逻辑
Modal.confirm({ Modal.confirm({
title: '是否确认删除', title: '是否确认删除',
@@ -458,6 +454,7 @@
// 删除选中的数据需要清空 // 删除选中的数据需要清空
deptTreeSelectedKeys.value = []; deptTreeSelectedKeys.value = [];
selectRef.value = ''; selectRef.value = '';
roleTreeData.value = [{ zhName: '全部', selectable: false, orgInfo: {}, children: [] }];
} }
}); });
}, },
@@ -467,16 +464,20 @@
}); });
}; };
const deleteUser = () => { const deleteUser = (data) => {
Modal.confirm({ Modal.confirm({
title: '是否确认删除', title: '是否确认删除',
onOk() { onOk() {
http.post(department.delRole, { roleId: selectRoleRef.value.roleId }).then(() => { http.post(department.delRole, { roleId: data.roleId }).then(() => {
getUserTree({ deptId: selectRef.value.deptInfo.deptId }); getUserTree({ deptId: selectRef.value.deptInfo.deptId });
clearRoleData(); clearRoleData();
// 清空select树 // 清空select树
if (data.selected) {
// 删除选中的数据需要清空
roleTreeSelectedKeys.value = []; roleTreeSelectedKeys.value = [];
selectRoleRef.value = ''; selectRoleRef.value = '';
}
NsMessage.success('操作成功'); NsMessage.success('操作成功');
}); });
}, },
@@ -554,6 +555,7 @@
}; };
// 保存角色权限 // 保存角色权限
const rolePermission = () => { const rolePermission = () => {
if (!roleTotalCheckedKeys.value?.length) return;
http http
.post(department.addRolePermission, { .post(department.addRolePermission, {
// deptId: selectRef.value?.deptInfo.deptId, // deptId: selectRef.value?.deptInfo.deptId,
@@ -645,6 +647,7 @@
rolePermissionTreeData.value = []; rolePermissionTreeData.value = [];
roleCheckedKeys.value = []; roleCheckedKeys.value = [];
roleTreeSelectedKeys.value = []; roleTreeSelectedKeys.value = [];
roleDisabled.value = true;
}; };
/** /**
@@ -739,10 +742,10 @@
// { title: '新增角色', func: addUser, key: 'addUser' }, // { title: '新增角色', func: addUser, key: 'addUser' },
]); ]);
const filterAction = (data, actions) => { const filterAction = (data, actions, keyV = 'addDept') => {
if (data.hasOwnProperty('orgInfo')) { if (data.hasOwnProperty('orgInfo')) {
// 企业节点 // 企业节点
return actions.filter(({ key }) => key === 'addDept'); return actions.filter(({ key }) => key === keyV);
} }
return actions; return actions;
}; };

View File

@@ -44,6 +44,7 @@ export const formConfig = (disabled) => {
label: '性别', label: '性别',
field: 'sex', field: 'sex',
component: 'NsRadioGroup', component: 'NsRadioGroup',
defaultValue: '男',
componentProps: { componentProps: {
radioType: 'radio', radioType: 'radio',
options: [ options: [

View File

@@ -4,30 +4,17 @@
<div class="main"> <div class="main">
<div class="left"> <div class="left">
<div class="top"> <div class="top">
<ns-tree-api v-bind="orgTreeConfig" @select="handleSelect"> <ns-tree-api v-bind="orgTreeConfig" @select="handleSelect" v-model:treeData="treeData">
<template #title="data"> <template #title="data">
{{ data.orgInfo?.orgName }} {{ data.orgInfo?.orgName }}
</template> </template>
</ns-tree-api> </ns-tree-api>
</div> </div>
<div class="top"> <div class="top">
<!-- <div class="ns-table-title">关联部门</div> <ns-tree-api
v-bind="deptTreeConfig"
<a-input-search @select="handleSelect2"
v-model:value="searchValue2" v-model:treeData="treeDataDept">
style="margin-bottom: 8px"
placeholder="请输入关联部门"
@search="onSearch2" />
<a-tree
v-if="treeData2?.length"
:tree-data="treeData2"
defaultExpandAll
@select="handleSelect2">
<template #title="data">
{{ data.deptInfo?.deptName }}
</template>
</a-tree> -->
<ns-tree-api v-bind="deptTreeConfig" @select="handleSelect2">
<template #title="data"> <template #title="data">
{{ data.deptInfo?.deptName }} {{ data.deptInfo?.deptName }}
</template> </template>
@@ -87,7 +74,7 @@
import { formConfig, formConfig2 } from './config'; import { formConfig, formConfig2 } from './config';
import { origanizemanage } from '/@/api/origanizemanage'; import { origanizemanage } from '/@/api/origanizemanage';
defineOptions({ name: 'OrderListIndex' }); defineOptions({ name: 'UserManageIndex' });
const mainRef = ref(); const mainRef = ref();
const data = reactive({}); const data = reactive({});
@@ -113,19 +100,21 @@
const casData = ref([]); const casData = ref([]);
const formSchema2 = formConfig2(casData); const formSchema2 = formConfig2(casData);
const treeData = ref([]); const treeData = ref([]);
const treeDataDept = ref([]);
const treeData2 = ref([]); const treeData2 = ref([]);
const userAuthList = ref([]); const userAuthList = ref([]);
const orgId = JSON.parse(sessionStorage.getItem('userInfo')).orgId; // const orgId = JSON.parse(sessionStorage.getItem('userInfo')).orgId;
const orgId = JSON.parse(sessionStorage.getItem('ORGID')!);
const orgTreeConfig = ref({ const orgTreeConfig = ref({
selectedKeys: ['0-0'], selectedKeys: ['0-0'],
defaultExpandAll: true, defaultExpandAll: true,
api: origanizemanage.queryOrgTree, api: origanizemanage.queryOrgTree,
defaultParams: { orgId }, params: { orgId },
transform: (data) => { transform: (data) => {
const otherOrg = data[0].listOrg; const otherOrg = data[0]?.listOrg;
let treeData = []; let treeData = [];
// 特殊处理 // 特殊处理
if (data[0].orgInfo) { if (data[0]?.orgInfo) {
treeData = data; treeData = data;
} }
otherOrg?.map((item) => { otherOrg?.map((item) => {
@@ -153,7 +142,7 @@
const deptTreeConfig = ref({ const deptTreeConfig = ref({
defaultExpandAll: true, defaultExpandAll: true,
api: origanizemanage.queryDeptTree, api: origanizemanage.queryDeptTree,
defaultParams: { orgId }, params: { orgId },
header: { header: {
title: '关联部门', title: '关联部门',
@@ -192,11 +181,11 @@
}); });
}); });
}; };
getOrgTree(); // getOrgTree();
// 部门树 // 部门树
fetch(origanizemanage.queryDeptTree).then((res) => { // fetch(origanizemanage.queryDeptTree).then((res) => {
treeData2.value = res.data; // treeData2.value = res.data;
}); // });
const onSearch = () => { const onSearch = () => {
console.log(searchValue.value); console.log(searchValue.value);
@@ -225,8 +214,10 @@
}; };
const handleSelect = (selectedKeys: any, info: any) => { const handleSelect = (selectedKeys: any, info: any) => {
console.log(info);
fetch(origanizemanage.queryDeptTree, { orgId: info.node?.orgInfo.orgId }).then((res) => { fetch(origanizemanage.queryDeptTree, { orgId: info.node?.orgInfo.orgId }).then((res) => {
treeData2.value = res.data; treeDataDept.value = res.data;
}); });
tableFetch({ orgId: info.node?.orgInfo.orgId }); tableFetch({ orgId: info.node?.orgInfo.orgId });
}; };
@@ -298,6 +289,7 @@
opMap.value.type = 'add'; opMap.value.type = 'add';
setTimeout(() => { setTimeout(() => {
formData.value = { formData.value = {
sex: '男',
orgName: JSON.parse(sessionStorage.getItem('userInfo')).orgName, orgName: JSON.parse(sessionStorage.getItem('userInfo')).orgName,
}; };
userAuthList.value.splice(0); userAuthList.value.splice(0);
@@ -350,30 +342,23 @@
customRender: (text: any) => { customRender: (text: any) => {
return text.index + 1; return text.index + 1;
}, },
sorter: { sorter: true,
compare: (a, b) => a.address - b.address,
},
}, },
{ {
title: '账号', title: '账号',
dataIndex: 'accountNo', dataIndex: 'accountNo',
sorter: { sorter: true,
compare: (a, b) => a.accountNo - b.accountNo,
},
}, },
{ {
title: '姓名', title: '姓名',
dataIndex: 'realName', dataIndex: 'realName',
sorter: { sorter: true,
compare: (a, b) => a.realName - b.realName,
},
}, },
{ {
title: '性别', title: '性别',
dataIndex: 'sex', dataIndex: 'sex',
sorter: { sorter: true,
compare: (a, b) => a.name - b.name, textNumber: 4,
},
}, },
{ {
title: '手机号', title: '手机号',
@@ -381,11 +366,15 @@
}, },
{ {
title: '邮箱', title: '邮箱',
textNumber: 5,
textEllipsis: true,
dataIndex: 'email', dataIndex: 'email',
}, },
{ {
title: '组织关系', title: '组织关系',
dataIndex: 'orgName', dataIndex: 'orgName',
// textNumber: 9,
// textEllipsis: true,
}, },
{ {
title: '部门/角色', title: '部门/角色',

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/projectIcon.svg" />
<meta name="referrer" content="never" /> <meta name="referrer" content="never" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <script type="text/javascript"> <!-- <script type="text/javascript">

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36">
<g id="组_23402" data-name="组 23402" transform="translate(-959.12 -738.12)">
<rect id="矩形_16530" data-name="矩形 16530" width="36" height="36" transform="translate(959.12 738.12)" fill="none"/>
<g id="组_23400" data-name="组 23400" transform="translate(960.956 739.956)">
<path id="路径_30576" data-name="路径 30576" d="M207.674,163.872v-9.284a2.553,2.553,0,0,0-1.179-2.063l-8.056-4.634a2.417,2.417,0,0,0-2.358,0l-8.023,4.65a2.38,2.38,0,0,0-1.179,2.063v9.333A2.553,2.553,0,0,0,188.059,166l8.056,4.585a2.417,2.417,0,0,0,2.358,0l8.056-4.634A2.331,2.331,0,0,0,207.674,163.872Z" transform="translate(-181.117 -142.881)" fill="#4388fb" opacity="0.2"/>
<path id="路径_30577" data-name="路径 30577" d="M265.893,314.283h-2.718l-.884-2.653h-4.224l-.884,2.653h-2.718l4.224-11.625h2.9Zm-4.093-4.617-1.326-4.044a9.365,9.365,0,0,1-.2-1.015h-.065a5.831,5.831,0,0,1-.2,1.015l-1.326,4.044Zm8.072-7.073v11.625h-2.456V302.592Z" transform="translate(-246.539 -292.932)" fill="#4388fb"/>
<path id="路径_30578" data-name="路径 30578" d="M36.685,20.095a.9.9,0,0,0-.884.884v2.472a1.535,1.535,0,0,1-.77,1.294L23.7,31.262a1.422,1.422,0,0,1-1.523,0l-11.33-6.517a1.456,1.456,0,0,1-.77-1.294V20.177a2.409,2.409,0,0,0-1-4.6,2.425,2.425,0,0,0-2.423,2.407,2.391,2.391,0,0,0,1.637,2.276v3.176a3.268,3.268,0,0,0,1.637,2.816l11.33,6.582a3.244,3.244,0,0,0,1.637.409,3.471,3.471,0,0,0,1.637-.475l11.281-6.517a3.268,3.268,0,0,0,1.637-2.816V20.963A.76.76,0,0,0,36.685,20.095Zm.884-6.942V10.287a3.268,3.268,0,0,0-1.637-2.816L24.585.954a3.284,3.284,0,0,0-3.291,0L9.947,7.471A3.268,3.268,0,0,0,8.31,10.287v2.227a.884.884,0,1,0,1.768,0V10.287a1.535,1.535,0,0,1,.77-1.294l11.33-6.517a1.422,1.422,0,0,1,1.523,0L34.982,9.059a1.456,1.456,0,0,1,.77,1.294v2.734a2.4,2.4,0,1,0,1.817.065Z" transform="translate(-6.656 -0.512)" fill="#4388fb"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -4,13 +4,6 @@ const home = {
name: 'home', name: 'home',
meta: { title: '首页', icon: 'dicizhishou', index: 0, hideChildren: true }, meta: { title: '首页', icon: 'dicizhishou', index: 0, hideChildren: true },
redirect: { name: 'homeIndex' }, redirect: { name: 'homeIndex' },
children: [
{
path: 'homeModule',
name: 'HomeModule',
meta: { title: '首页', hideChildren: true, icon: 'dicizhishou' },
component: Base,
redirect: { name: 'homeIndex' },
children: [ children: [
{ {
path: 'index', path: 'index',
@@ -23,7 +16,5 @@ const home = {
}, },
}, },
], ],
},
],
}; };
export default home; export default home;

View File

@@ -1,15 +1,8 @@
const Base = () => import('/nerv-lib/saas/view/system/layout/content.vue'); const Base = () => import('/nerv-lib/saas/view/system/layout/content.vue');
const organizationManage = { const organizationManage = {
path: '/organizationManage', path: '/organizationManage',
name: 'organizationManage',
meta: { title: '企业管理', icon: 'dicizhishou', index: 99, hideChildren: true },
redirect: { name: 'EnterpriseManage' },
children: [
{
path: 'enterpriseManage',
name: 'EnterpriseManage', name: 'EnterpriseManage',
meta: { title: '企业管理', hideChildren: true, icon: 'dicizhishou' }, meta: { title: '企业管理', icon: 'dicizhishou', index: 99, hideChildren: true },
component: Base,
redirect: { name: 'EnterpriseManageIndex' }, redirect: { name: 'EnterpriseManageIndex' },
children: [ children: [
{ {
@@ -23,7 +16,5 @@ const organizationManage = {
}, },
}, },
], ],
},
],
}; };
export default organizationManage; export default organizationManage;

View File

@@ -14,7 +14,8 @@
.ant-menu-inline .ant-menu-item, .ant-menu-inline .ant-menu-item,
.ant-menu-inline .ant-menu-submenu-title { .ant-menu-inline .ant-menu-submenu-title {
width: 100% !important; max-width: 100% !important;
transition: none !important;
} }
.ns-basic-table .ant-btn:hover { .ns-basic-table .ant-btn:hover {
@@ -46,17 +47,17 @@
} }
// header菜单字体样式 // header菜单字体样式
.ant-menu-dark.ant-menu-horizontal>.ant-menu-item, // .ant-menu-dark.ant-menu-horizontal>.ant-menu-item,
.ant-menu-dark.ant-menu-horizontal>.ant-menu-submenu { // .ant-menu-dark.ant-menu-horizontal>.ant-menu-submenu {
color: #fff; // color: #fff;
} // }
.ant-menu-dark .ant-menu-item, // .ant-menu-dark .ant-menu-item,
.ant-menu-dark .ant-menu-item-group-title, // .ant-menu-dark .ant-menu-item-group-title,
.ant-menu-dark .ant-menu-item>a, // .ant-menu-dark .ant-menu-item>a,
.ant-menu-dark .ant-menu-item>span>a { // .ant-menu-dark .ant-menu-item>span>a {
color: #fff; // color: #fff;
} // }
@font-face { @font-face {
/*给字体命名*/ /*给字体命名*/
@@ -111,13 +112,13 @@
.ant-menu-title-content { .ant-menu-title-content {
svg { svg {
color: #A1ABC2; // color: #A1ABC2;
} }
} }
.ant-menu-item-selected { .ant-menu-item-selected {
svg { svg {
color: #D0DBF5; // color: #D0DBF5;
} }
} }
@@ -181,3 +182,7 @@
background-color: #AEAEAE; background-color: #AEAEAE;
} }
} }
#app {
min-width: 1200px;
}

View File

@@ -120,14 +120,8 @@
provide('addChildForm', addChildForm); provide('addChildForm', addChildForm);
const getFormClass = computed(() => { const getFormClass = computed(() => {
if (props.formLayout === 'flexVertical') { if (props.formLayout) {
return formConfig.formLayout.flexVertical; return formConfig.formLayout[props.formLayout as keyof typeof formConfig.formLayout];
}
if (props.formLayout === 'flex') {
return formConfig.formLayout.flex;
}
if (props.formLayout === 'flexv2') {
return formConfig.formLayout.flexv2;
} }
return formConfig.formLayout.vertical; return formConfig.formLayout.vertical;
}); });

View File

@@ -1,9 +1,9 @@
<!-- @format --> <!-- @format -->
<template> <template>
<div class="ns-table-header" v-if="!isEmpty(getActions)"> <div class="ns-table-header">
<div class="ns-table-title ns-title-extra-box" v-if="tableTitle">{{ tableTitle }}</div> <div class="ns-table-title ns-title-extra-box" v-if="tableTitle">{{ tableTitle }}</div>
<div class="ns-table-header-action"> <div class="ns-table-header-action" v-if="!isEmpty(getActions)">
<slot name="header" :data="data"></slot> <slot name="header" :data="data"></slot>
<template v-for="item in getActions" :key="item.name"> <template v-for="item in getActions" :key="item.name">
<ns-button @click="item.finalHandle()" :disabled="item.dynamicDisabled" :type="item.type"> <ns-button @click="item.finalHandle()" :disabled="item.dynamicDisabled" :type="item.type">

View File

@@ -14,6 +14,7 @@ export const treeProps = {
type: [String, Object, Function] as PropType<string | Function | AxiosRequestConfig>, type: [String, Object, Function] as PropType<string | Function | AxiosRequestConfig>,
default: undefined, default: undefined,
}, },
treeData: PropTypes.array.def([]),
params: PropTypes.object.def(() => ({})), params: PropTypes.object.def(() => ({})),
dynamicParams: PropTypes.oneOfType([ dynamicParams: PropTypes.oneOfType([
PropTypes.string, PropTypes.string,

View File

@@ -1,4 +1,5 @@
<template> <template>
<a-spin :spinning="treeState.loading">
<div class="ns-tree-form"> <div class="ns-tree-form">
<div v-show="header" class="ns-tree-title"> <div v-show="header" class="ns-tree-title">
<ns-icon :name="header.icon" size="14" /> <ns-icon :name="header.icon" size="14" />
@@ -8,11 +9,11 @@
<ns-form ref="formElRef" v-bind="formConfig" :model="formModel" @finish="formFinish" /> <ns-form ref="formElRef" v-bind="formConfig" :model="formModel" @finish="formFinish" />
</div> </div>
</div> </div>
<a-spin :spinning="treeState.loading">
<div style="min-height: 300px"> <div style="min-height: 300px; overflow-y: scroll">
<ns-tree v-if="treeData?.length" v-bind="getBindValue" v-model:selectedKeys="selectedKeys"> <ns-tree v-if="treeData?.length" v-bind="getBindValue" v-model:selectedKeys="selectedKeys">
<template #[item]="data" v-for="(item, index) in Object.keys($slots)" :key="index"> <template #[item]="data" v-for="(item, index) in Object.keys($slots)" :key="index">
<slot :name="item" v-bind="data || {}"></slot> <slot :name="item" v-bind="{ ...data, formModel } || {}"></slot>
</template> </template>
</ns-tree> </ns-tree>
<!-- <a-empty v-if="!treeData?.length" /> --> <!-- <a-empty v-if="!treeData?.length" /> -->
@@ -20,7 +21,7 @@
</a-spin> </a-spin>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, nextTick, reactive, ref, unref, useAttrs } from 'vue'; import { computed, nextTick, reactive, ref, unref, useAttrs, watch } from 'vue';
import { TreeDataItem } from 'ant-design-vue/es/tree/Tree'; import { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
import { useApi } from '/nerv-lib/use/use-api'; import { useApi } from '/nerv-lib/use/use-api';
import { AxiosRequestConfig } from 'axios'; import { AxiosRequestConfig } from 'axios';
@@ -32,16 +33,28 @@
defineOptions({ defineOptions({
name: 'NsTreeApi', name: 'NsTreeApi',
}); });
const emit = defineEmits(['update:treeData']);
// const model = defineModel('treeData');
const formElRef = ref(); const formElRef = ref();
const props = defineProps(treeProps); const props = defineProps(treeProps);
const treeData = ref<TreeDataItem[]>([]);
const treeData = ref(props.treeData);
const selectedKeys = ref(props.selectedKeys || []); const selectedKeys = ref(props.selectedKeys || []);
const { httpRequest } = useApi(); const { httpRequest } = useApi();
const requestConfig: AxiosRequestConfig = { method: 'get' }; const requestConfig: AxiosRequestConfig = { method: 'get' };
const route = useRoute(); const route = useRoute();
const attrs = useAttrs(); const attrs = useAttrs();
const formModel = reactive({}); const formModel = reactive({});
watch(
() => props.treeData,
(val) => {
treeData.value = val;
},
{
deep: true,
},
);
const treeState = reactive({ const treeState = reactive({
loading: false, loading: false,
}); });
@@ -55,6 +68,7 @@
return props.isSticky ? 'sticky' : 'static'; return props.isSticky ? 'sticky' : 'static';
}); });
const formFinish = debounce((data: object) => { const formFinish = debounce((data: object) => {
selectedKeys.value = [];
getData(data); getData(data);
}, 200); }, 200);
const getBindValue = computed(() => ({ const getBindValue = computed(() => ({
@@ -66,7 +80,7 @@
treeState.loading = loading; treeState.loading = loading;
}; };
const httpPrams = computed(() => { const httpPrams = computed(() => {
return { ...route.params, ...route.query, ...props.defaultParams }; return { ...route.params, ...route.query, ...props.params };
}); });
const getData = (params = {}) => { const getData = (params = {}) => {
@@ -82,6 +96,8 @@
}) })
.then((res) => { .then((res) => {
treeData.value = transform(get(res, resultField)); treeData.value = transform(get(res, resultField));
emit('update:treeData', treeData.value);
// model.value = treeData.value;
}) })
.finally(() => { .finally(() => {
setLoading(false); setLoading(false);

View File

@@ -11,6 +11,17 @@ export const formConfig = {
gutter: [0, 0], gutter: [0, 0],
justify: 'space-around', justify: 'space-around',
}, },
formVertical: {
layout: 'horizontal',
class: 'ns-vertical-form',
wrapperCol: { span: 24 },
labelCol: { span: 0 },
span: 24,
sm: null, //≥576px <=768
lg: null, //>= 768
gutter: [0, 0],
justify: 'space-around',
},
flex: { flex: {
// layout: 'horizontal', // layout: 'horizontal',
class: 'ns-flex-form ns-flex-form-horizontal', class: 'ns-flex-form ns-flex-form-horizontal',

View File

@@ -431,11 +431,14 @@
flex: 1; flex: 1;
.projectTitle { .projectTitle {
font-size: 28px; font-size: 28px;
font-weight: 900; font-weight: 500;
letter-spacing: 2.33px; letter-spacing: 2.33px;
line-height: 40px; line-height: 40px;
color: @primary-color; color: @primary-color;
text-align: left; text-align: left;
overflow: hidden;
text-wrap: nowrap;
text-overflow: ellipsis;
} }
} }
:deep(.header-menu .ant-menu-title-content) { :deep(.header-menu .ant-menu-title-content) {

View File

@@ -19,33 +19,51 @@
<h1 class="lg_card_title">{{ configStore.projectName }}</h1> <h1 class="lg_card_title">{{ configStore.projectName }}</h1>
<p v-show="!errorShow" style="height: 8px"></p> <p v-show="!errorShow" style="height: 8px"></p>
<p v-show="errorShow" class="lg_card_error">{{ errorMsg }}</p> <p v-show="errorShow" class="lg_card_error">{{ errorMsg }}</p>
<a-form name="basic" :model="formState" @finish="submit">
<a-form-item name="userName" :rules="[{ required: true, message: '请输入用户名' }]">
<!-- <p class="lg_card_tip">用户名/手机号</p> --> <!-- <p class="lg_card_tip">用户名/手机号</p> -->
<a-input class="loginInfo" placeholder="用户名" v-model:value="userName"> <a-input class="loginInfo" placeholder="用户名" v-model:value="userName">
<template #prefix> <template #prefix>
<ns-icon class="loginIcon" name="userName" size="19" style="margin-right: 20px" /> <ns-icon class="loginIcon" name="userName" size="19" style="margin-right: 20px" />
</template> </template>
</a-input> </a-input>
</a-form-item>
<a-form-item name="password" :rules="[{ required: true, message: '请输入密码' }]">
<!-- <p class="lg_card_tip">密码</p> --> <!-- <p class="lg_card_tip">密码</p> -->
<a-input-password class="loginInfo" placeholder="密码" v-model:value="password"> <a-input-password class="loginInfo" placeholder="密码" v-model:value="password">
<template #prefix> <template #prefix>
<ns-icon class="loginIcon" name="passWord" size="19" style="margin-right: 20px" /> <ns-icon class="loginIcon" name="passWord" size="19" style="margin-right: 20px" />
</template> </template>
</a-input-password> </a-input-password>
<!-- 验证码 --> </a-form-item>
<a-form-item name="code" :rules="[{ validator }]">
<!-- 验证码 -->
<a-input v-model:value="code" placeholder="验证码" class="loginInfo"> <a-input v-model:value="code" placeholder="验证码" class="loginInfo">
<template #prefix> <template #prefix>
<ns-icon class="loginIcon" name="verifyIcon" size="19" style="margin-right: 20px" /> <ns-icon
class="loginIcon"
name="verifyIcon"
size="19"
style="margin-right: 20px" />
</template> </template>
<template #addonAfter> <template #addonAfter>
<ns-verify @get-code="onGetCode" /> <ns-verify @get-code="onGetCode" />
</template> </template>
</a-input> </a-input>
</a-form-item>
<!-- <a-form-item name="remember"> -->
<!-- 记住密码 --> <!-- 记住密码 -->
<a-checkbox v-model:checked="isRemember" class="loginInfo">记住密码</a-checkbox> <a-checkbox v-model:checked="isRemember" class="loginInfo">记住密码</a-checkbox>
<a-button @click="submit" :loading="loading" type="primary" class="loginInfo" <!-- </a-form-item> -->
>登录</a-button
> <a-form-item>
<a-button html-type="submit" :loading="loading" type="primary" class="loginInfo">
登录
</a-button>
</a-form-item>
</a-form>
</div> </div>
</a-layout-content> </a-layout-content>
<!-- <a-layout-footer>Copyright 2021 xu科技 All Rights Reserved</a-layout-footer> --> <!-- <a-layout-footer>Copyright 2021 xu科技 All Rights Reserved</a-layout-footer> -->
@@ -54,7 +72,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, onMounted, ref } from 'vue'; import { defineComponent, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { appConfigStore } from '/nerv-lib/saas/store/modules/app-config'; import { appConfigStore } from '/nerv-lib/saas/store/modules/app-config';
import { authorizationService } from '/nerv-base/store/modules/authorization-service'; import { authorizationService } from '/nerv-base/store/modules/authorization-service';
@@ -81,11 +99,12 @@
// title.value = appConfig.title ? appConfig.title : '账号登录'; // title.value = appConfig.title ? appConfig.title : '账号登录';
const loading = ref<boolean>(false); const loading = ref<boolean>(false);
const configStore = appConfigStore(); const configStore = appConfigStore();
console.log(configStore); const formState = reactive({ userName, password, code });
const { getThemeConfig: themeConfig, projectName } = storeToRefs(configStore); const { getThemeConfig: themeConfig, projectName } = storeToRefs(configStore);
const useAuthorization = authorizationService(); const useAuthorization = authorizationService();
const rememberFunc = (data) => { const rememberFunc = (data) => {
console.log(isRemember.value); console.log(isRemember.value);
if (!isRemember.value) return; if (!isRemember.value) return;
@@ -97,24 +116,28 @@
const { accountNo, password: pwd } = JSON.parse(data); const { accountNo, password: pwd } = JSON.parse(data);
userName.value = accountNo; userName.value = accountNo;
password.value = pwd; password.value = pwd;
formState.userName = userName.value;
formState.password = password.value;
} }
}); });
const submit = (): void => { const submit = (value): void => {
if (password.value === '') { console.log(value);
errorMsg.value = '请输入密码';
errorShow.value = true; // if (password.value === '') {
return; // errorMsg.value = '请输入密码';
}
if (userName.value === '') {
errorMsg.value = '请输入账号';
errorShow.value = true;
return;
}
// if (!code.value) {
// errorMsg.value = '请输入验证码';
// errorShow.value = true; // errorShow.value = true;
// return; // return;
// } // }
// if (userName.value === '') {
// errorMsg.value = '请输入账号';
// errorShow.value = true;
// return;
// }
// if (!code.value) {
// // errorMsg.value = '请输入验证码';
// // errorShow.value = true;
// return;
// }
// if (code.value.toLocaleLowerCase() !== verifyCode.value.toLocaleLowerCase()) { // if (code.value.toLocaleLowerCase() !== verifyCode.value.toLocaleLowerCase()) {
// errorMsg.value = '请输入正确的验证码'; // errorMsg.value = '请输入正确的验证码';
// errorShow.value = true; // errorShow.value = true;
@@ -208,7 +231,15 @@
const onGetCode = (res) => { const onGetCode = (res) => {
verifyCode.value = res; verifyCode.value = res;
}; };
const validator = async (rule, value) => {
if (!value) return Promise.reject('请输入验证码');
if (value?.toLocaleLowerCase() !== verifyCode.value.toLocaleLowerCase())
return Promise.reject('请输入正确的验证码');
};
return { return {
validator,
formState,
projectName, projectName,
onGetCode, onGetCode,
code, code,
@@ -323,7 +354,7 @@
.loginInfo { .loginInfo {
height: 48px; height: 48px;
width: 100%; width: 100%;
margin-bottom: 24px; // margin-bottom: 24px;
font-size: 16px !important; font-size: 16px !important;
:deep(.ant-input) { :deep(.ant-input) {
@@ -340,10 +371,12 @@
} }
} }
.loginInfo:last-child { .loginInfo:last-child {
margin-bottom: 16px; // margin-bottom: 16px;
} }
.loginInfo:nth-child(5n + 2) { .loginInfo:nth-child(4) {
margin-bottom: 0px; width: fit-content;
// margin-bottom: 0px;
// height: 20px !important;
} }
} }