diff --git a/app/admin/controller/Base.php b/app/admin/controller/Base.php index 1a8627f..6af5dfa 100755 --- a/app/admin/controller/Base.php +++ b/app/admin/controller/Base.php @@ -21,6 +21,7 @@ class Base extends MyController public $page_num = '10'; public $admin_id = 0; + public $config = []; /** * 后台初始化 */ @@ -277,5 +278,44 @@ class Base extends MyController return $uid; // 如果未找到或未配置,返回原值 } + /** + * 生成不带连字符的UUID(可选前缀) + * @param string $prefix 4位前缀(字母或数字) + * @param bool $withHyphens 是否包含连字符(默认false) + * @return string + */ + protected function generateUUIDWithPrefix(string $prefix = '', bool $withHyphens = false) + { + // 验证前缀 + if (!empty($prefix)) { + if (strlen($prefix) !== 4 || !ctype_alnum($prefix)) { + throw new \InvalidArgumentException('前缀必须是4位字母或数字'); + } + $prefix = strtoupper($prefix); + } + // 生成UUID(不带连字符的原始数据) + $uuid = sprintf( + '%04x%04x%04x%04x%04x%04x%04x%04x', + mt_rand(0, 0xffff), + mt_rand(0, 0xffff), + mt_rand(0, 0xffff), + mt_rand(0, 0x0fff) | 0x4000, + mt_rand(0, 0x3fff) | 0x8000, + mt_rand(0, 0xffff), + mt_rand(0, 0xffff), + mt_rand(0, 0xffff) + ); + + // 可选:重新添加连字符(标准UUID格式) + if ($withHyphens) { + $uuid = substr($uuid, 0, 8) . '-' . + substr($uuid, 8, 4) . '-' . + substr($uuid, 12, 4) . '-' . + substr($uuid, 16, 4) . '-' . + substr($uuid, 20, 12); + } + + return $prefix ? $prefix . ($withHyphens ? '-' : '') . $uuid : $uuid; + } } diff --git a/app/admin/controller/Goods.php b/app/admin/controller/Goods.php index 02de763..0158a52 100755 --- a/app/admin/controller/Goods.php +++ b/app/admin/controller/Goods.php @@ -20,7 +20,7 @@ class Goods extends Base */ public function goods(Request $request) { - + return View::fetch("Goods/goods"); } @@ -34,7 +34,7 @@ class Goods extends Base $title = $request->param('title/s', ''); $status = $request->param('status/s', ''); $type = $request->param('type/s', ''); - + // 构建查询条件 $where = []; if (!empty($title)) { @@ -46,12 +46,12 @@ class Goods extends Base if ($type !== '') { $where[] = ['type', '=', $type]; } - + $query = GoodsModel::where($where)->order('id desc'); $count = $query->count(); - + $list = $query->page($page, $limit)->select()->toArray(); - + // 处理图片路径 foreach ($list as &$item) { $item['imgurl'] = imageUrl($item['imgurl']); @@ -61,10 +61,10 @@ class Goods extends Base // 添加格式化时间 $item['addtime_text'] = date('Y-m-d H:i', $item['addtime']); } - + return $this->renderTable('获取成功', $count, $list); } - + /** * 获取盒子类型列表(前后端分离接口) */ @@ -77,7 +77,7 @@ class Goods extends Base ->order('sort_order') ->select() ->toArray(); - + return $this->renderTable('获取成功', count($goodsTypeList), $goodsTypeList); } @@ -89,7 +89,7 @@ class Goods extends Base if (!$request->isPost()) { $item_card = \app\common\model\ItemCard::where('id', '<', 3)->select()->toArray(); $shang = Shang::where('id', 'between', [34, 38])->select()->toArray(); - + // 查询可用的盒子类型 $goodsTypeList = Db::name('goods_type') ->field('value,sort_order,remark,is_fenlei,fl_name') @@ -97,7 +97,7 @@ class Goods extends Base ->order('sort_order') ->select() ->toArray(); - + View::assign('goodsTypeList', $goodsTypeList); View::assign('shang', $shang); View::assign('item_card', $item_card); @@ -121,7 +121,7 @@ class Goods extends Base } else { $data['daily_xiangou'] = intval($data['daily_xiangou']); } - if ($data['type'] == 1||$data['type'] == 11) { + if ($data['type'] == 1 || $data['type'] == 11) { if (RegInt($data['stock'])) { return $this->renderError("库存输入不规范,请设置大于0的整数"); } @@ -278,7 +278,7 @@ class Goods extends Base $type = $info['type']; $item_card = \app\common\model\ItemCard::where('id', '<', 3)->select()->toArray(); $shang = Shang::where('id', 'between', [34, 38])->select()->toArray(); - + // 查询可用的盒子类型 $goodsTypeList = Db::name('goods_type') ->field('value,sort_order,remark,is_fenlei,fl_name') @@ -286,18 +286,18 @@ class Goods extends Base ->order('sort_order') ->select() ->toArray(); - + View::assign('goodsTypeList', $goodsTypeList); View::assign('shang', $shang); View::assign('item_card', $item_card); View::assign('type', $type); View::assign('info', $info); - + // 确保daily_xiangou字段存在 if (!isset($info['daily_xiangou'])) { $info['daily_xiangou'] = 0; } - + return View::fetch("Goods/goods_edit"); } else { $data = input('post.'); @@ -326,7 +326,7 @@ class Goods extends Base $data['daily_xiangou'] = intval($data['daily_xiangou']); } $type = $info['type']; - if ($type == 1||$type == 11) { + if ($type == 1 || $type == 11) { if (RegInt($data['stock'])) { return $this->renderError("库存输入不规范,请设置大于0的整数"); } @@ -434,7 +434,7 @@ class Goods extends Base Db::startTrans(); $res = []; #添加套 - if ($type == 1 || $type == 11 || $type == 5 ||$type == 10 || $type == 6) { + if ($type == 1 || $type == 11 || $type == 5 || $type == 10 || $type == 6) { if (($data['stock'] > $info['stock'])) { #赏品 $goods_list = GoodsList::where(['goods_id' => $info['id']]) @@ -460,9 +460,9 @@ class Goods extends Base } $res[] = $info->allowField([])->update($data); #添加日志 - $info['update_time'] = date('Y-m-d H:i:i:s',$info['update_time']); - $data['update_time'] = date('Y-m-d H:i:i:s',$data['update_time']); - $res[] = AdminGoodsLog::add_goods_log(session('admin_id'),$info['id'],0,json_encode($info),json_encode($data)); + $info['update_time'] = date('Y-m-d H:i:i:s', $info['update_time']); + $data['update_time'] = date('Y-m-d H:i:i:s', $data['update_time']); + $res[] = AdminGoodsLog::add_goods_log(session('admin_id'), $info['id'], 0, json_encode($info), json_encode($data)); if (resCheck($res)) { Db::commit(); return $this->renderSuccess("编辑成功"); @@ -489,7 +489,7 @@ class Goods extends Base $result = GoodsModel::where(['id' => $id])->update(['status' => $status]); } elseif ($status == 3) { $result = GoodsModel::where(['id' => $id])->update(['delete_time' => time(), 'status' => 2]); -// $goods = GoodsList::field('id')->where(['goods_id' => $id])->find(); + // $goods = GoodsList::field('id')->where(['goods_id' => $id])->find(); // if ($goods) { // GoodsList::field('id')->where(['goods_id' => $id])->delete(); // } @@ -538,7 +538,7 @@ class Goods extends Base $real_pro = 0; foreach ($data['list'] as &$value) { $value['shang'] = Shang::where(['id' => $value['shang_id']])->value('title'); -// if ($value['goods_type'] == 2) { + // if ($value['goods_type'] == 2) { // $value['sale_time'] = date('Y-m-d', $value['sale_time']); // } else { // $value['sale_time'] = ''; @@ -566,7 +566,7 @@ class Goods extends Base if (!$info) { return $this->renderError('请求参数错误'); } - if ($info['type'] == 1 || $info['type'] == 5 || $info['type'] == 10 || $info['type'] == 11|| $info['type'] == 6) { + if ($info['type'] == 1 || $info['type'] == 5 || $info['type'] == 10 || $info['type'] == 11 || $info['type'] == 6) { $shang = Shang::where('id', '<=', 33)->where('id', '<>', 5)->select()->toArray(); } elseif ($info['type'] == 2 || $info['type'] == 8 || $info['type'] == 9) { $shang = Shang::where('id', 'between', [34, 38])->select()->toArray(); @@ -642,8 +642,8 @@ class Goods extends Base $data['prize_code'] = $prize_code; $save_sports_data[] = $data; } - } elseif (in_array($type,[2,8,9])) { - if (RegMoney($data['real_pro']*100)) { + } elseif (in_array($type, [2, 8, 9])) { + if (RegMoney($data['real_pro'] * 100)) { return $this->renderError('真实概率设置错误,最多保留两位小数1'); } @@ -678,14 +678,14 @@ class Goods extends Base if (RegZero($data['sort'])) { return $this->renderError('排序请输入整数'); } -// if ($data['card_no']) { + // if ($data['card_no']) { // $card_no_info = GoodsList::field('id')->where('card_no', '=', $data['card_no'])->find(); // if ($card_no_info) { // return $this->renderError('赠送编号已存在'); // } // } else { - $data['card_no'] = NULL; -// } + $data['card_no'] = NULL; + // } if (empty($data['imgurl'])) { return $this->renderError('请上传图片'); @@ -734,13 +734,13 @@ class Goods extends Base } else { return $this->renderError('请求参数错误1'); } - + View::assign('goods', $goods); View::assign('shang', $shang); View::assign('type', $info['type']); return View::fetch('Goods/goodslist_edit'); } else { - + $data = input('post.'); if (empty($data['id'])) { return $this->renderError('请求参数错误1'); @@ -791,7 +791,7 @@ class Goods extends Base if ($type == 1 || $type == 5 || $type == 10 || $type == 6 || $type == 11) { } elseif ($type == 2 || $type == 8 || $type == 9) { - if (RegMoney($data['real_pro']*1000)) { + if (RegMoney($data['real_pro'] * 1000)) { return $this->renderError('真实概率设置错误,最多保留两位小数'); } } else if ($type == 3) { @@ -804,7 +804,7 @@ class Goods extends Base if (RegZero($data['sort'])) { return $this->renderError('排序请输入整数'); } -// if ($data['card_no']) { + // if ($data['card_no']) { // $card_no_info = GoodsList::field('id') // ->where('prize_code', '<>', $goods['prize_code']) // ->where('card_no', '=', trim($data['card_no'])) @@ -813,8 +813,8 @@ class Goods extends Base // return $this->renderError('赠送编号已存在'); // } // } else { - $data['card_no'] = NULL; -// } + $data['card_no'] = NULL; + // } if (empty($data['imgurl'])) { return $this->renderError('请上传图片'); @@ -822,12 +822,12 @@ class Goods extends Base $data['update_time'] = time(); unset($data['id']); $res1 = GoodsList::where(['prize_code' => $goods['prize_code']])->update($data); - + if ($res1) { #添加日志 - $goods['update_time'] = date('Y-m-d H:i:i:s',$goods['update_time']); - $data['update_time'] = date('Y-m-d H:i:i:s',$data['update_time']); - $res2 = AdminGoodsLog::add_goods_log(session('admin_id'),$info['id'],$goods['id'],json_encode($goods),json_encode($data)); + $goods['update_time'] = date('Y-m-d H:i:i:s', $goods['update_time']); + $data['update_time'] = date('Y-m-d H:i:i:s', $data['update_time']); + $res2 = AdminGoodsLog::add_goods_log(session('admin_id'), $info['id'], $goods['id'], json_encode($goods), json_encode($data)); return $this->renderSuccess('编辑成功'); } else { return $this->renderError('编辑失败'); @@ -1173,10 +1173,10 @@ class Goods extends Base public function get_sync_addresses() { $config = getConfig('systemconfig'); - $syncAddresses = isset($config['sync_address']) && is_array($config['sync_address']) - ? $config['sync_address'] + $syncAddresses = isset($config['sync_address']) && is_array($config['sync_address']) + ? $config['sync_address'] : []; - + return $this->renderSuccess('获取成功', $syncAddresses); } @@ -1188,13 +1188,13 @@ class Goods extends Base $goods_id = trim(input('get.goods_id')); $start_time = trim(input('get.start_time')); $end_time = trim(input('get.end_time')); - + $whe = []; - + if ($goods_id) { $whe[] = ['goods_id', '=', $goods_id]; } - + if ($start_time && $end_time) { $start = strtotime($start_time); $end = strtotime($end_time . ' 23:59:59'); @@ -1206,7 +1206,7 @@ class Goods extends Base $end = strtotime($end_time . ' 23:59:59'); $whe[] = ['create_time', '<=', $end]; } - + // 获取日志数据 $list = Db::name('goods_offshelf_log') ->where($whe) @@ -1215,18 +1215,18 @@ class Goods extends Base 'list_rows' => $this->page, 'query' => request()->param(), ]); - + // 获取所有相关的盒子信息 $goodsIds = array_column($list->items(), 'goods_id'); $goodsInfo = []; - + if (!empty($goodsIds)) { $goods = Db::name('goods') ->field('id, title, status') ->whereIn('id', $goodsIds) ->select() ->toArray(); - + foreach ($goods as $item) { $goodsInfo[$item['id']] = [ 'title' => $item['title'], @@ -1234,7 +1234,7 @@ class Goods extends Base ]; } } - + // 转换时间戳并处理数据 $listItems = $list->items(); foreach ($listItems as &$item) { @@ -1242,7 +1242,7 @@ class Goods extends Base $item['goods_title'] = isset($goodsInfo[$item['goods_id']]) ? $goodsInfo[$item['goods_id']]['title'] : '未知盒子'; $item['goods_status'] = isset($goodsInfo[$item['goods_id']]) ? $goodsInfo[$item['goods_id']]['status'] : 2; // 默认下架状态 } - + View::assign('list', $listItems); View::assign('page', $list->render()); View::assign('count', $list->total()); @@ -1256,21 +1256,21 @@ class Goods extends Base { $goods_id = $this->request->post('goods_id/d', 0); $targets = $this->request->post('targets/a', []); - + if (empty($goods_id)) { return $this->renderError('盒子ID不能为空'); } - + if (empty($targets)) { return $this->renderError('同步目标不能为空'); } - + # 获取盒子数据 $goods = \app\common\model\Goods::find($goods_id); if (!$goods) { return $this->renderError('盒子不存在'); } - + # 检查是否有async_code,没有则生成 if (empty($goods['async_code'])) { $async_code = $this->generateUUID(); @@ -1280,10 +1280,10 @@ class Goods extends Base } else { $async_code = $goods['async_code']; } - + # 获取盒子奖品数据 $goodsList = \app\common\model\GoodsList::where('goods_id', $goods_id)->select()->toArray(); - + # 准备同步数据 $syncData = [ 'goods' => $goods->toArray(), @@ -1291,12 +1291,12 @@ class Goods extends Base 'async_code' => $async_code, 'sync_time' => time() ]; - + # 发送到所有目标 $successCount = 0; $failCount = 0; $errorMessages = []; - + foreach ($targets as $target) { $result = $this->sendSyncData($target, $syncData); if ($result['success']) { @@ -1306,11 +1306,11 @@ class Goods extends Base $errorMessages[] = $target . ': ' . $result['message']; } } - + # 更新同步状态 $goods->async_date = date('Y-m-d H:i:s'); $goods->save(); - + if ($failCount == 0) { return $this->renderSuccess("同步成功,已成功同步到 {$successCount} 个目标"); } else if ($successCount > 0) { @@ -1340,13 +1340,13 @@ class Goods extends Base try { // 清空订单表 $orderCount = Db::name('order')->where('goods_id', $id)->delete(); - + // 清空订单详情表 $orderListCount = Db::name('order_list')->where('goods_id', $id)->delete(); - + // 提交事务 Db::commit(); - + // 记录管理员操作日志 AdminGoodsLog::add_goods_log( session('admin_id'), @@ -1359,7 +1359,7 @@ class Goods extends Base 'clear_order_list_count' => $orderListCount ]) ); - + return $this->renderSuccess("操作成功,共清空订单 {$orderCount} 条,订单详情 {$orderListCount} 条"); } catch (\Exception $e) { // 回滚事务 @@ -1371,17 +1371,22 @@ class Goods extends Base /** * 生成UUID */ - private function generateUUID() + private function generateUUID() { - return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', - mt_rand(0, 0xffff), mt_rand(0, 0xffff), + return sprintf( + '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', + mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, - mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) + mt_rand(0, 0xffff), + mt_rand(0, 0xffff), + mt_rand(0, 0xffff) ); } + /** * 发送同步数据到目标 */ @@ -1390,7 +1395,7 @@ class Goods extends Base try { # 准备请求数据 $jsonData = json_encode($data); - + # 初始化CURL $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $target . "/api/goods/receive_sync"); @@ -1402,30 +1407,30 @@ class Goods extends Base 'Content-Length: ' . strlen($jsonData) ]); curl_setopt($ch, CURLOPT_TIMEOUT, 30); # 30秒超时 - + # 执行请求 $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); - + if ($error) { return ['success' => false, 'message' => "CURL错误: $error"]; } - + if ($httpCode != 200) { return ['success' => false, 'message' => "HTTP错误码: $httpCode"]; } - + $result = json_decode($response, true); if (!$result || !isset($result['status'])) { return ['success' => false, 'message' => "无效的响应: $response"]; } - + if ($result['status'] != 1) { return ['success' => false, 'message' => $result['msg'] ?? '同步失败']; } - + return ['success' => true]; } catch (\Exception $e) { return ['success' => false, 'message' => "异常: " . $e->getMessage()]; diff --git a/app/admin/controller/Reward.php b/app/admin/controller/Reward.php new file mode 100644 index 0000000..12dba13 --- /dev/null +++ b/app/admin/controller/Reward.php @@ -0,0 +1,233 @@ +page); + + // 获取关联的优惠券信息 + foreach ($data['list'] as $key => &$item) { + if ($item['reward_type'] == 1 && !empty($item['reward_id'])) { + $coupon = Coupon::find($item['reward_id']); + $item['coupon'] = $coupon; + } + } + + View::assign('list', $data['list']); + View::assign('count', $data['count']); + View::assign('page', $data['page']); + View::assign('reward_type', $reward_type); + + return View::fetch("Reward/index"); + } + + /** + * 添加奖励 + */ + public function add(Request $request) + { + if (!$request->isPost()) { + // 获取优惠券列表供选择 + $coupons = Coupon::where('status', 0)->select(); + View::assign('coupons', $coupons); + + return View::fetch("Reward/add"); + } else { + $data = input('post.'); + + // 处理优惠券类型的特殊情况 + if ($data['reward_type'] == 1) { + if (empty($data['reward_id'])) { + return $this->renderError("请选择优惠券"); + } + + // 获取优惠券信息,设置默认标题 + if (empty($data['title'])) { + $coupon = Coupon::find($data['reward_id']); + if ($coupon) { + $data['title'] = $coupon['title']; + } + } + } else { + // 非优惠券类型,reward_id设为0 + $data['reward_id'] = 0; + } + + $data['create_time'] = time(); + $data['update_time'] = time(); + + $result = RewardModel::insertGetId($data); + + if ($result) { + return $this->renderSuccess("添加成功"); + } else { + return $this->renderError("添加失败"); + } + } + } + + /** + * 编辑奖励 + */ + public function edit(Request $request) + { + if (!$request->isPost()) { + $id = input('get.id/d', 0); + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + $info = RewardModel::find($id); + if (empty($info)) { + return $this->renderError("奖励不存在"); + } + + // 获取优惠券列表供选择 + $coupons = Coupon::where('status', 0)->select(); + + View::assign('info', $info); + View::assign('coupons', $coupons); + + return View::fetch("Reward/edit"); + } else { + $data = input('post.'); + $id = isset($data['id']) ? intval($data['id']) : 0; + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + // 处理优惠券类型的特殊情况 + if ($data['reward_type'] == 1) { + if (empty($data['reward_id'])) { + return $this->renderError("请选择优惠券"); + } + } else { + // 非优惠券类型,reward_id设为0 + $data['reward_id'] = 0; + } + + $data['update_time'] = time(); + + $result = RewardModel::where('id', $id)->update($data); + + if ($result !== false) { + return $this->renderSuccess("编辑成功"); + } else { + return $this->renderError("编辑失败"); + } + } + } + + /** + * 删除奖励 + */ + public function delete(Request $request) + { + $id = input('post.id/d', 0); + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + $result = RewardModel::destroy($id); + + if ($result) { + return $this->renderSuccess("删除成功"); + } else { + return $this->renderError("删除失败"); + } + } + + /** + * 修改状态 + */ + public function status(Request $request) + { + $id = input('post.id/d', 0); + $status = input('post.status/d', 0); + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + $result = RewardModel::where('id', $id)->update(['status' => $status, 'update_time' => time()]); + + if ($result !== false) { + return $this->renderSuccess("状态更新成功"); + } else { + return $this->renderError("状态更新失败"); + } + } + + /** + * 根据reward_id获取奖励列表 + */ + public function getRewardsByRewardId(Request $request) + { + $reward_id = trim(input('get.reward_id', '')); + + if (empty($reward_id)) { + return json([ + 'code' => 1, + 'msg' => '参数错误', + 'data' => [] + ]); + } + + try { + // 查询对应的奖励列表 + $rewards = RewardModel::where('reward_id', $reward_id)->select()->toArray(); + + // 处理优惠券数据 + foreach ($rewards as &$reward) { + if ($reward['reward_type'] == 1) { // 优惠券类型 + // 查询优惠券信息 + $coupon = Coupon::find($reward['reward_extend']); + if ($coupon) { + $reward['coupon'] = $coupon; + } + } + } + + return json([ + 'code' => 0, + 'msg' => '获取成功', + 'data' => $rewards + ]); + } catch (\Exception $e) { + return json([ + 'code' => 1, + 'msg' => '获取奖励失败: ' . $e->getMessage(), + 'data' => [] + ]); + } + } +} \ No newline at end of file diff --git a/app/admin/controller/SignConfig.php b/app/admin/controller/SignConfig.php new file mode 100644 index 0000000..c7b7f50 --- /dev/null +++ b/app/admin/controller/SignConfig.php @@ -0,0 +1,386 @@ +page); + + // foreach ($data['list'] as $key => &$item) { + // // 获取关联的奖励 + // $rewardIds = SignConfigReward::getRewardIds($item['id']); + // $rewards = RewardModel::whereIn('id', $rewardIds)->select()->toArray(); + // $item['rewards'] = $rewards; + // } + + View::assign('list', $data['list']); + View::assign('count', $data['count']); + View::assign('page', $data['page']); + View::assign('type', $type); + return View::fetch("SignConfig/index"); + } + + public function getSignConfigList(Request $request) + { + $type = trim(input('get.type', 1)); + $keyword = trim(input('get.keyword')); + $limit = trim(input('get.limit', 1)); + $where = []; + if (!empty($keyword)) { + $where[] = ['title', 'like', '%' . $keyword . '%']; + } + + $where[] = ['type', '=', $type]; + $field = "*"; + $order = "sort asc, id asc"; + $data = SignConfigModel::getList($where, $field, $order, $limit); + + // 获取每个配置的奖励信息 + foreach ($data['list'] as $key => &$item) { + // 获取关联的奖励 + $rewards = RewardModel::where('reward_id', $item['reward_id'])->select()->toArray(); + $item['rewards'] = $rewards; + } + + return $this->renderTable('获取成功', $data['count'], $data['list']); + } + + /** + * 添加签到配置 + */ + public function add(Request $request) + { + if (!$request->isPost()) { + $type = input('get.type', 1); + + // 获取奖励列表供选择 + // $rewards = RewardModel::where('reward_id', 1)->select(); + + // 获取优惠券列表供选择 + $coupons = Coupon::where('status', 0)->select(); + + View::assign('type', $type); + + return View::fetch("SignConfig/add"); + } else { + $data = input('post.'); + //签到奖励 + $reward = json_decode($data['reward'], true); + unset($data['reward']); + $data['create_time'] = time(); + $data['update_time'] = time(); + //奖励关联表 + $data['reward_id'] = 'MHQD' . date('YmdHis') . mt_rand(1000, 9999); + // 开启事务 + \think\facade\Db::startTrans(); + try { + // 添加签到配置 + $configId = SignConfigModel::insertGetId($data); + + // 添加奖励表数据 + if (!empty($reward) && is_array($reward)) { + foreach ($reward as $item) { + $rewardData = [ + 'reward_type' => $item['reward_type'], + 'reward_value' => isset($item['reward_value']) && !empty($item['reward_value']) ? $item['reward_value'] : 0, + 'reward_extend' => isset($item['coupon_id']) && !empty($item['coupon_id']) ? $item['coupon_id'] : 0, + 'description' => '', + 'create_time' => time(), + 'update_time' => time(), + 'reward_id' => $data['reward_id'] + ]; + RewardModel::insert($rewardData); + } + } + + \think\facade\Db::commit(); + return $this->renderSuccess("添加成功"); + } catch (\Exception $e) { + \think\facade\Db::rollback(); + return $this->renderError("添加失败: " . $e->getMessage()); + } + } + } + + + /** + * 删除签到配置 + */ + public function delete(Request $request) + { + $id = input('post.id/d', 0); + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + // 先查询配置信息,获取reward_id + $info = SignConfigModel::find($id); + if (empty($info)) { + return $this->renderError("配置不存在"); + } + + // 开启事务 + \think\facade\Db::startTrans(); + try { + // 删除配置 + SignConfigModel::destroy($id); + + // 删除奖励数据,使用reward_id关联 + // if (!empty($info['reward_id'])) { + // RewardModel::where('reward_id', $info['reward_id'])->delete(); + // } + + \think\facade\Db::commit(); + return $this->renderSuccess("删除成功"); + } catch (\Exception $e) { + \think\facade\Db::rollback(); + return $this->renderError("删除失败: " . $e->getMessage()); + } + } + + /** + * 修改排序 + */ + public function sort(Request $request) + { + $id = input('post.id/d', 0); + $sort = input('post.sort/d', 0); + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + try { + SignConfigModel::where('id', $id)->update(['sort' => $sort, 'update_time' => time()]); + return $this->renderSuccess("排序更新成功"); + } catch (\Exception $e) { + return $this->renderError("排序更新失败: " . $e->getMessage()); + } + } + + /** + * 修改状态 + */ + public function status(Request $request) + { + $id = input('post.id/d', 0); + $status = input('post.status/d', 0); + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + try { + SignConfigModel::where('id', $id)->update(['status' => $status, 'update_time' => time()]); + return $this->renderSuccess("状态更新成功"); + } catch (\Exception $e) { + return $this->renderError("状态更新失败: " . $e->getMessage()); + } + } + + /** + * 获取优惠券列表API + */ + public function getCoupons(Request $request) + { + try { + // 获取有效的优惠券列表 + $coupons = Coupon::where('status', 0)->select()->toArray(); + + return json([ + 'code' => 0, + 'msg' => '获取成功', + 'data' => $coupons + ]); + } catch (\Exception $e) { + return json([ + 'code' => 1, + 'msg' => '获取优惠券失败: ' . $e->getMessage(), + 'data' => [] + ]); + } + } + + /** + * 编辑签到配置 + */ + public function edit(Request $request) + { + if (!$request->isPost()) { + $id = input('get.id/d', 0); + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + // 获取配置信息 + $info = SignConfigModel::find($id); + if (empty($info)) { + return $this->renderError("配置不存在"); + } + + // 获取关联的奖励 + $rewards = RewardModel::where('reward_id', $info['reward_id'])->select()->toArray(); + + View::assign('info', $info); + View::assign('rewards', $rewards); + + return View::fetch("SignConfig/edit"); + } + } + + /** + * 更新签到配置 + */ + public function update(Request $request) + { + $data = input('post.'); + $id = $data['id'] ?? 0; + + if (empty($id)) { + return $this->renderError("参数错误"); + } + + // 获取配置信息 + $info = SignConfigModel::find($id); + if (empty($info)) { + return $this->renderError("配置不存在"); + } + + // 奖励信息 + $reward = json_decode($data['reward'] ?? '[]', true); + unset($data['reward']); + $data['update_time'] = time(); + $data['reward_id'] = 'MHQD' . date('YmdHis') . mt_rand(1000, 9999);//$reward_id; + // 开启事务 + \think\facade\Db::startTrans(); + try { + // 更新配置 + SignConfigModel::update($data, ['id' => $id]); + + // 删除旧的奖励 + // RewardModel::where('reward_id', $info['reward_id'])->delete(); + + // 添加新的奖励 + if (!empty($reward) && is_array($reward)) { + foreach ($reward as $item) { + $rewardData = [ + 'reward_type' => $item['reward_type'], + 'reward_value' => isset($item['reward_value']) && !empty($item['reward_value']) ? $item['reward_value'] : 0, + 'reward_extend' => isset($item['coupon_id']) && !empty($item['coupon_id']) ? $item['coupon_id'] : 0, + 'description' => '', + 'create_time' => time(), + 'update_time' => time(), + 'reward_id' => $data['reward_id'] + ]; + RewardModel::insert($rewardData); + } + } + + \think\facade\Db::commit(); + return $this->renderSuccess("更新成功"); + } catch (\Exception $e) { + \think\facade\Db::rollback(); + return $this->renderError("更新失败: " . $e->getMessage()); + } + } + + /** + * 编辑签到奖励 + */ + public function rewardEdit(Request $request) + { + if (!$request->isPost()) { + $id = input('get.id/d', 0); + $reward_id = input('get.reward_id', ''); + + if (empty($id) || empty($reward_id)) { + return $this->renderError("参数错误"); + } + + // 获取配置信息 + $info = SignConfigModel::find($id); + if (empty($info)) { + return $this->renderError("配置不存在"); + } + + // 获取关联的奖励 + $rewards = RewardModel::where('reward_id', $reward_id)->select()->toArray(); + + View::assign('info', $info); + View::assign('reward_id', $reward_id); + View::assign('rewards', $rewards); + + return View::fetch("SignConfig/reward_edit"); + } else { + $id = input('post.id/d', 0); + $reward_id = input('post.reward_id', ''); + $reward = json_decode(input('post.reward', '[]'), true); + + if (empty($id) || empty($reward_id)) { + return $this->renderError("参数错误"); + } + + // 获取配置信息 + $info = SignConfigModel::find($id); + if (empty($info)) { + return $this->renderError("配置不存在"); + } + $info['reward_id'] = $reward_id = 'MHQD' . date('YmdHis') . mt_rand(1000, 9999);//$reward_id; + // 开启事务 + \think\facade\Db::startTrans(); + try { + // 删除旧的奖励 + //RewardModel::where('reward_id', $reward_id)->delete(); + $info->save(); + // 添加新的奖励 + if (!empty($reward) && is_array($reward)) { + foreach ($reward as $item) { + $rewardData = [ + 'reward_type' => $item['reward_type'], + 'reward_value' => isset($item['reward_value']) && !empty($item['reward_value']) ? $item['reward_value'] : 0, + 'reward_extend' => isset($item['coupon_id']) && !empty($item['coupon_id']) ? $item['coupon_id'] : 0, + 'description' => '', + 'create_time' => time(), + 'update_time' => time(), + 'reward_id' => $reward_id + ]; + RewardModel::insert($rewardData); + } + } + + \think\facade\Db::commit(); + return $this->renderSuccess("奖励更新成功"); + } catch (\Exception $e) { + \think\facade\Db::rollback(); + return $this->renderError("奖励更新失败: " . $e->getMessage()); + } + } + } +} \ No newline at end of file diff --git a/app/admin/route/app.php b/app/admin/route/app.php index dd1ad6f..cd1bb6b 100755 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -342,4 +342,40 @@ Route::rule('welfare_house', 'WelfareHouse/index', 'GET|POST'); Route::rule('welfare_house_add', 'WelfareHouse/add', 'GET|POST'); Route::rule('welfare_house_edit', 'WelfareHouse/edit', 'GET|POST'); Route::rule('welfare_house_del', 'WelfareHouse/del', 'POST'); -Route::rule('welfare_house_status', 'WelfareHouse/status', 'POST'); \ No newline at end of file +Route::rule('welfare_house_status', 'WelfareHouse/status', 'POST'); + +#============================ +#SignConfig.php签到配置管理 +#============================ +Route::rule('sign_config', 'SignConfig/index', 'GET|POST'); +Route::rule('sign_config_list', 'SignConfig/getSignConfigList', 'GET|POST'); +Route::rule('sign_config_add', 'SignConfig/add', 'GET|POST'); +Route::rule('sign_config_edit', 'SignConfig/edit', 'GET|POST'); +Route::rule('sign_config_delete', 'SignConfig/delete', 'POST'); +Route::rule('sign_config_sort', 'SignConfig/sort', 'POST'); +Route::rule('sign_config_status', 'SignConfig/status', 'POST'); +Route::rule('get_coupons', 'SignConfig/getCoupons', 'GET'); + +#============================ +#Reward.php奖励管理 +#============================ +Route::rule('reward', 'Reward/index', 'GET|POST'); +Route::rule('reward_add', 'Reward/add', 'GET|POST'); +Route::rule('reward_edit', 'Reward/edit', 'GET|POST'); +Route::rule('reward_delete', 'Reward/delete', 'POST'); +Route::rule('reward_status', 'Reward/status', 'POST'); +Route::rule('get_rewards_by_id', 'Reward/getRewardsByRewardId', 'GET'); + +// 签到配置 +Route::get('sign_config', 'SignConfig/index'); +Route::get('sign_config_list', 'SignConfig/getSignConfigList'); +Route::get('sign_config_add', 'SignConfig/add'); +Route::post('sign_config_add', 'SignConfig/add'); +Route::get('sign_config_edit', 'SignConfig/edit'); +Route::post('sign_config_update', 'SignConfig/update'); +Route::get('sign_config_reward_edit', 'SignConfig/rewardEdit'); +Route::post('sign_config_reward_edit', 'SignConfig/rewardEdit'); +Route::post('sign_config_delete', 'SignConfig/delete'); +Route::post('sign_config_sort', 'SignConfig/sort'); +Route::post('sign_config_status', 'SignConfig/status'); +Route::get('sign_config_coupons', 'SignConfig/getCoupons'); \ No newline at end of file diff --git a/app/admin/view/Public/footer.html b/app/admin/view/Public/footer.html index f1290b4..5e569c3 100755 --- a/app/admin/view/Public/footer.html +++ b/app/admin/view/Public/footer.html @@ -1,2 +1,7 @@ + - \ No newline at end of file + + + + + diff --git a/app/admin/view/Public/header2.html b/app/admin/view/Public/header2.html index 075d32b..222062b 100755 --- a/app/admin/view/Public/header2.html +++ b/app/admin/view/Public/header2.html @@ -8,9 +8,11 @@ + + \ No newline at end of file diff --git a/app/admin/view/Reward/add.html b/app/admin/view/Reward/add.html new file mode 100644 index 0000000..21334b8 --- /dev/null +++ b/app/admin/view/Reward/add.html @@ -0,0 +1,184 @@ +{include file="Public:header2"/} + +
+ + 奖励管理> + 添加奖励 + +
+ +
+
+
+
+
+
+
+
+ +
+ + + + +
+
+ +
+ +
+ +
+
+ + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + +
+
+
+ +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+{include file="Public:footer"/} + + + \ No newline at end of file diff --git a/app/admin/view/Reward/edit.html b/app/admin/view/Reward/edit.html new file mode 100644 index 0000000..c8af16e --- /dev/null +++ b/app/admin/view/Reward/edit.html @@ -0,0 +1,185 @@ +{include file="Public:header2"/} + +
+ + 奖励管理> + 编辑奖励 + +
+ +
+
+
+
+
+
+ +
+
+ +
+ + + + +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + +
+
+
+ +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+{include file="Public:footer"/} + + + \ No newline at end of file diff --git a/app/admin/view/SignConfig/add.html b/app/admin/view/SignConfig/add.html new file mode 100644 index 0000000..0ca13e9 --- /dev/null +++ b/app/admin/view/SignConfig/add.html @@ -0,0 +1,185 @@ +{include file="Public:header2"/} + +
+
+
+
+
+
+
+
+ +
+ + + +
+
+ +
+ +
+ +
+
签到多少天可以获得奖励
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+{include file="Public:footer"/} + \ No newline at end of file diff --git a/app/admin/view/SignConfig/edit.html b/app/admin/view/SignConfig/edit.html new file mode 100644 index 0000000..36605a6 --- /dev/null +++ b/app/admin/view/SignConfig/edit.html @@ -0,0 +1,185 @@ +{include file="Public:header2"/} + +
+
+
+
+
+
+ +
+
+ +
+ + +
+
+ +
+ +
+ +
+
签到多少天可以获得奖励
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+{include file="Public:footer"/} + \ No newline at end of file diff --git a/app/admin/view/SignConfig/reward_edit.html b/app/admin/view/SignConfig/reward_edit.html new file mode 100644 index 0000000..0908200 --- /dev/null +++ b/app/admin/view/SignConfig/reward_edit.html @@ -0,0 +1,86 @@ +{include file="Public:header2"/} + +
+
+
+
+
+

编辑 "{$info.title}" 的签到奖励

+
+
+
+ + +
+ + +
+ +
+
+
+
+ +
+
+ + +
+
+
+
+
+
+
+
+
+{include file="Public:footer"/} + \ No newline at end of file diff --git a/app/api/controller/Sign.php b/app/api/controller/Sign.php new file mode 100644 index 0000000..71dd465 --- /dev/null +++ b/app/api/controller/Sign.php @@ -0,0 +1,241 @@ +getUser(); + $user_id = $user['id']; + + // 添加Redis锁防止重复请求 + $redis = new RedisHelper(); + $lock_key = 'user_sign_lock:' . $user_id; + + // 检查是否存在锁 + if ($redis->exists($lock_key)) { + return $this->renderError('操作频繁,请稍后再试'); + } + + // 设置锁,5秒过期 + $redis->set($lock_key, 1, 3); + + try { + $app_setting = getConfig('app_setting'); + if ($app_setting && $app_setting['sign_in_spend_limit'] && $app_setting['sign_in_spend_limit'] > 0) { + //消费门槛 + //获取当天开始和结束时间 + $today_start = strtotime(date('Y-m-d 00:00:00')); + $today_end = strtotime(date('Y-m-d 23:59:59')); + + //查询用户今日是否达到消费门槛 + $order_count = Order::where('user_id', '=', $user_id) + ->where('status', '=', 1) // 已支付订单 + ->where(function ($query) { + $query->where('price', '>', 0) + ->whereOr('use_money', '>', 0); + }) + ->where('pay_time', '>=', $today_start) + ->where('pay_time', '<=', $today_end) + ->count(); + + if ($order_count == 0) { + // 删除锁后返回错误 + $redis->delete($lock_key); + return $this->renderError('您今日尚未达到签到消费门槛,请消费后再来签到'); + } + } + // 执行签到 + $result = UserSign::add($user_id); + if ($result['status']) { + return $this->renderSuccess($result['msg'], $result['data']); + } else { + return $this->renderError($result['msg']); + } + } catch (\Exception $e) { + + return $this->renderError('签到失败:' . $e->getMessage()); + } finally { + // 删除锁 + $redis->delete($lock_key); + } + + } + + /** + * 获取签到信息 + */ + public function info() + { + $user = $this->getUser(); + $user_id = $user['id']; + + // 获取用户今日签到信息 + list($days, $is_sign) = UserSign::getListByUserId($user_id, 0); + + $current_month = date('m', time()); + $current_year = date('Y', time()); + + // 查询本月累计签到领取记录 + $leiji_list = UserSign::where('user_id', '=', $user_id) + ->where('month', '=', $current_month) + ->where('year', '=', $current_year) + ->where('sign_type', '=', 1) + ->field('days') + ->order(['create_time' => 'desc']) + ->select() + ->toArray(); + + // 获取用户本月已签到日期 + $signDays = UserSign::getMonthSignDays($user_id); + + // 获取累计签到配置 + $continuousConfigs = SignConfig::where(['type' => 2, 'status' => 1]) + ->field('id,reward_id,day,description,sort,icon,title') + ->order('sort asc') + ->select() + ->toArray(); + // 当前月份总天数 + $totalDays = date('t'); + // 获取每日签到配置 + $dailyConfigs = SignConfig::where(['type' => 1, 'status' => 1]) + ->where('day', '<=', $totalDays) + ->field('id,reward_id,day,description,sort,icon,title') + ->order('sort asc') + ->select() + ->toArray(); + + // 处理配置关联的奖励信息 + $nowDay = date('j'); + // 每日签到配置 + foreach ($dailyConfigs as &$config) { + $day = $config['day']; + // 获取关联的奖励ID + $rewardIds = $config['reward_id']; + + // 获取奖励详情 + $rewards = Reward::where('reward_id', '=', $rewardIds) + ->field('reward_type,reward_extend,reward_value') + ->select() + ->toArray(); + // 处理奖励类型名称 + foreach ($rewards as &$reward) { + $reward['reward_type_text'] = $this->getRewardTypeText($reward['reward_type']); + } + $config['title'] = "第" . $config['day'] . "天"; + $config['rewards'] = $rewards; + + if ($signDays >= $day) { + $config['is_sign'] = 2; + } else { + if ($nowDay == $day) { + $config['is_sign'] = 1; + } else { + $config['is_sign'] = 0; + } + } + + } + // 累计签到配置 + foreach ($continuousConfigs as &$config) { + $day = $config['day']; + // 获取关联的奖励ID + $rewardIds = $config['reward_id']; + + // 获取奖励详情 + $rewards = Reward::where('reward_id', '=', $rewardIds) + ->field('reward_type,reward_extend,reward_value') + ->select() + ->toArray(); + // 处理奖励类型名称 + foreach ($rewards as &$reward) { + $reward['reward_type_text'] = $this->getRewardTypeText($reward['reward_type']); + } + $config['title'] = "累计签到" . $config['day'] . "天"; + $config['rewards'] = $rewards; + // $leiji_list->find($config['day']); + //判断$leiji_lis 是否包含 day + $is_contain = array_column($leiji_list, 'days'); + if (in_array($config['day'], $is_contain)) { + $config['is_sign'] = 2; + } else { + if ($signDays >= $day) { + $config['is_sign'] = 1; + } else { + $config['is_sign'] = 0; + } + } + + + } + + // 计算下次月重置剩余天数 + $restDays = $totalDays - $nowDay; + + $data = [ + 'days' => $days, // 签到天数 + 'is_sign' => $is_sign, // 今日是否已签到 + 'sign_days' => $signDays, // 已签到日期数组 + 'total_days' => intval($totalDays), // 当月总天数 + 'rest_days' => intval($restDays), // 距离月底还有几天 + 'continuous_configs' => $continuousConfigs, // 累计签到配置 + 'daily_configs' => $dailyConfigs // 每日签到配置 + ]; + + return $this->renderSuccess('请求成功', $data); + } + + /** + * 处理配置关联的奖励信息 + */ + private function processConfigRewards(&$configs) + { + foreach ($configs as &$config) { + // 获取关联的奖励ID + $rewardIds = $config['reward_id']; + + // 获取奖励详情 + $rewards = Reward::where('reward_id', '=', $rewardIds) + ->field('reward_type,reward_extend,reward_value') + ->select() + ->toArray(); + + // 处理奖励类型名称 + foreach ($rewards as &$reward) { + $reward['reward_type_text'] = $this->getRewardTypeText($reward['reward_type']); + } + + $config['rewards'] = $rewards; + } + } + + /** + * 获取奖励类型文本 + */ + private function getRewardTypeText($type) + { + $types = [ + + 1 => '钻石', + 2 => 'UU币', + 3 => '达达卷', + 4 => '优惠券', + ]; + return isset($types[$type]) ? $types[$type] : '未知'; + } +} \ No newline at end of file diff --git a/app/api/route/app.php b/app/api/route/app.php index e3af10a..09739d7 100755 --- a/app/api/route/app.php +++ b/app/api/route/app.php @@ -151,9 +151,7 @@ Route::any('seckill_order_detail','Seckill/seckill_order_detail'); Route::any('seckill_order_confirm','Seckill/seckill_order_confirm'); Route::any('seckill_order_logistics','Seckill/seckill_order_logistics'); -//签到 -Route::any('sign','UserSign/index'); //签到页面 -Route::any('sign_add','UserSign/sign_add'); //签到 + //generate_urllink Route::any('generate_urllink','Index/generate_urllink'); @@ -174,4 +172,10 @@ Route::rule('config', 'Config/index', 'GET'); #============================ #WelfareHouse.php福利屋 #============================ -Route::any('welfare_house_list', 'WelfareHouse/getList'); \ No newline at end of file +Route::any('welfare_house_list', 'WelfareHouse/getList'); + +#============================ +# 签到管理 +#============================ +Route::rule('sign', 'Sign/signAdd', 'POST'); +Route::rule('sign_info', 'Sign/info', 'POST'); \ No newline at end of file diff --git a/app/common.php b/app/common.php index b6b4551..3b44c66 100755 --- a/app/common.php +++ b/app/common.php @@ -146,7 +146,7 @@ if (!function_exists('getConfig')) { /** * 获取系统配置 * @param string $type 配置关键词 - * @return void + * @return */ function getConfig($type) { @@ -274,7 +274,7 @@ if (!function_exists('create_order_no')) { if (strpos($pre, 'MH_') !== false) { // 引入微信支付帮助类 $wxpayConfig = \app\common\helper\WxPayHelper::getWxPayConfig(); - + // 如果存在商户信息并且有前缀,则使用商户前缀 if (!empty($wxpayConfig['merchant']) && !empty($wxpayConfig['merchant']['order_prefix'])) { $merchant_prefix = $wxpayConfig['merchant']['order_prefix']; @@ -282,7 +282,7 @@ if (!function_exists('create_order_no')) { $pre = 'MH_' . $merchant_prefix; } } - + $order_no = $pre . date('Ymd') . substr(implode('', array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); $r = Db::name($tale)->field('id')->where([$field => $order_no])->find(); if ($r) { diff --git a/app/common/model/Reward.php b/app/common/model/Reward.php new file mode 100644 index 0000000..007fc49 --- /dev/null +++ b/app/common/model/Reward.php @@ -0,0 +1,66 @@ +field($field) + ->order($order) + ->paginate(['list_rows' => $pageSize, 'query' => request()->param()]); + $page = $list->render(); + $data['list'] = $list->toArray()['data']; + $data['count'] = $list->total(); + $data['last_page'] = $list->toArray()['last_page']; + $data['page'] = $page; + return $data; + } + + /** + * 获取列表 不分页 + */ + public static function getAllList($where = [], $field = '*', $order = '', $limit = '0') + { + $data = self::where($where) + ->field($field) + ->order($order) + ->limit($limit) + ->select(); + return $data; + } + + /** + * 获取单条数据 + */ + public static function getInfo($where = [], $field = '*') + { + $data = self::where($where) + ->field($field) + ->find(); + return $data; + } + + /** + * 获取奖励类型名称 + */ + public function getRewardTypeTextAttr($value, $data) + { + $types = [ + 1 => '优惠券', + 2 => '钻石', + 3 => 'UU币', + 4 => '达达卷' + ]; + return isset($data['reward_type']) && isset($types[$data['reward_type']]) ? $types[$data['reward_type']] : '未知'; + } +} \ No newline at end of file diff --git a/app/common/model/SignConfig.php b/app/common/model/SignConfig.php new file mode 100644 index 0000000..813646b --- /dev/null +++ b/app/common/model/SignConfig.php @@ -0,0 +1,72 @@ +field($field) + ->order($order) + ->paginate(['list_rows' => $pageSize, 'query' => request()->param()]); + $page = $list->render(); + $data['list'] = $list->toArray()['data']; + $data['count'] = $list->total(); + $data['last_page'] = $list->toArray()['last_page']; + $data['page'] = $page; + return $data; + } + + /** + * 获取列表 不分页 + */ + public static function getAllList($where = [], $field = '*', $order = '', $limit = '0') + { + $data = self::where($where) + ->field($field) + ->order($order) + ->limit($limit) + ->select(); + return $data; + } + + /** + * 获取单条数据 + */ + public static function getInfo($where = [], $field = '*') + { + $data = self::where($where) + ->field($field) + ->find(); + return $data; + } + + /** + * 获取类型名称 + */ + public function getTypeTextAttr($value, $data) + { + $types = [ + 1 => '累计签到', + 2 => '每日签到' + ]; + return isset($data['type']) && isset($types[$data['type']]) ? $types[$data['type']] : '未知'; + } + + /** + * 获取当前签到配置关联的所有奖励 + */ + public function rewards() + { + return $this->belongsToMany(Reward::class, SignConfigReward::class, 'reward_id', 'sign_config_id'); + } +} \ No newline at end of file diff --git a/app/common/model/SignConfigReward.php b/app/common/model/SignConfigReward.php new file mode 100644 index 0000000..f3bb9e4 --- /dev/null +++ b/app/common/model/SignConfigReward.php @@ -0,0 +1,63 @@ +field($field) + ->order($order) + ->paginate(['list_rows' => $pageSize, 'query' => request()->param()]); + $page = $list->render(); + $data['list'] = $list->toArray()['data']; + $data['count'] = $list->total(); + $data['last_page'] = $list->toArray()['last_page']; + $data['page'] = $page; + return $data; + } + + /** + * 获取所有配置关联的奖励ID + * @param int $configId 配置ID + * @return array 奖励ID数组 + */ + public static function getRewardIds($configId) + { + return self::where('sign_config_id', $configId) + ->column('reward_id'); + } + + /** + * 批量添加配置奖励关联 + * @param int $configId 配置ID + * @param array $rewardIds 奖励ID数组 + * @return bool 是否成功 + */ + public static function addBatch($configId, $rewardIds) + { + // 先删除原有关联 + self::where('sign_config_id', $configId)->delete(); + + // 批量添加新关联 + $data = []; + foreach ($rewardIds as $rewardId) { + $data[] = [ + 'sign_config_id' => $configId, + 'reward_id' => $rewardId, + 'create_time' => time() + ]; + } + + return self::insertAll($data); + } +} \ No newline at end of file diff --git a/app/common/model/User.php b/app/common/model/User.php index 2110119..a7b8f3d 100755 --- a/app/common/model/User.php +++ b/app/common/model/User.php @@ -359,7 +359,7 @@ class User extends Base * 用户余额变化 * @param $user_id * @param $change_money - * @param $type 1后台充值 2在线充值 3抽赏消费 4背包兑换 5推荐奖励 + * @param $type 1后台充值 2在线充值 3抽赏消费 4背包兑换 5推荐奖励,6签到赠送 * @param $content * @param int $share_uid * @param string $other diff --git a/app/common/model/UserSign.php b/app/common/model/UserSign.php index aebe5b7..5b30aee 100755 --- a/app/common/model/UserSign.php +++ b/app/common/model/UserSign.php @@ -7,7 +7,9 @@ use app\common\model\User; use app\common\model\Goods; use app\common\model\GoodsList; use app\common\model\OrderList; - +use app\common\model\SignConfig; +use app\common\model\SignConfigReward; +use app\common\service\RewardService; use think\Model; class UserSign extends Base @@ -34,89 +36,162 @@ class UserSign extends Base { //签到日期 $sign_date = date('Y-m-d', time()); + $current_month = date('m', time()); + $current_year = date('Y', time()); + + //检查今日是否已签到 + $today_sign = self::where('user_id', $user_id) + ->where('sign_date', $sign_date) + ->find(); + + if (!empty($today_sign)) { + return ["status" => false, "msg" => "今日您已签到"]; + } //获取连续签到天数 - $days = self::getDays($user_id, $sign_date); - if ($days == '-1') { - return "今日您已签到"; - } - $config = getConfig('sign'); - if ($days > 7) { - $days = 1; - } - if ($days == 1) { - $num = $config['one_num']; - } elseif ($days == 2) { - $num = $config['two_num']; - } elseif ($days == 3) { - $num = $config['three_num']; - } elseif ($days == 4) { - $num = $config['four_num']; - } elseif ($days == 5) { - $num = $config['five_num']; - } elseif ($days == 6) { - $num = $config['six_num']; - } elseif ($days == 7) { - $num = $config['seven_num']; - } + $days = self::getDays($user_id, $sign_date, $current_month, $current_year); + //签到数据 $data = [ 'user_id' => $user_id, 'sign_date' => date('Y-m-d', time()), 'sign_day' => intval(date('d', time())), 'days' => $days, - 'num' => $num, + 'month' => $current_month, + 'year' => $current_year, 'create_time' => time(), 'update_time' => time(), ]; + + // 执行签到并记录 self::insert($data); - User::changeIntegral($user_id, $num, 2,'签到'); - return ['msg' => "签到成功,获得{$num}个积分", 'data' => ['num' => $num]]; + + $day_count = self::getMonthSignDays($user_id); + //处理每日签到奖励 + self::processSignRewards($user_id, 1, $day_count); + // 处理累计签到奖励 + self::processSignRewards($user_id, 2, $day_count); + + return ['status' => true, 'msg' => "签到成功", 'data' => ['days' => $day_count]]; + } + + /** + * 处理签到奖励 + * @param int $user_id 用户ID + * @param int $type 配置类型 1-每日签到 ,2-累计签到, + * @param int $day 天数或星期几 + */ + protected static function processSignRewards($user_id, $type, $day) + { + + // 查找符合条件的配置 + $reward = SignConfig::where('type', '=',$type) + ->where('status','=', 1) + ->where('day', '=',$day) + ->field('reward_id')->find(); + if ($reward) { + RewardService::sendReward($user_id, $reward['reward_id'], $type == 1 ? "签到奖励" : "累计签到奖励"); + } } /** - * 获取签到信息 + * 获取签到信息 - 计算连续签到天数 + * @param int $user_id 用户ID + * @param string $sign_date 签到日期 + * @param int $current_month 当前月份 + * @param int $current_year 当前年份 + * @return int 连续签到天数 */ - public static function getDays($user_id, $sign_date) + public static function getDays($user_id, $sign_date, $current_month = null, $current_year = null) { - $row = self::where('user_id', '=', $user_id)->order(['create_time' => 'desc'])->find(); + if ($current_month === null) { + $current_month = date('m', time()); + } + + if ($current_year === null) { + $current_year = date('Y', time()); + } + + // 查询该用户最近一次签到记录 + $row = self::where('user_id', '=', $user_id) + ->order(['create_time' => 'desc']) + ->find(); + if (empty($row)) { + return 1; // 第一次签到 + } + + // 如果是新的一个月,重置签到天数 + if ($row['month'] != $current_month || $row['year'] != $current_year) { return 1; } - $dif = (strtotime($sign_date) - strtotime($row['create_time'])) / (24 * 60 * 60); + + // 判断是否是今天已经签到 if (strtotime($row['sign_date']) == strtotime($sign_date)) { - return -1; //今日已签到 + return -1; // 今日已签到 } + + // 计算两次签到的时间差(天数) + $dif = (strtotime($sign_date) - strtotime($row['sign_date'])) / (24 * 60 * 60); + if ($dif > 1) { - return 1; + return 1; // 不是连续签到,重置为1 + } else { + return $row['days'] + 1; // 连续签到 } - if ($dif < 1) { - return $row['days'] + 1; - } - return false; } - public static function getListByUserId($user_id) + /** + * 获取用户签到信息 + * @param int $user_id 用户ID + * @param int $sign_type 签到类型 0-每日签到 1-累计签到 + * @return array [连续签到天数, 今日是否签到] + */ + public static function getListByUserId($user_id, $sign_type = 0) { - $str = date('Y-m-d', time()); - $arr = explode('-', $str); - $beginYesterday = mktime(0, 0, 0, date('m'), date('d') - 1, date('Y')); //查询昨天到今天 的数据看今日是否签到和连续签到天数 - $list = self::where('user_id', '=', $user_id) - ->whereTime('create_time', '>=', $beginYesterday) - ->order(['create_time' => 'desc'])->select()->toArray(); - $res = array_column($list, 'sign_day'); - $len = count($list); + $current_date = date('Y-m-d', time()); + $current_month = date('m', time()); + $current_year = date('Y', time()); - if ($len == 0) { - $days = 0; - $is_sign = 0; - } else { - $days = $list[0]['days']; //连续签到天数 - $is_sign = ($list[0]['sign_date'] == date('Y-m-d', time())) ? 1 : 0; //今日是否签到 + // 查询本月签到记录 + $list = self::where('user_id', '=', $user_id) + ->where('month', '=', $current_month) + ->where('year', '=', $current_year) + ->where('sign_type', '=', $sign_type) + ->order(['create_time' => 'desc']) + ->select() + ->toArray(); + + $days = 0; + $is_sign = 0; + + if (!empty($list)) { + $days = $list[0]['days']; // 连续签到天数 + $is_sign = ($list[0]['sign_date'] == $current_date) ? 1 : 0; // 今日是否签到 } return [$days, $is_sign]; } + + + /** + * 获取用户本月签到记录 + * @param int $user_id 用户ID + * @return int 本月已签到的数量 + */ + public static function getMonthSignDays($user_id): int + { + $current_month = date('m', time()); + $current_year = date('Y', time()); + + $sign_days = self::where('user_id', '=', $user_id) + ->where('month', '=', $current_month) + ->where('year', '=', $current_year) + ->where('sign_type', '=', '0') + ->count(); + + return $sign_days; + } } \ No newline at end of file diff --git a/app/common/service/RewardService.php b/app/common/service/RewardService.php new file mode 100644 index 0000000..f6f8270 --- /dev/null +++ b/app/common/service/RewardService.php @@ -0,0 +1,114 @@ + false, 'msg' => '用户ID不能为空']; + } + + + // 获取奖励信息 + $rewards = Reward::where('reward_id', '=', $reward_id) + ->select() + ->toArray(); + + if (empty($rewards)) { + return ['status' => false, 'msg' => '未找到有效奖励']; + } + + $result = []; + $user = User::find($user_id); + + if (empty($user)) { + return ['status' => false, 'msg' => '用户不存在']; + } + + foreach ($rewards as $reward) { + $res = self::sendSingleReward($user_id, $reward, $source); + $result[] = $res; + } + + return ['status' => true, 'msg' => '奖励发放成功', 'data' => $result]; + } + + /** + * 发放单个奖励 + * @param int $user_id 用户ID + * @param array $reward 奖励信息 + * @param string $source 奖励来源 + * @return array 处理结果 + */ + protected static function sendSingleReward($user_id, $reward, $source) + { + $result = ['reward_id' => $reward['id'], 'status' => false, 'msg' => '']; + + switch ($reward['reward_type']) { + + case 1: // 钻石 + $res = User::changeMoney($user_id, $reward['reward_value'], 6, $source); + $result['status'] = !empty($res); + $result['msg'] = $result['status'] ? '钻石发放成功' : '钻石发放失败'; + break; + + + case 2: // 货币1 + $res = User::changeIntegral($user_id, $reward['reward_value'], 6, $source); + $result['status'] = !empty($res); + $result['msg'] = $result['status'] ? 'UU币发放成功' : 'UU币发放失败'; + break; + + case 3: // 货币2 + $res = User::changeMoney2($user_id, $reward['reward_value'], 6, $source); + $result['status'] = !empty($res); + $result['msg'] = $result['status'] ? '达达券发放成功' : '达达券发放失败'; + break; + case 4: // 优惠券 + if (!empty($reward['reward_extend'])) { + $coupon = Coupon::find($reward['reward_extend']); + if (!empty($coupon)) { + // 发放优惠券 + $ttype = isset($coupon['ttype']) ? $coupon['ttype'] : 0; + $res = CouponReceive::insert([ + 'user_id' => $user_id, + 'title' => $coupon['title'], + 'price' => $coupon['price'], + 'man_price' => $coupon['man_price'], + 'end_time' => $coupon['effective_day'] * 86400 + time(), + 'addtime' => time(), + 'coupon_id' => $coupon['id'], + 'state' => $ttype + ]); + + $result['status'] = !empty($res); + $result['msg'] = $result['status'] ? '优惠券发放成功' : '优惠券发放失败'; + } else { + $result['msg'] = '优惠券不存在'; + } + } else { + $result['msg'] = '优惠券ID不能为空'; + } + break; + + default: + $result['msg'] = '不支持的奖励类型'; + break; + } + + return $result; + } +} \ No newline at end of file diff --git a/config/menu.php b/config/menu.php index 929f3a8..8335e1f 100755 --- a/config/menu.php +++ b/config/menu.php @@ -25,7 +25,7 @@ return [ 'name' => '用户邀请列表', ], [ - 'url' => '/admin/sign', + 'url' => '/admin/sign_config', 'name' => '用户签到设置', ], ], diff --git a/create_sign_tables.sql b/create_sign_tables.sql new file mode 100644 index 0000000..d9e293f --- /dev/null +++ b/create_sign_tables.sql @@ -0,0 +1,45 @@ +-- 创建奖励表 +CREATE TABLE IF NOT EXISTS `reward` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `reward_type` tinyint(1) NOT NULL COMMENT '奖励类型(1:优惠券,2:钻石,3:货币1,4:货币2)', + `reward_id` int(11) DEFAULT NULL COMMENT '奖励ID(当reward_type=1时为优惠券ID)', + `reward_value` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '奖励值', + `title` varchar(100) DEFAULT NULL COMMENT '奖励标题', + `description` varchar(255) DEFAULT NULL COMMENT '奖励描述', + `icon` varchar(255) DEFAULT NULL COMMENT '奖励图标', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0禁用,1启用)', + `create_time` int(11) DEFAULT NULL, + `update_time` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='奖励表'; + +-- 创建签到配置表 +CREATE TABLE IF NOT EXISTS `sign_config` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `type` tinyint(1) NOT NULL COMMENT '配置类型(1:累计签到配置,2:每日签到配置)', + `days` int(11) DEFAULT NULL COMMENT '累计天数(type=1时有效)', + `day` tinyint(1) DEFAULT NULL COMMENT '指定星期几(type=2时有效,1-7代表周一到周日)', + `title` varchar(100) DEFAULT NULL COMMENT '配置标题', + `icon` varchar(255) DEFAULT NULL COMMENT '图标', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0禁用,1启用)', + `sort` int(11) DEFAULT '0' COMMENT '排序', + `create_time` int(11) DEFAULT NULL, + `update_time` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='签到配置表'; + +-- 创建签到配置奖励关联表 +CREATE TABLE IF NOT EXISTS `sign_config_reward` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `sign_config_id` int(11) NOT NULL COMMENT '签到配置ID', + `reward_id` int(11) NOT NULL COMMENT '奖励ID', + `create_time` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_sign_config_id` (`sign_config_id`), + KEY `idx_reward_id` (`reward_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='签到配置奖励关联表'; + +-- 修改用户签到表,添加month和year字段 +ALTER TABLE `user_sign` +ADD COLUMN `month` int(11) DEFAULT NULL COMMENT '签到月份' AFTER `days`, +ADD COLUMN `year` int(11) DEFAULT NULL COMMENT '签到年份' AFTER `month`; \ No newline at end of file diff --git a/public/static/admin/reward-component.js b/public/static/admin/reward-component.js new file mode 100644 index 0000000..58d2e3f --- /dev/null +++ b/public/static/admin/reward-component.js @@ -0,0 +1,326 @@ +/** + * 奖励信息组件 + * 用于创建和管理奖励信息表单元素 + */ + +/** + * 初始化奖励信息区域 + * @param {string} containerId - 容器ID + * @param {Array|string} existingRewards - 已存在的奖励数据数组或reward_id + */ +function initRewardInfo(containerId, existingRewards = null) { + var $ = layui.$; + var form = layui.form; + + // 奖励类型选项 + var rewardTypes = [ + { value: '1', text: '余额' }, + { value: '2', text: '货币1' }, + { value: '3', text: '货币2' }, + { value: '4', text: '优惠券' } + ]; + + // 存储优惠券数据 + var couponsData = []; + + // 创建奖励信息卡片 + var cardHtml = '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '' + + '
' + + '
' + + '
'; + + // 渲染奖励信息卡片 + $('#' + containerId).html(cardHtml); + + // 请求优惠券数据 + function fetchCoupons(callback) { + var load = layer.load(2); + $.ajax({ + url: '/admin/get_coupons', + type: 'GET', + dataType: 'json', + success: function (res) { + layer.close(load); + if (res.code == 0) { + couponsData = res.data; + if (typeof callback === 'function') { + callback(couponsData); + } + } else { + layer.msg(res.msg || '获取优惠券失败', { icon: 2, anim: 6, time: 1500 }); + } + }, + error: function () { + layer.close(load); + layer.msg('网络错误,请稍后重试', { icon: 2, anim: 6, time: 1500 }); + } + }); + } + + // 生成唯一ID + function generateUniqueId() { + return 'reward_' + new Date().getTime() + '_' + Math.floor(Math.random() * 1000); + } + + // 添加奖励项 + function addRewardItem(rewardData = null) { + var uniqueId = generateUniqueId(); + var html = '
' + + '
' + + '' + + '
'; + + // 根据奖励类型决定显示哪个输入区域 + var rewardValueDisplay = (!rewardData || rewardData.reward_type != '4') ? '' : 'style="display:none;"'; + var couponDisplay = (!rewardData || rewardData.reward_type != '4') ? 'style="display:none;"' : ''; + var rewardValue = rewardData ? rewardData.reward_value : ''; + + html += '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
'; + + $('#rewardContainer').append(html); + form.render('select'); // 重新渲染表单 + + // 绑定删除按钮事件 + $('.remove-reward[data-id="' + uniqueId + '"]').click(function () { + var id = $(this).data('id'); + $('#' + id).remove(); + }); + + // 如果是优惠券类型,需要加载优惠券数据 + if (rewardData && rewardData.reward_type == '4') { + var $item = $('#' + uniqueId); + var $couponSelect = $item.find('.coupon-select'); + + // 获取优惠券数据并选中指定的优惠券 + if (couponsData.length > 0) { + fillCouponOptions($couponSelect, couponsData, rewardData.reward_extend); + } else { + fetchCoupons(function (coupons) { + fillCouponOptions($couponSelect, coupons, rewardData.reward_extend); + }); + } + } + + return uniqueId; + } + + // 添加奖励按钮点击事件 + $('#addReward').click(function () { + addRewardItem(); + }); + + // 监听奖励类型选择 + form.on('select(rewardTypeFilter)', function (data) { + var $item = $(data.elem).closest('.reward-item'); + var value = data.value; + + if (value == '4') { // 选择了优惠券 + $item.find('.reward-value-container').hide(); + $item.find('.coupon-container').show(); + $item.find('.reward-value-input').val(''); // 清空奖励数值 + + // 获取当前选择框的优惠券选择框 + var $couponSelect = $item.find('.coupon-select'); + + // 如果优惠券数据已加载,直接填充 + if (couponsData.length > 0) { + fillCouponOptions($couponSelect, couponsData); + } else { + // 否则请求加载 + fetchCoupons(function (coupons) { + fillCouponOptions($couponSelect, coupons); + }); + } + } else { + $item.find('.reward-value-container').show(); + $item.find('.coupon-container').hide(); + $item.find('.coupon-select').val(''); // 清空优惠券选择 + form.render('select'); + } + }); + + // 填充优惠券选项 + function fillCouponOptions($select, coupons, selectedCouponId = null) { + // 清空现有选项,保留第一个"请选择" + $select.find('option:not(:first)').remove(); + + // 添加优惠券选项 + for (var i = 0; i < coupons.length; i++) { + var coupon = coupons[i]; + var selected = selectedCouponId && coupon.id == selectedCouponId ? 'selected' : ''; + $select.append(''); + } + + // 重新渲染表单 + form.render('select'); + } + + // 处理初始化奖励数据 + if (existingRewards) { + // 如果传入的是字符串(reward_id),则通过接口获取奖励数据 + if (typeof existingRewards === 'string' && existingRewards.trim() !== '') { + var rewardId = existingRewards; + + // 通过API获取奖励数据 + var loadingIndex = layer.load(1, { shade: [0.1, '#fff'] }); + $.ajax({ + url: '/admin/get_rewards_by_id', + type: 'GET', + data: { reward_id: rewardId }, + dataType: 'json', + success: function(res) { + layer.close(loadingIndex); + if (res.status === 1 && res.data && res.data.length > 0) { + // 先获取优惠券数据,再初始化奖励表单 + fetchCoupons(function() { + // 遍历奖励数据,添加奖励项 + for (var i = 0; i < res.data.length; i++) { + var rewardItem = { + reward_type: res.data[i].reward_type.toString(), + reward_value: res.data[i].reward_value || '', + reward_extend: res.data[i].reward_extend || '' + }; + addRewardItem(rewardItem); + } + }); + } else { + layer.msg('没有找到奖励数据或获取失败', { icon: 2, time: 2000 }); + } + }, + error: function() { + layer.close(loadingIndex); + layer.msg('网络错误,无法获取奖励数据', { icon: 2, time: 2000 }); + } + }); + } + // 如果传入的是数组,直接使用 + else if (Array.isArray(existingRewards) && existingRewards.length > 0) { + // 先获取优惠券数据,再初始化奖励表单 + fetchCoupons(function() { + for (var i = 0; i < existingRewards.length; i++) { + addRewardItem(existingRewards[i]); + } + }); + } + } else { + // 预加载优惠券数据,以便后续使用 + fetchCoupons(); + } +} + +/** + * 验证奖励信息 + * @returns {boolean} - 验证结果 + */ +function validateRewardInfo() { + var $ = layui.$; + var hasRewardType = false; + + $('.reward-type-select').each(function () { + if ($(this).val()) { + hasRewardType = true; + var $item = $(this).closest('.reward-item'); + var rewardType = $(this).val(); + + // 如果不是优惠券类型,检查奖励数值 + if (rewardType != '4' && !$item.find('.reward-value-input').val()) { + layer.msg('请输入奖励数值', { icon: 2, anim: 6, time: 1500 }); + hasRewardType = false; + return false; + } + + // 如果是优惠券类型,检查是否选择了优惠券 + if (rewardType == '4' && !$item.find('.coupon-select').val()) { + layer.msg('请选择优惠券', { icon: 2, anim: 6, time: 1500 }); + hasRewardType = false; + return false; + } + } + }); + + if (!hasRewardType) { + layer.msg('请至少添加一项奖励信息', { icon: 2, anim: 6, time: 1500 }); + return false; + } + + // 验证通过后,处理奖励数据 + processRewardData(); + return true; +} + +/** + * 处理奖励数据,将其转换为JSON格式并添加到隐藏字段 + */ +function processRewardData() { + var $ = layui.$; + var rewardData = []; + + // 收集所有奖励项的数据 + $('.reward-item').each(function () { + var $item = $(this); + var rewardType = $item.find('.reward-type-select').val(); + + if (rewardType) { + var rewardObj = { + reward_type: rewardType, + reward_value: '', + coupon_id: '' + }; + + // 根据奖励类型设置相应的值 + if (rewardType == '4') { // 优惠券类型 + rewardObj.coupon_id = $item.find('.coupon-select').val() || ''; + } else { // 其他类型 + rewardObj.reward_value = $item.find('.reward-value-input').val() || ''; + } + + rewardData.push(rewardObj); + } + }); + + // 将奖励数据转换为JSON字符串 + var rewardJson = JSON.stringify(rewardData); + + // 检查表单中是否已存在reward隐藏字段 + if ($('input[name="reward"]').length > 0) { + $('input[name="reward"]').val(rewardJson); + } else { + // 创建隐藏字段并添加到表单中 + $('form').append(''); + } + + // 清除可能残留的旧字段(兼容性考虑) + $('input[name="reward_type[]"], input[name="reward_value[]"], input[name="coupon_id[]"]').remove(); +} \ No newline at end of file