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

This commit is contained in:
JiangQiming 2023-03-23 21:00:30 +08:00
commit 4578810ab9
33 changed files with 271 additions and 185 deletions

View File

@ -48,7 +48,7 @@ export const category = (data: any) => server.post('/device/category/_tree', dat
/** /**
* *
*/ */
export const getProviders = () => server.get('/gateway/device/providers') export const getProviders = (terms?:any) => server.get('/gateway/device/providers',terms)
/** /**
* *

View File

@ -108,4 +108,29 @@ export const onlyMessage = (msg: string, type: 'success' | 'error' | 'warning' =
content: msg, content: msg,
key: type key: type
}) })
}
export interface SearchItemData {
column: any;
value: any;
termType: string;
type?: string;
}
export const handleParamsToString = (terms:SearchItemData[] = []) => {
const _terms: any[] = [
{ terms: [null,null,null]},
{ terms: [null,null,null]}
]
let termsIndex = 0
let termsStar = 0
terms.forEach((item, index) => {
if (index > 2) {
termsIndex = 1
termsStar = 4
}
_terms[termsIndex].terms[index - termsStar ] = item
})
return JSON.stringify({ terms: _terms})
} }

View File

@ -118,6 +118,16 @@ export const postStream = function(url: string, data={}, params = {}) {
}) })
} }
const showNotification = ( message: string, description: string, key?: string, show: boolean = true ) => {
if (show) {
Notification.error({
key,
message,
description
})
}
}
/** /**
* *
* @param {Object} error * @param {Object} error
@ -128,44 +138,19 @@ const errorHandler = (error: any) => {
const data = error.response.data const data = error.response.data
const status = error.response.status const status = error.response.status
if (status === 403) { if (status === 403) {
Notification.error({ showNotification( 'Forbidden', (data.message + '').substr(0, 90), '403')
key: '403',
message: 'Forbidden',
description: (data.message + '').substr(0, 90)
})
setTimeout(() => {
router.push({
name: 'Exception403'
})
}, 0)
} else if (status === 500) { } else if (status === 500) {
Notification.error({ showNotification( 'Server Side Error', (data.message + '').substr(0, 90), '500')
key: '500',
message: 'Server Side Error',
description: (data.message + '').substr(0, 90)
})
} else if (status === 400) { } else if (status === 400) {
Notification.error({ showNotification( 'Request Error', (data.message + '').substr(0, 90), '400')
key: '400',
message: 'Request Error',
description: (data.message + '').substr(0, 90)
})
} else if (status === 401) { } else if (status === 401) {
Notification.error({ showNotification( 'Unauthorized', '用户未登录', '401')
key: '401',
message: 'Unauthorized',
description: '用户未登录'
})
setTimeout(() => { setTimeout(() => {
location.href = `/#${LoginPath}` location.href = `/#${LoginPath}`
}, 0) }, 0)
} }
} else if (error.response === undefined) { } else if (error.response === undefined) {
Notification.error({ showNotification( error.message, (error.stack + '').substr(0, 90), undefined)
message: error.message,
description: (error.stack + '').substr(0, 90)
})
} }
return Promise.reject(error) return Promise.reject(error)
} }

View File

@ -37,6 +37,7 @@
:status="getState(slotProps).value" :status="getState(slotProps).value"
:statusText="getState(slotProps).text" :statusText="getState(slotProps).text"
:statusNames="StatusColorEnum" :statusNames="StatusColorEnum"
@click="handlEye(slotProps.id)"
> >
<template #img> <template #img>
<slot name="img"> <slot name="img">
@ -48,8 +49,9 @@
<Ellipsis style="width: calc(100% - 100px)"> <Ellipsis style="width: calc(100% - 100px)">
<span <span
style=" style="
font-size: 16px; font-size: 18px;
font-weight: 600; font-weight: 800;
line-height: 22px;
" "
> >
{{ slotProps.name }} {{ slotProps.name }}
@ -276,6 +278,9 @@ const handlEdit = (data: object) => {
current.value = _.cloneDeep(data); current.value = _.cloneDeep(data);
visible.value = true; visible.value = true;
}; };
const handlEye = (id: string) => {
menuStory.jumpPage(`DataCollect/Collector`, {}, { channelId: id });
};
const saveChange = (value: object) => { const saveChange = (value: object) => {
visible.value = false; visible.value = false;
current.value = {}; current.value = {};

View File

@ -81,6 +81,7 @@
? '正常的采集器不能删除' ? '正常的采集器不能删除'
: '删除', : '删除',
}" }"
:danger="data?.state?.value === 'disabled'"
hasPermission="DataCollect/Collector:delete" hasPermission="DataCollect/Collector:delete"
:popConfirm="{ :popConfirm="{
title: `该操作将会删除下属点位,确定删除?`, title: `该操作将会删除下属点位,确定删除?`,
@ -253,7 +254,7 @@ watch(
<style lang="less" scoped> <style lang="less" scoped>
.tree-container { .tree-container {
padding-right: 24px; padding-right: 24px;
width: 300px; width: 350px;
.add-btn { .add-btn {
margin: 10px 0; margin: 10px 0;

View File

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

View File

@ -265,6 +265,7 @@ const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
const column = { const column = {
username: 'context.username', username: 'context.username',
description: 'action',
}; };
/** /**

View File

@ -31,10 +31,11 @@
<script setup lang="ts" name="FileUpload"> <script setup lang="ts" name="FileUpload">
import { LocalStore } from '@/utils/comm'; import { LocalStore } from '@/utils/comm';
import { TOKEN_KEY } from '@/utils/variable'; import { TOKEN_KEY } from '@/utils/variable';
import { FIRMWARE_UPLOAD, querySystemApi } from '@/api/device/firmware'; import { FIRMWARE_UPLOAD } from '@/api/device/firmware';
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
import type { UploadChangeParam } from 'ant-design-vue'; import type { UploadChangeParam } from 'ant-design-vue';
import { notification as Notification } from 'ant-design-vue'; import { notification as Notification } from 'ant-design-vue';
import { useSystem } from '@/store/system';
const emit = defineEmits(['update:modelValue', 'update:extraValue', 'change']); const emit = defineEmits(['update:modelValue', 'update:extraValue', 'change']);
@ -45,6 +46,10 @@ const props = defineProps({
}, },
}); });
const paths: string = useSystem().$state.configInfo.paths?.[
'base-path'
] as string;
const fileValue = ref(props.modelValue); const fileValue = ref(props.modelValue);
const loading = ref(false); const loading = ref(false);
@ -53,11 +58,9 @@ const handleChange = async (info: UploadChangeParam) => {
if (info.file.status === 'done') { if (info.file.status === 'done') {
loading.value = false; loading.value = false;
const result = info.file.response?.result; const result = info.file.response?.result;
const api: any = await querySystemApi(['paths']); // todo base-pathpinia const f = `${paths || ''}/file/${result.id}?accessKey=${
const path = api.result[0]?.properties result.others.accessKey
? api.result[0]?.properties['base-path'] }`;
: '';
const f = `${path}/file/${result.id}?accessKey=${result.others.accessKey}`;
onlyMessage('上传成功!', 'success'); onlyMessage('上传成功!', 'success');
fileValue.value = f; fileValue.value = f;
emit('update:modelValue', f); emit('update:modelValue', f);

View File

@ -38,8 +38,8 @@
selectedRowKeys: _selectedRowKeys, selectedRowKeys: _selectedRowKeys,
onSelect: onSelectChange, onSelect: onSelectChange,
onSelectAll: onSelectAllChange, onSelectAll: onSelectAllChange,
onChange: onChange,
}" }"
@cancelSelect="cancelSelect"
:params="params" :params="params"
> >
<template #headerTitle> <template #headerTitle>
@ -125,7 +125,7 @@ const defaultParams = {
}; };
const statusMap = new Map(); const statusMap = new Map();
statusMap.set('online', 'success'); statusMap.set('online', 'processing');
statusMap.set('offline', 'error'); statusMap.set('offline', 'error');
statusMap.set('notActive', 'warning'); statusMap.set('notActive', 'warning');
@ -223,8 +223,10 @@ const getSelectedRowsKey = (selectedRows: T[]) =>
const getSetRowKey = (selectedRows: T[]) => const getSetRowKey = (selectedRows: T[]) =>
new Set([..._selectedRowKeys.value, ...getSelectedRowsKey(selectedRows)]); new Set([..._selectedRowKeys.value, ...getSelectedRowsKey(selectedRows)]);
const cancelSelect = () => { const onChange = (selectedRowKeys: T[]) => {
_selectedRowKeys.value = []; if (selectedRowKeys.length === 0) {
_selectedRowKeys.value = [];
}
}; };
const handleOk = () => { const handleOk = () => {
@ -249,7 +251,7 @@ const onVisible = () => {
const handleCancel = () => { const handleCancel = () => {
visible.value = false; visible.value = false;
cancelSelect(); _selectedRowKeys.value = [];
}; };
onMounted(() => { onMounted(() => {

View File

@ -51,6 +51,7 @@
style="padding: 0px" style="padding: 0px"
@click="i.onClick" @click="i.onClick"
type="link" type="link"
:danger="i.key === 'delete'"
:hasPermission="'device/Firmware:' + i.key" :hasPermission="'device/Firmware:' + i.key"
> >
<template #icon <template #icon
@ -68,7 +69,6 @@
<script lang="ts" setup name="FirmwarePage"> <script lang="ts" setup name="FirmwarePage">
import type { ActionsType } from '@/components/Table/index'; import type { ActionsType } from '@/components/Table/index';
import { query, queryProduct, remove } from '@/api/device/firmware'; import { query, queryProduct, remove } from '@/api/device/firmware';
import { message } from 'ant-design-vue';
import moment from 'moment'; import moment from 'moment';
import _ from 'lodash'; import _ from 'lodash';
import Save from './Save/index.vue'; import Save from './Save/index.vue';

View File

@ -418,6 +418,8 @@ import { marked } from 'marked';
import type { TableColumnType } from 'ant-design-vue'; import type { TableColumnType } from 'ant-design-vue';
import { useMenuStore } from '@/store/menu'; import { useMenuStore } from '@/store/menu';
import _ from 'lodash'; import _ from 'lodash';
import encodeQuery from '@/utils/encodeQuery';
const tableRef = ref(); const tableRef = ref();
const formRef = ref(); const formRef = ref();
const menuStore = useMenuStore(); const menuStore = useMenuStore();
@ -501,14 +503,15 @@ const query = reactive({
return new Promise((res) => { return new Promise((res) => {
getProviders().then((resp: any) => { getProviders().then((resp: any) => {
listData.value = []; listData.value = [];
console.log(description.value);
if (isNoCommunity) { if (isNoCommunity) {
listData.value = (resp?.result || []).map( (resp?.result || []).map((item: any) => {
(item: any) => ({ if (item.id != 'plugin_gateway') {
label: item.name, listData.value.push({
value: item.id, label: item.name,
}), value: item.id,
); });
}
});
} else { } else {
listData.value = (resp?.result || []) listData.value = (resp?.result || [])
.filter((i: any) => .filter((i: any) =>
@ -568,17 +571,7 @@ const query = reactive({
}); });
const param = ref<Record<string, any>>({ const param = ref<Record<string, any>>({
pageSize: 4, pageSize: 4,
terms: [ terms: [],
{
terms: [
{
column: 'channel',
termType: 'nin',
value: 'plugin',
},
],
},
],
}); });
const queryParams = ref<Record<string, any>>({}); const queryParams = ref<Record<string, any>>({});
/** /**
@ -1085,10 +1078,10 @@ nextTick(() => {
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 12px;
} }
.changeBtn{ .changeBtn {
margin: 0 0 0 20px; margin: 0 0 0 20px;
color: #315EFB; color: #315efb;
background: #ffffff; background: #ffffff;
border: 1px solid #315EFB border: 1px solid #315efb;
} }
</style> </style>

View File

@ -111,7 +111,7 @@ import {
getProtocolDetail, getProtocolDetail,
} from '@/api/device/product'; } from '@/api/device/product';
import { message } from 'jetlinks-ui-components'; import { message } from 'jetlinks-ui-components';
import { getImage } from '@/utils/comm'; import { getImage, handleParamsToString } from '@/utils/comm'
import encodeQuery from '@/utils/encodeQuery'; import encodeQuery from '@/utils/encodeQuery';
import { useMenuStore } from '@/store/menu'; import { useMenuStore } from '@/store/menu';
@ -286,7 +286,7 @@ const jumpDevice = () => {
{}, {},
{ {
target: 'device-instance', target: 'device-instance',
q: JSON.stringify({ terms: [{ terms: [{ searchParams }] }] }), q: handleParamsToString([searchParams]),
}, },
); );
}; };

View File

@ -447,12 +447,14 @@ const query = reactive({
listData.value = []; listData.value = [];
// const list = () => { // const list = () => {
if (isNoCommunity) { if (isNoCommunity) {
listData.value = (resp?.result || []).map( (resp?.result || []).map((item: any) => {
(item: any) => ({ if (item.id != 'plugin_gateway') {
label: item.name, listData.value.push({
value: item.id, label: item.name,
}), value: item.id,
); });
}
});
} else { } else {
listData.value = (resp?.result || []) listData.value = (resp?.result || [])
.filter((i: any) => .filter((i: any) =>

View File

@ -482,6 +482,7 @@
type="primary" type="primary"
style="margin-right: 8px" style="margin-right: 8px"
@click="saveData" @click="saveData"
:loading="loading"
:hasPermission="`link/AccessConfig:${ :hasPermission="`link/AccessConfig:${
id === ':id' ? 'add' : 'update' id === ':id' ? 'add' : 'update'
}`" }`"
@ -534,7 +535,7 @@ const props = defineProps({
const route = useRoute(); const route = useRoute();
const view = route.query.view as string; const view = route.query.view as string;
const id = route.params.id as string; const id = route.params.id as string;
const loading = ref(false);
const activeKey: any = ref([]); const activeKey: any = ref([]);
const clientHeight = document.body.clientHeight; const clientHeight = document.body.clientHeight;
@ -638,10 +639,17 @@ const saveData = () => {
transport: 'SIP', transport: 'SIP',
channel: 'gb28181', channel: 'gb28181',
}; };
params.configuration.sipId = Number(params.configuration?.sipId); loading.value = true;
const resp = const resp =
id === ':id' ? await save(params) : await update({ ...params, id }); id === ':id'
if (resp.status === 200) { ? await save(params).catch(() => {
loading.value = false;
})
: await update({ ...params, id }).catch(() => {
loading.value = false;
});
if (resp?.status === 200) {
onlyMessage('操作成功', 'success'); onlyMessage('操作成功', 'success');
history.back(); history.back();
} }
@ -667,12 +675,14 @@ const next = async () => {
...data1, ...data1,
...data2, ...data2,
}; };
} else {
return onlyMessage('请新增或完善配置', 'error');
} }
current.value = current.value + 1; current.value = current.value + 1;
params.configuration = data1; params.configuration = data1;
}) })
.catch((err) => { .catch((err) => {
err.errorFields.forEach((item: any) => { err.errorFields?.forEach((item: any) => {
const activeId: any = const activeId: any =
dynamicValidateForm.cluster[item.name[1]].id; dynamicValidateForm.cluster[item.name[1]].id;
if (!activeKey.value.includes(activeId)) { if (!activeKey.value.includes(activeId)) {
@ -680,10 +690,24 @@ const next = async () => {
} }
}); });
}); });
} else {
current.value = current.value + 1;
params.configuration = data1;
} }
}; };
const prev = () => { const prev = () => {
current.value = current.value - 1; current.value = current.value - 1;
develop();
};
const develop = () => {
if (dynamicValidateForm.cluster.length !== 0) {
dynamicValidateForm.cluster.forEach((item) => {
const id: any = JSON.stringify(Date.now() + Math.random());
item.id = id;
activeKey.value.push(id);
});
}
}; };
onMounted(() => { onMounted(() => {
@ -723,21 +747,13 @@ onMounted(() => {
const { configuration, name, description = '' } = props.data; const { configuration, name, description = '' } = props.data;
formData.value = { name, description }; formData.value = { name, description };
if (configuration?.shareCluster) { formState.value = {
formState.value = { ...formState.value,
...formState.value, ...props.data.configuration,
...props.data.configuration, };
}; if (!configuration?.shareCluster) {
} else {
formState.value = {
...formState.value,
...props.data.configuration,
};
dynamicValidateForm.cluster = configuration.cluster; dynamicValidateForm.cluster = configuration.cluster;
if (dynamicValidateForm.cluster.length === 1) { develop();
activeKey.value = ['1'];
dynamicValidateForm.cluster[0].id = 1;
}
} }
} }
}); });

View File

@ -13,6 +13,17 @@
:request="list" :request="list"
:defaultParams="{ :defaultParams="{
sorts: [{ name: 'createTime', order: 'desc' }], sorts: [{ name: 'createTime', order: 'desc' }],
terms: [
{
terms: [
{
termType: 'nin',
column: 'provider',
value: 'plugin_gateway', //todo
},
],
},
],
}" }"
gridColumn="2" gridColumn="2"
:gridColumns="[1, 2]" :gridColumns="[1, 2]"
@ -40,6 +51,7 @@
enabled: 'processing', enabled: 'processing',
disabled: 'error', disabled: 'error',
}" }"
@click="handlEye(slotProps.id)"
> >
<template #img> <template #img>
<slot name="img"> <slot name="img">
@ -52,13 +64,9 @@
style=" style="
width: calc(100% - 100px); width: calc(100% - 100px);
margin-bottom: 20px; margin-bottom: 20px;
color: #2f54eb;
" "
> >
<span <span class="card-title">
class="card-title"
@click.stop="handlEye(slotProps.id)"
>
{{ slotProps.name }} {{ slotProps.name }}
</span> </span>
</Ellipsis> </Ellipsis>
@ -310,10 +318,12 @@ 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 = (res?.result || [])?.map((item: any) => ({ providersOptions.value = (res?.result || [])
label: item.name, ?.map((item: any) => ({
value: item.id, label: item.name,
})); value: item.id,
}))
.filter((item: any) => item.value !== 'plugin_gateway'); // todo
}; };
getProvidersList(); getProvidersList();

View File

@ -41,7 +41,7 @@
<CertificateFile <CertificateFile
name="cert" name="cert"
v-model:modelValue="formData.configs.cert" v-model:modelValue="formData.configs.cert"
placeholder='证书格式以"-----BEGIN CERTIFICATE-----"开头,以"-----END CERTIFICATE-----"结尾"' placeholder="请输入证书文件"
/> />
</j-form-item> </j-form-item>
<j-form-item <j-form-item
@ -51,7 +51,7 @@
<CertificateFile <CertificateFile
name="key" name="key"
v-model:modelValue="formData.configs.key" v-model:modelValue="formData.configs.key"
placeholder='证书私钥格式以"-----BEGIN (RSA|EC) PRIVATE KEY-----"开头,以"-----END(RSA|EC) PRIVATE KEY-----"结尾。' placeholder="请输入证书私钥"
/> />
</j-form-item> </j-form-item>
<j-form-item label="说明" name="description"> <j-form-item label="说明" name="description">

View File

@ -44,6 +44,7 @@
style="padding: 0px" style="padding: 0px"
@click="i.onClick" @click="i.onClick"
type="link" type="link"
:danger="i.key === 'delete'"
:hasPermission="'link/Certificate:' + i.key" :hasPermission="'link/Certificate:' + i.key"
> >
<template #icon <template #icon
@ -96,6 +97,7 @@ const columns = [
ellipsis: true, ellipsis: true,
search: { search: {
type: 'string', type: 'string',
first: true,
}, },
}, },
{ {

View File

@ -75,8 +75,6 @@ const pickerTimeChange = () => {
const getCPUEcharts = async (val: any) => { const getCPUEcharts = async (val: any) => {
loading.value = true; loading.value = true;
console.log(224, val);
const res: any = await dashboard(defulteParamsData('cpu', val)); const res: any = await dashboard(defulteParamsData('cpu', val));
if (res.success) { if (res.success) {
const _cpuOptions = {}; const _cpuOptions = {};

View File

@ -114,8 +114,8 @@ const getNetworkEcharts = async (val: any) => {
loading.value = false; loading.value = false;
}, 300); }, 300);
}; };
const networkValueRender = (obj: any) => {
const { value } = obj; const formatterData = (value: any) => {
let _data = ''; let _data = '';
if (value >= 1024 && value < 1024 * 1024) { if (value >= 1024 && value < 1024 * 1024) {
_data = `${Number((value / 1024).toFixed(2))}KB`; _data = `${Number((value / 1024).toFixed(2))}KB`;
@ -124,7 +124,14 @@ const networkValueRender = (obj: any) => {
} else { } else {
_data = `${value}B`; _data = `${value}B`;
} }
return `${obj?.axisValueLabel}<br />${obj?.marker}${obj?.seriesName}: ${_data}`; return _data;
};
const networkValueRender = (obj: any) => {
const { value } = obj;
return `${obj?.axisValueLabel}<br />${obj?.marker}${
obj?.seriesName
} &nbsp; ${formatterData(value)}`;
}; };
const setOptions = (data: any, key: string) => ({ const setOptions = (data: any, key: string) => ({
@ -149,9 +156,12 @@ const handleNetworkOptions = (optionsData: any, xAxis: any) => {
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
axisLabel: {
formatter: (_value: any) => formatterData(_value),
},
}, },
grid: { grid: {
left: '100px', left: '70px',
right: '50px', right: '50px',
}, },
tooltip: { tooltip: {

View File

@ -27,10 +27,11 @@
<script setup lang="ts" name="FileUpload"> <script setup lang="ts" name="FileUpload">
import { LocalStore } from '@/utils/comm'; import { LocalStore } from '@/utils/comm';
import { TOKEN_KEY } from '@/utils/variable'; import { TOKEN_KEY } from '@/utils/variable';
import { PROTOCOL_UPLOAD, querySystemApi } from '@/api/link/protocol'; import { PROTOCOL_UPLOAD } from '@/api/link/protocol';
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
import type { UploadChangeParam, UploadProps } from 'ant-design-vue'; import type { UploadChangeParam, UploadProps } from 'ant-design-vue';
import { notification as Notification } from 'ant-design-vue'; import { notification as Notification } from 'ant-design-vue';
import { useSystem } from '@/store/system';
const emit = defineEmits(['update:modelValue', 'change']); const emit = defineEmits(['update:modelValue', 'change']);
@ -41,6 +42,10 @@ const props = defineProps({
}, },
}); });
const paths: string = useSystem().$state.configInfo.paths?.[
'base-path'
] as string;
const value = ref(props.modelValue); const value = ref(props.modelValue);
const loading = ref(false); const loading = ref(false);
@ -58,11 +63,9 @@ const handleChange = async (info: UploadChangeParam) => {
if (info.file.status === 'done') { if (info.file.status === 'done') {
loading.value = false; loading.value = false;
const result = info.file.response?.result; const result = info.file.response?.result;
const api: any = await querySystemApi(['paths']); // todo base-pathpinia const f = `${paths || ''}/file/${result.id}?accessKey=${
const path = api.result[0]?.properties result.others.accessKey
? api.result[0]?.properties['base-path'] }`;
: '';
const f = `${path}/file/${result.id}?accessKey=${result.others.accessKey}`;
onlyMessage('上传成功!', 'success'); onlyMessage('上传成功!', 'success');
value.value = f; value.value = f;
emit('update:modelValue', f); emit('update:modelValue', f);

View File

@ -37,6 +37,7 @@
:disabled="!!id" :disabled="!!id"
v-model:value="formData.type" v-model:value="formData.type"
:options="options" :options="options"
:column="2"
@change="changeType" @change="changeType"
/> />
</j-form-item> </j-form-item>

View File

@ -103,18 +103,6 @@
:key="cluster.id" :key="cluster.id"
:show-arrow="!formData.shareCluster" :show-arrow="!formData.shareCluster"
> >
<!-- <j-collapse-panel
:key="cluster.id"
:header="
cluster.serverId
? cluster.serverId
: !formData.shareCluster
? `#${index + 1}.配置信息`
: ''
"
collapsible="header"
:show-arrow="!formData.shareCluster"
> -->
<template #header v-if="!shareCluster"> <template #header v-if="!shareCluster">
<div class="collapse-header"> <div class="collapse-header">
{{ {{
@ -1136,10 +1124,6 @@ const filterConfigByType = (data: any, type: string) => {
}); });
}; };
const changeheader = (value: string) => {
console.log(22, value);
};
const getPortOptions = (portOptions: object, index = 0) => { const getPortOptions = (portOptions: object, index = 0) => {
if (!portOptions) return; if (!portOptions) return;
const type = formData.value.type; const type = formData.value.type;
@ -1224,6 +1208,10 @@ const saveData = async () => {
}); });
}); });
if (!formRef2Data?.cluster) {
return onlyMessage('请新增或完善配置', 'error');
}
const { configuration } = formRef2Data?.cluster[0]; const { configuration } = formRef2Data?.cluster[0];
const params = shareCluster.value const params = shareCluster.value
? { ...formData.value, configuration } ? { ...formData.value, configuration }
@ -1418,5 +1406,6 @@ watch(
background: #ffffff; background: #ffffff;
border: 1px solid #e50012; border: 1px solid #e50012;
border-radius: 2px; border-radius: 2px;
cursor: pointer;
} }
</style> </style>

View File

@ -113,6 +113,19 @@ export const Validator = {
regOnlyNumber: new RegExp(/^\d+$/), regOnlyNumber: new RegExp(/^\d+$/),
}; };
const validateAddress = (_rule: any, value: string): Promise<any> =>
new Promise(async (resolve, reject) => {
if (
Validator.regIpv4.test(value) ||
Validator.regIPv6.test(value) ||
Validator.regDomain.test(value)
) {
return resolve('');
} else {
return reject('请输入正确的IP地址或者域名');
}
});
export const Rules = { export const Rules = {
name: [ name: [
{ {
@ -160,10 +173,14 @@ export const Rules = {
message: '请输入公网地址', message: '请输入公网地址',
}, },
{ {
pattern: validator: validateAddress,
Validator.regIpv4 || Validator.regIPv6 || Validator.regDomain, message: '请输入正确的IP地址或者域名',
message: '请输入正确格式的域名或ip',
}, },
// {
// pattern:
// Validator.regIpv4 || Validator.regIPv6 || Validator.regDomain,
// message: '请输入正确格式的域名或ip',
// },
], ],
publicPort: [ publicPort: [
{ {
@ -181,9 +198,7 @@ export const Rules = {
message: '请输入远程地址', message: '请输入远程地址',
}, },
{ {
pattern: validator: validateAddress,
Validator.regIpv4 || Validator.regIPv6 || Validator.regDomain,
message: '请输入正确格式的域名或ip', message: '请输入正确格式的域名或ip',
}, },
], ],

View File

@ -39,6 +39,7 @@
enabled: 'processing', enabled: 'processing',
disabled: 'error', disabled: 'error',
}" }"
@click="handlEye(slotProps.id)"
> >
<template #img> <template #img>
<slot name="img"> <slot name="img">
@ -51,15 +52,14 @@
style=" style="
width: calc(100% - 100px); width: calc(100% - 100px);
margin-bottom: 20px; margin-bottom: 20px;
color: #2f54eb;
" "
> >
<span <span
style=" style="
font-size: 16px; font-size: 18px;
font-weight: 600; font-weight: 800;
line-height: 22px;
" "
@click.stop="handlEye(slotProps.id)"
> >
{{ slotProps.name }} {{ slotProps.name }}
</span> </span>
@ -136,6 +136,7 @@
style="padding: 0px" style="padding: 0px"
@click="i.onClick" @click="i.onClick"
type="link" type="link"
:danger="i.key === 'delete'"
:hasPermission="'link/Type:' + i.key" :hasPermission="'link/Type:' + i.key"
> >
<template #icon <template #icon

View File

@ -76,10 +76,7 @@
message: '请输入API Host', message: '请输入API Host',
}, },
{ {
pattern: validator: validateAddress,
Validator.regIpv4 ||
Validator.regIPv6 ||
Validator.regDomain,
message: '请输入正确的IP地址或者域名', message: '请输入正确的IP地址或者域名',
}, },
]" ]"
@ -133,10 +130,7 @@
message: '请输入RTP IP', message: '请输入RTP IP',
}, },
{ {
pattern: validator: validateAddress,
Validator.regIpv4 ||
Validator.regIPv6 ||
Validator.regDomain,
message: '请输入正确的IP地址或者域名', message: '请输入正确的IP地址或者域名',
}, },
]" ]"
@ -197,15 +191,8 @@
style="width: 100%" style="width: 100%"
:min="1" :min="1"
:max=" :max="
Number( formData.configuration
formData.configuration .dynamicRtpPortRange1 || 65535
.dynamicRtpPortRange1,
) < 65535
? Number(
formData.configuration
.dynamicRtpPortRange1,
)
: 65535
" "
:precision="0" :precision="0"
placeholder="起始端口" placeholder="起始端口"
@ -231,7 +218,8 @@
<j-input-number <j-input-number
style="width: 100%" style="width: 100%"
:min=" :min="
formData.configuration.dynamicRtpPortRange0 formData.configuration
.dynamicRtpPortRange0 || 1
" "
:max="65535" :max="65535"
:precision="0" :precision="0"
@ -305,6 +293,19 @@ const Validator = {
regOnlyNumber: new RegExp(/^\d+$/), regOnlyNumber: new RegExp(/^\d+$/),
}; };
const validateAddress = (_rule: any, value: string): Promise<any> =>
new Promise(async (resolve, reject) => {
if (
Validator.regIpv4.test(value) ||
Validator.regIPv6.test(value) ||
Validator.regDomain.test(value)
) {
return resolve('');
} else {
return reject('请输入正确的IP地址或者域名');
}
});
const formData = ref<FormDataType>({ const formData = ref<FormDataType>({
name: '', name: '',
provider: undefined, provider: undefined,

View File

@ -38,9 +38,10 @@
:status="slotProps.state.value" :status="slotProps.state.value"
:statusText="slotProps.state.text" :statusText="slotProps.state.text"
:statusNames="{ :statusNames="{
enabled: 'success', enabled: 'processing',
disabled: 'error', disabled: 'error',
}" }"
@click="handlEye(slotProps.id)"
> >
<template #img> <template #img>
<slot name="img"> <slot name="img">
@ -53,15 +54,14 @@
style=" style="
width: calc(100% - 100px); width: calc(100% - 100px);
margin-bottom: 10px; margin-bottom: 10px;
color: #2f54eb;
" "
> >
<span <span
style=" style="
font-size: 16px; font-size: 18px;
font-weight: 600; font-weight: 800;
line-height: 22px;
" "
@click.stop="handlEye(slotProps.id)"
> >
{{ slotProps.name }} {{ slotProps.name }}
</span> </span>

View File

@ -188,11 +188,18 @@ const handOptionByColumn = (option: any) => {
} }
} }
watchEffect(() => { watch(() => [columnOptions.value, paramsValue.column], () => {
if (!props.value.error && props.value.column) { // option if (paramsValue.column) {
const option = getOption(columnOptions.value, paramsValue.column, 'id') const option = getOption(columnOptions.value, paramsValue.column, 'id')
if (option) { if (option && Object.keys(option).length) {
handOptionByColumn(option) handOptionByColumn(option)
if (props.value.error) {
emit('update:value', {
...props.value,
error: false
})
formItemContext.onFieldChange()
}
} else { } else {
emit('update:value', { emit('update:value', {
...props.value, ...props.value,
@ -203,6 +210,12 @@ watchEffect(() => {
} }
}) })
watchEffect(() => {
if (!props.value.error && props.value.column) { // option
}
})
const showDouble = computed(() => { const showDouble = computed(() => {
const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false
return isRange return isRange

View File

@ -213,7 +213,7 @@ const rules = [
return Promise.reject(new Error('请选择操作符')) return Promise.reject(new Error('请选择操作符'))
} }
if (v.value === undefined) { if (v.value.value === undefined) {
return Promise.reject(new Error('请选择或输入参数值')) return Promise.reject(new Error('请选择或输入参数值'))
} else { } else {
if ( if (

View File

@ -81,6 +81,7 @@ import { ContextKey } from './util'
import { useSceneStore } from 'store/scene' import { useSceneStore } from 'store/scene'
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { Form } from 'jetlinks-ui-components' import { Form } from 'jetlinks-ui-components'
import { pick } from 'lodash-es'
const sceneStore = useSceneStore() const sceneStore = useSceneStore()
const { data: formModel } = storeToRefs(sceneStore) const { data: formModel } = storeToRefs(sceneStore)
@ -187,11 +188,18 @@ const handOptionByColumn = (option: any) => {
} }
} }
watchEffect(() => { watch(() => [columnOptions.value, paramsValue.column], () => {
if (!props.value.error && props.value.column) { // option if (paramsValue.column) {
const option = getOption(columnOptions.value, paramsValue.column, 'column') const option = getOption(columnOptions.value, paramsValue.column, 'column')
if (option) { if (option && Object.keys(option).length) {
handOptionByColumn(option) handOptionByColumn(option)
if (props.value.error) {
emit('update:value', {
...props.value,
error: false
})
formItemContext.onFieldChange()
}
} else { } else {
emit('update:value', { emit('update:value', {
...props.value, ...props.value,
@ -200,7 +208,7 @@ watchEffect(() => {
formItemContext.onFieldChange() formItemContext.onFieldChange()
} }
} }
}) }, { immediate: true, deep: true })
const showDouble = computed(() => { const showDouble = computed(() => {
const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false
@ -225,15 +233,17 @@ const mouseout = () => {
} }
const columnSelect = (option: any) => { const columnSelect = (option: any) => {
paramsValue.termType = 'eq' const termTypes = option.termTypes
paramsValue.termType = termTypes?.length ? termTypes[0].id : 'eq'
paramsValue.value = { paramsValue.value = {
source: tabsOptions.value[0].key, source: tabsOptions.value[0].key,
value: undefined value: undefined
} }
emit('update:value', { ...paramsValue }) handOptionByColumn(option)
formItemContext.onFieldChange()
formModel.value.options!.when[props.whenName].terms[props.termsName].terms[props.name][0] = option.name formModel.value.options!.when[props.whenName].terms[props.termsName].terms[props.name][0] = option.name
formModel.value.options!.when[props.whenName].terms[props.termsName].terms[props.name][1] = paramsValue.termType formModel.value.options!.when[props.whenName].terms[props.termsName].terms[props.name][1] = paramsValue.termType
emit('update:value', { ...paramsValue })
formItemContext.onFieldChange()
} }
const termsTypeSelect = (e: { key: string, name: string }) => { const termsTypeSelect = (e: { key: string, name: string }) => {
@ -242,9 +252,9 @@ const termsTypeSelect = (e: { key: string, name: string }) => {
source: tabsOptions.value[0].key, source: tabsOptions.value[0].key,
value: value value: value
} }
formModel.value.options!.when[props.whenName].terms[props.termsName].terms[props.name][1] = e.name
emit('update:value', { ...paramsValue }) emit('update:value', { ...paramsValue })
formItemContext.onFieldChange() formItemContext.onFieldChange()
formModel.value.options!.when[props.whenName].terms[props.termsName].terms[props.name][1] = e.name
} }
const valueSelect = (_: any, label: string, labelObj: Record<number, any>) => { const valueSelect = (_: any, label: string, labelObj: Record<number, any>) => {
@ -277,7 +287,7 @@ const onDelete = () => {
} }
nextTick(() => { nextTick(() => {
Object.assign(paramsValue, props.value) Object.assign(paramsValue, pick(props.value, ['column', 'options', 'termType', 'terms', 'type', 'value']))
}) })
</script> </script>

View File

@ -120,7 +120,7 @@ const rules = [
return Promise.reject(new Error('请选择操作符')); return Promise.reject(new Error('请选择操作符'));
} }
if (v.value === undefined) { if (!v.value?.value) {
return Promise.reject(new Error('请选择或输入参数值')); return Promise.reject(new Error('请选择或输入参数值'));
} else { } else {
if ( if (

View File

@ -311,7 +311,7 @@ const getActions = (
}, },
icon: 'LikeOutlined', icon: 'LikeOutlined',
popConfirm: { popConfirm: {
title: '', title: '确认手动触发?',
onConfirm: async () => { onConfirm: async () => {
const resp = await _execute(data.id); const resp = await _execute(data.id);
if (resp.status === 200) { if (resp.status === 200) {

View File

@ -92,7 +92,7 @@ export default defineConfig(({ mode}) => {
[env.VITE_APP_BASE_API]: { [env.VITE_APP_BASE_API]: {
// target: 'http://192.168.33.22:8800', // target: 'http://192.168.33.22:8800',
// target: 'http://192.168.32.244:8881', // target: 'http://192.168.32.244:8881',
// target: 'http://120.77.179.54:8844', // 120测试 // target: 'http://120.77.179.54:8844', // 120测试
target: 'http://192.168.33.46:8844', // 本地开发环境 target: 'http://192.168.33.46:8844', // 本地开发环境
ws: 'ws://192.168.33.46:8844', ws: 'ws://192.168.33.46:8844',
changeOrigin: true, changeOrigin: true,

View File

@ -3700,8 +3700,8 @@ jetlinks-store@^0.0.3:
jetlinks-ui-components@^1.0.5: jetlinks-ui-components@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.5.tgz#f2e62df4054e513df39e3355592d95e356438328" resolved "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.5.tgz#147926716787ac22464b5ce81180ce43a93e40cc"
integrity sha512-vfQ8g8nEJueDkHCVcg9WeWDDjnPklyigbobB1CQArfHLd5O4x6vLFWvF69k0yqytCvIOXB13CzhLtMnv68pC5w== integrity sha512-guypzc4QurKHfVoDrCo28Bx721kbTx8/W9r8jROWINI0J11ZTRi5bMmqK/2783Jg4kI0s4wZBWebRbIHBgoCyA==
dependencies: dependencies:
"@vueuse/core" "^9.12.0" "@vueuse/core" "^9.12.0"
ant-design-vue "^3.2.15" ant-design-vue "^3.2.15"