fix: 自测修改设备管理
This commit is contained in:
parent
0589ea17ed
commit
db5514d27f
|
@ -100,7 +100,7 @@ export const deviceImport = (productId: string, fileUrl: string, autoDeploy: boo
|
||||||
* @param type 文件类型
|
* @param type 文件类型
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const deviceExport = (productId: string, type: string) => `${BASE_API_PATH}/device-instance${!!productId ? '/' + productId : ''}/export.${type}`
|
export const deviceExport = (productId: string, type: string) => `${BASE_API_PATH}/device-instance${!!productId ? `/${productId}` : ''}/export.${type}`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证设备ID是否重复
|
* 验证设备ID是否重复
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
name="file"
|
name="file"
|
||||||
:action="FILE_UPLOAD"
|
:action="FILE_UPLOAD"
|
||||||
:headers="{
|
:headers="{
|
||||||
'X-Access-Token': LocalStore.get(TOKEN_KEY)
|
'X-Access-Token': LocalStore.get(TOKEN_KEY),
|
||||||
}"
|
}"
|
||||||
accept=".xlsx,.csv"
|
accept=".xlsx,.csv"
|
||||||
:maxCount="1"
|
:maxCount="1"
|
||||||
|
@ -26,19 +26,23 @@
|
||||||
</a-space>
|
</a-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="进行中" />
|
<a-badge v-if="flag" status="processing" text="进行中" />
|
||||||
<a-badge v-else status="success" text="已完成" />
|
<a-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>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { FILE_UPLOAD } from '@/api/comm'
|
import { FILE_UPLOAD } from '@/api/comm';
|
||||||
import { TOKEN_KEY } from '@/utils/variable';
|
import { 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 { deviceImport, deviceTemplateDownload ,templateDownload} from '@/api/device/instance'
|
import {
|
||||||
import { EventSourcePolyfill } from 'event-source-polyfill'
|
deviceImport,
|
||||||
|
deviceTemplateDownload,
|
||||||
|
templateDownload,
|
||||||
|
} from '@/api/device/instance';
|
||||||
|
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
type Emits = {
|
type Emits = {
|
||||||
|
@ -50,11 +54,11 @@ const props = defineProps({
|
||||||
// 组件双向绑定的值
|
// 组件双向绑定的值
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
product: {
|
product: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -62,67 +66,62 @@ const props = defineProps({
|
||||||
return {
|
return {
|
||||||
fileType: 'xlsx',
|
fileType: 'xlsx',
|
||||||
autoDeploy: false,
|
autoDeploy: false,
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const importLoading = ref<boolean>(false)
|
const importLoading = ref<boolean>(false);
|
||||||
const flag = ref<boolean>(false)
|
const flag = ref<boolean>(false);
|
||||||
const count = ref<number>(0)
|
const count = ref<number>(0);
|
||||||
const errMessage = ref<string>('')
|
const errMessage = ref<string>('');
|
||||||
|
|
||||||
const downFile =async (type: string) => {
|
const downFile = async (type: string) => {
|
||||||
// downloadFile(deviceTemplateDownload(props.product, type));
|
// downloadFile(deviceTemplateDownload(props.product, type));
|
||||||
const res:any =await templateDownload(props.product, type)
|
const res: any = await templateDownload(props.product, type);
|
||||||
if(res){
|
if (res) {
|
||||||
const blob = new Blob([res], { type: type });
|
const blob = new Blob([res], { type: type });
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
console.log(url);
|
downloadFileByUrl(url, `设备导入模版`, type);
|
||||||
downloadFileByUrl(
|
|
||||||
url,
|
|
||||||
`设备导入模版`,
|
|
||||||
type,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const submitData = async (fileUrl: string) => {
|
const submitData = async (fileUrl: string) => {
|
||||||
if (!!fileUrl) {
|
if (!!fileUrl) {
|
||||||
count.value = 0
|
count.value = 0;
|
||||||
errMessage.value = ''
|
errMessage.value = '';
|
||||||
flag.value = true
|
flag.value = true;
|
||||||
const autoDeploy = !!props?.file?.autoDeploy || false;
|
const autoDeploy = !!props?.file?.autoDeploy || false;
|
||||||
importLoading.value = true
|
importLoading.value = true;
|
||||||
let dt = 0;
|
let dt = 0;
|
||||||
const source = new EventSourcePolyfill(deviceImport(props.product, fileUrl, autoDeploy));
|
const source = new EventSourcePolyfill(
|
||||||
source.onmessage = (e: any) => {
|
deviceImport(props.product, fileUrl, autoDeploy),
|
||||||
const res = JSON.parse(e.data);
|
);
|
||||||
if (res.success) {
|
source.onmessage = (e: any) => {
|
||||||
const temp = res.result.total;
|
const res = JSON.parse(e.data);
|
||||||
dt += temp;
|
if (res.success) {
|
||||||
count.value = dt
|
const temp = res.result.total;
|
||||||
} else {
|
dt += temp;
|
||||||
errMessage.value = res.message || '失败'
|
count.value = dt;
|
||||||
}
|
} else {
|
||||||
};
|
errMessage.value = res.message || '失败';
|
||||||
source.onerror = (e: { status: number; }) => {
|
}
|
||||||
if (e.status === 403) errMessage.value = '暂无权限,请联系管理员'
|
};
|
||||||
flag.value = false
|
source.onerror = (e: { status: number }) => {
|
||||||
source.close();
|
if (e.status === 403) errMessage.value = '暂无权限,请联系管理员';
|
||||||
};
|
flag.value = false;
|
||||||
source.onopen = () => {};
|
source.close();
|
||||||
|
};
|
||||||
|
source.onopen = () => {};
|
||||||
} else {
|
} else {
|
||||||
message.error('请先上传文件')
|
message.error('请先上传文件');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const uploadChange = async (info: Record<string, any>) => {
|
const uploadChange = async (info: Record<string, any>) => {
|
||||||
if (info.file.status === 'done') {
|
if (info.file.status === 'done') {
|
||||||
const resp: any = info.file.response || { result: '' };
|
const resp: any = info.file.response || { result: '' };
|
||||||
await submitData(resp?.result || '');
|
await submitData(resp?.result || '');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
|
@ -1693,7 +1693,7 @@ const Status = defineComponent({
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{
|
{
|
||||||
bindParentVisible && (
|
bindParentVisible.value && (
|
||||||
<BindParentDevice
|
<BindParentDevice
|
||||||
data={device.value}
|
data={device.value}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
instanceStore.current.deviceType?.text
|
instanceStore.current.deviceType?.text
|
||||||
}}</j-descriptions-item>
|
}}</j-descriptions-item>
|
||||||
<j-descriptions-item label="固件版本">{{
|
<j-descriptions-item label="固件版本">{{
|
||||||
instanceStore.current.firmwareInfo?.version
|
instanceStore.current?.firmwareInfo?.version
|
||||||
}}</j-descriptions-item>
|
}}</j-descriptions-item>
|
||||||
<j-descriptions-item label="连接协议">{{
|
<j-descriptions-item label="连接协议">{{
|
||||||
instanceStore.current?.protocolName
|
instanceStore.current?.transport
|
||||||
}}</j-descriptions-item>
|
}}</j-descriptions-item>
|
||||||
<j-descriptions-item label="消息协议">{{
|
<j-descriptions-item label="消息协议">{{
|
||||||
instanceStore.current.transport
|
instanceStore.current.protocolName
|
||||||
}}</j-descriptions-item>
|
}}</j-descriptions-item>
|
||||||
<j-descriptions-item label="创建时间">{{
|
<j-descriptions-item label="创建时间">{{
|
||||||
instanceStore.current.createTime
|
instanceStore.current.createTime
|
||||||
|
|
|
@ -109,7 +109,9 @@ const loading = ref<boolean>(false);
|
||||||
const instanceStore = useInstanceStore();
|
const instanceStore = useInstanceStore();
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
|
||||||
const modelRef = reactive({
|
const modelRef = reactive<{
|
||||||
|
metrics: any[]
|
||||||
|
}>({
|
||||||
metrics: [],
|
metrics: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,12 @@
|
||||||
:tab="i.tab"
|
:tab="i.tab"
|
||||||
/>
|
/>
|
||||||
</j-tabs>
|
</j-tabs>
|
||||||
<JEmpty v-else style="margin: 250px 0" />
|
<JEmpty v-else style="margin: 180px 0" />
|
||||||
</div>
|
</div>
|
||||||
<div class="property-box-right">
|
<div class="property-box-right">
|
||||||
<Event v-if="type === 'event'" :data="data" />
|
<Event v-if="type === 'event'" :data="data" />
|
||||||
<Property v-else :data="properties" />
|
<Property v-else-if="type === 'property'" :data="properties" />
|
||||||
|
<JEmpty v-else style="margin: 220px 0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</j-card>
|
</j-card>
|
||||||
|
@ -97,6 +98,13 @@ const onSearch = () => {
|
||||||
} else {
|
} else {
|
||||||
tabList.value = _.cloneDeep(arr)
|
tabList.value = _.cloneDeep(arr)
|
||||||
}
|
}
|
||||||
|
const dt = tabList.value?.[0]
|
||||||
|
if (dt) {
|
||||||
|
data.value = dt
|
||||||
|
type.value = dt.type;
|
||||||
|
} else {
|
||||||
|
type.value = ''
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const tabChange = (key: string) => {
|
const tabChange = (key: string) => {
|
||||||
const dt = tabList.value.find((i) => i.key === key);
|
const dt = tabList.value.find((i) => i.key === key);
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
<div>
|
<div>
|
||||||
<div style="display: flex; align-items: center">
|
<div style="display: flex; align-items: center">
|
||||||
<AIcon type="ArrowLeftOutlined" @click="onBack" />
|
<AIcon type="ArrowLeftOutlined" @click="onBack" />
|
||||||
<div style="margin-left: 20px">{{ instanceStore.current.name }}</div>
|
<div style="margin-left: 20px">
|
||||||
|
{{ instanceStore.current.name }}
|
||||||
|
</div>
|
||||||
<j-divider type="vertical" />
|
<j-divider type="vertical" />
|
||||||
<j-space>
|
<j-space>
|
||||||
<j-badge
|
<j-badge
|
||||||
|
@ -79,7 +81,7 @@
|
||||||
<j-descriptions-item label="所属产品">
|
<j-descriptions-item label="所属产品">
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
type="link"
|
type="link"
|
||||||
style="margin-top: -5px; padding: 0"
|
style="margin-top: -5px; padding: 0"
|
||||||
@click="jumpProduct"
|
@click="jumpProduct"
|
||||||
hasPermission="device/Product:view"
|
hasPermission="device/Product:view"
|
||||||
>
|
>
|
||||||
|
@ -116,8 +118,8 @@ import Function from './Function/index.vue';
|
||||||
import Modbus from './Modbus/index.vue';
|
import Modbus from './Modbus/index.vue';
|
||||||
import OPCUA from './OPCUA/index.vue';
|
import OPCUA from './OPCUA/index.vue';
|
||||||
import EdgeMap from './EdgeMap/index.vue';
|
import EdgeMap from './EdgeMap/index.vue';
|
||||||
import Parsing from './Parsing/index.vue'
|
import Parsing from './Parsing/index.vue';
|
||||||
import Log from './Log/index.vue'
|
import Log from './Log/index.vue';
|
||||||
import { _deploy, _disconnect } from '@/api/device/instance';
|
import { _deploy, _disconnect } from '@/api/device/instance';
|
||||||
import { message } from 'jetlinks-ui-components';
|
import { message } from 'jetlinks-ui-components';
|
||||||
import { getImage } from '@/utils/comm';
|
import { getImage } from '@/utils/comm';
|
||||||
|
@ -149,17 +151,13 @@ const list = ref([
|
||||||
key: 'Metadata',
|
key: 'Metadata',
|
||||||
tab: '物模型',
|
tab: '物模型',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'Log',
|
|
||||||
tab: '日志管理',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'Function',
|
key: 'Function',
|
||||||
tab: '设备功能',
|
tab: '设备功能',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ChildDevice',
|
key: 'Log',
|
||||||
tab: '子设备',
|
tab: '日志管理',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -174,7 +172,7 @@ const tabs = {
|
||||||
OPCUA,
|
OPCUA,
|
||||||
EdgeMap,
|
EdgeMap,
|
||||||
Parsing,
|
Parsing,
|
||||||
Log
|
Log,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStatus = (id: string) => {
|
const getStatus = (id: string) => {
|
||||||
|
@ -255,6 +253,17 @@ watchEffect(() => {
|
||||||
tab: '设备诊断',
|
tab: '设备诊断',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
instanceStore.current.features?.find(
|
||||||
|
(item: any) => item.id === 'transparentCodec',
|
||||||
|
) &&
|
||||||
|
!keys.includes('Parsing')
|
||||||
|
) {
|
||||||
|
list.value.push({
|
||||||
|
key: 'Parsing',
|
||||||
|
tab: '数据解析',
|
||||||
|
});
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
instanceStore.current.protocol === 'modbus-tcp' &&
|
instanceStore.current.protocol === 'modbus-tcp' &&
|
||||||
!keys.includes('Modbus')
|
!keys.includes('Modbus')
|
||||||
|
@ -273,6 +282,13 @@ watchEffect(() => {
|
||||||
tab: 'OPC UA',
|
tab: 'OPC UA',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (instanceStore.current.deviceType?.value === 'gateway') {
|
||||||
|
// 产品类型为网关的情况下才显示此模块
|
||||||
|
list.value.push({
|
||||||
|
key: 'ChildDevice',
|
||||||
|
tab: '子设备',
|
||||||
|
});
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
instanceStore.current.accessProvider === 'edge-child-device' &&
|
instanceStore.current.accessProvider === 'edge-child-device' &&
|
||||||
instanceStore.current.parentId &&
|
instanceStore.current.parentId &&
|
||||||
|
@ -283,15 +299,6 @@ watchEffect(() => {
|
||||||
tab: '边缘端映射',
|
tab: '边缘端映射',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
instanceStore.current.features?.find((item: any) => item.id === 'transparentCodec') &&
|
|
||||||
!keys.includes('Parsing')
|
|
||||||
) {
|
|
||||||
list.value.push({
|
|
||||||
key: 'Parsing',
|
|
||||||
tab: '数据解析',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
import { queryNoPagingPost } from '@/api/device/product';
|
import { queryNoPagingPost } from '@/api/device/product';
|
||||||
import { downloadFile } from '@/utils/utils';
|
import { downloadFile } from '@/utils/utils';
|
||||||
import encodeQuery from '@/utils/encodeQuery';
|
import encodeQuery from '@/utils/encodeQuery';
|
||||||
import { BASE_API_PATH } from '@/utils/variable';
|
|
||||||
import { deviceExport } from '@/api/device/instance';
|
import { deviceExport } from '@/api/device/instance';
|
||||||
|
|
||||||
const emit = defineEmits(['close']);
|
const emit = defineEmits(['close']);
|
||||||
|
|
|
@ -1,92 +1,106 @@
|
||||||
<template>
|
<template>
|
||||||
<j-modal :maskClosable="false" width="800px" :visible="true" title="当前进度" @ok="handleCancel" @cancel="handleCancel">
|
<j-modal
|
||||||
|
:maskClosable="false"
|
||||||
|
width="800px"
|
||||||
|
:visible="true"
|
||||||
|
title="当前进度"
|
||||||
|
@ok="handleCancel"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<j-badge v-if="flag" status="processing" text="进行中" />
|
<j-badge v-if="flag" status="processing" text="进行中" />
|
||||||
<j-badge v-else status="success" text="已完成" />
|
<j-badge v-else status="success" text="已完成" />
|
||||||
</div>
|
</div>
|
||||||
<p>总数量:{{count}}</p>
|
<p>总数量:{{ count }}</p>
|
||||||
<a style="color: red">{{errMessage}}</a>
|
<a style="color: red">{{ errMessage }}</a>
|
||||||
</j-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { EventSourcePolyfill } from 'event-source-polyfill'
|
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||||
|
|
||||||
const emit = defineEmits(['close'])
|
const emit = defineEmits(['close', 'save']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
api: {
|
api: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
const eventSource = ref<Record<string, any>>({})
|
// const eventSource = ref<Record<string, any>>({})
|
||||||
const count = ref<number>(0)
|
const count = ref<number>(0);
|
||||||
const flag = ref<boolean>(false)
|
const flag = ref<boolean>(false);
|
||||||
const errMessage = ref<string>('')
|
const errMessage = ref<string>('');
|
||||||
const isSource = ref<boolean>(false)
|
const isSource = ref<boolean>(false);
|
||||||
const id = ref<string>('')
|
const id = ref<string>('');
|
||||||
const source = ref<Record<string, any>>({})
|
const source = ref<Record<string, any>>({});
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
emit('close')
|
emit('close');
|
||||||
}
|
emit('save');
|
||||||
|
};
|
||||||
|
|
||||||
|
// const handleOk = () => {
|
||||||
|
// emit('close');
|
||||||
|
// emit('save');
|
||||||
|
// };
|
||||||
|
|
||||||
const getData = (api: string) => {
|
const getData = (api: string) => {
|
||||||
let dt = 0
|
let dt = 0;
|
||||||
const _source = new EventSourcePolyfill(api)
|
const _source = new EventSourcePolyfill(api);
|
||||||
source.value = _source
|
source.value = _source;
|
||||||
_source.onmessage = (e: any) => {
|
_source.onmessage = (e: any) => {
|
||||||
const res = JSON.parse(e.data);
|
const res = JSON.parse(e.data);
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
case 'active':
|
case 'active':
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
dt += res.total;
|
dt += res.total;
|
||||||
count.value = dt
|
count.value = dt;
|
||||||
} else {
|
} else {
|
||||||
if (res.source) {
|
if (res.source) {
|
||||||
const msg = `${res.source.name}: ${res.message}`;
|
const msg = `${res.source.name}: ${res.message}`;
|
||||||
errMessage.value = msg
|
errMessage.value = msg;
|
||||||
id.value = res.source.id
|
id.value = res.source.id;
|
||||||
isSource.value = true
|
isSource.value = true;
|
||||||
} else {
|
} else {
|
||||||
errMessage.value = res.message
|
errMessage.value = res.message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'sync':
|
case 'sync':
|
||||||
dt += res;
|
dt += res;
|
||||||
count.value = dt
|
count.value = dt;
|
||||||
break;
|
break;
|
||||||
case 'import':
|
case 'import':
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
const temp = res.result.total;
|
const temp = res.result.total;
|
||||||
dt += temp;
|
dt += temp;
|
||||||
count.value = dt
|
count.value = dt;
|
||||||
} else {
|
} else {
|
||||||
errMessage.value = res.message
|
errMessage.value = res.message;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_source.onerror = () => {
|
_source.onerror = () => {
|
||||||
flag.value = false
|
flag.value = false;
|
||||||
_source.close();
|
_source.close();
|
||||||
};
|
};
|
||||||
_source.onopen = () => {};
|
_source.onopen = () => {};
|
||||||
}
|
};
|
||||||
|
|
||||||
watch(() => props.api,
|
watch(
|
||||||
|
() => props.api,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if(newValue) {
|
if (newValue) {
|
||||||
getData(newValue)
|
getData(newValue);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{deep: true, immediate: true}
|
{ deep: true, immediate: true },
|
||||||
)
|
);
|
||||||
</script>
|
</script>
|
|
@ -9,12 +9,7 @@
|
||||||
:confirmLoading="loading"
|
:confirmLoading="loading"
|
||||||
>
|
>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 10px">
|
||||||
<j-form
|
<j-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||||
:layout="'vertical'"
|
|
||||||
ref="formRef"
|
|
||||||
:rules="rules"
|
|
||||||
:model="modelRef"
|
|
||||||
>
|
|
||||||
<j-row type="flex">
|
<j-row type="flex">
|
||||||
<j-col flex="180px">
|
<j-col flex="180px">
|
||||||
<j-form-item name="photoUrl">
|
<j-form-item name="photoUrl">
|
||||||
|
@ -22,14 +17,33 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</j-col>
|
</j-col>
|
||||||
<j-col flex="auto">
|
<j-col flex="auto">
|
||||||
<j-form-item name="id">
|
<j-form-item
|
||||||
|
name="id"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
pattern: /^[a-zA-Z0-9_\-]+$/,
|
||||||
|
message: '请输入英文或者数字或者-或者_',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
max: 64,
|
||||||
|
message: '最多输入64个字符',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: vailId,
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>
|
<span>
|
||||||
ID
|
ID
|
||||||
<j-tooltip title="若不填写,系统将自动生成唯一ID">
|
<j-tooltip
|
||||||
|
title="若不填写,系统将自动生成唯一ID"
|
||||||
|
>
|
||||||
<AIcon
|
<AIcon
|
||||||
type="QuestionCircleOutlined"
|
type="QuestionCircleOutlined"
|
||||||
style="margin-left: 2px;" />
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
</j-tooltip>
|
</j-tooltip>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -39,7 +53,20 @@
|
||||||
:disabled="!!data?.id"
|
:disabled="!!data?.id"
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<j-form-item label="名称" name="name">
|
<j-form-item
|
||||||
|
label="名称"
|
||||||
|
name="name"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入名称',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
max: 64,
|
||||||
|
message: '最多输入64个字符',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<j-input
|
<j-input
|
||||||
v-model:value="modelRef.name"
|
v-model:value="modelRef.name"
|
||||||
placeholder="请输入名称"
|
placeholder="请输入名称"
|
||||||
|
@ -47,13 +74,23 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</j-col>
|
</j-col>
|
||||||
</j-row>
|
</j-row>
|
||||||
<j-form-item name="productId">
|
<j-form-item
|
||||||
|
name="productId"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择所属产品',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>所属产品
|
<span
|
||||||
|
>所属产品
|
||||||
<j-tooltip title="只能选择“正常”状态的产品">
|
<j-tooltip title="只能选择“正常”状态的产品">
|
||||||
<AIcon
|
<AIcon
|
||||||
type="QuestionCircleOutlined"
|
type="QuestionCircleOutlined"
|
||||||
style="margin-left: 2px" />
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
</j-tooltip>
|
</j-tooltip>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -68,10 +105,20 @@
|
||||||
v-for="item in productList"
|
v-for="item in productList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
>{{item.name}}</j-select-option>
|
>{{ item.name }}</j-select-option
|
||||||
|
>
|
||||||
</j-select>
|
</j-select>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<j-form-item label="说明" name="describe">
|
<j-form-item
|
||||||
|
label="说明"
|
||||||
|
name="describe"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
max: 200,
|
||||||
|
message: '最多输入200个字符'
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<j-textarea
|
<j-textarea
|
||||||
v-model:value="modelRef.describe"
|
v-model:value="modelRef.describe"
|
||||||
placeholder="请输入说明"
|
placeholder="请输入说明"
|
||||||
|
@ -123,45 +170,6 @@ const vailId = async (_: Record<string, any>, value: string) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const rules = {
|
|
||||||
name: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
max: 64,
|
|
||||||
message: '最多输入64个字符',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
photoUrl: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请上传图标',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
productId: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择所属产品',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
id: [
|
|
||||||
{
|
|
||||||
max: 64,
|
|
||||||
message: '最多输入64个字符',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: /^[j-zA-Z0-9_\-]+$/,
|
|
||||||
message: '请输入英文或者数字或者-或者_',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
validator: vailId,
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.data,
|
() => props.data,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
|
@ -199,13 +207,13 @@ const handleSave = () => {
|
||||||
.validate()
|
.validate()
|
||||||
.then(async (_data: any) => {
|
.then(async (_data: any) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const obj = {...toRaw(modelRef), ..._data}
|
const obj = { ..._data };
|
||||||
if(!obj.id){
|
if (!obj.id) {
|
||||||
delete obj.id
|
delete obj.id;
|
||||||
}
|
}
|
||||||
const resp = await update(obj).finally(() => {
|
const resp = await update(obj).finally(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
})
|
});
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
message.success('操作成功!');
|
message.success('操作成功!');
|
||||||
emit('save');
|
emit('save');
|
||||||
|
|
|
@ -252,6 +252,7 @@
|
||||||
@close="operationVisible = false"
|
@close="operationVisible = false"
|
||||||
:api="api"
|
:api="api"
|
||||||
:type="type"
|
:type="type"
|
||||||
|
@save="onRefresh"
|
||||||
/>
|
/>
|
||||||
<Save
|
<Save
|
||||||
v-if="visible"
|
v-if="visible"
|
||||||
|
@ -314,6 +315,7 @@ const columns = [
|
||||||
key: 'id',
|
key: 'id',
|
||||||
search: {
|
search: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
defaultTermType: 'eq'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -322,6 +324,7 @@ const columns = [
|
||||||
key: 'name',
|
key: 'name',
|
||||||
search: {
|
search: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
first: true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -389,6 +392,7 @@ const columns = [
|
||||||
hideInTable: true,
|
hideInTable: true,
|
||||||
search: {
|
search: {
|
||||||
type: 'select',
|
type: 'select',
|
||||||
|
rename: 'productId$product-info',
|
||||||
options: () =>
|
options: () =>
|
||||||
new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
getProviders().then((resp: any) => {
|
getProviders().then((resp: any) => {
|
||||||
|
|
|
@ -13,17 +13,16 @@
|
||||||
import { useSceneStore } from '@/store/scene';
|
import { useSceneStore } from '@/store/scene';
|
||||||
import Action from '../action/index.vue';
|
import Action from '../action/index.vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { ActionsType } from '@/components/Table';
|
import { ActionsType } from '@/views/rule-engine/Scene/typings';
|
||||||
|
|
||||||
const sceneStore = useSceneStore();
|
const sceneStore = useSceneStore();
|
||||||
const { data } = storeToRefs(sceneStore);
|
const { data } = storeToRefs(sceneStore);
|
||||||
|
|
||||||
const onActionAdd = (_data: ActionsType) => {
|
const onActionAdd = (_data: any) => {
|
||||||
console.log(_data)
|
if (data.value?.branches && _data) {
|
||||||
// if (data?.branches && _data) {
|
data?.value.branches?.[0].then.push(_data)
|
||||||
// const newThen = [...data?.branches?.[0].then, data];
|
console.log(data?.value.branches?.[0].then)
|
||||||
// data.branches[0].then = newThen;
|
}
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onActionUpdate = (_data: ActionsType, type: boolean) => {
|
const onActionUpdate = (_data: ActionsType, type: boolean) => {
|
||||||
|
|
|
@ -18,13 +18,7 @@
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<!-- <j-card-select
|
<CardSelect v-model:value="formModel.type" :options="options"/>
|
||||||
v-model:value="formModel.type"
|
|
||||||
:options="options"
|
|
||||||
type="horizontal"
|
|
||||||
float="right"
|
|
||||||
/> -->
|
|
||||||
<a-radio-group v-model:value="formModel.type" :options="options" />
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<ActionTypeComponent
|
<ActionTypeComponent
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
|
@ -46,6 +40,7 @@ import { PropType } from 'vue';
|
||||||
import { ActionsType } from '../../../typings';
|
import { ActionsType } from '../../../typings';
|
||||||
import ActionTypeComponent from './ActionTypeComponent.vue';
|
import ActionTypeComponent from './ActionTypeComponent.vue';
|
||||||
import { randomString } from '@/utils/utils';
|
import { randomString } from '@/utils/utils';
|
||||||
|
import CardSelect from '../../components/CardSelect.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
branchesName: {
|
branchesName: {
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<a-spin :spinning="loading">
|
<a-spin :spinning="loading">
|
||||||
<!-- <j-card-select
|
<div class="notify-type-warp" :class="{ disabled: disabled }">
|
||||||
v-model:value="notifyType"
|
<div
|
||||||
:options="options"
|
:key="item.id"
|
||||||
:icon-size="106"
|
v-for="item in options"
|
||||||
/> -->
|
class="notify-type-item"
|
||||||
<a-radio-group v-model:value="notifyType" :options="options" @change="onRadioChange" />
|
:class="{ active: notifyType === item.value }"
|
||||||
|
@click="onSelect(item.value)"
|
||||||
|
>
|
||||||
|
<div class="notify-type-item-image">
|
||||||
|
<img :width="106" :src="item.iconUrl" />
|
||||||
|
</div>
|
||||||
|
<div class="notify-type-item-title">{{item.label}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -26,9 +34,13 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:value'])
|
const emit = defineEmits(['update:value']);
|
||||||
|
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const notifyType = ref('');
|
const notifyType = ref('');
|
||||||
|
@ -37,17 +49,19 @@ const options = ref<any[]>([]);
|
||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
notifyType.value = newVal
|
notifyType.value = newVal;
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true },
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
const onRadioChange = (e: any) => {
|
const onSelect = (val: string) => {
|
||||||
emit('update:value', e.target.value)
|
if (!props.disabled) {
|
||||||
}
|
emit('update:value', val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
notice.queryMessageType().then((resp) => {
|
notice.queryMessageType().then((resp) => {
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
options.value = (resp.result as any[]).map((item) => {
|
options.value = (resp.result as any[]).map((item) => {
|
||||||
|
@ -58,11 +72,65 @@ onMounted(() => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
loading.value = false
|
loading.value = false;
|
||||||
});
|
});
|
||||||
notifyType.value = props.value
|
notifyType.value = props.value;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
.notify-type-warp {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 16px 24px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.notify-type-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 172px;
|
||||||
|
border: 1px solid #e0e4e8;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
.notify-type-item-title {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notify-type-item-image {
|
||||||
|
width: 106px;
|
||||||
|
margin: 16px 33px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @primary-color-hover;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-color: @primary-color-active;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
.notify-type-item {
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: initial;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -26,7 +26,7 @@
|
||||||
:actions="
|
:actions="
|
||||||
serialArray.length ? serialArray[0].actions : []
|
serialArray.length ? serialArray[0].actions : []
|
||||||
"
|
"
|
||||||
@add="onAdd"
|
@add="(_item) => onAdd(_item, false)"
|
||||||
@delete="onDelete"
|
@delete="onDelete"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
? parallelArray[0].actions
|
? parallelArray[0].actions
|
||||||
: []
|
: []
|
||||||
"
|
"
|
||||||
@add="onAdd"
|
@add="(_item) => onAdd(_item, true)"
|
||||||
@delete="onDelete"
|
@delete="onDelete"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,6 +98,8 @@ watch(
|
||||||
parallelArray.value = newVal.filter((item) => item.parallel);
|
parallelArray.value = newVal.filter((item) => item.parallel);
|
||||||
serialArray.value = newVal.filter((item) => !item.parallel);
|
serialArray.value = newVal.filter((item) => !item.parallel);
|
||||||
|
|
||||||
|
console.log(parallelArray.value, serialArray.value, '123')
|
||||||
|
|
||||||
const isSerialActions = serialArray.value.some((item) => {
|
const isSerialActions = serialArray.value.some((item) => {
|
||||||
return !!item.actions.length;
|
return !!item.actions.length;
|
||||||
});
|
});
|
||||||
|
@ -128,7 +130,7 @@ const onDelete = (_key: string) => {
|
||||||
emit('update', serialArray[0], false);
|
emit('update', serialArray[0], false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const onAdd = (actionItem: any) => {
|
const onAdd = (actionItem: any, _parallel: boolean) => {
|
||||||
const newParallelArray = [...parallelArray.value];
|
const newParallelArray = [...parallelArray.value];
|
||||||
if (newParallelArray.length) {
|
if (newParallelArray.length) {
|
||||||
const indexOf = newParallelArray[0].actions?.findIndex(
|
const indexOf = newParallelArray[0].actions?.findIndex(
|
||||||
|
@ -140,12 +142,11 @@ const onAdd = (actionItem: any) => {
|
||||||
newParallelArray[0].actions.push(actionItem);
|
newParallelArray[0].actions.push(actionItem);
|
||||||
}
|
}
|
||||||
parallelArray.value = [...newParallelArray];
|
parallelArray.value = [...newParallelArray];
|
||||||
console.log(parallelArray.value);
|
emit('update', newParallelArray[0], _parallel);
|
||||||
emit('update', newParallelArray[0], true);
|
|
||||||
} else {
|
} else {
|
||||||
actionItem.key = randomString();
|
actionItem.key = randomString();
|
||||||
emit('add', {
|
emit('add', {
|
||||||
parallel: true,
|
parallel: _parallel,
|
||||||
key: randomString(),
|
key: randomString(),
|
||||||
actions: [actionItem],
|
actions: [actionItem],
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
<template>
|
||||||
|
<div class="scene-trigger-way-warp" :class="{disabled: disabled}">
|
||||||
|
<template v-for="item in options" :key="item.value">
|
||||||
|
<div
|
||||||
|
class="trigger-way-item"
|
||||||
|
:class="{ active: item?.value === value }"
|
||||||
|
:style="{width: `${cardSize}px`}"
|
||||||
|
@click="onSelect(item.value)"
|
||||||
|
>
|
||||||
|
<div class="way-item-title">
|
||||||
|
<p>{{ item.label }}</p>
|
||||||
|
<span>{{ item.subLabel }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="way-item-image">
|
||||||
|
<img :src="item.iconUrl" :width="imageSize" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { PropType } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array as PropType<any[]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String as PropType<'vertical' | 'horizontal'>,
|
||||||
|
default: 'horizontal',
|
||||||
|
},
|
||||||
|
imageSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 48
|
||||||
|
},
|
||||||
|
cardSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 237
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:value'])
|
||||||
|
|
||||||
|
const onSelect = (_type: string) => {
|
||||||
|
if (!props.disabled) {
|
||||||
|
emit('update:value', _type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.scene-trigger-way-warp {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 16px 24px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.trigger-way-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid #e0e4e8;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
.way-item-title {
|
||||||
|
p {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: rgba(#000, 0.35);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.way-item-image {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 !important;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @primary-color-hover;
|
||||||
|
.way-item-image {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-color: @primary-color-active;
|
||||||
|
.way-item-image {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
.trigger-way-item {
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: initial;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue