```
feat(shopro_wechat_trade): 微信同步页面优化及数据格式化功能 - 新增formatListItem方法对同步记录数据进行格式化处理, 包括同步类型、状态、发货模式和错误信息的中文映射 - 实现统计项点击筛选功能,添加高亮状态指示器 - 重构前端JavaScript代码,使用预格式化数据字段提升显示性能 - 添加详情弹窗功能,支持查看完整的同步请求响应内容 - 优化重试按钮交互,增加确认提示防止误操作 - 更新页面布局样式,改善用户界面体验 ```
这个提交包含在:
@@ -1,6 +1,80 @@
|
||||
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
|
||||
var SYNC_TYPE_MAP = {
|
||||
shipping: '发货同步',
|
||||
confirm: '确认收货同步'
|
||||
};
|
||||
|
||||
var DELIVERY_MODE_MAP = {
|
||||
1: '统一发货',
|
||||
2: '分拆发货'
|
||||
};
|
||||
|
||||
function escapeHtml(text) {
|
||||
return $('<div/>').text(text == null ? '' : text).html();
|
||||
}
|
||||
|
||||
function formatSyncTypeBadge(row) {
|
||||
var key = row.sync_type || '';
|
||||
var text = row.sync_type_text || SYNC_TYPE_MAP[key] || key || '-';
|
||||
if (key === 'shipping') {
|
||||
return '<span class="label label-info">' + escapeHtml(text) + '</span>';
|
||||
}
|
||||
if (key === 'confirm') {
|
||||
return '<span class="label label-primary">' + escapeHtml(text) + '</span>';
|
||||
}
|
||||
return escapeHtml(text);
|
||||
}
|
||||
|
||||
function formatStatusBadge(row) {
|
||||
var text = row.status_text || '';
|
||||
var status = row.status || '';
|
||||
if (!text) {
|
||||
var retryCount = parseInt(row.retry_count, 10) || 0;
|
||||
if (status === 'success') {
|
||||
text = '成功';
|
||||
} else if (status === 'failed') {
|
||||
text = '失败';
|
||||
} else if (status === 'pending') {
|
||||
text = retryCount > 0 ? '待重试' : '处理中';
|
||||
} else {
|
||||
text = status || '-';
|
||||
}
|
||||
}
|
||||
if (status === 'success') {
|
||||
return '<span class="label label-success">' + escapeHtml(text) + '</span>';
|
||||
}
|
||||
if (status === 'failed') {
|
||||
return '<span class="label label-danger">' + escapeHtml(text) + '</span>';
|
||||
}
|
||||
if (status === 'pending') {
|
||||
var pendingClass = (parseInt(row.retry_count, 10) || 0) > 0 ? 'label-warning' : 'label-default';
|
||||
return '<span class="label ' + pendingClass + '">' + escapeHtml(text) + '</span>';
|
||||
}
|
||||
return escapeHtml(text);
|
||||
}
|
||||
|
||||
function formatJsonText(raw) {
|
||||
if (!raw) {
|
||||
return '(无)';
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(JSON.parse(raw), null, 2);
|
||||
} catch (e) {
|
||||
return raw;
|
||||
}
|
||||
}
|
||||
|
||||
function formatDatetime(value) {
|
||||
return value ? Table.api.formatter.datetime(value) : '-';
|
||||
}
|
||||
|
||||
var Controller = {
|
||||
index: function () {
|
||||
var $page = $('.wx-sync-page');
|
||||
var $statusFilter = $('#wx-sync-status-filter');
|
||||
var $typeFilter = $('#wx-sync-type-filter');
|
||||
var $orderSnFilter = $('#wx-sync-order-sn-filter');
|
||||
|
||||
Table.api.init({
|
||||
extend: {
|
||||
index_url: 'shopro_wechat_trade/sync/index',
|
||||
@@ -8,56 +82,214 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||
}
|
||||
});
|
||||
|
||||
var table = $("#table");
|
||||
var table = $('#table');
|
||||
|
||||
function highlightStat(status) {
|
||||
$page.find('.stat-item').removeClass('stat-item-active');
|
||||
$page.find('.stat-item[data-status="' + (status || '') + '"]').addClass('stat-item-active');
|
||||
}
|
||||
|
||||
function refreshTable() {
|
||||
table.bootstrapTable('refresh', { pageNumber: 1 });
|
||||
}
|
||||
|
||||
function applyStatusFilter(status) {
|
||||
$statusFilter.val(status || '');
|
||||
highlightStat(status || '');
|
||||
refreshTable();
|
||||
}
|
||||
|
||||
table.bootstrapTable({
|
||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||
pk: 'id',
|
||||
sortName: 'id',
|
||||
sortOrder: 'desc',
|
||||
search: false,
|
||||
commonSearch: false,
|
||||
showExport: false,
|
||||
queryParams: function (params) {
|
||||
params.status = $('#status-filter').val();
|
||||
params.status = $statusFilter.val();
|
||||
params.sync_type = $typeFilter.val();
|
||||
params.order_sn = $.trim($orderSnFilter.val());
|
||||
return params;
|
||||
},
|
||||
columns: [
|
||||
{ field: 'id', title: 'ID' },
|
||||
{ field: 'order_sn', title: '订单号' },
|
||||
{ field: 'sync_type', title: '类型' },
|
||||
{ field: 'status', title: '状态' },
|
||||
{ field: 'delivery_mode', title: '发货模式' },
|
||||
{ field: 'errcode', title: 'errcode' },
|
||||
{ field: 'errmsg', title: 'errmsg' },
|
||||
{ field: 'retry_count', title: '重试次数' },
|
||||
{ field: 'id', title: 'ID', width: 70 },
|
||||
{
|
||||
field: 'order_sn',
|
||||
title: '订单号',
|
||||
formatter: function (value, row) {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
if (row.order_id) {
|
||||
return '<a href="javascript:;" class="btn-link btn-order" data-id="' + row.order_id + '">' + escapeHtml(value) + '</a>';
|
||||
}
|
||||
return escapeHtml(value);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'sync_type_text',
|
||||
title: '类型',
|
||||
escape: false,
|
||||
formatter: function (value, row) {
|
||||
return formatSyncTypeBadge(row);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'status_text',
|
||||
title: '状态',
|
||||
escape: false,
|
||||
formatter: function (value, row) {
|
||||
return formatStatusBadge(row);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'delivery_mode_text',
|
||||
title: '发货模式',
|
||||
formatter: function (value, row) {
|
||||
if ((row.sync_type || '') !== 'shipping') {
|
||||
return '<span class="text-muted">-</span>';
|
||||
}
|
||||
return escapeHtml(value || '-');
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'error_text',
|
||||
title: '错误信息',
|
||||
formatter: function (value, row) {
|
||||
if (row.status === 'success' || value === '-') {
|
||||
return '<span class="text-muted">-</span>';
|
||||
}
|
||||
return escapeHtml(value || '-');
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'retry_count',
|
||||
title: '重试次数',
|
||||
width: 90,
|
||||
formatter: function (value, row) {
|
||||
if (row.status === 'success') {
|
||||
return '<span class="text-muted">-</span>';
|
||||
}
|
||||
return value || 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'createtime',
|
||||
title: '创建时间',
|
||||
formatter: function (value) {
|
||||
return value ? Table.api.formatter.datetime(value) : '';
|
||||
}
|
||||
formatter: formatDatetime
|
||||
},
|
||||
{
|
||||
field: 'operate',
|
||||
title: '操作',
|
||||
width: 140,
|
||||
escape: false,
|
||||
table: table,
|
||||
events: Table.api.events.operate,
|
||||
formatter: function (value, row) {
|
||||
if (row.status === 'success') {
|
||||
return '-';
|
||||
var html = [];
|
||||
html.push('<a href="javascript:;" class="btn btn-xs btn-info btn-detail" data-id="' + row.id + '">详情</a>');
|
||||
if (row.status !== 'success') {
|
||||
html.push(' <a href="javascript:;" class="btn btn-xs btn-warning btn-retry" data-id="' + row.id + '">重试</a>');
|
||||
}
|
||||
return '<a href="javascript:;" class="btn btn-xs btn-warning btn-retry" data-id="' + row.id + '">重试</a>';
|
||||
return html.join('');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
$('#status-filter').on('change', function () {
|
||||
table.bootstrapTable('refresh');
|
||||
$page.on('click', '.stat-item', function () {
|
||||
applyStatusFilter($(this).data('status') || '');
|
||||
});
|
||||
|
||||
$statusFilter.on('change', function () {
|
||||
highlightStat($(this).val() || '');
|
||||
refreshTable();
|
||||
});
|
||||
|
||||
$typeFilter.on('change', refreshTable);
|
||||
|
||||
$page.on('click', '#wx-sync-btn-search', function (e) {
|
||||
e.preventDefault();
|
||||
refreshTable();
|
||||
});
|
||||
|
||||
$page.on('click', '#wx-sync-btn-reset', function (e) {
|
||||
e.preventDefault();
|
||||
$statusFilter.val('');
|
||||
$typeFilter.val('');
|
||||
$orderSnFilter.val('');
|
||||
highlightStat('');
|
||||
refreshTable();
|
||||
});
|
||||
|
||||
$page.on('click', '#wx-sync-btn-failed', function (e) {
|
||||
e.preventDefault();
|
||||
applyStatusFilter('failed');
|
||||
$typeFilter.val('');
|
||||
});
|
||||
|
||||
$orderSnFilter.on('keypress', function (e) {
|
||||
if (e.which === 13) {
|
||||
e.preventDefault();
|
||||
refreshTable();
|
||||
}
|
||||
});
|
||||
|
||||
table.on('click', '.btn-order', function () {
|
||||
Fast.api.open('shopro/order/order/detail?id=' + $(this).data('id'), '订单详情');
|
||||
});
|
||||
|
||||
table.on('click', '.btn-retry', function () {
|
||||
var id = $(this).data('id');
|
||||
$.post('shopro_wechat_trade/sync/retry', { id: id }, function (ret) {
|
||||
Backend.api.toastr[ret.code === 1 ? 'success' : 'error'](ret.msg);
|
||||
table.bootstrapTable('refresh');
|
||||
Layer.confirm('将重新向微信发起同步请求,是否继续?', { icon: 3, title: '确认重试' }, function (index) {
|
||||
Layer.close(index);
|
||||
$.post('shopro_wechat_trade/sync/retry', { id: id }, function (ret) {
|
||||
Backend.api.toastr[ret.code === 1 ? 'success' : 'error'](ret.msg);
|
||||
refreshTable();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
table.on('click', '.btn-detail', function () {
|
||||
var id = $(this).data('id');
|
||||
$.get('shopro_wechat_trade/sync/detail', { id: id }, function (ret) {
|
||||
if (ret.code !== 1) {
|
||||
Backend.api.toastr.error(ret.msg || '加载失败');
|
||||
return;
|
||||
}
|
||||
var row = ret.data || {};
|
||||
var $tpl = $('#sync-detail-template').clone().removeAttr('id').removeClass('hide');
|
||||
$tpl.find('.detail-id').text(row.id || '-');
|
||||
$tpl.find('.detail-order-sn').text(row.order_sn || '-');
|
||||
$tpl.find('.detail-sync-type').html(formatSyncTypeBadge(row));
|
||||
$tpl.find('.detail-status').html(formatStatusBadge(row));
|
||||
if (row.sync_type === 'shipping') {
|
||||
$tpl.find('.detail-delivery-mode').text(row.delivery_mode_text || DELIVERY_MODE_MAP[row.delivery_mode] || '-');
|
||||
$tpl.find('.detail-delivery-mode-row').show();
|
||||
} else {
|
||||
$tpl.find('.detail-delivery-mode-row').hide();
|
||||
}
|
||||
$tpl.find('.detail-retry').text(row.retry_count || 0);
|
||||
if (row.status === 'success') {
|
||||
$tpl.find('.detail-error-row').hide();
|
||||
} else {
|
||||
$tpl.find('.detail-error').text(row.error_text && row.error_text !== '-' ? row.error_text : '-');
|
||||
$tpl.find('.detail-error-row').show();
|
||||
}
|
||||
$tpl.find('.detail-create').text(formatDatetime(row.createtime));
|
||||
$tpl.find('.detail-update').text(formatDatetime(row.updatetime));
|
||||
$tpl.find('.detail-request').text(formatJsonText(row.request_payload));
|
||||
$tpl.find('.detail-response').text(formatJsonText(row.response_payload));
|
||||
|
||||
Layer.open({
|
||||
type: 1,
|
||||
title: '同步记录详情 #' + row.id,
|
||||
area: ['720px', '80%'],
|
||||
shadeClose: true,
|
||||
content: $tpl.prop('outerHTML')
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户