ufutx.dma/app/Http/Controllers/ShopController.php
2026-03-04 14:42:40 +08:00

610 lines
24 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Facades\CommonService;
use App\Facades\WechatService;
use App\Http\Response\ResponseJson;
use App\Models\Message;
use App\Models\OperateStockLog;
use App\Models\Shop;
use App\Models\ShopCode;
use App\Models\ShopCodeLog;
use App\Models\ShopOrder;
use App\Models\ShopOrderStatus;
use App\Models\User;
use App\Models\Version;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;
class ShopController extends Controller
{
use ResponseJson;
protected $key;
protected $url;
public function __construct()
{
// $this->url = env('SHOP_URL','https://saas.ufutx.com/api/');
// $this->key = env('SHOP_KEY','eyJpdiI6Ijg0elMrZkpRNC9vWXZFekJ0bUlZa0E9PSIsInZhbHVlIjoiTVpqenR0dDdHM2laMDRyZFFvZmc5Y2NFZ29hZER5UUwrWVlzOHphMGRnR0Q2dlNQSDBsekdRNEtYaWsxekd0S212NU40V0lOWjJKemNDemJIRGRVUEZlbXVnNllTRzExZkdHZ2Q1Z2ppUEZTRGVQc0JzZi9nbkJvSTBWbzRpU3prUDhlbE9xS09aTzdFak5oZ1hlWEpsaC9KNmc4NGI3K1M3a2d6RTBDU1N0RHkzUXpXcm9qNnJpdnpGYTVKblFHIiwibWFjIjoiZWZjNWMyMjlhZTVhZDBjN2Y0ZjI1ZGRjNGMzM2RiN2U5OGEwN2ZmMGI2ODk5N2Y0ODI2YTkxMjIxZjY0ZTcxYyIsInRhZyI6IiJ9');
$this->url = config("app.shop_url");
$this->key = config('app.shop_key');
}
/**
* 获取商品列表
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getGoodsList(Request $request)
{
try {
$user = auth()->user();
$keyword = $request->get('keyword');
$page = $request->get('page',1);
$accid = User::SAAS_PREFIX.$user->id;
//是否会员
$is_vip = $user->isVip();
$query = http_build_query(['accid'=>$accid, 'page'=>$page, 'keyword'=>$keyword, 'is_vip'=>$is_vip]);
$headers = [
'Key' => $this->key, // 自定义头部参数(示例)
];
$url = $this->url . 'shops?' . $query;
Log::info("商品列表url $url");
$client = new Client();
$response = $client->get($url, [
'headers' => $headers,
]);
$code = $response->getStatusCode();
if($code != 200){
return $this->failure('请求失败');
}
$body = $response->getBody()->getContents(); // 获取响应内容
$list = json_decode($body, true);
if($list['code'] == 1){
return $this->failure($list['message']);
}
$data = $list['data'] ?? [];
//增加特定逻辑处理特定业务场景
$version = $request->get('version');
$version_status = Version::where('type', Version::TYPE_MP)->where('version',$version)->value('status');
if($version_status == Version::STATUS_CHECK){
foreach ($data['data'] as $index => $item){
if($item['id'] == 8192){
unset($data['data'][$index]);
}
}
$data['data'] = array_values($data['data']);
}
return $this->success('ok', $data);
} catch (\Exception $e) {
Log::error('getGoodsList:' . $e->getMessage());
return $this->failure('请求失败');
}
}
public function getGoodsListV2(Request $request)
{
$shops = Shop::whereHas("shopFood",function ($sql) {
$sql->show()->orderByDesc("id");
})->orderByDesc("id")->paginate();
foreach ($shops as $shop)
{
$shop->origin_price = $shop->price;
}
return $this->success('ok', $shops);
}
/**
* 获取商品详情
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getGoodsDetail(Request $request)
{
try {
$user = auth()->user();
$accid = User::SAAS_PREFIX.$user->id;
$goods_id = $request->get('id');
if (empty($goods_id)) {
return $this->failure('请选择商品');
}
//是否会员
$is_vip = $user->isVip();
$headers = [
'Key' => $this->key, // 自定义头部参数(示例)
];
$agent_accid = $request->agent_user_id?User::SAAS_PREFIX.$request->agent_user_id:null;
$query = http_build_query(['accid'=>$accid, 'agent'=>$request->agent, 'agent_accid'=>$agent_accid, 'is_vip'=>$is_vip]);
$url = $this->url . 'shops/' . $goods_id.'?'.$query;
Log::info("getGoodsDetail初始化商城域名 ".env('SHOP_URL'));
Log::info("商品详情url $url");
$client = new Client();
$response = $client->get($url, [
'headers' => $headers,
]);
$code = $response->getStatusCode();
if($code != 200){
return $this->failure('请求失败');
}
$body = $response->getBody()->getContents(); // 获取响应内容
$list = json_decode($body, true);
if($list['code'] == 1){
return $this->failure($list['message']);
}
$data = $list['data'] ?? [];
return $this->success('ok', $data);
} catch (\Exception $e) {
Log::error('getGoodsDetail:' . $e->getMessage());
return $this->failure('请求失败');
}
}
public function getGoodsDetailV2(Request $request)
{
$user = auth()->user();
$id = $request->input('id');
$shop = Shop::find($id);
$skus = $shop->sku;
if ($skus && is_array($skus)) {
foreach ($skus as &$sku) {
$sku['origin_price'] = $sku['price'];
}
$shop->sku = $skus;
}
$shop->recive = ShopOrder::where('user_id', $user->id)->select('id','name','mobile','address')->orderByDesc("id")->first()?:null;
return $this->success('ok', $shop);
}
public function getGoodsDetailV3(Request $request)
{
$user = auth()->user();
$id = $request->input('id');
$shop = Shop::find($id);
if (empty($shop)) {
return $this->failure("商品不存在");
}
$skus = $shop->sku;
if ($skus && is_array($skus)) {
$skus = $user->getGoodsSku($skus);
$shop->sku = $skus;
}
$shop->recive = ShopOrder::where('user_id', $user->id)->select('id','name','mobile','address')->orderByDesc("id")->first()?:null;
return $this->success('ok',$shop);
}
/**
* 获取订单列表
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getShopOrderList(Request $request)
{
try {
$user = auth()->user();
$accid = User::SAAS_PREFIX.$user->id;
$page = $request->get('page',1);
$status = $request->get('status');
$headers = [
'Key' => $this->key, // 自定义头部参数(示例)
];
$url = $this->url . 'shops/orders' . '?page='.$page.'&accid=' . $accid . '&pay_status=' . $status;
$client = new Client();
Log::info("商品订单列表url $url");
$response = $client->get($url, [
'headers' => $headers,
]);
$code = $response->getStatusCode();
if($code != 200){
return $this->failure('请求失败');
}
$body = $response->getBody()->getContents(); // 获取响应内容
$list = json_decode($body, true);
if($list['code'] == 1){
return $this->failure($list['message']);
}
$data = $list['data'] ?? [];
return $this->success('ok', $data);
} catch (\Exception $e) {
Log::error('getMyOrderList:' . $e->getMessage());
return $this->failure('请求失败');
}
}
public function getShopOrderListV2(Request $request)
{
$orders = ShopOrder::owner(auth()->id())->paidStatus()->orderByDesc("id")->paginate();
return $this->success('ok', $orders);
}
/**
* 获取订单详情
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getOrderDetail(Request $request)
{
try {
$user = auth()->user();
$accid = User::SAAS_PREFIX.$user->id;
$order_id = $request->get('id');
if (empty($order_id)) {
return $this->failure('请选择订单');
}
$headers = [
'Key' => $this->key, // 自定义头部参数(示例)
];
$url = $this->url . 'shops/orders/' . $order_id . '?accid=' . $accid;
Log::info("商品订单详情url $url");
$client = new Client();
$response = $client->get($url, [
'headers' => $headers,
]);
$code = $response->getStatusCode();
if($code != 200){
return $this->failure('请求失败');
}
$body = $response->getBody()->getContents(); // 获取响应内容
$list = json_decode($body, true);
if($list['code'] == 1){
return $this->failure($list['message']);
}
$data = $list['data'] ?? [];
$data['recive']['tracks'] = json_decode($data['recive']['tracks'],true);
// 假设$data是你的JSON字符串解析后得到的数组
if(!empty($data['recive']['tracks'])){
usort($data['recive']['tracks'], function($a, $b) {
return strtotime($b['created_at']) - strtotime($a['created_at']);
});
}
return $this->success('ok', $data);
} catch (\Exception $e) {
Log::error('getOrderDetail:' . $e->getMessage());
return $this->failure('请求失败');
}
}
public function getOrderDetailV2(Request $request)
{
$id = $request->input('id');
$order = ShopOrder::find($id);
if (empty($order)) return $this->failure("订单不存在");
$order->status;
return $this->success('ok', $order);
}
/**
* 购买商品
* @param Request $request
* @return \Illuminate\Http\JsonResponse|void
*/
public function payOrder(Request $request)
{
try {
$from_user_id = $request->input('from_user_id');
Log::info("商城下单 分享人id $from_user_id");
$id = $request->input('id');
if (empty($id)) {
return $this->failure('请选择商品');
}
$sku_id = $request->input('sku_id');
// if (empty($sku_id)) {
// return $this->failure('请选择规格');
// }
$name = $request->input('name');
if (empty($name)) {
return $this->failure('请填写收货人');
}
$mobile = $request->input('mobile');
if (empty($mobile)) {
return $this->failure('请填写电话');
}
$num = $request->input('num');
if (empty($num)) {
return $this->failure('请选择数量');
}
$address = $request->input('address');
if (empty($address)) {
return $this->failure('请选择地址');
}
$user = auth()->user();
$open_id = $user->wechat->openid;
if (empty($open_id)) {
return $this->failure('获取用户openid失败');
}
//是否会员
$is_vip = $user->isVip();
$app_id = config('wechat.mini_program.app_id');
$headers = [
'Key' => $this->key, // 自定义头部参数(示例)
];
$url = $this->url . 'shops/' . $id . '/orders';
$client = new Client();
$agent_user_id = $request->input('agent_user_id');
$response = $client->post($url, [
'headers' => $headers,
'json' => [
'accid' => User::SAAS_PREFIX.$user->id,
'sku_id' => $sku_id,
'openid' => $open_id,
'app_id' => $app_id,
'name' => $name,
'mobile' => $mobile,
'num' => $num,
'address' => $address,
'nickname' => $user->name??'',
'pic' => $user->avatar??'',
'from_accid'=> $from_user_id?User::SAAS_PREFIX.$from_user_id:null,
'agent'=>$request->input('agent',0),
'agent_accid'=>$agent_user_id?User::SAAS_PREFIX.$agent_user_id:null,
'is_vip'=>$is_vip,
],
]);
$code = $response->getStatusCode();
if($code != 200){
return $this->failure('支付失败');
}
$body = $response->getBody()->getContents(); // 获取响应内容
$list = json_decode($body, true);
if($list['code'] == 1){
return $this->failure($list['message']);
}
$data = $list['data'] ?? [];
return $this->success('ok', $data);
} catch (\Exception $e) {
Log::error('payOrder:' . $e->getMessage());
return $this->failure('支付失败');
}
}
public function payOrderV2(Request $request)
{
$user = auth()->user();
$data = $request->all();
$data['user_id'] = $user->id;
$shop = Shop::find($data['id']);
$sku_arr = $shop->sku;
$sku = null;
if (is_array($sku_arr) && count($sku_arr)) {//含sku
$sku = collect($sku_arr)->where('sku_id', $request->sku_id)->first();
if (empty($sku)) throw new \Exception("获取sku信息失败");
if (isset($sku['stock']) && $sku['stock'] < $data['num']) return $this->failure("库存不足");
$data['price'] = $data['origin_price'] = $sku['price'] * $data['num'];
}else {
$data['price'] = $data['origin_price'] = $shop->price * $data['num'];
}
if ($data['price'] < 0) throw new \Exception("订单计算错误");
$data['pay_type'] = $data['price'] == 0?ShopOrder::FREEPAYTYPE:ShopOrder::WECHATPAYTYPE;
$data['trade_no'] = CommonService::getTradeNo();
$data['shop_id'] = $shop->id;
$data['shop_info'] = ["id"=>$shop->id, 'title'=>$shop->title, 'pic'=>$shop->icon, "sku"=> $sku];
$data['sku_id'] = $sku?$sku['sku_id']:0;
$callback = config('app.url')."/api/shop/order/".$data['trade_no'].'/callback';
$data['pay_status'] = $data['price'] > 0?ShopOrder::UNPAIDSTATUS:ShopOrder::PAIDSTATUS;
$data['express_type'] = $data['express_type']??"ONLINE";
DB::beginTransaction();
//生成未支付订单
$order = ShopOrder::create($data);
ShopOrderStatus::create(['order_id'=>$order->id, 'status'=>ShopOrder::UNPAIDSTATUS]);
$data['order_id'] = $order->id;
$config = [];
if ($data['price'] > 0) {
$openid = $user->wechat->openid;
//获取支付配置
$config = WechatService::mpPay($data['trade_no'], $openid, $data['price'], $shop->title,$callback);
}else {
$this->markOrder($order);
}
$order->config = $config;
DB::commit();
return $this->success('ok', $order);
}
public function getGoodsShip($sku, $num) {
if ($num <= $sku["ship_num"]) return $sku['ship_price'];
$over_num = number_format($num - $sku['ship_num']);
$ship_price = $sku['ship_price'] + $over_num * $sku['ship_each_price'];
if ($sku['ship_max_price'] && $ship_price > $sku['ship_max_price']) return $sku['ship_max_price'];
return number_format($ship_price, 2, '.', '');
}
public function payOrderV3(Request $request)
{
$user = auth()->user();
$data = $request->all();
$data['express_type'] = $data['express_type']??ShopOrder::ONLINETYPE;
$data['user_id'] = $user->id;
$shop = Shop::find($data['id']);
$sku_arr = $shop->sku;
$sku = null;
$ship_fee = 0;
if (is_array($sku_arr) && count($sku_arr)) {//含sku
$sku = $user->getGoodsSku($sku_arr, $data['sku_id']);
if (empty($sku)) throw new \Exception("获取sku信息失败");
if (isset($sku['stock']) && $sku['stock'] < $data['num']) return $this->failure("库存不足");
$data['price'] = $sku['price'] * $data['num'];
$data['origin_price'] = $sku['origin_price'] * $data['num'];
//快递费
if($data['express_type'] == ShopOrder::ONLINETYPE) {
$ship_fee = $this->getGoodsShip($sku, $data['num']);
}
}else {
$data['price'] = $data['origin_price'] = $shop->price * $data['num'];
}
if ($data['price'] < 0) throw new \Exception("订单计算错误");
$data['price'] = number_format($data['price'] + $ship_fee, 2, '.','');
$data['origin_price'] = number_format($data['origin_price'] + $ship_fee, 2, '.','');
$data['ship_fee'] = $ship_fee;
$data['pay_type'] = $data['price'] == 0?ShopOrder::FREEPAYTYPE:ShopOrder::WECHATPAYTYPE;
$data['trade_no'] = CommonService::getTradeNo();
$data['shop_id'] = $shop->id;
$data['shop_info'] = ["id"=>$shop->id, 'title'=>$shop->title, 'pic'=>$shop->icon, "sku"=> $sku];
$data['sku_id'] = $sku?$sku['sku_id']:0;
$callback = config('app.url')."/api/shop/order/".$data['trade_no'].'/callback';
$data['pay_status'] = $data['price'] > 0?ShopOrder::UNPAIDSTATUS:ShopOrder::PAIDSTATUS;
DB::beginTransaction();
//生成未支付订单N
$order = ShopOrder::create($data);
ShopOrderStatus::create(['order_id'=>$order->id, 'status'=>ShopOrder::UNPAIDSTATUS]);
$data['order_id'] = $order->id;
$config = [];
if ($data['price'] > 0) {
$openid = $user->wechat->openid;
//获取支付配置
$config = WechatService::mpPay($data['trade_no'], $openid, $data['price'], $shop->title,$callback);
}else {
$this->markOrder($order);
}
$order->config = $config;
DB::commit();
return $this->success('ok', $order);
}
public function orderCallbackV2($trade_no)
{
$order = ShopOrder::where("trade_no", $trade_no)->first();
if (empty($order)) throw new \Exception("订单号{$trade_no} 不存在订单");
if ($order->pay_status != ShopOrder::UNPAIDSTATUS) return false;
$res = WechatService::mpPaid($trade_no);
if ($res) throw new \Exception("订单号{$trade_no} 支付失败 {$res}");
$this->markOrder($order);
return true;
}
public function markOrder($order)
{
DB::beginTransaction();
//修改订单状态
$order->update(['pay_status'=>ShopOrder::PAIDSTATUS]);
ShopOrderStatus::create(['order_id'=>$order->id, 'status'=>ShopOrder::PAIDSTATUS]);
//修改库存
DB::commit();
}
/**
* 订单回调
* @param Request $request
* @return \Illuminate\Http\JsonResponse|void
*/
public function orderCallback(Request $request){
try {
$trade_no = $request->get('trade_no');
if(empty($trade_no)){
return $this->failure('订单号不为空');
}
$headers = [
'Key' => $this->key, // 自定义头部参数(示例)
];
$url = $this->url . 'order/' . $trade_no . '/callback';
$client = new Client();
$response = $client->post($url, [
'headers' => $headers,
]);
$code = $response->getStatusCode();
if($code != 200){
return $this->failure('支付失败');
}
$body = $response->getBody()->getContents(); // 获取响应内容
$list = json_decode($body, true);
if($list['code'] == 1){
return $this->failure($list['message']);
}
$data = $list['data'] ?? [];
$num = $request->input('num');
Log::info("支付回调--用户购买数量---$num");
if ($num) {
$user_id = $request->input('user_id');
$user = User::find($user_id);
$goods_id = $request->input('goods_id');
$goods_name = $request->input('goods_name');
$sku_name = $request->input('sku_name');
$sku_stock = $request->input('sku_stock');
$map = [];
$map['id'] = $goods_id;
$map['name'] = $goods_name.'/'.$sku_name;
$map['stock'] = $sku_stock;
$map['num'] = $num;
$map['after_num'] = $sku_stock-$num;
$map['type'] = OperateStockLog::TYPE_MP;
$map['remark'] = '用户:'.$user->name.' 购买了商品:'.$goods_name.' 购买数量:'.$num.' 订单号:'.$trade_no;
$map['operate_type'] = OperateStockLog::OPERATE_TYPE_OUT;
$map['status'] = OperateStockLog::OPERATE_STATUS_PASS;
OperateStockLog::addLog($user,$map);
}
return $this->success('ok',$data);
}catch (\Exception $e) {
Log::error('orderCallback:' . $e->getMessage());
return $this->failure('支付失败');
}
}
/**
* 签收订单
* @param Request $request
*/
public function takeGoods(Request $request){
try {
$order_id = $request->input('id');
if(empty($order_id)){
return $this->failure('订单id不为空');
}
$user = auth()->user();
$accid = User::SAAS_PREFIX.$user->id;
$headers = [
'Key' => $this->key, // 自定义头部参数(示例)
];
$url = $this->url . 'sign/orders/' . $order_id ;
$client = new Client();
$response = $client->post($url, [
'headers' => $headers,
'json' => [
'accid' => $accid,
],
]);
$code = $response->getStatusCode();
if($code != 200){
return $this->failure('支付失败');
}
$body = $response->getBody()->getContents(); // 获取响应内容
$list = json_decode($body, true);
if($list['code'] == 1){
return $this->failure($list['message']);
}
$data = $list['data'] ?? [];
return $this->success('ok', $data);
}catch (\Exception $e) {
Log::error('takeGoods:' . $e->getMessage());
return $this->failure('签收失败');
}
}
public function takeGoodsV2(Request $request)
{
$order_id = $request->input('id');
$order = ShopOrder::find($order_id);
if ($order->pay_status != ShopOrder::SENDSTATUS) return $this->failure("该订单状态暂不能签收");
//修改订单状态
$order->update(['pay_status'=>ShopOrder::SIGNEDSTATUS]);
ShopOrderStatus::create(['order_id'=>$order->id, 'status'=>ShopOrder::SIGNEDSTATUS]);
return $this->success('ok');
}
}