fix: 优化切换条件指标值错误问题;bug#23806、23826、23762、23672

* feat: 修改docker文件

* fix: bug#23086、23808、23669

* fix:删除+编辑

* fix: bug#23086

* fix: bug#23808

* fix: bug#23669

* fix: 优化切换条件指标值错误问题;bug#23806、23826、23762、23672

* fix: bug#23762、23672

* fix: bug#23826

* fix: 切换条件指标值错误问题

* fix: bug#23806
This commit is contained in:
qiaochuLei 2024-04-12 16:52:29 +08:00 committed by GitHub
parent a9a6a096e6
commit eb279582b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 326 additions and 150 deletions

View File

@ -1,3 +1,3 @@
#!/usr/bin/env bash #!/usr/bin/env bash
docker build -t registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-ui-vue:2.2.0-SNAPSHOT . docker build -t registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-ui-vue:2.1.0-TEST .
docker push registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-ui-vue:2.2.0-SNAPSHOT docker push registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-ui-vue:2.1.0-TEST

51
package-lock.json generated
View File

@ -21,6 +21,7 @@
"event-source-polyfill": "^1.0.31", "event-source-polyfill": "^1.0.31",
"global": "^4.4.0", "global": "^4.4.0",
"jetlinks-store": "^0.0.3", "jetlinks-store": "^0.0.3",
"jetlinks-ui-components": "^1.0.37",
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2", "jsencrypt": "^3.3.2",
"less": "^4.1.3", "less": "^4.1.3",
@ -5216,6 +5217,30 @@
"resolved": "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz", "resolved": "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz",
"integrity": "sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==" "integrity": "sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q=="
}, },
"node_modules/jetlinks-ui-components": {
"version": "1.0.37",
"resolved": "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.37.tgz",
"integrity": "sha512-Zhjz5/Zs02Jy40eLmh/zgF9zQlDKUpeHptTYzb9LQjszqAUAV3XjWPcNoyMqE4nP8Q3uagyw1yxJfWvzxDf62Q==",
"dependencies": {
"@vueuse/core": "^9.12.0",
"@vueuse/router": "^9.13.0",
"ant-design-vue": "^3.2.15",
"colorpicker-v3": "^2.10.2",
"lodash-es": "^4.17.21",
"monaco-editor": "^0.40.0",
"onigasm": "^2.2.5",
"sortablejs": "^1.15.0",
"vuedraggable": "^4.1.0"
},
"engines": {
"node": ">=18.14.0"
}
},
"node_modules/jetlinks-ui-components/node_modules/monaco-editor": {
"version": "0.40.0",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.40.0.tgz",
"integrity": "sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g=="
},
"node_modules/js-cookie": { "node_modules/js-cookie": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
@ -8823,8 +8848,11 @@
"version": "2.0.5", "version": "2.0.5",
"resolved": "http://registry.jetlinks.cn/init-package-json/-/init-package-json-2.0.5.tgz", "resolved": "http://registry.jetlinks.cn/init-package-json/-/init-package-json-2.0.5.tgz",
"integrity": "sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA==", "integrity": "sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA==",
<<<<<<< HEAD
=======
"resolved": "http://registry.jetlinks.cn/init-package-json/-/init-package-json-2.0.5.tgz", "resolved": "http://registry.jetlinks.cn/init-package-json/-/init-package-json-2.0.5.tgz",
"integrity": "sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA==", "integrity": "sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA==",
>>>>>>> dev-bug
"inBundle": true, "inBundle": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
@ -17472,6 +17500,29 @@
"resolved": "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz", "resolved": "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz",
"integrity": "sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==" "integrity": "sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q=="
}, },
"jetlinks-ui-components": {
"version": "1.0.37",
"resolved": "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.37.tgz",
"integrity": "sha512-Zhjz5/Zs02Jy40eLmh/zgF9zQlDKUpeHptTYzb9LQjszqAUAV3XjWPcNoyMqE4nP8Q3uagyw1yxJfWvzxDf62Q==",
"requires": {
"@vueuse/core": "^9.12.0",
"@vueuse/router": "^9.13.0",
"ant-design-vue": "^3.2.15",
"colorpicker-v3": "^2.10.2",
"lodash-es": "^4.17.21",
"monaco-editor": "^0.40.0",
"onigasm": "^2.2.5",
"sortablejs": "^1.15.0",
"vuedraggable": "^4.1.0"
},
"dependencies": {
"monaco-editor": {
"version": "0.40.0",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.40.0.tgz",
"integrity": "sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g=="
}
}
},
"js-cookie": { "js-cookie": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",

View File

@ -4,7 +4,7 @@
placeholder="请上传文件" placeholder="请上传文件"
v-model:value="fileValue" v-model:value="fileValue"
style="width: calc(100% - 110px)" style="width: calc(100% - 110px)"
:disabled="true" @change="fileValueChange"
/> />
<j-upload <j-upload
name="file" name="file"
@ -79,6 +79,10 @@ const handleChange = async (info: UploadChangeParam) => {
} }
}; };
const fileValueChange = () =>{
emit('update:modelValue',fileValue.value)
}
watch( watch(
() => props.modelValue, () => props.modelValue,
(value) => { (value) => {

View File

@ -9,9 +9,14 @@
> >
<j-tab-pane v-for="func in newFunctions" :key="func.id"> <j-tab-pane v-for="func in newFunctions" :key="func.id">
<template #tab> <template #tab>
<div style="width: 100px; text-align: left"> <j-tooltip>
<j-ellipsis>{{ func.name }}</j-ellipsis> <template #title>
{{ func.name }}
</template>
<div style="max-width: 100px" class="tabTitle">
{{ func.name }}
</div> </div>
</j-tooltip>
</template> </template>
</j-tab-pane> </j-tab-pane>
</j-tabs> </j-tabs>
@ -34,10 +39,7 @@
> >
执行 执行
</j-button> </j-button>
<j-button <j-button type="default" @click="handleClear()">
type="default"
@click="handleClear()"
>
清空 清空
</j-button> </j-button>
</j-space> </j-space>
@ -76,7 +78,7 @@ const newFunctions = ref<any[]>([]);
* @param type * @param type
* @param json * @param json
*/ */
const setInitValue = (type: string, json?: any) => { const setInitValue = (type: string, json?: any) => {
let initVal: any = ''; let initVal: any = '';
if (['int', 'long', 'float', 'double'].includes(type)) { if (['int', 'long', 'float', 'double'].includes(type)) {
initVal = 0; initVal = 0;
@ -122,8 +124,8 @@ watch(
}, },
{ {
immediate: true, immediate: true,
deep: true deep: true,
} },
); );
const onTabChange = (_key: string) => { const onTabChange = (_key: string) => {
@ -148,7 +150,8 @@ const handleExecute = async (func: any) => {
loading.value = false; loading.value = false;
}); });
if (resp.success) { if (resp.success) {
executeResult.value = resp?.result instanceof Array ? resp?.result?.[0] : resp.result; executeResult.value =
resp?.result instanceof Array ? resp?.result?.[0] : resp.result;
onlyMessage('操作成功'); onlyMessage('操作成功');
} }
}; };
@ -181,4 +184,9 @@ const handleClear = () => {
overflow: auto; overflow: auto;
} }
} }
.tabTitle {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style> </style>

View File

@ -6,12 +6,22 @@
<span>精简模式下参数只支持输入框的方式录入</span> <span>精简模式下参数只支持输入框的方式录入</span>
</j-space> </j-space>
</div> </div>
<j-tabs v-model="activeKey" tab-position="left" @change="onTabChange" :destroyInactiveTabPane="true"> <j-tabs
v-model="activeKey"
tab-position="left"
@change="onTabChange"
:destroyInactiveTabPane="true"
>
<j-tab-pane v-for="func in newFunctions" :key="func.id"> <j-tab-pane v-for="func in newFunctions" :key="func.id">
<template #tab> <template #tab>
<Ellipsis style="width: 100px; text-align: left"> <j-tooltip>
<template #title>
{{ func.name }} {{ func.name }}
</Ellipsis> </template>
<div style="max-width: 150px" class="tabTitle">
{{ func.name }}
</div>
</j-tooltip>
</template> </template>
<j-row :gutter="30"> <j-row :gutter="30">
<j-col :span="15"> <j-col :span="15">
@ -137,7 +147,7 @@ const columns = ref([
}, },
]); ]);
const executeResult = ref('') const executeResult = ref('');
// //
const newFunctions = computed(() => { const newFunctions = computed(() => {
@ -174,7 +184,7 @@ const newFunctions = computed(() => {
? tableItem['json']?.['properties'][0] ? tableItem['json']?.['properties'][0]
: undefined, : undefined,
value: undefined, value: undefined,
required: tableItem.expands?.required required: tableItem.expands?.required,
}); });
} }
@ -203,17 +213,18 @@ const handleExecute = async (func: any) => {
obj[item.id] = item.value; obj[item.id] = item.value;
} }
}); });
loading.value = true loading.value = true;
const { success, result } = await execute( const { success, result } = await execute(
route.params.id as string, route.params.id as string,
func.id, func.id,
obj, obj,
).catch(() => { )
loading.value = false .catch(() => {
loading.value = false;
}) })
.finally(() => { .finally(() => {
loading.value = false loading.value = false;
}) });
if (!success) return; if (!success) return;
onlyMessage('操作成功'); onlyMessage('操作成功');
executeResult.value = result instanceof Array ? result[0] : result; executeResult.value = result instanceof Array ? result[0] : result;
@ -227,13 +238,13 @@ const handleExecute = async (func: any) => {
* 清空 * 清空
*/ */
const handleClear = (func: any) => { const handleClear = (func: any) => {
executeResult.value = '' executeResult.value = '';
proxy?.$refs[`${func.id}Ref`][0].resetFields(); proxy?.$refs[`${func.id}Ref`][0].resetFields();
}; };
const onTabChange = (_key: string) => { const onTabChange = (_key: string) => {
executeResult.value = '' executeResult.value = '';
} };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@ -263,4 +274,9 @@ const onTabChange = (_key: string) => {
overflow: auto; overflow: auto;
} }
} }
.tabTitle {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style> </style>

View File

@ -160,8 +160,19 @@ watch(
); );
modelRef.metrics = list || []; modelRef.metrics = list || [];
} else { } else {
modelRef.metrics = modelRef.metrics = (
props.data.expands?.metrics || []; props.data.expands?.metrics || []
).map((item: any) => {
const val = Array.isArray(item?.value)
? item?.value
: isNumber(item?.value)
? [item.value]
: item?.value?.split(',');
return {
...item,
value: val,
};
});
} }
} }
} }

View File

@ -16,7 +16,18 @@
:tabBarStyle="{ width: '200px' }" :tabBarStyle="{ width: '200px' }"
@change="tabChange" @change="tabChange"
> >
<j-tab-pane v-for="i in tabList" :key="i.key" :tab="i.tab" /> <j-tab-pane v-for="i in tabList" :key="i.key">
<template #tab>
<j-tooltip>
<template #title>
{{ i.tab }}
</template>
<div style="max-width: 150px" class="tabTitle">
{{ i.tab }}
</div>
</j-tooltip>
</template>
</j-tab-pane>
</j-tabs> </j-tabs>
<JEmpty v-else style="margin: 180px 0" /> <JEmpty v-else style="margin: 180px 0" />
</div> </div>
@ -129,4 +140,9 @@ const tabChange = (key: string) => {
flex: 1; flex: 1;
} }
} }
.tabTitle {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style> </style>

View File

@ -161,7 +161,6 @@ const submitData = async (fileUrl: string) => {
errCount.value = et; errCount.value = et;
} }
} }
flag.value=false;
disabled.value = false; disabled.value = false;
}; };
source.onerror = (e: { status: number }) => { source.onerror = (e: { status: number }) => {

View File

@ -720,7 +720,10 @@ const getActions = (
const resp = await _delete(data.id); const resp = await _delete(data.id);
if (resp.status === 200) { if (resp.status === 200) {
onlyMessage('操作成功!'); onlyMessage('操作成功!');
_selectedRowKeys.value=[]; const index = _selectedRowKeys.value.findIndex((id: any) => id === data.id);
if (index !== -1) {
_selectedRowKeys.value.splice(index, 1);
}
instanceRef.value?.reload(); instanceRef.value?.reload();
} else { } else {
onlyMessage('操作失败!', 'error'); onlyMessage('操作失败!', 'error');

View File

@ -210,7 +210,7 @@
key="add" key="add"
:disabled="hasOperate('add', type)" :disabled="hasOperate('add', type)"
:tooltip="{ :tooltip="{
placement: hasOperate('add', type) ? 'topRight' : 'top', placement:'top',
title: hasOperate('add', type) title: hasOperate('add', type)
? '当前的存储方式不支持新增' ? '当前的存储方式不支持新增'
: '新增', : '新增',

View File

@ -680,7 +680,10 @@ const getActions = (
const resp: any = await del(data.id); const resp: any = await del(data.id);
if (resp.status === 200) { if (resp.status === 200) {
onlyMessage('操作成功'); onlyMessage('操作成功');
_selectedRowKeys.value=[]; const index = _selectedRowKeys.value.findIndex((id: any) => id === data.id);
if (index !== -1) {
_selectedRowKeys.value.splice(index, 1);
}
cardManageRef.value?.reload(); cardManageRef.value?.reload();
} else { } else {
onlyMessage('操作失败!', 'error'); onlyMessage('操作失败!', 'error');

View File

@ -205,7 +205,6 @@ const tableRef = ref<Record<string, any>>({});
const params = ref<Record<string, any>>({}); const params = ref<Record<string, any>>({});
let providersList = ref<Record<string, any>>([]); let providersList = ref<Record<string, any>>([]);
const providersOptions = ref<Record<string, any>>([]);
const statusMap = new Map(); const statusMap = new Map();
statusMap.set('enabled', 'success'); statusMap.set('enabled', 'success');
@ -227,7 +226,13 @@ const columns = [
key: 'provider', key: 'provider',
search: { search: {
type: 'select', type: 'select',
options: providersOptions, options: async() =>{
const res: any = await getProviders();
const providersOptions = accessConfigTypeFilter(res.result || []);
return providersOptions.filter((i:any)=>{
return i.id !== 'modbus-tcp' && i.id !== 'opc-ua'
})
},
}, },
}, },
{ {
@ -331,10 +336,6 @@ const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
const getProvidersList = async () => { const getProvidersList = async () => {
const res: any = await getProviders(); const res: any = await getProviders();
providersList.value = res.result; providersList.value = res.result;
providersOptions.value = accessConfigTypeFilter(res.result || []);
providersOptions.value = providersOptions.value.filter((i:any)=>{
return i.id !== 'modbus-tcp' && i.id !== 'opc-ua'
})
}; };
getProvidersList(); getProvidersList();

View File

@ -303,7 +303,7 @@ watch(
const showDouble = computed(() => { const showDouble = computed(() => {
const isRange = paramsValue.termType const isRange = paramsValue.termType
? doubleParamsKey.includes(paramsValue.termType) ? arrayParamsKey.includes(paramsValue.termType)
: false; : false;
const isSourceMetric = paramsValue.value?.source === 'metric'; const isSourceMetric = paramsValue.value?.source === 'metric';
if (metricsCacheOption.value.length) { if (metricsCacheOption.value.length) {
@ -324,13 +324,7 @@ const showDouble = computed(() => {
}); });
const showArray = computed(()=>{ const showArray = computed(()=>{
const isRange = paramsValue.termType ? [ const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false;
'in',
'nin',
'contains_all',
'contains_any',
'not_contains',
].includes(paramsValue.termType) : false;
const isSourceMetric = paramsValue.value?.source === 'metric'; const isSourceMetric = paramsValue.value?.source === 'metric';
if (metricsCacheOption.value.length) { if (metricsCacheOption.value.length) {
metricOption.value = metricsCacheOption.value.filter((item) => metricOption.value = metricsCacheOption.value.filter((item) =>
@ -458,6 +452,8 @@ const termsTypeSelect = (e: { key: string; name: string }) => {
if (arrayParamsKey.includes(e.key) !== isArray) { if (arrayParamsKey.includes(e.key) !== isArray) {
// //
newValue.value = undefined; newValue.value = undefined;
}else{
newValue.value = paramsValue.value!.value
} }
} }
if (['isnull', 'notnull'].includes(e.key)) { if (['isnull', 'notnull'].includes(e.key)) {

View File

@ -53,10 +53,16 @@
</slot> </slot>
</template> </template>
<template #content> <template #content>
<Ellipsis> <Ellipsis
<h3 class="card-item-content-title"> style="
width: calc(100% - 100px);
font-size: 16px;
color: rgb(49, 94, 251);
font-weight: 700;
margin-bottom: 8px;
"
>
{{ slotProps.name }} {{ slotProps.name }}
</h3>
</Ellipsis> </Ellipsis>
<j-row> <j-row>
<j-col :span="12"> <j-col :span="12">

View File

@ -457,7 +457,7 @@ const uploader: uploaderType = {
uploader.imageTypes uploader.imageTypes
.map((m: string) => m.split('.')[1]) .map((m: string) => m.split('.')[1])
.filter((typeStr) => file.type.includes(typeStr)).length > 0; .filter((typeStr) => file.type.includes(typeStr)).length > 0;
const sizeBool = file.size / 1024 / 1024 < 2; const sizeBool = file.size / 1024 / 1024 < 4;
if (!typeBool) { if (!typeBool) {
onlyMessage(`请上传.jpg.png.jfif.pjp.pjpeg.jpeg格式的图片`, 'error'); onlyMessage(`请上传.jpg.png.jfif.pjp.pjpeg.jpeg格式的图片`, 'error');
} else if (!sizeBool) { } else if (!sizeBool) {

View File

@ -1,6 +1,11 @@
<template> <template>
<div class="left-contain"> <div class="left-contain">
<j-input placeholder="分组名称" v-model:value="searchValue" @pressEnter="search" @change="searchChange"> <j-input
placeholder="分组名称"
v-model:value="searchValue"
@pressEnter="search"
@change="searchChange"
>
<template #suffix> <template #suffix>
<AIcon type="SearchOutlined" @click="search" /> <AIcon type="SearchOutlined" @click="search" />
</template> </template>
@ -11,150 +16,207 @@
</j-button> </j-button>
</div> </div>
<div class="listBox"> <div class="listBox">
<j-tree :tree-data="listData" v-if="listData.length" :fieldNames="{ title: 'name', key: 'id', children: 'children' }" <j-tree
blockNode :selectedKeys="selectedKeys" :default-expanded-keys="['global_role']" :tree-data="listData"
:showLine="{ showLeafIcon: false }"> v-if="listData.length"
:fieldNames="{ title: 'name', key: 'id', children: 'children' }"
blockNode
:selectedKeys="selectedKeys"
:default-expanded-keys="['global_role']"
:showLine="{ showLeafIcon: false }"
>
<template #title="item"> <template #title="item">
<div v-if="selectId === item.data.id"> <div v-if="selectId === item.data.id">
<j-input v-model:value="addName" @blur="() => saveGroup(item.data)" ref="inputRef" <j-input
:maxlength="64"></j-input> v-model:value="addName"
@blur="() => saveGroup(item.data)"
ref="inputRef"
:maxlength="64"
></j-input>
</div> </div>
<div class="treeItem" @click="() => selectGroup(item.data.id)" v-else> <div
class="treeItem"
@click="() => selectGroup(item.data.id)"
v-else
>
<template v-if="!item?.children"> <template v-if="!item?.children">
<div class="itemText"> <div class="itemText">
<Ellipsis style="width: calc(100%-100px)">{{ item.name }}</Ellipsis> <Ellipsis style="width: calc(100%-100px)">{{
item.name
}}</Ellipsis>
</div> </div>
<div @click="(e) => e.stopPropagation()" v-if="item.id !== 'default_group'"> <div
<PermissionButton type="text" hasPermission="system/Role:groupDelete" :popConfirm="{ @click="(e) => e.stopPropagation()"
v-if="item.id !== 'default_group'"
>
<PermissionButton
type="text"
hasPermission="system/Role:groupDelete"
:popConfirm="{
title: `确定要删除?`, title: `确定要删除?`,
onConfirm: () => deleteGroup(item.id), onConfirm: () => deleteGroup(item.id),
}" :disabled="item.id === 'default_group'"> }"
:disabled="item.id === 'default_group'"
>
删除 删除
</PermissionButton> </PermissionButton>
<PermissionButton type="text" hasPermission="system/Role:groupUpdate" <PermissionButton
@click="editGroup(item.data)" :disabled="item.id === 'default_group'"> type="text"
hasPermission="system/Role:groupUpdate"
@click="editGroup(item.data)"
:disabled="item.id === 'default_group'"
>
编辑 编辑
</PermissionButton> </PermissionButton>
</div> </div>
</template> </template>
<template v-else> <template v-else>
<Ellipsis style="width: calc(100%-100px)">{{ item.name }}</Ellipsis> <Ellipsis style="width: calc(100%-100px)">{{
item.name
}}</Ellipsis>
</template> </template>
</div> </div>
</template> </template>
</j-tree> </j-tree>
<j-empty v-else style="margin-top: 100px;" /> <j-empty v-else style="margin-top: 100px" />
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
import { queryRoleGroup, saveRoleGroup, deleteRoleGroup } from '@/api/system/role'; import {
queryRoleGroup,
saveRoleGroup,
deleteRoleGroup,
} from '@/api/system/role';
import { randomString } from '@/utils/utils'; import { randomString } from '@/utils/utils';
import { useUserInfo } from '@/store/userInfo'; import { useUserInfo } from '@/store/userInfo';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
const emit = defineEmits(['selectData']) const emit = defineEmits(['selectData']);
const userInfoStore = useUserInfo() const userInfoStore = useUserInfo();
const { userInfos } = storeToRefs(userInfoStore) const { userInfos } = storeToRefs(userInfoStore);
const admin = computed(() => { const admin = computed(() => {
return userInfos.value?.username === 'admin'; return userInfos.value?.username === 'admin';
}) });
const listData: any = ref([{ const listData: any = ref([
{
name: '全局角色', name: '全局角色',
id: 'global_role', id: 'global_role',
children: [] children: [],
}]) },
const selectedKeys = ref<string[]>(['global_role']) ]);
const searchValue = ref() const selectedKeys = ref<string[]>(['global_role']);
const inputRef = ref() const searchValue = ref();
const addName = ref() const inputRef = ref();
const selectId = ref() const addName = ref();
const selectId = ref();
const queryGroup = async (select?: Boolean, searchName?: string) => { const queryGroup = async (select?: Boolean, searchName?: string) => {
const params = searchName ? { sorts: [{ name: 'createTime', order: 'desc' }], terms: [{ terms: [{ value: '%' + searchName + '%', termType: 'like', column: 'name' }] }] } : { sorts: [{ name: 'createTime', order: 'desc' }] } const params = searchName
const req: any = await queryRoleGroup(params) ? {
sorts: [{ name: 'createTime', order: 'desc' }],
terms: [
{
terms: [
{
value: '%' + searchName + '%',
termType: 'like',
column: 'name',
},
],
},
],
}
: { sorts: [{ name: 'createTime', order: 'desc' }] };
const req: any = await queryRoleGroup(params);
if (req.status === 200) { if (req.status === 200) {
listData.value[0].children = req.result listData.value[0].children = req.result;
if(req.result[req.result.length - 1].id === 'default_group'){ if (req.result[req.result.length - 1].id === 'default_group') {
req.result.unshift(req.result[req.result.length - 1]) req.result.unshift(req.result[req.result.length - 1]);
req.result.pop() req.result.pop();
} }
// if(req.result.length && select){ // if(req.result.length && select){
// selectGroup(req.result[0].id) // selectGroup(req.result[0].id)
// } // }
} }
} };
const addGroup = () => { const addGroup = () => {
addName.value = '' addName.value = '';
const newId = randomString() const newId = randomString();
listData.value[0].children.splice(1, 0, ({ listData.value[0].children.splice(1, 0, {
name: '', name: '',
id: newId id: newId,
})) });
selectId.value = newId selectId.value = newId;
nextTick(() => { nextTick(() => {
inputRef.value.focus() inputRef.value.focus();
}) });
} };
const saveGroup = async (data: any) => { const saveGroup = async (data: any) => {
if (addName.value === '') { if (addName.value === '' ) {
listData.value[0].children.splice(1,1) if(data.name===''){
} else { listData.value[0].children.splice(1, 1);
}
}
else {
const saveData = { const saveData = {
name: addName.value, name: addName.value,
id: data.id id: data.id,
} };
const res = await saveRoleGroup(saveData) const res = await saveRoleGroup(saveData);
if (res.status === 200) { if (res.status === 200) {
onlyMessage('操作成功!') onlyMessage('操作成功!');
queryGroup() queryGroup();
} else { } else {
onlyMessage('操作失败!') onlyMessage('操作失败!');
} }
} }
setTimeout(()=>{ setTimeout(() => {
selectId.value = '' selectId.value = '';
},300) }, 300);
} };
const search = () => { const search = () => {
queryGroup(true, searchValue.value) queryGroup(true, searchValue.value);
} };
const searchChange = () => { const searchChange = () => {
if (searchValue.value === '') { if (searchValue.value === '') {
queryGroup() queryGroup();
} }
} };
const selectGroup = (id: string) => { const selectGroup = (id: string) => {
selectedKeys.value = [id] selectedKeys.value = [id];
id === 'global_role' ? emit('selectData', '') : emit('selectData', selectedKeys.value) id === 'global_role'
} ? emit('selectData', '')
: emit('selectData', selectedKeys.value);
};
const deleteGroup = async (id: string) => { const deleteGroup = async (id: string) => {
const res: any = await deleteRoleGroup(id) const res: any = await deleteRoleGroup(id);
if (res.status === 200) { if (res.status === 200) {
onlyMessage('操作成功!') onlyMessage('操作成功!');
queryGroup(true) queryGroup(true);
} else { } else {
onlyMessage('操作失败!') onlyMessage('操作失败!');
} }
} };
const editGroup = (data: any) => { const editGroup = (data: any) => {
if(!selectId.value){ if (!selectId.value) {
selectId.value = data.id selectId.value = data.id;
addName.value = data.name addName.value = data.name;
listData.value[0].children.forEach((item: any) => { listData.value[0].children.forEach((item: any) => {
if (item.id === data.id) { if (item.id === data.id) {
item.edit = true item.edit = true;
} }
}) });
nextTick(() => { nextTick(() => {
inputRef.value.focus() inputRef.value.focus();
}) });
} }
};
}
onMounted(() => { onMounted(() => {
queryGroup(true) queryGroup(true);
}) });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.controls { .controls {
@ -167,7 +229,7 @@ onMounted(() => {
.itemText { .itemText {
line-height: 32px; line-height: 32px;
max-width: 40% max-width: 40%;
} }
} }

View File

@ -145,7 +145,7 @@
class="more-button-item" class="more-button-item"
v-for="( v-for="(
item, index item, index
) in bindings" ) in bindings.slice(4,bindings.length-1)"
:key="index" :key="index"
@click=" @click="
handleClickOther( handleClickOther(