| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- <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>
|