123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 |
- <?php
- namespace app\api\controller;
- use app\common\controller\Api;
- use think\Db;
- use addons\epay\library\Service;
- /**
- * 产品
- */
- class Product extends Api
- {
- protected $noNeedLogin = ['cate_product_lists','lists','info','test','xieyi_info'];
- protected $noNeedRight = ['*'];
- protected $order_status = [
- 0 => '待付款',
- 1 => '待出行',
- 2 => '已完成',
- 10 => '已取消',//未付取消
- 21 => '售后中',//已付取消
- 22 => '已退款',//已付已退
- ];
- //分类页,全部商品列表
- public function cate_product_lists(){
- $where = [
- 'p.is_show'=>1,
- 'p.jxtype'=>0,
- ];
- $keyword = input('keyword','','trim');
- if(!empty($keyword)){
- $where['p.name'] = ['LIKE','%'.$keyword.'%'];
- if($this->auth->isLogin()){
- Db::name('user_search')->insertGetId(['user_id'=>$this->auth->id,'keyword'=>$keyword]);
- }
- }
- //排序字段
- $orderby = input('orderby','view_number','trim');
- if($orderby != 'price' && $orderby != 'sell_number'){
- $orderby = 'view_number';
- }
- //排序方式
- $sort = input('sort',1,'intval');//1正序,2倒叙
- if($sort == 1){
- $sort = 'asc';
- }else{
- $sort = 'desc';
- }
- if($orderby == 'view_number'){$sort = 'desc';}
- $list = Db::name('product')->alias('p')
- ->join('procate','p.procate_id = procate.id','LEFT')
- ->field('p.id,p.name,p.images,p.title,p.info,p.image,p.address,p.price,p.view_number,p.procate_id,
- procate.name as procate_name
- ')->where($where)->order('p.'.$orderby,$sort)->select();
- $list = list_domain_image($list,['image','images']);
- foreach($list as $key => $product){
- $list[$key]['image'] = isset($product['images'][0]) ? $product['images'][0] : $product['image'];
- }
- $procate = Db::name('procate')->field('id,name')->order('weigh desc,id desc')->select();
- foreach($procate as $key => &$cate){
- $cate['child'] = [];
- foreach($list as $pk => $product){
- if($cate['id'] == $product['procate_id']){
- $cate['child'][] = $product;
- }
- }
- if(empty($cate['child'])){
- unset($procate[$key]);
- }
- }
- //因为有unset,所以去键名
- $result = [];
- $result[] = ['id'=>0,'name'=>'全部','child'=>$list];
- foreach($procate as $key => $val){
- $result[] = $val;
- }
- $this->success(1,$result);
- }
- //商品列表
- public function lists()
- {
- $where = [
- 'is_show'=>1,
- 'jxtype'=>0,
- ];
- //首页分类
- $tag_id = input('tag_id',0);
- if($tag_id){
- if($tag_id == -1){
- $where['is_recommend'] = 1;
- }else{
- $where['protag_id'] = $tag_id;
- }
- }
- //业务分类
- $cate_id = input('cate_id',0,'intval');
- if($cate_id){
- $where['procate_id'] = $cate_id;
- }
- //搜索
- $keyword = input('keyword','','trim');
- if(!empty($keyword)){
- $where['name'] = ['LIKE','%'.$keyword.'%'];
- if($this->auth->isLogin()){
- Db::name('user_search')->insertGetId(['user_id'=>$this->auth->id,'keyword'=>$keyword]);
- }
- }
- $list = Db::name('product')->field('content',true)->where($where)->order('weigh desc,id desc')->autopage()->select();
- $list = list_domain_image($list,['image','images']);
- $this->success(1,$list);
- }
- //商品详情+选路线规格
- public function info(){
- $id = input('id',0);
- $info = Db::name('product')->where('id',$id)->find();
- if(!$info){
- $this->error('不存在的商品');
- }
- if($info['is_show'] != 1){
- $this->error('商品已下架');
- }
- $info = info_domain_image($info,['image','images']);
- //访问量自增1
- Db::name('product')->where('id',$id)->setInc('view_number');
- //是否收藏
- $info['is_collect'] = 0;
- if($this->auth->isLogin()){
- $collect = Db::name('user_collect')->where('user_id',$this->auth->id)->where('product_id',$id)->find();
- if($collect){
- $info['is_collect'] = 1;
- }
- }
- //追加路线
- //单程
- $road = Db::name('product_road')->where('product_id',$id)->where('roadtype','IN','1,2')->select();
- if(!empty($road)){
- $roadtype = ['name'=>'单程票','type'=>1,'child'=>$road];
- $info['road'][] = $roadtype;
- }
- //往返
- $road = Db::name('product_road')->where('product_id',$id)->where('roadtype',3)->select();
- if(!empty($road)){
- $roadtype = ['name'=>'往返票','type'=>2,'child'=>$road];
- $info['road'][] = $roadtype;
- }
- $this->success(1,$info);
- }
- //商品详情+已确定线路,选班次
- public function banci(){
- $id = input('id',0);
- $info = Db::name('product')->where('id',$id)->find();
- if(!$info){
- $this->error('不存在的商品');
- }
- if($info['is_show'] != 1){
- $this->error('商品已下架');
- }
- $info = info_domain_image($info,['image','images']);
- //是否收藏
- $info['is_collect'] = 0;
- if($this->auth->isLogin()){
- $collect = Db::name('user_collect')->where('user_id',$this->auth->id)->where('product_id',$id)->find();
- if($collect){
- $info['is_collect'] = 1;
- }
- }
- //根据选择的路线显示
- $road_id = input('xianlu_id',0);
- $road_info = Db::name('product_road')->where('id',$road_id)->find();
- $info['xianlu_id'] = $road_id;//回传
- //获取票
- $ticket_map = [
- 'road_id' => $road_id,
- ];
- if($this->auth->group_id != 4){
- $ticket_map['is_qudao'] = 0;
- }
- $ticket = Db::name('product_ticket')->where($ticket_map)->select();
- $info['ticket'] = $ticket;
- if($road_info['roadtype'] == 3){
- $road_list = Db::name('product_road')->where('product_id',$id)->where('roadtype','IN','1,2')->order('roadtype','asc')->select();
- }else{
- $road_list = Db::name('product_road')->where('id',$road_id)->select();
- }
- //循环road
- $road_data= [];
- $today = time();
- foreach($road_list as $key => $road){
- //出发地
- $chufadi = Db::name('product_chufadi')->where('road_id',$road['id'])->select();
- //出发日期
- $riqi_data = [];
- //产品的所有日历
- $chufabanci = Db::name('product_chufabanci')
- ->where('road_id',$road['id'])
- ->where('fache_status',0)
- ->where('chufatime','gt',$today)
- ->where('ticket_remain','gt',0)
- ->order('chufatime','asc')->select();
- foreach($chufabanci as $bckey => $rili){
- $riqi = date('Y-m-d',$rili['chufatime']);
- $shijian = date('H:i',$rili['chufatime']);
- $chufabanci[$bckey]['riqi'] = $riqi;
- $chufabanci[$bckey]['shijian'] = $shijian;
- //
- $riqi_data[] = $riqi;
- }
- $riqi_data = (array_flip(array_flip($riqi_data)));//去重
- //双循环,入child
- $riqi_data_new = [];
- foreach($riqi_data as $riqi){
- $child = [];
- foreach($chufabanci as $bckey => $rili){
- if($riqi == $rili['riqi']){
- $child[] = $rili;
- }
- }
- $thisbanci = [
- 'name' => substr($riqi,5),
- 'name_ymd' => $riqi,
- 'child' => $child,
- ];
- $riqi_data_new[] = $thisbanci;
- }
- $thisroad = [
- 'road_id'=>$road['id'],
- 'roadtype'=>$road['roadtype'],
- 'roadname'=>$road['roadname'],
- 'chufadi' => $chufadi,
- 'chufabanci' => $riqi_data_new,
- ];
- $road_data[] = $thisroad;
- }
- $info['road'] = $road_data;
- //协议名字
- $info['xieyi_name'] = '';
- if($info['xieyi_id']){
- $xieyi = Db::name('product_xieyi')->where('id',$info['xieyi_id'])->where('deletetime',NULL)->find();
- if(!empty($xieyi)){
- $info['xieyi_name'] = $xieyi['name'];
- }else{
- $info['xieyi_id'] = 0;
- }
- }else{
- $info['xieyi_id'] = 0;
- }
- $this->success(1,$info);
- }
- //产品协议
- public function xieyi_info(){
- $id = input('id',0);
- $info = Db::name('product_xieyi')->where('id',$id)->find();
- $this->success(1,$info);
- }
- //商品详情,这一天有几个班次
- //给前端的辅助方法
- public function banci_time(){
- $road_id = input('road_id',0);
- $riqi_ymd = strtotime(input('riqi_ymd',date('Y-m-d')));
- $riqi_end = $riqi_ymd + 86399;
- //产品的所有日历
- $chufabanci = Db::name('product_chufabanci')
- ->where('road_id',$road_id)
- ->where('fache_status',0)
- ->where('chufatime','BETWEEN',[$riqi_ymd,$riqi_end])
- ->where('chufatime','gt',time())
- ->where('ticket_remain','gt',0)
- ->order('chufatime','asc')->select();
- foreach($chufabanci as $bckey => $rili){
- $riqi = date('m-d',$rili['chufatime']);
- $shijian = date('H:i',$rili['chufatime']);
- $chufabanci[$bckey]['riqi'] = $riqi;
- $chufabanci[$bckey]['riqi_ymd'] = date('Y-m-d',$rili['chufatime']);
- $chufabanci[$bckey]['shijian'] = $shijian;
- }
- $this->success(1,$chufabanci);
- }
- //下单
- public function submit(){
- $realname = input('realname','');
- $mobile = input('mobile','');
- if(empty($realname) || empty($mobile)){
- $this->error('请填写姓名和手机号');
- }
- //分享人用户id,检验
- $share_uid = input('share_uid',0,'intval');
- if(!empty($share_uid)){
- $share_user = Db::name('user')->field('id')->where('id',$share_uid)->find();
- if(!empty($share_user)){
- $share_uid = $share_user['id'];
- //保存上
- Db::name('user')->where('id',$this->auth->id)->update(['intro_uid'=>$share_uid]);
- }else{
- $share_uid = 0;
- }
- }else{
- $share_uid = !empty($this->auth->intro_uid) ? $this->auth->intro_uid : 0 ;
- }
- //商品
- $product_id = input('product_id',0);
- $product_info = Db::name('product')->where('id',$product_id)->find();
- if(!$product_info){
- $this->error('不存在的商品');
- }
- if($product_info['is_show'] != 1){
- $this->error('商品已下架');
- }
- //路线
- $road = input('road','','htmlspecialchars_decode');
- if(empty($road)){
- $this->error('请选择路线');
- }
- //子订单公共数据
- $nowtime = time();
- $order_item_public = [
- 'order_id' => 0,
- 'product_id' => $product_id,
- 'user_id' => $this->auth->id,
- 'createtime' => $nowtime,
- ];
- //初始路线,仅给票用
- $road_id = input('xianlu_id',0);
- $road_info = Db::name('product_road')->where('product_id',$product_id)->where('id',$road_id)->find();
- if(!$road_info){
- $this->error('不存在的路线');
- }
- //此路拥有的票
- $ticket_list = Db::name('product_ticket')->where('road_id',$road_id)->column('id,name,price');
- //循环票
- $order_ticket_all = [];
- $ticket_num = 0;//单个路线所需票数
- $total_fee = 0;//订单总价格
- $ticket_str = '';
- $ticket = input('ticket','','htmlspecialchars_decode');
- if(empty($ticket)){
- $this->error('请选择票数');
- }
- $ticket = json_decode($ticket,true);
- foreach($ticket as $tic){
- if(!isset($tic['ticket_id']) || !isset($tic['number']) ){$this->error('票数据错误1');}
- if(!isset($ticket_list[$tic['ticket_id']])){$this->error('票数据错误2');}
- $tic['number'] = intval($tic['number']);
- if($tic['number'] == 0){
- continue;
- }
- $ticket_num += $tic['number'];
- $ticket_info = $ticket_list[$tic['ticket_id']];
- $order_ticket = [
- 'road_id' => $road_id,
- 'roadname' => $road_info['roadname'],
- 'roadtype' => $road_info['roadtype'],
- 'ticket_id' => $ticket_info['id'],
- 'ticket_name' => $ticket_info['name'],
- 'ticket_price' => $ticket_info['price'],
- 'ticket_number' => $tic['number'],
- 'pay_fee' => bcmul($tic['number'],$ticket_info['price'],2),
- ];
- $total_fee = bcadd($total_fee,$order_ticket['pay_fee'],2);
- $order_ticket = array_merge($order_item_public,$order_ticket);
- $order_ticket_all[] = $order_ticket;
- $ticket_str .= $ticket_info['name'].'*'.$tic['number'].',';
- }
- $ticket_str = mb_substr($ticket_str,0,-1);
- if($ticket_num == 0){
- $this->error('您还没选票');
- }
- //订单入库
- $order_data = [
- 'order_no' => createUniqueNo('P',$this->auth->id),
- 'product_id' => $product_id,
- 'product_name' => $product_info['name'],
- 'user_id' => $this->auth->id,
- 'createtime' => $nowtime,
- 'pay_fee' => $total_fee,
- 'status' => 0,
- 'paytime' => 0,
- 'realname' => $realname,
- 'mobile' => $mobile,
- 'road_id' => $road_info['id'],
- 'roadtype' => $road_info['roadtype'],
- 'roadname' => $road_info['roadname'],
- 'ticket_str' => $ticket_str,
- 'share_uid' => $share_uid,
- 'jxtype' => $product_info['jxtype'],
- 'xieyi_id' => $product_info['xieyi_id'], //冗余协议id
- ];
- //入库
- Db::startTrans();
- $order_id = Db::name('order')->insertGetId($order_data);
- if(!$order_id){
- Db::rollback();
- $this->error('下单失败,请稍后再试');
- }
- //order_ticket入库
- foreach($order_ticket_all as &$order_ticket){
- $order_ticket['order_id'] = $order_id;
- }
- $rs_ticket = Db::name('order_ticket')->insertAll($order_ticket_all);
- if(!$rs_ticket){
- Db::rollback();
- $this->error('下单失败,请稍后再试');
- }
- //去程和返程
- $order_info_all = [];
- $road = json_decode($road,true);
- if($road_info['roadtype'] == 3 && count($road) != 2){Db::rollback();$this->error('路线数据错误'); } //往返路线,road数量只能是2
- if($road_info['roadtype'] != 3 && count($road) != 1){Db::rollback();$this->error('路线数据错误'); } //单程路线,road数量只能是1
- $order_update = [];
- foreach($road as $ro){
- //检查路线id
- $ro_info = Db::name('product_road')->where('product_id',$product_id)->where('id',$ro['road_id'])->find();
- if(empty($ro_info)){
- Db::rollback();
- $this->error('路线数据不存在');
- }
- //检查出发地
- $chufadi = Db::name('product_chufadi')->where('road_id',$ro['road_id'])->where('id',$ro['chufadi_id'])->find();
- if(empty($chufadi)){
- Db::rollback();
- $this->error('出发地数据不存在');
- }
- //检查出发班次
- $chufabanci = Db::name('product_chufabanci')->where('road_id',$ro['road_id'])->where('id',$ro['chufabanci_id'])->lock(true)->find();
- if(empty($chufabanci)){
- Db::rollback();
- $this->error('出发班次不存在');
- }
- /*if($ro_info['roadtype'] == $chufadi['chufatype'] && $ro_info['roadtype'] == $chufabanci['chufatype']){
- }else{
- $this->error('路线数据不正确');
- }*/
- //这个班次,票数是否足够
- if($chufabanci['ticket_remain'] < $ticket_num){
- Db::rollback();
- $this->error($ro_info['roadname'].'此班次票数不足,请换一个时间');
- }
- $banci_update = [
- 'ticket_remain' => $chufabanci['ticket_remain'] - $ticket_num
- ];
- $banci_rs = Db::name('product_chufabanci')->where('id',$ro['chufabanci_id'])->update($banci_update);
- if($banci_rs === false){
- Db::rollback();
- $this->error('购票失败');
- }
- //冗余订单数据,去返的出发时间
- if($chufabanci['chufatype'] == 1){
- $order_update['go_chufatime'] = $chufabanci['chufatime'];
- }
- if($chufabanci['chufatype'] == 2){
- $order_update['back_chufatime'] = $chufabanci['chufatime'];
- }
- //冗余订单数据,去返的出发地
- if($chufadi['chufatype'] == 1){
- $order_update['go_chufaname'] = $chufadi['chufaname'];
- }
- if($chufadi['chufatype'] == 2){
- $order_update['back_chufaname'] = $chufadi['chufaname'];
- }
- //校验完成
- $order_info = [
- 'road_id' => $ro_info['id'],
- 'roadname'=> $ro_info['roadname'],
- 'roadtype'=> $ro_info['roadtype'],
- 'chufadi_id'=> $chufadi['id'],
- 'chufaname'=> $chufadi['chufaname'],
- 'longitude'=> $chufadi['longitude'],
- 'latitude'=> $chufadi['latitude'],
- 'chufabanci_id'=> $chufabanci['id'],
- 'chufatime'=> $chufabanci['chufatime'],
- 'ticket_number'=> $ticket_num,
- 'order_id' => $order_id, //覆盖order_id
- 'hexiao_no' => createUniqueNo('HX'),
- 'hexiao_status' => 0,
- 'hexiao_uid' => 0,
- ];
- $order_info = array_merge($order_item_public,$order_info);
- $order_info_all[] = $order_info;
- }
- $order_info_rs = Db::name('order_road')->insertAll($order_info_all);
- if(!$order_info_rs){
- Db::rollback();
- $this->error('下单失败,请稍后再试');
- }
- //修改订单
- $order_up = Db::name('order')->where('id',$order_id)->update($order_update);
- if($order_up === false){
- Db::rollback();
- $this->error('下单失败,请稍后再试');
- }
- //准备付款
- Db::commit();
- $this->success('下单成功',$order_id);
- }
- //订单详情
- public function order_info(){
- $order_id = input('order_id',0);
- $order = Db::name('order')->where('id',$order_id)->find();
- if(empty($order)){
- $this->error('不存在的订单');
- }
- //订单状态文字
- $order['status_text'] = isset($this->order_status[$order['status']]) ? $this->order_status[$order['status']] : '';
- //订单支付截止时间
- $order_auto_cancel_minite = config('site.order_auto_cancel_minite');
- $order['last_paytime'] = date('Y-m-d H:i',$order['createtime'] + ($order_auto_cancel_minite * 60));
- //商品
- $product = Db::name('product')->field('id,name,title,info,image')->where('id',$order['product_id'])->find();
- if($product){
- $product = info_domain_image($product,['image']);
- }
- //路线
- $order_road = Db::name('order_road')->field('roadtype,chufaname,chufatime,roadname,longitude,latitude')->where('order_id',$order_id)->order('roadtype asc')->select();
- foreach($order_road as $key => $road){
- $order_road[$key]['chufatime_text'] = date('Y-m-d H:i',$road['chufatime']);
- }
- //票
- $order_ticket = Db::name('order_ticket')->field('ticket_name,ticket_number')->where('order_id',$order_id)->select();
- //结果
- $result = [
- 'order' => $order,
- 'product' => $product,
- 'order_road' => $order_road,
- 'order_ticket' => $order_ticket,
- 'ticket_str' => $order['ticket_str']
- ];
- $this->success(1,$result);
- }
- /**
- * json 请求
- * @param $url
- * @return mixed
- */
- private function getJson($url){
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- $output = curl_exec($ch);
- curl_close($ch);
- return json_decode($output, true);
- }
- //支付订单
- public function pay_order(){
- //code值
- $code = input('code');
- if (!$code) {
- $this->error(__('Invalid parameters'));
- }
- $config = config('wxMiniProgram');
- $getopenid = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$config['appid'].'&secret='.$config['secret'].'&js_code='.$code.'&grant_type=authorization_code';
- $openidInfo = $this->getJson($getopenid);
- if(!isset($openidInfo['openid'])) {
- $this->error('用户openid获取失败',$openidInfo);
- }
- //订单
- $pay_type = 'wechat';
- $platform = 'miniapp';
- $order_id = input('order_id',0);
- $map = [
- 'id' => $order_id,
- 'user_id' => $this->auth->id,
- 'status' => 0,
- ];
- $order = Db::name('order')->where($map)->find();
- if(empty($order)){
- $this->error('请刷新重试');
- }
- $pay_data = [
- 'user_id' => $order['user_id'],
- 'out_trade_no' => createUniqueNo('P',$order_id),
- 'order_amount' => $order['pay_fee'],
- //'order_amount' => 0.01,//测试支付强制0.01元
- 'createtime' => time(),
- 'notifytime' => 0,
- 'pay_type' => $pay_type,
- 'platform' => $platform,
- 'order_status' => 0,
- 'table_name' => 'order',
- 'table_id' => $order['id'],
- ];
- Db::name('pay_order')->insertGetId($pay_data);
- $openid = $openidInfo['openid'];
- //下单
- $params = [
- 'type' => $pay_type,
- 'orderid' => $pay_data['out_trade_no'],
- 'title' => '支付订单',
- 'amount' => $pay_data['order_amount'],
- 'method' => $platform,
- 'openid' => $openid,
- 'notifyurl' => config('pay_notify_url').'/api/pay/order_notify_base/paytype/'.$pay_type,
- 'returnurl' => '',
- ];
- $res = Service::submitOrder($params);
- if($pay_type == 'wechat'){
- $this->success('success',json_decode($res,true));
- }else{
- $this->success('success',$res);
- }
- }
- //提交订单的数据格式
- public function test(){
- $ticket_data = [
- [
- 'ticket_id' => 1,
- 'number' => 2,
- ],
- [
- 'ticket_id' => 4,
- 'number' => 3,
- ],
- ];
- dump(json_encode($ticket_data));
- $road_data = [
- [
- 'road_id' => 1,
- 'chufadi_id' => 1,
- 'chufabanci_id' => 1,
- ],
- [
- 'road_id' => 2,
- 'chufadi_id' => 4,
- 'chufabanci_id' => 7,
- ],
- ];
- dump(json_encode($road_data));
- }
- }
|