256 lines
8.0 KiB
Vue
256 lines
8.0 KiB
Vue
<template>
|
|
<view class="db-page">
|
|
<view class="db-header" :style="safeAreaStyle">
|
|
<view class="db-header__nav">
|
|
<view class="db-header__left">
|
|
<text class="db-header__back" @click="goBack">←</text>
|
|
<text class="db-header__title">地磅单管理</text>
|
|
</view>
|
|
<view /><!-- 胶囊占位 -->
|
|
</view>
|
|
</view>
|
|
|
|
<view class="db-search-wrap">
|
|
<db-search
|
|
v-model="keyword"
|
|
placeholder="搜索车牌号"
|
|
@change="onKeyword"
|
|
@search="reload"
|
|
@clear="onClear"
|
|
/>
|
|
</view>
|
|
<view class="db-filter-bar">
|
|
<view
|
|
v-for="item in dateFilters"
|
|
:key="item.value"
|
|
class="db-filter-chip"
|
|
:class="{ 'db-filter-chip--active': dateFilter === item.value }"
|
|
@click="setFilter(item.value)"
|
|
>
|
|
{{ item.label }}
|
|
</view>
|
|
</view>
|
|
|
|
<view class="db-list">
|
|
<view v-if="!loading && !list.length" class="db-empty">暂无数据</view>
|
|
<view v-for="item in list" :key="item.id" class="db-card" @click="viewItem(item)">
|
|
<view class="db-card__head">
|
|
<text class="db-card__title">{{ item.vehicleNo || '未填车牌' }}</text>
|
|
<db-tag v-if="item.isVoided" type="danger">已作废</db-tag>
|
|
<db-tag v-else :type="item.businessType === '入库' ? 'success' : 'warning'">
|
|
{{ item.businessType }}
|
|
</db-tag>
|
|
</view>
|
|
<view class="db-card__row">
|
|
<text class="db-card__label">货物</text>
|
|
<text>{{ item.cargoName || '--' }}</text>
|
|
</view>
|
|
<view class="db-card__row">
|
|
<text class="db-card__label">供货单位</text>
|
|
<text>{{ item.supplier || '--' }}</text>
|
|
</view>
|
|
<view class="db-card__row">
|
|
<text class="db-card__label">毛重/皮重</text>
|
|
<text>{{ item.grossWeight ?? '--' }} / {{ item.tareWeight ?? '--' }} kg</text>
|
|
</view>
|
|
<view class="db-card__row">
|
|
<text class="db-card__label">净重</text>
|
|
<text>{{ item.netWeight ?? '--' }} kg</text>
|
|
</view>
|
|
<view class="db-card__foot" @click.stop>
|
|
<db-btn size="small" type="primary" plain @click="viewRelated(item)">关联</db-btn>
|
|
<db-btn
|
|
v-if="!item.isVoided"
|
|
size="small"
|
|
type="primary"
|
|
|
|
@click="editItem(item)"
|
|
>
|
|
{{ needsSecond(item) ? '二次过磅' : '编辑' }}
|
|
</db-btn>
|
|
<db-btn
|
|
v-if="!item.isVoided"
|
|
size="small"
|
|
type="danger"
|
|
|
|
@click="voidItem(item)"
|
|
>
|
|
作废
|
|
</db-btn>
|
|
<db-btn size="small" type="danger" plain @click="removeItem(item)">删除</db-btn>
|
|
</view>
|
|
</view>
|
|
<view v-if="loading" class="db-empty">加载中...</view>
|
|
</view>
|
|
|
|
<db-popup :show="relatedOpen" height="75vh" @close="relatedOpen = false" @update:show="(v) => (relatedOpen = v)">
|
|
<view style="padding: 16px">
|
|
<view class="db-header__title" style="margin-bottom: 12px">关联数据</view>
|
|
<view v-if="relatedLoading" class="db-empty">加载中...</view>
|
|
<template v-else>
|
|
<view v-if="related.plan" class="db-card">
|
|
<db-tag type="primary">计划</db-tag>
|
|
<view class="db-card__row" style="margin-top: 8px">
|
|
<text class="db-card__label">计划号</text>
|
|
<text>{{ related.plan.planNo || '--' }}</text>
|
|
</view>
|
|
</view>
|
|
<view v-if="related.inventory" class="db-card">
|
|
<db-tag type="success">出入库</db-tag>
|
|
<view class="db-card__row" style="margin-top: 8px">
|
|
<text class="db-card__label">车牌</text>
|
|
<text>{{ related.inventory.vehicleNo || '--' }}</text>
|
|
</view>
|
|
<view class="db-card__row">
|
|
<text class="db-card__label">数量</text>
|
|
<text>{{ related.inventory.quantity ?? '--' }} 吨</text>
|
|
</view>
|
|
</view>
|
|
<view v-if="!related.plan && !related.inventory" class="db-empty">暂无关联数据</view>
|
|
</template>
|
|
</view>
|
|
</db-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
import { PAGE_PATHS } from '@/config/api'
|
|
import { getSafeAreaStyle } from '@/utils/safeArea'
|
|
import { weighingApi } from '@/pages/db/api/db'
|
|
import { formatYmd, addDays, weekRange } from '@/pages/db/utils/dbDate'
|
|
import DbSearch from '@/components/db-ui/db-search.vue'
|
|
import DbTag from '@/components/db-ui/db-tag.vue'
|
|
import DbBtn from '@/components/db-ui/db-btn.vue'
|
|
import DbPopup from '@/components/db-ui/db-popup.vue'
|
|
|
|
const safeAreaStyle = getSafeAreaStyle()
|
|
const keyword = ref('')
|
|
const dateFilter = ref('all')
|
|
const loading = ref(false)
|
|
const list = ref([])
|
|
const relatedOpen = ref(false)
|
|
const relatedLoading = ref(false)
|
|
const related = ref({ plan: null, inventory: null })
|
|
let debounce = null
|
|
|
|
const dateFilters = [
|
|
{ label: '全部', value: 'all' },
|
|
{ label: '今日', value: 'today' },
|
|
{ label: '明日', value: 'tomorrow' },
|
|
{ label: '昨日', value: 'yesterday' },
|
|
{ label: '本周', value: 'week' }
|
|
]
|
|
|
|
function needsSecond(item) {
|
|
return Number(item.grossWeight) > 0 && (!item.tareWeight || Number(item.tareWeight) === 0)
|
|
}
|
|
|
|
function buildParams() {
|
|
const params = {}
|
|
if (keyword.value) params.vehicleNo = keyword.value
|
|
const today = new Date()
|
|
if (dateFilter.value === 'today') {
|
|
const d = formatYmd(today)
|
|
params.dateFrom = d
|
|
params.dateTo = d
|
|
} else if (dateFilter.value === 'tomorrow') {
|
|
const t = formatYmd(addDays(today, 1))
|
|
params.dateFrom = t
|
|
params.dateTo = t
|
|
} else if (dateFilter.value === 'yesterday') {
|
|
const y = formatYmd(addDays(today, -1))
|
|
params.dateFrom = y
|
|
params.dateTo = y
|
|
} else if (dateFilter.value === 'week') {
|
|
const w = weekRange(today)
|
|
params.dateFrom = w.from
|
|
params.dateTo = w.to
|
|
}
|
|
return params
|
|
}
|
|
|
|
async function reload() {
|
|
loading.value = true
|
|
try {
|
|
const records = (await weighingApi.list(buildParams())) || []
|
|
const getDate = (r) =>
|
|
r.inventoryDate ||
|
|
(r.grossWeightTime ? String(r.grossWeightTime).split(' ')[0] : '') ||
|
|
(r.createdAt ? String(r.createdAt).split(' ')[0] : '') ||
|
|
''
|
|
list.value = records.slice().sort((a, b) => getDate(b).localeCompare(getDate(a)))
|
|
} catch (e) {
|
|
list.value = []
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
function onKeyword(v) {
|
|
keyword.value = typeof v === 'string' ? v : keyword.value
|
|
if (debounce) clearTimeout(debounce)
|
|
debounce = setTimeout(reload, 300)
|
|
}
|
|
function onClear() {
|
|
keyword.value = ''
|
|
reload()
|
|
}
|
|
function setFilter(v) {
|
|
if (dateFilter.value === v) return
|
|
dateFilter.value = v
|
|
reload()
|
|
}
|
|
function goBack() {
|
|
uni.navigateBack({ fail: () => uni.reLaunch({ url: PAGE_PATHS.workbench }) })
|
|
}
|
|
function editItem(item) {
|
|
uni.navigateTo({ url: `${PAGE_PATHS.dbWeighingDetail}?id=${item.id}&mode=edit` })
|
|
}
|
|
function viewItem(item) {
|
|
uni.navigateTo({ url: `${PAGE_PATHS.dbWeighingDetail}?id=${item.id}&mode=view` })
|
|
}
|
|
async function viewRelated(item) {
|
|
relatedOpen.value = true
|
|
relatedLoading.value = true
|
|
try {
|
|
related.value = (await weighingApi.getRelated(item.id)) || { plan: null, inventory: null }
|
|
} catch (e) {
|
|
relatedOpen.value = false
|
|
} finally {
|
|
relatedLoading.value = false
|
|
}
|
|
}
|
|
function voidItem(item) {
|
|
uni.showModal({
|
|
title: '确认作废',
|
|
content: '确定作废该地磅单吗?',
|
|
success: async (res) => {
|
|
if (!res.confirm) return
|
|
await weighingApi.void(item.id)
|
|
uni.showToast({ title: '已作废', icon: 'success' })
|
|
reload()
|
|
}
|
|
})
|
|
}
|
|
function removeItem(item) {
|
|
uni.showModal({
|
|
title: '确认删除',
|
|
content: '确定删除该地磅单吗?',
|
|
success: async (res) => {
|
|
if (!res.confirm) return
|
|
await weighingApi.delete(item.id)
|
|
uni.showToast({ title: '删除成功', icon: 'success' })
|
|
reload()
|
|
}
|
|
})
|
|
}
|
|
|
|
onShow(reload)
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import '@/styles/db-theme.scss';
|
|
</style>
|