using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; namespace 水電瓦斯抄錶.Models { public class MeterItem { public string ItemId { get; set; } public string Shop { get; set; } public string Type { get; set; } public string Loc { get; set; } public string Meter { get; set; } public string Month { get; set; } public decimal LastVal { get; set; } public decimal? NowVal { get; set; } public string Photo { get; set; } } public class UserModel { public int Id { get; set; } public string Name { get; set; } public string Pass { get; set; } public string Role { get; set; } } public class MeterDbHelper { private static string ConnStr => ConfigurationManager.ConnectionStrings["BitanDb"].ConnectionString; private SqlConnection GetConn() => new SqlConnection(ConnStr); // ── 使用者 ────────────────────────────────────────── public UserModel GetUser(string name) { using (var conn = GetConn()) using (var cmd = new SqlCommand( "SELECT Id,Name,Pass,Role FROM Users WHERE Name=@n", conn)) { cmd.Parameters.AddWithValue("@n", name); conn.Open(); using (var r = cmd.ExecuteReader()) { if (!r.Read()) return null; return new UserModel { Id = (int)r["Id"], Name = r["Name"].ToString(), Pass = r["Pass"].ToString(), Role = r["Role"].ToString() }; } } } public List GetAllUsers() { var list = new List(); using (var conn = GetConn()) using (var cmd = new SqlCommand( "SELECT Id,Name,Pass,Role FROM Users ORDER BY CASE Role WHEN 'pending' THEN 0 ELSE 1 END, Id", conn)) { conn.Open(); using (var r = cmd.ExecuteReader()) while (r.Read()) list.Add(new UserModel { Id = (int)r["Id"], Name = r["Name"].ToString(), Pass = r["Pass"].ToString(), Role = r["Role"].ToString() }); } return list; } public bool AddUser(string name, string pass) { using (var conn = GetConn()) using (var cmd = new SqlCommand( "INSERT INTO Users(Name,Pass,Role) VALUES(@n,@p,'pending')", conn)) { cmd.Parameters.AddWithValue("@n", name); cmd.Parameters.AddWithValue("@p", pass); conn.Open(); return cmd.ExecuteNonQuery() > 0; } } public bool UpdateUserRole(int id, string role) { using (var conn = GetConn()) using (var cmd = new SqlCommand( "UPDATE Users SET Role=@r WHERE Id=@id", conn)) { cmd.Parameters.AddWithValue("@r", role); cmd.Parameters.AddWithValue("@id", id); conn.Open(); return cmd.ExecuteNonQuery() > 0; } } public bool DeleteUser(int id) { using (var conn = GetConn()) using (var cmd = new SqlCommand("DELETE FROM Users WHERE Id=@id", conn)) { cmd.Parameters.AddWithValue("@id", id); conn.Open(); return cmd.ExecuteNonQuery() > 0; } } // ── 抄表資料 ──────────────────────────────────────── public List GetByMonth(string month) { var list = new List(); using (var conn = GetConn()) using (var cmd = new SqlCommand( "SELECT ItemId,Shop,Type,Loc,Meter,Month,LastVal,NowVal,Photo FROM MeterItems WHERE Month=@m ORDER BY Id", conn)) { cmd.Parameters.AddWithValue("@m", month); conn.Open(); using (var r = cmd.ExecuteReader()) while (r.Read()) list.Add(MapItem(r)); } return list; } public void SaveItems(string month, List items) { using (var conn = GetConn()) { conn.Open(); using (var tx = conn.BeginTransaction()) { // 刪除該月舊資料再重新插入 var del = new SqlCommand("DELETE FROM MeterItems WHERE Month=@m", conn, tx); del.Parameters.AddWithValue("@m", month); del.ExecuteNonQuery(); foreach (var item in items) { var ins = new SqlCommand(@" INSERT INTO MeterItems(ItemId,Shop,Type,Loc,Meter,Month,LastVal,NowVal,Photo,UpdatedAt) VALUES(@id,@shop,@type,@loc,@meter,@month,@last,@now,@photo,GETDATE())", conn, tx); ins.Parameters.AddWithValue("@id", item.ItemId ?? ""); ins.Parameters.AddWithValue("@shop", item.Shop ?? ""); ins.Parameters.AddWithValue("@type", item.Type ?? ""); ins.Parameters.AddWithValue("@loc", (object)item.Loc ?? DBNull.Value); ins.Parameters.AddWithValue("@meter", (object)item.Meter ?? DBNull.Value); ins.Parameters.AddWithValue("@month", month); ins.Parameters.AddWithValue("@last", item.LastVal); ins.Parameters.AddWithValue("@now", (object)item.NowVal ?? DBNull.Value); ins.Parameters.AddWithValue("@photo", (object)item.Photo ?? DBNull.Value); ins.ExecuteNonQuery(); } tx.Commit(); } } } public void DeleteItemAllMonths(string itemId, string type) { using (var conn = GetConn()) using (var cmd = new SqlCommand( "DELETE FROM MeterItems WHERE ItemId=@id AND Type=@t", conn)) { cmd.Parameters.AddWithValue("@id", itemId); cmd.Parameters.AddWithValue("@t", type); conn.Open(); cmd.ExecuteNonQuery(); } } public void DeleteMonth(string month) { using (var conn = GetConn()) using (var cmd = new SqlCommand("DELETE FROM MeterItems WHERE Month=@m", conn)) { cmd.Parameters.AddWithValue("@m", month); conn.Open(); cmd.ExecuteNonQuery(); } } // ── 抄錄日期 ──────────────────────────────────────── public string GetRecordDate(string month) { using (var conn = GetConn()) using (var cmd = new SqlCommand( "SELECT RecordDate FROM DateLog WHERE Month=@m", conn)) { cmd.Parameters.AddWithValue("@m", month); conn.Open(); var val = cmd.ExecuteScalar(); return val == null ? "" : Convert.ToDateTime(val).ToString("yyyy-MM-dd"); } } public void SaveRecordDate(string month, string date) { using (var conn = GetConn()) using (var cmd = new SqlCommand(@" MERGE DateLog AS t USING (SELECT @m AS Month, @d AS RecordDate) AS s ON t.Month = s.Month WHEN MATCHED THEN UPDATE SET RecordDate=s.RecordDate WHEN NOT MATCHED THEN INSERT(Month,RecordDate) VALUES(s.Month,s.RecordDate);", conn)) { cmd.Parameters.AddWithValue("@m", month); cmd.Parameters.AddWithValue("@d", date); conn.Open(); cmd.ExecuteNonQuery(); } } private MeterItem MapItem(IDataReader r) => new MeterItem { ItemId = r["ItemId"].ToString(), Shop = r["Shop"].ToString(), Type = r["Type"].ToString(), Loc = r["Loc"] == DBNull.Value ? "" : r["Loc"].ToString(), Meter = r["Meter"] == DBNull.Value ? "" : r["Meter"].ToString(), Month = r["Month"].ToString().Trim(), LastVal = Convert.ToDecimal(r["LastVal"]), NowVal = r["NowVal"] == DBNull.Value ? (decimal?)null : Convert.ToDecimal(r["NowVal"]), Photo = r["Photo"] == DBNull.Value ? "" : r["Photo"].ToString() }; } }