651 lines
17 KiB
Vue
651 lines
17 KiB
Vue
<template>
|
||
<view class="task">
|
||
<u-alert class="margin-bottom-20" type = "warning" description = "此页面数据项设置之后自动更新" :show-icon="true" :closable="true"></u-alert>
|
||
<view class="baseInfo">
|
||
|
||
<!-- 任务基本信息 -->
|
||
<view class="title">
|
||
<text class="taskName">{{baseInfo.taskName}}</text>
|
||
<u-tag @click="showPicker1=true" plain color="#fff" :text="baseInfo.status | transformStatusToText(typeList)" size="mini" :bgColor="baseInfo.status | transformTagColor()" :borderColor="baseInfo.status | transformTagColor()" ></u-tag>
|
||
</view>
|
||
<view class="content">
|
||
<u-row class="item">
|
||
<u-col span="6">
|
||
<view class="item">地块名称:{{baseInfo.landName?baseInfo.landName:"--"}}</view>
|
||
</u-col>
|
||
<u-col span="6">
|
||
<view class="item">批次名称:{{baseInfo.batchName}}</view>
|
||
</u-col>
|
||
</u-row>
|
||
<u-row class="item">
|
||
<u-col span="6">
|
||
<view class="item">开始时间:{{baseInfo.planStart}}</view>
|
||
</u-col>
|
||
<u-col span="6">
|
||
<view class="item">结束时间:{{baseInfo.planFinish}}</view>
|
||
</u-col>
|
||
</u-row>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 任务状态 -->
|
||
<view class="taskStatus" @click="showPicker1=true">
|
||
<view class="label">
|
||
<u-icon name="hourglass-half-fill" size="20" color="#2b7"></u-icon>
|
||
<text>任务状态</text>
|
||
</view>
|
||
<view class="status">
|
||
<text>{{baseInfo.status | transformStatusToText(typeList)}}</text>
|
||
<u-icon name="arrow-right"></u-icon>
|
||
</view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
<!-- 任务实际实际时间-->
|
||
<view class="actualTime" >
|
||
<view class="label">
|
||
<u-icon name="calendar-fill" size="20" color="#2b7"></u-icon>
|
||
<text>任务实际开始结束时间</text>
|
||
</view>
|
||
<view class="content">
|
||
<u-tag plain color="#2b7" borderColor="#2b7" @click="showDate1=true" :text="`开始时间:${baseInfo.actualStart?baseInfo.actualStart:'未设置'}`"></u-tag>
|
||
<u-tag plain color="#2b7" borderColor="#2b7" @click="showDate2=true" :text="`结束时间:${baseInfo.actualFinish?baseInfo.actualFinish:'未设置'}`"></u-tag>
|
||
</view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 责任人 -->
|
||
<view class="header" @click="showPicker2=true">
|
||
<view class="label">
|
||
<u-icon name="account-fill" size="20" color="#2b7"></u-icon>
|
||
<text>责任人</text>
|
||
</view>
|
||
<view class="name">
|
||
<u-avatar class="avatar" :text="baseInfo.taskHead | transformHeadFirstName(employeeList)" size="24" fontSize="12" bgColor="#2b7"></u-avatar>
|
||
<u-icon name="arrow-right"></u-icon>
|
||
</view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 任务内容 -->
|
||
<view class="taskdetail">
|
||
<view class="label">
|
||
<u-icon name="file-text-fill" size="20" color="#2b7"></u-icon>
|
||
<text>任务内容</text>
|
||
</view>
|
||
<u-textarea class="margin-top-20" v-model="baseInfo.remark" placeholder="请输入内容" @blur="changeBaseInfo" height="200rpx"></u-textarea>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 参与人 -->
|
||
<view class="participants" @click="selectEmployee">
|
||
<view class="label">
|
||
<u-icon name="plus-people-fill" size="20" color="#2b7"></u-icon>
|
||
<text>参与人</text>
|
||
</view>
|
||
<view class="member">
|
||
<scroll-view :scroll-x="true" style="display: flex;">
|
||
<view class="memberList">
|
||
<u-avatar class="avatar" bgColor="#2b7" size="24" fontSize="12" v-for="(item,index) in taskEmployeeList"
|
||
:key="index" :text="item.employeeName.slice(0,1)"></u-avatar>
|
||
</view>
|
||
</scroll-view>
|
||
<u-icon name="arrow-right" ></u-icon>
|
||
</view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 人工工时 -->
|
||
<view class="workHours" @click="jump('employeeWorkHours')">
|
||
<view class="label">
|
||
<u-icon name="man-add-fill" size="25" color="#2b7"></u-icon>
|
||
<text>人工工时</text>
|
||
<text class="margin-left-20 font-weight-bold">{{workHour}}小时</text>
|
||
</view>
|
||
|
||
<view class="content">工时详情<u-icon name="arrow-right" class="margin-left-20"></u-icon></view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 机械工时 -->
|
||
<view class="workHours" @click="jump('machineWorkHours')">
|
||
<view class="label">
|
||
<u-icon name="car-fill" size="25" color="#2b7"></u-icon>
|
||
<text>机械工时</text>
|
||
<text class="margin-left-20 font-weight-bold">{{machineryHour}}小时</text>
|
||
</view>
|
||
<view class="content">工时详情<u-icon name="arrow-right" class="margin-left-20"></u-icon></view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 农资用量 -->
|
||
<view class="consume" @click="jump('materialUsedCount')">
|
||
<view class="label">
|
||
<view class="flex">
|
||
<u-icon name="bag-fill" size="20" color="#2b7"></u-icon>
|
||
<text>农资用量</text>
|
||
</view>
|
||
<u-icon name="arrow-right" class="margin-left-20"></u-icon>
|
||
</view>
|
||
<view class="content">
|
||
<!-- 微信小程序,开发工具图表会显示最上层,但是真机没有问题,无需在意 -->
|
||
<qiun-data-charts :canvas2d="true" canvasId="BleFwOHudClAKDffjpTSNNSnIWLnNHPM" type="column" :opts="opts" :chartData="chartData" :tooltipShow="false" :ontouch="true"/>
|
||
</view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 图片 -->
|
||
<view class="image">
|
||
<view class="label">
|
||
<u-icon name="camera-fill" size="20" color="#2b7"></u-icon>
|
||
<text>图片</text>
|
||
</view>
|
||
<view class="content">
|
||
<image-upload v-model="baseInfo.taskImages" :maxSize="2"></image-upload>
|
||
</view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 视频 -->
|
||
<view class="video">
|
||
<view class="label">
|
||
<u-icon name="play-right-fill" size="20" color="#2b7"></u-icon>
|
||
<text>视频</text>
|
||
</view>
|
||
<view class="content">
|
||
<video-upload v-model="baseInfo.taskVideos" :maxCount="2" :maxSize="5"></video-upload>
|
||
</view>
|
||
</view>
|
||
<u-gap height="10" bgColor="#eee"></u-gap>
|
||
|
||
<!-- 日志 -->
|
||
<view class="log">
|
||
<view class="label" @click="logVisiable=!logVisiable">
|
||
<view class="flex">
|
||
<u-icon name="info-circle-fill" size="20" color="#2b7"></u-icon>
|
||
<text>任务日志</text>
|
||
</view>
|
||
<u-icon :name="!logVisiable?'arrow-down':'arrow-up'"></u-icon>
|
||
</view>
|
||
<view class="content" v-if="logVisiable">
|
||
<view v-for="item in logList" :key="item.operId">
|
||
<text style="color: #2b7">{{item.createTime}}</text>:由 <text style="color: #ffba00;">{{item.operName}}</text>{{item.operDes}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 兼容ios微信浏览器的margin-bottom无效的情况 -->
|
||
<view class="height-30"></view>
|
||
|
||
<!-- 任务状态和负责人选择控件 -->
|
||
<u-picker :show="showPicker1" :columns="[typeList]" keyName='dictLabel' @confirm="confirmPicker($event,1)" @cancel="showPicker1=false"></u-picker>
|
||
<u-picker :show="showPicker2" :columns="[employeeList]" keyName='employeeName' @confirm="confirmPicker($event,2)" @cancel="showPicker2=false"></u-picker>
|
||
|
||
<!-- 时间选择控件 -->
|
||
<u-datetime-picker :show="showDate1" @cancel="showDate1=false" v-model="todayDate" mode="date" @confirm="confirmDatePicker($event,1)"></u-datetime-picker>
|
||
<u-datetime-picker :show="showDate2" @cancel="showDate2=false" v-model="todayDate" mode="date" @confirm="confirmDatePicker($event,2)"></u-datetime-picker>
|
||
|
||
<u-toast ref="uToast"></u-toast>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
//任务ID
|
||
taskId:null,
|
||
//任务信息
|
||
baseInfo:{},
|
||
//任务状态列表
|
||
typeList:[],
|
||
//参与任务雇员列表
|
||
taskEmployeeList:[],
|
||
//雇员列表
|
||
employeeList:[],
|
||
showPicker1:false,
|
||
showPicker2:false,
|
||
showDate1:false,
|
||
showDate2:false,
|
||
//设置日期选择控件定位到当天
|
||
todayDate: Number(new Date()),
|
||
//是否监听图片的第一次值的变化
|
||
isWatchPicChanges:false,
|
||
//是否监听视频的第一次值的变化
|
||
isWatchVideoChanges:false,
|
||
//任务日志列表
|
||
logList:[],
|
||
//人工工时统计
|
||
workHour:0,
|
||
//机械工时统计
|
||
machineryHour:0,
|
||
//农资统计图标数据
|
||
chartData: {},
|
||
//图标配置数据项
|
||
opts: {
|
||
color: ["#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],
|
||
padding: [15,15,0,5],
|
||
touchMoveLimit: 24,
|
||
enableScroll: true,
|
||
legend: {
|
||
show:false
|
||
},
|
||
xAxis: {
|
||
disableGrid: true,
|
||
scrollShow: true,
|
||
itemCount: 4,
|
||
},
|
||
yAxis: {},
|
||
extra: {
|
||
column: {
|
||
type: "group",
|
||
width: 10,
|
||
activeBgColor: "#000000",
|
||
activeBgOpacity: 0.08,
|
||
linearType: "custom",
|
||
barBorderCircle: true,
|
||
}
|
||
}
|
||
},
|
||
//控制日志的折叠参数
|
||
logVisiable:false
|
||
}
|
||
},
|
||
onLoad(option) {
|
||
this.taskId = option?.taskId;
|
||
this.getData();
|
||
},
|
||
async onPullDownRefresh() {
|
||
//this.getData()等所有的promise resolve了之后才resolve
|
||
await this.getData();
|
||
uni.stopPullDownRefresh();
|
||
},
|
||
onShow() {
|
||
this.getData();
|
||
},
|
||
watch:{
|
||
//监听上传图片触发保存
|
||
"baseInfo.taskImages":{
|
||
handler(val){
|
||
if(this.isWatchPicChanges){
|
||
this.changeBaseInfo("taskImages",val)
|
||
}
|
||
this.isWatchPicChanges=true
|
||
}
|
||
},
|
||
//监听上传视频触发保存
|
||
"baseInfo.taskVideos":{
|
||
handler(val){
|
||
if(this.isWatchVideoChanges){
|
||
this.changeBaseInfo("taskVideos",val)
|
||
}
|
||
this.isWatchVideoChanges=true
|
||
}
|
||
}
|
||
},
|
||
filters:{
|
||
//将任务状态值翻译成名称
|
||
transformStatusToText(val,typeList){
|
||
let name="--"
|
||
typeList.forEach((item,index)=>{
|
||
if(item.dictValue==val){
|
||
name = item.dictLabel
|
||
}
|
||
})
|
||
return name
|
||
},
|
||
//将任务状态值翻译成任务Tag的颜色
|
||
transformTagColor(val){
|
||
let color = ""
|
||
if(val==0){
|
||
color="#dadada"
|
||
}else if(val==1){
|
||
color="#fc842d"
|
||
}else if(val==2){
|
||
color="#ead900"
|
||
}else if(val==3){
|
||
color="#2b7"
|
||
}else{
|
||
color="#636363"
|
||
}
|
||
return color;
|
||
},
|
||
//将任务负责人ID翻译成姓
|
||
transformHeadFirstName(val,employeeList){
|
||
let firstName=""
|
||
employeeList.forEach((item,index)=>{
|
||
if(item.employeeId==val){
|
||
firstName = item.employeeName
|
||
}
|
||
})
|
||
firstName=firstName[0]
|
||
return firstName
|
||
}
|
||
},
|
||
methods:{
|
||
//统一调用查询数据接口
|
||
getData(){
|
||
Promise.all([
|
||
//获取任务详情
|
||
this.getTask(),
|
||
//查询参与任务的雇员
|
||
this.getTaskEmployeeList(),
|
||
//查询任务日志
|
||
this.getTaskLogList(),
|
||
//统计人工工时
|
||
this.getCostEmployeeListToCountHours(),
|
||
//统计机械工时
|
||
this.getCostMachineListToCountHours(),
|
||
//农资用量
|
||
this.loadMaterialMap(),
|
||
//获取字典
|
||
this.getDic(),
|
||
//查询雇员列表
|
||
this.getEmployeeList()
|
||
])
|
||
},
|
||
//根据任务ID查询任务详情
|
||
async getTask(){
|
||
const {data} = await uni.$u.http.get("/agriculture/batchTask/"+this.taskId)
|
||
this.baseInfo = data;
|
||
},
|
||
//根据任务ID查看任务雇员
|
||
async getTaskEmployeeList(){
|
||
const {rows} = await uni.$u.http.get('/agriculture/taskEmployee/list?taskId='+this.taskId);
|
||
this.taskEmployeeList=rows
|
||
},
|
||
//根据任务ID查询任务日志
|
||
async getTaskLogList(){
|
||
const {rows} = await uni.$u.http.get('/agriculture/log/list?taskId='+this.taskId)
|
||
this.logList=rows;
|
||
},
|
||
//根据任务ID加载农资用量图标
|
||
async loadMaterialMap(){
|
||
const {data} = await uni.$u.http.get('/agriculture/costMaterial/selectMaterialGroupByMaterialName/'+this.taskId);
|
||
let chartData = {
|
||
categories: data.map(item=>item.materialName),
|
||
series: [
|
||
{
|
||
name: "农资用量",
|
||
data: data.map(item=>item.num)
|
||
}
|
||
]
|
||
};
|
||
this.chartData = JSON.parse(JSON.stringify(chartData));
|
||
},
|
||
//根据任务ID查询人工工时列表,然后统计总工时
|
||
async getCostEmployeeListToCountHours(){
|
||
const {rows} = await uni.$u.http.get('/agriculture/costEmployee/list?taskId='+this.taskId)
|
||
//先清空
|
||
this.workHour=0;
|
||
rows.forEach(item=>{
|
||
this.workHour+=item.workingHours;
|
||
})
|
||
},
|
||
//根据任务ID查询机械工时列表,然后统计总工时
|
||
async getCostMachineListToCountHours(){
|
||
const {rows} = await uni.$u.http.get('/agriculture/costMachine/list?taskId='+this.taskId)
|
||
//先清空
|
||
this.machineryHour=0;
|
||
rows.forEach(item=>{
|
||
this.machineryHour+=item.workingHours
|
||
})
|
||
},
|
||
//获取字典
|
||
async getDic(){
|
||
const {data} = await uni.$u.http.get('/system/dict/data/type/agriculture_batch_task_status')
|
||
this.typeList=data
|
||
},
|
||
//查询雇员列表
|
||
async getEmployeeList(){
|
||
const {rows} = await uni.$u.http.get('/agriculture/employee/list')
|
||
this.employeeList=rows;
|
||
},
|
||
//保存任务修改数据
|
||
changeBaseInfo(key,value){
|
||
let query={
|
||
...this.baseInfo
|
||
}
|
||
if(key&&value){
|
||
query[key]=value
|
||
}
|
||
uni.$u.http.put('/agriculture/batchTask',query).then(res=>{
|
||
this.baseInfo[key]=value
|
||
this.$refs.uToast.show({
|
||
type: 'success',
|
||
message: "修改成功",
|
||
duration:'500'
|
||
})
|
||
})
|
||
},
|
||
//状态选择和责任人选择控件的确认事件
|
||
confirmPicker(data,type){
|
||
if(type==1){
|
||
this.changeBaseInfo('status',data.value[0].dictValue)
|
||
this.showPicker1=false
|
||
}else if(type==2){
|
||
this.changeBaseInfo('taskHead',data.value[0].employeeId)
|
||
this.showPicker2=false
|
||
}
|
||
},
|
||
//日期选择控件确认事件
|
||
confirmDatePicker(data,type){
|
||
if(type==1){
|
||
this.changeBaseInfo('actualStart',uni.$u.timeFormat(data.value, 'yyyy-mm-dd'))
|
||
this.showDate1=false
|
||
}else if(type==2){
|
||
this.changeBaseInfo('actualFinish',uni.$u.timeFormat(data.value, 'yyyy-mm-dd'))
|
||
this.showDate2=false
|
||
}
|
||
},
|
||
//处理参与人员选择
|
||
selectEmployee(){
|
||
uni.$u.route({
|
||
url: 'pages/farm/detail/employee',
|
||
params: {
|
||
taskId: this.baseInfo.taskId
|
||
}
|
||
})
|
||
},
|
||
//页面跳转
|
||
jump(pageName){
|
||
console.log(this.taskId)
|
||
uni.$u.route({
|
||
url: 'pages/farm/detail/'+pageName,
|
||
params: {
|
||
taskId:this.taskId
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.task{
|
||
// padding:0 10rpx;
|
||
background-color: #eee;
|
||
.baseInfo{
|
||
background: #fff;
|
||
.title{
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
padding:0 20rpx;
|
||
height:80rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
.taskName{
|
||
font-size: 40rpx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
.content{
|
||
box-sizing: border-box;
|
||
.item{
|
||
font-size: 25rpx;
|
||
padding:10rpx;
|
||
}
|
||
}
|
||
.taskdetail{
|
||
padding: 20rpx;
|
||
box-sizing: border-box;
|
||
.label{
|
||
display: flex;
|
||
}
|
||
}
|
||
.taskStatus{
|
||
padding: 20rpx;
|
||
box-sizing: border-box;
|
||
height: 120rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
.label{
|
||
display: flex;
|
||
width: 30%;
|
||
}
|
||
.status{
|
||
max-width: 70%;
|
||
display: flex;
|
||
text{
|
||
margin-right: 20rpx;
|
||
font-color:#eee;
|
||
font-size:25rpx;
|
||
}
|
||
|
||
}
|
||
}
|
||
.actualTime{
|
||
padding: 20rpx 20rpx 0;
|
||
box-sizing: border-box;
|
||
.label{
|
||
display: flex;
|
||
}
|
||
.content{
|
||
display: flex;
|
||
padding:20rpx 0;
|
||
justify-content: space-between;
|
||
view{
|
||
flex:0 0 auto;//不放大也不缩写
|
||
}
|
||
}
|
||
}
|
||
|
||
.header{
|
||
padding: 20rpx;
|
||
box-sizing: border-box;
|
||
height: 120rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
.label{
|
||
display: flex;
|
||
width: 30%;
|
||
}
|
||
.name{
|
||
max-width: 70%;
|
||
display: flex;
|
||
.avatar{
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
}
|
||
}
|
||
.participants{
|
||
padding: 20rpx;
|
||
box-sizing: border-box;
|
||
height: 120rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
.label{
|
||
width: 30%;
|
||
display: flex;
|
||
}
|
||
.member{
|
||
max-width: 70%;
|
||
display: flex;
|
||
.memberList{
|
||
display: flex;
|
||
.avatar{
|
||
margin-right: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.workHours{
|
||
padding: 20rpx;
|
||
box-sizing: border-box;
|
||
height: 120rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
.label{
|
||
width: 50%;
|
||
display: flex;
|
||
}
|
||
.content{
|
||
display:flex;
|
||
font-size: 25rpx;
|
||
}
|
||
}
|
||
.consume{
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
.label{
|
||
padding:20rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
.content{
|
||
height: 300rpx;
|
||
box-sizing: border-box;
|
||
padding:0 20rpx 20rpx;
|
||
}
|
||
}
|
||
.image{
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
.label{
|
||
padding:20rpx;
|
||
display:flex;
|
||
}
|
||
.content{
|
||
box-sizing: border-box;
|
||
padding:0 20rpx 0rpx;
|
||
}
|
||
}
|
||
.video{
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
.label{
|
||
padding:20rpx;
|
||
display: flex;
|
||
}
|
||
.content{
|
||
box-sizing: border-box;
|
||
padding:0 20rpx 20rpx;
|
||
}
|
||
}
|
||
.log{
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
.label{
|
||
padding:20rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
.content{
|
||
box-sizing: border-box;
|
||
padding:0 20rpx 20rpx;
|
||
font-size:24rpx;
|
||
view{
|
||
line-height: 40rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|