作者 何书鹏
1 个管道 的构建 通过 耗费 16 秒

测试接口

... ... @@ -3,6 +3,7 @@
namespace app\api\controller;
use app\common\controller\Api;
use think\Db;
/**
* 首页接口
... ... @@ -28,10 +29,10 @@ class Index extends Api
public function index()
{
$banner_list = db('banner')->field('id,type,url')->select();
$category_list = db('category')->field('id,image,name')->select();
$dept_list = db('appointment_dept')->field('id,image,name')->select();
$doctor_list = $this->getDoctorList(['a.status'=>'1'],['a.status'=>'desc','a.createtime'=>'desc']);
$doctor_list = $doctor_list->items();
$this->success('请求成功',compact('banner_list','category_list','doctor_list'));
$this->success('请求成功',compact('banner_list','dept_list','doctor_list'));
}
/**
... ... @@ -39,7 +40,9 @@ class Index extends Api
* @ApiTitle (专科服务)
* @ApiSummary (专科服务)
* @ApiMethod (GET)
* @ApiParams (name=topic_id, type=string, required=true, description="推荐ID")
* @ApiParams (name=type, type=integer, required=true, description="服务类型:1=文字沟通,2=音频沟通")
* @ApiParams (name=dept_id, type=integer, required=true, description="专科ID")
* @ApiParams (name=date, type=string, required=true, description="日期")
* @ApiReturn({
"code": 1,
"msg": "成功",
... ... @@ -47,14 +50,55 @@ class Index extends Api
"data": null
})
*/
public function zhuankefuwu(){
$category_id = $this->request->get('category_id');
$time = $this->request->get('time');
if(empty($category_id) || empty($time)){
$this->error('缺少必须参数');
public function appointment(){
$post = $this->request->post();
empty($post['type']) && $this->error('请选择服务类型');
empty($post['dept_id']) && $this->error('请选择专科');
empty($post['date']) && $this->error('请选择日期');
for($i = 0; $i < 7; $i++){
$day = time()+$i*86400;
$date_arr[] = date('Y-m-d',$day);
}
!in_array($post['date'],$date_arr) && $this->error('预约时间不合法');
$dept = db('appointment_dept')->where('id',$post['dept_id'])->find();
empty($dept) && $this->error('专科不存在');
// 是否已预约
$has = db('appointment')
->where('user_id',$this->auth->id)
->where('dept_id',$post['dept_id'])
->where('date',$post['date'])
->where('status','in','1,2')
->find();
!empty($has) && $this->error('您已预约,请勿重复操作');
// 是否可以预约
$doctor = db('doctor')
->alias('a')
->join('doctor_nowork b','b.doctor_id = a.id and b.date = '.$post['date'],'left')
->join('appointment c','c.doctor_id = a.id and c.date = '.$post['date'].' and c.status in (1,2)','left')
->where('b.id',null)
->where('c.id',null)
->where('a.dept_id',$post['dept_id'])
->field('a.id,level_id')
->find();
empty($doctor) && $this->error('已被预约满了,请再等等或选择其他日期预约');
// 分配一个医生
$pay_price = 0.01;
$appointment = db('appointment')->insert(array_merge([
'user_id' => $this->auth->id,
'order_sn' => get_order_sn(),
'doctor_id' => $doctor['id'],
'pay_price' => $pay_price
],$post));
// 发起微信支付
$Wechat = new Wechat;
$openid = Db::name('third')->where('user_id',$this->auth->id)->value('openid');
if(!$payment = $Wechat->wxPay($appointment['order_sn'], $openid, $pay_price)){
$this->error($Wechat->getError());
}
$this->success('成功',[
'payment' => $payment,
'appointment_id' => $appointment['id']
]);
}
/**
... ... @@ -62,6 +106,7 @@ class Index extends Api
* @ApiTitle (专科服务-会诊时间-日期)
* @ApiSummary (专科服务-会诊时间-日期)
* @ApiMethod (GET)
* @ApiParams (name=dept_id, type=integer, required=true, description="专科ID")
* @ApiReturn({
"code": 1,
"msg": "成功",
... ... @@ -70,71 +115,32 @@ class Index extends Api
})
*/
public function dateList(){
$dept_id = $this->request->get('dept_id');
$arr = [];
$week_cn= ['周日','周一','周二','周三','周四','周五','周六'];
for($i = 0; $i < 7; $i++){
$day = time()+$i*86400;
$arr[] = [
'date' => date('m.d',$day),
'name' => $i == 0 ? '今天' : ($i == 1 ? '明天' : $week_cn[(date('w')+$i)%7]),
];
}
}
/**
* @ApiWeigh (93)
* @ApiTitle (专科服务-会诊时间-时间段)
* @ApiSummary (专科服务-会诊时间-时间段)
* @ApiMethod (GET)
* @ApiReturn({
"code": 1,
"msg": "成功",
"time": "1624349789",
"data": null
})
*/
public function timeList(){
$date = $this->request->get('date');
$category_id = $this->request->get('category_id');
if(empty($date) || empty($category_id)){
$this->error('缺少必需参数');
}
$date_arr = [];
for($i = 0; $i < 7; $i++){
$day = time()+$i*86400;
$date_arr[] = date('m.d',$day);
}
!in_array($date,$date_arr) && $this->error('日期不合法');
$shijianduan = 1 * 3600;
$time = str_replace('.','-',date('Y').'.'.$date);
$start = strtotime($time);
$end = strtotime('+1 days',$start);
$shijianduan_arr = [];
for ($starttime=$start; $starttime<$end; $starttime+=$shijianduan)
{
$endtime = $starttime+$shijianduan;
$date = date('Y-m-d',$day);
// 预约状态:1=确认预约,2=已预约,3=已约满
$appointment = db('appointment')
->where('user_id',$this->auth->id)
->where('category_id',$category_id)
->where('starttime',$starttime)
->where('endtime',$endtime)
->where('dept_id',$dept_id)
->where('date',$date)
->find();
$appointment = db('no_yuyue')
->where('user_id',$this->auth->id)
->where('category_id',$category_id)
->where('starttime',$starttime)
->where('endtime',$endtime)
$doctor = db('doctor')
->alias('a')
->join('doctor_nowork b','b.doctor_id = a.id and b.date = '.$date,'left')
->join('appointment c','c.doctor_id = a.id and c.date = '.$date.' and c.status in (1,2)','left')
->where('b.id',null)
->where('c.id',null)
->where('a.dept_id',$dept_id)
->field('a.id,level_id')
->find();
$shijianduan_arr[] = [
'name' => date('H:i',$starttime).'-'.date('H:i',$endtime),
'time' => $starttime.'-'.$endtime,
'is_past' => $endtime < time() ? 1 : 0,
'is_have_appointment' => $appointment ? 1 : 0,
'is_can_appoint' =>
$arr[] = [
'date' => $date,
'name' => $i == 0 ? '今天' : date('m月d日',$day),
'status' => !empty($appointment) ? 2 : (empty($doctor) ? 3 : 1),
];
}
halt($shijianduan_arr);
}
/**
... ... @@ -227,10 +233,10 @@ class Index extends Api
* @ApiSummary (医生详情)
* @ApiMethod (GET)
* @ApiReturn({
"code": 1,
"msg": "成功",
"time": "1624349789",
"data": null
"code": 1,
"msg": "成功",
"time": "1624349789",
"data": null
})
*/
public function doctorInfo(){
... ...
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\common\controller\Wechat;
use think\Db;
use think\Exception;
use think\exception\PDOException;
/**
* 支付回调
* @internal
*/
class Notify extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
protected $layout = '';
public function _initialize()
{
parent::_initialize();
}
/**
* 异步回调(预约)
* @ApiInternal
*/
public function notifyAppointment()
{
$payment = Wechat::payment();
$response = $payment->handlePaidNotify(function($message, $fail){
if ($message['return_code'] !== 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
return $fail('通信失败,请稍后再通知我');
}
// 用户支付失败 - 支付失败也需要返回true,表示服务器已处理,不然微信会反复通知,没有意义
if ($message['result_code'] === 'FAIL') {
return true;
}
// 支付成功后的业务逻辑
if ($message['result_code'] === 'SUCCESS') {
Db::startTrans();
try {
// 处理订单
$this->handleAppointmentOrder($message);
Db::commit();
} catch (PDOException $e) {
Db::rollback();
return $fail('服务器处理失败,请稍后再通知我');
} catch (Exception $e) {
Db::rollback();
return $fail('服务器处理失败,请稍后再通知我');
}
}
return true;
});
$response->send(); // return $response;
}
/**
* 异步回调(预约)-处理订单
*/
private function handleAppointmentOrder($message)
{
$order = \app\api\model\Order::get(['order_sn'=>$message['out_trade_no']]);
if (!$order || $order['pay_status'] == '1') { // 如果订单不存在 或者 订单已经支付过了
return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
}
$order->transaction_id = $message['transaction_id']; // 回填微信的订单号
$order->pay_time = time(); // 更新支付时间为当前时间
$order->status = '1';
$order->save();
return true;
}
/**
* 异步回调(礼物)
* @ApiInternal
*/
public function notifyGift()
{
$payment = Wechat::payment();
$response = $payment->handlePaidNotify(function($message, $fail){
if ($message['return_code'] !== 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
return $fail('通信失败,请稍后再通知我');
}
// 用户支付失败 - 支付失败也需要返回true,表示服务器已处理,不然微信会反复通知,没有意义
if ($message['result_code'] === 'FAIL') {
return true;
}
// 支付成功后的业务逻辑
if ($message['result_code'] === 'SUCCESS') {
Db::startTrans();
try {
// 处理订单
$this->handleGiftOrder($message);
Db::commit();
} catch (PDOException $e) {
Db::rollback();
return $fail('服务器处理失败,请稍后再通知我');
} catch (Exception $e) {
Db::rollback();
return $fail('服务器处理失败,请稍后再通知我');
}
}
return true;
});
$response->send(); // return $response;
}
/**
* 异步回调(礼物)-零元
* @ApiInternal
*/
public function notifyGiftZero($message)
{
Db::startTrans();
try {
$this->handleGiftOrder($message);
Db::commit();
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
return false;
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
return false;
}
return true;
}
/**
* 异步回调(礼物)-处理订单
*/
private function handleGiftOrder($message)
{
$order = \app\api\model\Order::get(['order_sn'=>$message['out_trade_no']]);
if (!$order || $order['pay_status'] == '1') { // 如果订单不存在 或者 订单已经支付过了
return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
}
$order->transaction_id = $message['transaction_id']; // 回填微信的订单号
$order->pay_time = time(); // 更新支付时间为当前时间
$order->pay_status = '1';
$order->save();
return true;
}
}
... ...
... ... @@ -3,11 +3,10 @@
namespace app\api\controller;
use app\common\controller\Api;
use app\common\library\Ems;
use app\common\library\Sms;
use EasyWeChat\Factory;
use fast\Random;
use think\Validate;
use think\Db;
use think\Exception;
use think\exception\PDOException;
/**
* 会员接口
... ... @@ -27,7 +26,7 @@ class User extends Api
* @ApiTitle (个人中心)
* @ApiSummary (个人中心)
* @ApiMethod (GET)
* @ApiHeaders (name="token", type="string", required=true, description="token ")
* @ApiHeaders (name="token", type="string", required=true, description="token")
* @ApiReturn ({
"code": 1,
"msg": "成功",
... ... @@ -166,4 +165,272 @@ class User extends Api
}
$this->error($this->auth->getError());
}
/**
* @ApiWeigh (89)
* @ApiTitle (医生入驻)
* @ApiSummary (医生入驻)
* @ApiMethod (POST)
* @ApiHeaders (name="token", type="string", required=true, description="token")
* @ApiParams (name=nickname, type=string, required=true, description="姓名")
* @ApiParams (name=mobile, type=string, required=true, description="联系电话")
* @ApiParams (name=city, type=string, required=true, description="所在城市")
* @ApiParams (name=idcard_front, type=string, required=true, description="身份证正面")
* @ApiParams (name=idcard_back, type=string, required=true, description="身份证反面")
* @ApiParams (name=certificates, type=string, required=true, description="从医资格证")
* @ApiReturn({
"code": 1,
"msg": "成功",
"time": "1622016289",
"data": null
})
*/
public function ruzhu(){
$post = $this->request->post();
empty($post['nickname']) && $this->error('请填写姓名');
empty($post['mobile']) && $this->error('请填写联系电话');
empty($post['city']) && $this->error('请选择所在城市');
empty($post['idcard_front']) && $this->error('请上传身份证正面');
empty($post['idcard_back']) && $this->error('请上传身份证反面');
empty($post['certificates']) && $this->error('请上传从医资格证');
$has = db('doctor')->where('user_id',$this->auth->id)->find();
!empty($has) && $this->error('您已申请,请勿重复操作');
db('doctor')->insert(array_merge([
'user_id' => $this->auth->id
],$post));
$this->success('成功');
}
/**
* @ApiWeigh (87)
* @ApiTitle (订单列表)
* @ApiSummary (订单列表)
* @ApiMethod (POST)
* @ApiHeaders (name="token", type="string", required=true, description="token")
* @ApiParams (name=status, type=integer, required=true, description="状态:1=未开始,2=诊断中,3=已完成,4=待评价")
* @ApiReturn({
"code": 1,
"msg": "成功",
"time": "1622016289",
"data": null
})
*/
public function orderList(){
$status = $this->request->get('status');
empty($status) && $this->error('缺少必需参数');
$where['user_id'] = $this->auth->id;
if($status != 4){
$where['status'] = $status;
}else{
$where['status'] = 3;
$where['is_appraise'] = '0';
}
$list = db('order')
->where($where)
->field('category_id,yuyueshiian,doctor_id')
->paginate(10);
$this->success('成功',$list);
}
/**
* @ApiWeigh (85)
* @ApiTitle (订单-确认完成)
* @ApiSummary (订单-确认完成)
* @ApiMethod (POST)
* @ApiHeaders (name="token", type="string", required=true, description="token")
* @ApiReturn({
"code": 1,
"msg": "成功",
"time": "1622016289",
"data": null
})
*/
public function orderConfirm(){
$order_id = $this->request->get('order_id');
empty($order_id) && $this->error('缺少必需参数');
$order = db('order')->where('id',$order_id)->find();
empty($order) && $this->error('订单不存在');
$order['status'] == '1' && $this->error('预约未开始');
$order['status'] == '3' && $this->error('已确认完成,请勿重复操作');
$doctor = db('doctor')->where('id',$order['doctor_id'])->find();
empty($doctor) && $this->error('医生不存在');
Db::startTrans();
try{
db('order')->where('id',$order_id)->update(['status'=>'3']);
// 统计月接单量
$receive_num_where = [
'doctor_id' => $order['doctor_id'],
'month' => date('Y-m'),
];
$receive_num = db('doctor_receive_num')
->where($receive_num_where)
->find();
if(empty($receive_num)){
db('doctor_receive_num')->insert($receive_num_where);
}else{
db('doctor_receive_num')->where('id',$receive_num['id'])->setInc('receive_num');
}
$month_receive_num = db('doctor_receive_num')->where($receive_num_where)->value('receive_num');
db('doctor')->where('id',$order['doctor_id'])->update([
'month_receive_num' => $month_receive_num
]);
// 统计总接单量
db('doctor')->where('id',$order['doctor_id'])->setInc('total_receive_num');
Db::commit();
}catch (PDOException $e){
Db::rollback();
$this->error($e->getMessage());
}catch (Exception $e){
Db::rollback();
$this->error($e->getMessage());
}
$this->success('成功');
}
/**
* @ApiWeigh (83)
* @ApiTitle (订单-评论)
* @ApiSummary (订单-评论)
* @ApiMethod (GET)
* @ApiHeaders (name="token", type="string", required=true, description="token")
* @ApiParams (name=is_solve, type=string, required=true, description="问题是否解决:0=否,1=是")
* @ApiParams (name=star, type=string, required=true, description="满意度")
* @ApiParams (name=content, type=string, required=true, description="服务评价")
* @ApiParams (name=video, type=string, required=true, description="评价视频")
* @ApiParams (name=images, type=string, required=true, description="评价图片")
* @ApiReturn({
"code": 1,
"msg": "成功",
"time": "1622016289",
"data": null
})
*/
public function orderAppraise(){
$post = $this->request->post();
!isset($post['is_solve']) && $this->error('请确定问题是否解决');
!in_array($post['is_solve'],['0','1']) && $this->error('问题是否解决参数不合法');
empty($post['star']) && $this->error('请选择满意度');
empty($post['content']) && $this->error('请输入服务评价');
$order = Order::get($post['order_id']);
empty($order) && $this->error('订单不存在');
$order['status'] != '3' && $this->error('订单未完成,无法评价');
$order['is_appraise'] == '1' && $this->error('已评价,请勿重复操作');
$doctor = Doctor::get($order['doctor_id']);
empty($doctor) && $this->error('医生信息不存在');
// 视频封面
if(!empty($post['video'])){
// 获取七牛云视频信息
$video = cdnurl($post['video'],true);
$video_info = json_decode(file_get_contents($video.'?avinfo'),true);
if(empty($video_info['streams'][0]['width'])) {
$width = $video_info['streams'][1]['width'];
$height = $video_info['streams'][1]['height'];
} else {
$width = $video_info['streams'][0]['width'];
$height = $video_info['streams'][0]['height'];
}
$post['video_cover'] = $video.'?vframe/jpg/offset/1/w/'.$width.'/h/'.$height;
}
Db::startTrans();
try{
// 评价
OrderAppraise::create(array_merge([
'user_id' => $this->auth->id,
'doctor_id' => $order['doctor_id']
],$post));
// 更新订单状态
$order->save(['is_appraise'=>'1']);
// 平均星级
$star = OrderAppraise::where('doctor_id',$order['doctor_id'])->avg('star');
$doctor->setInc('star',round($star,2));
Db::commit();
}catch (PDOException $e){
Db::rollback();
$e->getMessage();
}catch (Exception $e){
Db::rollback();
$e->getMessage();
}
$this->success('成功');
}
public function gift(){
$list = db('gift')->select();
$this->success('成功',$list);
}
/**
* @ApiWeigh (99)
* @ApiTitle (购买礼物)
* @ApiSummary (购买礼物)
* @ApiMethod (POST)
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
* @ApiParams (name="is_custom", type="string", required=true, description="是否自定义:0=否,1=是")
* @ApiParams (name="gift_id", type="inter", required=false, description="礼物ID")
* @ApiParams (name="pay_price", type="float", required=false, description="自定义金额")
*
* @ApiReturn({
"code": 1, //返回码:0=错误普通提示,1=成功,2=普通弹窗提示,3=跳转弹窗提示
"msg": "成功",
"time": "1604282876",
"data": {
"payment": [], //支付数据
"order_id": 15, //订单ID
}
})
*/
public function payGift(){
$is_custom = $this->request->get('is_custom');
$gift_id = $this->request->get('gift_id');
$pay_price = $this->request->get('pay_price');
!isset($is_custom) && $this->error('缺少必需参数');
switch ($is_custom){
case '0':
empty($gift_id) && $this->error('请选择礼物');
$gift = db('gift')->where('id',$gift_id)->find();
empty($gift) && $this->error('礼物不存在');
$pay_price = $gift['price'];
break;
case '1':
empty($pay_price) && $this->error('请填写自定义金额');
break;
default:
$this->error('参数不合法');
}
$order = GiftOrder::create([
'user_id' => $this->auth->id,
'order_sn' => get_order_sn(),
'gift_id' => $is_custom == '0' ? $gift_id : 0,
'pay_price' => $pay_price,
]);
$payment = [];
if($pay_price <= 0){
Db::startTrans();
try {
// 处理订单
(new Notify())->handleOrder([
'out_trade_no' => $order['order_sn'],
'transaction_id' => ''
]);
Db::commit();
} catch (\think\exception\PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (\think\Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
}else{
// 发起微信支付
$Wechat = new Wechat;
$openid = Db::name('third')->where('user_id',$this->auth->id)->value('openid');
if(!$payment = $Wechat->wxPay($this->model['order_sn'], $openid, $pay_price)){
$this->error($Wechat->getError());
}
}
$this->success('成功',[
'payment' => $payment,
'order_id' => $order['id']
]);
}
}
... ...
<?php
namespace app\common\controller;
use think\Controller;
use think\Request;
use EasyWeChat\Factory;
class Wechat extends Controller
{
// 错误信息
protected $_error = '';
/**
* 小程序配置
*/
public static function miniProgram(){
$wechat = get_addon_config('third')['wechat'];
$config = [
'app_id' => $wechat['app_id'],
'secret' => $wechat['app_secret'],
// 下面为可选项
// 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
'response_type' => 'array',
'log' => [
'level' => 'debug',
'file' => __DIR__.'/wechat.log',
],
];
return Factory::miniProgram($config);
}
/**
* 微信支付配置
*/
public static function payment(){
$config = get_addon_config('third')['wechat'];
$config = [
'app_id' => $wechat['app_id'],
'secret' => $wechat['app_secret'],
'notify_url' => request()->domain() . url('/index/notify/notify')
];
return Factory::payment($config);
}
/**
* 微信支付
*/
public function wxPay($order_no,$openid,$order_price)
{
$payment = self::payment();
$result = $payment->order->unify([
'body' => $order_no,
'out_trade_no' => $order_no,
'total_fee' => $order_price * 100,
'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
'openid' => $openid,
]);
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
return $payment->jssdk->bridgeConfig($result['prepay_id'], false); // 返回数组
}
if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) {
$this->setError($result['return_msg']);
return false;
}
$this->setError($result['err_code_des']);
return false;
}
/**
* 设置错误信息
*/
public function setError($error)
{
$this->_error = $error;
return $this;
}
/**
* 获取错误信息
*/
public function getError()
{
return $this->_error ? __($this->_error) : '';
}
}
... ...