391 lines
12 KiB
Vue
391 lines
12 KiB
Vue
<template>
|
|
<div class="p-2">
|
|
<PageHeader></PageHeader>
|
|
<div class="EditBody">
|
|
<div class="title">
|
|
<div>基本信息</div>
|
|
</div>
|
|
<div class="bodybox">
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" label-position="right">
|
|
<el-form-item label="巡检计划名称" prop="planName">
|
|
<el-input v-model="form.planName" placeholder="请输入"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="巡检人员" prop="inspectorIds">
|
|
<div class="inspectorIdsBox">
|
|
<div v-for="(item, index) in checkoutUserlist" :key="index" class="inspector_items">
|
|
<div class="name">{{ item.nickName }}</div>
|
|
<i @click="handleDelete" class="deleteaction">
|
|
<el-icon><Delete /></el-icon>
|
|
</i>
|
|
</div>
|
|
<RepairUser @change="handleUserChange" returnvalue="*" :is-multiple="true" user-type="inspection" ref="RepairUserRef">
|
|
<template #default>
|
|
<div @click="handleAddUser" class="inspector_items add flex flex-items-center justify-center">
|
|
<el-icon><Plus /></el-icon>
|
|
<span class="ml-10px"> 添加 </span>
|
|
</div>
|
|
</template>
|
|
</RepairUser>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item label="执行周期">
|
|
<el-date-picker
|
|
@update:model-value="handleTime"
|
|
v-model="taskDate"
|
|
type="daterange"
|
|
range-separator="到"
|
|
format="YYYY-MM-DD"
|
|
value-format="YYYY-MM-DD"
|
|
start-placeholder="开启日期"
|
|
end-placeholder="结束日期"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="任务时间">
|
|
<el-select v-model="form.taskTime" placeholder="选择任务时间段" style="width: 100%">
|
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
|
</el-select>
|
|
<div flex flex-wrap>
|
|
<div
|
|
class="week-items"
|
|
@click="checkoutWeekFun(item)"
|
|
:class="{
|
|
active: checkoutWeek.includes(item)
|
|
}"
|
|
v-for="(item, index) in 7"
|
|
:key="index"
|
|
>
|
|
<div class="iconbox">
|
|
<el-icon v-show="checkoutWeek.includes(item)"><Check /></el-icon>
|
|
</div>
|
|
<span class="ml-5px">{{ numToWeek(item) }}</span>
|
|
</div>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item label="提醒时间">
|
|
<el-select v-model="form.remindTime" placeholder="请选择" style="width: 100%">
|
|
<el-option v-for="item in remindTimeoptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="巡检设置">
|
|
<el-radio-group v-model="form.inspectSetting">
|
|
<el-radio label="必须拍照" value="1" />
|
|
<el-radio label="允许跳检" value="0" />
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
<el-form-item label="计划路线">
|
|
<el-select @change="handlChangeMap" v-model="form.routeIds" placeholder="请选择" style="width: 100%">
|
|
<el-option v-for="item in planlist" :key="item.value" :label="item.routeName" :value="item.id" />
|
|
</el-select>
|
|
<div class="mapbox" id="PlanMapBox"></div>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="submit">提交</el-button>
|
|
<el-button @click="routeback">返回</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { listRoute } from '@/api/system/InspectionRoute';
|
|
import RepairUser from '@/components/Holder/repairUser.vue';
|
|
import PageHeader from '@/components/Pageheader/index.vue';
|
|
import { numToWeek } from '@/utils/time';
|
|
import { Delete } from '@element-plus/icons-vue';
|
|
import { ref } from 'vue';
|
|
import AMapLoader from '@amap/amap-jsapi-loader';
|
|
import { addPlan, getPlan, updatePlan } from '@/api/system/InspectionPlan';
|
|
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
|
|
const form = ref({
|
|
id: null,
|
|
planName: '', // 巡检计划名称
|
|
inspectorIds: '', // 巡检人员
|
|
taskTime: '', // 任务时间段
|
|
executeCycle: '', // 执行周期
|
|
executeDay: '', // 执行周期具体的周几
|
|
remindTime: '', // 提醒时间
|
|
routeIds: '', // 计划路线id
|
|
inspectSetting: '1' // 巡检设置
|
|
});
|
|
const rules = ref({
|
|
planName: [{ required: true, message: '请输入巡检计划名称', trigger: 'blur' }],
|
|
inspectorIds: [{ required: true, message: '请选择巡检人员', trigger: 'blur' }],
|
|
executeCycle: [{ required: true, message: '请输入执行周期', trigger: 'blur' }],
|
|
routeIds: [{ required: true, message: '请选择路线', trigger: 'blur' }]
|
|
});
|
|
|
|
// 执行周期
|
|
const taskDateSplit = ' - ';
|
|
const taskDate = ref([]);
|
|
function handleTime(val: string[]) {
|
|
taskDate.value = val;
|
|
form.value.executeCycle = `${val[0]}${taskDateSplit}${val[1]}`;
|
|
}
|
|
// 选择周几
|
|
const checkoutWeek = ref([]);
|
|
function checkoutWeekFun(val: number) {
|
|
if (!checkoutWeek.value.includes(val)) {
|
|
checkoutWeek.value.push(val);
|
|
form.value.executeDay = checkoutWeek.value.join(',');
|
|
} else {
|
|
checkoutWeek.value = checkoutWeek.value.filter((item) => item !== val);
|
|
}
|
|
}
|
|
|
|
// 任务时间
|
|
const options = ref([
|
|
{
|
|
value: '09:00-11:00; 13:00-15:00',
|
|
label: '09:00-11:00; 13:00-15:00'
|
|
}
|
|
]);
|
|
// 提醒时间
|
|
const remindTimeoptions = ref([
|
|
{
|
|
value: 10,
|
|
label: '任务开始前10分钟'
|
|
},
|
|
{
|
|
value: 15,
|
|
label: '任务开始前15分钟'
|
|
},
|
|
{
|
|
value: 20,
|
|
label: '任务开始前30分钟'
|
|
}
|
|
]);
|
|
|
|
// 巡检计划id
|
|
const editid = ref(null);
|
|
|
|
// 初始化
|
|
// 路线列表
|
|
const planlist = ref([]);
|
|
async function init() {
|
|
const res = await listRoute();
|
|
planlist.value = res.rows;
|
|
if (route.query.id) {
|
|
editid.value = route.query.id;
|
|
getPlan(editid.value).then((res) => {
|
|
form.value = {
|
|
id: res.data.id,
|
|
planName: res.data.planName, // 巡检计划名称
|
|
inspectorIds: res.data.inspectorIds, // 巡检人员
|
|
taskTime: res.data.taskTime, // 任务时间段
|
|
executeCycle: res.data.executeCycle, // 执行周期
|
|
executeDay: res.data.executeDay, // 执行周期具体的周几
|
|
remindTime: res.data.remindTime, // 提醒时间
|
|
routeIds: res.data.routeIds, // 计划路线id
|
|
inspectSetting: String(res.data.inspectSetting) // 巡检设置
|
|
};
|
|
taskDate.value = res.data.executeCycle.split(taskDateSplit);
|
|
checkoutWeek.value = res.data.executeDay
|
|
.split(',')
|
|
.map((item) => Number(item))
|
|
.filter((item) => item);
|
|
|
|
handlChangeMap(res.data.routeIds);
|
|
});
|
|
}
|
|
}
|
|
|
|
init();
|
|
|
|
// 选择 巡检人员
|
|
const RepairUserRef = ref<InstanceType<typeof RepairUser>>();
|
|
function handleAddUser() {
|
|
RepairUserRef.value.open();
|
|
}
|
|
const checkoutUserlist = ref([]);
|
|
function handleUserChange(val) {
|
|
checkoutUserlist.value = val;
|
|
}
|
|
function handleDelete(id) {
|
|
checkoutUserlist.value = checkoutUserlist.value.filter((item) => item.userId !== id);
|
|
}
|
|
|
|
// 返回
|
|
function routeback() {
|
|
router.back();
|
|
}
|
|
|
|
const AMapLib = ref(null);
|
|
const map = ref(null);
|
|
const mapReady = ref(false);
|
|
|
|
const markerlist = [];
|
|
function handlChangeMap(val) {
|
|
map.value.remove(markerlist);
|
|
if (val) {
|
|
const find = planlist.value.find((item) => item.id === val);
|
|
if (find) {
|
|
if (find.points && find.points.length > 0) {
|
|
find.points.forEach((item, index) => {
|
|
const lnglat = item.location.split(',').map(Number);
|
|
const marker = new AMapLib.value.Marker({
|
|
position: new AMapLib.value.LngLat(lnglat[0], lnglat[1]), //经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
|
|
title: item.pointName,
|
|
content: `
|
|
<div style="display:flex;align-items:center;justify-content:center;width:30px;height:30px;line-height:18px;border-radius:50%;background-color:rgba(26,117,255,0.3);">
|
|
<div
|
|
style=" width: 20px;
|
|
border-radius: 50%;
|
|
height: 20px;
|
|
line-height: 20px;
|
|
background-color: rgba(26,117,255,1);
|
|
color: #ffffff;
|
|
font-size: 20px;
|
|
text-align: center;"
|
|
>${index + 1}</div>
|
|
</div>`
|
|
});
|
|
//将创建的点标记添加到已有的地图实例:
|
|
map.value.add(marker);
|
|
markerlist.push(marker);
|
|
});
|
|
}
|
|
if (find.pathPoints && typeof find.pathPoints === 'string') {
|
|
const path = JSON.parse(find.pathPoints);
|
|
console.log(path);
|
|
//创建 Polyline 实例
|
|
const polyline = new AMapLib.value.Polyline({
|
|
path: path,
|
|
strokeWeight: 2, //线条宽度
|
|
strokeColor: 'red', //线条颜色
|
|
lineJoin: 'round' //折线拐点连接处样式
|
|
});
|
|
map.value.add(polyline);
|
|
markerlist.push(polyline);
|
|
}
|
|
map.value.setFitView();
|
|
}
|
|
}
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await nextTick();
|
|
window._AMapSecurityConfig = { securityJsCode: '09534b3534d8da53968529a9ce164118' };
|
|
AMapLoader.load({
|
|
key: '8e302fe1be5f4db62bc734db23dca149',
|
|
version: '2.0',
|
|
plugins: ['AMap.Scale', 'AMap.Marker']
|
|
}).then(async (AMap) => {
|
|
AMapLib.value = AMap;
|
|
map.value = new AMap.Map('PlanMapBox', {
|
|
viewMode: '3D',
|
|
zoom: 11,
|
|
center: [116.397428, 39.90923]
|
|
});
|
|
mapReady.value = true;
|
|
});
|
|
});
|
|
const formRef = ref();
|
|
function submit() {
|
|
formRef.value?.validate(async (valid: boolean) => {
|
|
if (valid) {
|
|
form.value.inspectorIds = checkoutUserlist.value.map((item) => item.userId).join(',');
|
|
if (editid.value) {
|
|
updatePlan(form.value).then(() => {
|
|
ElMessage.success('编辑成功');
|
|
routeback();
|
|
});
|
|
} else {
|
|
addPlan(form.value).then(() => {
|
|
ElMessage.success('添加成功');
|
|
routeback();
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.EditBody {
|
|
margin-top: 20px;
|
|
padding: 30px;
|
|
background-color: white;
|
|
.bodybox {
|
|
width: 600px;
|
|
margin: 0 auto;
|
|
margin-top: 20px;
|
|
}
|
|
.inspectorIdsBox {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
.inspector_items {
|
|
width: 120px;
|
|
height: 40px;
|
|
line-height: 40px;
|
|
margin: 5px;
|
|
text-align: center;
|
|
border-radius: 5px;
|
|
background-color: #ddeaff;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0 2px;
|
|
.name {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
text-wrap: nowrap;
|
|
}
|
|
&.add {
|
|
background-color: #ddeaff25;
|
|
border: 1px dashed #ccc;
|
|
cursor: pointer;
|
|
&:hover {
|
|
background-color: rgba(221, 234, 255, 0.199);
|
|
border-color: #44a0ff;
|
|
color: #44a0ff;
|
|
}
|
|
}
|
|
.deleteaction {
|
|
margin-left: 10px;
|
|
cursor: pointer;
|
|
&:hover {
|
|
color: red;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.week-items {
|
|
width: 90px;
|
|
height: 30px;
|
|
line-height: 30px;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
margin: 10px 5px;
|
|
border: 1px solid #ccc;
|
|
color: #000;
|
|
display: flex;
|
|
align-items: center;
|
|
.iconbox {
|
|
width: 30px;
|
|
height: 30px;
|
|
margin-left: 5px;
|
|
text-align: center;
|
|
line-height: 30px;
|
|
}
|
|
&.active {
|
|
color: rgba(26, 117, 255, 1);
|
|
background-color: rgba(26, 117, 255, 0.15);
|
|
border: none;
|
|
}
|
|
}
|
|
|
|
.mapbox {
|
|
margin-top: 20px;
|
|
width: 100%;
|
|
height: 400px;
|
|
border: 1px solid #ccc;
|
|
}
|
|
}
|
|
</style>
|