@@ -5,7 +5,7 @@ VITE_PUBLIC_PATH = '/' | |||
VITE_APP_USE_MOCK = false | |||
# proxy | |||
VITE_PROXY = [["/api","http://192.168.11.241:9011/api"]] | |||
VITE_PROXY = [["/api","http://192.168.11.11:9099/api"]] | |||
# base api | |||
VITE_APP_GLOB_BASE_API = '/api' |
@@ -72,6 +72,17 @@ export function getQuestionList(params) { | |||
params | |||
}) | |||
} | |||
/** | |||
* @description: 获取问题类型 | |||
* @return {*} | |||
*/ | |||
export function getQuestionType(params) { | |||
return request({ | |||
url: '/question/type', | |||
method: 'GET', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description: 问题确认/忽略 |
@@ -6,7 +6,7 @@ | |||
<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" /> | |||
<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> | |||
</template> | |||
<n-form-item class="form__button"> |
@@ -8,10 +8,10 @@ | |||
<div class="user_msg"> | |||
<n-image | |||
class="user_avatar" | |||
:src="userInfo.avatar" | |||
:src="getUserInfo.avatar" | |||
preview-disabled | |||
/> | |||
<span class="user_name">{{ userInfo.realname }}</span> | |||
<span class="user_name">{{ getUserInfo.realname }}</span> | |||
</div> | |||
</n-dropdown> | |||
</n-layout-header> | |||
@@ -43,11 +43,11 @@ export default defineComponent({ | |||
key: 'out', | |||
icon: renderIcon(LogoutOutlined) | |||
} | |||
], | |||
userInfo: { | |||
avatar: '', | |||
realname: '管理员' | |||
} | |||
] | |||
}) | |||
const getUserInfo = computed(() => { | |||
return userStore.userInfo | |||
}) | |||
const getLogoWidth = computed(() => { | |||
@@ -70,6 +70,7 @@ export default defineComponent({ | |||
return { | |||
...toRefs(data), | |||
getUserInfo, | |||
getLogoWidth, | |||
handleSelect | |||
} |
@@ -7,7 +7,9 @@ import { useTagsMenuStore } from './tagsMenu.js' | |||
import { usePermissionStore } from './permission.js' | |||
export const useUserStore = defineStore('user', { | |||
persist: true, | |||
persist: { | |||
enabled: true | |||
}, | |||
state() { | |||
return { | |||
userInfo: {} |
@@ -10,10 +10,10 @@ | |||
label-placement="left" | |||
> | |||
<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 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> | |||
</p> | |||
@@ -38,6 +38,7 @@ | |||
<script> | |||
import { dataToSelect } from '@/utils/handleData.js' | |||
import { airportList } from '@/api/dashboard/index.js' | |||
import { getTaskList } from '@/api/task/index.js' | |||
import VideoPlayer from '@/components/VideoPlayer/index.vue' | |||
import { reactive, computed, toRefs } from 'vue' | |||
@@ -66,10 +67,28 @@ export default { | |||
if (res.code === 0) { | |||
data.airOptionsAll = res.data | |||
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 row = data.airOptionsAll.find((item) => { return item.id === data.videoForm.airportId }) | |||
return { | |||
@@ -93,6 +112,8 @@ export default { | |||
return { | |||
...toRefs(data), | |||
loadAirport, | |||
handleAirportChange, | |||
handleVideoChange, | |||
getVideoOptions | |||
} | |||
} |
@@ -20,7 +20,7 @@ import search from './tools/search.js' | |||
import HeadSearch from '@/components/Search/index.vue' | |||
import DataTable from '@/components/DataTable/index.vue' | |||
import { reactive, unref, toRefs } from 'vue' | |||
import { getTaskList } from '@/api/task/index.js' | |||
import { getQuestionList } from '@/api/task/index.js' | |||
export default { | |||
name: 'TaskAll', | |||
@@ -39,9 +39,10 @@ export default { | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(data.searchParams), | |||
status: 1, | |||
...res | |||
} | |||
return await getTaskList(_params) | |||
return await getQuestionList(_params) | |||
} | |||
function handleModal() { |
@@ -3,10 +3,13 @@ import { reactive } from 'vue' | |||
const data = reactive([ | |||
{ | |||
label: '选择时间', | |||
key: 'code', | |||
key: 'time', | |||
type: 'date', | |||
value: null, | |||
props: { | |||
type: 'daterange' | |||
type: 'daterange', | |||
valueFormat: 'yyyy-MM-dd HH:mm:ss', | |||
format: 'yyyy-MM-dd HH:mm:ss' | |||
} | |||
}, | |||
{ |
@@ -1,8 +1,8 @@ | |||
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 TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { h, ref, reactive } from 'vue' | |||
import { taskDelete } from '@/api/task/index.js' | |||
/* 注册table */ | |||
const tableRef = ref() | |||
@@ -10,205 +10,106 @@ const searchParams = ref() | |||
function handleSearch(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 }) | |||
} | |||
/** | |||
* @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.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({ | |||
tableRef, | |||
searchParams, | |||
rowData: {}, | |||
modalType: 'create', | |||
modalShow: false, | |||
liveDrawer: false, | |||
demandDrawer: false, | |||
verifyDrawer: false, | |||
positionDrawer: false, | |||
handleSearch, | |||
columns: [ | |||
{ | |||
title: '任务标号', | |||
key: 'code', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '任务名称', | |||
key: 'name', | |||
title: '序号', | |||
key: 'key', | |||
render: (_, index) => { | |||
return `${index + 1}` | |||
}, | |||
align: 'center' | |||
}, | |||
{ | |||
title: '巡检方式', | |||
key: 'inspectionType', | |||
title: '问题类型', | |||
key: 'type', | |||
align: 'center', | |||
render(row) { | |||
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', | |||
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', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.status, | |||
filters: TASK_STATUS | |||
data: [{ name: row.lng }, { name: row.lat }] | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '操作', | |||
title: '位置', | |||
key: 'position', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '详情', | |||
label: '图片位置', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onPositiveClick: getRowData.bind(null, row, 'preview') | |||
onClick: handlePositionDrawer.bind(null, row) | |||
}, | |||
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' | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '备注', | |||
key: 'note', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '所属任务', | |||
key: 'note', | |||
align: 'center' | |||
} | |||
] |
@@ -11,7 +11,7 @@ | |||
<n-gi><span>林场名称</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>{{ reportDetail?.mission?.mileage/1000 }}公里</span></n-gi> | |||
</n-grid> | |||
</div> | |||
</div> | |||
@@ -30,7 +30,7 @@ | |||
<n-gi><span>巡检结束时间</span></n-gi> | |||
<n-gi><span>{{ reportDetail?.mission?.executionEndTime }}</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> | |||
</div> | |||
</div> | |||
@@ -100,7 +100,6 @@ export default defineComponent({ | |||
const data = reactive({ | |||
reportDetail: {}, | |||
weatherList: [], | |||
questionNum: 0, | |||
problemsNum: { | |||
'type_1': 0, | |||
'type_2': 0, | |||
@@ -142,7 +141,6 @@ export default defineComponent({ | |||
'type_3': 0, | |||
'type_4': 0 | |||
} | |||
data.questionNum = res.data.questionReportList.length | |||
res.data.questionTypeInfo.forEach((item) => { | |||
const key = `type_${item.type}` | |||
data.problemsNum[key] = item.quantity |
@@ -64,6 +64,7 @@ export default { | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(data.searchParams), | |||
missionId: props.data.id, | |||
...res | |||
} | |||
if (_params.status === 'all') _params.status = '' |
@@ -1,4 +1,4 @@ | |||
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 TableImage from '@/components/DataTable/tools/Image.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
@@ -73,13 +73,22 @@ const data = reactive({ | |||
}, | |||
{ | |||
title: '序号', | |||
key: 'name', | |||
key: 'key', | |||
render: (_, index) => { | |||
return `${index + 1}` | |||
}, | |||
align: 'center' | |||
}, | |||
{ | |||
title: '问题类型', | |||
key: 'questionName', | |||
align: 'center' | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.type, | |||
filters: QUESTION_TYPE | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '问题图片', |