@@ -32,7 +32,7 @@ | |||
> | |||
<div | |||
style=" | |||
width: 150px; | |||
width: 195px; | |||
white-space: nowrap; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
@@ -72,10 +72,10 @@ | |||
</div> | |||
<div v-else class="listDetail"> | |||
<n-date-picker | |||
:on-update:formatted-value="abc" | |||
:default-formatted-value="efg" | |||
:on-update:formatted-value="changeDate" | |||
:default-formatted-value="lastSevenDateList" | |||
type="daterange" | |||
:default-value="[Date.now() - 6.048e8, Date.now()]" | |||
:is-date-disabled="disablePreviousDate" | |||
style="margin-bottom: 15px" | |||
/> | |||
@@ -203,6 +203,8 @@ export default { | |||
listShow: false, | |||
// 时间范围是一周前至今天 | |||
efg: '', | |||
initDate: 0, | |||
clickListNum: 0, | |||
listIcon: new URL( | |||
'../../../assets/images/listChecked.png', | |||
import.meta.url | |||
@@ -229,7 +231,8 @@ export default { | |||
listChecked: false, | |||
airportSelected: true, | |||
problemLayerList: [], | |||
airportPopupShow: false | |||
airportPopupShow: false, | |||
lastSevenDateList: [] | |||
}) | |||
watch( | |||
() => data.page, | |||
@@ -385,6 +388,10 @@ export default { | |||
// console.log(new Date().getFullYear()) | |||
} | |||
// 获取近7天的日期 | |||
const initSevenDate = () => { | |||
data.lastSevenDateList = [getDay(-7), getDay(0)] | |||
} | |||
/** | |||
* 展示机场信息 | |||
* @param {} e | |||
@@ -473,10 +480,24 @@ export default { | |||
query: { rowInfo: JSON.stringify(item) } | |||
}) | |||
} | |||
const abc = (value) => { | |||
const changeDate = (value) => { | |||
if (value) { | |||
data.lastSevenDateList = value | |||
} | |||
if (data.initDate == 0) { | |||
// 默认加载近7天的问题图层 | |||
// 获取近7天的日期 | |||
getQuestionInfo(getDay(-7), getDay(0)) | |||
} else { | |||
getQuestionInfo(value[0], value[1]) | |||
} | |||
data.initDate += 1 | |||
} | |||
// 获取问题图层数据 | |||
const getQuestionInfo = (startTime, endTime) => { | |||
getQuestionList({ | |||
startTime: value[0], | |||
endTime: value[1] | |||
startTime: startTime, | |||
endTime: endTime | |||
}).then((res) => { | |||
if (res.code === 0) { | |||
const arr = res.data | |||
@@ -499,6 +520,35 @@ export default { | |||
} | |||
}) | |||
} | |||
// 获取日期 | |||
const getDay = (day) => { | |||
var today = new Date() | |||
var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day | |||
today.setTime(targetday_milliseconds) // 注意,这行是关键代码 | |||
var tYear = today.getFullYear() | |||
var tMonth = today.getMonth() | |||
var tDate = today.getDate() | |||
tMonth = doHandleMonth(tMonth + 1) | |||
tDate = doHandleMonth(tDate) | |||
return tYear + '-' + tMonth + '-' + tDate | |||
} | |||
const doHandleMonth = (month) => { | |||
var m = month | |||
if (month.toString().length == 1) { | |||
m = '0' + month | |||
} | |||
return m | |||
} | |||
// 添加问题图层 | |||
const addproblemLayer = (narr) => { | |||
if (data.problemLayerList.length > 0) { | |||
@@ -614,6 +664,12 @@ export default { | |||
* @description:是否展示列表 | |||
*/ | |||
const showList = () => { | |||
// 判断是不是第一次点击列表按钮 | |||
if (data.clickListNum == 0) { | |||
// 第一次点击列表按钮会显示问题图层 | |||
changeDate() | |||
} | |||
data.clickListNum += 1 | |||
data.listChecked = !data.listChecked | |||
} | |||
/** | |||
@@ -656,6 +712,7 @@ export default { | |||
initMap() | |||
initTaskList() | |||
initProblemType() | |||
initSevenDate() | |||
}) | |||
return { | |||
@@ -683,7 +740,7 @@ export default { | |||
} | |||
return ts > Date.now() | |||
}, | |||
abc, | |||
changeDate, | |||
showAirportList, | |||
handleProblemTypeValue, | |||
hideProblemInfo, | |||
@@ -781,7 +838,7 @@ export default { | |||
position: absolute; | |||
top: 64px; | |||
right: 90px; | |||
width: 355px; | |||
width: 400px; | |||
height: 428px; | |||
background: #000000; | |||
box-sizing: border-box; | |||
@@ -802,7 +859,7 @@ export default { | |||
} | |||
} | |||
.listDetail { | |||
width: 345px; | |||
width: 390px; | |||
height: 383px; | |||
background: #2c2c2c; | |||
font-size: 14px; |
@@ -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', |