C#基于Sunnyui框架和MVC模式实现用户登录管理
C#基于Sunnyui框架和MVC模式实现用户登录管理
- 1 Controller
- 1.1 UserManagementController.cs(控制器入口)
- 2 Model
- 2.1 UserRepository.cs(用户管理模型)
- 2.2 User.cs(用户结构体)
- 2.3 SQLiteHelper.cs(数据库工具类)
- 3 View
- 3.1 LoginView.cs(用户登录窗体)
- 3.2 UserManagementForm(用户信息管理窗体)
- 3.2.1 UserManagementForm.cs
- 3.2.2 UserManagementForm.Designer.cs
- 3.3 UserUpdataForm.cs(添加、修改用户对话框)
- 4 扩展类
说明
- 类库结构如上图;
- 外部调用通过控制器入口调用
- 用户信息存储于数据库表中,路径:输出目录中userdata.db;
- 初始化自动生成开发者账号信息;
1 Controller
1.1 UserManagementController.cs(控制器入口)
using System;
using System.Windows.Forms;
using UserManage.Extensions;
using UserManage.Model;
using UserManage.View;namespace UserManage.Controller
{public class UserManagementController{private const string PermissionPrompt = "权限不足,请登录管理员账号";private readonly LoginView _loginForm;private readonly UserRepository _userRepository;private readonly UserManagementForm _userManagementForm;private User _currentUser;public UserType UserPermission => _currentUser?.UserType ?? UserType.Null;public UserManagementController(){_loginForm = new LoginView();_userRepository = new UserRepository();_userManagementForm = new UserManagementForm();_loginForm.LoginClicked += LoginForm_LoginClicked;_userManagementForm.AddUserClicked += UserManagementForm_AddUserClicked;_userManagementForm.ModifyUserClicked += UserManagementForm_ChangeUserPasswordClicked;_userManagementForm.DeleteUserClicked += UserManagementForm_DeleteUserClicked;}public UserManagementController(UserManagementForm userManagementForm){this._userManagementForm = userManagementForm;}public void RunLoginForm(){_loginForm.ShowDialog();}public void RunUserManagementForm(){if (_currentUser == null){UserManageExtension.ShowMsg(PermissionPrompt);return;}if (_currentUser.UserType != UserType.Developer && _currentUser.UserType != UserType.Admin){UserManageExtension.ShowMsg(PermissionPrompt);return;}LoadUser();_userManagementForm.ShowDialog();}private void LoadUser(){var table = _userRepository.GetUserTable();table.Columns[0].ColumnName = "用户名";table.Columns[1].ColumnName = "密码";table.Columns[2].ColumnName = "用户类型";_currentUser = _userRepository.GetUser(_currentUser.Username, _currentUser.Password);if (_currentUser.UserType != UserType.Developer){for (int i = 0; i < table.Rows.Count; i++){if (table.Rows[i][2].ToString().GetUserTypeByText() == UserType.Developer){table.Rows[i][1] = "******";}}}_userManagementForm.LoadUsers(table);}private void LoginForm_LoginClicked(object sender, EventArgs e){string username = _loginForm.Username;string password = _loginForm.Password;_currentUser = _userRepository.AuthenticateUser(username, password);if (_currentUser != null){_loginForm.Hide();}else{UserManageExtension.ShowMsg("用户名或密码错误!");}}private void UserManagementForm_AddUserClicked(object sender, EventArgs e){UserUpdataForm addDialog = new UserUpdataForm();switch (UserPermission){case UserType.Developer:addDialog.RefreshAddUserInfo();addDialog.AddUserType(UserType.Developer, UserType.Admin, UserType.NormalUser);break;case UserType.Admin:addDialog.RefreshAddUserInfo();addDialog.AddUserType(UserType.NormalUser);break;default:UserManageExtension.ShowMsg(PermissionPrompt);return;}addDialog.EnterClicked += (o, args) =>{try{string username = addDialog.UserName;string password = addDialog.Password;UserType userType = addDialog.UserType;if (addDialog.UserType == UserType.Null){UserManageExtension.ShowMsg("请选择用户类型!");return;}if (UserManageExtension.Confirm($"请确认添加用户信息" +$"{Environment.NewLine}用户名:{username}" +$"{Environment.NewLine}密码:{password}" +$"{Environment.NewLine}用户类型:{userType.GetUserTypeText()}" +$"{Environment.NewLine}确认添加?")){_userRepository.AddUser(username, password, userType);addDialog.DialogResult = DialogResult.OK;}}catch (Exception ex){UserManageExtension.ShowMsg(ex.Message);}};addDialog.ShowDialog();LoadUser();}private void UserManagementForm_DeleteUserClicked(object sender, EventArgs e){var selectUser = _userManagementForm.SelectUser;if (selectUser == null){UserManageExtension.ShowMsg(PermissionPrompt);return;}if (selectUser.UserType == UserType.Developer){UserManageExtension.ShowMsg("无法删除开发者账户", "警告");return;}if (!UserManageExtension.Confirm($"您正在删除用户[{selectUser.Username}],删除后将无法恢复,请确认是否继续?"))return;switch (UserPermission){case UserType.Developer:case UserType.Admin:_userRepository.DeleteUser(selectUser.Username);break;default:UserManageExtension.ShowMsg(PermissionPrompt);return;}LoadUser();}private void UserManagementForm_ChangeUserPasswordClicked(object sender, EventArgs e){var selectUser = _userManagementForm.SelectUser;if (selectUser == null){UserManageExtension.ShowMsg("请选择需要修改的用户");return;}if (selectUser.UserType == UserType.Developer && _currentUser.UserType != UserType.Developer){UserManageExtension.ShowMsg(PermissionPrompt);return;}UserUpdataForm updataDialog = new UserUpdataForm();switch (UserPermission){case UserType.Developer:updataDialog.RefreshUdpataUserInfo(selectUser);updataDialog.AddUserType(UserType.Developer, UserType.Admin, UserType.NormalUser);break;case UserType.Admin:updataDialog.RefreshUdpataUserInfo(selectUser);updataDialog.AddUserType(UserType.NormalUser);break;default:UserManageExtension.ShowMsg(PermissionPrompt);return;}updataDialog.EnterClicked += (o, args) =>{try{if (updataDialog.UserType == UserType.Null){UserManageExtension.ShowMsg("请选择用户类型!");return;}string username = updataDialog.UserName;string password = updataDialog.Password;UserType userType = updataDialog.UserType;if (UserManageExtension.Confirm($"用户[{username}],密码修改为{Environment.NewLine}{password}{Environment.NewLine}是否确认修改?")){_userRepository.ChangePassword(username, password, userType.GetUserTypeText());updataDialog.DialogResult = DialogResult.OK;}}catch (Exception ex){UserManageExtension.ShowMsg(ex.Message);}};updataDialog.ShowDialog();LoadUser();}}
}
2 Model
2.1 UserRepository.cs(用户管理模型)
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using UserManage.Extensions;namespace UserManage.Model
{public class UserRepository{private const string TableName = "User";private string connectionString = "Data Source=users.db;Version=3;";private SQLiteHelper _sqLiteHelper;public const string DeveloperName = "Veizu";public const string DeveloperPassword = "Aa123456";public UserRepository(){CreateUserTable();EnsureDeveloperExists();}private void CreateUserTable(){string datasource = Path.Combine(Application.StartupPath, "userdata.db");string tableInfo = TableName + "( " + "Username CHAR(50) PRIMARY KEY," + "Password CHAR(50)," + "UserType CHAR(50)" + ")";if (File.Exists(datasource)){_sqLiteHelper = SQLiteHelper.OpenConnection(datasource);if (_sqLiteHelper.IsExistsTable(TableName)){_sqLiteHelper.CreateTableSql(tableInfo);}}else{_sqLiteHelper = SQLiteHelper.OpenConnection(datasource, true, tableInfo);}}private void EnsureDeveloperExists(){try{AddUser(DeveloperName, DeveloperPassword, UserType.Developer);}catch (Exception ex){}}public User AuthenticateUser(string username, string password){return GetUser(username, password);}public void IsValidUsernamePassword(string username, string password){string pattern = @"^[a-zA-Z\u4e00-\u9fa5][a-zA-Z0-9\u4e00-\u9fa5]*$";var ret = Regex.IsMatch(username, pattern);if (!ret){throw new ArgumentException("用户名第一个字符必须是英文字母或中文开头,仅允许包含中文、英文和数字。");}pattern = @"^[a-zA-Z0-9]+$";ret = Regex.IsMatch(password, pattern);if (!ret){throw new ArgumentException("用户密码仅允许字母和数字。");}const int passwordLength = 6;if (password.Length < passwordLength){throw new ArgumentException($"用户密码不得少于{passwordLength}个字符。");}}public bool IsUserExists(string username, string password = null){return GetUser(username, password) != null;}public DataTable GetUserTable(){var table = _sqLiteHelper.Select(TableName);return table.Copy();}public User GetUser(string username, string password = null){User user = null;var table = GetUserTable();foreach (DataRow row in table.Rows){if (row[nameof(User.Username)].ToString().Equals(username)){if (!string.IsNullOrWhiteSpace(password)){if (row[nameof(User.Password)].ToString().Equals(password)){UserType userType = row[nameof(User.UserType)].ToString().GetUserTypeByText();user = new User(username, password, userType);}}else{user = new User(username);}}}return user;}public void AddUser(string username, string password, UserType userType){IsValidUsernamePassword(username, password);if (IsUserExists(username)){throw new ArgumentException("该用户名已存在,请选择其他用户名。");}var parameter1 = new SQLiteParameter { ParameterName = nameof(User.Username), Value = username };var parameter2 = new SQLiteParameter { ParameterName = nameof(User.Password), Value = password };var parameter3 = new SQLiteParameter { ParameterName = nameof(User.UserType), Value = userType.GetUserTypeText() };_sqLiteHelper.Insert(TableName, parameter1, parameter2, parameter3);}public void DeleteUser(string username){_sqLiteHelper.Delete(TableName, nameof(User.Username), username);}public void ChangePassword(string username, string newPassword, string newUserType){IsValidUsernamePassword(username, newPassword);string updateQuery = $"UPDATE {TableName} SET {nameof(User.Password)} = '{newPassword}',{nameof(User.UserType)} = '{newUserType}' WHERE {nameof(User.Username)} = '{username}';";_sqLiteHelper.ExecuteSql(updateQuery);}}
}
2.2 User.cs(用户结构体)
namespace UserManage.Model
{public enum UserType{Null = 1,Developer = 3,Admin = 5,NormalUser = 7,}public class User{public string Username { get; set; }public string Password { get; set; }public UserType UserType { get; set; }public User(string username, string password, UserType userType){Username = username;Password = password;UserType = userType;}public User(string username){Username = username;}}
}
2.3 SQLiteHelper.cs(数据库工具类)
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Reflection;namespace UserManage.Model
{public class SQLiteHelper{public static SQLiteConnection _conn;private static SQLiteConnectionStringBuilder _connstr;public static SQLiteHelper OpenConnection<T>(string datasource) where T : class{if (!File.Exists(datasource)) SQLiteConnection.CreateFile(datasource);var sqLite = new SQLiteHelper();_conn = new SQLiteConnection();_connstr = new SQLiteConnectionStringBuilder { DataSource = datasource };_conn.ConnectionString = _connstr.ToString();_conn.Open();var tableName = Path.GetFileNameWithoutExtension(datasource);string query = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}';";using (SQLiteCommand command = new SQLiteCommand(query, _conn)){// 执行查询并获取结果object result = command.ExecuteScalar();// 如果结果不为空,则表存在if (result == null){sqLite.CreateTable<T>();}}return sqLite;}/// <summary>/// 打开数据库/// </summary>/// <param name="datasource">数据库路径</param>/// <param name="isCreate">是否创建数据库文件</param>/// <param name="tableInfo">创建数据库文件时同时创建的表结构信息;例如:TableName(ListIndex INTEGER, ListTime CHAR(23), ListSpeed INTEGER, ListRemark CHAR(50))</param>/// <returns>返回SQLiteHelper实例</returns>public static SQLiteHelper OpenConnection(string datasource, bool isCreate, string tableInfo = null){if (isCreate) SQLiteConnection.CreateFile(datasource);var sqLite = new SQLiteHelper();_conn = new SQLiteConnection();_connstr = new SQLiteConnectionStringBuilder { DataSource = datasource };_conn.ConnectionString = _connstr.ToString();_conn.Open();if (isCreate) sqLite.CreateTableSql(tableInfo);return sqLite;}/// <summary>/// 打开数据库/// </summary>/// <param name="datasource">数据库路径</param>/// <returns>返回SQLiteHelper实例</returns>public static SQLiteHelper OpenConnection(string datasource) => OpenConnection(datasource, false);/// <summary>/// 关闭/// </summary>public void CloseConnection(){if (_conn.State == ConnectionState.Closed)return;_conn.Close();_conn.Dispose();_connstr.Clear();}/// <summary>/// 执行自定义SQL语句,/// </summary>/// <param name="sql">自定义SQL语句</param>/// <returns>返回影响行数</returns>public int ExecuteSql(string sql){using (var cmd = _conn.CreateCommand()){cmd.CommandText = sql;return cmd.ExecuteNonQuery();}}public int CreateTable<T>() where T : class{string createTableQuery = GenerateCreateTableQuery(typeof(T));// 创建SQLite命令对象using (SQLiteCommand command = new SQLiteCommand(createTableQuery, _conn)){// 执行SQL命令command.ExecuteNonQuery();}return 0;}static string GenerateCreateTableQuery(Type type){// 获取实体类名称string tableName = type.Name;// 初始化SQL语句字符串构建器System.Text.StringBuilder query = new System.Text.StringBuilder();query.Append($"CREATE TABLE IF NOT EXISTS {tableName} (");// 获取实体类的所有属性PropertyInfo[] properties = type.GetProperties();for (int i = 0; i < properties.Length; i++){PropertyInfo property = properties[i];// 获取属性名称string columnName = property.Name;// 获取属性类型string columnType = GetSqliteType(property.PropertyType);query.Append($"{columnName} {columnType}");if (i < properties.Length - 1){query.Append(", ");}}query.Append(");");return query.ToString();}static string GetSqliteType(Type type){// 根据C#类型映射到SQLite类型if (type == typeof(int) || type == typeof(long)){return "INTEGER";}else if (type == typeof(string)){return "TEXT";}else if (type == typeof(double) || type == typeof(float)){return "REAL";}else if (type == typeof(List<DateTime>) || type == typeof(List<double>)){return "BLOB";}else{return "TEXT";}}/// <summary>/// 执行自定义SQL语句,/// </summary>/// <param name="tableInfo">表结构信息;例如:TableName(ListIndex INTEGER, ListTime CHAR(23), ListSpeed INTEGER, ListRemark CHAR(50))</param>/// <returns>返回影响行数</returns>public int CreateTableSql(string tableInfo) => ExecuteSql($"CREATE TABLE {tableInfo}");/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="colName">字段名</param>/// <param name="value">参数数据</param>/// <returns>int</returns>public int Insert(string tableName, string colName, string value){using (var cmd = _conn.CreateCommand()){cmd.CommandText = $"INSERT INTO {tableName} VALUES(@{colName})";cmd.Parameters.Add(colName, DbType.String).Value = value;return cmd.ExecuteNonQuery();}}/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="parameters">键值对</param>/// <returns>int</returns>public int Insert(string tableName, SQLiteParameter parameters){using (var cmd = _conn.CreateCommand()){// 添加参数到命令对象 cmd.Parameters.Add(parameters);// 构建完整的INSERT语句 string query = $"INSERT INTO {tableName} ({parameters.ParameterName}) VALUES (@{parameters.ParameterName});";cmd.CommandText = query;// 执行命令并返回受影响的行数 return cmd.ExecuteNonQuery();}}/// <summary>/// 从库中删除表/// </summary>/// <param name="tableName"></param>public int DeleteTable(string tableName){using (var cmd = _conn.CreateCommand()){cmd.CommandText = $"DROP TABLE IF EXISTS {tableName}";return cmd.ExecuteNonQuery();}}/// <summary>/// 执行删除操作/// </summary>/// <param name="tableName">表名</param>/// <param name="colName">字段名</param>/// <param name="value">参数数据</param>/// <returns>int</returns>public int Delete(string tableName, string colName, object value){using (var cmd = _conn.CreateCommand()){cmd.CommandText = $"DELETE FROM {tableName} WHERE {colName} = @value;";cmd.Parameters.Add("value", DbType.Object).Value = value;return cmd.ExecuteNonQuery();}}/// <summary>/// 执行查询操作/// </summary>/// <param name="tableName">表名</param>/// <returns>DataTable</returns>public DataTable Select(string tableName){var dt = new DataTable();var cmd = _conn.CreateCommand();cmd.CommandText = $"select * from {tableName}";var dao = new SQLiteDataAdapter(cmd);dao.Fill(dt);cmd.ExecuteNonQuery();dao.Dispose();return dt.Copy();}public bool IsExistsTable(string tableName){string cmdText = $"select count(*) from sqlite_master where name='{tableName}' and type='table';";int count = ExecuteSql(cmdText);return count > 0;}public bool IsExistsData(string tableName, Dictionary<string, object> parameter){string query = $"SELECT COUNT(*) FROM {tableName} WHERE ";foreach (var key in parameter.Keys){query += $"{key} = @{key}";}query += $";";SQLiteCommand command = new SQLiteCommand(query, _conn);foreach (var key in parameter.Keys){command.Parameters.AddWithValue($"@{key}", parameter[key]);}int count = Convert.ToInt32(command.ExecuteScalar());return count > 0;}/// <summary>/// 执行插入操作/// </summary>/// <param name="tableName">表名</param>/// <param name="parameters">键值对字典</param>/// <returns>int</returns>public int Insert(string tableName, params SQLiteParameter[] parameters){int count = -1;try{using (var cmd = _conn.CreateCommand()){string query = $"INSERT INTO" +$" {tableName}" +$" ({string.Join(",", parameters.Select(p => p.ParameterName))})" +$" VALUES ({string.Join(",", parameters.Select(p => "@" + p.ParameterName))});";cmd.Parameters.AddRange(parameters);cmd.CommandText = query;count = cmd.ExecuteNonQuery();}return count;}catch (Exception ex){throw ex;}}/// <summary>/// 批量插入/// </summary>/// <param name="tableName"></param>/// <param name="col"></param>/// <param name="list"></param>public void Insert(string tableName, string[] col, List<object[]> list){var cmd = _conn.CreateCommand();SQLiteTransaction transaction = _conn.BeginTransaction();cmd.Transaction = transaction;try{object[] obj = list.First();var parameters = new List<SQLiteParameter>();for (int i = 0; i < col.Length; i++){parameters.Add(new SQLiteParameter(col[i], obj[i]));}string sql = $"INSERT INTO" +$" {tableName}" +$" ({string.Join(",", parameters.Select(p => p.ParameterName))})" +$" VALUES ({string.Join(",", parameters.Select(p => "@" + p.ParameterName))});";foreach (var value in list){parameters = new List<SQLiteParameter>();for (int i = 0; i < col.Length; i++){parameters.Add(new SQLiteParameter(col[i], value[i]));}cmd.Parameters.AddRange(parameters.ToArray());cmd.CommandText = sql;cmd.ExecuteNonQuery();}transaction.Commit();}catch (Exception e){}}/// <summary>/// 执行更新操作/// </summary>/// <param name="tableName">表名</param>/// <param name="setValues">新数据</param>/// <param name="whereClause">条件</param>/// <param name="parameters">条件数据</param>/// <returns>int</returns>public int Update(string tableName, Dictionary<string, object> setValues, string whereClause, List<SQLiteParameter> parameters){using (var cmd = _conn.CreateCommand()){List<string> setColumns = new List<string>();int index = 0;foreach (var kvp in setValues){setColumns.Add($"{kvp.Key} = @{kvp.Key}");cmd.Parameters.Add(new SQLiteParameter($"@{kvp.Key}", kvp.Value));index++;}string query = $"UPDATE {tableName} SET {string.Join(",", setColumns)} WHERE {whereClause}";cmd.CommandText = query;cmd.Parameters.AddRange(parameters.ToArray());return cmd.ExecuteNonQuery();}}}
}
3 View
3.1 LoginView.cs(用户登录窗体)
using System;
using System.Windows.Forms;
using Sunny.UI;
using UserManage.Model;namespace UserManage.View
{public partial class LoginView : UIForm{private UILabel lblUsername;private UILabel lblPassword;private UITextBox txtUsername;private UITextBox txtPassword;private UIButton btnLogin;public event EventHandler LoginClicked;public string Username => txtUsername.Text;public string Password => txtPassword.Text;public LoginView(){InitializeComponent();InitializeUI();}private void LoginView_VisibleChanged(object sender, EventArgs e){txtUsername.Text = string.Empty;txtPassword.Text = string.Empty;txtUsername.Text = "Veizu";txtPassword.Text = "Aa123456";}private void InitializeUI(){// 设置窗体样式this.Text = "用户登录";this.Size = new System.Drawing.Size(300, 250);this.StartPosition = FormStartPosition.CenterScreen;int locationY = 80;int yInterval = 20;// 用户名标签lblUsername = new UILabel();lblUsername.Location = new System.Drawing.Point(30, locationY);lblUsername.Size = new System.Drawing.Size(80, 25);lblUsername.Text = "用户名:";this.Controls.Add(lblUsername);// 用户名文本框txtUsername = new UITextBox();txtUsername.Location = new System.Drawing.Point(120, locationY);txtUsername.Size = new System.Drawing.Size(150, 25);this.Controls.Add(txtUsername);// 密码标签locationY += yInterval + txtUsername.Height;lblPassword = new UILabel();lblPassword.Location = new System.Drawing.Point(30, locationY);lblPassword.Size = new System.Drawing.Size(80, 25);lblPassword.Text = "密码:";this.Controls.Add(lblPassword);// 密码文本框txtPassword = new UITextBox();txtPassword.Location = new System.Drawing.Point(120, locationY);txtPassword.Size = new System.Drawing.Size(150, 25);txtPassword.PasswordChar = '*';this.Controls.Add(txtPassword);// 登录按钮locationY += yInterval + txtPassword.Height;btnLogin = new UIButton();btnLogin.Size = new System.Drawing.Size(100, 30);int btnLoginX = txtPassword.Location.X + txtPassword.Width - btnLogin.Width;btnLogin.Location = new System.Drawing.Point(btnLoginX, locationY);btnLogin.Text = "登录";btnLogin.Click += btnLogin_Click;this.Controls.Add(btnLogin);}private void btnLogin_Click(object sender, EventArgs e){LoginClicked?.Invoke(this, EventArgs.Empty);}}
}
3.2 UserManagementForm(用户信息管理窗体)
3.2.1 UserManagementForm.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sunny.UI;
using UserManage.Extensions;
using UserManage.Model;namespace UserManage.View
{public partial class UserManagementForm : UIForm{public User SelectUser{get{if (dgv_User.CurrentCell != null){var row = dgv_User.Rows[dgv_User.CurrentCell.RowIndex];string username = row.Cells[0].Value.ToString();string password = row.Cells[1].Value.ToString();UserType userType = row.Cells[2].Value.ToString().GetUserTypeByText();return new User(username, password, userType);}else{return null;}}}public event EventHandler AddUserClicked;public event EventHandler ModifyUserClicked;public event EventHandler DeleteUserClicked;public UserManagementForm(){InitializeComponent();InitializeUI();}private void InitializeUI(){// 设置窗体样式this.Size = new Size(800, 600);this.Text = "用户管理";this.StartPosition = FormStartPosition.CenterScreen;}/// <summary>/// 设置数据表样式/// </summary>private void SetDgvStyle(UIDataGridView table){try{table.ClearSelection();//int index = dgvStandard.CurrentCell.RowIndex;//获取选中行table.MultiSelect = false; //不可多选table.AllowUserToAddRows = false; //设置不显示添加行table.AllowUserToDeleteRows = false; //设置不允许删除行table.AllowUserToResizeColumns = false; //设置列不可调整table.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //列名居中table.AllowUserToResizeRows = false; //设置行不可调整table.RowHeadersVisible = false; //设置表头不显示行标题table.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; //列填充控件显示区域table.CausesValidation = false; //焦点table.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single; //边框样式table.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; //列高调整table.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //单元格内容居中table.ReadOnly = true; //只读设置table.RowHeadersWidth = 4; //列宽设置(按照权重设置时需要先添加列)table.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders; //设置列表头不可调整table.RowTemplate.Height = 28; //设置行高table.ScrollBars = ScrollBars.Vertical; //显示垂直滚动条table.TabStop = false; //设置无Tab焦点table.VirtualMode = true; //设置可进行数据管理//dgv.Rows[lastTableHeadRow].Frozen = true;//冻结指定行for (var i = 0; i < table.Columns.Count; i++){table.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable; //禁止点击列名排序dgv_User.Columns[i].FillWeight = 1; //按权重分配列宽}}catch (Exception){// ignored}}private void btnAddUser_Click(object sender, EventArgs e){AddUserClicked?.Invoke(this, EventArgs.Empty);}private void btnModifyUser_Click(object sender, EventArgs e){ModifyUserClicked?.Invoke(this, EventArgs.Empty);}private void btnDeleteUser_Click(object sender, EventArgs e){DeleteUserClicked?.Invoke(this, EventArgs.Empty);}public void LoadUsers(DataTable table){dgv_User.DataSource = null;dgv_User.DataSource = table;SetDgvStyle(dgv_User);}}}
3.2.2 UserManagementForm.Designer.cs
namespace UserManage.View
{partial class UserManagementForm{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();this.btn_Add = new Sunny.UI.UIButton();this.btn_Updata = new Sunny.UI.UIButton();this.btn_Del = new Sunny.UI.UIButton();this.dgv_User = new Sunny.UI.UIDataGridView();((System.ComponentModel.ISupportInitialize)(this.dgv_User)).BeginInit();this.SuspendLayout();// // btn_Add// this.btn_Add.Cursor = System.Windows.Forms.Cursors.Hand;this.btn_Add.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Add.Location = new System.Drawing.Point(59, 60);this.btn_Add.MinimumSize = new System.Drawing.Size(1, 1);this.btn_Add.Name = "btn_Add";this.btn_Add.Size = new System.Drawing.Size(149, 35);this.btn_Add.TabIndex = 0;this.btn_Add.Text = "添加用户";this.btn_Add.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Add.Click += new System.EventHandler(this.btnAddUser_Click);// // btn_Updata// this.btn_Updata.Cursor = System.Windows.Forms.Cursors.Hand;this.btn_Updata.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Updata.Location = new System.Drawing.Point(233, 60);this.btn_Updata.MinimumSize = new System.Drawing.Size(1, 1);this.btn_Updata.Name = "btn_Updata";this.btn_Updata.Size = new System.Drawing.Size(149, 35);this.btn_Updata.TabIndex = 0;this.btn_Updata.Text = "修改用户";this.btn_Updata.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Updata.Click += new System.EventHandler(this.btnModifyUser_Click);// // btn_Del// this.btn_Del.Cursor = System.Windows.Forms.Cursors.Hand;this.btn_Del.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Del.Location = new System.Drawing.Point(407, 60);this.btn_Del.MinimumSize = new System.Drawing.Size(1, 1);this.btn_Del.Name = "btn_Del";this.btn_Del.Size = new System.Drawing.Size(149, 35);this.btn_Del.TabIndex = 0;this.btn_Del.Text = "删除用户";this.btn_Del.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.btn_Del.Click += new System.EventHandler(this.btnDeleteUser_Click);// // uiDataGridView1// dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255)))));this.dgv_User.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;this.dgv_User.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right)));this.dgv_User.BackgroundColor = System.Drawing.Color.White;this.dgv_User.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;dataGridViewCellStyle2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255)))));dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));dataGridViewCellStyle2.ForeColor = System.Drawing.Color.White;dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True;this.dgv_User.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2;this.dgv_User.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Window;dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));dataGridViewCellStyle3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight;dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText;dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.False;this.dgv_User.DefaultCellStyle = dataGridViewCellStyle3;this.dgv_User.EnableHeadersVisualStyles = false;this.dgv_User.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.dgv_User.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255)))));this.dgv_User.Location = new System.Drawing.Point(39, 122);this.dgv_User.Name = "dgv_User";dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;dataGridViewCellStyle4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255)))));dataGridViewCellStyle4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));dataGridViewCellStyle4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));dataGridViewCellStyle4.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(160)))), ((int)(((byte)(255)))));dataGridViewCellStyle4.SelectionForeColor = System.Drawing.Color.White;dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;this.dgv_User.RowHeadersDefaultCellStyle = dataGridViewCellStyle4;dataGridViewCellStyle5.BackColor = System.Drawing.Color.White;dataGridViewCellStyle5.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.dgv_User.RowsDefaultCellStyle = dataGridViewCellStyle5;this.dgv_User.RowTemplate.Height = 23;this.dgv_User.SelectedIndex = -1;this.dgv_User.Size = new System.Drawing.Size(901, 503);this.dgv_User.StripeOddColor = System.Drawing.Color.FromArgb(((int)(((byte)(235)))), ((int)(((byte)(243)))), ((int)(((byte)(255)))));this.dgv_User.TabIndex = 1;// // UserManagementForm// this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;this.ClientSize = new System.Drawing.Size(982, 658);this.Controls.Add(this.dgv_User);this.Controls.Add(this.btn_Del);this.Controls.Add(this.btn_Updata);this.Controls.Add(this.btn_Add);this.Name = "UserManagementForm";this.Text = "UserManagementForm__";this.ZoomScaleRect = new System.Drawing.Rectangle(15, 15, 800, 450);((System.ComponentModel.ISupportInitialize)(this.dgv_User)).EndInit();this.ResumeLayout(false);}#endregionprivate Sunny.UI.UIButton btn_Add;private Sunny.UI.UIButton btn_Updata;private Sunny.UI.UIButton btn_Del;private Sunny.UI.UIDataGridView dgv_User;}
}
3.3 UserUpdataForm.cs(添加、修改用户对话框)
using System;
using System.Windows.Forms;
using Sunny.UI;
using UserManage.Extensions;
using UserManage.Model;namespace UserManage.View
{public partial class UserUpdataForm : UIForm{private UILabel lblUsername;private UILabel lblUserType;private UILabel lblPassword;private UITextBox txtUsername;private UIComboBox comUserType;private UITextBox txtPassword;private UIButton btnEnter;public UserType UserType => comUserType.Text.GetUserTypeByText();public string UserName => txtUsername.Text;public string Password => txtPassword.Text;public event EventHandler EnterClicked;public UserUpdataForm(){InitializeComponent();InitializeUI();}private void InitializeUI(){// 设置窗体样式this.Size = new System.Drawing.Size(300, 280);this.StartPosition = FormStartPosition.CenterScreen;int locationY = 80;int yInterval = 20;// 用户名标签lblUsername = new UILabel();lblUsername.Location = new System.Drawing.Point(30, locationY);lblUsername.Size = new System.Drawing.Size(80, 25);lblUsername.Text = "用户名:";this.Controls.Add(lblUsername);// 用户名文本框txtUsername = new UITextBox();txtUsername.Location = new System.Drawing.Point(120, locationY);txtUsername.Size = new System.Drawing.Size(150, 25);this.Controls.Add(txtUsername);// 用户类型locationY += yInterval + txtUsername.Height;lblUserType = new UILabel();lblUserType.Location = new System.Drawing.Point(30, locationY);lblUserType.Size = new System.Drawing.Size(80, 25);lblUserType.Text = "用户类型:";this.Controls.Add(lblUserType);// 用户类型下拉框comUserType = new UIComboBox();comUserType.Location = new System.Drawing.Point(120, locationY);comUserType.Size = new System.Drawing.Size(150, 25);this.Controls.Add(comUserType);// 密码标签locationY += yInterval + comUserType.Height;lblPassword = new UILabel();lblPassword.Location = new System.Drawing.Point(30, locationY);lblPassword.Size = new System.Drawing.Size(80, 25);lblPassword.Text = "密码:";this.Controls.Add(lblPassword);// 密码文本框txtPassword = new UITextBox();txtPassword.Location = new System.Drawing.Point(120, locationY);txtPassword.Size = new System.Drawing.Size(150, 25);this.Controls.Add(txtPassword);// 登录按钮locationY += yInterval + txtPassword.Height;btnEnter = new UIButton();btnEnter.Size = new System.Drawing.Size(100, 30);int btnLoginX = txtPassword.Location.X + txtPassword.Width - btnEnter.Width;btnEnter.Location = new System.Drawing.Point(btnLoginX, locationY);btnEnter.Click += BtnEnterClick;this.Controls.Add(btnEnter);}private void BtnEnterClick(object sender, EventArgs e){EnterClicked?.Invoke(this, EventArgs.Empty);}public void AddUserType(params UserType[] userTypes){if (comUserType != null){foreach (var userType in userTypes){comUserType.Items.Add(userType.GetUserTypeText());}}}public void RefreshAddUserInfo(){txtUsername.Text = string.Empty;txtPassword.Text = string.Empty;comUserType.Text = string.Empty;this.Text = "添加用户";btnEnter.Text = "添加";txtUsername.ReadOnly = false;}public void RefreshUdpataUserInfo(User user){comUserType.Text = user.UserType.GetUserTypeText();txtUsername.Text = user.Username;txtPassword.Text = user.Password;txtUsername.ReadOnly = true;this.Text = "修改用户";btnEnter.Text = "确认";}}
}
4 扩展类
using Sunny.UI;
using UserManage.Model;namespace UserManage.Extensions
{public static class UserManageExtension{public static string GetUserTypeText(this UserType type){switch (type){case UserType.Developer:return "开发者";case UserType.Admin:return "管理员";case UserType.NormalUser:return "普通用户";default:return "未登录";}}public static UserType GetUserTypeByText(this string text){if (text.Equals(UserType.Developer.GetUserTypeText()))return UserType.Developer;else if (text.Equals(UserType.Admin.GetUserTypeText()))return UserType.Admin;else if (text.Equals(UserType.NormalUser.GetUserTypeText()))return UserType.NormalUser;elsereturn UserType.Null;}public static void ShowMsg(string text, string title = "提示"){UIMessageBox.ShowError(text);}public static bool Confirm(string text){return UIMessageBox.ShowAsk(text);}}
}
相关文章:
C#基于Sunnyui框架和MVC模式实现用户登录管理
C#基于Sunnyui框架和MVC模式实现用户登录管理 1 Controller1.1 UserManagementController.cs(控制器入口) 2 Model2.1 UserRepository.cs(用户管理模型)2.2 User.cs(用户结构体)2.3 SQLiteHelper.cs&#x…...
Spring Boot实战(三十六)编写单元测试
目录 一、什么是单元测试?二、Spring Boot 中的单元测试依赖三、举例 Spring Boot 中不同层次的单元测试3.1 Service层3.2 Controller 层3.3 Repository层 四、Spring Boot 中 Mock、Spy 对象的使用4.1 使用Mock对象的背景4.2 什么是Mock对象,有哪些好处…...
声音分离人声和配乐-从头设计数字生命第4课——仙盟创梦IDE
音频分离在数字人中具有多方面的重要作用,主要体现在以下几个方面: 提高语音合成质量:通过音频分离,可以将原始音频中的语音部分与其他背景噪音或干扰声音分离开来。这样在进行语音合成时,能够获得更纯净的语音信号&am…...
http协议、全站https
一、http协议 1、为何要学http协议? 用户用浏览器访问网页,默认走的都是http协议,所以要深入研究web层,必须掌握http协议 2、什么是http协议 1、全称Hyper Text Transfer Protocol(超文本传输协议) ### 一个请求得到一个响应包 普通…...
Mediamtx与FFmpeg远程与本地推拉流使用
1.本地推拉流 启服 推流 ffmpeg -re -stream_loop -1 -i ./DJI_0463.MP4 -s 1280x720 -an -c:v h264 -b:v 2000k -maxrate 2500k -minrate 1500k -bufsize 3000k -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream 拉流 ffplay -rtsp_transport tcp rtsp://43.136.…...
css3新特性第七章(3D变换)
css新特性第七章(3D变换) 一、3d空间和景深 元素进行 3D 变换的首要操作:父元素必须开启 3D 空间! 使用 transform-style 开启 3D 空间,可选值如下: flat : 让子元素位于此元素的二维平面内( 2D 空间&…...
redis经典问题
1.缓存雪崩 指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。 解决方案: 1)Redis 高可用,主从哨兵,Redis cluster,避免全盘崩…...
数据仓库是什么?数据仓库架构有哪些?
目录 数据仓库是什么?数据仓库架构有哪些? 一、数据仓库是什么? 二、数据仓库的架构分层 1. 获取层 2. 数据层 3. 应用层 4. 访问层 三、数据仓库的价值体现 1.决策支持 2.业务优化 3.提升竞争力 四、数据仓库的未来发展趋势 总…...
Nginx 通过 Let‘s Encrypt 实现 HTTPS 访问全流程指南
一、Let’s Encrypt 与 Certbot 简介 Let’s Encrypt 是由非营利组织 ISRG 运营的免费证书颁发机构(CA),旨在推动 HTTPS 的普及。其核心工具 Certbot 能自动化完成证书申请、部署与续期,大幅降低 HTTPS 的配置复杂度。通过 Certb…...
网络知识:路由器静态路由与动态路由介绍
目录 一、静态路由 1.1 什么是静态路由? 1.2 静态路由的好处 1.3 静态路由的局限 1.4 静态路由应用场景 微型办公室网络 性能要求高业务流量 安全性要求高的环境 二、动态路由 2.1 什么是动态路由? 2.2 动态路由的好处 2.3 动态路由的局限 2.4 动态路由的应用场…...
LLaMA3微调全流程:从LoRA到QLoRA,7B参数模型推理速度提升4倍的代码实战
LLaMA3微调全流程:从LoRA到QLoRA,7B参数模型推理速度提升4倍的代码实战 发现了一个巨牛的人工智能学习网站,分享一下给大家!https://www.captainbed.cn/ccc 前言 在大模型时代,LLaMA系列作为开源社区的明星模型&#…...
日内组合策略思路
一、策略概述 本策略是一种针对日内交易设计的策略,其核心在于通过识别市场趋势和突破信号,结合动态止损和止盈机制,实现日内交易的盈利。策略以金字塔式的加仓方式控制风险,并通过灵活的平仓策略锁定收益。 二、交易逻辑思路 市场…...
从空气污染监测到嵌入式仿真教学:基于STM32与MQ135的实践探索
一、嵌入式系统在环境监测中的技术演进 随着全球城市化进程加速,世界卫生组织(WHO)数据显示,92%的人口长期暴露于超标PM2.5环境中。在此背景下,基于STM32微控制器的智能监测系统因其高性价比(单节点成本低…...
【数据结构】Map与Set结构详解
数据结构系列五:Map与Set(一) 一、接口的实现 1.方法上 2.成员上 二、Map的内外双接口结构 1.实现 1.1外部Map接口的实现 1.1.1临摹整体 1.1.2外部类实现整体 1.2内部Entry接口的实现 1.2.1临摹内部 1.2.2内部类实现内部 2.关系 3.意义 3.1逻辑内聚 …...
银河麒麟(内核CentOS8)安装rbenv、ruby2.6.5和rails5.2.6
一、安装 rbenv 和 ruby-build 1.安装 rbenv git clone https://github.com/rbenv/rbenv.git ~/.rbenv 2. 添加 rbenv 到 PATH echo export PATH"$HOME/.rbenv/bin:$PATH" >> ~/.bashrc echo eval "$(rbenv init -)" >> ~/.bashrc source ~…...
豆包桌面版 1.47.4 可做浏览器,免安装绿色版
自己动手升级更新办法: 下载新版本后安装,把 C:\Users\用户名\AppData\Local\Doubao\Application 文件夹的文件,拷贝替换 DoubaoPortable\App\Doubao 文件夹的文件,就升级成功了。 再把安装的豆包彻底卸载就可以。 桌面版比网页版…...
Linux 命令行与 vi/vim 编辑器完全指南
一、Linux 命令行基础 (一)命令与命令行简介 命令:Linux 系统内置的操作指令,以字符化形式使用,用于指示系统执行特定任务。 命令行(终端):提供字符化的操作界面,用户通…...
海量聊天消息处理:ShardingJDBC分库分表、ClickHouse冷热数据分离、ES复合查询方案、Flink实时计算与SpringCloud集成
海量聊天消息处理:ShardingJDBC分库分表、ClickHouse冷热数据分离、ES复合查询方案、Flink实时计算与SpringCloud集成 一、背景介绍 每天有2000万条聊天消息,一年下来几千万亿海量数据。为应对这种规模的数据存储和处理需求,本文将从以下几…...
金融系统上云之路:云原生后端架构在金融行业的演化与实践
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:为什么金融行业也要“云原生”? 金融行业素来以“安全第一、稳定优先”著称,面对每日亿级交易请求、秒级风控响应、PB级数据处理,系统稳定性和性能要求极高。长期以来,大型金融机构往…...
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
[洛谷 P1226] 快速幂求模题解 📌 题目链接 https://www.luogu.com.cn/problem/P1226 📝 题目描述 给定正整数 a、b 和质数 p,要求计算: a^b % p其中: 1 ≤ a ≤ 10^90 ≤ b ≤ 10^92 ≤ p ≤ 10^9 💡…...
深度学习小记(包括pytorch 还有一些神经网络架构)
这个是用来增加深度学习的知识面或者就是记录一些常用的命令,会不断的更新 import torchvision.transforms as transforms toPIL transforms.ToPILImage()#可以把tensor转换为Image类型的 imgtoPIL(img) #利用save就可以保存下来 img.save("/opt/data/private/stable_si…...
Spring Boot默认缓存管理
Spring框架支持透明地向应用程序添加缓存,以及对缓存进行管理,其管理缓存的核心是将缓存应用于操作数据的方法,从而减少操作数据的执行次数,同时不会对程序本身造成任何干扰。Spring Boot继承了Spring框架的缓存管理功能ÿ…...
倚光科技:微透镜阵列低成本加工新范式
在光通信、机器视觉、生物医学成像等前沿领域,微透镜阵列凭借其独特的光学特性成为不可或缺的核心部件。然而,传统加工方式往往面临成本高、效率低、精度难控等困境。倚光科技深耕光学加工领域多年,创新运用单点金刚石车床技术,成…...
Vue+Flask豆瓣LSTM影评+推荐算法大数据可视化平台深度学习系统源码
文章结尾部分有CSDN官方提供的学长 联系方式名片 文章结尾部分有CSDN官方提供的学长 联系方式名片 关注B站,有好处! 编号: F011 视频介绍 VueFlask豆瓣LSTM影评推荐算法大数据可视化平台深度学习系统源码(2023重制) 1…...
【MySQL】基本查询
目录 增加 查询 基本查询 where子句 结果排序 筛选分页结果 修改(更新) 删除 普通删除 截断表 插入查询结果 聚合函数 分组查询 这一节的内容是对表内容的增删查改,其中重点是表的查询 增加 语法: INSERT [INTO] table_name [(column [, …...
hive默认的建表格式
在 Hive 中创建表时,默认的建表语法格式如下: CREATE TABLE table_name (column1_type,column2_type,... ) ROW FORMAT DELIMITED FIELDS TERMINATED BY , STORED AS TEXTFILE;在这个语法中: CREATE TABLE table_name:指定要创建…...
配置RSUniVLM环境(自用)
首先git clone这个仓库,但是好像不太行,就直接下载下来吧 创个容器弄,容器里需要conda gpu 镜像的话 在dockerhub找到了一个:docker pull vkashyap10/llava-next 下载在了 ssh root10.12.107.240 amos123 这个机器上。等会看…...
产品经理对于电商接口的梳理||电商接口文档梳理与接入
接口梳理7个注意点总结 ①注意要测试环境和生产环境。生产上线时候要提醒研发换到生产环境调用。 ②注意必输字段和选输字段,要传入字段的含义和校验。枚举值不清楚含义的要询问对方含义,比如说单据类型字段枚举值是B2C发货单,BBC发货单&am…...
深入探索Spark-Streaming:从Kafka数据源创建DStream
在大数据处理领域,Spark-Streaming是一个强大的实时流处理框架,而Kafka作为高性能的分布式消息队列,二者结合能实现高效的数据处理。今天就来聊聊Spark-Streaming中从Kafka数据源创建DStream的相关知识。 早期,Spark-Streaming通过…...
R 语言科研绘图第 41 期 --- 桑基图-基础
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
基于STM32的汽车主门电动窗开关系统设计方案
芯片和功能模块选型 主控芯片 STM32F103C8T6:基于 ARM Cortex - M3 内核,有丰富的 GPIO 接口用于连接各类外设,具备 ADC 模块可用于电流检测,还有 CAN 控制器方便实现 CAN 总线通信。它资源丰富、成本低,适合学生进行 DIY 项目开发。按键模块 轻触按键:用于控制车窗的自…...
Spring Boot 配置处理器深度解析:元数据驱动的工程实践
Spring Boot 配置处理器深度解析:元数据驱动的工程实践 引言:为什么关注配置处理器? 在 Spring Boot 中,spring-boot-configuration-processor 是支撑“配置即文档”“配置即代码”的基础设施。它通过编译期生成结构化的配置元数…...
深入详解人工智能数学基础——概率论中的贝叶斯深度学习
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
Bandizip解压缩软件 v7.37 正式版解锁专业版
软件介绍 Bandizip 是一款专业的解压缩软件,号称解压速度最快的压缩和解压缩文件管理器。支持多核快速压缩、文件拖放,可创建带密码和多卷的压缩包,提取包括RAR/RAR5/7Z/ZIP在内30多种格式;支持WinZip、7-Zip和WinRAR及其它压缩格…...
算法笔记.spfa算法(bellman-ford算法的改进)
题目:(来源于AcWing) 给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数。 请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 impossible。 …...
HTML给图片居中
在不同的布局场景下,让 <img> 元素居中的方法有所不同。下面为你介绍几种常见的居中方式 1. 块级元素下的水平居中 如果 <img> 元素是块级元素(可以通过 display: block 设置),可以使用 margin: 0 auto 来实现水平居…...
C#中用 OxyPlot 在 WinForms 实现波形图可视化(附源码教程)
今天给大家安利一个超级实用的绘图控件库——OxyPlot,配合WinForms使用,让你轻松绘制专业级图表! 本文将手把手教你如何搭建一个简单的波形图显示窗口,完整步骤 源码解析,建议收藏! 项目搭建步骤…...
arm-linux emmc镜像备份 和 rootfs镜像备份
介绍 对于系统镜像存储介质,我们更推荐使用eMMC, eMMC具有更快的读写速度和更高的稳定系, 而SD卡会有兼容性较差的问题, 使用部分品牌部分系列的SD卡会导致系统无法启动或运行异常。 另外,安卓系统镜像无法运行在SD卡上。 注意事项 使用野火LubanCat的镜像烧录到SD卡, 只…...
opencv--图像变换
图像变换 图像滤波用于处理像素(去噪),从而改变图像质量。 图像的几何变换是指改变图像的几何位置、几何形状、几何尺寸等几何特征。 <详细了解,看opencv书> 概念 矩阵的运算 链接 齐次坐标 链接 齐次坐标就是用N1维来代表N维坐标ÿ…...
C语言基础(day0424)
目录 一. 键盘输入 1.1 grtchar() 1.2 scanf() 总结: 二. 全局变量/局部变量(函数的分类) 1.全局变量 2.局部变量 三.C语言内存模型(堆栈内存and so on ) 3.1 栈区&#x…...
前端项目搭建集锦:vite、vue、react、antd、vant、ts、sass、eslint、prettier、浏览器扩展,开箱即用,附带项目搭建教程
前端项目搭建集锦:vite、vue、react、antd、vant、ts、sass、eslint、prettier、浏览器扩展,开箱即用,附带项目搭建教程 前言:一、Vue项目下载快速通道二、React项目下载快速通道三、BrowserPlugins项目下载快速通道四、项目搭建教…...
Next.js v15 eslint 规则配置
问题 An empty interface declaration allows any non-nullish value, including literals like 0 and "". If that’s what you want, disable this lint rule with an inline comment or configure the ‘allowInterfaces’ rule option.If you want a type meanin…...
【C语言经典算法实战】:从“移动距离”问题看矩阵坐标计算
🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:AI 【前言】 在C语言算法学习与实践领域中,矩阵相关问题是极具代表性且高频出现的题型。“移动距离”问题将…...
算法题(133):二维差分
审题: 本题需要我们多次对某个矩形区域的数据加k,最后输出加完的数据 思路: 方法一:二维差分 本题涉及的是对二维的区间加同一个数的操作,且只显示一次最终结果,所以我们可以使用差分的方法 二维差分的性质…...
java kafka
安装 安装下载 导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apach…...
数据结构【树和二叉树】
树和二叉树 前言1.树1.1树的概念和结构1.2树的相关术语1.3树的表示方法1.4 树形结构实际运用场景 2.二叉树2.1二叉树的概念和结构2.2二叉树具备以下特点:2.3二叉树分类 3.满二叉树4.完全二叉树5.二叉树性质6.附:树和二叉树图示 前言 欢迎莅临姜行运主页…...
.NET代码保护混淆和软件许可系统——Eziriz .NET Reactor 7
.NET代码保护混淆和软件许可系统——Eziriz .NET Reactor 7 1、简介2、功能特点3、知识产权保护功能4、强大的许可系统5、软件开发工具包6、部署方式7、下载 1、简介 .NET Reactor是用于为.NET Framework编写的软件的功能强大的代码保护和软件许可系统,并且支持生成…...
运维打铁:Centos 7使用yum安装 Redis 5
文章目录 一、安装前信息说明二、安装 Redis三、创建 Redis 相关数据目录四、启动 Redis 服务五、修改 Redis 数据目录和端口1. 修改 Redis 配置文件 /etc/redis.conf2. 拷贝数据到数据目录并授权3. 重启 Redis 并连接访问 六、常见问题及解决办法1. Redis 安装失败2. Redis 服…...
【蓝桥杯】可分解的正整数
可分解的正整数 定义一种特殊的整数序列,这种序列由连续递增的整数组成,并满足以下条件: 序列长度至少为 3。序列中的数字是连续递增的整数(即相邻元素之差为 1),可以包括正整数、负整数或 0。 例如&…...
长城杯铁人三项初赛-REVERSE复现
前言 记录记录 1.LoginToMe int __fastcall main(int argc, const char **argv, const char **envp) {unsigned int v3; // eaxchar s[96]; // [rsp10h] [rbp-70h] BYREFint v6; // [rsp70h] [rbp-10h]int v7; // [rsp78h] [rbp-8h]int i; // [rsp7Ch] [rbp-4h]memset(s, 0, s…...