Files
zszq-trs/YLErpWeb/wwwroot/Scripts/app/swaptrade/tradeEndConfirmList.js
T
hjhan fa927b2133 fix(zszq-trs): 结算确认书列表新增每行发送邮件按钮,复用 BatchSendSettleEmail
- 新增 tradeEndConfirmSendEmail.js(独立文件降冲突),含纯函数 buildSettleEmailSendPayload 便于单测
- tradeEndConfirmList.js showToolName 加按钮,受 pageData.canSendEmail + ContractDocUrl 控制,跳过"多空组合"
- cshtml 引入新脚本;后端零改动(复用 SwapEndConfirmService.BatchSendSettleEmail -> bond-oms Java)
- 安全: 新按钮不引入新增 XSS/CSRF 暴露; CSRF token 缺失为全站既有问题,与批量按钮同源
2026-08-21 13:21:15 +08:00

550 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
function ShowNotionalFormater(cellValue, options, rowObject) {
return otcformat.trading.umprice(rowObject.swap_flow_event.Quantity);
}
function ShowTradeStatusFormater(cellValue, options, rowObject) {
return cellValue == 0 ? "已平仓" : "部分平仓";
}
function gridComplete() {
$(".selftooltip").tooltip({ html: true, show: 50000, trigger: "hover" });
}
function showToolName(cellValue, options, rowObject) {
var html =
"<input type=\"button\" class=\"wentiEdit\" title='查看交易信息' onclick=\"starttradeView('{0}','{2}')\" value=\"{1}\" />"
.template(rowObject.trade.EncryptId, "查看", rowObject.trade.TradeType);
if (rowObject.ContractDocUrl != undefined && rowObject.ContractDocUrl != null && rowObject.ContractDocUrl != "") {
html +=
"<input type=\"button\" class=\"wentiEdit\" title='下载结算确认书' style=\"width: 50px!important;\" onclick=\"DownLoadDoc('{0}')\" value=\"{1}\" />"
.template(rowObject.ContractDocUrl, "下载");
} else {
html +=
"<input type=\"button\" class=\"wentiEdit\" title='未生成结算确认书' disabled='disabled' style=\"width: 50px!important;\" value=\"{0}\" />"
.template("下载");
}
//var disabled = pageData.canGenerate == true ? "" : "disabled";
//html += "<input type=\"button\" class=\"wentiEdit\" title='修改支付日期' onclick=\"ModifyPayDate('{0}','{1}')\" style=\"width: 120px!important;\" value=\"{2}\" {3}/>"
// .template(rowObject.swap_flow_event.EncryptId, rowObject.swap_flow_event.PayDate, "修改支付日期", disabled);
if (rowObject.ContractDocUrl && pageData.canSendEmail) {
html +=
"<input type=\"button\" class=\"wentiEdit\" title='发送结算确认书邮件到客户' onclick=\"sendSettleEmail('{0}','{1}')\" value=\"{2}\" />"
.template(rowObject.swap_flow_event.EncryptId, rowObject.trade.StructureType, "发送Email");
}
return html;
}
//下载清算确认书
function DownLoadDoc(res) {
window.open(res);
}
function closeModifyDateModal() {
$('#myModal').modal('hide');
}
function saveModifyPayDate() {
var id = $("#hidflowId").val();
var payDate = $("#payDateInput").val();
if (payDate == "" || payDate == undefined) {
main.alert("请选择支付日期");
return;
}
main.post("/swaptrade2/UpdatePayDate/", { Id: id, PayDate: payDate }, {
success: function (resp) {
if (resp.success) {
main.message("更新成功");
} else {
main.alert("更新失败");
}
$('#myModal').modal('hide');
SearchClick();
}
});
}
//修改支付日期
function ModifyPayDate(id, oldPayDate) {
$("#myModal").modal("show");
$("#hidflowId").val(id);
$("#payDateInput").val(oldPayDate.replace(" 00:00:00",""));
$("#payDateInput").datepicker({
changeMonth: true,
changeYear: true,
showButtonPanel: true,
showOtherMonths: true,
selectOtherMonths: true
});
}
function GenetateEndBillByReqDate() {
var jgrid = jQuery('#listGrid');
var flowEventIds = main.GetGridIds(jgrid);
if (flowEventIds.length === 0) {
main.message("请选择交易");
return;
}
main.confirm("请确认支付日期是否正确,如果正确请点击【确认】继续生成确认书,否则点击【取消】修改支付时间后再继续",
function () {
var htmlContent = '<form class="form-horizontal" role="form" style="padding:15px 12px 5px">' +
'<div class="form-group">' +
'<label class="col-sm-4 control-label">文档类型</label>' +
'<div class="btn-group col-sm-8" data-toggle="buttons">' +
'<label class="btn btn-sm btn-primary " style="border:none;display:none;"><input type="radio" name="docType" value="PDF"> PDF</label>' +
'<label class="btn btn-sm btn-primary active" style="border:none"><input checked type="radio" name="docType" value="Excel"> Excel</label>' +
'</div>' +
'</div>' +
'</form>';
GenerateSettleBills("DOC", flowEventIds);
});
//main.open2("生成结算确认书",
// htmlContent,
// {
// area: ["300px", "165px"],
// btn: ['生成', '取消'],
// yes: function (index, layero) {
// /*var docType = $('input[name="docType"]:checked').val();*/
// GenerateSettleBills("DOC", flowEventIds);
// },
// cancel: function (index, layero) {
// parent.layer.closeAll();
// },
// success: function (layero, index) {
// $(".btn-group").on("click",
// ".btn",
// function (event) {
// $('input[name="docType"]:checked').prop("checked", false);
// $(this).children("input").prop("checked", true);
// });
// }
// });
}
function GenerateSettleBills(docType, flowEventIds) {
var confirmBookPostData = { flowEventIds: flowEventIds, docType: docType };
main.post("/swaptrade2/GJGenerateSettleBillByFlowEventIds/", confirmBookPostData, {
success: function (resp) {
if (resp.success) {
main.downloadFiles(resp.obj);
} else {
main.alert(resp.msg.replace("\r\n", "<br/>"));
main.downloadFiles(resp.obj);
}
reloadtrade();
parent.layer.closeAll();
}
});
}
function starttradeView(id) {
main.open("查看交易", "/swaptrade2/tradeView/?enid=" + id + "&isOnlyCloseButton=true", { area: ['90%', '90%'] });
}
function reloadtrade() {
//重新加载
SearchClick();
$('#modal-edittrade').modal('hide');
}
function SendEmailEitherReport() {
var jgrid = jQuery('#listGrid');
var flowEventIds = main.GetGridIds(jgrid);
var selIds = [];
for (var i= 0; i < flowEventIds.length;i++) {
var rowData = $("#listGrid").jqGrid('getRowData', flowEventIds[i]);
if (rowData && rowData["trade.StructureType"]!="多空组合") {
selIds.push(flowEventIds[i]);
}
}
if (flowEventIds.length === 0) {
main.message("请选择交易");
return;
}
if (selIds.length === 0) {
main.message("请选择普通交易");
return;
}
// EQD-5320: 改走本系统后端代理(/swaptrade2/BatchSendSettleEmail → BondOmsInterface_BaseUrl → bond-oms)
// 与债券计算器同一条服务端出口;原直连 /trs_hub_api 反向代理在未配 nginx 的环境 404
var url = "/swaptrade2/BatchSendSettleEmail";
var postData = { swapFlowEventIds: selIds.join(',') }
$.ajax({
type: "post",
url: url,
data: postData,
dataType: "json",
success: function (res) {
// 兜底非标准返回结构,绝不让点击"无反应"
if (res && res.success) {
main.message(res.msg || ("发送成功(共" + selIds.length + "笔)"));
SearchClick(); // 刷新列表以反映发送状态
} else {
var msg = (res && (res.msg || res.message)) || "发送失败:服务返回异常结构";
main.message(msg);
console.error("[批量发送确认书] 业务失败:", res);
}
},
error: function (xhr, textStatus, errThrown) {
// 请求层失败:超时/返回非JSON(如被登录页重定向)
var detail = "HTTP " + xhr.status + " " + (textStatus || "") + (errThrown ? " " + errThrown : "");
main.message("发送请求失败(" + detail + "):请检查服务是否可用,详情见控制台与网络面板");
console.error("[批量发送确认书] 请求失败:", detail, xhr);
},
beforeSend(jqXHR) {
main.waitMe(true);
},
complete(jqXHR, textStatus) {
main.waitMe(false);
}
});
}
function SearchClick(isSearchclick) {
var listGrid = $('#listGrid');
listGrid.appendPostData({ TradeNumber: $("#TradeNumber").val() });
listGrid.appendPostData({ ClientIds: $("#ClientId").val() == null ? "" : $("#ClientId").val().join() });
listGrid.appendPostData({ AssetIds: ($("#AssetId").val() || []).join() });
listGrid.appendPostData({ AssetIdGroupList: $("#GroupId").val() });
listGrid.appendPostData({ TraderNames: $("#TraderName").val() == null ? "" : $("#TraderName").val().join(",") });
listGrid.appendPostData({ UnderlyingIds: $("#UnderlyingId").val() == null ? "" : $("#UnderlyingId").val().join() });
listGrid.appendPostData({ BuySell: $("#BuySell").val() });
listGrid.appendPostData({ StartDateStart: $("#DateFromStartDate").val() });
listGrid.appendPostData({ StartDateEnd: $("#DateToStartDate").val() });
listGrid.appendPostData({ UnWindDateStart: $("#DateFromUnWindDate").val() });
listGrid.appendPostData({ UnWindDateEnd: $("#DateToUnWindDate").val() });
listGrid.appendPostData({ Comments: $("#Comments").val() });
listGrid.appendPostData({ ExerciseDateStart: $("#DateFromExerciseDate").val() });
listGrid.appendPostData({ ExerciseDateEnd: $("#DateToExerciseDate").val() });
if (typeof (isSearchclick) != "undefined" && isSearchclick) {
//点击搜索时默认第一页
listGrid.jqGrid('setGridParam', { page: 1 });
}
listGrid.trigger('reloadGrid');
}
function BatchDownLoadDoc() {
var startDate = $("#DateFromUnWindDate").val();
var endDate = $("#DateToUnWindDate").val();
var clientIds = $("#ClientId").val();
var jgrid = jQuery('#listGrid');
var flowEventIds = main.GetGridIds(jgrid);
var tip = "下载" + startDate + "至" + endDate + "的结算确认书";
batchDownload(startDate, endDate, clientIds, flowEventIds, ["DOCX"]);
var htmlContent = '<form class="form-horizontal" role="form" style="padding:15px 12px 5px">' +
'<div class="form-group">' +
'<label style="padding:10px 12px 10px">' + tip + '</label><br />' +
'<label class="col-sm-5 control-label">文档类型</label>' +
'<label class="btn btn-sm btn-primary " style="border:none;display:none;"><input type="radio" name="docType" value="PDF"> PDF</label>' +
'<label class="btn btn-sm btn-primary active" style="border:none"><input checked type="radio" name="docType" value="Excel"> Excel</label>';
// main.open2("批量下载结算确认书",
// htmlContent + '</div></form>',
// {
// area: ["400px", "250px"],
// btn: ['下载', '取消'],
// yes: function (index, layero) {
// var docpdf = [];
// $('input[name="docType"]:checked').each(function (i) {
// docpdf.push($(this).val())
// })
// var isSeal = $("#SingleBookSeal").val() == '是' ? true : false;
// var confirmBookPostData = { TradeDateStart: startDate, TradeDateEnd: endDate, ClientIds: clientIds, TradeIds: null, flowEventIds: tradeCashIdList, docpdf: docpdf, IsSeal: isSeal };
// if (pageData.IsAutoSealAndUploadFiles) {
// confirmBookPostData.SealResults = $("#SealResults").val();
// //confirmBookPostData.SealDateStart = $("#DateFromSealDate").val();
// //confirmBookPostData.SealDateEnd = $("#DateToSealDate").val();
// }
// openWindowWithPost("/swaptrade2/BatchDownLoadDoc/", confirmBookPostData);
// parent.layer.closeAll();
// },
// cancel: function (index, layero) {
// parent.layer.closeAll();
// },
// success: function (layero, index) {
// $(".btn-group").on("click", ".btn", function (event) {
// $('input[name="docType"]:checked').prop("checked", false);
// $(this).children("input").prop("checked", true);
// });
// }
// });
}
function batchDownload(startDate, endDate, clientIds, flowEventIds, docpdf) {
var confirmBookPostData = { TradeDateStart: startDate, TradeDateEnd: endDate, ClientIds: clientIds, flowEventIds: flowEventIds, docpdf: docpdf };
openWindowWithPost("/swaptrade2/BatchDownLoadDoc/", confirmBookPostData);
parent.layer.closeAll();
}
function BatchDelDoc() {
var jgrid = jQuery('#listGrid');
var flowEventIds = main.GetGridIds(jgrid);
if (flowEventIds.length == 0) {
main.msg("未选择任何项");
return;
}
var confirmBookDelPostData = { flowEventIds: flowEventIds };
main.confirm("确认重置选定的结算确认书吗?", function () {
main.post("/swaptrade2/BatchDelDoc/", confirmBookDelPostData, {
success: function (resp) {
if (resp.success) {
main.message("重置成功");
reloadtrade();
} else {
main.alert(resp.msg);
}
}
});
});
}
function openWindowWithPost(url, data) {
var form = document.createElement("form");
form.target = "_blank";
form.method = "POST";
form.action = url;
form.style.display = "none";
for (var key in data) {
if (data[key] instanceof Array) {
if (data[key].length === 0) {
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = null;
form.appendChild(input);
}
else {
data[key].forEach((item, index, array) => {
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = data[key][index];
form.appendChild(input);
});
}
}
else {
var input1 = document.createElement("input");
input1.type = "hidden";
input1.name = key;
input1.value = data[key];
form.appendChild(input1);
}
}
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
const colModelGrid = (new function () {
this.setControl = function (encryptId) {
var button = "#bt_" + encryptId;
var inputSelect = "#ip_" + encryptId;
if ($(inputSelect).prop("disabled")) {
$(inputSelect).prop("disabled", false);
$(button).prop("title", "保存结算确认书编号");
$(button).html("<i class='fa fa-floppy-o'></i>");
} else {
this.changeCode(encryptId, $(inputSelect).val(), function () {
$(button).html("<i class='fa fa-pencil-square-o'></i>");
$(inputSelect).prop("disabled", true);
$(button).prop("title", "修改结算确认书编号");
});
}
}
this.changeCode = function (encryptId, code, callback) {
var data = new FormData();
data.append("encryptId", encryptId);
data.append("ContractCode", code);
$.ajax({
type: "Post",
//async: false,
url: "/trade/UploadContractFile",
contentType: false,
processData: false,
data: data,
success: function (res) {
main.message(res.msg);
if (!res.success) {
} else {
callback();
}
},
beforeSend(jqXHR) {
main.waitMe(true);
},
complete(jqXHR, textStatus) {
main.waitMe(false);
}
});
}
this.upload = function (encryptId) {
var srcurl = "/TradeConfirmBook/confirmBookUpload/?Id=" + encryptId;
main.open("上传确认书", srcurl, {
area: ['500px', '420px'],
end: SearchClick(true)
});
};
this.colModels = [
{
name: 'trade.id', label: 'trade.id', index: 'trade.id', width: 1, align: 'left', hidden: true
}, {
name: 'id', label: 'id', index: 'swap_flow_event.id', width: 1, align: 'left', hidden: true
}, {
name: 'swap_flow_event.EventId', label: 'swap_flow_event.EventId', index: 'swap_flow_event.EventId', width: 1, align: 'left', hidden: true
}, {
name: 'trade.EncryptId', label: 'EncryptId', index: 'trade.EncryptId', width: 0, align: 'left', hidden: true
}, {
name: 'trade_contract_r.id', label: 'trade_contract_r.id', index: 'trade_contract_r.id', width: 0, align: 'left', hidden: true
}, {
name: '', label: '操作', index: '', align: 'left', width: 300, formatter: showToolName
}, {
name: 'swap_position.PosiQuantity', label: '交易状态', index: 'swap_position.PosiQuantity', width: 70, align: 'left', formatter: ShowTradeStatusFormater
}, {
name: 'swap_flow_event.UnwindDate', label: '平仓日期', index: 'swap_flow_event.UnwindDate', width: 80, align: 'left', formatter: 'date'
}, {
name: 'swap_flow_event.PayDate', label: '支付日期', index: 'swap_flow_event.PayDate', width: 80, align: 'left', formatter: 'date'
}, {
name: 'trade.TradeNumber', label: '交易编号', index: 'trade.TradeNumber', width: 240, align: 'left'
}, {
name: 'ConfirmContractR.ContractCode', label: '合约编号', index: 'ConfirmContractR.ContractCode', width: 240, align: 'left'
}, {
name: 'ContractCode', label: '结算确认书编号', index: 'ContractCode', width: 240, align: 'left',
formatter: function (cellValue, options, rowObject) {
var html = "";
if (cellValue) {
if (!pageData.isWuChan) {
html += "<a href='javascript:;' title='修改结算确认书编号' id='bt_" + rowObject.trade_contract_document?.EncryptId + "' onclick='colModelGrid.setControl(\"" + rowObject.trade_contract_document?.EncryptId + "\")' ><i class='fa fa-pencil-square-o'></i></a>";
}
html += "<input style='width: 100%;' id='ip_" + rowObject.trade_contract_document?.EncryptId + "' type='text' value='" + cellValue + "' disabled />";
} else {
html = "";
}
return html;
}
}, {
name: 'trade.ClientName', label: '客户名称', index: 'trade.ClientName', width: 180, align: 'left'
}, {
name: 'swap_flow_event.Quantity', label: '份额', index: 'swap_flow_event.Quantity', width: 150, align: 'left', formatter: ShowNotionalFormater
}, {
name: 'swap_flow_event.TradingAmountAvg', label: '结算价', index: 'swap_flow_event.TradingAmountAvg', width: 150, align: 'left', formatter: otcformat.trading.umprice
}, {
name: 'swap_event.unwindData.SwapCloseAmount', label: '了结总额', index: 'swap_event.unwindData.SwapCloseAmount', width: 150, align: 'left', formatter: otcformat.trading.StockEqvNotional, sortable: false,
}, {
name: 'trade.TradeDate', label: '交易日期', index: 'trade.TradeDate', width: 90, align: 'left', formatter: 'date'
}, {
name: 'swap_flow_event.UnderlyingCode', label: '标的代码', index: 'swap_flow_event.UnderlyingCode', width: 120, align: 'left'
}, {
name: 'trade.StructureType', label: '结构类型', index: 'trade.StructureType', width: 110, align: 'left',
formatter: function (cellvalue, options, rowObject) {
return rowObject.trade.StructureType;
}
}, {
name: 'trade.ExerciseDate', label: '到期日期', index: 'trade.ExerciseDate', width: 90, align: 'left', formatter: 'date'
}, {
name: 'trade.StartDate', label: '开始日期', index: 'trade.StartDate', width: 90, align: 'left', formatter: 'date'
}, {
name: 'trade.AssetBookName', label: '簿记账户', index: 'trade.AssetBookName', width: 100, align: 'left'
}, {
name: 'trade.TraderName', label: '交易员', index: 'trade.TraderName', width: 70, align: 'left'
}, {
name: 'trade.Comments', label: '备注', index: 'trade.Comments', width: 140, align: 'left'
}, {
name: 'trade.OptName', label: '交易操作者', index: 'trade.OptName', width: 70, align: 'left'
}, {
name: 'swap_flow_event.OptTime', label: '交易操作时间', index: 'trade_cash.OptTime', width: 150, align: 'left', formatter: 'datetime'
}, {
name: 'trade_contract_document.OptName', label: '操作人', index: 'trade_contract_document.OptName', width: 70, align: 'left'
}, {
name: 'trade_contract_document.OptDate', label: '操作时间', index: 'trade_contract_document.OptDate', width: 100, align: 'left', formatter: 'date'
}]
}());
function __initJqGrid() {
var PostData = { UnWindDateStart: pageData.curDate, UnWindDateEnd: pageData.curDate, ValidState: $("#ValidState").val() };
let __jq = {
AfterInsertRow: typeof AfterInsertRow !== 'undefined' ? AfterInsertRow : void 0,
rowclick: typeof rowclick !== 'undefined' ? rowclick : void 0,
rowdblclick: typeof rowdblclick !== 'undefined' ? rowdblclick : void 0,
gridComplete: typeof gridComplete !== 'undefined' ? gridComplete : void 0,
onJqgridPaging: typeof onJqgridPaging !== 'undefined' ? onJqgridPaging : void 0
};
let grid = jQuery('#listGrid').jqGrid({
url: '/swaptrade2/EitherEndTradeReportQuery',
datatype: pageData.initEmptyView ? 'local' : 'json',
multiselect: true,
height: 'auto',
width: '90%',
autowidth: false,
shrinkToFit: false,
viewrecords: true,
jsonReader: { repeatitems: false },
cmTemplate: { align: 'center', width: 120 },
mtype: 'POST',
postData: PostData,
afterInsertRow: __jq.AfterInsertRow,
onSelectRow: __jq.rowclick,
ondblClickRow: __jq.rowdblclick,
colModel: colModelGrid.colModels,
pager: jQuery('#pagerGrid'),
pagerpos: 'left',
rowNum: 20,
rowList: [20, 30, 50, 200, 10000],
loadComplete: __jq.gridComplete,
onPaging: __jq.onJqgridPaging,
footerrow: false,
});
pageData.initEmptyView && jQuery("#listGrid").jqGrid('setGridParam', { datatype: 'json' });
}
$(function () {
$(".datepicker").datepicker({
changeMonth: true,
changeYear: true,
showButtonPanel: true,
showOtherMonths: true,
selectOtherMonths: true
});
$("#DateToUnWindDate").val(pageData.curDate);
if (!pageData.initEmptyView) {
$("#DateFromUnWindDate").val(pageData.curDate);
}
__initJqGrid();
document.onkeydown = function (event) {
try {
var e = event ? event : (window.event ? window.event : null);
if (e.keyCode === 13) {
SearchClick(true);
}
} catch (e) {
//
}
};
let underlyingCtrl = new tradeHelper.UnderlyingSelectCtrl('#UnderlyingId')
.setFlag(tradeHelper.UnderlyingSelectFlag.OtcTrade);
});