fix: 修改设备新增

This commit is contained in:
100011797 2023-03-06 11:19:11 +08:00
parent 21e45c060d
commit 66234bdfd4
10 changed files with 151 additions and 93 deletions

View File

@ -28,5 +28,4 @@ const props = defineProps({
*/
statusNames: { type: Object },
});
</script>

View File

@ -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" />

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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');

View File

@ -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>

View File

@ -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[];
}

View File

@ -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);
}

View File

@ -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"