revert: 恢复误删的Admin后台区域——用户澄清/admin管理后台是在用的,上条消息"没有使用"指的是admin页面也没引用jquery-3.6.0而非页面废弃。恢复Areas/Admin整目录28文件+Scripts/admin两文件。jquery三件套/3个业务死JS/11个死视图/NCrontab的删除仍然有效(admin布局零jquery引用,复验不受影响)

This commit is contained in:
hjhan
2026-08-22 10:19:36 +08:00
parent d42742ab10
commit d7e6955132
30 changed files with 2634 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
namespace YLErp.Web.Areas.Admin
{
public static class AdminContext
{
public static string AdminAuthValue { get; private set; }
static AdminContext()
{
AdminAuthValue = Guid.NewGuid().ToString("N");
}
public static string NewAdminCookieValue()
{
return AdminAuthValue = Guid.NewGuid().ToString("N");
}
}
}
@@ -0,0 +1,152 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Text;
using YieldChain.Models;
namespace YLErp.Web.Areas.Admin.Controllers
{
[Authorize(policy: "yc_identity"), Area("Admin")]
public abstract class AdminBaseController : Controller
{
/// <summary>
/// JSON序列化时是否包括NULL值
/// </summary>
protected virtual bool JsonIncludeNullValue { get; set; }
#region ----HTTP响应----
/// <summary>
/// 返回JSON错误信息
/// </summary>
protected JsonResult JsonError(string errmsg)
{
return JsonResp(1, errmsg);
}
/// <summary>
/// 返回JSON错误信息
/// </summary>
protected JsonResult JsonError(string errmsg, bool locale)
{
if (locale)
{
return JsonResp(1, errmsg);
}
return Json(new ApiResponseModel(1, errmsg));
}
/// <summary>
/// 返回JSON错误信息
/// </summary>
protected JsonResult JsonError(int errcode, string errmsg)
{
return JsonResp(errcode, errmsg);
}
/// <summary>
/// 返回JSON成功信息
/// </summary>
protected JsonResult JsonSuccess(object resultData, string message = null)
{
return JsonResp(0, message, resultData);
}
/// <summary>
/// 返回JSON格式的成功消息
/// </summary>
protected JsonResult JsonSuccess()
{
return Json(new ApiResponseModel(0));
}
/// <summary>
/// 返回JSON格式的成功消息
/// </summary>
protected JsonResult JsonSuccessMessage(string message)
{
return JsonResp(0, message);
}
/// <summary>
/// 返回JSON格式的模型验证失败
/// </summary>
protected JsonResult JsonModelError(string separator = "\\n\\n")
{
var sb = new StringBuilder();
foreach (var item in ModelState.Values)
{
if (item.Errors.Count > 0)
{
for (var i = item.Errors.Count - 1; i >= 0; i--)
{
if (sb.Length > 0)
{
sb.Append(separator);
}
sb.Append(item.Errors[i].ErrorMessage);
}
}
}
return JsonResp(2, sb.ToString());
}
/// <summary>
/// 返回JSON格式的消息
/// </summary>
/// <param name="errcode">0-无错误,其他-有错误发生</param>
/// <param name="message">错误或成功消息</param>
/// <param name="resultData">结果数据</param>
protected JsonResult JsonResp(int errcode, string message, object resultData = null)
{
return Json(new ApiResponseModel(errcode, message, resultData));
}
#endregion
UserInfo _curUser;
protected UserInfo CurUser
{
get
{
if (User.Identity.IsAuthenticated)
{
if (_curUser != null)
{
return _curUser;
}
_curUser = Server.CacheProvider.Get("loginUser^" + HttpContext.User.GetUserId()) as UserInfo;
if (_curUser != null)
{
_curUser.UserFrom = OptUserFrom.WebUI;
return _curUser;
}
}
return new UserInfo { UserName = "系统", UserFrom = OptUserFrom.WebUI };
}
}
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!CurUser.HasRight("系统管理-系统配置管理"))
{
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
context.Result = JsonError("没有权限");
}
else
{
context.Result = new ContentResult { Content = "您无权访问此页面。", ContentType = "text/plain; charset=utf-8" };
}
}
base.OnActionExecuting(context);
}
}
}
@@ -0,0 +1,42 @@
using YLErp.Modules.AppModule.UpgradModule;
namespace YLErp.Web.Areas.Admin.Controllers
{
public class DbUpdateController : AdminBaseController
{
public ActionResult Index()
{
return View();
}
/// <summary>
/// 加载所有数据库脚本升级列表
/// </summary>
public JsonResult AjaxGetUpdateList()
{
var list = DbUpdateService.GetUpdateList();
return JsonSuccess(list);
}
/// <summary>
/// 查看数据库脚本升级内容
/// </summary>
public JsonResult AjaxGetUpdateContent(IEnumerable<string> upKeyList)
{
var content = DbUpdateService.GetUpdateContent(upKeyList);
return JsonSuccess(content);
}
/// <summary>
/// 执行所选数据库脚本升级文件内容
/// </summary>
public JsonResult AjaxExecuteUpdate(IEnumerable<string> upKeyList, bool isUpdateDone = false)
{
var responseDtos = DbUpdateService.ExecuteUpdate(upKeyList, isUpdateDone);
return JsonSuccess(responseDtos);
}
}
}
@@ -0,0 +1,32 @@
using YLErp.Providers;
namespace YLErp.Web.Areas.Admin.Controllers
{
public class HomeController : AdminBaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult Logout()
{
MemoryCacheProvider.Default.Remove("myadminadmin");
return Redirect("/admin/Login");
}
public JsonResult AjaxRestart()
{
try
{
System.Diagnostics.Process.GetCurrentProcess().Kill();
return Json("重启中...");
}
catch (Exception ex)
{
return Json("重启失败:" + ex.Message);
}
}
}
}
@@ -0,0 +1,290 @@
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
}
}
@@ -0,0 +1,42 @@
using YLErp.Modules.ReportModule;
namespace YLErp.Web.Areas.Admin.Controllers
{
public class OwnerInfoController : AdminBaseController
{
// GET: Admin/Owner_info
public ActionResult Index()
{
return View();
}
public JsonResult GetOwnerInfo()
{
var sList = DbContextFactory.GetYLDbContext().Owner_Info.ToList();
return Json(sList);
}
public JsonResult PostOwnerInfo(Owner_info o)
{
var i = new Owner_infoService(CurUser).AddOrUpdate(o);
return Json(i);
}
public ActionResult OwnerInfoEdit(int ID)
{
Owner_info v;
v = DbContextFactory.GetYLDbContext().Owner_Info.Find(ID);
if (v == null)
{
v = new Owner_info();
}
return View(v);
}
public JsonResult Deleteowner(int ID)
{
var i = new Owner_infoService(CurUser).Dele(ID);
return Json(i);
}
}
}
@@ -0,0 +1,70 @@
using YLErp.Modules.ExchangeTradeModule;
using YLErp.Modules.SuperviseReportModule.ChangJiangReport.Service;
using YLErp.Modules.SystemModule;
namespace YLErp.Web.Areas.Admin.Controllers
{
public class ToolsController : AdminBaseController
{
public ActionResult Index()
{
return View();
}
/// <summary>
/// 重新初始化实时风险计算
/// </summary>
public JsonResult AjaxResetTradeRiskCalcTaskRunner()
{
Modules.TradeRiskCalcModule.TradeRiskCalcTaskRunner.Reset();
return JsonSuccess();
}
/// <summary>
/// 重置对冲交易持仓
/// </summary>
public JsonResult AjaxResetTradePosition()
{
new ExchangeTradePositionService(CurUser).ResetExchangeTradePosition();
return JsonSuccess();
}
public JsonResult AjaxResetsysUser()
{
var functionRightXmlFilePath = Server.MapPath("/App_Data/FunctionRight.xml");
new SysFunctionService(CurUser).SyncFunctionRight(functionRightXmlFilePath);
BaseOUDAL.UserBLL.AddDefaultUser();
FunctionHelper.Initialize();
return JsonSuccess();
}
/// <summary>
/// 长江监管报告-场外业务持仓表
/// </summary>
public JsonResult AjaxChangeJiangSuperviseReportPosition(ChangeJiangSuperviseReportPositionRequest req)
{
if (req == null)
{
return JsonError("参数不可为空");
}
if (req.Date == DateTime.MinValue)
{
return JsonError("未传入有效的结算日期");
}
var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.Supervise_Position);
var changes = new SuperviseReportPositionService(OptUserInfo.SystemUser).SaveReportData(req.Date.Date, nv?["敞口算法"], req.ClearExistings);
return JsonSuccessMessage($"执行完成,共更新{changes}条");
}
}
public class ChangeJiangSuperviseReportPositionRequest
{
public DateTime Date { get; set; }
public bool ClearExistings { get; set; }
}
}
@@ -0,0 +1,9 @@
namespace YLErp.Web.Areas.Admin.Models
{
public class BalanceRecalcBSRequest
{
public DateTime? TradeDateStart { get; set; }
public DateTime? TradeDateEnd { get; set; }
}
}
@@ -0,0 +1,60 @@
using System.Reflection;
namespace YLErp.Web.Areas.Admin.Models
{
/// <summary>
///
/// </summary>
public class OtcFormatViewModel
{
public IEnumerable<SelectItemNest> SelectItems { get; set; }
public static OtcFormatViewModel CreateViewModel(OtcFormatModel otcFormat)
{
if (otcFormat is null)
{
throw new System.ArgumentNullException(nameof(otcFormat));
}
var selectItems = GetSelectItems(otcFormat);
return new OtcFormatViewModel { SelectItems = selectItems };
}
private static IEnumerable<SelectItemNest> GetSelectItems(object obj, int depth = 0)
{
var flags = BindingFlags.Instance | BindingFlags.Public;
var properties = obj.GetType().GetProperties(flags);
var resultList = new List<SelectItemNest>(properties.Length);
foreach (var p in properties)
{
if (p.CanRead && p.CanWrite)
{
var attr = p.GetCustomAttribute(typeof(OtcFormatConfigAttribute)) as OtcFormatConfigAttribute;
if (attr == null)
{
continue;
}
var item = new SelectItemNest
{
Value = p.Name,
Text = attr.Label,
Tag = p.GetValue(obj)
};
if (depth == 0)
{
item.SelectItems = GetSelectItems(item.Tag, depth + 1);
}
resultList.Add(item);
}
}
return resultList;
}
}
}
@@ -0,0 +1,9 @@
namespace YLErp.Web.Areas.Admin.Models
{
public class PluginViewModel
{
public IEnumerable<string> Directories { get; set; }
public IEnumerable<FileInfo> Files { get; set; }
}
}
@@ -0,0 +1,37 @@
using YLErp.Abstract;
namespace YLErp.Web.Areas.Admin.Models
{
public class ZTreeMenuItem : ITreeMenuItem
{
public string id { get; set; }
public string name { get; set; }
public bool open { get; set; }
public List<ZTreeMenuItem> children { get; set; }
public ITreeMenuItem AppendChild(string id, string name, string[] rights,
string url, string icon, string target)
{
var menu = new ZTreeMenuItem
{
id = id,
name = name,
open = false
};
if (children == null)
{
children = new List<ZTreeMenuItem>();
}
children.Add(menu);
return menu;
}
public override string ToString()
{
return name;
}
}
}
@@ -0,0 +1,94 @@
@{
ViewData["Title"] = "数据库升级";
}
<div class="card" id="dbUpdateDiv">
<div class="card-header">
<h4 class="card-title">数据库升级</h4>
<button class="btn btn-primary ml-2" v-on:click="executeUpdate()">批量执行</button>
<button class="btn btn-primary ml-2" v-on:click="executeUpdate('isUpdateDone')">批量更新为已执行</button>
<button class="btn btn-primary ml-2" v-on:click="viewUpdateContent()">查看升级内容</button>
<button class="btn btn-primary ml-2" v-on:click="getUpdateList">刷新升级列表</button>
</div>
<div class="card-body">
<div class="border">
<div class="p-3 form-inline mb-3 border-bottom">
<label class="mr-1">版本:</label>
<select class="form-control" style="width:100px;" v-model="filter.version">
<option value="">---</option>
<option v-for="item in filter.versionItems">{{item}}</option>
</select>
<label class="ml-3 mr-1">数据库:</label>
<select class="form-control" style="width:100px;" v-model="filter.dbschema">
<option value="">---</option>
<option value="prod">prod</option>
<option value="client">client</option>
<option value="admin">admin</option>
</select>
<label class="ml-3"><input type="checkbox" v-model="filter.upstate" class="mr-1" />只显示未执行</label>
</div>
<table class="table table-hover">
<colgroup>
<col span="1" width="30" />
<col span="1" width="90" />
<col span="1" width="90" />
<col span="1" width="90" />
<col span="1" width="120" />
</colgroup>
<thead>
<tr>
<th><label><input type="checkbox" v-model="checkAll" v-on:change="changeAllChecked" /></label></th>
<th>版本</th>
<th>数据库</th>
<th>内容</th>
<th>操作</th>
<th>执行结果</th>
</tr>
</thead>
<tbody>
<tr v-for="item in updateList" v-bind:style="isShowItem(item)">
<td><input type="checkbox" v-model="item.checked" v-on:change="changeItemChecked(item)" /></td>
<td>{{item.Version}}</td>
<td>{{item.DbSchema}}</td>
<td><a href="javascript:void(0)" v-on:click="viewUpdateContent(item.UpKey)">查看</a></td>
<td><a href="javascript:void(0)" v-on:click="executeUpdate(item)">{{item.UpState<1?"执行更新":"重新执行"}}</a></td>
<td :class="itemStatusClass(item)">{{item.UpResult}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal" id="dbContentModal" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
数据库升级脚本内容
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<textarea class="codesql public_text" id="dbContentText"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
@section heads{
<link href="~/Statics/libs/codemirror/lib/codemirror.css" rel="stylesheet" />
}
@section scripts{
<script src="~/Statics/libs/codemirror/lib/codemirror.js"></script>
<script src="~/Statics/libs/codemirror/addon/matchbrackets.js"></script>
<script src="~/Statics/libs/codemirror/addon/comment/continuecomment.js"></script>
<script src="~/Statics/libs/codemirror/addon/comment/comment.js"></script>
<script src="~/Statics/libs/codemirror/mode/sql.js"></script>
<script src="~/Scripts/admin/dbupdate.js"></script>
}
@@ -0,0 +1,35 @@
@{
ViewData["Title"] = "首页";
}
@section heads{
<style>
hr {margin:10px 0; }
.col-m1 { width:300px; }
</style>
}
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-auto col-m1">当前版本</div>
<div class="col">@(AppManager.Version)</div>
</div>
<hr />
<div class="row">
<div class="col-auto col-m1">启动时间</div>
<div class="col">@(AppManager.StartTime)</div>
</div>
<hr />
@foreach (var item in AppManager.GetSysInfo())
{
<div class="row">
<div class="col-auto col-m1">@(item.Key)</div>
<div class="col">@(item.Message)</div>
<div class="col-auto col-m1">@(item.TimeStamp)</div>
</div>
<hr />
}
</div>
</div>
@@ -0,0 +1,156 @@
@model IEnumerable<AppConfig>
@{
var id = 0;
ViewData["Title"] = "全局配置(AppConfig)";
}
@section heads{
<style>
input[type=checkbox] {
width: 17px;
height: 17px;
vertical-align: middle;
margin-top: -3px;
margin-right: 3px;
}
</style>
}
<div style="position:fixed;left:0;right:0;bottom:0px;z-index:10;max-height:65px;">
<div class="container">
<div class="alert alert-danger row" style="margin-bottom:0">
<div class="col">
<p class="m-0 p-3 text-break" id="respMsg">修改后自动保存</p>
</div>
<div class="col-auto text-right" style="width:100px;">
<button class="btn btn-primary" onclick="ResetConfig()">刷新配置</button>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="card-title">全局配置(AppConfig)</h4>
</div>
<div class="card-body" style="padding-bottom: 70px;">
@foreach (var item in Model)
{
id++;
var label = item.PName + "-" + item.Remark;
<div class="mb-5">
@if (item.PType == "bool")
{
var val = item.PValue?.ToLowerInvariant();
<label>
<input id="config@(id)" type="checkbox" name="@(item.PName)" onchange="SaveValue('@id')" @("true" == val ? "checked" : "") />
@(label)
</label>
}
else if (item.PType == "string" || item.PType == "int" || item.PType == "double")
{
<div class="font-weight-bold mb-2">@(label)</div>
<input id="config@(id)" type="text" name="@(item.PName)" value="@(item.PValue)" data-value="@(item.PValue)" onblur="SaveValue('@id')" onkeydown="OnInputKeyDown('@id')" class="form-control" style="width:700px" />
}
else if (item.PType == "text")
{
<div style="font-weight:700">@(label)</div>
<textarea id="config@(id)" rows="3" name="@(item.PName)" data-value="@(item.PValue)" onblur="SaveValue('@id')" onkeydown="OnInputKeyDown('@id')" class="form-control" style="width:700px">@(item.PValue)</textarea>
}
else if (item.PType == "html")
{
<div style="font-weight:700">@(label)</div>
<textarea id="config@(id)" rows="3" name="@(item.PName)" data-value="@(item.PValue)" onblur="SaveValue('@id',true)" onkeydown="OnInputKeyDown('@id',true)" class="form-control" style="width:700px">@(item.PValue)</textarea>
<div class="mt-2">
<button class="btn btn-primary" onclick="showUeditorConfig('@id','@(label)')">使用编辑器配置</button>
</div>
}
else
{
IEnumerable<string> names = null;
if (item.PType == "CompanyEnum")
{
names = Enum.GetNames(typeof(YLErp.Configuration.CompanyEnum));
}
else if (item.PType == "ComponentVersion")
{
names = Enum.GetNames(typeof(YLErp.Configuration.ComponentVersion));
}
else if (item.PType == "VolModeEnum")
{
names = Enum.GetNames(typeof(YLErp.Configuration.VolModeEnum));
}
else if (item.PType == "VolSurfaceKeyDateShiftEnum")
{
names = Enum.GetNames(typeof(YLErp.Configuration.VolSurfaceKeyDateShiftEnum));
}
else if (item.PType == "SmoothingDaycountMode")
{
names = Enum.GetNames(typeof(YLErp.Configuration.Enums.SmoothingDaycountMode));
}
else if (item.PType == "ForwardTradePriceModel")
{
names = Enum.GetNames(typeof(YLErp.Configuration.Enums.ForwardTradePriceModel));
}
else if (item.PType == "SaleMode")
{
names = Enum.GetNames(typeof(YLErp.Configuration.Enums.SaleMode));
}
else if (item.PType == "OptionTypeAndBuySell")
{
names = Enum.GetNames(typeof(YLErp.Configuration.Enums.OptionTypeAndBuySell));
}
else if (item.PType == "ForwardValueIsSupplyOrPay")
{
names = Enum.GetNames(typeof(YLErp.Configuration.Enums.ForwardValueIsSupplyOrPay));
}
else if (item.PType == "ExchangeOptionVolType")
{
names = Enum.GetNames(typeof(YLErp.Configuration.Enums.ExchangeOptionVolType));
}
<div style="font-weight:700">@(label)</div>
if (names != null)
{
<select id="config@(id)" class="form-control" name="@(item.PName)" style="width:500px;" onchange="SaveValue('@id')">
@foreach (var name in names)
{
<option value="@(name)" @(name == item.PValue ? "selected" : "")>@(name)</option>
}
</select>
}
}
</div>
}
</div>
</div>
<div class="modal" tabindex="-1" role="dialog" id="ueditorModal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">配置</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="editor"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-min" onclick="saveUeditorConfig()">保存</button>
<button type="button" class="btn btn-secondary btn-min" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
@section scripts{
<script src="~/Scripts/ueditor/ueditor.config.js?v=@(HtmlUtil.JsVersion)"></script>
<script src="~/Scripts/ueditor/ueditor.all.min.js?v=@(HtmlUtil.JsVersion)"></script>
<script>
var saveConfigValueUrl = '@Url.Action("AjaxSaveAppConfig")';
var resetConfigValueUrl = '@Url.Action("AjaxResetAppConfig")';
</script>
<script src="~/Scripts/admin/appconfig.js?v=@(HtmlUtil.JsVersion)"></script>
}
@@ -0,0 +1,64 @@
@{
ViewData["Title"] = "客户编辑页面配置";
}
<div class="card">
<div class="card-header">
<h4 class="card-title">客户编辑页面配置</h4>
<div class="ml-auto">
<a href="/admin/otcConfig/downClientEditConfig?t=cur" target="_blank">下载当前配置文件</a>
<a href="/admin/otcConfig/downClientEditConfig?t=def" target="_blank" class="ml-3">下载默认配置文件</a>
</div>
</div>
<div class="card-body">
<div class="border" id="codeDiv">
<textarea id="code" name="code">@ViewData["config"]</textarea>
</div>
<p class="mt-2">使用'meta_'前缀定义扩展属性,属性中不允许出现下划线</p>
<p class="mt-2">
列表配置:
<br />
hidden代表是否要默认在列表中隐藏;如:hidden:true
<br />
optionHide代表是否要在列配置中隐藏;如:optionHide:true
</p>
<div class="mt-4 text-center">
<button class="btn btn-primary pl-5 pr-5" onclick="saveConfig()">保存</button>
</div>
</div>
</div>
@section heads{
<link href="~/Statics/libs/codemirror/lib/codemirror.css" rel="stylesheet" />
<style>
body *::-webkit-scrollbar { width: 10px; height: 10px; transition: .3s background; }
.CodeMirror { height: 100%; min-height: 300px; }
</style>
}
@section scripts{
<script src="~/Statics/libs/codemirror/lib/codemirror.js"></script>
<script src="~/Statics/libs/codemirror/addon/matchbrackets.js"></script>
<script src="~/Statics/libs/codemirror/addon/comment/continuecomment.js"></script>
<script src="~/Statics/libs/codemirror/addon/comment/comment.js"></script>
<script src="~/Statics/libs/codemirror/mode/javascript.js"></script>
<script>
var codeEditor;
$(function () {
$('#codeDiv').height($(window).height() - 300);
codeEditor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
continueComments: "Enter",
extraKeys: { "Ctrl-Q": "toggleComment" }
});
});
function saveConfig() {
main.post("/admin/otcConfig/AjaxSaveClientEditConfig", { config: codeEditor.getValue() }).done(function () {
main.alert("保存成功");
}).fail(function () {
main.alert("提交失败");
});
}
</script>
}
@@ -0,0 +1,87 @@
@{
ViewData["Title"] = "邮件模板配置";
}
<div class="card">
<div class="card-header">
<h4 class="card-title">邮件模板配置</h4>
</div>
<div class="card-body">
<div class="mb-4">
<select name="EmailType" id="EmailType" onchange="changeType()" class="form-control" style="width:150px;">
<option value="交易确认书">交易确认书</option>
<option value="结算确认书">结算确认书</option>
<option value="交易确认书(用印)">交易确认书(用印)</option>
<option value="结算确认书(用印)">结算确认书(用印)</option>
@* EQD-5320 资金通知书:value 与 bond-oms Java FundEmailHandler 查询的 EmailType 一字不差,勿改名;
此场景 {{文档编号}}/{{交易列表}} 渲染为空,可用 {{客户名称}}/{{交易日期}} *@
<option value="追保资金通知书">追保资金通知书</option>
<option value="轧差资金通知书">轧差资金通知书</option>
</select>
</div>
<div class="mb-4">
<label>邮件标题模板(变量参数:{{客户名称}},{{交易日期}},{{文档编号}})</label>
<input type="text" name="TitleTemplate" id="TitleTemplate" class="form-control" />
</div>
<div class="mb-4">
<label>邮件内容模板(变量参数:{{客户名称}},{{交易日期}},{{文档编号}})</label>
<div id="editor"></div>
</div>
<div class="mb-4">
<button class="btn btn-primary" style="width:120px;" onclick="saveData()">保存</button>
</div>
</div>
</div>
@section scripts{
<script src="~/Scripts/ueditor/ueditor.config.js?v=@(HtmlUtil.JsVersion)"></script>
<script src="~/Scripts/ueditor/ueditor.all.min.js?v=@(HtmlUtil.JsVersion)"></script>
<script>
var page = {
AjaxSaveDataUrl:'@(Url.Action("AjaxSaveMailTemplate"))',
AjaxGetDetailUrl: '@(Url.Action("AjaxGetMailTemplate"))'
};
var ueditor;
$(function () {
ueditor = UE.getEditor('editor', {
autoHeight: false,
wordCount: false,
autoHeightEnabled: false,
initialFrameHeight: 500
});
ueditor.ready(changeType);
});
function changeType() {
ueditor.reset();
ueditor.setContent('');
var emailType = $('#EmailType').val();
main.post(page.AjaxGetDetailUrl, { emailType: emailType })
.done(function (resp) {
$('#TitleTemplate').val(resp.data.TitleTemplate);
let html = main.decodeHtmlEntity(resp.data.BodyTemplate);
ueditor.execCommand('insertHtml', html || "");
});
}
function saveData() {
var data = {
EmailType: $('#EmailType').val(),
TitleTemplate: $.trim($('#TitleTemplate').val())
};
data.BodyTemplate = encodeURIComponent(ueditor.getContent());
if (!data.TitleTemplate) {
return main.alert('缺少邮件标题模板');
}
var $e = $(event.target).prop('disabled', true);
main.post(page.AjaxSaveDataUrl, data).done(function (resp) {
layer.msg('保存成功');
}).always(function () {
$e.prop('disabled', false);
});
}
</script>
}
@@ -0,0 +1,88 @@
@using YLErp.Commons
@using YLErp.Web.Areas.Admin.Models
@model OtcFormatViewModel
@{
ViewData["Title"] = "OtcFormat配置";
var pageObj = new
{
AjaxSaveUrl = Url.Action("AjaxSaveOtcFormat")
};
}
@section heads{
<style>
.btn-primary { min-width: 100px; }
.opt-title-dev { width: 120px; line-height: 32px; }
.opt-input-dev { width: 150px; margin-right: 20px; }
.opt-input-dev input { text-align: center; }
.opt-check-dev { line-height: 35px; }
.opt-check-dev > label { margin-right: 35px; }
.opt-check-dev input { margin-right: 5px; }
</style>
}
<div class="card">
<div class="card-header">
<h4 class="card-title">OtcFormat配置</h4>
</div>
<div class="card-body" id="configCont">
@foreach (var item in Model.SelectItems)
{
<div class="card">
<div class="card-header">
<h4 class="card-title">@(item.Text)</h4>
</div>
<div class="card-body otcformat" data-pname="@(item.Value)">
@foreach (var item2 in item.SelectItems)
{
var opt = (OtcFormatOption)item2.Tag;
<form class="row mb-4 opt-item-div" data-pname="@(item2.Value)">
<div class="col-auto opt-title-dev">
@(item2.Text):
</div>
<div class="col-auto opt-input-dev">
<input type="number" class="form-control" min="0" step="1" max="6" name="precision" value="@(opt.precision)" />
</div>
<div class="col opt-check-dev">
<label><input type="checkbox" name="rounded" value="true" @(opt.rounded ? "checked" : "") />四舍五入</label>
<label><input type="checkbox" name="grouping" value="true" @(opt.grouping ? "checked" : "") />千分位分组</label>
<input type="hidden" name="rounded" value="false" />
<input type="hidden" name="grouping" value="false" />
</div>
</form>
}
</div>
</div>
}
<div class="offset-3 mt-5">
<button type="button" class="btn btn-primary" onclick="saveConfig()">保存</button>
</div>
</div>
</div>
@section scripts{
<script>
const page = @Json.Serialize(pageObj);
function saveConfig() {
let postData = {};
$('.otcformat').each(function () {
let item = {};
$(this).find('form').each(function () {
item[$(this).data("pname")] = $(this).serializeObject();
});
postData[$(this).data("pname")] = item;
});
main.post(page.AjaxSaveUrl, postData).done(function (resp) {
main.alert("保存成功");
});
}
</script>
}
@@ -0,0 +1,170 @@
@model YLErp.Configuration.SettlementConfig
@{
ViewData["Title"] = "收盘配置";
var pageObj = new
{
AjaxSaveUrl = Url.Action("AjaxSaveSettlementConfig"),
AjaxReCalcBuySell = Url.Action("AjaxClientBalanceReCalcBS"),
AjaxReCalcBuySellProcess=Url.Action("AjaxClientBalanceReCalcProcess"),
};
var allVolTypes = YLErp.Web.Models.SettlementViewModel.GetVolTypes();
var checkedVolTypes = Model.VolTypes.Split(',').Where(n => !string.IsNullOrWhiteSpace(n)).ToArray();
}
@section heads{
<style>
.form-label { width: 120px !important; }
.btn-primary { min-width: 100px; }
.search-label{
margin-right:5px
}
.search-input{
width:120px;
height:30px;
}
</style>
}
<div class="card">
<div class="card-header">
<h4 class="card-title">收盘配置</h4>
</div>
<div class="card-body" id="configCont">
<form class="form-layout" onsubmit="return false;" id="form1">
<div class="form-row">
<label class="form-label col-auto">功能版本:</label>
<div class="col">
<select name="Version" class="form-control" id="selVersion" onchange="changeVersion()" style="width:160px;">
<option value="V2" selected>V2</option>
</select>
</div>
</div>
<div class="form-row">
<label class="form-label col-auto"></label>
<div class="col">
<label class="mr-2">
<input type="checkbox" name="CalcPnlExplain" class="mr-1" value="true" @(Model.CalcPnlExplain ? "checked" : "") />
是否计算盈亏分解指标
</label>
</div>
</div>
<div class="form-row">
<label class="form-label col-auto"></label>
<div class="col">
<label class="mr-2">
<input type="checkbox" name="CalcPnlExplain" class="mr-1" value="true" @(Model.CheckExchangeClose ? "checked" : "") />
是否检查场内交易平仓(平仓超过开仓时报错)
</label>
</div>
</div>
<div class="form-row v2-show">
<label class="form-label col-auto">默认价格模式:</label>
<div class="col">
<label class="mr-2"><input type="checkbox" name="PriceType" class="mr-1" value="1" @((Model.PriceType & 1) > 0 ? "checked" : "") />收盘价</label>
<label class="mr-2"><input type="checkbox" name="PriceType" class="mr-1" value="2" @((Model.PriceType & 2) > 0 ? "checked" : "") />结算价</label>
</div>
</div>
<div class="form-row v2-show">
<label class="form-label col-auto">默认波动率类型:</label>
<div class="col">
@foreach (var item in allVolTypes)
{
var _checked = checkedVolTypes.Contains(item.Value) ? "checked" : "";
<label class="mr-2"><input type="checkbox" name="VolTypes" class="mr-1" value="@(item.Value)" @(_checked) />@(item.Text)</label>
}
</div>
</div>
<div class="form-row v2-show">
<label class="form-label col-auto">部分结算:</label>
<div class="col">
<label class="mr-2"><input type="checkbox" name="SupportPart" class="mr-1" value="true" @(Model.SupportPart ? "checked" : "") />支持</label>
</div>
</div>
<div class="form-row v2-show">
<label class="form-label col-auto">分客户结算:</label>
<div class="col">
<label class="mr-2"><input type="checkbox" name="SubCustomerPart" class="mr-1" value="true" @(Model.SubCustomerPart ? "checked" : "") />支持</label>
</div>
</div>
<div class="form-row v2-show">
<label class="form-label col-auto">调试配置:</label>
<div class="col">
<label class="mr-2"><input type="checkbox" name="SkipLastPvCheck" class="mr-1" value="true" @(Model.SkipLastPvCheck ? "checked" : "") />跳过上一交易日结算检查</label>
<label class="mr-2"><input type="checkbox" name="OutputDebugLog" class="mr-1" value="true" @(Model.OutputDebugLog ? "checked" : "") />输出调试日志</label>
<label class="mr-2">
<input type="checkbox" name="CalcForwradMargin" class="mr-1" value="true" @(Model.CalcForwradMargin ? "checked" : "") />计算远期预付金
</label>
</div>
</div>
<div class="form-row v2-show">
<label class="form-label col-auto">买卖权资金结算: </label>
<div class="col">
<label class="mr-2">
<input type="checkbox" name="CalcBuySell" class="mr-1" value="true" @(Model.CalcBuySell ? "checked" : "") />支持
</label>
<label class="mr-2">
<span class="search-label" >日期</span>
<input class="search-input" id="DateFromTradeDate" type="text">-
<input class="search-input" id="DateToTradeDate" type="text">
</label>
<label class="mr-2"> <button type="button" class="btn btn-primary" onclick="reCalcBuySell()">重新计算</button></label>
<label class="mr-2" id="reCalcResult"></label>
</div>
</div>
<input type="hidden" name="CalcForwradMargin" value="false" />
</form>
<div>
<div class="form-label d-inline-block"></div>
<button type="button" class="btn btn-primary" onclick="saveConfig()">保存</button>
</div>
</div>
</div>
@section scripts{
<script>
const page = @Json.Serialize(pageObj);
var sh;
function saveConfig() {
let $e = $(event.target).prop('disabled', true);
let data = $('#form1').serializeObject();
Array.isArray(data.PriceType)&&(data.PriceType = data.PriceType.reduce((s, x) => s | parseInt(x), 0));
Array.isArray(data.VolTypes)&&(data.VolTypes = data.VolTypes.join(","));
main.post(page.AjaxSaveUrl, data).done(function (resp) {
layer.msg('保存成功');
}).always(function () {
$e.prop('disabled', false);
});
}
function changeVersion() {
}
function reCalcBuySell(){
let $e = $(event.target).prop('disabled', true);
main.post(page.AjaxReCalcBuySell, { TradeDateStart: $("#DateFromTradeDate").val(), TradeDateEnd: $("#DateToTradeDate").val() }).done(function (resp) {
$("#reCalcResult").text("正在计算中");
layer.msg('开始计算');
sh=setInterval(getReCalcBuySellProcess,10000);
}).always(function () {
$e.prop('disabled', false);
});
}
function getReCalcBuySellProcess(){
main.post(page.AjaxReCalcBuySellProcess).done(function (resp) {
if (resp!=null&&resp.data) {
if (resp.data.Msg == "全部计算结束" || resp.data.Msg.indexOf("异常")!=-1) {
clearInterval(sh);
}
var msg = resp.data.SettleDate + " " + resp.data.Msg;
$("#reCalcResult").text(msg);
}else{
clearInterval(sh);
}
})
}
</script>
}
@@ -0,0 +1,162 @@
@model YLErp.MailKit.SmtpConfig
@{
ViewData["Title"] = "邮件发送配置";
var pageObj = new
{
Model = Model,
AjaxSaveSmtpConfig = Url.Action("AjaxSaveSmtpConfig"),
AjaxSendMailTest = Url.Action("AjaxSendMailTest")
};
}
@section heads{
<style>
.btn-primary {
min-width: 100px;
}
</style>
}
<div class="card">
<div class="card-header">
<h4 class="card-title">邮件发送配置</h4>
</div>
<div class="card-body" id="configCont" v-cloak>
<form class="form-layout" onsubmit="return false;" id="form1">
<div class="row">
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">主机:</label>
<div class="col">
<input type="text" class="form-control" name="Server" v-model="Server" maxlength="50">
</div>
</div>
<div class="form-row">
<label class="form-label col-auto">端口:</label>
<div class="col">
<input type="number" class="form-control" name="Port" v-model="Port" step="1" min="0" max="66666">
</div>
</div>
<div class="form-row">
<label class="form-label col-auto">选项:</label>
<div class="col">
<!--使用SSL-->
<label class="mr-2"><input type="checkbox" class="mr-1" name="EnableSsl" v-model="EnableSsl">使用SSL</label>
<!--压缩附件-->
<label class="mr-2"><input type="checkbox" class="mr-1" name="ZipAttach" v-model="ZipAttach">压缩附件</label>
</div>
</div>
</div>
</div>
<div class="form-row">
<label class="form-label col-auto">用户</label>
<div class="col">
<input type="text" class="form-control" name="UserName" v-model="UserName" maxlength="100">
</div>
<label class="form-label col-auto w-auto">密码</label>
<div class="col">
<input type="password" class="form-control" name="Password" v-model="Password" maxlength="30">
</div>
<div class="col-auto">
<!--需要回执-->
<label><input type="checkbox" class="mr-1" name="Receipt" v-model="Receipt">需要回执</label>
</div>
<label class="form-label col-auto">显示名称</label>
<div class="col">
<input type="text" class="form-control" name="From" v-model="From" maxlength="100" placeholder="可不填,默认为用户">
</div>
</div>
<div class="form-row" v-for="item in OtherUsers">
<label class="form-label col-auto"><a href="javascript:;" v-on:click="removeUser(item)"><i class="fa fa-remove"></i></a> 用户</label>
<div class="col">
<input type="text" class="form-control" name="UserName" v-model="item.UserName" maxlength="100">
</div>
<label class="form-label col-auto w-auto">密码</label>
<div class="col">
<input type="password" class="form-control" name="Password" v-model="item.Password" maxlength="30">
</div>
<div class="col-auto">
<!--需要回执-->
<input type="hidden" name="Receipt" value="false">
<label><input type="checkbox" class="mr-1" name="Receipt" v-model="item.Receipt">需要回执</label>
</div>
<label class="form-label col-auto">显示名称</label>
<div class="col">
<input type="text" class="form-control" name="From" v-model="item.From" maxlength="100" placeholder="可不填,默认为用户">
</div>
</div>
</form>
<div class="offset-3 mt-5">
<button type="button" class="btn btn-primary" v-on:click="saveConfig">保存</button>
<button type="button" class="btn btn-primary" v-on:click="newUser">新增用户</button>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="card-title">邮件发送测试</h4>
</div>
<div class="card-body">
<div class="form-inline">
<div class="form-group">
<span>发送测试邮件到&nbsp;&nbsp;</span>
<input type="text" class="form-control" name="mailTo" id="txtmailTo" style="width:300px;" />
<button class="btn btn-primary ml-2" id="btnSendMailTest" onclick="sendMailTest()">发送</button>
</div>
</div>
</div>
</div>
@section scripts{
<script>
const page = @Json.Serialize(pageObj);
!page.Model.OtherUsers && (page.Model.OtherUsers = []);
const vue = new Vue({
el: '#configCont',
data: page.Model,
methods: {
newUser() {
this.OtherUsers.push({ UserName: '', Password: '', Receipt: true });
},
removeUser(item) {
var index = this.OtherUsers.indexOf(item);
this.OtherUsers.splice(index,1);
},
saveConfig() {
var users = this.OtherUsers.map(x => (x.UserName || '').trim().toLowerCase());
users.push((this.UserName || '').trim().toLowerCase());
if (users.some(x => !x)) {
return main.alert('用户不能为空');
}
if (users.length !== _.uniq(users).length) {
return main.alert('用户不能重复');
}
var $e = $(event.target).prop('disabled', true);
main.post(page.AjaxSaveSmtpConfig, this.$data).done(function (resp) {
layer.msg('保存成功');
}).always(function () {
$e.prop('disabled', false);
});
}
}
});
function sendMailTest() {
var $e = $(event.target).prop('disabled', true);
main.post(page.AjaxSendMailTest, { mailTo: $('#txtmailTo').val() }).done(function (resp) {
layer.msg('发送成功');
}).always(function () {
$e.prop('disabled', false);
});
}
</script>
}
@@ -0,0 +1,68 @@
@{
ViewData["Title"] = "结算报告配置";
var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.TradeMarketReportCfg);
var pageObj = new
{
Model = new
{
TradeMarketReportStartDate = nv?["开始日期"].TrimToNull() ?? "NONE",
},
AjaxSaveConfigUrl = Url.Action("AjaxSaveAppConfig")
};
}
@section heads{
<style>
.btn-primary {
min-width: 100px;
}
.form-layout .form-row .form-label {
width: 220px;
}
</style>
}
<div class="card">
<div class="card-header">
<h4 class="card-title">结算报告配置</h4>
</div>
<div class="card-body" id="configCont" v-cloak>
<form class="form-layout" onsubmit="return false;" id="form1">
<div class="form-row">
<label class="form-label col-auto">开始日期:</label>
<div class="col">
<select name="TradeMarketReportStartDate" v-model="TradeMarketReportStartDate" class="form-control d-inline-block" style="width:200px;">
<option value="NONE">空值</option>
<option value="SYSTEMDATE">系统日期</option>
</select>
</div>
</div>
</form>
<div class="offset-3 mt-5">
<button type="button" class="btn btn-primary" v-on:click="saveConfig">保存</button>
</div>
</div>
</div>
@section scripts{
<script>
const page = @Json.Serialize(pageObj);
const vue = new Vue({
el: '#configCont',
data: page.Model,
methods: {
saveConfig() {
var $e = $(event.target).prop('disabled', true);
let data = { name: 'Erp.TradeMarketReportCfg', value: '&开始日期=' + this.TradeMarketReportStartDate };
main.post(page.AjaxSaveConfigUrl, data).done(function (resp) {
layer.msg('保存成功');
}).always(function () {
$e.prop('disabled', false);
});
}
}
});
</script>
}
@@ -0,0 +1,94 @@
@{
ViewData["Title"] = "交易要素配置";
var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(PS.Config.ErpElement.TradePricingCfg);
var pageObj = new
{
Model = new
{
TradeCloseVolatility = nv?["目标波动率"].TrimToNull() ?? "BidAsk",
NumOfSmoothingDays = nv?["平滑过渡天数"].TrimToNull() ?? "NONE",
ForwardPriceType = nv?["远期期初价类型"].TrimToNull() ??"期权行权价格"
},
AjaxSaveConfigUrl = Url.Action("AjaxSaveAppConfig")
};
}
@section heads{
<style>
.btn-primary {
min-width: 100px;
}
.form-layout .form-row .form-label {
width: 220px;
}
</style>
}
<div class="card">
<div class="card-header">
<h4 class="card-title">交易要素配置(默认值)</h4>
</div>
<div class="card-body" id="configCont" v-cloak>
<form class="form-layout" onsubmit="return false;" id="form1">
<div class="form-row">
<label class="form-label col-auto">目标波动率:</label>
<div class="col">
<select name="TradeCloseVolatility" v-model="TradeCloseVolatility" class="form-control d-inline-block" style="width:200px;">
<option value="BidAsk">BidAsk</option>
<option value="Mid">Mid</option>
</select>
</div>
</div>
<div class="form-row">
<label class="form-label col-auto">平滑过渡天数:</label>
<div class="col">
<select name="NumOfSmoothingDays" v-model="NumOfSmoothingDays" class="form-control d-inline-block" style="width:200px;">
<option value="TTM">TTM</option>
<option value="ONE">1</option>
<option value="NONE">空值</option>
</select>
</div>
</div>
<div class="card-header">
<h5 class="card-title" style="font-size:1rem;">累计期权交易要素配置</h5>
</div>
<div class="form-row" style="margin-top:10px;">
<label class="form-label col-auto" >远期期初价类型:</label>
<div class="col">
<select name="ForwardPriceType" v-model="ForwardPriceType" class="form-control d-inline-block" style="width:200px;">
<option value="期权行权价格">期权行权价格</option>
<option value="期权期初价格">期权期初价格</option>
<option value="远期开仓现价">远期开仓现价</option>
<option value="期权成交日收盘价">期权成交日收盘价</option>
</select>
</div>
</div>
</form>
<div class="offset-3 mt-5">
<button type="button" class="btn btn-primary" v-on:click="saveConfig">保存</button>
</div>
</div>
</div>
@section scripts{
<script>
const page = @Json.Serialize(pageObj);
const vue = new Vue({
el: '#configCont',
data: page.Model,
methods: {
saveConfig() {
var $e = $(event.target).prop('disabled', true);
let data = { name: 'Erp.TradePricingCfg', value: '&目标波动率=' + this.TradeCloseVolatility + "&平滑过渡天数=" + this.NumOfSmoothingDays+ "&远期期初价类型=" + this.ForwardPriceType };
main.post(page.AjaxSaveConfigUrl, data).done(function (resp) {
layer.msg('保存成功');
}).always(function () {
$e.prop('disabled', false);
});
}
}
});
</script>
}
@@ -0,0 +1,125 @@
@model IEnumerable<YLErp.Web.App_Start.AppConfig.ConfigFieldAttributeDto>
@{
ViewData["Title"] = "当前系统配置";
}
@section heads{
<style>
body { padding-bottom: 50px; }
input[type=checkbox] { width: 18px; height: 18px; vertical-align: middle; margin-top: -3px; margin-right: 2px; }
hr { margin-top: 1rem; margin-bottom: 1rem; }
.popover {
max-width: 450px;
}
</style>
}
<div class="card">
<div class="card-header">
<h4 class="card-title">当前系统配置</h4>
</div>
<div class="card-body">
<form id="form1" onsubmit="return false;">
@foreach (var attr in Model)
{
var label = attr.Description;
<div>
@if (attr.FieldType == typeof(Boolean))
{
<label>
<input type="checkbox" name="@(attr.FieldName)" @("True" == attr.FieldValue ? "checked" : "") value="true" />
@(label)
</label>
}
else if (attr.FieldType == typeof(String))
{
<div style="font-weight:700">@(label)</div>
if (!string.IsNullOrWhiteSpace(attr.DataMapString))
{
<textarea name="@(attr.FieldName)" rows="2" class="form-control">@(attr.FieldValue)</textarea>
<button type="button" class="btn btn-link has-popover" data-toggle="popover" data-placement="bottom" title="参数说明" data-content="@Html.Raw(attr.DataMapString.Trim().Replace("\n", "<br>"))">配置参数说明</button>
}
else
{
<input type="text" name="@(attr.FieldName)" value="@(attr.FieldValue)" class="form-control" style="display:inline-block;width:500px" />
}
}
else if (attr.FieldType == typeof(int))
{
if (attr.IsFlags && !string.IsNullOrWhiteSpace(attr.DataMapString))
{
<label class="mr-2">@(label):</label>
var flags = int.Parse(attr.FieldValue);
var nv = YieldChain.Helpers.UrlHelper.ParseQueryString(attr.DataMapString);
foreach (var key in nv.AllKeys)
{
var chked = (int.Parse(nv[key]) & flags) > 0;
<label class="mr-1"><input type="checkbox" @(chked ? "checked" : "") value="@(nv[key])" onchange="_config.changeFlags()" />@(key)</label>
}
<input type="hidden" class="flags" name="@(attr.FieldName)" value="@(attr.FieldValue)" />
}
}
</div>
<hr />
}
</form>
<div>
<button class="btn btn-primary" style="width:120px;" onclick="_config.save()">保存配置</button>
</div>
</div>
</div>
@section scripts{
<script>
var saveUrl = '@Url.Action("AjaxSaveWebConfig")';
const OtcWebConfig = function (options) {
if (!options || !options.saveUrl) {
alert("缺少配置参数:saveUrl");
return;
}
//保存配置
this.save = function () {
$.post(options.saveUrl, $('#form1').serialize()).done(function (resp) {
if (resp.errcode) {
layer.alert(resp.errmsg);
} else {
layer.msg('保存成功');
}
}).fail(function () {
layer.alert('请求失败');
});
};
this.changeFlags = function () {
var $e = $(event.target);
var flag = parseInt($e.val());
if (!flag) {
alert('程序错误1');
return;
}
var $ef = $e.parent().nextAll('.flags');
var flags = parseInt($ef.val());
if (isNaN(flags) || flags < 0) {
alert('程序错误2');
return;
}
if ($e.prop('checked')) {
flags |= flag;
} else {
flags ^= flag;
}
$ef.val(flags);
};
};
const _config = new OtcWebConfig({ saveUrl: saveUrl });
$(function () {
$('.has-popover').popover({ html:true});
});
</script>
}
@@ -0,0 +1,87 @@
@section scripts{
<script>
function Add() {
startclientView(0);
}
function addFunctionAlty(value, row, index) {
return [
'<button id="Delete" type="button" class="btn btn-primary">删除</button>',
].join('');
}
window.operateEvents = {
'click #Delete': function (e, value, row, index) {
deleteowner(row.ID);
},
'click #Edit': function (e, value, row, index) {
startclientView(row.ID);
}
};
$('#table').bootstrapTable({
url: "OwnerInfo/GetOwnerInfo",
onDblClickRow: function (arg1, arg2, arg3) {
startclientView(arg1.ID);
},
refreshOptions: function () { }
});
function startclientView(id) {
var srcurl = "/Admin/OwnerInfo/OwnerInfoEdit?ID=" + id;
layer.open({
type: 2,
title: "编辑确认书信息",
shadeClose: false,
shade: 0.4,
area: ['700px', '800px'],
content: srcurl
});
}
function Change() {
$('#table').bootstrapTable('refreshOptions', {});
}
function deleteowner(ID) {
if (confirm("确定删除吗?")) {
$.ajax({
type: "Post",
url: "/OwnerInfo/Deleteowner",
data: { id: ID },
success: function (data) {
Change();
},
error: function (msg) {
alert("error:" + msg);
}
});
}
}
</script>
}
<button class="btn btn-primary" onclick="Add()">添加</button>
<button class="btn btn-primary" onclick="Change()">刷新</button>
<table id="table" data-toggle="table">
<thead>
<tr>
<th data-field="ID" data-visible="false"></th>
<th data-field="Condition">条件</th>
<th data-field="FullName">公司全称</th>
<th data-field="CounterpartyCode">营业执照</th>
<th data-field="RegisteredAddress">注册地址</th>
<th data-field="LegalPerson">法人</th>
<th data-field="BankAccount">户名</th>
<th data-field="Bank">开户行</th>
<th data-field="Card">账号</th>
<th data-field="Payment">大额行号</th>
<th data-field="ContactName">联系人</th>
<th data-field="Address">地址</th>
<th data-field="Email">邮件</th>
<th data-field="PhoneNumber">电话</th>
<th data-field="Fax">传真</th>
<th data-events="operateEvents" data-formatter="addFunctionAlty">操作</th>
</tr>
</thead>
</table>
@@ -0,0 +1,198 @@
@model Owner_info
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>OwnerInfoEdit</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="msapplication-TileColor" content="#2d89ef">
<meta name="theme-color" content="#4188c9">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<link href="~/statics/bundles/bundleV2.min.css" rel="stylesheet" />
<link href="~/Style/Admin/main.css" rel="stylesheet" />
<script src="~/statics/bundles/bundleV2.js?v=@(HtmlUtil.JsVersion)"></script>
<script src="~/Statics/libs/layer/layer.js?v=@(HtmlUtil.JsVersion)"></script>
<script>
function btnSave() {
let ID = parseInt($("#ID").val());
let Condition = $("#Condition").val();
let FullName = $("#FullName").val();
let CounterpartyCode = $("#CounterpartyCode").val();
let RegisteredAddress = $("#RegisteredAddress").val();
let LegalPerson = $("#LegalPerson").val();
let BankAccount = $("#BankAccount").val();
let Bank = $("#Bank").val();
let Card = $("#Card").val();
let Payment = $("#Payment").val();
let ContactName = $("#ContactName").val();
let Address = $("#Address").val();
let Email = $("#Email").val();
let PhoneNumber = $("#PhoneNumber").val();
let Fax = $("#Fax").val();
var date = {
Condition: Condition,
ID: ID,
FullName: FullName,
CounterpartyCode: CounterpartyCode,
RegisteredAddress:RegisteredAddress,
LegalPerson: LegalPerson,
BankAccount: BankAccount,
Bank: Bank,
Card: Card,
Payment: Payment,
ContactName: ContactName,
Address: Address,
Email: Email,
PhoneNumber: PhoneNumber,
Fax: Fax
}
var srcurl = "/Admin/OwnerInfo/PostOwnerInfo";
main.post(srcurl, date).done(function (resp) {
window.parent.layer.closeAll();
window.parent.Change();
}).always(function () {
$e.prop('disabled', false);
});
};
</script>
</head>
<body>
<form class="form-layout" onsubmit="return false;" id="form1">
<div class="card-body" id="OwnerInfo">
<input type="text" class="form-control" id="ID" hidden value="@Model.ID" />
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">条件</label>
<div class="col">
<input type="text" class="form-control" id="Condition" value="@Model.Condition" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">公司全称</label>
<div class="col">
<input type="text" class="form-control" id="FullName" value="@Model.FullName" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">营业执照</label>
<div class="col">
<input type="text" class="form-control" id="CounterpartyCode" value="@Model.CounterpartyCode" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">注册地址</label>
<div class="col">
<input type="text" class="form-control" id="RegisteredAddress" value="@Model.RegisteredAddress" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">法人</label>
<div class="col">
<input type="text" class="form-control" id="LegalPerson" value="@Model.LegalPerson" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">户名</label>
<div class="col">
<input type="text" class="form-control" id="BankAccount" value="@Model.BankAccount" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">开户行</label>
<div class="col">
<input type="text" class="form-control" id="Bank" value="@Model.Bank" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">账号</label>
<div class="col">
<input type="text" class="form-control" id="Card" value="@Model.Card" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">大额行号</label>
<div class="col">
<input type="text" class="form-control" id="Payment" value="@Model.Payment" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">联系人</label>
<div class="col">
<input type="text" class="form-control" id="ContactName" value="@Model.ContactName" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">地址</label>
<div class="col">
<input type="text" class="form-control" id="Address" value="@Model.Address" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">邮件</label>
<div class="col">
<input type="text" class="form-control" id="Email" value="@Model.Email" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">电话</label>
<div class="col">
<input type="text" class="form-control" id="PhoneNumber" value="@Model.PhoneNumber" />
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-row">
<label class="form-label col-auto">传真</label>
<div class="col">
<input type="text" class="form-control" id="Fax" value="@Model.Fax" />
</div>
</div>
</div>
</div>
</form>
<div class="card-footer">
<div class="col-auto">
<button class="btn btn-primary" onclick="btnSave()">保存</button>
</div>
</div>
</body>
</html>
@@ -0,0 +1,162 @@
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="msapplication-TileColor" content="#2d89ef">
<meta name="theme-color" content="#4188c9">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<title>系统管理-@(ViewData["Title"])</title>
<link href="~/statics/bundles/bundleV2.min.css" rel="stylesheet" />
<link href="~/Style/Admin/main.css" rel="stylesheet" />
@RenderSection("heads", required: false)
</head>
<body>
<div class="page">
<div class="flex-fill">
<div class="header py-4">
<div class="container">
<div class="d-flex">
<a class="header-brand" href="/admin/home">
系统管理后台
</a>
<div class="d-flex order-lg-2 ml-auto">
<div class="nav-item d-none d-md-flex">
<button class="btn btn-danger" onclick="restartOtcSystem()">重启系统</button>
</div>
<div class="nav-item d-none d-md-flex">
<button class="btn btn-danger" onclick="exist()">退出</button>
</div>
</div>
<a href="#" class="header-toggler d-lg-none ml-3 ml-lg-0" data-toggle="collapse" data-target="#headerMenuCollapse">
<span class="header-toggler-icon"></span>
</a>
</div>
</div>
</div>
<div class="header collapse d-lg-flex p-0" id="headerMenuCollapse">
<div class="container">
<div class="row align-items-center">
<div class="col-lg order-lg-first">
<ul class="nav nav-tabs border-0 flex-column flex-lg-row" id="headerMenuNavs">
<li class="nav-item">
<a class="nav-link" href="@Url.Action("AppConfig","OtcConfig")">AppConfig</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("WebConfig","OtcConfig")">OtcWeb配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("SmtpConfig","OtcConfig")">邮件发送配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("MailTemplate","OtcConfig")">邮件模板配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("OtcFormat","OtcConfig")">OtcFormat配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("SettlementConfig","OtcConfig")">收盘配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("TradePricingCfg","OtcConfig")">交易要素配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("ClientEditConfig","OtcConfig")">客户编辑配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("TradeMarketReportCfg","OtcConfig")">结算报告配置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("","Tools")">系统工具</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("","OwnerInfo")">确认书信息</a>
</li>
<li class="nav-item">
<a class="nav-link" href="@Url.Action("","DbUpdate")">数据库升级</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="my-3 my-md-5">
<div class="container">
@RenderBody()
</div>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" id="modalLoading">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" style="width: 100%"></div>
</div>
</div>
</div>
</div>
</div>
<div class="modal" data-backdrop="static" data-keyboard="false" tabindex="-1" role="dialog" id="waitMeModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="progress mt-5 mb-5">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 100%"></div>
</div>
</div>
</div>
</div>
</div>
<script src="~/statics/bundles/bundleV2.js?v=@(HtmlUtil.JsVersion)"></script>
<script src="~/Statics/libs/layer/layer.js?v=@(HtmlUtil.JsVersion)"></script>
<script>
var _layout = {
AjaxRestartUrl: '@Url.Action("AjaxRestart","Home")'
};
//重启系统
function restartOtcSystem() {
$.post(_layout.AjaxRestartUrl).done(function (resp) {
if (resp) {
alert(resp);
window.location.reload();
}
});
}
function exist() {
window.location.href = "/Account/logout";
}
$(function () {
var path = location.pathname.toLowerCase();
$('#headerMenuNavs').find('.nav-link').each(function () {
if ($(this).attr('href').toLowerCase() === path) {
$(this).addClass('active');
return false;
}
});
});
</script>
@RenderSection("scripts", required: false)
</body>
</html>
@@ -0,0 +1,90 @@
@{
ViewData["Title"] = "系统工具";
}
@section heads{
<link href="~/statics/libs/datetime/flatpickr/flatpickr.min.css" rel="stylesheet" />
}
<div class="card">
<div class="card-header">
<h4 class="card-title">重新初始化实时风险运算</h4>
</div>
<div class="card-body">
<button class="btn btn-primary" onclick="resetTradePosition()">重置对冲交易持仓</button>
<button class="btn btn-primary" onclick="resetTradeRiskCalcTaskRunner()">重新初始化实时风险运算</button>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="card-title">重新初始化系统默认用户</h4>
</div>
<div class="card-body">
<button class="btn btn-primary" onclick="resetsysUser()">重新初始化系统默认用户</button>
</div>
@if (PS.Config.Company == YLErp.Configuration.CompanyEnum.长江)
{
<div class="card-body">
<div class="">
<label><input type="checkbox" id="inputChangeJiangCheck1" checked /> 清除所选日期已存在的数据</label>
</div>
<div class="mt-2">
<span class="">结算日期:</span><input type="text" id="inputChangeJiangDate1" value="@(DateTime.Today.ToString("yyyy-MM-dd"))" />
<button class="btn btn-primary" onclick="changeJiangSuperviseReportPosition()">执行</button>
</div>
<div class="mt-2 small">使用的结算数据来源由appconfig中的Supervise_Position配置决定</div>
</div>
}
</div>
<div class="card">
<div class="card-header">
<h4 class="card-title">定价日志</h4>
</div>
<div class="card-body">
<button class="btn btn-primary" onclick="queryCalcLog()">查看定价引擎日志</button>
</div>
</div>
@section scripts{
<script src="~/statics/libs/datetime/flatpickr/flatpickr.min.js"></script>
<script>
var page = {
AjaxResetTradePositionUrl: '@Url.Action("AjaxResetTradePosition", "Tools")',
AjaxResetTradeRiskCalcTaskRunnerUrl: '@Url.Action("AjaxResetTradeRiskCalcTaskRunner", "Tools")',
AjaxResetsysUserUrl: '@Url.Action("AjaxResetsysUser", "Tools")',
AjaxChangeJiangUrl: '@Url.Action("AjaxChangeJiangSuperviseReportPosition", "Tools")'
};
$(function () {
flatpickr("#inputChangeJiangDate1", {});
});
//重新初始化实时风险运算
function resetTradeRiskCalcTaskRunner() {
main.post(page.AjaxResetTradeRiskCalcTaskRunnerUrl).done(function (resp) { main.alert('操作成功'); });
}
//重置对冲交易持仓
function resetTradePosition() {
main.post(page.AjaxResetTradePositionUrl).done(function (resp) {main.alert('操作成功');});
}
//重新初始化系统默认用户
function resetsysUser() {
main.post(page.AjaxResetsysUserUrl).done(function (resp) { main.alert('操作成功'); });
}
//长江监管报告-场外业务持仓表
function changeJiangSuperviseReportPosition() {
let postData = {
date: $('#inputChangeJiangDate1').val(),
clearExistings: $('#inputChangeJiangCheck1').prop('checked')
};
main.post(page.AjaxChangeJiangUrl, postData ).done(function (resp) { main.alert('操作成功'); });
}
function queryCalcLog()
{
window.open("/calclog");
}
</script>
}
@@ -0,0 +1,5 @@
@using YLErp
@using YLErp.Web
@using YLErp.Configuration
@using YLErp.Model.Enum
@using YLErp.DBModels
@@ -0,0 +1,3 @@
@{
Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
}
@@ -0,0 +1,73 @@
//保存配置
function SaveValue(id, blEncodeURI) {
var $e = $('#config' + id);
var value = '';
if ($e.is("select") || $e.attr("type") === "text" || $e.is("textarea")) {
value = $e.val();
if (blEncodeURI) value = encodeURIComponent(value);
if ($e.data("value") === value) {
return;
}
} else if ($e.attr("type") === "checkbox") {
value = $e.prop("checked").toString();
}
else {
alert("不支持");
return;
}
main.post(saveConfigValueUrl, { name: $e.attr("name"), value: value }).done(function (resp) {
$e.data("value", value);
$('#respMsg').text(resp.data);
});
}
function OnInputKeyDown(blEncodeURI) {
if (event.keyCode === 13) {
SaveValue(blEncodeURI);
}
}
//重置配置
function ResetConfig() {
main.post(resetConfigValueUrl).done(function (resp) {
$('#respMsg').text(resp.data);
});
}
var ueditor, ueditorConfigId;
function showUeditorConfig(id, title) {
ueditorConfigId = id;
$('.modal-title', '#ueditorModal').text(title || '配置');
$('#ueditorModal').modal('show');
}
function saveUeditorConfig() {
let cont = ueditor.getContent();
$('#config' + ueditorConfigId).val(cont).blur();
$('#ueditorModal').modal('hide');
}
$(function () {
$('#ueditorModal').on('shown.bs.modal', function () {
function insertHtml(editor) {
let content = $('#config' + ueditorConfigId).val() || '';
ueditor.execCommand('insertHtml', content);
}
if (ueditor) {
ueditor.reset();
ueditor.setContent('');
insertHtml();
} else {
ueditor = UE.getEditor('editor', {
autoHeight: false,
wordCount: false,
autoHeightEnabled: false,
initialFrameHeight: 500
});
ueditor.ready(insertHtml);
}
});
});
+113
View File
@@ -0,0 +1,113 @@
var sqlViewer = CodeMirror.fromTextArea(document.getElementById('dbContentText'), {
mode: "text/x-mysql",
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
autofocus: true,
readOnly: true
});
var vue = new Vue({
el: "#dbUpdateDiv",
data: {
updateList: [],
checkAll: false,
filter: { version: '', dbschema: '', upstate: '', versionItems: [] }
},
mounted: function () {
this.getUpdateList();
},
methods: {
//获取升级列表列表
getUpdateList() {
var thisObj = this;
main.post("/Admin/DbUpdate/AjaxGetUpdateList").done(function (resp) {
thisObj.checkAll = false;
thisObj.updateList = resp.data;
let verSet = new Set();
Object.assign(thisObj.filter, { versionItems: [], dbschemaItems: [] })
thisObj.updateList.forEach(x => {
x.checked = false;
verSet.add(x.Version);
});
thisObj.filter.versionItems = Array.from(verSet);
}).fail(function () {
main.alert("加载失败");
});
},
changeItemChecked() {
this.checkAll = this.updateList.every(x => x.checked);
},
changeAllChecked() {
let checked = this.checkAll;
this.updateList.forEach(x => {
x.checked = checked;
});
},
//查看脚本内容
viewUpdateContent(upkey) {
if (upkey) {
upkey = [upkey];
} else {
upkey = this.updateList.filter(x => x.checked).map(x => x.UpKey);
if (!upkey.length) {
return main.alert("请至少选择一项!");
}
}
main.post("/Admin/DbUpdate/AjaxGetUpdateContent", { upKeyList: upkey }).done(function (resp) {
sqlViewer.getDoc().setValue(resp.data);
$("#dbContentModal").modal('show');
sqlViewer.refresh();
});
},
//执行脚本内容
executeUpdate(item) {
let confirmMsg, upkeyList, upMap = {}, isUpdateDone = item === "isUpdateDone";
if (item && !isUpdateDone) {
upkeyList = [item.UpKey];
upMap[item.UpKey] = item;
confirmMsg = item.UpState < 1 ? "确定要执行更新吗?" : "确定要重新执行吗?";
} else {
upkeyList = this.updateList.filter(x => x.checked).map(x => {
upMap[x.UpKey] = x; return x.UpKey;
});
if (!upkeyList.length) {
return main.alert("请至少选择一项!");
}
confirmMsg = "确定要执行批量更新吗?";
}
main.confirm(confirmMsg, function () {
$("#waitMeModal").modal("show");
let postData = { upKeyList: upkeyList, isUpdateDone: isUpdateDone };
main.post("/Admin/DbUpdate/AjaxExecuteUpdate", postData).done(function (resp) {
resp.data.forEach(x => {
let item = upMap[x.UpKey];
if (item) {
item.UpState = x.UpState;
item.UpResult = x.UpResult;
}
});
}).always(() => {
$("#waitMeModal").modal("hide");
});
});
},
itemStatusClass(item) {
if (item.UpState < 0) {
return "text-danger";
}
if (item.UpState > 0) {
return "text-muted";
}
},
isShowItem(item) {
return (this.filter.version && item.Version !== this.filter.version)
|| (this.filter.dbschema && item.DbSchema !== this.filter.dbschema)
|| (this.filter.upstate == true && item.UpState > 0) ? "display:none" : "display:table-row";
}
}
});