{ | { | ||||
"recommendations": ["johnsoncodehk.volar"] | |||||
"recommendations": ["vue.volar"] | |||||
} | } |
import { defAxios as request } from '@/utils/http' | |||||
/** | |||||
* @description: 获取工单列表 | |||||
* @param {*} params | |||||
* @return {*} | |||||
*/ | |||||
export function generateOrder(ids) { | |||||
return request({ | |||||
url: `/workOrder/generate/${ids}`, | |||||
method: 'POST' | |||||
}) | |||||
} | |||||
/** | |||||
* @description: 获取工单列表 | |||||
* @param {*} params | |||||
* @return {*} | |||||
*/ | |||||
export function getOrderList(params) { | |||||
return request({ | |||||
url: '/workOrder/page', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | |||||
* @description: 分配工单 | |||||
* @param {*} data | |||||
* @return {*} | |||||
*/ | |||||
export function assignOrder(data) { | |||||
return request({ | |||||
url: '/workOrder/assign', | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description: 获取工单下的问题 | |||||
* @param {*} data | |||||
* @return {*} | |||||
*/ | |||||
export function getOrderQuesList(params) { | |||||
return request({ | |||||
url: '/workOrder/question/page', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | |||||
* @description: 处理问题 | |||||
* @param {*} data | |||||
* @return {*} | |||||
*/ | |||||
export function handleOrder(data) { | |||||
return request({ | |||||
url: '/workOrder/handle', | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} |
<template> | <template> | ||||
<n-image v-bind="getProps" /> | |||||
<!-- <n-image v-if="getProps.src" v-bind="getProps" /> --> | |||||
<n-image v-for="(item,index) in getProps" v-show="index < limit" :key="index" v-bind="item" /> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import { defineComponent, computed, toRaw } from 'vue' | import { defineComponent, computed, toRaw } from 'vue' | ||||
import { isArray } from '@/utils/is.js' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'TableImage', | name: 'TableImage', | ||||
props: { | props: { | ||||
type: Object, | type: Object, | ||||
default: null, | default: null, | ||||
required: true | required: true | ||||
}, | |||||
limit: { | |||||
type: Number, | |||||
default: 1 | |||||
} | } | ||||
}, | }, | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const getProps = computed(() => { | const getProps = computed(() => { | ||||
return (toRaw(props.images)) | |||||
const images = { ...toRaw(props.images) } | |||||
let list = [] | |||||
if (isArray(images.src)) { | |||||
list = images.src | |||||
} | |||||
if (images.src) { | |||||
list = images.src.split(',') | |||||
} | |||||
return list.map((item) => { | |||||
return { | |||||
...toRaw(props.images), | |||||
src: item | |||||
} | |||||
}) | |||||
}) | }) | ||||
return { | return { |
<template> | <template> | ||||
<n-switch v-bind="getSwitchProps" v-model:value="switchVlue" @update:value="changeValue" /> | |||||
<n-switch v-bind="getSwitchProps" v-model:value="getSwitchValue" @update:value="changeValue" /> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
import { defineComponent, ref, unref, computed } from 'vue' | |||||
import { defineComponent, unref, computed } from 'vue' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'TableSwitch', | name: 'TableSwitch', | ||||
props: { | props: { | ||||
}, | }, | ||||
emits: ['change'], | emits: ['change'], | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const switchVlue = ref() | |||||
const { data, rowKey } = unref(props) | |||||
switchVlue.value = rowKey ? data[rowKey] : data | |||||
// const switchValue = ref() | |||||
// const { data, rowKey } = unref(props) | |||||
// switchValue.value = rowKey ? data[rowKey] : data | |||||
const getSwitchValue = computed(() => { | |||||
const { data, rowKey } = unref(props) | |||||
const value = rowKey ? data[rowKey] : data | |||||
return value | |||||
}) | |||||
const getSwitchProps = computed(() => { | const getSwitchProps = computed(() => { | ||||
console.log(111) | |||||
return { | return { | ||||
...unref(props) | ...unref(props) | ||||
} | } | ||||
emit('change', params) | emit('change', params) | ||||
} | } | ||||
return { | return { | ||||
switchVlue, | |||||
// switchValue, | |||||
getSwitchValue, | |||||
getSwitchProps, | getSwitchProps, | ||||
changeValue | changeValue | ||||
} | } |
{ label: '待确认', value: 3 } | { label: '待确认', value: 3 } | ||||
] | ] | ||||
export const ORDER_STATUS = [ | |||||
{ label: '待生成', value: 0 }, | |||||
{ label: '已生成', value: 1 }, | |||||
{ label: '待分配', value: 5 }, | |||||
{ label: '处理中', value: 10 }, | |||||
{ label: '已完成', value: 15 } | |||||
] | |||||
export const ORDER_STATUS2 = [ | |||||
{ label: '待分配', value: 5 }, | |||||
{ label: '已分配', value: 10 }, | |||||
{ label: '已完成', value: 15 } | |||||
] | |||||
export const QUES_STATUS = [ | |||||
{ label: '待处理', value: 0 }, | |||||
{ label: '已处理', value: 1 } | |||||
] | |||||
export const USER_STATUS = [ | export const USER_STATUS = [ | ||||
{ label: '正常', value: 1 }, | { label: '正常', value: 1 }, | ||||
{ label: '禁用', value: 2 } | { label: '禁用', value: 2 } |
<template> | |||||
<Modal | |||||
:options="getModalOptions" | |||||
:on-positive-click="handleConfirm" | |||||
:on-negative-click="handleClose" | |||||
:on-close="handleClose" | |||||
> | |||||
<template #Context> | |||||
<n-form | |||||
ref="formRef" | |||||
:model="assignForm" | |||||
:rules="assignRules" | |||||
:label-width="80" | |||||
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-select v-if="item.type === 'select'" v-model:value="assignForm[item.key]" v-bind="item.props" /> | |||||
</n-form-item> | |||||
</template> | |||||
</n-form> | |||||
</template> | |||||
</Modal> | |||||
</template> | |||||
<script> | |||||
import { form, getUserOptions } from '../tools/form.js' | |||||
import { defineComponent, ref, reactive, computed, toRefs } from 'vue' | |||||
import Modal from '@/components/Modal/index.vue' | |||||
import { assignOrder } from '@/api/order/index.js' | |||||
export default defineComponent({ | |||||
name: 'UserModal', | |||||
components: { Modal }, | |||||
props: { | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
type: { | |||||
type: String, | |||||
default: 'create' | |||||
}, | |||||
data: { | |||||
type: Object, | |||||
default: () => null | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null, | |||||
'reload': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
getUserOptions() | |||||
const { assignForm, assignRules } = form | |||||
const formRef = ref() | |||||
const data = reactive({ | |||||
assignForm: { | |||||
...assignForm | |||||
}, | |||||
assignRules: { | |||||
...assignRules | |||||
}, | |||||
disabled: props.type === 'preview' | |||||
}) | |||||
const getModalOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
title: '分配用户', | |||||
negativeText: '取消', | |||||
positiveText: '确认' | |||||
} | |||||
}) | |||||
const getFormOptions = computed(() => { | |||||
return { | |||||
...form.formItem | |||||
} | |||||
}) | |||||
function handleConfirm() { | |||||
formRef.value?.validate((errors) => { | |||||
if (!errors) { | |||||
const params = { | |||||
id: props.data.id, | |||||
...data.assignForm | |||||
// handleUserList: data.assignForm.handleUserList.join(',') | |||||
} | |||||
assignOrder(params) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
emit('reload') | |||||
handleClose() | |||||
} | |||||
}) | |||||
} else { | |||||
$message.error('请完善必填信息') | |||||
} | |||||
}) | |||||
} | |||||
/* 关闭弹窗 */ | |||||
const handleClose = () => { | |||||
emit('update:visible', false) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
formRef, | |||||
getModalOptions, | |||||
getFormOptions, | |||||
handleConfirm, | |||||
handleClose | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
</style> |
<template> | |||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||||
<n-drawer-content closable title="图片位置"> | |||||
<PositionMsg :data="getPostionOptions" :show-legend="false" /> | |||||
</n-drawer-content> | |||||
</n-drawer> | |||||
</template> | |||||
<script> | |||||
import PositionMsg from '@/components/PositionMsg/index.vue' | |||||
import { defineComponent, computed, reactive, toRefs } from 'vue' | |||||
export default defineComponent({ | |||||
name: 'LiveDrawer', | |||||
components: { PositionMsg }, | |||||
props: { | |||||
/* 可见 */ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
}) | |||||
/* 获取抽屉的信息 */ | |||||
const getDrawerOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
width: '100%', | |||||
placement: 'right' | |||||
} | |||||
}) | |||||
const getPostionOptions = computed(() => { | |||||
return [props.data] | |||||
}) | |||||
function handleDrawerColse() { | |||||
emit('update:visible', false) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
getDrawerOptions, | |||||
getPostionOptions, | |||||
handleDrawerColse | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.n-button+.n-button{ | |||||
margin-left: 30px; | |||||
} | |||||
</style> |
<template> | |||||
<Modal | |||||
:options="getModalOptions" | |||||
:on-close="handleClose" | |||||
> | |||||
<template #Context> | |||||
<div class="modal-form"> | |||||
<label>问题类型</label> | |||||
{{ getQuestionType }} | |||||
</div> | |||||
<div class="carousel__flex"> | |||||
<n-icon size="26" color="#8A8A8A"> | |||||
<LeftOutlined @click="handleCarousel('prev')" /> | |||||
</n-icon> | |||||
<div class="carousel__container"> | |||||
<label>问题图片</label> | |||||
<n-carousel ref="carouselRef" :default-index="selectIndex" :show-dots="false"> | |||||
<img | |||||
v-for="item in getCarouselInfo" | |||||
:key="item.id" | |||||
class="carousel-img" | |||||
:src="item.fileMarkerUrl" | |||||
> | |||||
</n-carousel> | |||||
</div> | |||||
<n-icon size="26" color="#8A8A8A"> | |||||
<RightOutlined @click="handleCarousel('next')" /> | |||||
</n-icon> | |||||
</div> | |||||
</template> | |||||
</Modal> | |||||
</template> | |||||
<script> | |||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
import { LeftOutlined, RightOutlined } from '@vicons/antd' | |||||
import Modal from '@/components/Modal/index.vue' | |||||
import { defineComponent, computed, ref, reactive, toRefs } from 'vue' | |||||
export default defineComponent({ | |||||
name: 'UserModal', | |||||
components: { Modal, LeftOutlined, RightOutlined }, | |||||
props: { | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: () => null | |||||
}, | |||||
selectRow: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const formRef = ref() | |||||
const data = reactive({ | |||||
selectRow: props.selectRow, | |||||
selectIndex: props.data.findIndex((item) => { return item.id === props.selectRow.id }), | |||||
selectType: props.selectRow.type | |||||
}) | |||||
/* 获取弹窗的属性 */ | |||||
const getModalOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
title: '图片详情', | |||||
width: 700 | |||||
} | |||||
}) | |||||
const getCarouselInfo = computed(() => { | |||||
return props.data | |||||
}) | |||||
const getQuestionType = computed(() => { | |||||
const row = QUESTION_TYPE.value.find((item) => { return item.value === data.selectRow.type }) | |||||
return row?.label || '-' | |||||
}) | |||||
const carouselRef = ref(null) | |||||
function handleCarousel(type) { | |||||
const currentIndex = carouselRef.value.getCurrentIndex() | |||||
switch (type) { | |||||
case 'prev': | |||||
if (currentIndex !== 0) { | |||||
carouselRef.value.prev() | |||||
data.selectRow = props.data[currentIndex - 1] | |||||
data.selectType = props.data[currentIndex - 1].type | |||||
} | |||||
break | |||||
case 'next': | |||||
if (currentIndex !== props.data.length - 1) { | |||||
carouselRef.value.next() | |||||
data.selectRow = props.data[currentIndex + 1] | |||||
data.selectType = props.data[currentIndex + 1].type | |||||
} | |||||
break | |||||
} | |||||
} | |||||
/* 关闭弹窗 */ | |||||
const handleClose = () => { | |||||
emit('update:visible', false) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
formRef, | |||||
getModalOptions, | |||||
getQuestionType, | |||||
getCarouselInfo, | |||||
carouselRef, | |||||
handleCarousel, | |||||
handleClose | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.carousel__flex{ | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
margin-bottom: 20px; | |||||
.carousel__container{ | |||||
width: calc(100% - 100px); | |||||
display: flex; | |||||
margin-right: 40px; | |||||
label{ | |||||
width: 70px; | |||||
flex-shrink: 0; | |||||
} | |||||
} | |||||
.n-icon{ | |||||
cursor: pointer; | |||||
} | |||||
.carousel-img{ | |||||
width: 100%; | |||||
height: 280px; | |||||
object-fit: cover | |||||
} | |||||
} | |||||
.modal-form{ | |||||
width: calc(100% - 60px); | |||||
display: flex; | |||||
align-items: center; | |||||
margin: 20px auto 20px; | |||||
label{ | |||||
width: 70px; | |||||
flex-shrink: 0; | |||||
} | |||||
.n-select{ | |||||
width: 300px; | |||||
} | |||||
} | |||||
</style> |
<template> | |||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||||
<n-drawer-content closable title="问题列表"> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<DataTable | |||||
ref="tableRef" | |||||
:columns="columns" | |||||
:row-key="(row) => row.id" | |||||
:request="loadDataTable" | |||||
size="large" | |||||
@fetch-success="getTableData" | |||||
/> | |||||
<MapDrawer v-model:visible="mapDrawer" :data="rowData" /> | |||||
<PreviewModal v-if="previewModal" v-model:visible="previewModal" :data="pageData" :select-row="rowData" /> | |||||
</n-drawer-content> | |||||
</n-drawer> | |||||
</template> | |||||
<script> | |||||
import table from '../tools/quesTable.js' | |||||
import { search } from '../tools/quesSearch.js' | |||||
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 MapDrawer from './MapDrawer.vue' | |||||
import { getOrderQuesList } from '@/api/order/index.js' | |||||
export default defineComponent({ | |||||
name: 'LiveDrawer', | |||||
components: { HeadSearch, DataTable, MapDrawer, PreviewModal }, | |||||
props: { | |||||
/* 可见 */ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
search, | |||||
...toRefs(table), | |||||
pageData: [] | |||||
}) | |||||
/* 获取抽屉的信息 */ | |||||
const getDrawerOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
width: '100%', | |||||
placement: 'right' | |||||
} | |||||
}) | |||||
/* 关闭抽屉 */ | |||||
function handleDrawerColse() { | |||||
emit('update:visible', false) | |||||
} | |||||
watch(() => [props.visible, props.data], | |||||
([val1, val2]) => { | |||||
// if (val1 && val2.id) { | |||||
// } | |||||
}) | |||||
const loadDataTable = async(res) => { | |||||
const _params = { | |||||
...unref(data.searchParams), | |||||
workOrderId: props.data.id, | |||||
...res | |||||
} | |||||
if (_params.questionType === 'all') _params.questionType = null | |||||
if (_params.status === 'all') _params.status = null | |||||
return await getOrderQuesList(_params) | |||||
} | |||||
function getTableData(list) { | |||||
data.pageData = list.items | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
getDrawerOptions, | |||||
handleDrawerColse, | |||||
loadDataTable, | |||||
getTableData | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.report__container{ | |||||
width: 900px; | |||||
margin: 0 auto 40px auto; | |||||
.report__item{ | |||||
margin-bottom: 40px; | |||||
.report__item--title{ | |||||
font-size: 18px; | |||||
color: #333333; | |||||
line-height: 44px; | |||||
} | |||||
.n-grid{ | |||||
border-top: 1px solid rgba(216, 216, 216, 1); | |||||
border-left: 1px solid rgba(216, 216, 216, 1); | |||||
>div{ | |||||
position: relative; | |||||
text-align: center; | |||||
font-size: 14px; | |||||
color: #333333; | |||||
line-height: 20px; | |||||
padding: 6px 12px; | |||||
word-wrap: break-word; | |||||
word-break: normal; | |||||
border-right: 1px solid rgba(216, 216, 216, 1); | |||||
border-bottom: 1px solid rgba(216, 216, 216, 1); | |||||
&:nth-child(2n-1){ | |||||
span{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 50%; | |||||
transform: translate(-50%,-50%); | |||||
} | |||||
background: rgba(228, 231, 237, 1); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.report__operate{ | |||||
text-align: center; | |||||
} | |||||
} | |||||
::v-deep(.n-image){ | |||||
width: 100%; | |||||
img{ | |||||
width: 100%; | |||||
} | |||||
} | |||||
</style> |
<template> | |||||
<div> | |||||
<n-card> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<DataTable | |||||
ref="tableRef" | |||||
:columns="columns" | |||||
:row-key="(row) => row.id" | |||||
:request="loadDataTable" | |||||
size="large" | |||||
/> | |||||
</n-card> | |||||
</div> | |||||
<AssignModal v-if="modalShow" v-model:visible="modalShow" :data="rowData" @reload="handleSearch" /> | |||||
<QuestionDrawer v-model:visible="detailDrawer" :data="rowData" /> | |||||
</template> | |||||
<script> | |||||
import table from './tools/table.js' | |||||
import { search } from './tools/search.js' | |||||
import HeadSearch from '@/components/Search/index.vue' | |||||
import DataTable from '@/components/DataTable/index.vue' | |||||
import AssignModal from './components/AssignModal.vue' | |||||
import QuestionDrawer from './components/QuestionDrawer.vue' | |||||
import { reactive, unref, toRefs, onUnmounted } from 'vue' | |||||
import { getOrderList } from '@/api/order/index.js' | |||||
export default { | |||||
name: 'TaskAll', | |||||
components: { HeadSearch, DataTable, AssignModal, QuestionDrawer }, | |||||
setup() { | |||||
const data = reactive({ | |||||
search, | |||||
...toRefs(table) | |||||
}) | |||||
/** | |||||
* @description: 加载表格数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadDataTable = async(res) => { | |||||
const _params = { | |||||
...unref(data.searchParams), | |||||
...res | |||||
} | |||||
return await getOrderList(_params) | |||||
} | |||||
onUnmounted(() => { | |||||
data.searchParams = null | |||||
}) | |||||
return { | |||||
...toRefs(data), | |||||
loadDataTable | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
</style> |
import { ref, reactive } from 'vue' | |||||
import { getUserList } from '@/api/system/user/index' | |||||
const userOptions = ref() | |||||
export const form = reactive({ | |||||
assignForm: { | |||||
handleUserList: [] | |||||
}, | |||||
assignRules: { | |||||
handleUserList: [{ required: true, type: 'array', message: '请选择分配用户', trigger: 'blur' }] | |||||
}, | |||||
formItem: [ | |||||
{ type: 'select', key: 'handleUserList', label: '人员姓名', props: { multiple: true, options: userOptions, placeholder: '请选择用户', labelField: 'realname', valueField: 'id' }} | |||||
] | |||||
}) | |||||
export const getUserOptions = async function() { | |||||
const res = await getUserList({ page: 1, limit: 100 }) | |||||
userOptions.value = res.data.records | |||||
} | |||||
import { reactive } from 'vue' | |||||
import { QUESTION_TYPE_ALL, QUES_STATUS } from '@/utils/dictionary.js' | |||||
export const search = reactive([ | |||||
{ | |||||
label: '问题类型', | |||||
key: 'questionType', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择问题类型', | |||||
options: QUESTION_TYPE_ALL | |||||
} | |||||
}, | |||||
{ | |||||
label: '问题状态', | |||||
key: 'status', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择问题状态', | |||||
options: [ | |||||
{ label: '全部', value: 'all' }, | |||||
...QUES_STATUS | |||||
] | |||||
} | |||||
} | |||||
]) |
import { QUESTION_TYPE, QUES_STATUS } from '@/utils/dictionary.js' | |||||
import TableImage from '@/components/DataTable/tools/Image.vue' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||||
import { h, ref, reactive } from 'vue' | |||||
/* 注册table */ | |||||
const tableRef = ref() | |||||
const searchParams = ref() | |||||
function handleSearch(params) { | |||||
searchParams.value = { ...params } | |||||
if (params?.time?.length) { | |||||
searchParams.value = { | |||||
...params, | |||||
startTime: params.time[0], | |||||
endTime: params.time[1] | |||||
} | |||||
} | |||||
delete searchParams.value.time | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
/* 位置 */ | |||||
function handlePositionDrawer(row) { | |||||
data.rowData = row | |||||
data.mapDrawer = true | |||||
} | |||||
function handleImgPreview(row) { | |||||
data.rowData = row | |||||
data.previewModal = true | |||||
} | |||||
const data = reactive({ | |||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | |||||
mapDrawer: false, | |||||
previewModal: false, | |||||
handleSearch, | |||||
columns: [ | |||||
{ | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '问题类型', | |||||
key: 'questionName', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '问题图片', | |||||
key: 'fileMarkerUrl', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableImage, { | |||||
images: { | |||||
width: 36, | |||||
height: 36, | |||||
src: row.fileMarkerUrl, | |||||
previewDisabled: true, | |||||
onClick: handleImgPreview.bind(null, row) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '经纬度', | |||||
key: 'name', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: [{ name: row.lng }, { name: row.lat }] | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '位置', | |||||
key: 'position', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '图片位置', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handlePositionDrawer.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '问题状态', | |||||
key: 'status', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.status, | |||||
filters: QUES_STATUS | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '处理人员', | |||||
key: 'handlerUserName', | |||||
align: 'center', | |||||
width: 100 | |||||
}, | |||||
{ | |||||
title: '处理时间', | |||||
key: 'handlerTime', | |||||
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 | |||||
} | |||||
] | |||||
}) | |||||
export default data |
import { reactive } from 'vue' | |||||
import { ORDER_STATUS2 } from '@/utils/dictionary.js' | |||||
export const search = reactive([ | |||||
{ | |||||
label: '工单编号', | |||||
key: 'reportNo', | |||||
props: { | |||||
placeholder: '请输入工单编号' | |||||
} | |||||
}, | |||||
{ | |||||
label: '工单分配状态', | |||||
key: 'status', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择工单分配状态', | |||||
options: ORDER_STATUS2 | |||||
} | |||||
}, | |||||
{ | |||||
label: '工单生成时间', | |||||
key: 'time', | |||||
type: 'date', | |||||
value: null, | |||||
props: { | |||||
type: 'daterange', | |||||
valueFormat: 'yyyy-MM-dd', | |||||
format: 'yyyy-MM-dd' | |||||
} | |||||
} | |||||
]) |
import { ORDER_STATUS } from '@/utils/dictionary.js' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||||
import { h, ref, reactive } from 'vue' | |||||
/* 注册table */ | |||||
const tableRef = ref() | |||||
const searchParams = ref() | |||||
function handleSearch(params) { | |||||
console.log(params) | |||||
searchParams.value = { ...params } | |||||
if (params?.time?.length) { | |||||
searchParams.value = { | |||||
...params, | |||||
createStartTime: params.time[0], | |||||
createEndTime: params.time[1] | |||||
} | |||||
} | |||||
delete searchParams.value.time | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
/** | |||||
* @description: 获取数据及操作 | |||||
* @param {*} row 单行数据 | |||||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||||
* @return {*} | |||||
*/ | |||||
function handleAssign(row) { | |||||
data.rowData = row | |||||
data.modalShow = true | |||||
} | |||||
function handleDetail(row) { | |||||
data.rowData = row | |||||
data.detailDrawer = true | |||||
} | |||||
const data = reactive({ | |||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | |||||
modalShow: false, | |||||
detailDrawer: false, | |||||
handleSearch, | |||||
columns: [ | |||||
{ | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '工单编号', | |||||
key: 'code', | |||||
align: 'center', | |||||
width: 250 | |||||
}, | |||||
{ | |||||
title: '问题总数', | |||||
key: 'questionTotal', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '未处理问题数', | |||||
key: 'unhandledTotal', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '工单分配状态', | |||||
key: 'status', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.status, | |||||
filters: ORDER_STATUS | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '工单生成时间', | |||||
key: 'createTime', | |||||
align: 'center', | |||||
width: 200 | |||||
}, | |||||
{ | |||||
title: '工单完成时间', | |||||
key: 'finishTime', | |||||
align: 'center', | |||||
width: 200 | |||||
}, | |||||
{ | |||||
title: '处理人员', | |||||
key: 'assignUserName', | |||||
align: 'center', | |||||
width: 200 | |||||
}, | |||||
{ | |||||
title: '操作', | |||||
align: 'center', | |||||
width: 150, | |||||
fixed: 'right', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '分配', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleAssign.bind(null, row) | |||||
}, | |||||
auth: 'basic_list', | |||||
hidden: row.status !== 5 | |||||
}, | |||||
{ | |||||
label: '详情', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleDetail.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
} | |||||
] | |||||
}) | |||||
export default data |
<template> | |||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||||
<n-drawer-content closable title="图片位置"> | |||||
<PositionMsg :data="getPostionOptions" :show-legend="false" /> | |||||
</n-drawer-content> | |||||
</n-drawer> | |||||
</template> | |||||
<script> | |||||
import PositionMsg from '@/components/PositionMsg/index.vue' | |||||
import { defineComponent, computed, reactive, toRefs } from 'vue' | |||||
export default defineComponent({ | |||||
name: 'LiveDrawer', | |||||
components: { PositionMsg }, | |||||
props: { | |||||
/* 可见 */ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
}) | |||||
/* 获取抽屉的信息 */ | |||||
const getDrawerOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
width: '100%', | |||||
placement: 'right' | |||||
} | |||||
}) | |||||
const getPostionOptions = computed(() => { | |||||
return [props.data] | |||||
}) | |||||
function handleDrawerColse() { | |||||
emit('update:visible', false) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
getDrawerOptions, | |||||
getPostionOptions, | |||||
handleDrawerColse | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.n-button+.n-button{ | |||||
margin-left: 30px; | |||||
} | |||||
</style> |
<template> | |||||
<Modal | |||||
:options="getModalOptions" | |||||
:on-close="handleClose" | |||||
> | |||||
<template #Context> | |||||
<div class="modal-form"> | |||||
<label>问题类型</label> | |||||
{{ getQuestionType }} | |||||
</div> | |||||
<div class="carousel__flex"> | |||||
<n-icon size="26" color="#8A8A8A"> | |||||
<LeftOutlined @click="handleCarousel('prev')" /> | |||||
</n-icon> | |||||
<div class="carousel__container"> | |||||
<label>问题图片</label> | |||||
<n-carousel ref="carouselRef" :default-index="selectIndex" :show-dots="false"> | |||||
<img | |||||
v-for="item in getCarouselInfo" | |||||
:key="item.id" | |||||
class="carousel-img" | |||||
:src="item.fileMarkerUrl" | |||||
> | |||||
</n-carousel> | |||||
</div> | |||||
<n-icon size="26" color="#8A8A8A"> | |||||
<RightOutlined @click="handleCarousel('next')" /> | |||||
</n-icon> | |||||
</div> | |||||
</template> | |||||
</Modal> | |||||
</template> | |||||
<script> | |||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
import { LeftOutlined, RightOutlined } from '@vicons/antd' | |||||
import Modal from '@/components/Modal/index.vue' | |||||
import { defineComponent, computed, ref, reactive, toRefs } from 'vue' | |||||
export default defineComponent({ | |||||
name: 'UserModal', | |||||
components: { Modal, LeftOutlined, RightOutlined }, | |||||
props: { | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: () => null | |||||
}, | |||||
selectRow: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const formRef = ref() | |||||
const data = reactive({ | |||||
selectRow: props.selectRow, | |||||
selectIndex: props.data.findIndex((item) => { return item.id === props.selectRow.id }), | |||||
selectType: props.selectRow.type | |||||
}) | |||||
/* 获取弹窗的属性 */ | |||||
const getModalOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
title: '图片详情', | |||||
width: 700 | |||||
} | |||||
}) | |||||
const getCarouselInfo = computed(() => { | |||||
return props.data | |||||
}) | |||||
const getQuestionType = computed(() => { | |||||
const row = QUESTION_TYPE.value.find((item) => { return item.value === data.selectRow.type }) | |||||
return row?.label || '-' | |||||
}) | |||||
const carouselRef = ref(null) | |||||
function handleCarousel(type) { | |||||
const currentIndex = carouselRef.value.getCurrentIndex() | |||||
switch (type) { | |||||
case 'prev': | |||||
if (currentIndex !== 0) { | |||||
carouselRef.value.prev() | |||||
data.selectRow = props.data[currentIndex - 1] | |||||
data.selectType = props.data[currentIndex - 1].type | |||||
} | |||||
break | |||||
case 'next': | |||||
if (currentIndex !== props.data.length - 1) { | |||||
carouselRef.value.next() | |||||
data.selectRow = props.data[currentIndex + 1] | |||||
data.selectType = props.data[currentIndex + 1].type | |||||
} | |||||
break | |||||
} | |||||
} | |||||
/* 关闭弹窗 */ | |||||
const handleClose = () => { | |||||
emit('update:visible', false) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
formRef, | |||||
getModalOptions, | |||||
getQuestionType, | |||||
getCarouselInfo, | |||||
carouselRef, | |||||
handleCarousel, | |||||
handleClose | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.carousel__flex{ | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
margin-bottom: 20px; | |||||
.carousel__container{ | |||||
width: calc(100% - 100px); | |||||
display: flex; | |||||
margin-right: 40px; | |||||
label{ | |||||
width: 70px; | |||||
flex-shrink: 0; | |||||
} | |||||
} | |||||
.n-icon{ | |||||
cursor: pointer; | |||||
} | |||||
.carousel-img{ | |||||
width: 100%; | |||||
height: 280px; | |||||
object-fit: cover | |||||
} | |||||
} | |||||
.modal-form{ | |||||
width: calc(100% - 60px); | |||||
display: flex; | |||||
align-items: center; | |||||
margin: 20px auto 20px; | |||||
label{ | |||||
width: 70px; | |||||
flex-shrink: 0; | |||||
} | |||||
.n-select{ | |||||
width: 300px; | |||||
} | |||||
} | |||||
</style> |
<template> | |||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||||
<n-drawer-content closable title="问题列表"> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<DataTable | |||||
ref="tableRef" | |||||
:columns="columns" | |||||
:row-key="(row) => row.id" | |||||
:request="loadDataTable" | |||||
size="large" | |||||
@fetch-success="getTableData" | |||||
/> | |||||
<MapDrawer v-model:visible="mapDrawer" :data="rowData" /> | |||||
<PreviewModal v-if="previewModal" v-model:visible="previewModal" :data="pageData" :select-row="rowData" /> | |||||
<QuestionModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :order-id="orderId" :data="rowData" @reload="handleSearch" /> | |||||
</n-drawer-content> | |||||
</n-drawer> | |||||
</template> | |||||
<script> | |||||
import table from '../tools/quesTable.js' | |||||
import { search } from '../tools/quesSearch.js' | |||||
import HeadSearch from '@/components/Search/index.vue' | |||||
import DataTable from '@/components/DataTable/index.vue' | |||||
import { defineComponent, reactive, unref, toRefs, computed, watch } from 'vue' | |||||
import MapDrawer from './MapDrawer.vue' | |||||
import QuestionModal from './QuestionModal.vue' | |||||
import PreviewModal from './PreviewModal.vue' | |||||
import { getOrderQuesList } from '@/api/order/index.js' | |||||
export default defineComponent({ | |||||
name: 'LiveDrawer', | |||||
components: { HeadSearch, DataTable, MapDrawer, QuestionModal, PreviewModal }, | |||||
props: { | |||||
/* 可见 */ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
search, | |||||
...toRefs(table), | |||||
orderId: null, | |||||
pageData: [] | |||||
}) | |||||
/* 获取抽屉的信息 */ | |||||
const getDrawerOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
width: '100%', | |||||
placement: 'right' | |||||
} | |||||
}) | |||||
/* 关闭抽屉 */ | |||||
function handleDrawerColse() { | |||||
emit('update:visible', false) | |||||
} | |||||
watch(() => [props.visible, props.data], | |||||
([val1, val2]) => { | |||||
if (val1 && val2.id) { | |||||
data.orderId = val2.id | |||||
} | |||||
}) | |||||
const loadDataTable = async(res) => { | |||||
const _params = { | |||||
...unref(data.searchParams), | |||||
workOrderId: props.data.id, | |||||
...res | |||||
} | |||||
if (_params.questionType === 'all') _params.questionType = null | |||||
if (_params.status === 'all') _params.status = null | |||||
return await getOrderQuesList(_params) | |||||
} | |||||
function getTableData(list) { | |||||
data.pageData = list.items | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
getDrawerOptions, | |||||
handleDrawerColse, | |||||
loadDataTable, | |||||
getTableData | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.report__container{ | |||||
width: 900px; | |||||
margin: 0 auto 40px auto; | |||||
.report__item{ | |||||
margin-bottom: 40px; | |||||
.report__item--title{ | |||||
font-size: 18px; | |||||
color: #333333; | |||||
line-height: 44px; | |||||
} | |||||
.n-grid{ | |||||
border-top: 1px solid rgba(216, 216, 216, 1); | |||||
border-left: 1px solid rgba(216, 216, 216, 1); | |||||
>div{ | |||||
position: relative; | |||||
text-align: center; | |||||
font-size: 14px; | |||||
color: #333333; | |||||
line-height: 20px; | |||||
padding: 6px 12px; | |||||
word-wrap: break-word; | |||||
word-break: normal; | |||||
border-right: 1px solid rgba(216, 216, 216, 1); | |||||
border-bottom: 1px solid rgba(216, 216, 216, 1); | |||||
&:nth-child(2n-1){ | |||||
span{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 50%; | |||||
transform: translate(-50%,-50%); | |||||
} | |||||
background: rgba(228, 231, 237, 1); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.report__operate{ | |||||
text-align: center; | |||||
} | |||||
} | |||||
::v-deep(.n-image){ | |||||
width: 100%; | |||||
img{ | |||||
width: 100%; | |||||
} | |||||
} | |||||
</style> |
<template> | |||||
<Modal | |||||
:options="getModalOptions" | |||||
:on-positive-click="handleConfirm" | |||||
: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' | |||||
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 { | |||||
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 handleClose = () => { | |||||
emit('update:visible', false) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
formRef, | |||||
getModalOptions, | |||||
getFormOptions, | |||||
ossRefs, | |||||
handleUploadStatus, | |||||
handleConfirm, | |||||
handleClose | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
</style> |
<template> | |||||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||||
<n-drawer-content closable title="报告详情"> | |||||
<div class="report__container"> | |||||
<div class="report__item"> | |||||
<p class="report__item--title">林场信息</p> | |||||
<div> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>责任单位</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.company }}</span></n-gi> | |||||
<n-gi><span>林场名称</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.lcName }}</span></n-gi> | |||||
<n-gi><span>巡查里程</span></n-gi> | |||||
<n-gi><span>{{ reportDetail?.mission?.mileage / 1000 }}公里</span></n-gi> | |||||
</n-grid> | |||||
</div> | |||||
</div> | |||||
<div class="report__item"> | |||||
<p class="report__item--title">巡检信息</p> | |||||
<div> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>气象信息</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.airWeather || '-' }}</span></n-gi> | |||||
<n-gi><span>巡检方式</span></n-gi> | |||||
<n-gi><span>{{ taskType[reportDetail.mission?.inspectionType] }}</span></n-gi> | |||||
<n-gi><span>巡检设备</span></n-gi> | |||||
<n-gi><span>{{ reportDetail?.mission?.droneName }}</span></n-gi> | |||||
<n-gi><span>巡检开始时间</span></n-gi> | |||||
<n-gi><span>{{ reportDetail?.mission?.executionStartTime }}</span></n-gi> | |||||
<n-gi><span>巡检结束时间</span></n-gi> | |||||
<n-gi><span>{{ reportDetail?.mission?.executionEndTime }}</span></n-gi> | |||||
<n-gi><span>问题数量</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.questionCount }}</span></n-gi> | |||||
</n-grid> | |||||
</div> | |||||
</div> | |||||
<div class="report__item"> | |||||
<p class="report__item--title">巡检结果</p> | |||||
<div> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>巡检内容</span></n-gi> | |||||
<n-gi><span>巡检检查结果</span></n-gi> | |||||
<template v-for="(item,index) in problemsList" :key="index"> | |||||
<n-gi><span>{{ item.label }}</span></n-gi> | |||||
<n-gi><span>{{ item.value }}</span></n-gi> | |||||
</template> | |||||
</n-grid> | |||||
</div> | |||||
</div> | |||||
<div v-if="reportDetail.questionCount>0" class="report__item"> | |||||
<p class="report__item--title">问题清单</p> | |||||
<!-- <n-image-group> --> | |||||
<div v-for="(item,index) in reportDetail.questionReportList" :key="index"> | |||||
<p>问题{{ index + 1 }}</p> | |||||
<n-grid :cols="2"> | |||||
<n-gi><span>坐标</span></n-gi> | |||||
<n-gi><span>{{ item.lng }},{{ item.lat }}</span></n-gi> | |||||
<n-gi><span>问题描述</span></n-gi> | |||||
<n-gi><span>{{ item.questionDesc ? item.questionDesc : '-' }}</span></n-gi> | |||||
<n-gi><span>问题图片</span></n-gi> | |||||
<n-gi><n-image :src="item.fileMarkerUrl" /></n-gi> | |||||
</n-grid> | |||||
</div> | |||||
<!-- </n-image-group> --> | |||||
</div> | |||||
<div class="report__operate"> | |||||
<n-button type="primary" @click="handleDownload">下载</n-button> | |||||
</div> | |||||
</div> | |||||
</n-drawer-content> | |||||
</n-drawer> | |||||
</template> | |||||
<script> | |||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
import { getReportDetail, reportDownload } from '@/api/report/index.js' | |||||
import { defineComponent, reactive, toRefs, computed, watch } from 'vue' | |||||
export default defineComponent({ | |||||
name: 'LiveDrawer', | |||||
props: { | |||||
/* 可见 */ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
'update:visible': null | |||||
}, | |||||
setup(props, { emit }) { | |||||
const data = reactive({ | |||||
reportDetail: {}, | |||||
problemsList: [], | |||||
taskType: { | |||||
1: '日常巡检', | |||||
2: '应急巡检' | |||||
} | |||||
}) | |||||
/* 获取抽屉的信息 */ | |||||
const getDrawerOptions = computed(() => { | |||||
return { | |||||
show: props.visible, | |||||
width: '100%', | |||||
placement: 'right' | |||||
} | |||||
}) | |||||
/* 关闭抽屉 */ | |||||
function handleDrawerColse() { | |||||
emit('update:visible', false) | |||||
} | |||||
watch(() => props.data, | |||||
(val) => { | |||||
if (val.id) { | |||||
getReportDetail(val.id) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
data.reportDetail = res.data | |||||
data.problemsList = [] | |||||
QUESTION_TYPE.value.forEach((item) => { | |||||
const obj = { | |||||
label: item.label, | |||||
value: 0 | |||||
} | |||||
res.data.questionTypeInfo.forEach((list) => { | |||||
if (item.code === list.type) { | |||||
obj.value = list.quantity | |||||
} | |||||
}) | |||||
data.problemsList.push(obj) | |||||
}) | |||||
// data.reportDetail.questionReportList.forEach((item, index) => { | |||||
// if (index === 0)item.fileMarkerUrl = 'https://image.t-aaron.com/XJRW20220720165837/2022-07-20-17-07-34_frame-6563-6720_type-%E6%B0%B4%E7%94%9F%E6%A4%8D%E8%A2%AB_o3MORSWHXz5pQ8F9_s-live-XJRW20220720165837-a0ec218ddd884ffcadd4f3c8fc27d825_AI.jpg' | |||||
// if (index === 1)item.fileMarkerUrl = 'https://image.t-aaron.com/XJRW20220720165837/2022-07-20-17-04-30_frame-1802-1920_type-%E6%B0%B4%E7%94%9F%E6%A4%8D%E8%A2%AB_b0N6GXoM178nUxhC_s-live-XJRW20220720165837-a0ec218ddd884ffcadd4f3c8fc27d825_AI.jpg' | |||||
// }) | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
function handleDownload() { | |||||
reportDownload(props.data.id) | |||||
.then((res) => { | |||||
const download = document.createElement('iframe') | |||||
download.src = res.data | |||||
download.style.display = 'none' | |||||
document.body.appendChild(download) | |||||
setTimeout(() => { | |||||
document.body.removeChild(download) | |||||
}, 300) | |||||
}) | |||||
} | |||||
return { | |||||
...toRefs(data), | |||||
getDrawerOptions, | |||||
handleDrawerColse, | |||||
handleDownload | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.report__container{ | |||||
width: 900px; | |||||
margin: 0 auto 40px auto; | |||||
.report__item{ | |||||
margin-bottom: 40px; | |||||
.report__item--title{ | |||||
font-size: 18px; | |||||
color: #333333; | |||||
line-height: 44px; | |||||
} | |||||
.n-grid{ | |||||
border-top: 1px solid rgba(216, 216, 216, 1); | |||||
border-left: 1px solid rgba(216, 216, 216, 1); | |||||
>div{ | |||||
position: relative; | |||||
text-align: center; | |||||
font-size: 14px; | |||||
color: #333333; | |||||
line-height: 20px; | |||||
padding: 6px 12px; | |||||
word-wrap: break-word; | |||||
word-break: normal; | |||||
border-right: 1px solid rgba(216, 216, 216, 1); | |||||
border-bottom: 1px solid rgba(216, 216, 216, 1); | |||||
&:nth-child(2n-1){ | |||||
span{ | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 50%; | |||||
transform: translate(-50%,-50%); | |||||
} | |||||
background: rgba(228, 231, 237, 1); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.report__operate{ | |||||
text-align: center; | |||||
} | |||||
} | |||||
::v-deep(.n-image){ | |||||
width: 100%; | |||||
img{ | |||||
width: 100%; | |||||
} | |||||
} | |||||
</style> |
<template> | |||||
<div> | |||||
<n-card> | |||||
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||||
<DataTable | |||||
ref="tableRef" | |||||
:columns="columns" | |||||
:row-key="(row) => row.id" | |||||
:request="loadDataTable" | |||||
size="large" | |||||
/> | |||||
</n-card> | |||||
</div> | |||||
<QuestionDrawer v-model:visible="detailDrawer" :data="rowData" /> | |||||
</template> | |||||
<script> | |||||
import table from './tools/table.js' | |||||
import { search } from './tools/search.js' | |||||
import HeadSearch from '@/components/Search/index.vue' | |||||
import DataTable from '@/components/DataTable/index.vue' | |||||
import QuestionDrawer from './components/QuestionDrawer.vue' | |||||
import { reactive, unref, toRefs, onUnmounted } from 'vue' | |||||
import { getOrderList } from '@/api/order/index.js' | |||||
export default { | |||||
name: 'TaskAll', | |||||
components: { HeadSearch, DataTable, QuestionDrawer }, | |||||
setup() { | |||||
const data = reactive({ | |||||
search, | |||||
...toRefs(table) | |||||
}) | |||||
/** | |||||
* @description: 加载表格数据 | |||||
* @param {*} res | |||||
* @return {*} | |||||
*/ | |||||
const loadDataTable = async(res) => { | |||||
const _params = { | |||||
...unref(data.searchParams), | |||||
...res | |||||
} | |||||
return await getOrderList(_params) | |||||
} | |||||
onUnmounted(() => { | |||||
data.searchParams = null | |||||
}) | |||||
return { | |||||
...toRefs(data), | |||||
loadDataTable | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
</style> |
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: 'oss', refIndex: 0, key: 'imageStatus', file: 'handlerImage', label: '封面', mode: true }, | |||||
{ type: 'input', key: 'handlerResult', label: '描述', props: { type: 'textarea', maxlength: 255 }, mode: true } | |||||
] | |||||
}) | |||||
import { reactive } from 'vue' | |||||
import { QUESTION_TYPE_ALL, QUES_STATUS } from '@/utils/dictionary.js' | |||||
export const search = reactive([ | |||||
{ | |||||
label: '问题类型', | |||||
key: 'questionType', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择问题类型', | |||||
options: QUESTION_TYPE_ALL | |||||
} | |||||
}, | |||||
{ | |||||
label: '问题状态', | |||||
key: 'status', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择问题状态', | |||||
options: [ | |||||
{ label: '全部', value: 'all' }, | |||||
...QUES_STATUS | |||||
] | |||||
} | |||||
} | |||||
]) |
import { QUESTION_TYPE, QUES_STATUS } from '@/utils/dictionary.js' | |||||
import TableImage from '@/components/DataTable/tools/Image.vue' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||||
import { h, ref, reactive } from 'vue' | |||||
/* 注册table */ | |||||
const tableRef = ref() | |||||
const searchParams = ref() | |||||
function handleSearch(params) { | |||||
searchParams.value = { ...params } | |||||
if (params?.time?.length) { | |||||
searchParams.value = { | |||||
...params, | |||||
startTime: params.time[0], | |||||
endTime: params.time[1] | |||||
} | |||||
} | |||||
delete searchParams.value.time | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
function handleDetail(row, type) { | |||||
data.rowData = row | |||||
data.modalType = type | |||||
data.modalShow = true | |||||
} | |||||
/* 位置 */ | |||||
function handlePositionDrawer(row) { | |||||
data.rowData = row | |||||
data.mapDrawer = true | |||||
} | |||||
function handleImgPreview(row) { | |||||
data.rowData = row | |||||
data.previewModal = true | |||||
} | |||||
const data = reactive({ | |||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | |||||
mapDrawer: false, | |||||
previewModal: false, | |||||
modalShow: false, | |||||
modalType: 'preview', | |||||
handleSearch, | |||||
columns: [ | |||||
{ | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '问题类型', | |||||
key: 'questionName', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '问题图片', | |||||
key: 'fileMarkerUrl', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableImage, { | |||||
images: { | |||||
width: 36, | |||||
height: 36, | |||||
src: row.fileMarkerUrl, | |||||
previewDisabled: true, | |||||
onClick: handleImgPreview.bind(null, row) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '经纬度', | |||||
key: 'name', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: [{ name: row.lng }, { name: row.lat }] | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '位置', | |||||
key: 'position', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '图片位置', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handlePositionDrawer.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '问题状态', | |||||
key: 'status', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.status, | |||||
filters: QUES_STATUS | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '处理人员', | |||||
key: 'handlerUserName', | |||||
align: 'center', | |||||
width: 100 | |||||
}, | |||||
{ | |||||
title: '处理时间', | |||||
key: 'handlerTime', | |||||
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: '操作', | |||||
align: 'center', | |||||
width: 150, | |||||
fixed: 'right', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '处理', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleDetail.bind(null, row, 'update') | |||||
}, | |||||
auth: 'basic_list', | |||||
hidden: row.status === 1 | |||||
}, | |||||
{ | |||||
label: '详情', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleDetail.bind(null, row, 'preview') | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
} | |||||
] | |||||
}) | |||||
export default data |
import { reactive } from 'vue' | |||||
import { ORDER_STATUS2 } from '@/utils/dictionary.js' | |||||
export const search = reactive([ | |||||
{ | |||||
label: '工单编号', | |||||
key: 'reportNo', | |||||
props: { | |||||
placeholder: '请输入工单编号' | |||||
} | |||||
}, | |||||
{ | |||||
label: '工单分配状态', | |||||
key: 'status', | |||||
type: 'select', | |||||
props: { | |||||
placeholder: '请选择工单分配状态', | |||||
options: ORDER_STATUS2 | |||||
} | |||||
}, | |||||
{ | |||||
label: '工单生成时间', | |||||
key: 'time', | |||||
type: 'date', | |||||
value: null, | |||||
props: { | |||||
type: 'daterange', | |||||
valueFormat: 'yyyy-MM-dd', | |||||
format: 'yyyy-MM-dd' | |||||
} | |||||
} | |||||
]) |
import { ORDER_STATUS } from '@/utils/dictionary.js' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||||
import { h, ref, reactive } from 'vue' | |||||
/* 注册table */ | |||||
const tableRef = ref() | |||||
const searchParams = ref() | |||||
function handleSearch(params) { | |||||
console.log(params) | |||||
searchParams.value = { ...params } | |||||
if (params?.time?.length) { | |||||
searchParams.value = { | |||||
...params, | |||||
createStartTime: params.time[0], | |||||
createEndTime: params.time[1] | |||||
} | |||||
} | |||||
delete searchParams.value.time | |||||
tableRef.value.reFetch({ searchParams }) | |||||
} | |||||
/** | |||||
* @description: 获取数据及操作 | |||||
* @param {*} row 单行数据 | |||||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||||
* @return {*} | |||||
*/ | |||||
function handleAssign(row) { | |||||
data.rowData = row | |||||
data.modalShow = true | |||||
} | |||||
function handleDetail(row) { | |||||
data.rowData = row | |||||
data.detailDrawer = true | |||||
} | |||||
const data = reactive({ | |||||
tableRef, | |||||
searchParams, | |||||
rowData: {}, | |||||
modalShow: false, | |||||
detailDrawer: false, | |||||
handleSearch, | |||||
columns: [ | |||||
{ | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '工单编号', | |||||
key: 'code', | |||||
align: 'center', | |||||
width: 250 | |||||
}, | |||||
{ | |||||
title: '问题总数', | |||||
key: 'questionTotal', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '未处理问题数', | |||||
key: 'unhandledTotal', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '工单状态', | |||||
key: 'status', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.status, | |||||
filters: ORDER_STATUS | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '工单生成时间', | |||||
key: 'createTime', | |||||
align: 'center', | |||||
width: 200 | |||||
}, | |||||
{ | |||||
title: '工单完成时间', | |||||
key: 'finishTime', | |||||
align: 'center', | |||||
width: 200 | |||||
}, | |||||
{ | |||||
title: '处理人员', | |||||
key: 'assignUserName', | |||||
align: 'center', | |||||
width: 200 | |||||
}, | |||||
{ | |||||
title: '操作', | |||||
align: 'center', | |||||
width: 150, | |||||
fixed: 'right', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '工单问题', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleDetail.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
} | |||||
] | |||||
}) | |||||
export default data |
:request="loadDataTable" | :request="loadDataTable" | ||||
:row-key="(row) => row.id" | :row-key="(row) => row.id" | ||||
@fetch-success="getTableData" | @fetch-success="getTableData" | ||||
/> | |||||
@update:checked-row-keys="handleCheck" | |||||
> | |||||
<template #tableTitle> | |||||
<n-button type="primary" @click="handleOrder"> 生成工单 </n-button> | |||||
</template> | |||||
</DataTable> | |||||
</n-card> | </n-card> | ||||
</div> | </div> | ||||
import DataTable from '@/components/DataTable/index.vue' | import DataTable from '@/components/DataTable/index.vue' | ||||
import MapDrawer from './components/MapDrawer.vue' | import MapDrawer from './components/MapDrawer.vue' | ||||
import PreviewModal from './components/PreviewModal.vue' | import PreviewModal from './components/PreviewModal.vue' | ||||
import { reactive, unref, toRefs, onUnmounted } from 'vue' | |||||
import { reactive, ref, unref, toRefs, onUnmounted } from 'vue' | |||||
import { getQuestionList } from '@/api/task/index.js' | import { getQuestionList } from '@/api/task/index.js' | ||||
import { generateOrder } from '@/api/order/index.js' | |||||
export default { | export default { | ||||
name: 'QuestionList', | name: 'QuestionList', | ||||
data.pageData = list.items | data.pageData = list.items | ||||
} | } | ||||
// 选择表格数据 | |||||
const selectedIds = ref([]) | |||||
function handleCheck(rowKeys) { | |||||
selectedIds.value = rowKeys | |||||
} | |||||
const handleOrder = async() => { | |||||
if (selectedIds.value.length) { | |||||
const ids = selectedIds.value.join(',') | |||||
const res = await generateOrder(ids) | |||||
if (res.code === 0) { | |||||
selectedIds.value = [] | |||||
data.handleSearch() | |||||
} | |||||
} else { | |||||
$message.warning('请至少选中一条数据') | |||||
} | |||||
} | |||||
return { | return { | ||||
...toRefs(data), | ...toRefs(data), | ||||
loadDataTable, | loadDataTable, | ||||
getTableData, | getTableData, | ||||
handleModal | |||||
handleModal, | |||||
handleOrder, | |||||
handleCheck, | |||||
selectedIds | |||||
} | } | ||||
} | } | ||||
} | } |
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
import { QUESTION_TYPE, ORDER_STATUS, QUES_STATUS } from '@/utils/dictionary.js' | |||||
import TableImage from '@/components/DataTable/tools/Image.vue' | import TableImage from '@/components/DataTable/tools/Image.vue' | ||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | import TableTags from '@/components/DataTable/tools/Tags.vue' | ||||
import TableAction from '@/components/DataTable/tools/Action.vue' | import TableAction from '@/components/DataTable/tools/Action.vue' | ||||
tableRef.value.reFetch({ searchParams }) | tableRef.value.reFetch({ searchParams }) | ||||
} | } | ||||
function handlePreview(row) { | |||||
data.orderModal = true | |||||
data.rowData = row | |||||
} | |||||
/* 位置 */ | /* 位置 */ | ||||
function handlePositionDrawer(row) { | function handlePositionDrawer(row) { | ||||
data.rowData = row | data.rowData = row | ||||
tableRef, | tableRef, | ||||
searchParams, | searchParams, | ||||
rowData: {}, | rowData: {}, | ||||
orderModal: false, | |||||
mapDrawer: false, | mapDrawer: false, | ||||
previewModal: false, | previewModal: false, | ||||
handleSearch, | handleSearch, | ||||
columns: [ | columns: [ | ||||
{ | |||||
type: 'selection', | |||||
disabled(row) { | |||||
return row.wordOrderStatus === 1 | |||||
} | |||||
}, | |||||
{ | { | ||||
title: '序号', | title: '序号', | ||||
key: 'key', | key: 'key', | ||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
title: '备注', | |||||
key: 'note', | |||||
align: 'center' | |||||
title: '工单生成状态', | |||||
key: 'wordOrderStatus', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.wordOrderStatus, | |||||
filters: ORDER_STATUS | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '处理状态', | |||||
key: 'handleStatus', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.handleStatus, | |||||
filters: QUES_STATUS | |||||
}) | |||||
} | |||||
}, | |||||
{ | |||||
title: '操作', | |||||
align: 'center', | |||||
width: 150, | |||||
fixed: 'right', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '查看', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handlePreview.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
} | } | ||||
] | ] | ||||
}) | }) | ||||
<n-gi><span>{{ item.questionDesc ? item.questionDesc : '-' }}</span></n-gi> | <n-gi><span>{{ item.questionDesc ? item.questionDesc : '-' }}</span></n-gi> | ||||
<n-gi><span>问题图片</span></n-gi> | <n-gi><span>问题图片</span></n-gi> | ||||
<n-gi><n-image :src="item.fileMarkerUrl" /></n-gi> | <n-gi><n-image :src="item.fileMarkerUrl" /></n-gi> | ||||
<n-gi v-if="type === 'result' && item.questionHandleList"><span>处理结果</span></n-gi> | |||||
<n-gi v-if="type === 'result' && item.questionHandleList"><n-image v-for="(cItem,cIndex) in item.questionHandleList" :key="cIndex" :src="cItem.handlerImage" /></n-gi> | |||||
</n-grid> | </n-grid> | ||||
</div> | </div> | ||||
<!-- </n-image-group> --> | <!-- </n-image-group> --> | ||||
data: { | data: { | ||||
type: Object, | type: Object, | ||||
default: () => {} | default: () => {} | ||||
}, | |||||
type: { | |||||
type: String, | |||||
default: 'inspection' | |||||
} | } | ||||
}, | }, | ||||
emits: { | emits: { |
</n-card> | </n-card> | ||||
</div> | </div> | ||||
<ReportDrawer v-model:visible="detailDrawer" :data="rowData" /> | |||||
<ReportDrawer v-model:visible="detailDrawer" :type="detailType" :data="rowData" /> | |||||
</template> | </template> | ||||
onUnmounted(() => { | onUnmounted(() => { | ||||
data.searchParams = null | data.searchParams = null | ||||
data.detailDrawer = false | |||||
}) | }) | ||||
return { | return { |
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | * @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | ||||
* @return {*} | * @return {*} | ||||
*/ | */ | ||||
function getRowData(row) { | |||||
function getRowData(row, type) { | |||||
data.rowData = row | data.rowData = row | ||||
data.detailDrawer = true | data.detailDrawer = true | ||||
data.detailType = type | |||||
} | } | ||||
const data = reactive({ | const data = reactive({ | ||||
searchParams, | searchParams, | ||||
rowData: {}, | rowData: {}, | ||||
detailDrawer: false, | detailDrawer: false, | ||||
detailType: 'inspection', | |||||
handleSearch, | handleSearch, | ||||
columns: [ | columns: [ | ||||
props: { | props: { | ||||
type: 'primary', | type: 'primary', | ||||
text: true, | text: true, | ||||
onClick: getRowData.bind(null, row) | |||||
onClick: getRowData.bind(null, row, 'inspection') | |||||
}, | |||||
auth: 'basic_list' | |||||
}, | |||||
{ | |||||
label: '处理报告', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: getRowData.bind(null, row, 'result') | |||||
}, | }, | ||||
auth: 'basic_list' | auth: 'basic_list' | ||||
} | } |
{ type: 'input', key: 'permission', label: '权限标识', props: { maxlength: '20', placeholder: '请输入部门名称', disabled: menuType0, clearable: true }}, | { type: 'input', key: 'permission', label: '权限标识', props: { maxlength: '20', placeholder: '请输入部门名称', disabled: menuType0, clearable: true }}, | ||||
{ type: 'input', key: 'path', label: '路由地址', props: { maxlength: '20', placeholder: '请输入部门名称', disabled: menuType1, clearable: true }}, | { type: 'input', key: 'path', label: '路由地址', props: { maxlength: '20', placeholder: '请输入部门名称', disabled: menuType1, clearable: true }}, | ||||
{ type: 'number', key: 'sort', label: '排序号', props: { min: 0, placeholder: '请输入排序号', clearable: true }}, | { type: 'number', key: 'sort', label: '排序号', props: { min: 0, placeholder: '请输入排序号', clearable: true }}, | ||||
{ type: 'input', key: 'component', label: '组件路径', props: { maxlength: '20', placeholder: '请输入部门名称', disabled: menuType1, clearable: true }}, | |||||
{ type: 'input', key: 'component', label: '组件路径', props: { maxlength: '200', placeholder: '请输入部门名称', disabled: menuType1, clearable: true }}, | |||||
{ type: 'radio', key: 'hide', label: '是否可见', options: MENU_VISIBLE }, | { type: 'radio', key: 'hide', label: '是否可见', options: MENU_VISIBLE }, | ||||
{ type: 'radio', key: 'status', label: '菜单状态', options: MENU_STATUS } | { type: 'radio', key: 'status', label: '菜单状态', options: MENU_STATUS } | ||||
] | ] |
}) | }) | ||||
} | } | ||||
}, | }, | ||||
{ | |||||
title: '工单生成状态', | |||||
key: 'status', | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.status, | |||||
filters: QUESTION_STATUS | |||||
}) | |||||
} | |||||
}, | |||||
{ | { | ||||
title: '操作', | title: '操作', | ||||
align: 'center', | align: 'center', |