approve.vue 9.58 KB
<template>
    <view class="page">
        <scroll-view class="scroll" scroll-y>
            <view class="detail-page">
                <view class="section">
                    <text class="row company">{{ form.purchaseOrderName }}</text>
                    <view class="row"><text class="label">补货单编号</text><text class="value">{{ form.code }}</text></view>
                    <view class="row"><text class="label">分厂</text><text class="value">{{ form.workshopName }}</text>
                    </view>
                    <view class="row"><text class="label">办事处</text><text class="value">{{ form.deptName }}</text>
                    </view>
                    <view class="row"><text class="label">区域</text><text class="value">{{ form.regionName }}</text>
                    </view>
                    <view class="row"><text class="label">购货单位</text><text class="value">{{ form.customerName }}</text>
                    </view>
                    <view class="row"><text class="label">原计划发货日期</text><text class="value">{{ form.originPlanShipDate
                            }}</text></view>
                </view>

                <!-- 产品 -->
                <view class="section2">
                    <Product mode="approve" :list="initPurchaseOrderLineList"
                        :canEditSupplementary="canEditSupplementary" @change="purchaseOrderLineListChange" />
                </view>
                <view class="section3">
                    <view class="view-total">
                        <view class="head">合计</view>
                        <view class="row">
                            <view class="row2">
                                <text class="label">需发</text><text class="value">{{ form.totalQuantity }}</text>
                            </view>
                            <view class="row2">
                                <text class="label">实发</text><text class="value">{{ form.totalShippedQuantity }}</text>
                            </view>
                        </view>
                        <view class="row">
                            <view class="row2">
                                <text class="label">需求补货</text><text class="value">{{ form.totalSupplementaryQuantity
                                }}</text>
                            </view>
                        </view>
                    </view>
                </view>

            </view>
        </scroll-view>
    </view>
</template>

<script>
import { getDetailApi } from '@/api/replenishment_order.js'
import Product from './product.vue'

export default {
    name: 'ReplenishmentOrderApprove',
    components: { Product },
    props: { id: { type: [String, Number], default: '' } },
    data() {
        return {
            form: {},
            initPurchaseOrderLineList: [],
            roleCodes: [],
            canEditSupplementary: false
        }
    },
    computed: {
    },
    watch: {
        id: {
            immediate: true,
            handler(val) {
                const v = (val !== undefined && val !== null) ? String(val) : ''
                if (v) {
                    this.loadDetail(v);
                    this.getRoleInfo();
                }
            }
        }
    },
    onLoad(query) {

    },
    methods: {
        getRoleInfo() {
            this.roleCodes = this.$store.getters.roleCodes || [];
            console.log('roleCodes', this.roleCodes)
            // 一分厂经营办计划员/二分厂经营办计划员/三分厂经营办计划员/四分厂经营办计划员
            const allowed = ['yfcjybjhy', 'efcjybjhy', 'sfcjybjhy', 'ztfcjybjhy'];
            this.canEditSupplementary = allowed.some((code) => this.roleCodes.includes(code));
            console.log('canEditSupplementary', this.canEditSupplementary)
        },
        async loadDetail(id) {
            try {
                const res = await getDetailApi(id)
                const m = res.data || {}
                const next = { ...this.form, ...m }
                // 确保ID存在
                next.id = m.id || id
                // 映射列表
                // 注意:详情返回的是 replenishmentOrderLineList,需要赋值给 initPurchaseOrderLineList 以便 Product 组件初始化
                // 且需要处理字段兼容性,确保 Product 组件能正确显示和编辑
                const lines = Array.isArray(m.replenishmentOrderLineList) ? m.replenishmentOrderLineList.map(x => ({
                    ...x,
                    // 确保 Product 组件需要的字段存在
                    // Product组件使用: quantity(需发), shippedQuantity(实发), supplementaryQuantity(需求补货), salesPrice(单价)
                    // 详情接口返回的字段应该已经包含了这些,如果有差异需要在此处转换
                    // 注意:add.vue中 onRelateConfirm 做了映射,这里是回显,通常直接使用即可
                })) : []

                this.form = next;
                this.initPurchaseOrderLineList = lines;
                // 初始计算合计
                this.calculateSummary(lines)
            } catch (e) {
                this.form = {}
            }
        },
        calculateSummary(list) {
            const summary = (list || []).reduce((acc, it) => {
                const qty = Number(it.supplementaryQuantity) || 0
                const shipped = Number(it.shippedQuantity) || 0
                const orderQty = Number(it.quantity) || 0
                acc.totalSupplementaryQuantity += qty
                acc.totalShippedQuantity += shipped
                acc.totalQuantity += orderQty
                return acc
            }, { totalQuantity: 0, totalShippedQuantity: 0, totalSupplementaryQuantity: 0 })
            this.form.totalQuantity = summary.totalQuantity
            this.form.totalShippedQuantity = summary.totalShippedQuantity
            this.form.totalSupplementaryQuantity = summary.totalSupplementaryQuantity
        },
        purchaseOrderLineListChange(data) {
            const list = Array.isArray(data) ? data : []
            this.form.purchaseOrderLineList = list
            this.calculateSummary(list)
        },
        getFormValues() {
            const m = this.form || {}
            return JSON.parse(JSON.stringify(m))
        },
        // 审批-通过:校验表单
        checkForm() {
            if (this.canEditSupplementary) {
                const list = Array.isArray(this.form.purchaseOrderLineList) ? this.form.purchaseOrderLineList : [];
                console.log('checkForm__list', list)
                if (list.length === 0) {
                    uni.showToast({ title: '请先添加产品', icon: 'none' })
                    return false
                }
                const fields = [
                    { key: 'supplementaryQuantity', label: '需求补货数量' },
                ]
                for (let i = 0; i < list.length; i++) {
                    const it = list[i] || {}
                    for (const f of fields) {
                        const v = it && it[f.key]
                        if (v === undefined || v === null || String(v).trim() === '') {
                            uni.showToast({ title: `产品第${i + 1}条:${f.label}不能为空!`, icon: 'none' })
                            return false
                        }
                    }
                }
                return true
            } else {
                return true
            }

        }
    }
}
</script>

<style lang="scss" scoped>
.page {
    display: flex;
    flex-direction: column;
    height: 100vh;
}

.scroll {
    flex: 1;
    background: #f3f3f3;
}

.detail-page {
    padding-bottom: 150rpx;
}

.section {
    padding: 32rpx;
    background: #fff;
    margin-bottom: 20rpx;
    position: relative;

}

.row {
    display: flex;
    margin-bottom: 28rpx;

    &:last-child {
        margin-bottom: 0;
    }

    &.company {
        font-size: 36rpx;
        font-weight: 600;
        color: rgba(0, 0, 0, 0.9);
        padding-top: 10rpx;
        margin-bottom: 32rpx;
        line-height: 50rpx;
    }

    .label {
        width: 240rpx;
        line-height: 32rpx;
        font-size: 28rpx;
        color: rgba(0, 0, 0, 0.6);
    }

    .value {
        flex: 1;
        line-height: 32rpx;
        font-size: 28rpx;
        color: rgba(0, 0, 0, 0.9);
        text-align: right;
        word-break: break-all;
    }
}

.title-header {
    background-color: #fff;
    display: flex;
    align-items: center;
    padding: 32rpx 32rpx 22rpx;
    border-bottom: 1rpx dashed #f0f0f0;

    &_icon {
        width: 32rpx;
        height: 28rpx;
        margin-right: 16rpx;
    }

    span {
        color: rgba(0, 0, 0, 0.9);
        font-size: 32rpx;
        line-height: 44rpx;
        font-weight: 600;
    }
}

.section3 {
    padding: 0 32rpx;
    background-color: #fff;
    margin-top: 20rpx;
}

.view-total {
    padding: 20rpx 0;

    .head {
        font-size: 32rpx;
        font-weight: 600;
        line-height: 50rpx;
        color: rgba(0, 0, 0, 0.9);
        padding-bottom: 16rpx;
        margin-bottom: 24rpx;
        border-bottom: 1px dashed #E7E7E7;
    }

    .row {
        display: flex;
        margin-bottom: 24rpx;
        line-height: 32rpx;

        .row2 {
            width: 50%;
        }

        .label {
            width: 180rpx;
            margin-right: 14rpx;
            color: rgba(0, 0, 0, 0.6);
            font-size: 28rpx;
        }

        .value {
            flex: 1;
            color: rgba(0, 0, 0, 0.9);
            font-size: 28rpx;
            white-space: pre-wrap;
            word-break: break-all;
        }
    }
}
</style>