fix: 物联网卡
This commit is contained in:
parent
9f0bc42fb9
commit
43a8d39655
|
@ -571,3 +571,6 @@ export const queryLog = (deviceId: string, data: Record<string, unknown>) => ser
|
||||||
*/
|
*/
|
||||||
export const queryLogsType = () => server.get(`/dictionary/device-log-type/items`)
|
export const queryLogsType = () => server.get(`/dictionary/device-log-type/items`)
|
||||||
|
|
||||||
|
export const getDeviceNumber = (data?:any) => server.post<number>('/device-instance/_count', data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,14 +40,13 @@
|
||||||
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, onlyMessage } from '@/utils/comm';
|
import { LocalStore, onlyMessage } from '@/utils/comm';
|
||||||
import { downloadFile, downloadFileByUrl } from '@/utils/utils';
|
import { downloadFileByUrl } from '@/utils/utils';
|
||||||
import {
|
import {
|
||||||
deviceImport,
|
deviceImport,
|
||||||
deviceTemplateDownload,
|
|
||||||
templateDownload,
|
templateDownload,
|
||||||
} from '@/api/device/instance';
|
} from '@/api/device/instance';
|
||||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'jetlinks-ui-components';
|
||||||
|
|
||||||
type Emits = {
|
type Emits = {
|
||||||
(e: 'update:modelValue', data: string[]): void;
|
(e: 'update:modelValue', data: string[]): void;
|
||||||
|
@ -73,6 +72,15 @@ const props = defineProps({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
url: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
fileType: 'xlsx',
|
||||||
|
autoDeploy: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const importLoading = ref<boolean>(false);
|
const importLoading = ref<boolean>(false);
|
||||||
|
@ -81,7 +89,6 @@ 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));
|
|
||||||
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 });
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { getDeviceNumber } from '@/api/device/product';
|
import { getDeviceNumber } from '@/api/device/instance';
|
||||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||||
|
|
||||||
const emit = defineEmits(['close', 'save']);
|
const emit = defineEmits(['close', 'save']);
|
||||||
|
@ -36,6 +36,10 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const count = ref<number>(0);
|
const count = ref<number>(0);
|
||||||
|
@ -90,7 +94,7 @@ watch(
|
||||||
() => props.api,
|
() => props.api,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
getDeviceNumber({}).then(resp => {
|
getDeviceNumber(props.data).then(resp => {
|
||||||
if(resp.status === 200){
|
if(resp.status === 200){
|
||||||
total.value = resp.result
|
total.value = resp.result
|
||||||
getData(newValue);
|
getData(newValue);
|
||||||
|
|
|
@ -268,6 +268,7 @@
|
||||||
@close="operationVisible = false"
|
@close="operationVisible = false"
|
||||||
:api="api"
|
:api="api"
|
||||||
:type="type"
|
:type="type"
|
||||||
|
:data="params"
|
||||||
@save="onRefresh"
|
@save="onRefresh"
|
||||||
/>
|
/>
|
||||||
<Save
|
<Save
|
||||||
|
@ -575,7 +576,7 @@ onMounted(() => {
|
||||||
const handleParams = (config: Record<string, any>) => {
|
const handleParams = (config: Record<string, any>) => {
|
||||||
const _terms: Record<string, any> = {};
|
const _terms: Record<string, any> = {};
|
||||||
paramsFormat(config, _terms);
|
paramsFormat(config, _terms);
|
||||||
if (Object.keys(_terms._value).length && Object.keys(_terms).length) {
|
if (Object.keys(_terms).length) {
|
||||||
const url = new URLSearchParams();
|
const url = new URLSearchParams();
|
||||||
Object.keys(_terms).forEach((key) => {
|
Object.keys(_terms).forEach((key) => {
|
||||||
url.append(key, _terms[key]);
|
url.append(key, _terms[key]);
|
||||||
|
@ -715,7 +716,7 @@ const activeAllDevice = () => {
|
||||||
type.value = 'active';
|
type.value = 'active';
|
||||||
const activeAPI = `${BASE_API_PATH}/device-instance/deploy?:X_Access_Token=${LocalStore.get(
|
const activeAPI = `${BASE_API_PATH}/device-instance/deploy?:X_Access_Token=${LocalStore.get(
|
||||||
TOKEN_KEY,
|
TOKEN_KEY,
|
||||||
)}&${handleParams(params)}`;
|
)}&${handleParams(params.value)}`;
|
||||||
api.value = activeAPI;
|
api.value = activeAPI;
|
||||||
operationVisible.value = true;
|
operationVisible.value = true;
|
||||||
};
|
};
|
||||||
|
@ -724,7 +725,7 @@ const syncDeviceStatus = () => {
|
||||||
type.value = 'sync';
|
type.value = 'sync';
|
||||||
const syncAPI = `${BASE_API_PATH}/device-instance/state/_sync?:X_Access_Token=${LocalStore.get(
|
const syncAPI = `${BASE_API_PATH}/device-instance/state/_sync?:X_Access_Token=${LocalStore.get(
|
||||||
TOKEN_KEY,
|
TOKEN_KEY,
|
||||||
)}&${handleParams(params)}`;
|
)}&${handleParams(params.value)}`;
|
||||||
api.value = syncAPI;
|
api.value = syncAPI;
|
||||||
operationVisible.value = true;
|
operationVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,11 +6,15 @@
|
||||||
title="导入"
|
title="导入"
|
||||||
okText="确定"
|
okText="确定"
|
||||||
cancelText="取消"
|
cancelText="取消"
|
||||||
@ok="handleOk"
|
|
||||||
@cancel="handleCancel"
|
@cancel="handleCancel"
|
||||||
>
|
>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 10px">
|
||||||
<j-form :layout="'vertical'" :model="modelRef" ref="formRef" :rules="rules">
|
<j-form
|
||||||
|
:layout="'vertical'"
|
||||||
|
:model="modelRef"
|
||||||
|
ref="formRef"
|
||||||
|
:rules="rules"
|
||||||
|
>
|
||||||
<j-form-item label="平台对接" required name="configId">
|
<j-form-item label="平台对接" required name="configId">
|
||||||
<j-select
|
<j-select
|
||||||
showSearch
|
showSearch
|
||||||
|
@ -33,6 +37,14 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
|
|
||||||
<j-form-item label="文件上传" v-if="modelRef.configId">
|
<j-form-item label="文件上传" v-if="modelRef.configId">
|
||||||
|
<UploadFile
|
||||||
|
:product="modelRef.configId"
|
||||||
|
v-model="modelRef.upload"
|
||||||
|
:file="modelRef.fileType"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-form>
|
||||||
|
<!-- <j-form-item label="文件上传" v-if="modelRef.configId">
|
||||||
<j-upload
|
<j-upload
|
||||||
v-model:fileList="modelRef.upload"
|
v-model:fileList="modelRef.upload"
|
||||||
name="file"
|
name="file"
|
||||||
|
@ -70,30 +82,30 @@
|
||||||
<a-icon class="check-num" style="color: red" type="close" />
|
<a-icon class="check-num" style="color: red" type="close" />
|
||||||
失败 总数量
|
失败 总数量
|
||||||
<span class="check-num">{{ errCount }}</span>
|
<span class="check-num">{{ errCount }}</span>
|
||||||
</div>
|
</div> -->
|
||||||
</j-form>
|
|
||||||
</div>
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<j-button type="primary" @click="handleOk">关闭</j-button>
|
||||||
|
</template>
|
||||||
</j-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { FILE_UPLOAD } from '@/api/comm';
|
// import { downloadFile, downloadFileByUrl } from '@/utils/utils';
|
||||||
import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable';
|
import {
|
||||||
import { LocalStore } from '@/utils/comm';
|
queryPlatformNoPage,
|
||||||
import { downloadFile, downloadFileByUrl } from '@/utils/utils';
|
_import,
|
||||||
import { queryPlatformNoPage, _import ,exportCard} from '@/api/iot-card/cardManagement';
|
} from '@/api/iot-card/cardManagement';
|
||||||
// import { message } from 'ant-design-vue';
|
import UploadFile from './UploadFile.vue'
|
||||||
import { message } from 'jetlinks-ui-components';
|
|
||||||
|
|
||||||
|
|
||||||
const emit = defineEmits(['close', 'save']);
|
const emit = defineEmits(['close', 'save']);
|
||||||
|
|
||||||
const configList = ref<Record<string, any>[]>([]);
|
const configList = ref<Record<string, any>[]>([]);
|
||||||
const loading = ref<boolean>(false);
|
// const loading = ref<boolean>(false);
|
||||||
const totalCount = ref<number>(0);
|
// const totalCount = ref<number>(0);
|
||||||
const errCount = ref<number>(0);
|
// const errCount = ref<number>(0);
|
||||||
const formRef = ref(null)
|
const formRef = ref(null);
|
||||||
const importStatus = ref(false)
|
// const importStatus = ref(false);
|
||||||
const modelRef = reactive({
|
const modelRef = reactive({
|
||||||
configId: undefined,
|
configId: undefined,
|
||||||
upload: [],
|
upload: [],
|
||||||
|
@ -101,8 +113,8 @@ const modelRef = reactive({
|
||||||
});
|
});
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
configId: [{ required: true, message: '请选择平台对接'}]
|
configId: [{ required: true, message: '请选择平台对接' }],
|
||||||
}
|
};
|
||||||
|
|
||||||
const getConfig = async () => {
|
const getConfig = async () => {
|
||||||
const resp: any = await queryPlatformNoPage({
|
const resp: any = await queryPlatformNoPage({
|
||||||
|
@ -125,59 +137,52 @@ const getConfig = async () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const fileChange = (info: any) => {
|
// const fileChange = (info: any) => {
|
||||||
loading.value = true;
|
// loading.value = true;
|
||||||
if (info.file.status === 'done') {
|
// if (info.file.status === 'done') {
|
||||||
const r = info.file.response || { result: '' };
|
// const r = info.file.response || { result: '' };
|
||||||
_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;
|
||||||
importStatus.value = true
|
// importStatus.value = true;
|
||||||
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;
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
const downFileFn =async (type: string) => {
|
// const downFileFn = async (type: string) => {
|
||||||
// const url = `${BASE_API_PATH}/network/card/template.${type}`;
|
// // const url = `${BASE_API_PATH}/network/card/template.${type}`;
|
||||||
// downloadFile(url);
|
// // downloadFile(url);
|
||||||
const res:any = await exportCard(type)
|
// const res: any = await exportCard(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);
|
// console.log(url);
|
||||||
downloadFileByUrl(
|
// downloadFileByUrl(url, `物联卡导入模版`, type);
|
||||||
url,
|
// }
|
||||||
`物联卡导入模版`,
|
// };
|
||||||
type,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
totalCount.value = 0;
|
// totalCount.value = 0;
|
||||||
errCount.value = 0;
|
// errCount.value = 0;
|
||||||
modelRef.configId = undefined;
|
modelRef.configId = undefined;
|
||||||
|
|
||||||
emit('close', true);
|
emit('close', true);
|
||||||
if (importStatus.value) {
|
// if (importStatus.value) {
|
||||||
emit('save', true)
|
// emit('save', true);
|
||||||
}
|
// }
|
||||||
importStatus.value = false
|
// importStatus.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
formRef.value.validate().then(res => {
|
emit('save', true);
|
||||||
handleCancel()
|
};
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getConfig();
|
getConfig();
|
||||||
</script>
|
</script>
|
||||||
|
@ -188,3 +193,4 @@ getConfig();
|
||||||
color: @primary-color;
|
color: @primary-color;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
<template>
|
||||||
|
<j-space align="end">
|
||||||
|
<j-upload
|
||||||
|
v-model:fileList="modelValue.upload"
|
||||||
|
name="file"
|
||||||
|
:action="FILE_UPLOAD"
|
||||||
|
:headers="{
|
||||||
|
'X-Access-Token': LocalStore.get(TOKEN_KEY),
|
||||||
|
}"
|
||||||
|
:maxCount="1"
|
||||||
|
:showUploadList="false"
|
||||||
|
@change="uploadChange"
|
||||||
|
:accept="
|
||||||
|
props?.file ? `.${props?.file}` : '.xlsx'
|
||||||
|
"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
>
|
||||||
|
<j-button>
|
||||||
|
<template #icon><AIcon type="UploadOutlined" /></template>
|
||||||
|
文件上传
|
||||||
|
</j-button>
|
||||||
|
</j-upload>
|
||||||
|
<div style="margin-left: 20px">
|
||||||
|
<j-space>
|
||||||
|
下载模板
|
||||||
|
<a @click="downFile('xlsx')">.xlsx</a>
|
||||||
|
<a @click="downFile('csv')">.csv</a>
|
||||||
|
</j-space>
|
||||||
|
</div>
|
||||||
|
</j-space>
|
||||||
|
<div style="margin-top: 20px" v-if="importLoading">
|
||||||
|
<j-badge v-if="flag" status="processing" text="进行中" />
|
||||||
|
<j-badge v-else status="success" text="已完成" />
|
||||||
|
<span>总数量:{{ count }}</span>
|
||||||
|
<p style="color: red">{{ errMessage }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { FILE_UPLOAD } from '@/api/comm';
|
||||||
|
import { TOKEN_KEY } from '@/utils/variable';
|
||||||
|
import { LocalStore, onlyMessage } from '@/utils/comm';
|
||||||
|
import { downloadFileByUrl } from '@/utils/utils';
|
||||||
|
import { exportCard, _import } from '@/api/iot-card/cardManagement';
|
||||||
|
import { message } from 'jetlinks-ui-components';
|
||||||
|
|
||||||
|
type Emits = {
|
||||||
|
(e: 'update:modelValue', data: string[]): void;
|
||||||
|
};
|
||||||
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 组件双向绑定的值
|
||||||
|
modelValue: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
product: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
file: {
|
||||||
|
type: String,
|
||||||
|
default: 'xlsx',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const importLoading = ref<boolean>(false);
|
||||||
|
const flag = ref<boolean>(false);
|
||||||
|
const count = ref<number>(0);
|
||||||
|
const errMessage = ref<string>('');
|
||||||
|
|
||||||
|
const downFile = async (type: string) => {
|
||||||
|
const res: any = await exportCard(type);
|
||||||
|
if (res) {
|
||||||
|
const blob = new Blob([res], { type: type });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
downloadFileByUrl(url, `物联卡导入模版`, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const beforeUpload = (_file: any) => {
|
||||||
|
const fileType = props?.file === 'csv' ? 'csv' : 'xlsx';
|
||||||
|
const isCsv = _file.type === 'text/csv';
|
||||||
|
const isXlsx =
|
||||||
|
_file.type ===
|
||||||
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
|
||||||
|
if (!isCsv && fileType !== 'xlsx') {
|
||||||
|
onlyMessage('请上传.csv格式文件', 'warning');
|
||||||
|
}
|
||||||
|
if (!isXlsx && fileType !== 'csv') {
|
||||||
|
onlyMessage('请上传.xlsx格式文件', 'warning');
|
||||||
|
}
|
||||||
|
return (isCsv && fileType !== 'xlsx') || (isXlsx && fileType !== 'csv');
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadChange = async (info: Record<string, any>) => {
|
||||||
|
importLoading.value = true;
|
||||||
|
if (info.file.status === 'done') {
|
||||||
|
const resp: any = info.file.response || { result: '' };
|
||||||
|
flag.value = true;
|
||||||
|
_import(props.product, { fileUrl: resp.result })
|
||||||
|
.then((response: any) => {
|
||||||
|
count.value = response.result?.total || 0
|
||||||
|
message.success('导入成功');
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
errMessage.value = err?.response?.data?.message || '导入失败'
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
flag.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
Reference in New Issue