Skip to content

Commit 52a3653

Browse files
committed
2 parents a299a9f + e2e47a5 commit 52a3653

File tree

446 files changed

+9174
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

446 files changed

+9174
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ ToolGood.Algorithm
44

55
ToolGood.Algorithm是一个功能强大、轻量级、兼容`Excel公式`的算法类库,旨在提高开发人员在不同业务场景中的生产力。
66

7+
WebAssembly版本,请看csharp文件夹下`ToolGood.Algorithm.WebAssembly`,`ToolGood.Algorithm2.WebTest` 两个项目。
78

89
**适用场景:** 代码与算法分离,避免项目强制升级
910

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
namespace ToolGood.Algorithm.WebAssembly
2+
{
3+
using Microsoft.JSInterop;
4+
using System.Reflection.Metadata;
5+
using System.Text.Json;
6+
using ToolGood.Algorithm;
7+
using ToolGood.Algorithm.Enums;
8+
9+
public class Program
10+
{
11+
private static void Main(string[] args)
12+
{
13+
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
14+
}
15+
16+
[JSInvokable]
17+
public static string TryEvaluateString(string exp, string def = null, string data = null, string option = null)
18+
{
19+
AlgorithmEngine ae;
20+
if (option == null) {
21+
ae = new AlgorithmEngine();
22+
} else {
23+
var ops = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(option);
24+
ae = new AlgorithmEngine(bool.Parse(ops["IgnoreCase"].ToString()));
25+
ae.UseExcelIndex = bool.Parse(ops["UseExcelIndex"].ToString());
26+
ae.UseTempDict = bool.Parse(ops["UseTempDict"].ToString());
27+
ae.UseLocalTime = bool.Parse(ops["UseLocalTime"].ToString());
28+
ae.DistanceUnit = (DistanceUnitType)(int.Parse(ops["DistanceUnit"].ToString()));
29+
ae.AreaUnit = (AreaUnitType)(int.Parse(ops["AreaUnit"].ToString()));
30+
ae.VolumeUnit = (VolumeUnitType)(int.Parse(ops["VolumeUnit"].ToString()));
31+
ae.MassUnit = (MassUnitType)(int.Parse(ops["MassUnit"].ToString()));
32+
}
33+
if (data != null) {
34+
ae.AddParameterFromJson(data);
35+
}
36+
return ae.TryEvaluate(exp, def);
37+
}
38+
39+
[JSInvokable]
40+
public static decimal TryEvaluateNumber(string exp, decimal def, string data = null, string option = null)
41+
{
42+
AlgorithmEngine ae;
43+
if (option == null) {
44+
ae = new AlgorithmEngine();
45+
} else {
46+
var ops = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(option);
47+
ae = new AlgorithmEngine(bool.Parse(ops["IgnoreCase"].ToString()));
48+
ae.UseExcelIndex = bool.Parse(ops["UseExcelIndex"].ToString());
49+
ae.UseTempDict = bool.Parse(ops["UseTempDict"].ToString());
50+
ae.UseLocalTime = bool.Parse(ops["UseLocalTime"].ToString());
51+
ae.DistanceUnit = (DistanceUnitType)(int.Parse(ops["DistanceUnit"].ToString()));
52+
ae.AreaUnit = (AreaUnitType)(int.Parse(ops["AreaUnit"].ToString()));
53+
ae.VolumeUnit = (VolumeUnitType)(int.Parse(ops["VolumeUnit"].ToString()));
54+
ae.MassUnit = (MassUnitType)(int.Parse(ops["MassUnit"].ToString()));
55+
}
56+
if (data != null) {
57+
ae.AddParameterFromJson(data);
58+
}
59+
return ae.TryEvaluate(exp, def);
60+
}
61+
62+
[JSInvokable]
63+
public static bool TryEvaluateBool(string exp, bool def, string data = null, string option = null)
64+
{
65+
AlgorithmEngine ae;
66+
if (option == null) {
67+
ae = new AlgorithmEngine();
68+
} else {
69+
var ops = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(option);
70+
ae = new AlgorithmEngine(bool.Parse(ops["IgnoreCase"].ToString()));
71+
ae.UseExcelIndex = bool.Parse(ops["UseExcelIndex"].ToString());
72+
ae.UseTempDict = bool.Parse(ops["UseTempDict"].ToString());
73+
ae.UseLocalTime = bool.Parse(ops["UseLocalTime"].ToString());
74+
ae.DistanceUnit = (DistanceUnitType)(int.Parse(ops["DistanceUnit"].ToString()));
75+
ae.AreaUnit = (AreaUnitType)(int.Parse(ops["AreaUnit"].ToString()));
76+
ae.VolumeUnit = (VolumeUnitType)(int.Parse(ops["VolumeUnit"].ToString()));
77+
ae.MassUnit = (MassUnitType)(int.Parse(ops["MassUnit"].ToString()));
78+
}
79+
if (data != null) {
80+
ae.AddParameterFromJson(data);
81+
}
82+
return ae.TryEvaluate(exp, def);
83+
}
84+
85+
[JSInvokable]
86+
public static string TryEvaluateDateTime(string exp, DateTime def, string data = null, string option = null)
87+
{
88+
AlgorithmEngine ae;
89+
if (option == null) {
90+
ae = new AlgorithmEngine();
91+
} else {
92+
var ops = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(option);
93+
ae = new AlgorithmEngine(bool.Parse(ops["IgnoreCase"].ToString()));
94+
ae.UseExcelIndex = bool.Parse(ops["UseExcelIndex"].ToString());
95+
ae.UseTempDict = bool.Parse(ops["UseTempDict"].ToString());
96+
ae.UseLocalTime = bool.Parse(ops["UseLocalTime"].ToString());
97+
ae.DistanceUnit = (DistanceUnitType)(int.Parse(ops["DistanceUnit"].ToString()));
98+
ae.AreaUnit = (AreaUnitType)(int.Parse(ops["AreaUnit"].ToString()));
99+
ae.VolumeUnit = (VolumeUnitType)(int.Parse(ops["VolumeUnit"].ToString()));
100+
ae.MassUnit = (MassUnitType)(int.Parse(ops["MassUnit"].ToString()));
101+
}
102+
if (data != null) {
103+
ae.AddParameterFromJson(data);
104+
}
105+
return ae.TryEvaluate(exp, def).ToString("yyyy-MM-dd HH:mm:ss");
106+
}
107+
[JSInvokable]
108+
109+
public static String GetSimplifiedFormula(String formula, string data = null, string option = null)
110+
{
111+
AlgorithmEngine ae;
112+
if (option == null) {
113+
ae = new AlgorithmEngine();
114+
} else {
115+
var ops = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(option);
116+
ae = new AlgorithmEngine(bool.Parse(ops["IgnoreCase"].ToString()));
117+
ae.UseExcelIndex = bool.Parse(ops["UseExcelIndex"].ToString());
118+
ae.UseTempDict = bool.Parse(ops["UseTempDict"].ToString());
119+
ae.UseLocalTime = bool.Parse(ops["UseLocalTime"].ToString());
120+
ae.DistanceUnit = (DistanceUnitType)(int.Parse(ops["DistanceUnit"].ToString()));
121+
ae.AreaUnit = (AreaUnitType)(int.Parse(ops["AreaUnit"].ToString()));
122+
ae.VolumeUnit = (VolumeUnitType)(int.Parse(ops["VolumeUnit"].ToString()));
123+
ae.MassUnit = (MassUnitType)(int.Parse(ops["MassUnit"].ToString()));
124+
}
125+
if (data != null) {
126+
ae.AddParameterFromJson(data);
127+
}
128+
return ae.GetSimplifiedFormula(formula);
129+
}
130+
131+
132+
[JSInvokable]
133+
public static string EvaluateFormula(string exp,string splitChars, string data = null, string option = null)
134+
{
135+
AlgorithmEngine ae;
136+
if (option == null) {
137+
ae = new AlgorithmEngine();
138+
} else {
139+
var ops = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(option);
140+
ae = new AlgorithmEngine(bool.Parse(ops["IgnoreCase"].ToString()));
141+
ae.UseExcelIndex = bool.Parse(ops["UseExcelIndex"].ToString());
142+
ae.UseTempDict = bool.Parse(ops["UseTempDict"].ToString());
143+
ae.UseLocalTime = bool.Parse(ops["UseLocalTime"].ToString());
144+
ae.DistanceUnit = (DistanceUnitType)(int.Parse(ops["DistanceUnit"].ToString()));
145+
ae.AreaUnit = (AreaUnitType)(int.Parse(ops["AreaUnit"].ToString()));
146+
ae.VolumeUnit = (VolumeUnitType)(int.Parse(ops["VolumeUnit"].ToString()));
147+
ae.MassUnit = (MassUnitType)(int.Parse(ops["MassUnit"].ToString()));
148+
}
149+
if (data != null) {
150+
ae.AddParameterFromJson(data);
151+
}
152+
return ae.EvaluateFormula(exp, splitChars.ToCharArray());
153+
}
154+
155+
[JSInvokable]
156+
public static bool IsKeywords(string parameter)
157+
{
158+
return AlgorithmEngineHelper.IsKeywords(parameter);
159+
}
160+
161+
[JSInvokable]
162+
public static string GetDiyNames(String exp)
163+
{
164+
return JsonSerializer.Serialize(AlgorithmEngineHelper.GetDiyNames(exp));
165+
}
166+
167+
168+
[JSInvokable]
169+
public static string UnitConversion(decimal src, string oldSrcUnit, string oldTarUnit, string name = null)
170+
{
171+
Dictionary<string,object> dic = new Dictionary<string,object>();
172+
try {
173+
var r = AlgorithmEngineHelper.UnitConversion(src, oldSrcUnit, oldTarUnit, name);
174+
dic["code"] = 0;
175+
dic["result"] = r;
176+
177+
} catch (Exception ex) {
178+
dic["code"] = 1;
179+
dic["error"] = ex.Message;
180+
}
181+
return JsonSerializer.Serialize(dic);
182+
}
183+
184+
}
185+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"profiles": {
3+
"ToolGood.Algorithm.WebAssembly": {
4+
"commandName": "Project",
5+
"launchBrowser": true,
6+
"environmentVariables": {
7+
"ASPNETCORE_ENVIRONMENT": "Development"
8+
},
9+
"applicationUrl": "https://localhost:51417;http://localhost:51418"
10+
}
11+
}
12+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
10+
<!--<PackageReference Include="SkiaSharp.Views.Blazor" Version="2.88.8" />-->
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\ToolGood.Algorithm2\ToolGood.Algorithm2.csproj" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@page
2+
@model ErrorModel
3+
@{
4+
ViewData["Title"] = "Error";
5+
}
6+
7+
<h1 class="text-danger">Error.</h1>
8+
<h2 class="text-danger">An error occurred while processing your request.</h2>
9+
10+
@if (Model.ShowRequestId)
11+
{
12+
<p>
13+
<strong>Request ID:</strong> <code>@Model.RequestId</code>
14+
</p>
15+
}
16+
17+
<h3>Development Mode</h3>
18+
<p>
19+
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
20+
</p>
21+
<p>
22+
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
23+
It can result in displaying sensitive information from exceptions to end users.
24+
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
25+
and restarting the app.
26+
</p>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.AspNetCore.Mvc.RazorPages;
3+
using System.Diagnostics;
4+
5+
namespace ToolGood.Algorithm2.WebTest.Pages
6+
{
7+
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
8+
[IgnoreAntiforgeryToken]
9+
public class ErrorModel : PageModel
10+
{
11+
public string? RequestId { get; set; }
12+
13+
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
14+
15+
private readonly ILogger<ErrorModel> _logger;
16+
17+
public ErrorModel(ILogger<ErrorModel> logger)
18+
{
19+
_logger = logger;
20+
}
21+
22+
public void OnGet()
23+
{
24+
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
25+
}
26+
}
27+
28+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
@page
2+
@model IndexModel
3+
@{
4+
Layout = null;
5+
}
6+
<html>
7+
<head>
8+
<meta charset="UTF-8" />
9+
</head>
10+
<body>
11+
编译ToolGood.Algorithm.WebAssembly项目,生成文件夹下的wwwroot文件夹中的_framework文件夹中就是生成的WebAssembly和相关文件
12+
<br />
13+
我们运行前端项目. 由于Blazor会生成blat、dll等不被Web服务器默认接受的文件类型,所以请确保在Web服务器上为如下格式的文件配置MimeType:.gz、.dat、.wasm
14+
15+
16+
<pre>
17+
DistanceUnitType = new class { constructor() { this.MM = 1; this.CM = 2; this.DM = 3; this.M = 4; this.KM = 5; } }();
18+
AreaUnitType = new class { constructor() { this.MM2 = 11; this.CM2 = 12; this.DM2 = 13; this.M2 = 14; this.KM2 = 15; } }();
19+
VolumeUnitType = new class { constructor() { this.MM3 = 21; this.CM3 = 22; this.DM3 = 23; this.M3 = 24; this.KM3 = 25; } }();
20+
MassUnitType = new class { constructor() { this.G = 31; this.KG = 32; this.T = 33; } }();
21+
AlgorithmEngine = class {
22+
constructor() {
23+
this.UseExcelIndex = true;
24+
this.UseTempDict = false;
25+
this.UseLocalTime = false;
26+
this.DistanceUnit = DistanceUnitType.M;
27+
this.AreaUnit = AreaUnitType.M2;
28+
this.VolumeUnit = VolumeUnitType.M3;
29+
this.MassUnit = MassUnitType.KG;
30+
this.IgnoreCase = false;
31+
}
32+
TryEvaluateString = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateString', exp, def, data, JSON.stringify(this)); }
33+
TryEvaluateNumber = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateNumber', exp, def, data, JSON.stringify(this)); }
34+
TryEvaluateBool = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateBool', exp, def, data, JSON.stringify(this)); }
35+
TryEvaluateDateTime = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateDateTime', exp, def, data, JSON.stringify(this)); }
36+
TryEvaluate = function (exp, def, data) {
37+
if (def == null) { return this.TryEvaluateString(exp, def, data); }
38+
if (typeof def == "number") { return this.TryEvaluateNumber(exp, def, data); }
39+
if (typeof def == "boolean") { return this.TryEvaluateBool(exp, def, data); }
40+
if (typeof def == "object" && def instanceof Date) { return this.TryEvaluateDateTime(exp, def, data); }
41+
return this.TryEvaluateString(exp, def, data);
42+
}
43+
};
44+
45+
window.onload = async function () {
46+
await Blazor.start();
47+
var ae = new AlgorithmEngine();
48+
r = ae.TryEvaluate("'S' & 1", "")
49+
alert("'S' & 1 =>" + r);
50+
r = ae.TryEvaluate("1+2", 0)
51+
alert("1+2 =>" + r);
52+
r = ae.TryEvaluate("1=1", false)
53+
alert("1=1 =>" + r);
54+
r = ae.TryEvaluate("date(2014,1,2)", new Date())
55+
alert('date(2014,1,2) =>' + r);
56+
};
57+
</pre>
58+
</body>
59+
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
60+
<script>
61+
DistanceUnitType = new class { constructor() { this.MM = 1; this.CM = 2; this.DM = 3; this.M = 4; this.KM = 5; } }();
62+
AreaUnitType = new class { constructor() { this.MM2 = 11; this.CM2 = 12; this.DM2 = 13; this.M2 = 14; this.KM2 = 15; } }();
63+
VolumeUnitType = new class { constructor() { this.MM3 = 21; this.CM3 = 22; this.DM3 = 23; this.M3 = 24; this.KM3 = 25; } }();
64+
MassUnitType = new class { constructor() { this.G = 31; this.KG = 32; this.T = 33; } }();
65+
AlgorithmEngine = class {
66+
constructor() {
67+
this.UseExcelIndex = true;
68+
this.UseTempDict = false;
69+
this.UseLocalTime = false;
70+
this.DistanceUnit = DistanceUnitType.M;
71+
this.AreaUnit = AreaUnitType.M2;
72+
this.VolumeUnit = VolumeUnitType.M3;
73+
this.MassUnit = MassUnitType.KG;
74+
this.IgnoreCase = false;
75+
}
76+
TryEvaluateString = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateString', exp, def, data, JSON.stringify(this)); }
77+
TryEvaluateNumber = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateNumber', exp, def, data, JSON.stringify(this)); }
78+
TryEvaluateBool = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateBool', exp, def, data, JSON.stringify(this)); }
79+
TryEvaluateDateTime = function (exp, def, data) { return DotNet.invokeMethod('ToolGood.Algorithm.WebAssembly', 'TryEvaluateDateTime', exp, def, data, JSON.stringify(this)); }
80+
TryEvaluate = function (exp, def, data) {
81+
if (def == null) { return this.TryEvaluateString(exp, def, data); }
82+
if (typeof def == "number") { return this.TryEvaluateNumber(exp, def, data); }
83+
if (typeof def == "boolean") { return this.TryEvaluateBool(exp, def, data); }
84+
if (typeof def == "object" && def instanceof Date) { return this.TryEvaluateDateTime(exp, def, data); }
85+
return this.TryEvaluateString(exp, def, data);
86+
}
87+
};
88+
89+
window.onload = async function () {
90+
await Blazor.start();
91+
var ae = new AlgorithmEngine();
92+
r = ae.TryEvaluate("'S' & 1", "")
93+
alert("'S' & 1 =>" + r);
94+
r = ae.TryEvaluate("1+2", 0)
95+
alert("1+2 =>" + r);
96+
r = ae.TryEvaluate("1=1", false)
97+
alert("1=1 =>" + r);
98+
r = ae.TryEvaluate("date(2014,1,2)", new Date())
99+
alert('date(2014,1,2) =>' + r);
100+
};
101+
</script>
102+
</html>

0 commit comments

Comments
 (0)