本代码针对某公司笔试题而来,没有经过验证,请各位大侠捉虫
/*
* 网吧收银计算费用的类对象及方法
* 规则:
* 1. 上午八点到中午12点为2元一小时,下午从12点到晚上10点为3元一小时
* 半小时计费一次,不足半小时按半小时计算
* 2. 包夜从晚上10点到早上8点,一次性收费10元
* 要求:
* 1. 时间节点及费用可配置
* 2. 实现基本的对象类及算法
* 说明:
* 1. 本算法,按时间顺序,每半小时结算一次,包夜时段内直接跳过循环,
* 到包夜结束一次性计费。
* 2. 本算法支持跨天多天连续上网的计费
*/
using System;
namespace Model
{
/// <summary>
/// 上机记录类
/// </summary>
public class PlayRecord
{
#region 属性
/// <summary>
/// 上机记录编号,自增长
/// </summary>
public int id { get; set; }
/// <summary>
/// 玩家身份证号码
/// </summary>
public int IDCard { get; set; }
/// <summary>
/// 电脑编号
/// </summary>
public int Code { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public DateTime Start { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime End { get; set; }
/// <summary>
/// 押金、预付费、保证金(单位:分)
/// </summary>
public int Deposit { get; set; }
/// <summary>
/// 金额(单位:分)
/// </summary>
public int Amount { get; set; }
/// <summary>
/// 状态
/// 0:开机,1:结账,2:异常
/// </summary>
public int Status { get; set; }
/// <summary>
/// 备注,说明
/// </summary>
public string Description { get; set; }
#endregion
#region 拓展属性(便于通过配置文件灵活配置)
/// <summary>
/// 上午上机,每半小时(30分钟)收费金额(单位:分)
/// </summary>
public static int fNum = 100;
/// <summary>
/// 下午上机,每半小时(30分钟)收费金额(单位:分)
/// </summary>
public static int aNum = 150;
/// <summary>
/// 包夜上机,一次性收费金额(单位:分)
/// </summary>
public static int eNum = 1000;
/// <summary>
/// 包夜起点时间的小时数
/// </summary>
public static int eHour = 22;
/// <summary>
/// 上午起点时间的小时数
/// </summary>
public static int fHour = 8;
/// <summary>
/// 下午起点时间的小时数
/// </summary>
public static int aHour = 12;
#endregion
#region 方法
/// <summary>
/// 添加一条上机记录
/// </summary>
/// <param name=""></param>
public static bool Add(PlayRecord record)
{
//数据业务代码
return true;
}
/// <summary>
/// 根据身份证号码查找当前上机记录
/// </summary>
/// <param name="IDCard"></param>
/// <returns></returns>
public static PlayRecord Find(string IDCard)
{
//数据业务代码
return new PlayRecord();
}
/// <summary>
/// 根据身份证号码结账
/// </summary>
/// <param name="IDCard"></param>
/// <returns></returns>
public static int checkout(string IDCard)
{
#region 数据、变量初始化及校验
var cnt = 0; //声明上机金额变量
var re = Find(IDCard);//查找上机记录
if(re == null)
{//没有找到上机记录,返回零值
return 0;
}
var st = re.Start;//上机时间
var now = DateTime.Now;
//结账时间精确到分钟
var et = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0);
#endregion
#region 起点时间归整
if (st.Hour >= 0 && st.Hour < fHour)//包夜时段凌晨上机
{
cnt += eNum; //包夜费用统一10元
//时间移动至早上包夜结束时间
st = new DateTime(st.Year, st.Month, st.Day, fHour, 0, 0);
}
if (st.Hour >= eHour && st.Hour < 24)//包夜时段深夜上机
{
cnt += eNum;//包夜费用统一10元
st = st.AddDays(1);//天数加一
//时间移动至第二天早上包夜结束时间
st = new DateTime(st.Year, st.Month, st.Day , fHour, 0, 0);
}
if (st.Hour == (aHour - 1) && st.Minute > 30)//下午上机时间前半个小时内上机
{
cnt += fNum; //收取一元
//时间移动至中午12点整计费调整点
st = new DateTime(st.Year, st.Month, st.Day, aHour, 0, 0);
}
if (st.Hour == (eHour - 1) && st.Minute > 30)//包夜前半个小时内上机
{
cnt += aNum; //收取一元五角
//时间移动至晚上10点整计费调整点
st = new DateTime(st.Year, st.Month, st.Day, eHour, 0, 0);
}
#endregion
#region 中间时间,按半小时一次,循环处理
st = st.AddMinutes(30);
while (st <= re.End)
{
if (st.Hour >= 0 && st.Hour < fHour && st.Hour >= eHour && st.Hour < 24)
{//包夜时段,直接跳过
continue;
}
else if (st.Hour == fHour && st.Minute == 0)
{//包夜结账时点,一次性计费
cnt += eNum;
}
else if ((st.Hour >= fHour && st.Hour < aHour) || (st.Hour == aHour && st.Minute == 0))
{//上午时段,半小时一元
cnt += fNum;
}
else if ((st.Hour >= aHour && st.Hour < eHour) || (st.Hour == eHour && st.Minute == 0))
{//下午时段,半小时一元五角
cnt += aNum;
}
st = st.AddMinutes(30);
}
#endregion
#region 末端时间处理
if(et != st)//下机时间不在半小时的整点时间
{
if ((st.Hour >= 0 && st.Hour < fHour) || (st.Hour > eHour && st.Hour < 24))//包夜时段下机
{
cnt += eNum;//包夜费用统一10元
}
if (st.Hour > fHour && st.Hour < aHour)//上午时段下机
{
cnt += fNum; //收取一元
}
if (st.Hour > aHour && st.Hour < eHour)//下午下机
{
cnt += aNum; //收取一元五角
}
}
#endregion
//返回上机总金额(精确到分)
return cnt - re.Deposit;
}
#endregion
}
}