Files
admin-web/src/modules/overseas-warehouse/pages/CartonsView.vue
T
2026-08-22 12:24:15 +08:00

70 lines
6.9 KiB
Vue

<script setup lang="ts">
import { reactive, ref } from 'vue'
import { Eye, Pencil, Plus } from '@lucide/vue'
import { useRouter } from 'vue-router'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import AdminPage from '@/shared/components/AdminPage.vue'
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
import ContractPendingNotice from '../components/ContractPendingNotice.vue'
import ContractPendingFormDialog from '../components/ContractPendingFormDialog.vue'
import { overseasWarehousePermissions as permission } from '../permissions'
import type { CartonListItem } from '../types'
const access = useAccessPreviewStore()
const router = useRouter()
const rows = ref<CartonListItem[]>([])
const page = ref(1)
const pageSize = ref(10)
const filters = ref<QueryModel>({ cartonNo: '', fbaWarehouse: '', status: '' })
const fields: QueryField[] = [
{ key: 'cartonNo', type: 'input', label: '箱号', placeholder: '请输入箱号', width: 190 },
{ key: 'fbaWarehouse', type: 'select', label: '所属FBA仓', placeholder: '全部FBA仓', width: 180, options: [] },
{ key: 'status', type: 'select', label: '状态', placeholder: '全部状态', width: 150, options: ['在库', '已出库'].map((value) => ({ label: value, value })) },
]
const columns: DataTableColumn[] = [
{ key: 'actions', label: '操作', width: 180, fixed: 'left', slotName: 'actions' },
{ key: 'cartonNo', label: '箱号', minWidth: 180 }, { key: 'fbaWarehouse', label: '所属FBA仓', minWidth: 150 },
{ key: 'sku', label: '商品SKU', minWidth: 150 }, { key: 'productName', label: '中文品名', minWidth: 180 },
{ key: 'quantity', label: '数量', width: 100, align: 'right' }, { key: 'weight', label: '重量(kg)', width: 110, align: 'right' },
{ key: 'status', label: '状态', width: 100 },
]
const dialogOpen = ref(false)
const dialogMode = ref<'create' | 'edit'>('create')
const form = reactive({ cartonNo: '', fbaWarehouse: '', sku: '', productName: '', quantity: undefined as number | undefined, weight: undefined as number | undefined, palletNo: '', inboundOrderNo: '', outboundOrderNo: '', status: '在库', remark: '' })
function optionalNumber(value: unknown) { const number = Number(value); return value === '' || value == null || !Number.isFinite(number) ? undefined : number }
function openForm(mode: 'create' | 'edit', source?: object) { const row = source as CartonListItem | undefined; dialogMode.value = mode; Object.assign(form, { cartonNo: '', fbaWarehouse: '', sku: '', productName: '', quantity: undefined, weight: undefined, palletNo: '', inboundOrderNo: '', outboundOrderNo: '', status: '在库', remark: '' }); if (mode === 'edit' && row) Object.assign(form, { cartonNo: String(row.cartonNo || ''), fbaWarehouse: String(row.fbaWarehouse || ''), sku: String(row.sku || ''), productName: String(row.productName || ''), quantity: optionalNumber(row.quantity), weight: optionalNumber(row.weight), palletNo: String(row.palletNo || ''), inboundOrderNo: String(row.inboundOrderNo || ''), outboundOrderNo: String(row.outboundOrderNo || ''), status: String(row.status || '在库'), remark: String(row.remark || '') }); dialogOpen.value = true }
function canEditCarton(source: object) { return String((source as CartonListItem).status) === '在库' }
function openDetail(source: object) { const row = source as CartonListItem; void router.push({ name: 'overseas-carton-detail', params: { cartonId: String(row.cartonNo) } }) }
</script>
<template>
<AdminPage><ListPageLayout aria-label="箱号管理列表">
<template #toolbar><QueryToolbar v-model="filters" class="surface-panel" :fields="fields" ariaLabel="箱号筛选" preference-key="overseas-cartons-query" @search="page = 1" /></template>
<template #state><ContractPendingNotice domain="箱号管理" /></template>
<section class="surface-panel table-panel"><DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :total="0" preference-key="overseas-cartons" row-key="cartonNo" empty-text="海外区域箱号查询契约待接入">
<template #toolbar-actions><el-button v-if="access.can(permission.cartonCreate)" type="primary" @click="openForm('create')"><Plus :size="16" />新增箱号</el-button></template>
<template #actions="{ row }"><el-button size="small" plain type="primary" @click="openDetail(row)"><Eye :size="15" />查看</el-button><el-button v-if="access.can(permission.cartonEdit) && canEditCarton(row)" size="small" plain @click="openForm('edit', row)"><Pencil :size="15" />编辑</el-button></template>
<template #pagination-left>共 0 条箱号记录</template>
</DataTable></section>
</ListPageLayout>
<ContractPendingFormDialog v-model="dialogOpen" :title="dialogMode === 'create' ? '新增箱号' : '编辑箱号'" width="min(860px, calc(100vw - 28px))" domain="箱号">
<el-form label-position="top"><el-row :gutter="16">
<el-col :span="12"><el-form-item label="箱号" required><el-input v-model="form.cartonNo" :readonly="dialogMode === 'edit'" placeholder="请输入箱号" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="所属 FBA 仓" required><el-select v-model="form.fbaWarehouse" placeholder="FBA仓候选接口待接入" disabled /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="商品 SKU" required><el-input v-model="form.sku" placeholder="请输入商品 SKU" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="中文品名" required><el-input v-model="form.productName" placeholder="请输入中文品名" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="数量" required><el-input-number v-model="form.quantity" :min="1" :precision="0" controls-position="right" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="重量(kg)" required><el-input-number v-model="form.weight" :min="0.01" :precision="2" controls-position="right" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="关联托盘"><el-input v-model="form.palletNo" placeholder="请输入关联托盘号" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="关联入库单"><el-input v-model="form.inboundOrderNo" placeholder="请输入关联入库单号" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="关联出库单"><el-input v-model="form.outboundOrderNo" readonly /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="状态"><el-input v-model="form.status" readonly /></el-form-item></el-col>
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item></el-col>
</el-row></el-form>
</ContractPendingFormDialog>
</AdminPage>
</template>