fix: 物联卡组件替换及部分场景联动

This commit is contained in:
wzyyy 2023-03-04 11:51:42 +08:00
parent c055250aec
commit 7e053e0d00
17 changed files with 531 additions and 174 deletions

View File

@ -24,7 +24,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.1", "jetlinks-ui-components": "^1.0.3",
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"less": "^4.1.3", "less": "^4.1.3",
"less-loader": "^11.1.0", "less-loader": "^11.1.0",

View File

@ -1,6 +1,6 @@
import type { Slots } from 'vue' import type { Slots } from 'vue'
import { TOKEN_KEY } from '@/utils/variable' import { TOKEN_KEY } from '@/utils/variable'
import { message } from 'ant-design-vue' import { message } from 'jetlinks-ui-components';
/** /**
* *

View File

@ -103,7 +103,7 @@ import {
saveDeviceCode, saveDeviceCode,
delDeviceCode delDeviceCode
} from '@/api/device/instance' } from '@/api/device/instance'
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
import { isBoolean } from 'lodash'; import { isBoolean } from 'lodash';
const defaultValue = const defaultValue =

View File

@ -72,7 +72,7 @@ import {
testCode, testCode,
saveProductCode, saveProductCode,
} from '@/api/device/instance' } from '@/api/device/instance'
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
import { isBoolean } from 'lodash'; import { isBoolean } from 'lodash';
const defaultValue = const defaultValue =

View File

@ -1,39 +1,16 @@
<!-- 绑定设备 --> <!-- 绑定设备 -->
<template> <template>
<j-modal <j-modal :maskClosable="false" width="1100px" :visible="true" title="选择设备" okText="确定" cancelText="取消" @ok="handleOk"
:maskClosable="false" @cancel="handleCancel" :confirmLoading="btnLoading">
width="1100px"
:visible="true"
title="选择设备"
okText="确定"
cancelText="取消"
@ok="handleOk"
@cancel="handleCancel"
:confirmLoading="btnLoading"
>
<div style="margin-top: 10px"> <div style="margin-top: 10px">
<Search <Search :columns="columns" target="iot-card-bind-device" @search="handleSearch" type="simple" />
:columns="columns" <j-pro-table ref="bindDeviceRef" :columns="columns" :request="queryUnbounded" model="TABLE" :defaultParams="{
target="iot-card-bind-device"
@search="handleSearch"
type="simple"
/>
<j-pro-table
ref="bindDeviceRef"
:columns="columns"
:request="queryUnbounded"
model="TABLE"
:defaultParams="{
sorts: [{ name: 'createTime', order: 'desc' }], sorts: [{ name: 'createTime', order: 'desc' }],
}" }" :rowSelection="{
:rowSelection="{
type: 'radio', type: 'radio',
selectedRowKeys: _selectedRowKeys, selectedRowKeys: _selectedRowKeys,
onSelect: onSelectChange, onSelect: onSelectChange,
}" }" @cancelSelect="cancelSelect" :params="params">
@cancelSelect="cancelSelect"
:params="params"
>
<template #registryTime="slotProps"> <template #registryTime="slotProps">
{{ {{
slotProps.registryTime slotProps.registryTime
@ -44,10 +21,7 @@
}} }}
</template> </template>
<template #state="slotProps"> <template #state="slotProps">
<j-badge <j-badge :text="slotProps.state.text" :status="statusMap.get(slotProps.state.value)" />
:text="slotProps.state.text"
:status="statusMap.get(slotProps.state.value)"
/>
</template> </template>
</j-pro-table> </j-pro-table>
</div> </div>
@ -57,7 +31,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { queryUnbounded, bind } from '@/api/iot-card/cardManagement'; import { queryUnbounded, bind } from '@/api/iot-card/cardManagement';
import moment from 'moment'; import moment from 'moment';
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
const emit = defineEmits(['change']); const emit = defineEmits(['change']);
@ -141,7 +115,7 @@ const handleOk = () => {
bind(props.cardId, _selectedRowKeys.value[0]) bind(props.cardId, _selectedRowKeys.value[0])
.then((resp: any) => { .then((resp: any) => {
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
emit('change', true); emit('change', true);
} }
}) })

View File

@ -1,6 +1,6 @@
<template> <template>
<!-- 导入 --> <!-- 导入 -->
<a-modal <j-modal
:maskClosable="false" :maskClosable="false"
:visible="true" :visible="true"
title="导出" title="导出"
@ -10,19 +10,19 @@
@cancel="handleCancel" @cancel="handleCancel"
> >
<div style="margin-top: 10px"> <div style="margin-top: 10px">
<a-space> <j-space>
<span>文件格式</span> <span>文件格式</span>
<a-radio-group <j-radio-group
v-model:value="type" v-model:value="type"
placeholder="请选择文件格式" placeholder="请选择文件格式"
button-style="solid" button-style="solid"
> >
<a-radio-button value="xlsx">xlsx</a-radio-button> <j-radio-button value="xlsx">xlsx</j-radio-button>
<a-radio-button value="csv">csv</a-radio-button> <j-radio-button value="csv">csv</j-radio-button>
</a-radio-group> </j-radio-group>
</a-space> </j-space>
</div> </div>
</a-modal> </j-modal>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@ -82,7 +82,9 @@ import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable';
import { LocalStore } from '@/utils/comm'; import { LocalStore } from '@/utils/comm';
import { downloadFile, downloadFileByUrl } from '@/utils/utils'; import { downloadFile, downloadFileByUrl } from '@/utils/utils';
import { queryPlatformNoPage, _import ,exportCard} from '@/api/iot-card/cardManagement'; import { queryPlatformNoPage, _import ,exportCard} from '@/api/iot-card/cardManagement';
import { message } from 'ant-design-vue'; // import { message } from 'ant-design-vue';
import { message } from 'jetlinks-ui-components';
const emit = defineEmits(['close']); const emit = defineEmits(['close']);
@ -125,10 +127,10 @@ const fileChange = (info: any) => {
_import(modelRef.configId, { fileUrl: r.result }) _import(modelRef.configId, { fileUrl: r.result })
.then((resp: any) => { .then((resp: any) => {
totalCount.value = resp.result.total; totalCount.value = resp.result.total;
message.success('导入成功'); message.success('导入成功')
}) })
.catch((err) => { .catch((err) => {
message.error(err.response.data.message || '导入失败'); message.error(err.response.data.message || '导入失败')
}) })
.finally(() => { .finally(() => {
loading.value = false; loading.value = false;

View File

@ -98,7 +98,7 @@ import {
add, add,
edit, edit,
} from '@/api/iot-card/cardManagement'; } from '@/api/iot-card/cardManagement';
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
import { OperatorList, TypeList } from '@/views/iot-card/data'; import { OperatorList, TypeList } from '@/views/iot-card/data';
const emit = defineEmits(['change']); const emit = defineEmits(['change']);
@ -236,7 +236,7 @@ const handleOk = () => {
: await edit(toRaw(modelRef)); : await edit(toRaw(modelRef));
btnLoading.value = false; btnLoading.value = false;
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
emit('change', true); emit('change', true);
formRef.value.resetFields(); formRef.value.resetFields();
} }

View File

@ -248,22 +248,14 @@
</template> </template>
<template #action="slotProps"> <template #action="slotProps">
<j-space :size="16"> <j-space :size="16">
<template <template v-for="i in getActions(slotProps, 'table')" :key="i.key">
v-for="i in getActions(slotProps,'table')" <PermissionButton :disabled="i.disabled" :popConfirm="i.popConfirm" :tooltip="{
:key="i.key"
>
<PermissionButton
:disabled="i.disabled"
:popConfirm="i.popConfirm"
:tooltip="{
...i.tooltip, ...i.tooltip,
}" }" @click="i.onClick" type="link" style="padding: 0px"
@click="i.onClick" :hasPermission="'iot-card/CardManagement:' + i.key">
type="link" <template #icon>
style="padding: 0px" <AIcon :type="i.icon" />
:hasPermission="'iot-card/CardManagement:' + i.key" </template>
>
<template #icon><AIcon :type="i.icon" /></template>
</PermissionButton> </PermissionButton>
</template> </template>
</j-space> </j-space>
@ -297,7 +289,7 @@ import {
removeCards, removeCards,
unbind, unbind,
} from '@/api/iot-card/cardManagement'; } from '@/api/iot-card/cardManagement';
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
import type { CardManagement } from './typing'; import type { CardManagement } from './typing';
import { getImage } from '@/utils/comm'; import { getImage } from '@/utils/comm';
import BindDevice from './BindDevice.vue'; import BindDevice from './BindDevice.vue';
@ -513,7 +505,7 @@ const getActions = (
onConfirm: async () => { onConfirm: async () => {
unbind(data.id).then((resp: any) => { unbind(data.id).then((resp: any) => {
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
cardManageRef.value?.reload(); cardManageRef.value?.reload();
} }
}); });
@ -562,21 +554,21 @@ const getActions = (
if (data.cardStateType?.value === 'toBeActivated') { if (data.cardStateType?.value === 'toBeActivated') {
changeDeploy(data.id).then((resp) => { changeDeploy(data.id).then((resp) => {
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
cardManageRef.value?.reload(); cardManageRef.value?.reload();
} }
}); });
} else if (data.cardStateType?.value === 'deactivate') { } else if (data.cardStateType?.value === 'deactivate') {
resumption(data.id).then((resp) => { resumption(data.id).then((resp) => {
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
cardManageRef.value?.reload(); cardManageRef.value?.reload();
} }
}); });
} else { } else {
unDeploy(data.id).then((resp) => { unDeploy(data.id).then((resp) => {
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
cardManageRef.value?.reload(); cardManageRef.value?.reload();
} }
}); });
@ -597,7 +589,7 @@ const getActions = (
onConfirm: async () => { onConfirm: async () => {
const resp: any = await del(data.id); const resp: any = await del(data.id);
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
cardManageRef.value?.reload(); cardManageRef.value?.reload();
} else { } else {
message.error('操作失败!'); message.error('操作失败!');
@ -692,7 +684,7 @@ const handleStop = () => {
) { ) {
unDeployBatch(_selectedRowKeys.value).then((res: any) => { unDeployBatch(_selectedRowKeys.value).then((res: any) => {
if (res.status === 200) { if (res.status === 200) {
message.success('操作成功'); message.success('操作成功')
} }
}); });
} else { } else {
@ -710,7 +702,7 @@ const handleResumption = () => {
) { ) {
resumptionBatch(_selectedRowKeys.value).then((res: any) => { resumptionBatch(_selectedRowKeys.value).then((res: any) => {
if (res.status === 200) { if (res.status === 200) {
message.success('操作成功'); message.success('操作成功')
} }
}); });
} else { } else {
@ -736,7 +728,7 @@ const handleSync = () => {
const handelRemove = async () => { const handelRemove = async () => {
const resp = await removeCards(_selectedRow.value); const resp = await removeCards(_selectedRow.value);
if (resp.status === 200) { if (resp.status === 200) {
message.success('操作成功'); message.success('操作成功')
_selectedRowKeys.value = []; _selectedRowKeys.value = [];
_selectedRow.value = []; _selectedRow.value = [];
cardManageRef.value?.reload(); cardManageRef.value?.reload();

View File

@ -133,7 +133,7 @@
import { getImage } from '@/utils/comm'; import { getImage } from '@/utils/comm';
import PlatformType from '@/views/iot-card/components/PlatformType.vue'; import PlatformType from '@/views/iot-card/components/PlatformType.vue';
import { queryById, save, update } from '@/api/iot-card/platform'; import { queryById, save, update } from '@/api/iot-card/platform';
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
import Doc from '../doc/index.vue'; import Doc from '../doc/index.vue';
const router = useRouter(); const router = useRouter();

View File

@ -1,19 +1,9 @@
<!-- 平台对接 --> <!-- 平台对接 -->
<template> <template>
<page-container> <page-container>
<Search <Search :columns="columns" target="platform-search" @search="handleSearch" />
:columns="columns" <j-pro-table ref="platformRef" :columns="columns" :request="queryList"
target="platform-search" :defaultParams="{ sorts: [{ name: 'createTime', order: 'desc' }] }" :params="params" :gridColumn="3">
@search="handleSearch"
/>
<j-pro-table
ref="platformRef"
:columns="columns"
:request="queryList"
:defaultParams="{ sorts: [{ name: 'createTime', order: 'desc' }] }"
:params="params"
:gridColumn="3"
>
<template #headerTitle> <template #headerTitle>
<j-space> <j-space>
<!-- <j-button type="primary" @click="handleAdd"> <!-- <j-button type="primary" @click="handleAdd">
@ -25,17 +15,11 @@
</j-space> </j-space>
</template> </template>
<template #card="slotProps"> <template #card="slotProps">
<CardBox <CardBox :value="slotProps" :actions="getActions(slotProps, 'card')" v-bind="slotProps"
:value="slotProps" :status="slotProps.state.value" :statusText="slotProps.state.text" :statusNames="{
:actions="getActions(slotProps, 'card')"
v-bind="slotProps"
:status="slotProps.state.value"
:statusText="slotProps.state.text"
:statusNames="{
enabled: 'success', enabled: 'success',
disabled: 'error', disabled: 'error',
}" }">
>
<template #img> <template #img>
<slot name="img"> <slot name="img">
<img :src="getImage('/iot-card/iot-card-bg.png')" /> <img :src="getImage('/iot-card/iot-card-bg.png')" />
@ -72,33 +56,22 @@
</CardBox> </CardBox>
</template> </template>
<template #state="slotProps"> <template #state="slotProps">
<j-badge <j-badge :text="slotProps.state.text" :status="
:text="slotProps.state.text"
:status="
slotProps.state.value === 'disabled' slotProps.state.value === 'disabled'
? 'error' ? 'error'
: 'success' : 'success'
" " />
/>
</template> </template>
<template #action="slotProps"> <template #action="slotProps">
<j-space :size="16"> <j-space :size="16">
<template <template v-for="i in getActions(slotProps, 'table')" :key="i.key">
v-for="i in getActions(slotProps,'table')" <PermissionButton :disabled="i.disabled" :popConfirm="i.popConfirm" :tooltip="{
:key="i.key"
>
<PermissionButton
:disabled="i.disabled"
:popConfirm="i.popConfirm"
:tooltip="{
...i.tooltip, ...i.tooltip,
}" }" @click="i.onClick" type="link" style="padding: 0px"
@click="i.onClick" :hasPermission="'iot-card/Platform:' + i.key">
type="link" <template #icon>
style="padding: 0px" <AIcon :type="i.icon" />
:hasPermission="'iot-card/Platform:' + i.key" </template>
>
<template #icon><AIcon :type="i.icon" /></template>
</PermissionButton> </PermissionButton>
</template> </template>
</j-space> </j-space>
@ -110,7 +83,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getImage } from '@/utils/comm'; import { getImage } from '@/utils/comm';
import type { ActionsType } from '@/components/Table'; import type { ActionsType } from '@/components/Table';
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
import { queryList, update, del } from '@/api/iot-card/platform'; import { queryList, update, del } from '@/api/iot-card/platform';
import { useMenuStore } from 'store/menu' import { useMenuStore } from 'store/menu'
const menuStory = useMenuStore() const menuStory = useMenuStore()
@ -193,7 +166,7 @@ const getActions = (
icon: 'EditOutlined', icon: 'EditOutlined',
onClick: () => { onClick: () => {
// router.push(`/iot-card/Platform/detail/${data.id}`); // router.push(`/iot-card/Platform/detail/${data.id}`);
menuStory.jumpPage('iot-card/Platform/Detail',{id:data.id}); menuStory.jumpPage('iot-card/Platform/Detail', { id: data.id });
}, },
}, },
{ {
@ -207,8 +180,7 @@ const getActions = (
? 'StopOutlined' ? 'StopOutlined'
: 'PlayCircleOutlined', : 'PlayCircleOutlined',
popConfirm: { popConfirm: {
title: `确认${ title: `确认${data.state.value === 'enabled' ? '禁用' : '启用'
data.state.value === 'enabled' ? '禁用' : '启用'
}`, }`,
okText: ' 确定', okText: ' 确定',
cancelText: '取消', cancelText: '取消',
@ -266,7 +238,7 @@ const handleSearch = (e: any) => {
* 新增 * 新增
*/ */
const handleAdd = () => { const handleAdd = () => {
menuStory.jumpPage('iot-card/Platform/Detail',{id:'add'}) menuStory.jumpPage('iot-card/Platform/Detail', { id: 'add' })
}; };
</script> </script>

View File

@ -68,7 +68,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { queryPlatformNoPage, recharge } from '@/api/iot-card/cardManagement'; import { queryPlatformNoPage, recharge } from '@/api/iot-card/cardManagement';
import { message } from 'ant-design-vue'; import { message } from 'jetlinks-ui-components';
import { PaymentMethod } from '@/views/iot-card/data'; import { PaymentMethod } from '@/views/iot-card/data';
const emit = defineEmits(['change']); const emit = defineEmits(['change']);
@ -167,7 +167,7 @@ const handleOk = () => {
btnLoading.value = false; btnLoading.value = false;
if (resp.status === 200) { if (resp.status === 200) {
if (resp.result === '失败') { if (resp.result === '失败') {
message.error('缴费失败'); message.error('缴费失败')
} else { } else {
window.open(resp.result); window.open(resp.result);
} }
@ -176,6 +176,7 @@ const handleOk = () => {
} }
}) })
.catch((err: any) => { .catch((err: any) => {
btnLoading.value=false
console.log('error', err); console.log('error', err);
}); });
}; };

View File

@ -0,0 +1,261 @@
<template>
<Search
:columns="columns"
type='simple'
@search="handleSearch"
class='search'
target="scene-triggrt-device-device"
/>
<a-divider style='margin: 0' />
<j-pro-table
ref='actionRef'
model='CARD'
:columns='columns'
:params='params'
:request='productQuery'
:gridColumn='2'
:gridColumns='[2,2,2]'
:bodyStyle='{
paddingRight: 0,
paddingLeft: 0
}'
>
<template #card="slotProps">
<CardBox
:value='slotProps'
:active="rowKey === slotProps.id"
:status="slotProps.state"
:statusText="slotProps.state === 1 ? '正常' : '禁用'"
:statusNames="{ 1: 'success', 0: 'error', }"
@click="handleClick"
>
<template #img>
<slot name="img">
<img width='88' height='88' :src="slotProps.photoUrl || getImage('/device-product.png')" />
</slot>
</template>
<template #content>
<div style='width: calc(100% - 100px)'>
<Ellipsis>
<span style="font-size: 16px;font-weight: 600" >
{{ slotProps.name }}
</span>
</Ellipsis>
</div>
<a-row>
<a-col :span="12">
<div class="card-item-content-text">
设备类型
</div>
<div>直连设备</div>
</a-col>
</a-row>
</template>
</CardBox>
</template>
</j-pro-table>
</template>
<script setup lang='ts' name='Product'>
import { getProviders, queryGatewayList, queryProductList } from '@/api/device/product'
import { queryTree } from '@/api/device/category'
import { getTreeData_api } from '@/api/system/department'
import { isNoCommunity } from '@/utils/utils'
import { getImage } from '@/utils/comm'
type Emit = {
(e: 'update:rowKey', data: string): void
(e: 'update:detail', data: string): void
(e: 'change', data: string): void
}
const actionRef = ref()
const params = ref({})
const props = defineProps({
rowKey: {
type: String,
default: ''
},
detail: {
type: Object,
default: () => ({})
}
})
const emit = defineEmits<Emit>()
const columns = [
{
title: 'ID',
dataIndex: 'id',
width: 300,
ellipsis: true,
fixed: 'left',
search: {
type: 'string',
},
},
{
title: '名称',
dataIndex: 'name',
width: 200,
ellipsis: true,
search: {
type: 'string',
first: true
}
},
{
title: '网关类型',
dataIndex: 'accessProvider',
width: 150,
ellipsis: true,
hideInTable: true,
search: {
type: 'select',
options: () => getProviders().then((resp: any) => {
if (isNoCommunity) {
return (resp?.result || []).map((item: any) => ({
label: item.name,
value: item.id
}))
} else {
return (resp?.result || []).filter((item: any) => [
'mqtt-server-gateway',
'http-server-gateway',
'mqtt-client-gateway',
'tcp-server-gateway',
].includes(item.id))
.map((item: any) => ({
label: item.name,
value: item.id,
}))
}
})
}
},
{
title: '接入方式',
dataIndex: 'accessName',
width: 150,
ellipsis: true,
search: {
type: 'select',
options: () => queryGatewayList().then((resp: any) =>
resp.result.map((item: any) => ({
label: item.name, value: item.id
}))
)
}
},
{
title: '设备类型',
dataIndex: 'deviceType',
width: 150,
search: {
type: 'select',
options: [
{ label: '直连设备', value: 'device' },
{ label: '网关子设备', value: 'childrenDevice' },
{ label: '网关设备', value: 'gateway' },
]
}
},
{
title: '状态',
dataIndex: 'state',
width: '90px',
search: {
type: 'select',
options: [
{ label: '禁用', value: 0 },
{ label: '正常', value: 1 },
]
}
},
{
title: '说明',
dataIndex: 'describe',
ellipsis: true,
width: 300,
},
{
dataIndex: 'classifiedId',
title: '分类',
hideInTable: true,
search: {
type: 'treeSelect',
options: queryTree({ paging: false }).then(resp => resp.result),
componentProps: {
fieldNames: {
label: 'name',
value: 'id',
}
}
}
},
{
dataIndex: 'id$dim-assets',
title: '所属组织',
hideInTable: true,
search: {
type: 'treeSelect',
options: getTreeData_api({ paging: false }).then((resp: any) => {
const formatValue = (list: any[]) => {
return list.map((item: any) => {
if (item.children) {
item.children = formatValue(item.children);
}
return {
...item,
value: JSON.stringify({
assetType: 'product',
targets: [
{
type: 'org',
id: item.id,
},
],
}),
}
})
}
return formatValue(resp.result)
}),
}
}
]
const handleSearch = (p: any) => {
params.value = p
}
const productQuery = (p: any) => {
const sorts: any = [];
if (props.rowKey) {
sorts.push({
name: 'id',
value: props.rowKey,
});
}
sorts.push({ name: 'createTime', order: 'desc' });
p.sorts = sorts
return queryProductList(p)
}
const handleClick = (detail: any) => {
emit('update:rowKey', detail.id)
emit('update:detail', detail)
emit('change', detail)
}
</script>
<style scoped lang='less'>
.search {
margin-bottom: 0;
padding-right: 0px;
padding-left: 0px;
}
</style>

View File

@ -0,0 +1,14 @@
<template>
<div>
</div>
</template>
<script setup lang='ts' name="Device">
</script>
<style scoped lang='less'>
</style>

View File

@ -1,22 +1,104 @@
<template> <template>
<j-modal <j-modal title="执行动作" visible :width="860" @cancel="onCancel" @ok="save" :maskClosable="false">
title="执行动作" <j-steps :current='DeviceModel.current' @change='stepChange'>
visible <j-step>
:width="860" <template #title>选择产品</template>
@cancel="onCancel" </j-step>
@ok="onOk" <j-step>
:maskClosable="false" <template #title>选择设备</template>
> </j-step>
device <j-step>
<template #title>执行动作</template>
</j-step>
</j-steps>
<j-divider style='margin-bottom: 10px;' />
<div class='steps-content'>
<Product v-if='DeviceModel.current === 0' v-model:rowKey='DeviceModel.productId'
v-model:detail='DeviceModel.productDetail' />
</div>
<template #footer>
<div class='steps-action'>
<j-button v-if='DeviceModel.current === 0' @click='cancel'>取消</j-button>
<j-button v-else @click='prev'>上一步</j-button>
<j-button type='primary' v-if='DeviceModel.current < 2' @click='saveClick'>下一步</j-button>
<j-button type='primary' v-else @click='saveClick'>确定</j-button>
</div>
</template>
</j-modal> </j-modal>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
const emit = defineEmits(['cancel', 'save']); import { DeviceModelType } from './typings';
const onCancel = () => { import Product from './Product.vue';
import { onlyMessage } from '@/utils/comm';
type Emit = {
(e: 'cancel'): void
(e: 'save', data: any, options: Record<string, any>): void
}
const DeviceModel = reactive<DeviceModelType>({
steps: [],
current: 0,
productId: '',
deviceId: '',
productDetail: {},
device: {},
deviceDetail: {},
options: {},
selector: 'fixed',
selectorValues: [],
upperKey: '',
source: 'fixed',
relationName: '',
message: {},
propertiesName: '',
propertiesValue: '',
columns: [],
actionName: '',
tagList: [],
})
const emit = defineEmits<Emit>()
const cancel = () => {
emit('cancel'); emit('cancel');
}; };
const onOk = () => { const save = async(step?: number) => {
emit('save'); let _step = step !== undefined ? step : DeviceModel.current
if (_step === 0) {
DeviceModel.productId ? DeviceModel.current = 1 : onlyMessage('请选择产品', 'error')
} else if (_step === 1) {
} else {
}
}; };
const stepChange = (step: number) => {
if (step !== 0) {
save(step - 1)
} else {
DeviceModel.current = 0
}
}
const prev = () => {
DeviceModel.current = DeviceModel.current - 1
}
const saveClick = () => save()
</script> </script>
<style lang="less" scoped>
.steps-steps {
width: 100%;
margin-bottom: 17px;
padding-bottom: 17px;
border-bottom: 1px solid #f0f0f0;
}
.steps-content {
width: 100%;
}
</style>

View File

@ -0,0 +1,28 @@
import { ProductItem } from '@/views/device/Product/typings';
import { ActionsDeviceProps } from '../../../typings';
type DeviceModelType = {
steps: {
key: string;
title: string;
content: React.ReactNode;
}[];
current: number;
productId: string;
deviceId: string;
productDetail: ProductItem | any;
device: Partial<ActionsDeviceProps>;
deviceDetail: any;
options: any;
selector: string;
selectorValues: any;
upperKey: string;
source: string;
relationName: string;
message: any;
propertiesName: string;
propertiesValue: string | any;
columns: string[];
actionName: string;
tagList: any[];
}

View File

@ -2146,7 +2146,7 @@ cli-width@^3.0.0:
resolved "https://registry.npmmirror.com/cli-width/-/cli-width-3.0.0.tgz" resolved "https://registry.npmmirror.com/cli-width/-/cli-width-3.0.0.tgz"
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
clipboard@^2.0.4: clipboard@^2.0.10, clipboard@^2.0.4:
version "2.0.11" version "2.0.11"
resolved "https://registry.jetlinks.cn/clipboard/-/clipboard-2.0.11.tgz" resolved "https://registry.jetlinks.cn/clipboard/-/clipboard-2.0.11.tgz"
integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw== integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==
@ -3416,6 +3416,11 @@ highlight.js@^11.3.1:
resolved "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.7.0.tgz" resolved "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.7.0.tgz"
integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ== integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
hls.js@^1.0.10:
version "1.3.4"
resolved "https://registry.jetlinks.cn/hls.js/-/hls.js-1.3.4.tgz#8212a3f95c3321f64a586f20e67876f3a9d09488"
integrity sha512-iFEwVqtEDk6sKotcTwtJ5OMo/nuDTk9PrpB8FI2J2WYf8EriTVfR4FaK0aNyYtwbYeRSWCXJKlz23xeREdlNYg==
homedir-polyfill@^1.0.0: homedir-polyfill@^1.0.0:
version "1.0.3" version "1.0.3"
resolved "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz" resolved "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz"
@ -3896,10 +3901,10 @@ jetlinks-store@^0.0.3:
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@^1.0.2: jetlinks-ui-components@^1.0.3:
version "1.0.2" version "1.0.3"
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.2.tgz#753507e4a84dee966c65d4ae33943507bd60cc9d" resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.3.tgz#8307018ed5bcdd42f3bb4e29376e04f3e8a425db"
integrity sha512-LXKetf75/uqzWP4XOobm+iUWTVEeMJNnwEk+GrNftQdcDzGvUxBaoFCoS+HBH06FnE2VBbh6rEwrpDhkLSNEow== integrity sha512-jH/BtAu21zVzMopHCXEn1jwbGHh/1XHP68ekiOGH+jWowLbb2pkX0kHFyF6ydhYa7cspvJ04atWlEugXvXZYvg==
dependencies: dependencies:
"@vueuse/core" "^9.12.0" "@vueuse/core" "^9.12.0"
ant-design-vue "^3.2.15" ant-design-vue "^3.2.15"
@ -6554,6 +6559,11 @@ three@0.143.0:
resolved "https://registry.npmjs.org/three/-/three-0.143.0.tgz" resolved "https://registry.npmjs.org/three/-/three-0.143.0.tgz"
integrity sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg== integrity sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==
throttle-debounce@^3.0.1:
version "3.0.1"
resolved "https://registry.jetlinks.cn/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"
integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==
through2@^4.0.0: through2@^4.0.0:
version "4.0.2" version "4.0.2"
resolved "https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz" resolved "https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz"
@ -6940,6 +6950,11 @@ uuid@^3.3.2:
resolved "https://registry.jetlinks.cn/uuid/-/uuid-3.4.0.tgz" resolved "https://registry.jetlinks.cn/uuid/-/uuid-3.4.0.tgz"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
v-clipboard3@^0.1.4:
version "0.1.4"
resolved "https://registry.jetlinks.cn/v-clipboard3/-/v-clipboard3-0.1.4.tgz#13bdd12ce9728190d70f6ebf8b71de59d88b550e"
integrity sha512-iGIXgluf2WLbT+/Z1de9kKzoK9c9aPpy+zcPlY8/fneO+NHK95QEmFx2Q9LoxeUPRemD+nOfEv1J20Ki7W0v7Q==
v8-compile-cache-lib@^3.0.1: v8-compile-cache-lib@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" resolved "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz"
@ -7072,6 +7087,13 @@ vue-types@^3.0.0:
dependencies: dependencies:
is-plain-object "3.0.1" is-plain-object "3.0.1"
vue3-json-viewer@^2.2.2:
version "2.2.2"
resolved "https://registry.jetlinks.cn/vue3-json-viewer/-/vue3-json-viewer-2.2.2.tgz#43a512f378c602bb6b7f2a72adeaf7d15b443885"
integrity sha512-56l3XDGggnpwEqZieXsSMhNT4NhtO6d7zuSAxHo4i0UVxymyY2jRb7UMQOU1ztChKALZCAzX7DlgrsnEhxu77A==
dependencies:
clipboard "^2.0.10"
vue3-markdown-it@^1.0.10: vue3-markdown-it@^1.0.10:
version "1.0.10" version "1.0.10"
resolved "https://registry.npmmirror.com/vue3-markdown-it/-/vue3-markdown-it-1.0.10.tgz" resolved "https://registry.npmmirror.com/vue3-markdown-it/-/vue3-markdown-it-1.0.10.tgz"
@ -7099,7 +7121,16 @@ vue3-ts-jsoneditor@^2.7.1:
vanilla-jsoneditor "^0.7.9" vanilla-jsoneditor "^0.7.9"
vue "^3.2.37" vue "^3.2.37"
vue@^3.2.25: vue3-video-play@^1.3.1-beta.6:
version "1.3.1-beta.6"
resolved "https://registry.jetlinks.cn/vue3-video-play/-/vue3-video-play-1.3.1-beta.6.tgz#bca3f55a11053eaa37053835e4610c04d9cc509e"
integrity sha512-Olrx2/LNAds7fuor/yX9ZKT9sOcwcfTt2g2YbbCrEaAmZ5Tb0hwBr5z+/CoLwELzzRzXCHPmWWoT0Wm5W/Nwpw==
dependencies:
hls.js "^1.0.10"
throttle-debounce "^3.0.1"
vue "^3.2.2"
vue@^3.2.2, vue@^3.2.25:
version "3.2.47" version "3.2.47"
resolved "https://registry.jetlinks.cn/vue/-/vue-3.2.47.tgz#3eb736cbc606fc87038dbba6a154707c8a34cff0" resolved "https://registry.jetlinks.cn/vue/-/vue-3.2.47.tgz#3eb736cbc606fc87038dbba6a154707c8a34cff0"
integrity sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ== integrity sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==