This commit is contained in:
youda 2025-05-13 16:05:15 +08:00
parent 6754ace425
commit 0d3c550f5b
8 changed files with 432 additions and 40 deletions

View File

@ -186,4 +186,48 @@ class Diamond extends Base
return $this->err('删除失败');
}
}
/**
* 更改钻石商品状态
*/
public function status()
{
if (!request()->isPost()) {
return $this->err('请求方式错误');
}
$id = input('post.id/d', 0);
$status = input('post.status/d', 0);
if (!$id) {
return $this->err('参数错误');
}
$info = DiamondProducts::getInfo($id);
if (!$info) {
return $this->err('商品不存在');
}
// 更新状态
$result = DiamondProducts::where('id', $id)->update(['status' => $status, 'updated_at' => date('Y-m-d H:i:s')]);
if ($result) {
return $this->succ('状态更新成功');
} else {
return $this->err('状态更新失败');
}
}
/**
* 获取钻石商品最大排序值
*/
public function get_max_sort()
{
$maxSort = DiamondProducts::max('sort_order');
return json([
'status' => 1,
'msg' => '获取成功',
'data' => intval($maxSort)
]);
}
}

View File

@ -473,4 +473,6 @@ Route::rule('diamond', 'Diamond/index', 'GET|POST');
Route::rule('diamond_add', 'Diamond/add', 'GET|POST');
Route::rule('diamond_edit', 'Diamond/edit', 'GET|POST');
Route::rule('diamond_del', 'Diamond/del', 'GET|POST');
Route::rule('diamond_status', 'Diamond/status', 'POST');
Route::rule('diamond_get_max_sort', 'Diamond/get_max_sort', 'GET');

View File

@ -37,11 +37,7 @@
<!-- 商品状态模板 -->
<script type="text/html" id="statusTpl">
{{# if(d.status == 1){ }}
<button class="layui-btn layui-btn-normal layui-btn-radius layui-btn-sm">启用</button>
{{# } else { }}
<button class="layui-btn layui-btn-danger layui-btn-radius layui-btn-sm">禁用</button>
{{# } }}
<input type="checkbox" name="status" lay-skin="switch" lay-filter="statusSwitch" lay-text="启用|禁用" value="{{d.id}}" {{# if(d.status == 1){ }}checked{{# } }}>
</script>
<!-- 是否首充模板 -->
@ -127,8 +123,8 @@
<div class="layui-form-item">
<label class="layui-form-label">是否首充</label>
<div class="layui-input-inline">
<input type="radio" name="is_first" value="1" title="是" lay-filter="is_first" {{# if(d.is_first == 1){ }}checked{{# } }}>
<input type="radio" name="is_first" value="0" title="否" lay-filter="is_first" {{# if(d.is_first == 0){ }}checked{{# } }}>
<input type="radio" name="is_first" value="1" title="是" lay-filter="is_first" {{# if(d.is_first == 1 || d.id === undefined){ }}checked{{# } }}>
<input type="radio" name="is_first" value="0" title="否" lay-filter="is_first" {{# if(d.is_first == 0 && d.id !== undefined){ }}checked{{# } }}>
</div>
</div>
@ -162,8 +158,8 @@
</div>
<label class="layui-form-label">状态</label>
<div class="layui-input-inline">
<input type="radio" name="status" value="1" title="启用" {{# if(d.status == 1){ }}checked{{# } }}>
<input type="radio" name="status" value="0" title="禁用" {{# if(d.status == 0){ }}checked{{# } }}>
<input type="radio" name="status" value="1" title="启用" {{# if(d.status == 1 || d.id === undefined){ }}checked{{# } }}>
<input type="radio" name="status" value="0" title="禁用" {{# if(d.status == 0 && d.id !== undefined){ }}checked{{# } }}>
</div>
</div>
@ -199,7 +195,7 @@
{ field: 'is_first', title: '是否有首充', width: 100, templet: '#isFirstTpl' },
{ field: 'normal_image', title: '展示图', width: 120, templet: '#imageTpl' },
{ field: 'sort_order', title: '排序', width: 80 },
{ field: 'status', title: '状态', width: 80, templet: '#statusTpl' },
{ field: 'status', title: '状态', width: 120, templet: '#statusTpl' },
{ field: 'created_at', title: '创建时间', width: 160 },
{ field: 'updated_at', title: '更新时间', width: 160 },
{ fixed: 'right', title: '操作', toolbar: '#toolbarTpl', width: 150 }
@ -230,35 +226,46 @@
var first_bonus_reward_instance = null;
// 添加按钮点击事件
$('#addBtn').on('click', function () {
layer.open({
type: 1,
title: '添加钻石商品',
area: ['900px', '90%'],
content: laytpl($('#formTpl').html()).render({ d: {} }),
success: function (layero, index) {
form.render();
initUpload();
// 页面加载时初始化奖励信息区域
base_reward_instance = initRewardInfo('base_reward_container', null, 'base_reward');
console.log(base_reward_instance);
// 获取当前最大排序值
$.get('{:url("/admin/diamond_get_max_sort")}', function(res) {
const maxSort = res.data || 0;
console.log(maxSort);
layer.open({
type: 1,
title: '添加钻石商品',
area: ['800px', '90%'],
content: laytpl($('#formTpl').html()).render({ d: {sort_order: maxSort + 1} }),
success: function (layero, index) {
form.render();
initUpload();
// 页面加载时初始化奖励信息区域
base_reward_instance = initRewardInfo('base_reward_container', null, 'base_reward');
console.log(base_reward_instance);
first_bonus_reward_instance = initRewardInfo('first_bonus_reward_container', null, 'first_bonus_reward');
// 监听关闭按钮点击事件
$('.closeBtn').on('click', function() {
layer.closeAll('page');
});
// 监听是否首充单选框变化
form.on('radio(is_first)', function (data) {
var value = data.value;
if (value == 1) {
$(data.elem).closest('.layui-form').find('.first-charge-fields').show();
} else {
$(data.elem).closest('.layui-form').find('.first-charge-fields').hide();
}
});
}
first_bonus_reward_instance = initRewardInfo('first_bonus_reward_container', null, 'first_bonus_reward');
// 监听关闭按钮点击事件
$('.closeBtn').on('click', function() {
layer.closeAll('page');
});
// 监听是否首充单选框变化
form.on('radio(is_first)', function (data) {
var value = data.value;
if (value == 1) {
$(data.elem).closest('.layui-form').find('.first-charge-fields').show();
} else {
$(data.elem).closest('.layui-form').find('.first-charge-fields').hide();
}
});
form.val('diamondForm', {sort_order: maxSort + 1});
// 默认显示首充字段
$('.first-charge-fields').show();
form.render();
}
});
});
});
@ -364,6 +371,34 @@
return false;
});
// 监听状态开关切换
form.on('switch(statusSwitch)', function(obj){
var id = this.value;
var status = obj.elem.checked ? 1 : 0;
$.ajax({
url: '{:url("/admin/diamond_status")}',
type: 'post',
data: { id: id, status: status },
success: function(res) {
if (res.status === 1) {
layer.msg(res.msg, { icon: 1, time: 1000 });
} else {
// 如果修改失败,将开关状态切换回去
obj.elem.checked = status === 0 ? true : false;
form.render('checkbox');
layer.msg(res.msg, { icon: 2, time: 1500 });
}
},
error: function() {
// 如果请求出错,将开关状态切换回去
obj.elem.checked = status === 0 ? true : false;
form.render('checkbox');
layer.msg('操作失败,请重试', { icon: 2, time: 1500 });
}
});
});
// 初始化图片上传
function initUpload() {
$('.upload-image').each(function () {

View File

@ -15,6 +15,8 @@ use app\common\model\Order;
use app\common\model\OrderList;
use app\common\model\UserVip;
use app\common\model\UserCoupon;
use app\common\model\DiamondProducts;
use app\common\model\DiamondOrder;
use think\facade\Db;
use app\common\model\CouponReceive as CouponReceiveModel;
use \think\Request;
@ -868,4 +870,112 @@ class Mall extends Base
return $this->renderSuccess('请求成功', $data);
}
public function get_diamond_list()
{
$diamond_list = Db::name('diamond_products')->field('products_id,name,normal_image,normal_select_image,price,status,is_first,first_charge_image,first_select_charge_image')
->where(['status' => 1])
->where('products_type', '=', 1)
->order('sort_order asc')
->select()->toArray();
$user_id = $this->getuserid();
$diamond_order_count = 0;
if ($user_id > 0) {
$diamond_order_count = DiamondOrder::where('user_id', $user_id)
->where('status', '=', 'success')->count();
}
foreach ($diamond_list as &$value) {
//商品有首充,并且用户没有购买记录,才显示首充
if ($value['is_first'] == 1 && $diamond_order_count == 0) {
$value['image'] = $value['first_charge_image'];
$value['select_image'] = $value['first_select_charge_image'];
} else {
$value['image'] = $value['normal_image'];
$value['select_image'] = $value['normal_select_image'];
}
unset($value['normal_image']);
unset($value['normal_select_image']);
unset($value['first_charge_image']);
unset($value['first_select_charge_image']);
unset($value['is_first']);
}
return $this->renderSuccess('请求成功', $diamond_list);
}
public function createOrderProducts()
{
$user_id = $this->getuserid();
if ($user_id == 0) {
return $this->renderError("未登录");
}
$product_id = request()->param('product_id', '');
$pay_type = request()->param('pay_type/d', 2); //1.小程序微信支付2.h5支付宝3.app微信4.app支付宝
$diamond_product = DiamondProducts::where('products_id', '=', $product_id)->find();
if (!$diamond_product) {
return $this->renderError("商品不存在");
}
if ($diamond_product['status'] != 1) {
return $this->renderError("商品已下架");
}
$redis = (new \app\common\server\RedisHelper())->getRedis();
$redis_key = "kpw_products" . '_' . $user_id;
$redis_key_info = $redis->get($redis_key);
if ($redis_key_info) {
return $this->renderError("当前操作太快了,请等待");
} else {
$redis->set($redis_key, 1, 10);
}
// 查询用户钻石订单数,判断是否首充
$diamond_order_count = DiamondOrder::where('user_id', $user_id)
->where('status', '=', DiamondOrder::STATUS_SUCCESS)->count();
Db::startTrans();
try {
$user = $this->getUser();
$attach = 'order_product';
$title = '购买钻石' . $diamond_product['name'];
$price = $diamond_product['price'];
$payRes = \app\common\server\platform\PlatformFactory::createPay($user, $diamond_product['price'], $title, $attach, "ZS_");
if ($payRes['status'] !== 1) {
throw new \Exception(isset($payRes['msg']) ? $payRes['msg'] : "购买失败,请刷新重试");
}
$order_num = $payRes['data']['order_no'];
// 创建钻石订单
$order_id = DiamondOrder::insertGetId([
'order_no' => $order_num,
'user_id' => $user['id'],
'diamond_id' => $diamond_product['id'],
'product_id' => $product_id,
'amount_paid' => $price,
'pay_method' => $pay_type == 1 || $pay_type == 3 ? DiamondOrder::PAY_METHOD_WECHAT : DiamondOrder::PAY_METHOD_ALIPAY,
'is_first_charge' => $diamond_order_count == 0 ? 1 : 0,
'status' => DiamondOrder::STATUS_PENDING,
'created_at' => date('Y-m-d H:i:s')
]);
if (!$order_id) {
throw new \Exception("订单创建失败");
}
Db::commit();
// 删除redis锁
$redis->del($redis_key);
return $this->renderSuccess("下单成功", [
'status' => 1,
'order_num' => $order_num,
'res' => $payRes['data']['res'],
]);
} catch (\Exception $e) {
Db::rollback();
// 删除redis锁
$redis->del($redis_key);
return $this->renderError($e->getMessage());
}
}
}

View File

@ -2819,6 +2819,81 @@ class Notify extends Base
$this->wx_gf_fahuo($user_id, $order_num);
}
} elseif ($order_type == 'order_product') {
// 钻石订单处理逻辑
$diamondOrder = \app\common\model\DiamondOrder::where('order_no', '=', $order_num)
->where('status', '=', \app\common\model\DiamondOrder::STATUS_PENDING)
->find();
if (!$diamondOrder) {
writelog('pay_notify_error', "未找到钻石订单或状态错误: " . $order_num);
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '未找到钻石订单或状态错误');
Db::rollback();
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
return;
}
// 验证用户ID是否一致
if ($diamondOrder['user_id'] != $user_id) {
writelog('pay_notify_error', "用户ID不匹配: 通知中的用户ID={$user_id}, 钻石订单中的用户ID={$diamondOrder['user_id']}");
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '用户ID不匹配');
Db::rollback();
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
return;
}
$price = $diamondOrder['amount_paid'];
// 查询钻石商品信息
$diamondProduct = \app\common\model\DiamondProducts::where('id', '=', $diamondOrder['diamond_id'])->find();
if (!$diamondProduct) {
writelog('pay_notify_error', "未找到钻石商品: " . $diamondOrder['diamond_id']);
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '未找到钻石商品');
Db::rollback();
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
return;
}
$reward_log = '';
if ($diamondProduct['base_reward'] == "") {
writelog('pay_notify_error', "商品没有设置基础奖励: " . $diamondOrder['diamond_id']);
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '商品没有设置基础奖励');
Db::rollback();
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
return;
}
// 给用户钱包加钻石
$reward_res = RewardService::sendReward($user_id, $diamondProduct['base_reward'], '购买商品' . $diamondProduct['name']);
if ($reward_res) {
$reward_log = '购买商品' . implode(',', $reward_res['data']);
}
//判断商品是否开启首充
if ($diamondProduct['is_first'] == 1) {
//判断是否有首充
$diamond_order_count = \app\common\model\DiamondOrder::where('user_id', $user_id)
->where('status', '=', 'success')->count();
if ($diamond_order_count == 0 && $diamondProduct['first_bonus_reward'] != '') {
$reward_res = RewardService::sendReward($user_id, $diamondProduct['first_bonus_reward'], '首充赠送');
$reward_log = '首充赠送' . implode(',', $reward_res['data']);
}
}
// 更新订单状态为支付成功
$res[] = $diamondOrder->save([
'status' => \app\common\model\DiamondOrder::STATUS_SUCCESS,
'paid_at' => date('Y-m-d H:i:s'),
'reward_log' => '支付成功,' . $reward_log
]);
// 记录支付信息
$res[] = Db::name('profit_pay')->insert([
'user_id' => $user_id,
'order_num' => $order_num,
'change_money' => $price,
'content' => '购买钻石' . $diamondProduct['name'],
'pay_type' => $payment_type == 'alipay' ? 2 : 1,
'addtime' => time(),
]);
} else {
// 普通盒子订单处理逻辑
$orderInfo = Order::where('order_num', '=', $order_num)
@ -2905,6 +2980,13 @@ class Notify extends Base
// 标记订单为卡单状态
if ($order_type == 'order_list_send') {
OrderListSend::where(['send_num' => $order_num])->update(['kd_is' => 1]);
} elseif ($order_type == 'order_product') {
// 钻石订单处理异常,标记为失败状态
\app\common\model\DiamondOrder::where(['order_no' => $order_num])
->update([
'status' => \app\common\model\DiamondOrder::STATUS_FAILED,
'reward_log' => '支付处理异常: ' . $e->getMessage()
]);
} else {
Order::where(['order_num' => $order_num])->update(['kd_is' => 1]);
}

View File

@ -1254,5 +1254,35 @@ class User extends Base
}
}
/**
* 我的
*/
public function userInfo(Request $request)
{
$user_id = $this->getuserid();
if ($user_id == 0) {
return $this->renderError("未登录");
}
$user = Usermodel::where('id', '=', $user_id)->find();
if (!$user) {
return $this->renderError("用户不存在");
}
$userinfo['id'] = $user['id'];
$userinfo['ID'] = $user['id'];
$userinfo['mobile_is'] = $user['mobile'] ? 1 : 0;
$userinfo['nickname'] = $user['nickname'];
$userinfo['headimg'] = imageUrl($user['headimg']);
$userinfo['mobile'] = $user['mobile'] ? substr_replace($user['mobile'], '****', 3, 4) : '';
$userinfo['money'] = $user['money'];//钻石
$userinfo['money2'] = $user['money2'];//达达券
$userinfo['integral'] = $user['integral'];//UU币
$userinfo['uid'] = $user['uid'] ? $user['uid'] : $user['id'];
$day = floor(abs(time() - $user['addtime']) / 86400);
$userinfo['day'] = $day;
return $this->renderSuccess("请求成功", $userinfo);
}
}

View File

@ -47,6 +47,7 @@ Route::any('getDanye', 'Index/getDanye');
#User.php个人中心
#============================
Route::any('user', 'User/user');
Route::any('userInfo', 'User/userInfo');
Route::any('update_userinfo', 'User/update_userinfo');
Route::any('vip_list', 'User/vip_list');
Route::any('profitIntegral', 'User/profitIntegral');
@ -235,4 +236,10 @@ Route::any('getAddressList', 'Other/getAddressList');
Route::any('deleteAddress', 'Other/deleteAddress');
Route::any('setDefaultAddress', 'Other/setDefaultAddress');
Route::any('getAddressDetail', 'Other/getAddressDetail');
#=============用户地址管理=============
#=============用户地址管理=============
#============================
# 钻石管理
#============================
Route::any('get_diamond_list', 'Mall/get_diamond_list');
Route::any('createOrderProducts', 'Mall/createOrderProducts');

View File

@ -0,0 +1,82 @@
<?php
declare (strict_types = 1);
namespace app\common\model;
use think\Model;
/**
* 钻石支付订单记录模型
*/
class DiamondOrder extends Model
{
// 表名
protected $name = 'diamond_orders';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
// 定义时间戳字段名
protected $createTime = 'created_at';
protected $updateTime = false; // 不使用更新时间
// 类型转换
protected $type = [
'id' => 'integer',
'user_id' => 'integer',
'diamond_id' => 'integer',
'amount_paid' => 'float',
'is_first_charge' => 'boolean',
];
// 设置只读字段
protected $readonly = ['order_no'];
// 订单状态常量
const STATUS_PENDING = 'pending';
const STATUS_SUCCESS = 'success';
const STATUS_FAILED = 'failed';
// 支付方式常量
const PAY_METHOD_ALIPAY = 'alipay';
const PAY_METHOD_WECHAT = 'wechat';
/**
* 关联用户
*/
public function user()
{
return $this->belongsTo('User', 'user_id');
}
/**
* 获取订单状态列表
*/
public static function getStatusList()
{
return [
self::STATUS_PENDING => '待支付',
self::STATUS_SUCCESS => '支付成功',
self::STATUS_FAILED => '支付失败'
];
}
/**
* 获取支付方式列表
*/
public static function getPayMethodList()
{
return [
self::PAY_METHOD_ALIPAY => '支付宝',
self::PAY_METHOD_WECHAT => '微信支付'
];
}
/**
* 生成唯一订单号
*/
public static function generateOrderNo()
{
return date('YmdHis') . substr(implode('', array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
}