订单信息
This commit is contained in:
@@ -22,10 +22,11 @@ use Modules\Common\Http\Controllers\BaseController;
|
|||||||
class StoreOrderController extends BaseController
|
class StoreOrderController extends BaseController
|
||||||
{
|
{
|
||||||
/** 状态中文名(通知文案用) */
|
/** 状态中文名(通知文案用) */
|
||||||
private const STATUS_NAMES = [
|
private const array STATUS_NAMES = [
|
||||||
StoreOrderModel::STATUS_PENDING => '待汇总',
|
StoreOrderModel::STATUS_PENDING => '待接单',
|
||||||
StoreOrderModel::STATUS_SUMMARIZED => '已汇总',
|
StoreOrderModel::STATUS_SUMMARIZED => '已接单',
|
||||||
StoreOrderModel::STATUS_DELIVERING => '配送中',
|
StoreOrderModel::STATUS_DELIVERING => '采购中',
|
||||||
|
StoreOrderModel::STATUS_DISTRIBUTION => '配送中',
|
||||||
StoreOrderModel::STATUS_COMPLETED => '已完成',
|
StoreOrderModel::STATUS_COMPLETED => '已完成',
|
||||||
StoreOrderModel::STATUS_CANCELLED => '已取消',
|
StoreOrderModel::STATUS_CANCELLED => '已取消',
|
||||||
];
|
];
|
||||||
@@ -43,11 +44,30 @@ class StoreOrderController extends BaseController
|
|||||||
{
|
{
|
||||||
$params = $request->all();
|
$params = $request->all();
|
||||||
$pageSize = $params['pageSize'] ?? 10;
|
$pageSize = $params['pageSize'] ?? 10;
|
||||||
$data = $this->buildSearch($params, StoreOrderModel::query()->with('store:id,name'))
|
$query = StoreOrderModel::query()->with([
|
||||||
|
'store:id,name,address,contact,phone',
|
||||||
|
'items:id,order_id,product_id,product_name,product_spec,price,quantity,amount',
|
||||||
|
'items.product'
|
||||||
|
]);
|
||||||
|
$data = $this->buildSearch($params, $query)
|
||||||
->orderBy('order_date', 'desc')
|
->orderBy('order_date', 'desc')
|
||||||
->orderBy('id', 'desc')
|
->orderBy('id', 'desc')
|
||||||
->paginate($pageSize)
|
->paginate($pageSize)
|
||||||
->toArray();
|
->toArray();
|
||||||
|
$box_amount = site_config('services.box_amount');
|
||||||
|
$tray_amount = site_config('services.tray_amount');
|
||||||
|
foreach ($data['data'] as &$item) {
|
||||||
|
$item['box_amount'] = number_format($box_amount * $item['box_num'], 2);
|
||||||
|
$item['tray_amount'] = number_format($tray_amount * $item['tray_num'], 2);
|
||||||
|
if(count($item['items']) > 0) {
|
||||||
|
foreach ($item['items'] as &$product) {
|
||||||
|
if($product['product'] && $product['product']['images_arr'] > 0) {
|
||||||
|
$product['image'] = $product['product']['images_arr'][0]['preview_url'] ?? '';
|
||||||
|
unset($product['product']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return $this->success($data);
|
return $this->success($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class StoreOrderItemModel extends Model
|
|||||||
'store_id' => 'integer',
|
'store_id' => 'integer',
|
||||||
'product_id' => 'integer',
|
'product_id' => 'integer',
|
||||||
'price' => 'decimal:2',
|
'price' => 'decimal:2',
|
||||||
'quantity' => 'decimal:2',
|
'quantity' => 'integer',
|
||||||
'weight' => 'decimal:3',
|
'weight' => 'decimal:3',
|
||||||
'amount' => 'decimal:2',
|
'amount' => 'decimal:2',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -14,16 +14,18 @@ class StoreOrderModel extends Model
|
|||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
/** 状态:待汇总(可被采购单生成归集、可取消) */
|
/** 状态:待接单(可被采购单生成归集、可取消) */
|
||||||
public const STATUS_PENDING = 0;
|
public const int STATUS_PENDING = 0;
|
||||||
/** 状态:已汇总(已生成采购单) */
|
/** 状态:已接单(已生成采购单) */
|
||||||
public const STATUS_SUMMARIZED = 1;
|
public const int STATUS_SUMMARIZED = 1;
|
||||||
|
/** 状态:采购中 */
|
||||||
|
public const int STATUS_DELIVERING = 2;
|
||||||
/** 状态:配送中 */
|
/** 状态:配送中 */
|
||||||
public const STATUS_DELIVERING = 2;
|
public const int STATUS_DISTRIBUTION = 3;
|
||||||
/** 状态:已完成 */
|
/** 状态:已完成 */
|
||||||
public const STATUS_COMPLETED = 3;
|
public const int STATUS_COMPLETED = 4;
|
||||||
/** 状态:已取消 */
|
/** 状态:已取消 */
|
||||||
public const STATUS_CANCELLED = 9;
|
public const int STATUS_CANCELLED = 9;
|
||||||
|
|
||||||
protected $table = 'store_order';
|
protected $table = 'store_order';
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
@@ -35,17 +37,28 @@ class StoreOrderModel extends Model
|
|||||||
'total_quantity',
|
'total_quantity',
|
||||||
'total_weight',
|
'total_weight',
|
||||||
'total_amount',
|
'total_amount',
|
||||||
|
'product_amount',
|
||||||
|
'added_amount',
|
||||||
|
'box_num',
|
||||||
|
'tray_num',
|
||||||
'status',
|
'status',
|
||||||
'remark',
|
'remark',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'store_id' => 'integer',
|
'store_id' => 'integer',
|
||||||
|
'purchase_id' => 'integer',
|
||||||
|
'statement_id' => 'integer',
|
||||||
'order_date' => 'date:Y-m-d',
|
'order_date' => 'date:Y-m-d',
|
||||||
'total_quantity' => 'decimal:2',
|
'total_quantity' => 'integer',
|
||||||
'total_weight' => 'decimal:3',
|
'total_weight' => 'decimal:3',
|
||||||
'total_amount' => 'decimal:2',
|
'total_amount' => 'decimal:2',
|
||||||
|
'product_amount' => 'decimal:2',
|
||||||
|
'added_amount' => 'decimal:2',
|
||||||
|
'box_num' => 'integer',
|
||||||
|
'tray_num' => 'integer',
|
||||||
'status' => 'integer',
|
'status' => 'integer',
|
||||||
|
'created_at' => 'datetime:Y-m-d H:i:s',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,11 +18,17 @@ return new class extends Migration
|
|||||||
$table->increments('id')->comment('订单ID');
|
$table->increments('id')->comment('订单ID');
|
||||||
$table->string('order_no', 32)->unique()->comment('订单编号');
|
$table->string('order_no', 32)->unique()->comment('订单编号');
|
||||||
$table->integer('store_id')->comment('门店ID');
|
$table->integer('store_id')->comment('门店ID');
|
||||||
|
$table->integer('purchase_id')->nullable()->comment('关联采购单ID');
|
||||||
|
$table->integer('statement_id')->nullable()->comment('关联账单ID');
|
||||||
$table->date('order_date')->comment('订货日期');
|
$table->date('order_date')->comment('订货日期');
|
||||||
$table->decimal('total_quantity', 10, 2)->default(0)->comment('订货总量');
|
$table->integer('total_quantity', 10)->default(0)->comment('订货总量');
|
||||||
$table->decimal('total_weight', 10, 3)->default(0)->comment('总重量');
|
$table->decimal('total_weight', 10, 3)->default(0)->comment('总重量');
|
||||||
$table->decimal('total_amount', 10, 2)->default(0)->comment('订单总金额');
|
$table->decimal('total_amount', 10, 2)->default(0)->comment('订单总金额');
|
||||||
$table->integer('status')->default(0)->comment('订单状态(0待汇总 1已汇总 2配送中 3已完成 9已取消)');
|
$table->decimal('product_amount', 10, 2)->default(0)->comment('商品总金额');
|
||||||
|
$table->decimal('added_amount', 10, 2)->default(0)->comment('附加金额');
|
||||||
|
$table->decimal('box_num', 10, 2)->default(0)->comment('周转框数量');
|
||||||
|
$table->decimal('tray_num', 10, 2)->default(0)->comment('周转托盘数量');
|
||||||
|
$table->integer('status')->default(0)->comment('订单状态(0待接单 1已接单 2采购中 3配送中 4已完成 9已取消)');
|
||||||
$table->string('remark', 255)->default('')->comment('订单备注');
|
$table->string('remark', 255)->default('')->comment('订单备注');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->index(['store_id', 'order_date'], 'store_order_store_date_index');
|
$table->index(['store_id', 'order_date'], 'store_order_store_date_index');
|
||||||
@@ -41,7 +47,7 @@ return new class extends Migration
|
|||||||
$table->string('product_name', 100)->comment('品名(快照)');
|
$table->string('product_name', 100)->comment('品名(快照)');
|
||||||
$table->string('product_spec', 100)->default('')->comment('规格/包规(快照)');
|
$table->string('product_spec', 100)->default('')->comment('规格/包规(快照)');
|
||||||
$table->decimal('price', 10, 2)->default(0)->comment('单价(下单时客户等级价快照)');
|
$table->decimal('price', 10, 2)->default(0)->comment('单价(下单时客户等级价快照)');
|
||||||
$table->decimal('quantity', 10, 2)->default(0)->comment('订货量');
|
$table->integer('quantity', 10)->default(0)->comment('订货量');
|
||||||
$table->decimal('weight', 10, 3)->default(0)->comment('重量');
|
$table->decimal('weight', 10, 3)->default(0)->comment('重量');
|
||||||
$table->decimal('amount', 10, 2)->default(0)->comment('单品金额');
|
$table->decimal('amount', 10, 2)->default(0)->comment('单品金额');
|
||||||
$table->string('remark', 255)->default('')->comment('门店下单备注');
|
$table->string('remark', 255)->default('')->comment('门店下单备注');
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export interface IStoreOrderItem {
|
|||||||
product_name?: string;
|
product_name?: string;
|
||||||
product_spec?: string;
|
product_spec?: string;
|
||||||
price?: string;
|
price?: string;
|
||||||
quantity?: string;
|
image?: string;
|
||||||
|
quantity?: number;
|
||||||
weight?: string;
|
weight?: string;
|
||||||
amount?: string;
|
amount?: string;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
@@ -18,12 +19,24 @@ export default interface IStoreOrder {
|
|||||||
id?: number;
|
id?: number;
|
||||||
order_no?: string;
|
order_no?: string;
|
||||||
store_id?: number;
|
store_id?: number;
|
||||||
store?: { id: number; name: string };
|
purchase_id?: number;
|
||||||
|
statement_id?: number;
|
||||||
|
store?: {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
address: string;
|
||||||
|
contact: string;
|
||||||
|
phone: string;
|
||||||
|
};
|
||||||
order_date?: string;
|
order_date?: string;
|
||||||
total_quantity?: string;
|
total_quantity?: number;
|
||||||
total_weight?: string;
|
total_weight?: string;
|
||||||
total_amount?: string;
|
total_amount?: string;
|
||||||
/** 0待汇总 1已汇总 2配送中 3已完成 9已取消 */
|
product_amount: string;
|
||||||
|
added_amount: string;
|
||||||
|
box_num: number;
|
||||||
|
tray_num: number;
|
||||||
|
/** 0待接单 1已接单 2采购中 3配送中 4已完成 9已取消 */
|
||||||
status?: number;
|
status?: number;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
items?: IStoreOrderItem[];
|
items?: IStoreOrderItem[];
|
||||||
@@ -31,10 +44,11 @@ export default interface IStoreOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const STORE_ORDER_STATUS_MAP: Record<number, { text: string; color: string }> = {
|
export const STORE_ORDER_STATUS_MAP: Record<number, { text: string; color: string }> = {
|
||||||
0: { text: '待汇总', color: 'default' },
|
0: { text: '待接单', color: 'default' },
|
||||||
1: { text: '已汇总', color: 'processing' },
|
1: { text: '已接单', color: 'processing' },
|
||||||
2: { text: '配送中', color: 'warning' },
|
2: { text: '采购中', color: 'warning' },
|
||||||
3: { text: '已完成', color: 'success' },
|
3: { text: '配送中', color: 'success' },
|
||||||
|
4: { text: '已完成', color: 'success' },
|
||||||
9: { text: '已取消', color: 'error' },
|
9: { text: '已取消', color: 'error' },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+116
-20
@@ -9,6 +9,7 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag,
|
||||||
Typography,
|
Typography,
|
||||||
|
Image,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import type { TableProps } from 'antd';
|
import type { TableProps } from 'antd';
|
||||||
import XinTable from '@/components/XinTable';
|
import XinTable from '@/components/XinTable';
|
||||||
@@ -84,16 +85,61 @@ const StoreOrderPage: React.FC = () => {
|
|||||||
const columns: XinTableColumn<IStoreOrder>[] = [
|
const columns: XinTableColumn<IStoreOrder>[] = [
|
||||||
{
|
{
|
||||||
title: '订单号',
|
title: '订单号',
|
||||||
|
hideInTable: true,
|
||||||
dataIndex: 'order_no',
|
dataIndex: 'order_no',
|
||||||
valueType: 'text',
|
valueType: 'text',
|
||||||
|
hideInForm: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '商品信息',
|
||||||
|
dataIndex: 'items',
|
||||||
hideInForm: true,
|
hideInForm: true,
|
||||||
render: (_, record) => <Text copyable={{ text: record.order_no }}>{record.order_no}</Text>,
|
hideInSearch: true,
|
||||||
|
width: 300,
|
||||||
|
render: (_, record) => {
|
||||||
|
return (
|
||||||
|
<Space orientation={'vertical'} className={'max-h-30 w-60 overflow-y-auto pr-6'}>
|
||||||
|
{ record.items && record.items.length > 0 && record.items.map(item => (
|
||||||
|
<div className={'flex'}>
|
||||||
|
<Image src={item.image} width={40} height={40} ></Image>
|
||||||
|
<div className={'ml-2.5'}>
|
||||||
|
<div>{item.product_name}</div>
|
||||||
|
<div>{ item.price } ¥ × { item.quantity }</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基本信息',
|
||||||
|
dataIndex: 'order_no',
|
||||||
|
hideInForm: true,
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 300,
|
||||||
|
render: (_, record) => {
|
||||||
|
return (
|
||||||
|
<Space orientation={'vertical'}>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>订货门店:</Text>
|
||||||
|
<Tag color="blue">{record.store?.name ?? `门店#${record.store_id}`}</Tag>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>订单号:</Text>
|
||||||
|
<Text copyable={{ text: record.order_no }}>{record.order_no}</Text>
|
||||||
|
</div>
|
||||||
|
<div><Text type={'secondary'}>订货时间:</Text>{record.created_at}</div>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '门店',
|
title: '门店',
|
||||||
dataIndex: 'store_id',
|
dataIndex: 'store_id',
|
||||||
valueType: 'select',
|
valueType: 'select',
|
||||||
hideInForm: true,
|
hideInForm: true,
|
||||||
|
hideInTable: true,
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
options: stores.map((s) => ({ label: s.name, value: s.id })),
|
options: stores.map((s) => ({ label: s.name, value: s.id })),
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
@@ -101,53 +147,103 @@ const StoreOrderPage: React.FC = () => {
|
|||||||
},
|
},
|
||||||
render: (_, record) => record.store?.name ?? '-',
|
render: (_, record) => record.store?.name ?? '-',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '门店信息',
|
||||||
|
dataIndex: 'store_id',
|
||||||
|
hideInForm: true,
|
||||||
|
hideInSearch: true,
|
||||||
|
width: 300,
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space orientation={'vertical'}>
|
||||||
|
<div><Text type={'secondary'}>联系人:</Text>{ record.store?.contact ?? '-' }</div>
|
||||||
|
<div><Text type={'secondary'}>联系电话:</Text>{ record.store?.phone ?? '-' }</div>
|
||||||
|
<div><Text type={'secondary'}>门店地址:</Text>{ record.store?.address ?? '-' }</div>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '订货日期',
|
title: '订货日期',
|
||||||
dataIndex: 'order_date',
|
dataIndex: 'order_date',
|
||||||
valueType: 'dateRange',
|
valueType: 'dateRange',
|
||||||
hideInForm: true,
|
hideInForm: true,
|
||||||
|
hideInTable: true,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
render: (_, record) => record.order_date,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '订货总量',
|
title: '订单信息',
|
||||||
dataIndex: 'total_quantity',
|
|
||||||
hideInForm: true,
|
hideInForm: true,
|
||||||
|
dataIndex: 'status',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
align: 'right',
|
width: 200,
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space orientation={'vertical'}>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>订货数量:</Text>
|
||||||
|
{record.total_quantity}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>周转框数量:</Text>
|
||||||
|
{record.box_num}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>周转托盘数量:</Text>
|
||||||
|
{record.tray_num}
|
||||||
|
</div>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '订单金额',
|
title: '附加信息',
|
||||||
dataIndex: 'total_amount',
|
|
||||||
hideInForm: true,
|
hideInForm: true,
|
||||||
|
dataIndex: 'box_num',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
align: 'right',
|
width: 200,
|
||||||
render: (_, record) => <Text strong>¥{record.total_amount}</Text>,
|
render: (_, record) => (
|
||||||
|
<Space orientation={'vertical'}>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>附加总金额:</Text>
|
||||||
|
{record.added_amount} ¥
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>商品总金额:</Text>
|
||||||
|
{record.product_amount} ¥
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Text type={'secondary'}>订单总金额:</Text>
|
||||||
|
{record.total_amount} ¥
|
||||||
|
</div>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '订单状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
valueType: 'select',
|
valueType: 'select',
|
||||||
hideInForm: true,
|
hideInForm: true,
|
||||||
|
align: 'center',
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
options: Object.entries(STORE_ORDER_STATUS_MAP).map(([value, item]) => ({
|
options: Object.entries(STORE_ORDER_STATUS_MAP).map(([value, item]) => ({
|
||||||
value: Number(value),
|
value: Number(value),
|
||||||
label: item.text,
|
label: item.text,
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
render: (_, record) => {
|
render: (_, record) => (
|
||||||
const item = STORE_ORDER_STATUS_MAP[record.status ?? 0];
|
<Tag color={STORE_ORDER_STATUS_MAP[record.status ?? 0]?.color}>
|
||||||
return <Tag color={item?.color}>{item?.text}</Tag>;
|
{STORE_ORDER_STATUS_MAP[record.status ?? 0]?.text}
|
||||||
},
|
</Tag>
|
||||||
align: 'center',
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '备注',
|
title: '采购单ID',
|
||||||
dataIndex: 'remark',
|
dataIndex: 'purchase_id',
|
||||||
|
valueType: 'digit',
|
||||||
|
hideInForm: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '账单ID',
|
||||||
|
dataIndex: 'statement_id',
|
||||||
|
valueType: 'digit',
|
||||||
hideInForm: true,
|
hideInForm: true,
|
||||||
hideInSearch: true,
|
|
||||||
ellipsis: true,
|
|
||||||
render: (_, record) => record.remark || '-',
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user