教师登录、时区设置、教师设置

This commit is contained in:
Dai 2024-07-11 00:10:33 +08:00
commit f736287ee0
1099 changed files with 360637 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
/runtime
/.idea
/.vscode
/vendor
*.log
.env
/tests/tmp
/tests/.phpunit.result.cache
/certificate/

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 walkor<walkor@workerman.net> and contributors (see https://github.com/walkor/webman/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

59
README.md Normal file
View File

@ -0,0 +1,59 @@
<div style="padding:18px;max-width: 1024px;margin:0 auto;background-color:#fff;color:#333">
<h1>webman</h1>
基于<a href="https://www.workerman.net" target="__blank">workerman</a>开发的超高性能PHP框架
<h1>学习</h1>
<ul>
<li>
<a href="https://www.workerman.net/webman" target="__blank">主页 / Home page</a>
</li>
<li>
<a href="https://www.workerman.net/doc/webman" target="__blank">文档 / Document</a>
</li>
<li>
<a href="https://www.workerman.net/doc/webman/install.html" target="__blank">安装 / Install</a>
</li>
<li>
<a href="https://www.workerman.net/questions" target="__blank">问答 / Questions</a>
</li>
<li>
<a href="https://www.workerman.net/apps" target="__blank">市场 / Apps</a>
</li>
<li>
<a href="https://www.workerman.net/sponsor" target="__blank">赞助 / Sponsors</a>
</li>
<li>
<a href="https://www.workerman.net/doc/webman/thanks.html" target="__blank">致谢 / Thanks</a>
</li>
</ul>
<div style="float:left;padding-bottom:30px;">
<h1>赞助商</h1>
<h4>特别赞助</h4>
<a href="https://www.crmeb.com/?form=workerman" target="__blank">
<img src="https://www.workerman.net/img/sponsors/6429/20230719111500.svg" width="200">
</a>
<h4>铂金赞助</h4>
<a href="https://www.fadetask.com/?from=workerman" target="__blank"><img src="https://www.workerman.net/img/sponsors/1/20230719084316.png" width="200"></a>
<a href="https://www.yilianyun.net/?from=workerman" target="__blank" style="margin-left:20px;"><img src="https://www.workerman.net/img/sponsors/6218/20230720114049.png" width="200"></a>
<h4>金牌赞助</h4>
</div>
<div style="clear: both">
<h1>LICENSE</h1>
The webman is open-sourced software licensed under the MIT.
</div>
</div>

57
app/BaseController.php Normal file
View File

@ -0,0 +1,57 @@
<?php
namespace app;
use app\constant\ResponseCode;
use support\Response;
class BaseController
{
protected $noNeedLogin = [];
/**
* @desc 接口成功响应数据
* @param array $data
* @param string $msg
* @param int $code
* @return Response
*/
public function success($data, string $msg = 'success', int $code = ResponseCode::SUCCESS)
{
$result = [
'code' => $code,
'msg' => $msg,
'data' => $data
];
return json($result);
}
/**
* @desc 接口返回失败数据
* @param $msg
* @param int $code
* @param $data
* @return Response
*/
public function fail($msg = 'fail', int $code = ResponseCode::FAIL, $data = [])
{
return $this->response_json($code, $msg, $data);
}
/**
* @desc 根据数据自动返回结果
* @param array $data 必须参数 int: code string:msg array:data
* @return Response
*/
public function json(array $data)
{
$sendData = isset($data['data']) ? $data['data'] : [];
$code = isset($data['code']) ? $data['code'] : 0;
$msg = isset($data['msg']) ? $data['msg'] : '';
$result = [
'code' => $code,
'msg' => $msg,
'data' => $sendData
];
return json($result);
}
}

20
app/BaseModel.php Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace app;
use think\Model;
use think\model\concern\SoftDelete;
class BaseModel extends Model
{
use SoftDelete;
protected $connection = 'mysql';
protected $autoWriteTimestamp = true;
// 定义时间戳字段名
protected $createTime = 'created_at';
protected $updateTime = 'updated_at';
protected $deleteTime = 'deleted_at';
}

View File

@ -0,0 +1,97 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\CaseShareService;
use support\Request;
class CaseShareController extends BaseController
{
protected $noNeedLogin = ['getCaseShareList', 'caseDetail', 'getPhotographerCaseShareServiceType'];
/**
* @desc 保存案例
* @param Request $request
* @return \support\Response
*/
public function insert(Request $request)
{
$service = new CaseShareService();
$res = $service->insert($request);
return $this->json($res);
}
/**
* @desc 删除案例
* @param Request $request
* @return \support\Response
*/
public function del(Request $request)
{
$service = new CaseShareService();
$res = $service->del($request->post());
return $this->json($res);
}
/**
* @desc 更新案例
* @param Request $request
* @return \support\Response
*/
public function update(Request $request)
{
$service = new CaseShareService();
$res = $service->update($request);
return $this->json($res);
}
/**
* @desc 获取案例列表
* @param Request $request
* @return \support\Response
*/
public function getCaseShareList(Request $request)
{
$service = new CaseShareService();
$res = $service->getCaseShareList($request->get());
return $this->json($res);
}
/**
* @desc 获取用户案例列表
* @param Request $request
* @return \support\Response
*/
public function getUserCaseShareList(Request $request)
{
$service = new CaseShareService();
$res = $service->getUserCaseShareList($request);
return $this->json($res);
}
/**
* @desc 案例详情
* @param Request $request
* @return \support\Response
*/
public function cashShareDetail(Request $request)
{
$service = new CaseShareService();
$res = $service->caseDetail($request->get());
return $this->json($res);
}
/**
* @desc 摄影师案例服务类型
* @param Request $request
* @return \support\Response
*/
public function getPhotographerCaseShareServiceType(Request $request)
{
$service = new CaseShareService();
$res = $service->getPhotographerCaseShareServiceType($request->get());
return $this->json($res);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\ChatRecordsService;
use support\Request;
class ChatController extends BaseController
{
/**
* @desc 发送消息
* @param Request $request
* @return \support\Response
*/
public function sendMsg(Request $request)
{
$service = new ChatRecordsService();
$res = $service->sendMsg($request);
return $this->json($res);
}
/**
* @desc 获取用户消息
* @param Request $request
* @return \support\Response
*/
public function getUserChatMsg(Request $request)
{
$service = new ChatRecordsService();
$res = $service->getUserChatMsg($request);
return $this->json($res);
}
public function updateMsgRead(Request $request)
{
$service = new ChatRecordsService();
$res = $service->updateMsgRead($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\ChatFriendService;
use support\Request;
class ChatFriendController extends BaseController
{
/**
* @desc 聊天朋友
* @param Request $request
* @return \support\Response
*/
public function getFriends(Request $request)
{
$service = new ChatFriendService();
$res = $service->getFriends($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\DepositOrderService;
use support\Request;
class DepositOrderController extends BaseController
{
/**
* @desc 竞价订单支付定金
* @param Request $request
* @return \support\Response
*/
public function payBidOrder(Request $request)
{
$service = new DepositOrderService();
$res = $service->payBidOrder($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\DeviceService;
use support\Request;
class DeviceController extends BaseController
{
protected $noNeedLogin = ['*'];
/**
* @desc 设备列表
* @param Request $request
* @return \support\Response
*/
public function getDeviceList(Request $request)
{
$service = new DeviceService();
$res = $service->getDeviceService($request->get());
return $this->json($res);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace app\api\controller;
use app\BaseController;
use plugin\admin\app\model\Dict;
use plugin\admin\app\model\Option;
use support\Request;
class DictController extends BaseController
{
protected $noNeedLogin = ['*'];
public function get(Request $request)
{
$name = $request->get('name');
$value = Option::where('name', Dict::dictNameToOptionName($name))->value('value');
$value = $value ? json_decode($value, true) : [];
return $this->success($value);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\FavoriteService;
use support\Request;
class FavoriteController extends BaseController
{
/**
* @desc 收藏
* @param Request $request
* @return \support\Response
*/
public function add(Request $request)
{
$service = new FavoriteService();
$res = $service->add($request);
return $this->json($res);
}
/**
* @desc 取消收藏
* @param Request $request
* @return \support\Response
*/
public function cancel(Request $request)
{
$service = new FavoriteService();
$res = $service->cancel($request);
return $this->json($res);
}
/**
* @desc 收藏列表
* @param Request $request
* @return \support\Response
*/
public function getFavoriteList(Request $request)
{
$service = new FavoriteService();
$res = $service->getFavoriteList($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\PaidServiceService;
use support\Request;
class PaidServiceController extends BaseController
{
/**
* @desc 增值服务列表
* @param Request $request
* @return \support\Response
*/
public function getList(Request $request)
{
$service = new PaidServiceService();
$res = $service->getList($request->get());
return $this->json($res);
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace app\api\controller;
use app\common\service\PayService;
use support\Request;
class PayController
{
public function pay(Request $request)
{
$service = new PayService();
$res = $service->payment($request->post());
return $this->json($res);
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\PhotoServiceService;
use support\Request;
class PhotoServiceController extends BaseController
{
protected $noNeedLogin = ['select'];
/**
* @desc 获取摄影师自己的服务
* @param Request $request
* @return \support\Response
*/
public function getPhotographerSelfService(Request $request)
{
$service = new PhotoServiceService();
$res = $service->getPhotographerSelfService($request);
return $this->json($res);
}
/**
* @desc 摄影师拍照服务
* @param Request $request
* @return \support\Response
*/
public function select(Request $request)
{
$service = new PhotoServiceService();
$res = $service->select($request->get());
return $this->json($res);
}
/**
* @desc 添加拍照服务
* @param Request $request
* @return \support\Response
*/
public function add(Request $request)
{
$service = new PhotoServiceService();
$res = $service->add($request);
return $this->json($res);
}
/**
* @desc 添加拍照服务
* @param Request $request
* @return \support\Response
*/
public function edit(Request $request)
{
$service = new PhotoServiceService();
$res = $service->edit($request);
return $this->json($res);
}
public function del(Request $request)
{
$service = new PhotoServiceService();
$res = $service->del($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\PhotoServiceOrderService;
use support\Request;
class PhotoServiceOrderController extends BaseController
{
/**
* @desc 拍照服务支付
* @param Request $request
* @return \support\Response
*/
public function pay(Request $request)
{
$service = new PhotoServiceOrderService();
$res = $service->pay($request);
return $this->json($res);
}
/**
* @desc 支付保证金
* @param Request $request
* @return \support\Response
*/
public function payOrderDeposit(Request $request)
{
$service = new PhotoServiceOrderService();
$res = $service->payOrderDeposit($request);
return $this->json($res);
}
/**
* @desc 计算支付价格
* @param Request $request
* @return \support\Response
*/
public function calculatePrice(Request $request)
{
$service = new PhotoServiceOrderService();
$res = $service->calculatePrice($request->post());
return $this->json($res);
}
/**
* @desc 摄影师拍照订单列表
* @param Request $request
* @return \support\Response
*/
public function getPhotoServiceOrderForPhotographer(Request $request)
{
$service = new PhotoServiceOrderService();
$res = $service->getPhotoServiceOrderForPhotographer($request);
return $this->json($res);
}
/**
* @desc 摄影师拍照订单列表
* @param Request $request
* @return \support\Response
*/
public function getPhotoServiceOrderForUser(Request $request)
{
$service = new PhotoServiceOrderService();
$res = $service->getPhotoServiceOrderForUser($request);
return $this->json($res);
}
public function cancelPhotoOrder(Request $request)
{
$service = new PhotoServiceOrderService();
$res = $service->getPhotoServiceOrderForUser($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\PhotographerService;
use support\Request;
class PhotographerController extends BaseController
{
protected $noNeedLogin = ['getServiceType'];
/**
* @desc 摄影师申请
* @param Request $request
* @return \support\Response
*/
public function apply(Request $request)
{
$service = new PhotographerService();
$res = $service->apply($request);
return $this->json($res);
}
/**
* @desc 摄影师详情
* @param Request $request
* @return \support\Response
*/
public function edit(Request $request)
{
$service = new PhotographerService();
$res = $service->edit($request);
return $this->json($res);
}
/**
* @desc 摄影师详情
* @param Request $request
* @return \support\Response
*/
public function detail(Request $request)
{
$service = new PhotographerService();
$res = $service->detail($request);
return $this->json($res);
}
/**
* @desc 服务列表
* @param Request $request
* @return \support\Response
*/
public function getServiceType(Request $request)
{
$service = new PhotographerService();
$res = $service->getServiceType($request->get());
return $this->json($res);
}
/**
* @desc 退出工作室
* @param Request $request
* @return \support\Response
*/
public function quitStudio(Request $request)
{
$service = new PhotographerService();
$res = $service->quitStudio($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\RequirementBiddingService;
use support\Request;
class RequirementBiddingController extends BaseController
{
/**
* @desc 报价
* @param Request $request
* @return \support\Response
*/
public function bid(Request $request)
{
$service = new RequirementBiddingService();
$res = $service->bid($request);
return $this->json($res);
}
/**
* @desc 获取用户需求的出价列表
* @param Request $request
* @return \support\Response
*/
public function getUserRequirementBiddingOrderList(Request $request)
{
$service = new RequirementBiddingService();
$res = $service->getUserRequirementBiddingOrderList($request);
return $this->json($res);
}
/**
* @desc 确定出价
* @param Request $request
* @return \support\Response
*/
public function confirmBid(Request $request)
{
$service = new RequirementBiddingService();
$res = $service->confirmBid($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\RequirementService;
use support\Request;
class RequirementController extends BaseController
{
/**
* @desc 发布需求
* @param Request $request
* @return \support\Response
*/
public function publish(Request $request)
{
$service = new RequirementService();
$result = $service->publish($request);
return $this->json($result);
}
/**
* @desc 删除需求
* @param Request $request
* @return \support\Response
*/
public function del(Request $request)
{
$service = new RequirementService();
$result = $service->del($request);
return $this->json($result);
}
/**
* @desc 需求详情
* @param Request $request
* @return \support\Response
*/
public function detail(Request $request)
{
$service = new RequirementService();
$result = $service->detail($request->get());
return $this->json($result);
}
/**
* @desc 需求列表
* @param Request $request
* @return \support\Response
*/
public function getRequirement(Request $request)
{
$service = new RequirementService();
$result = $service->getRequirement($request->get());
return $this->json($result);
}
/**
* @desc 用户自己的需求列表
* @param Request $request
* @return \support\Response
*/
public function getUserSelfRequirementList(Request $request)
{
$service = new RequirementService();
$result = $service->getUserSelfRequirementList($request);
return $this->json($result);
}
/**
* @desc 竞价中的需求
* @param Request $request
* @return \support\Response
*/
public function getBidRequirements(Request $request)
{
$service = new RequirementService();
$res = $service->getBidRequirements($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\RequirementOrderService;
use support\Request;
class RequirementOrderController extends BaseController
{
/**
* @desc 支付
* @param Request $request
* @return \support\Response
*/
public function payRequirement(Request $request)
{
$service = new RequirementOrderService();
$res = $service->payRequirement($request);
return $this->json($res);
}
/**
* @desc 需求退款
* @param Request $request
* @return \support\Response
*/
public function requirementRefund(Request $request)
{
$service = new RequirementOrderService();
$res = $service->requirementRefund($request->post());
return $this->json($res);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\ServiceStandardService;
use support\Request;
class ServiceStandardController extends BaseController
{
/**
* @desc 服务标准
* @param Request $request
* @return \support\Response
*/
public function getStandard(Request $request)
{
$service = new ServiceStandardService();
$res = $service->getStandard($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\ServiceTypeService;
use support\Request;
class ServiceTypeController extends BaseController
{
protected $noNeedLogin = ['*'];
public function getServiceType(Request $request)
{
$service = new ServiceTypeService();
$res = $service->getServiceType($request->get());
return $this->json($res);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\SlideshowService;
use support\Request;
class SlideshowController extends BaseController
{
protected $noNeedLogin = ['*'];
public function getSlideshow(Request $request)
{
$service = new SlideshowService();
$res = $service->getSlideshow();
return $this->json($res);
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\StudioApplyService;
use support\Request;
class StudioApplyController extends BaseController
{
/**
* @desc 申请加入工作室
* @param Request $request
* @return \support\Response
*/
public function apply(Request $request)
{
$service = new StudioApplyService();
$res = $service->apply($request);
return $this->json($res);
}
/**
* @desc 申请列表
* @param Request $request
* @return \support\Response
*/
public function getPhotographerApplyList(Request $request)
{
$service = new StudioApplyService();
$res = $service->getPhotographerApplyList($request->get());
return $this->json($res);
}
/**
* @desc 更改审核状态
* @param Request $request
* @return \support\Response
*/
public function changeApplyStatus(Request $request)
{
$service = new StudioApplyService();
$res = $service->changeApplyStatus($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\StudioService;
use support\Request;
use think\Exception;
class StudioController extends BaseController
{
protected $noNeedLogin = ['detail'];
/**
* @desc 添加工作室
* @param Request $request
* @return \support\Response
*/
public function add(Request $request)
{
$service = new StudioService();
$res = $service->add($request);
return $this->json($res);
}
/**
* @desc 工作室列表
* @param Request $request
* @return \support\Response
*/
public function select(Request $request)
{
$service = new StudioService();
$res = $service->select($request);
return $this->json($res);
}
/**
* @desc 工作室详情
* @param Request $request
* @return \support\Response
*/
public function detail(Request $request)
{
$service = new StudioService();
$res = $service->detail($request);
return $this->json($res);
}
/**
* @desc 工作室摄影师
* @param Request $request
* @return \support\Response
*/
public function getStudioPhotographer(Request $request)
{
$service = new StudioService();
$res = $service->getStudioPhotographer($request->get());
return $this->json($res);
}
/**
* @desc 移除摄影师
* @param Request $request
* @return \support\Response
*/
public function removePhotographer(Request $request)
{
$service = new StudioService();
$res = $service->removePhotographer($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\TeacherService;
use support\Request;
class TeacherController extends BaseController
{
protected $noNeedLogin = ['login'];
public function login(Request $request)
{
$service = new TeacherService();
$res = $service->login($request->post());
return $this->json($res);
}
/**
* @desc 设置时区
* @param Request $request
* @return \support\Response
*/
public function setTimeZone(Request $request)
{
$service = new TeacherService();
$res = $service->setTimeZone($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\model\TimeZone;
use app\common\service\UploadService;
use app\constant\ResponseCode;
use app\utils\QiniuUtils;
use support\Request;
use Tinywan\Jwt\JwtToken;
class TestController extends BaseController
{
protected $noNeedLogin = ['*'];
public function test(Request $request)
{
try {
$time_zone = json_decode(file_get_contents(base_path('/timezones.json')), true);
foreach ($time_zone as $index => $item) {
$res = TimeZone::create([
'name' => $item['value'],
'abbr' => $item['abbr'],
'text' => $item['text'],
'offset' => $item['offset'],
'utc' => json_encode($item['utc'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
]);
if ($res) {
var_dump($index . '-成功');
} else {
var_dump($index . '-失败');
}
}
print '<pre>';
print_r('success');
die;
$token_data = [
'id' => 7
];
$token = JwtToken::generateToken($token_data);
print '<pre>';
print_r($token);
die;
// throw new \Exception('显示是错误测试');
} catch (\Exception $e) {
return $this->json([
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
]);
}
// return $this->json([
// 'code' => ResponseCode::SUCCESS,
// 'data'=>[1,2,3],
// 'msg' => '变更成功',
// ]);
}
public function upload(Request $request)
{
$service = new UploadService();
$res = $service->uploadImg($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\TimeZoneService;
use support\Request;
class TimeZoneController extends BaseController
{
protected $noNeedLogin = ['*'];
public function getTimeZone(Request $request)
{
$service = new TimeZoneService();
$res = $service->getTimeZone($request->get());
return $this->json($res);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\UploadService;
use support\Request;
class UploadController extends BaseController
{
protected $noNeedLogin = ['*'];
/**
* @desc 上传图片
* @param Request $request
* @return \support\Response
*/
public function uploadImg(Request $request)
{
$service = new UploadService();
$res = $service->uploadImg($request->file('image'));
return $this->json($res);
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace app\api\controller;
use app\BaseController;
use app\common\service\UserService;
use support\Request;
class UserController extends BaseController
{
protected $noNeedLogin = ['miniLogin'];
/**
* 用户登录
* @param Request $request
* @return \support\Response
*/
public function miniLogin(Request $request)
{
$service = new UserService();
$res = $service->login($request->post());
return $this->json($res);
}
public function userInfo(Request $request)
{
$service = new UserService();
$res = $service->userInfo($request);
return $this->json($res);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class BiddingOrder extends BaseModel
{
/**
* @desc 摄影师
* @return \think\model\relation\HasOne
*/
public function photographer()
{
return $this->hasOne(Photographer::class, 'id', 'photographer_id');
}
public function requirement()
{
return $this->hasOne(Requirement::class, 'id', 'requirement_id');
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
*
*/
class CaseShare extends BaseModel
{
/**
* @desc 服务类别
* @return \think\model\relation\HasOne
*/
public function serviceType()
{
return $this->hasOne(ServiceType::class, 'id', 'service_type');
}
public function photographer()
{
return $this->hasOne(Photographer::class, 'id', 'photographer_id');
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class ChatFriend extends BaseModel
{
/**
* @desc 好友信息
* @return \think\model\relation\HasOne
*/
public function friend()
{
return $this->hasOne(User::class, 'id', 'friend_id')->bind(['nickname', 'avatar', 'is_photographer']);
}
/**
* @desc 好友摄影师信息
* @return \think\model\relation\HasOne
*/
public function photographer()
{
return $this->hasOne(Photographer::class, 'id', 'photographer_id')->bind([
// 'photographer_id' => 'id',
'photographer_name' => 'name',
'photographer_avatar' => 'avatar',
]);
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
*
*/
class ChatRecords extends BaseModel
{
}

View File

@ -0,0 +1,31 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_deposit_order
* @property integer $id (主键)
* @property integer $user_id 用户
* @property integer $photographer_id 摄影师
* @property integer $requirement_id 需求
* @property mixed $requirement_detail 需求详情
* @property string $deposit_amount 保证金
* @property string $trade_no 交易单号
* @property string $transaction_id 交易流水号
* @property integer $pay_status 支付状态 0:未支付 1已支付 2:支付失败
* @property string $pay_time 支付时间
* @property string $refund_trade_no 退款单号
* @property string $refund_transaction_id 退款流水号
* @property string $refund_time 退款时间
* @property integer $is_refund 退款状态 0:为退款 1:已退款
* @property mixed $created_at 创建时间
* @property string $updated_at
* @property string $deleted_at
*/
class DepositOrder extends BaseModel
{
}

View File

@ -0,0 +1,11 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class Device extends BaseModel
{
}

View File

@ -0,0 +1,24 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_favorite
* @property integer $id (主键)
* @property integer $user_id 用户
* @property integer $photographer_id 摄影师
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class Favorite extends BaseModel
{
public function photographer()
{
return $this->hasOne(Photographer::class, 'id', 'photographer_id');
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_paid_service 增值服务
* @property integer $id (主键)
* @property string $service_name 服务名称
* @property string $price 价格
* @property integer $sort 排序(越大越靠前)
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class PaidService extends BaseModel
{
}

View File

@ -0,0 +1,24 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_photo_service 拍照服务
* @property integer $id (主键)
* @property integer $user_id
* @property integer $photographer_id 摄影师
* @property integer $service_type 服务类型
* @property string $service_standard 服务标准
* @property string $detail 服务详情
* @property string $price 服务价格
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at 删除时间
*/
class PhotoService extends BaseModel
{
}

View File

@ -0,0 +1,39 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_photo_service_order
* @property integer $id (主键)
* @property integer $user_id 用户id
* @property string $user_name 姓名
* @property string $user_mobile 手机号
* @property string $service_address 服务地址
* @property string $service_time 服务时间
* @property mixed $photo_service_detail 拍照服务详情
* @property mixed $paid_service_detail 增值服务详情
* @property integer $photographer_id 摄影师id
* @property integer $is_need_deposit 是否需要保证金
* @property string $deposit_amount 保证金
* @property integer $deposit_order_id 保证金订单id
* @property string $deposit_trade_no 保证金订单号
* @property integer $deposit_pay_status 保证金状态 0未支付 1已支付 2
* @property integer $deposit_is_refund 保证金是否退款 0:未退款 1已退款
* @property string $total 金额
* @property string $remake 备注
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class PhotoServiceOrder extends BaseModel
{
public function photographer()
{
return $this->hasOne(Photographer::class, 'id', 'photographer_id');
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class Photographer extends BaseModel
{
/**
* @desc 工作室
* @return \think\model\relation\HasOne
*/
public function studio()
{
return $this->hasOne(Studio::class, 'id', 'studio_id')->bind([
'studio_name',
'studio_img' => 'img',
'studio_introductions' => 'introductions',
]);
}
public function user()
{
return $this->hasOne(User::class, 'id', 'user_id')->bind(['nickname']);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_ratio 定金比例
* @property integer $id (主键)
* @property string $ratio 定金比例
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class Ratio extends BaseModel
{
}

View File

@ -0,0 +1,21 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class Requirement extends BaseModel
{
public function serviceType()
{
return $this->hasOne(ServiceType::class, 'id', 'service_type')->bind(['service_name']);
}
public function bidWinPhotographer()
{
return $this->hasOne(Photographer::class, 'id', 'bid_win_photographer_id');
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_requirement_order
* @property integer $id (主键)
* @property integer $user_id
* @property integer $requirement_id 需求
* @property mixed $requirement_deteail 需求详情
* @property string $trade_no 交易单号
* @property string $transaction_id 交易流水号
* @property string $amount 金额
* @property integer $pay_status 支付状态 0:未支付 1:已支付 2:取消支付 3:支付失败
* @property string $pay_time 支付时间
* @property string $refund_trade_no 退款单号
* @property string $refund_transaction_id 退款流水号
* @property string $refund_time 退款时间
* @property integer $is_refund 是否退款 0:为退款 1:已退款
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class RequirementOrder extends BaseModel
{
}

View File

@ -0,0 +1,21 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_service_standard 服务标准
* @property integer $id (主键)
* @property string $standard_name 服务标准
* @property integer $sort 排序(越大越靠前)
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class ServiceStandard extends BaseModel
{
}

View File

@ -0,0 +1,11 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class ServiceType extends BaseModel
{
}

View File

@ -0,0 +1,20 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_slideshow_setting 轮播图
* @property integer $id (主键)
* @property string $img 轮播图
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at 删除时间
*/
class Slideshow extends BaseModel
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class Studio extends BaseModel
{
}

View File

@ -0,0 +1,21 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class StudioApply extends BaseModel
{
public function photographer()
{
return $this->hasOne(Photographer::class, 'id', 'photographer_id');
}
public function studio()
{
return $this->hasOne(Studio::class, 'id', 'studio_id');
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace app\common\model;
use app\BaseModel;
use plugin\admin\app\controller\Base;
use support\Model;
/**
* wa_teacher 教师
* @property integer $id (主键)
* @property string $account 账号
* @property string $password 密码
* @property string $slat 密码盐
* @property string $teacher_name 教师姓名
* @property integer $age 年龄
* @property string $openid Openid
* @property string $time_zone_name 时区名称
* @property string $time_zone 时差
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class Teacher extends BaseModel
{
}

View File

@ -0,0 +1,24 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
/**
* wa_time_zone 时差
* @property integer $id (主键)
* @property string $name 时区名称
* @property string $text 描述
* @property string $offset 时差
* @property string $utc utc国家
* @property mixed $created_at 创建时间
* @property string $updated_at 更新时间
* @property string $deleted_at
*/
class TimeZone extends BaseModel
{
}

26
app/common/model/User.php Normal file
View File

@ -0,0 +1,26 @@
<?php
namespace app\common\model;
use app\BaseModel;
use support\Model;
class User extends BaseModel
{
protected $table = 'wa_users';
/**
* @desc 工作室
* @return \think\model\relation\HasOne
*/
public function studio()
{
return $this->hasOne(Studio::class, 'id', 'studio_id');
}
public function photographer()
{
return $this->hasOne(Photographer::class, 'user_id', 'id');
}
}

View File

@ -0,0 +1,295 @@
<?php
namespace app\common\service;
use app\common\model\CaseShare;
use app\common\model\Photographer;
use app\common\model\ServiceType;
use app\common\model\User;
use app\common\validate\CaseShareValidate;
use app\constant\ResponseCode;
use think\Exception;
class CaseShareService
{
public function insert($request)
{
try {
$user = User::where(['id' => $request->user->id])->findOrEmpty();
if (!$user->is_photographer) {
throw new Exception('您还不是摄影师,不能发布案例');
}
$validate = new CaseShareValidate();
$requestData = $request->post();
if (!$validate->check($requestData)) {
throw new Exception($validate->getError());
}
//查找摄影师
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('为找到摄影师信息');
}
$service_type = ServiceType::where(['id'=>$requestData['service_type']])->findOrEmpty();
CaseShare::create([
'user_id' => $request->user->id,
'photographer_id' => $photographer->id,
'service_type' => $requestData['service_type'],
'service_name' => $service_type->service_name,
'case_name' => $requestData['case_name'],
'case_briefing' => $requestData['case_briefing'],
'case_introduce' => $requestData['case_introduce'],
'imgs' => !empty($requestData['imgs']) ? $requestData['imgs'] : '',
// 'imgs' => !empty($requestData['imgs']) ? json_encode($requestData['imgs'], JSON_UNESCAPED_UNICODE) : '',
]);
return [
'code' => ResponseCode::SUCCESS,
'data' => [],
'msg' => '提交成功,审核成功后自动发布'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 更新案例
* @param $request
* @return array
*/
public function update($request)
{
try {
$req_data = $request->post();
$case = CaseShare::where(['id' => $req_data['id']])->findOrEmpty();
if ($case->isEmpty()) {
throw new Exception('未找到案例');
}
if ($case->user_id != $request->user->id) {
throw new Exception('非案例所有者不能操作');
}
//查找摄影师
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('为找到摄影师信息');
}
$validate = new CaseShareValidate();
if (!$validate->check($req_data)) {
throw new Exception($validate->getError());
}
$res = $case->save([
'photographer_id' => $photographer->id,
'service_type' => $req_data['service_type'],
'case_name' => $req_data['case_name'],
'case_briefing' => $req_data['case_briefing'],
'case_introduce' => $req_data['case_introduce'],
'imgs' => empty($req_data['imgs']) ? '' : json_encode($req_data['img'], JSON_UNESCAPED_UNICODE),
]);
if (!$res) {
throw new Exception('更新失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '更新成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 删除成功
* @param $request
* @return array
*/
public function del($request)
{
try {
$case = CaseShare::where(['id' => $request['id']])->findOrEmpty();
if ($case->isEmpty()) {
throw new Exception('未找到案例或已被删除');
}
$res = $case->delete();
if (!$res) {
throw new Exception('操作失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '已删除成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 案例列表
* @param $request
* @return array
*/
public function getCaseShareList($request)
{
try {
$case = CaseShare::where(['is_apply' => 1]);
if (isset($request['is_recommend']) && $request['is_recommend']) {
$case->where(['is_recommend' => $request['is_recommend']]);
}
if (isset($request['service_type']) && $request['service_type']) {
$case->where(['service_type' => $request['service_type']]);
}
$page = isset($request['page']) ? $request['page'] : 1;
$limit = isset($request['limit']) ? $request['limit'] : 10;
$total = $case->count();
$list = $case->with(['photographer'])->page($page, $limit)->select();
foreach ($list as &$item){
if($item['imgs']){
$item['imgs'] = explode(',', stripslashes($item['imgs']));
}
}
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page
],
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 用户案例列表
* @param $request
* @return array
*/
public function getUserCaseShareList($request)
{
try {
$requestData = $request->get();
$case = CaseShare::where(['user_id' => $request->user->id]);
if (isset($requestData['is_recommend']) && $requestData['is_recommend']) {
$case->where(['is_recommend' => $requestData['is_recommend']]);
}
if (isset($requestData['service_type']) && $requestData['service_type']) {
$case->where(['service_type' => $requestData['service_type']]);
}
$page = isset($requestData['page']) ? $requestData['page'] : 1;
$limit = isset($requestData['limit']) ? $requestData['limit'] : 10;
$total = $case->count();
$list = $case->page($page, $limit)->select();
foreach ($list as &$item){
if($item['imgs']){
$item['imgs'] = explode(',', $item['imgs']);
}
}
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page
],
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 案例详情
* @param $request
* @return array
*/
public function caseDetail($request)
{
try {
$case = CaseShare::where(['id' => $request['id']])->with(['serviceType', 'photographer'])->findOrEmpty();
if ($case->isEmpty()) {
throw new Exception('未找到案例');
}
if ($case->imgs) {
$case->imgs = explode(',', $case->imgs);
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $case,
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 摄影师案例服务类型
* @param $request
* @return array
*/
public function getPhotographerCaseShareServiceType($request)
{
try {
$photographer = Photographer::where(['id' => $request['photographer_id']])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('摄影师不存在');
}
$service_type = CaseShare::where(['photographer_id' => $request['photographer_id']])->field('service_type')->select()->toArray();
if($service_type){
$service_type = array_unique(array_column($service_type, 'service_type'));
$service_type = ServiceType::where(['id'=>$service_type])->order('sort desc, id desc')->field('id,service_name')->select();
}else{
$service_type = [];
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $service_type,
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace app\common\service;
use app\common\model\ChatFriend;
use app\constant\ResponseCode;
use think\Exception;
class ChatFriendService
{
/**
* @desc 获取聊天朋友
* @param $request
* @return array
*/
public function getFriends($request)
{
try {
$data = $request->get();
$chat_friend = ChatFriend::where(['user_id' => $request->user->id])->with(['friend', 'photographer'])->order('latest_chat_time desc, id desc');
$page = isset($data['page']) ? $data['page'] : 1;
$limit = isset($data['limit']) ? $data['limit'] : 10;
$total = $chat_friend->count();
$list = $chat_friend->page($page, $limit)->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,145 @@
<?php
namespace app\common\service;
use app\common\model\ChatFriend;
use app\common\model\ChatRecords;
use app\common\model\Photographer;
use app\constant\ResponseCode;
use think\Exception;
class ChatRecordsService
{
/**
* @desc 发送消息
* @param $request
* @return array
*/
public function sendMsg($request)
{
try {
$data = $request->post();
//记录聊天数据
$res = ChatRecords::create([
'from_user_id' => $request->user->id,
'to_user_id' => $data['user_id'],
'type' => $data['type'],
'content' => $data['content'],
]);
//判断是否是好友
$friend = ChatFriend::where(['user_id' => $request->user->id, 'friend_id' => $data['user_id']])->findOrEmpty();
if ($friend->isEmpty()) {
$friend_photographer = Photographer::where(['user_id' => $data['user_id']])->findOrEmpty();
$friend_photographer_id = 0;
if (!$friend_photographer->isEmpty()) {
$friend_photographer_id = $friend_photographer->id;
}
ChatFriend::create([
'user_id' => $request->user->id,
'friend_id' => $data['user_id'],
'photographer_id' => $friend_photographer_id
]);
$photographer = Photographer::where(['user_id' => $data['user_id']])->findOrEmpty();
$photographer_id = 0;
if (!$photographer->isEmpty()) {
$photographer_id = $photographer->id;
}
ChatFriend::create([
'user_id' => $data['user_id'],
'friend_id' => $request->user->id,
'photographer_id' => $photographer_id
]);
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '发送成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 获取用户发送的消息
* @param $request
* @return array
*/
public function getUserChatMsg($request)
{
try {
$data = $request->get();
$chat_msg = ChatRecords::whereRaw('(from_user_id = ? and to_user_id = ?) or (from_user_id = ? and to_user_id = ?)', [
$request->user->id,
$data['user_id'],
$data['user_id'],
$request->user->id
])
->field('from_user_id,to_user_id,type,content, created_at')
->order('created_at desc');
$page = isset($data['page']) ? $data['page'] : 1;
$limit = isset($data['limit']) ? $data['limit'] : 10;
$total = $chat_msg->count();
$list = $chat_msg->page($page, $limit)->select()->toArray();
foreach ($list as &$item) {
if($item['from_user_id'] == $request->user->id){
$item['is_i_send'] = 1;
}else{
$item['is_i_send'] = 0;
}
}
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 标记消息已读
* @param $request
* @return array
*/
public function updateMsgRead($request)
{
try {
$data = $request->post();
ChatRecords::where(['from_user_id' => $data['from_user_id'], 'to_user_id' => $request->user->id, 'status' => 0])->update(['status' => 1]);
return [
'code' => ResponseCode::SUCCESS,
'msg' => '已读',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace app\common\service;
use app\common\model\BiddingOrder;
use app\common\model\DepositOrder;
use app\common\model\Requirement;
use app\common\model\User;
use app\constant\ResponseCode;
use think\Exception;
class DepositOrderService
{
/**
* 需求保证金回调地址
*/
const NOTIFY_URL = '/notify/WechatPayNotify/requirement_deposit_notify';
/**
* @desc 竞价订单支付定金
* @param $request
* @return array
*/
public function payBidOrder($request)
{
try {
$requestData = $request->post();
$bidding_order = BiddingOrder::where(['id' => $requestData['bidding_order_id']])->findOrEmpty();
if ($bidding_order->isEmpty()) {
throw new Exception('未找到出价订单');
}
if ($bidding_order->bind_status != 1) {
throw new Exception('该出价订单未中标,支付失败');
}
if ($bidding_order->pay_final_status != 0) {
throw new Exception('订单状态异常,支付失败');
}
$requirement = Requirement::where(['id' => $bidding_order->requirement_id])->findOrEmpty();
//@todo判断是否需要支付定金
if(1){
}
$trade_no = generate_order_no('B');
//创建订单
DepositOrder::create([
'user_id' => $bidding_order->user_id,
'photographer_id' => $bidding_order->photographer_id,
'detail' => json_encode($requirement->toArray()),
'order_type' => 'requirement',
'deposit_amount' => $requirement->deposit_amount,
'trade_no' => $trade_no,
'pay_status' => 0,
]);
$pay_data = [
'trade_no' => $trade_no,
'total_amount' => $bidding_order->bidding_price,
'desc' => $requirement->requirement_trade_no . '-定金',
'notify_url' => getenv('SERVER_DOMAIN') . self::NOTIFY_URL,//回调地址
'openid' => $request->user->openid,
];
$result = (new PayService())->payment($pay_data);
if(isset($result['code'])){
throw new Exception($result['msg']);
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $result,
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace app\common\service;
use app\common\model\Device;
use app\constant\ResponseCode;
use think\Exception;
class DeviceService
{
/**
* @desc 设备列表
* @return array
*/
public function getDeviceService()
{
try {
$list = Device::order('sort desc, id desc')->field('id,device_name')->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list
],
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,128 @@
<?php
namespace app\common\service;
use app\common\model\Favorite;
use app\constant\ResponseCode;
use support\Redis;
use think\Exception;
class FavoriteService
{
/**
* @desc 收藏
* @param $request
* @return array
*/
public function add($request)
{
try {
$data = $request->post();
$redis_key = 'favorite_' . $request->user->id . '-' . $data['photographer_id'];
if (Redis::get($redis_key)) {
throw new Exception('不能操作太频繁哟~');
}
Redis::setEx($redis_key, 5, 1);
$favorite = Favorite::where(['user_id' => $request->user->id, 'photographer_id' => $data['photographer_id']])->findOrEmpty();
if (!$favorite->isEmpty()) {
throw new Exception('您已收藏了该摄影师,不能重复收藏哟~');
}
$res = Favorite::create([
'user_id' => $request->user->id,
'photographer_id' => $data['photographer_id']
]);
if (!$res) {
throw new Exception('收藏失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '收藏成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 取消收藏
* @param $request
* @return array
*/
public function cancel($request)
{
try {
$data = $request->post();
$redis_key = 'favorite_' . $request->user->id . '-' . $data['photographer_id'];
if (Redis::get($redis_key)) {
throw new Exception('不能操作太频繁哟~');
}
Redis::setEx($redis_key, 5, 1);
$favorite = Favorite::where(['user_id' => $request->user->id, 'photographer_id' => $data['photographer_id']])->findOrEmpty();
if ($favorite->isEmpty()) {
throw new Exception('您未收藏该摄影师');
}
$res = $favorite->delete();
if (!$res) {
throw new Exception('取消收藏失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '取消成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 收藏列表
* @param $request
* @return array
*/
public function getFavoriteList($request)
{
try {
$data = $request->get();
$favorite = Favorite::order('id desc')->where(['user_id' => $request->user->id]);
$page = isset($data['page']) ? $data['page'] : 1;
$limit = isset($data['limit']) ? $data['limit'] : 10;
$total = $favorite->count();
$list = $favorite->with(['photographer'])->page($page, $limit)->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace app\common\service;
use app\common\model\PaidService;
use app\constant\ResponseCode;
use think\Exception;
class PaidServiceService
{
/**
* @desc 增值服务列表
* @param $request
* @return array
*/
public function getList($request)
{
try {
$model = PaidService::order('sort desc,id desc');
if(isset($request['service_type_id']) && $request['service_type_id']){
$model->where(['service_type_id'=>$request['service_type_id']]);
}
$list = $model->field('id,service_name,price')->select();
return [
'code' => ResponseCode::SUCCESS,
'data'=> $list
];
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,180 @@
<?php
namespace app\common\service;
use app\common\service\Channel\wechat\WechatConstants;
use app\constant\ResponseCode;
use GuzzleHttp\Exception\RequestException;
use think\Exception;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
use WeChatPay\Util\PemUtil;
class PayService
{
protected $config;
protected $instance;
protected $platformPublicKeyInstance;
protected $merchantPrivateKeyInstance;
public function __construct()
{
// 服务商 商户号
$merchantId = getenv('MERCHANT_ID');
// 从本地文件中加载「商户API私钥」「商户API私钥」会用来生成请求的签名
$merchantPrivateKeyFilePath = 'file://' . base_path() . '/certificate/apiclient_key.pem';
$this->merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」
$merchantCertificateSerial = '3297EB3A1132A39DAFFD70A6C4A6C3078CD346F7';
// 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
$this->platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 从「微信支付平台证书」中获取「证书序列号」
$platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
// 构造一个 APIv3 客户端实例
$this->instance = Builder::factory([
'mchid' => $merchantId,
'serial' => $merchantCertificateSerial,
'privateKey' => $this->merchantPrivateKeyInstance,
'certs' => [
$platformCertificateSerial => $this->platformPublicKeyInstance,
],
]);
}
/**
* @desc jsapi支付
* @param array $pay_data
* @param $seller_channel
* @return array
*/
public function payment(array $pay_data)
{
try {
$request_data = [
'appid' => getenv('APP_ID'),// 公众号ID
'mchid' => getenv('MERCHANT_ID'),//直连商户号
'description' => $pay_data['desc'],//商品描述
'out_trade_no' => $pay_data['out_trade_no'],//商户订单号
'notify_url' => $pay_data['notify_url'],//通知地址
'amount' => [
'total' => round($pay_data['total_amount'] * 100),//总金额 单位为分
],
'payer' => [
'openid' => $pay_data['openid'],// 用户在服务商AppID下的唯一标识
]
];
$resp = $this->instance
->chain('/v3/pay/transactions/jsapi')
->post([
'json' => $request_data,
// 'debug' => true
]);
$result = json_decode($resp->getBody(), true);
raw_log('wechat_pay/transactions_jsapi', ['request_data' => $request_data, 'result' => $result]);
$pay_data = [
'appId' => getenv('APP_ID'), //微信小程序appid
'timeStamp' => strval(Formatter::timestamp()),
'nonceStr' => Formatter::nonce(),
'package' => 'prepay_id=' . $result['prepay_id'],
];
$pay_data['paySign'] = Rsa::sign(
Formatter::joinedByLineFeed(...array_values($pay_data)),
$this->merchantPrivateKeyInstance
);
$pay_data['signType'] = 'RSA';
return $pay_data;
} catch (RequestException $exception) {
$response = $exception->getResponse();
$result = json_decode($response->getBody()->getContents(), true);
raw_log('wechat_pay/transactions_jsapi_failed', ['pay_data' => $pay_data, 'result' => $result]);
return [
'code' => ResponseCode::FAIL,
'msg' => $result['message']
];
}
}
/**
* @desc 退款
* @param $refund_data
* @return array
*/
public function refundPayment($refund_data)
{
try {
//退款数据
$request_data = [
'out_trade_no' => $refund_data['out_trade_no'],//微信支付订单号
'out_refund_no' => $refund_data['out_refund_no'],//商户退款单号
'reason' => $refund_data['refund_desc'],//退款原因
'notify_url' => $refund_data['notify_url'],//通知地址
'amount' => [
'refund' => round($refund_data['refund_amount'] * 100),//退款金额
'total' => round($refund_data['total'] * 100),//原订单金额
'currency' => 'CNY',//退款币种
]
];
$resp = $this->instance
->chain('/v3/refund/domestic/refunds')
->post([
'json' => $request_data,
// 'debug' => true
]);
$result = json_decode($resp->getBody(), true);
raw_log('wechat_pay/refund', ['request_data' => $request_data, 'result' => $result]);
return [
'transaction_id' => $result['transaction_id'],
'out_transaction_id' => $result['refund_id'],
'out_trade_no' => $result['out_refund_no'],
];
} catch (RequestException $exception) {
$response = $exception->getResponse();
$result = json_decode($response->getBody()->getContents(), true);
raw_log('wechat_pay/refund_failed', ['request_data' => $request_data, 'result' => $result]);
return [
'code' => ResponseCode::FAIL,
'msg' => $result['message']
];
}
}
/**
* @desc 余额查询 微信没有余额查询接口,返回假数据
* @param $seller_channel
* @return array
*/
public function queryBalanceAmount($seller_channel)
{
return [
'code'=>ResponseCode::SUCCESS,
'data'=>[
'total_amount'=>0.00,
'settled_amount'=>0.00,
'not_settled_amount'=>0.00
]
];
}
}

View File

@ -0,0 +1,378 @@
<?php
namespace app\common\service;
use app\common\model\DepositOrder;
use app\common\model\PaidService;
use app\common\model\Photographer;
use app\common\model\PhotoService;
use app\common\model\PhotoServiceOrder;
use app\constant\ResponseCode;
use support\Redis;
use think\Exception;
class PhotoServiceOrderService
{
const NOTIFY_URL = '/notify/WechatPayNotify/photo_notify';
const NOTIFY_DEPOSIT_URL = '/notify/WechatPayNotify/photo_deposit_notify';
public function pay($request)
{
try {
$data = $request->post();
$redis_key = 'photo_service_order_' . $request->user->id;
// if (Redis::get($redis_key)) {
// throw new Exception('请勿频繁操作');
// }
// Redis::setEx($redis_key, 3, 1);
//计算服务价格
$photo_service_price = 0.00;
$paid_service_price = 0.00;
$photo_service_detail = [];
$paid_service_detail = [];
if ($data['photo_service']) {
$photo_service = json_decode($data['photo_service'], true);
foreach ($photo_service as $item) {
$service = PhotoService::where(['id' => $item['id']])->findOrEmpty();
// if($service->isEmpty()){
// throw new Exception('所选拍照服务不存在');
// }
$photo_service_price += round($service->price + $item['number'], 2);
array_push($photo_service_detail, [
'service' => $service->toArray(),
'number' => $item['number']
]);
}
}
if ($data['paid_service']) {
$paid_service = json_decode($data['paid_service'], true);
foreach ($paid_service as $item) {
$service = PaidService::where(['id' => $item['id']])->findOrEmpty();
$paid_service_price += round($service->price * $item['number'], 2);
array_push($paid_service_detail, [
'service' => $service->toArray(),
'number' => $item['number']
]);
}
}
$total = round($photo_service_price + $paid_service_price, 2);
//保证金
$deposit = 0.00;
if ($data['is_need_deposit']) {
$ratio = RatioService::ratio();
$deposit = round($total * $ratio / 100, 2);
}
$order_no = generate_order_no('P');
//插入订单
$res = PhotoServiceOrder::create([
'user_id' => $request->user->id,
'trade_no' => $order_no,
'user_name' => $data['user_name'],
'sex' => $data['sex'],
'user_mobile' => $data['user_mobile'],
'service_address' => $data['service_address'],
'service_time' => $data['service_time'],
'photo_service_type' => $data['photo_service_type'],
'photo_service_data' => $data['photo_service'],
'photo_service_detail' => json_encode($photo_service_detail),
'paid_service_type' => $data['paid_service_type'],
'paid_service_data' => $data['paid_service'],
'paid_service_detail' => json_encode($paid_service_detail),
'photographer_id' => $data['photographer_id'],
'is_need_deposit' => $data['is_need_deposit'],
'deposit_amount' => $deposit,
'total' => $total,
'remake' => $data['remake'],
]);
if (!$res) {
throw new Exception('创建订单失败');
}
$pay_data = [
'trade_no' => $order_no,
'total_amount' => $total,
'desc' => '拍照服务付款',
'notify_url' => getenv('SERVER_DOMAIN') . self::NOTIFY_URL,//回调地址
'openid' => $request->user->openid,
];
$result = (new PayService())->payment($pay_data);
if (isset($result['code'])) {
throw new Exception($result['msg']);
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $result,
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 计算价格
* @param $request
* @return array|void
*/
public function calculatePrice($request)
{
try {
$photo_service_price = 0.00;
$paid_service_price = 0.00;
if ($request['photo_service']) {
$photo_service = json_decode($request['photo_service'], true);
foreach ($photo_service as $item) {
$service = PhotoService::where(['id' => $item['id']])->findOrEmpty();
$photo_service_price += round($service->price + $item['number'], 2);
}
}
if ($request['paid_service']) {
$paid_service = json_decode($request['paid_service'], true);
foreach ($paid_service as $item) {
$service = PaidService::where(['id' => $item['id']])->findOrEmpty();
$paid_service_price += round($service->price * $item['number'], 2);
}
}
$total = round($photo_service_price + $paid_service_price, 2);
$deposit = 0.00;
if ($request['is_need_deposit']) {
$ratio = RatioService::ratio();
$deposit = round($total * $ratio / 100, 2);
}
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'total' => $total,
'deposit' => $deposit,
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 拍照服务支付保证金
* @param $request
* @return array
*/
public function payOrderDeposit($request)
{
try {
$data = $request->post();
//查找订单
$photo_order = PhotoServiceOrder::where(['id' => $data['order_id']])->findOrEmpty();
if ($photo_order->isEmpty()) {
throw new Exception('订单不存在');
}
if ($photo_order->is_need_deposit != 1) {
throw new Exception('该订单无需支付保证金');
}
if ($photo_order->pay_status != 1) {
throw new Exception('用户未付款,无需支付保证金');
}
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->id != $photo_order->photographer_id) {
throw new Exception('非摄影师本人无法支付');
}
$order_no = generate_order_no('D');
$deposit_order = DepositOrder::create([
'user_id' => $request->user->id,
'photographer_id' => $photographer->id,
'order_type' => 'photo',
'deposit_amount' => $photo_order->deposit_amount,
'trade_no' => $order_no,
]);
if (!$deposit_order) {
throw new Exception('创建订单失败');
}
//订单表中插入保证金订单号
$photo_order->save([
'deposit_order_id' => $deposit_order->id,
'deposit_trade_no' => $order_no
]);
$pay_data = [
'trade_no' => $order_no,
'total_amount' => $photo_order->deposit_amount,
'desc' => '拍照服务付款',
'notify_url' => getenv('SERVER_DOMAIN') . self::NOTIFY_DEPOSIT_URL,//回调地址
'openid' => $request->user->openid,
];
$result = (new PayService())->payment($pay_data);
if (isset($result['code'])) {
throw new Exception($result['msg']);
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $result
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 摄影师拍照订单列表
* @param $request
* @return array|void
*/
public function getPhotoServiceOrderForPhotographer($request)
{
try {
$data = $request->get();
//摄影师信息
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到摄影师信息');
}
$order = PhotoServiceOrder::order('id desc')->where(['photographer_id' => $photographer->id]);
if (isset($data['status']) && $data['status'] != -1) {
$order->where(['status' => $data['status']]);
}
$page = isset($data['page']) ? $data['page'] : 1;
$limit = isset($data['limit']) ? $data['limit'] : 10;
$total = $order->count();
$list = $order->page($page, $limit)->with(['photographer'])->select();
foreach ($list as &$item){
if($item['photo_service_detail']){
$item['photo_service_detail'] = json_decode($item['photo_service_detail'], true);
}
if($item['paid_service_detail']){
$item['paid_service_detail'] = json_decode($item['paid_service_detail'], true);
}
}
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 摄影师拍照订单列表
* @param $request
* @return array|void
*/
public function getPhotoServiceOrderForUser($request)
{
try {
$data = $request->get();
$order = PhotoServiceOrder::order('id desc')->where(['user_id' => $request->user->id]);
if (isset($data['status']) && $data['status'] != -1) {
$order->where(['status' => $data['status']]);
}
$page = isset($data['page']) ? $data['page'] : 1;
$limit = isset($data['limit']) ? $data['limit'] : 10;
$total = $order->count();
$list = $order->page($page, $limit)->with(['photographer'])->select();
foreach ($list as &$item){
if($item['photo_service_detail']){
$item['photo_service_detail'] = json_decode($item['photo_service_detail'], true);
}
if($item['paid_service_detail']){
$item['paid_service_detail'] = json_decode($item['paid_service_detail'], true);
}
}
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
public function confirmPhotoOrder($request)
{
try {
$data = $request->post();
$photographer = Photographer::where(['user_id'=>$request->user->id])->findOrEmpty();
if($photographer->isEmpty()){
throw new Exception('未找到您的摄影师信息,操作失败');
}
$order = PhotoServiceOrder::where(['out_trade_no'=>$data['out_trade_no']])->findOrEmpty();
if($order->isEmpty()){
throw new Exception('未找到订单信息');
}
if($order->photographer_id != $photographer->id){
throw new Exception('非该订单摄影师不能操作');
}
$order->save([
]);
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 取消订单
* @param $request
* @return array|void
*/
public function cancelPhotoOrder($request)
{
try {
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,199 @@
<?php
namespace app\common\service;
use app\common\model\Photographer;
use app\common\model\PhotoService;
use app\common\validate\PhotoServiceValidate;
use app\constant\ResponseCode;
use think\Exception;
class PhotoServiceService
{
/**
* @desc 获取摄影师自己的的服务列表
* @param $request
* @return array
*/
public function getPhotographerSelfService($request)
{
try {
$list = PhotoService::where(['user_id' => $request->user->id])->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => $list
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 获取摄影师的服务列表
* @param $request
* @return array
*/
public function select($request)
{
try {
$photographer_service = PhotoService::where(['photographer_id' => $request['photographer_id']]);
if(isset($request['service_type']) && !empty($request['service_type'])){
$photographer_service->where(['service_type' => $request['service_type']]);
}
$list = $photographer_service->field('id,photographer_id,service_type,service_standard,detail,price')
->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => $list
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 添加拍照服务
* @param $request
* @return array
*/
public function add($request)
{
try {
$data = $request->post();
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到摄影师信息,添加失败');
}
$validate = new PhotoServiceValidate();
if (!$validate->check($data)) {
throw new Exception($validate->getError());
}
$servicePhotoExit = PhotoService::where(['photographer_id' => $photographer->id, 'service_type' => $data['service_type']])->findOrEmpty();
if (!$servicePhotoExit->isEmpty()) {
throw new Exception('该服务类型内容已存在,不能重复添加');
}
$res = PhotoService::create([
'user_id' => $request->user->id,
'photographer_id' => $photographer->id,
'service_type' => $data['service_type'],
'service_standard' => $data['service_standard'],
'detail' => $data['detail'],
'price' => $data['price'],
]);
if (!$res) {
throw new Exception('添加失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '添加成功',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 添加拍照服务
* @param $request
* @return array
*/
public function edit($request)
{
try {
$data = $request->post();
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到摄影师信息,操作失败');
}
$validate = new PhotoServiceValidate();
if (!$validate->check($data)) {
throw new Exception($validate->getError());
}
$photoService = PhotoService::where(['id' => $data['id']])->findOrEmpty();
if ($photoService->isEmpty()) {
throw new Exception('服务内容不存在');
}
if ($photographer->id != $photoService->photographer_id) {
throw new Exception('非摄影师本人不能操作');
}
$res = $photoService->save([
'service_type' => $data['service_type'],
'service_standard' => $data['service_standard'],
'detail' => $data['detail'],
'price' => $data['price'],
]);
if (!$res) {
throw new Exception('操作失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '操作成功',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 删除拍照服务
* @param $request
* @return array
*/
public function del($request)
{
try {
$data = $request->post();
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到摄影师信息,操作失败');
}
$validate = new PhotoServiceValidate();
if (!$validate->check($data)) {
throw new Exception($validate->getError());
}
$photoService = PhotoService::where(['id' => $data['id']])->findOrEmpty();
if ($photoService->isEmpty()) {
throw new Exception('服务内容不存在');
}
if ($photographer->id != $photoService->photographer_id) {
throw new Exception('非摄影师本人不能操作');
}
$res = $photoService->delete();
if (!$res) {
throw new Exception('操作失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '操作成功',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,258 @@
<?php
namespace app\common\service;
use app\common\model\Favorite;
use app\common\model\Photographer;
use app\common\model\Requirement;
use app\common\model\ServiceType;
use app\common\model\Studio;
use app\common\model\User;
use app\common\validate\PhotographerValidate;
use app\constant\ResponseCode;
use think\Exception;
class PhotographerService
{
/**
* @desc 摄影师申请
* @param $request
* @return array
*/
public function apply($request)
{
try {
$requestData = $request->post();
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if (!$photographer->findOrEmpty()) {
if ($photographer->apply_status == 0) {
throw new Exception('你已有申请待审批,请勿重新申请');
}
if ($photographer->apply_status == 1) {
throw new Exception('你是摄影师,请勿重新申请');
}
}
$validate = new PhotographerValidate();
if (!$validate->check($requestData)) {
throw new Exception($validate->getError());
}
$res = Photographer::create([
'user_id' => $request->user->id,
'name' => $requestData['name'],
'avatar' => $requestData['avatar'],
'sex' => $requestData['sex'],
'mobile' => $requestData['mobile'],
'device_id' => $requestData['device_id'],
'service_type' => $requestData['service_type'],
'age' => $requestData['age'],
'province_code' => $requestData['province_code'],
'province_name' => $requestData['province_name'],
'city_code' => $requestData['city_code'],
'city_name' => $requestData['city_name'],
'work_time' => $requestData['work_time'],
'work_year' => $requestData['work_year'],
'introduce' => $requestData['introduce'],
]);
if (!$res) {
throw new Exception('操作失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '申请已提交,请等待平台审核'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 更改申请状态
* @param $request
* @return array|void
*/
public function changeApply($request)
{
try {
$photographer = Photographer::where(['id' => $request['id']])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('申请不存在');
}
$photographer->save(['apply_status' => $request['apply_status']]);
if ($request['apply_status'] == 1) {
User::where(['id' => $photographer->user_id])->save(['is_photographer' => 1]);
} else {
User::where(['id' => $photographer->user_id])->save(['is_photographer' => 0]);
}
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 摄影师编辑
* @param $request
* @return array|void
*/
public function edit($request)
{
try {
$requestData = $request->post();
$photographer = Photographer::where(['id' => $requestData['id']])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到摄影师');
}
$photographer->save([
'user_id' => $request->user->id,
'name' => $requestData['name'],
'avatar' => $requestData['avatar'],
'sex' => $requestData['sex'],
'mobile' => $requestData['mobile'],
'device_id' => $requestData['device_id'],
'service_type' => $requestData['service_type'],
'age' => $requestData['age'],
'city_name' => $requestData['city_name'],
'work_time' => $requestData['work_time'],
'work_year' => $requestData['work_year'],
'introduce' => $requestData['introduce'],
]);
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 摄影师详情
* @param $request
* @return array
*/
public function detail($request)
{
try {
$data = $request->get();
if (!isset($data['id'])) {
throw new Exception('参数错误');
}
$photographer = Photographer::where(['id' => $data['id'], 'apply_status' => 1])->with('studio')->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('摄影师不存在');
}
if ($photographer->device_id) {
$photographer->device_id = array_map('intval', explode(',', $photographer->device_id));
}
if ($photographer->service_type) {
$photographer->service_type = array_map('intval', explode(',', $photographer->service_type));
}
$photographer->is_favorite = 0;
if (!empty($request->user)) {
$favorite = Favorite::where(['user_id' => $request->user->id, 'photographer_id' => $photographer->id])->findOrEmpty();
if (!$favorite->isEmpty()) {
$photographer->is_favorite = 1;
}
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $photographer,
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 获取摄影师的服务类目
* @param $request
* @return array
*/
public function getServiceType($request)
{
try {
$photographer = Photographer::where(['id' => $request['photographer_id']])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到摄影师');
}
$service_type = [];
if ($photographer->service_type) {
$service_type = ServiceType::where(['id' => explode(',', $photographer->service_type)])->order('sort desc, id desc')->field('id,service_name')->select();
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $service_type,
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc
* @param $request
* @return array|void
*/
public function quitStudio($request)
{
try {
$data = $request->post();
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到您的摄影师数据,退出失败');
}
if(empty($photographer->studio_id)){
throw new Exception('摄影师未加入工作室');
}
// $studio = Studio::where(['id' => $photographer->studio_id])->findOrEmpty();
// if ($studio->isEmpty()) {
// throw new Exception('未找到工作室信息,退出失败');
// }
$photographer->save([
'studio_id' => 0
]);
User::where(['id' => $request->user->id])->save([
'studio_id' => 0
]);
return [
'code' => ResponseCode::SUCCESS,
'msg' => '操作成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace app\common\service;
use app\common\model\Ratio;
class RatioService
{
/**
* @desc 定金比例
* @return mixed
*/
public static function ratio()
{
return Ratio::where(['id'=>1])->value('ratio');
}
}

View File

@ -0,0 +1,189 @@
<?php
namespace app\common\service;
use app\common\model\BiddingOrder;
use app\common\model\Photographer;
use app\common\model\Requirement;
use app\common\model\ServiceType;
use app\constant\ResponseCode;
use think\Exception;
class RequirementBiddingService
{
/**
* @desc 报价
* @param $request
* @return array
*/
public function bid($request)
{
try {
$data = $request->post();
$requirement = Requirement::where(['id' => $data['requirement_id']])->findOrEmpty();
if ($requirement->isEmpty()) {
throw new Exception('报价需求不存在');
}
if ($requirement->status != 1) {
throw new Exception('当前需求已不在报价阶段,无法报价');
}
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到您的摄影师信息,不能报价');
}
$bidding_order = BiddingOrder::where(['user_id' => $photographer->user_id, 'requirement_id' => $requirement->id])->findOrEmpty();
if (!$bidding_order->isEmpty()) {
throw new Exception('你已存在报价记录,不能再次报价');
}
if (!isset($data['bidding_price']) || $data['bidding_price'] <= 0) {
throw new Exception('请输入正确的报价价格');
}
$res = BiddingOrder::create([
'user_id' => $request->user->id,
'photographer_id' => $photographer->id,
'requirement_id' => $requirement->id,
'requirement_user_id' => $requirement->user_id,
'requirement_detail' => json_encode($requirement->toArray()),
'requirement_price' => $requirement->price,
'bidding_price' => $data['bidding_price'],
]);
if (!$res) {
throw new Exception('报价失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '报价成功',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 获取用户需求的出价列表
* @param $request
* @return array
*/
public function getUserRequirementBiddingOrderList($request)
{
try {
$data = $request->get();
$bidding_order = BiddingOrder::where(['requirement_user_id' => $request->user->id, 'requirement_id' => $data['requirement_id']])->order('requirement_id desc,id desc');
$page = isset($data['page']) ? $data['page'] : 1;
$limit = isset($data['limit']) ? $data['limit'] : 10;
$total = $bidding_order->count();
$list = $bidding_order->with(['photographer'])
->field('id,user_id,photographer_id,requirement_id,requirement_price,bidding_price,bind_status,created_at')
->page($page, $limit)
->select();
foreach ($list as &$item) {
if ($item['photographer']) {
$service_type_name = '';
if($item['photographer']['service_type']){
$service_type_name = ServiceType::where([
'id'=>explode(',',$item['photographer']['service_type'])
])
->field('service_name')
->order('sort desc, id desc')
->select();
if($service_type_name){
$service_type_name = array_column($service_type_name->toArray(),'service_name');
}
}
$item['photographer']['service_type_name'] = $service_type_name;
}
}
$requirement = Requirement::where(['id' => $data['requirement_id']])->with('serviceType')->findOrEmpty();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'requirement' => $requirement,
'total' => $total,
'page' => $page
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 确定报价
* @param $request
* @return array|void
*/
public function confirmBid($request)
{
try {
$data = $request->post();
$bid_order = BiddingOrder::where(['id' => $data['bidding_order_id']])->findOrEmpty();
if ($bid_order->isEmpty()) {
throw new Exception('竞价订单不存在');
}
$requirement = Requirement::where(['id' => $bid_order->requirement_id])->findOrEmpty();
if ($requirement->isEmpty()) {
throw new Exception('需求不存在');
}
if ($requirement->status != 1) {
throw new Exception('需求不在出价中,无法确定报价');
}
if ($request->user->id != $bid_order->requirement_user_id) {
throw new Exception('非需求本人无法确定报价');
}
//计算定金
$ratio = RatioService::ratio();
$deposit_amount = 0;
if($requirement->is_need_deposit){
$deposit_amount = round($ratio * $bid_order->bidding_price / 100, 2);
}
//需求表
$requirement->save([
'bidding_order_id' => $bid_order->id,
'bid_win_user_id' => $bid_order->user_id,
'bid_win_photographer_id' => $bid_order->photographer_id,
'final_price' => $bid_order->bidding_price,
'deposit_amount' => $deposit_amount,
'status' => 2
]);
//竞价表
$bid_order->save([
'bind_status' => 1
]);
//更新其他竞价数据为【未中标】
BiddingOrder::where(['requirement_id' => $bid_order->requirement_id])->where('id', '<>', $bid_order->id)->save([
'bind_status' => 2
]);
return [
'code' => ResponseCode::SUCCESS,
'msg' => '确定出价完成,请尽快完成支付',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,127 @@
<?php
namespace app\common\service;
use app\common\model\Requirement;
use app\common\model\RequirementOrder;
use app\constant\ResponseCode;
use think\Exception;
class RequirementOrderService
{
/**
* 回调地址
*/
const NOTIFY_URL = '/notify/WechatPayNotify/requirement_notify';
const NOTIFY_REQUIREMENT_REFUND_URL = '/notify/WechatPayNotify/requirement_refund_notify';//需求退款
/**
* @desc 用户支付需求金额
* @param $require
* @return array|void
*/
public function payRequirement($request)
{
try {
$request_data = $request->post();
$requirement = Requirement::where(['id' => $request_data['requirement_id']])->findOrEmpty();
if ($requirement->status != 2) {
throw new Exception('需求订单状态错误,支付失败');
}
$requirement_order = RequirementOrder::where(['requirement_trade_no' => $requirement->requirement_trade_no])->findOrEmpty();
if ($requirement_order->isEmpty()) {
throw new Exception('需求订单不存在');
}
if ($requirement_order->pay_status != 0) {
throw new Exception('订单状态校验失败,支付失败');
}
$out_trade_no = generate_order_no('R');
$requirement_order->save([
'user_id' => $request->user->id,
'out_trade_no' => $out_trade_no,
'requirement_detail' => json_encode($requirement->toArray()),
'amount' => $requirement->final_price
]);
$pay_data = [
'out_trade_no' => $out_trade_no,
// 'total_amount' => $requirement_order->amount,
'total_amount' => 0.01,
'desc' => $requirement->requirement_trade_no . '-支付',
'notify_url' => getenv('SERVER_DOMAIN') . self::NOTIFY_URL,//回调地址
'openid' => $request->user->openid,
];
$result = (new PayService())->payment($pay_data);
if (isset($result['code'])) {
throw new Exception($result['msg']);
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $result,
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 需求退款
* @param $request
* @return array|void
*/
public function requirementRefund($request)
{
try {
//查找订单
$order = RequirementOrder::where(['out_trade_no' => $request['out_trade_no']])->findOrEmpty();
if ($order->isEmpty()) {
throw new Exception('未找到订单信息');
}
if ($order->pay_status != 1) {
throw new Exception('订单状态错误,退款失败');
}
if ($order->is_refund) {
throw new Exception('订单已退款');
}
$refund_trade_no = generate_order_no('T');
$order->save([
'refund_trade_no' => $refund_trade_no,
'refund_amount' => $order->amount,
]);
$refund_data = [
'out_trade_no' => $order->out_trade_no,
'out_refund_no' => $refund_trade_no,
'refund_desc' => '正常退款',
'notify_url' => getenv('SERVER_DOMAIN') . self::NOTIFY_REQUIREMENT_REFUND_URL,
'total' => $order->amount,
'refund_amount' => $order->amount,
];
$result = (new PayService())->refundPayment($refund_data);
if(isset($result['code'])){
throw new Exception($result['msg']);
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '已申请退款',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,268 @@
<?php
namespace app\common\service;
use app\common\model\Photographer;
use app\common\model\Requirement;
use app\common\model\RequirementOrder;
use app\common\model\User;
use app\common\validate\RequirementValidate;
use app\constant\ResponseCode;
use think\Exception;
class RequirementService
{
/**
* @desc 发布需求
* @param $request
* @return array
*/
public function publish($request)
{
try {
$data = $request->post();
$validate = new RequirementValidate();
if (!$validate->check($data)) {
throw new Exception($validate->getError());
}
$user = User::where(['id' => $request->user->id])->findOrEmpty();
// if ($user->is_photographer) {
// throw new Exception('只有普通用户可以发布需求哟~');
// }
$requirement = Requirement::create([
'user_id' => $request->user->id,
'user_name' => $data['user_name'],
'sex' => $data['sex'],
'mobile' => $data['mobile'],
'service_address' => $data['service_address'],
'service_time' => $data['service_time'],
'service_type' => $data['service_type'],
'is_need_deposit' => $data['is_need_deposit'],
'price' => $data['price'],
'mark' => $data['mark'],
'status' => 1,//0:初始化 1:竞价中 2:已竞价 3:已完成 4:用户取消'
]);
if (!$requirement) {
throw new Exception('发布失败');
}
$requirement_trade_no = generate_order_no('D');
//生成一条需求订单
$requirement_order = RequirementOrder::create([
'requirement_id' => $requirement->id,
'requirement_trade_no' => $requirement_trade_no,
]);
$requirement->save(['requirement_trade_no' => $requirement_trade_no]);
return [
'code' => ResponseCode::SUCCESS,
'msg' => '发布成功',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 删除需求
* @param $request
* @return array
*/
public function del($request)
{
try {
$data = $request->post();
$requirement = Requirement::where(['id' => $data['id']])->findOrEmpty();
if ($requirement->findOrEmpty()) {
throw new Exception('未找到需求');
}
if ($requirement->user_id != $request->user->id) {
throw new Exception('非需求发布者,不能操作');
}
//@todo:约定某些状态无法删除
if ($requirement->status == 0) {
}
$res = $requirement->delete();
if (!$res) {
throw new Exception('删除失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '操作成功',
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 需求详情
* @param $request
* @return array
*/
public function detail($request)
{
try {
$requirement = Requirement::where(['id' => $request['id']])->with(['serviceType'])->findOrEmpty();
if ($requirement->isEmpty()) {
throw new Exception('需求未找到');
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $requirement,
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 用户自己的需求列表
* @param $request
* @return array
*/
public function getUserSelfRequirementList($request)
{
try {
$data = $request->get();
$requirement = Requirement::order('id desc')->where(['user_id' => $request->user->id]);
if (isset($data['service_type']) && $data['service_type'] != '') {
$requirement->where(['service_type' => $data['service_type']]);
}
if (isset($data['status']) && $data['status']) {
if ($data['status'] == 1) {
$requirement->where(['status' => [1, 2]]);
} else {
$requirement->where(['status' => $data['status']]);
}
}
$page = isset($data['page']) ? $data['page'] : 1;
$limit = isset($data['limit']) ? $data['limit'] : 10;
$total = $requirement->count();
$list = $requirement->page($page, $limit)->with(['serviceType', 'bidWinPhotographer'])->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 获取需求列表
* @param $request
* @return array
*/
public function getRequirement($request)
{
try {
$requirement = Requirement::order('id desc');
if (isset($request['service_type']) && !empty($request['service_type'])) {
$requirement->where(['service_type' => $request['service_type']]);
}
$page = isset($request['page']) ? $request['page'] : 1;
$limit = isset($request['limit']) ? $request['limit'] : 10;
$total = $requirement->count();
$list = $requirement->page($page, $limit)->with('serviceType')->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 竞价中的需求
* @param $request
* @return array
*/
public function getBidRequirements($request)
{
try {
$requestData = $request->get();
$photographer = Photographer::where(['user_id' => $request->user->id])->findOrEmpty();
$service_type = [];
if ($photographer->service_type) {
$service_type = explode(',', $photographer->service_type);
}
$requirement = Requirement::where(['service_type' => $service_type]);
if (isset($requestData['status']) && $requestData['status']) {
if ($requestData['status'] == 1) {
$requirement->where(['status' => [1, 2]]);
} else {
$requirement->where(['status' => $requestData['status']]);
}
}
$page = isset($requestData['page']) ? $requestData['page'] : 1;
$limit = isset($requestData['limit']) ? $requestData['limit'] : 10;
$total = $requirement->count();
$list = $requirement->with('serviceType')->page($page, $limit)->order('id desc')->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
]
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
public function cance()
{
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace app\common\service;
use app\common\model\ServiceStandard;
use app\constant\ResponseCode;
use think\Exception;
class ServiceStandardService
{
/**
* @desc 服务标准
* @param $request
* @return array
*/
public function getStandard($request)
{
try {
$standard = ServiceStandard::order('sort desc, id desc')->field('standard_name')->select();
return [
'code' => ResponseCode::SUCCESS,
'data'=> $standard
];
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace app\common\service;
use app\common\model\ServiceType;
use app\constant\ResponseCode;
use think\Exception;
class ServiceTypeService
{
/**
* @desc 服务类型
* @param $request
* @return array
*/
public function getServiceType($request)
{
try {
$service = ServiceType::order('sort desc,id desc')->field('id,service_name')->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => $service,
];
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace app\common\service;
use app\common\model\Slideshow;
use app\constant\ResponseCode;
use support\Request;
class SlideshowService
{
public function getSlideshow()
{
$res = Slideshow::field('img')->order('sort desc,id desc')->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => $res,
];
}
}

View File

@ -0,0 +1,143 @@
<?php
namespace app\common\service;
use app\common\model\Photographer;
use app\common\model\Studio;
use app\common\model\StudioApply;
use app\common\model\User;
use app\constant\ResponseCode;
use think\Exception;
class StudioApplyService
{
public function apply($request)
{
try {
$data = $request->post();
$user = User::where(['id' => $request->user->id])->findOrEmpty();
if (!$user->is_photographer) {
throw new Exception('你还不是摄影师,请先成为摄影师再申请加入');
}
if ($user->studio_id) {
throw new Exception('您已加入了工作室,不能重复申请');
}
$photographer = Photographer::where(['user_id' => $user->id])->findOrEmpty();
if ($photographer->isEmpty()) {
throw new Exception('未找到您的摄影师信息,申请失败');
}
$studio = Studio::where(['id' => $data['studio_id']])->findOrEmpty();
if ($studio->isEmpty()) {
throw new Exception('未找到工作室信息,申请失败');
}
$studio_apply = StudioApply::where(['user_id' => $user->id, 'photographer_id' => $photographer->id, 'apply_status' => 0])->findOrEmpty();
if (!$studio_apply->isEmpty()) {
throw new Exception('您有申请正在审批,不能重复申请');
}
$res = StudioApply::create([
'user_id' => $user->id,
'photographer_id' => $photographer->id,
'studio_id' => $studio->id
]);
if (!$res) {
throw new Exception('申请失败');
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '申请成功,请等待工作室审核通过'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 申请列表
* @param $request
* @return array
*/
public function getPhotographerApplyList($request)
{
try {
if(!isset($request['studio_id'])){
throw new Exception('参数错误');
}
$apply = StudioApply::order('id desc')->where(['id' => $request['studio_id']]);
$page = isset($request['page']) ? $request['page'] : 1;
$limit = isset($request['limit']) ? $request['limit'] : 10;
$total = $apply->count();
$list = $apply->with(['photographer'])->page($page, $limit)->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page
],
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 更改审核状态
* @param $request
* @return array
*/
public function changeApplyStatus($request)
{
try {
$data = $request->post();
$user = User::where(['id' => $request->user->id])->findOrEmpty();
$apply = StudioApply::where(['id' => $data['id']])->findOrEmpty();
$studio = Studio::where(['id' => $apply->studio_id])->findOrEmpty();
if ($apply->isEmpty()) {
throw new Exception('申请不存在,修改失败');
}
if ($user->id != $studio->user_id) {
throw new Exception('非工作室管理人员禁止操作');
}
$apply->save(['apply_status' => $request['apply_status']]);
if ($request['apply_status'] == 1) {
//通过
$photographer = Photographer::where(['id' => $apply->photographer_id])->findOrEmpty();
$photographer->save(['studio_id' => $apply->studio_id]);
User::where(['id' => $photographer->user_id])->save(['studio_id' => $apply->studio_id]);
} else {
//拒绝
$photographer = Photographer::where(['id' => $apply->photographer_id])->findOrEmpty();
$photographer->save(['studio_id' => 0]);
User::where(['id' => $photographer->user_id])->save(['studio_id' => 0]);
}
return [
'code' => ResponseCode::SUCCESS,
'msg' => '操作成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,198 @@
<?php
namespace app\common\service;
use app\common\model\Photographer;
use app\common\model\ServiceType;
use app\common\model\Studio;
use app\common\model\User;
use app\constant\ResponseCode;
use think\Exception;
class StudioService
{
/**
* @desc 添加工作室
* @param $request
* @return array
*/
public function add($request)
{
try {
$post_data = $request->post();
$user = User::where(['id' => $request->user->id])->findOrEmpty();
if (!$user->is_photographer) {
throw new Exception('您还不是摄影师,请先成为摄影师');
}
$studio = Studio::where(['studio_name' => $post_data['studio_name']])->findOrEmpty();
if (!$studio->isEmpty()) {
throw new Exception('工作室名称已存在,请更换名称');
}
//@todo判断是否一个人只能添加一个工作室
$res = Studio::create([
'studio_name' => $post_data['studio_name'],
'img' => $post_data['img'],
'introductions' => $post_data['introductions'],
'user_id' => $request->user->id
]);
if (!$res) {
throw new Exception('添加失败');
}
User::where(['id' => $request->user->id])->save(['studio_id' => $res->id]);
return [
'code' => ResponseCode::SUCCESS,
'msg' => '添加成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 工作室列表
* @param $request
* @return array
*/
public function select($request)
{
try {
$list = Studio::order('id desc')->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => $list,
'msg' => 'success'
];
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 详情
* @param $request
* @return array
*/
public function detail($request)
{
try {
$data = $request->get();
$studio = Studio::where(['id' => $data['id']])->findOrEmpty();
if ($studio->isEmpty()) {
throw new Exception('工作室不存在');
}
$studio = $studio->toArray();
$studio['is_me'] = 0;
if((array)$request->user){
if($studio['user_id'] == $request->user->id){
$studio['is_me'] = 1;
}
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $studio,
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 工作室摄影师
* @param $request
* @return array
*/
public function getStudioPhotographer($request)
{
try {
$studio = Studio::where(['id' => $request['studio_id']])->findOrEmpty();
if ($studio->isEmpty()) {
throw new Exception('工作室不存在');
}
$photographer = Photographer::where(['p.studio_id' => $studio->id])->alias('p');
$page = isset($request['page']) ? $request['page'] : 1;
$limit = isset($request['limit']) ? $request['limit'] : 10;
$total = $photographer->count();
$list = $photographer->page($page, $limit)->select();
foreach ($list as &$item) {
$service_type_name = '';
if ($item['service_type']) {
$service_type_name = ServiceType::where([
'id' => explode(',', $item['service_type'])
])
->field('service_name')
->order('sort desc, id desc')
->select();
if ($service_type_name) {
$service_type_name = array_column($service_type_name->toArray(), 'service_name');
}
}
$item['service_type_name'] = $service_type_name;
}
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page
],
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 移除摄影师
* @param $request
* @return array
*/
public function removePhotographer($request)
{
try {
$data = $request->post();
$studio = Studio::where(['id' => $data['studio_id']])->findOrEmpty();
$photographer = Photographer::where(['id' => $data['photographer_id']])->findOrEmpty();
if ($studio->user_id != $request->user->id) {
throw new Exception('非工作室管理者不能操作');
}
$photographer->save(['studio_id' => 0]);
User::where(['id' => $photographer->user_id])->save(['studio_id' => 0]);
return [
'code' => ResponseCode::SUCCESS,
'msg' => '操作成功'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace app\common\service;
use app\common\model\Teacher;
use app\common\model\TimeZone;
use app\constant\ResponseCode;
use think\Exception;
use Tinywan\Jwt\JwtToken;
class TeacherService
{
/**
* @desc 登录
* @param $request
* @return array
*/
public function login($request)
{
try {
$teacher = Teacher::where(['account' => $request['account']])->findOrEmpty();
if ($teacher->isEmpty()) {
throw new Exception('账号不存在');
}
if (empty($request['password'])) {
throw new Exception('请填写密码');
}
if (md5($request['password'] . $teacher->salt) != $teacher->password) {
throw new Exception('密码错误,请填写正确的密码');
}
$token_data = [
'id' => $teacher->id,
'role' => 'teacher'
];
$token = JwtToken::generateToken($token_data);
// unset($token['refresh_token']);
return [
'code' => ResponseCode::SUCCESS,
'data' => $token,
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 设置时区
* @param $request
* @return array|void
*/
public function setTimeZone($request)
{
try {
$teacher = Teacher::where(['id' => $request->teacher->id])->findOrEmpty();
$time_zone = TimeZone::where(['id' => $request->post('time_zone_id')])->findOrEmpty();
$teacher->save([
'time_zone_id' => $time_zone->id,
'time_zone_name' => $time_zone->name,
'time_zone_abbr' => $time_zone->abbr,
'time_zone_offset' => $time_zone->offset,
]);
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace app\common\service;
use app\common\model\TimeZone;
use app\constant\ResponseCode;
use think\Exception;
class TimeZoneService
{
public function getTimeZone($request)
{
try {
$time_zone = TimeZone::order('sort desc, id asc')->where(['status'=>1]);
$page = isset($request['page']) ? $request['page'] : 1;
$limit = isset($request['limit']) ? $request['limit'] : 10;
$total = $time_zone->count();
$list = $time_zone->page($page, $limit)->field('id,name,abbr,text,offset')->select();
return [
'code' => ResponseCode::SUCCESS,
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
],
'msg' => 'success'
];
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace app\common\service;
use app\constant\ResponseCode;
use app\utils\QiniuUtils;
use think\Exception;
class UploadService
{
public function uploadImg($file)
{
ini_set('memory_limit', '256M');
try {
if ($file && $file->isValid()) {
$ext = $file->getUploadExtension();
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'JPG', 'JPEG', 'PBG'])) {
$type = 'images';
} else {
$type = 'other';
}
$fileSize = $file->getSize();
$uploadDir = '/files/' . $type . '/' . date('Ym') . '/';
$filename = date('YmdHis') . rand(999, 99999);
$uploadPath = $uploadDir . $filename . '.' . $ext;
$rootUploadDir = public_path() . $uploadDir;
if (!is_dir($rootUploadDir)) {
mkdir($rootUploadDir, 0777, true);
}
$filePath = public_path() . $uploadPath;
$file->move($filePath);
//上传到七牛云
$res = QiniuUtils::upload($filePath);
if($res['code'] == ResponseCode::FAIL){
throw new Exception($res['msg']);
}
//删除本地图片
unlink($filePath);
return [
'code' => ResponseCode::SUCCESS,
'msg' => '上传成功',
'data' => $res['data']
];
}else{
throw new Exception('文件无效');
}
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

View File

@ -0,0 +1,129 @@
<?php
namespace app\common\service;
use app\common\model\Photographer;
use app\common\model\User;
use app\constant\ResponseCode;
use think\Exception;
use Tinywan\Jwt\JwtToken;
use Webman\Config;
class UserService
{
/**
* @desc 登录
* @param $request
* @return array
*/
public function login($request)
{
try {
if (!isset($request['code']) || empty($request['code'])) {
throw new Exception('参数code错误');
}
if (!isset($request['avatar']) || empty($request['avatar'])) {
throw new Exception('参数avatar错误');
}
if (!isset($request['nickname']) || empty($request['nickname'])) {
throw new Exception('参数code错误');
}
$openid = self::getUserOpenId($request['code']);
if (!$openid) {
throw new Exception('获取openid失败');
}
$user = User::where(['openid' => $openid])->findOrEmpty();
if ($user->isEmpty()) {
$user = User::create([
'nickname' => $request['nickname'],
'openid' => $openid,
'avatar' => $request['avatar'],
]);
}
$token_data = [
'id' => $user->id
];
$token = JwtToken::generateToken($token_data);
unset($token['refresh_token']);
return [
'code' => ResponseCode::SUCCESS,
'data' => $token,
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
public function select($request)
{
try {
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* @desc 用户信息
* @param $request
* @return array
*/
public function userInfo($request)
{
try {
$user = User::where(['id' => $request->user->id])->with(['studio', 'photographer'])->field('id,nickname,openid,avatar,is_photographer,studio_id')->findOrEmpty();
if ($user->isEmpty()) {
throw new Exception('未找到用户');
}
return [
'code' => ResponseCode::SUCCESS,
'data' => $user,
'msg' => 'success'
];
} catch (Exception $e) {
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
/**
* 获取openid
* @param $code
* @return false|mixed
*/
public static function getUserOpenId($code)
{
$appid = getenv('APP_ID');//小程序的appid
$appSecret = getenv('APP_SECRET');// 小程序的$appSecret
$wxUrl = 'https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code';
$getUrl = sprintf($wxUrl, $appid, $appSecret, $code);//把appidappsecretcode拼接到url里
$result = curl_get($getUrl);//请求拼接好的url
raw_log('wechat/get_openid', ['get_url' => $getUrl, 'result' => $result]);
$wxResult = json_decode($result, true);
if (!$wxResult) {
return false;
}
if (array_key_exists('errcode', $wxResult)) {
return false;
}
return $wxResult['openid'];
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace app\common\validate;
use think\Validate;
class CaseShareValidate extends Validate
{
protected $rule = [
'service_type' => 'require',
'case_name' => 'require',
// 'case_briefing' => 'require',
'case_introduce' => 'require',
// 'imgs' => 'require',
];
protected $message = [
'service_type' => '请选择服务项目',
'case_name' => '请填写案例名称',
// 'case_briefing' => '请填写案例简介',
'case_introduce' => '请填写案例介绍',
'imgs' => '请上传案例图片',
];
}

View File

@ -0,0 +1,37 @@
<?php
namespace app\common\validate;
use think\Validate;
class PhotoServiceOrderValidate extends Validate
{
protected $rule = [
'user_name' => 'require',
'sex' => 'require',
'user_mobile' => 'require',
'service_address' => 'require|mobile',
'service_time' => 'require',
'service_type' => 'require',
'photo_service_ids' => 'require',
// 'paid_service_detail' => 'require',
'is_need_deposit' => 'require',
'total' => 'require',
'remake' => 'require',
];
protected $message = [
'user_name' => '请填写姓名',
'sex' => '请选择性别',
'user_mobile' => '请填写手机号',
'service_address' => '请填写服务地点',
'service_time' => '请选择服务时间',
'service_type' => '请选择服务类型',
'photo_service_detail' => 'require',
'paid_service_detail' => 'require',
'is_need_deposit' => 'require',
'total' => 'require',
'remake' => 'require',
];
}

View File

@ -0,0 +1,31 @@
<?php
namespace app\common\validate;
use think\Validate;
class PhotoServiceValidate extends Validate
{
protected $rule = [
'service_type' => 'require',
'service_standard' => 'require',
'detail' => 'require',
'price' => 'checkPrice',
];
protected $message = [
'service_type' => '请选择服务类别',
'service_standard' => '请选择服务标准',
'detail' => '请填写服务内容',
'price' => '请填写服务价格',
];
public function checkPrice($value, $rule, $data = [], $field = '')
{
if (empty($value) || !is_numeric($value) || $value < 0) {
return '请填写正确服务价格';
}
return true;
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace app\common\validate;
use think\Validate;
class PhotographerValidate extends Validate
{
protected $rule = [
'name' => 'require',
'sex' => 'require',
'mobile' => 'require|mobile',
'device_id' => 'require',
'service_type' => 'require',
'age' => 'require',
// 'province_code' => 'require',
'province_name' => 'require',
// 'city_code' => 'require',
'city_name' => 'require',
'work_time' => 'require',
'work_year' => 'require',
'introduce' => 'require',
];
protected $message = [
'name' => '请填写姓名',
'sex' => '请选择性别',
'mobile' => '请填写正确的手机号',
'device_id' => '请选择设备',
'service_type' => '请选择服务类型',
'age' => '请填写年龄',
// 'province_code' => '请选择省份',
'province_name' => '请选择省份',
// 'city_code' => '请选择城市',
'city_name' => '请选择城市',
'work_time' => '请选择工作时间',
'work_year' => '请选择工作年限',
'introduce' => '请填写个人简介',
];
}

View File

@ -0,0 +1,32 @@
<?php
namespace app\common\validate;
use think\Validate;
class RequirementValidate extends Validate
{
protected $rule = [
'user_name' => 'require',
'sex' => 'require',
'mobile' => 'require|mobile',
'service_address' => 'require',
'service_type' => 'require',
'service_time' => 'require',
'is_need_deposit' => 'require',
'price' => 'require',
// 'mark' => 'require',
];
protected $message = [
'user_name' => '请填写姓名',
'sex' => '请选择性别',
'mobile' => '请填写正确的手机号',
'service_address' => '请填写服务地址',
'service_type' => '请选择服务类型',
'service_time' => '请选择服务时间',
'is_need_deposit' => '请选择是否需要缴纳保证金',
'price' => '请填写价格',
// 'mark' => '',
];
}

View File

@ -0,0 +1,17 @@
<?php
namespace app\constant;
class ResponseCode
{
const SUCCESS = 2000; // 接口处理成功
const FAIL = 3005; // 接口处理失败
const NEED_LOGIN = 4001;//需要登录
const WEB_API_SUCCESS = 0;//后台api接口
const WEB_API_FAIL = 1;//后台api接口
}

View File

@ -0,0 +1,28 @@
<?php
namespace app\controller;
use support\Request;
class IndexController
{
public function index(Request $request)
{
static $readme;
if (!$readme) {
$readme = file_get_contents(base_path('README.md'));
}
return $readme;
}
public function view(Request $request)
{
return view('index/view', ['name' => 'webman']);
}
public function json(Request $request)
{
return json(['code' => 0, 'msg' => 'ok']);
}
}

62
app/functions.php Normal file
View File

@ -0,0 +1,62 @@
<?php
/**
* Here is your custom functions.
*/
if (!function_exists('generate_order_no')) {
/**
* 生成 前缀+24位数字的订单号
* @param string $prefix 前缀
* @return string
*/
function generate_order_no($prefix = '')
{
$randLen = 6;
$id = base_convert(substr(uniqid(), 0 - $randLen), 16, 10);
if (strlen($id) > 10) {
$id = substr($id, -10);
} elseif (strlen($id) < 10) {
$rLen = 10 - strlen($id);
$id = $id . rand(pow(10, $rLen - 1), pow(10, $rLen) - 1);
}
$dateTimeStr = date('YmdHis');
return $prefix . $dateTimeStr . $id;
}
}
/**
* 记录日志,默认存放路径为:{$config_path}/logs/{$dir_name}/ddddmm/d.log
* @dir_name logs/下的目录路径
* @data 日志数据
*/
if (!function_exists('raw_log')) {
function raw_log(string $dir_name, $data)
{
$log_path = runtime_path() . "/logs/{$dir_name}/" . date('Ym');
if (!is_dir($log_path)) {
mkdir($log_path, 0777, true);
}
$log_path .= '/' . date('d') . '.log';
$log = new Monolog\Logger($dir_name);
$log->pushHandler(new \Monolog\Handler\StreamHandler($log_path, \Monolog\Logger::INFO));
$log->info('', $data);
}
}
/**
* @desc 生成随机字符串
* @param $len
* @return string
* @throws \Random\RandomException
*/
if (!function_exists('random_str')) {
function random_str($len = 32)
{
return bin2hex(random_bytes(round($len / 2)));
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace app\middleware;
use app\common\model\AdminUserModel;
use app\common\model\MchTerminalModel;
use app\common\model\Teacher;
use app\constant\ResponseCode;
use ReflectionClass;
use think\Exception;
use think\model\Collection;
use Tinywan\Jwt\Exception\JwtCacheTokenException;
use Tinywan\Jwt\Exception\JwtTokenException;
use Tinywan\Jwt\Exception\JwtTokenExpiredException;
use Tinywan\Jwt\JwtToken;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
class ApiAuthCheckMiddleware implements MiddlewareInterface
{
public function process(Request $request, callable $handler): Response
{
$request->user = new \stdClass();
$request->teacher = new \stdClass();
$request->partents = new \stdClass();
// 通过反射获取控制器哪些方法不需要登录和鉴权
$controller = new ReflectionClass($request->controller);
$noNeedLogin = $controller->getDefaultProperties()['noNeedLogin'] ?? [];
// $res = JwtToken::getExtend();
$is_need_login = 0;
$msg = '';
try {
$extend = JwtToken::getExtend();
if ($extend['role'] == 'student') {
} elseif ($extend['role'] == 'teacher') {
$request->teacher = \support\Db::table('teacher')
->where('id', $extend['id'])
->select('id','account','teacher_name','openid','time_zone_name','time_zone_abbr','time_zone_offset')
->first();
} elseif ($extend['role'] == 'parents') {
}
// $request->user = JwtToken::getUser();
} catch (JwtTokenExpiredException $e) {
$is_need_login = 1;
$msg = $e->getMessage();
} catch (JwtTokenException $e) {
$is_need_login = 1;
$msg = $e->getMessage();
} catch (JwtCacheTokenException $e) {
$is_need_login = 1;
$msg = $e->getMessage();
}
// 访问的方法需要登录
if (!in_array($request->action, $noNeedLogin) && !in_array('*', $noNeedLogin) && $is_need_login) {
return json([
'code' => ResponseCode::NEED_LOGIN,
'msg' => $msg,
]);
}
return $handler($request);
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
/**
* Class StaticFile
* @package app\middleware
*/
class StaticFile implements MiddlewareInterface
{
public function process(Request $request, callable $next): Response
{
// Access to files beginning with. Is prohibited
if (strpos($request->path(), '/.') !== false) {
return response('<h1>403 forbidden</h1>', 403);
}
/** @var Response $response */
$response = $next($request);
// Add cross domain HTTP header
/*$response->withHeaders([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Credentials' => 'true',
]);*/
return $response;
}
}

29
app/model/Test.php Normal file
View File

@ -0,0 +1,29 @@
<?php
namespace app\model;
use support\Model;
class Test extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'test';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}

View File

@ -0,0 +1,345 @@
<?php
namespace app\notify\controller;
use app\common\model\Requirement;
use app\common\model\RequirementOrder;
use app\common\service\Channel\wechat\WechatConstants;
use support\Request;
use think\Exception;
use WeChatPay\Crypto\AesGcm;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
class WechatPayNotifyController
{
/**
* @desc 需求订单支付回调
* @param Request $request
* @return void
*/
public function requirement_notify(Request $request)
{
try {
$post_data = $request->post();
$header = $request->header();
raw_log('wechat_pay/requirement_notify', ['post' => $post_data, 'header' => $header]);
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
$mch_id = getenv('MERCHANT_ID');
// 根据通知的平台证书序列号,查询本地平台证书文件,
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 检查通知时间偏移量允许5分钟之内的偏移
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
$verifiedStatus = Rsa::verify(
// 构造验签名串
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
$inWechatpaySignature,
$platformPublicKeyInstance
);
// 验签
if ($timeOffsetStatus && $verifiedStatus) {
// 使用PHP7的数据解构语法从Array中解构并赋值变量
['resource' => [
'ciphertext' => $ciphertext,
'nonce' => $nonce,
'associated_data' => $aad
]] = $post_data;
// 加密文本消息解密
$inBodyResource = AesGcm::decrypt($ciphertext, getenv('API_V3'), $nonce, $aad);
// 把解密后的文本转换为PHP Array数组
$pay_result = json_decode($inBodyResource, true);
if ($pay_result['trade_state'] == 'SUCCESS') {
$order = RequirementOrder::where(['out_trade_no' => $pay_result['out_trade_no']])->findOrEmpty();
if ($order->isEmpty()) {
throw new Exception('未找到订单' . $pay_result['out_trade_no']);
}
if ($order->amount * 100 != $pay_result['amount']['total']) {
throw new Exception('订单金额不一致-' . $pay_result['out_trade_no']);
}
if ($order->pay_status == 0) {
$res = $order->save([
'pay_status' => 1,
'transaction_id' => $pay_result['transaction_id'],
'pay_time' => date('Y-m-d H:i:s', strtotime($pay_result['success_time'])),
]);
$requirement = Requirement::where(['id' => $order->requirement_id])->findOrEmpty();
$requirement->save([
'requirement_pay_order_status' => 1
]);
if ($requirement->deposit_pay_status == 1) {
//保证金已支付,进入服务中状态
$requirement->save([
'status' => 3
]);
}
if ($res) {
return json('success');
}
}
return json('success');
}
} else {
throw new Exception('验签失败');
}
} catch (Exception $e) {
var_dump($e->getMessage());
raw_log('wechat_pay/requirement_notify_error', ['exception' => $e->getMessage()]);
}
}
/**
* @desc 需求退款
* @param Request $request
* @return \support\Response|void
*/
public function requirement_refund_notify(Request $request)
{
try {
$post_data = $request->post();
$header = $request->header();
$post_data = '{"id":"ce358553-a4ae-5ecd-bab0-c4a31292989d","create_time":"2024-07-04T17:40:35+08:00","resource_type":"encrypt-resource","event_type":"REFUND.SUCCESS","summary":"退款成功","resource":{"original_type":"refund","algorithm":"AEAD_AES_256_GCM","ciphertext":"uc/STAVhRAgsEn+Wcl7ZDq4JiXh5KxLyX3c6WKtnZPLKq/ch1JGFKMR2Fbdvk5W5p5qcd2NJLwaUEmPjopV3n5aAD/r7DGsn+wUhiUwk71YIRhSZyrIrOTNXFLZ/yIu5cr7qkBnEP1YCD/oeSmNy6cz2uq8kag90M6RtOgJO4KFsJ0tOqW/OWs3h4eBoWxyRzKVZHY/FyNSeOgKN8ZodkRlP0Tjm2oPqtaxJcvE3O8TG5jkKlCopk/q8pd/lYUP8k0W1R+LYc2njh6NMc+plmH/6qrI7Ep5AzuU89PhDoQY8WemqogyABqtnXQ+8yMIWkmQSHHB3I1WKegqGFNSXHoUyViONoy7FKdWmstpUfAtjPjXJl23g3WYkjeaKO4bPKZakKj2KUscPQUs8dOa0eggA0mxqLMHgZl9+UKqoC4e/7a+CdR3DMKlJjYFC/Zisfjxy++1gPC4Oh5BIP7QVT3atsgNkZynXAY+3qmF9/lyeWONzrPXdukanEZMwLi2UXIELHEQvPUv7aKgI","associated_data":"refund","nonce":"xaAOLXTSOskU"}}';
$header = '{"x-real-ip":"175.24.211.24","host":"sypt.lingruikj.com","x-forwarded-proto":"https","content-length":"840","user-agent":"Mozilla/4.0","content-type":"application/json","wechatpay-nonce":"gSSvoVuO1PPtuPtdFvvugy99YI1leUMF","wechatpay-timestamp":"1720086041","wechatpay-serial":"660FAD2D6E804E37BE9D77EF5882718CC1E3399F","wechatpay-signature":"Vatqwnzb0cYGMT1nOnpp086CUV8URBgWVeqPJW1tw/tt/w1htnnTs1lk0v+Z/i3cqpnkfr1XErzMQZ1yZXA7qH7nloRdjBYWLwJiwTrnrLDMLU//Oz1sUve4Mt910zIPGkMTbg2Zr+b6YXqPNVBYvFtjjRnBlqRpyVz07lsVDKA4Ygfslw+sZur4qC/yZy6d3fKwxIRy6S/GHBd+/kRnuagyjheuU+JZ32ScozXdt6AQF05S3VGzohiNvrIu48v9imlf3K6NdzGnSJPeiKQ9BSoOw0CkSl9idEYIIFfdbhbu9kc5l4V8bNQc45W8EUylXLT7cFa6B63+TZts5KOosw==","wechatpay-signature-type":"WECHATPAY2-SHA256-RSA2048","pragma":"no-cache","accept":"*/*"}';
$post_data = json_decode($post_data, true);
$header = json_decode($header, true);
raw_log('wechat_pay/requirement_refund_notify', ['post' => $post_data, 'header' => $header]);
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
$mch_id = getenv('MERCHANT_ID');
// 根据通知的平台证书序列号,查询本地平台证书文件,
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 检查通知时间偏移量允许5分钟之内的偏移
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
$verifiedStatus = Rsa::verify(
// 构造验签名串
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
$inWechatpaySignature,
$platformPublicKeyInstance
);
// 验签
if ($timeOffsetStatus && $verifiedStatus) {
// 使用PHP7的数据解构语法从Array中解构并赋值变量
['resource' => [
'ciphertext' => $ciphertext,
'nonce' => $nonce,
'associated_data' => $aad
]] = $post_data;
// 加密文本消息解密
$inBodyResource = AesGcm::decrypt($ciphertext, getenv('API_V3'), $nonce, $aad);
// 把解密后的文本转换为PHP Array数组
$pay_result = json_decode($inBodyResource, true);
if ($pay_result['refund_status'] == 'SUCCESS') {
$order = RequirementOrder::where(['out_trade_no' => $pay_result['out_trade_no']])->findOrEmpty();
if ($order->isEmpty()) {
throw new Exception('未找到订单' . $pay_result['out_trade_no']);
}
if ($order->pay_status != 1) {
throw new Exception('订单状态错误-' . $order->pay_status . $pay_result['out_trade_no']);
}
if ($order->is_refund != 0) {
throw new Exception('订单退款状态错误-' . $order->is_refund . $pay_result['out_trade_no']);
}
if ($order->refund_amount * 100 != $pay_result['amount']['total']) {
throw new Exception('退款金额不一致-' . $pay_result['out_trade_no']);
}
$order->save([
'refund_transaction_id' => $pay_result['refund_id'],
'is_refund' => 1,
'refund_time' => date('Y-m-d H:i:s', strtotime($pay_result['success_time'])),
]);
$requirement = Requirement::where(['id' => $order->requirement_id])->findOrEmpty();
if (!$requirement->isEmpty()) {
$requirement->save([
'requirement_pay_order_status' => 3
]);
if ($order->deposit_pay_status == 3) {
//保证金已退款,更新需求状态为已退款
$requirement->save([
'status' => 5
]);
}
}
return json('success');
}
} else {
throw new Exception('验签失败');
}
} catch (Exception $e) {
var_dump($e->getMessage());
raw_log('wechat_pay/requirement_refund_notify_error', ['exception' => $e->getMessage()]);
}
}
/**
* @desc 保证金订单回调
* @param Request $request
* @return void
*/
public function requirement_deposit_notify(Request $request)
{
try {
$post_data = $request->post();
$header = $request->header();
raw_log('wechat_pay/requirement_notify', ['post' => $post_data, 'header' => $header]);
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
$mch_id = getenv('MERCHANT_ID');
// 根据通知的平台证书序列号,查询本地平台证书文件,
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 检查通知时间偏移量允许5分钟之内的偏移
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
$verifiedStatus = Rsa::verify(
// 构造验签名串
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
$inWechatpaySignature,
$platformPublicKeyInstance
);
// 验签
if ($timeOffsetStatus && $verifiedStatus) {
}
} catch (Exception $e) {
}
}
/**
* @desc 拍照服务支付回调
* @param Request $request
* @return void
*/
public function photo_notify(Request $request)
{
try {
$post_data = $request->post();
$header = $request->header();
raw_log('wechat_pay/photo_notify', ['post' => $post_data, 'header' => $header]);
} catch (Exception $e) {
}
}
/**
* @desc 支付保证金回调
* @param Request $request
* @return void
*/
public function photo_deposit_notify(Request $request)
{
try {
$post_data = $request->post();
$header = $request->header();
raw_log('wechat_pay/photo_deposit_notify', ['post' => $post_data, 'header' => $header]);
//@todo:支付成功更新拍照服务中保证金状态
} catch (Exception $e) {
}
}
/**
* @desc 拍照退款
* @param Request $request
* @return void
*/
public function photo_refund_notify(Request $request)
{
try {
$post_data = $request->post();
$header = $request->header();
raw_log('wechat_pay/refund_notify', ['post' => $post_data, 'header' => $header]);
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
$mch_id = getenv('MERCHANT_ID');
// 根据通知的平台证书序列号,查询本地平台证书文件,
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 检查通知时间偏移量允许5分钟之内的偏移
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
$verifiedStatus = Rsa::verify(
// 构造验签名串
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
$inWechatpaySignature,
$platformPublicKeyInstance
);
// 验签
if ($timeOffsetStatus && $verifiedStatus) {
}
} catch (Exception $e) {
}
}
/**
* @desc 拍照订单保证金退款回调
* @param Request $request
* @return void
*/
public function photo_deposit_refund_notify(Request $request)
{
try {
}catch (Exception $e){
}
}
}

66
app/utils/QiniuUtils.php Normal file
View File

@ -0,0 +1,66 @@
<?php
namespace app\utils;
use app\constant\ResponseCode;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use think\Exception;
class QiniuUtils
{
/**
* @desc 上传到七牛云
* @param $filePath
* @return array
* @throws \Exception
*/
public static function upload($filePath = '')
{
try {
if(!file_exists($filePath)){
throw new Exception('文件不存在');
}
// 需要填写你的 Access Key 和 Secret Key
$accessKey = getenv('QI_NIU_ACCESS_KEY');
$secretKey = getenv('QI_NIU_SECRET_KEY');
$bucket = getenv('QI_NIU_BUCKET');
// 构建鉴权对象
$auth = new Auth($accessKey, $secretKey);
// 生成上传 Token
$token = $auth->uploadToken($bucket);
// 上传到存储后保存的文件名
$filename = pathinfo($filePath, PATHINFO_FILENAME);
$key = getenv('APP_NAME') .'/' . date('Ymd') . '/' . $filename . '.' . pathinfo($filePath, PATHINFO_EXTENSION);
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
// 调用 UploadManager 的 putFile 方法进行文件的上传。
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath, null, 'application/octet-stream', true, null, 'v2');
if ($err !== null) {
throw new Exception($err->getResponse()->error);
}
$qiniu_url = getenv('QI_NIU_URL') . '/' . $ret['key'];
return [
'code' => ResponseCode::SUCCESS,
'data' => $qiniu_url,
];
}catch (Exception $e){
return [
'code' => ResponseCode::FAIL,
'msg' => $e->getMessage()
];
}
}
}

68
composer.json Normal file
View File

@ -0,0 +1,68 @@
{
"name": "workerman/webman",
"type": "project",
"keywords": [
"high performance",
"http service"
],
"homepage": "https://www.workerman.net",
"license": "MIT",
"description": "High performance HTTP Service Framework.",
"authors": [
{
"name": "walkor",
"email": "walkor@workerman.net",
"homepage": "https://www.workerman.net",
"role": "Developer"
}
],
"support": {
"email": "walkor@workerman.net",
"issues": "https://github.com/walkor/webman/issues",
"forum": "https://wenda.workerman.net/",
"wiki": "https://workerman.net/doc/webman",
"source": "https://github.com/walkor/webman"
},
"require": {
"php": ">=7.2",
"workerman/webman-framework": "^1.5.0",
"monolog/monolog": "^2.0",
"webman/think-cache": "^1.0",
"vlucas/phpdotenv": "^5.6",
"webman/console": "^1.3",
"wechatpay/wechatpay": "^1.4",
"webman/event": "^1.0",
"topthink/think-validate": "^2.0",
"workerman/crontab": "^1.0",
"webman/admin": "^0.6.28",
"illuminate/database": "^8.83",
"qiniu/php-sdk": "^7.12",
"tinywan/jwt": "^1.10",
"webman/think-orm": "^1.1"
},
"suggest": {
"ext-event": "For better performance. "
},
"autoload": {
"psr-4": {
"": "./",
"app\\": "./app",
"App\\": "./app",
"app\\View\\Components\\": "./app/view/components"
},
"files": [
"./support/helpers.php"
]
},
"scripts": {
"post-package-install": [
"support\\Plugin::install"
],
"post-package-update": [
"support\\Plugin::install"
],
"pre-package-uninstall": [
"support\\Plugin::uninstall"
]
}
}

4227
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

26
config/app.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use support\Request;
return [
'debug' => true,
'error_reporting' => E_ALL,
'default_timezone' => 'Asia/Shanghai',
'request_class' => Request::class,
'public_path' => base_path() . DIRECTORY_SEPARATOR . 'public',
'runtime_path' => base_path(false) . DIRECTORY_SEPARATOR . 'runtime',
'controller_suffix' => 'Controller',
'controller_reuse' => false,
];

21
config/autoload.php Normal file
View File

@ -0,0 +1,21 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'files' => [
base_path() . '/app/functions.php',
base_path() . '/support/Request.php',
base_path() . '/support/Response.php',
]
];

20
config/bootstrap.php Normal file
View File

@ -0,0 +1,20 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
support\bootstrap\Session::class,
support\bootstrap\LaravelDb::class,
Webman\ThinkCache\ThinkCache::class,
Webman\ThinkOrm\ThinkOrm::class,
];

15
config/container.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return new Webman\Container;

36
config/database.php Normal file
View File

@ -0,0 +1,36 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
// 默认数据库
'default' => 'mysql',
// 各种数据库配置
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => getenv('DB_HOST'),
'port' => getenv('DB_PORT'),
'database' => getenv('DB_NAME'),
'username' => getenv('DB_USER'),
'password' => getenv('DB_PASSWORD'),
'unix_socket' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'prefix' => 'wa_',
'strict' => true,
'engine' => null,
],
],
];

15
config/dependence.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [];

5
config/event.php Normal file
View File

@ -0,0 +1,5 @@
<?php
return [
];

17
config/exception.php Normal file
View File

@ -0,0 +1,17 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'' => support\exception\Handler::class,
];

32
config/log.php Normal file
View File

@ -0,0 +1,32 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
return [
'default' => [
'handlers' => [
[
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
runtime_path() . '/logs/webman.log',
7, //$maxFiles
Monolog\Logger::DEBUG,
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [null, 'Y-m-d H:i:s', true],
],
]
],
],
];

Some files were not shown because too many files have changed in this diff Show More