<!-- 道面巡检主页面 -->
<template>
<div id="roadSchedule">
<!-- 查询条件 -->
<div class="totalCondition">
<condition
ref="condition"
@setData="setData"
@setLoading="setLoading"
@setSelects="setSelects"
/>
</div>
<!-- 表格 -->
<div class="table_wrap">
<el-form class="tbForm" :model="fromData" ref="fromTable">
<el-table
height="100%"
:data="fromData.data.slice((this.page - 1) * this.size, (this.page - 1) * this.size+ this.size)"
stripe
v-loading="loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
@row-contextmenu="rightClick"
ref="table"
>
<el-table-column label="日期">
<template slot-scope="scope">
<el-form-item
v-show="scope.row.showRow"
:prop="'data.'+scope.$index+'.newStartDate'"
:rules="fromaDataRules.newStartDate"
>
<el-date-picker
v-model="scope.row.newStartDate"
type="date"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="请选择日期"
:clearable="false"
></el-date-picker>
</el-form-item>
<span v-show="!scope.row.showRow">{{scope.row.newStartDate}}</span>
</template>
</el-table-column>
<el-table-column label="开始时间">
<template slot-scope="scope">
<el-form-item
v-show="scope.row.showRow"
:prop="'data.'+scope.$index+'.patrolStartTime'"
:rules="fromaDataRules.patrolStartTime"
>
<el-time-picker
v-model="scope.row.patrolStartTime"
format="HH:mm"
value-format="HH:mm"
placeholder="请选择开始时间"
:clearable="false"
></el-time-picker>
</el-form-item>
<span v-show="!scope.row.showRow">{{scope.row.patrolStartTime}}</span>
</template>
</el-table-column>
<el-table-column label="结束时间">
<template slot-scope="scope">
<el-form-item
v-show="scope.row.showRow"
:prop="'data.'+scope.$index+'.patrolEndTime'"
:rules="fromaDataRules.patrolEndTime"
>
<el-date-picker
v-model="scope.row.patrolEndTime"
type="datetime"
format="yyyy-MM-dd HH:mm"
value-format="yyyy-MM-dd HH:mm"
placeholder="请选择结束时间"
:clearable="false"
></el-date-picker>
</el-form-item>
<span
v-show="!scope.row.showRow"
>{{diffDays(scope.row.newStartDate,scope.row.patrolEndTime)}}</span>
</template>
</el-table-column>
<el-table-column label="巡检人">
<template slot-scope="scope">
<el-form-item
v-show="scope.row.showRow"
:prop="'data.'+scope.$index+'.personLiable'"
:rules="fromaDataRules.personLiable"
>
<el-input placeholder="请输入巡检人" v-model="scope.row.personLiable"></el-input>
</el-form-item>
<span v-show="!scope.row.showRow">{{scope.row.personLiable}}</span>
</template>
</el-table-column>
<el-table-column label="任务描述">
<template slot-scope="scope">
<el-form-item
v-show="scope.row.showRow"
:prop="'data.'+scope.$index+'.taskDescription'"
:rules="fromaDataRules.taskDescription"
>
<el-input placeholder="请输入任务描述" v-model="scope.row.taskDescription"></el-input>
</el-form-item>
<span v-show="!scope.row.showRow">{{scope.row.taskDescription}}</span>
</template>
</el-table-column>
<el-table-column label="任务状态">
<template slot-scope="scope">
<div v-show="scope.row.showRow">
<el-form-item
:prop="'data.'+scope.$index+'.patrolStatus'"
:rules="fromaDataRules.patrolStatus"
>
<el-select v-model="scope.row.patrolStatus" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.id"
:label="item.content"
:value="item.content"
></el-option>
</el-select>
<el-button type="text" @click="saveRow(scope.row)">
<i class="el-icon-check"></i>
</el-button>
</el-form-item>
</div>
<div v-show="!scope.row.showRow">
<span>{{scope.row.patrolStatus}}</span>
<el-button
v-if="scope.row.patrolStatus==='进行中'||scope.row.patrolStatus==='已完成'"
type="text"
size="medium"
@click="clickDetail(scope.row)"
> 详情</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-form>
</div>
<!-- 分页组件 -->
<div class="pagination_wrap">
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="page"
:page-sizes="[20, 30, 40, 100]"
:page-size.sync="size"
:total="total"
></el-pagination>
</div>
<!-- 右键菜单 -->
<v-contextmenu ref="contextmenu" :menus="menus" />
<!-- 详情展示地图 -->
<dialogMap v-if="isShowDialogMap" />
<!-- 计划录入弹框 -->
<planEnter v-if="isShowPlanEnter" @successPublic="successPublic" />
<!-- 模板设置弹框 -->
<templateSetting v-if="isShowTemplate" />
</div>
</template>
<script type="text/ecmascript-6">
import condition from './components/condition/index';
import dialogMap from './components/dialogMap/index';
import planEnter from './components/dialogs/planEnter';
import templateSetting from './components/dialogs/templateSetting';
import { mapState, mapMutations } from 'vuex';
import { formatTime } from '@/utils/time.js';
export default {
components: {
condition, // 查询条件
dialogMap, // 详情地图
planEnter, // 计划录入弹框
templateSetting // 模板设置弹框
},
data() {
const self = this;
return {
// 校验规则
fromaDataRules: {
personLiable: [
{ required: true, message: '巡检人不能为空', trigger: 'blur,change' }
],
taskDescription: [
{
required: true,
message: '任务描述不能为空',
trigger: 'blur,change'
}
],
patrolEndTime: [
{
required: true,
message: '结束时间不能为空',
trigger: 'blur,change'
}
],
patrolStartTime: [
{
required: true,
message: '开始时间不能为空',
trigger: 'blur,change'
}
],
newStartDate: [
{ required: true, message: '日期不能为空', trigger: 'blur,change' }
]
},
// 表格主数据
fromData: {
data: []
},
// 编辑时任务状态列表
options: [],
page: 1,
size: 20,
loading: false,
// 当前行数据
currentRow: {},
// 当前行数据索引值
currentRowIndex: '',
// 右键菜单项数据
menus: [
{
name: '编辑',
group: '1',
handler() {
self.edit();
}
},
{
name: '删除',
group: '1',
handler() {
self.remove();
}
}
]
};
},
// 监听的数据
computed: {
...mapState('roadSchedule', [
'isShowPlanEnter',
'isShowTemplate',
'isShowDialogMap'
]),
/**
* 计算数据总数
* @returns {Number}
*/
total() {
return this.fromData.data.length;
},
/**
* 计算当前页开始索引
* @returns {Number}
*/
index() {
return (this.page - 1) * this.size + 1;
}
},
methods: {
...mapMutations('roadSchedule', [
'setShowPlanEnter',
'setTemplateTableData',
'setShowDialogMap',
'setDialogMapData'
]),
/**
* 右键菜单的显示
*/
handleContextmenu(evt) {
// 禁用浏览器默认行为
evt.preventDefault();
// 调用弹出方法
this.$refs.contextmenu.popover(evt);
},
/**
* 监听计划发布传递的数据,如果发布成功,再次重新查询列表
* @params {Boolean} val-子组件传递的数据
*/
successPublic(val) {
if (val) {
this.$refs.condition.search();
}
},
/**
* 点击详情,传入详情数据
*/
clickDetail(row) {
this.setShowDialogMap(true);
this.setDialogMapData(row);
},
/**
* 保存当前行
*/
saveRow(row) {
const seleted = row;
// 匹配后台参数yyyy-MM-DD HH:mm:ss格式
seleted.patrolStartTime = `${seleted.newStartDate} ${seleted.patrolStartTime}:00`;
seleted.patrolEndTime = `${seleted.patrolEndTime}:00`;
// 表单校验通过
this.$refs.fromTable.validate((valid) => {
if (valid) {
this.$api.roadSchedule
.updatePatrolTasks(seleted)
.then((res) => {
this.$utils.vIfElse(
res && res.error,
() => {
// 返回错误信息
this.$message.error(_.get(res.error, 'message'));
},
() => {
// 请求成功处理
this.$refs.condition.search();
this.clearCurrentRow('');
this.$message.success('保存成功!'); // 消息弹框
}
);
})
.catch((error) => {
this.$message.error(_.get(error, 'response.data.message') || '保存失败!');
});
} else {
return false;
}
});
},
/**
* 右键菜单-编辑
*/
edit() {
this.currentRow.showRow = true;
this.$set(this.fromData.data, this.currentRowIndex, this.currentRow);
},
/**
* 右键菜单-删除
*/
remove() {
this.$confirm('此操作将永久删除, 是否继续?', '', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
this.$api.roadSchedule
.deletePatrolTasks(this.currentRow.id)
.then((res) => {
this.$message.success('删除成功!'); // 消息弹框
this.$refs.condition.search();
this.clearCurrentRow('');
})
.catch((error) => {
this.$message.error(_.get(error, 'response.data.message') || '删除失败!');
});
})
.catch(() => {
this.$message('已取消删除!');
});
},
/**
* 右击表格当前行触发
*/
rightClick(row, column, event) {
// 阻止浏览器右键默认
event.preventDefault();
// 当前行在编辑状态时 或者 有正在编辑的行
// TODO 等后台把接口的任务状态返回符合要求
if (
row.patrolStatus === '未进行' &&
row.showRow === false &&
(!this.currentRow.id || this.currentRow.showRow === false)
) {
// 定义变量接收该节点所对应的对象
this.currentRow = row;
// 调用弹出方法
this.$refs.contextmenu.popover(event);
// 获取当前右键点击table下标
this.fromData.data.forEach((item, index) => {
if (item.id === row.id) {
this.currentRowIndex = index;
return false;
}
});
}
},
/**
* 计算开始时间和结束时间间隔天数 格式化列表结束时间 HHmm格式或HHmm(+n)
* @param {Date} strDateStart strDateEnd:开始时间;strDateEnd:
*/
diffDays(strDateStart, strDateEnd) {
const HHMM = formatTime(strDateEnd, 'hhmm', true);
const strDateS = new Date(strDateStart).getTime();
const strDateE = new Date(strDateEnd).getTime();
const days = parseInt((strDateE - strDateS) / 1000 / 60 / 60 / 24, 10); // 把相差的毫秒数转换为天数
if (days > 0) {
return `${HHMM}(+${days})`;
}
return `${HHMM}`;
},
/**
* 日期转毫秒数
*/
dateToTime(str) {
return new Date(str.replace(/-/g, '/')).getTime(); // 用/替换日期中的-是为了解决Safari的兼容
},
/**
* 设置表格数据
*/
setData(data) {
this.fromData.data = data;
},
/**
* 设置加载中转圈圈
*/
setLoading(val) {
this.loading = val;
},
/**
* 设置下拉数据
*/
setSelects(arr) {
this.options = arr;
},
/**
* 清空当前行
*/
clearCurrentRow(val) {
this.currentRow = {};
this.currentRowIndex = '';
}
}
};
</script>
<style lang="scss">
#roadSchedule {
//设置列表表单的 高度
.tbForm {
height: 100%;
.el-input {
& > input {
border: 1px solid #2050a0;
}
}
.el-icon-check {
font-size: 22px;
font-weight: bolder;
vertical-align: middle;
}
}
// 隐藏默认图标
.el-icon-date {
position: absolute;
display: none;
}
//分隔符 - 的颜色
.el-range-separator {
color: rgb(255, 255, 255);
}
padding-left: 10px;
padding-right: 10px;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
.box-card {
position: absolute;
z-index: 1000;
.edit {
cursor: pointer;
}
.delete {
cursor: pointer;
margin-top: 5px;
}
}
.el-card__body {
padding-top: 5px;
padding-right: 15px;
padding-bottom: 5px;
padding-left: 15px;
}
.el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: #2050a0 !important;
}
.title {
height: 40px;
line-height: 40px;
font-size: 16px;
}
.planBtn {
width: 107px;
height: 30px;
line-height: 30px;
text-align: center;
background-color: #01bba7;
cursor: pointer;
border-radius: 4px;
}
.amvs_dialog {
background: rgba(0, 0, 0, 0.5);
z-index: 100;
}
.table_wrap {
margin-top: 10px;
flex: 1;
.el-input__inner {
height: 30px;
background: #383838;
border: none;
border-radius: 1px;
width: 220px;
color: #fff;
}
.el-input__icon {
line-height: 28px;
}
}
.pagination_wrap {
height: 80px;
display: flex;
justify-content: flex-end;
align-items: center;
}
.el-table th {
color: #cbcbcb;
}
.el-table {
color: #bcbcbc;
}
}
</style>