Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev
This commit is contained in:
commit
76a880b130
|
@ -9,7 +9,7 @@ export const updateMeInfo_api = (data:object) => server.put(`/user/detail`,data)
|
||||||
// 修改登录用户密码
|
// 修改登录用户密码
|
||||||
export const updateMepsd_api = (data:object) => server.put(`/user/passwd`,data);
|
export const updateMepsd_api = (data:object) => server.put(`/user/passwd`,data);
|
||||||
// 第三方账号解绑
|
// 第三方账号解绑
|
||||||
export const unBind_api = (appId: string) => server.post(`/application/sso/${appId}/unbind/me`);
|
export const unBind_api = (appId: string) => server.post(`/application/sso/${appId}/unbind/me`, []);
|
||||||
/**
|
/**
|
||||||
* 校验字段合法性
|
* 校验字段合法性
|
||||||
* @param type 类型
|
* @param type 类型
|
||||||
|
|
|
@ -67,6 +67,14 @@
|
||||||
</j-upload>
|
</j-upload>
|
||||||
</template>
|
</template>
|
||||||
</j-input>
|
</j-input>
|
||||||
|
<j-input
|
||||||
|
v-else-if="typeMap.get(itemType) === 'password'"
|
||||||
|
allowClear
|
||||||
|
type="password"
|
||||||
|
v-model:value="myValue"
|
||||||
|
style="width: 100%"
|
||||||
|
@change='inputChange'
|
||||||
|
/>
|
||||||
<j-input
|
<j-input
|
||||||
v-else
|
v-else
|
||||||
allowClear
|
allowClear
|
||||||
|
@ -148,7 +156,7 @@ const componentsType = ref<ITypes>({
|
||||||
double: 'inputNumber',
|
double: 'inputNumber',
|
||||||
string: 'input',
|
string: 'input',
|
||||||
array: 'input',
|
array: 'input',
|
||||||
password: 'input',
|
password: 'password',
|
||||||
enum: 'select',
|
enum: 'select',
|
||||||
boolean: 'select',
|
boolean: 'select',
|
||||||
date: 'date',
|
date: 'date',
|
||||||
|
|
|
@ -2,6 +2,8 @@ export const LoginPath = '/login'
|
||||||
export const InitHomePath = '/init-home'
|
export const InitHomePath = '/init-home'
|
||||||
export const AccountCenterBindPath = '/account/center/bind'
|
export const AccountCenterBindPath = '/account/center/bind'
|
||||||
export const InitLicense = '/init-license'
|
export const InitLicense = '/init-license'
|
||||||
|
export const NotificationSubscriptionCode = 'account/NotificationSubscription'
|
||||||
|
export const NotificationRecordCode = 'account/NotificationRecord'
|
||||||
|
|
||||||
export const AccountMenu = {
|
export const AccountMenu = {
|
||||||
path: '/account',
|
path: '/account',
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { queryOwnThree } from '@/api/system/menu'
|
import { queryOwnThree } from '@/api/system/menu'
|
||||||
import { filterAsyncRouter, findCodeRoute, MenuItem } from '@/utils/menu'
|
import { filterAsyncRouter, findCodeRoute, MenuItem } from '@/utils/menu'
|
||||||
import { isArray } from 'lodash-es'
|
import { cloneDeep, isArray } from 'lodash-es'
|
||||||
import { usePermissionStore } from './permission'
|
import { usePermissionStore } from './permission'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { onlyMessage } from '@/utils/comm'
|
import { onlyMessage } from '@/utils/comm'
|
||||||
import { AccountMenu } from '@/router/menu'
|
import { AccountMenu, NotificationRecordCode, NotificationSubscriptionCode } from '@/router/menu'
|
||||||
|
import { MESSAGE_SUBSCRIBE_MENU_CODE, USER_CENTER_MENU_CODE } from '@/utils/consts'
|
||||||
|
|
||||||
const defaultOwnParams = [
|
const defaultOwnParams = [
|
||||||
{
|
{
|
||||||
|
@ -96,6 +97,13 @@ export const useMenuStore = defineStore({
|
||||||
const permission = usePermissionStore()
|
const permission = usePermissionStore()
|
||||||
permission.permissions = {}
|
permission.permissions = {}
|
||||||
const { menusData, silderMenus } = filterAsyncRouter(resp.result)
|
const { menusData, silderMenus } = filterAsyncRouter(resp.result)
|
||||||
|
|
||||||
|
// 是否存在通知订阅
|
||||||
|
const hasMessageSub = resp.result.some((item: { code: string }) => item.code === MESSAGE_SUBSCRIBE_MENU_CODE)
|
||||||
|
console.log('hasMessageSub', hasMessageSub)
|
||||||
|
if (!hasMessageSub) {
|
||||||
|
AccountMenu.children = AccountMenu.children.filter((item: { code: string }) => ![NotificationSubscriptionCode, NotificationRecordCode].includes(item.code) )
|
||||||
|
}
|
||||||
this.menus = findCodeRoute([...resp.result, AccountMenu])
|
this.menus = findCodeRoute([...resp.result, AccountMenu])
|
||||||
Object.keys(this.menus).forEach((item) => {
|
Object.keys(this.menus).forEach((item) => {
|
||||||
const _item = this.menus[item]
|
const _item = this.menus[item]
|
||||||
|
@ -112,7 +120,7 @@ export const useMenuStore = defineStore({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
menusData.push(AccountMenu)
|
menusData.push(AccountMenu)
|
||||||
this.siderMenus = silderMenus
|
this.siderMenus = silderMenus.filter((item: { name: string }) => ![USER_CENTER_MENU_CODE, MESSAGE_SUBSCRIBE_MENU_CODE].includes(item.name))
|
||||||
res(menusData)
|
res(menusData)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { MESSAGE_SUBSCRIBE_MENU_DATA } from '@/views/init-home/data/baseMenu'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态颜色
|
* 状态颜色
|
||||||
*/
|
*/
|
||||||
|
@ -47,3 +49,8 @@ export const SystemConst = {
|
||||||
VERSION_CODE: 'version_code',
|
VERSION_CODE: 'version_code',
|
||||||
AMAP_KEY : 'amap_key',
|
AMAP_KEY : 'amap_key',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const USER_CENTER_MENU_CODE = 'account-center'
|
||||||
|
export const USER_CENTER_MENU_BUTTON_CODE = 'user-center-passwd-update'
|
||||||
|
export const MESSAGE_SUBSCRIBE_MENU_CODE = 'message-subscribe'
|
||||||
|
export const MESSAGE_SUBSCRIBE_MENU_BUTTON_CODE = 'message-subscribe-view'
|
||||||
|
|
|
@ -330,11 +330,13 @@ const handleOk = async () => {
|
||||||
if (data?.configuration.function !== 'HoldingRegisters') {
|
if (data?.configuration.function !== 'HoldingRegisters') {
|
||||||
codec.provider = 'int8';
|
codec.provider = 'int8';
|
||||||
}
|
}
|
||||||
|
const { interval } = formData.value.configuration;
|
||||||
const params = {
|
const params = {
|
||||||
...props.data,
|
...props.data,
|
||||||
...data,
|
...data,
|
||||||
provider,
|
provider,
|
||||||
collectorId,
|
collectorId,
|
||||||
|
interval,
|
||||||
};
|
};
|
||||||
|
|
||||||
// address是多余字段,但是react版本上使用到了这个字段
|
// address是多余字段,但是react版本上使用到了这个字段
|
||||||
|
@ -413,23 +415,17 @@ const filterOption = (input: string, option: any) => {
|
||||||
const getProviderList = async () => {
|
const getProviderList = async () => {
|
||||||
const res: any = await queryCodecProvider();
|
const res: any = await queryCodecProvider();
|
||||||
providerListAll.value = res.result
|
providerListAll.value = res.result
|
||||||
.filter((i: any) => i.id !== 'property')
|
.filter((i: any) => i.id !== 'property' && i.id !== 'bool')
|
||||||
.map((item: any) => ({
|
.map((item: any) => ({
|
||||||
value: item.id,
|
value: item.id,
|
||||||
label: item.name,
|
label: item.name,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setProviderList(formData.value.configuration.function);
|
setProviderList(formData.value.configuration.function);
|
||||||
};
|
};
|
||||||
getProviderList();
|
getProviderList();
|
||||||
|
|
||||||
const setProviderList = (value: string | undefined) => {
|
const setProviderList = (value: string | undefined) => {
|
||||||
providerList.value =
|
providerList.value = providerListAll.value;
|
||||||
value === 'HoldingRegisters'
|
|
||||||
? providerListAll.value
|
|
||||||
: providerListAll.value.filter(
|
|
||||||
(item: any) => item.value !== 'bool',
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|
|
@ -132,11 +132,13 @@ const formData = ref({
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
const data = await formRef.value?.validate();
|
const data = await formRef.value?.validate();
|
||||||
|
const { interval } = formData.value.configuration;
|
||||||
const params = {
|
const params = {
|
||||||
...props.data,
|
...props.data,
|
||||||
...data,
|
...data,
|
||||||
provider,
|
provider,
|
||||||
collectorId,
|
collectorId,
|
||||||
|
interval,
|
||||||
};
|
};
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
|
@ -101,7 +101,7 @@ const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
accessModes: [],
|
accessModes: [],
|
||||||
interval: '',
|
interval: undefined,
|
||||||
features: [],
|
features: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -118,7 +118,10 @@ const handleOk = async () => {
|
||||||
const data = cloneDeep(formData.value);
|
const data = cloneDeep(formData.value);
|
||||||
const { accessModes, features, interval } = data;
|
const { accessModes, features, interval } = data;
|
||||||
const ischange =
|
const ischange =
|
||||||
accessModes.length !== 0 || features.length !== 0 || !!interval;
|
accessModes.length !== 0 ||
|
||||||
|
features.length !== 0 ||
|
||||||
|
Number(interval) === 0 ||
|
||||||
|
!!interval;
|
||||||
if (ischange) {
|
if (ischange) {
|
||||||
const params = cloneDeep(props.data);
|
const params = cloneDeep(props.data);
|
||||||
params.forEach((i: any) => {
|
params.forEach((i: any) => {
|
||||||
|
@ -132,7 +135,7 @@ const handleOk = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
features.length !== 0 && (i.features = data.features);
|
features.length !== 0 && (i.features = data.features);
|
||||||
if (!!interval) {
|
if (!!interval || Number(interval) === 0) {
|
||||||
i.interval = data.interval;
|
i.interval = data.interval;
|
||||||
i.configuration = {
|
i.configuration = {
|
||||||
...i.configuration,
|
...i.configuration,
|
||||||
|
|
|
@ -281,9 +281,14 @@
|
||||||
<span>{{
|
<span>{{
|
||||||
getText(slotProps)
|
getText(slotProps)
|
||||||
}}</span>
|
}}</span>
|
||||||
<span>{{
|
<span
|
||||||
|
v-if="
|
||||||
getInterval(slotProps)
|
getInterval(slotProps)
|
||||||
}}</span>
|
"
|
||||||
|
>{{
|
||||||
|
getInterval(slotProps)
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</Ellipsis>
|
</Ellipsis>
|
||||||
</div>
|
</div>
|
||||||
|
@ -334,7 +339,7 @@ import SaveModBus from './Save/SaveModBus.vue';
|
||||||
import SaveOPCUA from './Save/SaveOPCUA.vue';
|
import SaveOPCUA from './Save/SaveOPCUA.vue';
|
||||||
import Scan from './Scan/index.vue';
|
import Scan from './Scan/index.vue';
|
||||||
import { colorMap } from '../data.ts';
|
import { colorMap } from '../data.ts';
|
||||||
import { cloneDeep, isNumber } from 'lodash-es';
|
import { cloneDeep, isNumber, throttle } from 'lodash-es';
|
||||||
import { getWebSocket } from '@/utils/websocket';
|
import { getWebSocket } from '@/utils/websocket';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
@ -616,17 +621,6 @@ const handleClick = (dt: any) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//节流
|
|
||||||
let timer: any = null;
|
|
||||||
function throttle(fn: any, delay = 1000) {
|
|
||||||
if (timer == null) {
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
fn();
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = null;
|
|
||||||
}, delay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const subscribeProperty = (value: any) => {
|
const subscribeProperty = (value: any) => {
|
||||||
const list = value.map((item: any) => item.id);
|
const list = value.map((item: any) => item.id);
|
||||||
const id = `collector-${props.data?.channelId || 'channel'}-${
|
const id = `collector-${props.data?.channelId || 'channel'}-${
|
||||||
|
@ -643,7 +637,7 @@ const subscribeProperty = (value: any) => {
|
||||||
//防止刷新过快
|
//防止刷新过快
|
||||||
throttle(() => {
|
throttle(() => {
|
||||||
propertyValue.value.set(payload.pointId, payload);
|
propertyValue.value.set(payload.pointId, payload);
|
||||||
});
|
}, 1000);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -107,11 +107,7 @@
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<div style="color: #616161" v-if="visibleEndian">
|
<div style="color: #616161" v-if="visibleEndian">
|
||||||
<p>
|
<p>当前内存布局: {{ endianData }}</p>
|
||||||
当前内存布局:{{
|
|
||||||
endianMap.get(formData.configuration.endian)
|
|
||||||
}}{{ endianMap.get(formData.configuration.endianIn) }}
|
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
只有4字节数据类型(int32、ieee754 float)
|
只有4字节数据类型(int32、ieee754 float)
|
||||||
具有4种内存布局,其它只有ABCD、DCBA两种内存布局(以双字配置为准)
|
具有4种内存布局,其它只有ABCD、DCBA两种内存布局(以双字配置为准)
|
||||||
|
@ -182,10 +178,21 @@ const emit = defineEmits(['change']);
|
||||||
const id = props.data.id;
|
const id = props.data.id;
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
const endianMap = new Map([
|
|
||||||
['BIG', 'AB'],
|
const endianData = computed(() => {
|
||||||
['LITTLE', 'BA'],
|
const { endian, endianIn } = formData.value.configuration;
|
||||||
]);
|
if (endian) {
|
||||||
|
if (endianIn) {
|
||||||
|
if (endian === 'BIG') {
|
||||||
|
return endianIn === 'BIG' ? 'ABCD' : 'BADC';
|
||||||
|
} else {
|
||||||
|
return endianIn === 'BIG' ? 'CDBA' : 'DCBA';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return endian === 'BIG' ? 'ABCD' : 'DCBA';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
channelId: undefined,
|
channelId: undefined,
|
||||||
|
|
|
@ -310,6 +310,9 @@ watch(
|
||||||
:deep(.ant-tree-list-holder-inner) {
|
:deep(.ant-tree-list-holder-inner) {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
:deep(.ant-tree-list) {
|
||||||
|
width: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.ant-tree-treenode) {
|
:deep(.ant-tree-treenode) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card" v-if='updatePassword'>
|
||||||
<h3>修改密码</h3>
|
<h3>修改密码</h3>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="content" style="align-items: flex-end">
|
<div class="content" style="align-items: flex-end">
|
||||||
|
@ -245,7 +245,10 @@ import moment from 'moment';
|
||||||
import { getMe_api, getView_api, setView_api } from '@/api/home';
|
import { getMe_api, getView_api, setView_api } from '@/api/home';
|
||||||
import { isNoCommunity } from '@/utils/utils';
|
import { isNoCommunity } from '@/utils/utils';
|
||||||
import { userInfoType } from './typing';
|
import { userInfoType } from './typing';
|
||||||
|
import { usePermissionStore } from 'store/permission'
|
||||||
|
|
||||||
|
const btnHasPermission = usePermissionStore().hasPermission;
|
||||||
|
const updatePassword = btnHasPermission('account-center:user-center-passwd-update')
|
||||||
const permission = 'system/User';
|
const permission = 'system/User';
|
||||||
const userInfo = ref<userInfoType>({} as any);
|
const userInfo = ref<userInfoType>({} as any);
|
||||||
// 第三方账号
|
// 第三方账号
|
||||||
|
@ -361,7 +364,7 @@ function getViews() {
|
||||||
.then((resp: any) => {
|
.then((resp: any) => {
|
||||||
if (resp?.status === 200) {
|
if (resp?.status === 200) {
|
||||||
if (resp.result) currentView.value = resp.result?.content;
|
if (resp.result) currentView.value = resp.result?.content;
|
||||||
else if (resp.result.username === 'admin') {
|
else if (resp.result?.username === 'admin') {
|
||||||
currentView.value = 'comprehensive';
|
currentView.value = 'comprehensive';
|
||||||
} else currentView.value = 'init';
|
} else currentView.value = 'init';
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,10 @@ watch(
|
||||||
() => user.userInfos,
|
() => user.userInfos,
|
||||||
(val: any) => {
|
(val: any) => {
|
||||||
// 超管默认综合管理视图
|
// 超管默认综合管理视图
|
||||||
if (val.username === 'admin') selectValue.value = 'comprehensive';
|
if (val.username === 'admin') {
|
||||||
|
selectValue.value = 'comprehensive';
|
||||||
|
confirm();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { getImage } from '@/utils/comm';
|
import { getImage } from '@/utils/comm';
|
||||||
import BaseMenu from '../data/baseMenu';
|
import BaseMenu, { MESSAGE_SUBSCRIBE_MENU_DATA, USER_CENTER_MENU_DATA } from '../data/baseMenu'
|
||||||
import { getSystemPermission, updateMenus } from '@/api/initHome';
|
import { getSystemPermission, updateMenus } from '@/api/initHome';
|
||||||
/**
|
/**
|
||||||
* 获取菜单数据
|
* 获取菜单数据
|
||||||
|
@ -70,7 +70,8 @@ const menuCount = (menus: any[]) => {
|
||||||
*/
|
*/
|
||||||
const initMenu = async () => {
|
const initMenu = async () => {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
const res = await updateMenus(menuDatas.current);
|
// 用户中心
|
||||||
|
const res = await updateMenus([...menuDatas.current!, USER_CENTER_MENU_DATA, MESSAGE_SUBSCRIBE_MENU_DATA]);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,3 +1,55 @@
|
||||||
|
import {
|
||||||
|
MESSAGE_SUBSCRIBE_MENU_BUTTON_CODE,
|
||||||
|
MESSAGE_SUBSCRIBE_MENU_CODE,
|
||||||
|
USER_CENTER_MENU_BUTTON_CODE,
|
||||||
|
USER_CENTER_MENU_CODE
|
||||||
|
} from '@/utils/consts'
|
||||||
|
|
||||||
|
export const USER_CENTER_MENU_DATA = {
|
||||||
|
id: '19a1f2c763e1231f1e1',
|
||||||
|
accessSupport: { value: 'unsupported', label: '不支持'},
|
||||||
|
supportDataAccess: false,
|
||||||
|
code: USER_CENTER_MENU_CODE,
|
||||||
|
name: '个人中心',
|
||||||
|
url: '/user-center',
|
||||||
|
sortIndex: 9999,
|
||||||
|
granted: true,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
id: USER_CENTER_MENU_BUTTON_CODE,
|
||||||
|
name: '修改密码',
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
permission: 'user',
|
||||||
|
action: ['update-self-pwd']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MESSAGE_SUBSCRIBE_MENU_DATA = {
|
||||||
|
id: '23a1f2c7123e56731f890',
|
||||||
|
accessSupport: { value: 'unsupported', label: '不支持'},
|
||||||
|
supportDataAccess: false,
|
||||||
|
code: MESSAGE_SUBSCRIBE_MENU_CODE,
|
||||||
|
name: '通知订阅',
|
||||||
|
url: '/message-subscribe',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
id: MESSAGE_SUBSCRIBE_MENU_BUTTON_CODE,
|
||||||
|
name: '查看',
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
permission: 'alarm-config',
|
||||||
|
action: ['query']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
sortIndex: 9998
|
||||||
|
}
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
// 物联网
|
// 物联网
|
||||||
{
|
{
|
||||||
|
@ -4015,6 +4067,10 @@ export default [
|
||||||
permission: 'network-card',
|
permission: 'network-card',
|
||||||
actions: ['save'],
|
actions: ['save'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
permission: 'device-instance',
|
||||||
|
actions: ['query'],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4218,5 +4274,5 @@ export default [
|
||||||
supportDataAccess: false
|
supportDataAccess: false
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -134,18 +134,14 @@ const submitData = async () => {
|
||||||
* 判断是否已有配置
|
* 判断是否已有配置
|
||||||
*/
|
*/
|
||||||
const judgeInitSet = async () => {
|
const judgeInitSet = async () => {
|
||||||
if (userInfo.$state.userInfos.username === 'admin') {
|
|
||||||
const resp: any = await getInit();
|
const resp: any = await getInit();
|
||||||
if (resp.status === 200 && resp.result.length) {
|
if (resp.status === 200 && resp.result.length) {
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
window.location.href = '/';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onBeforeMount(() => {
|
||||||
judgeInitSet();
|
// judgeInitSet();
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.page-container {
|
.page-container {
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
import { queryPlatformNoPage, recharge } from '@/api/iot-card/cardManagement';
|
import { queryPlatformNoPage, recharge } from '@/api/iot-card/cardManagement';
|
||||||
import { message } from 'jetlinks-ui-components';
|
import { message } from 'jetlinks-ui-components';
|
||||||
import { PaymentMethod } from '@/views/iot-card/data';
|
import { PaymentMethod } from '@/views/iot-card/data';
|
||||||
|
import { onlyMessage } from '@/utils/comm'
|
||||||
|
|
||||||
const emit = defineEmits(['change', 'save']);
|
const emit = defineEmits(['change', 'save']);
|
||||||
|
|
||||||
|
@ -168,6 +169,8 @@ const handleOk = () => {
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
if (resp.result === '失败') {
|
if (resp.result === '失败') {
|
||||||
message.error('缴费失败')
|
message.error('缴费失败')
|
||||||
|
} else if(!resp.result) {
|
||||||
|
onlyMessage('操作过于频繁,请稍后再试!', 'warning')
|
||||||
} else {
|
} else {
|
||||||
window.open(resp.result);
|
window.open(resp.result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ const saveChange = (val: any) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
rechargeRef.value?.reload();
|
rechargeRef.value?.reload();
|
||||||
}, 500)
|
}, 700)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -654,7 +654,7 @@ const saveData = () => {
|
||||||
onlyMessage('操作成功', 'success');
|
onlyMessage('操作成功', 'success');
|
||||||
if (route.query.save) {
|
if (route.query.save) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window?.onTabSaveSuccess(resp.result);
|
window?.onTabSaveSuccess(resp);
|
||||||
window.close();
|
window.close();
|
||||||
} else {
|
} else {
|
||||||
history.back();
|
history.back();
|
||||||
|
|
|
@ -315,7 +315,7 @@ const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
|
||||||
text: '删除',
|
text: '删除',
|
||||||
disabled: state === 'enabled',
|
disabled: state === 'enabled',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
title: state === 'enabled' ? '已启用的设备不能删除' : '删除',
|
title: state === 'enabled' ? '请先禁用,再删除' : '删除',
|
||||||
},
|
},
|
||||||
popConfirm: {
|
popConfirm: {
|
||||||
title: '确认删除?',
|
title: '确认删除?',
|
||||||
|
|
|
@ -1365,11 +1365,23 @@ const getDetail = () => {
|
||||||
...cloneDeep(Configuration), //防止编辑时,表单字段不完善,导致输入/选择框新出现时找不到
|
...cloneDeep(Configuration), //防止编辑时,表单字段不完善,导致输入/选择框新出现时找不到
|
||||||
...configuration,
|
...configuration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const configRef = Store.get('configRef').filter(
|
||||||
|
(item: any) => item.host === '0.0.0.0',
|
||||||
|
);
|
||||||
|
getPortOptions(configRef); //更新端口
|
||||||
} else {
|
} else {
|
||||||
dynamicValidateForm.cluster = {
|
dynamicValidateForm.cluster = cluster;
|
||||||
...cloneDeep(FormStates2), //同上
|
//遍历数据更新对应的本地端口
|
||||||
...cluster,
|
setTimeout(() => {
|
||||||
};
|
cluster.forEach((item: any, index: number) => {
|
||||||
|
const { host } = item.configuration;
|
||||||
|
let configRef = Store.get('configRef').filter(
|
||||||
|
(item: any) => item.host === host,
|
||||||
|
);
|
||||||
|
getPortOptions(configRef, index);
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamicValidateForm.cluster.length === 1) {
|
if (dynamicValidateForm.cluster.length === 1) {
|
||||||
|
|
|
@ -319,9 +319,9 @@ const handleAdd = () => {
|
||||||
const tab: any = window.open(
|
const tab: any = window.open(
|
||||||
`${origin}/#/iot/link/accessConfig/detail/:id?save=true&view=false&type=${props.channel}`,
|
`${origin}/#/iot/link/accessConfig/detail/:id?save=true&view=false&type=${props.channel}`,
|
||||||
);
|
);
|
||||||
tab.onTabSaveSuccess = async (value: string) => {
|
tab.onTabSaveSuccess = async (value: any) => {
|
||||||
await getGatewayList();
|
await getGatewayList();
|
||||||
handleClick(value);
|
handleClick(value?.result);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -159,6 +159,7 @@ const paramsValue = reactive<TermsType>({
|
||||||
const formItemContext = Form.useInjectFormItemContext()
|
const formItemContext = Form.useInjectFormItemContext()
|
||||||
const showDelete = ref(false)
|
const showDelete = ref(false)
|
||||||
const columnOptions: any = inject('filter-params') //
|
const columnOptions: any = inject('filter-params') //
|
||||||
|
const columnType = ref<string>()
|
||||||
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // 条件值
|
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // 条件值
|
||||||
const valueOptions = ref<any[]>([]) // 默认手动输入下拉
|
const valueOptions = ref<any[]>([]) // 默认手动输入下拉
|
||||||
const arrayParamsKey = ['nbtw', 'btw', 'in', 'nin', 'contains_all', 'contains_any', 'not_contains']
|
const arrayParamsKey = ['nbtw', 'btw', 'in', 'nin', 'contains_all', 'contains_any', 'not_contains']
|
||||||
|
@ -175,6 +176,7 @@ const handOptionByColumn = (option: any) => {
|
||||||
if (option) {
|
if (option) {
|
||||||
termTypeOptions.value = option.termTypes || []
|
termTypeOptions.value = option.termTypes || []
|
||||||
tabsOptions.value[0].component = option.type
|
tabsOptions.value[0].component = option.type
|
||||||
|
columnType.value = option.type
|
||||||
const _options = isArray(option.options) ? option.options : []
|
const _options = isArray(option.options) ? option.options : []
|
||||||
if (option.type === 'boolean') {
|
if (option.type === 'boolean') {
|
||||||
valueOptions.value = _options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || [
|
valueOptions.value = _options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || [
|
||||||
|
@ -289,6 +291,7 @@ const termsTypeSelect = (e: { key: string, name: string }) => {
|
||||||
let value = arrayParamsKey.includes(e.key) ? [ oldValue, undefined ] : oldValue
|
let value = arrayParamsKey.includes(e.key) ? [ oldValue, undefined ] : oldValue
|
||||||
|
|
||||||
// 如果上次的值 在 timeTypeKeys中 则不变
|
// 如果上次的值 在 timeTypeKeys中 则不变
|
||||||
|
if (columnType.value ==='date') {
|
||||||
if (timeTypeKeys.includes(e.key)) {
|
if (timeTypeKeys.includes(e.key)) {
|
||||||
if (tabsOptions.value[0].component !== 'int') {
|
if (tabsOptions.value[0].component !== 'int') {
|
||||||
value = undefined
|
value = undefined
|
||||||
|
@ -298,6 +301,7 @@ const termsTypeSelect = (e: { key: string, name: string }) => {
|
||||||
value = undefined
|
value = undefined
|
||||||
tabsOptions.value[0].component = 'date'
|
tabsOptions.value[0].component = 'date'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
paramsValue.value = {
|
paramsValue.value = {
|
||||||
source: paramsValue.value?.source || tabsOptions.value[0].key,
|
source: paramsValue.value?.source || tabsOptions.value[0].key,
|
||||||
|
|
|
@ -152,6 +152,7 @@ const paramsValue = reactive<TermsType>({
|
||||||
|
|
||||||
const showDelete = ref(false)
|
const showDelete = ref(false)
|
||||||
const columnOptions: any = inject(ContextKey) //
|
const columnOptions: any = inject(ContextKey) //
|
||||||
|
const columnType = ref<string>()
|
||||||
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // 条件值
|
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // 条件值
|
||||||
const valueOptions = ref<any[]>([]) // 默认手动输入下拉
|
const valueOptions = ref<any[]>([]) // 默认手动输入下拉
|
||||||
const metricOption = ref<any[]>([]) // 根据termType获取对应指标值
|
const metricOption = ref<any[]>([]) // 根据termType获取对应指标值
|
||||||
|
@ -165,7 +166,7 @@ const handOptionByColumn = (option: any) => {
|
||||||
metricsCacheOption.value = option.metrics?.map((item: any) => ({...item, label: item.name})) || []
|
metricsCacheOption.value = option.metrics?.map((item: any) => ({...item, label: item.name})) || []
|
||||||
tabsOptions.value.length = 1
|
tabsOptions.value.length = 1
|
||||||
tabsOptions.value[0].component = option.dataType
|
tabsOptions.value[0].component = option.dataType
|
||||||
|
columnType.value = option.dataType
|
||||||
if (option.metrics && option.metrics.length) {
|
if (option.metrics && option.metrics.length) {
|
||||||
|
|
||||||
tabsOptions.value.push(
|
tabsOptions.value.push(
|
||||||
|
@ -281,6 +282,7 @@ const termsTypeSelect = (e: { key: string, name: string }) => {
|
||||||
const oldValue = isArray(paramsValue.value!.value) ? paramsValue.value!.value[0] : paramsValue.value!.value
|
const oldValue = isArray(paramsValue.value!.value) ? paramsValue.value!.value[0] : paramsValue.value!.value
|
||||||
let value = arrayParamsKey.includes(e.key) ? [ oldValue, undefined ] : oldValue
|
let value = arrayParamsKey.includes(e.key) ? [ oldValue, undefined ] : oldValue
|
||||||
// 如果上次的值 在 timeTypeKeys中 则不变
|
// 如果上次的值 在 timeTypeKeys中 则不变
|
||||||
|
if (columnType.value === 'date') {
|
||||||
if (timeTypeKeys.includes(e.key)) {
|
if (timeTypeKeys.includes(e.key)) {
|
||||||
if (tabsOptions.value[0].component !== 'int') {
|
if (tabsOptions.value[0].component !== 'int') {
|
||||||
value = undefined
|
value = undefined
|
||||||
|
@ -290,6 +292,7 @@ const termsTypeSelect = (e: { key: string, name: string }) => {
|
||||||
value = undefined
|
value = undefined
|
||||||
tabsOptions.value[0].component = 'date'
|
tabsOptions.value[0].component = 'date'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
paramsValue.value = {
|
paramsValue.value = {
|
||||||
source: paramsValue.value?.source || tabsOptions.value[0].key,
|
source: paramsValue.value?.source || tabsOptions.value[0].key,
|
||||||
|
|
|
@ -123,7 +123,6 @@ export const EventEmitter = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isActionChange = (_metadata: any, _message: any) => {
|
export const isActionChange = (_metadata: any, _message: any) => {
|
||||||
console.log(_metadata, _message)
|
|
||||||
const _properties = _metadata?.properties || [];
|
const _properties = _metadata?.properties || [];
|
||||||
const _functions = _metadata?.functions || [];
|
const _functions = _metadata?.functions || [];
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<j-input
|
<j-input
|
||||||
:disabled="record.scale !== undefined"
|
:disabled="record.old_id"
|
||||||
v-model:value="record.name"
|
v-model:value="record.name"
|
||||||
placeholder="请输入名称"
|
placeholder="请输入名称"
|
||||||
/>
|
/>
|
||||||
|
@ -104,12 +104,10 @@
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.key === 'precision'">
|
<template v-else-if="column.key === 'scale'">
|
||||||
<j-form-item
|
<j-form-item :name="['data', index, 'scale']">
|
||||||
:name="['data', index, 'precision']"
|
|
||||||
>
|
|
||||||
<j-input-number
|
<j-input-number
|
||||||
v-model:value="record.precision"
|
v-model:value="record.scale"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="99999"
|
:max="99999"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@ -117,7 +115,15 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.key === 'notnull'">
|
<template v-else-if="column.key === 'notnull'">
|
||||||
<j-form-item :name="['data', index, 'notnull']">
|
<j-form-item
|
||||||
|
:name="['data', index, 'notnull']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择是否不能为空',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<j-radio-group
|
<j-radio-group
|
||||||
v-model:value="record.notnull"
|
v-model:value="record.notnull"
|
||||||
button-style="solid"
|
button-style="solid"
|
||||||
|
@ -132,7 +138,7 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.key === 'comment'">
|
<template v-else-if="column.key === 'comment'">
|
||||||
<j-form-item :name="['data', index, 'notnull']">
|
<j-form-item :name="['data', index, 'comment']">
|
||||||
<j-input
|
<j-input
|
||||||
v-model:value="record.comment"
|
v-model:value="record.comment"
|
||||||
placeholder="请输入说明"
|
placeholder="请输入说明"
|
||||||
|
@ -147,7 +153,8 @@
|
||||||
:danger="true"
|
:danger="true"
|
||||||
:popConfirm="{
|
:popConfirm="{
|
||||||
title: `确认删除`,
|
title: `确认删除`,
|
||||||
onConfirm: () => clickDel(record, index),
|
onConfirm: () =>
|
||||||
|
clickDel(record, index),
|
||||||
}"
|
}"
|
||||||
:disabled="record.status"
|
:disabled="record.status"
|
||||||
>
|
>
|
||||||
|
@ -217,6 +224,7 @@ import {
|
||||||
delSaveRow_api,
|
delSaveRow_api,
|
||||||
} from '@/api/system/dataSource';
|
} from '@/api/system/dataSource';
|
||||||
import { onlyMessage } from '@/utils/comm';
|
import { onlyMessage } from '@/utils/comm';
|
||||||
|
import { randomString } from '@/utils/utils';
|
||||||
import { FormInstance, message } from 'ant-design-vue';
|
import { FormInstance, message } from 'ant-design-vue';
|
||||||
import { DataNode } from 'ant-design-vue/lib/tree';
|
import { DataNode } from 'ant-design-vue/lib/tree';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
@ -243,13 +251,14 @@ const columns = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '精度',
|
title: '精度',
|
||||||
dataIndex: 'precision',
|
dataIndex: 'scale',
|
||||||
key: 'precision',
|
key: 'scale',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '不能为空',
|
title: '不能为空',
|
||||||
dataIndex: 'notnull',
|
dataIndex: 'notnull',
|
||||||
key: 'notnull',
|
key: 'notnull',
|
||||||
|
width: 130
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '说明',
|
title: '说明',
|
||||||
|
@ -287,6 +296,7 @@ const queryTables = (key: string) => {
|
||||||
rdbTables_api(id, key).then((resp: any) => {
|
rdbTables_api(id, key).then((resp: any) => {
|
||||||
table.data = resp.result.columns.map(
|
table.data = resp.result.columns.map(
|
||||||
(item: object, index: number) => ({
|
(item: object, index: number) => ({
|
||||||
|
old_id: randomString(),
|
||||||
...item,
|
...item,
|
||||||
index,
|
index,
|
||||||
}),
|
}),
|
||||||
|
@ -348,7 +358,7 @@ const table = reactive({
|
||||||
|
|
||||||
const addRow = () => {
|
const addRow = () => {
|
||||||
const initData: dbColumnType = {
|
const initData: dbColumnType = {
|
||||||
precision: 0,
|
scale: 0,
|
||||||
length: 0,
|
length: 0,
|
||||||
notnull: false,
|
notnull: false,
|
||||||
type: '',
|
type: '',
|
||||||
|
@ -363,19 +373,22 @@ const clickDel = (row: any, index: number) => {
|
||||||
delSaveRow_api(id, leftData.selectedKeys[0], [row.name]).then(
|
delSaveRow_api(id, leftData.selectedKeys[0], [row.name]).then(
|
||||||
(resp: any) => {
|
(resp: any) => {
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
table.data.splice(index, 1)
|
table.data.splice(index, 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
table.data.splice(index, 1)
|
table.data.splice(index, 1);
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clickSave = () => {
|
const clickSave = () => {
|
||||||
formRef.value.validate().then((_data: any) => {
|
formRef.value.validate().then((_data: any) => {
|
||||||
const columns = cloneDeep(table.data);
|
const columns = cloneDeep(table.data);
|
||||||
columns.forEach((item) => delete item.index);
|
columns.forEach((item: any) => {
|
||||||
|
delete item?.old_id
|
||||||
|
delete item?.index
|
||||||
|
});
|
||||||
if (!columns.length) {
|
if (!columns.length) {
|
||||||
onlyMessage('请配置数据源字段', 'error');
|
onlyMessage('请配置数据源字段', 'error');
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -29,7 +29,7 @@ export type dbColumnType = {
|
||||||
previousName?: string,
|
previousName?: string,
|
||||||
type: String,
|
type: String,
|
||||||
length: number,
|
length: number,
|
||||||
precision: number,
|
scale: number,
|
||||||
notnull: boolean,
|
notnull: boolean,
|
||||||
comment: string,
|
comment: string,
|
||||||
name: string,
|
name: string,
|
||||||
|
|
|
@ -172,12 +172,16 @@ const confirm = () => {
|
||||||
return message.warning('请先勾选数据');
|
return message.warning('请先勾选数据');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('table.selectedRows: ', table.selectedRows);
|
||||||
const params = table.selectedRows.map((item: any) => ({
|
const params = table.selectedRows.map((item: any) => ({
|
||||||
targetType: 'org',
|
targetType: 'org',
|
||||||
targetId: props.parentId,
|
targetId: props.parentId,
|
||||||
assetType: props.assetType,
|
assetType: props.assetType,
|
||||||
assetIdList: [item.id],
|
assetIdList: [item.id],
|
||||||
permission: item.selectPermissions,
|
// 保存时, 过滤没有的权限
|
||||||
|
permission: item.selectPermissions.filter((f: any) =>
|
||||||
|
item.permissionList.map((m: any) => m.value).includes(f),
|
||||||
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 分配产品资产后, 进入设备资产分配,默认查询第一个产品下的设备
|
// 分配产品资产后, 进入设备资产分配,默认查询第一个产品下的设备
|
||||||
|
|
|
@ -258,7 +258,6 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import PermissionButton from '@/components/PermissionButton/index.vue';
|
import PermissionButton from '@/components/PermissionButton/index.vue';
|
||||||
|
|
||||||
import { FormInstance, message } from 'ant-design-vue';
|
import { FormInstance, message } from 'ant-design-vue';
|
||||||
import ChooseIconDialog from '../components/ChooseIconDialog.vue';
|
import ChooseIconDialog from '../components/ChooseIconDialog.vue';
|
||||||
import PermissChoose from '../components/PermissChoose.vue';
|
import PermissChoose from '../components/PermissChoose.vue';
|
||||||
|
|
|
@ -63,26 +63,29 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import PermissionButton from '@/components/PermissionButton/index.vue';
|
import PermissionButton from '@/components/PermissionButton/index.vue';
|
||||||
|
|
||||||
import ButtonAddDialog from '../components/ButtonAddDialog.vue';
|
import ButtonAddDialog from '../components/ButtonAddDialog.vue';
|
||||||
|
|
||||||
import { getMenuInfo_api, saveMenuInfo_api } from '@/api/system/menu';
|
import { getMenuInfo_api, saveMenuInfo_api } from '@/api/system/menu';
|
||||||
import { message } from 'jetlinks-ui-components';
|
import { message } from 'jetlinks-ui-components';
|
||||||
|
|
||||||
const permission = 'system/Menu';
|
const permission = 'system/Menu';
|
||||||
// 路由
|
// 路由
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const routeParams = {
|
const routeParams = reactive({
|
||||||
id: route.params.id === ':id' ? '' : (route.params.id as string),
|
id: route.params.id === ':id' ? '' : (route.params.id as string),
|
||||||
...route.query,
|
...route.query,
|
||||||
};
|
});
|
||||||
|
const paramsId = ref('');
|
||||||
|
|
||||||
// 弹窗相关
|
// 弹窗相关
|
||||||
const selectItem = ref<any>({});
|
const selectItem = ref<any>({});
|
||||||
const dialogVisible = ref(false);
|
const dialogVisible = ref(false);
|
||||||
const dialogTitle = ref<'查看' | '新增' | '编辑'>('新增');
|
const dialogTitle = ref<'查看' | '新增' | '编辑'>('新增');
|
||||||
const openDialog = (mode: '查看' | '新增' | '编辑', row: object) => {
|
const openDialog = (mode: '查看' | '新增' | '编辑', row: object) => {
|
||||||
if (!routeParams.id) return message.warning('请先新增菜单基本信息');
|
if (!routeParams.id && !paramsId.value) {
|
||||||
|
return message.warning('请先新增菜单基本信息');
|
||||||
|
}
|
||||||
|
console.log(3);
|
||||||
|
|
||||||
selectItem.value = { ...row };
|
selectItem.value = { ...row };
|
||||||
dialogTitle.value = mode;
|
dialogTitle.value = mode;
|
||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
|
@ -147,6 +150,15 @@ type tableDataItem = {
|
||||||
description?: string;
|
description?: string;
|
||||||
permissions: object[];
|
permissions: object[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.params.id,
|
||||||
|
(value) => {
|
||||||
|
if (!!value) {
|
||||||
|
paramsId.value = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -73,6 +73,7 @@ import BaseMenu from '@/views/init-home/data/baseMenu';
|
||||||
import type { AntTreeNodeDropEvent } from 'ant-design-vue/es/tree';
|
import type { AntTreeNodeDropEvent } from 'ant-design-vue/es/tree';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { onlyMessage } from '@/utils/comm';
|
import { onlyMessage } from '@/utils/comm';
|
||||||
|
import { MESSAGE_SUBSCRIBE_MENU_CODE, USER_CENTER_MENU_CODE } from '@/utils/consts'
|
||||||
|
|
||||||
const selectedKeys: any = ref([]);
|
const selectedKeys: any = ref([]);
|
||||||
const treeData = ref<any>([]);
|
const treeData = ref<any>([]);
|
||||||
|
@ -103,10 +104,55 @@ const params = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 过滤子级空children
|
||||||
|
const filterAndClean = (data: any) => {
|
||||||
|
// 如果 data 是一个数组,则对每个元素递归调用此函数
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
return data
|
||||||
|
.filter((item) => item !== null) // 过滤掉 null 元素
|
||||||
|
.map((item: any) => filterAndClean(item)); // 递归调用此函数
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果 data 是一个对象,则递归调用此函数来清除其子元素
|
||||||
|
if (typeof data === 'object') {
|
||||||
|
let cleanedChildren = filterAndClean(data.children); // 递归清除子元素
|
||||||
|
if (Array.isArray(cleanedChildren)) {
|
||||||
|
cleanedChildren = cleanedChildren.filter((i) => i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleanedChildren !== undefined) {
|
||||||
|
data.children = cleanedChildren;
|
||||||
|
} else {
|
||||||
|
delete data.children; // 如果 children 是 undefined,则将其删除
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
|
const { arrMap, rootSet } = developArrToMap(
|
||||||
|
cloneDeep(treeData.value),
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
const dataMap = new Map();
|
||||||
|
// 过滤选中菜单的map
|
||||||
|
selectedKeys.value.forEach((item: string) => {
|
||||||
|
if (arrMap.has(item)) {
|
||||||
|
dataMap.set(item, arrMap.get(item));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const _saveDataMap = {
|
||||||
|
arrMap: dataMap,
|
||||||
|
rootSet,
|
||||||
|
};
|
||||||
|
|
||||||
|
const dataArr = filterAndClean(mergeMapToArr(_saveDataMap, _saveDataMap));
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await updateMenus(treeData.value);
|
const res = await updateMenus(dataArr).catch(() => {});
|
||||||
if (res.status === 200) {
|
if (res?.status === 200) {
|
||||||
onlyMessage('操作成功', 'success');
|
onlyMessage('操作成功', 'success');
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
@ -140,7 +186,7 @@ onMounted(() => {
|
||||||
);
|
);
|
||||||
getMenuTree_api(params).then((resp: any) => {
|
getMenuTree_api(params).then((resp: any) => {
|
||||||
if (resp.status == 200) {
|
if (resp.status == 200) {
|
||||||
systemMenu.value = resp.result;
|
systemMenu.value = resp.result?.filter((item: { code: string }) => ![USER_CENTER_MENU_CODE, MESSAGE_SUBSCRIBE_MENU_CODE].includes(item.code));
|
||||||
//初始化菜单
|
//初始化菜单
|
||||||
const baseMenuData = developArrToMap(baseMenu.value);
|
const baseMenuData = developArrToMap(baseMenu.value);
|
||||||
const systemMenuData = developArrToMap(systemMenu.value, true);
|
const systemMenuData = developArrToMap(systemMenu.value, true);
|
||||||
|
|
|
@ -31,12 +31,12 @@ export const filterMenu = (permissions: string[], menus: any[]) => {
|
||||||
export const mergeMapToArr = (baseMenuData: any, systemMenuData: any) => {
|
export const mergeMapToArr = (baseMenuData: any, systemMenuData: any) => {
|
||||||
const updataArr = (r: any) => {
|
const updataArr = (r: any) => {
|
||||||
for (let i = 0; i < r.length; i++) {
|
for (let i = 0; i < r.length; i++) {
|
||||||
const child = r[i].children;
|
let child = r[i].children;
|
||||||
if (child) {
|
if (child) {
|
||||||
updataArr(child);
|
updataArr(child);
|
||||||
}
|
}
|
||||||
r[i] = newMap.get(r[i].code);
|
r[i] = newMap.get(r[i].code);
|
||||||
delete r[i].parentCode;
|
r[i]?.parentCode && delete r[i].parentCode;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const root: any = [];
|
const root: any = [];
|
||||||
|
@ -45,7 +45,7 @@ export const mergeMapToArr = (baseMenuData: any, systemMenuData: any) => {
|
||||||
...new Set([...baseMenuData?.rootSet, ...systemMenuData.rootSet]),
|
...new Set([...baseMenuData?.rootSet, ...systemMenuData.rootSet]),
|
||||||
];
|
];
|
||||||
newRootArr.forEach((item: any) => {
|
newRootArr.forEach((item: any) => {
|
||||||
root.push(newMap.get(item));
|
newMap.has(item) && root.push(newMap.get(item));
|
||||||
});
|
});
|
||||||
updataArr(root);
|
updataArr(root);
|
||||||
return root;
|
return root;
|
||||||
|
@ -55,9 +55,10 @@ export const mergeMapToArr = (baseMenuData: any, systemMenuData: any) => {
|
||||||
* 平铺菜单
|
* 平铺菜单
|
||||||
* @param value 默认菜单以及查询系统菜单 baseMenu systemMenu
|
* @param value 默认菜单以及查询系统菜单 baseMenu systemMenu
|
||||||
* @param checked 查询系统菜单传true
|
* @param checked 查询系统菜单传true
|
||||||
|
* @param save 保存时传true
|
||||||
* @returns 平铺菜单Map、根菜单名、系统选中的keys
|
* @returns 平铺菜单Map、根菜单名、系统选中的keys
|
||||||
*/
|
*/
|
||||||
export const developArrToMap = (Menu: any, checked = false) => {
|
export const developArrToMap = (Menu: any, checked = false, save = false) => {
|
||||||
const rootSet = new Set();
|
const rootSet = new Set();
|
||||||
const arrMap = new Map();
|
const arrMap = new Map();
|
||||||
const checkedKeys: any = [];
|
const checkedKeys: any = [];
|
||||||
|
@ -65,10 +66,16 @@ export const developArrToMap = (Menu: any, checked = false) => {
|
||||||
arr.forEach((item: any) => {
|
arr.forEach((item: any) => {
|
||||||
item.title = item.code;
|
item.title = item.code;
|
||||||
item.key = item.code;
|
item.key = item.code;
|
||||||
|
if (save) {
|
||||||
|
delete item.checked; //保存时删除 checked 字段
|
||||||
|
checkedKeys.push(item.code);
|
||||||
|
} else {
|
||||||
if (checked || item?.checked) {
|
if (checked || item?.checked) {
|
||||||
item.checked = item?.checked || checked;
|
item.checked = item?.checked || checked;
|
||||||
checkedKeys.push(item.code);
|
checkedKeys.push(item.code);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
arrMap.set(item.code, item);
|
arrMap.set(item.code, item);
|
||||||
if (parentCode === 'root') {
|
if (parentCode === 'root') {
|
||||||
rootSet.add(item.code); //处理根菜单
|
rootSet.add(item.code); //处理根菜单
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<j-radio-button
|
<j-radio-button
|
||||||
v-for="typeStr in iconKeys"
|
v-for="typeStr in iconKeys"
|
||||||
:value="typeStr"
|
:value="typeStr"
|
||||||
|
:key="typeStr"
|
||||||
:class="{ active: selected === typeStr }"
|
:class="{ active: selected === typeStr }"
|
||||||
>
|
>
|
||||||
<AIcon :type="typeStr" />
|
<AIcon :type="typeStr" />
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import iconKeys from './fields';
|
||||||
const emits = defineEmits(['confirm', 'update:visible']);
|
const emits = defineEmits(['confirm', 'update:visible']);
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
|
@ -28,38 +30,6 @@ const confirm = () => {
|
||||||
emits('confirm', selected.value);
|
emits('confirm', selected.value);
|
||||||
emits('update:visible', false);
|
emits('update:visible', false);
|
||||||
};
|
};
|
||||||
const iconKeys = [
|
|
||||||
'EyeOutlined',
|
|
||||||
'EditOutlined',
|
|
||||||
'PlusOutlined',
|
|
||||||
'DeleteOutlined',
|
|
||||||
'CheckCircleOutlined',
|
|
||||||
'StopOutlined',
|
|
||||||
'CheckOutlined',
|
|
||||||
'CloseOutlined',
|
|
||||||
'DownOutlined',
|
|
||||||
'ImportOutlined',
|
|
||||||
'ExportOutlined',
|
|
||||||
'SyncOutlined',
|
|
||||||
'ExclamationCircleOutlined',
|
|
||||||
'UploadOutlined',
|
|
||||||
'LoadingOutlined',
|
|
||||||
'PlusCircleOutlined',
|
|
||||||
'QuestionCircleOutlined',
|
|
||||||
'DisconnectOutlined',
|
|
||||||
'LinkOutlined',
|
|
||||||
'PoweroffOutlined',
|
|
||||||
'SwapOutlined',
|
|
||||||
'BugOutlined',
|
|
||||||
'BarsOutlined',
|
|
||||||
'ArrowDownOutlined',
|
|
||||||
'SmallDashOutlined',
|
|
||||||
'TeamOutlined',
|
|
||||||
'MenuUnfoldOutlined',
|
|
||||||
'MenuFoldOutlined',
|
|
||||||
'InfoCircleOutlined',
|
|
||||||
'SearchOutlined',
|
|
||||||
];
|
|
||||||
|
|
||||||
const selected = ref<string>('');
|
const selected = ref<string>('');
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
const direction = [
|
||||||
|
'StepBackward',
|
||||||
|
'StepForward',
|
||||||
|
'FastBackward',
|
||||||
|
'FastForward',
|
||||||
|
'Shrink',
|
||||||
|
'ArrowsAlt',
|
||||||
|
'Down',
|
||||||
|
'Up',
|
||||||
|
'Left',
|
||||||
|
'Right',
|
||||||
|
'CaretUp',
|
||||||
|
'CaretDown',
|
||||||
|
'CaretLeft',
|
||||||
|
'CaretRight',
|
||||||
|
'UpCircle',
|
||||||
|
'DownCircle',
|
||||||
|
'LeftCircle',
|
||||||
|
'RightCircle',
|
||||||
|
'DoubleRight',
|
||||||
|
'DoubleLeft',
|
||||||
|
'VerticalLeft',
|
||||||
|
'VerticalRight',
|
||||||
|
'VerticalAlignTop',
|
||||||
|
'VerticalAlignMiddle',
|
||||||
|
'VerticalAlignBottom',
|
||||||
|
'Forward',
|
||||||
|
'Backward',
|
||||||
|
'Rollback',
|
||||||
|
'Enter',
|
||||||
|
'Retweet',
|
||||||
|
'Swap',
|
||||||
|
'SwapLeft',
|
||||||
|
'SwapRight',
|
||||||
|
'ArrowUp',
|
||||||
|
'ArrowDown',
|
||||||
|
'ArrowLeft',
|
||||||
|
'ArrowRight',
|
||||||
|
'PlayCircle',
|
||||||
|
'UpSquare',
|
||||||
|
'DownSquare',
|
||||||
|
'LeftSquare',
|
||||||
|
'RightSquare',
|
||||||
|
'Login',
|
||||||
|
'Logout',
|
||||||
|
'MenuFold',
|
||||||
|
'MenuUnfold',
|
||||||
|
'BorderBottom',
|
||||||
|
'BorderHorizontal',
|
||||||
|
'BorderInner',
|
||||||
|
'BorderOuter',
|
||||||
|
'BorderLeft',
|
||||||
|
'BorderRight',
|
||||||
|
'BorderTop',
|
||||||
|
'BorderVerticle',
|
||||||
|
'PicCenter',
|
||||||
|
'PicLeft',
|
||||||
|
'PicRight',
|
||||||
|
'RadiusBottomleft',
|
||||||
|
'RadiusBottomright',
|
||||||
|
'RadiusUpleft',
|
||||||
|
'RadiusUpright',
|
||||||
|
'Fullscreen',
|
||||||
|
'FullscreenExit',
|
||||||
|
];
|
||||||
|
|
||||||
|
const suggestion = [
|
||||||
|
'Question',
|
||||||
|
'QuestionCircle',
|
||||||
|
'Plus',
|
||||||
|
'PlusCircle',
|
||||||
|
'Pause',
|
||||||
|
'PauseCircle',
|
||||||
|
'Minus',
|
||||||
|
'MinusCircle',
|
||||||
|
'PlusSquare',
|
||||||
|
'MinusSquare',
|
||||||
|
'Info',
|
||||||
|
'InfoCircle',
|
||||||
|
'Exclamation',
|
||||||
|
'ExclamationCircle',
|
||||||
|
'Close',
|
||||||
|
'CloseCircle',
|
||||||
|
'CloseSquare',
|
||||||
|
'Check',
|
||||||
|
'CheckCircle',
|
||||||
|
'CheckSquare',
|
||||||
|
'ClockCircle',
|
||||||
|
'Warning',
|
||||||
|
'IssuesClose',
|
||||||
|
'Stop',
|
||||||
|
];
|
||||||
|
|
||||||
|
const editor = [
|
||||||
|
'Edit',
|
||||||
|
'Form',
|
||||||
|
'Copy',
|
||||||
|
'Scissor',
|
||||||
|
'Delete',
|
||||||
|
'Snippets',
|
||||||
|
'Diff',
|
||||||
|
'Highlight',
|
||||||
|
'AlignCenter',
|
||||||
|
'AlignLeft',
|
||||||
|
'AlignRight',
|
||||||
|
'BgColors',
|
||||||
|
'Bold',
|
||||||
|
'Italic',
|
||||||
|
'Underline',
|
||||||
|
'Strikethrough',
|
||||||
|
'Redo',
|
||||||
|
'Undo',
|
||||||
|
'ZoomIn',
|
||||||
|
'ZoomOut',
|
||||||
|
'FontColors',
|
||||||
|
'FontSize',
|
||||||
|
'LineHeight',
|
||||||
|
'Dash',
|
||||||
|
'SmallDash',
|
||||||
|
'SortAscending',
|
||||||
|
'SortDescending',
|
||||||
|
'Drag',
|
||||||
|
'OrderedList',
|
||||||
|
'UnorderedList',
|
||||||
|
'RadiusSetting',
|
||||||
|
'ColumnWidth',
|
||||||
|
'ColumnHeight',
|
||||||
|
];
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
'AreaChart',
|
||||||
|
'PieChart',
|
||||||
|
'BarChart',
|
||||||
|
'DotChart',
|
||||||
|
'LineChart',
|
||||||
|
'RadarChart',
|
||||||
|
'HeatMap',
|
||||||
|
'Fall',
|
||||||
|
'Rise',
|
||||||
|
'Stock',
|
||||||
|
'BoxPlot',
|
||||||
|
'Fund',
|
||||||
|
'Sliders',
|
||||||
|
];
|
||||||
|
|
||||||
|
// const logo = [
|
||||||
|
// 'Android',
|
||||||
|
// 'Apple',
|
||||||
|
// 'Windows',
|
||||||
|
// 'Ie',
|
||||||
|
// 'Chrome',
|
||||||
|
// 'Github',
|
||||||
|
// 'Aliwangwang',
|
||||||
|
// 'Dingding',
|
||||||
|
// 'WeiboSquare',
|
||||||
|
// 'WeiboCircle',
|
||||||
|
// 'TaobaoCircle',
|
||||||
|
// 'Html5',
|
||||||
|
// 'Weibo',
|
||||||
|
// 'Twitter',
|
||||||
|
// 'Wechat',
|
||||||
|
// 'Youtube',
|
||||||
|
// 'AlipayCircle',
|
||||||
|
// 'Taobao',
|
||||||
|
// 'Skype',
|
||||||
|
// 'Qq',
|
||||||
|
// 'MediumWorkmark',
|
||||||
|
// 'Gitlab',
|
||||||
|
// 'Medium',
|
||||||
|
// 'Linkedin',
|
||||||
|
// 'GooglePlus',
|
||||||
|
// 'Dropbox',
|
||||||
|
// 'Facebook',
|
||||||
|
// 'Codepen',
|
||||||
|
// 'CodeSandbox',
|
||||||
|
// 'CodeSandboxCircle',
|
||||||
|
// 'Amazon',
|
||||||
|
// 'Google',
|
||||||
|
// 'CodepenCircle',
|
||||||
|
// 'Alipay',
|
||||||
|
// 'AntDesign',
|
||||||
|
// 'AntCloud',
|
||||||
|
// 'Aliyun',
|
||||||
|
// 'Zhihu',
|
||||||
|
// 'Slack',
|
||||||
|
// 'SlackSquare',
|
||||||
|
// 'Behance',
|
||||||
|
// 'BehanceSquare',
|
||||||
|
// 'Dribbble',
|
||||||
|
// 'DribbbleSquare',
|
||||||
|
// 'Instagram',
|
||||||
|
// 'Yuque',
|
||||||
|
// 'Alibaba',
|
||||||
|
// 'Yahoo',
|
||||||
|
// 'Reddit',
|
||||||
|
// 'Sketch',
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// 不显示,需要过滤
|
||||||
|
// const filter = [
|
||||||
|
// 'AlipaySquare',
|
||||||
|
// 'AmazonCircle',
|
||||||
|
// 'AmazonSquare',
|
||||||
|
// 'BehanceCircle',
|
||||||
|
// 'CodeSandboxSquare',
|
||||||
|
// 'CodeSandboxSquare',
|
||||||
|
// 'CodepenSquare',
|
||||||
|
// 'DingtalkCircle',
|
||||||
|
// 'DingtalkSquare',
|
||||||
|
// 'DribbbleCircle',
|
||||||
|
// 'DropboxCircle',
|
||||||
|
// 'DropboxSquare',
|
||||||
|
// 'Golden',
|
||||||
|
// 'GoogleCircle',
|
||||||
|
// 'GoogleSquare',
|
||||||
|
// 'GooglePlusCircle',
|
||||||
|
// 'GooglePlusSquare',
|
||||||
|
// 'GooglePlusSquare',
|
||||||
|
// 'IeCircle',
|
||||||
|
// 'IeSquare',
|
||||||
|
// 'MediumCircle',
|
||||||
|
// 'MediumSquare',
|
||||||
|
// 'QqCircle',
|
||||||
|
// 'QqSquare',
|
||||||
|
// 'RedditCircle',
|
||||||
|
// 'RedditSquare',
|
||||||
|
// 'Signal',
|
||||||
|
// 'SketchCircle',
|
||||||
|
// 'SketchSquare',
|
||||||
|
// 'SlackCircle',
|
||||||
|
// 'TaobaoSquare',
|
||||||
|
// 'TwitterCircle',
|
||||||
|
// 'TwitterSquare',
|
||||||
|
// 'ZhihuCircle',
|
||||||
|
// 'ZhihuSquare',
|
||||||
|
// 'createFromIconfontCN',
|
||||||
|
// 'default',
|
||||||
|
// 'getTwoToneColor',
|
||||||
|
// 'setTwoToneColor',
|
||||||
|
// ];
|
||||||
|
|
||||||
|
const datum = [...direction, ...suggestion, ...editor, ...data];
|
||||||
|
|
||||||
|
const iconKeys = datum.map((item) => item + 'Outlined');
|
||||||
|
|
||||||
|
export default iconKeys;
|
|
@ -25,6 +25,7 @@
|
||||||
<AIcon type="PlusOutlined" />新增
|
<AIcon type="PlusOutlined" />新增
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
<j-button
|
<j-button
|
||||||
|
v-if="admin"
|
||||||
style="margin-left: 12px"
|
style="margin-left: 12px"
|
||||||
@click="router.push('/system/Menu/Setting')"
|
@click="router.push('/system/Menu/Setting')"
|
||||||
>菜单配置</j-button
|
>菜单配置</j-button
|
||||||
|
@ -79,10 +80,12 @@
|
||||||
|
|
||||||
<script setup lang="ts" name="Menu">
|
<script setup lang="ts" name="Menu">
|
||||||
import PermissionButton from '@/components/PermissionButton/index.vue';
|
import PermissionButton from '@/components/PermissionButton/index.vue';
|
||||||
|
|
||||||
import { getMenuTree_api, delMenuInfo_api } from '@/api/system/menu';
|
import { getMenuTree_api, delMenuInfo_api } from '@/api/system/menu';
|
||||||
import { message } from 'jetlinks-ui-components';
|
import { message } from 'jetlinks-ui-components';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useUserInfo } from '@/store/userInfo';
|
||||||
|
import { MESSAGE_SUBSCRIBE_MENU_CODE, USER_CENTER_MENU_CODE } from '@/utils/consts'
|
||||||
|
const admin = useUserInfo().userInfos?.type.id === 'admin';
|
||||||
|
|
||||||
const permission = 'system/Menu';
|
const permission = 'system/Menu';
|
||||||
|
|
||||||
|
@ -108,7 +111,7 @@ const columns = [
|
||||||
search: {
|
search: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
width: 220,
|
// width: 220,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '页面地址',
|
title: '页面地址',
|
||||||
|
@ -133,7 +136,8 @@ const columns = [
|
||||||
title: '说明',
|
title: '说明',
|
||||||
dataIndex: 'describe',
|
dataIndex: 'describe',
|
||||||
key: 'describe',
|
key: 'describe',
|
||||||
width: 200,
|
ellipsis: true,
|
||||||
|
// width: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
|
@ -150,8 +154,9 @@ const columns = [
|
||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'action',
|
dataIndex: 'action',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
|
fixed: 'right',
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
width: 140,
|
width: 200,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const queryParams = ref({ terms: [] });
|
const queryParams = ref({ terms: [] });
|
||||||
|
@ -201,7 +206,7 @@ const table = reactive({
|
||||||
return {
|
return {
|
||||||
code: resp.message,
|
code: resp.message,
|
||||||
result: {
|
result: {
|
||||||
data: resp.result,
|
data: resp.result?.filter((item: { code: string }) => ![USER_CENTER_MENU_CODE, MESSAGE_SUBSCRIBE_MENU_CODE].includes(item.code)),
|
||||||
pageIndex: resp.pageIndex,
|
pageIndex: resp.pageIndex,
|
||||||
pageSize: resp.pageSize,
|
pageSize: resp.pageSize,
|
||||||
total: resp.total,
|
total: resp.total,
|
||||||
|
@ -246,6 +251,7 @@ const table = reactive({
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.menu-container {
|
.menu-container {
|
||||||
|
width: 100%;
|
||||||
:deep(.ant-table-cell) {
|
:deep(.ant-table-cell) {
|
||||||
.ant-btn-link {
|
.ant-btn-link {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
import { FormInstance, message } from 'ant-design-vue';
|
import { FormInstance, message } from 'ant-design-vue';
|
||||||
import PermissTree from '../components/PermissTree.vue';
|
import PermissTree from '../components/PermissTree.vue';
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
|
import { USER_CENTER_MENU_DATA } from '@/views/init-home/data/baseMenu'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getRoleDetails_api,
|
getRoleDetails_api,
|
||||||
|
@ -71,7 +72,7 @@ const form = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
},
|
},
|
||||||
menus: [],
|
menus: [USER_CENTER_MENU_DATA],
|
||||||
getForm: () => {
|
getForm: () => {
|
||||||
getRoleDetails_api(roleId).then((resp) => {
|
getRoleDetails_api(roleId).then((resp) => {
|
||||||
if (resp.status) {
|
if (resp.status) {
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
<j-checkbox
|
<j-checkbox
|
||||||
v-model:checked="record.granted"
|
v-model:checked="record.granted"
|
||||||
:indeterminate="record.indeterminate"
|
:indeterminate="record.indeterminate"
|
||||||
|
:disabled='record.code === USER_CENTER_MENU_CODE'
|
||||||
@change="menuChange(record, true)"
|
@change="menuChange(record, true)"
|
||||||
>{{ record.name }}</j-checkbox
|
>{{ record.name }}</j-checkbox
|
||||||
>
|
>
|
||||||
|
@ -63,6 +64,7 @@
|
||||||
v-for="button in record.buttons"
|
v-for="button in record.buttons"
|
||||||
v-model:checked="button.granted"
|
v-model:checked="button.granted"
|
||||||
@change="actionChange(record)"
|
@change="actionChange(record)"
|
||||||
|
:disabled='[USER_CENTER_MENU_BUTTON_CODE].includes(button.id)'
|
||||||
>{{ button.name }}</j-checkbox
|
>{{ button.name }}</j-checkbox
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,9 +100,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep, uniqBy } from 'lodash-es';
|
||||||
import { getPrimissTree_api } from '@/api/system/role';
|
import { getPrimissTree_api } from '@/api/system/role';
|
||||||
import { getCurrentInstance } from 'vue';
|
import { getCurrentInstance } from 'vue';
|
||||||
|
import {
|
||||||
|
USER_CENTER_MENU_BUTTON_CODE,
|
||||||
|
MESSAGE_SUBSCRIBE_MENU_BUTTON_CODE,
|
||||||
|
USER_CENTER_MENU_CODE,
|
||||||
|
MESSAGE_SUBSCRIBE_MENU_CODE
|
||||||
|
} from '@/utils/consts'
|
||||||
|
|
||||||
const emits = defineEmits(['update:selectItems']);
|
const emits = defineEmits(['update:selectItems']);
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -156,7 +165,7 @@ const selectAllChange = () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log('selectAllChange: ', flatTableData);
|
// console.log('selectAllChange: ', flatTableData);
|
||||||
indeterminate.value = false;
|
indeterminate.value = false;
|
||||||
emits(
|
emits(
|
||||||
'update:selectItems',
|
'update:selectItems',
|
||||||
|
@ -165,24 +174,25 @@ const selectAllChange = () => {
|
||||||
};
|
};
|
||||||
// 表头-批量设置
|
// 表头-批量设置
|
||||||
const bulkShow = ref<boolean>(false);
|
const bulkShow = ref<boolean>(false);
|
||||||
const bulkOptions = [
|
const bulkOptions = ref();
|
||||||
{
|
// const bulkOptions = [
|
||||||
label: '全部数据',
|
// {
|
||||||
value: 'ignore',
|
// label: '全部数据',
|
||||||
},
|
// value: 'ignore',
|
||||||
{
|
// },
|
||||||
label: '所在组织及下级组织',
|
// {
|
||||||
value: 'org-include-children',
|
// label: '所在组织及下级组织',
|
||||||
},
|
// value: 'org-include-children',
|
||||||
{
|
// },
|
||||||
label: '所在组织',
|
// {
|
||||||
value: 'org',
|
// label: '所在组织',
|
||||||
},
|
// value: 'org',
|
||||||
{
|
// },
|
||||||
label: '自己创建的',
|
// {
|
||||||
value: 'creator',
|
// label: '自己创建的',
|
||||||
},
|
// value: 'creator',
|
||||||
];
|
// },
|
||||||
|
// ];
|
||||||
const bulkValue = ref<string>('');
|
const bulkValue = ref<string>('');
|
||||||
const bulkChange = () => {
|
const bulkChange = () => {
|
||||||
if (!bulkValue) return;
|
if (!bulkValue) return;
|
||||||
|
@ -198,7 +208,7 @@ const bulkChange = () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log('bulkChange: ', flatTableData);
|
// console.log('bulkChange: ', flatTableData);
|
||||||
emits(
|
emits(
|
||||||
'update:selectItems',
|
'update:selectItems',
|
||||||
flatTableData.filter((item) => item.granted),
|
flatTableData.filter((item) => item.granted),
|
||||||
|
@ -221,9 +231,10 @@ const init = () => {
|
||||||
() => {
|
() => {
|
||||||
// 深克隆表格数据的扁平版 因为会做一些改动 该改动只用于反馈给父组件,本组件无需变化
|
// 深克隆表格数据的扁平版 因为会做一些改动 该改动只用于反馈给父组件,本组件无需变化
|
||||||
const selected = cloneDeep(flatTableData).filter(
|
const selected = cloneDeep(flatTableData).filter(
|
||||||
(item) =>
|
(item: any) =>
|
||||||
(item.granted && item.parentId) ||
|
(item.granted && item.parentId) ||
|
||||||
(item.indeterminate && item.buttons),
|
(item.indeterminate && item.buttons) ||
|
||||||
|
item.code === USER_CENTER_MENU_CODE || item.code === MESSAGE_SUBSCRIBE_MENU_CODE, // 放开个人中心以及消息订阅
|
||||||
);
|
);
|
||||||
|
|
||||||
selected.forEach((item) => {
|
selected.forEach((item) => {
|
||||||
|
@ -259,9 +270,17 @@ init();
|
||||||
function getAllPermiss() {
|
function getAllPermiss() {
|
||||||
const id = route.params.id as string;
|
const id = route.params.id as string;
|
||||||
getPrimissTree_api(id).then((resp) => {
|
getPrimissTree_api(id).then((resp) => {
|
||||||
tableData.value = resp.result;
|
const _result = resp.result
|
||||||
|
// 默认选中个人中心相关设置
|
||||||
|
tableData.value = _result.map((item: { code: string , buttons: any[], granted: boolean}) => {
|
||||||
|
if (item.code === USER_CENTER_MENU_CODE) {
|
||||||
|
item.granted = true
|
||||||
|
item.buttons = item.buttons.map( b => ({...b, granted: true, enabled: true}))
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
});
|
||||||
|
|
||||||
treeToSimple(resp.result); // 表格数据扁平化
|
treeToSimple(tableData.value); // 表格数据扁平化
|
||||||
|
|
||||||
const selectList = flatTableData.filter((item) => item.granted); // 第一列选中的项
|
const selectList = flatTableData.filter((item) => item.granted); // 第一列选中的项
|
||||||
emits('update:selectItems', selectList); // 选中的项传回父组件
|
emits('update:selectItems', selectList); // 选中的项传回父组件
|
||||||
|
@ -396,6 +415,16 @@ function treeToSimple(treeData: tableItemType[]) {
|
||||||
flatTableData.push(item);
|
flatTableData.push(item);
|
||||||
item.children && treeToSimple(item.children);
|
item.children && treeToSimple(item.children);
|
||||||
});
|
});
|
||||||
|
// console.log('flatTableData: ', flatTableData);
|
||||||
|
// 根据所有权限, 取assetAccesses并集数据
|
||||||
|
let assets: any[] = [];
|
||||||
|
flatTableData?.forEach((item: any) => {
|
||||||
|
assets = [...assets, ...item.assetAccesses];
|
||||||
|
});
|
||||||
|
bulkOptions.value = uniqBy(assets, 'supportId')?.map((m: any) => ({
|
||||||
|
label: m.name,
|
||||||
|
value: m.supportId,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 设置子节点的状态
|
* 设置子节点的状态
|
||||||
|
|
|
@ -92,8 +92,8 @@ export default defineConfig(({ mode}) => {
|
||||||
[env.VITE_APP_BASE_API]: {
|
[env.VITE_APP_BASE_API]: {
|
||||||
// target: 'http://192.168.33.22:8800',
|
// target: 'http://192.168.33.22:8800',
|
||||||
// target: 'http://192.168.32.244:8881',
|
// target: 'http://192.168.32.244:8881',
|
||||||
// target: 'http://120.77.179.54:8844', // 120测试
|
target: 'http://120.77.179.54:8844', // 120测试
|
||||||
target: 'http://192.168.33.46:8844', // 本地开发环境
|
// target: 'http://192.168.33.46:8844', // 本地开发环境
|
||||||
ws: 'ws://192.168.33.46:8844',
|
ws: 'ws://192.168.33.46:8844',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/api/, '')
|
rewrite: (path) => path.replace(/^\/api/, '')
|
||||||
|
|
|
@ -3700,8 +3700,8 @@ jetlinks-store@^0.0.3:
|
||||||
|
|
||||||
jetlinks-ui-components@^1.0.5:
|
jetlinks-ui-components@^1.0.5:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.5.tgz#c71ecae61776bff738f43efe46aac7264f092736"
|
resolved "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.5.tgz#8cbd59900e692dd931d289f3d5a6f4541485fd9f"
|
||||||
integrity sha512-+1a/4nA5RCiInRFyyaVCMEWSBzNU8lzxOYTTpY0GiNhuJuhGE5AbBsVp9CXXF0lFECK2iqaAElY+QN4Wjms1Dw==
|
integrity sha512-ytX39qMt3kkEisURoIKlv2rAhGSvI74/WLLqkP6dJdz4q1k3UpANDtcnrz9rGRwTAKszVQ6kCga6VL6kGJiteQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vueuse/core" "^9.12.0"
|
"@vueuse/core" "^9.12.0"
|
||||||
ant-design-vue "^3.2.15"
|
ant-design-vue "^3.2.15"
|
||||||
|
|
Loading…
Reference in New Issue