diff --git a/application/.htaccess b/application/.htaccess new file mode 100644 index 00000000..3418e55a --- /dev/null +++ b/application/.htaccess @@ -0,0 +1 @@ +deny from all \ No newline at end of file diff --git a/application/admin/common.php b/application/admin/common.php new file mode 100644 index 00000000..90f292c1 --- /dev/null +++ b/application/admin/common.php @@ -0,0 +1,120 @@ + +// +---------------------------------------------------------------------- + +// 应用公共文件 +/** + * 获取用户名称 + * @param $uid + * @return mixed + */ +function getUserNickname($uid){ + return \app\admin\model\user\User::where('uid',$uid)->value('nickname'); +} + +/** + * 获取产品名称 + * @param $id + * @return mixed + */ +function getProductName($id){ + return \app\admin\model\store\StoreProduct::where('id',$id)->value('store_name'); +} + +/** + * 获取拼团名称 + * @param $id + * @return mixed + */ +function getCombinationTitle($id){ + return \app\admin\model\store\StoreCombination::where('id',$id)->value('title'); +} + +/** + * 获取订单编号 + * @param $id + */ +function getOrderId($id){ + return \app\admin\model\order\StoreOrder::where('id',$id)->value('order_id'); +} + + +/** + * 根据用户uid获取订单数 + * @param $uid + * @return int|string + */ +function getOrderCount($uid){ + return \app\admin\model\order\StoreOrder::where('uid',$uid)->where('paid',1)->where('refund_status',0)->where('status',2)->count(); +} +/** + * 格式化属性 + * @param $arr + * @return array + */ +function attrFormat($arr){ + $data = []; + $res = []; + if(count($arr) > 1){ + for ($i=0; $i < count($arr)-1; $i++) { + if($i == 0) $data = $arr[$i]['detail']; + //替代变量1 + $rep1 = []; + foreach ($data as $v) { + foreach ($arr[$i+1]['detail'] as $g) { + //替代变量2 + $rep2 = ($i!=0?'':$arr[$i]['value']."_").$v."-".$arr[$i+1]['value']."_".$g; + $tmp[] = $rep2; + if($i==count($arr)-2){ + foreach (explode('-', $rep2) as $k => $h) { + //替代变量3 + $rep3 = explode('_', $h); + //替代变量4 + $rep4['detail'][$rep3[0]] = $rep3[1]; + } + $res[] = $rep4; + } + } + } + $data = $tmp; + } + }else{ + $dataArr = []; + foreach ($arr as $k=>$v){ + foreach ($v['detail'] as $kk=>$vv){ + $dataArr[$kk] = $v['value'].'_'.$vv; + $res[$kk]['detail'][$v['value']] = $vv; + } + } + $data[] = implode('-',$dataArr); + } + return [$data,$res]; +} + +function getMonth($time='',$ceil=0){ + if(empty($time)){ + $firstday = date("Y-m-01",time()); + $lastday = date("Y-m-d",strtotime("$firstday +1 month -1 day")); + }else if($time=='n'){ + if($ceil!=0) + $season = ceil(date('n') /3)-$ceil; + else + $season = ceil(date('n') /3); + $firstday=date('Y-m-01',mktime(0,0,0,($season - 1) *3 +1,1,date('Y'))); + $lastday=date('Y-m-t',mktime(0,0,0,$season * 3,1,date('Y'))); + }else if($time=='y'){ + $firstday=date('Y-01-01'); + $lastday=date('Y-12-31'); + }else if($time=='h'){ + $firstday = date('Y-m-d', strtotime('this week +'.$ceil.' day')) . ' 00:00:00'; + $lastday = date('Y-m-d', strtotime('this week +'.($ceil+1).' day')) . ' 23:59:59'; + } + return array($firstday,$lastday); +} diff --git a/application/admin/config.php b/application/admin/config.php new file mode 100644 index 00000000..90bc3784 --- /dev/null +++ b/application/admin/config.php @@ -0,0 +1,23 @@ + +// +---------------------------------------------------------------------- + + +return [ + 'session' => [ + // SESSION 前缀 + 'prefix' => 'admin', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + ], + 'system_wechat_tag' => '_system_wechat' +]; diff --git a/application/admin/controller/AuthApi.php b/application/admin/controller/AuthApi.php new file mode 100644 index 00000000..be1fcd16 --- /dev/null +++ b/application/admin/controller/AuthApi.php @@ -0,0 +1,111 @@ +$status],$id); + if($res) return JsonService::successful('修改成功'); + else return JsonService::fail('修改失败'); + } + + /** + * 修改砍价状态 + * @param $status + * @param int $id + */ + public function set_bargain_status($status,$id = 0){ + if(!$id) return JsonService::fail('参数错误'); + $res = StoreBargain::edit(['status'=>$status],$id); + if($res) return JsonService::successful('修改成功'); + else return JsonService::fail('修改失败'); + } + /** + * 修改秒杀产品状态 + * @param $status + * @param int $id + */ + public function set_seckill_status($status,$id = 0){ + if(!$id) return JsonService::fail('参数错误'); + $res = StoreSeckill::edit(['status'=>$status],$id); + if($res) return JsonService::successful('修改成功'); + else return JsonService::fail('修改失败'); + } +} + + diff --git a/application/admin/controller/AuthController.php b/application/admin/controller/AuthController.php new file mode 100644 index 00000000..0aac3381 --- /dev/null +++ b/application/admin/controller/AuthController.php @@ -0,0 +1,89 @@ +redirect('Login/index'); + try{ + $adminInfo = SystemAdmin::activeAdminInfoOrFail(); + }catch (\Exception $e){ + return $this->failed(SystemAdmin::getErrorInfo($e->getMessage()),Url::build('Login/index')); + } + $this->adminInfo = $adminInfo; + $this->adminId = $adminInfo['id']; + $this->getActiveAdminInfo(); + $this->auth = SystemAdmin::activeAdminAuthOrFail(); + $this->adminInfo->level === 0 || $this->checkAuth(); + $this->assign('_admin',$this->adminInfo); + HookService::listen('admin_visit',$this->adminInfo,'system',false,SystemBehavior::class); + } + + + protected function checkAuth($action = null,$controller = null,$module = null,array $route = []) + { + static $allAuth = null; + if($allAuth === null) $allAuth = SystemRole::getAllAuth(); + if($module === null) $module = $this->request->module(); + if($controller === null) $controller = $this->request->controller(); + if($action === null) $action = $this->request->action(); + if(!count($route)) $route = $this->request->route(); + if(in_array(strtolower($controller),$this->skipLogController,true)) return true; + $nowAuthName = SystemMenus::getAuthName($action,$controller,$module,$route); + $baseNowAuthName = SystemMenus::getAuthName($action,$controller,$module,[]); + if((in_array($nowAuthName,$allAuth) && !in_array($nowAuthName,$this->auth)) || (in_array($baseNowAuthName,$allAuth) && !in_array($baseNowAuthName,$this->auth))) + exit($this->failed('没有权限访问!')); + return true; + } + + + /** + * 获得当前用户最新信息 + * @return SystemAdmin + */ + protected function getActiveAdminInfo() + { + $adminId = $this->adminId; + $adminInfo = SystemAdmin::getValidAdminInfoOrFail($adminId); + if(!$adminInfo) $this->failed(SystemAdmin::getErrorInfo('请登陆!')); + $this->adminInfo = $adminInfo; + SystemAdmin::setLoginInfo($adminInfo); + return $adminInfo; + } +} \ No newline at end of file diff --git a/application/admin/controller/Common.php b/application/admin/controller/Common.php new file mode 100644 index 00000000..0cf3c753 --- /dev/null +++ b/application/admin/controller/Common.php @@ -0,0 +1,23 @@ + + * @day: 2017/12/07 + */ + +namespace app\admin\controller; + + +use service\UtilService; + +class Common extends AuthController +{ + public function rmPublicResource($url) + { + $res = UtilService::rmPublicResource($url); + if($res->status) + return $this->successful('删除成功!'); + else + return $this->failed($res->msg); + } +} \ No newline at end of file diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php new file mode 100644 index 00000000..a7c7ce75 --- /dev/null +++ b/application/admin/controller/Index.php @@ -0,0 +1,169 @@ +adminInfo->toArray(); + $roles = explode(',',$adminInfo['roles']); + $site_logo = SystemConfig::getOneConfig('menu_name','site_logo')->toArray(); +// dump(SystemMenus::menuList()); +// exit(); + $this->assign([ + 'menuList'=>SystemMenus::menuList(), + 'site_logo'=>json_decode($site_logo['value'],true), + 'role_name'=>SystemRole::where('id',$roles[0])->field('role_name')->find() + ]); + return $this->fetch(); + } + //后台首页内容 + public function main() + { + /*首页第一行统计*/ + $now_month = strtotime(date('Y-m')); + $pre_month = strtotime(date('Y-m',strtotime('-1 month'))); + $now_day = strtotime(date('Y-m-d')); + $pre_day = strtotime(date('Y-m-d',strtotime('-1 day')));//昨天时间戳 + $day = strtotime(date('Y-m-d',strtotime('0 day')));//今天时间戳 + //昨天待发货数量 + $topData['orderDeliveryNum'] = StoreOrder::isMainYesterdayCount($pre_day,$day) + ->where('status',0) + ->where('paid',1) + ->where('refund_status',0) + ->count(); + //昨天退换货订单数 + $topData['orderRefundNum'] = StoreOrder::isMainYesterdayCount($pre_day,$day) + ->where('paid',1) + ->where('refund_status','IN','1,2') + ->count(); + //库存预警 + $replenishment_num = SystemConfig::getValue('store_stock') > 0 ? SystemConfig::getValue('store_stock') : 20;//库存预警界限 + $topData['stockProduct'] = StoreProduct::where('stock','<=',$replenishment_num)->where('is_del',0)->count(); + //待处理提现 + $topData['treatedExtract'] = UserExtract::where('status',0)->count(); + //昨日订单数 + $topData['orderNum'] = StoreOrder::isMainYesterdayCount($pre_day,$day)->count(); + //昨日交易额 + $orderPriceNum = StoreOrder::isMainYesterdayCount($pre_day,$day)->field('sum(pay_price) as pay_price')->find()['pay_price']; + $topData['orderPriceNum'] = $orderPriceNum ? $orderPriceNum : 0; + //总收入->日 + $now_day_order_p = StoreOrder::where('paid',1)->where('pay_time','gt',$now_day)->value('sum(pay_price)'); + $pre_day_order_p = StoreOrder::where('paid',1)->where('pay_time','gt',$pre_day)->where('pay_time','lt',$now_day)->value('sum(pay_price)'); + $first_line['d_price'] = [ + 'data' => $now_day_order_p ? $now_day_order_p : 0, + 'percent' => abs($now_day_order_p - $pre_day_order_p), + 'is_plus' => $now_day_order_p - $pre_day_order_p > 0 ? 1 : ($now_day_order_p - $pre_day_order_p == 0 ? -1 : 0) + ]; + + //总收入->月 + $now_month_order_p = StoreOrder::where('paid',1)->where('pay_time','gt',$now_month)->value('sum(pay_price)'); + $pre_month_order_p = StoreOrder::where('paid',1)->where('pay_time','gt',$pre_month)->where('pay_time','lt',$now_month)->value('sum(pay_price)'); + $first_line['m_price'] = [ + 'data' => $now_month_order_p > 0 ? $now_month_order_p : 0, + 'percent' => abs($now_month_order_p - $pre_month_order_p), + 'is_plus' => $now_month_order_p - $pre_month_order_p > 0 ? 1 : ($now_month_order_p - $pre_month_order_p == 0 ? -1 : 0) + ]; + + //新粉丝->日 + $now_day_user = DB::name('User')->where('add_time','gt',$now_day)->count(); + $pre_day_user = DB::name('User')->where('add_time','gt',$pre_day)->where('add_time','lt',$now_day)->count(); + $pre_day_user = $pre_day_user ? $pre_day_user : 0; + $first_line['day'] = [ + 'data' => $now_day_user ? $now_day_user : 0, + 'percent' => abs($now_day_user - $pre_day_user), + 'is_plus' => $now_day_user - $pre_day_user > 0 ? 1 : ($now_day_user - $pre_day_user == 0 ? -1 : 0) + ]; + + //新粉丝->月 + $now_month_user = DB::name('User')->where('add_time','gt',$now_month)->count(); + $pre_month_user = DB::name('User')->where('add_time','gt',$pre_month)->where('add_time','lt',$now_month)->count(); + $first_line['month'] = [ + 'data' => $now_month_user ? $now_month_user : 0, + 'percent' => abs($now_month_user - $pre_month_user), + 'is_plus' => $now_month_user - $pre_month_user > 0 ? 1 : ($now_month_user - $pre_month_user == 0 ? -1 : 0) + ]; + + /*首页第二行统计*/ + $second_line['order_count_max'] = 50; //max最小为100 + for ($i=0; $i < 7; $i++) { + $time = strtotime('-'.$i.' day'); + $now_day_info = strtotime(date('Y-m-d',strtotime('-'.($i-1).' day'))); + $pre_day_info = strtotime(date('Y-m-d',strtotime('-'.$i.' day'))); + $order_count[$i]['y'] = date('Y',$time); + $order_count[$i]['m'] = date('m',$time); + $order_count[$i]['d'] = date('d',$time); + $order_count[$i]['count'] = StoreOrder::where('add_time','gt',$pre_day_info)->where('add_time','lt',$now_day_info)->count(); + $second_line['order_count_max'] = $second_line['order_count_max'] > $order_count[$i]['count'] ? $second_line['order_count_max'] : $order_count[$i]['count']; + } + $second_line['order_count'] = $order_count; + + //本月订单总数 + $now_order_info_c = StoreOrder::where('add_time','gt',$now_month)->count(); + $pre_order_info_c = StoreOrder::where('add_time','gt',$pre_month)->where('add_time','lt',$now_month)->count(); + $order_info['first'] = [ + 'data' => $now_order_info_c ? $now_order_info_c : 0, + 'percent' => abs($now_order_info_c - $pre_order_info_c), + 'is_plus' => $now_order_info_c - $pre_order_info_c > 0 ? 1 : ($now_order_info_c - $pre_order_info_c == 0 ? -1 : 0) + ]; + + //上月订单总数 + $second_now_month = strtotime(date('Y-m',strtotime('-1 month'))); + $second_pre_month = strtotime(date('Y-m',strtotime('-2 month'))); + $now_order_info_c = StoreOrder::where('add_time','gt',$pre_month)->where('add_time','lt',$now_month)->count(); + $pre_order_info_c = StoreOrder::where('add_time','gt',$second_pre_month)->where('add_time','lt',$second_now_month)->count(); + $order_info["second"] = [ + 'data' => $now_order_info_c ? $now_order_info_c : 0, + 'percent' => abs($now_order_info_c - $pre_order_info_c), + 'is_plus' => $now_order_info_c - $pre_order_info_c > 0 ? 1 : ($now_order_info_c - $pre_order_info_c == 0 ? -1 : 0) + ]; + $second_line['order_info'] = $order_info; + + /*首页第三行统计*/ + $third_line['order_count_max'] = 100; //max最小为100 + for ($x=0; $x < 30; $x++) { + $time = strtotime('-'.$x.' day'); + $now_day_info = strtotime(date('Y-m-d',strtotime('-'.($x-1).' day'))); + $pre_day_info = strtotime(date('Y-m-d',strtotime('-'.$x.' day'))); + $price_count[$x]['y'] = date('Y',$time); + $price_count[$x]['m'] = date('m',$time); + $price_count[$x]['d'] = date('d',$time); + $price_count[$x]['count'] = StoreOrder::where('paid',1)->where('pay_time','gt',$pre_day_info)->where('pay_time','lt',$now_day_info)->value('sum(pay_price)'); + $third_line['order_count_max'] = $third_line['order_count_max'] > $price_count[$x]['count'] ? $third_line['order_count_max'] : $price_count[$x]['count']; + } + $third_line['price_count'] = $price_count; + $this->assign([ + 'first_line' => $first_line, + 'second_line' => $second_line, + 'third_line' => $third_line, + 'topData' => $topData, + ]); + return $this->fetch(); + } + public function test(){ + UpgradeService::start(); + } +} + + diff --git a/application/admin/controller/Login.php b/application/admin/controller/Login.php new file mode 100644 index 00000000..d98ea6f4 --- /dev/null +++ b/application/admin/controller/Login.php @@ -0,0 +1,73 @@ +fetch(); + } + + /** + * 登录验证 + 验证码验证 + */ + public function verify(Request $request) + { + if(!$request->isPost()) return $this->failed('请登陆!'); + list($account,$pwd,$verify) = UtilService::postMore([ + 'account','pwd','verify' + ],$request,true); + //检验验证码 + if(!captcha_check($verify)) return $this->failed('验证码错误,请重新输入'); + $error = Session::get('login_error')?:['num'=>0,'time'=>time()]; + if($error['num'] >=5 && $error['time'] < strtotime('+ 5 minutes')) + return $this->failed('错误次数过多,请稍候再试!'); + //检验帐号密码 + $res = SystemAdmin::login($account,$pwd); + if($res){ + Session::set('login_error',null); + return $this->redirect(Url::build('Index/index')); + }else{ + $error['num'] += 1; + $error['time'] = time(); + Session::set('login_error',$error); + return $this->failed(SystemAdmin::getErrorInfo('用户名错误,请重新输入')); + } + } + + public function captcha() + { + ob_clean(); + $captcha = new \think\captcha\Captcha([ + 'codeSet'=>'0123456789', + 'length'=>4, + 'fontSize'=>30 + ]); + return $captcha->entry(); + } + + /** + * 退出登陆 + */ + public function logout() + { + SystemAdmin::clearLoginInfo(); + $this->redirect('Login/index'); + } +} \ No newline at end of file diff --git a/application/admin/controller/agent/AgentManage.php b/application/admin/controller/agent/AgentManage.php new file mode 100644 index 00000000..fcac6257 --- /dev/null +++ b/application/admin/controller/agent/AgentManage.php @@ -0,0 +1,96 @@ +request); + $this->assign([ + 'where'=>$where, + ]); + $limitTimeList = [ + 'today'=>implode(' - ',[date('Y/m/d'),date('Y/m/d',strtotime('+1 day'))]), + 'week'=>implode(' - ',[ + date('Y/m/d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)), + date('Y-m-d', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600)) + ]), + 'month'=>implode(' - ',[date('Y/m').'/01',date('Y/m').'/'.date('t')]), + 'quarter'=>implode(' - ',[ + date('Y').'/'.(ceil((date('n'))/3)*3-3+1).'/01', + date('Y').'/'.(ceil((date('n'))/3)*3).'/'.date('t',mktime(0,0,0,(ceil((date('n'))/3)*3),1,date('Y'))) + ]), + 'year'=>implode(' - ',[ + date('Y').'/01/01',date('Y/m/d',strtotime(date('Y').'/01/01 + 1year -1 day')) + ]) + ]; + $uidAll = UserModel::getAll($where); + $this->assign(compact('limitTimeList','uidAll')); + $this->assign(UserModel::systemPage($where)); + return $this->fetch(); + } + + /** + * 一级推荐人页面 + * @return mixed + */ + public function stair($uid = ''){ + if($uid == '') return $this->failed('参数错误'); + $list = User::alias('u') + ->where('u.spread_uid',$uid) + ->field('u.avatar,u.nickname,u.now_money,u.add_time,u.uid') + ->where('u.status',1) + ->order('u.add_time DESC') + ->select() + ->toArray(); + $this->assign('list',$list); + return $this->fetch(); + } + + /** + * 个人资金详情页面 + * @return mixed + */ + public function now_money($uid = ''){ + if($uid == '') return $this->failed('参数错误'); + $list = UserBill::where('uid',$uid)->where('category','now_money') + ->field('mark,pm,number,add_time') + ->where('status',1)->order('add_time DESC')->select()->toArray(); + foreach ($list as &$v){ + $v['add_time'] = date('Y-m-d H:i:s',$v['add_time']); + } + $this->assign('list',$list); + return $this->fetch(); + } +} diff --git a/application/admin/controller/article/Article.php b/application/admin/controller/article/Article.php new file mode 100644 index 00000000..ab3b403a --- /dev/null +++ b/application/admin/controller/article/Article.php @@ -0,0 +1,192 @@ +request); + if($cid) + $where['cid'] = $cid; + else + $where['cid'] = ''; + $this->assign('where',$where); + $where['merchant'] = 0;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1 + $this->assign('cid',$cid); + $this->assign('cate',ArticleCategoryModel::getTierList()); + $this->assign(ArticleModel::getAll($where)); + return $this->fetch(); + } + + /** + * 展示页面 添加和删除 + * @return mixed + */ + public function create(){ + $id = input('id'); + $cid = input('cid'); + $news = array(); + $news['id'] = ''; + $news['image_input'] = ''; + $news['title'] = ''; + $news['author'] = ''; + $news['is_banner'] = ''; + $news['is_hot'] = ''; + $news['content'] = ''; + $news['synopsis'] = ''; + $news['url'] = ''; + $news['cid'] = array(); + if($id){ + $news = ArticleModel::where('n.id',$id)->alias('n')->field('n.*,c.content')->join('ArticleContent c','c.nid=n.id')->find(); + if(!$news) return $this->failedNotice('数据不存在!'); + $news['cid'] = explode(',',$news['cid']); + } + $all = array(); + $select = 0; + if(!$cid) + $cid = ''; + else { + if($id){ + $all = ArticleCategoryModel::where('id',$cid)->where('hidden','neq',0)->column('id,title'); + $select = 1; + }else{ + $all = ArticleCategoryModel::where('id',$cid)->column('id,title'); + $select = 1; + } + + } + if(empty($all)){ + $select = 0; + $list = ArticleCategoryModel::getTierList(); + $all = []; + foreach ($list as $menu){ + $all[$menu['id']] = $menu['html'].$menu['title']; + } + } + $this->assign('all',$all); + $this->assign('news',$news); + $this->assign('cid',$cid); + $this->assign('select',$select); + return $this->fetch(); + } + + /** + * 上传图文图片 + * @return \think\response\Json + */ + public function upload_image(){ + $res = Upload::Image($_POST['file'],'wechat/image/'.date('Ymd')); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,'',5); + if(!$res->status) return Json::fail($res->error); + return Json::successful('上传成功!',['url'=>$res->filePath]); + } + + /** + * 添加和修改图文 + * @param Request $request + * @return \think\response\Json + */ + public function add_new(Request $request){ + $post = $request->post(); + $data = Util::postMore([ + ['id',0], + ['cid',[]], + 'title', + 'author', + 'image_input', + 'content', + 'synopsis', + 'share_title', + 'share_synopsis', + ['visit',0], + ['sort',0], + 'url', + ['status',1],],$request); + $data['cid'] = implode(',',$data['cid']); + $content = $data['content']; + unset($data['content']); + if($data['id']){ + $id = $data['id']; + unset($data['id']); + ArticleModel::beginTrans(); + $res1 = ArticleModel::edit($data,$id,'id'); + $res2 = ArticleModel::setContent($id,$content); + if($res1 && $res2) + $res = true; + else + $res =false; +// dump($res); +// exit(); + ArticleModel::checkTrans($res); + if($res) + return Json::successful('修改图文成功!',$id); + else + return Json::fail('修改图文失败!',$id); + }else{ + $data['add_time'] = time(); + $data['admin_id'] = $this->adminId; + ArticleModel::beginTrans(); + $res1 = ArticleModel::set($data); + $res2 = false; + if($res1) + $res2 = ArticleModel::setContent($res1->id,$content); + if($res1 && $res2) + $res = true; + else + $res =false; + ArticleModel::checkTrans($res); + if($res) + return Json::successful('添加图文成功!',$res1->id); + else + return Json::successful('添加图文失败!',$res1->id); + } + } + + /** + * 删除图文 + * @param $id + * @return \think\response\Json + */ + public function delete($id) + { + $res = ArticleModel::del($id); + if(!$res) + return Json::fail('删除失败,请稍候再试!'); + else + return Json::successful('删除成功!'); + } + + public function merchantIndex(){ + $where = Util::getMore([ + ['title',''] + ],$this->request); + $this->assign('where',$where); + $where['cid'] = input('cid'); + $where['merchant'] = 1;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1 + $this->assign(ArticleModel::getAll($where)); + return $this->fetch(); + } +} \ No newline at end of file diff --git a/application/admin/controller/article/ArticleCategory.php b/application/admin/controller/article/ArticleCategory.php new file mode 100644 index 00000000..a446e233 --- /dev/null +++ b/application/admin/controller/article/ArticleCategory.php @@ -0,0 +1 @@ +request); $this->assign('where',$where); $this->assign(ArticleCategoryModel::systemPage($where)); return $this->fetch(); } /** * 添加分类管理 * */ public function create(){ $f = array(); $f[] = Form::select('pid','父级id')->setOptions(function(){ $list = ArticleCategoryModel::getTierList(); $menus[] = ['value'=>0,'label'=>'顶级分类']; foreach ($list as $menu){ $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['title']]; } return $menus; })->filterable(1); $f[] = Form::input('title','分类名称'); $f[] = Form::input('intr','分类简介')->type('textarea'); // $f[] = Form::select('new_id','图文列表')->setOptions(function(){ // $list = ArticleModel::getNews(); // $options = []; // foreach ($list as $id=>$roleName){ // $options[] = ['label'=>$roleName,'value'=>$id]; // } // return $options; // })->multiple(1)->filterable(1); $f[] = Form::frameImageOne('image','分类图片',Url::build('admin/widget.images/index',array('fodder'=>'image')))->icon('image'); $f[] = Form::number('sort','排序',0); $f[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']]); $form = Form::make_post_form('添加分类',$f,Url::build('save')); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * s上传图片 * */ public function upload(){ $res = Upload::image('file','article'); $thumbPath = Upload::thumb($res->dir); if($res->status == 200) return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); else return Json::fail($res->error); } /** * 保存分类管理 * */ public function save(Request $request){ $data = Util::postMore([ 'title', 'pid', 'intr', ['new_id',[]], ['image',[]], ['sort',0], 'status',],$request); if(!$data['title']) return Json::fail('请输入分类名称'); if(count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张'); if($data['sort'] < 0) return Json::fail('排序不能是负数'); $data['add_time'] = time(); $data['image'] = $data['image'][0]; $new_id = $data['new_id']; unset($data['new_id']); $res = ArticleCategoryModel::set($data); if(!ArticleModel::saveBatchCid($res['id'],implode(',',$new_id))) return Json::fail('文章列表添加失败'); return Json::successful('添加分类成功!'); } /** * 修改分类 * */ public function edit($id){ if(!$id) return $this->failed('参数错误'); $article = ArticleCategoryModel::get($id)->getData(); if(!$article) return Json::fail('数据不存在!'); $f = array(); $f[] = Form::select('pid','父级id',(string)$article['pid'])->setOptions(function(){ $list = ArticleCategoryModel::getTierList(); $menus[] = ['value'=>0,'label'=>'顶级分类']; foreach ($list as $menu){ $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['title']]; } return $menus; })->filterable(1); $f[] = Form::input('title','分类名称',$article['title']); $f[] = Form::input('intr','分类简介',$article['intr'])->type('textarea'); // $f[] = Form::select('new_id','图文列表',explode(',',$article->getData('new_id')))->setOptions(function(){ // $list = ArticleModel::getNews(); // $options = []; // foreach ($list as $id=>$roleName){ // $options[] = ['label'=>$roleName,'value'=>$id]; // } // return $options; // })->multiple(1)->filterable(1); $f[] = Form::frameImageOne('image','分类图片',Url::build('admin/widget.images/index',array('fodder'=>'image')),$article['image'])->icon('image'); $f[] = Form::number('sort','排序',0); $f[] = Form::radio('status','状态',$article['status'])->options([['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']]); $form = Form::make_post_form('编辑分类',$f,Url::build('update',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } public function update(Request $request, $id) { $data = Util::postMore([ 'pid', 'title', 'intr', // ['new_id',[]], ['image',[]], ['sort',0], 'status',],$request); if(!$data['title']) return Json::fail('请输入分类名称'); if(count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张'); if($data['sort'] < 0) return Json::fail('排序不能是负数'); $data['image'] = $data['image'][0]; if(!ArticleCategoryModel::get($id)) return Json::fail('编辑的记录不存在!'); // if(!ArticleModel::saveBatchCid($id,implode(',',$data['new_id']))) return Json::fail('文章列表添加失败'); // unset($data['new_id']); ArticleCategoryModel::edit($data,$id); return Json::successful('修改成功!'); } /** * 删除分类 * */ public function delete($id) { $res = ArticleCategoryModel::delArticleCategory($id); if(!$res) return Json::fail(ArticleCategoryModel::getErrorInfo('删除失败,请稍候再试!')); else return Json::successful('删除成功!'); } } \ No newline at end of file diff --git a/application/admin/controller/finance/Finance.php b/application/admin/controller/finance/Finance.php new file mode 100644 index 00000000..cfd78a86 --- /dev/null +++ b/application/admin/controller/finance/Finance.php @@ -0,0 +1,230 @@ + + * Date: 2018/6/14 下午5:25 + */ + +namespace app\admin\controller\finance; + +use app\admin\controller\AuthController; +use app\admin\model\user\UserBill; +use service\JsonService as Json; +use app\admin\model\finance\FinanceModel; +use service\UtilService as Util; +use service\FormBuilder as Form; +//use FormBuilder\Form; +use service\HookService; +use think\Url; +use app\admin\model\user\User; +use app\admin\model\user\UserExtract; + +/** + * 微信充值记录 + * Class UserRecharge + * @package app\admin\controller\user + */ +class Finance extends AuthController + +{ + + /** + * 显示操作记录 + */ + public function index(){ + + //创建form + $form = Form::create('/save.php',[ + Form::input('goods_name','商品名称') + ,Form::input('goods_name1','password')->type('password') + ,Form::input('goods_name2','textarea')->type('textarea') + ,Form::input('goods_name3','email')->type('email') + ,Form::input('goods_name4','date')->type('date') + ,Form::cityArea('address','cityArea',[ + '陕西省','西安市' + ]) + ,Form::dateRange('limit_time','dateRange', + strtotime('- 10 day'), + time() + ) + ,Form::dateTime('add_time','dateTime') + ,Form::color('color','color','#ff0000') + ,Form::checkbox('checkbox','checkbox',[1])->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']]) + ,Form::date('riqi','date','2018-03-1') + ,Form::dateTimeRange('dateTimeRange','区间时间段') + ,Form::year('year','year') + ,Form::month('month','month') + ,Form::frame('frame','frame','http://baidu.com') + ,Form::frameInputs('month','frameInputs','http://baidu.com') + ,Form::frameFiles('month1','frameFiles','http://baidu.com') + ,Form::frameImages('month2','frameImages','http://baidu.com') + ,Form::frameInputOne('month3','frameInputOne','http://baidu.com') + ,Form::frameFileOne('month4','frameFileOne','http://baidu.com') + ,Form::frameImageOne('month5','frameImageOne','http://baidu.com') + ,Form::hidden('month6','hidden') + ,Form::number('month7','number') +// ,Form::input input输入框,其他type: text类型Form::text,password类型Form::password,textarea类型Form::textarea,url类型Form::url,email类型Form::email,date类型Form::idate + ,Form::radio('month8','radio')->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']]) + ,Form::rate('month9','rate') + ,Form::select('month10','select')->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']]) + ,Form::selectMultiple('month11','selectMultiple') + ,Form::selectOne('month12','selectOne') + ,Form::slider('month13','slider',2) + ,Form::sliderRange('month23','sliderRange',2,13) + ,Form::switches('month14','区间时间段') + ,Form::timePicker('month15','区间时间段') + ,Form::time('month16','区间时间段') + ,Form::timeRange('month17','区间时间段') +// ,Form::upload('month','区间时间段') +// ,Form::uploadImages('month','区间时间段') +// ,Form::uploadFiles('month','区间时间段') +// ,Form::uploadImageOne('month','区间时间段') +// ,Form::uploadFileOne('month','区间时间段') + + ]); + $html = $form->setMethod('get')->setTitle('编辑商品')->view(); + echo $html; + + } + /** + * 显示资金记录 + */ + public function bill(){ + $list=UserBill::where('type','not in',['gain','system_sub','deduction','sign']) + ->where('category','not in','integral') + ->field(['title','type']) + ->group('type') + ->distinct(true) + ->select() + ->toArray(); + $this->assign('selectList',$list); + return $this->fetch(); + } + /** + * 显示资金记录ajax列表 + */ + public function billlist(){ + $where = Util::getMore([ + ['start_time',''], + ['end_time',''], + ['nickname',''], + ['limit',20], + ['page',1], + ['type',''], + ]); + return Json::successlayui(FinanceModel::getBillList($where)); + } + /** + *保存资金监控的excel表格 + */ + public function save_bell_export(){ + $where = Util::getMore([ + ['start_time',''], + ['end_time',''], + ['nickname',''], + ['type',''], + ]); + FinanceModel::SaveExport($where); + } +// /** +// * 显示佣金记录 +// */ +// public function commission_list(){ +// +// //创建form +// $form = Form::create('/save.php',[ +// Form::input('goods_name','商品名称') +// ,Form::input('goods_name1','password')->type('password') +// ,Form::input('goods_name3','email')->type('email') +// ,Form::input('goods_name4','date')->type('date') +// ,Form::cityArea('address','cityArea',[ +// '陕西省','西安市' +// ]) +// ,Form::dateRange('limit_time','dateRange', +// strtotime('- 10 day'), +// time() +// ) +// ,Form::dateTime('add_time','dateTime') +// ,Form::color('color','color','#ff0000') +// ,Form::checkbox('checkbox','checkbox',[1])->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']]) +// ,Form::date('riqi','date','2018-03-1') +// ,Form::dateTimeRange('dateTimeRange','区间时间段') +// ,Form::year('year','year') +// +// ,Form::hidden('month6','hidden') +// ,Form::number('month7','number') +// +// +// ]); +// $rule = $form->setMethod('post')->setTitle('编辑商品')->getRules(); +// $action = Url::build('save'); +// $this->assign(compact('form','rule','action')); +// return $this->fetch(); +// } + /** + * 显示佣金记录 + */ + public function commission_list(){ + $this->assign('is_layui',true); + return $this->fetch(); + } + /** + * 佣金记录异步获取 + */ + public function get_commission_list(){ + $get=Util::getMore([ + ['page',1], + ['limit',20], + ['nickname',''], + ['price_max',''], + ['price_min',''], + ['order',''] + ]); + return Json::successlayui(User::getCommissionList($get)); + } + /** + * 保存excel表格 + */ + public function save_export(){ + $get=Util::getMore([ + ['page',1], + ['limit',20], + ['nickname',''], + ['price_max',''], + ['price_min',''], + ['order',''] + ]); + User::setUserWhere($get,true); + } + /** + * 显示操作记录 + */ + public function index3(){ + + } + /** + * 佣金详情 + */ + public function content_info($uid=''){ + if($uid=='') return $this->failed('缺少参数'); + $this->assign('userinfo',User::getUserinfo($uid)); + $this->assign('uid',$uid); + return $this->fetch(); + } + /** + * 佣金提现记录个人列表 + */ + public function get_extract_list($uid=''){ + if($uid=='') return Json::fail('缺少参数'); + $where=Util::getMore([ + ['page',1], + ['limit',20], + ['start_time',''], + ['end_time',''], + ['nickname',''] + ]); + return Json::successlayui(UserBill::getExtrctOneList($where,$uid)); + } + +} + diff --git a/application/admin/controller/finance/UserExtract.php b/application/admin/controller/finance/UserExtract.php new file mode 100644 index 00000000..91fce337 --- /dev/null +++ b/application/admin/controller/finance/UserExtract.php @@ -0,0 +1,105 @@ +request); + $this->assign('where',$where); + $this->assign(UserExtractModel::systemPage($where)); + return $this->fetch(); + } + public function edit($id){ + if(!$id) return $this->failed('数据不存在'); + $UserExtract = UserExtractModel::get($id); + if(!$UserExtract) return JsonService::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('real_name','姓名',$UserExtract['real_name']); + $f[] = Form::number('extract_price','提现金额',$UserExtract['extract_price'])->precision(2); + if($UserExtract['extract_type']=='alipay'){ + $f[] = Form::input('alipay_code','支付宝账号',$UserExtract['alipay_code']); + }else{ + $f[] = Form::input('bank_code','银行卡号',$UserExtract['bank_code']); + $f[] = Form::input('bank_address','开户行',$UserExtract['bank_address']); + } + $f[] = Form::input('mark','备注',$UserExtract['mark'])->type('textarea'); + $form = Form::make_post_form('编辑',$f,Url::build('update',array('id'=>$id))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + + } + public function update(Request $request,$id) + { + $UserExtract = UserExtractModel::get($id); + if(!$UserExtract) return JsonService::fail('数据不存在!'); + if($UserExtract['extract_type']=='alipay'){ + $data = Util::postMore([ + 'real_name', + 'mark', + 'extract_price', + 'alipay_code', + ],$request); + if(!$data['real_name']) return JsonService::fail('请输入姓名'); + if($data['extract_price']<=-1) return JsonService::fail('请输入提现金额'); + if(!$data['alipay_code']) return JsonService::fail('请输入支付宝账号'); + }else{ + $data = Util::postMore([ + 'real_name', + 'extract_price', + 'mark', + 'bank_code', + 'bank_address', + ],$request); + if(!$data['real_name']) return JsonService::fail('请输入姓名'); + if($data['extract_price']<=-1) return JsonService::fail('请输入提现金额'); + if(!$data['bank_code']) return JsonService::fail('请输入银行卡号'); + if(!$data['bank_address']) return JsonService::fail('请输入开户行'); + } + if(!UserExtractModel::edit($data,$id)) + return JsonService::fail(UserExtractModel::getErrorInfo('修改失败')); + else + return JsonService::successful('修改成功!'); + } + public function fail(Request $request,$id) + { + if(!UserExtractModel::be(['id'=>$id,'status'=>0])) return JsonService::fail('操作记录不存在或状态错误!'); + $fail_msg =$request->post(); + $res = UserExtractModel::changeFail($id,$fail_msg['message']); + if($res){ + return JsonService::successful('操作成功!'); + }else{ + return JsonService::fail('操作失败!'); + } + } + public function succ($id) + { + if(!UserExtractModel::be(['id'=>$id,'status'=>0])) + return JsonService::fail('操作记录不存在或状态错误!'); + UserExtractModel::beginTrans(); + $res = UserExtractModel::changeSuccess($id); + if($res){ + return JsonService::successful('操作成功!'); + }else{ + return JsonService::fail('操作失败!'); + } + } +} \ No newline at end of file diff --git a/application/admin/controller/finance/UserRecharge.php b/application/admin/controller/finance/UserRecharge.php new file mode 100644 index 00000000..d122d5c6 --- /dev/null +++ b/application/admin/controller/finance/UserRecharge.php @@ -0,0 +1,89 @@ +request); + $this->assign('where',$where); + $this->assign(UserRechargeModel::systemPage($where)); + return $this->fetch(); + } + + /**退款 + * @param $id + * @return mixed|void + */ + public function edit($id){ + if(!$id) return $this->failed('数据不存在'); + $UserRecharge = UserRechargeModel::get($id); + if(!$UserRecharge) return Json::fail('数据不存在!'); + if($UserRecharge['paid'] == 1){ + $f = array(); + $f[] = Form::input('order_id','退款单号',$UserRecharge->getData('order_id'))->disabled(1); + $f[] = Form::number('refund_price','退款金额',$UserRecharge->getData('price'))->precision(2)->min(0)->max($UserRecharge->getData('price')); + $form = Form::make_post_form('编辑',$f,Url::build('updateRefundY',array('id'=>$id))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + else return Json::fail('数据不存在!'); + } + + /**退款更新 + * @param Request $request + * @param $id + */ + public function updateRefundY(Request $request, $id){ + $data = Util::postMore([ + 'refund_price', + ],$request); + if(!$id) return $this->failed('数据不存在'); + $UserRecharge = UserRechargeModel::get($id); + if(!$UserRecharge) return Json::fail('数据不存在!'); + if($UserRecharge['price'] == $UserRecharge['refund_price']) return Json::fail('已退完支付金额!不能再退款了'); + if(!$data['refund_price']) return Json::fail('请输入退款金额'); + $refund_price = $data['refund_price']; + $data['refund_price'] = bcadd($data['refund_price'],$UserRecharge['refund_price'],2); + $bj = bccomp((float)$UserRecharge['price'],(float)$data['refund_price'],2); + if($bj < 0) return Json::fail('退款金额大于支付金额,请修改退款金额'); + $refund_data['pay_price'] = $UserRecharge['price']; + $refund_data['refund_price'] = $refund_price; + try{ + HookService::listen('user_recharge_refund',$UserRecharge['order_id'],$refund_data,true,PaymentBehavior::class); + }catch(\Exception $e){ + return Json::fail($e->getMessage()); + } + UserRechargeModel::edit($data,$id); + WechatTemplateService::sendTemplate(WechatUserWap::uidToOpenid($UserRecharge['uid']),WechatTemplateService::ORDER_REFUND_STATUS, [ + 'first'=>'亲,您充值的金额已退款,本次退款'. + $data['refund_price'].'金额', + 'keyword1'=>$UserRecharge['order_id'], + 'keyword2'=>$UserRecharge['price'], + 'keyword3'=>date('Y-m-d H:i:s',$UserRecharge['add_time']), + 'remark'=>'点击查看订单详情' + ],Url::build('wap/My/balance','',true,true)); + UserBill::expend('系统退款',$UserRecharge['uid'],'now_money','user_recharge_refund',$refund_price,$id,$UserRecharge['price'],'退款给用户'.$refund_price.'元'); + return Json::successful('退款成功!'); + } +} diff --git a/application/admin/controller/order/StoreOrder.php b/application/admin/controller/order/StoreOrder.php new file mode 100644 index 00000000..91efae55 --- /dev/null +++ b/application/admin/controller/order/StoreOrder.php @@ -0,0 +1 @@ +request); $limitTimeList = [ 'yesterday'=>implode(' - ',[date('Y/m/d',strtotime('-1 day')),date('Y/m/d')]), 'today'=>implode(' - ',[date('Y/m/d'),date('Y/m/d',strtotime('+1 day'))]), 'week'=>implode(' - ',[ date('Y/m/d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)), date('Y-m-d', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600)) ]), 'month'=>implode(' - ',[date('Y/m').'/01',date('Y/m').'/'.date('t')]), 'quarter'=>implode(' - ',[ date('Y').'/'.(ceil((date('n'))/3)*3-3+1).'/01', date('Y').'/'.(ceil((date('n'))/3)*3).'/'.date('t',mktime(0,0,0,(ceil((date('n'))/3)*3),1,date('Y'))) ]), 'year'=>implode(' - ',[ date('Y').'/01/01',date('Y/m/d',strtotime(date('Y').'/01/01 + 1year -1 day')) ]) ]; $seven_day = strtotime(date('Y-m-d',strtotime('-7 day')));//前7天时间戳 $orderTopData = []; //最近7天下单数量 $orderTopData['sevenDayOrderNum'] = StoreOrderModel::where('add_time','>=',$seven_day)->count(); //代付款数量 $orderTopData['noPayNum'] = StoreOrderModel::where('paid',0)->count(); //代发货数量 $orderTopData['noDeliveryNum'] = StoreOrderModel::where('status',0)->where('refund_status',0)->where('paid',1)->count(); //退换货数量 $orderTopData['yesRefundNum'] = StoreOrderModel::where('refund_status','IN','1,2')->count(); //7天收入 $orderTopData['sevenDayPrice'] = StoreOrderModel::where('pay_time','>=',$seven_day)->where('paid',1)->count(); $this->assign(StoreOrderModel::systemPage($where,$this->adminId)); $this->assign('price',StoreOrderModel::getOrderPrice($where)); $this->assign(compact('where','limitTimeList','orderTopData')); return $this->fetch(); } public function orderchart(){ $where = Util::getMore([ ['status',''], ['real_name',''], ['is_del',0], ['data',''], ['combination_id',''], ['export',0], ['order','id desc'] ],$this->request); $limitTimeList = [ 'today'=>implode(' - ',[date('Y/m/d'),date('Y/m/d',strtotime('+1 day'))]), 'week'=>implode(' - ',[ date('Y/m/d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)), date('Y-m-d', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600)) ]), 'month'=>implode(' - ',[date('Y/m').'/01',date('Y/m').'/'.date('t')]), 'quarter'=>implode(' - ',[ date('Y').'/'.(ceil((date('n'))/3)*3-3+1).'/01', date('Y').'/'.(ceil((date('n'))/3)*3).'/'.date('t',mktime(0,0,0,(ceil((date('n'))/3)*3),1,date('Y'))) ]), 'year'=>implode(' - ',[ date('Y').'/01/01',date('Y/m/d',strtotime(date('Y').'/01/01 + 1year -1 day')) ]) ]; if($where['data'] == '') $where['data'] = $limitTimeList['today']; $orderCount = [ urlencode('未支付')=>StoreOrderModel::getOrderWhere($where,StoreOrderModel::statusByWhere(0))->count(), urlencode('未发货')=>StoreOrderModel::getOrderWhere($where,StoreOrderModel::statusByWhere(1))->count(), urlencode('待收货')=>StoreOrderModel::getOrderWhere($where,StoreOrderModel::statusByWhere(2))->count(), urlencode('待评价')=>StoreOrderModel::getOrderWhere($where,StoreOrderModel::statusByWhere(3))->count(), urlencode('交易完成')=>StoreOrderModel::getOrderWhere($where,StoreOrderModel::statusByWhere(4))->count(), urlencode('退款中')=>StoreOrderModel::getOrderWhere($where,StoreOrderModel::statusByWhere(-1))->count(), urlencode('已退款')=>StoreOrderModel::getOrderWhere($where,StoreOrderModel::statusByWhere(-2))->count() ]; $model = StoreOrderModel::getOrderWhere($where,new StoreOrderModel())->field('sum(total_num) total_num,count(*) count,sum(total_price) total_price,sum(refund_price) refund_price,from_unixtime(add_time,\'%Y-%m-%d\') add_time') ->group('from_unixtime(add_time,\'%Y-%m-%d\')'); $orderPrice = $model->select()->toArray(); $orderDays = []; $orderCategory = [ ['name'=>'商品数','type'=>'line','data'=>[]], ['name'=>'订单数','type'=>'line','data'=>[]], ['name'=>'订单金额','type'=>'line','data'=>[]], ['name'=>'退款金额','type'=>'line','data'=>[]] ]; foreach ($orderPrice as $price){ $orderDays[] = $price['add_time']; $orderCategory[0]['data'][] = $price['total_num']; $orderCategory[1]['data'][] = $price['count']; $orderCategory[2]['data'][] = $price['total_price']; $orderCategory[3]['data'][] = $price['refund_price']; } $this->assign(StoreOrderModel::systemPage($where,$this->adminId)); $this->assign('price',StoreOrderModel::getOrderPrice($where)); $this->assign(compact('limitTimeList','where','orderCount','orderPrice','orderDays','orderCategory')); return $this->fetch(); } /** * 修改支付金额等 * @param $id * @return mixed|\think\response\Json|void */ public function edit($id) { if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); $f = array(); $f[] = Form::input('order_id','订单编号',$product->getData('order_id'))->disabled(1); $f[] = Form::number('total_price','商品总价',$product->getData('total_price'))->min(0); $f[] = Form::number('total_postage','原始邮费',$product->getData('total_postage'))->min(0); $f[] = Form::number('pay_price','实际支付金额',$product->getData('pay_price'))->min(0); $f[] = Form::number('pay_postage','实际支付邮费',$product->getData('pay_postage')); $f[] = Form::number('gain_integral','赠送积分',$product->getData('gain_integral')); // $f[] = Form::radio('status','状态',$product->getData('status'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); $form = Form::make_post_form('修改订单',$f,Url::build('update',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** 修改订单提交更新 * @param Request $request * @param $id */ public function update(Request $request, $id) { $data = Util::postMore([ 'order_id', 'total_price', 'total_postage', 'pay_price', 'pay_postage', 'gain_integral', ],$request); if($data['total_price'] <= 0) return Json::fail('请输入商品总价'); if($data['pay_price'] <= 0) return Json::fail('请输入实际支付金额'); $data['order_id'] = StoreOrderModel::changeOrderId($data['order_id']); StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_edit',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'order_edit','修改商品总价为:'.$data['total_price'].' 实际支付金额'.$data['pay_price']); return Json::successful('修改成功!'); } /** * 送货 * @param $id * send */ public function delivery($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1 && $product['status'] == 0) { $f = array(); $f[] = Form::input('delivery_name','送货人姓名')->required('送货人姓名不能为空','required:true;'); $f[] = Form::input('delivery_id','送货人电话')->required('请输入正确电话号码','telephone'); $form = Form::make_post_form('修改订单',$f,Url::build('updateDelivery',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } else return Json::fail('数据不存在!'); } public function updateDelivery(Request $request, $id){ $data = Util::postMore([ 'delivery_name', 'delivery_id', ],$request); $data['delivery_type'] = 'send'; if(!$data['delivery_name']) return Json::fail('请输入送货人姓名'); if(!(int)$data['delivery_id']) return Json::fail('请输入送货人电话号码'); else if(!preg_match("/^1[3456789]{1}\d{9}$/",$data['delivery_id'])) return Json::fail('请输入正确的送货人电话号码'); $data['status'] = 1; StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_delivery',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'delivery','已配送 发货人:'.$data['delivery_name'].' 发货人电话:'.$data['delivery_id']); return Json::successful('修改成功!'); } /** * 发货 * @param $id * express */ public function deliver_goods($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1 && $product['status'] == 0){ $f = array(); $f[] = Form::select('delivery_name','快递公司')->setOptions(function(){ $list = db('express')->where('is_show',1)->order('sort DESC')->column('id,name'); $menus = []; foreach ($list as $k=>$v){ $menus[] = ['value'=>$v,'label'=>$v]; } return $menus; })->filterable(1); $f[] = Form::input('delivery_id','快递单号')->number(1); $form = Form::make_post_form('修改订单',$f,Url::build('updateDeliveryGoods',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } else return Json::fail('数据不存在!'); } /**发货保存 * @param Request $request * @param $id */ public function updateDeliveryGoods(Request $request, $id){ $data = Util::postMore([ 'delivery_name', 'delivery_id', ],$request); $data['delivery_type'] = 'express'; if(!$data['delivery_name']) return Json::fail('请选择快递公司'); if(!$data['delivery_id']) return Json::fail('请输入快递单号'); $data['status'] = 1; StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_delivery_goods',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'delivery_goods','已发货 快递公司:'.$data['delivery_name'].' 快递单号:'.$data['delivery_id']); return Json::successful('修改成功!'); } /** * 修改状态为已收货 * @param $id * @return \think\response\Json|void */ public function take_delivery($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['status'] == 2) return Json::fail('不能重复收货!'); if($product['paid'] == 1 && $product['status'] == 1) $data['status'] = 2; else if($product['pay_type'] == 'offline') $data['status'] = 2; else return Json::fail('请先发货或者送货!'); if(!StoreOrderModel::edit($data,$id)) return Json::fail(StoreOrderModel::getErrorInfo('收货失败,请稍候再试!')); else{ try{ HookService::listen('store_product_order_take_delivery',$data,$id,false,StoreProductBehavior::class); }catch (Exception $e){ return Json::fail($e->getMessage()); } StoreOrderStatus::setStatus($id,'take_delivery','已收货'); return Json::successful('收货成功!'); } } /** * 修改退款状态 * @param $id * @return \think\response\Json|void */ public function refund_y($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1){ $f = array(); $f[] = Form::input('order_id','退款单号',$product->getData('order_id'))->disabled(1); $f[] = Form::number('refund_price','退款金额',$product->getData('pay_price'))->precision(2)->min(0.01); $f[] = Form::radio('type','状态',1)->options([['label'=>'直接退款','value'=>1],['label'=>'退款后,返回原状态','value'=>2]]); $form = Form::make_post_form('退款处理',$f,Url::build('updateRefundY',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } else return Json::fail('数据不存在!'); } /**退款处理 * @param Request $request * @param $id */ public function updateRefundY(Request $request, $id){ $data = Util::postMore([ 'refund_price', ['type',1], ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['pay_price'] == $product['refund_price']) return Json::fail('已退完支付金额!不能再退款了'); if(!$data['refund_price']) return Json::fail('请输入退款金额'); $refund_price = $data['refund_price']; $data['refund_price'] = bcadd($data['refund_price'],$product['refund_price'],2); $bj = bccomp((float)$product['pay_price'],(float)$data['refund_price'],2); if($bj < 0) return Json::fail('退款金额大于支付金额,请修改退款金额'); if($data['type'] == 1){ $data['refund_status'] = 2; }else if($data['type'] == 2){ $data['refund_status'] = 0; } $type = $data['type']; unset($data['type']); $refund_data['pay_price'] = $product['pay_price']; $refund_data['refund_price'] = $refund_price; if($product['pay_type'] == 'weixin'){ if($product['is_channel']){ try{ HookService::listen('routine_pay_order_refund',$product['order_id'],$refund_data,true,PaymentBehavior::class); }catch(\Exception $e){ return Json::fail($e->getMessage()); } }else{ try{ HookService::listen('wechat_pay_order_refund',$product['order_id'],$refund_data,true,PaymentBehavior::class); }catch(\Exception $e){ return Json::fail($e->getMessage()); } } }else if($product['pay_type'] == 'yue'){ ModelBasic::beginTrans(); $res1 = User::bcInc($product['uid'],'now_money',$refund_price,'uid'); $res2 = $res2 = UserBill::income('商品退款',$product['uid'],'now_money','pay_product_refund',$refund_price,$product['id'],$product['pay_price'],'订单退款到余额'.floatval($refund_price).'元'); try{ HookService::listen('store_order_yue_refund',$product,$refund_data,false,StoreProductBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } $res = $res1 && $res2; ModelBasic::checkTrans($res); if(!$res) return Json::fail('余额退款失败!'); } $resEdit = StoreOrderModel::edit($data,$id); if($resEdit){ $data['type'] = $type; if($data['type'] == 1) StorePink::setRefundPink($id); HookService::afterListen('store_product_order_refund_y',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'refund_price','退款给用户'.$refund_price.'元'); return Json::successful('修改成功!'); }else{ StoreOrderStatus::setStatus($id,'refund_price','退款给用户'.$refund_price.'元失败'); return Json::successful('修改失败!'); } } public function order_info($oid = '') { if(!$oid || !($orderInfo = StoreOrderModel::get($oid))) return $this->failed('订单不存在!'); $userInfo = User::getUserInfo($orderInfo['uid']); if($userInfo['spread_uid']){ $spread = User::where('uid',$userInfo['spread_uid'])->value('nickname'); }else{ $spread =''; } $this->assign(compact('orderInfo','userInfo','spread')); return $this->fetch(); } public function express($oid = '') { if(!$oid || !($order = StoreOrderModel::get($oid))) return $this->failed('订单不存在!'); if($order['delivery_type'] != 'express' || !$order['delivery_id']) return $this->failed('该订单不存在快递单号!'); $cacheName = $order['order_id'].$order['delivery_id']; $result = CacheService::get($cacheName,null); if($result === null){ $result = Express::query($order['delivery_id']); if(is_array($result) && isset($result['result']) && isset($result['result']['deliverystatus']) && $result['result']['deliverystatus'] >= 3) $cacheTime = 0; else $cacheTime = 1800; CacheService::set($cacheName,$result,$cacheTime); } $this->assign([ 'order'=>$order, 'express'=>$result ]); return $this->fetch(); } /** * 修改配送信息 * @param $id * @return mixed|\think\response\Json|void */ public function distribution($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); $f = array(); $f[] = Form::input('order_id','退款单号',$product->getData('order_id'))->disabled(1); if($product['delivery_type'] == 'send'){ $f[] = Form::input('delivery_name','送货人姓名',$product->getData('delivery_name')); $f[] = Form::input('delivery_id','送货人电话',$product->getData('delivery_id')); }else if($product['delivery_type'] == 'express'){ $f[] = Form::select('delivery_name','快递公司',$product->getData('delivery_name'))->setOptions(function (){ $list = db('express')->where('is_show',1)->column('id,name'); $menus = []; foreach ($list as $k=>$v){ $menus[] = ['value'=>$v,'label'=>$v]; } return $menus; }); $f[] = Form::input('delivery_id','快递单号',$product->getData('delivery_id')); } $form = Form::make_post_form('配送信息',$f,Url::build('updateDistribution',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /**修改配送信息 * @param Request $request * @param $id */ public function updateDistribution(Request $request, $id){ $data = Util::postMore([ 'delivery_name', 'delivery_id', ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['delivery_type'] == 'send'){ if(!$data['delivery_name']) return Json::fail('请输入送货人姓名'); if(!(int)$data['delivery_id']) return Json::fail('请输入送货人电话号码'); else if(!preg_match("/^1[3456789]{1}\d{9}$/",$data['delivery_id'])) return Json::fail('请输入正确的送货人电话号码'); }else if($product['delivery_type'] == 'express'){ if(!$data['delivery_name']) return Json::fail('请选择快递公司'); if(!$data['delivery_id']) return Json::fail('请输入快递单号'); } StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_distribution',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'distribution','修改发货信息为'.$data['delivery_name'].'号'.$data['delivery_id']); return Json::successful('修改成功!'); } /** * 修改退款状态 * @param $id * @return mixed|\think\response\Json|void */ public function refund_n($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); $f[] = Form::input('order_id','退款单号',$product->getData('order_id'))->disabled(1); $f[] = Form::input('refund_reason','退款原因')->type('textarea'); $form = Form::make_post_form('退款',$f,Url::build('updateRefundN',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /**不退款原因 * @param Request $request * @param $id */ public function updateRefundN(Request $request, $id){ $data = Util::postMore([ 'refund_reason', ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if(!$data['refund_reason']) return Json::fail('请输入退款原因'); $data['refund_status'] = 0; StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_refund_n',$data['refund_reason'],$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'refund_n','不退款原因:'.$data['refund_reason']); return Json::successful('修改成功!'); } /** * 立即支付 * @param $id */ public function offline($id){ $res = StoreOrderModel::updateOffline($id); if($res){ try{ HookService::listen('store_product_order_offline',$id,false,StoreProductBehavior::class); }catch (Exception $e){ return Json::fail($e->getMessage()); } StoreOrderStatus::setStatus($id,'offline','线下付款'); return Json::successful('修改成功!'); }else{ return Json::fail('修改失败!'); } } /** * 修改积分和金额 * @param $id * @return mixed|\think\response\Json|void */ public function integral_back($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1){ $f[] = Form::input('order_id','退款单号',$product->getData('order_id'))->disabled(1); $f[] = Form::number('back_integral','退积分')->min(0); $form = Form::make_post_form('退积分',$f,Url::build('updateIntegralBack',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); }else{ return Json::fail('参数错误!'); } return $this->fetch('public/form-builder'); } /** 退积分保存 * @param Request $request * @param $id */ public function updateIntegralBack(Request $request, $id){ $data = Util::postMore([ 'back_integral', ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($data['back_integral'] <= 0) return Json::fail('请输入积分'); if($product['use_integral'] == $product['back_integral']) return Json::fail('已退完积分!不能再积分了'); $back_integral = $data['back_integral']; $data['back_integral'] = bcadd($data['back_integral'],$product['back_integral'],2); $bj = bccomp((float)$product['use_integral'],(float)$data['back_integral'],2); if($bj < 0) return Json::fail('退积分大于支付积分,请修改退积分'); ModelBasic::beginTrans(); $res1 = User::bcInc($product['uid'],'integral',$back_integral,'uid'); $res2 = UserBill::income('商品退积分',$product['uid'],'integral','pay_product_integral_back',$back_integral,$product['id'],$product['pay_price'],'订单退积分'.floatval($back_integral).'积分到用户积分'); try{ HookService::listen('store_order_integral_back',$product,$back_integral,false,StoreProductBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } $res = $res1 && $res2; ModelBasic::checkTrans($res); if(!$res) return Json::fail('退积分失败!'); StoreOrderModel::edit($data,$id); StoreOrderStatus::setStatus($id,'integral_back','商品退积分:'.$data['back_integral']); return Json::successful('退积分成功!'); } public function remark(Request $request){ $data = Util::postMore(['id','remark'],$request); if(!$data['id']) return Json::fail('参数错误!'); if($data['remark'] == '') return Json::fail('请输入要备注的内容!'); $id = $data['id']; unset($data['id']); StoreOrderModel::edit($data,$id); return Json::successful('备注成功!'); } public function order_status($oid){ if(!$oid) return $this->failed('数据不存在'); $this->assign(StoreOrderStatus::systemPage($oid)); return $this->fetch(); } } \ No newline at end of file diff --git a/application/admin/controller/order/StoreOrderPink.php b/application/admin/controller/order/StoreOrderPink.php new file mode 100644 index 00000000..a10a36f6 --- /dev/null +++ b/application/admin/controller/order/StoreOrderPink.php @@ -0,0 +1 @@ +request); $this->assign('where',$where); $this->assign(StorePink::systemPage($where)); return $this->fetch(); } public function order_pink($id){ if(!$id) return $this->failed('数据不存在'); $StorePink = StorePink::getPinkUserOne($id); if(!$StorePink) return $this->failed('数据不存在!'); $list = StorePink::getPinkMember($id); $list[] = $StorePink; $this->assign('list',$list); return $this->fetch(); } /** * 修改支付金额等 * @param $id * @return mixed|\think\response\Json|void */ public function edit($id) { if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); $this->assign([ 'title'=>'修改订单','rules'=>$this->read($id)->getContent(), 'action'=>Url::build('update',array('id'=>$id)) ]); return $this->fetch('public/common_form'); } public function read($id) { if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); FormBuilder::text('order_id','订单编号',$product->getData('order_id'))->readonly(); FormBuilder::number('total_price','商品总价',$product->getData('total_price'))->min(0); FormBuilder::number('total_postage','原始邮费',$product->getData('total_postage'))->min(0); FormBuilder::number('pay_price','实际支付金额',$product->getData('pay_price'))->min(0); FormBuilder::number('pay_postage','实际支付邮费',$product->getData('pay_postage'))->min(0); FormBuilder::number('gain_integral','赠送积分',$product->getData('gain_integral'))->min(0); return FormBuilder::builder(); } public function update(Request $request, $id) { $data = Util::postMore([ 'order_id', 'total_price', 'total_postage', 'pay_price', 'pay_postage', 'gain_integral', ],$request); if($data['total_price'] <= 0) return Json::fail('请输入商品总价'); if($data['pay_price'] <= 0) return Json::fail('请输入实际支付金额'); $data['order_id'] = StoreOrderModel::changeOrderId($data['order_id']); StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_edit',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'order_edit','修改商品总价为:'.$data['total_price'].' 实际支付金额'.$data['pay_price']); return Json::successful('修改成功!'); } /** * 送货 * @param $id * send */ public function delivery($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1 && $product['status'] == 0) { $this->assign([ 'title' => '送货信息', 'rules' => $this->readDelivery($id)->getContent(), 'action' => Url::build('updateDelivery', array('id' => $id)) ]); return $this->fetch('public/common_form'); } else return Json::fail('数据不存在!'); } public function readDelivery($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); FormBuilder::text('delivery_name','送货人姓名'); FormBuilder::text('delivery_id','送货人电话')->number(); return FormBuilder::builder(); } public function updateDelivery(Request $request, $id){ $data = Util::postMore([ 'delivery_name', 'delivery_id', ],$request); $data['delivery_type'] = 'send'; if(!$data['delivery_name']) return Json::fail('请输入送货人姓名'); if(!(int)$data['delivery_id']) return Json::fail('请输入送货人电话号码'); else if(!preg_match("/^1[3456789]{1}\d{9}$/",$data['delivery_id'])) return Json::fail('请输入正确的送货人电话号码'); $data['status'] = 1; StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_delivery',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'delivery','已配送 发货人:'.$data['delivery_name'].' 发货人电话:'.$data['delivery_id']); return Json::successful('修改成功!'); } /** * 发货 * @param $id * express */ public function deliver_goods($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1 && $product['status'] == 0){ $this->assign([ 'title'=>'发货信息','rules'=>$this->readDeliveryGoods($id)->getContent(), 'action'=>Url::build('updateDeliveryGoods',array('id'=>$id)) ]); return $this->fetch('public/common_form'); } else return Json::fail('数据不存在!'); } public function readDeliveryGoods($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); FormBuilder::select('delivery_name','快递公司',function(){ $list = db('express')->where('is_show',1)->column('id,name'); $menus = []; foreach ($list as $k=>$v){ $menus[] = ['value'=>$v,'label'=>$v]; } return $menus; })->filterable(); FormBuilder::text('delivery_id','快递单号'); return FormBuilder::builder(); } public function updateDeliveryGoods(Request $request, $id){ $data = Util::postMore([ 'delivery_name', 'delivery_id', ],$request); $data['delivery_type'] = 'express'; if(!$data['delivery_name']) return Json::fail('请选择快递公司'); if(!$data['delivery_id']) return Json::fail('请输入快递单号'); $data['status'] = 1; StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_delivery_goods',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'delivery_goods','已发货 快递公司:'.$data['delivery_name'].' 快递单号:'.$data['delivery_id']); return Json::successful('修改成功!'); } /** * 修改状态为已收货 * @param $id * @return \think\response\Json|void */ public function take_delivery($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['status'] == 2) return Json::fail('不能重复收货!'); if($product['paid'] == 1 && $product['status'] == 1) $data['status'] = 2; else if($product['pay_type'] == 'offline') $data['status'] = 2; else return Json::fail('请先发货或者送货!'); if(!StoreOrderModel::edit($data,$id)) return Json::fail(StoreOrderModel::getErrorInfo('收货失败,请稍候再试!')); else{ try{ HookService::listen('store_product_order_take_delivery',$data,$id,false,StoreProductBehavior::class); }catch (Exception $e){ return Json::fail($e->getMessage()); } StoreOrderStatus::setStatus($id,'take_delivery','已收货'); return Json::successful('收货成功!'); } } /** * 修改退款状态 * @param $id * @return \think\response\Json|void */ public function refund_y($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1){ $this->assign([ 'title'=>'退款','rules'=>$this->readRefundY($id)->getContent(), 'action'=>Url::build('updateRefundY',array('id'=>$id)) ]); return $this->fetch('public/common_form'); } else return Json::fail('数据不存在!'); } public function readRefundY($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); FormBuilder::text('order_id','退款单号',$product->getData('order_id'))->readonly(); FormBuilder::number('refund_price','退款金额',$product->getData('pay_price'))->min(0); FormBuilder::radio('type','状态',[['label'=>'直接退款','value'=>1],['label'=>'退款后,返回原状态','value'=>2]],1); return FormBuilder::builder(); } public function updateRefundY(Request $request, $id){ $data = Util::postMore([ 'refund_price', ['type',1], ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['pay_price'] == $product['refund_price']) return Json::fail('已退完支付金额!不能再退款了'); if(!$data['refund_price']) return Json::fail('请输入退款金额'); $refund_price = $data['refund_price']; $data['refund_price'] = bcadd($data['refund_price'],$product['refund_price'],2); $bj = bccomp((float)$product['pay_price'],(float)$data['refund_price'],2); if($bj < 0) return Json::fail('退款金额大于支付金额,请修改退款金额'); if($data['type'] == 1){ $data['refund_status'] = 2; }else if($data['type'] == 2){ $data['refund_status'] = 0; } $type = $data['type']; unset($data['type']); $refund_data['pay_price'] = $product['pay_price']; $refund_data['refund_price'] = $refund_price; if($product['pay_type'] == 'weixin'){ try{ HookService::listen('wechat_pay_order_refund',$product['order_id'],$refund_data,true,PaymentBehavior::class); }catch(\Exception $e){ return Json::fail($e->getMessage()); } }else if($product['pay_type'] == 'yue'){ ModelBasic::beginTrans(); $res1 = User::bcInc($product['uid'],'now_money',$refund_price,'uid'); $res2 = $res2 = UserBill::income('商品退款',$product['uid'],'now_money','pay_product_refund',$refund_price,$product['id'],$product['pay_price'],'订单退款到余额'.floatval($refund_price).'元'); try{ HookService::listen('store_order_yue_refund',$product,$refund_data,false,StoreProductBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } $res = $res1 && $res2; ModelBasic::checkTrans($res); if(!$res) return Json::fail('余额退款失败!'); } StoreOrderModel::edit($data,$id); $data['type'] = $type; HookService::afterListen('store_product_order_refund_y',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'refund_price','退款给用户'.$refund_price.'元'); return Json::successful('修改成功!'); } /** * 修改配送信息 * @param $id * @return mixed|\think\response\Json|void */ public function distribution($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); $this->assign([ 'title'=>'配送信息','rules'=>$this->readDistribution($id)->getContent(), 'action'=>Url::build('updateDistribution',array('id'=>$id)) ]); return $this->fetch('public/common_form'); } public function readDistribution($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['delivery_type'] == 'send'){ FormBuilder::text('delivery_name','送货人姓名',$product->getData('delivery_name')); FormBuilder::text('delivery_id','送货人电话',$product->getData('delivery_id'))->number(); }else if($product['delivery_type'] == 'express'){ FormBuilder::select('delivery_name','快递公司',function(){ $list = db('express')->where('is_show',1)->column('id,name'); $menus = []; foreach ($list as $k=>$v){ $menus[] = ['value'=>$v,'label'=>$v]; } return $menus; },$product->getData('delivery_name'))->filterable(); FormBuilder::text('delivery_id','快递单号',$product->getData('delivery_id')); } return FormBuilder::builder(); } public function updateDistribution(Request $request, $id){ $data = Util::postMore([ 'delivery_name', 'delivery_id', ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['delivery_type'] == 'send'){ if(!$data['delivery_name']) return Json::fail('请输入送货人姓名'); if(!(int)$data['delivery_id']) return Json::fail('请输入送货人电话号码'); else if(!preg_match("/^1[3456789]{1}\d{9}$/",$data['delivery_id'])) return Json::fail('请输入正确的送货人电话号码'); }else if($product['delivery_type'] == 'express'){ if(!$data['delivery_name']) return Json::fail('请选择快递公司'); if(!$data['delivery_id']) return Json::fail('请输入快递单号'); } StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_distribution',$data,$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'distribution','修改发货信息为'.$data['delivery_name'].'号'.$data['delivery_id']); return Json::successful('修改成功!'); } /** * 修改退款状态 * @param $id * @return mixed|\think\response\Json|void */ public function refund_n($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); $this->assign([ 'title'=>'退款','rules'=>$this->readRefundN($id)->getContent(), 'action'=>Url::build('updateRefundN',array('id'=>$id)) ]); return $this->fetch('public/common_form'); } public function readRefundN($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); FormBuilder::text('order_id','退款单号',$product->getData('order_id'))->readonly(); FormBuilder::textarea('refund_reason','退款原因'); return FormBuilder::builder(); } public function updateRefundN(Request $request, $id){ $data = Util::postMore([ 'refund_reason', ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if(!$data['refund_reason']) return Json::fail('请输入退款原因'); $data['refund_status'] = 0; StoreOrderModel::edit($data,$id); HookService::afterListen('store_product_order_refund_n',$data['refund_reason'],$id,false,StoreProductBehavior::class); StoreOrderStatus::setStatus($id,'refund_n','不退款原因:'.$data['refund_reason']); return Json::successful('修改成功!'); } /** * 立即支付 * @param $id */ public function offline($id){ $res = StoreOrderModel::updateOffline($id); if($res){ try{ HookService::listen('store_product_order_offline',$id,false,StoreProductBehavior::class); }catch (Exception $e){ return Json::fail($e->getMessage()); } StoreOrderStatus::setStatus($id,'offline','线下付款'); return Json::successful('修改成功!'); }else{ return Json::fail('修改失败!'); } } /** * 修改积分和金额 * @param $id * @return mixed|\think\response\Json|void */ public function integral_back($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($product['paid'] == 1){ $this->assign([ 'title'=>'退积分','rules'=>$this->readIntegralBack($id)->getContent(), 'action'=>Url::build('updateIntegralBack',array('id'=>$id)) ]); }else{ return Json::fail('参数错误!'); } return $this->fetch('public/common_form'); } public function readIntegralBack($id){ if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); FormBuilder::text('order_id','退积分单号',$product->getData('order_id'))->readonly(); FormBuilder::number('back_integral','退积分')->min(0); return FormBuilder::builder(); } public function updateIntegralBack(Request $request, $id){ $data = Util::postMore([ 'back_integral', ],$request); if(!$id) return $this->failed('数据不存在'); $product = StoreOrderModel::get($id); if(!$product) return Json::fail('数据不存在!'); if($data['back_integral'] <= 0) return Json::fail('请输入积分'); if($product['use_integral'] == $product['back_integral']) return Json::fail('已退完积分!不能再积分了'); $back_integral = $data['back_integral']; $data['back_integral'] = bcadd($data['back_integral'],$product['back_integral'],2); $bj = bccomp((float)$product['use_integral'],(float)$data['back_integral'],2); if($bj < 0) return Json::fail('退积分大于支付积分,请修改退积分'); ModelBasic::beginTrans(); $res1 = User::bcInc($product['uid'],'integral',$back_integral,'uid'); $res2 = UserBill::income('商品退积分',$product['uid'],'integral','pay_product_integral_back',$back_integral,$product['id'],$product['pay_price'],'订单退积分'.floatval($back_integral).'积分到用户积分'); try{ HookService::listen('store_order_integral_back',$product,$back_integral,false,StoreProductBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } $res = $res1 && $res2; ModelBasic::checkTrans($res); if(!$res) return Json::fail('退积分失败!'); StoreOrderModel::edit($data,$id); StoreOrderStatus::setStatus($id,'integral_back','商品退积分:'.$data['back_integral']); return Json::successful('退积分成功!'); } public function remark(Request $request){ $data = Util::postMore(['id','remark'],$request); if(!$data['id']) return Json::fail('参数错误!'); if($data['remark'] == '') return Json::fail('请输入要备注的内容!'); $id = $data['id']; unset($data['id']); StoreOrderModel::edit($data,$id); return Json::successful('备注成功!'); } public function order_status($oid){ if(!$oid) return $this->failed('数据不存在'); $this->assign(StoreOrderStatus::systemPage($oid)); return $this->fetch(); } } \ No newline at end of file diff --git a/application/admin/controller/record/Record.php b/application/admin/controller/record/Record.php new file mode 100644 index 00000000..d296f5c2 --- /dev/null +++ b/application/admin/controller/record/Record.php @@ -0,0 +1,604 @@ + + * Date: 2018/6/14 下午5:25 + */ + +namespace app\admin\controller\record; + +use app\admin\controller\AuthController; +use app\admin\model\store\StoreProduct; +use app\admin\model\order\StoreOrder; +use app\admin\model\ump\StoreBargain; +use app\admin\model\ump\StoreSeckill; +use app\admin\model\ump\StoreCombination; +use service\JsonService; +use service\UtilService as Util; +use app\admin\model\user\User; +use app\admin\model\user\UserBill; +use app\admin\model\user\UserExtract; +use app\admin\model\store\StoreCouponUser; +/** + * 微信充值记录 + * Class UserRecharge + * @package app\admin\controller\user + */ +class Record extends AuthController + +{ + + /** + * 显示操作记录 + */ + public function index(){ + + + } + /** + * 显示订单记录 + */ + public function chart_order(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + public function get_echarts_order(){ + $where=Util::getMore([ + ['type',''], + ['status',''], + ['data',''], + ]); + return JsonService::successful(StoreOrder::getEchartsOrder($where)); + } + /** + * 显示产品记录 + */ + public function chart_product(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 获取产品曲线图数据 + */ + public function get_echarts_product($type='',$data=''){ + return JsonService::successful(StoreProduct::getChatrdata($type,$data)); + + } + + /** + * 获取销量 + */ + public function get_echarts_maxlist($data=''){ + return JsonService::successful(StoreProduct::getMaxList(compact('data'))); + } + /** + * 获取利润 + */ + public function get_echarts_profity($data=''){ + return JsonService::successful(StoreProduct::ProfityTop10(compact('data'))); + } + /** + * 获取缺货列表 + */ + public function getLackList(){ + $where=Util::getMore([ + ['page',1], + ['limit',20], + ]); + return JsonService::successlayui(StoreProduct::getLackList($where)); + } + /** + * 表单快速修改 + */ + public function editField($id=''){ + $post=$this->request->post(); + StoreProduct::beginTrans(); + try{ + StoreProduct::edit($post,$id); + StoreProduct::commitTrans(); + return JsonService::successful('修改成功'); + }catch (\Exception $e){ + StoreProduct::rollbackTrans(); + return JsonService::fail($e->getMessage()); + } + } + //获取差评 + public function getnegativelist(){ + $where=Util::getMore([ + ['page',1], + ['limit',10], + ]); + return JsonService::successful(StoreProduct::getnegativelist($where)); + } + /** + * 获取退货 + */ + public function getTuiPriesList(){ + return JsonService::successful(StoreProduct::TuiProductList()); + } + //营销统计 + /** + * 显示积分统计 + */ + public function chart_score(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 获取积分头部信息 + */ + public function getScoreBadgeList($data=''){ + return JsonService::successful(UserBill::getScoreBadgeList(compact('data'))); + } + /** + * 获取积分曲线图和柱状图 + */ + public function getScoreCurve($data='',$limit=20){ + return JsonService::successful(UserBill::getScoreCurve(compact('data','limit'))); + } + /** + * 显示优惠券统计 + */ + public function chart_coupon(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 获取优惠劵头部信息 + */ + public function getCouponBadgeList($data=''){ + return JsonService::successful(StoreCouponUser::getCouponBadgeList(compact('data'))); + } + /** + * 获取优惠劵数据图表 + */ + public function getConponCurve($data=''){ + return JsonService::successful(StoreCouponUser::getConponCurve(compact('data'))); + } + /** + * 显示拼团统计 + */ + public function chart_combination(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 显示砍价统计 + */ + public function chart_bargain(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 显示秒杀统计 + */ + public function chart_seckill(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + //财务统计 + /** + * 显示反佣统计 + */ + public function chart_rebate(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + //获取用户返佣柱状图 + public function getUserBillBrokerage($data=''){ + return JsonService::successful(UserBill::getUserBillChart(compact('data'))); + } + //获取用户返佣头部信息 + public function getRebateBadge($data=''){ + return JsonService::successful(UserBill::getRebateBadge(compact('data'))); + } + //获得 返佣列表,带分页 + public function getFanList($page=1,$limit=20){ + return JsonService::successful(UserBill::getFanList(compact('page','limit'))); + } + //获得 返佣总次数 + public function getFanCount(){ + return JsonService::successful(UserBill::getFanCount()); + } + /** + * 显示充值统计 + */ + public function chart_recharge(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 获取用户充值柱状图和曲线图 + */ + public function getEchartsRecharge($data=''){ + return JsonService::successful(UserBill::getEchartsRecharge(compact('data'))); + } + /** + * 显示提现统计 + */ + public function chart_cash(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + //获取提现头部信息 + public function getExtractHead($data=''){ + return JsonService::successful(UserExtract::getExtractHead(compact('data'))); + } + //会员统计 + /** + * 显示用户统计 + */ + public function user_chart(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 获取头部信息 + * + * 人数 增长 分销人数 分销增长 + */ + public function getBadgeList($data='',$is_promoter='',$status=''){ + return JsonService::successful(User::getBadgeList(compact('data','is_promoter','status'))); + } + /* + * 获取用户增长曲线图 + * + */ + public function getUserChartList($data='',$is_promoter='',$status=''){ + return JsonService::successful(User::getUserChartList(compact('data','is_promoter','status'))); + } + /* + * 获取提现分布图和提现人数金额曲线图 + * + */ + public function getExtractData($data=''){ + return JsonService::successful(UserExtract::getExtractList(compact('data'))); + } + /* + * 分销会员统计 + * + */ + public function user_distribution_chart(){ + $limit=10; + $top10list=User::getUserDistributionTop10List($limit); + $this->assign([ + 'is_layui'=>true, + 'limit'=>$limit, + 'year'=>getMonth('y'), + 'commissionList'=>$top10list['commission'], + 'extractList'=>$top10list['extract'], + ]); + return $this->fetch(); + } + /* + * 获取分销会员统计会员头部详情 + * + */ + public function getDistributionBadgeList($data=''){ + return JsonService::successful(User::getDistributionBadgeList(compact('data'))); + } + /* + * 获取分销会员统计图表数据 + * + * $data 时间范围 + * + */ + public function getUserDistributionChart($data=''){ + return JsonService::successful(User::getUserDistributionChart(compact('data'))); + } + /** + * 会员业务 + */ + public function user_business_chart(){ + $limit=10; + $top10list=User::getUserTop10List($limit); + $this->assign([ + 'is_layui'=>true, + 'limit'=>$limit, + 'year'=>getMonth('y'), + 'integralList'=>$top10list['integral'], + 'moneyList'=>$top10list['now_money'], + 'shopcountList'=>$top10list['shopcount'], + 'orderList'=>$top10list['order'], + 'lastorderList'=>$top10list['lastorder'] + ]); + return $this->fetch(); + } + /* + * 获取 会员业务的 + * 购物会员统计 + * 分销商业务人数和提现人数统计 + * 分销商业务佣金和提现金额统计 + * 曲线图 + * $data 时间 + */ + public function getUserBusinessChart($data=''){ + return JsonService::successful(User::getUserBusinessChart(compact('data'))); + } + /* + * 获取 会员业务 + * 会员总余额 分销商总佣金 分销商总佣金余额 分销商总提现佣金 本月分销商业务佣金 本月分销商佣金提现金额 + * 上月分销商业务佣金 上月分销商佣金提现金额 + * $where 查询条件 + * + * return array + */ + public function getUserBusinesHeade($data){ + return JsonService::successful(User::getUserBusinesHeade(compact('data'))); + } + /** + * 显示用户属性统计 + */ + public function user_attr(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + /** + * 获取用户属性统计 + */ + public function getEchartsData($data=''){ + return JsonService::successful(User::getEchartsData(compact('data'))); + } + //排行榜 + /** + * 显示产品排行榜 + */ + public function ranking_saleslists(){ + $this->assign([ + 'is_layui'=>true, + ]); + return $this->fetch(); + } + /* + *获取产品排行 带分页 + */ + public function getSaleslists($start_time='',$end_time='',$title='',$page=1,$limit=20){ + return JsonService::successlayui(StoreProduct::getSaleslists(compact('start_time','end_time','title','page','limit'))); + } + /* + *生成表格,并下载 + */ + public function save_product_export($start_time='',$end_time='',$title=''){ + return JsonService::successlayui(StoreProduct::SaveProductExport(compact('start_time','end_time','title'))); + } + /* + *获取单个商品的详情 + */ + public function product_info($id=''){ + if($id=='') $this->failed('缺少商品id'); + if(!StoreProduct::be(['id'=>$id])) return $this->failed('商品不存在!'); + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y'), + 'id'=>$id, + ]); + return $this->fetch(); + } + /* + *获取单个商品的详情头部信息 + */ + public function getProductBadgeList($id='',$data=''){ + return JsonService::successful(StoreProduct::getProductBadgeList($id,$data)); + } + /* + *获取单个商品的销售曲线图 + */ + public function getProductCurve($id='',$data='',$limit=20){ + return JsonService::successful(StoreProduct::getProductCurve(compact('id','data','limit'))); + } + /* + *获取单个商品的销售总条数 + */ + public function getProductCount($id,$data=''){ + return JsonService::successful(StoreProduct::setWhere(compact('data')) + ->where('a.product_id',$id) + ->join('user c','c.uid=a.uid') + ->where('a.is_pay',1) + ->count()); + } + /* + *获取单个商品的销售列表 + */ + public function getSalelList($data='',$id=0,$page=1,$limit=20){ + return JsonService::successful(StoreProduct::getSalelList(compact('data','id','page','limit'))); + } + /** + * 显示反佣排行榜 + */ + public function ranking_commission(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + public function getcommissionlist($page=1,$limit=20){ + return JsonService::successful(UserExtract::where('status',1) + ->field(['real_name','extract_price','balance']) + ->order('extract_price desc') + ->page($page,$limit) + ->select()); + } + public function getmonthcommissionlist($page=1,$limit=20){ + return JsonService::successful(UserExtract::where('status',1) + ->whereTime('add_time','month') + ->field(['real_name','extract_price','balance']) + ->order('extract_price desc') + ->page($page,$limit) + ->select()); + } + //获取佣金返现总条数 + public function getCommissonCount(){ + return JsonService::successful(UserExtract::where('status',1)->count()); + } + //获取本月佣金返现条数 + public function getMonthCommissonCount(){ + return JsonService::successful(UserExtract::where('status',1)->whereTime('add_time','month')->count()); + } + /** + * 显示积分排行榜 + */ + public function ranking_point(){ + $this->assign([ + 'is_layui'=>true, + 'year'=>getMonth('y') + ]); + return $this->fetch(); + } + //获取所有积分排行总人数 + public function getPountCount(){ + return JsonService::successful(User::where(['status'=>1])->where('integral','neq',0)->count()); + } + //获取积分排行列表 + public function getpointList($page=1,$limit=20){ + return JsonService::successful(($list=User::where(['status'=>1]) + ->where('integral','neq',0) + ->field(['nickname','integral']) + ->order('integral desc') + ->page($page,$limit) + ->select()) && count($list) ? $list->toArray():[]); + } + //获取本月积分排行别表 + public function getMonthpountList($page=1,$limit=20){ + return JsonService::successful(($list=User::where('status',1) + ->where('integral','neq',0) + ->whereTime('add_time','month') + ->order('integral desc') + ->field(['nickname','integral']) + ->page($page,$limit) + ->select()) && count($list) ? $list->toArray():[]); + } + public function getMonthPountCount(){ + return JsonService::successful(User::where('status',1)->where('integral','neq',0)->whereTime('add_time','month')->count()); + } + /** + * + * 显示下级会员排行榜 + */ + public function ranking_lower(){ + echo " 复购率 复购增长率 活跃度 活跃率 分销总金额 增长率 消费会员 非消费会员 消费排行榜 积分排行榜 余额排行榜 分销总金额排行榜 分销人数排行榜 分销余额排行榜 购物金额排行榜 购物次数排行榜 提现排行榜 "; + } + /** + * 获取砍价产品曲线图数据 + */ + public function get_mark_echarts_product($type='',$data='',$model = 0){ + if(!$model) return JsonService::successful(StoreBargain::getChatrdata($type,$data)); + if($model) return JsonService::successful(StoreSeckill::getChatrdata($type,$data)); + } + /** + * 获取拼团产品曲线图数据 + */ + public function get_combination_echarts_product($type='',$data=''){ + return JsonService::successful(StoreCombination::getChatrdata($type,$data)); + } + /* + * 获取拼团销量 + */ + public function get_combination_maxlist($data=''){ + return JsonService::successful(StoreCombination::getMaxList(compact('data'))); + } + /* + * 拼团盈利 + */ + public function get_combination_profity($data=''){ + return JsonService::successful(StoreCombination::ProfityTop10(compact('data'))); + } + /* + * 拼团退货 + */ + public function get_combination_refund_list(){ + $where = Util::getMore([ + ['page',1], + ['limit',20], + ]); + return JsonService::successlayui(StoreCombination::getBargainRefundList($where)); + } + /** + * 获取销量 + */ + public function get_mark_echarts_maxlist($data='',$model = 0){ + if(!$model) return JsonService::successful(StoreBargain::getMaxList(compact('data'))); + if($model) return JsonService::successful(StoreSeckill::getMaxList(compact('data'))); + } + + /** + * 获取利润 + */ + public function get_mark_echarts_profity($data='',$model = 0){ + if(!$model) return JsonService::successful(StoreBargain::ProfityTop10(compact('data'))); + if($model) return JsonService::successful(StoreSeckill::ProfityTop10(compact('data'))); + } + /** + * 获取补货的砍价产品 + */ + public function get_mark_lack_list($model = 0){ + $where = Util::getMore([ + ['page',1], + ['limit',20], + ]); + if(!$model) return JsonService::successlayui(StoreBargain::getLackList($where)); + if($model) return JsonService::successlayui(StoreSeckill::getLackList($where)); + } + /** + * 获取砍价产品的评论 + */ + public function get_mark_negative_list($model = 0){ + $where = Util::getMore([ + ['page',1], + ['limit',20], + ]); + if(!$model) return JsonService::successlayui(StoreBargain::getNegativeList($where)); + if($model) return JsonService::successlayui(StoreSeckill::getNegativeList($where)); + } + /** + * 获取砍价产品的退货 + */ + public function get_mark_bargain_refund_list($model = 0){ + $where = Util::getMore([ + ['page',1], + ['limit',20], + ]); + if(!$model) return JsonService::successlayui(StoreBargain::getBargainRefundList($where)); + if($model) return JsonService::successlayui(StoreSeckill::getBargainRefundList($where)); + } + + + +} + diff --git a/application/admin/controller/record/StoreStatistics.php b/application/admin/controller/record/StoreStatistics.php new file mode 100644 index 00000000..32e89e16 --- /dev/null +++ b/application/admin/controller/record/StoreStatistics.php @@ -0,0 +1,83 @@ +request); + $where['date']=$this->request->param('date'); + $where['data']=$this->request->param('data'); + $where['export']=$this->request->param('export'); + $trans=StatisticsModel::trans();//最近交易 + $seckill=StatisticsModel::getSeckill($where);//秒杀商品 + $ordinary=StatisticsModel::getOrdinary($where);//普通商品 + $pink=StatisticsModel::getPink($where);//拼团商品 + $recharge=StatisticsModel::getRecharge($where);//充值 + $extension=StatisticsModel::getExtension($where);//推广金 + $orderCount = [ + urlencode('微信支付')=>StatisticsModel::getTimeWhere($where,StatisticsModel::statusByWhere('weixin'))->count(), + urlencode('余额支付')=>StatisticsModel::getTimeWhere($where,StatisticsModel::statusByWhere('yue'))->count(), + urlencode('线下支付')=>StatisticsModel::getTimeWhere($where,StatisticsModel::statusByWhere('offline'))->count(), + ]; + $Statistic = [ + ['name'=>'营业额','type'=>'line','data'=>[]], + ['name'=>'支出','type'=>'line','data'=>[]], + ['name'=>'盈利','type'=>'line','data'=>[]], + ]; + $orderinfos=StatisticsModel::getOrderInfo($where); + $orderinfo=$orderinfos['orderinfo']; + $orderDays=[]; + if (empty($orderinfo)){ + $orderDays[]=date('Y-m-d',time()); + $Statistic[0]['data'][] = 0; + $Statistic[1]['data'][] = 0; + $Statistic[2]['data'][] = 0; + } + foreach($orderinfo as $info){ + $orderDays[]=$info['pay_time']; + $Statistic[0]['data'][] = $info['total_price']+$info['pay_postage']; + $Statistic[1]['data'][] = $info['coupon_price']+$info['deduction_price']+$info['cost']; + $Statistic[2]['data'][] = ($info['total_price']+$info['pay_postage'])-($info['coupon_price']+$info['deduction_price']+$info['cost']); + } + $price=$orderinfos['price']+$orderinfos['postage']; + $cost=$orderinfos['deduction']+$orderinfos['coupon']+$orderinfos['cost']; + $Consumption=StatisticsModel::getConsumption($where)['number']; + $header=[ + ['name'=>'总营业额', 'class'=>'fa-line-chart', 'value'=>'¥'.$price, 'color'=>'red'], + ['name'=>'总支出', 'class'=>'fa-area-chart', 'value'=>'¥'.($cost+$extension), 'color'=>'lazur'], + ['name'=>'总盈利', 'class'=>'fa-bar-chart', 'value'=>'¥'.bcsub($price,$cost,0), 'color'=>'navy'], + ['name'=>'新增消费', 'class'=>'fa-pie-chart', 'value'=>'¥'.($Consumption==0?0:$Consumption), 'color'=>'yellow'] + ]; + $data=[ + ['value'=>$orderinfos['cost'], 'name'=>'商品成本'], + ['value'=>$orderinfos['coupon'], 'name'=>'优惠券抵扣'], + ['value'=>$orderinfos['deduction'], 'name'=>'积分抵扣'], + ['value'=>$extension, 'name'=>'推广人佣金'] + ]; + + $this->assign(StatisticsModel::systemTable($where)); + $this->assign(compact('where','trans','orderCount','orderPrice','orderDays','header','Statistic','ordinary','pink','recharge','data','seckill')); + $this->assign('price',StatisticsModel::getOrderPrice($where)); + + return $this->fetch(); + } +} \ No newline at end of file diff --git a/application/admin/controller/routine/RoutineTemplate.php b/application/admin/controller/routine/RoutineTemplate.php new file mode 100644 index 00000000..7db5d68a --- /dev/null +++ b/application/admin/controller/routine/RoutineTemplate.php @@ -0,0 +1,116 @@ +request); + $this->assign('where',$where); + $this->assign(RoutineTemplateModel::SystemPage($where)); + return $this->fetch(); + } + + /** + * 添加模板消息 + * @return mixed + */ + public function create() + { + $f = array(); + $f[] = Form::input('tempkey','模板编号'); + $f[] = Form::input('tempid','模板ID'); + $f[] = Form::input('name','模板名'); + $f[] = Form::input('content','回复内容')->type('textarea'); + $f[] = Form::radio('status','状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + $form = Form::make_post_form('添加模板消息',$f,Url::build('save')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + public function save(Request $request) + { + $data = Util::postMore([ + 'tempkey', + 'tempid', + 'name', + 'content', + ['status',0] + ],$request); + if($data['tempkey'] == '') return Json::fail('请输入模板编号'); + if($data['tempkey'] != '' && RoutineTemplateModel::be($data['tempkey'],'tempkey')) + return Json::fail('请输入模板编号已存在,请重新输入'); + if($data['tempid'] == '') return Json::fail('请输入模板ID'); + if($data['name'] == '') return Json::fail('请输入模板名'); + if($data['content'] == '') return Json::fail('请输入回复内容'); + $data['add_time'] = time(); + RoutineTemplateModel::set($data); + return Json::successful('添加模板消息成功!'); + } + + /** + * 编辑模板消息 + * @param $id + * @return mixed|\think\response\Json|void + */ + public function edit($id) + { + if(!$id) return $this->failed('数据不存在'); + $product = RoutineTemplateModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('tempkey','模板编号',$product->getData('tempkey'))->disabled(1); + $f[] = Form::input('name','模板名',$product->getData('name'))->disabled(1); + $f[] = Form::input('tempid','模板ID',$product->getData('tempid')); + $f[] = Form::radio('status','状态',$product->getData('status'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + $form = Form::make_post_form('编辑模板消息',$f,Url::build('update',compact('id'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'tempid', + ['status',0] + ],$request); + if($data['tempid'] == '') return Json::fail('请输入模板ID'); + if(!$id) return $this->failed('数据不存在'); + $product = RoutineTemplateModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + RoutineTemplateModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除模板消息 + * @param $id + * @return \think\response\Json + */ + public function delete($id) + { + if(!$id) return Json::fail('数据不存在!'); + if(!RoutineTemplateModel::del($id)) + return Json::fail(RoutineTemplateModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + +} \ No newline at end of file diff --git a/application/admin/controller/setting/SystemAdmin.php b/application/admin/controller/setting/SystemAdmin.php new file mode 100644 index 00000000..dfe95378 --- /dev/null +++ b/application/admin/controller/setting/SystemAdmin.php @@ -0,0 +1,212 @@ +adminInfo; + $where = Util::getMore([ + ['name',''], + ['roles',''], + ['level',bcadd($admin->level,1,0)] + ],$this->request); + $this->assign('where',$where); + $this->assign('role',SystemRole::getRole(bcadd($admin->level,1,0))); + $this->assign(AdminModel::systemPage($where)); + return $this->fetch(); + } + + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create() + { + $admin = $this->adminInfo; + $f = array(); + $f[] = Form::input('account','管理员账号'); + $f[] = Form::input('pwd','管理员密码')->type('password'); + $f[] = Form::input('conf_pwd','确认密码')->type('password'); + $f[] = Form::input('real_name','管理员姓名'); + $f[] = Form::select('roles','管理员身份')->setOptions(function ()use($admin){ + $list = SystemRole::getRole(bcadd($admin->level,1,0)); + $options = []; + foreach ($list as $id=>$roleName){ + $options[] = ['label'=>$roleName,'value'=>$id]; + } + return $options; + })->multiple(1); + $f[] = Form::radio('status','状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + $form = Form::make_post_form('添加管理员',$f,Url::build('save')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request) + { + $data = Util::postMore([ + 'account', + 'conf_pwd', + 'pwd', + 'real_name', + ['roles',[]], + ['status',0] + ],$request); + if(!$data['account']) return Json::fail('请输入管理员账号'); + if(!$data['roles']) return Json::fail('请选择至少一个管理员身份'); + if(!$data['pwd']) return Json::fail('请输入管理员登陆密码'); + if($data['pwd'] != $data['conf_pwd']) return Json::fail('两次输入密码不想同'); + if(AdminModel::be($data['account'],'account')) return Json::fail('管理员账号已存在'); + $data['pwd'] = md5($data['pwd']); + unset($data['conf_pwd']); + $data['level'] = $this->adminInfo['level'] + 1; + AdminModel::set($data); + return Json::successful('添加管理员成功!'); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + if(!$id) return $this->failed('参数错误'); + $admin = AdminModel::get($id); + if(!$admin) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('account','管理员账号',$admin->account); + $f[] = Form::input('pwd','管理员密码')->type('password'); + $f[] = Form::input('conf_pwd','确认密码')->type('password'); + $f[] = Form::input('real_name','管理员姓名',$admin->real_name); + $f[] = Form::select('roles','管理员身份',explode(',',$admin->roles))->setOptions(function ()use($admin){ + $list = SystemRole::getRole($admin->level); + $options = []; + foreach ($list as $id=>$roleName){ + $options[] = ['label'=>$roleName,'value'=>$id]; + } + return $options; + })->multiple(1); + $f[] = Form::radio('status','状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + $form = Form::make_post_form('编辑管理员',$f,Url::build('update',compact('id'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'account', + 'conf_pwd', + 'pwd', + 'real_name', + ['roles',[]], + ['status',0] + ],$request); + if(!$data['account']) return Json::fail('请输入管理员账号'); + if(!$data['roles']) return Json::fail('请选择至少一个管理员身份'); + if(!$data['pwd']) + unset($data['pwd']); + else{ + if(isset($data['pwd']) && $data['pwd'] != $data['conf_pwd']) return Json::fail('两次输入密码不想同'); + $data['pwd'] = md5($data['pwd']); + } + if(AdminModel::where('account',$data['account'])->where('id','<>',$id)->count()) return Json::fail('管理员账号已存在'); + unset($data['conf_pwd']); + AdminModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!$id) + return JsonService::fail('删除失败!'); + if(AdminModel::edit(['is_del'=>1,'status'=>0],$id,'id')) + return JsonService::successful('删除成功!'); + else + return JsonService::fail('删除失败!'); + } + + /** + * 个人资料 展示 + * */ + public function adminInfo(){ + $adminInfo = $this->adminInfo;//获取当前登录的管理员 + $this->assign('adminInfo',$adminInfo); + return $this->fetch(); + } + + public function setAdminInfo(Request $request){ + $adminInfo = $this->adminInfo;//获取当前登录的管理员 + if($request->isPost()){ + $data = Util::postMore([ + ['new_pwd',''], + ['new_pwd_ok',''], + ['pwd',''], + 'real_name', + ],$request); +// if ($data['pwd'] == '') unset($data['pwd']); + if($data['pwd'] != ''){ + $pwd = md5($data['pwd']); + if($adminInfo['pwd'] != $pwd) return Json::fail('原始密码错误'); + } + if($data['new_pwd'] != ''){ + if(!$data['new_pwd_ok']) return Json::fail('请输入确认新密码'); + if($data['new_pwd'] != $data['new_pwd_ok']) return Json::fail('俩次密码不一样'); + } + if($data['pwd'] != '' && $data['new_pwd'] != ''){ + $data['pwd'] = md5($data['new_pwd']); + }else{ + unset($data['pwd']); + } + unset($data['new_pwd']); + unset($data['new_pwd_ok']); + AdminModel::edit($data,$adminInfo['id']); + return Json::successful('修改成功!,请重新登录'); + } + } +} diff --git a/application/admin/controller/setting/SystemConfig.php b/application/admin/controller/setting/SystemConfig.php new file mode 100644 index 00000000..f096a52c --- /dev/null +++ b/application/admin/controller/setting/SystemConfig.php @@ -0,0 +1 @@ +assign('tab_id',$tab_id); $list = ConfigModel::getAll($tab_id); if($type==3){//其它分类 $config_tab = null; }else{ $config_tab = ConfigModel::getConfigTabAll($type); foreach ($config_tab as $kk=>$vv){ $arr = ConfigModel::getAll($vv['value'])->toArray(); if(empty($arr)){ unset($config_tab[$kk]); } } } $this->assign('config_tab',$config_tab); $this->assign('list',$list); return $this->fetch(); } /** * 添加字段 * */ public function create(Request $request){ $data = Util::getMore(['type',],$request);//接收参数 $tab_id = !empty($request->param('tab_id'))?$request->param('tab_id'):1; $formbuider = array(); switch ($data['type']){ case 0://文本框 $formbuider = ConfigModel::createInputRule($tab_id); break; case 1://多行文本框 $formbuider = ConfigModel::createTextAreaRule($tab_id); break; case 2://单选框 $formbuider = ConfigModel::createRadioRule($tab_id); break; case 3://文件上传 $formbuider = ConfigModel::createUploadRule($tab_id); break; case 4://多选框 $formbuider = ConfigModel::createCheckboxRule($tab_id); break; } $form = Form::make_post_form('添加字段',$formbuider,Url::build('save')); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * 保存字段 * */ public function save(Request $request){ $data = Util::postMore([ 'menu_name', 'type', 'config_tab_id', 'parameter', 'upload_type', 'required', 'width', 'high', 'value', 'info', 'desc', 'sort', 'status',],$request); if(!$data['info']) return Json::fail('请输入配置名称'); if(!$data['menu_name']) return Json::fail('请输入字段名称'); if($data['menu_name']){ $oneConfig = ConfigModel::getOneConfig('menu_name',$data['menu_name']); if(!empty($oneConfig)) return Json::fail('请重新输入字段名称,之前的已经使用过了'); } if(!$data['desc']) return Json::fail('请输入配置简介'); if($data['sort'] < 0){ $data['sort'] = 0; } if($data['type'] == 'text'){ if(!ConfigModel::valiDateTextRole($data)) return Json::fail(ConfigModel::getErrorInfo()); } if($data['type'] == 'textarea'){ if(!ConfigModel::valiDateTextareaRole($data)) return Json::fail(ConfigModel::getErrorInfo()); } if($data['type'] == 'radio' || $data['type'] == 'checkbox'){ if(!$data['parameter']) return Json::fail('请输入配置参数'); if(!ConfigModel::valiDateRadioAndCheckbox($data)) return Json::fail(ConfigModel::getErrorInfo()); $data['value'] = json_encode($data['value']); } ConfigModel::set($data); return Json::successful('添加菜单成功!'); } /** * @param Request $request * @param $id * @return \think\response\Json */ public function update_config(Request $request, $id) { $data = Util::postMore(['status','info','desc','sort','config_tab_id','required','parameter','value','upload_type'],$request); if(!ConfigModel::get($id)) return Json::fail('编辑的记录不存在!'); ConfigModel::edit($data,$id); return Json::successful('修改成功!'); } /** * 修改是否显示子子段 * @param $id * @return mixed */ public function edit_cinfig($id){ $menu = ConfigModel::get($id)->getData(); if(!$menu) return Json::fail('数据不存在!'); $formbuider = array(); $formbuider[] = Form::input('menu_name','字段变量',$menu['menu_name'])->disabled(1); $formbuider[] = Form::select('config_tab_id','分类',(string)$menu['config_tab_id'])->setOptions(ConfigModel::getConfigTabAll(-1)); $formbuider[] = Form::input('info','配置名称',$menu['info'])->autofocus(1); $formbuider[] = Form::input('desc','配置简介',$menu['desc']); //输入框验证规则 if(!empty($menu['required'])){ $formbuider[] = Form::input('value','默认值',$menu['value']); $formbuider[] = Form::number('width','文本框宽(%)',$menu['width']); $formbuider[] = Form::input('required','验证规则',$menu['required'])->placeholder('多个请用,隔开例如:required:true,url:true'); } //多行文本 if(!empty($menu['high'])){ $formbuider[] = Form::textarea('value','默认值',$menu['value'])->rows(5); $formbuider[] = Form::number('width','文本框宽(%)',$menu['width']); $formbuider[] = Form::number('high','多行文本框高(%)',$menu['high']); }else{ $formbuider[] = Form::input('value','默认值',$menu['value']); } //单选和多选参数配置 if(!empty($menu['parameter'])){ $formbuider[] = Form::textarea('parameter','配置参数',$menu['parameter'])->placeholder("参数方式例如:\n1=白色\n2=红色\n3=黑色"); } //上传类型选择 if(!empty($menu['upload_type'])){ $formbuider[] = Form::radio('upload_type','上传类型',$menu['upload_type'])->options([['value'=>1,'label'=>'单图'],['value'=>2,'label'=>'多图'],['value'=>3,'label'=>'文件']]); } $formbuider[] = Form::number('sort','排序',$menu['sort']); $formbuider[] = Form::radio('status','状态',$menu['status'])->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); $form = Form::make_post_form('编辑字段',$formbuider,Url::build('update_config',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); // $this->assign(['title'=>'编辑菜单','read'=>Url::build('read_config',array('id'=>$id)),'update'=>Url::build('update_config',array('id'=>$id))]); // return $this->fetch(); } /** * 删除子字段 * @return \think\response\Json */ public function delete_cinfig(){ $id = input('id'); if(!ConfigModel::del($id)) return Json::fail(ConfigModel::getErrorInfo('删除失败,请稍候再试!')); else return Json::successful('删除成功!'); } /** * 保存数据 true * */ public function save_basics(){ $request = Request::instance(); if($request->isPost()){ $post = $request->post(); $tab_id = $post['tab_id']; unset($post['tab_id']); foreach ($post as $k=>$v){ if(is_array($v)){ $res = ConfigModel::where('menu_name',$k)->column('type,upload_type'); foreach ($res as $kk=>$vv){ if($kk == 'upload'){ if($vv == 1 || $vv == 3){ $post[$k] = $v[0]; } } } } } foreach ($post as $k=>$v){ ConfigModel::edit(['value' => json_encode($v)],$k,'menu_name'); } return $this->successfulNotice('修改成功'); } } /** * 模板表单提交 * */ public function view_upload(){ if($_POST['type'] == 3){ $res = Upload::file($_POST['file'],'config/file'); }else{ $res = Upload::Image($_POST['file'],'config/image'); } if(!$res->status) return Json::fail($res->error); return Json::successful('上传成功!',['url'=>$res->filePath]); } /** * 基础配置 单个 * @return mixed|void */ public function index_alone(){ $tab_id = input('tab_id'); if(!$tab_id) return $this->failed('参数错误,请重新打开'); $this->assign('tab_id',$tab_id); $list = ConfigModel::getAll($tab_id); $config_tab = ConfigModel::getConfigTabAll(); foreach ($config_tab as $kk=>$vv){ $arr = ConfigModel::getAll($vv['value'])->toArray(); if(empty($arr)){ unset($config_tab[$kk]); } } $this->assign('config_tab',$config_tab); $this->assign('list',$list); return $this->fetch(); } /** * 保存数据 单个 * @return mixed */ public function save_basics_alone(){ $request = Request::instance(); if($request->isPost()){ $post = $request->post(); $tab_id = $post['tab_id']; unset($post['tab_id']); foreach ($post as $k=>$v){ ConfigModel::edit(['value' => json_encode($v)],$k,'menu_name'); } return $this->successfulNotice('修改成功'); } } /** * 获取文件名 * */ public function getImageName(){ $request = Request::instance(); $post = $request->post(); $src = $post['src']; $data['name'] = basename($src); exit(json_encode($data)); } } \ No newline at end of file diff --git a/application/admin/controller/setting/SystemConfigTab.php b/application/admin/controller/setting/SystemConfigTab.php new file mode 100644 index 00000000..272ffb11 --- /dev/null +++ b/application/admin/controller/setting/SystemConfigTab.php @@ -0,0 +1 @@ +assign('tab_id',$tab_id); $list = ConfigModel::getAll($tab_id); foreach ($list as $k=>$v){ $list[$k]['value'] = json_decode($v['value'],true); if($v['type'] == 'radio' || $v['type'] == 'checkbox'){ $list[$k]['value'] = ConfigTabModel::getRadioOrCheckboxValueInfo($v['menu_name'],$v['value']); } if($v['type'] == 'upload' && !empty($v['value'])){ if($v['upload_type'] == 1 || $v['upload_type'] == 3) $list[$k]['value'] = explode(',',$v['value']); } } $this->assign('list',$list); return $this->fetch(); } /** * 基础配置 * @return mixed */ public function index(){ $where = Util::getMore([ ['status',''], ['title',''], ],$this->request); $this->assign('where',$where); $this->assign(ConfigTabModel::getSystemConfigTabPage($where)); return $this->fetch(); } /** * 添加配置分类 * @return mixed */ public function create(){ $form = Form::create(Url::build('save'),[ Form::input('title','分类昵称'), Form::input('eng_title','分类字段'), Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')))->icon('ionic'), Form::radio('type','类型',0)->options([['value'=>0,'label'=>'系统'],['value'=>1,'label'=>'公众号'],['value'=>2,'label'=>'小程序'],['value'=>3,'label'=>'其它']]), Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]) ]); $form->setMethod('post')->setTitle('添加分类配置'); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * 保存分类名称 * @param Request $request * @return \think\response\Json */ public function save(Request $request){ $data = Util::postMore([ 'eng_title', 'status', 'title', 'icon', 'type'],$request); if(!$data['title']) return Json::fail('请输入按钮名称'); ConfigTabModel::set($data); return Json::successful('添加菜单成功!'); } /** * 修改分类 * @param $id * @return mixed */ public function edit($id){ $menu = ConfigTabModel::get($id)->getData(); if(!$menu) return Json::fail('数据不存在!'); $form = Form::create(Url::build('update',array('id'=>$id)),[ Form::input('title','分类昵称',$menu['title']), Form::input('eng_title','分类字段',$menu['eng_title']), Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')),$menu['icon'])->icon('ionic'), Form::radio('type','类型',$menu['type'])->options([['value'=>0,'label'=>'系统'],['value'=>1,'label'=>'公众号'],['value'=>2,'label'=>'小程序'],['value'=>3,'label'=>'其它']]), Form::radio('status','状态',$menu['status'])->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]) ]); $form->setMethod('post')->setTitle('添加分类配置'); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * @param Request $request * @param $id * @return \think\response\Json */ public function update(Request $request, $id) { $data = Util::postMore(['title','status','eng_title','icon','type'],$request); if(!$data['title']) return Json::fail('请输入分类昵称'); if(!$data['eng_title']) return Json::fail('请输入分类字段'); if(!ConfigTabModel::get($id)) return Json::fail('编辑的记录不存在!'); ConfigTabModel::edit($data,$id); return Json::successful('修改成功!'); } /** * @param $id * @return \think\response\Json */ public function delete($id){ if(!ConfigTabModel::del($id)) return Json::fail(ConfigTabModel::getErrorInfo('删除失败,请稍候再试!')); else return Json::successful('删除成功!'); } } \ No newline at end of file diff --git a/application/admin/controller/setting/SystemGroup.php b/application/admin/controller/setting/SystemGroup.php new file mode 100644 index 00000000..6120cf5c --- /dev/null +++ b/application/admin/controller/setting/SystemGroup.php @@ -0,0 +1,106 @@ +assign(GroupModel::page()); + return $this->fetch(); + } + + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create() + { + $this->assign(['title'=>'添加数据组','save'=>Url::build('save')]); + return $this->fetch(); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request) + { + $params = Util::postMore([ + ['name',''], + ['config_name',''], + ['info',''], + ['typelist',[]], + ],$this->request); + + //数据组名称判断 + if(!$params['name'])return Json::fail('请输入数据组名称!'); + if(!$params['config_name'])return Json::fail('请输入配置名称!'); + if(GroupModel::be($params['config_name'],'config_name')) return Json::fail('数据关键字已存在!'); + $data["name"] = $params['name']; + $data["config_name"] = $params['config_name']; + $data["info"] = $params['info']; + //字段信息判断 + if(!count($params['typelist'])) + return Json::fail('字段至少存在一个!'); + else{ + $validate = ["name","type","title","description"]; + foreach ($params["typelist"] as $key => $value) { + foreach ($value as $name => $field) { + if(empty($field["value"]) && in_array($name,$validate)) + return Json::fail("字段".($key + 1).":".$field["placeholder"]."不能为空!"); + else + $data["fields"][$key][$name] = $field["value"]; + } + } + } + $data["fields"] = json_encode($data["fields"]); + GroupModel::set($data); + return Json::successful('添加数据组成功!'); + } + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!GroupModel::del($id)) + return Json::fail(GroupModel::getErrorInfo('删除失败,请稍候再试!')); + else{ + GroupDataModel::del(["gid"=>$id]); + return Json::successful('删除成功!'); + } + } +} diff --git a/application/admin/controller/setting/SystemGroupData.php b/application/admin/controller/setting/SystemGroupData.php new file mode 100644 index 00000000..b2391203 --- /dev/null +++ b/application/admin/controller/setting/SystemGroupData.php @@ -0,0 +1,220 @@ +request); + $this->assign('where',$where); + $this->assign(compact("gid")); + $this->assign(GroupModel::getField($gid)); + $where['gid'] = $gid; + $this->assign(GroupDataModel::getList($where)); + return $this->fetch(); + } + + /** + * 显示创建资源表单页. + * @return \think\Response + */ + public function create($gid) + { + $Fields = GroupModel::getField($gid); + $f = array(); + foreach ($Fields["fields"] as $key => $value) { + if($value["type"] == "input") + $f[] = Form::input($value["title"],$value["name"]); + else if($value["type"] == "textarea") + $f[] = Form::input($value["title"],$value["name"])->type('textarea')->placeholder($value['param']); + else if($value["type"] == "radio") { + $params = explode("-", $value["param"]); + foreach ($params as $index => $param) { + $info[$index]["value"] = $param; + $info[$index]["label"] = $param; + } + $f[] = Form::radio($value["title"],$value["name"],$info[0]["value"])->options($info); + }else if($value["type"] == "checkbox"){ + $params = explode("-",$value["param"]); + foreach ($params as $index => $param) { + $info[$index]["value"] = $param; + $info[$index]["label"] = $param; + } + $f[] = Form::checkbox($value["title"],$value["name"],$info[0])->options($info); + }else if($value["type"] == "upload") + $f[] = Form::frameImageOne($value["title"],$value["name"],Url::build('admin/widget.images/index',array('fodder'=>$value["title"])))->icon('image'); + else if($value['type'] == 'uploads') + $f[] = Form::frameImages($value["title"],$value["name"],Url::build('admin/widget.images/index',array('fodder'=>$value["title"])))->maxLength(5)->icon('images')->width('100%')->height('550px')->spin(0); + } + $f[] = Form::number('sort','排序',1); + $f[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); + $form = Form::make_post_form('添加数据',$f,Url::build('save',compact('gid'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request,$gid) + { + $Fields = GroupModel::getField($gid); + $params = $request->post(); + foreach ($params as $key => $param) { + foreach ($Fields['fields'] as $index => $field) { + if($key == $field["title"]){ + if($param == "" || count($param) == 0) + return Json::fail($field["name"]."不能为空!"); + else{ + $value[$key]["type"] = $field["type"]; + $value[$key]["value"] = $param; + } + } + } + } + + $data = array("gid"=>$gid,"add_time"=>time(),"value"=>json_encode($value),"sort"=>$params["sort"],"status"=>$params["status"]); + GroupDataModel::set($data); + return Json::successful('添加数据成功!'); + } + + /** + * 显示指定的资源 + * + * @param int $id + * @return \think\Response + */ + public function read($id) + { + // + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($gid,$id) + { + $GroupData = GroupDataModel::get($id); + $GroupDataValue = json_decode($GroupData["value"],true); + $Fields = GroupModel::getField($gid); + $f = array(); + foreach ($Fields["fields"] as $key => $value) { + if($value["type"] == "input") $f[] = Form::input($value["title"],$value["name"],$GroupDataValue[$value["title"]]["value"]); + if($value["type"] == "textarea") $f[] = Form::input($value["title"],$value["name"],$GroupDataValue[$value["title"]]["value"])->type('textarea'); + if($value["type"] == "radio"){ + $params = explode("-",$value["param"]); + foreach ($params as $index => $param) { + $info[$index]["value"] = $param; + $info[$index]["label"] = $param; + } + $f[] = Form::radio($value["title"],$value["name"],$GroupDataValue[$value["title"]]["value"])->options($info); + } + if($value["type"] == "checkbox"){ + $params = explode("-",$value["param"]); + foreach ($params as $index => $param) { + $info[$index]["value"] = $param; + $info[$index]["label"] = $param; + } + $f[] = Form::checkbox($value["title"],$value["name"],$GroupDataValue[$value["title"]]["value"])->options($info); + } + if($value["type"] == "upload"){ + $image = is_string($GroupDataValue[$value["title"]]["value"])?$GroupDataValue[$value["title"]]["value"]:$GroupDataValue[$value["title"]]["value"][0]; + $f[] = Form::frameImageOne($value["title"],$value["name"],Url::build('admin/widget.images/index',array('fodder'=>$value["title"])),$image)->icon('image'); + } + else if($value['type'] == 'uploads') { + $f[] = Form::frameImages($value["title"], $value["name"], Url::build('admin/widget.images/index', array('fodder' => $value["title"])), $GroupDataValue[$value["title"]]["value"])->maxLength(5)->icon('images')->width('100%')->height('550px')->spin(0); + } + } + $f[] = Form::input('sort','排序',$GroupData["sort"]); + $f[] = Form::radio('status','状态',$GroupData["status"])->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); + $form = Form::make_post_form('添加用户通知',$f,Url::build('update',compact('id'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + $GroupData = GroupDataModel::get($id); + $Fields = GroupModel::getField($GroupData["gid"]); + $params = $request->post(); + foreach ($params as $key => $param) { + foreach ($Fields['fields'] as $index => $field) { + if($key == $field["title"]){ + if($param == "" || count($param) == 0) + return Json::fail($field["name"]."不能为空!"); + else{ + $value[$key]["type"] = $field["type"]; + $value[$key]["value"] = $param; + } + } + } + } + $data = array("value"=>json_encode($value),"sort"=>$params["sort"],"status"=>$params["status"]); + GroupDataModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!GroupDataModel::del($id)) + return Json::fail(GroupDataModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + public function upload() + { + $res = Upload::image('file','common'); + $thumbPath = Upload::thumb($res->dir); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,6); + + if($res->status == 200) + return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); + else + return Json::fail($res->error); + } +} diff --git a/application/admin/controller/setting/SystemMenus.php b/application/admin/controller/setting/SystemMenus.php new file mode 100644 index 00000000..eea8da6b --- /dev/null +++ b/application/admin/controller/setting/SystemMenus.php @@ -0,0 +1,175 @@ +request->param('pid')?$this->request->param('pid'):0; + $params = Util::getMore([ + ['is_show',''], +// ['access',''], + ['keyword',''], + ['pid',$pid] + ],$this->request); + $this->assign(MenusModel::getAdminPage($params)); + $this->assign(compact('params')); + return $this->fetch(); + } + + + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create($cid = 0) + { + $form = Form::create(Url::build('save'),[ + Form::input('menu_name','按钮名称')->required('按钮名称必填'), + Form::select('pid','父级id',$cid)->setOptions(function(){ + $list = (Util::sortListTier(MenusModel::all()->toArray(),'顶级','pid','menu_name')); + $menus = [['value'=>0,'label'=>'顶级按钮']]; + foreach ($list as $menu){ + $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['menu_name']]; + } + return $menus; + })->filterable(1), + Form::select('module','模块名')->options([['label'=>'总后台','value'=>'admin']]), + Form::input('controller','控制器名'), + Form::input('action','方法名'), + Form::input('params','参数')->placeholder('举例:a/123/b/234'), + Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')))->icon('ionic'), + Form::number('sort','排序',0), + Form::radio('is_show','是否菜单',1)->options([['value'=>0,'label'=>'隐藏'],['value'=>1,'label'=>'显示(菜单只显示三级)']]), + ]); + $form->setMethod('post')->setTitle('添加权限'); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request) + { + $data = Util::postMore([ + 'menu_name', + 'controller', + ['module','admin'], + 'action', + 'icon', + 'params', + ['pid',0], + ['sort',0], + ['is_show',0], + ['access',1]],$request); + if(!$data['menu_name']) return Json::fail('请输入按钮名称'); + MenusModel::set($data); + return Json::successful('添加菜单成功!'); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + $menu = MenusModel::get($id); + if(!$menu) return Json::fail('数据不存在!'); + $form = Form::create(Url::build('update',array('id'=>$id)),[ + Form::input('menu_name','按钮名称',$menu['menu_name']), + Form::select('pid','父级id',(string)$menu->getData('pid'))->setOptions(function()use($id){ + $list = (Util::sortListTier(MenusModel::where('id','<>',$id)->select()->toArray(),'顶级','pid','menu_name')); + $menus = [['value'=>0,'label'=>'顶级按钮']]; + foreach ($list as $menu){ + $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['menu_name']]; + } + return $menus; + })->filterable(1), + Form::select('module','模块名',$menu['module'])->options([['label'=>'总后台','value'=>'admin'],['label'=>'总后台1','value'=>'admin1']]), + Form::input('controller','控制器名',$menu['controller']), + Form::input('action','方法名',$menu['action']), + Form::input('params','参数',MenusModel::paramStr($menu['params']))->placeholder('举例:a/123/b/234'), + Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')),$menu['icon'])->icon('ionic'), + Form::number('sort','排序',$menu['sort']), + Form::radio('is_show','是否菜单',$menu['is_show'])->options([['value'=>0,'label'=>'隐藏'],['value'=>1,'label'=>'显示(菜单只显示三级)']]) + ]); + $form->setMethod('post')->setTitle('编辑权限'); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'menu_name', + 'controller', + ['module','admin'], + 'action', + 'params', + 'icon', + ['sort',0], + ['pid',0], + ['is_show',0], + ['access',1]],$request); + if(!$data['menu_name']) return Json::fail('请输入按钮名称'); + if(!MenusModel::get($id)) return Json::fail('编辑的记录不存在!'); + MenusModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!$id) return $this->failed('参数错误,请重新打开'); + $res = MenusModel::delMenu($id); + if(!$res) + return Json::fail(MenusModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + +} diff --git a/application/admin/controller/setting/SystemNotice.php b/application/admin/controller/setting/SystemNotice.php new file mode 100644 index 00000000..39d02ca2 --- /dev/null +++ b/application/admin/controller/setting/SystemNotice.php @@ -0,0 +1 @@ +assign(NoticeModel::page(function($notice){ $notice->push_admin_name = !empty($notice->push_admin) ? implode(',',SystemAdmin::where('id','IN',$notice->push_admin)->column('real_name')) : ''; })); return $this->fetch(); } public function create() { $f = array(); $f[] = Form::input('title','通知标题'); $f[] = Form::input('type','通知类型'); $f[] = Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')))->icon('ionic'); $f[] = Form::input('template','通知模板'); $f[] = Form::input('table_title','通知数据')->type('textarea')->placeholder('数据1-key1,数据2-key2'); $f[] = Form::select('push_admin','通知管理员')->setOptions(function(){ $list = SystemAdmin::getOrdAdmin('real_name,id')?:[]; $options = []; foreach ($list as $admin){ $options[] = ['label'=>$admin['real_name'],'value'=>$admin['id']]; } return $options; })->multiple(1); $f[] = Form::radio('status','状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); $form = Form::make_post_form('添加通知模板',$f,Url::build('save')); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } public function save(Request $request) { $data = UtilService::postMore([ 'title', 'type', 'icon', 'template','table_title', ['push_admin', []], ['status', 0] ], $request); $data['push_admin'] = array_unique(array_filter($data['push_admin'])); if (!$data['template']) return $this->failed('请填写通知模板'); if (!$data['title']) return $this->failed('请输入模板标题'); if (!$data['type']) return $this->failed('请输入模板类型'); if (NoticeModel::set($data)) return $this->successful('添加通知成功'); else return $this->failed('添加失败!'); } /**编辑通知模板 * @param $id * @return mixed|void */ public function edit($id) { $data = NoticeModel::get($id); if(!$data) return JsonService::fail('数据不存在!'); $data->tableTitle = implode(',',array_map(function($value){ return $value['title'].'-'.$value['key']; },$data->table_title)); $data->tableTitleStr = implode(',',array_map(function($value){ return $value['title'].'-'.$value['key']; },$data->table_title)); $f = array(); $f[] = Form::input('title','通知标题',$data->title); $f[] = Form::input('type','通知类型',$data->type); $f[] = Form::frameInputOne('icon','图标',Url::build('admin/widget.widgets/icon',array('fodder'=>'icon')),$data->icon)->icon('ionic'); $f[] = Form::input('template','通知模板',$data->template); $f[] = Form::input('table_title','通知数据',$data->tableTitleStr)->type('textarea')->placeholder('数据1-key1,数据2-key2'); $f[] = Form::select('push_admin','通知管理员',$data->push_admin)->setOptions(function(){ $list = SystemAdmin::getOrdAdmin('real_name,id')?:[]; $options = []; foreach ($list as $admin){ $options[] = ['label'=>$admin['real_name'],'value'=>$admin['id']]; } return $options; })->multiple(1); $f[] = Form::radio('status','状态',$data->status)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); $form = Form::make_post_form('编辑通知模板',$f,Url::build('update',array('id'=>$id))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } public function update(Request $request, $id) { $data = UtilService::postMore([ 'title','type','icon','template','table_title', ['push_admin',[]],['status',0] ],$request); $data['push_admin'] = array_unique(array_filter($data['push_admin'])); if(!$data['template']) return $this->failed('请填写通知模板'); if(!$data['title']) return $this->failed('请输入模板标题'); if(!$data['type']) return $this->failed('请输入模板类型'); NoticeModel::edit($data,$id); return $this->successful('修改成功!'); } /** * 删除指定资源 * * @param int $id * @return \think\Response */ public function delete($id) { $res = NoticeModel::del($id); if(!$res) return $this->failed(('删除失败,请稍候再试!')); else return $this->successful('删除成功!'); } public function message($type = 'all') { return $this->fetch(); } } \ No newline at end of file diff --git a/application/admin/controller/setting/SystemRole.php b/application/admin/controller/setting/SystemRole.php new file mode 100644 index 00000000..c19658ef --- /dev/null +++ b/application/admin/controller/setting/SystemRole.php @@ -0,0 +1,145 @@ +request); + $where['level'] = $this->adminInfo['level']; + $this->assign('where',$where); + $this->assign(RoleModel::systemPage($where)); + return $this->fetch(); + } + + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create() + { + +// if(0 == 0){ +// }else{ +// dump($this->adminInfo['level']); +// } + $menus = $this->adminInfo['level'] == 0 ? SystemMenus::ruleList() : SystemMenus::rolesByRuleList($this->adminInfo['roles']); + $this->assign(['menus'=>json($menus)->getContent(),'saveUrl'=>Url::build('save')]); + return $this->fetch(); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request) + { + $data = Util::postMore([ + 'role_name', + ['status',0], + ['checked_menus',[],'','rules'] + ],$request); + if(!$data['role_name']) return Json::fail('请输入身份名称'); + if(!is_array($data['rules']) || !count($data['rules']) ) + return Json::fail('请选择最少一个权限'); + foreach ($data['rules'] as $v){ + $pid = SystemMenus::where('id',$v)->value('pid'); + if(!in_array($pid,$data['rules'])) $data['rules'][] = $pid; + } + $data['rules'] = implode(',',$data['rules']); + $data['level'] = $this->adminInfo['level']+1; + RoleModel::set($data); + return Json::successful('添加身份成功!'); + } + + /** + * 显示指定的资源 + * + * @param int $id + * @return \think\Response + */ + public function read($id) + { + // + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + // + $role = RoleModel::get($id); + $menus = $this->adminInfo['level'] == 0 ? SystemMenus::ruleList() : SystemMenus::rolesByRuleList($this->adminInfo['roles']); + $this->assign(['role'=>$role->toJson(),'menus'=>json($menus)->getContent(),'updateUrl'=>Url::build('update',array('id'=>$id))]); + return $this->fetch(); + } + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'role_name', + ['status',0], + ['checked_menus',[],'','rules'] + ],$request); + if(!$data['role_name']) return Json::fail('请输入身份名称'); + if(!is_array($data['rules']) || !count($data['rules']) ) + return Json::fail('请选择最少一个权限'); + foreach ($data['rules'] as $v){ + $pid = SystemMenus::where('id',$v)->value('pid'); + if(!in_array($pid,$data['rules'])) $data['rules'][] = $pid; + } + $data['rules'] = implode(',',$data['rules']); + RoleModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!RoleModel::del($id)) + return Json::fail(RoleModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } +} diff --git a/application/admin/controller/store/StoreCategory.php b/application/admin/controller/store/StoreCategory.php new file mode 100644 index 00000000..f11f87f3 --- /dev/null +++ b/application/admin/controller/store/StoreCategory.php @@ -0,0 +1,180 @@ +request->param('pid')?$this->request->param('pid'):0; + $where = Util::getMore([ + ['is_show',''], + ['pid',$pid], + ['cate_name',''], + ],$this->request); + $this->assign('where',$where); + $this->assign('cate',CategoryModel::getTierList()); + $this->assign(CategoryModel::systemPage($where)); + return $this->fetch(); + } + + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create() + { + $form = Form::create(Url::build('save'),[ + Form::select('pid','父级')->setOptions(function(){ + $list = CategoryModel::getTierList(); + $menus = [['value'=>0,'label'=>'顶级菜单']]; + foreach ($list as $menu){ + $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['cate_name']]; + } + return $menus; + })->filterable(1), + Form::input('cate_name','分类名称'), + Form::frameImageOne('pic','分类图标',Url::build('admin/widget.images/index',array('fodder'=>'pic')))->icon('image'), + Form::number('sort','排序'), + Form::radio('is_show','状态',1)->options([['label'=>'显示','value'=>1],['label'=>'隐藏','value'=>0]]) + ]); + $form->setMethod('post')->setTitle('添加分类'); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + + /** + * 上传图片 + * @return \think\response\Json + */ + public function upload() + { + $res = Upload::image('file','store/category'.date('Ymd')); + $thumbPath = Upload::thumb($res->dir); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,1); + + if($res->status == 200) + return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); + else + return Json::fail($res->error); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request) + { + $data = Util::postMore([ + 'pid', + 'cate_name', + ['pic',[]], + 'sort', + ['is_show',0] + ],$request); + if($data['pid'] == '') return Json::fail('请选择父类'); + if(!$data['cate_name']) return Json::fail('请输入分类名称'); + if(count($data['pic'])<1) return Json::fail('请上传分类图标'); + if($data['sort'] <0 ) $data['sort'] = 0; + $data['pic'] = $data['pic'][0]; + $data['add_time'] = time(); + CategoryModel::set($data); + return Json::successful('添加分类成功!'); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + $c = CategoryModel::get($id); + if(!$c) return Json::fail('数据不存在!'); + $form = Form::create(Url::build('update',array('id'=>$id)),[ + Form::select('pid','父级',(string)$c->getData('pid'))->setOptions(function() use($id){ + $list = CategoryModel::getTierList(CategoryModel::where('id','<>',$id)); +// $list = (Util::sortListTier(CategoryModel::where('id','<>',$id)->select()->toArray(),'顶级','pid','cate_name')); + $menus = [['value'=>0,'label'=>'顶级菜单']]; + foreach ($list as $menu){ + $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['cate_name']]; + } + return $menus; + })->filterable(1), + Form::input('cate_name','分类名称',$c->getData('cate_name')), + Form::frameImageOne('pic','分类图标',Url::build('admin/widget.images/index',array('fodder'=>'pic')),$c->getData('pic'))->icon('image'), + Form::number('sort','排序',$c->getData('sort')), + Form::radio('is_show','状态',$c->getData('is_show'))->options([['label'=>'显示','value'=>1],['label'=>'隐藏','value'=>0]]) + ]); + $form->setMethod('post')->setTitle('添加分类'); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'pid', + 'cate_name', + ['pic',[]], + 'sort', + ['is_show',0] + ],$request); + if($data['pid'] == '') return Json::fail('请选择父类'); + if(!$data['cate_name']) return Json::fail('请输入分类名称'); + if(count($data['pic'])<1) return Json::fail('请上传分类图标'); + if($data['sort'] <0 ) $data['sort'] = 0; + $data['pic'] = $data['pic'][0]; + CategoryModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!CategoryModel::delCategory($id)) + return Json::fail(CategoryModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } +} diff --git a/application/admin/controller/store/StoreInfoMana.php b/application/admin/controller/store/StoreInfoMana.php new file mode 100644 index 00000000..16e4346e --- /dev/null +++ b/application/admin/controller/store/StoreInfoMana.php @@ -0,0 +1 @@ +failed('数据不存在'); echo $is_list; exit(); $where = Util::getMore([ ['status',''], ['title',''], ],$this->request); $this->assign('where',$where); $this->assign(ArticleCategoryModel::systemPage($where)); return $this->fetch(); } /** * 添加分类管理 * */ public function create(){ FormBuilder::text('title','分类昵称'); FormBuilder::textarea('intr','分类简介'); FormBuilder::select('new_id','图文列表',function(){ $list = \app\admin\model\wechat\WechatNews::getNews(); $options = []; foreach ($list as $id=>$roleName){ $options[] = ['label'=>$roleName,'value'=>$id]; } return $options; })->multiple()->filterable(); FormBuilder::upload('image','分类图片'); FormBuilder::number('sort','排序',0); FormBuilder::radio('status','状态',[['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']],1); $rules = FormBuilder::builder()->getContent(); $this->assign(['title'=>'编辑菜单','rules'=>$rules,'save'=>Url::build('save')]); return $this->fetch(); } /** * s上传图片 * */ public function upload(){ $res = Upload::image('file','article'); $thumbPath = Upload::thumb($res->dir); if($res->status == 200) return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); else return Json::fail($res->error); } /** * 保存分类管理 * */ public function save(Request $request){ $data = Util::postMore([ 'title', 'intr', ['new_id',[]], ['image',[]], ['sort',0], 'status',],$request); if(!$data['title']) return Json::fail('请输入分类名称'); if(count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张'); if($data['sort'] < 0) return Json::fail('排序不能是负数'); $data['add_time'] = time(); $data['image'] = $data['image'][0]; $new_id = $data['new_id']; unset($data['new_id']); $res = ArticleCategoryModel::set($data); if(!WechatNewsModel::saveBatchCid($res['id'],implode(',',$new_id))) return Json::fail('文章列表添加失败'); return Json::successful('添加分类成功!'); } /** * 修改分类 * */ public function edit($id){ $this->assign(['title'=>'编辑菜单','read'=>Url::build('read',array('id'=>$id)),'update'=>Url::build('update',array('id'=>$id))]); return $this->fetch(); } public function read($id) { $article = ArticleCategoryModel::get($id)->getData(); if(!$article) return Json::fail('数据不存在!'); FormBuilder::text('title','分类昵称',$article['title']); FormBuilder::textarea('intr','分类简介',$article['intr']); $arr = ArticleCategoryModel::getArticle($id,'id,title,cid');//子文章 $new_id = array(); foreach ($arr as $k=>$v){ $new_id[$k] = $k; } FormBuilder::select('new_id','文章列表',function(){ $list = \app\admin\model\wechat\WechatNews::getNews(); $options = []; foreach ($list as $id=>$roleName){ $options[] = ['label'=>$roleName,'value'=>$id]; } return $options; },$new_id)->multiple(); FormBuilder::upload('image','分类图片')->defaultFileList($article['image']); FormBuilder::number('sort','排序',$article['sort']); FormBuilder::radio('status','状态',[['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']],$article['status']); return FormBuilder::builder(); } public function update(Request $request, $id) { $data = Util::postMore([ 'title', 'intr', ['new_id',[]], ['image',[]], ['sort',0], 'status',],$request); if(!$data['title']) return Json::fail('请输入分类名称'); if(count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张'); if($data['sort'] < 0) return Json::fail('排序不能是负数'); $data['image'] = $data['image'][0]; // dump($data); // exit; if(!ArticleCategoryModel::get($id)) return Json::fail('编辑的记录不存在!'); if(!WechatNewsModel::saveBatchCid($id,implode(',',$data['new_id']))) return Json::fail('文章列表添加失败'); unset($data['new_id']); ArticleCategoryModel::edit($data,$id); return Json::successful('修改成功!'); } /** * 删除分类 * */ public function delete($id) { $res = ArticleCategoryModel::delArticleCategory($id); if(!$res) return Json::fail(ArticleCategoryModel::getErrorInfo('删除失败,请稍候再试!')); else return Json::successful('删除成功!'); } } \ No newline at end of file diff --git a/application/admin/controller/store/StoreProduct.php b/application/admin/controller/store/StoreProduct.php new file mode 100644 index 00000000..5d8e5922 --- /dev/null +++ b/application/admin/controller/store/StoreProduct.php @@ -0,0 +1,466 @@ +request->param('type')], + ['cate_id',''], + ['is_show',''], + ['store_name',''], + ['sales',''], + ['export',0] + ],$this->request); + $this->assign('cate',CategoryModel::getTierList()); + + //出售中产品 + $data = ['is_show'=>1,'is_del'=>0]; + $onsale = ProductModel::where($data)->count(); + //待上架产品 + $data = ['is_show'=>0,'is_del'=>0]; + $forsale = ProductModel::where($data)->count(); + //仓库中产品 + $data = ['is_del'=>0]; + $warehouse = ProductModel::where($data)->count(); + //已经售馨产品 + $data = ['p.is_show'=>1,'p.is_del'=>0,'pav.stock|p.stock'=>0]; + $outofstock = ProductModel::alias('p') + ->join('StoreProductAttrValue pav','p.id=pav.product_id','LEFT') + ->where($data)->count(); + //警戒库存 + $data = ['p.is_show'=>1,'p.is_del'=>0,'pav.stock|p.stock'=>['elt',1]]; + $policeforce = ProductModel::alias('p') + ->join('StoreProductAttrValue pav','p.id=pav.product_id','LEFT') + ->where($data)->count(); + //回收站 + $data = ['is_del'=>1]; + $recycle = ProductModel::where($data)->count(); + $this->assign(compact('where','onsale','forsale','warehouse','outofstock','policeforce','recycle')); + $this->assign(ProductModel::systemPage($where,$this->adminInfo)); + return $this->fetch(); + } + + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create() + { +// $this->assign(['title'=>'添加产品','action'=>Url::build('save'),'rules'=>$this->rules()->getContent()]); +// return $this->fetch('public/common_form'); + $field = [ + Form::select('cate_id','产品分类')->setOptions(function(){ + $list = CategoryModel::getTierList(); + $menus=[]; + foreach ($list as $menu){ + $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['cate_name'],'disabled'=>$menu['pid']== 0];//,'disabled'=>$menu['pid']== 0]; + } + return $menus; + })->filterable(1)->multiple(1), + Form::input('store_name','产品名称')->col(Form::col(24)), + Form::input('store_info','产品简介')->type('textarea'), + Form::input('keyword','产品关键字')->placeholder('多个用英文状态下的逗号隔开'), + Form::input('unit_name','产品单位','件'), + Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')))->icon('image')->width('100%')->height('550px'), + Form::frameImages('slider_image','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'slider_image')))->maxLength(5)->icon('images')->width('100%')->height('550px')->spin(0), + Form::number('price','产品售价')->min(0)->col(8), + Form::number('ot_price','产品市场价')->min(0)->col(8), + Form::number('give_integral','赠送积分')->min(0)->precision(0)->col(8), + Form::number('postage','邮费')->min(0)->col(Form::col(8)), + Form::number('sales','销量')->min(0)->precision(0)->col(8), + Form::number('ficti','虚拟销量')->min(0)->precision(0)->col(8), + Form::number('stock','库存')->min(0)->precision(0)->col(8), + Form::number('cost','产品成本价')->min(0)->col(8), + Form::number('sort','排序')->col(8), + Form::radio('is_show','产品状态',0)->options([['label'=>'上架','value'=>1],['label'=>'下架','value'=>0]])->col(8), + Form::radio('is_hot','热卖单品',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_benefit','促销单品',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_best','精品推荐',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_new','首发新品',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_postage','是否包邮',0)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8) + ]; + $form = Form::create(Url::build('save')); + $form->setMethod('post')->setTitle('添加产品')->components($field)->setSuccessScript('parent.$(".J_iframe:visible")[0].contentWindow.location.reload();'); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 上传图片 + * @return \think\response\Json + */ + public function upload() + { + $res = Upload::image('file','store/product/'.date('Ymd')); + $thumbPath = Upload::thumb($res->dir); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,1); + if($res->status == 200) + return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); + else + return Json::fail($res->error); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request) + { + $data = Util::postMore([ + ['cate_id',[]], + 'store_name', + 'store_info', + 'keyword', + ['unit_name','件'], + ['image',[]], + ['slider_image',[]], + 'postage', + 'ot_price', + 'price', + 'sort', + 'stock', + 'sales', + 'ficti', + ['give_integral',0], + ['is_show',0], + ['cost',0], + ['is_hot',0], + ['is_benefit',0], + ['is_best',0], + ['is_new',0], + ['mer_use',0], + ['is_postage',0], + ],$request); + if(count($data['cate_id']) < 1) return Json::fail('请选择产品分类'); + $data['cate_id'] = implode(',',$data['cate_id']); + if(!$data['store_name']) return Json::fail('请输入产品名称'); +// if(!$data['store_info']) return Json::fail('请输入产品简介'); +// if(!$data['keyword']) return Json::fail('请输入产品关键字'); + if(count($data['image'])<1) return Json::fail('请上传产品图片'); + if(count($data['slider_image'])<1) return Json::fail('请上传产品轮播图'); + if($data['price'] == '' || $data['price'] < 0) return Json::fail('请输入产品售价'); + if($data['ot_price'] == '' || $data['ot_price'] < 0) return Json::fail('请输入产品市场价'); + if($data['postage'] == '' || $data['postage'] < 0) return Json::fail('请输入邮费'); + if($data['stock'] == '' || $data['stock'] < 0) return Json::fail('请输入库存'); + if($data['cost'] == '' || $data['ot_price'] < 0) return Json::fail('请输入产品成本价'); + if($data['sales'] == '' || $data['sales'] < 0) return Json::fail('请输入销量'); + if($data['give_integral'] < 0) return Json::fail('请输入赠送积分'); + $data['image'] = $data['image'][0]; + $data['slider_image'] = json_encode($data['slider_image']); + $data['add_time'] = time(); + $data['description'] = ''; + ProductModel::set($data); + return Json::successful('添加产品成功!'); + } + + + public function edit_content($id){ + if(!$id) return $this->failed('数据不存在'); + $product = ProductModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $this->assign([ + 'content'=>ProductModel::where('id',$id)->value('description'), + 'field'=>'description', + 'action'=>Url::build('change_field',['id'=>$id,'field'=>'description']) + ]); + return $this->fetch('public/edit_content'); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + if(!$id) return $this->failed('数据不存在'); + $product = ProductModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $form = Form::create(Url::build('update',array('id'=>$id)),[ + Form::select('cate_id','产品分类',explode(',',$product->getData('cate_id')))->setOptions(function(){ + $list = CategoryModel::getTierList(); + foreach ($list as $menu){ + $menus[] = ['value'=>$menu['id'],'label'=>$menu['html'].$menu['cate_name'],'disabled'=>$menu['pid']== 0];//,'disabled'=>$menu['pid']== 0]; + } + return $menus; + })->filterable(1)->multiple(1), + Form::input('store_name','产品名称',$product->getData('store_name')), + Form::input('store_info','产品简介',$product->getData('store_info'))->type('textarea'), + Form::input('keyword','产品关键字',$product->getData('keyword'))->placeholder('多个用英文状态下的逗号隔开'), + Form::input('unit_name','产品单位',$product->getData('unit_name')), + Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image')->width('100%')->height('550px'), + Form::frameImages('slider_image','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'slider_image')),json_decode($product->getData('slider_image'),1))->maxLength(5)->icon('images'), + Form::number('price','产品售价',$product->getData('price'))->min(0)->precision(2)->col(8), + Form::number('ot_price','产品市场价',$product->getData('ot_price'))->min(0)->col(8), + Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->precision(0)->col(8), + Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(8), + Form::number('sales','销量',$product->getData('sales'))->min(0)->precision(0)->col(8), + Form::number('ficti','虚拟销量',$product->getData('ficti'))->min(0)->precision(0)->col(8), + Form::number('stock','库存',ProductModel::getStock($id)>0?ProductModel::getStock($id):$product->getData('stock'))->min(0)->precision(0)->col(8), + Form::number('cost','产品成本价',$product->getData('cost'))->min(0)->col(8), + Form::number('sort','排序',$product->getData('sort'))->col(8), + Form::radio('is_show','产品状态',$product->getData('is_show'))->options([['label'=>'上架','value'=>1],['label'=>'下架','value'=>0]])->col(8), + Form::radio('is_hot','热卖单品',$product->getData('is_hot'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_benefit','促销单品',$product->getData('is_benefit'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_best','精品推荐',$product->getData('is_best'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_new','首发新品',$product->getData('is_new'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8), + Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(8) + ]); + $form->setMethod('post')->setTitle('编辑产品')->setSuccessScript('parent.$(".J_iframe:visible")[0].contentWindow.location.reload();'); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + $data = Util::postMore([ + ['cate_id',[]], + 'store_name', + 'store_info', + 'keyword', + ['unit_name','件'], + ['image',[]], + ['slider_image',[]], + 'postage', + 'ot_price', + 'price', + 'sort', + 'stock', + 'sales', + 'ficti', + ['give_integral',0], + ['is_show',0], + ['cost',0], + ['is_hot',0], + ['is_benefit',0], + ['is_best',0], + ['is_new',0], + ['mer_use',0], + ['is_postage',0], + ],$request); + if(count($data['cate_id']) < 1) return Json::fail('请选择产品分类'); + $data['cate_id'] = implode(',',$data['cate_id']); + if(!$data['store_name']) return Json::fail('请输入产品名称'); +// if(!$data['store_info']) return Json::fail('请输入产品简介'); +// if(!$data['keyword']) return Json::fail('请输入产品关键字'); + if(count($data['image'])<1) return Json::fail('请上传产品图片'); + if(count($data['slider_image'])<1) return Json::fail('请上传产品轮播图'); + if(count($data['slider_image'])>5) return Json::fail('轮播图最多5张图'); + if($data['price'] == '' || $data['price'] < 0) return Json::fail('请输入产品售价'); + if($data['ot_price'] == '' || $data['ot_price'] < 0) return Json::fail('请输入产品市场价'); + if($data['postage'] == '' || $data['postage'] < 0) return Json::fail('请输入邮费'); + if($data['cost'] == '' || $data['cost'] < 0) return Json::fail('请输入产品成本价'); + if($data['stock'] == '' || $data['stock'] < 0) return Json::fail('请输入库存'); + if($data['sales'] == '' || $data['sales'] < 0) return Json::fail('请输入销量'); + if($data['give_integral'] < 0) return Json::fail('请输入赠送积分'); + $data['image'] = $data['image'][0]; + $data['slider_image'] = json_encode($data['slider_image']); + ProductModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + public function attr($id) + { + if(!$id) return $this->failed('数据不存在!'); + $result = StoreProductAttrResult::getResult($id); + $image = ProductModel::where('id',$id)->value('image'); + $this->assign(compact('id','result','product','image')); + return $this->fetch(); + } + /** + * 生成属性 + * @param int $id + */ + public function is_format_attr($id = 0){ + if(!$id) return Json::fail('产品不存在'); + list($attr,$detail) = Util::postMore([ + ['items',[]], + ['attrs',[]] + ],$this->request,true); + $product = ProductModel::get($id); + if(!$product) return Json::fail('产品不存在'); + $attrFormat = attrFormat($attr)[1]; + if(count($detail)){ + foreach ($attrFormat as $k=>$v){ + foreach ($detail as $kk=>$vv){ + if($v['detail'] == $vv['detail']){ + $attrFormat[$k]['price'] = $vv['price']; + $attrFormat[$k]['cost'] = isset($vv['cost']) ? $vv['cost'] : $product['cost']; + $attrFormat[$k]['sales'] = $vv['sales']; + $attrFormat[$k]['pic'] = $vv['pic']; + $attrFormat[$k]['check'] = false; + break; + }else{ + $attrFormat[$k]['cost'] = $product['cost']; + $attrFormat[$k]['price'] = ''; + $attrFormat[$k]['sales'] = ''; + $attrFormat[$k]['pic'] = $product['image']; + $attrFormat[$k]['check'] = true; + } + } + } + }else{ + foreach ($attrFormat as $k=>$v){ + $attrFormat[$k]['cost'] = $product['cost']; + $attrFormat[$k]['price'] = $product['price']; + $attrFormat[$k]['sales'] = $product['stock']; + $attrFormat[$k]['pic'] = $product['image']; + $attrFormat[$k]['check'] = false; + } + } + return Json::successful($attrFormat); + } + + public function set_attr($id) + { + if(!$id) return $this->failed('产品不存在!'); + list($attr,$detail) = Util::postMore([ + ['items',[]], + ['attrs',[]] + ],$this->request,true); + $res = StoreProductAttr::createProductAttr($attr,$detail,$id); + if($res) + return $this->successful('编辑属性成功!'); + else + return $this->failed(StoreProductAttr::getErrorInfo()); + } + + public function clear_attr($id) + { + if(!$id) return $this->failed('产品不存在!'); + if(false !== StoreProductAttr::clearProductAttr($id) && false !== StoreProductAttrResult::clearResult($id)) + return $this->successful('清空产品属性成功!'); + else + return $this->failed(StoreProductAttr::getErrorInfo('清空产品属性失败!')); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!$id) return $this->failed('数据不存在'); + $data['is_del'] = 1; + if(!ProductModel::edit($data,$id)) + return Json::fail(ProductModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + + + + /** + * 点赞 + * @param $id + * @return mixed|\think\response\Json|void + */ + public function collect($id){ + if(!$id) return $this->failed('数据不存在'); + $product = ProductModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $this->assign(StoreProductRelation::getCollect($id)); + return $this->fetch(); + } + + /** + * 收藏 + * @param $id + * @return mixed|\think\response\Json|void + */ + public function like($id){ + if(!$id) return $this->failed('数据不存在'); + $product = ProductModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $this->assign(StoreProductRelation::getLike($id)); + return $this->fetch(); + } + /** + * 修改产品价格 + * @param Request $request + */ + public function edit_product_price(Request $request){ + $data = Util::postMore([ + ['id',0], + ['price',0], + ],$request); + if(!$data['id']) return Json::fail('参数错误'); + $res = ProductModel::edit(['price'=>$data['price']],$data['id']); + if($res) return Json::successful('修改成功'); + else return Json::fail('修改失败'); + } + + /** + * 修改产品库存 + * @param Request $request + */ + public function edit_product_stock(Request $request){ + $data = Util::postMore([ + ['id',0], + ['stock',0], + ],$request); + if(!$data['id']) return Json::fail('参数错误'); + $res = ProductModel::edit(['stock'=>$data['stock']],$data['id']); + if($res) return Json::successful('修改成功'); + else return Json::fail('修改失败'); + } + + + +} diff --git a/application/admin/controller/store/StoreProductReply.php b/application/admin/controller/store/StoreProductReply.php new file mode 100644 index 00000000..2dfe1c89 --- /dev/null +++ b/application/admin/controller/store/StoreProductReply.php @@ -0,0 +1,92 @@ +request); + $product_id = 0; + $product_id = input('product_id'); + if($product_id) + $where['product_id'] = $product_id; + else + $where['product_id'] = 0; + $this->assign('where',$where); + $this->assign(ProductReplyModel::systemPage($where)); + return $this->fetch(); + } + + /** + * @param $id + * @return \think\response\Json|void + */ + public function delete($id){ + if(!$id) return $this->failed('数据不存在'); + $data['is_del'] = 1; + if(!ProductReplyModel::edit($data,$id)) + return Json::fail(ProductReplyModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + public function set_reply(Request $request){ + $data = Util::postMore([ + 'id', + 'content', + ],$request); + if(!$data['id']) return Json::fail('参数错误'); + if($data['content'] == '') return Json::fail('请输入回复内容'); + $save['merchant_reply_content'] = $data['content']; + $save['merchant_reply_time'] = time(); + $save['is_reply'] = 2; + $res = ProductReplyModel::edit($save,$data['id']); + if(!$res) + return Json::fail(ProductReplyModel::getErrorInfo('回复失败,请稍候再试!')); + else + return Json::successful('回复成功!'); + } + + public function edit_reply(Request $request){ + $data = Util::postMore([ + 'id', + 'content', + ],$request); + if(!$data['id']) return Json::fail('参数错误'); + if($data['content'] == '') return Json::fail('请输入回复内容'); + $save['merchant_reply_content'] = $data['content']; + $save['merchant_reply_time'] = time(); + $save['is_reply'] = 2; + $res = ProductReplyModel::edit($save,$data['id']); + if(!$res) + return Json::fail(ProductReplyModel::getErrorInfo('回复失败,请稍候再试!')); + else + return Json::successful('回复成功!'); + } + +} diff --git a/application/admin/controller/system/Clear.php b/application/admin/controller/system/Clear.php new file mode 100644 index 00000000..c035d4c8 --- /dev/null +++ b/application/admin/controller/system/Clear.php @@ -0,0 +1,60 @@ +fetch(); + } + public function refresh_cache(){ + if(function_exists('shell_exec')){ + `php think optimize:schema`; + `php think optimize:autoload`; + `php think optimize:route`; + `php think optimize:config`; + }else if(function_exists('exec')){ + exec('php think optimize:schema'); + exec('php think optimize:autoload'); + exec('php think optimize:route'); + exec('php think optimize:config'); + } + return Json::successful('数据缓存刷新成功!'); + } + public function delete_cache(){ + $this->delDirAndFile("./runtime/temp"); + $this->delDirAndFile("./runtime/cache"); + return Json::successful('清除缓存成功!'); + } + public function delete_log(){ + $this->delDirAndFile("./runtime/log"); + return Json::successful('清除日志成功!'); + } + function delDirAndFile($dirName,$subdir=true){ + if ($handle = opendir("$dirName")){ + while(false !== ($item = readdir($handle))){ + if($item != "." && $item != ".."){ + if(is_dir("$dirName/$item")) + $this->delDirAndFile("$dirName/$item",false); + else + @unlink("$dirName/$item"); + } + } + closedir($handle); + if(!$subdir) @rmdir($dirName); + } + } +} + + diff --git a/application/admin/controller/system/SystemAttachment.php b/application/admin/controller/system/SystemAttachment.php new file mode 100644 index 00000000..b17cdb37 --- /dev/null +++ b/application/admin/controller/system/SystemAttachment.php @@ -0,0 +1,41 @@ +status==false && $res->error){ + exit(json_encode(['state'=>$res->error])); + } + $fileInfo = $res->fileInfo->getinfo(); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachmentModel::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,'',0); + $info = array( + "originalName" => $fileInfo['name'], + "name" => $res->fileInfo->getSaveName(), + "url" => '.'.$res->dir, + "size" => $fileInfo['size'], + "type" => $fileInfo['type'], + "state" => "SUCCESS" + ); + echo json_encode($info); + } +} diff --git a/application/admin/controller/system/SystemClear.php b/application/admin/controller/system/SystemClear.php new file mode 100644 index 00000000..6acbdd27 --- /dev/null +++ b/application/admin/controller/system/SystemClear.php @@ -0,0 +1,53 @@ +fetch(); + } + public function refresh_cache(){ + `php think optimize:schema`; + `php think optimize:autoload`; + `php think optimize:route`; + `php think optimize:config`; + return Json::successful('数据缓存刷新成功!'); + } + public function delete_cache(){ + $this->delDirAndFile("./runtime/temp"); + $this->delDirAndFile("./runtime/cache"); + return Json::successful('清除缓存成功!'); + } + public function delete_log(){ + $this->delDirAndFile("./runtime/log"); + return Json::successful('清除日志成功!'); + } + function delDirAndFile($dirName,$subdir=true){ + if ($handle = opendir("$dirName")){ + while(false !== ($item = readdir($handle))){ + if($item != "." && $item != ".."){ + if(is_dir("$dirName/$item")) + $this->delDirAndFile("$dirName/$item",false); + else + @unlink("$dirName/$item"); + } + } + closedir($handle); + if(!$subdir) @rmdir($dirName); + } + } +} + + diff --git a/application/admin/controller/system/SystemCleardata.php b/application/admin/controller/system/SystemCleardata.php new file mode 100644 index 00000000..6da840f1 --- /dev/null +++ b/application/admin/controller/system/SystemCleardata.php @@ -0,0 +1,157 @@ +fetch(); + } + //清除用户数据 + public function UserRelevant(){ + SystemCleardata::ClearData('user_recharge',1); + SystemCleardata::ClearData('user_address',1); + SystemCleardata::ClearData('user_bill',1); + SystemCleardata::ClearData('user_enter',1); + SystemCleardata::ClearData('user_extract',1); + SystemCleardata::ClearData('user_notice',1); + SystemCleardata::ClearData('user_notice_see',1); + SystemCleardata::ClearData('wechat_qrcode',1); + SystemCleardata::ClearData('wechat_message',1); + SystemCleardata::ClearData('store_coupon_user',1); + SystemCleardata::ClearData('store_coupon_issue_user',1); + SystemCleardata::ClearData('store_bargain_user',1); + SystemCleardata::ClearData('store_bargain_user_help',1); + SystemCleardata::ClearData('store_product_reply',1); + $this->delDirAndFile('./public/uploads/store/comment'); + SystemCleardata::ClearData('store_product_relation',1); + return Json::successful('清除数据成功!'); + } + //清除商城数据 + public function storedata(){ + SystemCleardata::ClearData('store_coupon',1); + SystemCleardata::ClearData('store_coupon_issue',1); + SystemCleardata::ClearData('store_bargain',1); + SystemCleardata::ClearData('store_combination',1); + SystemCleardata::ClearData('store_product_attr',1); + SystemCleardata::ClearData('store_product_attr_result',1); + SystemCleardata::ClearData('store_product_attr_value',1); + SystemCleardata::ClearData('store_seckill',1); + SystemCleardata::ClearData('store_product',1); + $this->delDirAndFile('./public/uploads/store/product'); + + return Json::successful('清除数据成功!'); + } + //清除产品分类 + public function categorydata(){ + SystemCleardata::ClearData('store_category',1); + $this->delDirAndFile('./public/uploads/store/product'); + return Json::successful('清除数据成功!'); + } + //清除订单数据 + public function orderdata(){ + SystemCleardata::ClearData('store_order',1); + SystemCleardata::ClearData('store_order_cart_info',1); + SystemCleardata::ClearData('store_order_copy',1); + SystemCleardata::ClearData('store_order_status',1); + SystemCleardata::ClearData('store_pink',1); + SystemCleardata::ClearData('store_cart',1); + return Json::successful('清除数据成功!'); + } + //清除客服数据 + public function kefudata(){ + SystemCleardata::ClearData('store_service',1); + $this->delDirAndFile('./public/uploads/store/service'); + SystemCleardata::ClearData('store_service_log',1); + return Json::successful('清除数据成功!'); + } + //修改用户默认密码 + public function userdate(){ + SystemCleardata::ClearData('user',1); + $headimgurl= WechatUser::Where('uid',1)->value('headimgurl'); + $data['account']='crmeb'; + $data['pwd']=md5(123456); + $data['avatar']=$headimgurl; + $data['add_time']=time(); + $data['status']=1; + $data['level']=0; + $data['user_type']="wechat"; + $data['is_promoter']=1; + User::create($data); + return Json::successful('清除数据成功!'); + } + //清除微信管理数据 + public function wechatdata(){ + SystemCleardata::ClearData('wechat_media',1); + SystemCleardata::ClearData('wechat_reply',1); + SystemCleardata::ClearData('wechat_news_content',1); + SystemCleardata::ClearData('wechat_news',1); + SystemCleardata::ClearData('wechat_news_category',1); + $this->delDirAndFile('./public/uploads/wechat'); + return Json::successful('清除数据成功!'); + } + //清除所有附件 + public function uploaddata(){ + $this->delDirAndFile('./public/uploads'); + return Json::successful('清除上传文件成功!'); + } + //清除微信用户 + public function wechatuserdata(){ + $data= WechatUser::get(1)->toArray(); + SystemCleardata::ClearData('wechat_user',1); + unset($data['uid']); + WechatUser::set($data); + return Json::successful('清除数据成功!'); + } + //清除内容分类 + public function articledata(){ + SystemCleardata::ClearData('article_category',1); + $this->delDirAndFile('./public/uploads/article/'); + return Json::successful('清除数据成功!'); + } + //清除制定表数据 + public function ClearData($table_name,$status){ + $table_name = Config::get('database')['prefix'].$table_name; + if($status){ + db::query('TRUNCATE TABLE '.$table_name); + }else{ + db::query('DELETE FROM'.$table_name); + } + + } + //递归删除文件 + function delDirAndFile($dirName,$subdir=true){ + if ($handle = opendir("$dirName")){ + while(false !== ($item = readdir($handle))){ + if($item != "." && $item != ".."){ + if(is_dir("$dirName/$item")) + $this->delDirAndFile("$dirName/$item",false); + else + @unlink("$dirName/$item"); + } + } + closedir($handle); + if(!$subdir) @rmdir($dirName); + } + } +} \ No newline at end of file diff --git a/application/admin/controller/system/SystemFile.php b/application/admin/controller/system/SystemFile.php new file mode 100644 index 00000000..af98bb2c --- /dev/null +++ b/application/admin/controller/system/SystemFile.php @@ -0,0 +1,233 @@ +getDir('./application'); + $extend = $this->getDir('./extend'); + $public = $this->getDir('./public'); + $arr = array(); + $arr = array_merge($app,$extend); + $arr = array_merge($arr,$public); + $fileAll = array();//本地文件 + $cha = array();//不同的文件 + foreach ($arr as $k=>$v) { + $fp = fopen($v, 'r'); + if (filesize($v)) $ct = fread($fp, filesize($v)); + else $ct = null; + fclose($fp); + $cthash = md5($ct); + $update_time = stat($v); + $fileAll[$k]['cthash'] = $cthash; + $fileAll[$k]['filename'] = $v; + $fileAll[$k]['atime'] = $update_time['atime']; + $fileAll[$k]['mtime'] = $update_time['mtime']; + $fileAll[$k]['ctime'] = $update_time['ctime']; + } + $file = SystemFileModel::all(function($query){ + $query->order('atime', 'desc'); + })->toArray();//数据库中的文件 + if(empty($file)){ + $data_num = array_chunk($fileAll,10); + SystemFileModel::beginTrans(); + $res = true; + foreach ($data_num as $k=>$v){ + $res = $res && SystemFileModel::insertAll($v); + } + SystemFileModel::checkTrans($res); + if($res){ + $cha = array();//不同的文件 + }else{ + $cha = $fileAll; + } + }else{ + $cha = array();//差异文件 + foreach ($file as $k=>$v){ + foreach ($fileAll as $ko=>$vo){ + if($v['filename'] == $vo['filename']){ + if($v['cthash'] != $vo['cthash']){ + $cha[$k]['filename'] = $v['filename']; + $cha[$k]['cthash'] = $v['cthash']; + $cha[$k]['atime'] = $v['atime']; + $cha[$k]['mtime'] = $v['mtime']; + $cha[$k]['ctime'] = $v['ctime']; + $cha[$k]['type'] = '已修改'; + } + unset($fileAll[$ko]); + unset($file[$k]); + } + } + + } + foreach ($file as $k=>$v){ + $cha[$k]['filename'] = $v['filename']; + $cha[$k]['cthash'] = $v['cthash']; + $cha[$k]['atime'] = $v['atime']; + $cha[$k]['mtime'] = $v['mtime']; + $cha[$k]['ctime'] = $v['ctime']; + $cha[$k]['type'] = '已删除'; + } + foreach ($fileAll as $k=>$v){ + $cha[$k]['filename'] = $v['filename']; + $cha[$k]['cthash'] = $v['cthash']; + $cha[$k]['atime'] = $v['atime']; + $cha[$k]['mtime'] = $v['mtime']; + $cha[$k]['ctime'] = $v['ctime']; + $cha[$k]['type'] = '新增的'; + } + + } +// dump($file); +// dump($fileAll); + $this->assign('cha',$cha); + return $this->fetch(); + } + public function filelist(){ + $app = $this->getDir('./application'); + print_r($app); + $extend = $this->getDir('./extend'); + $public = $this->getDir('./public'); + $arr = array(); + $arr = array_merge($app,$extend); + $arr = array_merge($arr,$public); + $fileAll = array();//本地文件 + foreach ($arr as $k=>$v) { + $fp = fopen($v, 'r'); + if (filesize($v)) $ct = fread($fp, filesize($v)); + else $ct = null; + fclose($fp); + $cthash = md5($ct); + $update_time = stat($v); + $fileAll[$k]['cthash'] = $cthash; + $fileAll[$k]['filename'] = $v; + $fileAll[$k]['atime'] = $update_time['atime']; + $fileAll[$k]['mtime'] = $update_time['mtime']; + $fileAll[$k]['ctime'] = $update_time['ctime']; + } + +// dump($file); + dump($fileAll); + } + /** + * 获取文件夹中的文件 不包括子文件 + * @param $dir + * @return array + */ + public function getNextDir(){ + $dir = './'; + $list = scandir($dir); + $dirlist = array(); + $filelist = array(); + foreach($list as $key=>$v) { + if($v !='.' && $v !='..'){ + if (is_dir($dir.'/'.$v)) { + $dirlist[$key]['name'] = $v; + $dirlist[$key]['type'] = 'dir'; + } + if(is_file($dir.'/'.$v)){ + $filelist[$key]['name'] = $v; + $filelist[$key]['type'] = 'file'; + } + } + } + $filesarr = array_merge($dirlist,$filelist); + print_r($filesarr); + } + /** + * 获取文件夹中的文件 包括子文件 不能直接用 直接使用 $this->getDir()方法 P156 + * @param $path + * @param $data + */ + public function searchDir($path,&$data){ + if(is_dir($path) && !strpos($path,'uploads')){ + $dp=dir($path); + while($file=$dp->read()){ + if($file!='.'&& $file!='..'){ + $this->searchDir($path.'/'.$file,$data); + } + } + $dp->close(); + } + if(is_file($path)){ + $data[]=$path; + } + } + + /** + * 获取文件夹中的文件 包括子文件 + * @param $dir + * @return array + */ + public function getDir($dir){ + $data=array(); + $this->searchDir($dir,$data); + return $data; + } + + //测试 + public function ceshi(){ + //创建form + $form = Form::create('/save.php',[ + Form::input('goods_name','商品名称') + ,Form::input('goods_name1','password')->type('password') + ,Form::input('goods_name2','textarea')->type('textarea') + ,Form::input('goods_name3','email')->type('email') + ,Form::input('goods_name4','date')->type('date') + ,Form::cityArea('address','cityArea',[ + '陕西省','西安市' + ]) + ,Form::dateRange('limit_time','dateRange', + strtotime('- 10 day'), + time() + ) + ,Form::dateTime('add_time','dateTime') + ,Form::color('color','color','#ff0000') + ,Form::checkbox('checkbox','checkbox',[1])->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']]) + ,Form::date('riqi','date','2018-03-1') + ,Form::dateTimeRange('dateTimeRange','区间时间段') + ,Form::year('year','year') + ,Form::month('month','month') + ,Form::frame('frame','frame','/admin/system.system_attachment/index.html?fodder=frame') + ,Form::frameInputs('frameInputs','frameInputs','/admin/system.system_attachment/index.html?fodder=frameInputs') + ,Form::frameFiles('month1','frameFiles','/admin/system.system_attachment/index.html?fodder=month1') + ,Form::frameImages('fodder1','frameImages','/admin/system.system_attachment/index.html?fodder=fodder1')->maxLength(3)->width('800px')->height('400px') + ,Form::frameImages('fodder11','frameImages','/admin/system.system_attachment/index.html?fodder=fodder11')->icon('images') + ,Form::frameInputOne('month3','frameInputOne','/admin/system.system_attachment/index.html?fodder=month3')->icon('ionic') + ,Form::frameFileOne('month4','frameFileOne','/admin/system.system_attachment/index.html?fodder=month4') + ,Form::frameImageOne('month5','frameImageOne','/admin/system.system_attachment/index.html?fodder=month5')->icon('image') + ,Form::hidden('month6','hidden') + ,Form::number('month7','number') +// ,Form::input input输入框,其他type: text类型Form::text,password类型Form::password,textarea类型Form::textarea,url类型Form::url,email类型Form::email,date类型Form::idate + ,Form::radio('month8','radio')->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']]) + ,Form::rate('month9','rate') + ,Form::select('month10','select')->options([['value'=>1,'label'=>'白色'],['value'=>2,'label'=>'红色'],['value'=>31,'label'=>'黑色']]) + ,Form::selectMultiple('month11','selectMultiple') + ,Form::selectOne('month12','selectOne') + ,Form::slider('month13','slider',2) + ,Form::sliderRange('month23','sliderRange',2,13) + ,Form::switches('month14','区间时间段') + ,Form::timePicker('month15','区间时间段') + ,Form::time('month16','区间时间段') + ,Form::timeRange('month17','区间时间段') +// ,Form::upload('month','区间时间段') +// ,Form::uploadImages('month','区间时间段') +// ,Form::uploadFiles('month','区间时间段') +// ,Form::uploadImageOne('month','区间时间段') +// ,Form::uploadFileOne('month','区间时间段') + + ]); + $html = $form->setMethod('get')->setTitle('编辑商品')->view(); + echo $html; + } +} diff --git a/application/admin/controller/system/SystemLog.php b/application/admin/controller/system/SystemLog.php new file mode 100644 index 00000000..fef5e516 --- /dev/null +++ b/application/admin/controller/system/SystemLog.php @@ -0,0 +1 @@ +request); $where['level'] = $this->adminInfo['level']; $this->assign('where',$where); $this->assign('admin',SystemAdmin::getOrdAdmin('id,real_name',$this->adminInfo['level'])); $this->assign(LogModel::systemPage($where)); return $this->fetch(); } } \ No newline at end of file diff --git a/application/admin/controller/system/SystemUpgradeclient.php b/application/admin/controller/system/SystemUpgradeclient.php new file mode 100644 index 00000000..57a14d76 --- /dev/null +++ b/application/admin/controller/system/SystemUpgradeclient.php @@ -0,0 +1,196 @@ +'1.0','version_code'=>0);//本站点信息 + public function _initialize() + { + parent::_initialize(); + //屏蔽所有错误避免操作文件夹发生错误提示 + ini_set('display_errors',0); + error_reporting(0); + self::snyweninfo();//更新站点信息 + $this->assign(['auth'=>self::isauth(),'app'=>uService::isWritable(APP_PATH),'extend'=>uService::isWritable(EXTEND_PATH),'public'=>uService::isWritable(ROOT_PATH.'public')]); + } + //同步更新站点信息 + public function snyweninfo(){ + $this->serverweb['ip'] = $this->request->ip(); + $this->serverweb['host'] = $this->request->host(); + $this->serverweb['https'] = !empty($this->request->domain())?$this->request->domain():SystemConfig::getValue('site_url'); + $this->serverweb['webname'] = SystemConfig::getValue('site_name'); + $local=uService::getVersion(); + if($local['code']==200 && isset($local['msg']['version']) && isset($local['msg']['version_code'])){ + $this->serverweb['version'] = uService::replace($local['msg']['version']); + $this->serverweb['version_code'] = (int)uService::replace($local['msg']['version_code']); + } + uService::snyweninfo($this->serverweb); + } + //是否授权 + public function isauth(){ + return uService::isauth(); + } + public function index(){ + $server=uService::start(); + $version=$this->serverweb['version']; + $version_code=$this->serverweb['version_code']; + $this->assign(compact('server','version','version_code')); + return $this->fetch(); + } + public function get_list(){ + $list=uService::request_post(uService::$isList,['page'=>input('post.page/d'),'limit'=>input('post.limit/d')]); + if(is_array($list) && isset($list['code']) && isset($list['data']) && $list['code']==200){ + $list=$list['data']; + }else{ + $list=[]; + } + Json::successful('ok',['list'=>$list,'page'=>input('post.page/d')+1]); + } + //删除备份文件 + public function setcopydel(){ + $post=input('post.'); + if(!isset($post['id'])) Json::fail('删除备份文件失败,缺少参数ID'); + if(!isset($post['ids'])) Json::fail('删除备份文件失败,缺少参数IDS'); + $fileservice=new uService; + if(is_array($post['ids'])){ + foreach ($post['ids'] as $file){ + $fileservice->del_dir(ROOT_PATH.'public'.DS.'copyfile'.$file); + } + } + if($post['id']){ + $copyFile=ROOT_PATH.'public'.DS.'copyfile'.$post['id']; + $fileservice->del_dir($copyFile); + } + Json::successful('删除成功'); + } + public function get_new_version_conte(){ + $post=$this->request->post(); + if(!isset($post['id'])) Json::fail('缺少参数ID'); + $versionInfo=uService::request_post(uService::$NewVersionCount,['id'=>$post['id']]); + if(isset($versionInfo['code']) && isset($versionInfo['data']['count']) && $versionInfo['code']==200){ + return Json::successful(['count'=>$versionInfo['data']['count']]); + }else{ + return Json::fail('服务器异常'); + } + } + //一键升级 + public function auto_upgrad(){ + $prefix=config('database.prefix'); + $fileservice=new uService; + $post=$this->request->post(); + if(!isset($post['id'])) Json::fail('缺少参数ID'); + $versionInfo=$fileservice->request_post(uService::$isNowVersion,['id'=>$post['id']]); + if($versionInfo===null) Json::fail('服务器异常,请稍后再试'); + if(isset($versionInfo['code']) && $versionInfo['code']==400) Json::fail(isset($versionInfo['msg'])?$versionInfo['msg']:'您暂时没有权限升级,请联系管理员!'); + if(is_array($versionInfo) && isset($versionInfo['data'])){ + $list=$versionInfo['data']; + $id=[]; + foreach ($list as $key=>$val){ + $savefile=ROOT_PATH . 'public' . DS.'upgrade_lv'; + //1,检查远程下载文件,并下载 + if(($save_path=$fileservice->check_remote_file_exists($val['zip_name'],$savefile))===false) Json::fail('远程升级包不存在'); + //2,首先解压文件 + $savename=ROOT_PATH.'public'.DS.'upgrade_lv'.DS.time(); + $fileservice->zipopen($save_path,$savename); + //3,执行SQL文件 + Db::startTrans(); + try{ + //参数3不介意大小写的 + $sqlfile=$fileservice->list_dir_info($savename.DS,true,'sql'); + if(is_array($sqlfile) && !empty($sqlfile)){ + foreach($sqlfile as $file){ + if(file_exists($file)){ + //为一键安装做工作记得表前缀要改为[#DB_PREFIX#]哦 + $execute_sql=explode(";\r",str_replace(['[#DB_PREFIX#]', "\n"], [$prefix, "\r"], file_get_contents($file))); + foreach($execute_sql as $_sql){ + if ($query_string = trim(str_replace(array( + "\r", + "\n", + "\t" + ), '', $_sql))) Db::execute($query_string); + } + //执行完sql记得删掉哦 + $fileservice->unlink_file($file); + } + } + } + Db::commit(); + }catch(\Exception $e){ + Db::rollback(); + //删除解压下的文件 + $fileservice->del_dir(ROOT_PATH.'public'.DS.'upgrade_lv'); + //删除压缩包 + $fileservice->unlink_file($save_path); + //升级失败发送错误信息 + $fileservice->request_post(uService::$isInsertLog,[ + 'content'=>'升级失败,错误信息为:'.$e->getMessage(), + 'add_time'=>time(), + 'ip'=>$this->request->ip(), + 'http'=>$this->request->domain(), + 'type'=>'error', + 'version'=>$val['version'] + ]); + return Json::fail('升级失败SQL文件执行有误'); + } + //4,备份文件 + $copyFile=ROOT_PATH.'public'.DS.'copyfile'.$val['id']; + $copyList=$fileservice->get_dirs($savename.DS); + if(isset($copyList['dir'])){ + if($copyList['dir'][0]=='.' && $copyList['dir'][1]=='..'){ + array_shift($copyList['dir']); + array_shift($copyList['dir']); + } + foreach($copyList['dir'] as $dir){ + if(file_exists(ROOT_PATH.$dir,$copyFile.DS.$dir)){ + $fileservice->copy_dir(ROOT_PATH.$dir,$copyFile.DS.$dir); + } + } + } + //5,覆盖文件 + $fileservice->handle_dir($savename,ROOT_PATH); + //6,删除升级生成的目录 + $fileservice->del_dir(ROOT_PATH.'public'.DS.'upgrade_lv'); + //7,删除压缩包 + $fileservice->unlink_file($save_path); + //8,改写本地升级文件 + $handle=fopen(APP_PATH.'version.php','w+'); + if($handle===false) Json::fail(APP_PATH.'version.php'.'无法写入打开'); + $content=<<$this->request->ip(), + 'https'=>$this->request->domain(), + 'update_time'=>time(), + 'content'=>'一键升级成功,升级版本号为:'.$val['version'].'。版本code为:'.$val['id'], + 'type'=>'log', + 'versionbefor'=>$this->serverweb['version'], + 'versionend'=>$val['version'] + ]; + $inset=$fileservice->request_post(uService::$isInsertLog,$posts); + $id[]=$val['id']; + } + //10,升级完成 + Json::successful('升级成功',['code'=>end($id),'version'=>$val['version']]); + }else{ + Json::fail('服务器异常,请稍后再试'); + } + } +} \ No newline at end of file diff --git a/application/admin/controller/ump/StoreCoupon.php b/application/admin/controller/ump/StoreCoupon.php new file mode 100644 index 00000000..dc6a847e --- /dev/null +++ b/application/admin/controller/ump/StoreCoupon.php @@ -0,0 +1,281 @@ +request); + $this->assign('where',$where); + $this->assign(CouponModel::systemPage($where)); + return $this->fetch(); + } + + /** + * @return mixed + */ + public function create() + { + $f = array(); + $f[] = Form::input('title','优惠券名称'); + $f[] = Form::number('coupon_price','优惠券面值',0)->min(0); + $f[] = Form::number('use_min_price','优惠券最低消费')->min(0); + $f[] = Form::number('coupon_time','优惠券有效期限')->min(0); + $f[] = Form::number('sort','排序'); + $f[] = Form::radio('status','状态',0)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + + $form = Form::make_post_form('添加优惠券',$f,Url::build('save'));//->setSuccessScript(''); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * @param Request $request + * @return \think\response\Json + */ + public function save(Request $request) + { + $data = Util::postMore([ + 'title', + 'coupon_price', + 'use_min_price', + 'coupon_time', + 'sort', + ['status',0] + ],$request); + if(!$data['title']) return Json::fail('请输入优惠券名称'); + if(!$data['coupon_price']) return Json::fail('请输入优惠券面值'); + if(!$data['coupon_time']) return Json::fail('请输入优惠券有效期限'); + $data['add_time'] = time(); + CouponModel::set($data); + return Json::successful('添加优惠券成功!'); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + $coupon = CouponModel::get($id); + if(!$coupon) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('title','优惠券名称',$coupon->getData('title')); + $f[] = Form::number('coupon_price','优惠券面值',$coupon->getData('coupon_price'))->min(0); + $f[] = Form::number('use_min_price','优惠券最低消费',$coupon->getData('use_min_price'))->min(0); + $f[] = Form::number('coupon_time','优惠券有效期限',$coupon->getData('coupon_time'))->min(0); + $f[] = Form::number('sort','排序',$coupon->getData('sort')); + $f[] = Form::radio('status','状态',$coupon->getData('status'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + + $form = Form::make_post_form('添加优惠券',$f,Url::build('update',array('id'=>$id))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + + /** + * 保存更新的资源 + * + * @param \think\Request $request + * @param int $id + * @return \think\Response + */ + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'title', + 'coupon_price', + 'use_min_price', + 'coupon_time', + 'sort', + ['status',0] + ],$request); + if(!$data['title']) return Json::fail('请输入优惠券名称'); + if(!$data['coupon_price']) return Json::fail('请输入优惠券面值'); + if(!$data['coupon_time']) return Json::fail('请输入优惠券有效期限'); + CouponModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!$id) return Json::fail('数据不存在!'); + $data['is_del'] = 1; + if(!CouponModel::edit($data,$id)) + return Json::fail(CouponModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + /** + * 修改优惠券状态 + * @param $id + * @return \think\response\Json + */ + public function status($id) + { + if(!$id) return Json::fail('数据不存在!'); + if(!CouponModel::editIsDel($id)) + return Json::fail(CouponModel::getErrorInfo('修改失败,请稍候再试!')); + else + return Json::successful('修改成功!'); + } + + /** + * @return mixed + */ + public function grant_subscribe(){ + $where = Util::getMore([ + ['status',''], + ['title',''], + ['is_del',0], + ],$this->request); + $this->assign('where',$where); + $this->assign(CouponModel::systemPageCoupon($where)); + return $this->fetch(); + } + + /** + * @return mixed + */ + public function grant_all(){ + $where = Util::getMore([ + ['status',''], + ['title',''], + ['is_del',0], + ],$this->request); + $this->assign('where',$where); + $this->assign(CouponModel::systemPageCoupon($where)); + return $this->fetch(); + } + + /** + * @param $id + */ + public function grant($id){ + $where = Util::getMore([ + ['status',''], + ['title',''], + ['is_del',0], + ],$this->request); + $nickname = UserModel::where('uid','IN',$id)->column('uid,nickname'); + $this->assign('where',$where); + $this->assign('uid',$id); + $this->assign('nickname',implode(',',$nickname)); + $this->assign(CouponModel::systemPageCoupon($where)); + return $this->fetch(); + } + + public function issue($id) + { + if(!CouponModel::be(['id'=>$id,'status'=>1,'is_del'=>0])) + return $this->failed('发布的优惠劵已失效或不存在!'); + $f = array(); + $f[] = Form::input('id','优惠劵ID',$id)->disabled(1); + $f[] = Form::dateTimeRange('range_date','领取时间')->placeholder('不填为永久有效'); + $f[] = Form::number('count','发布数量',0)->min(0)->placeholder('不填或填0,为不限量'); + $f[] = Form::radio('is_permanent','是否不限量',0)->options([['label'=>'限量','value'=>0],['label'=>'不限量','value'=>1]]); + $f[] = Form::radio('status','状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + + $form = Form::make_post_form('添加优惠券',$f,Url::build('update_issue',array('id'=>$id))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + +// FormBuilder::text('id','优惠劵ID',$id)->disabled(); +// FormBuilder::dateTimeRange('range_date','领取时间')->placeholder('不填为永久有效'); +// FormBuilder::text('count','发布数量')->placeholder('不填或填0,为不限量'); +// FormBuilder::radio('status','是否开启',[ +// ['value'=>1,'label'=>'开启'], +// ['value'=>0,'label'=>'关闭'] +// ],1); +// $this->assign(['title'=>'发布优惠券','rules'=>FormBuilder::builder()->getContent(),'action'=>Url::build('update_issue',array('id'=>$id))]); +// return $this->fetch('public/common_form'); + } + + public function update_issue(Request $request,$id) + { + list($_id,$rangeTime,$count,$status) = UtilService::postMore([ + 'id',['range_date',['','']],['count',0],['status',0] + ],$request,true); + if($_id != $id) return JsonService::fail('操作失败,信息不对称'); + if(!$count) $count = 0; + if(!CouponModel::be(['id'=>$id,'status'=>1,'is_del'=>0])) return JsonService::fail('发布的优惠劵已失效或不存在!'); + if(count($rangeTime)!=2) return JsonService::fail('请选择正确的时间区间'); + + list($startTime,$endTime) = $rangeTime; +// echo $startTime;echo $endTime;var_dump($rangeTime);die; + if(!$startTime) $startTime = 0; + if(!$endTime) $endTime = 0; + if(!$startTime && $endTime) return JsonService::fail('请选择正确的开始时间'); + if($startTime && !$endTime) return JsonService::fail('请选择正确的结束时间'); + if(StoreCouponIssue::setIssue($id,$count,strtotime($startTime),strtotime($endTime),$count,$status)) + return JsonService::successful('发布优惠劵成功!'); + else + return JsonService::fail('发布优惠劵失败!'); + } + + + /** + * 给分组用户发放优惠券 + */ + public function grant_group(){ + $where = Util::getMore([ + ['status',''], + ['title',''], + ['is_del',0], + ],$this->request); + $group = UserModel::getUserGroup(); + $this->assign('where',$where); + $this->assign('group',json_encode($group)); + $this->assign(CouponModel::systemPageCoupon($where)); + return $this->fetch(); + } + /** + * 给标签用户发放优惠券 + */ + public function grant_tag(){ + $where = Util::getMore([ + ['status',''], + ['title',''], + ['is_del',0], + ],$this->request); + $tag = UserModel::getUserTag();;//获取所有标签 + $this->assign('where',$where); + $this->assign('tag',json_encode($tag)); + $this->assign(CouponModel::systemPageCoupon($where)); + return $this->fetch(); + } +} diff --git a/application/admin/controller/ump/StoreCouponIssue.php b/application/admin/controller/ump/StoreCouponIssue.php new file mode 100644 index 00000000..05b0fc8f --- /dev/null +++ b/application/admin/controller/ump/StoreCouponIssue.php @@ -0,0 +1,63 @@ + + * @day: 2018/01/17 + */ + +namespace app\admin\controller\ump; + + +use app\admin\controller\AuthController; +use service\FormBuilder as Form; +use app\admin\model\ump\StoreCouponIssue as CouponIssueModel; +use app\admin\model\ump\StoreCouponIssueUser; +use service\JsonService; +use think\Url; +use traits\CurdControllerTrait; +use service\UtilService as Util; + +class StoreCouponIssue extends AuthController +{ + use CurdControllerTrait; + + protected $bindModel = CouponIssueModel::class; + + public function index() + { + $where=Util::getMore([ + ['status',''], + ['coupon_title',''] + ]); + $this->assign(CouponIssueModel::stsypage($where)); + $this->assign('where',$where); + return $this->fetch(); + } + + public function delete($id = '') + { + if(!$id) return JsonService::fail('参数有误!'); + if(CouponIssueModel::edit(['is_del'=>1],$id,'id')) + return JsonService::successful('删除成功!'); + else + return JsonService::fail('删除失败!'); + } + + public function edit($id = '') + { + if(!$id) return JsonService::fail('参数有误!'); + $issueInfo = CouponIssueModel::get($id); + if(-1 == $issueInfo['status'] || 1 == $issueInfo['is_del']) return $this->failed('状态错误,无法修改'); + $f = [Form::radio('status','是否开启',$issueInfo['status'])->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])]; + $form = Form::make_post_form('状态修改',$f,Url::build('change_field',array('id'=>$id,'field'=>'status'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + public function issue_log($id = '') + { + if(!$id) return JsonService::fail('参数有误!'); + $this->assign(StoreCouponIssueUser::systemCouponIssuePage($id)); + return $this->fetch(); + } +} \ No newline at end of file diff --git a/application/admin/controller/ump/StoreCouponUser.php b/application/admin/controller/ump/StoreCouponUser.php new file mode 100644 index 00000000..a8ef58ab --- /dev/null +++ b/application/admin/controller/ump/StoreCouponUser.php @@ -0,0 +1,114 @@ +request); + $this->assign('where',$where); + $this->assign(CouponUserModel::systemPage($where)); + return $this->fetch(); + } + + /** + * 给已关注的用户发放优惠券 + * @param $id + */ + public function grant_subscribe($id){ + if(!$id) return Json::fail('数据不存在!'); + $coupon = CouponModel::get($id)->toArray(); + if(!$coupon) return Json::fail('数据不存在!'); + $user = UserModel::getSubscribe('uid'); + if(!CouponUserModel::setCoupon($coupon,$user)) + return Json::fail(CouponUserModel::getErrorInfo('发放失败,请稍候再试!')); + else + return Json::successful('发放成功!'); + } + + /** + * 给所有人发放优惠券 + * @param $id + */ + public function grant_all($id){ + if(!$id) return Json::fail('数据不存在!'); + $coupon = CouponModel::get($id)->toArray(); + if(!$coupon) return Json::fail('数据不存在!'); + $user = UserModel::getUserAll('uid'); + if(!CouponUserModel::setCoupon($coupon,$user)) + return Json::fail(CouponUserModel::getErrorInfo('发放失败,请稍候再试!')); + else + return Json::successful('发放成功!'); + } + + /** + * 发放优惠券到指定个人 + * @param $id + * @param $uid + * @return \think\response\Json + */ + public function grant($id,$uid){ + if(!$id) return Json::fail('数据不存在!'); + $coupon = CouponModel::get($id)->toArray(); + if(!$coupon) return Json::fail('数据不存在!'); + $user = explode(',',$uid); + if(!CouponUserModel::setCoupon($coupon,$user)) + return Json::fail(CouponUserModel::getErrorInfo('发放失败,请稍候再试!')); + else + return Json::successful('发放成功!'); + + } + + public function grant_group($id,Request $request){ + $data = Util::postMore([ + ['group',0] + ],$request); + if(!$id) return Json::fail('数据不存在!'); + $coupon = CouponModel::get($id)->toArray(); + if(!$coupon) return Json::fail('数据不存在!'); + $user = WechatUser::where('groupid',$data['group'])->column('uid','uid'); + if(!CouponUserModel::setCoupon($coupon,$user)) + return Json::fail(CouponUserModel::getErrorInfo('发放失败,请稍候再试!')); + else + return Json::successful('发放成功!'); + } + + public function grant_tag($id,Request $request){ + $data = Util::postMore([ + ['tag',0] + ],$request); + if(!$id) return Json::fail('数据不存在!'); + $coupon = CouponModel::get($id)->toArray(); + if(!$coupon) return Json::fail('数据不存在!'); + $user = WechatUser::where("tagid_list","LIKE","%$data[tag]%")->column('uid','uid'); + if(!CouponUserModel::setCoupon($coupon,$user)) + return Json::fail(CouponUserModel::getErrorInfo('发放失败,请稍候再试!')); + else + return Json::successful('发放成功!'); + } + +} diff --git a/application/admin/controller/ump/StoreSeckill.php b/application/admin/controller/ump/StoreSeckill.php new file mode 100644 index 00000000..b1abcb17 --- /dev/null +++ b/application/admin/controller/ump/StoreSeckill.php @@ -0,0 +1,373 @@ +assign('countSeckill',StoreSeckillModel::getSeckillCount()); + $this->assign('seckillId',StoreSeckillModel::getSeckillIdAll()); + return $this->fetch(); + } + public function save_excel(){ + $where=Util::getMore([ + ['status',''], + ['store_name',''] + ]); + StoreSeckillModel::SaveExcel($where); + } + /** + * 异步获取砍价数据 + */ + public function get_seckill_list(){ + $where=Util::getMore([ + ['page',1], + ['limit',20], + ['status',''], + ['store_name',''] + ]); + $seckillList = StoreSeckillModel::systemPage($where); + if(is_object($seckillList['list'])) $seckillList['list'] = $seckillList['list']->toArray(); + $data = $seckillList['list']['data']; + foreach ($data as $k=>$v){ + $data[$k]['_stop_time'] = date('Y/m/d H:i:s',$v['stop_time']); + } + return Json::successlayui(['count'=>$seckillList['list']['total'],'data'=>$data]); + } + + /** + * 添加秒杀产品 + * @return form-builder + */ + public function create() + { + $f = array(); + $f[] = Form::input('title','产品标题'); + $f[] = Form::input('info','秒杀活动简介')->type('textarea'); + $f[] = Form::input('unit_name','单位')->placeholder('个、位'); + $f[] = Form::dateTimeRange('section_time','活动时间'); + $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')))->icon('image'); + $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')))->maxLength(5)->icon('images'); + $f[] = Form::number('price','秒杀价')->min(0)->col(12); + $f[] = Form::number('ot_price','原价')->min(0)->col(12); + $f[] = Form::number('cost','成本价')->min(0)->col(12); + $f[] = Form::number('stock','库存')->min(0)->precision(0)->col(12); + $f[] = Form::number('sales','销量')->min(0)->precision(0)->col(12); + $f[] = Form::number('sort','排序')->col(12); + $f[] = Form::number('num','单次购买产品个数')->precision(0)->col(12); + $f[] = Form::number('give_integral','赠送积分')->min(0)->precision(0)->col(12); + $f[] = Form::number('postage','邮费')->min(0)->col(12); + $f[] = Form::radio('is_postage','是否包邮',1)->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12); + $f[] = Form::radio('is_hot','热门推荐',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12); + $f[] = Form::radio('status','活动状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12); + $form = Form::make_post_form('添加用户通知',$f,Url::build('save')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /**保存秒杀产品 + * @param Request $request + * @param int $id + */ + public function save(Request $request,$id = 0) + { + $data = Util::postMore([ + 'title', + 'info', + 'unit_name', + ['image',''], + ['images',[]], + 'price', + 'ot_price', + 'cost', + 'sales', + 'stock', + 'sort', + 'give_integral', + 'postage', + ['section_time',[]], + ['is_postage',0], + ['cost',0], + ['is_hot',0], + ['status',0], + ['num',0] + ],$request); + if(!$data['title']) return Json::fail('请输入产品标题'); + if(!$data['unit_name']) return Json::fail('请输入产品单位'); +// var_dump($this->request->post()); + if(count($data['section_time'])<1) return Json::fail('请选择活动时间'); + $data['start_time'] = strtotime($data['section_time'][0]); + $data['stop_time'] = strtotime($data['section_time'][1]); + unset($data['section_time']); + if(!$data['image']) return Json::fail('请选择推荐图'); + if(count($data['images'])<1) return Json::fail('请选择轮播图'); + $data['images'] = json_encode($data['images']); + if($data['price'] == '' || $data['price'] < 0) return Json::fail('请输入产品秒杀售价'); + if($data['ot_price'] == '' || $data['ot_price'] < 0) return Json::fail('请输入产品原售价'); + if($data['cost'] == '' || $data['cost'] < 0) return Json::fail('请输入产品成本价'); + if($data['stock'] == '' || $data['stock'] < 0) return Json::fail('请输入库存'); + $data['add_time'] = time(); + if($data['num']<1) return Json::fail('请输入单次秒杀个数'); + if($id){ + $product = StoreSeckillModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + StoreSeckillModel::edit($data,$id); + return Json::successful('编辑成功!'); + }else{ + StoreSeckillModel::set($data); + return Json::successful('添加成功!'); + } + + } + /** 开启秒杀 + * @param $id + * @return mixed|void + */ + public function seckill($id){ + if(!$id) return $this->failed('数据不存在'); + $product = ProductModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('title','产品标题',$product->getData('store_name')); + $f[] = Form::input('info','秒杀活动简介',$product->getData('store_info'))->type('textarea'); + $f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位'); + $f[] = Form::dateTimeRange('section_time','活动时间'); + $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image'); + $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('slider_image')))->maxLength(5)->icon('images'); + $f[] = Form::number('price','秒杀价')->min(0)->col(12); + $f[] = Form::number('ot_price','原价',$product->getData('price'))->min(0)->col(12); + $f[] = Form::number('cost','成本价',$product->getData('cost'))->min(0)->col(12); + $f[] = Form::number('stock','库存',$product->getData('stock'))->min(0)->precision(0)->col(12); + $f[] = Form::number('sales','销量',$product->getData('sales'))->min(0)->precision(0)->col(12); + $f[] = Form::number('sort','排序',$product->getData('sort'))->col(12); + $f[] = Form::number('num','单次购买产品个数')->precision(0)->col(12); + $f[] = Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->precision(0)->col(12); + $f[] = Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(12); + $f[] = Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12); + $f[] = Form::radio('is_hot','热门推荐',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12); + $f[] = Form::radio('status','活动状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12); + $form = Form::make_post_form('添加用户通知',$f,Url::build('save')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 上传图片 + * @return \think\response\Json + */ + public function upload() + { + $res = Upload::image('file','store/seckill/'.date('Ymd')); + $thumbPath = Upload::thumb($res->dir); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,$thumbPath,4); + + if($res->status == 200) + return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); + else + return Json::fail($res->error); + } + + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + if(!$id) return $this->failed('数据不存在'); + $product = StoreSeckillModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('title','产品标题',$product->getData('title')); + $f[] = Form::input('info','秒杀活动简介',$product->getData('info'))->type('textarea'); + $f[] = Form::input('unit_name','单位',$product->getData('unit_name'))->placeholder('个、位'); + $f[] = Form::dateTimeRange('section_time','活动时间',$product->getData('start_time'),$product->getData('stop_time')); + $f[] = Form::frameImageOne('image','产品主图片(305*305px)',Url::build('admin/widget.images/index',array('fodder'=>'image')),$product->getData('image'))->icon('image'); + $f[] = Form::frameImages('images','产品轮播图(640*640px)',Url::build('admin/widget.images/index',array('fodder'=>'images')),json_decode($product->getData('images')))->maxLength(5)->icon('images'); + $f[] = Form::number('price','秒杀价',$product->getData('price'))->min(0)->col(12); + $f[] = Form::number('ot_price','原价',$product->getData('price'))->min(0)->col(12); + $f[] = Form::number('cost','成本价',$product->getData('cost'))->min(0)->col(12); + $f[] = Form::number('stock','库存',$product->getData('stock'))->min(0)->precision(0)->col(12); + $f[] = Form::number('sales','销量',$product->getData('sales'))->min(0)->precision(0)->col(12); + $f[] = Form::number('sort','排序',$product->getData('sort'))->col(12); + $f[] = Form::number('num','单次购买产品个数',$product->getData('num'))->precision(0)->col(12); + $f[] = Form::number('give_integral','赠送积分',$product->getData('give_integral'))->min(0)->precision(0)->col(12); + $f[] = Form::number('postage','邮费',$product->getData('postage'))->min(0)->col(12); + $f[] = Form::radio('is_postage','是否包邮',$product->getData('is_postage'))->options([['label'=>'是','value'=>1],['label'=>'否','value'=>0]])->col(12); + $f[] = Form::radio('is_hot','热门推荐',$product->getData('is_hot'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12); + $f[] = Form::radio('status','活动状态',$product->getData('status'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]])->col(12); + $form = Form::make_post_form('添加用户通知',$f,Url::build('save',compact('id'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!$id) return $this->failed('数据不存在'); + $data['is_del'] = 1; + if(!StoreSeckillModel::edit($data,$id)) + return Json::fail(StoreSeckillModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + public function edit_content($id){ + if(!$id) return $this->failed('数据不存在'); + $seckill = StoreSeckillModel::get($id); + if(!$seckill) return Json::fail('数据不存在!'); + $this->assign([ + 'content'=>StoreSeckillModel::where('id',$id)->value('description'), + 'field'=>'description', + 'action'=>Url::build('change_field',['id'=>$id,'field'=>'description']) + ]); + return $this->fetch('public/edit_content'); + } + + public function change_field(Request $request,$id,$field){ + if(!$id) return $this->failed('数据不存在'); + $seckill = StoreSeckillModel::get($id); + if(!$seckill) return Json::fail('数据不存在!'); + $data['description'] = $request->post('description'); + $res = StoreSeckillModel::edit($data,$id); + if($res) + return Json::successful('添加成功'); + else + return Json::fail('添加失败'); + } + /** + * 属性页面 + * @param $id + * @return mixed|void + */ + public function attr($id) + { + if(!$id) return $this->failed('数据不存在!'); + $result = StoreSeckillAttrResult::getResult($id); + $image = StoreSeckillModel::where('id',$id)->value('image'); + $this->assign(compact('id','result','product','image')); + return $this->fetch(); + } + + /** + * 生成属性 + * @param int $id + */ + public function is_format_attr($id = 0){ + if(!$id) return Json::fail('产品不存在'); + list($attr,$detail) = Util::postMore([ + ['items',[]], + ['attrs',[]] + ],$this->request,true); + $product = StoreSeckillModel::get($id); + if(!$product) return Json::fail('产品不存在'); + $attrFormat = attrFormat($attr)[1]; + if(count($detail)){ + foreach ($attrFormat as $k=>$v){ + foreach ($detail as $kk=>$vv){ + if($v['detail'] == $vv['detail']){ + $attrFormat[$k]['price'] = $vv['price']; + $attrFormat[$k]['sales'] = $vv['sales']; + $attrFormat[$k]['pic'] = $vv['pic']; + $attrFormat[$k]['check'] = false; + break; + }else{ + $attrFormat[$k]['price'] = ''; + $attrFormat[$k]['sales'] = ''; + $attrFormat[$k]['pic'] = $product['image']; + $attrFormat[$k]['check'] = true; + } + } + } + }else{ + foreach ($attrFormat as $k=>$v){ + $attrFormat[$k]['price'] = $product['price']; + $attrFormat[$k]['sales'] = $product['stock']; + $attrFormat[$k]['pic'] = $product['image']; + $attrFormat[$k]['check'] = false; + } + } + return Json::successful($attrFormat); + } + /** + * 添加 修改属性 + * @param $id + */ + public function set_attr($id) + { + if(!$id) return $this->failed('产品不存在!'); + list($attr,$detail) = Util::postMore([ + ['items',[]], + ['attrs',[]] + ],$this->request,true); + $res = StoreSeckillAttr::createProductAttr($attr,$detail,$id); + if($res) + return $this->successful('编辑属性成功!'); + else + return $this->failed(StoreSeckillAttr::getErrorInfo()); + } + + /** + * 清除属性 + * @param $id + */ + public function clear_attr($id) + { + if(!$id) return $this->failed('产品不存在!'); + if(false !== StoreSeckillAttr::clearProductAttr($id) && false !== StoreSeckillAttrResult::clearResult($id)) + return $this->successful('清空产品属性成功!'); + else + return $this->failed(StoreSeckillAttr::getErrorInfo('清空产品属性失败!')); + } + + /** + * 修改秒杀产品状态 + * @param $status + * @param int $id + */ + public function set_seckill_status($status,$id = 0){ + if(!$id) return Json::fail('参数错误'); + $res = StoreSeckillModel::edit(['status'=>$status],$id); + if($res) return Json::successful('修改成功'); + else return Json::fail('修改失败'); + } +} diff --git a/application/admin/controller/ump/UserPoint.php b/application/admin/controller/ump/UserPoint.php new file mode 100644 index 00000000..d2b2632d --- /dev/null +++ b/application/admin/controller/ump/UserPoint.php @@ -0,0 +1,70 @@ +assign([ + 'is_layui'=>true, + 'year'=>getMonth('y'), + ]); + return $this->fetch(); + } + + /** + * @return mixed + */ + public function create() + { + $this->assign(['title'=>'添加优惠券','action'=>Url::build('save'),'rules'=>$this->rules()->getContent()]); + return $this->fetch('public/common_form'); + } + //异步获取积分列表 + public function getponitlist(){ + $where = Util::getMore([ + ['start_time',''], + ['end_time',''], + ['nickname',''], + ['page',1], + ['limit',10], + ]); + return JsonService::successlayui(UserPointModel::getpointlist($where)); + } + //导出Excel表格 + public function export(){ + $where = Util::getMore([ + ['start_time',''], + ['end_time',''], + ['nickname',''], + ]); + UserPointModel::SaveExport($where); + } + //获取积分日志头部信息 + public function getuserpointbadgelist(){ + $where = Util::getMore([ + ['start_time',''], + ['end_time',''], + ['nickname',''], + ]); + return JsonService::successful(UserPointModel::getUserpointBadgelist($where)); + } + +} diff --git a/application/admin/controller/user/User.php b/application/admin/controller/user/User.php new file mode 100644 index 00000000..b08f1c58 --- /dev/null +++ b/application/admin/controller/user/User.php @@ -0,0 +1 @@ +assign('count_user',UserModel::getcount()); return $this->fetch(); } /** * 修改user表状态 * * @return json */ public function set_status($status='',$uid=0,$is_echo=0){ if($is_echo==0) { if ($status == '' || $uid == 0) return Json::fail('参数错误'); UserModel::where(['uid' => $uid])->update(['status' => $status]); }else{ $uids=Util::postMore([ ['uids',[]] ]); UserModel::destrSyatus($uids['uids'],$status); } return Json::successful($status==0 ? '禁用成功':'解禁成功'); } /** * 获取user表 * * @return json */ public function get_user_list(){ $where=Util::getMore([ ['page',1], ['limit',20], ['nickname',''], ['status',''], ['pay_count',''], ['is_promoter',''], ['order',''], ['data',''], ['user_type',''], ['country',''], ['province',''], ['city',''], ['user_time_type',''], ['user_time',''], ['sex',''], ]); return Json::successlayui(UserModel::getUserList($where)); } /** * 编辑模板消息 * @param $id * @return mixed|\think\response\Json|void */ public function edit($uid) { if(!$uid) return $this->failed('数据不存在'); $user = UserModel::get($uid); if(!$user) return Json::fail('数据不存在!'); $f = array(); $f[] = Form::input('uid','用户编号',$user->getData('uid'))->disabled(1); $f[] = Form::input('nickname','用户姓名',$user->getData('nickname')); $f[] = Form::radio('money_status','修改余额',1)->options([['value'=>1,'label'=>'增加'],['value'=>2,'label'=>'减少']])->col(12); $f[] = Form::number('money','余额')->min(0)->col(12); $f[] = Form::radio('integration_status','修改积分',1)->options([['value'=>1,'label'=>'增加'],['value'=>2,'label'=>'减少']])->col(12); $f[] = Form::number('integration','积分')->min(0)->col(12); $f[] = Form::radio('status','状态',$user->getData('status'))->options([['value'=>1,'label'=>'开启'],['value'=>0,'label'=>'锁定']]); $f[] = Form::radio('is_promoter','推广员',$user->getData('is_promoter'))->options([['value'=>1,'label'=>'开启'],['value'=>0,'label'=>'关闭']]); $form = Form::make_post_form('添加用户通知',$f,Url::build('update',array('id'=>$uid))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } public function update(Request $request, $uid) { $data = Util::postMore([ ['money_status',0], ['is_promoter',1], ['money',0], ['integration_status',0], ['integration',0], ['status',0], ],$request); if(!$uid) return $this->failed('数据不存在'); $user = UserModel::get($uid); if(!$user) return Json::fail('数据不存在!'); ModelBasic::beginTrans(); $res1 = false; $res2 = false; $edit = array(); if($data['money_status'] && $data['money']){//余额增加或者减少 if($data['money_status'] == 1){//增加 $edit['now_money'] = bcadd($user['now_money'],$data['money'],2); $res1 = UserBill::income('系统增加余额',$user['uid'],'now_money','system_add',$data['money'],$this->adminId,$user['now_money'],'系统增加了'.floatval($data['money']).'余额'); try{ HookService::listen('admin_add_money',$user,$data['money'],false,UserBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } }else if($data['money_status'] == 2){//减少 $edit['now_money'] = bcsub($user['now_money'],$data['money'],2); $res1 = UserBill::expend('系统减少余额',$user['uid'],'now_money','system_sub',$data['money'],$this->adminId,$user['now_money'],'系统扣除了'.floatval($data['money']).'余额'); try{ HookService::listen('admin_sub_money',$user,$data['money'],false,UserBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } } }else{ $res1 = true; } if($data['integration_status'] && $data['integration']){//积分增加或者减少 if($data['integration_status'] == 1){//增加 $edit['integral'] = bcadd($user['integral'],$data['integration'],2); $res2 = UserBill::income('系统增加积分',$user['uid'],'integral','system_add',$data['integration'],$this->adminId,$user['integral'],'系统增加了'.floatval($data['integration']).'积分'); try{ HookService::listen('admin_add_integral',$user,$data['integration'],false,UserBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } }else if($data['integration_status'] == 2){//减少 $edit['integral'] = bcsub($user['integral'],$data['integration'],2); $res2 = UserBill::expend('系统减少积分',$user['uid'],'integral','system_sub',$data['integration'],$this->adminId,$user['integral'],'系统扣除了'.floatval($data['integration']).'积分'); try{ HookService::listen('admin_sub_integral',$user,$data['integration'],false,UserBehavior::class); }catch (\Exception $e){ ModelBasic::rollbackTrans(); return Json::fail($e->getMessage()); } } }else{ $res2 = true; } $edit['status'] = $data['status']; $edit['is_promoter'] = $data['is_promoter']; if($edit) $res3 = UserModel::edit($edit,$uid); else $res3 = true; if($res1 && $res2 && $res3) $res =true; else $res = false; ModelBasic::checkTrans($res); if($res) return Json::successful('修改成功!'); else return Json::fail('修改失败'); } /** * 用户图表 * @return mixed */ public function user_analysis(){ $where = Util::getMore([ ['nickname',''], ['status',''], ['is_promoter',''], ['date',''], ['user_type',''], ['export',0] ],$this->request); $user_count=UserModel::consume($where,'',true); //头部信息 $header=[ [ 'name'=>'新增用户', 'class'=>'fa-line-chart', 'value'=>$user_count, 'color'=>'red' ], [ 'name'=>'用户留存', 'class'=>'fa-area-chart', 'value'=>$this->gethreaderValue(UserModel::consume($where,'',true),$where).'%', 'color'=>'lazur' ], [ 'name'=>'新增用户总消费', 'class'=>'fa-bar-chart', 'value'=>'¥'.UserModel::consume($where), 'color'=>'navy' ], [ 'name'=>'用户活跃度', 'class'=>'fa-pie-chart', 'value'=>$this->gethreaderValue(UserModel::consume($where,'',true)).'%', 'color'=>'yellow' ], ]; $name=['新增用户','用户消费']; $dates=$this->get_user_index($where,$name); $user_index=['name'=>json_encode($name), 'date'=>json_encode($dates['time']), 'series'=>json_encode($dates['series'])]; //用户浏览分析 $view=StoreVisit::getVisit($where['date'],['','warning','info','danger']); $view_v1=WechatMessage::getViweList($where['date'],['','warning','info','danger']); $view=array_merge($view,$view_v1); $view_v2=[]; foreach ($view as $val){ $view_v2['color'][]='#'.rand(100000,339899); $view_v2['name'][]=$val['name']; $view_v2['value'][]=$val['value']; } $view=$view_v2; //消费会员排行用户分析 $user_null=UserModel::getUserSpend($where['date']); //消费数据 $now_number=UserModel::getUserSpend($where['date'],true); list($paren_number,$title)=UserModel::getPostNumber($where['date']); if($paren_number==0) { $rightTitle=[ 'number'=>$now_number>0?$now_number:0, 'icon'=>'fa-level-up', 'title'=>$title ]; }else{ $number=(float)bcsub($now_number,$paren_number,4); if($now_number==0){ $icon='fa-level-down'; }else{ $icon=$now_number>$paren_number?'fa-level-up':'fa-level-down'; } $rightTitle=['number'=>$number, 'icon'=>$icon, 'title'=>$title]; } unset($title,$paren_number,$now_number); list($paren_user_count,$title)=UserModel::getPostNumber($where['date'],true,'add_time',''); if($paren_user_count==0){ $count=$user_count==0?0:$user_count; $icon=$user_count==0?'fa-level-down':'fa-level-up'; }else{ $count=(float)bcsub($user_count,$paren_user_count,4); $icon=$user_count<$paren_user_count?'fa-level-down':'fa-level-up'; } $leftTitle=[ 'count'=>$count, 'icon'=>$icon, 'title'=>$title ]; unset($count,$icon,$title); $consume=[ 'title'=>'消费金额为¥'.UserModel::consume($where), 'series'=>UserModel::consume($where,'xiaofei'), 'rightTitle'=>$rightTitle, 'leftTitle'=>$leftTitle, ]; $form=UserModel::consume($where,'form'); $grouping=UserModel::consume($where,'grouping'); $this->assign(compact('header','user_index','view','user_null','consume','form','grouping','where')); return $this->fetch(); } public function gethreaderValue($chart,$where=[]){ if($where){ switch($where['date']){ case null:case 'today':case 'week':case 'year': if($where['date']==null){ $where['date']='month'; } $sum_user=UserModel::whereTime('add_time',$where['date'])->count(); if($sum_user==0) return 0; $counts=bcdiv($chart,$sum_user,4)*100; return $counts; break; case 'quarter': $quarter=UserModel::getMonth('n'); $quarter[0]=strtotime($quarter[0]); $quarter[1]=strtotime($quarter[1]); $sum_user=UserModel::where('add_time','between',$quarter)->count(); if($sum_user==0) return 0; $counts=bcdiv($chart,$sum_user,4)*100; return $counts; default: //自定义时间 $quarter=explode('-',$where['date']); $quarter[0]=strtotime($quarter[0]); $quarter[1]=strtotime($quarter[1]); $sum_user=UserModel::where('add_time','between',$quarter)->count(); if($sum_user==0) return 0; $counts=bcdiv($chart,$sum_user,4)*100; return $counts; break; } }else{ $num=UserModel::count(); $chart=$num!=0?bcdiv($chart,$num,5)*100:0; return $chart; } } public function get_user_index($where,$name){ switch ($where['date']){ case null: $days = date("t",strtotime(date('Y-m',time()))); $dates=[]; $series=[]; $times_list=[]; foreach ($name as $key=>$val){ for($i=1;$i<=$days;$i++){ if(!in_array($i.'号',$times_list)){ array_push($times_list,$i.'号'); } $time=$this->gettime(date("Y-m",time()).'-'.$i); if($key==0){ $dates['data'][]=UserModel::where('add_time','between',$time)->count(); }else if($key==1){ $dates['data'][]=UserModel::consume(true,$time); } } $dates['name']=$val; $dates['type']='line'; $series[]=$dates; unset($dates); } return ['time'=>$times_list,'series'=>$series]; case 'today': $dates=[]; $series=[]; $times_list=[]; foreach ($name as $key=>$val){ for($i=0;$i<=24;$i++){ $strtitle=$i.'点'; if(!in_array($strtitle,$times_list)){ array_push($times_list,$strtitle); } $time=$this->gettime(date("Y-m-d ",time()).$i); if($key==0){ $dates['data'][]=UserModel::where('add_time','between',$time)->count(); }else if($key==1){ $dates['data'][]=UserModel::consume(true,$time); } } $dates['name']=$val; $dates['type']='line'; $series[]=$dates; unset($dates); } return ['time'=>$times_list,'series'=>$series]; case "week": $dates=[]; $series=[]; $times_list=[]; foreach ($name as $key=>$val){ for($i=0;$i<=6;$i++){ if(!in_array('星期'.($i+1),$times_list)){ array_push($times_list,'星期'.($i+1)); } $time=UserModel::getMonth('h',$i); if($key==0){ $dates['data'][]=UserModel::where('add_time','between',[strtotime($time[0]),strtotime($time[1])])->count(); }else if($key==1){ $dates['data'][]=UserModel::consume(true,[strtotime($time[0]),strtotime($time[1])]); } } $dates['name']=$val; $dates['type']='line'; $series[]=$dates; unset($dates); } return ['time'=>$times_list,'series'=>$series]; case 'year': $dates=[]; $series=[]; $times_list=[]; $year=date('Y'); foreach ($name as $key=>$val){ for($i=1;$i<=12;$i++){ if(!in_array($i.'月',$times_list)){ array_push($times_list,$i.'月'); } $t = strtotime($year.'-'.$i.'-01'); $arr= explode('/',date('Y-m-01',$t).'/'.date('Y-m-',$t).date('t',$t)); if($key==0){ $dates['data'][]=UserModel::where('add_time','between',[strtotime($arr[0]),strtotime($arr[1])])->count(); }else if($key==1){ $dates['data'][]=UserModel::consume(true,[strtotime($arr[0]),strtotime($arr[1])]); } } $dates['name']=$val; $dates['type']='line'; $series[]=$dates; unset($dates); } return ['time'=>$times_list,'series'=>$series]; case 'quarter': $dates=[]; $series=[]; $times_list=[]; foreach ($name as $key=>$val){ for($i=1;$i<=4;$i++){ $arr=$this->gettime('quarter',$i); if(!in_array(implode('--',$arr).'季度',$times_list)){ array_push($times_list,implode('--',$arr).'季度'); } if($key==0){ $dates['data'][]=UserModel::where('add_time','between',[strtotime($arr[0]),strtotime($arr[1])])->count(); }else if($key==1){ $dates['data'][]=UserModel::consume(true,[strtotime($arr[0]),strtotime($arr[1])]); } } $dates['name']=$val; $dates['type']='line'; $series[]=$dates; unset($dates); } return ['time'=>$times_list,'series'=>$series]; default: $list=UserModel::consume($where,'default'); $dates=[]; $series=[]; $times_list=[]; foreach ($name as $k=>$v){ foreach ($list as $val){ $date=$val['add_time']; if(!in_array($date,$times_list)){ array_push($times_list,$date); } if($k==0){ $dates['data'][]=$val['num']; }else if($k==1){ $dates['data'][]=UserBill::where(['uid'=>$val['uid'],'type'=>'pay_product'])->sum('number'); } } $dates['name']=$v; $dates['type']='line'; $series[]=$dates; unset($dates); } return ['time'=>$times_list,'series'=>$series]; } } public function gettime($time='',$season=''){ if(!empty($time) && empty($season)){ $timestamp0 = strtotime($time); $timestamp24 =strtotime($time)+86400; return [$timestamp0,$timestamp24]; }else if(!empty($time) && !empty($season)){ $firstday=date('Y-m-01',mktime(0,0,0,($season - 1) *3 +1,1,date('Y'))); $lastday=date('Y-m-t',mktime(0,0,0,$season * 3,1,date('Y'))); return [$firstday,$lastday]; } } /** * 会员等级首页 */ public function group(){ return $this->fetch(); } /** * 会员详情 */ public function see($uid=''){ $this->assign([ 'uid'=>$uid, 'userinfo'=>UserModel::getUserDetailed($uid), 'is_layui'=>true, 'headerList'=>UserModel::getHeaderList($uid), 'count'=>UserModel::getCountInfo($uid), ]); return $this->fetch(); } /** * 获取某用户的订单列表 */ public function getOneorderList($uid,$page=1,$limit=20){ return Json::successful(StoreOrder::getOneorderList(compact('uid','page','limit'))); } /** * 获取某用户的积分列表 */ public function getOneIntegralList($uid,$page=1,$limit=20){ return Json::successful(UserBillAdmin::getOneIntegralList(compact('uid','page','limit'))); } /** * 获取某用户的积分列表 */ public function getOneSignList($uid,$page=1,$limit=20){ return Json::successful(UserBillAdmin::getOneSignList(compact('uid','page','limit'))); } /** * 获取某用户的持有优惠劵 */ public function getOneCouponsList($uid,$page=1,$limit=20){ return Json::successful(StoreCouponUser::getOneCouponsList(compact('uid','page','limit'))); } /** * 获取某用户的余额变动记录 */ public function getOneBalanceChangList($uid,$page=1,$limit=20){ return Json::successful(UserBillAdmin::getOneBalanceChangList(compact('uid','page','limit'))); } } \ No newline at end of file diff --git a/application/admin/controller/user/UserNotice.php b/application/admin/controller/user/UserNotice.php new file mode 100644 index 00000000..13aa3156 --- /dev/null +++ b/application/admin/controller/user/UserNotice.php @@ -0,0 +1,296 @@ +assign(UserNoticeModel::getList()); + return $this->fetch(); + } + + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create(){ + $f = array(); + $f[] = Form::input('user','发送人','系统管理员'); + $f[] = Form::input('title','通知标题'); + $f[] = Form::input('content','通知内容')->type('textarea'); + $f[] = Form::radio('type','消息类型',1)->options([['label'=>'系统消息','value'=>1],['label'=>'用户通知','value'=>2]]); + $form = Form::make_post_form('添加用户通知',$f,Url::build('save')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request){ + $params = $request->post(); + if(!$params["user"])return Json::fail('请输入发送人!'); + if(!$params["title"])return Json::fail('请输入通知标题!'); + if(!$params["content"])return Json::fail('请输入通知内容!'); + if($params["type"] == 2){ + $uids = UserModel::order('uid desc')->column("uid"); + $params["uid"] = count($uids) > 0 ? ",".implode(",",$uids)."," : ""; + } + $params["add_time"] = time(); + UserNoticeModel::set($params); + return Json::successful('添加成功!'); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + $notice = UserNoticeModel::get($id); + if(!$notice) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('user','发送人',$notice["user"]); + $f[] = Form::input('title','通知标题',$notice["title"]); + $f[] = Form::input('content','通知内容',$notice["content"])->type('textarea'); + $f[] = Form::radio('type','消息类型',$notice["type"])->options([['label'=>'系统消息','value'=>1],['label'=>'用户通知','value'=>2]]); + $form = Form::make_post_form('编辑通知',$f,Url::build('update',["id"=>$id]),2); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function update(Request $request,$id) + { + $params = $request->post(); + if(!$params["user"])return Json::fail('请输入发送人!'); + if(!$params["title"])return Json::fail('请输入通知标题!'); + if(!$params["content"])return Json::fail('请输入通知内容!'); + UserNoticeModel::edit($params,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function send($id) + { + UserNoticeModel::edit(array("is_send"=>1,"send_time"=>time()),$id); + return Json::successful('发送成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!UserNoticeModel::del($id)) + return Json::fail(UserNoticeModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + /** + * 查询发送信息的用户资源 + * + * @param int $id + * @return \think\Response + */ + public function user($id){ + $notice = UserNoticeModel::get($id)->toArray(); + $model = new UserModel; + $model = $model::alias('A'); + $model = $model->field('A.*'); + if($notice["type"] == 2){ + if($notice["uid"] != ""){ + $uids = explode(",",$notice["uid"]); + array_splice($uids,0,1); + array_splice($uids,count($uids)-1,1); + $model = $model->where("A.uid","in",$uids); + }else{ + $model = $model->where("A.uid",$notice['uid']); + } + $model->order('A.uid desc'); + }else{ + $model = $model->join('__USER_NOTICE_SEE__ B','A.uid = B.uid','RIGHT'); + $model = $model->where("B.nid",$notice['id']); + $model->order('B.add_time desc'); + } + $this->assign(UserModel::page($model,function($item,$key) use ($notice){ + $item["is_see"] = UserNoticeSeeModel::where("uid",$item["uid"])->where("nid",$notice["id"])->count() > 0 ? 1 : 0; + })); + $this->assign(compact('notice')); + return $this->fetch(); + } + + /** + * 添加发送信息的用户 + * + * @param \think\Request $request + * @return \think\Response + */ + public function user_create($id){ + $where = Util::getMore([ + ['nickname',''], + ['data',''], + ],$this->request); + $this->assign('where',$where); + $this->assign(UserModel::systemPage($where)); + $this->assign(['title'=>'添加发送用户','save'=>Url::build('user_save',array('id'=>$id))]); + return $this->fetch(); + } + + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function user_save(Request $request,$id){ + $notice = UserNoticeModel::get($id)->toArray(); + if(!$notice) return Json::fail('通知信息不存在!'); + if($notice["type"] == 1) return Json::fail('系统通知不能管理用户!'); + + //查找当前选中的uid + $params = $request->post(); + if(isset($params["search"])){ + $model = new UserModel; + if($params['search']['nickname'] !== '') $model = $model->where('nickname','LIKE',"%".$params['search']['nickname']."%"); + if($params['search']['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$params['search']['data']); + $model = $model->where('add_time','>',strtotime($startTime)); + $model = $model->where('add_time','<',strtotime($endTime)); + } + $model = $model->order('uid desc'); + $uids = $model->column("uid"); + }else{ + $uids = $params["checked_menus"]; + } + if(count($uids) <= 0)return Json::fail('请选择要添加的用户!'); + + //合并原来和现在的uid + if($notice["uid"] != ""){ + $now_uids = explode(",",$notice["uid"]); + array_splice($now_uids,0,1); + array_splice($now_uids,count($now_uids)-1,1); + $now_uids = array_merge($now_uids,$uids); + }else{ + $now_uids = $uids; + } + + //编辑合并之后的uid + $res_uids = UserModel::where("uid","in",$now_uids)->order('uid desc')->column("uid"); + UserNoticeModel::edit(array("uid"=>",".implode(",",$res_uids).","),$notice["id"]); + return Json::successful('添加成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function user_delete($id,$uid) + { + $notice = UserNoticeModel::get($id)->toArray(); + if(!$notice) return Json::fail('通知信息不存在!'); + if($notice["type"] == 1) return Json::fail('系统通知不能管理用户!'); + if($notice["uid"] != ""){ + $res_uids = explode(",",$notice["uid"]); + array_splice($res_uids,0,1); + array_splice($res_uids,count($res_uids)-1,1); + } + array_splice($res_uids,array_search($uid,$res_uids),1); + $value = count($res_uids) > 0 ? ",".implode(",",$res_uids)."," : ""; + UserNoticeModel::edit(array("uid"=>$value),$notice["id"]); + return Json::successful('删除成功!'); + } + + /** + * 删除指定的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function user_select_delete(Request $request,$id){ + $params = $request->post(); + if(count($params["checked_menus"]) <= 0)return Json::fail('删除数据不能为空!'); + $notice = UserNoticeModel::get($id)->toArray(); + if(!$notice) return Json::fail('通知信息不存在!'); + + $res_uids = explode(",",$notice["uid"]); + array_splice($res_uids,0,1); + array_splice($res_uids,count($res_uids)-1,1); + foreach ($params["checked_menus"] as $key => $value) { + array_splice($res_uids,array_search($value,$res_uids),1); + } + $value = count($res_uids) > 0 ? ",".implode(",",$res_uids)."," : ""; + UserNoticeModel::edit(array("uid"=>$value),$notice["id"]); + return Json::successful('删除成功!'); + } + + /** + * @param $id + * @return mixed + */ + public function notice($id){ + $where = Util::getMore([ + ['title',''], + ],$this->request); + $nickname = UserModel::where('uid','IN',$id)->column('uid,nickname'); + $this->assign('where',$where); + $this->assign('uid',$id); + $this->assign('nickname',implode(',',$nickname)); + $this->assign(UserNoticeModel::getUserList($where)); + return $this->fetch(); + } + + + /** + * 给指定用户发送站内信息 + * @param $id + */ + public function send_user($id = 0,$uid = '') + { + if(!$id || $uid == '') return JsonService::fail('参数错误'); + $uid = ",".$uid.","; + UserNoticeModel::edit(array("is_send"=>1,"send_time"=>time(),'uid'=>$uid),$id); + return Json::successful('发送成功!'); + } +} \ No newline at end of file diff --git a/application/admin/controller/wechat/ArticleCategory.php b/application/admin/controller/wechat/ArticleCategory.php new file mode 100644 index 00000000..0d32b109 --- /dev/null +++ b/application/admin/controller/wechat/ArticleCategory.php @@ -0,0 +1 @@ +request); $this->assign('where',$where); $this->assign(ArticleCategoryModel::systemPage($where)); return $this->fetch(); } /** * 添加分类管理 * */ public function create(){ FormBuilder::text('title','分类昵称'); FormBuilder::textarea('intr','分类简介'); FormBuilder::select('new_id','图文列表',function(){ $list = \app\admin\model\wechat\WechatNews::getNews(); $options = []; foreach ($list as $id=>$roleName){ $options[] = ['label'=>$roleName,'value'=>$id]; } return $options; })->multiple()->filterable(); FormBuilder::upload('image','分类图片'); FormBuilder::number('sort','排序',0); FormBuilder::radio('status','状态',[['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']],1); $rules = FormBuilder::builder()->getContent(); $this->assign(['title'=>'编辑菜单','rules'=>$rules,'save'=>Url::build('save')]); return $this->fetch(); } /** * s上传图片 * */ public function upload(){ $res = Upload::image('file','article'); $thumbPath = Upload::thumb($res->dir); if($res->status == 200) return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); else return Json::fail($res->error); } /** * 保存分类管理 * */ public function save(Request $request){ $data = Util::postMore([ 'title', 'intr', ['new_id',[]], ['image',[]], ['sort',0], 'status',],$request); if(!$data['title']) return Json::fail('请输入分类名称'); if(count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张'); if($data['sort'] < 0) return Json::fail('排序不能是负数'); $data['add_time'] = time(); $data['image'] = $data['image'][0]; $new_id = $data['new_id']; unset($data['new_id']); $res = ArticleCategoryModel::set($data); if(!WechatNewsModel::saveBatchCid($res['id'],implode(',',$new_id))) return Json::fail('文章列表添加失败'); return Json::successful('添加分类成功!'); } /** * 修改分类 * */ public function edit($id){ $this->assign(['title'=>'编辑菜单','read'=>Url::build('read',array('id'=>$id)),'update'=>Url::build('update',array('id'=>$id))]); return $this->fetch(); } public function read($id) { $article = ArticleCategoryModel::get($id)->getData(); if(!$article) return Json::fail('数据不存在!'); FormBuilder::text('title','分类昵称',$article['title']); FormBuilder::textarea('intr','分类简介',$article['intr']); $arr = ArticleCategoryModel::getArticle($id,'id,title,cid');//子文章 $new_id = array(); foreach ($arr as $k=>$v){ $new_id[] = $k; } FormBuilder::select('new_id','文章列表',function(){ $list = \app\admin\model\wechat\WechatNews::getNews(); $options = []; foreach ($list as $id=>$roleName){ $options[] = ['label'=>$roleName,'value'=>$id]; } return $options; },$new_id)->multiple(); FormBuilder::upload('image','分类图片')->defaultFileList($article['image']); FormBuilder::number('sort','排序',$article['sort']); FormBuilder::radio('status','状态',[['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']],$article['status']); return FormBuilder::builder(); } public function update(Request $request, $id) { $data = Util::postMore([ 'title', 'intr', ['new_id',[]], ['image',[]], ['sort',0], 'status',],$request); if(!$data['title']) return Json::fail('请输入分类名称'); if(count($data['image']) != 1) return Json::fail('请选择分类图片,并且只能上传一张'); if($data['sort'] < 0) return Json::fail('排序不能是负数'); $data['image'] = $data['image'][0]; // dump($data); // exit; if(!ArticleCategoryModel::get($id)) return Json::fail('编辑的记录不存在!'); if(!WechatNewsModel::saveBatchCid($id,implode(',',$data['new_id']))) return Json::fail('文章列表添加失败'); unset($data['new_id']); ArticleCategoryModel::edit($data,$id); return Json::successful('修改成功!'); } /** * 删除分类 * */ public function delete($id) { $res = ArticleCategoryModel::delArticleCategory($id); if(!$res) return Json::fail(ArticleCategoryModel::getErrorInfo('删除失败,请稍候再试!')); else return Json::successful('删除成功!'); } } \ No newline at end of file diff --git a/application/admin/controller/wechat/Menus.php b/application/admin/controller/wechat/Menus.php new file mode 100644 index 00000000..9ba7298b --- /dev/null +++ b/application/admin/controller/wechat/Menus.php @@ -0,0 +1,38 @@ +where('key','wechat_menus')->value('result'); + $menus = $menus ? : '[]'; + $this->assign('menus',$menus); + return $this->fetch(); + } + + public function save(Request $request) + { + $buttons = $request->post('button/a',[]); + if(!count($buttons)) return $this->failed('请添加至少一个按钮'); + try{ + WechatService::menuService()->add($buttons); + Db::name('cache')->insert(['key'=>'wechat_menus','result'=>json_encode($buttons),'add_time'=>time()],true); + return $this->successful('修改成功!'); + }catch (\Exception $e){ + return $this->failed($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/application/admin/controller/wechat/Reply.php b/application/admin/controller/wechat/Reply.php new file mode 100644 index 00000000..7c8a1a62 --- /dev/null +++ b/application/admin/controller/wechat/Reply.php @@ -0,0 +1,171 @@ +failed('请输入参数key'); + if(empty(input('title'))) return $this->failed('请输入参数title'); + $replay = WechatReply::where('key',input('key'))->find(); + $replay_arr =count($replay) ? $replay->toArray() : []; + $replay_arr['data'] = json_decode(isset($replay_arr['data']) ? $replay_arr['data'] : '',true); + $this->assign('replay_arr',json_encode($replay_arr)); + $this->assign('key',input('key')); + $this->assign('title',input('title')); + return $this->fetch(); + } + + public function one_reply(){ + $where = Util::postMore([ + ['key'], + ['add',0], + ],$this->request); +// dump($where); +// exit(); + if(!empty($where['key'])) $replay = WechatReply::where('key',$where['key'])->find(); + $replay_arr = $replay->toArray(); + $replay_arr['code'] = 200; + $replay_arr['data'] = json_decode($replay_arr['data'],true); + if(empty($replay_arr)) { + $replay_arr['code'] = 0; + } + if($where['add'] && empty($where['key'])){ + $replay_arr['code'] = 0; + } + exit(json_encode($replay_arr)); + } + + public function save(Request $request) + { + $data = Util::postMore([ + 'type', + 'key', + ['status',0], + ['data',[]], + ],$request); + if(!isset($data['type']) && empty($data['type'])) + return Json::fail('请选择回复类型'); + if(!in_array($data['type'],WechatReply::$reply_type)) + return Json::fail('回复类型有误!'); + if(!isset($data['data']) || !is_array($data['data'])) + return Json::fail('回复消息参数有误!'); + $res = WechatReply::redact($data['data'],$data['key'],$data['type'],$data['status']); + if(!$res) + return Json::fail(WechatReply::getErrorInfo()); + else + return Json::successful('保存成功!',$data); + } + + public function upload_img(Request $request) + { + $name = $request->post('file'); + if(!$name) return Json::fail('请上传图片'); + $res = Upload::image($name,'wechat/image'); + return $res->status === true ? Json::successful('上传成功',$res->filePath) : Json::fail($res->error); + } + + public function upload_file(Request $request) + { + $name = $request->post('file'); + if(!$name) return Json::fail('请上传声音'); + $autoValidate['size'] = 2097152; + $res = Upload::file($name,'wechat/voice',true,$autoValidate); + return $res->status === true ? Json::successful('上传成功',$res->filePath) : Json::fail($res->error); + } + + /** + * 关键字回复 + * */ + public function keyword(){ + $where = Util::getMore([ + ['key',''], + ['type',''], + ],$this->request); + $this->assign('where',$where); + $this->assign(WechatReply::getKeyAll($where)); + return $this->fetch(); + + } + /** + * 添加关键字 + * */ + public function add_keyword(){ + $key = input('key'); + if(empty($key)) $key = ''; + $this->assign('key',$key); + $this->assign('dis',1); + $this->assign('replay_arr',json_encode(array())); + return $this->fetch(); + } + /** + * 修改关键字 + * */ + public function info_keyword(){ + $key = input('key'); + if(empty($key)) return $this->failed('参数错误,请重新修改'); + $replay = WechatReply::where('key',$key)->find(); + $replay_arr = $replay->toArray(); + $replay_arr['data'] = json_decode($replay_arr['data'],true); + $this->assign('replay_arr',json_encode($replay_arr)); + $this->assign('key',$key); + $this->assign('dis',2); + return $this->fetch('add_keyword'); + } + /** + * 保存关键字 + * */ + public function save_keyword(Request $request) + { + $data = Util::postMore([ + 'key', + 'type', + ['status',0], + ['data',[]], + ],$request); +// dump($data); +// exit(); + if(!isset($data['key']) && empty($data['key'])) + return Json::fail('请输入关键字'); + if(isset($data['key']) && !empty($data['key'])){ + if(trim($data['key']) == 'subscribe') return Json::fail('请重新输入关键字'); + if(trim($data['key']) == 'default') return Json::fail('请重新输入关键字'); + } + if(!isset($data['type']) && empty($data['type'])) + return Json::fail('请选择回复类型'); + if(!in_array($data['type'],WechatReply::$reply_type)) + return Json::fail('回复类型有误!'); + if(!isset($data['data']) || !is_array($data['data'])) + return Json::fail('回复消息参数有误!'); + $res = WechatReply::redact($data['data'],$data['key'],$data['type'],$data['status']); + if(!$res) + return Json::fail(WechatReply::getErrorInfo()); + else + return Json::successful('保存成功!',$data); + } + + /** + * 删除关键字 + * */ + public function delete($id){ + if(!WechatReply::del($id)) + return Json::fail(WechatReply::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + +} \ No newline at end of file diff --git a/application/admin/controller/wechat/StoreService.php b/application/admin/controller/wechat/StoreService.php new file mode 100644 index 00000000..39cc9c53 --- /dev/null +++ b/application/admin/controller/wechat/StoreService.php @@ -0,0 +1,166 @@ +assign(ServiceModel::getList(0)); + return $this->fetch(); + } + /** + * 显示创建资源表单页. + * + * @return \think\Response + */ + public function create(){ + $where = Util::getMore([ + ['nickname',''], + ['data',''], + ['tagid_list',''], + ['groupid','-1'], + ['sex',''], + ['export',''], + ['stair',''], + ['second',''], + ['order_stair',''], + ['order_second',''], + ['subscribe',''], + ['now_money',''], + ],$this->request); + $this->assign('where',$where); + $this->assign(UserModel::systemPage($where)); + $this->assign(['title'=>'添加客服','save'=>Url::build('save')]); + return $this->fetch(); + } + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function save(Request $request){ + $params = $request->post(); + if(count($params["checked_menus"]) <= 0)return Json::fail('请选择要添加的用户!'); + if(ServiceModel::where('mer_id',0)->where(array("uid"=>array("in",$params["checked_menus"])))->count())return Json::fail('添加用户中存在已有的客服!'); + foreach ($params["checked_menus"] as $key => $value) { + $now_user = UserModel::get($value); + $data[$key]["mer_id"] = 0; + $data[$key]["uid"] = $now_user["uid"]; + $data[$key]["avatar"] = $now_user["headimgurl"]; + $data[$key]["nickname"] = $now_user["nickname"]; + $data[$key]["add_time"] = time(); + } + ServiceModel::setAll($data); + return Json::successful('添加成功!'); + } + + /** + * 显示编辑资源表单页. + * + * @param int $id + * @return \think\Response + */ + public function edit($id) + { + $service = ServiceModel::get($id); + if(!$service) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::frameImageOne('avatar','客服头像',Url::build('admin/widget.images/index',array('fodder'=>'avatar')),$service['avatar'])->icon('image'); + $f[] = Form::input('nickname','客服名称',$service["nickname"]); + $f[] = Form::input('content','通知内容')->type('textarea'); + $f[] = Form::radio('status','状态',$service['status'])->options([['value'=>1,'label'=>'显示'],['value'=>0,'label'=>'隐藏']]); + $form = Form::make_post_form('修改数据',$f,Url::build('update',compact('id'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + /** + * 保存新建的资源 + * + * @param \think\Request $request + * @return \think\Response + */ + public function update(Request $request,$id) + { + $params = $request->post(); + if(empty($params["nickname"]))return Json::fail("客服名称不能为空!"); +// print_r($params);die; + $data = array("avatar"=>$params["avatar"],"nickname"=>$params["nickname"],'status'=>$params['status']); + ServiceModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除指定资源 + * + * @param int $id + * @return \think\Response + */ + public function delete($id) + { + if(!ServiceModel::del($id)) + return Json::fail(ServiceModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + /** + * 上传图片 + * @return \think\response\Json + */ + public function upload() + { + $res = Upload::image('file','store/service'); + $thumbPath = Upload::thumb($res->dir); + if($res->status == 200) + return Json::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>Upload::pathToUrl($thumbPath)]); + else + return Json::fail($res->error); + } + + /** + * 显示资源列表 + * + * @return \think\Response + */ + public function chat_user($id) + { + $now_service = ServiceModel::get($id); + if(!$now_service) return Json::fail('数据不存在!'); + $list = ServiceModel::getChatUser($now_service,0); + $this->assign(compact('list','now_service')); + return $this->fetch(); + } + + /** + * 显示资源列表 + * + * @return \think\Response + */ + public function chat_list($uid,$to_uid) + { + $this->assign(StoreServiceLog::getChatList($uid,$to_uid,0)); + $this->assign('to_uid',$to_uid); + return $this->fetch(); + } +} diff --git a/application/admin/controller/wechat/WechatMessage.php b/application/admin/controller/wechat/WechatMessage.php new file mode 100644 index 00000000..c3a19727 --- /dev/null +++ b/application/admin/controller/wechat/WechatMessage.php @@ -0,0 +1 @@ +request); $this->assign('where',$where); $this->assign('mold',MessageModel::$mold); $this->assign(MessageModel::systemPage($where)); return $this->fetch(); } } \ No newline at end of file diff --git a/application/admin/controller/wechat/WechatNews.php b/application/admin/controller/wechat/WechatNews.php new file mode 100644 index 00000000..41f810c9 --- /dev/null +++ b/application/admin/controller/wechat/WechatNews.php @@ -0,0 +1,186 @@ +request); + if($cid) + $where['cid'] = $cid; + else + $where['cid'] = ''; + $this->assign('where',$where); + $where['merchant'] = 0;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1 + $this->assign('cid',$cid); + $this->assign(WechatNewsModel::getAll($where)); + return $this->fetch(); + } + + /** + * 展示页面 添加和删除 + * @return mixed + */ + public function create(){ + $id = input('id'); + $cid = input('cid'); + $news = array(); + $news['id'] = ''; + $news['image_input'] = ''; + $news['title'] = ''; + $news['author'] = ''; + $news['content'] = ''; + $news['synopsis'] = ''; + $news['url'] = ''; + $news['cid'] = array(); + if($id){ + $news = \app\admin\model\wechat\WechatNews::where('n.id',$id)->alias('n')->field('n.*,c.content')->join('__WECHAT_NEWS_CONTENT__ c','c.nid=n.id')->find(); + if(!$news) return $this->failedNotice('数据不存在!'); + $news['cid'] = explode(',',$news['cid']); +// dump($news); + } + $all = array(); + $select = 0; + if(!$cid) + $cid = ''; + else { + if($id){ + $all = ArticleCategoryModel::where('id',$cid)->where('hidden','neq',0)->column('id,title'); + $select = 1; + }else{ + $all = ArticleCategoryModel::where('id',$cid)->column('id,title'); + $select = 1; + } + + } + if(empty($all)){ + $all = ArticleCategoryModel::getField('id,title');//新闻分类 + $select = 0; + } + $this->assign('all',$all); + $this->assign('news',$news); + $this->assign('cid',$cid); + $this->assign('select',$select); + return $this->fetch(); + } + + /** + * 上传图文图片 + * @return \think\response\Json + */ + public function upload_image(){ + $res = Upload::Image($_POST['file'],'wechat/image/'.date('Ymd')); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachment::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,'',5); + if(!$res->status) return Json::fail($res->error); + return Json::successful('上传成功!',['url'=>$res->filePath]); + } + + /** + * 添加和修改图文 + * @param Request $request + * @return \think\response\Json + */ + public function add_new(Request $request){ + $post = $request->post(); + $data = Util::postMore([ + ['id',0], + ['cid',[]], + 'title', + 'author', + 'image_input', + 'content', + 'synopsis', + 'share_title', + 'share_synopsis', + ['visit',0], + ['sort',0], + 'url', + ['status',1],],$request); + $data['cid'] = implode(',',$data['cid']); + $content = $data['content']; + unset($data['content']); + if($data['id']){ + $id = $data['id']; + unset($data['id']); + WechatNewsModel::beginTrans(); + $res1 = WechatNewsModel::edit($data,$id,'id'); + $res2 = WechatNewsModel::setContent($id,$content); + if($res1 && $res2) + $res = true; + else + $res =false; +// dump($res); +// exit(); + WechatNewsModel::checkTrans($res); + if($res) + return Json::successful('修改图文成功!',$id); + else + return Json::fail('修改图文失败!',$id); + }else{ + $data['add_time'] = time(); + $data['admin_id'] = $this->adminId; + WechatNewsModel::beginTrans(); + $res1 = WechatNewsModel::set($data); + $res2 = false; + if($res1) + $res2 = WechatNewsModel::setContent($res1->id,$content); + if($res1 && $res2) + $res = true; + else + $res =false; + WechatNewsModel::checkTrans($res); + if($res) + return Json::successful('添加图文成功!',$res1->id); + else + return Json::successful('添加图文失败!',$res1->id); + } + } + + /** + * 删除图文 + * @param $id + * @return \think\response\Json + */ + public function delete($id) + { + $res = WechatNewsModel::del($id); + if(!$res) + return Json::fail('删除失败,请稍候再试!'); + else + return Json::successful('删除成功!'); + } + + public function merchantIndex(){ + $where = Util::getMore([ + ['title',''] + ],$this->request); + $this->assign('where',$where); + $where['cid'] = input('cid'); + $where['merchant'] = 1;//区分是管理员添加的图文显示 0 还是 商户添加的图文显示 1 + $this->assign(WechatNewsModel::getAll($where)); + return $this->fetch(); + } +} \ No newline at end of file diff --git a/application/admin/controller/wechat/WechatNewsCategory.php b/application/admin/controller/wechat/WechatNewsCategory.php new file mode 100644 index 00000000..b2ab8bec --- /dev/null +++ b/application/admin/controller/wechat/WechatNewsCategory.php @@ -0,0 +1,284 @@ +request); + $this->assign('where',$where); + $this->assign('callback',$callback); + $this->assign(WechatNewsCategoryModel::getAll($where)); + return $this->fetch(); + } + public function index() + { + $where = Util::getMore([ + ['cate_name',''] + ],$this->request); + $this->assign('where',$where); + $this->assign(WechatNewsCategoryModel::getAll($where)); + return $this->fetch(); + } + public function create(){ + $f = array(); + $f[] = Form::input('cate_name','分类名称')->autofocus(1); + $f[] = Form::select('new_id','图文列表')->setOptions(function(){ + $list = ArticleModel::getNews(); + $options = []; + foreach ($list as $id=>$roleName){ + $options[] = ['label'=>$roleName,'value'=>$id]; + } + return $options; + })->filterable(1)->multiple(1); + $form = Form::make_post_form('编辑菜单',$f,Url::build('save')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + public function save(Request $request){ + $data = Util::postMore([ + 'cate_name', + ['new_id',[]], + ['sort',0], + ['add_time',time()], + ['status',1],],$request); + if(!$data['cate_name']) return Json::fail('请输入图文名称'); + if(empty($data['new_id'])) return Json::fail('请选择图文列表'); + $data['new_id'] = array_unique($data['new_id']); + if(count($data['new_id']) > 8){ + $data['new_id'] = array_slice($data['new_id'], 0, 8); + }; + $data['new_id'] = implode(',',$data['new_id']); + WechatNewsCategoryModel::set($data); + return Json::successful('添加菜单成功!'); + } + public function edit($id){ + $menu = WechatNewsCategoryModel::get($id); + if(!$menu) return Json::fail('数据不存在!'); + $arr_new_id = array_unique(explode(',',$menu->new_id)); + foreach ($arr_new_id as $k=>$v){ + $arr_new_id[$k] = intval($v); + } + $f = array(); + $f[] = Form::input('cate_name','分类名称',$menu['cate_name'])->autofocus(1); + $f[] = Form::select('new_id','图文列表',$arr_new_id)->setOptions(function(){ + $list = ArticleModel::getNews(); + $options = []; + foreach ($list as $id=>$roleName){ + $options[] = ['label'=>$roleName,'value'=>$id]; + } + return $options; + })->filterable(1)->multiple(1); + $form = Form::make_post_form('编辑图文',$f,Url::build('update',compact('id'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'cate_name', + ['new_id',[]], + ['sort',0], + ['status',1],],$request); + if(!$data['cate_name']) return Json::fail('请输入图文名称'); + if(empty($data['new_id'])) return Json::fail('请选择图文列表'); + if(count($data['new_id']) > 8){ + $data['new_id'] = array_slice($data['new_id'], 0, 8); + }; + $data['new_id'] = implode(',',$data['new_id']);; + if(!WechatNewsCategoryModel::get($id)) return Json::fail('编辑的记录不存在!'); + WechatNewsCategoryModel::edit($data,$id); + return Json::successful('修改成功!'); + } + public function delete($id){ + if(!WechatNewsCategoryModel::del($id)) + return Json::fail(WechatNewsCategoryModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + + + /** + * 发送消息 + * @param int $id + * @param string $wechat + * $wechat 不为空 发消息 / 空 群发消息 + */ + public function push($id = 0,$wechat = ''){ + if(!$id) return Json::fail('参数错误'); + $list = WechatNewsCategoryModel::getWechatNewsItem($id); + $wechatNews = []; + if($list){ + if($list['new'] && is_array($list['new'])){ + foreach ($list['new'] as $kk=>$vv){ + $wechatNews[$kk]['title'] = $vv['title']; + $wechatNews[$kk]['image'] = $vv['image_input']; + $wechatNews[$kk]['date'] = date('m月d日',time()); + $wechatNews[$kk]['description'] = $vv['synopsis']; + $wechatNews[$kk]['id'] = $vv['id']; + } + } + } + if($wechat != ''){//客服消息 + $wechatNews = WechatReply::tidyNews($wechatNews); + $message = WechatService::newsMessage($wechatNews); + $errorLog = [];//发送失败的用户 + $user = WechatUser::where('uid','IN',$wechat)->column('nickname,subscribe,openid','uid'); + if($user){ + foreach ($user as $v){ + if($v['subscribe'] && $v['openid']){ + try { + WechatService::staffService()->message($message)->to($v['openid'])->send(); + } catch (\Exception $e) { + $errorLog[] = $v['nickname'].'发送失败'; + } + }else{ + $errorLog[] = $v['nickname'].'没有关注发送失败(不是微信公众号用户)'; + } + } + }else return Json::fail('发送失败,参数不正确'); + if(!count($errorLog)) return Json::successful('全部发送成功'); + else return Json::successful(implode(',',$errorLog).',剩余的发送成功'); + }else{//群发消息 +// if($list){ +// if($list['new'] && is_array($list['new'])){ +// foreach ($list['new'] as $kk=>$vv){ +// $wechatNews[$kk]['title'] = $vv['title']; +// $wechatNews[$kk]['thumb_media_id'] = $vv['image_input']; +// $wechatNews[$kk]['author'] = $vv['author']; +// $wechatNews[$kk]['digest'] = $vv['synopsis']; +// $wechatNews[$kk]['show_cover_pic'] = 1; +// $wechatNews[$kk]['content'] = Db::name('articleContent')->where('nid',$vv["id"])->value('content'); +// $wechatNews[$kk]['content_source_url'] = $vv['url']; +// } +// } +// } + //6sFx6PzPF2v_Lv4FGOMzz-oQunU2Z3wrOWb-7zS508E + //6sFx6PzPF2v_Lv4FGOMzz7SUUuamgWwlqdVfhQ5ALT4 +// foreach ($wechatNews as $k=>$v){ +// $material = WechatService::materialService()->uploadImage(UtilService::urlToPath($v['thumb_media_id'])); +// dump($material); +// $wechatNews[$k]['thumb_media_id'] = $material->media_id; +// } +// $mediaIdNews = WechatService::uploadNews($wechatNews); +// $res = WechatService::sendNewsMessage($mediaIdNews->media_id); +// if($res->errcode) return Json::fail($res->errmsg); +// else return Json::successful('推送成功'); +// dump($mediaIdNews); +// dump($res); + } + } + + public function send_news($id = ''){ + if($id == '') return $this->failed('参数错误'); + $where = Util::getMore([ + ['cate_name',''] + ],$this->request); + $this->assign('where',$where); + $this->assign('wechat',$id); + $this->assign(WechatNewsCategoryModel::getAll($where)); + return $this->fetch(); + } + + public function append(){ + $this->assign('list',[ + [ + 'id'=>0, + 'title'=>'', + 'author'=>$this->adminInfo->real_name, + 'content'=>'', + 'image_input'=>'/public/system/module/wechat/news/images/image.png', + 'synopsis'=>'', + ] + ]); + $this->assign('id',0); + $this->assign('author',$this->adminInfo->real_name); + return $this->fetch(); + } + + public function append_save(Request $request){ + $data = UtilService::postMore([ + ['list',[]], + ['id',0] + ],$request); + $id = []; + $countList = count($data['list']); + if(!$countList) return JsonService::fail('请添加图文'); + Article::beginTrans(); + foreach ($data['list'] as $k=>$v){ + if($v['title'] == '') return JsonService::fail('标题不能为空'); + if($v['author'] == '') return JsonService::fail('作者不能为空'); + if($v['content'] == '') return JsonService::fail('正文不能为空'); + if($v['synopsis'] == '') return JsonService::fail('摘要不能为空'); + if($v['id']){ + $idC = $v['id']; + unset($v['id']); + Article::edit($v,$idC); + Db::name('ArticleContent')->where('nid',$idC)->update(['content'=>$v['content']]); + $data['list'][$k]['id'] = $idC; + $id[] = $idC; + }else{ + unset($v['id']); + $res = Article::set($v)->toArray(); + $id[] = $res['id']; + $data['list'][$k]['id'] = $res['id']; + Db::name('ArticleContent')->insert(['content'=>$v['content'],'nid'=>$res['id']]); + } + } + $countId = count($id); + if($countId != $countList){ + Article::checkTrans(false); + if($data['id']) return JsonService::fail('修改失败'); + else return JsonService::fail('添加失败'); + }else{ + Article::checkTrans(true); + $newsCategory['cate_name'] = $data['list'][0]['title']; + $newsCategory['new_id'] = implode(',',$id); + $newsCategory['sort'] = 0; + $newsCategory['add_time'] = time(); + $newsCategory['status'] = 1; + if($data['id']) { + WechatNewsCategoryModel::edit($newsCategory,$data['id']); + return JsonService::successful('修改成功'); + }else{ + WechatNewsCategoryModel::set($newsCategory); + return JsonService::successful('添加成功'); + } + } + } + + public function modify($id){ + $menu = WechatNewsCategoryModel::get($id); + $list = Article::getArticleList($menu['new_id']); + $this->assign('list',$list); + $this->assign('id',$id); + $this->assign('author',$this->adminInfo->real_name); + return $this->fetch('append'); + } + +} \ No newline at end of file diff --git a/application/admin/controller/wechat/WechatTemplate.php b/application/admin/controller/wechat/WechatTemplate.php new file mode 100644 index 00000000..1308ec77 --- /dev/null +++ b/application/admin/controller/wechat/WechatTemplate.php @@ -0,0 +1,130 @@ +request); + $this->assign('where',$where); + $this->assign(WechatTemplateModel::SystemPage($where)); + $industry = Cache::tag($this->cacheTag)->remember('_wechat_industry',function(){ + $cache = WechatTemplateService::getIndustry(); + if(!$cache) return []; + Cache::tag($this->cacheTag,['_wechat_industry']); + return $cache->toArray(); + },0)?:[]; + !is_array($industry) && $industry = []; + $this->assign('industry',$industry); + return $this->fetch(); + } + + /** + * 添加模板消息 + * @return mixed + */ + public function create() + { + $f = array(); + $f[] = Form::input('tempkey','模板编号'); + $f[] = Form::input('tempid','模板ID'); + $f[] = Form::input('name','模板名'); + $f[] = Form::input('content','回复内容')->type('textarea'); + $f[] = Form::radio('status','状态',1)->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + $form = Form::make_post_form('添加模板消息',$f,Url::build('save')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + public function save(Request $request) + { + $data = Util::postMore([ + 'tempkey', + 'tempid', + 'name', + 'content', + ['status',0] + ],$request); + if($data['tempkey'] == '') return Json::fail('请输入模板编号'); + if($data['tempkey'] != '' && WechatTemplateModel::be($data['tempkey'],'tempkey')) + return Json::fail('请输入模板编号已存在,请重新输入'); + if($data['tempid'] == '') return Json::fail('请输入模板ID'); + if($data['name'] == '') return Json::fail('请输入模板名'); + if($data['content'] == '') return Json::fail('请输入回复内容'); + $data['add_time'] = time(); + WechatTemplateModel::set($data); + return Json::successful('添加模板消息成功!'); + } + + /** + * 编辑模板消息 + * @param $id + * @return mixed|\think\response\Json|void + */ + public function edit($id) + { + if(!$id) return $this->failed('数据不存在'); + $product = WechatTemplateModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + $f = array(); + $f[] = Form::input('tempkey','模板编号',$product->getData('tempkey'))->disabled(1); + $f[] = Form::input('name','模板名',$product->getData('name'))->disabled(1); + $f[] = Form::input('tempid','模板ID',$product->getData('tempid')); + $f[] = Form::radio('status','状态',$product->getData('status'))->options([['label'=>'开启','value'=>1],['label'=>'关闭','value'=>0]]); + $form = Form::make_post_form('编辑模板消息',$f,Url::build('update',compact('id'))); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + public function update(Request $request, $id) + { + $data = Util::postMore([ + 'tempid', + ['status',0] + ],$request); + if($data['tempid'] == '') return Json::fail('请输入模板ID'); + if(!$id) return $this->failed('数据不存在'); + $product = WechatTemplateModel::get($id); + if(!$product) return Json::fail('数据不存在!'); + WechatTemplateModel::edit($data,$id); + return Json::successful('修改成功!'); + } + + /** + * 删除模板消息 + * @param $id + * @return \think\response\Json + */ + public function delete($id) + { + if(!$id) return Json::fail('数据不存在!'); + if(!WechatTemplateModel::del($id)) + return Json::fail(WechatTemplateModel::getErrorInfo('删除失败,请稍候再试!')); + else + return Json::successful('删除成功!'); + } + + +} \ No newline at end of file diff --git a/application/admin/controller/wechat/WechatUser.php b/application/admin/controller/wechat/WechatUser.php new file mode 100644 index 00000000..59b3bd2a --- /dev/null +++ b/application/admin/controller/wechat/WechatUser.php @@ -0,0 +1 @@ +request); $tagidList = explode(',',$where['tagid_list']); foreach ($tagidList as $k=>$v){ if(!$v){ unset($tagidList[$k]); } } $tagidList = array_unique($tagidList); $where['tagid_list'] = implode(',',$tagidList); $this->assign([ 'where'=>$where, 'groupList'=>UserModel::getUserGroup(), 'tagList'=>UserModel::getUserTag() ]); $limitTimeList = [ 'today'=>implode(' - ',[date('Y/m/d'),date('Y/m/d',strtotime('+1 day'))]), 'week'=>implode(' - ',[ date('Y/m/d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)), date('Y-m-d', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600)) ]), 'month'=>implode(' - ',[date('Y/m').'/01',date('Y/m').'/'.date('t')]), 'quarter'=>implode(' - ',[ date('Y').'/'.(ceil((date('n'))/3)*3-3+1).'/01', date('Y').'/'.(ceil((date('n'))/3)*3).'/'.date('t',mktime(0,0,0,(ceil((date('n'))/3)*3),1,date('Y'))) ]), 'year'=>implode(' - ',[ date('Y').'/01/01',date('Y/m/d',strtotime(date('Y').'/01/01 + 1year -1 day')) ]) ]; $uidAll = UserModel::getAll($where); $this->assign(compact('limitTimeList','uidAll')); $this->assign(UserModel::systemPage($where,true)); return $this->fetch(); } public function edit_user_tag($openid) { if(!$openid) return JsonService::fail('参数错误!'); $list = Collection::make(UserModel::getUserTag())->each(function($item){ return ['value'=>$item['id'],'label'=>$item['name']]; }); $tagList = UserModel::where('openid',$openid)->value('tagid_list'); $tagList = explode(',',$tagList)?:[]; $f = [Form::select('tag_id','用户标签',$tagList)->setOptions($list->toArray())->multiple(1)]; $form = Form::make_post_form('标签名称',$f,Url::build('update_user_tag',compact('openid'))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } public function update_user_tag(Request $request,$openid) { if(!$openid) return JsonService::fail('参数错误!'); $tagId = $request->post('tag_id/a',[]); if(!$tagId) return JsonService::fail('请选择用户标签!'); $tagList = explode(',',UserModel::where('openid',$openid)->value('tagid_list'))?:[]; UserModel::beginTrans(); if(!$tagId[0])unset($tagId[0]); UserModel::edit(['tagid_list'=>$tagId],$openid,'openid'); try{ foreach ($tagList as $tag){ if($tag) WechatService::userTagService()->batchUntagUsers([$openid],$tag); } foreach ($tagId as $tag){ WechatService::userTagService()->batchTagUsers([$openid],$tag); } }catch (\Exception $e){ UserModel::rollbackTrans(); return JsonService::fail($e->getMessage()); } UserModel::commitTrans(); return JsonService::successful('修改成功!'); } public function edit_user_group($openid) { if(!$openid) return JsonService::fail('参数错误!'); $list = Collection::make(UserModel::getUserGroup())->each(function($item){ return ['value'=>$item['id'],'label'=>$item['name']]; }); $groupId = UserModel::where('openid',$openid)->value('groupid'); $f = [Form::select('tag_id','用户标签',(string)$groupId)->setOptions($list->toArray())]; $form = Form::make_post_form('标签名称',$f,Url::build('update_user_group',compact('openid'))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } public function update_user_group(Request $request,$openid) { if(!$openid) return JsonService::fail('参数错误!'); $groupId = $request->post('group_id'); if(!$groupId) return JsonService::fail('请选择用户分组!'); UserModel::beginTrans(); UserModel::edit(['groupid'=>$groupId],$openid,'openid'); try{ WechatService::userGroupService()->moveUser($openid,$groupId); }catch (\Exception $e){ UserModel::rollbackTrans(); return JsonService::fail($e->getMessage()); } UserModel::commitTrans(); return JsonService::successful('修改成功!'); } /** * 用户标签列表 */ public function tag($refresh = 0) { if($refresh == 1) { UserModel::clearUserTag(); $this->redirect(Url::build('tag')); } $list = UserModel::getUserTag(); $this->assign(compact('list')); return $this->fetch(); } /** * 添加标签 * @return mixed */ public function create_tag() { $f = [Form::input('name','标签名称')]; $form = Form::make_post_form('标签名称',$f,Url::build('save_tag')); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * 添加 * @param Request $request * @return \think\response\Json */ public function save_tag(Request $request) { $tagName = $request->post('name'); if(!$tagName) return JsonService::fail('请输入标签名称!'); try{ WechatService::userTagService()->create($tagName); }catch (\Exception $e){ return JsonService::fail($e->getMessage()); } UserModel::clearUserTag(); return JsonService::successful('添加标签成功!'); } /** * 修改标签 * @param $id * @return mixed */ public function edit_tag($id) { $f = [Form::input('name','标签名称')]; $form = Form::make_post_form('标签名称',$f,Url::build('update_tag',['id'=>$id])); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * 修改标签 * @param Request $request * @param $id * @return \think\response\Json */ public function update_tag(Request $request, $id) { $tagName = $request->post('name'); if(!$tagName) return JsonService::fail('请输入标签名称!'); try{ WechatService::userTagService()->update($id,$tagName); }catch (\Exception $e){ return JsonService::fail($e->getMessage()); } UserModel::clearUserTag(); return JsonService::successful('修改标签成功!'); } /** * 删除标签 * @param $id * @return \think\response\Json */ public function delete_tag($id) { try{ WechatService::userTagService()->delete($id); }catch (\Exception $e){ return JsonService::fail($e->getMessage()); } UserModel::clearUserTag(); return JsonService::successful('删除标签成功!'); } /** * 用户分组列表 */ public function group($refresh = 0) { if($refresh == 1) { UserModel::clearUserGroup(); $this->redirect(Url::build('group')); } $list = UserModel::getUserGroup(); $this->assign(compact('list')); return $this->fetch(); } /** * 添加分组 * @return mixed */ public function create_group() { $f = [Form::input('name','分组名称')]; $form = Form::make_post_form('标签名称',$f,Url::build('save_group')); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * 添加 * @param Request $request * @return \think\response\Json */ public function save_group(Request $request) { $tagName = $request->post('name'); if(!$tagName) return JsonService::fail('请输入分组名称!'); try{ WechatService::userGroupService()->create($tagName); }catch (\Exception $e){ return JsonService::fail($e->getMessage()); } UserModel::clearUserGroup(); return JsonService::successful('添加分组成功!'); } /** * 修改分组 * @param $id * @return mixed */ public function edit_group($id) { $f = [Form::input('name','分组名称')]; $form = Form::make_post_form('标签名称',$f,Url::build('update_group',compact('id'))); $this->assign(compact('form')); return $this->fetch('public/form-builder'); } /** * 修改分组 * @param Request $request * @param $id * @return \think\response\Json */ public function update_group(Request $request, $id) { $tagName = $request->post('name'); if(!$tagName) return JsonService::fail('请输入分组名称!'); try{ WechatService::userGroupService()->update($id,$tagName); }catch (\Exception $e){ return JsonService::fail($e->getMessage()); } UserModel::clearUserGroup(); return JsonService::successful('修改分组成功!'); } /** * 删除分组 * @param $id * @return \think\response\Json */ public function delete_group($id) { try{ WechatService::userTagService()->delete($id); }catch (\Exception $e){ return JsonService::fail($e->getMessage()); } UserModel::clearUserGroup(); return JsonService::successful('删除分组成功!'); } public function synchro_tag($openid){ if(!$openid) return JsonService::fail('参数错误!'); $data = array(); if(UserModel::be($openid,'openid')){ try{ $tag = WechatService::userTagService()->userTags($openid)->toArray(); }catch (\Exception $e) { return JsonService::fail($e->getMessage()); } if($tag['tagid_list']) $data['tagid_list'] = implode(',',$tag['tagid_list']); else $data['tagid_list'] = ''; $res = UserModel::edit($data,$openid,'openid'); if($res) return JsonService::successful('同步成功'); else return JsonService::fail('同步失败!'); }else return JsonService::fail('参数错误!'); } /** * 一级推荐人页面 * @return mixed */ public function stair($uid = ''){ if($uid == '') return $this->failed('参数错误'); $list = User::alias('u') ->where('u.spread_uid',$uid) ->field('u.avatar,u.nickname,u.now_money,u.add_time,u.uid') ->where('u.status',1) ->order('u.add_time DESC') ->select() ->toArray(); $this->assign('list',$list); return $this->fetch(); } /** * 个人资金详情页面 * @return mixed */ public function now_money($uid = ''){ if($uid == '') return $this->failed('参数错误'); $list = UserBill::where('uid',$uid)->where('category','now_money') ->field('mark,pm,number,add_time') ->where('status',1)->order('add_time DESC')->select()->toArray(); foreach ($list as &$v){ $v['add_time'] = date('Y-m-d H:i:s',$v['add_time']); } $this->assign('list',$list); return $this->fetch(); } } \ No newline at end of file diff --git a/application/admin/controller/wechat/index.php b/application/admin/controller/wechat/index.php new file mode 100644 index 00000000..48c19b5a --- /dev/null +++ b/application/admin/controller/wechat/index.php @@ -0,0 +1,7 @@ +['tid'=>0,'name'=>'编辑器','path'=>'editor'] + ,1=>['tid'=>1,'name'=>'产品图片','path'=>'store/product'] + ,2=>['tid'=>2,'name'=>'拼团图片','path'=>'store/combination'] + ,3=>['tid'=>3,'name'=>'砍价图片','path'=>'store/bargain'] + ,4=>['tid'=>4,'name'=>'秒杀图片','path'=>'store/seckill'] + ,5=>['tid'=>5,'name'=>'文章图片','path'=>'wechat/image'] + ,6=>['tid'=>6,'name'=>'组合数据图','path'=>'common'] + ]; + /** + * 附件列表 + * @return \think\response\Json + */ + public function index() + { + $pid = input('pid')!=''?input('pid'):0; + $this->assign('pid',$pid); + //分类标题 + $typearray = Category::getAll(); + $this->assign(compact('typearray')); +// $typearray = self::dir; +// $this->assign(compact('typearray')); + $this->assign(SystemAttachmentModel::getAll($pid)); + return $this->fetch('widget/images'); + } + /** + * 编辑器上传图片 + * @return \think\response\Json + */ + public function upload() + { + $pid = input('pid')!=''?input('pid'):0; + + $res = Upload::image('file',$pid.'/'.date('Ymd')); + //产品图片上传记录 + $fileInfo = $res->fileInfo->getinfo(); + SystemAttachmentModel::attachmentAdd($res->fileInfo->getSaveName(),$fileInfo['size'],$fileInfo['type'],$res->dir,'',$pid); + $info = array( +// "originalName" => $fileInfo['name'], +// "name" => $res->fileInfo->getSaveName(), +// "url" => '.'.$res->dir, +// "size" => $fileInfo['size'], +// "type" => $fileInfo['type'], +// "state" => "SUCCESS" + 'code' =>200, + 'msg' =>'SUCCESS', + 'src' =>$res->dir + ); + echo json_encode($info); + } + + /** + * ajax 提交删除 + */ + public function delete(){ + $request = Request::instance(); + $post = $request->post(); + if(empty($post['imageid'] )) + Json::fail('还没选择要删除的图片呢?'); + foreach ($post['imageid'] as $v){ + self::deleteimganddata($v); + } + Json::successful('删除成功'); + } + + /**删除图片和数据记录 + * @param $att_id + */ + public function deleteimganddata($att_id){ + $attinfo = SystemAttachmentModel::get($att_id)->toArray(); + if($attinfo){ + @unlink(ROOT_PATH.ltrim($attinfo['att_dir'],'.')); + @unlink(ROOT_PATH.ltrim($attinfo['satt_dir'],'.')); + SystemAttachmentModel::where(['att_id'=>$att_id])->delete(); + } + } + /** + * 移动图片分类 + */ + public function moveimg($imgaes){ + + $formbuider = []; + $formbuider[] = Form::hidden('imgaes',$imgaes); + $formbuider[] = Form::select('pid','选择分类')->setOptions(function (){ + $list = Category::getCateList(); + $options = [['value'=>0,'label'=>'所有分类']]; + foreach ($list as $id=>$cateName){ + $options[] = ['label'=>$cateName['html'].$cateName['name'],'value'=>$cateName['id']]; + } + return $options; + })->filterable(1); + $form = Form::make_post_form('编辑分类',$formbuider,Url::build('moveImgCecate')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + + /**移动图片 + * @param Request $request + * @param $id + */ + public function moveImgCecate(Request $request) + { + $data = Util::postMore([ + 'pid', + 'imgaes' + ],$request); + if($data['imgaes'] == '') return Json::fail('请选择图片'); + if(!$data['pid']) return Json::fail('请选择分类'); + $res = SystemAttachmentModel::where('att_id','in',$data['imgaes'])->update(['pid'=>$data['pid']]); + if($res) + Json::successful('移动成功'); + else + Json::fail('移动失败!'); + } + /** + * ajax 添加分类 + */ + public function addcate($id){ + $id = $id || 0; + $formbuider = []; + $formbuider[] = Form::select('pid','上级分类','0')->setOptions(function (){ + $list = Category::getCateList(0); + $options = [['value'=>0,'label'=>'所有分类']]; + foreach ($list as $id=>$cateName){ + $options[] = ['label'=>$cateName['html'].$cateName['name'],'value'=>$cateName['id']]; + } + return $options; + })->filterable(1); + $formbuider[] = Form::input('name','分类名称'); + $form = Form::make_post_form('添加分类',$formbuider,Url::build('saveCate')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + /** + * 添加分类 + */ + public function saveCate(){ + $request = Request::instance(); + $post = $request->post(); + $data['pid'] = $post['pid']; + $data['name'] = $post['name']; + if(empty($post['name'] )) + Json::fail('分类名称不能为空!'); + $res = Category::create($data); + if($res) + Json::successful('添加成功'); + else + Json::fail('添加失败!'); + + } + /** + * 编辑分类 + */ + public function editcate($id){ + $Category = Category::get($id); + if(!$Category) return Json::fail('数据不存在!'); + $formbuider = []; + $formbuider[] = Form::hidden('id',$id); + $formbuider[] = Form::select('pid','上级分类',(string)$Category->getData('pid'))->setOptions(function ()use($id){ + $list = Category::getCateList(); + $options = [['value'=>0,'label'=>'所有分类']]; + foreach ($list as $id=>$cateName){ + $options[] = ['label'=>$cateName['html'].$cateName['name'],'value'=>$cateName['id']]; + } + return $options; + })->filterable(1); + $formbuider[] = Form::input('name','分类名称',$Category->getData('name')); + $form = Form::make_post_form('编辑分类',$formbuider,Url::build('updateCate')); + $this->assign(compact('form')); + return $this->fetch('public/form-builder'); + } + /** + * 更新分类 + * + * @param \think\Request $request + * @return \think\Response + */ + public function updateCate(Request $request,$id) + { + $data = Util::postMore([ + 'pid', + 'name' + ],$request); + if($data['pid'] == '') return Json::fail('请选择父类'); + if(!$data['name']) return Json::fail('请输入分类名称'); + Category::edit($data,$id); + return Json::successful('分类编辑成功!'); + } + /** + * 删除分类 + */ + public function deletecate($id){ + $chdcount = Category::where('pid',$id)->count(); + if($chdcount) return Json::fail('有子栏目不能删除'); + $chdcount = SystemAttachmentModel::where('pid',$id)->count(); + if($chdcount) return Json::fail('栏目内有图片不能删除'); + if(Category::del($id)) + return Json::successful('删除成功!'); + else + return Json::fail('删除失败'); + + + } + + + +} diff --git a/application/admin/controller/widget/Widgets.php b/application/admin/controller/widget/Widgets.php new file mode 100644 index 00000000..f20d7675 --- /dev/null +++ b/application/admin/controller/widget/Widgets.php @@ -0,0 +1,49 @@ +fetch('widget/icon'); + } + /** + * 会员列页面 + * @return \think\response\Json + */ + public function userlist() + { + return $this->fetch('widget/icon'); + } + /** + * 产品列表页 + * @return \think\response\Json + */ + public function productlist() + { + return $this->fetch('widget/icon'); + } + /** + * 图文列表页 + * @return \think\response\Json + */ + public function newtlist() + { + return $this->fetch('widget/icon'); + } + + +} diff --git a/application/admin/model/article/Article.php b/application/admin/model/article/Article.php new file mode 100644 index 00000000..161f0a13 --- /dev/null +++ b/application/admin/model/article/Article.php @@ -0,0 +1 @@ + * @day: 2017/11/02 */ namespace app\admin\model\article; use app\admin\model\system\SystemAdmin; use traits\ModelTrait; use basic\ModelBasic; use think\Db; /** * 图文管理 Model * Class WechatNews * @package app\admin\model\wechat */ class Article extends ModelBasic { use ModelTrait; /** * 获取配置分类 * @param array $where * @return array */ public static function getAll($where = array()){ $model = new self; // if($where['status'] !== '') $model = $model->where('status',$where['status']); // if($where['access'] !== '') $model = $model->where('access',$where['access']); if($where['title'] !== '') $model = $model->where('title','LIKE',"%$where[title]%"); if($where['cid'] !== '') $model = $model->where("CONCAT(',',cid,',') LIKE '%,$where[cid],%'"); if($where['cid'] == ''){ if(!$where['merchant']) $model = $model->where('mer_id',0); if($where['merchant']) $model = $model->where('mer_id','GT',0); } $model = $model->where('status',1)->where('hide',0); return self::page($model,function($item){ if(!$item['mer_id']) $item['admin_name'] = '总后台管理员---》'.SystemAdmin::where('id',$item['admin_id'])->value('real_name'); else $item['admin_name'] = Merchant::where('id',$item['mer_id'])->value('mer_name').'---》'.MerchantAdmin::where('id',$item['admin_id'])->value('real_name'); $item['content'] = Db::name('ArticleContent')->where('nid',$item['id'])->value('content'); $item['catename'] = Db::name('ArticleCategory')->where('id',$item['cid'])->value('title'); },$where); } /** * 删除图文 * @param $id * @return bool */ public static function del($id){ return self::edit(['status'=>0],$id,'id'); } /** * 获取指定字段的值 * @return array */ public static function getNews() { return self::where('status',1)->where('hide',0)->order('id desc')->column('id,title'); } /** * 给表中的字符串类型追加值 * 删除所有有当前分类的id之后重新添加 * @param $cid * @param $id * @return bool */ public static function saveBatchCid($cid,$id){ $res_all = self::where('cid','LIKE',"%$cid%")->select();//获取所有有当前分类的图文 foreach ($res_all as $k=>$v){ $cid_arr = explode(',',$v['cid']); if(in_array($cid,$cid_arr)){ $key = array_search($cid, $cid_arr); array_splice($cid_arr, $key, 1); } if(empty($cid_arr)) { $data['cid'] = 0; self::edit($data,$v['id']); }else{ $data['cid'] = implode(',',$cid_arr); self::edit($data,$v['id']); } } $res = self::where('id','IN',$id)->select(); foreach ($res as $k=>$v){ if(!in_array($cid,explode(',',$v['cid']))){ if(!$v['cid']){ $data['cid'] = $cid; }else{ $data['cid'] = $v['cid'].','.$cid; } self::edit($data,$v['id']); } } return true; } public static function setContent($id,$content){ $count = Db::name('ArticleContent')->where('nid',$id)->count(); $data['nid'] = $id; $data['content'] = $content; // dump($data); if($count){ $res = Db::name('ArticleContent')->where('nid',$id)->setField('content',$content); if($res !== false) $res = true; } else $res = Db::name('ArticleContent')->insert($data); // echo Db::getLastSql(); // exit(); return $res; } public static function merchantPage($where = array()){ $model = new self; if($where['title'] !== '') $model = $model->where('title','LIKE',"%$where[title]%"); if($where['cid'] !== '') $model = $model->where('cid','LIKE',"%$where[cid]%"); $model = $model ->where('status',1) ->where('hide',0) ->where('admin_id',$where['admin_id']) ->where('mer_id',$where['mer_id']); return self::page($model,function($item){ $item['content'] = Db::name('ArticleContent')->where('nid',$item['id'])->value('content'); },$where); } /** * 获取指定文章列表 图文管理使用 * @param string $id * @param string $field * @return false|\PDOStatement|string|\think\Collection */ public static function getArticleList($id = '',$field = 'title,author,image_input,synopsis,id'){ $list = self::where('id','IN',$id)->field($field)->select(); foreach ($list as $k=>$v){ $list[$k]['content'] = Db::name('ArticleContent')->where('nid',$v['id'])->value('content'); } return $list; } } \ No newline at end of file diff --git a/application/admin/model/article/ArticleCategory.php b/application/admin/model/article/ArticleCategory.php new file mode 100644 index 00000000..e0eb47f3 --- /dev/null +++ b/application/admin/model/article/ArticleCategory.php @@ -0,0 +1,85 @@ + + * @day: 2017/11/02 + */ +namespace app\admin\model\article; + +use traits\ModelTrait; +use app\admin\model\article\Article as ArticleModel; +use basic\ModelBasic; +use service\UtilService as Util; + +/** + * 文章分类model + * Class ArticleCategory + * @package app\admin\model\wechat + */ +class ArticleCategory extends ModelBasic +{ + use ModelTrait; + + /** + * 获取系统分页数据 分类 + * @param array $where + * @return array + */ + public static function systemPage($where = array()){ + $model = new self; + if($where['title'] !== '') $model = $model->where('title','LIKE',"%$where[title]%"); + if($where['status'] !== '') $model = $model->where('status',$where['status']); + $model = $model->where('is_del',0); + $model = $model->where('hidden',0); + return self::page($model); + } + + /** + * 删除分类 + * @param $id + * @return bool + */ + public static function delArticleCategory($id) + { + if(count(self::getArticle($id,'*'))>0) + return self::setErrorInfo('请先删除改分类下的文章!'); + return self::edit(['is_del'=>1],$id,'id'); + } + + /** + * 获取分类名称和id field + * @param $field + * @return array + */ + public static function getField($field){ + return self::where('is_del','eq',0)->where('status','eq',1)->where('hidden','eq',0)->column($field); + } + /** + * 分级排序列表 + * @param null $model + * @return array + */ + public static function getTierList($model = null) + { + if($model === null) $model = new self(); + return Util::sortListTier($model->select()->toArray()); + } + + /** + * 获取分类底下的文章 + * id 分类表中的分类id + * return array + * */ + public static function getArticle($id,$field){ + $res = ArticleModel::where('status',1)->where('hide',0)->column($field,'id'); + $new_res = array(); + foreach ($res as $k=>$v){ + $cid_arr = explode(',',$v['cid']); + if(in_array($id,$cid_arr)){ + $new_res[$k] = $res[$k]; + } + } + return $new_res; + } + +} \ No newline at end of file diff --git a/application/admin/model/finance/FinanceModel.php b/application/admin/model/finance/FinanceModel.php new file mode 100644 index 00000000..a22ee662 --- /dev/null +++ b/application/admin/model/finance/FinanceModel.php @@ -0,0 +1,262 @@ +where($where)->count(); + $rows = $model->where($where)->order($order)->limit($limit)->select()->each(function($e){ + return $e['add_time'] = date('Y-m-d H:i:s',$e['add_time']); + })->toArray(); + return compact('total','rows'); + } + public static function getBillList($where){ +// \think\Db::listen(function($sql, $time, $explain){ +// // 记录SQL +// echo $sql. ' ['.$time.'s]'; +// // 查看性能分析结果 +//// dump($explain); +// }); + $data=($data=self::setWhereList($where)->page((int)$where['page'],(int)$where['limit'])->select()) && count($data) ? $data->toArray():[]; + $count=self::setWhereList($where)->count(); + return compact('data','count'); + } + public static function SaveExport($where){ + $data=($data=self::setWhereList($where)->select()) && count($data) ? $data->toArray():[]; + $export = []; + foreach ($data as $value){ + $export[]=[ + $value['uid'], + $value['nickname'], + $value['pm']==0 ? '-'.$value['number']:$value['number'], + $value['title'], + $value['mark'], + $value['add_time'], + ]; + } + PHPExcelService::setExcelHeader(['会员ID','昵称','金额/积分','类型','备注','创建时间']) + ->setExcelTile('资金监控', '资金监控',date('Y-m-d H:i:s',time())) + ->setExcelContent($export) + ->ExcelSave(); + } + public static function setWhereList($where){ + $time['data']=''; + if($where['start_time']!='' && $where['end_time']!=''){ + $time['data']=$where['start_time'].' - '.$where['end_time']; + } + $model=self::getModelTime($time,self::alias('A') + ->join('user B','B.uid=A.uid') + ->where('A.category','not in','integral') + ->order('A.add_time desc'),'A.add_time'); + if(trim($where['type'])!=''){ + $model=$model->where('A.type',$where['type']); + }else{ + $model=$model->where('A.type','not in','gain,system_sub,deduction,sign'); + } + if($where['nickname']!=''){ + $model=$model->where('B.nickname|B.uid','like',"%$where[nickname]%"); + } + return $model->field(['A.*','FROM_UNIXTIME(A.add_time,"%Y-%m-%d %H:%i:%s") as add_time','B.uid','B.nickname']); + } + /** + * 获取营业数据 + */ + public static function getOrderInfo($where) + { + $orderinfo = self::getTimeWhere($where) + ->field('sum(total_price) total_price,sum(cost) cost,sum(pay_postage) pay_postage,sum(pay_price) pay_price,sum(coupon_price) coupon_price,sum(deduction_price) deduction_price,from_unixtime(pay_time,\'%Y-%m-%d\') pay_time')->order('pay_time')->group('from_unixtime(pay_time,\'%Y-%m-%d\')')->select()->toArray(); + $price = 0; + $postage = 0; + $deduction = 0; + $coupon = 0; + $cost = 0; + foreach ($orderinfo as $info) { + $price = bcadd($price, $info['total_price'], 2);//应支付 + $postage = bcadd($postage, $info['pay_postage'], 2);//邮费 + $deduction = bcadd($deduction, $info['deduction_price'], 2);//抵扣 + $coupon = bcadd($coupon, $info['coupon_price'], 2);//优惠券 + $cost = bcadd($cost, $info['cost'], 2);//成本 + } + return compact('orderinfo', 'price', 'postage', 'deduction', 'coupon', 'cost'); + } + + /** + * 处理where条件 + */ + public static function statusByWhere($status, $model = null) + { + if ($model == null) $model = new self; + if ('' === $status) + return $model; + else if ($status == 'weixin')//微信支付 + return $model->where('pay_type', 'weixin'); + else if ($status == 'yue')//余额支付 + return $model->where('pay_type', 'yue'); + else if ($status == 'offline')//线下支付 + return $model->where('pay_type', 'offline'); + else + return $model; + } + + public static function getTimeWhere($where, $model = null) + { + return self::getTime($where)->where('paid', 1)->where('refund_status', 0); + } + /** + * 获取时间区间 + */ + public static function getTime($where,$model=null,$prefix='add_time'){ + if ($model == null) $model = new self; + if ($where['data'] == '') { + switch ($where['date']){ + case 'today':case 'week':case 'month':case 'year': + $model=$model->whereTime($prefix,$where['date']); + break; + case 'quarter': + list($startTime,$endTime)=User::getMonth('n'); + $model = $model->where($prefix, '>', strtotime($startTime)); + $model = $model->where($prefix, '<', strtotime($endTime)); + break; + } + }else{ + list($startTime, $endTime) = explode(' - ', $where['data']); + $model = $model->where($prefix, '>', strtotime($startTime)); + $model = $model->where($prefix, '<', strtotime($endTime)); + } + return $model; + } + /** + * 获取新增消费 + */ + public static function getConsumption($where) + { + $consumption=self::getTime($where,new UserBill,'b.add_time')->alias('a')->join('user b','a.uid = b.uid') + ->field('sum(a.number) number') + ->where('a.type','pay_product')->find()->toArray(); + return $consumption; + } + /** + * 获取拼团商品 + */ + public static function getPink($where) + { + $pink = self::getTimeWhere($where)->where('pink_id', 'neq', 0)->sum('pay_price'); + return $pink; + } + /** + * 获取秒杀商品 + */ + public static function getSeckill($where){ + $seckill=self::getTimeWhere($where)->where('seckill_id', 'neq', 0)->sum('pay_price'); + return $seckill; + } + /** + * 获取普通商品数 + */ + public static function getOrdinary($where) + { + $ordinary = self::getTimeWhere($where)->where('pink_id', 'eq', 0)->where('seckill_id','eq','0')->sum('pay_price'); + return $ordinary; + } + + /** + * 获取用户充值 + */ + public static function getRecharge($where) + { + $Recharge = self::getTime($where,new UserBill)->where('type', 'system_add')->where('category','now_money')->sum('number'); + return $Recharge; + } + /** + * 获取推广金 + */ + public static function getExtension($where) + { + $extension = self::getTime($where,new UserBill)->where('type', 'brokerage')->where('category','now_money')->sum('number'); + return $extension; + } + + /** + * 最近交易 + */ + public static function trans() + { + $trans = self::alias('a') + ->join('user b', 'a.uid=b.uid') + ->join('store_order_cart_info c', 'a.id=c.oid') + ->join('store_product d', 'c.product_id=d.id') + ->field('b.nickname,a.pay_price,d.store_name') + ->order('a.add_time DESC') + ->limit('6') + ->select()->toArray(); + return $trans; + } + + /** + * 导出表格 + */ + public static function systemTable($where){ + $orderinfos=self::getOrderInfo($where); + if($where['export'] == 1){ + $export = []; + $orderinfo=$orderinfos['orderinfo']; + foreach($orderinfo as $info){ + $time=$info['pay_time']; + $price = $info['total_price']+$info['pay_postage']; + $zhichu = $info['coupon_price']+$info['deduction_price']+$info['cost']; + $profit = ($info['total_price']+$info['pay_postage'])-($info['coupon_price']+$info['deduction_price']+$info['cost']); + $deduction=$info['deduction_price'];//积分抵扣 + $coupon=$info['coupon_price'];//优惠 + $cost=$info['cost'];//成本 + $export[] = [$time,$price,$zhichu,$cost,$coupon,$deduction,$profit]; + } +// ExportService::exportCsv($export,'统计'.time(),['时间','营业额(元)','支出(元)','成本','优惠','积分抵扣','盈利(元)']); + dump($export); + PHPExcelService::setExcelHeader(['时间','营业额(元)','支出(元)','成本','优惠','积分抵扣','盈利(元)'])->setExcelTile('财务统计', '财务统计',date('Y-m-d H:i:s',time()))->setExcelContent($export)->ExcelSave(); + } + } +} \ No newline at end of file diff --git a/application/admin/model/order/StoreOrder.php b/application/admin/model/order/StoreOrder.php new file mode 100644 index 00000000..d1d53c78 --- /dev/null +++ b/application/admin/model/order/StoreOrder.php @@ -0,0 +1,658 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\order; + + +use app\admin\model\wechat\WechatUser; +use app\admin\model\ump\StorePink; +use app\admin\model\store\StoreProduct; +use service\PHPExcelService; +use traits\ModelTrait; +use basic\ModelBasic; +use service\WechatTemplateService; +use think\Url; +use think\Db; +/** + * 订单管理Model + * Class StoreOrder + * @package app\admin\model\store + */ +class StoreOrder extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function systemPage($where,$userid){ + $model = self::getOrderWhere($where,self::alias('a')->join('user r','r.uid=a.uid','LEFT'),'a.','r')->field('a.*,r.nickname'); + if($where['order']){ + $model = $model->order('a.'.$where['order']); + }else{ + $model = $model->order('a.id desc'); + } + if($where['export'] == 1){ + $list = $model->select()->toArray(); + $export = []; + foreach ($list as $index=>$item){ + + if ($item['pay_type'] == 'weixin'){ + $payType = '微信支付'; + }elseif($item['pay_type'] == 'yue'){ + $payType = '余额支付'; + }elseif($item['pay_type'] == 'offline'){ + $payType = '线下支付'; + }else{ + $payType = '其他支付'; + } + + $_info = db('store_order_cart_info')->where('oid',$item['id'])->column('cart_info'); + $goodsName = []; + foreach ($_info as $k=>$v){ + $v = json_decode($v,true); + $goodsName[] = implode( + [$v['productInfo']['store_name'], + isset($v['productInfo']['attrInfo']) ? '('.$v['productInfo']['attrInfo']['suk'].')' : '', + "[{$v['cart_num']} * {$v['truePrice']}]" + ],' '); + } + $item['cartInfo'] = $_info; + $export[] = [ + $item['order_id'],$payType, + $item['total_num'],$item['total_price'],$item['total_postage'],$item['pay_price'],$item['refund_price'], + $item['mark'],$item['remark'], + [$item['real_name'],$item['user_phone'],$item['user_address']], + $goodsName, + [$item['paid'] == 1? '已支付':'未支付','支付时间: '.($item['pay_time'] > 0 ? date('Y/md H:i',$item['pay_time']) : '暂无')] + + ]; + $list[$index] = $item; + } + PHPExcelService::setExcelHeader(['订单号','支付方式','商品总数','商品总价','邮费','支付金额','退款金额','用户备注','管理员备注','收货人信息','商品信息','支付状态']) + ->setExcelTile('订单导出','订单信息'.time(),' 生成时间:'.date('Y-m-d H:i:s',time())) + ->setExcelContent($export) + ->ExcelSave(); + } + return self::page($model,function ($item){ + $item['nickname'] = WechatUser::where('uid',$item['uid'])->value('nickname'); + $_info = db('store_order_cart_info')->where('oid',$item['id'])->field('cart_info')->select(); + foreach ($_info as $k=>$v){ + $_info[$k]['cart_info'] = json_decode($v['cart_info'],true); + } + $item['_info'] = $_info; + if($item['pink_id'] && $item['combination_id']){ + $pinkStatus = StorePink::where('order_id_key',$item['id'])->value('status'); + if($pinkStatus == 1){ + $item['pink_name'] = '[拼团订单]正在进行中'; + $item['color'] = '#f00'; + }else if($pinkStatus == 2){ + $item['pink_name'] = '[拼团订单]已完成'; + $item['color'] = '#00f'; + }else if($pinkStatus == 3){ + $item['pink_name'] = '[拼团订单]未完成'; + $item['color'] = '#f0f'; + }else{ + $item['pink_name'] = '[拼团订单]历史订单'; + $item['color'] = '#457856'; + } + }else{ + if($item['seckill_id']){ + $item['pink_name'] = '[秒杀订单]'; + $item['color'] = '#32c5e9'; + }else{ + $item['pink_name'] = '[普通订单]'; + $item['color'] = '#895612'; + } + + + } + },$where); + } + + public static function statusByWhere($status,$model = null,$alert='') + { + if($model == null) $model = new self; + if('' === $status) + return $model; + else if($status == 0)//未支付 + return $model->where($alert.'paid',0)->where($alert.'status',0)->where($alert.'refund_status',0); + else if($status == 1)//已支付 未发货 + return $model->where($alert.'paid',1)->where($alert.'status',0)->where($alert.'refund_status',0); + else if($status == 2)//已支付 待收货 + return $model->where($alert.'paid',1)->where($alert.'status',1)->where($alert.'refund_status',0); + else if($status == 3)// 已支付 已收货 待评价 + return $model->where($alert.'paid',1)->where($alert.'status',2)->where($alert.'refund_status',0); + else if($status == 4)// 交易完成 + return $model->where($alert.'paid',1)->where($alert.'status',3)->where($alert.'refund_status',0); + else if($status == -1)//退款中 + return $model->where($alert.'paid',1)->where($alert.'refund_status',1); + else if($status == -2)//已退款 + return $model->where($alert.'paid',1)->where($alert.'refund_status',2); + else if($status == -3)//退款 + return $model->where($alert.'paid',1)->where($alert.'refund_status','in','1,2'); + else + return $model; + } + + public static function timeQuantumWhere($startTime = null,$endTime = null,$model = null) + { + if($model === null) $model = new self; + if($startTime != null && $endTime != null) + $model = $model->where('add_time','>',strtotime($startTime))->where('add_time','<',strtotime($endTime)); + return $model; + } + + public static function changeOrderId($orderId) + { + $ymd = substr($orderId,2,8); + $key = substr($orderId,16); + return 'wx'.$ymd.date('His').$key; + } + + /** + * 线下付款 + * @param $id + * @return $this + */ + public static function updateOffline($id){ + $orderId = self::where('id',$id)->value('order_id'); + $res = self::where('order_id',$orderId)->update(['paid'=>1,'pay_time'=>time()]); + return $res; + } + + /** + * 退款发送模板消息 + * @param $oid + * $oid 订单id key + */ + public static function refundTemplate($data,$oid) + { + $order = self::where('id',$oid)->find(); + WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($order['uid']),WechatTemplateService::ORDER_REFUND_STATUS, [ + 'first'=>'亲,您购买的商品已退款,本次退款'.$data['refund_price'].'金额', + 'keyword1'=>$order['order_id'], + 'keyword2'=>$order['pay_price'], + 'keyword3'=>date('Y-m-d H:i:s',$order['add_time']), + 'remark'=>'点击查看订单详情' + ],Url::build('wap/My/order',['uni'=>$order['order_id']],true,true)); + } + + /** + * 处理where条件 + * @param $where + * @param $model + * @return mixed + */ + public static function getOrderWhere($where,$model,$aler='',$join=''){ +// $model = $model->where('combination_id',0); + if($where['status'] != '') $model = self::statusByWhere($where['status'],$model,$aler); + if($where['is_del'] != '' && $where['is_del'] != -1) $model = $model->where($aler.'is_del',$where['is_del']); + if($where['combination_id'] =='普通订单'){ + $model = $model->where($aler.'combination_id',0)->where($aler.'seckill_id',0); + } + if($where['combination_id'] =='拼团订单'){ + $model = $model->where($aler.'combination_id',">",0)->where($aler.'pink_id',">",0); + } + if($where['combination_id'] =='秒杀订单'){ + $model = $model->where($aler.'seckill_id',">",0); + } + + if($where['real_name'] != ''){ + $model = $model->where($aler.'order_id|'.$aler.'real_name|'.$aler.'user_phone'.($join ? '|'.$join.'.nickname|'.$join.'.uid':''),'LIKE',"%$where[real_name]%"); + } + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where($aler.'add_time','>',strtotime($startTime)); + $model = $model->where($aler.'add_time','<',strtotime($endTime)); + } + return $model; + } + + /** + * 处理订单金额 + * @param $where + * @return array + */ + public static function getOrderPrice($where){ + $model = new self; + $price = array(); + $price['pay_price'] = 0;//支付金额 + $price['refund_price'] = 0;//退款金额 + $price['pay_price_wx'] = 0;//微信支付金额 + $price['pay_price_yue'] = 0;//余额支付金额 + $price['pay_price_offline'] = 0;//线下支付金额 + $price['pay_price_other'] = 0;//其他支付金额 + $price['use_integral'] = 0;//用户使用积分 + $price['back_integral'] = 0;//退积分总数 + $price['deduction_price'] = 0;//抵扣金额 + $price['total_num'] = 0; //商品总数 + $model = self::getOrderWhere($where,$model); + $list = $model->select()->toArray(); + foreach ($list as $v){ + $price['total_num'] = bcadd($price['total_num'],$v['total_num'],0); + $price['pay_price'] = bcadd($price['pay_price'],$v['pay_price'],2); + $price['refund_price'] = bcadd($price['refund_price'],$v['refund_price'],2); + $price['use_integral'] = bcadd($price['use_integral'],$v['use_integral'],2); + $price['back_integral'] = bcadd($price['back_integral'],$v['back_integral'],2); + $price['deduction_price'] = bcadd($price['deduction_price'],$v['deduction_price'],2); + if ($v['pay_type'] == 'weixin'){ + $price['pay_price_wx'] = bcadd($price['pay_price_wx'],$v['pay_price'],2); + }elseif($v['pay_type'] == 'yue'){ + $price['pay_price_yue'] = bcadd($price['pay_price_yue'],$v['pay_price'],2); + }elseif($v['pay_type'] == 'offline'){ + $price['pay_price_offline'] = bcadd($price['pay_price_offline'],$v['pay_price'],2); + }else{ + $price['pay_price_other'] = bcadd($price['pay_price_other'],$v['pay_price'],2); + } + } + return $price; + } + + public static function systemPagePink($where){ + $model = new self; + $model = self::getOrderWherePink($where,$model); + $model = $model->order('id desc'); + + if($where['export'] == 1){ + $list = $model->select()->toArray(); + $export = []; + foreach ($list as $index=>$item){ + + if ($item['pay_type'] == 'weixin'){ + $payType = '微信支付'; + }elseif($item['pay_type'] == 'yue'){ + $payType = '余额支付'; + }elseif($item['pay_type'] == 'offline'){ + $payType = '线下支付'; + }else{ + $payType = '其他支付'; + } + + $_info = db('store_order_cart_info')->where('oid',$item['id'])->column('cart_info'); + $goodsName = []; + foreach ($_info as $k=>$v){ + $v = json_decode($v,true); + $goodsName[] = implode( + [$v['productInfo']['store_name'], + isset($v['productInfo']['attrInfo']) ? '('.$v['productInfo']['attrInfo']['suk'].')' : '', + "[{$v['cart_num']} * {$v['truePrice']}]" + ],' '); + } + $item['cartInfo'] = $_info; + $export[] = [ + $item['order_id'],$payType, + $item['total_num'],$item['total_price'],$item['total_postage'],$item['pay_price'],$item['refund_price'], + $item['mark'],$item['remark'], + [$item['real_name'],$item['user_phone'],$item['user_address']], + $goodsName, + [$item['paid'] == 1? '已支付':'未支付','支付时间: '.($item['pay_time'] > 0 ? date('Y/md H:i',$item['pay_time']) : '暂无')] + + ]; + $list[$index] = $item; + } + ExportService::exportCsv($export,'订单导出'.time(),['订单号','支付方式','商品总数','商品总价','邮费','支付金额','退款金额','用户备注','管理员备注','收货人信息','商品信息','支付状态']); + } + + return self::page($model,function ($item){ + $item['nickname'] = WechatUser::where('uid',$item['uid'])->value('nickname'); + $_info = db('store_order_cart_info')->where('oid',$item['id'])->field('cart_info')->select(); + foreach ($_info as $k=>$v){ + $_info[$k]['cart_info'] = json_decode($v['cart_info'],true); + } + $item['_info'] = $_info; + },$where); + } + + /** + * 处理where条件 + * @param $where + * @param $model + * @return mixed + */ + public static function getOrderWherePink($where,$model){ + $model = $model->where('combination_id','GT',0); + if($where['status'] != '') $model = $model::statusByWhere($where['status']); +// if($where['is_del'] != '' && $where['is_del'] != -1) $model = $model->where('is_del',$where['is_del']); + if($where['real_name'] != ''){ + $model = $model->where('order_id|real_name|user_phone','LIKE',"%$where[real_name]%"); + } + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('add_time','>',strtotime($startTime)); + $model = $model->where('add_time','<',strtotime($endTime)); + } + return $model; + } + + /** + * 处理订单金额 + * @param $where + * @return array + */ + public static function getOrderPricePink($where){ + $model = new self; + $price = array(); + $price['pay_price'] = 0;//支付金额 + $price['refund_price'] = 0;//退款金额 + $price['pay_price_wx'] = 0;//微信支付金额 + $price['pay_price_yue'] = 0;//余额支付金额 + $price['pay_price_offline'] = 0;//线下支付金额 + $price['pay_price_other'] = 0;//其他支付金额 + $price['use_integral'] = 0;//用户使用积分 + $price['back_integral'] = 0;//退积分总数 + $price['deduction_price'] = 0;//抵扣金额 + $price['total_num'] = 0; //商品总数 + $model = self::getOrderWherePink($where,$model); + $list = $model->select()->toArray(); + foreach ($list as $v){ + $price['total_num'] = bcadd($price['total_num'],$v['total_num'],0); + $price['pay_price'] = bcadd($price['pay_price'],$v['pay_price'],2); + $price['refund_price'] = bcadd($price['refund_price'],$v['refund_price'],2); + $price['use_integral'] = bcadd($price['use_integral'],$v['use_integral'],2); + $price['back_integral'] = bcadd($price['back_integral'],$v['back_integral'],2); + $price['deduction_price'] = bcadd($price['deduction_price'],$v['deduction_price'],2); + if ($v['pay_type'] == 'weixin'){ + $price['pay_price_wx'] = bcadd($price['pay_price_wx'],$v['pay_price'],2); + }elseif($v['pay_type'] == 'yue'){ + $price['pay_price_yue'] = bcadd($price['pay_price_yue'],$v['pay_price'],2); + }elseif($v['pay_type'] == 'offline'){ + $price['pay_price_offline'] = bcadd($price['pay_price_offline'],$v['pay_price'],2); + }else{ + $price['pay_price_other'] = bcadd($price['pay_price_other'],$v['pay_price'],2); + } + } + return $price; + } + + /** + * 获取昨天的订单 首页在使用 + * @param int $preDay + * @param int $day + * @return $this|StoreOrder + */ + public static function isMainYesterdayCount($preDay = 0,$day = 0){ + $model = new self(); + $model = $model->where('add_time','gt',$preDay); + $model = $model->where('add_time','lt',$day); + return $model; + } + + /** + * 获取用户购买次数 + * @param int $uid + * @return int|string + */ + public static function getUserCountPay($uid = 0){ + if(!$uid) return 0; + return self::where('uid',$uid)->where('paid',1)->count(); + } + + /** + * 获取单个用户购买列表 + * @param array $where + * @return array + */ + public static function getOneorderList($where){ + return self::where(['uid'=>$where['uid']]) + ->order('add_time desc') + ->page((int)$where['page'],(int)$where['limit']) + ->field(['order_id','real_name','total_num','total_price','pay_price', + 'FROM_UNIXTIME(pay_time,"%Y-%m-%d") as pay_time','paid','pay_type', + 'pink_id','seckill_id','bargain_id' + ])->select() + ->toArray(); + } + /* + * 设置订单统计图搜索 + * $where array 条件 + * return object + */ + public static function setEchatWhere($where,$status=null,$time=null){ + $model=self::statusByWhere($where['status']); + if($status!==null) $where['type']=$status; + if($time===true) $where['data']=''; + switch ($where['type']){ + case 1: + //普通商品 + $model=$model->where('combination_id',0)->where('seckill_id',0); + break; + case 2: + //拼团商品 + $model=$model->where('combination_id',">",0)->where('pink_id',">",0); + break; + case 3: + //秒杀商品 + $model=$model->where('seckill_id',">",0); + break; + case 4: + //砍价商品 + $model=$model->where('bargain_id','>',0); + break; + } + return self::getModelTime($where,$model); + } + /* + * 获取订单数据统计图 + * $where array + * $limit int + * return array + */ + public static function getEchartsOrder($where,$limit=20){ + $orderlist=self::setEchatWhere($where)->field([ + 'FROM_UNIXTIME(add_time,"%Y-%m-%d") as _add_time', + 'sum(total_num) total_num', + 'count(*) count', + 'sum(total_price) total_price', + 'sum(refund_price) refund_price', + 'group_concat(cart_id SEPARATOR "|") cart_ids' + ])->group('_add_time')->order('_add_time asc')->select(); + count($orderlist) && $orderlist=$orderlist->toArray(); + $legend=['商品数量','订单数量','订单金额','退款金额']; + $seriesdata=[ + [ + 'name'=>$legend[0], + 'type'=>'line', + 'data'=>[], + ], + [ + 'name'=>$legend[1], + 'type'=>'line', + 'data'=>[] + ], + [ + 'name'=>$legend[2], + 'type'=>'line', + 'data'=>[] + ], + [ + 'name'=>$legend[3], + 'type'=>'line', + 'data'=>[] + ] + ]; + $xdata=[]; + $zoom=''; + foreach ($orderlist as $item){ + $xdata[]=$item['_add_time']; + $seriesdata[0]['data'][]=$item['total_num']; + $seriesdata[1]['data'][]=$item['count']; + $seriesdata[2]['data'][]=$item['total_price']; + $seriesdata[3]['data'][]=$item['refund_price']; + } + count($xdata) > $limit && $zoom=$xdata[$limit-5]; + $badge=self::getOrderBadge($where); + $bingpaytype=self::setEchatWhere($where)->group('pay_type')->field(['count(*) as count','pay_type'])->select(); + count($bingpaytype) && $bingpaytype=$bingpaytype->toArray(); + $bing_xdata=['微信支付','余额支付','其他支付']; + $color=['#ffcccc','#99cc00','#fd99cc','#669966']; + $bing_data=[]; + foreach ($bingpaytype as $key=>$item){ + if($item['pay_type']=='weixin'){ + $value['name']=$bing_xdata[0]; + }else if($item['pay_type']=='yue'){ + $value['name']=$bing_xdata[1]; + }else{ + $value['name']=$bing_xdata[2]; + } + $value['value']=$item['count']; + $value['itemStyle']['color']=isset($color[$key]) ? $color[$key]:$color[0]; + $bing_data[]=$value; + } + return compact('zoom','xdata','seriesdata','badge','legend','bing_data','bing_xdata'); + } + + public static function getOrderBadge($where){ + return [ + [ + 'name'=>'拼团订单数量', + 'field'=>'个', + 'count'=>self::setEchatWhere($where,2)->count(), + 'content'=>'拼团总订单数量', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,2,true)->count(), + 'class'=>'fa fa-line-chart', + 'col'=>2 + ], + [ + 'name'=>'砍价订单数量', + 'field'=>'个', + 'count'=>self::setEchatWhere($where,4)->count(), + 'content'=>'砍价总订单数量', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,4,true)->count(), + 'class'=>'fa fa-line-chart', + 'col'=>2 + ], + [ + 'name'=>'秒杀订单数量', + 'field'=>'个', + 'count'=>self::setEchatWhere($where,3)->count(), + 'content'=>'秒杀总订单数量', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,3,true)->count(), + 'class'=>'fa fa-line-chart', + 'col'=>2 + ], + [ + 'name'=>'普通订单数量', + 'field'=>'个', + 'count'=>self::setEchatWhere($where,1)->count(), + 'content'=>'普通总订单数量', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,1,true)->count(), + 'class'=>'fa fa-line-chart', + 'col'=>2, + ], + [ + 'name'=>'使用优惠卷金额', + 'field'=>'元', + 'count'=>self::setEchatWhere($where)->sum('coupon_price'), + 'content'=>'普通总订单数量', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->sum('coupon_price'), + 'class'=>'fa fa-line-chart', + 'col'=>2 + ], + [ + 'name'=>'积分消耗数', + 'field'=>'个', + 'count'=>self::setEchatWhere($where)->sum('use_integral'), + 'content'=>'积分消耗总数', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->sum('use_integral'), + 'class'=>'fa fa-line-chart', + 'col'=>2 + ], + [ + 'name'=>'积分抵扣金额', + 'field'=>'个', + 'count'=>self::setEchatWhere($where)->sum('deduction_price'), + 'content'=>'积分抵扣总金额', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->sum('deduction_price'), + 'class'=>'fa fa-money', + 'col'=>2 + ], + [ + 'name'=>'在线支付金额', + 'field'=>'元', + 'count'=>self::setEchatWhere($where)->where('pay_type','weixin')->sum('pay_price'), + 'content'=>'在线支付总金额', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->where('pay_type','weixin')->sum('pay_price'), + 'class'=>'fa fa-weixin', + 'col'=>2 + ], + [ + 'name'=>'余额支付金额', + 'field'=>'元', + 'count'=>self::setEchatWhere($where)->where('pay_type','yue')->sum('pay_price'), + 'content'=>'余额支付总金额', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->where('pay_type','yue')->sum('pay_price'), + 'class'=>'fa fa-balance-scale', + 'col'=>2 + ], + [ + 'name'=>'赚取积分', + 'field'=>'分', + 'count'=>self::setEchatWhere($where)->sum('gain_integral'), + 'content'=>'赚取总积分', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->sum('gain_integral'), + 'class'=>'fa fa-gg-circle', + 'col'=>2 + ], + [ + 'name'=>'交易额', + 'field'=>'元', + 'count'=>self::setEchatWhere($where)->sum('pay_price'), + 'content'=>'总交易额', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->sum('pay_price'), + 'class'=>'fa fa-jpy', + 'col'=>2 + ], + [ + 'name'=>'订单商品数量', + 'field'=>'元', + 'count'=>self::setEchatWhere($where)->sum('total_num'), + 'content'=>'订单商品总数量', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::setEchatWhere($where,null,true)->sum('total_num'), + 'class'=>'fa fa-cube', + 'col'=>2 + ] + ]; + } + /* + * 退款列表 + * $where array + * return array + */ +// public static function getRefundList($where){ +// $refundlist=self::setEchatWhere($where)->field([ +// 'order_id','total_price','coupon_price','deduction_price', +// 'use_integral','FROM_UNIXTIME(add_time,"%Y-%m-%d") as add_time','FROM_UNIXTIME(pay_time,"%Y-%m-%d") as pay_time','combination_id', +// 'seckill_id','bargain_id','cost','status','cart_id','pay_price','refund_status' +// ])->page((int)$where['page'],(int)$where['limit'])->select(); +// count($refundlist) && $refundlist=$refundlist->toArray(); +// foreach($refundlist as &$item){ +// $item['product']=StoreProduct::where('id','in',function ($quers) use($item){ +// $quers->name('store_cart')->where('id','in',json_decode($item['cart_id'],true))->field('product_id'); +// })->field(['store_name','cost','price','image'])->select()->toArray(); +// if($item['refund_status']==1) { +// $item['_refund'] = '申请退款中'; +// }elseif ($item['refund_status']==2){ +// $item['_refund'] = '退款成功'; +// } +// } +// return $refundlist; +// } +} \ No newline at end of file diff --git a/application/admin/model/order/StoreOrderStatus.php b/application/admin/model/order/StoreOrderStatus.php new file mode 100644 index 00000000..bd3b9e38 --- /dev/null +++ b/application/admin/model/order/StoreOrderStatus.php @@ -0,0 +1,56 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\order; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 订单操作纪律model + * Class StoreOrderStatus + * @package app\admin\model\store + */ +class StoreOrderStatus extends ModelBasic +{ + use ModelTrait; + + /** + * @param $oid + * @param $type + * @param $message + */ + public static function setStatus($oid,$type,$message){ + $data['oid'] = (int)$oid; + $data['change_type'] = $type; + $data['change_message'] = $message; + $data['change_time'] = time(); + self::set($data); + } + + /** + * @param $where + * @return array + */ + public static function systemPage($oid){ + $model = new self; + $model = $model->where('oid',$oid); + $model = $model->order('change_time asc'); + return self::page($model); + } + /** + * @param $where + * @return array + */ + public static function systemPageMer($oid){ + $model = new self; + $model = $model->where('oid',$oid); +// $model = $model->where('change_type','LIKE','mer_%'); + $model = $model->order('change_time asc'); + return self::page($model); + } +} \ No newline at end of file diff --git a/application/admin/model/record/StoreStatistics.php b/application/admin/model/record/StoreStatistics.php new file mode 100644 index 00000000..10c04cda --- /dev/null +++ b/application/admin/model/record/StoreStatistics.php @@ -0,0 +1,206 @@ +field('pay_price,total_price,deduction_price,coupon_price,total_postage,pay_type,pay_time')->select()->toArray(); + if (empty($list)) { + $price['pay_price_wx'] = 0; + $price['pay_price_yue'] = 0; + $price['pay_price_offline'] = 0; + } + foreach ($list as $v) { + if ($v['pay_type'] == 'weixin') { + $price['pay_price_wx'] = bcadd($price['pay_price_wx'], $v['pay_price'], 2); + } elseif ($v['pay_type'] == 'yue') { + $price['pay_price_yue'] = bcadd($price['pay_price_yue'], $v['pay_price'], 2); + } elseif ($v['pay_type'] == 'offline') { + $price['pay_price_offline'] = bcadd($price['pay_price_offline'], $v['pay_price'], 2); + } + } + return $price; + } + + /** + * 获取营业数据 + */ + public static function getOrderInfo($where) + { + $orderinfo = self::getTimeWhere($where) + ->field('sum(total_price) total_price,sum(cost) cost,sum(pay_postage) pay_postage,sum(pay_price) pay_price,sum(coupon_price) coupon_price,sum(deduction_price) deduction_price,from_unixtime(pay_time,\'%Y-%m-%d\') pay_time')->order('pay_time')->group('from_unixtime(pay_time,\'%Y-%m-%d\')')->select()->toArray(); + $price = 0; + $postage = 0; + $deduction = 0; + $coupon = 0; + $cost = 0; + foreach ($orderinfo as $info) { + $price = bcadd($price, $info['total_price'], 2);//应支付 + $postage = bcadd($postage, $info['pay_postage'], 2);//邮费 + $deduction = bcadd($deduction, $info['deduction_price'], 2);//抵扣 + $coupon = bcadd($coupon, $info['coupon_price'], 2);//优惠券 + $cost = bcadd($cost, $info['cost'], 2);//成本 + } + return compact('orderinfo', 'price', 'postage', 'deduction', 'coupon', 'cost'); + } + + /** + * 处理where条件 + */ + public static function statusByWhere($status, $model = null) + { + if ($model == null) $model = new self; + if ('' === $status) + return $model; + else if ($status == 'weixin')//微信支付 + return $model->where('pay_type', 'weixin'); + else if ($status == 'yue')//余额支付 + return $model->where('pay_type', 'yue'); + else if ($status == 'offline')//线下支付 + return $model->where('pay_type', 'offline'); + else + return $model; + } + + public static function getTimeWhere($where, $model = null) + { + return self::getTime($where)->where('paid', 1)->where('refund_status', 0); + } + /** + * 获取时间区间 + */ + public static function getTime($where,$model=null,$prefix='add_time'){ + if ($model == null) $model = new self; + if ($where['data'] == '') { + switch ($where['date']){ + case 'today':case 'week':case 'month':case 'year': + $model=$model->whereTime($prefix,$where['date']); + break; + case 'quarter': + list($startTime,$endTime)=User::getMonth('n'); + $model = $model->where($prefix, '>', strtotime($startTime)); + $model = $model->where($prefix, '<', strtotime($endTime)); + break; + } + }else{ + list($startTime, $endTime) = explode(' - ', $where['data']); + $model = $model->where($prefix, '>', strtotime($startTime)); + $model = $model->where($prefix, '<', strtotime($endTime)); + } + return $model; + } + /** + * 获取新增消费 + */ + public static function getConsumption($where) + { + $consumption=self::getTime($where,new UserBill,'b.add_time')->alias('a')->join('user b','a.uid = b.uid') + ->field('sum(a.number) number') + ->where('a.type','pay_product')->find()->toArray(); + return $consumption; + } + /** + * 获取拼团商品 + */ + public static function getPink($where) + { + $pink = self::getTimeWhere($where)->where('pink_id', 'neq', 0)->sum('pay_price'); + return $pink; + } + /** + * 获取秒杀商品 + */ + public static function getSeckill($where){ + $seckill=self::getTimeWhere($where)->where('seckill_id', 'neq', 0)->sum('pay_price'); + return $seckill; + } + /** + * 获取普通商品数 + */ + public static function getOrdinary($where) + { + $ordinary = self::getTimeWhere($where)->where('pink_id', 'eq', 0)->where('seckill_id','eq','0')->sum('pay_price'); + return $ordinary; + } + + /** + * 获取用户充值 + */ + public static function getRecharge($where) + { + $Recharge = self::getTime($where,new UserBill)->where('type', 'system_add')->where('category','now_money')->sum('number'); + return $Recharge; + } + /** + * 获取推广金 + */ + public static function getExtension($where) + { + $extension = self::getTime($where,new UserBill)->where('type', 'brokerage')->where('category','now_money')->sum('number'); + return $extension; + } + + /** + * 最近交易 + */ + public static function trans() + { + $trans = self::alias('a') + ->join('user b', 'a.uid=b.uid') + ->join('store_order_cart_info c', 'a.id=c.oid') + ->join('store_product d', 'c.product_id=d.id') + ->field('b.nickname,a.pay_price,d.store_name') + ->order('a.add_time DESC') + ->limit('6') + ->select()->toArray(); + return $trans; + } + + /** + * 导出表格 + */ + public static function systemTable($where){ + $orderinfos=self::getOrderInfo($where); + if($where['export'] == 1){ + $export = []; + $orderinfo=$orderinfos['orderinfo']; + foreach($orderinfo as $info){ + $time=$info['pay_time']; + $price = $info['total_price']+$info['pay_postage']; + $zhichu = $info['coupon_price']+$info['deduction_price']+$info['cost']; + $profit = ($info['total_price']+$info['pay_postage'])-($info['coupon_price']+$info['deduction_price']+$info['cost']); + $deduction=$info['deduction_price'];//积分抵扣 + $coupon=$info['coupon_price'];//优惠 + $cost=$info['cost'];//成本 + $export[] = [$time,$price,$zhichu,$cost,$coupon,$deduction,$profit]; + } + PHPExcelService::setExcelHeader(['时间','营业额(元)','支出(元)','成本','优惠','积分抵扣','盈利(元)'])->setExcelTile('财务统计', '财务统计',date('Y-m-d H:i:s',time()))->setExcelContent($export)->ExcelSave(); + } + } +} \ No newline at end of file diff --git a/application/admin/model/record/StoreVisit.php b/application/admin/model/record/StoreVisit.php new file mode 100644 index 00000000..93e5789b --- /dev/null +++ b/application/admin/model/record/StoreVisit.php @@ -0,0 +1,57 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\store; + + +use traits\ModelTrait; +use basic\ModelBasic; +use app\admin\model\user\User; +/** + * + * Class StoreOrder + * @package app\admin\model\store + */ +class StoreVisit extends ModelBasic +{ + use ModelTrait; + /** + * @param $where + * @return array + */ + public static function getVisit($date,$class=[]){ + $model=new self(); + switch ($date){ + case null:case 'today':case 'week':case 'year': + if($date==null) $date='month'; + $model=$model->whereTime('add_time',$date); + break; + case 'quarter': + list($startTime,$endTime)=User::getMonth('n'); + $model = $model->where('add_time','>',$startTime); + $model = $model->where('add_time','<',$endTime); + break; + default: + list($startTime,$endTime)=explode('-',$date); + $model = $model->where('add_time','>',strtotime($startTime)); + $model = $model->where('add_time','<',strtotime($endTime)); + break; + } + $list=$model->group('type')->field('sum(count) as sum,product_id,cate_id,type,content')->order('sum desc')->limit(0,10)->select()->toArray(); + $view=[]; + foreach ($list as $key=>$val){ + $now_list['name']=$val['type']=='viwe'?'浏览量':'搜索'; + $now_list['value']=$val['sum']; + $now_list['class']=isset($class[$key])?$class[$key]:''; + $view[]=$now_list; + } + if(empty($list)){ + $view=[['name'=>'暂无数据', 'value'=>100, 'class'=>'']]; + } + return $view; + } +} \ No newline at end of file diff --git a/application/admin/model/routine/RoutineTemplate.php b/application/admin/model/routine/RoutineTemplate.php new file mode 100644 index 00000000..e8e7174d --- /dev/null +++ b/application/admin/model/routine/RoutineTemplate.php @@ -0,0 +1,32 @@ + + * @day: 2017/11/02 + */ +namespace app\admin\model\routine; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 小程序模板消息Model + * Class RoutineTemplate + * @package app\admin\model\wechat + */ +class RoutineTemplate extends ModelBasic +{ + use ModelTrait; + + /** + * 获取系统分页数据 分类 + * @param array $where + * @return array + */ + public static function systemPage($where = array()){ + $model = new self; + if($where['name'] !== '') $model = $model->where('name','LIKE',"%$where[name]%"); + if($where['status'] !== '') $model = $model->where('status',$where['status']); + return self::page($model); + } +} \ No newline at end of file diff --git a/application/admin/model/store/StoreBargain.php b/application/admin/model/store/StoreBargain.php new file mode 100644 index 00000000..96cd487d --- /dev/null +++ b/application/admin/model/store/StoreBargain.php @@ -0,0 +1,81 @@ +where('status',$where['status']); + if($where['store_name'] != ''){ + $model = $model->where('title','LIKE',"%$where[store_name]%"); + $model = $model->whereOr('store_name','LIKE',"%$where[store_name]%"); + } + if($where['data'] != '') $model = $model->whereTime('add_time', 'between', explode('-',$where['data'])); + $model = $model->order('id desc'); + $model = $model->where('is_del',0); + if($where['export'] == 1){ + $list = $model->select()->toArray(); + $export = []; + foreach ($list as $index=>$item){ + $export[] = [ + $item['title'], + $item['info'], + $item['store_name'], + '¥'.$item['price'], + '¥'.$item['cost'], + $item['num'], + '¥'.$item['bargain_max_price'], + '¥'.$item['bargain_min_price'], + $item['bargain_num'], + $item['status'] ? '开启' : '关闭', + date('Y-m-d H:i:s',$item['start_time']), + date('Y-m-d H:i:s',$item['stop_time']), + $item['sales'], + $item['stock'], + $item['give_integral'], + date('Y-m-d H:i:s',$item['add_time']), + ]; + $list[$index] = $item; + } + + PHPExcelService::setExcelHeader(['砍价活动名称','砍价活动简介','砍价产品名称','砍价金额','成本价','每次购买的砍价产品数量','用户每次砍价的最大金额','用户每次砍价的最小金额', + '用户每次砍价的次数','砍价状态','砍价开启时间','砍价结束时间','销量','库存','返多少积分','添加时间']) + ->setExcelTile('砍价产品导出','产品信息'.time(),' 生成时间:'.date('Y-m-d H:i:s',time())) + ->setExcelContent($export) + ->ExcelSave(); + } + return self::page($model,function($item){ + if($item['status']){ + if($item['start_time'] > time()) + $item['start_name'] = '活动未开始'; + else if($item['stop_time'] < time()) + $item['start_name'] = '活动已结束'; + else if($item['stop_time'] > time() && $item['start_time'] < time()) + $item['start_name'] = '正在进行中'; + } + + },$where); + } +} \ No newline at end of file diff --git a/application/admin/model/store/StoreCategory.php b/application/admin/model/store/StoreCategory.php new file mode 100644 index 00000000..4b16e1cf --- /dev/null +++ b/application/admin/model/store/StoreCategory.php @@ -0,0 +1,70 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\store; + + +use traits\ModelTrait; +use basic\ModelBasic; +use service\UtilService; + +/** + * Class StoreCategory + * @package app\admin\model\store + */ +class StoreCategory extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function systemPage($where){ + $model = new self; + if($where['pid'] != '') $model = $model->where('pid',$where['pid']); + else if($where['pid']=='' && $where['cate_name']=='') $model = $model->where('pid',0); + if($where['is_show'] != '') $model = $model->where('is_show',$where['is_show']); + if($where['cate_name'] != '') $model = $model->where('cate_name','LIKE',"%$where[cate_name]%"); + return self::page($model,function ($item){ + if($item['pid']){ + $item['pid_name'] = self::where('id',$item['pid'])->value('cate_name'); + }else{ + $item['pid_name'] = '顶级'; + } + },$where); + } + + /** + * 获取顶级分类 + * @return array + */ + public static function getCategory($field = 'id,cate_name') + { + return self::where('is_show',1)->column($field); + } + + /** + * 分级排序列表 + * @param null $model + * @return array + */ + public static function getTierList($model = null) + { + if($model === null) $model = new self(); + return UtilService::sortListTier($model->select()->toArray()); + } + + public static function delCategory($id){ + $count = self::where('pid',$id)->count(); + if($count) + return false; + else{ + return self::del($id); + } + } +} \ No newline at end of file diff --git a/application/admin/model/store/StoreCouponUser.php b/application/admin/model/store/StoreCouponUser.php new file mode 100644 index 00000000..4300f71c --- /dev/null +++ b/application/admin/model/store/StoreCouponUser.php @@ -0,0 +1,103 @@ + $time || $coupon['end_time'] < $time){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已过期'; + }else{ + if($coupon['add_time']+ 3600*24 > $time){ + $coupon['_type'] = 2; + $coupon['_msg'] = '可使用'; + }else{ + $coupon['_type'] = 1; + $coupon['_msg'] = '可使用'; + } + } + $coupon['integral']=db('store_coupon')->where(['id'=>$coupon['cid']])->value('integral'); + } + return $couponList; + } + //获取个人优惠券列表 + public static function getOneCouponsList($where){ + $list=self::where(['uid'=>$where['uid']])->page((int)$where['page'],(int)$where['limit'])->select(); + return self::tidyCouponList($list); + } + //获取优惠劵头部信息 + public static function getCouponBadgeList($where){ + return [ + [ + 'name'=>'总发放优惠券', + 'field'=>'张', + 'count'=>self::getModelTime($where,db('store_coupon_issue'))->where('status',1)->sum('total_count'), + 'background_color'=>'layui-bg-blue', + 'col'=>6, + ], + [ + 'name'=>'总使用优惠券', + 'field'=>'张', + 'count'=>self::getModelTime($where,new self())->where('status',1)->count(), + 'background_color'=>'layui-bg-blue', + 'col'=>6, + ] + ]; + } + //获取优惠劵图表 + public static function getConponCurve($where,$limit=20){ + //优惠劵发放记录 + $list=self::getModelTime($where,db('store_coupon_issue') + ->where('status',1) + ->field(['FROM_UNIXTIME(add_time,"%Y-%m-%d") as _add_time','sum(total_count) as total_count'])->group('_add_time')->order('_add_time asc'))->select(); + $date=[]; + $seriesdata=[]; + $zoom=''; + foreach ($list as $item){ + $date[]=$item['_add_time']; + $seriesdata[]=$item['total_count']; + } + unset($item); + if(count($date)>$limit){ + $zoom=$date[$limit-5]; + } + //优惠劵使用记录 + $componList=self::getModelTime($where,self::where('status',1)->field(['FROM_UNIXTIME(add_time,"%Y-%m-%d") as _add_time','sum(coupon_price) as coupon_price']) + ->group('_add_time')->order('_add_time asc'))->select(); + count($componList) && $componList=$componList->toArray(); + $compon_date=[]; + $compon_data=[]; + $compon_zoom=''; + foreach($componList as $item){ + $compon_date[]=$item['_add_time']; + $compon_data[]=$item['coupon_price']; + } + if(count($compon_date)>$limit){ + $compon_zoom=$compon_date[$limit-5]; + } + return compact('date','seriesdata','zoom','compon_date','compon_data','compon_zoom'); + } + +} \ No newline at end of file diff --git a/application/admin/model/store/StoreProduct.php b/application/admin/model/store/StoreProduct.php new file mode 100644 index 00000000..8ac70bac --- /dev/null +++ b/application/admin/model/store/StoreProduct.php @@ -0,0 +1,524 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\store; + +use app\admin\model\wechat\WechatUser; +use app\admin\model\system\Merchant; +use service\PHPExcelService; +use think\Db; +use traits\ModelTrait; +use basic\ModelBasic; +use app\admin\model\store\StoreCategory as CategoryModel; +use app\admin\model\order\StoreOrder; +use app\admin\model\system\SystemConfig; + +/** + * 产品管理 model + * Class StoreProduct + * @package app\admin\model\store + */ +class StoreProduct extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function systemPage($where,$adminInfo){ + $model = new self; + $model = $model->alias('p'); + if($where['store_name'] != '') $model = $model->where('p.store_name|p.keyword|p.id','LIKE',"%$where[store_name]%"); + if($where['cate_id'] != '') $model = $model->where('p.cate_id','LIKE',"%$where[cate_id]%"); + switch ($where['type']){ + case 1: + $data = ['p.is_show'=>1,'is_del'=>0]; + $model = $model->where($data); + break; + case 2: + $data = ['p.is_show'=>0,'is_del'=>0]; + $model = $model->where($data); + break; + case 3: + $data = ['p.is_del'=>0]; + $model = $model->where($data); + break; + case 4: + $data = ['p.is_show'=>1,'p.is_del'=>0,'pav.stock|p.stock'=>0]; + $model = $model->where($data); + break; + case 5: + $data = ['p.is_show'=>1,'p.is_del'=>0,'pav.stock|p.stock'=>['elt',1]]; + $model = $model->where($data); + break; + case 6: + $data = ['p.is_del'=>1]; + $model = $model->where($data); + break; + }; + $model = $model->field('p.*,sum("pav.stock") as vstock'); + $model = $model->join('StoreProductAttrValue pav','p.id=pav.product_id','LEFT'); + $model = $model->group('p.id'); + $order = ''; + if($where['sales'] != '') $order .= $where['sales']; + $order .= 'p.id desc'; + $model = $model->order($order); + if($where['export'] == 1){ + $list = $model->select()->toArray(); + $export = []; + foreach ($list as $index=>$item){ + $cateName = CategoryModel::where('id','IN',$item['cate_id'])->column('cate_name','id'); if(is_array($cateName)){ $cateNameStr = implode(',',$cateName); } + $export[] = [ + $item['store_name'], + $item['store_info'], + $cateName, + '¥'.$item['price'], + $item['stock'], + $item['sales'], + StoreProductRelation::where('product_id',$item['id'])->where('type','like')->count(), + StoreProductRelation::where('product_id',$item['id'])->where('type','collect')->count() + ]; + $list[$index] = $item; + } + PHPExcelService::setExcelHeader(['产品名称','产品简介','产品分类','价格','库存','销量','点赞人数','收藏人数']) + ->setExcelTile('产品导出','产品信息'.time(),'操作人昵称:'.$adminInfo['real_name'].' 生成时间:'.date('Y-m-d H:i:s',time())) + ->setExcelContent($export) + ->ExcelSave(); + } + return self::page($model,function($item){ + $cateName = CategoryModel::where('id','IN',$item['cate_id'])->column('cate_name','id'); + if(is_array($cateName)){ + $item['cate_name'] = implode(',',$cateName); } + $item['collect'] = StoreProductRelation::where('product_id',$item['id'])->where('type','collect')->count();//收藏 + $item['like'] = StoreProductRelation::where('product_id',$item['id'])->where('type','like')->count();//点赞 + $item['stock'] = self::getStock($item['id'])>0?self::getStock($item['id']):$item['stock'];//库存 + $item['stock_attr'] = self::getStock($item['id'])>0 ? true : false;//库存 + $item['sales_attr'] = self::getSales($item['id']);//属性销量 + $item['visitor'] = Db::name('store_visit')->where('product_id',$item['id'])->where('product_type','product')->count(); + + },$where); + } + public static function getChatrdata($type,$data){ + $legdata=['销量','数量','点赞','收藏']; + $model=self::setWhereType(self::order('id desc'),$type); + $list=self::getModelTime(compact('data'),$model) + ->field('FROM_UNIXTIME(add_time,"%Y-%c-%d") as un_time,count(id) as count,sum(sales) as sales') + ->group('un_time') + ->distinct(true) + ->select() + ->each(function($item) use($data){ + $item['collect']=self::getModelTime(compact('data'),new StoreProductRelation)->where(['type'=>'collect'])->count(); + $item['like']=self::getModelTime(compact('data'),new StoreProductRelation)->where(['type'=>'like'])->count(); + })->toArray(); + $chatrList=[]; + $datetime=[]; + $data_item=[]; + $itemList=[0=>[],1=>[],2=>[],3=>[]]; + foreach ($list as $item){ + $itemList[0][]=$item['sales']; + $itemList[1][]=$item['count']; + $itemList[2][]=$item['like']; + $itemList[3][]=$item['collect']; + array_push($datetime,$item['un_time']); + } + foreach ($legdata as $key=>$leg){ + $data_item['name']=$leg; + $data_item['type']='line'; + $data_item['data']=$itemList[$key]; + $chatrList[]=$data_item; + unset($data_item); + } + unset($leg); + $badge=self::getbadge(compact('data'),$type); + $count=self::setWhereType(self::getModelTime(compact('data'),new self()),$type)->count(); + return compact('datetime','chatrList','legdata','badge','count'); + + } + //获取 badge 内容 + public static function getbadge($where,$type){ + $StoreOrderModel=new StoreOrder; + $replenishment_num = SystemConfig::getValue('replenishment_num'); + $replenishment_num = $replenishment_num > 0 ? $replenishment_num : 20; + $stock1=self::getModelTime($where,new self())->where('stock','<',$replenishment_num)->column('stock'); + $sum_stock=self::where('stock','<',$replenishment_num)->column('stock'); + $stk=[]; + foreach ($stock1 as $item){ + $stk[]=$replenishment_num-$item; + } + $lack=array_sum($stk); + $sum=[]; + foreach ($sum_stock as $val){ + $sum[]=$replenishment_num-$val; + } + return [ + [ + 'name'=>'商品数量', + 'field'=>'件', + 'count'=>self::setWhereType(new self(),$type)->where('add_time','<',mktime(0,0,0,date('m'),date('d'),date('Y')))->sum('stock'), + 'content'=>'商品数量总数', + 'background_color'=>'layui-bg-blue', + 'sum'=>self::sum('stock'), + 'class'=>'fa fa fa-ioxhost', + ], + [ + 'name'=>'新增商品', + 'field'=>'件', + 'count'=>self::setWhereType(self::getModelTime($where,new self),$type)->where('is_new',1)->sum('stock'), + 'content'=>'新增商品总数', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::where('is_new',1)->sum('stock'), + 'class'=>'fa fa-line-chart', + ], + [ + 'name'=>'活动商品', + 'field'=>'件', + 'count'=>self::getModelTime($where,$StoreOrderModel)->sum('total_num'), + 'content'=>'活动商品总数', + 'background_color'=>'layui-bg-green', + 'sum'=>$StoreOrderModel->sum('total_num'), + 'class'=>'fa fa-bar-chart', + ], + [ + 'name'=>'缺货商品', + 'field'=>'件', + 'count'=>$lack, + 'content'=>'总商品数量', + 'background_color'=>'layui-bg-orange', + 'sum'=>array_sum($sum), + 'class'=>'fa fa-cube', + ], + ]; + } + public static function setWhereType($model,$type){ + switch ($type){ + case 1: + $data = ['is_show'=>1,'is_del'=>0]; + break; + case 2: + $data = ['is_show'=>0,'is_del'=>0]; + break; + case 3: + $data = ['is_del'=>0]; + break; + case 4: + $data = ['is_show'=>1,'is_del'=>0,'stock'=>0]; + break; + case 5: + $data = ['is_show'=>1,'is_del'=>0,'stock'=>['elt',1]]; + break; + case 6: + $data = ['is_del'=>1]; + break; + } + if(isset($data)) $model = $model->where($data); + return $model; + } + /* + * layui-bg-red 红 layui-bg-orange 黄 layui-bg-green 绿 layui-bg-blue 蓝 layui-bg-cyan 黑 + * 销量排行 top 10 + */ + public static function getMaxList($where){ + $classs=['layui-bg-red','layui-bg-orange','layui-bg-green','layui-bg-blue','layui-bg-cyan']; + $model=StoreOrder::alias('a')->join('StoreOrderCartInfo c','a.id=c.oid')->join('store_product b','b.id=c.product_id'); + $list=self::getModelTime($where,$model,'a.add_time')->group('c.product_id')->order('p_count desc')->limit(10) + ->field(['count(c.product_id) as p_count','b.store_name','sum(b.price) as sum_price'])->select(); + if(count($list)) $list=$list->toArray(); + $maxList=[]; + $sum_count=0; + $sum_price=0; + foreach ($list as $item){ + $sum_count+=$item['p_count']; + $sum_price=bcadd($sum_price,$item['sum_price'],2); + } + unset($item); + foreach ($list as $key=>&$item){ + $item['w']=bcdiv($item['p_count'],$sum_count,2)*100; + $item['class']=isset($classs[$key]) ?$classs[$key]:( isset($classs[$key-count($classs)]) ? $classs[$key-count($classs)]:''); + $item['store_name']=self::getSubstrUTf8($item['store_name']); + } + $maxList['sum_count']=$sum_count; + $maxList['sum_price']=$sum_price; + $maxList['list']=$list; + return $maxList; + } + //获取利润 + public static function ProfityTop10($where){ + $classs=['layui-bg-red','layui-bg-orange','layui-bg-green','layui-bg-blue','layui-bg-cyan']; + $model=StoreOrder::alias('a')->join('StoreOrderCartInfo c','a.id=c.oid')->join('store_product b','b.id=c.product_id'); + $list=self::getModelTime($where,$model,'a.add_time')->group('c.product_id')->order('profity desc')->limit(10) + ->field(['count(c.product_id) as p_count','b.store_name','sum(b.price) as sum_price','(b.price-b.cost) as profity']) + ->select(); + if(count($list)) $list=$list->toArray(); + $maxList=[]; + $sum_count=0; + $sum_price=0; + foreach ($list as $item){ + $sum_count+=$item['p_count']; + $sum_price=bcadd($sum_price,$item['sum_price'],2); + } + foreach ($list as $key=>&$item){ + $item['w']=bcdiv($item['sum_price'],$sum_price,2)*100; + $item['class']=isset($classs[$key]) ?$classs[$key]:( isset($classs[$key-count($classs)]) ? $classs[$key-count($classs)]:''); + $item['store_name']=self::getSubstrUTf8($item['store_name'],30); + } + $maxList['sum_count']=$sum_count; + $maxList['sum_price']=$sum_price; + $maxList['list']=$list; + return $maxList; + } + //获取缺货 + public static function getLackList($where){ + $replenishment_num = SystemConfig::getValue('replenishment_num'); + $replenishment_num = $replenishment_num > 0 ? $replenishment_num : 20; + $list=self::where('stock','<',$replenishment_num)->field(['id','store_name','stock','price'])->page((int)$where['page'],(int)$where['limit'])->order('stock asc')->select(); + if(count($list)) $list=$list->toArray(); + $count=self::where('stock','<',$replenishment_num)->count(); + return ['count'=>$count,'data'=>$list]; + } + //获取差评 + public static function getnegativelist($where){ + $list=self::alias('s')->join('StoreProductReply r','s.id=r.product_id') + ->field('s.id,s.store_name,s.price,count(r.product_id) as count') + ->page((int)$where['page'],(int)$where['limit']) + ->where('r.product_score',1) + ->order('count desc') + ->group('r.product_id') + ->select(); + if(count($list)) $list=$list->toArray(); + $count=self::alias('s')->join('StoreProductReply r','s.id=r.product_id')->group('r.product_id')->where('r.product_score',1)->count(); + return ['count'=>$count,'data'=>$list]; + } + public static function TuiProductList(){ + $perd=StoreOrder::alias('s')->join('StoreOrderCartInfo c','s.id=c.oid') + ->field('count(c.product_id) as count,c.product_id as id') + ->group('c.product_id') + ->where('s.status',-1) + ->order('count desc') + ->limit(10) + ->select(); + if(count($perd)) $perd=$perd->toArray(); + foreach ($perd as &$item){ + $item['store_name']=self::where(['id'=>$item['id']])->value('store_name'); + $item['price']=self::where(['id'=>$item['id']])->value('price'); + } + return $perd; + } + //编辑库存 + public static function changeStock($stock,$productId) + { + return self::edit(compact('stock'),$productId); + } + //获取库存数量 + public static function getStock($productId) + { + return StoreProductAttrValue::where(['product_id'=>$productId])->sum('stock'); + } + //获取总销量 + public static function getSales($productId) + { + return StoreProductAttrValue::where(['product_id'=>$productId])->sum('sales'); + } + + public static function getTierList($model = null) + { + if($model === null) $model = new self(); + return $model->field('id,store_name')->where('is_del',0)->select()->toArray(); + } + /** + * 设置查询条件 + * @param array $where + * @return array + */ + public static function setWhere($where){ + $time['data']=''; + if(isset($where['start_time']) && $where['start_time']!='' && isset($where['end_time']) && $where['end_time']!=''){ + $time['data']=$where['start_time'].' - '.$where['end_time']; + }else{ + $time['data']=isset($where['data'])? $where['data']:''; + } + $model=self::getModelTime($time,db('store_cart')->alias('a')->join('store_product b','a.product_id=b.id'),'a.add_time'); + if(isset($where['title']) && $where['title']!=''){ + $model=$model->where('b.store_name|b.id','like',"%$where[title]%"); + } + return $model; + } + /** + * 获取真实销量排行 + * @param array $where + * @return array + */ + public static function getSaleslists($where){ + $data=self::setWhere($where)->where('a.is_pay',1) + ->group('a.product_id') + ->field(['sum(a.cart_num) as num_product','b.store_name','b.image','b.price','b.id']) + ->order('num_product desc') + ->page((int)$where['page'],(int)$where['limit']) + ->select(); + $count=self::setWhere($where)->where('a.is_pay',1)->group('a.product_id')->count(); + foreach ($data as &$item){ + $item['sum_price']=bcdiv($item['num_product'],$item['price'],true); + } + return compact('data','count'); + } + public static function SaveProductExport($where){ + $list=self::setWhere($where) + ->where('a.is_pay',1) + ->field(['sum(a.cart_num) as num_product','b.store_name','b.image','b.price','b.id']) + ->order('num_product desc') + ->group('a.product_id') + ->select(); + $export=[]; + foreach ($list as $item){ + $export[]=[ + $item['id'], + $item['store_name'], + $item['price'], + bcmul($item['num_product'],$item['price'],2), + $item['num_product'], + ]; + } + PHPExcelService::setExcelHeader(['商品编号','商品名称','商品售价','销售额','销量']) + ->setExcelTile('产品销量排行','产品销量排行',' 生成时间:'.date('Y-m-d H:i:s',time())) + ->setExcelContent($export) + ->ExcelSave(); + } + /* + * 单个商品详情的头部查询 + * $id 商品id + * $where 条件 + */ + public static function getProductBadgeList($id,$where){ + $data['data']=$where; + $list=self::setWhere($data) + ->field(['sum(a.cart_num) as num_product','b.id','b.price']) + ->where('a.is_pay',1) + ->group('a.product_id') + ->order('num_product desc') + ->select(); + //排名 + $ranking=0; + //销量 + $xiaoliang=0; + //销售额 数组 + $list_price=[]; + foreach ($list as $key=>$item){ + if($item['id']==$id){ + $ranking=$key+1; + $xiaoliang=$item['num_product']; + } + $value['sum_price']=$item['price']*$item['num_product']; + $value['id']=$item['id']; + $list_price[]=$value; + } + //排序 + $list_price=self::my_sort($list_price,'sum_price',SORT_DESC); + //销售额排名 + $rank_price=0; + //当前销售额 + $num_price=0; + if($list_price!==false && is_array($list_price)){ + foreach ($list_price as $key=>$item){ + if($item['id']==$id){ + $num_price=$item['sum_price']; + $rank_price=$key+1; + continue; + } + } + } + return [ + [ + 'name'=>'销售额排名', + 'field'=>'名', + 'count'=>$rank_price, + 'background_color'=>'layui-bg-blue', + ], + [ + 'name'=>'销量排名', + 'field'=>'名', + 'count'=>$ranking, + 'background_color'=>'layui-bg-blue', + ], + [ + 'name'=>'商品销量', + 'field'=>'名', + 'count'=>$xiaoliang, + 'background_color'=>'layui-bg-blue', + ], + [ + 'name'=>'点赞次数', + 'field'=>'个', + 'count'=>db('store_product_relation')->where('product_id',$id)->where('type','like')->count(), + 'background_color'=>'layui-bg-blue', + ], + [ + 'name'=>'销售总额', + 'field'=>'元', + 'count'=>$num_price, + 'background_color'=>'layui-bg-blue', + 'col'=>12, + ], + ]; + } + /* + * 处理二维数组排序 + * $arrays 需要处理的数组 + * $sort_key 需要处理的key名 + * $sort_order 排序方式 + * $sort_type 类型 可不填写 + */ + public static function my_sort($arrays,$sort_key,$sort_order=SORT_ASC,$sort_type=SORT_NUMERIC ){ + if(is_array($arrays)){ + foreach ($arrays as $array){ + if(is_array($array)){ + $key_arrays[] = $array[$sort_key]; + }else{ + return false; + } + } + } + if(isset($key_arrays)){ + array_multisort($key_arrays,$sort_order,$sort_type,$arrays); + return $arrays; + } + return false; + } + /* + * 查询单个商品的销量曲线图 + * + */ + public static function getProductCurve($where){ + $list=self::setWhere($where) + ->where('a.product_id',$where['id']) + ->where('a.is_pay',1) + ->field(['FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as _add_time','sum(a.cart_num) as num']) + ->group('_add_time') + ->order('_add_time asc') + ->select(); + $seriesdata=[]; + $date=[]; + $zoom=''; + foreach ($list as $item){ + $date[]=$item['_add_time']; + $seriesdata[]=$item['num']; + } + if(count($date)>$where['limit']) $zoom=$date[$where['limit']-5]; + return compact('seriesdata','date','zoom'); + } + /* + * 查询单个商品的销售列表 + * + */ + public static function getSalelList($where){ + return self::setWhere($where) + ->where(['a.product_id'=>$where['id'],'a.is_pay'=>1]) + ->join('user c','c.uid=a.uid') + ->field(['FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as _add_time','c.nickname','b.price','a.id','a.cart_num as num']) + ->page((int)$where['page'],(int)$where['limit']) + ->select(); + } +} \ No newline at end of file diff --git a/application/admin/model/store/StoreProductAttr.php b/application/admin/model/store/StoreProductAttr.php new file mode 100644 index 00000000..d685496b --- /dev/null +++ b/application/admin/model/store/StoreProductAttr.php @@ -0,0 +1,117 @@ + + * @day: 2017/12/08 + */ + +namespace app\admin\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreProductAttr extends ModelBasic +{ + use ModelTrait; + + protected function setAttrValuesAttr($value) + { + return is_array($value) ? implode(',',$value) : $value; + } + + protected function getAttrValuesAttr($value) + { + return explode(',',$value); + } + + + public static function createProductAttr($attrList,$valueList,$productId) + { + $result = ['attr'=>$attrList,'value'=>$valueList]; + $attrValueList = []; + $attrNameList = []; + foreach ($attrList as $index=>$attr){ + if(!isset($attr['value'])) return self::setErrorInfo('请输入规则名称!'); + $attr['value'] = trim($attr['value']); + if(!isset($attr['value'])) return self::setErrorInfo('请输入规则名称!!'); + if(!isset($attr['detail']) || !count($attr['detail'])) return self::setErrorInfo('请输入属性名称!'); + foreach ($attr['detail'] as $k=>$attrValue){ + $attrValue = trim($attrValue); + if(empty($attrValue)) return self::setErrorInfo('请输入正确的属性'); + $attr['detail'][$k] = $attrValue; + $attrValueList[] = $attrValue; + $attr['detail'][$k] = $attrValue; + } + $attrNameList[] = $attr['value']; + $attrList[$index] = $attr; + } + $attrCount = count($attrList); + foreach ($valueList as $index=>$value){ + if(!isset($value['detail']) || count($value['detail']) != $attrCount) return self::setErrorInfo('请填写正确的商品信息'); + if(!isset($value['price']) || !is_numeric($value['price']) || floatval($value['price']) != $value['price']) + return self::setErrorInfo('请填写正确的商品价格'); + if(!isset($value['sales']) || !is_numeric($value['sales']) || intval($value['sales']) != $value['sales']) + return self::setErrorInfo('请填写正确的商品库存'); + if(!isset($value['cost']) || !is_numeric($value['cost']) || floatval($value['cost']) != $value['cost']) + return self::setErrorInfo('请填写正确的商品成本价格'); + if(!isset($value['pic']) || empty($value['pic'])) + return self::setErrorInfo('请上传商品图片'); + foreach ($value['detail'] as $attrName=>$attrValue){ + $attrName = trim($attrName); + $attrValue = trim($attrValue); + if(!in_array($attrName,$attrNameList,true)) return self::setErrorInfo($attrName.'规则不存在'); + if(!in_array($attrValue,$attrValueList,true)) return self::setErrorInfo($attrName.'属性不存在'); + if(empty($attrName)) return self::setErrorInfo('请输入正确的属性'); + $value['detail'][$attrName] = $attrValue; + } + $valueList[$index] = $value; + } + $attrGroup = []; + $valueGroup = []; + foreach ($attrList as $k=>$value){ + $attrGroup[] = [ + 'product_id'=>$productId, + 'attr_name'=>$value['value'], + 'attr_values'=>$value['detail'] + ]; + } + foreach ($valueList as $k=>$value){ + ksort($value['detail'],SORT_STRING); + $suk = implode(',',$value['detail']); + $valueGroup[$suk] = [ + 'product_id'=>$productId, + 'suk'=>$suk, + 'price'=>$value['price'], + 'cost'=>$value['cost'], + 'stock'=>$value['sales'], + 'image'=>$value['pic'] + ]; + } + if(!count($attrGroup) || !count($valueGroup)) return self::setErrorInfo('请设置至少一个属性!'); + $attrModel = new self; + $attrValueModel = new StoreProductAttrValue; + self::beginTrans(); + if(!self::clearProductAttr($productId)) return false; + $res = false !== $attrModel->saveAll($attrGroup) + && false !== $attrValueModel->saveAll($valueGroup) + && false !== StoreProductAttrResult::setResult($result,$productId); + self::checkTrans($res); + if($res) + return true; + else + return self::setErrorInfo('编辑商品属性失败!'); + } + + public static function clearProductAttr($productId) + { + if (empty($productId) && $productId != 0) return self::setErrorInfo('商品不存在!'); + $res = false !== self::where('product_id',$productId)->delete() + && false !== StoreProductAttrValue::clearProductAttrValue($productId); + if(!$res) + return self::setErrorInfo('编辑属性失败,清除旧属性失败!'); + else + return true; + } + +} \ No newline at end of file diff --git a/application/admin/model/store/StoreProductAttrResult.php b/application/admin/model/store/StoreProductAttrResult.php new file mode 100644 index 00000000..c75bc28c --- /dev/null +++ b/application/admin/model/store/StoreProductAttrResult.php @@ -0,0 +1,47 @@ + + * @day: 2017/12/09 + */ + +namespace app\admin\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreProductAttrResult extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['change_time']; + + protected static function setChangeTimeAttr($value) + { + return time(); + } + + protected static function setResultAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + public static function setResult($result,$product_id) + { + $result = self::setResultAttr($result); + $change_time = self::setChangeTimeAttr(0); + return self::insert(compact('product_id','result','change_time'),true); + } + + public static function getResult($productId) + { + return json_decode(self::where('product_id',$productId)->value('result'),true) ?: []; + } + + public static function clearResult($productId) + { + return self::del($productId); + } + +} \ No newline at end of file diff --git a/application/admin/model/store/StoreProductAttrValue.php b/application/admin/model/store/StoreProductAttrValue.php new file mode 100644 index 00000000..f50877f1 --- /dev/null +++ b/application/admin/model/store/StoreProductAttrValue.php @@ -0,0 +1,49 @@ + + * @day: 2017/12/08 + */ + +namespace app\admin\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreProductAttrValue extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['unique']; + + protected function setSukAttr($value) + { + return is_array($value) ? implode(',',$value) : $value; + } + + protected function setUniqueAttr($value,$data) + { + if(is_array($data['suk'])) $data['suk'] = $this->setSukAttr($data['suk']); + return self::uniqueId($data['product_id'].$data['suk'].uniqid(true)); + } + + public static function decProductAttrStock($productId,$unique,$num) + { + return false !== self::where('product_id',$productId)->where('unique',$unique) + ->dec('stock',$num)->inc('sales',$num)->update(); + } + + + public static function uniqueId($key) + { + return substr(md5($key),12,8); + } + + public static function clearProductAttrValue($productId) + { + return self::where('product_id',$productId)->delete(); + } + + +} \ No newline at end of file diff --git a/application/admin/model/store/StoreProductRelation.php b/application/admin/model/store/StoreProductRelation.php new file mode 100644 index 00000000..180f2ef5 --- /dev/null +++ b/application/admin/model/store/StoreProductRelation.php @@ -0,0 +1,38 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\store; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 点赞and收藏 model + * Class StoreProductRelation + * @package app\admin\model\store + */ +class StoreProductRelation extends ModelBasic +{ + use ModelTrait; + + + public static function getCollect($pid){ + $model = new self(); + $model = $model->where('r.product_id',$pid)->where('r.type','collect'); + $model = $model->alias('r')->join('__WECHAT_USER__ u','u.uid=r.uid'); + $model = $model->field('r.*,u.nickname'); + return self::page($model); + } + public static function getLike($pid){ + $model = new self(); + $model = $model->where('r.product_id',$pid)->where('r.type','like'); + $model = $model->alias('r')->join('__WECHAT_USER__ u','u.uid=r.uid'); + $model = $model->field('r.*,u.nickname'); + return self::page($model); + } + +} \ No newline at end of file diff --git a/application/admin/model/store/StoreProductReply.php b/application/admin/model/store/StoreProductReply.php new file mode 100644 index 00000000..789ff692 --- /dev/null +++ b/application/admin/model/store/StoreProductReply.php @@ -0,0 +1,46 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\store; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 评论管理 model + * Class StoreProductReply + * @package app\admin\model\store + */ +class StoreProductReply extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function systemPage($where){ + $model = new self; + if($where['comment'] != '') $model = $model->where('r.comment','LIKE',"%$where[comment]%"); + if($where['is_reply'] != ''){ + if($where['is_reply'] >= 0){ + $model = $model->where('r.is_reply',$where['is_reply']); + }else{ + $model = $model->where('r.is_reply','GT',0); + } + } + if($where['product_id']) $model = $model->where('r.product_id',$where['product_id']); + $model = $model->alias('r')->join('__WECHAT_USER__ u','u.uid=r.uid'); + $model = $model->join('__STORE_PRODUCT__ p','p.id=r.product_id'); + $model = $model->where('r.is_del',0); + $model = $model->field('r.*,u.nickname,u.headimgurl,p.store_name'); + return self::page($model,function($itme){ + + },$where); + } + +} \ No newline at end of file diff --git a/application/admin/model/store/StoreService.php b/application/admin/model/store/StoreService.php new file mode 100644 index 00000000..c9094291 --- /dev/null +++ b/application/admin/model/store/StoreService.php @@ -0,0 +1,55 @@ +alias('a'); + $model->join('__USER__ b ','b.uid = a.uid'); + $model->field('a.*,b.nickname as wx_name'); + $model->where("mer_id",$mer_id); + $model->order('a.id desc'); + return self::page($model,function($item,$key){ + }); + } + + /** + * @return array + */ + public static function getChatUser($now_service,$mer_id){ + $where = 'mer_id = '.$mer_id.' AND (uid = '.$now_service["uid"].' OR to_uid='.$now_service["uid"].')'; + $chat_list = ServiceLogModel::field("uid,to_uid")->where($where)->group("uid,to_uid")->select(); + if(count($chat_list) > 0){ + $arr_user = $arr_to_user = []; + foreach ($chat_list as $key => $value) { + array_push($arr_user,$value["uid"]); + array_push($arr_to_user,$value["to_uid"]); + } + $uids = array_merge($arr_user,$arr_to_user); + + $list = WechatUser::field("uid,nickname,headimgurl")->where(array("uid"=>array(array("in",$uids),array("neq",$now_service["uid"]))))->select(); + foreach ($list as $index => $user) { + $service = self::field("uid,nickname,avatar as headimgurl")->where(array("uid"=>$user["uid"]))->find(); + if($service)$list[$index] = $service; + } + }else{ + $list = null; + } + return $list; + } +} \ No newline at end of file diff --git a/application/admin/model/store/StoreServiceLog.php b/application/admin/model/store/StoreServiceLog.php new file mode 100644 index 00000000..21adf87a --- /dev/null +++ b/application/admin/model/store/StoreServiceLog.php @@ -0,0 +1,32 @@ +where($where); + $model->order("add_time desc"); + return self::page($model,function($item,$key) use ($mer_id){ + $user = StoreService::field("nickname,avatar")->where('mer_id',$mer_id)->where(array("uid"=>$item["uid"]))->find(); + if(!$user)$user = User::field("nickname,avatar")->where(array("uid"=>$item["uid"]))->find(); + $item["nickname"] = $user["nickname"]; + $item["avatar"] = $user["avatar"]; + }); + } +} \ No newline at end of file diff --git a/application/admin/model/store/StoreVisit.php b/application/admin/model/store/StoreVisit.php new file mode 100644 index 00000000..921f6fcf --- /dev/null +++ b/application/admin/model/store/StoreVisit.php @@ -0,0 +1,57 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\store; + + +use traits\ModelTrait; +use basic\ModelBasic; +use app\admin\model\user\User; +/** + * 商品浏览分析 + * Class StoreOrder + * @package app\admin\model\store + */ +class StoreVisit extends ModelBasic +{ + use ModelTrait; + /** + * @param $where + * @return array + */ + public static function getVisit($date,$class=[]){ + $model=new self(); + switch ($date){ + case null:case 'today':case 'week':case 'year': + if($date==null) $date='month'; + $model=$model->whereTime('add_time',$date); + break; + case 'quarter': + list($startTime,$endTime)=User::getMonth('n'); + $model = $model->where('add_time','>',$startTime); + $model = $model->where('add_time','<',$endTime); + break; + default: + list($startTime,$endTime)=explode('-',$date); + $model = $model->where('add_time','>',strtotime($startTime)); + $model = $model->where('add_time','<',strtotime($endTime)); + break; + } + $list=$model->group('type')->field('sum(count) as sum,product_id,cate_id,type,content')->order('sum desc')->limit(0,10)->select()->toArray(); + $view=[]; + foreach ($list as $key=>$val){ + $now_list['name']=$val['type']=='viwe'?'浏览量':'搜索'; + $now_list['value']=$val['sum']; + $now_list['class']=isset($class[$key])?$class[$key]:''; + $view[]=$now_list; + } + if(empty($list)){ + $view=[['name'=>'暂无数据', 'value'=>100, 'class'=>'']]; + } + return $view; + } +} \ No newline at end of file diff --git a/application/admin/model/system/SystemAdmin.php b/application/admin/model/system/SystemAdmin.php new file mode 100644 index 00000000..cae4c0e6 --- /dev/null +++ b/application/admin/model/system/SystemAdmin.php @@ -0,0 +1,159 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\system; + + +use traits\ModelTrait; +use basic\ModelBasic; +use behavior\system\SystemBehavior; +use service\HookService; +use think\Session; + +/** + * Class SystemAdmin + * @package app\admin\model\system + */ +class SystemAdmin extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + public static function setAddTimeAttr($value) + { + return time(); + } + + public static function setRolesAttr($value) + { + return is_array($value) ? implode(',', $value) : $value; + } + + + /** + * 用户登陆 + * @param string $account 账号 + * @param string $pwd 密码 + * @param string $verify 验证码 + * @return bool 登陆成功失败 + */ + public static function login($account,$pwd) + { + $adminInfo = self::get(compact('account')); + if(!$adminInfo) return self::setErrorInfo('登陆的账号不存在!'); + if($adminInfo['pwd'] != md5($pwd)) return self::setErrorInfo('账号或密码错误,请重新输入'); + if(!$adminInfo['status']) return self::setErrorInfo('该账号已被关闭!'); + self::setLoginInfo($adminInfo); + HookService::afterListen('system_admin_login',$adminInfo,null,false,SystemBehavior::class); + return true; + } + + /** + * 保存当前登陆用户信息 + */ + public static function setLoginInfo($adminInfo) + { + Session::set('adminId',$adminInfo['id']); + Session::set('adminInfo',$adminInfo); + } + + /** + * 清空当前登陆用户信息 + */ + public static function clearLoginInfo() + { + Session::delete('adminInfo'); + Session::delete('adminId'); + Session::clear(); + } + + /** + * 检查用户登陆状态 + * @return bool + */ + public static function hasActiveAdmin() + { + return Session::has('adminId') && Session::has('adminInfo'); + } + + /** + * 获得登陆用户信息 + * @return mixed + */ + public static function activeAdminInfoOrFail() + { + $adminInfo = Session::get('adminInfo'); + if(!$adminInfo) exception('请登陆'); + if(!$adminInfo['status']) exception('该账号已被关闭!'); + return $adminInfo; + } + + /** + * 获得登陆用户Id 如果没有直接抛出错误 + * @return mixed + */ + public static function activeAdminIdOrFail() + { + $adminId = Session::get('adminId'); + if(!$adminId) exception('访问用户为登陆登陆!'); + return $adminId; + } + + /** + * @return array + */ + public static function activeAdminAuthOrFail() + { + $adminInfo = self::activeAdminInfoOrFail(); + return $adminInfo->level === 0 ? SystemRole::getAllAuth() : SystemRole::rolesByAuth($adminInfo->roles); + } + + /** + * 获得有效管理员信息 + * @param $id + * @return static + */ + public static function getValidAdminInfoOrFail($id) + { + $adminInfo = self::get($id); + if(!$adminInfo) exception('用户不能存在!'); + if(!$adminInfo['status']) exception('该账号已被关闭!'); + return $adminInfo; + } + + /** + * @param $field + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getOrdAdmin($field = 'real_name,id',$level = 0){ + return self::where('level','>=',$level)->field($field)->select(); + } + + public static function getTopAdmin($field = 'real_name,id') + { + return self::where('level',0)->field($field)->select(); + } + + /** + * @param $where + * @return array + */ + public static function systemPage($where){ + $model = new self; + if($where['name'] != ''){ + $model = $model->where('account','LIKE',"%$where[name]%"); + $model = $model->where('real_name','LIKE',"%$where[name]%"); + } + if($where['roles'] != '') + $model = $model->where("CONCAT(',',roles,',') LIKE '%,$where[roles],%'"); + $model = $model->where('level','=',$where['level'])->where('is_del',0); + return self::page($model,function($admin,$key){ + $admin->roles = SystemRole::where('id','IN',$admin->roles)->column('role_name'); + },$where); + } +} \ No newline at end of file diff --git a/application/admin/model/system/SystemAttachment.php b/application/admin/model/system/SystemAttachment.php new file mode 100644 index 00000000..aae35c07 --- /dev/null +++ b/application/admin/model/system/SystemAttachment.php @@ -0,0 +1,52 @@ + + * @day: 2017/11/13 + */ + +namespace app\admin\model\system; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 文件检验model + * Class SystemFile + * @package app\admin\model\system + */ +class SystemAttachment extends ModelBasic +{ + use ModelTrait; + /**添加附件记录 + */ + public static function attachmentAdd($name,$att_size,$att_type,$att_dir,$satt_dir='',$pid = 0 ) + { + $data['name'] = $name; + $data['att_dir'] = $att_dir; + $data['satt_dir'] = $satt_dir; + $data['att_size'] = $att_size; + $data['att_type'] = $att_type; + $data['time'] = time(); + $data['pid'] = $pid; + return self::create($data); + } + /** + * 获取分类图 + * */ + public static function getAll($id){ + $model = new self; + $where['pid'] = $id; + $model->where($where)->order('att_id desc'); + return $model->page($model,$where,'',30); + } + /** + * 获取单条信息 + * */ + public static function getinfo($att_id){ + $model = new self; + $where['att_id'] = $att_id; + return $model->where($where)->select()->toArray()[0]; + } + +} \ No newline at end of file diff --git a/application/admin/model/system/SystemAttachmentCategory.php b/application/admin/model/system/SystemAttachmentCategory.php new file mode 100644 index 00000000..b1639b63 --- /dev/null +++ b/application/admin/model/system/SystemAttachmentCategory.php @@ -0,0 +1,73 @@ +select(),0); + } + public static function tidyMenuTier($menusList,$pid = 0,$navList = []) + { + + foreach ($menusList as $k=>$menu){ + $menu = $menu->getData(); + if($menu['pid'] == $pid){ + unset($menusList[$k]); + $menu['child'] = self::tidyMenuTier($menusList,$menu['id']); + $navList[] = $menu; + } + } + return $navList; + } + + /**获取分类下拉列表 + * @return array + */ + public static function getCateList($id = 10000){ + $model = new self(); + if($id == 0) + $model->where('pid',$id); + return UtilService::sortListTier($model->select()->toArray()); + } + /** + * 获取单条信息 + * */ + public static function getinfo($att_id){ + $model = new self; + $where['att_id'] = $att_id; + return $model->where($where)->select()->toArray()[0]; + } + +} \ No newline at end of file diff --git a/application/admin/model/system/SystemConfig.php b/application/admin/model/system/SystemConfig.php new file mode 100644 index 00000000..93702e47 --- /dev/null +++ b/application/admin/model/system/SystemConfig.php @@ -0,0 +1 @@ + * @day: 2017/11/02 */ namespace app\admin\model\system; use basic\ModelBasic; use service\FormBuilder as Form; use traits\ModelTrait; class SystemConfig extends ModelBasic { use ModelTrait; /** * 修改单个配置 * */ public static function setValue($menu,$value){ if(empty($menu) || !($config_one = self::get(['menu_name'=>$menu]))) return self::setErrorInfo('字段名称错误'); if($config_one['type'] == 'radio' || $config_one['type'] == 'checkbox'){ $parameter = array(); $option = array(); $parameter = explode(',',$config_one['parameter']); foreach ($parameter as $k=>$v){ if(isset($v) && !empty($v)){ $option[$k] = explode('-',$v); } } $value_arr = array();//选项的值 foreach ($option as $k=>$v){ foreach ($v as $kk=>$vv) if(!$kk){ $value_arr[$k] = $vv; } } $i = 0;// if(is_array($value)){ foreach ($value as $value_v){ if(in_array($value_v,$value_arr)){ $i++; } } if(count($value) != $i) return self::setErrorInfo('输入的值不属于选项中的参数'); }else{ if(in_array($value,$value_arr)){ $i++; } if(!$i) return self::setErrorInfo('输入的值不属于选项中的参数'); } if($config_one['type'] == 'radio' && is_array($value)) return self::setErrorInfo('单选按钮的值是字符串不是数组'); } $bool = self::edit(['value' => json_encode($value)],$menu,'menu_name'); return $bool; } /** * 获取单个参数配置 * */ public static function getValue($menu){ if(empty($menu) || !($config_one = self::get(['menu_name'=>$menu]))) return false; return json_decode($config_one['value'],true); } /** * 获得多个参数 * @param $menus * @return array */ public static function getMore($menus) { $menus = is_array($menus) ? implode(',',$menus) : $menus; $list = self::where('menu_name','IN',$menus)->column('value','menu_name')?:[]; foreach ($list as $menu => $value){ $list[$menu] = json_decode($value,true); } return $list; } public static function getAllConfig() { $list = self::column('value','menu_name')?:[]; foreach ($list as $menu => $value){ $list[$menu] = json_decode($value,true); } return $list; } /** * text 判断 * */ public static function valiDateTextRole($data){ if (!$data['width']) return self::setErrorInfo('请输入文本框的宽度'); if ($data['width'] <= 0) return self::setErrorInfo('请输入正确的文本框的宽度'); return true; } /** * radio 和 checkbox规则的判断 * */ public static function valiDateRadioAndCheckbox($data){ $parameter = array(); $option = array(); $option_new = array(); $data['parameter'] = str_replace("\r\n","\n",$data['parameter']);//防止不兼容 $parameter = explode("\n",$data['parameter']); if(count($parameter) < 2)return self::setErrorInfo('请输入正确格式的配置参数'); foreach ($parameter as $k=>$v){ if(isset($v) && !empty($v)){ $option[$k] = explode('=',$v); } } if(count($option) < 2)return self::setErrorInfo('请输入正确格式的配置参数'); $bool = 1; foreach ($option as $k=>$v){ $option_new[$k] = $option[$k][0]; foreach ($v as $kk=>$vv){ $vv_num = strlen($vv); if(!$vv_num){ $bool = 0; } } } // dump($option); if(!$bool)return self::setErrorInfo('请输入正确格式的配置参数'); $num1 = count($option_new);//提取该数组的数目 $arr2 = array_unique($option_new);//合并相同的元素 $num2 = count($arr2);//提取合并后数组个数 if($num1>$num2)return self::setErrorInfo('请输入正确格式的配置参数'); return true; } /** * textarea 判断 * */ public static function valiDateTextareaRole($data){ if (!$data['width']) return self::setErrorInfo('请输入多行文本框的宽度'); if (!$data['high']) return self::setErrorInfo('请输入多行文本框的高度'); if ($data['width'] < 0) return self::setErrorInfo('请输入正确的多行文本框的宽度'); if ($data['high'] < 0) return self::setErrorInfo('请输入正确的多行文本框的宽度'); return true; } /** * 获取一数据 * */ public static function getOneConfig($filed,$value){ $where[$filed] = $value; return self::where($where)->find(); } /** * 获取配置分类 * */ public static function getAll($id){ $where['config_tab_id'] = $id; $where['status'] = 1; return self::where($where)->order('sort desc,id asc')->select(); } /** * 获取所有配置分类 * */ public static function getConfigTabAll($type=0){ $configAll = \app\admin\model\system\SystemConfigTab::getAll($type); $config_tab = array(); foreach ($configAll as $k=>$v){ if(!$v['info']){ $config_tab[$k]['value'] = $v['id']; $config_tab[$k]['label'] = $v['title']; $config_tab[$k]['icon'] = $v['icon']; $config_tab[$k]['type'] = $v['type']; } } return $config_tab; } /** * 选择类型 * */ public static function radiotype($type='text'){ return [ ['value'=>'text','label'=>'文本框','disabled'=>1] ,['value'=>'textarea','label'=>'多行文本框','disabled'=>1] ,['value'=>'radio','label'=>'单选按钮','disabled'=>1] ,['value'=>'upload','label'=>'文件上传','disabled'=>1] ,['value'=>'checkbox','label'=>'多选按钮','disabled'=>1] ]; } /** * 文本框 * */ public static function createInputRule($tab_id){ $formbuider = array(); $formbuider[] = Form::radio('type','类型','text')->options(self::radiotype()); $formbuider[] = Form::select('config_tab_id','分类',$tab_id)->setOptions(SystemConfig::getConfigTabAll(-1)); $formbuider[] = Form::input('info','配置名称')->autofocus(1); $formbuider[] = Form::input('menu_name','字段变量')->placeholder('例如:site_url'); $formbuider[] = Form::input('desc','配置简介'); $formbuider[] = Form::input('value','默认值'); $formbuider[] = Form::number('width','文本框宽(%)',100); $formbuider[] = Form::input('required','验证规则')->placeholder('多个请用,隔开例如:required:true,url:true'); $formbuider[] = Form::number('sort','排序'); $formbuider[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); return $formbuider; } /** * 多行文本框 * */ public static function createTextAreaRule($tab_id){ $formbuider = array(); $formbuider[] = Form::radio('type','类型','textarea')->options(self::radiotype()); $formbuider[] = Form::select('config_tab_id','分类',$tab_id)->setOptions(SystemConfig::getConfigTabAll(-1)); $formbuider[] = Form::input('info','配置名称')->autofocus(1); $formbuider[] = Form::input('menu_name','字段变量')->placeholder('例如:site_url'); $formbuider[] = Form::input('desc','配置简介'); $formbuider[] = Form::textarea('value','默认值'); $formbuider[] = Form::number('width','文本框宽(%)',100); $formbuider[] = Form::number('high','多行文本框高(%)',5); $formbuider[] = Form::number('sort','排序'); $formbuider[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); return $formbuider; } /** * 单选按钮 * */ public static function createRadioRule($tab_id){ $formbuider = array(); $formbuider[] = Form::radio('type','类型','radio')->options(self::radiotype()); $formbuider[] = Form::select('config_tab_id','分类',$tab_id)->setOptions(SystemConfig::getConfigTabAll(-1)); $formbuider[] = Form::input('info','配置名称')->autofocus(1); $formbuider[] = Form::input('menu_name','字段变量')->placeholder('例如:site_url'); $formbuider[] = Form::input('desc','配置简介'); $formbuider[] = Form::textarea('parameter','配置参数')->placeholder("参数方式例如:\n1=男\n2=女\n3=保密"); $formbuider[] = Form::input('value','默认值'); $formbuider[] = Form::number('sort','排序'); $formbuider[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); return $formbuider; } /** * 文件上传 * */ public static function createUploadRule($tab_id){ $formbuider = array(); $formbuider[] = Form::radio('type','类型','upload')->options(self::radiotype()); $formbuider[] = Form::select('config_tab_id','分类',$tab_id)->setOptions(SystemConfig::getConfigTabAll(-1)); $formbuider[] = Form::input('info','配置名称')->autofocus(1); $formbuider[] = Form::input('menu_name','字段变量')->placeholder('例如:site_url'); $formbuider[] = Form::input('desc','配置简介'); $formbuider[] = Form::radio('upload_type','上传类型',1)->options([['value'=>1,'label'=>'单图'],['value'=>2,'label'=>'多图'],['value'=>3,'label'=>'文件']]); $formbuider[] = Form::number('sort','排序'); $formbuider[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); return $formbuider; } /** * 多选框 * */ public static function createCheckboxRule($tab_id){ $formbuider = array(); $formbuider[] = Form::radio('type','类型','checkbox')->options(self::radiotype()); $formbuider[] = Form::select('config_tab_id','分类',$tab_id)->setOptions(SystemConfig::getConfigTabAll(-1)); $formbuider[] = Form::input('info','配置名称')->autofocus(1); $formbuider[] = Form::input('menu_name','字段变量')->placeholder('例如:site_url'); $formbuider[] = Form::input('desc','配置简介'); $formbuider[] = Form::textarea('parameter','配置参数')->placeholder("参数方式例如:\n1=白色\n2=红色\n3=黑色"); $formbuider[] = Form::input('value','默认值'); $formbuider[] = Form::number('sort','排序'); $formbuider[] = Form::radio('status','状态',1)->options([['value'=>1,'label'=>'显示'],['value'=>2,'label'=>'隐藏']]); return $formbuider; } /** * 插入数据到数据库 * */ public static function set($data) { return self::create($data); } } \ No newline at end of file diff --git a/application/admin/model/system/SystemConfigTab.php b/application/admin/model/system/SystemConfigTab.php new file mode 100644 index 00000000..04e61db3 --- /dev/null +++ b/application/admin/model/system/SystemConfigTab.php @@ -0,0 +1 @@ + * @day: 2017/11/02 */ namespace app\admin\model\system; use traits\ModelTrait; use basic\ModelBasic; use think\Db; /** * 配置分类model * * Class SystemConfigTab * @package app\admin\model\system */ class SystemConfigTab extends ModelBasic { use ModelTrait; /** * 获取单选按钮或者多选按钮的显示值 * */ public static function getRadioOrCheckboxValueInfo($menu_name,$value){ $parameter = array(); $option = array(); $config_one = \app\admin\model\system\SystemConfig::getOneConfig('menu_name',$menu_name); // dump($config_one); // exit(); // if(empty($menu) || !($config_one = self::get(['menu_name'=>$menu]))) return false; $parameter = explode("\n",$config_one['parameter']); foreach ($parameter as $k=>$v){ if(isset($v) && !empty($v)){ $option[$k] = explode('=',$v); } } // $value = json_decode($value,true); if(!is_array($value)){ $value = explode("\n",$value); } // dump($value); // dump($option); $value_arr = array();//选项的值 foreach ($option as $k=>$v){ foreach ($v as $kk=>$vv){ if(is_array($value)) { if (in_array($v[0], $value)) { $value_arr[$k] = $v[1]; } } break; } } if(empty($value_arr)){ return '空'; } return $value_arr; // exit(); // if(is_array($value)){ // foreach ($value as $k=>$value_v){ // if(in_array($value_v,$value_arr)){ // $i[$k] = 1; // } // } // if(count($value) != $i) return self::setErrorInfo('输入的值不属于选项中的参数'); // }else{ // if(in_array($value,$value_arr)){ // $i++; // } // if(!$i) return self::setErrorInfo('输入的值不属于选项中的参数'); // } // if($config_one['type'] == 'radio' && is_array($value)) return self::setErrorInfo('单选按钮的值是字符串不是数组'); } /** * 插入数据到数据库 * */ public static function set($data) { return self::create($data); } /** * 获取全部 * */ public static function getAll($type = 0){ $where['status'] = 1; if($type>-1)$where['type'] = $type; return Db::name('SystemConfigTab')->where($where)->select(); } /** * 获取配置分类 * */ public static function getSystemConfigTabPage($where = array()) { $model = new self; if($where['title'] != '') $model = $model->where('title','LIKE',"%$where[title]%"); if($where['status'] != '') $model = $model->where('status',$where['status']); return self::page($model,$where); } public static function edit($data,$id,$field='id') { return self::update($data,[$field=>$id]); } /** * 更新数据 * @access public * @param array $data 数据数组 * @param array $where 更新条件 * @param array|true $field 允许字段 * @return $this */ public static function update($data = [], $where = [], $field = null) { $model = new static(); if (!empty($field)) { $model->allowField($field); } $result = $model->isUpdate(true)->save($data, $where); return $model; } } \ No newline at end of file diff --git a/application/admin/model/system/SystemFile.php b/application/admin/model/system/SystemFile.php new file mode 100644 index 00000000..a4829013 --- /dev/null +++ b/application/admin/model/system/SystemFile.php @@ -0,0 +1,23 @@ + + * @day: 2017/11/13 + */ + +namespace app\admin\model\system; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 附件管理model + * Class SystemAttachment + * @package app\admin\model\system + */ +class SystemFile extends ModelBasic +{ + use ModelTrait; + + +} \ No newline at end of file diff --git a/application/admin/model/system/SystemGroup.php b/application/admin/model/system/SystemGroup.php new file mode 100644 index 00000000..c7fe83e2 --- /dev/null +++ b/application/admin/model/system/SystemGroup.php @@ -0,0 +1,31 @@ + + * @day: 2017/11/13 + */ + +namespace app\admin\model\system; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 数据组model + * Class SystemGroup + * @package app\admin\model\system + */ +class SystemGroup extends ModelBasic +{ + use ModelTrait; + + /** + * 根据id获取当前记录中的fields值 + * @param $id + * @return array + */ + public static function getField($id){ + $fields = json_decode(self::where('id',$id)->value("fields"),true); + return compact('fields'); + } +} \ No newline at end of file diff --git a/application/admin/model/system/SystemGroupData.php b/application/admin/model/system/SystemGroupData.php new file mode 100644 index 00000000..d9c8b9e7 --- /dev/null +++ b/application/admin/model/system/SystemGroupData.php @@ -0,0 +1,112 @@ + + * @day: 2017/11/13 + */ + +namespace app\admin\model\system; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 数据列表 model + * Class SystemGroupData + * @package app\admin\model\system + */ +class SystemGroupData extends ModelBasic +{ + use ModelTrait; + + /** + * 根据where条件获取当前表中的前20条数据 + * @param $params + * @return array + */ + public static function getList($params){ + $model = new self; + if($params['gid'] !== '') $model = $model->where('gid',$params['gid']); + if($params['status'] !== '') $model = $model->where('status',$params['status']); + return self::page($model,function($item,$key){ + $info = json_decode($item->value,true); + foreach ($info as $index => $value) { + if($value["type"] == "checkbox")$info[$index]["value"] = implode(",",$value["value"]); + if($value["type"] == "upload" || $value["type"] == "uploads"){ + $html_img = ''; + if(is_array($value["value"])){ + foreach ($value["value"] as $img) { + $html_img .= '
'; + } + }else{ + $html_img = ''; + } + $info[$index]["value"] = $html_img; + } + } + $item->value = $info; + }); + } + + public static function getGroupData($config_name,$limit = 0) + { + $group = SystemGroup::where('config_name',$config_name)->field('name,info,config_name')->find(); + if(!$group) return false; + $group['data'] = self::getAllValue($config_name,$limit); + return $group; + } + + /** + * 获取单个值 + * @param $config_name + * @param int $limit + * @return mixed + */ + public static function getAllValue($config_name,$limit = 0){ + $model = new self; + $model->alias('a')->field('a.*,b.config_name')->join('system_group b','a.gid = b.id')->where(array("b.config_name"=>$config_name,"a.status"=>1))->order('sort desc,id ASC'); + if($limit > 0) $model->limit($limit); + $data = []; + $result = $model->select(); + if(!$result) return $data; + foreach ($result as $key => $value) { + $data[$key]["id"] = $value["id"]; + $fields = json_decode($value["value"],true); + foreach ($fields as $index => $field) { +// $data[$key][$index] = $field['type'] == 'upload' ? (isset($field["value"][0]) ? $field["value"][0]: ''):$field["value"]; + $data[$key][$index] = $field["value"]; + } + } + return $data; + } + + public static function tidyList($result) + { + $data = []; + if(!$result) return $data; + foreach ($result as $key => $value) { + $data[$key]["id"] = $value["id"]; + $fields = json_decode($value["value"],true); + foreach ($fields as $index => $field) { + $data[$key][$index] = $field['type'] == 'upload' ? (isset($field["value"][0]) ? $field["value"][0]: ''):$field["value"]; + } + } + return $data; + } + + + /** + * 根据id获取当前记录中的数据 + * @param $id + * @return mixed + */ + public static function getDateValue($id){ + $value = self::alias('a')->where(array("id"=>$id))->find(); + $data["id"] = $value["id"]; + $fields = json_decode($value["value"],true); + foreach ($fields as $index => $field) { + $data[$index] = $field["value"]; + } + return $data; + } +} \ No newline at end of file diff --git a/application/admin/model/system/SystemLog.php b/application/admin/model/system/SystemLog.php new file mode 100644 index 00000000..7b9d58ed --- /dev/null +++ b/application/admin/model/system/SystemLog.php @@ -0,0 +1,101 @@ + + * @day: 2017/11/28 + */ + +namespace app\admin\model\system; + + +use traits\ModelTrait; +use basic\ModelBasic; +use think\Request; +use app\admin\model\system\SystemMenus; +use app\admin\model\system\SystemAdmin; + +/** + * 管理员操作记录 + * Class SystemLog + * @package app\admin\model\system + */ +class SystemLog extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + + /** + * 管理员访问记录 + * @param Request $request + */ + public static function adminVisit($adminId,$adminName,$type) + { + $request = Request::instance(); + $module = $request->module(); + $controller = $request->controller(); + $action = $request->action(); + $route = $request->route(); + $data = [ + 'method'=>$request->method(), + 'admin_id'=>$adminId, + 'admin_name'=>$adminName, + 'path'=>SystemMenus::getAuthName($action,$controller,$module,$route), + 'page'=>SystemMenus::getVisitName($action,$controller,$module,$route)?:'未知', + 'ip'=>$request->ip(), + 'type'=>$type + ]; + return self::set($data); + } + + /** + * 手动添加管理员当前页面访问记录 + * @param array $adminInfo + * @param string $page 页面名称 + * @return object + */ + public static function setCurrentVisit($adminInfo, $page) + { + $request = Request::instance(); + $module = $request->module(); + $controller = $request->controller(); + $action = $request->action(); + $route = $request->route(); + $data = [ + 'method'=>$request->method(), + 'admin_id'=>$adminInfo['id'], + 'path'=>SystemMenus::getAuthName($action,$controller,$module,$route), + 'page'=>$page, + 'ip'=>$request->ip() + ]; + return self::set($data); + } + + /** + * 获取管理员访问记录 + * */ + public static function systemPage($where = array()){ + $model = new self; + $model = $model->alias('l'); + if($where['pages'] !== '') $model = $model->where('l.page','LIKE',"%$where[pages]%"); + if($where['admin_id'] != '') + $adminIds = $where['admin_id']; + else + $adminIds = SystemAdmin::where('level','>=',$where['level'])->column('id'); + $model = $model->where('l.admin_id','IN',$adminIds); + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('l.add_time','>',strtotime($startTime)); + $model = $model->where('l.add_time','<',strtotime($endTime)); + } + $model->where('l.type','system'); + $model = $model->order('l.id desc'); + return self::page($model,$where); + } +} \ No newline at end of file diff --git a/application/admin/model/system/SystemMenus.php b/application/admin/model/system/SystemMenus.php new file mode 100644 index 00000000..a23d4101 --- /dev/null +++ b/application/admin/model/system/SystemMenus.php @@ -0,0 +1,150 @@ + + * @day: 2017/11/02 + */ +namespace app\admin\model\system; + +use traits\ModelTrait; +use basic\ModelBasic; +use think\Url; + +/** + * 菜单 model + * Class SystemMenus + * @package app\admin\model\system + */ +class SystemMenus extends ModelBasic +{ + use ModelTrait; + + public static $isShowStatus = [1=>'显示',0=>'不显示']; + + public static $accessStatus = [1=>'管理员可用',0=>'管理员不可用']; + + public static function legalWhere($where = []) + { + $where['is_show'] = 1; + } + + public function setParamsAttr($value) + { + $value = $value ? explode('/',$value) : []; + $params = array_chunk($value,2); + $data = []; + foreach ($params as $param){ + if(isset($param[0]) && isset($param[1])) $data[$param[0]] = $param[1]; + } + return json_encode($data); + } + + protected function setControllerAttr($value) + { + return lcfirst($value); + } + + public function getParamsAttr($_value) + { + return json_decode($_value,true); + } + + public function getPidAttr($value) + { + return !$value ? '顶级' : self::get($value)['menu_name']; + } + + public static function getParentMenu($field='*',$filter=false) + { + $where = ['pid'=>0]; + $query = self::field($field); + $query = $filter ? $query->where(self::legalWhere($where)) : $query->where($where); + return $query->order('sort DESC')->select(); + } + + public static function menuList() + { + $menusList = self::where('is_show','1')->where('access','1')->order('sort DESC')->select(); + return self::tidyMenuTier(true,$menusList); + } + + public static function ruleList() + { + $ruleList = self::order('sort DESC')->select(); + return self::tidyMenuTier(false,$ruleList); + } + + public static function rolesByRuleList($rules) + { + $res = SystemRole::where('id','IN',$rules)->field('GROUP_CONCAT(rules) as ids')->find(); + $ruleList = self::where('id','IN',$res['ids'])->whereOr('pid',0)->order('sort DESC')->select(); + return self::tidyMenuTier(false,$ruleList); + } + + public static function getAuthName($action,$controller,$module,$route) + { + return strtolower($module.'/'.$controller.'/'.$action.'/'.SystemMenus::paramStr($route)); + } + + public static function tidyMenuTier($adminFilter = false,$menusList,$pid = 0,$navList = []) + { + static $allAuth = null; + static $adminAuth = null; + if($allAuth === null) $allAuth = $adminFilter == true ? SystemRole::getAllAuth() : [];//所有的菜单 + if($adminAuth === null) $adminAuth = $adminFilter == true ? SystemAdmin::activeAdminAuthOrFail() : [];//当前登录用户的菜单 + foreach ($menusList as $k=>$menu){ + $menu = $menu->getData(); + if($menu['pid'] == $pid){ + unset($menusList[$k]); + $params = json_decode($menu['params'],true);//获取参数 + $authName = self::getAuthName($menu['action'],$menu['controller'],$menu['module'],$params);// 按钮链接 + if($pid != 0 && $adminFilter && in_array($authName,$allAuth) && !in_array($authName,$adminAuth)) continue; + $menu['child'] = self::tidyMenuTier($adminFilter,$menusList,$menu['id']); + if($pid != 0 && !count($menu['child']) && !$menu['controller'] && !$menu['action']) continue; + $menu['url'] = !count($menu['child']) ? Url::build($menu['module'].'/'.$menu['controller'].'/'.$menu['action'],$params) : 'javascript:void(0);'; + if($pid == 0 && !count($menu['child'])) continue; + $navList[] = $menu; + } + } + return $navList; + } + + public static function delMenu($id) + { + if(self::where('pid',$id)->count()) + return self::setErrorInfo('请先删除改菜单下的子菜单!'); + return self::del($id); + } + + public static function getAdminPage($params) + { + $model = new self; + if($params['is_show'] !== '') $model = $model->where('is_show',$params['is_show']); +// if($params['access'] !== '') $model = $model->where('access',$params['access']);//子管理员是否可用 + if($params['pid'] !== ''&& !$params['keyword'] ) $model = $model->where('pid',$params['pid']); + if($params['keyword'] !== '') $model = $model->where('menu_name|id|pid','LIKE',"%$params[keyword]%"); + $model = $model->order('sort DESC,id DESC'); + return self::page($model,$params); + } + + public static function paramStr($params) + { + if(!is_array($params)) $params = json_decode($params,true)?:[]; + $p = []; + foreach ($params as $key => $param){ + $p[] = $key; + $p[] = $param; + } + return implode('/',$p); + } + + public static function getVisitName($action,$controller,$module,array $route = []) + { + $params = json_encode($route); + return self::where('action',$action) + ->where('controller',lcfirst($controller)) + ->where('module',lcfirst($module)) + ->where('params',['=',$params],['=','[]'],'or')->order('id DESC')->value('menu_name'); + } + +} \ No newline at end of file diff --git a/application/admin/model/system/SystemNotice.php b/application/admin/model/system/SystemNotice.php new file mode 100644 index 00000000..8330b898 --- /dev/null +++ b/application/admin/model/system/SystemNotice.php @@ -0,0 +1,121 @@ + + * @day: 2017/11/02 + */ +namespace app\admin\model\system; + +use traits\ModelTrait; +use basic\ModelBasic; +use think\Db; + +/** + * 后台通知model + * Class SystemNotice + * @package app\admin\model\system + */ +class SystemNotice extends ModelBasic +{ + use ModelTrait; + + protected function setResultAttr($value) + { + return json_encode($value); + } + + protected function setTableTitleAttr($value) + { + $list = []; + if(!empty($value)){ + $group = explode(',',$value); + $list = array_map(function($v){ + list($title,$key) = explode('-',$v); + return compact('title','key'); + },$group); + } + return json_encode($list); + } + + protected function getTableTitleAttr($value) + { + return json_decode($value,true); + } + + protected function getResultAttr($value) + { + return json_decode($value,true); + } + + protected function setPushAdminAttr($value) + { + $value = is_array($value) ? array_unique(array_filter($value)) : []; + return implode(',',$value); + } + + protected function getPushAdminAttr($value) + { + return array_filter(explode(',',$value)); + } + + public static function typeByAdminList($type,$field = 'id') + { + return self::where('type',$type)->field($field)->find(); + } + + public static function systemNoticeAdminDb() + { + return Db::name('SystemNoticeAdmin'); + } + + public static function adminMessage($notice_type,$admin_id,$link_id,array $table_data = []) + { + $table_data = json_encode($table_data); + $add_time = time(); + return self::systemNoticeAdminDb()->insert(compact('notice_type','admin_id','link_id','table_data','add_time')); + } + + public static function noticeMessage($noticeType,$linkId,array $tableData = []) + { + $noticeInfo = self::get(['type'=>$noticeType]); + if(!$noticeInfo) return self::setErrorInfo('通知模板消息不存在!'); + $adminIds = array_merge(array_map(function($v){ + return $v['id']; + },SystemAdmin::getTopAdmin('id')->toArray())?:[],self::typeByAdminList($noticeType,'push_admin')->push_admin?:[]); + $adminIds = array_unique(array_filter($adminIds)); + if(!count($adminIds)) return self::setErrorInfo('没有有效的通知用户!'); + foreach ($adminIds as $id){ + self::adminMessage($noticeType,$id,$linkId,$tableData); + } + return true; + } + + public static function getAdminNoticeTotal($adminId) + { + $list = self::alias('A')->join('__SYSTEM_NOTICE_ADMIN__ B','B.notice_type = A.type') + ->where('A.status',1)->where('B.is_visit',0)->where('B.is_click',0)->where('B.admin_id',$adminId) + ->field('count(B.id) total')->group('A.id')->select()->toArray(); + if(!$list) return 0; + return array_reduce($list,function($initial,$res){ + return $initial+$res['total']; + },0); + } + + public static function getAdminNotice($adminId) + { + $list = self::alias('A')->join('__SYSTEM_NOTICE_ADMIN__ B','B.notice_type = A.type') + ->where('A.status',1)->where('B.is_visit',0)->where('B.is_click',0)->where('B.admin_id',$adminId) + ->field('A.id,A.type,A.title,A.icon,count(B.id) total,A.template,max(B.add_time) as last_time') + ->group('A.id')->having('total > 0')->select()->toArray(); + $noticeTypeList = []; + array_walk($list,function(&$notice) use(&$noticeTypeList){ + $notice['message'] = sprintf($notice['template'],$notice['total']); + $noticeTypeList[] = $notice['type']; + }); + if(count($noticeTypeList)) + self::systemNoticeAdminDb()->where('notice_type','IN',$noticeTypeList)->where('admin_id',$adminId) + ->update(['is_visit'=>1,'visit_time'=>time()]); + return $list; + } + +} \ No newline at end of file diff --git a/application/admin/model/system/SystemRole.php b/application/admin/model/system/SystemRole.php new file mode 100644 index 00000000..7730876c --- /dev/null +++ b/application/admin/model/system/SystemRole.php @@ -0,0 +1,81 @@ + + * @day: 2017/11/13 + */ + +namespace app\admin\model\system; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 身份管理 model + * Class SystemRole + * @package app\admin\model\system + */ +class SystemRole extends ModelBasic +{ + use ModelTrait; + + public static function setRulesAttr($value) + { + return is_array($value) ? implode(',',$value) : $value; + } + + /** + * 选择管理员身份 + * @param int $level + * @param string $field + * @return array + */ + public static function getRole($level = 0 ,$field='id,role_name') + { + return self::where('status',1)->where('level','=',$level)->column($field); + } + + + public static function rolesByAuth($rules) + { + if(empty($rules)) return []; + $rules = self::where('id','IN',$rules)->where('status','1')->column('rules'); + $rules = array_unique(explode(',',implode(',',$rules))); + $_auth = SystemMenus::all(function($query) use($rules){ + $query->where('id','IN',$rules) + ->where('controller|action','<>','') + ->field('module,controller,action,params'); + }); + return self::tidyAuth($_auth?:[]); + } + + public static function getAllAuth() + { + static $auth = null; + $auth === null && ($auth = self::tidyAuth(SystemMenus::all(function($query){ + $query->where('controller|action','<>','')->field('module,controller,action,params'); + })?:[])); + return $auth; + } + + protected static function tidyAuth($_auth) + { + $auth = []; + foreach ($_auth as $k=>$val){ + $auth[] = SystemMenus::getAuthName($val['action'],$val['controller'],$val['module'],$val['params']); + } + return $auth; + } + + + public static function systemPage($where){ + $model = new self; + if($where['role_name'] != '') $model = $model->where('role_name','LIKE',"%$where[role_name]%"); + if($where['status'] != '') $model = $model->where('status',$where['status']); + $model->where('level','=',bcadd($where['level'],1,0)); + return self::page($model,(function($item,$key){ + $item->rules = SystemMenus::where('id','IN',$item->rules)->column('menu_name'); + }),$where); + } + +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreCoupon.php b/application/admin/model/ump/StoreCoupon.php new file mode 100644 index 00000000..9a2ae976 --- /dev/null +++ b/application/admin/model/ump/StoreCoupon.php @@ -0,0 +1,62 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\ump; + + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * Class StoreCategory + * @package app\admin\model\store + */ +class StoreCoupon extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function systemPage($where){ + $model = new self; + if($where['status'] != '') $model = $model->where('status',$where['status']); + if($where['title'] != '') $model = $model->where('title','LIKE',"%$where[title]%"); +// if($where['is_del'] != '') $model = $model->where('is_del',$where['is_del']); + $model = $model->where('is_del',0); + $model = $model->order('sort desc,id desc'); + return self::page($model,$where); + } + + /** + * @param $where + * @return array + */ + public static function systemPageCoupon($where){ + $model = new self; + if($where['status'] != '') $model = $model->where('status',$where['status']); + if($where['title'] != '') $model = $model->where('title','LIKE',"%$where[title]%"); +// if($where['is_del'] != '') $model = $model->where('is_del',$where['is_del']); + $model = $model->where('is_del',0); + $model = $model->where('status',1); + $model = $model->order('sort desc,id desc'); + return self::page($model,$where); + } + + public static function editIsDel($id){ + $data['status'] = 0; + self::beginTrans(); + $res1 = self::edit($data,$id); + $res2 = false !== StoreCouponUser::where('cid',$id)->setField('is_fail',1); + $res3 = false !== StoreCouponIssue::where('cid',$id)->setField('status',-1); + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + + } +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreCouponIssue.php b/application/admin/model/ump/StoreCouponIssue.php new file mode 100644 index 00000000..2b01ec81 --- /dev/null +++ b/application/admin/model/ump/StoreCouponIssue.php @@ -0,0 +1,40 @@ + + * @day: 2018/01/17 + */ + +namespace app\admin\model\ump; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponIssue extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + public static function stsypage($where){ + $model = self::alias('A')->field('A.*,B.title')->join('__STORE_COUPON__ B','A.cid = B.id')->where('A.is_del',0)->order('A.add_time DESC'); + if(isset($where['status']) && $where['status']!=''){ + $model=$model->where('A.status',$where['status']); + } + if(isset($where['coupon_title']) && $where['coupon_title']!=''){ + $model=$model->where('B.title','LIKE',"%$where[coupon_title]%"); + } + return self::page($model); + } + + protected function setAddTimeAttr() + { + return time(); + } + + public static function setIssue($cid,$total_count = 0,$start_time = 0,$end_time = 0,$remain_count = 0,$status = 0) + { + return self::set(compact('cid','start_time','end_time','total_count','remain_count','status')); + } +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreCouponIssueUser.php b/application/admin/model/ump/StoreCouponIssueUser.php new file mode 100644 index 00000000..db6ad52c --- /dev/null +++ b/application/admin/model/ump/StoreCouponIssueUser.php @@ -0,0 +1,29 @@ + + * @day: 2018/01/23 + */ + +namespace app\admin\model\ump; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponIssueUser extends ModelBasic +{ + use ModelTrait; + + public static function systemCouponIssuePage($issue_coupon_id) + { + $model = self::alias('A')->field('B.nickname,B.avatar,A.add_time') + ->join('__USER__ B','A.uid = B.uid') + ->where('A.issue_coupon_id',$issue_coupon_id); + return self::page($model,function($item){ + $item['add_time'] = $item['add_time'] == 0 ? '未知' : date('Y/m/d H:i',$item['add_time']); + return $item; + }); + } + +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreCouponUser.php b/application/admin/model/ump/StoreCouponUser.php new file mode 100644 index 00000000..9f52e7a7 --- /dev/null +++ b/application/admin/model/ump/StoreCouponUser.php @@ -0,0 +1,69 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\ump; + + +use app\admin\model\wechat\WechatUser as UserModel; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * Class StoreCategory + * @package app\admin\model\store + */ +class StoreCouponUser extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function systemPage($where){ + $model = new self; + if($where['status'] != '') $model = $model->where('status',$where['status']); + if($where['is_fail'] != '') $model = $model->where('status',$where['is_fail']); + if($where['coupon_title'] != '') $model = $model->where('coupon_title','LIKE',"%$where[coupon_title]%"); + if($where['nickname'] != ''){ + $uid = UserModel::where('nickname','LIKE',"%$where[nickname]%")->column('uid'); + $model = $model->where('uid','IN',implode(',',$uid)); + }; +// $model = $model->where('is_del',0); + $model = $model->order('id desc'); + return self::page($model,function ($item){ + $item['nickname'] = UserModel::where('uid',$item['uid'])->value('nickname'); + },$where); + } + + /** + * 给用户发放优惠券 + * @param $coupon + * @param $user + * @return int|string + */ + public static function setCoupon($coupon,$user){ + $data = array(); + foreach ($user as $k=>$v){ + $data[$k]['cid'] = $coupon['id']; + $data[$k]['uid'] = $v; + $data[$k]['coupon_title'] = $coupon['title']; + $data[$k]['coupon_price'] = $coupon['coupon_price']; + $data[$k]['use_min_price'] = $coupon['use_min_price']; + $data[$k]['add_time'] = time(); + $data[$k]['end_time'] = $data[$k]['add_time']+$coupon['coupon_time']*86400; + } + $data_num = array_chunk($data,30); + self::beginTrans(); + $res = true; + foreach ($data_num as $k=>$v){ + $res = $res && self::insertAll($v); + } + self::checkTrans($res); + return $res; + } +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreSeckill.php b/application/admin/model/ump/StoreSeckill.php new file mode 100644 index 00000000..f3c69d0d --- /dev/null +++ b/application/admin/model/ump/StoreSeckill.php @@ -0,0 +1,331 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\ump; + +use app\admin\model\order\StoreOrder; +use app\admin\model\store\StoreProductRelation; +use app\admin\model\system\SystemConfig; +use traits\ModelTrait; +use basic\ModelBasic; +use app\admin\model\store\StoreProduct; +use service\PHPExcelService; + +/** + * Class StoreSeckill + * @package app\admin\model\store + */ +class StoreSeckill extends ModelBasic +{ + use ModelTrait; + + /** + * 秒杀产品过滤条件 + * @param $model + * @param $type + * @return mixed + */ + public static function setWhereType($model,$type){ + switch ($type){ + case 1: + $data = ['status'=>0,'is_del'=>0]; + break; + case 2: + $data = ['status'=>1,'is_del'=>0]; + break; + case 3: + $data = ['status'=>1,'is_del'=>0,'stock'=>0]; + break; + case 4: + $data = ['status'=>1,'is_del'=>0,'stock'=>['elt',1]]; + break; + case 5: + $data = ['is_del'=>1]; + break; + } + if(isset($data)) $model = $model->where($data); + return $model; + } + + /** + * 秒杀产品数量 图标展示 + * @param $type + * @param $data + * @return array + */ + public static function getChatrdata($type,$data){ + $legdata = ['销量','数量','点赞','收藏']; + $model = self::setWhereType(self::order('id desc'),$type); + $list = self::getModelTime(compact('data'),$model) + ->field('FROM_UNIXTIME(add_time,"%Y-%c-%d") as un_time,count(id) as count,sum(sales) as sales') + ->group('un_time') + ->distinct(true) + ->select() + ->each(function($item) use($data){ + $item['collect']=self::getModelTime(compact('data'),new StoreProductRelation)->where(['type'=>'collect'])->count(); + $item['like']=self::getModelTime(compact('data'),new StoreProductRelation())->where(['type'=>'like'])->count(); + })->toArray(); + $chatrList=[]; + $datetime=[]; + $data_item=[]; + $itemList=[0=>[],1=>[],2=>[],3=>[]]; + foreach ($list as $item){ + $itemList[0][]=$item['sales']; + $itemList[1][]=$item['count']; + $itemList[2][]=$item['like']; + $itemList[3][]=$item['collect']; + array_push($datetime,$item['un_time']); + } + foreach ($legdata as $key=>$leg){ + $data_item['name']=$leg; + $data_item['type']='line'; + $data_item['data']=$itemList[$key]; + $chatrList[]=$data_item; + unset($data_item); + } + unset($leg); + $badge = self::getbadge(compact('data'),$type); + $count = self::setWhereType(self::getModelTime(compact('data'),new self()),$type)->count(); + return compact('datetime','chatrList','legdata','badge','count'); + + } + + /** + * 秒杀产品数量 + * @param $where + * @param $type + * @return array + */ + public static function getbadge($where,$type){ + $StoreOrderModel = new StoreOrder(); + $replenishment_num = SystemConfig::getValue('replenishment_num'); + $replenishment_num = $replenishment_num > 0 ? $replenishment_num : 20; + $stock1 = self::getModelTime($where,new self())->where('stock','<',$replenishment_num)->column('stock'); + $sum_stock = self::where('stock','<',$replenishment_num)->column('stock'); + $stk=[]; + foreach ($stock1 as $item){ + $stk[]=$replenishment_num-$item; + } + $lack=array_sum($stk); + $sum=[]; + foreach ($sum_stock as $val){ + $sum[]=$replenishment_num-$val; + } + return [ + [ + 'name'=>'商品数量', + 'field'=>'件', + 'count'=>self::setWhereType(new self(),$type)->where('add_time','<',mktime(0,0,0,date('m'),date('d'),date('Y')))->sum('stock'), + 'content'=>'商品数量总数', + 'background_color'=>'layui-bg-blue', + 'sum'=>self::sum('stock'), + 'class'=>'fa fa fa-ioxhost', + ], + [ + 'name'=>'新增商品', + 'field'=>'件', + 'count'=>self::setWhereType(self::getModelTime($where,new self),$type)->sum('stock'), + 'content'=>'新增商品总数', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::where('status',1)->sum('stock'), + 'class'=>'fa fa-line-chart', + ], + [ + 'name'=>'活动商品', + 'field'=>'件', + 'count'=>self::getModelTime($where,$StoreOrderModel)->where('seckill_id','NEQ',0)->sum('total_num'), + 'content'=>'活动商品总数', + 'background_color'=>'layui-bg-green', + 'sum'=>$StoreOrderModel->sum('total_num'), + 'class'=>'fa fa-bar-chart', + ], + [ + 'name'=>'缺货商品', + 'field'=>'件', + 'count'=>$lack, + 'content'=>'总商品数量', + 'background_color'=>'layui-bg-orange', + 'sum'=>array_sum($sum), + 'class'=>'fa fa-cube', + ], + ]; + } + + /** + * 销量排行 top 10 + * layui-bg-red 红 layui-bg-orange 黄 layui-bg-green 绿 layui-bg-blue 蓝 layui-bg-cyan 黑 + */ + public static function getMaxList($where){ + $classs=['layui-bg-red','layui-bg-orange','layui-bg-green','layui-bg-blue','layui-bg-cyan']; + $model=StoreOrder::alias('a')->join('store_seckill b','b.id=a.seckill_id')->where('a.paid',1); + $list=self::getModelTime($where,$model,'a.add_time')->group('a.seckill_id')->order('p_count desc')->limit(10) + ->field(['count(a.seckill_id) as p_count','b.title as store_name','sum(b.price) as sum_price'])->select(); + if(count($list)) $list=$list->toArray(); + $maxList=[]; + $sum_count=0; + $sum_price=0; + foreach ($list as $item){ + $sum_count+=$item['p_count']; + $sum_price=bcadd($sum_price,$item['sum_price'],2); + } + unset($item); + foreach ($list as $key=>&$item){ + $item['w']=bcdiv($item['p_count'],$sum_count,2)*100; + $item['class']=isset($classs[$key]) ?$classs[$key]:( isset($classs[$key-count($classs)]) ? $classs[$key-count($classs)]:''); + $item['store_name']=self::getSubstrUTf8($item['store_name']); + } + $maxList['sum_count']=$sum_count; + $maxList['sum_price']=$sum_price; + $maxList['list']=$list; + return $maxList; + } + + /** + * 获取秒杀利润 + * @param $where + * @return array + */ + public static function ProfityTop10($where){ + $classs=['layui-bg-red','layui-bg-orange','layui-bg-green','layui-bg-blue','layui-bg-cyan']; + $model = StoreOrder::alias('a')->join('store_seckill b','b.id = a.seckill_id')->where('a.paid',1); + $list=self::getModelTime($where,$model,'a.add_time')->group('a.seckill_id')->order('profity desc')->limit(10) + ->field(['count(a.seckill_id) as p_count','b.title as store_name','sum(b.price) as sum_price','(b.price-b.cost) as profity']) + ->select(); + if(count($list)) $list=$list->toArray(); + $maxList=[]; + $sum_count=0; + $sum_price=0; + foreach ($list as $item){ + $sum_count+=$item['p_count']; + $sum_price=bcadd($sum_price,$item['sum_price'],2); + } + foreach ($list as $key=>&$item){ + $item['w']=bcdiv($item['sum_price'],$sum_price,2)*100; + $item['class']=isset($classs[$key]) ?$classs[$key]:( isset($classs[$key-count($classs)]) ? $classs[$key-count($classs)]:''); + $item['store_name']=self::getSubstrUTf8($item['store_name'],30); + } + $maxList['sum_count']=$sum_count; + $maxList['sum_price']=$sum_price; + $maxList['list']=$list; + return $maxList; + } + + /** + * 获取秒杀缺货 + * @param $where + * @return array + */ + public static function getLackList($where){ + $replenishment_num = SystemConfig::getValue('replenishment_num'); + $replenishment_num = $replenishment_num > 0 ? $replenishment_num : 20; + $list=self::where('stock','<',$replenishment_num)->field(['id','title as store_name','stock','price'])->page((int)$where['page'],(int)$where['limit'])->order('stock asc')->select(); + if(count($list)) $list=$list->toArray(); + $count=self::where('stock','<',$replenishment_num)->count(); + return ['count'=>$count,'data'=>$list]; + } + + /** + * 秒杀产品评价 + * @param array $where + * @return array + */ + public static function getNegativeList($where = array()){ + $replenishment_num = 3; + return []; + } + + /** + * 秒杀产品退货 + * @param array $where + * @return mixed + */ + public static function getBargainRefundList($where = array()){ + $model = StoreOrder::alias('a')->join('store_seckill b','b.id=a.seckill_id'); + $list = self::getModelTime($where,$model,'a.add_time')->where('a.refund_status','NEQ',0)->group('a.seckill_id')->order('count desc')->page((int)$where['page'],(int)$where['limit']) + ->field(['count(a.seckill_id) as count','b.title as store_name','sum(b.price) as sum_price'])->select(); + if(count($list)) $list=$list->toArray(); + return $list; + } + + /** + * @param $where + * @return array + */ + public static function systemPage($where){ + $model = new self; + $model = $model->alias('s'); +// $model = $model->join('StoreProduct p','p.id=s.product_id'); + if($where['status'] != '') $model = $model->where('s.status',$where['status']); + if($where['store_name'] != '') $model = $model->where('s.title|s.id','LIKE',"%$where[store_name]%"); + $model = $model->page(bcmul($where['page'],$where['limit'],0),$where['limit']); + $model = $model->order('s.id desc'); + $model = $model->where('s.is_del',0); + return self::page($model,function($item){ + $item['store_name'] = StoreProduct::where('id',$item['product_id'])->value('store_name'); + if($item['status']){ + if($item['start_time'] > time()) + $item['start_name'] = '活动未开始'; + else if($item['stop_time'] < time()) + $item['start_name'] = '活动已结束'; + else if($item['stop_time'] > time() && $item['start_time'] < time()) + $item['start_name'] = '正在进行中'; + }else $item['start_name'] = '关闭'; + + },$where,$where['limit']); + } + public static function SaveExcel($where){ + $model = new self; + if($where['status'] != '') $model = $model->where('status',$where['status']); + if($where['store_name'] != '') $model = $model->where('title|id','LIKE',"%$where[store_name]%"); + $list = $model->order('id desc')->where('is_del',0)->select(); + count($list) && $list=$list->toArray(); + $excel=[]; + foreach ($list as $item){ + $item['store_name'] = StoreProduct::where('id',$item['product_id'])->value('store_name'); + if($item['status']){ + if($item['start_time'] > time()) + $item['start_name'] = '活动未开始'; + else if($item['stop_time'] < time()) + $item['start_name'] = '活动已结束'; + else if($item['stop_time'] > time() && $item['start_time'] < time()) + $item['start_name'] = '正在进行中'; + }else $item['start_name'] = '关闭'; + $excel[]=[ + $item['id'], + $item['title'], + $item['info'], + $item['ot_price'], + $item['price'], + $item['stock'], + $item['start_name'], + $item['stop_time'], + $item['stop_time'], + $item['status']? '开启':'关闭', + ]; + } + PHPExcelService::setExcelHeader(['编号','活动标题','活动简介','原价','秒杀价','库存','秒杀状态','结束时间','状态']) + ->setExcelTile('秒杀产品导出',' ',' 生成时间:'.date('Y-m-d H:i:s',time())) + ->setExcelContent($excel) + ->ExcelSave(); + } + + /** + * 获取秒杀产品id + * @return array + */ + public static function getSeckillIdAll(){ + return self::where('is_del',0)->column('id','id'); + } + + /** + * 获取秒杀的所有产品 + * @return int|string + */ + public static function getSeckillCount(){ + return self::where('is_del',0)->count(); + } +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreSeckillAttr.php b/application/admin/model/ump/StoreSeckillAttr.php new file mode 100644 index 00000000..6f8784de --- /dev/null +++ b/application/admin/model/ump/StoreSeckillAttr.php @@ -0,0 +1,114 @@ + + * @day: 2017/12/08 + */ + +namespace app\admin\model\ump; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreSeckillAttr extends ModelBasic +{ + use ModelTrait; + + protected function setAttrValuesAttr($value) + { + return is_array($value) ? implode(',',$value) : $value; + } + + protected function getAttrValuesAttr($value) + { + return explode(',',$value); + } + + + public static function createProductAttr($attrList,$valueList,$productId) + { + $result = ['attr'=>$attrList,'value'=>$valueList]; + $attrValueList = []; + $attrNameList = []; + foreach ($attrList as $index=>$attr){ + if(!isset($attr['value'])) return self::setErrorInfo('请输入规则名称!'); + $attr['value'] = trim($attr['value']); + if(!isset($attr['value'])) return self::setErrorInfo('请输入规则名称!!'); + if(!isset($attr['detail']) || !count($attr['detail'])) return self::setErrorInfo('请输入属性名称!'); + foreach ($attr['detail'] as $k=>$attrValue){ + $attrValue = trim($attrValue); + if(empty($attrValue)) return self::setErrorInfo('请输入正确的属性'); + $attr['detail'][$k] = $attrValue; + $attrValueList[] = $attrValue; + $attr['detail'][$k] = $attrValue; + } + $attrNameList[] = $attr['value']; + $attrList[$index] = $attr; + } + $attrCount = count($attrList); + foreach ($valueList as $index=>$value){ + if(!isset($value['detail']) || count($value['detail']) != $attrCount) return self::setErrorInfo('请填写正确的商品信息'); + if(!isset($value['price']) || !is_numeric($value['price']) || floatval($value['price']) != $value['price']) + return self::setErrorInfo('请填写正确的商品价格'); + if(!isset($value['sales']) || !is_numeric($value['sales']) || intval($value['sales']) != $value['sales']) + return self::setErrorInfo('请填写正确的商品库存'); + if(!isset($value['pic']) || empty($value['pic'])) + return self::setErrorInfo('请上传商品图片'); + foreach ($value['detail'] as $attrName=>$attrValue){ + $attrName = trim($attrName); + $attrValue = trim($attrValue); + if(!in_array($attrName,$attrNameList,true)) return self::setErrorInfo($attrName.'规则不存在'); + if(!in_array($attrValue,$attrValueList,true)) return self::setErrorInfo($attrName.'属性不存在'); + if(empty($attrName)) return self::setErrorInfo('请输入正确的属性'); + $value['detail'][$attrName] = $attrValue; + } + $valueList[$index] = $value; + } + $attrGroup = []; + $valueGroup = []; + foreach ($attrList as $k=>$value){ + $attrGroup[] = [ + 'product_id'=>$productId, + 'attr_name'=>$value['value'], + 'attr_values'=>$value['detail'] + ]; + } + foreach ($valueList as $k=>$value){ + ksort($value['detail'],SORT_STRING); + $suk = implode(',',$value['detail']); + $valueGroup[$suk] = [ + 'product_id'=>$productId, + 'suk'=>$suk, + 'price'=>$value['price'], + 'stock'=>$value['sales'], + 'image'=>$value['pic'] + ]; + } + if(!count($attrGroup) || !count($valueGroup)) return self::setErrorInfo('请设置至少一个属性!'); + $attrModel = new self; + $attrValueModel = new StoreSeckillAttrValue; + self::beginTrans(); + if(!self::clearProductAttr($productId)) return false; + $res = false !== $attrModel->saveAll($attrGroup) + && false !== $attrValueModel->saveAll($valueGroup) + && false !== StoreSeckillAttrResult::setResult($result,$productId); + self::checkTrans($res); + if($res) + return true; + else + return self::setErrorInfo('编辑商品属性失败!'); + } + + public static function clearProductAttr($productId) + { + if (empty($productId) && $productId != 0) return self::setErrorInfo('商品不存在!'); + $res = false !== self::where('product_id',$productId)->delete() + && false !== StoreSeckillAttrValue::clearProductAttrValue($productId); + if(!$res) + return self::setErrorInfo('编辑属性失败,清除旧属性失败!'); + else + return true; + } + +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreSeckillAttrResult.php b/application/admin/model/ump/StoreSeckillAttrResult.php new file mode 100644 index 00000000..711351ba --- /dev/null +++ b/application/admin/model/ump/StoreSeckillAttrResult.php @@ -0,0 +1,47 @@ + + * @day: 2017/12/09 + */ + +namespace app\admin\model\ump; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreSeckillAttrResult extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['change_time']; + + protected static function setChangeTimeAttr($value) + { + return time(); + } + + protected static function setResultAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + public static function setResult($result,$product_id) + { + $result = self::setResultAttr($result); + $change_time = self::setChangeTimeAttr(0); + return self::insert(compact('product_id','result','change_time'),true); + } + + public static function getResult($productId) + { + return json_decode(self::where('product_id',$productId)->value('result'),true) ?: []; + } + + public static function clearResult($productId) + { + return self::del($productId); + } + +} \ No newline at end of file diff --git a/application/admin/model/ump/StoreSeckillAttrValue.php b/application/admin/model/ump/StoreSeckillAttrValue.php new file mode 100644 index 00000000..46eee61e --- /dev/null +++ b/application/admin/model/ump/StoreSeckillAttrValue.php @@ -0,0 +1,49 @@ + + * @day: 2017/12/08 + */ + +namespace app\admin\model\ump; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreSeckillAttrValue extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['unique']; + + protected function setSukAttr($value) + { + return is_array($value) ? implode(',',$value) : $value; + } + + protected function setUniqueAttr($value,$data) + { + if(is_array($data['suk'])) $data['suk'] = $this->setSukAttr($data['suk']); + return self::uniqueId($data['product_id'].$data['suk'].uniqid(true)); + } + + public static function decProductAttrStock($productId,$unique,$num) + { + return false !== self::where('product_id',$productId)->where('unique',$unique) + ->dec('stock',$num)->inc('sales',$num)->update(); + } + + + public static function uniqueId($key) + { + return substr(md5($key),12,8); + } + + public static function clearProductAttrValue($productId) + { + return self::where('product_id',$productId)->delete(); + } + + +} \ No newline at end of file diff --git a/application/admin/model/user/User.php b/application/admin/model/user/User.php new file mode 100644 index 00000000..24df1216 --- /dev/null +++ b/application/admin/model/user/User.php @@ -0,0 +1 @@ + * @day: 2017/11/11 */ namespace app\admin\model\user; use app\admin\model\order\StoreOrder; use traits\ModelTrait; use app\wap\model\user\UserBill; use basic\ModelBasic; use app\admin\model\wechat\WechatUser; use app\admin\model\store\StoreCouponUser; use app\admin\model\user\UserExtract; /** * 用户管理 model * Class User * @package app\admin\model\user */ class User extends ModelBasic { use ModelTrait; /** * @param $where * @return array */ public static function systemPage($where){ $model = new self; if($where['status'] != '') $model = $model->where('status',$where['status']); if($where['is_promoter'] != '') $model = $model->where('is_promoter',$where['is_promoter']); if(isset($where['user_type']) && $where['user_type'] != '') $model = $model->where('user_type',$where['user_type']); if($where['nickname'] != '') $model = $model->where('nickname|uid','like',"%$where[nickname]%"); $model = $model->order('uid desc'); return self::page($model,function ($item){ if($item['spread_uid']){ $item['spread_uid_nickname'] = self::where('uid',$item['spread_uid'])->value('nickname'); }else{ $item['spread_uid_nickname'] = '无'; } },$where); } /** * 异步获取当前用户 信息 * @param $where * @return array */ public static function getUserList($where){ if($where['order']!=''){ $model=self::order(self::setOrder($where['order'])); }else{ $model=self::order('u.uid desc'); } if($where['user_time_type'] == 'visitno'){ list($startTime, $endTime) = explode(' - ', $where['user_time']); $model = $model->where('u.last_time', ['>', strtotime($endTime)], ['<', strtotime($startTime)],'or'); } if($where['user_time_type'] == 'visit'){ list($startTime, $endTime) = explode(' - ', $where['user_time']); $model = $model->where('u.last_time', '>', strtotime($startTime)); $model = $model->where('u.last_time', '<', strtotime($endTime)); } if($where['user_time_type'] == 'add_time'){ list($startTime, $endTime) = explode(' - ', $where['user_time']); $model = $model->where('u.add_time', '>', strtotime($startTime)); $model = $model->where('u.add_time', '<', strtotime($endTime)); } if($where['pay_count'] !== '') { if($where['pay_count'] == '-1') $model = $model->where('pay_count',0); else $model = $model->where('pay_count','>',$where['pay_count']); } if($where['country'] == 'domestic') $model = $model->where('w.country','EQ','中国'); else if($where['country'] == 'abroad') $model = $model->where('w.country','NEQ','中国'); // dump(self::setWherePage($model,$where,['w.province','w.city','u.status','u.is_promoter','u.user_type'],['u.nickname','u.uid'])); // dump($model); // dump($where); // exit(); $list = self::setWherePage($model,$where,['w.sex','w.province','w.city','u.status','u.is_promoter','u.user_type'],['u.nickname','u.uid']) ->alias('u') ->join('WechatUser w','u.uid=w.uid') ->field('u.*,w.country,w.province,w.city,w.sex,w.unionid,w.openid,w.routine_openid,w.groupid,w.tagid_list,w.subscribe,w.subscribe_time') ->page((int)$where['page'],(int)$where['limit']) ->select() ->each(function ($item){ $item['add_time']=date('Y-m-d H:i:s',$item['add_time']); if($item['last_time']) $item['last_time'] = date('Y-m-d H:i:s',$item['last_time']);//最近一次访问日期 else $item['last_time'] = '无访问';//最近一次访问日期 // self::edit(['pay_count'=>StoreOrder::getUserCountPay($item['uid'])],$item['uid']); $item['extract_count_price'] = UserExtract::getUserCountPrice($item['uid']);//累计提现 if($item['spread_uid']){ $item['spread_uid_nickname'] = self::where('uid',$item['spread_uid'])->value('nickname').'/'.$item['spread_uid']; }else{ $item['spread_uid_nickname'] = '无'; } if($item['user_type']=='wechat'){ $item['user_type']='微信类型'; }else if($item['user_type']=='routine'){ $item['user_type']='小程序类型'; }else $item['user_type']='其他类型'; if($item['sex'] == 1){ $item['sex']='男'; }else if($item['sex'] == 2){ $item['sex']='女'; }else $item['sex']='保密'; })->toArray(); // $model=self::getModelTime($where,$model,$where['time_visit'],'data',' - '); if($where['user_time_type'] == 'visitno'){ list($startTime, $endTime) = explode(' - ', $where['user_time']); $model = $model->where('u.last_time', ['>', strtotime($endTime)], ['<', strtotime($startTime)],'or'); } if($where['user_time_type'] == 'visit'){ list($startTime, $endTime) = explode(' - ', $where['user_time']); $model = $model->where('u.last_time', '>', strtotime($startTime)); $model = $model->where('u.last_time', '<', strtotime($endTime)); } if($where['user_time_type'] == 'add_time'){ list($startTime, $endTime) = explode(' - ', $where['user_time']); $model = $model->where('u.add_time', '>', strtotime($startTime)); $model = $model->where('u.add_time', '<', strtotime($endTime)); } if($where['pay_count'] !== '') $model = $model->where('pay_count','>',$where['pay_count']); if($where['country'] == 'domestic') $model = $model->where('w.country','EQ','中国'); else if($where['country'] == 'abroad') $model = $model->where('w.country','NEQ','中国'); $count=self::setWherePage($model,$where,['w.sex','w.province','w.city','u.status','u.is_promoter','u.user_type'],['u.nickname','u.uid'])->alias('u')->join('WechatUser w','u.uid=w.uid')->count(); return ['count'=>$count,'data'=>$list]; } /** * 修改用户状态 * @param $uids 用户uid * @param $status 修改状态 * @return array */ public static function destrSyatus($uids,$status){ if(empty($uids) && !is_array($uids)) return false; if($status=='') return false; self::beginTrans(); try{ $res=self::where('uid','in',$uids)->update(['status'=>$status]); self::checkTrans($res); return true; }catch (\Exception $e){ self::rollbackTrans(); return Json::fail($e->getMessage()); } } /* * 获取某季度,某年某年后的时间戳 * * self::getMonth('n',1) 获取当前季度的上个季度的时间戳 * self::getMonth('n') 获取当前季度的时间戳 */ public static function getMonth($time='',$ceil=0){ if(empty($time)){ $firstday = date("Y-m-01",time()); $lastday = date("Y-m-d",strtotime("$firstday +1 month -1 day")); }else if($time=='n'){ if($ceil!=0) $season = ceil(date('n') /3)-$ceil; else $season = ceil(date('n') /3); $firstday=date('Y-m-01',mktime(0,0,0,($season - 1) *3 +1,1,date('Y'))); $lastday=date('Y-m-t',mktime(0,0,0,$season * 3,1,date('Y'))); }else if($time=='y'){ $firstday=date('Y-01-01'); $lastday=date('Y-12-31'); }else if($time=='h'){ $firstday = date('Y-m-d', strtotime('this week +'.$ceil.' day')) . ' 00:00:00'; $lastday = date('Y-m-d', strtotime('this week +'.($ceil+1).' day')) . ' 23:59:59'; } return array($firstday,$lastday); } public static function getcount(){ return self::count(); } /* *获取用户某个时间段的消费信息 * * reutrn Array || number */ public static function consume($where,$status='',$keep=''){ $model = new self; $user_id=[]; if(is_array($where)){ if($where['is_promoter']!='') $model=$model->where('is_promoter',$where['is_promoter']); if($where['status']!='') $model=$model->where('status',$where['status']); switch ($where['date']){ case null:case 'today':case 'week':case 'year': if($where['date']==null){ $where['date']='month'; } if($keep){ $model=$model->whereTime('add_time',$where['date'])->whereTime('last_time',$where['date']); }else{ $model=$model->whereTime('add_time',$where['date']); } break; case 'quarter': $quarter=self::getMonth('n'); $startTime=strtotime($quarter[0]); $endTime=strtotime($quarter[1]); if($keep){ $model = $model->where('add_time','>',$startTime)->where('add_time','<',$endTime)->where('last_time','>',$startTime)->where('last_time','<',$endTime); }else{ $model = $model->where('add_time','>',$startTime)->where('add_time','<',$endTime); } break; default: //自定义时间 if(strstr($where['date'],'-')!==FALSE){ list($startTime,$endTime)=explode('-',$where['date']); $model = $model->where('add_time','>',strtotime($startTime))->where('add_time','<',strtotime($endTime)); }else{ $model=$model->whereTime('add_time','month'); } break; } }else{ if(is_array($status)){ $model=$model->where('add_time','>',$status[0])->where('add_time','<',$status[1]); } } if($keep===true){ return $model->count(); } if($status==='default'){ return $model->group('from_unixtime(add_time,\'%Y-%m-%d\')')->field('count(uid) num,from_unixtime(add_time,\'%Y-%m-%d\') add_time,uid')->select()->toArray(); } if($status==='grouping'){ return $model->group('user_type')->field('user_type')->select()->toArray(); } $uid=$model->field('uid')->select()->toArray(); foreach ($uid as $val){ $user_id[]=$val['uid']; } if(empty($user_id)){ $user_id=[0]; } if($status==='xiaofei'){ $list=UserBill::where('uid','in',$user_id) ->group('type') ->field('sum(number) as top_number,title') ->select() ->toArray(); $series=[ 'name'=>isset($list[0]['title'])?$list[0]['title']:'', 'type'=>'pie', 'radius'=> ['40%', '50%'], 'data'=>[] ]; foreach($list as $key=>$val){ $series['data'][$key]['value']=$val['top_number']; $series['data'][$key]['name']=$val['title']; } return $series; }else if($status==='form'){ $list=WechatUser::where('uid','in',$user_id)->group('city')->field('count(city) as top_city,city')->limit(0,10)->select()->toArray(); $count=self::getcount(); $option=[ 'legend_date'=>[], 'series_date'=>[] ]; foreach($list as $key=>$val){ $num=$count!=0?(bcdiv($val['top_city'],$count,2))*100:0; $t=['name'=>$num.'% '.(empty($val['city'])?'未知':$val['city']),'icon'=>'circle']; $option['legend_date'][$key]=$t; $option['series_date'][$key]=['value'=>$num,'name'=>$t['name']]; } return $option; }else{ $number=UserBill::where('uid','in',$user_id)->where('type','pay_product')->sum('number'); return $number; } } /* * 获取 用户某个时间段的钱数或者TOP20排行 * * return Array || number */ public static function getUserSpend($date,$status=''){ $model=new self(); $model=$model->alias('A'); switch ($date){ case null:case 'today':case 'week':case 'year': if($date==null) $date='month'; $model=$model->whereTime('A.add_time',$date); break; case 'quarter': list($startTime,$endTime)=User::getMonth('n'); $model = $model->where('A.add_time','>',strtotime($startTime)); $model = $model->where('A.add_time','<',strtotime($endTime)); break; default: list($startTime,$endTime)=explode('-',$date); $model = $model->where('A.add_time','>',strtotime($startTime)); $model = $model->where('A.add_time','<',strtotime($endTime)); break; } if($status===true){ return $model->join('user_bill B','B.uid=A.uid')->where('B.type','pay_product')->where('B.pm',0)->sum('B.number'); } $list=$model->join('user_bill B','B.uid=A.uid') ->where('B.type','pay_product') ->where('B.pm',0) ->field('sum(B.number) as totel_number,A.nickname,A.avatar,A.now_money,A.uid,A.add_time') ->order('totel_number desc') ->limit(0,20) ->select() ->toArray(); if(!isset($list[0]['totel_number'])){ $list=[]; } return $list; } /* * 获取 相对于上月或者其他的数据 * * return Array */ public static function getPostNumber($date,$status=false,$field='A.add_time',$t='消费'){ $model=new self(); if(!$status) $model=$model->alias('A'); switch ($date){ case null:case 'today':case 'week':case 'year': if($date==null) { $date='last month'; $title='相比上月用户'.$t.'增长'; } if($date=='today') { $date='yesterday'; $title='相比昨天用户'.$t.'增长'; } if($date=='week') { $date='last week'; $title='相比上周用户'.$t.'增长'; } if($date=='year') { $date='last year'; $title='相比去年用户'.$t.'增长'; } $model=$model->whereTime($field,$date); break; case 'quarter': $title='相比上季度用户'.$t.'增长'; list($startTime,$endTime)=User::getMonth('n',1); $model = $model->where($field,'>',$startTime); $model = $model->where($field,'<',$endTime); break; default: list($startTime,$endTime)=explode('-',$date); $title='相比'.$startTime.'-'.$endTime.'时间段用户'.$t.'增长'; $Time=strtotime($endTime)-strtotime($startTime); $model = $model->where($field,'>',strtotime($startTime)+$Time); $model = $model->where($field,'<',strtotime($endTime)+$Time); break; } if($status){ return [$model->count(),$title]; } $number=$model->join('user_bill B','B.uid=A.uid')->where('B.type','pay_product')->where('B.pm',0)->sum('B.number'); return [$number,$title]; } //获取用户新增,头部信息 public static function getBadgeList($where){ $user_count=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])->count(); $user_count_old=self::getOldDate($where)->count(); $fenxiao=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status'])->where('spread_uid','<>',0)->count(); $fenxiao_count=self::getOldDate($where)->where('spread_uid','neq',0)->count(); $newFemxiao_count=bcsub($fenxiao,$fenxiao_count,0); $order_count=bcsub($user_count,$user_count_old,0); return [ [ 'name'=>'会员人数', 'field'=>'个', 'count'=>$user_count, 'content'=>'会员总人数', 'background_color'=>'layui-bg-blue', 'sum'=>self::count(), 'class'=>'fa fa-bar-chart', ], [ 'name'=>'会员增长', 'field'=>'个', 'count'=>$order_count, 'content'=>'会员增长率', 'background_color'=>'layui-bg-cyan', 'sum'=>$user_count_old ? bcdiv($order_count,$user_count_old,2)*100:0, 'class'=>'fa fa-line-chart', ], [ 'name'=>'分销人数', 'field'=>'个', 'count'=>$fenxiao, 'content'=>'分销总人数', 'background_color'=>'layui-bg-green', 'sum'=>self::where('spread_uid','neq',0)->count(), 'class'=>'fa fa-bar-chart', ], [ 'name'=>'分销增长', 'field'=>'个', 'count'=>$newFemxiao_count, 'content'=>'分销总人数', 'background_color'=>'layui-bg-orange', 'sum'=>$fenxiao_count ? bcdiv($newFemxiao_count,$fenxiao_count,2)*100:0, 'class'=>'fa fa-cube', ], ]; } /* * 获取会员增长曲线图和分布图 * $where 查询条件 * $limit 显示条数,是否有滚动条 */ public static function getUserChartList($where,$limit=20){ $list=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter','status']) ->where('add_time','neq',0) ->field(['FROM_UNIXTIME(add_time,"%Y-%m-%d") as _add_time','count(uid) as num']) ->order('_add_time asc') ->group('_add_time') ->select(); count($list) && $list=$list->toArray(); $seriesdata=[]; $xdata=[]; $Zoom=''; foreach ($list as $item){ $seriesdata[]=$item['num']; $xdata[]=$item['_add_time']; } (count($xdata) > $limit) && $Zoom=$xdata[$limit-5]; //多次购物会员数量饼状图 $count=self::setWherePage(self::getModelTime($where,new self),$where,['is_promoter'])->count(); $user_count=self::setWherePage(self::getModelTime($where,self::alias('a')->join('store_order r','r.uid=a.uid'),'a.add_time'),$where,['is_promoter']) ->where('r.paid',1)->count('a.uid'); $shop_xdata=['多次购买数量占比','无购买数量占比']; $shop_data=[]; $count >0 && $shop_data=[ [ 'value'=>bcdiv($user_count,$count,2)*100, 'name'=>$shop_xdata[0], 'itemStyle'=>[ 'color'=>'#D789FF', ] ], [ 'value'=>bcdiv($count-$user_count,$count,2)*100, 'name'=>$shop_xdata[1], 'itemStyle'=>[ 'color'=>'#7EF0FB', ] ] ]; return compact('shop_data','shop_xdata','fenbu_data','fenbu_xdata','seriesdata','xdata','Zoom'); } //获取$date的前一天或者其他的时间段 public static function getOldDate($where,$moedls=null){ $model=$moedls ===null ? self::setWherePage(new self(),$where,['is_promoter','status']) :$moedls; switch ($where['data']){ case 'today': $model=$model->whereTime('add_time','yesterday'); break; case 'week': $model=$model->whereTime('add_time','last week'); break; case 'month': $model=$model->whereTime('add_time','last month'); break; case 'year': $model=$model->whereTime('add_time','last year'); break; case 'quarter': $time=self::getMonth('n',1); $model=$model->where('add_time','between',$time); break; } return $model; } //获取用户属性和性别分布图 public static function getEchartsData($where){ $model=self::alias('a'); $data=self::getModelTime($where,$model,'a.add_time') ->join('wechat_user r','r.uid=a.uid') ->group('r.province') ->field('count(r.province) as count,province') ->order('count desc') ->limit(15) ->select(); if(count($data)) $data=$data->toArray(); $legdata=[]; $dataList=[]; foreach ($data as $value){ $value['province']=='' && $value['province']='未知省份'; $legdata[]=$value['province']; $dataList[]=$value['count']; } $model=self::alias('a'); $sex=self::getModelTime($where,$model,'a.add_time') ->join('wechat_user r','r.uid=a.uid') ->group('r.sex') ->field('count(r.uid) as count,sex') ->order('count desc') ->select(); if(count($sex)) $sex=$sex->toArray(); $sexlegdata=['男','女','未知']; $sexcount=self::getModelTime($where,new self())->count(); $sexList=[]; $color=['#FB7773','#81BCFE','#91F3FE']; foreach ($sex as $key=>$item){ if($item['sex']==1){ $item_date['name']='男'; }else if($item['sex']==2){ $item_date['name']='女'; }else{ $item_date['name']='未知性别'; } $item_date['value']=bcdiv($item['count'],$sexcount,2)*100; $item_date['itemStyle']['color']=$color[$key]; $sexList[]=$item_date; } return compact('sexList','sexlegdata','legdata','dataList'); } //获取佣金记录列表 public static function getCommissionList($where){ $list=self::setCommissionWhere($where) ->page((int)$where['page'],(int)$where['limit']) ->select(); count($list) && $list=$list->toArray(); foreach ($list as &$value){ $value['ex_price']=db('user_extract')->where(['uid'=>$value['uid']])->sum('extract_price'); $value['extract_price']=db('user_extract')->where(['uid'=>$value['uid'],'status'=>1])->sum('extract_price'); } $count=self::setCommissionWhere($where)->count(); return ['data'=>$list,'count'=>$count]; } //获取佣金记录列表的查询条件 public static function setCommissionWhere($where){ $models=self::setWherePage(self::alias('A'),$where,[],['A.nickname','A.uid']) ->join('user_bill B','B.uid=A.uid') ->group('A.uid') ->where(['B.category'=>'now_money','B.type'=>'brokerage']) ->field(['sum(B.number) as sum_number','A.nickname','A.uid','A.now_money']); if($where['order']==''){ $models=$models->order('sum_number desc'); }else{ $models=$models->order($where['order']==1 ? 'sum_number desc':'sum_number asc'); } if($where['price_max']!='' && $where['price_min']!=''){ $models=$models->where('now_money','between',[$where['price_max'],$where['price_min']]); } return $models; } //获取某人用户推广信息 public static function getUserinfo($uid){ $userinfo=self::where(['uid'=>$uid])->field(['nickname','spread_uid','now_money','add_time'])->find()->toArray(); $userinfo['number']=UserBill::where(['category'=>'now_money','type'=>'brokerage'])->sum('number'); $userinfo['spread_name']=$userinfo['spread_uid'] ? self::where(['uid'=>$userinfo['spread_uid']])->value('nickname') :''; return $userinfo; } //获取某用户的详细信息 public static function getUserDetailed($uid){ $key_field=['real_name','phone','province','city','district','detail','post_code']; $Address=($thisAddress=db('user_address')->where(['uid'=>$uid,'is_default'=>1])->field($key_field)->find()) ? $thisAddress : db('user_address')->where(['uid'=>$uid])->field($key_field)->find(); $UserInfo=self::get($uid); return [ ['col'=>12,'name'=>'默认收货地址','value'=>'邮编:'.$thisAddress['post_code'].' 收货人电话:'.$thisAddress['phone'].' 地址:'.$thisAddress['province'].' '.$thisAddress['city'].' '.$thisAddress['district'].' '.$thisAddress['detail']], // ['name'=>'微信OpenID','value'=>WechatUser::where(['uid'=>$uid])->value('openid'),'col'=>8], ['name'=>'手机号码','value'=>$UserInfo['phone']], // ['name'=>'ID','value'=>$uid], ['name'=>'姓名','value'=>''], ['name'=>'微信昵称','value'=>$UserInfo['nickname']], ['name'=>'邮箱','value'=>''], ['name'=>'生日','value'=>''], ['name'=>'积分','value'=>UserBill::where(['category'=>'integral','uid'=>$uid])->where('type','in',['sign','system_add'])->sum('number')], ['name'=>'上级推广人','value'=>$UserInfo['spread_uid'] ? self::where(['uid'=>$UserInfo['spread_uid']])->value('nickname'):''], ['name'=>'账户余额','value'=>$UserInfo['now_money']], ['name'=>'佣金总收入','value'=>UserBill::where(['category'=>'now_money','type'=>'brokerage','uid'=>$uid])->sum('number')], ['name'=>'提现总金额','value'=>db('user_extract')->where(['uid'=>$uid,'status'=>1])->sum('extract_price')], ]; } //获取某用户的订单个数,消费明细 public static function getHeaderList($uid){ return [ [ 'title'=>'总计订单', 'value'=>StoreOrder::where(['uid'=>$uid])->count(), 'key'=>'笔', 'class'=>'', ], [ 'title'=>'总消费金额', 'value'=>StoreOrder::where(['uid'=>$uid,'paid'=>1])->sum('total_price'), 'key'=>'元', 'class'=>'', ], [ 'title'=>'本月订单', 'value'=>StoreOrder::where(['uid'=>$uid])->whereTime('add_time','month')->count(), 'key'=>'笔', 'class'=>'', ], [ 'title'=>'本月消费金额', 'value'=>StoreOrder::where(['uid'=>$uid])->whereTime('add_time','month')->sum('total_price'), 'key'=>'元', 'class'=>'', ] ]; } /* * 获取 会员 订单个数,积分明细,优惠劵明细 * * $uid 用户id; * * return array */ public static function getCountInfo($uid){ $order_count=StoreOrder::where(['uid'=>$uid])->count(); $integral_count=UserBill::where(['uid'=>$uid,'category'=>'integral'])->where('type','in',['deduction','system_add'])->count(); $sign_count=UserBill::where(['uid'=>$uid,'category'=>'integral','type'=>'sign'])->count(); $balanceChang_count=UserBill::where(['uid'=>$uid,'category'=>'now_money']) ->where('type','in',['system_add','pay_product','extract','pay_product_refund','system_sub']) ->count(); $coupon_count=StoreCouponUser::where(['uid'=>$uid])->count(); return compact('order_count','integral_count','sign_count','balanceChang_count','coupon_count'); } /* * 获取 会员业务的 * 购物会员统计 * 会员访问量 * * 曲线图 * * $where 查询条件 * * return array */ public static function getUserBusinessChart($where,$limit=20){ //获取购物会员人数趋势图 $list=self::getModelTime($where,self::where('a.status',1)->alias('a')->join('store_order r','r.uid=a.uid'),'a.add_time') ->where(['r.paid'=>1,'a.is_promoter'=>0]) ->where('a.add_time','neq',0) ->field(['FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as _add_time','count(r.uid) as count_user']) ->group('_add_time') ->order('_add_time asc') ->select(); count($list) && $list=$list->toArray(); $seriesdata=[]; $xdata=[]; $zoom=''; foreach ($list as $item){ $seriesdata[]=$item['count_user']; $xdata[]=$item['_add_time']; } count($xdata) > $limit && $zoom=$xdata[$limit-5]; //会员访问量 $visit=self::getModelTime($where,self::alias('a')->join('store_visit t','t.uid=a.uid'),'t.add_time') ->where('a.is_promoter',0) ->field(['FROM_UNIXTIME(t.add_time,"%Y-%m-%d") as _add_time','count(t.uid) as count_user']) ->group('_add_time') ->order('_add_time asc') ->select(); count($visit) && $visit=$visit->toArray(); $visit_data=[]; $visit_xdata=[]; $visit_zoom=''; foreach ($visit as $item){ $visit_data[]=$item['count_user']; $visit_xdata[]=$item['_add_time']; } count($visit_xdata) > $limit && $visit_zoom=$visit_xdata[$limit-5]; //多次购物会员数量饼状图 $count=self::getModelTime($where,self::where('is_promoter',0))->count(); $user_count=self::getModelTime($where,self::alias('a')->join('store_order r','r.uid=a.uid'),'a.add_time') ->where('a.is_promoter',0) ->where('r.paid',1) ->group('a.uid') ->count(); $shop_xdata=['多次购买数量占比','无购买数量占比']; $shop_data=[]; $count >0 && $shop_data=[ [ 'value'=>bcdiv($user_count,$count,2)*100, 'name'=>$shop_xdata[0], 'itemStyle'=>[ 'color'=>'#D789FF', ] ], [ 'value'=>bcdiv($count-$user_count,$count,2)*100, 'name'=>$shop_xdata[1], 'itemStyle'=>[ 'color'=>'#7EF0FB', ] ] ]; return compact('seriesdata','xdata','zoom','visit_data','visit_xdata','visit_zoom','shop_data','shop_xdata'); } /* * 获取用户 * 积分排行 * 会员余额排行榜 * 分销商佣金总额排行榜 * 购物笔数排行榜 * 购物金额排行榜 * 分销商佣金提现排行榜 * 上月消费排行榜 * $limit 查询多少条 * return array */ public static function getUserTop10List($limit=10,$is_promoter=0){ //积分排行 $integral=self::where('status',1) ->where('is_promoter',$is_promoter) ->order('integral desc') ->field(['nickname','phone','integral','FROM_UNIXTIME(add_time,"%Y-%m-%d") as add_time']) ->limit($limit) ->select(); count($integral) && $integral=$integral->toArray(); //会员余额排行榜 $now_money=self::where('status',1) ->where('is_promoter',$is_promoter) ->order('now_money desc') ->field(['nickname','phone','now_money','FROM_UNIXTIME(add_time,"%Y-%m-%d") as add_time']) ->limit($limit) ->select(); count($now_money) && $now_money=$now_money->toArray(); //购物笔数排行榜 $shopcount=self::alias('a') ->join('store_order r','r.uid=a.uid') ->where(['r.paid'=>1,'a.is_promoter'=>$is_promoter]) ->group('r.uid') ->field(['a.nickname','a.phone','count(r.uid) as sum_count','FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time']) ->order('sum_count desc') ->limit($limit) ->select(); count($shopcount) && $shopcount=$shopcount->toArray(); //购物金额排行榜 $order=self::alias('a') ->join('store_order r','r.uid=a.uid') ->where(['r.paid'=>1,'a.is_promoter'=>$is_promoter]) ->group('r.uid') ->field(['a.nickname','a.phone','sum(r.pay_price) as sum_price','FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time','r.uid']) ->order('sum_price desc') ->limit($limit) ->select(); count($order) && $order=$order->toArray(); //上月消费排行 $lastorder=self::alias('a') ->join('store_order r','r.uid=a.uid') ->where(['r.paid'=>1,'a.is_promoter'=>$is_promoter]) ->whereTime('r.pay_time','last month') ->group('r.uid') ->field(['a.nickname','a.phone','sum(r.pay_price) as sum_price','FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time','r.uid']) ->order('sum_price desc') ->limit($limit) ->select(); return compact('integral','now_money','shopcount','order','lastorder'); } /* * 获取 会员业务 * 会员总余额 会员总积分 * $where 查询条件 * * return array */ public static function getUserBusinesHeade($where){ return [ [ 'name'=>'会员总余额', 'field'=>'元', 'count'=>self::getModelTime($where,self::where('status',1))->sum('now_money'), 'background_color'=>'layui-bg-cyan', 'col'=>6, ], [ 'name'=>'会员总积分', 'field'=>'分', 'count'=>self::getModelTime($where,self::where('status',1))->sum('integral'), 'background_color'=>'layui-bg-cyan', 'col'=>6 ] ]; } /* * 分销会员头部信息查询获取 * * 分销商总佣金余额 * 分销商总提现佣金 * 本月分销商业务佣金 * 本月分销商佣金提现金额 * 上月分销商业务佣金 * 上月分销商佣金提现金额 * $where array 时间条件 * * return array */ public static function getDistributionBadgeList($where){ return [ [ 'name'=>'分销商总佣金', 'field'=>'元', 'count'=>self::getModelTime($where,UserBill::where('category','now_money')->where('type','brokerage'))->where('uid','in',function($query){ $query->name('user')->where('status',1)->where('is_promoter',1)->whereOr('spread_uid','neq',0)->field('uid'); })->sum('number'), 'background_color'=>'layui-bg-cyan', 'col'=>3, ], [ 'name'=>'分销商总佣金余额', 'field'=>'元', 'count'=>self::getModelTime($where,self::where('status',1)->where('is_promoter',1))->sum('now_money'), 'background_color'=>'layui-bg-cyan', 'col'=>3, ], [ 'name'=>'分销商总提现佣金', 'field'=>'元', 'count'=>self::getModelTime($where,UserExtract::where('status',1))->sum('extract_price'), 'background_color'=>'layui-bg-cyan', 'col'=>3, ], [ 'name'=>'本月分销商业务佣金', 'field'=>'元', 'count'=>self::getModelTime(['data'=>'month'],UserBill::where('category','now_money')->where('type','brokerage')) ->where('uid','in',function ($query){ $query->name('user')->where('status',1)->where('is_promoter',1)->whereOr('spread_uid','neq',0)->field('uid'); })->sum('number'), 'background_color'=>'layui-bg-cyan', 'col'=>3, ], [ 'name'=>'本月分销商佣金提现金额', 'field'=>'元', 'count'=>self::getModelTime(['data'=>'month'],UserExtract::where('status',1)) ->where('uid','in',function ($query){ $query->name('user')->where('status',1)->where('is_promoter',1)->field('uid'); })->sum('extract_price'), 'background_color'=>'layui-bg-cyan', 'col'=>4, ], [ 'name'=>'上月分销商业务佣金', 'field'=>'元', 'count'=>self::getOldDate(['data'=>'year'],UserBill::where('category','now_money')->where('uid','in',function ($query){ $query->name('user')->where('status',1)->where('is_promoter',1)->whereOr('spread_uid','neq',0)->field('uid'); })->where('type','brokerage'))->sum('number'), 'background_color'=>'layui-bg-cyan', 'col'=>4, ], [ 'name'=>'上月分销商佣金提现金额', 'field'=>'元', 'count'=>self::getOldDate(['data'=>'year'],UserBill::where('category','now_money')->where('uid','in',function ($query){ $query->name('user')->where('status',1)->where('is_promoter',1)->whereOr('spread_uid','neq',0)->field('uid'); })->where('type','brokerage'))->sum('number'), 'background_color'=>'layui-bg-cyan', 'col'=>4, ], ]; } /* * 分销会员 * 分销数量 饼状图 * 分销商会员访问量 曲线 * 获取购物会员人数趋势图 曲线 * 多次购物分销会员数量 饼状图 * $where array 条件 * $limit int n条数据后出拖动条 * return array */ public static function getUserDistributionChart($where,$limit=20){ //分销数量 $fenbu_user=self::getModelTime($where,new self)->field(['count(uid) as num'])->group('is_promoter')->select(); count($fenbu_user) && $fenbu_user=$fenbu_user->toArray(); $sum_user=0; $fenbu_data=[]; $fenbu_xdata=['分销商','非分销商']; $color=['#81BCFE','#91F3FE']; foreach($fenbu_user as $item){ $sum_user+=$item['num']; } foreach ($fenbu_user as $key=>$item){ $value['value']=bcdiv($item['num'],$sum_user,2)*100; $value['name']=isset($fenbu_xdata[$key]) ?$fenbu_xdata[$key].' %'.$value['value'] :''; $value['itemStyle']['color']=$color[$key]; $fenbu_data[]=$value; } //分销商会员访问量 $visit=self::getModelTime($where,self::alias('a')->join('store_visit t','t.uid=a.uid'),'t.add_time') ->where('a.is_promoter',1) ->field(['FROM_UNIXTIME(t.add_time,"%Y-%m-%d") as _add_time','count(t.uid) as count_user']) ->group('_add_time') ->order('_add_time asc') ->select(); count($visit) && $visit=$visit->toArray(); $visit_data=[]; $visit_xdata=[]; $visit_zoom=''; foreach ($visit as $item){ $visit_data[]=$item['count_user']; $visit_xdata[]=$item['_add_time']; } count($visit_xdata) > $limit && $visit_zoom=$visit_xdata[$limit-5]; //获取购物会员人数趋势图 $list=self::getModelTime($where,self::where('a.status',1)->alias('a')->join('store_order r','r.uid=a.uid'),'a.add_time') ->where(['r.paid'=>1,'a.is_promoter'=>1]) ->where('a.add_time','neq',0) ->field(['FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as _add_time','count(r.uid) as count_user']) ->group('_add_time') ->order('_add_time asc') ->select(); count($list) && $list=$list->toArray(); $seriesdata=[]; $xdata=[]; $zoom=''; foreach ($list as $item){ $seriesdata[]=$item['count_user']; $xdata[]=$item['_add_time']; } count($xdata) > $limit && $zoom=$xdata[$limit-5]; //多次购物分销会员数量饼状图 $count=self::getModelTime($where,self::where('is_promoter',1))->count(); $user_count=self::getModelTime($where,self::alias('a') ->join('store_order r','r.uid=a.uid'),'a.add_time') ->where('a.is_promoter',1) ->where('r.paid',1) ->group('a.uid') ->count(); $shop_xdata=['多次购买数量占比','无购买数量占比']; $shop_data=[]; $count >0 && $shop_data=[ [ 'value'=>bcdiv($user_count,$count,2)*100, 'name'=>$shop_xdata[0].$user_count.'人', 'itemStyle'=>[ 'color'=>'#D789FF', ] ], [ 'value'=>bcdiv($count-$user_count,$count,2)*100, 'name'=>$shop_xdata[1].($count-$user_count).'人', 'itemStyle'=>[ 'color'=>'#7EF0FB', ] ] ]; return compact('fenbu_data','fenbu_xdata','visit_data','visit_xdata','visit_zoom','seriesdata','xdata','zoom','shop_xdata','shop_data'); } /* * 分销商佣金提现排行榜 * 分销商佣金总额排行榜 * $limit 截取条数 * return array */ public static function getUserDistributionTop10List($limit){ //分销商佣金提现排行榜 $extract=self::alias('a') ->join('user_extract t','a.uid=t.uid') ->where(['t.status'=>1,'a.is_promoter'=>1]) ->group('t.uid') ->field(['a.nickname','a.phone','sum(t.extract_price) as sum_price','FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time','t.uid']) ->order('sum_price desc') ->limit($limit) ->select(); count($extract) && $extract=$extract->toArray(); //分销商佣金总额排行榜 $commission=UserBill::alias('l') ->join('user a','l.uid=a.uid') ->where(['l.status'=>'1','l.category'=>'now_money','l.type'=>'brokerage','a.is_promoter'=>1]) ->group('l.uid') ->field(['a.nickname','a.phone','sum(number) as sum_number','FROM_UNIXTIME(a.add_time,"%Y-%m-%d") as add_time']) ->order('sum_number desc') ->limit($limit) ->select(); count($commission) && $commission=$commission->toArray(); return compact('extract','commission'); } } \ No newline at end of file diff --git a/application/admin/model/user/UserBill.php b/application/admin/model/user/UserBill.php new file mode 100644 index 00000000..50ba732d --- /dev/null +++ b/application/admin/model/user/UserBill.php @@ -0,0 +1,276 @@ +field(['FROM_UNIXTIME(add_time,"%Y-%c-%d") as un_time','sum(number) as sum_number']) + ->order('un_time asc') + ->where(['category'=>$category,'type'=>$type,'pm'=>$pm]) + ->group('un_time') + ->select(); + if(count($list)) $list=$list->toArray(); + $legdata=[]; + $listdata=[]; + $dataZoom=''; + foreach ($list as $item){ + $legdata[]=$item['un_time']; + $listdata[]=$item['sum_number']; + } + if(count($legdata)>=$zoom) $dataZoom=$legdata[$zoom-1]; + //获取用户分布钱数 + $fenbulist=self::getModelTime($where,new self(),'a.add_time') + ->alias('a') + ->join('user r','a.uid=r.uid') + ->field(['a.uid','sum(a.number) as sum_number','r.nickname']) + ->where(['a.category'=>$category,'a.type'=>$type,'a.pm'=>$pm]) + ->order('sum_number desc') + ->group('a.uid') + ->limit(8) + ->select(); + //获取用户当前时间段总钱数 + $sum_number=self::getModelTime($where,new self()) + ->where(['category'=>$category,'type'=>$type,'pm'=>$pm]) + ->sum('number'); + if(count($fenbulist)) $fenbulist=$fenbulist->toArray(); + $fenbudate=[]; + $fenbu_legend=[]; + $color=['#ffcccc','#99cc00','#fd99cc','#669966','#66CDAA','#ADFF2F','#00BFFF','#00CED1','#66cccc','#ff9900','#ffcc00','#336699','#cccc00','#99ccff','#990066']; + foreach ($fenbulist as $key=>$value){ + $fenbu_legend[]=$value['nickname']; + $items['name']=$value['nickname']; + $items['value']=bcdiv($value['sum_number'],$sum_number,2)*100; + $items['itemStyle']['color']=$color[$key]; + $fenbudate[]=$items; + } + return compact('legdata','listdata','fenbudate','fenbu_legend','dataZoom'); + } + //获取头部信息 + public static function getRebateBadge($where){ + $datawhere=['category'=>'now_money','type'=>'brokerage','pm'=>1]; + return [ + [ + 'name'=>'返利数(笔)', + 'field'=>'个', + 'count'=>self::getModelTime($where,new self())->where($datawhere)->count(), + 'content'=>'返利总笔数', + 'background_color'=>'layui-bg-blue', + 'sum'=>self::where($datawhere)->count(), + 'class'=>'fa fa-bar-chart', + ], + [ + 'name'=>'返利金额(元)', + 'field'=>'个', + 'count'=>self::getModelTime($where,new self())->where($datawhere)->sum('number'), + 'content'=>'返利总金额', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::where($datawhere)->sum('number'), + 'class'=>'fa fa-line-chart', + ], + ]; + } + //获取返佣用户信息列表 + public static function getFanList($where){ + $datawhere=['a.category'=>'now_money','a.type'=>'brokerage','a.pm'=>1]; + $list=self::alias('a')->join('user r','a.uid=r.uid') + ->where($datawhere) + ->order('a.number desc') + ->join('store_order o','o.id=a.link_id') + ->field(['o.order_id','FROM_UNIXTIME(a.add_time,"%Y-%c-%d") as add_time','a.uid','o.uid as down_uid','r.nickname','r.avatar','r.spread_uid','r.level','a.number']) + ->page((int)$where['page'],(int)$where['limit']) + ->select(); + if(count($list)) $list=$list->toArray(); + return $list; + } + //获取返佣用户总人数 + public static function getFanCount(){ + $datawhere=['a.category'=>'now_money','a.type'=>'brokerage','a.pm'=>1]; + return self::alias('a')->join('user r','a.uid=r.uid')->join('store_order o','o.id=a.link_id')->where($datawhere)->count(); + } + //获取用户充值数据 + public static function getEchartsRecharge($where,$limit=15){ + $datawhere=['category'=>'now_money','pm'=>1]; + $list=self::getModelTime($where,self::where($datawhere)->where('type','in',['recharge','system_add'])) + ->field(['sum(number) as sum_money','FROM_UNIXTIME(add_time,"%Y-%c-%d") as un_time','count(id) as count']) + ->group('un_time') + ->order('un_time asc') + ->select(); + if(count($list)) $list=$list->toArray(); + $sum_count=self::getModelTime($where,self::where($datawhere)->where('type','in',['recharge','system_add']))->count(); + $xdata=[]; + $seriesdata=[]; + $data=[]; + $zoom=''; + foreach ($list as $value){ + $xdata[]=$value['un_time']; + $seriesdata[]=$value['sum_money']; + $data[]=$value['count']; + } + if(count($xdata)>$limit){ + $zoom=$xdata[$limit-5]; + } + return compact('xdata','seriesdata','data','zoom'); + } + //获取佣金提现列表 + public static function getExtrctOneList($where,$uid){ + $list=self::setOneWhere($where,$uid) + ->field(['number','link_id','mark','FROM_UNIXTIME(add_time,"%Y-%m-%d %H:%i:%s") as _add_time','status']) + ->select(); + count($list) && $list=$list->toArray(); + $count=self::setOneWhere($where,$uid)->count(); + foreach ($list as &$value){ + $value['order_id']=db('store_order')->where(['order_id'=>$value['link_id']])->value('order_id'); + } + return ['data'=>$list,'count'=>$count]; + } + //设置单个用户查询 + public static function setOneWhere($where,$uid){ + $model=self::where(['uid'=>$uid,'category'=>'now_money','type'=>'brokerage']); + $time['data']=''; + if($where['start_time']!='' && $where['end_time']!=''){ + $time['data']=$where['start_time'].' - '.$where['end_time']; + $model=self::getModelTime($time,$model); + } + if($where['nickname']!=''){ + $model=$model->where('link_id|mark','like',"%$where[nickname]%"); + } + return $model; + } + //查询积分个人明细 + public static function getOneIntegralList($where){ + return self::setWhereList( + $where, + ['deduction','system_add'], + ['title','number','balance','mark','FROM_UNIXTIME(add_time,"%Y-%m-%d") as add_time'] + ); + } + //查询个人签到明细 + public static function getOneSignList($where){ + return self::setWhereList( + $where,'sign', + ['title','number','mark','FROM_UNIXTIME(add_time,"%Y-%m-%d") as add_time'] + ); + } + //查询个人余额变动记录 + public static function getOneBalanceChangList($where){ + $list=self::setWhereList( + $where, + ['system_add','pay_product','extract','pay_product_refund','system_sub'], + ['FROM_UNIXTIME(add_time,"%Y-%m-%d") as add_time','title','type','mark','number','balance','pm','status'], + 'now_money' + ); + foreach ($list as &$item){ + switch ($item['type']){ + case 'system_add': + $item['_type']='系统添加'; + break; + case 'pay_product': + $item['_type']='商品购买'; + break; + case 'extract': + $item['_type']='提现'; + break; + case 'pay_product_refund': + $item['_type']='退款'; + break; + case 'system_sub': + $item['_type']='系统减少'; + break; + } + $item['_pm']=$item['pm']==1 ? '获得': '支出'; + } + return $list; + } + //设置where条件分页.返回数据 + public static function setWhereList($where,$type='',$field=[],$category='integral'){ + $models=self::where('uid',$where['uid']) + ->where('category',$category) + ->page((int)$where['page'],(int)$where['limit']) + ->field($field); + if(is_array($type)){ + $models=$models->where('type','in',$type); + }else{ + $models=$models->where('type',$type); + } + return ($list=$models->select()) && count($list) ? $list->toArray():[]; + } + //获取积分统计头部信息 + public static function getScoreBadgeList($where){ + return [ + [ + 'name'=>'总积分', + 'field'=>'个', + 'count'=>self::getModelTime($where,new self())->where('category','integral')->where('type','in',['gain','system_sub','deduction','sign'])->sum('number'), + 'background_color'=>'layui-bg-blue', + 'col'=>4, + ], + [ + 'name'=>'已使用积分', + 'field'=>'个', + 'count'=>self::getModelTime($where,new self())->where('category','integral')->where('type','deduction')->sum('number'), + 'background_color'=>'layui-bg-cyan', + 'col'=>4, + ], + [ + 'name'=>'未使用积分', + 'field'=>'个', + 'count'=>self::getModelTime($where,db('user'))->sum('integral'), + 'background_color'=>'layui-bg-cyan', + 'col'=>4, + ], + ]; + } + //获取积分统计曲线图和柱状图 + public static function getScoreCurve($where){ + //发放积分趋势图 + $list=self::getModelTime($where,self::where('category','integral') + ->field(['FROM_UNIXTIME(add_time,"%Y-%m-%d") as _add_time','sum(number) as sum_number']) + ->group('_add_time')->order('_add_time asc'))->select()->toArray(); + $date=[]; + $zoom=''; + $seriesdata=[]; + foreach ($list as $item){ + $date[]=$item['_add_time']; + $seriesdata[]=$item['sum_number']; + } + unset($item); + if(count($date)>$where['limit']){ + $zoom=$date[$where['limit']-5]; + } + //使用积分趋势图 + $deductionlist=self::getModelTime($where,self::where('category','integral')->where('type','deduction') + ->field(['FROM_UNIXTIME(add_time,"%Y-%m-%d") as _add_time','sum(number) as sum_number']) + ->group('_add_time')->order('_add_time asc'))->select()->toArray(); + $deduction_date=[]; + $deduction_zoom=''; + $deduction_seriesdata=[]; + foreach ($deductionlist as $item){ + $deduction_date[]=$item['_add_time']; + $deduction_seriesdata[]=$item['sum_number']; + } + if(count($deductionlist)>$where['limit']){ + $deduction_zoom=$deductionlist[$where['limit']-5]; + } + return compact('date','seriesdata','zoom','deduction_date','deduction_zoom','deduction_seriesdata'); + } +} \ No newline at end of file diff --git a/application/admin/model/user/UserExtract.php b/application/admin/model/user/UserExtract.php new file mode 100644 index 00000000..43a0c445 --- /dev/null +++ b/application/admin/model/user/UserExtract.php @@ -0,0 +1,262 @@ +where('a.status',$where['status']); + if($where['extract_type'] != '') $model = $model->where('a.extract_type',$where['extract_type']); + if($where['nireid'] != '') $model = $model->where('a.real_name|a.id|b.nickname|a.bank_code|a.alipay_code','like',"%$where[nireid]%"); + $model = $model->alias('a'); + $model = $model->field('a.*,b.nickname'); + $model = $model->join('__USER__ b','b.uid=a.uid','LEFT'); + $model = $model->order('a.id desc'); + return self::page($model); + } + + public static function changeFail($id,$fail_msg) + { + $fail_time = time(); + $data =self::get($id); + $extract_number=$data['extract_price']; + $mark='提现失败,退回佣金'.$extract_number.'元'; + $uid=$data['uid']; + $status = -1; + $User= User::find(['uid'=>$uid])->toArray(); + UserBill::income('提现失败',$uid,'now_money','extract',$extract_number,$id,$User['now_money'],$mark); + + User::bcInc($uid,'now_money',$extract_number,'uid'); + WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($uid),WechatTemplateService::USER_BALANCE_CHANGE,[ + 'first'=> $mark, + 'keyword1'=>'佣金提现', + 'keyword2'=>date('Y-m-d H:i:s',time()), + 'keyword3'=>$extract_number, + 'remark'=>'错误原因:'.$fail_msg + ],Url::build('wap/my/user_pro',[],true,true)); + return self::edit(compact('fail_time','fail_msg','status'),$id); + } + + public static function changeSuccess($id) + { + $status = 1; + $data =self::get($id); + $extract_number=$data['extract_price']; + $mark='成功提现佣金'.$extract_number.'元'; + $uid=$data['uid']; + WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($uid),WechatTemplateService::USER_BALANCE_CHANGE,[ + 'first'=> $mark, + 'keyword1'=>'佣金提现', + 'keyword2'=>date('Y-m-d H:i:s',time()), + 'keyword3'=>$extract_number, + 'remark'=>'点击查看我的佣金明细' + ],Url::build('wap/my/user_pro',[],true,true)); + return self::edit(compact('status'),$id); + } + //测试数据 + public static function test(){ + $uids=User::order('uid desc')->limit(2,20)->field(['uid','nickname'])->select()->toArray(); + $type=['bank','alipay','weixin']; + foreach ($uids as $item){ + $data=[ + 'uid'=>$item['uid'], + 'real_name'=>$item['nickname'], + 'extract_type'=>isset($type[rand(0,2)]) ? $type[rand(0,2)] :'alipay', + 'bank_code'=>rand(1000000,999999999), + 'bank_address'=>'中国', + 'alipay_code'=>rand(1000,9999999), + 'extract_price'=>rand(100,9999), + 'mark'=>'测试数据', + 'add_time'=>time(), + 'status'=>1, + 'wechat'=>rand(999,878788).$item['uid'], + ]; + self::set($data); + } + } + //获取头部提现信息 + public static function getExtractHead(){ + //本月提现人数 + $month=self::getModelTime(['data'=>'month'],self::where(['status'=>1]))->group('uid')->count(); + //本月提现笔数 + $new_month=self::getModelTime(['data'=>'month'],self::where(['status'=>1]))->distinct(true)->count(); + //上月提现人数 + $last_month=self::whereTime('add_time','last month')->where('status',1)->group('uid')->distinct(true)->count(); + //上月提现笔数 + $last_count=self::whereTime('add_time','last month')->where('status',1)->count(); + //本月提现金额 + $extract_price=self::getModelTime(['data'=>'month'],self::where(['status'=>1]))->sum('extract_price'); + //上月提现金额 + $last_extract_price=self::whereTime('add_time','last month')->where('status',1)->sum('extract_price'); + + return [ + [ + 'name'=>'总提现人数', + 'field'=>'个', + 'count'=>self::where(['status'=>1])->group('uid')->count(), + 'content'=>'', + 'background_color'=>'layui-bg-blue', + 'sum'=>'', + 'class'=>'fa fa-bar-chart', + ], + [ + 'name'=>'总提现笔数', + 'field'=>'笔', + 'count'=>self::where(['status'=>1])->distinct(true)->count(), + 'content'=>'', + 'background_color'=>'layui-bg-cyan', + 'sum'=>'', + 'class'=>'fa fa-line-chart', + ], + [ + 'name'=>'本月提现人数', + 'field'=>'人', + 'count'=>$month, + 'content'=>'', + 'background_color'=>'layui-bg-orange', + 'sum'=>'', + 'class'=>'fa fa-line-chart', + ], + [ + 'name'=>'本月提现笔数', + 'field'=>'笔', + 'count'=>$new_month, + 'content'=>'', + 'background_color'=>'layui-bg-green', + 'sum'=>'', + 'class'=>'fa fa-line-chart', + ], + [ + 'name'=>'本月提现金额', + 'field'=>'元', + 'count'=>$extract_price, + 'content'=>'提现总金额', + 'background_color'=>'layui-bg-cyan', + 'sum'=>self::where(['status'=>1])->sum('extract_price'), + 'class'=>'fa fa-line-chart', + ], + [ + 'name'=>'上月提现人数', + 'field'=>'个', + 'count'=>$last_month, + 'content'=>'环比增幅', + 'background_color'=>'layui-bg-blue', + 'sum'=>$last_month==0 ? '100%' :bcdiv($month,$last_month,2)*100, + 'class'=>$last_month==0 ? 'fa fa-level-up':'fa fa-level-down', + ], + [ + 'name'=>'上月提现笔数', + 'field'=>'笔', + 'count'=>$last_count, + 'content'=>'环比增幅', + 'background_color'=>'layui-bg-black', + 'sum'=>$last_count==0 ? '100%':bcdiv($new_month,$last_count,2)*100, + 'class'=>$last_count==0 ? 'fa fa-level-up':'fa fa-level-down', + ], + [ + 'name'=>'上月提现金额', + 'field'=>'元', + 'count'=>$last_extract_price, + 'content'=>'环比增幅', + 'background_color'=>'layui-bg-gray', + 'sum'=>$last_extract_price==0 ? '100%':bcdiv($extract_price,$last_extract_price,2)*100, + 'class'=>$last_extract_price==0 ? 'fa fa-level-up':'fa fa-level-down', + ], + ]; + } + //获取提现分布图和提现人数金额曲线图 + public static function getExtractList($where,$limit=15){ + $legdata=['提现人数','提现金额']; + $list=self::getModelTime($where,self::where('status',1)) + ->field([ + 'FROM_UNIXTIME(add_time,"%Y-%c-%d") as un_time', + 'count(uid) as count', + 'sum(extract_price) as sum_price', + ])->group('un_time')->order('un_time asc')->select(); + if(count($list)) $list=$list->toArray(); + $xdata=[]; + $itemList=[0=>[],1=>[]]; + $chatrList=[]; + $zoom=''; + foreach ($list as $value){ + $xdata[]=$value['un_time']; + $itemList[0][]=$value['count']; + $itemList[1][]=$value['sum_price']; + } + foreach ($legdata as $key=>$name){ + $item['name']=$name; + $item['type']='line'; + $item['data']=$itemList[$key]; + $chatrList[]=$item; + } + unset($item,$name,$key); + if(count($xdata)>$limit) $zoom=$xdata[$limit-5]; + //饼状图 + $cake=['支付宝','银行卡','微信']; + $fenbulist=self::getModelTime($where,self::where('status',1)) + ->field(['count(uid) as count','extract_type'])->group('extract_type')->order('count asc')->select(); + if(count($fenbulist)) $fenbulist=$fenbulist->toArray(); + $sum_count=self::getModelTime($where,self::where('status',1))->count(); + $color=['#FB7773','#81BCFE','#91F3FE']; + $fenbudata=[]; + foreach ($fenbulist as $key=>$item){ + if($item['extract_type']=='bank'){ + $item_date['name']='银行卡'; + }else if($item['extract_type']=='alipay'){ + $item_date['name']='支付宝'; + }else if($item['extract_type']=='weixin'){ + $item_date['name']='微信'; + } + $item_date['value']=bcdiv($item['count'],$sum_count,2)*100; + $item_date['itemStyle']['color']=$color[$key]; + $fenbudata[]=$item_date; + } + return compact('xdata','chatrList','legdata','zoom','cake','fenbudata'); + } + + /** + * 获取用户累计提现金额 + * @param int $uid + * @return int|mixed + */ + public static function getUserCountPrice($uid = 0){ + if(!$uid) return 0; + $price = self::where('uid',$uid)->where('status',1)->field('sum(extract_price) as price')->find()['price']; + return $price ? $price : 0; + } + + /** + * 获取用户累计提现次数 + * @param int $uid + * @return int|string + */ + public static function getUserCountNum($uid = 0){ + if(!$uid) return 0; + return self::where('uid',$uid)->count(); + } +} \ No newline at end of file diff --git a/application/admin/model/user/UserNotice.php b/application/admin/model/user/UserNotice.php new file mode 100644 index 00000000..c0f2a593 --- /dev/null +++ b/application/admin/model/user/UserNotice.php @@ -0,0 +1,39 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\user; + +use app\admin\model\wechat\WechatUser; +use app\admin\model\user\UserNoticeSee; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 用户通知 model + * Class UserNotice + * @package app\admin\model\user + */ +class UserNotice extends ModelBasic +{ + use ModelTrait; + + /** + * @return array + */ + public static function getList(){ + $model = new self; + $model->order('id desc'); + return self::page($model,function($item,$key){ + if($item["uid"] != ''){ + $uids = explode(",",$item["uid"]); + array_splice($uids,0,1); + array_splice($uids,count($uids)-1,1); + $item["uid"] = $uids; + } + }); + } +} \ No newline at end of file diff --git a/application/admin/model/user/UserNoticeSee.php b/application/admin/model/user/UserNoticeSee.php new file mode 100644 index 00000000..0bfe1a59 --- /dev/null +++ b/application/admin/model/user/UserNoticeSee.php @@ -0,0 +1,22 @@ + + * @day: 2017/11/11 + */ + +namespace app\admin\model\user; + +use app\admin\model\wechat\WechatUser; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 用户通知查看 model + * Class UserNoticeSee + * @package app\admin\model\user + */ +class UserNoticeSee extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/admin/model/user/UserPoint.php b/application/admin/model/user/UserPoint.php new file mode 100644 index 00000000..dc8c5b18 --- /dev/null +++ b/application/admin/model/user/UserPoint.php @@ -0,0 +1,109 @@ +where('category','integral')->select(); + return $model::page($model); + } + /* + * + * 异步获取积分信息 + * */ + public static function getpointlist($where){ + $list=self::setWhere($where) + ->order('a.add_time desc') + ->field(['a.*','b.nickname']) + ->page((int)$where['page'],(int)$where['limit']) + ->select() + ->toArray(); + foreach ($list as $key=>$item){ + $list[$key]['add_time']=date('Y-m-d', $item['add_time']); + } + $count=self::setWhere($where)->field(['a.*','b.nickname'])->count(); + return ['count'=>$count,'data'=>$list]; + } + //生成Excel表格并下载 + public static function SaveExport($where){ + $list=self::setWhere($where)->field(['a.*','b.nickname'])->select(); + $Export=[]; + foreach ($list as $key=>$item){ + $Export[]=[ + $item['id'], + $item['title'], + $item['balance'], + $item['number'], + $item['mark'], + $item['nickname'], + date('Y-m-d H:i:s',$item['add_time']), + ]; + } + PHPExcelService::setExcelHeader(['编号','标题','积分余量','明细数字','备注','用户微信昵称','添加时间']) + ->setExcelTile('积分日志','积分日志'.time(),'生成时间:'.date('Y-m-d H:i:s',time())) + ->setExcelContent($Export) + ->ExcelSave(); + } + public static function setWhere($where){ + $model=UserBill::alias('a')->join('__USER__ b','a.uid=b.uid','left')->where('a.category','integral'); + $time['data']=''; + if($where['start_time']!='' && $where['end_time']!=''){ + $time['data']=$where['start_time'].' - '.$where['end_time']; + } + $model=self::getModelTime($time,$model,'a.add_time'); + if($where['nickname']!=''){ + $model=$model->where('b.nickname|b.uid','like',$where['nickname']); + } + return $model; + } + //获取积分头部信息 + public static function getUserpointBadgelist($where){ + return [ + [ + 'name'=>'总积分', + 'field'=>'个', + 'count'=>self::setWhere($where)->sum('a.number'), + 'background_color'=>'layui-bg-blue', + ], + [ + 'name'=>'客户签到次数', + 'field'=>'个', + 'count'=>self::setWhere($where)->where('a.type','sign')->group('a.uid')->count(), + 'background_color'=>'layui-bg-cyan', + ], + [ + 'name'=>'签到送出积分', + 'field'=>'个', + 'count'=>self::setWhere($where)->where('a.type','sign')->sum('a.number'), + 'background_color'=>'layui-bg-cyan', + ], + [ + 'name'=>'使用积分', + 'field'=>'个', + 'count'=>self::setWhere($where)->where('a.type','deduction')->sum('a.number'), + 'background_color'=>'layui-bg-cyan', + ], + ]; + } +} \ No newline at end of file diff --git a/application/admin/model/user/UserRecharge.php b/application/admin/model/user/UserRecharge.php new file mode 100644 index 00000000..45cf73d4 --- /dev/null +++ b/application/admin/model/user/UserRecharge.php @@ -0,0 +1,35 @@ +alias('A'); + if($where['order_id'] != '') { + $model = $model->where('A.order_id|B.nickname','like',"%$where[order_id]%"); + $model = $model->whereOr('A.id',(int)$where['order_id']); + } + $model = $model->where('A.recharge_type','weixin'); + $model = $model->where('A.paid',1); + $model = $model->field('A.*,B.nickname'); + $model = $model->join('__USER__ B','A.uid = B.uid','RIGHT'); + $model = $model->order('A.id desc'); + + return self::page($model,$where); + + } + +} \ No newline at end of file diff --git a/application/admin/model/wechat/ArticleCategory.php b/application/admin/model/wechat/ArticleCategory.php new file mode 100644 index 00000000..909f61f2 --- /dev/null +++ b/application/admin/model/wechat/ArticleCategory.php @@ -0,0 +1,74 @@ + + * @day: 2017/11/02 + */ +namespace app\admin\model\wechat; + +use traits\ModelTrait; +use app\admin\model\wechat\WechatNews as NewsModel; +use basic\ModelBasic; + +/** + * 文章分类model + * Class ArticleCategory + * @package app\admin\model\wechat + */ +class ArticleCategory extends ModelBasic +{ + use ModelTrait; + + /** + * 获取系统分页数据 分类 + * @param array $where + * @return array + */ + public static function systemPage($where = array()){ + $model = new self; + if($where['title'] !== '') $model = $model->where('title','LIKE',"%$where[title]%"); + if($where['status'] !== '') $model = $model->where('status',$where['status']); + $model = $model->where('is_del',0); + $model = $model->where('hidden',0); + return self::page($model); + } + + /** + * 删除分类 + * @param $id + * @return bool + */ + public static function delArticleCategory($id) + { + if(count(self::getArticle($id,'*'))>0) + return self::setErrorInfo('请先删除改分类下的文章!'); + return self::edit(['is_del'=>1],$id,'id'); + } + + /** + * 获取分类名称和id field + * @param $field + * @return array + */ + public static function getField($field){ + return self::where('is_del','eq',0)->where('status','eq',1)->where('hidden','eq',0)->column($field); + } + + /** + * 获取分类底下的文章 + * id 分类表中的分类id + * return array + * */ + public static function getArticle($id,$field){ + $res = NewsModel::where('status',1)->where('hide',0)->column($field,'id'); + $new_res = array(); + foreach ($res as $k=>$v){ + $cid_arr = explode(',',$v['cid']); + if(in_array($id,$cid_arr)){ + $new_res[$k] = $res[$k]; + } + } + return $new_res; + } + +} \ No newline at end of file diff --git a/application/admin/model/wechat/StoreService.php b/application/admin/model/wechat/StoreService.php new file mode 100644 index 00000000..98feef3b --- /dev/null +++ b/application/admin/model/wechat/StoreService.php @@ -0,0 +1,50 @@ +order('id desc'),function($item){ + $item['wx_name']=WechatUser::where(['uid'=>$item['uid']])->value('nickname'); + }); + } + + /** + * @return array + */ + public static function getChatUser($now_service,$mer_id){ + $where = 'mer_id = '.$mer_id.' AND (uid = '.$now_service["uid"].' OR to_uid='.$now_service["uid"].')'; + $chat_list = ServiceLogModel::field("uid,to_uid")->where($where)->group("uid,to_uid")->select(); + if(count($chat_list) > 0){ + $arr_user = $arr_to_user = []; + foreach ($chat_list as $key => $value) { + array_push($arr_user,$value["uid"]); + array_push($arr_to_user,$value["to_uid"]); + } + $uids = array_merge($arr_user,$arr_to_user); + + $list = WechatUser::field("uid,nickname,headimgurl")->where(array("uid"=>array(array("in",$uids),array("neq",$now_service["uid"]))))->select(); + foreach ($list as $index => $user) { + $service = self::field("uid,nickname,avatar as headimgurl")->where(array("uid"=>$user["uid"]))->find(); + if($service)$list[$index] = $service; + } + }else{ + $list = null; + } + return $list; + } +} \ No newline at end of file diff --git a/application/admin/model/wechat/StoreServiceLog.php b/application/admin/model/wechat/StoreServiceLog.php new file mode 100644 index 00000000..c8a04668 --- /dev/null +++ b/application/admin/model/wechat/StoreServiceLog.php @@ -0,0 +1,32 @@ +where($where); + $model->order("add_time desc"); + return self::page($model,function($item,$key) use ($mer_id){ + $user = StoreService::field("nickname,avatar")->where('mer_id',$mer_id)->where(array("uid"=>$item["uid"]))->find(); + if(!$user)$user = User::field("nickname,avatar")->where(array("uid"=>$item["uid"]))->find(); + $item["nickname"] = $user["nickname"]; + $item["avatar"] = $user["avatar"]; + }); + } +} \ No newline at end of file diff --git a/application/admin/model/wechat/WechatMessage.php b/application/admin/model/wechat/WechatMessage.php new file mode 100644 index 00000000..e3027731 --- /dev/null +++ b/application/admin/model/wechat/WechatMessage.php @@ -0,0 +1,231 @@ + + * @day: 2017/11/28 + */ + +namespace app\admin\model\wechat; + + +use app\admin\model\user\User; +use think\Cache; +use traits\ModelTrait; +use basic\ModelBasic; +use app\admin\model\wechat\WechatUser as UserModel; + +/** + * 微信用户行为记录 model + * Class WechatMessage + * @package app\admin\model\wechat + */ +class WechatMessage extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + /** + * 微信用户操作的基本所有操作 + * @var array + */ + public static $mold = array( + 'event_subscribe'=>'关注微信号', + 'event_unsubscribe'=>'取消关注微信号', + 'event_scan'=>'扫码', + 'event_location'=>'获取位置', + 'event_click'=>'点击微信菜单关键字', + 'event_view'=>'点击微信菜单链接', + 'text'=>'收到文本消息', + 'image'=>'收到图片消息', + 'video'=>'收到视频消息', + 'voice'=>'收到声音消息', + 'location'=>'收到位置消息', + 'link'=>'收到链接消息', + 'event_scan_subscribe'=>'扫码关注' + ); + + public static function setAddTimeAttr($value) + { + return time(); + } + public static function setMessage($result,$openid,$type) + { + $data = compact('result','openid','type'); + return self::set($data); + } + + public static function setOnceMessage($result,$openid,$type,$unique,$cacheTime = 172800) + { + $cacheName = 'wechat_message_'.$type.'_'.$unique; + if(Cache::has($cacheName)) return true; + $res = self::setMessage($result,$openid,$type); + if($res) Cache::set($cacheName,1,$cacheTime); + return $res; + } + + /** + * 按钮事件 + * @param $Event + * @return mixed + */ + public static function tidyEvent($Event){ + $res = array( + 'msg'=>$Event['EventKey'], + ); + return $res; + } + /** + * 取消关注事件扫码 + * @param $Event + * @return mixed + */ + public static function tidyNull(){ + $res = array( + 'msg'=>'无', + ); + return $res; + } + /** + * 整理文本显示的数据 + * @param $text 收到的文本消息 + * return 返回收到的消息 + */ + public static function tidyText($text){ + $res = array( + 'rep_id'=> '1', + 'MsgId'=>$text['MsgId'], + 'Content'=>$text['Content'], + 'msg'=>$text['Content'], + ); + return $res; + } + /** + * 整理图片显示的数据 + * @param $image + * @return mixed + */ + public static function tidyImage($image){ + $res = array( + 'rep_id'=> '2', + 'MsgId'=>$image['MsgId'], + 'PicUrl'=>$image['PicUrl'], + 'MediaId'=>$image['MediaId'], + 'msg'=>'媒体ID:'.$image['MediaId'], + ); + return $res; + } + /** + * 整理视屏显示的数据 + * @param $video + * @return mixed + */ + public static function tidyVideo($video){ + $res = array( + 'rep_id'=> '3', + 'MsgId'=>$video['MsgId'], + 'MediaId'=>$video['MediaId'], + 'msg'=>'媒体ID:'.$video['MediaId'], + ); + return $res; + } + /** + * 整理声音显示的数据 + * @param $voice + * @return mixed + */ + public static function tidyVoice($voice){ + $res = array( + 'rep_id'=> '4', + 'MsgId'=>$voice['MsgId'], + 'MediaId'=>$voice['MediaId'], + 'msg'=>'媒体ID:'.$voice['MediaId'], + ); + return $res; + } + /** + * 地理位置 + * @param $location + * @return array + */ + public static function tidyLocation($location){ + $res = array( + 'rep_id'=> '5', + 'MsgId'=>$location['MsgId'], + 'Label'=>$location['Label'], + 'msg'=>$location['Label'], + ); + return $res; + } + /** + * 获取用户扫码点击事件 + * @param array $where + * @return array + */ + public static function systemPage($where = array()){ + $model = new self; + $model = $model->alias('m'); + if($where['nickname'] !== ''){ + $user = UserModel::where('nickname','LIKE',"%$where[nickname]%")->field('openid')->select(); + if(empty($user->toArray())) $model = $model->where('m.id',0); + foreach ($user as $v){ + $model = $model->where('m.openid',$v['openid']); + } + } + if($where['type'] !== '') $model = $model->where('m.type',$where['type']); + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('m.add_time','>',strtotime($startTime)); + $model = $model->where('m.add_time','<',strtotime($endTime)); + } + $model = $model->field('u.nickname,m.*')->join('WechatUser u','u.openid=m.openid')->order('m.id desc'); + return self::page($model,function ($item){ + switch ($item['type']){ + case 'text': $item['result_arr'] = self::tidyText(json_decode($item['result'],true));break; + case 'image': $item['result_arr'] = self::tidyImage(json_decode($item['result'],true));break; + case 'video': $item['result_arr'] = self::tidyVideo(json_decode($item['result'],true));break; + case 'voice': $item['result_arr'] = self::tidyVoice(json_decode($item['result'],true));break; + case 'location': $item['result_arr'] = self::tidyLocation(json_decode($item['result'],true));break; + case 'event_click': $item['result_arr'] = self::tidyEvent(json_decode($item['result'],true));break; + case 'event_view': $item['result_arr'] = self::tidyEvent(json_decode($item['result'],true));break; + case 'event_subscribe': $item['result_arr'] = self::tidyNull();break; + case 'event_unsubscribe': $item['result_arr'] = self::tidyNull();break; + case 'event_scan': $item['result_arr'] = self::tidyNull();break; + default :$item['result_arr'] = ['msg'=>$item['type']];break; + } + $item['type_name'] = isset(self::$mold[$item['type']]) ? self::$mold[$item['type']] : '未知'; + },$where); + } + + /* + * 获取应为记录数据 + * + */ + public static function getViweList($date,$class=[]){ + $model=new self(); + switch ($date){ + case null:case 'today':case 'week':case 'year': + if($date==null) $date='month'; + $model=$model->whereTime('add_time',$date); + break; + case 'quarter': + $time=User::getMonth('n'); + $model=$model->where('add_time','between', $time); + break; + default: + list($startTime,$endTime)=explode('-',$date); + $model = $model->where('add_time','>',strtotime($startTime)); + $model = $model->where('add_time','<',strtotime($endTime)); + break; + } + $list=$model->field(['type','count(*) as num','result'])->group('type')->limit(0,20)->select()->toArray(); + $viwe=[]; + foreach ($list as $key=>$item){ + $now_list['name']=isset(self::$mold[$item['type']]) ? self::$mold[$item['type']] : '未知'; + $now_list['value']=$item['num']; + $now_list['class']=isset($class[$key])?$class[$key]:''; + $viwe[]=$now_list; + } + return $viwe; + } +} \ No newline at end of file diff --git a/application/admin/model/wechat/WechatNews.php b/application/admin/model/wechat/WechatNews.php new file mode 100644 index 00000000..82f95dcf --- /dev/null +++ b/application/admin/model/wechat/WechatNews.php @@ -0,0 +1 @@ + * @day: 2017/11/02 */ namespace app\admin\model\wechat; use app\admin\model\system\Merchant; use app\admin\model\system\SystemAdmin; use app\merchant\model\merchant\MerchantAdmin; use traits\ModelTrait; use basic\ModelBasic; use think\Db; /** * 图文管理 Model * Class WechatNews * @package app\admin\model\wechat */ class WechatNews extends ModelBasic { use ModelTrait; /** * 获取配置分类 * @param array $where * @return array */ public static function getAll($where = array()){ $model = new self; // if($where['status'] !== '') $model = $model->where('status',$where['status']); // if($where['access'] !== '') $model = $model->where('access',$where['access']); if($where['title'] !== '') $model = $model->where('title','LIKE',"%$where[title]%"); if($where['cid'] !== '') $model = $model->where("CONCAT(',',cid,',') LIKE '%,$where[cid],%'"); if($where['cid'] == ''){ if(!$where['merchant']) $model = $model->where('mer_id',0); if($where['merchant']) $model = $model->where('mer_id','GT',0); } $model = $model->where('status',1)->where('hide',0); return self::page($model,function($item){ if(!$item['mer_id']) $item['admin_name'] = '总后台管理员---》'.SystemAdmin::where('id',$item['admin_id'])->value('real_name'); else $item['admin_name'] = Merchant::where('id',$item['mer_id'])->value('mer_name').'---》'.MerchantAdmin::where('id',$item['admin_id'])->value('real_name'); $item['content'] = Db::name('wechatNewsContent')->where('nid',$item['id'])->value('content'); },$where); } /** * 删除图文 * @param $id * @return bool */ public static function del($id){ return self::edit(['status'=>0],$id,'id'); } /** * 获取指定字段的值 * @return array */ public static function getNews() { return self::where('status',1)->where('hide',0)->order('id desc')->column('id,title'); } /** * 给表中的字符串类型追加值 * 删除所有有当前分类的id之后重新添加 * @param $cid * @param $id * @return bool */ public static function saveBatchCid($cid,$id){ $res_all = self::where('cid','LIKE',"%$cid%")->select();//获取所有有当前分类的图文 foreach ($res_all as $k=>$v){ $cid_arr = explode(',',$v['cid']); if(in_array($cid,$cid_arr)){ $key = array_search($cid, $cid_arr); array_splice($cid_arr, $key, 1); } if(empty($cid_arr)) { $data['cid'] = 0; self::edit($data,$v['id']); }else{ $data['cid'] = implode(',',$cid_arr); self::edit($data,$v['id']); } } $res = self::where('id','IN',$id)->select(); foreach ($res as $k=>$v){ if(!in_array($cid,explode(',',$v['cid']))){ if(!$v['cid']){ $data['cid'] = $cid; }else{ $data['cid'] = $v['cid'].','.$cid; } self::edit($data,$v['id']); } } return true; } public static function setContent($id,$content){ $count = Db::name('wechatNewsContent')->where('nid',$id)->count(); $data['nid'] = $id; $data['content'] = $content; // dump($data); if($count){ $res = Db::name('wechatNewsContent')->where('nid',$id)->setField('content',$content); if($res !== false) $res = true; } else $res = Db::name('wechatNewsContent')->insert($data); // echo Db::getLastSql(); // exit(); return $res; } public static function merchantPage($where = array()){ $model = new self; if($where['title'] !== '') $model = $model->where('title','LIKE',"%$where[title]%"); if($where['cid'] !== '') $model = $model->where('cid','LIKE',"%$where[cid]%"); $model = $model ->where('status',1) ->where('hide',0) ->where('admin_id',$where['admin_id']) ->where('mer_id',$where['mer_id']); return self::page($model,function($item){ $item['content'] = Db::name('wechatNewsContent')->where('nid',$item['id'])->value('content'); },$where); } } \ No newline at end of file diff --git a/application/admin/model/wechat/WechatNewsCategory.php b/application/admin/model/wechat/WechatNewsCategory.php new file mode 100644 index 00000000..c9d5992c --- /dev/null +++ b/application/admin/model/wechat/WechatNewsCategory.php @@ -0,0 +1 @@ + * @day: 2017/11/02 */ namespace app\admin\model\wechat; use traits\ModelTrait; use basic\ModelBasic; use app\admin\model\article\Article as ArticleModel; /** * 图文消息 model * Class WechatNewsCategory * @package app\admin\model\wechat */ class WechatNewsCategory extends ModelBasic { use ModelTrait; /** * 获取配置分类 * @param array $where * @return array */ public static function getAll($where = array()){ $model = new self; // if($where['status'] !== '') $model = $model->where('status',$where['status']); // if($where['access'] !== '') $model = $model->where('access',$where['access']); if($where['cate_name'] !== '') $model = $model->where('cate_name','LIKE',"%$where[cate_name]%"); $model = $model->where('status',1); return self::page($model,function ($item){ $new = ArticleModel::where('id','in',$item['new_id'])->where('hide',0)->select(); $item['new'] = $new; }); } /** * 获取一条图文 * @param int $id * @return array|false|\PDOStatement|string|\think\Model */ public static function getWechatNewsItem($id = 0){ if(!$id) return []; $list = self::where('id',$id)->where('status',1)->field('cate_name as title,new_id')->find(); if($list){ $list = $list->toArray(); $new = ArticleModel::where('id','in',$list['new_id'])->where('hide',0)->select(); if($new) $new = $new->toArray(); $list['new'] = $new; } return $list; } } \ No newline at end of file diff --git a/application/admin/model/wechat/WechatQrcode.php b/application/admin/model/wechat/WechatQrcode.php new file mode 100644 index 00000000..c9fce08a --- /dev/null +++ b/application/admin/model/wechat/WechatQrcode.php @@ -0,0 +1,112 @@ + + * @day: 2017/11/22 + */ + +namespace app\admin\model\wechat; + + +use traits\ModelTrait; +use basic\ModelBasic; +use service\WechatService; + +/** + * 获取二维码 + * Class WechatQrcode + * @package app\admin\model\wechat + */ +class WechatQrcode extends ModelBasic +{ + use ModelTrait; + + /** + * 创建临时二维码 有效期 30天 + * + * 修改时 要使用的主键id $qtcode_id + * @param $id + * @param $type + * @param string $qtcode_id + */ + public static function createTemporaryQrcode($id,$type,$qtcode_id=''){ + $qrcode = WechatService::qrcodeService(); + $data = $qrcode->temporary($id,30*24*3600)->toArray(); + $data['qrcode_url'] = $data['url']; + $data['expire_seconds'] = $data['expire_seconds']+time(); + $data['url'] = $qrcode->url($data['ticket']); + $data['status'] = 1; + $data['third_id'] = $id; + $data['third_type'] = $type; + if($qtcode_id){ + self::edit($data,$qtcode_id); + }else{ + $data['add_time'] = time(); + self::set($data); + } + } + + /** + * 创建永久二维码 + * @param $id + * @param $type + */ + public static function createForeverQrcode($id,$type){ + $qrcode = WechatService::qrcodeService(); + $data = $qrcode->forever($id)->toArray(); + $data['qrcode_url'] = $data['url']; + $data['url'] = $qrcode->url($data['ticket']); + $data['expire_seconds'] = 0; + $data['status'] = 1; + $data['third_id'] = $id; + $data['third_type'] = $type; + $data['add_time'] = time(); + self::set($data); + } + + /** + * 获取临时二维码 + * @param $type + * @param $id + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getTemporaryQrcode($type,$id){ + $res = self::where('third_id',$id)->where('third_type',$type)->find(); + if(empty($res)){ + self::createTemporaryQrcode($id,$type); + $res = self::getTemporaryQrcode($type,$id); + }else if(empty($res['expire_seconds']) || $res['expire_seconds'] < time()){ + self::createTemporaryQrcode($id,$type,$res['id']); + $res = self::getTemporaryQrcode($type,$id); + } + if(!$res['ticket']) exception('临时二维码获取错误'); + return $res; + } + + /** + * 获取永久二维码 + * @param $type + * @param $id + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getForeverQrcode($type,$id){ + $res = self::where('third_id',$id)->where('third_type',$type)->find(); + if(empty($res)) { + self::createForeverQrcode($id, $type); + $res = self::getForeverQrcode($type, $id); + } + if(!$res['ticket']) exception('临时二维码获取错误'); + return $res; + } + + public static function getQrcode($id,$type = 'id') + { + return self::where($type,$id)->find(); + } + + public static function scanQrcode($id,$type = 'id') + { + return self::where($type,$id)->setInc('scan'); + } + +} \ No newline at end of file diff --git a/application/admin/model/wechat/WechatReply.php b/application/admin/model/wechat/WechatReply.php new file mode 100644 index 00000000..66ce3cf9 --- /dev/null +++ b/application/admin/model/wechat/WechatReply.php @@ -0,0 +1,197 @@ + + * @day: 2017/11/22 + */ + +namespace app\admin\model\wechat; + +use app\admin\model\system\SystemConfig; +use traits\ModelTrait; +use basic\ModelBasic; +use service\HookService; +use service\UtilService; +use service\WechatService; +use think\Url; + +/** + * 关键字 model + * Class WechatReply + * @package app\admin\model\wechat + */ +class WechatReply extends ModelBasic +{ + use ModelTrait; + + public static $reply_type = ['text','image','news','voice']; + + public function getUrlAttr($value,$data) + { + return $value == '' ? \think\Url::build('index/index/news',['id'=>$data['id']]) : $value; + } + + /** + * @param $data + * @param $key + * @param $type + * @param int $status + * @return bool + */ + public static function redact($data,$key,$type,$status = 1) + { + $method = 'tidy'.ucfirst($type); + $res = self::$method($data,$key); + if(!$res) return false; + $count = self::where('key',$key)->count(); + if($count){ + $res = self::edit(['type'=>$type,'data'=>json_encode($res),'status'=>$status],$key,'key'); + if(!$res) return self::setErrorInfo('保存失败!'); + }else{ + $res = self::set([ + 'key'=>$key, + 'type'=>$type, + 'data'=>json_encode($res), + 'status'=>$status, + ]); + if(!$res) return self::setErrorInfo('保存失败!'); + } + return true; + } + + /** + * @param $key + * @param string $field + * @param int $hide + * @return bool + */ + public static function changeHide($key,$field='id',$hide = 0) + { + return self::edit(compact('hide'),$key,$field); + } + + + /** + * 整理文本输入的消息 + * @param $data + * @param $key + * @return array|bool + */ + public static function tidyText($data,$key) + { + $res = []; + if(!isset($data['content']) || $data['content'] == '') + return self::setErrorInfo('请输入回复信息内容'); + $res['content'] = $data['content']; + return $res; + } + + /** + * 整理图片资源 + * @param $data + * @param $key + * @return array|bool|mixed + */ + public static function tidyImage($data,$key) + { + if(!isset($data['src']) || $data['src'] == '') + return self::setErrorInfo('请上传回复的图片'); + $reply = self::get(['key'=>$key]); + if($reply) $reply['data'] = json_decode($reply['data'],true); + if($reply && isset($reply['data']['src']) && $reply['data']['src'] == $data['src']){ + $res = $reply['data']; + }else { + $res = []; + //TODO 图片转media + $res['src'] = $data['src']; + $material = (WechatService::materialService()->uploadImage(UtilService::urlToPath($data['src']))); + $res['media_id'] = $material->media_id; + HookService::afterListen('wechat_material', + ['media_id' => $material->media_id, 'path' => $res['src'], 'url' => $material->url], 'image'); + } + return $res; + } + + /** + * 整理声音资源 + * @param $data + * @param $key + * @return array|bool|mixed + */ + public static function tidyVoice($data,$key) + { + if(!isset($data['src']) || $data['src'] == '') + return self::setErrorInfo('请上传回复的声音'); + $reply = self::get(['key'=>$key]); + if($reply) $reply['data'] = json_decode($reply['data'],true); + if($reply && isset($reply['data']['src']) && $reply['data']['src'] == $data['src']){ + $res = $reply['data']; + }else{ + $res = []; + //TODO 声音转media + $res['src'] = $data['src']; + $material = (WechatService::materialService()->uploadVoice(UtilService::urlToPath($data['src']))); + $res['media_id'] = $material->media_id; + HookService::afterListen('wechat_material',['media_id'=>$material->media_id,'path'=>$res['src']],'voice'); + } + return $res; + } + + /** + * 整理图文资源 + * @param $data + * @param $key + * @return bool + */ + public static function tidyNews($data,$key = '') + { + if(!count($data)) + return self::setErrorInfo('请选择图文消息'); + $siteUrl = SystemConfig::getValue('site_url'); + foreach ($data as $k=>$v){ + if(empty($v['url'])) $data[$k]['url'] = $siteUrl.Url::build('wap/article/visit',['id'=>$v['id']]); + if($v['image']) $data[$k]['image'] = $v['image']; + } + return $data; + } + + /** + * 获取所有关键字 + * @param array $where + * @return array + */ + public static function getKeyAll($where = array()){ + $model = new self; + if($where['key'] !== '') $model = $model->where('key','LIKE',"%$where[key]%"); + if($where['type'] !== '') $model = $model->where('type',$where['type']); + $model = $model->where('key','<>','subscribe'); + $model = $model->where('key','<>','default'); + return self::page($model); + } + + /** + * 获取关键字 + * @param $key + * @param string $default + * @return array|\EasyWeChat\Message\Image|\EasyWeChat\Message\News|\EasyWeChat\Message\Text|\EasyWeChat\Message\Voice + */ + public static function reply($key,$default=''){ + $res = self::where('key',$key)->where('status','1')->find(); + if(empty($res)) $res = self::where('key','default')->where('status','1')->find(); + if(empty($res)){ + return WechatService::textMessage($default); + } + $res['data'] = json_decode($res['data'],true); + if($res['type'] == 'text'){ + return WechatService::textMessage($res['data']['content']); + }else if($res['type'] == 'image'){ + return WechatService::imageMessage($res['data']['media_id']); + }else if($res['type'] == 'news'){ + return WechatService::newsMessage($res['data']); + }else if($res['type'] == 'voice'){ + return WechatService::voiceMessage($res['data']['media_id']); + } + } + + +} \ No newline at end of file diff --git a/application/admin/model/wechat/WechatTemplate.php b/application/admin/model/wechat/WechatTemplate.php new file mode 100644 index 00000000..cf4fa131 --- /dev/null +++ b/application/admin/model/wechat/WechatTemplate.php @@ -0,0 +1,32 @@ + + * @day: 2017/11/02 + */ +namespace app\admin\model\wechat; + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 微信模板消息model + * Class WechatTemplate + * @package app\admin\model\wechat + */ +class WechatTemplate extends ModelBasic +{ + use ModelTrait; + + /** + * 获取系统分页数据 分类 + * @param array $where + * @return array + */ + public static function systemPage($where = array()){ + $model = new self; + if($where['name'] !== '') $model = $model->where('name','LIKE',"%$where[name]%"); + if($where['status'] !== '') $model = $model->where('status',$where['status']); + return self::page($model); + } +} \ No newline at end of file diff --git a/application/admin/model/wechat/WechatUser.php b/application/admin/model/wechat/WechatUser.php new file mode 100644 index 00000000..3a0f928e --- /dev/null +++ b/application/admin/model/wechat/WechatUser.php @@ -0,0 +1,294 @@ + + * @day: 2017/11/28 + */ + +namespace app\admin\model\wechat; + + +use app\admin\model\order\StoreOrder; +use app\admin\model\user\User; +use app\admin\model\user\UserExtract; +use service\ExportService; +use service\QrcodeService; +use think\Cache; +use think\Config; +use traits\ModelTrait; +use basic\ModelBasic; +use service\WechatService; +use service\PHPExcelService; +use service\SystemConfigService; + +/** + * 微信用户 model + * Class WechatUser + * @package app\admin\model\wechat + */ + class WechatUser extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + /** + * 用uid获得openid + * @param $uid + * @return mixed + */ + public static function uidToOpenid($uid,$update = false) + { + $cacheName = 'openid_'.$uid; + $openid = Cache::get($cacheName); + if($openid && !$update) return $openid; + $openid = self::where('uid',$uid)->value('openid'); + if(!$openid) exception('对应的openid不存在!'); + Cache::set($cacheName,$openid,0); + return $openid; + } + + public static function setAddTimeAttr($value) + { + return time(); + } + + /** + * .添加新用户 + * @param $openid + * @return object + */ + public static function setNewUser($openid) + { + $userInfo = WechatService::getUserInfo($openid); + $userInfo['tagid_list'] = implode(',',$userInfo['tagid_list']); + return self::set($userInfo); + } + + /** + * 更新用户信息 + * @param $openid + * @return bool + */ + public static function updateUser($openid) + { + $userInfo = WechatService::getUserInfo($openid); + $userInfo['tagid_list'] = implode(',',$userInfo['tagid_list']); + return self::edit($userInfo,$openid,'openid'); + } + + /** + * 用户存在就更新 不存在就添加 + * @param $openid + */ + public static function saveUser($openid) + { + self::be($openid,'openid') == true ? self::updateUser($openid) : self::setNewUser($openid); + } + + /** + * 用户取消关注 + * @param $openid + * @return bool + */ + public static function unSubscribe($openid) + { + return self::edit(['subscribe'=>0],$openid,'openid'); + } + + /** + * 获取微信用户 + * @param array $where + * @return array + */ + public static function systemPage($where = array(),$isall=false){ + self::setWechatUserOrder();//设置 一级推荐人 二级推荐人 一级推荐人订单 二级推荐人订单 佣金 + $model = new self; + if($isall==false) { + $status = (int)SystemConfigService::get('store_brokerage_statu'); + if ($status == 1) { + if ($uids = User::where(['is_promoter' => 1])->column('uid')) { + $model = $model->where('uid', 'in', implode(',', $uids)); + } + } + } + $model = $model->where('openid','NOT NULL'); + if($where['nickname'] !== '') $model = $model->where('nickname','LIKE',"%$where[nickname]%"); + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('add_time','>',strtotime($startTime)); + $model = $model->where('add_time','<',strtotime($endTime)); + } + if(isset($where['tagid_list']) && $where['tagid_list'] !== ''){ + $tagid_list = explode(',',$where['tagid_list']); + foreach ($tagid_list as $v){ + $model = $model->where('tagid_list','LIKE',"%$v%"); + } + } + if(isset($where['groupid']) && $where['groupid'] !== '-1' ) $model = $model->where('groupid',"$where[groupid]"); + if(isset($where['sex']) && $where['sex'] !== '' ) $model = $model->where('sex',"$where[sex]"); + if(isset($where['subscribe']) && $where['subscribe'] !== '' ) $model = $model->where('subscribe',"$where[subscribe]"); + if(isset($where['stair']) && $where['stair'] != '') $model = $model->order($where['stair']); + if(isset($where['second']) && $where['second'] != '') $model = $model->order($where['second']); + if(isset($where['order_stair']) && $where['order_stair'] != '') $model = $model->order($where['order_stair']); + if(isset($where['order_second']) && $where['order_second'] != '') $model = $model->order($where['order_second']); + if(isset($where['now_money']) && $where['now_money'] != '') $model = $model->order($where['now_money']); + $model = $model->order('uid desc'); + if(isset($where['export']) && $where['export'] == 1){ + $list = $model->select()->toArray(); + $export = []; + foreach ($list as $index=>$item){ + $export[] = [ + $item['nickname'], + $item['sex'], + $item['country'].$item['province'].$item['city'], + $item['stair'], + $item['second'], + $item['order_stair'], + $item['order_second'], + $item['now_money'], + $item['subscribe'] == 1? '关注':'未关注', + ]; + $list[$index] = $item; + } + PHPExcelService::setExcelHeader(['名称','性别','地区','一级推荐人','二级推荐人','一级推荐订单个数','二级推荐订单个数','获得佣金','是否关注公众号']) + ->setExcelTile('微信用户导出','微信用户导出'.time(),' 生成时间:'.date('Y-m-d H:i:s',time())) + ->setExcelContent($export) + ->ExcelSave(); + } + return self::page($model,function ($item){ + $item['qr_code'] = QrcodeService::getForeverQrcode('spread',$item['uid']); + $item['extract_count_price'] = UserExtract::getUserCountPrice($item['uid']);//累计提现 + $item['extract_count_num'] = UserExtract::getUserCountNum($item['uid']);//提现次数 +// $item['qr_code'] = ''; + },$where); + } + + /** + * 获取筛选后的所有用户uid + * @param array $where + * @return array + */ + public static function getAll($where = array()){ + $model = new self; + if($where['nickname'] !== '') $model = $model->where('nickname','LIKE',"%$where[nickname]%"); + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('add_time','>',strtotime($startTime)); + $model = $model->where('add_time','<',strtotime($endTime)); + } + if($where['tagid_list'] !== ''){ + $model = $model->where('tagid_list','LIKE',"%$where[tagid_list]%"); + } + if($where['groupid'] !== '-1' ) $model = $model->where('groupid',"$where[groupid]"); + if($where['sex'] !== '' ) $model = $model->where('sex',"$where[sex]"); + return $model->column('uid','uid'); + } + + /** + * 获取已关注的用户 + * @param $field + */ + public static function getSubscribe($field){ + return self::where('subscribe',1)->column($field); + } + + public static function getUserAll($field){ + return self::column($field); + } + + public static function getUserTag() + { + $tagName = Config::get('system_wechat_tag'); + return Cache::tag($tagName)->remember('_wechat_tag',function () use($tagName){ + Cache::tag($tagName,['_wechat_tag']); + $tag = WechatService::userTagService()->lists()->toArray()['tags']?:array(); + $list = []; + foreach ($tag as $g){ + $list[$g['id']] = $g; + } + return $list; + }); + } + + public static function clearUserTag() + { + Cache::rm('_wechat_tag'); + } + + public static function getUserGroup() + { + $tagName = Config::get('system_wechat_tag'); + return Cache::tag($tagName)->remember('_wechat_group',function () use($tagName){ + Cache::tag($tagName,['_wechat_group']); + $tag = WechatService::userGroupService()->lists()->toArray()['groups']?:array(); + $list = []; + foreach ($tag as $g){ + $list[$g['id']] = $g; + } + return $list; + }); + } + + public static function clearUserGroup() + { + Cache::rm('_wechat_group'); + } + + /** + * 获取推广人数 + * @param $uid //用户的uid + * @param int $spread + * $spread 0 一级推广人数 1 二级推广人数 + * @return int|string + */ + public static function getUserSpreadUidCount($uid,$spread = 1){ + $userStair = User::where('spread_uid',$uid)->column('uid','uid');//获取一级推家人 + if($userStair){ + if(!$spread) return count($userStair);//返回一级推人人数 + else return User::where('spread_uid','IN',implode(',',$userStair))->count();//二级推荐人数 + }else return 0; + } + + /** + * 获取推广人的订单 + * @param $uid + * @param int $spread + * $spread 0 一级推广总订单 1 所有推广总订单 + * @return int|string + */ + public static function getUserSpreadOrderCount($uid,$spread = 1){ + $userStair = User::where('spread_uid',$uid)->column('uid','uid');//获取一级推家人uid + if($userStair){ + if(!$spread){ + return StoreOrder::where('uid','IN',implode(',',$userStair))->where('paid',1)->where('refund_status',0)->where('status',2)->count();//获取一级推广人订单数 + } + else{ + $userSecond = User::where('spread_uid','IN',implode(',',$userStair))->column('uid','uid');//二级推广人的uid + if($userSecond){ + return StoreOrder::where('uid','IN',implode(',',$userSecond))->where('paid',1)->where('refund_status',0)->where('status',2)->count();//获取二级推广人订单数 + }else return 0; + } + }else return 0; + } + + /** + * 同步微信用户表内的 一级推荐人 二级推荐人 一级推荐人订单 二级推荐人订单 + */ + public static function setWechatUserOrder(){ + $uidAll = self::column('uid','uid'); + $item = []; + foreach ($uidAll as $k=>$v){ + $item['stair'] = self::getUserSpreadUidCount($v,0);//一级推荐人 + $item['second'] = self::getUserSpreadUidCount($v);//二级推荐人 + $item['order_stair'] = self::getUserSpreadOrderCount($v,0);//一级推荐人订单 + $item['order_second'] = self::getUserSpreadOrderCount($v);//二级推荐人订单 + $item['now_money'] = User::where('uid',$v)->value('now_money');//佣金 + if(!$item['stair'] && !$item['second'] && !$item['order_stair'] && !$item['order_second'] && !$item['now_money']) continue; + else self::edit($item,$v); + } + } + + + +} \ No newline at end of file diff --git a/application/admin/readme.txt b/application/admin/readme.txt new file mode 100644 index 00000000..7630a00a --- /dev/null +++ b/application/admin/readme.txt @@ -0,0 +1,11 @@ + +store 产品 +order 订单 +user 会员 +wechat 微信用户 +record 数据 +finance 财务 +ump 营销 +system 设置 +article 内容 +server 升级服务器版 \ No newline at end of file diff --git a/application/admin/view/agent/agent_manage/index.php b/application/admin/view/agent/agent_manage/index.php new file mode 100644 index 00000000..2cc21454 --- /dev/null +++ b/application/admin/view/agent/agent_manage/index.php @@ -0,0 +1,592 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + + + +{/block} +{block name="content"} +
+
+
+ +
+
+
+
+ +
+ 选择时间: + + + + + + +
+ +
+ + + + + + + + + + + +
+
+
+ + +
+
+ + + + + + + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + {if condition="$count"} + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + + + {/volist} + {else/} + + {/if} + +
+
+ + +
+
编号微信用户名称头像用户类型 +
+ + +
+
地区 +
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
推广二维码累计提现金额可提现金额提现次数
+ + + {$vo.uid} + + {$vo.nickname} + + {$vo.nickname} + + {if condition="$vo['user_type'] eq 'routine'"} + 小程序授权 + {else/} + 公众号授权 + {/if} + + {if condition="$vo['sex'] eq 1"} + 男 + {elseif condition="$vo['sex'] eq 2"/} + 女 + {else/} + 保密 + {/if} + + {$vo.country}{$vo.province}{$vo.city} + + + + {$vo.second} + + {$vo.order_stair} + + {$vo.order_second} + + + + {if condition="$vo['subscribe']"} + 关注 + {else/} + 未关注 + {/if} + + {if condition="$vo['user_type'] eq 'routine'"} + 暂无 + {else/} + {$vo.nickname} + {/if} + + {$vo.extract_count_price} + + {$vo.now_money} + + {$vo.extract_count_num} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/agent/agent_manage/now_money.php b/application/admin/view/agent/agent_manage/now_money.php new file mode 100644 index 00000000..ad8aa247 --- /dev/null +++ b/application/admin/view/agent/agent_manage/now_money.php @@ -0,0 +1,45 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + {/volist} + +
金额收入/支出记录时间
+ {$vo.number} + + {if condition="$vo['pm']"} + 收入 + {else/} + 支出 + {/if} + + {$vo.mark} + + {$vo.add_time} +
+
+
+
+
+
+{/block} diff --git a/application/admin/view/agent/agent_manage/stair.php b/application/admin/view/agent/agent_manage/stair.php new file mode 100644 index 00000000..8214cf7c --- /dev/null +++ b/application/admin/view/agent/agent_manage/stair.php @@ -0,0 +1,45 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
用户头像用户名称绑定时间订单个数获得佣金
+ {$vo.nickname} + + {$vo.nickname} + + {$vo.add_time|date="Y-m-d H:i:s",###} + + {$vo.uid|getOrderCount} + + {$vo.now_money} +
+
+
+
+
+
+{/block} diff --git a/application/admin/view/article/article/create.php b/application/admin/view/article/article/create.php new file mode 100644 index 00000000..d2707fc5 --- /dev/null +++ b/application/admin/view/article/article/create.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="head_top"} {/block} {block name="content"}
文章列表
{if condition="$news['image_input']"}
{else/}
{/if}
文章内容编辑
标题
作者
文章分类 {volist name="all" id="vo" key="k"} {if condition="$key eq $cid"} {elseif condition="in_array($key,$news['cid'])"} {else/} {/if} {/volist}
{if condition="$news['image_input']"}
{else/}
{/if}

封面大图片建议尺寸:900像素 * 500像素



{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/article/article/index.php b/application/admin/view/article/article/index.php new file mode 100644 index 00000000..c6203064 --- /dev/null +++ b/application/admin/view/article/article/index.php @@ -0,0 +1,92 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+
+ + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
id分类图片标题简介操作
{$vo.id}{$vo.catename} + + {$vo.title} + {$vo.synopsis} + + 编辑 + 删除 +
+
+
+
+
+
+ {include file="public/inner_page"} +
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/article/article/merchantindex.php b/application/admin/view/article/article/merchantindex.php new file mode 100644 index 00000000..e08849e3 --- /dev/null +++ b/application/admin/view/article/article/merchantindex.php @@ -0,0 +1,72 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+
+ {volist name="list" id="vo"} +
+
+
+ + + 编辑 + 删除 +
+
+

{$vo.admin_name}  {$vo.title}

+
+
+
+
+
+ {/volist} +
+
+
+
+
+ {include file="public/inner_page"} +
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/article/article_category/index.php b/application/admin/view/article/article_category/index.php new file mode 100644 index 00000000..63e2906a --- /dev/null +++ b/application/admin/view/article/article_category/index.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="content"}
{volist name="list" id="vo"} {/volist}
编号 分类昵称 分类图片 状态 查看文章 操作
{$vo.id} {$vo.title} {$vo.title} {if condition="$vo['status'] eq 1"} {else/} {/if} 查看文章
{include file="public/inner_page"}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/finance/finance/bill.php b/application/admin/view/finance/finance/bill.php new file mode 100644 index 00000000..a3ebdb38 --- /dev/null +++ b/application/admin/view/finance/finance/bill.php @@ -0,0 +1,102 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
搜索条件
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
-
+
+ +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
资金监控日志
+
+
+ +
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/finance/finance/commission_list.php b/application/admin/view/finance/finance/commission_list.php new file mode 100644 index 00000000..754ac1ae --- /dev/null +++ b/application/admin/view/finance/finance/commission_list.php @@ -0,0 +1,81 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
搜索
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
-
+
+ +
+
+
+ +
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
佣金记录列表
+
+ +
+ +
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/finance/finance/content_info.php b/application/admin/view/finance/finance/content_info.php new file mode 100644 index 00000000..e61eea26 --- /dev/null +++ b/application/admin/view/finance/finance/content_info.php @@ -0,0 +1,172 @@ +{extend name="public/container"} +{block name="content"} + +
+
+
+
+
搜索 + +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
-
+
+ +
+
+
+
+ +
+
+
+
+
+
+
+
+
+
用户信息 + +
+
+
    +
  • +
    +

    姓名

    +

    {$userinfo.nickname}

    +
    +
  • + {if $userinfo.spread_name} +
  • +
    +

    上级推广人

    +

    {$userinfo.spread_name}

    +
    +
  • + {/if} +
  • +
    +

    佣金总输入

    +

    {$userinfo.number}

    +
    +
  • +
  • +
    +

    佣金余额

    +

    {$userinfo.now_money}

    +
    +
  • +
  • +
    +

    创建时间

    +

    {$userinfo.add_time|date='Y-m-d H:i:s',###}

    +
    +
  • +
+
+
+
+
+
+
详情列表
+
+ +
+ +
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/finance/user_extract/index.php b/application/admin/view/finance/user_extract/index.php new file mode 100644 index 00000000..ef1cbc56 --- /dev/null +++ b/application/admin/view/finance/user_extract/index.php @@ -0,0 +1,284 @@ +{extend name="public/container"} + +{block name="content"} + +
+ +
+ +
+ +
+ +
+ +
+
+ + + +
+ + + + + + + +
+ + +
+ + +
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + + + + {/volist} + + + +
编号用户信息提现金额提现方式添加时间备注审核状态操作
+ + {$vo.id} + + + + 用户昵称: {$vo.nickname}/用户id:{$vo.uid} + + + + {$vo.extract_price} + + + 姓名:{$vo.real_name}
+ {if condition="$vo['extract_type'] eq 'bank'"} + + 银行卡号:{$vo.bank_code} +
+ 银行开户地址:{$vo.bank_address} + {else/} + 支付宝号:{$vo.alipay_code} + {/if} +
+ + {$vo.add_time|date='Y-m-d H:i:s',###} + + + {$vo.mark} + + + {if condition="$vo['status'] eq 1"} + + 提现通过
+ + + {elseif condition="$vo['status'] eq -1"/} + + 提现未通过
+ + 未通过原因:{$vo.fail_msg} +
+ 未通过时间:{$vo.fail_time|date='Y-m-d H:i:s',###} + + {else/} + + 未提现
+ + + + + + {/if} + +
+ + + + + +
+ +
+ + {include file="public/inner_page"} + +
+ +
+ +
+ +
+ +{/block} + +{block name="script"} + + + +{/block} + diff --git a/application/admin/view/finance/user_recharge/index.php b/application/admin/view/finance/user_recharge/index.php new file mode 100644 index 00000000..17cdef5c --- /dev/null +++ b/application/admin/view/finance/user_recharge/index.php @@ -0,0 +1,65 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
编号姓名订单编号支付金额支付类型支付时间操作
{$vo.id}{$vo.nickname}{$vo.order_id} + {$vo.price} + {if condition="$vo['refund_price'] GT 0"} +

退款金额:{$vo.refund_price}

+ {/if} +
微信支付{$vo.pay_time|date='Y-m-d H:i:s',###} + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/index/index.php b/application/admin/view/index/index.php new file mode 100644 index 00000000..7f041c65 --- /dev/null +++ b/application/admin/view/index/index.php @@ -0,0 +1,134 @@ + + + + + + + + CRMEB管理系统 + + + + + + + + +
+ + + + +
+
+ + + + + + 返回 + 刷新 +
+ +
+ +
+ + +
+ +
+
+ + + + + + + + +{include file="public/style"} + + + diff --git a/application/admin/view/index/main.php b/application/admin/view/index/main.php new file mode 100644 index 00000000..32b02604 --- /dev/null +++ b/application/admin/view/index/main.php @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ 订单 +
待发货订单数
+
+
+

{$topData.orderDeliveryNum}

+
+
+
+
+
+
+ 订单 +
退换货订单数
+
+
+

{$topData.orderRefundNum}

+
+
+
+
+
+
+ 商品 +
库存预警
+
+
+

{$topData.stockProduct}

+
+
+
+
+
+
+ 用户 +
待处理提现
+
+
+

{$topData.treatedExtract}

+
+
+
+
+
+
+ 订单 +
昨日订单数
+
+
+

{$topData.orderNum}

+
+
+
+
+
+
+ 订单 +
昨日交易额
+
+
+

{$topData.orderPriceNum}

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
订单
+
+
+
+
+
+
+
+
+
+
    +
  • +

    {$first_line.m_price.data}

    + 本月销售额 +
    + {$first_line.m_price.percent}% + {if condition='$first_line.m_price.is_plus egt 0'}{/if} +
    +
    +
    +
    +
  • +
  • +

    {$second_line.order_info.first.data}

    + 本月订单总数 +
    + {$second_line.order_info.first.percent}% + {if condition='$second_line.order_info.first.is_plus egt 0'}{/if} +
    +
    +
    +
    +
  • +
  • +

    {$second_line.order_info.second.data}

    + 上月订单总数 +
    + {$second_line.order_info.second.percent}% + {if condition='$second_line.order_info.second.is_plus egt 0'}{/if} +
    +
    +
    +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
收入
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/application/admin/view/login/index.php b/application/admin/view/login/index.php new file mode 100644 index 00000000..7c4f425e --- /dev/null +++ b/application/admin/view/login/index.php @@ -0,0 +1,73 @@ + + + + + + + 登录 - CRMEB管理系统 + + + + + + + +
+ +
+ + + + + + + + + + \ No newline at end of file diff --git a/application/admin/view/order/store_order/express.php b/application/admin/view/order/store_order/express.php new file mode 100644 index 00000000..0ee4fced --- /dev/null +++ b/application/admin/view/order/store_order/express.php @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + 物流信息 + + + + + + + + + +
+
+
+
+
+
物流公司:{$order.delivery_name}
+
物流单号:{$order.delivery_id}
+
+
+
+ +
+ +

暂无查询记录

+
+ +
    + {volist name="express.result.list" id="vo"} +
  • +
    +

    {$vo.status}

    + {$vo.time} +
    +
  • + {/volist} +
+ +
+
+
+ + diff --git a/application/admin/view/order/store_order/index.php b/application/admin/view/order/store_order/index.php new file mode 100644 index 00000000..d29f34fe --- /dev/null +++ b/application/admin/view/order/store_order/index.php @@ -0,0 +1,667 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + + +{/block} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ 订单状态: + + + + + + + + + +
+
+ 订单类型: + + + + + +
+
+ 创建时间: + + + + + + +
+ +
+ +
+
+
+ + + + + + + + +
+
+
+
+
+
+
+ toArray(); ?> +
+ 售出商品:{$price.total_num} + 订单数量:{$list_num.total} + 订单金额:¥{$price.pay_price} + 退款金额:¥{$price.refund_price} + {if condition="$price['pay_price_wx'] GT 0"} + 微信支付金额:¥{$price.pay_price_wx} + {/if} + {if condition="$price['pay_price_yue'] GT 0"} + 余额支付金额:¥{$price.pay_price_yue} + {/if} + {if condition="$price['pay_price_offline'] GT 0"} + 线下支付金额:¥{$price.pay_price_offline} + {/if} + {if condition="$price['pay_price_other'] GT 0"} + 线下支付金额:¥{$price.pay_price_other} + {/if} + {if condition="$price['use_integral'] GT 0"} + 积分抵扣:{$price.use_integral} (抵扣金额:¥{$price.deduction_price}) + {/if} + {if condition="$price['back_integral'] GT 0"} + 退回积分:{$price.back_integral} + {/if} +
+ +
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
订单号用户信息商品信息 +
+ + + +
+
支付状态订单状态详情操作
+ {$vo.order_id} 
  + {$vo.pink_name}   +
+

{$vo.nickname} / {$vo.uid}

+
+ + {volist name="info_order" id="info"} + {if condition="isset($info['cart_info']['productInfo']['attrInfo']) && !empty($info['cart_info']['productInfo']['attrInfo'])"} +

+ {$info.cart_info.productInfo.store_name} + {$info.cart_info.productInfo.store_name} {$info.cart_info.productInfo.attrInfo.suk} | ¥{$info.cart_info.truePrice}×{$info.cart_info.cart_num} +

+ {else/} +

+ {$info.cart_info.productInfo.store_name} + {$info.cart_info.productInfo.store_name} | ¥{$info.cart_info.truePrice}×{$info.cart_info.cart_num} +

+ {/if} + {/volist} +
+ ¥{$vo.pay_price} + + {if condition="$vo['paid'] eq 1"} +

+ {if condition="$vo['pay_type'] eq 'weixin'"} + 微信支付 + {elseif condition="$vo['pay_type'] eq 'yue'"} + 余额支付 + {elseif condition="$vo['pay_type'] eq 'offline'"} + 线下支付 + {else/} + 其他支付 + {/if} +

+ {else/} + {if condition="$vo['pay_type'] eq 'offline'"} +

线下支付

+

+ + {else/} +

未支付

+ {/if} + {/if} +
+ {if condition="$vo['paid'] eq 0 && $vo['status'] eq 0"} + 未支付 + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 0 && $vo['refund_status'] eq 0"/} + 未发货 + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 1 && $vo['refund_status'] eq 0"/} + 待收货 + + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 2 && $vo['refund_status'] eq 0"/} + 待评价 + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 3 && $vo['refund_status'] eq 0"/} + 交易完成 + {elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 1"/} + 申请退款
+ 退款原因:{$vo.refund_reason_wap} + {elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 2"/} + 已退款 + {/if} +
+ + 订单详情 + + + + {if condition="$vo['paid'] eq 0 && $vo['status'] eq 0 && $vo['refund_status'] eq 0"} + + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 0 && $vo['refund_status'] eq 0"/} + + +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 1"/} +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 1 && $vo['refund_status'] eq 0"/} + +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 2 && $vo['refund_status'] eq 0"/} +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 3 && $vo['refund_status'] eq 0"/} +
+ + +
+{elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 2"/} + +
+ + +
+ {/if} +
+
+
+ {include file="public/inner_page"} +
+
+
+
+ +{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/order/store_order/order_info.php b/application/admin/view/order/store_order/order_info.php new file mode 100644 index 00000000..cd27f3e0 --- /dev/null +++ b/application/admin/view/order/store_order/order_info.php @@ -0,0 +1,138 @@ +{extend name="public/container"} +{block name="content"} +
+ +
+
+
+
+ 收货信息 +
+
+
+
用户昵称: {$userInfo.nickname}
+
收货人: {$orderInfo.real_name}
+
联系电话: {$orderInfo.user_phone}
+
收货地址: {$orderInfo.user_address}
+
+
+
+
+
+
+
+ 订单信息 +
+
+
+
订单编号: {$orderInfo.order_id}
+
订单状态: + {if condition="$orderInfo['paid'] eq 0 && $orderInfo['status'] eq 0"} + 未支付 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 0 && $orderInfo['refund_status'] eq 0"/} + 未发货 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 1 && $orderInfo['refund_status'] eq 0"/} + 待收货 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 2 && $orderInfo['refund_status'] eq 0"/} + 待评价 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 3 && $orderInfo['refund_status'] eq 0"/} + 交易完成 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['refund_status'] eq 1"/} + 申请退款{$orderInfo.refund_reason_wap} + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['refund_status'] eq 2"/} + 已退款 + {/if} +
+
商品总数: {$orderInfo.total_num}
+
商品总价: ¥{$orderInfo.total_price}
+
支付邮费: ¥{$orderInfo.total_postage}
+
实际支付: ¥{$orderInfo.pay_price}
+ {if condition="$orderInfo['refund_price'] GT 0"} +
退款金额: ¥{$orderInfo.refund_price}
+ {/if} + {if condition="$orderInfo['deduction_price'] GT 0"} +
使用积分: {$orderInfo.use_integral}积分(抵扣了¥{$orderInfo.deduction_price})
+ {/if} + {if condition="$orderInfo['back_integral'] GT 0"} +
退回积分: ¥{$orderInfo.back_integral}
+ {/if} +
创建时间: {$orderInfo.add_time|date="Y/m/d H:i",###}
+
支付方式: + {if condition="$orderInfo['paid'] eq 1"} + {if condition="$orderInfo['pay_type'] eq 'weixin'"} + 微信支付 + {elseif condition="$orderInfo['pay_type'] eq 'yue'"} + 余额支付 + {elseif condition="$orderInfo['pay_type'] eq 'offline'"} + 线下支付 + {else/} + 其他支付 + {/if} + {else/} + {if condition="$orderInfo['pay_type'] eq 'offline'"} + 线下支付 + {else/} + 未支付 + {/if} + {/if} +
+ {notempty name="orderInfo.pay_time"} +
支付时间: {$orderInfo.pay_time|date="Y/m/d H:i",###}
+ {/notempty} +
用户备注: {$orderInfo.mark?:'无'}
+
商家备注: {$orderInfo.remark?:'无'}
+
推广人: {if $spread}{$spread}{else}无{/if}
+
+
+
+
+ {if condition="$orderInfo['delivery_type'] eq 'express'"} +
+
+
+ 物流信息 +
+
+
+
快递公司: {$orderInfo.delivery_name}
+
快递单号: {$orderInfo.delivery_id} |
+
+
+
+
+ {elseif condition="$orderInfo['delivery_type'] eq 'send'"} +
+
+
+ 配送信息 +
+
+
+
送货人姓名: {$orderInfo.delivery_name}
+
送货人电话: {$orderInfo.delivery_id}
+
+
+
+
+ {/if} +
+
+
+ 备注信息 +
+
+
+
{if $orderInfo.mark}{$orderInfo.mark}{else}暂无备注信息{/if}
+
+
+
+
+
+
+ + + +{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/order/store_order/order_status.php b/application/admin/view/order/store_order/order_status.php new file mode 100644 index 00000000..dd59f8ec --- /dev/null +++ b/application/admin/view/order/store_order/order_status.php @@ -0,0 +1,79 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
订单编号操作记录操作时间
+ {$vo.oid} + + {$vo.change_message} + + {$vo.change_time|date='Y-m-d H:i:s',###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/order/store_order/orderchart.php b/application/admin/view/order/store_order/orderchart.php new file mode 100644 index 00000000..904f049a --- /dev/null +++ b/application/admin/view/order/store_order/orderchart.php @@ -0,0 +1,278 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+
+ 订单状态: + + + + + + + + + +
+
+ 订单类型: + + + + + +
+
+ 创建时间: + + + + + + +
+ +
+ +
+
+ toArray(); ?> +
+
+ 售出商品:{$price.total_num} +
+
+ 订单数量:{$list_num.total} +
+
+ 订单金额:¥{$price.pay_price} +
+
+ 退款金额:¥{$price.refund_price} +
+
+
+
+
+
+
主要数据统计
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/order/store_order_pink/order_status.php b/application/admin/view/order/store_order_pink/order_status.php new file mode 100644 index 00000000..dd59f8ec --- /dev/null +++ b/application/admin/view/order/store_order_pink/order_status.php @@ -0,0 +1,79 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
订单编号操作记录操作时间
+ {$vo.oid} + + {$vo.change_message} + + {$vo.change_time|date='Y-m-d H:i:s',###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/public/common_form.php b/application/admin/view/public/common_form.php new file mode 100644 index 00000000..c1f3e31c --- /dev/null +++ b/application/admin/view/public/common_form.php @@ -0,0 +1,26 @@ + + + + {include file="public/head"} + {$title|default=''} + + +
+ +
+ + diff --git a/application/admin/view/public/container.php b/application/admin/view/public/container.php new file mode 100644 index 00000000..d9422a6d --- /dev/null +++ b/application/admin/view/public/container.php @@ -0,0 +1,18 @@ + + + + {include file="public/frame_head" /} + {block name="title"}{/block} + {block name="head_top"}{/block} + {include file="public/style" /} + {block name="head"}{/block} + + +
+{block name="content"}{/block} +{block name="foot"}{/block} +{block name="script"}{/block} +{include file="public/frame_footer" /} +
+ + diff --git a/application/admin/view/public/edit_content.php b/application/admin/view/public/edit_content.php new file mode 100644 index 00000000..0e47f324 --- /dev/null +++ b/application/admin/view/public/edit_content.php @@ -0,0 +1,67 @@ + + + + + + + + 编辑内容 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/admin/view/public/error.php b/application/admin/view/public/error.php new file mode 100644 index 00000000..48b3c66b --- /dev/null +++ b/application/admin/view/public/error.php @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/admin/view/public/exception.php b/application/admin/view/public/exception.php new file mode 100644 index 00000000..9daa6452 --- /dev/null +++ b/application/admin/view/public/exception.php @@ -0,0 +1,40 @@ + + + + + + + 404错误 + + + + +
+
+
+

+ 404{$msg} +

+
+
+

可能原因:

+
    +
  1. 页面加载失败
  2. +
  3. 找不到请求的页面
  4. +
  5. 输入的网址不正确
  6. +
+
+
+

可以尝试:

+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/application/admin/view/public/foot.php b/application/admin/view/public/foot.php new file mode 100644 index 00000000..ac6772ce --- /dev/null +++ b/application/admin/view/public/foot.php @@ -0,0 +1,3 @@ +
+ 2017 © crmEb +
\ No newline at end of file diff --git a/application/admin/view/public/form-builder.php b/application/admin/view/public/form-builder.php new file mode 100644 index 00000000..16f3c077 --- /dev/null +++ b/application/admin/view/public/form-builder.php @@ -0,0 +1,29 @@ + + + + + <?=$form->getTitle()?> + getScript())?> + + + + + + \ No newline at end of file diff --git a/application/admin/view/public/frame_footer.php b/application/admin/view/public/frame_footer.php new file mode 100644 index 00000000..e69de29b diff --git a/application/admin/view/public/frame_head.php b/application/admin/view/public/frame_head.php new file mode 100644 index 00000000..b7835472 --- /dev/null +++ b/application/admin/view/public/frame_head.php @@ -0,0 +1,22 @@ + + + + {empty name='is_layui'} + + {/empty} + + + + + + + + + + + diff --git a/application/admin/view/public/head.php b/application/admin/view/public/head.php new file mode 100644 index 00000000..dac63cd7 --- /dev/null +++ b/application/admin/view/public/head.php @@ -0,0 +1,9 @@ + + + + +{include file="public/style"} + \ No newline at end of file diff --git a/application/admin/view/public/inner_footer.php b/application/admin/view/public/inner_footer.php new file mode 100644 index 00000000..a05e5dfc --- /dev/null +++ b/application/admin/view/public/inner_footer.php @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/admin/view/public/inner_page.php b/application/admin/view/public/inner_page.php new file mode 100644 index 00000000..bc1b90ee --- /dev/null +++ b/application/admin/view/public/inner_page.php @@ -0,0 +1,11 @@ + +
+
+ +
+
+
+ {$page} +
+
+
\ No newline at end of file diff --git a/application/admin/view/public/notice.php b/application/admin/view/public/notice.php new file mode 100644 index 00000000..349f7187 --- /dev/null +++ b/application/admin/view/public/notice.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/application/admin/view/public/style.php b/application/admin/view/public/style.php new file mode 100644 index 00000000..7d08ddce --- /dev/null +++ b/application/admin/view/public/style.php @@ -0,0 +1,42 @@ + + + */ ?> + + \ No newline at end of file diff --git a/application/admin/view/public/success.php b/application/admin/view/public/success.php new file mode 100644 index 00000000..964bcb68 --- /dev/null +++ b/application/admin/view/public/success.php @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/admin/view/record/record/chart_bargain.php b/application/admin/view/record/record/chart_bargain.php new file mode 100644 index 00000000..f5f554ac --- /dev/null +++ b/application/admin/view/record/record/chart_bargain.php @@ -0,0 +1,315 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
图表展示:
+
+
+
+
+
+
+
+
+
+
销量排行 TOP10
+
+

商品销售总计:{{SalesList.sum_count}} 件 共计 {{SalesList.sum_price}}

+
+ {{item.store_name}} +
+
{{item.p_count}}
+
+
+
+
+
+
+
+
利润排行 TOP10
+
+

商品销售总计:{{ProfityList.sum_count}} 件 共计 {{ProfityList.sum_price}}

+ + + + + + + + + + + + + + + + + +
商品名称销量占比(%)购买个数利润(¥)
{{item.store_name}} {{item.w}}{{item.p_count}} {{item.sum_price}}
+
+
+
+
+
+
+
退货产品
+
+ + + + + + + + + + + + + + + + + +
商品名称单价退货数量操作
{{item.store_name}}{{item.sum_price}}{{item.count}}
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_cash.php b/application/admin/view/record/record/chart_cash.php new file mode 100644 index 00000000..9e6ffc1c --- /dev/null +++ b/application/admin/view/record/record/chart_cash.php @@ -0,0 +1,177 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
提现统计
+
+
+
+
+
+
+
+
+
+
提现方式
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_combination.php b/application/admin/view/record/record/chart_combination.php new file mode 100644 index 00000000..3c5e347f --- /dev/null +++ b/application/admin/view/record/record/chart_combination.php @@ -0,0 +1,267 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
图表展示:
+
+
+
+
+
+
+
+
+
+
销量排行 TOP10
+
+

商品销售总计:{{SalesList.sum_count}} 件 共计 {{SalesList.sum_price}}

+
+ {{item.store_name}} +
+
{{item.p_count}}
+
+
+
+
+
+
+
+
利润排行 TOP10
+
+

商品销售总计:{{ProfityList.sum_count}} 件 共计 {{ProfityList.sum_price}}

+ + + + + + + + + + + + + + + + + +
商品名称销量占比(%)购买个数利润(¥)
{{item.store_name}} {{item.w}}{{item.p_count}} {{item.sum_price}}
+
+
+
+
+
+
+
退货产品
+
+ + + + + + + + + + + + + + + + + +
商品名称单价退货数量操作
{{item.store_name}}{{item.sum_price}}{{item.count}}
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_coupon.php b/application/admin/view/record/record/chart_coupon.php new file mode 100644 index 00000000..32499884 --- /dev/null +++ b/application/admin/view/record/record/chart_coupon.php @@ -0,0 +1,177 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+
+
+ +
+ + + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
发放优惠券:
+
+
+
+
+
+
+
+
+
+
使用优惠券:
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_order.php b/application/admin/view/record/record/chart_order.php new file mode 100644 index 00000000..58522870 --- /dev/null +++ b/application/admin/view/record/record/chart_order.php @@ -0,0 +1,262 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
图表展示:
+
+
+
+
+
+
+
+
+
+
交易类型:
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_product.php b/application/admin/view/record/record/chart_product.php new file mode 100644 index 00000000..8ecfdce7 --- /dev/null +++ b/application/admin/view/record/record/chart_product.php @@ -0,0 +1,350 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
图表展示:
+
+
+
+
+
+
+
+
+
+
销量排行 TOP10
+
+

商品销售总计:{{SalesList.sum_count}} 件 共计 {{SalesList.sum_price}}

+
+ {{item.store_name}} +
+
{{item.p_count}}
+
+
+
+
+
+
+
+
利润排行 TOP10
+
+

商品销售总计:{{ProfityList.sum_count}} 件 共计 {{ProfityList.sum_price}}

+ + + + + + + + + + + + + + + + + +
商品名称销量占比(%)购买个数利润(¥)
{{item.store_name}} {{item.w}}{{item.p_count}} {{item.sum_price}}
+
+
+
+
+
+
+
待补货商品
+
+

注:库存列可进行快速编辑,点击当前页面空白保存编辑

+
+ +
+
+
+
+
+
差评产品
+
+ + + + + + + + + + + + + + + + + +
商品名称单价差评数量操作
{{item.store_name}}{{item.price}}{{item.count}}
+
+
+
+
+
+
退货产品
+
+ + + + + + + + + + + + + + + + + +
商品名称单价退货数量操作
{{item.store_name}}{{item.price}}{{item.count}}
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_rebate.php b/application/admin/view/record/record/chart_rebate.php new file mode 100644 index 00000000..5073be57 --- /dev/null +++ b/application/admin/view/record/record/chart_rebate.php @@ -0,0 +1,266 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
返佣图表
+
+
+
+
+
+
+
+
+
+
返佣分布
+
+
+
+
+
+
+
+
+
+
返佣列表
+
+ + + + + + + + + + + + + + + + + + +
返佣商返佣级别返佣金额
+ +
+
+

订单编号:{{item.order_id}}

+

返利时间:{{item.add_time}}

+

买 家 I D:{{item.down_uid}}

+

上 级 I D:{{item.spread_uid}}

+
+
+
+
+

会员ID:{{item.uid}}

+

昵 称:{{item.nickname}}

+
+
+
{{item.level==0? '顶级':item.level+'级分销'}}{{item.number}}
暂无数据
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_recharge.php b/application/admin/view/record/record/chart_recharge.php new file mode 100644 index 00000000..62bb81f1 --- /dev/null +++ b/application/admin/view/record/record/chart_recharge.php @@ -0,0 +1,166 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
充值笔数
+
+
+
+
+
+
+
+
+
+
充值金额
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_score.php b/application/admin/view/record/record/chart_score.php new file mode 100644 index 00000000..4c48c10b --- /dev/null +++ b/application/admin/view/record/record/chart_score.php @@ -0,0 +1,173 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+
+
+ +
+ + + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
发放积分:
+
+
+
+
+
+
+
+
+
+
使用积分:
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/chart_seckill.php b/application/admin/view/record/record/chart_seckill.php new file mode 100644 index 00000000..d577232d --- /dev/null +++ b/application/admin/view/record/record/chart_seckill.php @@ -0,0 +1,301 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
图表展示:
+
+
+
+
+
+
+
+
+
+
销量排行 TOP10
+
+

商品销售总计:{{SalesList.sum_count}} 件 共计 {{SalesList.sum_price}}

+
+ {{item.store_name}} +
+
{{item.p_count}}
+
+
+
+
+
+
+
+
利润排行 TOP10
+
+

商品销售总计:{{ProfityList.sum_count}} 件 共计 {{ProfityList.sum_price}}

+ + + + + + + + + + + + + + + + + +
商品名称销量占比(%)购买个数利润(¥)
{{item.store_name}} {{item.w}}{{item.p_count}} {{item.sum_price}}
+
+
+
+
+
+
+
退货产品
+
+ + + + + + + + + + + + + + + + + +
商品名称单价退货数量操作
{{item.store_name}}{{item.sum_price}}{{item.count}}
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/product_info.php b/application/admin/view/record/record/product_info.php new file mode 100644 index 00000000..ddb8b8ea --- /dev/null +++ b/application/admin/view/record/record/product_info.php @@ -0,0 +1,231 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+
+
+ +
+ + + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
发放优惠券:
+
+
+
+
+
+
+
+
+
+
销售记录:
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
序号时间会员昵称商品单价(元)购买数量销售总额(元)
{{item.id}}{{item._add_time}}{{item.nickname}}{{item.price}}{{item.num}}{{item.price*item.num}}
暂无数据
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/ranking_commission.php b/application/admin/view/record/record/ranking_commission.php new file mode 100644 index 00000000..31544618 --- /dev/null +++ b/application/admin/view/record/record/ranking_commission.php @@ -0,0 +1,139 @@ +{extend name="public/container"} +{block name="head_top"} +{/block} +{block name="content"} +
+
+
+
+
总佣金排名
+
+ + + + + + + + + + + + + + + + + + + + +
排名昵称/手机号收入佣金佣金余额
{{page==1 ?index+1:(index+1)+(page-1)*limit}}{{item.real_name}}{{item.extract_price}}{{item.balance}}
暂无数据
+
+
+
+
+
+
+
本月佣金排名
+
+ + + + + + + + + + + + + + + + + + + + +
排名昵称/手机号收入佣金佣金余额
{{page==1 ?index+1:(index+1)+(monthpage-1)*limit}}{{item.real_name}}{{item.extract_price}}{{item.balance}}
暂无数据
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/ranking_point.php b/application/admin/view/record/record/ranking_point.php new file mode 100644 index 00000000..d3392a19 --- /dev/null +++ b/application/admin/view/record/record/ranking_point.php @@ -0,0 +1,135 @@ +{extend name="public/container"} +{block name="head_top"} +{/block} +{block name="content"} +
+
+
+
+
当前积分排名
+
+ + + + + + + + + + + + + + + + + + +
排名昵称/手机号当前积分
{{page==1 ?index+1:(index+1)+(page-1)*limit}}{{item.nickname}}{{item.integral}}
暂无数据
+
+
+
+
+
+
+
本月积分排名
+
+ + + + + + + + + + + + + + + + + + +
排名昵称/手机号当前积分
{{page==1 ?index+1:(index+1)+(monthpage-1)*limit}}{{item.nickname}}{{item.integral}}
暂无数据
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/ranking_saleslists.php b/application/admin/view/record/record/ranking_saleslists.php new file mode 100644 index 00000000..80cfbfe3 --- /dev/null +++ b/application/admin/view/record/record/ranking_saleslists.php @@ -0,0 +1,98 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
搜索条件
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
-
+
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
资金监控日志
+
+
+ + +
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/user_attr.php b/application/admin/view/record/record/user_attr.php new file mode 100644 index 00000000..f48d7b1c --- /dev/null +++ b/application/admin/view/record/record/user_attr.php @@ -0,0 +1,159 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
地区分布
+
+
+
+
+
+
+
+
+
+
性别分布
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/user_business_chart.php b/application/admin/view/record/record/user_business_chart.php new file mode 100644 index 00000000..ca3ef36d --- /dev/null +++ b/application/admin/view/record/record/user_business_chart.php @@ -0,0 +1,364 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
购物会员统计
+
+
+
+
+
+
+
+
+
+
会员访问统计
+
+
+
+
+
+
+
+
+
+
购物会员数量饼状图
+
+
+
+
+
+
+
+
+
+
+
会员积分排行榜 TOP{$limit}
+
+ + + + + + + + + + + {volist name='integralList' id='vo'} + + + + + + + {/volist} + +
排名昵称/手机会员积分注册时间
{$key+1}{$vo.nickname}/{$vo.phone}{$vo.integral}{$vo.add_time}
+
+
+
+
+
+
会员余额排行榜 TOP{$limit}
+
+ + + + + + + + + + + {volist name='moneyList' id='vo'} + + + + + + + {/volist} + +
排名昵称/手机会员余额注册时间
{$key+1}{$vo.nickname}/{$vo.phone}{$vo.now_money}{$vo.add_time}
+
+
+
+
+
+
+
+
购物笔数排行榜 TOP{$limit}
+
+ + + + + + + + + + + {volist name='shopcountList' id='vo'} + + + + + + + {/volist} + +
排名昵称/手机购物次数注册时间
{$key+1}{$vo.nickname}/{$vo.phone}{$vo.sum_count}{$vo.add_time}
+
+
+
+
+
+
购物金额 TOP{$limit}
+
+ + + + + + + + + + + {volist name='orderList' id='vo'} + + + + + + + {/volist} + +
排名昵称/手机购物金额注册时间
{$key+1}{$vo.nickname}/{$vo.phone}{$vo.sum_price}{$vo.add_time}
+
+
+
+
+
+
+
+
上月消费排行榜 TOP{$limit}
+
+ + + + + + + + + + + {volist name='lastorderList' id='vo'} + + + + + + + {/volist} + +
排名昵称/手机消费金额注册时间
{$key+1}{$vo.nickname}/{$vo.phone}{$vo.sum_price}{$vo.add_time}
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/user_chart.php b/application/admin/view/record/record/user_chart.php new file mode 100644 index 00000000..1ecda07a --- /dev/null +++ b/application/admin/view/record/record/user_chart.php @@ -0,0 +1,206 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
会员统计
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/record/user_distribution_chart.php b/application/admin/view/record/record/user_distribution_chart.php new file mode 100644 index 00000000..2af9c32c --- /dev/null +++ b/application/admin/view/record/record/user_distribution_chart.php @@ -0,0 +1,281 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
搜索条件
+
+ +
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
分销会员统计
+
+
+
+
+
+
+
+
+
+
分销会员浏览统计
+
+
+
+
+
+
+
+
+
+
分销商数量饼状图
+
+
+
+
+
+
+
+
+
+
多次购物会员数量饼状图
+
+
+
+
+
+
+
+
+
+
+
分销商佣金总额排行榜 TOP{$limit}
+
+ + + + + + + + + + + {volist name='commissionList' id='vo'} + + + + + + + {/volist} + +
排名昵称/手机佣金注册时间
{$key+1}{$vo.nickname}/{$vo.phone}{$vo.sum_number}{$vo.add_time}
+
+
+
+
+
+
分销商佣金提现排行榜 TOP{$limit}
+
+ + + + + + + + + + + {volist name='extractList' id='vo'} + + + + + + + {/volist} + +
排名昵称/手机购物次数注册时间
{$key+1}{$vo.nickname}/{$vo.phone}{$vo.sum_price}{$vo.add_time}
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/record/store_statistics/index.php b/application/admin/view/record/store_statistics/index.php new file mode 100644 index 00000000..3005dd0c --- /dev/null +++ b/application/admin/view/record/store_statistics/index.php @@ -0,0 +1,443 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + +{/block} +{block name="content"} + +
+
+
+
+
+
+
+ 创建时间: + 全部 + 今天 + 本周 + 本月 + 本季度 + 本年 +
+ 自定义 +
+
+ +
+
+
+
+
+
+
+
+ {volist name='header' id='val'} +
+
+
+
+ +
+
+ {$val.name} +

{$val.value}

+
+
+
+ +
+ {/volist} +
+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
主要数据统计
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
支付方式
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
支出详情
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
营收详情
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
最近交易记录
+
+ + + + + + +
+
+
+
+ {volist name="trans" id="vo"} +

{$vo.nickname}

+

购买{$vo.store_name}

+

¥{$vo.pay_price}

+ {/volist} +
+
+
+
+
+
+
+
+
+ +
+ {if condition="$price['pay_price_wx'] GT 0"} +
+ 微信支付金额:¥{$price.pay_price_wx} +
+ {/if} + {if condition="$price['pay_price_yue'] GT 0"} +
+ 余额支付金额:¥{$price.pay_price_yue} +
+ {/if} + {if condition="$price['pay_price_offline'] GT 0"} +
+ 线下支付金额:¥{$price.pay_price_offline} +
+ {/if} +
+
+
+ + Excel导出 + +
+
+
+
+
+ + + +{/block} diff --git a/application/admin/view/routine/routine_template/index.php b/application/admin/view/routine/routine_template/index.php new file mode 100644 index 00000000..8525d0aa --- /dev/null +++ b/application/admin/view/routine/routine_template/index.php @@ -0,0 +1,101 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
编号模板编号模板ID模板名回复内容状态添加时间操作
+ {$vo.id} + + {$vo.tempkey} + + {$vo.tempid} + + {$vo.name} + +
{$vo.content}
+
+ + + {$vo.add_time|date='Y-m-d H:i:s',###} + + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/setting/system_admin/admininfo.php b/application/admin/view/setting/system_admin/admininfo.php new file mode 100644 index 00000000..166cc784 --- /dev/null +++ b/application/admin/view/setting/system_admin/admininfo.php @@ -0,0 +1,131 @@ +{extend name="public/container"} +{block name="head"} + + + + + +{/block} +{block name="content"} +
+
+
+
+
个人资料
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+ +
+ +
+
+{/block} +{block name="script"} + + +{/block} \ No newline at end of file diff --git a/application/admin/view/setting/system_admin/create.php b/application/admin/view/setting/system_admin/create.php new file mode 100644 index 00000000..53735339 --- /dev/null +++ b/application/admin/view/setting/system_admin/create.php @@ -0,0 +1,27 @@ + + + + {include file="public/head"} + {$title} + + +
+ +
+ + diff --git a/application/admin/view/setting/system_admin/edit.php b/application/admin/view/setting/system_admin/edit.php new file mode 100644 index 00000000..9bc3f837 --- /dev/null +++ b/application/admin/view/setting/system_admin/edit.php @@ -0,0 +1,87 @@ + + + + {include file="public/head"} + {$title} + + +
+ + + + + + + + + + 北京市 + 上海市 + 深圳市 + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 提交 + 重置 + + + + */ ?> + + +
+ + diff --git a/application/admin/view/setting/system_admin/index.php b/application/admin/view/setting/system_admin/index.php new file mode 100644 index 00000000..74e17bc4 --- /dev/null +++ b/application/admin/view/setting/system_admin/index.php @@ -0,0 +1,119 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+ + + + +
+ + +
+ */ ?> +
+ + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
姓名账号身份最后一次登陆时间最后一次登陆ip开启操作
+ {$vo.real_name} + + {$vo.account} + + {$vo.roles} + + {$vo.last_time? date('Y/m/d H:i',$vo.last_time) : ''} + + {$vo.last_ip} + + + + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/setting/system_config/create.php b/application/admin/view/setting/system_config/create.php new file mode 100644 index 00000000..ae489c73 --- /dev/null +++ b/application/admin/view/setting/system_config/create.php @@ -0,0 +1 @@ + {include file="public/head"} {$title}
\ No newline at end of file diff --git a/application/admin/view/setting/system_config/index.php b/application/admin/view/setting/system_config/index.php new file mode 100644 index 00000000..e32a2323 --- /dev/null +++ b/application/admin/view/setting/system_config/index.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="head"} {/block} {block name="content"}
$v){ if(!is_null(json_decode($v['value']))) $list[$k]['value'] = json_decode($v['value'],true); if($v['type'] == 'upload' && !empty($v['value'])){ if($v['upload_type'] == 1 || $v['upload_type'] == 3) $list[$k]['value'] = explode(',',$v['value']); } } $bool_upload_num = 0; ?>
{volist name="list" id="vo"} {eq name="$vo['config_tab_id']" value="$tab_id"}
{switch name="$vo['type']" } {case value="text" break="1"} {/case} {case value="textarea" break="1"} {/case} {case value="checkbox" break="1"} $v){ $option[$k] = explode('=',$v); } // dump($parameter); // exit(); } $checkbox_value = $vo['value']; if(!is_array($checkbox_value)) $checkbox_value = explode("\n",$checkbox_value); // dump($checkbox_value); // exit(); ?> {volist name="option" id="son" key="k"} {if condition="in_array($son[0],$checkbox_value)"} {else/} {/if} {/volist} {/case} {case value="radio" break="1"} $v){ $option[$k] = explode('=',$v); } } ?> {volist name="option" id="son"} {if condition="$son[0] eq $vo['value']"}
{else /}
{/if} {/volist} {/case} {case value="upload" break="1"} {if condition="$vo['upload_type'] EQ 3"}
{if condition="$num_img LT 1"}
{else/} {volist name="$vo['value']" id="img"}
×
{/volist} {/if}
{elseif condition="$vo['upload_type'] EQ 2"/}
{volist name="$vo['value']" id="img"}
image
×
{/volist}
{else/}
{if condition="$num_img LT 1"}
{else/} {volist name="$vo['value']" id="img"}
image
×
{/volist}
{/if}
{/if} {/case} {/switch}
{$vo.desc}
{/eq} {/volist}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/setting/system_config/index_alone.php b/application/admin/view/setting/system_config/index_alone.php new file mode 100644 index 00000000..7e3e2c49 --- /dev/null +++ b/application/admin/view/setting/system_config/index_alone.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="head"} {/block} {block name="content"}
配置
$v){ $list[$k]['value'] = json_decode($v['value'],true); } $bool_upload_num = 0; ?>
{volist name="list" id="vo"} {eq name="$vo['config_tab_id']" value="$tab_id"}
{switch name="$vo['type']" } {case value="text" break="1"} {/case} {case value="textarea" break="1"} {/case} {case value="checkbox" break="1"} $v){ $option[$k] = explode('-',$v); } // dump($option); // exit(); } $checkbox_value = $vo['value']; if(!is_array($checkbox_value)) $checkbox_value = explode(',',$checkbox_value); // dump($checkbox_value); // exit(); ?> {volist name="option" id="son" key="k"} {if condition="in_array($son[0],$checkbox_value)"} {else/} {/if} {/volist} {/case} {case value="radio" break="1"} $v){ $option[$k] = explode('-',$v); } } ?> {volist name="option" id="son"} {if condition="$son[0] eq $vo['value']"}
{else /}
{/if} {/volist} {/case} {case value="upload" break="1"} {if condition="$vo['upload_type'] EQ 3"}
点击上传 {if condition="$num_img LT 1"}
{else/} {volist name="$vo['value']" id="img"}
删除
{/volist} {/if}
{elseif condition="$vo['upload_type'] EQ 2"/}
点击上传
{volist name="$vo['value']" id="img"}
image
删除
{/volist}
{else/}
{if condition="$num_img LT 1"}
{else/} {volist name="$vo['value']" id="img"}
image
删除
{/volist}
{/if}
{/if} {/case} {/switch}
{$vo.desc}
{/eq} {/volist}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/setting/system_config_tab/create.php b/application/admin/view/setting/system_config_tab/create.php new file mode 100644 index 00000000..4ac4781e --- /dev/null +++ b/application/admin/view/setting/system_config_tab/create.php @@ -0,0 +1 @@ + {include file="public/head"} {$title}
\ No newline at end of file diff --git a/application/admin/view/setting/system_config_tab/create_base.php b/application/admin/view/setting/system_config_tab/create_base.php new file mode 100644 index 00000000..adace21f --- /dev/null +++ b/application/admin/view/setting/system_config_tab/create_base.php @@ -0,0 +1 @@ + {include file="public/head"} {$title}
\ No newline at end of file diff --git a/application/admin/view/setting/system_config_tab/edit.php b/application/admin/view/setting/system_config_tab/edit.php new file mode 100644 index 00000000..7e047874 --- /dev/null +++ b/application/admin/view/setting/system_config_tab/edit.php @@ -0,0 +1 @@ + {include file="public/head"} {$title}
\ No newline at end of file diff --git a/application/admin/view/setting/system_config_tab/edit_cinfig.php b/application/admin/view/setting/system_config_tab/edit_cinfig.php new file mode 100644 index 00000000..de4c0cbb --- /dev/null +++ b/application/admin/view/setting/system_config_tab/edit_cinfig.php @@ -0,0 +1 @@ + {include file="public/head"} {$title}
北京市 上海市 深圳市 - 提交 重置 */ ?>
\ No newline at end of file diff --git a/application/admin/view/setting/system_config_tab/index.php b/application/admin/view/setting/system_config_tab/index.php new file mode 100644 index 00000000..32a78e09 --- /dev/null +++ b/application/admin/view/setting/system_config_tab/index.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="content"}
{volist name="list" id="vo"} {/volist}
编号 分类昵称 分类字段 是否显示 操作
{$vo.id} {$vo.title} {$vo.eng_title} {if condition="$vo.status eq 1"} {elseif condition="$vo.status eq 2"/} {/if} {if condition="$vo['id'] gt 2"} {/if}
{include file="public/inner_page"}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/setting/system_config_tab/sonconfigtab.php b/application/admin/view/setting/system_config_tab/sonconfigtab.php new file mode 100644 index 00000000..e2be3a1d --- /dev/null +++ b/application/admin/view/setting/system_config_tab/sonconfigtab.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="content"}
{volist name="list" id="vo"} {/volist}
编号 配置名称 字段变量 字段类型 是否显示 操作
{$vo.id} {$vo.info} {$vo.menu_name} {$vo.type} 2){ if($vo['value']){ foreach ($vo['value'] as $v){ ?>
image
{if condition="$vo.status eq 1"} {elseif condition="$vo.status eq 2"/} {/if}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/setting/system_group/create.php b/application/admin/view/setting/system_group/create.php new file mode 100644 index 00000000..ce913b95 --- /dev/null +++ b/application/admin/view/setting/system_group/create.php @@ -0,0 +1,114 @@ + + + + {include file="public/head"} + {$title} + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + 文本框 + 多行文本框 + 单选框 + 多选框 + 单文件上传 + 多文件上传 + + + + + + + + + + + + + + 添加字段 + + 提交 + + +
+ + diff --git a/application/admin/view/setting/system_group/index.php b/application/admin/view/setting/system_group/index.php new file mode 100644 index 00000000..b5ca90c8 --- /dev/null +++ b/application/admin/view/setting/system_group/index.php @@ -0,0 +1,95 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+ + + + +
+ + +
+ */ ?> +
+ +
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
编号KEY数据组名称简介操作
+ {$vo.id} + + {$vo.config_name} + + {$vo.name} + + {$vo.info} + + 数据列表 + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/setting/system_group_data/create.php b/application/admin/view/setting/system_group_data/create.php new file mode 100644 index 00000000..58932262 --- /dev/null +++ b/application/admin/view/setting/system_group_data/create.php @@ -0,0 +1,28 @@ + + + + {include file="public/head"} + {$title} + + +
+ +
+ + diff --git a/application/admin/view/setting/system_group_data/edit.php b/application/admin/view/setting/system_group_data/edit.php new file mode 100644 index 00000000..58932262 --- /dev/null +++ b/application/admin/view/setting/system_group_data/edit.php @@ -0,0 +1,28 @@ + + + + {include file="public/head"} + {$title} + + +
+ +
+ + diff --git a/application/admin/view/setting/system_group_data/index.php b/application/admin/view/setting/system_group_data/index.php new file mode 100644 index 00000000..0a140597 --- /dev/null +++ b/application/admin/view/setting/system_group_data/index.php @@ -0,0 +1,111 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+ + + + +
+ + +
+ */ ?> +
+ + + +
+
+
+
+ + + + + {volist name="fields" id="vo"} + + {/volist} + + + + + + {volist name="list" id="vo"} + + + {volist name="fields" id="item"} + + {/volist} + + + + {/volist} + +
编号{$vo.name}是否可用操作
+ {$vo.id} + + {$vo.value[$item['title']]['value']} + + {if condition="$vo.status eq 1"} + + {elseif condition="$vo.status eq 2"/} + + {/if} + + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/setting/system_menus/edit_content.php b/application/admin/view/setting/system_menus/edit_content.php new file mode 100644 index 00000000..cdf346ae --- /dev/null +++ b/application/admin/view/setting/system_menus/edit_content.php @@ -0,0 +1,67 @@ + + + + + + + + 编辑内容 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/admin/view/setting/system_menus/index.php b/application/admin/view/setting/system_menus/index.php new file mode 100644 index 00000000..eef84a20 --- /dev/null +++ b/application/admin/view/setting/system_menus/index.php @@ -0,0 +1,116 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ 规则首页 + +
+ +
+
+
+
+
+
+ + + + + + + + **/?> +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + {/volist} + +
编号按钮名父级模块名控制器名方法名是否菜单操作
+ {$vo.id} + + {$vo.menu_name} + + {$vo.pid} + + {$vo.module} + + {$vo.controller} + + {$vo.action} + + + + + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/setting/system_notice/index.php b/application/admin/view/setting/system_notice/index.php new file mode 100644 index 00000000..c54ca12c --- /dev/null +++ b/application/admin/view/setting/system_notice/index.php @@ -0,0 +1,93 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+
+ +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
编号标题关键字模板发送管理员状态操作
+ {$vo.id} + + {$vo.title} + + {$vo.type} + + {$vo.template} + + {$vo.push_admin_name} + + + + + +
+
+
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/setting/system_notice/message.php b/application/admin/view/setting/system_notice/message.php new file mode 100644 index 00000000..49524e73 --- /dev/null +++ b/application/admin/view/setting/system_notice/message.php @@ -0,0 +1,225 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+ + +

+ 收件箱 (16) +

+
+
+ + + +
+ + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + 支付宝 + 支付宝提醒 + + 昨天 10:20
+ + Amaze UI + Amaze UI Beta2 发布 + 上午10:57
+ + WordPress 验证邮件 + wp-user-frontend-pro v2.1.9 + 上午9:21
+ + 淘宝网 + 史上最全!淘宝双11红包疯抢攻略! + 中午12:24
+ + 淘宝网 AD + 亲,双11来啦!帮你挑货,还送你4999元红包!仅此一次! + + 上午6:48
+ + 支付宝 + 支付宝提醒 + + 昨天 10:20
+ + Amaze UI + Amaze UI Beta2 发布 + 上午10:57
+ + WordPress 验证邮件 + wp-user-frontend-pro v2.1.9 + 上午9:21
+ + 淘宝网 + 史上最全!淘宝双11红包疯抢攻略! + 中午12:24
+ + 淘宝网 AD + 亲,双11来啦!帮你挑货,还送你4999元红包!仅此一次! + + 上午6:48
+ + 支付宝 + 支付宝提醒 + + 昨天 10:20
+ + Amaze UI + Amaze UI Beta2 发布 + 上午10:57
+ + WordPress 验证邮件 + wp-user-frontend-pro v2.1.9 + 上午9:21
+ + 淘宝网 + 史上最全!淘宝双11红包疯抢攻略! + 中午12:24
+ + 淘宝网 AD + 亲,双11来啦!帮你挑货,还送你4999元红包!仅此一次! + + 上午6:48
+ + +
+
+
+
+{/block} diff --git a/application/admin/view/setting/system_role/create.php b/application/admin/view/setting/system_role/create.php new file mode 100644 index 00000000..5ec22c3a --- /dev/null +++ b/application/admin/view/setting/system_role/create.php @@ -0,0 +1,90 @@ + + + + {include file="public/head"} + + + +
+ + + + + + + 开启 + 关闭 + + + + + + + 提交 + + +
+ + diff --git a/application/admin/view/setting/system_role/edit.php b/application/admin/view/setting/system_role/edit.php new file mode 100644 index 00000000..1f82a052 --- /dev/null +++ b/application/admin/view/setting/system_role/edit.php @@ -0,0 +1,94 @@ + + + + + {include file="public/head"} + + + +
+ + + + + + + 开启 + 关闭 + + + + + + + 提交 + + +
+ + diff --git a/application/admin/view/setting/system_role/index.php b/application/admin/view/setting/system_role/index.php new file mode 100644 index 00000000..78853a38 --- /dev/null +++ b/application/admin/view/setting/system_role/index.php @@ -0,0 +1,109 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+ + + + +
+ + +
+ */ ?> +
+ + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
编号身份昵称权限状态操作
+ {$vo.id} + + {$vo.role_name} + + {$vo.rules} + + + + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_bargain/index.php b/application/admin/view/store/store_bargain/index.php new file mode 100644 index 00000000..69cbc273 --- /dev/null +++ b/application/admin/view/store/store_bargain/index.php @@ -0,0 +1,236 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + +{/block} +{block name="content"} +
+
+ +
+
+
+
+
+
+ 创建时间: + + + + + +
+ +
+ +
+
+ 砍价状态: + + + + +
+ +
+ + + + + + +
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + {/volist} + +
编号砍价活动名称砍价产品名称砍价图片砍价价格砍价状态活动状态库存排序内容操作
+ {$vo.id} + + {$vo.title} + + {$vo.store_name} + + {$vo.store_name} + + {$vo.price} + + + + {$vo.start_name} + + {$vo.stock} + + {$vo.sort} + + + +
+
+ + +
+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_category/index.php b/application/admin/view/store/store_category/index.php new file mode 100644 index 00000000..eb58749b --- /dev/null +++ b/application/admin/view/store/store_category/index.php @@ -0,0 +1,133 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ 分类首页 + +
+ +
+
+
+
+
+
+ + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
编号父级分类名称分类图标排序是否显示操作
+ {$vo.id} + + {$vo.pid_name} + + {$vo.cate_name} + + {$vo.cate_name} + + {$vo.sort} + + + +
+
+ + +
+
+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_combination/attr.php b/application/admin/view/store/store_combination/attr.php new file mode 100644 index 00000000..ce9f54d6 --- /dev/null +++ b/application/admin/view/store/store_combination/attr.php @@ -0,0 +1,371 @@ + + + + {include file="public/head"} + {$title|default=''} + + + +
+ + + + + 添加新规则 + + + + + + + + + + + + + + 添加新规则 + + + + + + + {{ attr }} + + + + + + 添加 + + + + + + + 生成 + + + + + + + 保存中... +
+ + diff --git a/application/admin/view/store/store_combination/index.php b/application/admin/view/store/store_combination/index.php new file mode 100644 index 00000000..504d6d37 --- /dev/null +++ b/application/admin/view/store/store_combination/index.php @@ -0,0 +1,159 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+
+
+
+
+ + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + {/volist} + +
编号拼团名称产品名称拼团图片开始时间结束时间拼团人数价格产品状态推荐状态库存排序内容操作
+ {$vo.id} + + {$vo.title} + + {$vo.store_name}/{$vo.product_id} + + {$vo.store_name} + + {$vo.start_time|date="Y-m-d H:i:s",###} + + {$vo.stop_time|date="Y-m-d H:i:s",###} + + {$vo.people} + + {$vo.price} + + + + + + {$vo.stock} + + {$vo.sort} + + + +
+
+ + +
+
+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_coupon/grant.php b/application/admin/view/store/store_coupon/grant.php new file mode 100644 index 00000000..339e6ab1 --- /dev/null +++ b/application/admin/view/store/store_coupon/grant.php @@ -0,0 +1,90 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_coupon/grant_all.php b/application/admin/view/store/store_coupon/grant_all.php new file mode 100644 index 00000000..6667c72f --- /dev/null +++ b/application/admin/view/store/store_coupon/grant_all.php @@ -0,0 +1,90 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_coupon/grant_group.php b/application/admin/view/store/store_coupon/grant_group.php new file mode 100644 index 00000000..b94aead6 --- /dev/null +++ b/application/admin/view/store/store_coupon/grant_group.php @@ -0,0 +1,115 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_coupon/grant_subscribe.php b/application/admin/view/store/store_coupon/grant_subscribe.php new file mode 100644 index 00000000..2744b733 --- /dev/null +++ b/application/admin/view/store/store_coupon/grant_subscribe.php @@ -0,0 +1,90 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_coupon/grant_tag.php b/application/admin/view/store/store_coupon/grant_tag.php new file mode 100644 index 00000000..ad8d475b --- /dev/null +++ b/application/admin/view/store/store_coupon/grant_tag.php @@ -0,0 +1,115 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_coupon/index.php b/application/admin/view/store/store_coupon/index.php new file mode 100644 index 00000000..d7a721b2 --- /dev/null +++ b/application/admin/view/store/store_coupon/index.php @@ -0,0 +1,157 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+
+ + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + {/volist} + +
编号优惠券名称优惠券面值优惠券最低消费优惠券有效期限排序是否有效添加时间操作
+ {$vo.id} + + {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + {$vo.sort} + + + + {$vo.add_time|date='Y-m-d H:i:s',###} + +
+
+ + +
+
+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_coupon_issue/index.php b/application/admin/view/store/store_coupon_issue/index.php new file mode 100644 index 00000000..24255aad --- /dev/null +++ b/application/admin/view/store/store_coupon_issue/index.php @@ -0,0 +1,107 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+
+ +
+ +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + {/volist} + +
编号优惠券名称领取日期发布数量状态操作
+ {$vo.id} + + {$vo.title} + + {empty name="$vo.start_time"} + 不限时 + {else/} + {$vo.start_time|date="Y/m/d H:i",###} - {$vo.end_time|date="Y/m/d H:i",###} + {/empty} + + {empty name="$vo.total_count"} + 不限量 + {else/} + 发布:{$vo.total_count} +
+ 剩余:{$vo.remain_count} + {/empty} +
+ + 未开启 + + 已失效 + + 正常 + + + + {neq name="vo.status" value="-1"} + + {/neq} + +
+
+ {include file="public/inner_page"} +
+
+
+
+ +{/block} diff --git a/application/admin/view/store/store_coupon_issue/issue_log.php b/application/admin/view/store/store_coupon_issue/issue_log.php new file mode 100644 index 00000000..9c09f3fe --- /dev/null +++ b/application/admin/view/store/store_coupon_issue/issue_log.php @@ -0,0 +1,40 @@ +{include file="public/frame_head"} + +
+
+
+
+
+ + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
用户名用户头像领取时间
{$vo.nickname}{$vo.add_time}
+
+ {include file="public/inner_page"} +
+
+
+ +
+{include file="public/inner_footer"} diff --git a/application/admin/view/store/store_coupon_user/index.php b/application/admin/view/store/store_coupon_user/index.php new file mode 100644 index 00000000..219dec2c --- /dev/null +++ b/application/admin/view/store/store_coupon_user/index.php @@ -0,0 +1,104 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + {/volist} + +
编号优惠券名称发放人优惠券面值优惠券最低消费优惠券开始使用时间优惠券结束使用时间获取放方式是否可用状态
+ {$vo.id} + + {$vo.coupon_title} + + {$vo.nickname} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.add_time|date='Y-m-d H:i:s',###} + + {$vo.end_time|date='Y-m-d H:i:s',###} + + {$vo.type == 'send' ? '后台发放' : '手动领取'} + + {if condition="$vo['status'] eq 0" && $vo['is_fail'] eq 0} + + {else/} + + {/if} + + {if condition="$vo['status'] eq 2"} + 已过期 + {elseif condition="$vo['status'] eq 1"/} + 已使用 + {else/} + 未使用 + {/if} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} diff --git a/application/admin/view/store/store_order/express.php b/application/admin/view/store/store_order/express.php new file mode 100644 index 00000000..0ee4fced --- /dev/null +++ b/application/admin/view/store/store_order/express.php @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + 物流信息 + + + + + + + + + +
+
+
+
+
+
物流公司:{$order.delivery_name}
+
物流单号:{$order.delivery_id}
+
+
+
+ +
+ +

暂无查询记录

+
+ +
    + {volist name="express.result.list" id="vo"} +
  • +
    +

    {$vo.status}

    + {$vo.time} +
    +
  • + {/volist} +
+ +
+
+
+ + diff --git a/application/admin/view/store/store_order/index.php b/application/admin/view/store/store_order/index.php new file mode 100644 index 00000000..1e6d7b27 --- /dev/null +++ b/application/admin/view/store/store_order/index.php @@ -0,0 +1,609 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+
+ 订单状态: + + + + + + + + + +
+
+ 订单类型: + + + + + +
+
+ 创建时间: + + + + + + +
+ +
+ +
+
+
+ + + + + + + + +
+
+
+
+
+
+
+ toArray(); ?> +
+ 售出商品:{$price.total_num} + 订单数量:{$list_num.total} + 订单金额:¥{$price.pay_price} + 退款金额:¥{$price.refund_price} + {if condition="$price['pay_price_wx'] GT 0"} + 微信支付金额:¥{$price.pay_price_wx} + {/if} + {if condition="$price['pay_price_yue'] GT 0"} + 余额支付金额:¥{$price.pay_price_yue} + {/if} + {if condition="$price['pay_price_offline'] GT 0"} + 线下支付金额:¥{$price.pay_price_offline} + {/if} + {if condition="$price['pay_price_other'] GT 0"} + 线下支付金额:¥{$price.pay_price_other} + {/if} + {if condition="$price['use_integral'] GT 0"} + 积分抵扣:{$price.use_integral} (抵扣金额:¥{$price.deduction_price}) + {/if} + {if condition="$price['back_integral'] GT 0"} + 退回积分:{$price.back_integral} + {/if} +
+ +
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
订单号用户信息商品信息 +
+ + + +
+
支付状态订单状态详情操作
+ {$vo.order_id} 
  + {$vo.pink_name}   +
+

{$vo.nickname} / {$vo.uid}

+
+ + {volist name="info_order" id="info"} + {if condition="isset($info['cart_info']['productInfo']['attrInfo']) && !empty($info['cart_info']['productInfo']['attrInfo'])"} +

+ {$info.cart_info.productInfo.store_name} + {$info.cart_info.productInfo.store_name} {$info.cart_info.productInfo.attrInfo.suk} | ¥{$info.cart_info.truePrice}×{$info.cart_info.cart_num} +

+ {else/} +

+ {$info.cart_info.productInfo.store_name} + {$info.cart_info.productInfo.store_name} | ¥{$info.cart_info.truePrice}×{$info.cart_info.cart_num} +

+ {/if} + {/volist} +
+ ¥{$vo.pay_price} + + {if condition="$vo['paid'] eq 1"} +

+ {if condition="$vo['pay_type'] eq 'weixin'"} + 微信支付 + {elseif condition="$vo['pay_type'] eq 'yue'"} + 余额支付 + {elseif condition="$vo['pay_type'] eq 'offline'"} + 线下支付 + {else/} + 其他支付 + {/if} +

+ {else/} + {if condition="$vo['pay_type'] eq 'offline'"} +

线下支付

+

+ + {else/} +

未支付

+ {/if} + {/if} +
+ {if condition="$vo['paid'] eq 0 && $vo['status'] eq 0"} + 未支付 + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 0 && $vo['refund_status'] eq 0"/} + 未发货 + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 1 && $vo['refund_status'] eq 0"/} + 待收货 + + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 2 && $vo['refund_status'] eq 0"/} + 待评价 + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 3 && $vo['refund_status'] eq 0"/} + 交易完成 + {elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 1"/} + 申请退款
+ 退款原因:{$vo.refund_reason_wap} + {elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 2"/} + 已退款 + {/if} +
+ + 订单详情 + + + + {if condition="$vo['paid'] eq 0 && $vo['status'] eq 0 && $vo['refund_status'] eq 0"} + + {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 0 && $vo['refund_status'] eq 0"/} + + +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 1"/} +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 1 && $vo['refund_status'] eq 0"/} + +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 2 && $vo['refund_status'] eq 0"/} +
+ + +
+ {elseif condition="$vo['paid'] eq 1 && $vo['status'] eq 3 && $vo['refund_status'] eq 0"/} +
+ + +
+{elseif condition="$vo['paid'] eq 1 && $vo['refund_status'] eq 2"/} + +
+ + +
+ {/if} +
+
+
+ {include file="public/inner_page"} +
+
+
+
+ +{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_order/order_info.php b/application/admin/view/store/store_order/order_info.php new file mode 100644 index 00000000..cd27f3e0 --- /dev/null +++ b/application/admin/view/store/store_order/order_info.php @@ -0,0 +1,138 @@ +{extend name="public/container"} +{block name="content"} +
+ +
+
+
+
+ 收货信息 +
+
+
+
用户昵称: {$userInfo.nickname}
+
收货人: {$orderInfo.real_name}
+
联系电话: {$orderInfo.user_phone}
+
收货地址: {$orderInfo.user_address}
+
+
+
+
+
+
+
+ 订单信息 +
+
+
+
订单编号: {$orderInfo.order_id}
+
订单状态: + {if condition="$orderInfo['paid'] eq 0 && $orderInfo['status'] eq 0"} + 未支付 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 0 && $orderInfo['refund_status'] eq 0"/} + 未发货 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 1 && $orderInfo['refund_status'] eq 0"/} + 待收货 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 2 && $orderInfo['refund_status'] eq 0"/} + 待评价 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['status'] eq 3 && $orderInfo['refund_status'] eq 0"/} + 交易完成 + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['refund_status'] eq 1"/} + 申请退款{$orderInfo.refund_reason_wap} + {elseif condition="$orderInfo['paid'] eq 1 && $orderInfo['refund_status'] eq 2"/} + 已退款 + {/if} +
+
商品总数: {$orderInfo.total_num}
+
商品总价: ¥{$orderInfo.total_price}
+
支付邮费: ¥{$orderInfo.total_postage}
+
实际支付: ¥{$orderInfo.pay_price}
+ {if condition="$orderInfo['refund_price'] GT 0"} +
退款金额: ¥{$orderInfo.refund_price}
+ {/if} + {if condition="$orderInfo['deduction_price'] GT 0"} +
使用积分: {$orderInfo.use_integral}积分(抵扣了¥{$orderInfo.deduction_price})
+ {/if} + {if condition="$orderInfo['back_integral'] GT 0"} +
退回积分: ¥{$orderInfo.back_integral}
+ {/if} +
创建时间: {$orderInfo.add_time|date="Y/m/d H:i",###}
+
支付方式: + {if condition="$orderInfo['paid'] eq 1"} + {if condition="$orderInfo['pay_type'] eq 'weixin'"} + 微信支付 + {elseif condition="$orderInfo['pay_type'] eq 'yue'"} + 余额支付 + {elseif condition="$orderInfo['pay_type'] eq 'offline'"} + 线下支付 + {else/} + 其他支付 + {/if} + {else/} + {if condition="$orderInfo['pay_type'] eq 'offline'"} + 线下支付 + {else/} + 未支付 + {/if} + {/if} +
+ {notempty name="orderInfo.pay_time"} +
支付时间: {$orderInfo.pay_time|date="Y/m/d H:i",###}
+ {/notempty} +
用户备注: {$orderInfo.mark?:'无'}
+
商家备注: {$orderInfo.remark?:'无'}
+
推广人: {if $spread}{$spread}{else}无{/if}
+
+
+
+
+ {if condition="$orderInfo['delivery_type'] eq 'express'"} +
+
+
+ 物流信息 +
+
+
+
快递公司: {$orderInfo.delivery_name}
+
快递单号: {$orderInfo.delivery_id} |
+
+
+
+
+ {elseif condition="$orderInfo['delivery_type'] eq 'send'"} +
+
+
+ 配送信息 +
+
+
+
送货人姓名: {$orderInfo.delivery_name}
+
送货人电话: {$orderInfo.delivery_id}
+
+
+
+
+ {/if} +
+
+
+ 备注信息 +
+
+
+
{if $orderInfo.mark}{$orderInfo.mark}{else}暂无备注信息{/if}
+
+
+
+
+
+
+ + + +{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_order/order_status.php b/application/admin/view/store/store_order/order_status.php new file mode 100644 index 00000000..dd59f8ec --- /dev/null +++ b/application/admin/view/store/store_order/order_status.php @@ -0,0 +1,79 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
订单编号操作记录操作时间
+ {$vo.oid} + + {$vo.change_message} + + {$vo.change_time|date='Y-m-d H:i:s',###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_order/orderchart.php b/application/admin/view/store/store_order/orderchart.php new file mode 100644 index 00000000..904f049a --- /dev/null +++ b/application/admin/view/store/store_order/orderchart.php @@ -0,0 +1,278 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+
+ 订单状态: + + + + + + + + + +
+
+ 订单类型: + + + + + +
+
+ 创建时间: + + + + + + +
+ +
+ +
+
+ toArray(); ?> +
+
+ 售出商品:{$price.total_num} +
+
+ 订单数量:{$list_num.total} +
+
+ 订单金额:¥{$price.pay_price} +
+
+ 退款金额:¥{$price.refund_price} +
+
+
+
+
+
+
主要数据统计
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_order_pink/index.php b/application/admin/view/store/store_order_pink/index.php new file mode 100644 index 00000000..260f3448 --- /dev/null +++ b/application/admin/view/store/store_order_pink/index.php @@ -0,0 +1,212 @@ +{extend name="public/container"} +{block name="head_top"} + + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+
+ +
+ +
+ + + +
+ +
+
+ +
+
+ + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
开团团长开团时间拼团产品几人团几人参加结束时间状态操作
+ {$vo.uid|getUserNickname}/{$vo.uid} + + {$vo.add_time|date='Y-m-d H:i:s',###} + + {$vo.title}/{$vo.cid} + + {$vo.people}人 + + {$vo.count_people}人 + + {$vo.stop_time|date='Y-m-d H:i:s',###} + + {if condition="$vo['status'] eq 1"} + 进行中 + {elseif condition="$vo['status'] eq 2"} + 已完成 + {elseif condition="$vo['status'] eq 3"} + 未完成 + {/if} + +

+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_order_pink/order_pink.php b/application/admin/view/store/store_order_pink/order_pink.php new file mode 100644 index 00000000..5ec20a81 --- /dev/null +++ b/application/admin/view/store/store_order_pink/order_pink.php @@ -0,0 +1,173 @@ +{extend name="public/container"} +{block name="head_top"} + + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + {/volist} + +
编号用户名称用户头像订单编号金额订单状态
+ {$vo.id} + + {$vo.nickname}/{$vo.uid} + + {$vo.nickname} + + {$vo.order_id} + + ¥{$vo.price} + + {if condition="$vo['is_refund']"} + 已退款 + {else/} + 未退款 + {/if} +
+
+
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_order_pink/order_status.php b/application/admin/view/store/store_order_pink/order_status.php new file mode 100644 index 00000000..dd59f8ec --- /dev/null +++ b/application/admin/view/store/store_order_pink/order_status.php @@ -0,0 +1,79 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
订单编号操作记录操作时间
+ {$vo.oid} + + {$vo.change_message} + + {$vo.change_time|date='Y-m-d H:i:s',###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_product/attr.php b/application/admin/view/store/store_product/attr.php new file mode 100644 index 00000000..dc869dc5 --- /dev/null +++ b/application/admin/view/store/store_product/attr.php @@ -0,0 +1,392 @@ + + + + {include file="public/head"} + {$title|default=''} + + + + +
+ + + + + 添加新规则 + + + + + + + + + + + + + + 添加新规则 + + + + + + + {{ attr }} + + + + + + 添加 + + + + + + + 生成 + + + + + + + 保存中... +
+ + diff --git a/application/admin/view/store/store_product/collect.php b/application/admin/view/store/store_product/collect.php new file mode 100644 index 00000000..f5342bd0 --- /dev/null +++ b/application/admin/view/store/store_product/collect.php @@ -0,0 +1,34 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + {volist name="list" id="vo"} + + + + + {/volist} + +
点赞人点赞时间
+ {$vo.nickname} + + {$vo.add_time|date='Y-m-d H:i:s',###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} diff --git a/application/admin/view/store/store_product/index.php b/application/admin/view/store/store_product/index.php new file mode 100644 index 00000000..3da9a9df --- /dev/null +++ b/application/admin/view/store/store_product/index.php @@ -0,0 +1,373 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + + +{/block} +{block name="content"} +
+
+ +
+
+ +
+
+
+
+
+
+
+ + + + + + + + +
+
+ + + + + + + + + + +
+
+ + + + + + +
+ +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + {/volist} + +
编号产品图片产品名称产品价格虚拟销量商品访客数商品浏览量 +
+ + +
+
库存排序点赞收藏操作
+ + + {$vo.store_name} + + {$vo.store_name}
+ 价格:{$vo.price}
+ 分类:{$vo.cate_name} +
+ {$vo.price} + + + {$vo.ficti} + + {$vo.visitor} + + {$vo.browse} + + {$vo.sales} + + {$vo.stock} + + + {$vo.sort} + + +   {$vo.collect} + + + +   {$vo.like} + + +
+
+ + + + +
+
+ + + + + + + + + + +
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_product/like.php b/application/admin/view/store/store_product/like.php new file mode 100644 index 00000000..c2591b62 --- /dev/null +++ b/application/admin/view/store/store_product/like.php @@ -0,0 +1,34 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + {volist name="list" id="vo"} + + + + + {/volist} + +
收藏人收藏时间
+ {$vo.nickname} + + {$vo.add_time|date='Y-m-d H:i:s',###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} diff --git a/application/admin/view/store/store_product/statistics.php b/application/admin/view/store/store_product/statistics.php new file mode 100644 index 00000000..b8fbe06a --- /dev/null +++ b/application/admin/view/store/store_product/statistics.php @@ -0,0 +1,390 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+
+ 创建时间: + + + + + + +
+ +
+ +
+ {volist name='header' id='val'} +
+
+
+
+ +
+
+ {$val.name} +

{$val.value}

+
+
+
+
+ {/volist} + +
+
+
+
+
+
+
+
+
+
+
+
商品销量折线图
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
销量排行前十
+
+ + + + +
+
+
+
+ 当月前十商品销售总计: 件 + 共计 元 +
+
+ + +
+
+
+ {notempty name="stores"} + {volist name="stores" id="vo"} +
{$vo.name}
+
+ {$vo.sum} +
+ 40% Complete (success) +
+
+ {/volist} + {/notempty} +
+
+
+ +
+
+
+
+
+
利润排行前十
+
+ + + + + + +
+
+
+
+ 当月前十商品利润总计: 件 + 共计 元 +
+
+ + +
+
+ {notempty name="stor"} + {volist name="stor" id="vs"} +
{$vs.name}
+
+ + +
+ Complete +
+ +
+ {/volist} + {/notempty} +
+
+
+
+
+
+
+
+
+
+
+
+
待补货商品
+
+ + + + + + +
+
+
+ + + + + + + + {volist name="stock" id="vk"} + + + + + + + {/volist} +
商品信息商品单价库存数量操作
{$vk.store_name}{$vk.price}{$vk.stock} + + +
+
+ +
+ +
+
+
+
+
+
+
差评商品
+
+ + + + + + +
+
+
+ + + + + + + + {volist name="stor1" id="st"} + + + + + {/volist} +
商品信息商品单价差评数量操作
{$st.name}{$st.price}{$st.sun} + +
+
+
+
+
+
+
+
+
+
退货商品
+
+ + + + + + +
+
+
+ + + + + + + + {volist name="refund" id="st"} + + + + + {/volist} +
商品信息商品单价退货数量操作
{$st.name}{$st.price}{$st.sun} + +
+
+ +
+
+
+
+
+{/block} +{block name="script"} + + + + +{/block} diff --git a/application/admin/view/store/store_product_reply/index.php b/application/admin/view/store/store_product_reply/index.php new file mode 100644 index 00000000..455a6d6a --- /dev/null +++ b/application/admin/view/store/store_product_reply/index.php @@ -0,0 +1,201 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ {volist name="list" id="vo"} +
+ +
+ {/volist} +
+ + {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_seckill/attr.php b/application/admin/view/store/store_seckill/attr.php new file mode 100644 index 00000000..ce9f54d6 --- /dev/null +++ b/application/admin/view/store/store_seckill/attr.php @@ -0,0 +1,371 @@ + + + + {include file="public/head"} + {$title|default=''} + + + +
+ + + + + 添加新规则 + + + + + + + + + + + + + + 添加新规则 + + + + + + + {{ attr }} + + + + + + 添加 + + + + + + + 生成 + + + + + + + 保存中... +
+ + diff --git a/application/admin/view/store/store_seckill/index.php b/application/admin/view/store/store_seckill/index.php new file mode 100644 index 00000000..a74d2abd --- /dev/null +++ b/application/admin/view/store/store_seckill/index.php @@ -0,0 +1,148 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+
+
+ + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + {/volist} + +
编号产品图片活动标题活动简介价格库存开始时间结束时间添加时间产品状态内容操作
+ {$vo.id} + + {$vo.store_name} + + {$vo.title} + + {$vo.info} + + {$vo.price} + + {$vo.stock} + + {$vo.start_time|date='Y-m-d H:i:s',###} + + {$vo.stop_time|date='Y-m-d H:i:s',###} + + {$vo.add_time|date='Y-m-d H:i:s',###} + + {if condition="$vo['status']"} + {$vo.start_name} + {else/} + + {/if} + + + +
+
+ + +
+
+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/store/store_service/chat_list.php b/application/admin/view/store/store_service/chat_list.php new file mode 100644 index 00000000..c8b98855 --- /dev/null +++ b/application/admin/view/store/store_service/chat_list.php @@ -0,0 +1,46 @@ +{include file="public/frame_head"} + +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + {/volist} + +
用户名称用户头像发送消息发送时间
+ + {$vo.nickname} + + {$vo.msn}{$vo.add_time|date='Y-m-d H:i:s',###}
+
+ {include file="public/inner_page"} +
+
+
+ +
+{include file="public/inner_footer"} diff --git a/application/admin/view/store/store_service/chat_user.php b/application/admin/view/store/store_service/chat_user.php new file mode 100644 index 00000000..e042a73c --- /dev/null +++ b/application/admin/view/store/store_service/chat_user.php @@ -0,0 +1,32 @@ +{include file="public/frame_head"} +
+
+
+
+
+ + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
用户名称用户头像操作
{$vo.nickname} + +
+
+
+
+
+
+{include file="public/inner_footer"} diff --git a/application/admin/view/store/store_service/create.php b/application/admin/view/store/store_service/create.php new file mode 100644 index 00000000..389cf813 --- /dev/null +++ b/application/admin/view/store/store_service/create.php @@ -0,0 +1,157 @@ +{include file="public/frame_head"} + + + + + + +
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + + +
编号微信用户名称头像性别地区是否关注公众号首次关注时间
+ + + {$vo.uid} + + {$vo.nickname} + + {$vo.nickname} + + {if condition="$vo['sex'] eq 1"} + 男 + {elseif condition="$vo['sex'] eq 2"/} + 女 + {else/} + 保密 + {/if} + + {$vo.country}{$vo.province}{$vo.city} + + {if condition="$vo['subscribe']"} + 关注 + {else/} + 取消 + {/if} + + {$vo.add_time|date="Y-m-d H:i:s",###} +
+
+ {include file="public/inner_page"} +
+
+
+
+
+ +
+ +{include file="public/inner_footer"} diff --git a/application/admin/view/store/store_service/edit.php b/application/admin/view/store/store_service/edit.php new file mode 100644 index 00000000..58932262 --- /dev/null +++ b/application/admin/view/store/store_service/edit.php @@ -0,0 +1,28 @@ + + + + {include file="public/head"} + {$title} + + +
+ +
+ + diff --git a/application/admin/view/store/store_service/index.html b/application/admin/view/store/store_service/index.html new file mode 100644 index 00000000..3ee5d898 --- /dev/null +++ b/application/admin/view/store/store_service/index.html @@ -0,0 +1,161 @@ +{include file="public/frame_head"} +
+
+
+
+ +
+
+
+
+
+ + + + + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + + + {/volist} + +
编号产品图片产品名称产品分类价格产品状态热卖单品促销单品精品推荐首发新品库存点赞收藏内容秒杀操作评论
+ {$vo.id} + + {$vo.store_name} + + {$vo.store_name} + + {$vo.cate_name} + + {$vo.price} + + + + + + + + + + + + {$vo.stock} + + +   {$vo.collect} + + + +   {$vo.like} + + + + + + + + + + 查看 +
+
+ {include file="public/inner_page"} +
+
+
+ +
+ +{include file="public/inner_footer"} diff --git a/application/admin/view/store/store_service/index.php b/application/admin/view/store/store_service/index.php new file mode 100644 index 00000000..f1a66613 --- /dev/null +++ b/application/admin/view/store/store_service/index.php @@ -0,0 +1,74 @@ +{extend name="public/container"} +{block name="head_top"}{/block} +{block name="content"} +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
编号微信用户名称客服头像客服名称是否显示添加时间操作
{$vo.id}{$vo.wx_name}{$vo.nickname} + + {$vo.add_time|date='Y-m-d H:i:s',###} + + + +
+
+ {include file="public/inner_page"} +
+
+
+ {/block} + {block name="script"} + +
+{/block} diff --git a/application/admin/view/store/store_statistics/index.php b/application/admin/view/store/store_statistics/index.php new file mode 100644 index 00000000..3005dd0c --- /dev/null +++ b/application/admin/view/store/store_statistics/index.php @@ -0,0 +1,443 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + +{/block} +{block name="content"} + +
+
+
+
+
+
+
+ 创建时间: + 全部 + 今天 + 本周 + 本月 + 本季度 + 本年 +
+ 自定义 +
+
+ +
+
+
+
+
+
+
+
+ {volist name='header' id='val'} +
+
+
+
+ +
+
+ {$val.name} +

{$val.value}

+
+
+
+ +
+ {/volist} +
+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
主要数据统计
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
支付方式
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
支出详情
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
营收详情
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
最近交易记录
+
+ + + + + + +
+
+
+
+ {volist name="trans" id="vo"} +

{$vo.nickname}

+

购买{$vo.store_name}

+

¥{$vo.pay_price}

+ {/volist} +
+
+
+
+
+
+
+
+
+ +
+ {if condition="$price['pay_price_wx'] GT 0"} +
+ 微信支付金额:¥{$price.pay_price_wx} +
+ {/if} + {if condition="$price['pay_price_yue'] GT 0"} +
+ 余额支付金额:¥{$price.pay_price_yue} +
+ {/if} + {if condition="$price['pay_price_offline'] GT 0"} +
+ 线下支付金额:¥{$price.pay_price_offline} +
+ {/if} +
+
+
+ + Excel导出 + +
+
+
+
+
+ + + +{/block} diff --git a/application/admin/view/system/clear/index.php b/application/admin/view/system/clear/index.php new file mode 100644 index 00000000..a6ac0656 --- /dev/null +++ b/application/admin/view/system/clear/index.php @@ -0,0 +1,23 @@ +{include file="public/frame_head"} +
+ + + +
+ +{include file="public/inner_footer"} diff --git a/application/admin/view/system/system_cleardata/index.php b/application/admin/view/system/system_cleardata/index.php new file mode 100644 index 00000000..b3ee510b --- /dev/null +++ b/application/admin/view/system/system_cleardata/index.php @@ -0,0 +1,56 @@ +{include file="public/frame_head"} + +
+
清除数据请谨慎,清除就无法恢复哦! +
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +{include file="public/inner_footer"} diff --git a/application/admin/view/system/system_file/index.php b/application/admin/view/system/system_file/index.php new file mode 100644 index 00000000..eb4819b3 --- /dev/null +++ b/application/admin/view/system/system_file/index.php @@ -0,0 +1,68 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + + + {volist name="cha" id="vo"} + + + + + + + + + {/volist} + +
类型文件地址校验码上次访问时间上次修改时间上次改变时间
+ [{$vo.type}] + + {$vo.filename} + + {$vo.cthash} + + {$vo.atime|date='Y-m-d H:i:s',###} + + {$vo.mtime|date='Y-m-d H:i:s',###} + + {$vo.ctime|date='Y-m-d H:i:s',###} +
+
+
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/system/system_log/index.php b/application/admin/view/system/system_log/index.php new file mode 100644 index 00000000..9da2825c --- /dev/null +++ b/application/admin/view/system/system_log/index.php @@ -0,0 +1,116 @@ +{extend name="public/container"} +{block name="head_top"} + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ + +
+ +
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
编号ID/名称行为链接操作ip类型操作时间
+ {$vo.id} + + {$vo.admin_id} / {$vo.admin_name} + + {$vo.page} + + {$vo.path}({$vo.method}) + + {$vo.ip} + + {$vo.type} + + {$vo.add_time|date="Y-m-d H:i:s",###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} + diff --git a/application/admin/view/system/system_upgradeclient/index.php b/application/admin/view/system/system_upgradeclient/index.php new file mode 100644 index 00000000..3b9ac193 --- /dev/null +++ b/application/admin/view/system/system_upgradeclient/index.php @@ -0,0 +1,185 @@ +{extend name="public/container"} +{block name="content"} + +
+
+
+
+
+
+
+
+

在线升级 当前版本为:{{version}}

+
+
+
+
+ +
+

正在加载中

+
+ +
+

您没有权限升级

+
+ +
+

+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
版本号
+
更新内容
+
更新时间
+
+
+
+
+
{{item.version}}
+
{{item.content}}
+
{{item.add_time}}
+
+
+
+
+
+
+ 点击加载 +
+
+
+ 没有更多了 +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +{/block} \ No newline at end of file diff --git a/application/admin/view/ump/store_coupon/grant.php b/application/admin/view/ump/store_coupon/grant.php new file mode 100644 index 00000000..339e6ab1 --- /dev/null +++ b/application/admin/view/ump/store_coupon/grant.php @@ -0,0 +1,90 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/ump/store_coupon/grant_all.php b/application/admin/view/ump/store_coupon/grant_all.php new file mode 100644 index 00000000..6667c72f --- /dev/null +++ b/application/admin/view/ump/store_coupon/grant_all.php @@ -0,0 +1,90 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/ump/store_coupon/grant_group.php b/application/admin/view/ump/store_coupon/grant_group.php new file mode 100644 index 00000000..b94aead6 --- /dev/null +++ b/application/admin/view/ump/store_coupon/grant_group.php @@ -0,0 +1,115 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/ump/store_coupon/grant_subscribe.php b/application/admin/view/ump/store_coupon/grant_subscribe.php new file mode 100644 index 00000000..2744b733 --- /dev/null +++ b/application/admin/view/ump/store_coupon/grant_subscribe.php @@ -0,0 +1,90 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/ump/store_coupon/grant_tag.php b/application/admin/view/ump/store_coupon/grant_tag.php new file mode 100644 index 00000000..ad8d475b --- /dev/null +++ b/application/admin/view/ump/store_coupon/grant_tag.php @@ -0,0 +1,115 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
优惠券名称优惠券面值优惠券最低消费优惠券有效期限操作
+ {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/ump/store_coupon/index.php b/application/admin/view/ump/store_coupon/index.php new file mode 100644 index 00000000..3723767d --- /dev/null +++ b/application/admin/view/ump/store_coupon/index.php @@ -0,0 +1,162 @@ +{extend name="public/container"} +{block name="content"} + +
+
+
+
+ +
+ +
+
+
+
+
+
+ + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + {/volist} + +
编号优惠券名称优惠券面值优惠券最低消费优惠券有效期限排序是否有效添加时间操作
+ {$vo.id} + + {$vo.title} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.coupon_time}天 + + {$vo.sort} + + + + {$vo.add_time|date='Y-m-d H:i:s',###} + +
+
+ + +
+
+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/ump/store_coupon_issue/index.php b/application/admin/view/ump/store_coupon_issue/index.php new file mode 100644 index 00000000..82f6247a --- /dev/null +++ b/application/admin/view/ump/store_coupon_issue/index.php @@ -0,0 +1,107 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+
+ +
+ +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + {/volist} + +
编号优惠券名称领取日期发布数量状态操作
+ {$vo.id} + + {$vo.title} + + {empty name="$vo.start_time"} + 不限时 + {else/} + {$vo.start_time|date="Y/m/d H:i",###} - {$vo.end_time|date="Y/m/d H:i",###} + {/empty} + + {empty name="$vo.total_count"} + 不限量 + {else/} + 发布:{$vo.total_count} +
+ 剩余:{$vo.remain_count} + {/empty} +
+ + 未开启 + + 已失效 + + 正常 + + + + {neq name="vo.status" value="-1"} + + {/neq} + +
+
+ {include file="public/inner_page"} +
+
+
+
+ +{/block} diff --git a/application/admin/view/ump/store_coupon_issue/issue_log.php b/application/admin/view/ump/store_coupon_issue/issue_log.php new file mode 100644 index 00000000..9c09f3fe --- /dev/null +++ b/application/admin/view/ump/store_coupon_issue/issue_log.php @@ -0,0 +1,40 @@ +{include file="public/frame_head"} + +
+
+
+
+
+ + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
用户名用户头像领取时间
{$vo.nickname}{$vo.add_time}
+
+ {include file="public/inner_page"} +
+
+
+ +
+{include file="public/inner_footer"} diff --git a/application/admin/view/ump/store_coupon_user/index.php b/application/admin/view/ump/store_coupon_user/index.php new file mode 100644 index 00000000..73a69e39 --- /dev/null +++ b/application/admin/view/ump/store_coupon_user/index.php @@ -0,0 +1,104 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+
+ +
+ + + + + + + +
+ +
+
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + {/volist} + +
编号优惠券名称发放人优惠券面值优惠券最低消费优惠券开始使用时间优惠券结束使用时间获取放方式是否可用状态
+ {$vo.id} + + {$vo.coupon_title} + + {$vo.nickname} + + {$vo.coupon_price} + + {$vo.use_min_price} + + {$vo.add_time|date='Y-m-d H:i:s',###} + + {$vo.end_time|date='Y-m-d H:i:s',###} + + {$vo.type == 'send' ? '后台发放' : '手动领取'} + + {if condition="$vo['status'] eq 0" && $vo['is_fail'] eq 0} + + {else/} + + {/if} + + {if condition="$vo['status'] eq 2"} + 已过期 + {elseif condition="$vo['status'] eq 1"/} + 已使用 + {else/} + 未使用 + {/if} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} diff --git a/application/admin/view/ump/store_seckill/index.php b/application/admin/view/ump/store_seckill/index.php new file mode 100644 index 00000000..dc03c9e6 --- /dev/null +++ b/application/admin/view/ump/store_seckill/index.php @@ -0,0 +1,210 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
秒杀产品搜索
+
+
+ + 目前拥有{$countSeckill}个秒杀产品 +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+
+
+
秒杀产品列表
+
+
+ + + + +
+
+
+
+
+{/block} +{block name="script"} + + + +{/block} diff --git a/application/admin/view/ump/user_point/index.php b/application/admin/view/ump/user_point/index.php new file mode 100644 index 00000000..1a7c87b3 --- /dev/null +++ b/application/admin/view/ump/user_point/index.php @@ -0,0 +1,131 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
搜索条件
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
-
+
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ {{item.name}} + {{item.field}} +
+
+

{{item.count}}

+

+ {{item.content}} + {{item.sum}} +

+
+
+
+
+
+
积分日志
+
+
+
+
+
+
+
+ +{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/user/user/index.php b/application/admin/view/user/user/index.php new file mode 100644 index 00000000..5d10be87 --- /dev/null +++ b/application/admin/view/user/user/index.php @@ -0,0 +1,360 @@ +{extend name="public/container"} +{block name="head_top"} + +{/block} +{block name="content"} +
+
+
+
+
会员搜索
+
+ + + +
+
+
+
+ + 目前拥有{$count_user}个会员 +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + +
+ + +
+ + + +
+
+
+
+
+ + +{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/user/user/see.php b/application/admin/view/user/user/see.php new file mode 100644 index 00000000..5a74f0bc --- /dev/null +++ b/application/admin/view/user/user/see.php @@ -0,0 +1,368 @@ +{extend name="public/container"} +{block name="content"} + +
+
+
+
+
会员详情
+
+
    + {volist name='userinfo' id='vo'} + {if trim($vo.value)} +
  • +
    +

    {$vo.name}

    +

    {$vo.value}

    +
    +
  • + {/if} + {/volist} +
+
+
+
+
+
+
其他详情
+
+
+
    +
  • 消费能力
  • +
  • 积分明细
  • +
  • 签到记录
  • +
  • 持有优惠劵
  • +
  • 余额变动记录
  • +
+
+ {volist name='headerList' id='vo'} +
+
+
+ {$vo.title} + {$vo.key} +
+
+

{$vo.value}

+
+
+
+ {/volist} +
+ + + + + + + + + + + + + + + + + + + + + + + + +
订单编号收货人商品数量商品总价实付金额交易完成时间
{{item.order_id}} +

+ 正在加载 + 正在加载 + 拼团 + 秒杀 + 砍价 +

+
{{item.real_name}}{{item.total_num}}{{item.total_price}}{{item.pay_price}}{{item.pay_time}}
暂无数据
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
来源/用途积分变化变化后积分日期备注
{{item.title}}{{item.number}}{{item.balance}}{{item.add_time}}{{item.mark}}
暂无数据
+
+
+
+ + + + + + + + + + + + + + + + + + + + +
动作获得积分签到时间备注
{{item.title}}{{item.number}}{{item.add_time}}{{item.mark}}
暂无数据
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
优惠券名称面值有效期所需积分兑换时间
{{item.coupon_title}} +

+ 正在加载 +

+
{{item.coupon_price}}{{item._add_time}}-{{item._end_time}}{{item.integral}}{{item._add_time}}
暂无数据
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
变动金额变动后类型创建时间备注
{{item.number}} +

+ 有效 + 带确定 + 无效 +

+
{{item.balance}}{{item._type}}{{item.add_time}}{{item.mark}}
暂无数据
+
+
+
+
+
+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/admin/view/user/user/user_analysis.php b/application/admin/view/user/user/user_analysis.php new file mode 100644 index 00000000..d7dacb69 --- /dev/null +++ b/application/admin/view/user/user/user_analysis.php @@ -0,0 +1,382 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+
+ 创建时间: + + + + + +
+ +
+ +
+
+ 选择状态: + + + + +
+
+ 选择身份: + + + + +
+ {volist name='header' id='val'} +
+
+
+
+ +
+
+ {$val.name} +

{$val.value}

+
+
+
+
+ {/volist} + +
+
+
+
+
+
+
+
+
+
+
+
+
主要数据统计
+
+ + + +
+
+
+
+
+
+
+
+
+
+
消费统计
+
+ + + +
+
+
+
+

{$consume.rightTitle.title}

+

  ¥{$consume.rightTitle.number}

+
+
+

{$consume.leftTitle.title}

+

  {$consume.leftTitle.count}

+
+
+
+
+
+
+
+
+
+
+
+
用户分布
+
+ + + +
+
+
+
+
+
+
+
+
+
+
用户浏览分析(次)
+
+ + + +
+
+
+
+
+
+
+
+
+
+
消费排行榜 TOP20
+
+ + + +
+
+
+ + + + + + + + + + + + + {volist name='user_null' id='vo'} + + + + + + + + + {/volist} + {if !$user_null} + + + + {/if} + +
排名用户名时间消费金额 ¥余额 ¥操作
{$key+1}{$vo.nickname}{$vo.add_time|date='Y-m-d H:i:s',###}{$vo.totel_number}{$vo.now_money} + +

暂无数据

+
+
+
+
+{/block} +{block name="script"} + + +{/block} diff --git a/application/admin/view/user/user_extract/index.php b/application/admin/view/user/user_extract/index.php new file mode 100644 index 00000000..ef1cbc56 --- /dev/null +++ b/application/admin/view/user/user_extract/index.php @@ -0,0 +1,284 @@ +{extend name="public/container"} + +{block name="content"} + +
+ +
+ +
+ +
+ +
+ +
+
+ + + +
+ + + + + + + +
+ + +
+ + +
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + + + + {/volist} + + + +
编号用户信息提现金额提现方式添加时间备注审核状态操作
+ + {$vo.id} + + + + 用户昵称: {$vo.nickname}/用户id:{$vo.uid} + + + + {$vo.extract_price} + + + 姓名:{$vo.real_name}
+ {if condition="$vo['extract_type'] eq 'bank'"} + + 银行卡号:{$vo.bank_code} +
+ 银行开户地址:{$vo.bank_address} + {else/} + 支付宝号:{$vo.alipay_code} + {/if} +
+ + {$vo.add_time|date='Y-m-d H:i:s',###} + + + {$vo.mark} + + + {if condition="$vo['status'] eq 1"} + + 提现通过
+ + + {elseif condition="$vo['status'] eq -1"/} + + 提现未通过
+ + 未通过原因:{$vo.fail_msg} +
+ 未通过时间:{$vo.fail_time|date='Y-m-d H:i:s',###} + + {else/} + + 未提现
+ + + + + + {/if} + +
+ + + + + +
+ +
+ + {include file="public/inner_page"} + +
+ +
+ +
+ +
+ +{/block} + +{block name="script"} + + + +{/block} + diff --git a/application/admin/view/user/user_notice/create.php b/application/admin/view/user/user_notice/create.php new file mode 100644 index 00000000..58932262 --- /dev/null +++ b/application/admin/view/user/user_notice/create.php @@ -0,0 +1,28 @@ + + + + {include file="public/head"} + {$title} + + +
+ +
+ + diff --git a/application/admin/view/user/user_notice/index.php b/application/admin/view/user/user_notice/index.php new file mode 100644 index 00000000..e0990952 --- /dev/null +++ b/application/admin/view/user/user_notice/index.php @@ -0,0 +1,104 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
编号发送人通知标题通知内容消息类型是否发送操作
{$vo.id}{$vo.user}{$vo.title}{$vo.content} + {if condition="$vo['type'] eq 1"} + 系统消息 + {elseif condition="$vo['type'] eq 2" /} + 用户通知 + {/if} + + {if condition="$vo['is_send'] eq 1"} + 状态:已发送
+ 时间:{$vo.send_time|date='Y-m-d H:i:s',###} + {else /} + 状态:未发送 立即发送 + {/if} +
+ + {if condition="$vo['is_send'] eq 0"} + + {/if} + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/user/user_notice/notice.php b/application/admin/view/user/user_notice/notice.php new file mode 100644 index 00000000..4f38dd92 --- /dev/null +++ b/application/admin/view/user/user_notice/notice.php @@ -0,0 +1,82 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
编号发送人通知标题通知内容操作
{$vo.id}{$vo.user}{$vo.title}{$vo.content} + 立即发送 +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/user/user_notice/user.php b/application/admin/view/user/user_notice/user.php new file mode 100644 index 00000000..e4dca117 --- /dev/null +++ b/application/admin/view/user/user_notice/user.php @@ -0,0 +1,138 @@ +{include file="public/frame_head"} + + + + + +
+
+ {if condition="$notice['is_send'] eq 0 AND $notice['type'] eq 2"} +
+ + +
+ {/if} +
+
+ + + + {if condition="$notice['is_send'] eq 0 AND $notice['type'] eq 2"}{/if} + + + + + {if condition="$notice['is_send'] eq 1 AND $notice['type'] eq 2"}{/if} + {if condition="$notice['is_send'] eq 0 AND $notice['type'] eq 2"}{/if} + + + + + {volist name="list" id="vo"} + + {if condition="$notice['is_send'] eq 0 AND $notice['type'] eq 2"} + + {/if} + + + + + {if condition="$notice['is_send'] eq 1 AND $notice['type'] eq 2"} + + {/if} + {if condition="$notice['is_send'] eq 0 AND $notice['type'] eq 2"} + + {/if} + + {/volist} + + +
编号微信用户名称头像性别是否查看操作
+ + {$vo.uid}{$vo.nickname} + {$vo.nickname} + + {if condition="$vo['sex'] eq 1"} + 男 + {elseif condition="$vo['sex'] eq 2"/} + 女 + {else/} + 保密 + {/if} + + {if condition="$vo['is_see'] eq 1"} + + {else/} + + {/if} + + +
+
+ {include file="public/inner_page"} +
+
+
+ + +{include file="public/inner_footer"} \ No newline at end of file diff --git a/application/admin/view/user/user_notice/user_create.php b/application/admin/view/user/user_notice/user_create.php new file mode 100644 index 00000000..777be856 --- /dev/null +++ b/application/admin/view/user/user_notice/user_create.php @@ -0,0 +1,165 @@ +{include file="public/frame_head"} + + + + + + +
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + + +
编号微信用户名称头像性别地区是否关注公众号首次关注时间
+ + + {$vo.uid} + + {$vo.nickname} + + {$vo.nickname} + + {if condition="$vo['sex'] eq 1"} + 男 + {elseif condition="$vo['sex'] eq 2"/} + 女 + {else/} + 保密 + {/if} + + {$vo.country}{$vo.province}{$vo.city} + + {if condition="$vo['subscribe']"} + 关注 + {else/} + 取消 + {/if} + + {$vo.add_time|date="Y-m-d H:i:s",###} +
+
+ {include file="public/inner_page"} +
+
+
+
+
+ + +
+ +{include file="public/inner_footer"} diff --git a/application/admin/view/user/user_recharge/index.php b/application/admin/view/user/user_recharge/index.php new file mode 100644 index 00000000..1dc64069 --- /dev/null +++ b/application/admin/view/user/user_recharge/index.php @@ -0,0 +1,65 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
编号姓名订单编号支付金额支付类型支付时间操作
{$vo.id}{$vo.nickname}{$vo.order_id} + {$vo.price} + {if condition="$vo['refund_price'] GT 0"} +

退款金额:{$vo.refund_price}

+ {/if} +
微信支付{$vo.pay_time|date='Y-m-d H:i:s',###} + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/wechat/menus/index.php b/application/admin/view/wechat/menus/index.php new file mode 100644 index 00000000..6d01464f --- /dev/null +++ b/application/admin/view/wechat/menus/index.php @@ -0,0 +1,275 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="content"} +
+
+
+
+
+
公众号
+
+
9:36
+
+ +
+ +
+ +
+
+
+ +
+
+
+ +{/block} +{block name="script"} + + + + + +{/block} + diff --git a/application/admin/view/wechat/reply/add_keyword.php b/application/admin/view/wechat/reply/add_keyword.php new file mode 100644 index 00000000..042d49ca --- /dev/null +++ b/application/admin/view/wechat/reply/add_keyword.php @@ -0,0 +1,317 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + +{/block} +{block name="content"} +
+
+
+

{{msg}}

+
+
+
公众号
+
+
9:36
+
+
+
+ {{dataGroup.text.content}} +
+
+
+
+
{{dataGroup.news[0].title}}
+
{{dataGroup.news[0].date}}
+
+
{{dataGroup.news[0].description}}
+ +
+
+
+
+
{{dataGroup.news[0].title}}
+
+
+
{{newinfos.title}}
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
{{msg}}
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ + +
+
+ +
选择图文消息
+
+
+ +
+
+ +
+ + 上传 +
+
+
+ 文件最大2Mb,支持bmp/png/jpeg/jpg/gif格式 +
上传图片
+
+
+ +
+
+ +
+ + 上传 +
+
+
+
+
+
+
+
+
+
+
+
+
+{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/application/admin/view/wechat/reply/index.php b/application/admin/view/wechat/reply/index.php new file mode 100644 index 00000000..b6e5f4d6 --- /dev/null +++ b/application/admin/view/wechat/reply/index.php @@ -0,0 +1,344 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + +{/block} +{block name="content"} +
+
+
+

{{msg}}

+
+
+
公众号
+
+
9:36
+
+
+
+ {{dataGroup.text.content}} +
+
+ +
+
+
{{dataGroup.news[0].title}}
+
{{dataGroup.news[0].date}}
+
+
{{dataGroup.news[0].description}}
+ +
+
+
+
+
{{dataGroup.news[0].title}}
+
+
+
{{newinfos.title}}
+
+
+
+
+ +
+
+
+ +
+
+ + +
+
+

{{musicTit}}

+

{{musicInfo}}

+
+
+
*/ ?> + + +
+
{{videoTit}}
+
11月11日
+
+ +
+
+
{{videoInfo}}
+
*/ ?> + +
+
+
+
+
{{msg}}
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+
+ +
选择图文消息
+
+
+ +
+
+ +
+ + 上传 +
+
+
+ 文件最大2Mb,支持bmp/png/jpeg/jpg/gif格式 +
上传图片
+
+
+ +
+
+ +
+ + 上传 +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ + 上传 +
+
+
+

文件最大10MB,只支持MP4格式

+
+
+ +
+ +
+
+ +
+
+
+
+
+
+
+
+
+ + +{/block} +{block name="script"} + +{/block} + diff --git a/application/admin/view/wechat/reply/keyword.php b/application/admin/view/wechat/reply/keyword.php new file mode 100644 index 00000000..b2b50c8d --- /dev/null +++ b/application/admin/view/wechat/reply/keyword.php @@ -0,0 +1,102 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+ + +
+ + +
+
+
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
关键字回复类型状态操作
+ {$vo.key} + + {switch name="$vo['type']" } + {case value="text" break="1"}文字消息{/case} + {case value="voice" break="1"}声音消息{/case} + {case value="image" break="1"}图片消息{/case} + {case value="news" break="1"}图文消息{/case} + {/switch} + + {switch name="$vo['status']" } + {case value="1" break="1"}{/case} + {case value="0" break="1"}{/case} + {/switch} + + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} \ No newline at end of file diff --git a/application/admin/view/wechat/store_service/chat_list.php b/application/admin/view/wechat/store_service/chat_list.php new file mode 100644 index 00000000..c8b98855 --- /dev/null +++ b/application/admin/view/wechat/store_service/chat_list.php @@ -0,0 +1,46 @@ +{include file="public/frame_head"} + +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + {/volist} + +
用户名称用户头像发送消息发送时间
+ + {$vo.nickname} + + {$vo.msn}{$vo.add_time|date='Y-m-d H:i:s',###}
+
+ {include file="public/inner_page"} +
+
+
+ +
+{include file="public/inner_footer"} diff --git a/application/admin/view/wechat/store_service/chat_user.php b/application/admin/view/wechat/store_service/chat_user.php new file mode 100644 index 00000000..e042a73c --- /dev/null +++ b/application/admin/view/wechat/store_service/chat_user.php @@ -0,0 +1,32 @@ +{include file="public/frame_head"} +
+
+
+
+
+ + + + + + + + + + {volist name="list" id="vo"} + + + + + + {/volist} + +
用户名称用户头像操作
{$vo.nickname} + +
+
+
+
+
+
+{include file="public/inner_footer"} diff --git a/application/admin/view/wechat/store_service/create.php b/application/admin/view/wechat/store_service/create.php new file mode 100644 index 00000000..389cf813 --- /dev/null +++ b/application/admin/view/wechat/store_service/create.php @@ -0,0 +1,157 @@ +{include file="public/frame_head"} + + + + + + +
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + + +
编号微信用户名称头像性别地区是否关注公众号首次关注时间
+ + + {$vo.uid} + + {$vo.nickname} + + {$vo.nickname} + + {if condition="$vo['sex'] eq 1"} + 男 + {elseif condition="$vo['sex'] eq 2"/} + 女 + {else/} + 保密 + {/if} + + {$vo.country}{$vo.province}{$vo.city} + + {if condition="$vo['subscribe']"} + 关注 + {else/} + 取消 + {/if} + + {$vo.add_time|date="Y-m-d H:i:s",###} +
+
+ {include file="public/inner_page"} +
+
+
+
+
+ +
+ +{include file="public/inner_footer"} diff --git a/application/admin/view/wechat/store_service/edit.php b/application/admin/view/wechat/store_service/edit.php new file mode 100644 index 00000000..58932262 --- /dev/null +++ b/application/admin/view/wechat/store_service/edit.php @@ -0,0 +1,28 @@ + + + + {include file="public/head"} + {$title} + + +
+ +
+ + diff --git a/application/admin/view/wechat/store_service/index.html b/application/admin/view/wechat/store_service/index.html new file mode 100644 index 00000000..3ee5d898 --- /dev/null +++ b/application/admin/view/wechat/store_service/index.html @@ -0,0 +1,161 @@ +{include file="public/frame_head"} +
+
+
+
+ +
+
+
+
+
+ + + + + +
+ + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + + + {/volist} + +
编号产品图片产品名称产品分类价格产品状态热卖单品促销单品精品推荐首发新品库存点赞收藏内容秒杀操作评论
+ {$vo.id} + + {$vo.store_name} + + {$vo.store_name} + + {$vo.cate_name} + + {$vo.price} + + + + + + + + + + + + {$vo.stock} + + +   {$vo.collect} + + + +   {$vo.like} + + + + + + + + + + 查看 +
+
+ {include file="public/inner_page"} +
+
+
+ +
+ +{include file="public/inner_footer"} diff --git a/application/admin/view/wechat/store_service/index.php b/application/admin/view/wechat/store_service/index.php new file mode 100644 index 00000000..f1a66613 --- /dev/null +++ b/application/admin/view/wechat/store_service/index.php @@ -0,0 +1,74 @@ +{extend name="public/container"} +{block name="head_top"}{/block} +{block name="content"} +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + {/volist} + +
编号微信用户名称客服头像客服名称是否显示添加时间操作
{$vo.id}{$vo.wx_name}{$vo.nickname} + + {$vo.add_time|date='Y-m-d H:i:s',###} + + + +
+
+ {include file="public/inner_page"} +
+
+
+ {/block} + {block name="script"} + +
+{/block} diff --git a/application/admin/view/wechat/wechat_message/index.php b/application/admin/view/wechat/wechat_message/index.php new file mode 100644 index 00000000..bbb6ecbc --- /dev/null +++ b/application/admin/view/wechat/wechat_message/index.php @@ -0,0 +1,107 @@ +{extend name="public/container"} +{block name="head_top"} + + + +{/block} +{block name="content"} +
+
+
+
+
+
+
+ + +
+ +
+
+ + +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
编号操作用户操作名称关联内容操作时间
+ {$vo.id} + + {$vo.nickname} + + {$vo.type_name} + + {$vo['result_arr']['msg']} + + {$vo.add_time|date="Y-m-d H:i:s",###} +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/wechat/wechat_news_category/append.php b/application/admin/view/wechat/wechat_news_category/append.php new file mode 100644 index 00000000..f860ee5d --- /dev/null +++ b/application/admin/view/wechat/wechat_news_category/append.php @@ -0,0 +1,315 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + + + + + +{/block} +{block name="content"} +
+
+
+
+
文章列表
+
+
+ + + +
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
文章内容编辑
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+

选择封面

+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+ +
+
+{/block} +{block name="script"} + + +{/block} \ No newline at end of file diff --git a/application/admin/view/wechat/wechat_news_category/create.php b/application/admin/view/wechat/wechat_news_category/create.php new file mode 100644 index 00000000..cda77c62 --- /dev/null +++ b/application/admin/view/wechat/wechat_news_category/create.php @@ -0,0 +1 @@ + {include file="public/head"} {$title}
北京市 上海市 深圳市 - 提交 重置 */ ?>
\ No newline at end of file diff --git a/application/admin/view/wechat/wechat_news_category/edit.php b/application/admin/view/wechat/wechat_news_category/edit.php new file mode 100644 index 00000000..259a160f --- /dev/null +++ b/application/admin/view/wechat/wechat_news_category/edit.php @@ -0,0 +1 @@ + {include file="public/head"} {$title}
北京市 上海市 深圳市 - 提交 重置 */ ?>
\ No newline at end of file diff --git a/application/admin/view/wechat/wechat_news_category/index.php b/application/admin/view/wechat/wechat_news_category/index.php new file mode 100644 index 00000000..05c96f66 --- /dev/null +++ b/application/admin/view/wechat/wechat_news_category/index.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="head_top"} {/block} {block name="content"}
{volist name="list" id="vo"}
图文名称:{$vo.cate_name}
{volist name="$vo['new']" id="vvo" key="k"} {if condition="$k eq 1"}

{$vvo.title}

{else/}
{$vvo.title}
{/if} {/volist}
{/volist}
{include file="public/inner_page"}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/wechat/wechat_news_category/select.php b/application/admin/view/wechat/wechat_news_category/select.php new file mode 100644 index 00000000..bedef0b5 --- /dev/null +++ b/application/admin/view/wechat/wechat_news_category/select.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="head_top"} {/block} {block name="content"}
toArray(); $new_list = $new_list['data']; foreach ($new_list as $k=>$v){ $new_list[$k]['new'] = $v['new']->toArray(); } ?>
{volist name="list" id="vo"}
图文名称:{$vo.cate_name}
{volist name="$vo['new']" id="vvo" key="k"} {if condition="$k eq 1"}

{$vvo.title}

{else/}
{$vvo.title}
{/if} {/volist}
{/volist}
{include file="public/inner_page"}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/wechat/wechat_news_category/send_news.php b/application/admin/view/wechat/wechat_news_category/send_news.php new file mode 100644 index 00000000..936d739a --- /dev/null +++ b/application/admin/view/wechat/wechat_news_category/send_news.php @@ -0,0 +1 @@ +{extend name="public/container"} {block name="head_top"} {/block} {block name="content"}
{volist name="list" id="vo"}
图文名称:{$vo.cate_name}
{volist name="$vo['new']" id="vvo" key="k"} {if condition="$k eq 1"}

{$vvo.title}

{else/}
{$vvo.title}
{/if} {/volist}
{/volist}
{include file="public/inner_page"}
{/block} {block name="script"} {/block} \ No newline at end of file diff --git a/application/admin/view/wechat/wechat_template/index.php b/application/admin/view/wechat/wechat_template/index.php new file mode 100644 index 00000000..b8c6ec61 --- /dev/null +++ b/application/admin/view/wechat/wechat_template/index.php @@ -0,0 +1,111 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+ +
+ +
+
+
+
+
+
+ +
+ + +
+
+
+
+
+
+

主营行业:

+

副营行业:

+
+
+
+ + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
编号模板编号模板ID模板名回复内容状态添加时间操作
+ {$vo.id} + + {$vo.tempkey} + + {$vo.tempid} + + {$vo.name} + +
{$vo.content}
+
+ + + {$vo.add_time|date='Y-m-d H:i:s',###} + + + +
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/wechat/wechat_user/group.php b/application/admin/view/wechat/wechat_user/group.php new file mode 100644 index 00000000..436a5b46 --- /dev/null +++ b/application/admin/view/wechat/wechat_user/group.php @@ -0,0 +1,84 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + +{/block} +{block name="content"} +
+
+
+
+ + +
+
+
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + {/volist} + +
编号标签名人数操作
+ {$vo.id} + + {$vo.name} + + {$vo.count} + + {gt name="vo.id" value="99"} + + + {/gt} +
+
+
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/wechat/wechat_user/index.php b/application/admin/view/wechat/wechat_user/index.php new file mode 100644 index 00000000..f61802b5 --- /dev/null +++ b/application/admin/view/wechat/wechat_user/index.php @@ -0,0 +1,660 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + + + +{/block} +{block name="content"} +
+
+
+ +
+
+
+
+ +
+ 选择时间: + + + + + + +
+ +
+ + + + + + + + + + + +
+
+
+ 用户标签: + {volist name="tagList" id="vo"} + + {/volist} + +
+
+
+ + +
+
+ + + + + + + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + {if condition="$count"} + {volist name="list" id="vo"} + + + + + + + + + + + + + + + + + + + + + + {/volist} + {else/} + + {/if} + +
+
+ + +
+
编号微信用户名称头像 +
+ + +
+
地区 +
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
推广二维码 +
+ + +
+
用户标签操作
+ + + {$vo.uid} + + {$vo.nickname} + + {$vo.nickname} + + {if condition="$vo['sex'] eq 1"} + 男 + {elseif condition="$vo['sex'] eq 2"/} + 女 + {else/} + 保密 + {/if} + + {$vo.country}{$vo.province}{$vo.city} + + + + {$vo.second} + + {$vo.order_stair} + + {$vo.order_second} + + + + {if condition="$vo['subscribe']"} + 关注 + {else/} + 未关注 + {/if} + + {$vo.nickname} + + + 无 + + + 无 + + {$groupList[$vo['groupid']]['name']} + + + + + 无 + + + 无 + + {$tagList[$tag]['name']} + + + + + + +
+ + +
+
+
+ {include file="public/inner_page"} +
+
+
+
+{/block} +{block name="script"} + +{/block} diff --git a/application/admin/view/wechat/wechat_user/now_money.php b/application/admin/view/wechat/wechat_user/now_money.php new file mode 100644 index 00000000..ad8aa247 --- /dev/null +++ b/application/admin/view/wechat/wechat_user/now_money.php @@ -0,0 +1,45 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + {/volist} + +
金额收入/支出记录时间
+ {$vo.number} + + {if condition="$vo['pm']"} + 收入 + {else/} + 支出 + {/if} + + {$vo.mark} + + {$vo.add_time} +
+
+
+
+
+
+{/block} diff --git a/application/admin/view/wechat/wechat_user/stair.php b/application/admin/view/wechat/wechat_user/stair.php new file mode 100644 index 00000000..8214cf7c --- /dev/null +++ b/application/admin/view/wechat/wechat_user/stair.php @@ -0,0 +1,45 @@ +{extend name="public/container"} +{block name="content"} +
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + {/volist} + +
用户头像用户名称绑定时间订单个数获得佣金
+ {$vo.nickname} + + {$vo.nickname} + + {$vo.add_time|date="Y-m-d H:i:s",###} + + {$vo.uid|getOrderCount} + + {$vo.now_money} +
+
+
+
+
+
+{/block} diff --git a/application/admin/view/wechat/wechat_user/tag.php b/application/admin/view/wechat/wechat_user/tag.php new file mode 100644 index 00000000..d79c32e5 --- /dev/null +++ b/application/admin/view/wechat/wechat_user/tag.php @@ -0,0 +1,82 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + +{/block} +{block name="content"} +
+
+
+
+ + +
+
+
+
+
+
+
+ + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + {/volist} + +
编号标签名人数操作
+ {$vo.id} + + {$vo.name} + + {$vo.count} + + {gt name="vo.id" value="99"} + + + {/gt} +
+
+
+
+
+
+ +{/block} diff --git a/application/admin/view/widget/icon.php b/application/admin/view/widget/icon.php new file mode 100644 index 00000000..adde45f3 --- /dev/null +++ b/application/admin/view/widget/icon.php @@ -0,0 +1,820 @@ + + + + + icon + + + + + + + + + +
+
+ + + +
+
+
v4.3.0新增图标
+
    +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • +
+ + +
+
+ +
+
v4.2.0新增图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+ +
+
v4.1.0新增图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • + + +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
Web应用程序图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
Form Control Icons
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
货币图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
文本编辑器图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
方向图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
视频播放器图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
品牌图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+
医疗图标
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+
+
+ + + + + + diff --git a/application/admin/view/widget/images.php b/application/admin/view/widget/images.php new file mode 100644 index 00000000..b2d25d48 --- /dev/null +++ b/application/admin/view/widget/images.php @@ -0,0 +1,105 @@ + + + + + + + + + + +
+
+
+
+ + + +
+
+ +
+
+
+
+ + +
+
+ {volist name="list" id="vo"} +
+
+ +
+ {/volist} +
+
+ + + +
{$page}
+
+
+
+ + + + + diff --git a/application/command.php b/application/command.php new file mode 100644 index 00000000..826bb2b2 --- /dev/null +++ b/application/command.php @@ -0,0 +1,12 @@ + +// +---------------------------------------------------------------------- + +return []; diff --git a/application/common.php b/application/common.php new file mode 100644 index 00000000..1142f4d4 --- /dev/null +++ b/application/common.php @@ -0,0 +1,36 @@ + +// +---------------------------------------------------------------------- + +// 应用公共文件 + +/** + * 敏感词过滤 + * + * @param string + * @return string + */ +function sensitive_words_filter($str) +{ + if (!$str) return ''; + $file = ROOT_PATH. 'public/static/plug/censorwords/CensorWords'; + $words = file($file); + foreach($words as $word) + { + $word = str_replace(array("\r\n","\r","\n"," "), '', $word); + if (!$word) continue; + + $ret = preg_match("/$word/", $str, $match); + if ($ret) { + return $match[0]; + } + } + return ''; +} \ No newline at end of file diff --git a/application/config.php b/application/config.php new file mode 100644 index 00000000..c0245dd9 --- /dev/null +++ b/application/config.php @@ -0,0 +1,254 @@ + +// +---------------------------------------------------------------------- + +return [ + // +---------------------------------------------------------------------- + // | 应用设置 + // +---------------------------------------------------------------------- + + // 应用命名空间 + 'app_namespace' => 'app', + // 应用调试模式 + 'app_debug' => true, + // 应用Trace + 'app_trace' => false, + // 应用模式状态 + 'app_status' => '', + // 是否支持多模块 + 'app_multi_module' => true, + // 入口自动绑定模块 + 'auto_bind_module' => true, + // 注册的根命名空间 + 'root_namespace' => [ + 'model'=>'../model/' + ], + // 扩展函数文件 + 'extra_file_list' => [THINK_PATH . 'helper' . EXT], + // 默认输出类型 + 'default_return_type' => 'html', + // 默认AJAX 数据返回格式,可选json xml ... + 'default_ajax_return' => 'json', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', + // 默认时区 + 'default_timezone' => 'PRC', + // 是否开启多语言 + 'lang_switch_on' => false, + // 默认全局过滤方法 用逗号分隔多个 + 'default_filter' => '', + // 默认语言 + 'default_lang' => 'zh-cn', + // 应用类库后缀 + 'class_suffix' => false, + // 控制器类后缀 + 'controller_suffix' => false, + + // +---------------------------------------------------------------------- + // | 模块设置 + // +---------------------------------------------------------------------- + + // 默认模块名 + 'default_module' => 'admin', + // 禁止访问模块 + 'deny_module_list' => ['common'], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 默认验证器 + 'default_validate' => '', + // 默认的空控制器名 + 'empty_controller' => 'Error', + // 操作方法后缀 + 'action_suffix' => '', + // 自动搜索控制器 + 'controller_auto_search' => false, + + // +---------------------------------------------------------------------- + // | URL设置 + // +---------------------------------------------------------------------- + + // PATHINFO变量名 用于兼容模式 + 'var_pathinfo' => 's', + // 兼容PATH_INFO获取 + 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // URL普通方式参数 用于自动生成 + 'url_common_param' => false, + // URL参数方式 0 按名称成对解析 1 按顺序解析 + 'url_param_type' => 0, + // 是否开启路由 + 'url_route_on' => true, + // 路由使用完整匹配 + 'route_complete_match' => false, + // 路由配置文件(支持配置多个) + 'route_config_file' => ['route'], + // 是否强制使用路由 + 'url_route_must' => false, + // 域名部署 + 'url_domain_deploy' => false, + // 域名根,如thinkphp.cn + 'url_domain_root' => '', + // 是否自动转换URL中的控制器和操作名 + 'url_convert' => true, + // 默认的访问控制器层 + 'url_controller_layer' => 'controller', + // 表单请求类型伪装变量 + 'var_method' => '_method', + // 表单ajax伪装变量 + 'var_ajax' => '_ajax', + // 表单pjax伪装变量 + 'var_pjax' => '_pjax', + // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 + 'request_cache' => false, + // 请求缓存有效期 + 'request_cache_expire' => null, + // 全局请求缓存排除规则 + 'request_cache_except' => [], + + // +---------------------------------------------------------------------- + // | 模板设置 + // +---------------------------------------------------------------------- + + 'template' => [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 模板路径 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'php', + // 模板文件名分隔符 + 'view_depr' => DS, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', + ], + + // 视图输出字符串内容替换 + 'view_replace_str' => [ + '{__ADMIN_PATH}'=>'/public/system/', + '{__FRAME_PATH}'=>'/public/system/frame/', + '{__PLUG_PATH}'=>'/public/static/plug/', + '{__MODULE_PATH}'=>'/public/system/module/', + '{__STATIC_PATH}'=>'/public/static/', + '{__PUBLIC_PATH}'=>'/public/', + '{__WAP_PATH}'=>'/public/wap/' + ], + // 默认跳转页面对应的模板文件 + 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + + // +---------------------------------------------------------------------- + // | 异常及错误设置 + // +---------------------------------------------------------------------- + + // 异常页面的模板文件 + 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl', + + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => false, + // 异常处理handle类 留空使用 \think\exception\Handle + 'exception_handle' => '', + + // +---------------------------------------------------------------------- + // | 日志设置 + // +---------------------------------------------------------------------- + + 'log' => [ + // 日志记录方式,内置 file socket 支持扩展 + 'type' => 'File', + // 日志保存目录 + 'path' => LOG_PATH, + // 日志记录级别 + 'level' => [], + ], + + // +---------------------------------------------------------------------- + // | Trace设置 开启 app_trace 后 有效 + // +---------------------------------------------------------------------- + 'trace' => [ + // 内置Html Console 支持扩展 + 'type' => 'Html', + ], + + // +---------------------------------------------------------------------- + // | 缓存设置 + // +---------------------------------------------------------------------- + + 'cache' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => CACHE_PATH, + // 缓存前缀 + 'prefix' => '', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, + ], + + // +---------------------------------------------------------------------- + // | 会话设置 + // +---------------------------------------------------------------------- + + 'session' => [ + 'id' => '', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // SESSION 前缀 + 'prefix' => 'think', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + + 'expire' => 86400, + 'cache_expire' => 86400 + ], + + // +---------------------------------------------------------------------- + // | Cookie设置 + // +---------------------------------------------------------------------- + 'cookie' => [ + // cookie 名称前缀 + 'prefix' => '', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, + ], + + //分页配置 + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'page', + 'list_rows' => 15, + ], +]; diff --git a/application/constant.php b/application/constant.php new file mode 100644 index 00000000..ab5eae7c --- /dev/null +++ b/application/constant.php @@ -0,0 +1,3 @@ + +// +---------------------------------------------------------------------- + +return [ + // 数据库类型 + 'type' => 'mysql', + // 服务器地址 + 'hostname' => '127.0.0.1', + // 数据库名 + 'database' => '8_21', + // 用户名 + 'username' => 'root', + // 密码 + 'password' => 'root', + // 端口 + 'hostport' => '3306', + // 连接dsn + 'dsn' => '', + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => 'utf8', + // 数据库表前缀 + 'prefix' => 'eb_', + // 数据库调试模式 + 'debug' => false, + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 是否严格检查字段是否存在 + 'fields_strict' => false, + // 数据集返回类型 + 'resultset_type' => '\\think\\Collection', + // 自动写入时间戳字段 + 'auto_timestamp' => false, + // 时间字段取出后的默认时间格式 + 'datetime_format' => 'Y-m-d H:i:s', + // 是否需要进行SQL性能分析 + 'sql_explain' => false, +]; diff --git a/application/index.html b/application/index.html new file mode 100644 index 00000000..e69de29b diff --git a/application/index/config.php b/application/index/config.php new file mode 100644 index 00000000..37b8b458 --- /dev/null +++ b/application/index/config.php @@ -0,0 +1,23 @@ + +// +---------------------------------------------------------------------- + + +return [ + 'session' => [ + // SESSION 前缀 + 'prefix' => 'index', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + ], + 'empty_controller' =>'Index' +]; diff --git a/application/index/controller/Index.php b/application/index/controller/Index.php new file mode 100644 index 00000000..84832b89 --- /dev/null +++ b/application/index/controller/Index.php @@ -0,0 +1,13 @@ + +// +---------------------------------------------------------------------- +use \think\Route; + +Route::group('admin',function(){ + Route::rule('/index2','admin/Index/index2','get'); +// Route::controller('index','admin/Index'); +// resource('system_menus','SystemMenus'); +// Route::rule('/menus','SystemMenus','get'); +// Route::resource('menus','admin/SystemMenus',['var'=>['menus'=>'menu_id']]); +// Route::miss(function(){ +// return '页面不存在!'; +// }); +}); + diff --git a/application/routine/common.php b/application/routine/common.php new file mode 100644 index 00000000..c42a627d --- /dev/null +++ b/application/routine/common.php @@ -0,0 +1,53 @@ + +// +---------------------------------------------------------------------- + +// 应用公共文件 +if(!function_exists('unThumb')){ + function unThumb($src){ + return str_replace('/s_','/',$src); + } +} +/** +*判断拼团是否结束*/ +function isPinkStatus($pink){ + if(!$pink) return false; + return \app\wap\model\store\StorePink::isSetPinkOver($pink); +} + +/** + * 设置浏览信息 + * @param $uid + * @param int $product_id + * @param int $cate + * @param string $type + * @param string $content + * @param int $min + */ +function setView($uid,$product_id=0,$cate=0,$type='',$content='',$min=20){ + $Db=think\Db::name('store_visit'); + $view=$Db->where(['uid'=>$uid,'product_id'=>$product_id])->field('count,add_time,id')->find(); + if($view && $type!='search'){ + $time=time(); + if(($view['add_time']+$min)<$time){ + $Db->where(['id'=>$view['id']])->update(['count'=>$view['count']+1,'add_time'=>time()]); + } + }else{ + $Db->insert([ + 'add_time'=>time(), + 'count'=>1, + 'product_id'=>$product_id, + 'cate_id'=>$cate, + 'type'=>$type, + 'uid'=>$uid, + 'content'=>$content + ]); + } +} \ No newline at end of file diff --git a/application/routine/config.php b/application/routine/config.php new file mode 100644 index 00000000..8e8af14a --- /dev/null +++ b/application/routine/config.php @@ -0,0 +1,22 @@ + +// +---------------------------------------------------------------------- + + +return [ + 'session' => [ + // SESSION 前缀 + 'prefix' => 'routine', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + ], +]; diff --git a/application/routine/controller/AuthApi.php b/application/routine/controller/AuthApi.php new file mode 100644 index 00000000..a6c49afc --- /dev/null +++ b/application/routine/controller/AuthApi.php @@ -0,0 +1,1973 @@ +userInfo); + } + + /** + * 获取退款理由 + */ + public function get_refund_reason(){ + $reason = SystemConfig::getValue('refund_reason')?:[];//退款理由 + $reason = explode('=',$reason); + return JsonService::successful($reason); + } + + /** + * 获取提现银行 + */ + public function get_user_extract_bank(){ + $extractBank = SystemConfig::getValue('user_extract_bank')?:[];//提现银行 + $extractBank = explode('=',$extractBank); + return JsonService::successful($extractBank); + } + /** + * 首页 + */ + public function index(){ + $banner = GroupDataService::getData('routine_home_banner')?:[];//banner图 + $menus = GroupDataService::getData('routine_home_menus')?:[];//banner图 + $lovely = GroupDataService::getData('routine_lovely')?:[];//猜你喜欢图 + $best = StoreProduct::getBestProduct('id,image,store_name,cate_id,price,unit_name,sort',8);//精品推荐 + $new = StoreProduct::getNewProduct('id,image,store_name,cate_id,price,unit_name,sort',3);//今日上新 + $hot = StoreProduct::getHotProduct('id,image,store_name,cate_id,price,unit_name,sort',6);//猜你喜欢 + $data['banner'] = $banner; + $data['lovely'] = $lovely; + $data['menus'] = $menus; + $data['best'] = $best; + $data['new'] = $new; + $data['hot'] = $hot; + return JsonService::successful($data); + } + + /** + * 猜你喜欢 加载 + * @param Request $request + */ + public function get_hot_product(Request $request){ + $data = UtilService::postMore([['offset',0],['limit',0]],$request); + $hot = StoreProduct::getHotProductLoading('id,image,store_name,cate_id,price,unit_name,sort',$data['offset'],$data['limit']);//猜你喜欢 + return JsonService::successful($hot); + } + /** + * 分类搜索页面 + * @param Request $request + * @return \think\response\Json + */ + public function store(){ + $model = StoreProduct::validWhere(); + if($_GET){$data = $_GET['value']; + if($data!=''){ + $model = $model->where('store_name','LIKE',"%$data%")->whereOr('keyword','LIKE',"%$data%"); + if((int)$data) $model = $model->whereOr('id',$data); + } + $list = $model->field('id,store_name,cate_id,image,sales,price,stock')->select()->toArray(); + return JsonService::successful($list); + } + } + /** + * 分类页面 + * @param Request $request + * @return \think\response\Json + */ + public function store1(Request $request){ + $data = UtilService::postMore([['keyword',''],['cid',''],['sid','']],$request); + $keyword = addslashes($data['keyword']); + $cid = intval($data['cid']); + $sid = intval($data['sid']); + $category = null; + if($sid) $category = StoreCategory::get($sid); + if($cid && !$category) $category = StoreCategory::get($cid); + $data['keyword'] = $keyword; + $data['cid'] = $cid; + $data['sid'] = $sid; + return JsonService::successful($data); + } + /** + * 一级分类 + * @return \think\response\Json + */ + public function get_pid_cate(){ + $data = StoreCategory::pidByCategory(0,'id,cate_name');//一级分类 + return JsonService::successful($data); + } + /** + * 最小提现金额 + * @return \think\response\Json + */ + public function minmoney(){ + $data = SystemConfig::getValue('user_extract_min_price');//最小提现金额 + return JsonService::successful($data); + } + /** + * 二级分类 + * @param Request $request + * @return \think\response\Json + */ + public function get_id_cate(Request $request){ + $data = UtilService::postMore([['id',0]],$request); + $dataCateA = []; + $dataCateA[0]['id'] = $data['id']; + $dataCateA[0]['cate_name'] = '全部商品'; + $dataCateA[0]['pid'] = 0; + $dataCateE = StoreCategory::pidBySidList($data['id']);//根据一级分类获取二级分类 + if($dataCateE) $dataCateE = $dataCateE->toArray(); + $dataCate = []; + $dataCate = array_merge_recursive($dataCateA,$dataCateE); + return JsonService::successful($dataCate); + } + /** + * 分类页面产品 + * @param string $keyword + * @param int $cId + * @param int $sId + * @param string $priceOrder + * @param string $salesOrder + * @param int $news + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_product_list(Request $request) + { + $data = UtilService::getMore([ + ['sid',0], + ['cid',0], + ['keyword',''], + ['priceOrder',''], + ['salesOrder',''], + ['news',0], + ['first',0], + ['limit',0] + ],$request); + $sId = $data['sid']; + $cId = $data['cid']; + $keyword = $data['keyword']; + $priceOrder = $data['priceOrder']; + $salesOrder = $data['salesOrder']; + $news = $data['news']; + $first = $data['first']; + $limit = $data['limit']; + $model = StoreProduct::validWhere(); + if($sId){ + $model->where('cate_id',$sId); + }elseif($cId){ + $sids = StoreCategory::pidBySidList($cId)?:[]; + if($sids){ + $sidsr = []; + foreach($sids as $v){ + $sidsr[] = $v['id']; + } + $model->where('cate_id','IN',$sidsr); + } + } + if(!empty($keyword)) $model->where('keyword|store_name','LIKE',htmlspecialchars("%$keyword%")); + if($news!=0) $model->where('is_new',1); + $baseOrder = ''; + if($priceOrder) $baseOrder = $priceOrder == 'desc' ? 'price DESC' : 'price ASC'; + if($salesOrder) $baseOrder = $salesOrder == 'desc' ? 'sales DESC' : 'sales ASC'; + if($baseOrder) $baseOrder .= ', '; + $model->order($baseOrder.'sort DESC, add_time DESC'); + $list = $model->limit($first,$limit)->field('id,store_name,cate_id,image,sales,price,stock')->select()->toArray(); + return JsonService::successful($list); + } + /** + * 购物车 + * @return \think\response\Json + */ + public function get_cart_list(){ + return JsonService::successful(StoreCart::getUserProductCartList($this->userInfo['uid'])); + } + /** + * 商品详情页 + * @param Request $request + */ + public function details(Request $request){ + $data = UtilService::postMore(['id'],$request); + $id = $data['id']; + if(!$id || !($storeInfo = StoreProduct::getValidProduct($id))) return JsonService::fail('商品不存在或已下架'); + $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($id,$this->userInfo['uid'],'collect'); + list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($id); + setView($this->userInfo['uid'],$id,$storeInfo['cate_id'],'viwe'); + foreach ($productAttr as $k=>$v){ + $attr = $v['attr_values']; +// unset($productAttr[$k]['attr_values']); + foreach ($attr as $kk=>$vv){ + $productAttr[$k]['attr_value'][$kk]['attr'] = $vv; + $productAttr[$k]['attr_value'][$kk]['check'] = false; + } + } + $data['storeInfo'] = $storeInfo; + $data['similarity'] = StoreProduct::cateIdBySimilarityProduct($storeInfo['cate_id'],'id,store_name,image,price,sales',4); + $data['productAttr'] = $productAttr; + $data['productValue'] = $productValue; + $data['reply'] = StoreProductReply::getRecProductReply($storeInfo['id']); + $data['replyCount'] = StoreProductReply::productValidWhere()->where('product_id',$storeInfo['id'])->count(); + $data['mer_id'] = StoreProduct::where('id',$storeInfo['id'])->value('mer_id'); + return JsonService::successful($data); + } + + /** + * 获取产品评论 + * @param int $productId + * @return \think\response\Json + */ + public function get_product_reply($productId = 0){ + if(!$productId) return JsonService::fail('参数错误'); + $replyCount = StoreProductReply::productValidWhere()->where('product_id',$productId)->count(); + $reply = StoreProductReply::getRecProductReply($productId); + return JsonService::successful(['replyCount'=>$replyCount,'reply'=>$reply]); +} + /** + * 订单页面 + * @param Request $request + * @return \think\response\Json + */ + public function confirm_order(Request $request){ + $data = UtilService::postMore(['cartId'],$request); + $cartId = $data['cartId']; + if(!is_string($cartId) || !$cartId ) return JsonService::fail('请提交购买的商品'); + $cartGroup = StoreCart::getUserProductCartList($this->userInfo['uid'],$cartId,1); + if(count($cartGroup['invalid'])) return JsonService::fail($cartGroup['invalid'][0]['productInfo']['store_name'].'已失效!'); + if(!$cartGroup['valid']) return JsonService::fail('请提交购买的商品'); + $cartInfo = $cartGroup['valid']; + $priceGroup = StoreOrder::getOrderPriceGroup($cartInfo); + $other = [ + 'offlinePostage'=>SystemConfigService::get('offline_postage'), + 'integralRatio'=>SystemConfigService::get('integral_ratio') + ]; + $usableCoupon = StoreCouponUser::beUsableCoupon($this->userInfo['uid'],$priceGroup['totalPrice']); + $cartIdA = explode(',',$cartId); + if(count($cartIdA) > 1) $seckill_id=0; + else{ + $seckillinfo = StoreCart::where('id',$cartId)->find(); + if((int)$seckillinfo['seckill_id']>0) $seckill_id=$seckillinfo['seckill_id']; + else $seckill_id=0; + } + $data['usableCoupon'] = $usableCoupon; + $data['seckill_id'] = $seckill_id; + $data['cartInfo'] = $cartInfo; + $data['priceGroup'] = $priceGroup; + $data['orderKey'] = StoreOrder::cacheOrderInfo($this->userInfo['uid'],$cartInfo,$priceGroup,$other); + $data['offlinePostage'] = $other['offlinePostage']; + $data['userInfo'] = User::getUserInfo($this->userInfo['uid']); + $data['integralRatio'] = $other['integralRatio']; + return JsonService::successful($data); + } + + /** + * 获取可以使用的优惠券 + * @param int $totalPrice + * @return \think\response\Json + */ + public function get_use_coupon_order($totalPrice = 0){ + return JsonService::successful(StoreCouponUser::beUsableCouponList($this->userInfo['uid'],$totalPrice)); + } + /** + * 秒杀列表页 + * @return \think\response\Json + */ + public function seckill_index(){ + $lovely = GroupDataService::getData('routine_lovely')?:[];//banner图 + $seckill = StoreSeckill::where('is_del',0)->where('status',1)->where('start_time','<',time())->where('stop_time','>',time())->order('sort desc')->select()->toArray(); + $data['seckill'] = $seckill; + $data['lovely'] = $lovely; + return JsonService::successful($data); + } + /** + * 秒杀详情页 + * @param Request $request + * @return \think\response\Json + */ + public function seckill_detail(Request $request){ + $data = UtilService::postMore(['id'],$request); + $id = $data['id']; + if(!$id || !($storeInfo = StoreSeckill::getValidProduct($id))) return JsonService::fail('商品不存在或已下架!'); + $storeInfo['userLike'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'like','product_seckill'); + $storeInfo['like_num'] = StoreProductRelation::productRelationNum($storeInfo['product_id'],'like','product_seckill'); + $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'collect','product_seckill'); + $data['storeInfo'] = $storeInfo; + setView($this->userInfo['uid'],$id,$storeInfo['product_id'],'viwe'); + $data['reply'] = StoreProductReply::getRecProductReply($storeInfo['product_id']); + $data['replyCount'] = StoreProductReply::productValidWhere()->where('product_id',$storeInfo['id'])->count(); + return JsonService::successful($data); + } + + /** + * 个人中心 + * @return \think\response\Json + */ + public function my(){ + $this->userInfo['couponCount'] = StoreCouponUser::getUserValidCouponCount($this->userInfo['uid']); + $this->userInfo['like'] = StoreProductRelation::getUserIdLike($this->userInfo['uid']);; + $this->userInfo['orderStatusNum'] = StoreOrder::getOrderStatusNum($this->userInfo['uid']); + $this->userInfo['notice'] = UserNotice::getNotice($this->userInfo['uid']); + $this->userInfo['statu'] = (int)SystemConfig::getValue('store_brokerage_statu'); +// $this->userInfo['service_phone'] = SystemConfig::getValue('service_phone'); +// $this->userInfo['service_phone_str'] = SystemConfig::getValue('service_phone_str'); + return JsonService::successful($this->userInfo); + } + + + /** + * 用户签到 + * @return \think\response\Json + */ + public function user_sign() + { + $signed = UserSign::checkUserSigned($this->userInfo['uid']); + if($signed) return JsonService::fail('已签到'); + if(false !== $integral = UserSign::sign($this->userInfo)) + return JsonService::successful('签到获得'.floatval($integral).'积分'); + else + return JsonService::fail('签到失败!'); + } + /** + * 过度查$uniqueId + * @param string $productId + * @param int $cartNum + * @param string $uniqueId + * @return \think\response\Json + */ + public function unique(){ + $productId=$_GET['productId']; + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $uniqueId=StoreProductAttrValue::where('product_id',$productId)->value('unique'); + $data=$this->set_cart($productId,$cartNum = 1,$uniqueId); + if($data==true){ + return JsonService::successful('ok'); + } + + } + /** + * 加入到购物车 + * @param string $productId + * @param int $cartNum + * @param string $uniqueId + * @return \think\response\Json + */ + public function set_cart($productId = '',$cartNum = 1,$uniqueId = ''){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreCart::setCart($this->userInfo['uid'],$productId,$cartNum,$uniqueId,'product'); + if(!$res) return JsonService::fail(StoreCart::getErrorInfo()); + else{ +// HookService::afterListen('store_product_set_cart_after',$res,$this->userInfo,false,StoreProductBehavior::class); + return JsonService::successful('ok',['cartId'=>$res->id]); + } + } + + /** + * 拼团 秒杀 砍价 加入到购物车 + * @param string $productId + * @param int $cartNum + * @param string $uniqueId + * @param int $combinationId + * @param int $secKillId + * @return \think\response\Json + */ + public function now_buy($productId = '',$cartNum = 1,$uniqueId = '',$combinationId = 0,$secKillId = 0,$bargainId = 0){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + if($bargainId && StoreBargainUserHelp::getSurplusPrice($bargainId,$this->userInfo['uid'])) return JsonService::fail('请先砍价'); + $res = StoreCart::setCart($this->userInfo['uid'],$productId,$cartNum,$uniqueId,'product',1,$combinationId,$secKillId,$bargainId); + if(!$res) return JsonService::fail(StoreCart::getErrorInfo()); + else return JsonService::successful('ok',['cartId'=>$res->id]); + } + + /** + * 添加点赞 + * @param string $productId + * @param string $category + * @return \think\response\Json + */ + public function like_product($productId = '',$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::productRelation($productId,$this->userInfo['uid'],'like',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 取消点赞 + * @param string $productId + * @param string $category + * @return \think\response\Json + */ + public function unlike_product($productId = '',$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::unProductRelation($productId,$this->userInfo['uid'],'like',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 添加收藏 + * @param $productId + * @param string $category + * @return \think\response\Json + */ + public function collect_product($productId,$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::productRelation($productId,$this->userInfo['uid'],'collect',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 批量收藏 + * @param string $productId + * @param string $category + * @return \think\response\Json + */ + public function collect_product_all($productId = '',$category = 'product'){ + if($productId == '') return JsonService::fail('参数错误'); + $productIdS = explode(',',$productId); + $res = StoreProductRelation::productRelationAll($productIdS,$this->userInfo['uid'],'collect',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 取消收藏 + * @param $productId + * @param string $category + * @return \think\response\Json + */ + public function uncollect_product($productId,$category = 'product'){ + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误'); + $res = StoreProductRelation::unProductRelation($productId,$this->userInfo['uid'],'collect',$category); + if(!$res) return JsonService::fail(StoreProductRelation::getErrorInfo()); + else return JsonService::successful(); + } + + /** + * 获取购物车数量 + * @return \think\response\Json + */ + public function get_cart_num(){ + return JsonService::successful('ok',StoreCart::getUserCartNum($this->userInfo['uid'],'product')); + } + + /** + * 修改购物车产品数量 + * @param string $cartId + * @param string $cartNum + * @return \think\response\Json + */ + public function change_cart_num($cartId = '',$cartNum = ''){ + if(!$cartId || !$cartNum || !is_numeric($cartId) || !is_numeric($cartNum)) return JsonService::fail('参数错误!'); + StoreCart::changeUserCartNum($cartId,$cartNum,$this->userInfo['uid']); + return JsonService::successful(); + } + + /** + * 删除购物车产品 + * @param string $ids + * @return \think\response\Json + */ + public function remove_cart($ids=''){ + if(!$ids) return JsonService::fail('参数错误!'); + StoreCart::removeUserCart($this->userInfo['uid'],$ids); + return JsonService::successful(); + } + + + /** + * 获取用户优惠券 + * @return \think\response\Json + */ + public function get_use_coupons(){ + + if($_GET){ + if($_GET['types']==0||$_GET['types']==''){ + $list= StoreCouponUser::getUserAllCoupon($this->userInfo['uid']); + }elseif($_GET['types']==1){ + $list=StoreCouponUser::getUserValidCoupon($this->userInfo['uid']); + }elseif($_GET['types']==2){ + $list=StoreCouponUser::getUserAlreadyUsedCoupon($this->userInfo['uid']); + }else{ + $list=StoreCouponUser::getUserBeOverdueCoupon($this->userInfo['uid']); + } + foreach ($list as &$v){ + $v['add_time'] = date('Y/m/d',$v['add_time']); + $v['end_time'] = date('Y/m/d',$v['end_time']); + } + return JsonService::successful($list); + } + + } + /** + * 获取用户优惠券 + * @return \think\response\Json + */ + public function get_use_coupon(){ + + return JsonService::successful('',StoreCouponUser::getUserAllCoupon($this->userInfo['uid'])); + } + + /** + * 获取收藏产品 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_user_collect_product($first = 0,$limit = 8) + { + $list = StoreProductRelation::where('A.uid',$this->userInfo['uid']) + ->field('B.id pid,B.store_name,B.price,B.ot_price,B.sales,B.image,B.is_del,B.is_show')->alias('A') + ->where('A.type','collect')->where('A.category','product') + ->order('A.add_time DESC')->join('__STORE_PRODUCT__ B','A.product_id = B.id') + ->limit($first,$limit)->select()->toArray(); + foreach ($list as $k=>$product){ + if($product['pid']){ + $list[$k]['is_fail'] = $product['is_del'] && $product['is_show']; + }else{ + unset($list[$k]); + } + } + return JsonService::successful($list); + } + /** + * 获取收藏产品删除 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_user_collect_product_del() + { + if($_GET){ + $list = StoreProductRelation::where('uid',$this->userInfo['uid'])->where('product_id',$_GET['pid'])->delete(); + return JsonService::successful($list); + } + + } + + /** + * 设置为默认地址 + * @param string $addressId + * @return \think\response\Json + */ + public function set_user_default_address($addressId = '') + { + if(!$addressId || !is_numeric($addressId)) return JsonService::fail('参数错误!'); + if(!UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])) + return JsonService::fail('地址不存在!'); + $res = UserAddress::setDefaultAddress($addressId,$this->userInfo['uid']); + if(!$res) + return JsonService::fail('地址不存在!'); + else + return JsonService::successful(); + } + + /** + * 修改收货地址 + * @return \think\response\Json + */ + public function edit_user_address() + { + $request = Request::instance(); + if(!$request->isPost()) return JsonService::fail('参数错误!'); + $addressInfo = UtilService::postMore([ + ['address',[]], + ['is_default',false], + ['real_name',''], + ['post_code',''], + ['phone',''], + ['detail',''], + ['id',0] + ],$request); + $addressInfo['province'] = $addressInfo['address']['province']; + $addressInfo['city'] = $addressInfo['address']['city']; + $addressInfo['district'] = $addressInfo['address']['district']; + $addressInfo['is_default'] = $addressInfo['is_default'] == true ? 1 : 0; + $addressInfo['uid'] = $this->userInfo['uid']; + unset($addressInfo['address']); + + if($addressInfo['id'] && UserAddress::be(['id'=>$addressInfo['id'],'uid'=>$this->userInfo['uid'],'is_del'=>0])){ + $id = $addressInfo['id']; + unset($addressInfo['id']); + if(UserAddress::edit($addressInfo,$id,'id')){ + if($addressInfo['is_default']) + UserAddress::setDefaultAddress($id,$this->userInfo['uid']); + return JsonService::successful(); + }else + return JsonService::fail('编辑收货地址失败!'); + }else{ + if($address = UserAddress::set($addressInfo)){ + if($addressInfo['is_default']) + UserAddress::setDefaultAddress($address->id,$this->userInfo['uid']); + return JsonService::successful(); + }else + return JsonService::fail('添加收货地址失败!'); + } + + + } + + /** + * 获取一条用户地址 + * @param string $addressId + * @return \think\response\Json + */ + public function get_user_address($addressId = ''){ + $addressInfo = []; + if($addressId && is_numeric($addressId) && UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])){ + $addressInfo = UserAddress::find($addressId); + } + return JsonService::successful($addressInfo); + } + + + /** + * 获取默认地址 + * @return \think\response\Json + */ + public function user_default_address() + { + $defaultAddress = UserAddress::getUserDefaultAddress($this->userInfo['uid'],'id,real_name,phone,province,city,district,detail,is_default'); + if($defaultAddress) return JsonService::successful('ok',$defaultAddress); + else return JsonService::successful('empty',[]); + } + + /** + * 删除地址 + * @param string $addressId + * @return \think\response\Json + */ + public function remove_user_address($addressId = '') + { + if(!$addressId || !is_numeric($addressId)) return JsonService::fail('参数错误!'); + if(!UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])) + return JsonService::fail('地址不存在!'); + if(UserAddress::edit(['is_del'=>'1'],$addressId,'id')) + return JsonService::successful(); + else + return JsonService::fail('删除地址失败!'); + } + + /** + * 创建订单 + * @param string $key + * @return \think\response\Json + */ + public function create_order($key = '') + { + if(!$key) return JsonService::fail('参数错误!'); + if(StoreOrder::be(['order_id|unique'=>$key,'uid'=>$this->userInfo['uid'],'is_del'=>0])) + return JsonService::status('extend_order','订单已生成',['orderId'=>$key,'key'=>$key]); + list($addressId,$couponId,$payType,$useIntegral,$mark,$combinationId,$pinkId,$seckill_id,$formId,$bargainId) = UtilService::postMore([ + 'addressId','couponId','payType','useIntegral','mark',['combinationId',0],['pinkId',0],['seckill_id',0],['formId',''],['bargainId',''] + ],Request::instance(),true); + $payType = strtolower($payType); + if($bargainId) StoreBargainUser::setBargainUserStatus($bargainId,$this->userInfo['uid']);//修改砍价状态 + if($pinkId) if(StorePink::getIsPinkUid($pinkId,$this->userInfo['uid'])) return JsonService::status('ORDER_EXIST','订单生成失败,你已经在该团内不能再参加了',['orderId'=>StoreOrder::getStoreIdPink($pinkId,$this->userInfo['uid'])]); + if($pinkId) if(StoreOrder::getIsOrderPink($pinkId,$this->userInfo['uid'])) return JsonService::status('ORDER_EXIST','订单生成失败,你已经参加该团了,请先支付订单',['orderId'=>StoreOrder::getStoreIdPink($pinkId,$this->userInfo['uid'])]); + $order = StoreOrder::cacheKeyCreateOrder($this->userInfo['uid'],$key,$addressId,$payType,$useIntegral,$couponId,$mark,$combinationId,$pinkId,$seckill_id,$bargainId); + $orderId = $order['order_id']; + $info = compact('orderId','key'); + if($orderId){ + if($payType == 'weixin'){ + $orderInfo = StoreOrder::where('order_id',$orderId)->find(); + if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!'); + if($orderInfo['paid']) exception('支付已支付!'); + if(bcsub((float)$orderInfo['pay_price'],0,2) <= 0){ + if(StoreOrder::jsPayPrice($orderId,$this->userInfo['uid'],$formId)) + return JsonService::status('success','微信支付成功',$info); + else + return JsonService::status('pay_error',StoreOrder::getErrorInfo()); + }else{ + try{ + $jsConfig = StoreOrder::jsPay($orderId); + }catch (\Exception $e){ + return JsonService::status('pay_error',$e->getMessage(),$info); + } + $info['jsConfig'] = $jsConfig; + return JsonService::status('wechat_pay','订单创建成功',$info); + } + }else if($payType == 'yue'){ + if(StoreOrder::yuePay($orderId,$this->userInfo['uid'],$formId)) + return JsonService::status('success','余额支付成功',$info); + else + return JsonService::status('pay_error',StoreOrder::getErrorInfo()); + }else if($payType == 'offline'){ +// RoutineTemplate::sendOrderSuccess($formId,$orderId);//发送模板消息 + return JsonService::status('success','订单创建成功',$info); + } + }else{ + return JsonService::fail(StoreOrder::getErrorInfo('订单生成失败!')); + } + } + + /** + * 获取订单列表 + * @param string $type + * @param int $first + * @param int $limit + * @param string $search + * @return \think\response\Json + */ + public function get_user_order_list($type = '',$first = 0, $limit = 8,$search = '') + { +// StoreOrder::delCombination();//删除拼团未支付订单 + if($search){ + $order = StoreOrder::searchUserOrder($this->userInfo['uid'],$search)?:[]; + $list = $order == false ? [] : [$order]; + }else{ + $list = StoreOrder::getUserOrderList($this->userInfo['uid'],$type,$first,$limit); + } + foreach ($list as $k=>$order){ + $list[$k] = StoreOrder::tidyOrder($order,true); + if($list[$k]['_status']['_type'] == 3){ + foreach ($order['cartInfo']?:[] as $key=>$product){ + $list[$k]['cartInfo'][$key]['is_reply'] = StoreProductReply::isReply($product['unique'],'product'); + } + } + } + return JsonService::successful($list); + } + + /** + * 订单详情页 + * @param string $order_id + * @return \think\response\Json + */ + public function get_order($uni = ''){ + if($uni == '') return JsonService::fail('参数错误'); + $order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni); + if(!$order) return JsonService::fail('订单不存在'); + return JsonService::successful(StoreOrder::tidyOrder($order,true)); + } + + /** + * 获取订单内的某个产品信息 + * @param string $uni + * @param string $productId + * @return \think\response\Json + */ + public function get_order_product($unique = ''){ + if(!$unique || !StoreOrderCartInfo::be(['unique'=>$unique]) || !($cartInfo = StoreOrderCartInfo::where('unique',$unique)->find())) return JsonService::fail('评价产品不存在!'); + return JsonService::successful($cartInfo); + } + /** + * 删除订单 + * @param string $uni + * @return \think\response\Json + */ + public function user_remove_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + $res = StoreOrder::removeOrder($uni,$this->userInfo['uid']); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + /** + * 支付订单 + * @param string $uni + * @return \think\response\Json + */ + public function pay_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + $order= StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni); + if(!$order) return JsonService::fail('订单不存在!'); + if($order['paid']) return JsonService::fail('该订单已支付!'); + if($order['pink_id']) if(StorePink::isPinkStatus($order['pink_id'])) return JsonService::fail('该订单已失效!'); + if($order['pay_type'] == 'weixin'){ + try{ + $jsConfig = StoreOrder::jsPay($order); + }catch (\Exception $e){ + return JsonService::fail($e->getMessage()); + } + return JsonService::status('wechat_pay',['jsConfig'=>$jsConfig,'order_id'=>$order['order_id']]); + }else if($order['pay_type'] == 'yue'){ + if($res = StoreOrder::yuePay($order['order_id'],$this->userInfo['uid'])) + return JsonService::successful('余额支付成功'); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + }else if($order['pay_type'] == 'offline'){ + StoreOrder::createOrderTemplate($order); + return JsonService::successful('订单创建成功'); + } + } + + /** + * 申请退款 + * @param string $uni + * @param string $text + * @return \think\response\Json + */ + public function apply_order_refund(Request $request,$uni = '') + { + $data = UtilService::postMore([ + ['text',''], + ['refund_reason_wap_img',''], + ['refund_reason_wap_explain',''], + ],$request); + if($data['refund_reason_wap_img']){ + $data['refund_reason_wap_img'] = explode(',',$data['refund_reason_wap_img']); + } + if(!$uni || $data['text'] == '') return JsonService::fail('参数错误!'); + $res = StoreOrder::orderApplyRefund($uni,$this->userInfo['uid'],$data['text'],$data['refund_reason_wap_explain'],$data['refund_reason_wap_img']); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + /** + * 用户确认收货 + * @param string $uni + * @return \think\response\Json + */ + public function user_take_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + + $res = StoreOrder::takeOrder($uni,$this->userInfo['uid']); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + /** + * 充值 + * @param int $price + * @return \think\response\Json + */ + public function user_wechat_recharge($price = 0) + { + if(!$price || $price <=0) return JsonService::fail('参数错误'); + $storeMinRecharge = SystemConfigService::get('store_user_min_recharge'); + if($price < $storeMinRecharge) return JsonService::fail('充值金额不能低于'.$storeMinRecharge); + $rechargeOrder = UserRecharge::addRecharge($this->userInfo['uid'],$price); + if(!$rechargeOrder) return JsonService::fail('充值订单生成失败!'); + try{ + return JsonService::successful(UserRecharge::jsPay($rechargeOrder)); + }catch (\Exception $e){ + return JsonService::fail($e->getMessage()); + } + } + + /** + * 余额使用记录 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function user_balance_list($first = 0,$limit = 8) + { + $list = UserBill::where('uid',$this->userInfo['uid'])->where('category','now_money') + ->field('mark,pm,number,add_time') + ->where('status',1)->order('add_time DESC')->limit($first,$limit)->select()->toArray(); + foreach ($list as &$v){ + $v['add_time'] = date('Y/m/d H:i',$v['add_time']); + } + return JsonService::successful($list); + } + + /** + * 积分使用记录 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function user_integral_list($first = 0,$limit = 8) + { + $list = UserBill::where('uid',$this->userInfo['uid'])->where('category','integral') + ->field('mark,pm,number,add_time') + ->where('status',1)->order('add_time DESC')->limit($first,$limit)->select()->toArray(); + foreach ($list as &$v){ + $v['add_time'] = date('Y/m/d H:i',$v['add_time']); + $v['number'] = floatval($v['number']); + } + return JsonService::successful($list); + + } + + /** + * 评价订单 + * @param string $unique + * @return \think\response\Json + */ + public function user_comment_product($unique = '') + { + if(!$unique) return JsonService::fail('参数错误!'); + $cartInfo = StoreOrderCartInfo::where('unique',$unique)->find(); + $uid = $this->userInfo['uid']; + if(!$cartInfo || $uid != $cartInfo['cart_info']['uid']) return JsonService::fail('评价产品不存在!'); + if(StoreProductReply::be(['oid'=>$cartInfo['oid'],'unique'=>$unique])) + return JsonService::fail('该产品已评价!'); + $group = UtilService::postMore([ + ['comment',''],['pics',[]],['product_score',5],['service_score',5] + ],Request::instance()); + $group['comment'] = htmlspecialchars(trim($group['comment'])); + if($group['product_score'] < 1) return JsonService::fail('请为产品评分'); + else if($group['service_score'] < 1) return JsonService::fail('请为商家服务评分'); + if($cartInfo['cart_info']['combination_id']) $productId = $cartInfo['cart_info']['product_id']; + else if($cartInfo['cart_info']['seckill_id']) $productId = $cartInfo['cart_info']['product_id']; + else if($cartInfo['cart_info']['bargain_id']) $productId = $cartInfo['cart_info']['product_id']; + else $productId = $cartInfo['product_id']; + $group = array_merge($group,[ + 'uid'=>$uid, + 'oid'=>$cartInfo['oid'], + 'unique'=>$unique, + 'product_id'=>$productId, + 'reply_type'=>'product' + ]); + StoreProductReply::beginTrans(); + $res = StoreProductReply::reply($group,'product'); + if(!$res) { + StoreProductReply::rollbackTrans(); + return JsonService::fail('评价失败!'); + } + try{ +// HookService::listen('store_product_order_reply',$group,$cartInfo,false,StoreProductBehavior::class); + StoreOrder::checkOrderOver($cartInfo['oid']); + }catch (\Exception $e){ + StoreProductReply::rollbackTrans(); + return JsonService::fail($e->getMessage()); + } + StoreProductReply::commitTrans(); + return JsonService::successful(); + } + + /** + * 上传图片 + * @param string $filename + * @return \think\response\Json + */ + public function upload(Request $request) + { + $data = UtilService::postMore([['filename','']],$request); + $res = UploadService::image($data['filename'],'store/comment'); + if($res->status == 200) + return JsonService::successful('图片上传成功!',['name'=>$res->fileInfo->getSaveName(),'url'=>UploadService::pathToUrl($res->dir)]); + else + return JsonService::fail($res->error); + } + + /** + * 获取一级和二级分类 + * @return \think\response\Json + */ + public function get_product_category() + { + $parentCategory = StoreCategory::pidByCategory(0,'id,cate_name')->toArray(); + foreach ($parentCategory as $k=>$category){ + $category['child'] = StoreCategory::pidByCategory($category['id'],'id,cate_name')->toArray(); + $parentCategory[$k] = $category; + } + return JsonService::successful($parentCategory); + } + + /** + * 获取一级推荐人 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_spread_list($first = 0,$limit = 20) + { + $list = User::where('spread_uid',$this->userInfo['uid'])->field('uid,nickname,avatar,add_time')->limit($first,$limit)->order('add_time DESC')->select()->toArray(); + foreach ($list as $k=>$user){ + $list[$k]['add_time'] = date('Y/m/d',$user['add_time']); + $list[$k]['price'] = StoreOrder::getUserPrice($user['uid']); + } + $count = User::where('spread_uid',$this->userInfo['uid'])->field('uid,nickname,avatar,add_time')->count(); + $data['count'] = $count; + $data['list'] = $list; + return JsonService::successful($data); + } + + /** + * 获取二级推荐人 + * @param int $first + * @param int $limit + * @return \think\response\Json + */ + public function get_spread_list_two($two_uid=0,$first = 0,$limit = 20) + { + $list = User::where('spread_uid',$two_uid)->field('uid,nickname,avatar,add_time')->limit($first,$limit)->order('add_time DESC')->select()->toArray(); + foreach ($list as $k=>$user){ + $list[$k]['add_time'] = date('Y/m/d',$user['add_time']); + $list[$k]['price'] = StoreOrder::getUserPrice($user['uid']); + } + $count = User::where('spread_uid',$two_uid)->field('uid,nickname,avatar,add_time')->count(); + $data['count'] = $count; + $data['list'] = $list; + return JsonService::successful($data); + } + + /** + * 领取优惠券 + * @param string $couponId + * @return \think\response\Json + */ + public function user_get_coupon($couponId = '') + { + if(!$couponId || !is_numeric($couponId)) return JsonService::fail('参数错误!'); + if(StoreCouponIssue::issueUserCoupon($couponId,$this->userInfo['uid'])){ + return JsonService::successful('领取成功'); + }else{ + return JsonService::fail(StoreCouponIssue::getErrorInfo('领取失败!')); + } + } + + + /** + * 获取产品评论 + * @param string $productId + * @param int $first + * @param int $limit + * @param string $filter + * @return \think\response\Json + */ + public function product_reply_list($productId = '',$first = 0,$limit = 8, $filter = 'all') + { + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误!'); + $list = StoreProductReply::getProductReplyList($productId,$filter,$first,$limit); + if($list){ + foreach ($list as $k=>$v){ + foreach ($v['pics'] as $kk=>$vv){ + $list[$k]['pics'] = explode(',',$vv); + } + } + } + return JsonService::successful($list); + } + + /** + * 获取商品属性数据 + * @param string $productId + * @return \think\response\Json + */ + public function product_attr_detail($productId = '') + { + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误!'); + list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($productId); + return JsonService::successful(compact('productAttr','productValue')); + + } + + /** + * 获取用户所有地址 + * @return \think\response\Json + */ + public function user_address_list() + { + $list = UserAddress::getUserValidAddressList($this->userInfo['uid'],'id,real_name,phone,province,city,district,detail,is_default'); + return JsonService::successful($list); + } + + /** + * 用户通知 + * @param int $page + * @param int $limit + * @return \think\response\Json + */ + public function get_notice_list($page = 0, $limit = 8) + { + $list = UserNotice::getNoticeList($this->userInfo['uid'],$page,$limit); + return JsonService::successful($list); + } + + /** + * 修改用户通知为已查看 + * @param $nid + * @return \think\response\Json + */ + public function see_notice($nid){ + UserNotice::seeNotice($this->userInfo['uid'],$nid); + return JsonService::successful(); + } + + /** + * 客服提醒 + * @param Request $request + * @return \think\response\Json + */ + public function refresh_msn(Request $request) + { + $params = $request->post(); + $remind_where = "mer_id = ".$params["mer_id"]." AND uid = ".$params["uid"]." AND to_uid = ".$params["to_uid"]." AND type = 0 AND remind = 0"; + $remind_list = StoreServiceLog::where($remind_where)->order("add_time asc")->select(); + foreach ($remind_list as $key => $value) { + if(time() - $value["add_time"] > 3){ + StoreServiceLog::edit(array("remind"=>1),$value["id"]); + $now_user = StoreService::field("uid,nickname")->where(array("uid"=>$params["uid"]))->find(); + if(!$now_user)$now_user = User::field("uid,nickname")->where(array("uid"=>$params["uid"]))->find(); + if($params["to_uid"]) { + $head = '您有新的消息,请注意查收!'; + $head .= $params["mer_id"] > 0 ? "\n商户名称:".Merchant::where('id',$params["mer_id"])->value('mer_name') : ''; + WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($params["to_uid"]),WechatTemplateService::SERVICE_NOTICE,[ + 'first'=>$head, + 'keyword1'=>$now_user["nickname"], + 'keyword2'=>"客服提醒", + 'keyword3'=> preg_replace('//','[图片]',$value["msn"]), + 'keyword4'=>date('Y-m-d H:i:s',time()), + 'remark'=>'点击立即查看消息' + ],Url::build('service/service_ing',['to_uid'=>$now_user["uid"],'mer_id'=>$params["mer_id"]],true,true)); + } + } + } + $where = "mer_id = ".$params["mer_id"]." AND uid = ".$params["to_uid"]." AND to_uid = ".$params["uid"]." AND type = 0"; + $list = StoreServiceLog::where($where)->order("add_time asc")->select()->toArray(); + $ids = []; + foreach ($list as $key => $value) { + //设置发送人与接收人区别 + if($value["uid"] == $params["uid"]) + $list[$key]['my'] = "my"; + else + $list[$key]['my'] = "to"; + + array_push($ids,$value["id"]); + } + + //设置这些消息为已读 + StoreServiceLog::where(array("id"=>array("in",$ids)))->update(array("type"=>1,"remind"=>1)); + return JsonService::successful($list); + } + + public function add_msn(Request $request){ + $params = $request->post(); + if($params["type"] == "html") + $data["msn"] = htmlspecialchars_decode($params["msn"]); + else + $data["msn"] = $params["msn"]; + $data["uid"] = $params["uid"]; + $data["to_uid"] = $params["to_uid"]; + $data["mer_id"] = $params["mer_id"] > 0 ? $params["mer_id"] : 0; + $data["add_time"] = time(); + StoreServiceLog::set($data); + return JsonService::successful(); + } + + public function get_msn(Request $request){ + $params = $request->post(); + $size = 10; + $page = $params["page"]>=0 ? $params["page"] : 1; + $where = "(mer_id = ".$params["mer_id"]." AND uid = ".$params["uid"]." AND to_uid = ".$params["to_uid"].") OR (mer_id = ".$params["mer_id"]." AND uid = ".$params["to_uid"]." AND to_uid = ".$params["uid"].")"; + $list = StoreServiceLog::where($where)->limit(($page-1)*$size,$size)->order("add_time desc")->select()->toArray(); + foreach ($list as $key => $value) { + //设置发送人与接收人区别 + if($value["uid"] == $params["uid"]) + $list[$key]['my'] = "my"; + else + $list[$key]['my'] = "to"; + + //设置这些消息为已读 + if($value["uid"] == $params["to_uid"] && $value["to_uid"] == $params["uid"])StoreServiceLog::edit(array("type"=>1,"remind"=>1),$value["id"]); + } + $list=array_reverse($list); + return JsonService::successful($list); + } + + public function refresh_msn_new(Request $request){ + $params = $request->post(); + $now_user = User::getUserInfo($this->userInfo['uid']); + if($params["last_time"] > 0) + $where = "(uid = ".$now_user["uid"]." OR to_uid = ".$now_user["uid"].") AND add_time>".$params["last_time"]; + else + $where = "uid = ".$now_user["uid"]." OR to_uid = ".$now_user["uid"]; + + + $msn_list = StoreServiceLog::where($where)->order("add_time desc")->select()->toArray(); + $info_array = $list = []; + foreach ($msn_list as $key => $value){ + $to_uid = $value["uid"] == $now_user["uid"] ? $value["to_uid"] : $value["uid"]; + if(!in_array(["to_uid"=>$to_uid,"mer_id"=>$value["mer_id"]],$info_array)){ + $info_array[count($info_array)] = ["to_uid"=>$to_uid,"mer_id"=>$value["mer_id"]]; + + $to_user = StoreService::field("uid,nickname,avatar")->where(array("uid"=>$to_uid))->find(); + if(!$to_user)$to_user = User::field("uid,nickname,avatar")->where(array("uid"=>$to_uid))->find(); + $to_user["mer_id"] = $value["mer_id"]; + $to_user["mer_name"] = $value["mer_id"] > 0 ? "[".Merchant::where('id',$value["mer_id"])->value('mer_name')."]" : ''; + $value["to_info"] = $to_user; + $value["count"] = StoreServiceLog::where(array("mer_id"=>$value["mer_id"],"uid"=>$to_uid,"to_uid"=>$now_user["uid"],"type"=>0))->count(); + $list[count($list)] = $value; + } + } + return JsonService::successful($list); + } + + public function get_user_brokerage_list($uid, $first = 0,$limit = 8) + { + if(!$uid) + return $this->failed('用户不存在'); + $list = UserBill::field('A.mark,A.add_time,A.number,A.pm')->alias('A')->limit($first,$limit) + ->where('A.category','now_money')->where('A.type','brokerage') + ->where('A.uid',$this->userInfo['uid']) + ->join('__STORE_ORDER__ B','A.link_id = B.id AND B.uid = '.$uid)->select()->toArray(); + return JsonService::successful($list); + } + /* + * 申请提现 + */ +// public function user_extract() +// { +// if(UserExtract::userExtract($this->userInfo,UtilService::postMore([ +// ['type','','','extract_type'],'real_name','alipay_code','bank_code','bank_address',['price','','','extract_price'] +// ]))) +// return JsonService::successful('申请提现成功!'); +// else +// return JsonService::fail(Extract::getErrorInfo()); +// } + public function user_extract() + { $request = Request::instance(); + $list=$request->param(); + $data=$list['lists']; +// dump($data); +// dump($this->userInfo); + if(UserExtract::userExtract($this->userInfo,$data)) + return JsonService::successful('申请提现成功!'); + else + return JsonService::fail(UserExtract::getErrorInfo()); + } +/* + * 提现列表 + */ + public function extract($first = 0,$limit = 8) + { + $list=UserExtract::where('uid',$this->userInfo['uid'])->order('add_time desc')->limit($first,$limit)->select()->toArray(); + foreach($list as &$v){ + $v['add_time']=date('Y/m/d',$v['add_time']); + } + + return JsonService::successful($list); + + } + + /** + * 用户下级的订单 + * @param int $first + * @param int $limit + */ + public function subordinateOrderlist($first = 0, $limit = 8) + { $request = Request::instance(); + $lists=$request->param(); + $xuid=$lists['uid'];$status=$lists['status']; + if($status==0){ + $type=''; + }elseif($status==1){ + $type=4; + }elseif($status==2){ + $type=3; + }else{ + return false; + } + if($xuid==0){ + $arr=User::where('spread_uid',$this->userInfo['uid'])->column('uid'); + foreach($arr as $v){ + + $list = StoreOrder::getUserOrderList($v,$type,$first,$limit); + } + }else{ + $list = StoreOrder::getUserOrderList($xuid,$type,$first,$limit); + } + foreach ($list as $k=>$order){ + $list[$k] = StoreOrder::tidyOrder($order,true); + if($list[$k]['_status']['_type'] == 3){ + foreach ($order['cartInfo']?:[] as $key=>$product){ + $list[$k]['cartInfo'][$key]['is_reply'] = StoreProductReply::isReply($product['unique'],'product'); + } + } + } + return JsonService::successful($list); + } + /** + * 用户下级的订单 + * @param int $first + * @param int $limit + */ + public function subordinateOrderlistmoney() + { + $arr=User::where('spread_uid',$this->userInfo['uid'])->column('uid'); + foreach($arr as $v){ + $list = StoreOrder::getUserOrderList($v,$type=''); + } + + foreach ($list as $k=>$v){ + $arr[]=$v['pay_price']; + } + $cont=count($list); + $sum=array_sum($arr); + return JsonService::successful(['cont'=>$cont,'sum'=>$sum]); + } + /* + * 昨日推广佣金 + */ + public function yesterdayCommission(){ + $money=UserBill::where('uid',$this->userInfo['uid'])->where('category','now_money')->where('type','brokerage')->where('pm',1)->where('status',1)->whereTime('add_time', 'yesterday')->column('number'); + $sum= array_sum($money); + return JsonService::successful($sum); + } + /* + * 累计已提金额 + */ + public function extractsum(){ + $money=UserExtract::where('uid',$this->userInfo['uid'])->where('status',1)->column('extract_price'); + $sum= array_sum($money); + return JsonService::successful($sum); + } + /** + * 获取一条优惠券 + * @param int $couponId + * @return \think\response\Json + */ + public function get_coupon_rope($couponId = 0){ + if(!$couponId) return JsonService::fail('参数错误'); + $couponUser = StoreCouponUser::validAddressWhere()->where('id',$couponId)->where('uid',$this->userInfo['uid'])->find(); + return JsonService::successful($couponUser); + } + /** + * 获取 可以领取的优惠券 + * @param int $limit + * @return \think\response\Json + */ + public function get_issue_coupon_list($limit = 2) + { + $list = StoreCouponIssue::validWhere('A')->join('__STORE_COUPON__ B','A.cid = B.id') + ->field('A.*,B.coupon_price,B.use_min_price')->order('B.sort DESC,A.id DESC')->limit($limit)->select()->toArray()?:[]; + foreach ($list as $k=>$v){ + $list[$k]['is_use'] = StoreCouponIssueUser::be(['uid'=>$this->userInfo['uid'],'issue_coupon_id'=>$v['id']]); + } + return JsonService::successful($list); + } + + public function clear_cache($uni = '') + { + if($uni)CacheService::clear(); + } + + /** + * 获取今天正在拼团的人的头像和名称 + * @return \think\response\Json + */ + public function get_pink_second_one(){ + $addTime = mt_rand(time()-30000,time()); + $storePink = StorePink::where('p.add_time','GT',$addTime)->alias('p')->where('p.status',1)->join('User u','u.uid=p.uid')->field('u.nickname,u.avatar as src')->find(); + return JsonService::successful($storePink); + } + + /** + * 再来一单 + * @param string $uni + */ + public function order_details($uni = ''){ + + if(!$uni) return JsonService::fail('参数错误!'); + $order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni); + if(!$order) return JsonService::fail('订单不存在!'); + $order = StoreOrder::tidyOrder($order,true); + $res = array(); + foreach ($order['cartInfo'] as $v) { + if($v['combination_id']) return JsonService::fail('拼团产品不能再来一单,请在拼团产品内自行下单!'); + else $res[] = StoreCart::setCart($this->userInfo['uid'], $v['product_id'], $v['cart_num'], isset($v['productInfo']['attrInfo']['unique']) ? $v['productInfo']['attrInfo']['unique'] : '', 'product', 0, 0); + } + $cateId = []; + foreach ($res as $v){ + if(!$v) return JsonService::fail('再来一单失败,请重新下单!'); + $cateId[] = $v['id']; + } + return JsonService::successful('ok',implode(',',$cateId)); + + } + /** + * 获取分销二维码 + * @return \think\response\Json + */ + public function get_code(){ + header('content-type:image/jpg'); + if(!$this->userInfo['uid']) return JsonService::fail('授权失败,请重新授权'); + $path = 'public/uploads/routine/'.$this->userInfo['uid'].'.jpg'; + if(file_exists($path)) return JsonService::successful($path); + else file_put_contents($path,RoutineCode::getCode($this->userInfo['uid'])); + return JsonService::successful($path); + } + + /** + * 绑定推荐人 + * @param Request $request + * @return \think\response\Json + */ + public function spread_uid(Request $request){ + $data = UtilService::postMore(['spread_uid',0],$request); + if($data['spread_uid']){ + if(!$this->userInfo['spread_uid']){ + $res = User::edit(['spread_uid'=>$data['spread_uid']],$this->userInfo['uid']); + if($res) return JsonService::successful('绑定成功'); + else return JsonService::successful('绑定失败'); + }else return JsonService::fail('已存在被推荐人'); + }else return JsonService::fail('没有推荐人'); + } + + /** + * 获取砍价列表 + * @return \think\response\Json + */ + public function get_bargain_list($limit = 10){ + $bargain = StoreBargain::getList(); + $bargain = StoreBargainUser::getUserList($bargain,$limit); + $lovely = GroupDataService::getData('routine_lovely')?:[];//banner图 + $banner = GroupDataService::getData('bargain_banner')?:[];//banner图 + $banner = $banner[0]; + $bargainUser = StoreBargainUser::getBargainUserStatusSuccess(); + $data['bargain'] = $bargain; + $data['lovely'] = $lovely; + $data['banner'] = $banner; + $data['bargainUser'] = $bargainUser; + return JsonService::successful($data); + } + + /** + * 砍价详情 + * @param int $bargainId + * @return \think\response\Json + */ + public function get_bargain($bargainId = 0){ + if(!$bargainId) return JsonService::fail('参数错误'); + $bargain = StoreBargain::getBargainTerm($bargainId); + $bargain['time'] = time(); + return JsonService::successful($bargain); + } + + /** + * 获取人数 + * @param int $count + * @return \think\response\Json + */ + public function get_bargain_count($count = 0){ + $data['lookCount'] = StoreBargain::getBargainLook()['look'];//观看人数 + $data['shareCount'] = StoreBargain::getBargainShare()['share'];//观看人数 + $data['userCount'] = StoreBargainUser::count();//参与人数 + return JsonService::successful($data); + } + + /** + * 添加砍价分享次数 + * @param int $bargainId + */ + public function add_share_bargain($bargainId = 0){ + if(!$bargainId) return JsonService::successful(); + StoreBargain::addBargainShare($bargainId); + return JsonService::successful(); + } + + /** + * 添加砍价浏览次数 + * @param int $bargainId + */ + public function add_look_bargain($bargainId = 0){ + if(!$bargainId) return JsonService::successful(); + StoreBargain::addBargainLook($bargainId); + return JsonService::successful(); + } + + /** + * 获取砍价帮 + * @param int $bargainId + * @param int $uid + * @return \think\response\Json + */ + public function get_bargain_user($bargainId = 0,$bargainUid = 0,$limit = 15){ + if(!$bargainId || !$bargainUid) return JsonService::fail('参数错误'); + $bargainUserTableId = StoreBargainUser::setUserBargain($bargainId,$bargainUid); + $storeBargainUserHelp = StoreBargainUserHelp::getList($bargainUserTableId,$limit); + return JsonService::successful($storeBargainUserHelp); + } + /** + * 我的砍价 + * @param int $bargainId + * @return \think\response\Json + */ + public function mycut($bargainId = 0){ + if(!$bargainId ) return JsonService::fail('参数错误'); + $data= StoreBargainUser::where('bargain_id',$bargainId)->where('uid',$this->userInfo['uid'])->where('status',1)->find(); + return JsonService::successful($data); + } + /** + * 参与砍价产品 + * @param int $bargainId + * @return \think\response\Json + */ + public function set_bargain($bargainId = 0){ + if(!$bargainId) return JsonService::fail('参数错误'); + $res = StoreBargainUser::setBargain($bargainId,$this->userInfo['uid']); + if($res) { + $data['id'] = $res->id; + return JsonService::successful('参与成功',$data); + } + else return JsonService::fail('参与失败'); + } + + /** + * 判断当前登录人是否参与砍价 + * @param int $bargainId + * @return \think\response\Json + */ + public function is_bargain_user($bargainId = 0){ + if(!$bargainId) return JsonService::fail('参数错误'); + $data=StoreBargainUser::isBargainUser($bargainId,$this->userInfo['uid']); + if($data) return JsonService::successful($data); + else return JsonService::fail('没有参与砍价'); + } + /* + * 已砍掉的金额 + */ + public function speed_of_progress($bargainId = 0){ + if(!$bargainId) return JsonService::fail('参数错误'); + $price= StoreBargainUser::where('bargain_id',$bargainId)->where('status',1)->where('uid',$this->userInfo['uid'])->value('price'); + return JsonService::successful($price); + } + /** + * 帮好友砍价 + * @param int $bargainId + * @param int $bargainUserId + * @return \think\response\Json + */ + public function set_bargain_help($bargainId = 0,$bargainUserId = 0){ + if(!$bargainId || !$bargainUserId) return JsonService::fail('参数错误'); + $res = StoreBargainUserHelp::setBargainUserHelp($bargainId,$bargainUserId,$this->userInfo['uid']); + if($res) { + if(!StoreBargainUserHelp::getSurplusPrice($bargainId,$bargainUserId)){ + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $bargain = StoreBargain::where('id',$bargainId)->find()->toArray(); + $bargainUser = StoreBargainUser::where('id',$bargainUserTableId)->find()->toArray(); + RoutineTemplate::sendBargainSuccess($bargain,$bargainUser,$bargainUserId);//发送模板消息 + } + return JsonService::successful('砍价成功',$res); + } + else return JsonService::fail('砍价失败'); + } + + + /** + * 获取砍价帮总人数、剩余金额、进度条 + * @param int $bargainId + * @param int $bargainUserId + * @return \think\response\Json + */ + public function get_bargain_help_count($bargainId = 0,$bargainUserId = 0){ + if(!$bargainId || !$bargainUserId) return JsonService::fail('参数错误'); + $count = StoreBargainUserHelp::getBargainUserHelpPeopleCount($bargainId,$bargainUserId); + $price = StoreBargainUserHelp::getSurplusPrice($bargainId,$bargainUserId); + $pricePercent = StoreBargainUserHelp::getSurplusPricePercent($bargainId,$bargainUserId); + $data['count'] = $count; + $data['price'] = $price; + $data['pricePercent'] = $pricePercent; + return JsonService::successful($data); + } + + /** + * 判断当前砍价是否开启 + * @param int $bargainId + * @return \think\response\Json + */ + public function is_bargain_status($bargainId = 0){ + if(!$bargainId) return JsonService::fail('参数错误'); + if(!StoreBargain::setBargainStatus($bargainId)) return JsonService::successful(); + else return JsonService::fail(); + } + + + /** + * 判断用户是否可以砍价 + * @param int $bargainId + * @param int $bargainUserId + */ + public function is_bargain_user_help($bargainId = 0,$bargainUserId = 0){ + if(!$bargainId || !$bargainUserId) return JsonService::fail('参数错误'); + if(StoreBargainUserHelp::isBargainUserHelpCount($bargainId,$bargainUserId,$this->userInfo['uid'])) return JsonService::successful('请稍后在帮助好友砍价'); + else return JsonService::fail('您不能再帮忙砍价了'); + } + + /** + * 修改砍价状态为失败 + * @param int $bargainUserTableId + */ + public function set_user_bargain_status($bargainUserTableId = 0){ + if(!$bargainUserTableId) return JsonService::fail('参数错误'); + if(StoreBargainUser::editBargainUserStatus($bargainUserTableId)) return JsonService::successful('ok'); + else return JsonService::fail('no'); + } + + + + /** + * 获取用户信息 + * @param int $uid + * @return \think\response\Json + */ + public function get_user_info_uid($userId = 0){ + if(!$userId) return JsonService::fail('参数错误'); + $res = User::getUserInfo($userId); + if($res) return JsonService::successful($res); + else return JsonService::fail(User::getErrorInfo()); + } + + /** + * 获取砍价产品 个人中心 我的砍价 + */ + public function get_user_bargain_all(){ + $list = StoreBargainUser::getBargainUserAll($this->userInfo['uid']); + if($list){ + foreach ($list as $k=>$v){ + $list[$k]['helpCount'] = StoreBargainUserHelp::getBargainUserHelpPeopleCount($v['bargain_id'],$this->userInfo['uid']); + } + return JsonService::successful($list); + }else return JsonService::fail('暂无参与砍价'); + } + /* + * 查物流 + */ + public function express($uid,$uni = '') + { + if(!$uni || !($order = StoreOrder::getUserOrderDetail($uid,$uni))) return JsonService::fail('查询订单不存在!'); + if($order['delivery_type'] != 'express' || !$order['delivery_id']) return JsonService::fail('该订单不存在快递单号!'); + $cacheName = $uni.$order['delivery_id']; + CacheService::rm($cacheName); + $result = CacheService::get($cacheName,null); + if($result === NULL){ + $result = Express::query($order['delivery_id']); + if(is_array($result) && + isset($result['result']) && + isset($result['result']['deliverystatus']) && + $result['result']['deliverystatus'] >= 3) + $cacheTime = 0; + else + $cacheTime = 1800; + CacheService::set($cacheName,$result,$cacheTime); + } + + if($result) return JsonService::successful([ 'order'=>$order, 'express'=>$result]); + } + + /** + * 收集发送模板信息的formID + * @param string $formId + */ + public function get_form_id($formId = ''){ + if((int)$formId == '' || $formId == 'the formId is a mock one') return JsonService::fail('no'); + $data['form_id'] = $formId; + $data['uid'] = $this->userInfo['uid']; + $data['status'] = 1; + $data['stop_time'] = bcadd(time(),bcmul(6,86400,0),0); + RoutineFormId::set($data); + return JsonService::successful(); + } + + /** + * 获取拼团列表 + * @param int $offset + * @param int $limit + */ + public function get_combination_list($offset=0,$limit=20){ + $store_combination = StoreCombination::getAll($offset,$limit); + return JsonService::successful($store_combination); + } + + public function get_combination_list_banner(){ + $lovely = GroupDataService::getData('routine_lovely')?:[];//banner图 + return JsonService::successful($lovely[2]); + } + + /** + * 获取拼团产品详情 + * @param int $id + */ + public function combination_detail($id = 0){ + if(!$id) return JsonService::fail('拼团不存在或已下架'); + $combinationOne = StoreCombination::getCombinationOne($id); + if(!$combinationOne) return JsonService::fail('拼团不存在或已下架'); + $combinationOne['images'] = json_decode($combinationOne['images'],true); +// $combinationOne['userLike'] = StoreProductRelation::isProductRelation($combinationOne['product_id'],$this->userInfo['uid'],'like'); +// $combinationOne['like_num'] = StoreProductRelation::productRelationNum($combinationOne['product_id'],'like'); + $combinationOne['userCollect'] = StoreProductRelation::isProductRelation($id,$this->userInfo['uid'],'collect','pink_product'); + $pink = StorePink::getPinkAll($id);//拼团列表 + $pindAll = array(); + foreach ($pink as $k=>$v){ + $pink[$k]['count'] = StorePink::getPinkPeople($v['id'],$v['people']); + $pink[$k]['h'] = date('H',$v['stop_time']); + $pink[$k]['i'] = date('i',$v['stop_time']); + $pink[$k]['s'] = date('s',$v['stop_time']); + $pindAll[] = $v['id'];//开团团长ID + } + $user = WechatUser::get($this->userInfo['uid'])->toArray();//用户信息 + $data['pink'] = $pink; + $data['user'] = $user; + $data['pindAll'] = $pindAll; + $data['storeInfo'] = $combinationOne; + $data['reply'] = StoreProductReply::getRecProductReply($combinationOne['product_id']); + $data['replyCount'] = StoreProductReply::productValidWhere()->where('product_id',$combinationOne['product_id'])->count(); +// $data['mer_id'] = StoreProduct::where('id',$combinationOne['product_id'])->value('mer_id'); + return JsonService::successful($data); + } + + /** + * 开团页面 + * @param int $id + * @return mixed + */ + public function get_pink($id = 0){ + if(!$id) return JsonService::fail('参数错误'); + $pink = StorePink::getPinkUserOne($id); + if(isset($pink['is_refund']) && $pink['is_refund']) { + if($pink['is_refund'] != $pink['id']){ + $id = $pink['is_refund']; + return $this->get_pink($id); + }else{ + return JsonService::fail('订单已退款'); + } + } + if(!$pink) return JsonService::fail('参数错误'); + $pinkAll = array();//参团人 不包括团长 + $pinkT = array();//团长 + if($pink['k_id']){ + $pinkAll = StorePink::getPinkMember($pink['k_id']); + $pinkT = StorePink::getPinkUserOne($pink['k_id']); + }else{ + $pinkAll = StorePink::getPinkMember($pink['id']); + $pinkT = $pink; + } + $store_combination = StoreCombination::getCombinationOne($pink['cid']);//拼团产品 + $count = count($pinkAll)+1; + $count = (int)$pinkT['people']-$count;//剩余多少人 + $is_ok = 0;//判断拼团是否完成 + $idAll = array(); + $uidAll = array(); + if(!empty($pinkAll)){ + foreach ($pinkAll as $k=>$v){ + $idAll[$k] = $v['id']; + $uidAll[$k] = $v['uid']; + } + } + + $userBool = 0;//判断当前用户是否在团内 0未在 1在 + $pinkBool = 0;//判断当前用户是否在团内 0未在 1在 + $idAll[] = $pinkT['id']; + $uidAll[] = $pinkT['uid']; + if($pinkT['status'] == 2){ + $pinkBool = 1; + $is_ok = 1; + }else{ + if(!$count){//组团完成 + $is_ok = 1; + $idAll = implode(',',$idAll); + $orderPinkStatus = StorePink::setPinkStatus($idAll); + if($orderPinkStatus){ + if(in_array($this->userInfo['uid'],$uidAll)){ + StorePink::setPinkStopTime($idAll); + if(StorePink::isTpl($uidAll,$pinkT['id'])) StorePink::orderPinkAfter($uidAll,$pinkT['id']); + $pinkBool = 1; + }else $pinkBool = 3; + }else $pinkBool = 6; + } + else{ + if($pinkT['stop_time'] < time()){//拼团时间超时 退款 + if($pinkAll){ + foreach ($pinkAll as $v){ + if($v['uid'] == $this->userInfo['uid']){ + $res = StoreOrder::orderApplyRefund(StoreOrder::where('id',$v['order_id_key'])->value('order_id'),$this->userInfo['uid'],'拼团时间超时'); + if($res){ + if(StorePink::isTpl($v['uid'],$pinkT['id'])) StorePink::orderPinkAfterNo($v['uid'],$v['k_id']); + $pinkBool = 2; + }else return JsonService::fail(StoreOrder::getErrorInfo()); + } + } + } + if($pinkT['uid'] == $this->userInfo['uid']){ + $res = StoreOrder::orderApplyRefund(StoreOrder::where('id',$pinkT['order_id_key'])->value('order_id'),$this->userInfo['uid'],'拼团时间超时'); + if($res){ + if(StorePink::isTpl($pinkT['uid'],$pinkT['id'])) StorePink::orderPinkAfterNo($pinkT['uid'],$pinkT['id']); + $pinkBool = 2; + }else return JsonService::fail(StoreOrder::getErrorInfo()); + } + if(!$pinkBool) $pinkBool = 3; + } + } + } + $store_combination_host = StoreCombination::getCombinationHost();//获取推荐的拼团产品 + if(!empty($pinkAll)){ + foreach ($pinkAll as $v){ + if($v['uid'] == $this->userInfo['uid']) $userBool = 1; + } + } + if($pinkT['uid'] == $this->userInfo['uid']) $userBool = 1; + $combinationOne = StoreCombination::getCombinationOne($pink['cid']); + if(!$combinationOne) return JsonService::fail('拼团不存在或已下架'); + $store_combination['userInfo'] = $this->userInfo; + $data['pinkBool'] = $pinkBool; + $data['is_ok'] = $is_ok; + $data['userBool'] = $userBool; + $data['store_combination'] = $store_combination; + $data['pinkT'] = $pinkT; + $data['pinkAll'] = $pinkAll; + $data['count'] = $count; + $data['store_combination_host'] = $store_combination_host; + $data['current_pink_order'] = StorePink::getCurrentPink($id); + return JsonService::successful($data); + } + + /** + * 购物车库存修改 + * @param int $cartId + * @param int $cartNum + */ + public function set_buy_cart_num($cartId = 0,$cartNum = 0){ + if(!$cartId) return JsonService::fail('参数错误'); + $res = StoreCart::edit(['cart_num'=>$cartNum],$cartId); + if($res) return JsonService::successful(); + else return JsonService::fail('修改失败'); + } + + /** + * 获取后台联系方式 + */ + public function get_site_phone(){ + $data = SystemConfig::getValue('site_service_phone'); + return JsonService::successful($data); + } + + /** + * 获取产品链接的二维码 + * @param string $path + * @param int $width + */ + public function get_pages($path = '',$productId = 0,$width = 430){ + if($path == '' || !$productId) return JsonService::fail('参数错误'); header('content-type:image/jpg'); + if(!$this->userInfo['uid']) return JsonService::fail('授权失败,请重新授权'); + $path = 'public/uploads/routinepage/'.$productId.'.jpg'; + if(file_exists($path)) return JsonService::successful($path); + else file_put_contents($path,RoutineCode::getCode($this->userInfo['uid'])); + return JsonService::successful($path); + } + + /** + * 文章列表 + * @param int $cid + * @param int $first + * @param int $limit + */ + public function get_cid_article($cid = 0,$first = 0,$limit = 8){ + $list = ArticleModel::cidByArticleList($cid,$first,$limit,'id,title,image_input,visit,add_time,synopsis,url')?:[]; + foreach ($list as &$article){ + $article['add_time'] = date('Y-m-d H:i',$article['add_time']); + } + $data['list'] = $list; + return JsonService::successful($list); + } + + /** + * 获取热门文章 + */ + public function get_article_hot(){ + $hot = ArticleModel::getArticleListHot('id,title'); + return JsonService::successful($hot); + } + + /** + * 获取热门banner文章 + */ + public function get_article_banner(){ + $banner = ArticleModel::getArticleListBanner('id,title,image_input'); + return JsonService::successful($banner); + } + + /** + * 获取文章详情 + * @param int $id + */ + public function visit($id = 0) + { + $content = ArticleModel::getArticleOne($id); + if(!$content || !$content["status"]) return JsonService::fail('此文章已经不存在!'); + $content["visit"] = $content["visit"] + 1; + $content['add_time'] = date('Y-m-d H:i:s',$content['add_time']); + ArticleModel::edit(['visit'=>$content["visit"]],$id);//增加浏览次数 + return JsonService::successful($content); + } + + /** + * 刷新数据缓存 + */ + public function refresh_cache(){ + `php think optimize:schema`; + `php think optimize:autoload`; + `php think optimize:route`; + `php think optimize:config`; + } + + + +} \ No newline at end of file diff --git a/application/routine/controller/AuthController.php b/application/routine/controller/AuthController.php new file mode 100644 index 00000000..c6e22d67 --- /dev/null +++ b/application/routine/controller/AuthController.php @@ -0,0 +1,28 @@ + + * @day: 2017/12/11 + */ + +namespace app\routine\controller; + +use app\routine\model\user\User; +use service\JsonService; +use think\Controller; +use think\Request; +use think\Session; + +class AuthController extends Controller +{ + public $userInfo = []; + protected function _initialize() + { + parent::_initialize(); + $uid = Request::instance()->get('uid',0); + $userInfo = User::get($uid); + if($userInfo) $userInfo->toArray(); + else return JsonService::fail('没有获取用户UID'); + $this->userInfo = $userInfo;//根据uid获取用户信息 + } +} \ No newline at end of file diff --git a/application/routine/controller/Login.php b/application/routine/controller/Login.php new file mode 100644 index 00000000..7d405fbb --- /dev/null +++ b/application/routine/controller/Login.php @@ -0,0 +1,49 @@ +setCode($data['code']); + if(!isset($res['openid'])) return JsonService::fail('openid获取失败'); + if(isset($res['unionid'])) $data['unionid'] = $res['unionid']; + else $data['unionid'] = ''; + $data['openid'] = $res['openid']; + $data['session_key'] = $res['session_key']; + $data['uid'] = RoutineUser::routineOauth($data); + return JsonService::successful($data); + } + + /** + * 根据前台传code 获取 openid 和 session_key //会话密匙 + * @param string $code + * @return array|mixed + */ + public function setCode($code = ''){ + if($code == '') return []; + $routineAppId = 'wx7bc36cccc15e4be2';//小程序appID + $routineAppSecret = 'a13757487f35b0ad88c03455b1903c4d';//小程序AppSecret + $url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$routineAppId.'&secret='.$routineAppSecret.'&js_code='.$code.'&grant_type=authorization_code'; + return json_decode(RoutineBehavior::curlGet($url),true); + } +} \ No newline at end of file diff --git a/application/routine/model/article/Article.php b/application/routine/model/article/Article.php new file mode 100644 index 00000000..ad08eb51 --- /dev/null +++ b/application/routine/model/article/Article.php @@ -0,0 +1 @@ +where('hide',0)->where('id',$id)->order('id desc')->find(); if($list){ $list = $list->toArray(); $list["content"] = Db::name('articleContent')->where('nid',$id)->value('content'); return $list; } else return []; } /** * 获取某个分类底下的文章 * @param $cid * @param $first * @param $limit * @param string $field * @return mixed */ public static function cidByArticleList($cid, $first, $limit, $field = 'id,title,image_input,visit,add_time,synopsis,url') { $model = new self(); if ($cid) $model->where("CONCAT(',',cid,',') LIKE '%,$cid,%'", 'exp'); $model = $model->field($field); $model = $model->where('status', 1); $model = $model->where('hide', 0); $model = $model->order('sort DESC,add_time DESC'); if($limit) $model = $model->limit($first, $limit); return $model->select(); } /** * 获取热门文章 * @param string $field * @return mixed */ public static function getArticleListHot($field = 'id,title,image_input,visit,add_time,synopsis,url'){ $model = new self(); $model = $model->field($field); $model = $model->where('status', 1); $model = $model->where('hide', 0); $model = $model->where('is_hot', 1); $model = $model->order('sort DESC,add_time DESC'); return $model->select(); } /** * 获取轮播文章 * @param string $field * @return mixed */ public static function getArticleListBanner($field = 'id,title,image_input,visit,add_time,synopsis,url'){ $model = new self(); $model = $model->field($field); $model = $model->where('status', 1); $model = $model->where('hide', 0); $model = $model->where('is_banner', 1); $model = $model->order('sort DESC,add_time DESC'); return $model->select(); } } \ No newline at end of file diff --git a/application/routine/model/article/ArticleCategory.php b/application/routine/model/article/ArticleCategory.php new file mode 100644 index 00000000..3d74c93a --- /dev/null +++ b/application/routine/model/article/ArticleCategory.php @@ -0,0 +1,16 @@ + * @day: 2017/11/02 */ +namespace app\routine\model\article; + +use traits\ModelTrait; +use basic\ModelBasic; + + +/** + * Class ArticleCategory + * @package app\routine\model\article + */ +class ArticleCategory extends ModelBasic +{ + use ModelTrait; + +} \ No newline at end of file diff --git a/application/routine/model/routine/RoutineCode.php b/application/routine/model/routine/RoutineCode.php new file mode 100644 index 00000000..672c7753 --- /dev/null +++ b/application/routine/model/routine/RoutineCode.php @@ -0,0 +1,44 @@ +where('stop_time','LT',time())->delete(); + } + + /** + * 获取一个可以使用的formId + * @return bool|mixed + */ + public static function getFormIdOne($uid = 0){ + $formId = self::where('status',1)->where('stop_time','GT',time())->where('uid',$uid)->order('id asc')->find(); + if($formId) return $formId['form_id']; + else return false; + } + + /** + * 修改一个FormID为已使用 + * @param string $formId + * @return $this|bool + */ + public static function delFormIdOne($formId = ''){ + if($formId == '') return true; + return self::where('form_id',$formId)->update(['status'=>2]); + } +} \ No newline at end of file diff --git a/application/routine/model/routine/RoutineServer.php b/application/routine/model/routine/RoutineServer.php new file mode 100644 index 00000000..e686b228 --- /dev/null +++ b/application/routine/model/routine/RoutineServer.php @@ -0,0 +1,84 @@ +where('id',1)->find(); + if($accessToken['stop_time'] > time()) return $accessToken['access_token']; + else{ + $accessToken = self::getAccessToken(); + if(isset($accessToken['access_token'])){ + $data['access_token'] = $accessToken['access_token']; + $data['stop_time'] = bcadd($accessToken['expires_in'],time(),0); + db('routine_access_token')->where('id',1)->update($data); + } + return $accessToken['access_token']; + } + } +} \ No newline at end of file diff --git a/application/routine/model/routine/RoutineTemplate.php b/application/routine/model/routine/RoutineTemplate.php new file mode 100644 index 00000000..c74b0102 --- /dev/null +++ b/application/routine/model/routine/RoutineTemplate.php @@ -0,0 +1,123 @@ +find(); + if($formId == '') $formId = RoutineFormId::getFormIdOne($order['uid']); + $data['keyword1']['value'] = $orderId; + $data['keyword2']['value'] = date('Y-m-d H:i:s',time()); + $data['keyword3']['value'] = '已支付'; + $data['keyword4']['value'] = $order['pay_price']; + if($order['pay_type'] == 'yue') $data['keyword5']['value'] = '余额支付'; + else if($order['pay_type'] == 'weixin') $data['keyword5']['value'] = '微信支付'; +// else if($order['pay_type'] == 'offline') $data['keyword5']['value'] = '线下支付'; + RoutineFormId::delFormIdOne($formId); + RoutineTemplateService::sendTemplate(WechatUser::getOpenId($order['uid']),RoutineTemplateService::setTemplateId(RoutineTemplateService::ORDER_PAY_SUCCESS),'',$data,$formId); + } + /** + * 订单发货提醒 + * @param int $oid + * @param array $postageData + * @return bool + */ + public static function sendOrderGoods($oid = 0,$postageData=array()){ + if(!$oid || !$postageData) return true; + $order = StoreOrder::where('id',$oid)->find(); + if(!RoutineUser::isRoutineUser($order['uid'])) return true; + if($postageData['delivery_type'] == 'send'){//送货 + $data['keyword1']['value'] = $order['order_id']; + $data['keyword2']['value'] = $order['delivery_name']; + $data['keyword3']['value'] = $order['delivery_id']; + $data['keyword4']['value'] = date('Y-m-d H:i:s',time()); + $data['keyword5']['value'] = '您的商品已经发货请注意查收'; + $formId = RoutineFormId::getFormIdOne($order['uid']); + if($formId){ + RoutineFormId::delFormIdOne($formId); + RoutineTemplateService::sendTemplate(WechatUser::getOpenId($order['uid']),RoutineTemplateService::setTemplateId(RoutineTemplateService::ORDER_DELIVER_SUCCESS),'',$data,$formId); + } + }else if($postageData['delivery_type'] == 'express'){//发货 + $data['keyword1']['value'] = $order['order_id']; + $data['keyword2']['value'] = $order['delivery_name']; + $data['keyword3']['value'] = $order['delivery_id']; + $data['keyword4']['value'] = date('Y-m-d H:i:s',time()); + $data['keyword5']['value'] = '您的商品已经发货请注意查收'; + $formId = RoutineFormId::getFormIdOne($order['uid']); + if($formId){ + RoutineFormId::delFormIdOne($formId); + RoutineTemplateService::sendTemplate(WechatUser::getOpenId($order['uid']),RoutineTemplateService::setTemplateId(RoutineTemplateService::ORDER_POSTAGE_SUCCESS),'',$data,$formId); + } + } + } +} \ No newline at end of file diff --git a/application/routine/model/store/StoreBargain.php b/application/routine/model/store/StoreBargain.php new file mode 100644 index 00000000..171befab --- /dev/null +++ b/application/routine/model/store/StoreBargain.php @@ -0,0 +1,159 @@ + + * @day: 2017/12/18 + */ + +namespace app\routine\model\store; + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreBargain extends ModelBasic +{ + use ModelTrait; + + /** + * 正在开启的砍价活动 + * @return $this + */ + public static function validWhere($status = 1){ + return self::where('is_del',0)->where('status',$status)->where('start_time','LT',time())->where('stop_time','GT',time()); + } + + /** + * 判断砍价产品是否开启 + * @param int $bargainId + * @return int|string + */ + public static function validBargain($bargainId = 0){ + $model = self::validWhere(); + return $model->where('id',$bargainId)->count(); + } + /** + * 获取正在进行中的砍价产品 + * @param string $field + */ + public static function getList($field = 'id,product_id,title,price,min_price,image'){ + $model = self::validWhere(); + $list = $model->field($field)->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取一条正在进行中的砍价产品 + * @param int $bargainId + * @param string $field + * @return array + */ + public static function getBargainTerm($bargainId = 0,$field = 'id,product_id,bargain_num,num,unit_name,image,title,price,min_price,image,description,start_time,stop_time,rule'){ + if(!$bargainId) return []; + $model = self::validWhere(); + $bargain = $model->field($field)->where('id',$bargainId)->find(); + if($bargain) return $bargain->toArray(); + else return []; + } + + /** + * 获取一条砍价产品 + * @param int $bargainId + * @param string $field + * @return array + */ + public static function getBargain($bargainId = 0,$field = 'id,product_id,title,price,min_price,image'){ + if(!$bargainId) return []; + $model = new self(); + $bargain = $model->field($field)->where('id',$bargainId)->find(); + if($bargain) return $bargain->toArray(); + else return []; + } + + /** + * 获取最高价和最低价 + * @param int $bargainId + * @return array + */ + public static function getBargainMaxMinPrice($bargainId = 0){ + if(!$bargainId) return []; + return self::where('id',$bargainId)->field('bargain_min_price,bargain_max_price')->find()->toArray(); + } + + /** + * 获取砍价次数 + * @param int $bargainId + * @return mixed + */ + public static function getBargainNum($bargainId = 0){ + return self::where('id',$bargainId)->value('bargain_num'); + } + + /** + * 判断当前砍价是否活动进行中 + * @param int $bargainId + * @return bool + */ + public static function setBargainStatus($bargainId = 0){ + $model = self::validWhere(); + $count = $model->where('id',$bargainId)->count(); + if($count) return true; + else return false; + } + + /** + * 获取库存 + * @param int $bargainId + * @return mixed + */ + public static function getBargainStock($bargainId = 0){ + return self::where('id',$bargainId)->value('stock'); + } + /** + * 修改销量和库存 + * @param $num + * @param $CombinationId + * @return bool + */ + public static function decBargainStock($num,$bargainId) + { + $res = false !== self::where('id',$bargainId)->dec('stock',$num)->inc('sales',$num)->update(); + return $res; + } + + /** + * 获取所有砍价产品的浏览量 + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getBargainLook(){ + return self::field('sum(look) as look')->find(); + } + + /** + * 获取所有砍价产品的分享量 + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getBargainShare(){ + return self::field('sum(share) as share')->find(); + } + + /** + * 添加砍价产品分享次数 + * @param int $id + * @return bool + */ + public static function addBargainShare($id = 0){ + if(!$id) return false; + return self::where('id',$id)->inc('share',1)->update(); + } + + /** + * 添加砍价产品浏览次数 + * @param int $id + * @return bool + */ + public static function addBargainLook($id = 0){ + if(!$id) return false; + return self::where('id',$id)->inc('look',1)->update(); + } +} \ No newline at end of file diff --git a/application/routine/model/store/StoreBargainUser.php b/application/routine/model/store/StoreBargainUser.php new file mode 100644 index 00000000..832ebf7c --- /dev/null +++ b/application/routine/model/store/StoreBargainUser.php @@ -0,0 +1,141 @@ +$v){ + if(is_array($v)){ + $uid = self::getUserIdList($v['id']); + if(count($uid) > 0) { + $userInfo = User::where('uid','IN',implode(',',$uid))->limit($limit)->column('avatar','uid'); + $bargain[$k]['userInfo'] = $userInfo; + $bargain[$k]['userInfoCount'] = count($userInfo); + } + else { + $bargain[$k]['userInfo'] = []; + $bargain[$k]['userInfoCount'] = 0; + } + }else{ + $uid = self::getUserIdList($bargain['id']); + if(count($uid) > 0) $bargain['userInfo'] = User::where('uid','IN',implode(',',$uid))->column('avatar','uid'); + else $bargain['userInfo'] = []; + } + } + return $bargain; + } + + /** + * 根据砍价产品ID获取正在参与人的uid + * @param int $bargainId $bargainId 砍价产品ID + * @param int $status $status 状态 1 进行中 2 结束失败 3结束成功 + * @return array + */ + public static function getUserIdList($bargainId = 0,$status = 1){ + if(!$bargainId) return []; + return self::where('bargain_id',$bargainId)->where('status',$status)->column('uid','id'); + } + + /** + * 获取参与的ID + * @param int $bargainId + * @param int $uid + * @param int $status + * @return array|mixed + */ + public static function setUserBargain($bargainId = 0,$uid = 0,$status = 1){ + if(!$bargainId || !$uid) return []; + $bargainIdUserTableId = self::where('bargain_id',$bargainId)->where('uid',$uid)->where('status',$status)->value('id'); + return $bargainIdUserTableId; + } + + + + /** + * 添加一条砍价记录 + * @param int $bargainId + * @param int $uid + * @return bool|object + */ + public static function setBargain($bargainId = 0,$uid = 0){ + if(!$bargainId || !$uid || !StoreBargain::validBargain($bargainId) || self::be(['id'=>$bargainId,'uid'=>$uid,'status'=>1])) return false; + $data['bargain_id'] = $bargainId; + $data['uid'] = $uid; + $data['bargain_price_min'] = StoreBargain::where('id',$bargainId)->value('min_price'); + $data['bargain_price'] = StoreBargain::where('id',$bargainId)->value('price'); + $data['price'] = 0; + $data['status'] = 1; + $data['add_time'] = time(); + return self::set($data); + } + + + /** + * 判断当前人是否已经参与砍价 + * @param int $bargainId + * @param int $uid + * @return bool|mixed + */ + public static function isBargainUser($bargainId = 0,$uid = 0){ + if(!$bargainId || !$uid || !StoreBargain::validBargain($bargainId)) return false; + return self::where('bargain_id',$bargainId)->where('uid',$uid)->value('uid'); + } + + /** + * 获取用户砍掉的价格 + * @param int $bargainUserId + * @return mixed + */ + public static function getBargainUserPrice($bargainUserId = 0){ + return (float)self::where('id',$bargainUserId)->value('price'); + } + + + /** + * 获取用户可以砍掉的价格 + * @param int $bargainUserId + * @return string + */ + public static function getBargainUserDiffPrice($bargainId = 0,$bargainUserId = 0){ + $price = self::where('bargain_id',$bargainId)->where('uid',$bargainUserId)->field('bargain_price,bargain_price_min')->find()->toArray(); + return (float)bcsub($price['bargain_price'],$price['bargain_price_min'],0); + } + + /** + * 获取砍价表ID + * @param int $bargainId + * @param int $bargainUserId + * @return mixed + */ + public static function getBargainUserTableId($bargainId = 0,$bargainUserId = 0){ + return self::where('bargain_id',$bargainId)->where('uid',$bargainUserId)->value('id'); + } + + /** + * 修改砍价价格 + * @param int $bargainUserTableId + * @param array $price + * @return $this|bool + */ + public static function setBargainUserPrice($bargainUserTableId = 0, $price = array()){ + if(!$bargainUserTableId) return false; + return self::where('id',$bargainUserTableId)->update($price); + } +} \ No newline at end of file diff --git a/application/routine/model/store/StoreBargainUserHelp.php b/application/routine/model/store/StoreBargainUserHelp.php new file mode 100644 index 00000000..525283c7 --- /dev/null +++ b/application/routine/model/store/StoreBargainUserHelp.php @@ -0,0 +1,132 @@ +limit($limit)->column('uid,price','id'); + if($list){ + foreach ($list as $k=>$v){ + $userInfo = self::getBargainUserHelpUserInfo($v['uid']); + $list[$k]['nickname'] = $userInfo[$v['uid']]['nickname']; + $list[$k]['avatar'] = $userInfo[$v['uid']]['avatar']; + } + } + return $list; + } + + /** + * 获取用的昵称和头像 + * @param int $uid + * @return array + */ + public static function getBargainUserHelpUserInfo($uid = 0){ + if(!$uid) return []; + $userInfo = User::where('uid',$uid)->column('nickname,avatar','uid'); + return $userInfo; + } + + /** + * 帮忙砍价 + * @param int $bargainId + * @param int $bargainUserId + * @param int $uid + * @return bool|object + */ + public static function setBargainUserHelp($bargainId = 0,$bargainUserId = 0,$uid = 0){ + if(!self::isBargainUserHelpCount($bargainId,$bargainUserId,$uid) || !$bargainId || !$bargainUserId || !$uid || !StoreBargain::validBargain($bargainId) || !StoreBargainUser::be(['id'=>$bargainId,'uid'=>$bargainUserId,'status'=>1])) return false; + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $priceSection = StoreBargain::getBargainMaxMinPrice($bargainId); //获取砍价的价格区间 + $coverPrice = StoreBargainUser::getBargainUserDiffPrice($bargainId,$bargainUserId);//用户可以砍掉的金额 + $alreadyPrice= StoreBargainUser::getBargainUserPrice($bargainUserTableId);//用户已经砍掉的价格 + $surplusPrice = (float)bcsub($coverPrice,$alreadyPrice,2);//用户剩余要砍掉的价格 + $data['uid'] = $uid; + $data['bargain_id'] = $bargainId; + $data['bargain_user_id'] = $bargainUserTableId; + $data['price'] = mt_rand($priceSection['bargain_min_price'],$priceSection['bargain_max_price']); + $data['add_time'] = time(); + if($data['price'] > $surplusPrice) $data['price'] = $surplusPrice; + $price = bcadd($alreadyPrice,$data['price'],0); + $bargainUserData['price'] = $price; + self::beginTrans(); + $res1 = StoreBargainUser::setBargainUserPrice($bargainUserTableId,$bargainUserData); + $res2 = self::set($data); + $res = $res1 && $res2; + self::checkTrans($res); + if($res) return $data; + else return $res; + } + + /** + * 判断用户是否还可以砍价 + * @param int $bargainId + * @param int $bargainUserUid + * @param int $bargainUserHelpUid + * @return bool + */ + public static function isBargainUserHelpCount($bargainId = 0,$bargainUserUid = 0,$bargainUserHelpUid = 0){ + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserUid); + $bargainNum = StoreBargain::getBargainNum($bargainUserTableId); + $count = self::where('bargain_id',$bargainId)->where('bargain_user_id',$bargainUserTableId)->where('uid',$bargainUserHelpUid)->count(); + if($count < $bargainNum) return true; + else return false; + + } + + /** + * 获取砍价帮总人数 + * @param int $bargainId + * @param int $bargainUserId + * @return int|string + */ + public static function getBargainUserHelpPeopleCount($bargainId = 0,$bargainUserId = 0){ + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + if($bargainUserTableId) return self::where('bargain_user_id',$bargainUserTableId)->where('bargain_id',$bargainId)->count(); + else return 0; + } + + /** + * 获取用户还剩余的砍价金额 + * @param int $bargainId + * @param int $bargainUserId + * @return float + */ + public static function getSurplusPrice($bargainId = 0,$bargainUserId = 0){ + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $coverPrice = StoreBargainUser::getBargainUserDiffPrice($bargainId,$bargainUserId);//用户可以砍掉的金额 + $alreadyPrice= StoreBargainUser::getBargainUserPrice($bargainUserTableId);//用户已经砍掉的价格 + $surplusPrice = (float)bcsub($coverPrice,$alreadyPrice,2);//用户剩余要砍掉的价格 + return $surplusPrice; + } + + /** + * 获取砍价进度条 + * @param int $bargainId + * @param int $bargainUserId + * @return string + */ + public static function getSurplusPricePercent($bargainId = 0,$bargainUserId = 0){ + $coverPrice = StoreBargainUser::getBargainUserDiffPrice($bargainId,$bargainUserId);//用户可以砍掉的金额 + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $alreadyPrice= StoreBargainUser::getBargainUserPrice($bargainUserTableId);//用户已经砍掉的价格 + return bcmul(bcdiv($alreadyPrice,$coverPrice,2),100,0); + } +} + diff --git a/application/routine/model/store/StoreCart.php b/application/routine/model/store/StoreCart.php new file mode 100644 index 00000000..0be52362 --- /dev/null +++ b/application/routine/model/store/StoreCart.php @@ -0,0 +1,220 @@ + + * @day: 2017/12/18 + */ + +namespace app\routine\model\store; + + +use app\routine\model\store\StoreCombination; +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCart extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function setCart($uid,$product_id,$cart_num = 1,$product_attr_unique = '',$type='product',$is_new = 0,$combination_id=0,$seckill_id = 0,$bargain_id = 0) + { + if($cart_num < 1) $cart_num = 1; + if($seckill_id){ + if(!StoreSeckill::getValidProduct($seckill_id)) + return self::setErrorInfo('该产品已下架或删除'); + if(StoreSeckill::getProductStock($seckill_id) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + $where = ['type'=>$type,'uid'=>$uid,'product_id'=>$product_id,'product_attr_unique'=>$product_attr_unique,'is_new'=>$is_new,'is_pay'=>0,'is_del'=>0,'seckill_id'=>$seckill_id]; + if($cart = self::where($where)->find()){ + $cart->cart_num = $cart_num; + $cart->add_time = time(); + $cart->save(); + return $cart; + }else{ + return self::set(compact('uid','product_id','cart_num','product_attr_unique','is_new','type','seckill_id')); + } + }elseif($bargain_id){ + if(!StoreBargain::validBargain($bargain_id)) + return self::setErrorInfo('该产品已下架或删除'); + if(StoreBargain::getBargainStock($bargain_id) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + $where = ['type'=>$type,'uid'=>$uid,'product_id'=>$product_id,'product_attr_unique'=>$product_attr_unique,'is_new'=>$is_new,'is_pay'=>0,'is_del'=>0,'bargain_id'=>$bargain_id]; + if($cart = self::where($where)->find()){ + $cart->cart_num = $cart_num; + $cart->add_time = time(); + $cart->save(); + return $cart; + }else{ + return self::set(compact('uid','product_id','cart_num','product_attr_unique','is_new','type','bargain_id')); + } + }elseif($combination_id){//拼团 + if(!StoreCombination::getCombinationStock($combination_id,$cart_num)) + return self::setErrorInfo('该产品库存不足'.$cart_num); + if(!StoreCombination::isValidCombination($combination_id)) + return self::setErrorInfo('该产品已下架或删除'); + }else{ + if(!StoreProduct::isValidProduct($product_id)) + return self::setErrorInfo('该产品已下架或删除'); + if(!StoreProductAttr::issetProductUnique($product_id,$product_attr_unique)) + return self::setErrorInfo('请选择有效的产品属性'); + if(StoreProduct::getProductStock($product_id,$product_attr_unique) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + } + $where = ['type'=>$type,'uid'=>$uid,'product_id'=>$product_id,'product_attr_unique'=>$product_attr_unique,'is_new'=>$is_new,'is_pay'=>0,'is_del'=>0,'combination_id'=>$combination_id]; + if($cart = self::where($where)->find()){ + $cart->cart_num = $cart_num; + $cart->add_time = time(); + $cart->save(); + return $cart; + }else{ + return self::set(compact('uid','product_id','cart_num','product_attr_unique','is_new','type','combination_id')); + } + + } + + public static function removeUserCart($uid,$ids) + { + return self::where('uid',$uid)->where('id','IN',$ids)->update(['is_del'=>1]); + } + + public static function getUserCartNum($uid,$type) + { + return self::where('uid',$uid)->where('type',$type)->where('is_pay',0)->where('is_del',0)->where('is_new',0)->count(); + } + + public static function changeUserCartNum($cartId,$cartNum,$uid) + { + return self::where('uid',$uid)->where('id',$cartId)->update(['cart_num'=>$cartNum]); + } + + public static function getUserProductCartList($uid,$cartIds='',$status=0) + { + $productInfoField = 'id,image,slider_image,price,ot_price,vip_price,postage,mer_id,give_integral,cate_id,sales,stock,store_name,store_info,unit_name,is_show,is_del,is_postage,cost'; + $seckillInfoField = 'id,image,price,ot_price,postage,give_integral,sales,stock,title as store_name,unit_name,is_show,is_del,is_postage,cost'; + $bargainInfoField = 'id,image,min_price as price,price as ot_price,postage,give_integral,sales,stock,title as store_name,unit_name,status as is_show,is_del,is_postage,cost'; + $combinationInfoField = 'id,image,price,ot_price,postage,give_integral,sales,stock,title as store_name,is_show,is_del,is_postage,cost'; + $model = new self(); + $valid = $invalid = []; + $model = $model->where('uid',$uid)->where('type','product')->where('is_pay',0) + ->where('is_del',0); + if(!$status) $model->where('is_new',0); + if($cartIds) $model->where('id','IN',$cartIds); + $list = $model->select()->toArray(); + if(!count($list)) return compact('valid','invalid'); + foreach ($list as $k=>$cart){ + if($cart['seckill_id']){ + $product = StoreSeckill::field($seckillInfoField) + ->find($cart['seckill_id'])->toArray(); + }elseif($cart['bargain_id']){ + $product = StoreBargain::field($bargainInfoField) + ->find($cart['bargain_id'])->toArray(); + }elseif($cart['combination_id']){ + $product = StoreCombination::field($combinationInfoField) + ->find($cart['combination_id'])->toArray(); + }else{ + $product = StoreProduct::field($productInfoField) + ->find($cart['product_id'])->toArray(); + } + $cart['productInfo'] = $product; + //商品不存在 + if(!$product){ + $model->where('id',$cart['id'])->update(['is_del'=>1]); + //商品删除或无库存 + }else if(!$product['is_show'] || $product['is_del'] || !$product['stock']){ + $invalid[] = $cart; + //商品属性不对应 + }else if(!StoreProductAttr::issetProductUnique($cart['product_id'],$cart['product_attr_unique']) && !$cart['combination_id'] && !$cart['seckill_id']){ + $invalid[] = $cart; + //正常商品 + }else{ + if($cart['product_attr_unique']){ + $attrInfo = StoreProductAttr::uniqueByAttrInfo($cart['product_attr_unique']); + //商品没有对应的属性 + if(!$attrInfo || !$attrInfo['stock']) + $invalid[] = $cart; + else{ + $cart['productInfo']['attrInfo'] = $attrInfo; + $cart['truePrice'] = (float)$attrInfo['price']; + $cart['trueStock'] = $attrInfo['stock']; + $cart['costPrice'] = $cart['productInfo']['cost']; + $cart['productInfo']['image'] = empty($attrInfo['image']) ? $cart['productInfo']['image'] : $attrInfo['image']; + $valid[] = $cart; + } + }else{ + $cart['truePrice'] = (float)$cart['productInfo']['price']; + $cart['trueStock'] = $cart['productInfo']['stock']; + $cart['costPrice'] = $cart['productInfo']['cost']; + $valid[] = $cart; + } + } + } + + foreach ($valid as $k=>$cart){ + if($cart['trueStock'] < $cart['cart_num']){ + $cart['cart_num'] = $cart['trueStock']; + $model->where('id',$cart['id'])->update(['cart_num'=>$cart['cart_num']]); + $valid[$k] = $cart; + } + } + + return compact('valid','invalid'); + } + + /** + * 拼团 + * @param $uid + * @param string $cartIds + * @return array + */ + public static function getUserCombinationProductCartList($uid,$cartIds='') + { + $productInfoField = 'id,image,slider_image,price,cost,ot_price,vip_price,postage,mer_id,give_integral,cate_id,sales,stock,store_name,unit_name,is_show,is_del,is_postage'; + $model = new self(); + $valid = $invalid = []; + $model = $model->where('uid',$uid)->where('type','product')->where('is_pay',0) + ->where('is_del',0); + if($cartIds) $model->where('id','IN',$cartIds); + $list = $model->select()->toArray(); + if(!count($list)) return compact('valid','invalid'); + foreach ($list as $k=>$cart){ + $product = StoreProduct::field($productInfoField) + ->find($cart['product_id'])->toArray(); + $cart['productInfo'] = $product; + //商品不存在 + if(!$product){ + $model->where('id',$cart['id'])->update(['is_del'=>1]); + //商品删除或无库存 + }else if(!$product['is_show'] || $product['is_del'] || !$product['stock']){ + $invalid[] = $cart; + //商品属性不对应 +// }else if(!StoreProductAttr::issetProductUnique($cart['product_id'],$cart['product_attr_unique'])){ +// $invalid[] = $cart; + //正常商品 + }else{ + $cart['truePrice'] = (float)StoreCombination::where('id',$cart['combination_id'])->value('price'); + $cart['costPrice'] = (float)StoreCombination::where('id',$cart['combination_id'])->value('cost'); + $cart['trueStock'] = StoreCombination::where('id',$cart['combination_id'])->value('stock'); + $valid[] = $cart; + } + } + + foreach ($valid as $k=>$cart){ + if($cart['trueStock'] < $cart['cart_num']){ + $cart['cart_num'] = $cart['trueStock']; + $model->where('id',$cart['id'])->update(['cart_num'=>$cart['cart_num']]); + $valid[$k] = $cart; + } + } + + return compact('valid','invalid'); + } + + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreCategory.php b/application/routine/model/store/StoreCategory.php new file mode 100644 index 00000000..0b9043af --- /dev/null +++ b/application/routine/model/store/StoreCategory.php @@ -0,0 +1,32 @@ + + * @day: 2017/12/12 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; + +class StoreCategory extends ModelBasic +{ + public static function pidByCategory($pid,$field = '*',$limit = 0) + { + $model = self::where('pid',$pid)->where('is_show',1)->field($field); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function pidBySidList($pid) + { + return self::where('pid',$pid)->field('id,cate_name')->select(); + } + + public static function cateIdByPid($cateId) + { + return self::where('id',$cateId)->value('pid'); + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreCombination.php b/application/routine/model/store/StoreCombination.php new file mode 100644 index 00000000..6c0d7289 --- /dev/null +++ b/application/routine/model/store/StoreCombination.php @@ -0,0 +1,161 @@ + + * @day: 2017/11/11 + */ + +namespace app\routine\model\store; + + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 拼团model + * Class StoreCombination + * @package app\routine\model\store + */ +class StoreCombination extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function get_list($length=10){ + if($post=input('post.')){ + $where=$post['where']; + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->where('c.is_show',1)->where('c.is_del',0)->where('c.start_time','LT',time())->where('c.stop_time','GT',time()); + if(!empty($where['search'])){ + $model = $model->where('c.title','like',"%{$where['search']}%"); + $model = $model->whereOr('s.keyword','like',"{$where['search']}%"); + } + $model = $model->field('c.*,s.price as product_price'); + if($where['key']){ + if($where['sales']==1){ + $model = $model->order('c.sales desc'); + }else if($where['sales']==2){ + $model = $model->order('c.sales asc'); + } + if($where['price']==1){ + $model = $model->order('c.price desc'); + }else if($where['price']==2){ + $model = $model->order('c.price asc'); + } + if($where['people']==1){ + $model = $model->order('c.people asc'); + } + if($where['default']==1){ + $model = $model->order('c.sort desc,c.id desc'); + } + }else{ + $model = $model->order('c.sort desc,c.id desc'); + } + $page=is_string($where['page'])?(int)$where['page']+1:$where['page']+1; + $list = $model->page($page,$length)->select()->toArray(); + return ['list'=>$list,'page'=>$page]; + } + } + + /** + * 获取所有拼团数据 + * @param int $limit + * @param int $length + * @return mixed + */ + public static function getAll($limit = 0,$length = 0){ + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->field('c.*,s.price as product_price'); + $model = $model->order('c.sort desc,c.id desc'); + $model = $model->where('c.is_show',1); + $model = $model->where('c.is_del',0); +// $model = $model->where('c.start_time','LT',time()); +// $model = $model->where('c.stop_time','GT',time()); + if($limit && $length) $model = $model->limit($limit,$length); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取一条拼团数据 + * @param $id + * @return mixed + */ + public static function getCombinationOne($id){ + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->field('c.*,s.price as product_price'); + $model = $model->where('c.is_show',1); + $model = $model->where('c.is_del',0); + $model = $model->where('c.id',$id); +// $model = $model->where('c.start_time','LT',time()); +// $model = $model->where('c.stop_time','GT',time()-86400); + $list = $model->find(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取推荐的拼团产品 + * @return mixed + */ + public static function getCombinationHost($limit = 0){ + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->field('c.id,c.image,c.price,c.sales,c.title,c.people,s.price as product_price'); + $model = $model->where('c.is_del',0); + $model = $model->where('c.is_host',1); + $model = $model->where('c.is_host',1); + $model = $model->where('c.start_time','LT',time()); + $model = $model->where('c.stop_time','GT',time()); + if($limit) $model = $model->limit($limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 修改销量和库存 + * @param $num + * @param $CombinationId + * @return bool + */ + public static function decCombinationStock($num,$CombinationId) + { + $res = false !== self::where('id',$CombinationId)->dec('stock',$num)->inc('sales',$num)->update(); + return $res; + } + /** + * 判断库存是否足够 + * @param $id + * @param $cart_num + * @return int|mixed + */ + public static function getCombinationStock($id,$cart_num){ + $stock = self::where('id',$id)->value('stock'); + return $stock > $cart_num ? $stock : 0; + } + /** + * 获取产品状态 + * @param $id + * @return mixed + */ + public static function isValidCombination($id){ + $model = new self(); + $model = $model->where('id',$id); + $model = $model->where('is_del',0); + $model = $model->where('is_show',1); + return $model->count(); + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreCoupon.php b/application/routine/model/store/StoreCoupon.php new file mode 100644 index 00000000..6badd04c --- /dev/null +++ b/application/routine/model/store/StoreCoupon.php @@ -0,0 +1,17 @@ + + * @day: 2018/01/22 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCoupon extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/routine/model/store/StoreCouponIssue.php b/application/routine/model/store/StoreCouponIssue.php new file mode 100644 index 00000000..237cfb1c --- /dev/null +++ b/application/routine/model/store/StoreCouponIssue.php @@ -0,0 +1,60 @@ + + * @day: 2018/01/18 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponIssue extends ModelBasic +{ + use ModelTrait; + + /** + * @param string $prefix + * @return $this + */ + public static function validWhere($prefix = '') + { + $model = new self; + if($prefix){ + $model->alias($prefix); + $prefix .= '.'; + } + $newTime = time(); + return $model->where("{$prefix}status",1) + ->where(function($query) use($newTime,$prefix){ + $query->where(function($query) use($newTime,$prefix){ + $query->where("{$prefix}start_time",'<',$newTime)->where("{$prefix}end_time",'>',$newTime); + })->whereOr(function ($query) use($prefix){ + $query->where("{$prefix}start_time",0)->where("{$prefix}end_time",0); + }); + })->where("{$prefix}is_del",0); + } + + + public static function issueUserCoupon($id,$uid) + { + $issueCouponInfo = self::validWhere()->where('id',$id)->find(); + if(!$issueCouponInfo) return self::setErrorInfo('领取的优惠劵已领完或已过期!'); + if(StoreCouponIssueUser::be(['uid'=>$uid,'issue_coupon_id'=>$id])) + return self::setErrorInfo('已领取过该优惠劵!'); + self::beginTrans(); + $res1 = false != StoreCouponUser::addUserCoupon($uid,$issueCouponInfo['cid']); + $res2 = false != StoreCouponIssueUser::addUserIssue($uid,$id); + $res3 = true; + if($issueCouponInfo['total_count'] > 0){ + $issueCouponInfo['remain_count'] -= 1; + $res3 = false !== $issueCouponInfo->save(); + } + $res = $res1 && $res2 & $res3; + self::checkTrans($res); + return $res; + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreCouponIssueUser.php b/application/routine/model/store/StoreCouponIssueUser.php new file mode 100644 index 00000000..d3bb3237 --- /dev/null +++ b/application/routine/model/store/StoreCouponIssueUser.php @@ -0,0 +1,22 @@ + + * @day: 2018/01/22 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponIssueUser extends ModelBasic +{ + use ModelTrait; + public static function addUserIssue($uid,$issue_coupon_id) + { + $add_time = time(); + return self::set(compact('uid','issue_coupon_id','add_time')); + } +} \ No newline at end of file diff --git a/application/routine/model/store/StoreCouponUser.php b/application/routine/model/store/StoreCouponUser.php new file mode 100644 index 00000000..31114bb8 --- /dev/null +++ b/application/routine/model/store/StoreCouponUser.php @@ -0,0 +1,146 @@ + + * @day: 2017/12/20 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponUser extends ModelBasic +{ + use ModelTrait; + /** + * 获取用户优惠券(全部) + * @return \think\response\Json + */ + public static function getUserAllCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + /** + * 获取用户优惠券(未使用) + * @return \think\response\Json + */ + public static function getUserValidCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->where('status',0)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + /** + * 获取用户优惠券(已使用) + * @return \think\response\Json + */ + public static function getUserAlreadyUsedCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->where('status',1)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + /** + * 获取用户优惠券(已过期) + * @return \think\response\Json + */ + public static function getUserBeOverdueCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->where('status',2)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + public static function beUsableCoupon($uid,$price) + { + return self::where('uid',$uid)->where('is_fail',0)->where('status',0)->where('use_min_price','<=',$price)->find(); + } + + /** + * 获取用户可以使用的优惠券 + * @param $uid + * @param $price + * @return false|\PDOStatement|string|\think\Collection + */ + public static function beUsableCouponList($uid,$price){ + return self::where('uid',$uid)->where('is_fail',0)->where('status',0)->where('use_min_price','<=',$price)->select(); + } + + public static function validAddressWhere($model=null,$prefix = '') + { + self::checkInvalidCoupon(); + if($prefix) $prefix .='.'; + $model = self::getSelfModel($model); + return $model->where("{$prefix}is_fail",0)->where("{$prefix}status",0); + } + + public static function checkInvalidCoupon() + { + self::where('end_time','<',time())->where('status',0)->update(['status'=>2]); + } + + public static function tidyCouponList($couponList) + { + $time = time(); + foreach ($couponList as $k=>$coupon){ + $coupon['_add_time'] = date('Y/m/d',$coupon['add_time']); + $coupon['_end_time'] = date('Y/m/d',$coupon['end_time']); + $coupon['use_min_price'] = floatval($coupon['use_min_price']); + $coupon['coupon_price'] = floatval($coupon['coupon_price']); + if($coupon['is_fail']){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已失效'; + }else if ($coupon['status'] == 1){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已使用'; + }else if ($coupon['status'] == 2){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已过期'; + }else if($coupon['add_time'] > $time || $coupon['end_time'] < $time){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已过期'; + }else{ + if($coupon['add_time']+ 3600*24 > $time){ + $coupon['_type'] = 2; + $coupon['_msg'] = '可使用'; + }else{ + $coupon['_type'] = 1; + $coupon['_msg'] = '可使用'; + } + } + $couponList[$k] = $coupon; + } + return $couponList; + } + + public static function getUserValidCouponCount($uid) + { + self::checkInvalidCoupon(); + return self::where('uid',$uid)->where('status',0)->order('is_fail ASC,status ASC,add_time DESC')->count(); + } + + public static function useCoupon($id) + { + return self::where('id',$id)->update(['status'=>1,'use_time'=>time()]); + } + + public static function addUserCoupon($uid,$cid,$type = 'get') + { + $couponInfo = StoreCoupon::find($cid); + if(!$couponInfo) return self::setErrorInfo('优惠劵不存在!'); + $data = []; + $data['cid'] = $couponInfo['id']; + $data['uid'] = $uid; + $data['coupon_title'] = $couponInfo['title']; + $data['coupon_price'] = $couponInfo['coupon_price']; + $data['use_min_price'] = $couponInfo['use_min_price']; + $data['add_time'] = time(); + $data['end_time'] = $data['add_time']+$couponInfo['coupon_time']*86400; + $data['type'] = $type; + return self::set($data); + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreOrder.php b/application/routine/model/store/StoreOrder.php new file mode 100644 index 00000000..7d20ed78 --- /dev/null +++ b/application/routine/model/store/StoreOrder.php @@ -0,0 +1,736 @@ + + * @day: 2017/12/20 + */ + +namespace app\routine\model\store; + + +use app\routine\model\store\StoreCombination; +use app\routine\model\routine\RoutineFormId; +use app\routine\model\routine\RoutineTemplate; +use app\routine\model\store\StoreOrderCartInfo; +use app\routine\model\store\StoreOrderStatus; +use app\routine\model\store\StoreCart; +use app\routine\model\store\StoreProductReply; +use app\routine\model\user\User; +use app\routine\model\user\UserAddress; +use app\routine\model\user\UserBill; +use app\routine\model\user\WechatUser; +use basic\ModelBasic; +use behavior\wap\StoreProductBehavior; +use behavior\wechat\PaymentBehavior; +use service\HookService; +use service\RoutineService; +use service\SystemConfigService; +use service\WechatService; +use service\WechatTemplateService; +use think\Cache; +use think\Url; +use traits\ModelTrait; + +class StoreOrder extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected static $payType = ['weixin'=>'微信支付','yue'=>'余额支付','offline'=>'线下支付']; + + protected static $deliveryType = ['send'=>'商家配送','express'=>'快递配送']; + + protected function setAddTimeAttr() + { + return time(); + } + + protected function setCartIdAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + protected function getCartIdAttr($value) + { + return json_decode($value,true); + } + + public static function getOrderPriceGroup($cartInfo) + { + $storePostage = floatval(SystemConfigService::get('store_postage'))?:0; + $storeFreePostage = floatval(SystemConfigService::get('store_free_postage'))?:0; + $totalPrice = self::getOrderTotalPrice($cartInfo); + $costPrice = self::getOrderCostPrice($cartInfo); + if(!$storeFreePostage) { + $storePostage = 0; + }else{ + foreach ($cartInfo as $cart){ + if(!$cart['productInfo']['is_postage']) + $storePostage = bcadd($storePostage,$cart['productInfo']['postage'],2); + + } + if($storeFreePostage <= $totalPrice) $storePostage = 0; + } + return compact('storePostage','storeFreePostage','totalPrice','costPrice'); + } + + public static function getOrderTotalPrice($cartInfo) + { + $totalPrice = 0; + foreach ($cartInfo as $cart){ + $totalPrice = bcadd($totalPrice,bcmul($cart['cart_num'],$cart['truePrice'],2),2); + } + return $totalPrice; + } + public static function getOrderCostPrice($cartInfo) + { + $costPrice=0; + foreach ($cartInfo as $cart){ + $costPrice = bcadd($costPrice,bcmul($cart['cart_num'],$cart['costPrice'],2),2); + } + return $costPrice; + } + + + + /** + * 拼团 + * @param $cartInfo + * @return array + */ + public static function getCombinationOrderPriceGroup($cartInfo) + { + $storePostage = floatval(SystemConfigService::get('store_postage'))?:0; + $storeFreePostage = floatval(SystemConfigService::get('store_free_postage'))?:0; + $totalPrice = self::getCombinationOrderTotalPrice($cartInfo); + $costPrice = self::getCombinationOrderCostPrice($cartInfo); + if(!$storeFreePostage) { + $storePostage = 0; + }else{ + foreach ($cartInfo as $cart){ + if(!StoreCombination::where('id',$cart['combination_id'])->value('is_postage')) + $storePostage = bcadd($storePostage,StoreCombination::where('id',$cart['combination_id'])->value('postage'),2); + } + if($storeFreePostage <= $totalPrice) $storePostage = 0; + } + return compact('storePostage','storeFreePostage','totalPrice','costPrice'); + } + + + /** + * 拼团价格 + * @param $cartInfo + * @return float + */ + public static function getCombinationOrderTotalPrice($cartInfo) + { + $totalPrice = 0; + foreach ($cartInfo as $cart){ + if($cart['combination_id']){ + $totalPrice = bcadd($totalPrice,bcmul($cart['cart_num'],StoreCombination::where('id',$cart['combination_id'])->value('price'),2),2); + } + } + return (float)$totalPrice; + } + public static function getCombinationOrderCostPrice($cartInfo) + { + $costPrice = 0; + foreach ($cartInfo as $cart){ + if($cart['combination_id']){ + $totalPrice = bcadd($costPrice,bcmul($cart['cart_num'],StoreCombination::where('id',$cart['combination_id'])->value('price'),2),2); + } + } + return (float)$costPrice; + } + + + public static function cacheOrderInfo($uid,$cartInfo,$priceGroup,$other = [],$cacheTime = 600) + { + $key = md5(time()); + Cache::set('user_order_'.$uid.$key,compact('cartInfo','priceGroup','other'),$cacheTime); + return $key; + } + + public static function getCacheOrderInfo($uid,$key) + { + $cacheName = 'user_order_'.$uid.$key; + if(!Cache::has($cacheName)) return null; + return Cache::get($cacheName); + } + + public static function clearCacheOrderInfo($uid,$key) + { + Cache::clear('user_order_'.$uid.$key); + } + + public static function cacheKeyCreateOrder($uid,$key,$addressId,$payType,$useIntegral = false,$couponId = 0,$mark = '',$combinationId = 0,$pinkId = 0,$seckill_id=0,$bargain_id=0) + { + if(!array_key_exists($payType,self::$payType)) return self::setErrorInfo('选择支付方式有误!'); + if(self::be(['unique'=>$key,'uid'=>$uid])) return self::setErrorInfo('请勿重复提交订单'); + $userInfo = User::getUserInfo($uid); + if(!$userInfo) return self::setErrorInfo('用户不存在!'); + $cartGroup = self::getCacheOrderInfo($uid,$key); + if(!$cartGroup) return self::setErrorInfo('订单已过期,请刷新当前页面!'); + $cartInfo = $cartGroup['cartInfo']; + $priceGroup = $cartGroup['priceGroup']; + $other = $cartGroup['other']; + $payPrice = $priceGroup['totalPrice']; + $payPostage = $priceGroup['storePostage']; + if(!$addressId) return self::setErrorInfo('请选择收货地址!'); + if(!UserAddress::be(['uid'=>$uid,'id'=>$addressId,'is_del'=>0]) || !($addressInfo = UserAddress::find($addressId))) + return self::setErrorInfo('地址选择有误!'); + + //使用优惠劵 + $res1 = true; + if($couponId){ + $couponInfo = StoreCouponUser::validAddressWhere()->where('id',$couponId)->where('uid',$uid)->find(); + if(!$couponInfo) return self::setErrorInfo('选择的优惠劵无效!'); + if($couponInfo['use_min_price'] > $payPrice) + return self::setErrorInfo('不满足优惠劵的使用条件!'); + $payPrice = bcsub($payPrice,$couponInfo['coupon_price'],2); + $res1 = StoreCouponUser::useCoupon($couponId); + $couponPrice = $couponInfo['coupon_price']; + }else{ + $couponId = 0; + $couponPrice = 0; + } + if(!$res1) return self::setErrorInfo('使用优惠劵失败!'); + + //是否包邮 + if((isset($other['offlinePostage']) && $other['offlinePostage'] && $payType == 'offline')) $payPostage = 0; + $payPrice = bcadd($payPrice,$payPostage,2); + + //积分抵扣 + $res2 = true; + if($useIntegral && $userInfo['integral'] > 0){ + $deductionPrice = bcmul($userInfo['integral'],$other['integralRatio'],2); + if($deductionPrice < $payPrice){ + $payPrice = bcsub($payPrice,$deductionPrice,2); + $usedIntegral = $userInfo['integral']; + $res2 = false !== User::edit(['integral'=>0],$userInfo['uid'],'uid'); + }else{ + $deductionPrice = $payPrice; + $usedIntegral = bcdiv($payPrice,$other['integralRatio'],2); + $res2 = false !== User::bcDec($userInfo['uid'],'integral',$usedIntegral,'uid'); + $payPrice = 0; + } + $res2 = $res2 && false != UserBill::expend('积分抵扣',$uid,'integral','deduction',$usedIntegral,$key,$userInfo['integral'],'购买商品使用'.floatval($usedIntegral).'积分抵扣'.floatval($deductionPrice).'元'); + }else{ + $deductionPrice = 0; + $usedIntegral = 0; + } + if(!$res2) return self::setErrorInfo('使用积分抵扣失败!'); + + $cartIds = []; + $totalNum = 0; + $gainIntegral = 0; + foreach ($cartInfo as $cart){ + $cartIds[] = $cart['id']; + $totalNum += $cart['cart_num']; + $gainIntegral = bcadd($gainIntegral,isset($cart['productInfo']['give_integral']) ? : 0,2); + } + $orderInfo = [ + 'uid'=>$uid, + 'order_id'=>self::getNewOrderId(), + 'real_name'=>$addressInfo['real_name'], + 'user_phone'=>$addressInfo['phone'], + 'user_address'=>$addressInfo['province'].' '.$addressInfo['city'].' '.$addressInfo['district'].' '.$addressInfo['detail'], + 'cart_id'=>$cartIds, + 'total_num'=>$totalNum, + 'total_price'=>$priceGroup['totalPrice'], + 'total_postage'=>$priceGroup['storePostage'], + 'coupon_id'=>$couponId, + 'coupon_price'=>$couponPrice, + 'pay_price'=>$payPrice, + 'pay_postage'=>$payPostage, + 'deduction_price'=>$deductionPrice, + 'paid'=>0, + 'pay_type'=>$payType, + 'use_integral'=>$usedIntegral, + 'gain_integral'=>$gainIntegral, + 'mark'=>htmlspecialchars($mark), + 'combination_id'=>$combinationId, + 'pink_id'=>$pinkId, + 'seckill_id'=>$seckill_id, + 'bargain_id'=>$bargain_id, + 'cost'=>$priceGroup['costPrice'], + 'is_channel'=>1, + 'unique'=>$key + ]; + $order = self::set($orderInfo); + if(!$order)return self::setErrorInfo('订单生成失败!'); + $res5 = true; + foreach ($cartInfo as $cart){ + //减库存加销量 + if($combinationId) $res5 = $res5 && StoreCombination::decCombinationStock($cart['cart_num'],$combinationId); + else if($seckill_id) $res5 = $res5 && StoreSeckill::decSeckillStock($cart['cart_num'],$seckill_id); + else if($bargain_id) $res5 = $res5 && StoreBargain::decBargainStock($cart['cart_num'],$bargain_id); + else $res5 = $res5 && StoreProduct::decProductStock($cart['cart_num'],$cart['productInfo']['id'],isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique']:''); + } + //保存购物车商品信息 + $res4 = false !== StoreOrderCartInfo::setCartInfo($order['id'],$cartInfo); + //购物车状态修改 + $res6 = false !== StoreCart::where('id','IN',$cartIds)->update(['is_pay'=>1]); + if(!$res4 || !$res5 || !$res6) return self::setErrorInfo('订单生成失败!'); + try{ + HookService::listen('store_product_order_create',$order,compact('cartInfo','addressId'),false,StoreProductBehavior::class); + }catch (\Exception $e){ + return self::setErrorInfo($e->getMessage()); + } + self::clearCacheOrderInfo($uid,$key); + self::commitTrans(); + StoreOrderStatus::status($order['id'],'cache_key_create_order','订单生成'); + return $order; + } + + public static function getNewOrderId() + { + $count = (int) self::where('add_time',['>=',strtotime(date("Y-m-d"))],['<',strtotime(date("Y-m-d",strtotime('+1 day')))])->count(); + return 'wx'.date('YmdHis',time()).(10000+$count+1); + } + + public static function changeOrderId($orderId) + { + $ymd = substr($orderId,2,8); + $key = substr($orderId,16); + return 'wx'.$ymd.date('His').$key; + } + + public static function jsPay($orderId,$field = 'order_id') + { + if(is_string($orderId)) + $orderInfo = self::where($field,$orderId)->find(); + else + $orderInfo = $orderId; + if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!'); + if($orderInfo['paid']) exception('支付已支付!'); + if($orderInfo['pay_price'] <= 0) exception('该支付无需支付!'); + $openid = WechatUser::getOpenId($orderInfo['uid']); + return RoutineService::payRoutine($openid,$orderInfo['order_id'],$orderInfo['pay_price'],'productr',SystemConfigService::get('site_name')); + } + + public static function yuePay($order_id,$uid,$formId = '') + { + $orderInfo = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->find(); + if(!$orderInfo) return self::setErrorInfo('订单不存在!'); + if($orderInfo['paid']) return self::setErrorInfo('该订单已支付!'); + if($orderInfo['pay_type'] != 'yue') return self::setErrorInfo('该订单不能使用余额支付!'); + $userInfo = User::getUserInfo($uid); + if($userInfo['now_money'] < $orderInfo['pay_price']) + return self::setErrorInfo('余额不足'.floatval($orderInfo['pay_price'])); + self::beginTrans(); + $res1 = false !== User::bcDec($uid,'now_money',$orderInfo['pay_price'],'uid'); + $res2 = UserBill::expend('购买商品',$uid,'now_money','pay_product',$orderInfo['pay_price'],$orderInfo['id'],$userInfo['now_money'],'余额支付'.floatval($orderInfo['pay_price']).'元购买商品'); + $res3 = self::paySuccess($order_id,$formId); + try{ +// HookService::listen('yue_pay_product',$userInfo,$orderInfo,false,PaymentBehavior::class); + }catch (\Exception $e){ + self::rollbackTrans(); + return self::setErrorInfo($e->getMessage()); + } + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + } + + /** + * 微信支付 为 0元时 + * @param $order_id + * @param $uid + * @return bool + */ + public static function jsPayPrice($order_id,$uid,$formId = ''){ + $orderInfo = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->find(); + if(!$orderInfo) return self::setErrorInfo('订单不存在!'); + if($orderInfo['paid']) return self::setErrorInfo('该订单已支付!'); + $userInfo = User::getUserInfo($uid); + self::beginTrans(); + $res1 = UserBill::expend('购买商品',$uid,'now_money','pay_product',$orderInfo['pay_price'],$orderInfo['id'],$userInfo['now_money'],'微信支付'.floatval($orderInfo['pay_price']).'元购买商品'); + $res2 = self::paySuccess($order_id,$formId); + $res = $res1 && $res2; + self::checkTrans($res); + return $res; + } + + + + /** + * 用户申请退款 + * @param $uni + * @param $uid + * @param string $refundReasonWap + * @return bool + */ + public static function orderApplyRefund($uni, $uid,$refundReasonWap = '',$refundReasonWapExplain = '',$refundReasonWapImg = array()) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('支付订单不存在!'); + if($order['refund_status'] == 2) return self::setErrorInfo('订单已退款!'); + if($order['refund_status'] == 1) return self::setErrorInfo('正在申请退款中!'); + if($order['status'] == 1) return self::setErrorInfo('订单当前无法退款!'); + self::beginTrans(); + $res1 = false !== StoreOrderStatus::status($order['id'],'apply_refund','用户申请退款,原因:'.$refundReasonWap); + $res2 = false !== self::edit(['refund_status'=>1,'refund_reason_time'=>time(),'refund_reason_wap'=>$refundReasonWap,'refund_reason_wap_explain'=>$refundReasonWapExplain,'refund_reason_wap_img'=>json_encode($refundReasonWapImg)],$order['id'],'id'); + $res = $res1 && $res2; + self::checkTrans($res); + if(!$res) + return self::setErrorInfo('申请退款失败!'); + else{ + try{ + $adminIds = SystemConfigService::get('site_store_admin_uids'); + if(!$adminIds || !($adminList = array_unique(array_filter(explode(',',trim($adminIds)))))) return false; + RoutineTemplate::sendOrderRefundStatus($order,$refundReasonWap,$adminList);//小程序 发送模板消息 + }catch (\Exception $e){} + return true; + } + } + + /** + * //TODO 支付成功后 + * @param $orderId + * @param $notify + * @return bool + */ + public static function paySuccess($orderId,$formId = '') + { + $order = self::where('order_id',$orderId)->find(); + $resPink = true; + $res1 = self::where('order_id',$orderId)->update(['paid'=>1,'pay_time'=>time()]); + User::bcInc($order['uid'],'pay_count',1,'uid'); + if($order->combination_id && $res1 && !$order->refund_status) $resPink = StorePink::createPink($order);//创建拼团 + $oid = self::where('order_id',$orderId)->value('id'); + StoreOrderStatus::status($oid,'pay_success','用户付款成功'); + RoutineTemplate::sendOrderSuccess($formId,$orderId); + $res = $res1 && $resPink; + return false !== $res; + } + + public static function createOrderTemplate($order) + { + $goodsName = StoreOrderCartInfo::getProductNameList($order['id']); + WechatTemplateService::sendTemplate(WechatUser::getOpenId($order['uid']),WechatTemplateService::ORDER_CREATE, [ + 'first'=>'亲,您购买的商品已支付成功', + 'keyword1'=>date('Y/m/d H:i',$order['add_time']), + 'keyword2'=>implode(',',$goodsName), + 'keyword3'=>$order['order_id'], + 'remark'=>'点击查看订单详情' + ],Url::build('/wap/My/order',['uni'=>$order['order_id']],true,true)); + WechatTemplateService::sendAdminNoticeTemplate([ + 'first'=>"亲,您有一个新订单 \n订单号:{$order['order_id']}", + 'keyword1'=>'新订单', + 'keyword2'=>'线下支付', + 'keyword3'=>date('Y/m/d H:i',time()), + 'remark'=>'请及时处理' + ]); + } + + public static function getUserOrderDetail($uid,$key) + { + return self::where('order_id|unique',$key)->where('uid',$uid)->where('is_del',0)->find(); + } + + + /** + * TODO 订单发货 + * @param array $postageData 发货信息 + * @param string $oid orderID + */ + public static function orderPostageAfter($postageData, $oid) + { + $order = self::where('id',$oid)->find(); + $openid = WechatUser::getOpenId($order['uid']); + $url = Url::build('wap/My/order',['uni'=>$order['order_id']],true,true); + $group = [ + 'first'=>'亲,您的订单已发货,请注意查收', + 'remark'=>'点击查看订单详情' + ]; + if($postageData['delivery_type'] == 'send'){//送货 + $goodsName = StoreOrderCartInfo::getProductNameList($order['id']); + $group = array_merge($group,[ + 'keyword1'=>$goodsName, + 'keyword2'=>$order['pay_type'] == 'offline' ? '线下支付' : date('Y/m/d H:i',$order['pay_time']), + 'keyword3'=>$order['user_address'], + 'keyword4'=>$postageData['delivery_name'], + 'keyword5'=>$postageData['delivery_id'] + ]); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_DELIVER_SUCCESS,$group,$url); + + }else if($postageData['delivery_type'] == 'express'){//发货 + $group = array_merge($group,[ + 'keyword1'=>$order['order_id'], + 'keyword2'=>$postageData['delivery_name'], + 'keyword3'=>$postageData['delivery_id'] + ]); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_POSTAGE_SUCCESS,$group,$url); + } + } + + public static function orderTakeAfter($order) + { + $openid = WechatUser::getOpenId($order['uid']); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_TAKE_SUCCESS,[ + 'first'=>'亲,您的订单以成功签收,快去评价一下吧', + 'keyword1'=>$order['order_id'], + 'keyword2'=>'已收货', + 'keyword3'=>date('Y/m/d H:i',time()), + 'keyword4'=>implode(',',StoreOrderCartInfo::getProductNameList($order['id'])), + 'remark'=>'点击查看订单详情' + ],Url::build('My/order',['uni'=>$order['order_id']],true,true)); + } + + /** + * 删除订单 + * @param $uni + * @param $uid + * @return bool + */ + public static function removeOrder($uni, $uid) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('订单不存在!'); + $order = self::tidyOrder($order); + if($order['_status']['_type'] != 0 && $order['_status']['_type']!= -2 && $order['_status']['_type'] != 4) + return self::setErrorInfo('该订单无法删除!'); + if(false !== self::edit(['is_del'=>1],$order['id'],'id') && + false !==StoreOrderStatus::status($order['id'],'remove_order','删除订单')) + return true; + else + return self::setErrorInfo('订单删除失败!'); + } + + + /** + * //TODO 用户确认收货 + * @param $uni + * @param $uid + */ + public static function takeOrder($uni, $uid) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('订单不存在!'); + $order = self::tidyOrder($order); + if($order['_status']['_type'] != 2) return self::setErrorInfo('订单状态错误!'); + self::beginTrans(); + if(false !== self::edit(['status'=>2],$order['id'],'id') && + false !== StoreOrderStatus::status($order['id'],'user_take_delivery','用户已收货')){ + try{ + HookService::listen('store_product_order_user_take_delivery',$order,$uid,false,StoreProductBehavior::class); + }catch (\Exception $e){ + return self::setErrorInfo($e->getMessage()); + } + self::commitTrans(); + return true; + }else{ + self::rollbackTrans(); + return false; + } + } + + public static function tidyOrder($order,$detail = false) + { + if($detail == true && isset($order['id'])){ + $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid',$order['id'])->column('cart_info','unique')?:[]; + foreach ($cartInfo as $k=>$cart){ + $cartInfo[$k] = json_decode($cart, true); + $cartInfo[$k]['unique'] = $k; + } + $order['cartInfo'] = $cartInfo; + } + + $status = []; + if(!$order['paid'] && $order['pay_type'] == 'offline' && !$order['status'] >= 2){ + $status['_type'] = 9; + $status['_title'] = '线下付款'; + $status['_msg'] = '等待商家处理,请耐心等待'; + $status['_class'] = 'nobuy'; + }else if(!$order['paid']){ + $status['_type'] = 0; + $status['_title'] = '未支付'; + $status['_msg'] = '立即支付订单吧'; + $status['_class'] = 'nobuy'; + }else if($order['refund_status'] == 1){ + $status['_type'] = -1; + $status['_title'] = '申请退款中'; + $status['_msg'] = '商家审核中,请耐心等待'; + $status['_class'] = 'state-sqtk'; + }else if($order['refund_status'] == 2){ + $status['_type'] = -2; + $status['_title'] = '已退款'; + $status['_msg'] = '已为您退款,感谢您的支持'; + $status['_class'] = 'state-sqtk'; + }else if(!$order['status']){ + if($order['pink_id']){ + if(StorePink::where('id',$order['pink_id'])->where('status',1)->count()){ + $status['_type'] = 1; + $status['_title'] = '拼团中'; + $status['_msg'] = '等待其他人参加拼团'; + $status['_class'] = 'state-nfh'; + }else{ + $status['_type'] = 1; + $status['_title'] = '未发货'; + $status['_msg'] = '商家未发货,请耐心等待'; + $status['_class'] = 'state-nfh'; + } + }else{ + $status['_type'] = 1; + $status['_title'] = '未发货'; + $status['_msg'] = '商家未发货,请耐心等待'; + $status['_class'] = 'state-nfh'; + } + }else if($order['status'] == 1){ + $status['_type'] = 2; + $status['_title'] = '待收货'; + $status['_msg'] = date('m月d日H时i分',StoreOrderStatus::getTime($order['id'],'delivery_goods')).'服务商已发货'; + $status['_class'] = 'state-ysh'; + }else if($order['status'] == 2){ + $status['_type'] = 3; + $status['_title'] = '待评价'; + $status['_msg'] = '已收货,快去评价一下吧'; + $status['_class'] = 'state-ypj'; + }else if($order['status'] == 3){ + $status['_type'] = 4; + $status['_title'] = '交易完成'; + $status['_msg'] = '交易完成,感谢您的支持'; + $status['_class'] = 'state-ytk'; + } + if(isset($order['pay_type'])) + $status['_payType'] = isset(self::$payType[$order['pay_type']]) ? self::$payType[$order['pay_type']] : '其他方式'; + if(isset($order['delivery_type'])) + $status['_deliveryType'] = isset(self::$deliveryType[$order['delivery_type']]) ? self::$deliveryType[$order['delivery_type']] : '其他方式'; + $order['_status'] = $status; + return $order; + } + + public static function statusByWhere($status,$model = null) + { + $orderId = StorePink::where('uid',User::getActiveUid())->where('status',1)->column('order_id','id');//获取正在拼团的订单编号 + if($model == null) $model = new self; + if('' === $status) + return $model; + else if($status == 0) + return $model->where('paid',0)->where('status',0)->where('refund_status',0); + else if($status == 1)//待发货 + return $model->where('paid',1)->where('order_id','NOT IN',implode(',',$orderId))->where('status',0)->where('refund_status',0); + else if($status == 2) + return $model->where('paid',1)->where('status',1)->where('refund_status',0); + else if($status == 3) + return $model->where('paid',1)->where('status',2)->where('refund_status',0); + else if($status == 4) + return $model->where('paid',1)->where('status',3)->where('refund_status',0); + else if($status == -1) + return $model->where('paid',1)->where('refund_status',1); + else if($status == -2) + return $model->where('paid',1)->where('refund_status',2); + else if($status == -3) + return $model->where('paid',1)->where('refund_status','IN','1,2'); + else if($status == 11){ + return $model->where('order_id','IN',implode(',',$orderId)); + } + else + return $model; + } + + public static function getUserOrderList($uid,$status = '',$first = 0,$limit = 8) + { + $list = self::statusByWhere($status)->where('is_del',0)->where('uid',$uid) + ->field('seckill_id,bargain_id,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,pink_id,delivery_type') + ->order('add_time DESC')->limit($first,$limit)->select()->toArray(); + foreach ($list as $k=>$order){ + $list[$k] = self::tidyOrder($order,true); + } + + return $list; + } + + public static function searchUserOrder($uid,$order_id) + { + $order = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->field('seckill_id,bargain_id,combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,delivery_type') + ->order('add_time DESC')->find(); + if(!$order) + return false; + else + return self::tidyOrder($order->toArray(),true); + + } + + public static function orderOver($oid) + { + $res = self::edit(['status'=>'3'],$oid,'id'); + if(!$res) exception('评价后置操作失败!'); + StoreOrderStatus::status($oid,'check_order_over','用户评价'); + } + + public static function checkOrderOver($oid) + { + $uniqueList = StoreOrderCartInfo::where('oid',$oid)->column('unique'); + if(StoreProductReply::where('unique','IN',$uniqueList)->where('oid',$oid)->count() == count($uniqueList)){ + HookService::listen('store_product_order_over',$oid,null,false,StoreProductBehavior::class); + self::orderOver($oid); + } + } + + + public static function getOrderStatusNum($uid) + { + $noBuy = self::where('uid',$uid)->where('paid',0)->where('is_del',0)->where('pay_type','<>','offline')->count(); + $noPostageNoPink = self::where('o.uid',$uid)->alias('o')->where('o.paid',1)->where('o.pink_id',0)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->count(); + $noPostageYesPink = self::where('o.uid',$uid)->alias('o')->join('StorePink p','o.pink_id = p.id')->where('p.status',2)->where('o.paid',1)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->count(); + $noPostage = bcadd($noPostageNoPink,$noPostageYesPink); + $noTake = self::where('uid',$uid)->where('paid',1)->where('is_del',0)->where('status',1)->where('pay_type','<>','offline')->count(); + $noReply = self::where('uid',$uid)->where('paid',1)->where('is_del',0)->where('status',2)->count(); + $noPink = self::where('o.uid',$uid)->alias('o')->join('StorePink p','o.pink_id = p.id')->where('p.status',1)->where('o.paid',1)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->count(); + return compact('noBuy','noPostage','noTake','noReply','noPink'); + } + + public static function gainUserIntegral($order) + { + if($order['gain_integral'] > 0){ + $userInfo = User::getUserInfo($order['uid']); + ModelBasic::beginTrans(); + $res1 = false != User::where('uid',$userInfo['uid'])->update(['integral'=>bcadd($userInfo['integral'],$order['gain_integral'],2)]); + $res2 = false != UserBill::income('购买商品赠送积分',$order['uid'],'integral','gain',$order['gain_integral'],$order['id'],$userInfo['integral'],'购买商品赠送'.floatval($order['gain_integral']).'积分'); + $res = $res1 && $res2; + ModelBasic::checkTrans($res); + return $res; + } + return true; + } + + /** + * 获取当前订单中有没有拼团存在 + * @param $pid + * @return int|string + */ + public static function getIsOrderPink($pid = 0 ,$uid = 0){ + return self::where('uid',$uid)->where('pink_id',$pid)->where('refund_status',0)->where('is_del',0)->count(); + } + + /** + * 获取order_id + * @param $pid + * @return mixed + */ + public static function getStoreIdPink($pid = 0 ,$uid = 0){ + return self::where('uid',$uid)->where('pink_id',$pid)->where('is_del',0)->value('order_id'); + } + + /** + * 删除当前用户拼团未支付的订单 + */ + public static function delCombination(){ + self::where('combination','GT',0)->where('paid',0)->where('uid',User::getActiveUid())->delete(); + } + + public static function getUserPrice($uid =0){ + if(!$uid) return 0; + $price = self::where('paid',1)->where('uid',$uid)->where('status',2)->where('refund_status',0)->column('pay_price','id'); + $count = 0; + if($price){ + foreach ($price as $v){ + $count = bcadd($count,$v,2); + } + } + return $count; + } +} \ No newline at end of file diff --git a/application/routine/model/store/StoreOrderCartInfo.php b/application/routine/model/store/StoreOrderCartInfo.php new file mode 100644 index 00000000..48e51427 --- /dev/null +++ b/application/routine/model/store/StoreOrderCartInfo.php @@ -0,0 +1,49 @@ + + * @day: 2017/12/26 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreOrderCartInfo extends ModelBasic +{ + use ModelTrait; + + public static function getCartInfoAttr($value) + { + return json_decode($value,true)?:[]; + } + + public static function setCartInfo($oid,array $cartInfo) + { + $group = []; + foreach ($cartInfo as $cart){ + $group[] = [ + 'oid'=>$oid, + 'cart_id'=>$cart['id'], + 'product_id'=>$cart['productInfo']['id'], + 'cart_info'=>json_encode($cart), + 'unique'=>md5($cart['id'].''.$oid) + ]; + } + return self::setAll($group); + } + + public static function getProductNameList($oid) + { + $cartInfo = self::where('oid',$oid)->select(); + $goodsName = []; + foreach ($cartInfo as $cart){ + $suk = isset($cart['cart_info']['productInfo']['attrInfo']) ? '('.$cart['cart_info']['productInfo']['attrInfo']['suk'].')' : ''; + $goodsName[] = $cart['cart_info']['productInfo']['store_name'].$suk; + } + return $goodsName; + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreOrderStatus.php b/application/routine/model/store/StoreOrderStatus.php new file mode 100644 index 00000000..614e01cf --- /dev/null +++ b/application/routine/model/store/StoreOrderStatus.php @@ -0,0 +1,29 @@ + + * @day: 2017/12/28 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreOrderStatus extends ModelBasic +{ + use ModelTrait; + + public static function status($oid,$change_type,$change_message,$change_time = null) + { + if($change_time == null) $change_time = time(); + return self::set(compact('oid','change_type','change_message','change_time')); + } + + public static function getTime($oid,$change_type) + { + return self::where('oid',$oid)->where('change_type',$change_type)->value('change_time'); + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StorePink.php b/application/routine/model/store/StorePink.php new file mode 100644 index 00000000..5c29efac --- /dev/null +++ b/application/routine/model/store/StorePink.php @@ -0,0 +1,343 @@ + + * @day: 2017/12/18 + */ + +namespace app\routine\model\store; + +use app\routine\model\store\StoreCombination; +use app\routine\model\user\User; +use app\routine\model\user\WechatUser; +use basic\ModelBasic; +use service\WechatTemplateService; +use think\Url; +use traits\ModelTrait; + +/** + * 拼团Model + * Class StorePink + * @package app\wap\model\store + */ +class StorePink extends ModelBasic +{ + use ModelTrait; + + + /** + * 获取一条拼团数据 + * @param $id + * @return mixed + */ + public static function getPinkUserOne($id){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('id',$id); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $list = $model->find(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取拼团的团员 + * @param $id + * @return mixed + */ + public static function getPinkMember($id){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('k_id',$id); + $model = $model->where('is_refund',0); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $model = $model->order('id asc'); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 设置结束时间 + * @param $idAll + * @return $this + */ + public static function setPinkStopTime($idAll){ + $model = new self(); + $model = $model->where('id','IN',$idAll); + return $model->update(['stop_time'=>time(),'status'=>2]); + } + + /** + * 获取正在拼团的数据 团长 + * @return mixed + */ + public static function getPinkAll($cid){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('stop_time','GT',time()); + $model = $model->where('cid',$cid); + $model = $model->where('k_id',0); + $model = $model->where('is_refund',0); + $model = $model->order('add_time desc'); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取还差几人 + */ + public static function getPinkPeople($kid,$people){ + $model = new self(); + $model = $model->where('k_id',$kid)->where('is_refund',0); + $count = bcadd($model->count(),1,0); + return bcsub($people,$count,0); + } + + /** + * 判断订单是否在当前的拼团中 + * @param $orderId + * @param $kid + * @return bool + */ + public static function getOrderIdAndPink($orderId,$kid){ + $model = new self(); + $pink = $model->where('k_id',$kid)->whereOr('id',$kid)->column('order_id'); + if(in_array($orderId,$pink))return true; + else return false; + } + + /** + * 判断用户是否在团内 + * @param $id + * @return int|string + */ + public static function getIsPinkUid($id){ + $uid = User::getActiveUid(); + $pinkT = self::where('id',$id)->where('uid',$uid)->where('is_refund',0)->count(); + $pink = self::whereOr('k_id',$id)->where('uid',$uid)->where('is_refund',0)->count(); + if($pinkT) return true; + if($pink) return true; + else return false; + } + + + /** + * 判断是否发送模板消息 0 未发送 1已发送 + * @param $uidAll + * @return int|string + */ + public static function isTpl($uidAll,$pid){ + if(is_array($uidAll)){ + $countK = self::where('uid','IN',implode(',',$uidAll))->where('is_tpl',0)->where('id',$pid)->count(); + $count = self::where('uid','IN',implode(',',$uidAll))->where('is_tpl',0)->where('k_id',$pid)->count(); + } + else { + $countK = self::where('uid',$uidAll)->where('is_tpl',0)->where('id',$pid)->count(); + $count = self::where('uid',$uidAll)->where('is_tpl',0)->where('k_id',$pid)->count(); + } + return bcadd($countK,$count,0); + } + /** + * 拼团成功提示模板消息 + * @param $uidAll + * @param $pid + */ + public static function orderPinkAfter($uidAll,$pid){ + foreach ($uidAll as $v){ + $openid = WechatUser::uidToOpenid($v); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_SUCCESS,[ + 'first'=>'亲,您的拼团已经完成了', + 'keyword1'=> self::where('id',$pid)->whereOr('k_id',$pid)->where('uid',$v)->value('order_id'), + 'keyword2'=> self::alias('p')->where('p.id',$pid)->whereOr('p.k_id',$pid)->where('p.uid',$v)->join('__STORE_COMBINATION__ c','c.id=p.cid')->value('c.title'), + 'remark'=>'点击查看订单详情' + ],Url::build('My/order_pink_after',['id'=>$pid],true,true)); + } + self::where('uid','IN',implode(',',$uidAll))->where('id',$pid)->whereOr('k_id',$pid)->update(['is_tpl'=>1]); + } + + /** + * 拼团失败发送的模板消息 + * @param $uid + * @param $pid + */ + public static function orderPinkAfterNo($uid,$pid){ + $openid = WechatUser::uidToOpenid($uid); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_LOSE,[ + 'first'=>'亲,您的拼团失败', + 'keyword1'=> self::alias('p')->where('p.id',$pid)->whereOr('p.k_id',$pid)->where('p.uid',$uid)->join('__STORE_COMBINATION__ c','c.id=p.cid')->value('c.title'), + 'keyword2'=> self::where('id',$pid)->whereOr('k_id',$pid)->where('uid',$uid)->value('price'), + 'keyword3'=> self::alias('p')->where('p.id',$pid)->whereOr('p.k_id',$pid)->where('p.uid',$uid)->join('__STORE_ORDER__ c','c.order_id=p.order_id')->value('c.pay_price'), + 'remark'=>'点击查看订单详情' + ],Url::build('My/order_pink_after',['id'=>$pid],true,true)); + self::where('id',$pid)->update(['status'=>3]); + self::where('k_id',$pid)->update(['status'=>3]); + } + + /** + * 获取当前拼团数据返回订单编号 + * @param $id + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getCurrentPink($id){ + $uid = User::getActiveUid();//获取当前登录人的uid + $pink = self::where('id',$id)->where('uid',$uid)->find(); + if(!$pink) $pink = self::where('k_id',$id)->where('uid',$uid)->find(); + return StoreOrder::where('id',$pink['order_id_key'])->value('order_id'); + } + + public static function systemPage($where){ + $model = new self; + $model = $model->alias('p'); + $model = $model->field('p.*,c.title'); + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('p.add_time','>',strtotime($startTime)); + $model = $model->where('p.add_time','<',strtotime($endTime)); + } + if($where['status']) $model = $model->where('p.status',$where['status']); + $model = $model->where('p.k_id',0); + $model = $model->order('p.id desc'); + $model = $model->join('StoreCombination c','c.id=p.cid'); + return self::page($model,function($item)use($where){ + $item['count_people'] = bcadd(self::where('k_id',$item['id'])->count(),1,0); + },$where); + } + + public static function isPinkBe($data,$id){ + $data['id'] = $id; + $count = self::where($data)->count(); + if($count) return $count; + $data['k_id'] = $id; + $count = self::where($data)->count(); + if($count) return $count; + else return 0; + } + public static function isPinkStatus($pinkId){ + if(!$pinkId) return false; + $stopTime = self::where('id',$pinkId)->value('stop_time'); + if($stopTime < time()) return true; //拼团结束 + else return false;//拼团未结束 + } + + /** + * 判断拼团结束 后的状态 + * @param $pinkId + * @return bool + */ + public static function isSetPinkOver($pinkId){ + $people = self::where('id',$pinkId)->value('people'); + $stopTime = self::where('id',$pinkId)->value('stop_time'); + if($stopTime < time()){ + $countNum = self::getPinkPeople($pinkId,$people); + if($countNum) return false;//拼团失败 + else return true;//拼团成功 + }else return true; + } + + /** + * 拼团退款 + * @param $id + * @return bool + */ + public static function setRefundPink($oid){ + $res = true; + $order = StoreOrder::where('id',$oid)->find(); + if($order['pink_id']) $id = $order['pink_id']; + else return $res; + $count = self::where('id',$id)->where('uid',$order['uid'])->find();//正在拼团 团长 + $countY = self::where('k_id',$id)->where('uid',$order['uid'])->find();//正在拼团 团员 + if(!$count && !$countY) return $res; + if($count){//团长 + //判断团内是否还有其他人 如果有 团长为第二个进团的人 + $kCount = self::where('k_id',$id)->order('add_time asc')->find(); + if($kCount){ + $res11 = self::where('k_id',$id)->update(['k_id'=>$kCount['id']]); + $res12 = self::where('id',$kCount['id'])->update(['stop_time'=>$count['add_time']+86400,'k_id'=>0]); + $res1 = $res11 && $res12; + $res2 = self::where('id',$id)->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$kCount['id'],'status'=>3]); + }else{ + $res1 = true; + $res2 = self::where('id',$id)->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$id,'status'=>3]); + } + //修改结束时间为前一秒 团长ID为0 + $res = $res1 && $res2; + }else if($countY){//团员 + $res = self::where('id',$countY['id'])->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$id,'status'=>3]); + } + return $res; + + } + + + + /** + * 拼团人数完成时,判断全部人都是未退款状态 + * @param $pinkIds + * @return bool + */ + public static function setPinkStatus($pinkIds){ + $orderPink = self::where('id','IN',$pinkIds)->where('is_refund',1)->count(); + if(!$orderPink) return true; + else return false; + } + + + /** + * 创建拼团 + * @param $order + * @return mixed + */ + public static function createPink($order){ + $order = StoreOrder::tidyOrder($order,true)->toArray(); + if($order['pink_id']){//拼团存在 + $res = false; + $pink['uid'] = $order['uid'];//用户id + if(self::isPinkBe($pink,$order['pink_id'])) return false; + $pink['order_id'] = $order['order_id'];//订单id 生成 + $pink['order_id_key'] = $order['id'];//订单id 数据库id + $pink['total_num'] = $order['total_num'];//购买个数 + $pink['total_price'] = $order['pay_price'];//总金额 + $pink['k_id'] = $order['pink_id'];//拼团id + foreach ($order['cartInfo'] as $v){ + $pink['cid'] = $v['combination_id'];//拼团产品id + $pink['pid'] = $v['product_id'];//产品id + $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 + $pink['price'] = $v['productInfo']['price'];//单价 + $pink['stop_time'] = 0;//结束时间 + $pink['add_time'] = time();//开团时间 + $res = StorePink::set($pink)->toArray(); + } + if($res) return true; + else return false; + }else{ + $res = false; + $pink['uid'] = $order['uid'];//用户id + $pink['order_id'] = $order['order_id'];//订单id 生成 + $pink['order_id_key'] = $order['id'];//订单id 数据库id + $pink['total_num'] = $order['total_num'];//购买个数 + $pink['total_price'] = $order['pay_price'];//总金额 + $pink['k_id'] = 0;//拼团id + foreach ($order['cartInfo'] as $v){ + $pink['cid'] = $v['combination_id'];//拼团产品id + $pink['pid'] = $v['product_id'];//产品id + $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 + $pink['price'] = $v['productInfo']['price'];//单价 +// $stopTime = StoreCombination::where('id',$v['combination_id'])->value('stop_time');//获取拼团产品结束的时间 +// if($stopTime < time()+86400) $pink['stop_time'] = $stopTime;//结束时间 + $pink['stop_time'] = time()+86400;//结束时间 + $pink['add_time'] = time();//开团时间 + $res1 = self::set($pink)->toArray(); + $res2 = StoreOrder::where('id',$order['id'])->update(['pink_id'=>$res1['id']]); + $res = $res1 && $res2; + } + if($res) return true; + else return false; + } + } +} \ No newline at end of file diff --git a/application/routine/model/store/StoreProduct.php b/application/routine/model/store/StoreProduct.php new file mode 100644 index 00000000..b0034496 --- /dev/null +++ b/application/routine/model/store/StoreProduct.php @@ -0,0 +1,148 @@ + + * @day: 2017/12/12 + */ + +namespace app\routine\model\store; + + +use app\admin\model\store\StoreProductAttrValue; +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreProduct extends ModelBasic +{ + use ModelTrait; + + protected function getSliderImageAttr($value) + { + return json_decode($value,true)?:[]; + } + + public static function getValidProduct($productId,$field = '*') + { + return self::where('is_del',0)->where('is_show',1)->where('id',$productId)->field($field)->find(); + } + + public static function validWhere() + { + return self::where('is_del',0)->where('is_show',1)->where('mer_id',0); + } + + /** + * 新品产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getNewProduct($field = '*',$limit = 0) + { + $model = self::where('is_new',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + /** + * 热卖产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getHotProduct($field = '*',$limit = 0) + { + $model = self::where('is_hot',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + /** + * 热卖产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getHotProductLoading($field = '*',$offset = 0,$limit = 0) + { + $model = self::where('is_hot',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($offset,$limit); + return $model->select(); + } + + /** + * 精品产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getBestProduct($field = '*',$limit = 0) + { + $model = self::where('is_best',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + + /** + * 优惠产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getBenefitProduct($field = '*',$limit = 0) + { + $model = self::where('is_benefit',1) + ->where('is_del',0)->where('mer_id',0)->where('stock','>',0) + ->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function cateIdBySimilarityProduct($cateId,$field='*',$limit = 0) + { + $pid = StoreCategory::cateIdByPid($cateId)?:$cateId; + $cateList = StoreCategory::pidByCategory($pid,'id') ?:[]; + $cid = [$pid]; + foreach ($cateList as $cate){ + $cid[] = $cate['id']; + } + $model = self::where('cate_id','IN',$cid)->where('is_show',1)->where('is_del',0) + ->field($field)->order('sort DESC,id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function isValidProduct($productId) + { + return self::be(['id'=>$productId,'is_del'=>0,'is_show'=>1]) > 0; + } + + public static function getProductStock($productId,$uniqueId = '') + { + return $uniqueId == '' ? + self::where('id',$productId)->value('stock')?:0 + : StoreProductAttr::uniqueByStock($uniqueId); + } + + public static function decProductStock($num,$productId,$unique = '') + { + if($unique){ + $res = false !== StoreProductAttrValue::decProductAttrStock($productId,$unique,$num); + $res = $res && self::where('id',$productId)->setInc('sales',$num); + }else{ + $res = false !== self::where('id',$productId)->dec('stock',$num)->inc('sales',$num)->update(); + } + return $res; + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreProductAttr.php b/application/routine/model/store/StoreProductAttr.php new file mode 100644 index 00000000..fdb5e73b --- /dev/null +++ b/application/routine/model/store/StoreProductAttr.php @@ -0,0 +1,67 @@ + + * @day: 2017/12/13 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use think\Db; +use traits\ModelTrait; + +class StoreProductAttr extends ModelBasic +{ + + use ModelTrait; + + protected function getAttrValuesAttr($value) + { + return explode(',',$value); + } + + public static function storeProductAttrValueDb() + { + return Db::name('StoreProductAttrValue'); + } + + + /** + * 获取商品属性数据 + * @param $productId + * @return array + */ + public static function getProductAttrDetail($productId) + { + $attr = self::where('product_id',$productId)->select()->toArray()?:[]; + $_values = self::storeProductAttrValueDb()->where('product_id',$productId)->select(); + $values = []; + foreach ($_values as $value){ + $values[$value['suk']] = $value; + } + return [$attr,$values]; + } + + public static function uniqueByStock($unique) + { + return self::storeProductAttrValueDb()->where('unique',$unique)->value('stock')?:0; + } + + public static function uniqueByAttrInfo($unique, $field = '*') + { + return self::storeProductAttrValueDb()->field($field)->where('unique',$unique)->find(); + } + + public static function issetProductUnique($productId,$unique) + { + $res = self::be(['product_id'=>$productId]); + if($unique){ + return $res && self::storeProductAttrValueDb()->where('product_id',$productId)->where('unique',$unique)->count() > 0; + }else{ + return !$res; + } + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreProductRelation.php b/application/routine/model/store/StoreProductRelation.php new file mode 100644 index 00000000..08680fe3 --- /dev/null +++ b/application/routine/model/store/StoreProductRelation.php @@ -0,0 +1,108 @@ + + * @day: 2017/11/11 + */ + +namespace app\routine\model\store; + +use behavior\wap\StoreProductBehavior; +use service\HookService; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 点赞收藏model + * Class StoreProductRelation + * @package app\routine\model\store + */ +class StoreProductRelation extends ModelBasic +{ + use ModelTrait; + + /** + * 获取用户收藏所有产品的个数 + * @param $uid + * @return int|string + */ + public static function getUserIdLike($uid = 0){ + $count = self::where('uid',$uid)->where('type','like')->count(); + return $count; + } + + /** + * 添加点赞 收藏 + * @param $productId + * @param $uid + * @param $relationType + * @param string $category + * @return bool + */ + public static function productRelation($productId,$uid,$relationType,$category = 'product') + { + if(!$productId) return self::setErrorInfo('产品不存在!'); + $relationType = strtolower($relationType); + $category = strtolower($category); + $data = ['uid'=>$uid,'product_id'=>$productId,'type'=>$relationType,'category'=>$category]; + if(self::be($data)) return true; + $data['add_time'] = time(); + self::set($data); + HookService::afterListen('store_'.$category.'_'.$relationType,$productId,$uid,false,StoreProductBehavior::class); + return true; + } + + /** + * 批量 添加点赞 收藏 + * @param $productIdS + * @param $uid + * @param $relationType + * @param string $category + * @return bool + */ + public static function productRelationAll($productIdS,$uid,$relationType,$category = 'product'){ + $res = true; + if(is_array($productIdS)){ + self::beginTrans(); + foreach ($productIdS as $productId){ + $res = $res && self::productRelation($productId,$uid,$relationType,$category); + } + self::checkTrans($res); + return $res; + } + return $res; + } + + /** + * 取消 点赞 收藏 + * @param $productId + * @param $uid + * @param $relationType + * @param string $category + * @return bool + */ + public static function unProductRelation($productId,$uid,$relationType,$category = 'product') + { + if(!$productId) return self::setErrorInfo('产品不存在!'); + $relationType = strtolower($relationType); + $category = strtolower($category); + self::where(['uid'=>$uid,'product_id'=>$productId,'type'=>$relationType,'category'=>$category])->delete(); + HookService::afterListen('store_'.$category.'_un_'.$relationType,$productId,$uid,false,StoreProductBehavior::class); + return true; + } + + public static function productRelationNum($productId,$relationType,$category = 'product') + { + $relationType = strtolower($relationType); + $category = strtolower($category); + return self::where('type',$relationType)->where('product_id',$productId)->where('category',$category)->count(); + } + + public static function isProductRelation($product_id,$uid,$relationType,$category = 'product') + { + $type = strtolower($relationType); + $category = strtolower($category); + return self::be(compact('product_id','uid','type','category')); + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreProductReply.php b/application/routine/model/store/StoreProductReply.php new file mode 100644 index 00000000..30091f8b --- /dev/null +++ b/application/routine/model/store/StoreProductReply.php @@ -0,0 +1,97 @@ + + * @day: 2017/12/29 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use service\UtilService; +use traits\ModelTrait; + +class StoreProductReply extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + protected function setPicsAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + protected function getPicsAttr($value) + { + return json_decode($value,true); + } + + public static function reply($group,$type = 'product') + { + $group['reply_type'] = $type; + return self::set($group); + } + + public static function productValidWhere($alias = '') + { + $model = new self; + if($alias){ + $model->alias($alias); + $alias .= '.'; + } + return $model->where("{$alias}is_del",0)->where("{$alias}reply_type",'product'); + } + + public static function getProductReplyList($productId,$order = 'All',$first = 0,$limit = 8) + { + $model = self::productValidWhere('A')->where('A.product_id',$productId) + ->field('A.product_score,A.service_score,A.comment,A.pics,A.add_time,B.nickname,B.avatar,C.cart_info,A.merchant_reply_content') + ->join('__USER__ B','A.uid = B.uid') + ->join('__STORE_ORDER_CART_INFO__ C','A.unique = C.unique'); + $baseOrder = 'A.add_time DESC,A.product_score DESC, A.service_score DESC'; + if($order == 'new') $model->order($baseOrder); + else if($order == 'pic') $model->where('A.pics',['<>',''],['<>','[]'])->order('LENGTH(A.comment) DESC,'.$baseOrder); + else $model->order('LENGTH(A.comment) DESC,'.$baseOrder); + $list = $model->limit($first,$limit)->select()->toArray()?:[]; + foreach ($list as $k=>$reply){ + $list[$k] = self::tidyProductReply($reply); + } + return $list; + } + + public static function tidyProductReply($res) + { + $res['cart_info'] = json_decode($res['cart_info'],true)?:[]; + $res['suk'] = isset($res['cart_info']['productInfo']['attrInfo']) ? $res['cart_info']['productInfo']['attrInfo']['suk'] : ''; + $res['nickname'] = UtilService::anonymity($res['nickname']); + $res['add_time'] = date('Y-m-d H:i',$res['add_time']); + $res['star'] = ceil(($res['product_score'] + $res['service_score'])/2); + $res['comment'] = $res['comment']?:'此用户没有填写评价'; + unset($res['cart_info']); + return $res; + } + + public static function isReply($unique,$reply_type = 'product') + { + return self::be(['unique'=>$unique,'reply_type'=>$reply_type]); + } + + public static function getRecProductReply($productId) + { + $res = self::productValidWhere('A')->where('A.product_id',$productId) + ->field('A.product_score,A.service_score,A.comment,A.pics,A.add_time,B.nickname,B.avatar,C.cart_info') + ->join('__USER__ B','A.uid = B.uid') + ->join('__STORE_ORDER_CART_INFO__ C','A.unique = C.unique') + ->order('LENGTH(A.comment) DESC,A.product_score DESC, A.service_score DESC, A.add_time DESC')->find(); + if(!$res) return null; + return self::tidyProductReply($res->toArray()); + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreSeckill.php b/application/routine/model/store/StoreSeckill.php new file mode 100644 index 00000000..16b53d4b --- /dev/null +++ b/application/routine/model/store/StoreSeckill.php @@ -0,0 +1,99 @@ + + * @day: 2017/12/18 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; + +class StoreSeckill extends ModelBasic +{ + + protected function getImagesAttr($value) + { + return json_decode($value,true)?:[]; + } + + + /** + * 获取所有秒杀产品 + * @param string $field + * @return array + */ + public static function getListAll($offset = 0,$limit = 10,$field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock,sales'){ + $time = time(); + $model = self::where('is_del',0)->where('status',1)->where('stock','>',0)->field($field) + ->where('start_time','<',$time)->where('stop_time','>',$time)->order('sort DESC,add_time DESC'); + $model = $model->limit($offset,$limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + /** + * 获取热门推荐的秒杀产品 + * @param int $limit + * @param string $field + * @return array + */ + public static function getHotList($limit = 0,$field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock') + { + $time = time(); + $model = self::where('is_hot',1)->where('is_del',0)->where('status',1)->where('stock','>',0)->field($field) + ->where('start_time','<',$time)->where('stop_time','>',$time)->order('sort DESC,add_time DESC'); + if($limit) $model->limit($limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取一条秒杀产品 + * @param $id + * @param string $field + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getValidProduct($id,$field = '*') + { + $time = time(); + return self::where('id',$id)->where('is_del',0)->where('status',1)->where('start_time','<',$time)->where('stop_time','>',$time) + ->field($field)->find(); + } + + public static function initFailSeckill() + { + self::where('is_hot',1)->where('is_del',0)->where('status','<>',1)->where('stop_time','<',time())->update(['status'=>'-1']); + } + + public static function idBySimilaritySeckill($id,$limit = 4,$field='*') + { + $time = time(); + $list = []; + $productId = self::where('id',$id)->value('product_id'); + if($productId){ + $list = array_merge($list, self::where('product_id',$productId)->where('id','<>',$id) + ->where('is_del',0)->where('status',1)->where('stock','>',0) + ->field($field)->where('start_time','<',$time)->where('stop_time','>',$time) + ->order('sort DESC,add_time DESC')->limit($limit)->select()->toArray()); + } + $limit = $limit - count($list); + if($limit){ + $list = array_merge($list,self::getHotList($limit,$field)); + } + + return $list; + } + + public static function getProductStock($id){ + $stock = self::where('id',$id)->value('stock'); + if(self::where('id',$id)->where('num','gt',$stock)->count()){//单次购买的产品多于库存 + return $stock; + }else{ + return self::where('id',$id)->value('num'); + } + } + +} \ No newline at end of file diff --git a/application/routine/model/store/StoreService.php b/application/routine/model/store/StoreService.php new file mode 100644 index 00000000..bbcd53ad --- /dev/null +++ b/application/routine/model/store/StoreService.php @@ -0,0 +1,17 @@ + + * @day: 2017/12/23 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreService extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/routine/model/store/StoreServiceLog.php b/application/routine/model/store/StoreServiceLog.php new file mode 100644 index 00000000..f5748035 --- /dev/null +++ b/application/routine/model/store/StoreServiceLog.php @@ -0,0 +1,17 @@ + + * @day: 2017/12/23 + */ + +namespace app\routine\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreServiceLog extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/routine/model/user/RoutineUser.php b/application/routine/model/user/RoutineUser.php new file mode 100644 index 00000000..382b59c2 --- /dev/null +++ b/application/routine/model/user/RoutineUser.php @@ -0,0 +1,65 @@ + + * @day: 2017/12/21 + */ + +namespace app\routine\model\user; + +use basic\ModelBasic; +use traits\ModelTrait; +use app\routine\model\user\User; +use app\routine\model\user\WechatUser; +class RoutineUser extends ModelBasic +{ + use ModelTrait; + + /** + * 小程序创建用户后返回uid + * @param $routineInfo + * @return mixed + */ + public static function routineOauth($routine){ + $routineInfo['nickname'] = $routine['nickName'];//姓名 + $routineInfo['sex'] = $routine['gender'];//性别 + $routineInfo['language'] = $routine['language'];//语言 + $routineInfo['city'] = $routine['city'];//城市 + $routineInfo['province'] = $routine['province'];//省份 + $routineInfo['country'] = $routine['country'];//国家 + $routineInfo['headimgurl'] = $routine['avatarUrl'];//头像 +// $routineInfo[''] = $routine['code'];//临时登录凭证 是获取用户openid和session_key(会话密匙) + $routineInfo['routine_openid'] = $routine['routine_openid'];//openid + $routineInfo['session_key'] = $routine['session_key'];//会话密匙 + $routineInfo['unionid'] = $routine['unionid'];//用户在开放平台的唯一标识符 + $routineInfo['user_type'] = 'routine';//用户类型 + // 判断unionid 存在根据unionid判断 + if($routineInfo['unionid'] != '' && WechatUser::be(['unionid'=>$routineInfo['unionid']])){ + WechatUser::edit($routineInfo,$routineInfo['unionid'],'unionid'); + $uid = WechatUser::where('unionid',$routineInfo['unionid'])->value('uid'); + User::updateWechatUser($routineInfo,$uid); + }else if(WechatUser::be(['routine_openid'=>$routineInfo['routine_openid']])){ //根据小程序openid判断 + WechatUser::edit($routineInfo,$routineInfo['routine_openid'],'routine_openid'); + $uid = WechatUser::where('routine_openid',$routineInfo['routine_openid'])->value('uid'); + User::updateWechatUser($routineInfo,$uid); + }else{ + if(User::isUserSpread($routine['spid'])) $routineInfo['spread_uid'] = $routine['spid'];//用户上级 + else $routineInfo['spread_uid'] = 0; + $routineInfo['add_time'] = time();//用户添加时间 + $routineInfo = WechatUser::set($routineInfo); + $res = User::setRoutineUser($routineInfo); + $uid = $res->uid; + } + return $uid; + } + + /** + * 判断是否是小程序用户 + * @param int $uid + * @return bool|int|string + */ + public static function isRoutineUser($uid = 0){ + if(!$uid) return false; + return WechatUser::where('uid',$uid)->where('user_type','routine')->count(); + } +} \ No newline at end of file diff --git a/application/routine/model/user/User.php b/application/routine/model/user/User.php new file mode 100644 index 00000000..817ef298 --- /dev/null +++ b/application/routine/model/user/User.php @@ -0,0 +1,81 @@ + + * @day: 2017/12/21 + */ + +namespace app\routine\model\user; + +use basic\ModelBasic; +use think\Session; +use traits\ModelTrait; + +/** + * 用户model + * Class User + * @package app\routine\model\user + */ +class User extends ModelBasic +{ + use ModelTrait; + + public static function updateWechatUser($wechatUser,$uid) + { + return self::edit([ + 'nickname'=>$wechatUser['nickname']?:'', + 'avatar'=>$wechatUser['headimgurl']?:'' + ],$uid,'uid'); + } + + + + /** + * 小程序用户添加 + * @param $routineUser + * @param int $spread_uid + * @return object + */ + public static function setRoutineUser($routineUser,$spread_uid = 0){ + return self::set([ + 'account'=>'rt'.$routineUser['uid'].time(), + 'pwd'=>md5(123456), + 'nickname'=>$routineUser['nickname']?:'', + 'avatar'=>$routineUser['headimgurl']?:'', + 'spread_uid'=>$spread_uid, + 'uid'=>$routineUser['uid'], + 'add_time'=>$routineUser['add_time'], + 'user_type'=>$routineUser['user_type'] + ]); + } + + /** + * 获得当前登陆用户UID + * @return int $uid + */ + public static function getActiveUid() + { + $uid = null; + $uid = Session::get('LoginUid'); + if($uid) return $uid; + else return 0; + } + public static function getUserInfo($uid) + { + $userInfo = self::where('uid',$uid)->find(); + if(!$userInfo) exception('读取用户信息失败!'); + return $userInfo->toArray(); + } + + /** + * 判断当前用户是否推广员 + * @param int $uid + * @return bool + */ + public static function isUserSpread($uid = 0){ + if(!$uid) return false; + $isPromoter = self::where('uid',$uid)->value('is_promoter'); + if($isPromoter) return true; + else return false; + } +} \ No newline at end of file diff --git a/application/routine/model/user/UserAddress.php b/application/routine/model/user/UserAddress.php new file mode 100644 index 00000000..39525a57 --- /dev/null +++ b/application/routine/model/user/UserAddress.php @@ -0,0 +1,51 @@ + + * @day: 2017/12/25 + */ + +namespace app\routine\model\user; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class UserAddress extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function setDefaultAddress($id,$uid) + { + self::beginTrans(); + $res1 = self::where('uid',$uid)->update(['is_default'=>0]); + $res2 = self::where('id',$id)->where('uid',$uid)->update(['is_default'=>1]); + $res =$res1 !== false && $res2 !== false; + self::checkTrans($res); + return $res; + } + + public static function userValidAddressWhere($model=null,$prefix = '') + { + if($prefix) $prefix .='.'; + $model = self::getSelfModel($model); + return $model->where("{$prefix}is_del",0); + } + + public static function getUserValidAddressList($uid,$field = '*') + { + return self::userValidAddressWhere()->where('uid',$uid)->order('add_time DESC')->field($field)->select()->toArray()?:[]; + } + + public static function getUserDefaultAddress($uid,$field = '*') + { + return self::userValidAddressWhere()->where('uid',$uid)->where('is_default',1)->field($field)->find(); + } +} \ No newline at end of file diff --git a/application/routine/model/user/UserBill.php b/application/routine/model/user/UserBill.php new file mode 100644 index 00000000..3f036b03 --- /dev/null +++ b/application/routine/model/user/UserBill.php @@ -0,0 +1,37 @@ + + * @day: 2017/12/30 + */ + +namespace app\routine\model\user; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class UserBill extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function income($title,$uid,$category,$type,$number,$link_id = 0,$balance = 0,$mark = '',$status = 1) + { + $pm = 1; + return self::set(compact('title','uid','link_id','category','type','number','balance','mark','status','pm')); + } + + public static function expend($title,$uid,$category,$type,$number,$link_id = 0,$balance = 0,$mark = '',$status = 1) + { + $pm = 0; + return self::set(compact('title','uid','link_id','category','type','number','balance','mark','status','pm')); + } + +} \ No newline at end of file diff --git a/application/routine/model/user/UserExtract.php b/application/routine/model/user/UserExtract.php new file mode 100644 index 00000000..a6ad20b6 --- /dev/null +++ b/application/routine/model/user/UserExtract.php @@ -0,0 +1,113 @@ + + * @day: 2018/3/3 + */ + +namespace app\routine\model\user; + + +use basic\ModelBasic; +use service\SystemConfigService; +use service\WechatTemplateService; +use think\Url; +use traits\ModelTrait; + +class UserExtract extends ModelBasic +{ + use ModelTrait; + + //审核中 + const AUDIT_STATUS = 0; + //未通过 + const FAIL_STATUS = -1; + //已提现 + const SUCCESS_STATUS = 1; + + protected static $extractType = ['alipay','bank']; + + protected static $extractTypeMsg = ['alipay'=>'支付宝','bank'=>'银行卡']; + + protected static $status = array( + -1=>'未通过', + 0 =>'审核中', + 1 =>'已提现' + ); + + public static function userExtract($userInfo,$data){ + if(!in_array($data['extract_type'],self::$extractType)) + return self::setErrorInfo('提现方式不存在'); + if($userInfo['now_money'] < $data['extract_price']) + return self::setErrorInfo('余额不足'); + if(!$data['real_name']) + return self::setErrorInfo('输入姓名有误'); + $extractMinPrice = floatval(SystemConfigService::get('user_extract_min_price'))?:0; + if($data['extract_price'] < $extractMinPrice) + return self::setErrorInfo('提现金额不能小于'.$extractMinPrice); + $balance = bcsub($userInfo['now_money'],$data['extract_price']); + $insertData = [ + 'uid'=>$userInfo['uid'], + 'real_name'=>$data['real_name'], + 'extract_type'=>$data['extract_type'], + 'extract_price'=>($data['extract_price']), + 'add_time'=>time(), + 'balance'=>$balance, + 'status'=>self::AUDIT_STATUS + ]; + if($data['extract_type'] == 'alipay'){ + if(!$data['alipay_code']) return self::setErrorInfo('请输入支付宝账号'); + $insertData['alipay_code'] = $data['alipay_code']; + $mark = '使用支付宝提现'.$insertData['extract_price'].'元'; + }else{ + if(!$data['bank_code']) return self::setErrorInfo('请输入银行卡账号'); + if(!$data['bank_address']) return self::setErrorInfo('请输入开户行信息'); + $insertData['bank_code'] = $data['bank_code']; + $insertData['bank_address'] = $data['bank_address']; + $mark = '使用银联卡'.$insertData['bank_code'].'提现'.$insertData['extract_price'].'元'; + } + self::beginTrans(); + $res1 = self::set($insertData); + if(!$res1) return self::setErrorInfo('提现失败'); + $res2 = User::edit(['now_money'=>$balance],$userInfo['uid'],'uid'); + $res3 = UserBill::expend('余额提现',$userInfo['uid'],'now_money','extract',$data['extract_price'],$res1['id'],$balance,$mark); + $res = $res2 && $res3; + WechatTemplateService::sendTemplate( + WechatUser::uidToOpenid($userInfo['uid']), + WechatTemplateService::USER_BALANCE_CHANGE, + [ + 'first'=>'你好,申请余额提现成功!', + 'keyword1'=>'余额提现', + 'keyword2'=>date('Y-m-d'), + 'keyword3'=>$data['extract_price'], + 'remark'=>'点击查看我的余额明细' + ], + Url::build('wap/My/balance',[],true,true) + ); + if($res) + return true; + else + return self::setErrorInfo('提现失败!'); + } + + /** + * 获得用户最后一次提现信息 + * @param $openid + * @return mixed + */ + public static function userLastInfo($uid) + { + return self::where(compact('uid'))->order('add_time DESC')->find(); + } + + /** + * 获得用户提现总金额 + * @param $uid + * @return mixed + */ + public static function userExtractTotalPrice($uid) + { + return self::where('uid',$uid)->where('status',self::SUCCESS_STATUS)->value('SUM(extract_price)')?:0; + } + +} \ No newline at end of file diff --git a/application/routine/model/user/UserNotice.php b/application/routine/model/user/UserNotice.php new file mode 100644 index 00000000..18b5c22d --- /dev/null +++ b/application/routine/model/user/UserNotice.php @@ -0,0 +1,57 @@ + + * @day: 2017/11/11 + */ + +namespace app\routine\model\user; + +use app\admin\model\user\UserNoticeSee; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 用户通知 model + * Class UserNotice + * @package app\admin\model\user + */ +class UserNotice extends ModelBasic +{ + use ModelTrait; + public static function getNotice($uid){ + $count_notice = self::where('uid','like',"%,$uid,%")->where("is_send",1)->count(); + $see_notice = UserNoticeSee::where("uid",$uid)->count(); + return $count_notice-$see_notice; + } + /** + * @return array + */ + public static function getNoticeList($uid,$page,$limit = 8){ + //定义分页信息 + $count = self::where('uid','like',"%,$uid,%")->count(); + $data["lastpage"] = ceil($count/$limit) <= ($page+1) ? 1 : 0; + + $where['uid'] = array("like","%,$uid,%"); +// $where['uid'] = array(array("like","%,$uid,%"),array("eq",""), 'or'); + $where['is_send'] = 1; + $list = self::where($where)->field('id,user,title,content,add_time')->order("add_time desc")->limit($page*$limit,$limit)->select()->toArray(); + foreach ($list as $key => $value) { + $list[$key]["add_time"] = date("Y-m-d H:i:s",$value["add_time"]); + $list[$key]["is_see"] = UserNoticeSee::where("uid",$uid)->where("nid",$value["id"])->count() > 0 ? 1 : 0; + } + $data["list"] = $list; + return $data; + } + /** + * @return array + */ + public static function seeNotice($uid,$nid){ + if(UserNoticeSee::where("uid",$uid)->where("nid",$nid)->count() <= 0){ + $data["nid"] = $nid; + $data["uid"] = $uid; + $data["add_time"] = time(); + UserNoticeSee::set($data); + } + } +} \ No newline at end of file diff --git a/application/routine/model/user/UserRecharge.php b/application/routine/model/user/UserRecharge.php new file mode 100644 index 00000000..5fd576e6 --- /dev/null +++ b/application/routine/model/user/UserRecharge.php @@ -0,0 +1,60 @@ + + * @day: 2018/01/05 + */ + +namespace app\routine\model\user; + +use app\wap\model\user\WechatUser; +use basic\ModelBasic; +use service\WechatService; +use traits\ModelTrait; + +class UserRecharge extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function addRecharge($uid,$price,$recharge_type = 'weixin',$paid = 0) + { + $order_id = self::getNewOrderId(); + return self::set(compact('order_id','uid','price','recharge_type','paid')); + } + + public static function getNewOrderId() + { + $count = (int) self::where('add_time',['>=',strtotime(date("Y-m-d"))],['<',strtotime(date("Y-m-d",strtotime('+1 day')))])->count(); + return 'wx1'.date('YmdHis',time()).(10000+$count+1); + } + + public static function jsPay($orderInfo) + { + return WechatService::jsPay(WechatUser::uidToOpenid($orderInfo['uid']),$orderInfo['order_id'],$orderInfo['price'],'user_recharge','用户充值'); + } + + /** + * //TODO用户充值成功后 + * @param $orderId + */ + public static function rechargeSuccess($orderId) + { + $order = self::where('order_id',$orderId)->where('paid',0)->find(); + if(!$order) return false; + $user = User::getUserInfo($order['uid']); + self::beginTrans(); + $res1 = self::where('order_id',$order['order_id'])->update(['paid'=>1,'pay_time'=>time()]); + $res2 = UserBill::income('用户余额充值',$order['uid'],'now_money','recharge',$order['price'],$order['id'],$user['now_money'],'成功充值余额'.floatval($order['price']).'元'); + $res3 = User::edit(['now_money'=>bcadd($user['now_money'],$order['price'],2)],$order['uid'],'uid'); + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + } +} \ No newline at end of file diff --git a/application/routine/model/user/UserSign.php b/application/routine/model/user/UserSign.php new file mode 100644 index 00000000..db65eddf --- /dev/null +++ b/application/routine/model/user/UserSign.php @@ -0,0 +1,52 @@ + + * @day: 2018/02/28 + */ + +namespace app\routine\model\user; + + +use basic\ModelBasic; +use service\SystemConfigService; +use think\Model; + +class UserSign +{ + public static function checkUserSigned($uid) + { + return UserBill::be(['uid'=>$uid,'add_time'=>['>',strtotime('today')],'category'=>'integral','type'=>'sign']); + } + + public static function userSignedCount($uid) + { + return self::userSignBillWhere($uid)->count(); + } + + /** + * @param $uid + * @return Model + */ + public static function userSignBillWhere($uid) + { + return UserBill::where(['uid'=>$uid,'category'=>'integral','type'=>'sign']); + } + + public static function sign($userInfo) + { + $uid = $userInfo['uid']; + $min = SystemConfigService::get('sx_sign_min_int')?:0; + $max = SystemConfigService::get('sx_sign_max_int')?:5; + $integral = rand($min,$max); + ModelBasic::beginTrans(); + $res1 = UserBill::income('用户签到',$uid,'integral','sign',$integral,0,$userInfo['integral'],'签到获得'.floatval($integral).'积分'); + $res2 = User::bcInc($uid,'integral',$integral,'uid'); + $res = $res1 && $res2; + ModelBasic::checkTrans($res); + if($res) + return $integral; + else + return false; + } +} \ No newline at end of file diff --git a/application/routine/model/user/WechatUser.php b/application/routine/model/user/WechatUser.php new file mode 100644 index 00000000..2d8596da --- /dev/null +++ b/application/routine/model/user/WechatUser.php @@ -0,0 +1,28 @@ + + * @day: 2017/12/21 + */ + +namespace app\routine\model\user; + +use basic\ModelBasic; +use traits\ModelTrait; + +/** + * 微信用户model + * Class WechatUser + * @package app\routine\model\user + */ +class WechatUser extends ModelBasic +{ + use ModelTrait; + + public static function getOpenId($uid = ''){ + if($uid == '') return false; + return self::where('uid',$uid)->value('openid'); + } + + +} \ No newline at end of file diff --git a/application/routine/view/.keep b/application/routine/view/.keep new file mode 100644 index 00000000..e69de29b diff --git a/application/routine/view/crmebN.zip b/application/routine/view/crmebN.zip new file mode 100644 index 00000000..2a5bafe8 Binary files /dev/null and b/application/routine/view/crmebN.zip differ diff --git a/application/tags.php b/application/tags.php new file mode 100644 index 00000000..eeabe1a5 --- /dev/null +++ b/application/tags.php @@ -0,0 +1,29 @@ + +// +---------------------------------------------------------------------- + +// 应用行为扩展定义文件 +return [ + // 应用初始化 + 'app_init' => [], + // 应用开始 + 'app_begin' => [], + // 模块初始化 + 'module_init' => [], + // 操作开始执行 + 'action_begin' => [], + // 视图内容过滤 + 'view_filter' => [], + // 日志写入 + 'log_write' => [], + // 应用结束 + 'app_end' => [], + +]; diff --git a/application/version.php b/application/version.php new file mode 100644 index 00000000..fca79620 --- /dev/null +++ b/application/version.php @@ -0,0 +1,2 @@ +version=v2.0 +version_code=129 \ No newline at end of file diff --git a/application/wap/common.php b/application/wap/common.php new file mode 100644 index 00000000..4834154a --- /dev/null +++ b/application/wap/common.php @@ -0,0 +1,54 @@ + +// +---------------------------------------------------------------------- + +// 应用公共文件 +if(!function_exists('unThumb')){ + function unThumb($src){ + return str_replace('/s_','/',$src); + } +} +/** +*判断拼团是否结束*/ +function isPinkStatus($pink){ + if(!$pink) return false; + return \app\wap\model\store\StorePink::isSetPinkOver($pink); +} + +/** + * 设置浏览信息 + * @param $uid + * @param int $product_id + * @param int $cate + * @param string $type + * @param string $content + * @param int $min + */ +function setView($uid,$product_id=0,$cate=0,$type='',$product_type = 'product',$content='',$min=20){ + $Db=think\Db::name('store_visit'); + $view=$Db->where(['uid'=>$uid,'product_id'=>$product_id,'product_type'=>$product_type])->field('count,add_time,id')->find(); + if($view && $type!='search'){ + $time=time(); + if(($view['add_time']+$min)<$time){ + $Db->where(['id'=>$view['id']])->update(['count'=>$view['count']+1,'add_time'=>time()]); + } + }else{ + $Db->insert([ + 'add_time'=>time(), + 'count'=>1, + 'product_id'=>$product_id, + 'cate_id'=>$cate, + 'type'=>$type, + 'uid'=>$uid, + 'product_type'=>$product_type, + 'content'=>$content + ]); + } +} diff --git a/application/wap/config.php b/application/wap/config.php new file mode 100644 index 00000000..5689c877 --- /dev/null +++ b/application/wap/config.php @@ -0,0 +1,49 @@ + +// +---------------------------------------------------------------------- + +return [ + 'session' => [ + // SESSION 前缀 + 'prefix' => 'wap', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + ], + 'template' => [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 模板路径 + 'view_path' => APP_PATH .'wap/view/first/', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DS, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', + ], + // 视图输出字符串内容替换 + 'view_replace_str' => [ + '{__PLUG_PATH}'=>'/public/static/plug/', + '{__STATIC_PATH}'=>'/public/static/', + '{__PUBLIC_PATH}'=>'/public/', + '{__WAP_PATH}'=>'/application/wap/view/first/static/wap/' + ], + + 'exception_handle' =>\basic\WapException::class, + 'empty_controller' =>'AuthController' +]; diff --git a/application/wap/controller/Article.php b/application/wap/controller/Article.php new file mode 100644 index 00000000..1f8147fa --- /dev/null +++ b/application/wap/controller/Article.php @@ -0,0 +1,49 @@ +where('is_del',0)->where('id',$cid)->find()->toArray(); + if(!$cateInfo) return $this->failed('文章分类不存在!'); + $title = $cateInfo['title']; + } + $this->assign(compact('title','cid')); + return $this->fetch(); + } + + public function video_school() + { + return $this->fetch(); + } + + public function guide() + { + return $this->fetch(); + } + + public function visit($id = '') + { + $content = ArticleModel::where('status',1)->where('hide',0)->where('id',$id)->order('id desc')->find(); + if(!$content || !$content["status"]) return $this->failed('此文章已经不存在!'); + $content["content"] = Db::name('articleContent')->where('nid',$content["id"])->value('content'); + //增加浏览次数 + $content["visit"] = $content["visit"] + 1; + ArticleModel::where('id',$id)->update(["visit"=>$content["visit"]]); + $this->assign(compact('content')); + return $this->fetch(); + } +} \ No newline at end of file diff --git a/application/wap/controller/AuthApi.php b/application/wap/controller/AuthApi.php new file mode 100644 index 00000000..336888f6 --- /dev/null +++ b/application/wap/controller/AuthApi.php @@ -0,0 +1,743 @@ + + * @day: 2017/12/12 + */ + +namespace app\wap\controller; + + +use Api\Express; +use app\wap\model\store\StoreBargain; +use app\wap\model\store\StoreBargainUser; +use app\wap\model\store\StoreBargainUserHelp; +use app\wap\model\store\StoreCouponIssue; +use app\wap\model\store\StoreCouponIssueUser; +use app\wap\model\store\StoreOrderCartInfo; +use app\wap\model\store\StorePink; +use app\wap\model\store\StoreProductReply; +use app\wap\model\store\StoreService; +use app\wap\model\store\StoreServiceLog; +use app\wap\model\store\StoreCart; +use app\wap\model\store\StoreCategory; +use app\wap\model\store\StoreCouponUser; +use app\wap\model\store\StoreOrder; +use app\wap\model\store\StoreProduct; +use app\wap\model\store\StoreProductAttr; +use app\wap\model\store\StoreProductRelation; +use app\wap\model\user\User; +use app\wap\model\user\UserAddress; +use app\wap\model\user\UserBill; +use app\wap\model\user\UserExtract; +use app\wap\model\user\UserRecharge; +use app\wap\model\user\UserNotice; +use app\wap\model\user\UserSign; +use app\wap\model\user\WechatUser; +use behavior\wap\StoreProductBehavior; +use service\WechatTemplateService; +use service\CacheService; +use service\HookService; +use service\JsonService; +use service\SystemConfigService; +use service\UtilService; +use service\WechatService; +use think\Cache; +use think\Request; +use think\Url; + +class AuthApi extends AuthController +{ + + public function user_sign() + { + $signed = UserSign::checkUserSigned($this->userInfo['uid']); + if($signed) return JsonService::fail('已签到'); + if(false !== $integral = UserSign::sign($this->userInfo)) + return JsonService::successful('签到获得'.floatval($integral).'积分'); + else + return JsonService::fail('签到失败!'); + } + + public function set_cart($productId = '',$cartNum = 1,$uniqueId = '') + { + if(!$productId || !is_numeric($productId)) return $this->failed('参数错误!'); + $res = StoreCart::setCart($this->userInfo['uid'],$productId,$cartNum,$uniqueId,'product'); + if(!$res) + return $this->failed(StoreCart::getErrorInfo('加入购物车失败!')); + else{ + HookService::afterListen('store_product_set_cart_after',$res,$this->userInfo,false,StoreProductBehavior::class); + return $this->successful('ok',['cartId'=>$res->id]); + } + } + + public function now_buy($productId = '',$cartNum = 1,$uniqueId = '',$combinationId = 0,$secKillId=0,$bargainId = 0) + { + if($productId == '') return $this->failed('参数错误!'); + if($bargainId && StoreBargainUserHelp::getSurplusPrice($bargainId,$this->userInfo['uid'])) return JsonService::fail('请先砍价'); + $res = StoreCart::setCart($this->userInfo['uid'],$productId,$cartNum,$uniqueId,'product',1,$combinationId,$secKillId,$bargainId); + if(!$res) + return $this->failed(StoreCart::getErrorInfo('订单生成失败!')); + else { + return $this->successful('ok', ['cartId' => $res->id]); + } + } + + public function like_product($productId = '',$category = 'product') + { + if(!$productId || !is_numeric($productId)) return $this->failed('参数错误!'); + $res = StoreProductRelation::productRelation($productId,$this->userInfo['uid'],'like',$category); + if(!$res) + return $this->failed(StoreProductRelation::getErrorInfo('点赞失败!')); + else + return $this->successful(); + } + + public function unlike_product($productId = '',$category = 'product') + { + + if(!$productId || !is_numeric($productId)) return $this->failed('参数错误!'); + $res = StoreProductRelation::unProductRelation($productId,$this->userInfo['uid'],'like',$category); + if(!$res) + return $this->failed(StoreProductRelation::getErrorInfo('取消点赞失败!')); + else + return $this->successful(); + } + + public function collect_product($productId,$category = 'product') + { + if(!$productId || !is_numeric($productId)) return $this->failed('参数错误!'); + $res = StoreProductRelation::productRelation($productId,$this->userInfo['uid'],'collect',$category); + if(!$res) + return $this->failed(StoreProductRelation::getErrorInfo('收藏失败!')); + else + return $this->successful(); + } + + public function uncollect_product($productId,$category = 'product') + { + if(!$productId || !is_numeric($productId)) return $this->failed('参数错误!'); + $res = StoreProductRelation::unProductRelation($productId,$this->userInfo['uid'],'collect',$category); + if(!$res) + return $this->failed(StoreProductRelation::getErrorInfo('取消收藏失败!')); + else + return $this->successful(); + } + + public function get_cart_num() + { + return JsonService::successful('ok',StoreCart::getUserCartNum($this->userInfo['uid'],'product')); + } + + public function get_cart_list() + { + return JsonService::successful('ok',StoreCart::getUserProductCartList($this->userInfo['uid'])); + } + + public function change_cart_num($cartId = '',$cartNum = '') + { + if(!$cartId || !$cartNum || !is_numeric($cartId) || !is_numeric($cartNum)) return JsonService::fail('参数错误!'); + StoreCart::changeUserCartNum($cartId,$cartNum,$this->userInfo['uid']); + return JsonService::successful(); + } + + public function remove_cart($ids='') + { + if(!$ids) return JsonService::fail('参数错误!'); + StoreCart::removeUserCart($this->userInfo['uid'],$ids); + return JsonService::successful(); + } + + + public function get_use_coupon() + { + return JsonService::successful('',StoreCouponUser::getUserValidCoupon($this->userInfo['uid'])); + } + + public function get_user_collect_product($first = 0,$limit = 8) + { + $list = StoreProductRelation::where('A.uid',$this->userInfo['uid']) + ->field('B.id pid,B.store_name,B.price,B.ot_price,B.sales,B.image,B.is_del,B.is_show')->alias('A') + ->where('A.type','collect')->where('A.category','product') + ->order('A.add_time DESC')->join('__STORE_PRODUCT__ B','A.product_id = B.id') + ->limit($first,$limit)->select()->toArray(); + foreach ($list as $k=>$product){ + if($product['pid']){ + $list[$k]['is_fail'] = $product['is_del'] && $product['is_show']; + }else{ + unset($list[$k]); + } + } + return JsonService::successful($list); + } + + public function remove_user_collect_product($productId = '') + { + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误!'); + StoreProductRelation::unProductRelation($productId,$this->userInfo['uid'],'collect','product'); + return JsonService::successful(); + } + + public function set_user_default_address($addressId = '') + { + if(!$addressId || !is_numeric($addressId)) return JsonService::fail('参数错误!'); + if(!UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])) + return JsonService::fail('地址不存在!'); + $res = UserAddress::setDefaultAddress($addressId,$this->userInfo['uid']); + if(!$res) + return JsonService::fail('地址不存在!'); + else + return JsonService::successful(); + } + + public function edit_user_address() + { + $request = Request::instance(); + if(!$request->isPost()) return JsonService::fail('参数错误!'); + $addressInfo = UtilService::postMore([ + ['address',[]], + ['is_default',false], + ['real_name',''], + ['post_code',''], + ['phone',''], + ['detail',''], + ['id',0] + ],$request); + $addressInfo['province'] = $addressInfo['address']['province']; + $addressInfo['city'] = $addressInfo['address']['city']; + $addressInfo['district'] = $addressInfo['address']['district']; + $addressInfo['is_default'] = $addressInfo['is_default'] == true ? 1 : 0; + $addressInfo['uid'] = $this->userInfo['uid']; + unset($addressInfo['address']); + + if($addressInfo['id'] && UserAddress::be(['id'=>$addressInfo['id'],'uid'=>$this->userInfo['uid'],'is_del'=>0])){ + $id = $addressInfo['id']; + unset($addressInfo['id']); + if(UserAddress::edit($addressInfo,$id,'id')){ + if($addressInfo['is_default']) + UserAddress::setDefaultAddress($id,$this->userInfo['uid']); + return JsonService::successful(); + }else + return JsonService::fail('编辑收货地址失败!'); + }else{ + if($address = UserAddress::set($addressInfo)){ + if($addressInfo['is_default']) + UserAddress::setDefaultAddress($address->id,$this->userInfo['uid']); + return JsonService::successful(); + }else + return JsonService::fail('添加收货地址失败!'); + } + + + } + + public function user_default_address() + { + $defaultAddress = UserAddress::getUserDefaultAddress($this->userInfo['uid'],'id,real_name,phone,province,city,district,detail,is_default'); + if($defaultAddress) + return JsonService::successful('ok',$defaultAddress); + else + return JsonService::successful('empty',[]); + } + + public function remove_user_address($addressId = '') + { + if(!$addressId || !is_numeric($addressId)) return JsonService::fail('参数错误!'); + if(!UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])) + return JsonService::fail('地址不存在!'); + if(UserAddress::edit(['is_del'=>'1'],$addressId,'id')) + return JsonService::successful(); + else + return JsonService::fail('删除地址失败!'); + } + + /** + * 创建订单 + * @param string $key + * @return \think\response\Json + */ + public function create_order($key = '') + { + if(!$key) return JsonService::fail('参数错误!'); + if(StoreOrder::be(['order_id|unique'=>$key,'uid'=>$this->userInfo['uid'],'is_del'=>0])) + return JsonService::status('extend_order','订单已生成',['orderId'=>$key,'key'=>$key]); + list($addressId,$couponId,$payType,$useIntegral,$mark,$combinationId,$pinkId,$seckill_id,$bargainId) = UtilService::postMore([ + 'addressId','couponId','payType','useIntegral','mark',['combinationId',0],['pinkId',0],['seckill_id',0],['bargainId',0] + ],Request::instance(),true); + $payType = strtolower($payType); + if($bargainId) StoreBargainUser::setBargainUserStatus($bargainId,$this->userInfo['uid']);//修改砍价状态 + if($pinkId) if(StorePink::getIsPinkUid($pinkId)) return JsonService::status('ORDER_EXIST','订单生成失败,你已经在该团内不能再参加了',['orderId'=>StoreOrder::getStoreIdPink($pinkId)]); + if($pinkId) if(StoreOrder::getIsOrderPink($pinkId)) return JsonService::status('ORDER_EXIST','订单生成失败,你已经参加该团了,请先支付订单',['orderId'=>StoreOrder::getStoreIdPink($pinkId)]); + $order = StoreOrder::cacheKeyCreateOrder($this->userInfo['uid'],$key,$addressId,$payType,$useIntegral,$couponId,$mark,$combinationId,$pinkId,$seckill_id,$bargainId); + $orderId = $order['order_id']; + $info = compact('orderId','key'); + if($orderId){ + if($payType == 'weixin'){ + $orderInfo = StoreOrder::where('order_id',$orderId)->find(); + if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!'); + if($orderInfo['paid']) exception('支付已支付!'); + if(bcsub((float)$orderInfo['pay_price'],0,2) <= 0){ + if(StoreOrder::jsPayPrice($orderId,$this->userInfo['uid'])) + return JsonService::status('success','微信支付成功',$info); + else + return JsonService::status('pay_error',StoreOrder::getErrorInfo()); + }else{ + try{ + $jsConfig = StoreOrder::jsPay($orderId); + }catch (\Exception $e){ + return JsonService::status('pay_error',$e->getMessage(),$info); + } + $info['jsConfig'] = $jsConfig; + return JsonService::status('wechat_pay','订单创建成功',$info); + } + }else if($payType == 'yue'){ + if(StoreOrder::yuePay($orderId,$this->userInfo['uid'])) + return JsonService::status('success','余额支付成功',$info); + else + return JsonService::status('pay_error',StoreOrder::getErrorInfo()); + }else if($payType == 'offline'){ + StoreOrder::createOrderTemplate($order); + return JsonService::status('success','订单创建成功',$info); + } + }else{ + return JsonService::fail(StoreOrder::getErrorInfo('订单生成失败!')); + } + } + + public function get_user_order_list($type = '',$first = 0, $limit = 8,$search = '') + { +// StoreOrder::delCombination();//删除拼团未支付订单 + if($search){ + $order = StoreOrder::searchUserOrder($this->userInfo['uid'],$search)?:[]; + $list = $order == false ? [] : [$order]; + }else{ + if($type == 'first') $type = ''; + $list = StoreOrder::getUserOrderList($this->userInfo['uid'],$type,$first,$limit); + } + foreach ($list as $k=>$order){ + $list[$k] = StoreOrder::tidyOrder($order,true); + if($list[$k]['_status']['_type'] == 3){ + foreach ($order['cartInfo']?:[] as $key=>$product){ + $list[$k]['cartInfo'][$key]['is_reply'] = StoreProductReply::isReply($product['unique'],'product'); + } + } + } + return JsonService::successful($list); + } + + public function user_remove_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + $res = StoreOrder::removeOrder($uni,$this->userInfo['uid']); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + /** + * 支付订单 + * @param string $uni + * @return \think\response\Json + */ + public function pay_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + $order= StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni); + if(!$order) return JsonService::fail('订单不存在!'); + if($order['paid']) return JsonService::fail('该订单已支付!'); + if($order['pink_id']) if(StorePink::isPinkStatus($order['pink_id'])) return JsonService::fail('该订单已失效!'); + if($order['pay_type'] == 'weixin'){ + try{ + $jsConfig = StoreOrder::jsPay($order); + }catch (\Exception $e){ + return JsonService::fail($e->getMessage()); + } + return JsonService::status('wechat_pay',['jsConfig'=>$jsConfig,'order_id'=>$order['order_id']]); + }else if($order['pay_type'] == 'yue'){ + if($res = StoreOrder::yuePay($order['order_id'],$this->userInfo['uid'])) + return JsonService::successful('余额支付成功'); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + }else if($order['pay_type'] == 'offline'){ + StoreOrder::createOrderTemplate($order); + return JsonService::successful('订单创建成功'); + } + } + + public function apply_order_refund($uni = '',$text = '') + { + if(!$uni || $text == '') return JsonService::fail('参数错误!'); + $res = StoreOrder::orderApplyRefund($uni,$this->userInfo['uid'],$text); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + public function user_take_order($uni = '') + { + if(!$uni) return JsonService::fail('参数错误!'); + + $res = StoreOrder::takeOrder($uni,$this->userInfo['uid']); + if($res) + return JsonService::successful(); + else + return JsonService::fail(StoreOrder::getErrorInfo()); + } + + public function user_wechat_recharge($price = 0) + { + if(!$price || $price <=0) return JsonService::fail('参数错误'); + $storeMinRecharge = SystemConfigService::get('store_user_min_recharge'); + if($price < $storeMinRecharge) return JsonService::fail('充值金额不能低于'.$storeMinRecharge); + $rechargeOrder = UserRecharge::addRecharge($this->userInfo['uid'],$price); + if(!$rechargeOrder) return JsonService::fail('充值订单生成失败!'); + try{ + return JsonService::successful(UserRecharge::jsPay($rechargeOrder)); + }catch (\Exception $e){ + return JsonService::fail($e->getMessage()); + } + } + + public function user_balance_list($first = 0,$limit = 8) + { + $list = UserBill::where('uid',$this->userInfo['uid'])->where('category','now_money') + ->field('mark,pm,number,add_time') + ->where('status',1)->order('add_time DESC')->limit($first,$limit)->select()->toArray(); + foreach ($list as &$v){ + $v['add_time'] = date('Y/m/d H:i',$v['add_time']); + } + return JsonService::successful($list); + } + + public function user_integral_list($first = 0,$limit = 8) + { + $list = UserBill::where('uid',$this->userInfo['uid'])->where('category','integral') + ->field('mark,pm,number,add_time') + ->where('status',1)->order('add_time DESC')->limit($first,$limit)->select()->toArray(); + foreach ($list as &$v){ + $v['add_time'] = date('Y/m/d H:i',$v['add_time']); + $v['number'] = floatval($v['number']); + } + return JsonService::successful($list); + + } + + public function user_comment_product($unique = '') + { + if(!$unique) return JsonService::fail('参数错误!'); + $cartInfo = StoreOrderCartInfo::where('unique',$unique)->find(); + $uid = $this->userInfo['uid']; + if(!$cartInfo || $uid != $cartInfo['cart_info']['uid']) return JsonService::fail('评价产品不存在!'); + if(StoreProductReply::be(['oid'=>$cartInfo['oid'],'unique'=>$unique])) + return JsonService::fail('该产品已评价!'); + $group = UtilService::postMore([ + ['comment',''],['pics',[]],['product_score',5],['service_score',5] + ],Request::instance()); + $group['comment'] = htmlspecialchars(trim($group['comment'])); + if(sensitive_words_filter($group['comment'])) return JsonService::fail('请注意您的用词,谢谢!!'); + if($group['product_score'] < 1) return JsonService::fail('请为产品评分'); + else if($group['service_score'] < 1) return JsonService::fail('请为商家服务评分'); + $group = array_merge($group,[ + 'uid'=>$uid, + 'oid'=>$cartInfo['oid'], + 'unique'=>$unique, + 'product_id'=>$cartInfo['product_id'], + 'reply_type'=>'product' + ]); + StoreProductReply::beginTrans(); + $res = StoreProductReply::reply($group,'product'); + if(!$res) { + StoreProductReply::rollbackTrans(); + return JsonService::fail('评价失败!'); + } + try{ + HookService::listen('store_product_order_reply',$group,$cartInfo,false,StoreProductBehavior::class); + }catch (\Exception $e){ + StoreProductReply::rollbackTrans(); + return JsonService::fail($e->getMessage()); + } + StoreProductReply::commitTrans(); + return JsonService::successful(); + } + + public function get_product_category() + { + $parentCategory = StoreCategory::pidByCategory(0,'id,cate_name')->toArray(); + foreach ($parentCategory as $k=>$category){ + $category['child'] = StoreCategory::pidByCategory($category['id'],'id,cate_name')->toArray(); + $parentCategory[$k] = $category; + } + return JsonService::successful($parentCategory); + } + + public function get_spread_list($first = 0,$limit = 20) + { + $list = User::where('spread_uid',$this->userInfo['uid'])->field('uid,nickname,avatar,add_time')->limit($first,$limit)->order('add_time DESC')->select()->toArray(); + foreach ($list as $k=>$user){ + $list[$k]['add_time'] = date('Y/m/d',$user['add_time']); + } + return JsonService::successful($list); + } + + public function get_product_list($keyword = '', $cId = 0,$sId = 0,$priceOrder = '', $salesOrder = '', $news = 0, $first = 0, $limit = 8) + { + if(!empty($keyword)) $keyword = base64_decode(htmlspecialchars($keyword)); + $model = StoreProduct::validWhere(); + if($cId && $sId){ + $model->where('cate_id',$sId); + }elseif($cId){ + $sids = StoreCategory::pidBySidList($cId)?:[]; + $sids[] = $cId; + $model->where('cate_id','IN',$sids); + } + if(!empty($keyword)) $model->where('keyword|store_name','LIKE',"%$keyword%"); + if($news) $model->where('is_new',1); + $baseOrder = ''; + if($priceOrder) $baseOrder = $priceOrder == 'desc' ? 'price DESC' : 'price ASC'; + if($salesOrder) $baseOrder = $salesOrder == 'desc' ? 'sales DESC' : 'sales ASC'; + if($baseOrder) $baseOrder .= ', '; + $model->order($baseOrder.'sort DESC, add_time DESC'); + $list = $model->limit($first,$limit)->field('id,store_name,image,sales,price,stock')->select()->toArray(); + if($list) setView($this->uid,0,$sId,'search','product',$keyword); + return JsonService::successful($list); + } + + public function user_get_coupon($couponId = '') + { + if(!$couponId || !is_numeric($couponId)) return JsonService::fail('参数错误!'); + if(StoreCouponIssue::issueUserCoupon($couponId,$this->userInfo['uid'])){ + return JsonService::successful('领取成功'); + }else{ + return JsonService::fail(StoreCouponIssue::getErrorInfo('领取失败!')); + } + } + + public function product_reply_list($productId = '',$first = 0,$limit = 8, $filter = 'all') + { + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误!'); + $list = StoreProductReply::getProductReplyList($productId,$filter,$first,$limit); + return JsonService::successful($list); + } + + public function product_attr_detail($productId = '') + { + if(!$productId || !is_numeric($productId)) return JsonService::fail('参数错误!'); + list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($productId); + return JsonService::successful(compact('productAttr','productValue')); + + } + + public function user_address_list() + { + $list = UserAddress::getUserValidAddressList($this->userInfo['uid'],'id,real_name,phone,province,city,district,detail,is_default'); + return JsonService::successful($list); + } + + public function get_notice_list($page = 0, $limit = 8) + { + $list = UserNotice::getNoticeList($this->userInfo['uid'],$page,$limit); + return JsonService::successful($list); + } + public function see_notice($nid){ + UserNotice::seeNotice($this->userInfo['uid'],$nid); + return JsonService::successful(); + } + + public function refresh_msn(Request $request) + { + $params = $request->post(); + $remind_where = "mer_id = ".$params["mer_id"]." AND uid = ".$params["uid"]." AND to_uid = ".$params["to_uid"]." AND type = 0 AND remind = 0"; + $remind_list = StoreServiceLog::where($remind_where)->order("add_time asc")->select(); + foreach ($remind_list as $key => $value) { + if(time() - $value["add_time"] > 3){ + StoreServiceLog::edit(array("remind"=>1),$value["id"]); + $now_user = StoreService::field("uid,nickname")->where(array("uid"=>$params["uid"]))->find(); + if(!$now_user)$now_user = User::field("uid,nickname")->where(array("uid"=>$params["uid"]))->find(); + if($params["to_uid"]) { + $head = '您有新的消息,请注意查收!'; + WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($params["to_uid"]),WechatTemplateService::SERVICE_NOTICE,[ + 'first'=>$head, + 'keyword1'=>$now_user["nickname"], + 'keyword2'=>"客服提醒", + 'keyword3'=> preg_replace('//','[图片]',$value["msn"]), + 'keyword4'=>date('Y-m-d H:i:s',time()), + 'remark'=>'点击立即查看消息' + ],Url::build('service/service_ing',['to_uid'=>$now_user["uid"],'mer_id'=>$params["mer_id"]],true,true)); + } + } + } + $where = "mer_id = ".$params["mer_id"]." AND uid = ".$params["to_uid"]." AND to_uid = ".$params["uid"]." AND type = 0"; + $list = StoreServiceLog::where($where)->order("add_time asc")->select()->toArray(); + $ids = []; + foreach ($list as $key => $value) { + //设置发送人与接收人区别 + if($value["uid"] == $params["uid"]) + $list[$key]['my'] = "my"; + else + $list[$key]['my'] = "to"; + + array_push($ids,$value["id"]); + } + + //设置这些消息为已读 + StoreServiceLog::where(array("id"=>array("in",$ids)))->update(array("type"=>1,"remind"=>1)); + return JsonService::successful($list); + } + + public function add_msn(Request $request){ + $params = $request->post(); + if($params["type"] == "html") + $data["msn"] = htmlspecialchars_decode($params["msn"]); + else + $data["msn"] = $params["msn"]; + $data["uid"] = $params["uid"]; + $data["to_uid"] = $params["to_uid"]; + $data["mer_id"] = $params["mer_id"] > 0 ? $params["mer_id"] : 0; + $data["add_time"] = time(); + StoreServiceLog::set($data); + return JsonService::successful(); + } + + public function get_msn(Request $request){ + $params = $request->post(); + $size = 10; + $page = $params["page"]>=0 ? $params["page"] : 1; + $where = "(mer_id = ".$params["mer_id"]." AND uid = ".$params["uid"]." AND to_uid = ".$params["to_uid"].") OR (mer_id = ".$params["mer_id"]." AND uid = ".$params["to_uid"]." AND to_uid = ".$params["uid"].")"; + $list = StoreServiceLog::where($where)->limit(($page-1)*$size,$size)->order("add_time desc")->select()->toArray(); + foreach ($list as $key => $value) { + //设置发送人与接收人区别 + if($value["uid"] == $params["uid"]) + $list[$key]['my'] = "my"; + else + $list[$key]['my'] = "to"; + + //设置这些消息为已读 + if($value["uid"] == $params["to_uid"] && $value["to_uid"] == $params["uid"])StoreServiceLog::edit(array("type"=>1,"remind"=>1),$value["id"]); + } + $list=array_reverse($list); + return JsonService::successful($list); + } + + public function refresh_msn_new(Request $request){ + $params = $request->post(); + $now_user = User::getUserInfo($this->userInfo['uid']); + if($params["last_time"] > 0) + $where = "(uid = ".$now_user["uid"]." OR to_uid = ".$now_user["uid"].") AND add_time>".$params["last_time"]; + else + $where = "uid = ".$now_user["uid"]." OR to_uid = ".$now_user["uid"]; + + + $msn_list = StoreServiceLog::where($where)->order("add_time desc")->select()->toArray(); + $info_array = $list = []; + foreach ($msn_list as $key => $value){ + $to_uid = $value["uid"] == $now_user["uid"] ? $value["to_uid"] : $value["uid"]; + if(!in_array(["to_uid"=>$to_uid,"mer_id"=>$value["mer_id"]],$info_array)){ + $info_array[count($info_array)] = ["to_uid"=>$to_uid,"mer_id"=>$value["mer_id"]]; + + $to_user = StoreService::field("uid,nickname,avatar")->where(array("uid"=>$to_uid))->find(); + if(!$to_user)$to_user = User::field("uid,nickname,avatar")->where(array("uid"=>$to_uid))->find(); + $to_user["mer_id"] = $value["mer_id"]; + $to_user["mer_name"] = ''; + $value["to_info"] = $to_user; + $value["count"] = StoreServiceLog::where(array("mer_id"=>$value["mer_id"],"uid"=>$to_uid,"to_uid"=>$now_user["uid"],"type"=>0))->count(); + $list[count($list)] = $value; + } + } + return JsonService::successful($list); + } + + public function get_user_brokerage_list($uid, $first = 0,$limit = 8) + { + if(!$uid) + return $this->failed('用户不存在'); + $list = UserBill::field('A.mark,A.add_time,A.number,A.pm')->alias('A')->limit($first,$limit) + ->where('A.category','now_money')->where('A.type','brokerage') + ->where('A.uid',$this->userInfo['uid']) + ->join('__STORE_ORDER__ B','A.link_id = B.id AND B.uid = '.$uid)->select()->toArray(); + return JsonService::successful($list); + } + + public function user_extract() + { + if(UserExtract::userExtract($this->userInfo,UtilService::postMore([ + ['type','','','extract_type'],'real_name','alipay_code','bank_code','bank_address',['price','','','extract_price'] + ]))) + return JsonService::successful('申请提现成功!'); + else + return JsonService::fail(Extract::getErrorInfo()); + } + + public function get_issue_coupon_list($limit = 2) + { + $list = StoreCouponIssue::validWhere('A')->join('__STORE_COUPON__ B','A.cid = B.id') + ->field('A.*,B.coupon_price,B.use_min_price')->order('B.sort DESC,A.id DESC')->limit($limit)->select()->toArray()?:[]; + $list_coupon=[]; + foreach ($list as $k=>&$v){ + if(!($v['is_use']=StoreCouponIssueUser::be(['uid'=>$this->userInfo['uid'],'issue_coupon_id'=>$v['id']])) && $v['total_count'] > 0 && $v['remain_count'] >0){ + array_push($list_coupon,$v); + } + } + return JsonService::successful($list_coupon); + } + + public function clear_cache($uni = '') + { + if($uni)CacheService::clear(); + } + + /** + * 获取今天正在拼团的人的头像和名称 + * @return \think\response\Json + */ + public function get_pink_second_one(){ + $addTime = mt_rand(time()-30000,time()); + $storePink = StorePink::where('p.add_time','GT',$addTime)->alias('p')->where('p.status',1)->join('User u','u.uid=p.uid')->field('u.nickname,u.avatar as src')->find(); + return JsonService::successful($storePink); + } + + public function order_details($uni = ''){ + + if(!$uni) return JsonService::fail('参数错误!'); + $order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni); + if(!$order) return JsonService::fail('订单不存在!'); + $order = StoreOrder::tidyOrder($order,true); + $res = array(); + foreach ($order['cartInfo'] as $v) { + if($v['combination_id']) return JsonService::fail('拼团产品不能再来一单,请在拼团产品内自行下单!'); + else $res[] = StoreCart::setCart($this->userInfo['uid'], $v['product_id'], $v['cart_num'], isset($v['productInfo']['attrInfo']['unique']) ? $v['productInfo']['attrInfo']['unique'] : '', 'product', 0, 0); + } + $cateId = []; + foreach ($res as $v){ + if(!$v) return JsonService::fail('再来一单失败,请重新下单!'); + $cateId[] = $v['id']; + } + return JsonService::successful('ok',implode(',',$cateId)); + + } + + + /** + * 帮好友砍价 + * @param int $bargainId + * @param int $bargainUserId + * @return \think\response\Json + */ + public function set_bargain_help(){ + list($bargainId,$bargainUserId) = UtilService::postMore([ + 'bargainId','bargainUserId'],Request::instance(),true); + if(!$bargainId || !$bargainUserId) return JsonService::fail('参数错误'); + $res = StoreBargainUserHelp::setBargainUserHelp($bargainId,$bargainUserId,$this->userInfo['uid']); + if($res) { + if(!StoreBargainUserHelp::getSurplusPrice($bargainId,$bargainUserId)){//砍价成功,发模板消息 + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $bargain = StoreBargain::where('id',$bargainId)->find()->toArray(); + $bargainUser = StoreBargainUser::where('id',$bargainUserTableId)->find()->toArray(); + } + return JsonService::status('SUCCESS','砍价成功'); + } + else return JsonService::status('ERROR','砍价失败,请稍后再帮助朋友砍价'); + } + +} \ No newline at end of file diff --git a/application/wap/controller/AuthController.php b/application/wap/controller/AuthController.php new file mode 100644 index 00000000..b6b41b5b --- /dev/null +++ b/application/wap/controller/AuthController.php @@ -0,0 +1,51 @@ + + * @day: 2017/12/11 + */ + +namespace app\wap\controller; + + +use app\wap\model\store\StoreOrder; +use app\wap\model\user\User; +use app\wap\model\user\WechatUser; +use basic\WapBasic; +use service\UtilService; +use think\Cookie; +use think\Session; +use think\Url; + +class AuthController extends WapBasic +{ + /** + * 用户ID + * @var int + */ + protected $uid; + + /** + * 用户信息 + * @var + */ + protected $userInfo; + + protected function _initialize() + { + parent::_initialize(); + try{ + $uid = User::getActiveUid(); + }catch (\Exception $e){ + Cookie::set('is_login',0); + $url=$this->request->url(true); + return $this->redirect(Url::build('Login/index',['ref'=>base64_encode(htmlspecialchars($url))])); + } + $this->userInfo = User::getUserInfo($uid); + if(!$this->userInfo || !isset($this->userInfo['uid'])) return $this->failed('读取用户信息失败!'); + if(!$this->userInfo['status']) return $this->failed('已被禁止登陆!'); + $this->uid = $this->userInfo['uid']; + $this->assign('userInfo',$this->userInfo); + } + +} \ No newline at end of file diff --git a/application/wap/controller/Index.php b/application/wap/controller/Index.php new file mode 100644 index 00000000..bc7c9977 --- /dev/null +++ b/application/wap/controller/Index.php @@ -0,0 +1,93 @@ + + * @day: 2017/12/11 + */ + +namespace app\wap\controller; + +use app\wap\model\store\StoreSeckill; +use app\wap\model\store\StoreCategory; +use app\wap\model\store\StoreOrder; +use app\wap\model\store\StorePink; +use app\wap\model\store\StoreProduct; +use app\wap\model\user\User; +use app\wap\model\user\UserNotice; +use app\wap\model\user\WechatUser; +use basic\WapBasic; +use service\GroupDataService; +use service\QrcodeService; +use service\SystemConfigService; +use service\WechatService; +use think\Db; +use think\Url; + +class Index extends AuthController +//class Index extends WapBasic +{ + public function index() + { + try{ + $uid = User::getActiveUid(); + $notice = UserNotice::getNotice($uid); + }catch (\Exception $e){ + $notice = 0; + } + $storePink = StorePink::where('p.add_time','GT',time()-86300)->alias('p')->where('p.status',1)->join('User u','u.uid=p.uid')->field('u.nickname,u.avatar as src,p.add_time')->order('p.add_time desc')->limit(20)->select(); + if($storePink){ + foreach ($storePink as $k=>$v){ + $remain = $v['add_time']%86400; + $hour = floor($remain/3600); + $storePink[$k]['nickname'] = $v['nickname'].$hour.'小时之前拼单'; + } + } + $seckillnum=(int)GroupDataService::getData('store_seckill'); + $storeSeckill=StoreSeckill::where('is_del',0)->where('status',1) + ->where('start_time','<',time())->where('stop_time','>',time()) + ->limit($seckillnum)->order('sort desc')->select()->toArray(); + foreach($storeSeckill as $key=>$value){ + $round=round($value['sales']/$value['stock'],2)*100; + if($round<100){ + $storeSeckill[$key]['round']=$round; + }else{ + $storeSeckill[$key]['round']=100; + } + } + $this->assign([ + 'banner'=>GroupDataService::getData('store_home_banner')?:[], + 'menus'=>GroupDataService::getData('store_home_menus')?:[], + 'roll_news'=>GroupDataService::getData('store_home_roll_news')?:[], + 'category'=>StoreCategory::pidByCategory(0,'id,cate_name'), + 'pinkImage'=>SystemConfigService::get('store_home_pink'), + 'notice'=>$notice, + 'storeSeckill'=>$storeSeckill, + 'storePink'=>$storePink, + ]); + return $this->fetch(); + } + + public function about() + { + + return $this->fetch(); + } + + public function spread($uni = '') + { + if(!$uni || $uni == 'now') $this->redirect(Url::build('spread',['uni'=>$this->oauth()])); + $wechatUser = WechatUser::getWechatInfo($uni); + $statu = (int)SystemConfigService::get('store_brokerage_statu'); + if($statu == 1){ + if(!User::be(['uid'=>$this->userInfo['uid'],'is_promoter'=>1])) + return $this->failed('没有权限访问!'); + } + $qrInfo = QrcodeService::getTemporaryQrcode('spread',$wechatUser['uid']); + $this->assign([ + 'qrInfo'=>$qrInfo, + 'wechatUser'=>$wechatUser + ]); + return $this->fetch(); + } + +} \ No newline at end of file diff --git a/application/wap/controller/Login.php b/application/wap/controller/Login.php new file mode 100644 index 00000000..0af7b741 --- /dev/null +++ b/application/wap/controller/Login.php @@ -0,0 +1,75 @@ + + * @day: 2018/01/15 + */ + +namespace app\wap\controller; + + +use app\wap\model\user\User; +use app\wap\model\user\WechatUser; +use basic\WapBasic; +use service\UtilService; +use service\WechatService; +use think\Cookie; +use think\Request; +use think\Session; +use think\Url; + +class Login extends WapBasic +{ + public function index($ref = '') + { + Cookie::set('is_bg',1); + $ref && $ref=htmlspecialchars(base64_decode($ref)); + if(UtilService::isWechatBrowser()){ + $this->_logout(); + $openid = $this->oauth(); + Cookie::delete('_oen'); + exit($this->redirect(empty($ref) ? Url::build('Index/index') : $ref)); + } + $this->assign('ref',$ref); + return $this->fetch(); + } + + public function check(Request $request) + { + list($account,$pwd,$ref) = UtilService::postMore(['account','pwd','ref'],$request,true); + if(!$account || !$pwd) return $this->failed('请输入登录账号'); + if(!$pwd) return $this->failed('请输入登录密码'); + if(!User::be(['account'=>$account])) return $this->failed('登陆账号不存在!'); + $userInfo = User::where('account',$account)->find(); + $errorInfo = Session::get('login_error_info','wap')?:['num'=>0]; + $now = time(); + if($errorInfo['num'] > 5 && $errorInfo['time'] < ($now - 900)) + return $this->failed('错误次数过多,请稍候再试!'); + if($userInfo['pwd'] != md5($pwd)){ + Session::set('login_error_info',['num'=>$errorInfo['num']+1,'time'=>$now],'wap'); + return $this->failed('账号或密码输入错误!'); + } + if(!$userInfo['status']) return $this->failed('账号已被锁定,无法登陆!'); + $this->_logout(); + Session::set('loginUid',$userInfo['uid'],'wap'); + $userInfo['last_time'] = time(); + $userInfo['last_ip'] = $request->ip(); + $userInfo->save(); + Session::delete('login_error_info','wap'); + Cookie::set('is_login',1); + exit($this->redirect(empty($ref) ? Url::build('Index/index') : $ref)); + } + + public function logout() + { + $this->_logout(); + $this->successful('退出登陆成功',Url::build('Index/index')); + } + + private function _logout() + { + Session::clear('wap'); + Cookie::delete('is_login'); + } + +} \ No newline at end of file diff --git a/application/wap/controller/Merchant.php b/application/wap/controller/Merchant.php new file mode 100644 index 00000000..da4f93e8 --- /dev/null +++ b/application/wap/controller/Merchant.php @@ -0,0 +1,63 @@ + + * @day: 2017/12/18 + */ + +namespace app\wap\controller; + + +use app\wap\model\user\UserEnter; +use service\JsonService; +use service\UtilService; +use think\Cookie; +use think\Db; +use think\Request; +use think\Url; + +class Merchant extends AuthController +{ + public function agreement() + { + return $this->fetch(); + } + + public function apply() + { + if(UserEnter::be($this->userInfo['uid'],'uid')){ + $enterInfo = UserEnter::where('uid',$this->userInfo['uid'])->find()->toArray(); + if($enterInfo['status'] == 0) return $this->failed('正在审核中,请耐心等待!'); + if($enterInfo['status'] == 1) return $this->failed('审核已通过'); + }else{ + if(!Cookie::get('_mer_check_auth')) return $this->failed('请先同意入驻协议!',Url::build('agreement')); + $enterInfo = []; + } + $this->assign(compact('enterInfo')); + return $this->fetch(); + } + + public function submit(Request $request) + { + $data = UtilService::postMore([ + ['province',''], + ['city',''], + ['district',''], + ['address',''], + ['company_name','','','merchant_name'], + ['link_user',''], + ['link_tel',''], + ['charter',[]], + ['id',0] + ],$request); + if($data['id'] == 0 && UserEnter::be(['uid'=>$this->userInfo['uid']])) + return JsonService::fail('已提交商户信息,请勿重复申请!'); + + if(($data['id'] >0 && UserEnter::editEvent($data,$this->userInfo['uid'])) || UserEnter::setEnter($data,$this->userInfo['uid'])) + return JsonService::successful(); + else + return JsonService::fail('提交失败!'); + } + + +} \ No newline at end of file diff --git a/application/wap/controller/My.php b/application/wap/controller/My.php new file mode 100644 index 00000000..67573d3e --- /dev/null +++ b/application/wap/controller/My.php @@ -0,0 +1,458 @@ + + * @day: 2017/12/21 + */ + +namespace app\wap\controller; + + +use Api\Express; +use app\admin\model\system\SystemConfig; +use app\wap\model\store\StoreBargainUser; +use app\wap\model\store\StoreBargainUserHelp; +use app\wap\model\store\StoreCombination; +use app\wap\model\store\StoreOrderCartInfo; +use app\wap\model\store\StorePink; +use app\wap\model\store\StoreProduct; +use app\wap\model\store\StoreProductRelation; +use app\wap\model\store\StoreProductReply; +use app\wap\model\store\StoreCouponUser; +use app\wap\model\store\StoreOrder; +use app\wap\model\user\User; +use app\wap\model\user\UserBill; +use app\wap\model\user\UserExtract; +use app\wap\model\user\UserNotice; +use service\GroupDataService; +use app\wap\model\user\UserAddress; +use app\wap\model\user\UserSign; +use service\CacheService; +use service\SystemConfigService; +use think\Request; +use think\Url; + +class My extends AuthController +{ + + public function user_cut(){ + $list = StoreBargainUser::getBargainUserAll($this->userInfo['uid']); + if($list){ + foreach ($list as $k=>$v){ + $list[$k]['con_price'] = bcsub($v['bargain_price'],$v['price'],2); + $list[$k]['helpCount'] = StoreBargainUserHelp::getBargainUserHelpPeopleCount($v['bargain_id'],$this->userInfo['uid']); + } + $this->assign('list',$list); + }else return $this->failed('暂无参与砍价',Url::build('My/index')); + return $this->fetch(); + } + public function index() + { +// echo date('Y-m-d,H:i:s',1521516681); + $this->assign([ + 'menus'=>GroupDataService::getData('my_index_menu')?:[], + 'orderStatusNum'=>StoreOrder::getOrderStatusNum($this->userInfo['uid']), + 'notice'=>UserNotice::getNotice($this->userInfo['uid']), + 'statu' =>(int)SystemConfig::getValue('store_brokerage_statu'), + ]); + return $this->fetch(); + } + + + public function sign_in() + { + $signed = UserSign::checkUserSigned($this->userInfo['uid']); + $signCount = UserSign::userSignedCount($this->userInfo['uid']); + $signList = UserSign::userSignBillWhere($this->userInfo['uid']) + ->field('number,add_time')->order('id DESC') + ->limit(30)->select()->toArray(); + $goodsList = StoreProduct::getNewProduct('image,price,sales,store_name,id','0,20')->toArray(); + $this->assign(compact('signed','signCount','signList','goodsList')); + return $this->fetch(); + } + + public function coupon() + { + $uid = $this->userInfo['uid']; + $couponList = StoreCouponUser::all(function($query) use($uid){ + $query->where('status','0')->where('uid',$uid)->order('is_fail ASC,status ASC,add_time DESC')->whereOr(function($query) use($uid){ + $query->where('uid',$uid)->where('status','<>',0)->where('end_time','>',time()-(7*86400)); + }); + })->toArray(); + $couponList = StoreCouponUser::tidyCouponList($couponList); + $this->assign([ + 'couponList'=>$couponList + ]); + return $this->fetch(); + } + + public function collect() + { + return $this->fetch(); + } + + public function address() + { + $this->assign([ + 'address'=>UserAddress::getUserValidAddressList($this->userInfo['uid'],'id,real_name,phone,province,city,district,detail,is_default') + ]); + return $this->fetch(); + } + + public function recharge() + { + return $this->fetch(); + } + + public function edit_address($addressId = '') + { + if($addressId && is_numeric($addressId) && UserAddress::be(['is_del'=>0,'id'=>$addressId,'uid'=>$this->userInfo['uid']])){ + $addressInfo = UserAddress::find($addressId)->toArray(); + }else{ + $addressInfo = []; + } + $this->assign(compact('addressInfo')); + return $this->fetch(); + } + + public function order($uni = '') + { + if(!$uni || !$order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni)) return $this->redirect(Url::build('order_list')); + $this->assign([ + 'order'=>StoreOrder::tidyOrder($order,true) + ]); + return $this->fetch(); + } + + public function orderPinkOld($uni = '') + { + if(!$uni || !$order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni)) return $this->redirect(Url::build('order_list')); + $this->assign([ + 'order'=>StoreOrder::tidyOrder($order,true) + ]); + return $this->fetch('order'); + } + + + public function order_list() + { + return $this->fetch(); + } + + public function order_reply($unique = '') + { + if(!$unique || !StoreOrderCartInfo::be(['unique'=>$unique]) || !($cartInfo = StoreOrderCartInfo::where('unique',$unique)->find())) return $this->failed('评价产品不存在!'); + $this->assign(['cartInfo'=>$cartInfo]); + return $this->fetch(); + } + + public function balance() + { + $this->assign([ + 'userMinRecharge'=>SystemConfigService::get('store_user_min_recharge') + ]); + return $this->fetch(); + } + + public function integral() + { + return $this->fetch(); + } + + public function spread_list() + { + $statu = (int)SystemConfig::getValue('store_brokerage_statu'); + if($statu == 1){ + if(!User::be(['uid'=>$this->userInfo['uid'],'is_promoter'=>1])) + return $this->failed('没有权限访问!'); + } + $this->assign([ + 'total'=>User::where('spread_uid',$this->userInfo['uid'])->count() + ]); + return $this->fetch(); + } + + public function notice() + { + + return $this->fetch(); + } + + public function express($uni = '') + { + if(!$uni || !($order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni))) return $this->failed('查询订单不存在!'); + if($order['delivery_type'] != 'express' || !$order['delivery_id']) return $this->failed('该订单不存在快递单号!'); + $cacheName = $uni.$order['delivery_id']; + $result = CacheService::get($cacheName,null); + if($result === null){ + $result = Express::query($order['delivery_id']); + if(is_array($result) && + isset($result['result']) && + isset($result['result']['deliverystatus']) && + $result['result']['deliverystatus'] >= 3) + $cacheTime = 0; + else + $cacheTime = 1800; + CacheService::set($cacheName,$result,$cacheTime); + } + $this->assign([ + 'order'=>$order, + 'express'=>$result + ]); + return $this->fetch(); + } + + + public function user_pro() + { + $statu = (int)SystemConfig::getValue('store_brokerage_statu'); + if($statu == 1){ + if(!User::be(['uid'=>$this->userInfo['uid'],'is_promoter'=>1])) + return $this->failed('没有权限访问!'); + } + $userBill = new UserBill(); + $number = $userBill->where('uid',$this->userInfo['uid']) + ->where('add_time','BETWEEN',[strtotime('today -1 day'),strtotime('today')]) + ->where('category','now_money') + ->where('type','brokerage') + ->value('SUM(number)')?:0; + $allNumber = $userBill + ->where('uid',$this->userInfo['uid']) + ->where('category','now_money') + ->where('type','brokerage') + ->value('SUM(number)')?:0; + $extractNumber = UserExtract::userExtractTotalPrice($this->userInfo['uid']); + $this->assign([ + 'number'=>$number, + 'allnumber'=>$allNumber, + 'extractNumber'=>$extractNumber + ]); + return $this->fetch(); + } + + + public function commission() + { + $uid = (int)Request::instance()->get('uid',0); + if(!$uid) return $this->failed('用户不存在!'); + $this->assign(['uid'=>$uid]); + return $this->fetch(); + } + + public function extract() + { + $minExtractPrice = floatval(SystemConfigService::get('user_extract_min_price'))?:0; + $extractInfo = UserExtract::userLastInfo($this->userInfo['uid'])?:[ + 'extract_type'=>'bank', + 'real_name'=>'', + 'bank_code'=>'', + 'bank_address'=>'', + 'alipay_code'=>'' + ]; + $this->assign(compact('minExtractPrice','extractInfo')); + return $this->fetch(); + } + + + /** + * 创建拼团 + * @param string $uni + */ +// public function createPink($uni = ''){ +// if(!$uni || !$order = StoreOrder::getUserOrderDetail($this->userInfo['uid'],$uni)) return $this->redirect(Url::build('order_list')); +// $order = StoreOrder::tidyOrder($order,true)->toArray(); +// if($order['pink_id']){//拼团存在 +// $res = false; +// $pink['uid'] = $order['uid'];//用户id +// if(StorePink::isPinkBe($pink,$order['pink_id'])) return $this->redirect('order_pink',['id'=>$order['pink_id']]); +// $pink['order_id'] = $order['order_id'];//订单id 生成 +// $pink['order_id_key'] = $order['id'];//订单id 数据库id +// $pink['total_num'] = $order['total_num'];//购买个数 +// $pink['total_price'] = $order['pay_price'];//总金额 +// $pink['k_id'] = $order['pink_id'];//拼团id +// foreach ($order['cartInfo'] as $v){ +// $pink['cid'] = $v['combination_id'];//拼团产品id +// $pink['pid'] = $v['product_id'];//产品id +// $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 +// $pink['price'] = $v['productInfo']['price'];//单价 +// $pink['stop_time'] = 0;//结束时间 +// $pink['add_time'] = time();//开团时间 +// $res = StorePink::set($pink)->toArray(); +// } +// if($res) $this->redirect('order_pink',['id'=>$res['id']]); +// else $this->failed('创建拼团失败,请退款后再次拼团',Url::build('my/index')); +// $this->redirect('order_pink',['id'=>$order['pink_id']]); +// }else{ +// $res = false; +// $pink['uid'] = $order['uid'];//用户id +// $pink['order_id'] = $order['order_id'];//订单id 生成 +// $pink['order_id_key'] = $order['id'];//订单id 数据库id +// $pink['total_num'] = $order['total_num'];//购买个数 +// $pink['total_price'] = $order['pay_price'];//总金额 +// $pink['k_id'] = 0;//拼团id +// foreach ($order['cartInfo'] as $v){ +// $pink['cid'] = $v['combination_id'];//拼团产品id +// $pink['pid'] = $v['product_id'];//产品id +// $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 +// $pink['price'] = $v['productInfo']['price'];//单价 +// $pink['stop_time'] = time()+86400;//结束时间 +// $pink['add_time'] = time();//开团时间 +// $res1 = StorePink::set($pink)->toArray(); +// $res2 = StoreOrder::where('id',$order['id'])->update(['pink_id'=>$res1['id']]); +// $res = $res1 && $res2; +// } +// if($res) $this->redirect('order_pink',['id'=>$res1['id']]); +// else $this->failed('创建拼团失败,请退款后再次拼团',Url::build('my/index')); +// } +// } + + /** + * 参团详情页 + */ + public function order_pink($id = 0){ + if(!$id) return $this->failed('参数错误',Url::build('my/index')); + $pink = StorePink::getPinkUserOne($id); + if(isset($pink['is_refund']) && $pink['is_refund']) { + if($pink['is_refund'] != $pink['id']){ + $id = $pink['is_refund']; + return $this->order_pink($id); + }else{ + return $this->failed('订单已退款',Url::build('store/combination_detail',['id'=>$pink['cid']])); + } + } + if(!$pink) return $this->failed('参数错误',Url::build('my/index')); + $pinkAll = array();//参团人 不包括团长 + $pinkT = array();//团长 + if($pink['k_id']){ + $pinkAll = StorePink::getPinkMember($pink['k_id']); + $pinkT = StorePink::getPinkUserOne($pink['k_id']); + }else{ + $pinkAll = StorePink::getPinkMember($pink['id']); + $pinkT = $pink; + } + $store_combination = StoreCombination::getCombinationOne($pink['cid']);//拼团产品 + $count = count($pinkAll)+1; + $count = (int)$pinkT['people']-$count;//剩余多少人 + $is_ok = 0;//判断拼团是否完成 + $idAll = array(); + $uidAll = array(); + if(!empty($pinkAll)){ + foreach ($pinkAll as $k=>$v){ + $idAll[$k] = $v['id']; + $uidAll[$k] = $v['uid']; + } + } + + $userBool = 0;//判断当前用户是否在团内 0未在 1在 + $pinkBool = 0;//判断当前用户是否在团内 0未在 1在 + $idAll[] = $pinkT['id']; + $uidAll[] = $pinkT['uid']; + if($pinkT['status'] == 2){ + $pinkBool = 1; + }else{ + if(!$count){//组团完成 + $idAll = implode(',',$idAll); + $orderPinkStatus = StorePink::setPinkStatus($idAll); + if($orderPinkStatus){ + if(in_array($this->uid,$uidAll)){ + StorePink::setPinkStopTime($idAll); + if(StorePink::isTpl($uidAll,$pinkT['id'])) StorePink::orderPinkAfter($uidAll,$pinkT['id']); + $pinkBool = 1; + }else $pinkBool = 3; + }else $pinkBool = 6; + } + else{ + if($pinkT['stop_time'] < time()){//拼团时间超时 退款 + if($pinkAll){ + foreach ($pinkAll as $v){ + if($v['uid'] == $this->uid){ + $res = StoreOrder::orderApplyRefund(StoreOrder::where('id',$v['order_id_key'])->value('order_id'),$this->uid,'拼团时间超时'); + if($res){ + if(StorePink::isTpl($v['uid'],$pinkT['id'])) StorePink::orderPinkAfterNo($v['uid'],$v['k_id']); + $pinkBool = 2; + }else return $this->failed(StoreOrder::getErrorInfo(),Url::build('index')); + } + } + } + if($pinkT['uid'] == $this->uid){ + $res = StoreOrder::orderApplyRefund(StoreOrder::where('id',$pinkT['order_id_key'])->value('order_id'),$this->uid,'拼团时间超时'); + if($res){ + if(StorePink::isTpl($pinkT['uid'],$pinkT['id'])) StorePink::orderPinkAfterNo($pinkT['uid'],$pinkT['id']); + $pinkBool = 2; + }else return $this->failed(StoreOrder::getErrorInfo(),Url::build('index')); + } + if(!$pinkBool) $pinkBool = 3; + } + } + } + $store_combination_host = StoreCombination::getCombinationHost();//获取推荐的拼团产品 + if(!empty($pinkAll)){ + foreach ($pinkAll as $v){ + if($v['uid'] == $this->uid) $userBool = 1; + } + } + if($pinkT['uid'] == $this->uid) $userBool = 1; + $combinationOne = StoreCombination::getCombinationOne($pink['cid']); + if(!$combinationOne) return $this->failed('拼团不存在或已下架'); + $combinationOne['images'] = json_decode($combinationOne['images'],true); + $combinationOne['userLike'] = StoreProductRelation::isProductRelation($combinationOne['product_id'],$this->userInfo['uid'],'like'); + $combinationOne['like_num'] = StoreProductRelation::productRelationNum($combinationOne['product_id'],'like'); + $combinationOne['userCollect'] = StoreProductRelation::isProductRelation($combinationOne['product_id'],$this->userInfo['uid'],'collect'); + $this->assign('storeInfo',$combinationOne); + $this->assign('current_pink_order',StorePink::getCurrentPink($id)); + $this->assign(compact('pinkBool','is_ok','userBool','store_combination','pinkT','pinkAll','count','store_combination_host')); + return $this->fetch(); + } + + /** + * 参团详情页 失败或者成功展示页 + */ + public function order_pink_after($id = 0){ + if(!$id) return $this->failed('参数错误',Url::build('my/index')); + $pink = StorePink::getPinkUserOne($id); + if(!$pink) return $this->failed('参数错误',Url::build('my/index')); + $pinkAll = array();//参团人 不包括团长 + $pinkT = array();//团长 + if($pink['k_id']){ + $pinkAll = StorePink::getPinkMember($pink['k_id']); + $pinkT = StorePink::getPinkUserOne($pink['k_id']); + }else{ + $pinkAll = StorePink::getPinkMember($pink['id']); + $pinkT = $pink; + } + $store_combination = StoreCombination::getCombinationOne($pink['cid']);//拼团产品 + $count = count($pinkAll)+1; + $count = (int)$pinkT['people']-$count;//剩余多少人 + $idAll = array(); + $uidAll = array(); + if(!empty($pinkAll)){ + foreach ($pinkAll as $k=>$v){ + $idAll[$k] = $v['id']; + $uidAll[$k] = $v['uid']; + } + } + $idAll[] = $pinkT['id']; + $uidAll[] = $pinkT['uid']; + $userBool = 0;//判断当前用户是否在团内是否完成拼团 + if(!$count) $userBool = 1;//组团完成 + $store_combination_host = StoreCombination::getCombinationHost();//获取推荐的拼团产品 + $combinationOne = StoreCombination::getCombinationOne($pink['cid']); + if(!$combinationOne) return $this->failed('拼团不存在或已下架'); + $combinationOne['images'] = json_decode($combinationOne['images'],true); + $combinationOne['userLike'] = StoreProductRelation::isProductRelation($combinationOne['product_id'],$this->userInfo['uid'],'like'); + $combinationOne['like_num'] = StoreProductRelation::productRelationNum($combinationOne['product_id'],'like'); + $combinationOne['userCollect'] = StoreProductRelation::isProductRelation($combinationOne['product_id'],$this->userInfo['uid'],'collect'); + $this->assign('storeInfo',$combinationOne); + $this->assign(compact('userBool','store_combination','pinkT','pinkAll','count','store_combination_host')); + return $this->fetch(); + } + + /** + * 售后服务 退款订单 + * @return mixed + */ + public function order_customer(){ + return $this->fetch(); + } + +} diff --git a/application/wap/controller/PublicApi.php b/application/wap/controller/PublicApi.php new file mode 100644 index 00000000..c37a21e2 --- /dev/null +++ b/application/wap/controller/PublicApi.php @@ -0,0 +1,105 @@ + + * @day: 2017/12/12 + */ + +namespace app\wap\controller; + + +use app\wap\model\store\StoreCombination; +use app\admin\model\system\SystemGroup; +use app\admin\model\system\SystemGroupData; +use app\wap\model\store\StoreCategory; +use app\wap\model\store\StoreCouponIssue; +use app\wap\model\store\StoreProduct; +use app\wap\model\wap\ArticleCategory; +use service\JsonService; +use service\UtilService; +use think\Cache; + +class PublicApi +{ + public function get_cid_article($cid = 0,$first = 0,$limit = 8) + { + $list = ArticleCategory::cidByArticleList($cid,$first,$limit,'id,title,image_input,visit,add_time,synopsis,url')?:[]; + + foreach ($list as &$article){ + $article['add_time'] = date('Y-m-d H:i',$article['add_time']); + } + return JsonService::successful('ok',$list); + } + + public function get_video_list($key = '', $first = 0,$limit = 8) + { + $gid = SystemGroup::where('config_name',$key)->value('id'); + if(!$gid){ + $list = []; + }else{ + $video = SystemGroupData::where('gid',$gid)->where('status',1)->order('sort DESC,add_time DESC')->limit($first,$limit)->select(); + $list = SystemGroupData::tidyList($video); + } + return JsonService::successful('ok',$list); + } + + public function get_issue_coupon_list($limit = 2) + { + $list = StoreCouponIssue::validWhere('A')->join('__STORE_COUPON__ B','A.cid = B.id') + ->field('A.*,B.coupon_price,B.use_min_price')->order('id DESC')->limit($limit)->select()->toArray(); + return JsonService::successful($list); + } + + public function get_category_product_list($limit = 4) + { + $cateInfo = StoreCategory::where('is_show',1)->where('pid',0)->field('id,cate_name,pic') + ->order('sort DESC')->select()->toArray(); + $result = []; + $StoreProductModel = new StoreProduct; + foreach ($cateInfo as $k=>$cate){ + $cate['product'] = $StoreProductModel::alias('A')->where('A.is_del',0)->where('A.is_show',1) + ->where('A.mer_id',0)->where('B.pid',$cate['id']) + ->join('__STORE_CATEGORY__ B','B.id = A.cate_id') + ->order('A.is_benefit DESC,A.sort DESC,A.add_time DESC') + ->limit($limit)->field('A.id,A.image,A.store_name,A.sales,A.price,A.unit_name')->select()->toArray(); + if(count($cate['product'])) + $result[] = $cate; + } + return JsonService::successful($result); + } + + public function get_best_product_list($first = 0,$limit = 8) + { + $list = StoreProduct::validWhere()->where('mer_id',0)->order('is_best DESC,sort DESC,add_time DESC') + ->limit($first,$limit)->field('id,image,store_name,sales,price,unit_name')->select()->toArray(); + return JsonService::successful($list); + } + + public function wechat_media_id_by_image($mediaIds = '') + { + if(!$mediaIds) return JsonService::fail('参数错误'); + $mediaIds = explode(',',$mediaIds); + $temporary = \service\WechatService::materialTemporaryService(); + $pathList = []; + foreach ($mediaIds as $mediaId){ + if(!$mediaId) continue; + try{ + $content = $temporary->getStream($mediaId); + }catch (\Exception $e){ + continue; + } + $name = substr(md5($mediaId),12,20).'.jpg'; + $path = '.'.DS.'public'.DS.'uploads'.DS.'wechat'.DS.'media'.DS.$name; + $res = file_put_contents($path,$content); + if($res) $pathList[] = UtilService::pathToUrl($path); + } + return JsonService::successful($pathList); + } + + + public function get_pink_host($limit = 0){ + $list = StoreCombination::getCombinationHost($limit); + if($list) return JsonService::successful($list); + else return JsonService::successful([]); + } +} \ No newline at end of file diff --git a/application/wap/controller/Service.php b/application/wap/controller/Service.php new file mode 100644 index 00000000..51312ec8 --- /dev/null +++ b/application/wap/controller/Service.php @@ -0,0 +1,49 @@ + + * @day: 2017/12/23 + */ + +namespace app\wap\controller; + +use app\wap\model\store\StoreService; +use service\SystemConfigService; +use app\wap\model\user\User; +use app\admin\model\system\Merchant; +use think\Request; + +class Service extends AuthController +{ + public function service_list(Request $request){ + $params = Request::instance()->param(); + $merchant = isset($params['mer_id']) && $params['mer_id'] > 0 ? Merchant::where('id',$params['mer_id'])->find() : array("id"=>0,"mer_name"=>""); + $list = StoreService::field('uid,avatar,nickname')->where('mer_id',$merchant['id'])->where('status',1)->order("id desc")->select(); + $this->assign(compact('list','merchant')); + return $this->fetch(); + } + public function service_ing(Request $request){ + $params = Request::instance()->param(); + $to_uid = $params['to_uid']; + $merchant = isset($params['mer_id']) && $params['mer_id'] > 0 ? Merchant::where('id',$params['mer_id'])->find() : array("id"=>0,"mer_name"=>""); + if(!isset($to_uid) || empty($to_uid))$this->failed('未获取到接收用户信息!'); + if($this->userInfo['uid'] == $to_uid)$this->failed('您不能进行自言自语!'); + + //发送用户信息 + $now_user = StoreService::where('mer_id',$merchant['id'])->where(array("uid"=>$this->userInfo['uid']))->find(); + if(!$now_user)$now_user = User::getUserInfo($this->userInfo['uid']); + $this->assign('user',$now_user); + + //接收用户信息 + $to_user = StoreService::where('mer_id',$merchant['id'])->where(array("uid"=>$to_uid))->find(); + if(!$to_user)$to_user = User::getUserInfo($to_uid); + $this->assign([ + 'to_user'=>$to_user, + 'merchant'=>$merchant, + ]); + return $this->fetch(); + } + public function service_new(){ + return $this->fetch(); + } +} \ No newline at end of file diff --git a/application/wap/controller/Store.php b/application/wap/controller/Store.php new file mode 100644 index 00000000..6d86cf12 --- /dev/null +++ b/application/wap/controller/Store.php @@ -0,0 +1,298 @@ + + * @day: 2017/12/12 + */ + +namespace app\wap\controller; + + +use app\admin\model\system\SystemConfig; +use app\wap\model\store\StoreBargain; +use app\wap\model\store\StoreBargainUser; +use app\wap\model\store\StoreBargainUserHelp; +use app\wap\model\store\StoreCategory; +use app\wap\model\store\StoreCoupon; +use app\wap\model\store\StoreSeckill; +use app\wap\model\store\StoreCouponIssue; +use app\wap\model\store\StoreCouponIssueUser; +use app\wap\model\store\StoreCouponUser; +use app\wap\model\store\StorePink; +use app\wap\model\store\StoreProductReply; +use app\wap\model\store\StoreCart; +use app\wap\model\store\StoreOrder; +use app\wap\model\store\StoreProduct; +use app\wap\model\store\StoreProductAttr; +use app\wap\model\store\StoreProductRelation; +use app\wap\model\user\User; +use app\wap\model\user\WechatUser; +use app\wap\model\store\StoreCombination; +use service\GroupDataService; +use service\SystemConfigService; +use service\UtilService; +use think\Cache; +use think\Request; +use think\Url; +use service\JsonService; + +class Store extends AuthController +{ + + public function index($keyword = '',$cid = '',$sid = '') + { + if($keyword != '') $keyword = base64_decode($keyword); + $keyword = addslashes($keyword); + $cid = intval($cid); + $sid = intval($sid); + $category = null; + if($sid) + $category = StoreCategory::get($sid); + if($cid && !$category) + $category = StoreCategory::get($cid); + $this->assign(compact('keyword','cid','sid','category')); + return $this->fetch(); + } + + public function category() + { + $_category = StoreCategory::all(function($query){ + $query->field('id,pid,cate_name')->where('is_show',1)->order('sort DESC'); + })->toArray(); + $category = []; + foreach ($_category as $c){ + if(!$c['pid']){ + $c['child'] = []; + $category[$c['id']] = $c; + } + } + foreach ($_category as $c){ + if($c['pid']){ + $category[$c['pid']]['child'][] = $c; + } + } + foreach ($category as $key => $value) { + if(!isset($value['id'])){ + unset($category[$key]); + } + } + $this->assign(compact('category')); + return $this->fetch(); + } + + public function issue_coupon() + { + $list = $list = StoreCouponIssue::validWhere('A')->join('__STORE_COUPON__ B','A.cid = B.id') + ->field('A.*,B.coupon_price,B.use_min_price')->order('B.sort DESC,A.id DESC')->select()->toArray(); + $sort = []; + $lists= []; + foreach ($list as &$v){ + $v['add_time'] = date('Y/m/d',$v['add_time']); + $v['end_time'] = date('Y/m/d',$v['end_time']); + if((int)$v['is_permanent']==0 && $v['remain_count'] >0){ + $sort[] = $v['is_get'] = StoreCouponIssueUser::be(['uid'=>$this->userInfo['uid'],'issue_coupon_id'=>$v['id']]) ? 1:0; + array_push($lists,$v); + } + } + array_multisort($sort,SORT_ASC,SORT_NUMERIC,$lists); + $this->assign(compact('lists')); + return $this->fetch(); + } + + public function detail($id = 0) + { + if(!$id || !($storeInfo = StoreProduct::getValidProduct($id))) return $this->failed('商品不存在或已下架!'); + $storeInfo['userLike'] = StoreProductRelation::isProductRelation($id,$this->userInfo['uid'],'like'); + $storeInfo['like_num'] = StoreProductRelation::productRelationNum($id,'like'); + $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($id,$this->userInfo['uid'],'collect'); + list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($id); + setView($this->userInfo['uid'],$id,$storeInfo['cate_id'],'viwe'); + $this->assign([ + 'storeInfo'=>$storeInfo, + 'similarity'=>StoreProduct::cateIdBySimilarityProduct($storeInfo['cate_id'],'id,store_name,image,price,sales',4), + 'productAttr'=>$productAttr, + 'productValue'=>$productValue, + 'reply'=>StoreProductReply::getRecProductReply($storeInfo['id']), + 'replyCount'=>StoreProductReply::productValidWhere()->where('product_id',$storeInfo['id'])->count(), + 'mer_id' => StoreProduct::where('id',$storeInfo['id'])->value('mer_id') + ]); + return $this->fetch(); + } + + public function reply_list($productId = '') + { + if(!$productId || !is_numeric($productId)) return $this->failed('商品不存在!'); + $this->assign([ + 'productId'=>$productId, + 'replyCount'=>StoreProductReply::productValidWhere()->where('product_id',$productId)->count(), + 'picReplyCount'=>StoreProductReply::productValidWhere()->where('product_id',$productId)->where('pics',['<>',''],['<>','[]'])->count() + ]); + return $this->fetch(); + } + + public function cart() + { + return $this->fetch(); + } + + public function confirm_order($cartId = '') + { + if(!is_string($cartId) || !$cartId ){ + return $this->failed('请提交购买的商品!'); + } + $cartGroup = StoreCart::getUserProductCartList($this->userInfo['uid'],$cartId,1); + + if(count($cartGroup['invalid'])) + return $this->failed($cartGroup['invalid'][0]['productInfo']['store_name'].'已失效!'); + if(!$cartGroup['valid']) return $this->failed('请提交购买的商品!'); + $cartInfo = $cartGroup['valid']; + $priceGroup = StoreOrder::getOrderPriceGroup($cartInfo); + $other = [ + 'offlinePostage'=>SystemConfigService::get('offline_postage'), + 'integralRatio'=>SystemConfigService::get('integral_ratio') + ]; + + $usableCoupon = StoreCouponUser::beUsableCoupon($this->userInfo['uid'],$priceGroup['totalPrice']); + $cartIdA = explode(',',$cartId); + $seckill_id=0; + $bargain_id=0; + if(count($cartIdA) == 1){ + $cartInfoMark = StoreCart::where('id',$cartId)->find(); + if((int)$cartInfoMark['seckill_id']>0) $seckill_id = $cartInfoMark['seckill_id']; + else if((int)$cartInfoMark['bargain_id']>0) $bargain_id = $cartInfoMark['bargain_id']; + else $seckill_id=0; + } + $this->assign([ + 'usableCoupon'=>$usableCoupon, + 'seckill_id'=>$seckill_id, + 'bargain_id'=>$bargain_id, + 'cartInfo'=>$cartInfo, + 'priceGroup'=>$priceGroup, + 'orderKey'=>StoreOrder::cacheOrderInfo($this->userInfo['uid'],$cartInfo,$priceGroup,$other), + 'offlinePostage'=>$other['offlinePostage'], + 'userInfo'=>User::getUserInfo($this->userInfo['uid']), + 'integralRatio'=>$other['integralRatio'] + ]); + + return $this->fetch(); + } + //获取列表 + public function get_list(){ + return JsonService::successful(StoreCombination::get_list(20)); + } + /** + * 秒杀列表页 + * + */ + public function seckill_index(){ + $storeSeckill=StoreSeckill::where('is_del',0)->where('status',1)->where('start_time','<',time())->where('stop_time','>',time())->order('sort desc')->select()->toArray(); + + $this->assign('seckillProduct',$storeSeckill); + + return $this->fetch(); + } + /** + * 秒杀详情页 + * @param string $id + */ + public function seckill_detail($id = ''){ + + if(!$id || !($storeInfo = StoreSeckill::getValidProduct($id))) return $this->failed('商品不存在或已下架!'); + $storeInfo['userLike'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'like','product_seckill'); + + $storeInfo['like_num'] = StoreProductRelation::productRelationNum($storeInfo['product_id'],'like','product_seckill'); + + $storeInfo['userCollect'] = StoreProductRelation::isProductRelation($storeInfo['product_id'],$this->userInfo['uid'],'collect','product_seckill'); + list($productAttr,$productValue) = StoreProductAttr::getProductAttrDetail($storeInfo['product_id']); + $wechatInfo = WechatUser::get($this->userInfo['uid']); + setView($this->userInfo['uid'],$id,$storeInfo['product_id'],'viwe','seckill'); + //是否关注 + if(!$wechatInfo) $isFollow = 0; + else $isFollow = $wechatInfo['subscribe']; + $this->assign([ + 'storeInfo'=>$storeInfo, +// 'similarity'=>StoreProduct::cateIdBySimilarityProduct($storeInfo['cate_id'],'id,store_name,image,price,sales',4), + 'productAttr'=>$productAttr, + 'productValue'=>$productValue, + 'reply'=>StoreProductReply::getRecProductReply($storeInfo['product_id']), + 'replyCount'=>StoreProductReply::productValidWhere()->where('product_id',$storeInfo['product_id'])->count(), + 'mer_id' => 0, + 'merchant'=>null, + 'site'=>SystemConfigService::more(['wechat_qrcode','wechat_name','wechat_avatar']), + 'isFollow'=>$isFollow + ]); + return $this->fetch(); + } + + public function cut_list(){ + $bargain = StoreBargain::getList(); + $bargain = StoreBargainUser::getUserList($bargain); + $bargainUser = StoreBargainUser::getBargainUserStatusSuccess(); + $this->assign([ + 'bargain'=>$bargain, + 'bargainUser'=>$bargainUser, + ]); + return $this->fetch(); + } + public function cut_con($id = 0,$bargainUid = 0){ + if(!$id) return $this->failed('参数错误'); + //砍价产品 + $bargain = StoreBargain::getBargainTerm($id); + $bargain['time'] = time(); + $description = htmlspecialchars_decode($bargain['description']); + $rule = isset($bargain['rule']) ? htmlspecialchars_decode($bargain['rule']) : ''; + if(!$bargainUid) + //判断当前登录人是不是砍价 + if(!StoreBargainUser::isBargainUser($id,$this->userInfo['uid'])) + // 参与砍价 + if(!StoreBargainUser::setBargain($id,$this->userInfo['uid'])) return $this->failed('参与失败,请重新参与砍价',Url::build('store/bargain')); + //顶部人数 + StoreBargain::addBargainLook($id); + $lookCount = StoreBargain::getBargainLook()['look'];//观看人数 + $shareCount = StoreBargain::getBargainShare()['share'];//观看人数 + //砍价 + $selfCut = 0; + if(!$bargainUid){ + $res = StoreBargainUserHelp::setBargainUserHelp($id,$bargainUid ? $bargainUid : $this->userInfo['uid'],$this->userInfo['uid']); + if($res) { + $selfCut = 1; + if(!StoreBargainUserHelp::getSurplusPrice($id,$bargainUid ? $bargainUid : $this->userInfo['uid'])){ + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($id,$bargainUid ? $bargainUid : $this->userInfo['uid']); + $bargain = StoreBargain::where('id',$id)->find()->toArray(); + $bargainUser = StoreBargainUser::where('id',$bargainUserTableId)->find()->toArray(); + } + } + $userInfoBargain = $this->userInfo; + }else $userInfoBargain = User::getUserInfo($bargainUid); + //砍价帮 + $bargainUserTableId = StoreBargainUser::setUserBargain($id,$bargainUid ? $bargainUid : $this->userInfo['uid']); + $storeBargainUserHelp = StoreBargainUserHelp::getList($bargainUserTableId,15); + //获取砍价帮总人数 + $count = StoreBargainUserHelp::getBargainUserHelpPeopleCount($id,$bargainUid ? $bargainUid : $this->userInfo['uid']); + //获取用户还剩余的砍价金额 + $price = StoreBargainUserHelp::getSurplusPrice($id,$bargainUid ? $bargainUid : $this->userInfo['uid']); + //获取砍价进度条 + $pricePercent = StoreBargainUserHelp::getSurplusPricePercent($id,$bargainUid ? $bargainUid : $this->userInfo['uid']); + $selfCutPrice = bcsub(bcsub($bargain['price'],$price,2),$bargain['min_price'],2); + //判断当前登录人是否砍价 1 微砍价 2 已砍价 + $userInfoBargainBool = StoreBargainUserHelp::isBargainUserHelpCount($id,$bargainUid,$this->userInfo['uid']) ? 1 : 2; + $this->assign([ + 'userInfoBargainBool'=>$userInfoBargainBool, + 'selfCut'=>$selfCut, + 'userInfoBargain'=>$userInfoBargain, + 'selfCutPrice'=>$selfCutPrice, + 'bargain'=>$bargain, + 'description'=>$description, + 'rule'=>$rule, + 'shareCount'=>$shareCount, + 'lookCount'=>$lookCount, + 'userCount'=>StoreBargainUser::count(), + 'userHelpList'=>$storeBargainUserHelp, + 'count'=>$count, + 'price'=>$price, + 'pricePercent'=>$pricePercent, + 'bargainUid'=>$bargainUid, + ]); + return $this->fetch(); + } +} \ No newline at end of file diff --git a/application/wap/controller/Wechat.php b/application/wap/controller/Wechat.php new file mode 100644 index 00000000..81f25f59 --- /dev/null +++ b/application/wap/controller/Wechat.php @@ -0,0 +1,40 @@ + + * @day: 2017/12/18 + */ + +namespace app\wap\model\store; + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreBargain extends ModelBasic +{ + use ModelTrait; + + /** + * 正在开启的砍价活动 + * @return $this + */ + public static function validWhere($status = 1){ + return self::where('is_del',0)->where('status',$status)->where('start_time','LT',time())->where('stop_time','GT',time()); + } + + /** + * 判断砍价产品是否开启 + * @param int $bargainId + * @return int|string + */ + public static function validBargain($bargainId = 0){ + $model = self::validWhere(); + return $model->where('id',$bargainId)->count(); + } + /** + * 获取正在进行中的砍价产品 + * @param string $field + */ + public static function getList($field = 'id,product_id,title,price,min_price,image'){ + $model = self::validWhere(); + $list = $model->field($field)->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取正在开启的砍价活动 + * @return int|string + */ + public static function getListCount(){ + return self::validWhere()->count(); + } + + /** + * 获取一条正在进行中的砍价产品 + * @param int $bargainId + * @param string $field + * @return array + */ + public static function getBargainTerm($bargainId = 0,$field = 'rule,id,product_id,bargain_num,num,unit_name,image,title,price,min_price,image,description,start_time,stop_time'){ + if(!$bargainId) return []; + $model = self::validWhere(); + $bargain = $model->field($field)->where('id',$bargainId)->find(); + if($bargain) return $bargain->toArray(); + else return []; + } + + /** + * 获取一条砍价产品 + * @param int $bargainId + * @param string $field + * @return array + */ + public static function getBargain($bargainId = 0,$field = 'id,product_id,title,price,min_price,image'){ + if(!$bargainId) return []; + $model = new self(); + $bargain = $model->field($field)->where('id',$bargainId)->find(); + if($bargain) return $bargain->toArray(); + else return []; + } + + /** + * 获取最高价和最低价 + * @param int $bargainId + * @return array + */ + public static function getBargainMaxMinPrice($bargainId = 0){ + if(!$bargainId) return []; + return self::where('id',$bargainId)->field('bargain_min_price,bargain_max_price')->find()->toArray(); + } + + /** + * 获取砍价次数 + * @param int $bargainId + * @return mixed + */ + public static function getBargainNum($bargainId = 0){ + return self::where('id',$bargainId)->value('bargain_num'); + } + + /** + * 判断当前砍价是否活动进行中 + * @param int $bargainId + * @return bool + */ + public static function setBargainStatus($bargainId = 0){ + $model = self::validWhere(); + $count = $model->where('id',$bargainId)->count(); + if($count) return true; + else return false; + } + + /** + * 获取库存 + * @param int $bargainId + * @return mixed + */ + public static function getBargainStock($bargainId = 0){ + return self::where('id',$bargainId)->value('stock'); + } + /** + * 修改销量和库存 + * @param $num + * @param $CombinationId + * @return bool + */ + public static function decBargainStock($num,$bargainId) + { + $res = false !== self::where('id',$bargainId)->dec('stock',$num)->inc('sales',$num)->update(); + return $res; + } + + /** + * 获取所有砍价产品的浏览量 + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getBargainLook(){ + return self::field('sum(look) as look')->find(); + } + + /** + * 获取所有砍价产品的分享量 + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getBargainShare(){ + return self::field('sum(share) as share')->find(); + } + + /** + * 添加砍价产品分享次数 + * @param int $id + * @return bool + */ + public static function addBargainShare($id = 0){ + if(!$id) return false; + return self::where('id',$id)->inc('share',1)->update(); + } + + /** + * 添加砍价产品浏览次数 + * @param int $id + * @return bool + */ + public static function addBargainLook($id = 0){ + if(!$id) return false; + return self::where('id',$id)->inc('look',1)->update(); + } +} \ No newline at end of file diff --git a/application/wap/model/store/StoreBargainUser.php b/application/wap/model/store/StoreBargainUser.php new file mode 100644 index 00000000..33b2f27e --- /dev/null +++ b/application/wap/model/store/StoreBargainUser.php @@ -0,0 +1,203 @@ +$v){ + if(is_array($v)){ + $uid = self::getUserIdList($v['id']); + if(count($uid) > 0) { + $userInfo = User::where('uid','IN',implode(',',$uid))->limit($limit)->column('avatar','uid'); + $bargain[$k]['userInfo'] = $userInfo; + $bargain[$k]['userInfoCount'] = count($userInfo); + } + else { + $bargain[$k]['userInfo'] = []; + $bargain[$k]['userInfoCount'] = 0; + } + }else{ + $uid = self::getUserIdList($bargain['id']); + if(count($uid) > 0) $bargain['userInfo'] = User::where('uid','IN',implode(',',$uid))->column('avatar','uid'); + else $bargain['userInfo'] = []; + } + } + return $bargain; + } + + /** + * 根据砍价产品ID获取正在参与人的uid + * @param int $bargainId $bargainId 砍价产品ID + * @param int $status $status 状态 1 进行中 2 结束失败 3结束成功 + * @return array + */ + public static function getUserIdList($bargainId = 0,$status = 1){ + if(!$bargainId) return []; + return self::where('bargain_id',$bargainId)->where('status',$status)->column('uid','id'); + } + + /** + * 获取参与的ID + * @param int $bargainId + * @param int $uid + * @param int $status + * @return array|mixed + */ + public static function setUserBargain($bargainId = 0,$uid = 0,$status = 1){ + if(!$bargainId || !$uid) return []; + $bargainIdUserTableId = self::where('bargain_id',$bargainId)->where('uid',$uid)->where('status',$status)->value('id'); + return $bargainIdUserTableId; + } + + + + /** + * 添加一条砍价记录 + * @param int $bargainId + * @param int $uid + * @return bool|object + */ + public static function setBargain($bargainId = 0,$uid = 0){ + if(!$bargainId || !$uid || !StoreBargain::validBargain($bargainId) || self::be(['bargain_id'=>$bargainId,'uid'=>$uid,'status'=>1])) return false; + $data['bargain_id'] = $bargainId; + $data['uid'] = $uid; + $data['bargain_price_min'] = StoreBargain::where('id',$bargainId)->value('min_price'); + $data['bargain_price'] = StoreBargain::where('id',$bargainId)->value('price'); + $data['price'] = 0; + $data['status'] = 1; + $data['add_time'] = time(); + return self::set($data); + } + + + /** + * 判断当前人是否已经参与砍价 + * @param int $bargainId + * @param int $uid + * @return bool|mixed + */ + public static function isBargainUser($bargainId = 0,$uid = 0){ + if(!$bargainId || !$uid || !StoreBargain::validBargain($bargainId)) return false; + return self::where('bargain_id',$bargainId)->where('uid',$uid)->value('uid'); + } + + /** + * 获取用户砍掉的价格 + * @param int $bargainUserId + * @return mixed + */ + public static function getBargainUserPrice($bargainUserId = 0){ + return (float)self::where('id',$bargainUserId)->value('price'); + } + + + /** + * 获取用户可以砍掉的价格 + * @param int $bargainUserId + * @return string + */ + public static function getBargainUserDiffPrice($bargainId = 0,$bargainUserId = 0){ + $price = self::where('bargain_id',$bargainId)->where('uid',$bargainUserId)->field('bargain_price,bargain_price_min')->find()->toArray(); + return (float)bcsub($price['bargain_price'],$price['bargain_price_min'],0); + } + + /** + * 获取砍价表ID + * @param int $bargainId + * @param int $bargainUserId + * @return mixed + */ + public static function getBargainUserTableId($bargainId = 0,$bargainUserId = 0,$status = 1){ + return self::where('bargain_id',$bargainId)->where('uid',$bargainUserId)->where('status',$status)->value('id'); + } + + /** + * 修改砍价价格 + * @param int $bargainUserTableId + * @param array $price + * @return $this|bool + */ + public static function setBargainUserPrice($bargainUserTableId = 0, $price = array()){ + if(!$bargainUserTableId) return false; + return self::where('id',$bargainUserTableId)->update($price); + } + + /** + * 获取用户的砍价产品 + * @param $uid + * @return array + */ + public static function getBargainUserAll($uid = 0){ + if(!$uid) return []; + $model = new self; + $model = $model->alias('u'); + $model = $model->field('u.id,u.bargain_id,u.bargain_price,u.bargain_price_min,u.price,u.status,b.title,b.image,b.stop_time'); + $model = $model->join('StoreBargain b','b.id=u.bargain_id'); + $model = $model->where('u.uid',$uid); + $model = $model->order('u.id desc'); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 修改用户砍价状态 支付订单 + * @param int $bargainId + * @param int $uid + * @return $this|bool + */ + public static function setBargainUserStatus($bargainId = 0, $uid = 0){ + $count = self::where('uid',$uid)->where('bargain_id',$bargainId)->where('status',1)->count(); + if(!$count) return false; + $userPrice = (float)self::where('uid',$uid)->where('bargain_id',$bargainId)->where('status',1)->value('price'); + $price = self::getBargainUserDiffPrice($bargainId,$uid); + if(bcsub($price,$userPrice,0) > 0) return false; + return self::where('uid',$uid)->where('bargain_id',$bargainId)->where('status',1)->update(['status'=>3]); + } + + /** + * 修改砍价状态为 砍价失败 + * @param int $bargainUserTableId + * @return $this|bool + */ + public static function editBargainUserStatus($bargainUserTableId = 0){ + if(!$bargainUserTableId) return false; + return self::where('id',$bargainUserTableId)->update(['status'=>2]); + } + + /** + * 获取砍价成功的用户信息 + * @return array|false|\PDOStatement|string|\think\Collection + */ + public static function getBargainUserStatusSuccess(){ + $bargainUser = self::where('status',3)->order('id desc')->field('uid,bargain_price_min,bargain_id')->select()->toArray(); + if($bargainUser) { + foreach ($bargainUser as $k=>$v) { + $bargainUser[$k]['avatar'] = User::where('uid',$v['uid'])->value('avatar'); + $bargainUser[$k]['info'] = User::where('uid',$v['uid'])->value('nickname').'砍价成功了'.$v['bargain_price_min'].'砍到了'.StoreBargain::where('id',$v['bargain_id'])->value('title'); + } + } + else{ + $bargainUser[0]['avatar'] = 'http://thirdwx.qlogo.cn/mmopen/ajNVdqHZLLCx03Y4hkSeVgQZGZLYDSQz6SZ7PDDNSLj3RxVPYqibMvW4cIOicPSSmA0xbrL9DY2RkunA1pulAs9g/132'; + $bargainUser[0]['info'] = '砍价上线了,快邀请您的好友来砍价'; + } + return $bargainUser; + } +} \ No newline at end of file diff --git a/application/wap/model/store/StoreBargainUserHelp.php b/application/wap/model/store/StoreBargainUserHelp.php new file mode 100644 index 00000000..4ead5fcc --- /dev/null +++ b/application/wap/model/store/StoreBargainUserHelp.php @@ -0,0 +1,132 @@ +limit($limit)->column('uid,price','id'); + if($list){ + foreach ($list as $k=>$v){ + $userInfo = self::getBargainUserHelpUserInfo($v['uid']); + $list[$k]['nickname'] = $userInfo[$v['uid']]['nickname']; + $list[$k]['avatar'] = $userInfo[$v['uid']]['avatar']; + } + } + return $list; + } + + /** + * 获取用的昵称和头像 + * @param int $uid + * @return array + */ + public static function getBargainUserHelpUserInfo($uid = 0){ + if(!$uid) return []; + $userInfo = User::where('uid',$uid)->column('nickname,avatar','uid'); + return $userInfo; + } + + /** + * 帮忙砍价 + * @param int $bargainId + * @param int $bargainUserId + * @param int $uid + * @return bool|object + */ + public static function setBargainUserHelp($bargainId = 0,$bargainUserId = 0,$uid = 0){ + if(!self::isBargainUserHelpCount($bargainId,$bargainUserId,$uid) || !$bargainId || !$bargainUserId || !$uid || !StoreBargain::validBargain($bargainId) || !StoreBargainUser::be(['bargain_id'=>$bargainId,'uid'=>$bargainUserId,'status'=>1])) return false; + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $priceSection = StoreBargain::getBargainMaxMinPrice($bargainId); //获取砍价的价格区间 + $coverPrice = StoreBargainUser::getBargainUserDiffPrice($bargainId,$bargainUserId);//用户可以砍掉的金额 + $alreadyPrice= StoreBargainUser::getBargainUserPrice($bargainUserTableId);//用户已经砍掉的价格 + $surplusPrice = (float)bcsub($coverPrice,$alreadyPrice,2);//用户剩余要砍掉的价格 + $data['uid'] = $uid; + $data['bargain_id'] = $bargainId; + $data['bargain_user_id'] = $bargainUserTableId; + $data['price'] = mt_rand($priceSection['bargain_min_price'],$priceSection['bargain_max_price']); + $data['add_time'] = time(); + if($data['price'] > $surplusPrice) $data['price'] = $surplusPrice; + $price = bcadd($alreadyPrice,$data['price'],0); + $bargainUserData['price'] = $price; + self::beginTrans(); + $res1 = StoreBargainUser::setBargainUserPrice($bargainUserTableId,$bargainUserData); + $res2 = self::set($data); + $res = $res1 && $res2; + self::checkTrans($res); + if($res) return $data; + else return $res; + } + + /** + * 判断用户是否还可以砍价 + * @param int $bargainId + * @param int $bargainUserUid + * @param int $bargainUserHelpUid + * @return bool + */ + public static function isBargainUserHelpCount($bargainId = 0,$bargainUserUid = 0,$bargainUserHelpUid = 0){ + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserUid); + $bargainNum = StoreBargain::getBargainNum($bargainId); + $count = self::where('bargain_id',$bargainId)->where('bargain_user_id',$bargainUserTableId)->where('uid',$bargainUserHelpUid)->count(); + if($count < $bargainNum) return true; + else return false; + } + + /** + * 获取砍价帮总人数 + * @param int $bargainId + * @param int $bargainUserId + * @return int|string + */ + public static function getBargainUserHelpPeopleCount($bargainId = 0,$bargainUserId = 0){ + if(!$bargainId || !$bargainUserId) return 0; + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + if($bargainUserTableId) return self::where('bargain_user_id',$bargainUserTableId)->where('bargain_id',$bargainId)->count(); + else return 0; + } + + /** + * 获取用户还剩余的砍价金额 + * @param int $bargainId + * @param int $bargainUserId + * @return float + */ + public static function getSurplusPrice($bargainId = 0,$bargainUserId = 0){ + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $coverPrice = StoreBargainUser::getBargainUserDiffPrice($bargainId,$bargainUserId);//用户可以砍掉的金额 + $alreadyPrice= StoreBargainUser::getBargainUserPrice($bargainUserTableId);//用户已经砍掉的价格 + $surplusPrice = (float)bcsub($coverPrice,$alreadyPrice,2);//用户剩余要砍掉的价格 + return $surplusPrice; + } + + /** + * 获取砍价进度条 + * @param int $bargainId + * @param int $bargainUserId + * @return string + */ + public static function getSurplusPricePercent($bargainId = 0,$bargainUserId = 0){ + $coverPrice = StoreBargainUser::getBargainUserDiffPrice($bargainId,$bargainUserId);//用户可以砍掉的金额 + $bargainUserTableId = StoreBargainUser::getBargainUserTableId($bargainId,$bargainUserId); + $alreadyPrice= StoreBargainUser::getBargainUserPrice($bargainUserTableId);//用户已经砍掉的价格 + if($coverPrice < 1) return 0; + else if($alreadyPrice) return bcmul(bcdiv($alreadyPrice,$coverPrice,2),100,0); + } +} + diff --git a/application/wap/model/store/StoreCart.php b/application/wap/model/store/StoreCart.php new file mode 100644 index 00000000..2cb52f6c --- /dev/null +++ b/application/wap/model/store/StoreCart.php @@ -0,0 +1,233 @@ + + * @day: 2017/12/18 + */ + +namespace app\wap\model\store; + + +use app\wap\model\store\StoreCombination; +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCart extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function setCart($uid,$product_id,$cart_num = 1,$product_attr_unique = '',$type='product',$is_new = 0,$combination_id=0,$seckill_id = 0,$bargain_id = 0) + { + if($cart_num < 1) $cart_num = 1; + if($seckill_id){ + if(!StoreSeckill::getValidProduct($seckill_id)) + return self::setErrorInfo('该产品已下架或删除'); + $stock=StoreSeckill::where('id',$seckill_id)->value('stock'); + if(!StoreSeckill::where('id',$seckill_id)->where('num','gt',$stock)->count()){//单次购买的产品多于库存 + $stock=StoreSeckill::where('id',$seckill_id)->value('num'); + if($stock<1) return self::setErrorInfo('该产品单次秒杀不足1件'); + } + if($stock<$cart_num) return self::setErrorInfo('该产品库存不足'.$cart_num); + }elseif($combination_id) {//拼团 + if (!StoreCombination::getCombinationStock($combination_id, $cart_num)) + return self::setErrorInfo('该产品库存不足' . $cart_num); + if (!StoreCombination::isValidCombination($combination_id)) + return self::setErrorInfo('该产品已下架或删除'); + }elseif($bargain_id){//砍价 + if(!StoreBargain::validBargain($bargain_id)) + return self::setErrorInfo('该产品已下架或删除'); + if(StoreBargain::getBargainStock($bargain_id) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + }else{ + if(!StoreProduct::isValidProduct($product_id)) + return self::setErrorInfo('该产品已下架或删除'); + if(!StoreProductAttr::issetProductUnique($product_id,$product_attr_unique)) + return self::setErrorInfo('请选择有效的产品属性'); + if(StoreProduct::getProductStock($product_id,$product_attr_unique) < $cart_num) + return self::setErrorInfo('该产品库存不足'.$cart_num); + } + $where = ['type'=>$type,'uid'=>$uid,'product_id'=>$product_id,'product_attr_unique'=>$product_attr_unique,'is_new'=>$is_new,'is_pay'=>0,'is_del'=>0,'combination_id'=>$combination_id,'seckill_id'=>$seckill_id,'bargain_id'=>$bargain_id]; + if($cart = self::where($where)->find()){ + $cart->cart_num = $cart_num; + $cart->add_time = time(); + $cart->save(); + return $cart; + }else{ + return self::set(compact('uid','product_id','cart_num','product_attr_unique','is_new','type','combination_id','seckill_id','bargain_id')); + } + + } + + public static function removeUserCart($uid,$ids) + { + return self::where('uid',$uid)->where('id','IN',$ids)->update(['is_del'=>1]); + } + + public static function getUserCartNum($uid,$type) + { + return self::where('uid',$uid)->where('type',$type)->where('is_pay',0)->where('is_del',0)->where('is_new',0)->count(); + } + + public static function changeUserCartNum($cartId,$cartNum,$uid) + { + return self::where('uid',$uid)->where('id',$cartId)->update(['cart_num'=>$cartNum]); + } + + public static function getUserProductCartList($uid,$cartIds='',$status=0) + { + $productInfoField = 'id,image,slider_image,price,cost,ot_price,vip_price,postage,mer_id,give_integral,cate_id,sales,stock,store_name,unit_name,is_show,is_del,is_postage'; + $seckillInfoField = 'id,image,images as slider_image,price,cost,ot_price,postage,give_integral,sales,stock,title as store_name,unit_name,is_show,is_del,is_postage'; + $bargainInfoField = 'id,image,min_price as price,price as ot_price,postage,give_integral,sales,stock,title as store_name,unit_name,status as is_show,is_del,is_postage,cost'; + $model = new self(); + $valid = $invalid = []; + if($cartIds) + $model = $model->where('uid',$uid)->where('type','product')->where('is_pay',0) + ->where('is_del',0); + else + $model = $model->where('uid',$uid)->where('type','product')->where('is_pay',0)->where('is_new',0) + ->where('is_del',0); + if($cartIds) $model->where('id','IN',$cartIds); + $list = $model->select()->toArray(); + if(!count($list)) return compact('valid','invalid'); + foreach ($list as $k=>$cart) { + if ($cart['seckill_id']) { + $product = StoreSeckill::field($seckillInfoField) + ->find($cart['seckill_id'])->toArray(); + }elseif($cart['bargain_id']){ + $product = StoreBargain::field($bargainInfoField) + ->find($cart['bargain_id'])->toArray(); + }else{ + $product = StoreProduct::field($productInfoField) + ->find($cart['product_id'])->toArray(); + } + $cart['productInfo'] = $product; + //商品不存在 + if (!$product) { + $model->where('id', $cart['id'])->update(['is_del' => 1]); + //商品删除或无库存 + } else if (!$product['is_show'] || $product['is_del'] || !$product['stock']) { + $invalid[] = $cart; + //商品属性不对应并且没有seckill_id + } else if (!$cart['bargain_id'] && !$cart['seckill_id'] && !StoreProductAttr::issetProductUnique($cart['product_id'], $cart['product_attr_unique'])) { + $invalid[] = $cart; + //正常商品 + } else { + if ($status) { +// if ($cart['seckill_id'] != 0) { + if ($cart['product_attr_unique']) { + $attrInfo = StoreProductAttr::uniqueByAttrInfo($cart['product_attr_unique']); + //商品没有对应的属性 + if (!$attrInfo || !$attrInfo['stock']){ + $invalid[] = $cart; + }else { + $cart['productInfo']['attrInfo'] = $attrInfo; + $cart['truePrice'] = (float)$attrInfo['price']; + $cart['costPrice'] = (float)$attrInfo['cost']; + $cart['trueStock'] = $attrInfo['stock']; + $cart['productInfo']['image'] = empty($attrInfo['image']) ? $cart['productInfo']['image'] : $attrInfo['image']; + $valid[] = $cart; + } + } else { + $cart['truePrice'] = (float)$cart['productInfo']['price']; + $cart['costPrice'] = (float)$cart['productInfo']['cost']; + $cart['trueStock'] = $cart['productInfo']['stock']; + $valid[] = $cart; + } +// }else{ +// +// } + } else { + if ($cart['seckill_id'] == 0) { + if ($cart['product_attr_unique']) { + $attrInfo = StoreProductAttr::uniqueByAttrInfo($cart['product_attr_unique']); + //商品没有对应的属性 + if (!$attrInfo || !$attrInfo['stock']) + $invalid[] = $cart; + else { + $cart['productInfo']['attrInfo'] = $attrInfo; + $cart['truePrice'] = (float)$attrInfo['price']; + $cart['costPrice'] = (float)$attrInfo['cost']; + $cart['trueStock'] = $attrInfo['stock']; + $cart['productInfo']['image'] = empty($attrInfo['image']) ? $cart['productInfo']['image'] : $attrInfo['image']; + $valid[] = $cart; + } + } else { + $cart['truePrice'] = (float)$cart['productInfo']['price']; + $cart['costPrice'] = (float)$cart['productInfo']['cost']; + $cart['trueStock'] = $cart['productInfo']['stock']; + $valid[] = $cart; + } + } + + } + + } + } + foreach ($valid as $k=>$cart){ + if($cart['trueStock'] < $cart['cart_num']){ + $cart['cart_num'] = $cart['trueStock']; + $model->where('id',$cart['id'])->update(['cart_num'=>$cart['cart_num']]); + $valid[$k] = $cart; + } + } + return compact('valid','invalid'); + } + + /** + * 拼团 + * @param $uid + * @param string $cartIds + * @return array + */ + public static function getUserCombinationProductCartList($uid,$cartIds='') + { + $productInfoField = 'id,image,slider_image,price,cost,ot_price,vip_price,postage,mer_id,give_integral,cate_id,sales,stock,store_name,unit_name,is_show,is_del,is_postage'; + $model = new self(); + $valid = $invalid = []; + $model = $model->where('uid',$uid)->where('type','product')->where('is_pay',0) + ->where('is_del',0); + if($cartIds) $model->where('id','IN',$cartIds); + $list = $model->select()->toArray(); + if(!count($list)) return compact('valid','invalid'); + foreach ($list as $k=>$cart){ + $product = StoreProduct::field($productInfoField) + ->find($cart['product_id'])->toArray(); + $cart['productInfo'] = $product; + //商品不存在 + if(!$product){ + $model->where('id',$cart['id'])->update(['is_del'=>1]); + //商品删除或无库存 + }else if(!$product['is_show'] || $product['is_del'] || !$product['stock']){ + $invalid[] = $cart; + //商品属性不对应 +// }else if(!StoreProductAttr::issetProductUnique($cart['product_id'],$cart['product_attr_unique'])){ +// $invalid[] = $cart; + //正常商品 + }else{ + $cart['truePrice'] = (float)StoreCombination::where('id',$cart['combination_id'])->value('price'); + $cart['costPrice'] = (float)StoreCombination::where('id',$cart['combination_id'])->value('cost'); + $cart['trueStock'] = StoreCombination::where('id',$cart['combination_id'])->value('stock'); + $valid[] = $cart; + } + } + + foreach ($valid as $k=>$cart){ + if($cart['trueStock'] < $cart['cart_num']){ + $cart['cart_num'] = $cart['trueStock']; + $model->where('id',$cart['id'])->update(['cart_num'=>$cart['cart_num']]); + $valid[$k] = $cart; + } + } + + return compact('valid','invalid'); + } + + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreCategory.php b/application/wap/model/store/StoreCategory.php new file mode 100644 index 00000000..654e47d7 --- /dev/null +++ b/application/wap/model/store/StoreCategory.php @@ -0,0 +1,32 @@ + + * @day: 2017/12/12 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; + +class StoreCategory extends ModelBasic +{ + public static function pidByCategory($pid,$field = '*',$limit = 0) + { + $model = self::where('pid',$pid)->where('is_show',1)->field($field); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function pidBySidList($pid) + { + return self::where('pid',$pid)->column('id'); + } + + public static function cateIdByPid($cateId) + { + return self::where('id',$cateId)->value('pid'); + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreCombination.php b/application/wap/model/store/StoreCombination.php new file mode 100644 index 00000000..5f0477ba --- /dev/null +++ b/application/wap/model/store/StoreCombination.php @@ -0,0 +1,170 @@ + + * @day: 2017/11/11 + */ + +namespace app\wap\model\store; + + +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 拼团model + * Class StoreCombination + * @package app\admin\model\store + */ +class StoreCombination extends ModelBasic +{ + use ModelTrait; + + /** + * @param $where + * @return array + */ + public static function get_list($length=10){ + if($post=input('post.')){ + $where=$post['where']; + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->where('c.is_show',1)->where('c.is_del',0)->where('c.start_time','LT',time())->where('c.stop_time','GT',time()); + if(!empty($where['search'])){ + $model = $model->where('c.title','like',"%{$where['search']}%"); + $model = $model->whereOr('s.keyword','like',"{$where['search']}%"); + } + $model = $model->field('c.*,s.price as product_price'); + if($where['key']){ + if($where['sales']==1){ + $model = $model->order('c.sales desc'); + }else if($where['sales']==2){ + $model = $model->order('c.sales asc'); + } + if($where['price']==1){ + $model = $model->order('c.price desc'); + }else if($where['price']==2){ + $model = $model->order('c.price asc'); + } + if($where['people']==1){ + $model = $model->order('c.people asc'); + } + if($where['default']==1){ + $model = $model->order('c.sort desc,c.id desc'); + } + }else{ + $model = $model->order('c.sort desc,c.id desc'); + } + $page=is_string($where['page'])?(int)$where['page']+1:$where['page']+1; + $list = $model->page($page,$length)->select()->toArray(); + return ['list'=>$list,'page'=>$page]; + } + } + /** + * 获取所有拼团数据 + * @param int $limit + * @param int $length + * @return mixed + */ + public static function getAll($limit = 0,$length = 0){ + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->field('c.*,s.price as product_price'); + $model = $model->order('c.sort desc,c.id desc'); + $model = $model->where('c.is_show',1); + $model = $model->where('c.is_del',0); + $model = $model->where('c.start_time','LT',time()); + $model = $model->where('c.stop_time','GT',time()); + if($limit && $length) $model = $model->limit($limit,$length); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + /** + * 获取一条拼团数据 + * @param $id + * @return mixed + */ + public static function getCombinationOne($id){ + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->field('c.*,s.price as product_price,s.cate_id'); + $model = $model->where('c.is_show',1); + $model = $model->where('c.is_del',0); + $model = $model->where('c.id',$id); + $model = $model->where('c.start_time','LT',time()); + $model = $model->where('c.stop_time','GT',time()-86400); + $list = $model->find(); + if($list) return $list->toArray(); + else return []; + } + /** + * 获取产品状态 + * @param $id + * @return mixed + */ + public static function isValidCombination($id){ + $model = new self(); + $model = $model->where('id',$id); + $model = $model->where('is_del',0); + $model = $model->where('is_show',1); + return $model->count(); + } + /** + * 判断库存是否足够 + * @param $id + * @param $cart_num + * @return int|mixed + */ + public static function getCombinationStock($id,$cart_num){ + $stock = self::where('id',$id)->value('stock'); + return $stock > $cart_num ? $stock : 0; + } + + /** + * 获取推荐的拼团产品 + * @return mixed + */ + public static function getCombinationHost($limit = 0){ + $model = new self(); + $model = $model->alias('c'); + $model = $model->join('StoreProduct s','s.id=c.product_id'); + $model = $model->field('c.id,c.image,c.price,c.sales,c.title,c.people,s.price as product_price'); + $model = $model->where('c.is_del',0); + $model = $model->where('c.is_host',1); + $model = $model->where('c.is_show',1); + $model = $model->where('c.start_time','LT',time()); + $model = $model->where('c.stop_time','GT',time()); + if($limit) $model = $model->limit($limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 修改销量和库存 + * @param $num + * @param $CombinationId + * @return bool + */ + public static function decCombinationStock($num,$CombinationId) + { + $res = false !== self::where('id',$CombinationId)->dec('stock',$num)->inc('sales',$num)->update(); + return $res; + } + + /** + * 增加浏览量 + * @param int $id + * @return bool + */ + public static function editIncBrowse($id = 0){ + if(!$id) return false; + $browse = self::where('id',$id)->value('browse'); + $browse = bcadd($browse,1,0); + self::edit(['browse'=>$browse],$id); + } +} \ No newline at end of file diff --git a/application/wap/model/store/StoreCoupon.php b/application/wap/model/store/StoreCoupon.php new file mode 100644 index 00000000..fac3354d --- /dev/null +++ b/application/wap/model/store/StoreCoupon.php @@ -0,0 +1,17 @@ + + * @day: 2018/01/22 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCoupon extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/wap/model/store/StoreCouponIssue.php b/application/wap/model/store/StoreCouponIssue.php new file mode 100644 index 00000000..fed9e52a --- /dev/null +++ b/application/wap/model/store/StoreCouponIssue.php @@ -0,0 +1,63 @@ + + * @day: 2018/01/18 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use think\Db; +use traits\ModelTrait; + +class StoreCouponIssue extends ModelBasic +{ + use ModelTrait; + + /** + * @param string $prefix + * @return $this + */ + public static function validWhere($prefix = '') + { + $model = new self; + if($prefix){ + $model->alias($prefix); + $prefix .= '.'; + } + $newTime = time(); + return $model->where("{$prefix}status",1) + ->where(function($query) use($newTime,$prefix){ + $query->where(function($query) use($newTime,$prefix){ + $query->where("{$prefix}start_time",'<',$newTime)->where("{$prefix}end_time",'>',$newTime); + })->whereOr(function ($query) use($prefix){ + $query->where("{$prefix}start_time",0)->where("{$prefix}end_time",0); + }); + })->where("{$prefix}is_del",0); + } + + + public static function issueUserCoupon($id,$uid) + { + $issueCouponInfo = self::validWhere()->where('id',$id)->find(); + if(!$issueCouponInfo) return self::setErrorInfo('领取的优惠劵已领完或已过期!'); + if(StoreCouponIssueUser::be(['uid'=>$uid,'issue_coupon_id'=>$id])) + return self::setErrorInfo('已领取过该优惠劵!'); + self::beginTrans(); + if($issueCouponInfo['is_permanent']==0 && $issueCouponInfo['total_count'] ==0) + return self::setErrorInfo('该优惠劵已领完'); + $res1 = false != StoreCouponUser::addUserCoupon($uid,$issueCouponInfo['cid']); + $res2 = false != StoreCouponIssueUser::addUserIssue($uid,$id); + $res3 = false; + if($issueCouponInfo['total_count'] > 0){ + $issueCouponInfo['remain_count'] -= 1; + $res3 = false !== $issueCouponInfo->save(); + } + $res = $res1 && $res2 & $res3; + self::checkTrans($res); + return $res; + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreCouponIssueUser.php b/application/wap/model/store/StoreCouponIssueUser.php new file mode 100644 index 00000000..7712dfb1 --- /dev/null +++ b/application/wap/model/store/StoreCouponIssueUser.php @@ -0,0 +1,22 @@ + + * @day: 2018/01/22 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponIssueUser extends ModelBasic +{ + use ModelTrait; + public static function addUserIssue($uid,$issue_coupon_id) + { + $add_time = time(); + return self::set(compact('uid','issue_coupon_id','add_time')); + } +} \ No newline at end of file diff --git a/application/wap/model/store/StoreCouponUser.php b/application/wap/model/store/StoreCouponUser.php new file mode 100644 index 00000000..b6a74c60 --- /dev/null +++ b/application/wap/model/store/StoreCouponUser.php @@ -0,0 +1,113 @@ + + * @day: 2017/12/20 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreCouponUser extends ModelBasic +{ + use ModelTrait; + + public static function getUserAllCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + + public static function getUserValidCoupon($uid) + { + self::checkInvalidCoupon(); + $couponList = self::where('uid',$uid)->where('status',0)->order('is_fail ASC,status ASC,add_time DESC')->select()->toArray(); + return self::tidyCouponList($couponList); + } + + public static function beUsableCoupon($uid,$price) + { + if(is_array($price)) return self::where('uid',$uid)->where('is_fail',0)->where('status',0)->where('use_min_price','<=',$price['totalPrice'])->find(); + else return self::where('uid',$uid)->where('is_fail',0)->where('status',0)->where('use_min_price','<=',$price)->find(); + + } + + public static function validAddressWhere($model=null,$prefix = '') + { + self::checkInvalidCoupon(); + if($prefix) $prefix .='.'; + $model = self::getSelfModel($model); + return $model->where("{$prefix}is_fail",0)->where("{$prefix}status",0); + } + + public static function checkInvalidCoupon() + { + self::where('end_time','<',time())->where('status',0)->update(['status'=>2]); + } + + public static function tidyCouponList($couponList) + { + $time = time(); + foreach ($couponList as $k=>$coupon){ + $coupon['_add_time'] = date('Y/m/d',$coupon['add_time']); + $coupon['_end_time'] = date('Y/m/d',$coupon['end_time']); + $coupon['use_min_price'] = floatval($coupon['use_min_price']); + $coupon['coupon_price'] = floatval($coupon['coupon_price']); + if($coupon['is_fail']){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已失效'; + }else if ($coupon['status'] == 1){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已使用'; + }else if ($coupon['status'] == 2){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已过期'; + }else if($coupon['add_time'] > $time || $coupon['end_time'] < $time){ + $coupon['_type'] = 0; + $coupon['_msg'] = '已过期'; + }else{ + if($coupon['add_time']+ 3600*24 > $time){ + $coupon['_type'] = 2; + $coupon['_msg'] = '可使用'; + }else{ + $coupon['_type'] = 1; + $coupon['_msg'] = '可使用'; + } + } + $couponList[$k] = $coupon; + } + return $couponList; + } + + public static function getUserValidCouponCount($uid) + { + self::checkInvalidCoupon(); + return self::where('uid',$uid)->where('status',0)->order('is_fail ASC,status ASC,add_time DESC')->count(); + } + + public static function useCoupon($id) + { + return self::where('id',$id)->update(['status'=>1,'use_time'=>time()]); + } + + public static function addUserCoupon($uid,$cid,$type = 'get') + { + $couponInfo = StoreCoupon::find($cid); + if(!$couponInfo) return self::setErrorInfo('优惠劵不存在!'); + $data = []; + $data['cid'] = $couponInfo['id']; + $data['uid'] = $uid; + $data['coupon_title'] = $couponInfo['title']; + $data['coupon_price'] = $couponInfo['coupon_price']; + $data['use_min_price'] = $couponInfo['use_min_price']; + $data['add_time'] = time(); + $data['end_time'] = $couponInfo['add_time']+$couponInfo['coupon_time']*86400; + $data['type'] = $type; + return self::set($data); + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreOrder.php b/application/wap/model/store/StoreOrder.php new file mode 100644 index 00000000..4cb95cd4 --- /dev/null +++ b/application/wap/model/store/StoreOrder.php @@ -0,0 +1,735 @@ + + * @day: 2017/12/20 + */ + +namespace app\wap\model\store; + + +use app\wap\model\store\StoreCombination; +use app\wap\model\store\StoreOrderCartInfo; +use app\wap\model\store\StoreOrderStatus; +use app\wap\model\store\StoreProductReply; +use app\wap\model\user\User; +use app\wap\model\user\UserAddress; +use app\wap\model\user\UserBill; +use app\wap\model\user\WechatUser; +use basic\ModelBasic; +use behavior\wap\StoreProductBehavior; +use behavior\wechat\PaymentBehavior; +use service\HookService; +use service\JsonService; +use service\SystemConfigService; +use service\UtilService; +use service\WechatService; +use service\WechatTemplateService; +use think\Cache; +use think\Db; +use think\Request; +use think\Url; +use traits\ModelTrait; + +class StoreOrder extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected static $payType = ['weixin'=>'微信支付','yue'=>'余额支付','offline'=>'线下支付']; + + protected static $deliveryType = ['send'=>'商家配送','express'=>'快递配送']; + + protected function setAddTimeAttr() + { + return time(); + } + + protected function setCartIdAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + protected function getCartIdAttr($value) + { + return json_decode($value,true); + } + + public static function getOrderPriceGroup($cartInfo) + { + $storePostage = floatval(SystemConfigService::get('store_postage'))?:0; + $storeFreePostage = floatval(SystemConfigService::get('store_free_postage'))?:0; + $totalPrice = self::getOrderTotalPrice($cartInfo); + $costPrice = self::getOrderCostPrice($cartInfo); + if(!$storeFreePostage) { + $storePostage = 0; + }else{ + foreach ($cartInfo as $cart){ + if(!$cart['productInfo']['is_postage']) + $storePostage = bcadd($storePostage,$cart['productInfo']['postage'],2); + + } + if($storeFreePostage <= $totalPrice) $storePostage = 0; + } + return compact('storePostage','storeFreePostage','totalPrice','costPrice'); + } + + public static function getOrderTotalPrice($cartInfo) + { + $totalPrice = 0; + foreach ($cartInfo as $cart){ + $totalPrice = bcadd($totalPrice,bcmul($cart['cart_num'],$cart['truePrice'],2),2); + } + return $totalPrice; + } + public static function getOrderCostPrice($cartInfo) + { + $costPrice=0; + foreach ($cartInfo as $cart){ + $costPrice = bcadd($costPrice,bcmul($cart['cart_num'],$cart['costPrice'],2),2); + } + return $costPrice; + } + + + + /** + * 拼团 + * @param $cartInfo + * @return array + */ + public static function getCombinationOrderPriceGroup($cartInfo) + { + $storePostage = floatval(SystemConfigService::get('store_postage'))?:0; + $storeFreePostage = floatval(SystemConfigService::get('store_free_postage'))?:0; + $totalPrice = self::getCombinationOrderTotalPrice($cartInfo); + $costPrice = self::getCombinationOrderCostPrice($cartInfo); + if(!$storeFreePostage) { + $storePostage = 0; + }else{ + foreach ($cartInfo as $cart){ + if(!StoreCombination::where('id',$cart['combination_id'])->value('is_postage')) + $storePostage = bcadd($storePostage,StoreCombination::where('id',$cart['combination_id'])->value('postage'),2); + } + if($storeFreePostage <= $totalPrice) $storePostage = 0; + } + return compact('storePostage','storeFreePostage','totalPrice','costPrice'); + } + + + /** + * 拼团价格 + * @param $cartInfo + * @return float + */ + public static function getCombinationOrderTotalPrice($cartInfo) + { + $totalPrice = 0; + foreach ($cartInfo as $cart){ + if($cart['combination_id']){ + $totalPrice = bcadd($totalPrice,bcmul($cart['cart_num'],StoreCombination::where('id',$cart['combination_id'])->value('price'),2),2); + } + } + return (float)$totalPrice; + } + public static function getCombinationOrderCostPrice($cartInfo) + { + $costPrice = 0; + foreach ($cartInfo as $cart){ + if($cart['combination_id']){ + $totalPrice = bcadd($costPrice,bcmul($cart['cart_num'],StoreCombination::where('id',$cart['combination_id'])->value('price'),2),2); + } + } + return (float)$costPrice; + } + + + public static function cacheOrderInfo($uid,$cartInfo,$priceGroup,$other = [],$cacheTime = 600) + { + $key = md5(time()); + Cache::set('user_order_'.$uid.$key,compact('cartInfo','priceGroup','other'),$cacheTime); + return $key; + } + + public static function getCacheOrderInfo($uid,$key) + { + $cacheName = 'user_order_'.$uid.$key; + if(!Cache::has($cacheName)) return null; + return Cache::get($cacheName); + } + + public static function clearCacheOrderInfo($uid,$key) + { + Cache::clear('user_order_'.$uid.$key); + } + + public static function cacheKeyCreateOrder($uid,$key,$addressId,$payType,$useIntegral = false,$couponId = 0,$mark = '',$combinationId = 0,$pinkId = 0,$seckill_id=0,$bargainId = 0) + { + if(!array_key_exists($payType,self::$payType)) return self::setErrorInfo('选择支付方式有误!'); + if(self::be(['unique'=>$key,'uid'=>$uid])) return self::setErrorInfo('请勿重复提交订单'); + $userInfo = User::getUserInfo($uid); + if(!$userInfo) return self::setErrorInfo('用户不存在!'); + $cartGroup = self::getCacheOrderInfo($uid,$key); + if(!$cartGroup) return self::setErrorInfo('订单已过期,请刷新当前页面!'); + $cartInfo = $cartGroup['cartInfo']; + $priceGroup = $cartGroup['priceGroup']; + $other = $cartGroup['other']; + $payPrice = $priceGroup['totalPrice']; + $payPostage = $priceGroup['storePostage']; + if(!$addressId) return self::setErrorInfo('请选择收货地址!'); + if(!UserAddress::be(['uid'=>$uid,'id'=>$addressId,'is_del'=>0]) || !($addressInfo = UserAddress::find($addressId))) + return self::setErrorInfo('地址选择有误!'); + + //使用优惠劵 + $res1 = true; + if($couponId){ + $couponInfo = StoreCouponUser::validAddressWhere()->where('id',$couponId)->where('uid',$uid)->find(); + if(!$couponInfo) return self::setErrorInfo('选择的优惠劵无效!'); + if($couponInfo['use_min_price'] > $payPrice) + return self::setErrorInfo('不满足优惠劵的使用条件!'); + $payPrice = bcsub($payPrice,$couponInfo['coupon_price'],2); + $res1 = StoreCouponUser::useCoupon($couponId); + $couponPrice = $couponInfo['coupon_price']; + }else{ + $couponId = 0; + $couponPrice = 0; + } + if(!$res1) return self::setErrorInfo('使用优惠劵失败!'); + + //是否包邮 + if((isset($other['offlinePostage']) && $other['offlinePostage'] && $payType == 'offline')) $payPostage = 0; + $payPrice = bcadd($payPrice,$payPostage,2); + //积分抵扣 + $res2 = true; + if($useIntegral && $userInfo['integral'] > 0){ + $deductionPrice = bcmul($userInfo['integral'],$other['integralRatio'],2); + if($deductionPrice < $payPrice){ + $payPrice = bcsub($payPrice,$deductionPrice,2); + $usedIntegral = $userInfo['integral']; + $res2 = false !== User::edit(['integral'=>0],$userInfo['uid'],'uid'); + }else{ + $deductionPrice = $payPrice; + $usedIntegral = bcdiv($payPrice,$other['integralRatio'],2); + $res2 = false !== User::bcDec($userInfo['uid'],'integral',$usedIntegral,'uid'); + $payPrice = 0; + } + $res2 = $res2 && false != UserBill::expend('积分抵扣',$uid,'integral','deduction',$usedIntegral,$key,$userInfo['integral'],'购买商品使用'.floatval($usedIntegral).'积分抵扣'.floatval($deductionPrice).'元'); + }else{ + $deductionPrice = 0; + $usedIntegral = 0; + } + if(!$res2) return self::setErrorInfo('使用积分抵扣失败!'); + + $cartIds = []; + $totalNum = 0; + $gainIntegral = 0; + foreach ($cartInfo as $cart){ + $cartIds[] = $cart['id']; + $totalNum += $cart['cart_num']; + $gainIntegral = bcadd($gainIntegral,$cart['productInfo']['give_integral'],2); + } + $orderInfo = [ + 'uid'=>$uid, + 'order_id'=>self::getNewOrderId(), + 'real_name'=>$addressInfo['real_name'], + 'user_phone'=>$addressInfo['phone'], + 'user_address'=>$addressInfo['province'].' '.$addressInfo['city'].' '.$addressInfo['district'].' '.$addressInfo['detail'], + 'cart_id'=>$cartIds, + 'total_num'=>$totalNum, + 'total_price'=>$priceGroup['totalPrice'], + 'total_postage'=>$priceGroup['storePostage'], + 'coupon_id'=>$couponId, + 'coupon_price'=>$couponPrice, + 'pay_price'=>$payPrice, + 'pay_postage'=>$payPostage, + 'deduction_price'=>$deductionPrice, + 'paid'=>0, + 'pay_type'=>$payType, + 'use_integral'=>$usedIntegral, + 'gain_integral'=>$gainIntegral, + 'mark'=>htmlspecialchars($mark), + 'combination_id'=>$combinationId, + 'pink_id'=>$pinkId, + 'seckill_id'=>$seckill_id, + 'bargain_id'=>$bargainId, + 'cost'=>$priceGroup['costPrice'], + 'unique'=>$key + ]; + $order = self::set($orderInfo); + if(!$order)return self::setErrorInfo('订单生成失败!'); + $res5 = true; + foreach ($cartInfo as $cart){ + //减库存加销量 + if($combinationId) $res5 = $res5 && StoreCombination::decCombinationStock($cart['cart_num'],$combinationId); + else if($seckill_id) $res5 = $res5 && StoreSeckill::decSeckillStock($cart['cart_num'],$seckill_id); + else if($bargainId) $res5 = $res5 && StoreBargain::decBargainStock($cart['cart_num'],$bargainId); + else $res5 = $res5 && StoreProduct::decProductStock($cart['cart_num'],$cart['productInfo']['id'],isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique']:''); + + } + //保存购物车商品信息 + $res4 = false !== StoreOrderCartInfo::setCartInfo($order['id'],$cartInfo); + //购物车状态修改 + $res6 = false !== StoreCart::where('id','IN',$cartIds)->update(['is_pay'=>1]); + if(!$res4 || !$res5 || !$res6) return self::setErrorInfo('订单生成失败!'); + try{ + HookService::listen('store_product_order_create',$order,compact('cartInfo','addressId'),false,StoreProductBehavior::class); + }catch (\Exception $e){ + return self::setErrorInfo($e->getMessage()); + } + self::clearCacheOrderInfo($uid,$key); + self::commitTrans(); + StoreOrderStatus::status($order['id'],'cache_key_create_order','订单生成'); + return $order; + } + + public static function getNewOrderId() + { + $count = (int) self::where('add_time',['>=',strtotime(date("Y-m-d"))],['<',strtotime(date("Y-m-d",strtotime('+1 day')))])->count(); + return 'wx'.date('YmdHis',time()).(10000+$count+1); + } + + public static function changeOrderId($orderId) + { + $ymd = substr($orderId,2,8); + $key = substr($orderId,16); + return 'wx'.$ymd.date('His').$key; + } + + public static function jsPay($orderId,$field = 'order_id') + { + if(is_string($orderId)) + $orderInfo = self::where($field,$orderId)->find(); + else + $orderInfo = $orderId; + if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!'); + if($orderInfo['paid']) exception('支付已支付!'); + if($orderInfo['pay_price'] <= 0) exception('该支付无需支付!'); + $openid = WechatUser::uidToOpenid($orderInfo['uid']); + return WechatService::jsPay($openid,$orderInfo['order_id'],$orderInfo['pay_price'],'product',SystemConfigService::get('site_name')); + } + + public static function yuePay($order_id,$uid) + { + $orderInfo = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->find(); + if(!$orderInfo) return self::setErrorInfo('订单不存在!'); + if($orderInfo['paid']) return self::setErrorInfo('该订单已支付!'); + if($orderInfo['pay_type'] != 'yue') return self::setErrorInfo('该订单不能使用余额支付!'); + $userInfo = User::getUserInfo($uid); + if($userInfo['now_money'] < $orderInfo['pay_price']) + return self::setErrorInfo('余额不足'.floatval($orderInfo['pay_price'])); + self::beginTrans(); + $res1 = false !== User::bcDec($uid,'now_money',$orderInfo['pay_price'],'uid'); + $res2 = UserBill::expend('购买商品',$uid,'now_money','pay_product',$orderInfo['pay_price'],$orderInfo['id'],$userInfo['now_money'],'余额支付'.floatval($orderInfo['pay_price']).'元购买商品'); + $res3 = self::paySuccess($order_id); + try{ + HookService::listen('yue_pay_product',$userInfo,$orderInfo,false,PaymentBehavior::class); + }catch (\Exception $e){ + self::rollbackTrans(); + return self::setErrorInfo($e->getMessage()); + } + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + } + + /** + * 微信支付 为 0元时 + * @param $order_id + * @param $uid + * @return bool + */ + public static function jsPayPrice($order_id,$uid){ + $orderInfo = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->find(); + if(!$orderInfo) return self::setErrorInfo('订单不存在!'); + if($orderInfo['paid']) return self::setErrorInfo('该订单已支付!'); + $userInfo = User::getUserInfo($uid); + self::beginTrans(); + $res1 = UserBill::expend('购买商品',$uid,'now_money','pay_product',$orderInfo['pay_price'],$orderInfo['id'],$userInfo['now_money'],'微信支付'.floatval($orderInfo['pay_price']).'元购买商品'); + $res2 = self::paySuccess($order_id); + $res = $res1 && $res2; + self::checkTrans($res); + return $res; + } + + public static function yueRefundAfter($order) + { + + } + + /** + * 用户申请退款 + * @param $uni + * @param $uid + * @param string $refundReasonWap + * @return bool + */ + public static function orderApplyRefund($uni, $uid,$refundReasonWap = '') + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('支付订单不存在!'); + if($order['refund_status'] == 2) return self::setErrorInfo('订单已退款!'); + if($order['refund_status'] == 1) return self::setErrorInfo('正在申请退款中!'); + if($order['status'] == 1) return self::setErrorInfo('订单当前无法退款!'); + self::beginTrans(); + $res1 = false !== StoreOrderStatus::status($order['id'],'apply_refund','用户申请退款,原因:'.$refundReasonWap); + $res2 = false !== self::edit(['refund_status'=>1,'refund_reason_wap'=>$refundReasonWap],$order['id'],'id'); + $res = $res1 && $res2; + self::checkTrans($res); + if(!$res) + return self::setErrorInfo('申请退款失败!'); + else{ + try{ + HookService::afterListen('store_product_order_apply_refund',$order['id'],$uid,false,StoreProductBehavior::class); + }catch (\Exception $e){} + return true; + } + } + + /** + * //TODO 支付成功后 + * @param $orderId + * @param $notify + * @return bool + */ + public static function paySuccess($orderId) + { + $order = self::where('order_id',$orderId)->find(); + $resPink = true; + User::bcInc($order['uid'],'pay_count',1,'uid'); + $res1 = self::where('order_id',$orderId)->update(['paid'=>1,'pay_time'=>time()]); + if($order->combination_id && $res1 && !$order->refund_status) $resPink = StorePink::createPink($order);//创建拼团 + $oid = self::where('order_id',$orderId)->value('id'); + StoreOrderStatus::status($oid,'pay_success','用户付款成功'); + WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($order['uid']),WechatTemplateService::ORDER_PAY_SUCCESS, [ + 'first'=>'亲,您购买的商品已支付成功', + 'keyword1'=>$orderId, + 'keyword2'=>$order['pay_price'], + 'remark'=>'点击查看订单详情' + ],Url::build('wap/My/order',['uni'=>$orderId],true,true)); + WechatTemplateService::sendAdminNoticeTemplate([ + 'first'=>"亲,您有一个新订单 \n订单号:{$order['order_id']}", + 'keyword1'=>'新订单', + 'keyword2'=>'已支付', + 'keyword3'=>date('Y/m/d H:i',time()), + 'remark'=>'请及时处理' + ]); + $res = $res1 && $resPink; + return false !== $res; + } + + public static function createOrderTemplate($order) + { + $goodsName = StoreOrderCartInfo::getProductNameList($order['id']); + WechatTemplateService::sendTemplate(WechatUser::uidToOpenid($order['uid']),WechatTemplateService::ORDER_CREATE, [ + 'first'=>'亲,您购买的商品已支付成功', + 'keyword1'=>date('Y/m/d H:i',$order['add_time']), + 'keyword2'=>implode(',',$goodsName), + 'keyword3'=>$order['order_id'], + 'remark'=>'点击查看订单详情' + ],Url::build('/wap/My/order',['uni'=>$order['order_id']],true,true)); + WechatTemplateService::sendAdminNoticeTemplate([ + 'first'=>"亲,您有一个新订单 \n订单号:{$order['order_id']}", + 'keyword1'=>'新订单', + 'keyword2'=>'线下支付', + 'keyword3'=>date('Y/m/d H:i',time()), + 'remark'=>'请及时处理' + ]); + } + + public static function getUserOrderDetail($uid,$key) + { + return self::where('order_id|unique',$key)->where('uid',$uid)->where('is_del',0)->find(); + } + + + /** + * TODO 订单发货 + * @param array $postageData 发货信息 + * @param string $oid orderID + */ + public static function orderPostageAfter($postageData, $oid) + { + $order = self::where('id',$oid)->find(); + $openid = WechatUser::uidToOpenid($order['uid']); + $url = Url::build('wap/My/order',['uni'=>$order['order_id']],true,true); + $group = [ + 'first'=>'亲,您的订单已发货,请注意查收', + 'remark'=>'点击查看订单详情' + ]; + if($postageData['delivery_type'] == 'send'){//送货 + $goodsName = StoreOrderCartInfo::getProductNameList($order['id']); + $group = array_merge($group,[ + 'keyword1'=>$goodsName, + 'keyword2'=>$order['pay_type'] == 'offline' ? '线下支付' : date('Y/m/d H:i',$order['pay_time']), + 'keyword3'=>$order['user_address'], + 'keyword4'=>$postageData['delivery_name'], + 'keyword5'=>$postageData['delivery_id'] + ]); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_DELIVER_SUCCESS,$group,$url); + + }else if($postageData['delivery_type'] == 'express'){//发货 + $group = array_merge($group,[ + 'keyword1'=>$order['order_id'], + 'keyword2'=>$postageData['delivery_name'], + 'keyword3'=>$postageData['delivery_id'] + ]); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_POSTAGE_SUCCESS,$group,$url); + } + } + + public static function orderTakeAfter($order) + { + $openid = WechatUser::uidToOpenid($order['uid']); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_TAKE_SUCCESS,[ + 'first'=>'亲,您的订单以成功签收,快去评价一下吧', + 'keyword1'=>$order['order_id'], + 'keyword2'=>'已收货', + 'keyword3'=>date('Y/m/d H:i',time()), + 'keyword4'=>implode(',',StoreOrderCartInfo::getProductNameList($order['id'])), + 'remark'=>'点击查看订单详情' + ],Url::build('My/order',['uni'=>$order['order_id']],true,true)); + } + + /** + * 删除订单 + * @param $uni + * @param $uid + * @return bool + */ + public static function removeOrder($uni, $uid) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('订单不存在!'); + $order = self::tidyOrder($order); + if($order['_status']['_type'] != 0 && $order['_status']['_type']!= -2 && $order['_status']['_type'] != 4) + return self::setErrorInfo('该订单无法删除!'); + if(false !== self::edit(['is_del'=>1],$order['id'],'id') && + false !==StoreOrderStatus::status($order['id'],'remove_order','删除订单')) + return true; + else + return self::setErrorInfo('订单删除失败!'); + } + + + /** + * //TODO 用户确认收货 + * @param $uni + * @param $uid + */ + public static function takeOrder($uni, $uid) + { + $order = self::getUserOrderDetail($uid,$uni); + if(!$order) return self::setErrorInfo('订单不存在!'); + $order = self::tidyOrder($order); + if($order['_status']['_type'] != 2) return self::setErrorInfo('订单状态错误!'); + self::beginTrans(); + if(false !== self::edit(['status'=>2],$order['id'],'id') && + false !== StoreOrderStatus::status($order['id'],'user_take_delivery','用户已收货')){ + try{ + HookService::listen('store_product_order_user_take_delivery',$order,$uid,false,StoreProductBehavior::class); + }catch (\Exception $e){ + return self::setErrorInfo($e->getMessage()); + } + self::commitTrans(); + return true; + }else{ + self::rollbackTrans(); + return false; + } + } + + public static function tidyOrder($order,$detail = false) + { + if($detail == true && isset($order['id'])){ + $cartInfo = self::getDb('StoreOrderCartInfo')->where('oid',$order['id'])->column('cart_info','unique')?:[]; + foreach ($cartInfo as $k=>$cart){ + $cartInfo[$k] = json_decode($cart, true); + $cartInfo[$k]['unique'] = $k; + } + $order['cartInfo'] = $cartInfo; + } + + $status = []; + if(!$order['paid'] && $order['pay_type'] == 'offline' && !$order['status'] >= 2){ + $status['_type'] = 9; + $status['_title'] = '线下付款'; + $status['_msg'] = '等待商家处理,请耐心等待'; + $status['_class'] = 'nobuy'; + }else if(!$order['paid']){ + $status['_type'] = 0; + $status['_title'] = '未支付'; + $status['_msg'] = '立即支付订单吧'; + $status['_class'] = 'nobuy'; + }else if($order['refund_status'] == 1){ + $status['_type'] = -1; + $status['_title'] = '申请退款中'; + $status['_msg'] = '商家审核中,请耐心等待'; + $status['_class'] = 'state-sqtk'; + }else if($order['refund_status'] == 2){ + $status['_type'] = -2; + $status['_title'] = '已退款'; + $status['_msg'] = '已为您退款,感谢您的支持'; + $status['_class'] = 'state-sqtk'; + }else if(!$order['status']){ + if($order['pink_id']){ + if(StorePink::where('id',$order['pink_id'])->where('status',1)->count()){ + $status['_type'] = 1; + $status['_title'] = '拼团中'; + $status['_msg'] = '等待其他人参加拼团'; + $status['_class'] = 'state-nfh'; + }else{ + $status['_type'] = 1; + $status['_title'] = '未发货'; + $status['_msg'] = '商家未发货,请耐心等待'; + $status['_class'] = 'state-nfh'; + } + }else{ + $status['_type'] = 1; + $status['_title'] = '未发货'; + $status['_msg'] = '商家未发货,请耐心等待'; + $status['_class'] = 'state-nfh'; + } + }else if($order['status'] == 1){ + $status['_type'] = 2; + $status['_title'] = '待收货'; + $status['_msg'] = date('m月d日H时i分',StoreOrderStatus::getTime($order['id'],'delivery_goods')).'服务商已发货'; + $status['_class'] = 'state-ysh'; + }else if($order['status'] == 2){ + $status['_type'] = 3; + $status['_title'] = '待评价'; + $status['_msg'] = '已收货,快去评价一下吧'; + $status['_class'] = 'state-ypj'; + }else if($order['status'] == 3){ + $status['_type'] = 4; + $status['_title'] = '交易完成'; + $status['_msg'] = '交易完成,感谢您的支持'; + $status['_class'] = 'state-ytk'; + } + if(isset($order['pay_type'])) + $status['_payType'] = isset(self::$payType[$order['pay_type']]) ? self::$payType[$order['pay_type']] : '其他方式'; + if(isset($order['delivery_type'])) + $status['_deliveryType'] = isset(self::$deliveryType[$order['delivery_type']]) ? self::$deliveryType[$order['delivery_type']] : '其他方式'; + $order['_status'] = $status; + return $order; + } + + public static function statusByWhere($status,$model = null) + { + $orderId = StorePink::where('uid',User::getActiveUid())->where('status',1)->column('order_id','id');//获取正在拼团的订单编号 + if($model == null) $model = new self; + if('' === $status) + return $model; + else if($status == 0) + return $model->where('paid',0)->where('status',0)->where('refund_status',0); + else if($status == 1)//待发货 + return $model->where('paid',1)->where('order_id','NOT IN',implode(',',$orderId))->where('status',0)->where('refund_status',0); + else if($status == 2) + return $model->where('paid',1)->where('status',1)->where('refund_status',0); + else if($status == 3) + return $model->where('paid',1)->where('status',2)->where('refund_status',0); + else if($status == 4) + return $model->where('paid',1)->where('status',3)->where('refund_status',0); + else if($status == -1) + return $model->where('paid',1)->where('refund_status',1); + else if($status == -2) + return $model->where('paid',1)->where('refund_status',2); + else if($status == 11){ + return $model->where('order_id','IN',implode(',',$orderId)); + } + else + return $model; + } + + public static function getUserOrderList($uid,$status = '',$first = 0,$limit = 8) + { + $list = self::statusByWhere($status)->where('is_del',0)->where('uid',$uid) + ->field('combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,pink_id,delivery_type') + ->order('add_time DESC')->limit($first,$limit)->select()->toArray(); + foreach ($list as $k=>$order){ + $list[$k] = self::tidyOrder($order,true); + } + return $list; + } + + public static function searchUserOrder($uid,$order_id) + { + $order = self::where('uid',$uid)->where('order_id',$order_id)->where('is_del',0)->field('combination_id,id,order_id,pay_price,total_num,total_price,pay_postage,total_postage,paid,status,refund_status,pay_type,coupon_price,deduction_price,delivery_type') + ->order('add_time DESC')->find(); + if(!$order) + return false; + else + return self::tidyOrder($order->toArray(),true); + + } + + public static function orderOver($oid) + { + $res = self::edit(['status'=>'3'],$oid,'id'); + if(!$res) exception('评价后置操作失败!'); + StoreOrderStatus::status($oid,'check_order_over','用户评价'); + } + + public static function checkOrderOver($oid) + { + $uniqueList = StoreOrderCartInfo::where('oid',$oid)->column('unique'); + if(StoreProductReply::where('unique','IN',$uniqueList)->where('oid',$oid)->count() == count($uniqueList)){ + HookService::listen('store_product_order_over',$oid,null,false,StoreProductBehavior::class); + self::orderOver($oid); + } + } + + + public static function getOrderStatusNum($uid) + { + $noBuy = self::where('uid',$uid)->where('paid',0)->where('is_del',0)->where('pay_type','<>','offline')->where('refund_status',0)->count(); + $noPostageNoPink = self::where('o.uid',$uid)->alias('o')->where('o.paid',1)->where('o.pink_id',0)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->where('o.refund_status',0)->count(); + $noPostageYesPink = self::where('o.uid',$uid)->alias('o')->join('StorePink p','o.pink_id = p.id')->where('p.status',2)->where('o.paid',1)->where('o.is_del',0)->where('o.status',0)->where('o.refund_status',0)->where('o.pay_type','<>','offline')->count(); + $noPostage = bcadd($noPostageNoPink,$noPostageYesPink); + $noTake = self::where('uid',$uid)->where('paid',1)->where('is_del',0)->where('status',1)->where('pay_type','<>','offline')->where('refund_status',0)->count(); + $noReply = self::where('uid',$uid)->where('paid',1)->where('is_del',0)->where('status',2)->where('refund_status',0)->count(); + $noPink = self::where('o.uid',$uid)->alias('o')->join('StorePink p','o.pink_id = p.id')->where('p.status',1)->where('o.paid',1)->where('o.is_del',0)->where('o.status',0)->where('o.pay_type','<>','offline')->where('o.refund_status',0)->count(); + return compact('noBuy','noPostage','noTake','noReply','noPink'); + } + + public static function gainUserIntegral($order) + { + if($order['gain_integral'] > 0){ + $userInfo = User::getUserInfo($order['uid']); + ModelBasic::beginTrans(); + $res1 = false != User::where('uid',$userInfo['uid'])->update(['integral'=>bcadd($userInfo['integral'],$order['gain_integral'],2)]); + $res2 = false != UserBill::income('购买商品赠送积分',$order['uid'],'integral','gain',$order['gain_integral'],$order['id'],$userInfo['integral'],'购买商品赠送'.floatval($order['gain_integral']).'积分'); + $res = $res1 && $res2; + ModelBasic::checkTrans($res); + return $res; + } + return true; + } + + /** + * 获取当前订单中有没有拼团存在 + * @param $pid + * @return int|string + */ + public static function getIsOrderPink($pid){ + $uid = User::getActiveUid(); + return self::where('uid',$uid)->where('pink_id',$pid)->where('refund_status',0)->where('is_del',0)->count(); + } + + /** + * 获取order_id + * @param $pid + * @return mixed + */ + public static function getStoreIdPink($pid){ + $uid = User::getActiveUid(); + return self::where('uid',$uid)->where('pink_id',$pid)->where('is_del',0)->value('order_id'); + } + + /** + * 删除当前用户拼团未支付的订单 + */ + public static function delCombination(){ + self::where('combination','GT',0)->where('paid',0)->where('uid',User::getActiveUid())->delete(); + } +} \ No newline at end of file diff --git a/application/wap/model/store/StoreOrderCartInfo.php b/application/wap/model/store/StoreOrderCartInfo.php new file mode 100644 index 00000000..83874e8a --- /dev/null +++ b/application/wap/model/store/StoreOrderCartInfo.php @@ -0,0 +1,49 @@ + + * @day: 2017/12/26 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreOrderCartInfo extends ModelBasic +{ + use ModelTrait; + + public static function getCartInfoAttr($value) + { + return json_decode($value,true)?:[]; + } + + public static function setCartInfo($oid,array $cartInfo) + { + $group = []; + foreach ($cartInfo as $cart){ + $group[] = [ + 'oid'=>$oid, + 'cart_id'=>$cart['id'], + 'product_id'=>$cart['productInfo']['id'], + 'cart_info'=>json_encode($cart), + 'unique'=>md5($cart['id'].''.$oid) + ]; + } + return self::setAll($group); + } + + public static function getProductNameList($oid) + { + $cartInfo = self::where('oid',$oid)->select(); + $goodsName = []; + foreach ($cartInfo as $cart){ + $suk = isset($cart['cart_info']['productInfo']['attrInfo']) ? '('.$cart['cart_info']['productInfo']['attrInfo']['suk'].')' : ''; + $goodsName[] = $cart['cart_info']['productInfo']['store_name'].$suk; + } + return $goodsName; + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreOrderStatus.php b/application/wap/model/store/StoreOrderStatus.php new file mode 100644 index 00000000..2cff92e1 --- /dev/null +++ b/application/wap/model/store/StoreOrderStatus.php @@ -0,0 +1,29 @@ + + * @day: 2017/12/28 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreOrderStatus extends ModelBasic +{ + use ModelTrait; + + public static function status($oid,$change_type,$change_message,$change_time = null) + { + if($change_time == null) $change_time = time(); + return self::set(compact('oid','change_type','change_message','change_time')); + } + + public static function getTime($oid,$change_type) + { + return self::where('oid',$oid)->where('change_type',$change_type)->value('change_time'); + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StorePink.php b/application/wap/model/store/StorePink.php new file mode 100644 index 00000000..312fe9e5 --- /dev/null +++ b/application/wap/model/store/StorePink.php @@ -0,0 +1,343 @@ + + * @day: 2017/12/18 + */ + +namespace app\wap\model\store; + +use app\wap\model\store\StoreCombination; +use app\wap\model\user\User; +use app\wap\model\user\WechatUser; +use basic\ModelBasic; +use service\WechatTemplateService; +use think\Url; +use traits\ModelTrait; + +/** + * 拼团Model + * Class StorePink + * @package app\wap\model\store + */ +class StorePink extends ModelBasic +{ + use ModelTrait; + + + /** + * 获取一条拼团数据 + * @param $id + * @return mixed + */ + public static function getPinkUserOne($id){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('id',$id); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $list = $model->find(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取拼团的团员 + * @param $id + * @return mixed + */ + public static function getPinkMember($id){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('k_id',$id); + $model = $model->where('is_refund',0); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $model = $model->order('id asc'); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 设置结束时间 + * @param $idAll + * @return $this + */ + public static function setPinkStopTime($idAll){ + $model = new self(); + $model = $model->where('id','IN',$idAll); + return $model->update(['stop_time'=>time(),'status'=>2]); + } + + /** + * 获取正在拼团的数据 团长 + * @return mixed + */ + public static function getPinkAll($cid){ + $model = new self(); + $model = $model->alias('p'); + $model = $model->field('p.*,u.nickname,u.avatar'); + $model = $model->where('stop_time','GT',time()); + $model = $model->where('cid',$cid); + $model = $model->where('k_id',0); + $model = $model->where('is_refund',0); + $model = $model->order('add_time desc'); + $model = $model->join('__USER__ u','u.uid = p.uid'); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取还差几人 + */ + public static function getPinkPeople($kid,$people){ + $model = new self(); + $model = $model->where('k_id',$kid)->where('is_refund',0); + $count = bcadd($model->count(),1,0); + return bcsub($people,$count,0); + } + + /** + * 判断订单是否在当前的拼团中 + * @param $orderId + * @param $kid + * @return bool + */ + public static function getOrderIdAndPink($orderId,$kid){ + $model = new self(); + $pink = $model->where('k_id',$kid)->whereOr('id',$kid)->column('order_id'); + if(in_array($orderId,$pink))return true; + else return false; + } + + /** + * 判断用户是否在团内 + * @param $id + * @return int|string + */ + public static function getIsPinkUid($id){ + $uid = User::getActiveUid(); + $pinkT = self::where('id',$id)->where('uid',$uid)->where('is_refund',0)->count(); + $pink = self::whereOr('k_id',$id)->where('uid',$uid)->where('is_refund',0)->count(); + if($pinkT) return true; + if($pink) return true; + else return false; + } + + + /** + * 判断是否发送模板消息 0 未发送 1已发送 + * @param $uidAll + * @return int|string + */ + public static function isTpl($uidAll,$pid){ + if(is_array($uidAll)){ + $countK = self::where('uid','IN',implode(',',$uidAll))->where('is_tpl',0)->where('id',$pid)->count(); + $count = self::where('uid','IN',implode(',',$uidAll))->where('is_tpl',0)->where('k_id',$pid)->count(); + } + else { + $countK = self::where('uid',$uidAll)->where('is_tpl',0)->where('id',$pid)->count(); + $count = self::where('uid',$uidAll)->where('is_tpl',0)->where('k_id',$pid)->count(); + } + return bcadd($countK,$count,0); + } + /** + * 拼团成功提示模板消息 + * @param $uidAll + * @param $pid + */ + public static function orderPinkAfter($uidAll,$pid){ + foreach ($uidAll as $v){ + $openid = WechatUser::uidToOpenid($v); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_SUCCESS,[ + 'first'=>'亲,您的拼团已经完成了', + 'keyword1'=> self::where('id',$pid)->whereOr('k_id',$pid)->where('uid',$v)->value('order_id'), + 'keyword2'=> self::alias('p')->where('p.id',$pid)->whereOr('p.k_id',$pid)->where('p.uid',$v)->join('__STORE_COMBINATION__ c','c.id=p.cid')->value('c.title'), + 'remark'=>'点击查看订单详情' + ],Url::build('My/order_pink_after',['id'=>$pid],true,true)); + } + self::where('uid','IN',implode(',',$uidAll))->where('id',$pid)->whereOr('k_id',$pid)->update(['is_tpl'=>1]); + } + + /** + * 拼团失败发送的模板消息 + * @param $uid + * @param $pid + */ + public static function orderPinkAfterNo($uid,$pid){ + $openid = WechatUser::uidToOpenid($uid); + WechatTemplateService::sendTemplate($openid,WechatTemplateService::ORDER_USER_GROUPS_LOSE,[ + 'first'=>'亲,您的拼团失败', + 'keyword1'=> self::alias('p')->where('p.id',$pid)->whereOr('p.k_id',$pid)->where('p.uid',$uid)->join('__STORE_COMBINATION__ c','c.id=p.cid')->value('c.title'), + 'keyword2'=> self::where('id',$pid)->whereOr('k_id',$pid)->where('uid',$uid)->value('price'), + 'keyword3'=> self::alias('p')->where('p.id',$pid)->whereOr('p.k_id',$pid)->where('p.uid',$uid)->join('__STORE_ORDER__ c','c.order_id=p.order_id')->value('c.pay_price'), + 'remark'=>'点击查看订单详情' + ],Url::build('My/order_pink_after',['id'=>$pid],true,true)); + self::where('id',$pid)->update(['status'=>3]); + self::where('k_id',$pid)->update(['status'=>3]); + } + + /** + * 获取当前拼团数据返回订单编号 + * @param $id + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getCurrentPink($id){ + $uid = User::getActiveUid();//获取当前登录人的uid + $pink = self::where('id',$id)->where('uid',$uid)->find(); + if(!$pink) $pink = self::where('k_id',$id)->where('uid',$uid)->find(); + return StoreOrder::where('id',$pink['order_id_key'])->value('order_id'); + } + + public static function systemPage($where){ + $model = new self; + $model = $model->alias('p'); + $model = $model->field('p.*,c.title'); + if($where['data'] !== ''){ + list($startTime,$endTime) = explode(' - ',$where['data']); + $model = $model->where('p.add_time','>',strtotime($startTime)); + $model = $model->where('p.add_time','<',strtotime($endTime)); + } + if($where['status']) $model = $model->where('p.status',$where['status']); + $model = $model->where('p.k_id',0); + $model = $model->order('p.id desc'); + $model = $model->join('StoreCombination c','c.id=p.cid'); + return self::page($model,function($item)use($where){ + $item['count_people'] = bcadd(self::where('k_id',$item['id'])->count(),1,0); + },$where); + } + + public static function isPinkBe($data,$id){ + $data['id'] = $id; + $count = self::where($data)->count(); + if($count) return $count; + $data['k_id'] = $id; + $count = self::where($data)->count(); + if($count) return $count; + else return 0; + } + public static function isPinkStatus($pinkId){ + if(!$pinkId) return false; + $stopTime = self::where('id',$pinkId)->value('stop_time'); + if($stopTime < time()) return true; //拼团结束 + else return false;//拼团未结束 + } + + /** + * 判断拼团结束 后的状态 + * @param $pinkId + * @return bool + */ + public static function isSetPinkOver($pinkId){ + $people = self::where('id',$pinkId)->value('people'); + $stopTime = self::where('id',$pinkId)->value('stop_time'); + if($stopTime < time()){ + $countNum = self::getPinkPeople($pinkId,$people); + if($countNum) return false;//拼团失败 + else return true;//拼团成功 + }else return true; + } + + /** + * 拼团退款 + * @param $id + * @return bool + */ + public static function setRefundPink($oid){ + $res = true; + $order = StoreOrder::where('id',$oid)->find(); + if($order['pink_id']) $id = $order['pink_id']; + else return $res; + $count = self::where('id',$id)->where('uid',$order['uid'])->find();//正在拼团 团长 + $countY = self::where('k_id',$id)->where('uid',$order['uid'])->find();//正在拼团 团员 + if(!$count && !$countY) return $res; + if($count){//团长 + //判断团内是否还有其他人 如果有 团长为第二个进团的人 + $kCount = self::where('k_id',$id)->order('add_time asc')->find(); + if($kCount){ + $res11 = self::where('k_id',$id)->update(['k_id'=>$kCount['id']]); + $res12 = self::where('id',$kCount['id'])->update(['stop_time'=>$count['add_time']+86400,'k_id'=>0]); + $res1 = $res11 && $res12; + $res2 = self::where('id',$id)->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$kCount['id'],'status'=>3]); + }else{ + $res1 = true; + $res2 = self::where('id',$id)->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$id,'status'=>3]); + } + //修改结束时间为前一秒 团长ID为0 + $res = $res1 && $res2; + }else if($countY){//团员 + $res = self::where('id',$countY['id'])->update(['stop_time'=>time()-1,'k_id'=>0,'is_refund'=>$id,'status'=>3]); + } + return $res; + + } + + + + /** + * 拼团人数完成时,判断全部人都是未退款状态 + * @param $pinkIds + * @return bool + */ + public static function setPinkStatus($pinkIds){ + $orderPink = self::where('id','IN',$pinkIds)->where('is_refund',1)->count(); + if(!$orderPink) return true; + else return false; + } + + + /** + * 创建拼团 + * @param $order + * @return mixed + */ + public static function createPink($order){ + $order = StoreOrder::tidyOrder($order,true)->toArray(); + if($order['pink_id']){//拼团存在 + $res = false; + $pink['uid'] = $order['uid'];//用户id + if(self::isPinkBe($pink,$order['pink_id'])) return false; + $pink['order_id'] = $order['order_id'];//订单id 生成 + $pink['order_id_key'] = $order['id'];//订单id 数据库id + $pink['total_num'] = $order['total_num'];//购买个数 + $pink['total_price'] = $order['pay_price'];//总金额 + $pink['k_id'] = $order['pink_id'];//拼团id + foreach ($order['cartInfo'] as $v){ + $pink['cid'] = $v['combination_id'];//拼团产品id + $pink['pid'] = $v['product_id'];//产品id + $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 + $pink['price'] = $v['productInfo']['price'];//单价 + $pink['stop_time'] = 0;//结束时间 + $pink['add_time'] = time();//开团时间 + $res = StorePink::set($pink)->toArray(); + } + if($res) return true; + else return false; + }else{ + $res = false; + $pink['uid'] = $order['uid'];//用户id + $pink['order_id'] = $order['order_id'];//订单id 生成 + $pink['order_id_key'] = $order['id'];//订单id 数据库id + $pink['total_num'] = $order['total_num'];//购买个数 + $pink['total_price'] = $order['pay_price'];//总金额 + $pink['k_id'] = 0;//拼团id + foreach ($order['cartInfo'] as $v){ + $pink['cid'] = $v['combination_id'];//拼团产品id + $pink['pid'] = $v['product_id'];//产品id + $pink['people'] = StoreCombination::where('id',$v['combination_id'])->value('people');//几人拼团 + $pink['price'] = $v['productInfo']['price'];//单价 +// $stopTime = StoreCombination::where('id',$v['combination_id'])->value('stop_time');//获取拼团产品结束的时间 +// if($stopTime < time()+86400) $pink['stop_time'] = $stopTime;//结束时间 + $pink['stop_time'] = time()+86400;//结束时间 + $pink['add_time'] = time();//开团时间 + $res1 = self::set($pink)->toArray(); + $res2 = StoreOrder::where('id',$order['id'])->update(['pink_id'=>$res1['id']]); + $res = $res1 && $res2; + } + if($res) return true; + else return false; + } + } +} \ No newline at end of file diff --git a/application/wap/model/store/StoreProduct.php b/application/wap/model/store/StoreProduct.php new file mode 100644 index 00000000..fb600c24 --- /dev/null +++ b/application/wap/model/store/StoreProduct.php @@ -0,0 +1,134 @@ + + * @day: 2017/12/12 + */ + +namespace app\wap\model\store; + + +use app\admin\model\store\StoreProductAttrValue; +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreProduct extends ModelBasic +{ + use ModelTrait; + + protected function getSliderImageAttr($value) + { + return json_decode($value,true)?:[]; + } + + public static function getValidProduct($productId,$field = '*') + { + return self::where('is_del',0)->where('is_show',1)->where('id',$productId)->field($field)->find(); + } + + public static function validWhere() + { + return self::where('is_del',0)->where('is_show',1)->where('mer_id',0); + } + + /** + * 新品产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getNewProduct($field = '*',$limit = 0) + { + $model = self::where('is_new',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + /** + * 热卖产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getHotProduct($field = '*',$limit = 0) + { + $model = self::where('is_hot',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + /** + * 精品产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getBestProduct($field = '*',$limit = 0) + { + $model = self::where('is_best',1)->where('is_del',0)->where('mer_id',0) + ->where('stock','>',0)->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + + /** + * 优惠产品 + * @param string $field + * @param int $limit + * @return false|\PDOStatement|string|\think\Collection + */ + public static function getBenefitProduct($field = '*',$limit = 0) + { + $model = self::where('is_benefit',1) + ->where('is_del',0)->where('mer_id',0)->where('stock','>',0) + ->where('is_show',1)->field($field) + ->order('sort DESC, id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function cateIdBySimilarityProduct($cateId,$field='*',$limit = 0) + { + $pid = StoreCategory::cateIdByPid($cateId)?:$cateId; + $cateList = StoreCategory::pidByCategory($pid,'id') ?:[]; + $cid = [$pid]; + foreach ($cateList as $cate){ + $cid[] = $cate['id']; + } + $model = self::where('cate_id','IN',$cid)->where('is_show',1)->where('is_del',0) + ->field($field)->order('sort DESC,id DESC'); + if($limit) $model->limit($limit); + return $model->select(); + } + + public static function isValidProduct($productId) + { + return self::be(['id'=>$productId,'is_del'=>0,'is_show'=>1]) > 0; + } + + public static function getProductStock($productId,$uniqueId = '') + { + if(!$uniqueId) $uniqueId = ''; + return (string)$uniqueId == '' ? + self::where('id',$productId)->value('stock')?:0 + : StoreProductAttr::uniqueByStock($uniqueId); + } + + public static function decProductStock($num,$productId,$unique = '') + { + if($unique){ + $res = false !== StoreProductAttrValue::decProductAttrStock($productId,$unique,$num); + $res = $res && self::where('id',$productId)->setInc('sales',$num); + }else{ + $res = false !== self::where('id',$productId)->dec('stock',$num)->inc('sales',$num)->update(); + } + return $res; + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreProductAttr.php b/application/wap/model/store/StoreProductAttr.php new file mode 100644 index 00000000..1d671b71 --- /dev/null +++ b/application/wap/model/store/StoreProductAttr.php @@ -0,0 +1,67 @@ + + * @day: 2017/12/13 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use think\Db; +use traits\ModelTrait; + +class StoreProductAttr extends ModelBasic +{ + + use ModelTrait; + + protected function getAttrValuesAttr($value) + { + return explode(',',$value); + } + + public static function storeProductAttrValueDb() + { + return Db::name('StoreProductAttrValue'); + } + + + /** + * 获取商品属性数据 + * @param $productId + * @return array + */ + public static function getProductAttrDetail($productId) + { + $attr = self::where('product_id',$productId)->select()->toArray()?:[]; + $_values = self::storeProductAttrValueDb()->where('product_id',$productId)->select(); + $values = []; + foreach ($_values as $value){ + $values[$value['suk']] = $value; + } + return [$attr,$values]; + } + + public static function uniqueByStock($unique) + { + return self::storeProductAttrValueDb()->where('unique',$unique)->value('stock')?:0; + } + + public static function uniqueByAttrInfo($unique, $field = '*') + { + return self::storeProductAttrValueDb()->field($field)->where('unique',$unique)->find(); + } + + public static function issetProductUnique($productId,$unique) + { + $res = self::be(['product_id'=>$productId]); + if($unique){ + return $res && self::storeProductAttrValueDb()->where('product_id',$productId)->where('unique',$unique)->count() > 0; + }else{ + return !$res; + } + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreProductRelation.php b/application/wap/model/store/StoreProductRelation.php new file mode 100644 index 00000000..d1b4cfcd --- /dev/null +++ b/application/wap/model/store/StoreProductRelation.php @@ -0,0 +1,63 @@ + + * @day: 2017/12/14 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use behavior\wap\StoreProductBehavior; +use service\HookService; +use traits\ModelTrait; + +class StoreProductRelation extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr($value) + { + return time(); + } + + public static function productRelation($productId,$uid,$relationType,$category = 'product') + { + if(!$productId) return self::setErrorInfo('产品不存在!'); + $relationType = strtolower($relationType); + $category = strtolower($category); + $data = ['uid'=>$uid,'product_id'=>$productId,'type'=>$relationType,'category'=>$category]; + if(self::be($data)) return true; + self::set($data); + HookService::afterListen('store_'.$category.'_'.$relationType,$productId,$uid,false,StoreProductBehavior::class); + return true; + } + + public static function unProductRelation($productId,$uid,$relationType,$category = 'product') + { + if(!$productId) return self::setErrorInfo('产品不存在!'); + $relationType = strtolower($relationType); + $category = strtolower($category); + self::where(['uid'=>$uid,'product_id'=>$productId,'type'=>$relationType,'category'=>$category])->delete(); + HookService::afterListen('store_'.$category.'_un_'.$relationType,$productId,$uid,false,StoreProductBehavior::class); + return true; + } + + public static function productRelationNum($productId,$relationType,$category = 'product') + { + $relationType = strtolower($relationType); + $category = strtolower($category); + return self::where('type',$relationType)->where('product_id',$productId)->where('category',$category)->count(); + } + + public static function isProductRelation($product_id,$uid,$relationType,$category = 'product') + { + $type = strtolower($relationType); + $category = strtolower($category); + return self::be(compact('product_id','uid','type','category')); + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreProductReply.php b/application/wap/model/store/StoreProductReply.php new file mode 100644 index 00000000..0eb2fdab --- /dev/null +++ b/application/wap/model/store/StoreProductReply.php @@ -0,0 +1,97 @@ + + * @day: 2017/12/29 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use service\UtilService; +use traits\ModelTrait; + +class StoreProductReply extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + protected function setPicsAttr($value) + { + return is_array($value) ? json_encode($value) : $value; + } + + protected function getPicsAttr($value) + { + return json_decode($value,true); + } + + public static function reply($group,$type = 'product') + { + $group['reply_type'] = $type; + return self::set($group); + } + + public static function productValidWhere($alias = '') + { + $model = new self; + if($alias){ + $model->alias($alias); + $alias .= '.'; + } + return $model->where("{$alias}is_del",0)->where("{$alias}reply_type",'product'); + } + + public static function getProductReplyList($productId,$order = 'All',$first = 0,$limit = 8) + { + $model = self::productValidWhere('A')->where('A.product_id',$productId) + ->field('A.product_score,A.service_score,A.comment,A.pics,A.add_time,B.nickname,B.avatar,C.cart_info,A.merchant_reply_content') + ->join('__USER__ B','A.uid = B.uid') + ->join('__STORE_ORDER_CART_INFO__ C','A.unique = C.unique'); + $baseOrder = 'A.add_time DESC,A.product_score DESC, A.service_score DESC'; + if($order == 'new') $model->order($baseOrder); + else if($order == 'pic') $model->where('A.pics',['<>',''],['<>','[]'])->order('LENGTH(A.comment) DESC,'.$baseOrder); + else $model->order('LENGTH(A.comment) DESC,'.$baseOrder); + $list = $model->limit($first,$limit)->select()->toArray()?:[]; + foreach ($list as $k=>$reply){ + $list[$k] = self::tidyProductReply($reply); + } + return $list; + } + + public static function tidyProductReply($res) + { + $res['cart_info'] = json_decode($res['cart_info'],true)?:[]; + $res['suk'] = isset($res['cart_info']['productInfo']['attrInfo']) ? $res['cart_info']['productInfo']['attrInfo']['suk'] : ''; + $res['nickname'] = UtilService::anonymity($res['nickname']); + $res['add_time'] = date('Y-m-d H:i',$res['add_time']); + $res['star'] = ceil(($res['product_score'] + $res['service_score'])/2); + $res['comment'] = $res['comment']?:'此用户没有填写评价'; + unset($res['cart_info']); + return $res; + } + + public static function isReply($unique,$reply_type = 'product') + { + return self::be(['unique'=>$unique,'reply_type'=>$reply_type]); + } + + public static function getRecProductReply($productId) + { + $res = self::productValidWhere('A')->where('A.product_id',$productId) + ->field('A.product_score,A.service_score,A.comment,A.pics,A.add_time,B.nickname,B.avatar,C.cart_info') + ->join('__USER__ B','A.uid = B.uid') + ->join('__STORE_ORDER_CART_INFO__ C','A.unique = C.unique') + ->order('LENGTH(A.comment) DESC,A.product_score DESC, A.service_score DESC, A.add_time DESC')->find(); + if(!$res) return null; + return self::tidyProductReply($res->toArray()); + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreSeckill.php b/application/wap/model/store/StoreSeckill.php new file mode 100644 index 00000000..29ec429b --- /dev/null +++ b/application/wap/model/store/StoreSeckill.php @@ -0,0 +1,109 @@ + + * @day: 2017/12/18 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; + +class StoreSeckill extends ModelBasic +{ + + protected function getImagesAttr($value) + { + return json_decode($value,true)?:[]; + } + + + /** + * 获取所有秒杀产品 + * @param string $field + * @return array + */ + public static function getListAll($field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock,sales'){ + $time = time(); + $model = self::where('is_del',0)->where('status',1)->where('stock','>',0)->field($field) + ->where('start_time','<',$time)->where('stop_time','>',$time)->order('sort DESC,add_time DESC'); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + /** + * 获取热门推荐的秒杀产品 + * @param int $limit + * @param string $field + * @return array + */ + public static function getHotList($limit = 0,$field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock') + { + $time = time(); + $model = self::where('is_hot',1)->where('is_del',0)->where('status',1)->where('stock','>',0)->field($field) + ->where('start_time','<',$time)->where('stop_time','>',$time)->order('sort DESC,add_time DESC'); + if($limit) $model->limit($limit); + $list = $model->select(); + if($list) return $list->toArray(); + else return []; + } + + /** + * 获取一条秒杀产品 + * @param $id + * @param string $field + * @return array|false|\PDOStatement|string|\think\Model + */ + public static function getValidProduct($id,$field = '*') + { + $time = time(); + return self::where('id',$id)->where('is_del',0)->where('status',1)->where('start_time','<',$time)->where('stop_time','>',$time) + ->field($field)->find(); + } + + public static function initFailSeckill() + { + self::where('is_hot',1)->where('is_del',0)->where('status','<>',1)->where('stop_time','<',time())->update(['status'=>'-1']); + } + + public static function idBySimilaritySeckill($id,$limit = 4,$field='*') + { + $time = time(); + $list = []; + $productId = self::where('id',$id)->value('product_id'); + if($productId){ + $list = array_merge($list, self::where('product_id',$productId)->where('id','<>',$id) + ->where('is_del',0)->where('status',1)->where('stock','>',0) + ->field($field)->where('start_time','<',$time)->where('stop_time','>',$time) + ->order('sort DESC,add_time DESC')->limit($limit)->select()->toArray()); + } + $limit = $limit - count($list); + if($limit){ + $list = array_merge($list,self::getHotList($limit,$field)); + } + + return $list; + } + + public static function getProductStock($id){ + $stock = self::where('id',$id)->value('stock'); + if(self::where('id',$id)->where('num','gt',$stock)->count()){//单次购买的产品多于库存 + return $stock; + }else{ + return self::where('id',$id)->value('num'); + } + } + + /** + * 修改秒杀库存 + * @param int $num + * @param int $seckillId + * @return bool + */ + public static function decSeckillStock($num = 0,$seckillId = 0){ + $res = false !== self::where('id',$seckillId)->dec('stock',$num)->inc('sales',$num)->update(); + return $res; + } + +} \ No newline at end of file diff --git a/application/wap/model/store/StoreService.php b/application/wap/model/store/StoreService.php new file mode 100644 index 00000000..66d16113 --- /dev/null +++ b/application/wap/model/store/StoreService.php @@ -0,0 +1,17 @@ + + * @day: 2017/12/23 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreService extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/wap/model/store/StoreServiceLog.php b/application/wap/model/store/StoreServiceLog.php new file mode 100644 index 00000000..fbe58db4 --- /dev/null +++ b/application/wap/model/store/StoreServiceLog.php @@ -0,0 +1,17 @@ + + * @day: 2017/12/23 + */ + +namespace app\wap\model\store; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class StoreServiceLog extends ModelBasic +{ + use ModelTrait; +} \ No newline at end of file diff --git a/application/wap/model/user/User.php b/application/wap/model/user/User.php new file mode 100644 index 00000000..04915ec8 --- /dev/null +++ b/application/wap/model/user/User.php @@ -0,0 +1,116 @@ + + * @day: 2017/12/21 + */ + +namespace app\wap\model\user; + + +use basic\ModelBasic; +use service\SystemConfigService; +use think\Request; +use think\response\Redirect; +use think\Session; +use think\Url; +use traits\ModelTrait; + +class User extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time','add_ip','last_time','last_ip']; + + protected function setAddTimeAttr($value) + { + return time(); + } + + protected function setAddIpAttr($value) + { + return Request::instance()->ip(); + } + + protected function setLastTimeAttr($value) + { + return time(); + } + + protected function setLastIpAttr($value) + { + return Request::instance()->ip(); + } + + public static function setWechatUser($wechatUser,$spread_uid = 0) + { + return self::set([ + 'account'=>'wx'.$wechatUser['uid'].time(), + 'pwd'=>md5(123456), + 'nickname'=>$wechatUser['nickname']?:'', + 'avatar'=>$wechatUser['headimgurl']?:'', + 'spread_uid'=>$spread_uid, + 'uid'=>$wechatUser['uid'], + 'user_type'=>'wechat' + ]); + + } + + public static function updateWechatUser($wechatUser,$uid) + { + return self::edit([ + 'nickname'=>$wechatUser['nickname']?:'', + 'avatar'=>$wechatUser['headimgurl']?:'' + ],$uid,'uid'); + } + + public static function setSpreadUid($uid,$spreadUid) + { + return self::where('uid',$uid)->update(['spread_uid'=>$spreadUid]); + } + + + public static function getUserInfo($uid) + { + $userInfo = self::where('uid',$uid)->find(); + if(!$userInfo) exception('读取用户信息失败!'); + return $userInfo->toArray(); + } + + /** + * 获得当前登陆用户UID + * @return int $uid + */ + public static function getActiveUid() + { + $uid = null; + if(Session::has('loginUid','wap')) $uid = Session::get('loginUid','wap'); + if(!$uid && Session::has('loginOpenid','wap') && ($openid = Session::get('loginOpenid','wap'))) + $uid = WechatUser::openidToUid($openid); + if(!$uid) exit(exception('请登陆!')); + return $uid; + } + + public static function backOrderBrokerage($orderInfo) + { + $userInfo = User::getUserInfo($orderInfo['uid']); + if(!$userInfo || !$userInfo['spread_uid']) return true; + $storeBrokerageStatu = SystemConfigService::get('store_brokerage_statu') ? : 1;//获取后台分销类型 + if($storeBrokerageStatu == 1){ + if(!User::be(['uid'=>$userInfo['spread_uid'],'is_promoter'=>1])) return true; + } + $brokerageRatio = (SystemConfigService::get('store_brokerage_ratio') ?: 0)/100; + if($brokerageRatio <= 0) return true; + $cost = isset($orderInfo['cost']) ? $orderInfo['cost'] : 0;//成本价 + $brokeragePrice = bcmul(bcsub($orderInfo['pay_price'],$cost,2),$brokerageRatio,2); + if($brokeragePrice <= 0) return true; + $mark = $userInfo['nickname'].'成功消费'.floatval($orderInfo['pay_price']).'元,奖励推广佣金'.floatval($brokeragePrice); + self::beginTrans(); + $res1 = UserBill::income('获得推广佣金',$userInfo['spread_uid'],'now_money','brokerage',$brokeragePrice,$orderInfo['id'],0,$mark); + $res2 = self::bcInc($userInfo['spread_uid'],'now_money',$brokeragePrice,'uid'); + $res = $res1 && $res2; + self::checkTrans($res); + return $res; + } + +} \ No newline at end of file diff --git a/application/wap/model/user/UserAddress.php b/application/wap/model/user/UserAddress.php new file mode 100644 index 00000000..62b506c3 --- /dev/null +++ b/application/wap/model/user/UserAddress.php @@ -0,0 +1,51 @@ + + * @day: 2017/12/25 + */ + +namespace app\wap\model\user; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class UserAddress extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function setDefaultAddress($id,$uid) + { + self::beginTrans(); + $res1 = self::where('uid',$uid)->update(['is_default'=>0]); + $res2 = self::where('id',$id)->where('uid',$uid)->update(['is_default'=>1]); + $res =$res1 !== false && $res2 !== false; + self::checkTrans($res); + return $res; + } + + public static function userValidAddressWhere($model=null,$prefix = '') + { + if($prefix) $prefix .='.'; + $model = self::getSelfModel($model); + return $model->where("{$prefix}is_del",0); + } + + public static function getUserValidAddressList($uid,$field = '*') + { + return self::userValidAddressWhere()->where('uid',$uid)->order('add_time DESC')->field($field)->select()->toArray()?:[]; + } + + public static function getUserDefaultAddress($uid,$field = '*') + { + return self::userValidAddressWhere()->where('uid',$uid)->where('is_default',1)->field($field)->find(); + } +} \ No newline at end of file diff --git a/application/wap/model/user/UserBill.php b/application/wap/model/user/UserBill.php new file mode 100644 index 00000000..8a7db37e --- /dev/null +++ b/application/wap/model/user/UserBill.php @@ -0,0 +1,37 @@ + + * @day: 2017/12/30 + */ + +namespace app\wap\model\user; + + +use basic\ModelBasic; +use traits\ModelTrait; + +class UserBill extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function income($title,$uid,$category,$type,$number,$link_id = 0,$balance = 0,$mark = '',$status = 1) + { + $pm = 1; + return self::set(compact('title','uid','link_id','category','type','number','balance','mark','status','pm')); + } + + public static function expend($title,$uid,$category,$type,$number,$link_id = 0,$balance = 0,$mark = '',$status = 1) + { + $pm = 0; + return self::set(compact('title','uid','link_id','category','type','number','balance','mark','status','pm')); + } + +} \ No newline at end of file diff --git a/application/wap/model/user/UserExtract.php b/application/wap/model/user/UserExtract.php new file mode 100644 index 00000000..1a4926e8 --- /dev/null +++ b/application/wap/model/user/UserExtract.php @@ -0,0 +1,113 @@ + + * @day: 2018/3/3 + */ + +namespace app\wap\model\user; + + +use basic\ModelBasic; +use service\SystemConfigService; +use service\WechatTemplateService; +use think\Url; +use traits\ModelTrait; + +class UserExtract extends ModelBasic +{ + use ModelTrait; + + //审核中 + const AUDIT_STATUS = 0; + //未通过 + const FAIL_STATUS = -1; + //已提现 + const SUCCESS_STATUS = 1; + + protected static $extractType = ['alipay','bank']; + + protected static $extractTypeMsg = ['alipay'=>'支付宝','bank'=>'银行卡']; + + protected static $status = array( + -1=>'未通过', + 0 =>'审核中', + 1 =>'已提现' + ); + + public static function userExtract($userInfo,$data){ + if(!in_array($data['extract_type'],self::$extractType)) + return self::setErrorInfo('提现方式不存在'); + if($userInfo['now_money'] < $data['extract_price']) + return self::setErrorInfo('余额不足'); + if(!$data['real_name']) + return self::setErrorInfo('输入姓名有误'); + $extractMinPrice = floatval(SystemConfigService::get('user_extract_min_price'))?:0; + if($data['extract_price'] < $extractMinPrice) + return self::setErrorInfo('提现金额不能小于'.$extractMinPrice); + $balance = bcsub($userInfo['now_money'],$data['extract_price']); + $insertData = [ + 'uid'=>$userInfo['uid'], + 'real_name'=>$data['real_name'], + 'extract_type'=>$data['extract_type'], + 'extract_price'=>($data['extract_price']), + 'add_time'=>time(), + 'balance'=>$balance, + 'status'=>self::AUDIT_STATUS + ]; + if($data['extract_type'] == 'alipay'){ + if(!$data['alipay_code']) return self::setErrorInfo('请输入支付宝账号'); + $insertData['alipay_code'] = $data['alipay_code']; + $mark = '使用支付宝提现'.$insertData['extract_price'].'元'; + }else{ + if(!$data['bank_code']) return self::setErrorInfo('请输入银行卡账号'); + if(!$data['bank_address']) return self::setErrorInfo('请输入开户行信息'); + $insertData['bank_code'] = $data['bank_code']; + $insertData['bank_address'] = $data['bank_address']; + $mark = '使用银联卡'.$insertData['bank_code'].'提现'.$insertData['extract_price'].'元'; + } + self::beginTrans(); + $res1 = self::set($insertData); + if(!$res1) return self::setErrorInfo('提现失败'); + $res2 = User::edit(['now_money'=>$balance],$userInfo['uid'],'uid'); + $res3 = UserBill::expend('余额提现',$userInfo['uid'],'now_money','extract',$data['extract_price'],$res1['id'],$balance,$mark); + $res = $res2 && $res3; + WechatTemplateService::sendTemplate( + WechatUser::uidToOpenid($userInfo['uid']), + WechatTemplateService::USER_BALANCE_CHANGE, + [ + 'first'=>'你好,申请余额提现成功!', + 'keyword1'=>'余额提现', + 'keyword2'=>date('Y-m-d'), + 'keyword3'=>$data['extract_price'], + 'remark'=>'点击查看我的余额明细' + ], + Url::build('wap/My/balance',[],true,true) + ); + if($res) + return true; + else + return self::setErrorInfo('提现失败!'); + } + + /** + * 获得用户最后一次提现信息 + * @param $openid + * @return mixed + */ + public static function userLastInfo($uid) + { + return self::where(compact('uid'))->order('add_time DESC')->find(); + } + + /** + * 获得用户提现总金额 + * @param $uid + * @return mixed + */ + public static function userExtractTotalPrice($uid) + { + return self::where('uid',$uid)->where('status',self::SUCCESS_STATUS)->value('SUM(extract_price)')?:0; + } + +} \ No newline at end of file diff --git a/application/wap/model/user/UserNotice.php b/application/wap/model/user/UserNotice.php new file mode 100644 index 00000000..bf577dba --- /dev/null +++ b/application/wap/model/user/UserNotice.php @@ -0,0 +1,57 @@ + + * @day: 2017/11/11 + */ + +namespace app\wap\model\user; + +use app\admin\model\user\UserNoticeSee; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * 用户通知 model + * Class UserNotice + * @package app\admin\model\user + */ +class UserNotice extends ModelBasic +{ + use ModelTrait; + public static function getNotice($uid){ + $count_notice = self::where('uid','like',"%,$uid,%")->where("is_send",1)->count(); + $see_notice = UserNoticeSee::where("uid",$uid)->count(); + return $count_notice-$see_notice; + } + /** + * @return array + */ + public static function getNoticeList($uid,$page,$limit = 8){ + //定义分页信息 + $count = self::where('uid','like',"%,$uid,%")->count(); + $data["lastpage"] = ceil($count/$limit) <= ($page+1) ? 1 : 0; + + $where['uid'] = array("like","%,$uid,%"); +// $where['uid'] = array(array("like","%,$uid,%"),array("eq",""), 'or'); + $where['is_send'] = 1; + $list = self::where($where)->field('id,user,title,content,add_time')->order("add_time desc")->limit($page*$limit,$limit)->select()->toArray(); + foreach ($list as $key => $value) { + $list[$key]["add_time"] = date("Y-m-d H:i:s",$value["add_time"]); + $list[$key]["is_see"] = UserNoticeSee::where("uid",$uid)->where("nid",$value["id"])->count() > 0 ? 1 : 0; + } + $data["list"] = $list; + return $data; + } + /** + * @return array + */ + public static function seeNotice($uid,$nid){ + if(UserNoticeSee::where("uid",$uid)->where("nid",$nid)->count() <= 0){ + $data["nid"] = $nid; + $data["uid"] = $uid; + $data["add_time"] = time(); + UserNoticeSee::set($data); + } + } +} \ No newline at end of file diff --git a/application/wap/model/user/UserRecharge.php b/application/wap/model/user/UserRecharge.php new file mode 100644 index 00000000..bde6c671 --- /dev/null +++ b/application/wap/model/user/UserRecharge.php @@ -0,0 +1,60 @@ + + * @day: 2018/01/05 + */ + +namespace app\wap\model\user; + +use app\wap\model\user\WechatUser; +use basic\ModelBasic; +use service\WechatService; +use traits\ModelTrait; + +class UserRecharge extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + protected function setAddTimeAttr() + { + return time(); + } + + public static function addRecharge($uid,$price,$recharge_type = 'weixin',$paid = 0) + { + $order_id = self::getNewOrderId(); + return self::set(compact('order_id','uid','price','recharge_type','paid')); + } + + public static function getNewOrderId() + { + $count = (int) self::where('add_time',['>=',strtotime(date("Y-m-d"))],['<',strtotime(date("Y-m-d",strtotime('+1 day')))])->count(); + return 'wx1'.date('YmdHis',time()).(10000+$count+1); + } + + public static function jsPay($orderInfo) + { + return WechatService::jsPay(WechatUser::uidToOpenid($orderInfo['uid']),$orderInfo['order_id'],$orderInfo['price'],'user_recharge','用户充值'); + } + + /** + * //TODO用户充值成功后 + * @param $orderId + */ + public static function rechargeSuccess($orderId) + { + $order = self::where('order_id',$orderId)->where('paid',0)->find(); + if(!$order) return false; + $user = User::getUserInfo($order['uid']); + self::beginTrans(); + $res1 = self::where('order_id',$order['order_id'])->update(['paid'=>1,'pay_time'=>time()]); + $res2 = UserBill::income('用户余额充值',$order['uid'],'now_money','recharge',$order['price'],$order['id'],$user['now_money'],'成功充值余额'.floatval($order['price']).'元'); + $res3 = User::edit(['now_money'=>bcadd($user['now_money'],$order['price'],2)],$order['uid'],'uid'); + $res = $res1 && $res2 && $res3; + self::checkTrans($res); + return $res; + } +} \ No newline at end of file diff --git a/application/wap/model/user/UserSign.php b/application/wap/model/user/UserSign.php new file mode 100644 index 00000000..ff6493ee --- /dev/null +++ b/application/wap/model/user/UserSign.php @@ -0,0 +1,52 @@ + + * @day: 2018/02/28 + */ + +namespace app\wap\model\user; + + +use basic\ModelBasic; +use service\SystemConfigService; +use think\Model; + +class UserSign +{ + public static function checkUserSigned($uid) + { + return UserBill::be(['uid'=>$uid,'add_time'=>['>',strtotime('today')],'category'=>'integral','type'=>'sign']); + } + + public static function userSignedCount($uid) + { + return self::userSignBillWhere($uid)->count(); + } + + /** + * @param $uid + * @return Model + */ + public static function userSignBillWhere($uid) + { + return UserBill::where(['uid'=>$uid,'category'=>'integral','type'=>'sign']); + } + + public static function sign($userInfo) + { + $uid = $userInfo['uid']; + $min = SystemConfigService::get('sx_sign_min_int')?:0; + $max = SystemConfigService::get('sx_sign_max_int')?:5; + $integral = rand($min,$max); + ModelBasic::beginTrans(); + $res1 = UserBill::income('用户签到',$uid,'integral','sign',$integral,0,$userInfo['integral'],'签到获得'.floatval($integral).'积分'); + $res2 = User::bcInc($uid,'integral',$integral,'uid'); + $res = $res1 && $res2; + ModelBasic::checkTrans($res); + if($res) + return $integral; + else + return false; + } +} \ No newline at end of file diff --git a/application/wap/model/user/WechatUser.php b/application/wap/model/user/WechatUser.php new file mode 100644 index 00000000..dcf4e623 --- /dev/null +++ b/application/wap/model/user/WechatUser.php @@ -0,0 +1,165 @@ + + * @day: 2017/12/14 + */ + +namespace app\wap\model\user; + +use app\wap\model\store\StoreCoupon; +use app\wap\model\store\StoreCouponUser; +use basic\ModelBasic; +use service\SystemConfigService; +use service\UtilService; +use service\WechatService; +use service\CacheService as Cache; +use think\Session; +use traits\ModelTrait; + +class WechatUser extends ModelBasic +{ + use ModelTrait; + + protected $insert = ['add_time']; + + public static function setAddTimeAttr($value) + { + return time(); + } + + /** + * .添加新用户 + * @param $openid + * @return object + */ + public static function setNewUser($openid) + { + $userInfo = WechatService::getUserInfo($openid); + if(!isset($userInfo['subscribe']) || !$userInfo['subscribe'] || !isset($userInfo['openid'])) + exception('请关注公众号!'); + $userInfo['tagid_list'] = implode(',',$userInfo['tagid_list']); + self::beginTrans(); + $wechatUser = self::set($userInfo); + if(!$wechatUser){ + self::rollbackTrans(); + exception('用户储存失败!'); + } + if(!User::setWechatUser($wechatUser)){ + self::rollbackTrans(); + exception('用户信息储存失败!'); + } + self::commitTrans(); + self::userFirstSubGiveCoupon($openid); + return $wechatUser; + } + + public static function userFirstSubGiveCoupon($openid) + { + $couponId = SystemConfigService::get('wechat_first_sub_give_coupon'); + if($couponId) StoreCouponUser::addUserCoupon(self::openidToUid($openid),$couponId); + } + + public static function userTakeOrderGiveCoupon($uid) + { + $couponId = SystemConfigService::get('store_order_give_coupon'); + if($couponId) StoreCouponUser::addUserCoupon($uid,$couponId); + } + + /** + * 更新用户信息 + * @param $openid + * @return bool + */ + public static function updateUser($openid) + { + $userInfo = WechatService::getUserInfo($openid); + $userInfo['tagid_list'] = implode(',',$userInfo['tagid_list']); + return self::edit($userInfo,$openid,'openid'); + } + + /** + * 用户存在就更新 不存在就添加 + * @param $openid + */ + public static function saveUser($openid) + { + self::be($openid,'openid') == true ? self::updateUser($openid) : self::setNewUser($openid); + } + + /** + * 用户取消关注 + * @param $openid + * @return bool + */ + public static function unSubscribe($openid) + { + return self::edit(['subscribe'=>0],$openid,'openid'); + } + + /** + * 用uid获得openid + * @param $uid + * @return mixed + */ + public static function uidToOpenid($uid,$update = false) + { + $cacheName = 'openid_'.$uid; + $openid = Cache::get($cacheName); + if($openid && !$update) return $openid; + $openid = self::where('uid',$uid)->value('openid'); + if(!$openid) exception('对应的openid不存在!'); + Cache::set($cacheName,$openid,0); + return $openid; + } + + /** + * 用uid获得Unionid + * @param $uid + * @return mixed + */ + public static function uidToUnionid($uid,$update = false) + { + $cacheName = 'unionid_'.$uid; + $unionid = Cache::get($cacheName); + if($unionid && !$update) return $unionid; + $unionid = self::where('uid',$uid)->value('unionid'); + if(!$unionid) exception('对应的unionid不存在!'); + Cache::set($cacheName,$unionid,0); + return $unionid; + } + + /** + * 用openid获得uid + * @param $uid + * @return mixed + */ + public static function openidToUid($openid,$update = false) + { + $cacheName = 'uid_'.$openid; + $uid = Cache::get($cacheName); + if($uid && !$update) return $uid; + $uid = self::where('openid',$openid)->value('uid'); + if(!$uid) exception('对应的uid不存在!'); + Cache::set($cacheName,$uid,0); + return $uid; + } + + /** + * 获取用户信息 + * @param $openid + * @return array + */ + public static function getWechatInfo($openid) + { + if(is_numeric($openid)) $openid = self::uidToOpenid($openid); + $wechatInfo = self::where('openid',$openid)->find(); + if(!$wechatInfo) { + self::setNewUser($openid); + $wechatInfo = self::where('openid',$openid)->find(); + } + if(!$wechatInfo) exception('获取用户信息失败!'); + return $wechatInfo->toArray(); + } + +} \ No newline at end of file diff --git a/application/wap/model/wap/ArticleCategory.php b/application/wap/model/wap/ArticleCategory.php new file mode 100644 index 00000000..e1f76a85 --- /dev/null +++ b/application/wap/model/wap/ArticleCategory.php @@ -0,0 +1,27 @@ + + * @day: 2017/11/02 */ + +namespace app\wap\model\wap; + +use think\Db; +use traits\ModelTrait; +use basic\ModelBasic; + +/** + * Class ArticleCategory + * @package app\wap\model + */ +class ArticleCategory extends ModelBasic +{ + use ModelTrait; + + public static function cidByArticleList($cid, $first, $limit, $field = '*') + { + $model = Db::name('article'); + if ($cid) $model->where("CONCAT(',',cid,',') LIKE '%,$cid,%'", 'exp'); + return $model->field($field)->where('status', 1)->where('hide', 0)->order('sort DESC,add_time DESC')->limit($first, $limit)->select(); + } +} \ No newline at end of file diff --git a/application/wap/view/first/article/index.html b/application/wap/view/first/article/index.html new file mode 100644 index 00000000..5d4be181 --- /dev/null +++ b/application/wap/view/first/article/index.html @@ -0,0 +1,117 @@ +{extend name="public/container"} +{block name="title"}{$title}{/block} +{block name="content"} + +
+
+
+
+ +

正在加载中

+

加载更多

+

没有更多了

+
+
+
+
+ + +{/block} \ No newline at end of file diff --git a/application/wap/view/first/article/visit.html b/application/wap/view/first/article/visit.html new file mode 100644 index 00000000..d5d3af58 --- /dev/null +++ b/application/wap/view/first/article/visit.html @@ -0,0 +1,15 @@ +{extend name="public/container"} +{block name="title"}{$content.title}{/block} +{block name="content"} +
+
+
+
+

{$content.title}

+ 发布时间:{$content.add_time|date='Y-m-d H:i:s',###} 作者:{$content.author} 浏览:{$content.visit} +
+
{$content.content}
+
+
+
+{/block} \ No newline at end of file diff --git a/application/wap/view/first/index/about.html b/application/wap/view/first/index/about.html new file mode 100644 index 00000000..4f77535e --- /dev/null +++ b/application/wap/view/first/index/about.html @@ -0,0 +1,14 @@ +{extend name="public/container"} +{block name="title"}关于我们{/block} +{block name="content"} +
+
+
+

+
+
+

众邦科技提供技术支持

+

版本号:V1.0

+
+
+{/block} \ No newline at end of file diff --git a/application/wap/view/first/index/index.html b/application/wap/view/first/index/index.html new file mode 100644 index 00000000..98eed54b --- /dev/null +++ b/application/wap/view/first/index/index.html @@ -0,0 +1,388 @@ +{extend name="public/container"} +{block name="head_top"} + + + + + + + +{/block} +{block name="title"} + +{/block} +{block name="content"} +
+
+
+ + +
+ +
+ {notempty name="banner"} + + {/notempty} + {notempty name="menus"} + + {/notempty} + {notempty name="roll_news"} +
+
+
+
    {volist name="roll_news" id="vo"} +
  • {$vo.info} +
  • + {/volist} +
+
+
+ {/notempty} +
+ + +
+
+
+
{{item.coupon_price}} +

满{{item.use_min_price}}元可用

+
+
+
+
+ + 查看更多 > +
+ + {notempty name="storeSeckill"} +
+
限时秒杀
+
    + {volist name="storeSeckill" id="vo"} +
  • +
    +
    + 00 + : + 00 + : + 00 +
    +
    +
    +
    {$vo.title}
    +
    {$vo.price} ¥{$vo.ot_price} +
    +
    + + 已抢{$vo.round}% +
    + 马上抢
    +
  • + {/volist} +
+
+ {/notempty} +
+
+ 拼团 . 花少钱买好货 +
+
+
+
+
+ +
+
+
{{item.title}}
+
+ ¥{{item.price}} + ¥{{item.product_price}} + 已拼{{item.sales}}单 +
+ + {{item.people}}人团 + 去开团 + + +
+
+
+
+ + + +

正在加载中

+

+ 点击加载

+

+ 没有更多了

+
+ {include file="public/store_menu"} +
+ +
+{/block} \ No newline at end of file diff --git a/application/wap/view/first/index/spread.html b/application/wap/view/first/index/spread.html new file mode 100644 index 00000000..8def42cf --- /dev/null +++ b/application/wap/view/first/index/spread.html @@ -0,0 +1,32 @@ +{extend name="public/container"} +{block name="title"}分享二维码{/block} +{block name="content"} + + + +{/block} \ No newline at end of file diff --git a/application/wap/view/first/login/index.html b/application/wap/view/first/login/index.html new file mode 100644 index 00000000..8f7123f9 --- /dev/null +++ b/application/wap/view/first/login/index.html @@ -0,0 +1,15 @@ +{extend name="public/container"} +{block name="head_top"} +{block name="title"}立即登陆{/block} +{block name="content"} +
+
+
+
+
+ +
+
+
+
+{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/address.html b/application/wap/view/first/my/address.html new file mode 100644 index 00000000..92358a68 --- /dev/null +++ b/application/wap/view/first/my/address.html @@ -0,0 +1,72 @@ +{extend name="public/container"} +{block name="title"}地址管理{/block} +{block name="content"} +
+
+
+ + {volist name="address" id="vo"} +
+ +
+
+ +
+
+ 编辑 + 删除 +
+
+
+ {/volist} +
+ + 新增地址 + +
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/balance.html b/application/wap/view/first/my/balance.html new file mode 100644 index 00000000..38529837 --- /dev/null +++ b/application/wap/view/first/my/balance.html @@ -0,0 +1,163 @@ +{extend name="public/container"} +{block name="title"}我的账户{/block} +{extend name="public/container"} +{block name="head"} + +{/block} +{block name="content"} + +
+
+
+
+

当前余额(元)

+ {$userInfo.now_money} +
+
+ +
+
+ +
+
+
    +
  • +
    +

    + +
    +
    {{item.pm == 1 ? '+' : '-'}}{{item.number}}
    +
  • +
+

正在加载中

+

加载更多

+

没有更多了

+
+
+
+
+
+
+
+
+
输入充值金额
+
+ + +
+
充值提示:单次充值金额不能低于{{minRecharge}}元
+ +
+
+
+
+
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/collect.html b/application/wap/view/first/my/collect.html new file mode 100644 index 00000000..9aacb8e5 --- /dev/null +++ b/application/wap/view/first/my/collect.html @@ -0,0 +1,99 @@ +{extend name="public/container"} +{block name="title"}已收藏商品{/block} +{block name="content"} + +
+
+ + +
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/commission.html b/application/wap/view/first/my/commission.html new file mode 100644 index 00000000..b19d9bb9 --- /dev/null +++ b/application/wap/view/first/my/commission.html @@ -0,0 +1,131 @@ +{extend name="public/container"} +{block name="title"}我的账户{/block} +{extend name="public/container"} +{block name="head"} + +{/block} +{block name="content"} + +
+
+
+ +
+
+
    +
  • +
    +

    + +
    +
    {{item.pm == 1 ? '+' : '-'}}{{item.number}}
    +
  • +
+

正在加载中

+

加载更多

+

没有更多了

+
+
+
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/coupon.html b/application/wap/view/first/my/coupon.html new file mode 100644 index 00000000..3299260a --- /dev/null +++ b/application/wap/view/first/my/coupon.html @@ -0,0 +1,56 @@ +{extend name="public/container"} +{block name="title"}我的优惠劵{/block} +{block name="content"} +
+
+
+ 全部 + 未使用 + 已使用 + 已过期 +
+
+ {empty name="couponList"} +
+ +

暂无有效优惠券

+
+ {else/} +
    + {volist name="couponList" id="vo"} +
  • +
    +
    +

    满{$vo.use_min_price}元可用现金券

    + {$vo._add_time}至{$vo._end_time}使用 +
    +
    +
    + {$vo.coupon_price} +

    {$vo._msg}

    +
    + {eq name='vo._type' value='2'}{/eq} +
  • + {/volist} +
+ {/empty} +
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/edit_address.html b/application/wap/view/first/my/edit_address.html new file mode 100644 index 00000000..44e39caa --- /dev/null +++ b/application/wap/view/first/my/edit_address.html @@ -0,0 +1,117 @@ +{extend name="public/container" /} +{block name="title"}添加地址{/block} +{block name="content"} + +
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+ +
+ +
+
+ + +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/express.html b/application/wap/view/first/my/express.html new file mode 100644 index 00000000..9070065f --- /dev/null +++ b/application/wap/view/first/my/express.html @@ -0,0 +1,34 @@ +{extend name="public/container"} +{block name="title"}物流信息{/block} +{block name="content"} +
+
+
+
+
+
物流公司:{$order.delivery_name}
+
物流单号:{$order.delivery_id}
+
+
+
+ +
+ +

暂无查询记录

+
+ +
    + {volist name="express.result.list" id="vo"} +
  • +
    +

    {$vo.status}

    + {$vo.time} +
    +
  • + {/volist} +
+ +
+
+
+{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/extract.html b/application/wap/view/first/my/extract.html new file mode 100644 index 00000000..2b8fb480 --- /dev/null +++ b/application/wap/view/first/my/extract.html @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + 用户提现 + {include file="public/style" /} + + +
+
+
+
银联卡
+
+
    +
  • 支付宝
  • +
  • 银联卡
  • + +
+
+
+
+
+ +
+ + +
+
+ +
+ + 余额:¥{$userInfo.now_money} +
+
+
+
提现
+
+
+{include file="public/right_nav" /} + + + \ No newline at end of file diff --git a/application/wap/view/first/my/index.html b/application/wap/view/first/my/index.html new file mode 100644 index 00000000..9d174373 --- /dev/null +++ b/application/wap/view/first/my/index.html @@ -0,0 +1,112 @@ +{extend name="public/container"} +{block name="title"}个人中心{/block} +{block name="content"} + + + {include file="public/store_menu"} + +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/integral.html b/application/wap/view/first/my/integral.html new file mode 100644 index 00000000..f85fd408 --- /dev/null +++ b/application/wap/view/first/my/integral.html @@ -0,0 +1,111 @@ +{extend name="public/container"} +{block name="title"}我的积分{/block} +{extend name="public/container"} +{block name="head"} + +{/block} +{block name="content"} +
+
+
+
+ 我的积分 +

{$userInfo.integral|floatval}

+ 获取积分 */ ?> +
+
+ + 进入积分商城 + 收货地址管理 +
*/ ?> +
+
收支明细
+
+
+
    +
  • +
    +
    +

    + +
    +
    +
    +
    {{item.pm == 1 ? '+' : '-'}}{{item.number}}积分
    +
    +
  • +
+

正在加载中

+

加载更多

+

没有更多了

+
+
+ +
+ + + +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/notice.html b/application/wap/view/first/my/notice.html new file mode 100644 index 00000000..daf05278 --- /dev/null +++ b/application/wap/view/first/my/notice.html @@ -0,0 +1,111 @@ +{extend name="public/container"} +{block name="title"}消息通知{/block} +{block name="content"} +
+
+
    +
  • +
    + + {{item.user}} + {{item.add_time}} +
    +
    +
    {{item.title}}
    +
    {{item.content}}
    +
    + +
  • +

    正在加载中

    +

    加载更多

    +

    没有更多了

    +
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/order.html b/application/wap/view/first/my/order.html new file mode 100644 index 00000000..15db3d8d --- /dev/null +++ b/application/wap/view/first/my/order.html @@ -0,0 +1,269 @@ +{extend name="public/container"} +{block name="title"}订单详情{/block} +{block name="content"} +
+
+
+
+
+
+

{$order._status._title}

+ {if condition="$order['pink_id']"} + {if condition="isPinkStatus($order['pink_id'])"} + {$order._status._msg} + {else/} + 拼团活动已经结束 + {/if} + {else/} + {$order._status._msg} + {/if} +
+
+
+
+ +
+

{$order.real_name} {$order.user_phone}

+

{$order.user_address}

+
+
+ {egt name="order._status._type" value="2"} +
+
配送信息
+
+
    +
  • 配送方式:{$order._status._deliveryType}
  • + {eq name="order.delivery_type" value="express"} +
  • 快递公司:{$order.delivery_name}
  • +
  • 快递单号:{$order.delivery_id}
  • + {/eq} + {eq name="order.delivery_type" value="send"} +
  • 配送人员:{$order.delivery_name}
  • +
  • 联系电话:{$order.delivery_id}
  • + {/eq} +
+
+
+ {/egt} +
+
产品信息
+
+ +
+
+
+ {gt name="order.total_postage" value="0"} +

运费 ¥{$order.total_postage}

+ {/gt} +

商品总价 ¥{$order.total_price}

+ {gt name="order.coupon_price" value="0"} +

优惠 -¥{$order.coupon_price}

+ {/gt} + {gt name="order.deduction_price" value="0"} +

积分抵扣 -¥{$order.deduction_price}

+ {/gt} +
+
实付款 ¥{$order.pay_price}
+
+
+
+
订单信息
+
+
    +
  • 订单编号:{$order.order_id}
  • +
  • 下单时间:{$order.add_time|date="Y-m-d H:i",###}
  • +
  • 支付方式:{$order._status._payType}
  • +
  • 支付状态:{$order.paid == 1 ? '已支付' : '未支付'}
  • + {eq name="order.paid" value="1"} +
  • 支付时间:{$order.pay_time|date="Y-m-d H:i",###}
  • + {/eq} +
+
+
+ 2))): ?> +
+
+ + + 更多 + + + + {if condition="$order['pink_id']"} + 查看拼团 + {/if} + + 立即付款 + + {eq name="order.delivery_type" value="express"} + 查询快递 + {/eq} + 确认收货 + +
+ + {eq name="order._status._type" value="3"} +
+ + {/eq} +
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/order_customer.html b/application/wap/view/first/my/order_customer.html new file mode 100644 index 00000000..c0663fa4 --- /dev/null +++ b/application/wap/view/first/my/order_customer.html @@ -0,0 +1,253 @@ +{extend name="public/container"} +{block name="title"}退款/售后{/block} +{block name="content"} + +
+
+
+
+ + +
+ +
+
+
+
拼团订单: {{item.order_id}}
+ +
+
+

运费 ¥{{item.total_postage}}

+

商品总价 ¥{{item.total_price}}

+

优惠 -¥{{item.coupon_price}}

+

积分抵扣 -¥{{item.deduction_price}}

+
+
实付款 ¥{{item.pay_price}}
+ + +
+
+

正在加载中

+

加载更多

+

没有更多了

+
+
+
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/order_list.html b/application/wap/view/first/my/order_list.html new file mode 100644 index 00000000..79e76121 --- /dev/null +++ b/application/wap/view/first/my/order_list.html @@ -0,0 +1,256 @@ +{extend name="public/container"} +{block name="title"}订单列表{/block} +{block name="content"} + +
+
+
+
+ + +
+ +
+
+
+
拼团订单: {{item.order_id}}
+ +
+
+

运费 ¥{{item.total_postage}}

+

商品总价 ¥{{item.total_price}}

+

优惠 -¥{{item.coupon_price}}

+

积分抵扣 -¥{{item.deduction_price}}

+
+
实付款 ¥{{item.pay_price}}
+ + +
+
+

正在加载中

+

加载更多

+

没有更多了

+
+
+
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/order_pink.html b/application/wap/view/first/my/order_pink.html new file mode 100644 index 00000000..9d57ac77 --- /dev/null +++ b/application/wap/view/first/my/order_pink.html @@ -0,0 +1,257 @@ +{extend name="public/container"} +{block name="head_top"} + + + +{/block} +{block name="title"}{$store_combination.title}{/block} +{block name="content"} + + +
+
+
    +
  • +
    +
    +
    +

    {$store_combination.title}

    +

    {$pinkT.people}人团·已团{$store_combination.sales}

    +

    + {$pinkT.price}拼团劲省 +

    +
    +
    +
  • +
+
+ +
+
+
    +
  • + +
    团长
    +
  • + {volist name="pinkAll" id="vo"} +
  • + {/volist} + +
  • + +
+
+
+ {if condition="$pinkBool eq 1 && $userBool"} + +
+
+
拼团成功
+ 商家正在努力发货,请耐心等待 +
+
+ {elseif condition="$pinkBool eq 1 && !$userBool"} + +
+
+
拼团已完成
+ 请您参加别的拼团 +
+
+ {elseif condition="$pinkBool eq 2 && $userBool"} + +
+
+
拼团时间已到
+ 退款中 +
+
+ {elseif condition="$pinkBool eq 3"} + +
+
+
拼团已结束
+ 请您参加别的拼团 +
+
+ {elseif condition="$pinkBool eq 6"} + +
+
+
拼团人数已满
+ 等待订单状态 +
+
+ {elseif condition="$pinkBool eq 2 && !$userBool"} + +
+
+
拼团已结束
+ 请您参加别的拼团 +
+
+ {elseif condition="!$pinkBool && !$userBool"} +
仅剩{$count}个名额
+
+ 剩余 +
+
+ 00 + : + 00 + : + 00 +
+
+ +
+
+
正在拼团中...
+ +
+
+ {elseif condition="!$pinkBool && $userBool"} +
仅剩{$count}个名额
+
+ 剩余 +
+
+ 00 + : + 00 + : + 00 +
+
+ + +
+
+
正在拼团中...
+ +
+
+ {/if} +
+
+
+
+ +
+ +
+
+
+ + + +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/order_pink_after.html b/application/wap/view/first/my/order_pink_after.html new file mode 100644 index 00000000..a7b9ba98 --- /dev/null +++ b/application/wap/view/first/my/order_pink_after.html @@ -0,0 +1,172 @@ +{extend name="public/container"} +{block name="head_top"} + + +{/block} +{block name="title"}{$store_combination.title}{/block} +{block name="content"} + + +
+
+
    +
  • +
    +
    +
    +

    {$store_combination.title}

    +

    {$pinkT.people}人团·已团{$store_combination.sales}

    +

    + {$pinkT.price}拼团劲省 +

    +
    +
    +
  • +
+
+ +
+
+
    +
  • + +
    团长
    +
  • + {volist name="pinkAll" id="vo"} +
  • + {/volist} + +
  • + +
+
+
+
+ {if condition="$userBool"} +
+
拼团成功
+ 商家正在努力发货,请耐心等待 +
+ {else/} +
+
拼团失败
+ 退款中 +
+ {/if} +
+
+
+
+
+ +
+ +
+
+
+ + + +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/order_reply.html b/application/wap/view/first/my/order_reply.html new file mode 100644 index 00000000..0087eb27 --- /dev/null +++ b/application/wap/view/first/my/order_reply.html @@ -0,0 +1,98 @@ +{extend name="public/container"} +{block name="title"}评价页面{/block} +{block name="content"} + +
+
+
+
+
+

{$cartInfo.cart_info.productInfo.store_name}

+

+

¥{$cartInfo.cart_info.truePrice}X{$cartInfo.cart_info.cart_num}

+
+
+
+
+ +
+
+
+
+ +

添加图片

+
+
+
+
+
+ 产品评分 +
+ + + + + +
+ 1 +
+
+ 商家服务 +
+ + + + + +
+ +
+ 立即评价 +
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/sign_in.html b/application/wap/view/first/my/sign_in.html new file mode 100644 index 00000000..07716fd2 --- /dev/null +++ b/application/wap/view/first/my/sign_in.html @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + 今日签到 + + + + + + + {include file="public/requirejs"} + + +
+
+
+
+

当前积分

+

{$userInfo.integral|floatval}

+

签到{$signCount}天

+
+
今日已签到
+
立即签到
+
+
+
+
+
    + {volist name="signList" id="vo"} +
  • +
    +

    每日签到奖励

    + {$vo.add_time|date="Y-m-d",###} +
    + +{$vo.number} +
  • + {/volist} +
+
+
+ +
+
+ + 新品推荐 + +
+ +
+
+
+{include file="public/right_nav" /} + + + \ No newline at end of file diff --git a/application/wap/view/first/my/spread_list.html b/application/wap/view/first/my/spread_list.html new file mode 100644 index 00000000..f67025d0 --- /dev/null +++ b/application/wap/view/first/my/spread_list.html @@ -0,0 +1,95 @@ +{extend name="public/container"} +{block name="title"}我的推广人{/block} +{block name="content"} + +
+
+
+ + 推荐人统计:{$total} +
+
+
+
    +
  • +
    +
    +
    + +

    + 关注时间: {{item.add_time}} +
    +
    +
  • +
+

正在加载中

+

加载更多

+

没有更多了

+
+ +
+
+
+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/my/user_cut.html b/application/wap/view/first/my/user_cut.html new file mode 100644 index 00000000..656d7919 --- /dev/null +++ b/application/wap/view/first/my/user_cut.html @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + {include file="public/requirejs" /} + 我的砍价 + + +
+
    +
  • +
    +
    +
    +
    +
    + + +
    继续砍价
    + + + +
    砍价失败
    + + + +
    重砍一个
    + +
    +
      +
    • +
      +
      当前价
      +
    • +
    • +
      +
      最低价
      +
    • +
    • +
      +
      人帮砍
      +
    • +
    +
    + + {{todo.difftime.days}}{{todo.difftime.hour}}{{todo.difftime.minute}}{{todo.difftime.second}}秒后结束 +
    +
  • +
+
+ + + + \ No newline at end of file diff --git a/application/wap/view/first/my/user_pro.html b/application/wap/view/first/my/user_pro.html new file mode 100644 index 00000000..dcb7d476 --- /dev/null +++ b/application/wap/view/first/my/user_pro.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + 我的余额 + + + + + + + + +
+
+
+
+

{$userInfo.now_money}

+ 我的余额 +
+
+ 立即提现 +
+
+
    +
  • +

    昨日推广佣金

    +

    {$number}元

    +
  • +
  • +

    累计获得佣金

    +

    {$allnumber}元

    +
  • +
  • +

    累计已提佣金

    +

    {$extractNumber}元

    +
  • +
  • + 佣金明细 + +
  • + + 推广详情 + + */ ?> +
+
+
+{include file="public/right_nav" /} + + \ No newline at end of file diff --git a/application/wap/view/first/public/container.html b/application/wap/view/first/public/container.html new file mode 100644 index 00000000..0849e7bc --- /dev/null +++ b/application/wap/view/first/public/container.html @@ -0,0 +1,33 @@ + + + + {include file="public/head" /} + {block name="title"}{/block} + {include file="public/style" /} + {block name="head_top"}{/block} + + + {include file="public/requirejs" /} + {block name="head"}{/block} + + + +{block name="content"}{/block} +{block name="foot"}{/block} +{include file="public/foot" /} +{include file="public/right_nav" /} + + diff --git a/application/wap/view/first/public/error.html b/application/wap/view/first/public/error.html new file mode 100644 index 00000000..2252d7d1 --- /dev/null +++ b/application/wap/view/first/public/error.html @@ -0,0 +1,33 @@ + + + + + {if condition="$title"}<?php echo ($title);?>{else/}错误提示{/if} + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/wap/view/first/public/foot.html b/application/wap/view/first/public/foot.html new file mode 100644 index 00000000..1231fd41 --- /dev/null +++ b/application/wap/view/first/public/foot.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/application/wap/view/first/public/head.html b/application/wap/view/first/public/head.html new file mode 100644 index 00000000..a32cfa2a --- /dev/null +++ b/application/wap/view/first/public/head.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/application/wap/view/first/public/requirejs.html b/application/wap/view/first/public/requirejs.html new file mode 100644 index 00000000..b43971a5 --- /dev/null +++ b/application/wap/view/first/public/requirejs.html @@ -0,0 +1,51 @@ + + \ No newline at end of file diff --git a/application/wap/view/first/public/right_nav.html b/application/wap/view/first/public/right_nav.html new file mode 100644 index 00000000..11aeddef --- /dev/null +++ b/application/wap/view/first/public/right_nav.html @@ -0,0 +1,10 @@ + + + + + */ ?> +
+ + +
+ diff --git a/application/wap/view/first/public/store_menu.html b/application/wap/view/first/public/store_menu.html new file mode 100644 index 00000000..a2c54eb6 --- /dev/null +++ b/application/wap/view/first/public/store_menu.html @@ -0,0 +1,29 @@ +
+controller();$now_a = $request->action(); +$menu = [ + ['c'=>'Index','a'=>'index','name'=>'店铺主页','class'=>'home'], + ['c'=>'Store','a'=>'category','name'=>'商品分类','class'=>'sort'], + ['c'=>'Store','a'=>'cart','name'=>'购物车','class'=>'car'], + ['c'=>'Service','a'=>'service_list','name'=>'联系卖家','class'=>'server'], + ['c'=>'My','a'=>'index','name'=>'我的','class'=>'user'], +]; +?> + \ No newline at end of file diff --git a/application/wap/view/first/public/style.html b/application/wap/view/first/public/style.html new file mode 100644 index 00000000..615274ed --- /dev/null +++ b/application/wap/view/first/public/style.html @@ -0,0 +1,5 @@ + + + + + diff --git a/application/wap/view/first/public/success.html b/application/wap/view/first/public/success.html new file mode 100644 index 00000000..82c93f78 --- /dev/null +++ b/application/wap/view/first/public/success.html @@ -0,0 +1,33 @@ + + + + + {if condition="$title"}<?php echo ($title);?>{else/}成功提醒{/if} + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/wap/view/first/service/server_ing.html b/application/wap/view/first/service/server_ing.html new file mode 100644 index 00000000..9883effd --- /dev/null +++ b/application/wap/view/first/service/server_ing.html @@ -0,0 +1,44 @@ + + + + + + + + + 联系客服 + + + + + + + + + +
+

+ + + \ No newline at end of file diff --git a/application/wap/view/first/service/service_ing.html b/application/wap/view/first/service/service_ing.html new file mode 100644 index 00000000..46a93bd8 --- /dev/null +++ b/application/wap/view/first/service/service_ing.html @@ -0,0 +1,64 @@ +{extend name="public/container"} +{block name="title"}与{$to_user.nickname}聊天中{/block} +{block name="head_top"} + + + + + + + +{/block} +{block name="content"} +
+

+ + +{/block} diff --git a/application/wap/view/first/service/service_list.html b/application/wap/view/first/service/service_list.html new file mode 100644 index 00000000..7b0a51fd --- /dev/null +++ b/application/wap/view/first/service/service_list.html @@ -0,0 +1,32 @@ +{extend name="public/container"} +{block name="title"}客服列表{/block} +{block name="head_top"} + +{/block} +{block name="content"} + +{if condition="$merchant.id > 0"} +
+ +
{$merchant.mer_name}
+ 进店 +
+{/if} +
+ {empty name="list"} +
+ +

当前没有在线客服

+
+ {else/} +
    + {volist name="list" id="vo"} +
  • + + {$vo.nickname} +
  • + {/volist} +
+ {/empty} +
+{/block} \ No newline at end of file diff --git a/application/wap/view/first/service/service_new.html b/application/wap/view/first/service/service_new.html new file mode 100644 index 00000000..b7894845 --- /dev/null +++ b/application/wap/view/first/service/service_new.html @@ -0,0 +1,76 @@ +{extend name="public/container"} +{block name="title"}聊天记录{/block} +{block name="head_top"} + + + + +{/block} +{block name="content"} +
+

+ +{/block} \ No newline at end of file diff --git a/application/wap/view/first/static/wap/bargain/css/FJL.picker.css b/application/wap/view/first/static/wap/bargain/css/FJL.picker.css new file mode 100644 index 00000000..bdad29c6 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/css/FJL.picker.css @@ -0,0 +1,34 @@ +/** +* 选择列表插件 +* varstion 2.0.0 +* by Houfeng +* Houfeng@DCloud.io +**/ +.mui-pciker-list li,.mui-picker,.mui-picker-inner{box-sizing:border-box;overflow:hidden}.mui-picker{background-color:#ddd;position:relative;height:200px;border:1px solid rgba(0,0,0,.1);-webkit-user-select:none;user-select:none}.mui-dtpicker,.mui-poppicker{left:0;background-color:#eee;box-shadow:0 -5px 7px 0 rgba(0,0,0,.1);-webkit-transition:.3s;width:100%}.mui-picker-inner{position:relative;width:100%;height:100%;-webkit-mask-box-image:-webkit-linear-gradient(bottom,transparent,transparent 5%,#fff 20%,#fff 80%,transparent 95%,transparent);-webkit-mask-box-image:linear-gradient(top,transparent,transparent 5%,#fff 20%,#fff 80%,transparent 95%,transparent)}.mui-pciker-list,.mui-pciker-rule{box-sizing:border-box;padding:0;margin:-18px 0 0;width:100%;height:36px;line-height:36px;position:absolute;left:0;top:50%}.mui-pciker-rule-bg{z-index:0}.mui-pciker-rule-ft{z-index:2;border-top:solid 1px rgba(0,0,0,.1);border-bottom:solid 1px rgba(0,0,0,.1)}.mui-pciker-list{z-index:1;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:perspective(750pt) rotateY(0) rotateX(0);transform:perspective(750pt) rotateY(0) rotateX(0)}.mui-pciker-list li{width:100%;height:100%;position:absolute;text-align:center;vertical-align:middle;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-size:1pc;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#888;padding:0 8px;white-space:nowrap;-webkit-text-overflow:ellipsis;text-overflow:ellipsis;cursor:default;visibility:hidden}.mui-pciker-list li.highlight,.mui-pciker-list li.visible{visibility:visible}.mui-pciker-list li.highlight{color:#222}.mui-poppicker{position:fixed;z-index:999;border-top:solid 1px #ccc;bottom:0;-webkit-transform:translateY(300px)}.mui-poppicker.mui-active{-webkit-transform:translateY(0)}.mui-android-5-1 .mui-poppicker{bottom:-300px;-webkit-transition-property:bottom;-webkit-transform:none}.mui-android-5-1 .mui-poppicker.mui-active{bottom:0;-webkit-transition-property:bottom;-webkit-transform:none}.mui-poppicker-header{padding:6px;font-size:14px;color:#888}.mui-poppicker-header .mui-btn{font-size:9pt;padding:5px 10px}.mui-poppicker-btn-cancel{float:left}.mui-poppicker-btn-ok{float:right}.mui-poppicker-clear{clear:both;height:0;line-height:0;font-size:0;overflow:hidden}.mui-poppicker-body{position:relative;width:100%;height:200px;border-top:solid 1px #ddd}.mui-poppicker-body .mui-picker{width:100%;height:100%;margin:0;border:none;float:left}.mui-dtpicker{position:fixed;z-index:999999;border-top:solid 1px #ccc;bottom:0;-webkit-transform:translateY(300px)}.mui-dtpicker.mui-active{-webkit-transform:translateY(0)}.mui-dtpicker-active-for-page{overflow:hidden!important}.mui-android-5-1 .mui-dtpicker{bottom:-300px;-webkit-transition-property:bottom;-webkit-transform:none}.mui-android-5-1 .mui-dtpicker.mui-active{bottom:0;-webkit-transition-property:bottom;-webkit-transform:none}.mui-dtpicker-header{padding:6px;font-size:14px;color:#888}.mui-dtpicker-header button{font-size:9pt;padding:5px 10px}.mui-dtpicker-header button:last-child{float:right}.mui-dtpicker-body{position:relative;width:100%;height:200px}.mui-ios .mui-dtpicker-body{-webkit-perspective:75pc;perspective:75pc;-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.mui-dtpicker-title h5{display:inline-block;width:20%;margin:0;padding:8px;text-align:center;border-top:solid 1px #ddd;background-color:#f0f0f0;border-bottom:solid 1px #ccc}[data-type=hour] [data-id=title-i],[data-type=hour] [data-id=picker-i],[data-type=month] [data-id=title-i],[data-type=month] [data-id=picker-d],[data-type=month] [data-id=title-d],[data-type=month] [data-id=picker-h],[data-type=month] [data-id=title-h],[data-type=month] [data-id=picker-i],[data-type=time] [data-id=picker-y],[data-type=time] [data-id=picker-m],[data-type=time] [data-id=picker-d],[data-type=time] [data-id=title-y],[data-type=time] [data-id=title-m],[data-type=time] [data-id=title-d],[data-type=date] [data-id=title-i],[data-type=date] [data-id=picker-h],[data-type=date] [data-id=title-h],[data-type=date] [data-id=picker-i]{display:none}.mui-dtpicker .mui-picker{width:20%;height:100%;margin:0;float:left;border:none}[data-type=hour] [data-id=picker-h],[data-type=hour] [data-id=title-h],[data-type=datetime] [data-id=picker-h],[data-type=datetime] [data-id=title-h]{border-left:dotted 1px #ccc}[data-type=datetime] .mui-picker,[data-type=time] .mui-dtpicker-title h5{width:20%}[data-type=date] .mui-dtpicker-title h5,[data-type=date] .mui-picker{width:33.3%}[data-type=hour] .mui-dtpicker-title h5,[data-type=hour] .mui-picker{width:25%}[data-type=month] .mui-dtpicker-title h5,[data-type=month] .mui-picker,[data-type=time] .mui-dtpicker-title h5,[data-type=time] .mui-picker{width:50%} +[data-type=date] .mui-dtpicker-title h5, [data-type=date] .mui-picker { + width: 33.3%; + font-size: 0.28rem; + font-weight: normal; +} +.mui-dtpicker-title{ + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; +} +.mui-pciker-list li { + font-size: 0.23rem; +} +.mui-dtpicker-header button{ + background-color: #ccc; + border-radius: 0.09rem; +} +.mui-dtpicker-header .mui-btn-blue{ + background-color: #6c56a5; + color: #fff; +} +.mui-dtpicker-header { + padding: 6px 14px; +} \ No newline at end of file diff --git a/application/wap/view/first/static/wap/bargain/css/base.css b/application/wap/view/first/static/wap/bargain/css/base.css new file mode 100644 index 00000000..7ba6d119 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/css/base.css @@ -0,0 +1,363 @@ +@charset "UTF-8"; +/** + *相关初始化 +*/ +.color-red { + color: #f15f60 !important; +} +.color-green { + color: #52c87a !important; +} +.color-yellow { + color: #ffba00 !important; +} +.color-orange { + color: #f8693c !important; +} +.color-blue { + color: #30d1ff !important; +} +.font30 { + font-size: 0.32rem !important; +} +.font32 { + font-size: 0.32rem !important; +} +/* padding20 */ +.padding20 { + padding: 0.2rem; +} +/* pad20 */ +.pad20 { + padding: 0 0.2rem; +} +/* padding30 */ +.padding30 { + padding: 0.3rem; +} +/*pad30 */ +.pad30 { + padding: 0 0.3rem; +} +/* pad-left20 */ +.pad-left20 { + padding-left: 0.2rem; +} +/* margin-top:10 */ +.martop10 { + margin-top: 0.1rem; +} +/* margin-top:15 */ +.martop15 { + margin-top: 0.15rem; +} +/* margin-top:15 */ +.martop20 { + margin-top: 0.2rem; +} +/* martop108 */ +.martop108 { + margin-top: 1.08rem !important; +} +.mar0 { + margin: 0 !important; +} +.label-text { + display: inline-block; + margin-left: 0.1rem; + padding: 0 0.04rem; + font-size: 0.18rem !important; + color: #fff; + border-radius: 3px; +} +.label-text.post-txt { + background-color: #ff3d3d; +} +.label-text.send-txt { + background-color: #4eb047; +} +.label-text.new-txt { + background-color: #ff8a00; +} +.price { + font-size: 0.32rem; + color: #ff0300; +} +.price i { + font-style: normal; + font-size: 0.22rem; +} +.price span { + font-size: 0.28rem; +} +.old-price { + font-size: 0.24rem; + color: #999; +} +/* layout */ +.acea-row { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; + -webkit-box-lines: multiple; + -moz-box-lines: multiple; + -o-box-lines: multiple; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +/* 辅助类 */ + +} +.acea-row.row-middle { + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} +.acea-row.row-bottom { + -webkit-box-align: end; + -moz-box-align: end; + -o-box-align: end; + -ms-flex-align: end; + -webkit-align-items: flex-end; + align-items: flex-end; +} +.acea-row.row-center { + -webkit-box-pack: center; + -moz-box-pack: center; + -o-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; +} +.acea-row.row-between { + -webkit-box-pack: justify; + -moz-box-pack: justify; + -o-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; +} +.acea-row.row-column { + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} +/* 竖排组合 */ +.acea-row.row-column-all { + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: justify; + -moz-box-pack: justify; + -o-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; +} +/* 横排组合 */ +.acea-row.row-wrap-all { + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: justify; + -moz-box-pack: justify; + -o-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; +} +/* 上下左右垂直居中 */ +.acea-row.row-center-wrapper { + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: center; + -moz-box-pack: center; + -o-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; +} +/* 上下两边居中对齐 */ +.acea-row.row-between-wrapper { + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: justify; + -moz-box-pack: justify; + -o-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; +} +/* acea-row-pad20 */ +.acea-row-pad20 { + padding: 0 0.2rem; +} +/* box-card-20 */ +.box-card-20 { + padding: 0.2rem; + background-color: #fff; +} +/* box-card-pad20 */ +.box-card-pad20 { + padding: 0 0.2rem; + background-color: #fff; +} +/* box-card-30 */ +.box-card-30 { + padding: 0.3rem; + background-color: #fff; +} +/* radius-box */ +.radius-box { + border-radius: 5px; + background-color: #fff; +} +/* 轮播图 */ +.slider-banner { + position: relative; + width: 100%; + overflow: hidden; +} +.slider-banner img { + display: block; + width: 100%; + height: auto; +} +.slider-banner .swiper-pagination-bullet-active { + background-color: #fff; +} +.img-box img { + display: block; + width: 100%; + height: 100%; +} +.avatar img { + display: block; + width: 100%; + height: 100%; + border-radius: 50%; +} +/* 动画 */ +@-moz-keyframes progress { + from { + background-position: 0; + } + to { + background-position: 4.8rem; + } +} +@-webkit-keyframes progress { + from { + background-position: 0; + } + to { + background-position: 4.8rem; + } +} +@-o-keyframes progress { + from { + background-position: 0; + } + to { + background-position: 4.8rem; + } +} +@keyframes progress { + from { + background-position: 0; + } + to { + background-position: 4.8rem; + } +} +@-moz-keyframes bgshow { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 50% { + opacity: 0.5; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} +@-webkit-keyframes bgshow { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 50% { + opacity: 0.5; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} +@-o-keyframes bgshow { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 50% { + opacity: 0.5; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} +@keyframes bgshow { + 0% { + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + } + 50% { + opacity: 0.5; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + } + 100% { + opacity: 1; + -ms-filter: none; + filter: none; + } +} diff --git a/application/wap/view/first/static/wap/bargain/css/reset.css b/application/wap/view/first/static/wap/bargain/css/reset.css new file mode 100644 index 00000000..2f910e40 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/css/reset.css @@ -0,0 +1,105 @@ +body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td,select { margin:0; padding:0; } +body, button, input, select, textarea {font-size:.3rem; line-height: 1.5; } +h1, h2, h3, h4, h5, h6{ font-size:100%; } +address, cite, dfn, em, var { font-style:normal; } +code, kbd, pre, samp { font-family:couriernew, courier, monospace; } +small{ font-size:12px; } +ul, ol { list-style:none; } +sup { vertical-align:text-top; } +sub{ vertical-align:text-bottom; } +legend { color:#000; } +fieldset, img { border:0; } +button, input, select, textarea { font-size:100%; } +table { border-collapse:collapse; border-spacing:0; } +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, menu, nav, section { display: block; } +input,input[type="search"],button,select,option,textarea,a{ outline:none; border:0; -webkit-appearance:none;border-radius: 0; background:none;-webkit-box-sizing:border-box;box-sizing:border-box;} +/* custom */ +a { text-decoration: none; -webkit-backface-visibility: hidden; color:#333; } +body { -webkit-text-size-adjust: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', arial, sans-serif, 'Droid Sans Fallback'; color:#333;} +div,section,header,footer{-webkit-box-sizing:border-box; box-sizing:border-box;} +input{line-height: normal; box-sizing:border-box;} +.fl{ float:left; } +.fr{ float:right; } +.clear{ clear:both; height: 0; line-height: 0; font-size: 0; } +.clearfix:after{ content:"."; display:block; height:0; visibility:hidden; clear:both; overflow: hidden; } +.flex { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: box; + display: flex; +} +.con-cell{ display: table-cell; height: 100%; vertical-align: middle; } +.old-price{text-decoration: line-through;} + +.icon { + width: 1em; height: 1em; + vertical-align: -0.15em; + fill: currentColor; + overflow: hidden; +} + +[v-cloak] { + display: none; +} +.iconfont{ + font-size: .36rem; +} +/* 一像素边框 */ +@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) { + .border-1px::after { + -webkit-transform: scaleY(0.7); + -moz-transform: scaleY(0.7); + -o-transform: scaleY(0.7); + -ms-transform: scaleY(0.7); + transform: scaleY(0.7); + } + .border-1px::before { + -webkit-transform: scaleY(0.7); + -moz-transform: scaleY(0.7); + -o-transform: scaleY(0.7); + -ms-transform: scaleY(0.7); + transform: scaleY(0.7); + } +} +@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) { + .border-1px::after { + -webkit-transform: scaleY(0.5); + -moz-transform: scaleY(0.5); + -o-transform: scaleY(0.5); + -ms-transform: scaleY(0.5); + transform: scaleY(0.5); + } + .border-1px::before { + -webkit-transform: scaleY(0.5); + -moz-transform: scaleY(0.5); + -o-transform: scaleY(0.5); + -ms-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) { + .border-1px::after { + -webkit-transform: scaleY(0.33); + -moz-transform: scaleY(0.33); + -o-transform: scaleY(0.33); + -ms-transform: scaleY(0.33); + transform: scaleY(0.33); + } + .border-1px::before { + -webkit-transform: scaleY(0.33); + -moz-transform: scaleY(0.33); + -o-transform: scaleY(0.33); + -ms-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.ovf{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;} +.ovf2{word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;} + + + + diff --git a/application/wap/view/first/static/wap/bargain/css/style.css b/application/wap/view/first/static/wap/bargain/css/style.css new file mode 100644 index 00000000..b4e0ed8e --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/css/style.css @@ -0,0 +1,234 @@ +body{background-color:#f5f5f5;} + +/*砍价*/ +.cut-con .cut-bg{background-image:url("../images/cut-con-bg.png");background-repeat:no-repeat;background-size:100% 100%; +width:100%;height:5.21rem;} +.cut-con .cut-bg .header{width:100%;height:0.5rem;text-align:center;font-size:0.22rem;color:#fff; +background-color:rgba(255,255,255,0.2);} +.cut-con .cut-bg .header span{color:#170405;margin-right:0.13rem;} +.cut-con .cut-bg .activity-rules{font-size:0.26rem;color:#ff3d3d;background-color:#fbe806;width:0.8rem;height:0.8rem; + border-radius:50%;box-shadow:0.02rem 0.02rem 0.08rem #FBE806;text-align:center;right:0.23rem;position:fixed;top:0.76rem;} +.cut-con .cut-bg .activity-rules .activity{padding-top:0.03rem;} +.cut-con .cut-bg .time{font-size:0.24rem;width:4.5rem;height:0.5rem;border-radius:50rem;background-color:#fff;margin:2.78rem auto 0 auto; + text-align:center;line-height:0.5rem;color:#F60509;} +.cut-con .cut-bg .time span{color:#333333;} +.cut-con .cut-padding{padding:0 0.52rem;margin-top: -1.2rem;} +.cut-con .figure{background-image:url("../images/cut-con-line.jpg");width:100%;padding: 0.05rem;border-radius:0.15rem} +.cut-con .figure .picture{width:1.9rem;height:1.9rem;} +.cut-con .figure img{width:100%;height:100%;border-radius:5px;} +.cut-con .cut-write{width:100%;background-color:#fff;margin:0 auto;border-radius:0.15rem; padding:.25rem .2rem;-webkit-justify-content: space-between; justify-content: space-between;} +.cut-con .cut-write .figure-con{width: 2.73rem; padding: .1rem 0;} +.cut-con .cut-write .write-text{font-size:0.26rem;color:#262626;line-height:1.4;} +.cut-con .cut-write .write-money{font-size:0.24rem;padding:0 0.2rem;} +.cut-con .cut-write .write-num{color:#FF3D3D; font-size: .2rem} +.cut-con .cut-write .write-num span{font-size:0.4rem;} +.cut-con .cut-write .write-yuan{color:#AAAAAA;text-decoration-line:line-through; font-size: .22rem; } +.cut-con .cut-tip{font-size:0.28rem;color:#fff;text-align:center;margin:0.45rem 0 0.42rem 0;} +.cut-con .cut-tip span{color:#FFE400;font-size:0.35rem;} +.cut-con .cut-tip img{width:0.7rem;height:0.7rem;border-radius:50%;margin-right:0.24rem;} +.cut-con .progress {border:1px solid #481500;border-radius:50rem;background-color:#fff;height:0.32rem;transform: translateZ(0); + box-sizing: border-box;-webkit-box-sizing:border-box;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;margin:0.27rem auto 0 auto; + width:5.3rem;} +.cut-con .progress.compressing view.bar{background-color:#bad753;} +.cut-con .progress div.bar{min-width: 30%;width: 100%;height: 100%;border-radius: 50rem; animation: progress 3s linear 0s infinite; + background: linear-gradient(410deg, rgba(186,215,83,1) 0%, rgba(186,215,83,1) 31%, rgba(144,195,30,1) 33%, rgba(144,195,30,1) 67%, rgba(186,215,83,1) 69%); + background-size: 0.52rem 0.34rem;} +.cut-con .cut-pro{font-size:0.18rem;color:#FF3D3D;width:2.7rem;height:0.4rem;line-height:0.4rem;text-align:center; + background-color:#FFE400;margin:0 auto;border-radius:0.1rem;position:relative;} +.cut-con .cut-pro:after{position: absolute;content: "";right: 50%;bottom: -0.2rem;width: 0;height: 0;border-right: 0.15rem solid transparent; + border-top: 0.2rem solid #FFE400;border-left: 0.15rem solid transparent;display: inline-block;margin-right: -0.075rem;} +.cut-con .pro-money{font-size:0.22rem;width:5.3rem;margin:0.13rem auto 0 auto;} +.cut-con .pro-money .original-price{color:#FFFFFF;} +.cut-con .pro-money .target-price{color:#FFE400;text-align:right;} +.cut-con .cut-but{height:0.8rem;line-height:0.8rem;background: linear-gradient(to top, #ffbb00 0%,#ffe400 100%); + border-radius:50rem;box-shadow:0 0.09rem 0 #E09300;font-size:0.34rem;color:#FF3D3D;text-align:center;font-weight:bold; + margin:0.4rem 0 0.58rem 0;width:100%;} +.cut-con .cut-but2{background: linear-gradient(to top, #cccccc 0%,#ffffff 100%);color:#999999;box-shadow:0 0.09rem 0 #B1B1B1;} +.cut-con .cut-but3{width:100%;height:0.8rem;line-height: 0.785rem;border-radius:50rem;font-size:0.34rem;color:#ffe400; + text-align:center;margin:0.4rem 0 0.58rem 0;border:0.03rem solid #ffe400;} +.cut-con .bargain-list{background-color:#ffe7e7;border-radius:0.17rem;padding-top:0.01rem;} +.cut-con .bargain-list .list-title{text-align:center;background-image:url(../images/cut-con-title.png);background-repeat:no-repeat; + background-size:100% 100%;width:5rem;height:0.06rem;margin:0.43rem auto;position:relative;} +.cut-con .bargain-list .list-title span{font-size:0.34rem;color:#FF3D3D;position:absolute;top:-0.24rem;left:50%;margin-left:-0.73rem; + width:1.46rem;} +.cut-con .cut-ul{max-height:5.45rem;overflow-y:auto; -webkit-overflow-scrolling: touch; padding:0 .2rem;} +.cut-con .cut-ul .cut-item{width:100%;height:1.08rem;border-bottom:0.01rem dashed #FF3D3D;;margin:0 auto;} +.cut-con .cut-ul .cut-item .li-pic img{width:0.66rem;height:0.66rem;border:0.02rem solid #FF3E3E;border-radius:50%;margin-right:0.12rem;} +.cut-con .cut-ul .cut-item .li-pic .pic-title{font-size:0.24rem;color:#FF3D3D;width:1.8rem;} +.cut-con .cut-ul .cut-item .li-pic .pic-con{font-size:0.2rem;color:#999999;margin-top:0.06rem;width:1.8rem;} +.cut-con .bargain-list .cut-display{text-align:center;font-size:0.22rem;color:#FF9A9A;height:0.81rem;line-height:0.81rem;} +.cut-con .bargain-list .cut-price{font-size:0.26rem;color:#ff3d3d;} +.cut-con .bargain-list2{margin:0.5rem 0;padding-bottom:0.24rem;} +.cut-con .bargain-list2 .shop-con{padding:0 0.3rem;line-height:1.5;font-size: 0.26rem;color: #666666;} +.cut-con .bargain-list2 .shop-con img{width:100%;margin:0.15rem 0;} +/*弹框 */ +.cut-con .popup{ + width: 5.1rem; + /* min-height:4.6rem; */ + border-radius:0.35rem; + z-index:99; + background-color:#fff; + position:fixed; + top:25%; + left:50%; + /* margin-left:-3rem; */ + padding:0 0.3rem 0.5rem 0.3rem; + display:none; + transform: translateX(-50%); + } +.cut-con .popup .popup-title{ + font-size:0.32rem; + color:#FF3D3D; + text-align:center; + height: 1rem; + line-height: 1rem; + border-bottom:1px dashed #FF3D3D; + position:relative; + } +.cut-con .popup .popup-con{font-size: 0.22rem;color:#666666;margin-top:0.32rem;} +.cut-con .popup .popup-con li{line-height:1.7;} +.cut-con .popup .popup-title .iconfont,.cut-con .popup2 .popup2-bg .iconfont{ + font-size: 0.2rem; + position:absolute; + top:-0.26rem; + right:-0.54rem; + width: 0.6rem; + height: 0.6rem; + border-radius:50%; + color:#FF3D3D; + background-color:#F7F7F7; + text-align:center; + line-height: 0.6rem; + } +.cut-con .mask,.cut-con .mask2{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#000;opacity:0.7;display:none;} +.cut-con .popup2{ + width: 5.12rem; + /* height:6.4rem; */ + position:fixed; + top:50%; + left:50%; + /* margin-left:-3rem; */ + /* margin-top:-3.2rem; */ + background-color:#FFFFFF; + z-index:99; + border-radius:0.32rem; + transform: translate(-50%,-50%); + padding-bottom: .4rem; + } +.cut-con .popup2 .popup2-bg{background-image:url("../images/cut-con-mask.png");background-repeat:no-repeat;background-size:100% 100%; + width:100%;height:3.4rem;position:relative;} +.cut-con .popup2 .popup2-bg .iconfont{right: -0.2rem;} +.cut-con .popup2 .popup2-con{font-size: 0.26rem;color:#666666;padding: 0.2rem 0.5rem;text-align:center;line-height:1.7;} +.cut-con .popup2 .popup2-con span{color:#FF3D3D;} +.cut-con .popup2 .popup2-bnt{ + width: 3.25rem; + height: 0.6rem; + background: linear-gradient(to top, #ff3d3d,#ff7579); + color:#fff; + line-height:0.73rem; + font-size: 0.26rem; + border-radius:50rem; + margin: 0 auto; + display: block; + /* padding-bottom: .4rem; */ + } +.cut-con .mask2{display:block;} +@keyframes progress +{ + from {background-position:0;} + to {background-position:4.8rem;} +} +/*我的砍价*/ +.user-cut .usercut-item{background-color:#fff;padding:0 0.2rem;margin-bottom:0.13rem;} +.user-cut .usercut-item .picture{width: .55rem;height: .55rem;} +.user-cut .usercut-item .picture img{width:100%;height:100%; border-radius: 5px;} +.user-cut .usercut-item .requirement{width: 3.8rem;font-size: 0.26rem;color:#000000;} +.user-cut .usercut-item .time{font-size:0.26rem;color:#333333;margin-top:0.1rem; padding: .15rem 0; font-size: .22rem;} +.user-cut .usercut-item .time span{color:#f60509;} +.user-cut .usercut-item .time .time-icon{display: inline-block; width: .25rem; height: .25rem; background-image: url('../images/time-icon.png'); background-size: 100% 100%;vertical-align: -.04rem;} +.user-cut .usercut-item .usercut-ticket{padding:0.2rem 0;} +.user-cut .usercut-item .item-list{border-bottom:0.02rem dashed #dddddd;} +.user-cut .usercut-item .item-list .item{flex:1 25%;-webkit-flex:1 25%;text-align:center;border-left:0.02rem dashed #DDDDDD;margin:0.22rem 0;font-size: 0.22rem;color:#333333;} +.user-cut .usercut-item .item-list .item:nth-of-type(1){border-left:none;} +.user-cut .usercut-item .item-list .item .money{font-size: 0.3rem;color: #282828;margin-bottom:0.03rem;} +.user-cut .usercut-item .status{height:0.9rem;font-size:0.26rem;color:#ffa200;} +.user-cut .usercut-item .but{width:1.4rem;height: 0.45rem;border-radius: 30px;/* box-shadow: 0 5px 10px #ffb9b9; */color: #ff3d3d;font-size:0.24rem;text-align:center;line-height: 0.45rem;border: 1px solid #ff3d3d;} +/*会员绑定*/ +.member-binding .header{width:100%;height:3.76rem;background-color:#444552;padding:0.36rem 0.2rem 0 0.2rem;} +.member-binding .bindings-header{ + background: linear-gradient(top,#efaa3f 0%,#e48d05 100%); + background: -webkit-linear-gradient(top, #efaa3f 0%,#e48d05 100%); + background: -moz-linear-gradient(top,#efaa3f 0%,#e48d05 100%); +} +.member-binding .header .card{width:100%;height:3.4rem;border-radius:0.2rem 0.2rem 0 0; + background: linear-gradient(left,#aab0bd 0%,#d4d4dd 100%); + background: -webkit-linear-gradient(left, #aab0bd 0%,#d4d4dd 100%); + background: -moz-linear-gradient(left,#aab0bd 0%,#d4d4dd 100%);} +.member-binding .bindings-header .bindings-card{ + background: linear-gradient(left,#7750d7 0%,#9572ea 100%); + background: -webkit-linear-gradient(left, #7750d7 0%,#9572ea 100%); + background: -moz-linear-gradient(left,#7750d7 0%,#9572ea 100%); +} +.member-binding .header .card .card-bg{background-image:url("../images/member-binding-line.png"); + background-repeat:no-repeat;background-size:100% 100%;width:100%;height:100%;padding:0 0.51rem;align-content: space-between; +-webkit-align-content:space-between;} +.member-binding .header .card .bindings-card-bg{background-image:url("../images/member-binding-line2.png");} +.member-binding .header .card .card-bg .head-portrait{height:1.3rem;font-size:0.3rem;color:#fff;width: 100%;} +.member-binding .header .card .card-bg .picture span{width:3.63rem;} +.member-binding .header .card .card-bg .picture img{width:0.74rem;height:0.74rem;border-radius:50%;margin-right:0.18rem;} +.member-binding .header .card .card-bg .vip{font-weight:bold;} +.member-binding .header .card .card-bg .bindings-vip{color:#ffee00;} +.member-binding .header .card .card-bg .english{font-size:0.42rem;color:#fff;font-family:"Arial";font-style:italic;font-weight:bold;} +.member-binding .header .card .card-bg .status{font-size:0.26rem;color:rgba(255,255,255,0.6);margin-top:0.05rem;} +.member-binding .header .card .card-bg .text{height:1.43rem;} +.member-binding .nav{background-color:#464855;padding:0 0.2rem;height:1.5rem;} +.member-binding .bindings-nav{background-color:#efaa3f;} +.member-binding .nav .nav-item{flex:1;-webkit-flex:1;text-align:center;font-size:0.26rem;color:rgba(255,255,255,0.7);} +.member-binding .nav .nav-item .num{font-size:0.3rem;color:#fff;margin-top:0.1rem;} +.member-binding .member-binding-con{margin:0.2rem 0.2rem 1.6rem 0.2rem;} +.member-binding .member-information{background-color:#fff;padding:0.15rem;margin-bottom:0.15rem;} +.member-binding .member-information .information-border{border:1px solid #e3dcf7;padding:0 0.28rem;} +.member-binding .member-information .information-border .title{font-size:0.3rem;color:#282828;text-align:center; + height:0.96rem;line-height:0.96rem;font-weight:bold;} +.member-binding .member-information .information-border .item{border-top:1px dashed #dddddd;font-size:0.28rem;color:#282828; +padding:0.27rem 0;} +.member-binding .member-information .information-border .item .item-con{color:#828897;} +.member-binding .member-information .information-border .item .iconfont{font-size:0.35rem;color:#bfbfbf;margin-right:0.16rem;} +.member-binding .bill .bill-item{height:1.27rem;border-top:1px dashed #dddddd;font-size:0.24rem;color:#999999;} +.member-binding .bill .bill-item .name{font-size:0.28rem;color:#333333;margin-bottom:0.03rem;width:4.4rem;} +.member-binding .bill .bill-item .money{font-size:0.3rem;color:#e88320;} +.member-binding .but{width:7.1rem;height:0.86rem;line-height:0.86rem;font-size:0.28rem;color:#fff;text-align:center;display:block; +background-color:#E88320;border-radius:50rem;position:fixed;bottom:0.4rem;left:50%;margin-left:-3.55rem;} +/*内容详情*/ +.content-details{padding:0 0.2rem;} +.content-details .header{padding:0.56rem 0 0.32rem 0;border-bottom:1px dashed #b8b8b8;} +.content-details .header .title{font-size:0.36rem;color:#333333;} +.content-details .header .time{font-size:0.22rem;color:#888888;margin-top:0.15rem;} +.content-details .header .time span{margin-left:0.33rem;} +.content-details .details-con{font-size:0.28rem;color:#555555;line-height:1.5;padding-top:0.3rem;} +.content-details .details-con img{width:100%;height:auto;margin:0.3rem 0;} + + + +/*砍价列表*/ +.cut-list .header-bg{background-image:url("../images/cut-list-bg.jpg");background-repeat:no-repeat;background-size:100% 100%; + width:100%;height:3rem;} +.cut-list .swiper-text{width:100%;height:0.72rem;background-color:#fff;padding:0 0.2rem;} +.cut-list .swiper-text .swiper-slide img{width:0.52rem;height:0.52rem;border-radius:50%;} +.cut-list .swiper-text .swiper-slide span{width:5.34rem;font-size:0.26rem;color:#545454; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;} +.cut-list .cut-ul{padding:0 0.2rem;margin-bottom:0.4rem; display: -webkit-flex; display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; -webkit-justify-content: space-between; justify-content: space-between;} +.cut-list .cut-ul .cut-item{background-color:#fff;border-radius:0.1rem;margin-top:0.15rem;width: 2.92rem;} +.cut-list .cut-ul .cut-item .cut-text{ padding:.25rem 0.2rem;} +.cut-list .cut-ul .cut-item .cut-text .cut-con{width: 100%;} +.cut-list .cut-ul .cut-item .cut-text .icon{display: inline-block; width: .27rem; height: .21rem; background-image: url('../images//count-icon.png'); background-size: 100% 100%;} +.cut-list .cut-ul .cut-item .picture{width:100%;height: 2.92rem;} +.cut-list .cut-ul .cut-item .picture img{width:100%;height:100%;border-radius:0.1rem 0.1rem 0 0;} +.cut-list .cut-ul .cut-item .cut-con .name{font-size:0.24rem;color:#262626;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;} +.cut-list .cut-ul .cut-item .cut-con .text{font-size:0.22rem;color:#666666; text-align: center; margin: .2rem 0;} +.cut-list .cut-ul .cut-item .cut-con .text span{font-size:0.26rem;color:#999999;margin-left:0.2rem;} +.cut-list .cut-ul .cut-item .cut-con .num{font-size:0.38rem;font-style:normal;} +.cut-list .cut-ul .cut-item .cut-con .zero{font-size:0.28rem;font-style:normal;} +.cut-list .cut-ul .cut-item .cut-text .cut-but{font-size:0.2rem;width:100%;height:0.5rem;background-color:#ff3d3d; +text-align:center;border-radius:50px;color:#fff;line-height:0.5rem;box-shadow: 0 5px 10px #ffb9b9;} +.cut-list .cut-ul .cut-item .cut-text .cut-but .cut-but-icon{display: inline-block; width: .27rem; height: .23rem; background-image: url('../images/cut-but-icon.png'); background-size: 100% 100%; vertical-align: middle;margin-right: .1rem;} + diff --git a/application/wap/view/first/static/wap/bargain/css/swiper.min.css b/application/wap/view/first/static/wap/bargain/css/swiper.min.css new file mode 100644 index 00000000..b222bea4 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/css/swiper.min.css @@ -0,0 +1,15 @@ +/** + * Swiper 3.4.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2017, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: March 10, 2017 + */ +.swiper-container{margin-left:auto;margin-right:auto;position:relative;overflow:hidden;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate(0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-box-lines:multiple;-moz-box-lines:multiple;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex:0 0 auto;flex-shrink:0;width:100%;height:100%;position:relative}.swiper-container-autoheight,.swiper-container-autoheight .swiper-slide{height:auto}.swiper-container-autoheight .swiper-wrapper{-webkit-box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;align-items:flex-start;-webkit-transition-property:-webkit-transform,height;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform,height}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-wp8-horizontal{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-wp8-vertical{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;-moz-background-size:27px 44px;-webkit-background-size:27px 44px;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:.3s;-moz-transition:.3s;-o-transition:.3s;transition:.3s;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-white .swiper-pagination-bullet{background:#fff}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-container-vertical>.swiper-pagination-bullets{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-o-transform:translate(0,-50%);-ms-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:5px 0;display:block}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 5px}.swiper-pagination-progress{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progress .swiper-pagination-progressbar{background:#007aff;position:absolute;left:0;top:0;width:100%;height:100%;-webkit-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;-o-transform-origin:left top;transform-origin:left top}.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar{-webkit-transform-origin:right top;-moz-transform-origin:right top;-ms-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top}.swiper-container-horizontal>.swiper-pagination-progress{width:100%;height:4px;left:0;top:0}.swiper-container-vertical>.swiper-pagination-progress{width:4px;height:100%;left:0;top:0}.swiper-pagination-progress.swiper-pagination-white{background:rgba(255,255,255,.5)}.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar{background:#fff}.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar{background:#000}.swiper-container-3d{-webkit-perspective:1200px;-moz-perspective:1200px;-o-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-coverflow .swiper-wrapper,.swiper-container-flip .swiper-wrapper{-ms-perspective:1200px}.swiper-container-cube,.swiper-container-flip{overflow:visible}.swiper-container-cube .swiper-slide,.swiper-container-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-container-cube .swiper-slide .swiper-slide,.swiper-container-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-active .swiper-slide-active,.swiper-container-flip .swiper-slide-active,.swiper-container-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top,.swiper-container-flip .swiper-slide-shadow-bottom,.swiper-container-flip .swiper-slide-shadow-left,.swiper-container-flip .swiper-slide-shadow-right,.swiper-container-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-slide{visibility:hidden;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-zoom-container{width:100%;height:100%;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-box-pack:center;-moz-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-moz-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;object-fit:contain}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-moz-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;-moz-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:"";width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;-webkit-background-size:100%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/application/wap/view/first/static/wap/bargain/font/iconfont.css b/application/wap/view/first/static/wap/bargain/font/iconfont.css new file mode 100644 index 00000000..fa355976 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/font/iconfont.css @@ -0,0 +1,155 @@ + +@font-face {font-family: "iconfont"; + src: url('iconfont.eot?t=1530525478386'); /* IE9*/ + src: url('iconfont.eot?t=1530525478386#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAD4oAAsAAAAAgGwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZXOUvLY21hcAAAAYAAAAJQAAAF9gEqtcpnbHlmAAAD0AAANeMAAHGI5JpiFWhlYWQAADm0AAAAMQAAADYTlXRFaGhlYQAAOegAAAAeAAAAJAmVBd1obXR4AAA6CAAAADAAAAEMEJv//2xvY2EAADo4AAAAiAAAAIi6FNYIbWF4cAAAOsAAAAAfAAAAIAF/AiZuYW1lAAA64AAAAUUAAAJtPlT+fXBvc3QAADwoAAAB/wAAAxStMm4SeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkEWKcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGBwYKl42MDf8b2CIYT7OcBoozAiSAwDoewyceJzF1MlOFGEUxfF/Mwk4i4jzhIrzLCKiogvjwpUL4ooExRlEJSHNRnFWNBqjJK58Aja81KF5Cj3Vh0W71JhYlV+nulI3Xf19516gEai3g9YAdT8o+YrSd98tVe/X01q931Aa8feTbPdzaymrVW1qV4c61aVe9alf1zSgQY1qXBOa1EfNam6+e/5z5UtlZmHq509Xl0VNVU9N1ZDGXFXW05qqr4tVf3qU/JYnuVJzXq05hxnx+ZDpmvNTtWonu2liDUvpZC/L2cgeTrPea7SBLV6HdrbR5dVYwVbWsYx97GcVB7xGhzjMEY5yjOOc8G+foo5NbKbba7Xdq9XLWfr8ec5ncXWeHVygnxYucoldtNHMalayhB7O0OGXafqL//2PjtL/++nfj2XFR/31xW+XrbzIryjCu4ZK4f1DdeGdRPXhPUUN4d1FjeF9Rk3hHUdLwnuPmsMpQC3hPKDWcDKc5XBGUHsUHaWOcG5QZzhBqCuKjlNPUNSdCecL9QbFs31RdKD6w+lD18I5RAPhRKLBKFZOQ+GUohvhvKKb4eSi4XCG0a0oJoFuh3ON7oQTju6Gs47uhVOP7ofzjx6EOwGNhHsCjYa7A42F+wQ9Cop9exzuHfQk3EVoPNxPaCKKaaVyuMfQZLjb0NOgWMtn4b5DU0Gxrs+j+syLcHeil1G9fhXV2tdRrX0T7mP0NtzR6F24t9H7oNi36aDI0Ydw56OP4RmAZsPTAM2F5wLz3eEJwfzn8Kyg8iU8Nah8Dc8PKt/Ck4TKTHimsDAVdPwCZqIPP3ic7X15nCRFlX++iLzvOrKyquuu6qrs+6hzZnqmey5gmrkvGGYYDhluBhiQQxQYYABBDgVFdJFzABcYEWUVEEHgp4CKF+uxqKx8RHFXWd1dZHWlk9+LzOqmBxk/u/x+/6BUZ8adkREvIr7xXkTka07guNdfoA/TJBfjerhRbim3huNA7IeSSbJQ9BpDpB+couC4cZN6Za8olUtDdAG4JTGeqLUaVVeURAtMyEG9WGt5Q8SDZmOcjEEtkQVIpbvWRyuZKP0wqEkvd7F/ILkVnHw5Y40P+pMDE/FaISafpUejqWj0ClkUBJkQ3jJhu5tQBEUV/d2C1eU8nO8ledBTXteKQ4xCOnrkBxsnZyuuArBzJ8TSBfPOiUhXBK8PdCVi0ZRkG3Kyyyh3x+GsF7VkTM9Wf87hT8a6PkUfoHO4CtZ0nJvgFnIbuG3cB7DGQ1A2QcqBi6ZTbg6B18Ya1VptdI1Du1l3MI6G8WFQmBwd6AXPHUIauAkHQxll6hjeqNQSLqORh5mzQBo+OI4vk8KnE/Vau1UlB0XK6VwZ9Bs0aAyWCnPiifhorrsSBIz2lnP99il3/4Lnf3F3aH7pD4Lwhy+FJiydnORNS+AL9AuXyZomf+IbvH/9wtOHREsT6xccgEFnbDkeYNvBkiCZ0pGnApx5NE91kYrwX1YEcl1z+jb01IU5bZq0s3aikFk4sLw6yvyuDcLMO+/+Rc/MO9H0f7ltG2ZoSYuXX/YFqtka/41PrP/t8ICoW+JoE/1TH+u58agjbuillinQwXtPPOW+AdBkk6PYBt+in6ctTuNcLouUn0XHDoECKtNypNgsw+sPvsrzrz4Ymjc+y/PP3hiYt4+D8W3aFF594MFXBeHVBx949bWf8M/eFKa46Vmy3H9+nLU5wfft5Dm6E98scVwMJChie22md2x+bTPPvbYZXXRnYL22+Qh6M3uGx2ceoU/QxZzBDXFzuXl7l9IbjQWdYAJaXhX7frXZDgptgegmWhOQkBxaqjZatURcLM8FAo/6guA/GpoHpMb6c0npQKoIpjQI0LUsm07yK0DhLebVEtnsQC6XoItnnkBz6hM9NRC7E39QeaLIbVkxvTrw3ck/KjzIgR+WZIYzeHFsPN9Pd9MVXB+3iTuEew93Ipa+0WxVvSr2Qw9LLmLnc+NIYpf1QDeslttq41/Vq6A3h4MtPhqXglrisMDuXAui8Q/DyphNcwLwoRg1IaypMO2gO6HRqO8vbV68eLO0f63ZALAsWczG46n07WefdUcXLbh5VY7ZU6+QTRtHtm7IAe+9f42YMJ102ommaGNw8Ygs5a4+Gi68kQLsPwE3rIH8cB4voJAfyuMFyw1jy0db9XRtISELa+l666ObI5bZl03kJANO3kXIrlMAYpHuwqCxRzqmYkfzFUKzXeMrFVmFaDqKYyPWVZPlTccAufUSO5bJHSb7Mci47DX5pJvLDedyQT+4id5Mj+Qy3AD2AkRGd7TkVVvtWLlUbcfGEfJyINF6jogSiDEKSJp2rGiysFqiXfJYJxmHoGvM+Nr1HMQRYE0W+mpElSk9fG4xa//KHOmC9aWU87tjUo7AR6f+FD1uFTyysZxK/M5/RE0Iv6zli8OUFyg1qKahKRR5KlCyQK3Gq6Isi1U9Kc0XjjCNlASH1XJwm5uFesb/FsTMdMTPW3Cx/zO4CYOgDobiv2fka4RqoitQURNcaRnzbI8mAGRdBlPbLk2PhcfpI3ScG+bGuAO49RxXKYlSpdVssL5SD0cE1jjhCjMYir1FEJ2ZUT0LNWHWCJ/tpr09i+L+A5IGa53xysR6QtZPTGwgIPv3OGOliQ0AGyaq4w4cKAQRzDswD2DewMAYwNjUc4E1EASR6qyYX1cKtznJXPrWTAEfCR9MubtTGeZbT0rZ3dF4GIpv81gWYUZjU69PZ4G5+v88KyagCcfRL5MnuSLXwDlkEkdY1WsMQ0AJbNW6JOZhtDOyWgwnRltefDQcUMMQwkUeKrNABSNCxKBfBgC68OXLL395IcEBAEBC3wRBJxYB5n777LO/PRembf/86QoERKrVVtRqsFMBQRAvu4WQWz4oSSqlphJ4LqWUSMCLAGdfSciVZ/N8x/7oTA4TG34DLI8VNVZNhidP4pw5wYkBGs7j9sNRICbqxUgR2IQfKVbKrJbVsHaIiKzhcb5D7gFnzWKzUa3giBkP0EasFlnaBKYtizvAsGC5/0l4AJZbBqDj2KeqCyS6tDm+pZA/aN68/cg876mYAx9eAx92po5XJUnvzvTMT7bOBjE53+tvRaLLMv3piA4P+Mv0CPzd75ThgreC1zYM9q+x1NU9hWElHr/5qadujscn9YyeiGqRBQVJKozF7SX5mEY79fse8j8NxPkl3EpuLbcRezgrZaw1RMpFL5i53brrIOg76EIzByFfUAzc7jipesVSFfuygEBQZjgohGDIOnmRFttS0YND4LuRrLhJEPW0NrUrcYUeiehHDCxxu6OaFoX2mhYBbJVxHM/tHq8No56vRrtATMAf0HITka4uvy/a1VXuwjkDvuLvN0ZGc9bUfdavEedgp+YmtCM0NwJfsfzfavVSoqjp1UhPe6RHS2h49bQB2qvrYjoSSV8BXaV4uhRfmy6l05FEAiJAzz1wSUAL7Nc7yIM4U0Zwbu7lmkiLSDmSQ9iKRbB9GV0itMhqh9we9lZvH26IXwyVuZUqDiLSxvG4y/8eY05giJn7cH8WrvNPyFShQrqn/hCOYSL7K5GZwOv9e1kc9kU2Rz+Oc7TO2VycSyJGF7hu5GGb2JILuEU493E4Jy0IhlUWEVeqN8tO5451buZu4t2enZDOiogVsZ0jDLQd5EciGIYNjpSAyWgy2Z1Mbjo1+F35wgtzQtdvw/D5oe+Fqe7yCMBIeceVNH7ljsBNjkxGr8RUzPjqxhc2vLABnp/rl9D+6sZT34jy7w1Cpp7Bp8ml3SMwd2oReXQujHRPva88wtHXX3/9fB7oBdhKLW4x1hVHniSWcKi1EImqJQknmDxOPe0WTjdS6EZuE1uSdU7EJGwmhKoKe6bjpb9YpWX1rv1qkNLUVZlVWV/IQHqVmtNT+4+mNNBWmeWYl4E/ZWBqleWoz2g5ZsB+39RyCY0ZJL5WAyVZOyCFGa3JdPlmZnVmrQqaC7X9gzDTSsN/ZFZ/M5HTnlETWe0Z7YRnVId5nNw03rxI76OjnBP0v0U4JrlKrdWMNKrlYkl0IvHEGI6H2gR4ZQlHZxVjgk6HMWK5UhuHxgzT8tZuelLW87JTPcz8wZlG1TgjJn7g/f+uGqZCfqQahjr1vO7oeMW6up7WHcN4k+uUfJYsCrJ4NJs/1zTPHbz8clEhi4JHH1XEP+lOMqEDSit/7gj435/Te2iWU7B+y5AjbbTceoTVg3EK1EExi6GoVw2mE+x6yDMQyBHkyphUxti4gJGrthN5SLBWXVtKzp2bLJHzvYWj5YRmpLsHaq3BkVqrdfTQAkrr1U21o4/wnxf0qGEVIpJbjxYN27AiToRSqihx3croDuGTRXidKybhnKrUu3rbMfXRww5emFfGHQfpYouGAjnDlm0lOzz1ey2VjyZGelKmaccTuVIjGrcIEQiVaMAzsDp+A3n8GreKO4w7PuA/G0GZS2ySEB3ERRxoCbcdMBCNqhdyle1moxXKjUy0bDMhrBwyCIyvQKgdY8DbbEgzyQKKNAPm02uOYxj9ZCF/2uSK21dM7sgXkfPcctrHtcEMTorVzKB6/WF1GtFzeiSajgA0vJz0+EeuekLOV+sA9Wq2WoOP2FpWsyw0bN8Hy7GAmGicb4rrVx54eqFYLJ6xfOV60yjHPlQ7U4R0HmrL8eF8l3iodZlh28ZlRjRqXOY14JoneP7xa6BW3VOt16t7ymWW7R7dsvRTdctQZVW3mGyCxLqXXINoG2V8lQds2shDMBqRoyzDRbbu/0FP5vWX4V/0fFKfek23x3Xk0ND9G/gXzc3rU3/SOzR/ku5BPi2KOIhzWMCatQLSBrMyTr9CWSRsFg7mYEIZTqNsHxcZ+KFUD0jV5rTthSVphzDh1DuJ4Zrv1xYBSTca7Up1wchIDmARxF74wkU8LKqRo0YXA3/RbQzR34so/V5ZA11+b8e6UNRs8Zz3ibYmXvDeIAk5VDlXKfZRMkSJpwqjJeXcZs7fmK+tIGQFvvxu/wrd0tYpmqas0yx9E2YpXcCef9/7WF4XSBiwCesOWPcfk9/QCkMPhXgKwAGw2z+0ATv8q2m3fyhzngqnMnKLAc2fJr/mZKRUhqvgKBxlPVQSPafmJhj3zjiXRpWhRpEBT1GotxxRKjtligOVuvV2nZYp+Y8xkxeM+Z967RfJAv1Q4bWPFZI0nSy8dgYZPGgH3TowdtL8+b9aBpNjxy46Brb0IOu2kojwKBSSq1YlC1MnJAuFJPz8UjhoLX8CxP3fQPy555g5PQ8/Tn7BWSgj5zmP4QQg+EmRcJWlHRkCKFcb7Xoi7s3YpcDGXlMssckM238BQkgzHEE4/zHuBXkSevlrv0liH8snaTyw/dgL0ejeF3wIov4fo/mU7aTysHB4ZCHkU46NbvJiITn1aVZ2silZ8EXoBui+MDAvYob/y2g0liyAY0ci8ytzDgQ4cE5lfiRiO1jxsJ+iUP4V8hhaCvKTXKXM2KlGtYQSUrXZaAcLJB2ZgnXN5rSIIDH+SyTcCKR70ngNm9GcUbCzHk7GrdYkRDNRsn3t2u2EtIu5nujCOEuUPilqzh2KFaxUq6e9DGBZmw3QdScRctK6BSuzqbGKGWV94vX/Qx+j3Vw5kHKW4fhB7sFl+MugxkH4YfPONOm9GTZAqrzB8pQrjIUP3Sz8DYaiONtTaRadW/vaMLd30SI21ZOHoy6AG52YwECY0zv1Hd22ddjNTP/QN7mTtg3Xh7b/KVDnY3qyvnduC5KxqT3RVCpK1seS0IJ239Se3jnwRytp4fVZsFzbdi34naV/WLNt7cMMh6Zdy1qtDn58me5GfmqA28x9Ejshk1fxaociTA2nnTZj42vBigEDhXD5IMGWEyiD9SAiYDLCNmyxeYpJO4Q5SmLQgDhjxZi3jUiDWY5DgDlB5hNsUhsnmAKfZhl3XoHP9XcQCJEIGeJG46CLeooRS80l2xPdQNRsPHWwPTqvZnc3TduyI8mD4wfK0o6Tek+6Zc1FGcPsMue5Q6ctbDQ2nJtBZpPYycqJY6WYW4ZSxq6P16xcsVKQ16myyGPjJgFUNzEwkI5QVZDKxXwaUFJJRCvVaMIWFCGRL9ku5XUhmuzvKzjxQj8slq1VC2qnLaguqq6vZ7T4nIFmjPI8lXNxdyyX1yOHZrZvO+aWHssmN3g3bhk+ttdp6W5SMtYsSJSzfYsHDjg1axt2rZJTeEHglUwkWXcEv0hkIRqrmLqlCv1UMjWbp/m0pepgRavVqAWSknLzlOiyrgt8v5HGluiuMzzEBv0SWcJmmJgCK+GL8AWyxF8GXwzWwx6jXw7WtgZmr2s1hkgsx7zIeEhieYgE7dGZBNgKBkw9OsXzU4+gueT83Vcogho3Ivo99+q2EVd45d49eqqo77k3Mqjbn6WLhSAhJt98284lU9cqSdcA0Pbco4PhJpV77jWKSf0z99j6YOQzQd97jH4pKFMO8e5NpQKxNDwzMeZA8uC/H5kS2AteE5aef9ud/vN6Sb8T325cDgJ7PbDXP/rIzOv9f8AkmKKY0i8Hnr0TgnWNL9O78Z0OSvGDKDNwQsDrN8YJjuEcwQFvEhR1mPRXZEyKVGTM42w3w4NGlWamnlqwBpzeepbMydZ7HXRt8w9STVOFu5i5D/dismY+OS7T6EkkehqZqeuZixxnxpFORty8Co3AZVzJvBgcznOP0G9jmXsRNxsMGYM1u2ZremnPBNcxO4t6jshLKH5Xu8nJ5oCeNBRqi3J/elWjvirdL4s2VQzXGDAS/rcS9MMJ/5uvOklz8YhWdFsO5M9uZKuEVLONs/PgtNyiNrLY7D96yXF9fccv7pRjEstB2HwLbRKd+je62B/3x4P+dSmdoudx/cFKQUd8KuaCkjE2LaQew1MX6bcAxgNWDgsfCwSRQIhsF91O3wuElLOGlxCycJjYw+MA8YwLsejU72JRJ0b0WAzcjAMTw7cZMeW8qX8zUegmFjlPiaXV+1W83gdjdcq3VgDs11psIuu53LUBCu6U6ebBSiw3XctY3F5GcIpMqxe72QTIF6vpuPowMoEPq0Hf/C7yVYOcirNxfHbfrMQi2GNi49AswvOffp7nn//0lk+2/X9cCpfzz18wMuqfSX7K//jO3T8V4ICFPnzfP+f2n05Nti48gA1PE/N9lV5BjWBdWsO8YzjXp7H3l3G+H0SehMmxXKwYKbooewIKnxSnHQFlUjodhlIqk1XbKKy6MxJrER0s1RnwXv+KrQ89BPvDe9Ga+t7WrVd0gsjQ1q2/2hr8HsLb/5etGLwVPgGnb30QEv6VcLr/rw9+aOvUGexJTIzPPoS/IDE+GNAklL1NrourYl9sht3PCZlLafbC3sxkngPygnru5s3nquBlYU7W+9lX2Cj+SmguZEt+CwPz8ciBRxJyxLJ4Dqd275czSb4yBT9naQ4i5CBMGcqKj/ADWA4Rebl0IP1zMaHtVmgRkI9tjEOw1ipMr63NOKDoFK+E7l27oLxr6iEUC1GUSZmJXM7vcbPZwVyOnhzaUwLZf+ohUlr/j/+43hfJZ81UJoUM4mDuZshh9CDyv6E99WAzGBe/pI/QTMBRjjpsLdBkc2i469OuhxNksEkwDt7M/Ajh6hh9RLjqA/PP/dnquSsJ2FJ9Z5ESKyrKEZtOrB1a2U+IbmhR5CPlA6t8Oj24mZwsrPvmcbVjt+nG2XXXIdlRAqKrWxGgxUXVJW3ecjQlEaGkeOaQpMvWER1e+Tn697QPW44LenI7KFSwekdZQVrog1s2d19+8EptT286LvDv2XLYr752sRo/NzeSceqkb8vajxRWQilitLoHThfhfd/89cnH70eEcumzHNtj6fQNFXt0nmshN7WW28LWYsRgZRjFeA+F8SoD0NisBVAoeVJ7hl2tMokv7oplwfXYbDTdoZC1gumdR4FtOroMjsmYrKOIwUSspZoFthuNxmdtuvi/qZSXJ3r6yZmbVr3XVNSV7yGiokDNmlOw7BXvIeQ9K5YdQ3rz/uUIJ65lwXzMTpN104SdekQF3daPshIWGEkTDp+1LzP1Xb06kdm/D7OANQsJOWw/14FljbzEk40LF24kaJYXuLDWTJr4+HXA8gLN1jtyyOs/4qO0hGPf4+rcBLecW4FUClYoxgKO2C0nkOGVEGOQLcZwNzItkeCkU2RdGWGVdJbdOs4OC5oDUSIvPhhx3chDtut+8VAodfm/7CrD1rYHgy0y3mrVr/F3aFFbg6s0GwwVPUbHE9X38tASpKpdXdVUVpZyAwADOUmGOcNTt402R1pk6/CcqbvBQeYSmUzn5piLknXEje2GqBuNJKMBK9IT8CM/IS9g75iWaIa5Nvch7gruY9x13E3cp7n7uIe4J7hvct/nnude4v6Tex00cKEMozABG+FEuBg+BnfAA/AgfAWehu/Br8AnKbZSW2t4RTFeKYtxpFpDCC1PKpcCRy+U4kiPRqUTXg/tYba126h6wWJtO3D3A6PdGLD+VA6n/YDllIIF4DFgQFKenvYDYfgN1qA/2PyCGUkGymEPRZcJoVOa3hGUprvvzIr/GyHTaYQ/C0GsR4RHaEdkF2a5pX2EC+XqBJPj2QyKNWAeFA7RI3olq9PDkKkqt0sSK2bAmudBZHVmry1XvUYbpbEOw98KKOHVgzU0C5oBN+9IohRPINs/BlJpOJQ0MS2brz02Ui0iTgezXUPRZa+vTZAWop6EBML3iG1G1aANZmosSjOyAhYo7gYLRKwKzb1KFBYoIDIWKKiDE+4+SewhKBEd2b9XeLK+wPMFfuo1QXiA5/ds5/ntPPyrfxzPw/W8/yLP2zzfz/On8Xz6Ljset6+zHMc6jRl3M+MSFjb1e+ZsMOd7mWsLc/mvMifsZzuOfRBzkjXMvAPj/HYSDLZaaJDvJJFzQ/7Nfw5Z9IiuK5KimIqyVdG0qKZ1fC/u5YPv7OX1n+J1HS+wBE3DKx1a/upO8Ik/liFFpNslkgL5x4JEklS9XaVJIn1VgBSFHwOFJAiThhLPxFBgQOEGlOOMSMQ4TgMFFInEM3GiaGYU5QkmWso8RLuiQAygVAbpmE8KdJGkQn1FHaTlVKiMgCgvJTxdjHmNVnoagFijzucNfm5MBmh65eCHYnY6GjUjjlNMJNZbKiQKyFkh/qnqWVYsbp4lyBpRZeIWElTJOk6EsCdU3snFgbBSUqrIZ2zAHGUFZDmJN+QU/OWYi933Ovk4BHfOgXg+uN8yKAjtOOELyHkjO+3LKmsWk2SA0TqqdTNam8oprJEiegUUQ8Grb6/II/bywdmM/nw8MC9hbSJ8NHDfBdpZknSWJijymazCZ8rKh4QzBZ5H417FjEVNokmU8jQKkS5kjjUFo5AaVjRiStFMlAeU2QEFQTNim0gIUxAJNR/kT1DdCFtMjJof4P8LSR8xzJMpPUF1IpVRGZo9lmWb7xHFLSU70tPcFI/He+Jxne124yUliqwljgfVTjg2Cow8SqcOQCwb218WVYEXZZPYTtySkVg8PqDyohWPWQSLKshAIwzIBwMcf4n8+/8axz1owxLE8WPh/fABuAg+CFcinl8Hn4Jb4U64Fz6LEurD8Bg8zRC91GgXE/F6Zz1L6NgIAQ1ErTgiegMRGBE/DJ9O581C9BDF/zKih+5pRA+35P8c0Wdw/H+E6PsO+f+B6OFWB1v5Zlsd0pv8tCRFsFKMOyh7ZYahTmfmChF9mi61Ts29NyL7QwDNzsCyW23U4l4pXmu45WpA9b8Uk4O3jqFzp34vCETjJwII9u9HAH6Av49BsAD/4h+PEPxx3n/FZhj8idMYBucDzP14AMEMYwNEvoR5p15hZpMZ72WBW5jLD3AZ9mfmwbMgGA2E4BB4AwRmQ97/sRIgsCyxgf1mBO6gsxjEwXf28vpPh5ALZgi50wi8phN8+A8EWRZ+wE5g/EBSVQkN5XlEMOUHqro4AaqluZiRuA5fJa1jC99x5AQ1EkPnZkGShHWiJIldsiEvkIKfElWo+PFzKT2XfurPQv5OApZcVGIqFT8WBG0L8RDkFDNCkJwOeuBNaLgXSP45dk7bX5xBycDeF0qGvt6/BJJnaW8Nkn8viRBhJPN/K0q8KkGEkc7/Lc40A6r/W0Y+iKhRSdOkMKeyZmuyqspo5SVVllWJZ4/zxyKSSTxvQixmiOwYjjjxPwjhigGWPUN+tA8s+xR3B3cv9wD3GPd17lnuJ9wvuH/nprBMDlSgCYtgEtbCIXAGXACXMcyqBpjldtbihQ5WSR1sYpjF4r1OeL1j741Zb3ChIUfqFUNZgGHTNBcacp5vYFYYHi5Ehc/ujVlsZML/AJ/eArFmcG5GaJ6FRu7/ArHYgae/hFjtSLUsvYli036v6rUWQIhOKA4GC1zI3mEYW/eaXlMvoawUcp+0z3cQV35N5+d4Pkf9p+/h+Xv4O47h+WN4+IZ/Icadx//J4nmLv/pEnj+Rz91sxWLWlWYsZp7IXDeb8bh5HjN8hwWOssCTmLGRBf43C4MgcC1zkn4WegM6/Q2uETPwIrcl2M9/WWYnFTRZkmUEkYP38n1/Lx98Hr0RVVWwQxuy7P9EUFW8pnhNwyvFLFX1T0ADnbDsKQYAocEghRnfZuPlKWbM2UTp3pcriIJqq6IkqDwICwXghyRVwqt/nI/EI/zpIMH0lZTlzDR0ZGT87UEGAZmEeDywwnvG8abwWd6/U5ASuu57umGkDANeDY9tlBSDVfg4VtmIVmKVNWRvOk5X8DoEMAbjSxDGwuGMFEKMUYI/LzAvD8xPIYBwAiu08DonSlSRgGPkeB1NSCmvcwGEcMpNopgUkUd1RfEkgthpMBAx8GFCKcQEACEGNGYwIDZ4SarYBOcsjiu/bXxow2Y4H3bCZXAN/B3cALfDZ+CL72LEW2NEpVxFMdTrlNztyJ/94DWa6EKpNeBchtnByhA4UIbENG6Craz1w16szKynqy3MfTw8odsPIjsy4QZ1bjJOZbr43swZ9hl6/Hnc3wCirNhNcDBYWTYyzAw1r2YO7MIKCipES1+NsklaU3Vdzco6SpPkVk2SKcor6nnwAWSqnsV3SpEM0a9mjgvZkcULZR0fFQV5N0E5Qx9J266dSadR6kxHIiYyFY5pbs7YbFfSzqDg14XiqBaEvkPRaAlhq4Wapd5gooilIhjp6pgRuVOVPgF6VEe6ylRW7THV1ND7bXzzjTrgC6iB2KTK83VZBNXR4Xdsq9ey7SFGkq5om5HEMbt0Rii7j1EvHekEcohIbxejBmENHA/bYQdyMB+B++BpeAa+C9+H5+GX8G/vYtU+sMozsURtr2qBmA+OdUtuAiGGrX61W0MgWtA54p0HR0SpaIItrGNiSfSChMPwRgaJMIe2K3lS52ZrvKUAC4PDUfVQVmMfnwwBLQeLbhaUw5NOwV4COwyFvBXjgJDyyCZ5nRxEyUmEsp5XD8of3B47FlLD1BLiI1sKnLb/BiCue0AwLZH2K+LBvNKPboEMKMImuo3yQ0AE3eDJoMDTg6kmDKJX58lQ4BXISJ9ENxGhT7QtifSK/MGIlb0CeqTlZIXVub8zn5hYxTHGRYwBSp5kfsiaTBDdNgAWiIwbERcAenUygXzKwrmKMpdacYvOYfA2hzlXHBv8+ghvq0AJ3qoOhCDmvkNRseyKvGxKCV6+SxETIi+ZskvR/TBJEkmTqIi2JtyFlHapqItk2k8gmyDCXRLFvonI6VDxLmwJh3muqwpezgvvaxW2oCq8hKRmsxMETn+KsukL+cGXkOiUydsUSf+ShKL+SzKwR0B+Cauh3yH14N+DxCJ48TZhFlFNnOFMEhzNq75tfC1CCYZhDsqJB8Bq2Ahb4CjE2zNgF1zxLrruixMM1v3LDLWkchzRLdhtKKHE92c8WfiJndvZvZGCcxntYDnPCY5mYVIn2DbAkgYnIOtD4JbZCaPg4DDbg/XqVU8seX8L2LdShNryGmJHa23zsDErm8/Ydiaftca6urub3d3pZKEwUigcw46D8TzbGOAlNkpuYqwIpcidqTi6urq8WNGIpsQXhVTpN6BXCUlPdhES6xJ+/hOtmFmRLr5DQUqr1GqVnlarJ5K27XSRGasZXZrdZzG6jBQyVtKmyI9hxUxsrQbzjgPjzkaJETM3d4Fp6N2JRPcCfjANJJUiYFQSxEt2dSW5vreNId0oSe4Ph8BJwZr5xXAVXAsfhU/BHXA33AP/AI/AE+9iyVtjCdbcDU7semV2Ospl9VwAs0+Ne4xFcutus448FJMvQ6ZrDBxGAbbiJDU7rBZ7iJ1dmnkIk7CHPOktpEYxWP/+34X/9UPQP17K2J+Ecyha56U3s6WrS5kRPYOtzGyNpJjVvp9xT9nsOWjd1BUyTPeH1tnzGY4UUu9n1uWGrEmSJhsiG+aKqMa9WSFYFkmNV/4szTsUnHKgbJPBdUHeplyXlYRtjGzbBOksQBOiUcAQWCwLu0Qpn5fEXYL81W5F2sUWwtC4EZRdCnR1BdYKkVFEjrPWM+QuiMfV/0EIg6/M28awMtSRBzryXZz6Cyvk7emTGeE5jc76uJtAcJg+qdH0EG0CATAL7NAFCn4zq9+hv/k3gCKw5GFR1Ih6u0o05PUfFlXQFPF2UdFA+aKEggP/MC/oIBUh059RAAUMxI5UJSUz5zt0/J8li3vYGYI9osyr8h6247VH0p4E+R5BFIV7ZCi1nGzWaVGFAYNCW7FkMjbtY8M2+//AfzRgCRwBu94dvfsYvZ5UmsVVSGVPCriMdrAmI3pui31/0w/h3lW7xM7V43AfhmprgrRqeZIDi7BxXqu7I6M4xiegOTLqscPujiTia+OjbsKRnNpou/Y3MLpXHn2MGLOutWIibDtGcexrbQe2H00hYlxrRMmlBLI5XhTBpZQvWEQhVoGn1AURxBKQrADULfCEHbnlC5AkImTJO3TMf3Z4WHyZtcTLIh0aAvllJAQ49stycwTIy+z7pZcJHAuWRQSsqktl4Fmn4EHmE1Dg+YSNJnFBoFmALBUYyQpgc+xU8tvEghx4MIJ4MAfmw0Kc0feHA2AFyibHwClwNlwAl8Mn4S74AnwFvg7fg2fhR+9ixj4kk+kjou50Dt5MnnUHs2jW2XfqoTtRa5RQaEBTqnqNmpOotdEU3dmemZK8sZn1Fttbe4s/0pv8XrheXGNCzRtp3fIQhC4pALB6UwpK9NcPRTfBwJLBwSUDq8pDQ/sPDZUL/f0L+/tPufHGW3bvvvH66+mNN/YpOPzWybZdlQGlfbzlacc6SVVNVZVCTvp9sqJYHZ8ktV8RZEl8hc3irzAW/RVM+ycm4bzC5nhjkp0jmqQrWNSKFYqyX03G17xDUewkO84OE7UhUUrgtQyimVgsEy2dSHecuE2R8pIlSxaKN1grxqfBjKsfFAuJpmQZxTSpm1HTVHOMmpr0dVm8SZRk8UZRpqp0k6So0o2S+hAoN6nqjSpcIAnDorQCRcZhSRFBGZZhcVFG6ONybxv7enEUsBXcbXDcu6i2D06Iff/TOUPIPp8WpXqVrbe2Z85rM44owRZdh9np8eGZA4fsoyFJDPeyAt04bDXXQ2z760cZ7FblDPbsTHfK/J0V/29ipspZwNwgW06Z//YLIwFQShNZl0m6BJBYSYyoAa5qEWgDWFkhI7xDoaG+ONcvAjvvB2J/bnEsnc7x6dii3IDMdm7kgdyiWJq4EVia6ROBMrSkIPZllkKkn23nuKArPK/oWEqOK7ztcb0Rbgn2vP8JfgovwGvvju197Ms0y8Fn+GUnKOlbmHWWMSYO6hyao2+YyNJ0vs5o1lsNr9wM9NMw0wtC0F0PNCotgHrwoT1bYQ2+gkIbKzTtZ7bEXtJstbF92OWx93W2vDFalBLx4HJZoWbvfjc7dlua3g4vhx9LNutePeGOtibgbwBvTv8RPjOXDafZ91wc2D9CLkWedWvPS6oIC6mu09n3QhBV6XkckGDQcFjOuNH80XclFdTgB6r0XVBNhdRNmA4Cs04UU42Lnd+1OTedThuZTMbN2nEBpMg7FM1awTHmCEEoJ1hbUwPouDVThSg7+h1hJ4MA2FHwacPW7qFsCYe6fJIXgU8ixAFN8hJzuTwvSTyfBFkyqMjOCWGkErpFg0Y0osuGKKUksUsUDXbWir1FF2xdklJBuGGJOobdnjnDOKPH6D2xpllaIoFGraLyep7jam8bN9m3HBOwFCZhFayDg+BwOAKOh9Nmdqk+DjcF33R8ER6FJ+Hb8EP453exdR/SYLmEkhWWGeWsfmCLSSh+oYkhWaizozoepsIQ9hT7yLtZdxEDvY6c6JWl6SM9bvkvCJbljsK6t4ib1h4zfd66PatdmO2+qT1m2uVN/r9++PzP+wl5jpAS6X5OEO4XisLzPyoKnwN58DC6bbR+2KaRnpXzU9Gqa5lUzHeBmTDxSrEP6iIRPUShLwXBAKlUKtThoqu6Htf14eWULqeRxZQupuUzKD2DFlcTspqWBikdJNUIpRF6bg+lPfSj3ZR20xe2UbrtnXomaAm5m5CLGSE/J9wtIB0vFsSLhOKiE5tzdsypjzYK1ULXSmpRvNIa0tCyeoDRMGnXQWcNrScwWLNMc+BN4YcAO83dFMWMKJ4jirFwngms/xc+0YN5iHQHI8qdDKfAme9i2T74RCxD3GUnGlk+w9CquqXh4Og15ucGZyXj7Bxkrd0aDnQDTaf3Ztarpsvglpg8WWrU2efEyDiGFfvrhxgQM5PtdGpJZjHVJLo4zvdKwsLskq70nBXZlBhfyCtrlxKZiuJSEhfc9AHNruTCTDNdLrfK5c4pnggV4siQWUmBUKaA6J0KEl3tyUyKdxbzksYvTi95kF8YE1KZVXMyqaXZhYKhrlpKqYR0yCxMdjUmu1whLnfO7EBhuIDXEDFMECMWBRk5MT440Mf0ljSFL9InuQp3QKCXkGnLnIDyLB0lbnlap5WU4NuJboxo75WqnCMiO9Mbqs8OwiqtQF1jPfzWvW6S4CuFjk4NprmCPpZSbFPnIZcDet1pO66jUMgQWdVcXjn2Bl6H4vkXwpjJ3/HdmKApMoWYA+To5dV4QrWzpiHb1F1/YnF4KyUn/+n30TBJPE62LfdYioxpKDZNrj+xMHwYpdvhkmQ9blh85ZDhM2+g9IYzawd3y7pWHDFq37vllHFKx0+59bvn2WVTVmlyrLj6OFJcddAJXiyqxHNW6+btxljlpA8Vw/jUWKETX41HlVh+Jr6jY+p+cgbT+FNRgH7en/QP/DI84E924m4n20N9fG2M3T2jhI/M9Q+F3Q3/atjBkqEI//q99Am6KNAHH+pfW8qt5A7izuEuCrCZiyU4t8W1q5wncjM0x9aKzVYzM0uTiDArjbtvtkhgulJDLejtcab5xEMQrkqYZaf9xbdYrJ8GzlEByGNPAGHaRZ543H/9RXL+YYefR+l5hx92/j8ffQkhlxwdmoecRchZhwSm/wrZvo7pp9u+dt32B2Fo/6HBA4bW9rRaa1ut3my1Os/z/PMnnMkRe1EPT0bnNM7ddXrfUIa3U31LhHnbbf3bO5bubFZOBbeUTJYTPUxZeS6X1JmKNwve97jvCzgBdkr1+vcPP4+wQp1PyHn+5+nFRx9zaVCqS+GR6QIdsunsn6/djl0Gy4OlOqo0zJa7LwRWoLWt28Cbxwr1rYnJnNtfl9lHl15rQb7cK1KFELvLhHzrg8MZTxYejiSTJTcxCTmmpz23NlQ7F+g4upN+jY5h28a53Iyek4O5I3D0nca9n7uYu2rv9hVmSM70UAYalGcajO6jvfcZvvdxqxy80XzwppNYDr5mOq6GTfvE4wERpx57zH8NdsDwAcN4re9tQ3tDC6Ddm/UYbbIH7aB0x0EbTyN0x0ams+jIAyfRfM+yS+6j9L5LLvksz39u1zm3UnrrOefcgmYTiYRt15vM5UZykO+0nL87PGY4L9fbO7+X9GRjrltJpmDHE0GDTpfFf7obCzEysguL0Orrbe8G1mHmVf3/DItATtt40A44nRw5OV0Sv0w/d/Guz7FCXHIf2UhvOWe6LP6aCCtI8gDWgYbznfaC45MMOQtbexf09OTzPacmK0m8OK6E7fh5bMf9Aj1VGa4Xpcd53GJuHXcUdyq3k/sIdyN3N/dl7mnuGe457iXuFZRWI1CAQZgLS2AlrIXDUEI8Ey5iX/3v3d6VeqSMbcB0hGFjR7ABQxW/TMvNUNCmkTLGxcphAlqPBKeEqTTzjQQKQMPQ2bWagDpDXtaaFjihYMW4DalzuK8WHvb7C6kbwyTUNIk8mZvABwNlJc1ARdMEIH/gtdxQ0ZpUb8VY4RH0I40W+8I1IbLeF2E9uBlpVaVAr5JTrpakkod1bMZC9U9ZKFdFqdqWkC2qByoWpXKo5hcCFSkuVrbBPn0LPFjjBvtEDqccpx0oXHS8RMursn9PwtCLrWjFgtOJTPkWU7buiJLDlt4T1ZjDZMVgEOF79vKMYdZNhDnRrSEZcP5qCMBN97THn3idg+Ty5V4iA5AdQCPnqJblWMQ4rTwCn4bhix+HFo6EO68Ab74HE1lBk1ZIGs2aK4yYUliQFwmQ6JIkEZZjB05+Iytp8nKm/IOm90qxH6ZYIZDk02SRV6keRedGeUDGRRuIngJD1cw8owuouiiRhshgMl0WN9AfLF9eSWRzWKQ8lgjAcCwwV8x+Wlagy5iTqw6fGh3QJYU4A8IGqdzlDuZPBlVM8oZAIRkF44Ma8kMFOenA9nWylASatDxa4gHmCNlYOW2SVq9uFTKZzC5QRIEULdn/L3CTCeQnvnZQohdcAEeMvnqQ65EEAUeOLT7ZiQrgVIdeJm7/wdDdA+9/bGYAc4yson+GkXNgAivg+I9hc11uaf5jSFgVFqnm9TDc7Tfh6crI1A/g+71z2n3+fvClvFct+Pt1i2J3oDtFzou8d3zULOlqtV/hxYJtH5mn3YKQB1Kwu3lMhqwnS3Ti3omKQSICxT+KRzmR+VkcocQAgvU1yhPRyNrkkP8i063C35NqmkY/Vukc/zITsg4MYifIOP4PU1k4C0zN/6FmGioMqsZ1mJM9lgeRWKoE6aHkOis2UTKBEPL1z1Bw+wyjeQIMmWmjWwQeSHcq738N5tt5s1sHrTvb7f8cskaX1k1IdyK5DvqKQ2ddLPB3bUIcFxJpFI5bVwF3taTkyZD6U5IiJ5TTm9JJ6e8h7W/treZiti2B4vT3FGIRWwZlJfB3C0ek3AR2s4ko4y3SiFu302/QuYhbDkp8oT7xDdxx3NncLu6D3PXcDdw93D9wj3Pf4n7I/Zx7mXsVKNgogvVDC+btjVRQZNtTRTbyZ1wVN9THOzFL5V1cnD0HxQLdr232n0Jq4SG/Kns8CGJKEcOgcoWdW3GYZLcAAqVwYnVmSqsUnaLQUSHLcsniI5ViMwgL/p9IJ5sKQ02GjkznItOjmwu+PCtJaDI18F71DWaI6XadlQCRjkXPTIqBVJoL+KBpfqnZYIrHkWfyGjP/0sRlhWIJWZHaIjvYxNRNiZQttQtAH39jFp0ia/z/iGWFFNxXEjJR/z9SFcTkf+qRuv1bHIL4ZRpxPvu1ZYcTcviyycPhiMkxtgQyNn81wKoXpx6TNVWbHIVltWWaihIMJVOPWTFVX9uGZe21ukYsixB/bv8ilX04tYiq6qL+y+vLCCxp1JYCmfD/yFQfwkn+pzTD0OAoFentfxI2+nfDl/0uWSWKuqAPon0LVIWo/mAsE4VoOlaKp4GIle6YHkWZhJfRY4uGIB7PdA3H0tGCLMaiRtGLaFFVFxBaFNvgxZNjTONOrBBPp+OGKylaTGHfnNsa04/u/0TCbDLEUClN8ztFBUxRBvlsmU9KCSWJ0s7tzzwDpzzuT6E4O01A39+JmHXuzkgC+2by6mvdzJ3HmxHb2E7h8MkZkjU65Fo9f2y1f6Eq8/WRsbGRumwATsYxE+erRQCLWnUzSeEL0OivU0JJvb8BOkmN1PYDpNVIaslcy9AqjEieYuRTz6qS1z0IMNjtSepyK8KqNg7puCzEonp3RaVLCNMcJPBKRI52oonEKFIJIpUII4oWw6iuGHuyh+nS1WPdqrCErYFrckDWP8kSL/QJVNSFfsVVxEVYZllYJCpZkMu6rZV1hYeTktP/j+a/6CNUCWSHeTiacWTOYviZes5gaSFQNsY005QsmFEhXWIqF2dJbkyQq7Ll1M43kvXm9D+EIE3/m/yeiy7cw/N7LrxoD4zc/lNpjmiowkZRFzcKqiHOkZ++7vqv8/zXrz/8pgZvGJSfc+9xdzA1oIePRHlj7sC6JatXr/ZWrly5aAPsvGgPpXsuCkwQhX/aPYdlsVHA7DDPOR97ktJvXH/9N+gha9hHbuLBR4Lw0zvv/OlvDu5WM8dflesvTkwU+3NXhfX/Fr2cLkfZqhsRjWnQjlSEiNAuN0tek/EA4T5c3UFWoerhNMOUCDpUZPrUWl7Lo5f55/nnwkXRwmjFaMWGB+o9heFkwav11wbyxWKBafH+DDz8s5/5S3/2bM0Z1yJ0U2RoWYv09VF9fkzYEh0pVEdpHZaJ2ZR9nZBL2uH/VkOZ7ynyFHKIeZTiJrjV3BbuUOQQuUpxlhLYSNBEofZX9s9EMIrOimd6QdqzPryYPq40218JP8PofIMRah8iL089H+r3JqUWs6c+3VOv95CSx3T7ezGfJpmqziRMJfP5G32bqbqxfaa7zQ8jfAz3/zUKEPWZ8WgautLprjnkgDZ8uH0AQds/Fe3jMTP/1DBT+DDaUy+xXM/rZHJhMvdBx7qGaSFCI5pLXoO8PjOeg8g1TDMiGlss287ZdqcvP0Ofog2kmce1mZZ3RqtAZ0qHFrFys+wU8S6HrOU00WLhNDRDVuHNnZ4aU79Ml8tp0oWmtb7Pv6Jv/fhaQtaOk5MDuxfmDUxd0/k3Kyej7f/+kWPEiC6eKdniM6IZORBKaTiDHT0opf0PpUvkpHPxB+vG/bnj6wBteHJ83dTfD7IcBuHJ0N7+6NGSYUtniuIzkm0EOt65139M/w/1cAbux9l3MTfJHcitx3G7lY3cTq3qwXd57FtnZJzbbxEa1rgsMZWC5dn1ntY+9cb+x8yKKLWmfphhKmQzn1svWcL6z2U9IFVp6pqQDvdPdi3sWvYPzLO+H4nw1Y1Gwdj41VkUmbq2D3p7enr/0IciA4rc7h963W4XL/IEVLP+Fsx8vSiuxxfA7bnqNszTn4OkmUwmJxl5npq/PiDPRl3fyEj0VJj1y24yOey6yQjLkSnJZNb/BV6BIN8AeJxjYGRgYADiG00nmuL5bb4ycLMwgMD1BAk1GP3//39T1u3Mx4FcDgYmkCgAS44MAQAAAHicY2BkYGBu+N/AEMMm9R8IWLczAEVQgDMAsVYHfAAAeJxjYWBgYH7JwMDCgIQZoXQmmjgK/v8ftxwRmBeHeAUqn3Ul+XawSZGmHgAPrgWoAAAAAAB2ATgBcAGKAegCjgMQA5oEEASABQYFXAXcBkgGuAcqB74H5AhiCHgIygk4CYIKBArqCvgLQgt8C9YMGgwoDJAMvA0aDV4Npg34DigOvA8yEhYUfBaMGN4bjh2wIBIh8CP2JnQoYCr8LXQvdjAcMCowQDEuMhI0bjZYNtg3JDe+ODA4xHicY2BkYGBwZpJiMGIAASYg5gJCBob/YD4DABaXAagAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicbVJnc9swDPVLrRGPuEn33rtq7XTvkf4PnyLTImyLVCThZPvXF5Tt65fqKBEPIB7AB7X2Wpun0/r/c4I9nEMbHnwECLGPDrrooY8DDHAehzjCBVzEJVzGFVzFNVzHDdzELdzGHdzFPdzHAzzEIzzGEzzFMzzHC7xEhFd4jSFGOMYbvMU7vMcHfMQnfMYXfMU3fMcP/MQv/MYJ/rSw9GY0VaZdUab8lGNzSn5FSzKpN1dTPj6ax2ZGca1oKcG1tiYN5fySYpP6iY4l3E5pWoWp5ZoTrQLJrZWJvIIWNOqsLGumM8kNciFdsAmqgrNcVW3H70+YdGyDM+GbxBQ2vJLTkaSVJIn/sNTKSMmokljiGvCFX5LaroJHiTVR0Hw5D4QuYRuF233kjp4qE7oLZfJ2k7hQVVRQqiu/kkOa/UooZxSoQi6Zxb1tubVsaVhLO06VQVYapqhSC5VLCyqYSDOaY98JQyacCPckNqNOzRNaaxoORz1nNl4Bg5pTVTjdZDk8l6I7yQQf1NzMYUYLFujX7NQRiq1o4uvXXGppRzw7ZDkRh6DuBq1oY4uKtinT/ye/oLDmBTX0peWSrZtIJaHeVr0osfmqvxtBgzxtMzX2jKrLcZCrorRm7EmpfBy4grL8pu/RvkxvynNh64hValrJBZ3pLiA/UKv1F7Ws6K4A') format('woff'), + url('iconfont.ttf?t=1530525478386') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ + url('iconfont.svg?t=1530525478386#iconfont') format('svg'); /* iOS 4.1- */ +} + +.iconfont { + font-family:"iconfont" !important; + font-size:16px; + font-style:normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-jifen:before { content: "\e670"; } + +.icon-time:before { content: "\e627"; } + +.icon-guanbi:before { content: "\e676"; } + +.icon-tixing:before { content: "\e615"; } + +.icon-kefu2:before { content: "\e602"; } + +.icon-kanjiaweixuanzhong:before { content: "\e893"; } + +.icon-fenxiang:before { content: "\e736"; } + +.icon-chakan:before { content: "\e68a"; } + +.icon-gift:before { content: "\e63c"; } + +.icon-gouwuche:before { content: "\e604"; } + +.icon-xinwen-:before { content: "\e65e"; } + +.icon-rili1:before { content: "\e607"; } + +.icon-youhuiquan:before { content: "\e640"; } + +.icon-pinglun:before { content: "\e891"; } + +.icon-trumpet:before { content: "\e663"; } + +.icon-kefu:before { content: "\e78f"; } + +.icon-duihao:before { content: "\e603"; } + +.icon-qiandai:before { content: "\e6b1"; } + +.icon-xiangyou:before { content: "\e679"; } + +.icon-huiyuanqia:before { content: "\e638"; } + +.icon-shenfen-tianchong:before { content: "\e656"; } + +.icon-wenhao:before { content: "\e980"; } + +.icon-rili:before { content: "\e613"; } + +.icon-icon-:before { content: "\e617"; } + +.icon-icon-up:before { content: "\e608"; } + +.icon-duicuo-:before { content: "\e671"; } + +.icon-duicuo-1:before { content: "\e672"; } + +.icon-wenben:before { content: "\e623"; } + +.icon-xingming:before { content: "\e652"; } + +.icon-caret-right:before { content: "\e639"; } + +.icon-tuichu:before { content: "\e678"; } + +.icon-tongji:before { content: "\e687"; } + +.icon-erweima:before { content: "\e600"; } + +.icon-shenfenzheng:before { content: "\e605"; } + +.icon-wangguan:before { content: "\e6ac"; } + +.icon-msnui-telephone:before { content: "\e601"; } + +.icon-dianhua:before { content: "\e609"; } + +.icon-weixin:before { content: "\e63a"; } + +.icon-dingdan1:before { content: "\e606"; } + +.icon-wudizhi001:before { content: "\e661"; } + +.icon-wudingdan001:before { content: "\e662"; } + +.icon-wugerenxinxi001:before { content: "\e664"; } + +.icon-konggouwuche001:before { content: "\e665"; } + +.icon-wujifenjilu001:before { content: "\e666"; } + +.icon-wukefu:before { content: "\e667"; } + +.icon-wupinglun001:before { content: "\e668"; } + +.icon-wushangpin001:before { content: "\e669"; } + +.icon-wushoucang001:before { content: "\e66a"; } + +.icon-wushouyi001:before { content: "\e66b"; } + +.icon-wuxiaoxi001:before { content: "\e66c"; } + +.icon-youhuiquan001:before { content: "\e66d"; } + +.icon-wuliu001:before { content: "\e66f"; } + +.icon-sousuo:before { content: "\e673"; } + +.icon-pintuan:before { content: "\e60a"; } + +.icon-icon-up-copy:before { content: "\e894"; } + +.icon-xiangyou-copy:before { content: "\e895"; } + +.icon-home_:before { content: "\e67e"; } + +.icon-news_:before { content: "\e67f"; } + +.icon-person_:before { content: "\e680"; } + +.icon-home_1:before { content: "\e681"; } + +.icon-shop_:before { content: "\e682"; } + +.icon-shop_1:before { content: "\e683"; } + +.icon-news_1:before { content: "\e684"; } + +.icon-person_1:before { content: "\e685"; } + +.icon-shouhou:before { content: "\e686"; } + +.icon-jifen1:before { content: "\e688"; } + +.icon-daifukuan:before { content: "\e689"; } + +.icon-daishiyong:before { content: "\e68b"; } + +.icon-daipingjia:before { content: "\e68c"; } + diff --git a/application/wap/view/first/static/wap/bargain/font/iconfont.eot b/application/wap/view/first/static/wap/bargain/font/iconfont.eot new file mode 100644 index 00000000..dd473800 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/font/iconfont.eot differ diff --git a/application/wap/view/first/static/wap/bargain/font/iconfont.js b/application/wap/view/first/static/wap/bargain/font/iconfont.js new file mode 100644 index 00000000..9515ef8f --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/font/iconfont.js @@ -0,0 +1 @@ +(function(window){var svgSprite='';var script=function(){var scripts=document.getElementsByTagName("script");return scripts[scripts.length-1]}();var shouldInjectCss=script.getAttribute("data-injectcss");var ready=function(fn){if(document.addEventListener){if(~["complete","loaded","interactive"].indexOf(document.readyState)){setTimeout(fn,0)}else{var loadFn=function(){document.removeEventListener("DOMContentLoaded",loadFn,false);fn()};document.addEventListener("DOMContentLoaded",loadFn,false)}}else if(document.attachEvent){IEContentLoaded(window,fn)}function IEContentLoaded(w,fn){var d=w.document,done=false,init=function(){if(!done){done=true;fn()}};var polling=function(){try{d.documentElement.doScroll("left")}catch(e){setTimeout(polling,50);return}init()};polling();d.onreadystatechange=function(){if(d.readyState=="complete"){d.onreadystatechange=null;init()}}}};var before=function(el,target){target.parentNode.insertBefore(el,target)};var prepend=function(el,target){if(target.firstChild){before(el,target.firstChild)}else{target.appendChild(el)}};function appendSvg(){var div,svg;div=document.createElement("div");div.innerHTML=svgSprite;svgSprite=null;svg=div.getElementsByTagName("svg")[0];if(svg){svg.setAttribute("aria-hidden","true");svg.style.position="absolute";svg.style.width=0;svg.style.height=0;svg.style.overflow="hidden";prepend(svg,document.body)}}if(shouldInjectCss&&!window.__iconfont__svg__cssinject__){window.__iconfont__svg__cssinject__=true;try{document.write("")}catch(e){console&&console.log(e)}}ready(appendSvg)})(window) \ No newline at end of file diff --git a/application/wap/view/first/static/wap/bargain/font/iconfont.svg b/application/wap/view/first/static/wap/bargain/font/iconfont.svg new file mode 100644 index 00000000..8fcb7472 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/font/iconfont.svg @@ -0,0 +1,240 @@ + + + + + +Created by iconfont + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/application/wap/view/first/static/wap/bargain/font/iconfont.ttf b/application/wap/view/first/static/wap/bargain/font/iconfont.ttf new file mode 100644 index 00000000..6491e791 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/font/iconfont.ttf differ diff --git a/application/wap/view/first/static/wap/bargain/font/iconfont.woff b/application/wap/view/first/static/wap/bargain/font/iconfont.woff new file mode 100644 index 00000000..3e884b24 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/font/iconfont.woff differ diff --git a/application/wap/view/first/static/wap/bargain/images/count-icon.png b/application/wap/view/first/static/wap/bargain/images/count-icon.png new file mode 100644 index 00000000..56ea7077 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/count-icon.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/cut-but-icon.png b/application/wap/view/first/static/wap/bargain/images/cut-but-icon.png new file mode 100644 index 00000000..796099e3 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/cut-but-icon.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/cut-con-bg.png b/application/wap/view/first/static/wap/bargain/images/cut-con-bg.png new file mode 100644 index 00000000..97616214 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/cut-con-bg.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/cut-con-line.jpg b/application/wap/view/first/static/wap/bargain/images/cut-con-line.jpg new file mode 100644 index 00000000..278753cd Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/cut-con-line.jpg differ diff --git a/application/wap/view/first/static/wap/bargain/images/cut-con-line.png b/application/wap/view/first/static/wap/bargain/images/cut-con-line.png new file mode 100644 index 00000000..6727e222 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/cut-con-line.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/cut-con-mask.png b/application/wap/view/first/static/wap/bargain/images/cut-con-mask.png new file mode 100644 index 00000000..4d93dbfc Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/cut-con-mask.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/cut-con-title.png b/application/wap/view/first/static/wap/bargain/images/cut-con-title.png new file mode 100644 index 00000000..a338b90b Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/cut-con-title.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/cut-list-bg.jpg b/application/wap/view/first/static/wap/bargain/images/cut-list-bg.jpg new file mode 100644 index 00000000..42c26952 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/cut-list-bg.jpg differ diff --git a/application/wap/view/first/static/wap/bargain/images/member-binding-line.png b/application/wap/view/first/static/wap/bargain/images/member-binding-line.png new file mode 100644 index 00000000..32a39928 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/member-binding-line.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/member-binding-line2.png b/application/wap/view/first/static/wap/bargain/images/member-binding-line2.png new file mode 100644 index 00000000..22dcfb4e Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/member-binding-line2.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/new-page-banner.jpg b/application/wap/view/first/static/wap/bargain/images/new-page-banner.jpg new file mode 100644 index 00000000..709ccd8c Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/new-page-banner.jpg differ diff --git a/application/wap/view/first/static/wap/bargain/images/new-page-pic.jpg b/application/wap/view/first/static/wap/bargain/images/new-page-pic.jpg new file mode 100644 index 00000000..abd210e3 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/new-page-pic.jpg differ diff --git a/application/wap/view/first/static/wap/bargain/images/newtext.png b/application/wap/view/first/static/wap/bargain/images/newtext.png new file mode 100644 index 00000000..f97f290a Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/newtext.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/order-list.jpg b/application/wap/view/first/static/wap/bargain/images/order-list.jpg new file mode 100644 index 00000000..41815a0a Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/order-list.jpg differ diff --git a/application/wap/view/first/static/wap/bargain/images/order-submission.jpg b/application/wap/view/first/static/wap/bargain/images/order-submission.jpg new file mode 100644 index 00000000..04a80b5b Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/order-submission.jpg differ diff --git a/application/wap/view/first/static/wap/bargain/images/owl_happy.png b/application/wap/view/first/static/wap/bargain/images/owl_happy.png new file mode 100644 index 00000000..96f59f15 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/owl_happy.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/promotion-bg.png b/application/wap/view/first/static/wap/bargain/images/promotion-bg.png new file mode 100644 index 00000000..cf7c9fa3 Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/promotion-bg.png differ diff --git a/application/wap/view/first/static/wap/bargain/images/time-icon.png b/application/wap/view/first/static/wap/bargain/images/time-icon.png new file mode 100644 index 00000000..5d7f968c Binary files /dev/null and b/application/wap/view/first/static/wap/bargain/images/time-icon.png differ diff --git a/application/wap/view/first/static/wap/bargain/js/FJL.min.js b/application/wap/view/first/static/wap/bargain/js/FJL.min.js new file mode 100644 index 00000000..9a2bb01e --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/js/FJL.min.js @@ -0,0 +1,9 @@ +/*! + * ===================================================== + * Mui v3.3.0 (http://dev.dcloud.net.cn/mui) + * ===================================================== + */ +var mui=function(a,b){var c=/complete|loaded|interactive/,d=/^#([\w-]+)$/,e=/^\.([\w-]+)$/,f=/^[\w-]+$/,g=/translate(?:3d)?\((.+?)\)/,h=/matrix(3d)?\((.+?)\)/,i=function(b,c){if(c=c||a,!b)return j();if("object"==typeof b)return i.isArrayLike(b)?j(i.slice.call(b),null):j([b],null);if("function"==typeof b)return i.ready(b);if("string"==typeof b)try{if(b=b.trim(),d.test(b)){var e=a.getElementById(RegExp.$1);return j(e?[e]:[])}return j(i.qsa(b,c),b)}catch(f){}return j()},j=function(a,b){return a=a||[],Object.setPrototypeOf(a,i.fn),a.selector=b||"",a};i.uuid=0,i.data={},i.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},j=1,k=arguments.length,l=!1;for("boolean"==typeof h&&(l=h,h=arguments[j]||{},j++),"object"==typeof h||i.isFunction(h)||(h={}),j===k&&(h=this,j--);k>j;j++)if(null!=(a=arguments[j]))for(c in a)d=h[c],e=a[c],h!==e&&(l&&e&&(i.isPlainObject(e)||(f=i.isArray(e)))?(f?(f=!1,g=d&&i.isArray(d)?d:[]):g=d&&i.isPlainObject(d)?d:{},h[c]=i.extend(l,g,e)):e!==b&&(h[c]=e));return h},i.noop=function(){},i.slice=[].slice,i.filter=[].filter,i.type=function(a){return null==a?String(a):k[{}.toString.call(a)]||"object"},i.isArray=Array.isArray||function(a){return a instanceof Array},i.isArrayLike=function(a){var b=!!a&&"length"in a&&a.length,c=i.type(a);return"function"===c||i.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a},i.isWindow=function(a){return null!=a&&a===a.window},i.isObject=function(a){return"object"===i.type(a)},i.isPlainObject=function(a){return i.isObject(a)&&!i.isWindow(a)&&Object.getPrototypeOf(a)===Object.prototype},i.isEmptyObject=function(a){for(var c in a)if(c!==b)return!1;return!0},i.isFunction=function(a){return"function"===i.type(a)},i.qsa=function(b,c){return c=c||a,i.slice.call(e.test(b)?c.getElementsByClassName(RegExp.$1):f.test(b)?c.getElementsByTagName(b):c.querySelectorAll(b))},i.ready=function(b){return c.test(a.readyState)?b(i):a.addEventListener("DOMContentLoaded",function(){b(i)},!1),this},i.buffer=function(a,b,c){function d(){e&&(e.cancel(),e=0),f=i.now(),a.apply(c||this,arguments),g=i.now()}var e,f=0,g=0,b=b||150;return i.extend(function(){!f||g>=f&&i.now()-g>b||f>g&&i.now()-f>8*b?d():(e&&e.cancel(),e=i.later(d,b,null,arguments))},{stop:function(){e&&(e.cancel(),e=0)}})},i.each=function(a,b,c){if(!a)return this;if("number"==typeof a.length)[].every.call(a,function(a,c){return b.call(a,c,a)!==!1});else for(var d in a)if(c){if(a.hasOwnProperty(d)&&b.call(a[d],d,a[d])===!1)return a}else if(b.call(a[d],d,a[d])===!1)return a;return this},i.focus=function(a){i.os.ios?setTimeout(function(){a.focus()},10):a.focus()},i.trigger=function(a,b,c){return a.dispatchEvent(new CustomEvent(b,{detail:c,bubbles:!0,cancelable:!0})),this},i.getStyles=function(a,b){var c=a.ownerDocument.defaultView.getComputedStyle(a,null);return b?c.getPropertyValue(b)||c[b]:c},i.parseTranslate=function(a,b){var c=a.match(g||"");return c&&c[1]||(c=["","0,0,0"]),c=c[1].split(","),c={x:parseFloat(c[0]),y:parseFloat(c[1]),z:parseFloat(c[2])},b&&c.hasOwnProperty(b)?c[b]:c},i.parseTranslateMatrix=function(a,b){var c=a.match(h),d=c&&c[1];c?(c=c[2].split(","),"3d"===d?c=c.slice(12,15):(c.push(0),c=c.slice(4,7))):c=[0,0,0];var e={x:parseFloat(c[0]),y:parseFloat(c[1]),z:parseFloat(c[2])};return b&&e.hasOwnProperty(b)?e[b]:e},i.hooks={},i.addAction=function(a,b){var c=i.hooks[a];return c||(c=[]),b.index=b.index||1e3,c.push(b),c.sort(function(a,b){return a.index-b.index}),i.hooks[a]=c,i.hooks[a]},i.doAction=function(a,b){i.isFunction(b)?i.each(i.hooks[a],b):i.each(i.hooks[a],function(a,b){return!b.handle()})},i.later=function(a,b,c,d){b=b||0;var e,f,g=a,h=d;return"string"==typeof a&&(g=c[a]),e=function(){g.apply(c,i.isArray(h)?h:[h])},f=setTimeout(e,b),{id:f,cancel:function(){clearTimeout(f)}}},i.now=Date.now||function(){return+new Date};var k={};return i.each(["Boolean","Number","String","Function","Array","Date","RegExp","Object","Error"],function(a,b){k["[object "+b+"]"]=b.toLowerCase()}),window.JSON&&(i.parseJSON=JSON.parse),i.fn={each:function(a){return[].every.call(this,function(b,c){return a.call(b,c,b)!==!1}),this}},"function"==typeof define&&define.amd&&define("mui",[],function(){return i}),i}(document);!function(a,b){function c(c){this.os={};var d=[function(){var a=c.match(/(MicroMessenger)\/([\d\.]+)/i);return a&&(this.os.wechat={version:a[2].replace(/_/g,".")}),!1},function(){var a=c.match(/(Android);?[\s\/]+([\d.]+)?/);return a&&(this.os.android=!0,this.os.version=a[2],this.os.isBadAndroid=!/Chrome\/\d/.test(b.navigator.appVersion)),this.os.android===!0},function(){var a=c.match(/(iPhone\sOS)\s([\d_]+)/);if(a)this.os.ios=this.os.iphone=!0,this.os.version=a[2].replace(/_/g,".");else{var b=c.match(/(iPad).*OS\s([\d_]+)/);b&&(this.os.ios=this.os.ipad=!0,this.os.version=b[2].replace(/_/g,"."))}return this.os.ios===!0}];[].every.call(d,function(b){return!b.call(a)})}c.call(a,navigator.userAgent)}(mui,window),function(a,b){function c(c){this.os=this.os||{};var d=c.match(/Html5Plus/i);d&&(this.os.plus=!0,a(function(){b.body.classList.add("mui-plus")}),c.match(/StreamApp/i)&&(this.os.stream=!0,a(function(){b.body.classList.add("mui-plus-stream")})))}c.call(a,navigator.userAgent)}(mui,document),function(a){"ontouchstart"in window?(a.isTouchable=!0,a.EVENT_START="touchstart",a.EVENT_MOVE="touchmove",a.EVENT_END="touchend"):(a.isTouchable=!1,a.EVENT_START="mousedown",a.EVENT_MOVE="mousemove",a.EVENT_END="mouseup"),a.EVENT_CANCEL="touchcancel",a.EVENT_CLICK="click";var b=1,c={},d={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"},e=function(){return!0},f=function(){return!1},g=function(b,c){return b.detail?b.detail.currentTarget=c:b.detail={currentTarget:c},a.each(d,function(a,c){var d=b[a];b[a]=function(){return this[c]=e,d&&d.apply(b,arguments)},b[c]=f},!0),b},h=function(a){return a&&(a._mid||(a._mid=b++))},i={},j=function(b,d,e,f){return function(e){for(var f=c[b._mid][d],h=[],i=e.target,j={};i&&i!==document&&i!==b&&(!~["click","tap","doubletap","longtap","hold"].indexOf(d)||!i.disabled&&!i.classList.contains("mui-disabled"));i=i.parentNode){var k={};a.each(f,function(c,d){j[c]||(j[c]=a.qsa(c,b)),j[c]&&~j[c].indexOf(i)&&(k[c]||(k[c]=d))},!0),a.isEmptyObject(k)||h.push({element:i,handlers:k})}j=null,e=g(e),a.each(h,function(b,c){i=c.element;var f=i.tagName;return"tap"===d&&"INPUT"!==f&&"TEXTAREA"!==f&&"SELECT"!==f&&(e.preventDefault(),e.detail&&e.detail.gesture&&e.detail.gesture.preventDefault()),a.each(c.handlers,function(b,c){a.each(c,function(a,b){b.call(i,e)===!1&&(e.preventDefault(),e.stopPropagation())},!0)},!0),e.isPropagationStopped()?!1:void 0},!0)}},k=function(a,b){var c=i[h(a)],d=[];if(c){if(d=[],b){var e=function(a){return a.type===b};return c.filter(e)}d=c}return d},l=/^(INPUT|TEXTAREA|BUTTON|SELECT)$/;a.fn.on=function(b,d,e){return this.each(function(){var f=this;h(f),h(e);var g=!1,k=c[f._mid]||(c[f._mid]={}),m=k[b]||(k[b]={});a.isEmptyObject(m)&&(g=!0);var n=m[d]||(m[d]=[]);if(n.push(e),g){var o=i[h(f)];o||(o=[]);var p=j(f,b,d,e);o.push(p),p.i=o.length-1,p.type=b,i[h(f)]=o,f.addEventListener(b,p),"tap"===b&&f.addEventListener("click",function(a){if(a.target){var b=a.target.tagName;if(!l.test(b))if("A"===b){var c=a.target.href;c&&~c.indexOf("tel:")||a.preventDefault()}else a.preventDefault()}})}})},a.fn.off=function(b,d,e){return this.each(function(){var f=h(this);if(b)if(d)if(e){var g=c[f]&&c[f][b]&&c[f][b][d];a.each(g,function(a,b){return h(b)===h(e)?(g.splice(a,1),!1):void 0},!0)}else c[f]&&c[f][b]&&delete c[f][b][d];else c[f]&&delete c[f][b];else c[f]&&delete c[f];c[f]?(!c[f][b]||a.isEmptyObject(c[f][b]))&&k(this,b).forEach(function(a){this.removeEventListener(a.type,a),delete i[f][a.i]}.bind(this)):k(this).forEach(function(a){this.removeEventListener(a.type,a),delete i[f][a.i]}.bind(this))})}}(mui),function(a,b,c){a.targets={},a.targetHandles=[],a.registerTarget=function(b){return b.index=b.index||1e3,a.targetHandles.push(b),a.targetHandles.sort(function(a,b){return a.index-b.index}),a.targetHandles},b.addEventListener(a.EVENT_START,function(b){for(var d=b.target,e={};d&&d!==c;d=d.parentNode){var f=!1;if(a.each(a.targetHandles,function(c,g){var h=g.name;f||e[h]||!g.hasOwnProperty("handle")?e[h]||g.isReset!==!1&&(a.targets[h]=!1):(a.targets[h]=g.handle(b,d),a.targets[h]&&(e[h]=!0,g.isContinue!==!0&&(f=!0)))}),f)break}}),b.addEventListener("click",function(b){for(var d=b.target,e=!1;d&&d!==c&&("A"!==d.tagName||(a.each(a.targetHandles,function(a,c){c.name;return c.hasOwnProperty("handle")&&c.handle(b,d)?(e=!0,b.preventDefault(),!1):void 0}),!e));d=d.parentNode);})}(mui,window,document),function(a){String.prototype.trim===a&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Object.setPrototypeOf=Object.setPrototypeOf||function(a,b){return a.__proto__=b,a}}(),function(){function a(a,b){b=b||{bubbles:!1,cancelable:!1,detail:void 0};var c=document.createEvent("Events"),d=!0;for(var e in b)"bubbles"===e?d=!!b[e]:c[e]=b[e];return c.initEvent(a,d,!0),c}"undefined"==typeof window.CustomEvent&&(a.prototype=window.Event.prototype,window.CustomEvent=a)}(),Function.prototype.bind=Function.prototype.bind||function(a){var b=Array.prototype.splice.call(arguments,1),c=this,d=function(){var e=b.concat(Array.prototype.splice.call(arguments,0));return this instanceof d?void c.apply(this,e):c.apply(a,e)};return d.prototype=c.prototype,d},function(a){"classList"in a.documentElement||!Object.defineProperty||"undefined"==typeof HTMLElement||Object.defineProperty(HTMLElement.prototype,"classList",{get:function(){function a(a){return function(c){var d=b.className.split(/\s+/),e=d.indexOf(c);a(d,e,c),b.className=d.join(" ")}}var b=this,c={add:a(function(a,b,c){~b||a.push(c)}),remove:a(function(a,b){~b&&a.splice(b,1)}),toggle:a(function(a,b,c){~b?a.splice(b,1):a.push(c)}),contains:function(a){return!!~b.className.split(/\s+/).indexOf(a)},item:function(a){return b.className.split(/\s+/)[a]||null}};return Object.defineProperty(c,"length",{get:function(){return b.className.split(/\s+/).length}}),c}})}(document),function(a){if(!a.requestAnimationFrame){var b=0;a.requestAnimationFrame=a.webkitRequestAnimationFrame||function(c,d){var e=(new Date).getTime(),f=Math.max(0,16.7-(e-b)),g=a.setTimeout(function(){c(e+f)},f);return b=e+f,g},a.cancelAnimationFrame=a.webkitCancelAnimationFrame||a.webkitCancelRequestAnimationFrame||function(a){clearTimeout(a)}}}(window),function(a,b,c){if((a.os.android||a.os.ios)&&!b.FastClick){var d=function(a,b){return"LABEL"===b.tagName&&b.parentNode&&(b=b.parentNode.querySelector("input")),!b||"radio"!==b.type&&"checkbox"!==b.type||b.disabled?!1:b};a.registerTarget({name:c,index:40,handle:d,target:!1});var e=function(c){var d=a.targets.click;if(d){var e,f;document.activeElement&&document.activeElement!==d&&document.activeElement.blur(),f=c.detail.gesture.changedTouches[0],e=document.createEvent("MouseEvents"),e.initMouseEvent("click",!0,!0,b,1,f.screenX,f.screenY,f.clientX,f.clientY,!1,!1,!1,!1,0,null),e.forwardedTouchEvent=!0,d.dispatchEvent(e),c.detail&&c.detail.gesture.preventDefault()}};b.addEventListener("tap",e),b.addEventListener("doubletap",e),b.addEventListener("click",function(b){return a.targets.click&&!b.forwardedTouchEvent?(b.stopImmediatePropagation?b.stopImmediatePropagation():b.propagationStopped=!0,b.stopPropagation(),b.preventDefault(),!1):void 0},!0)}}(mui,window,"click"),function(a,b){a(function(){if(a.os.ios){var c="mui-focusin",d="mui-bar-tab",e="mui-bar-footer",f="mui-bar-footer-secondary",g="mui-bar-footer-secondary-tab";b.addEventListener("focusin",function(h){if(!(a.os.plus&&window.plus&&plus.webview.currentWebview().children().length>0)){var i=h.target;if(i.tagName&&("TEXTAREA"===i.tagName||"INPUT"===i.tagName&&("text"===i.type||"search"===i.type||"number"===i.type))){if(i.disabled||i.readOnly)return;b.body.classList.add(c);for(var j=!1;i&&i!==b;i=i.parentNode){var k=i.classList;if(k&&k.contains(d)||k.contains(e)||k.contains(f)||k.contains(g)){j=!0;break}}if(j){var l=b.body.scrollHeight,m=b.body.scrollLeft;setTimeout(function(){window.scrollTo(m,l)},20)}}}}),b.addEventListener("focusout",function(a){var d=b.body.classList;d.contains(c)&&(d.remove(c),setTimeout(function(){window.scrollTo(b.body.scrollLeft,b.body.scrollTop)},20))})}})}(mui,document),function(a){a.namespace="mui",a.classNamePrefix=a.namespace+"-",a.classSelectorPrefix="."+a.classNamePrefix,a.className=function(b){return a.classNamePrefix+b},a.classSelector=function(b){return b.replace(/\./g,a.classSelectorPrefix)},a.eventName=function(b,c){return b+(a.namespace?"."+a.namespace:"")+(c?"."+c:"")}}(mui),function(a,b){a.gestures={session:{}},a.preventDefault=function(a){a.preventDefault()},a.stopPropagation=function(a){a.stopPropagation()},a.addGesture=function(b){return a.addAction("gestures",b)};var c=Math.round,d=Math.abs,e=Math.sqrt,f=(Math.atan,Math.atan2),g=function(a,b,c){c||(c=["x","y"]);var d=b[c[0]]-a[c[0]],f=b[c[1]]-a[c[1]];return e(d*d+f*f)},h=function(a,b){if(a.length>=2&&b.length>=2){var c=["pageX","pageY"];return g(b[1],b[0],c)/g(a[1],a[0],c)}return 1},i=function(a,b,c){c||(c=["x","y"]);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*f(e,d)/Math.PI},j=function(a,b){return a===b?"":d(a)>=d(b)?a>0?"left":"right":b>0?"up":"down"},k=function(a,b){var c=["pageX","pageY"];return i(b[1],b[0],c)-i(a[1],a[0],c)},l=function(a,b,c){return{x:b/a||0,y:c/a||0}},m=function(b,c){a.gestures.stoped||a.doAction("gestures",function(d,e){a.gestures.stoped||a.options.gestureConfig[e.name]!==!1&&e.handle(b,c)})},n=function(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1},o=function(a,b,c){for(var d=[],e=[],f=0;fc[b]}):d.sort()),d},p=function(a){var b=a.length;if(1===b)return{x:c(a[0].pageX),y:c(a[0].pageY)};for(var d=0,e=0,f=0;b>f;)d+=a[f].pageX,e+=a[f].pageY,f++;return{x:c(d/b),y:c(e/b)}},q=function(){return a.options.gestureConfig.pinch},r=function(b){for(var d=[],e=0;e1&&!c.firstMultiTouch?c.firstMultiTouch=r(b):1===e&&(c.firstMultiTouch=!1);var f=c.firstTouch,l=c.firstMultiTouch,m=l?l.center:f.center,n=b.center=p(d);b.timestamp=a.now(),b.deltaTime=b.timestamp-f.timestamp,b.angle=i(m,n),b.distance=g(m,n),s(b),b.offsetDirection=j(b.deltaX,b.deltaY),b.scale=l?h(l.touches,d):1,b.rotation=l?k(l.touches,d):0,v(b)},u=25,v=function(b){var c,e,f,g,h=a.gestures.session,i=h.lastInterval||b,k=b.timestamp-i.timestamp;if(b.gesture.type!=a.EVENT_CANCEL&&(k>u||void 0===i.velocity)){var m=i.deltaX-b.deltaX,n=i.deltaY-b.deltaY,o=l(k,m,n);e=o.x,f=o.y,c=d(o.x)>d(o.y)?o.x:o.y,g=j(m,n)||i.direction,h.lastInterval=b}else c=i.velocity,e=i.velocityX,f=i.velocityY,g=i.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g},w={},x=function(a){for(var b=0;b300&&(c=h,f.flickStart=e.center);break;case a.EVENT_END:case a.EVENT_CANCEL:e.flick=!1,f.flickStart&&g.flickMaxTime>h-c&&e.distance>g.flickMinDistince&&(e.flick=!0,e.flickTime=h-c,e.flickDistanceX=e.center.x-f.flickStart.x,e.flickDistanceY=e.center.y-f.flickStart.y,a.trigger(f.target,b,e),a.trigger(f.target,b+e.direction,e))}};a.addGesture({name:b,index:5,handle:d,options:{flickMaxTime:200,flickMinDistince:10}})}(mui,"flick"),function(a,b){var c=function(c,d){var e=a.gestures.session;if(c.type===a.EVENT_END||c.type===a.EVENT_CANCEL){var f=this.options;d.swipe=!1,d.direction&&f.swipeMaxTime>d.deltaTime&&d.distance>f.swipeMinDistince&&(d.swipe=!0,a.trigger(e.target,b,d),a.trigger(e.target,b+d.direction,d))}};a.addGesture({name:b,index:10,handle:c,options:{swipeMaxTime:300,swipeMinDistince:18}})}(mui,"swipe"),function(a,b){var c=function(c,d){var e=a.gestures.session;switch(c.type){case a.EVENT_START:break;case a.EVENT_MOVE:if(!d.direction||!e.target)return;e.lockDirection&&e.startDirection&&e.startDirection&&e.startDirection!==d.direction&&("up"===e.startDirection||"down"===e.startDirection?d.direction=d.deltaY<0?"up":"down":d.direction=d.deltaX<0?"left":"right"),e.drag||(e.drag=!0,a.trigger(e.target,b+"start",d)),a.trigger(e.target,b,d),a.trigger(e.target,b+d.direction,d);break;case a.EVENT_END:case a.EVENT_CANCEL:e.drag&&d.isFinal&&a.trigger(e.target,b+"end",d)}};a.addGesture({name:b,index:20,handle:c,options:{fingers:1}})}(mui,"drag"),function(a,b){var c,d,e=function(e,f){var g=a.gestures.session,h=this.options;switch(e.type){case a.EVENT_END:if(!f.isFinal)return;var i=g.target;if(!i||i.disabled||i.classList&&i.classList.contains("mui-disabled"))return;if(f.distanceg.holdThreshold&&clearTimeout(c);break;case a.EVENT_END:case a.EVENT_CANCEL:clearTimeout(c)}};a.addGesture({name:b,index:10,handle:d,options:{fingers:1,holdTimeout:500,holdThreshold:2}})}(mui,"longtap"),function(a,b){var c,d=function(d,e){var f=a.gestures.session,g=this.options;switch(d.type){case a.EVENT_START:a.options.gestureConfig.hold&&(c&&clearTimeout(c),c=setTimeout(function(){e.hold=!0,a.trigger(f.target,b,e)},g.holdTimeout));break;case a.EVENT_MOVE:break;case a.EVENT_END:case a.EVENT_CANCEL:c&&(clearTimeout(c)&&(c=null),a.trigger(f.target,"release",e))}};a.addGesture({name:b,index:10,handle:d,options:{fingers:1,holdTimeout:0}})}(mui,"hold"),function(a,b){var c=function(c,d){var e=this.options,f=a.gestures.session;switch(c.type){case a.EVENT_START:break;case a.EVENT_MOVE:if(a.options.gestureConfig.pinch){if(d.touches.length<2)return;f.pinch||(f.pinch=!0,a.trigger(f.target,b+"start",d)),a.trigger(f.target,b,d);var g=d.scale,h=d.rotation,i="undefined"==typeof d.lastScale?1:d.lastScale,j=1e-12;g>i?(i=g-j,a.trigger(f.target,b+"out",d)):i>g&&(i=g+j,a.trigger(f.target,b+"in",d)),Math.abs(h)>e.minRotationAngle&&a.trigger(f.target,"rotate",d)}break;case a.EVENT_END:case a.EVENT_CANCEL:a.options.gestureConfig.pinch&&f.pinch&&2===d.touches.length&&(f.pinch=!1,a.trigger(f.target,b+"end",d))}};a.addGesture({name:b,index:10,handle:c,options:{minRotationAngle:0}})}(mui,"pinch"),function(a){function b(a,b){var c="MUI_SCROLL_POSITION_"+document.location.href+"_"+b.src,d=parseFloat(localStorage.getItem(c))||0;d&&!function(a){b.onload=function(){window.scrollTo(0,a)}}(d),setInterval(function(){var a=window.scrollY;d!==a&&(localStorage.setItem(c,a+""),d=a)},100)}a.global=a.options={gestureConfig:{tap:!0,doubletap:!1,longtap:!1,hold:!1,flick:!0,swipe:!0,drag:!0,pinch:!1}},a.initGlobal=function(b){return a.options=a.extend(!0,a.global,b),this};var c={},d=!1;a.init=function(b){return d=!0,a.options=a.extend(!0,a.global,b||{}),a.ready(function(){a.doAction("inits",function(b,d){var e=!(c[d.name]&&!d.repeat);e&&(d.handle.call(a),c[d.name]=!0)})}),this},a.addInit=function(b){return a.addAction("inits",b)},a.addInit({name:"iframe",index:100,handle:function(){var b=a.options,c=b.subpages||[];!a.os.plus&&c.length&&e(c[0])}});var e=function(c){var d=document.createElement("div");d.className="mui-iframe-wrapper";var e=c.styles||{};"string"!=typeof e.top&&(e.top="0px"),"string"!=typeof e.bottom&&(e.bottom="0px"),d.style.top=e.top,d.style.bottom=e.bottom;var f=document.createElement("iframe");f.src=c.url,f.id=c.id||c.url,f.name=f.id,d.appendChild(f),document.body.appendChild(d),a.os.wechat&&b(d,f)};a(function(){var b=document.body.classList,c=[];a.os.ios?(c.push({os:"ios",version:a.os.version}),b.add("mui-ios")):a.os.android&&(c.push({os:"android",version:a.os.version}),b.add("mui-android")),a.os.wechat&&(c.push({os:"wechat",version:a.os.wechat.version}),b.add("mui-wechat")),c.length&&a.each(c,function(c,d){var e="";d.version&&a.each(d.version.split("."),function(c,f){e=e+(e?"-":"")+f,b.add(a.className(d.os+"-"+e))})})})}(mui),function(a){var b={swipeBack:!1,preloadPages:[],preloadLimit:10,keyEventBind:{backbutton:!0,menubutton:!0}},c={autoShow:!0,duration:a.os.ios?200:100,aniShow:"slide-in-right"};a.options.show&&(c=a.extend(!0,c,a.options.show)),a.currentWebview=null,a.isHomePage=!1,a.extend(!0,a.global,b),a.extend(!0,a.options,b),a.waitingOptions=function(b){return a.extend(!0,{},{autoShow:!0,title:"",modal:!1},b)},a.showOptions=function(b){return a.extend(!0,{},c,b)},a.windowOptions=function(b){return a.extend({scalable:!1,bounce:""},b)},a.plusReady=function(a){return window.plus?setTimeout(function(){a()},0):document.addEventListener("plusready",function(){a()},!1),this},a.fire=function(b,c,d){b&&(""!==d&&(d=d||{},a.isPlainObject(d)&&(d=JSON.stringify(d||{}).replace(/\'/g,"\\u0027").replace(/\\/g,"\\u005c"))),b.evalJS("typeof mui!=='undefined'&&mui.receive('"+c+"','"+d+"')"))},a.receive=function(b,c){if(b){try{c&&(c=JSON.parse(c))}catch(d){}a.trigger(document,b,c)}};var d=function(b){if(!b.preloaded){a.fire(b,"preload");for(var c=b.children(),d=0;da.options.preloadLimit){var h=a.data.preloads.shift(),i=a.webviews[h];i&&i.webview&&a.closeAll(i.webview),delete a.webviews[h]}}else c!==!1&&(d=plus.webview.create(b.url,e,a.windowOptions(b.styles),b.extras),b.subpages&&a.each(b.subpages,function(b,c){var e=c.id||c.url,f=plus.webview.getWebviewById(e);f||(f=plus.webview.create(c.url,e,a.windowOptions(c.styles),c.extras)),d.append(f)}));return d}},a.preload=function(b){return b.preload||(b.preload=!0),a.createWindow(b)},a.closeOpened=function(b){var c=b.opened();if(c)for(var d=0,e=c.length;e>d;d++){var f=c[d],g=f.opened();g&&g.length>0?(a.closeOpened(f),f.close("none")):f.parent()!==b&&f.close("none")}},a.closeAll=function(b,c){a.closeOpened(b),c?b.close(c):b.close()},a.createWindows=function(b){a.each(b,function(b,c){a.createWindow(c,!1)})},a.appendWebview=function(b){if(window.plus){var c,d=b.id||b.url;return a.webviews[d]||(plus.webview.getWebviewById(d)||(c=plus.webview.create(b.url,d,b.styles,b.extras)),plus.webview.currentWebview().append(c),a.webviews[d]=b),c}},a.webviews={},a.data.preloads=[],a.plusReady(function(){a.currentWebview=plus.webview.currentWebview()}),a.addInit({name:"5+",index:100,handle:function(){var b=a.options,c=b.subpages||[];a.os.plus&&a.plusReady(function(){a.each(c,function(b,c){a.appendWebview(c)}),plus.webview.currentWebview()===plus.webview.getWebviewById(plus.runtime.appid)&&(a.isHomePage=!0,setTimeout(function(){d(plus.webview.currentWebview())},300)),a.os.ios&&a.options.statusBarBackground&&plus.navigator.setStatusBarBackground(a.options.statusBarBackground),a.os.android&&parseFloat(a.os.version)<4.4&&null==plus.webview.currentWebview().parent()&&document.addEventListener("resume",function(){var a=document.body;a.style.display="none",setTimeout(function(){a.style.display=""},10)})})}}),window.addEventListener("preload",function(){var b=a.options.preloadPages||[];a.plusReady(function(){a.each(b,function(b,c){a.createWindow(a.extend(c,{preload:!0}))})})}),a.supportStatusbarOffset=function(){return a.os.plus&&a.os.ios&&parseFloat(a.os.version)>=7},a.ready(function(){a.supportStatusbarOffset()&&document.body.classList.add("mui-statusbar")})}(mui),function(a,b){a.addBack=function(b){return a.addAction("backs",b)},a.addBack({name:"browser",index:100,handle:function(){return b.history.length>1?(b.history.back(),!0):!1}}),a.back=function(){("function"!=typeof a.options.beforeback||a.options.beforeback()!==!1)&&a.doAction("backs")},b.addEventListener("tap",function(b){var c=a.targets.action;c&&c.classList.contains("mui-action-back")&&(a.back(),a.targets.action=!1)}),b.addEventListener("swiperight",function(b){var c=b.detail;a.options.swipeBack===!0&&Math.abs(c.angle)<3&&a.back()})}(mui,window),function(a,b){a.os.plus&&a.os.android&&a.addBack({name:"mui",index:5,handle:function(){if(a.targets._popover&&a.targets._popover.classList.contains("mui-active"))return a(a.targets._popover).popover("hide"),!0;var b=document.querySelector(".mui-off-canvas-wrap.mui-active");if(b)return a(b).offCanvas("close"),!0;var c=a.isFunction(a.getPreviewImage)&&a.getPreviewImage();return c&&c.isShown()?(c.close(),!0):a.closePopup()}}),a.__back__first=null,a.addBack({name:"5+",index:10,handle:function(){if(!b.plus)return!1;var c=plus.webview.currentWebview(),d=c.parent();return d?d.evalJS("mui&&mui.back();"):c.canBack(function(d){d.canBack?b.history.back():c.id===plus.runtime.appid?a.__back__first?(new Date).getTime()-a.__back__first<2e3&&plus.runtime.quit():(a.__back__first=(new Date).getTime(),mui.toast("再按一次退出应用"),setTimeout(function(){a.__back__first=null},2e3)):c.preload?c.hide("auto"):a.closeAll(c)}),!0}}),a.menu=function(){var c=document.querySelector(".mui-action-menu");if(c)a.trigger(c,a.EVENT_START),a.trigger(c,"tap");else if(b.plus){var d=a.currentWebview,e=d.parent();e&&e.evalJS("mui&&mui.menu();")}};var c=function(){a.back()},d=function(){a.menu()};a.plusReady(function(){a.options.keyEventBind.backbutton&&plus.key.addEventListener("backbutton",c,!1),a.options.keyEventBind.menubutton&&plus.key.addEventListener("menubutton",d,!1)}),a.addInit({name:"keyEventBind",index:1e3,handle:function(){a.plusReady(function(){a.options.keyEventBind.backbutton||plus.key.removeEventListener("backbutton",c),a.options.keyEventBind.menubutton||plus.key.removeEventListener("menubutton",d)})}})}(mui,window),function(a){a.addInit({name:"pullrefresh",index:1e3,handle:function(){var b=a.options,c=b.pullRefresh||{},d=c.down&&c.down.hasOwnProperty("callback"),e=c.up&&c.up.hasOwnProperty("callback");if(d||e){var f=c.container;if(f){var g=a(f);1===g.length&&(a.os.plus&&a.os.android?a.plusReady(function(){var b=plus.webview.currentWebview();if(e){var f={};f.up=c.up,f.webviewId=b.id||b.getURL(),g.pullRefresh(f)}if(d){var h=b.parent(),i=b.id||b.getURL();if(h){e||g.pullRefresh({webviewId:i});var j={webviewId:i};j.down=a.extend({},c.down),j.down.callback="_CALLBACK",h.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('"+JSON.stringify(j)+"')")}}}):g.pullRefresh(c))}}}})}(mui),function(a,b,c){var d="application/json",e="text/html",f=/)<[^<]*)*<\/script>/gi,g=/^(?:text|application)\/javascript/i,h=/^(?:text|application)\/xml/i,i=/^\s*$/;a.ajaxSettings={type:"GET",beforeSend:a.noop,success:a.noop,error:a.noop,complete:a.noop,context:null,xhr:function(a){return new b.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:d,xml:"application/xml, text/xml",html:e,text:"text/plain"},timeout:0,processData:!0,cache:!0};var j=function(a,b){var c=b.context;return b.beforeSend.call(c,a,b)===!1?!1:void 0},k=function(a,b,c){c.success.call(c.context,a,"success",b),m("success",b,c)},l=function(a,b,c,d){d.error.call(d.context,c,b,a),m(b,c,d)},m=function(a,b,c){c.complete.call(c.context,b,a)},n=function(b,c,d,e){var f,g=a.isArray(c),h=a.isPlainObject(c);a.each(c,function(c,i){f=a.type(i),e&&(c=d?e:e+"["+(h||"object"===f||"array"===f?c:"")+"]"),!e&&g?b.add(i.name,i.value):"array"===f||!d&&"object"===f?n(b,i,d,c):b.add(c,i)})},o=function(b){if(b.processData&&b.data&&"string"!=typeof b.data){var e=b.contentType;!e&&b.headers&&(e=b.headers["Content-Type"]),e&&~e.indexOf(d)?b.data=JSON.stringify(b.data):b.data=a.param(b.data,b.traditional)}!b.data||b.type&&"GET"!==b.type.toUpperCase()||(b.url=p(b.url,b.data), +b.data=c)},p=function(a,b){return""===b?a:(a+"&"+b).replace(/[&?]{1,2}/,"?")},q=function(a){return a&&(a=a.split(";",2)[0]),a&&(a===e?"html":a===d?"json":g.test(a)?"script":h.test(a)&&"xml")||"text"},r=function(b,d,e,f){return a.isFunction(d)&&(f=e,e=d,d=c),a.isFunction(e)||(f=e,e=c),{url:b,data:d,success:e,dataType:f}};a.ajax=function(d,e){"object"==typeof d&&(e=d,d=c);var f=e||{};f.url=d||f.url;for(var g in a.ajaxSettings)f[g]===c&&(f[g]=a.ajaxSettings[g]);o(f);var h=f.dataType;f.cache!==!1&&(e&&e.cache===!0||"script"!==h)||(f.url=p(f.url,"_="+a.now()));var m,n=f.accepts[h&&h.toLowerCase()],r={},s=function(a,b){r[a.toLowerCase()]=[a,b]},t=/^([\w-]+:)\/\//.test(f.url)?RegExp.$1:b.location.protocol,u=f.xhr(f),v=u.setRequestHeader;if(s("X-Requested-With","XMLHttpRequest"),s("Accept",n||"*/*"),(n=f.mimeType||n)&&(n.indexOf(",")>-1&&(n=n.split(",",2)[0]),u.overrideMimeType&&u.overrideMimeType(n)),(f.contentType||f.contentType!==!1&&f.data&&"GET"!==f.type.toUpperCase())&&s("Content-Type",f.contentType||"application/x-www-form-urlencoded"),f.headers)for(var w in f.headers)s(w,f.headers[w]);if(u.setRequestHeader=s,u.onreadystatechange=function(){if(4===u.readyState){u.onreadystatechange=a.noop,clearTimeout(m);var b,c=!1,d="file:"===t;if(u.status>=200&&u.status<300||304===u.status||0===u.status&&d&&u.responseText){h=h||q(f.mimeType||u.getResponseHeader("content-type")),b=u.responseText;try{"script"===h?(1,eval)(b):"xml"===h?b=u.responseXML:"json"===h&&(b=i.test(b)?null:a.parseJSON(b))}catch(e){c=e}c?l(c,"parsererror",u,f):k(b,u,f)}else{var g=u.status?"error":"abort",j=u.statusText||null;d&&(g="error",j="404"),l(j,g,u,f)}}},j(u,f)===!1)return u.abort(),l(null,"abort",u,f),u;if(f.xhrFields)for(var w in f.xhrFields)u[w]=f.xhrFields[w];var x="async"in f?f.async:!0;u.open(f.type.toUpperCase(),f.url,x,f.username,f.password);for(var w in r)r.hasOwnProperty(w)&&v.apply(u,r[w]);return f.timeout>0&&(m=setTimeout(function(){u.onreadystatechange=a.noop,u.abort(),l(null,"timeout",u,f)},f.timeout)),u.send(f.data?f.data:null),u},a.param=function(a,b){var c=[];return c.add=function(a,b){this.push(encodeURIComponent(a)+"="+encodeURIComponent(b))},n(c,a,b),c.join("&").replace(/%20/g,"+")},a.get=function(){return a.ajax(r.apply(null,arguments))},a.post=function(){var b=r.apply(null,arguments);return b.type="POST",a.ajax(b)},a.getJSON=function(){var b=r.apply(null,arguments);return b.dataType="json",a.ajax(b)},a.fn.load=function(b,c,d){if(!this.length)return this;var e,g=this,h=b.split(/\s/),i=r(b,c,d),j=i.success;return h.length>1&&(i.url=h[0],e=h[1]),i.success=function(a){if(e){var b=document.createElement("div");b.innerHTML=a.replace(f,"");var c=document.createElement("div"),d=b.querySelectorAll(e);if(d&&d.length>0)for(var h=0,i=d.length;i>h;h++)c.appendChild(d[h]);g[0].innerHTML=c.innerHTML}else g[0].innerHTML=a;j&&j.apply(g,arguments)},a.ajax(i),this}}(mui,window),function(a){var b=document.createElement("a");b.href=window.location.href,a.plusReady(function(){a.ajaxSettings=a.extend(a.ajaxSettings,{xhr:function(a){if(a.crossDomain)return new plus.net.XMLHttpRequest;if("file:"!==b.protocol){var c=document.createElement("a");if(c.href=a.url,c.href=c.href,a.crossDomain=b.protocol+"//"+b.host!=c.protocol+"//"+c.host,a.crossDomain)return new plus.net.XMLHttpRequest}return new window.XMLHttpRequest}})})}(mui),function(a,b,c){a.offset=function(a){var d={top:0,left:0};return typeof a.getBoundingClientRect!==c&&(d=a.getBoundingClientRect()),{top:d.top+b.pageYOffset-a.clientTop,left:d.left+b.pageXOffset-a.clientLeft}}}(mui,window),function(a,b){a.scrollTo=function(a,c,d){c=c||1e3;var e=function(c){if(0>=c)return b.scrollTo(0,a),void(d&&d());var f=a-b.scrollY;setTimeout(function(){b.scrollTo(0,b.scrollY+f/c*10),e(c-10)},16.7)};e(c)},a.animationFrame=function(a){var b,c,d;return function(){b=arguments,d=this,c||(c=!0,requestAnimationFrame(function(){a.apply(d,b),c=!1}))}}}(mui,window),function(a){var b=!1,c=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/,d=function(){};d.extend=function(a){function d(){!b&&this.init&&this.init.apply(this,arguments)}var e=this.prototype;b=!0;var f=new this;b=!1;for(var g in a)f[g]="function"==typeof a[g]&&"function"==typeof e[g]&&c.test(a[g])?function(a,b){return function(){var c=this._super;this._super=e[a];var d=b.apply(this,arguments);return this._super=c,d}}(g,a[g]):a[g];return d.prototype=f,d.prototype.constructor=d,d.extend=arguments.callee,d},a.Class=d}(mui),function(a,b,c){var d="mui-pull-top-pocket",e="mui-pull-bottom-pocket",f="mui-pull",g="mui-pull-loading",h="mui-pull-caption",i="mui-pull-caption-down",j="mui-pull-caption-refresh",k="mui-pull-caption-nomore",l="mui-icon",m="mui-spinner",n="mui-icon-pulldown",o="mui-block",p="mui-hidden",q="mui-visibility",r=g+" "+l+" "+n,s=g+" "+l+" "+n,t=g+" "+l+" "+m,u=['
','
','
{contentrefresh}
',"
"].join(""),v={init:function(b,c){this._super(b,a.extend(!0,{scrollY:!0,scrollX:!1,indicators:!0,deceleration:.003,down:{height:50,contentinit:"下拉可以刷新",contentdown:"下拉可以刷新",contentover:"释放立即刷新",contentrefresh:"正在刷新..."},up:{height:50,auto:!1,contentinit:"上拉显示更多",contentdown:"上拉显示更多",contentrefresh:"正在加载...",contentnomore:"没有更多数据了",duration:300}},c))},_init:function(){this._super(),this._initPocket()},_initPulldownRefresh:function(){this.pulldown=!0,this.pullPocket=this.topPocket,this.pullPocket.classList.add(o),this.pullPocket.classList.add(q),this.pullCaption=this.topCaption,this.pullLoading=this.topLoading},_initPullupRefresh:function(){this.pulldown=!1,this.pullPocket=this.bottomPocket,this.pullPocket.classList.add(o),this.pullPocket.classList.add(q),this.pullCaption=this.bottomCaption,this.pullLoading=this.bottomLoading},_initPocket:function(){var a=this.options;a.down&&a.down.hasOwnProperty("callback")&&(this.topPocket=this.scroller.querySelector("."+d),this.topPocket||(this.topPocket=this._createPocket(d,a.down,s),this.wrapper.insertBefore(this.topPocket,this.wrapper.firstChild)),this.topLoading=this.topPocket.querySelector("."+g),this.topCaption=this.topPocket.querySelector("."+h)),a.up&&a.up.hasOwnProperty("callback")&&(this.bottomPocket=this.scroller.querySelector("."+e),this.bottomPocket||(this.bottomPocket=this._createPocket(e,a.up,t),this.scroller.appendChild(this.bottomPocket)),this.bottomLoading=this.bottomPocket.querySelector("."+g),this.bottomCaption=this.bottomPocket.querySelector("."+h),this.wrapper.addEventListener("scrollbottom",this))},_createPocket:function(a,c,d){var e=b.createElement("div");return e.className=a,e.innerHTML=u.replace("{contentrefresh}",c.contentinit).replace("{icon}",d),e},_resetPullDownLoading:function(){var a=this.pullLoading;a&&(this.pullCaption.innerHTML=this.options.down.contentdown,a.style.webkitTransition="",a.style.webkitTransform="",a.style.webkitAnimation="",a.className=s)},_setCaptionClass:function(a,b,c){if(!a)switch(c){case this.options.up.contentdown:b.className=h+" "+i;break;case this.options.up.contentrefresh:b.className=h+" "+j;break;case this.options.up.contentnomore:b.className=h+" "+k}},_setCaption:function(a,b){if(!this.loading){var c=this.options,d=this.pullPocket,e=this.pullCaption,f=this.pullLoading,g=this.pulldown,h=this;d&&(b?setTimeout(function(){e.innerHTML=h.lastTitle=a,g?f.className=s:(h._setCaptionClass(!1,e,a),f.className=t),f.style.webkitAnimation="",f.style.webkitTransition="",f.style.webkitTransform=""},100):a!==this.lastTitle&&(e.innerHTML=a,g?a===c.down.contentrefresh?(f.className=t,f.style.webkitAnimation="spinner-spin 1s step-end infinite"):a===c.down.contentover?(f.className=r,f.style.webkitTransition="-webkit-transform 0.3s ease-in",f.style.webkitTransform="rotate(180deg)"):a===c.down.contentdown&&(f.className=s,f.style.webkitTransition="-webkit-transform 0.3s ease-in",f.style.webkitTransform="rotate(0deg)"):(a===c.up.contentrefresh?f.className=t+" "+q:f.className=t+" "+p,h._setCaptionClass(!1,e,a)),this.lastTitle=a))}}};a.PullRefresh=v}(mui,document),function(a,b,c,d){var e="mui-scroll",f="mui-scrollbar",g="mui-scrollbar-indicator",h=f+"-vertical",i=f+"-horizontal",j="mui-active",k={quadratic:{style:"cubic-bezier(0.25, 0.46, 0.45, 0.94)",fn:function(a){return a*(2-a)}},circular:{style:"cubic-bezier(0.1, 0.57, 0.1, 1)",fn:function(a){return Math.sqrt(1- --a*a)}},outCirc:{style:"cubic-bezier(0.075, 0.82, 0.165, 1)"},outCubic:{style:"cubic-bezier(0.165, 0.84, 0.44, 1)"}},l=a.Class.extend({init:function(b,c){this.wrapper=this.element=b,this.scroller=this.wrapper.children[0],this.scrollerStyle=this.scroller&&this.scroller.style,this.stopped=!1,this.options=a.extend(!0,{scrollY:!0,scrollX:!1,startX:0,startY:0,indicators:!0,stopPropagation:!1,hardwareAccelerated:!0,fixedBadAndorid:!1,preventDefaultException:{tagName:/^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/},momentum:!0,snapX:.5,snap:!1,bounce:!0,bounceTime:500,bounceEasing:k.outCirc,scrollTime:500,scrollEasing:k.outCubic,directionLockThreshold:5,parallaxElement:!1,parallaxRatio:.5},c),this.x=0,this.y=0,this.translateZ=this.options.hardwareAccelerated?" translateZ(0)":"",this._init(),this.scroller&&(this.refresh(),this.scrollTo(this.options.startX,this.options.startY))},_init:function(){this._initParallax(),this._initIndicators(),this._initEvent()},_initParallax:function(){this.options.parallaxElement&&(this.parallaxElement=c.querySelector(this.options.parallaxElement),this.parallaxStyle=this.parallaxElement.style,this.parallaxHeight=this.parallaxElement.offsetHeight,this.parallaxImgStyle=this.parallaxElement.querySelector("img").style)},_initIndicators:function(){var a=this;if(a.indicators=[],this.options.indicators){var b,c=[];a.options.scrollY&&(b={el:this._createScrollBar(h),listenX:!1},this.wrapper.appendChild(b.el),c.push(b)),this.options.scrollX&&(b={el:this._createScrollBar(i),listenY:!1},this.wrapper.appendChild(b.el),c.push(b));for(var d=c.length;d--;)this.indicators.push(new m(this,c[d]))}},_initSnap:function(){this.currentPage={},this.pages=[];for(var a=this.snaps,b=a.length,c=0,d=-1,e=0,f=0,g=0,h=0,i=0;b>i;i++){var k=a[i],l=k.offsetLeft,m=k.offsetWidth;(0===i||l<=a[i-1].offsetLeft)&&(c=0,d++),this.pages[c]||(this.pages[c]=[]),e=this._getSnapX(l),h=Math.round(m*this.options.snapX),f=e-h,g=e-m+h,this.pages[c][d]={x:e,leftX:f,rightX:g,pageX:c,element:k},k.classList.contains(j)&&(this.currentPage=this.pages[c][0]),e>=this.maxScrollX&&c++}this.options.startX=this.currentPage.x||0},_getSnapX:function(a){return Math.max(Math.min(0,-a+this.wrapperWidth/2),this.maxScrollX)},_gotoPage:function(a){this.currentPage=this.pages[Math.min(a,this.pages.length-1)][0];for(var b=0,c=this.snaps.length;c>b;b++)b===a?this.snaps[b].classList.add(j):this.snaps[b].classList.remove(j);this.scrollTo(this.currentPage.x,0,this.options.scrollTime)},_nearestSnap:function(a){if(!this.pages.length)return{x:0,pageX:0};var b=0,c=this.pages.length;for(a>0?a=0:ab;b++){var d="left"===this.direction?this.pages[b][0].leftX:this.pages[b][0].rightX;if(a>=d)return this.pages[b][0]}return{x:0,pageX:0}},_initEvent:function(c){var d=c?"removeEventListener":"addEventListener";b[d]("orientationchange",this),b[d]("resize",this),this.scroller[d]("webkitTransitionEnd",this),this.wrapper[d](a.EVENT_START,this),this.wrapper[d](a.EVENT_CANCEL,this),this.wrapper[d](a.EVENT_END,this),this.wrapper[d]("drag",this),this.wrapper[d]("dragend",this),this.wrapper[d]("flick",this),this.wrapper[d]("scrollend",this),this.options.scrollX&&this.wrapper[d]("swiperight",this);var e=this.wrapper.querySelector(".mui-segmented-control");e&&mui(e)[c?"off":"on"]("click","a",a.preventDefault),this.wrapper[d]("scrollstart",this),this.wrapper[d]("refresh",this)},_handleIndicatorScrollend:function(){this.indicators.map(function(a){a.fade()})},_handleIndicatorScrollstart:function(){this.indicators.map(function(a){a.fade(1)})},_handleIndicatorRefresh:function(){this.indicators.map(function(a){a.refresh()})},handleEvent:function(b){if(this.stopped)return void this.resetPosition();switch(b.type){case a.EVENT_START:this._start(b);break;case"drag":this.options.stopPropagation&&b.stopPropagation(),this._drag(b);break;case"dragend":case"flick":this.options.stopPropagation&&b.stopPropagation(),this._flick(b);break;case a.EVENT_CANCEL:case a.EVENT_END:this._end(b);break;case"webkitTransitionEnd":this.transitionTimer&&this.transitionTimer.cancel(),this._transitionEnd(b);break;case"scrollstart":this._handleIndicatorScrollstart(b);break;case"scrollend":this._handleIndicatorScrollend(b),this._scrollend(b),b.stopPropagation();break;case"orientationchange":case"resize":this._resize();break;case"swiperight":b.stopPropagation();break;case"refresh":this._handleIndicatorRefresh(b)}},_start:function(b){if(this.moved=this.needReset=!1,this._transitionTime(),this.isInTransition){this.needReset=!0,this.isInTransition=!1;var c=a.parseTranslateMatrix(a.getStyles(this.scroller,"webkitTransform"));this.setTranslate(Math.round(c.x),Math.round(c.y)),a.trigger(this.scroller,"scrollend",this),b.preventDefault()}this.reLayout(),a.trigger(this.scroller,"beforescrollstart",this)},_getDirectionByAngle:function(a){return-80>a&&a>-100?"up":a>=80&&100>a?"down":a>=170||-170>=a?"left":a>=-35&&10>=a?"right":null},_drag:function(c){var d=c.detail;if((this.options.scrollY||"up"===d.direction||"down"===d.direction)&&a.os.ios&&parseFloat(a.os.version)>=8){var e=d.gesture.touches[0].clientY;if(e+10>b.innerHeight||10>e)return void this.resetPosition(this.options.bounceTime)}var f=isReturn=!1;this._getDirectionByAngle(d.angle);if("left"===d.direction||"right"===d.direction?this.options.scrollX?(f=!0,this.moved||(a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=d.direction)):this.options.scrollY&&!this.moved&&(isReturn=!0):"up"===d.direction||"down"===d.direction?this.options.scrollY?(f=!0,this.moved||(a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=d.direction)):this.options.scrollX&&!this.moved&&(isReturn=!0):isReturn=!0,(this.moved||f)&&(c.stopPropagation(),d.gesture&&d.gesture.preventDefault()),!isReturn){this.moved?c.stopPropagation():a.trigger(this.scroller,"scrollstart",this);var g=0,h=0;this.moved?(g=d.deltaX-a.gestures.session.prevTouch.deltaX,h=d.deltaY-a.gestures.session.prevTouch.deltaY):(g=d.deltaX,h=d.deltaY);var i=Math.abs(d.deltaX),j=Math.abs(d.deltaY);i>j+this.options.directionLockThreshold?h=0:j>=i+this.options.directionLockThreshold&&(g=0),g=this.hasHorizontalScroll?g:0,h=this.hasVerticalScroll?h:0;var k=this.x+g,l=this.y+h;(k>0||k0?0:this.maxScrollX),(l>0||l0?0:this.maxScrollY),this.requestAnimationFrame||this._updateTranslate(),this.direction=d.deltaX>0?"right":"left",this.moved=!0,this.x=k,this.y=l,a.trigger(this.scroller,"scroll",this)}},_flick:function(b){if(this.moved){b.stopPropagation();var c=b.detail;if(this._clearRequestAnimationFrame(),"dragend"!==b.type||!c.flick){var d=Math.round(this.x),e=Math.round(this.y);if(this.isInTransition=!1,!this.resetPosition(this.options.bounceTime)){if(this.scrollTo(d,e),"dragend"===b.type)return void a.trigger(this.scroller,"scrollend",this);var f=0,g="";return this.options.momentum&&c.flickTime<300&&(momentumX=this.hasHorizontalScroll?this._momentum(this.x,c.flickDistanceX,c.flickTime,this.maxScrollX,this.options.bounce?this.wrapperWidth:0,this.options.deceleration):{destination:d,duration:0},momentumY=this.hasVerticalScroll?this._momentum(this.y,c.flickDistanceY,c.flickTime,this.maxScrollY,this.options.bounce?this.wrapperHeight:0,this.options.deceleration):{destination:e,duration:0},d=momentumX.destination,e=momentumY.destination,f=Math.max(momentumX.duration,momentumY.duration),this.isInTransition=!0),d!=this.x||e!=this.y?((d>0||d0||e0&&this.y<=this.maxScrollY)&&a.trigger(this.scroller,"scrollbottom",this)},_resize:function(){var a=this;clearTimeout(a.resizeTimeout),a.resizeTimeout=setTimeout(function(){a.refresh()},a.options.resizePolling)},_transitionTime:function(b){if(b=b||0,this.scrollerStyle.webkitTransitionDuration=b+"ms",this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration=b+"ms"),this.options.fixedBadAndorid&&!b&&a.os.isBadAndroid&&(this.scrollerStyle.webkitTransitionDuration="0.001s",this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration="0.001s")),this.indicators)for(var c=this.indicators.length;c--;)this.indicators[c].transitionTime(b);b&&(this.transitionTimer&&this.transitionTimer.cancel(),this.transitionTimer=a.later(function(){a.trigger(this.scroller,"webkitTransitionEnd")},b+100,this))},_transitionTimingFunction:function(a){if(this.scrollerStyle.webkitTransitionTimingFunction=a,this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration=a),this.indicators)for(var b=this.indicators.length;b--;)this.indicators[b].transitionTimingFunction(a)},_translate:function(a,b){this.x=a,this.y=b},_clearRequestAnimationFrame:function(){this.requestAnimationFrame&&(cancelAnimationFrame(this.requestAnimationFrame),this.requestAnimationFrame=null)},_updateTranslate:function(){var a=this;(a.x!==a.lastX||a.y!==a.lastY)&&a.setTranslate(a.x,a.y),a.requestAnimationFrame=requestAnimationFrame(function(){a._updateTranslate()})},_createScrollBar:function(a){var b=c.createElement("div"),d=c.createElement("div");return b.className=f+" "+a,d.className=g,b.appendChild(d),a===h?(this.scrollbarY=b,this.scrollbarIndicatorY=d):a===i&&(this.scrollbarX=b,this.scrollbarIndicatorX=d),this.wrapper.appendChild(b),b},_preventDefaultException:function(a,b){for(var c in b)if(b[c].test(a[c]))return!0;return!1},_reLayout:function(){if(this.hasHorizontalScroll||(this.maxScrollX=0,this.scrollerWidth=this.wrapperWidth),this.hasVerticalScroll||(this.maxScrollY=0,this.scrollerHeight=this.wrapperHeight),this.indicators.map(function(a){a.refresh()}),this.options.snap&&"string"==typeof this.options.snap){var a=this.scroller.querySelectorAll(this.options.snap);this.itemLength=0,this.snaps=[];for(var b=0,c=a.length;c>b;b++){var d=a[b];d.parentNode===this.scroller&&(this.itemLength++,this.snaps.push(d))}this._initSnap()}},_momentum:function(a,b,c,e,f,g){var h,i,j=parseFloat(Math.abs(b)/c);return g=g===d?6e-4:g,h=a+j*j/(2*g)*(0>b?-1:1),i=j/g,e>h?(h=f?e-f/2.5*(j/8):e,b=Math.abs(h-a),i=b/j):h>0&&(h=f?f/2.5*(j/8):0,b=Math.abs(a)+h,i=b/j),{destination:Math.round(h),duration:i}},_getTranslateStr:function(a,b){return this.options.hardwareAccelerated?"translate3d("+a+"px,"+b+"px,0px) "+this.translateZ:"translate("+a+"px,"+b+"px) "},setStopped:function(a){this.stopped=!!a},setTranslate:function(b,c){if(this.x=b,this.y=c,this.scrollerStyle.webkitTransform=this._getTranslateStr(b,c),this.parallaxElement&&this.options.scrollY){var d=c*this.options.parallaxRatio,e=1+d/((this.parallaxHeight-d)/2);e>1?(this.parallaxImgStyle.opacity=1-d/100*this.options.parallaxRatio,this.parallaxStyle.webkitTransform=this._getTranslateStr(0,-d)+" scale("+e+","+e+")"):(this.parallaxImgStyle.opacity=1,this.parallaxStyle.webkitTransform=this._getTranslateStr(0,-1)+" scale(1,1)")}if(this.indicators)for(var f=this.indicators.length;f--;)this.indicators[f].updatePosition();this.lastX=this.x,this.lastY=this.y,a.trigger(this.scroller,"scroll",this)},reLayout:function(){this.wrapper.offsetHeight;var b=parseFloat(a.getStyles(this.wrapper,"padding-left"))||0,c=parseFloat(a.getStyles(this.wrapper,"padding-right"))||0,d=parseFloat(a.getStyles(this.wrapper,"padding-top"))||0,e=parseFloat(a.getStyles(this.wrapper,"padding-bottom"))||0,f=this.wrapper.clientWidth,g=this.wrapper.clientHeight;this.scrollerWidth=this.scroller.offsetWidth,this.scrollerHeight=this.scroller.offsetHeight,this.wrapperWidth=f-b-c,this.wrapperHeight=g-d-e,this.maxScrollX=Math.min(this.wrapperWidth-this.scrollerWidth,0),this.maxScrollY=Math.min(this.wrapperHeight-this.scrollerHeight,0),this.hasHorizontalScroll=this.options.scrollX&&this.maxScrollX<0,this.hasVerticalScroll=this.options.scrollY&&this.maxScrollY<0,this._reLayout()},resetPosition:function(a){var b=this.x,c=this.y;return a=a||0,!this.hasHorizontalScroll||this.x>0?b=0:this.x0?c=0:this.yb;b++)if(a[b].parentNode===this.wrapper){this.scroller=a[b];break}this.scrollerStyle=this.scroller&&this.scroller.style},refresh:function(){this._reInit(),this.reLayout(),a.trigger(this.scroller,"refresh",this),this.resetPosition()},scrollTo:function(a,b,c,d){var d=d||k.circular;this.isInTransition=c>0,this.isInTransition?(this._clearRequestAnimationFrame(),this._transitionTimingFunction(d.style),this._transitionTime(c),this.setTranslate(a,b)):this.setTranslate(a,b)},scrollToBottom:function(a,b){a=a||this.options.scrollTime,this.scrollTo(0,this.maxScrollY,a,b)},gotoPage:function(a){this._gotoPage(a)},destroy:function(){this._initEvent(!0),delete a.data[this.wrapper.getAttribute("data-scroll")],this.wrapper.setAttribute("data-scroll","")}}),m=function(b,d){this.wrapper="string"==typeof d.el?c.querySelector(d.el):d.el,this.wrapperStyle=this.wrapper.style,this.indicator=this.wrapper.children[0],this.indicatorStyle=this.indicator.style,this.scroller=b,this.options=a.extend({listenX:!0,listenY:!0,fade:!1,speedRatioX:0,speedRatioY:0},d),this.sizeRatioX=1,this.sizeRatioY=1,this.maxPosX=0,this.maxPosY=0,this.options.fade&&(this.wrapperStyle.webkitTransform=this.scroller.translateZ,this.wrapperStyle.webkitTransitionDuration=this.options.fixedBadAndorid&&a.os.isBadAndroid?"0.001s":"0ms",this.wrapperStyle.opacity="0")};m.prototype={handleEvent:function(a){},transitionTime:function(b){b=b||0,this.indicatorStyle.webkitTransitionDuration=b+"ms",this.scroller.options.fixedBadAndorid&&!b&&a.os.isBadAndroid&&(this.indicatorStyle.webkitTransitionDuration="0.001s")},transitionTimingFunction:function(a){this.indicatorStyle.webkitTransitionTimingFunction=a},refresh:function(){this.transitionTime(),this.options.listenX&&!this.options.listenY?this.indicatorStyle.display=this.scroller.hasHorizontalScroll?"block":"none":this.options.listenY&&!this.options.listenX?this.indicatorStyle.display=this.scroller.hasVerticalScroll?"block":"none":this.indicatorStyle.display=this.scroller.hasHorizontalScroll||this.scroller.hasVerticalScroll?"block":"none",this.wrapper.offsetHeight,this.options.listenX&&(this.wrapperWidth=this.wrapper.clientWidth,this.indicatorWidth=Math.max(Math.round(this.wrapperWidth*this.wrapperWidth/(this.scroller.scrollerWidth||this.wrapperWidth||1)),8),this.indicatorStyle.width=this.indicatorWidth+"px",this.maxPosX=this.wrapperWidth-this.indicatorWidth,this.minBoundaryX=0,this.maxBoundaryX=this.maxPosX,this.sizeRatioX=this.options.speedRatioX||this.scroller.maxScrollX&&this.maxPosX/this.scroller.maxScrollX),this.options.listenY&&(this.wrapperHeight=this.wrapper.clientHeight,this.indicatorHeight=Math.max(Math.round(this.wrapperHeight*this.wrapperHeight/(this.scroller.scrollerHeight||this.wrapperHeight||1)),8),this.indicatorStyle.height=this.indicatorHeight+"px",this.maxPosY=this.wrapperHeight-this.indicatorHeight,this.minBoundaryY=0,this.maxBoundaryY=this.maxPosY,this.sizeRatioY=this.options.speedRatioY||this.scroller.maxScrollY&&this.maxPosY/this.scroller.maxScrollY),this.updatePosition()},updatePosition:function(){var a=this.options.listenX&&Math.round(this.sizeRatioX*this.scroller.x)||0,b=this.options.listenY&&Math.round(this.sizeRatioY*this.scroller.y)||0;athis.maxBoundaryX?(this.width=Math.max(this.indicatorWidth-(a-this.maxPosX),8),this.indicatorStyle.width=this.width+"px",a=this.maxPosX+this.indicatorWidth-this.width):this.width!=this.indicatorWidth&&(this.width=this.indicatorWidth,this.indicatorStyle.width=this.width+"px"),bthis.maxBoundaryY?(this.height=Math.max(this.indicatorHeight-3*(b-this.maxPosY),8),this.indicatorStyle.height=this.height+"px",b=this.maxPosY+this.indicatorHeight-this.height):this.height!=this.indicatorHeight&&(this.height=this.indicatorHeight,this.indicatorStyle.height=this.height+"px"),this.x=a,this.y=b,this.indicatorStyle.webkitTransform=this.scroller._getTranslateStr(a,b)},fade:function(a,b){if(!b||this.visible){clearTimeout(this.fadeTimeout),this.fadeTimeout=null;var c=a?250:500,d=a?0:300;a=a?"1":"0",this.wrapperStyle.webkitTransitionDuration=c+"ms",this.fadeTimeout=setTimeout(function(a){this.wrapperStyle.opacity=a,this.visible=+a}.bind(this,a),d)}}},a.Scroll=l,a.fn.scroll=function(b){var c=[];return this.each(function(){var d=null,e=this,f=e.getAttribute("data-scroll");if(f)d=a.data[f];else{f=++a.uuid;var g=a.extend({},b);e.classList.contains("mui-segmented-control")&&(g=a.extend(g,{scrollY:!1,scrollX:!0,indicators:!1,snap:".mui-control-item"})),a.data[f]=d=new l(e,g),e.setAttribute("data-scroll",f)}c.push(d)}),1===c.length?c[0]:c}}(mui,window,document),function(a,b,c,d){var e="mui-visibility",f="mui-hidden",g=a.Scroll.extend(a.extend({handleEvent:function(a){this._super(a),"scrollbottom"===a.type&&a.target===this.scroller&&this._scrollbottom()},_scrollbottom:function(){this.pulldown||this.loading||(this.pulldown=!1,this._initPullupRefresh(),this.pullupLoading())},_start:function(a){a.touches&&a.touches.length&&a.touches[0].clientX>30&&a.target&&!this._preventDefaultException(a.target,this.options.preventDefaultException)&&a.preventDefault(),this.loading||(this.pulldown=this.pullPocket=this.pullCaption=this.pullLoading=!1),this._super(a)},_drag:function(a){this._super(a),!this.pulldown&&!this.loading&&this.topPocket&&"down"===a.detail.direction&&this.y>=0&&this._initPulldownRefresh(),this.pulldown&&this._setCaption(this.y>this.options.down.height?this.options.down.contentover:this.options.down.contentdown)},_reLayout:function(){this.hasVerticalScroll=!0,this._super()},resetPosition:function(a){if(this.pulldown){if(this.y>=this.options.down.height)return this.pulldownLoading(d,a||0),!0;!this.loading&&this.topPocket.classList.remove(e)}return this._super(a)},pulldownLoading:function(a,b){if("undefined"==typeof a&&(a=this.options.down.height),this.scrollTo(0,a,b,this.options.bounceEasing),!this.loading){this._initPulldownRefresh(),this._setCaption(this.options.down.contentrefresh),this.loading=!0,this.indicators.map(function(a){a.fade(0)});var c=this.options.down.callback;c&&c.call(this)}},endPulldownToRefresh:function(){var a=this;a.topPocket&&a.loading&&this.pulldown&&(a.scrollTo(0,0,a.options.bounceTime,a.options.bounceEasing),a.loading=!1,a._setCaption(a.options.down.contentdown,!0),setTimeout(function(){a.loading||a.topPocket.classList.remove(e)},350))},pullupLoading:function(a,b,c){b=b||0,this.scrollTo(b,this.maxScrollY,c,this.options.bounceEasing),this.loading||(this._initPullupRefresh(),this._setCaption(this.options.up.contentrefresh),this.indicators.map(function(a){a.fade(0)}),this.loading=!0,a=a||this.options.up.callback,a&&a.call(this))},endPullupToRefresh:function(a){var b=this;b.bottomPocket&&(b.loading=!1,a?(this.finished=!0,b._setCaption(b.options.up.contentnomore),b.wrapper.removeEventListener("scrollbottom",b)):(b._setCaption(b.options.up.contentdown),b.loading||b.bottomPocket.classList.remove(e)))},disablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.className="mui-pull-bottom-pocket "+f,this.wrapper.removeEventListener("scrollbottom",this)},enablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.classList.remove(f),this._setCaption(this.options.up.contentdown),this.wrapper.addEventListener("scrollbottom",this)},refresh:function(a){a&&this.finished&&(this.enablePullupToRefresh(),this.finished=!1),this._super()}},a.PullRefresh));a.fn.pullRefresh=function(b){if(1===this.length){var c=this[0],d=null;b=b||{};var e=c.getAttribute("data-pullrefresh");return e?d=a.data[e]:(e=++a.uuid,a.data[e]=d=new g(c,b),c.setAttribute("data-pullrefresh",e)),b.down&&b.down.auto?d.pulldownLoading(b.down.autoY):b.up&&b.up.auto&&d.pullupLoading(),d}}}(mui,window,document),function(a,b){var c="mui-slider",d="mui-slider-group",e="mui-slider-loop",f="mui-action-previous",g="mui-action-next",h="mui-slider-item",i="mui-active",j="."+h,k=".mui-slider-progress-bar",l=a.Slider=a.Scroll.extend({init:function(b,c){this._super(b,a.extend(!0,{fingers:1,interval:0,scrollY:!1,scrollX:!0,indicators:!1,scrollTime:1e3,startX:!1,slideTime:0,snap:j},c)),this.options.startX},_init:function(){this._reInit(),this.scroller&&(this.scrollerStyle=this.scroller.style,this.progressBar=this.wrapper.querySelector(k),this.progressBar&&(this.progressBarWidth=this.progressBar.offsetWidth,this.progressBarStyle=this.progressBar.style),this._super(),this._initTimer())},_triggerSlide:function(){var b=this;b.isInTransition=!1;b.currentPage;b.slideNumber=b._fixedSlideNumber(),b.loop&&(0===b.slideNumber?b.setTranslate(b.pages[1][0].x,0):b.slideNumber===b.itemLength-3&&b.setTranslate(b.pages[b.itemLength-2][0].x,0)),b.lastSlideNumber!=b.slideNumber&&(b.lastSlideNumber=b.slideNumber,b.lastPage=b.currentPage,a.trigger(b.wrapper,"slide",{slideNumber:b.slideNumber})),b._initTimer()},_handleSlide:function(b){var c=this;if(b.target===c.wrapper){var d=b.detail;d.slideNumber=d.slideNumber||0;for(var e=c.scroller.querySelectorAll(j),f=[],g=0,h=e.length;h>g;g++){var k=e[g];k.parentNode===c.scroller&&f.push(k)}var l=d.slideNumber;if(c.loop&&(l+=1),!c.wrapper.classList.contains("mui-segmented-control"))for(var g=0,h=f.length;h>g;g++){var k=f[g];k.parentNode===c.scroller&&(g===l?k.classList.add(i):k.classList.remove(i))}var m=c.wrapper.querySelector(".mui-slider-indicator");if(m){m.getAttribute("data-scroll")&&a(m).scroll().gotoPage(d.slideNumber);var n=m.querySelectorAll(".mui-indicator");if(n.length>0)for(var g=0,h=n.length;h>g;g++)n[g].classList[g===d.slideNumber?"add":"remove"](i);else{var o=m.querySelector(".mui-number span");if(o)o.innerText=d.slideNumber+1;else for(var p=m.querySelectorAll(".mui-control-item"),g=0,h=p.length;h>g;g++)p[g].classList[g===d.slideNumber?"add":"remove"](i)}}b.stopPropagation()}},_handleTabShow:function(a){var b=this;b.gotoItem(a.detail.tabNumber||0,b.options.slideTime)},_handleIndicatorTap:function(a){var b=this,c=a.target;(c.classList.contains(f)||c.classList.contains(g))&&(b[c.classList.contains(f)?"prevItem":"nextItem"](),a.stopPropagation())},_initEvent:function(b){var c=this;c._super(b);var d=b?"removeEventListener":"addEventListener";c.wrapper[d]("slide",this),c.wrapper[d](a.eventName("shown","tab"),this)},handleEvent:function(b){switch(this._super(b),b.type){case"slide":this._handleSlide(b);break;case a.eventName("shown","tab"):~this.snaps.indexOf(b.target)&&this._handleTabShow(b)}},_scrollend:function(a){this._super(a),this._triggerSlide(a)},_drag:function(a){this._super(a);var c=a.detail.direction;if("left"===c||"right"===c){var d=this.wrapper.getAttribute("data-slidershowTimer");d&&b.clearTimeout(d),a.stopPropagation()}},_initTimer:function(){var a=this,c=a.wrapper,d=a.options.interval,e=c.getAttribute("data-slidershowTimer");e&&b.clearTimeout(e),d&&(e=b.setTimeout(function(){c&&((c.offsetWidth||c.offsetHeight)&&a.nextItem(!0), +a._initTimer())},d),c.setAttribute("data-slidershowTimer",e))},_fixedSlideNumber:function(a){a=a||this.currentPage;var b=a.pageX;return this.loop&&(b=0===a.pageX?this.itemLength-3:a.pageX===this.itemLength-1?0:a.pageX-1),b},_reLayout:function(){this.hasHorizontalScroll=!0,this.loop=this.scroller.classList.contains(e),this._super()},_getScroll:function(){var b=a.parseTranslateMatrix(a.getStyles(this.scroller,"webkitTransform"));return b?b.x:0},_transitionEnd:function(b){b.target===this.scroller&&this.isInTransition&&(this._transitionTime(),this.isInTransition=!1,a.trigger(this.wrapper,"scrollend",this))},_flick:function(a){if(this.moved){var b=a.detail,c=b.direction;this._clearRequestAnimationFrame(),this.isInTransition=!0,"flick"===a.type?(b.deltaTime<200&&(this.x=this._getPage(this.slideNumber+("right"===c?-1:1),!0).x),this.resetPosition(this.options.bounceTime)):"dragend"!==a.type||b.flick||this.resetPosition(this.options.bounceTime),a.stopPropagation()}},_initSnap:function(){if(this.scrollerWidth=this.itemLength*this.scrollerWidth,this.maxScrollX=Math.min(this.wrapperWidth-this.scrollerWidth,0),this._super(),this.currentPage.x)this.slideNumber=this._fixedSlideNumber(),this.lastSlideNumber="undefined"==typeof this.lastSlideNumber?this.slideNumber:this.lastSlideNumber;else{var a=this.pages[this.loop?1:0];if(a=a||this.pages[0],!a)return;this.currentPage=a[0],this.slideNumber=0,this.lastSlideNumber="undefined"==typeof this.lastSlideNumber?0:this.lastSlideNumber}this.options.startX=this.currentPage.x||0},_getSnapX:function(a){return Math.max(-a,this.maxScrollX)},_getPage:function(a,b){return this.loop?a>this.itemLength-(b?2:3)?(a=1,time=0):(b?-1:0)>a?(a=this.itemLength-2,time=0):a+=1:(b||(a>this.itemLength-1?(a=0,time=0):0>a&&(a=this.itemLength-1,time=0)),a=Math.min(Math.max(0,a),this.itemLength-1)),this.pages[a][0]},_gotoItem:function(b,c){this.currentPage=this._getPage(b,!0),this.scrollTo(this.currentPage.x,0,c,this.options.scrollEasing),0===c&&a.trigger(this.wrapper,"scrollend",this)},setTranslate:function(a,b){this._super(a,b);var c=this.progressBar;c&&(this.progressBarStyle.webkitTransform=this._getTranslateStr(-a*(this.progressBarWidth/this.wrapperWidth),0))},resetPosition:function(a){return a=a||0,this.x>0?this.x=0:this.xb;b++)if(a[b].parentNode===this.wrapper){this.scroller=a[b];break}this.scrollerStyle=this.scroller&&this.scroller.style,this.progressBar&&(this.progressBarWidth=this.progressBar.offsetWidth,this.progressBarStyle=this.progressBar.style)},refresh:function(b){b?(a.extend(this.options,b),this._super(),this._initTimer()):this._super()},destroy:function(){this._initEvent(!0),delete a.data[this.wrapper.getAttribute("data-slider")],this.wrapper.setAttribute("data-slider","")}});a.fn.slider=function(b){var d=null;return this.each(function(){var e=this;if(this.classList.contains(c)||(e=this.querySelector("."+c)),e&&e.querySelector(j)){var f=e.getAttribute("data-slider");f?(d=a.data[f],d&&b&&d.refresh(b)):(f=++a.uuid,a.data[f]=d=new l(e,b),e.setAttribute("data-slider",f))}}),d},a.ready(function(){a(".mui-slider").slider(),a(".mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control").scroll({scrollY:!1,scrollX:!0,indicators:!1,snap:".mui-control-item"})})}(mui,window),function(a,b){if(a.os.plus&&a.os.android){var c="mui-plus-pullrefresh",d="mui-visibility",e="mui-hidden",f="mui-block",g="mui-pull-caption",h="mui-pull-caption-down",i="mui-pull-caption-refresh",j="mui-pull-caption-nomore",k=a.Class.extend({init:function(a,b){this.element=a,this.options=b,this.wrapper=this.scroller=a,this._init(),this._initPulldownRefreshEvent()},_init:function(){var a=this;window.addEventListener("dragup",a),b.addEventListener("plusscrollbottom",a),a.scrollInterval=window.setInterval(function(){a.isScroll&&!a.loading&&window.pageYOffset+window.innerHeight+10>=b.documentElement.scrollHeight&&(a.isScroll=!1,a.bottomPocket&&a.pullupLoading())},100)},_initPulldownRefreshEvent:function(){var b=this;b.topPocket&&b.options.webviewId&&a.plusReady(function(){var a=plus.webview.getWebviewById(b.options.webviewId);if(a){b.options.webview=a;var c=b.options.down,d=c.height;a.addEventListener("dragBounce",function(d){switch(b.pulldown?b.pullPocket.classList.add(f):b._initPulldownRefresh(),d.status){case"beforeChangeOffset":b._setCaption(c.contentdown);break;case"afterChangeOffset":b._setCaption(c.contentover);break;case"dragEndAfterChangeOffset":a.evalJS("mui&&mui.options.pullRefresh.down.callback()"),b._setCaption(c.contentrefresh)}},!1),a.setBounce({position:{top:2*d+"px"},changeoffset:{top:d+"px"}})}})},handleEvent:function(a){var b=this;b.stopped||(b.isScroll=!1,("dragup"===a.type||"plusscrollbottom"===a.type)&&(b.isScroll=!0,setTimeout(function(){b.isScroll=!1},1e3)))}}).extend(a.extend({setStopped:function(a){this.stopped=!!a;var b=plus.webview.currentWebview();if(this.stopped)b.setStyle({bounce:"none"}),b.setBounce({position:{top:"none"}});else{var c=this.options.down.height;b.setStyle({bounce:"vertical"}),b.setBounce({position:{top:2*c+"px"},changeoffset:{top:c+"px"}})}},pulldownLoading:function(){a.plusReady(function(){plus.webview.currentWebview().setBounce({offset:{top:this.options.down.height+"px"}})}.bind(this))},_pulldownLoading:function(){var b=this;a.plusReady(function(){var a=plus.webview.getWebviewById(b.options.webviewId);a.setBounce({offset:{top:b.options.down.height+"px"}})})},endPulldownToRefresh:function(){var a=plus.webview.currentWebview();a.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('"+JSON.stringify({webviewId:a.id})+"')._endPulldownToRefresh()")},_endPulldownToRefresh:function(){var a=this;a.topPocket&&a.options.webview&&(a.options.webview.endPullToRefresh(),a.loading=!1,a._setCaption(a.options.down.contentdown,!0),setTimeout(function(){a.loading||a.topPocket.classList.remove(f)},350))},pullupLoading:function(a){var b=this;b.isLoading||(b.isLoading=!0,b.pulldown!==!1?b._initPullupRefresh():this.pullPocket.classList.add(f),setTimeout(function(){b.pullLoading.classList.add(d),b.pullLoading.classList.remove(e),b.pullCaption.innerHTML="",b.pullCaption.className=g+" "+i,b.pullCaption.innerHTML=b.options.up.contentrefresh,a=a||b.options.up.callback,a&&a.call(b)},300))},endPullupToRefresh:function(a){var c=this;c.pullLoading&&(c.pullLoading.classList.remove(d),c.pullLoading.classList.add(e),c.isLoading=!1,a?(c.finished=!0,c.pullCaption.className=g+" "+j,c.pullCaption.innerHTML=c.options.up.contentnomore,b.removeEventListener("plusscrollbottom",c),window.removeEventListener("dragup",c)):(c.pullCaption.className=g+" "+h,c.pullCaption.innerHTML=c.options.up.contentdown))},disablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.className="mui-pull-bottom-pocket "+e,window.removeEventListener("dragup",this)},enablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.classList.remove(e),this.pullCaption.className=g+" "+h,this.pullCaption.innerHTML=this.options.up.contentdown,b.addEventListener("plusscrollbottom",this),window.addEventListener("dragup",this)},scrollTo:function(b,c,d){a.scrollTo(c,d)},scrollToBottom:function(c){a.scrollTo(b.documentElement.scrollHeight,c)},refresh:function(a){a&&this.finished&&(this.enablePullupToRefresh(),this.finished=!1)}},a.PullRefresh));a.fn.pullRefresh=function(d){var e;0===this.length?(e=b.createElement("div"),e.className="mui-content",b.body.appendChild(e)):e=this[0];var f=d;d=d||{},"string"==typeof d&&(d=a.parseJSON(d)),!d.webviewId&&(d.webviewId=plus.webview.currentWebview().id||plus.webview.currentWebview().getURL());var g=null,h=d.webviewId&&d.webviewId.replace(/\//g,"_"),i=e.getAttribute("data-pullrefresh-plus-"+h);return i||"undefined"!=typeof f?(i?g=a.data[i]:(i=++a.uuid,e.setAttribute("data-pullrefresh-plus-"+h,i),b.body.classList.add(c),a.data[i]=g=new k(e,d)),d.down&&d.down.auto?g._pulldownLoading():d.up&&d.up.auto&&g.pullupLoading(),g):!1}}}(mui,document),function(a,b,c,d){var e="mui-off-canvas-left",f="mui-off-canvas-right",g="mui-off-canvas-backdrop",h="mui-off-canvas-wrap",i="mui-slide-in",j="mui-active",k="mui-transitioning",l=".mui-inner-wrap",m=a.Class.extend({init:function(b,d){this.wrapper=this.element=b,this.scroller=this.wrapper.querySelector(l),this.classList=this.wrapper.classList,this.scroller&&(this.options=a.extend(!0,{dragThresholdX:10,scale:.8,opacity:.1,preventDefaultException:{tagName:/^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/}},d),c.body.classList.add("mui-fullscreen"),this.refresh(),this.initEvent())},_preventDefaultException:function(a,b){for(var c in b)if(b[c].test(a[c]))return!0;return!1},refresh:function(a){this.slideIn=this.classList.contains(i),this.scalable=this.classList.contains("mui-scalable")&&!this.slideIn,this.scroller=this.wrapper.querySelector(l),this.offCanvasLefts=this.wrapper.querySelectorAll("."+e),this.offCanvasRights=this.wrapper.querySelectorAll("."+f),a?a.classList.contains(e)?this.offCanvasLeft=a:a.classList.contains(f)&&(this.offCanvasRight=a):(this.offCanvasRight=this.wrapper.querySelector("."+f),this.offCanvasLeft=this.wrapper.querySelector("."+e)),this.offCanvasRightWidth=this.offCanvasLeftWidth=0,this.offCanvasLeftSlideIn=this.offCanvasRightSlideIn=!1,this.offCanvasRight&&(this.offCanvasRightWidth=this.offCanvasRight.offsetWidth,this.offCanvasRightSlideIn=this.slideIn&&this.offCanvasRight.parentNode===this.wrapper),this.offCanvasLeft&&(this.offCanvasLeftWidth=this.offCanvasLeft.offsetWidth,this.offCanvasLeftSlideIn=this.slideIn&&this.offCanvasLeft.parentNode===this.wrapper),this.backdrop=this.scroller.querySelector("."+g),this.options.dragThresholdX=this.options.dragThresholdX||10,this.visible=!1,this.startX=null,this.lastX=null,this.offsetX=null,this.lastTranslateX=null},handleEvent:function(b){switch(b.type){case a.EVENT_START:b.target&&!this._preventDefaultException(b.target,this.options.preventDefaultException)&&b.preventDefault();break;case"webkitTransitionEnd":b.target===this.scroller&&this._dispatchEvent();break;case"drag":var c=b.detail;this.startX?this.lastX=c.center.x:(this.startX=c.center.x,this.lastX=this.startX),!this.isDragging&&Math.abs(this.lastX-this.startX)>this.options.dragThresholdX&&("left"===c.direction||"right"===c.direction)&&(this.slideIn?(this.scroller=this.wrapper.querySelector(l),this.classList.contains(j)?this.offCanvasRight&&this.offCanvasRight.classList.contains(j)?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):"left"===c.direction&&this.offCanvasRight?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):"right"===c.direction&&this.offCanvasLeft?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):this.scroller=null):this.classList.contains(j)?"left"===c.direction?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):"right"===c.direction?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth),this.offCanvas&&this.scroller&&(this.startX=this.lastX,this.isDragging=!0,a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=c.direction,this.offCanvas.classList.remove(k),this.scroller.classList.remove(k),this.offsetX=this.getTranslateX(),this._initOffCanvasVisible())),this.isDragging&&(this.updateTranslate(this.offsetX+(this.lastX-this.startX)),c.gesture.preventDefault(),b.stopPropagation());break;case"dragend":if(this.isDragging){var c=b.detail,d=c.direction;this.isDragging=!1,this.offCanvas.classList.add(k),this.scroller.classList.add(k);var e=0,f=this.getTranslateX();if(this.slideIn){if(e=f>=0?this.offCanvasRightWidth&&f/this.offCanvasRightWidth||0:this.offCanvasLeftWidth&&f/this.offCanvasLeftWidth||0,"right"===d&&0>=e&&(e>=-.5||c.swipe)?this.openPercentage(100):"right"===d&&e>0&&(e>=.5||c.swipe)?this.openPercentage(0):"right"===d&&-.5>=e?this.openPercentage(0):"right"===d&&e>0&&.5>=e?this.openPercentage(-100):"left"===d&&e>=0&&(.5>=e||c.swipe)?this.openPercentage(-100):"left"===d&&0>e&&(-.5>=e||c.swipe)?this.openPercentage(0):"left"===d&&e>=.5?this.openPercentage(0):"left"===d&&e>=-.5&&0>e?this.openPercentage(100):this.openPercentage(0),1===e||-1===e||0===e)return void this._dispatchEvent()}else{if(e=f>=0?this.offCanvasLeftWidth&&f/this.offCanvasLeftWidth||0:this.offCanvasRightWidth&&f/this.offCanvasRightWidth||0,0===e)return this.openPercentage(0),void this._dispatchEvent();"right"===d&&e>=0&&(e>=.5||c.swipe)?this.openPercentage(100):"right"===d&&0>e&&(e>-.5||c.swipe)?this.openPercentage(0):"right"===d&&e>0&&.5>e?this.openPercentage(0):"right"===d&&.5>e?this.openPercentage(-100):"left"===d&&0>=e&&(-.5>=e||c.swipe)?this.openPercentage(-100):"left"===d&&e>0&&(.5>=e||c.swipe)?this.openPercentage(0):"left"===d&&0>e&&e>=-.5?this.openPercentage(0):"left"===d&&e>.5?this.openPercentage(100):this.openPercentage(0),(1===e||-1===e)&&this._dispatchEvent()}}}},_dispatchEvent:function(){this.classList.contains(j)?a.trigger(this.wrapper,"shown",this):a.trigger(this.wrapper,"hidden",this)},_initOffCanvasVisible:function(){this.visible||(this.visible=!0,this.offCanvasLeft&&(this.offCanvasLeft.style.visibility="visible"),this.offCanvasRight&&(this.offCanvasRight.style.visibility="visible"))},initEvent:function(){var b=this;b.backdrop&&b.backdrop.addEventListener("tap",function(a){b.close(),a.detail.gesture.preventDefault()}),this.classList.contains("mui-draggable")&&(this.wrapper.addEventListener(a.EVENT_START,this),this.wrapper.addEventListener("drag",this),this.wrapper.addEventListener("dragend",this)),this.wrapper.addEventListener("webkitTransitionEnd",this)},openPercentage:function(a){var b=a/100;this.slideIn?(this.offCanvasLeft&&a>=0?(b=0===b?-1:0,this.updateTranslate(this.offCanvasLeftWidth*b),this.offCanvasLeft.classList[0!==a?"add":"remove"](j)):this.offCanvasRight&&0>=a&&(b=0===b?1:0,this.updateTranslate(this.offCanvasRightWidth*b),this.offCanvasRight.classList[0!==a?"add":"remove"](j)),this.classList[0!==a?"add":"remove"](j)):(this.offCanvasLeft&&a>=0?(this.updateTranslate(this.offCanvasLeftWidth*b),this.offCanvasLeft.classList[0!==b?"add":"remove"](j)):this.offCanvasRight&&0>=a&&(this.updateTranslate(this.offCanvasRightWidth*b),this.offCanvasRight.classList[0!==b?"add":"remove"](j)),this.classList[0!==b?"add":"remove"](j))},updateTranslate:function(b){if(b!==this.lastTranslateX){if(this.slideIn){if(this.offCanvas.classList.contains(f)){if(0>b)return void this.setTranslateX(0);if(b>this.offCanvasRightWidth)return void this.setTranslateX(this.offCanvasRightWidth)}else{if(b>0)return void this.setTranslateX(0);if(b<-this.offCanvasLeftWidth)return void this.setTranslateX(-this.offCanvasLeftWidth)}this.setTranslateX(b)}else{if(!this.offCanvasLeft&&b>0||!this.offCanvasRight&&0>b)return void this.setTranslateX(0);if(this.leftShowing&&b>this.offCanvasLeftWidth)return void this.setTranslateX(this.offCanvasLeftWidth);if(this.rightShowing&&b<-this.offCanvasRightWidth)return void this.setTranslateX(-this.offCanvasRightWidth);this.setTranslateX(b),b>=0?(this.leftShowing=!0,this.rightShowing=!1,b>0&&(this.offCanvasLeft&&a.each(this.offCanvasLefts,function(a,b){b===this.offCanvasLeft?this.offCanvasLeft.style.zIndex=0:b.style.zIndex=-1}.bind(this)),this.offCanvasRight&&(this.offCanvasRight.style.zIndex=-1))):(this.rightShowing=!0,this.leftShowing=!1,this.offCanvasRight&&a.each(this.offCanvasRights,function(a,b){b===this.offCanvasRight?b.style.zIndex=0:b.style.zIndex=-1}.bind(this)),this.offCanvasLeft&&(this.offCanvasLeft.style.zIndex=-1))}this.lastTranslateX=b}},setTranslateX:a.animationFrame(function(a){if(this.scroller)if(this.scalable&&this.offCanvas.parentNode===this.wrapper){var b=Math.abs(a)/this.offCanvasWidth,c=1-(1-this.options.scale)*b,d=this.options.scale+(1-this.options.scale)*b,f=(1-(1-this.options.opacity)*b,this.options.opacity+(1-this.options.opacity)*b);this.offCanvas.classList.contains(e)?(this.offCanvas.style.webkitTransformOrigin="-100%",this.scroller.style.webkitTransformOrigin="left"):(this.offCanvas.style.webkitTransformOrigin="200%",this.scroller.style.webkitTransformOrigin="right"),this.offCanvas.style.opacity=f,this.offCanvas.style.webkitTransform="translate3d(0,0,0) scale("+d+")",this.scroller.style.webkitTransform="translate3d("+a+"px,0,0) scale("+c+")"}else this.slideIn?this.offCanvas.style.webkitTransform="translate3d("+a+"px,0,0)":this.scroller.style.webkitTransform="translate3d("+a+"px,0,0)"}),getTranslateX:function(){if(this.offCanvas){var b=this.slideIn?this.offCanvas:this.scroller,c=a.parseTranslateMatrix(a.getStyles(b,"webkitTransform"));return c&&c.x||0}return 0},isShown:function(a){var b=!1;if(this.slideIn)b="left"===a?this.classList.contains(j)&&this.wrapper.querySelector("."+e+"."+j):"right"===a?this.classList.contains(j)&&this.wrapper.querySelector("."+f+"."+j):this.classList.contains(j)&&(this.wrapper.querySelector("."+e+"."+j)||this.wrapper.querySelector("."+f+"."+j));else{var c=this.getTranslateX();b="right"===a?this.classList.contains(j)&&0>c:"left"===a?this.classList.contains(j)&&c>0:this.classList.contains(j)&&0!==c}return b},close:function(){this._initOffCanvasVisible(),this.offCanvas=this.wrapper.querySelector("."+f+"."+j)||this.wrapper.querySelector("."+e+"."+j),this.offCanvasWidth=this.offCanvas.offsetWidth,this.scroller&&(this.offCanvas.offsetHeight,this.offCanvas.classList.add(k),this.scroller.classList.add(k),this.openPercentage(0))},show:function(a){return this._initOffCanvasVisible(),this.isShown(a)?!1:(a||(a=this.wrapper.querySelector("."+f)?"right":"left"),"right"===a?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth),this.scroller&&(this.offCanvas.offsetHeight,this.offCanvas.classList.add(k),this.scroller.classList.add(k),this.openPercentage("left"===a?100:-100)),!0)},toggle:function(a){var b=a;a&&a.classList&&(b=a.classList.contains(e)?"left":"right",this.refresh(a)),this.show(b)||this.close()}}),n=function(a){if(parentNode=a.parentNode,parentNode){if(parentNode.classList.contains(h))return parentNode;if(parentNode=parentNode.parentNode,parentNode.classList.contains(h))return parentNode}},o=function(b,d){if("A"===d.tagName&&d.hash){var e=c.getElementById(d.hash.replace("#",""));if(e){var f=n(e);if(f)return a.targets._container=f,e}}return!1};a.registerTarget({name:d,index:60,handle:o,target:!1,isReset:!1,isContinue:!0}),b.addEventListener("tap",function(b){if(a.targets.offcanvas)for(var d=b.target;d&&d!==c;d=d.parentNode)if("A"===d.tagName&&d.hash&&d.hash==="#"+a.targets.offcanvas.id){b.detail&&b.detail.gesture&&b.detail.gesture.preventDefault(),a(a.targets._container).offCanvas().toggle(a.targets.offcanvas),a.targets.offcanvas=a.targets._container=null;break}}),a.fn.offCanvas=function(b){var c=[];return this.each(function(){var d=null,e=this;e.classList.contains(h)||(e=n(e));var f=e.getAttribute("data-offCanvas");f?d=a.data[f]:(f=++a.uuid,a.data[f]=d=new m(e,b),e.setAttribute("data-offCanvas",f)),("show"===b||"close"===b||"toggle"===b)&&d.toggle(),c.push(d)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-off-canvas-wrap").offCanvas()})}(mui,window,document,"offcanvas"),function(a,b){var c="mui-action",d=function(a,b){var d=b.className||"";return"string"!=typeof d&&(d=""),d&&~d.indexOf(c)?(b.classList.contains("mui-action-back")&&a.preventDefault(),b):!1};a.registerTarget({name:b,index:50,handle:d,target:!1,isContinue:!0})}(mui,"action"),function(a,b,c,d){var e="mui-modal",f=function(a,b){if("A"===b.tagName&&b.hash){var d=c.getElementById(b.hash.replace("#",""));if(d&&d.classList.contains(e))return d}return!1};a.registerTarget({name:d,index:50,handle:f,target:!1,isReset:!1,isContinue:!0}),b.addEventListener("tap",function(b){a.targets.modal&&(b.detail.gesture.preventDefault(),a.targets.modal.classList.toggle("mui-active"))})}(mui,window,document,"modal"),function(a,b,c,d){var e="mui-popover",f="mui-popover-arrow",g="mui-popover-action",h="mui-backdrop",i="mui-bar-popover",j="mui-bar-backdrop",k="mui-backdrop-action",l="mui-active",m="mui-bottom",n=function(b,d){if("A"===d.tagName&&d.hash){if(a.targets._popover=c.getElementById(d.hash.replace("#","")),a.targets._popover&&a.targets._popover.classList.contains(e))return d;a.targets._popover=null}return!1};a.registerTarget({name:d,index:60,handle:n,target:!1,isReset:!1,isContinue:!0});var o,p=function(a){},q=function(b){this.removeEventListener("webkitTransitionEnd",q),this.addEventListener(a.EVENT_MOVE,a.preventDefault),a.trigger(this,"shown",this)},r=function(b){v(this,"none"),this.removeEventListener("webkitTransitionEnd",r),this.removeEventListener(a.EVENT_MOVE,a.preventDefault),p(!1),a.trigger(this,"hidden",this)},s=function(){var b=c.createElement("div");return b.classList.add(h),b.addEventListener(a.EVENT_MOVE,a.preventDefault),b.addEventListener("tap",function(b){var d=a.targets._popover;d&&(d.addEventListener("webkitTransitionEnd",r),d.classList.remove(l),t(d),c.body.setAttribute("style",""))}),b}(),t=function(b){s.setAttribute("style","opacity:0"),a.targets.popover=a.targets._popover=null,o=a.later(function(){!b.classList.contains(l)&&s.parentNode&&s.parentNode===c.body&&c.body.removeChild(s)},350)};b.addEventListener("tap",function(b){if(a.targets.popover){for(var d=!1,e=b.target;e&&e!==c;e=e.parentNode)e===a.targets.popover&&(d=!0);d&&(b.detail.gesture.preventDefault(),u(a.targets._popover,a.targets.popover))}});var u=function(a,b,d){if(!("show"===d&&a.classList.contains(l)||"hide"===d&&!a.classList.contains(l))){o&&o.cancel(),a.removeEventListener("webkitTransitionEnd",q),a.removeEventListener("webkitTransitionEnd",r),s.classList.remove(j),s.classList.remove(k);var e=c.querySelector(".mui-popover.mui-active");if(e&&(e.addEventListener("webkitTransitionEnd",r),e.classList.remove(l),a===e))return void t(e);var f=!1;(a.classList.contains(i)||a.classList.contains(g))&&(a.classList.contains(g)?(f=!0,s.classList.add(k)):s.classList.add(j)),v(a,"block"),a.offsetHeight,a.classList.add(l),s.setAttribute("style",""),c.body.appendChild(s),p(!0),w(a,b,f),s.classList.add(l),a.addEventListener("webkitTransitionEnd",q)}},v=function(a,b,c,d){var e=a.style;"undefined"!=typeof b&&(e.display=b),"undefined"!=typeof c&&(e.top=c+"px"),"undefined"!=typeof d&&(e.left=d+"px")},w=function(d,e,h){if(d&&e){if(h)return void v(d,"block");var i=b.innerWidth,j=b.innerHeight,k=d.offsetWidth,l=d.offsetHeight,n=e.offsetWidth,o=e.offsetHeight,p=a.offset(e),q=d.querySelector("."+f);q||(q=c.createElement("div"),q.className=f,d.appendChild(q));var r=q&&q.offsetWidth/2||0,s=0,t=0,u=0,w=0,x=d.classList.contains(g)?0:5,y="top";l+rt&&(t=x),t+k>i&&(t=i-k-x),q&&("top"===y?q.classList.add(m):q.classList.remove(m),u-=t,w=k/2-r/2+u,w=Math.max(Math.min(w,k-2*r-6),6),q.setAttribute("style","left:"+w+"px"))):"middle"===y&&q.setAttribute("style","display:none"),v(d,"block",s,t)}};a.createMask=function(b){var d=c.createElement("div");d.classList.add(h),d.addEventListener(a.EVENT_MOVE,a.preventDefault),d.addEventListener("tap",function(){e.close()});var e=[d];return e._show=!1,e.show=function(){return e._show=!0,d.setAttribute("style","opacity:1"),c.body.appendChild(d),e},e._remove=function(){return e._show&&(e._show=!1,d.setAttribute("style","opacity:0"),a.later(function(){var a=c.body;d.parentNode===a&&a.removeChild(d)},350)),e},e.close=function(){b?b()!==!1&&e._remove():e._remove()},e},a.fn.popover=function(){var b=arguments;this.each(function(){a.targets._popover=this,("show"===b[0]||"hide"===b[0]||"toggle"===b[0])&&u(this,b[1],b[0])})}}(mui,window,document,"popover"),function(a,b,c,d,e){var f="mui-control-item",g="mui-segmented-control",h="mui-segmented-control-vertical",i="mui-control-content",j="mui-bar-tab",k="mui-tab-item",l=function(a,b){return b.classList&&(b.classList.contains(f)||b.classList.contains(k))?(b.parentNode&&b.parentNode.classList&&b.parentNode.classList.contains(h)||a.preventDefault(),b):!1};a.registerTarget({name:d,index:80,handle:l,target:!1}),b.addEventListener("tap",function(b){var e=a.targets.tab;if(e){for(var h,l,m,n="mui-active",o="."+n,p=e.parentNode;p&&p!==c;p=p.parentNode){if(p.classList.contains(g)){h=p.querySelector(o+"."+f);break}p.classList.contains(j)&&(h=p.querySelector(o+"."+k))}h&&h.classList.remove(n);var q=e===h;if(e&&e.classList.add(n),e.hash&&(m=c.getElementById(e.hash.replace("#","")))){if(!m.classList.contains(i))return void e.classList[q?"remove":"add"](n);if(!q){var r=m.parentNode;l=r.querySelectorAll("."+i+o);for(var s=0;sthis.handleX/2||!this.initialState&&a>this.handleX/2)&&(b=!0),this.lastChanged!==b&&(b?(this.handle.style.webkitTransform="translate("+(this.initialState?0:this.handleX)+"px,0)",this.classList[this.initialState?"remove":"add"](f)):(this.handle.style.webkitTransform="translate("+(this.initialState?this.handleX:0)+"px,0)",this.classList[this.initialState?"add":"remove"](f)),this.lastChanged=b)}}),a.fn["switch"]=function(b){var c=[];return this.each(function(){var b=null,d=this.getAttribute("data-switch");d?b=a.data[d]:(d=++a.uuid,a.data[d]=new k(this),this.setAttribute("data-switch",d)),c.push(b)}),c.length>1?c:c[0]},a.ready(function(){a("."+d)["switch"]()})}(mui,window,"toggle"),function(a,b,c){function d(a,b){var c=b?"removeEventListener":"addEventListener";a[c]("drag",F),a[c]("dragend",F),a[c]("swiperight",F),a[c]("swipeleft",F),a[c]("flick",F)}var e,f,g="mui-active",h="mui-selected",i="mui-grid-view",j="mui-table-view-radio",k="mui-table-view-cell",l="mui-collapse-content",m="mui-disabled",n="mui-switch",o="mui-btn",p="mui-slider-handle",q="mui-slider-left",r="mui-slider-right",s="mui-transitioning",t="."+p,u="."+q,v="."+r,w="."+h,x="."+o,y=.8,z=isOpened=openedActions=progress=!1,A=sliderActionLeft=sliderActionRight=buttonsLeft=buttonsRight=sliderDirection=sliderRequestAnimationFrame=!1,B=translateX=lastTranslateX=sliderActionLeftWidth=sliderActionRightWidth=0,C=function(a){a?f?f.classList.add(g):e&&e.classList.add(g):(B&&B.cancel(),f?f.classList.remove(g):e&&e.classList.remove(g))},D=function(){if(translateX!==lastTranslateX){if(buttonsRight&&buttonsRight.length>0){progress=translateX/sliderActionRightWidth,translateX<-sliderActionRightWidth&&(translateX=-sliderActionRightWidth-Math.pow(-translateX-sliderActionRightWidth,y));for(var a=0,b=buttonsRight.length;b>a;a++){var c=buttonsRight[a];"undefined"==typeof c._buttonOffset&&(c._buttonOffset=c.offsetLeft),buttonOffset=c._buttonOffset,E(c,translateX-buttonOffset*(1+Math.max(progress,-1)))}}if(buttonsLeft&&buttonsLeft.length>0){progress=translateX/sliderActionLeftWidth,translateX>sliderActionLeftWidth&&(translateX=sliderActionLeftWidth+Math.pow(translateX-sliderActionLeftWidth,y));for(var a=0,b=buttonsLeft.length;b>a;a++){var d=buttonsLeft[a];"undefined"==typeof d._buttonOffset&&(d._buttonOffset=sliderActionLeftWidth-d.offsetLeft-d.offsetWidth),buttonOffset=d._buttonOffset,buttonsLeft.length>1&&(d.style.zIndex=buttonsLeft.length-a),E(d,translateX+buttonOffset*(1-Math.min(progress,1)))}}E(A,translateX),lastTranslateX=translateX}sliderRequestAnimationFrame=requestAnimationFrame(function(){D()})},E=function(a,b){a&&(a.style.webkitTransform="translate("+b+"px,0)")};b.addEventListener(a.EVENT_START,function(b){e&&C(!1),e=f=!1,z=isOpened=openedActions=!1;for(var g=b.target,h=!1;g&&g!==c;g=g.parentNode)if(g.classList){var p=g.classList;if(("INPUT"===g.tagName&&"radio"!==g.type&&"checkbox"!==g.type||"BUTTON"===g.tagName||p.contains(n)||p.contains(o)||p.contains(m))&&(h=!0),p.contains(l))break;if(p.contains(k)){e=g;var q=e.parentNode.querySelector(w);if(!e.parentNode.classList.contains(j)&&q&&q!==e)return a.swipeoutClose(q),void(e=h=!1);if(!e.parentNode.classList.contains(i)){var r=e.querySelector("a");r&&r.parentNode===e&&(f=r)}var s=e.querySelector(t);s&&(d(e),b.stopPropagation()),h||(s?(B&&B.cancel(),B=a.later(function(){C(!0)},100)):C(!0));break}}}),b.addEventListener(a.EVENT_MOVE,function(a){C(!1)});var F={handleEvent:function(a){switch(a.type){case"drag":this.drag(a);break;case"dragend":this.dragend(a);break;case"flick":this.flick(a);break;case"swiperight":this.swiperight(a);break;case"swipeleft":this.swipeleft(a)}},drag:function(a){if(e){z||(A=sliderActionLeft=sliderActionRight=buttonsLeft=buttonsRight=sliderDirection=sliderRequestAnimationFrame=!1,A=e.querySelector(t),A&&(sliderActionLeft=e.querySelector(u), +sliderActionRight=e.querySelector(v),sliderActionLeft&&(sliderActionLeftWidth=sliderActionLeft.offsetWidth,buttonsLeft=sliderActionLeft.querySelectorAll(x)),sliderActionRight&&(sliderActionRightWidth=sliderActionRight.offsetWidth,buttonsRight=sliderActionRight.querySelectorAll(x)),e.classList.remove(s),isOpened=e.classList.contains(h),isOpened&&(openedActions=e.querySelector(u+w)?"left":"right")));var b=a.detail,c=b.direction,d=b.angle;if("left"===c&&(d>150||-150>d)?(buttonsRight||buttonsLeft&&isOpened)&&(z=!0):"right"===c&&d>-30&&30>d&&(buttonsLeft||buttonsRight&&isOpened)&&(z=!0),z){a.stopPropagation(),a.detail.gesture.preventDefault();var f=a.detail.deltaX;if(isOpened&&("right"===openedActions?f-=sliderActionRightWidth:f+=sliderActionLeftWidth),f>0&&!buttonsLeft||0>f&&!buttonsRight){if(!isOpened)return;f=0}0>f?sliderDirection="toLeft":f>0?sliderDirection="toRight":sliderDirection||(sliderDirection="toLeft"),sliderRequestAnimationFrame||D(),translateX=f}}},flick:function(a){z&&a.stopPropagation()},swipeleft:function(a){z&&a.stopPropagation()},swiperight:function(a){z&&a.stopPropagation()},dragend:function(b){if(z){b.stopPropagation(),sliderRequestAnimationFrame&&(cancelAnimationFrame(sliderRequestAnimationFrame),sliderRequestAnimationFrame=null);var c=b.detail;z=!1;var d="close",f="toLeft"===sliderDirection?sliderActionRightWidth:sliderActionLeftWidth,g=c.swipe||Math.abs(translateX)>f/2;g&&(isOpened?"left"===c.direction&&"right"===openedActions?d="open":"right"===c.direction&&"left"===openedActions&&(d="open"):d="open"),e.classList.add(s);var i;if("open"===d){var j="toLeft"===sliderDirection?-f:f;if(E(A,j),i="toLeft"===sliderDirection?buttonsRight:buttonsLeft,"undefined"!=typeof i){for(var k=null,l=0;l0&&buttonsLeft!==i)for(var l=0,n=buttonsLeft.length;n>l;l++){var o=buttonsLeft[l];m=o._buttonOffset,"undefined"==typeof m&&(o._buttonOffset=sliderActionLeftWidth-o.offsetLeft-o.offsetWidth),E(o,m)}if(buttonsRight&&buttonsRight.length>0&&buttonsRight!==i)for(var l=0,n=buttonsRight.length;n>l;l++){var p=buttonsRight[l];m=p._buttonOffset,"undefined"==typeof m&&(p._buttonOffset=p.offsetLeft),E(p,-m)}}}};a.swipeoutOpen=function(b,c){if(b){var d=b.classList;if(!d.contains(h)){c||(c=b.querySelector(v)?"right":"left");var e=b.querySelector(a.classSelector(".slider-"+c));if(e){e.classList.add(h),d.add(h),d.remove(s);for(var f,g=e.querySelectorAll(x),i=e.offsetWidth,j="right"===c?-i:i,k=g.length,l=0;k>l;l++)f=g[l],"right"===c?E(f,-f.offsetLeft):E(f,i-f.offsetWidth-f.offsetLeft);d.add(s);for(var l=0;k>l;l++)E(g[l],j);E(b.querySelector(t),j)}}}},a.swipeoutClose=function(b){if(b){var c=b.classList;if(c.contains(h)){var d=b.querySelector(v+w)?"right":"left",e=b.querySelector(a.classSelector(".slider-"+d));if(e){e.classList.remove(h),c.remove(h),c.add(s);var f,g=e.querySelectorAll(x),i=e.offsetWidth,j=g.length;E(b.querySelector(t),0);for(var k=0;j>k;k++)f=g[k],"right"===d?E(f,-f.offsetLeft):E(f,i-f.offsetWidth-f.offsetLeft)}}}},b.addEventListener(a.EVENT_END,function(a){e&&(C(!1),A&&d(e,!0))}),b.addEventListener(a.EVENT_CANCEL,function(a){e&&(C(!1),A&&d(e,!0))});var G=function(b){var c=b.target&&b.target.type||"";if("radio"!==c&&"checkbox"!==c){var d=e.classList;if(d.contains("mui-radio")){var f=e.querySelector("input[type=radio]");f&&(f.disabled||f.readOnly||(f.checked=!f.checked,a.trigger(f,"change")))}else if(d.contains("mui-checkbox")){var f=e.querySelector("input[type=checkbox]");f&&(f.disabled||f.readOnly||(f.checked=!f.checked,a.trigger(f,"change")))}}};b.addEventListener(a.EVENT_CLICK,function(a){e&&e.classList.contains("mui-collapse")&&a.preventDefault()}),b.addEventListener("doubletap",function(a){e&&G(a)});var H=/^(INPUT|TEXTAREA|BUTTON|SELECT)$/;b.addEventListener("tap",function(b){if(e){var c=!1,d=e.classList,f=e.parentNode;if(f&&f.classList.contains(j)){if(d.contains(h))return;var i=f.querySelector("li"+w);return i&&i.classList.remove(h),d.add(h),void a.trigger(e,"selected",{el:e})}if(d.contains("mui-collapse")&&!e.parentNode.classList.contains("mui-unfold")){if(H.test(b.target.tagName)||b.detail.gesture.preventDefault(),!d.contains(g)){var k=e.parentNode.querySelector(".mui-collapse.mui-active");k&&k.classList.remove(g),c=!0}d.toggle(g),c&&a.trigger(e,"expand")}else G(b)}})}(mui,window,document),function(a,b){a.alert=function(c,d,e,f){if(a.os.plus){if("undefined"==typeof c)return;"function"==typeof d?(f=d,d=null,e="确定"):"function"==typeof e&&(f=e,e=null),a.plusReady(function(){plus.nativeUI.alert(c,f,d,e)})}else b.alert(c)}}(mui,window),function(a,b){a.confirm=function(c,d,e,f){if(a.os.plus){if("undefined"==typeof c)return;"function"==typeof d?(f=d,d=null,e=null):"function"==typeof e&&(f=e,e=null),a.plusReady(function(){plus.nativeUI.confirm(c,f,d,e)})}else f(b.confirm(c)?{index:0}:{index:1})}}(mui,window),function(a,b){a.prompt=function(c,d,e,f,g){if(a.os.plus){if("undefined"==typeof message)return;"function"==typeof d?(g=d,d=null,e=null,f=null):"function"==typeof e?(g=e,e=null,f=null):"function"==typeof f&&(g=f,f=null),a.plusReady(function(){plus.nativeUI.prompt(c,g,e,d,f)})}else{var h=b.prompt(c);g(h?{index:0,value:h}:{index:1,value:""})}}}(mui,window),function(a,b){var c="mui-active";a.toast=function(b){if(a.os.plus)a.plusReady(function(){plus.nativeUI.toast(b,{verticalAlign:"bottom"})});else{var d=document.createElement("div");d.classList.add("mui-toast-container"),d.innerHTML='
'+b+"
",d.addEventListener("webkitTransitionEnd",function(){d.classList.contains(c)||d.parentNode.removeChild(d)}),document.body.appendChild(d),d.offsetHeight,d.classList.add(c),setTimeout(function(){d.classList.remove(c)},2e3)}}}(mui,window),function(a,b,c){var d="mui-popup",e="mui-popup-backdrop",f="mui-popup-in",g="mui-popup-out",h="mui-popup-inner",i="mui-popup-title",j="mui-popup-text",k="mui-popup-input",l="mui-popup-buttons",m="mui-popup-button",n="mui-popup-button-bold",e="mui-popup-backdrop",o="mui-active",p=[],q=function(){var b=c.createElement("div");return b.classList.add(e),b.addEventListener(a.EVENT_MOVE,a.preventDefault),b.addEventListener("webkitTransitionEnd",function(){this.classList.contains(o)||b.parentNode&&b.parentNode.removeChild(b)}),b}(),r=function(a){return'
'},s=function(a,b,c){return'
'+b+'
'+a.replace(/\r\n/g,"
").replace(/\n/g,"
")+"
"+(c||"")+"
"},t=function(a){for(var b=a.length,c=[],d=0;b>d;d++)c.push(''+a[d]+"");return'
'+c.join("")+"
"},u=function(b,e){var h=c.createElement("div");h.className=d,h.innerHTML=b;var i=function(){h.parentNode&&h.parentNode.removeChild(h),h=null};h.addEventListener(a.EVENT_MOVE,a.preventDefault),h.addEventListener("webkitTransitionEnd",function(a){h&&a.target===h&&h.classList.contains(g)&&i()}),h.style.display="block",c.body.appendChild(h),h.offsetHeight,h.classList.add(f),q.classList.contains(o)||(q.style.display="block",c.body.appendChild(q),q.offsetHeight,q.classList.add(o));var j=a.qsa("."+m,h),l=h.querySelector("."+k+" input"),n={element:h,close:function(a,b){h&&(e&&e({index:a||0,value:l&&l.value||""}),b!==!1?(h.classList.remove(f),h.classList.add(g)):i(),p.pop(),p.length?p[p.length-1].show(b):q.classList.remove(o))}},r=function(a){n.close(j.indexOf(a.target))};return a(h).on("tap","."+m,r),p.length&&p[p.length-1].hide(),p.push({close:n.close,show:function(a){h.style.display="block",h.offsetHeight,h.classList.add(f)},hide:function(){h.style.display="none",h.classList.remove(f)}}),n},v=function(b,c,d,e,f){return"undefined"!=typeof b?("function"==typeof c?(e=c,f=d,c=null,d=null):"function"==typeof d&&(f=e,e=d,d=null),a.os.plus&&"div"!==f?plus.nativeUI.alert(b,e,c||"提示",d||"确定"):u(s(b,c||"提示")+t([d||"确定"]),e)):void 0},w=function(b,c,d,e,f){return"undefined"!=typeof b?("function"==typeof c?(e=c,f=d,c=null,d=null):"function"==typeof d&&(f=e,e=d,d=null),a.os.plus&&"div"!==f?plus.nativeUI.confirm(b,e,c,d||["取消","确认"]):u(s(b,c||"提示")+t(d||["取消","确认"]),e)):void 0},x=function(b,c,d,e,f,g){return"undefined"!=typeof b?("function"==typeof c?(f=c,g=d,c=null,d=null,e=null):"function"==typeof d?(f=d,g=e,d=null,e=null):"function"==typeof e&&(g=f,f=e,e=null),a.os.plus&&"div"!==g?plus.nativeUI.prompt(b,f,d||"提示",c,e||["取消","确认"]):u(s(b,d||"提示",r(c))+t(e||["取消","确认"]),f)):void 0},y=function(){return p.length?(p[p.length-1].close(),!0):!1},z=function(){for(;p.length;)p[p.length-1].close()};a.closePopup=y,a.closePopups=z,a.alert=v,a.confirm=w,a.prompt=x}(mui,window,document),function(a,b){var c="mui-progressbar",d="mui-progressbar-in",e="mui-progressbar-out",f="mui-progressbar-infinite",g=".mui-progressbar",h=function(b){if(b=a(b||"body"),0!==b.length){if(b=b[0],b.classList.contains(c))return b;var d=b.querySelectorAll(g);if(d)for(var e=0,f=d.length;f>e;e++){var h=d[e];if(h.parentNode===b)return h}}},i=function(h,i,j){if("number"==typeof h&&(j=i,i=h,h="body"),h=a(h||"body"),0!==h.length){h=h[0];var l;if(h.classList.contains(c))l=h;else{var m=h.querySelectorAll(g+":not(."+e+")");if(m)for(var n=0,o=m.length;o>n;n++){var p=m[n];if(p.parentNode===h){l=p;break}}l?l.classList.add(d):(l=b.createElement("span"),l.className=c+" "+d+("undefined"!=typeof i?"":" "+f)+(j?" "+c+"-"+j:""),"undefined"!=typeof i&&(l.innerHTML=""),h.appendChild(l))}return i&&k(h,i),l}},j=function(a){var b=h(a);if(b){var c=b.classList;c.contains(d)&&!c.contains(e)&&(c.remove(d),c.add(e),b.addEventListener("webkitAnimationEnd",function(){b.parentNode&&b.parentNode.removeChild(b),b=null}))}},k=function(a,b,c){"number"==typeof a&&(c=b,b=a,a=!1);var d=h(a);if(d&&!d.classList.contains(f)){b&&(b=Math.min(Math.max(b,0),100)),d.offsetHeight;var e=d.querySelector("span");if(e){var g=e.style;g.webkitTransform="translate3d("+(-100+b)+"%,0,0)","undefined"!=typeof c?g.webkitTransitionDuration=c+"ms":g.webkitTransitionDuration=""}return d}};a.fn.progressbar=function(a){var b=[];return a=a||{},this.each(function(){var c=this,d=c.mui_plugin_progressbar;d?a&&d.setOptions(a):c.mui_plugin_progressbar=d={options:a,setOptions:function(a){this.options=a},show:function(){return i(c,this.options.progress,this.options.color)},setProgress:function(a){return k(c,a)},hide:function(){return j(c)}},b.push(d)}),1===b.length?b[0]:b}}(mui,document),function(a,b,c){var d="mui-icon",e="mui-icon-clear",f="mui-icon-speech",g="mui-icon-search",h="mui-icon-eye",i="mui-input-row",j="mui-placeholder",k="mui-tooltip",l="mui-hidden",m="mui-focusin",n="."+e,o="."+f,p="."+h,q="."+j,r="."+k,s=function(a){for(;a&&a!==c;a=a.parentNode)if(a.classList&&a.classList.contains(i))return a;return null},t=function(a,b){this.element=a,this.options=b||{actions:"clear"},~this.options.actions.indexOf("slider")?(this.sliderActionClass=k+" "+l,this.sliderActionSelector=r):(~this.options.actions.indexOf("clear")&&(this.clearActionClass=d+" "+e+" "+l,this.clearActionSelector=n),~this.options.actions.indexOf("speech")&&(this.speechActionClass=d+" "+f,this.speechActionSelector=o),~this.options.actions.indexOf("search")&&(this.searchActionClass=j,this.searchActionSelector=q),~this.options.actions.indexOf("password")&&(this.passwordActionClass=d+" "+h,this.passwordActionSelector=p)),this.init()};t.prototype.init=function(){this.initAction(),this.initElementEvent()},t.prototype.initAction=function(){var b=this,c=b.element.parentNode;c&&(b.sliderActionClass?b.sliderAction=b.createAction(c,b.sliderActionClass,b.sliderActionSelector):(b.searchActionClass&&(b.searchAction=b.createAction(c,b.searchActionClass,b.searchActionSelector),b.searchAction.addEventListener("tap",function(c){a.focus(b.element),c.stopPropagation()})),b.speechActionClass&&(b.speechAction=b.createAction(c,b.speechActionClass,b.speechActionSelector),b.speechAction.addEventListener("click",a.stopPropagation),b.speechAction.addEventListener("tap",function(a){b.speechActionClick(a)})),b.clearActionClass&&(b.clearAction=b.createAction(c,b.clearActionClass,b.clearActionSelector),b.clearAction.addEventListener("tap",function(a){b.clearActionClick(a)})),b.passwordActionClass&&(b.passwordAction=b.createAction(c,b.passwordActionClass,b.passwordActionSelector),b.passwordAction.addEventListener("tap",function(a){b.passwordActionClick(a)}))))},t.prototype.createAction=function(a,b,e){var f=a.querySelector(e);if(!f){var f=c.createElement("span");f.className=b,b===this.searchActionClass&&(f.innerHTML=''+this.element.getAttribute("placeholder")+"",this.element.setAttribute("placeholder",""),this.element.value.trim()&&a.classList.add("mui-active")),a.insertBefore(f,this.element.nextSibling)}return f},t.prototype.initElementEvent=function(){var b=this.element;if(this.sliderActionClass){var c=this.sliderAction,d=null,e=function(){c.classList.remove(l);var a=b.offsetLeft,e=b.offsetWidth-28,f=c.offsetWidth,g=Math.abs(b.max-b.min),h=e/g*Math.abs(b.value-b.min);c.style.left=14+a+h-f/2+"px",c.innerText=b.value,d&&clearTimeout(d),d=setTimeout(function(){c.classList.add(l)},1e3)};b.addEventListener("input",e),b.addEventListener("tap",e),b.addEventListener(a.EVENT_MOVE,function(a){a.stopPropagation()})}else{if(this.clearActionClass){var f=this.clearAction;if(!f)return;a.each(["keyup","change","input","focus","cut","paste"],function(a,c){!function(a){b.addEventListener(a,function(){f.classList[b.value.trim()?"remove":"add"](l)})}(c)}),b.addEventListener("blur",function(){f.classList.add(l)})}this.searchActionClass&&(b.addEventListener("focus",function(){b.parentNode.classList.add("mui-active")}),b.addEventListener("blur",function(){b.value.trim()||b.parentNode.classList.remove("mui-active")}))}},t.prototype.setPlaceholder=function(a){if(this.searchActionClass){var b=this.element.parentNode.querySelector(q);b&&(b.getElementsByTagName("span")[1].innerText=a)}else this.element.setAttribute("placeholder",a)},t.prototype.passwordActionClick=function(a){"text"===this.element.type?this.element.type="password":this.element.type="text",this.passwordAction.classList.toggle("mui-active"),a.preventDefault()},t.prototype.clearActionClick=function(b){var c=this;c.element.value="",a.focus(c.element),c.clearAction.classList.add(l),b.preventDefault()},t.prototype.speechActionClick=function(d){if(b.plus){var e=this,f=e.element.value;e.element.value="",c.body.classList.add(m),plus.speech.startRecognize({engine:"iFly"},function(b){e.element.value+=b,a.focus(e.element),plus.speech.stopRecognize(),a.trigger(e.element,"recognized",{value:e.element.value}),f!==e.element.value&&(a.trigger(e.element,"change"),a.trigger(e.element,"input"))},function(a){c.body.classList.remove(m)})}else alert("only for 5+");d.preventDefault()},a.fn.input=function(b){var c=[];return this.each(function(){var b=null,d=[],e=s(this.parentNode);if("range"===this.type&&e.classList.contains("mui-input-range"))d.push("slider");else{var f=this.classList;f.contains("mui-input-clear")&&d.push("clear"),a.os.android&&a.os.stream||!f.contains("mui-input-speech")||d.push("speech"),f.contains("mui-input-password")&&d.push("password"),"search"===this.type&&e.classList.contains("mui-search")&&d.push("search")}var g=this.getAttribute("data-input-"+d[0]);if(g)b=a.data[g];else{g=++a.uuid,b=a.data[g]=new t(this,{actions:d.join(",")});for(var h=0,i=d.length;i>h;h++)this.setAttribute("data-input-"+d[h],g)}c.push(b)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-input-row input").input()})}(mui,window,document),function(a,b){var c=/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,d=function(a){var b=a.match(c);return b&&5===b.length?[b[1],b[2],b[3],b[4]]:[]},e=function(b,c){this.element=b,this.options=a.extend({top:0,offset:150,duration:16},c||{}),this._style=this.element.style,this._bgColor=this._style.backgroundColor;var e=d(mui.getStyles(this.element,"backgroundColor"));if(!e.length)throw new Error("元素背景颜色必须为RGBA");this._R=e[0],this._G=e[1],this._B=e[2],this._A=e[3],this._bufferFn=a.buffer(this.handleScroll,this.options.duration,this),this.initEvent()};e.prototype.initEvent=function(){b.addEventListener("scroll",this._bufferFn),b.addEventListener(a.EVENT_MOVE,this._bufferFn)},e.prototype.handleScroll=function(){this._style.backgroundColor="rgba("+this._R+","+this._G+","+this._B+","+(b.scrollY-this.options.top)/this.options.offset+")"},e.prototype.destory=function(){b.removeEventListener("scroll",this._bufferFn),b.removeEventListener(a.EVENT_MOVE,this._bufferFn),this.element.style.backgroundColor=this._bgColor,this.element.mui_plugin_transparent=null},a.fn.transparent=function(a){a=a||{};var b=[];return this.each(function(){var c=this.mui_plugin_transparent;if(!c){var d=this.getAttribute("data-top"),f=this.getAttribute("data-offset"),g=this.getAttribute("data-duration");null!==d&&"undefined"==typeof a.top&&(a.top=d),null!==f&&"undefined"==typeof a.offset&&(a.offset=f),null!==g&&"undefined"==typeof a.duration&&(a.duration=g),c=this.mui_plugin_transparent=new e(this,a)}b.push(c)}),1===b.length?b[0]:b},a.ready(function(){a(".mui-bar-transparent").transparent()})}(mui,window),function(a){var b="ontouchstart"in document,c=b?"tap":"click",d="change",e="mui-numbox",f=".mui-btn-numbox-plus,.mui-numbox-btn-plus",g=".mui-btn-numbox-minus,.mui-numbox-btn-minus",h=".mui-input-numbox,.mui-numbox-input",i=a.Numbox=a.Class.extend({init:function(b,c){var d=this;if(!b)throw"构造 numbox 时缺少容器元素";d.holder=b,c=c||{},c.step=parseInt(c.step||1),d.options=c,d.input=a.qsa(h,d.holder)[0],d.plus=a.qsa(f,d.holder)[0],d.minus=a.qsa(g,d.holder)[0],d.checkValue(),d.initEvent()},initEvent:function(){var b=this;b.plus.addEventListener(c,function(c){var e=parseInt(b.input.value)+b.options.step;b.input.value=e.toString(),a.trigger(b.input,d,null)}),b.minus.addEventListener(c,function(c){var e=parseInt(b.input.value)-b.options.step;b.input.value=e.toString(),a.trigger(b.input,d,null)}),b.input.addEventListener(d,function(c){b.checkValue();var e=parseInt(b.input.value);a.trigger(b.holder,d,{value:e})})},getValue:function(){var a=this;return parseInt(a.input.value)},checkValue:function(){var a=this,b=a.input.value;if(null==b||""==b||isNaN(b))a.input.value=a.options.min||0,a.minus.disabled=null!=a.options.min;else{var b=parseInt(b);null!=a.options.max&&!isNaN(a.options.max)&&b>=parseInt(a.options.max)?(b=a.options.max,a.plus.disabled=!0):a.plus.disabled=!1,null!=a.options.min&&!isNaN(a.options.min)&&b<=parseInt(a.options.min)?(b=a.options.min,a.minus.disabled=!0):a.minus.disabled=!1,a.input.value=b}},setOption:function(a,b){var c=this;c.options[a]=b}});a.fn.numbox=function(a){return this.each(function(a,b){if(!b.numbox)if(d)b.numbox=new i(b,d);else{var c=b.getAttribute("data-numbox-options"),d=c?JSON.parse(c):{};d.step=b.getAttribute("data-numbox-step")||d.step,d.min=b.getAttribute("data-numbox-min")||d.min,d.max=b.getAttribute("data-numbox-max")||d.max,b.numbox=new i(b,d)}}),this[0]?this[0].numbox:null},a.ready(function(){a("."+e).numbox()})}(mui); \ No newline at end of file diff --git a/application/wap/view/first/static/wap/bargain/js/FJL.picker.min.js b/application/wap/view/first/static/wap/bargain/js/FJL.picker.min.js new file mode 100644 index 00000000..458d1c99 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/js/FJL.picker.min.js @@ -0,0 +1 @@ +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('!f(e,t,i,n){g a=30,r=4X,s=40,c=10,l=e.4d=f(e){x e/(1A.3T/2v)},o=(e.4h=f(e){x e*(1A.3T/2v)},3R.4j.3P()),d=3R.4l.3P(),u=(d.1n("3Q")>-1||d.1n("3X")>-1||d.1n("3W")>-1)&&(o.1n("3Q")>-1||o.1n("3X")>-1||o.1n("3W")>-1),p=e.4v=f(e,t){g i=j;i.17=e,i.z=t||{},i.26(),i.3y(),i.2M(!0),i.3i()};p.H.2B=f(){g e=j;x e.1q=[].1J.1I(e.17.4t("2A")),e.1q},p.H.26=f(){g e=j;e.D=e.17.2j("P"),e.2B(),e.3U=e.17.3O,e.r=e.3U/2-c,e.d=2*e.r,e.3H=e.1q.25>0?e.1q[0].3O:s,e.1t=N(e.22(.8*e.3H)),e.3K=e.1t/2,e.47=r,e.1h=0,e.1B=e.1h-a,e.D.O=e.1h,u&&(e.D.14.3E="2b 2b "+e.r+"2t")},p.H.2M=f(e){g t=j;e&&(t.U=[]),t.1q.2C(f(i){g n=t.1q.1n(i);J(t.1f=t.1t*n,i.O=t.1f,i.14.3E="2b 2b -"+t.r+"2t",i.14.41="4s("+t.r+"2t) 3f("+-t.1f+"3d)",e){g a={};a.C=i.2h||"",a.A=i.3b("F-A")||a.C,t.U.18(a)}}),t.1x=t.1f+a,t.2p(t.1h)},p.H.22=f(e){g t=j,i=b=4r(t.r);e=1A.2E(e);g n=2v*N(e/t.d);e%=t.d;g a=(i*i+b*b-e*e)/(2*i*b),r=n+l(1A.4q(a));x r},p.H.2p=f(e){g t=j;t.1q.2C(f(i){g n=1A.2E(i.O-e);n0?i-c:i+c;l>t.1x&&(l=t.1x),l2S&&(i.1Q=a,i.24=n.1T)}i.20=!0},p.H.2L=f(e){g t=j,i=e.1m?e.1m[0]:e,n=e.2K||1e.2i(),a=(i.1T-t.24)/(n-t.1Q),r=a>0?-1:1,s=4u-4*r*-1,c=1A.2E(a/s),l=a*c/2,o=t.D.O,d=t.22(l)*r,u=d;x o+dt.1x&&(d=t.1x-o,c=c*(d/u)*.6),0==d?1D t.2u():1D t.2I(n,o,d,c)},p.H.2I=f(e,t,i,n){g a=j;a.20=!1,f(e,t,i,n){g r=13,s=n/r,c=0;!f l(){J(!a.20){g e=a.3u(c,t,i,s);x a.1b(e),c++,c>s-1||ea.1x?1D a.2u():1D 2f(l,r)}}()}(e,t,i,n)},p.H.3u=f(e,t,i,n){x-i*((e=e/n-1)*e*e*e-1)+t},p.H.2u=f(){g e=j;J(e.D.Oe.1f)e.D.14.1Y="3v 2D-2F",e.1b(e.1f);X{g t=N((e.D.O/e.1t).3B(0));e.D.14.1Y="4Q 2D-2F",e.1b(e.1t*t)}e.2l()},p.H.2l=f(t){g i=j;2f(f(){g n=i.1K(),a=i.U[n];!e.3q||n==i.3r&&t!==!0||e.3q(i.17,"1C",{4R:n,3h:a}),i.3r=n,"f"==2z t&&t()},0)},p.H.2H=f(e){g t=j;x et.1f?t.1f:e},p.H.19=f(e){g t=j;t.U=e||[];g i=[];t.U.2C(f(e){1Z!==e&&e!==n&&i.18("<2A>"+(e.C||e)+"")}),t.D.2h=i.4S(""),t.2B(),t.2M(),t.1b(t.2H(t.D.O)),t.2l(!0)},p.H.51=f(){g e=j;x e.U},p.H.1K=f(){g e=j;x N((e.D.O/e.1t).3B(0))},p.H.2q=f(e,t,i){g n=j;n.D.14.1Y="";g a=n.2H(n.1t*e);J(t&&t>0){g r=a-n.D.O;n.2I(1e.2i(),n.D.O,r,t)}X n.1b(a);n.2l(i)},p.H.1s=f(){g e=j;x e.U[e.1K()]},p.H.S=f(){g e=j;x(e.U[e.1K()]||{}).A},p.H.4E=f(){g e=j;x(e.U[e.1K()]||{}).C},p.H.1o=f(e,t,i){g n=j;L(g a 1R n.U){g r=n.U[a];J(r.A==e)x 1D n.2q(a,t,i)}},e.3a&&(e.3a.k=f(e){x j.4b(f(t,i){J(!i.k)J(e)i.k=2k p(i,e);X{g n=i.3b("F-k-z"),a=n?4H.4G(n):{};i.k=2k p(i,a)}}),j[0]?j[0].k:1Z},e.4A(f(){e(".v-k").k()}))}(2y.v||2y,2y,2w,1D 0),f(e,t){e.1N=f(i){x"46"!=2z i?i 2e 42||i[0]&&i.25?[].1J.1I(i):[i]:(e.1g||(e.1g=t.4c("q")),e.1g.2h=i,[].1J.1I(e.1g.4a))};g i=\' <1a w="v-M v-W-M-15">2m <1a w="v-M v-M-3Z v-W-M-Z">2n \',n=\'

\';e.4C=e.3M.3F({26:f(n){g a=j;a.z=n||{},a.z.1j=a.z.1j||["2m","2n"],a.Y=e.1N(i)[0],t.V.2r(a.Y),a.Z=a.Y.2j(".v-W-M-Z"),a.15=a.Y.2j(".v-W-M-15"),a.V=a.Y.2j(".v-W-V"),a.1l=e.3G(),a.15.1O=a.z.1j[0],a.Z.1O=a.z.1j[1],a.15.K("1v",f(e){a.R()},!1),a.Z.K("1v",f(e){J(a.1U){g t=a.1U(a.3g());t!==!1&&a.R()}},!1),a.1l[0].K("1v",f(){a.R()},!1),a.3m(),a.Y.K(e.2x,f(e){e.1p()},!1),a.Y.K(e.2s,f(e){e.1p()},!1)},3m:f(){g t=j,i=t.z.4N||1,a=3S/i+"%";t.1P=[];L(g r=1;i>=r;r++){g s=e.1N(n)[0];s.14.4M=a,t.V.2r(s);g c=e(s).k();t.1P.18(c),s.K("1C",f(e){g t=j.4P;J(t&&t.k){g i=e.4O||{},n=i.3h||{};t.k.19(n.4J)}},!1)}},4T:f(e){g t=j;e=e||[],t.1P[0].19(e)},3g:f(){g e=j,t=[];L(g i 1R e.1P){g n=e.1P[i];t.18(n.1s()||{})}x t},2d:f(i){g n=j;n.1U=i,n.1l.2d(),t.V.Q.1F(e.1k("W-1i-L-2c")),n.Y.Q.1F(e.1k("1i")),n.2g=e.1H,e.1H=f(){n.R()}},R:f(){g i=j;i.27||(i.Y.Q.1r(e.1k("1i")),i.1l.3C(),t.V.Q.1r(e.1k("W-1i-L-2c")),e.1H=i.2g)},3k:f(){g e=j;e.R(),2f(f(){e.Y.3j.3l(e.Y);L(g t 1R e)e[t]=1Z,3e e[t];e.27=!0},2S)}})}(v,2w),f(e,t){e.1N=f(i){x"46"!=2z i?i 2e 42||i[0]&&i.25?[].1J.1I(i):[i]:(e.1g||(e.1g=t.4c("q")),e.1g.2h=i,[].1J.1I(e.1g.4a))};g i=\' <1a F-I="M-15" w="v-M">2m <1a F-I="M-Z" w="v-M v-M-3Z">2n <16 F-I="1u-y">3c<16 F-I="1u-m">39<16 F-I="1u-d">3o<16 F-I="1u-h">3z<16 F-I="1u-i">3x

\';e.4I=e.3M.3F({26:f(n){g a=j,r=e.1N(i)[0];t.V.2r(r),e(\'[F-I*="k"]\',r).k();g s=a.E={k:r,1l:e.3G(),Z:e(\'[F-I="M-Z"]\',r)[0],15:e(\'[F-I="M-15"]\',r)[0],y:e(\'[F-I="k-y"]\',r)[0],m:e(\'[F-I="k-m"]\',r)[0],d:e(\'[F-I="k-d"]\',r)[0],h:e(\'[F-I="k-h"]\',r)[0],i:e(\'[F-I="k-i"]\',r)[0],1M:e(\'[F-I*="1u-"]\',r)};s.15.K("1v",f(){a.R()},!1),s.Z.K("1v",f(){g e=a.1U(a.3Y());e!==!1&&a.R()},!1),s.y.K("1C",f(e){a.z.1c||a.z.1d?a.37():a.21()},!1),s.m.K("1C",f(e){a.21()},!1),s.d.K("1C",f(e){(a.z.1c||a.z.1d)&&a.2N()},!1),s.h.K("1C",f(e){(a.z.1c||a.z.1d)&&a.2W()},!1),s.1l[0].K("1v",f(){a.R()},!1),a.3n(n),a.E.k.K(e.2x,f(e){e.1p()},!1),a.E.k.K(e.2s,f(e){e.1p()},!1)},3Y:f(){g e=j,t=e.E,i=e.z.1w,n={1w:i,y:t.y.k.1s(),m:t.m.k.1s(),d:t.d.k.1s(),h:t.h.k.1s(),i:t.i.k.1s(),3I:f(){x j.A}};4B(i){1S"2X":n.A=n.y.A+"-"+n.m.A+"-"+n.d.A+" "+n.h.A+":"+n.i.A,n.C=n.y.C+"-"+n.m.C+"-"+n.d.C+" "+n.h.C+":"+n.i.C;2a;1S"4F":n.A=n.y.A+"-"+n.m.A+"-"+n.d.A,n.C=n.y.C+"-"+n.m.C+"-"+n.d.C;2a;1S"4Z":n.A=n.h.A+":"+n.i.A,n.C=n.h.C+":"+n.i.C;2a;1S"4W":n.A=n.y.A+"-"+n.m.A,n.C=n.y.C+"-"+n.m.C;2a;1S"4V":n.A=n.y.A+"-"+n.m.A+"-"+n.d.A+" "+n.h.A,n.C=n.y.C+"-"+n.m.C+"-"+n.d.C+" "+n.h.C}x n},1o:f(e){g t=j,i=t.E,n=t.43(e);i.y.k.1o(n.y,0,f(){i.m.k.1o(n.m,0,f(){i.d.k.1o(n.d,0,f(){i.h.k.1o(n.h,0,f(){i.i.k.1o(n.i,0)})})})})},3V:f(e){x e%4==0&&e%3S!=0||e%4U==0},2Q:f(e,t){L(g i 1R e){g n=e[i];J(n===t)x!0}x!1},48:f(e,t){g i=j;x i.2Q([1,3,5,7,8,10,12],t)?31:i.2Q([4,6,9,11],t)?30:i.3V(e)?29:28},1L:f(e){x e=e.3I(),e.25<2&&(e=0+e),e},2T:f(){x j.z.1V===N(j.E.y.k.S())},36:f(){x j.z.1c&&j.2T()&&j.z.1c===N(j.E.m.k.S())},2Z:f(){x j.36()&&j.z.33===N(j.E.d.k.S())},3L:f(){x j.2Z()&&j.z.2V===N(j.E.h.k.S())},2U:f(){x j.z.1W===N(j.E.y.k.S())},38:f(){x j.z.1d&&j.2U()&&j.z.1d===N(j.E.m.k.S())},34:f(){x j.38()&&j.z.2P===N(j.E.d.k.S())},3J:f(){x j.34()&&j.z.2Y===N(j.E.h.k.S())},3s:f(e){g t=j,i=t.z,n=t.E,a=[];J(i.T.y)a=i.T.y;X L(g r=i.1V,s=i.1W,c=r;s>=c;c++)a.18({C:c+"",A:c});n.y.k.19(a)},37:f(e){g t=j,i=t.z,n=t.E,a=[];J(i.T.m)a=i.T.m;X L(g r=i.1c&&t.2T()?i.1c:1,s=i.1d&&t.2U()?i.1d:12;s>=r;r++){g c=t.1L(r);a.18({C:c,A:c})}n.m.k.19(a)},21:f(e){g t=j,i=t.z,n=t.E,a=[];J(i.T.d)a=i.T.d;X L(g r=t.36()?i.33:1,s=t.38()?i.2P:t.48(N(j.E.y.k.S()),N(j.E.m.k.S()));s>=r;r++){g c=t.1L(r);a.18({C:c,A:c})}n.d.k.19(a),e=e||n.d.k.S()},2N:f(e){g t=j,i=t.z,n=t.E,a=[];J(i.T.h)a=i.T.h;X L(g r=t.2Z()?i.2V:0,s=t.34()?i.2Y:23;s>=r;r++){g c=t.1L(r);a.18({C:c,A:c})}n.h.k.19(a)},2W:f(e){g t=j,i=t.z,n=t.E,a=[];J(i.T.i)a=i.T.i;X L(g r=t.3L()?i.3D:0,s=t.3J()?i.3p:4K;s>=r;r++){g c=t.1L(r);a.18({C:c,A:c})}n.i.k.19(a)},3A:f(){g e=j,t=e.z,i=e.E;i.1M.4b(f(e,i){i.1O=t.1M[e]})},3t:f(){g e=j,t=e.z,i=e.E;i.15.1O=t.1j[0],i.Z.1O=t.1j[1]},43:f(e){g t={};J(e){g i=e.44(":","-").44(" ","-").4L("-");t.y=i[0],t.m=i[1],t.d=i[2],t.h=i[3],t.i=i[4]}X{g n=2k 1e;t.y=n.1X(),t.m=n.2O()+1,t.d=n.2R(),t.h=n.35(),t.i=n.32()}x t},3n:f(e){g t=j;e=e||{},e.1M=e.1M||["3c","39","3o","3z","3x"],e.1j=e.1j||["2m","2n"],e.1w=e.1w||"2X",e.T=e.T||{},t.z=e;g i=2k 1e,n=e.4Y;n 2e 1e&&!3N(n.3w())&&(e.1V=n.1X(),e.1c=n.2O()+1,e.33=n.2R(),e.2V=n.35(),e.3D=n.32());g a=e.50;a 2e 1e&&!3N(a.3w())&&(e.1W=a.1X(),e.1d=a.2O()+1,e.2P=a.2R(),e.2Y=a.35(),e.3p=a.32()),e.1V=e.1V||i.1X()-5,e.1W=e.1W||i.1X()+5;g r=t.E;t.3A(),t.3t(),r.k.4i("F-1w",e.1w),t.3s(),t.37(),t.21(),t.2N(),t.2W(),t.1o(e.A)},2d:f(i){g n=j,a=n.E;n.1U=i||e.4y,a.1l.2d(),t.V.Q.1F(e.1k("1y-1i-L-2c")),a.k.Q.1F(e.1k("1i")),n.2g=e.1H,e.1H=f(){n.R()}},R:f(){g i=j;J(!i.27){g n=i.E;n.k.Q.1r(e.1k("1i")),n.1l.3C(),t.V.Q.1r(e.1k("1y-1i-L-2c")),e.1H=i.2g}},3k:f(){g e=j;e.R(),2f(f(){e.E.k.3j.3l(e.E.k);L(g t 1R e)e[t]=1Z,3e e[t];e.27=!0},2S)}})}(v,2w);',62,312,'|||||||||||||||function|var|||this|picker||||||div|||||mui|class|return||options|value|pciker|text|list|ui|data|rule|prototype|id|if|addEventListener|for|btn|parseInt|angle|ul|classList|hide|getSelectedValue|customData|items|body|poppicker|else|panel|ok|||||style|cancel|h5|holder|push|setItems|button|setAngle|beginMonth|endMonth|Date|endAngle|__create_dom_div__|beginAngle|active|buttons|className|mask|changedTouches|indexOf|setSelectedValue|preventDefault|elementItems|remove|getSelectedItem|itemAngle|title|tap|type|endExceed|dtpicker|ft|Math|beginExceed|change|void|inner|add|bg|back|call|slice|getSelectedIndex|_0|labels|dom|innerText|pickers|lastMoveTime|in|case|pageY|callback|beginYear|endYear|getFullYear|webkitTransition|null|stopInertiaMove|_1|calcAngle||lastMoveStart|length|init|disposed|||break|center|page|show|instanceof|setTimeout|__back|innerHTML|now|querySelector|new|triggerChange|取消|确定|highlight|calcElementItemVisibility|setSelectedIndex|appendChild|EVENT_MOVE|px|endScroll|180|document|EVENT_START|window|typeof|li|findElementItems|forEach|ease|abs|out|elementItem|correctAngle|scrollDistAngle|updateInertiaParams|timeStamp|startInertiaScroll|calcElementItemPostion|_10|getMonth|endDay|_6|getDate|300|_7|_8|beginHours|_9|datetime|endHours|_3|||getMinutes|beginDay|_4|getHours|_5|_11|_2|月|fn|getAttribute|年|deg|delete|rotateX|getSelectedItems|item|bindEvent|parentNode|dispose|removeChild|_14|_19|日|endMinutes|trigger|lastIndex|_13|_12|quartEaseOut|150ms|valueOf|分|initInertiaParams|时|_18|toFixed|close|beginMinutes|webkitTransformOrigin|extend|createMask|itemHeight|toString|_16|hightlightRange|_15|Class|isNaN|offsetHeight|toLowerCase|iphone|navigator|100|PI|height|isLeapYear|ipod|ipad|getSelected|blue||webkitTransform|Array|_17|replace|visible|string|visibleRange|getDayNum|header|childNodes|each|createElement|rad2deg|0deg|1000px|perspective|deg2rad|setAttribute|platform|rotateY|userAgent|tagName|LI|target|startAngle|acos|parseFloat|translateZ|querySelectorAll|6e|Picker|200|EVENT_CANCEL|noop|EVENT_END|ready|switch|PopPicker|clear|getSelectedText|date|parse|JSON|DtPicker|children|59|split|width|layer|detail|nextSibling|100ms|index|join|setData|400|hour|month|90|beginDate|time|endDate|getItems'.split('|'),0,{})) diff --git a/application/wap/view/first/static/wap/bargain/js/jquery-2.1.4.min.js b/application/wap/view/first/static/wap/bargain/js/jquery-2.1.4.min.js new file mode 100644 index 00000000..4686e1c1 --- /dev/null +++ b/application/wap/view/first/static/wap/bargain/js/jquery-2.1.4.min.js @@ -0,0 +1,7 @@ +/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("