不要使用 CSS 方式设置 canvas 的宽高,应使用属性来设置其尺寸。
直接设置属性:
<canvas id="canvas" width="400" height="300"></canvas>因属性值是以 px 为单位的,如果项目全程使用 rem 等其它尺寸单位,可通过 JS 来设置
var canvas = document.getElementById('canvas');
coatingW = $('#coating_frame').width();
coatingH = $('#coating_frame').height();
canvas.width = coatingW;
canvas.height = coatingH;按材料
| 铅酸电池 | 成本低、低温性好、性价比高;能量密度低、寿命短、体积大、安全性差。 |
| 镍氢电池 | 成本低、技术成熟、寿命长、耐用;能量密度低、体积大、电压低、有电池记忆效应。含有重金属,遗弃后对环境造成污染。 |
| 锰酸锂电池 | 成本低、安全性和低温性能好的正极材料,但是其材料本身并不太稳定,容易分解产生气体,因此多用于和其它材料混合使用,以降低电芯成本,但其循环寿命衰减较快,容易发生鼓胀,高温性能较差、寿命相对短。 |
| 磷酸铁锂电池 | 是一种使用磷酸铁锂(LiFePO4)作为正极材料,碳作为负极材料的锂离子电池。具有工作电压高、能量密度大、循环寿命长、安全性能好、自放电率小、无记忆效应的优点。电池温度处于500-600℃时,其内部化学成分才开始分解,并且穿刺、短路、高温都不会燃烧或者爆炸,使用寿命也较长。但车辆续航里程一般,当温度低于-5℃时,充电效率低,不适合北方在冬天充电的需求。 |
| 三元锂电池 | 是指正极材料使用镍钴锰酸锂(Li(NiCoMn)O2)或者镍钴铝酸锂的三元正极材料的锂电池。能量密度高、循环寿命长、不惧低温;高温下稳定不足。能量密度可达最高,但高温性相对较差,关于续航里程有要求的纯电动汽车,其是主流方向,且适合北方天气,低温时电池更加稳定。 |
按制造和封装形式
| 1865电池 | 18650是锂离子电池的鼻祖。日本SONY公司当年为了节省成本而定下的一种标准性的锂离子电池型号,其中18表示直径为18mm,65表示长度为65mm,0表示为圆柱形电池。优点:容量大、寿命长、安全性能高、电压高、没有记忆效应、内阻小、可串联或并联组合成18650锂电池组、使用范围广。 |
| 2170电池 | 2017年1月4日,特斯拉官方宣布新一代锂电池“2170”开始量产。直径为21mm、高度70mm。 |
| 4680电池 | 2020年9月特斯拉发布了的新型电池类型,据介绍,相较2170电池,该电池能量方面提高5倍,续航里程提高16%,动力方面提高6倍。2022年初开始量产。 |
| 刀片电池 | 是比亚迪于2020年3月29日发布的电池产品。该电池采用磷酸铁锂技术。“刀片电池”通过结构创新,在成组时可以跳过“模组”,大幅提高了体积利用率,最终达成在同样的空间内装入更多电芯的设计目标。相较传统电池包,“刀片电池”的体积利用率提升了50%以上,也就是说续航里程可提升50%以上,达到了高能量密度三元锂电池的同等水平。 |
| 麒麟电池 | 2022年3月26日,宁德时代首席科学家吴凯在2022年电动汽车百人会论坛上表示:宁德时代通过不断技术迭代,推出了第三代CTP技术,其系统重量、能量密度及体积能量密度继续引领行业最高水平。在相同的化学体系、同等电池包尺寸下,麒麟电池包的电量,相比4680系统可以提升13%。第三代CTP技术,兼顾极速、无损、安全、高效等优势,适用磷酸铁锂、三元电池,涵盖乘用车、商用车领域。 |
电动汽车就是 EV(Electric vehicle),按照当前的产品模式可分为纯电动的 BEV(Battery Electric vehicle),混合电动汽车 HEV(Hybrid Electric vehicle),插电式混合动力汽车 PHEV(Plug-in Hybrid Electric vehicle),和增程式电动车 EREV(Extended-Range Electric Vehicles)。




自 2023 年 4 月起,Windows 11 已经重新支持显示“秒”,无需第三方工具来实现,点击查看详情。
ElevenClock 下载地址:GitHub,开源软件放心使用
效果:

* 该软件不会影响右下角的显示桌面和系统通知功能。
v3.3 设置方法:
√ 在主屏幕上时钟区显示本程序的时钟样式
ElevenClock 不直接修改任务栏上的时钟区域,而是将时钟覆盖在系统时钟区域的上方。
√ 不要在辅助监视器上显示时钟
此项按实际需求勾选
√ 时间与日期设置 - Set a custom date and time format (for advanced users only)
填写以下内容并 Apply
%H:%M:%S
%Y/%#m/%#d %a
如果不想显示星期,把 %a 去掉即可。
√ 使用自定义字体大小
因分辨率缩放设置不同可能导致显示的字体大小与系统时钟不同,会导致覆盖面过大或过小,从而使系统托盘中的其它图标显示不完整。所以应选择一个与系统时间差不多的字体大小。当显示“周序号”时 ElevenClock 时钟区域可能会远宽于系统时钟区域,可以设置系统时钟显示“星期”(方法见文末)。
v3.2 设置方法:
√ 在主屏幕上时钟区显示本程序的时钟样式
ElevenClock 不直接修改任务栏上的时钟区域,而是将时钟覆盖在系统时钟区域的上方。
√ 不要在辅助监视器上显示时钟
此项按实际需求勾选
√ 显示秒数
这是我们的最终目的。
√ 使用自定义字体大小
因分辨率缩放设置不同可能导致显示的字体大小与系统时钟不同,会导致覆盖面过大或过小,从而使系统托盘中的其它图标显示不完整。所以应选择一个与系统时间差不多的字体大小。当显示“周序号”时 ElevenClock 时钟区域可能会远宽于系统时钟区域,可以设置系统时钟显示“星期”(方法见文末)。
如何显示系统时间“星期”:
打开“更改日期和时间”,在“日期”选项卡的“短日期”中添加“ddd”。

项目 - 属性 - 生成 - 输出 - 文档文件,勾选“生成包含 API 文档的文件。”,“XML 文档文件路径”可留空。

在配置方法 AddSwaggerGen 中添加以下两行
var xmlFilename = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"; options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
将 Windows 更新代理更新到最新版本:从 Microsoft 下载中心手动下载 Windows 更新代理
再次尝试。
public static class EntityFrameworkCoreExtension
{
private static DbCommand CreateCommand(DatabaseFacade facade, string sql, out DbConnection connection, params object[] parameters)
{
var conn = facade.GetDbConnection();
connection = conn;
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
return cmd;
}
public static DataTable SqlQuery(this DatabaseFacade facade, string sql, params object[] parameters)
{
var command = CreateCommand(facade, sql, out DbConnection conn, parameters);
var reader = command.ExecuteReader();
var dt = new DataTable();
dt.Load(reader);
reader.Close();
conn.Close();
return dt;
}
public static List<T> SqlQuery<T>(this DatabaseFacade facade, string sql, params object[] parameters) where T : class, new()
{
var dt = SqlQuery(facade, sql, parameters);
return dt.ToList<T>();
}
public static List<T> ToList<T>(this DataTable dt) where T : class, new()
{
var propertyInfos = typeof(T).GetProperties();
var list = new List<T>();
foreach (DataRow row in dt.Rows)
{
var t = new T();
foreach (PropertyInfo p in propertyInfos)
{
if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)
{
p.SetValue(t, row[p.Name], null);
}
}
list.Add(t);
}
return list;
}
}调用示例:
var data = db.Database.SqlQuery<List<string>>("SELECT 'title' FROM `table` WHERE `id` = {0};", id);普通的 nginx http 反向代理 https 时是需要配置证书的,但我们又不可能由源域名的证书,所以要使用 nginx 的 stream 模块。普通的 nginx 反向代理属于第七层代理,而 stream 模块是第四层代理,通过转发的 tcp/ip 协议实现高功能,所以不需要证书。
我们这里以使用宝塔安装的 nginx 为例,其实其他系统也是类似,只要找到编译的 nginx 的源码目录就行了
编译前先将已经安装的 nginx 文件进行备份
通过 ps 命令查看 nginx 文件的路径。以下所有步骤都以自身 nginx 路径为准
# ps -elf | grep nginx
# cd /www/server/nginx/sbin/
# cp nginx nginx.bak然后查看当前 nginx 编译的参数
/www/server/nginx/sbin/nginx -V将 ./configure arguents:之后的内容复制到记事本备用(备注:我们这里其实使用的是 Tengine-2.3.1,所以下面的编译参数可能跟普通 nginx 不是很一样)
内容如下:
--user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --with-openssl=/www/server/nginx/src/openssl --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --add-module=/www/server/nginx/src/lua_nginx_module --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-pcre=pcre-8.42 --with-cc-opt=-Wno-error --add-module=/www/server/nginx/src/ngx-pagespeed
进入 src 目录
cd /www/server/nginx/src我们在上面的内容中加入两个参数
./configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --with-openssl=/www/server/nginx/src/openssl --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --add-module=/www/server/nginx/src/lua_nginx_module --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-pcre=pcre-8.42 --with-cc-opt=-Wno-error --add-module=/www/server/nginx/src/ngx-pagespeed --with-stream --with-stream_ssl_preread_module
并执行它
然后
make && make install重启 nginx
service nginx restartnginx -V 看看模块是不是加载了

新建个站点,配置反向代理
卸载
使用 nginx.bak 文件替换掉自编译的 nginx 文件,替换后重启 nginx。
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace xxx.xxx.xxx.Controllers
{
public class DiscuzTinyintViewerController : Controller
{
public IActionResult Index()
{
using var context = new Data.xxx.xxxContext();
var conn = context.Database.GetDbConnection();
conn.Open();
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT `TABLE_NAME` FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE();";
Dictionary<string, List<FieldType>?> tables = new();
using var r = cmd.ExecuteReader();
while (r.Read())
{
tables.Add((string)r["TABLE_NAME"], null);
}
conn.Close();
foreach (var table in tables)
{
var conn2 = context.Database.GetDbConnection();
conn2.Open();
using var cmd2 = conn2.CreateCommand();
cmd2.CommandText = "DESCRIBE " + table.Key;
using var r2 = cmd2.ExecuteReader();
List<FieldType> fields = new();
while (r2.Read())
{
if (((string)r2[1]).Contains("tinyint(1)"))
{
fields.Add(new()
{
Field = (string)r2[0],
Type = (string)r2[1],
Null = (string)r2[2],
});
}
}
conn2.Close();
tables[table.Key] = fields;
}
foreach (var table in tables)
{
foreach (var f in table.Value)
{
var conn3 = context.Database.GetDbConnection();
conn3.Open();
using var cmd3 = conn3.CreateCommand();
cmd3.CommandText = $"SELECT {f.Field} as F, COUNT({f.Field}) as C FROM {table.Key} GROUP BY {f.Field}";
using var r3 = cmd3.ExecuteReader();
List<FieldType.ValueCount> vs = new();
while (r3.Read())
{
vs.Add(new() { Value = Convert.ToString(r3["F"]), Count = Convert.ToInt32(r3["C"]) });
}
conn3.Close();
f.groupedValuesCount = vs;
}
}
return Json(tables.Where(c => c.Value != null && c.Value.Count > 0));
}
private class FieldType
{
public string Field { get; set; }
public string Type { get; set; }
public string Null { get; set; }
public List<ValueCount> groupedValuesCount { get; set; }
public class ValueCount
{
public string Value { get; set; }
public int Count { get; set; }
}
public string RecommendedType
{
get
{
if (groupedValuesCount == null || groupedValuesCount.Count < 2)
{
return "无建议";
}
else if (groupedValuesCount.Count == 2 && groupedValuesCount.Any(c => c.Value == "0") && groupedValuesCount.Any(c => c.Value == "1"))
{
return "bool" + (Null == "YES" ? "?" : "");
}
else
{
return "sbyte" + (Null == "YES" ? "?" : "");
}
}
}
}
}
}[{
"key": "pre_forum_post",
"value": [{
"field": "first",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "0",
"count": 1395501
}, {
"value": "1",
"count": 179216
}],
"recommendedType": "bool"
}, {
"field": "invisible",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "-5",
"count": 9457
}, {
"value": "-3",
"count": 1412
}, {
"value": "-2",
"count": 1122
}, {
"value": "-1",
"count": 402415
}, {
"value": "0",
"count": 1160308
}, {
"value": "1",
"count": 3
}],
"recommendedType": "sbyte"
}, {
"field": "anonymous",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "0",
"count": 1574690
}, {
"value": "1",
"count": 27
}],
"recommendedType": "bool"
}, {
"field": "usesig",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "0",
"count": 162487
}, {
"value": "1",
"count": 1412230
}],
"recommendedType": "bool"
}, {
"field": "htmlon",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "0",
"count": 1574622
}, {
"value": "1",
"count": 95
}],
"recommendedType": "bool"
}, {
"field": "bbcodeoff",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "-1",
"count": 935448
}, {
"value": "0",
"count": 639229
}, {
"value": "1",
"count": 40
}],
"recommendedType": "sbyte"
}, {
"field": "smileyoff",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "-1",
"count": 1359482
}, {
"value": "0",
"count": 215186
}, {
"value": "1",
"count": 49
}],
"recommendedType": "sbyte"
}, {
"field": "parseurloff",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "0",
"count": 1572844
}, {
"value": "1",
"count": 1873
}],
"recommendedType": "bool"
}, {
"field": "attachment",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "0",
"count": 1535635
}, {
"value": "1",
"count": 2485
}, {
"value": "2",
"count": 36597
}],
"recommendedType": "sbyte"
}, {
"field": "comment",
"type": "tinyint(1)",
"null": "NO",
"groupedValuesCount": [{
"value": "0",
"count": 1569146
}, {
"value": "1",
"count": 5571
}],
"recommendedType": "bool"
}]
}]Regex.Escape(String) 方法:
通过替换为转义码来转义最小的字符集(\、*、+、?、|、{、[、(、)、^、$、.、# 和空白)。 这将指示正则表达式引擎按原义解释这些字符而不是解释为元字符。
示例:
string str = @"123\c\d\e";
string r1 = @"\d";
string r2 = Regex.Escape(r1);
return Json(new
{
m1 = Regex.Matches(str, r1).Select(c => c.Value),
m2 = Regex.Matches(str, r2).Select(c => c.Value)
});结果:
{
"m1":[
"1",
"2",
"3"
],
"m2":[
"\\d"
]
}一般地,我们使用通配符 a*c 在字符串 abcd 中查找:
string s = @"abcd";
string w = @"a*c";
string r = Regex.Escape(w).Replace(@"\*", @".*?").Replace(@"\?", @".?");
return Content(Regex.Match(s, r).Value);结果:
abc同理,使用通配符 \d*\f 在字符串 \a\b\c\d\e\f 中查找:
string s = @"\a\b\c\d\e\f";
string w = @"\d*\f";
string r = Regex.Escape(w).Replace(@"\*", @".*?").Replace(@"\?", @".?");
return Content(Regex.Match(s, r).Value);结果:
\d\e\f
