基于C#和SQL server数据库的记账本

肝了好久,本男神终于把C#期末大作业搞完了!!!!!

目录

一、写在前面

1.1 设计目的

1.2 设计内容

二、设计思路

三、基本功能描述

3.1 基本功能

3.2 功能模块图

 四、软件设计

4.1 设计步骤

4.2 系统开发工具

4.3 数据库逻辑设计

 五、一个无声展示视频~~

六、上代码!!

6.1 自定义类MailveriCode

6.1.1 类的功能:实现发送QQ邮箱验证码,注册用户或者找回用户密码时会用到。

6.1.2 MailveriCode

6.2 注册界面

6.2.1 界面展示

6.2.2 代码~

6.3 登陆界面

6.3.1 界面展示

​编辑 

6.3.2 代码

6.4 忘记密码界面

6.4.1 界面展示

6.4.2 代码

6.5 主界面

6.5.1 界面展示

6.5.2 代码

6.6 帮助界面

6.6.1 界面展示

6.6.2 制作方式

七、总结

7.1 后记

7.2 不足之处


一、写在前面

1.1 设计目的

记账就是将生活中的各项经济活动按时间顺序进行记录,用于日后的查询和统计。由于传统手工记账本具有携带不便、不能实时记账、容易遗失、后期查找分析困难等缺点,电子记账越来越受到人们的青睐。将笔记本电脑与记账相结合,不仅可解决传统手工记账的不足,还使记账不受时空限制,且能快速进行信息的查找和统计。

移动互联网时代,随着科技的进步,移动支付几乎取代了现金支付。根据用户的日常需求,开发了一款记账软件,通过简单的操作流程,帮助用户查阅消费记录。

1.2 设计内容

这是一款面向大众的Winform程序,用以提供电子记账服务,使得记账不再受时空限制,主要具有以下几大功能:

  1. 用户管理:实现了用户注册以及密码修改的功能。
  2. 记账管理:将收入与支出分别显示出来,记账信息清晰明了,同时进行了账单的统计。
  3. 主页:显示了用户的个人信息以及记账的所有信息。
  4. 查询:可以查询某一或某些条件下的所有收支记录。
  5. 发送邮件:自定义类MailveriCode,实现了随机生成验证码、发送验证码、检验验证码是否正确的功能。
  6. 用户注销:可以将用户的信息与历史记录彻底删除。

二、设计思路

  1. 用户登录界面:通过用户名以及密码登录,一个用户名只能对应一个用户,一个邮箱只能注册一个账号。
  2. 用户注册界面:没有设置默认头像,所以用户需要设置默认的头像才可以注册成功。这里用到了SmtpClien类及自定义类MailveriCode实现发送QQ邮箱验证码,来验证用户的信息。
  3. 用户注销:将用户的信息与历史记录彻底删除。
  4. 找回密码界面:用户可以根据自己的邮箱找回密码,同样用到了SmtpClien类提供的方法。
  5. 主界面:使用多个GroupBox来展示用户信息以及总收入、总支出信息,并对金额进行了统计展示。用户也可以在该界面修改头像、增加账单记录、查询记账信息、删除记账信息。

三、基本功能描述

3.1 基本功能

  1. 用户管理:可以进行新用户的注册以及老用户修改密码的功能。
  2. 记账管理:用户登录后可以进行收入或支出的记录。
  3. 查询与统计:用户可以对账单中已有的账单项目进行查找与删除,也可以增加新的记录,界面中也会显示总账单。
  4. 发送邮件:利用自定义类MailveriCode在需要时对指定的邮箱发送邮件,获得验证码,并检查用户给出的验证码是否与发送的一致,从而确认用户身份。
  5. 找回密码:用户可以在登录界面点击“忘记密码”,从而可以根据注册时的邮箱重新设置密码。
  6. 修改头像:在主界面,用户可以点击头像进行修改。
  7. 注销用户:用户可以在主界面右上角点击注销用户,从而删除所有数据库的信息以及历史记录。
  8. 帮助功能:在主界面点击窗体标题框中的“?”即可进入帮助界面,包括如何进行注册等使用说明。
  9. 设置了验证码的有效时长:通过两个timer控件对用户重新获取验证码和验证码的有效时常进行了设置。

3.2 功能模块图

 四、软件设计

4.1 设计步骤

  1. 根据用户的需求,列出功能清单。
  2. 界面设计。首次打开程序需要进行用户的注册,并通过带参数的构造函数新建界面,显示该用户的所有信息。
  3. 数据库设计。使用SQL server数据库,将数据保存在不同的表中,提高了灵活性,增强了用户与数据之间的联系。设计所需数据的类型及名称。
  4. 设计代码。连接数据库并读取数据库的内容,同时加入界面上各个空间功能的实现代码。
  5. 设计自定义邮箱验证码类,在用户注册以及找回密码时可以直接调用,也可以随时更改对验证码的需求。
  6. 新用户的注册。注册成功后,用户的信息会被记录到SQL server数据库当中,系统会自动分配用户的账号。
  7. 用户修改密码。用户可以通过“忘记密码”选项设置新的密码。
  8. 记录账目信息。用户首先选择类别收入/支出,系统数据库为提供选项,对于其他类,用户可以在备注中添加信息。
  9. 提供查询功能。允许用户对历史收入、支出账目进行各种条件的组合查询。在查询时,如果用户没有选择支出或收入按钮,则在支出与收入的DataGridView中都会显示查询的内容。
  10. 将所有功能模块连接起来,测试整个软件的功能,并不断调试。

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 后记

通过前期系统调研与需求分析、设计等一系列工作,将系统主要分为以下几个模块:用户注册与登录、用户找回密码、记录收支、用户查阅收支记录、帮助中心。综上所述,随着移动支付的不断升级,消费习惯也在不断变化,冲动消费、刺激消费这类问题也接踵而至。电子的记账本为用户提供了更加方便的记账方式,能够更加快捷地查找消费记录,适合当前社会的需求。

我学会了:

  1. 通过软件提供的类来实现发送邮件的功能,从而绑定用户的信息。
  2. 设计带参数的初始化函数,可以将不同用户的信息分隔开。
  3. 学会了制作帮助文档,并在登录界面按下enter键相当于按下登录按钮,提高了用户界面友好性。
  4. 学会了用sql语句将图片插入到数据库中。
  5. 学会了制作图标icon。

7.2 不足之处

  1. 在每一个界面都进行了测试,但是没有将异常记录下来,应该将错误积累下来以便于下次遇到相似的问题时比较学习。
  2. 在连接数据库的过程当中经常会出现SQL语句格式写错的情况,而且有时候发现不了,应该现在SQL server中写入SQL命令保证语句正确,缩短处理异常的时间。
  3. 对于头像图片的选择还是有尺寸要求的,这块还需要再继续研究一下,目前对于自己使用已经足够了。

OK 本男神的介绍就到这里了,欢迎评论+私信!

  • 22
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Issme

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值