992 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="addIssue">
<view class="fixedheader">
<headers :showBack="true">
<view class="headerName">
{{ current == 0 ? '工作票详情' : '查看实时监控'}}
</view>
</headers>
</view>
<view class="content" :style="{paddingTop: mobileTopHeight + 44 + 'px'}">
<view class="content_header" v-if="workTicketInfo.status == 2">
<u-dropdown>
<u-dropdown-item @change="onVideoItemChange" :title="itemListUp" v-model="itemId"
:options="workTicketInfo.itemList"></u-dropdown-item>
</u-dropdown>
<!-- 'https://gcalic.v.myalicdn.com/gc/wgw05_1/index.m3u8' -->
<my-player-m3u8 :src="videoItemInfo.videoInfo.url" :showMask="stateShow" :autoplay="true" />
</view>
<u-tabs :bar-height="4" :font-size="28" active-color="#498CEC" inactive-color="#B3B3B3" :bar-width="375"
:list="list" :is-scroll="false" :current="current" @change="change"></u-tabs>
<scroll-view scroll-y="true" :class="{'content_main_active': workTicketInfo.status == 2}" class="content_main" v-if="current == 0">
<view class="header-title">
<view>
工作票基本信息
</view>
<view
:class="{'wks_active': workTicketInfo.status == 1, 'sgz_active': workTicketInfo.status == 2,'ztz_active': workTicketInfo.status == 3,'ywg_acitve': workTicketInfo.status == 4}">
{{statusUp(workTicketInfo.status)}}
</view>
</view>
<view class="main-box">
<view class="box-item">
<view>工作票编号:</view>
<view>{{workTicketInfo.workTicketNumber}}</view>
</view>
<view class="box-item">
<view>当前绑定监控:</view>
<view>{{ itemListDevNameUp }}</view>
</view>
<view class="box-item">
<view>类别:</view>
<view>{{workTicketInfo.typeName}}</view>
</view>
<view class="box-content">
<view>作业内容:</view>
<view @click="workTicketInfo.expandMoreShow = !workTicketInfo.expandMoreShow">
{{workTicketInfo.expandMoreShow ? '收起': '展开更多'}}
</view>
</view>
<view :class="{'webkit-clamp_2': !workTicketInfo.expandMoreShow}" class="box-content_detail">
{{workTicketInfo.workContent}}
</view>
<view class="box-content">
<view>安全措施:</view>
<view @click="workTicketInfo.expandMoreShow1 = !workTicketInfo.expandMoreShow1">
{{workTicketInfo.expandMoreShow1 ? '收起': '展开更多'}}
</view>
</view>
<view :class="{'webkit-clamp_2': !workTicketInfo.expandMoreShow1}" class="box-content_detail">
{{workTicketInfo.workContent}}
</view>
<view class="box-item">
<view>施工场站:</view>
<view>{{workTicketInfo.constructionAreaNames}}</view>
</view>
<view class="box-item">
<view>施工地点:</view>
<view>{{workTicketInfo.constructionAddr}}</view>
</view>
<view class="box-item">
<view>施工人员:</view>
<view>{{workTicketInfo.operator}}</view>
</view>
<view class="box-item">
<view>施工计划时间:</view>
<view>{{workTicketInfo.constructionTimeBegin}}至{{workTicketInfo.constructionTimeEnd}}</view>
</view>
<view class="box-img">
<view>作业票附件:</view>
<view class="imgBox_wrap">
<view class="imgBox" v-show="workTicketAttachmentList.length>0"
v-for="(item,index) in workTicketAttachmentList" :key="index">
<image :src="url_config+'image/'+item.url" class="img"
@click="previewImage(url_config+'image/'+item.url)">
</image>
</view>
</view>
</view>
<!-- <view class="box-img">
<view>安全风险分析:</view>
<view class="imgBox_wrap">
<view class="imgBox" v-show="safetyRiskAnalysisList.length>0"
v-for="(item,index) in safetyRiskAnalysisList" :key="index">
<image :src="url_config+'image/'+item.url" class="img"
@click="previewImage(url_config+'image/'+item.url)">
</image>
</view>
</view>
</view> -->
<view class="box-img">
<view>其他附件:</view>
<view class="imgBox_wrap_list">
<view class="imgBox_list imgBox_list_active"
@click="previewImage(url_config+'image/'+item.url)"
v-show="otherAttachmentList.length>0" v-for="(item,index) in otherAttachmentList"
:key="index">
<view>
<u-icon name="file-text"></u-icon>
<view>{{item.name}}</view>
</view>
<view @click.stop="deleteImg(item,3)">
下载
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<scroll-view scroll-y="true" :class="{'content_main_active': workTicketInfo.status == 2}" class="content_main1" v-else-if="current == 1">
<view class="header-title">
历史作业记录
</view>
<view class="content_main1_box">
<u-time-line>
<u-time-line-item v-for="(item, index) in workTicketHistoryList" :key="item.id">
<!-- 此处自定义了左边内容,用一个图标替代 -->
<template v-slot:node>
<view class="u-node"
:style="index == workTicketHistoryList.length - 1 ? 'background: #8EC25A;' : 'background: #4B8DEC;'">
<!-- 此处为uView的icon组件 -->
<u-icon name="file-text" color="#fff" :size="24"></u-icon>
</view>
</template>
<template v-slot:content>
<view>
<view class="u-order-title">
<view>{{item.no}}</view>
<view>{{itemDiffUp(item)}}</view>
</view>
<view class="u-order-time">
{{item.begin ? item.begin : '暂无'}} - {{item.end ? item.end : '暂无'}}
</view>
<view class="u-order-desc" @click="onNavigateDetail(item)">
历史回放
<u-icon name="arrow-right-double" color="#2979ff" size="28"></u-icon>
</view>
</view>
</template>
</u-time-line-item>
</u-time-line>
</view>
</scroll-view>
<view class="confrim-btn">
<view v-if="workTicketInfo.status == 1" @click="onChangeState(1)" class="btn-start">开始作业
</view>
<view v-if="workTicketInfo.status == 2" @click="onStateShow(2)">暂停作业</view>
<view v-if="workTicketInfo.status == 3" @click="onChangeState(3)">继续作业</view>
<view v-if="workTicketInfo.status == 2 || workTicketInfo.status == 3" @click="onStateShow(4)"
class="btn-error">结束作业</view>
<view @click="onDelete" class="btn-error">删除</view>
<view @click="onEdit" class="btn-start">编辑</view>
</view>
</view>
<u-toast ref="uToast" />
<u-modal @cancel="onStateCancel" @confirm="onStateConfirm" v-model="stateShow"
:confirm-text="stateType == 2 ? ',立即暂停' : '立即结束'" :show-cancel-button="true" cancel-text=",继续作业">
<view class="slot-content">
<view class="content_main-box1" v-if="stateType == 2">
<view>
暂未全部施工完成将进入暂停施工状态待下次点击继续作业...
</view>
<view>
<u-icon name="info-circle"></u-icon>
<view>点击暂停作业后则会下发指令到作业监控设备关闭设备录像</view>
</view>
</view>
<view class="content_main-box1" v-else-if="stateType == 4">
<view>
作业已全部施工完成点击结束作业
</view>
<view>
<u-icon name="info-circle"></u-icon>
<view>点击结束作业后则会下发指令到作业监控设备关闭设备录像并释放此设备</view>
</view>
</view>
</view>
</u-modal>
</view>
</template>
<script>
import dayjs from 'dayjs';
import MyPlayerM3u8 from '@/components/my-player-m3u8/my-player-m3u8.vue';
export default {
components: {
MyPlayerM3u8
},
data() {
return {
mobileTopHeight: 0,
projectDetail: {},
list: [{
name: '基本信息'
}, {
name: '历史作业记录'
}],
current: 0,
workTicketInfo: {
workTicketNumber: "",
applicants: [],
applicantsName: "",
constructionAreas: [],
constructionAreasName: "",
applicationTime: "",
constructionTimeBegin: "",
constructionTimeEnd: "",
operatorsName: "",
operators: [],
workContent: "",
safetyMeasure: "",
},
workTicketAttachmentList: [],
safetyRiskAnalysisList: [],
otherAttachmentList: [],
workTicketId: "",
workTicketHistoryList: [],
stateShow: false,
stateType: "",
itemId: "",
videoItemInfo: {
videoInfo: {
url: "https://gcalic.v.myalicdn.com/gc/wgw05_1/index.m3u8",
}
},
}
},
onLoad(opts) {
this.projectDetail = JSON.parse(uni.getStorageSync('projectDetail'))
this.workTicketId = opts.id;
this.getWorkTicketQueryByIdFn();
this.getWorkTicketHistoryQueryByIdFn();
},
mounted() {
var that = this
uni.getSystemInfo({
success(res) {
that.mobileTopHeight = res.statusBarHeight ? res.statusBarHeight : 0;
uni.setStorageSync('systemInfo', res)
console.log(res)
}
})
},
methods: {
onStateShow(type) {
this.stateType = type;
this.stateShow = true;
},
onStateCancel() {
this.stateShow = false;
},
onStateConfirm() {
this.onChangeState(this.stateType);
this.stateShow = false;
},
onNavigateDetail(row) {
uni.navigateTo({
url: `./historicalReplay?id=${row.id}`
})
},
statechange(e) {
console.log('live-player code:', e.detail.code)
},
error(e) {
console.error('live-player error:', e.detail.errMsg)
},
//预览图片
previewImage(url) {
uni.previewImage({
urls: [url]
})
},
onEdit() {
uni.navigateTo({
url: `./addWorkTicket?workTicketId=${this.workTicketId}&edit=${true}`
})
},
onChangeState(operateStatus) {
let that = this;
let data = {
projectSn: this.projectDetail.projectSn,
id: this.workTicketId,
operateStatus,
};
this.sendRequest({
url: 'xmgl/workTicket/operateWorkTicket',
method: 'POST',
data: data,
success: res => {
if (res.code == 200) {
that.showToast('修改成功', 'success');
that.getWorkTicketQueryByIdFn();
that.getWorkTicketHistoryQueryByIdFn();
}
}
})
},
onDelete() {
let that = this;
let data = {
projectSn: this.projectDetail.projectSn,
id: this.workTicketId,
};
uni.showModal({
title: '提示',
content: '确定删除该作业吗?',
success: function(res) {
if (res.confirm) {
that.sendRequest({
url: 'xmgl/workTicket/delete',
method: 'POST',
data: data,
success: res => {
if (res.code == 200) {
that.showToast('删除成功!', 'success');
uni.navigateBack({
delta: 1
})
}
}
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
change(index) {
this.current = index;
},
// 列表查询工作票历史记录信息
getWorkTicketHistoryQueryByIdFn() {
let that = this;
let data = {
projectSn: this.projectDetail.projectSn,
workTicketId: this.workTicketId,
};
this.sendRequest({
url: 'xmgl/workTicketHistory/list',
method: 'GET',
data: data,
success: res => {
if (res.code == 200) {
that.workTicketHistoryList = res.result.sort((a, b) => a.no - b.no);
}
}
})
},
onVideoItemChange() {
this.getVideoItemInfoPoliceCameraItemFn();
},
// 根据itemId查询视频播放url
getVideoItemInfoPoliceCameraItemFn() {
let that = this;
let data = {
projectSn: this.projectDetail.projectSn,
itemId: this.itemId,
};
this.sendRequest({
url: 'xmgl/policeCameraItem/getVideoItemInfo',
method: 'POST',
data: data,
success: res => {
if (res.code == 200) {
that.videoItemInfo = res.result;
}
}
})
},
// 通过id查询工作票信息
getWorkTicketQueryByIdFn() {
let that = this;
let data = {
projectSn: this.projectDetail.projectSn,
id: this.workTicketId,
};
this.sendRequest({
url: 'xmgl/workTicket/queryById',
method: 'GET',
data: data,
success: res => {
if (res.code == 200) {
that.workTicketInfo = {
...res.result,
expandMoreShow: false,
expandMoreShow1: false,
itemList: res.result.itemList ? res.result.itemList.map(item => {
return {
...item,
label: item.devName,
value: item.itemId
}
}) : [],
};
if (that.workTicketInfo.itemList.length > 0) {
that.itemId = that.workTicketInfo.itemList[0].itemId;
that.getVideoItemInfoPoliceCameraItemFn();
}
that.otherAttachmentList = res.result.otherAttachment && Array.isArray(JSON
.parse(
res.result.otherAttachment)) ? JSON.parse(res.result
.otherAttachment) : [];
that.safetyRiskAnalysisList = res.result.safetyRiskAnalysis && Array
.isArray(JSON
.parse(res.result.safetyRiskAnalysis)) ? JSON.parse(res.result
.safetyRiskAnalysis) : [];
that.workTicketAttachmentList = res.result.workTicketAttachment && Array
.isArray(
JSON.parse(res.result.workTicketAttachment)) ? JSON.parse(res
.result
.workTicketAttachment) : [];
}
}
})
},
showToast(title, type) {
this.$refs.uToast.show({
title: title,
type: type,
})
},
},
computed: {
itemListUp() {
const find = this.workTicketInfo.itemList && this.workTicketInfo.itemList.find(item => item.value == this
.itemId);
return find ? find.label : '--'
},
itemListDevNameUp(){
return this.workTicketInfo.itemList ? this.workTicketInfo.itemList.map(item => item.devName).join('、') : ""
},
statusUp() {
return (id) => {
const dataList = [{
value: 1,
label: "未开始"
}, {
value: 2,
label: "施工中"
}, {
value: 3,
label: "暂停中"
}, {
value: 4,
label: "已完工"
}]
const find = dataList.find(item => item.value == id);
return find ? find.label : '--'
}
},
itemDiffUp() {
return (row) => {
// 定义两个日期
const date = this.$dayjs();
const date1 = this.$dayjs(row.begin);
const date2 = row.end ? this.$dayjs(row.end) : date;
// 计算两个日期之间的差异(默认单位是毫秒)
const diffInMilliseconds = date2.diff(date1);
const durationObj = this.$dayjs.duration(diffInMilliseconds);
const hour = durationObj.hours();
const minute = durationObj.minutes();
const second = durationObj.seconds();
return `${hour}h${minute}min${second}s`;
}
},
}
}
</script>
<style scoped lang="scss">
/deep/ .m3u8-player {
height: 420rpx;
}
/deep/ .uicon-arrow-down {
// position: absolute;
// top: 50%;
// right: -4px;
margin-top: -5px;
border: 3px solid;
border-color: transparent transparent #dcdee0 #dcdee0;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
opacity: .8;
content: '';
}
/deep/ .u-dropdown__menu__item__arrow--rotate .uicon-arrow-down {
border-color: transparent transparent rgb(49, 144, 243) rgb(49, 144, 243);
}
/deep/ .uicon-arrow-down::before {
display: none;
}
/deep/ .u-cell-item-box {
margin: 20rpx 26rpx;
width: calc(100% - 26rpx - 26rpx);
border-radius: 6rpx;
}
/deep/ .u-dropdown__menu {
flex-wrap: wrap;
// height: 166rpx !important;
box-shadow: none;
padding: 0 26rpx;
.u-dropdown__menu__item {
width: 40%;
// height: 82rpx;
flex: initial;
.u-flex {
width: 100%;
}
}
}
/deep/ .u-dropdown__menu__item__text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/deep/ .u-mode-center-box {
width: 698rpx !important;
.u-model__title {
padding: 0;
font-size: 32rpx;
color: #272D45;
height: 86rpx;
background-color: #FFFFFF;
box-shadow: 0rpx 8rpx 10rpx -8rpx rgba(81, 129, 246, 0.42);
display: flex;
align-items: center;
justify-content: center;
}
.u-model__content__message {
padding: 26rpx 26rpx 72rpx;
font-size: 28rpx;
color: #171717;
}
.u-model__footer__button {
height: 76rpx;
line-height: 76rpx;
background-color: rgba(81, 129, 246, 0.1);
font-weight: 500;
font-size: 28rpx;
color: #5181F6;
}
.hairline-left {
background-color: #5181F6;
color: white !important;
}
.content_main-box1 {
padding: 26rpx 28rpx;
>view:first-child {
font-weight: 500;
font-size: 28rpx;
color: #171717;
}
>view:last-child {
display: flex;
align-items: flex-start;
font-size: 24rpx;
color: #FFA026;
margin-top: 26rpx;
.u-icon {
font-size: 35rpx;
margin-right: 20rpx;
}
}
}
}
.content {
position: relative;
background-color: white;
// overflow: hidden;
// min-height: calc(100vh);
.content_main_active {
height: calc(100vh - 88rpx - 500rpx - 80rpx - 100rpx - 26rpx) !important;
}
.content_header {
// background-color: white;
}
.content_main1 {
padding-top: 26rpx;
padding-bottom: 100rpx;
// background-color: white;
// min-height: calc(100vh - 88rpx - 40rpx - 40rpx);
.header-title {
padding: 12rpx 16rpx;
border-bottom: 2rpx solid #EFF3F7;
font-weight: 500;
font-size: 30rpx;
color: #1A1A1A;
}
.content_main1_box {
padding: 40rpx 26rpx;
/deep/ .u-time-axis {
padding-left: 60rpx;
}
.u-node {
width: 44rpx;
height: 44rpx;
border-radius: 100rpx;
display: flex;
justify-content: center;
align-items: center;
background: #d0d0d0;
}
.u-order-title {
display: flex;
align-items: center;
justify-content: space-between;
>view:first-child {
font-size: 28rpx;
color: #4D4D4D;
}
>view:last-child {
padding: 6rpx 20rpx;
background-color: rgba(75, 141, 236, 0.1);
border-radius: 76rpx 76rpx 76rpx 76rpx;
border: 2rpx solid #FFFFFF;
font-size: 21rpx;
color: #4B8DEC;
}
}
.u-order-desc {
font-weight: 500;
font-size: 24rpx;
color: #4D8EEC;
margin-top: 26rpx;
.u-icon {
color: #4F8FEC;
margin-left: 26rpx;
/deep/ .u-icon__icon {
font-size: 24rpx !important;
}
}
}
.u-order-time {
font-weight: 500;
font-size: 28rpx;
color: #4D4D4D;
margin-top: 10rpx;
}
}
}
.content_main {
padding-top: 26rpx;
padding-bottom: 100rpx;
background-color: white;
.main-box {
padding: 26rpx;
.box-content_detail {
font-size: 28rpx;
color: #4D4D4D;
margin-top: 4rpx;
}
.webkit-clamp_2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
/* 限制为两行 */
overflow: hidden;
}
.box-content {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 26rpx;
font-size: 28rpx;
>view:first-child {
color: #808080;
}
>view:last-child {
font-size: 24rpx;
color: #4D8EEC;
}
}
.box-img {
display: flex;
flex-direction: column;
margin-top: 26rpx;
font-size: 28rpx;
>view:first-child {
width: 192rpx;
margin-right: 26rpx;
color: #808080;
}
.imgBox_wrap_list {
flex-direction: column;
align-items: flex-start !important;
.imgBox_list {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 14rpx 26rpx 14rpx 40rpx;
>view:first-child {
display: flex;
align-items: center;
.u-icon {
font-size: 40rpx;
color: #B3B3B3;
}
>view:last-child {
margin-left: 14rpx;
width: 320rpx;
font-size: 24rpx;
color: #808080;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
>view:last-child {
font-weight: 500;
font-size: 24rpx;
color: #4D8EEC;
}
}
.imgBox_list:nth-child(even) {
background-color: #FBFBFB;
}
.imgBox_list:nth-child(odd) {
background-color: #FFFFFF;
}
}
.imgBox_wrap {
display: flex;
flex-wrap: wrap;
margin-left: 192rpx;
flex: 1;
>view:not(:last-child) {
margin-right: 26rpx;
}
>view {
margin-bottom: 20rpx;
}
.imgBox {
width: 164rpx;
height: 164rpx;
display: inline-flex;
position: relative;
border-radius: 8rpx;
.img {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
}
}
}
.box-item {
display: flex;
align-items: center;
margin-top: 26rpx;
font-size: 28rpx;
>view:first-child {
width: 192rpx;
margin-right: 26rpx;
color: #808080;
}
>view:last-child {
flex: 1;
color: #4D4D4D;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
/* 限制为两行 */
overflow: hidden;
}
}
/deep/ .u-input {
width: 550rpx;
height: 68rpx;
line-height: 68rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
border: 2rpx solid #D8DBE8;
}
.changetime {
width: 550rpx;
height: 68rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
border: 2rpx solid #D8DBE8;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 34rpx;
font-size: 28rpx;
color: #4D4D4D;
.changetime_icon {
width: 36rpx;
height: 36rpx;
background-image: url('@/static/workTicketManage/index-icon7.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
}
.textarea {
position: relative;
/deep/ .u-input {
height: 160rpx;
line-height: 68rpx;
}
.textarea_text {
position: absolute;
right: 20rpx;
bottom: 20rpx;
font-size: 22rpx;
color: #B3B3B3;
}
}
}
.header-title {
padding: 12rpx 16rpx;
border-bottom: 2rpx solid #EFF3F7;
display: flex;
align-items: center;
justify-content: space-between;
>view:first-child {
font-weight: 500;
font-size: 30rpx;
color: #1A1A1A;
}
>view:last-child {
padding: 4rpx 20rpx;
border-radius: 4rpx;
border: 2rpx solid #F1F1F1;
font-weight: 500;
font-size: 22rpx;
}
.wks_active {
background-color: #898989;
color: #1A1A1A;
}
.sgz_active {
background-color: #BED0FA;
color: #5181F6;
}
.ztz_active {
background-color: #C38100;
color: #FFFFFF;
}
.ywg_acitve {
background-color: #88CF65;
color: #1A1A1A;
}
}
}
.confrim-btn {
width: 100%;
padding: 18rpx 26rpx;
background-color: #FFFFFF;
box-shadow: 0rpx -8rpx 8rpx 0rpx rgba(0, 0, 0, 0.05);
display: flex;
justify-content: flex-end;
position: fixed;
bottom: 0;
z-index: 1;
>view {
padding: 10rpx 20rpx;
font-weight: 500;
border-radius: 6rpx;
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #3E89FD;
color: #3E89FD;
}
>view:not(:first-child) {
margin-left: 20rpx;
}
.btn-error {
border: 2rpx solid #ED2B29;
color: #ED2B29;
}
.btn-start {
background-color: #3E89FD;
border-color: #3E89FD;
color: #FFFFFF;
}
}
}
.addIssue {
min-height: 100vh;
background-color: #F2F3F7;
}
.fixedheader {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
/deep/ .headerBox {
border-bottom: none;
}
.headerName {
z-index: 1;
}
}
</style>