fix: 修改设备新增
This commit is contained in:
parent
21e45c060d
commit
66234bdfd4
|
@ -28,5 +28,4 @@ const props = defineProps({
|
|||
*/
|
||||
statusNames: { type: Object },
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="upload-image-warp">
|
||||
<div class="upload-image-border">
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
list-type="picture-card"
|
||||
class="avatar-uploader"
|
||||
|
@ -45,7 +45,7 @@
|
|||
/>
|
||||
</template>
|
||||
</div>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
<div class="upload-loading-mask" v-if="props.disabled"></div>
|
||||
<div class="upload-loading-mask" v-if="imageUrl && loading">
|
||||
<AIcon type="LoadingOutlined" style="font-size: 20px" />
|
||||
|
|
|
@ -8,7 +8,7 @@ import CardBox from './CardBox/index.vue';
|
|||
// import Search from './Search'
|
||||
import NormalUpload from './NormalUpload/index.vue'
|
||||
import FileFormat from './FileFormat/index.vue'
|
||||
// import JUpload from './JUpload/index.vue'
|
||||
import JProUpload from './JUpload/index.vue'
|
||||
import { BasicLayoutPage, BlankLayoutPage } from './Layout'
|
||||
import { PageContainer } from 'jetlinks-ui-components/es/components'
|
||||
import Ellipsis from './Ellipsis/index.vue'
|
||||
|
@ -27,7 +27,7 @@ export default {
|
|||
// .component('Search', Search)
|
||||
.component('NormalUpload', NormalUpload)
|
||||
.component('FileFormat', FileFormat)
|
||||
// .component('JUpload', JUpload)
|
||||
.component('JProUpload', JProUpload)
|
||||
.component('BasicLayoutPage', BasicLayoutPage)
|
||||
.component('BlankLayoutPage', BlankLayoutPage)
|
||||
.component('PageContainer', PageContainer)
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<template>
|
||||
<a-modal :maskClosable="false" width="800px" :visible="true" title="导出" @ok="handleOk" @cancel="handleCancel">
|
||||
<j-modal
|
||||
:maskClosable="false"
|
||||
width="800px"
|
||||
:visible="true"
|
||||
title="导出"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<div style="background-color: rgb(236, 237, 238)">
|
||||
<p style="padding: 10px">
|
||||
<AIcon type="ExclamationCircleOutlined" />
|
||||
|
@ -7,63 +14,86 @@
|
|||
</p>
|
||||
</div>
|
||||
<div style="margin-top: 20px">
|
||||
<a-form :layout="'vertical'">
|
||||
<a-form-item label="产品">
|
||||
<a-select showSearch v-model:value="modelRef.product" placeholder="请选择产品">
|
||||
<a-select-option :value="item.id" v-for="item in productList" :key="item.id" :title="item.name"></a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="文件格式">
|
||||
<a-radio-group button-style="solid" v-model:value="modelRef.fileType" placeholder="请选择文件格式">
|
||||
<a-radio-button value="xlsx">xlsx</a-radio-button>
|
||||
<a-radio-button value="csv">csv</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<j-form :layout="'vertical'">
|
||||
<j-form-item label="产品">
|
||||
<j-select
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
v-model:value="modelRef.product"
|
||||
placeholder="请选择产品"
|
||||
allowClear
|
||||
>
|
||||
<j-select-option
|
||||
:value="item.id"
|
||||
v-for="item in productList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
>{{ item.name }}</j-select-option
|
||||
>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
<j-form-item label="文件格式">
|
||||
<j-radio-group
|
||||
button-style="solid"
|
||||
v-model:value="modelRef.fileType"
|
||||
placeholder="请选择文件格式"
|
||||
>
|
||||
<j-radio-button value="xlsx">xlsx</j-radio-button>
|
||||
<j-radio-button value="csv">csv</j-radio-button>
|
||||
</j-radio-group>
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</div>
|
||||
</a-modal>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { queryNoPagingPost } from '@/api/device/product'
|
||||
import { downloadFile } from '@/utils/utils'
|
||||
import encodeQuery from '@/utils/encodeQuery'
|
||||
import { BASE_API_PATH } from '@/utils/variable'
|
||||
import { deviceExport } from '@/api/device/instance'
|
||||
import { queryNoPagingPost } from '@/api/device/product';
|
||||
import { downloadFile } from '@/utils/utils';
|
||||
import encodeQuery from '@/utils/encodeQuery';
|
||||
import { BASE_API_PATH } from '@/utils/variable';
|
||||
import { deviceExport } from '@/api/device/instance';
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
const emit = defineEmits(['close']);
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
}
|
||||
})
|
||||
default: undefined,
|
||||
},
|
||||
});
|
||||
const modelRef = reactive({
|
||||
product: undefined,
|
||||
fileType: 'xlsx'
|
||||
fileType: 'xlsx',
|
||||
});
|
||||
|
||||
const productList = ref<Record<string, any>[]>([])
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
};
|
||||
|
||||
const productList = ref<Record<string, any>[]>([]);
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
() => {
|
||||
queryNoPagingPost({paging: false}).then(resp => {
|
||||
if(resp.status === 200){
|
||||
productList.value = resp.result as Record<string, any>[]
|
||||
queryNoPagingPost({ paging: false }).then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
productList.value = resp.result as Record<string, any>[];
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
{immediate: true, deep: true}
|
||||
)
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
|
||||
const handleOk = () => {
|
||||
const params = encodeQuery(props.data);
|
||||
downloadFile(deviceExport(modelRef.product || "", modelRef.fileType),params);
|
||||
emit('close')
|
||||
}
|
||||
downloadFile(
|
||||
deviceExport(modelRef.product || '', modelRef.fileType),
|
||||
params,
|
||||
);
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
emit('close')
|
||||
}
|
||||
emit('close');
|
||||
};
|
||||
</script>
|
|
@ -1,36 +1,35 @@
|
|||
<template>
|
||||
<a-modal :maskClosable="false" width="800px" :visible="true" title="导入" @ok="handleCancel" @cancel="handleCancel">
|
||||
<j-modal :maskClosable="false" width="800px" :visible="true" title="导入" @ok="handleSave" @cancel="handleCancel">
|
||||
<div style="margin-top: 10px">
|
||||
<a-form :layout="'vertical'">
|
||||
<a-row>
|
||||
<a-col span="24">
|
||||
<a-form-item label="产品" required>
|
||||
<a-select showSearch v-model:value="modelRef.product" placeholder="请选择产品">
|
||||
<a-select-option :value="item.id" v-for="item in productList" :key="item.id" :title="item.name"></a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-item label="文件格式" v-if="modelRef.product">
|
||||
<j-form :layout="'vertical'">
|
||||
<j-row>
|
||||
<j-col span="24">
|
||||
<j-form-item label="产品" required>
|
||||
<j-select showSearch v-model:value="modelRef.product" placeholder="请选择产品">
|
||||
<j-select-option :value="item.id" v-for="item in productList" :key="item.id" :label="item.name">{{ item.name }}</j-select-option>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
<j-col span="24">
|
||||
<j-form-item label="文件格式" v-if="modelRef.product">
|
||||
<FileFormat v-model="modelRef.file" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-item label="文件上传" v-if="modelRef.product">
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
<j-col span="12">
|
||||
<j-form-item label="文件上传" v-if="modelRef.product">
|
||||
<NormalUpload :product="modelRef.product" v-model="modelRef.upload" :file="modelRef.file" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</j-form>
|
||||
</div>
|
||||
</a-modal>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { queryNoPagingPost } from '@/api/device/product'
|
||||
import { Form } from 'ant-design-vue';
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
const emit = defineEmits(['close', 'save'])
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
|
@ -38,7 +37,6 @@ const props = defineProps({
|
|||
}
|
||||
})
|
||||
const productList = ref<Record<string, any>[]>([])
|
||||
const useForm = Form.useForm;
|
||||
|
||||
const modelRef = reactive({
|
||||
product: undefined,
|
||||
|
@ -64,4 +62,8 @@ watch(
|
|||
const handleCancel = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
emit('close')
|
||||
}
|
||||
</script>
|
|
@ -18,7 +18,7 @@
|
|||
<j-row type="flex">
|
||||
<j-col flex="180px">
|
||||
<j-form-item name="photoUrl">
|
||||
<JUpload v-model="modelRef.photoUrl" />
|
||||
<JProUpload v-model="modelRef.photoUrl" />
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
<j-col flex="auto">
|
||||
|
@ -60,15 +60,14 @@
|
|||
<j-select
|
||||
showSearch
|
||||
v-model:value="modelRef.productId"
|
||||
placeholder="请选择所属产品"
|
||||
:filter-option="filterOption"
|
||||
:disabled="!!data?.id"
|
||||
placeholder="请选择状态为“正常”的产品"
|
||||
>
|
||||
<j-select-option
|
||||
:value="item.id"
|
||||
v-for="item in productList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:disabled="!!data?.id"
|
||||
>{{item.name}}</j-select-option>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
|
@ -105,16 +104,12 @@ const formRef = ref();
|
|||
|
||||
const modelRef = reactive({
|
||||
productId: undefined,
|
||||
id: '',
|
||||
id: undefined,
|
||||
name: '',
|
||||
describe: '',
|
||||
photoUrl: getImage('/device/instance/device-card.png'),
|
||||
});
|
||||
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
};
|
||||
|
||||
const vailId = async (_: Record<string, any>, value: string) => {
|
||||
if (!props?.data?.id && value) {
|
||||
const resp = await isExists(value);
|
||||
|
@ -202,10 +197,15 @@ const handleCancel = () => {
|
|||
const handleSave = () => {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(async () => {
|
||||
.then(async (_data: any) => {
|
||||
loading.value = true;
|
||||
const resp = await update(toRaw(modelRef));
|
||||
loading.value = false;
|
||||
const obj = {...toRaw(modelRef), ..._data}
|
||||
if(!obj.id){
|
||||
delete obj.id
|
||||
}
|
||||
const resp = await update(obj).finally(() => {
|
||||
loading.value = false;
|
||||
})
|
||||
if (resp.status === 200) {
|
||||
message.success('操作成功!');
|
||||
emit('save');
|
||||
|
|
|
@ -229,7 +229,7 @@
|
|||
</template>
|
||||
</JProTable>
|
||||
</page-container>
|
||||
<Import v-if="importVisible" @close="importVisible = false" />
|
||||
<Import v-if="importVisible" @close="importVisible = false" @save="onRefresh" />
|
||||
<Export
|
||||
v-if="exportVisible"
|
||||
@close="exportVisible = false"
|
||||
|
@ -259,7 +259,6 @@ import {
|
|||
batchDeployDevice,
|
||||
batchDeleteDevice,
|
||||
} from '@/api/device/instance';
|
||||
// import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import { getImage, LocalStore } from '@/utils/comm';
|
||||
import { message } from 'ant-design-vue';
|
||||
import Import from './Import/index.vue';
|
||||
|
@ -275,6 +274,7 @@ import {
|
|||
} from '@/api/device/product';
|
||||
import { queryTree } from '@/api/device/category';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { ActionsType } from './typings';
|
||||
|
||||
const router = useRouter();
|
||||
const instanceRef = ref<Record<string, any>>({});
|
||||
|
@ -696,4 +696,8 @@ const saveBtn = () => {
|
|||
const handleSearch = (_params: any) => {
|
||||
params.value = _params;
|
||||
};
|
||||
|
||||
const onRefresh = () => {
|
||||
instanceRef.value?.reload();
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -83,4 +83,17 @@ type InstanceModel = {
|
|||
params: Set<string>; // 处理无限循环Card
|
||||
active?: string; // 当前编辑的Card
|
||||
selectedRows: Map<string, any>;
|
||||
}
|
||||
|
||||
export interface ActionsType {
|
||||
key: string;
|
||||
text?: string;
|
||||
disabled?: boolean;
|
||||
permission?: boolean;
|
||||
onClick?: (data: any) => void;
|
||||
style?: CSSProperties;
|
||||
tooltip?: TooltipProps;
|
||||
popConfirm?: PopconfirmProps;
|
||||
icon?: string;
|
||||
children?: ActionsType[];
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<Search :columns="columns" target="scene" @search="handleSearch" />
|
||||
<j-advanced-search :columns="columns" target="scene" @search="handleSearch" />
|
||||
<JProTable
|
||||
ref="sceneRef"
|
||||
:columns="columns"
|
||||
|
@ -23,7 +23,6 @@
|
|||
<template #card="slotProps">
|
||||
<SceneCard
|
||||
:value="slotProps"
|
||||
@click="handleClick"
|
||||
:actions="getActions(slotProps, 'card')"
|
||||
:status="slotProps.state?.value"
|
||||
:statusText="slotProps.state?.text"
|
||||
|
@ -50,7 +49,7 @@
|
|||
<Ellipsis style="width: calc(100% - 100px)">
|
||||
<span
|
||||
style="font-size: 16px; font-weight: 600"
|
||||
@click.stop="handleView(slotProps.id)"
|
||||
@click.stop="handleView(slotProps.id, slotProps.triggerType)"
|
||||
>
|
||||
{{ slotProps.name }}
|
||||
</span>
|
||||
|
@ -126,7 +125,7 @@
|
|||
import SaveModal from './Save/save.vue';
|
||||
import type { SceneItem } from './typings';
|
||||
import { useMenuStore } from 'store/menu';
|
||||
import { query, _delete, _action } from '@/api/rule-engine/scene';
|
||||
import { query, _delete, _action, _execute } from '@/api/rule-engine/scene';
|
||||
import { message } from 'ant-design-vue';
|
||||
import type { ActionsType } from '@/components/Table';
|
||||
import { getImage } from '@/utils/comm';
|
||||
|
@ -180,10 +179,12 @@ const columns = [
|
|||
scopedSlots: true,
|
||||
search: {
|
||||
type: 'select',
|
||||
options: Array.from(typeMap).map((item) => ({
|
||||
label: item[1],
|
||||
value: item[0],
|
||||
})),
|
||||
options: Array.from(typeMap).map((item) => {
|
||||
return {
|
||||
label: item[1]?.text,
|
||||
value: item[0],
|
||||
}
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -305,9 +306,18 @@ const getActions = (
|
|||
: '未启用,不能手动触发',
|
||||
},
|
||||
icon: 'LikeOutlined',
|
||||
onClick: () => {
|
||||
// handleView(data.id, data.triggerType);
|
||||
},
|
||||
popConfirm: {
|
||||
title: '',
|
||||
onConfirm: async () => {
|
||||
const resp = await _execute(data.id)
|
||||
if (resp.status === 200) {
|
||||
message.success('操作成功!');
|
||||
sceneRef.value?.reload();
|
||||
} else {
|
||||
message.error('操作失败!');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
actions.splice(1, 0, _item);
|
||||
}
|
||||
|
|
|
@ -3903,8 +3903,8 @@ jetlinks-store@^0.0.3:
|
|||
|
||||
jetlinks-ui-components@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.4.tgz#38f2abbb6c686ce1e1d7c08a318a6c2f50267adc"
|
||||
integrity sha512-bpmSoKVpdgZ2FUxIBaqBpewt2T9g1tTf4tECam9uTdww6SDxyvLzWmeKIUfVIwp2Ts7uKpHPFsCtI8fPmZuRjw==
|
||||
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.4.tgz#31f6879f83d394ba45bfd6e94ce0b20de817d490"
|
||||
integrity sha512-5X26+GsqsduCUSmlaYOAw/MDwKRsZFnifzzRqHcm5qbCi0KrrkID9aKatsMRaeTVEEca1/nzPaPGgXAo6bEpfQ==
|
||||
dependencies:
|
||||
"@vueuse/core" "^9.12.0"
|
||||
ant-design-vue "^3.2.15"
|
||||
|
|
Loading…
Reference in New Issue