<script setup lang="ts"> import { toRaw, ref, computed } from 'vue' import { formatDate } from '@/utils/index' import { onLoad, onShow } from '@dcloudio/uni-app' import { useLoginStore } from '@/stores/modules/login' import { getTaskRepotPageAPI, getTaskDetailAPI, postOperateAPI,postOperateAPIEnd } from '@/services/pgMaster' const popup = ref<UniHelper.UniPopupInstance>() const userStore = useLoginStore() const dictInfo = userStore?.dictInfo || [] const unitDictData = dictInfo.filter(e => e.dictType == 'heli_material_unit') || [] const userId = userStore.userInfo.userId const isShowStart = computed(() => { let flag = true if (historyList.value.length) { const obj = historyList.value[0] if (!obj?.endTime) { flag = false } } // // 派工数量和总报工数量相等了就不展示开始生产 // if (detailInfo.value.amount == detailInfo.value.totalReportAmount) { // flag = false // } return flag }) const isShowEnd = computed(() => { let flag = true if (historyList.value.length) { const obj = historyList.value[0] if (obj?.endTime) { flag = false } } else { flag = false } return flag }) const productionTitle = ref('开始生产') const amount = ref('') const workTime = ref('') // 详情数据 const detailInfo = ref({}) let isLoading = ref(false) const historyList = ref([]) const formObj = ref({}) // 历史明细 const getData = async () => { // 发送请求 isLoading.value = true const params = { pageNo: 1, integerpageSize: 5, bgUser: userId, zjMxId: detailInfo.value.id, } const data = await getTaskRepotPageAPI(params) data.list.forEach((e) => { e.startTimeStr = e.startTime && formatDate(e.startTime, 'YYYY-MM-DD HH:mm') e.endTimeStr = e.endTime && formatDate(e.endTime, 'YYYY-MM-DD HH:mm') e.bgTime = e.bgTime && formatDate(e.bgTime, 'YYYY-MM-DD HH:mm') e.entTime = e.entTime && formatDate(e.entTime, 'YYYY-MM-DD HH:mm') }) if (data.list[0]) { formObj.value = data.list[0] const time = formObj.value.endTime - formObj.value.startTime //时间差秒 const leave1 = time % (24 * 3600 * 1000) //计算天数后剩余的毫秒数 workTime.value = Math.floor(leave1 / (3600 * 1000)) } historyList.value = data.list isLoading.value = false } // 详情 const getDetailData = async (id) => { // 发送请求 // isLoading.value = true const params = { id, } const data = await getTaskDetailAPI(params) data.startTime = formatDate(data.startTime, 'YYYY-MM-DD') data.entTime = formatDate(data.entTime, 'YYYY-MM-DD') // 单位枚举 const lineObj = unitDictData.find((q) => q.value == data.unit) || {} data.unit = lineObj.label detailInfo.value = data || {} isLoading.value = false } onLoad(async (options: any) => { await getDetailData(options.id) await getData() const obj = historyList.value[0] // 最新的报工是否完成 if (obj && obj?.workTime == null && obj.endTime) { popup.value?.open() } }) // 生产完成 const handleComplate = async () => { /* const params = { id: detailInfo.value?.id, active: 'FINISH', ownerId: userId, } const data = await postOperateAPI(params) const url = `/pages/productionReport/productionReport-detail?id=${detailInfo.value.id}` uni.redirectTo({ url, }) */ } // 提交报工 const handleOk = async (active) => { const params = { zjMxId: detailInfo.value?.id, amount: amount.value, workTime: workTime.value, bgUser: userId, } const data = await postOperateAPIEnd(params) const url = `/pages/pgMaster/pgMaster-detail?id=${detailInfo.value.id}` uni.redirectTo({ url, }) } // 开始生产 const handleStart = async () => { const params = { zjMxId: detailInfo.value?.id, workTime: workTime.value, bgUser: userId, } const data = await postOperateAPI(params) const url = `/pages/pgMaster/pgMaster-detail?id=${detailInfo.value.id}` uni.redirectTo({ url, }) //popup.value.open(); /* const params = { id: detailInfo.value.id, active: 'START', ownerId: userId, } const data = await postOperateAPI(params) const url = `/pages/productionReport/productionReport-detail?id=${detailInfo.value.id}` uni.redirectTo({ url, }) productionTitle.value = '生产中' */ } // 结束生产 const handleStop = async () => { popup.value.open(); } </script> <template> <view class="data-detail"> <template v-if="!isLoading"> <view class="module"> <view class="module-info"> <view class="product-item">项目:{{detailInfo.projectName}}</view> <image src="/static/images/productionReport-page.png" class="product-img" mode="scaleToFill"></image> <view :class="[detailInfo.pgType == 1 ? 'had' : 'unhad', 'product-status']">{{ detailInfo.pgType == 1 ? '已完成' : '未完成' }}</view> <view class="product-item">子项目:{{ detailInfo.projectSubCode || '' }} {{' ' + detailInfo.projectSubName }} </view> <view class="product-item">模具名称:{{detailInfo.mouldName}}</view> <view class="product-row"> <view class="row-item"> <view class="label">派工数量</view> <view class="val">{{ detailInfo.amount }}</view> </view> </view> <view class="product-row"> <!-- <view class="row-item"> <view class="label">预计工时</view> <view class="val">{{ detailInfo.gongShi }}</view> </view> --> <view class="row-item"> <view class="label">总报工数量</view> <view class="val high-color">{{ detailInfo.amounts }}</view> </view> <view class="row-item"> <view class="label">总报工工时</view> <view class="val high-color">{{ detailInfo.workTime }}</view> </view> </view> <!-- <view class="product-item">预计生产日期:{{ detailInfo.startTime }} ~ {{ detailInfo.entTime }}</view> --> <view class="finish" v-if="isShowStart && detailInfo.procedureStatus !== 2 && detailInfo.totalWorkTime" @click="handleComplate"> <image class="complate-img" src="/static/images/productionReport-detail-complate.png" mode="scaleToFill" /> 生产完成 </view> </view> </view> <view class="module-list"> <view class="module-title">历史报工明细</view> <view class="history-list"> <view class="no-data" v-if="!historyList.length"> 无数据... </view> <template v-else> <view class="item" v-for="(item, index) in historyList" :key="item.id"> <view class="product-row"> <view class="row-item"> <view class="label">报工人:</view> <view class="val high-color">{{ item.userName }}</view> </view> </view> <view class="product-item">报工时间:{{ item.bgTime }}~{{item.entTime}}</view> <!-- <view class="product-item">生产结束时间:{{ item.endTimeStr }}</view> --> <view class="product-row"> <view class="row-item"> <view class="label">报工工时:</view> <view class="val high-color">{{ item.workTime }}</view> </view> <view class="row-item"> <view class="label">报工数量:</view> <view class="val high-color">{{ item.amount }}</view> </view> </view> <view class="tip-index"> <image src="/static/images/productionReport-detail-index.png" class="icon-status" mode="scaleToFit"> </image> <view class="text">{{historyList.length - index}}</view> </view> </view> </template> </view> </view> <view class="action" v-if="detailInfo.pgType !== 1"> <view class="action-item start" v-if="detailInfo.active != 'START'" @click="handleStart">开始报工</view> <view class="action-item stop" v-if="detailInfo.active == 'START'" @click="handleStop">结束报工</view> </view> </template> <view class="loading-text" v-else>加载中..</view> <uni-popup class="popup" ref="popup" :mask-click="false" type="bottom" background-color="#fff"> <view class="title"> <view class="text">填写信息</view> <!-- <view class="close" @click="handleClose">X</view> --> </view> <view class="cont"> <view class="item"> <view class="label">过程检开始时间:</view> <view class="val">{{ formObj.startTime }}</view> </view> <view class="item"> <view class="label">过程检结束时间:</view> <view class="val">{{ formObj.endTime }}</view> </view> <view class="item"> <view class="label"><span class="star">*</span>本次报工工时:</view> <uni-easyinput class="val" type="digit" v-model="workTime" placeholder="请输入本次报工工时"></uni-easyinput> <view class="unit">小时</view> </view> <view class="item"> <view class="label"><span class="star">*</span>本次报工数量:</view> <uni-easyinput class="val" type="number" v-model="amount" placeholder="请输入本次报工数量"></uni-easyinput> <view class="unit"> {{ detailInfo.unit }}</view> </view> </view> <view class="ok" @click="handleOk">确定</view> </uni-popup> </view> </template> <style lang="scss"> // 订单列表 .data-detail { border-radius: 10rpx; padding-bottom: 200rpx; .module { background: linear-gradient(178deg, #356899 7%, #356899 57%, #F4F6F9 94%); padding: 20rpx; .module-info { padding: 20rpx 20rpx 80rpx; border-radius: 10rpx; min-height: 100rpx; font-size: 28rpx; border-bottom: 2rpx solid #F2F2F2; background: linear-gradient(215deg, #C7D3E5 8%, rgba(222, 228, 236, 0) 13%), linear-gradient(162deg, #FFFFFF 25%, #E4EFFD 106%); position: relative; border-top-right-radius: 100rpx; .product-img { position: absolute; right: 0rpx; top: 0; width: 100rpx; height: 100rpx; } .product-status { width: 140rpx; border-raduis: 10rpx; text-align: center; padding: 8rpx 12rpx; &.had { background: #E8FFEA; color: #00B42A; } &.unhad { background: #FFF7E8; color: #FF7D00; } } .product-item { margin: 20rpx 0; display: flex; align-items: center; color: #737D88 } .product-row { margin: 20rpx 0; display: flex; flex-direction: row; justify-content: space-between; color: #737D88; .row-item { flex: 1; .label { margin-bottom: 10rpx; } .val { color: #1D2129; &.high-color { color: #00B42A } } } } .finish { position: absolute; right: 40rpx; bottom: 30rpx; background: linear-gradient(142deg, #FEB34A 14%, #FE9B12 83%); color: #fff; width: 200rpx; text-align: center; padding: 10rpx; border-radius: 31rpx; display: flex; align-items: center; justify-content: center; .complate-img { width: 30rpx; height: 30rpx; margin-right: 10rpx; } } } } .module-list { padding: 20rpx 20rpx; // box-shadow: 0px 0px 8px 0px rgba(161, 161, 177, 0.12); .module-title { color: #0D0D26; font-size: 36rpx; margin: 20rpx 0; font-weight: 500; } .history-list { display: flex; flex-direction: column; align-items: center; min-height: 200rpx; justify-content: center; padding: 0rpx 10rpx; .item { margin: 10rpx 0; background: #EAEEF4; font-size: 28rpx; padding: 20rpx; width: 100%; border-radius: 10rpx; color: #737D88; position: relative; .product-item { margin: 10rpx 0; .hight-color { color: #00B42A; } } .product-row { margin: 20rpx 0; display: flex; flex-direction: row; justify-content: space-between; color: #737D88; .row-item { flex: 1; display: flex; flex-direction: row; .label { margin-bottom: 10rpx; &.high-color { color: #00B42A } } .val { color: #1D2129; &.high-color { color: #00B42A } } } } .tip-index { position: absolute; top: 0rpx; right: 0rpx; .icon-status { width: 100rpx; height: 72rpx; z-index: 1; } .text { color: #fff; position: absolute; top: 4rpx; right: 30rpx; z-index: 2; } } } .no-data { font-size: 28rpx; color: #444; } } .table-cont { font-size: 24rpx; } .button { color: #356899; } } .action { display: flex; justify-content: center; align-items: center; position: fixed; bottom: 0rpx; border-radius: 18rpx; padding: 30rpx 30rpx; background: #FFFFFF; margin: 0 auto; width: 100vw; box-shadow: 0px -4px 10px 0px rgba(121, 153, 183, 0.2); .action-item { width: 272rpx; height: 86rpx; display: flex; justify-content: center; align-items: center; margin: 0 20rpx; font-size: 40rpx; color: #fff; width: 272rpx; height: 86rpx; border-radius: 24rpx; &.start { background: linear-gradient(157deg, #2EACE6 -3%, #356899 90%); } &.stop { background: linear-gradient(167deg, #FEA97B -2%, #F75E40 87%); } &.finish { background: linear-gradient(142deg, #FEB34A 14%, #FE9B12 83%); } } } .loading-text { text-align: center; font-size: 28rpx; color: #666; padding: 20rpx 0; } .popup { .title { line-height: 1; padding: 40rpx; font-size: 32rpx; font-weight: normal; border-bottom: 1rpx solid #ddd; color: #444; .close { position: absolute; right: 24rpx; top: 40rpx; height: 60rpx; width: 60rpx; text-align: center; } } .cont { display: flex; flex-direction: column; align-items: center; margin: 40rpx; height: 50vh; .item { display: flex; align-items: center; margin: 20rpx 0; color: #737D88; width: 94%; .label { font-size: 32rpx; width: 260rpx; .star { color: red } } .val { flex: 1; font-size: 32rpx; } .unit { width: 100rpx; margin-left: 4rpx; text-align: center; } } } .ok { font-size: 32rpx; margin: 20rpx auto 80rpx; text-align: center; width: 200rpx; border-radius: 10rpx; padding: 8rpx 0; background-color: #3C8AF7; color: #fff; } } } </style>