FrontController.OtcFormat 原使用 ResponseCache(Duration=600, Location=Any), 导致在 Admin 配置页保存 OtcFormat 后,前端最长 600s 内仍返回旧内容, 表现为'改了配置前端不起效果',需手工加 ?v= 才能破缓存。 改为 NoStore 后保存即对所有用户立即生效。 同时在 FrontController 类注释补充完整排查文档: - 三个同名 otcformat.js 文件的角色与路径 - DB AppConfig 真相源(PGroup=ProjectConfig, PName=OtcFormatConfig) - 写入/读取/启动三条数据流 - '前端不起效果'的 4 步排查顺序 - 多节点落盘只写当前节点的坑 OtcConfigController.AjaxSaveOtcFormat 补充多节点陷阱说明并指向 FrontController 文档。
291 lines
8.9 KiB
C#
291 lines
8.9 KiB
C#
using Newtonsoft.Json;
|
|
using Org.BouncyCastle.Asn1.Ocsp;
|
|
using YLErp.Commons;
|
|
using YLErp.Modules.AppModule;
|
|
using YLErp.Modules.EodModule.SettlementModule;
|
|
using YLErp.Web.App_Start.AppConfig;
|
|
using YLErp.Web.Areas.Admin.Models;
|
|
|
|
namespace YLErp.Web.Areas.Admin.Controllers
|
|
{
|
|
public class OtcConfigController : AdminBaseController
|
|
{
|
|
public ActionResult Index()
|
|
{
|
|
return AppConfig();
|
|
}
|
|
|
|
#region----AppConfig----
|
|
|
|
public ActionResult AppConfig()
|
|
{
|
|
var datas = DbContextFactory.GetYLDbContext().AppConfig.Where(n => n.PGroup == "ProjectConfig").ToArray();
|
|
foreach (var data in datas)
|
|
{
|
|
if (data.PType == "string")
|
|
{
|
|
data.PGroup = "01";
|
|
}
|
|
else if (data.PType == "text")
|
|
{
|
|
data.PGroup = "01";
|
|
}
|
|
else if (data.PType == "bool")
|
|
{
|
|
data.PGroup = "11";
|
|
}
|
|
else
|
|
{
|
|
data.PGroup = "02";
|
|
}
|
|
}
|
|
datas = datas.OrderBy(n => n.PGroup).ThenBy(n => n.PName).ToArray();
|
|
return View("AppConfig", datas);
|
|
}
|
|
|
|
public JsonResult AjaxSaveAppConfig(string name, string value)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
return JsonError("保存失败,请求参数不能为空");
|
|
}
|
|
if (!string.IsNullOrWhiteSpace(value))
|
|
{
|
|
value = Uri.UnescapeDataString(value);
|
|
}
|
|
using (var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
var data = db.AppConfig.FirstOrDefault(n => n.PGroup == "ProjectConfig" && n.PName == name);
|
|
if (data == null)
|
|
{
|
|
return JsonError("保存失败,没有找到配置数据");
|
|
}
|
|
data.PValue = value;
|
|
PS.SetConfig(name, value);
|
|
db.SaveChanges();
|
|
return JsonSuccess($"{DateTime.Now:yyyyMMdd HH:mm:ss}--保存成功--{data.PName}={data.PValue}");
|
|
}
|
|
}
|
|
|
|
public JsonResult AjaxResetAppConfig()
|
|
{
|
|
AppManager.ResetAppConfig();
|
|
return JsonSuccess("刷新配置成功");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region----OtcWebConfig---
|
|
|
|
public ActionResult WebConfig()
|
|
{
|
|
var list = AppHelper.GetConfigFieldAttributes();
|
|
return View(list);
|
|
}
|
|
|
|
public JsonResult AjaxSaveWebConfig(OtcAppConfig model)
|
|
{
|
|
if (model == null)
|
|
{
|
|
return JsonError("请求参数无效");
|
|
}
|
|
var json = JsonHelper.Serialize(model);
|
|
AppHelper.ResetConfig(json);
|
|
return JsonSuccess();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region----OtcFormat----
|
|
|
|
public ActionResult OtcFormat()
|
|
{
|
|
var viewModel = OtcFormatViewModel.CreateViewModel(OtcFormatHelper.FormatModel);
|
|
|
|
return View(viewModel);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存配置
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 保存链路:写 DB(AppConfig.OtcFormatConfig) → 落盘 App_Data/Config/otcformat.js → 刷新内存。
|
|
/// 注意:File.WriteAllText 只写当前节点磁盘。多节点部署下,未处理本次请求的节点文件不会更新,
|
|
/// 会造成"DB 正确但 /front/otcformat 返回旧值"。完整排查见 FrontController 类注释。
|
|
/// </remarks>
|
|
public JsonResult AjaxSaveOtcFormat(OtcFormatModel model)
|
|
{
|
|
if (model is null)
|
|
{
|
|
return JsonError("参数不能为空");
|
|
}
|
|
|
|
var json = JsonConvert.SerializeObject(model, Formatting.Indented);
|
|
|
|
var service = new AppConfigService(OptUserInfo.SystemUser);
|
|
|
|
service.SaveOtcFormatConfig(json);
|
|
|
|
var path = Server.MapPath("~/App_Data/Config/otcformat.js");
|
|
var jscode = "var main = main || {};\r\nmain.formatOptions= " + json + ";\r\n\r\n";
|
|
System.IO.File.WriteAllText(path, jscode);
|
|
|
|
OtcFormatHelper.Initialize(json);
|
|
|
|
return JsonSuccess();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region---SMTP Config----
|
|
|
|
public ActionResult SmtpConfig()
|
|
{
|
|
return View(AppManager.SmtpConfig);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存邮件发送配置
|
|
/// </summary>
|
|
public JsonResult AjaxSaveSmtpConfig(SmtpConfigExt smtpConfig)
|
|
{
|
|
AppManager.ResetSmtpConfig(smtpConfig);
|
|
return JsonSuccessMessage("保存成功");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 邮件发送测试
|
|
/// </summary>
|
|
public JsonResult AjaxSendMailTest(string mailTo)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(mailTo))
|
|
{
|
|
return JsonError("发送邮件地址不能为空");
|
|
}
|
|
LogFactory.GetLogger().Info($"邮件发送测试,mailTo={mailTo}");
|
|
var error = EmailHelper.SendMail(mailTo, "邮件发送测试", "邮件发送测试");
|
|
LogFactory.GetLogger().Info($"邮件发送测试完成,mailTo={mailTo},error={error}");
|
|
if (string.IsNullOrWhiteSpace(error))
|
|
{
|
|
return JsonSuccess();
|
|
}
|
|
return JsonError(error);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region----MailTemplate----
|
|
|
|
public ActionResult MailTemplate()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
public JsonResult AjaxGetMailTemplate(string emailType)
|
|
{
|
|
var data = new EmailTemplateService(CurUser).GetData(emailType);
|
|
return JsonSuccess(data ?? new EmailTemplate());
|
|
}
|
|
|
|
public JsonResult AjaxSaveMailTemplate(EmailTemplate data)
|
|
{
|
|
data.IsBodyHtml = true;
|
|
data.BodyTemplate = Uri.UnescapeDataString(data.BodyTemplate ?? string.Empty);
|
|
new EmailTemplateService(CurUser).SaveData(data);
|
|
return JsonSuccess("保存成功");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region----收盘配置----
|
|
|
|
public ActionResult SettlementConfig()
|
|
{
|
|
var config = PS.Config.GetSettlementConfig();
|
|
|
|
return View(config);
|
|
}
|
|
|
|
public JsonResult AjaxSaveSettlementConfig(Configuration.SettlementConfig config)
|
|
{
|
|
var json = config.ToJson();
|
|
new AppConfigService(CurUser).SaveConfig("ProjectConfig", "Erp.SettlementConfig", json, "string", "收盘配置");
|
|
PS.SetConfig("Erp.SettlementConfig", json);
|
|
return JsonSuccess();
|
|
}
|
|
/// <summary>
|
|
/// 客户资金分买卖权结算重算
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public JsonResult AjaxClientBalanceReCalcBS(BalanceRecalcBSRequest request)
|
|
{
|
|
Task.Run(() => new EodClientBalanceCalcBS(CurUser).ClientBalanceReCalc(request.TradeDateStart,request.TradeDateEnd));
|
|
return JsonSuccess();
|
|
}
|
|
public JsonResult AjaxClientBalanceReCalcProcess()
|
|
{
|
|
EodClientBalanceCalcBS.thQueue.TryPeek(out EodClientBalanceReCalcModel result);//取出最新进度
|
|
return JsonSuccess(result);
|
|
}
|
|
#endregion
|
|
|
|
#region----登出----
|
|
public ActionResult Logout()
|
|
{
|
|
return Redirect("/admin/Login");
|
|
}
|
|
#endregion
|
|
|
|
#region----交易要素配置----
|
|
|
|
public ActionResult TradePricingCfg()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region----ClientEditConfig----
|
|
|
|
public ActionResult ClientEditConfig()
|
|
{
|
|
ViewData["config"] = YLErp.Modules.SystemModule.ClientEditConfigService.GetCurrentConfigJson();
|
|
return View();
|
|
}
|
|
|
|
public ActionResult downClientEditConfig(string t)
|
|
{
|
|
string configJson;
|
|
|
|
if ("def".Equals(t, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
configJson = YLErp.Modules.SystemModule.ClientEditConfigService.GetDefaultConfigJson();
|
|
}
|
|
else
|
|
{
|
|
configJson = YLErp.Modules.SystemModule.ClientEditConfigService.GetCurrentConfigJson();
|
|
}
|
|
var buffer = System.Text.Encoding.UTF8.GetBytes(configJson);
|
|
return File(buffer, "application/javascript; charset=utf-8", "clientEditConfig.js");
|
|
}
|
|
|
|
public JsonResult AjaxSaveClientEditConfig(string config)
|
|
{
|
|
YLErp.Modules.SystemModule.ClientEditConfigService.SaveEditConfig(config);
|
|
|
|
return JsonSuccess();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region----结算报告配置----
|
|
|
|
public ActionResult TradeMarketReportCfg()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|