quote.vue 9.91 KB
<template>
    <view class="page">
        <scroll-view class="scroll" scroll-y>
            <uni-list>
                <uni-list-item class="select-item is-filled">
                    <template v-slot:body>
                        <view class="item-title">项目名称</view>
                    </template>
                    <template v-slot:footer>
                        <text class="readonly-text">{{ form.name || '-' }}</text>
                    </template>
                </uni-list-item>
                <uni-list-item class="select-item is-filled">
                    <template v-slot:body>
                        <view class="item-title">开始时间</view>
                    </template>
                    <template v-slot:footer>
                        <text class="readonly-text">{{ form.startTime || '-' }}</text>
                    </template>
                </uni-list-item>
                <uni-list-item class="select-item is-filled">
                    <template v-slot:body>
                        <view class="item-title">截止时间</view>
                    </template>
                    <template v-slot:footer>
                        <text class="readonly-text">{{ form.endTime || '-' }}</text>
                    </template>
                </uni-list-item>
                <!-- 品种 -->
                <uni-list-item class="select-item is-filled">
                    <template v-slot:body>
                        <view class="item-title"><text class="required">*</text><text>品种</text></view>
                    </template>
                    <template v-slot:footer>
                        <text class="readonly-text">{{ form.productName || '-' }}</text>
                    </template>
                </uni-list-item>

                <!-- 数量 -->
                <uni-list-item class="select-item" :class="form.quantity !== '' && form.quantity != null ? 'is-filled' : 'is-empty'">
                    <template v-slot:body>
                        <view class="item-title"><text class="required">*</text><text>数量(吨)</text></view>
                    </template>
                    <template v-slot:footer>
                        <uni-easyinput v-model="form.quantity" type="digit" :inputBorder="false" placeholder="请输入数量" @blur="onQuantityBlur" />
                    </template>
                </uni-list-item>

                <!-- 价格 -->
                <uni-list-item class="select-item" :class="form.price !== '' && form.price != null ? 'is-filled' : 'is-empty'">
                    <template v-slot:body>
                        <view class="item-title"><text class="required">*</text><text>价格</text></view>
                    </template>
                    <template v-slot:footer>
                        <uni-easyinput v-model="form.price" type="digit" :inputBorder="false" placeholder="请输入价格" @blur="onPriceBlur" />
                    </template>
                </uni-list-item>
            </uni-list>
        </scroll-view>

        <view class="footer">
            <button class="btn submit" @click="onSubmit">提交报价</button>
        </view>
    </view>
</template>

<script>
import { supplierQuotationProjectDetailApi, supplierQuotationProjectQuoteApi } from '@/api/procure-manage/supplierQuotationProject.js'

export default {
    name: 'QuoteSupplierPrice',
    data() {
        return {
            projectId: '',
            form: {
                projectId: '',
                productId: '',
                productName: '',
                quantity: '',
                price: '',
                startTime: '',
                endTime: '',
                name: ''
            }
        }
    },
    onLoad(options) {
        this.projectId = (options && options.id) ? options.id : ''
        this.form.projectId = this.projectId
        if (!this.projectId) return
        this.loadDetail()
    },
    methods: {
        async loadDetail() {
            try {
                const res = await supplierQuotationProjectDetailApi({ id: this.projectId })
                const d = (res && res.data) ? res.data : {}
                this.form.productId = d.productId || ''
                this.form.productName = d.productName || ''
                this.form.name = d.name || ''
                this.form.startTime = d.startTime?.substring(0, 16) || ''
                this.form.endTime = d.endTime?.substring(0, 16) || ''
                // 数量默认带出项目数量,可修改
                if (d.quantity != null && d.quantity !== '') this.form.quantity = String(d.quantity)
            } catch (e) {
                uni.showToast({ title: '加载项目信息失败', icon: 'none' })
            }
        },
        onQuantityBlur() {
            let v = this.form.quantity
            if (v === '' || v == null) return
            v = parseFloat(v)
            if (isNaN(v)) { this.form.quantity = ''; return }
            this.form.quantity = String(v)
        },
        onPriceBlur() {
            let v = this.form.price
            if (v === '' || v == null) return
            v = parseFloat(v)
            if (isNaN(v)) { this.form.price = ''; return }
            this.form.price = String(v)
        },
        validateRequired() {
            if (!this.form.projectId) { uni.showToast({ title: '缺少项目ID', icon: 'none' }); return false }
            if (!this.form.productId) { uni.showToast({ title: '缺少品种', icon: 'none' }); return false }
            if (this.form.quantity === '' || this.form.quantity == null) { uni.showToast({ title: '请输入数量', icon: 'none' }); return false }
            if (isNaN(parseFloat(this.form.quantity))) { uni.showToast({ title: '数量格式不正确', icon: 'none' }); return false }
            if (this.form.price === '' || this.form.price == null) { uni.showToast({ title: '请输入价格', icon: 'none' }); return false }
            if (isNaN(parseFloat(this.form.price))) { uni.showToast({ title: '价格格式不正确', icon: 'none' }); return false }
            return true
        },
        async onSubmit() {
            if (!this.validateRequired()) return
            const confirmRes = await new Promise(resolve => {
                uni.showModal({ title: '提示', content: '确定提交报价吗?', confirmText: '确定', cancelText: '取消', success: resolve })
            })
            if (!(confirmRes && confirmRes.confirm)) return
            const payload = {
                projectId: this.form.projectId,
                productId: this.form.productId,
                quantity: parseFloat(this.form.quantity),
                price: parseFloat(this.form.price)
            }
            try {
                await supplierQuotationProjectQuoteApi(payload)
                uni.showToast({ title: '报价成功', icon: 'none' })
                try { uni.setStorageSync('SUPPLIER_PRICE_LIST_NEED_REFRESH', '1') } catch (e) {}
                setTimeout(() => { uni.navigateBack() }, 400)
            } catch (e) {
                uni.showToast({ title: e.msg || '报价失败', icon: 'none' })
            }
        }
    }
}
</script>

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

.scroll {
    flex: 1;
    padding: 12rpx 0 200rpx !important;
}

.footer {
    z-index: 2;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 32rpx;
    padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
    background: #fff;
    box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);

    .btn {
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 12rpx;
        font-size: 32rpx;
    }

    .submit {
        background: $theme-primary;
        color: #fff;
    }
}

::v-deep .uni-list {
    .uni-easyinput {
        display: flex;

        .uni-input-input {
            color: rgba(0, 0, 0, 0.9);
        }
    }

    .uni-input-placeholder {
        z-index: 1;
    }

    .uni-input-input {
        background-color: #ffffff;
    }

    background: transparent;

    &-item {
        &__extra-text {
            font-size: 32rpx;
        }

        &__content-title {
            font-size: 32rpx;
            color: rgba(0, 0, 0, 0.9);
        }

        &__container {
            padding: 32rpx;

            .uni-easyinput {
                &__placeholder-class {
                    font-size: 32rpx;
                    color: rgba(0, 0, 0, 0.4);
                }

                &__content {
                    border: none;
                    background-color: #ffffff !important;

                    &-input {
                        padding-left: 0 !important;
                        height: 48rpx;
                        line-height: 48rpx;
                        font-size: 32rpx;
                    }

                    .content-clear-icon {
                        font-size: 44rpx !important;
                    }
                }
            }

            .item-title,
            .uni-list-item__content {
                flex: none;
                min-height: 48rpx;
                line-height: 48rpx;
                font-size: 32rpx;
                position: relative;
                width: 240rpx;
                margin-right: 32rpx;
                color: rgba(0, 0, 0, 0.9);

                .required {
                    color: red;
                    position: absolute;
                    top: 50%;
                    transform: translateY(-50%);
                    left: -16rpx;
                }
            }
        }

        &.select-item {
            .readonly-text {
                font-size: 32rpx;
                color: rgba(0, 0, 0, 0.9);
                text-align: right;
            }

            &.is-empty {
                .uni-list-item__extra-text {
                    color: rgba(0, 0, 0, 0.4) !important;
                }
            }

            &.is-filled {
                .uni-list-item__extra-text {
                    color: rgba(0, 0, 0, 0.9) !important;
                }
            }
        }
    }
}
</style>