Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev

This commit is contained in:
JiangQiming 2023-03-28 16:08:21 +08:00
commit 0bef99ca88
22 changed files with 148 additions and 91 deletions

View File

@ -43,7 +43,7 @@ export const detail = (id: string) => server.get<ProductItem>(`/device-product/$
* *
* @param data * @param data
*/ */
export const category = (data: any) => server.post('/device/category/_tree', data) export const category = (data: any) => server.get('/device/category/_tree?paging=false', data)
/** /**
* *

View File

@ -42,9 +42,7 @@ import { getStreamingAggType } from '@/api/device/product'
const props = defineProps({ const props = defineProps({
value: { value: {
type: Object, type: Object,
default: () => ({ default: () => ({})
type: 'script',
})
}, },
name: { name: {
type: Array as PropType<(string| number)[]>, type: Array as PropType<(string| number)[]>,
@ -89,7 +87,7 @@ const changeWindow = (val: boolean | string | number) => {
props.value.window = {} props.value.window = {}
} }
} else { } else {
delete props.value.type props.value.type = 'script'
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<a-space align="end"> <j-space align="end">
<a-upload <j-upload
v-model:fileList="modelValue.upload" v-model:fileList="modelValue.upload"
name="file" name="file"
:action="FILE_UPLOAD" :action="FILE_UPLOAD"
@ -12,21 +12,22 @@
:showUploadList="false" :showUploadList="false"
@change="uploadChange" @change="uploadChange"
> >
<a-button> <j-button>
<template #icon><AIcon type="UploadOutlined" /></template> <template #icon><AIcon type="UploadOutlined" /></template>
文件上传 文件上传
</a-button> </j-button>
</a-upload> </j-upload>
<div style="margin-left: 20px"> <div style="margin-left: 20px">
<a-space> <j-space>
下载模板
<a @click="downFile('xlsx')">.xlsx</a> <a @click="downFile('xlsx')">.xlsx</a>
<a @click="downFile('csv')">.csv</a> <a @click="downFile('csv')">.csv</a>
</a-space> </j-space>
</div> </div>
</a-space> </j-space>
<div style="margin-top: 20px" v-if="importLoading"> <div style="margin-top: 20px" v-if="importLoading">
<a-badge v-if="flag" status="processing" text="进行中" /> <j-badge v-if="flag" status="processing" text="进行中" />
<a-badge v-else status="success" text="已完成" /> <j-badge v-else status="success" text="已完成" />
<span>总数量{{ count }}</span> <span>总数量{{ count }}</span>
<p style="color: red">{{ errMessage }}</p> <p style="color: red">{{ errMessage }}</p>
</div> </div>

View File

@ -99,8 +99,8 @@
@click="handleClick" @click="handleClick"
:active="_selectedRowKeys.includes(slotProps.id)" :active="_selectedRowKeys.includes(slotProps.id)"
class="card-box" class="card-box"
:status="getState(slotProps).value" :status="slotProps?.runningState?.value"
:statusText="getState(slotProps)?.text" :statusText="slotProps?.runningState?.text"
:statusNames="Object.fromEntries(colorMap.entries())" :statusNames="Object.fromEntries(colorMap.entries())"
> >
<template #title> <template #title>
@ -282,7 +282,7 @@ import BatchUpdate from './components/BatchUpdate/index.vue';
import SaveModBus from './Save/SaveModBus.vue'; 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, getState } from '../data.ts'; import { colorMap } from '../data.ts';
import { cloneDeep, isNumber } from 'lodash-es'; import { cloneDeep, isNumber } from 'lodash-es';
import { getWebSocket } from '@/utils/websocket'; import { getWebSocket } from '@/utils/websocket';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';

View File

@ -38,8 +38,14 @@
<j-tag <j-tag
class="tree-left-tag" class="tree-left-tag"
v-if="data.id !== '*'" v-if="data.id !== '*'"
:color="colorMap.get(getState(data)?.value)" :color="colorMap.get(data?.runningState?.value)"
>{{ getState(data)?.text }}</j-tag >{{ data?.runningState?.text }}</j-tag
>
<j-tag
class="tree-left-tag2"
v-if="data.id !== '*'"
:color="colorMap.get(data?.state?.value)"
>{{ data?.state?.text }}</j-tag
> >
<span <span
v-if="data.id !== '*'" v-if="data.id !== '*'"
@ -119,7 +125,7 @@ import Save from './Save/index.vue';
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
import { Store } from 'jetlinks-store'; import { Store } from 'jetlinks-store';
import _ from 'lodash'; import _ from 'lodash';
import { colorMap, getState } from '../data.ts'; import { colorMap } from '../data.ts';
const props = defineProps({ const props = defineProps({
data: { data: {
@ -285,7 +291,7 @@ watch(
<style lang="less" scoped> <style lang="less" scoped>
.tree-container { .tree-container {
padding-right: 24px; padding-right: 24px;
width: 350px; width: 370px;
.add-btn { .add-btn {
margin: 10px 0; margin: 10px 0;
@ -311,6 +317,11 @@ watch(
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.tree-left-tag2 {
width: 50px;
display: flex;
justify-content: center;
}
.func-btns { .func-btns {
// display: none; // display: none;
display: block; display: block;

View File

@ -4,6 +4,8 @@ colorMap.set('partialError', 'warning');
colorMap.set('failed', 'error'); colorMap.set('failed', 'error');
colorMap.set('stopped', 'default'); colorMap.set('stopped', 'default');
colorMap.set('processing', '#cccccc'); colorMap.set('processing', '#cccccc');
colorMap.set('enabled', 'processing');
colorMap.set('disabled', 'error');
export const getState = (record: any) => { export const getState = (record: any) => {
const enabled = record?.state?.value === 'enabled'; const enabled = record?.state?.value === 'enabled';

View File

@ -36,9 +36,9 @@ const changeTree = (row: any) => {
min-height: calc(100vh - 180px); min-height: calc(100vh - 180px);
width: 100%; width: 100%;
.left { .left {
width: 350px; width: 370px;
border-right: 1px #eeeeee solid; border-right: 1px #eeeeee solid;
margin: 10px; margin: 10px 10px 0 0;
} }
.right { .right {
flex: 1; flex: 1;

View File

@ -4,7 +4,6 @@
width="800px" width="800px"
:visible="true" :visible="true"
title="导入" title="导入"
@ok="handleSave"
@cancel="handleCancel" @cancel="handleCancel"
> >
<div style="margin-top: 10px"> <div style="margin-top: 10px">
@ -44,6 +43,9 @@
</j-row> </j-row>
</j-form> </j-form>
</div> </div>
<template #footer>
<j-button type="primary" @click="handleSave">关闭</j-button>
</template>
</j-modal> </j-modal>
</template> </template>
@ -100,6 +102,7 @@ const handleCancel = () => {
}; };
const handleSave = () => { const handleSave = () => {
emit('close');
emit('save'); emit('save');
}; };
</script> </script>

View File

@ -193,6 +193,8 @@ watch(
} }
}); });
Object.assign(modelRef, newValue); Object.assign(modelRef, newValue);
// description describe
modelRef.describe = newValue?.describe || newValue?.description
}, },
{ immediate: true, deep: true }, { immediate: true, deep: true },
); );

View File

@ -77,7 +77,7 @@
type="primary" type="primary"
:popConfirm="{ :popConfirm="{
title: `确定应用配置?`, title: `确定应用配置?`,
onConfirm: handleConfig, onConfirm: handleDeploy,
}" }"
:disabled="productStore.current?.state === 0" :disabled="productStore.current?.state === 0"
:tooltip=" :tooltip="

View File

@ -68,7 +68,11 @@
:tree-data="treeList" :tree-data="treeList"
@change="valueChange" @change="valueChange"
allow-clear allow-clear
:fieldNames="{ label: 'name', value: 'id' }" :fieldNames="{
label: 'name',
value: 'id',
children: 'children',
}"
:filterTreeNode=" :filterTreeNode="
(v, option) => filterSelectNode(v, option) (v, option) => filterSelectNode(v, option)
" "
@ -120,11 +124,7 @@ import { FILE_UPLOAD } from '@/api/comm';
import { isInput } from '@/utils/regular'; import { isInput } from '@/utils/regular';
import type { Rule } from 'ant-design-vue/es/form'; import type { Rule } from 'ant-design-vue/es/form';
import { queryProductId, addProduct, editProduct } from '@/api/device/product'; import { queryProductId, addProduct, editProduct } from '@/api/device/product';
import { import encodeQuery from '@/utils/encodeQuery';
SearchOutlined,
CheckOutlined,
DeleteOutlined,
} from '@ant-design/icons-vue';
const productStore = useProductStore(); const productStore = useProductStore();
const emit = defineEmits(['success']); const emit = defineEmits(['success']);
const props = defineProps({ const props = defineProps({
@ -246,14 +246,25 @@ const valueChange = (value: string, label: string) => {
* 查询产品分类 * 查询产品分类
*/ */
const queryProductTree = async () => { const queryProductTree = async () => {
category({ category(encodeQuery({ sorts: { sortIndex: 'asc' } })).then((resp) => {
paging: false,
}).then((resp) => {
if (resp.status === 200) { if (resp.status === 200) {
treeList.value = resp.result; treeList.value = resp.result;
treeList.value = dealProductTree(treeList.value);
} }
}); });
}; };
/**
* 处理产品分类key
*/
const dealProductTree = (arr: any) => {
return arr.map((element: any) => {
element.key = element.id;
if (element.children) {
element.children = dealProductTree(element.children);
}
return element
});
};
watch( watch(
() => props.isAdd, () => props.isAdd,
() => { () => {
@ -326,7 +337,7 @@ const submitData = () => {
// //
form.classifiedId form.classifiedId
? form.classifiedId ? form.classifiedId
: (form.classifiedId = ''); // : (form.classifiedId = ''); //
form.classifiedName form.classifiedName
? form.classifiedName ? form.classifiedName
: (form.classifiedName = ''); : (form.classifiedName = '');

View File

@ -117,11 +117,16 @@ const routeChange = async (id: string) => {
}); });
} }
} }
watch(
() => route.params.id, // watch(
(id) => routeChange(id as string), // () => route.params.id,
{ immediate: true } // (id) => routeChange(id as string),
) // { immediate: true }
// )
onMounted(() => {
routeChange(route.params.id as string)
})
watch( watch(
() => [props.visible, props.type], () => [props.visible, props.type],

View File

@ -110,9 +110,9 @@
}" }"
/> />
</template> </template>
<template #createTime="slotProps"> <template #registryTime="slotProps">
<span>{{ <span>{{
dayjs(slotProps.createTime).format('YYYY-MM-DD HH:mm:ss') dayjs(slotProps.registryTime).format('YYYY-MM-DD HH:mm:ss')
}}</span> }}</span>
</template> </template>
<template #action="slotProps"> <template #action="slotProps">

View File

@ -1021,7 +1021,9 @@
type="primary" type="primary"
@click="saveData" @click="saveData"
:loading="loading" :loading="loading"
:hasPermission="`link/Type:${id ? 'update' : 'add'}`" :hasPermission="`link/Type:${
id !== ':id' ? 'update' : 'add'
}`"
> >
保存 保存
</PermissionButton> </PermissionButton>
@ -1219,7 +1221,9 @@ const saveData = async () => {
loading.value = true; loading.value = true;
const resp: any = const resp: any =
id === ':id' ? await save(params) : await update({ ...params, id }); id === ':id'
? await save(params).catch(() => {})
: await update({ ...params, id }).catch(() => {});
loading.value = false; loading.value = false;
if (resp?.status === 200) { if (resp?.status === 200) {
onlyMessage('操作成功', 'success'); onlyMessage('操作成功', 'success');

View File

@ -22,7 +22,7 @@
<PermissionButton <PermissionButton
type="primary" type="primary"
@click="add" @click="add"
hasPermission="device/Instance:add" hasPermission="rule-engine/Alarm/Configuration:add"
> >
<template #icon <template #icon
><AIcon type="PlusOutlined" ><AIcon type="PlusOutlined"
@ -82,7 +82,7 @@
<PermissionButton <PermissionButton
:disabled="item.disabled" :disabled="item.disabled"
:popConfirm="item.popConfirm" :popConfirm="item.popConfirm"
:tooltip="{ ...item.tootip }" :tooltip="{ ...item.tooltip }"
@click="item.onClick" @click="item.onClick"
:hasPermission=" :hasPermission="
'rule-engine/Alarm/Configuration:' + 'rule-engine/Alarm/Configuration:' +

View File

@ -287,7 +287,7 @@ const orgCol = [
}, },
]; ];
let params:any = ref({ let params: any = ref({
sorts: [{ name: 'alarmTime', order: 'desc' }], sorts: [{ name: 'alarmTime', order: 'desc' }],
terms: [], terms: [],
}); });
@ -369,7 +369,10 @@ const getActions = (
key: 'solve', key: 'solve',
text: '告警处理', text: '告警处理',
tooltip: { tooltip: {
title: '告警处理', title:
currentData.state?.value === 'normal'
? '无告警'
: '告警处理',
}, },
icon: 'ToolOutlined', icon: 'ToolOutlined',
onClick: () => { onClick: () => {
@ -432,14 +435,14 @@ const closeLog = () => {
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.content-left{ .content-left {
border-right: .2px solid rgba(0,0,0,0.2); border-right: 0.2px solid rgba(0, 0, 0, 0.2);
} }
.content-right-title{ .content-right-title {
color: #666; color: #666;
font-size: 12px font-size: 12px;
} }
.content-left-title{ .content-left-title {
font-size: 18px font-size: 18px;
} }
</style> </style>

View File

@ -12,7 +12,7 @@
placeholder="请输入时间" placeholder="请输入时间"
v-model:value="_value" v-model:value="_value"
:precision="3" :precision="3"
:min="0" :min="0.001"
:max="65535" :max="65535"
> >
<template #addonAfter> <template #addonAfter>
@ -60,8 +60,8 @@ const unit = ref<'seconds' | 'minutes' | 'hours'>(
watch( watch(
() => props.value, () => props.value,
(newVal) => { (newVal) => {
_value.value = newVal?.time || 0 _value.value = newVal?.time || 0;
unit.value = newVal?.unit || 'seconds' unit.value = newVal?.unit || 'seconds';
}, },
{ {
immediate: true, immediate: true,
@ -73,17 +73,21 @@ const onCancel = () => {
emit('cancel'); emit('cancel');
}; };
const onOk = () => { const onOk = () => {
if (unref(_value) || unref(_value) === 0) { if (unref(_value)) {
emit(
'save',
{
time: _value.value,
unit: unit.value,
},
{
name: `${_value.value} ${
timeUnitEnum[unit.value]
}执行后续动作`,
},
);
} else { } else {
onlyMessage('请输入时间', 'error'); onlyMessage('请输入时间', 'error');
} }
emit(
'save',
{
time: _value.value,
unit: unit.value,
},
{ name: `${_value.value} ${timeUnitEnum[unit.value]}后,执行后续动作` },
);
}; };
</script> </script>

View File

@ -172,9 +172,8 @@ const handleClick = (_detail: any) => {
}; };
watch(() => props.value?.[0]?.value, (newVal) => { watch(() => props.value?.[0]?.value, (newVal) => {
console.log(newVal, '123')
if(newVal){ if(newVal){
detail(newVal[0]?.value).then(resp => { detail(newVal).then(resp => {
emit('change', resp.result); emit('change', resp.result);
}) })
} }

View File

@ -99,7 +99,7 @@ const handleItem = (data: any) => {
valueType: data.valueType ? data.valueType.type : '-', valueType: data.valueType ? data.valueType.type : '-',
format: data.valueType ? data.valueType.format : undefined, format: data.valueType ? data.valueType.format : undefined,
options: data.valueType ? data.valueType.elements : undefined, options: data.valueType ? data.valueType.elements : undefined,
value: data.value, value: data?.value,
}; };
}; };
@ -135,9 +135,9 @@ watch(
options.value = newTag.map((item: any) => { options.value = newTag.map((item: any) => {
return { label: item.name, value: item.id, ...item }; return { label: item.name, value: item.id, ...item };
}); });
if (newVal && newVal[0] && newVal[0].name && newTag && newTag.length) { if (newVal && newVal[0] && newVal[0]?.name && newTag && newTag.length) {
const names: string[] = []; const names: string[] = [];
const newTagList = newVal[0].value const newTagList = newVal[0]?.value
.filter((valueItem: any) => { .filter((valueItem: any) => {
return newTag.some( return newTag.some(
(item: any) => valueItem.column === item.id, (item: any) => valueItem.column === item.id,
@ -151,8 +151,8 @@ watch(
names.push(oldItem.name); names.push(oldItem.name);
return { return {
...handleItem(oldItem), ...handleItem(oldItem),
value: valueItem.value, value: valueItem?.value,
type: valueItem.type, type: valueItem?.type,
}; };
} }
return valueItem; return valueItem;
@ -169,12 +169,12 @@ watch(
); );
const onValueChange = () => { const onValueChange = () => {
const _data = tagList.value.filter((item) => !!item.value); const _data = tagList.value.filter((item) => !!item?.value);
const newValue = _data.map((item: any) => { const newValue = _data.map((item: any) => {
return { return {
column: item.id, column: item.id,
type: item.type, type: item?.type,
value: item.value, value: item?.value,
}; };
}); });
emits('update:value', [{ value: newValue, name: '标签' }]); emits('update:value', [{ value: newValue, name: '标签' }]);

View File

@ -77,10 +77,10 @@
钉钉 钉钉
</span> </span>
<span class="notify-text-highlight">{{ <span class="notify-text-highlight">{{
options?.orgName || '' options?.sendTo || ''
}}</span> }}</span>
<span class="notify-text-highlight">{{ <span class="notify-text-highlight">{{
options?.sendTo || '' options?.orgName || ''
}}</span> }}</span>
发送 发送
<span class="notify-text-highlight"> <span class="notify-text-highlight">
@ -107,10 +107,10 @@
微信 微信
</span> </span>
<span class="notify-text-highlight">{{ <span class="notify-text-highlight">{{
options?.orgName || '' options?.sendTo || ''
}}</span> }}</span>
<span class="notify-text-highlight">{{ <span class="notify-text-highlight">{{
options?.sendTo || '' options?.orgName || ''
}}</span> }}</span>
<span class="notify-text-highlight">{{ <span class="notify-text-highlight">{{
options?.tagName || '' options?.tagName || ''

View File

@ -44,7 +44,12 @@
v-else-if="getType(item) === 'link'" v-else-if="getType(item) === 'link'"
v-model:value="modelRef[item.id]" v-model:value="modelRef[item.id]"
/> />
<BuildIn v-else :item="item" v-model:value="modelRef[item.id]" /> <BuildIn
v-else
:item="item"
v-model:value="modelRef[item.id]"
@change="(val) => onChange(val, 'build-in')"
/>
</j-form-item> </j-form-item>
</j-form> </j-form>
</template> </template>
@ -79,7 +84,6 @@ const formRef = ref();
const modelRef = reactive({}); const modelRef = reactive({});
watchEffect(() => { watchEffect(() => {
console.log(props?.value)
Object.assign(modelRef, props?.value); Object.assign(modelRef, props?.value);
}); });
@ -88,6 +92,9 @@ const getType = (item: any) => {
}; };
const checkValue = (_rule: any, value: any, item: any) => { const checkValue = (_rule: any, value: any, item: any) => {
if(!value){
return Promise.resolve();
}
const type = item.expands?.businessType || item?.type; const type = item.expands?.businessType || item?.type;
if (type === 'file') { if (type === 'file') {
return Promise.resolve(); return Promise.resolve();
@ -153,7 +160,7 @@ const checkValue = (_rule: any, value: any, item: any) => {
if ( if (
props.notify.notifyType && props.notify.notifyType &&
['sms', 'voice'].includes(props?.notify?.notifyType) && ['sms', 'voice'].includes(props?.notify?.notifyType) &&
value?.source !== 'relation' value?.source !== 'relation' && value?.value
) { ) {
const reg = /^[1][3-9]\d{9}$/; const reg = /^[1][3-9]\d{9}$/;
if (!reg.test(value?.value)) { if (!reg.test(value?.value)) {
@ -173,6 +180,8 @@ const onChange = (val: any, type: any) => {
emit('change', { tagName: val }); emit('change', { tagName: val });
} else if (type === 'user') { } else if (type === 'user') {
emit('change', { sendTo: val }); emit('change', { sendTo: val });
} else if (type === 'build-in') {
// emit('change', { sendTo: val });
} }
}; };

View File

@ -16,12 +16,14 @@
placeholder="请选择参数" placeholder="请选择参数"
style="width: calc(100% - 120px)" style="width: calc(100% - 120px)"
:fieldNames="{ label: 'name', value: 'id' }" :fieldNames="{ label: 'name', value: 'id' }"
@change="(val) => itemOnChange(undefined, val)" @change="(val, label) => itemOnChange(undefined, val, label)"
> >
<template #title="{ fullName, description }"> <template #title="{ fullName, description }">
<j-space> <j-space>
{{ fullName }} {{ fullName }}
<span style="color: grey; margin-left: 5px">{{ description }}</span> <span style="color: grey; margin-left: 5px">{{
description
}}</span>
</j-space> </j-space>
</template> </template>
</j-tree-select> </j-tree-select>
@ -84,7 +86,7 @@ const props = defineProps({
}, },
}); });
const emit = defineEmits(['update:value']); const emit = defineEmits(['update:value', 'change']);
const source = computed(() => { const source = computed(() => {
return props.value?.source || 'fixed'; return props.value?.source || 'fixed';
@ -97,15 +99,18 @@ const sourceChange = (val: any) => {
emit('update:value', { emit('update:value', {
...props.value, ...props.value,
source: val, source: val,
value: undefined value: undefined,
}); });
}; };
const itemOnChange = (val: any, _upperKey?: string) => { const itemOnChange = (val: any, _upperKey?: string, label?: any) => {
emit('update:value', { emit('update:value', {
...props.value, ...props.value,
value: val, value: val,
upperKey: _upperKey upperKey: _upperKey,
});
emit('change', {
sendTo: label?.[0] || val,
}); });
}; };
@ -164,7 +169,7 @@ watch(
watch( watch(
() => props.value.upperKey, () => props.value.upperKey,
(newVal) => { (newVal) => {
upperKey.value = newVal upperKey.value = newVal;
}, },
{ immediate: true }, { immediate: true },
); );