From 04c6b703776ee1ed52b6177f64bb19f66812c395 Mon Sep 17 00:00:00 2001 From: youda Date: Fri, 11 Apr 2025 18:05:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 + app/admin/controller/Statistics.php | 288 +++++++++++----- app/admin/route/app.php | 8 + app/admin/view/Goods/goods_extend.html | 0 app/admin/view/Statistics/exchangeList.html | 73 ++++ app/admin/view/Statistics/goodsList.html | 81 +++++ app/admin/view/Statistics/orderList.html | 73 ++++ app/admin/view/Statistics/profit.html | 318 ++++++++---------- app/admin/view/Statistics/shipmentList.html | 79 +++++ app/admin/view/Statistics/userstatistics.html | 50 +-- app/api/controller/FuLiWu.php | 2 +- app/api/controller/Goods.php | 10 +- app/api/controller/Login.php | 34 +- app/api/controller/Notify.php | 28 +- app/api/controller/Order.php | 134 ++++++++ app/api/controller/Pay.php | 2 +- app/api/route/app.php | 8 +- app/command/AutoGoodsOffshelf.php | 3 + app/command/FlwOpen.php | 7 +- app/command/RankMonth.php | 4 +- app/command/RankWeek.php | 3 + app/command/UserStatisticsDay.php | 29 +- app/common.php | 14 +- app/common/model/UserLoginLog.php | 2 +- config/menu.php | 16 +- public/storage/poster/share/21549.png | Bin 0 -> 16939 bytes table.sql | 64 ++-- 27 files changed, 961 insertions(+), 376 deletions(-) mode change 100644 => 100755 app/admin/view/Goods/goods_extend.html create mode 100644 app/admin/view/Statistics/exchangeList.html create mode 100644 app/admin/view/Statistics/goodsList.html create mode 100644 app/admin/view/Statistics/orderList.html create mode 100644 app/admin/view/Statistics/shipmentList.html create mode 100644 app/api/controller/Order.php create mode 100644 public/storage/poster/share/21549.png diff --git a/README.md b/README.md index c2a217a..edea654 100755 --- a/README.md +++ b/README.md @@ -68,8 +68,15 @@ composer require yzalis/identicon composer require topthink/think-image php think UserStatisticsHour ``` +## +1. 接入微信小程序订单(需要订单页面,订单详情页面) +2. 修改前端支付页面,当抽数不够时,只显示对应的按钮。 +3. +SELECT goods_id,goods_title,goods_price,order_total,order_zhe_total,price,use_money,use_integral,use_money2,addtime,pay_time,prize_num,use_coupon FROM `order` where user_id=21544 and status=1 + +## 原抽无限赏奖逻辑(内存消耗过大,不在使用) ```sh // #组合中奖商品 diff --git a/app/admin/controller/Statistics.php b/app/admin/controller/Statistics.php index 0aff64a..d605d80 100755 --- a/app/admin/controller/Statistics.php +++ b/app/admin/controller/Statistics.php @@ -23,100 +23,93 @@ class Statistics extends Base public function profit(Request $request) { + $goodId = trim(input('get.goodId')); $title = trim(input('get.title')); - $id = trim(input('get.goodId')); $status = trim(input('get.status')); $type = trim(input('get.type')); $addtime = trim(input('get.addtime')); // 构建查询条件 - $whe = []; - if ($title) - $whe[] = ['title', 'like', '%' . $title . '%']; - if ($id) - $whe[] = ['id', '=', $id]; - if ($status) - $whe[] = ['status', '=', $status]; - if ($type) - $whe[] = ['type', '=', $type]; + $where = [['delete_time', '=', null]]; + if ($goodId) { + $where[] = ['id', '=', $goodId]; + } + if ($title) { + $where[] = ['title', 'like', '%' . $title . '%']; + } + if ($status) { + $where[] = ['status', '=', $status]; + } + if ($type) { + $where[] = ['type', '=', $type]; + } // 解析时间范围 - $whe3 = []; - $whe4 = []; + $startTime = 0; + $endTime = time(); if ($addtime) { - [$start_time, $end_time] = $this->parseTimeRange($addtime); - $whe3[] = ['addtime', 'BETWEEN', [$start_time, $end_time]]; - $whe4[] = ['addtime', 'BETWEEN', [$start_time, $end_time]]; + $times = explode(' - ', $addtime); + $startTime = strtotime($times[0]); + $endTime = strtotime($times[1]); } - // 获取商品ID列表 - $goodList = GoodsModel::where($whe)->column('id'); - if (empty($goodList)) { + // 获取测试用户ID + $testUsers = User::where('istest', '>', 0)->column('id'); + $testUserIds = empty($testUsers) ? [0] : $testUsers; + $testUserIdsStr = implode(',', $testUserIds); - View::assign([ + // 构建SQL查询 + $query = Db::name('goods')->alias('goods') + ->field([ + 'goods.id', + 'goods.title', + 'goods.imgurl', + 'goods.price', + 'goods.stock', + 'goods.status', + 'goods.type', + '(SELECT COALESCE(sum(use_money), 0) + COALESCE(sum(price), 0) FROM `order` WHERE status=1 AND (price>0 OR use_money>0) AND pay_time > ' . $startTime . ' and pay_time < ' . $endTime . ' AND goods_id=goods.id AND status=1 AND user_id NOT IN (' . $testUserIdsStr . ')) AS use_money', + '(SELECT COALESCE(sum(goodslist_money), 0) FROM `order_list` WHERE goods_id=goods.id AND user_id NOT IN (' . $testUserIdsStr . ') AND addtime > ' . $startTime . ' and addtime < ' . $endTime . ') AS sc_money', + '(SELECT COALESCE(sum(goodslist_money), 0) FROM `order_list` WHERE goods_id=goods.id AND LENGTH(recovery_num)>0 AND user_id NOT IN (' . $testUserIdsStr . ') AND addtime > ' . $startTime . ' and addtime < ' . $endTime . ') AS re_money', + '(SELECT COALESCE(sum(goodslist_money), 0) FROM `order_list` WHERE goods_id=goods.id AND LENGTH(send_num)>0 AND user_id NOT IN (' . $testUserIdsStr . ') AND addtime > ' . $startTime . ' and addtime < ' . $endTime . ') AS fh_money', + '(SELECT count(1) FROM `order_list` WHERE goods_id=goods.id AND user_id NOT IN (' . $testUserIdsStr . ') AND addtime > ' . $startTime . ' and addtime < ' . $endTime . ' and parent_goods_list_id=0 ) AS cj_count' + ]) + ->where($where) + ->order(['goods.id' => 'desc']); - 'sum_dingdan' => 0, - 'sum_shiji' => 0, - 'sum_chuhuo' => 0, - 'price_all' => 0, - 'sum_shijilirun' => 0, - 'sum_dingdanlirun' => 0, - 'use_money_all' => 0, - 'order_total_all' => 0, - 'list' => [], - 'count' => 0, - 'page' => '', - ]); - return View::fetch("Statistics/profit"); + // 获取列表数据 + $list = $query->select()->toArray(); + + // 计算总金额 + $totalIncome = 0; + $totalCost = 0; + $totalProfit = 0; + $totalReMoney = 0; + $totalFhMoney = 0; + + foreach ($list as &$item) { + // 计算单个盒子的利润和利润率 + $item['profit'] = $item['use_money'] - $item['sc_money']; + $item['profit_rate'] = $item['use_money'] > 0 ? round(($item['profit'] / $item['use_money']) * 100, 2) : 0; + $item['is_negative'] = $item['profit'] < 0; + + // 计算总金额 + $totalIncome += $item['use_money']; + $totalCost += $item['sc_money']; + $totalReMoney += $item['re_money']; + $totalFhMoney += $item['fh_money']; } - // 获取测试用户ID列表 - $userList = User::where('istest', '>', 0)->column('id'); - - // 订单筛选条件 - $whe3[] = ['user_id', 'not in', $userList]; - $whe3[] = ['status', '=', 1]; - $whe3[] = ['goods_id', 'in', $goodList]; - - $whe4[] = ['user_id', 'not in', $userList]; - $whe4[] = ['goods_id', 'in', $goodList]; - - // 统计订单数据 - $orderTotals = OrderModel::where($whe3) - ->field('SUM(order_total) as order_total_all, - SUM(order_zhe_total) as order_zhe_total_all, - SUM(price) as price_all, - SUM(use_money) as use_money_all') - ->find(); - - $goodslistMoneyAll = OrderList::where($whe4)->sum('goodslist_money'); - - // 获取商品列表 - $data = GoodsModel::getList($whe, "*", "id desc", 20); - - // 计算每个商品的订单详情 - foreach ($data['list'] as &$value) { - $value = array_merge($value, $this->calculateOrderDetails($value['id'], $userList, $addtime)); - } - - // 计算利润 - $sum_shijilirun = round($orderTotals->order_zhe_total_all - $goodslistMoneyAll, 2); - $sum_dingdanlirun = round($orderTotals->order_total_all - $goodslistMoneyAll, 2); + $totalProfit = $totalIncome - $totalCost; // 传递数据给视图 View::assign([ - - 'sum_dingdan' => $orderTotals->order_total_all, - 'sum_shiji' => $orderTotals->order_zhe_total_all, - 'sum_chuhuo' => $goodslistMoneyAll, - 'price_all' => $orderTotals->price_all, - 'sum_shijilirun' => $sum_shijilirun, - 'sum_dingdanlirun' => $sum_dingdanlirun, - 'use_money_all' => $orderTotals->use_money_all, - 'order_total_all' => $orderTotals->order_total_all, - 'list' => $data['list'], - 'count' => $data['count'], - 'page' => $data['page'], + 'list' => $list, + 'totalIncome' => $totalIncome, + 'totalCost' => $totalCost, + 'totalProfit' => $totalProfit, + 'totalReMoney' => $totalReMoney, + 'totalFhMoney' => $totalFhMoney, ]); return View::fetch("Statistics/profit"); @@ -413,5 +406,148 @@ class Statistics extends Base return View::fetch('Statistics/userstatistics'); } + /** + * 订单列表 + */ + public function orderList(Request $request) + { + $goodsId = $request->param('goods_id', 0, 'intval'); + + // 获取测试用户ID + $testUsers = User::where('istest', '>', 0)->column('id'); + + // 查询条件 + $where = [ + ['status', '=', 1], + ['goods_id', '=', $goodsId] + ]; + + if (!empty($testUsers)) { + $where[] = ['user_id', 'not in', $testUsers]; + } + + // 获取订单列表 + $list = OrderModel::where($where) + ->append(['user_info']) + ->order('id', 'desc') + ->paginate(['list_rows' => 50, 'query' => request()->param()]); + + // 传递数据给视图 + View::assign([ + 'list' => $list, + 'page' => $list->render(), + 'goods_id' => $goodsId + ]); + + return View::fetch("Statistics/orderList"); + } + + /** + * 出货列表 + */ + public function goodsList(Request $request) + { + $goodsId = $request->param('goods_id', 0, 'intval'); + + // 获取测试用户ID + $testUsers = User::where('istest', '>', 0)->column('id'); + + // 查询条件 + $where = [ + ['goods_id', '=', $goodsId] + ]; + + if (!empty($testUsers)) { + $where[] = ['user_id', 'not in', $testUsers]; + } + + // 获取出货列表 + $list = OrderList::where($where) + ->order('id', 'desc') + ->paginate(['list_rows' => 50, 'query' => request()->param()]); + + // 传递数据给视图 + View::assign([ + 'list' => $list, + 'page' => $list->render(), + 'goods_id' => $goodsId + ]); + + return View::fetch("Statistics/goodsList"); + } + + /** + * 兑换列表 + */ + public function exchangeList(Request $request) + { + $goodsId = $request->param('goods_id', 0, 'intval'); + + // 获取测试用户ID + $testUsers = User::where('istest', '>', 0)->column('id'); + + // 查询条件 + $where = [ + ['goods_id', '=', $goodsId] + ]; + + $where[] = ['recovery_num', '!=', '']; + // $where[] = ['recovery_num', '!=', null]; + + if (!empty($testUsers)) { + $where[] = ['user_id', 'not in', $testUsers]; + } + + // 获取兑换列表 + $list = OrderList::where($where) + ->order('id', 'desc') + ->paginate(['list_rows' => 50, 'query' => request()->param()]); + + // 传递数据给视图 + View::assign([ + 'list' => $list, + 'page' => $list->render(), + 'goods_id' => $goodsId + ]); + + return View::fetch("Statistics/exchangeList"); + } + + /** + * 发货列表 + */ + public function shipmentList(Request $request) + { + $goodsId = $request->param('goods_id', 0, 'intval'); + + // 获取测试用户ID + $testUsers = User::where('istest', '>', 0)->column('id'); + + // 查询条件 + $where = [ + ['goods_id', '=', $goodsId] + ]; + + $where[] = ['send_num', '<>', '']; + // $where[] = ['send_num', '<>', null]; + + if (!empty($testUsers)) { + $where[] = ['user_id', 'not in', $testUsers]; + } + + // 获取发货列表 + $list = OrderList::where($where) + ->order('id', 'desc') + ->paginate(['list_rows' => 50, 'query' => request()->param()]); + + // 传递数据给视图 + View::assign([ + 'list' => $list, + 'page' => $list->render(), + 'goods_id' => $goodsId + ]); + + return View::fetch("Statistics/shipmentList"); + } } diff --git a/app/admin/route/app.php b/app/admin/route/app.php index 48a7ece..54360bb 100755 --- a/app/admin/route/app.php +++ b/app/admin/route/app.php @@ -312,6 +312,14 @@ Route::rule('productcate_del', 'ProductCate/del', 'GET|POST'); Route::rule('statistics_profit', 'Statistics/profit', 'GET'); //数据看台 Route::rule('statistics_dataStand', 'Statistics/DataStand', 'GET'); +//兑换列表 +Route::rule('statistics_exchangeList', 'Statistics/exchangeList', 'GET'); +//发货列表 +Route::rule('statistics_shipmentList', 'Statistics/shipmentList', 'GET'); +//出货列表 +Route::rule('statistics_orderList', 'Statistics/goodsList', 'GET'); +//支付订单 +Route::rule('statistics_order', 'Statistics/orderList', 'GET'); //利润支出 Route::rule('ProfitExpenses', 'Profit/index', 'GET'); diff --git a/app/admin/view/Goods/goods_extend.html b/app/admin/view/Goods/goods_extend.html old mode 100644 new mode 100755 diff --git a/app/admin/view/Statistics/exchangeList.html b/app/admin/view/Statistics/exchangeList.html new file mode 100644 index 0000000..aefa6a9 --- /dev/null +++ b/app/admin/view/Statistics/exchangeList.html @@ -0,0 +1,73 @@ +{include file="Public:header2"/} + + +
+
+
兑换列表
+
+ + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo" key="i"} + + + + + + + + + + + + + + + + + {/volist} + {if condition="empty($list)"} + + + + {/if} + +
序号ID订单ID用户ID兑换单号盒子ID奖品ID奖品名称奖品图片奖品价值兑换价值奖品类型添加时间选择时间
{$i}{$vo.id}{$vo.order_id}{$vo.user_id}{$vo.recovery_num}{$vo.goods_id}{$vo.goodslist_id}{$vo.goodslist_title} + + ¥ {$vo.goodslist_price}¥ {$vo.goodslist_money} + {if condition="$vo.goodslist_type eq 1"} + 现货 + {elseif condition="$vo.goodslist_type eq 2"} + 预售 + {elseif condition="$vo.goodslist_type eq 3"} + 货币 + {elseif condition="$vo.goodslist_type eq 4"} + 宝箱 + {/if} + {$vo.addtime|date="Y-m-d H:i:s"}{$vo.choice_time|date="Y-m-d H:i:s"}
暂时没有数据!
+
+ {$page|raw} +
+
+
+
+ {include file="Public:footer"/} + + \ No newline at end of file diff --git a/app/admin/view/Statistics/goodsList.html b/app/admin/view/Statistics/goodsList.html new file mode 100644 index 0000000..b3a0ff1 --- /dev/null +++ b/app/admin/view/Statistics/goodsList.html @@ -0,0 +1,81 @@ +{include file="Public:header2"/} + + +
+
+
出货列表
+
+ + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + {/volist} + {if condition="empty($list)"} + + + + {/if} + +
ID订单ID用户ID盒子ID盒子排序奖品ID奖品名称奖品图片奖品价值兑换价值奖品类型状态添加时间
{$vo.id}{$vo.order_id}{$vo.user_id}{$vo.goods_id}{$vo.num}{$vo.goodslist_id}{$vo.goodslist_title} + + ¥ {$vo.goodslist_price}¥ {$vo.goodslist_money} + {if condition="$vo.goodslist_type eq 1"} + 现货 + {elseif condition="$vo.goodslist_type eq 2"} + 预售 + {elseif condition="$vo.goodslist_type eq 3"} + 货币 + {elseif condition="$vo.goodslist_type eq 4"} + 宝箱 + {/if} + + {if condition="$vo.status eq 0"} + 待选择 + {elseif condition="$vo.status eq 1"} + 回收 + {elseif condition="$vo.status eq 2"} + 选择发货 + {elseif condition="$vo.status eq 3"} + 发布集市 + {/if} + {$vo.addtime|date="Y-m-d H:i:s"}
暂时没有数据!
+
+ {$page|raw} +
+
+
+
+ {include file="Public:footer"/} + + \ No newline at end of file diff --git a/app/admin/view/Statistics/orderList.html b/app/admin/view/Statistics/orderList.html new file mode 100644 index 0000000..f5034c6 --- /dev/null +++ b/app/admin/view/Statistics/orderList.html @@ -0,0 +1,73 @@ +{include file="Public:header2"/} + + +
+
+
支付订单列表
+
+ + + + + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + + + {/volist} + {if condition="empty($list)"} + + + + {/if} + +
序号订单ID订单号用户ID用户昵称盒子ID盒子名称订单总金额实际支付微信钻石UU币达达卷优惠券抵扣订单状态下单时间支付时间
{$i}{$vo.id}{$vo.order_num}{$vo.user_id}{$vo.user_info? $vo.user_info.nickname:$vo.user_id}{$vo.goods_id}{$vo.goods_title}¥ {$vo.order_total}¥ {$vo.order_zhe_total}¥ {$vo.price}¥ {$vo.use_money}¥ {$vo.use_coupon}¥ {$vo.use_integral}¥ {$vo.use_money2} + {if condition="$vo.status eq 1"} + 已支付 + {else} + 未支付 + {/if} + {$vo.addtime|date="Y-m-d H:i:s"}{$vo.pay_time|date="Y-m-d H:i:s"}
暂时没有数据!
+
+ {$page|raw} +
+
+
+
+ {include file="Public:footer"/} + + \ No newline at end of file diff --git a/app/admin/view/Statistics/profit.html b/app/admin/view/Statistics/profit.html index 8f5743d..5883bb4 100755 --- a/app/admin/view/Statistics/profit.html +++ b/app/admin/view/Statistics/profit.html @@ -1,9 +1,9 @@ -{include file="Public:header2"/} +{include file="Public:header3"/}
- +
@@ -32,8 +32,6 @@
@@ -45,186 +43,172 @@
-
+ +
-
- 订单收入:{$sum_dingdan} - 实际收入:{$sum_shiji} - 微信收入:{$price_all} - 余额收入:{$use_money_all} - - 出货价值:{$sum_chuhuo} - 订单利润:{if condition="$sum_dingdanlirun < 0"} - {$sum_dingdanlirun} - {elseif condition="$sum_dingdanlirun >= 0"} - {$sum_dingdanlirun} - {/if} - - 实际利润: - {if condition="$sum_shijilirun < 0"} {$sum_shijilirun} - {elseif condition="$sum_shijilirun >= 0"} - {$sum_shijilirun} - {/if} - - +
+
+
+
总收入
+
+ ¥ {$totalIncome|default="0"|round=2} +
+
+
+
+
+
总出货价值
+
+ ¥ {$totalCost|default="0"|round=2} +
+
+
+
+
+
总利润
+
+ ¥ {$totalProfit|default="0"|round=2} +
+
+
+
+
+
总兑换/发货价值
+
+ ¥ {$totalReMoney|default="0"|round=2} / + ¥ {$totalFhMoney|default="0"|round=2} +
+
+
+ + - - - - - + + + + + + + {volist name="list" id="vo"} - + + + - - - - - + + - - - - {/volist} - - {if condition="empty($list)"} + + + + + + {/volist} + {if condition="empty($list)"} - + {/if} -
盒子ID 盒子名称 盒子类型/状态盒子数据支付金额抵扣相关支付金额合计盒子单价抽奖次数收入 出货价值兑换价值发货价值 利润利润率操作
{$vo.id}{$vo.title} - {if condition="$vo['type'] eq 1"} -
- {$vo['id']} -
- {elseif condition="$vo['type'] eq 11"} -
- {$vo['id']} -
- - {else } - - {$vo['id']} - {/if} -
{$vo['title']} - {if condition="$vo['type'] eq 1"} - - {elseif condition="$vo['type'] eq 2"} - - {elseif condition="$vo['type'] eq 3"} - - {elseif condition="$vo['type'] eq 5"} - - {elseif condition="$vo['type'] eq 6"} - - {elseif condition="$vo['type'] eq 8"} - - {elseif condition="$vo['type'] eq 9"} - - {elseif condition="$vo['type'] eq 10"} - - {elseif condition="$vo['type'] eq 11"} - + {if condition="$vo.type eq 1"} + + {elseif condition="$vo.type eq 2"} + + {elseif condition="$vo.type eq 3"} + + {elseif condition="$vo.type eq 5"} + + {elseif condition="$vo.type eq 6"} + + {elseif condition="$vo.type eq 8"} + + {elseif condition="$vo.type eq 9"} + + {elseif condition="$vo.type eq 10"} + + {elseif condition="$vo.type eq 11"} + {/if} / - {if condition="$vo['status'] eq 1" } - 上架 - {elseif condition="$vo['status'] eq 2"} - 下架 - {elseif condition="$vo['status'] eq 3"} - 售罄 + {if condition="$vo.status eq 1"} + 上架 + {elseif condition="$vo.status eq 2"} + 下架 + {elseif condition="$vo.status eq 3"} + 售罄 {/if} 盒子单价:{$vo['price']}
- 订单数量:{$vo['order_count']}
- 抽奖次数:{$vo['count_OrderList']}
-
¥ {$vo.price}{$vo.cj_count} - 微信-支付金额:{$vo['count_price']}
- 钻石-支付金额: {$vo['count_yue']}
+ ¥ {$vo.use_money|default="0"|round=2}
- 积分抵扣: {$vo['count_use_score']}
- 优惠卷抵扣:{$vo['count_use_coupon']} + ¥ {$vo.sc_money|default="0"|round=2}
- 订单收入:{$vo['order_total']}
- 实际收入:{$vo['order_zhe_total']}(去除折扣)
- 收入核算1:{$vo['order_total']}(订单数量*价格)
- 收入核算2:{$vo['count_heji']}(微信+余额+各种抵扣)
- -
出货价值:{$vo['goodslist_price']}实际利润: - {if condition="$vo['lirun'] < 0"} {$vo['lirun']}
- 利润率: {$vo['lirulv']}%
- {elseif condition="$vo['lirun'] >= 0"} - {$vo['lirun']}
- 实际利润率: {$vo['lirulv']}%
- {/if} - - 订单利润: - {if condition="$vo['liruns'] < 0"} - {$vo['liruns']}
- 订单利润率: {$vo['lirulvs']}%
- {elseif condition="$vo['liruns'] >= 0"} - {$vo['liruns']}
- 订单利润率: {$vo['lirulvs']}%
- {/if} - - - - +
+ ¥ {$vo.re_money|default="0"|round=2} + ¥ {$vo.fh_money|default="0"|round=2} + + = 0"}layui-bg-green{else}layui-bg-red{/if}"> + ¥ {$vo.profit|default="0"|round=2} + + + = 0"}layui-bg-green{else}layui-bg-red{/if}"> + {$vo.profit_rate|default="0"|round=2}% + + + + + + +
暂时没有数据!暂时没有数据!
-
- {$page|raw} -
- {include file="Public:footer"/} + {include file="Public:footer3"/} - \ No newline at end of file diff --git a/app/admin/view/Statistics/shipmentList.html b/app/admin/view/Statistics/shipmentList.html new file mode 100644 index 0000000..d1faef6 --- /dev/null +++ b/app/admin/view/Statistics/shipmentList.html @@ -0,0 +1,79 @@ +{include file="Public:header"/} + + +
+
+
发货列表
+
+ + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + {/volist} + {if condition="empty($list)"} + + + + {/if} + +
ID订单ID用户ID发货单号盒子ID奖品ID奖品名称奖品图片奖品价值兑换价值奖品类型保险状态添加时间选择时间
{$vo.id}{$vo.order_id}{$vo.user_id}{$vo.send_num}{$vo.goods_id}{$vo.goodslist_id}{$vo.goodslist_title} + + ¥ {$vo.goodslist_price}¥ {$vo.goodslist_money} + {if condition="$vo.goodslist_type eq 1"} + 现货 + {elseif condition="$vo.goodslist_type eq 2"} + 预售 + {elseif condition="$vo.goodslist_type eq 3"} + 货币 + {elseif condition="$vo.goodslist_type eq 4"} + 宝箱 + {/if} + + {if condition="$vo.insurance_is eq 0"} + + {elseif condition="$vo.insurance_is eq 1"} + + {/if} + {$vo.addtime|date="Y-m-d H:i:s"}{$vo.choice_time|date="Y-m-d H:i:s"}
暂时没有数据!
+
+ {$page|raw} +
+
+
+
+ {include file="Public:footer"/} + + \ No newline at end of file diff --git a/app/admin/view/Statistics/userstatistics.html b/app/admin/view/Statistics/userstatistics.html index 140d05e..797934d 100755 --- a/app/admin/view/Statistics/userstatistics.html +++ b/app/admin/view/Statistics/userstatistics.html @@ -193,7 +193,7 @@ trigger: 'axis' }, legend: { - data: ['登录', '注册', '消费人数', '微信充值人数'] + data: ['登录', '注册'] }, grid: { left: '3%', @@ -241,18 +241,18 @@ data: registerData // 使用生成的时间序列数据 }, - { - name: '消费人数', - type: 'line', + // { + // name: '消费人数', + // type: 'line', - data: consumeData // 使用生成的时间序列数据 - }, - { - name: '微信充值人数', - type: 'line', - stack: 'Total', - data: consume_rmb_count // 使用生成的时间序列数据 - } + // data: consumeData // 使用生成的时间序列数据 + // }, + // { + // name: '微信充值人数', + // type: 'line', + // stack: 'Total', + // data: consume_rmb_count // 使用生成的时间序列数据 + // } ] }; @@ -269,7 +269,7 @@ trigger: 'axis' }, legend: { - data: ['总消费', '微信充值', '余额充值'] + data: ['总消费', '微信消费', '钻石消费'] }, grid: { left: '3%', @@ -312,13 +312,13 @@ data: recharge_sum // 使用生成的时间序列数据 }, { - name: '微信充值', + name: '微信消费', type: 'line', data: recharge_amount // 使用生成的时间序列数据 }, { - name: '余额充值', + name: '钻石消费', type: 'line', data: balance_consume // 使用生成的时间序列数据 @@ -338,7 +338,7 @@ trigger: 'axis' }, legend: { - data: ['利润', '总收入', '总支出'] + data: ['总收入', '总支出'] }, grid: { left: '3%', @@ -374,12 +374,12 @@ } ], series: [ - { - name: '利润', - type: 'line', + // { + // name: '利润', + // type: 'line', - data: all_money // 使用生成的时间序列数据 - }, + // data: all_money // 使用生成的时间序列数据 + // }, { name: '总收入', type: 'line', @@ -395,8 +395,8 @@ ] }; // 使用刚指定的配置项和数据显示图表 - var lirun = echarts.init(document.getElementById('lirun')); - lirun.setOption(option2); + // var lirun = echarts.init(document.getElementById('lirun')); + // lirun.setOption(option2); // 指定图表的配置项和数据 var option3 = { @@ -464,8 +464,8 @@ ] }; // 使用刚指定的配置项和数据显示图表 - var qita = echarts.init(document.getElementById('qita')); - qita.setOption(option3); + // var qita = echarts.init(document.getElementById('qita')); + // qita.setOption(option3); diff --git a/app/api/controller/FuLiWu.php b/app/api/controller/FuLiWu.php index 773a813..a9d3af5 100755 --- a/app/api/controller/FuLiWu.php +++ b/app/api/controller/FuLiWu.php @@ -316,7 +316,7 @@ class FuLiWu extends Base public function fuliwu_user_winning_records(Request $request) { $user = $this->getUser(); - $user_id = $user['user_id']; + $user_id = $user['id']; $list = OrderList::where('user_id', '=', $user_id) ->where('order_type', '=', 15) diff --git a/app/api/controller/Goods.php b/app/api/controller/Goods.php index 98ddce1..312cbf5 100755 --- a/app/api/controller/Goods.php +++ b/app/api/controller/Goods.php @@ -287,8 +287,8 @@ class Goods extends Base #概率 if ($surplus_stock > 0) { $pro_basics = bcdiv("$surplus_stock", "$all_surplus_stock", 4); - $pro = '概率:' . ($pro_basics * 100) . '%'; - $pro_num = ($pro_basics * 100); + $pro = '概率:' . removeTrailingZeros(($pro_basics * 100)) . '%'; + $pro_num = removeTrailingZeros(($pro_basics * 100)); } else { $pro = '概率:' . 0 . '%'; $pro_num = 0; @@ -441,8 +441,8 @@ class Goods extends Base } if ($value_1['stock'] == 0) { //保留两位小数 - $value_1['pro'] = '概率:' . round($value_1['real_pro'], 2) . '%'; - $value_1['pro_num'] = round($value_1['real_pro'], 2); + $value_1['pro'] = '概率:' . removeTrailingZeros(round($value_1['real_pro'], 2)) . '%'; + $value_1['pro_num'] = removeTrailingZeros(round($value_1['real_pro'], 2)); unset($value_1['surplus_stock']); unset($value_1['stock']); continue; @@ -459,7 +459,7 @@ class Goods extends Base #概率 if ($surplus_stock_1 > 0) { //计算概率,保留两位小数 - $pro_num_1 = round(($surplus_stock_1 / $goodsList_surplus_stock) * 100, 2); + $pro_num_1 = removeTrailingZeros(round(($surplus_stock_1 / $goodsList_surplus_stock) * 100, 2) ); $pro_1 = '概率:' . $pro_num_1 . '%'; } else { $pro_1 = '概率:' . 0 . '%'; diff --git a/app/api/controller/Login.php b/app/api/controller/Login.php index 4b492d8..10723e0 100755 --- a/app/api/controller/Login.php +++ b/app/api/controller/Login.php @@ -567,7 +567,7 @@ class Login extends Base public function ip_location($last_login_ip) { if ($last_login_ip) { - $url = "https://restapi.amap.com/v3/ip?key=6a46ad822120e393956e89d498e8c40b&ip=" . "$last_login_ip" . ""; + $url = "https://restapi.amap.com/v3/ip?key=2bf9bdfeb03a8835ce324443eb18e4da&ip=" . "$last_login_ip" . ""; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @@ -682,35 +682,7 @@ class Login extends Base $data = $wxServer->getAccessTokenOffiaccountSign($url); return $this->renderSuccess('', $data); } - public function test() - { - $account_token['token'] = "77f6358084be8d5545747911e7f9d5ad5644a114"; - $account_token['logintype'] = "2"; - return $this->renderSuccess("登录成功", $account_token); - } - - public function test1() - { - $share_image = getConfig("base")['share_image']; - $public_path = dirname($_SERVER['SCRIPT_FILENAME']); - $poster_bg = $public_path . $share_image; - // var_dump($poster_bg); - // $rule = getConfig('base'); - // $draw_people_num = $rule['draw_people_num']; - // $user_id = 31; - // $pid = 24; - // if(!empty($pid)){ - // $num = 0; - // $num = ProfitDraw::where(['type'=>5,'user_id'=>$pid])->count(); - // if(bccomp("$num","$draw_people_num") < 0){ - // #可以获得一张抽奖券 - // $res= User::changeDraw($pid, 1,5 , '获得一张抽奖券',$user_id); - // var_dump($res); - // } - - // } - // log::info($res); - } + /** @@ -762,7 +734,7 @@ class Login extends Base ); // //将数据写入redis,过期时间为当天剩余的时间 // $redis->set($redis_key, json_encode($user), 86400 - time() % 86400); - return $this->renderSuccess('登录记录成功', [ + return $this->renderSuccess('登录成功', [ 'uid' => $user['uid'] ?: $user['id'], 'nickname' => $user['nickname'], 'headimg' => imageUrl($user['headimg']) diff --git a/app/api/controller/Notify.php b/app/api/controller/Notify.php index b30ad5c..ba41413 100755 --- a/app/api/controller/Notify.php +++ b/app/api/controller/Notify.php @@ -1156,18 +1156,18 @@ class Notify extends Base $currentRange = 0; foreach ($goodslist as $good) { - if ($good['stock'] <= 0) { - continue; - } + // if ($good['stock'] <= 0) { + // continue; + // } #判断今日库存 $user_quanju_count = OrderList::field('id') ->where('goods_id', '=', $goods_id) ->where('parent_goods_list_id', '=', 0) ->where('addtime', '>=', $todayMidnight) ->count(); - if ($user_quanju_count >= $good['stock']) { - continue; - } + // if ($user_quanju_count >= $good['stock']) { + // continue; + // } $rangeStart = $currentRange; $currentRange += $good['real_pro']; $probabilityRanges[] = [ @@ -1203,7 +1203,10 @@ class Notify extends Base ->order('id desc') ->value('luck_no'); $luck_no++; - + $doubling = $prize_info['doubling']; + if(!$doubling){ + $doubling=0; + } #新增记录 $save_prize_info = [ 'order_id' => $order_id, @@ -1211,7 +1214,7 @@ class Notify extends Base 'status' => 0,#0未操作 1选择兑换 2选择发货 'goods_id' => $goods_id, 'num' => 0, - 'doubling' => $prize_info['doubling'], + 'doubling' => $doubling, 'shang_id' => $prize_info['shang_id'], 'goodslist_id' => $prize_info['id'], 'goodslist_title' => $prize_info['title'], @@ -1359,7 +1362,10 @@ class Notify extends Base ->order('id desc') ->value('luck_no'); $luck_no++; - + $doubling =$prize_info['doubling']; + if(!$doubling){ + $doubling=0; + } #新增记录 $save_prize_info = [ 'order_id' => $order_id, @@ -1367,7 +1373,7 @@ class Notify extends Base 'status' => 0,#0未操作 1选择兑换 2选择发货 'goods_id' => $goods_id, 'num' => 0, - 'doubling' => $prize_info['doubling'], + 'doubling' => $doubling, 'shang_id' => $prize_info['shang_id'], 'goodslist_id' => $prize_info['id'], 'goodslist_title' => $prize_info['title'], @@ -1574,7 +1580,7 @@ class Notify extends Base Db::name('goods_king_rank')->where([['user_id', '=', $infinite_goods['king_user_id']], ['goods_id', '=', $v['goods_id']]])->order('id', 'desc')->limit(1)->inc('z_nums', 1)->update(); $king_money = $infinite_goods['lingzhu_fan']; if ($king_money && $king_money > 0) { - + Db::name('goods_king_rank')->where([['user_id', '=', $infinite_goods['king_user_id']], ['goods_id', '=', $v['goods_id']]])->order('id', 'desc')->limit(1)->inc('money', floatval($king_money))->update(); // User::changeIntegral($infinite_goods['king_user_id'], $king_money, 4, '领主收益'); diff --git a/app/api/controller/Order.php b/app/api/controller/Order.php new file mode 100644 index 0000000..a873686 --- /dev/null +++ b/app/api/controller/Order.php @@ -0,0 +1,134 @@ +getUser(); + + // 获取分页参数 + $page = $this->request->param('page', 1); + $pageSize = $this->request->param('page_size', 10); + + // 获取订单列表 + $orderQuery = Db::name('order') + ->field('goods_id, goods_title, goods_price, order_total, order_zhe_total, price, use_money, use_integral, use_money2, addtime, pay_time, prize_num, use_coupon, order_num') + ->where([ + 'user_id' => $user['id'], + 'status' => 1 + ]) + ->order('addtime desc'); + + // 获取总数 + $total = $orderQuery->count(); + + // 获取分页数据 + $orderList = $orderQuery->page($page, $pageSize)->select()->toArray(); + + // 格式化数据 + foreach ($orderList as &$order) { + // 格式化时间 + $order['addtime'] = date('Y-m-d H:i:s', $order['addtime']); + $order['pay_time'] = $order['pay_time'] ? date('Y-m-d H:i:s', $order['pay_time']) : ''; + // 格式化价格数据 + $order['goods_price'] = (float)$order['goods_price']; + $order['order_total'] = (float)$order['order_total']; + $order['order_zhe_total'] = (float)$order['order_zhe_total']; + $order['price'] = (float)$order['price']; + $order['use_money'] = (float)$order['use_money']; + $order['use_money2'] = (float)$order['use_money2']; + } + unset($order); + + // 返回分页数据 + $data = [ + 'list' => $orderList, + 'total' => $total, + 'page' => (int)$page, + 'page_size' => (int)$pageSize, + 'total_pages' => ceil($total / $pageSize) + ]; + + return $this->renderSuccess('获取成功', $data); + } + + /** + * 获取订单详情 + * + * @return \think\Response + */ + public function getOrderDetail() + { + // 获取订单编号 + $orderNum = $this->request->param('order_num', ''); + if (empty($orderNum)) { + return $this->renderError('订单编号不能为空'); + + } + + // 获取当前登录用户 + $user = $this->getUser(); + + // 获取订单详情 + $orderInfo = Db::name('order') + ->field('goods_id, goods_title, goods_price, id, order_total, order_zhe_total, price, use_money, use_integral, use_money2, addtime, pay_time, prize_num, use_coupon') + ->where([ + 'status' => 1, + 'order_num' => $orderNum + ]) + ->find(); + + if (!$orderInfo) { + return $this->renderError('订单不存在'); + + } + + // 格式化时间 + $orderInfo['addtime'] = date('Y-m-d H:i:s', $orderInfo['addtime']); + $orderInfo['pay_time'] = $orderInfo['pay_time'] ? date('Y-m-d H:i:s', $orderInfo['pay_time']) : ''; + + // 格式化价格数据 + $orderInfo['goods_price'] = (float)$orderInfo['goods_price']; + $orderInfo['order_total'] = (float)$orderInfo['order_total']; + $orderInfo['order_zhe_total'] = (float)$orderInfo['order_zhe_total']; + $orderInfo['price'] = (float)$orderInfo['price']; + $orderInfo['use_money'] = (float)$orderInfo['use_money']; + $orderInfo['use_money2'] = (float)$orderInfo['use_money2']; + + // 获取订单商品列表 + $orderGoods = Db::name('order_list') + ->field('goodslist_title, goodslist_imgurl, goodslist_price, addtime') + ->where([ + 'order_id' => $orderInfo['id'] + ]) + ->select()->toArray(); + + // 格式化订单商品数据 + foreach ($orderGoods as &$goods) { + $goods['addtime'] = date('Y-m-d H:i:s', $goods['addtime']); + $goods['goodslist_price'] = (float)$goods['goodslist_price']; + $goods['goodslist_imgurl'] = imageUrl($goods['goodslist_imgurl']); + } + unset($goods); + + $orderInfo['goods_list'] = $orderGoods; + + return $this->renderSuccess('获取成功', $orderInfo); + } + +} \ No newline at end of file diff --git a/app/api/controller/Pay.php b/app/api/controller/Pay.php index 5b90f6b..d1977fe 100755 --- a/app/api/controller/Pay.php +++ b/app/api/controller/Pay.php @@ -179,7 +179,7 @@ class Pay extends Base return $this->wxpay($order_num, $total, $title, $openid, $notify); } elseif ($type == 4) { //积分 商城购买 - $order = ProductOrder::getInfo(['order_num' => $order_num]); + $order = OrderModel::getInfo(['order_num' => $order_num]); $total = $order['total_money']; $notify = 'https://' . $_SERVER['HTTP_HOST'] . '/api/notify/order_notify4'; return $this->wxpay($order_num, $total, $title, $openid, $notify); diff --git a/app/api/route/app.php b/app/api/route/app.php index 3a656f9..5692383 100755 --- a/app/api/route/app.php +++ b/app/api/route/app.php @@ -199,4 +199,10 @@ Route::rule('login_record', 'Login/recordLogin', 'GET|POST'); Route::any('advlist', 'Index/getAdvert'); Route::any('recordConsume', 'Index/record'); Route::any('getPeopleList', 'Index/get_user_yaoqing'); -Route::any('getRankList', 'Index/getRankList'); \ No newline at end of file +Route::any('getRankList', 'Index/getRankList'); + +#============================ +#Order.php订单管理 +#============================ +Route::any('order_list', 'Order/getOrderList'); +Route::any('order_detail', 'Order/getOrderDetail'); \ No newline at end of file diff --git a/app/command/AutoGoodsOffshelf.php b/app/command/AutoGoodsOffshelf.php index 97797bc..bf0114d 100755 --- a/app/command/AutoGoodsOffshelf.php +++ b/app/command/AutoGoodsOffshelf.php @@ -8,6 +8,9 @@ use think\console\Input; use think\console\Output; use think\facade\Db; +/** + * 自动下架利润率过低的盒子 + */ class AutoGoodsOffshelf extends Command { protected function configure() diff --git a/app/command/FlwOpen.php b/app/command/FlwOpen.php index a74b871..46fa0b7 100755 --- a/app/command/FlwOpen.php +++ b/app/command/FlwOpen.php @@ -73,6 +73,7 @@ class FlwOpen extends Command protected function special_prize_notice_time($goods_id, $goods_title) { + echo ('福利屋开奖$goods_id' . $goods_id . '福利屋开奖$goods_title' . $goods_title) . PHP_EOL; $res = []; $num = 0; #第几箱 print_r('$goods_id' . $goods_id); @@ -101,6 +102,8 @@ class FlwOpen extends Command ->toArray(); // 如果没有参与用户,直接返回 if (empty($all_order_list)) { + + echo ('福利屋开奖完成没有用户参加, goods_id: ' . $goods_id) . PHP_EOL; Goods::where(['id' => $goods_id])->update(['is_open' => 1, 'status' => 3]); return $res; } @@ -187,10 +190,10 @@ class FlwOpen extends Command // 更新福利屋状态为已开奖 echo ('福利屋开奖完成 goods_id: ' . $goods_id) . PHP_EOL; - Log::info('福利屋开奖完成 goods_id: ' . $goods_id. PHP_EOL) ; + Log::info('福利屋开奖完成 goods_id: ' . $goods_id . PHP_EOL); } else { echo ('福利屋开奖未完成 goods_id: ' . $goods_id . ', 未处理用户数: ' . $unprocessed_count) . PHP_EOL; - Log::info('福利屋开奖未完成 goods_id: ' . $goods_id . ', 未处理用户数: ' . $unprocessed_count) ; + Log::info('福利屋开奖未完成 goods_id: ' . $goods_id . ', 未处理用户数: ' . $unprocessed_count); } return $res; diff --git a/app/command/RankMonth.php b/app/command/RankMonth.php index c2a75f8..b756fb1 100755 --- a/app/command/RankMonth.php +++ b/app/command/RankMonth.php @@ -13,7 +13,9 @@ use think\console\input\Option; use think\console\Output; use think\facade\Db; - +/** + * 月榜定榜 + */ class RankMonth extends Command { protected function configure() diff --git a/app/command/RankWeek.php b/app/command/RankWeek.php index 9fab7e6..49d4594 100755 --- a/app/command/RankWeek.php +++ b/app/command/RankWeek.php @@ -14,6 +14,9 @@ use think\console\Output; use think\facade\Db; +/** + * 周榜定榜 + */ class RankWeek extends Command { protected function configure() diff --git a/app/command/UserStatisticsDay.php b/app/command/UserStatisticsDay.php index 3c569fe..bf6bf32 100755 --- a/app/command/UserStatisticsDay.php +++ b/app/command/UserStatisticsDay.php @@ -16,12 +16,17 @@ use app\common\model\OrderList; use app\common\model\OrderListRecovery; use app\common\model\ProfitExpenses; use app\common\model\ProfitRvenue; +use app\common\model\UserLoginLog; + class UserStatisticsDay extends Command { // php think UserStatisticsDay + /** + * 用户每天数据统计 + */ protected function configure() { - $this->setName('UserStatisticsHour')->setDescription('用户每天数据统计'); + $this->setName('UserStatisticsDay')->setDescription('用户每天数据统计'); } protected function execute(Input $input, Output $output) @@ -42,9 +47,12 @@ class UserStatisticsDay extends Command $today_start = strtotime($today); $today_end = strtotime($today . ' +1 day'); - // 查询当天的登录人数 - $loginCount = UserAccount::where('last_login_time', '>=', $today_start) - ->where('last_login_time', '<', $today_end) + // // 查询当天的登录人数 + // $loginCount = UserAccount::where('last_login_time', '>=', $today_start) + // ->where('last_login_time', '<', $today_end) + // ->count('DISTINCT user_id'); + $loginCount = UserLoginLog::where('login_time','>=',$today_start) + ->where('login_time','<',$today_end) ->count('DISTINCT user_id'); //当天注册人数 $registerCount = User::where('addtime', '>=', $today_start) @@ -86,12 +94,13 @@ class UserStatisticsDay extends Command )->sum('use_money'); //今日消费 - $order_zhe_total = OrderModel::where('status', '=', 1)->whereNotIn('user_id', $userNotArray) - ->whereBetweenTime( - 'addtime', - $today_start, - $today_end - )->sum('order_zhe_total'); + $order_zhe_total= $order_today_price+$money_today; + // $order_zhe_total = OrderModel::where('status', '=', 1)->whereNotIn('user_id', $userNotArray) + // ->whereBetweenTime( + // 'addtime', + // $today_start, + // $today_end + // )->sum('order_zhe_total'); //今日消费 $consume_order_count = OrderModel::where('status', '=', 1)->whereNotIn('user_id', $userNotArray) ->whereBetweenTime( diff --git a/app/common.php b/app/common.php index c8c9329..eeb6e89 100755 --- a/app/common.php +++ b/app/common.php @@ -281,10 +281,10 @@ if (!function_exists('create_order_no')) { // 在MH_后面添加商户前缀,而不是替换MH_ $pre = 'MH_' . $merchant_prefix; } - + // 获取当前域名的微信小程序配置 $miniprogramConfig = \app\common\helper\MiniprogramHelper::getMiniprogramConfig(); - + // 如果小程序配置存在且有订单前缀,则添加到订单号中 if (!empty($miniprogramConfig) && !empty($miniprogramConfig['order_prefix'])) { // 在现有前缀后面添加小程序订单前缀 @@ -788,4 +788,14 @@ function getData($url, $header) curl_close($ch); return $handles; +} +if (!function_exists('removeTrailingZeros')) { + function removeTrailingZeros($numStr) + { + if (strpos($numStr, '.') !== false) { + $numStr = rtrim($numStr, '0'); // 移除右侧的零 + $numStr = rtrim($numStr, '.'); // 处理小数点后全零的情况 + } + return $numStr; + } } \ No newline at end of file diff --git a/app/common/model/UserLoginLog.php b/app/common/model/UserLoginLog.php index b097e73..5590360 100755 --- a/app/common/model/UserLoginLog.php +++ b/app/common/model/UserLoginLog.php @@ -42,7 +42,7 @@ class UserLoginLog extends Model // 如果今天已记录,则不再记录 if ($exist) { - return true; + return false; } // 添加登录记录 diff --git a/config/menu.php b/config/menu.php index da5f2fb..ce479ae 100755 --- a/config/menu.php +++ b/config/menu.php @@ -16,10 +16,10 @@ return [ 'url' => '/admin/record', 'name' => '流水排行', ], - [ - 'url' => '/admin/vip', - 'name' => 'VIP管理', - ], + // [ + // 'url' => '/admin/vip', + // 'name' => 'VIP管理', + // ], [ 'url' => '/admin/user_invite', 'name' => '用户邀请列表', @@ -99,10 +99,10 @@ return [ 'url' => '/admin/ProfitRvenue', 'name' => '其它收入', ], - [ - 'url' => '/admin/user_statistics', - 'name' => '数据统计', - ], + // [ + // 'url' => '/admin/user_statistics', + // 'name' => '数据统计', + // ], ], ], [ diff --git a/public/storage/poster/share/21549.png b/public/storage/poster/share/21549.png new file mode 100644 index 0000000000000000000000000000000000000000..930d4fc02b247da0576bedda6768579b09648f88 GIT binary patch literal 16939 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 opz$m%#D<`i!`rRK(>s3oY