文件
Henglianshutong/addons/shopro/console/PartnerInstall.php

265 行
10 KiB
PHP

<?php
namespace addons\shopro\console;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use app\common\library\Menu;
class PartnerInstall extends Command
{
protected function configure()
{
$this->setName('shopro:partner:install')
->setDescription('导入收益中心表结构/配置,并升级后台菜单');
}
protected function execute(Input $input, Output $output)
{
$prefix = config('database.prefix') ?: 'fa_';
$output->writeln('prefix=' . $prefix);
$this->ensureAgentColumns($prefix, $output);
$this->runSqlFile($prefix, $output);
$this->applyBusinessConfig($output);
$this->enableCommissionGoods($output);
$this->backfillTasters($output);
$this->backfillLastSelfOrder($output);
$this->upgradeMenu($output);
$this->clearConfigCache($output);
$output->writeln('shopro:partner:install done');
return 0;
}
protected function ensureAgentColumns($prefix, Output $output)
{
$table = $prefix . 'shopro_commission_agent';
$columns = [
'is_venue' => "tinyint(1) NOT NULL DEFAULT 0 COMMENT '酒道馆'",
'is_county' => "tinyint(1) NOT NULL DEFAULT 0 COMMENT '区县代理'",
'county_code' => "varchar(20) NOT NULL DEFAULT '' COMMENT '区县编码'",
'direct_order_seq' => "int(11) NOT NULL DEFAULT 0 COMMENT '直推合格单累计'",
'madow' => "decimal(20,8) NOT NULL DEFAULT 0.00000000 COMMENT 'dmepa'",
'voucher_total' => "decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '兑换券总额'",
'voucher_released' => "decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '兑换券已释放'",
'voucher_used' => "decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '兑换券已使用'",
'last_self_order_time' => "bigint(16) DEFAULT NULL COMMENT '本人最近合格订单时间'",
];
foreach ($columns as $name => $ddl) {
if ($this->columnExists($table, $name)) {
$output->writeln("skip column {$name}");
continue;
}
Db::execute("ALTER TABLE `{$table}` ADD COLUMN `{$name}` {$ddl}");
$output->writeln("add column {$name}");
}
$indexes = [
'idx_venue' => 'is_venue',
'idx_county' => 'is_county',
'idx_last_self_order' => 'last_self_order_time',
];
foreach ($indexes as $idx => $col) {
if ($this->indexExists($table, $idx)) {
continue;
}
try {
Db::execute("ALTER TABLE `{$table}` ADD KEY `{$idx}` (`{$col}`)");
} catch (\Exception $e) {
$output->writeln('index ' . $idx . ' ' . $e->getMessage());
}
}
}
protected function runSqlFile($prefix, Output $output)
{
$file = (defined('ADDON_PATH') ? ADDON_PATH : ROOT_PATH . 'addons/') . 'shopro/upgrade/partner_v2.sql';
if (!is_file($file)) {
$output->writeln('sql file missing');
return;
}
$sql = str_replace('__PREFIX__', $prefix, file_get_contents($file));
$sql = preg_replace('/^--.*$/m', '', $sql);
$parts = array_filter(array_map('trim', explode(';', $sql)));
foreach ($parts as $part) {
if ($part === '' || stripos($part, 'ALTER TABLE') !== false && stripos($part, 'shopro_commission_agent') !== false) {
continue;
}
if (stripos($part, 'SET @') === 0) {
continue;
}
try {
Db::execute($part);
$output->writeln('ok: ' . mb_substr(preg_replace('/\s+/', ' ', $part), 0, 80));
} catch (\Exception $e) {
$output->writeln('skip: ' . $e->getMessage());
}
}
}
protected function upgradeMenu(Output $output)
{
try {
$info = get_addon_info('shopro');
$class = get_addon_class('shopro');
$addon = new $class($info);
if (method_exists($addon, 'upgrade')) {
$addon->upgrade();
$output->writeln('menu upgraded');
}
} catch (\Exception $e) {
$output->writeln('menu upgrade fail: ' . $e->getMessage());
try {
$shopro = new \ReflectionClass(\addons\shopro\Shopro::class);
$method = $shopro->getMethod('getMenu');
$method->setAccessible(true);
$menu = $method->invoke(null);
Menu::upgrade('shopro', $menu['new']);
$output->writeln('menu upgraded via reflection');
} catch (\Exception $ex) {
$output->writeln('menu fail: ' . $ex->getMessage());
}
}
}
protected function applyBusinessConfig(Output $output)
{
$force = [
'shop.commission.partner_mode' => '1',
'shop.commission.partner_enable' => '1',
'shop.commission.agent_check' => '0',
];
foreach ($force as $code => $value) {
$row = Db::name('shopro_config')->where('code', $code)->find();
if ($row) {
Db::name('shopro_config')->where('code', $code)->update(['value' => $value]);
} else {
Db::name('shopro_config')->insert([
'code' => $code,
'parent_code' => 'shop.commission',
'name' => $code,
'type' => 'boolean',
'value' => $value,
'weigh' => 80,
]);
}
$output->writeln("config {$code}={$value}");
}
$become = Db::name('shopro_config')->where('code', 'shop.commission.become_agent')->find();
if ($become) {
Db::name('shopro_config')->where('code', 'shop.commission.become_agent')->update([
'value' => json_encode(['type' => 'user', 'value' => ''], JSON_UNESCAPED_UNICODE),
]);
$output->writeln('config become_agent=user');
}
$form = Db::name('shopro_config')->where('code', 'shop.commission.agent_form')->find();
if ($form) {
$val = json_decode($form['value'], true);
if (!is_array($val)) {
$val = [];
}
$val['status'] = '0';
Db::name('shopro_config')->where('code', 'shop.commission.agent_form')->update([
'value' => json_encode($val, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
]);
$output->writeln('config agent_form.status=0');
}
$level = Db::name('shopro_config')->where('code', 'shop.commission.level')->find();
if ($level && intval($level['value']) < 1) {
Db::name('shopro_config')->where('code', 'shop.commission.level')->update(['value' => '1']);
$output->writeln('config level=1');
}
}
protected function enableCommissionGoods(Output $output)
{
$goodsIds = Db::name('shopro_goods')->where('status', 'up')->column('id');
$count = 0;
foreach ($goodsIds as $goodsId) {
$row = Db::name('shopro_commission_goods')->where('goods_id', $goodsId)->find();
if ($row) {
if (intval($row['status']) !== 1) {
Db::name('shopro_commission_goods')->where('goods_id', $goodsId)->update(['status' => 1]);
$count++;
}
continue;
}
Db::name('shopro_commission_goods')->insert([
'goods_id' => $goodsId,
'self_rules' => 0,
'commission_rules' => '{}',
'status' => 1,
'commission_config' => null,
'commission_order_status' => 1,
]);
$count++;
}
$output->writeln("commission goods enabled: {$count}/" . count($goodsIds));
}
protected function backfillTasters(Output $output)
{
$userIds = Db::name('user')->column('id');
$now = time();
$count = 0;
foreach ($userIds as $userId) {
$exists = Db::name('shopro_commission_agent')->where('user_id', $userId)->find();
if ($exists) {
continue;
}
Db::name('shopro_commission_agent')->insert([
'user_id' => $userId,
'level' => 1,
'status' => 'normal',
'apply_num' => 1,
'become_time' => $now,
'createtime' => $now,
'updatetime' => $now,
]);
$count++;
}
$output->writeln("backfill tasters: {$count}");
}
protected function backfillLastSelfOrder(Output $output)
{
$count = (new \addons\shopro\service\partner\ActiveService())->syncActiveTimes();
$output->writeln("backfill last_self_order_time (self + direct): {$count}");
}
protected function clearConfigCache(Output $output)
{
$codes = [
'shop.commission',
'shop.commission.partner_mode',
'shop.commission.partner_enable',
'shop.commission.become_agent',
'shop.commission.agent_form',
'shop.commission.agent_check',
'shop.commission.level',
];
foreach ($codes as $code) {
cache('config:' . $code, null);
}
$output->writeln('config cache cleared');
}
protected function columnExists($table, $column)
{
$database = config('database.database');
$row = Db::query("SELECT COUNT(*) AS c FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?", [$database, $table, $column]);
return intval($row[0]['c'] ?? 0) > 0;
}
protected function indexExists($table, $index)
{
$database = config('database.database');
$row = Db::query("SELECT COUNT(*) AS c FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND INDEX_NAME = ?", [$database, $table, $index]);
return intval($row[0]['c'] ?? 0) > 0;
}
}