这个帮助类,目前我们只用到了两个,我就先更新这两个,后面有用到的,我会继续更新这个Helper帮助类

在Tools.cs中 有很多方法 跟Utils里是重复的,而且Utils里的方法更加新一点,大家可以删除Tools.cs里重复的,我只是删除了部分重复的。

RegexHelper

 using System.Text.RegularExpressions;

 namespace Common
{
/// <summary>
/// 操作正则表达式的公共类
/// </summary>
public class RegexHelper
{
#region 验证输入字符串是否与模式字符串匹配
/// <summary>
/// 验证输入字符串是否与模式字符串匹配,匹配返回true
/// </summary>
/// <param name="input">输入字符串</param>
/// <param name="pattern">模式字符串</param>
public static bool IsMatch(string input, string pattern)
{
return IsMatch(input, pattern, RegexOptions.IgnoreCase);
} /// <summary>
/// 验证输入字符串是否与模式字符串匹配,匹配返回true
/// </summary>
/// <param name="input">输入的字符串</param>
/// <param name="pattern">模式字符串</param>
/// <param name="options">筛选条件</param>
public static bool IsMatch(string input, string pattern, RegexOptions options)
{
return Regex.IsMatch(input, pattern, options);
}
#endregion
}
}

Tools

 using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel; namespace Common
{
/// <summary>
/// 功能描述:共用工具类
/// </summary>
public static class Tools
{ #region 得到字符串长度,一个汉字长度为2
/// <summary>
/// 得到字符串长度,一个汉字长度为2
/// </summary>
/// <param name="inputString">参数字符串</param>
/// <returns></returns>
public static int StrLength(string inputString)
{
System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding();
int tempLen = ;
byte[] s = ascii.GetBytes(inputString);
for (int i = ; i < s.Length; i++)
{
if ((int)s[i] == )
tempLen += ;
else
tempLen += ;
}
return tempLen;
}
#endregion #region 截取指定长度字符串
/// <summary>
/// 截取指定长度字符串
/// </summary>
/// <param name="inputString">要处理的字符串</param>
/// <param name="len">指定长度</param>
/// <returns>返回处理后的字符串</returns>
public static string ClipString(string inputString, int len)
{
bool isShowFix = false;
if (len % == )
{
isShowFix = true;
len--;
}
System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding();
int tempLen = ;
string tempString = "";
byte[] s = ascii.GetBytes(inputString);
for (int i = ; i < s.Length; i++)
{
if ((int)s[i] == )
tempLen += ;
else
tempLen += ; try
{
tempString += inputString.Substring(i, );
}
catch
{
break;
} if (tempLen > len)
break;
} byte[] mybyte = System.Text.Encoding.Default.GetBytes(inputString);
if (isShowFix && mybyte.Length > len)
tempString += "…";
return tempString;
}
#endregion #region 获得两个日期的间隔
/// <summary>
/// 获得两个日期的间隔
/// </summary>
/// <param name="DateTime1">日期一。</param>
/// <param name="DateTime2">日期二。</param>
/// <returns>日期间隔TimeSpan。</returns>
public static TimeSpan DateDiff(DateTime DateTime1, DateTime DateTime2)
{
TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
TimeSpan ts = ts1.Subtract(ts2).Duration();
return ts;
}
#endregion #region 格式化日期时间
/// <summary>
/// 格式化日期时间
/// </summary>
/// <param name="dateTime1">日期时间</param>
/// <param name="dateMode">显示模式</param>
/// <returns>0-9种模式的日期</returns>
public static string FormatDate(DateTime dateTime1, string dateMode)
{
switch (dateMode)
{
case "":
return dateTime1.ToString("yyyy-MM-dd");
case "":
return dateTime1.ToString("yyyy-MM-dd HH:mm:ss");
case "":
return dateTime1.ToString("yyyy/MM/dd");
case "":
return dateTime1.ToString("yyyy年MM月dd日");
case "":
return dateTime1.ToString("MM-dd");
case "":
return dateTime1.ToString("MM/dd");
case "":
return dateTime1.ToString("MM月dd日");
case "":
return dateTime1.ToString("yyyy-MM");
case "":
return dateTime1.ToString("yyyy/MM");
case "":
return dateTime1.ToString("yyyy年MM月");
default:
return dateTime1.ToString();
}
}
#endregion #region 得到随机日期
/// <summary>
/// 得到随机日期
/// </summary>
/// <param name="time1">起始日期</param>
/// <param name="time2">结束日期</param>
/// <returns>间隔日期之间的 随机日期</returns>
public static DateTime GetRandomTime(DateTime time1, DateTime time2)
{
Random random = new Random();
DateTime minTime = new DateTime();
DateTime maxTime = new DateTime(); System.TimeSpan ts = new System.TimeSpan(time1.Ticks - time2.Ticks); // 获取两个时间相隔的秒数
double dTotalSecontds = ts.TotalSeconds;
int iTotalSecontds = ; if (dTotalSecontds > System.Int32.MaxValue)
{
iTotalSecontds = System.Int32.MaxValue;
}
else if (dTotalSecontds < System.Int32.MinValue)
{
iTotalSecontds = System.Int32.MinValue;
}
else
{
iTotalSecontds = (int)dTotalSecontds;
} if (iTotalSecontds > )
{
minTime = time2;
maxTime = time1;
}
else if (iTotalSecontds < )
{
minTime = time1;
maxTime = time2;
}
else
{
return time1;
} int maxValue = iTotalSecontds; if (iTotalSecontds <= System.Int32.MinValue)
maxValue = System.Int32.MinValue + ; int i = random.Next(System.Math.Abs(maxValue)); return minTime.AddSeconds(i);
}
/// <summary>
/// 获取时间戳
/// </summary>
public static string GetRandomTimeSpan()
{
TimeSpan ts = DateTime.Now - new DateTime(, , , , , , );
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
#endregion #region HTML转行成TEXT
/// <summary>
/// HTML转行成TEXT
/// </summary>
/// <param name="strHtml"></param>
/// <returns></returns>
public static string HtmlToTxt(string strHtml)
{
string[] aryReg ={
@"<script[^>]*?>.*?</script>",
@"<(\/\s*)?!?((\w+:)?\w+)(\w+(\s*=?\s*(([""'])(\\[""'tbnr]|[^\7])*?\7|\w+)|.{0})|\s)*?(\/\s*)?>",
@"([\r\n])[\s]+",
@"&(quot|#34);",
@"&(amp|#38);",
@"&(lt|#60);",
@"&(gt|#62);",
@"&(nbsp|#160);",
@"&(iexcl|#161);",
@"&(cent|#162);",
@"&(pound|#163);",
@"&(copy|#169);",
@"&#(\d+);",
@"-->",
@"<!--.*\n"
}; string newReg = aryReg[];
string strOutput = strHtml;
for (int i = ; i < aryReg.Length; i++)
{
Regex regex = new Regex(aryReg[i], RegexOptions.IgnoreCase);
strOutput = regex.Replace(strOutput, string.Empty);
} strOutput.Replace("<", "");
strOutput.Replace(">", "");
strOutput.Replace("\r\n", ""); return strOutput;
}
#endregion #region 判断对象是否为空
/// <summary>
/// 判断对象是否为空,为空返回true
/// </summary>
/// <typeparam name="T">要验证的对象的类型</typeparam>
/// <param name="data">要验证的对象</param>
public static bool IsNullOrEmpty<T>(this T data)
{
//如果为null
if (data == null)
{
return true;
} //如果为""
if (data.GetType() == typeof(String))
{
if (string.IsNullOrEmpty(data.ToString().Trim()) || data.ToString() == "")
{
return true;
}
} //如果为DBNull
if (data.GetType() == typeof(DBNull))
{
return true;
} //不为空
return false;
} /// <summary>
/// 判断对象是否为空,为空返回true
/// </summary>
/// <param name="data">要验证的对象</param>
public static bool IsNullOrEmpty(this object data)
{
//如果为null
if (data == null)
{
return true;
} //如果为""
if (data.GetType() == typeof(String))
{
if (string.IsNullOrEmpty(data.ToString().Trim()))
{
return true;
}
} //如果为DBNull
if (data.GetType() == typeof(DBNull))
{
return true;
} //不为空
return false;
}
#endregion #region 验证是否为浮点数
/// <summary>
/// 验证是否浮点数
/// </summary>
/// <param name="floatNum"></param>
/// <returns></returns>
public static bool IsFloat(this string floatNum)
{
//如果为空,认为验证不合格
if (IsNullOrEmpty(floatNum))
{
return false;
}
//清除要验证字符串中的空格
floatNum = floatNum.Trim(); //模式字符串
string pattern = @"^(-?\d+)(\.\d+)?$"; //验证
return RegexHelper.IsMatch(floatNum, pattern);
}
#endregion #region 验证是否为整数
/// <summary>
/// 验证是否为整数 如果为空,认为验证不合格 返回false
/// </summary>
/// <param name="number">要验证的整数</param>
public static bool IsInt(this string number)
{
//如果为空,认为验证不合格
if (IsNullOrEmpty(number))
{
return false;
} //清除要验证字符串中的空格
number = number.Trim(); //模式字符串
string pattern = @"^[0-9]+[0-9]*$"; //验证
return RegexHelper.IsMatch(number, pattern);
}
#endregion #region 验证是否为数字
/// <summary>
/// 验证是否为数字
/// </summary>
/// <param name="number">要验证的数字</param>
public static bool IsNumber(this string number)
{
//如果为空,认为验证不合格
if (IsNullOrEmpty(number))
{
return false;
} //清除要验证字符串中的空格
number = number.Trim(); //模式字符串
string pattern = @"^[0-9]+[0-9]*[.]?[0-9]*$"; //验证
return RegexHelper.IsMatch(number, pattern);
}
#endregion #region 验证日期是否合法
/// <summary>
/// 是否是日期
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public static bool IsDate(this object date)
{ //如果为空,认为验证合格
if (IsNullOrEmpty(date))
{
return false;
}
string strdate = date.ToString();
try
{
//用转换测试是否为规则的日期字符
date = Convert.ToDateTime(date).ToString("d");
return true;
}
catch
{
//如果日期字符串中存在非数字,则返回false
if (!IsInt(strdate))
{
return false;
} #region 对纯数字进行解析
//对8位纯数字进行解析
if (strdate.Length == )
{
//获取年月日
string year = strdate.Substring(, );
string month = strdate.Substring(, );
string day = strdate.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
}
if (Convert.ToInt32(month) > || Convert.ToInt32(day) > )
{
return false;
} //拼接日期
date = Convert.ToDateTime(year + "-" + month + "-" + day).ToString("d");
return true;
} //对6位纯数字进行解析
if (strdate.Length == )
{
//获取年月
string year = strdate.Substring(, );
string month = strdate.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
}
if (Convert.ToInt32(month) > )
{
return false;
} //拼接日期
date = Convert.ToDateTime(year + "-" + month).ToString("d");
return true;
} //对5位纯数字进行解析
if (strdate.Length == )
{
//获取年月
string year = strdate.Substring(, );
string month = strdate.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
} //拼接日期
date = year + "-" + month;
return true;
} //对4位纯数字进行解析
if (strdate.Length == )
{
//获取年
string year = strdate.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
} //拼接日期
date = Convert.ToDateTime(year).ToString("d");
return true;
}
#endregion return false;
} }
/// <summary>
/// 验证日期是否合法,对不规则的作了简单处理
/// </summary>
/// <param name="date">日期</param>
public static bool IsDate(ref string date)
{
//如果为空,认为验证合格
if (IsNullOrEmpty(date))
{
return true;
} //清除要验证字符串中的空格
date = date.Trim(); //替换\
date = date.Replace(@"\", "-");
//替换/
date = date.Replace(@"/", "-"); //如果查找到汉字"今",则认为是当前日期
if (date.IndexOf("今") != -)
{
date = DateTime.Now.ToString();
} try
{
//用转换测试是否为规则的日期字符
date = Convert.ToDateTime(date).ToString("d");
return true;
}
catch
{
//如果日期字符串中存在非数字,则返回false
if (!IsInt(date))
{
return false;
} #region 对纯数字进行解析
//对8位纯数字进行解析
if (date.Length == )
{
//获取年月日
string year = date.Substring(, );
string month = date.Substring(, );
string day = date.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
}
if (Convert.ToInt32(month) > || Convert.ToInt32(day) > )
{
return false;
} //拼接日期
date = Convert.ToDateTime(year + "-" + month + "-" + day).ToString("d");
return true;
} //对6位纯数字进行解析
if (date.Length == )
{
//获取年月
string year = date.Substring(, );
string month = date.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
}
if (Convert.ToInt32(month) > )
{
return false;
} //拼接日期
date = Convert.ToDateTime(year + "-" + month).ToString("d");
return true;
} //对5位纯数字进行解析
if (date.Length == )
{
//获取年月
string year = date.Substring(, );
string month = date.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
} //拼接日期
date = year + "-" + month;
return true;
} //对4位纯数字进行解析
if (date.Length == )
{
//获取年
string year = date.Substring(, ); //验证合法性
if (Convert.ToInt32(year) < || Convert.ToInt32(year) > )
{
return false;
} //拼接日期
date = Convert.ToDateTime(year).ToString("d");
return true;
}
#endregion return false;
}
}
#endregion /// <summary>
/// //前台显示邮箱的掩码替换(由tzh@qq.com等替换成t*****@qq.com)
/// </summary>
/// <param name="Email">邮箱</param>
/// <returns></returns>
public static string GetEmail(string Email)
{ string strArg = "";
string SendEmail = "";
Match match = Regex.Match(Email, @"(\w)\w+@"); if (match.Success)
{
strArg = match.Groups[].Value + "*****@";
SendEmail = Regex.Replace(Email, @"\w+@", strArg);
}
else
SendEmail = Email;
return SendEmail;
} /// <summary>
/// 检查字符串是否存在与一个,组合到一起的字符串数组中
/// </summary>
/// <param name="strSplit">未分割的字符串</param>
/// <param name="split">分割符号</param>
/// <param name="targetValue">目标字符串</param>
/// <returns></returns>
public static bool CheckStringHasValue(string strSplit, char split, string targetValue)
{
string[] strList = strSplit.Split(split);
foreach (string str in strList)
{
if (targetValue == str)
return true;
}
return false;
} #region 枚举型相关操作 /// <summary>
/// 功能描述;获取枚举名称.传入枚举类型和枚举值
/// </summary>
/// <param name="enumType"></param>
/// <param name="intEnumValue"></param>
/// <returns></returns>
public static string GetEnumText<T>(int intEnumValue)
{
return Enum.GetName(typeof(T), intEnumValue);
} /// <summary>
/// 功能描述:获取枚举项集合,传入枚举类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IList<object> BindEnums<T>()
{
IList<object> _list = new List<object>();
//遍历枚举集合
foreach (int i in Enum.GetValues(typeof(T)))
{
var _selItem = new
{
Value = i,
Text = Enum.GetName(typeof(T), i)
};
_list.Add(_selItem);
}
return _list;
} ///<summary>
/// 返回 Dic 枚举项,描述
///</summary>
///<param name="enumType"></param>
///<returns>Dic枚举项,描述</returns>
public static Dictionary<string, string> BindEnums(Type enumType)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
FieldInfo[] fieldinfos = enumType.GetFields();
foreach (FieldInfo field in fieldinfos)
{
if (field.FieldType.IsEnum)
{
Object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false); dic.Add(field.Name, ((DescriptionAttribute)objs[]).Description);
} } return dic;
}
///<summary>
/// 返回 List《Enums.EnumsClass》 枚举值、名称、描述
///</summary>
public static List<Enums.EnumsClass> BindEnumsList(Type enumType)
{
var list = new List<Enums.EnumsClass>();
FieldInfo[] fieldinfos = enumType.GetFields();
var enumvalue = Enum.GetValues(enumType);
foreach (FieldInfo field in fieldinfos)
{
if (field.FieldType.IsEnum)
{
int ev = -;
Object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
foreach (int item in enumvalue)
{
if (Enum.GetName(enumType, item) == field.Name)
{
ev = item;
break;
}
}
list.Add(new Enums.EnumsClass
{
Name = field.Name,
Value = ev,
Text = ((DescriptionAttribute)objs[]).Description
});
}
}
return list;
} #endregion #region 获取集合中某个字段的拼接,例:获取姓名拼接 /// <summary>
/// 功能描述:获取集合中某个字段的拼接,例:获取姓名拼接
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">集合</param>
/// <param name="strFieldName">字段名</param>
/// <param name="strSplit">分隔符</param>
/// <returns></returns>
public static string GetFieldValueJoin<T>(IList<T> list, string strFieldName, string strSplit)
{
//判断入口
if (list == null || list.Count <= || string.IsNullOrEmpty(strFieldName))
return string.Empty; //获取属性
PropertyInfo _pro = typeof(T).GetProperty(strFieldName);
if (_pro == null)
return string.Empty;
//变量,记录返回值
string _strReturn = string.Empty;
foreach (T _entityI in list)
{
//获取属性值
object _objValue = _pro.GetValue(_entityI, null);
if (_objValue == null || string.IsNullOrEmpty(_objValue.ToString()))
//没有属性值,则跳过
continue; //有属性值,则拼接
_strReturn += _objValue.ToString() + strSplit;
} if (string.IsNullOrEmpty(_strReturn))
return string.Empty; return _strReturn.Substring(, _strReturn.Length - strSplit.Length);
} #endregion }
}

原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com

【C#公共帮助类】 ToolsHelper帮助类的更多相关文章

  1. 【转】C#类的分类(静态类、实例类、嵌套类、结构、简单的抽象类、简单的密封类)

    静态类 -------------------------------------------------------------------------------- 静态类就是在class关键字前 ...

  2. java内部类、接口、集合框架、泛型、工具类、实现类

    .t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.内部类 1.成员内部类. (1)成员内部类的实例化: 外部类名.内部类 ...

  3. python之继承、抽象类、新式类和经典类

    一.上节补充1.静态属性静态属性 : 类的属性,所有的对象共享这个变量 如果用对象名去修改类的静态属性:在对象的空间中又创建了一个属性,而不能修改类中属性的值 操作静态属性应该用类名来操作 例1:请你 ...

  4. UML类图与类间六种关系表示

    UML类图与类间六种关系表示 1.类与类图 类封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性,操作,关系的对象集合的总称. 类图是使用频率最高的UML图之一. 类图用于描述系统中所包含的 ...

  5. c++——派生类和基类转换(类型兼容性原则)

    基类也叫父类,派生类也叫子类. 类之间的继承关系继承关系是类之间的父子关系. 继承关系的特点如下:A. 子类拥有父类的所有属性和行为B. 子类也是一种特殊的父类C. 子类对象可以当父类对象使用D. 子 ...

  6. C++——类继承以及类初始化顺序

    对于类以及类继承, 几个主要的问题:1) 继承方式: public/protected/private继承. 这是c++搞的, 实际上继承方式是一种允许子类控制的思想. 子类通过public继承, 可 ...

  7. 适用于app.config与web.config的ConfigUtil读写工具类 基于MongoDb官方C#驱动封装MongoDbCsharpHelper类(CRUD类) 基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD) C# 实现AOP 的几种常见方式

    适用于app.config与web.config的ConfigUtil读写工具类   之前文章:<两种读写配置文件的方案(app.config与web.config通用)>,现在重新整理一 ...

  8. C++派生类与基类的关系

    派生类与基类有这些关系: 1.公有派生类从基类继承所有成员和成员函数 2.公有派生类无法直接访问从基类继承的私有成员,但可以通过继承的公共接口访问. 3.公有派生类无法继承基类的友元函数. 4.基类先 ...

  9. Java实验项目三——编程实现Person类,学生类的设计及其继承关系

    Program: 编程实现Person类,学生类的设计及其继承关系 代码如下: 定义抽象类Person 1 /* 2 * Description:建立抽象类 3 * 4 * Written By:Ca ...

  10. JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

随机推荐

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. 用scikit-learn进行LDA降维

    在线性判别分析LDA原理总结中,我们对LDA降维的原理做了总结,这里我们就对scikit-learn中LDA的降维使用做一个总结. 1. 对scikit-learn中LDA类概述 在scikit-le ...

  3. 细说WebSocket - Node篇

    在上一篇提高到了 web 通信的各种方式,包括 轮询.长连接 以及各种 HTML5 中提到的手段.本文将详细描述 WebSocket协议 在 web通讯 中的实现. 一.WebSocket 协议 1. ...

  4. mysql学习之 sql语句的技巧及优化

    一.sql中使用正则表达式 select name,email from user where email Regexp "@163[.,]com$"; sql语句中使用Regex ...

  5. VisualStudio2013 如何打开之前版本开发的(.vdproj )安装项目

    当你的项目使用早于 visualstudio2013 的版本开发并且使用 Visual Studio Installer 制作安装项目时,在升级至 VS2013 后会发现新安装项目无法打开, VS20 ...

  6. 前端学HTTP之重定向和负载均衡

    前面的话 HTTP并不是独自运行在网上的.很多协议都会在HTTP报文的传输过程中对其数据进行管理.HTTP只关心旅程的端点(发送者和接收者),但在包含有镜像服务器.Web代理和缓存的网络世界中,HTT ...

  7. C#如何在PDF文件添加图片印章

    文档中添加印章可以起一定的作用,比如,防止文件随意被使用,或者确保文档内容的安全性和权威性.C#添加图片印章其实也有很多实现方法,这里我使用的是免费的第三方软件Free Spire.PDF,向大家阐述 ...

  8. ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案

    好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下: 出现乱码的原因: ...

  9. CSS3新特性应用之结构与布局

    一.自适应内部元素 利用width的新特性min-content实现 width新特性值介绍: fill-available,自动填充盒子模型中剩余的宽度,包含margin.padding.borde ...

  10. HTML5 程序设计 - 使用HTML5 Canvas API

    请你跟着本篇示例代码实现每个示例,30分钟后,你会高喊:“HTML5 Canvas?!在哥面前,那都不是事儿!” 呵呵.不要被滚动条吓到,很多都是代码和图片.我没有分开写,不过上面给大家提供了目录,方 ...