作者 杨育虎

2

... ... @@ -66,7 +66,7 @@ class Renwu extends Backend
foreach ($list as $row) {
$row->getRelation('user')->visible(['nickname','mobile','address','address_con','car_num','color','car_type']);
$row->getRelation('user')->visible(['nickname','mobile','address','address_con','car_num','color','car_type','vip']);
$row->getRelation('vip')->visible(['title']);
}
$list = collection($list)->toArray();
... ...
... ... @@ -35,5 +35,8 @@ return [
'User.car_num' => '车牌号',
'User.color' => '车辆颜色',
'User.car_type' => '车型',
'User.vip' => '会员状态',
'User.vip 1' => '会员',
'User.vip 0' => '非会员',
'Vip.title' => '会员名称'
];
... ...
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-heading">
{:build_heading(null,FALSE)}
<ul class="nav nav-tabs" data-field="type">
<li class="active"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
{foreach name="typeList" item="vo"}
<li><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
{/foreach}
</ul>
</div>
<div class="panel-body">
<div id="myTabContent" class="tab-content">
... ...
... ... @@ -6,6 +6,7 @@ use app\common\controller\Api;
use app\common\library\Sms as Smslib;
use app\common\model\User;
use think\Hook;
use think\Db;
/**
* 手机短信接口
... ... @@ -17,16 +18,12 @@ class Sms extends Api
/**
* 发送验证码
*
* @param string $mobile 手机号
* @param string $event 事件名称
* @ApiParams (name="mobile", type="integer", required=true, description="手机号")
*/
public function send()
{
$mobile = $this->request->request("mobile");
$event = $this->request->request("event");
$event = $event ? $event : 'register';
$event = 1;
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号不正确'));
}
... ... @@ -35,26 +32,27 @@ class Sms extends Api
$this->error(__('发送频繁'));
}
$ipSendTotal = \app\common\model\Sms::where(['ip' => $this->request->ip()])->whereTime('createtime', '-1 hours')->count();
if ($ipSendTotal >= 5) {
if ($ipSendTotal >= 20) {
$this->error(__('发送频繁'));
}
if ($event) {
$userinfo = User::getByMobile($mobile);
if ($event == 'register' && $userinfo) {
//已被注册
$this->error(__('已被注册'));
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->error(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
//未注册
$this->error(__('未注册'));
}
}
if (!Hook::get('sms_send')) {
$this->error(__('请在后台插件管理安装短信验证插件'));
}
$ret = Smslib::send($mobile, null, $event);
$url = "https://api.mix2.zthysms.com/v2/sendSms";
$records = [];
$code = mt_rand(1000, 9999);
$tKey = time();
$password = md5(md5('cxz307311') . $tKey);
$date = array(
'username' => 'xiche', //用户名
'password' => $password, //密码
'tKey' => $tKey, //tKey
'signature' => '【零感驿站】',
'records' => $records,
'mobile' => $mobile,
'content' => '【零感驿站】您的验证码是:"' . $code . '",请于10分钟内使用,如非本人操作,可忽略此消息。'
);
$ret = $this->httpPost($url, $date);
$time = time();
$ip = request()->ip();
$sms = \app\common\model\Sms::create(['event' => $event, 'mobile' => $mobile, 'code' => $code, 'ip' => $ip, 'createtime' => $time]);
if ($ret) {
$this->success(__('发送成功'));
} else {
... ... @@ -64,36 +62,23 @@ class Sms extends Api
/**
* 检测验证码
*
* @param string $mobile 手机号
* @param string $event 事件名称
* @param string $captcha 验证码
* @ApiParams (name="mobile", type="integer", required=true, description="手机号")
* @ApiParams (name="code", type="integer", required=true, description="验证码")
*/
public function check()
{
$mobile = $this->request->request("mobile");
$event = $this->request->request("event");
$event = $event ? $event : 'register';
$captcha = $this->request->request("captcha");
$code = $this->request->request("code");
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号不正确'));
}
if ($event) {
$userinfo = User::getByMobile($mobile);
if ($event == 'register' && $userinfo) {
//已被注册
$this->error(__('已被注册'));
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->error(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
//未注册
$this->error(__('未注册'));
}
}
$ret = Smslib::check($mobile, $captcha, $event);
$ret = Db::name('sms')->where('mobile', $mobile)->where('code', $code)->find();
$time = time();
$times = $ret['createtime'] + 60 * 10;
if ($ret) {
if ($time > $times) {
$this->error(__('验证码已失效'));
}
$this->success(__('成功'));
} else {
$this->error(__('验证码不正确'));
... ...
... ... @@ -3,6 +3,7 @@
namespace app\api\controller;
use app\common\controller\Api;
use function fast\e;
use think\Db;
/**
... ... @@ -105,6 +106,171 @@ class User extends Api
/**
* 用户接口
* @ApiTitle (用户接口-开屏页Code)
* @ApiSummary (开屏页Code)
* @ApiMethod (POST)
* @ApiRoute (/api/User/OpenCode)
* @ApiParams (name="code", type="integer", required=true, description="Code")
* @ApiReturnParams (name="code", type="integer", required=true, sample="0")
* @ApiReturnParams (name="msg", type="string", required=true, sample="返回成功")
* @ApiReturn ({
'code':'1',
'msg':'返回成功',
"data": {
"avatar": "https://thirdwx.qlogo.cn/mmopen/vi_32/0wpUDw5m0LRvdDueia3uMWmrYb53GXRaTnYwMWC18kRmX6P6PIaPDgQqarEIfwroicx1z51D6bjQicOV0PibBx2PqQ/132",
"nickname": "Gody",
"token": "3dda6e452f4778fcc72e21178494bbc1",
"mobile": null,
"is_user":1=已注册,0=未注册,
"vip":会员状态:1=会员,0=非会员,
"exptime":会员到期时间,
"type":身份:1=用户,2=找车工,3=洗车工
}
})
*/
public function OpenCode()
{
// 授权登录
$ch = curl_init();
$appid = "wx243943911c16fbfc";
$secret = "297d8f02691bd23a6fb3828a200d5f7e";
$code = input('code');
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$secret&js_code=$code&grant_type=authorization_code";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$output = curl_exec($ch);
if ($output === FALSE) {
echo "CURL Error:" . curl_error($ch);
}
curl_close($ch);
$curl_result = json_decode($output, true);
$openid = $curl_result['openid'];
$is_open = Db::name('user')->where(['openid' => $openid])->find();
if ($is_open['is_black'] == 1) {
$this->error('您已被拉黑', 0);
die;
}
if (empty($is_open)) {
$type = 0;
$return = [
'is_user' => $type,
'nickname' => '',
'avatar' => '',
'mobile' => '',
'vip' => '',
'exptime' => '',
'type' => '',
'token' => ''
];
} else {
$type = 1;
$token = $this->request->token();
$res = Db::name("user")->where(['openid' => $openid])->update(['token' => $token,]);
if (!$res) {
$this->error('令牌更新失败', 0);
die;
}
$return = [
'is_user' => $type,
'nickname' => $is_open['nickname'],
'avatar' => $is_open['avatar'],
'mobile' => $is_open['mobile'],
'vip' => $is_open['vip'],
'exptime' => $is_open['exptime'],
'type' => $is_open['type'],
'token' => $token
];
}
$this->success('成功', $return);
}
/**
* 用户接口
* @ApiTitle (用户接口-绑定手机)
* @ApiSummary (绑定手机)
* @ApiMethod (POST)
* @ApiRoute (/api/User/CheckMobile)
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
* @ApiParams (name="type", type="integer", required=true, description="1=手机号授权,2=验证码授权")
* @ApiParams (name="mobile", type="integer", required=true, description="手机号")
* @ApiParams (name="code", type="integer", required=true, description="验证码")
* @ApiReturnParams (name="code", type="integer", required=true, sample="0")
* @ApiReturnParams (name="msg", type="string", required=true, sample="返回成功")
* @ApiReturn ({
'code':'1',
'msg':'返回成功',
"data": {
}
})
*/
public function CheckMobile()
{
$user_id = $this->is_token($this->request->header());
$param = $this->request->param();
if ($param['type'] == 2) {
$this->CheckCode($param['mobile'], $param['code']);
}
$res = Db::name('user')->where('id', $user_id)->update(['mobile' => $param['mobile']]);
$this->res($res);
}
/**
* 用户接口
* @ApiTitle (用户接口-完善信息)
* @ApiSummary (完善信息)
* @ApiMethod (POST)
* @ApiRoute (/api/User/AddUserCon)
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
* @ApiParams (name="mobile", type="integer", required=true, description="手机号")
* @ApiParams (name="code", type="integer", required=true, description="code")
* @ApiParams (name="car_num", type="integer", required=true, description="车牌号")
* @ApiParams (name="car_type", type="integer", required=true, description="车型")
* @ApiParams (name="color", type="integer", required=true, description="车辆颜色")
* @ApiParams (name="address", type="integer", required=true, description="我的地址")
* @ApiParams (name="address_con", type="integer", required=true, description="详细地址")
* @ApiParams (name="lng", type="integer", required=true, description="经度")
* @ApiParams (name="lat", type="integer", required=true, description="纬度")
* @ApiReturnParams (name="code", type="integer", required=true, sample="0")
* @ApiReturnParams (name="msg", type="string", required=true, sample="返回成功")
* @ApiReturn ({
'code':'1',
'msg':'返回成功',
"data": {
}
})
*/
public function AddUserCon()
{
$param = $this->request->param();
$user_id = $this->is_token($this->request->header());
$mobile = Db::name('user')->where('id', $user_id)->value('mobile');
$this->CheckCode($mobile, $param['code']);
$data = [
'mobile' => $param['mobile'],
'car_num' => $param['car_num'],
'car_type' => $param['car_type'],
'color' => $param['color'],
'address' => $param['address'],
'address_con' => $param['address_con'],
'lng' => $param['lng'],
'lat' => $param['lat'],
];
$res = Db::name('user')->where('id', $user_id)->update($data);
if (!$res) {
$this->error('请填写完整信息', 0);
die;
}
$this->success('成功', 1);
}
/**
* 用户接口
* @ApiTitle (用户接口-用户协议)
* @ApiSummary (用户协议)
* @ApiMethod (POST)
... ... @@ -430,4 +596,91 @@ class User extends Api
}
$this->success('成功', $list);
}
/**
* 用户接口
* @ApiTitle (用户接口-员工订单详情)
* @ApiSummary (员工订单详情)
* @ApiMethod (POST)
* @ApiRoute (/api/User/OrderContent)
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
* @ApiParams (name="id", type="int", required=true, description="ID")
* @ApiReturnParams (name="code", type="integer", required=true, sample="0")
* @ApiReturnParams (name="msg", type="string", required=true, sample="返回成功")
* @ApiReturn ({
'code':'1',
'msg':'返回成功',
"data": {
"id": 1,
"title": "洗车季卡",
"time": 1599209757,
"mobile": "13292442918",
"address": "河北省唐山市路南区",
"address_con": "万达广场第五棵大杨树旁",
"userlng": "116.39050",
"userlat": "39.89223",
"car_num": "冀B123456",
"car_type": "AE86",
"color": "五颜六色的白",
"zhao_type": 0,
"zhao_images": [],
"car_address": "",
"lat": "",
"lng": "",
"order_sn": "202009031647068127236526",
"xi_type": 0,
"xi_images": [],
"createtime": "2020-09-04 16:55:57",
"times": "2020-09-04 16:55:57",
"user_level": 1
}
})
*/
public function OrderContent()
{
$user_id = $this->is_token($this->request->header());
$id = input('id');
$list = Db::name('renwu')->where('a.id', $id)
->alias('a')
->join('vip v', 'v.id=a.vip_id')
->join('user u', 'u.id=a.user_id')
->field('a.id,v.title,a.createtime as time,u.mobile,u.address,u.address_con,u.lng as userlng,u.lat as userlat,u.car_num,u.car_type,u.color,a.zhao_type,a.zhao_images,a.car_address,a.lat,a.lng,a.order_sn,a.xi_type,a.xi_images')
->find();
if (empty($list)) {
$this->error('参数错误', 0);
die;
}
if (empty($list['zhao_images'])) {
$zhao_images = [];
} else {
if (strstr($list['zhao_images'], ',')) {
$zhao_images = explode(',', $list['zhao_images']);
} else {
$zhao_images = explode(' ', $list['zhao_images']);
}
foreach ($zhao_images as $k => $v) {
$zhao_images[$k] = cdnurl($v);
}
}
if (empty($list['xi_images'])) {
$xi_images = [];
} else {
if (strstr($list['xi_images'], ',')) {
$xi_images = explode(',', $list['xi_images']);
} else {
$xi_images = explode(' ', $list['xi_images']);
}
foreach ($xi_images as $k => $v) {
$xi_images[$k] = cdnurl($v);
}
}
$list['createtime'] = date('Y-m-d H:i:s', $list['time']);
$list['times'] = date('Y-m-d H:i:s', $list['time']);
$list['zhao_images'] = $zhao_images;
$list['xi_images'] = $xi_images;
$user_type = Db::name('user')->where('id', $user_id)->value('type');
$list['user_level'] = $user_type;
$this->success('成功', $list);
}
}
... ...
... ... @@ -410,4 +410,48 @@ class Api
$osn = $order_id_main . str_pad((100 - $order_id_sum % 100) % 100, 2, '0', STR_PAD_LEFT); //生成唯一订单号
return $osn;
}
function httpPost($url, $date)
{ // 模拟提交数据函数
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
curl_setopt($curl, CURLOPT_POST, true); // 发送一个常规的Post请求
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($date)); // Post提交的数据包
curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
curl_setopt($curl, CURLOPT_HEADER, false); // 显示返回的Header区域内容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
curl_setopt($curl, CURLOPT_HEADER, true); //开启header
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8'
)); //类型为json
$result = curl_exec($curl); // 执行操作
if (curl_errno($curl)) {
echo 'Error POST' . curl_error($curl);
}
curl_close($curl); // 关键CURL会话
return $result; // 返回数据
}
//检测验证码
function CheckCode($mobile, $code)
{
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号不正确'));
}
$ret = Db::name('sms')->where('mobile', $mobile)->where('code', $code)->find();
if ($ret) {
$time = time();
$times = $ret['createtime'] + 60 * 10;
if ($time > $times) {
$this->error(__('验证码已失效'));
}
} else {
$this->error(__('验证码不正确'));
}
}
}
... ...
此 diff 太大无法显示。
... ... @@ -26,22 +26,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'order_sn', title: __('Order_sn')},
{field: 'user_id', title: __('User_id')},
{field: 'vip_id', title: __('Vip_id')},
{field: 'type', title: __('Type'), searchList: {"1":__('Type 1'),"0":__('Type 0'),"2":__('Type 2')}, formatter: Table.api.formatter.normal},
{field: 'xi_id', title: __('Xi_id')},
{field: 'xi_type', title: __('Xi_type'), searchList: {"1":__('Xi_type 1'),"0":__('Xi_type 0'),"2":__('Xi_type 2')}, formatter: Table.api.formatter.normal},
{field: 'xi_images', title: __('Xi_images'), events: Table.api.events.image, formatter: Table.api.formatter.images},
{field: 'zhao_id', title: __('Zhao_id')},
{field: 'zhao_type', title: __('Zhao_type'), searchList: {"1":__('Zhao_type 1'),"0":__('Zhao_type 0'),"2":__('Zhao_type 2')}, formatter: Table.api.formatter.normal},
{field: 'zhao_images', title: __('Zhao_images'), events: Table.api.events.image, formatter: Table.api.formatter.images},
{field: 'car_address', title: __('Car_address')},
{field: 'lat', title: __('Lat')},
{field: 'lng', title: __('Lng')},
{field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'startime', title: __('Startime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'endtime', title: __('Endtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
// {field: 'user_id', title: __('User_id')},
// {field: 'vip_id', title: __('Vip_id')},
{field: 'user.nickname', title: __('User.nickname')},
{field: 'user.mobile', title: __('User.mobile')},
{field: 'user.address', title: __('User.address')},
... ... @@ -49,7 +35,22 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
{field: 'user.car_num', title: __('User.car_num')},
{field: 'user.color', title: __('User.color')},
{field: 'user.car_type', title: __('User.car_type')},
{field: 'user.vip', title: __('User.vip')},
{field: 'vip.title', title: __('Vip.title')},
{field: 'type', title: __('Type'), searchList: {"1":__('Type 1'),"0":__('Type 0'),"2":__('Type 2')}, formatter: Table.api.formatter.normal},
// {field: 'xi_id', title: __('Xi_id')},
{field: 'xi_type', title: __('Xi_type'), searchList: {"1":__('Xi_type 1'),"0":__('Xi_type 0'),"2":__('Xi_type 2')}, formatter: Table.api.formatter.normal},
// {field: 'xi_images', title: __('Xi_images'), events: Table.api.events.image, formatter: Table.api.formatter.images},
// {field: 'zhao_id', title: __('Zhao_id')},
{field: 'zhao_type', title: __('Zhao_type'), searchList: {"1":__('Zhao_type 1'),"0":__('Zhao_type 0'),"2":__('Zhao_type 2')}, formatter: Table.api.formatter.normal},
// {field: 'zhao_images', title: __('Zhao_images'), events: Table.api.events.image, formatter: Table.api.formatter.images},
{field: 'car_address', title: __('Car_address')},
// {field: 'lat', title: __('Lat')},
// {field: 'lng', title: __('Lng')},
{field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'startime', title: __('Startime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'endtime', title: __('Endtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
... ...