标签列表上传图片功能

main
zhufu 2025-08-23 15:46:43 +08:00
parent f52f984cc4
commit e1b1f2811d
4 changed files with 314 additions and 4 deletions

View File

@ -69,6 +69,7 @@ enum Api {
LoadNewCaseInfoMineralsTuBanImportantList = '/api/DroneCaseinfoMineralsNew/LoadNewCaseInfoMineralsTuBanImportantList',
AddImportantXianSuo = '/api/DroneCaseinfoMineralsNew/AddImportantXianSuo',
MineralsNewGetCaseInfoById = '/api/DroneCaseinfoMineralsNew/GetCaseInfoById',
UpdatePicturePath = '/api/DroneCaseInfoMinerals/UpdatePicturePath',
}
export function LoadCaiKuangTaskList(params) {
@ -197,3 +198,6 @@ export function AddImportantXianSuo(params){
export function MineralsNewGetCaseInfoById(params?: { id: string }){
return defHttp.get({ url: Api.MineralsNewGetCaseInfoById, params });
}
export function UpdatePicturePath(params?: { id: string }){
return defHttp.post({ url: Api.UpdatePicturePath, params });
}

View File

@ -48,6 +48,20 @@
<ShowInfoModal :showInfoData="showInfoData" />
</div>
</a-modal>
<a-modal
style="width: 50vw; margin: 0px; padding: 0px"
wrap-class-name="full-modal"
:centered="true"
:mask="false"
:maskClosable="false"
:keyboard="false"
v-model:open="uploadOpen"
title="上传图片"
:footer="null"
@cancel="uploadOpen = false"
>
<UploadModal :allTableData="allTableData" />
</a-modal>
</PageWrapper>
</template>
<script lang="ts" setup>
@ -63,6 +77,7 @@
import { dataProcessingCount } from '@/views/demo/tiankongdi/util';
import { PageWrapper } from '@/components/Page';
import { message } from 'ant-design-vue';
import UploadModal from './uploadModal.vue';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
@ -77,6 +92,7 @@
page: 1,
limit: 10,
})
const uploadOpen = ref(false);
const [registerTable, { getForm, reload, getPaginationRef, getDataSource }] =
useTable({
title: '标签列表',
@ -120,10 +136,10 @@
let fileName = '';
if (exportType == 'excel') {
url = VITE_GLOB_API_URL + '/api/DroneCaseInfoSatellite/ExportCaseInfoWpxfTuBanList';
fileName = '线索共享统计报表' + new Date().getTime() + '.xls';
fileName = '标签列表统计报表' + new Date().getTime() + '.xls';
} else if (exportType == 'shp') {
url = VITE_GLOB_API_URL + '/api/DroneCaseInfoSatellite/ExportCaseInfoWpxfShapefile';
fileName = '线索共享矢量数据' + new Date().getTime() + '.zip';
url = VITE_GLOB_API_URL + '/api/DroneCaseinfoMineralsNew/ExportNewIllegalCaiKuangShapefile';
fileName = '标签列表矢量数据' + new Date().getTime() + '.zip';
}
axios({
method: 'post',
@ -148,8 +164,12 @@
const open = ref<boolean>(false);
function onBtnClicked(domId) {
switch (domId) {
case 'btnUpload':
uploadOpen.value = true;
break;
case 'btnExport':
open.value = true;
// open.value = true;
handleExport('shp')
break;
default:
break;

View File

@ -0,0 +1,258 @@
<template>
<div>
<div class="upload">
<a-upload
v-model:file-list="fileList"
list-type="picture-card"
multiple
:accept="'.jpg,.jpeg,.png'"
:showUploadList="false"
:custom-request="customRequest"
>
<div>
<PlusOutlined />
<div style="margin-top: 8px">上传图片</div>
</div>
</a-upload>
</div>
<div class="table">
状态筛选
<a-select
v-model:value="selectStatus"
mode="multiple"
style="width: 90%; margin-top: 5px; margin-bottom: 5px"
allowClear
:options="[
{
value: 'uploading',
label: '上传中',
},
{
value: 'done',
label: '上传成功',
},
{
value: 'error',
label: '上传失败',
},
{
value: 'updateSuccess',
label: '插入成功',
},
{
value: 'updateError',
label: '插入失败',
},
]"
/>
<a-table
:columns="uploadColumns"
:data-source="filterData"
:pagination="false"
bordered
:scroll="{ y: 600 }"
>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'size'">
{{ parseFloat(record.size / 1024 / 1024).toFixed(2) }} MB
</template>
<template v-if="column.dataIndex === 'percent'">
<a-progress
v-if="record.status == 'error'"
:percent="record.percent"
status="exception"
/>
<a-progress
v-if="['done', 'updateSuccess', 'updateError'].includes(record.status)"
:percent="record.percent"
/>
</template>
<template v-if="column.dataIndex === 'status'">
<a-tag color="processing" v-if="record.status == 'uploading'"></a-tag>
<a-tag color="success" v-if="record.status == 'done'"></a-tag>
<a-tag color="error" v-if="record.status == 'error'"></a-tag>
<a-tag color="green" v-if="record.status == 'updateSuccess'"></a-tag>
<a-tag color="red" v-if="record.status == 'updateError'"></a-tag>
</template>
<template v-if="column.dataIndex === 'url' || column.dataIndex === 'message'">
{{ record.url || record.message }}
</template>
</template>
</a-table>
<div class="updateDiv">
<a-button type="primary" @click="startUploadCXJGData">
将上传成功的图片插入到数据库
</a-button>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { defineProps, ref, watch, onMounted, defineEmits, computed } from 'vue';
import { PlusOutlined, CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons-vue';
import { getAppEnvConfig } from '@/utils/env';
import axios from 'axios';
import { UpdatePicturePath } from '@/api/illegalmining/index';
import { uploadColumns } from './util';
import { message } from 'ant-design-vue';
const { VITE_GLOB_INFO_IMAGE_URL } = getAppEnvConfig();
const props = defineProps(['allTableData']);
//
const fileList: any = ref();
const selectStatus = ref([]);
const filterData = computed(() => {
if (fileList.value && selectStatus.value.length > 0) {
return fileList.value.filter((item) => selectStatus.value.includes(item.status));
} else {
return fileList.value;
}
});
//
const customRequest = (file) => {
const formData = new FormData();
formData.append('files', file.file);
axios({
method: 'post',
url: `${VITE_GLOB_INFO_IMAGE_URL}/api/Platform/Upload`,
params: { project: 'DroneEnforcement' },
data: formData,
headers: {
'Content-type': 'multipart/form-data',
},
}).then((res) => {
const index = fileList.value.findIndex((item) => item.uid === file.file.uid);
//
if (res.data.code == '200') {
let data = res.data.result;
fileList.value[index] = {
...fileList.value[index],
percent: 100,
status: 'done',
url: data[0].filePath,
};
} else {
//
fileList.value[index] = {
...fileList.value[index],
percent: 0,
status: 'error',
url: '',
message: res.data.message,
};
}
console.log('fileList',fileList.value)
});
};
// -
let uoloadArray: any = [];
async function startUploadCXJGData() {
const list = fileList.value;
uoloadArray = [];
if (!list || list.length === 0) return;
list.forEach((item) => {
if (item.status === 'done' || item.status === 'updateError') {
//
let caseid = item.name.split('.').slice(0, -1).join('.');
let flag = false;
if (caseid.includes('_CX')) {
flag = true;
}
if (caseid.includes('_')) {
caseid = caseid.split('_').slice(0, 1).join('_');
}
if (flag) {
caseid = caseid + '_CX';
}
const index = fileList.value.findIndex((l) => l.uid === item.uid);
const path = item.url;
// 线
const uoloadArrayIndex = uoloadArray.findIndex((l) => l.caseid === caseid);
if (uoloadArrayIndex != -1) {
uoloadArray[uoloadArrayIndex].index += ',' + index;
uoloadArray[uoloadArrayIndex].path += ',' + path;
} else {
uoloadArray.push({
caseid: caseid,
index: index.toString(),
path: path,
});
}
}
});
// -
if (!uoloadArray || uoloadArray.length === 0) return;
for (let i = 0; i < uoloadArray.length; i++) {
await UpdateUploadCXJGData(uoloadArray[i]);
}
}
// -
async function UpdateUploadCXJGData(value) {
let querys = {
caseno: value.caseid,
path: value.path,
};
try {
await UpdatePicturePath(querys).then((res) => {
if (res) {
const indexs = value.index.split(',');
indexs?.forEach((index) => {
fileList.value[index] = {
...fileList.value[index],
status: 'updateSuccess',
};
});
} else {
const indexs = value.index.split(',');
indexs?.forEach((index) => {
fileList.value[index] = {
...fileList.value[index],
status: 'updateError',
};
});
if (props.allTableData.findIndex((item) => item.caseno == value.caseid)) {
message.error(`线索【${value.caseid}】不存在!`);
} else {
message.error(`线索【${value.caseid}】有未审核的图片,不允许继续上传,请先审核!`);
}
}
});
} catch (error) {
const indexs = value.index.split(',');
indexs?.forEach((index) => {
fileList.value[index] = {
...fileList.value[index],
status: 'updateError',
};
});
console.error('上传或审核出错:', error);
}
}
</script>
<style lang="less" scoped>
.upload {
width: 100%;
margin-left: 20px;
}
.table {
// width: 95%;
margin-left: 20px;
margin-right: 20px;
}
.updateDiv {
position: absolute;
bottom: 10px;
right: 10px;
gap: 10px;
}
::v-deep .ant-select-selection-item {
width: 85px !important;
}
</style>

View File

@ -219,3 +219,31 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 6 },
},
];
export const uploadColumns: BasicColumn[] = [
{
title: '名称',
dataIndex: 'name',
width: 150,
},
{
title: '大小',
dataIndex: 'size',
width: 80,
},
{
title: '进度',
dataIndex: 'percent',
width: 100,
},
{
title: '状态',
dataIndex: 'status',
width: 80,
align: 'center',
},
{
title: '路径/上传图片失败原因',
dataIndex: 'url',
width: 280,
},
];