Files
crm_uiapp/src/pages-erp/pick-broccoli/index.vue

332 lines
9.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="yd-page-container">
<!-- 顶部导航栏 -->
<wd-navbar
title="采摘管理"
left-arrow placeholder safe-area-inset-top fixed
@click-left="handleBack"
/>
<!-- 搜索组件 -->
<SearchForm @search="handleQuery" @reset="handleReset" />
<!-- 采摘记录列表 -->
<view class="px-24rpx">
<view
v-for="item in list"
:key="item.id"
class="mb-20rpx overflow-hidden rounded-12rpx bg-white shadow-sm"
@click="handleCardClick(item)"
>
<view class="p-24rpx">
<!-- 头部采摘编号 + 状态 -->
<view class="mb-16rpx flex items-center justify-between">
<view class="text-30rpx text-[#333] font-semibold">
{{ item.pickCode }}
</view>
<view
class="rounded-8rpx px-16rpx py-4rpx text-24rpx"
:class="getStatusClass(item.status)"
>
{{ getStatusText(item.status) }}
</view>
</view>
<!-- 产品 -->
<view class="mb-8rpx flex items-center justify-between text-26rpx text-[#666]">
<text class="text-[#999]">产品</text>
<text>{{ item.productName || '-' }}</text>
</view>
<!-- 采摘人员 -->
<view class="mb-8rpx flex items-center justify-between text-26rpx text-[#666]">
<text class="text-[#999]">采摘人员</text>
<text>{{ item.userName || '-' }}</text>
</view>
<!-- 田间编号 -->
<view class="mb-8rpx flex items-center justify-between text-26rpx text-[#666]">
<text class="text-[#999]">田间编号</text>
<text>{{ item.fieldCode || '-' }}</text>
</view>
<!-- 框编号 -->
<view class="mb-8rpx flex items-center justify-between text-26rpx text-[#666]">
<text class="text-[#999]">框编号</text>
<text>{{ item.basketCode || '-' }}</text>
</view>
<!-- 重量 -->
<view class="mb-8rpx flex items-center justify-between text-26rpx text-[#666]">
<text class="text-[#999]">重量</text>
<text class="font-semibold">{{ item.basketWeight || 0 }} kg</text>
</view>
<!-- 车牌号 -->
<view class="mb-8rpx flex items-center justify-between text-26rpx text-[#666]">
<text class="text-[#999]">车牌号</text>
<text>{{ item.licensePlate || '-' }}</text>
</view>
<!-- 采摘时间 -->
<view class="flex items-center justify-between text-26rpx text-[#666]">
<text class="text-[#999]">采摘时间</text>
<text>{{ formatDate(item.pickTime) }}</text>
</view>
</view>
<!-- 操作按钮 -->
<view class="flex flex-wrap gap-12rpx px-24rpx pb-20rpx" @click.stop>
<wd-button
v-if="hasAccessByCodes(['erp:pick-broccoli:update']) && (item.status ?? 0) < 3"
size="small" type="primary" plain @click="handleEdit(item)"
>
编辑
</wd-button>
<wd-button
v-if="hasAccessByCodes(['erp:pick-broccoli:query'])"
size="small" plain @click="handleDetail(item)"
>
详情
</wd-button>
<wd-button
v-if="hasAccessByCodes(['erp:pick-broccoli:update']) && item.status === 1"
size="small" type="success" plain @click="handleStatusUpdate(item, 2, '装框')"
>
装框
</wd-button>
<wd-button
v-if="hasAccessByCodes(['erp:pick-broccoli:update']) && item.status === 2"
size="small" type="warning" plain @click="handleLoadTruck(item)"
>
装车
</wd-button>
<wd-button
v-if="hasAccessByCodes(['erp:pick-broccoli:delete']) && (item.status ?? 0) < 3"
size="small" type="error" plain @click="handleDelete(item.id!)"
>
删除
</wd-button>
</view>
</view>
<!-- 加载更多 -->
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="py-100rpx text-center">
<wd-status-tip image="content" tip="暂无采摘记录数据" />
</view>
<wd-loadmore
v-if="list.length > 0"
:state="loadMoreState"
@reload="loadMore"
/>
</view>
<!-- 新增按钮 -->
<wd-fab
v-if="hasAccessByCodes(['erp:pick-broccoli:create'])"
position="right-bottom"
type="primary"
:expandable="false"
@click="handleAdd"
/>
</view>
</template>
<script lang="ts" setup>
import type { PickBroccoli } from '@/api/erp/pick-broccoli'
import type { LoadMoreState } from '@/http/types'
import { onReachBottom } from '@dcloudio/uni-app'
import { onMounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { deletePickBroccoli, getPickBroccoliPage, loadTruck, updatePickBroccoliStatus } from '@/api/erp/pick-broccoli'
import { useAccess } from '@/hooks/useAccess'
import { navigateBackPlus } from '@/utils'
import SearchForm from './components/search-form.vue'
definePage({
style: {
navigationBarTitleText: '',
navigationStyle: 'custom',
},
})
const { hasAccessByCodes } = useAccess()
const toast = useToast()
const total = ref(0)
const list = ref<PickBroccoli[]>([])
const loadMoreState = ref<LoadMoreState>('loading')
const queryParams = ref<Record<string, any>>({
pageNo: 1,
pageSize: 10,
})
/** 格式化日期 */
function formatDate(date?: string) {
if (!date) return '-'
return new Date(date).toLocaleString('zh-CN')
}
/** 获取状态文本 */
function getStatusText(status?: number) {
switch (status) {
case 1: return '已采摘'
case 2: return '已装框'
case 3: return '已装车'
case 4: return '已入库'
default: return '未知'
}
}
/** 获取状态样式 */
function getStatusClass(status?: number) {
switch (status) {
case 1: return 'bg-[#e6f7ff] text-[#1890ff]'
case 2: return 'bg-[#fff7e6] text-[#fa8c16]'
case 3: return 'bg-[#f9f0ff] text-[#722ed1]'
case 4: return 'bg-[#f6ffed] text-[#52c41a]'
default: return 'bg-[#f5f5f5] text-[#999]'
}
}
/** 返回上一页 */
function handleBack() {
navigateBackPlus()
}
/** 查询采摘记录列表 */
async function getList() {
loadMoreState.value = 'loading'
try {
const params = { ...queryParams.value }
const data = await getPickBroccoliPage(params)
list.value = [...list.value, ...data.list]
total.value = data.total
loadMoreState.value = list.value.length >= total.value ? 'finished' : 'loading'
} catch {
queryParams.value.pageNo = queryParams.value.pageNo > 1 ? queryParams.value.pageNo - 1 : 1
loadMoreState.value = 'error'
}
}
/** 搜索按钮操作 */
function handleQuery(data?: Record<string, any>) {
queryParams.value = {
...data,
pageNo: 1,
pageSize: queryParams.value.pageSize,
}
list.value = []
getList()
}
/** 重置按钮操作 */
function handleReset() {
handleQuery()
}
/** 加载更多 */
function loadMore() {
if (loadMoreState.value === 'finished') {
return
}
queryParams.value.pageNo++
getList()
}
/** 刷新列表 */
function refreshList() {
list.value = []
queryParams.value.pageNo = 1
getList()
}
/** 卡片点击 — 打开详情 */
function handleCardClick(item: PickBroccoli) {
handleDetail(item)
}
/** 新增采摘记录 */
function handleAdd() {
uni.navigateTo({
url: '/pages-erp/pick-broccoli/form/index',
})
}
/** 查看详情 */
function handleDetail(item: PickBroccoli) {
uni.navigateTo({
url: `/pages-erp/pick-broccoli/detail/index?id=${item.id}`,
})
}
/** 编辑 */
function handleEdit(item: PickBroccoli) {
uni.navigateTo({
url: `/pages-erp/pick-broccoli/form/index?id=${item.id}`,
})
}
/** 状态更新(装框) */
function handleStatusUpdate(item: PickBroccoli, status: number, text: string) {
uni.showModal({
title: '提示',
content: `确认将该记录状态更新为"${text}完成"吗?`,
success: async (res) => {
if (!res.confirm) return
try {
await updatePickBroccoliStatus(item.id!, status)
toast.success(`${text}操作成功`)
refreshList()
} catch {
// error handled by http
}
},
})
}
/** 装车操作 — 简易输入车牌号 + 装车人 */
function handleLoadTruck(item: PickBroccoli) {
// 小程序端用简化方式:直接输入车牌号
uni.showModal({
title: '装车',
content: '请输入车牌号',
editable: true,
placeholderText: '车牌号',
success: async (res) => {
if (!res.confirm || !res.content) return
try {
// 使用当前用户作为装车人(简化处理)
await loadTruck(item.id!, res.content, 0, '')
toast.success('装车操作成功')
refreshList()
} catch {
// error handled by http
}
},
})
}
/** 删除 */
function handleDelete(id: number) {
uni.showModal({
title: '提示',
content: '确定要删除该采摘记录吗?',
success: async (res) => {
if (!res.confirm) return
try {
await deletePickBroccoli(id)
toast.success('删除成功')
refreshList()
} catch {
// error handled by http
}
},
})
}
/** 触底加载更多 */
onReachBottom(() => {
loadMore()
})
/** 初始化 */
onMounted(() => {
getList()
})
</script>
<style lang="scss" scoped>
</style>