初始上传
This commit is contained in:
38
addon/v3tov4/config/diy_view.php
Executable file
38
addon/v3tov4/config/diy_view.php
Executable file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
return [
|
||||
|
||||
// 自定义模板页面类型,格式:[ 'title' => '页面类型名称', 'name' => '页面标识', 'path' => '页面路径', 'value' => '页面数据,json格式' ]
|
||||
'template' => [],
|
||||
|
||||
// 后台自定义组件——装修
|
||||
'util' => [],
|
||||
|
||||
// 自定义页面路径
|
||||
'link' => [],
|
||||
|
||||
// 自定义图标库
|
||||
'icon_library' => [],
|
||||
|
||||
// uni-app 组件,格式:[ 'name' => '组件名称/文件夹名称', 'path' => '文件路径/目录路径' ],多个逗号隔开,自定义组件名称前缀必须是diy-,也可以引用第三方组件
|
||||
'component' => [],
|
||||
|
||||
// uni-app 页面,多个逗号隔开
|
||||
'pages' => [],
|
||||
|
||||
// 模板信息,格式:'title' => '模板名称', 'name' => '模板标识', 'cover' => '模板封面图', 'preview' => '模板预览图', 'desc' => '模板描述'
|
||||
'info' => [],
|
||||
|
||||
// 主题风格配色,格式可以自由定义扩展,【在uni-app中通过:this.themeStyle... 获取定义的颜色字段,例如:this.themeStyle.main_color】
|
||||
'theme' => [],
|
||||
|
||||
// 自定义页面数据,格式:[ 'title' => '页面名称', 'name' => "页面标识", 'value' => [页面数据,json格式] ]
|
||||
'data' => []
|
||||
];
|
||||
17
addon/v3tov4/config/event.php
Executable file
17
addon/v3tov4/config/event.php
Executable file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
// 事件定义文件
|
||||
return [
|
||||
'bind' => [
|
||||
|
||||
],
|
||||
|
||||
'listen' => [
|
||||
'ShowPromotion' => [
|
||||
'addon\v3tov4\event\ShowPromotion',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'subscribe' => [
|
||||
],
|
||||
];
|
||||
21
addon/v3tov4/config/info.php
Executable file
21
addon/v3tov4/config/info.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
return [
|
||||
'name' => 'v3tov4',
|
||||
'title' => 'v3Tov4迁移数据',
|
||||
'description' => 'v3Tov4迁移数据',
|
||||
'type' => 'tool', //插件类型 system :系统插件(自动安装), promotion:扩展营销插件 tool:工具插件
|
||||
'status' => 1,
|
||||
'author' => '',
|
||||
'version' => '5.5.3',
|
||||
'version_no' => '553250709001',
|
||||
'content' => '',
|
||||
];
|
||||
34
addon/v3tov4/config/menu_shop.php
Executable file
34
addon/v3tov4/config/menu_shop.php
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 平台端菜单设置
|
||||
// +----------------------------------------------------------------------
|
||||
return [
|
||||
[
|
||||
'name' => 'TOOL_UPGRADE',
|
||||
'title' => 'v3Tov4迁移',
|
||||
'url' => 'v3tov4://shop/upgrade/index',
|
||||
'parent' => 'PROMOTION_TOOL',
|
||||
'is_show' => 1,
|
||||
'picture' => 'addon/v3tov4/shop/view/public/img/migration_new.png',
|
||||
'picture_selected' => 'addon/v3tov4/shop/view/public/img/migration_select.png',
|
||||
'sort' => 1,
|
||||
'child_list' => [
|
||||
[
|
||||
'name' => 'TOOL_UPGRADE_DATA',
|
||||
'title' => '迁移数据',
|
||||
'url' => 'v3tov4://shop/upgrade/index',
|
||||
'is_show' => 1,
|
||||
'sort' => 1,
|
||||
'child_list' => []
|
||||
],
|
||||
[
|
||||
'name' => 'TOOL_UPGRADE_LOG',
|
||||
'title' => '迁移日志',
|
||||
'url' => 'v3tov4://shop/upgrade/log',
|
||||
'is_show' => 1,
|
||||
'sort' => 2,
|
||||
'child_list' => []
|
||||
]
|
||||
]
|
||||
],
|
||||
];
|
||||
32
addon/v3tov4/event/Install.php
Executable file
32
addon/v3tov4/event/Install.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
|
||||
namespace addon\v3tov4\event;
|
||||
|
||||
/**
|
||||
* 应用安装
|
||||
*/
|
||||
class Install
|
||||
{
|
||||
/**
|
||||
* 执行安装
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try{
|
||||
return success();
|
||||
}catch (\Exception $e)
|
||||
{
|
||||
return error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
48
addon/v3tov4/event/ShowPromotion.php
Executable file
48
addon/v3tov4/event/ShowPromotion.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
|
||||
namespace addon\v3tov4\event;
|
||||
|
||||
/**
|
||||
* 活动展示
|
||||
*/
|
||||
class ShowPromotion
|
||||
{
|
||||
|
||||
/**
|
||||
* 活动展示
|
||||
* @return array
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$data = [
|
||||
'shop' => [
|
||||
[
|
||||
//插件名称
|
||||
'name' => 'v3tov4',
|
||||
//店铺端展示分类 shop:营销活动 member:互动营销
|
||||
'show_type' => 'tool',
|
||||
//展示主题
|
||||
'title' => 'v3Tov4迁移数据',
|
||||
//展示介绍
|
||||
'description' => '商城V3版数据迁移到V4版',
|
||||
//展示图标
|
||||
'icon' => 'addon/v3tov4/icon.png',
|
||||
//跳转链接
|
||||
'url' => 'v3tov4://shop/upgrade/index',
|
||||
]
|
||||
]
|
||||
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
32
addon/v3tov4/event/UnInstall.php
Executable file
32
addon/v3tov4/event/UnInstall.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
|
||||
namespace addon\v3tov4\event;
|
||||
|
||||
/**
|
||||
* 应用卸载
|
||||
*/
|
||||
class UnInstall
|
||||
{
|
||||
/**
|
||||
* 执行卸载
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try{
|
||||
return success();
|
||||
}catch (\Exception $e)
|
||||
{
|
||||
return error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
addon/v3tov4/icon.png
Executable file
BIN
addon/v3tov4/icon.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
232
addon/v3tov4/model/Fenxiao.php
Executable file
232
addon/v3tov4/model/Fenxiao.php
Executable file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\v3tov4\model;
|
||||
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 迁移分销相关数据(分销商、分销商等级)
|
||||
*/
|
||||
class Fenxiao extends Upgrade
|
||||
{
|
||||
/**
|
||||
* 同步分销商数据
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
*/
|
||||
public function getFenxiaoList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('fenxiao')->startTrans();
|
||||
|
||||
$field = 'np.promoter_id,np.promoter_shop_name,np.uid,np.promoter_level,np.parent_promoter,np.regidter_time,np.audit_time,np.lock_time,npl.level_name';
|
||||
$join = [
|
||||
[ 'nfx_promoter_level npl', 'np.promoter_level = npl.level_id', 'left' ],
|
||||
];
|
||||
// 查询v3分销商表
|
||||
$list = $this->getPageList('nfx_promoter', [ [ 'is_audit', '=', '1' ] ], $field, $page_index, $page_size, 'np', $join);
|
||||
$data = [];
|
||||
if (!empty($list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空分销商表
|
||||
$prefix = config('database')['connections']['mysql']['prefix'];
|
||||
model('fenxiao')->execute("TRUNCATE TABLE {$prefix}fenxiao");
|
||||
}
|
||||
foreach ($list as $item) {
|
||||
// 分销商编号
|
||||
$time_str = date('YmdHi');
|
||||
$max_no = Cache::get('fenxiao_no_' . $time_str);
|
||||
if (empty($max_no)) {
|
||||
$max_no = 1;
|
||||
} else {
|
||||
$max_no += 1;
|
||||
}
|
||||
$fenxiao_no = $time_str . sprintf('%04d', $max_no);
|
||||
// 上上级分销商id
|
||||
$grand_parent = 0;
|
||||
if (!empty($item[ 'parent_promoter' ])) {
|
||||
$parent_promoter_info = $this->getInfo('nfx_promoter', [ [ 'promoter_id', '=', $item[ 'parent_promoter' ] ] ], 'parent_promoter');
|
||||
if (!empty($parent_promoter_info) && !empty($parent_promoter_info[ 'parent_promoter' ])) {
|
||||
$grand_parent = $parent_promoter_info[ 'parent_promoter' ];
|
||||
}
|
||||
}
|
||||
// 查询分销商账户数据
|
||||
$account_info = $this->getInfo('nfx_user_account', [ [ 'uid', '=', $item[ 'uid' ] ] ], 'commission,commission_cash,commission_withdraw');
|
||||
$data[] = [
|
||||
'fenxiao_id' => $item['promoter_id'],
|
||||
'site_id' => 1,
|
||||
'fenxiao_no' => $fenxiao_no,
|
||||
'fenxiao_name' => $item['promoter_shop_name'],
|
||||
'member_id' => $item['uid'],
|
||||
'level_id' => $item['promoter_level'],
|
||||
'level_name' => $item['level_name'],
|
||||
'parent' => $item['parent_promoter'],
|
||||
'grand_parent' => $grand_parent,
|
||||
'account' => $account_info['commission_cash'] ?? 0,
|
||||
'account_withdraw' => $account_info['commission_withdraw'] ?? 0,
|
||||
'total_commission' => $account_info['commission'] ?? 0,
|
||||
'create_time' => $item['regidter_time'],
|
||||
'audit_time' => $item['audit_time'],
|
||||
'lock_time' => $item['lock_time']
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4分销商表
|
||||
model('fenxiao')->addList($data);
|
||||
model('fenxiao')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('fenxiao')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的分销商的数量
|
||||
*/
|
||||
public function getFenxiaoCount()
|
||||
{
|
||||
return $this->getCount('nfx_promoter', [ [ 'is_audit', '=', '1' ] ], 'promoter_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步待审核分销商数据
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
*/
|
||||
public function getFenxiaoApplyList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('fenxiao_apply')->startTrans();
|
||||
|
||||
$field = 'np.promoter_shop_name,np.parent_promoter,np.uid,np.promoter_level,np.regidter_time,npl.level_name,su.user_tel,su.nick_name,su.user_headimg,su.reg_time,su.user_name';
|
||||
$join = [
|
||||
[ 'nfx_promoter_level npl', 'np.promoter_level = npl.level_id', 'left' ],
|
||||
[ 'sys_user su', 'su.uid = np.uid', 'left' ]
|
||||
];
|
||||
// 查询v3分销商表
|
||||
$list = $this->getPageList('nfx_promoter', [ [ 'is_audit', '=', '0' ] ], $field, $page_index, $page_size, 'np', $join);
|
||||
|
||||
$data = [];
|
||||
if (!empty($list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空分销商申请表
|
||||
$prefix = config('database')['connections']['mysql']['prefix'];
|
||||
model('fenxiao_apply')->execute("TRUNCATE TABLE {$prefix}fenxiao_apply");
|
||||
}
|
||||
foreach ($list as $item) {
|
||||
$user_info = $this->getInfo('sys_user', [ [ 'uid', '=', $item[ 'uid' ] ] ]);
|
||||
if ($user_info) {
|
||||
$data[] = [
|
||||
'site_id' => 1,
|
||||
'fenxiao_name' => $item['promoter_shop_name'],
|
||||
'parent' => $item['parent_promoter'],
|
||||
'member_id' => $item['uid'],
|
||||
'mobile' => $item['user_tel'] ?? 0,
|
||||
'nickname' => $item['nick_name'] ?? $item['user_name'],
|
||||
'headimg' => $item['user_headimg'],
|
||||
'level_id' => $item['promoter_level'],
|
||||
'level_name' => $item['level_name'],
|
||||
'reg_time' => $item['reg_time'],
|
||||
'create_time' => $item['regidter_time']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
// 添加到v4分销商申请表
|
||||
model('fenxiao_apply')->addList($data);
|
||||
model('fenxiao_apply')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('fenxiao_apply')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的待审核分销商的数量
|
||||
*/
|
||||
public function getFenxiaoApplyCount()
|
||||
{
|
||||
return $this->getCount('nfx_promoter', [ [ 'is_audit', '=', '0' ] ], 'promoter_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步分销商等级数据
|
||||
*/
|
||||
public function getFenxiaoLevelList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('fenxiao_level')->startTrans();
|
||||
|
||||
if ($page_index == 1) {
|
||||
$field = 'level_id,level_name,level_0,level_1,level_2,level_money,create_time';
|
||||
// 查询v3分销商表
|
||||
$list = $this->getList('nfx_promoter_level', [], $field, 'level_money asc');
|
||||
$data = [];
|
||||
if (!empty($list)) {
|
||||
// 首次清空分销商申请表
|
||||
$prefix = config('database')['connections']['mysql']['prefix'];
|
||||
model('fenxiao_level')->execute("TRUNCATE TABLE {$prefix}fenxiao_level");
|
||||
|
||||
foreach ($list as $key => $item) {
|
||||
$data[] = [
|
||||
'level_id' => $item['level_id'],
|
||||
'level_num' => ($key + 1),
|
||||
'site_id' => 1,
|
||||
'level_name' => $item['level_name'],
|
||||
'one_rate' => $item['level_0'],
|
||||
'two_rate' => $item['level_1'],
|
||||
'three_rate' => $item['level_2'],
|
||||
'upgrade_type' => 1,
|
||||
'order_money' => $item['level_money'],
|
||||
'create_time' => $item['create_time'],
|
||||
'status' => 1
|
||||
];
|
||||
}
|
||||
|
||||
// 添加到v4分销商等级表
|
||||
model('fenxiao_level')->addList($data);
|
||||
}
|
||||
|
||||
// 添加默认分销商等级
|
||||
$default_level = [
|
||||
'site_id' => 1,
|
||||
'level_name' => '默认等级',
|
||||
'level_num' => 0,
|
||||
'one_rate' => 0,
|
||||
'two_rate' => 0,
|
||||
'three_rate' => 0,
|
||||
'upgrade_type' => 1,
|
||||
'order_money' => 0,
|
||||
'create_time' => time(),
|
||||
'status' => 1,
|
||||
'is_default' => 1
|
||||
];
|
||||
model('fenxiao_level')->add($default_level);
|
||||
}
|
||||
|
||||
model('fenxiao_level')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('fenxiao_level')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的分销商等级的数量
|
||||
*/
|
||||
public function getFenxiaoLevelCount()
|
||||
{
|
||||
return $this->getCount('nfx_promoter_level', [], 'level_id');
|
||||
}
|
||||
}
|
||||
455
addon/v3tov4/model/Goods.php
Executable file
455
addon/v3tov4/model/Goods.php
Executable file
@@ -0,0 +1,455 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\v3tov4\model;
|
||||
|
||||
use app\model\goods\Goods as GoodsModel;
|
||||
use app\model\system\Stat;
|
||||
|
||||
/**
|
||||
* 迁移商品相关数据(商品、商品分类、商品标签)
|
||||
*/
|
||||
class Goods extends Upgrade
|
||||
{
|
||||
|
||||
private $site_id = 1;
|
||||
|
||||
/**
|
||||
* 迁移商品数据
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
* @return array
|
||||
*/
|
||||
public function getGoodsList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
|
||||
// 查询v3商品表
|
||||
$field = 'goods_id, goods_name, category_id, category_id_1, category_id_2, category_id_3, group_id_array, goods_type, market_price, price, promotion_price, cost_price, shipping_fee, shipping_fee_id, stock, max_buy, clicks, min_stock_alarm, sales, collects, star, evaluates, picture, keywords, introduction, description, code, state, sort, img_id_array, sku_img_array, goods_attribute_id, goods_spec_format, goods_weight, goods_volume, supplier_id, create_time, update_time, min_buy, is_virtual, goods_video_address, goods_unit';
|
||||
$goods_list = $this->getPageList('ns_goods', [ [ 'goods_type', 'in', '1,2' ] ], $field, $page_index, $page_size);
|
||||
|
||||
if (!empty($goods_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空商品表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('goods')->execute("TRUNCATE TABLE {$prefix}goods");
|
||||
model('goods_sku')->execute("TRUNCATE TABLE {$prefix}goods_sku");
|
||||
}
|
||||
|
||||
foreach ($goods_list as $item) {
|
||||
|
||||
// 商品参数
|
||||
$item[ 'goods_attr_class' ] = 0;
|
||||
$item[ 'goods_attr_name' ] = '';
|
||||
if (!empty($item[ 'goods_attribute_id' ])) {
|
||||
$attribute_info = $this->getInfo('ns_attribute', [ [ 'attr_id', '=', $item[ 'goods_attribute_id' ] ] ], 'attr_id,attr_name');
|
||||
if (!empty($attribute_info)) {
|
||||
$item[ 'goods_attr_class' ] = $attribute_info[ 'attr_id' ];
|
||||
$item[ 'goods_attr_name' ] = $attribute_info[ 'attr_name' ];
|
||||
}
|
||||
}
|
||||
$join = [
|
||||
[ 'ns_attribute_value nav', 'nav.attr_value_id = nga.attr_value_id', 'right' ],
|
||||
];
|
||||
$goods_attribute_list = $this->getList("ns_goods_attribute", [ [ 'goods_id', '=', $item[ 'goods_id' ] ] ], 'nav.attr_id as attr_class_id,nga.attr_id,nga.attr_value_id,nga.attr_value,nga.attr_value_name', '', 'nga', $join);
|
||||
$item[ 'goods_attr_format' ] = '';
|
||||
if (!empty($goods_attribute_list)) {
|
||||
$item[ 'goods_attr_format' ] = [];
|
||||
foreach ($goods_attribute_list as $attr_k => $attr_v) {
|
||||
$item[ 'goods_attr_format' ][] = [
|
||||
"attr_class_id" => $attr_v[ 'attr_class_id' ],
|
||||
"attr_id" => $attr_v[ 'attr_id' ],
|
||||
"attr_name" => $attr_v[ 'attr_value' ],
|
||||
"attr_value_id" => $attr_v[ 'attr_value_id' ],
|
||||
"attr_value_name" => $attr_v[ 'attr_value_name' ]
|
||||
];
|
||||
}
|
||||
$item[ 'goods_attr_format' ] = json_encode($item[ 'goods_attr_format' ]);
|
||||
}
|
||||
|
||||
// 商品标签
|
||||
$item[ 'label_id' ] = 0;
|
||||
if (!empty($item[ 'group_id_array' ])) {
|
||||
$item[ 'label_id' ] = explode(",", $item[ 'group_id_array' ])[ 0 ];
|
||||
}
|
||||
|
||||
if ($item[ 'goods_type' ] == 1) {
|
||||
$item[ 'goods_class' ] = 1;
|
||||
$item[ 'goods_class_name' ] = '实物商品';
|
||||
} elseif ($item[ 'goods_type' ] == 2) {
|
||||
$item[ 'goods_class' ] = 0;
|
||||
$item[ 'goods_class_name' ] = '虚拟商品';
|
||||
}
|
||||
|
||||
//商品主图
|
||||
$picture_info = $this->getInfo("sys_album_picture", [ [ 'pic_id', '=', $item[ 'picture' ] ] ], 'pic_cover');
|
||||
$item[ 'goods_image' ] = $picture_info[ 'pic_cover' ];
|
||||
|
||||
$goods_spec_format = json_decode($item[ 'goods_spec_format' ], true);
|
||||
$goods_spec_format_temp = [];
|
||||
// 循环处理规格
|
||||
foreach ($goods_spec_format as $spec_k => $spec_v) {
|
||||
$goods_spec_format_temp[ $spec_k ] = [
|
||||
"spec_name" => $spec_v[ 'spec_name' ],
|
||||
"spec_id" => $spec_v[ 'spec_id' ],
|
||||
"value" => []
|
||||
];
|
||||
foreach ($spec_v[ 'value' ] as $spec_value_k => $spec_value_v) {
|
||||
$goods_spec_format_temp[ $spec_k ] [ 'value' ][ $spec_value_k ] = [
|
||||
"spec_name" => $spec_v[ 'spec_name' ],
|
||||
"spec_id" => $spec_v[ 'spec_id' ],
|
||||
"spec_value_name" => $spec_value_v[ 'spec_value_name' ],
|
||||
"spec_value_id" => $spec_value_v[ 'spec_value_id' ]
|
||||
];
|
||||
if ($spec_value_v[ 'spec_show_type' ] == 2) {
|
||||
$goods_spec_format_temp[ $spec_k ] [ 'value' ][ $spec_value_k ][ 'image' ] = $spec_value_v[ 'spec_value_data' ];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// SKU数据
|
||||
$item[ 'goods_sku_data' ] = [];
|
||||
|
||||
if (!empty($goods_spec_format_temp)) {
|
||||
$item[ 'goods_spec_format' ] = json_encode($goods_spec_format_temp);
|
||||
} else {
|
||||
$item[ 'goods_spec_format' ] = '';
|
||||
}
|
||||
|
||||
|
||||
// 排序:按价格升序
|
||||
$goods_sku_list = $this->getList("ns_goods_sku", [ [ 'goods_id', '=', $item[ 'goods_id' ] ] ], "sku_id,goods_id,sku_name,attr_value_items,market_price, price, promote_price, cost_price, stock, picture, code, weight, volume, sku_img_array", 'price asc');
|
||||
|
||||
foreach ($goods_sku_list as $sku_k => $sku_v) {
|
||||
|
||||
$sku_spec_format = '';
|
||||
if (!empty($sku_v[ 'attr_value_items' ])) {
|
||||
$sku_spec_format = [];
|
||||
$attr_value_items = explode(";", $sku_v[ 'attr_value_items' ]);
|
||||
foreach ($attr_value_items as $attr_value_k => $attr_value_v) {
|
||||
$temp = explode(":", $attr_value_v);
|
||||
$spec_id = $temp[ 0 ];
|
||||
$spec_value_id = $temp[ 1 ];
|
||||
foreach ($goods_spec_format_temp as $spec_temp_k => $spec_temp_v) {
|
||||
if ($spec_temp_v[ 'spec_id' ] == $spec_id) {
|
||||
foreach ($spec_temp_v[ 'value' ] as $spec_temp_value_k => $spec_temp_value_v) {
|
||||
if ($spec_temp_value_v[ 'spec_value_id' ] == $spec_value_id) {
|
||||
$sku_spec_format[] = [
|
||||
"spec_name" => $spec_temp_value_v[ 'spec_name' ],
|
||||
"spec_id" => $spec_id,
|
||||
"spec_value_id" => $spec_value_id,
|
||||
"spec_value_name" => $spec_temp_value_v[ 'spec_value_name' ]
|
||||
];
|
||||
if (!empty($spec_temp_value_v[ 'image' ])) {
|
||||
$sku_spec_format[ count($sku_spec_format) - 1 ][ 'image' ] = $spec_temp_value_v[ 'image' ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pic_id_arr = explode(",", $item[ 'img_id_array' ]);
|
||||
if (!empty($sku_v[ 'sku_img_array' ])) {
|
||||
$pic_id_arr = array_merge(explode(",", $sku_v[ 'sku_img_array' ]), $pic_id_arr);
|
||||
}
|
||||
|
||||
$sku_images = [];
|
||||
$picture_list = $this->getList("sys_album_picture", [ [ 'pic_id', 'in', implode(",", $pic_id_arr) ] ], 'pic_cover');
|
||||
foreach ($picture_list as $picture_list_k => $picture_list_v) {
|
||||
$sku_images[] = $picture_list_v[ 'pic_cover' ];
|
||||
}
|
||||
|
||||
$item[ 'goods_sku_data' ] [] = [
|
||||
'sku_id' => $sku_v[ 'sku_id' ],
|
||||
'site_id' => $this->site_id,
|
||||
'sku_name' => $item[ 'goods_name' ] . ' ' . $sku_v[ 'sku_name' ],
|
||||
'spec_name' => $sku_v[ 'sku_name' ],
|
||||
'sku_no' => $sku_v[ 'code' ],
|
||||
'sku_spec_format' => !empty($sku_spec_format) ? json_encode($sku_spec_format) : "",
|
||||
'price' => $sku_v[ 'price' ],
|
||||
'cost_price' => $sku_v[ 'cost_price' ],
|
||||
'market_price' => $sku_v[ 'market_price' ],
|
||||
'discount_price' => $sku_v[ 'promote_price' ],//sku折扣价(默认等于单价)
|
||||
'is_free_shipping' => $item[ 'shipping_fee' ] == 0 ? 1 : 0,
|
||||
'shipping_template' => 0,//$item[ 'shipping_fee_id' ],
|
||||
'stock' => $sku_v[ 'stock' ],
|
||||
'weight' => $sku_v[ 'weight' ],
|
||||
'volume' => $sku_v[ 'volume' ],
|
||||
'goods_id' => $item[ 'goods_id' ],
|
||||
'goods_class' => $item[ 'goods_type' ],
|
||||
"sku_image" => $sku_images[ 0 ],
|
||||
"sku_images" => implode(",", $sku_images),
|
||||
'collect_num' => $item[ 'collects' ],
|
||||
'click_num' => $item[ 'clicks' ],
|
||||
'goods_content' => $item['description']
|
||||
];
|
||||
}
|
||||
|
||||
$res = $this->addGoods($item);
|
||||
if ($res[ 'code' ] < 0) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要迁移商品数量
|
||||
* @return int
|
||||
*/
|
||||
public function getGoodsCount()
|
||||
{
|
||||
return $this->getCount('ns_goods', [ [ 'goods_type', 'in', '1,2' ] ], 'goods_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品添加
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
private function addGoods($data)
|
||||
{
|
||||
model('goods')->startTrans();
|
||||
|
||||
try {
|
||||
|
||||
$goods_image = $data[ 'goods_image' ];
|
||||
|
||||
$category_id = [];
|
||||
if (!empty($data[ 'category_id_1' ])) {
|
||||
$category_id[] = $data[ 'category_id_1' ];
|
||||
}
|
||||
if (!empty($data[ 'category_id_2' ])) {
|
||||
$category_id[] = $data[ 'category_id_2' ];
|
||||
}
|
||||
if (!empty($data[ 'category_id_3' ])) {
|
||||
$category_id[] = $data[ 'category_id_3' ];
|
||||
}
|
||||
$category_json = '["' . implode(",", $category_id) . '"]';
|
||||
|
||||
$goods_data = array (
|
||||
'goods_image' => $goods_image,
|
||||
'goods_stock' => $data[ 'stock' ],
|
||||
'price' => $data[ 'price' ],
|
||||
'market_price' => $data[ 'market_price' ],
|
||||
'cost_price' => $data[ 'cost_price' ],
|
||||
'goods_spec_format' => $data[ 'goods_spec_format' ],
|
||||
'category_id' => implode(",", $category_id),
|
||||
'category_json' => $category_json,
|
||||
'label_id' => $data[ 'label_id' ],
|
||||
'sku_id' => $data[ 'goods_sku_data' ][ 0 ][ 'sku_id' ]
|
||||
);
|
||||
|
||||
$common_data = array (
|
||||
'goods_id' => $data[ 'goods_id' ],
|
||||
'goods_name' => $data[ 'goods_name' ],
|
||||
'goods_class' => $data[ 'goods_class' ],
|
||||
'goods_class_name' => $data[ 'goods_class_name' ],
|
||||
'goods_attr_class' => $data[ 'goods_attr_class' ],
|
||||
'goods_attr_name' => $data[ 'goods_attr_name' ],
|
||||
'site_id' => $this->site_id,
|
||||
'goods_content' => $data[ 'description' ],
|
||||
'goods_state' => $data[ 'state' ] == 10 ? 0 : $data[ 'state' ],
|
||||
'goods_stock_alarm' => $data[ 'min_stock_alarm' ],
|
||||
'is_free_shipping' => $data[ 'shipping_fee' ] == 0 ? 1 : 0,
|
||||
'shipping_template' => 0,//$data[ 'shipping_fee_id' ],
|
||||
'goods_attr_format' => $data[ 'goods_attr_format' ],
|
||||
'introduction' => $data[ 'introduction' ],
|
||||
'keywords' => $data[ 'keywords' ],
|
||||
'unit' => $data[ 'goods_unit' ],
|
||||
'video_url' => $data[ 'goods_video_address' ],
|
||||
'sort' => $data[ 'sort' ],
|
||||
'goods_service_ids' => '',
|
||||
'virtual_sale' => 0,
|
||||
'max_buy' => $data[ 'max_buy' ],
|
||||
'min_buy' => $data[ 'min_buy' ],
|
||||
'evaluate' => $data[ 'evaluates' ],
|
||||
'sale_num' => $data[ 'sales' ],
|
||||
'create_time' => $data[ 'create_time' ],
|
||||
'modify_time' => $data[ 'update_time' ],
|
||||
'is_virtual' => $data[ 'is_virtual' ],
|
||||
'supplier_id' => $data[ 'supplier_id' ]
|
||||
);
|
||||
|
||||
$goods_id = model('goods')->add(array_merge($goods_data, $common_data));
|
||||
model('goods_sku')->addList($data[ 'goods_sku_data' ]);
|
||||
|
||||
if (!empty($data[ 'goods_spec_format' ])) {
|
||||
// 刷新SKU商品规格项/规格值JSON字符串
|
||||
$goods_model = new GoodsModel();
|
||||
$goods_model->dealGoodsSkuSpecFormat($goods_id, $data[ 'goods_spec_format' ]);
|
||||
}
|
||||
|
||||
// 添加店铺添加统计
|
||||
$stat = new Stat();
|
||||
// $stat->addShopStat([ 'add_goods_count' => 1, 'site_id' => $this->site_id ]);
|
||||
$stat->switchStat(['type' => 'add_goods', 'data' => [ 'add_goods_count' => 1, 'site_id' => $this->site_id ]]);
|
||||
model('goods')->commit();
|
||||
return $this->success($goods_id);
|
||||
} catch (\Exception $e) {
|
||||
model('goods')->rollback();
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移商品分类数据
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
* @return array
|
||||
*/
|
||||
public function getGoodsCategoryList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
|
||||
model("goods_category")->startTrans();
|
||||
|
||||
// 查询v3商品分类表
|
||||
$field = 'category_id, category_name, short_name, pid, level , is_visible, attr_id, attr_name, keywords, description, sort, category_pic';
|
||||
$goods_category_list = $this->getPageList('ns_goods_category', [], $field, $page_index, $page_size);
|
||||
|
||||
if (!empty($goods_category_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空商品分类表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('goods_category')->execute("TRUNCATE TABLE {$prefix}goods_category");
|
||||
}
|
||||
$data = [];
|
||||
foreach ($goods_category_list as $k => $v) {
|
||||
$category_id_1 = 0;
|
||||
$category_id_2 = 0;
|
||||
$category_id_3 = 0;
|
||||
$category_full_name = [];
|
||||
if ($v[ 'level' ] == 1) {
|
||||
$category_id_1 = $v[ 'category_id' ];
|
||||
$category_full_name[] = $v[ 'category_name' ];
|
||||
} elseif ($v[ 'level' ] == 2) {
|
||||
$category_id_2 = $v[ 'category_id' ];
|
||||
$one_category = $this->getInfo("ns_goods_category", [ [ 'category_id', '=', $v[ 'pid' ] ] ], 'category_id,category_name');
|
||||
$category_id_1 = $one_category[ 'category_id' ];
|
||||
|
||||
$category_full_name[] = $one_category[ 'category_name' ];
|
||||
$category_full_name[] = $v[ 'category_name' ];
|
||||
} elseif ($v[ 'level' ] == 3) {
|
||||
$category_id_3 = $v[ 'category_id' ];
|
||||
$two_category = $this->getInfo("ns_goods_category", [ [ 'category_id', '=', $v[ 'pid' ] ] ], 'category_id,pid,category_name');
|
||||
$one_category = $this->getInfo("ns_goods_category", [ [ 'category_id', '=', $two_category[ 'pid' ] ] ], 'category_id,category_name');
|
||||
$category_id_1 = $one_category[ 'category_id' ];
|
||||
$category_id_2 = $two_category[ 'category_id' ];
|
||||
|
||||
$category_full_name[] = $one_category[ 'category_name' ];
|
||||
$category_full_name[] = $two_category[ 'category_name' ];
|
||||
$category_full_name[] = $v[ 'category_name' ];
|
||||
}
|
||||
$data[] = [
|
||||
'category_id' => $v[ 'category_id' ],
|
||||
'site_id' => $this->site_id,
|
||||
'category_name' => $v[ 'category_name' ],
|
||||
'short_name' => $v[ 'short_name' ],
|
||||
'pid' => $v[ 'pid' ],
|
||||
'level' => $v[ 'level' ],
|
||||
'is_show' => $v[ 'is_visible' ],
|
||||
'sort' => $v[ 'sort' ],
|
||||
'image' => $v[ 'category_pic' ],
|
||||
'keywords' => $v[ 'keywords' ],
|
||||
'description' => $v[ 'description' ],
|
||||
'category_id_1' => $category_id_1,
|
||||
'category_id_2' => $category_id_2,
|
||||
'category_id_3' => $category_id_3,
|
||||
'category_full_name' => implode("/", $category_full_name),
|
||||
'image_adv' => '',
|
||||
'commission_rate' => 0
|
||||
];
|
||||
}
|
||||
model("goods_category")->addList($data);
|
||||
}
|
||||
|
||||
model('goods_category')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('goods_category')->rollback();
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要迁移商品分类数量
|
||||
* @return int
|
||||
*/
|
||||
public function getGoodsCategoryCount()
|
||||
{
|
||||
return $this->getCount('ns_goods_category', [], 'category_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移商品标签数据
|
||||
* 丢失数据:上下级、图片、是否显示
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
* @return array
|
||||
*/
|
||||
public function getGoodsLabelList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model("goods_label")->startTrans();
|
||||
|
||||
// 查询v3商品标签表
|
||||
$field = 'group_id, group_name, is_visible, sort, group_dec';
|
||||
$goods_group_list = $this->getPageList('ns_goods_group', [], $field, $page_index, $page_size);
|
||||
|
||||
if (!empty($goods_group_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空商品标签表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('goods_label')->execute("TRUNCATE TABLE {$prefix}goods_label");
|
||||
}
|
||||
$data = [];
|
||||
foreach ($goods_group_list as $k => $v) {
|
||||
$data[] = [
|
||||
'id' => $v[ 'group_id' ],
|
||||
'site_id' => $this->site_id,
|
||||
'label_name' => $v[ 'group_name' ],
|
||||
'desc' => $v[ 'group_dec' ],
|
||||
'create_time' => time(),
|
||||
'update_time' => 0,
|
||||
'sort' => $v[ 'sort' ]
|
||||
];
|
||||
}
|
||||
model("goods_label")->addList($data);
|
||||
}
|
||||
|
||||
model("goods_label")->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model("goods_label")->rollback();
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要迁移商品标签数量
|
||||
* @return int
|
||||
*/
|
||||
public function getGoodsLabelCount()
|
||||
{
|
||||
return $this->getCount('ns_goods_group', [], 'group_id');
|
||||
}
|
||||
|
||||
}
|
||||
83
addon/v3tov4/model/Log.php
Executable file
83
addon/v3tov4/model/Log.php
Executable file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\v3tov4\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* v3Tov4迁移数据日志
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Log extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 添加日志
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addLogList($data)
|
||||
{
|
||||
$res = model("v3_upgrade_log")->addList($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑日志
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editLog($data, $condition = [])
|
||||
{
|
||||
$res = model("v3_upgrade_log")->update($data, $condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除日志
|
||||
* @param $ids
|
||||
* @return array
|
||||
*/
|
||||
public function deleteLog($ids)
|
||||
{
|
||||
$res = model("v3_upgrade_log")->delete([ [ 'id', 'in', $ids ] ]);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新的模块迁移数据
|
||||
* @param $module
|
||||
* @param $status
|
||||
* @return array
|
||||
*/
|
||||
public function getLogFirstData($module, $status)
|
||||
{
|
||||
$res = model("v3_upgrade_log")->getFirstData([ [ 'module', '=', $module ], [ 'status', '=', $status ] ], 'id,module,title,create_time,remark,status', 'create_time desc');
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志分页
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getLogPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc', $field = 'id,module,title,create_time,remark,status')
|
||||
{
|
||||
$list = model('v3_upgrade_log')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
}
|
||||
411
addon/v3tov4/model/Member.php
Executable file
411
addon/v3tov4/model/Member.php
Executable file
@@ -0,0 +1,411 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\v3tov4\model;
|
||||
|
||||
/**
|
||||
* 迁移会员相关数据(会员、等级、标签、收货地址、商品收藏、足迹、账户流水)
|
||||
*/
|
||||
class Member extends Upgrade
|
||||
{
|
||||
/**
|
||||
* 同步会员数据
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
*/
|
||||
public function getMemberList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('member')->startTrans();
|
||||
|
||||
$field = 'su.uid,su.user_name,su.user_password,su.user_headimg,su.user_tel,su.wx_openid,su.real_name,su.sex,su.location,su.nick_name,su.reg_time,su.birthday,su.wx_applet_openid,nma.point,nma.balance,nm.member_level,nm.member_label,nml.level_name,nsma.source_uid,nsma.promoter_id,nsma.is_promoter';
|
||||
$join = [
|
||||
[ 'ns_member_account nma', 'su.uid = nma.uid', 'left' ],
|
||||
[ 'ns_member nm', 'su.uid = nm.uid', 'left' ],
|
||||
[ 'ns_member_level nml', 'nm.member_level = nml.level_id', 'left' ],
|
||||
[ 'nfx_shop_member_association nsma', 'nsma.uid = nm.uid', 'left' ]
|
||||
];
|
||||
// 查询v3会员表
|
||||
$member_list = $this->getPageList('sys_user', [ [ 'is_member', '=', '1' ] ], $field, $page_index, $page_size, 'su', $join);
|
||||
$member_data = [];
|
||||
if (!empty($member_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空会员表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('member')->execute("TRUNCATE TABLE {$prefix}member");
|
||||
}
|
||||
foreach ($member_list as $item) {
|
||||
$member_label = '';
|
||||
if (!empty($item[ 'member_label' ])) {
|
||||
$label_result = $this->query("SELECT GROUP_CONCAT(nml.label_name) AS label_name FROM ns_member_label nml WHERE nml.id IN ({$item['member_label']});");
|
||||
if (!empty($label_result[ 0 ][ 'label_name' ])) $member_label = $label_result[ 0 ][ 'label_name' ];
|
||||
}
|
||||
$member_data[] = [
|
||||
'member_id' => $item['uid'],
|
||||
'site_id' => 1,
|
||||
'source_member' => $item['source_uid'] ?? 0,
|
||||
'fenxiao_id' => $item['promoter_id'] ?? 0,
|
||||
'is_fenxiao' => $item['is_promoter'] ?? 0,
|
||||
'username' => $item['user_name'],
|
||||
'nickname' => $item['nick_name'],
|
||||
'mobile' => $item['user_tel'],
|
||||
'password' => md5($item['user_password'] . 'NiuCloud'),
|
||||
'headimg' => $item['user_headimg'],
|
||||
'member_level' => $item['member_level'],
|
||||
'member_level_name' => $item['level_name'],
|
||||
'member_label' => $item['member_label'],
|
||||
'member_label_name' => $member_label,
|
||||
'wx_openid' => $item['wx_openid'],
|
||||
'weapp_openid' => $item['wx_applet_openid'],
|
||||
'realname' => $item['real_name'],
|
||||
'sex' => $item['sex'],
|
||||
'location' => $item['location'],
|
||||
'birthday' => $item['birthday'],
|
||||
'reg_time' => $item['reg_time'],
|
||||
'point' => is_null($item['point']) ? 0 : $item['point'],
|
||||
'balance' => is_null($item['balance']) ? 0 : $item['balance']
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4会员表
|
||||
model('member')->addList($member_data);
|
||||
model('member')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('member')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的会员的数量
|
||||
*/
|
||||
public function getMemberCount()
|
||||
{
|
||||
return $this->getCount('sys_user', [ [ 'is_member', '=', '1' ] ], 'uid');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步会员等级数据
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
*/
|
||||
public function getMemberLevelList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('member_level')->startTrans();
|
||||
|
||||
$field = 'level_id,level_name,level,desc,is_default,goods_discount,give_point,give_money';
|
||||
// 查询v3会员等级表
|
||||
$level_list = $this->getPageList('ns_member_level', [], $field, $page_index, $page_size);
|
||||
$level_data = [];
|
||||
if (!empty($level_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空会员等级表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('member_level')->execute("TRUNCATE TABLE {$prefix}member_level");
|
||||
}
|
||||
foreach ($level_list as $item) {
|
||||
$level_data[] = [
|
||||
'level_id' => $item['level_id'],
|
||||
'site_id' => 1,
|
||||
'level_name' => $item['level_name'],
|
||||
'sort' => $item['level'],
|
||||
'remark' => $item['desc'],
|
||||
'is_default' => $item['is_default'],
|
||||
'consume_discount' => $item['goods_discount'] * 100,
|
||||
'send_point' => $item['give_point'],
|
||||
'send_balance' => $item['give_money'],
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4会员等级表
|
||||
model('member_level')->addList($level_data);
|
||||
model('member_level')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('member_level')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的会员等级的数量
|
||||
*/
|
||||
public function getMemberLevelCount()
|
||||
{
|
||||
return $this->getCount('ns_member_level', [], 'level_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步会员标签数据
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
*/
|
||||
public function getMemberLabelList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('member_label')->startTrans();
|
||||
|
||||
$field = 'id,label_name,create_time,desc';
|
||||
// 查询v3会员标签表
|
||||
$label_list = $this->getPageList('ns_member_label', [], $field, $page_index, $page_size);
|
||||
$label_data = [];
|
||||
if (!empty($label_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空会员标签表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('member_level')->execute("TRUNCATE TABLE {$prefix}member_label");
|
||||
}
|
||||
foreach ($label_list as $item) {
|
||||
$label_data[] = [
|
||||
'label_id' => $item['id'],
|
||||
'site_id' => 1,
|
||||
'label_name' => $item['label_name'],
|
||||
'create_time' => $item['create_time'],
|
||||
'remark' => $item['desc']
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4会员标签表
|
||||
model('member_label')->addList($label_data);
|
||||
model('member_label')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('member_label')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的会员标签的数量
|
||||
*/
|
||||
public function getMemberLabelCount()
|
||||
{
|
||||
return $this->getCount('ns_member_label', [], 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步会员收货地址数据
|
||||
*/
|
||||
public function getMemberAddressList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('member_address')->startTrans();
|
||||
|
||||
$join = [
|
||||
[ 'sys_province sp', 'sp.province_id = nmea.province', 'left' ],
|
||||
[ 'sys_city sc', 'sc.city_id = nmea.city', 'left' ],
|
||||
[ 'sys_district sd', 'sd.district_id = nmea.district', 'left' ],
|
||||
];
|
||||
$field = 'nmea.id,nmea.uid,nmea.consigner,nmea.mobile,nmea.phone,nmea.address,nmea.is_default,sp.province_name,sc.city_name,sd.district_name';
|
||||
// 查询v3会员收货地址表
|
||||
$address_list = $this->getPageList('ns_member_express_address', [], $field, $page_index, $page_size, 'nmea', $join);
|
||||
$address_data = [];
|
||||
if (!empty($address_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空会员收货地址表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('member_address')->execute("TRUNCATE TABLE {$prefix}member_address");
|
||||
}
|
||||
foreach ($address_list as $item) {
|
||||
$province_info = model('area')->getInfo([ [ 'name', 'like', '%' . $item[ 'province_name' ] . '%' ], [ 'level', '=', 1 ] ], 'id,name');
|
||||
$city_info = model('area')->getInfo([ [ 'name', 'like', '%' . $item[ 'city_name' ] . '%' ], [ 'level', '=', 2 ] ], 'id,name');
|
||||
$district_info = model('area')->getInfo([ [ 'name', 'like', '%' . $item[ 'district_name' ] . '%' ], [ 'level', '=', 3 ] ], 'id,name');
|
||||
$full_address = ( $province_info[ 'name' ] ?? '' ) . ' ' . ( $city_info[ 'name' ] ?? '' ) . ' ' . ( $district_info[ 'name' ] ?? '' ) . ' ' . $item[ 'address' ];
|
||||
$address_data[] = [
|
||||
'id' => $item['id'],
|
||||
'member_id' => $item['uid'],
|
||||
'site_id' => 1,
|
||||
'name' => $item['consigner'],
|
||||
'mobile' => $item['mobile'],
|
||||
'telephone' => $item['phone'],
|
||||
'province_id' => $province_info['id'] ?? 0,
|
||||
'city_id' => $city_info['id'] ?? 0,
|
||||
'district_id' => $district_info['id'] ?? 0,
|
||||
'community_id' => 0,
|
||||
'address' => $item['address'],
|
||||
'full_address' => $full_address,
|
||||
'is_default' => $item['is_default']
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4会员收货地址表
|
||||
model('member_address')->addList($address_data);
|
||||
model('member_address')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('member_address')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的会员收货地址的数量
|
||||
*/
|
||||
public function getMemberAddressCount()
|
||||
{
|
||||
return $this->getCount('ns_member_express_address', [], 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步会员商品收藏数据
|
||||
*/
|
||||
public function getMemberCollectList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('goods_collect')->startTrans();
|
||||
|
||||
$field = 'uid,fav_id,goods_name,goods_image,fav_time';
|
||||
// 查询v3会员收藏表
|
||||
$label_list = $this->getPageList('ns_member_favorites', [ [ 'fav_type', '=', 'goods' ] ], $field, $page_index, $page_size);
|
||||
$label_data = [];
|
||||
if (!empty($label_list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空会员收藏表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('goods_collect')->execute("TRUNCATE TABLE {$prefix}goods_collect");
|
||||
}
|
||||
foreach ($label_list as $item) {
|
||||
$label_data[] = [
|
||||
'member_id' => $item['uid'],
|
||||
'goods_id' => $item['fav_id'],
|
||||
'sku_name' => $item['goods_name'],
|
||||
'sku_image' => $item['goods_image'],
|
||||
'create_time' => $item['fav_time'],
|
||||
'site_id' => 1
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4会员收藏表
|
||||
model('goods_collect')->addList($label_data);
|
||||
model('goods_collect')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('goods_collect')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的会员商品收藏的数量
|
||||
*/
|
||||
public function getMemberCollectCount()
|
||||
{
|
||||
return $this->getCount('ns_member_favorites', [ [ 'fav_type', '=', 'goods' ] ], 'log_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步会员足迹数据
|
||||
*/
|
||||
public function getMemberBrowseList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('goods_browse')->startTrans();
|
||||
|
||||
$field = 'uid,create_time,goods_id';
|
||||
// 查询v3会员足迹表
|
||||
$list = $this->getPageList('ns_goods_browse', [], $field, $page_index, $page_size);
|
||||
$data = [];
|
||||
if (!empty($list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空会员足迹表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('goods_browse')->execute("TRUNCATE TABLE {$prefix}goods_browse");
|
||||
}
|
||||
foreach ($list as $item) {
|
||||
$sku_info = $this->getInfo('ns_goods_sku', [ [ 'goods_id', '=', $item[ 'goods_id' ] ] ], 'sku_id');
|
||||
$data[] = [
|
||||
'member_id' => $item['uid'],
|
||||
'browse_time' => $item['create_time'],
|
||||
'site_id' => 1,
|
||||
'sku_id' => $sku_info['sku_id'] ?? 0,
|
||||
'goods_id' => $item['goods_id']
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4会员足迹表
|
||||
model('goods_browse')->addList($data);
|
||||
model('goods_browse')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('goods_browse')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的会员足迹的数量
|
||||
*/
|
||||
public function getMemberBrowseCount()
|
||||
{
|
||||
return $this->getCount('ns_goods_browse', [], 'browse_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步会员账户流水
|
||||
* @param $page_index
|
||||
* @param $page_size
|
||||
* @return array
|
||||
*/
|
||||
public function getMemberAccountRecordList($page_index, $page_size)
|
||||
{
|
||||
try {
|
||||
model('member_account')->startTrans();
|
||||
|
||||
$join = [
|
||||
[ 'sys_user su', 'su.uid = nmar.uid', 'left' ]
|
||||
];
|
||||
$field = 'nmar.uid,nmar.account_type,nmar.number,nmar.from_type,nmar.text,nmar.create_time,su.user_name,su.user_tel';
|
||||
// 查询v3会员账户流水表
|
||||
$list = $this->getPageList('ns_member_account_records', [ [ 'account_type', 'in', [ 1, 2 ] ] ], $field, $page_index, $page_size, 'nmar', $join);
|
||||
$data = [];
|
||||
if (!empty($list)) {
|
||||
if ($page_index == 1) {
|
||||
// 首次清空会员账户流水表
|
||||
$prefix = config("database")[ "connections" ][ "mysql" ][ "prefix" ];
|
||||
model('member_account')->execute("TRUNCATE TABLE {$prefix}member_account");
|
||||
}
|
||||
foreach ($list as $item) {
|
||||
$from_type = [ 'type' => '', 'name' => '' ];
|
||||
$data[] = [
|
||||
'site_id' => 1,
|
||||
'member_id' => $item['uid'],
|
||||
'account_type' => $item['account_type'] == 1 ? 'point' : 'balance',
|
||||
'account_data' => $item['number'],
|
||||
'from_type' => $from_type['type'],
|
||||
'type_name' => $from_type['name'],
|
||||
'remark' => $item['text'],
|
||||
'create_time' => $item['create_time'],
|
||||
'username' => $item['user_name'],
|
||||
'mobile' => $item['user_tel'],
|
||||
];
|
||||
}
|
||||
}
|
||||
// 添加到v4会员账户流水表
|
||||
model('member_account')->addList($data);
|
||||
model('member_account')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('member_account')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要同步的会员账户流水的数量
|
||||
*/
|
||||
public function getMemberAccountRecordCount()
|
||||
{
|
||||
return $this->getCount('ns_member_account_records', [ [ 'account_type', 'in', [ 1, 2 ] ] ], 'id');
|
||||
}
|
||||
|
||||
}
|
||||
386
addon/v3tov4/model/Upgrade.php
Executable file
386
addon/v3tov4/model/Upgrade.php
Executable file
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\v3tov4\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* V3版本升级
|
||||
*/
|
||||
class Upgrade extends BaseModel
|
||||
{
|
||||
private $db = 'v3';
|
||||
|
||||
private $task_class = [
|
||||
'goods' => [
|
||||
'name' => '商品',
|
||||
'class' => 'addon\v3tov4\model\Goods',
|
||||
'is_show' => 1,
|
||||
'introduction' => '迁移商品、商品分类、商品标签等数据',
|
||||
'desc' => <<<EOT
|
||||
变动说明
|
||||
1、商品标签(ns_goods_group)转移到商品分组(ns_goods_label),丢失图片
|
||||
2、商品分类(ns_goods_category),废弃pc端模板、手机端模板设置、是否显示、关联商品类型ID,完善上下级关联字段
|
||||
3、相册图片直接查询存表
|
||||
4、丢失商品类型数据
|
||||
5、丢失商品评价数据
|
||||
6、丢失回收站数据
|
||||
7、丢失阶梯优惠数据
|
||||
8、丢失积分设置
|
||||
9、丢失会员折扣
|
||||
10、丢失分销设置
|
||||
11、丢失卡券商品
|
||||
12、丢失网盘以及下载商品
|
||||
13、丢失商品品牌,已废弃
|
||||
14、丢失商品规格
|
||||
15、ns_goods表字段变动说明
|
||||
1、移除brand_id,品牌id
|
||||
2、category_id_1、category_id_2、category_id_3合并到category_id、category_json字段
|
||||
3、promotion_price转移到ns_goods_sku表中的discount_price字段
|
||||
4、移除point_exchange_type、point_exchange,积分兑换字段
|
||||
5、移除give_point字段,购买商品赠送积分
|
||||
6、移除shop_id字段,店铺id
|
||||
7、移除is_member_discount字段,参与会员折扣
|
||||
8、shipping_fee对应is_free_shipping字段,是否免邮
|
||||
9、shipping_fee_id对应shipping_template字段,指定运费模板id
|
||||
10、stock对应goods_stock字段,商品库存
|
||||
11、min_stock_alarm对应goods_stock_alarm字段,库存预警
|
||||
12、移除star字段,好评星级
|
||||
13、移除shares字段,分享数
|
||||
14、evaluates对应evaluate字段,评价数
|
||||
15、移除province_id、city_id,地区id字段
|
||||
16、picture对应goods_image字段,商品主图路径
|
||||
17、goods_content对应description字段,商品详情
|
||||
18、移除QRcode字段,商品二维码
|
||||
19、移除is_stock_visible字段,页面不显示库存
|
||||
20、移除is_hot字段,是否热销商品
|
||||
21、移除is_recommend字段,是否推荐
|
||||
22、移除is_new字段,是否新品
|
||||
23、移除is_pre_sale字段,是否预售
|
||||
24、移除is_bill字段,是否开具增值税发票
|
||||
25、移除img_id_array字段,商品图片序列
|
||||
26、移除sku_img_array字段,商品sku应用图片列表
|
||||
27、移除match_point、match_ratio字段,实物与描述相符(根据评价计算)、百分比
|
||||
28、移除real_sales字段,实际销量
|
||||
29、goods_weight转移到ns_goods_sku表中的weight字段,重量(单位g)
|
||||
30、goods_volume转移到ns_goods_sku表中的volume字段,体积(单位立方米)
|
||||
31、移除shipping_fee_type字段,计价方式1.重量2.体积3.计件
|
||||
32、移除extend_category_id、extend_category_id_1、extend_category_id_2、extend_category_id_3字段
|
||||
33、移除production_date字段,生产日期
|
||||
34、移除shelf_life字段,保质期
|
||||
35、移除pc_custom_template字段,pc端商品自定义模板
|
||||
36、移除wap_custom_template字段,wap端商品自定义模板
|
||||
37、goods_video_address对应video_url字段,视频
|
||||
38、移除max_use_point字段,积分抵现最大可用积分数
|
||||
39、移除is_open_presell字段,是否支持预售
|
||||
40、移除presell_time、presell_day字段,预售发货时间/天数
|
||||
41、移除presell_delivery_type字段,预售发货方式1
|
||||
42、移除presell_price字段,预售金额
|
||||
43、goods_unit对应unit字段,单位
|
||||
44、移除decimal_reservation_number字段,价格保留方式 0 去掉角和分,1去掉分,2 保留角和分
|
||||
45、移除integral_give_type字段,积分赠送类型 0固定值 1按比率
|
||||
16、ns_goods_sku表字段变动说明
|
||||
1、promote_price对应discount_price字段,促销价格
|
||||
2、移除QRcode字段,商品二维码
|
||||
3、移除sku_img_array字段,sku图片序列
|
||||
4、移除extend_json字段,虚拟扩展
|
||||
EOT
|
||||
],
|
||||
'member' => [
|
||||
'name' => '会员',
|
||||
'class' => 'addon\v3tov4\model\Member',
|
||||
'is_show' => 1,
|
||||
'introduction' => '迁移会员、等级、标签、收货地址、商品收藏、足迹、账户流水等数据',
|
||||
'desc' => <<<EOT
|
||||
变动说明
|
||||
1、丢失会员账户数据
|
||||
2、会员主表 数据表: sys_user -> ns_member
|
||||
1、member_id 由 v3 sys_user uid对应转入
|
||||
2、source_member 来源会员id 查询v3 nfx_shop_member_association
|
||||
3、fenxiao_id 分销商id 查询会员是否是分销商 是则为自身分销商id 否查询上级分销商
|
||||
4、username 由 v3 sys_user user_name 字段对应转入
|
||||
5、nickname 由 v3 sys_user nick_name 字段对应转入
|
||||
6、mobile 由 v3 sys_user user_tel 字段对应转入
|
||||
7、email 由 v3 sys_user user_email 字段对应转入
|
||||
8、password 由 v3 sys_user user_password 字段对应转入
|
||||
9、headimg 头像需从v3站点进行拉取
|
||||
10、member_level、member_level_name、member_label、member_label_name 这些字段需关联v3 ns_member 查询到 会员等级 会员标签 去这两表中查询
|
||||
11、wx_openid 公众号openid v3 sys_user wx_openid 字段对应转入
|
||||
12、weapp_openid 小程序openid v3 sys_user wx_applet_openid 字段对应转入
|
||||
13、realname 由v3 sys_user real_name 字段对应转入
|
||||
14、sex 由v3 sys_user sex 字段对应转入
|
||||
15、location 由v3 sys_user location 字段对应转入
|
||||
16、birthday 由v3 sys_user birthday 字段对应转入
|
||||
17、reg_time 由v3 sys_user reg_time 字段对应转入
|
||||
18、point 积分 由v3 ns_member_account point 字段对应转入
|
||||
19、balance 储值余额 由v3 ns_member_account balance 字段对应转入
|
||||
EOT
|
||||
],
|
||||
'fenxiao' => [
|
||||
'name' => '分销',
|
||||
'class' => 'addon\v3tov4\model\Fenxiao',
|
||||
'introduction' => '迁移分销商、分销商等级等数据',
|
||||
'is_show' => 0,
|
||||
'desc' => <<<EOT
|
||||
变动说明
|
||||
1、分销商 数据表:nfx_promoter -> ns_fenxiao
|
||||
1、fenxiao_id 由v3 nfx_promoter promoter_id 字段对应转入
|
||||
2、fenxiao_no 按v4分销商编号生成规则生成
|
||||
3、fenxiao_name 由v3 nfx_promoter promoter_shop_name 字段对应转入
|
||||
4、mobile 由v3 nfx_promoter balance 字段对应转入
|
||||
5、member_id 由v3 nfx_promoter uid 字段对应转入
|
||||
6、level_id 由v3 nfx_promoter promoter_level 字段对应转入
|
||||
7、level_name 查询对应分销商等级名称
|
||||
8、parent 由v3 nfx_promoter parent_promoter 字段对应转入
|
||||
9、grand_parent 查询上上级分销商id
|
||||
10、account 当前佣金 由v3 nfx_promoter (commossion_total - commission_cash) 总佣金 - 已提现佣金
|
||||
11、account_withdraw 已提现佣金 由v3 nfx_promoter commission_cash 字段对应转入
|
||||
12、create_time 由v3 nfx_promoter audit_time 字段对应转入
|
||||
13、total_commission 累计佣金 由v3 nfx_promoter commossion_total 字段对应转入
|
||||
2、分销商申请 数据表:nfx_promoter -> ns_fenxiao_apply
|
||||
1、fenxiao_name 由v3 nfx_promoter promoter_shop_name 字段对应转入
|
||||
2、parent 由v3 nfx_promoter parent_promoter 字段对应转入
|
||||
3、member_id 由v3 nfx_promoter uid 字段对应转入
|
||||
4、mobile 查询会员相应数据
|
||||
5、nickname 查询会员相应数据
|
||||
6、headimg 查询会员相应数据
|
||||
7、level_id 由v3 nfx_promoter promoter_level 字段对应转入
|
||||
8、level_name 查询相应分销商等级名称
|
||||
9、create_time 由v3 nfx_promoter regidter_time 字段对应转入
|
||||
3、分销等级数据表:nfx_promoter_level -> ns_fenxiao_level
|
||||
1、level_id 由v3 nfx_promoter_level level_id 字段对应转入
|
||||
2、level_name 由v3 nfx_promoter_level level_name 字段对应转入
|
||||
3、one_rate 由v3 nfx_promoter_level level_0 字段对应转入
|
||||
4、two_rate 由v3 nfx_promoter_level level_1 字段对应转入
|
||||
5、three_rate 由v3 nfx_promoter_level level_2 字段对应转入
|
||||
6、create_time 由v3 nfx_promoter_level create_time 字段对应转入
|
||||
4、分销商品 (规则不同不做迁移)
|
||||
EOT
|
||||
],
|
||||
// 'order' => [
|
||||
// 'name' => '订单',
|
||||
// 'class' => 'addon\v3tov4\model\Goods'
|
||||
// ]
|
||||
];
|
||||
|
||||
private $page_size = 10;
|
||||
|
||||
/**
|
||||
* 获取数据迁移项
|
||||
* @return array
|
||||
*/
|
||||
public function getTaskClass()
|
||||
{
|
||||
return $this->task_class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分页
|
||||
* @return int
|
||||
*/
|
||||
public function getPageSize()
|
||||
{
|
||||
return $this->page_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分页列表
|
||||
* @param $table
|
||||
* @param $where
|
||||
* @param $page
|
||||
* @param $page_size
|
||||
* @param $ailas
|
||||
* @param $join
|
||||
*/
|
||||
final protected function getPageList($table, $where = [], $field = '*', $page = 1, $page_size = 10, $alias = '', $join = null)
|
||||
{
|
||||
$table = Db::connect($this->db)->table($table);
|
||||
if (!empty($join)) {
|
||||
$table = $this->parseJoin($table, $join);
|
||||
}
|
||||
$list = $table->alias($alias)->where($where)->field($field)->limit($page_size)->page($page)->select()->toArray();
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
* @param $table
|
||||
* @param array $where
|
||||
* @param string $field
|
||||
* @param string $alias
|
||||
* @param null $join
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
final protected function getList($table, $where = [], $field = '*', $order = "", $alias = '', $join = null)
|
||||
{
|
||||
$table = Db::connect($this->db)->table($table);
|
||||
if (!empty($join)) {
|
||||
$table = $this->parseJoin($table, $join);
|
||||
}
|
||||
$list = $table->alias($alias)->where($where)->order($order)->field($field)->select()->toArray();
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单条数据
|
||||
* @param $table
|
||||
* @param array $where
|
||||
* @param string $field
|
||||
* @param string $alias
|
||||
* @param null $join
|
||||
* @return mixed
|
||||
*/
|
||||
final protected function getInfo($table, $where = [], $field = '*', $alias = 'a', $join = null)
|
||||
{
|
||||
$table = Db::connect($this->db)->table($table);
|
||||
if (!empty($join)) {
|
||||
$table = $this->parseJoin($table, $join);
|
||||
}
|
||||
$info = $table->alias($alias)->where($where)->field($field)->find();
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* sql查询
|
||||
* @param $sql
|
||||
* @return mixed
|
||||
*/
|
||||
final protected function query($sql)
|
||||
{
|
||||
$res = Db::connect($this->db)->query($sql);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数量
|
||||
* @param $table
|
||||
* @param array $where
|
||||
* @param string $field
|
||||
*/
|
||||
final protected function getCount($table, $where = [], $field = '*')
|
||||
{
|
||||
$table = Db::connect($this->db)->table($table);
|
||||
$count = $table->where($where)->count($field);
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* join分析
|
||||
* @access protected
|
||||
* @param array $join
|
||||
* @param array $options 查询条件
|
||||
* @return string
|
||||
*/
|
||||
final protected function parseJoin($db_obj, $join)
|
||||
{
|
||||
foreach ($join as $item) {
|
||||
list($table, $on, $type) = $item;
|
||||
$type = strtolower($type);
|
||||
switch ( $type ) {
|
||||
case "left":
|
||||
$db_obj = $db_obj->leftJoin($table, $on);
|
||||
break;
|
||||
case "inner":
|
||||
$db_obj = $db_obj->join($table, $on);
|
||||
break;
|
||||
case "right":
|
||||
$db_obj = $db_obj->rightjoin($table, $on);
|
||||
break;
|
||||
case "full":
|
||||
$db_obj = $db_obj->fulljoin($table, $on);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $db_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据同步任务列表
|
||||
*/
|
||||
public function getSyncTask($class)
|
||||
{
|
||||
$task_class = [];
|
||||
$class_array = explode(',', $class);
|
||||
foreach ($class_array as $item) {
|
||||
if (isset($this->task_class[ $item ])) {
|
||||
array_push($task_class, $this->task_class[ $item ][ 'class' ]);
|
||||
if ($item == 'member') {
|
||||
array_push($task_class, $this->task_class[ 'fenxiao' ][ 'class' ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
$methods = $this->getTaskMethod($task_class);
|
||||
$task = [];
|
||||
foreach ($methods as $method => $class_name) {
|
||||
$class = new $class_name();
|
||||
$count = $class->$method();
|
||||
if ($count > 0) {
|
||||
for ($i = 0; $i < ceil(( $count / $this->page_size )); $i++) {
|
||||
array_push($task, [
|
||||
'class' => $class_name,
|
||||
'method' => str_replace('Count', 'List', $method),
|
||||
'page' => $i + 1,
|
||||
'page_size' => $this->page_size
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $task;
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行任务
|
||||
*/
|
||||
public function run($task)
|
||||
{
|
||||
try {
|
||||
|
||||
[ 'class' => $class_name, 'method' => $method, 'page' => $page, 'page_size' => $page_size ] = $task;
|
||||
$class = new $class_name();
|
||||
$res = $class->$method($page, $page_size);
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类中的方法
|
||||
* @param $class_array
|
||||
* @return array
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
private function getTaskMethod($class_array)
|
||||
{
|
||||
$method_array = [];
|
||||
foreach ($class_array as $class_name) {
|
||||
$class = new \ReflectionClass($class_name);
|
||||
$methods = $class->getMethods();
|
||||
foreach ($methods as $method) {
|
||||
if (strpos($method->name, 'Count') !== false && $method->name != 'getCount') {
|
||||
$method_array[ $method->name ] = $method->class;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $method_array;
|
||||
}
|
||||
}
|
||||
271
addon/v3tov4/shop/controller/Upgrade.php
Executable file
271
addon/v3tov4/shop/controller/Upgrade.php
Executable file
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\v3tov4\shop\controller;
|
||||
|
||||
use addon\v3tov4\model\Log;
|
||||
use app\model\system\Database;
|
||||
use app\shop\controller\BaseShop;
|
||||
use addon\v3tov4\model\Upgrade as UpgradeModel;
|
||||
use addon\v3tov4\model\Log as LogModel;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 升级
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Upgrade extends BaseShop
|
||||
{
|
||||
/**
|
||||
* 数据迁移
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$log = new LogModel();
|
||||
$upgrade = new UpgradeModel();
|
||||
$task_class = $upgrade->getTaskClass();
|
||||
|
||||
if (request()->isJson()) {
|
||||
$index = input('index', -1);
|
||||
$class = input('class', '');
|
||||
|
||||
if ($index == -1) {
|
||||
// 添加迁移日志
|
||||
$class_array = explode(',', $class);
|
||||
$log_data = [];
|
||||
foreach ($class_array as $k => $v) {
|
||||
if ($task_class[ $v ][ 'is_show' ]) {
|
||||
$log_data[] = [
|
||||
'module' => $v,
|
||||
'title' => $task_class[ $v ][ 'name' ],
|
||||
'remark' => $task_class[ $v ][ 'introduction' ],
|
||||
'create_time' => time()
|
||||
];
|
||||
}
|
||||
}
|
||||
$log->addLogList($log_data);
|
||||
$task_list = $upgrade->getSyncTask($class);
|
||||
if (empty($task_list[ 'code' ])) {
|
||||
Cache::set('upgrade_error_task', '');
|
||||
}
|
||||
Cache::set('upgrade_task', $task_list);
|
||||
} else {
|
||||
$task_list = Cache::get('upgrade_task');
|
||||
$run_res = $upgrade->run($task_list[ $index ]);
|
||||
if ($run_res[ 'code' ] < 0) {
|
||||
$task_error_list = Cache::get('upgrade_error_task');
|
||||
if (empty($task_error_list)) {
|
||||
$task_error_list = [
|
||||
'data' => $task_list[ $index ],
|
||||
'error' => $run_res[ 'message' ]
|
||||
];
|
||||
} else {
|
||||
array_push($task_error_list, [ 'data' => $task_list[ $index ], 'error' => $run_res[ 'message' ] ]);
|
||||
}
|
||||
Cache::set('upgrade_error_task', $task_error_list);
|
||||
}
|
||||
}
|
||||
$task_error_list = Cache::get('upgrade_error_task');
|
||||
if (!empty($task_list[ 'code' ])) {
|
||||
return error(-1, $task_list[ 'message' ]);
|
||||
} elseif (!empty($task_error_list)) {
|
||||
$count = 0;
|
||||
foreach ($task_error_list as $k => $v) {
|
||||
if (!empty($v[ 'error' ])) {
|
||||
return error(-1, $v[ 'error' ]);
|
||||
} else {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if ($count == count($task_error_list)) {
|
||||
return success(0, '', [ 'index' => $index, 'total' => count($task_list), 'page_size' => $upgrade->getPageSize() ]);
|
||||
}
|
||||
} else {
|
||||
return success(0, '', [ 'index' => $index, 'total' => count($task_list), 'page_size' => $upgrade->getPageSize() ]);
|
||||
}
|
||||
} else {
|
||||
$this->assign('task_class', $task_class);
|
||||
return $this->fetch("upgrade/index");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份数据库
|
||||
*/
|
||||
public function backupSql()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
try {
|
||||
$upgrade_no = date('YmdHi');
|
||||
|
||||
$database = new Database();
|
||||
ini_set('memory_limit', '500M');
|
||||
$size = 300;
|
||||
$volumn = 1024 * 1024 * 2;
|
||||
$dump = '';
|
||||
$last_table = input('last_table', '');
|
||||
$series = max(1, input('series', 1));
|
||||
if (empty($last_table)) {
|
||||
$catch = true;
|
||||
} else {
|
||||
$catch = false;
|
||||
}
|
||||
$back_sql_root = "upload/backup/{$upgrade_no}/sql";
|
||||
if (!is_dir($back_sql_root)) {
|
||||
dir_mkdir($back_sql_root);
|
||||
}
|
||||
$tables = $database->getDatabaseList();
|
||||
if (empty($tables)) {
|
||||
return success();
|
||||
}
|
||||
foreach ($tables as $table) {
|
||||
$table = array_shift($table);
|
||||
if (!empty($last_table) && $table == $last_table) {
|
||||
$catch = true;
|
||||
}
|
||||
if (!$catch) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($dump)) {
|
||||
$dump .= "\n\n";
|
||||
}
|
||||
if ($table != $last_table) {
|
||||
$row = $database->getTableSchemas($table);
|
||||
$dump .= $row;
|
||||
}
|
||||
$index = 0;
|
||||
if (!empty(input('index'))) {
|
||||
$index = input('index');
|
||||
}
|
||||
//枚举所有表的INSERT语句
|
||||
while (true) {
|
||||
$start = $index * $size;
|
||||
$result = $database->getTableInsertSql($table, $start, $size);
|
||||
if (!empty($result)) {
|
||||
$dump .= $result[ 'data' ];
|
||||
if (strlen($dump) > $volumn) {
|
||||
$bakfile = "{$back_sql_root}/backup-{$series}.sql";
|
||||
$dump .= "\n\n";
|
||||
file_put_contents($bakfile, $dump);
|
||||
++$series;
|
||||
++$index;
|
||||
$current = array (
|
||||
'is_backup_end' => 0,
|
||||
'last_table' => $table,
|
||||
'index' => $index,
|
||||
'series' => $series,
|
||||
);
|
||||
$current_series = $series - 1;
|
||||
return success(0, '正在导出数据, 请不要关闭浏览器, 当前第 ' . $current_series . ' 卷.', $current);
|
||||
}
|
||||
}
|
||||
if (empty($result) || count($result[ 'result' ]) < $size) {
|
||||
break;
|
||||
}
|
||||
++$index;
|
||||
}
|
||||
}
|
||||
$back_file = "{$back_sql_root}/backup-{$series}.sql";
|
||||
$dump .= "\n\n----MySQL Dump End";
|
||||
file_put_contents($back_file, $dump);
|
||||
return success(0, '数据库备份完成', [ 'is_backup_end' => 1 ]);
|
||||
} catch (\Exception $e) {
|
||||
return error(-1, $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新的模块迁移状态,防止重复迁移
|
||||
* @return array
|
||||
*/
|
||||
public function checkModuleIsUpgrade()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$log = new LogModel();
|
||||
$upgrade = new UpgradeModel();
|
||||
$task_class = $upgrade->getTaskClass();
|
||||
$module = input('module', '');
|
||||
if (!empty($module)) {
|
||||
$module_arr = explode(",", $module);
|
||||
$res = [];
|
||||
foreach ($module_arr as $k => $v) {
|
||||
if ($task_class[ $v ][ 'is_show' ]) {
|
||||
$item = $log->getLogFirstData($v, 1);
|
||||
$res[] = [
|
||||
'module' => $v,
|
||||
'title' => $task_class[ $v ][ 'name' ],
|
||||
'count' => (int) ( $item[ 'data' ] )
|
||||
];
|
||||
}
|
||||
}
|
||||
return success(0, '', $res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新迁移日志状态
|
||||
* @return array
|
||||
*/
|
||||
public function updateLogStatus()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$log = new LogModel();
|
||||
$upgrade = new UpgradeModel();
|
||||
$task_class = $upgrade->getTaskClass();
|
||||
$module = input('module', '');
|
||||
if (!empty($module)) {
|
||||
$module_arr = explode(",", $module);
|
||||
$res = success(0, '', 0);
|
||||
foreach ($module_arr as $k => $v) {
|
||||
if ($task_class[ $v ][ 'is_show' ]) {
|
||||
$log_info = $log->getLogFirstData($v, 0);
|
||||
$log_info = $log_info[ 'data' ];
|
||||
if (!empty($log_info)) {
|
||||
$edit_res = $log->editLog([ 'status' => 1 ], [ [ 'id', '=', $log_info[ 'id' ] ] ]);
|
||||
$res[ 'data' ] = $edit_res[ 'data' ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function log()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$log = new LogModel();
|
||||
$page = input('page', 1);
|
||||
$page_size = input('page_size', PAGE_LIST_ROWS);
|
||||
$condition = [];
|
||||
$list = $log->getLogPageList($condition, $page, $page_size);
|
||||
return $list;
|
||||
} else {
|
||||
return $this->fetch("upgrade/log");
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteLog()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$ids = input('ids', '');
|
||||
if (!empty($ids)) {
|
||||
$log = new LogModel();
|
||||
$res = $log->deleteLog($ids);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
addon/v3tov4/shop/view/public/img/migration_new.png
Executable file
BIN
addon/v3tov4/shop/view/public/img/migration_new.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
addon/v3tov4/shop/view/public/img/migration_select.png
Executable file
BIN
addon/v3tov4/shop/view/public/img/migration_select.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
316
addon/v3tov4/shop/view/upgrade/index.html
Executable file
316
addon/v3tov4/shop/view/upgrade/index.html
Executable file
@@ -0,0 +1,316 @@
|
||||
<style>
|
||||
.js-migrate-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.progress-bar-wrap .layui-input-block {
|
||||
padding-top: 11px;
|
||||
min-height: initial;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 10px;
|
||||
background: #e8e8e8;
|
||||
width: 60%;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-bar .curr {
|
||||
content: '';
|
||||
background: var(--base-color);
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.progress-bar .value {
|
||||
position: absolute;
|
||||
right: -70px;
|
||||
top: -3px;
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
.js-save[disabled] {
|
||||
background: #d2d2d2 !important;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.laytable-cell-1-0-3 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="layui-collapse tips-wrap">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">操作提示</h2>
|
||||
<ul class="layui-colla-content layui-show">
|
||||
<li>在迁移数据前,首先会备份原数据,SQL文件存放在upload/backup文件夹下</li>
|
||||
<li>迁移数据开始后,请不要关闭当前页面,以免造成未知错误</li>
|
||||
<li>文档参考:<a href="https://www.kancloud.cn/niucloud/niushop_b2c_v4/1852551" target="_blank" class="text-color">v3Tov4迁移数据说明文档</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form form-wrap">
|
||||
|
||||
<table lay-filter="migrate_list" lay-skin="line" class="js-migrate-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th lay-data="{checkbox:true,field:'key', width:'5%'}"></th>
|
||||
<th lay-data="{field:'name',width:'20%'}">迁移模块</th>
|
||||
<th lay-data="{field:'introduction',width:'65%'}">描述</th>
|
||||
<th lay-data="{field:'action',width:'10%'}" >迁移说明</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach name="$task_class" item="vo" key="k"}
|
||||
{if $vo['is_show']}
|
||||
<tr>
|
||||
<td>{$k}</td>
|
||||
<td>{$vo['name']}</td>
|
||||
<td>{$vo['introduction']}</td>
|
||||
<td>
|
||||
<div class="table-btn">
|
||||
<a class="layui-btn js-select-desc" data-desc='{$vo["desc"]}'>详情</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{foreach name="$task_class" item="vo" key="k"}
|
||||
<input type="hidden" name="migrate_data" title="{$vo['name']}" value="{$k}" lay-skin="primary">
|
||||
{/foreach}
|
||||
|
||||
<div class="layui-form-item progress-bar-wrap">
|
||||
<label class="layui-form-label mid">迁移进度:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="progress-bar">
|
||||
<span class="curr"></span>
|
||||
<span class="value">0%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row mid">
|
||||
<button class="layui-btn js-save" lay-submit lay-filter="save">迁移</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var form, table;
|
||||
var index = -1;// 当前页
|
||||
var migrate_data = [];// 已选迁移模块
|
||||
var total = 0;// 总页数
|
||||
var page_size = 0;//每页数量
|
||||
|
||||
var last_table = "";
|
||||
var backup_index = 0;
|
||||
var series = 0;
|
||||
var is_backup_end = 0;// 是否备份完成
|
||||
var repeat_flag = false; //防重复标识
|
||||
|
||||
layui.use(['form', 'table'], function () {
|
||||
form = layui.form;
|
||||
table = layui.table;
|
||||
|
||||
table.init('migrate_list');
|
||||
|
||||
table.on('checkbox(migrate_list)', function (obj) {
|
||||
if (obj.type == "all") {
|
||||
migrate_data = [];
|
||||
if (obj.checked) {
|
||||
$("input[name='migrate_data']").each(function () {
|
||||
migrate_data.push($(this).val());
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (obj.checked) {
|
||||
migrate_data.push(obj.data.key);
|
||||
} else {
|
||||
for (var i in migrate_data) {
|
||||
if (migrate_data[i] == obj.data.key) migrate_data.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("body").off("click", ".js-select-desc").on("click", ".js-select-desc", function () {
|
||||
var desc = $(this).attr("data-desc");
|
||||
layer.open({
|
||||
title: '迁移说明',
|
||||
area: ['900px', '600px'],
|
||||
content: '<pre>' + desc + '</pre>'
|
||||
});
|
||||
});
|
||||
|
||||
form.on("submit(save)", function (data) {
|
||||
if (!migrate_data.length) {
|
||||
layer.msg("请选择要迁移的数据");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (repeat_flag) return false;
|
||||
repeat_flag = true;
|
||||
|
||||
checkModuleIsUpgrade(function () {
|
||||
execute();
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
function execute() {
|
||||
if (is_backup_end) {
|
||||
migrate();
|
||||
} else {
|
||||
$(".js-save").text("数据备份中...").attr("disabled", true);
|
||||
backupSql(function (res) {
|
||||
if (res.code >= 0) {
|
||||
$(".js-save").text("数据迁移中...").attr("disabled", true);
|
||||
migrate();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迁移数据
|
||||
*/
|
||||
function migrate() {
|
||||
$.ajax({
|
||||
url: ns.url("v3tov4://shop/upgrade/index"),
|
||||
dataType: 'JSON',
|
||||
type: 'POST',
|
||||
data: {index: index, 'class': migrate_data.toString()},
|
||||
success: function (res) {
|
||||
if (res.code >= 0) {
|
||||
var data = res.data;
|
||||
index = parseInt(data.index);
|
||||
total = parseInt(data.total);
|
||||
page_size = parseInt(data.page_size);
|
||||
var progress = 0;
|
||||
if (index > -1) {
|
||||
// 进度计算公式:(当前页 * 每页数量) / 总数量(每页数量 * 总页数) * 100
|
||||
progress = parseFloat(((index + 1) * page_size) / (page_size * total) * 100).toFixed(2);
|
||||
}
|
||||
|
||||
$(".progress-bar .curr").css("width", progress + "%");
|
||||
$(".progress-bar .value").text(progress + "%");
|
||||
if ((parseInt(index) + 1) < total) {
|
||||
index++;
|
||||
execute();
|
||||
} else {
|
||||
updateLogStatus();
|
||||
$(".js-save").text("迁移完成").removeAttr("disabled");
|
||||
layer.msg("迁移完成");
|
||||
}
|
||||
} else {
|
||||
layer.msg(res.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据备份
|
||||
* @param callback
|
||||
*/
|
||||
function backupSql(callback) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: ns.url("v3tov4://shop/upgrade/backupSql"),
|
||||
dataType: 'json',
|
||||
data: {
|
||||
last_table: last_table,
|
||||
index: backup_index,
|
||||
series: series
|
||||
},
|
||||
success: function (res) {
|
||||
if (res.code >= 0) {
|
||||
var data = res.data;
|
||||
//判断是否备份完成
|
||||
if (data.is_backup_end) {
|
||||
is_backup_end = data.is_backup_end;
|
||||
if (callback) callback(res);
|
||||
} else {
|
||||
last_table = data.last_table;
|
||||
series = data.series;
|
||||
backup_index = data.index;
|
||||
backupSql(callback);
|
||||
}
|
||||
} else {
|
||||
if (callback) callback(res);
|
||||
is_backup_end = 0;
|
||||
layer.msg("备份发生错误:", res.message);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最新的模块迁移状态,防止重复迁移
|
||||
* @param callback
|
||||
*/
|
||||
function checkModuleIsUpgrade(callback) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: ns.url("v3tov4://shop/upgrade/checkModuleIsUpgrade"),
|
||||
dataType: 'json',
|
||||
data: {
|
||||
module: migrate_data.toString()
|
||||
},
|
||||
success: function (res) {
|
||||
var data = res.data;
|
||||
var module = [];
|
||||
var message = '';
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].count) {
|
||||
module.push(data[i].title);
|
||||
}
|
||||
}
|
||||
if (module.length) {
|
||||
message = "[ " + module.join(",") + ' ] 数据已迁移成功,确定要重新迁移吗?';
|
||||
var index = layer.confirm(message, {
|
||||
title: '操作提示',
|
||||
// btn: ['返回列表', '继续添加'],
|
||||
closeBtn: 0,
|
||||
yes: function () {
|
||||
if (callback) callback();
|
||||
layer.close(index);
|
||||
}, btn2: function () {
|
||||
repeat_flag = false;
|
||||
layer.close(index);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (callback) callback();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新迁移日志状态
|
||||
*/
|
||||
function updateLogStatus() {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: ns.url("v3tov4://shop/upgrade/updateLogStatus"),
|
||||
dataType: 'json',
|
||||
data: {
|
||||
module: migrate_data.toString()
|
||||
},
|
||||
success: function (res) {
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
129
addon/v3tov4/shop/view/upgrade/log.html
Executable file
129
addon/v3tov4/shop/view/upgrade/log.html
Executable file
@@ -0,0 +1,129 @@
|
||||
<style>
|
||||
.layui-layout-admin .tips-wrap{margin-bottom: 15px;}
|
||||
</style>
|
||||
|
||||
<div class="layui-collapse tips-wrap">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">操作提示</h2>
|
||||
<ul class="layui-colla-content layui-show">
|
||||
<li>迁移数据日志</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<table id="upgrade_log" lay-filter="upgrade_log"></table>
|
||||
</div>
|
||||
<!--操作-->
|
||||
<script type="text/html" id="operation">
|
||||
<div class="table-btn">
|
||||
<a class="layui-btn" lay-event="delete">删除</a>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- 批量删除 -->
|
||||
<script type="text/html" id="batchOperation">
|
||||
<button class="layui-btn layui-btn-primary" lay-event="delete">批量删除</button>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var repeat_flag = false;
|
||||
var table = new Table({
|
||||
elem: '#upgrade_log',
|
||||
filter: "upgrade_log",
|
||||
url: ns.url("v3tov4://shop/upgrade/log"),
|
||||
cols: [[{
|
||||
width: "3%",
|
||||
type: 'checkbox',
|
||||
field: 'id',
|
||||
unresize: 'false'
|
||||
}, {
|
||||
field: 'title',
|
||||
width: '25%',
|
||||
title: '迁移模块',
|
||||
unresize: 'true'
|
||||
}, {
|
||||
field: 'remark',
|
||||
width: '35%',
|
||||
title: '备注',
|
||||
unresize: 'true'
|
||||
}, {
|
||||
width: '17%',
|
||||
title: '迁移时间',
|
||||
unresize: 'true',
|
||||
templet: function (d) {
|
||||
return ns.time_to_date(d.create_time);
|
||||
}
|
||||
}, {
|
||||
width: '10%',
|
||||
title: '迁移状态',
|
||||
unresize: 'true',
|
||||
templet: function (d) {
|
||||
return d.status ? "完成" : "未完成";
|
||||
}
|
||||
}, {
|
||||
title: '操作',
|
||||
toolbar: '#operation',
|
||||
unresize: 'false',
|
||||
align:'right'
|
||||
}]],
|
||||
bottomToolbar: "#batchOperation"
|
||||
});
|
||||
|
||||
/**
|
||||
* 批量操作
|
||||
*/
|
||||
table.bottomToolbar(function (obj) {
|
||||
if (obj.data.length < 1) {
|
||||
layer.msg('请选择要操作的数据');
|
||||
return;
|
||||
}
|
||||
switch (obj.event) {
|
||||
case "delete":
|
||||
var id_array = new Array();
|
||||
for (i in obj.data) id_array.push(obj.data[i].id);
|
||||
deleteLog(id_array.toString());
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 监听工具栏操作
|
||||
*/
|
||||
table.tool(function (obj) {
|
||||
var data = obj.data;
|
||||
switch (obj.event) {
|
||||
case 'delete':
|
||||
deleteLog(data.id);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
function deleteLog(id) {
|
||||
if (repeat_flag) return;
|
||||
repeat_flag = true;
|
||||
|
||||
layer.confirm('确定要删除该日志吗?', function (index) {
|
||||
layer.close(index);
|
||||
$.ajax({
|
||||
url: ns.url("v3tov4://shop/upgrade/deleteLog"),
|
||||
data: {
|
||||
"ids": id
|
||||
},
|
||||
dataType: 'JSON',
|
||||
type: 'POST',
|
||||
success: function (res) {
|
||||
layer.msg(res.message);
|
||||
repeat_flag = false;
|
||||
|
||||
if (res.code == 0) {
|
||||
table.reload({
|
||||
page: {
|
||||
curr: 1
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user