地铁扣费系统

1.算法设计规则

1、票价分为基本票价扣费票价扣费票价是在基本票价的基础上,根据票卡类型、时间段进行特殊计算得到的(也有可能等于基本票价),是扣费操作时需要从卡上扣除的金额。

2、基本票价计算规则:按进站点与出站点之间的最短里程分级计算:

  • 3千米(包含3千米,但不包括0)以内:2元。
  • 3千米 至 5千米(包含5千米):3元。
  • 5千米 至 10千米(包含10千米):4元。
  • 10千米以上:5元。

 

3、进出站为同一站点的,则按进出站时长计算:

(1)小于等于30分钟:

单程票:票卡面值作为扣费票价

其他卡:0元,且不受任何时间段的限制,即直接作为扣费票价

(2)大于30分钟:

单程票:(票卡面值,3元)中“最大值”作为扣费票价

其他卡:3元,且不享受任何时间段的优惠,即直接作为扣费票价

 

4、扣费票价计算规则1:按照各种票卡的类型计算:

  • 普通卡(C):正常时间段以基本票价作为扣费票价;特殊时间段收费参见“5、扣费票价计算规则2”。
  • 老年卡(B):正常时间段以基本票价的9折作为扣费票价(如出现小数,则向下取整);特殊时间段收费参见“5、扣费票价计算规则2”。
  • 单程票(A):即一次性车票,任何时间段不享受任何优惠,直接以(票卡面值基本票价)中“最大值”作为扣费票价

 

5、扣费票价计算规则2(不涉及单程票)按照进站时间的不同区间计算:

  • 进站时间为[7:00,9:00)、[16:30,18:30)时,无任何优惠,所有类型的交通卡(单程票除外)以基本票价作为扣费票价
  • 进站时间为[10:00,11:00)、[15:00,16:00)时,所有类型的交通卡(单程票除外)以基本票价的5折作为扣费票价(如出现小数,则向下取整)。
  • 参数名称

    参数说明

    类型

    取值范围

    示例

    卡号

    卡号

    整数

    0 ~ 9,0为通配卡号,只在查询(q)命令中可用。

    5

    卡类型

    票卡的类型:

    单程票/老年卡/普通卡

    字符

    A(a),B(b),C(c)

    B,b

    金额()

    卡扣费前余额

    卡扣费后余额

    扣费金额

    (遇小数向下取整)

    整数

    0 ~ 999

    888

    时间

    进站时间

    出站时间

    查询起始时间

    查询终止时间

    HH:MM

    00:00~23:59

    注意命令输入格式:

    合法:09:05

    非法:9:05、09:5、9:5

    站点名称

    进站站点名称

    出站站点名称

    字符串

    共六个站名:S1~S6

    S5

 

2.扣费操作

命令格式:c 卡号 卡类型 卡扣费前余额 进站时间 进站站点名称 出站时间 出站站点名称

功能说明

1、按照输入条件和“1.2算法设计规则”,对票卡进行扣费操作(减去扣费票价)。

2、输出信息调用系统已提供的接口完成(接口参见“3.4 API说明”)。

3、如果:进站时间 > 出站时间,则不扣费,输出参数错误。

编号

用例标题

测试步骤

预期输出

1

请求扣费命令参数非法

C 9 C 20 12:05 S1 11:20 S4

E02:参数错误(时间关系错误)

4、如果从进站点到出站点之间的路线不存在,则不扣费,输出无效路线,并显示“卡扣费余额”(“卡扣费后余额”等于“卡扣费前余额”)。

编号

用例标题

测试步骤

预期输出

1

无效线路,扣费失败

C 3 C 85 09:05 S3 10:20 S8

I10:扣费失败(无效路线)

<卡号=3><余额=85>

注意:3/4同时发生时,以3输出优先。

5、如果“卡扣费余额”大于等于扣费票价,则扣费,输出扣费成功,并显示“卡扣费余额”。

注意:如果单程票面值大于等于扣费票价,则按票面值扣费。例如:单程票面值5元,应收票价为3元,则本次扣费为5元,余额为0。

编号

用例标题

测试步骤

预期输出

1

正常扣费成功

C 1 A 3 07:00 S4 08:25 S3

I11:扣费成功

<卡号=1><余额=0>

6、不是单程票的,扣费成功后,如果“卡扣费余额”小于20元,则输出余额过低,并显示“卡扣费余额”。

编号

用例标题

测试步骤

预期输出

1

正常扣费成功,卡内余额偏低

C 4 B 20 10:05 S1 11:20 S4

I12:扣费成功(余额过低)

<卡号=4><余额=18>

7、如票“卡扣费余额”不足以扣费,则不扣费,输出扣费失败(余额不足),并显示“卡扣费余额”(“卡扣费后余额”等于“卡扣费前余额”)。

编号

用例标题

测试步骤

预期输出

1

余额不足,扣费失败

C 4 B 1 15:00 S1 15:55 S4

I13:扣费失败(余额不足)

<卡号=4><余额=1>

8、调用系统已提供的写日志接口(接口参见“3.4 API说明”),将“地铁乘车记录”记录到内存日志中,日志记录中包含如下字段:

<卡号><进站时间HH:MM><进站站点名称><出站时间HH:MM><出站站点名称><实际扣款金额><扣费是否成功>

注意:

  • 请求扣费操作(c/C)所有(无论是否成功或失败)输出返回时,均要求要记录日志。
  • 仅请求扣费操作(c/C)才记录日志,其他任何操作(查询扣费日志(q/Q)、初始化(r/R))均要求不要记录日志。
  • 系统最多记录10条日志,超过的系统会自动丢弃,程序初始化(或复位(r/R))后日志记录自动清空,自动从头记录。

约束说明:无。

void opChargeProc(TravelInfo_ST* pstTravelInfo)
{
	enter_time=pstTravelInfo->nInHour*60+pstTravelInfo->nInMinute;
	out_time=pstTravelInfo->nOutHour*60+pstTravelInfo->nOutMinute;
	//进站时间 > 出站时间
	RetCode_EN enOpFlg=RET_ERROR;
	if(pstTravelInfo->nInHour>pstTravelInfo->nOutHour)
	{
		apiPrintErrInfo(E02);
	return;
	}
	if(pstTravelInfo->nInHour==pstTravelInfo->nOutHour&&pstTravelInfo->nInMinute>pstTravelInfo->nOutMinute)
	{
		apiPrintErrInfo(E02);
	return;
	}
	//从进站点到出站点之间的路线不存在
	
	if(apiGetDistanceBetweenTwoStation(pstTravelInfo->sInStation,pstTravelInfo->sOutStation,distance)==RET_ERROR)
	{
		apiPrintOpStatusInfo(I10,pstTravelInfo->nCardNo,pstTravelInfo->nCardMoney);
	return;
	}
	//如果"卡扣费前余额"大于等于扣费票价,则扣费,输出扣费成功,并显示"卡扣费后余额"
	//基础票价
	if(0<*distance&&*distance<=3)
		baseprice=2;
	else if(3<*distance&&*distance<=5)
		baseprice=3;
	else if(5<*distance&&*distance<=10)
		baseprice=4;
	else if(*distance>10)
		baseprice=5;
	//扣费票价
	//int fee=pstTravelInfo->nCardMoney;//未扣费前卡内余额
	//card_blance=fee-feeprice;//扣费后卡内余额
	distance_time=apiTimeDiff(pstTravelInfo->nOutHour,pstTravelInfo->nOutMinute,pstTravelInfo->nInHour,pstTravelInfo->nInMinute);
	//同一站点
	if(*distance==0)
	{
		if(distance_time<=30)//小于等于30分钟
		{
			if(pstTravelInfo->enCardType==CARDTYPE_A)//单程票
			{
				feeprice=pstTravelInfo->nCardMoney;
			}
			else//其他卡
			{
				feeprice=0;
			}
		}
		if(distance_time>30)//大于30分钟
		{
			if(pstTravelInfo->enCardType==CARDTYPE_A)//单程票
			{
				if(pstTravelInfo->nCardMoney>3)
				{
					feeprice=pstTravelInfo->nCardMoney;

				}
				else
				{
					feeprice=3;
				}
			}
			else//其他卡
			{
				feeprice=3;
			}
		}
		
	}
	//不同站点
	if(*distance!=0)
	{
		if(pstTravelInfo->enCardType==CARDTYPE_A)
		{
			//基本票价大于票卡面值
			if(baseprice>pstTravelInfo->nCardMoney)
			{
				feeprice=baseprice;
			}
			//基础票价小于票卡面值
			else
			{
				feeprice=pstTravelInfo->nCardMoney;
			}
		
	
		}
		//老年卡
		if(pstTravelInfo->enCardType==CARDTYPE_B)
		{
			//进站时间[7:00,9:00)、[16:30,18:30)
			if((enter_time>=7*60&&enter_time<9*60)||(enter_time>=16*60+30&&enter_time<18*60+30))
			{
				feeprice=baseprice;
			}
			//进站时间为[10:00,11:00)、[15:00,16:00)
			else if((enter_time>=10*60&&enter_time<11*60)||(enter_time>=15*60&&enter_time<16*60))
			{
		
				feeprice=int(baseprice*0.5);
				
			}
			//正常时间
			else
			{
				feeprice=int(baseprice*0.9);
			}
		}
		//普通卡
		if(pstTravelInfo->enCardType==CARDTYPE_C)
		{
			//进站时间[7:00,9:00)、[16:30,18:30)
			if((enter_time>=7*60&&enter_time<9*60)||(enter_time>=16*60+30&&enter_time<18*60+30))
			{
				feeprice=baseprice;
			}
			//进站时间为[10:00,11:00)、[15:00,16:00)
			if((enter_time>=10*60&&enter_time<11*60)||(enter_time>=15*60&&enter_time<16*60))
			{
				feeprice=int(baseprice*0.5);
			}
			//正常时间
			else
			{
				feeprice=baseprice;
			}
		}
	}
	int fee=pstTravelInfo->nCardMoney;//未扣费前卡内余额
	card_blance=fee-feeprice;//扣费后卡内余额
	//5."卡扣费前余额"大于等于扣费票价
	if(fee>=feeprice)
	{
		//apiPrintOpStatusInfo(I11,pstTravelInfo->nCardNo,card_blance);
		//return;
	
	//"卡扣费后余额"小于20元
		enOpFlg=RET_OK;
		if(card_blance>=0&&card_blance<20)
		{
			//单程票
			if(pstTravelInfo->enCardType==CARDTYPE_A)
			{
				apiPrintOpStatusInfo(I12,pstTravelInfo->nCardNo,card_blance);
				return;
			}	
			//其他卡
			if(pstTravelInfo->enCardType==CARDTYPE_B||pstTravelInfo->enCardType==CARDTYPE_C)
				{
					apiPrintOpStatusInfo(I12,pstTravelInfo->nCardNo,card_blance);
					return;
				}
		}
	  else if(card_blance>=20)//"卡扣费后余额"大于等于20元
	  {
		  	if(pstTravelInfo->enCardType==CARDTYPE_B||pstTravelInfo->enCardType==CARDTYPE_C)//其他卡
			{
				//printf("%d\n",feeprice);
				apiPrintOpStatusInfo(I11,pstTravelInfo->nCardNo,card_blance);
				return;
			}
	  }
	}
	//"卡扣费前余额"不足以扣费
	else 
	{
		apiPrintOpStatusInfo(I13,pstTravelInfo->nCardNo,fee);
		return;
	}
	apiWriteLog(feeprice,pstTravelInfo,enOpFlg);
	//日志记录

}

 

 

 

 

你可能感兴趣的:(数据库,服务器,c++,数据结构)