VITE_APP_USE_MOCK = false | VITE_APP_USE_MOCK = false | ||||
# proxy | # proxy | ||||
VITE_PROXY = [["/api","http://192.168.11.241:9011/api"]] | |||||
VITE_PROXY = [["/api","http://192.168.11.11:9099/api"]] | |||||
# base api | # base api | ||||
VITE_APP_GLOB_BASE_API = '/api' | VITE_APP_GLOB_BASE_API = '/api' |
params | params | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* @description: 获取问题类型 | |||||
* @return {*} | |||||
*/ | |||||
export function getQuestionType(params) { | |||||
return request({ | |||||
url: '/question/type', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | /** | ||||
* @description: 问题确认/忽略 | * @description: 问题确认/忽略 |
<n-input v-if="['input'].includes(item.type) || !item.type" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" /> | <n-input v-if="['input'].includes(item.type) || !item.type" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" /> | ||||
<n-select v-if="['select'].includes(item.type)" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" /> | <n-select v-if="['select'].includes(item.type)" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" /> | ||||
<AreaCascader v-if="['area'].includes(item.type)" :ref="el=>{itemRefs[item.refIndex] = el}" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" @selectd="handleSelect" /> | <AreaCascader v-if="['area'].includes(item.type)" :ref="el=>{itemRefs[item.refIndex] = el}" v-model:value="getFormOptions.form[item.key]" v-bind="item.props" @selectd="handleSelect" /> | ||||
<n-date-picker v-if="['date'].includes(item.type)" v-model="getFormOptions.form[item.key]" v-bind="item.props" /> | |||||
<n-date-picker v-if="['date'].includes(item.type)" v-model:formatted-value="getFormOptions.form[item.key]" v-bind="item.props" /> | |||||
</n-form-item> | </n-form-item> | ||||
</template> | </template> | ||||
<n-form-item class="form__button"> | <n-form-item class="form__button"> |
<div class="user_msg"> | <div class="user_msg"> | ||||
<n-image | <n-image | ||||
class="user_avatar" | class="user_avatar" | ||||
:src="userInfo.avatar" | |||||
:src="getUserInfo.avatar" | |||||
preview-disabled | preview-disabled | ||||
/> | /> | ||||
<span class="user_name">{{ userInfo.realname }}</span> | |||||
<span class="user_name">{{ getUserInfo.realname }}</span> | |||||
</div> | </div> | ||||
</n-dropdown> | </n-dropdown> | ||||
</n-layout-header> | </n-layout-header> | ||||
key: 'out', | key: 'out', | ||||
icon: renderIcon(LogoutOutlined) | icon: renderIcon(LogoutOutlined) | ||||
} | } | ||||
], | |||||
userInfo: { | |||||
avatar: '', | |||||
realname: '管理员' | |||||
} | |||||
] | |||||
}) | |||||
const getUserInfo = computed(() => { | |||||
return userStore.userInfo | |||||
}) | }) | ||||
const getLogoWidth = computed(() => { | const getLogoWidth = computed(() => { | ||||
return { | return { | ||||
...toRefs(data), | ...toRefs(data), | ||||
getUserInfo, | |||||
getLogoWidth, | getLogoWidth, | ||||
handleSelect | handleSelect | ||||
} | } |
import { usePermissionStore } from './permission.js' | import { usePermissionStore } from './permission.js' | ||||
export const useUserStore = defineStore('user', { | export const useUserStore = defineStore('user', { | ||||
persist: true, | |||||
persist: { | |||||
enabled: true | |||||
}, | |||||
state() { | state() { | ||||
return { | return { | ||||
userInfo: {} | userInfo: {} |
label-placement="left" | label-placement="left" | ||||
> | > | ||||
<n-form-item label="机场选择:" path="airportId"> | <n-form-item label="机场选择:" path="airportId"> | ||||
<n-select v-model:value="videoForm.airportId" :options="airOptions" /> | |||||
<n-select v-model:value="videoForm.airportId" :options="airOptions" @update:value="handleAirportChange" /> | |||||
</n-form-item> | </n-form-item> | ||||
<n-form-item label="回放选择:" path="taskId"> | <n-form-item label="回放选择:" path="taskId"> | ||||
<n-select v-model:value="videoForm.taskId" :options="taskOptions" /> | |||||
<n-select v-model:value="videoForm.taskId" :options="taskOptions" @update:value="handleVideoChange" /> | |||||
</n-form-item> | </n-form-item> | ||||
</n-form> | </n-form> | ||||
</p> | </p> | ||||
<script> | <script> | ||||
import { dataToSelect } from '@/utils/handleData.js' | import { dataToSelect } from '@/utils/handleData.js' | ||||
import { airportList } from '@/api/dashboard/index.js' | import { airportList } from '@/api/dashboard/index.js' | ||||
import { getTaskList } from '@/api/task/index.js' | |||||
import VideoPlayer from '@/components/VideoPlayer/index.vue' | import VideoPlayer from '@/components/VideoPlayer/index.vue' | ||||
import { reactive, computed, toRefs } from 'vue' | import { reactive, computed, toRefs } from 'vue' | ||||
if (res.code === 0) { | if (res.code === 0) { | ||||
data.airOptionsAll = res.data | data.airOptionsAll = res.data | ||||
data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | data.airOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | ||||
data.videoForm.airportId = res.data[0].id | |||||
data.videoForm.airportId = res.data[0]?.id | |||||
if (res.data[0]?.id) { | |||||
loadTaskOption(res.data[0].id) | |||||
} | |||||
} | } | ||||
})() | })() | ||||
async function loadTaskOption(id) { | |||||
const res = await getTaskList({ page: 1, limit: 600, status: 4, airportId: id }) | |||||
if (res.code === 0) { | |||||
data.taskOptions = dataToSelect(res.data.records, { label: 'name', value: 'id' }) | |||||
} | |||||
} | |||||
function handleAirportChange(value) { | |||||
loadTaskOption(value) | |||||
} | |||||
function handleVideoChange(value) { | |||||
} | |||||
const getVideoOptions = computed(() => { | const getVideoOptions = computed(() => { | ||||
const row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | const row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | ||||
return { | return { | ||||
return { | return { | ||||
...toRefs(data), | ...toRefs(data), | ||||
loadAirport, | loadAirport, | ||||
handleAirportChange, | |||||
handleVideoChange, | |||||
getVideoOptions | getVideoOptions | ||||
} | } | ||||
} | } |
import HeadSearch from '@/components/Search/index.vue' | import HeadSearch from '@/components/Search/index.vue' | ||||
import DataTable from '@/components/DataTable/index.vue' | import DataTable from '@/components/DataTable/index.vue' | ||||
import { reactive, unref, toRefs } from 'vue' | import { reactive, unref, toRefs } from 'vue' | ||||
import { getTaskList } from '@/api/task/index.js' | |||||
import { getQuestionList } from '@/api/task/index.js' | |||||
export default { | export default { | ||||
name: 'TaskAll', | name: 'TaskAll', | ||||
const loadDataTable = async(res) => { | const loadDataTable = async(res) => { | ||||
const _params = { | const _params = { | ||||
...unref(data.searchParams), | ...unref(data.searchParams), | ||||
status: 1, | |||||
...res | ...res | ||||
} | } | ||||
return await getTaskList(_params) | |||||
return await getQuestionList(_params) | |||||
} | } | ||||
function handleModal() { | function handleModal() { |
const data = reactive([ | const data = reactive([ | ||||
{ | { | ||||
label: '选择时间', | label: '选择时间', | ||||
key: 'code', | |||||
key: 'time', | |||||
type: 'date', | type: 'date', | ||||
value: null, | |||||
props: { | props: { | ||||
type: 'daterange' | |||||
type: 'daterange', | |||||
valueFormat: 'yyyy-MM-dd HH:mm:ss', | |||||
format: 'yyyy-MM-dd HH:mm:ss' | |||||
} | } | ||||
}, | }, | ||||
{ | { |
import { TASK_MODE, TASK_TYPE, TASK_STATUS } from '@/utils/dictionary.js' | |||||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
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' | ||||
import { h, ref, reactive } from 'vue' | import { h, ref, reactive } from 'vue' | ||||
import { taskDelete } from '@/api/task/index.js' | |||||
/* 注册table */ | /* 注册table */ | ||||
const tableRef = ref() | const tableRef = ref() | ||||
function handleSearch(params) { | function handleSearch(params) { | ||||
searchParams.value = { ...params } | searchParams.value = { ...params } | ||||
if (params?.time?.length) { | |||||
searchParams.value = { | |||||
startTime: params.time[0], | |||||
endTime: params.time[1] | |||||
} | |||||
} | |||||
delete searchParams.value.time | |||||
tableRef.value.reFetch({ searchParams }) | tableRef.value.reFetch({ searchParams }) | ||||
} | } | ||||
/** | |||||
* @description: 获取数据及操作 | |||||
* @param {*} row 单行数据 | |||||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||||
* @return {*} | |||||
*/ | |||||
function getRowData(row, type) { | |||||
data.rowData = row | |||||
data.modalType = type | |||||
data.modalShow = true | |||||
} | |||||
function handleRowDelete(row) { | |||||
taskDelete(row.id) | |||||
.then(res => { | |||||
if (res.code === 0) { | |||||
handleSearch() | |||||
} | |||||
}) | |||||
} | |||||
function handleImplement(row) { | |||||
data.rowData = row | |||||
} | |||||
/* 直播 */ | |||||
function handleTaskLive(row) { | |||||
/* 位置 */ | |||||
function handlePositionDrawer(row) { | |||||
data.rowData = row | data.rowData = row | ||||
data.liveDrawer = true | |||||
} | |||||
/* 回放 */ | |||||
function handleTaskDemand(row) { | |||||
data.rowData = row | |||||
data.demandDrawer = true | |||||
} | |||||
/* 问题核实 */ | |||||
function handleTaskVerify(row) { | |||||
data.rowData = row | |||||
data.verifyDrawer = true | |||||
data.positionDrawer = true | |||||
} | } | ||||
const data = reactive({ | const data = reactive({ | ||||
tableRef, | tableRef, | ||||
searchParams, | searchParams, | ||||
rowData: {}, | rowData: {}, | ||||
modalType: 'create', | |||||
modalShow: false, | |||||
liveDrawer: false, | |||||
demandDrawer: false, | |||||
verifyDrawer: false, | |||||
positionDrawer: false, | |||||
handleSearch, | handleSearch, | ||||
columns: [ | columns: [ | ||||
{ | { | ||||
title: '任务标号', | |||||
key: 'code', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '任务名称', | |||||
key: 'name', | |||||
title: '序号', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | { | ||||
title: '巡检方式', | |||||
key: 'inspectionType', | |||||
title: '问题类型', | |||||
key: 'type', | |||||
align: 'center', | align: 'center', | ||||
render(row) { | render(row) { | ||||
return h(TableTags, { | return h(TableTags, { | ||||
data: row.inspectionType, | |||||
filters: TASK_MODE | |||||
data: row.type, | |||||
filters: QUESTION_TYPE | |||||
}) | }) | ||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
title: '巡检机场', | |||||
key: 'airportName', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '巡检路线', | |||||
key: 'inspectionLineName', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '任务类型', | |||||
key: 'type', | |||||
title: '问题图片', | |||||
key: 'fileMarkerUrl', | |||||
align: 'center', | align: 'center', | ||||
render(row) { | render(row) { | ||||
return h(TableTags, { | |||||
data: row.type, | |||||
filters: TASK_TYPE | |||||
return h(TableImage, { | |||||
images: { | |||||
width: 36, | |||||
height: 36, | |||||
src: row.fileMarkerUrl | |||||
// previewDisabled: true | |||||
// onClick: handleImgPreview.bind(null, row) | |||||
} | |||||
}) | }) | ||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
title: '巡检时间', | |||||
key: 'executionStartTime', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '状态', | |||||
key: 'status', | |||||
title: '经纬度', | |||||
key: 'name', | |||||
align: 'center', | align: 'center', | ||||
render(row) { | render(row) { | ||||
return h(TableTags, { | return h(TableTags, { | ||||
data: row.status, | |||||
filters: TASK_STATUS | |||||
data: [{ name: row.lng }, { name: row.lat }] | |||||
}) | }) | ||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
title: '操作', | |||||
title: '位置', | |||||
key: 'position', | |||||
align: 'center', | align: 'center', | ||||
width: 150, | |||||
fixed: 'right', | |||||
render(row) { | render(row) { | ||||
return h(TableAction, { | return h(TableAction, { | ||||
actions: [ | actions: [ | ||||
{ | { | ||||
label: '详情', | |||||
label: '图片位置', | |||||
type: 'button', | type: 'button', | ||||
props: { | props: { | ||||
type: 'primary', | type: 'primary', | ||||
text: true, | text: true, | ||||
onPositiveClick: getRowData.bind(null, row, 'preview') | |||||
onClick: handlePositionDrawer.bind(null, row) | |||||
}, | }, | ||||
auth: 'basic_list' | auth: 'basic_list' | ||||
}, | |||||
{ | |||||
label: '删除', | |||||
type: 'popconfirm', | |||||
tip: '是否删除该数据?', | |||||
props: { | |||||
onPositiveClick: handleRowDelete.bind(null, row) | |||||
}, | |||||
ButtonProps: { | |||||
text: true, | |||||
type: 'primary' | |||||
}, | |||||
auth: 'basic_list' | |||||
}, | |||||
{ | |||||
label: '立即执行', | |||||
type: 'popconfirm', | |||||
tip: '是否立即开始执行任务?', | |||||
props: { | |||||
onClick: handleImplement.bind(null, row) | |||||
}, | |||||
ButtonProps: { | |||||
text: true, | |||||
type: 'primary' | |||||
}, | |||||
auth: 'basic_list', | |||||
show: row.status === 1 | |||||
}, | |||||
{ | |||||
label: '直播', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleTaskLive.bind(null, row) | |||||
}, | |||||
auth: 'basic_list', | |||||
show: row.status === 2 | |||||
}, | |||||
{ | |||||
label: '轨迹', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleTaskDemand.bind(null, row) | |||||
}, | |||||
auth: 'basic_list', | |||||
show: row.status === 4 | |||||
}, | |||||
{ | |||||
label: '问题核实', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
text: true, | |||||
onClick: handleTaskVerify.bind(null, row) | |||||
}, | |||||
auth: 'basic_list', | |||||
show: row.status !== 1 | |||||
} | } | ||||
], | ], | ||||
align: 'center' | align: 'center' | ||||
}) | }) | ||||
} | } | ||||
}, | |||||
{ | |||||
title: '备注', | |||||
key: 'note', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '所属任务', | |||||
key: 'note', | |||||
align: 'center' | |||||
} | } | ||||
] | ] |
<n-gi><span>林场名称</span></n-gi> | <n-gi><span>林场名称</span></n-gi> | ||||
<n-gi><span>{{ reportDetail.lcName }}</span></n-gi> | <n-gi><span>{{ reportDetail.lcName }}</span></n-gi> | ||||
<n-gi><span>巡查里程</span></n-gi> | <n-gi><span>巡查里程</span></n-gi> | ||||
<n-gi><span>-</span></n-gi> | |||||
<n-gi><span>{{ reportDetail?.mission?.mileage/1000 }}公里</span></n-gi> | |||||
</n-grid> | </n-grid> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<n-gi><span>巡检结束时间</span></n-gi> | <n-gi><span>巡检结束时间</span></n-gi> | ||||
<n-gi><span>{{ reportDetail?.mission?.executionEndTime }}</span></n-gi> | <n-gi><span>{{ reportDetail?.mission?.executionEndTime }}</span></n-gi> | ||||
<n-gi><span>问题数量</span></n-gi> | <n-gi><span>问题数量</span></n-gi> | ||||
<n-gi><span>{{ questionNum }}</span></n-gi> | |||||
<n-gi><span>{{ reportDetail.questionCount }}</span></n-gi> | |||||
</n-grid> | </n-grid> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
const data = reactive({ | const data = reactive({ | ||||
reportDetail: {}, | reportDetail: {}, | ||||
weatherList: [], | weatherList: [], | ||||
questionNum: 0, | |||||
problemsNum: { | problemsNum: { | ||||
'type_1': 0, | 'type_1': 0, | ||||
'type_2': 0, | 'type_2': 0, | ||||
'type_3': 0, | 'type_3': 0, | ||||
'type_4': 0 | 'type_4': 0 | ||||
} | } | ||||
data.questionNum = res.data.questionReportList.length | |||||
res.data.questionTypeInfo.forEach((item) => { | res.data.questionTypeInfo.forEach((item) => { | ||||
const key = `type_${item.type}` | const key = `type_${item.type}` | ||||
data.problemsNum[key] = item.quantity | data.problemsNum[key] = item.quantity |
const loadDataTable = async(res) => { | const loadDataTable = async(res) => { | ||||
const _params = { | const _params = { | ||||
...unref(data.searchParams), | ...unref(data.searchParams), | ||||
missionId: props.data.id, | |||||
...res | ...res | ||||
} | } | ||||
if (_params.status === 'all') _params.status = '' | if (_params.status === 'all') _params.status = '' |
import { QUESTION_STATUS } from '@/utils/dictionary.js' | |||||
import { QUESTION_STATUS, QUESTION_TYPE } from '@/utils/dictionary.js' | |||||
import TableTags from '@/components/DataTable/tools/Tags.vue' | import TableTags from '@/components/DataTable/tools/Tags.vue' | ||||
import TableImage from '@/components/DataTable/tools/Image.vue' | import TableImage from '@/components/DataTable/tools/Image.vue' | ||||
import TableAction from '@/components/DataTable/tools/Action.vue' | import TableAction from '@/components/DataTable/tools/Action.vue' | ||||
}, | }, | ||||
{ | { | ||||
title: '序号', | title: '序号', | ||||
key: 'name', | |||||
key: 'key', | |||||
render: (_, index) => { | |||||
return `${index + 1}` | |||||
}, | |||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | { | ||||
title: '问题类型', | title: '问题类型', | ||||
key: 'questionName', | key: 'questionName', | ||||
align: 'center' | |||||
align: 'center', | |||||
render(row) { | |||||
return h(TableTags, { | |||||
data: row.type, | |||||
filters: QUESTION_TYPE | |||||
}) | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
title: '问题图片', | title: '问题图片', |