+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/shop_config/website.html b/application/admin/view/shop_config/website.html
new file mode 100755
index 0000000..b11548b
--- /dev/null
+++ b/application/admin/view/shop_config/website.html
@@ -0,0 +1,201 @@
+{extend name='public/base' /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/shop_config/withdraw.html b/application/admin/view/shop_config/withdraw.html
new file mode 100755
index 0000000..09e57d4
--- /dev/null
+++ b/application/admin/view/shop_config/withdraw.html
@@ -0,0 +1,70 @@
+{extend name='public/base' /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/slide/add.html b/application/admin/view/slide/add.html
new file mode 100755
index 0000000..75be08d
--- /dev/null
+++ b/application/admin/view/slide/add.html
@@ -0,0 +1,264 @@
+{extend name='public/base' /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/slide/index.html b/application/admin/view/slide/index.html
new file mode 100755
index 0000000..c8732f7
--- /dev/null
+++ b/application/admin/view/slide/index.html
@@ -0,0 +1,137 @@
+{extend name="public/base" /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+ 清空查询
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+
diff --git a/application/admin/view/template/404.html b/application/admin/view/template/404.html
new file mode 100755
index 0000000..5556275
--- /dev/null
+++ b/application/admin/view/template/404.html
@@ -0,0 +1,17 @@
+
+{extend name="public/base" /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
404
+
+
哎呀!找不到页面。
+
+ 我们找不到您要查找的页面。
+ 同时,您可以 返回上一页 或者 去首页
+
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/template/500.html b/application/admin/view/template/500.html
new file mode 100755
index 0000000..81e9a01
--- /dev/null
+++ b/application/admin/view/template/500.html
@@ -0,0 +1,17 @@
+
+{extend name="public/base" /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
404
+
+
哎呀!页面出问题了。
+
+ 当前页面出现了一点点问题。
+ 同时,您可以 返回上一页 或者 去首页
+
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/template/content.html b/application/admin/view/template/content.html
new file mode 100755
index 0000000..f0c48a9
--- /dev/null
+++ b/application/admin/view/template/content.html
@@ -0,0 +1,11 @@
+
+{extend name="public/base" /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/user/add.html b/application/admin/view/user/add.html
new file mode 100755
index 0000000..2bc4b88
--- /dev/null
+++ b/application/admin/view/user/add.html
@@ -0,0 +1,227 @@
+{extend name='public/base' /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/user/adjust_account.html b/application/admin/view/user/adjust_account.html
new file mode 100755
index 0000000..4978f4b
--- /dev/null
+++ b/application/admin/view/user/adjust_account.html
@@ -0,0 +1,113 @@
+{extend name="layout1" /}
+{block name='content'}
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/user/index.html b/application/admin/view/user/index.html
new file mode 100755
index 0000000..26b58de
--- /dev/null
+++ b/application/admin/view/user/index.html
@@ -0,0 +1,270 @@
+{extend name="public/base" /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 用户信息
+
+
+ 用户等级
+
+
+ 可提现金额
+
+
+ 设备数量
+
+ 注册时间
+
+ 操作
+
+
+
+
+ {foreach name="data" item="item"}
+
+
+
+
+
+
+
+
+
+
+
+ {$item.user_level_id_text}
+
+
+ {$item.user_money}
+
+
+ {$item.create_time}
+
+
+
+ 修改
+
+
+ 账户调整
+
+ {if $item.status==1}
+
+ 禁用
+
+ {else/}
+
+ 启用
+
+ {/if}
+
+
+ {/foreach}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+
diff --git a/application/admin/view/withdraw/lists.html b/application/admin/view/withdraw/lists.html
new file mode 100755
index 0000000..eda7dcd
--- /dev/null
+++ b/application/admin/view/withdraw/lists.html
@@ -0,0 +1,251 @@
+{extend name="public/base" /}
+{block name='content'}
+{include file='public/content_header' /}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提现单号
+
+
+ 用户信息
+
+
+
+ 收款账户信息
+
+ 提现金额信息
+ 提现状态
+ 审核备注
+ 创建时间
+ 操作
+
+
+
+
+ {foreach name="data" item="item"}
+
+
+ {$item.sn}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {$item.status_text}
+
+
+ {$item.description}
+
+
+ {$item.create_time}
+
+
+
+ {if $item.status eq 1}
+
+ 审核
+
+ {/if}
+
+
+
+
+ {/foreach}
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+
diff --git a/application/admin/view/withdraw/review.html b/application/admin/view/withdraw/review.html
new file mode 100755
index 0000000..ed4cf27
--- /dev/null
+++ b/application/admin/view/withdraw/review.html
@@ -0,0 +1,120 @@
+{extend name="layout1" /}
+{block name='content'}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/api/common.php b/application/api/common.php
new file mode 100755
index 0000000..34f7d31
--- /dev/null
+++ b/application/api/common.php
@@ -0,0 +1,201 @@
+ '*'];
+ if (request()->isOptions()) {
+ $header = config('api.cross_domain.header');
+ return json('',200,$header);
+ }
+ }
+
+ return json([
+ 'code' => $code,
+ 'msg' => $msg,
+ 'data' => $data,
+ ], $code, $header);
+ }
+}
+
+if(!function_exists('unauthorized')){
+ /**
+ * 未授权
+ * @param string $msg
+ * @param string $data
+ * @param int $code
+ * @return Json
+ */
+ function unauthorized($msg = 'unauthorized', $data = '', $code = 401)
+ {
+ return result($msg, $data, $code);
+ }
+}
+
+if(!function_exists('client_error')){
+ /**
+ * 客户端错误
+ * @param string $msg
+ * @param string $data
+ * @param int $code
+ * @return Json
+ */
+ function client_error($msg = 'client error', $data = '', $code = 400)
+ {
+ return result($msg, $data, $code);
+ }
+}
+
+if(!function_exists('server_error')){
+ /**
+ * 服务端错误
+ * @param string $msg
+ * @param string $data
+ * @param int $code
+ * @return Json
+ */
+ function server_error($msg = 'server error', $data = '', $code = 500)
+ {
+ return result($msg, $data, $code);
+ }
+}
+
+if(!function_exists('error_404')){
+ /**
+ * 资源或接口不存在
+ * @param string $msg
+ * @param string $data
+ * @param int $code
+ * @return Json
+ */
+ function error_404($msg = '404 not found', $data = '', $code = 404)
+ {
+ return result($msg, $data, $code);
+ }
+}
+
+if (!function_exists('get_ad')) {
+ /**
+ * 广告列表
+ * @param string $alias 广告别名
+ * @param string $num。显示数量
+ * @return li
+ */
+ function get_ad($alias, $num = '999')
+ {
+ $_malladviceModel = new Slide();
+ $where = 'alias="'.$alias.'"';
+ $malladvice_list = $_malladviceModel->where($where)->limit($num)->order('sort_number desc')->select();
+ $ad = array();
+ $web_url = ShopConfig::get('website', 'img_url');
+ foreach ($malladvice_list as $key => $row) {
+ $ad[$key]['id'] = $row['id'];
+ if($row['jump_type']==1){
+ $ad[$key]['unionid'] = Crypt::encrypt($row['jump_target']);
+ }else{
+ $ad[$key]['url'] = $row['jump_target'];
+ }
+ $ad[$key]['type'] = $row['jump_type'];
+ $ad[$key]['name'] = $row['name'];
+ $ad[$key]['describe'] = $row['describe'];
+ $ad[$key]['img'] = $web_url . $row['img'];
+ }
+ return $ad;
+ }
+}
+
+if(!function_exists('curl_request')){
+ //参数1:访问的URL,参数2:post数据(不填则为GET),参数3:提交的$cookies,参数4:是否返回$cookies
+ function curl_request($url,$post='',$cookie='', $returnCookie=0)
+ {
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
+ curl_setopt($curl, CURLOPT_REFERER, "http://XXX");
+ if($post) {
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
+ }
+ if($cookie) {
+ curl_setopt($curl, CURLOPT_COOKIE, $cookie);
+ }
+ curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 10);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ $data = curl_exec($curl);
+ if (curl_errno($curl)) {
+ return curl_error($curl);
+ }
+ curl_close($curl);
+ if($returnCookie){
+ list($header, $body) = explode("\r\n\r\n", $data, 2);
+ preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
+ $info['cookie'] = substr($matches[1][0], 1);
+ $info['content'] = $body;
+ return $info;
+ }else{
+ return $data;
+ }
+ }
+}
+
+//分类递归
+if(!function_exists('getSubs')){
+ function getSubs($categorys,$catId=0,$level=1){
+ $subs=array();
+ foreach($categorys as $item){
+ if($item['parent_id']==$catId){
+ $item['son'] = getSubs($categorys, $item['cid']);
+ if(empty($item['son'])) {
+ unset($item['son']);
+ }
+ array_push($subs, $item);
+ }
+ }
+ return $subs;
+ }
+}
diff --git a/application/api/controller/AuthController.php b/application/api/controller/AuthController.php
new file mode 100755
index 0000000..14c60a0
--- /dev/null
+++ b/application/api/controller/AuthController.php
@@ -0,0 +1,109 @@
+param();
+ $avatar =$param['avatar']??'';
+ $nickname =$param['nickname']??'';
+ $code =$param['code']??'';
+ $distribution_code =$param['distribution_code']??'';
+ $encryptedData =$param['encryptedData']??'';
+ $iv =$param['iv']??'';
+ if(!$avatar || !$nickname || !$code){
+ return error('参数不足');
+ }
+ $user_info = $this->get_openid($code,$encryptedData,$iv);
+ if (!$user_info['openid']) {
+ return error('授权失败');
+ }
+ $where['mobile'] = array('EQ',$user_info['tel']);
+ $userinfo = $fumodel->field('id,avatar,nickname,openid')->where($where)->find();
+ if($userinfo && !$userinfo['openid']){
+ $data_login['login_ip']=$request->ip();
+ $data_login['login_time']=time();
+ $data_login['openid']=$user_info['openid'];
+ $fumodel->where('id', $userinfo['id'])->update($data_login);
+ $token = $this->getToken($userinfo['id']);
+ $uid=Crypt::encrypt($userinfo['id']);
+ return success(['token' => $token,'uid'=>$uid], '登录成功');
+ }else if($userinfo && $userinfo['openid']){
+ $data_login['login_ip']=$request->ip();
+ $data_login['login_time']=time();
+ $fumodel->where('id', $userinfo['id'])->update($data_login);
+ $token = $this->getToken($userinfo['id']);
+ $uid=Crypt::encrypt($userinfo['id']);
+ return success(['token' => $token,'uid'=>$uid], '登录成功');
+ }
+ //登录逻辑
+ // 启动事务
+ $fumodel->startTrans();
+ try {
+ $res['sn'] =create_user_sn();
+ $res['distribution_code'] =generate_invite_code();
+ $res['nickname']=$nickname;
+ $res['username'] = '用户'.$res['sn'];
+ $res['avatar'] = $avatar;
+ $res['openid'] = $user_info['openid'];
+ $res['mobile'] = $user_info['tel'];
+ $res['create_time'] = time();
+ $res['login_ip']=$request->ip();
+ $res['login_time']=time();
+ $fumodel::create($res);
+ $uid=$fumodel->getLastInsID();
+ //分销
+ if($distribution_code){
+ $fumodel->code($distribution_code,$uid);
+ }
+ $fumodel->commit();
+ } catch (Exception $e) {
+ $fumodel->rollback();
+ return client_error($e->getMessage());
+ }
+ $uid=Crypt::encrypt($uid);
+ $token = $this->getToken($uid);
+ //返回数据
+ return success(['token' => $token,'uid'=>$uid], '注册成功');
+ }
+
+ //获取用户临时code 用来去获取openid
+ public function get_openid($code,$encryptedData,$iv)
+ {
+
+ $APPID =ShopConfig::get('website', 'APPID');
+ $APPSECRET=ShopConfig::get('website', 'APPSECRET');
+ $url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' . $APPID. '&secret=' . $APPSECRET. '&js_code=' . $code . '&grant_type=authorization_code';
+ $val = curl_request($url);
+ $user_info = json_decode($val,true);
+ $encryptedData=urldecode($encryptedData);
+ $iv = urldecode($iv);
+ $pc = new WXBizDataCrypt($APPID,$user_info['session_key']);
+ $errCode = $pc->decryptData($encryptedData,$iv,$data);
+ $data1 = json_decode($data, true);
+ $user_info['tel']=$data1['purePhoneNumber'];
+ return $user_info;
+ }
+}
\ No newline at end of file
diff --git a/application/api/controller/CartController.php b/application/api/controller/CartController.php
new file mode 100755
index 0000000..e5b4d1d
--- /dev/null
+++ b/application/api/controller/CartController.php
@@ -0,0 +1,189 @@
+param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $goods_id = $param['goods_id']?Crypt::decrypt($param['goods_id']):'';
+ if(!$goods_id){
+ return client_error('该商品不存在');
+ }
+ $item_value=$param['item_value']??'';
+ if(!$item_value){
+ return client_error('请选择规格');
+ }
+ $goods_num=$param['goods_num']??'0';
+ if($goods_num=='0'){
+ return client_error('购买数量必须大于0');
+ }
+ $time = time();
+ $where = [
+ 'user_id' => $user_id,
+ 'goods_id' => $goods_id,
+ 'item_value' => $item_value,
+ ];
+ $info = Cart::where($where)->find();
+
+ $cart_num = $param['goods_num'] + (isset($info) ? $info['goods_num'] : 0);
+
+ if ($cmodel->checkStock($item_value, $cart_num,$goods_id)) {
+ return client_error('很抱歉,商品库存不足');
+ }
+ if ($info) {
+ //购物车内已有该商品
+ $update_data = [
+ 'goods_num' => $goods_num + $info['goods_num'],
+ 'update_time' => $time,
+ ];
+ $res =$cmodel
+ ->where('id', $info['id'])
+ ->update($update_data);
+ } else {
+ //新增购物车记录
+ $data = [
+ 'user_id' => $user_id,
+ 'goods_id' => $goods_id,
+ 'goods_num' => $goods_num,
+ 'item_value' => $item_value,
+ 'create_time' => $time,
+ ];
+ $res = $cmodel->insert($data);
+ }
+ return $res ? success('','添加成功') : client_error('添加失败');
+ }
+
+ //删除购物车
+ public function del(Request $request,Cart $cmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $cart_id= $param['cart_id']?Crypt::decrypt($param['cart_id']):'0';
+ if($cart_id=='0'){
+ return client_error('该购物车商品不存在');
+ }
+ $res = $cmodel->whereIn('id',$cart_id)->delete();
+ return $res ? success('','删除成功') : client_error('删除失败');
+ }
+
+ //变动购物车数量
+ public function change(Request $request,Cart $cmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $cart_id=$param['cart_id']?Crypt::decrypt($param['cart_id']):'0';
+ if($cart_id=='0'){
+ return client_error('该购物车商品不存在');
+ }
+ $goods_num=$param['goods_num']??'0';
+ if($goods_num=='0'){
+ return client_error('购买数量必须大于0');
+ }
+ $cart = $cmodel->where(['id' => $cart_id])->find();
+ if ($cmodel->checkStock($cart['item_value'], $goods_num,$cart['goods_id'])) {
+ return client_error('很抱歉,商品库存不足');
+ }
+ $update = [
+ 'update_time' => time(),
+ 'goods_num' => $goods_num,
+ ];
+ $res = $cmodel->where(['id' => $cart_id])->update($update);
+ return $res ? success('','更新成功') : client_error('更新失败');
+ }
+
+ //购物车选中状态
+ public function selected(Request $request,Cart $cmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $cart_id=$param['cart_id']?Crypt::decrypt($param['cart_id']):'0';
+ if($cart_id=='0'){
+ return client_error('该购物车商品不存在');
+ }
+ $res = $cmodel->where(['id' => $cart_id, 'user_id' => $user_id])
+ ->update(['selected' => $param['selected'], 'update_time' => time()]);
+ return $res ? success('','更新成功') : client_error('更新失败');
+ }
+
+ //列表
+ public function lists(Request $request,Cart $cmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $carts =$cmodel
+ ->alias('c')
+ ->field("mi.thumb_image as img,g.name,g.price,g.id as goods_id,gb.name as brand_name,c.goods_num,c.selected,c.id as cart_id,item_value")
+ ->join('goods g', 'g.id = c.goods_id')
+ ->join('goods_brand gb', 'gb.id= g.brand_id')
+ ->join('mall_image mi', 'mi.union_id= c.goods_id and is_cover=1 and mi.type=1', 'LEFT')
+ ->where('c.user_id', $user_id)
+ ->order('c.create_time desc')
+ ->select();
+ $goods_num = 0;
+ $total = 0;
+ $lists = [];
+ foreach ($carts as $k1 => $cart) {
+ $cart['goods_id'] = Crypt::encrypt($cart['goods_id']);
+ $cart['cart_id'] =Crypt::encrypt($cart['cart_id']);
+ $cart['img'] = $this->img_url.$cart['img'];
+ $cart['sub_price'] = 0;
+ if ($cart['selected'] ==1) {
+ $goods_num += $cart['goods_num'];
+ $total += $cart['price'] * $cart['goods_num'];
+ $cart['sub_price'] = round($cart['price'] * $cart['goods_num'], 2);
+ }
+ $cart['selected'] = intval($cart['selected']);
+ $lists[] = $cart;
+ }
+ $data=[
+ 'lists' => $lists,
+ 'total_amount' => round($total, 2),
+ 'total_num' => $goods_num,
+ ];
+ return success($data);
+ }
+
+ //获取购物车数量
+ public function cartnum(Request $request,Cart $cmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $num = $cmodel->where('user_id', $user_id)->sum('goods_num');
+ $data=['num' => $num ?? 0];
+ return success($data);
+ }
+}
\ No newline at end of file
diff --git a/application/api/controller/Controller.php b/application/api/controller/Controller.php
new file mode 100755
index 0000000..440bf57
--- /dev/null
+++ b/application/api/controller/Controller.php
@@ -0,0 +1,66 @@
+isOptions()) { //浏览器的option试探请求,要exit掉,不然你的业务会被执行两次
+ exit();
+ }
+ $this->request = $request;
+
+ //jwt验证
+ //$this->jtwInit();
+ //$this->checkToken();
+
+ //初始化基本数据
+ $this->param = $request->param();
+ $this->page = $this->param['page'] ?? 1;
+ $this->limit = $this->param['limit'] ?? 10;
+ $this->id = $this->param['id'] ?? 0;
+ $this->img_url=ShopConfig::get('website', 'img_url');
+
+ //limit防止过大处理
+ $this->limit = $this->limit <= 100 ? $this->limit : 100;
+ }
+
+
+}
diff --git a/application/api/controller/GoodsController.php b/application/api/controller/GoodsController.php
new file mode 100755
index 0000000..f172040
--- /dev/null
+++ b/application/api/controller/GoodsController.php
@@ -0,0 +1,249 @@
+
+ * @title 首页
+ */
+
+namespace app\api\controller;
+use app\common\model\Goodsindex;
+use app\common\model\Goods;
+use app\common\model\GoodsBrand;
+use app\common\model\GoodsItem;
+use app\common\model\GoodsCategory;
+use app\common\model\MallImage;
+use app\common\model\ShopConfig;
+use app\common\model\PhaseConfig;
+use app\common\model\GoodsCollect;
+use tools\Crypt;
+use think\Request;
+class GoodsController extends Controller
+{
+
+ protected $authExcept = [
+ 'goods_info','goods_list','category_list'
+ ];
+
+ //商品列表
+ public function goods_list(Request $request,Goods $model)
+ {
+ $param = $request->param();
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $where[]=array('status','=',1);
+ $where[]=array('gi.stock','>',0);
+ $keyword = $param['keyword']??'';
+ $where1='';
+ if($keyword){
+ foreach ($keyword as $v1) {
+ $where1.="( `spec_value` LIKE '%".$v1."%' OR `gb`.`name` LIKE '%".$v1."%' OR `gc`.`name` LIKE '%".$v1."%') or";
+ }
+ $where1=rtrim($where1,'or');
+ }
+ $sort=$param['sort']??'asc';
+ $order=$param['order']??'g.sort_number';
+ $goods_count = $model
+ ->alias('g')
+ ->where($where)
+ ->where($where1)
+ ->join('mall_image mi', 'mi.union_id= g.id and is_cover=1 and mi.type=1', 'LEFT')
+ ->join('goods_brand gb', 'gb.id = g.brand_id')
+ ->join('goods_item gi', 'gi.goods_id = g.id')
+ ->join('goods_category gc', 'gc.id = g.goods_category_id')
+ ->group('g.id')
+ ->count();
+ $totalPages = ceil($goods_count / $size);
+ $goods_list = $model
+ ->alias('g')
+ ->field("mi.thumb_image as img, g.name,g.price,g.id as goods_id,gb.name as brand_name")
+ ->join('mall_image mi', 'mi.union_id= g.id and is_cover=1 and mi.type=1', 'LEFT')
+ ->join('goods_brand gb', 'gb.id = g.brand_id')
+ ->join('goods_item gi', 'gi.goods_id = g.id')
+ ->join('goods_category gc', 'gc.id = g.goods_category_id')
+ ->where($where)
+ ->where($where1)
+ ->limit($page, $size)
+ ->group('g.id')
+ ->order($order.' '.$sort)
+ ->select();
+ if (!$goods_list) {
+ return success(array('list'=>[]));
+ }
+ foreach ($goods_list as $k1 => $v1) {
+ $goods_list[$k1]['img'] =$this->img_url.$v1['img'];
+ $goods_list[$k1]['goods_id'] = Crypt::encrypt($v1['goods_id']);
+ }
+ $page=array(
+ 'count'=>$goods_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$goods_list,'page'=>$page));
+ }
+
+ //商品详情
+ public function goods_info(Request $request,Goods $model,MallImage $mimodel,GoodsItem $gimodel,PhaseConfig $pcmodel)
+ {
+ $param = $request->param();
+ $gid = $param['gid']?Crypt::decrypt($param['gid']):'';
+ if(!$gid){
+ return client_error('暂无数据');
+ }
+ //商品信息
+ $goods_info=$model
+ ->alias('g')
+ ->field('g.name as goods_name,price,g.id as goods_id,detail,gb.name as brand_name,model,collocation_goods,original_price,goods_size,pc.name as phase_name,goods_category_id')
+ ->join('goods_brand gb', 'gb.id = g.brand_id')
+ ->join('phase_config pc', 'pc.id= g.phase_id', 'LEFT')
+ ->where(array('g.id'=>$gid,'status'=>1))->find();
+
+ //精选配置
+ $collocation_goods=json_decode($goods_info['collocation_goods']);
+ $where[]=array('g.id','in',$collocation_goods);
+ $where[]=array('g.status','=',1);
+ $goods_info['collocation_goods'] =$model
+ ->alias('g')
+ ->field("mi.thumb_image as img, g.name,g.price,g.id as goods_id,gb.name as brand_name")
+ ->join('goods_brand gb', 'gb.id= g.brand_id')
+ ->join('mall_image mi', 'mi.union_id= g.id and is_cover=1 and mi.type=1', 'LEFT')
+ ->where($where)
+ ->select();
+ foreach ($goods_info['collocation_goods'] as $k1 => $v1) {
+ $goods_info['collocation_goods'][$k1]['img'] =$this->img_url.$v1['img'];
+ $goods_info['collocation_goods'][$k1]['goods_id'] = Crypt::encrypt($v1['goods_id']);
+ }
+ $goods_info['goods_size']=explode("\r\n",$goods_info['goods_size']);
+
+ $img_list=$mimodel->field('thumb_image,ori_image')->where(array('union_id'=>$gid,'type'=>1))->select();
+ foreach ($img_list as $key => $value) {
+ $img_list[$key]['thumb_image'] =$this->img_url.$value['thumb_image'];
+ $img_list[$key]['ori_image'] =$this->img_url.$value['ori_image'];
+ }
+ //尺寸图片
+ $size_img=$this->img_url.ShopConfig::get('website', 'size_img');
+
+ //商品尺码
+ $goodsitem_list=$gimodel->field("id,spec_value,stock")->where(array('goods_id'=>$goods_info['goods_id']))->select();
+ foreach ($goodsitem_list as $key => $value) {
+ $goodsitem_list[$key]['id']=Crypt::encrypt($value['id']);
+ }
+
+ //品相列表
+ $phaseconfig_list=$pcmodel->field("name,describe")->all();
+ $goods_info['goods_id'] = Crypt::encrypt($goods_info['goods_id']);
+
+ $category_goods =$model
+ ->alias('g')
+ ->field("mi.thumb_image as img, g.name,g.price,g.id as goods_id,gb.name as brand_name")
+ ->join('goods_brand gb', 'gb.id= g.brand_id')
+ ->join('mall_image mi', 'mi.union_id= g.id and is_cover=1 and mi.type=1', 'LEFT')
+ ->where(array('g.goods_category_id'=>$goods_info['goods_category_id'],'g.status'=>1))
+ ->select();
+ foreach ($category_goods as $k1 => $v1) {
+ $category_goods[$k1]['img'] =$this->img_url.$v1['img'];
+ $category_goods[$k1]['goods_id'] = Crypt::encrypt($v1['goods_id']);
+ }
+ return success(array('info'=>$goods_info,'img_list'=>$img_list,'size_img'=>$size_img,'goodsitem_list'=>$goodsitem_list,'phaseconfig_list'=>$phaseconfig_list,'category_goods'=>$category_goods));
+ }
+
+ //商品筛选
+ public function category_list(Request $request,GoodsCategory $gcmodel,GoodsBrand $gbmodel)
+ {
+ $brand_list=$gbmodel->field('name,initial,img')->where(array('is_show'=>1))->select();
+ foreach ($brand_list as $k1 => $v1) {
+ $brand_list[$k1]['img'] =$this->img_url.$v1['img'];
+ }
+ $category_list=$gcmodel->field('name,id as cid,parent_id')->select();
+ $category=getSubs($category_list,0);
+ $size_list=ShopConfig::get('website', 'size');
+ $size_list=explode(',',$size_list);
+ $data=array(
+ 'brand_list'=>$brand_list,
+ 'category_list'=>$category,
+ 'size_list'=>$size_list,
+ );
+ return success($data);
+ }
+
+
+ //愿望清单列表
+ public function collectgoods_list(Request $request,GoodsCollect $gcmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $where[]=array('g.status','=',1);
+ $where[]=array('user_id','=',$user_id);
+
+ $goods_count = $gcmodel
+ ->alias('gc')
+ ->where($where)
+ ->join('goods g', 'g.id = gc.goods_id')
+ ->join('mall_image mi', 'mi.union_id= gc.goods_id and is_cover=1 and mi.type=1', 'LEFT')
+ ->join('goods_brand gb', 'gb.id = g.brand_id')
+ ->count();
+ $totalPages = ceil($goods_count / $size);
+ $goods_list = $gcmodel
+ ->alias('gc')
+ ->field("mi.thumb_image as img, g.name,g.price,g.id as goods_id,gb.name as brand_name")
+ ->join('goods g', 'g.id = gc.goods_id')
+ ->join('mall_image mi', 'mi.union_id= gc.goods_id and is_cover=1 and mi.type=1', 'LEFT')
+ ->join('goods_brand gb', 'gb.id = g.brand_id')
+ ->where($where)
+ ->limit($page, $size)
+ ->order('g.sort_number asc')
+ ->select();
+ if (!$goods_list) {
+ return success(array('list'=>[]));
+ }
+ foreach ($goods_list as $k1 => $v1) {
+ $goods_list[$k1]['img'] =$this->img_url.$v1['img'];
+ $goods_list[$k1]['goods_id'] = Crypt::encrypt($v1['goods_id']);
+ }
+ $page=array(
+ 'count'=>$goods_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$goods_list,'page'=>$page));
+ }
+
+ public function handlecollectgoods(Request $request,GoodsCollect $gcmodel){
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $goods_id = $param['goods_id']?Crypt::decrypt($param['goods_id']):'';
+ if(!$goods_id){
+ return client_error('该商品不存在');
+ }
+ if($param['is_collect']==1){
+ $where = [
+ 'user_id' => $user_id,
+ 'goods_id' => $goods_id
+ ];
+ $info = GoodsCollect::where($where)->find();
+ if(!$info){
+ $data =[
+ 'user_id'=>$user_id,
+ 'goods_id'=>$goods_id,
+ 'create_time'=>time(),
+ ];
+ $res =$gcmodel->insert($data);
+ }else{
+ return success('','操作成功');
+ }
+ }else{
+ $res =$gcmodel->where(['goods_id'=>$goods_id,'user_id'=>$user_id])->delete();
+ }
+ return $res ? success('','操作成功') : client_error('操作失败');
+ }
+}
\ No newline at end of file
diff --git a/application/api/controller/IndexController.php b/application/api/controller/IndexController.php
new file mode 100755
index 0000000..67450f9
--- /dev/null
+++ b/application/api/controller/IndexController.php
@@ -0,0 +1,114 @@
+
+ * @title 首页
+ */
+
+namespace app\api\controller;
+use app\common\model\GoodsIndex;
+use app\common\model\Goods;
+use app\common\model\GoodsBrand;
+use app\common\model\GoodsItem;
+use app\common\model\GoodsCategory;
+use app\common\model\MallImage;
+use app\common\model\ShopConfig;
+use app\common\model\PhaseConfig;
+use tools\Crypt;
+use think\Request;
+class IndexController extends Controller
+{
+
+ protected $authExcept = [
+ 'home','pattern_goods'
+ ];
+
+ public function home(Request $request,Goods $gmodel,GoodsIndex $gimodel)
+ {
+ // echo Crypt::encrypt(1).'|';
+ // echo $this->getToken(1);
+ $param = $request->param();
+ //首页轮播
+ $carousel = get_ad('carousel',6);
+ $goodsindex_list=$gimodel->where(array('status'=>1))->order('sort_number ASC')->select();
+ $goodsindex=array();
+ foreach ($goodsindex_list as $key => $value) {
+ $goodsindex[$key]['id'] = Crypt::encrypt($value['id']);
+ $goodsindex[$key]['name']=$value['name'];
+ $goodsindex[$key]['type']=$value['type'];
+ $goods_ids=json_decode($value['goods_ids']);
+ $where[]=array('g.id','in',$goods_ids);
+ $goods_list=$gmodel
+ ->alias('g')
+ ->field("mi.thumb_image as img, g.name,g.price,g.id as goods_id,gb.name as brand_name")
+ ->join('goods_brand gb', 'gb.id= g.brand_id')
+ ->join('mall_image mi', 'mi.union_id= g.id and is_cover=1 and mi.type=1', 'LEFT')
+ ->where($where)->select();
+ foreach ($goods_list as $k1 => $v1) {
+ $goods_list[$k1]['img'] =$this->img_url.$v1['img'];
+ $goods_list[$k1]['goods_id'] = Crypt::encrypt($v1['goods_id']);
+ }
+ $goodsindex[$key]['goods_list']=$goods_list;
+ }
+ $data = [
+ 'carousel' =>$carousel,//首页轮播
+ 'goodsindex' => $goodsindex,//模式板块
+ ];
+ return success($data);
+ }
+
+ //模式商品
+ public function pattern_goods(Request $request,Goods $model,GoodsIndex $gimodel)
+ {
+ $param = $request->param();
+ $id = $param['id']?Crypt::decrypt($param['id']):'';
+ if(!$id){
+ return success(array('list'=>[]));
+ }
+ $goodsindex_info=$gimodel->where(array('status'=>1,'id'=>$id))->find();
+ if(!$goodsindex_info){
+ return success(array('list'=>[]));
+ }
+
+ $id = $param['id']?Crypt::decrypt($param['id']):'';
+
+ $goods_ids=json_decode($goodsindex_info['goods_ids']);
+ $where[]=array('g.id','in',$goods_ids);
+
+ $sort=$param['sort']??'asc';
+ $order=$param['order']??'g.sort_number';
+
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $goods_count = $model
+ ->alias('g')
+ ->where($where)
+ ->join('goods_brand gb', 'gb.id= g.brand_id')
+ ->join('mall_image mi', 'mi.union_id= g.id and is_cover=1 and mi.type=1', 'LEFT')
+ ->count();
+ $totalPages = ceil($goods_count / $size);
+ $goods_list = $model
+ ->alias('g')
+ ->field("mi.thumb_image as img, g.name,g.price,g.id as goods_id,gb.name as brand_name")
+ ->join('goods_brand gb', 'gb.id= g.brand_id')
+ ->join('mall_image mi', 'mi.union_id= g.id and is_cover=1 and mi.type=1', 'LEFT')
+ ->where($where)
+ ->limit($page, $size)
+ ->order($order.' '.$sort)
+ ->select();
+ if (!$goods_list) {
+ return success(array('list'=>[]));
+ }
+ foreach ($goods_list as $k1 => $v1) {
+ $goods_list[$k1]['img'] =$this->img_url.$v1['img'];
+ $goods_list[$k1]['goods_id'] = Crypt::encrypt($v1['goods_id']);
+ }
+ $page=array(
+ 'count'=>$goods_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$goods_list,'page'=>$page));
+ }
+}
\ No newline at end of file
diff --git a/application/api/controller/OrderController.php b/application/api/controller/OrderController.php
new file mode 100755
index 0000000..6ef3a10
--- /dev/null
+++ b/application/api/controller/OrderController.php
@@ -0,0 +1,422 @@
+param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $action = $param['action'];
+ $info = Order::info($param, $user_id);
+ if (!$info) {
+ return client_error('商品信息不存在');
+ }
+ if($info['code'] == 0) {
+ return client_error($info['msg']);
+ }
+ if ($action == 'info') {
+ return success($info['data']);
+ }
+ $order = Order::add($user_id, $info['data'], $param);
+ if($order['code']==0){
+ return client_error($order['msg']);
+ }
+ return success($order['data']['order_sn'],'下单成功,正在调取支付');
+ }
+
+
+ //下单接口
+ public function consignment_buy(Request $request)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $json_value = $param['json_value'];
+ if (!$json_value) {
+ return client_error('商品信息不存在');
+ }
+ $json_value=json_decode($json_value,true);
+ $info = ConsignmentOrder::info($json_value, $user_id);
+ if (!$info) {
+ return client_error('商品信息不存在');
+ }
+ if($info['code'] == 0) {
+ return client_error($info['msg']);
+ }
+ $order = ConsignmentOrder::add($user_id, $info['data']);
+ if($order['code']==0){
+ return client_error($order['msg']);
+ }
+ $order_id=Crypt::encrypt($order['data']['order_id']);
+ return success($order_id,'寄卖订单已提交');
+ }
+
+ //寄卖参数
+ public function consignment_config(Request $request)
+ {
+ //寄卖流程
+ $procedure =ShopConfig::get('policy', 'procedure');
+ //寄卖规则
+ $rule =ShopConfig::get('policy', 'rule');
+ //寄卖成功提醒
+ $consignment =ShopConfig::get('policy', 'consignment');
+ //品相
+ $phaseconfig =PhaseConfig::field('name')->select();
+ //购买渠道
+ $channel =ShopConfig::get('website', 'channel');
+ $channel=explode(',',$channel);
+ //寄卖数量限制
+ $jmnum =ShopConfig::get('website', 'jmnum');
+ $data=array(
+ 'procedure'=>$procedure,
+ 'rule'=>$rule,
+ 'consignment'=>$consignment,
+ 'phaseconfig'=>$phaseconfig,
+ 'channel'=>$channel,
+ 'jmnum'=>$jmnum,
+ );
+ return success($data);
+ }
+
+ //上传图片
+ public function icon(Request $request)
+ {
+ $param = $request->param();
+ $file = request()->file('image');
+ if($file){
+ $info = $file->validate(['size'=>10*1024*1024,'ext'=>'jpg,png,gif'])->move(Env::get('root_path').'public/uploads/attachment');
+ if($info){
+ $data['avatar_logo']='/uploads/attachment/'.$info->getSaveName();
+ $data['avatar']=$this->img_url.$data['avatar_logo'];
+ return success($data);
+ }else{
+ // 上传失败获取错误信息
+ return client_error($file->getError());
+ }
+ }else{
+ return client_error('请上传图片');
+ }
+ }
+
+
+ //寄卖订单列表(审核中,待上架,已上架,取消/退回)
+ public function consignment_list(Request $request,ConsignmentOrder $model)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $where[] = ['o.user_id', '=', $user_id];
+ //订单类型
+ if ($param['status'] == '1') {
+ $where[] = ['o.order_status', 'in','0'];
+ }
+ if ($param['status'] == '2') {
+ $where[] = ['o.order_status', 'in',"1,3,4,5,6"];
+ }
+ if ($param['status'] == '3') {
+ $where[] = ['o.order_status', 'in','2'];
+ }
+ if ($param['status'] == '4') {
+ $where[] = ['o.order_status', 'in','7,8'];
+ }
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $order_count = $model
+ ->alias('o')
+ ->join('consignment_order_goods g', 'g.order_id = o.id')
+ ->with(['consignment_order_goods'])
+ ->where($where)
+ ->order('o.id desc')
+ ->group('o.id')
+ ->count();
+ $totalPages = ceil($order_count / $size);
+ $order_list = $model
+ ->alias('o')
+ ->field('o.order_sn,o.order_status,o.id')
+ ->join('consignment_order_goods g', 'g.order_id = o.id')
+ ->with(['consignment_order_goods'])
+ ->where($where)
+ ->order('o.id desc')
+ ->group('o.id')
+ ->limit($page, $size)
+ ->select();
+ if (!$order_list) {
+ return success(array('list'=>[]));
+ }
+ foreach ($order_list as $k1 => $v1) {
+ $order_list[$k1]['order_id'] = Crypt::encrypt($v1['id']);
+ $order_list[$k1]['order_status_text'] = $v1['order_status_text'];
+ unset($v1['id']);
+ foreach ($v1['consignment_order_goods'] as &$order_goods){
+ $order_goods['goods_img']=$this->img_url.$order_goods['goods_img'];
+ $order_goods['refund_status_text'] = $order_goods['refund_status_text'];
+ unset($order_goods['id'],$order_goods['goods_id'],$order_goods['order_id']);
+ }
+ }
+ $page=array(
+ 'count'=>$order_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$order_list,'page'=>$page));
+ }
+
+ //寄卖订单列表(已售出)
+ public function consignment_sold(Request $request,ConsignmentOrderGoods $cogmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $where[] = ['o.user_id', '=', $user_id];
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $order_count = $cogmodel
+ ->alias('cog')
+ ->join('consignment_order co', 'cog.order_id = co.id and co.order_status=2')
+ ->join('order_goods og', 'og.goods_id = cog.goods_id')
+ ->join('order o', 'og.order_id = o.id and o.order_status in (1,2,3)')
+ ->where($where)
+ ->order('o.id desc')
+ ->group('o.id')
+ ->count();
+ $totalPages = ceil($order_count / $size);
+ $order_list = $cogmodel
+ ->alias('cog')
+ ->field('cog.item_value,cog.goods_name,cog.goods_img,cog.goods_price,cog.brand_name,cog.phase_name,cog.class_name,cog.channel_name')
+ ->join('consignment_order co', 'cog.order_id = co.id and co.order_status=2')
+ ->join('order_goods og', 'og.goods_id = cog.goods_id')
+ ->join('order o', 'og.order_id = o.id and o.order_status in (1,2,3)')
+ ->where($where)
+ ->order('cog.id desc')
+ ->limit($page, $size)
+ ->select();
+ if (!$order_list) {
+ return success(array('list'=>[]));
+ }
+ foreach ($order_list as $k1 => $v1) {
+ $order_list[$k1]['goods_img'] = $this->img_url.$v1['goods_img'];
+ }
+ $page=array(
+ 'count'=>$order_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$order_list,'page'=>$page));
+ }
+
+
+ //寄卖订单详情
+ public function consignment_detail(Request $request,ConsignmentOrder $model)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $order_id = $param['order_id']?Crypt::decrypt($param['order_id']):'';
+ if(!$order_id){
+ return client_error('该订单不存在');
+ }
+ $where[] = ['o.user_id', '=', $user_id];
+ $where[] = ['o.id', '=', $order_id];
+ $order_info = $model
+ ->alias('o')
+ // ->field('o.order_sn,o.order_status,o.id,o.pay_time,total_amount,shipping_time,invoice_name,invoice_no,transaction_id,user_remark,confirm_take_time,cancel_time,o.create_time,province,city,district,address,mobile,consignee')
+ ->with(['consignment_order_goods','logs'])
+ ->where($where)
+ ->find();
+ if (!$order_info) {
+ return client_error('该订单不存在');
+ }
+ $order_info['order_id'] = Crypt::encrypt($order_info['id']);
+ $order_info['order_status_text'] = $order_info['order_status_text'];
+ foreach ($order_info['consignment_order_goods'] as &$order_goods){
+ $order_goods['goods_img']=$this->img_url.$order_goods['goods_img'];
+ $order_goods['id'] = Crypt::encrypt($order_goods['id']);
+ $order_goods['refund_status_text'] = $order_goods['refund_status_text'];
+ unset($order_goods['goods_id'],$order_goods['order_id']);
+ }
+ foreach ($order_info['logs'] as &$logs){
+ unset($logs['id'],$logs['order_id']);
+ }
+ unset($order_info['id'],$order_info['user_id'],$order_info['update_time'],$order_info['delete_time']);
+ return success($order_info);
+ }
+
+ /**
+ * Notes: 取消寄卖订单
+ * @param $order_id
+ * @param $user_id
+ */
+ public static function consignment_cancel(Request $request,ConsignmentOrder $model)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $order_id = $param['order_id']?Crypt::decrypt($param['order_id']):'';
+ if(!$order_id){
+ return client_error('该订单不存在');
+ }
+ $order = ConsignmentOrder::get([
+ 'user_id' => $user_id,
+ 'id' => $order_id
+ ]);
+ if (!$order || ($order['order_status']!='0' && $order['order_status']!='3')) {
+ return client_error('很抱歉!订单无法取消');
+ }
+ $model->startTrans();
+ try {
+ //取消订单
+ $update = [
+ 'cancel_time' => time(),
+ 'order_status' => 8,
+ ];
+ $model->where(['id' => $order_id])->update($update);
+ //记录日志
+ ConsignmentOrderLog::record(
+ $order_id,
+ '寄卖订单已取消'
+ );
+ $model->commit();
+ } catch (Exception $e) {
+ $model->rollback();
+ return client_error($e->getMessage());
+ }
+ return success('','取消成功');
+ }
+
+ /**
+ * Notes: 确认估价
+ * @param $order_id
+ * @param $user_id
+ */
+ public static function consignment_confirm(Request $request,ConsignmentOrder $model,ConsignmentOrderGoods $cogmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $order_id = $param['order_id']?Crypt::decrypt($param['order_id']):'';
+ if(!$order_id){
+ return client_error('该订单不存在');
+ }
+ $goods_id = $param['goods_id']?$param['goods_id']:'';
+ if(!$goods_id){
+ return client_error('请选择确认估价商品');
+ }
+ $is_return = $param['is_return'];
+ $consignee = $param['consignee']?$param['consignee']:'';
+ $address = $param['address']?$param['address']:'';
+ $mobile = $param['mobile']?$param['mobile']:'';
+ if(!$consignee || !$address || !$mobile){
+ return client_error('请选择取货地址');
+ }
+ $th_consignee = $param['th_consignee']?$param['th_consignee']:'';
+ $th_address = $param['th_address']?$param['th_address']:'';
+ $th_mobile = $param['th_mobile']?$param['th_mobile']:'';
+ if($is_return==1 && (!$th_consignee || !$th_address || !$th_mobile)){
+ return client_error('请选择退回地址');
+ }
+ $takeparts_time = $param['takeparts_time']?$param['takeparts_time']:'';
+ if(!$takeparts_time){
+ return client_error('请选择取件时间');
+ }
+ $goods_id=json_decode($goods_id,true);
+ //寄卖数量限制
+ $jmnum =ShopConfig::get('website', 'jmnum');
+ if($jmnum>count($goods_id)){
+ return client_error('寄卖满'.$jmnum.'件才可下单');
+ }
+ $goods_ids=array();
+ foreach ($goods_id as $key => $value) {
+ $goods_id=Crypt::decrypt($value);
+ if($goods_id>0){
+ $goods_ids[]=$goods_id;
+ }
+ }
+ //寄卖数量限制
+ $jmnum =ShopConfig::get('website', 'jmnum');
+ if($jmnum>count($goods_ids)){
+ return client_error('寄卖满'.$jmnum.'件才可下单');
+ }
+ $order = ConsignmentOrder::get([
+ 'user_id' => $user_id,
+ 'id' => $order_id
+ ]);
+ if (!$order || $order['order_status']!='3') {
+ return client_error('很抱歉!订单无法进行确认估价');
+ }
+
+ $model->startTrans();
+ try {
+ //确认订单
+ $update = [
+ 'update_time' => time(),
+ 'order_status' => 4,
+ 'is_return' => $is_return,
+ 'consignee' => $consignee,
+ 'address' => $address,
+ 'mobile' => $mobile,
+ 'th_consignee' => $th_consignee,
+ 'th_address' => $th_address,
+ 'th_mobile' => $th_mobile,
+ 'takeparts_time'=>$takeparts_time
+ ];
+ $model->where(['id' => $order_id])->update($update);
+
+ $update_goods = [
+ 'is_confirm' => 1,
+ ];
+ $where_goods[]=array('id','in',$goods_ids);
+ $cogmodel->where($where_goods)->update($update_goods);
+
+ //记录日志
+ ConsignmentOrderLog::record(
+ $order_id,
+ '您确认评估价格进行寄卖'
+ );
+ $model->commit();
+ } catch (Exception $e) {
+ $model->rollback();
+ return client_error($e->getMessage());
+ }
+ return success('','确认成功');
+ }
+}
\ No newline at end of file
diff --git a/application/api/controller/PaymentController.php b/application/api/controller/PaymentController.php
new file mode 100755
index 0000000..cc9fee5
--- /dev/null
+++ b/application/api/controller/PaymentController.php
@@ -0,0 +1,106 @@
+param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $order_sn=$param['order_sn']??'';
+ if(!isset($order_sn)) {
+ return client_error('订单不存在');
+ }
+ $order = $omodel
+ ->alias('o')
+ ->field("order_status,openid")
+ ->join('user u', 'u.id = o.user_id')
+ ->where(array('order_sn'=>$order_sn,'user_id'=>$user_id))
+ ->find();
+ //找不到订单
+ if (empty($order)) {
+ return client_error('订单不存在');
+ }
+ if ($order['order_status'] !='0') {
+ return client_error('该订单无法进行支付,请查看订单状态');
+ }
+ $order_wechatsn =$order_sn.str_pad(mt_rand(1, 999), 3, '0', STR_PAD_LEFT);
+ $WXPAYKEY=ShopConfig::get('website', 'WXPAYKEY');
+ $MCHID=ShopConfig::get('website', 'MCHID');
+ $APPID=ShopConfig::get('website', 'APPID');
+ $notify_url=ShopConfig::get('website', 'notify_url');
+ $WxxiaopayApi = new WxxiaopayApi($APPID,$MCHID,$WXPAYKEY,$notify_url);
+ $log_ip=$request->ip();
+ $wxData =$WxxiaopayApi->prePay($order_sn,$order_wechatsn,$order_sn,$order['openid'],$log_ip);
+ return success($wxData);
+ }
+
+ //微信小程序回调
+ public function wxnotify(Request $request,FrontMemberLog $fmlmodel,FrontUserMember $fummodel)
+ {
+ $xml = file_get_contents('php://input', 'r');
+ $data = $this->toArray($xml);
+ Log::write('微信回调2:'.var_export($data, true));
+ if($data['result_code']==='SUCCESS' && $data['return_code']==='SUCCESS'){
+ $order_sn = mb_substr($data['out_trade_no'],0,18);
+ $parameter['transaction_id']= $data['transaction_id']; //支付宝交易号
+ $parameter['pay_time'] =time();
+ $parameter['is_pay'] =1;
+ $order_info = $fmlmodel
+ ->alias('fml')
+ ->field('fml.*,fm.days as days')
+ ->where(array('order_sn'=>$order_sn))
+ ->join('front_member fm', 'fm.id = fml.member_id')
+ ->find();
+ if($order_info){
+ $fummodel_info=$fummodel->where(array('user_id'=>$order_info['user_id'],'cid'=>$order_info['cid']))->find();
+ $days_num=(60*60*24)*$order_info['days'];
+ $data_info['end_time']=time()+$days_num;
+ if($fummodel_info){
+ $fummodel->where(array('id'=>$fummodel_info['id']))->update($data_info);
+ }else{
+ $data_info['user_id']=$order_info['user_id'];
+ $data_info['cid']=$order_info['cid'];
+ $fummodel::create($data_info);
+ }
+ $fmlmodel->where(array('order_sn'=>$order_sn))->update($parameter);
+ exit('success');
+ }
+ }
+ exit('fail');
+ }
+
+ /**
+ * 将xml转为array
+ * @param string $xml xml字符串
+ * @return array 转换得到的数组
+ */
+ public function toArray($xml) {
+ //禁止引用外部xml实体
+ libxml_disable_entity_loader(true);
+ $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/application/api/controller/UserAddressController.php b/application/api/controller/UserAddressController.php
new file mode 100755
index 0000000..b087710
--- /dev/null
+++ b/application/api/controller/UserAddressController.php
@@ -0,0 +1,84 @@
+param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $result = UserAddress::infoUserAddress($user_id);
+ return success($result);
+ }
+
+ //设置默认地址
+ public function setDefault(Request $request)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $result = UserAddress::setDefaultAddress($user_id, $param);
+ return $result ? success('','设置成功') : client_error('设置失败');
+ }
+
+ //添加收货地址
+ public function add(Request $request, UserAddressValidate $validate)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $validate_result = $validate->scene('add')->check($param);
+ if (!$validate_result) {
+ return client_error($validate->getError());
+ }
+ $result = UserAddress::addUserAddress($user_id, $param);
+ return $result ? success('','添加成功') : client_error('添加失败');
+ }
+
+ //更新收货地址
+ public function update(Request $request, UserAddressValidate $validate)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $validate_result = $validate->scene('edit')->check($param);
+ if (!$validate_result) {
+ return client_error($validate->getError());
+ }
+ $result = UserAddress::editUserAddress($user_id, $param);
+ return $result ? success('','修改成功') : client_error('修改失败');
+ }
+
+ //删除收货地址
+ public function del(Request $request, UserAddressValidate $validate)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $validate_result = $validate->scene('del')->check($param);
+ if (!$validate_result) {
+ return client_error($validate->getError());
+ }
+ $result = UserAddress::delUserAddress($user_id, $param);
+ return $result ? success('','删除成功') : client_error('删除失败');
+ }
+}
diff --git a/application/api/controller/UserController.php b/application/api/controller/UserController.php
new file mode 100755
index 0000000..b472ca2
--- /dev/null
+++ b/application/api/controller/UserController.php
@@ -0,0 +1,593 @@
+param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $user = User::where('id',$user_id)->field('avatar,nickname,user_money')->find();
+ //消息数量
+ $user->notice_num = Notice::unRead($user_id) ? 1 : 0;
+ $goods_list=$gcmodel
+ ->alias('gc')
+ ->field("mi.thumb_image as img, g.name,g.price,g.id as goods_id,gb.name as brand_name")
+ ->join('goods g', 'g.id = gc.goods_id')
+ ->join('mall_image mi', 'mi.union_id= gc.goods_id and is_cover=1 and mi.type=1', 'LEFT')
+ ->join('goods_brand gb', 'gb.id = g.brand_id')
+ ->where(array('user_id'=>$user_id))
+ ->limit(3)
+ ->order('g.sort_number asc')
+ ->select();
+ foreach ($goods_list as $k1 => $v1) {
+ $goods_list[$k1]['img'] =$this->img_url.$v1['img'];
+ $goods_list[$k1]['goods_id'] = Crypt::encrypt($v1['goods_id']);
+ }
+ $user->collect =$goods_list;
+ //联系我们
+ $user->contactus =ShopConfig::get('policy', 'contactus');
+ //社群与交流
+ $user->community =ShopConfig::get('policy', 'community');
+ //隐私政策
+ $user->privacy =ShopConfig::get('policy', 'privacy');
+ //条款与条件
+ $user->clause =ShopConfig::get('policy', 'clause');
+ return success($user);
+ }
+
+ //我的消息
+ public function notice(Request $request,Notice $nmodel)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $where[]=array('user_id','=',$user_id);
+ $where[]=array('send_type','=',1);
+ $where[]=array('receive_type','in','2,3');
+ $notice_count = $nmodel
+ ->where($where)
+ ->count();
+ $totalPages = ceil($notice_count / $size);
+ $notice_list = $nmodel
+ ->field("title,content")
+ ->where($where)
+ ->limit($page, $size)
+ ->order('create_time DESC')
+ ->select();
+ if (!$notice_list) {
+ return success(array('list'=>[]));
+ }
+ $where1[]=array('user_id','=',$user_id);
+ Notice::setRead($where1);
+ $page=array(
+ 'count'=>$notice_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$notice_list,'page'=>$page));
+ }
+
+ //我的订单
+ public function order(Request $request,Order $model)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $where[] = ['o.user_id', '=', $user_id];
+ //订单类型
+ if ($param['order_status'] != '') {
+ $where[] = ['o.order_status', 'in', $param['order_status']];
+ }
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $order_count = $model
+ ->alias('o')
+ ->join('order_goods g', 'g.order_id = o.id')
+ ->with(['order_goods'])
+ ->where($where)
+ ->order('o.id desc')
+ ->group('o.id')
+ ->count();
+ $totalPages = ceil($order_count / $size);
+ $order_list = $model
+ ->alias('o')
+ ->field('o.order_sn,o.order_status,o.id')
+ ->join('order_goods g', 'g.order_id = o.id')
+ ->with(['order_goods'])
+ ->where($where)
+ ->order('o.id desc')
+ ->group('o.id')
+ ->limit($page, $size)
+ ->select();
+ if (!$order_list) {
+ return success(array('list'=>[]));
+ }
+ foreach ($order_list as $k1 => $v1) {
+ $order_list[$k1]['order_id'] = Crypt::encrypt($v1['id']);
+ $order_list[$k1]['order_status_text'] = $v1['order_status_text'];
+ unset($v1['id']);
+ foreach ($v1['order_goods'] as &$order_goods){
+ $order_goods['goods_img']=$this->img_url.$order_goods['goods_img'];
+ $order_goods['goods_id'] = Crypt::encrypt($order_goods['goods_id']);
+ unset($order_goods['id'],$order_goods['order_id']);
+ }
+ }
+ $page=array(
+ 'count'=>$order_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$order_list,'page'=>$page));
+ }
+
+ //我的订单详情
+ public function orderdetail(Request $request,Order $model)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $order_id = $param['order_id']?Crypt::decrypt($param['order_id']):'';
+ if(!$order_id){
+ return client_error('该订单不存在');
+ }
+ $where[] = ['o.user_id', '=', $user_id];
+ $where[] = ['o.id', '=', $order_id];
+ $order_info = $model
+ ->alias('o')
+ ->field('o.order_sn,o.order_status,o.id,o.pay_time,total_amount,shipping_time,invoice_name,invoice_no,transaction_id,user_remark,confirm_take_time,cancel_time,o.create_time,province,city,district,address,mobile,consignee')
+ ->join('order_goods g', 'g.order_id = o.id')
+ ->with(['order_goods'])
+ ->append(['delivery_address'])
+ ->where($where)
+ ->find();
+ if (!$order_info) {
+ return client_error('该订单不存在');
+ }
+ $order_info['order_id'] = Crypt::encrypt($order_info['id']);
+ $order_info['order_status_text'] = $order_info['order_status_text'];
+ foreach ($order_info['order_goods'] as &$order_goods){
+ $order_goods['goods_img']=$this->img_url.$order_goods['goods_img'];
+ $order_goods['goods_id'] = Crypt::encrypt($order_goods['goods_id']);
+ unset($order_goods['id'],$order_goods['order_id']);
+ }
+ unset($order_info['id']);
+ return success($order_info);
+ }
+
+
+ /**
+ * Notes: 取消订单
+ * @param $order_id
+ * @param $user_id
+ */
+ public static function ordercancel(Request $request,Order $model)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $order_id = $param['order_id']?Crypt::decrypt($param['order_id']):'';
+ if(!$order_id){
+ return client_error('该订单不存在');
+ }
+ $order = Order::get([
+ 'user_id' => $user_id,
+ 'id' => $order_id
+ ]);
+ if (!$order || $order['order_status']!='0') {
+ return client_error('很抱歉!订单无法取消');
+ }
+
+ $model->startTrans();
+ try {
+ //取消订单
+ $update = [
+ 'cancel_time' => time(),
+ 'order_status' => 4,
+ ];
+ $model->where(['id' => $order_id])->update($update);
+ $model->commit();
+ } catch (Exception $e) {
+ $model->rollback();
+ return client_error($e->getMessage());
+ }
+ return success('','取消成功');
+ }
+
+ /**
+ * Notes: 确认收货
+ * @param $order_id
+ * @param $user_id
+ */
+ public static function orderconfirm(Request $request,Order $model)
+ {
+ $param = $request->param();
+ $user_id = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$user_id){
+ return unauthorized('请先授权');
+ }
+ $order_id = $param['order_id']?Crypt::decrypt($param['order_id']):'';
+ if(!$order_id){
+ return client_error('该订单不存在');
+ }
+ $order = Order::get([
+ 'user_id' => $user_id,
+ 'id' => $order_id
+ ]);
+ if (!$order || $order['order_status']!='2') {
+ return client_error('很抱歉!订单未发货');
+ }
+
+ $model->startTrans();
+ try {
+ //确认订单
+ $update = [
+ 'confirm_take_time' => time(),
+ 'order_status' => 3,
+ ];
+ $model->where(['id' => $order_id])->update($update);
+ $model->commit();
+ } catch (Exception $e) {
+ $model->rollback();
+ return client_error($e->getMessage());
+ }
+ return success('','确认成功');
+ }
+
+
+
+ //收益统计
+ public function profit_census(Request $request,AccountLog $almodel,WithdrawApply $wamodel,User $umodel)
+ {
+ $param = $request->param();
+ $uid = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$uid){
+ return unauthorized('请先授权');
+ }
+ $type = $param['type']??'1';
+
+ //积分规则
+ $integral_rule =ShopConfig::get('policy', 'integral_rule');
+
+ //个人收益
+ if($type==1){
+ $where[]=array('source_type','in','100,110,120');
+ $where[]=array('user_id','eq',$uid);
+ //今日收益
+ $amount_today = $almodel
+ ->where($where)
+ ->whereTime('create_time', 'today')
+ ->sum('change_amount');
+ //已提现金额
+ $amount_ytx = $wamodel->where(array('user_id'=>$uid,'status'=>2))->sum('money');
+ //可提现金额
+ $amount_ktx = $umodel->where(array('id'=>$uid))->value('integral');
+ $data=array(
+ 'amount_today'=>$amount_today,
+ 'amount_ytx'=>$amount_ytx,
+ 'amount_ktx'=>$amount_ktx,
+ 'integral_rule'=>$integral_rule,
+ );
+ return success($data);
+ }
+
+ if($type==2){
+ $where[]=array('user_id','eq',$uid);
+ //今日收益
+ $amount_today = $almodel
+ ->where($where)
+ ->where(array('source_type'=>100))
+ ->whereTime('create_time', 'today')
+ ->sum('change_amount');
+ //累计收益
+ $amount_sum = $almodel
+ ->where($where)
+ ->where(array('source_type'=>100))
+ ->sum('change_amount');
+ //推广人数
+ $user_fans =$umodel->where([['first_leader|second_leader', '=', $uid]])->count();
+ $data=array(
+ 'amount_today'=>$amount_today,
+ 'amount_sum'=>$amount_sum,
+ 'user_fans'=>$user_fans,
+ 'integral_rule'=>$integral_rule,
+ );
+ return success($data);
+ }
+ }
+
+ //提现记录
+ public function withdraw(Request $request,WithdrawApply $wamodel)
+ {
+ $param = $request->param();
+ $uid = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$uid){
+ return unauthorized('请先授权');
+ }
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $withdraw_count = $wamodel
+ ->where(array('user_id'=>$uid))
+ ->count();
+ $totalPages = ceil($withdraw_count / $size);
+ $withdraw_list = $wamodel
+ ->field("money,create_time,poundage,status")
+ ->where(array('user_id'=>$uid))
+ ->limit($page, $size)
+ ->order('create_time DESC')
+ ->select();
+ if (!$withdraw_list) {
+ return client_error('暂无数据');
+ }
+ foreach ($withdraw_list as $key => $value) {
+ $withdraw_list[$key]['status_text'] =$wamodel->STATUS_TYPE[$value['status']];
+ }
+ $page=array(
+ 'count'=>$withdraw_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$withdraw_list,'page'=>$page));
+ }
+
+ //收益记录
+ public function account_log(Request $request,AccountLog $almodel)
+ {
+ $param = $request->param();
+ $uid = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$uid){
+ return unauthorized('请先授权');
+ }
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $where[]=array('user_id','=',$uid);
+ $type = $param['type']??'';
+ if($type){
+ $where[]=array('source_type','=',$type);
+ }
+ $accountlog_count = $almodel
+ ->alias('al')
+ ->where($where)
+ ->join('user u', 'u.id= al.user_id')
+ ->count();
+ $totalPages = ceil($accountlog_count / $size);
+ $accountlog_list = $almodel
+ ->alias('al')
+ ->field("change_amount,al.create_time,source_type,avatar,nickname")
+ ->where($where)
+ ->join('user u', 'u.id= al.user_id')
+ ->limit($page, $size)
+ ->order('create_time DESC')
+ ->select();
+ if (!$accountlog_list) {
+ return client_error('暂无数据');
+ }
+ foreach ($accountlog_list as $key => $value) {
+ $accountlog_list[$key]['avatar'] =$this->img_url.$value['avatar'];
+ $accountlog_list[$key]['source_type_text'] =$almodel->SOURCE_TYPE[$value['source_type']];
+ }
+ $amount_sum = $almodel
+ ->where($where)
+ ->sum('change_amount');
+ $page=array(
+ 'count'=>$accountlog_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ return success(array('list'=>$accountlog_list,'page'=>$page,'amount_sum'=>$amount_sum));
+ }
+
+ //邀请明细
+ public function invitation_user(Request $request,User $umodel)
+ {
+ $param = $request->param();
+ $uid = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$uid){
+ return unauthorized('请先授权');
+ }
+ $size=$param['size']>0?$param['size']:12;
+ $page_l=$param['page']>1?$param['page']:1;
+ $page=$size * ($page_l - 1);
+ $user_count = $umodel
+ ->where([['first_leader|second_leader', '=', $uid]])
+ ->count();
+ $totalPages = ceil($user_count / $size);
+ $user_list = $umodel
+ ->field("create_time,avatar,nickname")
+ ->where([['first_leader|second_leader', '=', $uid]])
+ ->limit($page, $size)
+ ->order('create_time DESC')
+ ->select();
+ if (!$user_list) {
+ return client_error('暂无数据');
+ }
+ foreach ($user_list as $key => $value) {
+ $user_list[$key]['avatar'] =$this->img_url.$value['avatar'];
+ }
+ $page=array(
+ 'count'=>$user_count,
+ 'num'=>$page_l,
+ 'size'=>$size,
+ 'page'=>$totalPages
+ );
+ //推广规则
+ $extension_rule =ShopConfig::get('policy', 'extension_rule');
+ return success(array('list'=>$user_list,'page'=>$page,'extension_rule'=>$extension_rule));
+ }
+
+ //提现账户列表
+ public function account_list(Request $request,WithdrawAccount $wamodel)
+ {
+ $param = $request->param();
+ $uid = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$uid){
+ return unauthorized('请先授权');
+ }
+ $account_list=$wamodel->field('real_name,real_tel,account,subbank,type,id')->where(array('user_id'=>$uid))->select();
+ foreach ($account_list as $key => $value) {
+ $account_list[$key]['id'] = Crypt::encrypt($value['id']);
+ }
+ return success($account_list);
+ }
+
+
+ //添加提现账户
+ public function account_add(Request $request,WithdrawAccount $wamodel, WithdrawAccountValidate $validate)
+ {
+ $param = $request->param();
+ $param['user_id'] = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$param['user_id']){
+ return unauthorized('请先授权');
+ }
+ $validate_result = $validate->scene('add')->check($param);
+ if (!$validate_result) {
+ return client_error($validate->getError());
+ }
+ // 启动事务
+ $wamodel->startTrans();
+ try{
+ $wamodel::create($param);
+ // 提交事务
+ $wamodel->commit();
+ }catch(\Exception $e){
+ // 回滚事务
+ $wamodel->rollback();
+ return client_error($e->getMessage());
+ }
+ return success('','添加成功');
+ }
+
+ //删除提现账户
+ public function account_dal(Request $request,WithdrawAccount $wamodel)
+ {
+ $param = $request->param();
+ $param['user_id'] = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$param['user_id']){
+ return unauthorized('请先授权');
+ }
+ $param['id'] = $param['id']?Crypt::decrypt($param['id']):'';
+ if (!$param['id']) {
+ return client_error('账户不存在');
+ }
+ $result = $wamodel->whereIn('id', $param['id'])->delete();
+ return $result ? success('','删除成功') : client_error('删除失败');
+ }
+ //提现操作
+ public function wthdrawal(Request $request,WithdrawAccount $wamodel,WithdrawApply $waymodel,AccountLog $almodel,User $umodel)
+ {
+ $param = $request->param();
+ $uid = $param['uid']?Crypt::decrypt($param['uid']):'';
+ if(!$uid){
+ return unauthorized('请先授权');
+ }
+ //提现积分
+ $integral = $param['integral']??'0';
+ //提现账户
+ $account_id = $param['account_id']?Crypt::decrypt($param['account_id']):'';
+ if(!$account_id){
+ return client_error('请选择提现账户');
+ }
+ $account_info=$wamodel->where(array('id'=>$account_id))->find();
+ if(!$account_info){
+ return client_error('请选择提现账户');
+ }
+ $umodel_info=$umodel->field('integral')->where(array('id'=>$uid))->find();
+ if($umodel_info['integral']<$integral){
+ return client_error('积分不足,无法提现');
+ }
+ $min_withdraw =ShopConfig::get('withdraw', 'min_withdraw');//最低提现
+ $max_withdraw =ShopConfig::get('withdraw', 'max_withdraw');//最高提现积分
+ $poundage_type =ShopConfig::get('withdraw', 'poundage_type');//手续费类型 1固定 2比例
+ $poundage =ShopConfig::get('withdraw', 'poundage');//手续费
+ if($integral<$min_withdraw){
+ return client_error('最少提现积分数'.$min_withdraw.',无法提现');
+ }
+ if($integral>$max_withdraw){
+ return client_error('最多提现积分数'.$max_withdraw.',无法提现');
+ }
+ if($poundage_type==2){
+ $poundage=$integral*($poundage/100);
+ }
+ // 启动事务
+ $waymodel->startTrans();
+ try{
+
+ $data = [
+ 'sn' => createSn('withdraw_apply', 'sn'),
+ 'user_id' => $uid,
+ 'type' => $account_info['type'],
+ 'account' => $account_info['account'] ?? '',
+ 'real_name' => $account_info['real_name'] ?? '',
+ 'real_tel' => $account_info['real_tel'] ?? '',
+ 'money' => $integral,
+ 'left_money' => $integral - $poundage,
+ 'money_qr_code' => '',
+ 'subbank' => $account_info['subbank'] ?? '',
+ 'poundage' => $poundage,
+ 'status' => 1, // 待提现
+ 'create_time' => time(),
+ ];
+ $withdraw_id = $waymodel->insertGetId($data);
+ //提交申请后,扣减用户的积分
+ $user = User::get($uid);
+ $user->integral = ['dec', $integral];
+ $user->save();
+
+ //增加佣金变动记录
+ $almodel->AccountRecord(
+ $uid,
+ $integral,
+ 2,
+ 140,
+ '',
+ $withdraw_id,
+ $data['sn']
+ );
+ // 提交事务
+ $waymodel->commit();
+ }catch(\Exception $e){
+ // 回滚事务
+ $waymodel->rollback();
+ return client_error($e->getMessage());
+ }
+ return success('','提交提现申请成功,等待审核打款');
+ }
+}
diff --git a/application/api/traits/ApiAuth.php b/application/api/traits/ApiAuth.php
new file mode 100755
index 0000000..b048c75
--- /dev/null
+++ b/application/api/traits/ApiAuth.php
@@ -0,0 +1,182 @@
+ 'token',
+ //加密使用的secret
+ 'secret' => '552ac90778a976c72f7f673db174df30',
+ //颁发者
+ 'iss' => 'iss',
+ //使用者
+ 'aud' => 'aud',
+ //过期时间,以秒为单位,默认2小时
+ 'ttl' => 30*60*60*24,
+ //刷新时间,以秒为单位,默认14天,以
+ 'refresh_ttl' => 1209600,
+ //是否自动刷新,开启后可自动刷新token,附在header中返回,name为`Authorization`,字段为`Bearer `+$token
+ 'auto_refresh' => true,
+ //黑名单宽限期,以秒为单位,首次token刷新之后在此时间内原token可以继续访问
+ 'blacklist_grace_period' => 60
+ ];
+
+ protected $token;
+
+ public function jtwInit()
+ {
+ $config = config('jwt.');
+ if ($config) {
+ $this->config = $config;
+ }
+ }
+
+ /**
+ * 检查token
+ */
+ public function checkToken()
+ {
+ $config = $this->config;
+ if (!in_array($this->request->action(true), $this->authExcept)) {
+
+ $token = $this->request->header($config['name']);
+ //缺少token
+ if (empty($token)) {
+ throw new HttpResponseException(error('缺少token'));
+ }
+
+ $this->token = $token;
+ $token_verify = true;
+ $signer = new Sha256();
+ try {
+ $jwt = (new TokenParser())->parse((string)$token);
+
+ //验证成功后给当前uid赋值
+ if (true === $jwt->verify($signer, $config['secret'])) {
+ $this->uid = $jwt->getClaim('uid');
+ $exp = $jwt->isExpired();
+ //token已过期
+ if ($exp) {
+ $token_verify = false;
+ $token_verify_msg = 'token已过期';
+ //如果为自动刷新
+ if ($config['auto_refresh']) {
+ $token = $this->refreshToken();
+ $token_verify = $token;
+ }
+ }
+ } else {
+ //token错误
+ $token_verify = false;
+ $token_verify_msg = 'token错误';
+ }
+ } catch (Exception $e) {
+ //token验证过程出错
+ $token_verify = false;
+ $token_verify_msg = $e->getMessage();
+ }
+
+ //统一处理token相关错误,返回401
+ if (!$token_verify) {
+ throw new HttpResponseException(unauthorized('token验证错误,错误信息:'.$token_verify_msg));
+ }
+
+ }
+ }
+
+
+ /**
+ * 获取token
+ * @param $uid int 用户ID
+ * @param array $data 更多数据
+ * @return string
+ * @throws Exception
+ */
+ public function getToken($uid, $data = [])
+ {
+ $config = $this->config;
+ //发放token
+ $signer = new Sha256();
+ $time = time();
+ $jti = md5($time . $uid . random_int(9999, 999999));
+ $jwt = (new Builder())->issuedBy($config['iss'])//颁发者(iss claim)
+ ->permittedFor($config['aud'])//使用者(aud claim)
+ ->identifiedBy($jti)//JWT ID (jti claim)
+ ->issuedAt($time)//签发时间(iat claim)
+ ->canOnlyBeUsedAfter($time)//可使用时间(nbf claim)
+ ->expiresAt($time + $config['ttl'])//过期时间(exp claim)
+ ->withClaim('uid', $uid); //用户ID
+
+ if (count($data) > 0) {
+ foreach ($data as $key => $value) {
+ $jwt = $jwt->withClaim($key, $value);
+ }
+ }
+
+ $token = $jwt->getToken($signer, new Key($config['secret']));
+
+ return (string)$token;
+ }
+
+
+ /**
+ * 刷新token
+ * @param $data
+ * @return string
+ */
+ public function refreshToken()
+ {
+ $result = false;
+ $claim_protect = [
+ 'iss', 'aud', 'jti', 'iat', 'exp', 'nbf', 'uid'
+ ];
+
+ $time = time();
+ $jwt = (new TokenParser())->parse((string)$this->token);
+ $jti = $jwt->getClaim('jti');
+ $nbf_time = $jwt->getClaim('nbf');
+ $refresh_time = $nbf_time + $this->config['refresh_ttl'];
+
+ if ($time >= $nbf_time && $time <= $refresh_time) {
+ $blacklist_time = cache('token_blacklist_' . $jti);
+ if ($blacklist_time) {
+ $grace_period = $blacklist_time + $this->config['blacklist_grace_period'];
+ if ($time < $grace_period) {
+ $result = true;
+ }
+
+ } else {
+ //颁发新的token
+ //将过期的token存到缓存中
+ $claims = $jwt->getClaims();
+ $data = [];
+ foreach ($claims as $key => $value) {
+ $name = $value->getName();
+ if (!in_array($name, $claim_protect)) {
+ $data[$name] = $value->getValue();
+ }
+ }
+
+ $token = $this->getToken($this->uid, $data);
+ cache('token_blacklist_' . $jti, $time, $refresh_time - $time + 1);
+ header('Authorization:Bearer ' . $token);
+ $result = true;
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/application/command.php b/application/command.php
new file mode 100755
index 0000000..cbc1faa
--- /dev/null
+++ b/application/command.php
@@ -0,0 +1,14 @@
+
+// +----------------------------------------------------------------------
+
+return [
+
+];
diff --git a/application/common.php b/application/common.php
new file mode 100755
index 0000000..2939121
--- /dev/null
+++ b/application/common.php
@@ -0,0 +1,164 @@
+
+// +----------------------------------------------------------------------
+use think\facade\Env;
+use app\common\model\Order;
+use think\db;
+
+// 应用公共文件
+
+if (!function_exists('get_middle_str')) {
+ /**
+ * 获取指定字符串中间内容
+ * @param string $str 原字符串
+ * @param string $leftStr 左侧
+ * @param string $rightStr
+ * @return bool|string
+ */
+ function get_middle_str($str, $leftStr, $rightStr)
+ {
+ $left = strpos($str, $leftStr);
+ $right = strpos($str, $rightStr, $left);
+ if ($left < 0 || $right < $left) {
+ return '';
+ }
+ return substr($str, $left + strlen($leftStr), $right - $left - strlen($leftStr));
+ }
+}
+
+
+if (!function_exists('format_size')) {
+ /**
+ * 格式化文件大小单位
+ * @param $size
+ * @param string $delimiter
+ * @return string
+ */
+ function format_size($size, $delimiter = '')
+ {
+ $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
+ for ($i = 0; $size >= 1024 && $i < 5; $i++) {
+ $size /= 1024;
+ }
+ return round($size, 2) . $delimiter . $units[$i];
+ }
+}
+
+if (!function_exists('thumbnail_img')) {
+ /**
+ * 生成缩略图
+ * @param string $status 上传后图片信息
+ * @param string $width 宽
+ * @param string $heigh 高
+ */
+ function thumbnail_img($status, $width, $heigh, $folder_name = '')
+ {
+ $img = Env::get('root_path') . 'public/uploads/attachment/' . $status->getSaveName();
+ $image = \think\Image::open($img);
+ $slt = substr($img, 0, strlen($img) - 4);
+ $image->thumb($width, $heigh, \think\Image::THUMB_CENTER)->save($slt . '_' . $width . '_' . $heigh . '.' . $status->getExtension());
+ $img_url = $status->getSaveName();
+ $img_slt = '/uploads/' . $folder_name . '/' . substr($img_url, 0, strlen($img_url) - 4) . '_' . $width . '_' . $heigh . '.' . $status->getExtension();
+ return $img_slt;
+ }
+}
+
+if (!function_exists('get_order_sn')) {
+ /**
+ * 获取得到新订单编号
+ */
+ function get_order_sn()
+ {
+ mt_srand((float) microtime() * 1000000);
+ $order_sn = 'O' . date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
+ $where = 'order_no="' . $order_sn . '"';
+ //开始编辑区域
+ $_OrderModel = new Order();
+ $count = $_OrderModel->where($where)->count();
+ //结束编辑区域
+ if ($count == 0) {
+ /* 否则就使用这个订单号 */
+ return $order_sn;
+ }
+ return get_order_sn();
+ }
+}
+
+
+/**
+ * Desc: 用时间生成订单编号
+ * @param $table
+ * @param $field
+ * @param string $prefix
+ * @param int $rand_suffix_length
+ * @param array $pool
+ */
+function createSn($table, $field, $prefix = '', $rand_suffix_length = 4, $pool = [])
+{
+ $suffix = '';
+ for ($i = 0; $i < $rand_suffix_length; $i++) {
+ if (empty($pool)) {
+ $suffix .= rand(0, 9);
+ } else {
+ $suffix .= $pool[array_rand($pool)];
+ }
+ }
+ $sn = $prefix . date('YmdHis') . $suffix;
+ if (Db::name($table)->where($field, $sn)->find()) {
+ return createSn($table, $field, $prefix, $rand_suffix_length, $pool);
+ }
+ return $sn;
+}
+
+/**
+ * 生成会员码
+ * @return 会员码
+ */
+function create_user_sn($prefix = '', $length = 8)
+{
+ $rand_str = '';
+ for ($i = 0; $i < $length; $i++) {
+ $rand_str .= mt_rand(0, 9);
+ }
+ $sn = $prefix . $rand_str;
+ if (Db::name('user')->where(['sn' => $sn])->find()) {
+ return create_user_sn($prefix, $length);
+ }
+ return $sn;
+}
+
+//生成用户邀请码
+function generate_invite_code()
+{
+
+ $letter_all = range('A', 'Z');
+ shuffle($letter_all);
+ //排除I、O字母
+ $letter_array = array_diff($letter_all, ['I', 'O', 'D']);
+ //排除1、0
+ $num_array = range('2', '9');
+ shuffle($num_array);
+
+ $pattern = array_merge($num_array, $letter_array, $num_array);
+ shuffle($pattern);
+ $pattern = array_values($pattern);
+
+ $code = '';
+ for ($i = 0; $i < 6; $i++) {
+ $code .= $pattern[mt_rand(0, count($pattern) - 1)];
+ }
+
+ $code = strtoupper($code);
+ $check = Db::name('user')->where('distribution_code', $code)->find();
+ if ($check) {
+ return generate_invite_code();
+ }
+ return $code;
+}
diff --git a/application/common/common.php b/application/common/common.php
new file mode 100755
index 0000000..b3d9bbc
--- /dev/null
+++ b/application/common/common.php
@@ -0,0 +1 @@
+module()==='api'){
+
+ $header = [];
+ //处理跨域请求问题
+ if (config('api.cross_domain.allow')) {
+ $header = ['Access-Control-Allow-Origin' => '*'];
+ if (request()->isOptions()) {
+ $header = config('api.cross_domain.header');
+ return json('',200,$header);
+ }
+ }
+
+ return json([
+ 'code' => 500,
+ 'msg' => $e->getMessage(),
+ 'data' => '',
+ ], 500,$header);
+ }
+
+
+ // 其他错误交给系统处理
+ return parent::render($e);
+ }
+
+}
\ No newline at end of file
diff --git a/application/common/helper/helper.php b/application/common/helper/helper.php
new file mode 100755
index 0000000..cd71f11
--- /dev/null
+++ b/application/common/helper/helper.php
@@ -0,0 +1,24 @@
+
+ */
+
+
+if (!function_exists('get_middle_str')) {
+ /**
+ * @param $str
+ * @param $leftStr
+ * @param $rightStr
+ * @return bool|string
+ */
+ function get_middle_str($str, $leftStr, $rightStr)
+ {
+ $left = strpos($str, $leftStr);
+ $right = strpos($str, $rightStr, $left);
+ if ($right < $left || $left < 0) {
+ return '';
+ }
+ return substr($str, $left + strlen($leftStr), $right - $left - strlen($leftStr));
+ }
+}
\ No newline at end of file
diff --git a/application/common/model/AccountLog.php b/application/common/model/AccountLog.php
new file mode 100755
index 0000000..6738e5d
--- /dev/null
+++ b/application/common/model/AccountLog.php
@@ -0,0 +1,65 @@
+'系统操作',
+ '110' =>'提现退回',
+ '120' =>'提现扣除',
+ ];
+
+ public function getSourceTypeTextAttr($value, $data)
+ {
+ return $this->SOURCE_TYPE[$data['source_type']];
+ }
+
+ /**
+ * Notes:记录会员账户流水,如果变动类型是成长值,且是增加的,则调用更新会员等级方法。该方法应在添加用户账户后调用
+ * @param int $user_id 用户id
+ * @param float $amount 变动数量
+ * @param int $change_type 变动类型:1-增加;2-减少
+ * @param int $source_type 来源类型
+ * @param string $remark 说明
+ * @param string $source_id 来源id
+ * @param string $source_sn 来源单号
+ * @param string $extra 额外字段说明
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\ModelNotFoundException
+ * @throws \think\exception\DbException
+ */
+ public static function AccountRecord($user_id,$amount,$change_type,$source_type,$remark ='',$source_id ='',$source_sn='',$extra=''){
+ $user = User::get($user_id);
+ if(empty($user)){
+ return false;
+ }
+ $account_log = new AccountLog();
+ $account_log->log_sn = createSn('account_log','log_sn','',4);
+ $account_log->user_id = $user_id;
+ $account_log->source_type = $source_type;
+ $account_log->source_id = $source_id;
+ $account_log->source_sn = $source_sn;
+ $account_log->change_amount = $amount;
+ $account_log->left_amount = $user->user_money;
+ $account_log->remark = $remark;
+ $account_log->extra = $extra;
+ $account_log->change_type = $change_type;
+ $account_log->create_time = time();
+ $account_log->save();
+ return true;
+
+ }
+}
diff --git a/application/common/model/Attachment.php b/application/common/model/Attachment.php
new file mode 100755
index 0000000..2092705
--- /dev/null
+++ b/application/common/model/Attachment.php
@@ -0,0 +1,200 @@
+
+ */
+
+namespace app\common\model;
+
+use think\model\concern\SoftDelete;
+
+class Attachment extends Model
+{
+ use SoftDelete;
+
+ protected $name = 'attachment';
+ protected $autoWriteTimestamp = true;
+
+ protected $fileType = [
+ '图片' => ['jpg', 'bmp', 'png', 'jpeg', 'gif', 'svg'],
+ '文档' => ['txt', 'doc', 'docx', 'xls', 'xlsx', 'pdf'],
+ '压缩文件' => ['rar', 'zip', '7z', 'tar'],
+ '音视' => ['mp3', 'ogg', 'flac', 'wma', 'ape'],
+ '视频' => ['mp4', 'wmv', 'avi', 'rmvb', 'mov', 'mpg']
+ ];
+
+ protected $fileThumb = [
+ 'picture' => ['jpg', 'bmp', 'png', 'jpeg', 'gif', 'svg'],
+ 'txt.svg' => ['txt', 'pdf'],
+ 'pdf.svg' => ['pdf'],
+ 'word.svg' => ['doc', 'docx'],
+ 'excel.svg' => ['xls', 'xlsx'],
+ 'archives.svg' => ['rar', 'zip', '7z', 'tar'],
+ 'audio.svg' => ['mp3', 'ogg', 'flac', 'wma', 'ape'],
+ 'video.svg' => ['mp4', 'wmv', 'avi', 'rmvb', 'mov', 'mpg']
+ ];
+
+ protected function initialize()
+ {
+ $thumb_path = config('attachment.thumb_path');
+ $this->fileThumb = [
+ 'picture' => ['jpg', 'bmp', 'png', 'jpeg', 'gif', 'svg'],
+ $thumb_path . 'txt.svg' => ['txt', 'pdf'],
+ $thumb_path . 'pdf.svg' => ['pdf'],
+ $thumb_path . 'word.svg' => ['doc', 'docx'],
+ $thumb_path . 'excel.svg' => ['xls', 'xlsx'],
+ $thumb_path . 'archives.svg' => ['rar', 'zip', '7z', 'tar'],
+ $thumb_path . 'audio.svg' => ['mp3', 'ogg', 'flac', 'wma', 'ape'],
+ $thumb_path . 'video.svg' => ['mp4', 'wmv', 'avi', 'rmvb', 'mov', 'mpg']
+ ];
+ parent::initialize();
+ }
+
+ //关联后台用户
+ public function adminUser()
+ {
+ return $this->belongsTo('AdminUser', 'admin_user_id', 'id');
+ }
+
+ //关联前台用户
+ public function User()
+ {
+ return $this->belongsTo('User', 'user_id', 'id');
+ }
+
+ //格式化大小
+ public function getSizeAttr($value)
+ {
+ $units = array(' B', ' KB', ' MB', ' GB', ' TB');
+ for ($i = 0; $value >= 1024 && $i < 4; $i++) {
+ $value /= 1024;
+ }
+ return round($value, 2) . $units[$i];
+ }
+
+ //文件分类
+ public function getFileTypeAttr($value, $data)
+ {
+ $type = '其他';
+ $extension = $data['extension'];
+ foreach ($this->fileType as $name => $array) {
+ if (in_array($extension, $array)) {
+ $type = $name;
+ break;
+ }
+ }
+ return $type;
+ }
+
+
+ //文件预览
+ public function getThumbnailAttr($value, $data)
+ {
+ $thumbnail = config('attachment.thumb_path') . 'unknown.svg';
+ $extension = $data['extension'];
+ foreach ($this->fileThumb as $name => $array) {
+ if (in_array($extension, $array)) {
+ $thumbnail = $name === 'picture' ? $data['url'] : $name;
+ break;
+ }
+ }
+ return $thumbnail;
+ }
+
+ public function getFileUrlAttr($value, $data)
+ {
+ $request = request();
+ $url_pre = $request->scheme() . '://' . $request->host();
+ return $url_pre . $data['url'];
+ }
+
+
+ public function upload($name, $path = '', $validate = [], $admin_user_id = 0, $user_id = 0)
+ {
+
+ if (!$_FILES[$name]['name']) {
+ $this->error = '请选择文件';
+ return false;
+ }
+
+ $file = request()->withFiles([$name => $_FILES[$name]])->file($name);
+ if ($file) {
+ $file_path = config('attachment.path') . $path;
+ $file_url = config('attachment.url') . $path;
+ $validate = array_merge(config('attachment.validate'), $validate);
+ $info = $file->validate($validate)->move($file_path);
+ if ($info) {
+ $file_info = [
+ 'admin_user_id' => $admin_user_id,
+ 'user_id' => $user_id,
+ 'original_name' => $info->getInfo('name'),
+ 'save_name' => $info->getFilename(),
+ 'save_path' => str_replace("\\", '/', $file_path . $info->getSaveName()),
+ 'extension' => $info->getExtension(),
+ 'mime' => $info->getInfo('type'),
+ 'size' => $info->getSize(),
+ 'md5' => $info->hash('md5'),
+ 'sha1' => $info->hash(),
+ 'url' => str_replace("\\", '/', $file_url . $info->getSaveName())
+ ];
+ return self::create($file_info);
+ }
+
+ $this->error = $file->getError();
+ } else {
+ $this->error = '无法获取文件';
+ }
+ return false;
+ }
+
+
+ /**
+ * @param $name
+ * @param string $path
+ * @param array $validate
+ * @param int $admin_user_id
+ * @param int $user_id
+ * @return array|bool
+ */
+ public function uploadMulti($name, $path = '', $validate = [], $admin_user_id = 0, $user_id = 0)
+ {
+ $result = [];
+
+ $files = request()->withFiles([$name => $_FILES[$name]])->file($name);
+ if ($files) {
+ foreach ($files as $file) {
+ $file_path = config('attachment.path') . $path;
+ $file_url = config('attachment.url') . $path;
+ $validate = array_merge(config('attachment.validate'), $validate);
+ $info = $file->validate($validate)->move($file_path);
+ if ($info) {
+ $file_info = [
+ 'admin_user_id' => $admin_user_id,
+ 'user_id' => $user_id,
+ 'original_name' => $info->getInfo('name'),
+ 'save_name' => $info->getFilename(),
+ 'save_path' => str_replace("\\", '/', $file_path . $info->getSaveName()),
+ 'extension' => $info->getExtension(),
+ 'mime' => $info->getInfo('type'),
+ 'size' => $info->getSize(),
+ 'md5' => $info->hash('md5'),
+ 'sha1' => $info->hash(),
+ 'url' => str_replace("\\", '/', $file_url . $info->getSaveName())
+ ];
+ $file_item = self::create($file_info);
+ $result[] = $file_item->url;
+ }
+ $this->error = $file->getError();
+ }
+ if (count($result) > 0) {
+ return $result;
+ }
+
+ return false;
+
+ }
+
+ $this->error = '无法获取文件';
+ return false;
+ }
+}
diff --git a/application/common/model/Cart.php b/application/common/model/Cart.php
new file mode 100755
index 0000000..0a87489
--- /dev/null
+++ b/application/common/model/Cart.php
@@ -0,0 +1,23 @@
+where(array('goods_id'=>$goods_id,'spec_value'=>$item_value))->find();
+ if ($goods_num > $item_info['stock']) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/application/common/model/ConsignmentOrder.php b/application/common/model/ConsignmentOrder.php
new file mode 100755
index 0000000..89ce511
--- /dev/null
+++ b/application/common/model/ConsignmentOrder.php
@@ -0,0 +1,241 @@
+hasMany('consignment_order_goods', 'order_id', 'id');
+ }
+
+ //订单用户
+ public function user()
+ {
+ return $this->hasOne('user', 'id', 'user_id')
+ ->field('id,sn,nickname,avatar,mobile,create_time');
+ }
+ //订单流程
+ public function logs()
+ {
+ return $this->hasMany('consignment_order_log', 'order_id', 'id')->order('id desc');
+ }
+
+ /**
+ * Notes: 结算详情
+ * @param $json_value
+ * @param $user_id
+ * @return array
+ */
+ public static function info($json_value, $user_id)
+ {
+ try{
+ $goods_lists = array();
+ $total_num = 0;//商品总数量
+ foreach ($json_value as $good) {
+ $goods_lists[] = $good;
+ //订单汇总信息
+ $total_num ++;
+ }
+ if (empty($goods_lists)) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>'无商品',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ //寄卖数量限制
+ $jmnum =ShopConfig::get('website', 'jmnum');
+ if($jmnum>$total_num){
+ $data=[
+ 'code' =>0,
+ 'msg' =>'寄卖满'.$jmnum.'件才可下单',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ $result = [
+ 'goods_lists' => array_values($goods_lists),
+ ];
+ $data=[
+ 'code' =>1,
+ 'msg' =>'',
+ 'data' =>$result,
+ ];
+ return $data;
+ } catch (Exception $e) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>$e->getMessage(),
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ }
+
+
+ /**
+ * Notes: 添加订单
+ * @param $user_id
+ * @param $data
+ * @param $post
+ */
+ public static function add($user_id, $data)
+ {
+ Db::startTrans();
+ try {
+ $goods_lists = $data['goods_lists'];
+ if (empty($data['goods_lists'])) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>'无商品',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ $order = self::addOrder($user_id, $data);
+ $order_id = $order['order_id'];
+ $addOrderGoods=self::addOrderGoods($order_id, $goods_lists);
+ if($addOrderGoods['code']==0){
+ return $addOrderGoods;
+ }
+ self::addOrderAfter($order_id, $user_id, $data);
+ Db::commit();
+ $data=[
+ 'code' =>1,
+ 'msg' =>'',
+ 'data' =>$order,
+ ];
+ return $data;
+ } catch (Exception $e) {
+ Db::rollback();
+ $data=[
+ 'code' =>0,
+ 'msg' =>$e->getMessage(),
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ }
+
+
+ /**
+ * Notes: 添加订单记录
+ * @param $user_id
+ * @param $data
+ * @param $user_address
+ * @param array $extra
+ */
+ public static function addOrder($user_id, $data)
+ {
+
+ $order_data = [
+ 'order_sn' => createSn('order', 'order_sn', '', 4),
+ 'user_id' => $user_id,
+ 'order_status' =>0,
+ 'create_time' => time(),
+ ];
+ $order_id = Db::name('consignment_order')->insertGetId($order_data);
+ return [
+ 'order_id' => $order_id,
+ 'order_sn' => $order_data['order_sn'],
+ ];
+ }
+
+
+ /**
+ * Notes: 添加订单商品记录
+ * @param $order_id
+ * @param $goods_lists
+ */
+ public static function addOrderGoods($order_id, $goods_lists)
+ {
+ foreach ($goods_lists as $k1 => $good) {
+ $goods_data = [
+ 'order_id' => $order_id,
+ 'item_value' => $good['item_value'],
+ 'goods_name' => $good['goods_name'],
+ 'item_value' => $good['item_value'],
+ 'goods_price' => $good['goods_price'],
+ 'goods_img' => $good['img'][0],
+ 'brand_name' => $good['brand_name'],
+ 'phase_name' => $good['phase_name'],
+ 'class_name' => $good['class_name'],
+ 'channel_name' => $good['channel_name'],
+ 'create_time' => time(),
+ ];
+ $goods_id = Db::name('consignment_order_goods')->insertGetId($goods_data);
+ foreach ($good['img'] as $key => $value) {
+ $goods_img[] = [
+ 'type' =>2,
+ 'union_id' => $goods_id,
+ 'thumb_image' => $value,
+ 'ori_image' => $value,
+ 'create_time' => time(),
+ ];
+ }
+ }
+ Db::name('mall_image')->insertAll($goods_img);
+ $data=[
+ 'code' =>1,
+ 'msg' =>'',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+
+
+ /**
+ * Notes: 下单后操作
+ * @param $order_id
+ * @param $user_id
+ * @param $type
+ * @param $data
+ */
+ public static function addOrderAfter($order_id, $user_id, $data)
+ {
+ //记录日志
+ ConsignmentOrderLog::record(
+ $order_id,
+ '寄卖下单成功',
+ '24小时内平台估价'
+ );
+ }
+}
diff --git a/application/common/model/ConsignmentOrderGoods.php b/application/common/model/ConsignmentOrderGoods.php
new file mode 100755
index 0000000..ea6ab6f
--- /dev/null
+++ b/application/common/model/ConsignmentOrderGoods.php
@@ -0,0 +1,29 @@
+order_id = $order_id;
+ $log->remark = $remark;
+ $log->extra = $extra;
+ $log->create_time = time();
+ $log->save();
+ }
+
+}
diff --git a/application/common/model/Goods.php b/application/common/model/Goods.php
new file mode 100755
index 0000000..26adc24
--- /dev/null
+++ b/application/common/model/Goods.php
@@ -0,0 +1,43 @@
+belongsTo(GoodsCategory::class);
+ }
+
+ //关联商品尺寸
+ public function goodsItem()
+ {
+ return $this->hasMany('goods_item', 'goods_id', 'id');
+ }
+
+ //关联品牌
+ public function goodsBrand()
+ {
+ return $this->hasOne('goods_brand','id','brand_id')->field('id,name');
+ }
+}
diff --git a/application/common/model/GoodsBrand.php b/application/common/model/GoodsBrand.php
new file mode 100755
index 0000000..0033b9e
--- /dev/null
+++ b/application/common/model/GoodsBrand.php
@@ -0,0 +1,35 @@
+hasMany(Goods::class);
+ }
+
+}
diff --git a/application/common/model/GoodsCollect.php b/application/common/model/GoodsCollect.php
new file mode 100755
index 0000000..5305122
--- /dev/null
+++ b/application/common/model/GoodsCollect.php
@@ -0,0 +1,14 @@
+ $value) {
+ $data = self::where(['spec_value' => $param['size'][$key][0], 'goods_id' => $goods_id])->find();
+ if (empty($data)) {
+ self::insert(['spec_value' => $param['size'][$key][0], 'goods_id' => $goods_id, 'stock' => $param['number'][$key][0]]);
+ } else {
+ self::where(['spec_value' => $param['size'][$key][0], 'goods_id' => $goods_id])
+ ->update(['stock' =>$param['number'][$key][0]]);
+ }
+ }
+ }
+}
diff --git a/application/common/model/MallImage.php b/application/common/model/MallImage.php
new file mode 100755
index 0000000..fa13bc4
--- /dev/null
+++ b/application/common/model/MallImage.php
@@ -0,0 +1,16 @@
+
+ */
+
+namespace app\common\model;
+
+use think\db\Query;
+
+class Model extends \think\Model
+{
+ //是否字段,使用场景:用户的是否冻结,文章是否为热门等等。
+ const BOOLEAN_TEXT = [0 => '否', 1 => '是'];
+ //用户等级
+ const LEVL_TEXT = [1 => '普通会员'];
+ //订单状态
+ const ORDER_TEXT = [0 => '待付款', 1=> '待发货',2=> '待收货',3=> '已完成',4=> '已取消'];
+ //寄卖状态
+ const JMORDER_TEXT = [0 => '审核中', 1=> '待上架',2=> '已上架',3=> '待客户确认',4=> '客户已确认',5=> '已取货',6=> '部分退回','7'=>'全部退回','8'=>'已取消'];
+ //寄卖商品信息
+ const JMORDER_GOODS_TEXT = [0 => '审核中', 1=> '同意',2=> '驳回',3=> '退还','4'=>'上架'];
+
+ //是否为软删除
+ public $softDelete = true;
+
+ //软删除字段默认值
+ protected $defaultSoftDelete = 0;
+
+ //可搜索字段
+ protected $searchField = [];
+
+ //可作为条件的字段
+ protected $whereField = [];
+
+ //禁止删除的数据id
+ public $noDeletionId = [
+ 1,2,3,4,5,6,7,8
+ ];
+
+ /**
+ * 查询处理
+ * @var Query $query
+ * @var array $param
+ */
+ public function scopeWhere($query, $param)
+ {
+ //关键词like搜索
+ $keywords = $param['_keywords'] ?? '';
+ if (!empty($keywords) && count($this->searchField) > 0) {
+ $this->searchField = implode('|', $this->searchField);
+ $query->where($this->searchField, 'like', '%' . $keywords . '%');
+ }
+
+ //字段条件查询
+ if (count($this->whereField) > 0 && count($param) > 0) {
+ foreach ($param as $key => $value) {
+ if (!empty($value) && in_array($key, $this->whereField)) {
+ $query->where($key, $value);
+ }
+ }
+ }
+
+ //排序
+ $order = $param['_order'] ?? '';
+ $by = $param['_by'] ?? 'desc';
+ $query->order($order ?: 'id', $by ?: 'desc');
+ }
+
+}
diff --git a/application/common/model/Notice.php b/application/common/model/Notice.php
new file mode 100755
index 0000000..6e5dd44
--- /dev/null
+++ b/application/common/model/Notice.php
@@ -0,0 +1,198 @@
+find();
+ if (empty($scene_info)) {
+ throw new Exception('信息错误');
+ }
+ $scene_info['system_notice']=json_decode($scene_info['system_notice'],true);
+ $scene_info['sms_notice']=json_decode($scene_info['sms_notice'],true);
+ $scene_info['oa_notice']=json_decode($scene_info['oa_notice'],true);
+ $scene_info['mnp_notice']=json_decode($scene_info['mnp_notice'],true);
+ $params = self::mergeParams($params);
+ //发送系统消息
+ if (isset($scene_info['system_notice']['status']) && $scene_info['system_notice']['status'] == 1) {
+ $content = self::contentFormat($scene_info['system_notice']['content'], $params);
+ self::addNoticeLog($params, $scene_info,1, $content);
+ }
+
+ //发送短信记录
+ if (isset($scene_info['sms_notice']['status']) && $scene_info['sms_notice']['status'] == 1) {
+
+ }
+
+ //发送公众号记录
+ if (isset($scene_info['oa_notice']['status']) && $scene_info['oa_notice']['status'] == 1) {
+ //(new WxMessageServer($user_id,Client_::oa))->send($params);
+ }
+
+ //发送小程序记录
+ if (isset($scene_info['mnp_notice']['status']) && $scene_info['mnp_notice']['status'] == 1) {
+ //echo 22;
+ //(new WxMessageServer($user_id, Client_::mnp))->send($params);
+ }
+ }
+
+
+ /**
+ * Notes: 拼装额外参数
+ * @param $params
+ */
+ public static function mergeParams($params)
+ {
+ //订单相关信息
+ if (!empty($params['order_id'])) {
+ $order = Db::name('order')->where(['id' => $params['order_id']])->find();
+ $order_goods = Db::name('order_goods')->alias('og')
+ ->field('g.name')
+ ->join('goods g', 'og.goods_id = g.id')
+ ->where('og.order_id', $params['order_id'])
+ ->find();
+
+ $goods_name = $order_goods['name'] ?? '商品';
+ if (mb_strlen($goods_name) > 8 ) {
+ $goods_name = mb_substr($goods_name,0,8) . '..';
+ }
+ $params['goods_name'] = $goods_name;
+ $params['order_sn'] = $order['order_sn'];
+ $params['time'] = date('Y-m-d H:i', $order['create_time']);
+ $params['total_num'] = $order['total_num'];
+ $params['order_amount'] = $order['order_amount'];
+ $order_id=Crypt::encrypt($params['order_id']);
+ }
+ //寄卖订单相关信息
+ if (!empty($params['jm_order_id'])) {
+ $order = Db::name('consignment_order')->where(['id' => $params['jm_order_id']])->find();
+ $order_goods = Db::name('consignment_order_goods')
+ ->field('goods_name')
+ ->where('order_id', $params['jm_order_id'])
+ ->find();
+
+ $goods_name = $order_goods['goods_name'] ?? '商品';
+ if (mb_strlen($goods_name) > 8 ) {
+ $goods_name = mb_substr($goods_name,0,8) . '..';
+ }
+ $params['goods_name'] = $goods_name;
+ $params['order_sn'] = $order['order_sn'];
+ $params['time'] = date('Y-m-d H:i', $order['create_time']);
+ $order_id=Crypt::encrypt($params['jm_order_id']);
+ }
+ //用户相关信息
+ if (!empty($params['user_id'])) {
+ $user = Db::name('user')->where('id', $params['user_id'])->find();
+ $params['nickname'] = $user['nickname'];
+ }
+
+ //跳转路径
+ $jump_path = NoticeSetting::getPathByScene($params['scene'], $order_id ?? 0);
+ $params['url'] = $jump_path['url'];
+ $params['page'] = $jump_path['page'];
+ return $params;
+ }
+
+
+ //格式化消息内容(替换文本)
+ public static function contentFormat($content, $params)
+ {
+ foreach ($params as $k => $v) {
+ $search_replace = '{'.$k.'}';
+ $content = str_replace($search_replace, $v, $content);
+ }
+ return $content;
+ }
+
+ //添加通知记录
+ public static function addNoticeLog($params, $scene_info, $send_type, $content, $extra = '')
+ {
+ return Db::name('notice')->insertGetId([
+ 'user_id' => $params['user_id'] ?? 0,
+ 'title' => self::getTitleByScene($send_type, $scene_info),
+ 'content' => $content,
+ 'scene' => $params['scene'],
+ 'receive_type' => self::getReceiveTypeByScene($params['scene']),
+ 'send_type' => $send_type,
+ 'extra' => $extra,
+ 'create_time' => time()
+ ]);
+ }
+
+ //根据不同发送类型获取标题
+ public static function getTitleByScene($send_type, $scene_info)
+ {
+ $title = '';
+ switch ($send_type) {
+ case NoticeSetting::SYSTEM_NOTICE:
+ $title = $scene_info['system_notice']['title'] ?? '';
+ break;
+ case NoticeSetting::SMS_NOTICE:
+ $title = '';
+ break;
+ case NoticeSetting::OA_NOTICE:
+ $title = $scene_info['oa_notice']['name'] ?? '';
+ break;
+ case NoticeSetting::MNP_NOTICE:
+ $title = $scene_info['mnp_notice']['name'] ?? '';
+ break;
+ }
+ return $title;
+ }
+
+
+ //根据场景返回当前接收对象
+ public static function getReceiveTypeByScene($scene)
+ {
+ if (in_array($scene, NoticeSetting::NOTICE_PLATFORM_SCENE)) {
+ return NoticeSetting::NOTICE_PLATFORM;
+ }
+
+ if (in_array($scene, NoticeSetting::NOTICE_USER_SCENE)) {
+ return NoticeSetting::NOTICE_USER;
+ }
+
+ if (in_array($scene, NoticeSetting::NOTICE_OTHER_SCENE)) {
+ return NoticeSetting::NOTICE_OTHER;
+ }
+ }
+
+ //更新为已读
+ public static function setRead($where)
+ {
+ //进入列表后全部已读
+ Db::name('notice')
+ ->where($where)
+ ->where('read','<>', 1)
+ ->update(['read' => 1]);
+ }
+
+ //是否有未读的消息
+ public static function unRead($user_id)
+ {
+ $un_read = Db::name('notice')
+ ->where(['user_id' => $user_id, 'read' => 0])
+ ->where(['send_type' =>1])
+ ->find();
+ if ($un_read){
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/application/common/model/NoticeSetting.php b/application/common/model/NoticeSetting.php
new file mode 100755
index 0000000..e157739
--- /dev/null
+++ b/application/common/model/NoticeSetting.php
@@ -0,0 +1,112 @@
+ $url, 'page' => $page];
+ }
+
+}
diff --git a/application/common/model/Order.php b/application/common/model/Order.php
new file mode 100755
index 0000000..f6ef089
--- /dev/null
+++ b/application/common/model/Order.php
@@ -0,0 +1,340 @@
+hasMany(OrderGoods::class, 'order_id', 'id')->field('goods_id,item_value,goods_name,goods_img,brand_name,goods_num,goods_price,total_price,order_id,id');
+ }
+
+ //订单用户
+ public function user()
+ {
+ return $this->hasOne('user', 'id', 'user_id')
+ ->field('id,sn,nickname,avatar,mobile,create_time');
+ }
+
+ //收货地址
+ public function getDeliveryAddressAttr($value, $data)
+ {
+ $region = Db::name('dev_region')
+ ->where('id', 'IN', [$data['province'], $data['city'], $data['district']])
+ ->order('level asc')
+ ->column('name');
+
+ $region_desc = implode('', $region);
+ return $region_desc . $data['address'];
+ }
+
+
+ /**
+ * Notes: 发货操作
+ * @param $data
+ */
+ public static function delivery_handle($data)
+ {
+ $order_id = $data['order_id'];
+ $order = Order::get(['id' => $order_id], ['order_goods']);
+ if ($order['invoice_no']){
+ return true;
+ }
+ //更新订单下商品的发货状态
+ $order->update_time = time();
+ $order->shipping_time = time();
+ $order->order_status = 2;
+ $order->invoice_name = $data['invoice_name'];
+ $order->invoice_no = $data['invoice_no'];
+ $order->save();
+ $data_info=[
+ 'user_id' => $order['user_id'],
+ 'order_id' => $order['id'],
+ 'scene' =>101,
+ 'shipping_name' => $data['invoice_name'],
+ 'invoice_no' => $data['invoice_no'],
+ 'time' => date('Y-m-d H:i:s')
+ ];
+ Notice::noticeByScene($order['user_id'],$data_info);
+ }
+
+
+ /**
+ * Notes: 结算详情
+ * @param $post
+ * @param $user_id
+ * @return array
+ */
+ public static function info($post, $user_id)
+ {
+ try{
+ $goods =Db::name('cart')
+ ->alias('c')
+ ->field("mi.thumb_image as goods_img,g.name as goods_name,g.price as goods_price,g.id as goods_id,gb.name as brand_name,c.goods_num,item_value,g.status,g.stock,g.original_price")
+ ->join('goods g', 'g.id = c.goods_id')
+ ->join('goods_brand gb', 'gb.id= g.brand_id')
+ ->join('mall_image mi', 'mi.union_id= c.goods_id and is_cover=1 and mi.type=1', 'LEFT')
+ ->where(array('c.user_id'=>$user_id,'selected'=>1))
+ ->select();
+ $goods_lists = array();
+ $total_num = 0;//商品总数量
+ $total_goods_price = 0;//商品总金额
+ foreach ($goods as $good) {
+ $good['sub_price'] = round($good['goods_price'] * $good['goods_num'], 2);
+ $goods_item=Db::name('goods_item')->where(array('spec_value'=>$good['item_value'],'goods_id'=>$good['goods_id']))->find();
+ $good['stock'] =$goods_item['stock'];
+ $goods_lists[] = $good;
+ //订单汇总信息
+ $total_num += $good['goods_num'];
+ $total_goods_price += $good['goods_price'] * $good['goods_num'];
+ }
+ if (empty($goods_lists)) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>'购物车无商品',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ //用户地址
+ $user_address = UserAddress::getOrderUserAddress($post, $user_id);
+
+ //订单金额
+ $total_amount = $total_goods_price;
+ //订单应付金额
+ $order_amount = $total_goods_price;
+
+
+ if ($order_amount <= 0){
+ $order_amount = 0;
+ }
+ $result = [
+ 'goods_lists' => array_values($goods_lists),
+ 'total_num' => $total_num,//订单总数量
+ 'total_goods_price' => round($total_goods_price, 2),//订单商品总价
+ 'total_amount' => round($total_amount, 2),//订单总价(商品价格,运费,优惠券等)
+ 'order_amount' => round($order_amount, 2),//订单应付价格
+ 'address' => $user_address,
+ 'remark' => $post['remark'] ?? '',
+ ];
+ $data=[
+ 'code' =>1,
+ 'msg' =>'',
+ 'data' =>$result,
+ ];
+ return $data;
+ } catch (Exception $e) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>$e->getMessage(),
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ }
+
+ /**
+ * Notes: 添加订单
+ * @param $user_id
+ * @param $data
+ * @param $post
+ */
+ public static function add($user_id, $data, $post)
+ {
+ Db::startTrans();
+ try {
+ $goods_lists = $data['goods_lists'];
+ if (empty($data['goods_lists'])) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>'购物车无商品',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ $user_address = $data['address'];
+ $user = User::get($user_id);
+ if (empty($data['address'])) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>'请选择收货地址',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ $order = self::addOrder($user_id, $data, $user_address);
+ $order_id = $order['order_id'];
+ $addOrderGoods=self::addOrderGoods($order_id, $goods_lists);
+ if($addOrderGoods['code']==0){
+ return $addOrderGoods;
+ }
+ self::addOrderAfter($order_id, $user_id, $data);
+
+ Db::commit();
+ $data=[
+ 'code' =>1,
+ 'msg' =>'',
+ 'data' =>$order,
+ ];
+ return $data;
+ } catch (Exception $e) {
+ Db::rollback();
+ $data=[
+ 'code' =>0,
+ 'msg' =>$e->getMessage(),
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ }
+
+ /**
+ * Notes: 添加订单记录
+ * @param $user_id
+ * @param $data
+ * @param $user_address
+ * @param array $extra
+ */
+ public static function addOrder($user_id, $data, $user_address)
+ {
+
+ $order_data = [
+ 'order_sn' => createSn('order', 'order_sn', '', 4),
+ 'user_id' => $user_id,
+ 'consignee' => $user_address['contact'],
+ 'province' => $user_address['province_id'],
+ 'city' => $user_address['city_id'],
+ 'district' => $user_address['district_id'],
+ 'address' => $user_address['address'],
+ 'mobile' => $user_address['telephone'],
+ 'total_goods_price' => $data['total_goods_price'],
+ 'order_amount' => $data['order_amount'],//应付金额
+ 'total_amount' => $data['total_amount'],//订单总金额
+ 'total_num' => $data['total_num'],//订单商品数量
+ 'user_remark' => $data['remark'],
+ 'create_time' => time(),
+ ];
+ $order_id = Db::name('order')->insertGetId($order_data);
+ return [
+ 'order_id' => $order_id,
+ 'order_sn' => $order_data['order_sn'],
+ 'order_amount' => $order_data['order_amount'],
+ ];
+ }
+
+ /**
+ * Notes: 添加订单商品记录
+ * @param $order_id
+ * @param $goods_lists
+ */
+ public static function addOrderGoods($order_id, $goods_lists)
+ {
+ foreach ($goods_lists as $k1 => $good) {
+ //商品验证
+ if ($good['status'] != 1) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>'包含不存在或已下架的商品,无法下单',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ if ($good['goods_num'] > $good['stock']) {
+ $data=[
+ 'code' =>0,
+ 'msg' =>'商品库存不足,无法下单',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+ $goods_data[] = [
+ 'order_id' => $order_id,
+ 'goods_id' => $good['goods_id'],
+ 'goods_img' => $good['goods_img'],
+ 'item_value' => $good['item_value'],
+ 'brand_name' => $good['brand_name'],
+ 'goods_name' => $good['goods_name'],
+ 'goods_num' => $good['goods_num'],
+ 'goods_price' => $good['goods_price'],//商品价格单价(未扣减优惠和积分价格)
+ 'total_price' => $good['goods_price'] * $good['goods_num'],
+ 'original_price' => $good['original_price'] ?? 0,//商品原始价格
+ 'create_time' => time(),
+ ];
+ }
+ Db::name('order_goods')->insertAll($goods_data);
+ $data=[
+ 'code' =>1,
+ 'msg' =>'',
+ 'data' =>'',
+ ];
+ return $data;
+ }
+
+
+ /**
+ * Notes: 下单后操作
+ * @param $order_id
+ * @param $user_id
+ * @param $type
+ * @param $data
+ */
+ public static function addOrderAfter($order_id, $user_id, $data)
+ {
+ $goods_data = $data['goods_lists'];
+
+ //下单时扣减商品库存
+ OrderGoods::decStock($goods_data);
+
+ //删除购物车商品
+ $cart_items = array_column($goods_data, 'item_value');
+ Db::name('cart')->where([
+ ['user_id', '=', $user_id],
+ ['selected', '=', 1],
+ ['item_value', 'in', $cart_items],
+ ])->delete();
+ }
+}
diff --git a/application/common/model/OrderGoods.php b/application/common/model/OrderGoods.php
new file mode 100755
index 0000000..e378200
--- /dev/null
+++ b/application/common/model/OrderGoods.php
@@ -0,0 +1,71 @@
+ $good) {
+ $item_value = $good['item_value'];
+ //扣除库存,扣除规格库存,增加商品销量
+ Db::name('goods')
+ ->where('id', $good['goods_id'])
+ ->update([
+ 'order_num' => Db::raw("order_num+" . $good['goods_num']),
+ 'stock' => Db::raw('stock-' . $good['goods_num'])
+ ]);
+ //扣除规格表库存
+ Db::name('goods_item')
+ ->where(array('goods_id'=>$good['goods_id'],'spec_value'=>$good['item_value']))
+ ->setDec('stock', $good['goods_num']);
+ $goods_ids[] = $good['goods_id'];
+ }
+ //下架商品总库存为0的商品
+ if (!empty($goods_ids)){
+ self::outGoods($goods_ids);
+ }
+ }
+
+ /**
+ * Notes: 下单后下架商品总库存为0的商品
+ * @param $goods_id
+ */
+ public static function outGoods($goods_ids)
+ {
+ try{
+ $goods = Db::name('goods')
+ ->field('id, stock')
+ ->where('id', 'in', $goods_ids)
+ ->select();
+ if (empty($goods)){
+ return true;
+ }
+ $need_handle_ids = [];
+ foreach ($goods as $good) {
+ if ($good['stock'] <= 0) {
+ $need_handle_ids[] = $good['id'];
+ }
+ }
+ if (empty($need_handle_ids)){
+ return true;
+ }
+ //下架订单商品中 商品总库存已为0的商品
+ Db::name('goods')->where('id', 'in', $need_handle_ids)->update(['status' => 0]);
+ } catch (\Exception $e) {}
+
+ }
+}
diff --git a/application/common/model/PhaseConfig.php b/application/common/model/PhaseConfig.php
new file mode 100755
index 0000000..b342019
--- /dev/null
+++ b/application/common/model/PhaseConfig.php
@@ -0,0 +1,25 @@
+ $type, 'name' => $name])
+ ->find();
+ if (empty($data)) {
+ self::insert(['type' => $type, 'name' => $name, 'value' => $value]);
+ } else {
+ self::where(['type' => $type, 'name' => $name])
+ ->update(['value' => $value, 'update_time' => $update_time]);
+ }
+ return $original;
+ }
+
+ /**
+ * Desc: 获取配置值
+ * @param $type
+ * @param $name
+ * @param string $default_value
+ * @return mixed|string
+ */
+ public static function get($type, $name = '', $default_value = null)
+ {
+ $value = self::where(['type' => $type, 'name' => $name])->value('value');
+ $json = json_decode($value, true);
+ if (json_last_error() === JSON_ERROR_NONE) {
+ $value = $json;
+ }
+ if ($value) {
+ return $value;
+ }
+ }
+}
diff --git a/application/common/model/Slide.php b/application/common/model/Slide.php
new file mode 100755
index 0000000..c3534c5
--- /dev/null
+++ b/application/common/model/Slide.php
@@ -0,0 +1,62 @@
+ 1, 'name' => '商品'],
+ ['id' => 3, 'name' => '网址'],
+ ];
+
+ public $BannerList = [
+ ['bm' => 'carousel', 'name' => '首页轮播图','cc'=>'750*500'],
+ ['bm' => 'merchant', 'name' => '首页精品推荐','cc'=>'710*289'],
+ ['bm' => 'goods', 'name' => '产品列表','cc'=>'710*240'],
+ ];
+
+
+ public function getJumpTypeTextAttr($value, $data)
+ {
+ $result = '--';
+ foreach ($this->jumpType as $item) {
+ if ($data['jump_type'] == $item['id']) {
+ $result = $item['name'];
+ break;
+ }
+ }
+
+ return $result;
+ }
+
+ public function getJumpTargetTextAttr($value, $data)
+ {
+ $result = '--';
+ switch ($data['jump_type']) {
+ case 1:
+ $result = Goods::where('id', $data['jump_target'])->value('name');
+ break;
+ case 3:
+ $result = $data['jump_target'];
+ break;
+ default:
+ break;
+ }
+
+ return $result;
+ }
+
+}
diff --git a/application/common/model/User.php b/application/common/model/User.php
new file mode 100755
index 0000000..4f1e190
--- /dev/null
+++ b/application/common/model/User.php
@@ -0,0 +1,118 @@
+belongsTo(UserLevel::class);
+ }
+
+ public static function getUserInfo($userId)
+ {
+ $user = self::field('id,sn,nickname,avatar,mobile')->findOrEmpty($userId)->toArray();
+ if (empty($user)) {
+ return '系统';
+ }
+ return $user;
+ }
+
+ /**
+ * 填写邀请码
+ * @param $code
+ * @param $my_id
+ * @return bool|string
+ */
+ public static function code($code, $my_id)
+ {
+ $my_leader = Db::name('user')
+ ->field(['id', 'first_leader', 'second_leader', 'ancestor_relation'])
+ ->where(['distribution_code' => $code])
+ ->find();
+
+ //更新我的第一上级、第二上级、关系链
+ $my_leader_id = $my_leader['id'];
+ $my_first_leader = $my_leader['first_leader'];
+ $my_leader['ancestor_relation'] = boolval($my_leader['ancestor_relation']) ? $my_leader['ancestor_relation'] : '';
+ $my_ancestor_relation = trim("{$my_leader_id},{$my_leader['ancestor_relation']}", ',');
+
+ $user = User::findOrEmpty($my_id);
+ // 旧关系链
+ if (!empty($user->ancestor_relation)) {
+ $old_ancestor_relation = $user->id . ',' .$user->ancestor_relation;
+ } else {
+ $old_ancestor_relation = $user->id;
+ }
+
+ $data = [
+ 'first_leader' => $my_leader_id,
+ 'second_leader' => $my_first_leader,
+ 'ancestor_relation' => $my_ancestor_relation,
+ ];
+ Db::name('user')
+ ->where(['id' => $my_id])
+ ->update($data);
+
+ //更新我向下一级的第二上级
+ $data = [
+ 'second_leader' => $my_leader_id,
+ ];
+ Db::name('user')
+ ->where(['first_leader' => $my_id])
+ ->update($data);
+
+ //更新与我相关的所有关系链
+ Db::name('user')
+ ->where("find_in_set({$my_id},ancestor_relation)")
+ ->exp('ancestor_relation', "replace(ancestor_relation,'{$old_ancestor_relation}','" . trim("{$my_id},{$my_ancestor_relation}", ',') . "')")
+ ->update();
+ }
+
+
+ //用户登录
+ public static function login($param)
+ {
+ $username = $param['username'];
+ $password = $param['password'];
+ $user = self::get(['username' => $username]);
+ if (!$user) {
+ exception('用户不存在');
+ }
+
+ if (!password_verify($password, $user->password)) {
+ exception('密码错误');
+ }
+
+ if ((int)$user->status !== 1) {
+ exception('用户被冻结');
+ }
+ return $user;
+ }
+}
diff --git a/application/common/model/UserAddress.php b/application/common/model/UserAddress.php
new file mode 100755
index 0000000..512ed8e
--- /dev/null
+++ b/application/common/model/UserAddress.php
@@ -0,0 +1,221 @@
+where(['user_id'=>$user_id])
+ ->field('id,contact,telephone,province_id,city_id,district_id,address,is_default')
+ ->select();
+ foreach ($info as &$item) {
+ $item['province'] = self::getAddress($item['province_id']);
+ $item['city'] = self::getAddress($item['city_id']);
+ $item['district'] = self::getAddress($item['district_id']);
+ }
+ return $info;
+ }
+
+ /**
+ * 获取默认地址
+ * @param $user_id
+ */
+ public static function getDefaultAddress($user_id){
+ $info = Db::name('user_address')
+ ->where(['is_default'=>1,'user_id'=>$user_id])
+ ->field('id,contact,telephone,province_id,city_id,district_id,address,is_default')
+ ->find();
+ if (!$info){
+ return [];
+ }
+ $info['province'] = self::getAddress($info['province_id']);
+ $info['city'] = self::getAddress($info['city_id']);
+ $info['district'] = self::getAddress($info['district_id']);
+
+ return $info;
+ }
+
+ /**
+ * 设置默认地址
+ * @param $user_id
+ * @param $post
+ * @return int|string
+ */
+ public static function setDefaultAddress($user_id,$post){
+ Db::startTrans();
+ try {
+ Db::name('user_address')
+ ->where(['user_id'=>$user_id])
+ ->update(['is_default'=>0]);
+
+ $result = Db::name('user_address')
+ ->where(['id'=>$post['id'],'user_id'=>$user_id])
+ ->update(['is_default'=>1]);
+ Db::commit();
+ } catch (Exception $e) {
+ Db::rollback();
+ return false;
+ }
+ return $result;
+ }
+
+
+ /**
+ * 添加收货地址
+ * @param $user_id
+ * @param $post
+ * @return int|string
+ */
+ public static function addUserAddress($user_id,$post) {
+ Db::startTrans();
+ try {
+ if ($post['is_default'] == 1){
+ Db::name('user_address')
+ ->where(['user_id'=>$user_id])
+ ->update(['is_default'=>0]);
+ }else{
+ $is_first = Db::name('user_address')
+ ->where(['user_id'=>$user_id])
+ ->select();
+ if (empty($is_first)){
+ $post['is_default'] = 1;
+ }
+ }
+ $data = [
+ 'user_id' => $user_id,
+ 'contact' => $post['contact'],
+ 'telephone' => $post['telephone'],
+ 'province_id' => $post['province_id'],
+ 'city_id' => $post['city_id'],
+ 'district_id' => $post['district_id'],
+ 'address' => $post['address'],
+ 'is_default' => $post['is_default'],
+ 'create_time' => time()
+ ];
+ $result = Db::name('user_address')->insert($data);
+ Db::commit();
+ } catch (Exception $e) {
+ Db::rollback();
+ return false;
+ }
+ return $result;
+ }
+
+
+ /**
+ * 编辑用户地址
+ * @param $user_id
+ * @param $post
+ */
+ public static function editUserAddress($user_id,$post) {
+ Db::startTrans();
+ try {
+ if ($post['is_default'] == 1){
+ Db::name('user_address')
+ ->where(['user_id'=>$user_id])
+ ->update(['is_default'=>0]);
+ }
+ $data = [
+ 'contact' => $post['contact'],
+ 'telephone' => $post['telephone'],
+ 'province_id' => $post['province_id'],
+ 'city_id' => $post['city_id'],
+ 'district_id' => $post['district_id'],
+ 'address' => $post['address'],
+ 'is_default' => $post['is_default'],
+ 'update_time' => time()
+ ];
+ $result = Db::name('user_address')
+ ->where(['id'=>$post['id'],'user_id'=>$user_id])
+ ->update($data);
+ Db::commit();
+ } catch (Exception $e) {
+ Db::rollback();
+ return false;
+ }
+ return $result;
+ }
+
+ /**
+ * 删除用户地址
+ * @param $user_id
+ * @param $post
+ */
+ public static function delUserAddress($user_id,$post) {
+ return Db::name('user_address')->where(['id'=>$post['id'],'user_id'=>$user_id])->delete();
+ }
+
+
+ /**
+ * Desc: 获取用户指定id的地址
+ * @param $address
+ * @param $user_id
+ */
+ public static function getUserAddressById($address, $user_id)
+ {
+ $info = Db::name('user_address')
+ ->where(['id' => $address, 'user_id' => $user_id])
+ ->field('id,contact,telephone,province_id,city_id,district_id,address,is_default')
+ ->find();
+
+ if (!$info) {
+ return [];
+ }
+
+ $info['province'] = self::getAddress($info['province_id']);
+ $info['city'] = self::getAddress($info['city_id']);
+ $info['district'] = self::getAddress($info['district_id']);
+
+ return $info;
+ }
+
+
+ //获取订单用户地址
+
+ /**
+ * Desc: 获取下单时用户地址
+ * @param $data
+ * @param $user_id
+ */
+ public static function getOrderUserAddress($data, $user_id)
+ {
+ if (isset($data['address_id']) && $data['address_id'] != 0){
+ return self::getUserAddressById($data['address_id'], $user_id);
+ }
+ return self::getDefaultAddress($user_id);
+ }
+
+ /**
+ * 通过id获取地址
+ * @param $val(为非数组,返回单独地点名,为数组时,按顺序拼接地址返回)
+ * @param string $address val为数组时,连接详细地址一起返回
+ * @return mixed|string
+ */
+ public static function getAddress($val, $address = '')
+ {
+ $area_id_name = Db::name('dev_region')->column('name', 'id');
+ if (!is_array($val)) {
+ return isset($area_id_name[$val]) ? $area_id_name[$val] : '';
+ }
+ $long_address = '';
+ foreach ($val as $id) {
+ $long_address .= isset($area_id_name[$id]) ? $area_id_name[$id] : '';
+ }
+ return $long_address . $address;
+ }
+}
diff --git a/application/common/model/UserLevel.php b/application/common/model/UserLevel.php
new file mode 100755
index 0000000..cd5830a
--- /dev/null
+++ b/application/common/model/UserLevel.php
@@ -0,0 +1,33 @@
+hasMany(User::class);
+ }
+
+
+}
diff --git a/application/common/model/WithdrawAccount.php b/application/common/model/WithdrawAccount.php
new file mode 100755
index 0000000..5071b1c
--- /dev/null
+++ b/application/common/model/WithdrawAccount.php
@@ -0,0 +1,15 @@
+'支付宝',
+ '2' =>'微信',
+ '3' =>'银行卡',
+ ];
+
+ public $STATUS_TYPE = [
+ '1' =>'待提现',
+ '2' =>'提现成功',
+ '3' =>'提现失败',
+ ];
+
+ public function getTypeTextAttr($value, $data)
+ {
+ return $this->WITHDRAW_TYPE[$data['type']];
+ }
+ //状态:1-待提现2-提现中3-提现成功4-提现失败获取器
+ public function getStatusTextAttr($value, $data)
+ {
+ return $this->STATUS_TYPE[$data['status']];
+ }//支付时间获取器
+ public function getPaymentTimeAttr($value)
+ {
+ return date('Y-m-d H:i:s',$value);
+ }
+
+ //支付时间修改器
+ public function setPaymentTimeAttr($value)
+ {
+ return strtotime($value);
+ }//转账时间获取器
+ public function getTransferTimeAttr($value)
+ {
+ return date('Y-m-d H:i:s',$value);
+ }
+
+ //转账时间修改器
+ public function setTransferTimeAttr($value)
+ {
+ return strtotime($value);
+ }//重新支付时间获取器
+ public function getRepayTimeAttr($value)
+ {
+ return date('Y-m-d H:i:s',$value);
+ }
+
+ //重新支付时间修改器
+ public function setRepayTimeAttr($value)
+ {
+ return strtotime($value);
+ }
+}
diff --git a/application/common/validate/AccountLogValidate.php b/application/common/validate/AccountLogValidate.php
new file mode 100755
index 0000000..d744299
--- /dev/null
+++ b/application/common/validate/AccountLogValidate.php
@@ -0,0 +1,46 @@
+ 'require',
+ 'user_id|用户id' => 'require',
+ 'source_type|来源类型' => 'require',
+ 'source_id|来源id' => 'require',
+ 'source_sn|来源单号' => 'require',
+ 'change_amount|变动总数' => 'require',
+ 'left_amount|剩余总数' => 'require',
+ 'remark|说明' => 'require',
+ 'extra|额外的字段说明' => 'require',
+ 'change_type|1-增加;2-减少' => 'require',
+
+ ];
+
+ protected $message = [
+ 'log_sn.require' => '流水单号(20位)不能为空',
+ 'user_id.require' => '用户id不能为空',
+ 'source_type.require' => '来源类型不能为空',
+ 'source_id.require' => '来源id不能为空',
+ 'source_sn.require' => '来源单号不能为空',
+ 'change_amount.require' => '变动总数不能为空',
+ 'left_amount.require' => '剩余总数不能为空',
+ 'remark.require' => '说明不能为空',
+ 'extra.require' => '额外的字段说明不能为空',
+ 'change_type.require' => '1-增加;2-减少不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['log_sn','user_id','source_type','source_id','source_sn','change_amount','left_amount','remark','extra','change_type',],
+'edit' => ['log_sn','user_id','source_type','source_id','source_sn','change_amount','left_amount','remark','extra','change_type',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/ArticleCategoryValidate.php b/application/common/validate/ArticleCategoryValidate.php
new file mode 100755
index 0000000..cb874e3
--- /dev/null
+++ b/application/common/validate/ArticleCategoryValidate.php
@@ -0,0 +1,29 @@
+ 'require',
+ 'name|名称' => 'require',
+
+ ];
+
+ protected $message = [
+ 'parent_id.require' => '上级分类不能为空',
+ 'name.require' => '名称不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['parent_id', 'name',],
+ 'edit' => ['parent_id', 'name',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/ArticleTagValidate.php b/application/common/validate/ArticleTagValidate.php
new file mode 100755
index 0000000..0dcc7ae
--- /dev/null
+++ b/application/common/validate/ArticleTagValidate.php
@@ -0,0 +1,29 @@
+ 'require',
+ 'tag_id|标签' => 'require',
+
+ ];
+
+ protected $message = [
+ 'article_id.require' => '文章不能为空',
+ 'tag_id.require' => '标签不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['article_id', 'tag_id',],
+ 'edit' => ['article_id', 'tag_id',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/ArticleValidate.php b/application/common/validate/ArticleValidate.php
new file mode 100755
index 0000000..c2d3087
--- /dev/null
+++ b/application/common/validate/ArticleValidate.php
@@ -0,0 +1,44 @@
+ 'require',
+ 'user_id|发布人' => 'require',
+ 'article_category_id|所属分类' => 'require',
+ 'description|简介' => 'require',
+ 'content|内容' => 'require',
+ 'is_top|是否置顶' => 'require',
+ 'is_hot|是否热门' => 'require',
+ 'sort_number|排序' => 'require',
+ 'view_count|浏览数' => 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '标题不能为空',
+ 'user_id.require' => '发布人不能为空',
+ 'article_category_id.require' => '所属分类不能为空',
+ 'description.require' => '简介不能为空',
+ 'content.require' => '内容不能为空',
+ 'is_top.require' => '是否置顶不能为空',
+ 'is_hot.require' => '是否热门不能为空',
+ 'sort_number.require' => '排序不能为空',
+ 'view_count.require' => '浏览数不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name','user_id','article_category_id','description','content','is_top','is_hot','sort_number','view_count',],
+'edit' => ['name','user_id','article_category_id','description','content','is_top','is_hot','sort_number','view_count',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/BrandValidate.php b/application/common/validate/BrandValidate.php
new file mode 100755
index 0000000..7b578fd
--- /dev/null
+++ b/application/common/validate/BrandValidate.php
@@ -0,0 +1,27 @@
+ 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '名称不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name',],
+ 'edit' => ['name',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/ConsignmentOrderValidate.php b/application/common/validate/ConsignmentOrderValidate.php
new file mode 100755
index 0000000..c391abf
--- /dev/null
+++ b/application/common/validate/ConsignmentOrderValidate.php
@@ -0,0 +1,48 @@
+ 'require',
+ 'user_id|用户id' => 'require',
+ 'order_status|订单状态;0-审核中;1-待上架;2-已上架;3-已取消' => 'require',
+ 'is_return|是否退回' => 'require',
+ 'consignee|收货人' => 'require',
+ 'address|地址' => 'require',
+ 'mobile|手机' => 'require',
+ 'th_consignee|退回收货人' => 'require',
+ 'th_address|退回地址' => 'require',
+ 'th_mobile|退回电话' => 'require',
+ 'goods_price|订单商品总价' => 'require',
+
+ ];
+
+ protected $message = [
+ 'order_sn.require' => '订单编号不能为空',
+ 'user_id.require' => '用户id不能为空',
+ 'order_status.require' => '订单状态;0-审核中;1-待上架;2-已上架;3-已取消不能为空',
+ 'is_return.require' => '是否退回不能为空',
+ 'consignee.require' => '收货人不能为空',
+ 'address.require' => '地址不能为空',
+ 'mobile.require' => '手机不能为空',
+ 'th_consignee.require' => '退回收货人不能为空',
+ 'th_address.require' => '退回地址不能为空',
+ 'th_mobile.require' => '退回电话不能为空',
+ 'goods_price.require' => '订单商品总价不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['order_sn','user_id','order_status','is_return','consignee','address','mobile','th_consignee','th_address','th_mobile','goods_price',],
+'edit' => ['order_sn','user_id','order_status','is_return','consignee','address','mobile','th_consignee','th_address','th_mobile','goods_price',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/DeliverAddressValidate.php b/application/common/validate/DeliverAddressValidate.php
new file mode 100755
index 0000000..b0c0ff8
--- /dev/null
+++ b/application/common/validate/DeliverAddressValidate.php
@@ -0,0 +1,43 @@
+ 'require',
+ 'name|姓名' => 'require',
+ 'mobile|手机号' => 'require',
+ 'province_id|省' => 'require',
+ 'city_id|市' => 'require',
+ 'district_id|区' => 'require',
+ 'street_id|街道' => 'require',
+ 'detail|详细地址' => 'require',
+ 'is_default|是否默认' => 'require',
+
+ ];
+
+ protected $message = [
+ 'user_id.require' => '用户不能为空',
+ 'name.require' => '姓名不能为空',
+ 'mobile.require' => '手机号不能为空',
+ 'province_id.require' => '省不能为空',
+ 'city_id.require' => '市不能为空',
+ 'district_id.require' => '区不能为空',
+ 'street_id.require' => '街道不能为空',
+ 'detail.require' => '详细地址不能为空',
+ 'is_default.require' => '是否默认不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['user_id', 'name', 'mobile', 'province_id', 'city_id', 'district_id', 'street_id', 'detail', 'is_default',],
+ 'edit' => ['user_id', 'name', 'mobile', 'province_id', 'city_id', 'district_id', 'street_id', 'detail', 'is_default',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/ExpressValidate.php b/application/common/validate/ExpressValidate.php
new file mode 100755
index 0000000..d31d3be
--- /dev/null
+++ b/application/common/validate/ExpressValidate.php
@@ -0,0 +1,29 @@
+ 'require',
+ 'code|编码' => 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '名称不能为空',
+ 'code.require' => '编码不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name', 'code',],
+ 'edit' => ['name', 'code',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/GoodsAttrCategoryValidate.php b/application/common/validate/GoodsAttrCategoryValidate.php
new file mode 100755
index 0000000..1947881
--- /dev/null
+++ b/application/common/validate/GoodsAttrCategoryValidate.php
@@ -0,0 +1,28 @@
+ 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '名称不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name',],
+ 'edit' => ['name',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/GoodsBrandValidate.php b/application/common/validate/GoodsBrandValidate.php
new file mode 100755
index 0000000..961474d
--- /dev/null
+++ b/application/common/validate/GoodsBrandValidate.php
@@ -0,0 +1,34 @@
+ 'require',
+ 'initial|品牌首字母' => 'require',
+ 'is_show|是否显示:1-是.0-否' => 'require',
+ 'sort|排序' => 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '品牌名称不能为空',
+ 'initial.require' => '品牌首字母不能为空',
+ 'is_show.require' => '是否显示:1-是.0-否不能为空',
+ 'sort.require' => '排序不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name','initial','is_show','sort',],
+'edit' => ['name','initial','is_show','sort',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/GoodsCategoryValidate.php b/application/common/validate/GoodsCategoryValidate.php
new file mode 100755
index 0000000..a11b0b1
--- /dev/null
+++ b/application/common/validate/GoodsCategoryValidate.php
@@ -0,0 +1,29 @@
+ 'require',
+ 'name|名称' => 'require',
+
+ ];
+
+ protected $message = [
+ 'parent_id.require' => '上级分类不能为空',
+ 'name.require' => '名称不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['parent_id', 'name',],
+ 'edit' => ['parent_id', 'name',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/GoodsIndexValidate.php b/application/common/validate/GoodsIndexValidate.php
new file mode 100755
index 0000000..eadbbdb
--- /dev/null
+++ b/application/common/validate/GoodsIndexValidate.php
@@ -0,0 +1,34 @@
+ 'require',
+ 'goods_ids|商品id组' => 'require',
+ 'sort_number|排序(升序)' => 'require',
+ 'status|是否上架' => 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '栏目名称不能为空',
+ 'goods_ids.require' => '商品id组不能为空',
+ 'sort_number.require' => '排序(升序)不能为空',
+ 'status.require' => '是否上架不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name','sort_number','status',],
+'edit' => ['name','sort_number','status',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/GoodsValidate.php b/application/common/validate/GoodsValidate.php
new file mode 100755
index 0000000..b508637
--- /dev/null
+++ b/application/common/validate/GoodsValidate.php
@@ -0,0 +1,43 @@
+ 'require',
+ 'name|名称' => 'require',
+ 'code|编码' => 'require',
+ 'price|售价' => 'require',
+ 'brand_id|品牌' => 'require',
+ 'detail|详情' => 'require',
+ 'stock|库存' => 'require',
+ 'sort_number|排序(升序' => 'require',
+ 'status|是否上架' => 'require',
+
+ ];
+
+ protected $message = [
+ 'goods_category_id.require' => '所属分类不能为空',
+ 'name.require' => '名称不能为空',
+ 'code.require' => '商品编号不能为空',
+ 'price.require' => '售价不能为空',
+ 'brand_id.require' => '品牌不能为空',
+ 'detail.require' => '详情不能为空',
+ 'stock.require' => '库存不能为空',
+ 'sort_number.require' => '排序(升序不能为空',
+ 'status.require' => '是否上架不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['goods_category_id', 'name','code', 'price', 'brand_id', 'detail', 'sort_number', 'status',],
+ 'edit' => ['goods_category_id', 'name','code', 'price', 'brand_id', 'detail', 'sort_number', 'status',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/OrderGoodsValidate.php b/application/common/validate/OrderGoodsValidate.php
new file mode 100755
index 0000000..e202098
--- /dev/null
+++ b/application/common/validate/OrderGoodsValidate.php
@@ -0,0 +1,37 @@
+ 'require',
+ 'goods_id|商品' => 'require',
+ 'number|数量' => 'require',
+ 'attr|规格' => 'require',
+ 'price|单价' => 'require',
+ 'total_price|总价' => 'require',
+
+ ];
+
+ protected $message = [
+ 'order_id.require' => '所属订单不能为空',
+ 'goods_id.require' => '商品不能为空',
+ 'number.require' => '数量不能为空',
+ 'attr.require' => '规格不能为空',
+ 'price.require' => '单价不能为空',
+ 'total_price.require' => '总价不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['order_id', 'goods_id', 'number', 'attr', 'price', 'total_price',],
+ 'edit' => ['order_id', 'goods_id', 'number', 'attr', 'price', 'total_price',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/OrderValidate.php b/application/common/validate/OrderValidate.php
new file mode 100755
index 0000000..14849f0
--- /dev/null
+++ b/application/common/validate/OrderValidate.php
@@ -0,0 +1,28 @@
+ 'require',
+ 'invoice_no|物流单号' => 'require',
+ ];
+
+ protected $message = [
+ 'invoice_name.require' => '物流公司不能为空',
+ 'invoice_no.require' => '物流单号不能为空',
+
+ ];
+
+ protected $scene = [
+ 'hansle'=>['invoice_name','invoice_no']
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/PhaseConfigValidate.php b/application/common/validate/PhaseConfigValidate.php
new file mode 100755
index 0000000..daa8bcc
--- /dev/null
+++ b/application/common/validate/PhaseConfigValidate.php
@@ -0,0 +1,30 @@
+ 'require',
+ 'describe|描述' => 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '名称不能为空',
+ 'describe.require' => '描述不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name','describe',],
+'edit' => ['name','describe',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/ShopConfigValidate.php b/application/common/validate/ShopConfigValidate.php
new file mode 100755
index 0000000..924dac7
--- /dev/null
+++ b/application/common/validate/ShopConfigValidate.php
@@ -0,0 +1,32 @@
+ 'require',
+ 'name|名称' => 'require',
+ 'value|值' => 'require',
+
+ ];
+
+ protected $message = [
+ 'type.require' => '类型不能为空',
+ 'name.require' => '名称不能为空',
+ 'value.require' => '值不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['type','name','value',],
+'edit' => ['type','name','value',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/SlideValidate.php b/application/common/validate/SlideValidate.php
new file mode 100755
index 0000000..44f1fb1
--- /dev/null
+++ b/application/common/validate/SlideValidate.php
@@ -0,0 +1,33 @@
+ 'require',
+ 'jump_type|跳转类型' => 'require',
+ 'jump_target|跳转目标' => 'require',
+ 'sort_number|排序' => 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '名称不能为空',
+ 'jump_type.require' => '跳转类型不能为空',
+ 'jump_target.require' => '跳转目标不能为空',
+ 'sort_number.require' => '排序不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name', 'jump_type', 'jump_target', 'sort_number',],
+ 'edit' => ['name', 'jump_type', 'jump_target', 'sort_number',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/TagValidate.php b/application/common/validate/TagValidate.php
new file mode 100755
index 0000000..c209014
--- /dev/null
+++ b/application/common/validate/TagValidate.php
@@ -0,0 +1,27 @@
+ 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '名称不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name',],
+ 'edit' => ['name',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/TestValidate.php b/application/common/validate/TestValidate.php
new file mode 100755
index 0000000..9f66809
--- /dev/null
+++ b/application/common/validate/TestValidate.php
@@ -0,0 +1,28 @@
+ 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name',],
+'edit' => ['name',],
+
+ ];
+
+
+
+}
diff --git a/application/common/validate/UserAddressValidate.php b/application/common/validate/UserAddressValidate.php
new file mode 100755
index 0000000..eb29a71
--- /dev/null
+++ b/application/common/validate/UserAddressValidate.php
@@ -0,0 +1,39 @@
+ 'require',
+ 'contact|收货人' => 'require',
+ 'telephone|手机号码' => 'require',
+ 'province_id|省' => 'require',
+ 'city_id|市' => 'require',
+ 'district_id|区' => 'require',
+ 'address|是否启用' => 'require',
+ 'post_code|邮编' => 'require',
+ ];
+
+ protected $message = [
+ 'id.require' => '该地址不存在',
+ 'contact.require' => '收货人不能为空',
+ 'telephone.require' => '手机号不能为空',
+ 'province_id.require' => '省不能为空',
+ 'city_id.require' => '市不能为空',
+ 'district_id.require' => '区不能为空',
+ 'address.require' => '详情地址不能为空',
+ 'post_code.require' => '邮编不能为空',
+ ];
+
+ protected $scene = [
+ 'add' => ['contact', 'telephone', 'province_id', 'city_id', 'district_id', 'address',],
+ 'edit' => ['contact', 'telephone', 'province_id', 'city_id', 'district_id', 'address',],
+ 'del' =>['id'],
+ ];
+
+
+}
diff --git a/application/common/validate/UserLevelValidate.php b/application/common/validate/UserLevelValidate.php
new file mode 100755
index 0000000..30eeed7
--- /dev/null
+++ b/application/common/validate/UserLevelValidate.php
@@ -0,0 +1,31 @@
+ 'require',
+ 'description|简介' => 'require',
+ 'status|是否启用' => 'require',
+
+ ];
+
+ protected $message = [
+ 'name.require' => '名称不能为空',
+ 'description.require' => '简介不能为空',
+ 'status.require' => '是否启用不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['name', 'description', 'status',],
+ 'edit' => ['name', 'description', 'status',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/UserValidate.php b/application/common/validate/UserValidate.php
new file mode 100755
index 0000000..64152bb
--- /dev/null
+++ b/application/common/validate/UserValidate.php
@@ -0,0 +1,37 @@
+ 'require',
+ 'username|用户名' => 'require',
+ 'mobile|手机号' => 'require',
+ 'nickname|昵称' => 'require',
+ 'password|密码' => 'require',
+ 'status|是否启用' => 'require',
+
+ ];
+
+ protected $message = [
+ 'user_level_id.require' => '用户等级不能为空',
+ 'username.require' => '用户名不能为空',
+ 'mobile.require' => '手机号不能为空',
+ 'nickname.require' => '昵称不能为空',
+ 'password.require' => '密码不能为空',
+ 'status.require' => '是否启用不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['user_level_id', 'username', 'mobile', 'nickname', 'password', 'status',],
+ 'edit' => ['user_level_id', 'username', 'mobile', 'nickname', 'password', 'status',],
+
+ ];
+
+
+}
diff --git a/application/common/validate/Validate.php b/application/common/validate/Validate.php
new file mode 100755
index 0000000..19ab734
--- /dev/null
+++ b/application/common/validate/Validate.php
@@ -0,0 +1,13 @@
+
+ * @date 2018/12/18
+ */
+
+namespace app\common\validate;
+
+class Validate extends \think\Validate
+{
+
+}
\ No newline at end of file
diff --git a/application/common/validate/WithdrawAccountValidate.php b/application/common/validate/WithdrawAccountValidate.php
new file mode 100755
index 0000000..f00e851
--- /dev/null
+++ b/application/common/validate/WithdrawAccountValidate.php
@@ -0,0 +1,29 @@
+ 'require',
+ 'real_tel|手机号' => 'require',
+ 'account|账号' => 'require',
+ 'type|类型' => 'require',
+ ];
+
+ protected $message = [
+ 'real_name.require' => '真实姓名不能为空',
+ 'real_tel.require' => '手机号不能为空',
+ 'account.require' => '账号不能为空',
+ 'type.require' => '类型不能为空',
+ ];
+
+ protected $scene = [
+ 'add' => ['real_name', 'real_tel', 'account', 'type',],
+ ];
+
+
+}
diff --git a/application/common/validate/WithdrawApplyValidate.php b/application/common/validate/WithdrawApplyValidate.php
new file mode 100755
index 0000000..d13d6df
--- /dev/null
+++ b/application/common/validate/WithdrawApplyValidate.php
@@ -0,0 +1,70 @@
+ 'require',
+ 'user_id|用户id' => 'require',
+ 'real_name|真实姓名' => 'require',
+ 'account|账号' => 'require',
+ 'type|类型:1-提现到钱包余额;2-提现到微信零钱;3-提现到微信收款码;4-提现到支付宝收款码' => 'require',
+ 'money|提现金额' => 'require',
+ 'left_money|用户可得的金额(扣除手续费后)' => 'require',
+ 'money_qr_code|收款二维码' => 'require',
+ 'poundage|手续费' => 'require',
+ 'remark|提现申请备注' => 'require',
+ 'status|状态:1-待提现2-提现中3-提现成功4-提现失败' => 'require',
+ 'pay_desc|微信零钱支付信息' => 'require',
+ 'payment_no|支付单号' => 'require',
+ 'payment_time|支付时间' => 'require',
+ 'description|审核备注' => 'require',
+ 'transfer_voucher|转账凭证' => 'require',
+ 'transfer_time|转账时间' => 'require',
+ 'pay_search_desc|微信零钱支付查询结果' => 'require',
+ 'transfer_description|转账备注' => 'require',
+ 'repay_time|重新支付时间' => 'require',
+ 'bank|提现银行' => 'require',
+ 'subbank|提现银行支行' => 'require',
+
+ ];
+
+ protected $message = [
+ 'sn.require' => '提现单号不能为空',
+ 'user_id.require' => '用户id不能为空',
+ 'real_name.require' => '真实姓名不能为空',
+ 'account.require' => '账号不能为空',
+ 'type.require' => '类型:1-提现到钱包余额;2-提现到微信零钱;3-提现到微信收款码;4-提现到支付宝收款码不能为空',
+ 'money.require' => '提现金额不能为空',
+ 'left_money.require' => '用户可得的金额(扣除手续费后)不能为空',
+ 'money_qr_code.require' => '收款二维码不能为空',
+ 'poundage.require' => '手续费不能为空',
+ 'remark.require' => '提现申请备注不能为空',
+ 'status.require' => '状态:1-待提现2-提现中3-提现成功4-提现失败不能为空',
+ 'pay_desc.require' => '微信零钱支付信息不能为空',
+ 'payment_no.require' => '支付单号不能为空',
+ 'payment_time.require' => '支付时间不能为空',
+ 'description.require' => '审核备注不能为空',
+ 'transfer_voucher.require' => '转账凭证不能为空',
+ 'transfer_time.require' => '转账时间不能为空',
+ 'pay_search_desc.require' => '微信零钱支付查询结果不能为空',
+ 'transfer_description.require' => '转账备注不能为空',
+ 'repay_time.require' => '重新支付时间不能为空',
+ 'bank.require' => '提现银行不能为空',
+ 'subbank.require' => '提现银行支行不能为空',
+
+ ];
+
+ protected $scene = [
+ 'add' => ['sn','user_id','real_name','account','type','money','left_money','money_qr_code','poundage','remark','status','pay_desc','payment_no','payment_time','description','transfer_voucher','transfer_time','pay_search_desc','transfer_description','repay_time','bank','subbank',],
+'edit' => ['sn','user_id','real_name','account','type','money','left_money','money_qr_code','poundage','remark','status','pay_desc','payment_no','payment_time','description','transfer_voucher','transfer_time','pay_search_desc','transfer_description','repay_time','bank','subbank',],
+
+ ];
+
+
+
+}
diff --git a/application/index/common.php b/application/index/common.php
new file mode 100755
index 0000000..a3bad14
--- /dev/null
+++ b/application/index/common.php
@@ -0,0 +1,54 @@
+isPost()) {
+ $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : url($url);
+ $result = [
+ 'code' => $code,
+ 'msg' => $msg,
+ 'data' => $data,
+ 'url' => $url,
+ 'wait' => $wait,
+ ];
+ $response = Response::create($result, 'json')->header($header);
+ throw new HttpResponseException($response);
+ }
+
+
+ if ($url === null) {
+ $url = request()->server('HTTP_REFERER') ?? 'index/index/index';
+ }
+
+ $response = new Redirect($url);
+
+ $response->code(302)->params($data)->with([$code ? 'success_message' : 'error_message' => $msg, 'url' => $url]);
+
+ throw new HttpResponseException($response);
+ }
+}
\ No newline at end of file
diff --git a/application/index/controller/Controller.php b/application/index/controller/Controller.php
new file mode 100755
index 0000000..0c13f77
--- /dev/null
+++ b/application/index/controller/Controller.php
@@ -0,0 +1,56 @@
+
+ */
+
+namespace app\index\controller;
+
+use app\common\model\User;
+use app\index\traits\{IndexAuth, IndexTree};
+
+class Controller extends \think\Controller
+{
+ use IndexAuth, IndexAuth;
+
+ /**
+ * 当前url
+ * @var string
+ */
+ protected $url;
+
+ /**
+ * 当前用户ID
+ * @var int
+ */
+ protected $uid = 0;
+
+ /**
+ * 当前用户
+ * @var User
+ */
+ protected $user;
+
+ /**
+ * 无需验证权限的url
+ * @var array
+ */
+ protected $authExcept = [];
+
+ protected function initialize()
+ {
+ $request = $this->request;
+ if (!in_array($request->action(true), $this->authExcept)) {
+ if (!$this->isLogin()) {
+ error('未登录', 'auth/login');
+ } else if ($this->user->id !== 1 && !$this->isLogin()) {
+ error('无权限');
+ }
+ }
+
+ if ((int)$request->param('check_auth') === 1) {
+ success();
+ }
+ }
+
+}
diff --git a/application/index/controller/IndexController.php b/application/index/controller/IndexController.php
new file mode 100755
index 0000000..f3f90a7
--- /dev/null
+++ b/application/index/controller/IndexController.php
@@ -0,0 +1,24 @@
+fetch();
+ }
+
+
+}
diff --git a/application/index/controller/UserController.php b/application/index/controller/UserController.php
new file mode 100755
index 0000000..82acd6d
--- /dev/null
+++ b/application/index/controller/UserController.php
@@ -0,0 +1,62 @@
+assign([
+ 'user' => $this->user
+ ]);
+
+ return $this->fetch();
+ }
+
+
+ //登录
+ public function login(Request $request, User $model)
+ {
+ $param = $request->param();
+
+ //登录逻辑
+ if ($this->request->isPost()) {
+
+ try {
+ $user = $model::login($param);
+ } catch (\Exception $exception) {
+
+ return error($exception->getMessage());
+ }
+
+ self::authLogin($user);
+
+ return success('登录成功');
+ }
+
+
+ return $this->fetch();
+ }
+
+
+ //退出
+ public function logout()
+ {
+ self::authLogout();
+
+ return redirect(url('index/index'));
+ }
+}
\ No newline at end of file
diff --git a/application/index/traits/IndexAuth.php b/application/index/traits/IndexAuth.php
new file mode 100755
index 0000000..fd36075
--- /dev/null
+++ b/application/index/traits/IndexAuth.php
@@ -0,0 +1,84 @@
+
+ */
+
+namespace app\index\traits;
+
+use app\common\model\User;
+use tools\SafeCookie;
+use think\facade\Session;
+
+trait IndexAuth
+{
+ public static $user_id = 'user_id';
+ public static $user_id_sign = 'user_sign';
+
+ //是否登录
+ protected function isLogin()
+ {
+ //这里要写个判断数据库的才行
+ $user_id = Session::get(self::$user_id);
+ $user = false;
+ $this->user = &$user;
+ if (empty($user_id)) {
+ if (SafeCookie::has(self::$user_id) && SafeCookie::has(self::$user_id_sign)) {
+ $user_id = SafeCookie::get(self::$user_id);
+ $sign = SafeCookie::get(self::$user_id_sign);
+ $user = User::get($user_id);
+ if ($user && $user->sign_str === $sign) {
+ Session::set(self::$user_id, $user_id);
+ Session::set(self::$user_id_sign, $sign);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ $user = User::get($user_id);
+ if(!$user) {
+ return false;
+ }
+ $this->uid = $user->id;
+
+ return Session::get(self::$user_id_sign) === $user->sign_str;
+ }
+
+ /**
+ * session 与cookie登录
+ * @param $user User
+ * @param bool $remember
+ * @return bool
+ */
+ public static function authLogin($user, $remember = false)
+ {
+ Session::set(self::$user_id, $user->id);
+ Session::set(self::$user_id_sign, $user->sign_str);
+
+ //记住登录
+ if ($remember === true) {
+ SafeCookie::set(self::$user_id, $user->id);
+ SafeCookie::set(self::$user_id_sign, $user->sign_str);
+ } else if (SafeCookie::has(self::$user_id) || SafeCookie::has(self::$user_id_sign)) {
+ SafeCookie::delete(self::$user_id);
+ SafeCookie::delete(self::$user_id_sign);
+ }
+
+ return true;
+ }
+
+ //退出
+ public static function authLogout()
+ {
+ Session::delete(self::$user_id);
+ Session::delete(self::$user_id_sign);
+ if (SafeCookie::has(self::$user_id) || SafeCookie::has(self::$user_id_sign)) {
+ SafeCookie::delete(self::$user_id);
+ SafeCookie::delete(self::$user_id_sign);
+ }
+ return true;
+ }
+
+
+}
\ No newline at end of file
diff --git a/application/index/traits/IndexTree.php b/application/index/traits/IndexTree.php
new file mode 100755
index 0000000..480d7f6
--- /dev/null
+++ b/application/index/traits/IndexTree.php
@@ -0,0 +1,114 @@
+
+ */
+
+namespace app\index\traits;
+
+trait IndexTree
+{
+ public $text, $html;
+ /**
+ * 生成树型结构所需要的2维数组
+ * @var array
+ */
+ public $array;
+
+ /**
+ * 生成树型结构所需修饰符号,可以换成图片
+ * @var array
+ */
+ public $icon = array('│', '├', '└');
+ public $space = ' ';
+ /**
+ * @access private
+ */
+ public $ret = '';
+
+
+ /**
+ * 构造函数,初始化类
+ * @param array $arr
+ * @return bool
+ */
+ public function initTree($arr=[])
+ {
+ $this->array = $arr;
+ $this->ret = '';
+ $this->html = '';
+ return is_array($arr);
+ }
+
+ /**
+ * 得到树型结构
+ * @param int $my_id ,表示获得这个ID下的所有子级
+ * @param string $str 生成树型结构的基本代码,例如:"
\$spacer\$name "
+ * @param int $sid 被选中的ID,比如在做树型下拉框的时候需要用到
+ * @param string $adds
+ * @param string $str_group
+ * @return string
+ */
+ public function getTree($my_id, $str, $sid = 0, $adds = '', $str_group = '')
+ {
+ $parent_id = '';
+ $n_str = '';
+ $number = 1;
+ $child = $this->getChild($my_id);
+
+ if (is_array($child)) {
+ $total = count($child);
+ foreach ($child as $id => $value) {
+ $j = $k = '';
+ if ($number == $total) {
+ $j .= $this->icon[2];
+ } else {
+ $j .= $this->icon[1];
+ $k = $adds ? $this->icon[0] : '';
+ }
+ $spacer = $adds ? $adds . $j : '';
+ $selected = $id == $sid ? 'selected' : '';
+ extract($value);
+ 0 == $parent_id && $str_group ? eval("\$n_str = \"$str_group\";") : eval("\$n_str = \"$str\";");
+ $this->ret .= $n_str;
+ $space = $this->space;
+ $this->getTree($id, $str, $sid, $adds . $k . $space, $str_group);
+ $number++;
+ }
+ }
+ return $this->ret;
+ }
+
+
+ /**
+ * 得到子级数组
+ * @param int $pid
+ * @return bool|array
+ */
+ public function getChild($pid)
+ {
+ $result = [];
+ foreach ($this->array as $key => $value) {
+ if ($value['parent_id'] == $pid) {
+ $result[$key] = $value;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * 递归获取级别
+ * @param int $id ID
+ * @param array $array 所有菜单
+ * @param int $i 所在级别
+ * @return int
+ */
+ public function getLevel($id, $array, $i = 0)
+ {
+ if ($array[$id]['parent_id'] == 0 || empty($array[$array[$id]['parent_id']]) || $id == $array[$id]['parent_id']) {
+ return $i;
+ }
+ $i++;
+ return self::getLevel($array[$id]['parent_id'], $array, $i);
+ }
+}
diff --git a/application/index/view/index/index.html b/application/index/view/index/index.html
new file mode 100755
index 0000000..c1d5f5f
--- /dev/null
+++ b/application/index/view/index/index.html
@@ -0,0 +1,39 @@
+
+
+
+
BearAdmin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BearAdmin
+
&一款基于ThinkPHP5.1+AdminLTE的后台快速开发管理系统
+
Go→
+
Github
+
+ Gitee
+
+
+
+
+
+
diff --git a/application/index/view/user/index.html b/application/index/view/user/index.html
new file mode 100755
index 0000000..cea872a
--- /dev/null
+++ b/application/index/view/user/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
个人中心
+
+
+
+个人中心
+
+
+
\ No newline at end of file
diff --git a/application/index/view/user/login.html b/application/index/view/user/login.html
new file mode 100755
index 0000000..ee4a87b
--- /dev/null
+++ b/application/index/view/user/login.html
@@ -0,0 +1,12 @@
+
+
+
+
+
登录
+
+
+
+登录
+
+
+
\ No newline at end of file
diff --git a/application/provider.php b/application/provider.php
new file mode 100755
index 0000000..d0fcd24
--- /dev/null
+++ b/application/provider.php
@@ -0,0 +1,14 @@
+
+// +----------------------------------------------------------------------
+
+// 应用容器绑定定义
+return [
+];
diff --git a/application/tags.php b/application/tags.php
new file mode 100755
index 0000000..4b18d10
--- /dev/null
+++ b/application/tags.php
@@ -0,0 +1,28 @@
+
+// +----------------------------------------------------------------------
+
+// 应用行为扩展定义文件
+return [
+ // 应用初始化
+ 'app_init' => [],
+ // 应用开始
+ 'app_begin' => [],
+ // 模块初始化
+ 'module_init' => [],
+ // 操作开始执行
+ 'action_begin' => [],
+ // 视图内容过滤
+ 'view_filter' => [],
+ // 日志写入
+ 'log_write' => [],
+ // 应用结束
+ 'app_end' => [],
+];
diff --git a/build.php b/build.php
new file mode 100755
index 0000000..34ba3c8
--- /dev/null
+++ b/build.php
@@ -0,0 +1,26 @@
+
+// +----------------------------------------------------------------------
+
+return [
+ // 生成应用公共文件
+ '__file__' => ['common.php'],
+
+ // 定义demo模块的自动生成 (按照实际定义的文件名生成)
+ 'demo' => [
+ '__file__' => ['common.php'],
+ '__dir__' => ['behavior', 'controller', 'model', 'view'],
+ 'controller' => ['Index', 'Test', 'UserType'],
+ 'model' => ['User', 'UserType'],
+ 'view' => ['index/index'],
+ ],
+
+ // 其他更多的模块定义
+];
diff --git a/composer.json b/composer.json
new file mode 100755
index 0000000..a729538
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "topthink/think",
+ "description": "the new thinkphp framework",
+ "type": "project",
+ "keywords": [
+ "framework",
+ "thinkphp",
+ "ORM"
+ ],
+ "homepage": "http://thinkphp.cn/",
+ "license": "Apache-2.0",
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.6.0",
+ "topthink/framework": "5.1.*",
+ "topthink/think-migration": "^2.0",
+ "topthink/think-captcha": "^2.0",
+ "lcobucci/jwt": "^3.3",
+ "phpoffice/phpspreadsheet": "^1.8",
+ "yupoxiong/region": "^1.1",
+ "overtrue/easy-sms": "^1.1",
+ "endroid/qr-code": "^3.6",
+ "overtrue/wechat": "^4.2",
+ "phpmailer/phpmailer": "^6.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "app\\": "application"
+ }
+ },
+ "extra": {
+ "think-path": "thinkphp"
+ },
+ "config": {
+ "preferred-install": "dist"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100755
index 0000000..d16cab0
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,2953 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "46a4a4dde67c08df891e6ada6d5f3078",
+ "packages": [
+ {
+ "name": "bacon/bacon-qr-code",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Bacon/BaconQrCode.git",
+ "reference": "eaac909da3ccc32b748a65b127acd8918f58d9b0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/eaac909da3ccc32b748a65b127acd8918f58d9b0",
+ "reference": "eaac909da3ccc32b748a65b127acd8918f58d9b0",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "dasprid/enum": "^1.0",
+ "ext-iconv": "*",
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phly/keep-a-changelog": "^1.4",
+ "phpunit/phpunit": "^6.4",
+ "squizlabs/php_codesniffer": "^3.1"
+ },
+ "suggest": {
+ "ext-imagick": "to generate QR code images"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BaconQrCode\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Ben Scholzen 'DASPRiD'",
+ "role": "Developer",
+ "email": "mail@dasprids.de",
+ "homepage": "http://www.dasprids.de"
+ }
+ ],
+ "description": "BaconQrCode is a QR code generator for PHP.",
+ "homepage": "https://github.com/Bacon/BaconQrCode",
+ "time": "2018-04-25T17:53:56+00:00"
+ },
+ {
+ "name": "dasprid/enum",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/DASPRiD/Enum.git",
+ "reference": "631ef6e638e9494b0310837fa531bedd908fc22b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/631ef6e638e9494b0310837fa531bedd908fc22b",
+ "reference": "631ef6e638e9494b0310837fa531bedd908fc22b",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4",
+ "squizlabs/php_codesniffer": "^3.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DASPRiD\\Enum\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Ben Scholzen 'DASPRiD'",
+ "email": "mail@dasprids.de",
+ "homepage": "https://dasprids.de/"
+ }
+ ],
+ "description": "PHP 7.1 enum implementation",
+ "keywords": [
+ "enum",
+ "map"
+ ],
+ "time": "2017-10-25T22:45:27+00:00"
+ },
+ {
+ "name": "easywechat-composer/easywechat-composer",
+ "version": "1.1.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/mingyoung/easywechat-composer.git",
+ "reference": "970144fd245e62869edd60db6cc477053219d891"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/mingyoung/easywechat-composer/zipball/970144fd245e62869edd60db6cc477053219d891",
+ "reference": "970144fd245e62869edd60db6cc477053219d891",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "composer-plugin-api": "^1.0",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "composer/composer": "^1.0",
+ "phpunit/phpunit": "^6.5 || ^7.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "EasyWeChatComposer\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "EasyWeChatComposer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "张铭阳",
+ "email": "mingyoungcheung@gmail.com"
+ }
+ ],
+ "description": "The composer plugin for EasyWeChat",
+ "time": "2019-02-22T07:59:50+00:00"
+ },
+ {
+ "name": "endroid/installer",
+ "version": "1.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/endroid/installer.git",
+ "reference": "d4ae2bbd7977148dcb514ad625ece1a36f751a8b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/endroid/installer/zipball/d4ae2bbd7977148dcb514ad625ece1a36f751a8b",
+ "reference": "d4ae2bbd7977148dcb514ad625ece1a36f751a8b",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "composer-plugin-api": "^1.1",
+ "php": ">=7.2"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ },
+ "class": "Endroid\\Installer\\Installer"
+ },
+ "autoload": {
+ "psr-4": {
+ "Endroid\\Installer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jeroen van den Enden",
+ "email": "info@endroid.nl"
+ }
+ ],
+ "time": "2019-03-30T21:42:01+00:00"
+ },
+ {
+ "name": "endroid/qr-code",
+ "version": "3.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/endroid/qr-code.git",
+ "reference": "15641eec67291c6404b612694f65345c84a79919"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/endroid/qr-code/zipball/15641eec67291c6404b612694f65345c84a79919",
+ "reference": "15641eec67291c6404b612694f65345c84a79919",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "bacon/bacon-qr-code": "^2.0",
+ "endroid/installer": "^1.1.5",
+ "ext-gd": "*",
+ "khanamiryan/qrcode-detector-decoder": "^1.0.2",
+ "myclabs/php-enum": "^1.5",
+ "php": ">=7.2",
+ "symfony/http-foundation": "^3.4|^4.0",
+ "symfony/options-resolver": "^3.4|^4.0",
+ "symfony/property-access": "^3.4|^4.0"
+ },
+ "require-dev": {
+ "endroid/test": "^1.1.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Endroid\\QrCode\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jeroen van den Enden",
+ "email": "info@endroid.nl"
+ }
+ ],
+ "description": "Endroid QR Code",
+ "homepage": "https://github.com/endroid/qr-code",
+ "keywords": [
+ "bundle",
+ "code",
+ "endroid",
+ "php",
+ "qr",
+ "qrcode"
+ ],
+ "time": "2019-05-25T20:13:40+00:00"
+ },
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "6.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.4",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.3-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2018-04-22T15:46:56+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "v1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "time": "2016-12-20T10:07:11+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "239400de7a173fe9901b9ac7c06497751f00727a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
+ "reference": "239400de7a173fe9901b9ac7c06497751f00727a",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0",
+ "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "ext-zlib": "*",
+ "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+ },
+ "suggest": {
+ "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.6-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "psr-7",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "time": "2019-07-01T23:21:34+00:00"
+ },
+ {
+ "name": "khanamiryan/qrcode-detector-decoder",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/khanamiryan/php-qrcode-detector-decoder.git",
+ "reference": "a75482d3bc804e3f6702332bfda6cccbb0dfaa76"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/khanamiryan/php-qrcode-detector-decoder/zipball/a75482d3bc804e3f6702332bfda6cccbb0dfaa76",
+ "reference": "a75482d3bc804e3f6702332bfda6cccbb0dfaa76",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^5.6|^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Zxing\\": "lib/"
+ },
+ "files": [
+ "lib/Common/customFunctions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ashot Khanamiryan",
+ "email": "a.khanamiryan@gmail.com",
+ "homepage": "https://github.com/khanamiryan",
+ "role": "Developer"
+ }
+ ],
+ "description": "QR code decoder / reader",
+ "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder/",
+ "keywords": [
+ "barcode",
+ "qr",
+ "zxing"
+ ],
+ "time": "2018-04-26T11:41:33+00:00"
+ },
+ {
+ "name": "lcobucci/jwt",
+ "version": "3.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/lcobucci/jwt.git",
+ "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/lcobucci/jwt/zipball/a11ec5f4b4d75d1fcd04e133dede4c317aac9e18",
+ "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "mikey179/vfsstream": "~1.5",
+ "phpmd/phpmd": "~2.2",
+ "phpunit/php-invoker": "~1.1",
+ "phpunit/phpunit": "^5.7 || ^7.3",
+ "squizlabs/php_codesniffer": "~2.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Lcobucci\\JWT\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Luís Otávio Cobucci Oblonczyk",
+ "email": "lcobucci@gmail.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "A simple library to work with JSON Web Token and JSON Web Signature",
+ "keywords": [
+ "JWS",
+ "jwt"
+ ],
+ "time": "2019-05-24T18:30:49+00:00"
+ },
+ {
+ "name": "markbaker/complex",
+ "version": "1.4.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarkBaker/PHPComplex.git",
+ "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/1ea674a8308baf547cbcbd30c5fcd6d301b7c000",
+ "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^5.6.0|^7.0.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
+ "phpcompatibility/php-compatibility": "^8.0",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phploc/phploc": "2.*",
+ "phpmd/phpmd": "2.*",
+ "phpunit/phpunit": "^4.8.35|^5.4.0",
+ "sebastian/phpcpd": "2.*",
+ "squizlabs/php_codesniffer": "^3.3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Complex\\": "classes/src/"
+ },
+ "files": [
+ "classes/src/functions/abs.php",
+ "classes/src/functions/acos.php",
+ "classes/src/functions/acosh.php",
+ "classes/src/functions/acot.php",
+ "classes/src/functions/acoth.php",
+ "classes/src/functions/acsc.php",
+ "classes/src/functions/acsch.php",
+ "classes/src/functions/argument.php",
+ "classes/src/functions/asec.php",
+ "classes/src/functions/asech.php",
+ "classes/src/functions/asin.php",
+ "classes/src/functions/asinh.php",
+ "classes/src/functions/atan.php",
+ "classes/src/functions/atanh.php",
+ "classes/src/functions/conjugate.php",
+ "classes/src/functions/cos.php",
+ "classes/src/functions/cosh.php",
+ "classes/src/functions/cot.php",
+ "classes/src/functions/coth.php",
+ "classes/src/functions/csc.php",
+ "classes/src/functions/csch.php",
+ "classes/src/functions/exp.php",
+ "classes/src/functions/inverse.php",
+ "classes/src/functions/ln.php",
+ "classes/src/functions/log2.php",
+ "classes/src/functions/log10.php",
+ "classes/src/functions/negative.php",
+ "classes/src/functions/pow.php",
+ "classes/src/functions/rho.php",
+ "classes/src/functions/sec.php",
+ "classes/src/functions/sech.php",
+ "classes/src/functions/sin.php",
+ "classes/src/functions/sinh.php",
+ "classes/src/functions/sqrt.php",
+ "classes/src/functions/tan.php",
+ "classes/src/functions/tanh.php",
+ "classes/src/functions/theta.php",
+ "classes/src/operations/add.php",
+ "classes/src/operations/subtract.php",
+ "classes/src/operations/multiply.php",
+ "classes/src/operations/divideby.php",
+ "classes/src/operations/divideinto.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Baker",
+ "email": "mark@lange.demon.co.uk"
+ }
+ ],
+ "description": "PHP Class for working with complex numbers",
+ "homepage": "https://github.com/MarkBaker/PHPComplex",
+ "keywords": [
+ "complex",
+ "mathematics"
+ ],
+ "time": "2018-10-13T23:28:42+00:00"
+ },
+ {
+ "name": "markbaker/matrix",
+ "version": "1.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarkBaker/PHPMatrix.git",
+ "reference": "6ea97472b5baf12119b4f31f802835b820dd6d64"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/6ea97472b5baf12119b4f31f802835b820dd6d64",
+ "reference": "6ea97472b5baf12119b4f31f802835b820dd6d64",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^5.6.0|^7.0.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
+ "phpcompatibility/php-compatibility": "^8.0",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phploc/phploc": "2.*",
+ "phpmd/phpmd": "2.*",
+ "phpunit/phpunit": "^4.8.35|^5.4.0",
+ "sebastian/phpcpd": "2.*",
+ "squizlabs/php_codesniffer": "^3.3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Matrix\\": "classes/src/"
+ },
+ "files": [
+ "classes/src/functions/adjoint.php",
+ "classes/src/functions/antidiagonal.php",
+ "classes/src/functions/cofactors.php",
+ "classes/src/functions/determinant.php",
+ "classes/src/functions/diagonal.php",
+ "classes/src/functions/identity.php",
+ "classes/src/functions/inverse.php",
+ "classes/src/functions/minors.php",
+ "classes/src/functions/trace.php",
+ "classes/src/functions/transpose.php",
+ "classes/src/operations/add.php",
+ "classes/src/operations/directsum.php",
+ "classes/src/operations/subtract.php",
+ "classes/src/operations/multiply.php",
+ "classes/src/operations/divideby.php",
+ "classes/src/operations/divideinto.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Baker",
+ "email": "mark@lange.demon.co.uk"
+ }
+ ],
+ "description": "PHP Class for working with matrices",
+ "homepage": "https://github.com/MarkBaker/PHPMatrix",
+ "keywords": [
+ "mathematics",
+ "matrix",
+ "vector"
+ ],
+ "time": "2018-11-04T22:12:12+00:00"
+ },
+ {
+ "name": "monolog/monolog",
+ "version": "1.24.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/monolog.git",
+ "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
+ "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "psr/log": "~1.0"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0.0"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "^2.4.9 || ^3.0",
+ "doctrine/couchdb": "~1.0@dev",
+ "graylog2/gelf-php": "~1.0",
+ "jakub-onderka/php-parallel-lint": "0.9",
+ "php-amqplib/php-amqplib": "~2.4",
+ "php-console/php-console": "^3.1.3",
+ "phpunit/phpunit": "~4.5",
+ "phpunit/phpunit-mock-objects": "2.3.0",
+ "ruflin/elastica": ">=0.90 <3.0",
+ "sentry/sentry": "^0.13",
+ "swiftmailer/swiftmailer": "^5.3|^6.0"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+ "ext-mongo": "Allow sending log messages to a MongoDB server",
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+ "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
+ "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+ "php-console/php-console": "Allow sending log messages to Google Chrome",
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
+ "sentry/sentry": "Allow sending log messages to a Sentry server"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Monolog\\": "src/Monolog"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+ "homepage": "http://github.com/Seldaek/monolog",
+ "keywords": [
+ "log",
+ "logging",
+ "psr-3"
+ ],
+ "time": "2018-11-05T09:00:11+00:00"
+ },
+ {
+ "name": "myclabs/php-enum",
+ "version": "1.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/php-enum.git",
+ "reference": "45f01adf6922df6082bcda36619deb466e826acf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/php-enum/zipball/45f01adf6922df6082bcda36619deb466e826acf",
+ "reference": "45f01adf6922df6082bcda36619deb466e826acf",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-json": "*",
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
+ "squizlabs/php_codesniffer": "1.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "MyCLabs\\Enum\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP Enum contributors",
+ "homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
+ }
+ ],
+ "description": "PHP Enum implementation",
+ "homepage": "http://github.com/myclabs/php-enum",
+ "keywords": [
+ "enum"
+ ],
+ "time": "2019-08-19T13:53:00+00:00"
+ },
+ {
+ "name": "overtrue/easy-sms",
+ "version": "1.1.15",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/overtrue/easy-sms.git",
+ "reference": "b2e7d5bbafb68c27bb767a4ea7c7742b358fcc71"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/overtrue/easy-sms/zipball/b2e7d5bbafb68c27bb767a4ea7c7742b358fcc71",
+ "reference": "b2e7d5bbafb68c27bb767a4ea7c7742b358fcc71",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^6.2",
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "mockery/mockery": "1.2.2",
+ "phpunit/phpunit": "^5.7 || ^7.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Overtrue\\EasySms\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "overtrue",
+ "email": "i@overtrue.me"
+ }
+ ],
+ "description": "The easiest way to send short message.",
+ "time": "2019-08-01T10:35:17+00:00"
+ },
+ {
+ "name": "overtrue/socialite",
+ "version": "2.0.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/overtrue/socialite.git",
+ "reference": "cfc513bbf5fb8c1761e8127eb9427ab05cb4ea10"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/overtrue/socialite/zipball/cfc513bbf5fb8c1761e8127eb9427ab05cb4ea10",
+ "reference": "cfc513bbf5fb8c1761e8127eb9427ab05cb4ea10",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "guzzlehttp/guzzle": "~5.0|~6.0",
+ "php": ">=7.0",
+ "symfony/http-foundation": "^2.7|^3.0|^4.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~1.2",
+ "phpunit/phpunit": "~6"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Overtrue\\Socialite\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "overtrue",
+ "email": "anzhengchao@gmail.com"
+ }
+ ],
+ "description": "A collection of OAuth 2 packages that extracts from laravel/socialite.",
+ "keywords": [
+ "login",
+ "oauth",
+ "qq",
+ "social",
+ "wechat",
+ "weibo"
+ ],
+ "time": "2019-07-05T14:42:52+00:00"
+ },
+ {
+ "name": "overtrue/wechat",
+ "version": "4.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/overtrue/wechat.git",
+ "reference": "e487edc44f9a3d26603bc3c153c087dd2cacd0b0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/overtrue/wechat/zipball/e487edc44f9a3d26603bc3c153c087dd2cacd0b0",
+ "reference": "e487edc44f9a3d26603bc3c153c087dd2cacd0b0",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "easywechat-composer/easywechat-composer": "^1.1",
+ "ext-fileinfo": "*",
+ "ext-openssl": "*",
+ "ext-simplexml": "*",
+ "guzzlehttp/guzzle": "^6.2",
+ "monolog/monolog": "^1.22",
+ "overtrue/socialite": "~2.0",
+ "php": ">=7.1",
+ "pimple/pimple": "^3.0",
+ "psr/simple-cache": "^1.0",
+ "symfony/cache": "^3.3 || ^4.3",
+ "symfony/event-dispatcher": "^4.3",
+ "symfony/http-foundation": "^2.7 || ^3.0 || ^4.0",
+ "symfony/psr-http-message-bridge": "^0.3 || ^1.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.15",
+ "mikey179/vfsstream": "^1.6",
+ "mockery/mockery": "^1.0",
+ "phpstan/phpstan": "^0.11.12",
+ "phpunit/phpunit": "~6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "EasyWeChat\\": "src/"
+ },
+ "files": [
+ "src/Kernel/Support/Helpers.php",
+ "src/Kernel/Helpers.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "overtrue",
+ "email": "anzhengchao@gmail.com"
+ }
+ ],
+ "description": "微信SDK",
+ "keywords": [
+ "sdk",
+ "wechat",
+ "weixin",
+ "weixin-sdk"
+ ],
+ "time": "2019-08-16T10:24:45+00:00"
+ },
+ {
+ "name": "phpmailer/phpmailer",
+ "version": "v6.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPMailer/PHPMailer.git",
+ "reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/0c41a36d4508d470e376498c1c0c527aa36a2d59",
+ "reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-filter": "*",
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "doctrine/annotations": "1.2.*",
+ "friendsofphp/php-cs-fixer": "^2.2",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phpunit/phpunit": "^4.8 || ^5.7",
+ "zendframework/zend-eventmanager": "3.0.*",
+ "zendframework/zend-i18n": "2.7.3",
+ "zendframework/zend-serializer": "2.7.*"
+ },
+ "suggest": {
+ "ext-mbstring": "Needed to send email in multibyte encoding charset",
+ "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
+ "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
+ "psr/log": "For optional PSR-3 debug logging",
+ "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
+ "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPMailer\\PHPMailer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1"
+ ],
+ "authors": [
+ {
+ "name": "Jim Jagielski",
+ "email": "jimjag@gmail.com"
+ },
+ {
+ "name": "Marcus Bointon",
+ "email": "phpmailer@synchromedia.co.uk"
+ },
+ {
+ "name": "Andy Prevost",
+ "email": "codeworxtech@users.sourceforge.net"
+ },
+ {
+ "name": "Brent R. Matzelle"
+ }
+ ],
+ "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
+ "time": "2019-02-01T15:04:28+00:00"
+ },
+ {
+ "name": "phpoffice/phpspreadsheet",
+ "version": "1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+ "reference": "8dea03eaf60a349b6097e4bcad11f894668280df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/8dea03eaf60a349b6097e4bcad11f894668280df",
+ "reference": "8dea03eaf60a349b6097e4bcad11f894668280df",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-fileinfo": "*",
+ "ext-gd": "*",
+ "ext-iconv": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "ext-xml": "*",
+ "ext-xmlreader": "*",
+ "ext-xmlwriter": "*",
+ "ext-zip": "*",
+ "ext-zlib": "*",
+ "markbaker/complex": "^1.4",
+ "markbaker/matrix": "^1.1",
+ "php": "^7.1",
+ "psr/simple-cache": "^1.0"
+ },
+ "require-dev": {
+ "dompdf/dompdf": "^0.8.0",
+ "friendsofphp/php-cs-fixer": "@stable",
+ "jpgraph/jpgraph": "^4.0",
+ "mpdf/mpdf": "^7.0.0",
+ "phpcompatibility/php-compatibility": "^8.0",
+ "phpunit/phpunit": "^7.5",
+ "squizlabs/php_codesniffer": "^3.3",
+ "tecnickcom/tcpdf": "^6.2"
+ },
+ "suggest": {
+ "dompdf/dompdf": "Option for rendering PDF with PDF Writer",
+ "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+ "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+ "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Maarten Balliauw",
+ "homepage": "https://blog.maartenballiauw.be"
+ },
+ {
+ "name": "Mark Baker",
+ "homepage": "https://markbakeruk.net"
+ },
+ {
+ "name": "Franck Lefevre",
+ "homepage": "https://rootslabs.net"
+ },
+ {
+ "name": "Erik Tilt"
+ },
+ {
+ "name": "Adrien Crivelli"
+ }
+ ],
+ "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+ "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+ "keywords": [
+ "OpenXML",
+ "excel",
+ "gnumeric",
+ "ods",
+ "php",
+ "spreadsheet",
+ "xls",
+ "xlsx"
+ ],
+ "time": "2019-08-17T22:24:35+00:00"
+ },
+ {
+ "name": "pimple/pimple",
+ "version": "v3.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Pimple.git",
+ "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32",
+ "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "psr/container": "^1.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^3.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Pimple": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Pimple, a simple Dependency Injection Container",
+ "homepage": "http://pimple.sensiolabs.org",
+ "keywords": [
+ "container",
+ "dependency injection"
+ ],
+ "time": "2018-01-21T07:42:36+00:00"
+ },
+ {
+ "name": "psr/cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "time": "2016-08-06T20:24:11+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "time": "2017-02-14T16:28:37+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2018-11-20T15:27:04+00:00"
+ },
+ {
+ "name": "psr/simple-cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/simple-cache.git",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\SimpleCache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for simple caching",
+ "keywords": [
+ "cache",
+ "caching",
+ "psr",
+ "psr-16",
+ "simple-cache"
+ ],
+ "time": "2017-10-23T01:57:42+00:00"
+ },
+ {
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/getallheaders.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "description": "A polyfill for getallheaders.",
+ "time": "2019-03-08T08:55:37+00:00"
+ },
+ {
+ "name": "symfony/cache",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/cache.git",
+ "reference": "1d8f7fee990c586f275cde1a9fc883d6b1e2d43e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/cache/zipball/1d8f7fee990c586f275cde1a9fc883d6b1e2d43e",
+ "reference": "1d8f7fee990c586f275cde1a9fc883d6b1e2d43e",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "psr/cache": "~1.0",
+ "psr/log": "~1.0",
+ "symfony/cache-contracts": "^1.1",
+ "symfony/service-contracts": "^1.1",
+ "symfony/var-exporter": "^4.2"
+ },
+ "conflict": {
+ "doctrine/dbal": "<2.5",
+ "symfony/dependency-injection": "<3.4",
+ "symfony/var-dumper": "<3.4"
+ },
+ "provide": {
+ "psr/cache-implementation": "1.0",
+ "psr/simple-cache-implementation": "1.0",
+ "symfony/cache-implementation": "1.0"
+ },
+ "require-dev": {
+ "cache/integration-tests": "dev-master",
+ "doctrine/cache": "~1.6",
+ "doctrine/dbal": "~2.5",
+ "predis/predis": "~1.1",
+ "psr/simple-cache": "^1.0",
+ "symfony/config": "~4.2",
+ "symfony/dependency-injection": "~3.4|~4.1",
+ "symfony/var-dumper": "^4.1.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Cache\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Cache component with PSR-6, PSR-16, and tags",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "caching",
+ "psr6"
+ ],
+ "time": "2019-08-26T08:26:39+00:00"
+ },
+ {
+ "name": "symfony/cache-contracts",
+ "version": "v1.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/cache-contracts.git",
+ "reference": "ec5524b669744b5f1dc9c66d3c2b091eb7e7f0db"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ec5524b669744b5f1dc9c66d3c2b091eb7e7f0db",
+ "reference": "ec5524b669744b5f1dc9c66d3c2b091eb7e7f0db",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "psr/cache": "^1.0"
+ },
+ "suggest": {
+ "symfony/cache-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Cache\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to caching",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "time": "2019-06-13T11:15:36+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/429d0a1451d4c9c4abe1959b2986b88794b9b7d2",
+ "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/event-dispatcher-contracts": "^1.1"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<3.4"
+ },
+ "provide": {
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "1.1"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~3.4|~4.0",
+ "symfony/dependency-injection": "~3.4|~4.0",
+ "symfony/expression-language": "~3.4|~4.0",
+ "symfony/http-foundation": "^3.4|^4.0",
+ "symfony/service-contracts": "^1.1",
+ "symfony/stopwatch": "~3.4|~4.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com",
+ "time": "2019-08-26T08:55:16+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v1.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "c61766f4440ca687de1084a5c00b08e167a2575c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c61766f4440ca687de1084a5c00b08e167a2575c",
+ "reference": "c61766f4440ca687de1084a5c00b08e167a2575c",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3"
+ },
+ "suggest": {
+ "psr/event-dispatcher": "",
+ "symfony/event-dispatcher-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\EventDispatcher\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to dispatching event",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "time": "2019-06-20T06:46:26+00:00"
+ },
+ {
+ "name": "symfony/http-foundation",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d804bea118ff340a12e22a79f9c7e7eb56b35adc",
+ "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/mime": "^4.3",
+ "symfony/polyfill-mbstring": "~1.1"
+ },
+ "require-dev": {
+ "predis/predis": "~1.0",
+ "symfony/expression-language": "~3.4|~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpFoundation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony HttpFoundation Component",
+ "homepage": "https://symfony.com",
+ "time": "2019-08-26T08:55:16+00:00"
+ },
+ {
+ "name": "symfony/inflector",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/inflector.git",
+ "reference": "b25a8dc15fada858432efa083c1ecd2cef5991a7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/inflector/zipball/b25a8dc15fada858432efa083c1ecd2cef5991a7",
+ "reference": "b25a8dc15fada858432efa083c1ecd2cef5991a7",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Inflector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Inflector Component",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "inflection",
+ "pluralize",
+ "singularize",
+ "string",
+ "symfony",
+ "words"
+ ],
+ "time": "2019-08-06T18:44:23+00:00"
+ },
+ {
+ "name": "symfony/mime",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/mime.git",
+ "reference": "987a05df1c6ac259b34008b932551353f4f408df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/987a05df1c6ac259b34008b932551353f4f408df",
+ "reference": "987a05df1c6ac259b34008b932551353f4f408df",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-intl-idn": "^1.10",
+ "symfony/polyfill-mbstring": "^1.0"
+ },
+ "require-dev": {
+ "egulias/email-validator": "^2.1.10",
+ "symfony/dependency-injection": "~3.4|^4.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Mime\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A library to manipulate MIME messages",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "mime",
+ "mime-type"
+ ],
+ "time": "2019-08-22T08:16:11+00:00"
+ },
+ {
+ "name": "symfony/options-resolver",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/options-resolver.git",
+ "reference": "81c2e120522a42f623233968244baebd6b36cb6a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/81c2e120522a42f623233968244baebd6b36cb6a",
+ "reference": "81c2e120522a42f623233968244baebd6b36cb6a",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony OptionsResolver Component",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
+ "time": "2019-08-08T09:29:19+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
+ "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.12-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "time": "2019-08-06T08:03:45+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-idn",
+ "version": "v1.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-idn.git",
+ "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6af626ae6fa37d396dc90a399c0ff08e5cfc45b2",
+ "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/polyfill-mbstring": "^1.3",
+ "symfony/polyfill-php72": "^1.9"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.12-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Idn\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Laurent Bassin",
+ "email": "laurent@bassin.info"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "idn",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2019-08-06T08:03:45+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
+ "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.12-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2019-08-06T08:03:45+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php72",
+ "version": "v1.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php72.git",
+ "reference": "04ce3335667451138df4307d6a9b61565560199e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e",
+ "reference": "04ce3335667451138df4307d6a9b61565560199e",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.12-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php72\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2019-08-06T08:03:45+00:00"
+ },
+ {
+ "name": "symfony/property-access",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/property-access.git",
+ "reference": "bb0c302375ffeef60c31e72a4539611b7f787565"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/property-access/zipball/bb0c302375ffeef60c31e72a4539611b7f787565",
+ "reference": "bb0c302375ffeef60c31e72a4539611b7f787565",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/inflector": "~3.4|~4.0"
+ },
+ "require-dev": {
+ "symfony/cache": "~3.4|~4.0"
+ },
+ "suggest": {
+ "psr/cache-implementation": "To cache access methods."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\PropertyAccess\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony PropertyAccess Component",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "access",
+ "array",
+ "extraction",
+ "index",
+ "injection",
+ "object",
+ "property",
+ "property path",
+ "reflection"
+ ],
+ "time": "2019-08-26T08:26:39+00:00"
+ },
+ {
+ "name": "symfony/psr-http-message-bridge",
+ "version": "v1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/psr-http-message-bridge.git",
+ "reference": "9ab9d71f97d5c7d35a121a7fb69f74fee95cd0ad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/9ab9d71f97d5c7d35a121a7fb69f74fee95cd0ad",
+ "reference": "9ab9d71f97d5c7d35a121a7fb69f74fee95cd0ad",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1",
+ "psr/http-message": "^1.0",
+ "symfony/http-foundation": "^3.4 || ^4.0"
+ },
+ "require-dev": {
+ "nyholm/psr7": "^1.1",
+ "symfony/phpunit-bridge": "^3.4.20 || ^4.0",
+ "zendframework/zend-diactoros": "^1.4.1 || ^2.0"
+ },
+ "suggest": {
+ "nyholm/psr7": "For a super lightweight PSR-7/17 implementation"
+ },
+ "type": "symfony-bridge",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Bridge\\PsrHttpMessage\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "PSR HTTP message bridge",
+ "homepage": "http://symfony.com",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr-17",
+ "psr-7"
+ ],
+ "time": "2019-03-11T18:22:33+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v1.1.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3",
+ "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3",
+ "psr/container": "^1.0"
+ },
+ "suggest": {
+ "symfony/service-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Service\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "time": "2019-08-20T14:44:19+00:00"
+ },
+ {
+ "name": "symfony/var-exporter",
+ "version": "v4.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-exporter.git",
+ "reference": "d5b4e2d334c1d80e42876c7d489896cfd37562f2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/d5b4e2d334c1d80e42876c7d489896cfd37562f2",
+ "reference": "d5b4e2d334c1d80e42876c7d489896cfd37562f2",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1.3"
+ },
+ "require-dev": {
+ "symfony/var-dumper": "^4.1.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\VarExporter\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "clone",
+ "construct",
+ "export",
+ "hydrate",
+ "instantiate",
+ "serialize"
+ ],
+ "time": "2019-08-22T07:33:08+00:00"
+ },
+ {
+ "name": "topthink/framework",
+ "version": "v5.1.38.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/framework.git",
+ "reference": "12d15c29d5d6a972fc8bfc8db005d64d4786028c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/framework/zipball/12d15c29d5d6a972fc8bfc8db005d64d4786028c",
+ "reference": "12d15c29d5d6a972fc8bfc8db005d64d4786028c",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.6.0",
+ "topthink/think-installer": "2.*"
+ },
+ "require-dev": {
+ "johnkary/phpunit-speedtrap": "^1.0",
+ "mikey179/vfsstream": "~1.6",
+ "phpdocumentor/reflection-docblock": "^2.0",
+ "phploc/phploc": "2.*",
+ "phpunit/phpunit": "^5.0|^6.0",
+ "sebastian/phpcpd": "2.*",
+ "squizlabs/php_codesniffer": "2.*"
+ },
+ "type": "think-framework",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ },
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "the new thinkphp framework",
+ "homepage": "http://thinkphp.cn/",
+ "keywords": [
+ "framework",
+ "orm",
+ "thinkphp"
+ ],
+ "time": "2019-08-12T00:58:30+00:00"
+ },
+ {
+ "name": "topthink/think-captcha",
+ "version": "v2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-captcha.git",
+ "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-captcha/zipball/54c8a51552f99ff9ea89ea9c272383a8f738ceee",
+ "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "topthink/framework": "5.1.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "think\\captcha\\": "src/"
+ },
+ "files": [
+ "src/helper.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "captcha package for thinkphp5",
+ "time": "2017-12-31T16:37:49+00:00"
+ },
+ {
+ "name": "topthink/think-installer",
+ "version": "v2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-installer.git",
+ "reference": "f5400a12c60e513911aef41fe443fa6920952675"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-installer/zipball/f5400a12c60e513911aef41fe443fa6920952675",
+ "reference": "f5400a12c60e513911aef41fe443fa6920952675",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "require-dev": {
+ "composer/composer": "1.0.*@dev"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "think\\composer\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "think\\composer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "time": "2018-05-11T06:45:42+00:00"
+ },
+ {
+ "name": "topthink/think-migration",
+ "version": "v2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-migration.git",
+ "reference": "70c89850ca29c2eab988c7c3475d1d5331901bb8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-migration/zipball/70c89850ca29c2eab988c7c3475d1d5331901bb8",
+ "reference": "70c89850ca29c2eab988c7c3475d1d5331901bb8",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "topthink/framework": "5.1.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Phinx\\": "phinx/src/Phinx",
+ "think\\migration\\": "src"
+ },
+ "files": [
+ "src/config.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "time": "2017-12-31T16:32:22+00:00"
+ },
+ {
+ "name": "yupoxiong/region",
+ "version": "v1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yupoxiong/region.git",
+ "reference": "13b241809f259bfd30444ab069d3028a7dd28160"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yupoxiong/region/zipball/13b241809f259bfd30444ab069d3028a7dd28160",
+ "reference": "13b241809f259bfd30444ab069d3028a7dd28160",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "yupoxiong\\region\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yupoxiong",
+ "email": "i@yufuping.com",
+ "homepage": "https://www.yufuping.com"
+ }
+ ],
+ "description": "ThinkPHP省市区(县)街道四级联动扩展",
+ "homepage": "https://github.com/yupoxiong/region",
+ "keywords": [
+ "region",
+ "thinkphp",
+ "省市区"
+ ],
+ "time": "2019-08-07T03:15:09+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=5.6.0"
+ },
+ "platform-dev": []
+}
diff --git a/config/admin/admin.php b/config/admin/admin.php
new file mode 100755
index 0000000..2194e8f
--- /dev/null
+++ b/config/admin/admin.php
@@ -0,0 +1,32 @@
+
+ * @date 2020/06/19
+ */
+
+return [
+ //后台名称
+ 'name' => '后台管理系统',
+ //后台名称简称
+ 'short_name' => '后台',
+ //后台作者
+ 'author' => '寄卖',
+ //后台版本
+ 'version' => '0.1',
+ //超级管理员默认密码警告
+ 'password_warning' => true,
+ //首页欢迎信息
+ 'welcome_info' => true,
+
+ //登录配置
+ 'login' => [
+ //开启token验证
+ 'token' => true,
+ //验证码选项:false/0不开启验证码,1ThinkPHP图形验证码,2极验点击滑动验证码
+ 'captcha' => 0,
+ //登录背景,false为不需要背景,填写背景地址则为显示
+ 'background' => '/static/admin/images/background.jpg',
+
+ ]
+];
\ No newline at end of file
diff --git a/config/admin/app.php b/config/admin/app.php
new file mode 100755
index 0000000..4e1e044
--- /dev/null
+++ b/config/admin/app.php
@@ -0,0 +1,19 @@
+
+ * @date 2020/06/19
+ */
+
+return [
+ 'default_ajax_return' => 'html',
+
+ // 默认跳转页面对应的模板文件
+ //'dispatch_success_tmpl' => Env::get('app_path') . 'admin/view/template/success.html',
+ //'dispatch_error_tmpl' => Env::get('app_path') . 'admin/view/template/error.html',
+
+ // 异常页面的模板文件
+ //'exception_tmpl' => Env::get('think_path') . 'tpl/think_exception.tpl',
+
+ // 错误显示信息,非调试模式有效
+ 'error_message' => '系统繁忙!请稍后再试~',
+];
\ No newline at end of file
diff --git a/config/admin/paginate.php b/config/admin/paginate.php
new file mode 100755
index 0000000..1cc6ce7
--- /dev/null
+++ b/config/admin/paginate.php
@@ -0,0 +1,12 @@
+
+ * @date 2020/06/19
+ */
+
+//分页配置
+return [
+ 'type' => '\tools\BearPage',
+ 'var_page' => 'page',
+ 'list_rows' => 10,
+];
\ No newline at end of file
diff --git a/config/admin/template.php b/config/admin/template.php
new file mode 100755
index 0000000..cc9ef5d
--- /dev/null
+++ b/config/admin/template.php
@@ -0,0 +1,19 @@
+
+ * @date 2020/06/19
+ */
+return [
+
+ //模版内标签替换
+ 'tpl_replace_string' => [
+ '__ADMIN_STATIC__' => '/static/admin',
+ '__ADMIN_JS__' => '/static/admin/js',
+ '__ADMIN_CSS__' => '/static/admin/css',
+ '__ADMIN_FONTS__' => '/static/admin/fonts',
+ '__ADMIN_IMAGES__' => '/static/admin/images',
+ '__ADMIN_PLUGINS__' => '/static/admin/plugins',
+ ]
+
+];
diff --git a/config/api.php b/config/api.php
new file mode 100755
index 0000000..29e08da
--- /dev/null
+++ b/config/api.php
@@ -0,0 +1,22 @@
+
+ * @date 2020/06/19
+ */
+
+return [
+ //api跨域设置
+ 'cross_domain' => [
+ //是否允许跨域
+ 'allow' => true,
+ //header设置
+ 'header' => [
+ 'Access-Control-Allow-Origin' => '*',
+ 'Access-Control-Allow-Methods' => '*',
+ 'Access-Control-Allow-Headers' => 'content-type,token',
+ 'Access-Control-Request-Headers' => 'Origin, content-Type, Accept, token',
+ ],
+
+ ],
+];
diff --git a/config/api/jwt.php b/config/api/jwt.php
new file mode 100755
index 0000000..6bdc214
--- /dev/null
+++ b/config/api/jwt.php
@@ -0,0 +1,19 @@
+ 'token',
+ //token加密使用的secret
+ 'secret' => '552ac90778a976c72f7f673db174df30',
+ //颁发者
+ 'iss' => 'iss',
+ //使用者
+ 'aud' => 'aud',
+ //过期时间,以秒为单位,默认2小时
+ 'ttl' => 30*60*60*24,
+ //刷新时间,以秒为单位,默认14天,以
+ 'refresh_ttl' => 1209600,
+ //是否自动刷新,开启后可自动刷新token,附在header中返回,name为`Authorization`,字段为`Bearer `+$token
+ 'auto_refresh' => true,
+ //黑名单宽限期,以秒为单位,首次token刷新之后在此时间内原token可以继续访问
+ 'blacklist_grace_period' => 60
+];
\ No newline at end of file
diff --git a/config/app.php b/config/app.php
new file mode 100755
index 0000000..634a585
--- /dev/null
+++ b/config/app.php
@@ -0,0 +1,155 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 应用设置
+// +----------------------------------------------------------------------
+
+return [
+ // 应用名称
+ 'app_name' => 'AdminDemo',
+ // 应用地址
+ 'app_host' => 'https://admindemo.yupoxiong.com',
+ // 应用调试模式
+ 'app_debug' => true,
+ // 应用Trace
+ 'app_trace' => false,
+ // 是否支持多模块
+ 'app_multi_module' => true,
+ // 入口自动绑定模块
+ 'auto_bind_module' => false,
+ // 注册的根命名空间
+ 'root_namespace' => [],
+ // 默认输出类型
+ 'default_return_type' => 'html',
+ // 默认AJAX 数据返回格式,可选json xml ...
+ 'default_ajax_return' => 'json',
+ // 默认JSONP格式返回的处理方法
+ 'default_jsonp_handler' => 'jsonpReturn',
+ // 默认JSONP处理方法
+ 'var_jsonp_handler' => 'callback',
+ // 默认时区
+ 'default_timezone' => 'Asia/Shanghai',
+ // 是否开启多语言
+ 'lang_switch_on' => false,
+ // 默认全局过滤方法 用逗号分隔多个
+ 'default_filter' => '',
+ // 默认语言
+ 'default_lang' => 'zh-cn',
+ // 应用类库后缀
+ 'class_suffix' => false,
+ // 控制器类后缀
+ 'controller_suffix' => 'Controller',
+
+ // +----------------------------------------------------------------------
+ // | 模块设置
+ // +----------------------------------------------------------------------
+
+ // 默认模块名
+ 'default_module' => 'index',
+ // 禁止访问模块
+ 'deny_module_list' => ['common'],
+ // 默认控制器名
+ 'default_controller' => 'Index',
+ // 默认操作名
+ 'default_action' => 'index',
+ // 默认验证器
+ 'default_validate' => '',
+ // 默认的空模块名
+ 'empty_module' => '',
+ // 默认的空控制器名
+ 'empty_controller' => 'Error',
+ // 操作方法前缀
+ 'use_action_prefix' => false,
+ // 操作方法后缀
+ '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' => '/',
+ // HTTPS代理标识
+ 'https_agent_name' => '',
+ // IP代理获取标识
+ 'http_agent_ip' => 'X-REAL-IP',
+ // URL伪静态后缀
+ 'url_html_suffix' => 'html',
+ // URL普通方式参数 用于自动生成
+ 'url_common_param' => false,
+ // URL参数方式 0 按名称成对解析 1 按顺序解析
+ 'url_param_type' => 0,
+ // 是否开启路由延迟解析
+ 'url_lazy_route' => true,
+ // 是否强制使用路由
+ 'url_route_must' => false,
+ // 合并路由规则
+ 'route_rule_merge' => false,
+ // 路由是否完全匹配
+ 'route_complete_match' => false,
+ // 使用注解路由
+ 'route_annotation' => 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' => [],
+ // 是否开启路由缓存
+ 'route_check_cache' => false,
+ // 路由缓存的Key自定义设置(闭包),默认为当前URL和请求类型的md5
+ 'route_check_cache_key' => '',
+ // 路由缓存类型及参数
+ 'route_cache_option' => [],
+
+ // 默认跳转页面对应的模板文件
+ 'dispatch_success_tmpl' => Env::get('think_path') . 'tpl/dispatch_jump.tpl',
+ 'dispatch_error_tmpl' => Env::get('think_path') . 'tpl/dispatch_jump.tpl',
+
+ // 异常页面的模板文件
+ 'exception_tmpl' => Env::get('think_path') . 'tpl/think_exception.tpl',
+
+ // 错误显示信息,非调试模式有效
+ 'error_message' => '页面错误!请稍后再试~',
+ // 显示错误信息
+ 'show_error_msg' => false,
+ // 异常处理handle类 留空使用 \think\exception\Handle
+ 'exception_handle' => '\\app\\common\\exception\\Http',
+ //程序加密密码,默认为`Taoqi,I love you.`的md5
+ 'app_key' => '51971d1dce6bd74b2b6117b06fa5aaf1',
+
+ 'http_exception_template' => [
+ // 定义404错误的模板文件地址
+ 404 => Env::get('app_path') . 'public/404.html',
+ // 还可以定义其它的HTTP status
+ //401 => Env::get('app_path') . '401.html',
+ ],
+
+];
diff --git a/config/attachment.php b/config/attachment.php
new file mode 100755
index 0000000..c3b5c91
--- /dev/null
+++ b/config/attachment.php
@@ -0,0 +1,17 @@
+
+ */
+
+return [
+ 'thumb_path'=>'/static/attachment/thumbnail/',
+ 'path' => app()->getRootPath() . 'public/uploads/attachment/', //上传目录配置(相对于根目录)
+ 'url' => '/uploads/attachment/', //url(相对于web目录)
+ 'validate' => [
+ //默认不超过50mb(52428800)
+ 'size' => 10240, //demo改成了不超过10k
+ //常用后缀
+ 'ext' => 'bmp,ico,psd,jpg,jpeg,png,gif,doc,docx,xls,xlsx,pdf,zip,rar,7z,tz,mp3,mp4,mov,swf,flv,avi,mpg,ogg,wav,flac,ape',
+ ],
+];
\ No newline at end of file
diff --git a/config/cache.php b/config/cache.php
new file mode 100755
index 0000000..985dbb1
--- /dev/null
+++ b/config/cache.php
@@ -0,0 +1,25 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 缓存设置
+// +----------------------------------------------------------------------
+
+return [
+ // 驱动方式
+ 'type' => 'File',
+ // 缓存保存目录
+ 'path' => '',
+ // 缓存前缀
+ 'prefix' => '',
+ // 缓存有效期 0表示永久缓存
+ 'expire' => 0,
+];
diff --git a/config/console.php b/config/console.php
new file mode 100755
index 0000000..a7fabca
--- /dev/null
+++ b/config/console.php
@@ -0,0 +1,20 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 控制台配置
+// +----------------------------------------------------------------------
+return [
+ 'name' => 'Think Console',
+ 'version' => '0.1',
+ 'user' => null,
+ 'auto_path' => env('app_path') . 'command' . DIRECTORY_SEPARATOR,
+];
diff --git a/config/cookie.php b/config/cookie.php
new file mode 100755
index 0000000..626be69
--- /dev/null
+++ b/config/cookie.php
@@ -0,0 +1,30 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | Cookie设置
+// +----------------------------------------------------------------------
+return [
+ // cookie 名称前缀
+ 'prefix' => '',
+ // cookie 保存时间
+ 'expire' => 5201314,
+ // cookie 保存路径
+ 'path' => '/',
+ // cookie 有效域名
+ 'domain' => '',
+ // cookie 启用安全传输
+ 'secure' => false,
+ // httponly设置
+ 'httponly' => '',
+ // 是否使用 setcookie
+ 'setcookie' => true,
+];
diff --git a/config/database.php b/config/database.php
new file mode 100755
index 0000000..2b9ed8a
--- /dev/null
+++ b/config/database.php
@@ -0,0 +1,63 @@
+
+// +----------------------------------------------------------------------
+
+return [
+ // 数据库类型
+ 'type' => 'mysql',
+ // 服务器地址
+ 'hostname' => '114.215.82.135',
+ // 数据库名
+ 'database' => 'dgg_jimai',
+ // 用户名
+ 'username' => 'dgg_jimai',
+ // 密码
+ 'password' => 'dgg_jimai@028',
+ // 端口
+ 'hostport' => '3306',
+ // 连接dsn
+ 'dsn' => '',
+ // 数据库连接参数
+ 'params' => [],
+ // 数据库编码默认采用utf8
+ 'charset' => 'utf8mb4',
+ // 数据库表前缀
+ 'prefix' => '',
+ // 数据库调试模式
+ 'debug' => true,
+ // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+ 'deploy' => 0,
+ // 数据库读写是否分离 主从式有效
+ 'rw_separate' => false,
+ // 读写分离后 主服务器数量
+ 'master_num' => 1,
+ // 指定从服务器序号
+ 'slave_no' => '',
+ // 自动读取主库数据
+ 'read_master' => false,
+ // 是否严格检查字段是否存在
+ 'fields_strict' => true,
+ // 数据集返回类型
+ 'resultset_type' => 'array',
+ // 自动写入时间戳字段
+ 'auto_timestamp' => false,
+ // 时间字段取出后的默认时间格式
+ 'datetime_format' => 'Y-m-d H:i:s',
+ // 是否需要进行SQL性能分析
+ 'sql_explain' => false,
+ // Builder类
+ 'builder' => '',
+ // Query类
+ 'query' => '\\think\\db\\Query',
+ // 是否需要断线重连
+ 'break_reconnect' => false,
+ // 断线标识字符串
+ 'break_match_str' => [],
+];
diff --git a/config/email.php b/config/email.php
new file mode 100755
index 0000000..f6de24c
--- /dev/null
+++ b/config/email.php
@@ -0,0 +1,24 @@
+
+ * @date 2020/06/19
+ */
+return [
+ 'smtp'=>[
+ //host
+ 'host'=>'smtp.163.com',
+ //用户名
+ 'username'=>'XXXXxxxxx0@163.com',
+ //密码/授权码
+ 'password'=>'xxxxxx',
+ //tls或ssl
+ 'smtp_secure'=>'ssl',
+ //端口
+ 'port'=>465,
+ //发件地址
+ 'address'=>'xxxxxx@163.com',
+ //发件人
+ 'name'=>'发件人名字',
+ ]
+];
\ No newline at end of file
diff --git a/config/geetest.php b/config/geetest.php
new file mode 100755
index 0000000..5b2c2b5
--- /dev/null
+++ b/config/geetest.php
@@ -0,0 +1,12 @@
+
+ * @date 2020/06/19
+ */
+return [
+ //请把ID和KEY换成自己的
+ 'id'=>'ed2e0eb9b8d871c64088b49f4a2054bc',
+ //一定要换成自己的
+ 'key'=>'c84ff2e2b64d6c9126e15846ecffabbd',
+];
\ No newline at end of file
diff --git a/config/generate.php b/config/generate.php
new file mode 100755
index 0000000..086380e
--- /dev/null
+++ b/config/generate.php
@@ -0,0 +1,33 @@
+
+ * @date 2020/06/19
+ */
+
+return [
+ //模版目录
+ 'template' => [
+ 'path' => Env::get('root_path') . 'extend/generate/stub/',
+ 'controller' => Env::get('root_path') . 'extend/generate/stub/Controller.stub',
+ 'model' => Env::get('root_path') . 'extend/generate/stub/Model.stub',
+ 'validate' => Env::get('root_path') . 'extend/generate/stub/Validate.stub',
+ 'view' => [
+ 'index' => Env::get('root_path') . 'extend/generate/stub/view/index.stub',
+ 'index_del1' => Env::get('root_path') . 'extend/generate/stub/view/index/del1.stub',
+ 'index_del2' => Env::get('root_path') . 'extend/generate/stub/view/index/del2.stub',
+ 'index_filter' => Env::get('root_path') . 'extend/generate/stub/view/index/filter.stub',
+ 'index_export' => Env::get('root_path') . 'extend/generate/stub/view/index/export.stub',
+ 'index_select1' => Env::get('root_path') . 'extend/generate/stub/view/index/select1.stub',
+ 'index_select2' => Env::get('root_path') . 'extend/generate/stub/view/index/select2.stub',
+ 'add' => Env::get('root_path') . 'extend/generate/stub/view/add.stub',
+ ],
+ ],
+ //生成文件目录
+ 'file_dir' => [
+ 'controller' => Env::get('app_path') . 'admin/controller/',
+ 'model' => Env::get('app_path') . 'common/model/',
+ 'validate' => Env::get('app_path') . 'common/validate/',
+ 'view' => Env::get('app_path') . 'admin/view/',
+ ],
+];
\ No newline at end of file
diff --git a/config/index/template.php b/config/index/template.php
new file mode 100755
index 0000000..1f628d9
--- /dev/null
+++ b/config/index/template.php
@@ -0,0 +1,17 @@
+ [
+ '__STATIC__' => '/static/index',
+ '__JS__' => '/static/index/js',
+ '__CSS__' => '/static/index/css',
+ '__FONTS__' => '/static/index/fonts',
+ '__IMAGES__' => '/static/index/images',
+ '__PLUGINS__' => '/static/index/plugins',
+ ]
+
+];
diff --git a/config/log.php b/config/log.php
new file mode 100755
index 0000000..b3d87b4
--- /dev/null
+++ b/config/log.php
@@ -0,0 +1,30 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 日志设置
+// +----------------------------------------------------------------------
+return [
+ // 日志记录方式,内置 file socket 支持扩展
+ 'type' => 'File',
+ // 日志保存目录
+ 'path' => '',
+ // 日志记录级别
+ 'level' => [],
+ // 单文件日志写入
+ 'single' => false,
+ // 独立日志级别
+ 'apart_level' => [],
+ // 最大日志文件数量
+ 'max_files' => 0,
+ // 是否关闭日志写入
+ 'close' => false,
+];
diff --git a/config/middleware.php b/config/middleware.php
new file mode 100755
index 0000000..fe15ec3
--- /dev/null
+++ b/config/middleware.php
@@ -0,0 +1,18 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 中间件配置
+// +----------------------------------------------------------------------
+return [
+ // 默认中间件命名空间
+ 'default_namespace' => 'app\\http\\middleware\\',
+];
diff --git a/config/session.php b/config/session.php
new file mode 100755
index 0000000..96ce03e
--- /dev/null
+++ b/config/session.php
@@ -0,0 +1,26 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 会话设置
+// +----------------------------------------------------------------------
+
+return [
+ 'id' => '',
+ // SESSION_ID的提交变量,解决flash上传跨域
+ 'var_session_id' => '',
+ // SESSION 前缀
+ 'prefix' => '',
+ // 驱动方式 支持redis memcache memcached
+ 'type' => '',
+ // 是否自动开启 SESSION
+ 'auto_start' => true,
+];
diff --git a/config/sms.php b/config/sms.php
new file mode 100755
index 0000000..aa0e1b5
--- /dev/null
+++ b/config/sms.php
@@ -0,0 +1,36 @@
+
+ * @date 2020/06/19
+ */
+return [
+ // HTTP 请求的超时时间(秒)
+ 'timeout' => 5.0,
+
+ // 默认发送配置
+ 'default' => [
+ // 网关调用策略,默认:顺序调用
+ 'strategy' => \Overtrue\EasySms\Strategies\OrderStrategy::class,
+
+ // 默认可用的发送网关
+ 'gateways' => [
+ 'yunpian', 'aliyun',
+ ],
+ ],
+ // 可用的网关配置
+ 'gateways' => [
+ 'errorlog' => [
+ 'file' => app()->getRuntimePath().'sms/easy-sms.log',
+ ],
+ 'aliyun' => [
+ 'access_key_id' => 'xxxxxxxxxx',
+ 'access_key_secret' => 'xxxxxxxxxx',
+ 'sign_name' => 'xxxxxxxxxx',
+ ],
+ 'yunpian' => [
+ 'api_key' => 'xxxxxxxxxx',
+ ],
+ //...
+ ],
+];
\ No newline at end of file
diff --git a/config/template.php b/config/template.php
new file mode 100755
index 0000000..299bd6f
--- /dev/null
+++ b/config/template.php
@@ -0,0 +1,35 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 模板设置
+// +----------------------------------------------------------------------
+
+return [
+ // 模板引擎类型 支持 php think 支持扩展
+ 'type' => 'Think',
+ // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
+ 'auto_rule' => 1,
+ // 模板路径
+ 'view_path' => '',
+ // 模板后缀
+ 'view_suffix' => 'html',
+ // 模板文件名分隔符
+ 'view_depr' => DIRECTORY_SEPARATOR,
+ // 模板引擎普通标签开始标记
+ 'tpl_begin' => '{',
+ // 模板引擎普通标签结束标记
+ 'tpl_end' => '}',
+ // 标签库标签开始标记
+ 'taglib_begin' => '{',
+ // 标签库标签结束标记
+ 'taglib_end' => '}',
+];
diff --git a/config/trace.php b/config/trace.php
new file mode 100755
index 0000000..425d301
--- /dev/null
+++ b/config/trace.php
@@ -0,0 +1,18 @@
+
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | Trace设置 开启 app_trace 后 有效
+// +----------------------------------------------------------------------
+return [
+ // 内置Html Console 支持扩展
+ 'type' => 'Html',
+];
diff --git a/config/ueditor.php b/config/ueditor.php
new file mode 100755
index 0000000..45e5f3f
--- /dev/null
+++ b/config/ueditor.php
@@ -0,0 +1,86 @@
+
+ * @date 2020/06/19
+ */
+
+return [
+
+ 'imageActionName' => 'uploadimage',
+ 'imageFieldName' => 'upfile',
+ 'imageMaxSize' => 20480, //demo改成了20k
+ 'imageAllowFiles' => [
+ '.png',
+ '.jpg',
+ '.jpeg',
+ '.gif',
+ '.bmp'
+ ],
+ 'imageCompressEnable' => true,
+ 'imageCompressBorder' => 1600,
+ 'imageInsertAlign' => 'none',
+ 'imageUrlPrefix' => '',//配置域名
+ 'imagePathFormat' => '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
+ 'scrawlActionName' => 'uploadscrawl',
+ 'scrawlFieldName' => 'upfile',
+ 'scrawlPathFormat' => '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
+ 'scrawlMaxSize' => 20480,
+ 'scrawlUrlPrefix' => '',
+
+ 'scrawlInsertAlign' => 'none',
+ 'scrawlAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp',],
+ 'snapscreenActionName' => 'uploadimage',
+ 'snapscreenPathFormat' => '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
+ 'snapscreenUrlPrefix' => '',//配置域名
+ 'snapscreenInsertAlign' => 'none',
+ 'catcherLocalDomain' => ['127.0.0.1', 'localhost', 'img.baidu.com',],
+ 'catcherActionName' => 'catchimage',
+ 'catcherFieldName' => 'source',
+ 'catcherPathFormat' => '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
+ 'catcherUrlPrefix' => '',
+ 'catcherMaxSize' => 20480,
+ 'catcherAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ ],
+ 'videoActionName' => 'uploadvideo',
+ 'videoFieldName' => 'upfile',
+ 'videoPathFormat' => '/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}',
+ 'videoUrlPrefix' => '',//配置域名
+ 'videoMaxSize' => 40960,
+ 'videoAllowFiles' => [
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid'
+ ],
+ 'fileActionName' => 'uploadfile',
+ 'fileFieldName' => 'upfile',
+ 'filePathFormat' => '/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}',
+ 'fileUrlPrefix' => '',//配置域名
+ 'fileMaxSize' => 10240,
+ 'fileAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
+ '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
+ '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml'
+ ],
+ 'imageManagerActionName' => 'listimage',
+ 'imageManagerListPath' => '/ueditor/php/upload/image/',
+ 'imageManagerListSize' => 20,
+ 'imageManagerUrlPrefix' => '',//配置域名
+ 'imageManagerInsertAlign' => 'none',
+ 'imageManagerAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ ],
+ 'fileManagerActionName' => 'listfile',
+ 'fileManagerListPath' => '/ueditor/php/upload/file/',
+ 'fileManagerUrlPrefix' => '',//配置域名
+ 'fileManagerListSize' => 20,
+ 'fileManagerAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
+ '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
+ '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml'
+ ]
+];
\ No newline at end of file
diff --git a/config/wechat.php b/config/wechat.php
new file mode 100755
index 0000000..a6afce7
--- /dev/null
+++ b/config/wechat.php
@@ -0,0 +1,83 @@
+
+ * @date 2020/06/19
+ */
+return [
+ /**
+ * 账号基本信息,请从微信公众平台/开放平台获取
+ */
+ 'app_id' => 'your-app-id', // AppID
+ 'secret' => 'your-app-secret', // AppSecret
+ 'token' => 'your-token', // Token
+ 'aes_key' => '', // EncodingAESKey,兼容与安全模式下请一定要填写!!!
+
+
+ /**
+ * 微信支付配置
+ */
+
+ 'key' => 'key-for-signature', // API 密钥
+
+ // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
+ 'cert_path' => 'path/to/your/cert.pem', // XXX: 绝对路径!!!!
+ 'key_path' => 'path/to/your/key', // XXX: 绝对路径!!!!
+
+ 'notify_url' => '默认的订单回调地址', // 你也可以在下单时单独设置来想覆盖它
+ /**
+ * 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
+ * 使用自定义类名时,构造函数将会接收一个 `EasyWeChat\Kernel\Http\Response` 实例
+ */
+ 'response_type' => 'array',
+ /**
+ * 日志配置
+ *
+ * level: 日志级别, 可选为:
+ * debug/info/notice/warning/error/critical/alert/emergency
+ * path:日志文件位置(绝对路径!!!),要求可写权限
+ */
+ 'log' => [
+ 'default' => 'dev', // 默认使用的 channel,生产环境可以改为下面的 prod
+ 'channels' => [
+ // 测试环境
+ 'dev' => [
+ 'driver' => 'single',
+ 'path' => '/tmp/easywechat.log',
+ 'level' => 'debug',
+ ],
+ // 生产环境
+ 'prod' => [
+ 'driver' => 'daily',
+ 'path' => '/tmp/easywechat.log',
+ 'level' => 'info',
+ ],
+ ],
+ ],
+
+ /**
+ * 接口请求相关配置,超时时间等,具体可用参数请参考:
+ * http://docs.guzzlephp.org/en/stable/request-config.html
+ *
+ * - retries: 重试次数,默认 1,指定当 http 请求失败时重试的次数。
+ * - retry_delay: 重试延迟间隔(单位:ms),默认 500
+ * - log_template: 指定 HTTP 日志模板,请参考:https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
+ */
+ 'http' => [
+ 'max_retries' => 1,
+ 'retry_delay' => 500,
+ 'timeout' => 5.0,
+ // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri
+ ],
+
+ /**
+ * OAuth 配置
+ *
+ * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
+ * callback:OAuth授权完成后的回调页地址
+ */
+ 'oauth' => [
+ 'scopes' => ['snsapi_userinfo'],
+ 'callback' => '/index/auth/wechat_callback.php',
+ ],
+];
\ No newline at end of file
diff --git a/database/migrations/20190302092540_admin_menu.php b/database/migrations/20190302092540_admin_menu.php
new file mode 100755
index 0000000..d7a1068
--- /dev/null
+++ b/database/migrations/20190302092540_admin_menu.php
@@ -0,0 +1,46 @@
+
+ */
+
+use think\Db;
+use think\migration\Migrator;
+use think\migration\db\Column;
+
+class AdminMenu extends Migrator
+{
+ public function change()
+ {
+ $table = $this->table('admin_menu', ['comment'=>'后台菜单','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table->addColumn('parent_id', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '父级菜单'])
+ ->addColumn('name', 'string', ['limit' => 30, 'default' => '', 'comment' => '名称'])
+ ->addColumn('url', 'string', ['limit' => 100, 'default' => '', 'comment' => 'url'])
+ ->addColumn('icon', 'string', ['limit' => 30, 'default' => 'fa-list', 'comment' => '图标'])
+ ->addColumn('is_show', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '等级'])
+ ->addColumn('sort_id', 'integer', ['limit' => 10, 'default' => '1000', 'comment' => '排序'])
+ ->addColumn('log_method', 'string', ['limit' => 8, 'default' => '不记录', 'comment' => '记录日志方法'])
+ ->addIndex(['url'], ['name' => 'index_url'])
+ ->create();
+ $this->insertData();
+ }
+
+ protected function insertData()
+ {
+ $data = '[{"id":1,"parent_id":0,"name":"后台首页","url":"admin/index/index","icon":"fa-home","is_show":1,"sort_id":99,"log_method":"不记录"},{"id":2,"parent_id":0,"name":"系统管理","url":"admin/sys","icon":"fa-desktop","is_show":1,"sort_id":1099,"log_method":"不记录"},{"id":3,"parent_id":2,"name":"用户管理","url":"admin/admin_user/index","icon":"fa-user","is_show":1,"sort_id":1000,"log_method":"不记录"},{"id":4,"parent_id":3,"name":"添加用户","url":"admin/admin_user/add","icon":"fa-plus","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":5,"parent_id":3,"name":"修改用户","url":"admin/admin_user/edit","icon":"fa-edit","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":6,"parent_id":3,"name":"删除用户","url":"admin/admin_user/del","icon":"fa-close","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":7,"parent_id":2,"name":"角色管理","url":"admin/admin_role/index","icon":"fa-group","is_show":1,"sort_id":1000,"log_method":"不记录"},{"id":8,"parent_id":7,"name":"添加角色","url":"admin/admin_role/add","icon":"fa-plus","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":9,"parent_id":7,"name":"修改角色","url":"admin/admin_role/edit","icon":"fa-edit","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":10,"parent_id":7,"name":"删除角色","url":"admin/admin_role/del","icon":"fa-close","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":11,"parent_id":7,"name":"角色授权","url":"admin/admin_role/access","icon":"fa-key","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":12,"parent_id":2,"name":"菜单管理","url":"admin/admin_menu/index","icon":"fa-align-justify","is_show":1,"sort_id":1000,"log_method":"不记录"},{"id":13,"parent_id":12,"name":"添加菜单","url":"admin/admin_menu/add","icon":"fa-plus","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":14,"parent_id":12,"name":"修改菜单","url":"admin/admin_menu/edit","icon":"fa-edit","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":15,"parent_id":12,"name":"删除菜单","url":"admin/admin_menu/del","icon":"fa-close","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":16,"parent_id":2,"name":"操作日志","url":"admin/admin_log/index","icon":"fa-keyboard-o","is_show":1,"sort_id":1000,"log_method":"不记录"},{"id":17,"parent_id":16,"name":"查看操作日志详情","url":"admin/admin_log/view","icon":"fa-search-plus","is_show":0,"sort_id":1000,"log_method":"不记录"},{"id":18,"parent_id":2,"name":"个人资料","url":"admin/admin_user/profile","icon":"fa-smile-o","is_show":1,"sort_id":1000,"log_method":"POST"},{"id":19,"parent_id":0,"name":"用户管理","url":"admin/user/mange","icon":"fa-users","is_show":1,"sort_id":1000,"log_method":"不记录"},{"id":20,"parent_id":19,"name":"用户管理","url":"admin/user/index","icon":"fa-user","is_show":1,"sort_id":1000,"log_method":"不记录"},{"id":21,"parent_id":20,"name":"添加用户","url":"admin/user/add","icon":"fa-plus","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":22,"parent_id":20,"name":"修改用户","url":"admin/user/edit","icon":"fa-pencil","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":23,"parent_id":20,"name":"删除用户","url":"admin/user/del","icon":"fa-trash","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":24,"parent_id":20,"name":"启用用户","url":"admin/user/enable","icon":"fa-circle","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":25,"parent_id":20,"name":"禁用用户","url":"admin/user/disable","icon":"fa-circle","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":26,"parent_id":19,"name":"用户等级管理","url":"admin/user_level/index","icon":"fa-th-list","is_show":1,"sort_id":1000,"log_method":"不记录"},{"id":27,"parent_id":26,"name":"添加用户等级","url":"admin/user_level/add","icon":"fa-plus","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":28,"parent_id":26,"name":"修改用户等级","url":"admin/user_level/edit","icon":"fa-pencil","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":29,"parent_id":26,"name":"删除用户等级","url":"admin/user_level/del","icon":"fa-trash","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":30,"parent_id":26,"name":"启用用户等级","url":"admin/user_level/enable","icon":"fa-circle","is_show":0,"sort_id":1000,"log_method":"POST"},{"id":31,"parent_id":26,"name":"禁用用户等级","url":"admin/user_level/disable","icon":"fa-circle","is_show":0,"sort_id":1000,"log_method":"POST"}]';
+
+ $msg = '后台管理菜单导入成功.' . "\n";
+ Db::startTrans();
+ $data = json_decode($data, true);
+ try {
+ foreach ($data as $item) {
+ \app\admin\model\AdminMenu::create($item);
+ }
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ $msg = $e->getMessage();
+ }
+ print ($msg);
+ }
+}
diff --git a/database/migrations/20190302094849_admin_user.php b/database/migrations/20190302094849_admin_user.php
new file mode 100755
index 0000000..4357141
--- /dev/null
+++ b/database/migrations/20190302094849_admin_user.php
@@ -0,0 +1,55 @@
+
+ */
+
+use think\Db;
+use think\migration\Migrator;
+use think\migration\db\Column;
+
+class AdminUser extends Migrator
+{
+ public function change()
+ {
+ $table = $this->table('admin_user', ['comment'=>'后台用户','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('username', 'string', ['limit' => 30, 'default' => '', 'comment' => '用户名'])
+ ->addColumn('password', 'string', ['limit' => 255, 'default' => password_hash('_default__password_', 1), 'comment' => '密码'])
+ ->addColumn('nickname', 'string', ['limit' => 30, 'default' => '', 'comment' => '昵称'])
+ ->addColumn('avatar', 'string', ['limit' => 255, 'default' => '/static/admin/images/avatar.png', 'comment' => '头像'])
+ ->addColumn('role', 'string', ['limit' => 200, 'default' => '', 'comment' => '角色'])
+ ->addColumn('status', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否启用'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->addIndex(['username'], ['name' => 'index_username'])
+ ->create();
+
+ $this->insertData();
+ }
+
+ protected function insertData()
+ {
+ $data = [
+ [
+ 'id' => 1,
+ 'username' => 'super-admin',
+ 'nickname' => '超级管理员',
+ 'password' => 'super-admin',
+ 'role' => [1]
+ ]
+ ];
+
+ $msg = '超级管理员创建成功.' . "\n" . '用户名:super-admin' . "\n" . '密码:super-admin' . "\n";
+ Db::startTrans();
+ try {
+ foreach ($data as $item) {
+ \app\admin\model\AdminUser::create($item);
+ }
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ $msg = $e->getMessage();
+ }
+ print ($msg);
+ }
+}
diff --git a/database/migrations/20190302094853_admin_log.php b/database/migrations/20190302094853_admin_log.php
new file mode 100755
index 0000000..efa2cd0
--- /dev/null
+++ b/database/migrations/20190302094853_admin_log.php
@@ -0,0 +1,25 @@
+
+ */
+
+use think\migration\Migrator;
+use think\migration\db\Column;
+
+class AdminLog extends Migrator
+{
+ public function change()
+ {
+ $table = $this->table('admin_log', ['comment'=>'后台操作日志','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('admin_user_id', 'integer', ['limit' => 10, 'comment' => '用户'])
+ ->addColumn('name', 'string', ['limit' => 30, 'default' => '', 'comment' => '操作'])
+ ->addColumn('url', 'string', ['limit' => 100, 'default' => '', 'comment' => 'URL'])
+ ->addColumn('log_method', 'string', ['limit' => 8, 'default' => '不记录', 'comment' => '记录日志方法'])
+ ->addColumn('log_ip', 'string', ['limit' => 20, 'default' => '', 'comment' => '操作IP'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'comment' => '操作时间'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20190302094933_admin_role.php b/database/migrations/20190302094933_admin_role.php
new file mode 100755
index 0000000..75a9c8a
--- /dev/null
+++ b/database/migrations/20190302094933_admin_role.php
@@ -0,0 +1,50 @@
+
+ */
+
+use think\Db;
+use think\migration\Migrator;
+use think\migration\db\Column;
+
+class AdminRole extends Migrator
+{
+ public function change()
+ {
+ $table = $this->table('admin_role', ['comment'=>'后台角色','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('description', 'string', ['limit' => 100, 'default' => '', 'comment' => '简介'])
+ ->addColumn('url', 'string', ['limit' => 1000, 'default' => '', 'comment' => '权限'])
+ ->addColumn('status', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否启用'])
+ ->create();
+ $this->insertData();
+ }
+
+ protected function insertData()
+ {
+ $data = [
+ [
+ 'id' => 1,
+ 'name' => '管理员',
+ 'description' => '后台管理员角色',
+ 'url' => range(1,31),
+ 'status' => 1
+ ],
+ ];
+
+ $msg = '添加管理员角色成功.' . "\n";
+ Db::startTrans();
+ try {
+ foreach ($data as $item) {
+ \app\admin\model\AdminRole::create($item);
+ }
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ $msg = $e->getMessage();
+ }
+ print ($msg);
+ }
+}
diff --git a/database/migrations/20190312021143_admin_log_data.php b/database/migrations/20190312021143_admin_log_data.php
new file mode 100755
index 0000000..7a9e112
--- /dev/null
+++ b/database/migrations/20190312021143_admin_log_data.php
@@ -0,0 +1,21 @@
+
+ */
+
+use think\migration\Migrator;
+use think\migration\db\Column;
+
+class AdminLogData extends Migrator
+{
+ public function change()
+ {
+ $table = $this->table('admin_log_data', ['comment'=>'后台操作日志数据','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('admin_log_id', 'integer', ['limit' => 11, 'comment' => '日志ID'])
+ ->addColumn('data', 'text', [ 'comment' => '日志内容'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20190518030432_attachment.php b/database/migrations/20190518030432_attachment.php
new file mode 100755
index 0000000..3860341
--- /dev/null
+++ b/database/migrations/20190518030432_attachment.php
@@ -0,0 +1,32 @@
+table('attachment', ['comment' => '附件表', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('admin_user_id', 'integer', ['limit' => 11, 'comment' => '后台用户ID'])
+ ->addColumn('user_id', 'integer', ['limit' => 11, 'comment' => '前台用户ID'])
+ ->addColumn('original_name', 'string', ['limit' => 200, 'default' => '', 'comment' => '原文件名'])
+ ->addColumn('save_name', 'string', ['limit' => 200, 'default' => '', 'comment' => '保存文件名'])
+ ->addColumn('save_path', 'string', ['limit' => 255, 'default' => '', 'comment' => '系统完整路径'])
+ ->addColumn('url', 'string', ['limit' => 255, 'default' => '', 'comment' => '系统完整路径'])
+ ->addColumn('extension', 'string', ['limit' => 100, 'default' => '', 'comment' => '后缀'])
+ ->addColumn('mime', 'string', ['limit' => 100, 'default' => '', 'comment' => '类型'])
+ ->addColumn('size', 'biginteger', ['limit' => 21, 'default' => '0', 'comment' => '大小'])
+ ->addColumn('md5', 'string', ['limit' => 32, 'default' => '', 'comment' => 'MD5'])
+ ->addColumn('sha1', 'string', ['limit' => 40, 'default' => '', 'comment' => 'SHA1'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190615081122_user.php b/database/migrations/20190615081122_user.php
new file mode 100755
index 0000000..88027b2
--- /dev/null
+++ b/database/migrations/20190615081122_user.php
@@ -0,0 +1,45 @@
+table('user', ['comment' => '用户', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('avatar', 'string', ['limit' => 255, 'default' => '/static/index/images/avatar.png', 'comment' => '头像'])
+ ->addColumn('username', 'string', ['limit' => 30, 'default' => '', 'comment' => '用户名'])
+ ->addColumn('nickname', 'string', ['limit' => 30, 'default' => '', 'comment' => '昵称'])
+ ->addColumn('mobile', 'string', ['limit' => 11, 'default' => '', 'comment' => '手机号'])
+ ->addColumn('user_level_id', 'integer', ['limit' => 10, 'default' => 1, 'comment' => '用户等级'])
+ ->addColumn('password', 'string', ['limit' => 255, 'default' => password_hash('_app__pass_', 1), 'comment' => '密码'])
+ ->addColumn('status', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否启用'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ $this->insertData();
+ }
+
+ protected function insertData()
+ {
+ $data = '[{"id":1,"avatar":"/uploads/attachment/20190822/02fce9aecd6cadf6e019e988ad8703ce.png","user_level_id":2,"username":"test001","mobile":"13000000001","nickname":"测试001","password":"$2y$10$HU5eKkvynPi0iP/eQqSrmuwUMQhDB18QLLNCwtAvc09KKoLuv3I16","status":1},{"id":2,"avatar":"/uploads/attachment/20190822/56644a9f283c058cd371316e186ef48a.png","user_level_id":3,"username":"test002","mobile":"18328374923","nickname":"测试2号会员","password":"$2y$10$HU5eKkvynPi0iP/eQqSrmuwUMQhDB18QLLNCwtAvc09KKoLuv3I16","status":1},{"id":3,"avatar":"/uploads/attachment/20190822/f0a7cd43074283b428b0a33ecfca5f9d.png","user_level_id":4,"username":"测试3号","mobile":"18653165683","nickname":"测试3号","password":"$2y$10$HU5eKkvynPi0iP/eQqSrmuwUMQhDB18QLLNCwtAvc09KKoLuv3I16","status":1},{"id":4,"avatar":"/uploads/attachment/20190822/1771ce624eccb96aad992df540126d3b.png","user_level_id":1,"username":"小女孩","mobile":"13638392923","nickname":"小女孩","password":"$2y$10$HU5eKkvynPi0iP/eQqSrmuwUMQhDB18QLLNCwtAvc09KKoLuv3I16","status":1}]';
+
+ $msg = '前台测试用户导入成功.' . "\n";
+ Db::startTrans();
+ $data = json_decode($data, true);
+ try {
+ foreach ($data as $item) {
+ \app\common\model\User::create($item);
+ }
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ $msg = $e->getMessage();
+ }
+ print ($msg);
+ }
+}
diff --git a/database/migrations/20190807030806_region.php b/database/migrations/20190807030806_region.php
new file mode 100755
index 0000000..e834ed8
--- /dev/null
+++ b/database/migrations/20190807030806_region.php
@@ -0,0 +1,111 @@
+table('region', ['comment' => '省市区表', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $region->addColumn('parent_id', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '父级ID'])
+ ->addColumn('level', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '等级'])
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('initial', 'string', ['limit' => 50, 'default' => '', 'comment' => '首字母'])
+ ->addColumn('pinyin', 'string', ['limit' => 255, 'default' => '', 'comment' => '拼音'])
+ ->addColumn('citycode', 'string', ['limit' => 10, 'default' => '', 'comment' => '城市编码'])
+ ->addColumn('adcode', 'string', ['limit' => 10, 'default' => '', 'comment' => '区域编码'])
+ ->addColumn('lng_lat', 'string', ['limit' => 30, 'default' => '', 'comment' => '中心经纬度'])
+ ->addIndex(['name'], ['name' => 'index_name'])
+ ->addIndex(['initial'], ['name' => 'index_initial'])
+ ->addIndex(['pinyin'], ['name' => 'index_pinyin'])
+ ->addIndex(['name', 'initial', 'pinyin'], ['name' => 'index_name_initial_pinyin'])
+ ->create();
+ $this->insertData();
+
+ }
+
+ /**
+ * 插入数据
+ */
+ public function insertData()
+ {
+ print ('正在下载json数据压缩包···' . "\n");
+ $online_zip = file_get_contents('http://json.think-region.yupoxiong.com/region.json.zip');
+ $zip_file = app()->getRuntimePath() . 'region.json.zip';
+ $json_file = app()->getRuntimePath() . 'region.json';
+ file_put_contents($zip_file, $online_zip);
+
+ print ('正在解压json数据压缩包···' . "\n");
+ $zipArc = new ZipArchive();
+ $zipArc->open($zip_file);
+ $zipArc->extractTo(app()->getRuntimePath());
+ $zipArc->close();
+
+ print ('正在读取json数据···' . "\n");
+ $json = file_get_contents($json_file);
+ $data = json_decode($json, true);
+ $msg = "\n" . '数据导入成功';
+ $total = count($data) + 1;
+
+ print ('正在导入数据···' . "\n");
+ Db::startTrans();
+ try {
+ foreach ($data as $key => $value) {
+ \yupoxiong\region\model\Region::create($value);
+ $this->showStatus($key + 1, $total, 10);
+ }
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ $msg = $e->getMessage();
+ }
+ print ($msg . "\n");
+ unset($data);
+ unlink($zip_file);
+ unlink($json_file);
+ }
+
+ /**
+ * 显示进度
+ * @param $done
+ * @param $total
+ * @param int $size
+ */
+ protected function showStatus($done, $total, $size = 20)
+ {
+ static $start_time;
+ if ($done > $total) return;
+ if (empty($start_time)) $start_time = time();
+ $now = time();
+ $percent = (double)($done / $total);
+ $bar = floor($percent * $size);
+ $status_bar = "\r[";
+ $status_bar .= str_repeat('=', $bar);
+ if ($bar < $size) {
+ $status_bar .= '>';
+ $status_bar .= str_repeat(' ', $size - $bar);
+ } else {
+ $status_bar .= '=';
+ }
+ $display = number_format($percent * 100, 0);
+ $status_bar .= "] $display% $done/$total";
+ $rate = ($now - $start_time) / $done;
+ $left = $total - $done;
+ $eta = round($rate * $left, 2);
+ $elapsed = $now - $start_time;
+ $status_bar .= ' 预计剩余: ' . number_format($eta) . ' 秒. 已执行: ' . number_format($elapsed) . ' 秒.';
+ echo "$status_bar ";
+ flush();
+ if ($done === $total) {
+ echo "\n";
+ }
+ }
+
+}
diff --git a/database/migrations/20190822082112_user_level.php b/database/migrations/20190822082112_user_level.php
new file mode 100755
index 0000000..24b986d
--- /dev/null
+++ b/database/migrations/20190822082112_user_level.php
@@ -0,0 +1,46 @@
+table('user_level', ['comment' => '用户等级', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 20, 'default' => '', 'comment' => '名称'])
+ ->addColumn('description', 'string', ['limit' => 50, 'default' => '', 'comment' => '简介'])
+ ->addColumn('img', 'string', ['limit' => 255, 'default' => '/static/index/images/user_level_default.png', 'comment' => '图片'])
+ ->addColumn('status', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否启用'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ $this->insertData();
+ }
+
+ protected function insertData()
+ {
+ $data = '[{"id":1,"name":"普通用户","description":"普通用户","img":"/uploads/attachment/20190822/65e4ad92ece9fdb7f3822ba4fc322bf6.png","status":1},{"id":2,"name":"青铜会员","description":"青铜会员","img":"/uploads/attachment/20190822/d0b153352b15ea7097403c563e9c3be4.png","status":1},{"id":3,"name":"白银会员","description":"白银会员","img":"/uploads/attachment/20190822/72031bafedeba534d1e862b8d717f8db.png","status":1},{"id":4,"name":"黄金会员","description":"黄金会员","img":"/uploads/attachment/20190822/6dcc15ea1701c449e63e6856f0931e2a.png","status":1}]';
+
+ $msg = '前台测试用户等级导入成功.' . "\n";
+ Db::startTrans();
+ $data = json_decode($data, true);
+ try {
+ foreach ($data as $item) {
+ \app\common\model\UserLevel::create($item);
+ }
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ $msg = $e->getMessage();
+ }
+ print ($msg);
+ }
+}
diff --git a/database/migrations/20190829040632_article_category.php b/database/migrations/20190829040632_article_category.php
new file mode 100755
index 0000000..06f5c8e
--- /dev/null
+++ b/database/migrations/20190829040632_article_category.php
@@ -0,0 +1,22 @@
+table('article_category', ['comment'=>'文章分类','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('parent_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '上级分类'])
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829040745_article.php b/database/migrations/20190829040745_article.php
new file mode 100755
index 0000000..a2153e4
--- /dev/null
+++ b/database/migrations/20190829040745_article.php
@@ -0,0 +1,31 @@
+table('article', ['comment' => '文章', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 30, 'default' => '', 'comment' => '标题'])
+ ->addColumn('user_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '发布人'])
+ ->addColumn('article_category_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '所属分类'])
+ ->addColumn('description', 'string', ['limit' => 50, 'default' => '', 'comment' => '简介'])
+ ->addColumn('content', 'text', [ 'comment' => '内容'])
+ ->addColumn('is_top', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否置顶'])
+ ->addColumn('is_hot', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否热门'])
+ ->addColumn('img', 'string', ['limit' => 255, 'default' => '', 'comment' => '缩略图'])
+ ->addColumn('sort_number', 'integer', ['limit' => 10, 'default' => 1000, 'comment' => '排序'])
+ ->addColumn('view_count', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '浏览数'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '发布时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20190829160826_article_comment.php b/database/migrations/20190829160826_article_comment.php
new file mode 100755
index 0000000..1d6139e
--- /dev/null
+++ b/database/migrations/20190829160826_article_comment.php
@@ -0,0 +1,20 @@
+table('article_comment', ['comment'=>'文章评论','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('user_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '评论用户'])
+ ->addColumn('parent_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '父级评论'])
+ ->addColumn('content', 'string', ['limit' => 300, 'default' => '', 'comment' => '评论内容'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829161048_article_tag.php b/database/migrations/20190829161048_article_tag.php
new file mode 100755
index 0000000..beed4a1
--- /dev/null
+++ b/database/migrations/20190829161048_article_tag.php
@@ -0,0 +1,20 @@
+table('article_tag', ['comment'=>'文章标签','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('article_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '文章'])
+ ->addColumn('tag_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '标签'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829161111_tag.php b/database/migrations/20190829161111_tag.php
new file mode 100755
index 0000000..e78c855
--- /dev/null
+++ b/database/migrations/20190829161111_tag.php
@@ -0,0 +1,19 @@
+table('tag', ['comment'=>'标签','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829161327_goods.php b/database/migrations/20190829161327_goods.php
new file mode 100755
index 0000000..ebb05a3
--- /dev/null
+++ b/database/migrations/20190829161327_goods.php
@@ -0,0 +1,31 @@
+table('goods', ['comment' => '商品', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('img', 'string', ['limit' => 255, 'default' => '', 'comment' => '图片'])
+ ->addColumn('slide', 'string', ['limit' => 2000, 'default' => '', 'comment' => '轮播'])
+ ->addColumn('goods_category_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '所属分类'])
+ ->addColumn('brand_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '品牌'])
+ ->addColumn('origin_price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '原价'])
+ ->addColumn('price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '售价'])
+ ->addColumn('attr', 'text', ['comment' => '规格'])
+ ->addColumn('detail', 'text', ['comment' => '详情'])
+ ->addColumn('weight', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '重量'])
+ ->addColumn('stock', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '库存'])
+ ->addColumn('sort_number', 'integer', ['limit' => 10, 'default' => 1000, 'comment' => '排序(升序)'])
+ ->addColumn('status', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否上架'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829161439_order.php b/database/migrations/20190829161439_order.php
new file mode 100755
index 0000000..acd6b7b
--- /dev/null
+++ b/database/migrations/20190829161439_order.php
@@ -0,0 +1,41 @@
+table('order', ['comment' => '订单', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('order_no', 'string', ['limit' => 50, 'default' => '', 'comment' => '订单编号'])
+ ->addColumn('user_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '下单用户'])
+ ->addColumn('order_price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '订单金额'])
+ ->addColumn('pay_price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '支付金额'])
+ ->addColumn('goods_price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '商品总额'])
+ ->addColumn('express_price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '运费'])
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '姓名'])
+ ->addColumn('mobile', 'string', ['limit' => 11, 'default' => '', 'comment' => '手机号'])
+ ->addColumn('province_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '省'])
+ ->addColumn('city_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '市'])
+ ->addColumn('district_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '区县'])
+ ->addColumn('street_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '街道'])
+ ->addColumn('address', 'string', ['limit' => 200, 'default' => '', 'comment' => '收货地址'])
+ ->addColumn('full_address', 'string', ['limit' => 500, 'default' => '', 'comment' => '完整收货地址'])
+ ->addColumn('express_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '快递公司'])
+ ->addColumn('express_no', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '快递单号'])
+ ->addColumn('pay_channel', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '支付渠道'])// 1支付宝,2微信,3余额
+ ->addColumn('pay_status', 'boolean', ['limit' => 1, 'default' => 0, 'comment' => '支付状态'])
+ ->addColumn('pay_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '付款时间'])
+ ->addColumn('deliver_status', 'boolean', ['limit' => 1, 'default' => 0, 'comment' => '发货状态'])// 0未发货,1已发货,2已收货
+ ->addColumn('deliver_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '发货时间'])
+ ->addColumn('receive_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '收货时间'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829161446_cart.php b/database/migrations/20190829161446_cart.php
new file mode 100755
index 0000000..e352885
--- /dev/null
+++ b/database/migrations/20190829161446_cart.php
@@ -0,0 +1,23 @@
+table('cart', ['comment' => '购物车', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+
+ ->addColumn('user_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '用户'])
+ ->addColumn('goods_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '商品'])
+ ->addColumn('number', 'integer', ['limit' => 10, 'default' => 1, 'comment' => '数量'])
+ ->addColumn('attr', 'string', ['limit' => 100, 'default' => '', 'comment' => '规格'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829161654_goods_category.php b/database/migrations/20190829161654_goods_category.php
new file mode 100755
index 0000000..c6f02d2
--- /dev/null
+++ b/database/migrations/20190829161654_goods_category.php
@@ -0,0 +1,21 @@
+table('goods_category', ['comment'=>'商品分类','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('parent_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '上级分类'])
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20190829161715_deliver_address.php b/database/migrations/20190829161715_deliver_address.php
new file mode 100755
index 0000000..62edadd
--- /dev/null
+++ b/database/migrations/20190829161715_deliver_address.php
@@ -0,0 +1,27 @@
+table('deliver_address', ['comment'=>'收货地址','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('user_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '用户'])
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '姓名'])
+ ->addColumn('mobile', 'string', ['limit' => 11, 'default' => '', 'comment' => '手机号'])
+ ->addColumn('province_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '省'])
+ ->addColumn('city_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '市'])
+ ->addColumn('district_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '区'])
+ ->addColumn('street_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '街道'])
+ ->addColumn('detail', 'string', ['limit' => 100, 'default' => '', 'comment' => '详细地址'])
+ ->addColumn('is_default', 'boolean', ['limit' => 1, 'default' => 0, 'comment' => '是否默认'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829163727_brand.php b/database/migrations/20190829163727_brand.php
new file mode 100755
index 0000000..c3852cf
--- /dev/null
+++ b/database/migrations/20190829163727_brand.php
@@ -0,0 +1,20 @@
+table('brand', ['comment'=>'品牌','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('img', 'string', ['limit' => 255, 'default' => '', 'comment' => '图片'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829164459_goods_attr.php b/database/migrations/20190829164459_goods_attr.php
new file mode 100755
index 0000000..7b2c891
--- /dev/null
+++ b/database/migrations/20190829164459_goods_attr.php
@@ -0,0 +1,19 @@
+table('goods_attr', ['comment'=>'商品规格','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829164515_goods_attr_category.php b/database/migrations/20190829164515_goods_attr_category.php
new file mode 100755
index 0000000..eda195c
--- /dev/null
+++ b/database/migrations/20190829164515_goods_attr_category.php
@@ -0,0 +1,19 @@
+table('goods_attr_category', ['comment'=>'商品规格分类','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829172742_express.php b/database/migrations/20190829172742_express.php
new file mode 100755
index 0000000..956329e
--- /dev/null
+++ b/database/migrations/20190829172742_express.php
@@ -0,0 +1,19 @@
+table('express', ['comment'=>'快递','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('code', 'string', ['limit' => 50, 'default' => '', 'comment' => '编码'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190829173031_order_goods.php b/database/migrations/20190829173031_order_goods.php
new file mode 100755
index 0000000..fc6cecd
--- /dev/null
+++ b/database/migrations/20190829173031_order_goods.php
@@ -0,0 +1,25 @@
+table('order_goods', ['comment'=>'订单商品','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('order_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '所属订单'])
+ ->addColumn('goods_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '商品'])
+ ->addColumn('number', 'integer', ['limit' => 10, 'default' => 1, 'comment' => '数量'])
+ ->addColumn('attr', 'string', ['limit' => 200, 'default' => '', 'comment' => '规格'])
+ ->addColumn('price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '单价'])
+ ->addColumn('total_price', 'decimal', ['precision' => 14, 'scale' => 2, 'default' => 0, 'comment' => '总价'])
+
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190904060153_slide.php b/database/migrations/20190904060153_slide.php
new file mode 100755
index 0000000..1079a3d
--- /dev/null
+++ b/database/migrations/20190904060153_slide.php
@@ -0,0 +1,23 @@
+table('slide', ['comment' => '轮播', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('img', 'string', ['limit' => 255, 'default' => '', 'comment' => '图片'])
+ ->addColumn('jump_type', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '跳转类型']) //1商品,2文章,3url
+ ->addColumn('jump_target', 'string', ['limit' => 255, 'default' => '', 'comment' => '跳转目标']) //跳转目标为数据ID或url地址
+ ->addColumn('sort_number', 'integer', ['limit' => 10, 'default' => 1000, 'comment' => '排序'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190904074520_staff.php b/database/migrations/20190904074520_staff.php
new file mode 100755
index 0000000..adcd237
--- /dev/null
+++ b/database/migrations/20190904074520_staff.php
@@ -0,0 +1,31 @@
+table('staff', ['comment' => '员工', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('avatar', 'string', ['limit' => 255, 'default' => '', 'comment' => '照片'])
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '姓名'])
+ ->addColumn('department_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '部门'])
+ ->addColumn('position_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '职位'])
+ ->addColumn('job_number', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '工号'])
+ ->addColumn('mobile', 'string', ['limit' => 11, 'default' => '', 'comment' => '手机号'])
+ ->addColumn('email', 'string', ['limit' => 100, 'default' => '', 'comment' => '邮箱'])
+ ->addColumn('birthday', 'date', [ 'comment' => '生日'])
+ ->addColumn('hired_date', 'date', [ 'comment' => '入职日期'])
+ ->addColumn('is_boss', 'boolean', ['limit' => 1, 'default' => 0, 'comment' => '是否为老板'])
+ ->addColumn('is_leader', 'boolean', ['limit' => 1, 'default' => 0, 'comment' => '是否所属部门领导'])
+ ->addColumn('sort_number', 'integer', ['limit' => 10, 'default' => 1000, 'comment' => '排序'])
+ ->addColumn('status', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否启用'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190904074525_department.php b/database/migrations/20190904074525_department.php
new file mode 100755
index 0000000..f555bf9
--- /dev/null
+++ b/database/migrations/20190904074525_department.php
@@ -0,0 +1,20 @@
+table('department', ['comment'=>'部门','engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('parent_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '上级部门'])
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20190904074743_position.php b/database/migrations/20190904074743_position.php
new file mode 100755
index 0000000..67556bb
--- /dev/null
+++ b/database/migrations/20190904074743_position.php
@@ -0,0 +1,20 @@
+table('position', ['comment' => '职位', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
+ $table
+ ->addColumn('name', 'string', ['limit' => 50, 'default' => '', 'comment' => '名称'])
+ ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
+ ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
+ ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
+ ->create();
+ }
+}
diff --git a/extend/generate/Generate.php b/extend/generate/Generate.php
new file mode 100755
index 0000000..a1c0f3d
--- /dev/null
+++ b/extend/generate/Generate.php
@@ -0,0 +1,1452 @@
+
+ */
+
+namespace generate;
+
+use app\admin\model\AdminMenu;
+use generate\field\Checkbox;
+use generate\field\Color;
+use generate\field\Date;
+use generate\field\DateRange;
+use generate\field\Datetime;
+use generate\field\DatetimeRange;
+use generate\field\Editor;
+use generate\field\Email;
+use generate\field\Field;
+use generate\field\File;
+use generate\field\Icon;
+use generate\field\IdCard;
+use generate\field\Image;
+use generate\field\Ip;
+use generate\field\Map;
+use generate\field\Mobile;
+use generate\field\MultiFile;
+use generate\field\MultiImage;
+use generate\field\MultiSelect;
+use generate\field\Number;
+use generate\field\Password;
+use generate\field\Radio;
+use generate\field\Select;
+use generate\field\SwitchField;
+use generate\field\Text;
+use generate\field\Textarea;
+use generate\field\Url;
+use generate\field\Year;
+use generate\field\YearMonth;
+use generate\field\YearMonthRange;
+use generate\field\YearRange;
+use generate\rule\Required;
+use think\Db;
+use think\facade\Env;
+use generate\traits\Tools;
+
+class Generate
+{
+
+ use Tools;
+
+ protected $config = [];
+
+ //主数据
+ protected $data = [];
+
+
+ /**
+ * 控制器和模型名、验证器名黑名单
+ * @var array
+ */
+ protected $blacklistName = [
+ 'Auth',
+ 'Index',
+ 'AdminUser',
+ 'AdminRole',
+ 'AdminMenu',
+ 'AdminLog',
+ 'AdminLogData',
+ 'Attachment',
+ ];
+
+ /**
+ * 表名黑名单
+ * @var array
+ */
+ protected $blacklistTable = [
+ 'admin_user',
+ 'admin_role',
+ 'admin_menu',
+ 'admin_log',
+ 'admin_log_data',
+ 'migrations',
+ 'attachment',
+ ];
+
+ public function __construct($data = [], $config = null)
+ {
+
+ $root_path = Env::get('root_path');
+ $app_path = Env::get('app_path');
+ $config_tmp = [
+ //模版目录
+ 'template' => [
+ 'path' => $root_path . 'extend/generate/stub/',
+ 'controller' => $root_path . 'extend/generate/stub/Controller.stub',
+ 'model' => $root_path . 'extend/generate/stub/Model.stub',
+ 'validate' => $root_path . 'extend/generate/stub/Validate.stub',
+ 'view' => [
+ 'index' => $root_path . 'extend/generate/stub/view/index.stub',
+ 'index_path' => $root_path . 'extend/generate/stub/view/index/',
+ 'index_del1' => $root_path . 'extend/generate/stub/view/index/del1.stub',
+ 'index_del2' => $root_path . 'extend/generate/stub/view/index/del2.stub',
+ 'index_filter' => $root_path . 'extend/generate/stub/view/index/filter.stub',
+ 'index_export' => $root_path . 'extend/generate/stub/view/index/export.stub',
+ 'index_select1' => $root_path . 'extend/generate/stub/view/index/select1.stub',
+ 'index_select2' => $root_path . 'extend/generate/stub/view/index/select2.stub',
+ 'add' => $root_path . 'extend/generate/stub/view/add.stub',
+ ],
+ ],
+ //生成文件目录
+ 'file_dir' => [
+ 'controller' => $app_path . 'admin/controller/',
+ 'model' => $app_path . 'common/model/',
+ 'validate' => $app_path . 'common/validate/',
+ 'view' => $app_path . 'admin/view/',
+ ],
+ ];
+
+ $config = $config ?? $config_tmp;
+ $this->config = $config;
+
+ $this->data = $data;
+ }
+
+
+ public function run()
+ {
+ $this->checkName($this->data);
+ $this->checkDir();
+
+ $this->createAddView();
+ $this->createIndexView();
+ $this->createController();
+ $this->createModel();
+ $this->createValidate();
+ $this->createMenu();
+ return '生成成功';
+
+ //先判断所有目录是否可写,控制器,模型,验证器,视图
+ //然后生成表,然后再生成各个代码
+ //检查目录
+
+ //检查名称
+
+ //判断是否为
+
+
+ //$this->createTable($this->data);
+
+
+ }
+
+
+ /**
+ * 获取所有表(除黑名单之外)
+ * @return array
+ */
+ public function getTable()
+ {
+ $table_data = Db::query('SHOW TABLES');
+ $table = [];
+
+ foreach ($table_data as $key => $value) {
+ $current = current($value);
+ if (!in_array($current, $this->blacklistTable)) {
+ $table[] = $current;
+ }
+ }
+
+ return $table;
+ }
+
+ /**
+ * 获取后台已有菜单,以select形式返回
+ */
+ public function getMenu()
+ {
+ $selected = 1;
+ $current_id = 0;
+ $result = AdminMenu::where('id', '<>', $current_id)->order('sort_id', 'asc')->order('id', 'asc')->column('id,parent_id,name,sort_id', 'id');
+ foreach ($result as $r) {
+ $r['selected'] = (int)$r['id'] === (int)$selected ? 'selected' : '';
+ }
+ $str = "
\$spacer \$name ";
+ $this->initTree($result);
+ return $this->getTree(0, $str, $selected);
+ }
+
+
+ //获取所有模块
+ protected function getModule()
+ {
+ $module = [];
+ $path = Env::get('app_path');
+ $dir = scandir($path);
+ foreach ($dir as $item) {
+ if ($item !== '.' && $item !== '..' && is_dir($path . $item)) {
+ $module[] = $item;
+ }
+ }
+ return count($module) > 0 ? $module : false;
+ }
+
+ //检查目录(是否可写)
+ protected function checkDir()
+ {
+ if (!is_dir($this->config['file_dir']['controller'])) {
+ $this->mkFolder($this->config['file_dir']['controller']);
+ }
+
+ if (!is_dir($this->config['file_dir']['model'])) {
+ $this->mkFolder($this->config['file_dir']['model']);
+ }
+
+ if (!is_dir($this->config['file_dir']['validate'])) {
+ $this->mkFolder($this->config['file_dir']['validate']);
+ }
+
+ if (!is_dir($this->config['file_dir']['view'])) {
+ $this->mkFolder($this->config['file_dir']['view']);
+ }
+
+
+ if (!is_writable($this->config['file_dir']['controller'])) {
+ throw new \Exception('控制器目录不可写');
+ }
+
+ if (!is_writable($this->config['file_dir']['model'])) {
+ throw new \Exception('模型目录不可写');
+ }
+
+ if (!is_writable($this->config['file_dir']['validate'])) {
+ throw new \Exception('验证器目录不可写');
+ }
+
+ if (!is_writable($this->config['file_dir']['view'])) {
+ throw new \Exception('视图目录不可写');
+ }
+
+ return true;
+ }
+
+ //检查名称是在黑名单,表是否存在
+ protected function checkName($data)
+ {
+ if (in_array($data['controller'], $this->blacklistName)) {
+ throw new \Exception('控制器名非法');
+ }
+
+ if (in_array($data['model'], $this->blacklistName)) {
+ throw new \Exception('模型名非法');
+ }
+
+ if (in_array($data['validate'], $this->blacklistName)) {
+ throw new \Exception('验证器名非法');
+ }
+
+ if (in_array($data['table'], $this->blacklistTable)) {
+ throw new \Exception('表名非法');
+ }
+
+ return true;
+ }
+
+
+ /**
+ * 创建数据表
+ * @param array $data
+ * @return bool
+ */
+ protected function createTable($data = [])
+ {
+ if (count($data) == 0) {
+ $data = $this->data;
+ }
+
+ //字段
+ $fields = [];
+ //索引
+ $indexes = [];
+
+ $fields[] = " `id` int(11) unsigned NOT NULL AUTO_INCREMENT";
+ foreach ($data['data'] as $item) {
+ // 字段
+ $fields[] = " `{$item['field_name']}` {$item['field_type']}"
+ . ($item['not_null'] ? ' NOT NULL' : ' ')
+ . (strtolower($item['default']) == 'null' ? '' : " DEFAULT '{$item['default']}'")
+ . ($item['comment'] === '' ? '' : " COMMENT '{$item['comment']}'");
+
+ // 索引
+ if (isset($item['key']) && $item['key'] && $item['name'] != 'id') {
+ $indexes[] = " KEY `{$item['name']}` (`{$item['name']}`)";
+ }
+ }
+
+ //自动生成时间戳
+ if (isset($data['auto_timestamp']) && $data['auto_timestamp']) {
+ $fields[] = " `create_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间'";
+ $fields[] = " `update_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '更新时间'";
+ }
+ //软删除
+ if (isset($data['soft_delete']) && $data['soft_delete']) {
+ $fields[] = " `delete_time` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除时间'";
+ }
+
+ // 默认主键为id
+ $fields[] = " PRIMARY KEY (`id`) ";
+ //表名
+ $name = config('database.prefix') . $data['table'];
+ $sql = "CREATE TABLE `{$name}` (\n"
+ . implode(",\n", array_merge($fields, $indexes))
+ . "\n)ENGINE=" . (isset($this->data['table_engine']) ? $this->data['table_engine'] : 'InnoDB')
+ . " DEFAULT CHARSET=utf8mb4 COMMENT '{$this->data['cn_name']}'";
+ //记录SQL日志
+ //Log::record("AUTO_CREATE_TABLE:\n{$sql};", 'sql');
+ $msg = 'error';
+ Db::startTrans();
+ try {
+ Db::query($sql);
+ Db::commit();
+ $result = true;
+ } catch (\Exception $e) {
+ Db::rollback();
+ $msg = $e->getMessage();
+ $result = false;
+ }
+
+ if ($result) {
+ return true;
+ }
+ return $msg;
+ }
+
+ //创建控制器
+ protected function createController()
+ {
+
+ //不生成控制器
+ if($this->data['controller']['create']==0){
+ return true;
+ }
+
+ $add_field_code = '';
+ $edit_field_code = '';
+
+ //关联代码
+ $relation_1 = '';
+ $relation_2 = '';
+ $relation_3 = '';
+
+ //导出代码
+ $export_header = '';
+ $export_body = '';
+ $export_name = '';
+ $export_code = '';
+ //with代码
+ $relation_with = '';
+ //with列表
+ $relation_with_list = '';
+
+ foreach ($this->data['data'] as $key => $value) {
+
+ if ($value['is_form'] == 1) {
+ switch ($value['form_type']) {
+ case 'file':
+ $add_field_code_tmp = File::$controllerAddCode;
+ $edit_field_code_tmp = File::$controllerEditCode;
+ break;
+ case 'image':
+ $add_field_code_tmp = Image::$controllerAddCode;
+ $edit_field_code_tmp = Image::$controllerEditCode;
+ break;
+ case 'multi_image':
+ $add_field_code_tmp = MultiImage::$controllerAddCode;
+ $edit_field_code_tmp = MultiImage::$controllerEditCode;
+ break;
+ case 'multi_file':
+ $add_field_code_tmp = MultiFile::$controllerAddCode;
+ $edit_field_code_tmp = MultiFile::$controllerEditCode;
+ break;
+ case 'editor':
+ $add_field_code_tmp = Editor::$controllerAddCode;
+ $edit_field_code_tmp = Editor::$controllerEditCode;
+ break;
+ default:
+ $add_field_code_tmp = '';
+ $edit_field_code_tmp = '';
+ break;
+ }
+
+ $add_field_code_tmp = str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($value['form_name'], $value['field_name']), $add_field_code_tmp);
+ $add_field_code .= $add_field_code_tmp;
+
+ $edit_field_code_tmp = str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($value['form_name'], $value['field_name']), $edit_field_code_tmp);
+ $edit_field_code .= $edit_field_code_tmp;
+
+
+ //关联处理
+ if ($value['is_relation'] == 1 && $value['relation_type'] == 1) {
+
+ $table_name = str_replace('_id', '', $value['field_name']);
+
+ $class_name = parse_name($table_name, 1);
+ $relation_1 .= 'use app\\common\\model\\' . $class_name . ";\n";
+
+ $code_3 = file_get_contents($this->config['template']['path'] . 'controller/relation_assign_2.stub');
+ $list_name = $table_name . '_list';
+ $code_3 = str_replace(array('[LIST_NAME]', '[CLASS_NAME]'), array($list_name, $class_name), $code_3);
+ $relation_3 .= $code_3;
+ }
+ }
+
+ if ($value['is_list'] == 1) {
+
+ //列表关联显示
+ if ($value['is_relation'] == 1 && $value['relation_type'] == 1) {
+ $relation_with_name = str_replace('_id', '', $value['field_name']);
+ $relation_with_list .= empty($relation_with_list) ? $relation_with_name : ',' . $relation_with_name;
+
+ }
+
+ //如果有列表导出
+ if ($this->data['view']['export'] == 1) {
+ $export_header .= "'" . $value['form_name'] . "',";
+ if ($value['getter_setter'] === 'switch') {
+ $export_body .= '$record[' . "'" . $value['field_name'] . "'" . '] = $item->' . $value['field_name'] . '_text' . ";\n";
+ } else if ($value['is_relation'] == 1 && $value['relation_type'] == 1) {
+
+ $relation_name = str_replace('_id', '', $value['field_name']);
+ $export_body .= '$record[' . "'" . $value['field_name'] . "'" . '] = $item->' . $relation_name . '->' . $value['relation_show'] . '?? ' . "'" . "'" . ";\n";
+ } else {
+ $export_body .= '$record[' . "'" . $value['field_name'] . "'" . '] = $item->' . $value['field_name'] . ";\n";
+ }
+ }
+
+ }
+
+ }
+
+
+ //启用禁用
+ $enable_code = '';
+ if (in_array(5, $this->data['controller']['action'])) {
+ $enable_tmp = file_get_contents($this->config['template']['path'] . 'controller/enable.stub');
+ $enable_tmp = str_replace('[MODEL_NAME]', $this->data['model']['name'], $enable_tmp);
+ $enable_code = $enable_tmp;
+ }
+
+ if (strlen($export_header) > 0) {
+ $export_name = $this->data['table'];
+ $code_export = file_get_contents($this->config['template']['path'] . 'controller/export.stub');
+ $code_export = str_replace(array('[HEADER_LIST]', '[BODY_ITEM]', '[FILE_NAME]'), array($export_header, $export_body, $export_name), $code_export);
+ $export_code = $code_export;
+ }
+
+
+ if (strlen($relation_3) > 0) {
+ $code_2 = file_get_contents($this->config['template']['path'] . 'controller/relation_assign_1.stub');
+ $code_2 = str_replace('[RELATION_LIST]', $relation_3, $code_2);
+ $relation_2 = $code_2;
+ }
+
+
+ //如果有列表显示
+ if (strlen($relation_with_list) > 0) {
+ $relation_with = file_get_contents($this->config['template']['path'] . 'controller/relation_with.stub');
+ $relation_with = str_replace('[WITH_LIST]', $relation_with_list, $relation_with);
+ }
+
+
+ $file = $this->config['template']['controller'];
+ $code = file_get_contents($file);
+
+ //控制器添加方法特殊字段处理
+ //控制器修改方法特殊字段处理
+ $code = str_replace(
+ array('[NAME]', '[CONTROLLER_NAME]', '[CONTROLLER_MODULE]', '[MODEL_NAME]', '[MODEL_MODULE]', '[VALIDATE_NAME]', '[VALIDATE_MODULE]', '[ADD_FIELD_CODE]', '[EDIT_FIELD_CODE]', '[RELATION_1]', '[RELATION_2]', '[RELATION_3]', '[EXPORT_CODE]', '[ENABLE_CODE]', '[RELATION_WITH]'),
+ array($this->data['cn_name'], $this->data['controller']['name'], $this->data['controller']['module'], $this->data['model']['name'], $this->data['model']['module'], $this->data['validate']['name'], $this->data['validate']['module'], $add_field_code, $edit_field_code, $relation_1, $relation_2, $relation_3, $export_code, $enable_code, $relation_with),
+ $code
+ );
+
+
+ $msg = '';
+ try {
+ file_put_contents($this->config['file_dir']['controller'] . $this->data['controller']['name'] . 'Controller' . '.php', $code);
+ $result = true;
+ } catch (\Exception $e) {
+ $msg = $e->getMessage();
+ $result = false;
+ }
+ return $result ?? $msg;
+ }
+
+ //创建模型
+
+ /**
+ * @return bool|string
+ */
+ protected function createModel()
+ {
+
+ //不生成模型
+ if($this->data['model']['create']==0){
+ return true;
+ }
+
+ $auto_time = 'protected $autoWriteTimestamp = true;';
+ $soft_delete1 = 'use think\model\concern\SoftDelete;';
+ $soft_delete2 = 'use SoftDelete;';
+ $soft_delete3_1 = 'public $softDelete = true;';
+ $soft_delete3_2 = 'public $softDelete = false;';
+
+ $file = $file = $this->config['template']['model'];
+ $code = file_get_contents($file);
+ $code = str_replace(array('[NAME]', '[TABLE_NAME]', '[MODEL_NAME]', '[MODEL_MODULE]'), array($this->data['cn_name'], $this->data['table'], $this->data['model']['name'], $this->data['model']['module']), $code);
+
+ //软删除
+ if ($this->data['model']['soft_delete']) {
+ $code = str_replace(array('[SOFT_DELETE_USE1]', '[SOFT_DELETE_USE2]', '[SOFT_DELETE_USE3]'), array($soft_delete1, $soft_delete2, $soft_delete3_1), $code);
+ } else {
+ $code = str_replace(array("\n" . '[SOFT_DELETE_USE1]' . "\n", "\n " . '[SOFT_DELETE_USE2]', '[SOFT_DELETE_USE3]'), array('', '', $soft_delete3_2), $code);
+ }
+
+ //自动时间戳
+ if ($this->data['model']['timestamp']) {
+ $code = str_replace('[AUTO_TIMESTAMP]', $auto_time, $code);
+ } else {
+ $code = str_replace('[AUTO_TIMESTAMP]' . "\n\n", '', $code);
+ }
+
+ //关联
+ $relation_code = '';
+ //获取器/修改器
+ $getter_setter_code = '';
+
+ foreach ($this->data['data'] as $key => $value) {
+
+ if ($value['is_relation']) {
+
+ $tmp_code = file_get_contents($this->config['template']['path'] . 'model/relation.stub');
+
+ if ($value['is_relation'] == 1) {
+ //外键
+ $relation_type = 'belongsTo';
+ $table_name = parse_name(str_replace('_id', '', $value['field_name']), 0, false);
+ //表中文名
+ $cn_name = '';
+ $table_info = Db::query('SHOW TABLE STATUS LIKE ' . "'" . $table_name . "'");
+ if ($table_info) {
+ $cn_name = $table_info[0]['Comment'] ?? '';
+ }
+ $relation_name = parse_name($table_name, 1, false);
+ $relation_class = parse_name($table_name, 1);
+ $tmp_code = str_replace(array('[RELATION_NAME]', '[RELATION_TYPE]', '[CLASS_NAME]', '[CN_NAME]'), array($relation_name, $relation_type, $relation_class, $cn_name), $tmp_code);
+ $relation_code .= $tmp_code;
+
+ } else if ($value['is_relation'] == 2) {
+ //主键
+ $relation_type = 'hasMany';
+ if ($value['relation_type'] == 2) {
+ $relation_type = 'hasOne';
+ }
+
+ $table_tmp = explode(',', $value['relation_table']);
+ foreach ($table_tmp as $item) {
+ $table_name = parse_name($item, 0, false);
+ $relation_name = parse_name($table_name, 1, false);
+ $relation_class = parse_name($item, 1);
+
+ //表中文名
+ $cn_name = '';
+ $table_info = Db::query('SHOW TABLE STATUS LIKE ' . "'" . $table_name . "'");
+ if ($table_info) {
+ $cn_name = $table_info[0]['Comment'] ?? '';
+ }
+
+ $tmp_code_item = str_replace(array('[RELATION_NAME]', '[RELATION_TYPE]', '[CLASS_NAME]', '[CN_NAME]'), array($relation_name, $relation_type, $relation_class, $cn_name), $tmp_code);
+ $relation_code .= $tmp_code_item;
+ }
+ }
+
+ }
+
+
+ if ($value['getter_setter']) {
+ switch ($value['getter_setter']) {
+ case 'switch':
+ $tmp_code = file_get_contents($this->config['template']['path'] . 'model/getter_setter_switch.stub');
+ $tmp_code = str_replace(array('[FIELD_NAME]', '[FORM_NAME_LOWER]', '[FORM_NAME]'), array(parse_name($value['field_name'], 1), $value['field_name'], $value['form_name']), $tmp_code);
+ $getter_setter_code .= $tmp_code;
+ break;
+ case 'datetime':
+ $tmp_code = file_get_contents($this->config['template']['path'] . 'model/getter_setter_datetime.stub');
+ $tmp_code = str_replace(array('[FIELD_NAME]', '[FORM_NAME]'), array(parse_name($value['field_name'], 1), $value['form_name']), $tmp_code);
+ $getter_setter_code .= $tmp_code;
+ break;
+ case 'date':
+ $tmp_code = file_get_contents($this->config['template']['path'] . 'model/getter_setter_date.stub');
+ $tmp_code = str_replace(array('[FIELD_NAME]', '[FORM_NAME]'), array(parse_name($value['field_name'], 1), $value['form_name']), $tmp_code);
+ $getter_setter_code .= $tmp_code;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ $code = str_replace(array('[RELATION]', '[GETTER_SETTER]'), array($relation_code, $getter_setter_code), $code);
+
+
+ //暂时不用switch,因为基础模型已经有status的获取器
+ /*//switch字段
+ $switch_field = '';
+ foreach ($this->data['data'] as $value) {
+ if ($value['form_type'] == 'switch') {
+ $switch_field .= "'" . $value['field_name'] . "',";
+ }
+ }
+ //switch字段替换
+ $code = str_replace('[SWITCH_FIELD]', $switch_field, $code);*/
+
+
+ //搜索字段
+ $search_field = '';
+ //多文件/多图上传获取器,修改器
+ $multi_field = '';
+ foreach ($this->data['data'] as $value) {
+ if ($value['is_search'] == 1) {
+ $search_field .= "'" . $value['field_name'] . "',";
+ }
+ //多图/文件的获取器/修改器处理
+ if ($value['form_type'] === 'multi_image' || $value['form_type'] === 'multi_file') {
+ $multi_field_tmp = MultiImage::$modelAttrCode;
+ $multi_field_tmp = str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($value['form_name'], parse_name($value['field_name'], 1)), $multi_field_tmp);
+ $multi_field .= $multi_field_tmp;
+ }
+
+ }
+ //搜索字段替换
+ //替换多图/多文件获取器,修改器
+ $code = str_replace(array('[SEARCH_FIELD]', '[MULTI_FIELD]'), array($search_field, $multi_field), $code);
+
+ $msg = '';
+ try {
+ file_put_contents($this->config['file_dir']['model'] . $this->data['model']['name'] . '.php', $code);
+ $result = true;
+ } catch (\Exception $e) {
+ $msg = $e->getMessage();
+ $result = false;
+ }
+ return $result ?? $msg;
+ }
+
+ //创建验证器
+ protected function createValidate()
+ {
+ //不生成验证器
+ if($this->data['validate']['create']==0){
+ return true;
+ }
+
+ $file = $this->config['template']['validate'];
+ $code = file_get_contents($file);
+ $code = str_replace(array('[NAME]', '[VALIDATE_NAME]', '[VALIDATE_MODULE]'), array($this->data['cn_name'], $this->data['validate']['name'], $this->data['validate']['module']), $code);
+
+
+ $rule_code = '';
+ $msg_code = '';
+ $scene_code = Field::$validateSceneCode;
+ $scene_code_tmp = '';
+ foreach ($this->data['data'] as $key => $value) {
+ if (is_array($value['form_validate']) && $value['is_form'] == 1) {
+
+ if (in_array('required', $value['form_validate']) && !in_array($value['form_type'], ['file', 'multi_file', 'image', 'multi_image'])) {
+
+ $rule_code_tmp = Required::$ruleValidate;
+ $rule_code_tmp = str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($value['form_name'], $value['field_name']), $rule_code_tmp);
+
+ $rule_code .= $rule_code_tmp;
+
+ $msg_code_tmp = Required::$msgValidate;
+
+ $msg_code_tmp = str_replace(array('[FIELD_NAME]', '[FORM_NAME]'), array($value['field_name'], $value['form_name']), $msg_code_tmp);
+ $msg_code .= $msg_code_tmp;
+
+ $scene_code_tmp .= "'" . $value['field_name'] . "',";
+
+
+ //[RULE_FIELD]
+ }
+ }
+ }
+
+ $scene_code = str_replace('[RULE_FIELD]', $scene_code_tmp, $scene_code);
+
+ //规则
+ //消息
+ //场景
+ $code = str_replace(array('[VALIDATE_RULE]', '[VALIDATE_MSG]', '[VALIDATE_SCENE]'), array($rule_code, $msg_code, $scene_code), $code);
+
+ //场景方法
+ $code = str_replace('[VALIDATE_SCENE_FUNC]', '', $code);
+ /*if ($this->data['validate_scene_func']) {
+ $code = str_replace('[VALIDATE_SCENE_FUNC]', '', $code);
+ } else {
+ $code = str_replace('[VALIDATE_SCENE_FUNC]', '', $code);
+ }*/
+
+ $msg = '';
+ try {
+ file_put_contents($this->config['file_dir']['validate'] . $this->data['validate']['name'] . 'Validate' . '.php', $code);
+ $result = true;
+ } catch (\Exception $e) {
+ $msg = $e->getMessage();
+ $result = false;
+ }
+ return $result ?? $msg;
+ }
+
+ //列表视图
+ protected function createIndexView()
+ {
+ //列表数据名称
+ $name_list = '';
+ //列表数据字段
+ $field_list = '';
+ //搜索框显示
+ $search_name = '';
+ $file_fields = ['file', 'image'];
+ $sort_code = '';
+ foreach ($this->data['data'] as $key => $value) {
+
+ if ($value['list_sort'] == 1) {
+ if (strlen($sort_code) == 0) {
+
+ $sort_code .= file_get_contents($this->config['template']['view']['index_path'] . 'sort1.stub');
+ }
+ $option_code = file_get_contents($this->config['template']['view']['index_path'] . 'sort_option.stub');
+ $option_code = str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($value['form_name'], $value['field_name']), $option_code);
+ $sort_code .= $option_code;
+ }
+
+
+ if ($value['is_list'] == 1) {
+ //名称显示
+ $name_list .= str_replace('[FORM_NAME]', $value['form_name'], Field::$listNameHtml);
+ //字段内容显示
+ if (in_array($value['form_type'], $file_fields)) {
+ //图片显示
+ $field_list .= str_replace('[FIELD_NAME]', $value['field_name'], Field::$listImgHtml);
+ } else if ($value['form_type'] === 'multi_image') {
+ //多图显示
+ $field_list .= str_replace('[FIELD_NAME]', $value['field_name'], Field::$listMultiImgHtml);
+ } else if ($value['form_type'] === 'switch' && $value['getter_setter'] === 'switch') {
+ //status switch显示
+ $field_list .= str_replace('[FIELD_NAME]', $value['field_name'], Field::$listSwitchHtml);
+ } else if ($value['is_relation'] == 1) {
+ //关联字段显示
+ if ($value['relation_type'] == 1) {
+ $value['field_name'] = str_replace('_id', '', $value['field_name']) . '.' . $value['relation_show'] . '|default=' . "''";
+ $field_list .= str_replace('[FIELD_NAME]', $value['field_name'], Field::$listFieldHtml);
+ }
+ } else {
+ //普通字段显示
+ $field_list .= str_replace('[FIELD_NAME]', $value['field_name'], Field::$listFieldHtml);
+ }
+
+ }
+
+ if ($value['is_search'] == 1) {
+ if (!empty($search_name)) {
+ $search_name .= '/' . $value['form_name'];
+ } else {
+ $search_name .= $value['form_name'];
+ }
+ }
+
+ }
+
+ if (strlen($sort_code) > 0) {
+ $sort_code .= file_get_contents($this->config['template']['view']['index_path'] . 'sort2.stub');;
+ }
+
+
+ $file = $this->config['template']['view']['index'];
+ $code = file_get_contents($file);
+
+
+ //列表删除判断
+ $del1 = '';
+ $del2 = '';
+ //列表选择
+ $select1 = '';
+ $select2 = '';
+
+ //列表添加
+ $create = '';
+
+ //列表刷新
+ $refresh = '';
+
+ if ($this->data['view']['delete']) {
+ $del1 = file_get_contents($this->config['template']['view']['index_del1']);
+ $del2 = file_get_contents($this->config['template']['view']['index_del2']);
+ $select1 = file_get_contents($this->config['template']['view']['index_select1']);
+ $select2 = file_get_contents($this->config['template']['view']['index_select2']);
+ $create = file_get_contents($this->config['template']['view']['index_path'] . 'create.stub');
+ $refresh = file_get_contents($this->config['template']['view']['index_path'] . 'refresh.stub');
+ }
+
+ $code = str_replace(array('[INDEX_DEL1]', '[INDEX_DEL2]', '[INDEX_SELECT1]', '[INDEX_SELECT2]', '[INDEX_CREATE]', '[INDEX_REFRESH]'), array($del1, $del2, $select1, $select2, $create, $refresh), $code);
+
+
+ //顶部筛选(filter)和导出。筛选功能暂时为必生成
+ //$filter = '';
+ $filter = file_get_contents($this->config['template']['view']['index_filter']);
+ $code = str_replace('[INDEX_FILTER]', $filter, $code);
+
+ //导出
+ $export = '';
+ if ($this->data['view']['export']) {
+ $export = file_get_contents($this->config['template']['view']['index_export']);
+ }
+
+ //启用/禁用
+ $enable1 = '';
+ $enable2 = '';
+ if ($this->data['view']['enable']) {
+ $enable1 = file_get_contents($this->config['template']['path'] . 'view/index/enable1.stub');
+ $enable2 = file_get_contents($this->config['template']['path'] . 'view/index/enable2.stub');
+ }
+
+ $code = str_replace(array('[INDEX_ENABLE1]', '[INDEX_ENABLE2]', '[INDEX_EXPORT]', '[NAME_LIST]', '[FIELD_LIST]', '[SEARCH_FIELD]', '[SORT_CODE]'), array($enable1, $enable2, $export, $name_list, $field_list, $search_name, $sort_code), $code);
+
+ $msg = '';
+ try {
+ file_put_contents($this->config['file_dir']['view'] . $this->data['table'] . '/index.html', $code);
+ $result = true;
+ } catch (\Exception $e) {
+ $msg = $e->getMessage();
+ $result = false;
+ }
+ return $result ?? $msg;
+ }
+
+ //add视图页面
+ protected function createAddView()
+ {
+
+ $html = '';
+ $form_body = '';
+ $form_rules = '';
+ $form_messages = '';
+
+ foreach ($this->data['data'] as $key => $value) {
+
+ if ($value['is_form'] == 1) {
+ try {
+
+ if ($value['form_type'] === 'switch') {
+ $value['form_type'] = 'switch_field';
+ } else if ($value['form_type'] === 'select') {
+ $value['relation_data'] = '';
+ if ($value['is_relation'] == 1 && $value['relation_type'] == 1) {
+ $list_code = file_get_contents($this->config['template']['path'] . 'view/add/select_data.stub');
+ $list_name = str_replace('_id', '', $value['field_name']) . '_list';
+ $list_code = str_replace(array('[DATA_LIST]', '[FIELD_NAME]', '[RELATION_SHOW]'), array($list_name, $value['field_name'], $value['relation_show']), $list_code);
+ $value['relation_data'] = $list_code;
+ }
+ }
+
+ $class_name = parse_name($value['form_type'], 1);
+ $class = '\\generate\\field\\' . $class_name;
+ $form_body .= $class::create($value);
+
+ } catch (\Exception $exception) {
+ echo $exception->getMessage();
+ exit();
+ } catch (\Error $error) {
+ echo $error->getMessage();
+ exit();
+ }
+
+ //验证暂时不处理图片和文件
+ if (is_array($value['form_validate'])
+ && $value['form_type'] !== 'image'
+ && $value['form_type'] !== 'file'
+ && $value['form_type'] !== 'multi_image'
+ && $value['form_type'] !== 'multi_file') {
+
+ if (in_array('required', $value['form_validate'])) {
+
+ $rule_html = Required::$ruleForm;
+
+ //如果是多选select,验证字段使用[]后缀
+ if ($value['form_type'] === 'multi_select' || $value['form_type'] === 'multi_image' || $value['form_type'] === 'multi_file') {
+ $value['field_name'] .= '[]';
+ }
+
+ $form_rules .= str_replace('[FIELD_NAME]', $value['field_name'], $rule_html);
+
+ $msg_html = Required::$msgForm;
+ $msg_html = str_replace(array('[FIELD_NAME]', '[FORM_NAME]'), array($value['field_name'], $value['form_name']), $msg_html);
+ $form_messages .= $msg_html;
+ }
+ }
+ }
+ }
+
+
+ $file = $this->config['template']['view']['add'];
+ $code = file_get_contents($file);
+ $code = str_replace(
+ array('[FORM_BODY]', '[FORM_RULES]', '[FORM_MESSAGES]'),
+ array($form_body, $form_rules, $form_messages),
+ $code);
+
+
+ $msg = '';
+ try {
+ if (!is_dir($this->config['file_dir']['view'] . $this->data['table'])) {
+ $this->mkFolder($this->config['file_dir']['view'] . $this->data['table']);
+ }
+
+ file_put_contents($this->config['file_dir']['view'] . $this->data['table'] . '/add.html', $code);
+ $result = true;
+ } catch (\Exception $e) {
+ $msg = $e->getMessage();
+ $result = false;
+ }
+ return $result ?? $msg;
+
+ /*$code = str_replace('[FORM_RULES]', $this->data['validate'], $code);
+ $code = str_replace('[VALIDATE_MODULE]', $this->data['validate_module'], $code);
+
+ //规则
+ if ($this->data['validate_rule']) {
+ $code = str_replace('[VALIDATE_RULE]', '', $code);
+ } else {
+ $code = str_replace('[VALIDATE_RULE]', '', $code);
+ }
+
+ //消息
+ if ($this->data['validate_msg']) {
+ $code = str_replace('[VALIDATE_MSG]', '', $code);
+ } else {
+ $code = str_replace('[VALIDATE_MSG]', '', $code);
+ }
+
+ //场景
+ if ($this->data['validate_scene']) {
+ $code = str_replace('[VALIDATE_SCENE]', '', $code);
+ } else {
+ $code = str_replace('[VALIDATE_SCENE]', '', $code);
+ }
+
+ //场景方法
+ if ($this->data['validate_scene_func']) {
+ $code = str_replace('[VALIDATE_SCENE_FUNC]', '', $code);
+ } else {
+ $code = str_replace('[VALIDATE_SCENE_FUNC]', '', $code);
+ }
+
+ $msg = '';
+ try {
+ file_put_contents($this->appPath . $this->data['vali\date_module'] . '/validate/' . $this->data['validate'] . '.php', $code);
+ $result = true;
+ } catch (\Exception $e) {
+ $msg = $e->getMessage();
+ $result = false;
+ }
+ return $result ?? $msg;
+
+ */
+
+ }
+
+ //自动添加菜单
+ protected function createMenu()
+ {
+ if ($this->data['menu']['create'] >= 0) {
+
+ //菜单前缀
+ $url_prefix = 'admin/' . $this->data['table'];
+ //显示名称
+ $name_show = $this->data['cn_name'];
+ Db::startTrans();
+ try {
+ $parent = [
+ 'parent_id' => $this->data['menu']['create'],
+ 'name' => $name_show . '管理',
+ 'url' => $url_prefix . '/index',
+ 'icon' => 'fa-list',
+ 'is_show' => 1,
+ 'log_method' => '不记录',
+ ];
+ $result = AdminMenu::create($parent);
+ if (in_array(2, $this->data['menu']['menu'])) {
+ AdminMenu::create([
+ 'parent_id' => $result->id,
+ 'name' => '添加' . $name_show,
+ 'url' => $url_prefix . '/add',
+ 'icon' => 'fa-plus',
+ 'is_show' => 0,
+ 'log_method' => 'POST',
+ ]);
+ }
+
+ if (in_array(3, $this->data['menu']['menu'])) {
+ AdminMenu::create([
+ 'parent_id' => $result->id,
+ 'name' => '修改' . $name_show,
+ 'url' => $url_prefix . '/edit',
+ 'icon' => 'fa-pencil',
+ 'is_show' => 0,
+ 'log_method' => 'POST',
+ ]);
+ }
+
+ if (in_array(4, $this->data['menu']['menu'])) {
+ AdminMenu::create([
+ 'parent_id' => $result->id,
+ 'name' => '删除' . $name_show,
+ 'url' => $url_prefix . '/del',
+ 'icon' => 'fa-trash',
+ 'is_show' => 0,
+ 'log_method' => 'POST',
+ ]);
+ }
+
+ if (in_array(5, $this->data['menu']['menu'])) {
+ AdminMenu::create([
+ 'parent_id' => $result->id,
+ 'name' => '启用' . $name_show,
+ 'url' => $url_prefix . '/enable',
+ 'icon' => 'fa-circle',
+ 'is_show' => 0,
+ 'log_method' => 'POST',
+ ]);
+
+ AdminMenu::create([
+ 'parent_id' => $result->id,
+ 'name' => '禁用' . $name_show,
+ 'url' => $url_prefix . '/disable',
+ 'icon' => 'fa-circle',
+ 'is_show' => 0,
+ 'log_method' => 'POST',
+ ]);
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ echo $e->getMessage();
+ Db::rollback();
+ }
+ }
+ }
+
+ //创建目录
+ protected function mkFolder($path)
+ {
+ if (!is_readable($path)) {
+ is_file($path) || mkdir($path, 0755) || is_dir($path);
+ }
+ }
+
+ //获取目录下的所有类名
+ public function getClassList($dir, $except = [])
+ {
+ $handler = opendir($dir);
+ while (($filename = readdir($handler)) !== false) {
+ if ($filename !== '.' && $filename !== '..') {
+ $filename = str_replace('.php', '', $filename);
+
+ if (!in_array($filename, $except)) {
+ $files[] = $filename;
+ }
+ }
+ }
+ closedir($handler);
+
+ return $files;
+ }
+
+
+ //获取字段列表
+ public function getAll($table_name)
+ {
+ $parse_name = parse_name($table_name, 1);
+
+ $data = [
+ //表
+ 'table' => [
+ 'name' => $table_name,
+ 'cn_name' => ''
+ ],
+ //控制器
+ 'controller' => [
+ 'create' => 1,
+ 'name' => $parse_name,
+ 'action' => [
+ 'index' => 1,
+ 'add' => 1,
+ 'edit' => 1,
+ 'del' => 1,
+ 'enable' => 0,
+ 'disable' => 0,
+ ],
+ 'del_relation' => [
+ //关联方法,删除模式,1判断关联,2不做操作,3关联删除
+ 'user' => 1,
+ ]
+ ],
+ //模型
+ 'model' => [
+ 'create' => 1,
+ 'name' => $parse_name,
+ 'auto_timestamp' => 1,
+ 'soft_delete' => 1,
+
+ ],
+ //验证器
+ 'validate' => [
+ 'create' => 1,
+ 'name' => $parse_name,
+ 'scene' => [
+ 'admin_add' => 1,
+ 'admin_edit' => 1,
+ 'api_add' => 1,
+ 'api_edit' => 1,
+ 'index_add' => 1,
+ 'index_edit' => 1,
+
+ ]
+ ],
+ //字段
+ 'field' => [
+ [
+ //字段名
+ 'name' => 'name',
+ //字段中文名
+ 'cn_name' => '名称',
+ //字段类型
+ 'field_type' => 'varchar(30)',
+ //是否列表显示
+ 'is_list' => 1,
+ //是否为搜索字段
+ 'is_search' => 1,
+ //是否为表单字段
+ 'is_form' => 1,
+ //表单类型
+ 'form_type' => 'text',
+ //表单验证
+ 'validate' => ['required'],
+ //验证场景
+ 'validate_scene' => ['admin_add'],
+ //获取器
+ 'getter' => 'date_time',
+ //修改器
+ 'setter' => 'date_time',
+ //关联显示
+ 'relation_display' => 1,
+ //关联显示字段
+ 'display_field' => 'name',
+
+ ],
+ ],
+
+ ];
+
+ //所有字段信息
+ $field_list = Db::query('SHOW FULL COLUMNS FROM `' . $table_name . '`');
+ //表信息
+ $table_info = Db::query('SHOW TABLE STATUS LIKE ' . "'" . $table_name . "'");
+ $table_info = $table_info[0];
+ //表名
+ $data['table']['name'] = $table_info['Name'];
+ //表中文名
+ $data['table']['cn_name'] = $table_info['Comment'];
+
+
+ //定义好以下情况,
+ //90%概率为列表的字段,
+ //90%概率不为列表的字段,
+ //90%为搜索的字段
+ //90%不为搜索的字段
+ //90%为表单的字段
+ //90不为表单的字段
+ //导出字段暂时和显示字段一样
+
+
+ //显示为列表的字段名,暂时不用
+ //$list_show_field = ['id','name','mobile','description','address','money','price', 'keywords','title','img','create_time','sort_number','user_id','status'];
+ //列表隐藏字段,如果为text字段,大概率隐藏
+ $list_hide_field = ['password', 'update_time', 'delete_time'];
+ $list_hide_type = ['tinytext', 'tinyblob', 'text', 'blob', 'longtext', 'longblob'];
+
+
+ /**
+ * @param $field
+ * @return mixed
+ * 常用类型
+ * tinyint,smallint,mediumint,int,bigint,float,double,decimal
+ * char,varchar,tinytext/tinyblob,text/blob,longtext/longblob
+ * date,datetime,timestamp,time,year
+ */
+
+
+ //搜索字段,如果为varchar,char字段,大概率需要搜索
+ $search_show_field = ['id', 'mobile', 'keywords', 'id_card', 'name', 'title', 'username', 'nickname', 'true_name', 'description'];
+ $search_show_type = ['char', 'varchar'];
+ //搜索隐藏字段
+ //$search_hide_field = ['id','name','description'];
+
+ //导出显示字段
+ //$export_show_field = ['id','create_time'];
+ //导出隐藏字段,和列表隐藏字段差不多
+ $export_hide_field = ['update_time', 'delete_time'];
+ $export_hide_type = ['tinytext', 'tinyblob', 'text', 'blob', 'longtext', 'longblob'];
+
+ //表单显示字段
+ //$form_show_field = ['id','create_time','update_time','delete_time'];
+ //表单隐藏字段
+ $form_hide_field = ['id', 'create_time', 'update_time', 'delete_time'];
+ $form_hide_type = ['double'];
+
+ $data['field'] = [];
+ foreach ($field_list as $key => $value) {
+
+ $field_data = [
+ //字段名
+ 'name' => $value['Field'],
+ //字段中文名
+ 'cn_name' => $value['Field'] === 'id' ? 'ID' : $value['Comment'],
+ //字段类型
+ 'field_type' => $value['Type'],
+ //字段长度
+ 'field_length' => 1,
+ //默认值
+ 'default' => $value['Default'],
+ //是否列表显示
+ 'is_list' => 1,
+ //是否为搜索字段
+ 'is_search' => 0,
+ //是否为表单字段
+ 'is_form' => 1,
+ //表单类型
+ 'form_type' => 'text',
+ //表单验证
+ 'validate' => ['required'],
+ 'validate_html' => '',
+ //验证场景
+ 'validate_scene' => ['admin_add'],
+ //获取器/修改器
+ 'getter_setter' => false,
+ //关联显示
+ 'relation_display' => 1,
+ //关联显示字段
+ 'display_field' => 'name',
+ ];
+
+
+ $field_info = $this->getFieldInfo($field_data['name'], $field_data['field_type']);
+
+ $field_data['field_length'] = $field_info['length'];
+
+ //处理是否为列表显示
+ if (in_array($field_info['name'], $list_hide_field) || in_array($field_info['type'], $list_hide_type)) {
+ $field_data['is_list'] = 0;
+ }
+
+ //处理是否为列表搜索
+ if (in_array($field_info['name'], $search_show_field) && in_array($field_info['type'], $search_show_type)) {
+ $field_data['is_search'] = 1;
+ }
+
+ //处理是否不为表单字段
+ if (in_array($field_info['name'], $form_hide_field) || in_array($field_info['type'], $form_hide_type)) {
+ $field_data['is_form'] = 0;
+ }
+
+ //处理字段表单类型
+ $form_info = $this->getFormInfo($field_info);
+ $field_data['form_type'] = $form_info['form_type'];
+ $field_data['getter_setter'] = $form_info['getter_setter'];
+
+
+ //验证
+ //$field_data['validate'] = [];
+ $field_data['validate_html'] = $this->getValidateHtml($field_data);
+
+
+ $data['field'][] = $field_data;
+
+ }
+
+
+ return $data;
+ }
+
+
+ //根据表单类型和长度返回相应的验证
+ public function getValidateHtml($field_data)
+ {
+ $html = '';
+
+
+ try {
+
+ if ($field_data['form_type'] === 'switch') {
+ $field_data['form_type'] = 'switch_field';
+ }
+
+ $class_name = parse_name($field_data['form_type'], 1);
+
+ $class = '\\generate\\field\\' . $class_name;
+ $html = $class::rule($field_data['field_length']);
+
+ } catch (\Exception $exception) {
+ echo $exception->getMessage();
+ } catch (\Error $error) {
+ echo $error->getMessage();
+ }
+
+ return $html;
+ }
+
+ public function getFormInfo($field_info)
+ {
+
+ //结尾:_id为select,_time为datetime,_date为date,
+ //结尾:_count为number,_lng/_longitude为map,img为image,slide为multiImage
+ //开头:is_为switch
+ //字段名:lng/longitude为map,password为password,money,price为number
+ //字段名:status大概率为switch或者其他
+ $field_data = [
+ 'form_type' => 'text',
+ 'getter_setter' => false,
+ ];
+
+ //id
+ if ($field_info['name'] === 'id') {
+ $field_data['form_type'] = 'number';
+ }
+
+ //_id为下拉列表,大多数为关联
+ if (strrchr($field_info['name'], '_id') === '_id') {
+ $field_data['form_type'] = 'select';
+ }
+
+ //日期时间
+ if (strrchr($field_info['name'], '_time') === '_time') {
+ $field_data['form_type'] = 'datetime';
+
+ $ignore_field = ['create_time', 'update_time', 'delete_time'];
+ if (!in_array($field_info['name'], $ignore_field) && $field_info['type'] === 'int') {
+ $field_data['getter_setter'] = 'datetime';
+ }
+ }
+
+ //日期
+ if ($field_info['type'] === 'datetime') {
+ $field_data['form_type'] = 'date';
+ }
+
+
+ //日期
+ if (strrchr($field_info['name'], '_date') === '_date') {
+ $field_data['form_type'] = 'date';
+ if ($field_info['type'] === 'int') {
+ $field_data['getter_setter'] = 'date';
+ }
+ }
+ //日期
+ if ($field_info['type'] === 'date') {
+ $field_data['form_type'] = 'date';
+ }
+
+ //数量
+ if (strrchr($field_info['name'], '_count') === '_count') {
+ $field_data['form_type'] = 'number';
+ }
+
+ //经纬度
+ if (strrchr($field_info['name'], '_lng') === '_lng') {
+ $field_data['form_type'] = 'map';
+ }
+
+ //图片
+ if (strrchr($field_info['name'], 'img') === 'img') {
+ $field_data['form_type'] = 'image';
+ }
+ //轮播
+ if (strrchr($field_info['name'], 'slide') === 'slide') {
+ $field_data['form_type'] = 'multi_image';
+ }
+
+ //密码
+ if (strrchr($field_info['name'], 'password') === 'password') {
+ $field_data['form_type'] = 'password';
+ }
+
+ //颜色
+ if (strrchr($field_info['name'], 'color') === 'color') {
+ $field_data['form_type'] = 'color';
+ }
+ //图标
+ if (strrchr($field_info['name'], 'icon') === 'icon') {
+ $field_data['form_type'] = 'icon';
+ }
+
+ //价格,暂时用number
+ if (strrchr($field_info['name'], 'price') === 'price') {
+ $field_data['form_type'] = 'number';
+ }
+
+ //金额,暂时用number
+ if (strrchr($field_info['name'], 'money') === 'money') {
+ $field_data['form_type'] = 'number';
+ }
+
+ //状态
+ if ($field_info['name'] === 'status') {
+ $field_data['form_type'] = 'switch';
+ $field_data['getter_setter'] = 'switch';
+ }
+
+ //手机号
+ if ($field_info['name'] === 'mobile') {
+ $field_data['form_type'] = 'mobile';
+ }
+
+
+ //头像
+ if ($field_info['name'] === 'avatar') {
+ $field_data['form_type'] = 'image';
+ }
+
+ //富文本
+ if ($field_info['type'] === 'text' || $field_info['type'] === 'longtext') {
+ $field_data['form_type'] = 'editor';
+ }
+
+ if (strpos($field_info['name'], 'is_') === 0 && $field_info['type'] === 'tinyint') {
+
+ $field_data['form_type'] = 'switch';
+ $field_data['getter_setter'] = 'switch';
+ }
+ return $field_data;
+ }
+
+}
\ No newline at end of file
diff --git a/extend/generate/field/Checkbox.php b/extend/generate/field/Checkbox.php
new file mode 100755
index 0000000..661e64d
--- /dev/null
+++ b/extend/generate/field/Checkbox.php
@@ -0,0 +1,37 @@
+
+ */
+
+namespace generate\field;
+
+class Checkbox extends Field
+{
+ public static $html = <<
+ [FORM_NAME]
+
+ \n
+EOF;
+
+ public static $rules = [
+ 'required' => '非空',
+ 'regular' => '自定义正则'
+ ];
+
+
+ public static function create($data)
+ {
+ $html = self::$html;
+ $html = str_replace('[FORM_NAME]', $data['form_name'], $html);
+ $html = str_replace('[FIELD_NAME]', $data['field_name'], $html);
+ return $html;
+ }
+}
\ No newline at end of file
diff --git a/extend/generate/field/City.php b/extend/generate/field/City.php
new file mode 100755
index 0000000..d70c386
--- /dev/null
+++ b/extend/generate/field/City.php
@@ -0,0 +1,45 @@
+
+ */
+
+namespace generate\field;
+
+class City extends Field
+{
+
+ public static $html = <<