lushihan 6 months ago
parent
commit
30743f1474
  1. 4
      hx-ai-intelligent/src/api/origanizemanage.ts
  2. 40
      hx-ai-intelligent/src/router/organizationManage.ts
  3. 2
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs.vue
  4. 10
      hx-ai-intelligent/src/view/organizationManage/departmentManage/config.ts
  5. 208
      hx-ai-intelligent/src/view/organizationManage/departmentManage/index.vue
  6. 10
      hx-ai-intelligent/src/view/organizationManage/usermanage/index.vue
  7. 2
      hx-ai-intelligent/vite.config.ts
  8. 10
      hx-op/.env
  9. 22
      hx-op/.env.development
  10. 35
      hx-op/.env.production
  11. 1
      hx-op/.version
  12. 74
      hx-op/build.sh
  13. 19
      hx-op/index.html
  14. BIN
      hx-op/public/asset/file/whiteListUser.xlsx
  15. BIN
      hx-op/public/asset/font/QuartzMS.TTF
  16. BIN
      hx-op/public/asset/image/NoImage.png
  17. BIN
      hx-op/public/asset/image/header.png
  18. BIN
      hx-op/public/asset/image/login/adminIcon.png
  19. BIN
      hx-op/public/asset/image/login/background.png
  20. BIN
      hx-op/public/asset/image/login/icon_clear.png
  21. BIN
      hx-op/public/asset/image/noResource.png
  22. BIN
      hx-op/public/asset/image/side.png
  23. BIN
      hx-op/public/asset/image/sider_collapsed_background.png
  24. 1
      hx-op/public/asset/js/tdt.js
  25. BIN
      hx-op/public/favicon.ico
  26. 12
      hx-op/release.yaml
  27. 35
      hx-op/resources/scripts/nervui/smart-parking-depositor/create.sh
  28. 1
      hx-op/resources/scripts/nervui/smart-parking-depositor/delete.sh
  29. 1
      hx-op/resources/scripts/nervui/smart-parking-depositor/setup.sh
  30. 1
      hx-op/resources/scripts/nervui/smart-parking-depositor/start.sh
  31. 1
      hx-op/resources/scripts/nervui/smart-parking-depositor/stop.sh
  32. 30
      hx-op/resources/scripts/nervui/smart-parking-depositor/type.json
  33. 64
      hx-op/resources/templates/deploy.json
  34. 26545
      hx-op/routes.json
  35. 215
      hx-op/src/App.vue
  36. 6
      hx-op/src/api/index.ts
  37. 9
      hx-op/src/api/origanizemanage.ts
  38. 17
      hx-op/src/api/user.ts
  39. 108
      hx-op/src/config/app.config.ts
  40. 2
      hx-op/src/config/index.ts
  41. 22
      hx-op/src/enum/http-enum.ts
  42. 10
      hx-op/src/icon/dicizhishou.svg
  43. 5
      hx-op/src/icon/downArrow.svg
  44. 8
      hx-op/src/icon/headerAdminIcon.svg
  45. 5
      hx-op/src/icon/passWord.svg
  46. 6
      hx-op/src/icon/trigger.svg
  47. 5
      hx-op/src/icon/userName.svg
  48. 18
      hx-op/src/main.ts
  49. 29
      hx-op/src/router/home.ts
  50. 11
      hx-op/src/router/index.ts
  51. 29
      hx-op/src/router/organizationManage.ts
  52. 12
      hx-op/src/store/item.ts
  53. 151
      hx-op/src/theme/detail.less
  54. 72
      hx-op/src/theme/form.less
  55. 183
      hx-op/src/theme/global.less
  56. 73
      hx-op/src/theme/global.scss
  57. 2
      hx-op/src/theme/theme.scss
  58. 36
      hx-op/src/theme/variable.less
  59. 1
      hx-op/src/types.d.ts
  60. 21
      hx-op/src/util/debounce.ts
  61. 17
      hx-op/src/view/developing.vue
  62. 74
      hx-op/src/view/organizationManage/enterpriseManage/TreeAdd.vue
  63. 335
      hx-op/src/view/organizationManage/enterpriseManage/config.ts
  64. 175
      hx-op/src/view/organizationManage/enterpriseManage/index.vue
  65. 43
      hx-op/src/view/organizationManage/enterpriseManage/mock.ts
  66. 51
      hx-op/tsconfig.json
  67. 20
      hx-op/vite.config.ts
  68. 35
      lib/component/form/cascader/cascader.vue
  69. 9
      lib/component/table/table.vue
  70. 2
      lib/saas/config/table.config.ts
  71. 14
      lib/saas/store/modules/app-config.ts
  72. 2
      lib/saas/view/system/layout/header.vue
  73. 3
      lib/util/http/axios.ts
  74. 2
      package.json

4
hx-ai-intelligent/src/api/origanizemanage.ts

@ -1,6 +1,7 @@
const BASE_URL = '/carbon-smart';
export enum permission {
add = `${BASE_URL}/admin/permission/save`,
permissionTree = `${BASE_URL}/api/dept/permissionTree`,
}
export enum origanizemanage {
@ -27,4 +28,7 @@ export enum department {
addRole = `${BASE_URL}/api/dept/addRole`,
editRole = `${BASE_URL}/api/dept/editRole`,
queryRoleTree = `${BASE_URL}/api/dept/queryRoleTree`,
queryDeptPermission = `${BASE_URL}/api/dept/queryDeptPermission`,
queryRolePermission = `${BASE_URL}/api/dept/queryRolePermission`,
}

40
hx-ai-intelligent/src/router/organizationManage.ts

@ -38,6 +38,41 @@ const organizationManage = {
meta: {
title: '用户管理',
keepAlive: true,
operates: [
{ title: '新增', code: 'userAdd' },
{
title: '导入',
code: 'userImport',
},
{
title: '模板下载',
code: 'userTemDownload',
},
{
title: '导出',
code: 'userExports',
},
{
title: '批量删除',
code: 'userBatchDel',
},
{
title: '编辑',
code: 'userEdit',
},
{
title: '冻结',
code: 'userFrozen',
},
{
title: '重置密码',
code: 'userCodeReset',
},
{
title: '删除',
code: 'userDelete',
},
],
// backApi: [],
},
},
@ -48,11 +83,11 @@ const organizationManage = {
name: 'AuthorityManage',
meta: { title: '部门/权限', hideChildren: true, icon: 'dicizhishou' },
component: Base,
redirect: { name: 'authorityManageIndex' },
redirect: { name: 'AuthorityManageIndex' },
children: [
{
path: 'index',
name: 'authorityManageIndex',
name: 'AuthorityManageIndex',
component: () => import('/@/view/organizationManage/departmentManage/index.vue'),
meta: {
title: '部门/权限',
@ -62,7 +97,6 @@ const organizationManage = {
},
],
},
],
};
export default organizationManage;

2
hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs.vue

@ -861,6 +861,8 @@
},
]);
const columns1 = [
]);
const columns1 = [
{
title: "序号",
dataIndex: "key",

10
hx-ai-intelligent/src/view/organizationManage/departmentManage/config.ts

@ -116,7 +116,7 @@ export const formConfig2 = (disabled2: Boolean) => {
// },
{
label: '节点编码',
field: 'code',
field: 'roleCode',
component: 'NsInput',
componentProps: {
disabled: disabled2,
@ -132,15 +132,16 @@ export const formConfig2 = (disabled2: Boolean) => {
},
{
label: '是否部门领导',
field: 'isleader',
field: 'isLeader',
component: 'NsRadioGroup',
componentProps: {
disabled: disabled2,
radioType: 'radio',
options: [
{ label: '是', value: 1 },
{ label: '否', value: 2 },
{ label: '是', value: 0 },
{ label: '否', value: 1 },
],
},
rules: [
{
required: true,
@ -148,7 +149,6 @@ export const formConfig2 = (disabled2: Boolean) => {
},
],
},
},
{
field: 'remark',
label: '备注',

208
hx-ai-intelligent/src/view/organizationManage/departmentManage/index.vue

@ -6,9 +6,7 @@
<div class="ns-table-title">部门管理</div>
<a-row>
<a-col :span="12" class="tree">
<ns-button :disabled="disabled" style="margin: 10px" type="primary" @click="addApartment"
>新增部门</ns-button
>
<ns-button style="margin: 10px" type="primary" @click="addApartment">新增部门</ns-button>
<ns-button :disabled="disabled" type="primary" @click="addApartmentSon"
>新增子部门</ns-button
>
@ -39,21 +37,28 @@
formLayout="vertical"
class="form" />
</a-tab-pane>
<a-tab-pane key="2" tab="部门权限">
<a-tab-pane key="2" :disabled="disabled" tab="部门权限">
<a-tree
:tree-data="apartmentAdminTreeData"
:fieldNames="{ children: 'menus', title: 'label', key: 'permissionId' }"
v-model:checkedKeys="ApartcheckedKeys"
checkable
:selectable="false"
defaultExpandAll
@select="ApartmentSelect">
<template #title="{ title }">
{{ title }}
</template>
<template #title="data"> {{ data.label }}</template>
</a-tree>
</a-tab-pane>
</a-tabs>
<ns-button style="margin: 20px" type="primary" @click="CancelApartment">取消</ns-button>
<ns-button type="primary" @click="ApartmentSure">确定</ns-button>
<div v-show="activeKey === '1'">
<ns-button style="margin: 16px" type="primary" @click="CancelApartment">取消</ns-button>
<ns-button type="primary" :disabled="disabled" @click="ApartmentSure">确定</ns-button>
</div>
<div v-show="activeKey === '2'">
<ns-button style="margin-left: 16px" type="primary" @click="apartmentPermission"
>确定</ns-button
>
</div>
</a-col>
</a-row>
</div>
@ -61,9 +66,7 @@
<div class="ns-table-title">角色管理</div>
<a-row>
<a-col :span="12" class="tree">
<ns-button :disabled="disabled2" style="margin: 10px" type="primary" @click="addUser"
>新增角色</ns-button
>
<ns-button style="margin: 10px" type="primary" @click="addUser">新增角色</ns-button>
<ns-button :disabled="disabled2" type="primary" @click="addUserSon">新增子角色</ns-button>
<ns-button :disabled="disabled2" style="margin: 10px" type="primary" @click="deleteUser"
>删除</ns-button
@ -87,32 +90,36 @@
formLayout="vertical"
class="form" />
</a-tab-pane>
<a-tab-pane key="2" tab="角色权限">
<a-tab-pane key="2" :disabled="disabled2" tab="角色权限">
<a-tree
v-if="userAdminTreeData?.length"
:tree-data="userAdminTreeData"
v-model:checkedKeys="UsercheckedKeys"
defaultExpandAll
:fieldNames="{ children: 'menus', title: 'label', key: 'permissionId' }"
:selectable="false"
checkable
@select="UserSelect">
<template #title="{ title }">
{{ title }}
</template>
</a-tree>
@select="UserSelect" />
</a-tab-pane>
</a-tabs>
<ns-button style="margin: 20px" type="primary" @click="CancelUser">取消</ns-button>
<ns-button type="primary" @click="UserSure">{{ disabled2 ? '编辑' : '确定' }}</ns-button>
<div v-show="activeKey2 === '1'">
<ns-button style="margin: 16px" type="primary" @click="CancelUser">取消</ns-button>
<ns-button type="primary" :disabled="disabled2" @click="UserSure"> 确定</ns-button>
</div>
<div v-show="activeKey2 === '2'">
<ns-button style="margin: 16px" type="primary" @click="rolePermission"> 确定</ns-button>
</div>
</a-col>
</a-row>
</div>
</div>
</template>
<script lang="ts">
import { createVNode, defineComponent, reactive, ref, watch } from 'vue';
import { createVNode, defineComponent, reactive, ref, watch, watchEffect } from 'vue';
import { Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { http } from '/nerv-lib/util/http';
import { cloneDeep } from 'lodash-es';
import { cloneDeep, get } from 'lodash-es';
import { formConfig, formConfig2 } from './config';
import { department } from '/@/api/origanizemanage';
import { permission } from '/@/api/origanizemanage';
@ -140,30 +147,18 @@
const projectId = JSON.parse(sessionStorage.getItem('userInfo')).projectId;
const userAdminTreeData = ref([]);
const apartmentTreeData = ref([]);
const apartmentAdminTreeData = ref([]);
const userTreeData = ref([]);
const getPermissionTree = (params) => {
return http.post(permission.permissionTree, params).then((res) => {
apartmentAdminTreeData.value = get(res, 'data.data');
userAdminTreeData.value = get(res, 'data.data');
});
};
getPermissionTree({ projectId });
const apartmentAdminTreeData = [
{
title: '首页',
key: '0-0',
children: [
{
title: '控制台',
key: '0-0-0',
children: [
{ title: 'leaf', key: '0-0-0-0' },
{ title: 'leaf', key: '0-0-0-1' },
],
},
{
title: '用户管理',
key: '0-0-1',
children: [{ key: '0-0-1-0', title: 'sss' }],
},
],
},
];
watch(ApartcheckedKeys, () => {
console.log('checkedKeys', ApartcheckedKeys.value);
});
@ -179,6 +174,7 @@
apartmentTreeData.value = res.data;
});
//
const getTree = () => {
getDepartList({ orgId }).then((res) => {
apartmentTreeData.value = res.data;
@ -186,12 +182,19 @@
});
};
const getUserTree = (params = { deptId: 2 }) => {
//
const getUserTree = (params = { deptId: selectRef.value?.deptInfo?.deptId }) => {
http.post(department.queryRoleTree, params).then((res) => {
userTreeData.value = res.data;
});
};
getUserTree({ deptId: 2 });
//
watchEffect(() => {
if (selectRef.value) {
getUserTree();
}
});
const opMap: any = {
type: 'add',
fuc: () => {},
@ -234,15 +237,14 @@
const addUser = () => {
disabled2.value = false;
opMap.type = 'addUser';
formData.value = {};
formData2.value = {};
opMap.fuc = (params) => {
delete params.roleId;
return http.post(department.addRole, {
...params,
orgId,
projectId,
enName: 'leader',
roleNote: 'wqe',
deptId: selectRef.value.deptInfo.deptId,
});
};
};
@ -250,17 +252,15 @@
const addUserSon = () => {
disabled.value = false;
opMap.type = 'addUserSon';
formData.value = {};
formData2.value = {};
opMap.fuc = (params) => {
delete params.roleId;
delete params.proleId;
return http.post(department.addRole, {
...params,
proleId: 4,
orgId,
projectId,
enName: 'leader',
roleNote: 'wqe',
proleId: selectRef2.value.roleId,
deptId: selectRef.value.deptInfo.deptId,
});
};
};
@ -279,7 +279,7 @@
onOk() {
http.post(department.deptDel, { deptId: selectRef.value.deptInfo.deptId }).then(() => {
getTree();
clearData();
clearApartData();
});
},
onCancel() {
@ -295,20 +295,85 @@
content: createVNode('div', { style: 'color:red;' }, ''),
onOk() {
http.post(department.delRole, { roleId: selectRef2.value.roleId }).then(() => {
getUserTree();
getUserTree({ deptId: selectRef.value.deptInfo.deptId });
});
},
class: 'test',
});
};
const clearData = () => {
const clearApartData = () => {
selectRef.value = {};
formData.value = {};
opMap.type = '';
opMap.fuc = '';
selectKey.value = '';
};
//
const apartmentPermission = () => {
http
.post(department.addPermission, {
deptId: selectRef.value?.deptInfo.deptId,
projectId,
permissionVoList: ApartcheckedKeys.value.map((item) => {
return { permissionId: item };
}),
})
.then(() => {
NsMessage.success('保存成功');
});
};
//
const rolePermission = () => {
http
.post(department.addRolePermission, {
// deptId: selectRef.value?.deptInfo.deptId,
roleId: selectRef2.value?.roleId,
projectId,
permissionVoList: UsercheckedKeys.value.map((item) => {
return { permissionId: item };
}),
})
.then(() => {
NsMessage.success('保存成功');
});
};
//
const getDeptPermission = () => {
http
.post(department.queryDeptPermission, { deptId: selectRef.value?.deptInfo.deptId })
.then((res) => {
ApartcheckedKeys.value = res.data.map((item) => {
return item.permissionId;
});
});
};
//
const getRolePermission = () => {
http
.post(department.queryRolePermission, { roleId: selectRef2.value?.roleId })
.then((res) => {
UsercheckedKeys.value = res.data.map((item) => {
return item.permissionId;
});
});
};
/**
* 默认选中视为编辑部门
* type editDpet
*/
const apartmentChoose = () => {
opMap.type = 'editDpet';
opMap.fuc = (params) => {
return http.post(department.deptEdit, params);
};
};
//
const SelectApartmentTree = (selectedKeys: any, info: any) => {
const { selected } = info;
@ -317,12 +382,21 @@
selectKey.value = selectedKeys[0];
selectRef.value = info.node.dataRef;
formData.value = cloneDeep(info.node.dataRef.deptInfo);
apartmentChoose();
ApartcheckedKeys.value.splice(0);
getDeptPermission();
// getUserTree({ deptId: selectRef.value.deptInfo.deptId });
};
/**
* 默认选中视为编辑角色
* type editDpet
*/
const roleChoose = () => {
opMap.type = 'editDpet';
opMap.fuc = (params) => {
return http.post(department.deptEdit, params);
};
getUserTree({ deptId: selectRef.value.deptInfo.deptId });
};
//
@ -334,10 +408,15 @@
selectKey2.value = selectedKeys[0];
selectRef2.value = info.node.dataRef;
formData2.value = cloneDeep(info.node.dataRef);
roleChoose();
UsercheckedKeys.value.splice(0);
getRolePermission();
};
const CancelApartment = () => {
disabled.value = true;
//
// clearApartData();
};
const CancelUser = () => {
@ -373,13 +452,15 @@
opMap.fuc && opMap.fuc({ ...formData.value, selectRef: selectRef.value });
}
};
const UserSure = () => {
disabled2.value = !disabled2.value;
console.log(formData2.value, 'formData2');
console.log(opMap.type, 'opMap.type');
const typeArr = ['addUserSon', 'addUser'];
const typeArr = ['addUserSon', 'addUser', 'editRole'];
if (typeArr.includes(opMap.type)) {
opMap.fuc && opMap.fuc(formData2.value);
opMap.fuc &&
opMap.fuc(formData2.value).then(() => {
getUserTree();
});
} else if (selectRef2.value && opMap.type === 'addson')
selectRef2.value['children'] = [
{
@ -391,7 +472,6 @@
else {
console.log('ss');
}
formData2.value = {};
};
return {
@ -424,6 +504,8 @@
UsercheckedKeys,
UserSelect,
formRef,
apartmentPermission,
rolePermission,
};
},
});

10
hx-ai-intelligent/src/view/organizationManage/usermanage/index.vue

@ -222,7 +222,7 @@
headerActions: [
{
label: '新增',
name: 'RoleTypeAdd',
name: 'userAdd',
type: 'primary',
handle: () => {
opMap.type = 'add';
@ -239,19 +239,19 @@
{
label: '导入',
type: 'primary',
name: 'RoleTypeAdd',
name: 'userImport',
handle: () => {},
},
{
label: '模板下载',
type: 'primary',
name: 'RoleTypeAdd',
name: 'userTemDownload',
handle: () => {},
},
{
label: '导出',
type: 'primary',
name: 'exports',
name: 'userExports',
},
{
label: '批量删除',
@ -345,7 +345,7 @@
actions: [
{
label: '编辑',
name: 'RoleTypeEdit',
name: 'userEdit',
// dynamicParams: 'uuid',
handle: (record: any) => {
userAuthList.value.splice(0);

2
hx-ai-intelligent/vite.config.ts

@ -12,7 +12,7 @@ const proxy = {
changeOrigin: true,
},
'/carbon-smart': {
target: 'http://123.60.103.97:8224',
target: 'http://192.168.112.144:8224',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/carbon-smart/, ''),
},

10
hx-op/.env

@ -0,0 +1,10 @@
# port
VITE_PORT = 3301
#mode
VITE_GLOB_APP_RUN_TYPE = saas
# spa-title
VITE_GLOB_APP_TITLE = hx-ai-intelligent Depositor
# spa shortname
VITE_GLOB_APP_SHORT_NAME = hx-ai-intelligent-depositor

22
hx-op/.env.development

@ -0,0 +1,22 @@
# Whether to open mock
VITE_USE_MOCK = true
# public path
VITE_PUBLIC_PATH = /hx-op/
# Cross-domain proxy, you can configure multiple
# Please note that no line breaks http://100.73.70.51
#VITE_PROXY = {"/community":{ "target":"http://100.73.70.51","changeOrigin": true,"prependPath":false},"/parking":{ "target":"http://100.73.70.246:8080","changeOrigin": true,"iprependPath":false}}
# VITE_PROXY=[["/api","http://100.73.70.51"],["/parking","http://100.73.70.246:8080"]]
# Delete console
VITE_DROP_CONSOLE = false
# Basic interface address SPA
VITE_GLOB_API_URL=/basic-api
# File upload address, optional
VITE_GLOB_UPLOAD_URL=/upload
# Interface prefix
VITE_GLOB_API_URL_PREFIX=

35
hx-op/.env.production

@ -0,0 +1,35 @@
# Whether to open mock
VITE_USE_MOCK = true
# public path
VITE_PUBLIC_PATH = /hx-op/
# Delete console
VITE_DROP_CONSOLE = true
# Whether to enable gzip or brotli compression
# Optional: gzip | brotli | none
# If you need multiple forms, you can use `,` to separate
VITE_BUILD_COMPRESS = 'none'
# Whether to delete origin files when using compress, default false
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
# Basic interface address SPA
VITE_GLOB_API_URL=/basic-api
# File upload address, optional
# It can be forwarded by nginx or write the actual address directly
VITE_GLOB_UPLOAD_URL=/upload
# Interface prefix
VITE_GLOB_API_URL_PREFIX=
# Whether to enable image compression
VITE_USE_IMAGEMIN= true
# use pwa
VITE_USE_PWA = false
# Is it compatible with older browsers
VITE_LEGACY = false

1
hx-op/.version

@ -0,0 +1 @@
0.0.1

74
hx-op/build.sh

@ -0,0 +1,74 @@
#!/bin/bash
SOURCE="$0"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
if [ -z $WORKSPACE ];then
echo "WORKSPACE not exists"
else
set DIR=$WORKSPACE
fi
echo "current dir"
echo "$DIR"
cd "$DIR"
projectname=$(basename `pwd`)
npm run parking-build
if [ -d "$DIR/dist" ];then
cd "$DIR/dist"
# copy module.json
cp ../module.json ./
# package
VERSION=$(cat ../.version)
lastdir=../release/
if [ -d ${lastdir} ];then
echo "删除旧release文件夹"
rm -rf ${lastdir}
else
echo "文件夹不存在!"
fi
mkdir -p ${lastdir}
dir=../release/nerv/$projectname/$VERSION
mkdir -p ${dir}
tar -zcvf "${dir}/$projectname-$VERSION.tgz" ./*
templatedir=../release/resources/templates/nerv/$projectname/$VERSION/$projectname
mkdir -p ${templatedir}
cp -r ../resources/templates/* ${templatedir}
cd ../
releasefile=nerv-$projectname-$VERSION.tgz
if [ -f ${releasefile} ];then
echo "删除旧包!"
rm -rf ${releasefile}
fi
tar -zcvf ${releasefile} ./release/* release.yaml
mkdir -p ./release/nervui
cp -r ./release/nerv/* ./release/nervui
if [ -f ${releasefile} ];then
echo "编译成功!"
mv ${releasefile} ./release
else
echo "编译失败!!!"
exit 1
fi
else
echo "编译失败!!!"
exit 1
fi

19
hx-op/index.html

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="referrer" content="never" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode: '09e43004c09d39c0e61f8fd65d5e6a5a',
};
</script> -->
<title>AI智能BAS系统</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./src/main.ts"></script>
</body>
</html>

BIN
hx-op/public/asset/file/whiteListUser.xlsx

Binary file not shown.

BIN
hx-op/public/asset/font/QuartzMS.TTF

Binary file not shown.

BIN
hx-op/public/asset/image/NoImage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
hx-op/public/asset/image/header.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
hx-op/public/asset/image/login/adminIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
hx-op/public/asset/image/login/background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

BIN
hx-op/public/asset/image/login/icon_clear.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
hx-op/public/asset/image/noResource.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
hx-op/public/asset/image/side.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
hx-op/public/asset/image/sider_collapsed_background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

1
hx-op/public/asset/js/tdt.js

File diff suppressed because one or more lines are too long

BIN
hx-op/public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

12
hx-op/release.yaml

@ -0,0 +1,12 @@
# 上传release目录信息到nerv-file仓库
release:
- {src: release, dest: /upload/pkg, include: [".*(.tgz)$"]}
- {src: release/resources/templates, dest: /upload/templates}
register:
name: nervui-smart-parking
version: 2.1.19
components:
- type: nervui-smart-parking
resources:
- {type: template, relativePath: /nervui-smart-parking/deploy.json}

35
hx-op/resources/scripts/nervui/smart-parking-depositor/create.sh

@ -0,0 +1,35 @@
echo "=====================================================create====================================================="
#!/usr/bin/env bash
function create() {
if [ -d "$nervui_app_home" ];then
echo "$nervui_app_home exists!"
else
echo "start mkdir $nervui_app_home"
mkdir -p "$nervui_app_home"
fi
pkg_file_name=${pkg_url##*/}
pkg_file_path="$nervui_app_home$pkg_file_name"
echo "start download $pkg_url"
curl -L -o $pkg_file_path $pkg_url
echo "start install $pkg_file_path"
tar -xf $pkg_file_path -C $nervui_app_home
}
if [ "$pkg_url" == "" ]; then
echo {\"error\":\"pkg_url is empty\"}
exit 1
elif [ "$nervui_app_home" == "" ]; then
echo {\"error\":\"nervui_app_home is empty\"}
exit 1
else
create
fi

1
hx-op/resources/scripts/nervui/smart-parking-depositor/delete.sh

@ -0,0 +1 @@
echo "=====================================================delete====================================================="

1
hx-op/resources/scripts/nervui/smart-parking-depositor/setup.sh

@ -0,0 +1 @@
echo "=====================================================setup====================================================="

1
hx-op/resources/scripts/nervui/smart-parking-depositor/start.sh

@ -0,0 +1 @@
echo "=====================================================start====================================================="

1
hx-op/resources/scripts/nervui/smart-parking-depositor/stop.sh

@ -0,0 +1 @@
echo "=====================================================stop====================================================="

30
hx-op/resources/scripts/nervui/smart-parking-depositor/type.json

@ -0,0 +1,30 @@
{
"name": "/nervui/nervui-smart-parking-op",
"operations": [
{
"name": "Create",
"type": "shell",
"implementor": "create.sh"
},
{
"name": "Delete",
"type": "shell",
"implementor": "delete.sh"
},
{
"name": "Setup",
"type": "shell",
"implementor": "setup.sh"
},
{
"name": "Start",
"type": "shell",
"implementor": "start.sh"
},
{
"name": "Stop",
"type": "shell",
"implementor": "stop.sh"
}
]
}

64
hx-op/resources/templates/deploy.json

@ -0,0 +1,64 @@
{
"name": "/nervui/nervui-smart-parking",
"version": 1,
"inputs": [
{
"name": "server_ip",
"type": "string",
"required": true,
"description": "应用安装IP地址",
"inputType": "ipSelectType"
},
{
"name": "version",
"type": "string",
"required": true,
"description": "软件版本",
"inputType": "versionSelectType"
},
{
"name": "install_dir",
"type": "string",
"required": true,
"defaultValue": "/data",
"inputType": "textInputType",
"description": "安装目录"
}
],
"nodes": [
{
"name": "nervui-smart-parking",
"type": "/nerv/nerv-orchestrator/cluster/Nervui",
"parameters": [
{
"name": "file_repository",
"value": "${nerv_file_repository}"
},
{
"name": "install_dir",
"value": "${install_dir}"
},
{
"name": "pkg_url",
"value": "/api/pkg/nerv/nervui-smart-parking/${version}/nervui-smart-parking-${version}.tgz"
}
],
"dependencies": [
{
"type": "contained",
"target": "host"
}
]
},
{
"name": "host",
"type": "/nerv/nerv-orchestrator/compute/Host",
"parameters": [
{
"name": "address",
"value": "${server_ip}"
}
]
}
]
}

26545
hx-op/routes.json

File diff suppressed because it is too large

215
hx-op/src/App.vue

@ -0,0 +1,215 @@
<template>
<a-config-provider :locale="locale">
<router-view />
</a-config-provider>
</template>
<script lang="ts">
import { defineComponent, watch, ref } from 'vue';
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import { useRouter } from 'vue-router';
export default defineComponent({
name: 'App',
setup() {
const router = useRouter();
const cachedViews = ['Status'];
return {
cachedViews,
locale: zhCN,
};
},
});
</script>
<style lang="less" scoped>
:deep(.ns-content) {
padding-top: 80px !important;
}
#app {
width: 100%;
height: 100%;
}
:deep(.ns-left-menu .firstMenuItem-selected .ant-menu-title-content) {
background: unset !important;
}
:deep(.ns-left-menu .ant-menu-item-selected .ant-menu-title-content) {
color: #fff !important;
background: @primary-color;
border-radius: 2px;
height: 40px;
line-height: 40px;
a {
color: #ffffff !important;
}
}
:deep(.ant-menu-light.ant-menu-horizontal > .ant-menu-item:hover) {
background: @primary-color;
}
:deep(.ant-menu-inline .ant-menu-submenu-title) {
color: rgba(255, 255, 255, 0.9) !important;
}
:deep(.ns-left-menu .ant-layout-sider-children .ant-menu-sub.ant-menu-inline) {
position: relative;
&::before {
display: flex;
width: 2px;
height: calc(100% - 40px);
position: absolute;
top: 20px;
left: 20px;
content: '';
background-color: rgba(255, 255, 255, 0.2);
}
}
//*************************tab list */
:deep(.tabListTable) {
.ns-table-title {
text-align: left;
height: 46px;
line-height: 46px;
font-size: 18px;
font-weight: bold;
user-select: text;
padding-left: 16px;
background: #fff;
width: calc(100% + 32px);
margin-left: -16px;
}
.tabs-list {
overflow: visible !important;
}
.ant-tabs-nav {
width: calc(100% + 32px);
margin-left: -16px !important;
background: #fff;
}
.ant-tabs-nav-wrap {
padding: 0 16px;
}
}
//********************* */
:deep(.nsDetailView) {
min-height: 100%;
height: 100%;
.ns-detail-content {
padding: 0px 24px;
border-top: 16px solid #e5ebf0;
}
.ant-descriptions-item-label {
color: rgba(0, 0, 0, 0.5);
font-family: PingFang SC;
font-size: 14px;
}
.ant-descriptions-item-content {
color: rgba(0, 0, 0, 0.95);
font-family: PingFang SC;
font-size: 14px;
}
.ant-descriptions-title {
&::after {
content: '';
width: 75px;
height: 7px;
display: block;
background: linear-gradient(90deg, #537fff 0%, #fff 82.67%);
margin-left: 2px;
margin-top: -2px;
}
}
.ant-descriptions-row > th,
.ant-descriptions-row > td {
padding-bottom: 8px;
}
.ns-page-header {
margin-bottom: 0 !important;
padding-top: 7px !important;
padding-bottom: 7px !important;
width: calc(100% + 32px);
margin-left: -16px;
.title {
cursor: pointer;
font-size: 18px !important;
}
}
.ant-descriptions-header {
margin: 16px 0 16px 0 !important;
.ant-descriptions-title {
line-height: 16px;
font-size: 16px;
}
}
}
:deep(.ns-detail .ant-descriptions-header .descriptions-title) {
&:after {
content: '';
width: 75px;
height: 7px;
display: block;
background: linear-gradient(90deg, @primary-color 0%, #fff 82.67%);
margin-left: 2px;
margin-top: -2px;
}
}
:deep(.ant-descriptions-header .descriptions-title) {
&:after {
content: '';
width: 75px;
height: 7px;
display: block;
background: linear-gradient(90deg, @primary-color 0%, #fff 82.67%);
margin-left: 2px;
margin-top: -2px;
}
}
</style>
<style lang="less">
//
.listTableModal .ant-modal-title {
font-weight: 600;
}
.listTableModal .ant-modal-body {
padding: 16px !important;
.ant-tabs-nav-wrap {
padding: 0px;
}
.ns-list-table {
border-left: 16px solid #e5ebf0;
border-right: 16px solid #e5ebf0;
border-bottom: 16px solid #e5ebf0;
}
}
:deep(.ant-menu-submenu-title) {
color: #ffffff !important;
}
</style>
<style lang="less">
//************************
.ant-menu-submenu-placement-bottomLeft {
.ant-menu-submenu {
background: rgb(3 24 53) !important;
}
.ant-menu-sub {
background: rgb(3 24 53) !important;
}
.ant-menu-title-content {
color: #fff !important;
.ns-icon {
margin-right: 7px;
transform: translateY(2px);
}
}
.ant-menu-submenu-arrow {
color: #fff !important;
}
}
</style>

6
hx-op/src/api/index.ts

@ -0,0 +1,6 @@
/***
* module:Array<resource>
*/
export const apiModule = {
parking: ['User', 'CurrentUser', 'Organizational'],
};

9
hx-op/src/api/origanizemanage.ts

@ -0,0 +1,9 @@
const BASE_URL = '/carbon-smart';
export enum enterPrise {
list = `${BASE_URL}/admin/org/queryByPage`,
del = `${BASE_URL}/admin/org/del`,
edit = `${BASE_URL}/admin/org/edit`,
save = `${BASE_URL}/admin/org/save`,
link = `${BASE_URL}/admin/org/link`,
}

17
hx-op/src/api/user.ts

@ -0,0 +1,17 @@
import { http } from '/nerv-lib/saas';
enum Api {
// USER_LOGIN = '/api/community/objs/Login', //用户登录
// USER_INFO = '/api/community/community/objs/CurrentUser', //获取用户信息
USER_LOGIN = 'api/web/objs/Login', //用户登录
USER_INFO = 'api/web/objs/CurrentUser', //获取用户信息
USER_RESOURCE = '/api/community/objs/User/Resource', //获取用户资源
}
export const userLogin = (data) => http.post(Api.USER_LOGIN, data);
export const userInfo = () => http.get(Api.USER_INFO);
export const userResource = () => http.get(Api.USER_RESOURCE);
/**
* @description
* @property `[fatherRegionUuid]`
*/

108
hx-op/src/config/app.config.ts

@ -0,0 +1,108 @@
/** @format */
import { http } from '/nerv-lib/saas';
import { ref } from 'vue';
const value = ref('1');
const transform = (data, map) => {
return Object.keys(map).reduce((pre, cur) => {
pre[cur] = data[map[cur]];
return pre;
}, {});
};
export const appConfig = {
projectType: 'web',
baseApi: '/api',
enablePermissions: false,
// themeColor: '#eee',
siderPosition: 'left',
baseHeader: '/parkingManage',
baseRouter: '/parkingManage/parkingLotManage',
themeConfig: {
bgImageUrl: `${import.meta.env.VITE_PUBLIC_PATH}/asset/image/login/background.png`,
},
// userCustomRouterGuard: (to, from, next, whiteNameList, authorizationStore, appConfig) => {
// console.log({ to, from, next, whiteNameList, authorizationStore, appConfig }, 'routeConfig');
// next();
// },
// customUpdatePwd: () => import('/@/view/updatePassword/updatePassword.vue'),
// userInfoApi: () => {
// return {
// code: 200,
// success: true,
// data: {
// accountCode: '1305107806187376793',
// accountName: 'adm*n',
// accountType: 'admin',
// accountStatus: 1,
// accountRealName: 'admin',
// organizationCode: 'dingcloud',
// authConfigList: [],
// organizeResCode: [],
// leadDepartmentUuidList: [],
// },
// };
// },
// headerSlotConfig: {
// component: 'NsSelect',
// componentProps: {
// style: { width: '200px' },
// placeholder: '请选择',
// value,
// onChange: (cur) => {
// value.value = cur;
// },
// options: [
// { label: '济阳', value: '1' },
// { label: '临沂', value: '2' },
// ],
// },
// },
timeout: 60 * 1000,
userLoginApi: '/carbon-smart/user/login',
userResourceApi: () => {
return { data: [] };
},
userInfoApi: () => {
return http.post('/carbon-smart/user/login/logInInfo').then((res) => {
const info = res.data;
const trD = transform(info, {
accountCode: 'userId',
accountName: 'realName',
accountRealName: 'realName',
orgId: 'orgId',
orgName: 'orgName',
projectId: 'projectId',
});
return { data: { ...trD } };
});
},
useHistoryTag: false,
// 修改密码配置
updatePassWordInfo: {
title: '修改密码',
subtitle: 'huaxing平台',
api: '/api/web/objs/User/changePassword',
},
// headerBellInfo: {
// isShow: true,
// api: '/api/web/objs/bulletin/readCount',
// toRouterName: 'NoticeManageIndex',
// },
resourceInfo: {
// application: {
// version: '1.1.74',
// label: '停车业务平台',
// dataScope: {
// scopeMode: 0,
// scopeType: '',
// dataTips: '',
// },
// },
// api: permission.add,
},
};

2
hx-op/src/config/index.ts

@ -0,0 +1,2 @@
import { appConfig } from '/@/config/app.config';
export { appConfig };

22
hx-op/src/enum/http-enum.ts

@ -0,0 +1,22 @@
export enum ResultEnum {
SUCCESS = 0,
ERROR = 1,
TIMEOUT = 401,
TOKEN_INVALID = 403,
}
export enum RequestEnum {
GET = 'POST',
POST = 'POST',
PUT = 'POST',
DELETE = 'POST',
}
export enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',
// form-data qs
FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
// form-data upload
FORM_DATA = 'multipart/form-data;charset=UTF-8',
}

10
hx-op/src/icon/dicizhishou.svg

@ -0,0 +1,10 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1175_4591)">
<path d="M40.6891 16.1069C41.3414 15.2143 41.7191 14.2873 41.7191 13.3947C41.7191 9.13748 34.2346 5.66992 24.9649 5.66992C15.6952 5.66992 8.21075 9.13748 8.21075 13.3947C8.21075 14.2873 8.58841 15.2143 9.24072 16.1069C7.31812 17.5146 6.90613 18.9565 6.90613 19.8492C6.90613 20.8791 7.42111 21.7718 8.21075 22.6987V36.6033C8.21075 40.8605 15.6952 44.3281 24.9649 44.3281C34.2346 44.3281 41.7191 40.8605 41.7191 36.6033V22.6987C42.5087 21.8061 43.0237 20.8791 43.0237 19.8492C43.0237 18.9565 42.646 17.5489 40.6891 16.1069ZM34.269 11.2318C35.3333 11.2318 36.1916 11.8154 36.1916 12.502C36.1916 13.1887 35.3333 13.7723 34.269 13.7723C33.2047 13.7723 32.3463 13.1887 32.3463 12.502C32.3463 11.8154 33.2047 11.2318 34.269 11.2318ZM25.1709 7.00888C26.1665 7.00888 26.9562 7.4552 26.9562 8.00452C26.9562 8.5195 26.1665 9.00015 25.1709 9.00015C24.1753 9.00015 23.3856 8.55383 23.3856 8.00452C23.3856 7.4552 24.1753 7.00888 25.1709 7.00888ZM25.1709 15.7979C26.2352 15.7979 27.0935 16.3816 27.0935 17.0682C27.0935 17.7549 26.2352 18.3385 25.1709 18.3385C24.1066 18.3385 23.2483 17.7549 23.2483 17.0682C23.2483 16.3816 24.1066 15.7979 25.1709 15.7979ZM16.4848 11.2318C17.5491 11.2318 18.4074 11.8154 18.4074 12.502C18.4074 13.1887 17.5491 13.7723 16.4848 13.7723C15.4205 13.7723 14.5622 13.1887 14.5622 12.502C14.5622 11.8154 15.4205 11.2318 16.4848 11.2318ZM15.9698 39.1782H13.3949V26.3036H15.0772C15.3519 26.4409 15.7295 26.4409 15.9698 26.5783V39.1782ZM26.2695 41.4785H23.6946V28.6039H26.2695V41.4785ZM36.5692 39.1782H33.9943V26.5439C34.269 26.4066 34.6466 26.4066 34.8869 26.2693H36.5692V39.1782ZM25.1366 24.999C15.5922 24.999 9.68704 21.6344 9.68704 19.8492C9.54971 19.3342 10.0647 18.6819 11.0947 17.9265H11.6096C14.5622 19.8492 19.4717 21.1538 24.9992 21.1538C30.6641 21.1538 35.6766 19.8492 38.7665 17.7892C38.9038 17.7892 38.9038 17.9265 39.0411 17.9265C39.9338 18.5789 40.5861 19.3342 40.5861 19.8492C40.5861 21.6688 34.6466 24.999 25.1366 24.999Z" fill="currentColor"/>
</g>
<defs>
<clipPath id="clip0_1175_4591">
<rect width="50" height="50" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

5
hx-op/src/icon/downArrow.svg

@ -0,0 +1,5 @@
<svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<g id="Frame">
<path id="Vector" d="M8.99953 9.87831L12.7119 6.16602L13.7725 7.22667L8.99953 11.9997L4.22656 7.22667L5.28723 6.16602L8.99953 9.87831Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 251 B

8
hx-op/src/icon/headerAdminIcon.svg

@ -0,0 +1,8 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="user">
<g id="user_2">
<path d="M17.25 7.5C17.25 10.3995 14.8995 12.75 12 12.75C9.1005 12.75 6.75 10.3995 6.75 7.5C6.75 4.6005 9.1005 2.25 12 2.25C14.8995 2.25 17.25 4.6005 17.25 7.5ZM15.75 7.5C15.75 5.42893 14.0711 3.75 12 3.75C9.92893 3.75 8.25 5.42893 8.25 7.5C8.25 9.57107 9.92893 11.25 12 11.25C14.0711 11.25 15.75 9.57107 15.75 7.5Z" fill="white" fill-opacity="0.9"/>
<path d="M20.9447 16.2792C21.4455 16.5183 21.75 17.032 21.75 17.5869V21C21.75 21.4142 21.4142 21.75 21 21.75H3C2.58579 21.75 2.25 21.4142 2.25 21V17.5869C2.25 17.032 2.55452 16.5183 3.0553 16.2792C5.7741 14.9806 8.79976 14.25 12 14.25C15.2002 14.25 18.2259 14.9806 20.9447 16.2792ZM12 15.75C9.05011 15.75 6.26152 16.4186 3.75 17.6097V20.25H20.25V17.6097C17.7385 16.4186 14.9499 15.75 12 15.75Z" fill="white" fill-opacity="0.9"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 923 B

5
hx-op/src/icon/passWord.svg

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="12" fill-opacity="0.1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.9352 9.87544L16.531 9.87547C16.531 8.58454 16.0608 7.36797 15.2071 6.44985C14.7866 5.99763 14.2954 5.64185 13.7472 5.39246C13.1745 5.13204 12.5662 5 11.9388 5C11.3114 5 10.7031 5.13204 10.1305 5.39243C9.58225 5.64182 9.09102 5.9976 8.67051 6.44983C7.81678 7.36797 7.34659 8.58452 7.34659 9.87544H8.94234C8.94234 8.06373 10.2865 6.58981 11.9388 6.58981C13.591 6.58981 14.9352 8.06373 14.9352 9.87544ZM7.46099 9.95703H16.539V9.95705C17.5421 9.95705 18 10.7674 18 11.7659V17.1925C18 18.191 17.5421 19.0014 16.539 19.0014H7.461C6.45786 19.0014 6 18.1919 6 17.1925V11.7659C6 10.7674 6.45787 9.95703 7.46099 9.95703ZM12.908 15.1319V16.2878C12.908 16.7871 12.5012 17.1922 12.0001 17.1922C11.4992 17.1922 11.0924 16.787 11.0924 16.2878V15.1328C10.5522 14.819 10.1846 14.242 10.1846 13.5745C10.1846 12.5751 10.997 11.7656 12.0001 11.7656C13.0034 11.7656 13.8157 12.5751 13.8157 13.5745C13.8159 14.242 13.4481 14.819 12.908 15.1319Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

6
hx-op/src/icon/trigger.svg

@ -0,0 +1,6 @@
<svg width="20" height="9" viewBox="0 0 20 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group 6356610" opacity="0.65">
<path id="Vector" d="M6.89084 5.13637L9.85448 8.1L8.95448 9L4.45446 4.49997L8.95448 -8.86233e-07L9.85448 0.899993L6.89091 3.86357L19.0918 3.86351L19.0918 5.13631L6.89084 5.13637Z" fill="white" fill-opacity="0.3"/>
<path id="Vector_2" d="M1.27246 0.0904379L1.27246 9L-0.000335336 9L-0.000334557 0.0904378L1.27246 0.0904379Z" fill="white" fill-opacity="0.65"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 503 B

5
hx-op/src/icon/userName.svg

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="12" fill-opacity="0.1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.3936 10.8691C12.0322 11.4221 10.4652 11.1164 9.42323 10.0946C8.56315 9.25057 8.18933 8.04123 8.42675 6.87091C8.66417 5.70058 9.48151 4.72368 10.6055 4.26681C11.4814 3.91106 12.518 3.91106 13.3939 4.26681C14.7552 4.81996 15.6428 6.12287 15.6427 7.56804C15.6427 9.01321 14.755 10.3161 13.3936 10.8691ZM9.08048 11.9575H14.9191H14.9193C16.6182 11.9575 18 13.3128 18 14.9788C18 16.6448 16.618 18 14.9193 18H9.08048C7.38197 18 6 16.6448 6 14.9788C6 13.3128 7.38176 11.9575 9.08048 11.9575Z" />
</svg>

After

Width:  |  Height:  |  Size: 686 B

18
hx-op/src/main.ts

@ -0,0 +1,18 @@
import { createApp } from 'vue';
import App from '/@/App.vue';
import { saasInit } from '/nerv-lib/saas';
import { apiModule } from '/@/api';
import { appConfig } from '/@/config';
import './theme/global.less';
import { LeftOutlined } from '@ant-design/icons-vue';
// import ElementPlus from 'element-plus'
// import 'element-plus/dist/index.css'
const app = createApp(App);
app.component('LeftOutlined', LeftOutlined);
saasInit({
app,
apiModule,
appConfig,
});
// app.use(ElementPlus)
app.mount('#app');

29
hx-op/src/router/home.ts

@ -0,0 +1,29 @@
const Base = () => import('/nerv-lib/saas/view/system/layout/content.vue');
const home = {
path: '/home',
name: 'home',
meta: { title: '首页', icon: 'dicizhishou', index: 0, hideChildren: true },
redirect: { name: 'homeIndex' },
children: [
{
path: 'homeModule',
name: 'HomeModule',
meta: { title: '首页', hideChildren: true, icon: 'dicizhishou' },
component: Base,
redirect: { name: 'homeIndex' },
children: [
{
path: 'index',
name: 'homeIndex',
component: () => import('/@/view/developing.vue'),
meta: {
title: '首页',
keepAlive: true,
// backApi: [],
},
},
],
},
],
};
export default home;

11
hx-op/src/router/index.ts

@ -0,0 +1,11 @@
/** @format */
const RootRoute = {
path: '/',
name: 'root',
redirect: { name: 'home' },
meta: {
title: 'Root',
},
};
export default RootRoute;

29
hx-op/src/router/organizationManage.ts

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

12
hx-op/src/store/item.ts

@ -0,0 +1,12 @@
import { defineStore } from 'pinia';
export const items = defineStore({
id: 'items',
state() {
return { list: [], count: 10 };
},
getters: {
double: (state: any) => state.count * 2,
},
actions: {},
});

151
hx-op/src/theme/detail.less

@ -0,0 +1,151 @@
.ns-view {
min-height: 100%;
height: 100%;
background: #e5ebf0;
}
.ns-detail-content {
border-top: 16px solid #e5ebf0;
padding: 16px 21px;
background: #fff;
height: calc(100% - 50px);
}
:deep(.ant-skeleton-paragraph) {
display: flex;
flex-wrap: wrap;
}
:deep(.ant-skeleton-paragraph li:nth-child(n)) {
display: block;
margin-right: 4%;
margin-top: 16px;
margin-bottom: 4px;
}
:deep(.ant-skeleton-paragraph li:nth-child(3n + 3)) {
margin-right: 0;
}
:deep(.ant-skeleton-content) {
padding: 0 8px 10px 10px;
}
:deep(.ant-descriptions-item-label) {
color: rgba(0, 0, 0, 0.5);
}
:deep(.ant-descriptions-item-label),
:deep(.ant-descriptions-item-content) {
line-height: 22px;
}
:deep(.ant-descriptions-view) {
padding-bottom: 8px;
}
:deep(.ant-descriptions-item) {
padding-right: 20px;
&:nth-child(2n) {
padding-left: 20px;
}
&:nth-child(3n) {
padding-left: 20px;
padding-right: 0;
}
}
.descriptions-title {
&:after {
content: '';
width: 75px;
height: 7px;
display: block;
background: linear-gradient(90deg, #537fff 0%, #fff 82.67%);
margin-left: 2px;
margin-top: -2px;
}
}
.ns-page-header {
margin-bottom: 0 !important;
padding-top: 7px !important;
padding-bottom: 7px !important;
width: calc(100% + 32px);
margin-left: -16px;
.title {
cursor: pointer;
font-size: 18px !important;
}
}
.ns-detail {
border-bottom: 1px solid #ecedef;
&:last-child {
border-bottom-width: 0;
}
&:first-child {
:deep(.ant-descriptions-header) {
margin-top: 0;
}
}
:deep(.ant-descriptions-header) {
margin-top: 12px;
margin-bottom: 12px;
.ant-descriptions-title {
line-height: 16px;
font-size: 16px;
}
}
}
:deep(.ant-image) {
width: 64px;
height: 64px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.ns-detail-html {
:deep(table) {
border-top: 1px solid #ffffff;
border-left: 1px solid #ffffff;
:deep(p) {
font-size: 12px;
color: #898e91;
}
}
:deep(th) {
border-right: 1px solid #ffffff;
font-size: 13px;
padding-top: 5px;
padding-bottom: 5px;
font-weight: normal;
background: #eff0f2;
}
:deep(td) {
border-top: 1px solid #ffffff;
border-right: 1px solid #ffffff;
padding-top: 5px;
padding-bottom: 5px;
font-size: 12px;
color: #606060;
text-align: center;
:deep(text) {
border-bottom: 1px solid #ffffff;
}
background: rgba(240, 242, 245, 0.5);
}
}

72
hx-op/src/theme/form.less

@ -0,0 +1,72 @@
.ns-view {
min-height: 100%;
height: 100%;
background: #e5ebf0;
}
.ns-page-header {
margin-bottom: 0 !important;
padding: 7px 16px !important;
width: calc(100% + 32px);
margin-left: -16px;
.title {
cursor: pointer;
font-size: 18px !important;
display: flex;
align-items: center;
.text {
margin-left: 6px;
}
}
}
:deep(.ant-spin-nested-loading) {
min-height: 100%;
height: 100%;
}
:deep(.ant-spin-container) {
min-height: 100%;
height: 100%;
}
:deep(.ant-divider) {
display: none;
}
.ns-add-form {
border-top: 16px solid #e5ebf0;
padding: 16px 21px;
background: #fff;
height: calc(100% - 47px) !important;
.ns-form {
// 第一个子表单Title距离顶部为0
:deep(.ns-form-item .ns-form-body .ns-child-form-title) {
padding-top: 0;
}
&:after {
display: none !important;
}
}
:deep(.ns-child-form-title) {
&:after {
content: '';
width: 75px;
height: 7px;
display: block;
background: linear-gradient(90deg, #537fff 0%, #fff 82.67%);
margin-left: 2px;
margin-top: -7px;
}
}
}
:deep(.ns-form.ns-vertical-form) {
padding-top: 16px !important;
}

183
hx-op/src/theme/global.less

@ -0,0 +1,183 @@
//侧边导航
// .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
// background: rgb(229, 247, 249) !important;
// }
// .ant-menu.ant-menu-dark .ant-menu-item-selected {
// color: #fff;
// background: #43BB79 !important;
// }
// .ant-menu-dark.ant-menu-horizontal>.ant-menu-item:hover {
// background-color: #43BB79 !important;
// }
.ant-menu-inline .ant-menu-item,
.ant-menu-inline .ant-menu-submenu-title {
width: 100% !important;
}
.ns-basic-table .ant-btn:hover {
border-color: transparent !important;
}
.ns-basic-table .ant-btn-link:hover {
background: none !important;
}
// .ns-detail {
// padding: 0px 24px 10px 24px !important;
// }
.ant-tabs-nav-wrap {
padding: 0 24px; // 列表tab边距
}
.ant-tabs-nav {
margin: 0 !important; // 列表tab下边距
}
.ns-richText-ZIndex {
z-index: 1;
}
.ant-input-number {
width: 100%; //inputNumber组件宽度
}
// header菜单字体样式
.ant-menu-dark.ant-menu-horizontal>.ant-menu-item,
.ant-menu-dark.ant-menu-horizontal>.ant-menu-submenu {
color: #fff;
}
.ant-menu-dark .ant-menu-item,
.ant-menu-dark .ant-menu-item-group-title,
.ant-menu-dark .ant-menu-item>a,
.ant-menu-dark .ant-menu-item>span>a {
color: #fff;
}
@font-face {
/*给字体命名*/
font-family: 'YouSheBiaoTiHei';
/*引入字体文件*/
src: url('/font/YouSheBiaoTiHei.ttf');
font-weight: normal;
font-style: normal;
}
@font-face {
/*给字体命名*/
font-family: 'DIN Alternate';
/*引入字体文件*/
src: url('/font/DIN Alternate Bold.ttf');
font-weight: normal;
font-style: normal;
}
@font-face {
/*给字体命名*/
font-family: 'PingFang Regular';
/*引入字体文件*/
src: url('/font/PingFang Regular.ttf');
font-weight: normal;
font-style: normal;
}
@font-face {
/*给字体命名*/
font-family: 'HYYakuHei';
/*引入字体文件*/
src: url('/font/HYYakuHei-85W.ttf');
font-weight: normal;
font-style: normal;
}
// .ant-popover-message {
// width: 250px !important;
// height: 198px !important;
// overflow: auto !important;
// position: relative;
// padding: 0;
// color: rgba(0, 0, 0, 0.85);
// font-size: 14px;
// }
// .ant-popover-inner-content {
// /* padding: 12px 16px; */
// padding: 0;
// color: rgba(0, 0, 0, 0.85);
// }
.ant-menu-title-content {
svg {
color: #A1ABC2;
}
}
.ant-menu-item-selected {
svg {
color: #D0DBF5;
}
}
//状态颜色
.commonStatus {
&::before{
content: '';
width: 8px;
height: 8px;
display: inline-block;
border-radius: 50%;
vertical-align: middle;
margin-right: 4px;
}
}
.statusWarn {
&::before{
background-color: #fa8214;
}
}
.statusSuccess {
&::before{
background-color: #0D9E3E;
}
}
.statusRunning {
&::before{
background-color: #1C4DDC;
}
}
.statusError {
&::before{
background-color: #D4321C;
}
}
.statusEmpty {
&::before{
width:0;
}
width:0;
}
.statusNotStart {
&::before{
background-color: #8B98AB;
}
}
.statusDone{
&::before{
background-color: #697383;
}
}
.statusInvalid{
&::before{
background-color: #AEAEAE;
}
}

73
hx-op/src/theme/global.scss

@ -0,0 +1,73 @@
@font-face {
font-family: 'QuartzMS';
src: url('/asset/font/QuartzMS.TTF') format('truetype');
}
@font-face {
font-family: 'FZDeSHJW_511M';
src: url('/asset/font/FZDeSHJW_511M.TTF') format('truetype');
}
@font-face {
font-family: 'Fzltth_SC';
src: url('/asset/font/Fzltth_SC.otf') format('truetype');
}
//侧边导航
// .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
// background: rgb(229, 247, 249) !important;
// }
.ant-menu-inline .ant-menu-item,
.ant-menu-inline .ant-menu-submenu-title {
width: 100% !important;
}
.ns-basic-table .ant-btn:hover {
border-color: transparent !important;
}
.ns-basic-table .ant-btn-link:hover {
background: none !important;
}
// .ns-detail {
// padding: 0px 24px 10px 24px !important;
// }
.ant-tabs-nav-wrap {
padding: 0 24px; // 列表tab边距
}
.ant-tabs-nav {
margin: 0 !important; // 列表tab下边距
}
.ns-richText-ZIndex {
z-index: 1;
}
.ant-input-number {
width: 100%; //inputNumber组件宽度
}
// header菜单字体样式
.ant-menu-dark.ant-menu-horizontal>.ant-menu-item,
.ant-menu-dark.ant-menu-horizontal>.ant-menu-submenu {
color: #fff;
}
.ant-menu-dark .ant-menu-item,
.ant-menu-dark .ant-menu-item-group-title,
.ant-menu-dark .ant-menu-item>a,
.ant-menu-dark .ant-menu-item>span>a {
color: #fff;
}
.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item:hover::after, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu:hover::after, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-active::after, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-active::after, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-open::after, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-open::after, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item-selected::after, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected::after {
border-bottom: unset !important;
}
.ant-menu-horizontal{
border-bottom: unset !important;
}

2
hx-op/src/theme/theme.scss

@ -0,0 +1,2 @@
@import "variable";
@import "global";

36
hx-op/src/theme/variable.less

@ -0,0 +1,36 @@
// @import "./global-antd.less";
@primary-color: #ff7602; // 全局主色
@layout-header-hover: #924908; //hover
@layout-header-background: #111519; // 头部背景色
// @layout-header-background:url(/asset/image/header_background.png) no-repeat;
// @ant-layout-sider-collapsed-background:url(/asset/image/sider_collapsed_background.png) no-repeat;
//btn
// @btn-height-base: 30px;
// @btn-height-lg: 30px;
// @btn-disable-bg: #dfe3e9; //禁用按钮background
// @btn-disable-border: 1px solid #ced0da;
// @btn-link-hover-bg: #37ABC4;
// @btn-text-hover-bg: #46ebdb;
// //input
// @input-height-base: 30px;
// //form
// @label-color: #52616f; //form-lable颜色
// @form-item-margin-bottom: 16px;
// //menu
//spin
// @border-width-base: 1px;
// @border-style-base: solid;

1
hx-op/src/types.d.ts

@ -0,0 +1 @@
declare module '*.vue';

21
hx-op/src/util/debounce.ts

@ -0,0 +1,21 @@
export function debounce(_this: any, fn: (arg0: any) => void) {
// 用rAF去做防抖
return function (...args: any) {
if (_this.lock) return;
const run = function () {
// requestIdleCallback-任务调度
window.requestIdleCallback(function (deadline) {
_this.lock = true;
// 判断空闲时间
// 显示器刷新频率HZ 16.7ms内不会重复执行
if (deadline.timeRemaining() > 1000 / 60) {
fn(...args);
_this.lock = false;
} else {
run();
}
});
};
run();
};
}

17
hx-op/src/view/developing.vue

@ -0,0 +1,17 @@
<template>
<div class="content">{{ content }}</div>
</template>
<script lang="ts" setup>
import { useRouter } from 'vue-router';
console.log(useRouter().currentRoute.value.meta);
const content = useRouter().currentRoute.value.meta.title + 'developing';
</script>
<style scoped lang="less">
.content {
font-size: 30px;
display: flex;
align-items: center;
justify-content: center;
}
</style>

74
hx-op/src/view/organizationManage/enterpriseManage/TreeAdd.vue

@ -0,0 +1,74 @@
<template>
<a-modal title="企业信息" :width="600" v-model:visible="visible" @ok="handleOk">
<ns-form ref="formRef" :schemas="formSchema" :model="formData" formLayout="vertical" />
</a-modal>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue';
export default defineComponent({
name: 'AddBorderVisible',
setup() {
let formData = ref({});
const formRef = ref();
const visible = ref(false);
const toggle = () => {
visible.value = !visible.value;
};
const formSchema = reactive([
{
field: 'name',
label: '企业名称',
component: 'NsInput',
componentProps: {
placeholder: '请输入企业名称',
maxLength: 20,
},
rules: [
{
required: true,
message: '请输入企业名称',
trigger: 'blur',
},
],
},
{
field: 'Isshare',
label: '点位数据',
component: 'NsRadioGroup',
componentProps: {
radioType: 'radio',
options: [
{ label: '分享', value: 1 },
{ label: '不分享', value: 2 },
],
},
rules: [
{
required: true,
message: '请选择是否分享',
type: 'number',
trigger: 'blur',
},
],
},
]);
const handleOk = () => {
formRef.value?.triggerSubmit().then(() => {
toggle();
});
};
return { handleOk, formData, formSchema, visible, toggle, formRef };
},
});
</script>
<style lang="less" scoped>
// :deep(.ns-child-form) {
// width: 1100px !important;
// justify-content: flex-start !important;
// }
// :deep(.ant-input-group-addon) {
// border: 0px solid #dcdfe2 !important;
// }
</style>

335
hx-op/src/view/organizationManage/enterpriseManage/config.ts

@ -0,0 +1,335 @@
import { mockData } from './mock';
import { cloneDeep } from 'lodash-es';
import { Modal } from 'ant-design-vue';
import { createVNode, ref } from 'vue';
import { NsMessage } from '/nerv-lib/component';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { enterPrise } from '/@/api/origanizemanage';
export const formConfig = [
{
field: 'zuzhi',
label: '组织ID',
component: 'NsInput',
componentProps: {
placeholder: '请输入组织ID',
},
rules: [
{
required: true,
message: '请输入组织编号',
trigger: 'blur',
},
],
},
{
field: 'jituanname',
label: '企业名称',
component: 'NsInput',
componentProps: {
placeholder: '请输入企业名称',
maxLength: 20,
},
rules: [
{
required: true,
message: '请输入企业名称',
trigger: 'blur',
},
],
},
{
field: 'jituanname',
label: '集团名称',
component: 'NsInput',
componentProps: {
placeholder: '请输入集团名称',
maxLength: 20,
},
},
{
field: 'cityName',
label: '省市区',
component: 'NsInputCity',
defaultValue: '',
fieldMap: ['provinceName', 'cityName', 'areaName', 'province', 'city', 'area'],
componentProps: {
placeholder: '请选择',
api: '/api/parking_merchant/objs/BaseArea',
isSeparate: true,
},
rules: [
{
required: true,
message: '请选择区域',
trigger: 'blur',
},
],
},
{
field: 'address',
label: '地址',
component: 'NsInput',
componentProps: {
placeholder: '请输入地址',
maxLength: 50,
},
},
{
field: 'person',
label: '联系人',
component: 'NsInput',
componentProps: {
placeholder: '请输入联系人',
maxLength: 10,
},
rules: [
{
required: true,
message: '请输入联系人',
trigger: 'blur',
},
],
},
{
field: 'phone',
label: '联系电话',
component: 'NsInput',
componentProps: {
placeholder: '请输入联系电话',
maxLength: 11,
},
rules: [
{
required: true,
message: '请输入联系电话',
trigger: 'blur',
},
],
},
];
export const tableConfig = (visible) => {
return {
// title: '企业管理',
api: enterPrise.list,
headerActions: [
{
label: '新增',
name: 'RoleTypeAdd',
type: 'primary',
handle: () => {
opMap.type = 'add';
opMap.fuc = (formData: any) => {
console.log(formData, 'formData');
mockData.value.push({
id: Math.random().toString().slice(2, 6),
...cloneDeep(formData),
});
};
visible.value = true;
},
},
],
rowSelection: null,
columns: [
{
title: '序号',
dataIndex: 'address',
width: 80,
customRender: (text: any) => {
return text.index + 1;
},
},
{
title: '组织ID',
dataIndex: 'orgCode',
},
{
title: '集团名称',
dataIndex: 'intro',
},
{
title: '组织名称',
dataIndex: 'orgName',
},
{
title: '状态',
dataIndex: 'status',
},
{
title: '省市区',
dataIndex: 'area',
customRender: ({ record }) => {
const { province = '', city = '', county = '' } = record;
return `${province}/${city}/${county}`;
},
},
{
title: '地址',
dataIndex: 'address',
},
{
title: '联系人',
dataIndex: 'person',
},
{
title: '联系电话',
dataIndex: 'phone',
},
],
columnActions: {
title: '操作',
actions: [
{
label: '编辑',
name: 'RoleTypeEdit',
handle: (record: any) => {
console.log(record, 'record');
formData.value = record;
opMap.type = 'edit';
opMap.fuc = (formData: any) => {
Object.assign(mockData.value.filter((item) => item.id === record.id)[0], formData);
};
visible.value = true;
},
},
{
label: '组织边界',
handle: (record: any) => {
console.log(record, 'record');
borderVisible.value = true;
},
},
{
label: '服务',
handle: (record: any) => {
console.log(record, 'record');
serviceVisible.value = true;
},
},
{
label: '冻结',
name: 'RoleTypeEdit',
handle: (record: any) => {
console.log(record, 'record');
Modal.confirm({
title: '是否冻结该账户',
icon: createVNode(ExclamationCircleOutlined),
content: createVNode('div', { style: 'color:red;' }, ''),
onOk() {
NsMessage.success('冻结成功');
},
class: 'test',
});
},
},
{
label: '重置密码',
name: 'RoleTypeEdit',
handle: (record: any) => {
console.log(record, 'record');
Modal.confirm({
title: '重置密码',
icon: createVNode(ExclamationCircleOutlined),
okText: '重置',
content: h('div', {}, [
h('p', `企业名称: ${record.jituanname}`),
h('p', '管理员账号: hxdtadmin'),
]),
onOk() {
Modal.confirm({
icon: createVNode(ExclamationCircleOutlined),
content: '是否确认重置该企业管理员密码',
onOk() {
Modal.success({
okText: '确认',
content: h('div', {}, [
h('p', '重置成功'),
h('p', '点击【确认】后自动复制密码并离开'),
]),
});
},
});
},
onCancel() {
console.log('Cancel');
},
class: 'test',
});
},
},
{
label: '删除',
name: 'RoleTypeEdit',
dynamicParams: 'orgId',
confirm: true,
isReload: true,
api: enterPrise.del,
},
],
},
formConfig: {
schemas: [
{
field: 'zuzhibianhao',
label: '组织ID',
component: 'NsInput',
componentProps: {
maxLength: 20,
},
},
{
field: 'jituanname',
label: '集团名称',
component: 'NsInput',
componentProps: {
maxLength: 20,
},
},
{
field: 'zuzhiname',
label: '组织名称',
component: 'NsInput',
componentProps: {
maxLength: 20,
},
},
{
field: 'status',
label: '状态',
component: 'NsSelect',
componentProps: {
options: [
{
label: '正常',
value: 1,
},
{
label: '冻结',
value: 2,
},
],
},
},
{
field: 'cityName',
label: '城市地区',
component: 'NsInputCity',
defaultValue: '',
fieldMap: ['provinceName', 'cityName', 'areaName', 'province', 'city', 'area'],
componentProps: {
api: '/api/parking_merchant/objs/BaseArea',
isSeparate: true,
},
},
],
params: {},
},
// pagination: { defaultPageSize: 10 },
rowKey: 'id',
};
};

175
hx-op/src/view/organizationManage/enterpriseManage/index.vue

@ -0,0 +1,175 @@
<!-- @format -->
<template>
<ns-view-list-table v-bind="tableConfig" :model="data" ref="mainRef" rowKey="uuid" />
<a-drawer
:width="600"
:visible="visible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<ns-form ref="formRef" :schemas="formSchema" :model="formData" formLayout="vertical" />
<template #footer>
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
<a-button type="primary" @click="onEdit">确定</a-button>
</template>
</a-drawer>
<a-drawer
:width="600"
:visible="borderVisible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<a-button type="primary" @click="borderAdd">新增</a-button>
<a-button type="primary" style="margin-left: 10px; margin-bottom: 10px" @click="borderAddSon"
>新增子集</a-button
>
<a-directory-tree @select="handleSelect" multiple :tree-data="treeData">
<template #title="{ title, key }">
{{ title }}
<a-button type="link" @click="editTree(title, key)">编辑</a-button>
<a-button type="link" danger @click="deleteTree(title, key)">删除</a-button>
</template>
</a-directory-tree>
</a-drawer>
<a-drawer
:width="600"
:visible="serviceVisible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<a-input-search
placeholder="请选择开通模块"
v-model:value="searchValue"
style="margin-bottom: 8px"
@search="onSearch" />
<a-tree
:tree-data="treeData"
v-model:checkedKeys="checkedKeys"
checkable
@select="ServiceSelect">
<template #title="{ title }">
{{ title }}
</template>
</a-tree>
<ns-button style="margin: 20px" type="primary" @click="onClose">取消</ns-button>
<ns-button type="primary" @click="Sure">确定</ns-button>
</a-drawer>
<TreeAdd ref="treeAdd" />
</template>
<script lang="ts" setup>
import { Modal } from 'ant-design-vue';
import { computed, createVNode, defineComponent, reactive, ref, watch } from 'vue';
import { http } from '/nerv-lib/util/http';
import { cloneDeep } from 'lodash-es';
import TreeAdd from './TreeAdd.vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { h } from 'vue';
import { formConfig } from './config';
import { NsMessage } from '/nerv-lib/component';
import { mockData, treeData } from './mock';
import { enterPrise } from '/@/api/origanizemanage';
import { tableConfig as insertConfig } from './config';
defineOptions({
name: 'EnterpriseManageIndex',
});
const data = reactive({});
const treeAdd = ref();
const mainRef = ref();
let formData = ref({});
const formRef = ref();
const searchValue = ref<string>('');
const checkedKeys = ref<string[]>([]);
const visible = ref(false);
const borderVisible = ref(false);
const serviceVisible = ref(false);
const treeAddVisible = ref(false);
const formSchema = formConfig;
const tableConfig = computed(() => {
return insertConfig(visible);
});
const opMap: any = {
type: 'add',
fuc: () => {},
record: {},
};
watch(checkedKeys, () => {
console.log('checkedKeys', checkedKeys.value);
});
const handleSelect = (selectedKeys: any, info: any) => {
console.log(selectedKeys, 'selectedKeys');
console.log(info, 'info');
};
const ServiceSelect = (selectedKeys: any, info: any) => {
console.log(selectedKeys, 'selectedKeys');
console.log(info, 'info');
};
const onClose = () => {
visible.value = false;
borderVisible.value = false;
serviceVisible.value = false;
};
const borderAdd = () => {
treeAddVisible.value = true;
treeAdd.value?.toggle();
};
const borderAddSon = () => {
treeAddVisible.value = true;
};
const onEdit = () => {
formRef.value?.triggerSubmit().then(() => {
console.log(formData.value, 'formData.value');
opMap.fuc && opMap.fuc(formData.value);
visible.value = false;
});
};
const Sure = () => {
serviceVisible.value = false;
};
const editTree = (title: any, key: any) => {
console.log(title, 'title');
console.log(key, 'key');
};
const deleteTree = (title: any, key: any) => {
console.log(title, 'title');
console.log(key, 'key');
Modal.confirm({
title: '是否确定删除',
icon: createVNode(ExclamationCircleOutlined),
content: createVNode('div', { style: 'color:red;' }, ''),
onOk() {
// http
// .post('/api/parking_merchant/objs/gateInfo/delete', {
// uuid: record.uuid,
// })
// .then((res) => {
// mainRef.value.nsTableRef.reload();
// });
},
onCancel() {
console.log('Cancel');
},
class: 'test',
});
};
const onSearch = () => {
console.log(searchValue.value);
};
</script>

43
hx-op/src/view/organizationManage/enterpriseManage/mock.ts

@ -0,0 +1,43 @@
import { ref } from 'vue';
export const mockData = ref([
{
id: 3,
zuzhi: '22',
jituanname: 'axb',
zuzhiname: '张三',
status: '男',
area: '123456789',
address: '1234567889',
person: '1',
phone: '1',
},
]);
export const mockData2 = ref([
{
information: '铁路局1/产品部1/产品总监1',
},
]);
export const treeData = ref([
{
title: '铁路总局',
key: '0-0',
children: [
{ title: '济阳站', key: '0-0-0' },
{ title: '临沂站', key: '0-0-1' },
],
},
]);
export const treeData2 = [
{
title: '全部',
key: '0-0',
children: [
{ title: '产品部', key: '0-0-0' },
{ title: '运维部', key: '0-0-1' },
],
},
];

51
hx-op/tsconfig.json

@ -0,0 +1,51 @@
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"jsx": "preserve",
"lib": ["esnext", "dom"],
"module": "esnext",
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
"paths": {
"/@/*": [
"src/*"
],
"/nerv-lib/*": [
"../lib/*"
],
"/nerv-base/*": [
"../lib/saas/*"
],
"/type/*": [
"../type/*"
]
},
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictFunctionTypes": false,
"target": "esnext",
"typeRoots": [
"../node_modules/@types",
"../node_modules/@vue",
"../type"
],
"types": ["vite/client"]
},
"include": [
"src/**/*",
"type/**/*",
"mock/**/*",
"vite.config.ts"
],
"exclude": [
"node_modules",
"dist",
"**/*.js"
]
}

20
hx-op/vite.config.ts

@ -0,0 +1,20 @@
import configFun from '../build/vite-default.config';
const dirname = __dirname;
const proxy = {
'/qa': {
target: 'http://100.86.13.179:8080/qa',
// target: 'http://100.86.13.206:8081/qa',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/qa/, ''),
},
'/carbon_emission': {
target: 'http://140.210.143.1:14492',
changeOrigin: true,
},
'/carbon-smart': {
target: 'http://192.168.112.144:8224',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/carbon-smart/, ''),
},
};
export default configFun({ dirname, proxy, serviceMode: 'saas', baseDir: '../' });

35
lib/component/form/cascader/cascader.vue

@ -1,17 +1,46 @@
<template>
<a-cascader :load-data="loadData" :options="options" change-on-select>
<a-cascader :load-data="loadData" :options="options">
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
<slot :name="item" v-bind="data || {}"> </slot>
</template>
</a-cascader>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { defineComponent, ref, toRefs } from 'vue';
import type { CascaderProps } from 'ant-design-vue';
import { http } from '/nerv-lib/util';
import { AxiosRequestConfig } from 'axios';
import { useApi } from '/nerv-lib/use';
import { get } from 'lodash-es';
const { httpRequest } = useApi();
export default defineComponent({
name: 'NsCascader',
props: {
api: [Function, String, Object],
options: Array,
listField: {
type: String,
default: 'data',
},
defaultParams: Object,
},
setup(props, { attrs }) {
let options = ref<any[]>(attrs['options'] || []);
console.log(props, attrs);
const requestConfig: AxiosRequestConfig = { method: 'get' };
let options = ref<any[]>(props['options'] || []);
if (props.api) {
// eslint-disable-next-line vue/no-setup-props-destructure
const { api, defaultParams, listField } = props;
httpRequest({
api,
params: defaultParams,
pathParams: {},
requestConfig,
}).then((res) => {
options.value = get(res, listField);
});
}
let loadData: CascaderProps['loadData'] | null = (selectOptions) => {
attrs['loadData'](selectOptions, options, attrs);
};

9
lib/component/table/table.vue

@ -353,7 +353,7 @@
}
const tableChangeEvent = (pagination: Props, filters: [], sorter: any) => {
// console.log('params', pagination, filters, sorter);
console.log('params', pagination, filters, sorter);
if (sorter?.field) {
if (sorter.order) {
orderRef.value = {
@ -383,7 +383,7 @@
if (pagination) {
const current = get(dataRef.value, props.pageField);
console.log(current);
function getTotal() {
let total = 0;
if (isFunction(getPageParams)) {
@ -393,7 +393,6 @@
}
return total;
}
console.log('current', (current >= 0 ? current : 0) + props.pageFieldOffset);
return {
showQuickJumper: true,
@ -406,13 +405,15 @@
},
...(pagination as Props),
total: getTotal(),
current: (current >= 0 ? current : 0) + props.pageFieldOffset, // 1
current: (current >= 0 ? current : 1) + props.pageFieldOffset, // 1
pageSize: get(dataRef.value, props.sizeField),
};
}
return false;
});
console.log(getPagination.value);
const getTableBindValues = computed(() => {
const { params, dynamicParams } = props;
return {

2
lib/saas/config/table.config.ts

@ -1,5 +1,5 @@
export const tableConfig = {
pageField: 'data.pages', //当前页
pageField: 'data.current', //当前页
pageCount: 'data.pageCount', //当前页
sizeField: 'data.size', // 每页数量
listField: 'data.records', // 数据集合

14
lib/saas/store/modules/app-config.ts

@ -108,18 +108,10 @@ export const appConfigStore = defineStore({
},
userLogin(data: loginData) {
if (this.userLoginApi) {
return httpRequest({ api: this.userLoginApi, params: data, pathParams: {}, requestConfig });
console.log(data);
// return httpRequest({ api: this.userLoginApi, params: data, pathParams: {}, requestConfig });
// return http.post(this.userLoginApi, data, {
// transformRequest: [
// (mode, headers) => {
// if (headers.qsToken) {
// delete headers.qsToken;
// }
// return JSON.stringify(mode);
// },
// ],
// });
return http.post(this.userLoginApi, data);
} else {
return null;
}

2
lib/saas/view/system/layout/header.vue

@ -10,7 +10,7 @@
<ns-icon v-else name="headerLogin" class="headerLogin" style="width: auto; height: 48px" />
</div>
<div>
<component :is="headerSlot.component" v-bind="headerSlot.componentProps" />
<component v-if="headerSlot" :is="headerSlot.component" v-bind="headerSlot.componentProps" />
</div>
<div class="header-menu">
<a-menu style="width: 100%" mode="horizontal" :selectedKeys="initHeaderKey">

3
lib/util/http/axios.ts

@ -87,7 +87,8 @@ export class NSAxios {
// config.url = newUrl;
return config;
}, undefined);
const errCodeArr = [13, 1];
const errCodeArr = [13, 1, 3005];
// const newMap = new Map([])
this.instance.interceptors.response.use(
(res: AxiosResponse) => {
console.log('success', res);

2
package.json

@ -9,6 +9,8 @@
"start": "npm run dev",
"ai": "vite serve ./hx-ai-intelligent --config ./hx-ai-intelligent/vite.config.ts",
"ai-build": "cross-env NODE_ENV=production vite build ./hx-ai-intelligent --config ./hx-ai-intelligent/vite.config.ts",
"ai-op": "vite serve ./hx-op --config ./hx-op/vite.config.ts",
"ai-op-build": "cross-env NODE_ENV=production vite build ./hx-op --config ./hx-op/vite.config.ts",
"dev": "vite",
"lint:eslint-fix": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
"build": "cross-env NODE_ENV=production vite build ",

Loading…
Cancel
Save