ApiBaseController.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?php
  2. /**
  3. * ApiBaseController.php UTF-8
  4. * api基类
  5. *
  6. * @date : 2017/11/15 16:44
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HUOSDK 8.0
  11. */
  12. namespace api\common\controller;
  13. use think\Db;
  14. use think\exception\HttpResponseException;
  15. use think\exception\HuoException;
  16. use think\exception\ValidateException;
  17. use think\Lang;
  18. use think\Loader;
  19. use think\Request;
  20. use think\Response;
  21. class ApiBaseController {
  22. //token
  23. protected $token = '';
  24. //设备类型
  25. protected $device_type = '';
  26. //用户 id
  27. protected $mem_id = 0;
  28. // 语言
  29. protected $lang = 'en';
  30. //用户
  31. protected $user;
  32. /* 返回类型 */
  33. protected $response_type = 'json';
  34. //用户类型
  35. protected $user_type;
  36. protected $allowed_device_types = ['mobile', 'android', 'iphone', 'ipad', 'web', 'pc', 'mac', 'wxapp'];
  37. /**
  38. * @var \think\Request Request实例
  39. */
  40. protected $request;
  41. // 验证失败是否抛出异常
  42. protected $fail_exception = false;
  43. // 是否批量验证
  44. protected $batch_validate = false;
  45. /**
  46. * 前置操作方法列表
  47. *
  48. * @var array $before_action_list
  49. * @access protected
  50. */
  51. protected $before_action_list = [];
  52. /**
  53. * 架构函数
  54. *
  55. * @param Request $request Request对象
  56. *
  57. * @access public
  58. */
  59. public function __construct(Request $request = null) {
  60. if (is_null($request)) {
  61. $request = Request::instance();
  62. }
  63. // Request::instance()->root(cmf_get_root() . '/');
  64. Lang::setAllowLangList(['en', 'ar']);
  65. $this->request = $request;
  66. // $this->response_type = Config::get('default_return_type');
  67. $this->_initLang();
  68. // 用户验证初始化
  69. $this->_initUser();
  70. // 控制器初始化
  71. $this->_initialize();
  72. // 前置操作方法
  73. if ($this->before_action_list) {
  74. foreach ($this->before_action_list as $method => $options) {
  75. if (is_numeric($method)) {
  76. $this->beforeAction($options);
  77. } else {
  78. $this->beforeAction($method, $options);
  79. }
  80. }
  81. }
  82. }
  83. // 初始化
  84. protected function _initialize() {
  85. }
  86. private function _initLang() {
  87. $_lang = $this->request->header('HS-Lang/s', 'en-us');
  88. $this->lang = $_lang;
  89. config('default_lang', $this->lang);
  90. }
  91. private function _initUser() {
  92. $_token = $this->request->header('HS-Token/s', '');
  93. $_device_type = $this->request->header('HS-Device-Type/s', '');
  94. if (empty($_token)) {
  95. return;
  96. }
  97. if (empty($_device_type)) {
  98. return;
  99. }
  100. if (!in_array($_device_type, $this->allowed_device_types)) {
  101. return;
  102. }
  103. $this->token = $_token;
  104. $this->device_type = $_device_type;
  105. $_mem_id = $this->getMemIdByToken($_token, $_device_type);
  106. if (!empty($_mem_id)) {
  107. $this->mem_id = $_mem_id;
  108. }
  109. }
  110. /**
  111. * @param $token
  112. * @param $device_type
  113. *
  114. * @return array|bool|false|\PDOStatement|string|\think\Model
  115. */
  116. public function getMemIdByToken($token, $device_type) {
  117. if (empty($token) || empty($device_type)) {
  118. return 0;
  119. }
  120. $_mem_id = Db::name('mem_token')
  121. ->where(['token' => $this->token, 'device_type' => $this->device_type])
  122. ->value('mem_id');
  123. if (empty($_mem_id)) {
  124. return 0;
  125. }
  126. return $_mem_id;
  127. }
  128. /**
  129. * 前置操作
  130. *
  131. * @access protected
  132. *
  133. * @param string $method 前置操作方法名
  134. * @param array $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]
  135. */
  136. protected function beforeAction($method, $options = []) {
  137. if (isset($options['only'])) {
  138. if (is_string($options['only'])) {
  139. $options['only'] = explode(',', $options['only']);
  140. }
  141. if (!in_array($this->request->action(), $options['only'])) {
  142. return;
  143. }
  144. } elseif (isset($options['except'])) {
  145. if (is_string($options['except'])) {
  146. $options['except'] = explode(',', $options['except']);
  147. }
  148. if (in_array($this->request->action(), $options['except'])) {
  149. return;
  150. }
  151. }
  152. call_user_func([$this, $method]);
  153. }
  154. /**
  155. * 设置验证失败后是否抛出异常
  156. *
  157. * @access protected
  158. *
  159. * @param bool $fail 是否抛出异常
  160. *
  161. * @return $this
  162. */
  163. protected function validateFailException($fail = true) {
  164. $this->fail_exception = $fail;
  165. return $this;
  166. }
  167. /**
  168. * 验证数据
  169. *
  170. * @access protected
  171. *
  172. * @param array $data 数据
  173. * @param string|array $validate 验证器名或者验证规则数组
  174. * @param array $message 提示信息
  175. * @param bool $batch 是否批量验证
  176. * @param mixed $callback 回调方法(闭包)
  177. *
  178. * @return array|string|true
  179. * @throws ValidateException
  180. */
  181. protected function validate($data, $validate, $message = [], $batch = false, $callback = null) {
  182. if (is_array($validate)) {
  183. $_valid_class = Loader::validate();
  184. $_valid_class->rule($validate);
  185. } else {
  186. if (strpos($validate, '.')) {
  187. // 支持场景
  188. list($validate, $scene) = explode('.', $validate);
  189. }
  190. $_valid_class = Loader::validate($validate);
  191. if (!empty($scene)) {
  192. $_valid_class->scene($scene);
  193. }
  194. }
  195. // 是否批量验证
  196. if ($batch || $this->batch_validate) {
  197. $_valid_class->batch(true);
  198. }
  199. if (is_array($message)) {
  200. $_valid_class->message($message);
  201. }
  202. if ($callback && is_callable($callback)) {
  203. call_user_func_array($callback, [$_valid_class, &$data]);
  204. }
  205. if (!$_valid_class->check($data)) {
  206. if ($this->fail_exception) {
  207. throw new ValidateException($_valid_class->getError());
  208. } else {
  209. return $_valid_class->getError();
  210. }
  211. } else {
  212. return true;
  213. }
  214. }
  215. /**
  216. * 操作成功跳转的快捷方法
  217. *
  218. * @access protected
  219. *
  220. * @param mixed $msg 提示信息
  221. * @param mixed $data 返回的数据
  222. * @param array $header 发送的Header信息
  223. *
  224. * @param int $code 返回码
  225. *
  226. * @return void
  227. */
  228. protected function success($msg = '', $data = '', $code = 200, array $header = []) {
  229. if (empty($data)) {
  230. $data = null;
  231. }
  232. $result = [
  233. 'code' => $code,
  234. 'msg' => $msg,
  235. 'data' => $data,
  236. ];
  237. $type = $this->getResponseType();
  238. $header['Access-Control-Allow-Origin'] = '*';
  239. $header['Access-Control-Allow-Headers'] = 'X-Requested-With,Content-Type,HS-Device-Type,HS-Token,HS-Lang';
  240. $header['Access-Control-Allow-Methods'] = 'GET,POST,PATCH,PUT,DELETE,OPTIONS';
  241. $response = Response::create($result, $type)->header($header);
  242. throw new HttpResponseException($response);
  243. }
  244. /**
  245. * 操作错误跳转的快捷方法
  246. *
  247. * @access protected
  248. *
  249. * @param mixed $msg 提示信息,若要指定错误码,可以传数组,格式为['code'=>您的错误码,'msg'=>'您的错误消息']
  250. * @param mixed $data 返回的数据
  251. * @param array $header 发送的Header信息
  252. *
  253. * @param int $code
  254. *
  255. * @return void
  256. */
  257. protected function error($msg = '', $data = '', $code = 400, array $header = []) {
  258. if (empty($data)) {
  259. $data = null;
  260. }
  261. $result = [
  262. 'code' => $code,
  263. 'msg' => $msg,
  264. 'data' => $data,
  265. ];
  266. $type = $this->getResponseType();
  267. $header['Access-Control-Allow-Origin'] = '*';
  268. $header['Access-Control-Allow-Headers'] = 'X-Requested-With,Content-Type,HS-Device-Type,HS-Token,HS-Lang';
  269. $header['Access-Control-Allow-Methods'] = 'GET,POST,PATCH,PUT,DELETE,OPTIONS';
  270. $response = Response::create($result, $type)->header($header);
  271. throw new HttpResponseException($response);
  272. }
  273. /**
  274. * 获取当前的response 输出类型
  275. *
  276. * @access protected
  277. * @return string
  278. */
  279. protected function getResponseType() {
  280. return $this->response_type;
  281. }
  282. /**
  283. * 获取当前登录用户的id
  284. *
  285. * @return int
  286. */
  287. public function getMemId() {
  288. if (empty($this->mem_id)) {
  289. // $this->error(lang('NO_LOGIN'), '', 1002);
  290. }
  291. $this->mem_id = rand(1, 10);
  292. return $this->mem_id;
  293. }
  294. }