<template>
|
<el-dialog
|
v-model="dialogShow"
|
width="50%"
|
:close-on-click-modal="false"
|
:close-on-press-escape="false"
|
destroy-on-close
|
>
|
<template #header>
|
<span>
|
{{
|
uploaded ? '问题详情' : createMode ? '添加问题' : '修改问题'
|
}}</span
|
>
|
</template>
|
<el-form
|
label-width="90px"
|
label-position="left"
|
:rules="rules"
|
:model="formObj"
|
ref="formRef"
|
>
|
<el-form-item label="问题名称" prop="cqName">
|
<el-input
|
:disabled="uploaded"
|
v-model="formObj.cqName"
|
placeholder="请输入问题名称"
|
></el-input>
|
</el-form-item>
|
<el-form-item label="问题描述" prop="cqDescription">
|
<el-input
|
:disabled="uploaded"
|
v-model="formObj.cqDescription"
|
type="textarea"
|
placeholder="请输入问题描述"
|
></el-input>
|
</el-form-item>
|
<el-form-item label="所在街镇" prop="cqStreet">
|
<el-select
|
v-model="formObj.cqStreet"
|
placeholder="所在街镇"
|
:disabled="uploaded"
|
>
|
<el-option
|
v-for="s in streets"
|
:key="s.value"
|
:label="s.label"
|
:value="s.label"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="详细地址" prop="cqAddress">
|
<el-input
|
:disabled="uploaded"
|
v-model="formObj.cqAddress"
|
placeholder="请输入地址或者通过“坐标拾取”自动获得"
|
></el-input>
|
</el-form-item>
|
<el-form-item label="坐标" prop="coordinate">
|
<el-input
|
:disabled="uploaded"
|
style="width: 300px; margin-right: 8px"
|
v-model="formObj.coordinate"
|
placeholder="经纬度坐标,格式为121.123452,31.231235"
|
></el-input>
|
<el-button
|
:disabled="uploaded"
|
plain
|
type="primary"
|
@click="openMapDialog"
|
>坐标拾取</el-button
|
>
|
</el-form-item>
|
<el-form-item label="问题图片" prop="files">
|
<el-upload
|
:class="uploadableClz"
|
ref="uploadRef"
|
:file-list="fileList"
|
action=""
|
:auto-upload="false"
|
list-type="picture-card"
|
name="images"
|
accept="image/png, image/jpeg"
|
:limit="maxImageCount"
|
multiple
|
:on-preview="handleFilePreview"
|
:on-remove="handleFileRemove"
|
:on-change="handleFileChange"
|
>
|
<el-icon><Plus /></el-icon>
|
<template #file="{ file }">
|
<div>
|
<img
|
class="el-upload-list__item-thumbnail"
|
:src="file.url"
|
alt=""
|
/>
|
<span class="el-upload-list__item-actions">
|
<span
|
class="el-upload-list__item-preview"
|
@click="handleFilePreview(file)"
|
>
|
<el-icon><zoom-in /></el-icon>
|
</span>
|
<!-- <span
|
v-if="!disabled"
|
class="el-upload-list__item-delete"
|
@click="handleDownload(file)"
|
>
|
<el-icon><Download /></el-icon>
|
</span> -->
|
<span
|
v-if="!uploaded"
|
class="el-upload-list__item-delete"
|
@click="handleFileRemove(file)"
|
>
|
<el-icon><Delete /></el-icon>
|
</span>
|
</span>
|
</div>
|
</template>
|
<template #tip>
|
<div class="el-upload__tip">
|
{{
|
`请选择小于500kb的jpg/png图片,最多${maxImageCount}张`
|
}}
|
</div>
|
</template>
|
</el-upload>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="onCancel">取消</el-button>
|
<el-button
|
:disabled="!edit"
|
type="primary"
|
:loading="loading"
|
@click="onSubmit"
|
>确定</el-button
|
>
|
</template>
|
</el-dialog>
|
<el-image-viewer
|
v-if="previewShow"
|
:url-list="urlList"
|
:initial-index="initialIndex"
|
:infinite="false"
|
@close="closePreview"
|
></el-image-viewer>
|
<MapSearch
|
v-model:show="mapDialogShow"
|
:defaultCoor="
|
formObj.coordinate
|
? formObj.coordinate.split(',')
|
: undefined
|
"
|
@on-submit="selectAddress"
|
></MapSearch>
|
</template>
|
|
<script setup>
|
import { reactive, ref, watch, computed, inject } from 'vue';
|
import { ElMessage } from 'element-plus';
|
import { useFormConfirm } from '@/composables/formConfirm';
|
import { streets } from '@/constant/street';
|
import clueQuestionApi from '@/api/clue/clueQuestionApi';
|
import { $clue } from '@/api/index';
|
import MapSearch from '@/components/map/MapSearch.vue';
|
|
// 决定当前是否是内部线索相关操作
|
const isInternal = inject('isInternal', false);
|
|
const props = defineProps({
|
// 应急线索对象
|
clueData: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
// 对话框显示控制
|
show: Boolean,
|
// 线索问题对象
|
question: Object,
|
// 问题是否已上传
|
uploaded: {
|
type: Boolean,
|
default: false
|
},
|
maxImageCount: {
|
type: Number,
|
default: 3
|
}
|
});
|
|
const emit = defineEmits(['update:show', 'onSubmit', 'onClose']);
|
|
// 创建或是修改模式
|
const createMode = ref(true);
|
|
// 上报弹出框
|
const dialogShow = ref(false);
|
const mapDialogShow = ref(false);
|
const uploadRef = ref();
|
const fileList = ref([]);
|
// 更新模式下,记录被删除的原有图片
|
let deletedFileList = [];
|
// 决定是否能上传图片
|
const uploadableClz = computed(() => {
|
return props.uploaded ||
|
(fileList.value && fileList.value.length >= props.maxImageCount)
|
? 'question-not-upload'
|
: '';
|
});
|
|
const previewShow = ref(false);
|
const initialIndex = ref(0);
|
const urlList = computed(() =>
|
fileList.value
|
? fileList.value.map((value) => {
|
return value.url;
|
})
|
: []
|
);
|
|
function handleFilePreview(file) {
|
initialIndex.value = fileList.value.indexOf(file);
|
previewShow.value = true;
|
}
|
|
function closePreview() {
|
previewShow.value = false;
|
}
|
|
function handleFileRemove(file, files) {
|
if (!createMode.value) {
|
if (file.url.indexOf($clue.imgUrl) != -1) {
|
const originUrl = file.url.replace($clue.imgUrl, '');
|
deletedFileList.push(originUrl);
|
}
|
}
|
const index = fileList.value.indexOf(file);
|
fileList.value.splice(index, 1);
|
// fileList.value = fileList;
|
edit.value = true;
|
}
|
|
function handleFileChange(file, files) {
|
fileList.value = files;
|
edit.value = true;
|
}
|
|
const { formObj, formRef, edit, onSubmit, onCancel, clear } =
|
useFormConfirm({
|
submit: {
|
do: submit
|
},
|
cancel: {
|
do: cancel
|
}
|
});
|
const loading = ref(false);
|
// 表单检查规则
|
const rules = reactive({
|
cqName: [
|
{
|
required: true,
|
message: '问题名称不能为空',
|
trigger: 'blur'
|
}
|
],
|
cqDescription: [
|
{
|
required: true,
|
message: '问题描述不能为空',
|
trigger: 'blur'
|
}
|
],
|
cqStreet: [
|
{
|
required: true,
|
message: '所在街镇不能为空',
|
trigger: 'change'
|
}
|
],
|
cqAddress: [
|
{
|
required: true,
|
message: '详细地址不能为空',
|
trigger: 'blur'
|
}
|
],
|
coordinate: [
|
{
|
required: true,
|
message: '坐标不能为空',
|
trigger: 'blur'
|
}
|
]
|
// cqLongitude: [
|
// {
|
// required: true,
|
// message: '经度不能为空',
|
// trigger: 'blur'
|
// }
|
// ],
|
// cqLatitude: [
|
// {
|
// required: true,
|
// message: '维度不能为空',
|
// trigger: 'blur'
|
// }
|
// ],
|
// files: [
|
// {
|
// required: true,
|
// message: '图片不能为空',
|
// trigger: 'change'
|
// }
|
// ]
|
});
|
|
function submit() {
|
if (!fileList.value || fileList.value.length == 0) {
|
ElMessage({
|
message: '至少上传一张图片',
|
type: 'error'
|
});
|
return;
|
}
|
const coor = formObj.value.coordinate.split(',');
|
const q = {
|
...formObj.value,
|
// cqId: formObj.value.cqId,
|
cId: parseInt(props.clueData.cid),
|
// cqName: formObj.value.cqName,
|
// cqDescription: formObj.value.cqDescription,
|
// cqStreet: formObj.value.cqStreet,
|
// cqAddress: formObj.value.cqAddress,
|
cqLongitude: parseFloat(coor[0]),
|
cqLatitude: parseFloat(coor[1]),
|
cqInternal: isInternal
|
// cqFilePath: formObj.value.cqFilePath
|
};
|
const files = [];
|
if (fileList.value) {
|
fileList.value.forEach((f) => {
|
if (f.url.indexOf($clue.imgUrl) == -1) {
|
files.push(f.raw);
|
}
|
});
|
}
|
return createMode.value
|
? uploadQuestion(q, files)
|
: updateQuestion(q, files);
|
}
|
|
function cancel() {
|
// clear();
|
dialogShow.value = false;
|
}
|
|
function openMapDialog() {
|
mapDialogShow.value = true;
|
}
|
|
function selectAddress(result) {
|
formObj.value.cqAddress = result.address;
|
formObj.value.coordinate = result.gpsLon + ',' + result.gpsLat;
|
}
|
|
/**
|
* 上传线索结论
|
*/
|
function uploadQuestion(question, files) {
|
loading.value = true;
|
return clueQuestionApi
|
.uploadQuestion(question, files)
|
.then(() => {
|
dialogShow.value = false;
|
// clear();
|
uploadRef.value.clearFiles();
|
emit('onSubmit');
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
}
|
|
function updateQuestion(question, newFiles) {
|
loading.value = true;
|
const deleteImgUrl = deletedFileList.join(';');
|
return clueQuestionApi
|
.updateQuestion(question, newFiles, deleteImgUrl)
|
.then(() => {
|
dialogShow.value = false;
|
// clear();
|
uploadRef.value.clearFiles();
|
emit('onSubmit');
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
}
|
|
function parseFormObj(question) {
|
question.coordinate =
|
question.cqLongitude + ',' + question.cqLatitude;
|
fileList.value = question.files.map((f, index) => {
|
return {
|
name: `${index}`,
|
url: f
|
};
|
});
|
return { ...question };
|
}
|
|
watch(
|
() => [props.show, props.question],
|
(val) => {
|
dialogShow.value = val[0];
|
if (val[0]) {
|
fileList.value = [];
|
deletedFileList = [];
|
if (val[1]) {
|
createMode.value = false;
|
formObj.value = parseFormObj(val[1]);
|
} else {
|
createMode.value = true;
|
formObj.value = {};
|
}
|
// edit.value = false
|
}
|
}
|
);
|
|
watch(dialogShow, (val) => {
|
if (!val) {
|
clear();
|
}
|
emit('update:show', val);
|
});
|
</script>
|
<style scoped>
|
:deep(.question-not-upload .el-upload-list > .el-upload) {
|
display: none;
|
}
|
</style>
|