@@ -15,6 +15,8 @@ | |||
<PreviewModal v-if="previewModal" v-model:visible="previewModal" :data="pageData" :select-row="rowData" /> | |||
<QuestionModal v-if="modalShow" v-model:visible="modalShow" :order-id="orderId" :data="rowData" @reload="handleSearch" /> | |||
</n-drawer-content> | |||
</n-drawer> | |||
@@ -27,12 +29,13 @@ import HeadSearch from '@/components/Search/index.vue' | |||
import DataTable from '@/components/DataTable/index.vue' | |||
import { defineComponent, reactive, unref, toRefs, computed, watch } from 'vue' | |||
import PreviewModal from './PreviewModal.vue' | |||
import QuestionModal from './QuestionModal.vue' | |||
import MapDrawer from './MapDrawer.vue' | |||
import { getOrderQuesList } from '@/api/order/index.js' | |||
export default defineComponent({ | |||
name: 'LiveDrawer', | |||
components: { HeadSearch, DataTable, MapDrawer, PreviewModal }, | |||
components: { HeadSearch, DataTable, MapDrawer, QuestionModal, PreviewModal }, | |||
props: { | |||
/* 可见 */ | |||
visible: { | |||
@@ -52,6 +55,7 @@ export default defineComponent({ | |||
const data = reactive({ | |||
search, | |||
...toRefs(table), | |||
orderId: null, | |||
pageData: [] | |||
}) | |||
@@ -69,9 +73,9 @@ export default defineComponent({ | |||
} | |||
watch(() => [props.visible, props.data], | |||
([val1, val2]) => { | |||
// if (val1 && val2.id) { | |||
// } | |||
if (val1 && val2.id) { | |||
data.orderId = val2.id | |||
} | |||
}) | |||
const loadDataTable = async(res) => { | |||
const _params = { |
@@ -0,0 +1,177 @@ | |||
<template> | |||
<Modal | |||
:options="getModalOptions" | |||
:on-positive-click="throttleFn" | |||
:on-negative-click="handleClose" | |||
:on-close="handleClose" | |||
> | |||
<template #Context> | |||
<n-form | |||
ref="formRef" | |||
:model="questionForm" | |||
:rules="questionRules" | |||
:label-width="120" | |||
label-placement="left" | |||
require-mark-placement="left" | |||
:disabled="disabled" | |||
> | |||
<template v-for="(item,index) in getFormOptions" :key="index"> | |||
<n-form-item :label="item.label" :path="item.key"> | |||
<n-input v-if="item.type === 'input'" v-model:value="questionForm[item.key]" v-bind="item.props" /> | |||
<n-select v-if="item.type === 'select'" v-model:value="questionForm[item.key]" v-bind="item.props" /> | |||
<n-image v-if="item.type === 'image'" v-model:src="questionForm[item.key]" v-bind="item.props" /> | |||
<UploadOss v-if="item.type === 'oss'" :ref="el=>{ossRefs[item.refIndex] = el}" :limit="5" :default-list="questionForm[item.file]" @upload-status="handleUploadStatus" /> | |||
</n-form-item> | |||
</template> | |||
</n-form> | |||
</template> | |||
</Modal> | |||
</template> | |||
<script> | |||
import { form } from '../tools/quesForm.js' | |||
import { defineComponent, ref, reactive, computed, toRefs } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import UploadOss from '@/components/UploadOss/index.vue' | |||
import { handleOrder } from '@/api/order/index.js' | |||
import { throttle } from '@/utils/index.js' | |||
export default defineComponent({ | |||
name: 'UserModal', | |||
components: { Modal, UploadOss }, | |||
props: { | |||
visible: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
type: { | |||
type: String, | |||
default: 'preview' | |||
}, | |||
orderId: { | |||
type: Number, | |||
default: null | |||
}, | |||
data: { | |||
type: Object, | |||
default: () => null | |||
} | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'reload': null | |||
}, | |||
setup(props, { emit }) { | |||
const MODAL_TYPE = { | |||
'preview': '问题详情', | |||
'update': '处理问题' | |||
} | |||
const { questionForm, questionRules } = form | |||
const formRef = ref() | |||
const data = reactive({ | |||
questionForm: { | |||
...questionForm, | |||
imageStatus: '', | |||
...props.data, | |||
position: `${props.data.lng},${props.data.lat}` | |||
}, | |||
questionRules: { | |||
...questionRules | |||
}, | |||
disabled: props.type === 'preview' | |||
}) | |||
const getModalOptions = computed(() => { | |||
return { | |||
show: props.visible, | |||
title: MODAL_TYPE[props.type], | |||
negativeText: '取消', | |||
positiveText: '确认' | |||
} | |||
}) | |||
const getFormOptions = computed(() => { | |||
if (props.type === 'preview' && props.data.status === 0) { | |||
const list = form.formItem.filter((item) => !item.mode) | |||
return { | |||
...list | |||
} | |||
} else if (props.data.status === 0) { | |||
const list = form.formItem.filter((item) => !item.handle) | |||
return { | |||
...list | |||
} | |||
} else { | |||
return { | |||
...form.formItem | |||
} | |||
} | |||
}) | |||
const ossRefs = ref([]) | |||
function handleUploadStatus(status) { | |||
switch (status) { | |||
case 'no-file': | |||
data.questionForm.imageStatus = '' | |||
break | |||
default: | |||
data.questionForm.imageStatus = status | |||
} | |||
} | |||
function handleConfirm() { | |||
if (props.type === 'preview') { | |||
handleClose() | |||
return | |||
} | |||
formRef.value?.validate((errors) => { | |||
if (!errors) { | |||
const uploads = ossRefs.value.map((item, index) => { | |||
return item.startUpload() | |||
}) | |||
Promise.all(uploads) | |||
.then(response => { | |||
const isError = response.map((item) => { | |||
return item.includes('error') | |||
}) | |||
if (!isError.includes(true)) { | |||
const imageStr = response.join() | |||
const params = { | |||
workOrderId: props.orderId, | |||
...data.questionForm, | |||
handlerImage: imageStr | |||
} | |||
handleOrder(params) | |||
.then(res => { | |||
if (res.code === 0) { | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} | |||
}) | |||
} else { | |||
$message.error('请完善必填信息') | |||
} | |||
}) | |||
} | |||
const throttleFn = throttle(handleConfirm, 5000) | |||
/* 关闭弹窗 */ | |||
const handleClose = () => { | |||
emit('update:visible', false) | |||
} | |||
return { | |||
...toRefs(data), | |||
formRef, | |||
getModalOptions, | |||
getFormOptions, | |||
ossRefs, | |||
handleUploadStatus, | |||
throttleFn, | |||
handleClose | |||
} | |||
} | |||
}) | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -0,0 +1,23 @@ | |||
import { ref, reactive } from 'vue' | |||
import { QUESTION_TYPE_ALL, QUES_STATUS } from '@/utils/dictionary.js' | |||
export const form = reactive({ | |||
questionForm: { | |||
handlerResult: '' | |||
}, | |||
questionRules: { | |||
imageStatus: { required: true, message: '请选择图片', trigger: ['blur', 'change'] } | |||
}, | |||
formItem: [ | |||
{ type: 'select', key: 'type', label: '问题类型', props: { options: QUESTION_TYPE_ALL, disabled: true }}, | |||
{ type: 'input', key: 'position', label: '问题经纬度', props: { disabled: true }}, | |||
{ type: 'input', key: 'createTime', label: '问题发现时间', props: { disabled: true }}, | |||
{ type: 'image', key: 'fileMarkerUrl', label: '问题图片', props: { width: 100 }}, | |||
{ type: 'select', key: 'status', label: '问题状态', props: { options: QUES_STATUS, disabled: true }}, | |||
{ type: 'input', key: 'handlerTime', label: '处理时间', props: { disabled: true }, mode: true, handle: true }, | |||
{ type: 'input', key: 'handlerUserName', label: '处理人员', props: { disabled: true }, mode: true, handle: true }, | |||
{ type: 'oss', refIndex: 0, key: 'imageStatus', file: 'handlerImage', label: '处理图片', mode: true }, | |||
{ type: 'input', key: 'handlerResult', label: '处理备注', props: { type: 'textarea', maxlength: 255 }, mode: true } | |||
] | |||
}) | |||
@@ -21,6 +21,11 @@ function handleSearch(params) { | |||
tableRef.value.reFetch({ searchParams }) | |||
} | |||
function handleDetail(row) { | |||
data.rowData = row | |||
data.modalShow = true | |||
} | |||
/* 位置 */ | |||
function handlePositionDrawer(row) { | |||
data.rowData = row | |||
@@ -38,6 +43,7 @@ const data = reactive({ | |||
rowData: {}, | |||
mapDrawer: false, | |||
previewModal: false, | |||
modalShow: false, | |||
handleSearch, | |||
columns: [ | |||
@@ -125,27 +131,50 @@ const data = reactive({ | |||
align: 'center', | |||
width: 200 | |||
}, | |||
// { | |||
// title: '处理后图片', | |||
// key: 'handlerImage', | |||
// align: 'center', | |||
// render(row) { | |||
// return h(TableImage, { | |||
// images: { | |||
// width: 36, | |||
// height: 36, | |||
// src: row.handlerImage, | |||
// previewDisabled: true | |||
// // onClick: handleImgPreview.bind(null, row) | |||
// } | |||
// }) | |||
// } | |||
// }, | |||
// { | |||
// title: '备注', | |||
// key: 'handlerResult', | |||
// align: 'center', | |||
// width: 200 | |||
// } | |||
{ | |||
title: '处理后图片', | |||
key: 'handlerImage', | |||
title: '操作', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableImage, { | |||
images: { | |||
width: 36, | |||
height: 36, | |||
src: row.handlerImage, | |||
previewDisabled: true | |||
// onClick: handleImgPreview.bind(null, row) | |||
} | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '详情', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onClick: handleDetail.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
} | |||
], | |||
align: 'center' | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '备注', | |||
key: 'handlerResult', | |||
align: 'center', | |||
width: 200 | |||
} | |||
] |
@@ -133,22 +133,22 @@ const data = reactive({ | |||
align: 'center', | |||
width: 200 | |||
}, | |||
{ | |||
title: '处理后图片', | |||
key: 'handlerImage', | |||
align: 'center', | |||
render(row) { | |||
return h(TableImage, { | |||
images: { | |||
width: 36, | |||
height: 36, | |||
src: row.handlerImage, | |||
previewDisabled: true, | |||
onClick: handleImgPreview.bind(null, row) | |||
} | |||
}) | |||
} | |||
}, | |||
// { | |||
// title: '处理后图片', | |||
// key: 'handlerImage', | |||
// align: 'center', | |||
// render(row) { | |||
// return h(TableImage, { | |||
// images: { | |||
// width: 36, | |||
// height: 36, | |||
// src: row.handlerImage, | |||
// previewDisabled: true, | |||
// // onClick: handleImgPreview.bind(null, row) | |||
// } | |||
// }) | |||
// } | |||
// }, | |||
{ | |||
title: '操作', | |||
align: 'center', |