@@ -51,6 +51,11 @@ class Config extends Common
|
||||
'name' => 'shopro/config/commission',
|
||||
'status' => $this->auth->check('shopro/config/commission')
|
||||
],
|
||||
[
|
||||
'label' => '合伙股东',
|
||||
'name' => 'shopro/config/partner',
|
||||
'status' => $this->auth->check('shopro/config/commission')
|
||||
],
|
||||
[
|
||||
'label' => '支付配置',
|
||||
'name' => 'shopro/pay_config',
|
||||
@@ -181,6 +186,92 @@ class Config extends Common
|
||||
$this->success('操作成功', null, $configs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合伙股东规则
|
||||
*/
|
||||
public function partner()
|
||||
{
|
||||
$keys = [
|
||||
'partner_mode', 'partner_enable', 'partner_count_type', 'partner_active_days',
|
||||
'partner_chain_max_depth', 'partner_push3_amounts', 'partner_madow_mode',
|
||||
'partner_madow_base_rate', 'partner_madow_step_orders', 'partner_voucher_times',
|
||||
'partner_voucher_days', 'partner_maker_bonus', 'partner_maker_peer_rate',
|
||||
'partner_maker_overtaken_rate', 'partner_team_total', 'partner_venue_split',
|
||||
'partner_county_full', 'partner_venue_share_per_order', 'partner_county_share_per_order',
|
||||
'partner_venue_peer_rate', 'partner_county_peer_rate',
|
||||
];
|
||||
if ('GET' === $this->request->method()) {
|
||||
$all = ShoproConfig::getConfigs('shop.commission', false) ?: [];
|
||||
$configs = [];
|
||||
foreach ($keys as $key) {
|
||||
$configs[$key] = $all[$key] ?? null;
|
||||
}
|
||||
$defaults = [
|
||||
'partner_mode' => 1,
|
||||
'partner_enable' => 1,
|
||||
'partner_count_type' => 'order',
|
||||
'partner_active_days' => 30,
|
||||
'partner_chain_max_depth' => 50,
|
||||
'partner_push3_amounts' => [398, 400, 600],
|
||||
'partner_madow_mode' => 'madow',
|
||||
'partner_madow_base_rate' => '0.00000075',
|
||||
'partner_madow_step_orders' => 1,
|
||||
'partner_voucher_times' => 1.5,
|
||||
'partner_voucher_days' => 365,
|
||||
'partner_maker_bonus' => ['2' => 20, '3' => 40, '4' => 60, '5' => 80, '6' => 100, '7' => 120],
|
||||
'partner_maker_peer_rate' => 0.10,
|
||||
'partner_maker_overtaken_rate' => 0.05,
|
||||
'partner_team_total' => 100,
|
||||
'partner_venue_split' => 50,
|
||||
'partner_county_full' => 100,
|
||||
'partner_venue_share_per_order' => 100,
|
||||
'partner_county_share_per_order' => 50,
|
||||
'partner_venue_peer_rate' => 0.10,
|
||||
'partner_county_peer_rate' => 0.10,
|
||||
];
|
||||
foreach ($defaults as $key => $value) {
|
||||
if ($configs[$key] === null || $configs[$key] === '') {
|
||||
$configs[$key] = $value;
|
||||
}
|
||||
}
|
||||
} elseif ('POST' === $this->request->method()) {
|
||||
check_env('commission');
|
||||
$params = $this->request->param();
|
||||
$save = [];
|
||||
foreach ($keys as $key) {
|
||||
if (array_key_exists($key, $params)) {
|
||||
$save[$key] = $params[$key];
|
||||
}
|
||||
}
|
||||
if (isset($save['partner_active_days']) && intval($save['partner_active_days']) < 1) {
|
||||
$this->error('领取窗口天数须 ≥ 1');
|
||||
}
|
||||
if (!empty($save['partner_maker_bonus']) && is_array($save['partner_maker_bonus'])) {
|
||||
$prev = null;
|
||||
foreach ([2, 3, 4, 5, 6, 7] as $lv) {
|
||||
$val = isset($save['partner_maker_bonus'][$lv])
|
||||
? (float) $save['partner_maker_bonus'][$lv]
|
||||
: (isset($save['partner_maker_bonus'][(string) $lv]) ? (float) $save['partner_maker_bonus'][(string) $lv] : null);
|
||||
if ($val === null) {
|
||||
continue;
|
||||
}
|
||||
if ($prev !== null && $val < $prev) {
|
||||
$this->error('创客 V1–V6 单笔基数必须递增');
|
||||
}
|
||||
$prev = $val;
|
||||
}
|
||||
}
|
||||
if (isset($save['partner_team_total'], $save['partner_venue_split'])
|
||||
&& (float) $save['partner_venue_split'] > (float) $save['partner_team_total']) {
|
||||
$this->error('酒道馆份额不能大于团队拆分总额');
|
||||
}
|
||||
$configs = ShoproConfig::setConfigs('shop.commission', $save);
|
||||
$this->success('规则已更新,仅对之后的新订单生效。', null, $configs);
|
||||
return;
|
||||
}
|
||||
$this->success('操作成功', null, $configs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 订单配置
|
||||
|
||||
@@ -12,7 +12,7 @@ use think\Db;
|
||||
|
||||
class Agent extends Common
|
||||
{
|
||||
protected $noNeedRight = ['select'];
|
||||
protected $noNeedRight = ['select', 'identity'];
|
||||
|
||||
protected $model = null;
|
||||
|
||||
@@ -52,6 +52,28 @@ class Agent extends Common
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$amounts = \addons\shopro\service\partner\PartnerConfig::push3Amounts();
|
||||
$seq = intval($detail->direct_order_seq ?? 0);
|
||||
$next = $amounts[$seq % count($amounts)] ?? 398;
|
||||
$last = intval($detail->last_self_order_time ?? 0);
|
||||
$days = \addons\shopro\service\partner\PartnerConfig::activeDays();
|
||||
$ago = $last ? intval(floor((time() - $last) / 86400)) : null;
|
||||
$cash = \app\admin\model\shopro\partner\Reward::where('user_id', $id)
|
||||
->where('status', 1)
|
||||
->where('amount', '>', 0)
|
||||
->sum('amount');
|
||||
|
||||
$detail->next_push3_amount = number_format((float) $next, 2, '.', '');
|
||||
$detail->next_push3_text = '第 ' . ($seq + 1) . ' 单将返 ' . $detail->next_push3_amount;
|
||||
$detail->last_self_order_text = $last ? date('Y-m-d H:i:s', $last) : '从未下单';
|
||||
$detail->active_status_text = !empty($detail->active_30d)
|
||||
? '正常领取'
|
||||
: ('已暂停' . ($ago !== null ? '(距今 ' . $ago . ' 天)' : ''));
|
||||
$detail->partner_cash_income = number_format((float) $cash, 2, '.', '');
|
||||
$detail->partner_mode = \addons\shopro\service\partner\PartnerConfig::isPartnerMode() ? 1 : 0;
|
||||
$rate = (new \addons\shopro\service\partner\RateService())->currentRate();
|
||||
$detail->madow_value = \addons\shopro\service\partner\IdentityService::formatMoney((float) ($detail->madow ?? 0) * (float) $rate);
|
||||
|
||||
$this->success('分销商详情', null, $detail);
|
||||
}
|
||||
|
||||
@@ -98,7 +120,7 @@ class Agent extends Common
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
$params = $this->request->only(['status', 'upgrade_lock', 'level_status', 'level', 'apply_info']);
|
||||
$params = $this->request->only(['status', 'upgrade_lock', 'level_status', 'level', 'apply_info', 'is_venue', 'is_county', 'county_code']);
|
||||
|
||||
$result = Db::transaction(function () use ($id, $params) {
|
||||
$row = $this->model->with(['user', 'level_info', 'level_status_info', 'upgrade_level'])->where('user_id', $id)->find();
|
||||
@@ -117,6 +139,14 @@ class Agent extends Common
|
||||
case 'level': // 修改等级
|
||||
return $this->changeLevel($row, $value);
|
||||
break;
|
||||
case 'is_venue':
|
||||
case 'is_county':
|
||||
case 'county_code':
|
||||
$result = $row->save([$field => $value]);
|
||||
if ($result) {
|
||||
LogModel::add($row->user_id, 'agent', ['type' => 'identity', 'field' => $field, 'value' => $value]);
|
||||
}
|
||||
return $result;
|
||||
default:
|
||||
return $row->save([$field => $value]);
|
||||
}
|
||||
@@ -129,6 +159,91 @@ class Agent extends Common
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开通 / 调整身份(弹窗一次提交)
|
||||
*/
|
||||
public function identity($id = null)
|
||||
{
|
||||
if (!$this->auth->check('shopro/commission/agent/edit')) {
|
||||
$this->error(__('You have no permission'));
|
||||
}
|
||||
$params = $this->request->only(['level', 'is_venue', 'is_county', 'county_code', 'upgrade_lock', 'remark']);
|
||||
if ($id === null || $id === '') {
|
||||
$this->error('请选择用户');
|
||||
}
|
||||
|
||||
$level = intval($params['level'] ?? 0);
|
||||
if ($level < 1 || $level > 7) {
|
||||
$this->error('请选择品酒师或创客等级');
|
||||
}
|
||||
$isVenue = intval($params['is_venue'] ?? 0) ? 1 : 0;
|
||||
$isCounty = intval($params['is_county'] ?? 0) ? 1 : 0;
|
||||
$countyCode = trim((string) ($params['county_code'] ?? ''));
|
||||
if ($isCounty && $countyCode === '') {
|
||||
$this->error('开通区县代理时请选择区县');
|
||||
}
|
||||
if (!$isCounty) {
|
||||
$countyCode = '';
|
||||
}
|
||||
$upgradeLock = array_key_exists('upgrade_lock', $params) ? intval($params['upgrade_lock']) : null;
|
||||
$remark = trim((string) ($params['remark'] ?? ''));
|
||||
|
||||
$result = Db::transaction(function () use ($id, $level, $isVenue, $isCounty, $countyCode, $upgradeLock, $remark) {
|
||||
$service = new AgentService(intval($id));
|
||||
if (!$service->user) {
|
||||
$this->error('未找到该用户');
|
||||
}
|
||||
if (!$service->agent) {
|
||||
$service->createNewAgent('user');
|
||||
$service = new AgentService(intval($id));
|
||||
}
|
||||
$row = $service->agent;
|
||||
if (!$row) {
|
||||
$this->error('未能生成分销身份');
|
||||
}
|
||||
|
||||
$before = \addons\shopro\service\partner\IdentityService::build($row);
|
||||
$levelModel = LevelModel::find($level);
|
||||
if (!$levelModel) {
|
||||
$this->error('未找到该等级');
|
||||
}
|
||||
|
||||
$save = [
|
||||
'level' => $level,
|
||||
'is_venue' => $isVenue,
|
||||
'is_county' => $isCounty,
|
||||
'county_code' => $countyCode,
|
||||
];
|
||||
if ($upgradeLock !== null) {
|
||||
$save['upgrade_lock'] = $upgradeLock ? 1 : 0;
|
||||
}
|
||||
$row->save($save);
|
||||
|
||||
$after = \addons\shopro\service\partner\IdentityService::build($row);
|
||||
$logRemark = $remark !== ''
|
||||
? $remark
|
||||
: sprintf('将「%s」从 %s 调整为 %s。已入账收益不追溯。', $service->user->nickname ?: $id, $before['identity_text'] ?: '未开通', $after['identity_text'] ?: '-');
|
||||
LogModel::add($row->user_id, 'agent', [
|
||||
'type' => 'identity',
|
||||
'field' => 'bundle',
|
||||
'value' => $after['identity_text'],
|
||||
'before' => $before['identity_text'],
|
||||
], null, $logRemark);
|
||||
LogModel::add($row->user_id, 'agent', ['type' => 'level', 'level' => $levelModel]);
|
||||
(new AgentService($row->user_id))->createAsyncAgentUpgrade();
|
||||
|
||||
return [
|
||||
'identity_text' => $after['identity_text'],
|
||||
'level' => $level,
|
||||
'is_venue' => $isVenue,
|
||||
'is_county' => $isCounty,
|
||||
'county_code' => $countyCode,
|
||||
];
|
||||
});
|
||||
|
||||
$this->success('身份已更新', null, $result);
|
||||
}
|
||||
|
||||
|
||||
// 修改状态
|
||||
private function changeStatus($row, $value)
|
||||
|
||||
@@ -180,9 +180,140 @@ class Order extends Common
|
||||
// 处理未支付订单 item status_code
|
||||
$order = $order->setOrderItemStatusByOrder($order);
|
||||
|
||||
$order->partner_split = $this->buildPartnerSplit($order);
|
||||
|
||||
$this->success('获取成功', null, $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合伙股东分成明细:即时奖列人;均分只汇总人数/人均
|
||||
*/
|
||||
protected function buildPartnerSplit($order)
|
||||
{
|
||||
$orderId = intval($order->id ?? 0);
|
||||
$shareTypes = ['venue_share', 'county_share', 'madow_share'];
|
||||
$items = [];
|
||||
$totalCash = 0;
|
||||
|
||||
$rows = \app\admin\model\shopro\partner\Reward::with(['user'])
|
||||
->where('order_id', $orderId)
|
||||
->order('id', 'asc')
|
||||
->select();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$type = (string) ($row->reward_type ?? '');
|
||||
if (in_array($type, $shareTypes, true)) {
|
||||
continue;
|
||||
}
|
||||
$amount = round((float) $row->amount, 2);
|
||||
$madow = (float) ($row->madow ?? 0);
|
||||
if (intval($row->status) === 1 && $amount > 0) {
|
||||
$totalCash = round($totalCash + $amount, 2);
|
||||
}
|
||||
$items[] = [
|
||||
'display' => 'user',
|
||||
'id' => intval($row->id),
|
||||
'reward_type' => $type,
|
||||
'reward_type_text' => $row->reward_type_text,
|
||||
'role_text' => $row->role_text ?? '',
|
||||
'user_id' => intval($row->user_id),
|
||||
'user' => $row->user,
|
||||
'amount' => number_format($amount, 2, '.', ''),
|
||||
'madow' => \addons\shopro\service\partner\IdentityService::formatMadow($madow),
|
||||
'status' => intval($row->status),
|
||||
'status_text' => $row->status_text,
|
||||
'formula' => $row->formula,
|
||||
'skip_reason_text' => $row->skip_reason_text,
|
||||
];
|
||||
}
|
||||
|
||||
$settleDate = null;
|
||||
$paidRaw = $order->getData('paid_time') ?? ($order['paid_time'] ?? null);
|
||||
if ($paidRaw) {
|
||||
$paidTs = is_numeric($paidRaw) ? intval($paidRaw) : strtotime((string) $paidRaw);
|
||||
if ($paidTs > 0) {
|
||||
$settleDate = date('Y-m-d', $paidTs);
|
||||
}
|
||||
}
|
||||
|
||||
if ($settleDate) {
|
||||
foreach ($shareTypes as $type) {
|
||||
$shareRows = \app\admin\model\shopro\partner\Reward::where('settle_date', $settleDate)
|
||||
->where('reward_type', $type)
|
||||
->where('status', 1)
|
||||
->where('user_id', '>', 0)
|
||||
->select();
|
||||
$userCount = count($shareRows);
|
||||
if ($userCount <= 0) {
|
||||
// 分母为 0 进平台的记录
|
||||
$platform = \app\admin\model\shopro\partner\Reward::where('settle_date', $settleDate)
|
||||
->where('reward_type', $type)
|
||||
->where('status', 1)
|
||||
->where('user_id', 0)
|
||||
->find();
|
||||
if (!$platform) {
|
||||
continue;
|
||||
}
|
||||
$items[] = [
|
||||
'display' => 'share',
|
||||
'reward_type' => $type,
|
||||
'reward_type_text' => \addons\shopro\service\partner\PartnerConfig::rewardTypeText($type),
|
||||
'user_count' => 0,
|
||||
'each_amount' => '0.00',
|
||||
'each_madow' => '0.00000000',
|
||||
'total_amount' => number_format((float) $platform->amount, 2, '.', ''),
|
||||
'total_madow' => \addons\shopro\service\partner\IdentityService::formatMadow($platform->madow ?? 0),
|
||||
'settle_date' => $settleDate,
|
||||
'status_text' => '已入账',
|
||||
'unit' => $type === 'madow_share' ? '马豆' : '元',
|
||||
'formula' => $platform->formula,
|
||||
'tip' => '付款日日结均分:当日无人参与,奖池进平台',
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
$totalAmount = 0;
|
||||
$totalMadow = 0;
|
||||
foreach ($shareRows as $sr) {
|
||||
$totalAmount = round($totalAmount + (float) $sr->amount, 2);
|
||||
$totalMadow = function_exists('bcadd')
|
||||
? (float) bcadd((string) $totalMadow, (string) ($sr->madow ?? 0), 8)
|
||||
: ($totalMadow + (float) ($sr->madow ?? 0));
|
||||
}
|
||||
$first = $shareRows[0];
|
||||
$eachAmount = number_format((float) $first->amount, 2, '.', '');
|
||||
$eachMadow = \addons\shopro\service\partner\IdentityService::formatMadow($first->madow ?? 0);
|
||||
$ext = is_array($first->ext) ? $first->ext : [];
|
||||
if (!empty($ext['share_user_count'])) {
|
||||
$userCount = intval($ext['share_user_count']);
|
||||
}
|
||||
|
||||
$items[] = [
|
||||
'display' => 'share',
|
||||
'reward_type' => $type,
|
||||
'reward_type_text' => \addons\shopro\service\partner\PartnerConfig::rewardTypeText($type),
|
||||
'user_count' => $userCount,
|
||||
'each_amount' => $eachAmount,
|
||||
'each_madow' => $eachMadow,
|
||||
'total_amount' => number_format($totalAmount, 2, '.', ''),
|
||||
'total_madow' => \addons\shopro\service\partner\IdentityService::formatMadow($totalMadow),
|
||||
'settle_date' => $settleDate,
|
||||
'status_text' => '已入账',
|
||||
'unit' => $type === 'madow_share' ? '马豆' : '元',
|
||||
'formula' => $first->formula,
|
||||
'tip' => '付款日日结均分(不列出参与用户名单)',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'items' => $items,
|
||||
'total_cash' => number_format($totalCash, 2, '.', ''),
|
||||
'settle_date' => $settleDate,
|
||||
'has_data' => count($items) > 0,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量发货渲染模板
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\shopro\partner;
|
||||
|
||||
use app\admin\controller\shopro\Common;
|
||||
use app\admin\model\shopro\partner\DailyReport;
|
||||
use addons\shopro\service\partner\DailySettleService;
|
||||
|
||||
class Daily extends Common
|
||||
{
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new DailyReport();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if (!$this->request->isAjax()) {
|
||||
return $this->view->fetch();
|
||||
}
|
||||
$list = $this->model->sheepFilter()->order('settle_date', 'desc')->paginate($this->request->param('list_rows', 10));
|
||||
$today = date('Y-m-d');
|
||||
$yesterday = date('Y-m-d', strtotime('-1 day'));
|
||||
$days = \addons\shopro\service\partner\PartnerConfig::activeDays();
|
||||
$since = time() - $days * 86400;
|
||||
$result = $list->toArray();
|
||||
$cashTypes = \addons\shopro\service\partner\PartnerConfig::instantTypes();
|
||||
$cashTypes = array_merge($cashTypes, ['venue_share', 'county_share']);
|
||||
$sumCash = function ($date) use ($cashTypes) {
|
||||
return (float) \app\admin\model\shopro\partner\Reward::where('settle_date', $date)
|
||||
->where('status', 1)
|
||||
->whereIn('reward_type', $cashTypes)
|
||||
->sum('amount');
|
||||
};
|
||||
$todayCash = $sumCash($today);
|
||||
// 即时奖无 settle_date,按入账日合计
|
||||
$todayStart = strtotime($today . ' 00:00:00');
|
||||
$todayEnd = $todayStart + 86400 - 1;
|
||||
$yStart = strtotime($yesterday . ' 00:00:00');
|
||||
$yEnd = $yStart + 86400 - 1;
|
||||
$instantToday = (float) \app\admin\model\shopro\partner\Reward::where('status', 1)
|
||||
->whereNull('settle_date')
|
||||
->whereBetween('createtime', [$todayStart, $todayEnd])
|
||||
->whereIn('reward_type', \addons\shopro\service\partner\PartnerConfig::instantTypes())
|
||||
->sum('amount');
|
||||
$instantYesterday = (float) \app\admin\model\shopro\partner\Reward::where('status', 1)
|
||||
->whereNull('settle_date')
|
||||
->whereBetween('createtime', [$yStart, $yEnd])
|
||||
->whereIn('reward_type', \addons\shopro\service\partner\PartnerConfig::instantTypes())
|
||||
->sum('amount');
|
||||
$result['kpi'] = [
|
||||
'today' => DailyReport::where('settle_date', $today)->find(),
|
||||
'yesterday' => DailyReport::where('settle_date', $yesterday)->find(),
|
||||
'today_cash' => number_format($todayCash + $instantToday, 2, '.', ''),
|
||||
'yesterday_cash' => number_format($sumCash($yesterday) + $instantYesterday, 2, '.', ''),
|
||||
'inactive_count' => \app\admin\model\shopro\commission\Agent::where(function ($q) use ($since) {
|
||||
$q->whereNull('last_self_order_time')->whereOr('last_self_order_time', '<', $since);
|
||||
})->count(),
|
||||
];
|
||||
$this->success('获取成功', null, $result);
|
||||
}
|
||||
|
||||
public function rerun()
|
||||
{
|
||||
$date = $this->request->param('settle_date');
|
||||
if (!$date) {
|
||||
$this->error('请选择日期');
|
||||
}
|
||||
$report = (new DailySettleService())->run($date, true);
|
||||
$this->success('重跑完成', null, $report);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\shopro\partner;
|
||||
|
||||
use app\admin\controller\shopro\Common;
|
||||
use app\admin\model\shopro\partner\Reward as RewardModel;
|
||||
use addons\shopro\service\Wallet;
|
||||
use addons\shopro\service\partner\PartnerConfig;
|
||||
use addons\shopro\service\partner\PartnerRewardService;
|
||||
use think\Db;
|
||||
|
||||
class Reward extends Common
|
||||
{
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new RewardModel();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if (!$this->request->isAjax()) {
|
||||
$exportConfig = (new \addons\shopro\library\Export())->getConfig();
|
||||
$this->assignconfig("save_type", $exportConfig['save_type'] ?? 'download');
|
||||
$this->assignconfig("rewardTypeMap", PartnerConfig::rewardTypeMap());
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
$showSkip = $this->request->param('show_skip', 0);
|
||||
$query = $this->model->sheepFilter()->with(['buyer', 'user', 'order']);
|
||||
if (!$showSkip) {
|
||||
$query->where(function ($q) {
|
||||
$q->where('amount', '>', 0)->whereOr('madow', '>', 0);
|
||||
});
|
||||
}
|
||||
$list = $query->paginate($this->request->param('list_rows', 10));
|
||||
$this->success('获取成功', null, $list);
|
||||
}
|
||||
|
||||
public function export()
|
||||
{
|
||||
$cellTitles = [
|
||||
'id' => 'Id',
|
||||
'createtime' => '入账时间',
|
||||
'user_nickname' => '受益人',
|
||||
'buyer_nickname' => '买家',
|
||||
'order_id' => '订单',
|
||||
'reward_type_text' => '奖项',
|
||||
'role_text' => '角色',
|
||||
'amount' => '金额',
|
||||
'madow' => '马豆',
|
||||
'base_amount' => '基数',
|
||||
'status_text' => '状态',
|
||||
'formula' => '公式',
|
||||
];
|
||||
$total = $this->model->sheepFilter()->count();
|
||||
if ($total <= 0) {
|
||||
$this->error('导出数据为空');
|
||||
}
|
||||
$export = new \addons\shopro\library\Export();
|
||||
$params = [
|
||||
'file_name' => '合伙股东收益流水',
|
||||
'cell_titles' => $cellTitles,
|
||||
'total' => $total,
|
||||
'is_sub_cell' => false,
|
||||
];
|
||||
$totalAmount = 0;
|
||||
$totalMadow = 0;
|
||||
$result = $export->export($params, function ($pages) use (&$totalAmount, &$totalMadow, $total) {
|
||||
$datas = $this->model->sheepFilter()->with(['buyer', 'user', 'order'])
|
||||
->limit((($pages['page'] - 1) * $pages['list_rows']), $pages['list_rows'])
|
||||
->select();
|
||||
$newDatas = [];
|
||||
foreach ($datas as $reward) {
|
||||
$newDatas[] = [
|
||||
'id' => $reward['id'],
|
||||
'createtime' => $reward['createtime'],
|
||||
'user_nickname' => $reward['user']['nickname'] ?? '-',
|
||||
'buyer_nickname' => $reward['buyer']['nickname'] ?? '-',
|
||||
'order_id' => $reward['order']['order_sn'] ?? $reward['order_id'],
|
||||
'reward_type_text' => $reward['reward_type_text'],
|
||||
'role_text' => $reward['role_text'] ?? $reward['role'],
|
||||
'amount' => $reward['amount'],
|
||||
'madow' => $reward['madow'],
|
||||
'base_amount' => $reward['base_amount'],
|
||||
'status_text' => $reward['status_text'],
|
||||
'formula' => $reward['formula'],
|
||||
];
|
||||
}
|
||||
$totalAmount += array_sum(array_column($newDatas, 'amount'));
|
||||
$totalMadow += array_sum(array_column($newDatas, 'madow'));
|
||||
if ($pages['is_last_page']) {
|
||||
$newDatas[] = ['id' => "总数:{$total};金额:{$totalAmount};马豆:{$totalMadow}"];
|
||||
}
|
||||
return $newDatas;
|
||||
});
|
||||
$this->success('导出成功', null, $result);
|
||||
}
|
||||
|
||||
public function reissue()
|
||||
{
|
||||
$params = $this->request->only(['user_id', 'reward_type', 'amount', 'order_id', 'memo']);
|
||||
if (empty($params['user_id']) || empty($params['reward_type']) || empty($params['memo'])) {
|
||||
$this->error('用户、奖项、备注必填');
|
||||
}
|
||||
$amount = round((float) ($params['amount'] ?? 0), 2);
|
||||
if ($amount == 0) {
|
||||
$this->error('请输入金额');
|
||||
}
|
||||
Db::transaction(function () use ($params, $amount) {
|
||||
$row = PartnerRewardService::write([
|
||||
'order_id' => intval($params['order_id'] ?? 0) ?: -time(),
|
||||
'user_id' => intval($params['user_id']),
|
||||
'buyer_id' => 0,
|
||||
'role' => 'system',
|
||||
'reward_type' => 'manual_' . $params['reward_type'],
|
||||
'amount' => $amount,
|
||||
'base_amount' => $amount,
|
||||
'ext' => ['formula' => '手工补发', 'memo' => $params['memo'], 'manual' => 1],
|
||||
'status' => 1,
|
||||
]);
|
||||
Wallet::change($params['user_id'], 'commission', $amount, 'reward_income', [
|
||||
'partner_reward_id' => $row->id ?? 0,
|
||||
'manual' => 1,
|
||||
], $params['memo']);
|
||||
});
|
||||
$this->success('补发成功');
|
||||
}
|
||||
|
||||
public function back()
|
||||
{
|
||||
$id = $this->request->param('id');
|
||||
$memo = trim((string) $this->request->param('memo', ''));
|
||||
if ($memo === '') {
|
||||
$this->error('请填写退回原因');
|
||||
}
|
||||
$row = $this->model->where('id', $id)->find();
|
||||
if (!$row) {
|
||||
$this->error('记录不存在');
|
||||
}
|
||||
if ($row->status != 1 || $row->settle_date) {
|
||||
$this->error('仅已入账的即时奖可退回');
|
||||
}
|
||||
Db::transaction(function () use ($row, $memo) {
|
||||
if ((float) $row->amount > 0 && $row->user_id > 0) {
|
||||
Wallet::change($row->user_id, 'commission', -$row->amount, 'reward_back', [
|
||||
'partner_reward_id' => $row->id,
|
||||
], $memo);
|
||||
}
|
||||
$ext = is_array($row->ext) ? $row->ext : (json_decode($row->ext ?: '{}', true) ?: []);
|
||||
$ext['back_memo'] = $memo;
|
||||
$row->ext = $ext;
|
||||
$row->status = -2;
|
||||
$row->save();
|
||||
});
|
||||
$this->success('已退回');
|
||||
}
|
||||
|
||||
public function backOrder()
|
||||
{
|
||||
$orderId = intval($this->request->param('order_id'));
|
||||
if ($orderId <= 0) {
|
||||
$this->error('请选择订单');
|
||||
}
|
||||
(new PartnerRewardService())->refund($orderId);
|
||||
$this->success('整单已退回');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\shopro\partner;
|
||||
|
||||
use app\admin\controller\shopro\Common;
|
||||
use app\admin\model\shopro\partner\VoucherPlan;
|
||||
use addons\shopro\service\partner\VoucherService;
|
||||
|
||||
class Voucher extends Common
|
||||
{
|
||||
protected $noNeedRight = ['logs'];
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new VoucherPlan();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if (!$this->request->isAjax()) {
|
||||
return $this->view->fetch();
|
||||
}
|
||||
$list = $this->model->sheepFilter()->with(['user', 'order'])->order('id', 'desc')->paginate($this->request->param('list_rows', 10));
|
||||
$userIds = [];
|
||||
foreach ($list as $row) {
|
||||
$userIds[] = intval($row->user_id);
|
||||
}
|
||||
$agents = [];
|
||||
if ($userIds) {
|
||||
$rows = \app\admin\model\shopro\commission\Agent::whereIn('user_id', $userIds)
|
||||
->field('user_id,voucher_used,voucher_released')
|
||||
->select();
|
||||
foreach ($rows as $agent) {
|
||||
$agents[$agent['user_id']] = $agent;
|
||||
}
|
||||
}
|
||||
foreach ($list as $row) {
|
||||
$agent = $agents[$row->user_id] ?? [];
|
||||
$used = (float) ($agent['voucher_used'] ?? 0);
|
||||
$released = (float) ($agent['voucher_released'] ?? 0);
|
||||
$row->voucher_used = number_format($used, 2, '.', '');
|
||||
$row->voucher_available = number_format(max(0, $released - $used), 2, '.', '');
|
||||
}
|
||||
$this->success('获取成功', null, $list);
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
$id = $this->request->param('id');
|
||||
$plan = $this->model->where('id', $id)->find();
|
||||
if (!$plan) {
|
||||
$this->error('计划不存在');
|
||||
}
|
||||
(new VoucherService())->closeByOrder($plan->order_id);
|
||||
$this->success('已关闭');
|
||||
}
|
||||
|
||||
/**
|
||||
* 按日释放日志
|
||||
*/
|
||||
public function logs()
|
||||
{
|
||||
$id = intval($this->request->param('id'));
|
||||
$plan = $this->model->where('id', $id)->find();
|
||||
if (!$plan) {
|
||||
$this->error('计划不存在');
|
||||
}
|
||||
$list = \app\admin\model\shopro\partner\Reward::where('user_id', $plan->user_id)
|
||||
->where('reward_type', 'voucher_release')
|
||||
->order('settle_date', 'desc')
|
||||
->order('id', 'desc')
|
||||
->limit(200)
|
||||
->select();
|
||||
$rows = [];
|
||||
foreach ($list as $item) {
|
||||
$ext = is_array($item->ext) ? $item->ext : (json_decode($item->ext ?: '{}', true) ?: []);
|
||||
$planIds = $ext['plan_ids'] ?? [];
|
||||
if (!$planIds && !empty($ext['plan_id'])) {
|
||||
$planIds = [$ext['plan_id']];
|
||||
}
|
||||
$planIds = array_map('intval', (array) $planIds);
|
||||
if ($planIds && !in_array(intval($plan->id), $planIds, true)) {
|
||||
continue;
|
||||
}
|
||||
$rows[] = [
|
||||
'id' => $item->id,
|
||||
'settle_date' => $item->settle_date,
|
||||
'amount' => $item->amount,
|
||||
'status_text' => $item->status_text,
|
||||
'formula' => $item->formula,
|
||||
'createtime' => $item->createtime,
|
||||
];
|
||||
}
|
||||
$this->success('ok', null, ['plan' => $plan, 'logs' => $rows]);
|
||||
}
|
||||
}
|
||||
@@ -49,8 +49,12 @@ class User extends Common
|
||||
if (!$user) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
$agent = \addons\shopro\service\partner\IdentityService::findAgent($id);
|
||||
$partner = \addons\shopro\service\partner\IdentityService::attachProfile($agent);
|
||||
$data = array_merge($user->toArray(), $partner);
|
||||
$data['has_agent'] = (bool) $agent;
|
||||
|
||||
$this->success('获取成功', null, $user);
|
||||
$this->success('获取成功', null, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
在新工单中引用
屏蔽一个用户