merge: merge dev
* fix: 登录加密 * fix: 登录加密功能 * fix: 树样式错乱bug修改 * fix: bug#17059 * fix: bug#17128 * fix: 17131 * fix: bug#17122 * fix: bug#17156 * fix: 修改bug * fix: bug#17056 * fix: bug#17005 * fix: 修改bug * fix: bug#17296 * fix: bug应用管理/集成菜单 * fix: bug#17299 * fix: bug#17148 * fix: bug#17392 * fix: bug#17416 * fix: bug#17417 * fix: bug#17418 * fix: bug#17421 * fix: bug#17556、17555 * fix: bug#17299 * fix: bug#17148 * fix: bug#17392 * fix: bug#17416 * fix: bug#17417 * fix: bug#17418 * fix: bug#17421 * fix: bug#17510 * fix: bug#17510 * fix: bug#17299 * fix: 修改tree样式 * fix: 修改样式 * fix: bug#17425 * fix: 跳转bug * fix: bug#17556、17555 * fix: 资产分配权限为空问题 * fix: 资产分配权限为空问题 * fix: bug#17557、17299 * fix: bug#17537,修复设备详情映射bug,修复数采仪表盘bug * fix: 资产分配权限为空问题 * fix: bug#17557、17299 * fix: 修改bug * fix: bug#17148 * fix: bug#17564 * fix: 数采仪表盘bug * fix: bug#17537 * fix: 设备详情bug * fix: 网关设备-远程控制兼容https * fix: bug网关设备跳转 * fix: bug网关设备跳转 * fix: 修复组织管理树编辑携带多余参数 * fix: 组织管理树提交bug * fix: 修复404页面 * fix: bug#17584 * fix: 组织管理树提交bug * fix: bug#17584
This commit is contained in:
parent
dd1d9ccbe6
commit
9e7e63f713
|
@ -4,6 +4,13 @@ import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable'
|
|||
import { DeviceInstance } from '@/views/device/Instance/typings'
|
||||
import { DeviceMetadata, UnitType } from '@/views/device/Product/typings';
|
||||
|
||||
/**
|
||||
* 重置设备继承产品的物模型规则
|
||||
* @param deviceId 设备ID
|
||||
* @param productId 产品ID
|
||||
*/
|
||||
export const resetRule = (productId:string,deviceId:string,data:any) => server.remove(`/virtual/property/product/${productId}/${deviceId}/_batch`,{},{data})
|
||||
|
||||
/**
|
||||
* 删除设备物模型
|
||||
* @param deviceId 设备ID
|
||||
|
|
|
@ -10,6 +10,11 @@ export const getProductList = (parmas?:any) => server.get('/device/product/_qu
|
|||
*/
|
||||
export const getDeviceList = (parmas?:any) => server.get('/device-instance/_query/no-paging?paging=false',parmas);
|
||||
|
||||
/**
|
||||
* 获取有设备的告警的产品名称
|
||||
*/
|
||||
export const getAlarmProduct = (parmas:any) => server.post('/device-instance/_query',parmas)
|
||||
|
||||
/**
|
||||
* 获取组织列表
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@ router.beforeEach((to, from, next) => {
|
|||
router.addRoute('base',{
|
||||
path: '/:pathMatch(.*)',
|
||||
name: 'error',
|
||||
component: () => NotFindPage
|
||||
component: NotFindPage
|
||||
})
|
||||
|
||||
next({ ...to, replace: true })
|
||||
|
|
|
@ -61,22 +61,21 @@ const data: any = ref({
|
|||
|
||||
const pickerTimeChange = () => {
|
||||
data.value.time.type = undefined;
|
||||
console.log(1);
|
||||
};
|
||||
|
||||
const getEcharts = async (val: any) => {
|
||||
loading.value = true;
|
||||
const resp: any = await dashboard(pointParams(val));
|
||||
if (resp.success) {
|
||||
const x = resp.result
|
||||
if (resp.success && resp?.result?.length) {
|
||||
const x = resp.result
|
||||
.map((item: any) => item.data.timeString)
|
||||
.reverse();
|
||||
const y = resp.result.map((item: any) => item.data.value).reverse();
|
||||
handleOptions(x, y);
|
||||
}
|
||||
setTimeout(() => {
|
||||
setTimeout(()=>{
|
||||
loading.value = false;
|
||||
}, 300);
|
||||
},300)
|
||||
};
|
||||
|
||||
const handleOptions = (x = [], y = []) => {
|
||||
|
|
|
@ -129,8 +129,9 @@ import { TOKEN_KEY } from '@/utils/variable'
|
|||
import { Form } from 'ant-design-vue'
|
||||
|
||||
import { applicationInfo, bindAccount } from '@/api/bind'
|
||||
import { code, authLogin, userDetail } from '@/api/login'
|
||||
import { code, authLogin, userDetail , authLoginConfig} from '@/api/login'
|
||||
import { useSystem } from '@/store/system'
|
||||
import {encrypt} from '@/utils/encrypt'
|
||||
|
||||
const useForm = Form.useForm;
|
||||
const systemStore = useSystem();
|
||||
|
@ -175,15 +176,17 @@ const getUrlCode = () => {
|
|||
const bindUser = ref<any>({ appName: '' })
|
||||
const getAppInfo = async () => {
|
||||
const code = getUrlCode()
|
||||
const { result } = await applicationInfo(code)
|
||||
bindUser.value = result
|
||||
const { result,success } = await applicationInfo(code)
|
||||
bindUser.value = result || {}
|
||||
|
||||
if (result.applicationProvider === 'dingtalk-ent-app') {
|
||||
bindUser.value.appName = '钉钉'
|
||||
} else if (result.applicationProvider === 'wechat-webapp') {
|
||||
bindUser.value.appName = '微信'
|
||||
} else {
|
||||
bindUser.value.appName = result.applicationName
|
||||
if(success){
|
||||
if (result?.applicationProvider === 'dingtalk-ent-app') {
|
||||
bindUser.value.appName = '钉钉'
|
||||
} else if (result?.applicationProvider === 'wechat-webapp') {
|
||||
bindUser.value.appName = '微信'
|
||||
} else {
|
||||
bindUser.value.appName = result?.applicationName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,7 +242,11 @@ const getCode = async () => {
|
|||
captcha.value.key = res.result?.key
|
||||
}
|
||||
|
||||
|
||||
const RsaConfig = reactive<any>({
|
||||
enabled:false, //是否加密
|
||||
publicKey:'', //rsa公钥,使用此公钥对密码进行加密
|
||||
id:'' //密钥ID
|
||||
})
|
||||
/**
|
||||
* 登录并绑定账户
|
||||
*/
|
||||
|
@ -252,14 +259,25 @@ const handleLoginBind = () => {
|
|||
bindCode: code,
|
||||
expires: 3600000
|
||||
}
|
||||
|
||||
const resq:any = await authLoginConfig()
|
||||
if(resq.status === 200){
|
||||
if(resq.result?.encrypt){
|
||||
RsaConfig.enabled = resq.result?.encrypt.enabled
|
||||
RsaConfig.publicKey = resq.result?.encrypt.publicKey
|
||||
RsaConfig.id = resq.result?.encrypt.id
|
||||
}
|
||||
}
|
||||
if (captcha.value.base64) {
|
||||
params.verifyKey = captcha.value.key
|
||||
} else {
|
||||
delete params.verifyCode
|
||||
}
|
||||
|
||||
const res = await authLogin(params)
|
||||
const data = {
|
||||
...params,
|
||||
password:RsaConfig.enabled?encrypt(params.password,RsaConfig.publicKey):params.password,
|
||||
encryptId:RsaConfig.enabled?RsaConfig.id:undefined
|
||||
}
|
||||
const res = await authLogin(data)
|
||||
console.log('res: ', res)
|
||||
if (res.success) {
|
||||
onlyMessage('登录成功')
|
||||
|
@ -273,11 +291,26 @@ const handleLoginBind = () => {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
const getQueryVariable = (): Map<string, string> => {
|
||||
const index = window.location.href.indexOf('?')
|
||||
const paramsUrl = window.location.href.substr(index + 1)
|
||||
const paramsArr = paramsUrl.split('#')?.[0] || ''
|
||||
|
||||
const vars = paramsArr.split('&');
|
||||
const maps = new Map()
|
||||
for (let i = 0; i < vars.length; i++) {
|
||||
const pair = vars[i].split('=');
|
||||
const [key, value] = pair
|
||||
maps.set(key, value)
|
||||
}
|
||||
return maps;
|
||||
}
|
||||
/**
|
||||
* 绑定成功跳转至页面url的: redirect
|
||||
*/
|
||||
const goRedirect = () => {
|
||||
const urlParams = new URLSearchParams(window.location.hash)
|
||||
const urlParams = getQueryVariable();
|
||||
const redirectUrl =
|
||||
urlParams.get('redirect') ||
|
||||
window.location.href.split('redirect=')?.[1]
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
:load-data="onLoadData"
|
||||
@check="onCheck"
|
||||
v-model:expandedKeys="expandedKeys"
|
||||
:showLine="{ showLeafIcon: false }"
|
||||
:show-icon="true"
|
||||
/>
|
||||
</j-card>
|
||||
<div style="width: 100px">
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
<template #bodyCell="{ column, text, record, index }">
|
||||
<div>
|
||||
<template
|
||||
v-if="['valueType', 'name'].includes(column.dataIndex)"
|
||||
v-if="['name'].includes(column.dataIndex)"
|
||||
>
|
||||
<span>{{ text }}</span>
|
||||
</template>
|
||||
<template v-else-if="['valueType'].includes(column.dataIndex)">
|
||||
<span>{{ text.type }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<j-form-item
|
||||
:name="['dataSource', index, 'value']"
|
||||
|
@ -24,19 +27,19 @@
|
|||
>
|
||||
<ValueItem
|
||||
v-model:modelValue="record.value"
|
||||
:itemType="record.type"
|
||||
:itemType="record.valueType.type"
|
||||
|
||||
:options="
|
||||
record.type === 'enum'
|
||||
record.valueType.type === 'enum'
|
||||
? (
|
||||
record?.dataType?.elements || []
|
||||
record?.valueType?.elements || []
|
||||
).map((item) => {
|
||||
return {
|
||||
label: item.text,
|
||||
value: item.value,
|
||||
};
|
||||
})
|
||||
: record.type === 'boolean'
|
||||
: record.valueType.type === 'boolean'
|
||||
? [
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false },
|
||||
|
@ -94,6 +97,7 @@ const formRef = ref<any>(null);
|
|||
|
||||
watchEffect(() => {
|
||||
modelRef.dataSource = _props?.modelValue || []
|
||||
console.log(modelRef.dataSource);
|
||||
})
|
||||
|
||||
const onSave = () =>
|
||||
|
|
|
@ -170,7 +170,7 @@ const funcChange = (val: string) => {
|
|||
id: item.id,
|
||||
name: item.name,
|
||||
value: undefined,
|
||||
valueType: item?.valueType?.type,
|
||||
valueType: item?.valueType,
|
||||
required: item?.expands?.required,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
:load-data="onLoadData"
|
||||
@check="onCheck"
|
||||
v-model:expandedKeys="expandedKeys"
|
||||
:showLine="{ showLeafIcon: false }"
|
||||
:show-icon="true"
|
||||
/>
|
||||
</j-card>
|
||||
<div style="width: 100px">
|
||||
|
|
|
@ -33,6 +33,10 @@ const props = defineProps({
|
|||
id: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
pluginId:{
|
||||
type:String,
|
||||
default: undefined
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -46,7 +50,7 @@ const handleOk = async () => {
|
|||
loading.value = true
|
||||
const res = await savePluginData(
|
||||
'device',
|
||||
props.accessId!,
|
||||
props.pluginId!,
|
||||
route.params.id as string,
|
||||
checkKey.value
|
||||
).catch(() => ({ success: false }))
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
v-if='inkingVisible'
|
||||
:id='inklingDeviceId'
|
||||
:accessId='instanceStore.current.accessId'
|
||||
:pluginId="channelId"
|
||||
@cancel="inkingVisible = false"
|
||||
@submit='saveInkling'
|
||||
/>
|
||||
|
@ -150,7 +151,7 @@ const queryInkling = () => {
|
|||
queryPluginAccessDetail(instanceStore.current?.accessId).then(async res => {
|
||||
if (res.success) {
|
||||
channelId.value = res.result.channelId
|
||||
const pluginRes = await getPluginData('device',instanceStore.current?.accessId, instanceStore.current?.id)
|
||||
const pluginRes = await getPluginData('device',channelId.value, instanceStore.current?.id)
|
||||
if (pluginRes.success) {
|
||||
inklingDeviceId.value = pluginRes.result?.externalId
|
||||
}
|
||||
|
|
|
@ -56,7 +56,24 @@
|
|||
{{ TypeStringMap[data.record.valueType?.type] }}
|
||||
</template>
|
||||
<template #inputs="{ data }">
|
||||
<InputParams v-model:value="data.record.inputs" />
|
||||
<j-tooltip
|
||||
v-if="target === 'device' && productNoEdit.id?.includes?.(data.record.id)"
|
||||
title="继承自产品物模型的数据不支持修改"
|
||||
>
|
||||
<!-- <ModelButton :disabled="true"/>-->
|
||||
<j-button :disabled="true" type="link" style="padding-left: 0;">
|
||||
<AIcon type="SettingOutlined" />
|
||||
配置
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
<PermissionButton
|
||||
v-else
|
||||
:has-permission="`${permission}:update`"
|
||||
type="link"
|
||||
key="inputs"
|
||||
>
|
||||
<InputParams v-model:value="data.record.inputs" />
|
||||
</PermissionButton>
|
||||
</template>
|
||||
<template #output="{ data }">
|
||||
{{ data.record.output?.type }}
|
||||
|
@ -71,7 +88,24 @@
|
|||
{{ data.record.id && !data.record?.expands?.source ? '设备' : sourceMap?.[data.record?.expands?.source] || '' }}
|
||||
</template>
|
||||
<template #properties="{ data }">
|
||||
<ConfigParams v-model:value="data.record.valueType" />
|
||||
<j-tooltip
|
||||
v-if="target === 'device' && productNoEdit.id?.includes?.(data.record.id)"
|
||||
title="继承自产品物模型的数据不支持修改"
|
||||
>
|
||||
<!-- <ModelButton :disabled="true"/>-->
|
||||
<j-button :disabled="true" type="link" style="padding-left: 0;">
|
||||
<AIcon type="SettingOutlined" />
|
||||
配置
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
<PermissionButton
|
||||
v-else
|
||||
:has-permission="`${permission}:update`"
|
||||
type="link"
|
||||
key="properties"
|
||||
>
|
||||
<ConfigParams v-model:value="data.record.valueType" />
|
||||
</PermissionButton>
|
||||
</template>
|
||||
<template #outInput>
|
||||
object
|
||||
|
@ -92,8 +126,13 @@
|
|||
配置
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
<OtherSetting
|
||||
v-else
|
||||
<PermissionButton
|
||||
v-else
|
||||
:has-permission="`${permission}:update`"
|
||||
type="link"
|
||||
key="setting"
|
||||
>
|
||||
<OtherSetting
|
||||
v-model:value="data.record.expands"
|
||||
:id="data.record.id"
|
||||
:disabled="target === 'device' && productNoEdit.id?.includes?.(data.record.id)"
|
||||
|
@ -103,11 +142,13 @@
|
|||
} : undefined"
|
||||
:type="data.record.valueType.type"
|
||||
/>
|
||||
</PermissionButton>
|
||||
|
||||
</template>
|
||||
<template #action="{data}">
|
||||
<j-space>
|
||||
<PermissionButton
|
||||
:has-permission="`${permission}:add`"
|
||||
:has-permission="`${permission}:update`"
|
||||
type="link"
|
||||
key="edit"
|
||||
style="padding: 0"
|
||||
|
@ -148,7 +189,7 @@
|
|||
<AIcon type="FileSearchOutlined" />
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
:has-permission="`${permission}:delete`"
|
||||
:has-permission="`${permission}:update`"
|
||||
type="link"
|
||||
key="delete"
|
||||
style="padding: 0"
|
||||
|
@ -228,6 +269,7 @@ import {cloneDeep} from "lodash";
|
|||
import {useSystem} from "store/system";
|
||||
import {storeToRefs} from "pinia";
|
||||
import { FULL_CODE } from 'jetlinks-ui-components/es/DataTable'
|
||||
import { usePermissionStore } from '@/store/permission';
|
||||
|
||||
const props = defineProps({
|
||||
target: {
|
||||
|
@ -253,6 +295,7 @@ const router = useRouter()
|
|||
const { data: metadata, noEdit, productNoEdit } = useMetadata(_target, props.type);
|
||||
const { hasOperate } = useOperateLimits(_target);
|
||||
|
||||
const permissionStore = usePermissionStore()
|
||||
const metadataStore = useMetadataStore()
|
||||
const instanceStore = useInstanceStore()
|
||||
const productStore = useProductStore()
|
||||
|
@ -467,7 +510,7 @@ const handleSaveClick = async (next?: Function) => {
|
|||
const tabsChange = inject('tabsChange')
|
||||
|
||||
const parentTabsChange = (next?: Function) => {
|
||||
if (editStatus.value) {
|
||||
if (editStatus.value && permissionStore.hasPermission(`${props.permission}:update`)) {
|
||||
const modal = Modal.confirm({
|
||||
content: '页面改动数据未保存',
|
||||
okText: '保存',
|
||||
|
|
|
@ -198,6 +198,12 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n
|
|||
},
|
||||
{ max: 64, message: '最多可输入64个字符' },
|
||||
]
|
||||
// rules:[{
|
||||
// callback(rule:any,value: any, dataSource: any[]) {
|
||||
// console.log(rule,value,dataSource,123)
|
||||
// return value
|
||||
// }
|
||||
// }]
|
||||
},
|
||||
doubleClick(record) {
|
||||
if (isExtendsProduct(record.id, productNoEdit?.value, 'name')) {
|
||||
|
@ -343,9 +349,8 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n
|
|||
callback(rule:any,value: any, dataSource: any[]) {
|
||||
const field = rule.field.split('.')
|
||||
const fieldIndex = Number(field[1])
|
||||
|
||||
const values = dataSource.find((item, index) => index === fieldIndex)
|
||||
return validatorConfig(values.output)
|
||||
return validatorConfig(values?.output)
|
||||
}
|
||||
}]
|
||||
},
|
||||
|
@ -420,6 +425,7 @@ export const useColumns = (type?: MetadataType, target?: 'device' | 'product', n
|
|||
props: {
|
||||
noEdit: noEdit?.value?.source || [],
|
||||
target: target,
|
||||
productNoEdit: productNoEdit?.value
|
||||
}
|
||||
},
|
||||
doubleClick(record){
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
v-if="type === 'array'"
|
||||
v-model:value="_valueType.elementType"
|
||||
:unitOptions="unitOptions"
|
||||
placement="topRight"
|
||||
placement="bottomRight"
|
||||
@confirm="(data) => {valueChange(data, 'array')}"
|
||||
/>
|
||||
<DataTableObject
|
||||
v-else-if="type === 'object'"
|
||||
:value="_valueType.properties"
|
||||
placement="topRight"
|
||||
placement="bottomRight"
|
||||
:columns="columns"
|
||||
@confirm="(data) => {valueChange(data, 'object')}"
|
||||
>
|
||||
|
@ -25,28 +25,28 @@
|
|||
<ConfigModal v-model:value="data.record.valueType" :showOther="false" />
|
||||
</template>
|
||||
</DataTableObject>
|
||||
<DataTableEnum v-else-if="type === 'enum'" v-model:value="_valueType" placement="topRight" @confirm="(data) => {valueChange(data, 'enum')}"/>
|
||||
<DataTableBoolean v-else-if="type === 'boolean'" v-model:value="_valueType" placement="topRight" @confirm="(data) => {valueChange(data, 'boolean')}" />
|
||||
<DataTableEnum v-else-if="type === 'enum'" v-model:value="_valueType" placement="bottomRight" @confirm="(data) => {valueChange(data, 'enum')}"/>
|
||||
<DataTableBoolean v-else-if="type === 'boolean'" v-model:value="_valueType" placement="bottomRight" @confirm="(data) => {valueChange(data, 'boolean')}" />
|
||||
<DataTableDouble
|
||||
v-else-if="['float', 'double'].includes(type)"
|
||||
:options="unitOptions"
|
||||
v-model:value="_valueType"
|
||||
placement="topRight"
|
||||
placement="bottomRight"
|
||||
@confirm="(data) => {valueChange(data, 'float')}"
|
||||
/>
|
||||
<DataTableInteger
|
||||
v-else-if="['int', 'long'].includes(type)"
|
||||
:options="unitOptions"
|
||||
v-model:value="_valueType.unit"
|
||||
placement="topRight"
|
||||
placement="bottomRight"
|
||||
@confirm="(data) => {valueChange(data, 'int')}"
|
||||
/>
|
||||
<DataTableFile v-else-if="type === 'file'" v-model:value="_valueType.fileType" placement="topRight" @confirm="(data) => {valueChange(data, 'file')}"/>
|
||||
<DataTableDate v-else-if="type === 'date'" v-model:value="_valueType.format" placement="topRight" @confirm="(data) => {valueChange(data, 'date')}"/>
|
||||
<DataTableFile v-else-if="type === 'file'" v-model:value="_valueType.fileType" placement="bottomRight" @confirm="(data) => {valueChange(data, 'file')}"/>
|
||||
<DataTableDate v-else-if="type === 'date'" v-model:value="_valueType.format" placement="bottomRight" @confirm="(data) => {valueChange(data, 'date')}"/>
|
||||
<DataTableString
|
||||
v-else-if="['string', 'password'].includes(type)"
|
||||
v-model:value="_valueType.maxLength"
|
||||
placement="topRight"
|
||||
placement="bottomRight"
|
||||
@confirm="(data) => {valueChange(data, 'string')}"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<DataTableObject v-model:value="value" :columns="columns" @confirm="confirm">
|
||||
<DataTableObject v-model:value="value" :columns="columns" @confirm="confirm" placement="bottomRight">
|
||||
<template #valueType="{ data }">
|
||||
<span>{{ TypeStringMap[data.record.valueType?.type] }}</span>
|
||||
</template>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<DataTableObject :value="value" :columns="columns" :onAdd="addItem" width="700px" @confirm="confirm">
|
||||
<DataTableObject :value="value" :columns="columns" :onAdd="addItem" width="700px" @confirm="confirm" placement="bottomRight">
|
||||
<template #valueType="{ data }">
|
||||
<span>{{ TypeStringMap[data.record.valueType?.type] }}</span>
|
||||
</template>
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
</div>
|
||||
<DataTableArray
|
||||
v-if="type === 'array'"
|
||||
placement="bottomRight"
|
||||
v-model:value="data.elementType"
|
||||
@confirm="valueChange"
|
||||
/>
|
||||
<DataTableObject
|
||||
v-else-if="type === 'object'"
|
||||
v-model:value="data.properties"
|
||||
placement="topRight"
|
||||
placement="bottomRight"
|
||||
:columns="columns"
|
||||
@confirm="valueChange"
|
||||
:onAdd="addItem"
|
||||
|
@ -23,24 +24,27 @@
|
|||
<ConfigModal v-model:value="data.record.valueType" :showOther="false"/>
|
||||
</template>
|
||||
</DataTableObject>
|
||||
<DataTableEnum v-else-if="type === 'enum'" v-model:value="data" @confirm="valueChange"/>
|
||||
<DataTableBoolean v-else-if="type === 'boolean'" v-model:value="data" @confirm="valueChange"/>
|
||||
<DataTableEnum v-else-if="type === 'enum'" placement="bottomRight" v-model:value="data" @confirm="valueChange"/>
|
||||
<DataTableBoolean v-else-if="type === 'boolean'" placement="bottomRight" v-model:value="data" @confirm="valueChange"/>
|
||||
<DataTableDouble
|
||||
v-else-if="['float', 'double'].includes(type)"
|
||||
placement="bottomRight"
|
||||
:options="unitOptions"
|
||||
v-model:value="data"
|
||||
@confirm="valueChange"
|
||||
/>
|
||||
<DataTableInteger
|
||||
placement="bottomRight"
|
||||
v-else-if="['int', 'long'].includes(type)"
|
||||
:options="unitOptions"
|
||||
v-model:value="data.unit"
|
||||
@confirm="valueChange"
|
||||
/>
|
||||
<DataTableFile v-else-if="type === 'file'" v-model:value="data.fileType" @confirm="valueChange"/>
|
||||
<DataTableDate v-else-if="type === 'date'" v-model:value="data.date" @confirm="valueChange"/>
|
||||
<DataTableFile v-else-if="type === 'file'" placement="bottomRight" v-model:value="data.fileType" @confirm="valueChange"/>
|
||||
<DataTableDate v-else-if="type === 'date'" placement="bottomRight" v-model:value="data.date" @confirm="valueChange"/>
|
||||
<DataTableString
|
||||
v-else-if="['string', 'password'].includes(type)"
|
||||
placement="bottomRight"
|
||||
v-model:value="data.maxLength"
|
||||
@confirm="valueChange"
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<j-popconfirm-modal
|
||||
body-style="padding-top:4px;width:600px;"
|
||||
placement="topRight"
|
||||
placement="bottomRight"
|
||||
:disabled="disabled"
|
||||
:get-popup-container="(node) => fullRef || node"
|
||||
@confirm="confirm"
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
>
|
||||
</j-select>
|
||||
<j-popconfirm-modal
|
||||
v-if="myValue != 'manual'"
|
||||
v-if="myValue != 'manual' && !showReset"
|
||||
:bodyStyle="{
|
||||
width: '450px',
|
||||
height: myValue === 'rule' ? '300px' : '80px',
|
||||
}"
|
||||
:get-popup-container="(node) => fullRef || node"
|
||||
placement="topLeft"
|
||||
placement="bottomRight"
|
||||
@confirm="confirm"
|
||||
@visibleChange="visibleChange"
|
||||
>
|
||||
|
@ -37,6 +37,56 @@
|
|||
<AIcon type="EditOutlined" />
|
||||
</j-button>
|
||||
</j-popconfirm-modal>
|
||||
<j-dropdown v-if="myValue === 'rule' && target === 'device' && showReset" :getPopupContainer="(triggerNode) => triggerNode.parentNode">
|
||||
<span style="width: 20px;" @click.prevent>
|
||||
<AIcon type="MoreOutlined" />
|
||||
</span>
|
||||
<template #overlay>
|
||||
<j-menu>
|
||||
<j-menu-item>
|
||||
<j-popconfirm-modal
|
||||
:bodyStyle="{
|
||||
width: '450px',
|
||||
height: myValue === 'rule' ? '300px' : '80px',
|
||||
}"
|
||||
:get-popup-container="(node) => fullRef || node"
|
||||
placement="bottomRight"
|
||||
@confirm="confirm"
|
||||
@visibleChange="visibleChange"
|
||||
>
|
||||
<template #content>
|
||||
<j-scrollbar v-if="myValue">
|
||||
<div style="padding: 0 10px">
|
||||
<VirtualRule
|
||||
v-if="visible"
|
||||
:value="value"
|
||||
:source="myValue"
|
||||
:dataSource="dataSource"
|
||||
ref="virtualRuleRef"
|
||||
/>
|
||||
</div>
|
||||
</j-scrollbar>
|
||||
</template>
|
||||
<j-button style="padding: 4px 8px" type="link">
|
||||
编辑
|
||||
</j-button>
|
||||
</j-popconfirm-modal>
|
||||
</j-menu-item>
|
||||
<j-menu-divider/>
|
||||
<j-menu-item>
|
||||
<div style="display: flex;">
|
||||
<j-button style="padding: 4px 8px" type="link" @click="resetRules">
|
||||
重置
|
||||
</j-button>
|
||||
<j-tooltip>
|
||||
<template #title>重置为产品属性规则</template>
|
||||
<AIcon type="QuestionCircleOutlined" style="margin-top: 10px;"/>
|
||||
</j-tooltip>
|
||||
</div>
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -45,7 +95,11 @@ import { isNoCommunity } from '@/utils/utils';
|
|||
import VirtualRule from './VirtualRule/index.vue';
|
||||
import { Form } from 'jetlinks-ui-components';
|
||||
import { FULL_CODE } from 'jetlinks-ui-components/es/DataTable'
|
||||
|
||||
import { useInstanceStore } from '@/store/instance';
|
||||
import { resetRule } from '@/api/device/instance';
|
||||
import { updata } from '@/api/rule-engine/configuration';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
const instanceStore = useInstanceStore();
|
||||
const PropertySource: { label: string; value: string }[] = isNoCommunity
|
||||
? [
|
||||
{
|
||||
|
@ -79,7 +133,7 @@ type Emit = {
|
|||
};
|
||||
|
||||
const fullRef = inject(FULL_CODE);
|
||||
|
||||
const showReset = ref(false);
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Object,
|
||||
|
@ -97,6 +151,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
productNoEdit:{
|
||||
type:Array,
|
||||
default: []
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits<Emit>();
|
||||
|
@ -116,7 +174,7 @@ const disabled = computed(() => {
|
|||
// return true;
|
||||
// }
|
||||
return props.noEdit?.length
|
||||
? props.noEdit.includes(props.value._sortIndex)
|
||||
? props.noEdit.includes(props.value.id) && props?.target === 'device'
|
||||
: false;
|
||||
});
|
||||
|
||||
|
@ -155,7 +213,26 @@ const confirm = async () => {
|
|||
}
|
||||
});
|
||||
};
|
||||
|
||||
//重置规则
|
||||
// const resetRules = async() =>{
|
||||
// let res:any = await queryProductVirtualProperty(instanceStore.current?.productId,props.value.id)
|
||||
// if(res && res.status === 200 && res.result.rule){
|
||||
// const data:any = {}
|
||||
// data.virtualRule = res.result.rule
|
||||
// data.virtualRule.triggerProperties = res.result.triggerProperties
|
||||
// data.type = type.value
|
||||
// updateValue({
|
||||
// source:myValue.value,
|
||||
// ...data
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
const resetRules = async() =>{
|
||||
let res:any = await resetRule(instanceStore.current?.productId,instanceStore.current?.id,props.value?.id)
|
||||
if(res.status === 200){
|
||||
onlyMessage('操作成功!')
|
||||
}
|
||||
}
|
||||
const cancel = () => {
|
||||
if (props.value.id && !props.value?.expands?.source) {
|
||||
myValue.value = 'device';
|
||||
|
@ -177,6 +254,13 @@ watch(
|
|||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
onMounted(()=>{
|
||||
if(props.target === 'device'){
|
||||
props.productNoEdit?.id?.forEach((item:any)=>{
|
||||
item === props.value?.id ? showReset.value = true : ''
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -257,14 +257,265 @@ const loadData = async () => {
|
|||
};
|
||||
loadData();
|
||||
|
||||
// const propertiesSet = new Set(['id','name','expands','valueType']);
|
||||
|
||||
// const handleMadeDataNull = (data:any) =>{
|
||||
// return data?.properties?.some?.((item:any,index:number)=>{
|
||||
// if(!item?.id){
|
||||
// onlyMessage(`属性定义第${index + 1}个数组中缺失id属性`,'error');
|
||||
// return true
|
||||
// }
|
||||
// if(!item?.name){
|
||||
// onlyMessage(`属性定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
// return
|
||||
// }
|
||||
// if(!item?.expands?.source){
|
||||
// onlyMessage(`属性定义第${index + 1}个数组中缺失expands.source属性`,'error');
|
||||
// return
|
||||
// }
|
||||
|
||||
// if((item?.expands?.source === 'device' || item?.expands?.source === 'rule') && !item?.expands?.type){
|
||||
// onlyMessage(`属性定义第${index + 1}个数组中缺失type属性`,'error');
|
||||
// return
|
||||
// }
|
||||
// }) || false
|
||||
// }
|
||||
const requiredCheck = (data:any) =>{
|
||||
let check:boolean = false;
|
||||
if(data?.properties && !check){
|
||||
data.properties.some((item:any,index:number)=>{
|
||||
if(!item?.id){
|
||||
onlyMessage(`属性定义第${index + 1}个数组中缺失id属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.name){
|
||||
onlyMessage(`属性定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.valueType?.type){
|
||||
onlyMessage(`标签定义第${index + 1}个数组中缺失valueType.type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.expands?.source){
|
||||
onlyMessage(`属性定义第${index + 1}个数组中缺失expands.source属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
|
||||
if((item?.expands?.source === 'device' || item?.expands?.source === 'rule') && !item?.expands?.type){
|
||||
onlyMessage(`属性定义第${index + 1}个数组中缺失type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
if(data?.functions && !check){
|
||||
data?.functions.forEach((item:any,index:number)=>{
|
||||
if(!item?.id){
|
||||
onlyMessage(`方法定义第${index + 1}个数组中缺失id属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.name){
|
||||
onlyMessage(`方法定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.async && item?.async !== false){
|
||||
onlyMessage(`方法定义第${index + 1}个数组中缺失async属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
if(data?.events && !check){
|
||||
data?.events.forEach((item:any,index:number)=>{
|
||||
if(!item?.id){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失id属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.name){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.async && item?.async !== false){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失async属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.valueType?.type){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失valueType.type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.expands?.level){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失expands.level属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!check){
|
||||
if(item?.valueType?.properties){
|
||||
item?.valueType?.properties.forEach((i:any,number:number)=>{
|
||||
if(!i?.id){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失valueType.properties数组第${number+1}项的id属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!i?.name){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失valueType.properties数组第${number+1}项的name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!i?.valueType?.type){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失valueType.properties数组第${number+1}项的valueType.type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}else{
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失valueType.properties数组`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if(data?.tags && !check){
|
||||
data?.tags.forEach((item:any,index:number)=>{
|
||||
if(!item?.id){
|
||||
onlyMessage(`标签定义第${index + 1}个数组中缺失id属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.name){
|
||||
onlyMessage(`标签定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.valueType?.type){
|
||||
onlyMessage(`标签定义第${index + 1}个数组中缺失valueType.type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.expands?.type){
|
||||
onlyMessage(`标签定义第${index + 1}个数组中缺失expands.type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
return check
|
||||
}
|
||||
|
||||
const aliCheck = (data:any) => {
|
||||
let check:boolean = false;
|
||||
if(data?.properties && !check){
|
||||
data.properties.some((item:any,index:number)=>{
|
||||
if(!item?.identifier){
|
||||
onlyMessage(`属性定义第${index + 1}个数组中缺失identifier属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.name){
|
||||
onlyMessage(`属性定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.dataType?.type){
|
||||
onlyMessage(`属性定义第${index + 1}个数组中缺失dataType.type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
if(data?.functions && !check){
|
||||
data?.functions.forEach((item:any,index:number)=>{
|
||||
if(!item?.identifier){
|
||||
onlyMessage(`方法定义第${index + 1}个数组中缺失identifier属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.name){
|
||||
onlyMessage(`方法定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.callType){
|
||||
onlyMessage(`方法定义第${index + 1}个数组中缺失callType属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
if(data?.events && !check){
|
||||
data?.events.forEach((item:any,index:number)=>{
|
||||
if(!item?.identifier){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失identifier属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.name){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!item?.type){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!check){
|
||||
if(item?.outputData){
|
||||
item?.outputData?.forEach((i:any,number:number)=>{
|
||||
if(!i?.identifier){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组第${number+1}项的id属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!i?.name){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组第${number+1}项的name属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!i?.dataType?.type){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组第${number+1}项的dataType.type属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
if(!i?.dataType?.specs){
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组第${number+1}项的dataType.specs属性`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
})
|
||||
}else{
|
||||
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组`,'error');
|
||||
check = true
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return check
|
||||
}
|
||||
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
|
||||
if(file.type === 'application/json') {
|
||||
const reader = new FileReader();
|
||||
reader.readAsText(file);
|
||||
reader.onload = (json) => {
|
||||
if(json.target?.result){
|
||||
onlyMessage('操作成功!')
|
||||
formModel.import = json.target?.result;
|
||||
const data = JSON.parse(json.target?.result);
|
||||
|
||||
let check = formModel.metadata === 'jetlinks' ? requiredCheck(data) : aliCheck(data)
|
||||
if(!check){
|
||||
onlyMessage('操作成功!')
|
||||
formModel.import = json.target?.result;
|
||||
}
|
||||
} else {
|
||||
onlyMessage('文件内容不能为空', 'error')
|
||||
}
|
||||
|
@ -330,6 +581,7 @@ const handleImport = async () => {
|
|||
if (data.metadata === 'alink') {
|
||||
try {
|
||||
const _import = JSON.parse(data.import);
|
||||
|
||||
loading.value = true;
|
||||
const res = await convertMetadata(
|
||||
'from',
|
||||
|
@ -337,7 +589,8 @@ const handleImport = async () => {
|
|||
_import,
|
||||
).catch((err) => err);
|
||||
if (res.status === 200) {
|
||||
const metadata = operateLimits(res.result);
|
||||
// const metadata = operateLimits(res.result); // 导入取并集逻辑
|
||||
const metadata = res.result
|
||||
let result;
|
||||
if (props?.type === 'device') {
|
||||
result = await saveMetadata(
|
||||
|
@ -393,14 +646,15 @@ const handleImport = async () => {
|
|||
return;
|
||||
}
|
||||
const { id } = route.params || {};
|
||||
const copyOperateLimits = operateLimits(
|
||||
_object as DeviceMetadata,
|
||||
);
|
||||
// const copyOperateLimits = operateLimits(
|
||||
// _object as DeviceMetadata,
|
||||
// );
|
||||
// console.log(copyOperateLimits,_object); // 导入取并集逻辑
|
||||
const params = {
|
||||
id,
|
||||
metadata: JSON.stringify(copyOperateLimits),
|
||||
metadata: JSON.stringify(_object),
|
||||
};
|
||||
const paramsDevice = copyOperateLimits;
|
||||
const paramsDevice = _object;
|
||||
let resp = undefined;
|
||||
loading.value = true;
|
||||
if (props?.type === 'device') {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class='device-detail-metadata' style="position: relative;">
|
||||
<!-- <div class="tips">-->
|
||||
<!-- <div class="tips">-->
|
||||
<!-- <j-tooltip :title="instanceStore.detail?.independentMetadata && type === 'device'-->
|
||||
<!-- ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'-->
|
||||
<!-- : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'">-->
|
||||
|
@ -12,8 +12,8 @@
|
|||
<!-- : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'-->
|
||||
<!-- }}-->
|
||||
<!-- </div>-->
|
||||
<!-- </j-tooltip>-->
|
||||
<!-- </div>-->
|
||||
<!-- </j-tooltip> -->
|
||||
<!-- </div> -->
|
||||
<j-tabs class="metadataNav" :activeKey="tabActiveKey" destroyInactiveTabPane type="card" @change="tabsChange">
|
||||
<template #rightExtra>
|
||||
<j-space>
|
||||
|
@ -30,7 +30,9 @@
|
|||
<PermissionButton :hasPermission="`${permission}:update`" @click="cat = true" key="tsl">物模型TSL</PermissionButton>
|
||||
</j-space>
|
||||
</template>
|
||||
|
||||
<template #centerExtra>
|
||||
<span class="desc">设备会默认继承产品的物模型,继承的物模型不支持删改</span>
|
||||
</template>
|
||||
<j-tab-pane tab="属性定义" key="properties">
|
||||
<BaseMetadata :target="type" type="properties" :permission="permission" />
|
||||
</j-tab-pane>
|
||||
|
@ -79,7 +81,6 @@ provide('_metadataType', props.type)
|
|||
|
||||
const showReset = computed(() => {
|
||||
if (props.type === 'device' && instanceStore.current.productMetadata) {
|
||||
console.log(instanceStore.current)
|
||||
const proMetadata = JSON.parse(instanceStore.current.productMetadata || '{}')
|
||||
const _metadata = JSON.parse(instanceStore.current.metadata || '{}')
|
||||
return !isEqual(_metadata, proMetadata)
|
||||
|
@ -128,5 +129,12 @@ const tabsChange = (e: string) => {
|
|||
padding: 0;
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
font-size: 13px;
|
||||
color: rgba(0,0,0,.8);
|
||||
display: inline-block;
|
||||
margin-top: 12px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -20,9 +20,12 @@ watch(
|
|||
deviceId.value = newId as string;
|
||||
_control(newId).then((resp: any) => {
|
||||
if (resp.status === 200) {
|
||||
const protocol = location.protocol
|
||||
const item = `${protocol}//${resp.result?.url}/#/login?token=${resp.result.token}`;
|
||||
url.value = item;
|
||||
const item = `http://${resp.result?.url}/#/login?token=${resp.result.token}`;
|
||||
if(window.location.protocol === 'https:' && item){
|
||||
window.open(item)
|
||||
}else{
|
||||
url.value = item;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ const filterMenu = (permissions: string[], menus: any[], hasProtocol: boolean) =
|
|||
return menus.filter((item) => {
|
||||
let isShow = false;
|
||||
if (item.showPage && item.showPage.length) {
|
||||
isShow = item.showPage.every((pItem: any) => {
|
||||
isShow = item.showPage.some((pItem: any) => {
|
||||
return permissions.includes(pItem);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -166,7 +166,9 @@
|
|||
<div class="card-item-content-text">
|
||||
平台对接
|
||||
</div>
|
||||
<Ellipsis style="width: calc(100% - 20px)">
|
||||
<div>{{ slotProps.platformConfigName }}</div>
|
||||
</Ellipsis>
|
||||
</j-col>
|
||||
<j-col :span="6">
|
||||
<div class="card-item-content-text">类型</div>
|
||||
|
|
|
@ -676,8 +676,10 @@ const saveData = () => {
|
|||
onlyMessage('操作成功', 'success');
|
||||
if (route.query.save) {
|
||||
// @ts-ignore
|
||||
window?.onTabSaveSuccess(resp);
|
||||
if((window as any).onTabSaveSuccess){
|
||||
(window as any).onTabSaveSuccess(resp);
|
||||
setTimeout(() => window.close(), 300);
|
||||
}
|
||||
} else {
|
||||
history.back();
|
||||
}
|
||||
|
|
|
@ -124,8 +124,10 @@ const onFinish = async (values: any) => {
|
|||
|
||||
if (route.query.save) {
|
||||
// @ts-ignore
|
||||
window?.onTabSaveSuccess(resp.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
if((window as any).onTabSaveSuccess){
|
||||
(window as any).onTabSaveSuccess(resp.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
}
|
||||
} else {
|
||||
history.back();
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</div>
|
||||
</j-spin>
|
||||
</template>
|
||||
m
|
||||
|
||||
<script lang="ts" setup name="Cpu">
|
||||
import { dashboard } from '@/api/link/dashboard';
|
||||
import dayjs from 'dayjs';
|
||||
|
@ -95,6 +95,9 @@ const serverData = reactive({
|
|||
|
||||
const pickerTimeChange = () => {
|
||||
data.value.type = undefined;
|
||||
if(props.isNoCommunity){
|
||||
getCPUEcharts(data.value)
|
||||
}
|
||||
};
|
||||
|
||||
const echartsOptions = computed(() => {
|
||||
|
|
|
@ -95,6 +95,9 @@ const serverData = reactive({
|
|||
|
||||
const pickerTimeChange = () => {
|
||||
data.value.type = undefined;
|
||||
if(props.isNoCommunity){
|
||||
getJVMEcharts(data.value)
|
||||
}
|
||||
};
|
||||
|
||||
const getJVMEcharts = async (val: any) => {
|
||||
|
|
|
@ -215,6 +215,7 @@ const columns = [
|
|||
]
|
||||
|
||||
const handleAdd = () => {
|
||||
editData.value = {}
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
|
|
|
@ -560,8 +560,10 @@ const handleSubmit = () => {
|
|||
onlyMessage('保存成功');
|
||||
if (route.query?.notifyType) {
|
||||
// @ts-ignore
|
||||
window?.onTabSaveSuccess(res.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
if((window as any).onTabSaveSuccess){
|
||||
(window as any).onTabSaveSuccess(res.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
}
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
|
@ -587,8 +589,10 @@ const handleSubmit = () => {
|
|||
onlyMessage('保存成功');
|
||||
if (route.query?.notifyType) {
|
||||
// @ts-ignore
|
||||
window?.onTabSaveSuccess(res.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
if((window as any).onTabSaveSuccess){
|
||||
(window as any).onTabSaveSuccess(res.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
}
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
|
|
|
@ -1261,8 +1261,10 @@ const handleSubmit = () => {
|
|||
onlyMessage('保存成功');
|
||||
if (route.query?.notifyType) {
|
||||
// @ts-ignore
|
||||
window?.onTabSaveSuccess(res.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
if((window as any).onTabSaveSuccess){
|
||||
(window as any).onTabSaveSuccess(res.result);
|
||||
setTimeout(() => window.close(), 300);
|
||||
}
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
|
|
|
@ -74,10 +74,11 @@
|
|||
|
||||
<script setup lang='ts' name='Oauth'>
|
||||
import { TOKEN_KEY } from '@/utils/variable'
|
||||
import { config, code, getOAuth2, initApplication, authLogin, settingDetail } from '@/api/login'
|
||||
import { config, code, getOAuth2, initApplication, authLogin, settingDetail,authLoginConfig } from '@/api/login'
|
||||
import { getMe_api } from '@/api/home'
|
||||
import { getImage, getToken } from '@/utils/comm'
|
||||
import Config from '../../../config/config'
|
||||
import {encrypt} from '@/utils/encrypt'
|
||||
|
||||
const spinning = ref(true)
|
||||
const isLogin = ref(false)
|
||||
|
@ -193,11 +194,27 @@ const getQueryVariable = (): Map<string, string> => {
|
|||
return maps;
|
||||
}
|
||||
|
||||
const RsaConfig = reactive<any>({
|
||||
enabled:false, //是否加密
|
||||
publicKey:'', //rsa公钥,使用此公钥对密码进行加密
|
||||
id:'' //密钥ID
|
||||
})
|
||||
|
||||
const doLogin = () => {
|
||||
formRef.value.validate().then( async data => {
|
||||
const res = await authLogin({
|
||||
const resq:any = await authLoginConfig()
|
||||
if(resq.status === 200){
|
||||
if(resq.result?.encrypt){
|
||||
RsaConfig.enabled = resq.result?.encrypt.enabled
|
||||
RsaConfig.publicKey = resq.result?.encrypt.publicKey
|
||||
RsaConfig.id = resq.result?.encrypt.id
|
||||
}
|
||||
}
|
||||
const res:any = await authLogin({
|
||||
verifyKey: captcha.key,
|
||||
...formModel
|
||||
...formModel,
|
||||
password:RsaConfig.enabled?encrypt(formModel.password,RsaConfig.publicKey):formModel.password,
|
||||
encryptId:RsaConfig.enabled?RsaConfig.id:undefined
|
||||
})
|
||||
if (res.success) {
|
||||
const token = res.result.token
|
||||
|
|
|
@ -10,10 +10,22 @@
|
|||
okText="确定"
|
||||
>
|
||||
<j-form layout="vertical" :model="inputData" ref="formRef">
|
||||
<j-form-item label="状态">
|
||||
<j-switch
|
||||
checked-children="启用"
|
||||
un-checked-children="启用"
|
||||
v-model:checked="inputData.status"
|
||||
></j-switch>
|
||||
</j-form-item>
|
||||
<j-form-item
|
||||
v-if="inputData.status"
|
||||
label="kafka地址"
|
||||
name="address"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入topic',
|
||||
},
|
||||
{
|
||||
max: 64,
|
||||
message: '最多输入64个字符',
|
||||
|
@ -26,9 +38,14 @@
|
|||
></j-input>
|
||||
</j-form-item>
|
||||
<j-form-item
|
||||
v-if="inputData.status"
|
||||
label="topic"
|
||||
name="topic"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入topic',
|
||||
},
|
||||
{
|
||||
max: 64,
|
||||
message: '最多输入64个字符',
|
||||
|
@ -37,13 +54,6 @@
|
|||
>
|
||||
<j-input v-model:value="inputData.topic"></j-input>
|
||||
</j-form-item>
|
||||
<j-form-item label="状态">
|
||||
<j-switch
|
||||
checked-children="启用"
|
||||
un-checked-children="启用"
|
||||
v-model:checked="inputData.status"
|
||||
></j-switch>
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
props.data?.alarmConfigName
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="告警时间" :span="1">{{
|
||||
dayjs(data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
||||
dayjs(props.data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="告警级别" :span="1">
|
||||
<j-tooltip
|
||||
|
|
|
@ -133,6 +133,7 @@ import {
|
|||
getDeviceList,
|
||||
getOrgList,
|
||||
query,
|
||||
getAlarmProduct
|
||||
} from '@/api/rule-engine/log';
|
||||
import { queryLevel } from '@/api/rule-engine/config';
|
||||
import Search from '@/components/Search';
|
||||
|
@ -285,7 +286,51 @@ const newColumns = computed(() => {
|
|||
otherColumns.title = '场景名称'
|
||||
break;
|
||||
}
|
||||
if(props.type === 'device'){
|
||||
const productColumns = {
|
||||
title: '产品名称',
|
||||
dataIndex: 'product_id',
|
||||
key: 'product_id',
|
||||
search: {
|
||||
type: 'select',
|
||||
options: async () => {
|
||||
const termType = [
|
||||
{
|
||||
column:"id$alarm-record",
|
||||
value:[
|
||||
{
|
||||
column: "targetType",
|
||||
termType: "eq",
|
||||
value: "device",
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
const resp: any = await getAlarmProduct({
|
||||
sorts: [{ name: 'alarmTime', order: 'desc' }],
|
||||
terms: termType
|
||||
});
|
||||
const listMap: Map<string, any> = new Map()
|
||||
|
||||
if (resp.status === 200) {
|
||||
resp.result.data.forEach(item => {
|
||||
if (item.productId) {
|
||||
listMap.set(item.productId, {
|
||||
label: item.productName,
|
||||
value: item.productId,
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
return [...listMap.values()]
|
||||
|
||||
}
|
||||
return [];
|
||||
},
|
||||
},
|
||||
}
|
||||
return [otherColumns,productColumns,...columns]
|
||||
}
|
||||
return ['all', 'detail'].includes(props.type) ? columns : [
|
||||
otherColumns,
|
||||
...columns,
|
||||
|
@ -297,9 +342,9 @@ let params: any = ref({
|
|||
terms: [],
|
||||
});
|
||||
const handleSearch = async (params: any) => {
|
||||
const resp = await query(params);
|
||||
const resp:any = await query(params);
|
||||
if (resp.status === 200) {
|
||||
const res = await getOrgList();
|
||||
const res:any = await getOrgList();
|
||||
if (res.status === 200) {
|
||||
resp.result.data.map((item: any) => {
|
||||
if (item.targetType === 'org') {
|
||||
|
@ -318,7 +363,7 @@ const handleSearch = async (params: any) => {
|
|||
}
|
||||
}
|
||||
};
|
||||
watchEffect(() => {
|
||||
onMounted(() => {
|
||||
if (props.type !== 'all' && !props.id) {
|
||||
params.value.terms = [
|
||||
{
|
||||
|
@ -354,6 +399,14 @@ const search = (data: any) => {
|
|||
type: 'and',
|
||||
});
|
||||
}
|
||||
if(props.type === 'device' && data?.terms[0]?.terms[0]?.column === 'product_id'){
|
||||
params.value.terms = [{
|
||||
column:"targetId$dev-instance",
|
||||
value:[
|
||||
data?.terms[0]?.terms[0]
|
||||
]
|
||||
}]
|
||||
}
|
||||
if (props.id) {
|
||||
params.value.terms.push({
|
||||
termType: 'eq',
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
</j-radio-button>
|
||||
</j-radio-group>
|
||||
<j-range-picker
|
||||
:show-time="{format:'HH:mm:ss'}"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
valueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
style="margin-left: 12px"
|
||||
|
|
|
@ -357,7 +357,6 @@ getCurrentAlarm();
|
|||
const initQueryTime = (data: any) => {
|
||||
queryCodition.startTime = data.start;
|
||||
queryCodition.endTime = data.end;
|
||||
console.log(queryCodition);
|
||||
selectChange();
|
||||
};
|
||||
const selectChange = () => {
|
||||
|
@ -439,10 +438,14 @@ const selectChange = () => {
|
|||
res.result
|
||||
.filter((item: any) => item.group === 'alarmTrend')
|
||||
.forEach((item: any) => {
|
||||
if(time === '1d'){
|
||||
item.data.timeString = item.data.timeString.split(' ')[0]
|
||||
}
|
||||
xData.push(item.data.timeString);
|
||||
sData.push(item.data.value);
|
||||
});
|
||||
const maxY = sData.sort((a,b)=>{
|
||||
const data:any = JSON.parse(JSON.stringify(sData))
|
||||
const maxY = data.sort((a,b)=>{
|
||||
return b-a
|
||||
})[0]
|
||||
alarmStatisticsOption.value = {
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<div class="card-item-content-text">
|
||||
设备类型
|
||||
</div>
|
||||
<div>直连设备</div>
|
||||
<div>{{ slotProps.deviceType.text}}</div>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</template>
|
||||
|
|
|
@ -243,7 +243,7 @@ const deleteScene = async (id: string) => {
|
|||
|
||||
const deleteModal = (id: string) => {
|
||||
Modal.confirm({
|
||||
title: '改场景已绑定告警,确定删除?',
|
||||
title: '该场景已绑定告警,确定删除?',
|
||||
onOk: async () => {
|
||||
await deleteScene(id)
|
||||
}
|
||||
|
|
|
@ -1,41 +1,17 @@
|
|||
<template>
|
||||
<j-modal
|
||||
visible
|
||||
title="集成菜单"
|
||||
width="600px"
|
||||
@ok="handleOk"
|
||||
@cancel="cancel"
|
||||
class="edit-dialog-container"
|
||||
:confirmLoading="loading"
|
||||
>
|
||||
<j-select
|
||||
v-model:value="form.checkedSystem"
|
||||
@change="(value) => value && getTree(value)"
|
||||
style="width: 200px"
|
||||
placeholder="请选择集成系统"
|
||||
>
|
||||
<j-select-option
|
||||
v-for="item in form.systemList"
|
||||
:value="item.value"
|
||||
:key="item.value"
|
||||
>{{ item.label }}</j-select-option
|
||||
>
|
||||
<j-modal visible title="集成菜单" width="600px" @ok="handleOk" @cancel="cancel" class="edit-dialog-container"
|
||||
:confirmLoading="loading">
|
||||
<j-select v-model:value="form.checkedSystem" @change="(value) => value && getTree(value) " style="width: 200px"
|
||||
placeholder="请选择集成系统">
|
||||
<j-select-option v-for="item in form.systemList" :value="item.value" :key="item.value">{{ item.label
|
||||
}}</j-select-option>
|
||||
</j-select>
|
||||
|
||||
<p style="margin: 20px 0 0 0" v-show="form.menuTree.length > 0">
|
||||
当前集成菜单
|
||||
</p>
|
||||
<j-tree
|
||||
v-model:checkedKeys="form.checkedMenu"
|
||||
v-model:expandedKeys="form.expandedKeys"
|
||||
checkable
|
||||
:tree-data="form.menuTree"
|
||||
:fieldNames="{ key: 'code', title: 'name' }"
|
||||
@check="treeCheck"
|
||||
:height="300"
|
||||
:showLine="{ showLeafIcon: false }"
|
||||
:show-icon="true"
|
||||
>
|
||||
<j-tree v-model:checkedKeys="form.checkedMenu" v-model:expandedKeys="form.expandedKeys" checkable
|
||||
:tree-data="form.menuTree" :fieldNames="{ key: 'code', title: 'name' }" @check="treeCheck" :height="300">
|
||||
<template #title="{ name }">
|
||||
<span>{{ name }}</span>
|
||||
</template>
|
||||
|
@ -68,10 +44,12 @@ const props = defineProps<{
|
|||
// 弹窗相关
|
||||
const loading = ref(false);
|
||||
const handleOk = async () => {
|
||||
const items = filterTree(form.menuTree, [
|
||||
const menuTree = JSON.parse(JSON.stringify(form.menuTree));
|
||||
const items = filterTree(menuTree, [
|
||||
...form.checkedMenu,
|
||||
...form.half,
|
||||
// ...form.half,
|
||||
]);
|
||||
console.log(items);
|
||||
if (form.checkedSystem) {
|
||||
if (items && items.length !== 0) {
|
||||
loading.value = true;
|
||||
|
@ -130,6 +108,16 @@ function getTree(params: string) {
|
|||
form.expandedKeys = resp.result.map((item: any) => item?.code);
|
||||
});
|
||||
}
|
||||
|
||||
const getCheckMenu = (data: any, keys: any) => {
|
||||
data.forEach((item: any) => {
|
||||
if (item.children) {
|
||||
getCheckMenu(item.children, keys)
|
||||
} else {
|
||||
keys.push(item.code)
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取当前用户可访问菜单
|
||||
*/
|
||||
|
@ -145,7 +133,9 @@ function getMenus(id: string) {
|
|||
getMenuTree_api(params).then((resp: any) => {
|
||||
if (resp.status === 200) {
|
||||
// form.menuTree = resp.result;
|
||||
const keys = resp.result.map((item: any) => item?.code) as string[];
|
||||
// const keys = resp.result.map((item: any) => item?.code) as string[];
|
||||
let keys: any = [];
|
||||
getCheckMenu(resp.result, keys)
|
||||
// form.expandedKeys = keys;
|
||||
form.checkedMenu = keys;
|
||||
}
|
||||
|
@ -172,10 +162,10 @@ function getSystemList(id: string) {
|
|||
|
||||
watch(() => props.data, (newVal: any) => {
|
||||
form.checkedSystem = newVal?.page.configuration?.checkedSystem
|
||||
if(form.checkedSystem){
|
||||
if (form.checkedSystem) {
|
||||
getTree(form.checkedSystem)
|
||||
}
|
||||
if(newVal?.id) {
|
||||
if (newVal?.id) {
|
||||
getSystemList(newVal?.id);
|
||||
getMenus(newVal?.id);
|
||||
}
|
||||
|
@ -190,17 +180,23 @@ function treeCheck(checkedKeys: any, e: CheckInfo) {
|
|||
}
|
||||
//过滤节点-默认带上父节点
|
||||
function filterTree(nodes: any[], list: any[]) {
|
||||
if (!nodes?.length) {
|
||||
return nodes;
|
||||
if (!nodes) {
|
||||
return [];
|
||||
}
|
||||
return nodes.filter((it) => {
|
||||
// 不符合条件的直接砍掉
|
||||
if (list.indexOf(it.code) <= -1) {
|
||||
return false;
|
||||
if (list.includes(it.code)) {
|
||||
return true
|
||||
} else if (it.children) {
|
||||
it.children = filterTree(it.children, list);
|
||||
return it.children.length
|
||||
}
|
||||
// if (list.indexOf(it.code) <= -1) {
|
||||
// return false;
|
||||
// }
|
||||
// 符合条件的保留,并且需要递归处理其子节点
|
||||
it.children = filterTree(it.children, list);
|
||||
return true;
|
||||
// it.children = filterTree(it.children, list);
|
||||
// return true;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -6,20 +6,22 @@
|
|||
只能分配有“共享”权限的资产数据
|
||||
</h5>
|
||||
|
||||
<div class="row">
|
||||
<span style="margin-right: 8px">批量配置</span>
|
||||
<j-switch v-model:checked="bulkBool" checked-children="开" un-checked-children="关" style="width: 56px" />
|
||||
</div>
|
||||
<div v-show="bulkBool">
|
||||
<j-checkbox-group v-model:value="bulkList" :options="options" />
|
||||
<div style="display: flex; margin-left: 24px;">
|
||||
<div class="row">
|
||||
<span style="margin-right: 8px">批量配置</span>
|
||||
<j-switch v-model:checked="bulkBool" checked-children="开" un-checked-children="关" style="width: 56px" />
|
||||
</div>
|
||||
<div v-show="bulkBool" style="margin-left: 30px;">
|
||||
<j-checkbox-group v-model:value="bulkList" :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<pro-search
|
||||
<!-- <pro-search
|
||||
type="simple"
|
||||
:columns="searchColumns"
|
||||
target="category-bind-modal"
|
||||
@search="search"
|
||||
/>
|
||||
/> -->
|
||||
<j-pro-table
|
||||
ref="tableRef"
|
||||
:request="table.requestFun"
|
||||
|
@ -32,7 +34,17 @@
|
|||
onSelectAll: selectAll
|
||||
}"
|
||||
:columns="columns"
|
||||
style="max-height: 500px; overflow:auto"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<pro-search
|
||||
type="simple"
|
||||
:columns="searchColumns"
|
||||
target="category-bind-modal"
|
||||
@search="search"
|
||||
style="width: 75%;"
|
||||
/>
|
||||
</template>
|
||||
<template #card="slotProps">
|
||||
<CardBox :value="slotProps" :actions="[{ key: 1 }]" v-bind="slotProps" :active="table._selectedRowKeys.value.includes(slotProps.id)
|
||||
" @click="table.onSelectChange" :status="slotProps.state?.value"
|
||||
|
@ -312,8 +324,8 @@ const table: any = {
|
|||
(perResp: any) => {
|
||||
data.forEach((item) => {
|
||||
item.permissionList = perResp.result
|
||||
.find((f: any) => f.assetId === item.id)
|
||||
.permissionInfoList?.map((m: any) => ({
|
||||
.find((f: any) => f?.assetId === item.id)
|
||||
?.permissionInfoList?.map((m: any) => ({
|
||||
label: m.name,
|
||||
value: m.id,
|
||||
disabled: true,
|
||||
|
@ -321,13 +333,13 @@ const table: any = {
|
|||
item.selectPermissions = ['read'];
|
||||
// 资产排序
|
||||
item.permissionList = item.permissionList
|
||||
.map((m: any) => {
|
||||
?.map((m: any) => {
|
||||
return {
|
||||
...m,
|
||||
idx: idxMap[m.value],
|
||||
};
|
||||
})
|
||||
.sort((a: any, b: any) => a.idx - b.idx);
|
||||
?.sort((a: any, b: any) => a.idx - b.idx);
|
||||
// 产品的状态进行转换处理
|
||||
if (props.assetType === 'product') {
|
||||
item.state = {
|
||||
|
@ -490,6 +502,7 @@ const search = (query: any) => {
|
|||
|
||||
h5 {
|
||||
padding: 12px;
|
||||
padding-left: 24px;
|
||||
background-color: #f6f6f6;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -498,4 +511,7 @@ const search = (query: any) => {
|
|||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
:deep(.jtable-body-header-left){
|
||||
width: 80%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -176,6 +176,9 @@ const form = reactive({
|
|||
submit: () => {
|
||||
const api = form.data.id ? updateDepartment_api : addDepartment_api;
|
||||
form.data.parentId = form.data.parentId ? form.data.parentId : '';
|
||||
if(form.data.id && form.data?.children){
|
||||
delete(form.data.children)
|
||||
}
|
||||
return api(form.data);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -130,12 +130,12 @@ function getTree(cb?: Function) {
|
|||
treeMap.clear()
|
||||
getTreeData_api(params)
|
||||
.then((resp: any) => {
|
||||
selectedKeys.value = [resp.result[0]?.id];
|
||||
sourceTree.value = resp.result.sort((a: any, b: any) =>
|
||||
a.sortIndex === b.sortIndex
|
||||
? b.createTime - a.createTime
|
||||
: a.sortIndex - b.sortIndex,
|
||||
); // 报存源数据
|
||||
selectedKeys.value = [resp.result[0]?.id];
|
||||
handleTreeMap(resp.result); // 将树形结构转换为map结构
|
||||
treeData.value = resp.result; // 第一次不用进行过滤
|
||||
cb && cb();
|
||||
|
@ -155,6 +155,7 @@ const search = debounce(() => {
|
|||
treeArray.set(item.id, item);
|
||||
}
|
||||
});
|
||||
expandedKeys.value = []
|
||||
dig(searchTree);
|
||||
treeData.value = ArrayToTree(cloneDeep([...treeArray.values()]));
|
||||
} else {
|
||||
|
@ -170,6 +171,10 @@ const search = debounce(() => {
|
|||
const _item = treeMap.get(item);
|
||||
pIds.push(_item.parentId);
|
||||
treeArray.set(item, _item);
|
||||
expandedKeys.value.push(_item.id)
|
||||
if(pIds.length > 0){
|
||||
dig(pIds)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -194,8 +199,10 @@ function delDepartment(id: string) {
|
|||
}
|
||||
function refresh(id: string) {
|
||||
// @ts-ignore
|
||||
window?.onTabSaveSuccess && window.onTabSaveSuccess(id);
|
||||
setTimeout(() => window.close(), 300);
|
||||
if(window?.onTabSaveSuccess){
|
||||
window.onTabSaveSuccess(id);
|
||||
setTimeout(() => window.close(), 300);
|
||||
}
|
||||
getTree();
|
||||
}
|
||||
|
||||
|
@ -268,7 +275,7 @@ init();
|
|||
.tree {
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
|
||||
flex: 1 1 auto;
|
||||
.department-tree-item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
:columns="columns"
|
||||
target="category"
|
||||
@search="(params:any)=>queryParams = {...params}"
|
||||
style="margin-bottom: 0;"
|
||||
/>
|
||||
<div class="table">
|
||||
<j-pro-table
|
||||
|
@ -31,6 +32,7 @@
|
|||
:defaultParams="{
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
}"
|
||||
style="max-height: 510px; overflow: auto; padding-top: 0;"
|
||||
/>
|
||||
</div>
|
||||
</j-modal>
|
||||
|
|
|
@ -253,6 +253,7 @@
|
|||
<ChooseIconDialog
|
||||
v-if="dialogVisible"
|
||||
v-model:visible="dialogVisible"
|
||||
:icon="form.data.icon"
|
||||
@confirm="(typeStr:string)=>choseIcon(typeStr)"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -237,7 +237,6 @@ const filterMenus = (menus: any[]) => {
|
|||
item.children = filterMenus(item.children);
|
||||
}
|
||||
if (!filterProtocolList.length && item.code == 'link/DataCollect') {
|
||||
debugger
|
||||
return false;
|
||||
}
|
||||
return item
|
||||
|
|
|
@ -24,6 +24,10 @@ import iconKeys from './fields';
|
|||
const emits = defineEmits(['confirm', 'update:visible']);
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
icon:{
|
||||
type:string,
|
||||
default:''
|
||||
}
|
||||
}>();
|
||||
|
||||
const confirm = () => {
|
||||
|
@ -31,7 +35,13 @@ const confirm = () => {
|
|||
emits('update:visible', false);
|
||||
};
|
||||
|
||||
|
||||
const selected = ref<string>('');
|
||||
|
||||
onMounted(()=>{
|
||||
console.log(props)
|
||||
props?.icon ? selected.value = props.icon : ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -50,11 +50,11 @@
|
|||
<AIcon type="EditOutlined" />
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:hasPermission="`${permission}:add`"
|
||||
:tooltip="{ title: '新增子菜单' }"
|
||||
:disabled="slotProps.level >= 3"
|
||||
@click="table.addChildren(slotProps)"
|
||||
>
|
||||
<AIcon type="PlusCircleOutlined" />
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
hasPermission="system/Platforms/Setting:update"
|
||||
@click="save"
|
||||
v-if="props.mode !== 'home'"
|
||||
style="margin-left: 20px;"
|
||||
>
|
||||
保存
|
||||
</PermissionButton>
|
||||
|
|
|
@ -157,7 +157,7 @@ const filterPath = (path: object, filterArr: string[]) => {
|
|||
.ant-tree-list {
|
||||
.ant-tree-list-holder-inner {
|
||||
.ant-tree-switcher-noop {
|
||||
display: none !important;
|
||||
// display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<div class="top">
|
||||
<slot name="top" />
|
||||
</div>
|
||||
<j-row :gutter="24" class="content">
|
||||
<j-row class="content" :style="{padding:'24px'}" >
|
||||
<j-col
|
||||
:span="24"
|
||||
v-if="props.showTitle"
|
||||
style="font-size: 16px; margin-bottom: 48px"
|
||||
style="font-size: 16px;margin-bottom: 48px;"
|
||||
>
|
||||
API文档
|
||||
</j-col>
|
||||
|
@ -180,7 +180,6 @@ watch(
|
|||
.api-page-container {
|
||||
.content {
|
||||
background-color: #fff;
|
||||
padding: 24px;
|
||||
margin: 0 !important;
|
||||
.tree-content {
|
||||
padding-bottom: 30px;
|
||||
|
|
|
@ -64,8 +64,10 @@ const confirm = () => {
|
|||
|
||||
if (route.query.save) {
|
||||
// @ts-ignore
|
||||
window?.onTabSaveSuccess(resp.result.id);
|
||||
setTimeout(() => window.close(), 300);
|
||||
if((window as any).onTabSaveSuccess){
|
||||
(window as any).onTabSaveSuccess(resp.result.id);
|
||||
setTimeout(() => window.close(), 300);
|
||||
}
|
||||
} else jumpPage(`system/Role/Detail`, { id: resp.result.id });
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue