Hexo的使用

使用Hexo生成博文中播入图片

  1. 把主页配置文件_config.yml 里的post_asset_folder:这个选项设置为true
  2. 在你的hexo目录下执行如下命令,下载一个可以上传本地图片的插件

    1
    npm install hexo-asset-image --save
  3. 执行

    1
    hexo new "newblog"

    生成newblog.md的同时,会生成一个同名的文件在Source目录下,将你要引用的图片放入这个目录下,在文章中引用图片时,

    1
    ![你想输入的文字](xxxx/图片名.jpg)

SourceTree使用

SourceTree的安装

安装没什么好说,但安装之后需要登陆之后才能使用,这个登陆也不知道怎么搞的,总是失败,在网上查找了一些解决方法,跳过这个初始化步骤。当然如果你人品好,登陆正常,可以跳过此步。

跳过初始化步骤

在目录 C:\Users{youruser}\AppData\Local\Atlassian\SourceTree 下创建文件accounts.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[
{
"$id": "1",
"$type": "SourceTree.Api.Host.Identity.Model.IdentityAccount, SourceTree.Api.Host.Identity",
"Authenticate": true,
"HostInstance": {
"$id": "2",
"$type": "SourceTree.Host.Atlassianaccount.AtlassianAccountInstance, SourceTree.Host.AtlassianAccount",
"Host": {
"$id": "3",
"$type": "SourceTree.Host.Atlassianaccount.AtlassianAccountHost, SourceTree.Host.AtlassianAccount",
"Id": "atlassian account"
},
"BaseUrl": "https://id.atlassian.com/"
},
"Credentials": {
"$id": "4",
"$type": "SourceTree.Model.BasicAuthCredentials, SourceTree.Api.Account",
"Username": "",
"Email": null
},
"IsDefault": false
}
]

OSharp读书笔记

EntityFramework与其它ORM相比有什么优点

  • EntityFramework 是微软大力发展的一个开源项目,EF 6 在 codeplex.com 开源,EF 7 在 github.com 随 ASP.NET 5 开源。
  • EntityFramework 能轻松支持各大主流数据库,只要引入相应数据库的 DataProvider 即可,能无差异的操作各大主流数据库。
  • EntityFramework 支持 linq to entities 语句查询,强类型支持,高效实现查询需求。
  • EntityFramework 全面封装了数据库细节,使用了大量的“约定胜于配置”的思想,使开发者不必直接对关系存储架构编程,减少代码量,减轻维护工作,并使项目可维护性更高

为什么要封装EntityFramework

  • 不是所有的开发人员都对 EntityFramework 足够熟悉,封装之后能将 EntityFramework 的细节及较敏感的 API 进行包装与隐藏,使 EntityFramework 的使用更加透明易用。
  • 统一的封装,有利于对业务层提供统一的 API,对业务层的代码规范非常有利。
  • 封装有利于业务实体与 EntityFramework 的解耦。如果不封装,所有业务实体模型(Model)都要在上下文类中设置一个 DbSet 类型的实体集,将与上下文强耦合,当需求发生变化时,都要对原有代码进行修改,很不利于维护。而封装之后,所有的实体模型都是动态加载到上下文类中的,业务实体与 EntityFramework 能够完全解耦,大大增强系统的可维护性。

IEnumerable 与 IQueryable 的区别

  在设计数据访问层的查询API的时候,IEnumerable 和 IQueryable 都可以作为集合类查询结果的返回类型,那么,这两者有什么区别呢?为什么误用的时候会造成致命的性能问题呢?
  IEnumerable 接口的声明为: 

1
2
3
4
/// <summary>
/// 公开枚举数,该枚举数支持在指定类型的集合上进行简单迭代。
/// </summary>
public interface IEnumerable<out T> : IEnumerable

IQueryable<<T> 接口的声明为:

1
2
3
4
/// <summary>
/// 提供对数据类型已知的特定数据源的查询进行计算的功能。
/// </summary>
public interface IQueryable<out T> : IEnumerable<T>, IQueryable, IEnumerable

在进行查询的时候,IEnumerable 接口接受一个 Func<T, bool> 类型的委托参数: public static IEnumerable Where(this IEnumerable source, Func<TSource, bool> predicate); ,而 IQueryable 接口接受一个 Expression<Func<T, bool>> 类型的表达式参数: public static IQueryable Where(this IQueryable source, Expression<Func<TSource, bool>> predicate); 。
正因为 IEnumerable 接受的参数 predicate 数据类型是委托类型,所以这个参数在被调用的时候,就会立即执行查询逻辑,然后将查询的结果保存在内存中,后续的查询逻辑是完全在内存中执行的。而 IQueryable 接受的参数 predicate 数据类型是表达式类型,这个参数会一直往下传递,直到被 IQueryable 中的 IQueryableProvider 类型的 Provider 属性解析成真正的查询语句(如 sql 语句),才传到数据源中进行查询动作。
所以,如果查询返回的数据集合很大的时候,使用 IEnumerable 作为返回类型,会将这个数据集合立即加载到内存中,比如在设计 IRepository 的 API 时,设计 IEnumerable GetAll(); , IEnumerable GetByPredicate(Func<T, bool> predicate); 这种 API ,是非常可怕的,如果一个表中有几十上百万的数据,也同样会把所有数据加载到内存中,可能直接就导致服务器宕机了。即使数据量不大,当并发量上来的时候,也同样会造成极大的性能问题。

过早地内存化数据

  IEnumerable 类型与 IQueryable 类型是支持延迟的,没有真正使用数据之前,不管怎么调用,都不会执行查询,数据还是在数据库内,只有真正使用数据的时候,才会执行查询,把数据本地化到内存中。这样一来,什么时候执行本地化操作(ToArray(),ToList()等操作)就显得非常重要了,如果过早的执行本地化操作,那么就容易造成加载到内存的数据集合过于庞大,记录条数过多,造成性能问题。因此,在进行数据查询的时候,原则上应该按需获取数据,取出的数据集合就尽量的小,字段应尽量少,到数据真正使用的时候,才执行数据内存本地化操作。对于筛选部分字段的需求,linq to entities 的 select 查询匿名结果的查询方式,提供了有力的支持。

导航属性的延迟加载与循环

  EntityFramework 实体模型的导航属性(即与当前表有外键关系的关联表)通常标记为 virtual,标记为 virtual 之后,相应属性的数据是具有延迟加载的特性的,只有真正用到相应属性的数据时,才会根据外键关系执行相应的查询动作,加载相应的数据。延迟加载的特性,能给系统性能带来优化,因为加载主干实体时只加载主干实体的信息,不会把关联实体的信息都加载进来,关联实体的数据只有用到的时候都会去加载。但也正是因为延迟加载,导航属性的数据是用到一次就执行一次查询动作,加载一次数据,一次还如,如果对于相同实体,需要多次用到同一个导航属性,就会产生多次重复的查询动作来加载导航属性的数据,给系统带来性能问题。例如如下的操作:

设计概要

设计概要

实现功能

基本信息

包含但不限于:
编码、中文名称、最新净值、净值日期
设置状态:分级:一般、关注、持有

历史净值

交易记录

Dom元素

标签

span

HTML <span> 元素
HTML <span> 元素是内联元素,可用作文本的容器
<span> 元素也没有特定的含义。
当与 CSS 一同使用时,<span> 元素可用于为部分文本设置样式属性。

EasyUI使用

1. datagrid使用

1.1. 初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$('#HouseData').datagrid({
url: '/Ashx/TempHouse.ashx?type=extractinghouseinfo&ownerinfo=' + ownerInfo,
method: 'get',
idField: 'house_id',
loadMsg: "数据加载中......",
fitColumns: true,//自适应宽度
singleSelect: true,//是否单选
pagination: true,//分页控件
pageSize: 15,//每页显示的记录条数,默认为10
pageList: [5, 10, 15],//可以设置每页记录条数的列表
beforePageText: '第',//页数文本框前显示的汉字
afterPageText: '页 共 {pages} 页',
displayMsg: '当前显示 {from} - {to} 条记录 共 {total} 条记录',
rownumbers: true,//行号
striped: true,//隔行变色
columns: [[
{ field: 'ck', checkbox: true },
{ field: 'house_id', title: '房屋ID', width: 180, hidden: 'true' },
{ field: 'income_id', title: '业务号', width: 180 },
{ field: 'right_id', title: '房产证号', width: 180 },
{ field: 'owner_name', title: '产权人', width: 180 },
{ field: 'card_id', title: '身份证号', width: 180 },
{ field: 'seat_name', title: '房屋坐落', width: 180 },
{ field: 'build_name', title: "幢名", width: 180 },
{ field: 'house_name', title: "房名", width: 180 },
{ field: 'current_floor', title: "所在层", width: 180 },
{ field: 'build_area', title: "建筑面积", width: 180 },
{ field: 'from_name', title: "产权来源", width: 180 }
]],
enableFilter: true
});

1.2. load,reload和loadData

1
2
3
$(“#grid”).datagrid(“load”,{ }); //里面写的是你要传输的参数的键值对,调用这个方法来加载数据的时候,它传给后台的分页信息是从第一页开始的。
$(“#grid”).datagrid(“reload”,{ });//但它传给后台的分布信息是当前的页码,就是实现刷新当前页的功能。
$(“#grid”).datagrid(“loadData”,{ “total”:”30″,rows:[] });//它加载的本地数据,就是不会跟后台什么的有交互,它的使用方式是

1.3. 获取选中行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if ($("#dg_houselist").datagrid("getSelections").length >= 1) {
var houseids = "";
var rows = $("#dg_houselist").datagrid("getSelections");
for (var i = 0; i < rows.length; i++) {
if (rows[i].limit_flag =="0") {
$.messager.alert("警告", rows[i].house_name + "不存在纪监查封");
return false;
}
houseids += rows[i].house_id + ",";
}


}
else {
$.messager.alert("友情提示", "请您选择要添加限制的房屋");
}

2. combobox

2.1. 从后台加载数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$("#comboid").combobox({
url:"/Ashx/ImpownContract.ashx?type=GetOtherMan",
valueField:"code",
textField: "name_c",
onSelect:function(record){
var selectValue = record.value;
}
});

//获取json数据格式
[
{"code":"0001","name_c":"中国工商银行股份有限公司兖州支行"},
{"code":"0002","name_c":"中国农业银行股份有限公司兖州市支行"},
{"code":"0003","name_c":"中国建设银行股份有限公司兖州支行"},
{"code":"0004","name_c":"中国银行股份有限公司兖州支行"},
{"code":"0005","name_c":"中国建设银行股份有限公司济宁分行"},
{"code":"0006","name_c":"山东圣泰农村合作银行草桥口支行"},
]

2.2. 常用方法

1
2
3
4
$("#xx").combobox({disabled: true});      //设置下拉款为禁用
$("#xx").combobox('setValue',xlid); //设置下拉款的默认值 xlid是你下拉款的id属性
$("#xx").combobox('getValue'); //获取下拉款id值
$("#xx").combobox('getText'); //获取下拉款name值

3. 判断元素是否隐藏

1
2
var isHaveHouse =  $("#HouseDiv").is(":hidden");//是否隐藏
var temp1=$("#test").is(":visible");//是否可见

4. Parser(解析器)

解析器是 easy ui 很重要的基础组件,在 easy ui 中我们可以简单的通过 class 定义一个组件,从而渲染出很好的交互效果,就是通过 parser 进行解析的。

parser 会获取全部在指定内定为 easy ui 组件的 class 定义,而且根据后缀定义把当前节点解析渲染成特定组件。

1
2
3
$.parser.parse();//不带参数,默认解析该页面中全部定义为 easyui 组件的节点
$.parser.onComplete();//在解析器完成解析操作的时候触发。
$.parser.parse('#cc');//带一个jquery 选择器,使用这样的方式能够单独解析局部 easyui 组件节点

5. checkbox

5.1. 获取元素下所有checkbox被选中的元素

1
2
3
4
var systemCodes = [];
$("#Flags input[type='checkbox']:checked").each(function(index, ele) {
systemCodes.push(ele.value);
});

5.2. 将指定value值的checkobx选中

1
2
3
4
5
6
7
8
if (res.Data != null) {
$("#Flags input:checkbox").each(function (index, ele) {
var value = ele.value;
if (res.Data.indexOf(value) >= 0) {
$(this).attr("checked", 'true');
}
});
}

razor语法

Razor标识符与任务域

@字符被定义为Razor服务器代码块的标识符,后面的表示的是服务器代码。
{}表示Razor的作用域

1
2
3
@{string userName= "razor test";}
<span>@userName</span>
<span>@DateTime.Now.ToString("yyyy-MM-hh")</span>

Razor注释

1
2
3
4
5
6
@{
@*
多行注释
*@
var i = 10; @* 单行注释 *@
}

Razor类型转换

AsInt(), IsInt()
 AsBool(),IsBool()
AsFloat(),IsFloat()
 AsDecimal(),IsDecimal()
 AsDateTime(),IsDateTime()
 ToString()

1
2
3
4
@{
var i = “10”;
}
<p> i = @i.AsInt() </p> <!-- 输出 i = 10 -->

布局Layout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
@RenderBody()

@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
  • @RenderBody
  • @Scripts.Render
  • @RenderSection

项目总结

1. 远程数据采集系统

1.1. 需求

  • 数据采集
  • 实时监控
  • 数据查询

1.2. 难点

数据监控的实时性
采集数据频率高,导致查询数据量大

2. 污水处理厂数据采集系统

2.1. 需求

  • 七个现场数据采集
  • 现场数据实时监控、预警并短信通知相关人员
  • 数据查询

2.2. 难点

数据监控的实时性
采集数据频率高,导致查询数据量大

3. 变压器厂绕线管理系统

4. 国际化

5. 机床厂管理系统

6. 冷链物流温湿度监测

7. 电厂数据接口

任务调配系统

数据采集系统

8. CAD二次开发

菜单改造

9. 维修资金

技术

  • ORM
  • WCF
  • MVC
  • AutoMapper
  • AutoFact

三方联网

10.房产交易综合管理平台

Session

在计算机专业术语中,Session 是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间,如果需要的话,可能还有一定的操作空间。
一个Session的概念需要包括特定的客户端,特定的服务器端以及不间断的操作时间。

Session 的工作原理

  • 当一个 Session 第一次被启用时,一个唯一的标识被存储于本地的 cookie 中。
  • 首先使用 session_start() 函数,PHP 从 session 仓库中加载已经存储的 session 变量
  • 当执行 PHP 脚本时,通过 session_register() 函数注册 session 变量。
  • 当 PHP 脚本执行结束时,未被销毁的 session 变量会被自动保存在本地一定路径下的 session 库中,这个路径可以通过 php.ini 文件中的 session.save_path 指定,下次浏览网页时可以加载使用。

单点登陆

单点登陆,(single sign on),简称SSO,是目前比较流行的企业业务整合解决方案之一。SSO的定义是在多个应用体系中,用户只需要登陆一次就可以访问所有相互信任的应用系统。

技术实现机制:

当用户第一次访问应用系统的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行校验,检查ticket的合法性。如果通过校验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。
要实现SSO,需要以下主要的功能:
所有应用系统共享一个身份认证系统。
  统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。
所有应用系统能够识别和提取ticket信息
  要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。
技术实现机制

技术

  • 三层架构
  • sql
  • EasyUI
  • Jquery
  • HighChart

完成的工作

合同管理模块

资金托管

楼盘管理

统计平台

GitHub博客部署

这是我的第一篇博客,我把它献给了提供这个博客的平台,记录一下在GitHub上如何部署自己的博客。
用到的工具:

  • Nodejs
    包含npm
  • Git
    这个不多说,是必需的
  • Hexo
    一个静态博客框架,只需要几条命令就可以快速创建自己的博客。

系统环境
Windows7 64bit
软件版本
NodeJs
Git 2.15.0.windows.1
Hexo 3.4.4

1. 工具的安装

1.1. NodeJs安装

在官网下载最新的安装包,按引导一步步安装。

1.2. Git安装

按引导至安装完成。

1.3. Hexo安装及配置

1.3.1. Hexo安装

打开命令行,找到刚才NodeJs的安装目录,输入如下指令

1
npm install hexo-cli -g

install hexo

1.3.2. Hexo初始化配置

  1. 配置博客目录
    在命令行中进入你要放置博客的路径,执行如下命令,会创建一个Blog的文件夹,并时行一些组件的安装。

    1
    hexo init blog

    init blog
    安装完成如下图所示
    init blog finish
    此时执行

    1
    hexo server

    hexo server

1.4. 发布到github

1.4.1. 注册github

注册过程不多说,注册完成后,按照如下页面所示设置GitHub Pages https://pages.github.com/

1.4.2. SSH key配置

1
$ cd ~/. ssh #检查本机已存在的ssh密钥

如果提示:No such file or directory 说明你是第一次使用git。

1
ssh-keygen -t rsa -C "邮件地址"

然后连续3次回车,最终会生成一个文件在用户目录下,打开用户目录,找到.ssh\id_rsa.pub文件,记事本打开并复制里面的内容,打开你的github主页,进入个人设置 -> SSH and GPG keys -> New SSH key:
add ssh key
然后在git bash中配置

1
2
$ git config --global user.name "liuxianan"// 你的github用户名,非昵称
$ git config --global user.email "xxx@qq.com"// 填写你的github注册邮箱

1.4.3. 上传插件安装

1
npm install hexo-deployer-git –save

install deployer
然后在你博客的目录下找到_config.yml配置deploy部分
deploy set

工具都安装完成后,就可以写博客了

1.5. hexo常用命令

1
2
3
4
5
6
7
hexo new "postName" #新建文章
hexo new page "pageName" #新建页面
hexo generate #生成静态页面至public目录
hexo server #开启预览访问端口(默认端口4000,'ctrl + c'关闭server)
hexo deploy #部署到GitHub
hexo help # 查看帮助
hexo version #查看Hexo的版本