機房重構之餘額實時判斷
機房重構經過近一個月的努力,終於成型了!在優化的過程中,注意到非常多的問題,今天就來總結一下上機使用者的餘額實時判斷。
一、有什麼用
大家應該對網咖的收費系統有所瞭解,如果你上機的時候充值了5元,網咖的收費是每小時5元,也就是你的金錢只可以上機一個小時,當快到一個小時的時候,系統會提醒你的餘額不足,讓你充值,如果不充值,就會自動下機!同理機房收費系統也需要同樣的機制,要不然,老闆會賠錢的!哈哈!
說說之前的版本,沒有這個判斷機制,一個卡片裡面有5元(大於最低金額),上機之後,如果使用者不下機,便可以一直上機,當使用者下機之後,會發現欠下鉅額的費用,這種機制已經不符合實際情況了。
二、思路
1、要實現實時的判斷使用者的餘額,那就需要一個計算使用者餘額的方法。
2、方法裡要注意對於不同型別的使用者,採用不同的收費政策。固定使用者和臨時使用者的收費策略不一樣。
3、這個方法要根據時間的間隔自動執行計算,並實時更新到使用者的餘額中。採用timer控制元件。
4、計算出使用者的實時餘額後,還不行!還需要一個判斷機制,判斷使用者的餘額是否充足。也就是將餘額的不同切位幾個不同的狀態,比如大於10元的狀態,不進行提示,不足10元的狀態,提醒使用者充值,然後不足5元的狀態,讓使用者下機。這種在不同的狀態間轉換的情況,讓我突然想起了設計模式中的狀態模式。
2、結合設計模式中的狀態模式,很好的對使用者的餘額進行判斷,並進行不同狀態的提示!很方便!
三、實現
1、首先需要封裝一個計算餘額的方法
//定義計算固定使用者花費金額的方法,括號裡的是需要傳進來的引數,也就是基本收據中的引數。因為結算需要基本資料中的資料
public double RegularUser(out double casttime, double Rate,double PrepareTime,double unitTime,DateTime StartDate, DateTime StartTime, DateTime EndDate, DateTime EndTime)
{
double castcash=0;//定義花費金額引數,預設為0
TimeSpan d1 = EndDate.Subtract(StartDate);//計算開始上機日期與下機日期間相隔的時間
TimeSpan t1 = EndTime.Subtract(StartTime);//計算開始上機時間與下機時間相隔的時間
double z1 = d1.TotalMinutes + t1.TotalMinutes;//將兩個時間加起來,此時為總分鐘數
casttime = Math.Ceiling(z1 / unitTime);//根據基本資料中的計算週期,計算幾個週期
if (z1<=PrepareTime)//如果上機時間小於準備時間,就不收費
{
castcash = 0;
}
else//如果上機時間大於準備時間,計算
{
castcash =Rate * Math.Ceiling(z1 / unitTime);
//ceiling函式是計算除法的一種,如果有餘數,則不管餘數多少都會近1.
}
return castcash;//返回計算好的消費時間
}
//臨時使用者的同理
public double CasualUser(out double casttime,double tmpRate, double PrepareTime, double unitTime, DateTime StartDate, DateTime StartTime, DateTime EndDate, DateTime EndTime)
{
double castcash = 0;
TimeSpan d1 = EndDate.Subtract(StartDate);
TimeSpan t1 = EndTime.Subtract(StartTime);
double z1 = d1.TotalMinutes + t1.TotalMinutes;
casttime = Math.Ceiling(z1 / unitTime);
if (z1 < PrepareTime)
{
castcash = 0;
}
else
{
castcash = tmpRate * Math.Ceiling(z1 / unitTime);
}
return castcash;
}
2、狀態模式的建立
計算餘額的方法已經封裝好了,接下來建立狀態模式。
PS:我是按照設計模式的書,先把狀態模式基本的程式碼敲出來了,然後根據自己的需要進行的改變,這也能看出來,自己對狀態模式的應用不夠熟悉。
public abstract class State//建立一個抽象的狀態類
{
public abstract void Checkbalance(Context balance,int cardno,double limitcash);//設定抽象方法和所需要的引數及其型別
}
public class Context//建立了一個環境類
{
private State current;//封裝欄位
private double balance;//這個用來接收傳進來的金額
private double limitcash;//接收傳進來的限制金額
private int cardno;//傳進來的卡號
public double Balance { get => balance; set => balance = value; }
public int Cardno { get => cardno; set => cardno = value; }
public double Limitcash { get => limitcash; set => limitcash = value; }
public void SetState(State s)//設定狀態的方法
{
current = s;
}
public void Checkbalance()//狀態模式中狀態轉換時執行的方法
{
current.Checkbalance(this,cardno,Limitcash);//接收當前的狀態,卡號,限制金額
}
}
class ConcreteStateC : State//具體的狀態類C
{
//金額大於最低限制金額limitcash+4
public override void Checkbalance(Context balance, int cardno, double limitcash)
{
double limitcashp = limitcash + 4;
if (balance.Balance >limitcashp)//大於的話,不執行操作
{
}
else
{
balance.SetState(new ConcreteStateA());如果小於這個值,則轉入A狀態
balance.Checkbalance();
}
}
}
public class ConcreteStateA:State//具體的狀態類A
{
//金額少於最小限制金額+4元,則提醒使用者充值!
public override void Checkbalance(Context balance,int cardno,double limitcash)
{
double limitcashp = limitcash + 4;
if (balance.Balance<=limitcashp&&balance .Balance>limitcash)
{
throw new Exception(cardno + "餘額已經不足"+limitcashp+"元,請充值!");
}
else
{
balance.SetState(new ConcreteStateC());
balance.Checkbalance();
}
}
}
public class ConcreteStateB : State
{
public override void Checkbalance(Context balance,int cardno, double limitcash)
{
if (balance.Balance <= limitcash)
{
throw new Exception(cardno + "餘額已經不足"+limitcash+"元,即將下機!");
}
else
{
balance.SetState(new ConcreteStateA());
balance.Checkbalance();
}
}
}
3、在客戶端中實現。
要想將這個實現,需要你已經完成了下機!如果你已經完成了下機的方法,並建立了相應的層。接下來就開始實現。
首先需要新增一個timer控制元件
在窗體的load事件中新增一下程式碼。
timer1.Interval = 60000;//計時器的計算時間間隔,這裡設定1分鐘,也就每隔一分鐘觸發一次事件
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
private void timer1_Tick(object sender, EventArgs e)
{
//例項化基本資料層,查詢基本資料
Entity.OnlineInfo line = new Entity.OnlineInfo();
Entity.BasicData basic = new Entity.BasicData();
Facade.Basicdatafacade facade1 = new Facade.Basicdatafacade();
DataTable res = facade1.Basicdatacheck();
//將基本資料複製給對應引數
double Rate = double.Parse(res.Rows[0][0].ToString());
double tmpRate = double.Parse(res.Rows[0][1].ToString());
double unitTime = double.Parse(res.Rows[0][2].ToString());
double PrepareTime = double.Parse(res.Rows[0][3].ToString());
double limitCash = double.Parse(res.Rows[0][4].ToString());
Facade.Loginandexitfacade facade = new Facade.Loginandexitfacade();
//查詢online表,現在是否有上機的學生
DataTable re = facade.Loginandexitpropro();
if (re.Rows.Count != 0)//如果有執行此步
{
//獲取現在的時間作為下機時間日期
DateTime Enddate = DateTime.Parse(DateTime.Now.ToShortDateString().ToString());
DateTime Endtime = DateTime.Parse(DateTime.Now.ToShortTimeString());
foreach (DataRow dt in re.Rows)
{
Downmethos methos = new Downmethos();
if (dt["type"].ToString().Trim() == "固定使用者")
{
double casttime;
double castcash = methos.RegularUser(out casttime, Rate, PrepareTime, unitTime, Startdate, Starttime, Enddate, Endtime);
Entity.CardInfo card = new Entity.CardInfo();
Facade.RegisterFacade facade2 = new Facade.RegisterFacade();
card.Cardno = int.Parse(dt[0].ToString());
DateTime Startdate = DateTime.Parse(dt[2].ToString());
DateTime Starttime = DateTime.Parse(dt[3].ToString());
DataTable resu = facade2.checkcardno(card);
double Cash = double.Parse(resu.Rows[0][2].ToString());
double finalcash = Cash - castcash;
//更新實餘額
Facade.Recharegefacade f = new Facade.Recharegefacade();
card.Cash = finalcash;
card.Ischeck = "未結賬";
f.Rechargecard(card);
try
{
Context c = new Context();
ConcreteStateB b = new ConcreteStateB();
c.SetState(b);
c.Cardno = int.Parse(dt[0].ToString());
c.Balance = finalcash;
c.Limitcash = int.Parse(res.Rows[0][4].ToString());
c.Checkbalance();
}
catch (Exception ex)
{
DialogResult resut = MessageBox.Show(ex.Message, "餘額提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
//Entity.sState state = new Entity.sState();
//Facade.statefacade sta = new Facade.statefacade();
//DataTable states = sta.sState();
//if (states.Rows[0][0].ToString().Trim() == "正在維護")
//{
// DialogResult result = MessageBox.Show("系統正在維護,您即將下線!", "系統維護", MessageBoxButtons.OK, MessageBoxIcon.Error);
// if (result == DialogResult.OK)
// {
if (finalcash <= limitCash)
{
Entity.downline downline = new Entity.downline();
Facade.DownLinefacade faca = new Facade.DownLinefacade();
downline.Cardno = int.Parse(dt[0].ToString());
downline.Consumetime = casttime;
downline.Consume = castcash;
downline.Offdate = DateTime.Parse(DateTime.Now.ToShortDateString());
downline.Offtime = DateTime.Parse(DateTime.Now.ToShortTimeString());
downline.Status = "true";
downline.Cash = finalcash;
downline.Computer = System.Environment.MachineName;
downline.Ischeck = "未結賬";
faca.downLine(downline);
}
else
{
}
}
}
else
{
double casttime;
double castcash = methos.CasualUser(out casttime, Rate, PrepareTime, unitTime, Startdate, Starttime, Enddate, Endtime);
Entity.CardInfo card = new Entity.CardInfo();
Facade.RegisterFacade facade2 = new Facade.RegisterFacade();
card.Cardno = int.Parse(dt[0].ToString());
DataTable resu = facade2.checkcardno(card);
double Cash = double.Parse(resu.Rows[0][2].ToString());
double finalcash = Cash - castcash;
//更新實餘額
Facade.Recharegefacade f = new Facade.Recharegefacade();
card.Cash = finalcash;
card.Ischeck = "未結賬";
f.Rechargecard(card);
try
{
Context c = new Context();
ConcreteStateB b = new ConcreteStateB();
c.SetState(b);
c.Cardno = int.Parse(dt[0].ToString());
c.Balance = finalcash;
c.Limitcash = int.Parse(res.Rows[0][4].ToString());
c.Checkbalance();
}
catch (Exception ex)
{
DialogResult resut = MessageBox.Show(ex.Message, "餘額提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
if (finalcash <= limitCash)
{
Entity.sState state = new Entity.sState();
Facade.statefacade sta = new Facade.statefacade();
DataTable states = sta.sState();
Entity.downline downline = new Entity.downline();
Facade.DownLinefacade faca = new Facade.DownLinefacade();
downline.Cardno = int.Parse(dt[0].ToString());
downline.Consumetime = casttime;
downline.Consume = castcash;
downline.Offdate = DateTime.Parse(DateTime.Now.ToShortDateString());
downline.Offtime = DateTime.Parse(DateTime.Now.ToShortTimeString());
downline.Status = "true";
downline.Cash = finalcash;
downline.Computer = System.Environment.MachineName;
downline.Ischeck = "未結賬";
faca.downLine(downline);
//lblcastcash.Text = castcash.ToString();
//lblcasttime.Text = casttime.ToString();
//lbldowndate.Text = DateTime.Now.ToShortDateString();
//lbldowntime.Text = DateTime.Now.ToShortTimeString();
//}
}
}
}
}
}
}
未完,還將更改!
相關文章
- C#機房重構-實時檢視上機餘額(狀態模式)C#模式
- 機房重構總結
- C#機房重構之註冊窗體C#
- 機房重構七層登陸之錯誤集錦
- 機房IT運維工作者如何在工作之餘提升自身實力?運維
- C#機房重構-如何一鍵清空C#
- 通達信金股分時分時副圖判斷機構買盤掌握精準介入時機
- js 判斷eventTarget 重複新增JS
- lisp 判斷時間Lisp
- js判斷時間JS
- 銀行核心業務系統之雙餘額機制-實戰片
- 怎麼判斷靠譜的it培訓機構
- 判斷金額的正規表示式
- python之判斷語句Python
- 11.9 python之判斷語句Python
- ACM之判斷迴文數ACM
- dataset 判斷整列是否有重複,找出重複資料
- JavaScript分支結構(判斷結構)使用教程JavaScript
- IDC機房之UPS
- 判斷字元是否重複正規表示式字元
- 【重溫基礎】18.相等性判斷
- js判斷手機系統JS
- mysql 插入時帶判斷條件MySql
- Python之判斷迴圈語句Python
- js之普通/高效判斷質數JS
- document API之visibilitychange事件:判斷頁API事件
- Js之設定日期時間 判斷日期是否在範圍內JS
- 向HashSet插入自定義物件判斷是否重複物件
- 一次專案程式碼重構-使用spring容器幹掉條件判斷Spring
- 如何判斷等保測評機構有資質?符合要求?
- JavaScript 判斷 iPhone X Series 機型JavaScriptiPhone
- ionic-判斷是裝置時手機還是平板(iPad,tablet)iPad
- 平穩突破單機房容量瓶頸,B站離線多機房架構實踐架構
- 12.python流程控制之if判斷Python
- 演算法之複雜度判斷演算法複雜度
- 怎麼判斷dns汙染,怎麼判斷dns汙染,具體判斷方法DNS
- 函式實現閏年判斷函式
- JS的判斷語句:判斷、迴圈JS