UploadController.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. namespace app\controller;
  3. use Exception;
  4. use Intervention\Image\ImageManagerStatic as Image;
  5. use plugin\admin\app\controller\Crud;
  6. use plugin\admin\app\model\Upload;
  7. use support\Db;
  8. use support\exception\BusinessException;
  9. use support\Request;
  10. use support\Response;
  11. use hg\apidoc\annotation as Apidoc;
  12. #[Apidoc\Title("上传")]
  13. #[Apidoc\Group("Upload")]
  14. #[Apidoc\Sort(1)]
  15. class UploadController extends Crud
  16. {
  17. /**
  18. * @var Upload
  19. */
  20. protected $model = null;
  21. /**
  22. * 只返回当前管理员数据
  23. * @var string
  24. */
  25. protected $dataLimit = 'personal';
  26. /**
  27. * 构造函数
  28. * @return void
  29. */
  30. public function __construct()
  31. {
  32. $this->model = new Upload;
  33. }
  34. #[Apidoc\Title("上传")]
  35. #[Apidoc\Url("api/file_front.html")]
  36. #[Apidoc\Method("POST")]
  37. #[Apidoc\Param("file", type: "file", require: true, desc: "上传图片")]
  38. #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
  39. #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
  40. public function file_front(Request $request): Response
  41. {
  42. $data = $this->base($request, '/upload/img/' . date('Ymd'));
  43. $realpath = $data['realpath'];
  44. try {
  45. $img = Image::make($realpath);
  46. $max_height = 1170;
  47. $max_width = 1170;
  48. $width = $img->width();
  49. $height = $img->height();
  50. $ratio = 1;
  51. if ($height > $max_height || $width > $max_width) {
  52. $ratio = $width > $height ? $max_width / $width : $max_height / $height;
  53. }
  54. $img->resize($width * $ratio, $height * $ratio)->save($realpath);
  55. } catch (Exception $e) {
  56. unlink($realpath);
  57. return error('处理图片发生错误');
  58. }
  59. Db::table('wa_users')->where('id',$request->user_data['id'])->update(['front_ima'=>$data['url']]);
  60. return success([
  61. 'url' => imageToBase64($data['url']),
  62. 'path' => $data['url'],
  63. ]);
  64. }
  65. #[Apidoc\Title("上传")]
  66. #[Apidoc\Url("api/file_reverse.html")]
  67. #[Apidoc\Method("POST")]
  68. #[Apidoc\Param("file", type: "file", require: true, desc: "上传图片")]
  69. #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
  70. #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
  71. public function file_reverse(Request $request): Response
  72. {
  73. $data = $this->base($request, '/upload/img/' . date('Ymd'));
  74. $realpath = $data['realpath'];
  75. try {
  76. $img = Image::make($realpath);
  77. $max_height = 1170;
  78. $max_width = 1170;
  79. $width = $img->width();
  80. $height = $img->height();
  81. $ratio = 1;
  82. if ($height > $max_height || $width > $max_width) {
  83. $ratio = $width > $height ? $max_width / $width : $max_height / $height;
  84. }
  85. $img->resize($width * $ratio, $height * $ratio)->save($realpath);
  86. } catch (Exception $e) {
  87. unlink($realpath);
  88. return error('处理图片发生错误');
  89. }
  90. Db::table('wa_users')->where('id',$request->user_data['id'])->update(['reverse_ima'=>$data['url']]);
  91. return success([
  92. 'url' => imageToBase64($data['url']),
  93. 'path' => $data['url'],
  94. ]);
  95. }
  96. /**
  97. * 获取上传数据
  98. * @param Request $request
  99. * @param $relative_dir
  100. * @return array
  101. * @throws BusinessException|RandomException
  102. */
  103. protected function base(Request $request, $relative_dir): array
  104. {
  105. $relative_dir = ltrim($relative_dir, '\\/');
  106. $file = current($request->file());
  107. if (!$file || !$file->isValid()) {
  108. throw new BusinessException('未找到上传文件', 400);
  109. }
  110. $admin_public_path = rtrim(config('app.public_path', ''), '\\/');
  111. $base_dir = $admin_public_path ? $admin_public_path . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
  112. $full_dir = $base_dir . $relative_dir;
  113. if (!is_dir($full_dir)) {
  114. mkdir($full_dir, 0777, true);
  115. }
  116. $ext = $file->getUploadExtension() ?: null;
  117. $mime_type = $file->getUploadMimeType();
  118. $file_name = $file->getUploadName();
  119. $file_size = $file->getSize();
  120. if (!$ext && $file_name === 'blob') {
  121. [$___image, $ext] = explode('/', $mime_type);
  122. unset($___image);
  123. }
  124. $ext = strtolower($ext);
  125. $ext_forbidden_map = ['php', 'php3', 'php5', 'css', 'js', 'html', 'htm', 'asp', 'jsp'];
  126. if (in_array($ext, $ext_forbidden_map)) {
  127. throw new BusinessException('不支持该格式的文件上传', 400);
  128. }
  129. $relative_path = $relative_dir . '/' . bin2hex(pack('Nn', time(), random_int(1, 65535))) . ".$ext";
  130. $full_path = $base_dir . $relative_path;
  131. $file->move($full_path);
  132. $image_with = $image_height = 0;
  133. if ($img_info = getimagesize($full_path)) {
  134. [$image_with, $image_height] = $img_info;
  135. $mime_type = $img_info['mime'];
  136. }
  137. return [
  138. 'url' => "/$relative_path",
  139. 'name' => $file_name,
  140. 'realpath' => $full_path,
  141. 'size' => $file_size,
  142. 'mime_type' => $mime_type,
  143. 'image_with' => $image_with,
  144. 'image_height' => $image_height,
  145. 'ext' => $ext,
  146. ];
  147. }
  148. #[Apidoc\Title("上传图片base64")]
  149. #[Apidoc\Url("api/base_file.html")]
  150. #[Apidoc\Method("POST")]
  151. #[Apidoc\Param("baseimg", type: "string", require: true, desc: "base64编码")]
  152. #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
  153. #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
  154. public function base_file(Request $request): Response
  155. {
  156. $param = $request->all();
  157. try {
  158. $base64Image_one = $param['baseimg']; // 获取Base64字符串
  159. $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image_one)); // 移除数据URL的前缀并解码
  160. $imageName = $request->user_data['id'] . time() . '.png'; // 生成一个唯一的文件名
  161. $data = '/upload/img/' . date('Ymd');
  162. $relative_dir = ltrim($data, '\\/');
  163. $admin_public_path = rtrim(config('app.public_path', ''), '\\/');
  164. $base_dir = $admin_public_path ? $admin_public_path . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
  165. $full_dir = $base_dir . $relative_dir;
  166. if (!is_dir($full_dir)) {
  167. mkdir($full_dir, 0777, true);
  168. }
  169. $imagePath_one = '/upload/img/' . date('Ymd') . '/' . $imageName; // 指定保存路径和文件名
  170. // 保存图片到服务器
  171. file_put_contents($base_dir . $imagePath_one, $imageData);
  172. } catch (Exception $e) {
  173. return error('处理图片发生错误');
  174. }
  175. Db::table('wa_users')->where('id', $request->user_data['id'])->update(['sign_img' => $imagePath_one]);
  176. return adminsuccess([
  177. 'url' => imageToBase64($imagePath_one),
  178. 'path' => $imagePath_one,
  179. ]);
  180. }
  181. #[Apidoc\Title("上传图片base64")]
  182. #[Apidoc\Url("api/card_file.html")]
  183. #[Apidoc\Method("POST")]
  184. #[Apidoc\Param("baseimg", type: "string", require: true, desc: "base64编码")]
  185. #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
  186. #[Apidoc\Header("front_ima", type: "string", require: true, desc: "正面图片——base64", mock: "")]
  187. #[Apidoc\Header("reverse_ima", type: "string", require: true, desc: "反面图片——base64", mock: "@")]
  188. #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
  189. public function card_file(Request $request): Response
  190. {
  191. $param = $request->all();
  192. try {
  193. if (!empty($param['front_ima'])) {
  194. $base64Image_one = $param['front_ima']; // 获取Base64字符串
  195. $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image_one)); // 移除数据URL的前缀并解码
  196. $imageName = $request->user_data['id'] . '1' . time() . '.png'; // 生成一个唯一的文件名
  197. $data = '/upload/img/' . date('Ymd');
  198. $relative_dir = ltrim($data, '\\/');
  199. $admin_public_path = rtrim(config('app.public_path', ''), '\\/');
  200. $base_dir = $admin_public_path ? $admin_public_path . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
  201. $full_dir = $base_dir . $relative_dir;
  202. if (!is_dir($full_dir)) {
  203. mkdir($full_dir, 0777, true);
  204. }
  205. $imagePath_one = '/upload/img/' . date('Ymd') . '/' . $imageName; // 指定保存路径和文件名
  206. // 保存图片到服务器
  207. file_put_contents($base_dir . $imagePath_one, $imageData);
  208. } else {
  209. $imagePath_one = $request->user_data['front_ima'];
  210. }
  211. if (!empty($param['reverse_ima'])) {
  212. $base64Image_two = $param['reverse_ima']; // 获取Base64字符串
  213. $imageData_two = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image_two)); // 移除数据URL的前缀并解码
  214. $imageName_two = $request->user_data['id'] . '2' . time() . '.png'; // 生成一个唯一的文件名
  215. $data = '/upload/img/' . date('Ymd');
  216. $relative_dir_two = ltrim($data, '\\/');
  217. $admin_public_path_two = rtrim(config('app.public_path', ''), '\\/');
  218. $base_dir_two = $admin_public_path_two ? $admin_public_path_two . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
  219. $full_dir_two = $base_dir_two . $relative_dir_two;
  220. if (!is_dir($full_dir_two)) {
  221. mkdir($full_dir_two, 0777, true);
  222. }
  223. $imagePath_two = '/upload/img/' . date('Ymd') . '/' . $imageName_two; // 指定保存路径和文件名
  224. // 保存图片到服务器
  225. file_put_contents($base_dir_two . $imagePath_two, $imageData_two);
  226. } else {
  227. $imagePath_two = $request->user_data['reverse_ima'];
  228. }
  229. } catch (Exception $e) {
  230. return error('处理图片发生错误');
  231. }
  232. Db::table('wa_users')->where('id', $request->user_data['id'])
  233. ->update([
  234. 'front_ima' => $imagePath_one,
  235. 'reverse_ima' => $imagePath_two,
  236. ]);
  237. return adminsuccess([
  238. 'front_ima' => imageToBase64($imagePath_one),
  239. 'reverse_ima' => imageToBase64($imagePath_two),
  240. 'path' => $imagePath_one,
  241. ]);
  242. }
  243. }