Index.php 62 KB

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