初始化项目:添加后端代码、ThinkPHP框架、前端资源
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\app\physical;
|
||||
|
||||
use app\common\controller\Api;
|
||||
use app\admin\model\app\physical\Category as CategoryModel;
|
||||
|
||||
/**
|
||||
* 商品分类接口
|
||||
*/
|
||||
class Category extends Api
|
||||
{
|
||||
protected $noNeedLogin = ['*'];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new CategoryModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类列表(三级分类)
|
||||
*
|
||||
* @param int $id 指定分类ID,不传则获取所有一级分类
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
|
||||
// 获取一级分类
|
||||
$query = $this->model
|
||||
->where('parent_id', 0)
|
||||
->where('status', 1)
|
||||
->where('uniacid', UNIACID)
|
||||
->order('weigh', 'asc')
|
||||
->order('id', 'asc');
|
||||
|
||||
if ($id) {
|
||||
// 指定 id 分类
|
||||
$query = $query->where('id', $id);
|
||||
}
|
||||
|
||||
$list = $query->select();
|
||||
|
||||
if (empty($list)) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
// 获取完整的三级分类树
|
||||
$result = [];
|
||||
foreach ($list as $item) {
|
||||
$result[] = $this->getCategoryTree($item);
|
||||
}
|
||||
|
||||
$this->success('获取成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有分类树
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$list = $this->model
|
||||
->where('parent_id', 0)
|
||||
->where('status', 1)
|
||||
->where('uniacid', UNIACID)
|
||||
->order('weigh', 'desc')
|
||||
->order('id', 'asc')
|
||||
->select();
|
||||
|
||||
$result = [];
|
||||
foreach ($list as $item) {
|
||||
$result[] = $this->getCategoryTree($item);
|
||||
}
|
||||
|
||||
$this->success('获取成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析子级关联关系
|
||||
*/
|
||||
protected function parseChildrenRelation($childrenString)
|
||||
{
|
||||
$parts = explode('.', $childrenString);
|
||||
$relation = [];
|
||||
$current = &$relation;
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if ($part === 'children') {
|
||||
$current[] = 'children';
|
||||
$current = &$current[0];
|
||||
}
|
||||
}
|
||||
|
||||
// 简化处理,直接返回嵌套关系
|
||||
if ($childrenString === 'children.children.children') {
|
||||
return ['children.children.children'];
|
||||
} elseif ($childrenString === 'children.children') {
|
||||
return ['children.children'];
|
||||
}
|
||||
|
||||
return ['children'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取分类树
|
||||
*/
|
||||
protected function getCategoryTree($category)
|
||||
{
|
||||
$data = [
|
||||
'id' => $category['id'],
|
||||
'name' => $category['name'],
|
||||
'parent_id' => $category['parent_id'],
|
||||
'image' => $category['image'] ?? '',
|
||||
'style' => $category['style'] ?? '',
|
||||
'weigh' => $category['weigh'] ?? 0,
|
||||
];
|
||||
|
||||
$children = $this->model
|
||||
->where('parent_id', $category['id'])
|
||||
->where('status', 1)
|
||||
->where('uniacid', UNIACID)
|
||||
->order('weigh', 'asc')
|
||||
->order('id', 'asc')
|
||||
->select();
|
||||
|
||||
if (!empty($children)) {
|
||||
$data['children'] = [];
|
||||
foreach ($children as $child) {
|
||||
$childData = $this->getCategoryTree($child);
|
||||
// 确保子分类也按权重和ID排序
|
||||
$data['children'][] = $childData;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\app\physical;
|
||||
|
||||
use app\common\controller\Api;
|
||||
use app\common\model\app\physical\OrderExpress;
|
||||
use app\common\model\app\physical\OrderExpressLog;
|
||||
use app\common\model\order\Order;
|
||||
use app\common\library\app\physical\express\Express as libraryExpress;
|
||||
|
||||
/**
|
||||
* 物流接口
|
||||
*/
|
||||
class Express extends Api
|
||||
{
|
||||
protected $noNeedLogin = ['*'];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
protected $orderExpressModel = null;
|
||||
protected $orderExpressLogModel = null;
|
||||
protected $orderModel = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->orderExpressModel = new OrderExpress;
|
||||
$this->orderExpressLogModel = new OrderExpressLog;
|
||||
$this->orderModel = new Order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看物流记录
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$orderNo = $this->request->param('order_no', '');
|
||||
$expressNo = $this->request->param('express_no', '');
|
||||
|
||||
if (!$orderNo && !$expressNo) {
|
||||
$this->error('参数错误');
|
||||
}
|
||||
|
||||
$userId = $this->auth->id;
|
||||
|
||||
if ($orderNo) {
|
||||
$order = $this->orderModel
|
||||
->where('order_no', $orderNo)
|
||||
->where('user_id', $userId)
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$order) {
|
||||
$this->error('订单不存在');
|
||||
}
|
||||
|
||||
$orderExpress = $this->orderExpressModel
|
||||
->where('order_id', $order['id'])
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$orderExpress) {
|
||||
$this->error('暂无物流信息');
|
||||
}
|
||||
|
||||
$orderId = $order['id'];
|
||||
} else {
|
||||
$orderExpress = $this->orderExpressModel
|
||||
->where('express_no', $expressNo)
|
||||
->where('user_id', $userId)
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$orderExpress) {
|
||||
$this->error('物流信息不存在');
|
||||
}
|
||||
|
||||
$orderId = $orderExpress['order_id'];
|
||||
}
|
||||
|
||||
$logs = $this->orderExpressLogModel
|
||||
->where('order_express_id', $orderExpress['id'])
|
||||
->where('uniacid', UNIACID)
|
||||
->order('change_date', 'desc')
|
||||
->select();
|
||||
|
||||
$logs = is_array($logs) ? $logs : $logs->toArray();
|
||||
|
||||
$result = [
|
||||
'express_name' => $orderExpress['express_name'],
|
||||
'express_code' => $orderExpress['express_code'],
|
||||
'express_no' => $orderExpress['express_no'],
|
||||
'status' => $orderExpress['status'],
|
||||
'status_text' => $this->getStatusText($orderExpress['status']),
|
||||
'order_id' => $orderId,
|
||||
'logs' => $logs
|
||||
];
|
||||
|
||||
$this->success('获取成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新物流信息
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function refresh()
|
||||
{
|
||||
$orderNo = $this->request->param('order_no', '');
|
||||
$expressNo = $this->request->param('express_no', '');
|
||||
|
||||
if (!$orderNo && !$expressNo) {
|
||||
$this->error('参数错误');
|
||||
}
|
||||
|
||||
$userId = $this->auth->id;
|
||||
|
||||
if ($orderNo) {
|
||||
$order = $this->orderModel
|
||||
->where('order_no', $orderNo)
|
||||
->where('user_id', $userId)
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$order) {
|
||||
$this->error('订单不存在');
|
||||
}
|
||||
|
||||
$orderExpress = $this->orderExpressModel
|
||||
->where('order_id', $order['id'])
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$orderExpress) {
|
||||
$this->error('暂无物流信息');
|
||||
}
|
||||
|
||||
$orderId = $order['id'];
|
||||
} else {
|
||||
$orderExpress = $this->orderExpressModel
|
||||
->where('express_no', $expressNo)
|
||||
->where('user_id', $userId)
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$orderExpress) {
|
||||
$this->error('物流信息不存在');
|
||||
}
|
||||
|
||||
$orderId = $orderExpress['order_id'];
|
||||
}
|
||||
|
||||
try {
|
||||
$physicalConfig = \app\common\model\app\Config::getConfig('physical');
|
||||
$aliyunConfig = [];
|
||||
$aliyunConfig['appcode'] = $physicalConfig['express_app_code'] ?? '';
|
||||
|
||||
$expressLib = new libraryExpress('aliyun', $aliyunConfig);
|
||||
|
||||
$address = \app\common\model\app\physical\OrderAddress::where([
|
||||
'order_id' => $orderId,
|
||||
'uniacid' => UNIACID
|
||||
])->find();
|
||||
|
||||
$expressLib->search([
|
||||
'order_id' => $orderId,
|
||||
'express_code' => $orderExpress['express_code'],
|
||||
'express_no' => $orderExpress['express_no'],
|
||||
'mobile' => $address ? $address['mobile'] : '',
|
||||
], $orderExpress);
|
||||
|
||||
$orderExpress = $this->orderExpressModel
|
||||
->where('id', $orderExpress['id'])
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->error('刷新失败:' . $e->getMessage());
|
||||
}
|
||||
|
||||
$logs = $this->orderExpressLogModel
|
||||
->where('order_express_id', $orderExpress['id'])
|
||||
->where('uniacid', UNIACID)
|
||||
->order('change_date', 'desc')
|
||||
->select();
|
||||
|
||||
$logs = is_array($logs) ? $logs : $logs->toArray();
|
||||
|
||||
$result = [
|
||||
'express_name' => $orderExpress['express_name'],
|
||||
'express_code' => $orderExpress['express_code'],
|
||||
'express_no' => $orderExpress['express_no'],
|
||||
'status' => $orderExpress['status'],
|
||||
'status_text' => $this->getStatusText($orderExpress['status']),
|
||||
'order_id' => $orderId,
|
||||
'logs' => $logs
|
||||
];
|
||||
|
||||
$this->success('刷新成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态文本
|
||||
*
|
||||
* @param string $status
|
||||
* @return string
|
||||
*/
|
||||
private function getStatusText($status)
|
||||
{
|
||||
$statusMap = [
|
||||
'noinfo' => '暂无信息',
|
||||
'transport' => '运输中',
|
||||
'delivery' => '派送中',
|
||||
'signfor' => '已签收',
|
||||
'refuse' => '拒签',
|
||||
'difficulty' => '疑难件',
|
||||
'invalid' => '无效单',
|
||||
'timeout' => '超时',
|
||||
'fail' => '派送失败',
|
||||
'back' => '退回'
|
||||
];
|
||||
|
||||
return $statusMap[$status] ?? '未知状态';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\app\physical;
|
||||
|
||||
use app\common\controller\Api;
|
||||
use app\common\service\app\physical\GoodsService;
|
||||
use app\admin\model\app\physical\Goods as GoodsModel;
|
||||
use app\admin\model\app\physical\Category as CategoryModel;
|
||||
use app\admin\model\app\physical\SkuPrice as SkuPriceModel;
|
||||
|
||||
/**
|
||||
* 商品接口
|
||||
*/
|
||||
class Goods extends Api
|
||||
{
|
||||
protected $noNeedLogin = ['*'];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
protected $model = null;
|
||||
protected $categoryModel = null;
|
||||
protected $skuPriceModel = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new GoodsModel;
|
||||
$this->categoryModel = new CategoryModel;
|
||||
$this->skuPriceModel = new SkuPriceModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$params = $this->request->param();
|
||||
|
||||
$keyword = $params['keyword'] ?? '';
|
||||
$category_id = $params['category_id'] ?? '';
|
||||
$is_category_deep = $params['is_category_deep'] ?? true;
|
||||
$sort = $params['sort'] ?? 'weigh';
|
||||
$order = $params['order'] ?? 'desc';
|
||||
|
||||
$physicalConfig = \app\common\model\app\Config::getConfig('physical');
|
||||
$showSales = $physicalConfig['show_sales'] ?? 1;
|
||||
|
||||
$service = new GoodsService(function ($goods) {
|
||||
return $goods;
|
||||
}, (new \app\admin\model\app\physical\Goods())->field(['id', 'name', 'cover', 'price', 'stock', 'total_sales', 'virtual_sales', 'weigh', 'createtime', 'spec_type']));
|
||||
|
||||
$service->up()->inStock();
|
||||
|
||||
if ($keyword) {
|
||||
$service->search($keyword);
|
||||
}
|
||||
|
||||
if ($category_id) {
|
||||
$service->category($category_id, $is_category_deep);
|
||||
}
|
||||
|
||||
if ($sort) {
|
||||
$service->order($sort, $order);
|
||||
}
|
||||
|
||||
$list = $service->paginate();
|
||||
|
||||
$isVirtualPay = \app\common\library\pay\VirtualPayService::isUseVirtualPay('physical');
|
||||
if ($isVirtualPay) {
|
||||
foreach ($list as &$item) {
|
||||
$item['is_virtual_pay'] = 1;
|
||||
$item = \app\common\library\pay\VirtualPayService::convertPriceFields($item, ['price']);
|
||||
}
|
||||
unset($item);
|
||||
} else {
|
||||
foreach ($list as &$item) {
|
||||
$item['is_virtual_pay'] = 0;
|
||||
}
|
||||
unset($item);
|
||||
}
|
||||
|
||||
$this->success('获取成功', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 ids 获取商品(不分页)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ids()
|
||||
{
|
||||
$params = $this->request->param();
|
||||
$ids = $params['ids'] ?? '';
|
||||
|
||||
if (empty($ids)) {
|
||||
$this->error('参数错误');
|
||||
}
|
||||
|
||||
$physicalConfig = \app\common\model\app\Config::getConfig('physical');
|
||||
$showSales = $physicalConfig['show_sales'] ?? 1;
|
||||
|
||||
$ids = is_array($ids) ? $ids : explode(',', $ids);
|
||||
|
||||
$list = $this->model
|
||||
->where('id', 'in', $ids)
|
||||
->where('status', 1)
|
||||
->where('uniacid', UNIACID)
|
||||
->order('weigh', 'desc')
|
||||
->field(['id', 'name', 'title', 'cover', 'image', 'price'])
|
||||
->select();
|
||||
|
||||
foreach ($list as &$item) {
|
||||
// 根据配置决定是否显示销量
|
||||
if ($showSales != 1) {
|
||||
unset($item['total_sales']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('获取成功', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品详情
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$id = $this->request->param('id');
|
||||
if (empty($id)) {
|
||||
$this->error('参数错误');
|
||||
}
|
||||
|
||||
$physicalConfig = \app\common\model\app\Config::getConfig('physical');
|
||||
$showSales = $physicalConfig['show_sales'] ?? 1;
|
||||
|
||||
$goods = $this->model
|
||||
->where('id', $id)
|
||||
->where('status', 1)
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$goods) {
|
||||
$this->error('商品不存在');
|
||||
}
|
||||
|
||||
// 增加虚拟浏览量
|
||||
$this->model->where('id', $id)
|
||||
->where('uniacid', UNIACID)
|
||||
->setInc('virtual_visit', 1);
|
||||
|
||||
$goods = $goods->toArray();
|
||||
|
||||
// 只保留需要的字段
|
||||
$allowedFields = ['id', 'name', 'title', 'image', 'cover', 'carousel', 'detail', 'price', 'min_price', 'stock', 'total_sales', 'service', 'single_limit', 'lifetime_limit', 'support_return', 'support_exchange', 'delivery_time', 'params', 'spec_type', 'sku_tree'];
|
||||
$goods = array_intersect_key($goods, array_flip($allowedFields));
|
||||
|
||||
if (isset($goods['params']) && is_string($goods['params'])) {
|
||||
$goods['params'] = json_decode($goods['params'], true);
|
||||
}
|
||||
|
||||
// 处理图片字段
|
||||
if (isset($goods['carousel']) && is_string($goods['carousel'])) {
|
||||
$goods['carousel'] = json_decode($goods['carousel'], true) ?: [];
|
||||
}
|
||||
|
||||
// 根据配置决定是否显示销量
|
||||
if ($showSales != 1) {
|
||||
unset($goods['total_sales']);
|
||||
}
|
||||
|
||||
$specType = $goods['spec_type'] ?? 'single';
|
||||
|
||||
if ($specType == 'single') {
|
||||
$skuPrice = $this->skuPriceModel
|
||||
->where('goods_id', $id)
|
||||
->where('uniacid', UNIACID)
|
||||
->where('status', 1)
|
||||
->order('id', 'asc')
|
||||
->find();
|
||||
|
||||
$goods['sku_prices'] = $skuPrice ? [$skuPrice->toArray()] : [];
|
||||
|
||||
// 根据配置决定是否显示销量
|
||||
if ($showSales != 1 && !empty($goods['sku_prices'])) {
|
||||
foreach ($goods['sku_prices'] as &$sku) {
|
||||
unset($sku['sales']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$skuPrices = $this->skuPriceModel
|
||||
->where('goods_id', $id)
|
||||
->where('uniacid', UNIACID)
|
||||
->where('status', 1)
|
||||
->order('weigh', 'asc')
|
||||
->select();
|
||||
|
||||
$goods['sku_prices'] = collection($skuPrices)->toArray();
|
||||
|
||||
// 根据配置决定是否显示销量
|
||||
if ($showSales != 1 && !empty($goods['sku_prices'])) {
|
||||
foreach ($goods['sku_prices'] as &$sku) {
|
||||
unset($sku['sales']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$skuPrice = $this->skuPriceModel
|
||||
->where('goods_id', $id)
|
||||
->where('uniacid', UNIACID)
|
||||
->where('status', 1)
|
||||
->order('price', 'asc')
|
||||
->find();
|
||||
|
||||
$goods['price'] = $skuPrice ? $skuPrice['price'] : 0;
|
||||
|
||||
// 计算总库存和总销量
|
||||
$skuPrices = $this->skuPriceModel
|
||||
->where('goods_id', $id)
|
||||
->where('uniacid', UNIACID)
|
||||
->where('status', 1)
|
||||
->select();
|
||||
|
||||
if ($skuPrices) {
|
||||
if (is_array($skuPrices)) {
|
||||
$skuPricesArray = $skuPrices;
|
||||
} else {
|
||||
$skuPricesArray = $skuPrices->toArray();
|
||||
}
|
||||
$goods['stock'] = array_sum(array_column($skuPricesArray, 'stock'));
|
||||
|
||||
// 根据配置决定是否显示销量
|
||||
if ($showSales == 1) {
|
||||
$goods['sales'] = array_sum(array_column($skuPricesArray, 'sales'));
|
||||
}
|
||||
} else {
|
||||
$goods['stock'] = 0;
|
||||
}
|
||||
|
||||
$goods['is_virtual_pay'] = \app\common\library\pay\VirtualPayService::isUseVirtualPay('physical');
|
||||
if ($goods['is_virtual_pay']) {
|
||||
$goods = \app\common\library\pay\VirtualPayService::convertPriceFields($goods, ['price', 'min_price']);
|
||||
if (!empty($goods['sku_prices'])) {
|
||||
foreach ($goods['sku_prices'] as &$sku) {
|
||||
$sku = \app\common\library\pay\VirtualPayService::convertPriceFields($sku, ['price', 'original_price']);
|
||||
}
|
||||
unset($sku);
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('获取成功', $goods);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user