肝了好久,本男神终于把C#期末大作业搞完了!!!!!
目录
6.1.1 类的功能:实现发送QQ邮箱验证码,注册用户或者找回用户密码时会用到。
一、写在前面
1.1 设计目的
记账就是将生活中的各项经济活动按时间顺序进行记录,用于日后的查询和统计。由于传统手工记账本具有携带不便、不能实时记账、容易遗失、后期查找分析困难等缺点,电子记账越来越受到人们的青睐。将笔记本电脑与记账相结合,不仅可解决传统手工记账的不足,还使记账不受时空限制,且能快速进行信息的查找和统计。
移动互联网时代,随着科技的进步,移动支付几乎取代了现金支付。根据用户的日常需求,开发了一款记账软件,通过简单的操作流程,帮助用户查阅消费记录。
1.2 设计内容
这是一款面向大众的Winform程序,用以提供电子记账服务,使得记账不再受时空限制,主要具有以下几大功能:
- 用户管理:实现了用户注册以及密码修改的功能。
- 记账管理:将收入与支出分别显示出来,记账信息清晰明了,同时进行了账单的统计。
- 主页:显示了用户的个人信息以及记账的所有信息。
- 查询:可以查询某一或某些条件下的所有收支记录。
- 发送邮件:自定义类MailveriCode,实现了随机生成验证码、发送验证码、检验验证码是否正确的功能。
- 用户注销:可以将用户的信息与历史记录彻底删除。
二、设计思路
- 用户登录界面:通过用户名以及密码登录,一个用户名只能对应一个用户,一个邮箱只能注册一个账号。
- 用户注册界面:没有设置默认头像,所以用户需要设置默认的头像才可以注册成功。这里用到了SmtpClien类及自定义类MailveriCode实现发送QQ邮箱验证码,来验证用户的信息。
- 用户注销:将用户的信息与历史记录彻底删除。
- 找回密码界面:用户可以根据自己的邮箱找回密码,同样用到了SmtpClien类提供的方法。
- 主界面:使用多个GroupBox来展示用户信息以及总收入、总支出信息,并对金额进行了统计展示。用户也可以在该界面修改头像、增加账单记录、查询记账信息、删除记账信息。
三、基本功能描述
3.1 基本功能
- 用户管理:可以进行新用户的注册以及老用户修改密码的功能。
- 记账管理:用户登录后可以进行收入或支出的记录。
- 查询与统计:用户可以对账单中已有的账单项目进行查找与删除,也可以增加新的记录,界面中也会显示总账单。
- 发送邮件:利用自定义类MailveriCode在需要时对指定的邮箱发送邮件,获得验证码,并检查用户给出的验证码是否与发送的一致,从而确认用户身份。
- 找回密码:用户可以在登录界面点击“忘记密码”,从而可以根据注册时的邮箱重新设置密码。
- 修改头像:在主界面,用户可以点击头像进行修改。
- 注销用户:用户可以在主界面右上角点击注销用户,从而删除所有数据库的信息以及历史记录。
- 帮助功能:在主界面点击窗体标题框中的“?”即可进入帮助界面,包括如何进行注册等使用说明。
- 设置了验证码的有效时长:通过两个timer控件对用户重新获取验证码和验证码的有效时常进行了设置。
3.2 功能模块图
四、软件设计
4.1 设计步骤
- 根据用户的需求,列出功能清单。
- 界面设计。首次打开程序需要进行用户的注册,并通过带参数的构造函数新建界面,显示该用户的所有信息。
- 数据库设计。使用SQL server数据库,将数据保存在不同的表中,提高了灵活性,增强了用户与数据之间的联系。设计所需数据的类型及名称。
- 设计代码。连接数据库并读取数据库的内容,同时加入界面上各个空间功能的实现代码。
- 设计自定义邮箱验证码类,在用户注册以及找回密码时可以直接调用,也可以随时更改对验证码的需求。
- 新用户的注册。注册成功后,用户的信息会被记录到SQL server数据库当中,系统会自动分配用户的账号。
- 用户修改密码。用户可以通过“忘记密码”选项设置新的密码。
- 记录账目信息。用户首先选择类别收入/支出,系统数据库为提供选项,对于其他类,用户可以在备注中添加信息。
- 提供查询功能。允许用户对历史收入、支出账目进行各种条件的组合查询。在查询时,如果用户没有选择支出或收入按钮,则在支出与收入的DataGridView中都会显示查询的内容。
- 将所有功能模块连接起来,测试整个软件的功能,并不断调试。
4.2 系统开发工具
系统开发平台: Microsoft Visual Studio 2015
系统开发语言:C#
数据库管理软件: Microsoft SQL Server Management Studio 18
软件体系架构:三层架构
4.3 数据库逻辑设计
数据库由RecordInfo、Type、UserInfo三张表组成。
1)RecordInfo表(记账信息表)
2)Type表(收支类型表)
3)UserInfo表(用户信息表)
五、一个无声展示视频~~
在B站:C#开发简易记账本[耶耶记账]_哔哩哔哩_bilibili
视频录得比较着急()有空会继续更新哒~~
六、上代码!!
6.1 自定义类MailveriCode
6.1.1 类的功能:实现发送QQ邮箱验证码,注册用户或者找回用户密码时会用到。
6.1.2 MailveriCode
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KeepAccounts
{
internal class MailveriCode
{
/// <summary>
/// 生成验证码
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
public static string CreateMailCode(int length)
{
char code;
int num;
string mailCode = string.Empty;
Random random = new Random();
//生成指定长度的验证码
//这里的验证码包括大写字母、小写字母以及数字,需求不同可以更改num取余的数字
for (int i = 0; i < length; i++)
{
num = random.Next();
if (num % 3 == 0)
code = (char)('0' + (char)(num % 10));
else if (num % 3 == 1)
code = (char)('A' + (char)(num % 26));
else
code = (char)('a' + (char)(num % 26));
mailCode += code.ToString();
}
return mailCode;
}
/// <summary>
/// 发送验证码
/// </summary>
/// <param name="MyMail"></param>
/// <param name="SendMail"></param>
/// <param name="MailSubject"></param>
/// <param name="MailBody"></param>
/// <param name="AuthorizationCode"></param>
/// <returns></returns>
public static bool SendMail(string MyMail, string SendMail, string MailSubject, string MailBody, string AuthorizationCode)
{
//实例化一个发送邮件类
MailMessage mailMessage = new MailMessage();
//发件人邮箱地址
mailMessage.From = new MailAddress(SendMail);
//收件人邮箱地址
mailMessage.To.Add(new MailAddress(MyMail));
//邮件标题及内容
mailMessage.Subject = MailSubject;
mailMessage.Body = MailBody;
//实例化一个SmtpClien类
SmtpClient client = new SmtpClient();
client.Host = "smtp.qq.com";
client.Port = 587;
//安全加密
client.EnableSsl = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
//验证发件人身份(发件人的邮箱,邮箱的生成授权码)
client.Credentials = new NetworkCredential(SendMail, AuthorizationCode);
try
{
client.Send(mailMessage);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "发送失败!", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
//finally
//{
// MessageBox.Show("发送成功!");
//}
return true;
}
/// <summary>
/// 验证QQ邮箱
/// </summary>
/// <param name="mail"></param>
/// <returns></returns>
public static bool CheckMail(string mail)
{
string str = @"^[1-9][0-9]{4,}@qq.com$";//注意这里验证的QQ邮箱是只有数字组成的
Regex regex = new Regex(str);
if (regex.IsMatch(mail))
{
return true;
}
return false;
}
}
}
6.2 注册界面
6.2.1 界面展示
6.2.2 代码~
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
namespace KeepAccounts
{
public partial class Register : Form
{
public static string photopath;
public byte[] bytes;//图片流~
string mailveriCode;
int time1 = 60;//控制发送邮件的倒计时为1分钟
int time2 = 60 * 5;//设置验证码的有效时长为5分钟
public Register()
{
InitializeComponent();
}
private void btnGetVeri_Click(object sender, EventArgs e)
{
mailveriCode = MailveriCode.CreateMailCode(6);
//获取收件人邮箱
string mymail = txtMail.Text.Trim();
//发件人邮箱
string sendmail = "**********@qq.com";//这里输入你用来发送邮件的邮箱
//标题
string subject = "耶耶记账邮箱验证码";
//内容
string body = "亲爱的用户:\r\n您正在验证身份,验证码是:" +
mailveriCode + "\r\n5分钟内有效,为了您的帐号安全,请勿泄露给他人。如果该验证码不为您本人申请,请无视。" +
"\r\n帐号服务由耶耶记账提供。";
//邮箱授权码
string authorizationCode = "iyctjhwtfufabagf";//!!需要自己在QQ邮箱的官网来找,教程之后可以出一个(画大饼ing
//判断邮箱是否正确,同时发送验证码
if (string.IsNullOrEmpty(mymail))
{
MessageBox.Show("邮箱不能为空,请输入邮箱。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtMail.Focus();
}
else if (MailveriCode.CheckMail(mymail) == false)
{
MessageBox.Show("输入的邮箱格式有误,请重新输入!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtMail.Focus();
}
else
{
if (MailveriCode.SendMail(mymail, sendmail, subject, body, authorizationCode) == true)
{
btnGetVeri.Enabled = false;
timer1.Interval = 1000;
timer1.Start();
timer2.Interval = 1000;
timer2.Start();
}
else
{
txtMailVeri.Focus();
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (time1 > 0)
{
time1--;
btnGetVeri.Text = "重新发送" + time1.ToString() + "s";
}
else
{
timer1.Stop();
btnGetVeri.Text = "重新获取验证码";
btnGetVeri.Enabled = true;
}
}
private void timer2_Tick(object sender, EventArgs e)
{
if (time2 == 0)
{
timer2.Stop();
mailveriCode = MailveriCode.CreateMailCode(6);
}
}
private void btnRegister_Click(object sender, EventArgs e)
{
if (txtName.Text.Trim() != "" && txtPsw.Text.Trim() != "")
{
string username = txtName.Text.Trim();
string usermail = txtMail.Text.Trim();
string vericode = txtMailVeri.Text.Trim();
string userpsw = txtPsw.Text.Trim();
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";//设置数据源服务器
scsb.UserID = "sa";//用户名
scsb.Password = "sa";//密码
scsb.InitialCatalog = "KeepAccounts";//要访问的数据库
//创建连接
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
//打开数据库
sqlConnection.Open();
//创建执行的SQL查询语句
string sql1 = "select user_name from UserInfo where user_name = '" + username + "'";
//创建用于执行SQL语句的对象
SqlCommand cmd1 = new SqlCommand(sql1, sqlConnection);//参数1:SQL语句,参数2:已经打开的数据库
//执行SQL语句并接受结果
SqlDataReader reader1 = cmd1.ExecuteReader();
//查找该昵称是否已经被注册
bool existed1 = reader1.HasRows;
reader1.Close();
if (existed1)
{
MessageBox.Show("该昵称已存在,请重新输入!","提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{
string sql2 = "select user_name from UserInfo where user_mail = '" + usermail + "'";
SqlCommand cmd2 = new SqlCommand(sql2, sqlConnection);
SqlDataReader reader2 = cmd2.ExecuteReader();
//查找该昵称是否已经被注册
bool existed2 = reader2.HasRows;
reader2.Close();
if (existed2)
{
MessageBox.Show("该邮箱已注册,请重新输入!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{
if (string.IsNullOrEmpty(vericode) == true)
{
MessageBox.Show("请输入验证码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtMailVeri.Focus();
return;
}
else if (vericode.ToLower() != mailveriCode.ToLower())
{
MessageBox.Show("验证码错误,请重新输入!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
txtMailVeri.Focus();
return;
}
//系统给定id值
string sql3 = "select max(user_id) as maxid from UserInfo";
SqlCommand cmd3 = new SqlCommand(sql3, sqlConnection);
SqlDataReader maxid = cmd3.ExecuteReader();
maxid.Read();
int userid = Convert.ToInt32(maxid["maxid"]) + 1;
maxid.Close();
//向数据库中插入该用户的信息
string sql4 = "insert into UserInfo(user_name,user_id,user_psw,user_mail,user_photo) values ('"
+ username + "'," + userid + ",'" + userpsw + "','" + usermail + "',@userphoto)";
SqlCommand cmd4 = new SqlCommand(sql4, sqlConnection);
SqlParameter sqlParameter = new SqlParameter("@userphoto", SqlDbType.Image);
sqlParameter.Value = bytes;
cmd4.Parameters.Add(sqlParameter);
cmd4.ExecuteNonQuery();
sqlConnection.Close();
MessageBox.Show("注册成功!");
this.Close();
}
}
}
else
{
MessageBox.Show("请将信息填写完整!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
#region 添加头像
private void picPhoto_Click(object sender, EventArgs e)
{
//文件对话框的初始目录为桌面
this.openFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
this.openFileDialog1.Filter = "JPEG(*.jpg;*.jpeg;*.jpe;*.jfif)|*.jpg|GIF(*.gif)|*.gif|PNG(*.png)|*.png|BMP(*.bmp)|*.bmp";
this.openFileDialog1.FilterIndex = 0;
this.openFileDialog1.RestoreDirectory = true;
this.openFileDialog1.Title = "选择头像";
this.openFileDialog1.CheckPathExists = true;
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
photopath = this.openFileDialog1.FileName;
FileStream fs = new FileStream(photopath, FileMode.Open, FileAccess.Read);
bytes = new byte[fs.Length];
fs.Read(bytes, 0, bytes.Length);
picPhoto.Image = Image.FromStream(fs);
picPhoto.BringToFront();
fs.Close();
}
}
#endregion
private void ckbSee_CheckedChanged(object sender, EventArgs e)
{
if (ckbSee.Checked)
{
txtPsw.PasswordChar = new char();
}
else
{
txtPsw.PasswordChar = '*';
}
}
private void txtPsw_TextChanged(object sender, EventArgs e)
{
txtPsw.PasswordChar = '*';
}
}
}
6.3 登陆界面
6.3.1 界面展示
6.3.2 代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KeepAccounts
{
public partial class frmLogin : Form
{
public frmLogin()
{
InitializeComponent();
//string strpath = Application.StartupPath + "yeyeKeepAccounts.chm";
//这里是在加入帮助文档,没有的把这段注释掉就好
string strpath = Application.StartupPath.Substring(0, Application.StartupPath.Substring(0, Application.StartupPath.LastIndexOf("\\")).LastIndexOf("\\"));
strpath += @"\yeyeKeepAccounts.chm";
HelpProvider1.HelpNamespace = strpath;
}
private void frmLogin_Load(object sender, EventArgs e)
{
CreateVeriCode();//生成随机验证码
}
public string code;//储存生成的验证码
private void CreateVeriCode()
{
code = "";
Random random = new Random();
int num;
char code1;
for(int i = 0; i < 4; i++)
{
num = random.Next();
if (num % 3 == 0)
code1 = (char)('0' + (char)(num % 10));
else if (num % 3 == 1)
code1 = (char)('A' + (char)(num % 26));
else
code1 = (char)('a' + (char)(num % 26));
this.code += code1.ToString();
}
lblVeri.Text = code;
}
#region 登录按钮事件(连接数据库验证用户名和密码)
private void btnLogin_Click(object sender, EventArgs e)
{
string username = txtName.Text.Trim();
string password = txtPsw.Text.Trim();
//声明一个SqlConnectionStringBuilder对象
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";//设置数据源服务器
scsb.UserID = "sa";//用户名
scsb.Password = "sa";//密码
scsb.InitialCatalog = "KeepAccounts";//要访问的数据库
//创建连接
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
//打开数据库
sqlConnection.Open();
//创建执行的SQL查询语句
string sql = "select user_id,user_psw from UserInfo where user_name = '" + username + "'and user_psw = '" + password + "'";
//创建用于执行SQL语句的对象
SqlCommand cmd = new SqlCommand(sql, sqlConnection);//参数1:SQL语句,参数2:已经打开的数据库
//执行SQL语句并接受结果
SqlDataReader reader = cmd.ExecuteReader();
//读取数据
if (reader.HasRows && txtVeri.Text.ToLower() == code.ToLower())
{
new MainBook(username).Show();
this.Hide();
}
else if (reader.HasRows && txtVeri.Text.ToLower() != code.ToLower())
{
MessageBox.Show("验证码错误", "提示");
CreateVeriCode();
return;
}
else
{
MessageBox.Show("用户名或密码错误", "提示");
CreateVeriCode();
return;
}
reader.Close();
sqlConnection.Close();
}
#endregion
#region 注册界面
#endregion
private void btnRegister_Click(object sender, EventArgs e)
{
new Register().Show();
}
#region 单击验证码标签刷新验证码
private void lblVeri_Click(object sender, EventArgs e)
{
CreateVeriCode();
}
#endregion
private void btnForget_Click(object sender, EventArgs e)
{
new frmForget().Show();
}
private void ckbPsw_CheckedChanged(object sender, EventArgs e)
{
if (ckbPsw.Checked)
{
txtPsw.PasswordChar = new char();
}
else
{
txtPsw.PasswordChar = '*';
}
}
private void txtPsw_TextChanged(object sender, EventArgs e)
{
txtPsw.PasswordChar = '*';
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
}
private void frmLogin_HelpButtonClicked(object sender, CancelEventArgs e)
{
//SendKeys.Send("{F1}");
SendKeys.SendWait("{F1}");
}
private void frmLogin_KeyUp(object sender, KeyEventArgs e)
{
}
}
}
6.4 忘记密码界面
6.4.1 界面展示
6.4.2 代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KeepAccounts
{
public partial class frmForget : Form
{
string mailveriCode;
int time1 = 60;//发送时间倒计时
int time2 = 60 * 5;//验证码有效时间
public frmForget()
{
InitializeComponent();
}
private bool MailExist(string mail)
{
//连接数据库
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
sqlConnection.Open();
string sql = "select user_mail from UserInfo where user_mail='" + mail + "'";
SqlCommand cmd = new SqlCommand(sql, sqlConnection);
SqlDataReader reader = cmd.ExecuteReader();
bool exist = reader.Read();
reader.Close();
sqlConnection.Close();
if (exist)
{
return true;
}
else
{
return false;
}
}
//控制timer1
private void timer1_Tick(object sender, EventArgs e)
{
if (time1 > 0)
{
time1--;
btnGetVeri.Text = "重新发送" + time1.ToString() + "s";
}
else
{
timer1.Stop();
btnGetVeri.Text = "重新获取验证码";
btnGetVeri.Enabled = true;
}
}
//控制timer2
private void timer2_Tick(object sender, EventArgs e)
{
if (time2 == 0)
{
timer2.Stop();
mailveriCode = MailveriCode.CreateMailCode(6);
}
}
private void btnGetVeri_Click(object sender, EventArgs e)
{
mailveriCode = MailveriCode.CreateMailCode(6);
//获取收件人邮箱
string mymail = txtMail.Text.Trim();
//发件人邮箱
string sendmail = "1577997510@qq.com";
//标题
string subject = "耶耶记账邮箱验证码";
//内容
string body = "亲爱的用户:\r\n您正在验证身份,验证码是:" +
mailveriCode + "\r\n5分钟内有效,为了您的帐号安全,请勿泄露给他人。如果该验证码不为您本人申请,请无视。" +
"\r\n帐号服务由耶耶记账提供。";
//邮箱授权码
string authorizationCode = "iyctjhwtfufabagf";
//判断邮箱是否正确,同时发送验证码
if (string.IsNullOrEmpty(mymail))
{
MessageBox.Show("邮箱不能为空,请输入邮箱。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtMail.Focus();
}
else if (MailveriCode.CheckMail(mymail) == false)
{
MessageBox.Show("输入的邮箱格式有误,请重新输入!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtMail.Focus();
}
else
{
if (MailveriCode.SendMail(mymail, sendmail, subject, body, authorizationCode) == true)
{
btnGetVeri.Enabled = false;
timer1.Interval = 1000;
timer1.Start();
timer2.Interval = 1000;
timer2.Start();
}
else
{
txtMailVeri.Focus();
}
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
txtPsw.PasswordChar = new char();
}
else
{
txtPsw.PasswordChar = '*';
}
}
private void txtPsw_TextChanged(object sender, EventArgs e)
{
txtPsw.PasswordChar = '*';
}
private void btnFind_Click(object sender, EventArgs e)
{
string userveriCode = txtMailVeri.Text.Trim();
string userpsw = txtPsw.Text.Trim();
if (txtMail.Text.Trim() != "" && txtPsw.Text.Trim() != "")
{
string usermail = txtMail.Text.Trim();
if (!MailExist(usermail))
{
MessageBox.Show("用户还未注册!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(userveriCode) == true)
{
MessageBox.Show("请输入验证码!");
txtMailVeri.Focus();
return;
}
else if (userveriCode.ToLower() != mailveriCode.ToLower())
{
MessageBox.Show("验证码错误,请重新输入!","警告",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
txtMailVeri.Focus();
return;
}
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
sqlConnection.Open();
string updatesql = "update UserInfo set user_psw='" + userpsw + "' where user_mail='" + usermail + "'";
SqlCommand cmd = new SqlCommand(updatesql, sqlConnection);
cmd.ExecuteNonQuery();
if (txtPsw.Text.Trim() == txtPswok.Text.Trim())
{
MessageBox.Show("密码修改成功!");
}
else
{
MessageBox.Show("两次输入密码不同,请确认密码!", "提示");
return;
}
sqlConnection.Close();
this.Close();
}
else if (txtMail.Text.Trim() == "" && txtPsw.Text.Trim() != "")
{
MessageBox.Show("邮箱不能为空", "提示");
txtMail.Focus();
}
else if (txtMail.Text.Trim() != "" && txtPsw.Text.Trim() == "")
{
MessageBox.Show("请输入密码", "提示");
txtPsw.Focus();
}
else
{
MessageBox.Show("请完善相关信息!", "提示");
txtMail.Focus();
}
}
}
}
6.5 主界面
6.5.1 界面展示
6.5.2 代码
这一部分需要注意的是对总账单金额的计算,当时写的时候就改了好多次。查询按钮下的计算实在有点抽象,所以干脆让 label 不可见了…😀😎我真聪明(bushi
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
namespace KeepAccounts
{
public partial class MainBook : Form
{
static string UserName;
static string UserId;
static string UserMail;
static string UserPsw;
private static float inmoney;
private static float outmoney;
private static float totmoney;
public static string photopath;
public byte[] bytes;
public MainBook()
{
InitializeComponent();
}
public MainBook(string username)
{
InitializeComponent();
Init(username);
ShowPerson();
}
public void Init(string username)
{
inmoney = 0;
outmoney = 0;
//声明一个SqlConnectionStringBuilder对象
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";//设置数据源服务器
scsb.UserID = "sa";//用户名
scsb.Password = "sa";//密码
scsb.InitialCatalog = "KeepAccounts";//要访问的数据库
//创建连接
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
//打开数据库
sqlConnection.Open();
//创建执行的SQL查询语句
string sql = "select * from UserInfo where user_name = '" + username + "'";
//创建用于执行SQL语句的对象
SqlCommand cmd = new SqlCommand(sql, sqlConnection);//参数1:SQL语句,参数2:已经打开的数据库
//执行SQL语句并接受结果
SqlDataReader reader = cmd.ExecuteReader();
//读取用户信息并显示
if (reader.Read())
{
UserName = reader["user_name"].ToString();
UserId = reader["user_id"].ToString();
UserMail = reader["user_mail"].ToString();
}
reader.Close();
lblName.Text = UserName;
lblId.Text = UserId;
lblMail.Text = UserMail;
sql = "select user_photo from UserInfo where user_name = '" + username + "'";
cmd = new SqlCommand(sql, sqlConnection);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds,"UserInfo");
int count = ds.Tables["UserInfo"].Rows.Count;
Byte[] bytes = new byte[0];
bytes = (Byte[])(ds.Tables["UserInfo"].Rows[count - 1]["user_photo"]);
MemoryStream ms = new MemoryStream(bytes);
picPhoto.Image = Image.FromStream(ms);
sql = "select * from RecordInfo where user_id = '" + UserId + "'";
cmd = new SqlCommand(sql, sqlConnection);
reader = cmd.ExecuteReader();
while (reader.Read())
{
string inorout = reader["in_out"].ToString().Trim();
float price = (float)Convert.ToDouble(reader["money"]);
if (inorout.Equals("收入"))
{
inmoney = inmoney + price;
lblMoneyIn.Text = Convert.ToString(inmoney);
}
else
{
outmoney = outmoney + price;
lblMoneyOut.Text = Convert.ToString(outmoney);
}
}
totmoney = inmoney - outmoney;
lbltotmoney.Text = Convert.ToString(totmoney);
if(totmoney > 0)
{
lbltottype.Text = "收入";
}
else
{
lbltottype.Text = "支出";
}
}
private void MainBook_Load(object sender, EventArgs e)
{
ShowPerson();
}
public void ShowPerson()
{
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
sqlConnection.Open();
string sql = "select bill_type as 类型,money as 金额, remark as 备注,record_time as 日期 from RecordInfo where in_out = '支出' and user_id = '" + UserId + "'";
SqlCommand cmd = new SqlCommand(sql, sqlConnection);
SqlDataAdapter myadapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
myadapter.Fill(ds, "RecordInfo");
dataGridViewOut.DataSource = ds;
dataGridViewOut.DataMember = "RecordInfo";
sql = "select bill_type as 类型,money as 金额, remark as 备注,record_time as 日期 from RecordInfo where in_out = '收入' and user_id = '" + UserId + "'";
cmd = new SqlCommand(sql, sqlConnection);
myadapter = new SqlDataAdapter(cmd);
ds = new DataSet();
myadapter.Fill(ds, "RecordInfo");
dataGridViewIn.DataSource = ds;
dataGridViewIn.DataMember = "RecordInfo";
int innum = dataGridViewIn.RowCount - 1;
int outnum = dataGridViewOut.RowCount - 1;
lblNumIn.Text = innum.ToString();
lblNumOut.Text = outnum.ToString();
}
string inorout;
string billtype;
private void radioButtonIn_CheckedChanged(object sender, EventArgs e)
{
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
sqlConnection.Open();
string sql = "select * from Type";
SqlCommand cmd = new SqlCommand(sql, sqlConnection);
SqlDataAdapter myadapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
myadapter.Fill(ds,"Type");
comboBox1.DataSource = ds;
comboBox1.DisplayMember = "Type.in_type";
inorout = "收入";
billtype = comboBox1.Text;
//dataGridViewIn.DataSource = ds;
//dataGridViewIn.DataMember = "InType";
}
private void radioButtonOut_CheckedChanged(object sender, EventArgs e)
{
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
sqlConnection.Open();
string sql = "select * from Type";
SqlCommand cmd = new SqlCommand(sql, sqlConnection);
SqlDataAdapter myadapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
myadapter.Fill(ds, "Type");
comboBox1.DataSource = ds;
comboBox1.DisplayMember = "Type.out_type";
inorout = "支出";
billtype = comboBox1.Text;
}
private void btnAdd_Click(object sender, EventArgs e)
{
float price = float.Parse(txtMoney.Text);
string note = txtNote.Text;
string time = dateTimePicker1.Text;
//string time = Convert.ToDateTime(dateTimePicker1.Text).Date.ToString("D");
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
string insertcmd = "insert into RecordInfo(user_id,bill_type,in_out,money,remark,record_time)" +
"values('" + UserId + "','" + comboBox1.Text + "','" + inorout + "','" + price + "','" + note + "','" + Convert.ToDateTime(time) + "')";
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(insertcmd, sqlConnection);
cmd.ExecuteNonQuery();
sqlConnection.Close();
dataGridViewIn.DataMember = "RecordInfo";
dataGridViewOut.DataMember = "RecordInfo";
if (radioButtonIn.Checked)
{
float pricein = (float)Convert.ToDouble(txtMoney.Text);
inmoney = inmoney + pricein;
lblMoneyIn.Text = inmoney.ToString();
}
else if (radioButtonOut.Checked)
{
float priceout = (float)Convert.ToDouble(txtMoney.Text);
outmoney = outmoney + priceout;
lblMoneyOut.Text = outmoney.ToString();
}
totmoney = inmoney - outmoney;
//lbltotmoney.Text = Convert.ToString(totmoney);
if (totmoney > 0)
{
lbltotmoney.Text = Convert.ToString(totmoney);
lbltottype.Text = "收入";
}
else
{
totmoney = -totmoney;
lbltotmoney.Text = Convert.ToString(totmoney);
lbltottype.Text = "支出";
}
ShowPerson();
}
private void btnDeleteOut_Click(object sender, EventArgs e)
{
float price = float.Parse(txtMoney.Text);
string note = txtNote.Text;
string time = dateTimePicker1.Text;
//string time = Convert.ToDateTime(dateTimePicker1.Text).Date.ToString("D");
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
string delcmd = "delete from RecordInfo where user_id='" + UserId +
"'and bill_type='" + comboBox1.Text + "'and money='" + price + "'and remark='" + note
+ "'and record_time='" + Convert.ToDateTime(time) + "'";
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(delcmd, sqlConnection);
cmd.ExecuteNonQuery();
sqlConnection.Close();
dataGridViewIn.DataMember = "RecordInfo";
dataGridViewOut.DataMember = "RecordInfo";
if (radioButtonIn.Checked)
{
float pricein = (float)Convert.ToDouble(txtMoney.Text);
inmoney = inmoney - pricein;
lblMoneyIn.Text = inmoney.ToString();
}
else if (radioButtonOut.Checked)
{
float priceout = (float)Convert.ToDouble(txtMoney.Text);
outmoney = outmoney - priceout;
lblMoneyOut.Text = outmoney.ToString();
}
totmoney = inmoney - outmoney;
//lbltotmoney.Text = Convert.ToString(totmoney);
if (totmoney > 0)
{
lbltotmoney.Text = Convert.ToString(totmoney);
lbltottype.Text = "收入";
}
else
{
totmoney = -totmoney;
lbltotmoney.Text = Convert.ToString(totmoney);
lbltottype.Text = "支出";
}
ShowPerson();
}
private void picPhoto_Click(object sender, EventArgs e)
{
//文件对话框的初始目录为桌面
this.openFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
this.openFileDialog1.Filter = "JPEG(*.jpg;*.jpeg;*.jpe;*.jfif)|*.jpg|GIF(*.gif)|*.gif|PNG(*.png)|*.png|BMP(*.bmp)|*.bmp";
this.openFileDialog1.FilterIndex = 0;
this.openFileDialog1.RestoreDirectory = true;
this.openFileDialog1.Title = "选择头像";
this.openFileDialog1.CheckPathExists = true;
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
photopath = this.openFileDialog1.FileName;
FileStream fs = new FileStream(photopath, FileMode.Open, FileAccess.Read);
bytes = new byte[fs.Length];
fs.Read(bytes, 0, bytes.Length);
picPhoto.Image = Image.FromStream(fs);
picPhoto.BringToFront();
fs.Close();
}
string username = lblName.Text.Trim();
string usermail = lblMail.Text.Trim();
string userid = lblId.Text.Trim();
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
string sql1 = "select * from UserInfo where user_id='" + UserId + "'";
sqlConnection.Open();
SqlCommand cmd1 = new SqlCommand(sql1, sqlConnection);
SqlDataReader reader = cmd1.ExecuteReader();
//读取用户信息并显示
if (reader.Read())
{
UserPsw = reader["user_psw"].ToString();
}
reader.Close();
sqlConnection.Close();
sql1 = "delete from UserInfo where user_id='" + UserId + "'";
sqlConnection.Open();
SqlCommand cmd2 = new SqlCommand(sql1, sqlConnection);
cmd1.ExecuteNonQuery();
sql1 = "insert into UserInfo(user_name,user_id,user_psw,user_mail,user_photo) values ('"
+ username + "'," + userid + ",'" + UserPsw + "','" + usermail + "',@userphoto)";
SqlCommand cmd3 = new SqlCommand(sql1, sqlConnection);
SqlParameter para = new SqlParameter("@userphoto", SqlDbType.Image, bytes.Length);
para.Value = bytes;
cmd3.Parameters.Add(para);
//SqlParameter sqlParameter = new SqlParameter("@userphoto", SqlDbType.Image);
//sqlParameter.Value = bytes;
//cmd3.Parameters.Add(sqlParameter);
cmd3.ExecuteNonQuery();
sqlConnection.Close();
MessageBox.Show("更改头像成功!");
}
private void MainBook_FormClosed(object sender, FormClosedEventArgs e)
{
System.Environment.Exit(0);
}
private void MainBook_Resize(object sender, EventArgs e)
{
}
private void btnCheck_Click(object sender, EventArgs e)
{
label10.Visible = false;
lblMoneyOut.Visible = false;
label8.Visible = false;
lblMoneyIn.Visible = false;
label11.Visible = false;
label13.Visible = false;
lbltotmoney.Visible = false;
lbltottype.Visible = false;
//float price = float.Parse(txtMoney.Text);
string note = txtNote.Text;
string time = dateTimePicker1.Text;
//string time = Convert.ToDateTime(dateTimePicker1.Text).Date.ToString("D");
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
DataSet ds = new DataSet();
string selectcmd = "select * from RecordInfo where record_time='" + Convert.ToDateTime(time) + "' and user_id='" + UserId + "'";
if (comboBox1.Text != "")
{
selectcmd += " and bill_type='" + comboBox1.Text.Trim() + "'";
}
if (txtNote.Text != "")
{
selectcmd += " and remark='" + txtNote.Text.Trim() + "'";
}
if (txtMoney.Text != "")
{
selectcmd += " and money='" + txtMoney.Text.Trim() + "'";
}
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(selectcmd, sqlConnection);
SqlDataAdapter myadapter = new SqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
sqlConnection.Close();
myadapter.Fill(ds, "RecordInfo");
if (radioButtonIn.Checked)
{
dataGridViewIn.DataSource = ds;
dataGridViewIn.DataMember = "RecordInfo";
}
else if(radioButtonOut.Checked)
{
dataGridViewOut.DataSource = ds;
dataGridViewOut.DataMember = "RecordInfo";
}
else
{
dataGridViewIn.DataSource = ds;
dataGridViewIn.DataMember = "RecordInfo";
dataGridViewOut.DataSource = ds;
dataGridViewOut.DataMember = "RecordInfo";
}
int innum = dataGridViewIn.RowCount - 1;
int outnum = dataGridViewOut.RowCount - 1;
lblNumIn.Text = innum.ToString();
lblNumOut.Text = outnum.ToString();
//ShowPerson();
}
private void btnDelUser_Click(object sender, EventArgs e)
{
//float price = float.Parse(txtMoney.Text);
string note = txtNote.Text;
string time = dateTimePicker1.Text;
//string time = Convert.ToDateTime(dateTimePicker1.Text).Date.ToString("D");
//MessageBox.Show("请确定是否注销用户信息并删除所有记录!", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
DialogResult dr = MessageBox.Show("请确定是否注销用户信息并删除所有记录!", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
if (dr==DialogResult.OK)
{
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
scsb.DataSource = "LAPTOP-3RQPGESC";
scsb.UserID = "sa";
scsb.Password = "sa";
scsb.InitialCatalog = "KeepAccounts";
SqlConnection sqlConnection = new SqlConnection(scsb.ToString());
string delcmd = "delete from RecordInfo where user_id='" + UserId + "'";
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(delcmd, sqlConnection);
cmd.ExecuteNonQuery();
string delcmd1 = "delete from UserInfo where user_id='" + UserId + "'";
//sqlConnection.Open();
SqlCommand cmd1 = new SqlCommand(delcmd1, sqlConnection);
cmd1.ExecuteNonQuery();
//sqlConnection.Close();
sqlConnection.Close();
dataGridViewIn.DataMember = "RecordInfo";
dataGridViewOut.DataMember = "RecordInfo";
this.Hide();
new frmLogin().Show();
}
}
}
}
6.6 帮助界面
6.6.1 界面展示
这一块是耗时最长的,而且离交作业的时间越来越近/(ㄒoㄒ)/~~,主要是也没有学过。查资料查了很多,尝试了各种方法(比刚刚计算账单还要抽象),才有了下面这个不是很好看的帮助中心,但是能写出来还是比较开心的(〃 ̄ω ̄〃)
6.6.2 制作方式
我这里是去复制了一整个网页的帮助界面出来,用网页的帮助模板,修改成自己的内容,导出为 .chm 文件,和 vs 里的 HelpProvider 控件关联起来,有了最后的联机帮助的界面。
此处需要将最大化与最小化按钮设置为False,才能看到“?”。
主要代码:
public frmLogin()
{
InitializeComponent();
//string strpath = Application.StartupPath + "yeyeKeepAccounts.chm";
string strpath = Application.StartupPath.Substring(0, Application.StartupPath.Substring(0, Application.StartupPath.LastIndexOf("\\")).LastIndexOf("\\"));
strpath += @"\yeyeKeepAccounts.chm";
HelpProvider1.HelpNamespace = strpath;
}
设置以下属性,单击HelpButton即可弹出帮助界面。
七、总结
7.1 后记
通过前期系统调研与需求分析、设计等一系列工作,将系统主要分为以下几个模块:用户注册与登录、用户找回密码、记录收支、用户查阅收支记录、帮助中心。综上所述,随着移动支付的不断升级,消费习惯也在不断变化,冲动消费、刺激消费这类问题也接踵而至。电子的记账本为用户提供了更加方便的记账方式,能够更加快捷地查找消费记录,适合当前社会的需求。
我学会了:
- 通过软件提供的类来实现发送邮件的功能,从而绑定用户的信息。
- 设计带参数的初始化函数,可以将不同用户的信息分隔开。
- 学会了制作帮助文档,并在登录界面按下enter键相当于按下登录按钮,提高了用户界面友好性。
- 学会了用sql语句将图片插入到数据库中。
- 学会了制作图标icon。
7.2 不足之处
- 在每一个界面都进行了测试,但是没有将异常记录下来,应该将错误积累下来以便于下次遇到相似的问题时比较学习。
- 在连接数据库的过程当中经常会出现SQL语句格式写错的情况,而且有时候发现不了,应该现在SQL server中写入SQL命令保证语句正确,缩短处理异常的时间。
- 对于头像图片的选择还是有尺寸要求的,这块还需要再继续研究一下,目前对于自己使用已经足够了。
OK 本男神的介绍就到这里了,欢迎评论+私信!