ImageHostService.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <?php
  2. namespace crmeb\services;
  3. use app\common\repositories\system\config\ConfigValueRepository;
  4. use http\Exception\InvalidArgumentException;
  5. use Swoole\Coroutine\System;
  6. use think\Exception;
  7. use think\exception\ValidateException;
  8. use think\facade\Config;
  9. use think\facade\Db;
  10. use think\facade\Log;
  11. class ImageHostService
  12. {
  13. private static $_instance;
  14. //原始路径
  15. public $origin;
  16. public $origin_json;
  17. //替换路径
  18. public $replace;
  19. public $replace_json;
  20. //数据库前缀
  21. public $db_prefix;
  22. //数据库名称
  23. public $success = true;
  24. public $limit = 10000;
  25. //需要更换的字段名
  26. public $fields_str = [
  27. 'image',
  28. 'cover_img',
  29. 'share_img',
  30. 'feeds_img',
  31. 'image_input',
  32. 'pic',
  33. 'mer_avatar',
  34. 'mini_banner',
  35. 'mer_banner',
  36. 'qrcode_url',
  37. 'avatar_img',
  38. 'avatar',
  39. 'attachment_src',
  40. 'brokerage_icon',
  41. 'pics',
  42. 'slider_image',
  43. 'extract_pic',
  44. 'cover_image',
  45. ];
  46. // 需要处理的json格式字段
  47. public $fields_json = [
  48. 'content',
  49. 'images',
  50. 'value',
  51. 'info',
  52. ];
  53. //需要处理的数据表名称
  54. public $range = [
  55. "article",
  56. "article_content",
  57. "broadcast_goods",
  58. "broadcast_room",
  59. "community",
  60. "community_topic",
  61. "diy",
  62. "guarantee",
  63. "member_interests",
  64. "merchant",
  65. "merchant_applyments",
  66. "merchant_intention",
  67. "routine_qrcode",
  68. "store_activity",
  69. "store_category",
  70. "store_product",
  71. "store_product_attr_value",
  72. "store_product_content",
  73. "store_product_reply",
  74. "store_service",
  75. "store_spu",
  76. "system_attachment",
  77. "system_config_value",
  78. "system_group_data",
  79. "user",
  80. "user_brokerage",
  81. "user_extract",
  82. "wechat_qrcode",
  83. ];
  84. public function __construct()
  85. {
  86. $this->db_prefix = Config::get('database.connections.' . Config::get('database.default') . '.prefix');
  87. //$this->db_tables_name = Config::get('database.connections.' . Config::get('database.default') . '.database');
  88. }
  89. public static function getInstance()
  90. {
  91. if (!self::$_instance instanceof self) {
  92. self::$_instance = new self;
  93. }
  94. return self::$_instance;
  95. }
  96. /**
  97. * 获取需要处理的字段
  98. * @param $type
  99. * @return mixed
  100. * @author Qinii
  101. * @day 2024/3/8
  102. */
  103. public function getFields($type = 'str')
  104. {
  105. $type = in_array($type,['str','json']) ? $type : 'str';
  106. $field = "fields_{$type}";
  107. return $this->{$field} ;
  108. }
  109. /**
  110. * 追加处理字段
  111. * @param array $fields
  112. * @param $type
  113. * @author Qinii
  114. * @day 2024/3/8
  115. */
  116. public function setFields(array $fields,$type = 'str')
  117. {
  118. $type = in_array($type,['str','json']) ? $type : 'str';
  119. $field = "fields_{$type}";
  120. if (!empty($fields)) {
  121. $this->{$field} = array_unique(array_merge($this->{$fields}, $fields));
  122. }
  123. }
  124. /**
  125. * 获取处理表名
  126. * @return string[]
  127. * @author Qinii
  128. * @day 2024/3/8
  129. */
  130. public function getRange()
  131. {
  132. return $this->range;
  133. }
  134. /**
  135. * 追加处理表名
  136. * @param array $ranges
  137. * @author Qinii
  138. * @day 2024/3/8
  139. */
  140. public function setRange(array $ranges)
  141. {
  142. if (!empty($fields)) {
  143. $this->range = array_unique(array_merge($this->range, $ranges));
  144. }
  145. }
  146. /**
  147. * 组合好需要更换的域名
  148. * @param $origin
  149. * @param $replace
  150. * @author Qinii
  151. * @day 2024/3/7
  152. */
  153. public function getHost($origin,$replace)
  154. {
  155. try {
  156. $origin_parse_url = parse_url($origin);
  157. // 解析站点 URL 的协议 http / https
  158. $originScheme = $origin_parse_url['scheme'];
  159. $this->origin = $origin_parse_url['scheme'].'://'.$origin_parse_url['host'];
  160. // 将站点 URL 中的协议替换为 JSON 格式
  161. $this->origin_json = str_replace($originScheme . '://', $originScheme . ':\\\/\\\/', $this->origin);
  162. $replace_parse_url = parse_url($replace);
  163. // 获取当前 URL 的协议
  164. $replaceScheme = $replace_parse_url['scheme'];
  165. $this->replace = $replace_parse_url['scheme'].'://'.$replace_parse_url['host'];
  166. // 将当前 URL 中的协议替换为 JSON 格式
  167. $this->replace_json = str_replace($replaceScheme . '://', $replaceScheme . ':\\\/\\\/', $this->replace);
  168. }catch (Exception $exception) {
  169. throw new ValidateException('请输入正确的域名');
  170. }
  171. }
  172. protected function getSql($db)
  173. {
  174. $table = $this->db_prefix.$db;
  175. $db_data = Db::table($table)->where([])->limit(1)->select();
  176. $sql = '';
  177. if ($db_data && isset($db_data[0])) {
  178. $db_info = $db_data[0];
  179. $sql_ = $sql = "UPDATE `{$table}` SET ";
  180. foreach ($this->getFields() as $field) {
  181. if (isset($db_info[$field])){
  182. $sql .= "`$field` = replace(`$field` ,'$this->origin','$this->replace'),";
  183. }
  184. }
  185. foreach ($this->getFields('json') as $field_) {
  186. if (isset($db_info[$field_])){
  187. $sql .= "`$field_` = replace(`$field_` ,'$this->origin_json','$this->replace_json'),";
  188. }
  189. }
  190. $sql = $sql == $sql_ ? '' : $sql;
  191. }
  192. return [$sql, $table];
  193. }
  194. public function getDb()
  195. {
  196. // $db_key = 'Tables_in_'.$this->db_tables_name;
  197. // $db = Db::query('show tables');
  198. // $data = array_column($db,$db_key);
  199. }
  200. /**
  201. * 执行替换操作
  202. * @param $sql
  203. * @param string $table
  204. * @author Qinii
  205. * @day 2024/3/8
  206. */
  207. public function originToReplace($sql, string $table)
  208. {
  209. if (!$sql) return true;
  210. $sql = trim($sql,',');
  211. return Db::transaction(function () use ($sql,$table) {
  212. try {
  213. Db::execute($sql);
  214. return true;
  215. } catch (\Throwable $e) {
  216. $error = [
  217. '更换图片地址错误提示【'.$table.'】'.$e->getMessage(),
  218. '更换图片地址错误SQL'.$sql
  219. ];
  220. Log::error(var_export($error,true));
  221. $this->success = false;
  222. return $error;
  223. }
  224. });
  225. }
  226. /**
  227. * 运行处理sql
  228. * @param string $origin
  229. * @param string $replac
  230. * @author Qinii
  231. * @day 2024/3/8
  232. */
  233. public function execute(string $origin, string $replace)
  234. {
  235. $this->getHost($origin,$replace);
  236. foreach ($this->getRange() as $db) {
  237. [$sql, $table] = $this->getSql($db);
  238. $res = $this->originToReplace($sql, $table);
  239. }
  240. app()->make(ConfigValueRepository::class)->syncConfig();
  241. return $this->success;
  242. }
  243. }