【前端】云工厂的纸掌柜app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

775 lines
23 KiB

<template>
<view>
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="订单详情"></uni-nav-bar>
<view class="status-area flex-row-center-start">
<image class="flex-base" style="width: 40rpx; height: 40rpx; margin-right: 16rpx" src="/static/imgs/order/status-icon.png"></image>
<text style="font-size: 30rpx; color: #ffffff">{{ supplierOrderStatusMap[orderInfo.status] || '-' }}</text>
</view>
<view class="address-area">
<view class="flex-row-start-start" style="padding: 24rpx 0 40rpx">
<image class="flex-base" style="width: 100rpx; height: 100rpx; margin-right: 20rpx" src="/static/imgs/order/customer-default.png"></image>
<view class="flex-col-start-start">
<text style="font-size: 30rpx; color: #333333; font-weight: 600">{{ orderInfo.customerEnterpriseName }}</text>
<text style="font-size: 26rpx; color: #333333; margin-top: 26rpx">送货时间: {{ orderInfo.receivedTime || '-' }}</text>
</view>
</view>
<view class="flex-row-start-start footer" style="margin-bottom: 0">
<image style="width: 32rpx; height: 32rpx; margin-right: 10rpx" src="/static/imgs/order/location-icon.png"></image>
<text style="font-size: 26rpx; color: #333333; word-break: break-all">
联系人: {{ `${orderInfo.deliveryAddress.receiver || '-'} ${orderInfo.deliveryAddress.receiverMobile || '-'}` }}
</text>
</view>
<view class="flex-row-start-start footer">
<image style="width: 32rpx; height: 32rpx; margin-right: 10rpx" src="/static/imgs/order/location-icon.png"></image>
<text style="font-size: 26rpx; color: #333333; word-break: break-all">{{ transformAddress(orderInfo.deliveryAddress) }}</text>
</view>
</view>
<view v-for="(order, index) in orderInfo.orderItems" :key="order.productId">
<view style="background-color: #fff; padding-bottom: 20rpx">
<view class="order-header flex-row-start-space">
<text style="font-size: 30rpx; font-weight: 600; line-height: 1.2">
{{ `${order.brandName}${order.productName} | ${order.gramWeight}g | ${order.width}*${order.length} | ${order.pieceQuantity}张` }}
</text>
<view v-if="orderInfo.status == supplierOrderStatusEnum.WAIT_DELIVERY">
<view v-if="steps[index].length > 0 && steps[index][0].desc == '未完成'" class="button-item" @click="operatePaper(index, 'cut')">分切</view>
<view
v-else-if="steps[index].length > 0 && steps[index][steps[index].length - 2].desc == '未完成'"
class="button-item"
@click="showModal(order, index)"
>
出库
</view>
<view
v-else-if="steps[index].length > 0 && steps[index][steps[index].length - 1].desc == '未完成'"
class="button-item"
@click="operatePaper(index, 'send')"
>
发货
</view>
</view>
</view>
<view class="order-row flex-row-center-space">
<text>重量(吨):</text>
<text>{{ order.buyTon }}</text>
</view>
<view class="order-row flex-row-center-space">
<text>单价(元/吨):</text>
<text>{{ order.unitPrice }}</text>
</view>
<view class="order-row flex-row-center-space">
<text>小计(元):</text>
<text>{{ order.subtotal }}</text>
</view>
<view class="order-row flex-row-center-space" style="margin: 0">
<text>备注信息:{{ order.remark }}</text>
</view>
</view>
<view style="padding: 24rpx 10rpx" v-if="showSendImgs(orderInfo.status)">
<uni-steps
:options="steps[index]"
active-color="#1890FF"
:active="order.outboundProcessList.length > 0 ? order.outboundProcessList.length - 1 : -1"
></uni-steps>
</view>
</view>
<!-- 送货凭证 -->
<view v-if="showSendImgs(orderInfo.status)" class="footer" :style="showList.includes(`send`) ? '' : 'height:88rpx;'">
<view class="header flex-row-center-space">
<text style="font-size: 28rpx; font-weight: 600">送货凭证</text>
<view class="flex-row-center-end" @click="changeShowIndex('send')">
<text style="font-size: 28rpx; margin-right: 8rpx">{{ showList.includes(`send`) ? '收起' : '展开' }}</text>
<uni-icons :type="showList.includes(`send`) ? 'top' : 'bottom'" size="16"></uni-icons>
</view>
</view>
<view class="imgs flex-row-start-start">
<view v-for="item in orderInfo.proofDelivery" :key="item.id" class="upload_img">
<uni-icons type="clear" size="16" class="close-icon" @click="deleteVoucher(item.id)"></uni-icons>
<image style="width: 120rpx; height: 120rpx" :src="item.imgUrl"></image>
</view>
<view class="default-upload" @click="uploadVoucher()">
<image src="/static/imgs/order/camera.png" class="icon"></image>
<text style="font-size: 26rpx; color: #4c4a58">上传凭证</text>
</view>
</view>
</view>
<view class="fee flex-row-center-space">
<text style="font-size: 28rpx; color: #555555">其他费用: ¥{{ orderInfo.otherFee || 0 }}</text>
<view class="flex-row-center-end">
<text style="font-size: 28rpx; color: #555555">合计:</text>
<text style="font-size: 40rpx; color: #f5222d; font-weight: 600">¥{{ orderInfo.totalOfferPrice || 0 }}</text>
</view>
</view>
<view class="order-footer">
<view class="flex-row-center-space order-line">
<text class="label">是否开票</text>
<text class="value">{{ invoiceStatusMap[orderInfo.invoiceOrNot] || '开票' }}</text>
</view>
<view class="flex-row-center-space order-line">
<text class="label">订单备注</text>
<text class="value">{{ orderInfo.remark || '无' }}</text>
</view>
<view class="flex-row-center-space order-line">
<text class="label">订单编号</text>
<view class="flex-row-center-end value">
<text>{{ orderInfo.orderId }}</text>
<text style="color: #007aff; margin-left: 8rpx" @click="clip(orderInfo.orderId)">复制</text>
</view>
</view>
<view class="flex-row-center-space order-line">
<text class="label">下单时间</text>
<text class="value">{{ orderInfo.createTime }}</text>
</view>
<view class="flex-row-center-space order-line">
<text class="label">供应商</text>
<text class="value">{{ orderInfo.supplierEnterpriseName }}</text>
</view>
</view>
<qn-footer fixed height="120rpx" v-if="orderInfo.status === supplierOrderStatusEnum.WAIT_SUPPLIER_CONFIRM">
<view class="flex-row-center-space" style="padding: 0 32rpx">
<view class="button button_cancel" @click="cancel(orderInfo)">取消订单</view>
<view class="button button_confirm" @click="confirm(orderInfo)">确认订单</view>
</view>
</qn-footer>
<qn-footer fixed height="120rpx" v-if="showSendImgs(orderInfo.status)">
<view class="flex-row-center-end" style="padding: 0 32rpx">
<view class="button button_cancel" v-show="orderInfo.status === supplierOrderStatusEnum.WAIT_DELIVERY" style="width: 220rpx" @click="cancel">
取消订单
</view>
<view class="button button_contact" @click="viewContract">查看合同</view>
<view class="button button_confirm" v-show="orderInfo.status === supplierOrderStatusEnum.WAIT_CLIENT_PAY" @click="confirmWxpay" style="width: 220rpx">
确认微信收款
</view>
<view class="button button_confirm" v-show="orderInfo.status === supplierOrderStatusEnum.WAIT_DELIVERY" @click="delivery" style="width: 220rpx">
确认发货
</view>
<view
class="button button_confirm"
v-show="orderInfo.paymentMethod === paymentMethodEnum.MONTHLY_PAY && orderInfo.status === supplierOrderStatusEnum.WAIT_CLIENT_REPAY"
@click="confirmRepay"
style="width: 220rpx"
>
确认还款
</view>
</view>
</qn-footer>
<uni-popup ref="popup" type="bottom">
<view class="popup_modal">
<slot name="title">
<view class="popup_modal-title">请输入出库数量</view>
</slot>
<view style="width: 750rpx; padding: 20rpx 32rpx">
<qn-easyinput
:maxlength="8"
:styles="{ disableColor: '#fff' }"
v-model="outInfo.quantity"
text="left"
type="number"
:placeholder="`出库上线${outInfo.max}`"
></qn-easyinput>
</view>
<view class="flex-row-center-space" style="margin-top: 40rpx; width: 750rpx; padding: 0 32rpx">
<view class="button button__submit" @click="makeOut">
<text class="text" style="color: white">确认</text>
</view>
<view class="button button__cancel" @click="closeModal">
<text class="text">取消</text>
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { go2, back, uploadImage } from '@/utils/hook.js'
import {
getSupplierOrderDetail,
cancelSupplierOrder,
confirmSupplierOrder,
supplierOperatePaper,
supplierUploadVoucher,
supplierDelivery,
supplierDeleteVoucher,
supplierConfirmRepay,
supplierConfirmWxpay
} from '@/apis/orderApi.js'
import { supplierOrderStatusMap, supplierOrderStatusEnum, paymentMethodEnum, invoiceStatusMap } from '@/enums/index.js'
import { transformFileToImg } from '@/apis/commonApi.js'
export default {
data() {
return {
orderInfo: {
deliveryAddress: {},
supplierOrder: []
},
supplierOrderStatusMap: Object.freeze(supplierOrderStatusMap),
supplierOrderStatusEnum: Object.freeze(supplierOrderStatusEnum),
paymentMethodEnum: Object.freeze(paymentMethodEnum),
showList: ['send', 'receive'],
steps: [],
outInfo: {
quantity: 0,
max: 0,
index: 0
},
invoiceStatusMap: Object.freeze(invoiceStatusMap)
}
},
onLoad(option) {
if (option.orderId) {
this.init(option.orderId)
} else {
uni.showToast({
title: '订单信息错误',
icon: 'error',
success: () => {
setTimeout(() => {
back()
}, 2000)
}
})
}
},
methods: {
go2,
back,
showModal(order, index) {
// 计算已出库数
let quantity = 0
order.outboundProcessList.forEach((item) => {
if (item.status == '30302') {
quantity += item.quantity
}
})
this.outInfo.quantity = 0
this.outInfo.max = order.pieceQuantity - quantity
this.outInfo.index = index
this.$refs.popup.open('bottom')
},
closeModal() {
this.$refs.popup.close()
},
makeOut() {
// 校验
if (this.outInfo.quantity > this.outInfo.max) {
uni.showToast({
title: '出库数量不能大于上限',
icon: 'none'
})
return
}
this.operatePaper(this.outInfo.index, 'outbound', this.outInfo.quantity)
this.closeModal()
},
transformAddress(address) {
let res = ''
if (address.provinceName) {
res = `${address.provinceName}${address.cityName}${address.districtName}${address.detail}`
}
return res
},
init(orderId) {
getSupplierOrderDetail({
supplierOrderId: orderId
}).then((res) => {
if (res) {
this.orderInfo = res
for (let i = 0; i < this.orderInfo.orderItems.length; i++) {
let item = this.orderInfo.orderItems[i]
this.steps[i] = this.transformStep(item.outboundProcessList, item.pieceQuantity)
}
}
})
},
// 确定微信收款
confirmWxpay() {
uni.showModal({
title: '提示',
content: '确定已经收到微信款项?',
success: (res) => {
if (res.confirm) {
supplierConfirmWxpay({
supplierOrderId: this.orderInfo.orderId
}).then((res) => {
if (res) {
uni.showToast({
title: '确认成功',
icon: 'success'
})
this.init(this.orderInfo.orderId)
}
})
}
}
})
},
// 生成步骤条
transformStep(list, quantity) {
// 分切 出库 完成
let step1 = [],
step2 = [],
step3 = []
// 出库数量
let outboundQuantity = 0
if (list && list.length > 0) {
list.forEach((item) => {
if (item.userName && item.userName.length > 3) {
item.userName = item.userName.substr(0, 2) + '...'
}
if (item.status == '30301') {
step1.push({
title: '分切',
desc: item.userName + '\n\r' + item.createTime
})
} else if (item.status == '30302') {
step2.push({
title: '出库',
desc: item.userName + ' ' + item.quantity + '\n\r' + item.createTime
})
outboundQuantity += item.quantity
} else if (item.status == '30303') {
step3.push({
title: '完成',
desc: '已完成'
})
}
})
}
if (step1.length == 0) {
step1.push({
title: '分切',
desc: '未完成'
})
}
if (step2.length == 0) {
step2.push({
title: '出库',
desc: '未完成'
})
} else if (outboundQuantity < quantity) {
// 判断是否出库完成
step2.push({
title: '出库',
desc: '未完成'
})
}
if (step3.length == 0) {
step3.push({
title: '完成',
desc: '未完成'
})
}
return [...step1, ...step2, ...step3]
},
changeShowIndex(index) {
let target = this.showList.indexOf(index)
if (target > -1) {
this.showList.splice(target, 1)
} else {
this.showList.push(index)
}
},
// 根据状态是否展示送货凭证
showSendImgs(status) {
let list = [
supplierOrderStatusEnum.WAIT_DELIVERY,
supplierOrderStatusEnum.RECEIVED,
supplierOrderStatusEnum.WAIT_CLIENT_LOAN,
supplierOrderStatusEnum.PAYING,
supplierOrderStatusEnum.WAIT_CLIENT_PAY,
supplierOrderStatusEnum.PAY_FAIL,
supplierOrderStatusEnum.FINISHED,
supplierOrderStatusEnum.WAIT_CLIENT_REPAY,
supplierOrderStatusEnum.REPAYING,
supplierOrderStatusEnum.CANCELED
]
return list.includes(status)
},
// 取消订单
cancel(order) {
uni.showModal({
title: '提示',
content: '确定取消订单吗?',
success: (res) => {
if (res.confirm) {
cancelSupplierOrder({
supplierOrderId: order.orderId
}).then((result) => {
if (result) {
uni.showToast({
title: '取消订单成功',
icon: 'success',
success: () => {
setTimeout(() => {
back()
}, 2000)
}
})
}
})
}
}
})
},
// 确认订单
confirm(order) {
uni.showModal({
title: '提示',
content: '确定确认订单吗?',
success: (res) => {
if (res.confirm) {
confirmSupplierOrder({
orderId: order.orderId
}).then((result) => {
if (result) {
// #ifdef APP-PLUS
go2('page-view', { title: '供应商订单签约', url: encodeURIComponent(result.signUrl) })
// #endif
// #ifdef H5
if (window) {
window.location.href = result.signUrl
}
// #endif
}
})
}
}
})
},
// cut: 分切 outbound: 出库 send: 发货
operatePaper(index, type, quantity) {
const map = {
cut: 30301,
outbound: 30302,
send: 30303
}
let target = this.orderInfo.orderItems[index]
supplierOperatePaper({
quantity: quantity || target.pieceQuantity,
supplierOderItemId: target.supplierOderItemId,
status: map[type]
}).then((res) => {
if (res) {
uni.showToast({
title: '操作成功',
icon: 'success',
success: () => {
setTimeout(() => {
this.init(this.orderInfo.orderId)
}, 1000)
}
})
}
})
},
// 上传送货凭证
uploadVoucher() {
uploadImage(['album'], 5)
.then((urls) => {
if (urls) {
supplierUploadVoucher({
supplierOrderId: this.orderInfo.orderId,
proofDeliveryUrl: urls
}).then((res) => {
if (res) {
uni.showToast({
title: '上传成功',
icon: 'success',
success: () => {
setTimeout(() => {
this.init(this.orderInfo.orderId)
}, 1000)
}
})
}
})
}
})
.catch((e) => {
uni.showToast({
title: '上传失败',
icon: 'fail'
})
})
},
// 确认送货
delivery() {
uni.showModal({
title: '提示',
content: '确定确认送货吗?',
success: (res) => {
if (res.confirm) {
supplierDelivery({
supplierOrderId: this.orderInfo.orderId
}).then((success) => {
if (success) {
uni.showToast({
title: '确认送货成功',
icon: 'success',
success: () => {
setTimeout(() => {
this.init(this.orderInfo.orderId)
}, 1000)
}
})
}
})
}
}
})
},
// 查看合同
viewContract() {
let url = this.orderInfo.contractUrl
if (url) {
transformFileToImg({ fileUrl: url }).then((res) => {
uni.previewImage({ urls: [res.imgUrl], current: res.imgUrl })
})
}
},
// 删除送货凭证
deleteVoucher(id) {
supplierDeleteVoucher({ id }).then((res) => {
if (res) {
uni.showToast({
title: '删除成功',
icon: 'success',
success: () => {
setTimeout(() => {
this.init(this.orderInfo.orderId)
}, 1000)
}
})
}
})
},
// 确认月结还款
confirmRepay() {
uni.showModal({
title: '提示',
content: '确定确认还款吗?',
success: (res) => {
if (res.confirm) {
supplierConfirmRepay({
supplierOrderId: this.orderInfo.orderId
}).then((susses) => {
if (susses) {
uni.showToast({
title: '确认还款成功',
icon: 'success',
success: () => {
setTimeout(() => {
this.init(this.orderInfo.orderId)
}, 1000)
}
})
}
})
}
}
})
},
// 复制
clip(content) {
uni.setClipboardData({
data: content,
success: function () {
uni.showToast({
title: '复制成功',
icon: 'success',
duration: 2000
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.status-area {
padding: 24rpx 32rpx;
width: 750rpx;
background-image: linear-gradient(90deg, #ff4d2e 6%, #ff952f 100%);
}
.address-area {
padding: 0 32rpx;
width: 750rpx;
background-color: #ffffff;
.footer {
padding: 24rpx 0;
background-color: #ffffff;
border-top: 1px solid #e5e5e5;
}
}
.order-header {
padding: 24rpx 32rpx;
word-break: break-all;
background: #fff;
width: 750rpx;
border-bottom: 2rpx dashed #d8d8d8;
margin-bottom: 20rpx;
.button-item {
margin-left: 20rpx;
width: 108rpx;
height: 54rpx;
background: #007aff;
border-radius: 26rpx;
font-size: 28rpx;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
flex-grow: 0;
flex-shrink: 0;
}
}
.order-row {
width: 750rpx;
padding: 0 32rpx;
margin-bottom: 18rpx;
font-size: 28rpx;
color: #555555;
}
.footer {
background-color: #ffffff;
width: 750rpx;
overflow: hidden;
margin-bottom: 20rpx;
.header {
padding: 24rpx 32rpx;
background-color: #fff;
}
.imgs {
padding: 16rpx 32rpx 32rpx;
min-height: 120rpx;
}
}
.fee {
padding: 24rpx 32rpx;
width: 750rpx;
background-color: #ffffff;
margin: 20rpx 0;
}
.order-footer {
padding: 0rpx 32rpx;
width: 750rpx;
background-color: #ffffff;
.order-line {
padding: 24rpx 0;
border-bottom: 2rpx solid #d8d8d8;
.label {
font-size: 28rpx;
color: #000000;
}
.value {
font-size: 28rpx;
color: #333333;
}
}
}
.default-upload {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx;
background-color: #dcdee0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.icon {
width: 56rpx;
height: 56rpx;
margin-bottom: 8rpx;
}
}
.upload_img {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx;
background-color: #dcdee0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
margin-right: 12rpx;
overflow: hidden;
.close-icon {
position: absolute;
top: 0;
right: 0;
z-index: 5;
}
}
.popup_modal {
width: 750rpx;
height: 600rpx;
background-color: #fff;
border-radius: 10px 10px 0 0;
.popup_modal-title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 750rpx;
height: 88rpx;
font-weight: 600;
border-bottom: 2rpx solid #d8d8d8;
}
.popup_modal-scroll {
width: 750rpx;
height: 600rpx;
.popup_modal-scroll-item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 750rpx;
height: 88rpx;
padding: 0rpx 32rpx;
border-bottom: 2rpx solid #d8d8d8;
}
}
}
.button {
height: 88rpx;
flex-grow: 0;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10rpx;
.text {
font-size: 30rpx;
font-weight: 500;
text-align: center;
}
}
.button__cancel {
width: 270rpx;
height: 88rpx;
border: 2rpx solid #979797;
}
.button__submit {
width: 400rpx;
height: 88rpx;
background: #007aff;
}
.button_cancel {
width: 270rpx;
border: 1px solid #979797;
}
.button_confirm {
width: 400rpx;
background-color: #007aff;
color: #fff;
}
.button_contact {
width: 220rpx;
border: 1px solid #007aff;
color: #007aff;
margin: 0 14rpx;
}
</style>