Merge branch 'dev' into dev-hub

This commit is contained in:
jackhoo_98 2023-03-17 14:58:13 +08:00
commit 2e0b45b444
24 changed files with 265 additions and 233 deletions

View File

@ -25,7 +25,7 @@
"event-source-polyfill": "^1.0.31",
"global": "^4.4.0",
"jetlinks-store": "^0.0.3",
"jetlinks-ui-components": "^1.0.5",
"jetlinks-ui-components": "^1.0.4",
"js-cookie": "^3.0.1",
"less": "^4.1.3",
"less-loader": "^11.1.0",

View File

@ -26,11 +26,10 @@ interface AMapProps {
class?: string;
AMapUI?: string | boolean;
}
const amapKey = localStorage.getItem('amap_key') || 'a0415acfc35af15f10221bfa5a6850b4';
const amapKey = localStorage.getItem('amap_key')
initAMapApiLoader({
key: amapKey || '',
securityJsCode: 'cae6108ec3dd222f946d1a7237c78be0',
});
const props = defineProps({

View File

@ -1,12 +1,12 @@
<!-- 坐标点拾取组件 -->
<template>
<div class="page-container">
<a-input allowClear v-model:value="inputPoint">
<j-input allowClear v-model:value="inputPoint">
<template #addonAfter>
<environment-outlined @click="modalVis = true" />
</template>
</a-input>
<a-modal
</j-input>
<j-modal
title="地理位置"
ok-text="确认"
cancel-text="取消"
@ -28,7 +28,7 @@
</el-amap>
{{ mapPoint }}
</div>
</a-modal>
</j-modal>
</div>
</template>

View File

@ -40,7 +40,7 @@
</j-button>
</template>
</template>
<j-tooltip v-else title="没有权限">
<j-tooltip v-else title="暂无权限,请联系管理员">
<slot v-if="noButton"></slot>
<j-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
<slot></slot>

View File

@ -15,87 +15,91 @@
<j-radio-button :value="0">全屏</j-radio-button>
</j-radio-group>
<div class="screen-tool-save">
<j-tooltip title="可保存分屏配置记录">
<AIcon type="QuestionCircleOutlined" />
</j-tooltip>
<j-popover
v-model:visible="visible"
trigger="click"
title="分屏名称"
>
<template #content>
<j-form
ref="formRef"
:model="formData"
layout="vertical"
>
<j-form-item
name="name"
:rules="[
{
required: true,
message: '请输入名称',
},
{
max: 64,
message: '最多可输入64个字符',
},
]"
>
<j-textarea v-model:value="formData.name" />
</j-form-item>
<j-button
type="primary"
@click="saveHistory"
:loading="loading"
style="width: 100%; margin-top: 16px"
>
保存
</j-button>
</j-form>
</template>
<j-dropdown-button
type="primary"
@click="visible = true"
<j-space>
<j-tooltip title="可保存分屏配置记录">
<AIcon type="QuestionCircleOutlined" />
</j-tooltip>
<j-popover
v-model:visible="visible"
trigger="click"
title="分屏名称"
>
保存
<template #overlay>
<j-menu>
<j-empty
v-if="!historyList.length"
description="暂无数据"
/>
<j-menu-item
v-for="(item, index) in historyList"
:key="`his${index}`"
@click="handleHistory(item)"
<template #content>
<j-form
ref="formRef"
:model="formData"
layout="vertical"
>
<j-form-item
name="name"
:rules="[
{
required: true,
message: '请输入名称',
},
{
max: 64,
message: '最多可输入64个字符',
},
]"
>
<j-space>
<span>{{ item.name }}</span>
<j-popconfirm
title="确认删除?"
ok-text="确认"
cancel-text="取消"
@confirm="(e: any) => {
e?.stopPropagation();
deleteHistory(item.key);
}
"
>
<AIcon
type="DeleteOutlined"
@click="
(e:any) =>
e?.stopPropagation()
"
/>
</j-popconfirm>
</j-space>
</j-menu-item>
</j-menu>
<j-textarea
v-model:value="formData.name"
/>
</j-form-item>
<j-button
type="primary"
@click="saveHistory"
:loading="loading"
style="width: 100%; margin-top: 16px"
>
保存
</j-button>
</j-form>
</template>
</j-dropdown-button>
</j-popover>
<j-dropdown-button
type="primary"
@click="visible = true"
>
保存
<template #overlay>
<j-menu>
<j-empty
v-if="!historyList.length"
description="暂无数据"
/>
<j-menu-item
v-for="(item, index) in historyList"
:key="`his${index}`"
@click="handleHistory(item)"
>
<j-space>
<span>{{ item.name }}</span>
<j-popconfirm
title="确认删除?"
ok-text="确认"
cancel-text="取消"
@confirm="(e: any) => {
e?.stopPropagation();
deleteHistory(item.key);
}
"
>
<AIcon
type="DeleteOutlined"
@click="
(e:any) =>
e?.stopPropagation()
"
/>
</j-popconfirm>
</j-space>
</j-menu-item>
</j-menu>
</template>
</j-dropdown-button>
</j-popover>
</j-space>
</div>
</div>
<!-- 播放器 -->
@ -127,7 +131,7 @@
>
刷新
</div>
<LivePlayer :url="item.url" autoplay />
<LivePlayer :live="true" :url="item.url" autoplay />
</div>
</template>
</div>

View File

@ -1,14 +1,17 @@
import { defineStore } from 'pinia';
import { systemVersion } from '@/api/comm'
import { useMenuStore } from './menu'
import { getDetails_api } from '@/api/system/basis';
export const useSystem = defineStore('system', {
state: () => ({
isCommunity: false
isCommunity: false,
configInfo: [] as any[]
}),
actions: {
getSystemVersion(): Promise<any[]> {
return new Promise(async(res, rej) => {
this.getSystemConfig();
return new Promise(async (res, rej) => {
const resp = await systemVersion()
if (resp.success && resp.result) {
const isCommunity = resp.result.edition === 'community'
@ -19,6 +22,12 @@ export const useSystem = defineStore('system', {
res(menuData)
}
})
},
getSystemConfig() {
const params = ['front', 'amap', 'paths'];
getDetails_api(params).then(({ status, result }: any) => {
this.configInfo = status === 200 ? [...result] : [];
})
}
}
})

View File

@ -91,8 +91,6 @@ const getLevelLabel = (id: number) => {
.label {
background-color: #fafafa;
}
.value {
}
}
}
</style>

View File

@ -118,20 +118,20 @@ const submitData = async () => {
if (props.isChild === 1) {
addParams.value = {
...formModel.value,
sortIndex:
childArr.value[childArr.value.length - 1].sortIndex + 1,
// sortIndex:
// childArr.value[childArr.value.length - 1].sortIndex + 1,
parentId: addObj.value.id,
};
} else if (props.isChild === 2) {
addParams.value = {
parentId: addObj.value.id,
...formModel.value,
sortIndex: 1,
// sortIndex: 1,
};
} else if (props.isChild === 3) {
addParams.value = {
...formModel.value,
sortIndex: arr.value[arr.value.length - 1].sortIndex + 1,
// sortIndex: arr.value[arr.value.length - 1].sortIndex + 1,
};
}
const res = await saveTree(addParams.value);

View File

@ -220,6 +220,7 @@ const table = reactive({
title: '说明',
dataIndex: 'description',
key: 'description',
ellipsis: true,
width: 700,
},
{

View File

@ -49,7 +49,7 @@
<j-input
v-model:value="form.id"
placeholder="请输入ID"
:disabled="disabled"
:disabled="idDisabled"
/>
</j-form-item>
<j-form-item label="名称" name="name">
@ -149,6 +149,7 @@ import { Form } from 'ant-design-vue';
import { getImage } from '@/utils/comm.ts';
import { message } from 'ant-design-vue';
import DialogTips from '../DialogTips/index.vue';
import { useProductStore } from '@/store/product';
import { filterTreeSelectNode, filterSelectNode } from '@/utils/comm';
import { FILE_UPLOAD } from '@/api/comm';
import { isInput } from '@/utils/regular';
@ -159,7 +160,7 @@ import {
CheckOutlined,
DeleteOutlined,
} from '@ant-design/icons-vue';
const productStore = useProductStore();
const emit = defineEmits(['success']);
const props = defineProps({
title: {
@ -178,6 +179,7 @@ const visible = ref<boolean>(false);
const logoLoading = ref<boolean>(false);
const formRef = ref();
const disabled = ref<boolean>(false);
const idDisabled = ref<boolean>(false);
const useForm = Form.useForm;
const _selectedRowKeys = ref([]);
const photoValue = ref('/images/device-product.png');
@ -296,6 +298,7 @@ watch(
*/
const show = (data: any) => {
if (props.isAdd === 2) {
productStore.refresh(data.id);
form.name = data.name;
form.classifiedId = data.classifiedId;
form.classifiedName = data.classifiedName;
@ -303,7 +306,8 @@ const show = (data: any) => {
form.deviceType = data.deviceType.value;
form.describe = form.describe;
form.id = data.id;
disabled.value = true;
disabled.value = productStore.current?.accessId ? true : false;
idDisabled.value = true;
} else if (props.isAdd === 1) {
form.name = '';
form.classifiedId = '';
@ -313,6 +317,7 @@ const show = (data: any) => {
form.describe = undefined;
form.id = undefined;
disabled.value = false;
disabled.vlaue = false;
}
visible.value = true;
};
@ -334,6 +339,7 @@ const submitData = () => {
formRef.value
.validate()
.then(async () => {
console.log(form);
//
if (props.isAdd === 1) {
if (form.id === '') {

View File

@ -103,7 +103,7 @@
...item.tooltip,
}"
@click="item.onClick"
:hasPermission="'device/Product:' + item.key"
:hasPermission="item.key ==='view' ? true : 'device/Product:' + item.key"
>
<AIcon
type="DeleteOutlined"
@ -197,40 +197,52 @@ const columns = [
dataIndex: 'id',
key: 'id',
scopedSlots: true,
width:200,
ellipsis: true,
},
{
title: '产品名称',
dataIndex: 'name',
key: 'name',
width:220,
ellipsis: true,
},
{
title: '接入方式',
dataIndex: 'accessName',
key: 'accessName',
width:220,
ellipsis: true,
},
{
title: '设备类型',
dataIndex: 'deviceType',
key: 'deviceType',
scopedSlots: true,
ellipsis: true,
width:120,
},
{
title: '状态',
dataIndex: 'state',
key: 'state',
scopedSlots: true,
ellipsis: true,
width:90,
},
{
title: '说明',
dataIndex: 'describe',
key: 'describe',
ellipsis: true,
},
{
title: '操作',
key: 'action',
fixed: 'right',
width: 250,
width: 200,
scopedSlots: true,
ellipsis: true,
},
];
@ -383,7 +395,7 @@ const beforeUpload = (file: any) => {
}
return true;
} catch {
message.error('请上传json格式文件');
// message.error('json');
}
return true;
};

View File

@ -726,7 +726,7 @@ const handleSubmit = () => {
// console.log('formData.value: ', formData.value);
formRef.value
.validate()
.then(async () => {
.then(() => {
const {
id,
cascadeName,
@ -750,16 +750,14 @@ const handleSubmit = () => {
],
};
btnLoading.value = true;
const res = formData.value.id
? await CascadeApi.update(params)
: await CascadeApi.save(params);
btnLoading.value = false;
if (res.success) {
message.success('操作成功');
router.back();
} else {
message.error('操作失败');
}
CascadeApi[id ? 'update' : 'save'](params)
.then(() => {
message.success('操作成功');
router.back();
})
.finally(() => {
btnLoading.value = false;
});
})
.catch((err: any) => {
console.log('err: ', err);

View File

@ -25,7 +25,7 @@
<div class="tool-item">刷新</div>
<div class="tool-item" @click.stop="handleReset">重置</div>
</div>
<LivePlayer :url="url" :protocol="mediaType" autoplay />
<LivePlayer :live="true" :url="url" :protocol="mediaType" autoplay />
</div>
<MediaTool
@onMouseDown="handleMouseDown"

View File

@ -317,9 +317,14 @@ watch(
() => _vis.value,
(val) => {
if (!val) {
formRef.value.resetFields();
formRef.value?.resetFields(); // resetFields
// ,
formData.value.id = undefined;
Object.keys(formData.value).forEach((key: string) => {
if (key === 'id') formData.value.id = undefined;
else if (key === 'deviceId')
formData.value.deviceId = route.query.id;
else formData.value[key] = '';
});
}
},
);

View File

@ -53,7 +53,7 @@
>
<j-input
v-model:value="formData.id"
placeholder="请输入"
placeholder="请输入ID"
:disabled="!!route.query.id"
/>
</j-form-item>

View File

@ -1,6 +1,6 @@
export const PROVIDER_OPTIONS = [
{ label: '固定地址', value: 'fixed-media' },
{ label: 'GB/T28181', value: 'gb28181-2016' },
{ label: '固定地址', value: 'fixed-media' },
]
export const streamMode = [
{ label: 'UDP', value: 'UDP' },

View File

@ -78,7 +78,12 @@
...item.tooltip,
}"
@click="item.onClick"
:hasPermission="'media/Device:' + item.key"
:hasPermission="
'media/Device:' +
(item.key !== 'updateChannel'
? item.key
: 'update')
"
>
<AIcon
type="DeleteOutlined"
@ -124,7 +129,10 @@
@click="i.onClick"
type="link"
style="padding: 0px"
:hasPermission="'media/Device:' + i.key"
:hasPermission="
'media/Device:' +
(i.key !== 'updateChannel' ? i.key : 'update')
"
>
<template #icon><AIcon :type="i.icon" /></template>
</PermissionButton>
@ -318,7 +326,7 @@ const getActions = (
},
},
{
key: 'view', // updateChannel
key: 'updateChannel',
text: '更新通道',
tooltip: {
title:
@ -366,6 +374,8 @@ const getActions = (
icon: 'DeleteOutlined',
},
];
return actions;
return data.provider === 'fixed-media'
? actions.filter((f: any) => f.key !== 'updateChannel')
: actions;
};
</script>

View File

@ -67,8 +67,8 @@
<span>{{ slotProps.channelNumber || 0 }}</span>
</template>
<template #state="slotProps">
<a-space>
<a-badge
<j-space>
<j-badge
:status="
slotProps.state.value === 'online'
? 'success'
@ -76,7 +76,7 @@
"
:text="slotProps.state.text"
/>
</a-space>
</j-space>
</template>
</JProTable>
</j-modal>

View File

@ -43,8 +43,8 @@ interface DataNode {
/**
* 点击节点
* @param _
* @param param1
* @param _
* @param param1
*/
const onSelect = (_: any, { node }: any) => {
emit('onSelect', { dId: node.deviceId, cId: node.channelId });
@ -68,23 +68,25 @@ const treeData = ref<any[]>([]);
const getDeviceList = async () => {
const res = await cascadeApi.getMediaTree({ paging: false });
if (res.success) {
treeData.value = res.result.map((m: any) => {
const extra: any = {};
extra.isLeaf = isLeaf(m);
return {
...m,
...extra,
};
});
treeData.value = res.result
.sort((a: any, b: any) => a.createTime - b.createTime)
.map((m: any) => {
const extra: any = {};
extra.isLeaf = isLeaf(m);
return {
...m,
...extra,
};
});
}
};
getDeviceList();
/**
* 更新数据
* @param list
* @param key
* @param children
* @param list
* @param key
* @param children
*/
const updateTreeData = (
list: DataNode[],
@ -146,7 +148,7 @@ const getChildren = (key: any, params: any): Promise<any> => {
/**
* 异步加载子节点数据
* @param param0
* @param param0
*/
const onLoadData = ({ key, children }: any): Promise<void> => {
return new Promise(async (resolve) => {

View File

@ -271,21 +271,31 @@ const getActions = (
/**
* 自动绑定
*/
const handleAutoBind = () => {
const arr = dataSource.value
.filter((item: any) => item.userId && item.status.value === 'error')
.map((i: any) => {
return {
userId: i.userId,
providerName: i.userName,
thirdPartyUserId: i.thirdPartyUserId,
};
});
const handleAutoBind = async () => {
await getTableData([
{
column: `id$user-third$${props.data.type}_${props.data.provider}$not`,
},
]);
const params = dataSource.value
.filter((f: any) => f.userId && f.status.value === 'error')
.map((m: any) => ({
userId: m.userId,
providerName: m.thirdPartyUserName,
thirdPartyUserId: m.thirdPartyUserId,
}));
configApi.dingTalkBindUser(arr, props.data.id).then(() => {
message.success('操作成功');
getTableData();
});
if (props.data.type === 'dingTalk') {
configApi.dingTalkBindUser(params, props.data.id).then(() => {
message.success('操作成功');
getTableData();
});
} else if (props.data.type === 'weixin') {
configApi.weChatBindUser(params, props.data.id).then(() => {
message.success('操作成功');
getTableData();
});
}
};
/**
@ -335,9 +345,9 @@ const getAllUsers = async (terms?: any) => {
*/
const dataSource = ref<any>([]);
const tableLoading = ref(false);
const getTableData = () => {
const getTableData = (terms?: any) => {
tableLoading.value = true;
Promise.all<any>([getDeptUsers(), getBindUsers(), getAllUsers()])
Promise.all<any>([getDeptUsers(), getBindUsers(), getAllUsers(terms)])
.then((res) => {
dataSource.value = [];
const [deptUsers, bindUsers, unBindUsers] = res;
@ -359,7 +369,7 @@ const getTableData = () => {
thirdPartyUserId: deptUser.id,
thirdPartyUserName: deptUser.name,
bindId: bindUser?.id,
userId: bindUser?.userId,
userId: unBindUser?.id,
userName: unBindUser
? `${unBindUser.name}(${unBindUser.username})`
: bindUser?.providerName,
@ -420,7 +430,6 @@ const handleBind = (row: any) => {
getAllUsers([
{
column: `id$user-third$${props.data.type}_${props.data.provider}$not`,
// value: props.data.id,
},
]);
};

View File

@ -194,6 +194,7 @@
.button-delete {
.deleteBtn();
}
}

View File

@ -3,7 +3,7 @@
<div class="basis-container">
<j-form
layout="vertical"
ref="formBasicRef"
ref="formRef"
:rules="rulesFrom"
:model="formValue"
>
@ -73,9 +73,7 @@
@change="
uploader.handleChangeLogo
"
:accept="
uploader.imageTypes.toString()
"
:accept="uploader.imageTypes"
>
<div
class="upload-image-content-logo"
@ -130,7 +128,9 @@
<div class="upload-tips">
推荐尺寸200*200
</div>
<div class="upload-tips">支持jpg,png</div>
<div class="upload-tips">
支持jpg,png,jfif,pjp,pjpeg,jpeg
</div>
</j-form-item>
</j-col>
<j-col>
@ -163,9 +163,7 @@
@change="
uploader.changeIconUpload
"
:accept="
uploader.imageTypes.toString()
"
:accept="uploader.iconTypes"
>
<div
class="upload-image-content-logo"
@ -224,7 +222,7 @@
"
:showUploadList="false"
@change="uploader.changeBackUpload"
:accept="uploader.imageTypes.toString()"
:accept="uploader.imageTypes"
>
<div class="upload-image-content-back">
<div
@ -260,7 +258,8 @@
</div>
</div>
<div class="upload-tips">
支持4M以内的图片:支持jpgpng
支持4M以内的图片:
支持jpg,png,jfif,pjp,pjpeg,jpeg
</div>
<div class="upload-tips">建议尺寸1400x1080</div>
</j-form-item>
@ -293,36 +292,31 @@ import { LocalStore } from '@/utils/comm';
import { save_api, getDetails_api } from '@/api/system/basis';
import { usePermissionStore } from '@/store/permission';
import { useSystem } from '@/store/system';
const action = ref<string>(`${BASE_API_PATH}/file/static`);
const headers = ref({ [TOKEN_KEY]: LocalStore.get(TOKEN_KEY) });
const formBasicRef = ref();
const action = `${BASE_API_PATH}/file/static`;
const headers = { [TOKEN_KEY]: LocalStore.get(TOKEN_KEY) };
const formRef = ref();
const form = reactive<formType>({
formValue: {
title: '',
headerTheme: 'light',
apiKey: '',
'base-path': `${window.location.origin}/api`,
logo: '/public/logo.png',
ico: '/public/favicon.ico',
backgroud: '/public/images/login.png',
logo: '',
ico: '',
backgroud: '',
},
rulesFrom: {
title: [
{
required: true,
message: '名称必填',
trigger: 'blur',
},
{
max: 64,
message: '最多可输入64个字符',
},
{
max: 64,
message: '最多可输入64个字符',
trigger: 'blur',
},
],
headerTheme: [
{
@ -344,40 +338,23 @@ const form = reactive<formType>({
iconLoading: false, //
saveLoading: false,
getDetails: () => {
const params = ['front', 'amap', 'paths'];
getDetails_api(params).then((resp: any) => {
console.log(resp);
const basis = resp.result?.filter(
(item: any) => item.scope === 'front',
);
const api = resp.result?.filter(
(item: any) => item.scope === 'amap',
);
const basePath = resp.result?.filter(
(item: any) => item.scope === 'paths',
);
console.log();
form.formValue = {
...basis[0].properties,
apiKey: api[0].properties.apiKey,
'base-path': basePath[0].properties['base-path'],
logo: form.formValue.logo || '/public/logo.png',
ico: form.formValue.ico || '/public/favicon.ico',
backgroud:
form.formValue.backgroud || '/public/images/login.png',
};
// localStorage.setItem(
// SystemConst.AMAP_KEY,
// api[0].properties.apiKey,
// );
});
const configInfo = useSystem().$state.configInfo;
const basis = configInfo.find((item: any) => item.scope === 'front');
const api = configInfo.find((item: any) => item.scope === 'amap');
const basePath = configInfo.find((item: any) => item.scope === 'paths');
form.formValue = {
...basis.properties,
apiKey: api.properties.apiKey,
'base-path': basePath.properties['base-path'],
logo: basis.properties.logo || '/public/logo.png',
ico: basis.properties.ico || '/public/favicon.ico',
backgroud: basis.properties.backgroud || '/public/images/login.png',
};
},
clickSave: () => {
const hasPermission = usePermissionStore().hasPermission;
if (hasPermission(`system/Basis:update`)) {
formBasicRef.value.validate().then(() => {
formRef.value.validate().then(() => {
form.saveLoading = true;
const params = [
{
@ -419,7 +396,14 @@ const form = reactive<formType>({
const { formValue, rulesFrom } = toRefs(form);
const uploader: uploaderType = {
imageTypes: ['jpg', 'jpeg', 'png', 'jfif', 'pjp', 'pjpeg'],
imageTypes: [
'image/jpg',
'image/jpeg',
'image/png',
'image/jfif',
'image/pjp',
'image/pjpeg',
],
iconTypes: ['image/x-icon'],
// logo
beforeLogoUpload: ({ size, type }: File) => {
@ -427,7 +411,6 @@ const uploader: uploaderType = {
uploader.imageTypes.filter((typeStr) => type.includes(typeStr))
.length > 0;
const sizeBool = size / 1024 / 1024 < 4;
if (!typeBool) {
message.error(`请上传.jpg.png.jfif.pjp.pjpeg.jpeg格式的图片`);
} else if (!sizeBool) {

View File

@ -38,7 +38,11 @@
:tooltip="{
title: '编辑',
}"
@click="table.clickEdit(slotProps)"
@click="
jumpPage(`system/Role/Detail`, {
id: slotProps.id,
})
"
>
<AIcon type="EditOutlined" />
</PermissionButton>
@ -48,7 +52,7 @@
:tooltip="{ title: '删除' }"
:popConfirm="{
title: `确定要删除吗`,
onConfirm: () => table.clickDel(slotProps),
onConfirm: () => clickDel(slotProps),
}"
>
<AIcon type="DeleteOutlined" />
@ -72,7 +76,6 @@ import { useMenuStore } from '@/store/menu';
const permission = 'system/Role';
const { jumpPage } = useMenuStore();
const addDialogRef = ref(); //
const isSave = !!useRoute().query.save;
const columns = [
@ -115,22 +118,14 @@ const columns = [
];
const queryParams = ref({});
//
const tableRef = ref<Record<string, any>>({});
const table = {
clickAdd: () => {
addDialogRef.value.openDialog(true, {});
},
clickDel: (row: any) => {
delRole_api(row.id).then((resp: any) => {
if (resp.status === 200) {
tableRef.value?.reload();
message.success('操作成功!');
}
});
},
clickEdit: ({ id }: { id: string }) => {
jumpPage(`system/Role/Detail`, { id });
},
const tableRef = ref<Record<string, any>>();
const clickDel = (row: any) => {
delRole_api(row.id).then((resp: any) => {
if (resp.status === 200) {
tableRef.value?.reload();
message.success('操作成功!');
}
});
};
const dialogVisible = ref(isSave);
</script>

View File

@ -3698,10 +3698,10 @@ jetlinks-store@^0.0.3:
resolved "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz"
integrity sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==
jetlinks-ui-components@^1.0.5:
version "1.0.5"
resolved "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.5.tgz#4f136aac4cc6aa6f4c6515b9f54b70cd9f254419"
integrity sha512-K5U2xwhZYSmkMUsWFcqnCh4NxFM+HDfcQurmcDMQTr0/1fkG4LPqhETN0HmurLcnJAu7C4Ks1HRZJRlGqBCxAw==
jetlinks-ui-components@^1.0.4:
version "1.0.4"
resolved "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.4.tgz#cd080b2d8320c7a03ed20f4c4c22e9a5c920a3c8"
integrity sha512-8xzDFH6jSGNrkbCMb+/FL/g9vB0c2GdsDq6QPUzgKFwzPiS+cPbpSxL0RNHez9MF7/NSSuY8wL4VaujiVXTpfg==
dependencies:
"@vueuse/core" "^9.12.0"
ant-design-vue "^3.2.15"