164 lines
4.7 KiB
Vue
164 lines
4.7 KiB
Vue
<script setup>
|
|
import { ref, computed } from 'vue'
|
|
import { onLoad, onShow } from '@dcloudio/uni-app'
|
|
import { getPlan, updateProductCerts, setHazardCertReady } from '@/api/pl'
|
|
import { chooseAndUploadImages } from '@/utils/upload'
|
|
import { dash, planCardSub, hasPurchaseCert, certReadyLabel } from '@/utils/plLabels'
|
|
import { PAGE_PATHS } from '@/config/api'
|
|
|
|
const id = ref('')
|
|
const detail = ref(null)
|
|
const acting = ref(false)
|
|
|
|
const products = computed(() =>
|
|
Array.isArray(detail.value?.products) ? detail.value.products : []
|
|
)
|
|
|
|
const goBack = () => {
|
|
uni.navigateBack({
|
|
fail: () => uni.navigateTo({ url: PAGE_PATHS.plCertList })
|
|
})
|
|
}
|
|
|
|
const load = async () => {
|
|
if (!id.value) return
|
|
try {
|
|
detail.value = await getPlan(id.value)
|
|
} catch (e) {
|
|
uni.showToast({ title: e.message || '加载失败', icon: 'none' })
|
|
}
|
|
}
|
|
|
|
const certUrls = (p) => {
|
|
const raw = p.purchaseCertUrl || p.purchase_cert_url || ''
|
|
return String(raw)
|
|
.split(',')
|
|
.map((s) => s.trim())
|
|
.filter(Boolean)
|
|
}
|
|
|
|
const preview = (urls, index) => {
|
|
uni.previewImage({ urls, current: urls[index] || urls[0] })
|
|
}
|
|
|
|
const uploadForProduct = async (product) => {
|
|
const current = certUrls(product)
|
|
acting.value = true
|
|
try {
|
|
const added = await chooseAndUploadImages({
|
|
folder: 'pl-purchase-cert',
|
|
maxCount: 6,
|
|
currentUrls: current
|
|
})
|
|
if (!added.length) return
|
|
const nextUrls = current.concat(added)
|
|
await updateProductCerts(id.value, [
|
|
{
|
|
id: product.id,
|
|
purchaseCertUrl: nextUrls.join(',')
|
|
}
|
|
])
|
|
uni.showToast({ title: '已上传', icon: 'success' })
|
|
await load()
|
|
} catch (e) {
|
|
uni.showToast({ title: e.message || '上传失败', icon: 'none' })
|
|
} finally {
|
|
acting.value = false
|
|
}
|
|
}
|
|
|
|
const markReady = (ready) => {
|
|
uni.showModal({
|
|
title: ready ? '标记证书齐备' : '取消齐备',
|
|
content: ready ? '确认该计划危化品证书已齐备?' : '确认取消证书齐备标记?',
|
|
success: async (r) => {
|
|
if (!r.confirm) return
|
|
acting.value = true
|
|
try {
|
|
await setHazardCertReady(id.value, ready)
|
|
uni.showToast({ title: '已更新', icon: 'success' })
|
|
load()
|
|
} catch (e) {
|
|
uni.showToast({ title: e.message || '操作失败', icon: 'none' })
|
|
} finally {
|
|
acting.value = false
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
onLoad((q) => {
|
|
id.value = q?.id || ''
|
|
})
|
|
onShow(() => load())
|
|
</script>
|
|
|
|
<template>
|
|
<view class="mp-page mp-page--sub mp-page--with-bottom">
|
|
<view class="mp-header mp-header--pl">
|
|
<text class="mp-subpage-back" @click="goBack">← 返回</text>
|
|
<text class="mp-header__title" style="margin-top: 16rpx">购买证上传</text>
|
|
</view>
|
|
|
|
<view v-if="detail" class="mp-detail-hero">
|
|
<view class="mp-detail-hero__top">
|
|
<view>
|
|
<text class="mp-detail-hero__title">{{ dash(detail.planNo) }}</text>
|
|
<text class="mp-detail-hero__sub">{{ planCardSub(detail) }}</text>
|
|
</view>
|
|
<text class="mp-tag" :class="'mp-tag--' + certReadyLabel(detail.hazardCertReady).tag">
|
|
{{ certReadyLabel(detail.hazardCertReady).text }}
|
|
</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="mp-block">
|
|
<text class="mp-block__title">产品购买证</text>
|
|
<mp-empty v-if="!products.length" compact title="暂无产品明细" />
|
|
<view v-for="p in products" :key="p.id" class="mp-block__panel" style="margin-bottom: 24rpx">
|
|
<view class="mp-kv">
|
|
<text class="mp-kv__label">{{ dash(p.productName) }}</text>
|
|
<text class="mp-kv__value">{{ hasPurchaseCert(p) ? '已上传' : '未上传' }}</text>
|
|
</view>
|
|
<view class="mp-photo-row" style="margin-top: 16rpx">
|
|
<view
|
|
v-for="(url, idx) in certUrls(p)"
|
|
:key="url + idx"
|
|
class="mp-photo-item"
|
|
@click="preview(certUrls(p), idx)"
|
|
>
|
|
<image :src="url" mode="aspectFill" />
|
|
</view>
|
|
<view
|
|
class="mp-photo-add"
|
|
:class="{ 'mp-photo-add--disabled': acting }"
|
|
@click="uploadForProduct(p)"
|
|
>
|
|
<text>+</text>
|
|
<text style="font-size: 22rpx">拍照</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="mp-bottom-bar">
|
|
<button
|
|
v-if="!detail?.hazardCertReady"
|
|
class="mp-btn mp-btn--primary mp-btn--block"
|
|
:disabled="acting"
|
|
@click="markReady(true)"
|
|
>
|
|
标记证书齐备
|
|
</button>
|
|
<button
|
|
v-else
|
|
class="mp-btn mp-btn--ghost mp-btn--block"
|
|
:disabled="acting"
|
|
@click="markReady(false)"
|
|
>
|
|
取消齐备
|
|
</button>
|
|
</view>
|
|
</view>
|
|
</template>
|