```
feat(split): 添加分账手动指定接收方功能 - 实现SplitManualService服务类,支持手动覆盖分账明细 - 新增SplitManual和SplitManualLog数据模型 - 修改SplitCalculator优先使用手动覆盖数据进行分账计算 - 添加分账记录手动指定接收方的数据库表结构 - 集成手动分账到汇付分账流程中,支持失败重试机制 - 添加商品详情内容更新SQL脚本用于汇付审核 ```
这个提交包含在:
@@ -18,9 +18,38 @@ define(['jquery', 'bootstrap', 'backend', 'form'], function ($, undefined, Backe
|
||||
status: '',
|
||||
channel: ''
|
||||
},
|
||||
splitHuifuOnly: !!(typeof Config !== 'undefined' && Config.splitHuifuOnly)
|
||||
splitHuifuOnly: !!(typeof Config !== 'undefined' && Config.splitHuifuOnly),
|
||||
manualDialogVisible: false,
|
||||
manualLoading: false,
|
||||
manualSaving: false,
|
||||
manualRow: null,
|
||||
manualContext: {
|
||||
order_sn: '',
|
||||
confirm_base: 0,
|
||||
max_split_amount: 0,
|
||||
has_manual: false,
|
||||
original_items: [],
|
||||
receiver_options: []
|
||||
},
|
||||
manualForm: {
|
||||
items: [],
|
||||
remark: ''
|
||||
},
|
||||
historyDrawerVisible: false,
|
||||
historyLoading: false,
|
||||
historyList: [],
|
||||
historyRow: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
manualItemsTotal() {
|
||||
var sum = 0;
|
||||
(this.manualForm.items || []).forEach(function (it) {
|
||||
sum += parseFloat(it.amount) || 0;
|
||||
});
|
||||
return sum;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList();
|
||||
},
|
||||
@@ -71,6 +100,18 @@ define(['jquery', 'bootstrap', 'backend', 'form'], function ($, undefined, Backe
|
||||
var n = parseFloat(v);
|
||||
return isNaN(n) ? '0.00' : n.toFixed(2);
|
||||
},
|
||||
roleTypeLabel(type) {
|
||||
var map = { platform: '平台', promoter: '推广员', regional_agent: '区域公司' };
|
||||
return map[type] || type || '接收方';
|
||||
},
|
||||
formatManualItemLine(it) {
|
||||
if (!it) return '—';
|
||||
var name = it.receiver_name || ('#' + (it.role_id || ''));
|
||||
var account = it.receiver_account || '';
|
||||
var amt = this.formatMoney(it.amount);
|
||||
var role = this.roleTypeLabel(it.role_type);
|
||||
return role + ' ' + name + (account ? ' (' + account + ')' : '') + ' ¥' + amt;
|
||||
},
|
||||
scrollCellWheel(e) {
|
||||
var el = e.currentTarget;
|
||||
if (!el || el.scrollWidth <= el.clientWidth) {
|
||||
@@ -85,6 +126,155 @@ define(['jquery', 'bootstrap', 'backend', 'form'], function ($, undefined, Backe
|
||||
if (!orderId) return;
|
||||
Fast.api.open('shopro/order/order/detail?id=' + orderId, '订单详情');
|
||||
},
|
||||
openManualDialog(row) {
|
||||
this.manualRow = row;
|
||||
this.manualDialogVisible = true;
|
||||
this.manualLoading = true;
|
||||
this.manualForm.remark = '';
|
||||
Fast.api.ajax({
|
||||
url: 'shopro/split/order/manualReceivers',
|
||||
type: 'GET',
|
||||
data: { split_order_id: row.id }
|
||||
}, (ret, res) => {
|
||||
var ctx = (res && res.data) ? res.data : {};
|
||||
this.manualContext = ctx;
|
||||
this.manualForm.items = this.cloneManualItems(ctx.current_items || []);
|
||||
if (!this.manualForm.items.length) {
|
||||
this.addManualRow();
|
||||
}
|
||||
this.manualLoading = false;
|
||||
return false;
|
||||
}, () => {
|
||||
this.manualLoading = false;
|
||||
this.manualDialogVisible = false;
|
||||
});
|
||||
},
|
||||
cloneManualItems(items) {
|
||||
return (items || []).map(function (it) {
|
||||
return {
|
||||
receiver_id: it.receiver_id || 0,
|
||||
role_type: it.role_type || 'promoter',
|
||||
amount: parseFloat(it.amount) || 0,
|
||||
description: it.description || '手动指定'
|
||||
};
|
||||
});
|
||||
},
|
||||
addManualRow() {
|
||||
this.manualForm.items.push({
|
||||
receiver_id: 0,
|
||||
role_type: 'promoter',
|
||||
amount: 0,
|
||||
description: '手动指定'
|
||||
});
|
||||
},
|
||||
removeManualRow(index) {
|
||||
this.manualForm.items.splice(index, 1);
|
||||
},
|
||||
onReceiverChange(row) {
|
||||
var opt = (this.manualContext.receiver_options || []).find(function (o) {
|
||||
return o.id === row.receiver_id;
|
||||
});
|
||||
if (opt) {
|
||||
row.role_type = opt.role_type || row.role_type;
|
||||
}
|
||||
},
|
||||
validateManualForm() {
|
||||
var items = this.manualForm.items || [];
|
||||
if (!items.length) {
|
||||
Layer.msg('请至少添加一行分账明细');
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (!items[i].receiver_id) {
|
||||
Layer.msg('第 ' + (i + 1) + ' 行请选择接收方');
|
||||
return false;
|
||||
}
|
||||
if (!items[i].amount || parseFloat(items[i].amount) <= 0) {
|
||||
Layer.msg('第 ' + (i + 1) + ' 行金额须大于 0');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var max = parseFloat(this.manualContext.max_split_amount) || 0;
|
||||
if (max > 0 && this.manualItemsTotal > max + 0.001) {
|
||||
Layer.msg('合计超过上限 ¥' + this.formatMoney(max));
|
||||
return false;
|
||||
}
|
||||
var base = parseFloat(this.manualContext.confirm_base) || 0;
|
||||
if (base > 0 && this.manualItemsTotal > base + 0.001) {
|
||||
Layer.msg('合计超过确认基数 ¥' + this.formatMoney(base));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
saveManual(andRetry) {
|
||||
if (!this.manualRow || !this.validateManualForm()) {
|
||||
return;
|
||||
}
|
||||
var url = andRetry
|
||||
? 'shopro/split/order/saveManualAndRetry'
|
||||
: 'shopro/split/order/saveManual';
|
||||
var tip = andRetry
|
||||
? '保存后将向汇付重新发起分账,是否继续?'
|
||||
: '仅保存覆盖配置,不会立即重试,是否继续?';
|
||||
var self = this;
|
||||
Layer.confirm(tip, { title: '确认', btn: ['确定', '取消'] }, function () {
|
||||
self.manualSaving = true;
|
||||
Fast.api.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
split_order_id: self.manualRow.id,
|
||||
items: self.manualForm.items,
|
||||
remark: self.manualForm.remark
|
||||
}
|
||||
}, () => {
|
||||
self.manualSaving = false;
|
||||
self.manualDialogVisible = false;
|
||||
self.getList();
|
||||
}, () => {
|
||||
self.manualSaving = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
clearManualOverride() {
|
||||
if (!this.manualRow) return;
|
||||
var self = this;
|
||||
Layer.confirm('清除后将恢复自动计算明细,是否继续?', { title: '清除手动指定', btn: ['清除', '取消'] }, function () {
|
||||
self.manualSaving = true;
|
||||
Fast.api.ajax({
|
||||
url: 'shopro/split/order/clearManual',
|
||||
type: 'POST',
|
||||
data: {
|
||||
split_order_id: self.manualRow.id,
|
||||
remark: self.manualForm.remark
|
||||
}
|
||||
}, () => {
|
||||
self.manualSaving = false;
|
||||
self.manualDialogVisible = false;
|
||||
self.getList();
|
||||
}, () => {
|
||||
self.manualSaving = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
openHistoryDrawer(row) {
|
||||
this.historyRow = row;
|
||||
this.historyDrawerVisible = true;
|
||||
this.historyLoading = true;
|
||||
this.historyList = [];
|
||||
Fast.api.ajax({
|
||||
url: 'shopro/split/order/manualHistory',
|
||||
type: 'GET',
|
||||
data: { order_id: row.order_id, limit: 50 }
|
||||
}, (ret, res) => {
|
||||
var data = (res && res.data) ? res.data : {};
|
||||
this.historyList = data.rows || [];
|
||||
this.historyLoading = false;
|
||||
return false;
|
||||
}, () => {
|
||||
this.historyLoading = false;
|
||||
});
|
||||
},
|
||||
retry(row) {
|
||||
var tip = this.splitHuifuOnly
|
||||
? '将向汇付重新发起该笔分账。若订单资金仍被冻结,请先发货/确认收货或按文档处理 FREEZE。'
|
||||
|
||||
在新工单中引用
屏蔽一个用户