Index.php 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878
  1. <?php
  2. namespace app\api\controller;
  3. use app\api\model\Banner;
  4. use app\api\model\Category;
  5. use app\api\model\CoinRecord;
  6. use app\api\model\Detail;
  7. use app\api\model\Goods;
  8. use app\api\model\MoneyRecord;
  9. use app\api\model\Order;
  10. use app\api\model\PriceRange;
  11. use app\api\model\Prizerecord;
  12. use app\api\model\RechargeList;
  13. use app\api\model\RechargeOrder;
  14. use app\api\model\SearchHistory;
  15. use app\api\model\Setting;
  16. use app\api\model\Box;
  17. use app\api\model\Star;
  18. use app\api\model\Text;
  19. use app\common\controller\Api;
  20. use think\Db;
  21. use think\db\exception\DataNotFoundException;
  22. use think\db\exception\ModelNotFoundException;
  23. use think\Exception;
  24. use think\exception\DbException;
  25. use app\api\library\Retail;
  26. use think\Validate;
  27. /**
  28. * 首页接口
  29. */
  30. class Index extends Api
  31. {
  32. protected $noNeedLogin = ['baseInfo', 'newestOpen', 'hotBox', 'cheapBox', 'recommend', 'categoryList',
  33. 'boxList', 'boxListByCategory', 'boxDetail', 'boxOpenRecord', 'tryBoxDetail', 'priceRange', 'rechargeList', 'getServiceInfo',
  34. 'getWechatLoginUrl', "getVirData", "sumUv", "getServiceurl", "lunbobox", 'boximages'];
  35. protected $noNeedRight = ['*'];
  36. protected $lockUserId = ['coinPay'];
  37. public function sumUv()
  38. {
  39. $ip = request()->ip();
  40. $check = db("uv")->where(['ip' => $ip])->whereTime("createtime", "today")->find();
  41. if (empty($check)) {
  42. db("uv")->insert(['ip' => $ip, "createtime" => time()]);
  43. }
  44. $this->success("记录成功");
  45. }
  46. /**
  47. *获取开盒假数据
  48. */
  49. public function getVirData()
  50. {
  51. $page = request()->param("page") ?? 1;
  52. $limit = request()->param("limit") ?? 10;
  53. $domain = request()->domain();
  54. $list = db("virtuial")->alias("a")->join("goods b", "b.id = a.goods_id")->order("a.add_time desc")->field("a.*,FROM_UNIXTIME(a.add_time,'%Y-%m-%d %H:%i') createtime,b.goods_name, b.image,b.coin_price price")->page($page, $limit)->select();
  55. foreach ($list as $k => $v) {
  56. $list[$k]['avatar'] = $domain . $v['avatar'];
  57. //$list[$k]['image'] = $domain.$v['image'];
  58. $list[$k]['image'] = $v['image'];
  59. }
  60. $total = db("virtuial")->order("add_time desc")->count();
  61. // print_r($list);die;
  62. $this->success("获取成功", ["list" => $list, "total" => $total]);
  63. }
  64. public function lunbobox()
  65. {
  66. $status = 1;
  67. $pagesize = input('pagesize/d', 10);
  68. $page = input('page/d', 1);
  69. $statusList = [1 => 'bag', 2 => 'exchange'];
  70. if (!isset($statusList[$status])) {
  71. $this->error('状态有误');
  72. }
  73. $status = $statusList[$status];
  74. $order = 'prize.id desc';
  75. if ('exchange' == $status) {
  76. $order = 'exchange_time desc';
  77. }
  78. $list = Prizerecord::alias('prize')
  79. ->distinct(true)
  80. ->field('prize.goods_name,prize.goods_image')
  81. ->field('prize.box_id')
  82. ->field('user.nickname,user.avatar')
  83. ->join('user user', 'user.id = prize.user_id')
  84. ->order($order)
  85. ->limit(20)
  86. ->select();
  87. foreach ($list as &$item) {
  88. $images = explode(',', $item['goods_image']);
  89. foreach ($images as $k => $vv) {
  90. $images[$k] = cdnurl($vv, true);
  91. }
  92. $item['goods_image'] = implode(',', $images);
  93. }
  94. $this->success('查询成功', $list);
  95. }
  96. /**
  97. * 基础信息
  98. * @author fuyelk <fuyelk@fuyelk.com>
  99. */
  100. public function baseInfo()
  101. {
  102. // 查询设置
  103. $setting = Setting::get(1);
  104. // 查询轮播图
  105. $banner = Banner::where('place', 'index')->order('weigh', 'desc')->select();
  106. $bannerlist = [];
  107. foreach ($banner as $item) {
  108. $bannerlist[] = [
  109. 'type' => $item->type,
  110. 'image' => cdnurl($item->image, true),
  111. 'value' => $item->value
  112. ];
  113. }
  114. $ret = [
  115. 'logo' => cdnurl($setting->logo_image, true), // 首页LOGO
  116. 'banner' => $bannerlist
  117. ];
  118. $this->success('查询成功', $ret);
  119. }
  120. public function sList()
  121. {
  122. $status = input('status/d');
  123. $pagesize = input('pagesize/d', 10);
  124. $page = input('page/d', 1);
  125. $statusList = [1 => 'bag', 2 => 'exchange'];
  126. if (!isset($statusList[$status])) {
  127. $this->error('状态有误');
  128. }
  129. $status = $statusList[$status];
  130. $order = 'prize.id desc';
  131. if ('exchange' == $status) {
  132. $order = 'exchange_time desc';
  133. }
  134. $order = Db::table('box_shai')->where('switch', '1')->order('create_time', 'desc')->limit(($page - 1) * $pagesize, $pagesize)->select();
  135. $list2 = array(
  136. 'id' => 1,
  137. 'stx' => 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic3.zhimg.com%2F50%2Fv2-6f1c492cbdfe3c24aae44e935a796d5a_hd.jpg&refer=http%3A%2F%2Fpic3.zhimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1632275904&t=20baefb74a9f7b152b601ec58726f1e7',
  138. 'smc' => '这个是名称',
  139. 'ssj' => '前天',
  140. 'szw' => '这个盲盒很好玩,我很喜欢,我也介绍了很多人过来完',
  141. 'simg' => array(
  142. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  143. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  144. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  145. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  146. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  147. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  148. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  149. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  150. 'https://img.alicdn.com/imgextra/i4/0/O1CN01CHW9ak1RdPu9Vg1r6_!!0-rate.jpg_400x400.jpg',
  151. )
  152. );
  153. /* ->each(function ($item) use ($status) {
  154. $item->goods_image = $item->goods_image ? cdnurl($item->goods_image, true) : '';
  155. $item->box_coin_price = intval($item->box_coin_price);
  156. $item->box_rmb_price = floatval($item->box_rmb_price);
  157. if ('exchange' == $status) {
  158. $item->time = date('Y-m-d H:i:s', $item->exchange_time);
  159. } else {
  160. $item->time = date('Y-m-d H:i:s', $item->create_time);
  161. }
  162. $item->hidden(['create_time', 'exchange_time']);
  163. });
  164. */
  165. //print_r($list);
  166. //exit;
  167. $ym = 'https://' . $_SERVER['HTTP_HOST'];
  168. foreach ($order as $k => $v) {
  169. // $order[$k]['box_tx']=$ym.$v['box_tx'];
  170. $order[$k]['box_img'] = explode(',', $v['box_img']);
  171. // foreach ($order[$k]['box_img'] as $k2=>$v2){
  172. // $order[$k]['box_img'][$k2]=$ym.$v2;
  173. // }
  174. if (time() - $v['create_time'] < 60 * 60) {
  175. $t = round((time() - $v['create_time']) / 60);
  176. if ($t == 0) {
  177. $t = 1;
  178. }
  179. $order[$k]['box_sj'] = $t . '分钟前';
  180. } else if (time() - $v['create_time'] > 60 * 60 && time() - $v['create_time'] < 60 * 60 * 24) {
  181. $t = round((time() - $v['create_time']) / 60 / 60);
  182. $order[$k]['box_sj'] = $t . '小时前';
  183. } else if (time() - $v['create_time'] > 60 * 60 * 24 && time() - $v['create_time'] < 60 * 60 * 24 * 7) {
  184. $t = round((time() - $v['create_time']) / 60 / 60 / 24);
  185. $order[$k]['box_sj'] = $t . '天前';
  186. } else if (time() - $v['create_time'] > 60 * 60 * 24 * 7) {
  187. $t = round((time() - $v['create_time']) / 60 / 60 / 24 / 7);
  188. $order[$k]['box_sj'] = $t . '周前';
  189. }
  190. }
  191. //print_r($order);
  192. $list = array(
  193. 'data' => $order
  194. );
  195. //$list=$order;
  196. foreach ($list as $k => $v) {
  197. // print_r($v);
  198. }
  199. $this->success('查询成功', $list);
  200. }
  201. /**
  202. * 最新开箱的盲盒列表
  203. * @author fuyelk <fuyelk@fuyelk.com>
  204. */
  205. public function newestOpen()
  206. {
  207. // 查询数量
  208. $limit = 5;
  209. // 查询用户最新购买的100个盲盒ID
  210. $boxIds = Order::field('box_id')->order('id', 'desc')->limit(100)->column('box_id');
  211. //Array ( [0] => 36 [1] => 37 [2] => 38 [3] => 39 [4] => 40 [5] => 36 [6] => 36 [7] => 36 [8] => 36 [9] => 41 [10] => 39 [11] => 39 [12] => 36 [13] => 37 [14] => 41 [15] => 41 )
  212. $boxIds = array_unique($boxIds);
  213. $boxAdd = [];
  214. // 新开箱不足5个,则按盲盒上架顺序补齐
  215. if (count($boxIds) < $limit) {
  216. $boxAdd = Box::whereNotIn('id', $boxIds)->order('update_time', 'desc')->limit($limit - count($boxIds))->column('id');
  217. }
  218. //Array ( [0] => 36 [1] => 37 [2] => 38 [3] => 39 [4] => 40 [5] => 41 )
  219. $boxIds = array_merge($boxIds, $boxAdd);
  220. // 查询空盲盒
  221. $existboxid = Detail::field('box_id')->distinct(true)->buildSql();
  222. $emptyBoxIds = Box::where('id', 'exp', 'not in ' . $existboxid)->column('id');
  223. $list = Box::alias('box')
  224. ->field('id box_id,box_name,coin_price,box_banner_images')
  225. ->whereNotIn('id', $emptyBoxIds)
  226. ->whereIn('id', $boxIds)
  227. ->order('id', 'desc')
  228. ->select();
  229. //print_r($list);die;
  230. foreach ($list as $item) {
  231. // 查询前5个商品图片
  232. $firstGoods = Detail::where('box_id', $item->box_id)->order('weigh', 'desc')->limit(4)->column('goods_id');
  233. $goods_images = Goods::whereIn('id', $firstGoods)->column('image');
  234. foreach ($goods_images as &$image) {
  235. $image = cdnurl($image, true);
  236. }
  237. // 查询最低价
  238. $allGoods = Detail::where('box_id', $item->box_id)->column('goods_id');
  239. $item->goods_num = count($allGoods);
  240. $min_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'asc')->value('coin_price');
  241. $item->price_min = round(Setting::getRmbFromCoin($min_coin_price ?: 0), 2);
  242. $max_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'desc')->value('coin_price');
  243. $item->price_max = round(Setting::getRmbFromCoin($max_coin_price ?: 0), 2);
  244. $item->goods_images = $goods_images;
  245. }
  246. //print_r($list);die;
  247. $this->success('查询成功', $list);
  248. }
  249. public function boximages()
  250. {
  251. $box_id = input('box_id');
  252. $tagName = [
  253. 'normal' => '普通',
  254. 'rare' => '稀有',
  255. 'supreme' => '史诗',
  256. 'legend' => '传说',
  257. ];
  258. // $firstGoods = db('box_detail')->where('box_id', 49)->find();
  259. // 查询商品id及概率
  260. $detail = db('box_detail')->where('box_id', $box_id)->order('weigh', 'desc')->column('goods_id');
  261. // 查询全部商品
  262. $moreGoods = db('goods')->field('image')
  263. ->where('status', 'online')
  264. ->whereIn('id', $detail)
  265. ->select();
  266. $ret = [
  267. 'goodsimagelist' => $moreGoods,
  268. ];
  269. $this->success('查询成功', $ret);
  270. }
  271. /**
  272. * 热门盲盒
  273. * @author fuyelk <fuyelk@fuyelk.com>
  274. */
  275. public function hotBox()
  276. {
  277. $pagesize = input('pagesize/d', 10);
  278. $page = input('page/d', 1);
  279. // 查询空盲盒
  280. $existboxid = Detail::field('box_id')->distinct(true)->buildSql();
  281. $emptyBoxIds = Box::where('id', 'exp', 'not in ' . $existboxid)->column('id');
  282. $list = Box::alias('box')
  283. ->field('id box_id,box_name,coin_price')
  284. ->where('is_hot', 1)
  285. ->whereNotIn('box.id', $emptyBoxIds)
  286. ->order('box.id', 'desc')
  287. ->paginate($pagesize, false, ['page' => $page])
  288. ->each(function ($item) {
  289. // 查询前6个商品图片
  290. $firstGoods = Detail::where('box_id', $item->box_id)->order('weigh', 'desc')->limit(6)->column('goods_id');
  291. $goods_images = Goods::whereIn('id', $firstGoods)->column('image');
  292. foreach ($goods_images as &$image) {
  293. $image = cdnurl($image, true);
  294. }
  295. // 查询最低价
  296. $allGoods = Detail::where('box_id', $item->box_id)->column('goods_id');
  297. $item->goods_num = count($allGoods);
  298. $min_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'asc')->value('coin_price');
  299. $item->price_min = round(Setting::getRmbFromCoin($min_coin_price ?: 0), 2);
  300. $max_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'desc')->value('coin_price');
  301. $item->price_max = round(Setting::getRmbFromCoin($max_coin_price ?: 0), 2);
  302. $item->goods_images = $goods_images;
  303. });
  304. $ret = [
  305. 'banner' => cdnurl(Setting::getSetting('hot_box_banner'), true),
  306. 'list' => $list
  307. ];
  308. $this->success('查询成功', $ret);
  309. }
  310. /**
  311. * 低价盲盒
  312. * @author fuyelk <fuyelk@fuyelk.com>
  313. */
  314. public function cheapBox()
  315. {
  316. $pagesize = input('pagesize/d', 10);
  317. $page = input('page/d', 1);
  318. // 查询空盲盒
  319. $existboxid = Detail::field('box_id')->distinct(true)->buildSql();
  320. $emptyBoxIds = Box::where('id', 'exp', 'not in ' . $existboxid)->column('id');
  321. $list = Box::alias('box')
  322. ->field('id box_id,box_name,coin_price')
  323. ->where('is_cheap', 1)
  324. ->whereNotIn('box.id', $emptyBoxIds)
  325. ->order('box.id', 'desc')
  326. ->paginate($pagesize, false, ['page' => $page])
  327. ->each(function ($item) {
  328. // 查询前6个商品图片
  329. $firstGoods = Detail::where('box_id', $item->box_id)->order('weigh', 'desc')->limit(6)->column('goods_id');
  330. $goods_images = Goods::whereIn('id', $firstGoods)->column('image');
  331. foreach ($goods_images as &$image) {
  332. $image = cdnurl($image, true);
  333. }
  334. // 查询最低价
  335. $allGoods = Detail::where('box_id', $item->box_id)->column('goods_id');
  336. $item->goods_num = count($allGoods);
  337. $min_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'asc')->value('coin_price');
  338. $item->price_min = round(Setting::getRmbFromCoin($min_coin_price ?: 0), 2);
  339. $max_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'desc')->value('coin_price');
  340. $item->price_max = round(Setting::getRmbFromCoin($max_coin_price ?: 0), 2);
  341. $item->goods_images = $goods_images;
  342. });
  343. $ret = [
  344. 'banner' => cdnurl(Setting::getSetting('cheap_box_banner'), true),
  345. 'list' => $list
  346. ];
  347. $this->success('查询成功', $ret);
  348. }
  349. /**
  350. * 推荐盲盒
  351. * @throws \think\Exception
  352. * @throws \think\db\exception\DataNotFoundException
  353. * @throws \think\db\exception\ModelNotFoundException
  354. * @throws \think\exception\DbException
  355. * @author fuyelk <fuyelk@fuyelk.com>
  356. */
  357. public function recommend()
  358. {
  359. $pagesize = input('pagesize/d', 10);
  360. $page = input('page/d', 1);
  361. // 查询空盲盒
  362. $existboxid = Detail::field('box_id')->distinct(true)->buildSql();
  363. $emptyBoxIds = Box::where('id', 'exp', 'not in ' . $existboxid)->column('id');
  364. $list = Box::alias('box')
  365. ->field('id box_id,box_name,coin_price,box_banner_images,box_foot_images')
  366. ->whereNotIn('id', $emptyBoxIds)
  367. ->order('sort', 'asc')
  368. ->where("switch", 1)
  369. ->paginate($pagesize, false, ['page' => $page])
  370. ->each(function ($item) {
  371. // 查询前6个商品图片
  372. // $firstGoods = Detail::where('box_id', $item->box_id)->order('weigh', 'desc')->limit(6)->column('goods_id');
  373. // $goods_images = Goods::whereIn('id', $firstGoods)->column('image');
  374. $goods_images = Detail::alias('a')->join("goods b", "b.id = a.goods_id")->where('a.box_id', $item->box_id)->order('a.weigh', 'desc')->limit(6)->column('b.image');
  375. foreach ($goods_images as &$image) {
  376. $image = cdnurl($image, true);
  377. }
  378. // 查询最低价
  379. $allGoods = Detail::where('box_id', $item->box_id)->column('goods_id');
  380. $item->goods_num = count($allGoods);
  381. $min_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'asc')->value('coin_price');
  382. $item->price_min = round(Setting::getRmbFromCoin($min_coin_price ?: 0), 2);
  383. $max_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'desc')->value('coin_price');
  384. $item->price_max = round(Setting::getRmbFromCoin($max_coin_price ?: 0), 2);
  385. $item->goods_images = $goods_images;
  386. $box_banner_images = explode(',', $item->box_banner_images);
  387. foreach ($box_banner_images as &$v) {
  388. $v = cdnurl($v, true);
  389. }
  390. $item->box_banner_images = implode(',', $box_banner_images);
  391. $box_foot_images = explode(',', $item->box_foot_images);
  392. foreach ($box_foot_images as &$v) {
  393. $v = cdnurl($v, true);
  394. }
  395. $item->box_foot_images = implode(',', $box_foot_images);
  396. });
  397. $this->success('查询成功', $list);
  398. }
  399. /**
  400. * 分类列表
  401. * @author fuyelk <fuyelk@fuyelk.com>
  402. */
  403. public function categoryList()
  404. {
  405. $list = Category::field('id category_id,name')->order('weigh', 'desc')->select();
  406. $this->success('查询成功', $list);
  407. }
  408. /**
  409. * 盲盒列表
  410. * @throws \think\exception\DbException
  411. * @author fuyelk <fuyelk@fuyelk.com>
  412. */
  413. public function boxListByCategory()
  414. {
  415. $pagesize = input('pagesize/d', 10);
  416. $page = input('page/d', 1);
  417. $category_id = input('category_id/d');
  418. $search = input('search', '');
  419. $sort = input('sort', '');
  420. $price = input('price', '');
  421. // 构建筛选条件
  422. $wherePrice = [];
  423. if ($price) {
  424. list($price_low, $price_heigh) = array_slice(explode('-', $price), 0, 2);
  425. if (!is_numeric($price_low) || !is_numeric($price_heigh)) {
  426. $this->error('价格筛选有误');
  427. }
  428. $wherePrice = ['coin_price' => ['between', [$price_low, $price_heigh]]];
  429. }
  430. // 构建排序条件
  431. $order = "";
  432. switch ($sort) {
  433. case '':
  434. $order = "id desc";
  435. break;
  436. case 'new':
  437. $order = "id desc";
  438. break;
  439. case 'combine_desc':
  440. $order = "sales desc";
  441. break;
  442. case 'combine_asc':
  443. $order = "sales asc";
  444. break;
  445. case 'price_desc':
  446. $order = "coin_price desc";
  447. break;
  448. case 'price_asc':
  449. $order = "coin_price asc";
  450. break;
  451. default:
  452. $this->error('排序方式有误');
  453. break;
  454. }
  455. if (empty($category_id) && empty($search)) {
  456. $this->error('查询条件有误');
  457. }
  458. $whereCategory = [];
  459. if (!empty($category_id)) {
  460. $whereCategory = ['category_id' => $category_id];
  461. }
  462. $whereSearch = [];
  463. if (!empty($search)) {
  464. // 过滤非法字符
  465. $search = preg_replace("/[!@#$%^&*=\-+_\[\]{};':\"\/<>?]+/", '', $search);
  466. // 创建搜索记录
  467. if ($this->auth->isLogin()) {
  468. if (!SearchHistory::where(['user_id' => $this->auth->id, 'search' => $search])->value('id')) {
  469. SearchHistory::create(['user_id' => $this->auth->id, 'search' => $search]);
  470. }
  471. }
  472. $whereSearch = "box_name like '%{$search}%'";
  473. }
  474. // 查询空盲盒
  475. $existboxid = Detail::field('box_id')->distinct(true)->buildSql();
  476. $emptyBoxIds = Box::where('id', 'exp', 'not in ' . $existboxid)->column('id');
  477. $list = Box::field('id box_id,box_name,coin_price,box_banner_images')
  478. ->order($order)
  479. ->whereNotIn('id', $emptyBoxIds)
  480. ->where($wherePrice)
  481. ->where($whereCategory)
  482. ->where($whereSearch)
  483. ->paginate($pagesize, false, ['page' => $page])
  484. ->each(function ($item) {
  485. // 查询第一张图片
  486. $goodsid = Detail::order('weigh', 'desc')->where('box_id', $item->box_id)->value('goods_id');
  487. $item->image = '';
  488. if ($goodsid) {
  489. $image = Goods::where('id', $goodsid)->value('image');
  490. $item->image = $image ? cdnurl($image, true) : '';
  491. }
  492. });
  493. $this->success('查询成功', $list);
  494. }
  495. /**
  496. * 搜索
  497. * @throws DbException
  498. * @author fuyelk <fuyelk@fuyelk.com>
  499. */
  500. public function search()
  501. {
  502. $pagesize = input('pagesize/d', 10);
  503. $page = input('page/d', 1);
  504. $category_id = input('category_id/d');
  505. $search = input('search', '');
  506. $sort = input('sort', '');
  507. $price = input('price', '');
  508. // 构建筛选条件
  509. $wherePrice = [];
  510. if ($price) {
  511. list($price_low, $price_heigh) = array_slice(explode('-', $price), 0, 2);
  512. if (!is_numeric($price_low) || !is_numeric($price_heigh)) {
  513. $this->error('价格筛选有误');
  514. }
  515. $wherePrice = ['coin_price' => ['between', [$price_low, $price_heigh]]];
  516. }
  517. // 构建排序条件
  518. $order = "";
  519. switch ($sort) {
  520. case '':
  521. $order = "id desc";
  522. break;
  523. case 'new':
  524. $order = "id desc";
  525. break;
  526. case 'combine_desc':
  527. $order = "sales desc";
  528. break;
  529. case 'combine_asc':
  530. $order = "sales asc";
  531. break;
  532. case 'price_desc':
  533. $order = "coin_price desc";
  534. break;
  535. case 'price_asc':
  536. $order = "coin_price asc";
  537. break;
  538. default:
  539. $this->error('排序方式有误');
  540. break;
  541. }
  542. $whereCategory = [];
  543. if (!empty($category_id)) {
  544. $whereCategory = ['category_id' => $category_id];
  545. }
  546. $whereSearch = [];
  547. if (!empty($search)) {
  548. // 过滤非法字符
  549. $search = preg_replace("/[!@#$%^&*=\-+_\[\]{};':\"\/<>?]+/", '', trim($search));
  550. if (!empty($search)) {
  551. // 创建搜索记录
  552. if ($this->auth->isLogin()) {
  553. if (!SearchHistory::where(['user_id' => $this->auth->id, 'search' => $search])->value('id')) {
  554. SearchHistory::create(['user_id' => $this->auth->id, 'search' => $search]);
  555. }
  556. }
  557. // 构建商品ID搜索
  558. $condition_goods_ids = Goods::field('id')->where('status', 'online')->where("goods_name like '%{$search}%'")->buildSql();
  559. // 构建商品、盲盒绑定
  560. $condition_box_detail = Detail::field('box_id')->where("goods_id in {$condition_goods_ids}")->buildSql();
  561. $whereSearch = "box_name like '%{$search}%' or id in $condition_box_detail";
  562. }
  563. }
  564. // 查询空盲盒
  565. $existboxid = Detail::field('box_id')->distinct(true)->buildSql();
  566. $emptyBoxIds = Box::where('id', 'exp', 'not in ' . $existboxid)->column('id');
  567. $list = Box::alias('box')
  568. ->field('id box_id,box_name,coin_price,box_banner_images')
  569. ->whereNotIn('id', $emptyBoxIds)
  570. ->where($wherePrice)
  571. ->where($whereCategory)
  572. ->where($whereSearch)
  573. ->where(['switch' => 1])
  574. ->order($order)
  575. ->paginate($pagesize, false, ['page' => $page])
  576. ->each(function ($item) {
  577. // 查询前6个商品图片
  578. $firstGoods = Detail::where('box_id', $item->box_id)->order('weigh', 'desc')->limit(6)->column('goods_id');
  579. $goods_images = Goods::whereIn('id', $firstGoods)->column('image');
  580. foreach ($goods_images as &$image) {
  581. $image = cdnurl($image, true);
  582. }
  583. // 查询最低价
  584. $allGoods = Detail::where('box_id', $item->box_id)->column('goods_id');
  585. $item->goods_num = count($allGoods);
  586. $min_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'asc')->value('coin_price');
  587. $item->price_min = round(Setting::getRmbFromCoin($min_coin_price ?: 0), 2);
  588. $max_coin_price = Goods::whereIn('id', $allGoods)->order('coin_price', 'desc')->value('coin_price');
  589. $item->price_max = round(Setting::getRmbFromCoin($max_coin_price ?: 0), 2);
  590. $item->goods_images = $goods_images;
  591. });
  592. $this->success('查询成功', $list);
  593. }
  594. /**
  595. * 盲盒详情
  596. * @throws \think\db\exception\DataNotFoundException
  597. * @throws \think\db\exception\ModelNotFoundException
  598. * @throws \think\exception\DbException
  599. * @author fuyelk <fuyelk@fuyelk.com>
  600. */
  601. public function boxDetail()
  602. {
  603. $box_id = input('box_id/d');
  604. if (empty($box_id)) {
  605. $this->error('请选择盲盒');
  606. }
  607. // 查询金币余额
  608. $mycoin = $this->auth->isLogin() ? $this->auth->coin : 0;
  609. // 查询是否收藏
  610. $is_star = $this->auth->isLogin() ? Star::check($this->auth->id, $box_id) : 0;
  611. // 查询盲盒基础信息
  612. $box = Box::field('box_banner_images,box_banner_images_desc,box_name,coin_price,box_banner_images')->where('id', $box_id)->find();
  613. if (empty($box)) {
  614. $this->error('盲盒有误');
  615. }
  616. $tagName = [
  617. 'normal' => '普通',
  618. 'rare' => '稀有',
  619. 'supreme' => '史诗',
  620. 'legend' => '传说',
  621. ];
  622. // 查询商品id及概率
  623. $detail = Detail::where('box_id', $box_id)->order('weigh desc')->column('rate', 'goods_id');
  624. // // 查询前6个商品
  625. // $firstGoods = Goods::field('image,coin_price,goods_name,tag')
  626. // ->where('status', 'online')
  627. // ->whereIn('id', array_slice(array_keys($detail), 0, 1000))
  628. // ->select();
  629. $firstGoods = Detail::alias("a")->join("goods b", "b.id = a.goods_id")->where('a.box_id', $box_id)->field("b.image,b.xiangqing,b.coin_price,b.goods_name,b.tag")->order("a.weigh desc")->select();
  630. foreach ($firstGoods as &$first) {
  631. $first->image = $first->image ? cdnurl($first->image, true) : $first->image;
  632. $first->tag = $tagName[$first->tag];
  633. // $first->price = round(Setting::getRmbFromCoin($first->coin_price ?: 0), 2);
  634. $first->price = $first->coin_price;
  635. if (!empty($first->xiangqing)) {
  636. if (strstr($first['xiangqing'], ',')) {
  637. $first['xiangqing'] = explode(',', $first['xiangqing']);
  638. // var_dump($first);
  639. // exit();
  640. }
  641. }
  642. $first->hidden(['coin_price']);
  643. }
  644. // var_dump($first);exit();
  645. // 查询全部商品
  646. $moreGoods = Goods::field('id,image,xiangqing,coin_price,goods_name,tag')
  647. ->where('status', 'online')
  648. ->whereIn('id', array_keys($detail))
  649. ->select();
  650. // 整理商品信息并记录每个类别的概率总合
  651. $rateList = [];
  652. foreach ($moreGoods as &$more) {
  653. if (isset($rateList[$more->tag])) {
  654. $rateList[$more->tag] += $detail[$more->id];
  655. } else {
  656. $rateList[$more->tag] = $detail[$more->id];
  657. }
  658. $more->image = $more->image ? cdnurl($more->image, true) : $more->image;
  659. $more->tag = $tagName[$more->tag];
  660. $more->price = round(Setting::getRmbFromCoin($more->coin_price ?: 0), 2);
  661. if (strstr($more->xiangqing, ',')) {
  662. $more->xiangqing = explode(',', $more->xiangqing);
  663. }
  664. $more->hidden(['id,coin_price']);
  665. }
  666. $tags = [
  667. 'normal' => 0,
  668. 'rare' => 0,
  669. 'supreme' => 0,
  670. 'legend' => 0
  671. ];
  672. // 没有的商品概率设为0
  673. foreach ($tags as $tag => &$rate) {
  674. if (isset($rateList[$tag])) {
  675. $rate = $rateList[$tag];
  676. }
  677. }
  678. // 计算全部类别概率总和
  679. $rate_sum = array_sum(array_values($tags));
  680. // 计算每个类别概率
  681. foreach ($tags as $tag => &$rate) {
  682. $rate = $rate_sum ? (round($rate / $rate_sum, 4) * 100) : 0 . '%';
  683. }
  684. // 查询该盲盒开箱记录
  685. $prize = Prizerecord::alias('prize')
  686. ->field('prize.goods_name,prize.goods_image,prize.goods_rmb_price,prize.create_time')
  687. ->field('user.nickname,user.avatar')
  688. ->join('user user', 'user.id = prize.user_id')
  689. ->where('prize.box_id', $box_id)
  690. ->order('prize.id', 'desc')
  691. ->limit(10)
  692. ->select();
  693. foreach ($prize as $prize_item) {
  694. $prize_item->create_time = date('Y-m-d H:i:s', $prize_item->create_time);
  695. $prize_item->avatar = $prize_item->avatar ? cdnurl($prize_item->avatar, true) : letter_avatar($prize_item->nickname);
  696. $prize_item->goods_image = $prize_item->goods_image ? cdnurl($prize_item->goods_image, true) : '';
  697. }
  698. $box_banner_images = [];
  699. $box_banner = [];
  700. $box->box_banner_images = explode(',', $box->box_banner_images);
  701. $banner_desc = $box->box_banner_images_desc;
  702. $banner_desc = $banner_desc ? json_decode($banner_desc, true) : [];
  703. foreach ($box->box_banner_images as $index => $image) {
  704. $image = $image ? cdnurl($image, true) : '';
  705. $box_banner_images[] = $image;
  706. $box_banner[] = [
  707. 'desc' => $banner_desc[$index] ?? '',
  708. 'image' => $image
  709. ];
  710. }
  711. $ret = [
  712. 'mycoin' => $mycoin,
  713. 'is_star' => $is_star,
  714. 'box_banner_images' => $box_banner_images,
  715. 'box_banner' => $box_banner,
  716. 'box_name' => $box->box_name,
  717. 'coin_price' => intval($box->coin_price),
  718. 'goodslist' => $firstGoods,
  719. 'more' => [
  720. 'goodslist' => $moreGoods,
  721. 'tags' => $tags
  722. ],
  723. 'record' => $prize
  724. ];
  725. $this->success('查询成功', $ret);
  726. }
  727. /**
  728. * 查询更多盲盒开箱记录
  729. * @throws DbException
  730. * @author fuyelk <fuyelk@fuyelk.com>
  731. */
  732. public function boxOpenRecord()
  733. {
  734. $box_id = input('box_id/d');
  735. $pagesize = input('pagesize/d', 10);
  736. $page = input('page/d', 1);
  737. if (empty($box_id)) {
  738. $this->error('请选择盲盒');
  739. }
  740. // 查询该盲盒开箱记录
  741. $record = Prizerecord::alias('prize')
  742. ->field('prize.goods_name,prize.goods_image,prize.goods_rmb_price,prize.create_time')
  743. ->field('user.nickname,user.avatar')
  744. ->join('user user', 'user.id = prize.user_id')
  745. ->where('prize.box_id', $box_id)
  746. ->order('prize.id', 'desc')
  747. ->paginate($pagesize, false, ['page' => $page])
  748. ->each(function ($item) {
  749. $item->create_time = date('Y-m-d H:i:s', $item->create_time);
  750. $item->avatar = $item->avatar ? cdnurl($item->avatar, true) : letter_avatar($item->nickname);
  751. $item->goods_image = $item->goods_image ? cdnurl($item->goods_image, true) : '';
  752. });
  753. $this->success('查询成功', $record);
  754. }
  755. /**
  756. * 试一试盲盒详情
  757. * @throws \think\db\exception\DataNotFoundException
  758. * @throws \think\db\exception\ModelNotFoundException
  759. * @throws \think\exception\DbException
  760. * @author fuyelk <fuyelk@fuyelk.com>
  761. */
  762. public function tryBoxDetail()
  763. {
  764. // 查询试一试盲盒
  765. $box_id = Box::where('is_try', 1)->value('id');
  766. // 查询金币余额
  767. $mycoin = $this->auth->isLogin() ? $this->auth->coin : 0;
  768. // 查询是否收藏
  769. $is_star = $this->auth->isLogin() ? Star::check($this->auth->id, $box_id) : 0;
  770. // 查询盲盒基础信息
  771. $box = Box::field('box_banner_images,box_name,coin_price')->where('id', $box_id)->find();
  772. if (empty($box)) {
  773. $this->error('盲盒有误');
  774. }
  775. $tagName = [
  776. 'normal' => '普通',
  777. 'rare' => '稀有',
  778. 'supreme' => '史诗',
  779. 'legend' => '传说',
  780. ];
  781. // 查询商品id及概率
  782. $detail = Detail::where('box_id', $box_id)->order('weigh', 'desc')->column('rate', 'goods_id');
  783. // 查询前6个商品
  784. $firstGoods = Goods::field('image,coin_price,goods_name,tag')
  785. ->where('status', 'online')
  786. ->whereIn('id', array_slice(array_keys($detail), 0, 6))
  787. ->select();
  788. foreach ($firstGoods as &$first) {
  789. $first->image = $first->image ? cdnurl($first->image, true) : $first->image;
  790. $first->tag = $tagName[$first->tag];
  791. $first->price = round(Setting::getRmbFromCoin($first->coin_price ?: 0), 2);
  792. $first->hidden(['coin_price']);
  793. }
  794. // 查询全部商品
  795. $moreGoods = Goods::field('id,image,coin_price,goods_name,tag')
  796. ->where('status', 'online')
  797. ->whereIn('id', array_keys($detail))
  798. ->select();
  799. // 整理商品信息并记录每个类别的概率总合
  800. $rateList = [];
  801. foreach ($moreGoods as &$more) {
  802. if (isset($rateList[$more->tag])) {
  803. $rateList[$more->tag] += $detail[$more->id];
  804. } else {
  805. $rateList[$more->tag] = $detail[$more->id];
  806. }
  807. $more->image = $more->image ? cdnurl($more->image, true) : $more->image;
  808. $more->tag = $tagName[$more->tag];
  809. $more->price = round(Setting::getRmbFromCoin($more->coin_price ?: 0), 2);
  810. $more->hidden(['id,coin_price']);
  811. }
  812. $tags = [
  813. 'normal' => 0,
  814. 'rare' => 0,
  815. 'supreme' => 0,
  816. 'legend' => 0
  817. ];
  818. // 没有的商品概率设为0
  819. foreach ($tags as $tag => &$rate) {
  820. if (isset($rateList[$tag])) {
  821. $rate = $rateList[$tag];
  822. }
  823. }
  824. // 计算全部类别概率总和
  825. $rate_sum = array_sum(array_values($tags));
  826. // 计算每个类别概率
  827. foreach ($tags as $tag => &$rate) {
  828. $rate = round($rate / $rate_sum, 4) * 100 . '%';
  829. }
  830. // 查询该盲盒开箱记录
  831. $prize = Prizerecord::alias('prize')
  832. ->field('prize.goods_name,prize.goods_image,prize.goods_rmb_price,prize.create_time')
  833. ->field('user.nickname,user.avatar')
  834. ->join('user user', 'user.id = prize.user_id')
  835. ->where('prize.box_id', $box_id)
  836. ->order('prize.id', 'desc')
  837. ->limit(3)
  838. ->select();
  839. foreach ($prize as $prize_item) {
  840. $prize_item->create_time = date('Y-m-d H:i:s', $prize_item->create_time);
  841. $prize_item->avatar = $prize_item->avatar ? cdnurl($prize_item->avatar, true) : letter_avatar($prize_item->nickname);
  842. $prize_item->goods_image = $prize_item->goods_image ? cdnurl($prize_item->goods_image, true) : '';
  843. }
  844. $box_banner_images = [];
  845. $box->box_banner_images = explode(',', $box->box_banner_images);
  846. foreach ($box->box_banner_images as $box_banner_image) {
  847. $box_banner_images[] = cdnurl($box_banner_image, true);
  848. }
  849. $ret = [
  850. 'box_id' => $box_id,
  851. 'mycoin' => $mycoin,
  852. 'is_star' => $is_star,
  853. 'box_banner_images' => $box_banner_images,
  854. 'box_name' => $box->box_name,
  855. 'coin_price' => intval($box->coin_price),
  856. 'goodslist' => $firstGoods,
  857. 'more' => [
  858. 'goodslist' => $moreGoods,
  859. 'tags' => $tags
  860. ],
  861. 'record' => $prize
  862. ];
  863. $this->success('查询成功', $ret);
  864. }
  865. /**
  866. * 抽奖测试
  867. * @author fuyelk <fuyelk@fuyelk.com>
  868. */
  869. public function test()
  870. {
  871. $prize = [];
  872. $times = $index = 1000;
  873. while (--$index >= 0) {
  874. $p = Detail::getOne(1);
  875. if (isset($prize[$p])) {
  876. $prize[$p]++;
  877. } else {
  878. $prize[$p] = 1;
  879. }
  880. }
  881. foreach ($prize as $goods => &$rate) {
  882. $rate = round($rate / $times, 2) * 100;
  883. }
  884. arsort($prize);
  885. de($prize);
  886. }
  887. /**
  888. * 点赞
  889. * @author fuyelk <fuyelk@fuyelk.com>
  890. */
  891. public function star()
  892. {
  893. $box_id = input('box_id/d');
  894. try {
  895. $res = Star::click($this->auth->id, $box_id);
  896. } catch (Exception $e) {
  897. $this->error('收藏失败');
  898. }
  899. if ($res) {
  900. $this->success('收藏成功', ['is_star' => 1]);
  901. }
  902. $this->success('取消收藏成功', ['is_star' => 0]);
  903. }
  904. /**
  905. * 试玩
  906. * @throws DataNotFoundException
  907. * @throws DbException
  908. * @throws ModelNotFoundException
  909. * @author fuyelk <fuyelk@fuyelk.com>
  910. */
  911. public function haveATry()
  912. {
  913. $box_id = input('box_id/d');
  914. $num = input('num/d');
  915. $select = input('select', '随机');
  916. if (empty($box_id)) {
  917. $this->error('请选择盲盒');
  918. }
  919. if (!in_array($num, [1, 5])) {
  920. $this->error('开箱数量有误');
  921. }
  922. // 检查盲盒是否可以试玩
  923. // $box = Box::where('id', $box_id)->where('is_try', 1)->value('id');
  924. // if (empty($box)) {
  925. // $this->error('该盲盒暂时不可试玩');
  926. // }
  927. try {
  928. if (1 == $num) {
  929. $goodsIds = [Detail::getOnes($box_id)];
  930. } else {
  931. $goodsIds = Detail::getMores($box_id, $num);
  932. }
  933. } catch (\Exception $e) {
  934. $this->error($e->getMessage());
  935. }
  936. foreach ($goodsIds as $goodsId) {
  937. $goodsInfo[] = Goods::field('image,goods_name,tag')->where('id', $goodsId)->find();
  938. }
  939. if (empty($goodsInfo)) {
  940. $this->error('抽奖失败');
  941. }
  942. foreach ($goodsInfo as $item) {
  943. if ($item->image) {
  944. $item->image = cdnurl($item->image, true);
  945. }
  946. }
  947. $ret = [
  948. 'select' => $select,
  949. 'goodsInfo' => $goodsInfo
  950. ];
  951. $this->success('抽奖成功', $ret);
  952. }
  953. /**
  954. * 创建盲盒订单
  955. * @author fuyelk <fuyelk@fuyelk.com>
  956. */
  957. public function createOrder()
  958. {
  959. $box_id = input('box_id/d');
  960. $num = input('num/d');
  961. $select = input('select', '');
  962. if (empty($box_id)) {
  963. $this->error('未选择盲盒');
  964. }
  965. if (!in_array($num, [1, 5, 9])) {
  966. $this->error('选择的盲盒数量有误');
  967. }
  968. // 检查盲盒
  969. $box = Box::field('id,box_name,box_banner_images,coin_price,box_banner_images')->where('id', $box_id)->find();
  970. if (empty($box)) {
  971. $this->error('选择的盲盒有误');
  972. }
  973. // 检查盲盒奖品
  974. $prize = Detail::where('box_id', $box_id)->order('weigh desc,id asc')->value('goods_id');
  975. if (empty($prize)) {
  976. $this->error('这个盲盒太火爆吧,商品暂时缺货!');
  977. }
  978. // 查询前6个商品的图片
  979. $goodsIds = Detail::where('box_id', $box_id)->order('weigh desc,id asc')->column('goods_id');
  980. $goodsImages = Goods::where('status', 'online')
  981. ->whereIn('id', $goodsIds)
  982. ->column('image');
  983. foreach ($goodsImages as &$image) {
  984. $image = cdnurl($image, true);
  985. }
  986. Db::startTrans();
  987. try {
  988. $rmb_price = round(Setting::getRmbFromCoin($box->coin_price ?: 0), 2);
  989. $res = Order::create([
  990. 'box_id' => $box_id,
  991. 'box_name' => $box->box_name,
  992. 'image' => $goodsImages[0] ?? '',
  993. 'coin_price' => $box->coin_price,
  994. 'rmb_price' => $rmb_price,
  995. 'num' => $num,
  996. 'coin_amount' => $box->coin_price * $num,
  997. 'rmb_amount' => $rmb_price * $num,
  998. 'user_id' => $this->auth->id,
  999. 'select' => $select,
  1000. 'out_trade_no' => date('YmdHis') . mt_rand(10000, 99999)
  1001. ]);
  1002. $ret = [
  1003. 'order_id' => intval($res->id),
  1004. 'box_name' => $res->box_name,
  1005. 'images' => $goodsImages,
  1006. 'coin_amount' => $res->coin_amount,
  1007. 'rmb_amount' => $res->rmb_amount,
  1008. 'notice' => Text::getText('pay_tipstips'),
  1009. 'coin_not_enough' => !!(intval($this->auth->coin) < intval($res->coin_amount)),
  1010. 'alipay' => $this->request->domain() . '/api/alipay/boxpay/orderid/' . intval($res->id),
  1011. 'wechat' => '/api/wechat/boxpay/orderid/' . intval($res->id),
  1012. ];
  1013. } catch (Exception $e) {
  1014. Db::rollback();
  1015. $this->error('创建订单失败');
  1016. }
  1017. Db::commit();
  1018. $this->success('创建订单成功', $ret);
  1019. }
  1020. /**
  1021. * 创建充值订单
  1022. * @author fuyelk <fuyelk@fuyelk.com>
  1023. */
  1024. public function createRechargeOrder()
  1025. {
  1026. $amount = input('amount/d');
  1027. if (empty($amount)) {
  1028. $this->error('金额不能为空');
  1029. }
  1030. // 检查金额是否允许
  1031. $rmb = RechargeList::where('coin', intval($amount))->value('rmb');
  1032. if (empty($rmb)) {
  1033. $this->error('充值金额有误');
  1034. }
  1035. Db::startTrans();
  1036. try {
  1037. $res = RechargeOrder::create([
  1038. 'user_id' => $this->auth->id,
  1039. 'coin_amount' => intval($amount),
  1040. 'rmb_amount' => round($rmb, 2),
  1041. 'out_trade_no' => date('YmdHis') . mt_rand(10000, 99999)
  1042. ]);
  1043. } catch (\Exception $e) {
  1044. Db::rollback();
  1045. $this->error('创建订单出错');
  1046. }
  1047. Db::commit();
  1048. $ret = [
  1049. 'alipay' => $this->request->domain() . '/api/alipay/rechargepay/orderid/' . intval($res->id),
  1050. 'wechat' => '/api/wechat/rechargepay/orderid/' . intval($res->id),
  1051. 'eepay' => '/api/eepay/rechargepay/orderid/' . intval($res->id),
  1052. ];
  1053. $this->success('创建订单成功', $ret);
  1054. }
  1055. /**
  1056. * 创建充值订单
  1057. * @author fuyelk <fuyelk@fuyelk.com>
  1058. */
  1059. public function createRechargeOrder_bak()
  1060. {
  1061. $amount = input('amount/d');
  1062. if (empty($amount)) {
  1063. $this->error('金额不能为空');
  1064. }
  1065. // 检查金额是否允许
  1066. $rmb = RechargeList::where('coin', intval($amount))->value('rmb');
  1067. if (empty($rmb)) {
  1068. $this->error('充值金额有误');
  1069. }
  1070. Db::startTrans();
  1071. try {
  1072. $res = RechargeOrder::create([
  1073. 'user_id' => $this->auth->id,
  1074. 'coin_amount' => intval($amount),
  1075. 'rmb_amount' => round($rmb, 2),
  1076. 'out_trade_no' => date('YmdHis') . mt_rand(10000, 99999)
  1077. ]);
  1078. } catch (\Exception $e) {
  1079. Db::rollback();
  1080. $this->error('创建订单出错');
  1081. }
  1082. Db::commit();
  1083. $ret = [
  1084. 'alipay' => $this->request->domain() . '/api/alipay/rechargepay/orderid/' . intval($res->id),
  1085. 'wechat' => '/api/wechat/rechargepay/orderid/' . intval($res->id),
  1086. ];
  1087. $this->success('创建订单成功', $ret);
  1088. }
  1089. /**
  1090. * 金币支付
  1091. * @author fuyelk <fuyelk@fuyelk.com>
  1092. */
  1093. public function coinPay()
  1094. {
  1095. $order_id = input('order_id/d');
  1096. if (empty($order_id)) {
  1097. $this->error('请选择支付订单');
  1098. }
  1099. $order = Order::field('id,box_id,num,status,coin_amount,out_trade_no,select')
  1100. ->where('id', $order_id)
  1101. ->where('user_id', $this->auth->id)
  1102. ->find();
  1103. if (empty($order)) {
  1104. $this->error('订单不存在');
  1105. }
  1106. if ('unpay' != $order->status) {
  1107. $this->error('该订单已支付,请勿重复支付');
  1108. }
  1109. // 查询用户余额
  1110. if (intval($this->auth->coin) < $order->coin_amount) {
  1111. $this->error('您的金币不足');
  1112. }
  1113. Db::startTrans();
  1114. try {
  1115. // 更新订单信息
  1116. $order->pay_method = 'coin';
  1117. $order->pay_coin = $order->coin_amount;
  1118. $order->pay_time = time();
  1119. $order->status = 'unused';// 状态:unpay=待支付,unused=待抽奖,used=已使用
  1120. $order->backend_read = 0;
  1121. $order->save();
  1122. $coin_before = $this->auth->coin;
  1123. // 减少金币余额
  1124. $user = $this->auth->getUser();
  1125. $user->setDec('coin', $order->pay_coin);
  1126. // 创建金币使用记录
  1127. CoinRecord::create([
  1128. 'user_id' => $this->auth->id,
  1129. 'before' => $coin_before,
  1130. 'after' => $this->auth->coin,
  1131. 'coin' => -$order->pay_coin,
  1132. 'order_id' => $order->id,
  1133. 'type' => 'pay_box', // 变更类型:pay_box=支付盲盒,recharge=充值,fromwallet=余额转入
  1134. ]);
  1135. $users = Db::table('box_user')->where('id', $this->auth->pid)->find();
  1136. $orderadd = Order::where('id', $order_id)->where('user_id', $this->auth->id)->find();
  1137. $lou = Db::table('box_setting')->where('id', 1)->find();
  1138. $kou = $lou['kou'];
  1139. if ($users['recharnum'] == 1) {
  1140. Db::table('box_user')->where('id', $users['id'])->setInc("recharnum", 1);
  1141. Retail::giveMoneys($orderadd);
  1142. } else {
  1143. Db::table('box_user')->where('id', $users['id'])->setInc("recharnum", 1);
  1144. $userarr = Db::table('box_user')->where('id', $users['id'])->find();
  1145. if (bcmod($userarr['recharnum'], $kou) == 0) {
  1146. } else {
  1147. Retail::giveMoneys($orderadd);
  1148. };
  1149. }
  1150. // print_r(bcmod($users['recharnum'],$kou);
  1151. } catch (\Exception $e) {
  1152. Db::rollback();
  1153. dta('用户支付失败,订单已回滚到待支付');
  1154. $this->error('支付失败');
  1155. }
  1156. Db::commit();
  1157. // 开箱
  1158. $prize = $this->open($order);
  1159. $this->success('支付成功', ['prize' => $prize]);
  1160. }
  1161. /**
  1162. * 余额支付
  1163. * @author fuyelk <fuyelk@fuyelk.com>
  1164. */
  1165. public function cmoneyPay()
  1166. {
  1167. $order_id = input('order_id/d');
  1168. if (empty($order_id)) {
  1169. $this->error('请选择支付订单');
  1170. }
  1171. $order = Order::field('id,box_id,num,status,rmb_amount,out_trade_no,select')
  1172. ->where('id', $order_id)
  1173. ->where('user_id', $this->auth->id)
  1174. ->find();
  1175. if (empty($order)) {
  1176. $this->error('订单不存在');
  1177. }
  1178. if ('unpay' != $order->status) {
  1179. $this->error('该订单已支付,请勿重复支付');
  1180. }
  1181. // 查询用户余额
  1182. if (intval($this->auth->money) < $order->rmb_amount) {
  1183. $this->error('您的余额不足');
  1184. }
  1185. Db::startTrans();
  1186. try {
  1187. // 更新订单信息
  1188. $order->pay_method = 'money';
  1189. $order->rmb_amount = $order->rmb_amount;
  1190. $order->pay_time = time();
  1191. $order->status = 'unused';// 状态:unpay=待支付,unused=待抽奖,used=已使用
  1192. $order->backend_read = 0;
  1193. $order->save();
  1194. $coin_before = $this->auth->money;
  1195. // 减少余额
  1196. $user = $this->auth->getUser();
  1197. $user->setDec('money', $order->rmb_amount);
  1198. // 创建余额使用记录
  1199. MoneyRecord::create([
  1200. 'user_id' => $this->auth->id,
  1201. 'before' => $this->auth->money,
  1202. 'after' => $this->auth->money - $order->rmb_amount,
  1203. 'money' => -$order->rmb_amount,
  1204. 'order_id' => $order->id,
  1205. 'type' => 'yezhifu', // 变更类型:box_exchange=盲盒回收,refund=库存不足,支付返回,withdrawal=提现,to_coin=转到钱包,withdrawal_fail=提现失败,yezhifu=余额支付
  1206. ]);
  1207. // $users= Db::table('box_user') ->where('id',$this->auth->pid)->find();
  1208. // $orderadd = Order::where('id', $order_id)->where('user_id', $this->auth->id)->find();
  1209. // $lou = Db::table('box_setting')->where('id', 1)->find();
  1210. // $kou = $lou['kou'];
  1211. // if($users['recharnum'] == 1){
  1212. // Db::table('box_user') ->where('id',$users['id'])->setInc("recharnum", 1);
  1213. // Retail::giveMoneys($orderadd);
  1214. // }else{
  1215. // Db::table('box_user') ->where('id',$users['id'])->setInc("recharnum", 1);
  1216. // $userarr= Db::table('box_user') ->where('id',$users['id'])->find();
  1217. // // if(bcmod($userarr['recharnum'],$kou) == 0){
  1218. // // }else{
  1219. // // Retail::giveMoneys($orderadd);
  1220. // // };
  1221. // }
  1222. // print_r(bcmod($users['recharnum'],$kou);
  1223. } catch (\Exception $e) {
  1224. Db::rollback();
  1225. dta('用户支付失败,订单已回滚到待支付');
  1226. $this->error('支付失败');
  1227. }
  1228. Db::commit();
  1229. // 开箱
  1230. $prize = $this->open($order);
  1231. $this->success('支付成功', ['prize' => $prize]);
  1232. }
  1233. /**
  1234. * 价格区间
  1235. * @author fuyelk <fuyelk@fuyelk.com>
  1236. */
  1237. public function priceRange()
  1238. {
  1239. $list = PriceRange::order('weigh desc,id asc')->column('range');
  1240. $this->success('查询成功', ['range' => $list]);
  1241. }
  1242. /**
  1243. * 充值列表
  1244. * @author fuyelk <fuyelk@fuyelk.com>
  1245. */
  1246. public function rechargeList()
  1247. {
  1248. $coinList = RechargeList::order('weigh desc,id desc')->column('coin,rmb', 'id');
  1249. $list = [];
  1250. foreach ($coinList as $item) {
  1251. $list[] = [
  1252. 'coin' => $item['coin'],
  1253. 'rmb' => floatval($item['rmb'])
  1254. ];
  1255. }
  1256. $num = Setting::getSetting('one_rmb_to_coin_num');
  1257. $ret = [
  1258. 'tips' => '充值金额数值比例1:' . round(Setting::getSetting('one_rmb_to_coin_num'), 2),
  1259. 'list' => $list,
  1260. 'bili' => $num,
  1261. 'notice' => Text::getText('recharge_introduction')
  1262. ];
  1263. $this->success('查询成功', $ret);
  1264. }
  1265. /**
  1266. * 开箱
  1267. * @param Order $order 订单
  1268. * @return array|bool
  1269. * @author fuyelk <fuyelk@fuyelk.com>
  1270. */
  1271. private function open(Order $order)
  1272. {
  1273. // 检查订单状态
  1274. if ('unused' != $order->status) { // 状态:unpay=待支付,unused=待抽奖,used=已使用
  1275. return false;
  1276. }
  1277. if (empty($order->box_id)) {
  1278. $this->error('请选择盲盒');
  1279. }
  1280. if (!in_array($order->num, [1, 5, 9])) {
  1281. $this->error('开箱数量有误');
  1282. }
  1283. // 检查盲盒是否可以试玩
  1284. $box = Box::where('id', $order->box_id)->value('id');
  1285. if (empty($box)) {
  1286. $this->error('盲盒有误');
  1287. }
  1288. try {
  1289. // 抽奖 begin
  1290. if (1 == $order->num) {
  1291. $goodsIds = [Detail::getOne($order->box_id)];
  1292. } else {
  1293. $goodsIds = Detail::getMore($order->box_id, $order->num);
  1294. }
  1295. } catch (\Exception $e) {
  1296. // 退款
  1297. if (!$this->refund($order)) {
  1298. $logID = "";
  1299. try {
  1300. $logID = dta($order->toArray(), '用户退款失败');
  1301. } catch (Exception $e) {
  1302. $logID = dta(['order_id' => $order->id], '用户退款失败');
  1303. }
  1304. $this->error('库存不足退款失败,请截屏联系平台:' . $logID);
  1305. }
  1306. $this->error('抽奖失败,已退款');
  1307. }
  1308. // 抽奖 end
  1309. // 查询抽中的奖品信息
  1310. foreach ($goodsIds as $goodsId) {
  1311. $goodsInfo[] = Goods::field('id,image,tag,coin_price,goods_name,delivery_fee')->where('id', $goodsId)->find();
  1312. }
  1313. // 抽奖失败
  1314. if (empty($goodsInfo)) {
  1315. // 退款
  1316. if (!$this->refund($order)) {
  1317. $logID = "";
  1318. try {
  1319. $logID = dta($order->toArray(), '用户退款失败');
  1320. } catch (Exception $e) {
  1321. $logID = dta(['order_id' => $order->id], '用户退款失败');
  1322. }
  1323. $this->error('库存不足退款失败,请截屏联系平台:' . $logID);
  1324. }
  1325. $this->error('抽奖失败,已退款');
  1326. }
  1327. $prizeInfo = [];
  1328. Db::startTrans();
  1329. try {
  1330. foreach ($goodsInfo as &$goods) {
  1331. // 创建开箱记录
  1332. $prize = Prizerecord::create([
  1333. 'box_id' => $order->box_id,
  1334. 'order_id' => $order->id,
  1335. 'out_trade_no' => $order->out_trade_no,
  1336. 'user_id' => $this->auth->id,
  1337. 'goods_id' => $goods->id,
  1338. 'goods_name' => $goods->goods_name,
  1339. 'goods_image' => $goods->image,
  1340. 'goods_coin_price' => $goods->coin_price,
  1341. 'goods_rmb_price' => round(Setting::getRmbFromCoin($goods->coin_price ?: 0), 2),
  1342. 'delivery_fee' => round($goods->delivery_fee, 2),
  1343. 'status' => 'bag', // 奖品状态:bag=盒柜,exchange=已回收,delivery=申请发货,received=已收货
  1344. ]);
  1345. // 减少商品库存
  1346. Goods::where('id', $goods->id)->setDec('stock');
  1347. $prizeInfo[] = [
  1348. 'prize_id' => intval($prize->id),
  1349. 'image' => $prize->goods_image ? cdnurl($prize->goods_image, true) : '',
  1350. 'goods_name' => $prize->goods_name,
  1351. 'tag' => $goods->tag
  1352. ];
  1353. }
  1354. // 增加盲盒销量
  1355. Box::where('id', $order->box_id)->setInc('sales', $order->num);
  1356. } catch (\Exception $e) {
  1357. dta(['order_id' => $order->id, 'error' => $e->getMessage()], '保存开箱记录、减少商品库存失败');
  1358. Db::rollback();
  1359. // 退款
  1360. if (!$this->refund($order)) {
  1361. $logID = "";
  1362. try {
  1363. $logID = dta($order->toArray(), '用户退款到金币失败');
  1364. } catch (Exception $e) {
  1365. $logID = dta(['order_id' => $order->id], '用户退款失败');
  1366. }
  1367. $this->error('库存不足退款失败,请截屏联系平台:' . $logID);
  1368. }
  1369. $this->error('抽奖失败,已退款');
  1370. }
  1371. Db::commit();
  1372. // 订单状态改为已使用
  1373. $order->save(['status' => 'used', 'backend_read' => 0]);
  1374. $ret = [
  1375. 'select' => $order->select,
  1376. 'prizeInfo' => $prizeInfo
  1377. ];
  1378. return $ret;
  1379. }
  1380. /**
  1381. * 通过订单号打开盲盒
  1382. * @author fuyelk <fuyelk@fuyelk.com>
  1383. */
  1384. public function openByOrderTrade()
  1385. {
  1386. $out_trade_no = input('out_trade_no');
  1387. $order_id = input('order_id');
  1388. if (empty($out_trade_no) && empty($order_id)) {
  1389. $this->error('参数有误');
  1390. }
  1391. $where = [];
  1392. if (!empty($out_trade_no)) {
  1393. $where['out_trade_no'] = $out_trade_no;
  1394. }
  1395. if (!empty($order_id)) {
  1396. $where['id'] = $order_id;
  1397. }
  1398. $order = Order::where($where)->where('user_id', $this->auth->id)->where('status', 'unused')->find();
  1399. if (empty($order)) {
  1400. $this->error('订单有误');
  1401. }
  1402. // 开箱
  1403. $prize = $this->open($order);
  1404. $this->success('开箱成功', ['prize' => $prize]);
  1405. }
  1406. /**
  1407. * 退款自动选择
  1408. * @param Order $order
  1409. * @return bool
  1410. * @author fuyelk <fuyelk@fuyelk.com>
  1411. */
  1412. private function refund(Order $order)
  1413. {
  1414. switch ($order->pay_method) {
  1415. case 'coin' :
  1416. return $this->refundToCoin($order);
  1417. break;
  1418. case 'wechat':
  1419. return $this->refundToMoney($order);
  1420. break;
  1421. case 'alipay':
  1422. return $this->refundToMoney($order);
  1423. break;
  1424. default:
  1425. return false;
  1426. }
  1427. }
  1428. /**
  1429. * 退款到金币
  1430. * @param Order $order 订单
  1431. * @author fuyelk <fuyelk@fuyelk.com>
  1432. */
  1433. private function refundToCoin(Order $order)
  1434. {
  1435. $coin_before = $this->auth->coin;
  1436. Db::startTrans();
  1437. try {
  1438. // 增加金币余额
  1439. $user = $this->auth->getUser();
  1440. $user->setInc('coin', $order->pay_coin);
  1441. // 创建金币记录
  1442. CoinRecord::create([
  1443. 'user_id' => $this->auth->id,
  1444. 'before' => $coin_before,
  1445. 'after' => $this->auth->coin,
  1446. 'coin' => $order->pay_coin,
  1447. 'order_id' => $order->id,
  1448. 'type' => 'refund', // 变更类型:pay_box=支付盲盒,recharge=充值,fromwallet=余额转入,refund=退款
  1449. ]);
  1450. // 更新订单状态为已退款
  1451. $order->save(['status' => 'refund', 'backend_read' => 0]);
  1452. } catch (\Exception $e) {
  1453. dta(['order_id' => $order->id, 'error' => $e->getMessage()], '用户退款到金币失败');
  1454. Db::rollback();
  1455. return false;
  1456. }
  1457. Db::commit();
  1458. return true;
  1459. }
  1460. /**
  1461. * 退款到余额
  1462. * @param Order $order 订单
  1463. * @author fuyelk <fuyelk@fuyelk.com>
  1464. */
  1465. private function refundToMoney(Order $order)
  1466. {
  1467. $money_before = $this->auth->money;
  1468. Db::startTrans();
  1469. try {
  1470. // 增加金币余额
  1471. $user = $this->auth->getUser();
  1472. $user->setInc('money', $order->pay_rmb);
  1473. // 创建余额记录
  1474. MoneyRecord::create([
  1475. 'user_id' => $this->auth->id,
  1476. 'before' => $money_before,
  1477. 'after' => $this->auth->money,
  1478. 'money' => $order->pay_rmb,
  1479. 'order_id' => $order->id,
  1480. 'type' => 'refund', // 变更类型:box_exchange=盲盒回收,refund=库存不足,支付返回,withdrawal=提现,to_coin=转到钱包,withdrawal_fail=提现失败
  1481. ]);
  1482. // 更新订单状态为已退款
  1483. $order->save(['status' => 'refund', 'backend_read' => 0]);
  1484. } catch (\Exception $e) {
  1485. dta(['order_id' => $order->id, 'error' => $e->getMessage()], '用户退款到余额失败');
  1486. Db::rollback();
  1487. return false;
  1488. }
  1489. Db::commit();
  1490. return true;
  1491. }
  1492. /**
  1493. * 获取客服信息
  1494. * @author fuyelk <fuyelk@fuyelk.com>
  1495. */
  1496. public function getServiceInfo()
  1497. {
  1498. $ret = [
  1499. 'number' => Setting::getSetting('service_number') ?: '',
  1500. 'qrcode' => ($qrcode = Setting::getSetting('service_qrcode')) ? cdnurl($qrcode, true) : '',
  1501. ];
  1502. $this->success('查询成功', $ret);
  1503. }
  1504. /**
  1505. * 获取落地域名
  1506. * @author fuyelk <fuyelk@fuyelk.com>
  1507. */
  1508. public function getServiceurl()
  1509. {
  1510. $ret = Setting::where('id', 1)->find();
  1511. // $curl = Setting::getSetting('curl');
  1512. // $abs = explode('|',$curl);
  1513. // $ret = [
  1514. // 'url' => Setting::getSetting('url')
  1515. // ];
  1516. $this->success('查询成功', $ret['url']);
  1517. }
  1518. /**
  1519. * 获取微信登录地址
  1520. * @author fuyelk <fuyelk@fuyelk.com>
  1521. */
  1522. public function getWechatLoginUrl()
  1523. {
  1524. $redirect = input('redirect');
  1525. if (empty($redirect)) {
  1526. $this->error('重定向地址不能为空');
  1527. }
  1528. $redirect = preg_match("/^http(.*)/", $redirect) ? $redirect : $this->request->domain() . $redirect;
  1529. $ret = [
  1530. 'url' => $this->request->domain() . '/index/wechat/bootToUrl?url=' . base64_encode($redirect)
  1531. ];
  1532. $this->success('查询成功', $ret);
  1533. }
  1534. /**
  1535. * 添加晒图
  1536. */
  1537. public function setShai()
  1538. {
  1539. $validate = new \think\Validate([
  1540. 'box_zw' => 'require',
  1541. 'box_img' => 'require',
  1542. 'token' => 'require',
  1543. ]);
  1544. $validate->message([
  1545. 'box_zw.require' => '盲盒详情banner文字不能为空',
  1546. 'box_img.require' => '盲盒详情banner不能为空',
  1547. 'token.require' => 'token不能为空',
  1548. ]);
  1549. $data = $this->request->param();
  1550. if (!$validate->check($data)) {
  1551. $this->error($validate->getError());
  1552. }
  1553. $params = [
  1554. 'box_mc' => $this->auth->nickname,
  1555. 'box_tx' => $this->auth->avatar ? cdnurl($this->auth->avatar, true) : '',
  1556. 'box_zw' => $data['box_zw'],
  1557. 'box_img' => $data['box_img'],
  1558. 'create_time' => time()
  1559. ];
  1560. Db::table('box_shai')->insertGetId($params);
  1561. $this->success();
  1562. }
  1563. }