合并代码
This commit is contained in:
@@ -25,6 +25,19 @@ namespace YLErp.DBModels
|
||||
[Column("book_id")]
|
||||
public string BookIds { get; set; }
|
||||
|
||||
private string _bookScopeName;
|
||||
|
||||
/// <summary>
|
||||
/// 适用簿记账户名称,仅用于列表展示,不持久化。
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
[DisplayName("适用簿记账户")]
|
||||
public string BookScopeName
|
||||
{
|
||||
get => string.IsNullOrWhiteSpace(BookIds) ? "全部" : _bookScopeName ?? string.Empty;
|
||||
set => _bookScopeName = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将簿记账户ID列表规范化为去空格、去重的逗号分隔字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
using YLErp.DBModels;
|
||||
using YLErp.Modules.MarginModule;
|
||||
using YLErp.Modules.SwapModule;
|
||||
|
||||
namespace YLErp.Modules.CalcModules
|
||||
{
|
||||
[TestClass]
|
||||
public class MarginTemplateV2BookScopeTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void BS_001_空范围适用全部簿记账户()
|
||||
{
|
||||
var template = new margin_template_v2 { BookIds = null };
|
||||
|
||||
Assert.IsTrue(template.IsApplicableToBook(1));
|
||||
Assert.IsTrue(template.IsApplicableToBook(11));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BS_002_按完整token精确匹配避免1命中11()
|
||||
{
|
||||
var template = new margin_template_v2 { BookIds = "11, 12,11" };
|
||||
|
||||
Assert.IsFalse(template.IsApplicableToBook(1));
|
||||
Assert.IsTrue(template.IsApplicableToBook(11));
|
||||
Assert.IsTrue(template.IsApplicableToBook(12));
|
||||
Assert.AreEqual("11,12", margin_template_v2.NormalizeBookIds(template.BookIds));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BS_003_账户范围只接受正整数并规范前导零()
|
||||
{
|
||||
Assert.IsNull(margin_template_v2.NormalizeBookIds(null));
|
||||
Assert.IsNull(margin_template_v2.NormalizeBookIds(" "));
|
||||
Assert.AreEqual("1,2", margin_template_v2.NormalizeBookIds("001, 2,001"));
|
||||
|
||||
Assert.ThrowsException<ArgumentException>(() => margin_template_v2.NormalizeBookIds("abc"));
|
||||
Assert.ThrowsException<ArgumentException>(() => margin_template_v2.NormalizeBookIds("0"));
|
||||
Assert.ThrowsException<ArgumentException>(() => margin_template_v2.NormalizeBookIds("-1"));
|
||||
Assert.ThrowsException<ArgumentException>(() => margin_template_v2.NormalizeBookIds("1,,2"));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BS_004_范围重叠空范围视为全部()
|
||||
{
|
||||
Assert.IsTrue(margin_template_v2.AreBookScopesOverlapping(null, "11"));
|
||||
Assert.IsTrue(margin_template_v2.AreBookScopesOverlapping("11,12", "12,13"));
|
||||
Assert.IsFalse(margin_template_v2.AreBookScopesOverlapping("1", "11"));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BS_005_收集所有重叠范围的适用结构()
|
||||
{
|
||||
var candidates = new[]
|
||||
{
|
||||
new margin_template_v2 { BookIds = "1", TradeTypes = "收益互换" },
|
||||
new margin_template_v2 { BookIds = "2", TradeTypes = "香草期权" },
|
||||
new margin_template_v2 { BookIds = "3", TradeTypes = "远期" }
|
||||
};
|
||||
|
||||
var tradeTypes = margin_template_v2.GetOverlappingTradeTypes(candidates, "1,2").ToList();
|
||||
|
||||
CollectionAssert.AreEquivalent(new[] { "收益互换", "香草期权" }, tradeTypes);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void BS_006_空交易ID不触发簿记账户查询()
|
||||
{
|
||||
Assert.IsNull(MarginTemplateV2RateHelper.GetTradeAssetId(null, null));
|
||||
Assert.IsNull(MarginTemplateV2RateHelper.GetTradeAssetId(0, null));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LEGACY_001_存量原样未知名称可保留()
|
||||
{
|
||||
Assert.IsTrue(SwapTradeService.CanKeepLegacyMarginTemplateName(
|
||||
false, "历史模板", "历史模板", false));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LEGACY_002_新增交易的未知名称不可保留()
|
||||
{
|
||||
Assert.IsFalse(SwapTradeService.CanKeepLegacyMarginTemplateName(
|
||||
true, "历史模板", "历史模板", false));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LEGACY_003_修改为不同未知名称不可保留()
|
||||
{
|
||||
Assert.IsFalse(SwapTradeService.CanKeepLegacyMarginTemplateName(
|
||||
false, "历史模板", "另一历史模板", false));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LEGACY_004_已存在V2名称不作为历史值()
|
||||
{
|
||||
Assert.IsFalse(SwapTradeService.CanKeepLegacyMarginTemplateName(
|
||||
false, "模板V2", "模板V2", true));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LEGACY_005_空名称不作为历史值()
|
||||
{
|
||||
Assert.IsFalse(SwapTradeService.CanKeepLegacyMarginTemplateName(
|
||||
false, null, null, false));
|
||||
Assert.IsFalse(SwapTradeService.CanKeepLegacyMarginTemplateName(
|
||||
false, " ", " ", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using BaseOUDAL;
|
||||
using System.Globalization;
|
||||
using YLErp.Model;
|
||||
|
||||
namespace YLErp.Modules.MarginModule
|
||||
@@ -77,8 +78,67 @@ namespace YLErp.Modules.MarginModule
|
||||
}
|
||||
|
||||
var retListResult = query.ToSearchList(req);
|
||||
SetBookScopeNames(retListResult);
|
||||
|
||||
return retListResult;
|
||||
}
|
||||
|
||||
private void SetBookScopeNames(SearchListResult<margin_template_v2> result)
|
||||
{
|
||||
var rows = result?.rows?.ToList();
|
||||
if (rows == null || rows.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parsedRows = rows.Select(row => new
|
||||
{
|
||||
Row = row,
|
||||
BookIds = row == null ? new List<int>() : ParseBookIdsForDisplay(row.BookIds)
|
||||
}).ToList();
|
||||
var bookIds = parsedRows.SelectMany(item => item.BookIds).Distinct().ToList();
|
||||
var bookNames = bookIds.Count == 0
|
||||
? new Dictionary<int, string>()
|
||||
: DbContext.assetunit
|
||||
.AsNoTracking()
|
||||
.Where(book => bookIds.Contains(book.id))
|
||||
.Select(book => new { book.id, book.Name })
|
||||
.ToDictionary(book => book.id, book => book.Name);
|
||||
|
||||
foreach (var item in parsedRows)
|
||||
{
|
||||
if (item.Row == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
item.Row.BookScopeName = string.IsNullOrWhiteSpace(item.Row.BookIds)
|
||||
? "全部"
|
||||
: string.Join(",", item.BookIds
|
||||
.Where(bookId => bookNames.ContainsKey(bookId))
|
||||
.Select(bookId => bookNames[bookId]));
|
||||
}
|
||||
|
||||
result.rows = rows;
|
||||
}
|
||||
|
||||
private static List<int> ParseBookIdsForDisplay(string bookIds)
|
||||
{
|
||||
var ids = new List<int>();
|
||||
if (string.IsNullOrWhiteSpace(bookIds))
|
||||
{
|
||||
return ids;
|
||||
}
|
||||
|
||||
foreach (var rawId in bookIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (int.TryParse(rawId.Trim(), NumberStyles.None, CultureInfo.InvariantCulture, out var id) && id > 0)
|
||||
{
|
||||
ids.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,9 +244,10 @@ namespace YLErp.Modules.TradeModule
|
||||
// 3 + 结束:审批人批准,本地按通过处理;
|
||||
// 3 + 强制归档:OA 流程被强制关闭。正常情况下,本地发起
|
||||
// forceEndOaFlow 后记录会先变为“归档中”、成功后变为“已归档”,
|
||||
// 不会进入本轮待查询集合;若仍被查询到,则按客户确认的口径视为同意。
|
||||
// 0(非退回)及 1 + 审批人:草稿/待办,继续等待。
|
||||
// 其他组合也必须继续等待,不能仅凭 flowStatusType=1 或 3 推进本地流程。
|
||||
// 不会进入本轮待查询集合;若仍被查询到,则视为同意。
|
||||
// 0(非退回):草稿,继续等待。
|
||||
// 1 + 审批人:OA 待办,继续等待。
|
||||
// 其他组合也必须继续等待,不会仅凭 flowStatusType=1 或 3 推进本地流程。
|
||||
var isReturned = flowStatusType == "0" && flowNode == "退回";
|
||||
var isApproved = flowStatusType == "3"
|
||||
&& (flowNode == "结束" || flowNode == "强制归档");
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
isAdd = Model == null || Model.id == 0,
|
||||
marginTemplates = ViewBag.MarginTemplates,
|
||||
marginTemplate = ViewBag.MarginTemplate,
|
||||
clientMarginTemplate = Model,
|
||||
isGFSM = PS.Config.Company == CompanyEnum.广发商贸
|
||||
clientMarginTemplate = Model
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,26 +42,26 @@
|
||||
|
||||
<form id="marginTemplateV2Form" method="post" onsubmit="return false;">
|
||||
<div class="row no-gutters">
|
||||
<div class="col form-layout" style="height: 520px; overflow-y: auto;">
|
||||
<div class="col form-layout tpl-base" style="height: 520px; overflow-y: auto;">
|
||||
<div class="border">
|
||||
<P>新模板信息</P>
|
||||
|
||||
@if (pageObj.isGFSM)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label class="formlabel">客户等级</label>
|
||||
<select v-model="clientMarginTemplate.ClientLevel" :disabled="isClientLevelDisabled" id="ClientLevel">
|
||||
<option value="">---</option>
|
||||
<option v-for="item in clientLevels" :value="item.Value">{{item.Text}}</option>
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<label class="formlabel">客户名称</label>
|
||||
<select v-model="clientMarginTemplate.ClientId" :disabled="isClientNameDisabled" id="ClientId">
|
||||
<option value="0">---</option>
|
||||
<option v-for="item in clientNames" :value="item.Value">{{item.Text}}</option>
|
||||
</select>
|
||||
@if (pageObj.isAdd)
|
||||
{
|
||||
@*新增:客户多选(类似适用簿记账户),保存时按选中客户逐条调用原有单条保存接口*@
|
||||
<select id="ClientId" class="chosen-select" multiple data-placeholder="请选择客户" style="width:260px;" v-model="selectedClientIds">
|
||||
<option v-for="item in clientNames" v-bind:value="item.Value">{{item.Text}}</option>
|
||||
</select>
|
||||
}
|
||||
else
|
||||
{
|
||||
@*编辑:单条绑定,仅改模板/日期,客户不可多选*@
|
||||
<select v-model="clientMarginTemplate.ClientId" id="ClientId">
|
||||
<option v-for="item in clientNames" v-bind:value="item.Value">{{item.Text}}</option>
|
||||
</select>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@@ -98,7 +97,7 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label class="formlabel">规则描述</label>
|
||||
<textarea class="text-box" rows="3" style="width: 320px; text-align:left;" v-model="marginTemplate.Comments" v-bind:title="marginTemplate.Comments" disabled>
|
||||
<textarea class="text-box" rows="3" style="text-align:left;" v-model="marginTemplate.Comments" v-bind:title="marginTemplate.Comments" disabled>
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
@@ -170,26 +169,6 @@
|
||||
<div class="border detail" v-show="marginTemplate.RuleType != @((int)MarginRuleTypeEnum.区间追保结构)">
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
@if (PS.Config.Company == CompanyEnum.广发商贸)
|
||||
{
|
||||
<template v-if="marginTemplate.RuleType == @((int)MarginRuleTypeEnum.默认预付金规则)">
|
||||
<div class="form-group">
|
||||
<label class="formlabel">Span涨跌幅选择</label>
|
||||
<select v-model="detail.SpanConfig.SpanRateType" disabled>
|
||||
<option value="@((int)DetailSpanRateTypeEnum.Span涨跌幅度)">@DetailSpanRateTypeEnum.Span涨跌幅度.ToString()</option>
|
||||
<option value="@((int)DetailSpanRateTypeEnum.Span涨跌幅度2)">@DetailSpanRateTypeEnum.Span涨跌幅度2.ToString()</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="formlabel">初始预付金系数</label>
|
||||
<input class="text-box" v-model="detail.SpanConfig.InitialMarginFactor" disabled />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="formlabel">发生追保时系数</label>
|
||||
<input class="text-box" v-model="detail.SpanConfig.CoefficientFactor" disabled/>
|
||||
</div>
|
||||
</template>
|
||||
}
|
||||
<template v-if="marginTemplate.RuleType == @((int)MarginRuleTypeEnum.按固定利率) || marginTemplate.RuleType == @((int)MarginRuleTypeEnum.按浮动盈亏)">
|
||||
<div class="form-group">
|
||||
<label class="formlabel">持仓预付金率</label>
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
name: 'RuleType', label: '预付金规则', index: 'RuleType', width: 150, formatter: ruleTypeFormat
|
||||
}, {
|
||||
name: 'TradeTypes', label: '适用结构', index: 'TradeTypes', width: 460
|
||||
}, {
|
||||
name: 'BookScopeName', label: '适用簿记账户', index: 'BookScopeName', width: 240
|
||||
}];
|
||||
|
||||
function showToolName(cellValue, options, rowObject) {
|
||||
@@ -197,4 +199,4 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@Html.Raw(JqGridSimple.OutTable())
|
||||
@Html.Raw(JqGridSimple.OutTable())
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
name: 'RuleType', label: '预付金规则', index: 'RuleType', width: 150, formatter: ruleTypeFormat
|
||||
}, {
|
||||
name: 'TradeTypes', label: '适用结构', index: 'TradeTypes', width: 460
|
||||
}, {
|
||||
name: 'BookScopeName', label: '适用簿记账户', index: 'BookScopeName', width: 240
|
||||
}, {
|
||||
name: 'BuySellTypeName', label: '适用买卖方向', index: 'BuySellTypeName', width: 150
|
||||
}, {
|
||||
@@ -201,4 +203,4 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@Html.Raw(JqGridSimple.OutTable())
|
||||
@Html.Raw(JqGridSimple.OutTable())
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
const consClients = ylotc.clients;
|
||||
|
||||
//定价格式化(来自配置)
|
||||
//定价格式化(来自配置)
|
||||
const inputFormatPercent = Object.freeze({ precision: 2, append: '%' });
|
||||
const inputFormatPercentNegative = Object.freeze({ precision: 2, append: '%', negative: true });
|
||||
const inputFormatNegative = Object.freeze({ precision: 2, negative: true });
|
||||
@@ -26,10 +24,9 @@ const vue = new Vue({
|
||||
clientMarginTemplate: page.clientMarginTemplate,
|
||||
marginTemplates: page.marginTemplates,
|
||||
marginTemplate: page.marginTemplate,
|
||||
clientLevels: [],
|
||||
clientNames: [],
|
||||
isClientLevelDisabled: false,
|
||||
isClientNameDisabled: false,
|
||||
//新增模式的客户多选(编辑模式仍为单条绑定,走 clientMarginTemplate.ClientId)
|
||||
selectedClientIds: [],
|
||||
isAdd: page.isAdd
|
||||
},
|
||||
created: function () {
|
||||
@@ -116,10 +113,6 @@ const vue = new Vue({
|
||||
amountBase: '期初全价 × 券面总额'
|
||||
};
|
||||
},
|
||||
//changeClient(yldata) {
|
||||
// let client = yldata || { id: 0 };
|
||||
// this.clientMarginTemplate.ClientId = client.id;
|
||||
//},
|
||||
changeMarginTemplate() {
|
||||
this.marginTemplates.forEach(x => {
|
||||
if (this.clientMarginTemplate.MarginTemplateId === x.id) {
|
||||
@@ -127,15 +120,54 @@ const vue = new Vue({
|
||||
$('#suitableType').prop('title', this.marginTemplate.TradeTypes);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
//新增=多选:按选中客户逐条调用原有单条保存接口(后端不变,每条走完整互斥校验);
|
||||
//编辑=单条,保持原行为。逐条收集成败,结束统一汇总——部分失败时列表刷新已成功部分,弹窗留在
|
||||
//当前内容上供修正重试(已成功的客户重试会因同天同结构互斥校验失败,不会重复入库)
|
||||
saveMarginTemplateV2() {
|
||||
var thisObj = this;
|
||||
main.post("/client_margin_template/saveClientMarginTemplate", { clientMarginTemplate: thisObj.clientMarginTemplate }).done(function (resp) {
|
||||
try {
|
||||
window.parent.reloadmargin_template();
|
||||
(parent || window).layer.closeAll();
|
||||
} catch (e) { }
|
||||
var ids = this.isAdd ? (this.selectedClientIds || []) : [this.clientMarginTemplate.ClientId];
|
||||
if (!ids.length) {
|
||||
main.message("请至少选择一个客户");
|
||||
return;
|
||||
}
|
||||
if (!this.clientMarginTemplate.MarginTemplateId) {
|
||||
main.message("请选择有效的预付金模板");
|
||||
return;
|
||||
}
|
||||
var okCount = 0;
|
||||
var fails = [];
|
||||
var chain = Promise.resolve();
|
||||
ids.forEach(function (clientId) {
|
||||
chain = chain.then(function () {
|
||||
//深拷贝:逐条改写 ClientId/id,绝不污染 Vue 表单对象(部分失败时弹窗保持打开)
|
||||
var payload = _.cloneDeep(thisObj.clientMarginTemplate);
|
||||
payload.ClientId = clientId;
|
||||
payload.id = thisObj.isAdd ? 0 : thisObj.clientMarginTemplate.id;
|
||||
//alertFn 置空:单条失败不逐个弹窗,由循环结束后统一汇总
|
||||
return main.post("/client_margin_template/saveClientMarginTemplate",
|
||||
{ clientMarginTemplate: payload },
|
||||
{ alertFn: function () { }, suppressError: true }
|
||||
).then(function () {
|
||||
okCount++;
|
||||
}, function (resp) {
|
||||
fails.push({ id: clientId, msg: (resp && (resp.msg || resp.errmsg)) || "保存失败" });
|
||||
});
|
||||
});
|
||||
});
|
||||
chain.then(function () {
|
||||
try { window.parent.reloadmargin_template(); } catch (e) { }
|
||||
if (!fails.length) {
|
||||
try { (parent || window).layer.closeAll(); } catch (e) { }
|
||||
return;
|
||||
}
|
||||
var nameOf = function (cid) {
|
||||
var c = thisObj.clientNames.find(function (x) { return String(x.Value) === String(cid); });
|
||||
return c ? c.Text : cid;
|
||||
};
|
||||
var detail = fails.map(function (f) { return nameOf(f.id) + ":" + f.msg; }).join("<br>");
|
||||
main.alert("成功 " + okCount + " 条,失败 " + fails.length + " 条:<br>" + detail);
|
||||
});
|
||||
},
|
||||
showTemplateDetail(detail) {
|
||||
@@ -146,28 +178,6 @@ const vue = new Vue({
|
||||
vueDetail.ruleType = vue.marginTemplate.RuleType;
|
||||
$("#myModal").modal("show");
|
||||
},
|
||||
SetClientLevelDropDown() {
|
||||
$.ajax({
|
||||
type: "get",
|
||||
url: "/client_margin_template/GetAllClientLevels",
|
||||
success: function (data) {
|
||||
if (data.obj) {
|
||||
for (var i = 0; i < data.obj.length; i++) {
|
||||
vue.clientLevels.push(data.obj[i]);
|
||||
}
|
||||
|
||||
if (vue.isAdd) {
|
||||
vue.clientMarginTemplate.ClientLevel = data.obj[0].Value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
error: function (msg) {
|
||||
alert("error:" + msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
SetClientNameDropDown() {
|
||||
$.ajax({
|
||||
type: "get",
|
||||
@@ -179,6 +189,14 @@ const vue = new Vue({
|
||||
vue.clientNames.push(data.obj[i]);
|
||||
}
|
||||
}
|
||||
//选项就位后再初始化/刷新 chosen(多选客户),并同步"有选中即隐藏搜索框"行为
|
||||
Vue.nextTick(function () {
|
||||
SetAceDropDown();
|
||||
$('.chosen-select').trigger('chosen:updated');
|
||||
$('select.chosen-select[multiple]').each(function () {
|
||||
refreshChosenSearchField(this);
|
||||
});
|
||||
});
|
||||
},
|
||||
error: function (msg) {
|
||||
alert("error:" + msg);
|
||||
@@ -187,58 +205,11 @@ const vue = new Vue({
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (page.isGFSM) {
|
||||
if (this.isAdd) {
|
||||
this.isClientNameDisabled = true;
|
||||
}
|
||||
else {
|
||||
if (this.clientMarginTemplate.ClientId == "0") this.isClientNameDisabled = true;
|
||||
if (this.clientMarginTemplate.ClientLevel == "") this.isClientLevelDisabled = true;
|
||||
}
|
||||
|
||||
this.SetClientLevelDropDown();
|
||||
|
||||
}
|
||||
this.SetClientNameDropDown();
|
||||
if (this.marginTemplate.TradeTypes != null && this.marginTemplate.TradeTypes != 'undefined') {
|
||||
$('#suitableType').prop('title', this.marginTemplate.TradeTypes);
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
'clientMarginTemplate.ClientLevel': {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal == '') {
|
||||
this.isClientLevelDisabled = true;
|
||||
this.isClientNameDisabled = false;
|
||||
|
||||
if (this.clientMarginTemplate.ClientId == '0') {
|
||||
if (this.clientNames.length > 0) {
|
||||
this.clientMarginTemplate.ClientId = this.clientNames[0].Value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
immediate: false
|
||||
},
|
||||
'clientMarginTemplate.ClientId': {
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal == '0') {
|
||||
this.isClientNameDisabled = true;
|
||||
this.isClientLevelDisabled = false;
|
||||
if (this.clientMarginTemplate.ClientLevel == '') {
|
||||
if (this.clientLevels.length > 0) {
|
||||
this.clientMarginTemplate.ClientLevel = this.clientLevels[0].Value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
immediate: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'vue-datepicker': FastVue.vueDatePicker(),
|
||||
@@ -246,6 +217,17 @@ const vue = new Vue({
|
||||
}
|
||||
});
|
||||
|
||||
//多选 chosen:已有选中项后隐藏搜索框(与 marginTemplateV2*Edit.js 同款行为)——
|
||||
//空框没有输入内容却占一行,放不下时还会换行留白;全部取消后恢复占位提示。
|
||||
//须为顶层函数:SetClientNameDropDown 的 nextTick 回调也会调用
|
||||
function refreshChosenSearchField(select) {
|
||||
var $sel = $(select);
|
||||
var $container = $sel.next('.chosen-container-multi');
|
||||
if ($container.length === 0) return;
|
||||
var noneSelected = $sel.find('option:selected').length === 0;
|
||||
$container.find('li.search-field').toggle(noneSelected);
|
||||
}
|
||||
|
||||
$(function () {
|
||||
$(".datepicker").change(function () {
|
||||
var dateVal = $(this).val();
|
||||
@@ -269,33 +251,15 @@ $(function () {
|
||||
$(this).datepicker("setDate", dateVal);
|
||||
});
|
||||
|
||||
//勾选变化走原 select 的 jQuery change 委托(chosen trigger_form_field_change),在此统一刷新搜索框
|
||||
$(document).on('change chosen:updated', 'select.chosen-select[multiple]', function () {
|
||||
refreshChosenSearchField(this);
|
||||
});
|
||||
|
||||
SetAceDropDown();
|
||||
|
||||
var width = 152;
|
||||
for (var i = 0; i < consClients.length; i++) {
|
||||
let ele = document.createElement('span')
|
||||
ele.innerText = consClients[i].Name;
|
||||
ele.style.fontSize = '14px';
|
||||
document.documentElement.append(ele);
|
||||
var charLength = ele.offsetWidth + 28;//滚动条
|
||||
document.documentElement.removeChild(ele);
|
||||
if (charLength > width) {
|
||||
width = charLength
|
||||
}
|
||||
}
|
||||
|
||||
//if (!page.isGFSM) {
|
||||
// let autoClient = FastVue.autocomplete(document.getElementById('ClientId'), {
|
||||
// nameField: 'Name', valueField: 'id', searchField: ['Name', 'PinYin'], width: width,
|
||||
// lookup: consClients, onSelect: vue.changeClient
|
||||
// });
|
||||
// let clientId = page.clientMarginTemplate.ClientId;
|
||||
// let client = clientId ? consClients.find(x => x.id === clientId) : null;
|
||||
// !client && page.isAdd && (client = consClients[0]);
|
||||
// autoClient.setData(client);
|
||||
// vue.changeClient(client);
|
||||
//}
|
||||
|
||||
$('select.chosen-select[multiple]').each(function () {
|
||||
refreshChosenSearchField(this);
|
||||
});
|
||||
});
|
||||
|
||||
var vueDetail = new Vue({
|
||||
|
||||
@@ -631,15 +631,16 @@ $(function () {
|
||||
if (!isNaN(idx)) vue.onUnderlyingTypeChange(idx);
|
||||
});
|
||||
|
||||
//多选 chosen:可选项已全部选中时隐藏搜索框——没有剩余项可选,空搜索框只会把控件撑高一截;
|
||||
//取消勾选后自动恢复。勾选变化会触发原 select 的 jQuery change(trigger_form_field_change),
|
||||
//多选 chosen:已有选中项后隐藏搜索框——空框没有输入内容却占一行,放不下时还会换行留白
|
||||
//(本页多选均为点选场景,无需键盘过滤);全部取消后恢复,显示"请选择…"占位。
|
||||
//勾选变化会触发原 select 的 jQuery change(trigger_form_field_change),
|
||||
//加载重建/增删区块后的 refreshChosen 会触发 chosen:updated,两处都走这里的委托统一刷新
|
||||
function refreshChosenSearchField(select) {
|
||||
var $sel = $(select);
|
||||
var $container = $sel.next('.chosen-container-multi');
|
||||
if ($container.length === 0) return;
|
||||
var allSelected = $sel.find('option').length > 0 && $sel.find('option:not(:selected)').length === 0;
|
||||
$container.find('li.search-field').toggle(!allSelected);
|
||||
var noneSelected = $sel.find('option:selected').length === 0;
|
||||
$container.find('li.search-field').toggle(noneSelected);
|
||||
}
|
||||
$(document).on('change chosen:updated', 'select.chosen-select[multiple]', function () {
|
||||
refreshChosenSearchField(this);
|
||||
|
||||
@@ -599,15 +599,16 @@ $(function () {
|
||||
if (!isNaN(idx)) vue.onUnderlyingTypeChange(idx);
|
||||
});
|
||||
|
||||
//多选 chosen:可选项已全部选中时隐藏搜索框——没有剩余项可选,空搜索框只会把控件撑高一截;
|
||||
//取消勾选后自动恢复。勾选变化会触发原 select 的 jQuery change(trigger_form_field_change),
|
||||
//多选 chosen:已有选中项后隐藏搜索框——空框没有输入内容却占一行,放不下时还会换行留白
|
||||
//(本页多选均为点选场景,无需键盘过滤);全部取消后恢复,显示"请选择…"占位。
|
||||
//勾选变化会触发原 select 的 jQuery change(trigger_form_field_change),
|
||||
//加载重建/增删区块后的 refreshChosen 会触发 chosen:updated,两处都走这里的委托统一刷新
|
||||
function refreshChosenSearchField(select) {
|
||||
var $sel = $(select);
|
||||
var $container = $sel.next('.chosen-container-multi');
|
||||
if ($container.length === 0) return;
|
||||
var allSelected = $sel.find('option').length > 0 && $sel.find('option:not(:selected)').length === 0;
|
||||
$container.find('li.search-field').toggle(!allSelected);
|
||||
var noneSelected = $sel.find('option:selected').length === 0;
|
||||
$container.find('li.search-field').toggle(noneSelected);
|
||||
}
|
||||
$(document).on('change chosen:updated', 'select.chosen-select[multiple]', function () {
|
||||
refreshChosenSearchField(this);
|
||||
|
||||
@@ -137,10 +137,13 @@ p {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
/*多选 chosen 的隐藏搜索框:全局 input[type=text] 152px 会把它撑宽到与已选标签挤不下而换行,
|
||||
在控件底部留出一截空行;限制宽度使 标签+搜索框 保持单行*/
|
||||
.form-layout .chosen-container-multi .chosen-choices li.search-field input {
|
||||
max-width: 70px;
|
||||
/*多选 chosen:有选中项后由页面 JS 隐藏搜索框(见 marginTemplateV2*Edit.js 的 refreshChosenSearchField),
|
||||
空态时搜索框独占控件全宽,负责展示"请选择…"占位*/
|
||||
|
||||
/*期限档位表操作列:delBtn 的 20px 左边距在 fixed 布局的窄列里会把"- 删除区块"挤成竖排*/
|
||||
.border.detail td .delBtn {
|
||||
margin-left: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/*区块标题(新模板信息/选择模板规则/参数组N):左色条 + 加粗,与表单正文分层*/
|
||||
@@ -160,3 +163,9 @@ p {
|
||||
.border.detail table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
/*标的资产类型多选(期限档位表单元格内):chosen 初始化取原生 select 的固有宽度(约 150px),
|
||||
窄容器放不下第二个已选标签,导致标签逐行竖排;单元格空间充足,容器撑满即可横向排列*/
|
||||
.border.detail .chosen-container-multi {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user