diff --git a/app/BaseApp/BaseClient.php b/app/BaseApp/BaseClient.php new file mode 100644 index 00000000..b33b12e3 --- /dev/null +++ b/app/BaseApp/BaseClient.php @@ -0,0 +1,23 @@ +service->list(), + '列表获取成功' + ); + } + + /** + * 获取下拉列表 + * @Method GET + * @return mixed + * @throws Exception + */ + public function option(): mixed + { + return jok( + $this->service->option(), + '列表获取成功' + ); + } + + /** + * 获取详情 + * + * @Method GET + * @return JsonResponse + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws Exception + */ + public function detail(): JsonResponse + { + $id = request()->get('id'); + if (empty($id)) UtilsService::getInstance()->notFound('参数错误'); + return jok( + $this->service->detail($id), + '详情获取成功' + ); + } + + /** + * 创建 + * + * @Method POST + * @return JsonResponse + * @throws Exception + */ + public function create(): JsonResponse + { + $params = $this->checkRequiredFields(request()->post()); + return jok( + $this->service->create($params), + '创建成功' + ); + } + + /** + * 更新 + * + * @Method POST + * @return JsonResponse + * @throws Exception + */ + public function update(): JsonResponse + { + $params = $this->checkRequiredFields(request()->post(), 'update'); + $id = $params['id']; + unset($params['id']); + return jok( + $this->service->update($id, $params), + '更新成功' + ); + } + + /** + * 删除 + * + * @Method POST + * @return JsonResponse + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws Exception + */ + public function delete(): JsonResponse + { + $id = request()->post('ids'); + if (empty($id)) UtilsService::getInstance()->notFound('参数错误'); + return jok( + $this->service->delete($id), + '删除成功' + ); + } + + + /** + * 检查必填字段 + * + * @Method NO + * @param array $data + * @param string $checkType + * @param bool $throw + * @return array + * @throws Exception + */ + public function checkRequiredFields(array $data = [], string $checkType = 'create', bool $throw = true): array + { + $checkFields = $checkType == 'create' ? $this->insertField : $this->updateField; + + if (!empty($this->notRequest)) { + $checkFields = array_merge($this->notRequest, $checkFields); + } + + $requiredFields = []; + $result = []; + foreach ($checkFields as $fieldName) { + $checkValue = $data[$fieldName] ?? ''; + if (is_array($checkValue)) { + $checkValue = json_encode($checkValue); + } + if (mb_strlen(strval($checkValue)) <= 0 && !in_array($fieldName, $this->notRequest)) { + $requiredFields[] = $fieldName; + } else { + $result[$fieldName] = $checkValue; + } + } + + if ($throw && $requiredFields) { + UtilsService::getInstance()->notFound('未填写的字段: ' . implode(',', $requiredFields)); + } + + if (!empty($requiredFields)) { + return $requiredFields; + } + + return $result; + } + +} diff --git a/app/BaseApp/BaseModel.php b/app/BaseApp/BaseModel.php new file mode 100755 index 00000000..2a990c96 --- /dev/null +++ b/app/BaseApp/BaseModel.php @@ -0,0 +1,26 @@ +isAuth) { + // 如果是home的接口可以不执行这个方法 + if (!\request()->is('api/home/*')) { + $this->authUser(); + } + } + $this->utils = UtilsService::getInstance(); + } + + /** + * 获取实例 + * @return null|static + */ + public static function getInstance(): null|static + { + $name = get_called_class(); + if (!isset(self::$_instance[$name])) { + self::$_instance[$name] = new static(); + } + + return self::$_instance[$name]; + } + + private function authUser() + { + $token = \request()->header('Authorization'); + $token = explode(' ', $token)[1]; + $userModel = UserModel::where('session_key', $token)->first(); + if (!$userModel) { + jexpire('token失效'); + } + $this->userId = $userModel->id; + $this->userInfo = $userModel->toArray(); + } +} diff --git a/app/Enum/ErrorEnum.php b/app/Enum/ErrorEnum.php new file mode 100755 index 00000000..91d0e2d7 --- /dev/null +++ b/app/Enum/ErrorEnum.php @@ -0,0 +1,55 @@ + '请求成功', + self::FAIL => '服务器异常', + self::NOT_FOUND => '未找到资源', + self::NOT_AUTH => '未授权', + self::NOT_PERMISSION => '您没有权限', + self::NOT_VALID => '字段验证失败', + self::NOT_EXIST => '资源不存在', + self::NOT_EXIST_OR_DELETED => '资源被删除', + }; + } +} diff --git a/app/Service/UtilsService.php b/app/Service/UtilsService.php new file mode 100755 index 00000000..6174d59c --- /dev/null +++ b/app/Service/UtilsService.php @@ -0,0 +1,220 @@ +value); + } + + /** + * 抛出未找到异常 2000 + * + * @param $msg + * @return mixed + * @throws Exception + */ + public function notFound($msg): mixed + { + return self::errorThrow($msg, ErrorEnum::NOT_FOUND); + } + + /** + * 未授权 401 + * + * @param $msg + * @return mixed + * @throws Exception + */ + public function notAuth($msg): mixed + { + exit(json_encode(['msg' => $msg, 'code' => ErrorEnum::NOT_AUTH->value])); + } + + /** + * 生成密码 + * @param $password + * @return string + */ + public function genPassword($password): string + { + return password_hash($password, PASSWORD_DEFAULT); + } + + /** + * 密码验证 + * + * @param $password + * @param $passwordAse + * @return bool + */ + public function checkPassword($password, $passwordAse): bool + { + // 盐 + return password_verify($password, $passwordAse); + } + + /** + * 生成OpenId + * @return string + * @throws RandomException + */ + public function genOpenId(): string + { + // 获取当前时间戳(精确到秒) + $timestamp = dechex(time()); + + // 生成16字节的随机数据,并转换为32个十六进制字符组成的字符串 + $randomString = bin2hex(random_bytes(16)); + + // 结合时间和随机字符串,确保总长度为28个字符 + return substr($timestamp . $randomString, 0, 28); + } + + /** + * 递归生成树形结构 + * @param $data + * @param int $pid + * @return array + */ + public function tree($data, int $pid = 0): array + { + $tree = []; + foreach ($data as $v) { + if ($v['pid'] == $pid) { + $v['children'] = $this->tree($data, $v['id']); + if (empty($v['children'])) { + unset($v['children']); + } + $tree[] = $v; + } + } + return $tree; + } + + + /** + * 检查手机号格式 + * + * @param string $phone + * @return bool + * @throws Exception + */ + public function checkPhone(string $phone): bool + { + $phone = trim($phone); + if (preg_match('/^1[3456789]\d{9}$/', $phone)) { + return true; + } else { + self::errorThrow('手机号格式不正确'); + } + } + + /** + * 生成订单号 + * @param int $type + * @return string + */ + public function genOrderNo(int $type = 0): string + { + $len = 9999999999; + switch ($type) { + case 0: + return 'DK'. date('Ymd') . str_pad(mt_rand(1, $len), 11, '0', STR_PAD_LEFT); + case 1: + return 'DD'. date('Ymd') . str_pad(mt_rand(1, $len), 11, '0', STR_PAD_LEFT); + default: + return ''; + } + } + + /** + * 是否是开发环境 + * @return bool + */ + public static function isDev(): bool + { + return env('ECS') === 'localhost'; + } + + /** + * 根据身份证号计算年龄 + * @param string $idno 身份证号(15位或18位) + * @return int|false 成功返回年龄,失败返回false + */ + public function getAgeFromIdNo($idno = '') + { + // 校验身份证号长度 + $len = strlen($idno); + if (!in_array($len, [15, 18])) { + return false; + } + + // 提取出生日期部分 + if ($len === 18) { + $datePart = substr($idno, 6, 8); + } else { + // 15位身份证补全年份为19XX + $datePart = '19' . substr($idno, 6, 6); + } + + // 分解年月日 + $year = substr($datePart, 0, 4); + $month = substr($datePart, 4, 2); + $day = substr($datePart, 6, 2); + + // 校验年月日是否为数字 + if (!ctype_digit($year) || !ctype_digit($month) || !ctype_digit($day)) { + return false; + } + + // 尝试创建日期对象 + try { + $birthDate = new DateTime("$year-$month-$day"); + } catch (Exception $e) { + return false; + } + + $currentDate = new DateTime(); + + // 检查出生日期是否在当前日期之前 + if ($birthDate > $currentDate) { + return false; + } + + // 计算年龄差 + $ageInterval = $currentDate->diff($birthDate); + return $ageInterval->y; + } +}