Upgrade.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\v3tov4\model;
  11. use app\model\BaseModel;
  12. use think\facade\Db;
  13. /**
  14. * V3版本升级
  15. */
  16. class Upgrade extends BaseModel
  17. {
  18. private $db = 'v3';
  19. private $task_class = [
  20. 'goods' => [
  21. 'name' => '商品',
  22. 'class' => 'addon\v3tov4\model\Goods',
  23. 'is_show' => 1,
  24. 'introduction' => '迁移商品、商品分类、商品标签等数据',
  25. 'desc' => <<<EOT
  26. 变动说明
  27. 1、商品标签(ns_goods_group)转移到商品分组(ns_goods_label),丢失图片
  28. 2、商品分类(ns_goods_category),废弃pc端模板、手机端模板设置、是否显示、关联商品类型ID,完善上下级关联字段
  29. 3、相册图片直接查询存表
  30. 4、丢失商品类型数据
  31. 5、丢失商品评价数据
  32. 6、丢失回收站数据
  33. 7、丢失阶梯优惠数据
  34. 8、丢失积分设置
  35. 9、丢失会员折扣
  36. 10、丢失分销设置
  37. 11、丢失卡券商品
  38. 12、丢失网盘以及下载商品
  39. 13、丢失商品品牌,已废弃
  40. 14、丢失商品规格
  41. 15、ns_goods表字段变动说明
  42. 1、移除brand_id,品牌id
  43. 2、category_id_1、category_id_2、category_id_3合并到category_id、category_json字段
  44. 3、promotion_price转移到ns_goods_sku表中的discount_price字段
  45. 4、移除point_exchange_type、point_exchange,积分兑换字段
  46. 5、移除give_point字段,购买商品赠送积分
  47. 6、移除shop_id字段,店铺id
  48. 7、移除is_member_discount字段,参与会员折扣
  49. 8、shipping_fee对应is_free_shipping字段,是否免邮
  50. 9、shipping_fee_id对应shipping_template字段,指定运费模板id
  51. 10、stock对应goods_stock字段,商品库存
  52. 11、min_stock_alarm对应goods_stock_alarm字段,库存预警
  53. 12、移除star字段,好评星级
  54. 13、移除shares字段,分享数
  55. 14、evaluates对应evaluate字段,评价数
  56. 15、移除province_id、city_id,地区id字段
  57. 16、picture对应goods_image字段,商品主图路径
  58. 17、goods_content对应description字段,商品详情
  59. 18、移除QRcode字段,商品二维码
  60. 19、移除is_stock_visible字段,页面不显示库存
  61. 20、移除is_hot字段,是否热销商品
  62. 21、移除is_recommend字段,是否推荐
  63. 22、移除is_new字段,是否新品
  64. 23、移除is_pre_sale字段,是否预售
  65. 24、移除is_bill字段,是否开具增值税发票
  66. 25、移除img_id_array字段,商品图片序列
  67. 26、移除sku_img_array字段,商品sku应用图片列表
  68. 27、移除match_point、match_ratio字段,实物与描述相符(根据评价计算)、百分比
  69. 28、移除real_sales字段,实际销量
  70. 29、goods_weight转移到ns_goods_sku表中的weight字段,重量(单位g)
  71. 30、goods_volume转移到ns_goods_sku表中的volume字段,体积(单位立方米)
  72. 31、移除shipping_fee_type字段,计价方式1.重量2.体积3.计件
  73. 32、移除extend_category_id、extend_category_id_1、extend_category_id_2、extend_category_id_3字段
  74. 33、移除production_date字段,生产日期
  75. 34、移除shelf_life字段,保质期
  76. 35、移除pc_custom_template字段,pc端商品自定义模板
  77. 36、移除wap_custom_template字段,wap端商品自定义模板
  78. 37、goods_video_address对应video_url字段,视频
  79. 38、移除max_use_point字段,积分抵现最大可用积分数
  80. 39、移除is_open_presell字段,是否支持预售
  81. 40、移除presell_time、presell_day字段,预售发货时间/天数
  82. 41、移除presell_delivery_type字段,预售发货方式1
  83. 42、移除presell_price字段,预售金额
  84. 43、goods_unit对应unit字段,单位
  85. 44、移除decimal_reservation_number字段,价格保留方式 0 去掉角和分,1去掉分,2 保留角和分
  86. 45、移除integral_give_type字段,积分赠送类型 0固定值 1按比率
  87. 16、ns_goods_sku表字段变动说明
  88. 1、promote_price对应discount_price字段,促销价格
  89. 2、移除QRcode字段,商品二维码
  90. 3、移除sku_img_array字段,sku图片序列
  91. 4、移除extend_json字段,虚拟扩展
  92. EOT
  93. ],
  94. 'member' => [
  95. 'name' => '会员',
  96. 'class' => 'addon\v3tov4\model\Member',
  97. 'is_show' => 1,
  98. 'introduction' => '迁移会员、等级、标签、收货地址、商品收藏、足迹、账户流水等数据',
  99. 'desc' => <<<EOT
  100. 变动说明
  101. 1、丢失会员账户数据
  102. 2、会员主表 数据表: sys_user -> ns_member
  103. 1、member_id 由 v3 sys_user uid对应转入
  104. 2、source_member 来源会员id 查询v3 nfx_shop_member_association
  105. 3、fenxiao_id 分销商id 查询会员是否是分销商 是则为自身分销商id 否查询上级分销商
  106. 4、username 由 v3 sys_user user_name 字段对应转入
  107. 5、nickname 由 v3 sys_user nick_name 字段对应转入
  108. 6、mobile 由 v3 sys_user user_tel 字段对应转入
  109. 7、email 由 v3 sys_user user_email 字段对应转入
  110. 8、password 由 v3 sys_user user_password 字段对应转入
  111. 9、headimg 头像需从v3站点进行拉取
  112. 10、member_level、member_level_name、member_label、member_label_name 这些字段需关联v3 ns_member 查询到 会员等级 会员标签 去这两表中查询
  113. 11、wx_openid 公众号openid v3 sys_user wx_openid 字段对应转入
  114. 12、weapp_openid 小程序openid v3 sys_user wx_applet_openid 字段对应转入
  115. 13、realname 由v3 sys_user real_name 字段对应转入
  116. 14、sex 由v3 sys_user sex 字段对应转入
  117. 15、location 由v3 sys_user location 字段对应转入
  118. 16、birthday 由v3 sys_user birthday 字段对应转入
  119. 17、reg_time 由v3 sys_user reg_time 字段对应转入
  120. 18、point 积分 由v3 ns_member_account point 字段对应转入
  121. 19、balance 储值余额 由v3 ns_member_account balance 字段对应转入
  122. EOT
  123. ],
  124. 'fenxiao' => [
  125. 'name' => '分销',
  126. 'class' => 'addon\v3tov4\model\Fenxiao',
  127. 'introduction' => '迁移分销商、分销商等级等数据',
  128. 'is_show' => 0,
  129. 'desc' => <<<EOT
  130. 变动说明
  131. 1、分销商 数据表:nfx_promoter -> ns_fenxiao
  132. 1、fenxiao_id 由v3 nfx_promoter promoter_id 字段对应转入
  133. 2、fenxiao_no 按v4分销商编号生成规则生成
  134. 3、fenxiao_name 由v3 nfx_promoter promoter_shop_name 字段对应转入
  135. 4、mobile 由v3 nfx_promoter balance 字段对应转入
  136. 5、member_id 由v3 nfx_promoter uid 字段对应转入
  137. 6、level_id 由v3 nfx_promoter promoter_level 字段对应转入
  138. 7、level_name 查询对应分销商等级名称
  139. 8、parent 由v3 nfx_promoter parent_promoter 字段对应转入
  140. 9、grand_parent 查询上上级分销商id
  141. 10、account 当前佣金 由v3 nfx_promoter (commossion_total - commission_cash) 总佣金 - 已提现佣金
  142. 11、account_withdraw 已提现佣金 由v3 nfx_promoter commission_cash 字段对应转入
  143. 12、create_time 由v3 nfx_promoter audit_time 字段对应转入
  144. 13、total_commission 累计佣金 由v3 nfx_promoter commossion_total 字段对应转入
  145. 2、分销商申请 数据表:nfx_promoter -> ns_fenxiao_apply
  146. 1、fenxiao_name 由v3 nfx_promoter promoter_shop_name 字段对应转入
  147. 2、parent 由v3 nfx_promoter parent_promoter 字段对应转入
  148. 3、member_id 由v3 nfx_promoter uid 字段对应转入
  149. 4、mobile 查询会员相应数据
  150. 5、nickname 查询会员相应数据
  151. 6、headimg 查询会员相应数据
  152. 7、level_id 由v3 nfx_promoter promoter_level 字段对应转入
  153. 8、level_name 查询相应分销商等级名称
  154. 9、create_time 由v3 nfx_promoter regidter_time 字段对应转入
  155. 3、分销等级数据表:nfx_promoter_level -> ns_fenxiao_level
  156. 1、level_id 由v3 nfx_promoter_level level_id 字段对应转入
  157. 2、level_name 由v3 nfx_promoter_level level_name 字段对应转入
  158. 3、one_rate 由v3 nfx_promoter_level level_0 字段对应转入
  159. 4、two_rate 由v3 nfx_promoter_level level_1 字段对应转入
  160. 5、three_rate 由v3 nfx_promoter_level level_2 字段对应转入
  161. 6、create_time 由v3 nfx_promoter_level create_time 字段对应转入
  162. 4、分销商品 (规则不同不做迁移)
  163. EOT
  164. ],
  165. // 'order' => [
  166. // 'name' => '订单',
  167. // 'class' => 'addon\v3tov4\model\Goods'
  168. // ]
  169. ];
  170. private $page_size = 10;
  171. /**
  172. * 获取数据迁移项
  173. * @return array
  174. */
  175. public function getTaskClass()
  176. {
  177. return $this->task_class;
  178. }
  179. /**
  180. * 获取分页
  181. * @return int
  182. */
  183. public function getPageSize()
  184. {
  185. return $this->page_size;
  186. }
  187. /**
  188. * 获取分页列表
  189. * @param $table
  190. * @param $where
  191. * @param $page
  192. * @param $page_size
  193. * @param $ailas
  194. * @param $join
  195. */
  196. final protected function getPageList($table, $where = [], $field = '*', $page = 1, $page_size = 10, $alias = '', $join = null)
  197. {
  198. $table = Db::connect($this->db)->table($table);
  199. if (!empty($join)) {
  200. $table = $this->parseJoin($table, $join);
  201. }
  202. $list = $table->alias($alias)->where($where)->field($field)->limit($page_size)->page($page)->select()->toArray();
  203. return $list;
  204. }
  205. /**
  206. * 获取列表
  207. * @param $table
  208. * @param array $where
  209. * @param string $field
  210. * @param string $alias
  211. * @param null $join
  212. * @return array
  213. * @throws \think\db\exception\DataNotFoundException
  214. * @throws \think\db\exception\DbException
  215. * @throws \think\db\exception\ModelNotFoundException
  216. */
  217. final protected function getList($table, $where = [], $field = '*', $order = "", $alias = '', $join = null)
  218. {
  219. $table = Db::connect($this->db)->table($table);
  220. if (!empty($join)) {
  221. $table = $this->parseJoin($table, $join);
  222. }
  223. $list = $table->alias($alias)->where($where)->order($order)->field($field)->select()->toArray();
  224. return $list;
  225. }
  226. /**
  227. * 查询单条数据
  228. * @param $table
  229. * @param array $where
  230. * @param string $field
  231. * @param string $alias
  232. * @param null $join
  233. * @return mixed
  234. */
  235. final protected function getInfo($table, $where = [], $field = '*', $alias = 'a', $join = null)
  236. {
  237. $table = Db::connect($this->db)->table($table);
  238. if (!empty($join)) {
  239. $table = $this->parseJoin($table, $join);
  240. }
  241. $info = $table->alias($alias)->where($where)->field($field)->find();
  242. return $info;
  243. }
  244. /**
  245. * sql查询
  246. * @param $sql
  247. * @return mixed
  248. */
  249. final protected function query($sql)
  250. {
  251. $res = Db::connect($this->db)->query($sql);
  252. return $res;
  253. }
  254. /**
  255. * 查询数量
  256. * @param $table
  257. * @param array $where
  258. * @param string $field
  259. */
  260. final protected function getCount($table, $where = [], $field = '*')
  261. {
  262. $table = Db::connect($this->db)->table($table);
  263. $count = $table->where($where)->count($field);
  264. return $count;
  265. }
  266. /**
  267. * join分析
  268. * @access protected
  269. * @param array $join
  270. * @param array $options 查询条件
  271. * @return string
  272. */
  273. final protected function parseJoin($db_obj, $join)
  274. {
  275. foreach ($join as $item) {
  276. list($table, $on, $type) = $item;
  277. $type = strtolower($type);
  278. switch ( $type ) {
  279. case "left":
  280. $db_obj = $db_obj->leftJoin($table, $on);
  281. break;
  282. case "inner":
  283. $db_obj = $db_obj->join($table, $on);
  284. break;
  285. case "right":
  286. $db_obj = $db_obj->rightjoin($table, $on);
  287. break;
  288. case "full":
  289. $db_obj = $db_obj->fulljoin($table, $on);
  290. break;
  291. default:
  292. break;
  293. }
  294. }
  295. return $db_obj;
  296. }
  297. /**
  298. * 获取数据同步任务列表
  299. */
  300. public function getSyncTask($class)
  301. {
  302. $task_class = [];
  303. $class_array = explode(',', $class);
  304. foreach ($class_array as $item) {
  305. if (isset($this->task_class[ $item ])) {
  306. array_push($task_class, $this->task_class[ $item ][ 'class' ]);
  307. if ($item == 'member') {
  308. array_push($task_class, $this->task_class[ 'fenxiao' ][ 'class' ]);
  309. }
  310. }
  311. }
  312. try {
  313. $methods = $this->getTaskMethod($task_class);
  314. $task = [];
  315. foreach ($methods as $method => $class_name) {
  316. $class = new $class_name();
  317. $count = $class->$method();
  318. if ($count > 0) {
  319. for ($i = 0; $i < ceil(( $count / $this->page_size )); $i++) {
  320. array_push($task, [
  321. 'class' => $class_name,
  322. 'method' => str_replace('Count', 'List', $method),
  323. 'page' => $i + 1,
  324. 'page_size' => $this->page_size
  325. ]);
  326. }
  327. }
  328. }
  329. return $task;
  330. } catch (\Exception $e) {
  331. return $this->error('', $e->getMessage());
  332. }
  333. }
  334. /**
  335. * 执行任务
  336. */
  337. public function run($task)
  338. {
  339. try {
  340. [ 'class' => $class_name, 'method' => $method, 'page' => $page, 'page_size' => $page_size ] = $task;
  341. $class = new $class_name();
  342. $res = $class->$method($page, $page_size);
  343. return $res;
  344. } catch (\Exception $e) {
  345. return $this->error('', $e->getMessage());
  346. }
  347. }
  348. /**
  349. * 获取类中的方法
  350. * @param $class_array
  351. * @return array
  352. * @throws \ReflectionException
  353. */
  354. private function getTaskMethod($class_array)
  355. {
  356. $method_array = [];
  357. foreach ($class_array as $class_name) {
  358. $class = new \ReflectionClass($class_name);
  359. $methods = $class->getMethods();
  360. foreach ($methods as $method) {
  361. if (strpos($method->name, 'Count') !== false && $method->name != 'getCount') {
  362. $method_array[ $method->name ] = $method->class;
  363. }
  364. }
  365. }
  366. return $method_array;
  367. }
  368. }