YNUtdPlatform/pages/workPlan/custody/index.vue

816 lines
24 KiB
Vue
Raw Normal View History

2024-10-23 09:10:06 +08:00
<template>
2024-10-23 11:35:25 +08:00
<view>
<u-navbar
class="u-navbar"
title="现场监护"
placeholder
@leftClick="leftClick"
leftIconColor="#fff"
bgColor="#00337A"
:titleStyle="{ color: '#FFF', fontSize: '32rpx' }"
/>
<view class="custody-container">
<view class="header-btn">
<view :class="{ active: current === 0 }" @tap="onCheckTap(0)">新增数据</view>
<view :class="{ active: current === 1 }" @tap="onCheckTap(1)">我的数据</view>
</view>
<view style="width: 100%">
<swiper style="width: 100%" :current="current" @change="onSwiperChange" :style="{ height: navHeight + 'px' }">
<swiper-item class="swiper-item-content" :style="{ height: navHeight + 'px' }">
<scroll-view scroll-y="true" class="scroll-view-y" :style="{ height: navHeight + 'px' }">
<view class="risk-header">
<view class="risk-left">
<view>今日</view>
<view>风险</view>
</view>
<view class="risk-right">
<view style="margin-top: 16rpx">
<text>我的项目</text>
2024-11-01 18:15:33 +08:00
<text style="color: #ca6d58">高风险 {{ riskInfo.gfxNum || 0 }}</text>
<text style="color: #c2a95d; margin-left: 46rpx">中风险 {{ riskInfo.zfxNum || 0 }}</text>
<text style="color: #b12d3f; margin-left: 46rpx">特高风险 {{ riskInfo.tgfxNum || 0 }}</text>
2024-10-23 11:35:25 +08:00
</view>
<view>
<text>全部项目</text>
2024-11-01 18:15:33 +08:00
<text style="color: #ca6d58">高风险 {{ riskInfo.gfxNumAll || 0 }}</text>
<text style="color: #c2a95d; margin-left: 46rpx">中风险 {{ riskInfo.zfxNumAll || 0 }}</text>
<text style="color: #b12d3f; margin-left: 46rpx">特高风险 {{ riskInfo.tgfxNumAll || 0 }}</text>
2024-10-23 11:35:25 +08:00
</view>
</view>
</view>
<!-- 选择今日 日计划风险 -->
<view class="change-today">
<view class="today-title">
<view class="title-bold">选择今日 日计划风险</view>
2024-11-01 18:15:33 +08:00
<view @tap="onSelectRisk">去选择风险点</view>
2024-10-23 11:35:25 +08:00
</view>
2024-11-01 18:15:33 +08:00
<uni-forms
:modelValue="submitParams"
ref="submitFormRef"
:rules="submitFormRules"
label-position="top"
label-width="200"
>
<uni-forms-item label="作业风险内容" required name="zynr">
<u--textarea placeholder="请填写" autoHeight v-model="submitParams.zynr" clearable></u--textarea>
2024-10-23 11:35:25 +08:00
</uni-forms-item>
2024-11-01 18:15:33 +08:00
<uni-forms-item label="风险等级" required name="fxdjName">
<u--input type="text" placeholder="请填写" v-model="submitParams.fxdjName" clearable />
2024-10-23 11:35:25 +08:00
</uni-forms-item>
2024-11-01 18:15:33 +08:00
<uni-forms-item label="工程名称" required name="proName">
<u--textarea type="text" autoHeight placeholder="请填写" v-model="submitParams.proName" clearable />
2024-10-23 11:35:25 +08:00
</uni-forms-item>
</uni-forms>
</view>
<!-- 现场监护 -->
<view class="scene-container">
<view class="title-bold">现场监护</view>
2024-11-01 18:15:33 +08:00
<uni-forms
:modelValue="submitParams"
ref="submitFormRef_2"
:rules="submitFormRules"
label-position="top"
label-width="200"
>
<uni-forms-item label="当前位置" required name="address">
<view class="address-content">
2024-11-07 15:45:24 +08:00
<u--textarea placeholder="请填写" autoHeight v-model="submitParams.address" />
2024-11-01 18:15:33 +08:00
<view class="address-info">
<text>
{{ submitParams.lat }}
</text>
<text>
{{ submitParams.lon }}
</text>
2024-11-07 15:45:24 +08:00
2024-11-07 20:21:02 +08:00
<!-- <view @tap="getLocationAddress">点击获取</view> -->
2024-11-01 18:15:33 +08:00
</view>
2024-11-07 20:21:02 +08:00
<!-- <view>{{ demoAddress }}</view> -->
2024-11-01 18:15:33 +08:00
</view>
2024-10-23 11:35:25 +08:00
</uni-forms-item>
<uni-forms-item label="附件上传(1-6张照片)" required>
<view class="example-body">
2024-11-01 18:15:33 +08:00
<uni-file-picker
v-model="imageValue"
fileMediatype="image"
mode="grid"
@select="select"
@delete="onDelete"
limit="6"
title="最多选择6张图片"
></uni-file-picker>
2024-10-23 11:35:25 +08:00
</view>
</uni-forms-item>
2024-11-01 18:15:33 +08:00
<uni-forms-item label="电子签名(1-6人)" required>
<view class="autograph">
<view class="autograph-img-box">
<view v-for="item in autographImgList" :key="item.name">
<image :src="item.url" mode="scaleToFill" class="view-autograph"></image>
<text class="delete-icon" @tap="onDeleteAutograph(item)">
<uni-icons type="trash-filled" size="24" style="color: #fa3534"></uni-icons>
</text>
</view>
</view>
<view class="open-box" @tap="onOpenAutograph">打开签字板</view>
</view>
2024-10-23 11:35:25 +08:00
</uni-forms-item>
2024-11-01 18:15:33 +08:00
<uni-forms-item label="备注(可编辑)" required name="remark">
<u--textarea placeholder="请填写" autoHeight v-model="submitParams.remark" clearable></u--textarea>
2024-10-23 11:35:25 +08:00
</uni-forms-item>
</uni-forms>
2024-11-01 18:15:33 +08:00
<view class="submit-btn" @tap="onSubmitForm">提交</view>
2024-10-23 11:35:25 +08:00
</view>
</scroll-view>
</swiper-item>
2024-11-01 18:15:33 +08:00
<!-- 我的数据 -->
<swiper-item>
<view class="swiper-item-content" :style="{ height: navHeight + 'px' }">
<scroll-view scroll-y="true" class="scroll-view-y" :style="{ height: navHeight + 'px' }">
<view class="my-data-header-container">
<view class="my-data-header">
<view style="width: 32%">
<uni-datetime-picker
type="date"
v-model="detailsParams.date"
:clear-icon="false"
@maskClick="maskClick"
/>
</view>
<view style="width: 48%">
<u--input type="text" placeholder="请填写" v-model="detailsParams.remark" clearable />
</view>
2024-11-07 11:25:10 +08:00
<view class="search-img" @tap="getMySceneListData"></view>
2024-11-01 18:15:33 +08:00
</view>
</view>
<view class="my-data-container" v-if="detailsList.length > 0">
<view class="my-data-content" v-for="item in detailsList" :key="item.id" @tap="onViewDetails(item)">
<view class="data-risk">
<text style="color: #cc413c">{{ item.fxdjName }}</text>
<text>{{ item.time }}</text>
</view>
<view class="pro-name-box">{{ item.proName }}</view>
<view class="pro-content">{{ item.zynr }}</view>
</view>
</view>
</scroll-view>
</view>
</swiper-item>
2024-10-23 11:35:25 +08:00
</swiper>
</view>
</view>
2024-11-01 18:15:33 +08:00
<!-- <m-tabbar fixed fill :current="0" :tabbar="tabbar" class="bottom-tab"></m-tabbar> -->
<uni-popup ref="popup" type="center">
<view class="autograph-container">
<view class="autograph-btn">
<view style="margin-right: 16rpx" @tap="onClear">清除</view>
<view @tap="onSave">保存</view>
</view>
<view class="autograph-area">签名区域</view>
<view class="autograph-area-box">
<l-signature
disableScroll
ref="signatureRef"
:penColor="penColor"
:penSize="penSize"
:openSmooth="openSmooth"
:preferToDataURL="false"
></l-signature>
</view>
</view>
</uni-popup>
2024-10-23 11:35:25 +08:00
</view>
2024-10-23 09:10:06 +08:00
</template>
<script>
2024-10-23 11:35:25 +08:00
import TabbarConfig from '../util/tabbar'
2024-11-03 14:42:17 +08:00
import { setRiskSubmitApi, getMySceneListApi, getTodayRiskApi } from '../../../api/workPlan/riskDay'
2024-10-23 11:35:25 +08:00
export default {
data() {
return {
current: 0,
tabbar: TabbarConfig,
navHeight: 100,
2024-11-01 18:15:33 +08:00
pH: 0, //窗口高度
/* 提交时参数 */
submitParams: {
photoPath: '', // 附件
signPath: '', // 签名
proId: '', // 项目ID
proTypes: '', // 工程类型
zynr: '', // 作业内容
fxdj: '', // 风险等级
address: '', // 地址
lon: '', // 经度
lat: '', // 纬度
remark: '', // 备注
fxdjName: '',
proName: ''
},
riskInfo: {},
penColor: '#000',
penSize: 3,
// url: '',
openSmooth: true,
autographSrc: '',
imageValue: [],
autographImgList: [],
submitFormRules: {
zynr: {
rules: [{ required: true, errorMessage: '请填写作业风险内容' }]
},
fxdjName: {
rules: [{ required: true, errorMessage: '请填写风险等级' }]
},
proName: {
rules: [{ required: true, errorMessage: '请填写工程名称' }]
},
address: {
rules: [{ required: true, errorMessage: '请填写当前位置' }]
},
photoPath: {
rules: [{ required: true, errorMessage: '请上传附件' }]
},
signPath: {
rules: [{ required: true, errorMessage: '请添加电子签名' }]
},
remark: {
rules: [{ required: true, errorMessage: '请填写备注' }]
}
},
detailsParams: {
date: '',
remark: ''
},
2024-11-07 15:45:24 +08:00
detailsList: [],
demoAddress: '',
demoAddress_2: ''
2024-10-23 11:35:25 +08:00
}
},
methods: {
leftClick() {
uni.navigateBack()
},
onCheckTap(type) {
this.current = type
2024-11-01 18:15:33 +08:00
if (type == 0) {
this.detailsParams.date = ''
this.detailsParams.remark = ''
} else {
this.getMySceneListData()
}
2024-10-23 11:35:25 +08:00
},
onSwiperChange(e) {
console.log('轮播图change事件', e)
this.current = e.target.current
2024-11-01 18:15:33 +08:00
},
/* 选择风险点 */
onSelectRisk() {
uni.navigateTo({ url: '/pages/workPlan/selectRisk/index' })
},
/* 打开签字版 */
onOpenAutograph() {
if (this.autographImgList.length === 6) {
uni.showToast({
title: '最多签名6人',
icon: 'none'
})
return
}
this.$refs.popup.open('enter')
},
onClear() {
// this.$refs.popup.close()
this.$refs.signatureRef.clear()
},
maskClick() {},
onSave() {
this.$refs.signatureRef.canvasToTempFilePath({
success: res => {
console.log(res, '画板结果--')
// 是否为空画板 无签名
// this.autographSrc = res.tempFilePath
uni.uploadFile({
url: 'http://192.168.0.14:19191/ynPlanApp/user/uploadPhoto',
filePath: res.tempFilePath,
name: 'image',
formData: {
file: res.tempFilePath,
photoType: 'photo'
},
header: { 'Content-Type': 'multipart/form-data' },
success: uploadFileRes => {
if (uploadFileRes.statusCode == 200) {
let imgNameList = res.tempFilePath.split('/')
let imgName = imgNameList[imgNameList.length - 1]
const itemInfo = {
name: imgName,
tempUrl: `ynPlan/photo/${this.$moment().format('YYYY')}/${this.$moment().format(
'MM'
)}/${this.$moment().format('DD')}/${imgName}`,
url: res.tempFilePath
}
this.autographImgList.push(itemInfo)
console.log('this.autographImgList', this.autographImgList)
}
}
})
this.$refs.popup.close()
}
})
},
select(e) {
e.tempFiles.forEach(item => {
const imgUrl = item.url
const imgName = item.name
uni.uploadFile({
url: 'http://192.168.0.14:19191/ynPlanApp/user/uploadPhoto',
filePath: imgUrl,
name: 'image',
formData: {
file: imgUrl,
photoType: 'photo'
},
header: { 'Content-Type': 'multipart/form-data' },
success: uploadFileRes => {
if (uploadFileRes.statusCode == 200) {
console.log('上传成功!')
const imgInfo = {
name: imgName,
tempUrl: `ynPlan/photo/${this.$moment().format('YYYY')}/${this.$moment().format(
'MM'
)}/${this.$moment().format('DD')}/${imgName}`,
url: imgUrl
}
this.imageValue.push(imgInfo)
}
}
})
})
},
onDelete(e) {
const tempFilePath = e.tempFilePath
this.imageValue = this.imageValue.filter(e => e.url !== tempFilePath)
},
/* 删除签名 */
onDeleteAutograph(item) {
this.autographImgList = this.autographImgList.filter(e => e.name !== item.name)
},
/* 表单提交 */
onSubmitForm() {
if (this.imageValue.length < 1) {
uni.showToast({ icon: 'none', title: '请上传附件图片' })
return
}
if (this.autographImgList.length < 1) {
uni.showToast({ icon: 'none', title: '请签名' })
return
}
if (this.imageValue.length > 0) {
let fileStr = ''
this.imageValue.forEach(e => {
fileStr += e.tempUrl + ','
})
this.submitParams.photoPath = fileStr.slice(0, -1)
}
if (this.autographImgList.length > 0) {
let fileStr = ''
this.autographImgList.forEach(e => {
fileStr += e.tempUrl + ','
})
this.submitParams.signPath = fileStr.slice(0, -1)
}
console.log(' this.submitParams---------参数', this.submitParams)
this.$refs.submitFormRef.validate(valid => {
if (valid) {
console.log(valid)
} else {
this.$refs.submitFormRef_2.validate(async res => {
if (res) {
console.log(res)
} else {
console.log('校验通过')
const result = await setRiskSubmitApi(this.submitParams)
console.log(result, 'resultresult提交结果')
if (result.resMsg == 'success') {
setTimeout(() => {
uni.showToast({ title: '提交成功', icon: 'none' })
}, 500)
uni.navigateBack()
}
}
})
}
})
},
/* 获取详情列表 */
async getMySceneListData() {
const res = await getMySceneListApi(this.detailsParams)
if (res.resMsg == 'success') {
this.detailsList = res.obj
} else {
this.detailsList = []
}
console.log(res, '详情数据')
},
/* 跳转详情 */
onViewDetails(item) {
console.log(item, '-----')
2024-11-03 14:42:17 +08:00
uni.navigateTo({ url: `/pages/workPlan/guaRecord/index?id=${item.id}` })
},
/* 获取今日风险 */
async getTodayRiskData() {
const res = await getTodayRiskApi({ id: '' })
if (res.resMsg == 'success') {
this.riskInfo = res.obj[0]
}
2024-11-07 15:45:24 +08:00
},
getLocationAddress() {
const this_ = this
uni.chooseLocation({
success: function (res) {
this_.submitParams.address = res.address
this_.submitParams.lon = res.longitude
this_.submitParams.lat = res.latitude
}
})
2024-10-23 11:35:25 +08:00
}
},
2024-11-01 18:15:33 +08:00
onLoad(options) {
this.getMySceneListData()
2024-11-03 14:42:17 +08:00
this.getTodayRiskData()
2024-11-01 18:15:33 +08:00
// 获取定位位置信息
2024-11-07 20:21:02 +08:00
uni.getLocation({
type: 'gcj02', // 默认为 gcj02可以选择 'wgs84'
altitude: false,
geocode: true,
success: res => {
console.log(res, '位置信息--')
this.demoAddress = res
const { latitude, longitude } = res
// const { province, city, district, street, streetNum, poiName } = res.address
2024-11-07 15:45:24 +08:00
2024-11-07 20:21:02 +08:00
uni.request({
url: `https://api.map.baidu.com/reverse_geocoding/v3/?ak=PM43nB8eDNTBrXkQwGrTQFcmOni3Z9nO&output=json&coordtype=gcj02ll&location=${latitude},${longitude}`,
method: 'GET',
// data: {
// ak: 'PM43nB8eDNTBrXkQwGrTQFcmOni3Z9nO',
// output: JSON,
// coordtype: 'gcj02ll',
// location: `${longitude},${latitude}`
// },
success: res => {
console.log('解析的地址', res)
this.submitParams.address = res.data.result.formatted_address
}
})
2024-11-12 13:10:59 +08:00
// console.log(longitude.toString().slice(0, 7), '-----')
2024-11-07 20:21:02 +08:00
2024-11-12 13:10:59 +08:00
this.submitParams.lon = longitude.length > 7 ? longitude.toString().slice(0, 7) : longitude
this.submitParams.lat = latitude.length > 6 ? longitude.toString().slice(0, 6) : latitude
2024-11-07 20:21:02 +08:00
// console.log(province, 'province')
// this.submitParams.address = `${province}${city}${district}${street}${streetNum}${poiName}`
},
fail: err => {
console.error('获取位置失败:', err)
uni.showToast({ title: '位置获取失败,请稍后尝试', icon: 'none' })
}
})
2024-11-07 15:45:24 +08:00
// uni.chooseLocation({
// success: function (res) {
// // this.demoAddress_2 = res
// console.log('获取位置--',res)
// // console.log('位置名称:' + res.name);
// // console.log('详细地址:' + res.address);
// // console.log('纬度:' + res.latitude);
// // console.log('经度:' + res.longitude);
// }
// })
2024-11-01 18:15:33 +08:00
const _this = this
uni.$on('update', function (data) {
// this_.getViewDataList()
console.log(data, '传递的数据')
const { proId, proName, zynr, fxdj, fxdjName } = data
_this.submitParams.zynr = zynr
_this.submitParams.fxdj = fxdj
_this.submitParams.proName = proName
_this.submitParams.fxdjName = fxdjName
_this.submitParams.proId = proId
_this.riskInfo = data
const remark = `(${uni.getStorageSync('wkName')})${_this
.$moment()
.format('YYYY-MM-DD')}到${proName},现场监护${fxdjName}作业实施`
_this.submitParams.remark = remark
})
},
onUnload() {
uni.$off('update')
},
2024-10-23 11:35:25 +08:00
onReady() {
let that = this
uni.getSystemInfo({
//调用uni-app接口获取屏幕高度
success(res) {
//成功回调函数
that._data.pH = res.windowHeight //windoHeight为窗口高度主要使用的是这个
console.log('res.windowHeight窗口高度', res.windowHeight)
let titleH = uni.createSelectorQuery().select('.scroll-view-y') //想要获取高度的元素名class/id
titleH
.boundingClientRect(data => {
let pH = that._data.pH
that._data.navHeight = pH - data.top //计算高度:元素高度=窗口高度-元素距离顶部的距离data.top
console.log('that._data.navHeight', that._data.navHeight)
})
.exec()
}
})
}
}
2024-10-23 09:10:06 +08:00
</script>
2024-10-23 11:35:25 +08:00
<style lang="scss" scoped>
.custody-container {
// background-color: #ccc;
.header-btn {
display: flex;
background-color: #fff;
view {
flex: 1;
padding: 30rpx 0;
color: #a8a8ad;
font-size: 36rpx;
text-align: center;
transition: all 0.3s ease;
}
.active {
color: #043372;
border-bottom: 2px solid #043372;
}
}
.swiper-item-content {
background-color: #efefef;
}
.scroll-view-y {
width: 100%;
background-color: #efefef;
.title-bold {
font-size: 32rpx;
font-weight: bold;
}
.risk-header {
width: 94%;
margin: 16rpx auto;
display: flex;
align-items: center;
background-color: #fff;
padding: 2rpx 14rpx;
border: 1px solid #ccc;
border-radius: 6rpx;
.risk-left {
padding: 10rpx;
border-radius: 10rpx;
background-color: #da0019;
color: #fff;
}
.risk-right {
margin-left: 6rpx;
}
}
.change-today {
width: 94%;
margin: 16rpx auto;
padding: 26rpx;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 6rpx;
.today-title {
display: flex;
justify-content: space-between;
align-items: center;
}
.today-title view:last-child {
padding: 26rpx 6rpx;
background-color: #d6001a;
border-radius: 20rpx;
color: #fff;
}
::v-deep .uni-forms-item__label {
font-weight: bold;
color: #000;
font-size: 26rpx;
}
}
.scene-container {
width: 94%;
margin: 16rpx auto;
padding: 26rpx;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 6rpx;
}
}
}
2024-11-01 18:15:33 +08:00
::v-deep .address-content {
position: relative;
.address-info {
position: absolute;
right: 0;
top: -30px;
2024-11-07 15:45:24 +08:00
display: flex;
align-items: center;
2024-11-01 18:15:33 +08:00
text {
2024-11-07 15:45:24 +08:00
margin-right: 16rpx;
2024-11-01 18:15:33 +08:00
}
}
}
.autograph {
position: relative;
.autograph-img-box {
width: 100%;
display: flex;
flex-wrap: wrap;
.view-autograph {
width: 100%;
height: 180rpx;
}
view {
width: 30%;
margin-left: 5%;
margin-top: 20rpx !important;
height: 180rpx;
background-color: #eee;
border: 1px solid #ccc;
box-sizing: border-box;
position: relative;
.delete-icon {
position: absolute;
top: 3rpx;
right: 3rpx;
}
}
}
.autograph-img-box view:nth-child(3n + 1) {
margin: 0;
}
}
.open-box {
position: absolute;
right: 0;
top: -68rpx;
// width: 140rpx;
height: 68rpx;
padding: 0 10rpx;
line-height: 68rpx;
text-align: center;
background-color: #003777;
color: #fff;
}
.autograph-container {
width: 95vw;
height: 50vh;
padding-bottom: 18rpx;
background-color: #fff;
display: flex;
flex-direction: column;
.autograph-btn {
width: 100%;
display: flex;
justify-content: center;
padding: 12rpx 0;
view {
width: 15%;
height: 62rpx;
border-radius: 12rpx;
border: 1px solid $u-primary;
color: $u-primary;
line-height: 62rpx;
text-align: center;
}
}
.autograph-area {
width: 94%;
margin: 0 auto;
padding: 10rpx 0;
}
.autograph-area-box {
margin: 0 auto;
width: 94%;
flex: 1;
border: 1px solid #fa3534;
}
}
.submit-btn {
width: 96%;
height: 78rpx;
margin: 0 auto;
border-radius: 14rpx;
background-color: #003777;
font-size: 26rpx;
text-align: center;
line-height: 78rpx;
color: #fff;
}
.my-data-header-container,
.my-data-container {
width: 96%;
margin: 16rpx auto 20rpx;
padding: 12rpx 0;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 10prx;
}
.my-data-header {
width: 96%;
margin: 0 auto;
display: flex;
justify-content: space-around;
align-items: center;
2024-11-07 11:25:10 +08:00
.search-img {
width: 68rpx;
height: 68rpx;
margin-right: 10rpx;
// margin-left: 30rpx;
background: url('../../../static/images/workPlan/search.png') no-repeat;
background-size: 100% 100%;
}
2024-11-01 18:15:33 +08:00
}
.my-data-content {
width: 96%;
margin: 0 auto 15rpx;
padding: 15rpx 0;
border: 1px solid #ccc;
border-radius: 6prx;
.data-risk {
display: flex;
justify-content: space-between;
padding: 10rpx;
}
.pro-name-box {
padding: 10rpx;
}
.pro-content {
width: 98%;
margin: 0 auto;
// padding: 15rpx 10rpx;
border: 1px solid #ccc;
border-radius: 6rpx;
}
}
2024-10-23 11:35:25 +08:00
</style>