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 getDeviceNumber = (data?:any) => server.post<number>('/device-instance/_count', data)
|
||||
|
||||
|
||||
|
|
|
@ -40,14 +40,13 @@
|
|||
import { FILE_UPLOAD } from '@/api/comm';
|
||||
import { TOKEN_KEY } from '@/utils/variable';
|
||||
import { LocalStore, onlyMessage } from '@/utils/comm';
|
||||
import { downloadFile, downloadFileByUrl } from '@/utils/utils';
|
||||
import { downloadFileByUrl } from '@/utils/utils';
|
||||
import {
|
||||
deviceImport,
|
||||
deviceTemplateDownload,
|
||||
templateDownload,
|
||||
} from '@/api/device/instance';
|
||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { message } from 'jetlinks-ui-components';
|
||||
|
||||
type Emits = {
|
||||
(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);
|
||||
|
@ -81,7 +89,6 @@ const count = ref<number>(0);
|
|||
const errMessage = ref<string>('');
|
||||
|
||||
const downFile = async (type: string) => {
|
||||
// downloadFile(deviceTemplateDownload(props.product, type));
|
||||
const res: any = await templateDownload(props.product, type);
|
||||
if (res) {
|
||||
const blob = new Blob([res], { type: type });
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getDeviceNumber } from '@/api/device/product';
|
||||
import { getDeviceNumber } from '@/api/device/instance';
|
||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||
|
||||
const emit = defineEmits(['close', 'save']);
|
||||
|
@ -36,6 +36,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: '',
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const count = ref<number>(0);
|
||||
|
@ -90,7 +94,7 @@ watch(
|
|||
() => props.api,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
getDeviceNumber({}).then(resp => {
|
||||
getDeviceNumber(props.data).then(resp => {
|
||||
if(resp.status === 200){
|
||||
total.value = resp.result
|
||||
getData(newValue);
|
||||
|
|
|
@ -268,6 +268,7 @@
|
|||
@close="operationVisible = false"
|
||||
:api="api"
|
||||
:type="type"
|
||||
:data="params"
|
||||
@save="onRefresh"
|
||||
/>
|
||||
<Save
|
||||
|
@ -575,7 +576,7 @@ onMounted(() => {
|
|||
const handleParams = (config: Record<string, any>) => {
|
||||
const _terms: Record<string, any> = {};
|
||||
paramsFormat(config, _terms);
|
||||
if (Object.keys(_terms._value).length && Object.keys(_terms).length) {
|
||||
if (Object.keys(_terms).length) {
|
||||
const url = new URLSearchParams();
|
||||
Object.keys(_terms).forEach((key) => {
|
||||
url.append(key, _terms[key]);
|
||||
|
@ -715,7 +716,7 @@ const activeAllDevice = () => {
|
|||
type.value = 'active';
|
||||
const activeAPI = `${BASE_API_PATH}/device-instance/deploy?:X_Access_Token=${LocalStore.get(
|
||||
TOKEN_KEY,
|
||||
)}&${handleParams(params)}`;
|
||||
)}&${handleParams(params.value)}`;
|
||||
api.value = activeAPI;
|
||||
operationVisible.value = true;
|
||||
};
|
||||
|
@ -724,7 +725,7 @@ const syncDeviceStatus = () => {
|
|||
type.value = 'sync';
|
||||
const syncAPI = `${BASE_API_PATH}/device-instance/state/_sync?:X_Access_Token=${LocalStore.get(
|
||||
TOKEN_KEY,
|
||||
)}&${handleParams(params)}`;
|
||||
)}&${handleParams(params.value)}`;
|
||||
api.value = syncAPI;
|
||||
operationVisible.value = true;
|
||||
};
|
||||
|
|
|
@ -6,11 +6,15 @@
|
|||
title="导入"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<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-select
|
||||
showSearch
|
||||
|
@ -33,6 +37,14 @@
|
|||
</j-form-item>
|
||||
|
||||
<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
|
||||
v-model:fileList="modelRef.upload"
|
||||
name="file"
|
||||
|
@ -70,30 +82,30 @@
|
|||
<a-icon class="check-num" style="color: red" type="close" />
|
||||
失败 总数量
|
||||
<span class="check-num">{{ errCount }}</span>
|
||||
</div>
|
||||
</j-form>
|
||||
</div> -->
|
||||
</div>
|
||||
<template #footer>
|
||||
<j-button type="primary" @click="handleOk">关闭</j-button>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { FILE_UPLOAD } from '@/api/comm';
|
||||
import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable';
|
||||
import { LocalStore } from '@/utils/comm';
|
||||
import { downloadFile, downloadFileByUrl } from '@/utils/utils';
|
||||
import { queryPlatformNoPage, _import ,exportCard} from '@/api/iot-card/cardManagement';
|
||||
// import { message } from 'ant-design-vue';
|
||||
import { message } from 'jetlinks-ui-components';
|
||||
|
||||
// import { downloadFile, downloadFileByUrl } from '@/utils/utils';
|
||||
import {
|
||||
queryPlatformNoPage,
|
||||
_import,
|
||||
} from '@/api/iot-card/cardManagement';
|
||||
import UploadFile from './UploadFile.vue'
|
||||
|
||||
const emit = defineEmits(['close', 'save']);
|
||||
|
||||
const configList = ref<Record<string, any>[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const totalCount = ref<number>(0);
|
||||
const errCount = ref<number>(0);
|
||||
const formRef = ref(null)
|
||||
const importStatus = ref(false)
|
||||
// const loading = ref<boolean>(false);
|
||||
// const totalCount = ref<number>(0);
|
||||
// const errCount = ref<number>(0);
|
||||
const formRef = ref(null);
|
||||
// const importStatus = ref(false);
|
||||
const modelRef = reactive({
|
||||
configId: undefined,
|
||||
upload: [],
|
||||
|
@ -101,8 +113,8 @@ const modelRef = reactive({
|
|||
});
|
||||
|
||||
const rules = {
|
||||
configId: [{ required: true, message: '请选择平台对接'}]
|
||||
}
|
||||
configId: [{ required: true, message: '请选择平台对接' }],
|
||||
};
|
||||
|
||||
const getConfig = async () => {
|
||||
const resp: any = await queryPlatformNoPage({
|
||||
|
@ -125,59 +137,52 @@ const getConfig = async () => {
|
|||
});
|
||||
};
|
||||
|
||||
const fileChange = (info: any) => {
|
||||
loading.value = true;
|
||||
if (info.file.status === 'done') {
|
||||
const r = info.file.response || { result: '' };
|
||||
_import(modelRef.configId, { fileUrl: r.result })
|
||||
.then((resp: any) => {
|
||||
totalCount.value = resp.result.total;
|
||||
importStatus.value = true
|
||||
message.success('导入成功')
|
||||
})
|
||||
.catch((err) => {
|
||||
message.error(err.response.data.message || '导入失败')
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
// const fileChange = (info: any) => {
|
||||
// loading.value = true;
|
||||
// if (info.file.status === 'done') {
|
||||
// const r = info.file.response || { result: '' };
|
||||
// _import(modelRef.configId, { fileUrl: r.result })
|
||||
// .then((resp: any) => {
|
||||
// totalCount.value = resp.result.total;
|
||||
// importStatus.value = true;
|
||||
// message.success('导入成功');
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// message.error(err.response.data.message || '导入失败');
|
||||
// })
|
||||
// .finally(() => {
|
||||
// loading.value = false;
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
|
||||
const downFileFn =async (type: string) => {
|
||||
// const url = `${BASE_API_PATH}/network/card/template.${type}`;
|
||||
// downloadFile(url);
|
||||
const res:any = await exportCard(type)
|
||||
if(res){
|
||||
const blob = new Blob([res], { type: type });
|
||||
const url = URL.createObjectURL(blob);
|
||||
console.log(url);
|
||||
downloadFileByUrl(
|
||||
url,
|
||||
`物联卡导入模版`,
|
||||
type,
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
// const downFileFn = async (type: string) => {
|
||||
// // const url = `${BASE_API_PATH}/network/card/template.${type}`;
|
||||
// // downloadFile(url);
|
||||
// const res: any = await exportCard(type);
|
||||
// if (res) {
|
||||
// const blob = new Blob([res], { type: type });
|
||||
// const url = URL.createObjectURL(blob);
|
||||
// console.log(url);
|
||||
// downloadFileByUrl(url, `物联卡导入模版`, type);
|
||||
// }
|
||||
// };
|
||||
|
||||
const handleCancel = () => {
|
||||
totalCount.value = 0;
|
||||
errCount.value = 0;
|
||||
// totalCount.value = 0;
|
||||
// errCount.value = 0;
|
||||
modelRef.configId = undefined;
|
||||
|
||||
emit('close', true);
|
||||
if (importStatus.value) {
|
||||
emit('save', true)
|
||||
}
|
||||
importStatus.value = false
|
||||
// if (importStatus.value) {
|
||||
// emit('save', true);
|
||||
// }
|
||||
// importStatus.value = false;
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
formRef.value.validate().then(res => {
|
||||
handleCancel()
|
||||
})
|
||||
}
|
||||
emit('save', true);
|
||||
};
|
||||
|
||||
getConfig();
|
||||
</script>
|
||||
|
@ -188,3 +193,4 @@ getConfig();
|
|||
color: @primary-color;
|
||||
}
|
||||
</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