目录
会海跳槽
票务开启
漂泊在外的日子
未完待续
会海跳槽
随着时刻表的出炉,意味着大规模的界面开发逐步进入正规。项目组里陆陆续续引进了8个人,最多的时候,同时有10个人在现场。“松工”为我们准备的办公室坐的满满当当,另外在他的办公室里也开辟了一个小会议桌,专门负责演示最新的系统界面。
这个时候,“会海”反而提出了离职请求。但我的记忆是比较模糊的,大概当时太专注于项目,而且“小娇”、“小光”、“小魏”,最初项目组的几个人,陆陆续续都因为各种各样的原因离职了。人员的变动对我来说已经是日常行为了。
不太记得“会海”离职的时候都说了些什么,当时公司也没有离职面谈的流程,只记得“会海”还是很客气,还是从其他同事哪里获悉,“会海”认为“小娇”的离去对他打击很大,但后来他是否还和“小娇”联系,就不得而知了。
还是介绍几个新成员,其中小骥就是前文做时刻表的员工:
海根:负责架构,造轮子,票务系统
小海:负责机务系统
海华:负责汽修系统和测试
文政:负责汽修系统
小骥:负责营运系统
巍巍:负责测试
票务开启
复盘看来,海根进入项目组以后,项目进度有了极大的推进。海根是架构出身,也是外地来上海的。虽然看上去其貌不扬,但是架构、设计、代码样样精通。进入项目组以后,就开始着手整理‘会海’之前留下来的轮子。
经过一番整理,最终确定了整个系统的构架,每个模块都可以独立的编译、测试、运行。同时一共共用的模块也进行了整合,把系统的耦合度降低了不少。
同时,由他负责了最复杂的票务系统的设计与开发。那个阶段,每天几乎都要跟他一起去票务部门进行调研。海根的记忆力奇好,甚至不用带本子做记录,回来以后就能够按照客户的描述,把界面全部画出来。而且他几乎不用借助其他工具,业务逻辑全部靠手写,代码也非常的清楚,即使在各类开发工具满天飞,AI编码也开始辅助人工的今天,他的代码依然还是很经典,看看票箱及相关操作的代码欣赏一下:
using System;
using Traffic.Common;
using System.Collections;
namespace Traffic.TicketBusiness.TicketBox
{
/// <summary>
/// 票箱。
/// </summary>
[Serializable()]
public class TicketBox:Props
{
[InTable]public int Id; //Id
[InTable]public int TicketStoreId; //票库Id
[InTable]public string Code; //名称
[InTable]public double TotalSum; //现存金额
[InTable]public System.DateTime CancelDate; //作废日期
[InTable]public int CancelFlag; //作废标志
public TicketBox(Props objProps)
{
this.TableName = Const.TABLENAME_TICKETBOX;
this.PropsToFields(objProps);
}
public TicketBox()
{
this.TableName = Const.TABLENAME_TICKETBOX;
}
}
/// <summary>
/// 售票员、票箱、工号的对照表。
/// </summary>
[Serializable()]
public class TicketBoxRelation:Props
{
[InTable]public int Id; //Id
[InTable]public int TicketBoxCode; //票箱号
[InTable]public string ConductorCode; //售票员工号
[InTable]public int RouteId; //路别Id
[InTable]public bool HasConditioner; //是否空调
[InTable]public int RedFlag; //红绿箱标志
public TicketBoxRelation(Props objProps)
{
this.TableName = Const.TABLENAME_TICKETBOXRELATION;
this.PropsToFields(objProps);
}
public TicketBoxRelation()
{
//
// TODO: 在此处添加构造函数逻辑
//
this.TableName = Const.TABLENAME_TICKETBOXRELATION;
}
}
}
票箱操作有很多功能,下面是发生遗失票的时候,改如何实现:
/// <summary>
/// 遗失票登记。
/// 一个票价一个遗失票登记单和一个一个遗失票登记单明细。
/// </summary>
/// <param name="sTicketBoxCode">票箱代号</param>
/// <param name="dTicketPrice">票价</param>
/// <param name="sBeginTicketMarkMolecule">开始票记(分子/分母)</param>
/// <param name="iBeginTicketNo">开始票号</param>
/// <param name="sEndTicketMarkMolecule">结束票记(分子/分母)</param>
/// <param name="iEndTicketNo">结束票号</param>
/// <returns></returns>
public Reports TicketLost(string sOperator,string sTicketBoxCode,double dTicketPrice,int iTicketMarkMolecule,int iTicketMarkDenominator,int iBeginTicketNo,int iEndTicketNo)
{
int iID;
int iCloseOffBillID=0;
int iTurnTime=0;
string sSQL;
OleDbDataReader reader;
Reports reports=new Reports();
//得到最新的客票结算单。
sSQL="Select Top 1 Id from pwTicketCloseOffBill Where TicketBoxCode='"+sTicketBoxCode+"' Order by CloseOffDate DESC";
reader=this.GetReader(sSQL);
if (reader.Read())
{
iCloseOffBillID=Conversion.getInt(reader.GetValue(0));
}
//票库作废是必须判断最后的客票结算单中是否有此票记票号。
sSQL="Select TurnTime from pwTicketCloseOffBillDetail Where TicketCloseOffBillID="+iCloseOffBillID+" And TicketPrice="+dTicketPrice+" And TicketMarkDenominator="+iTicketMarkDenominator+" And TicketMarkMolecule="+iTicketMarkMolecule+" And (BeginTicketNo<="+iBeginTicketNo+" And EndTicketNo>="+iEndTicketNo+")";
reader=this.GetReader(sSQL);
//如果找到,则取出其TurnTime,如果存在两个票记,则提示。
if ( reader.Read())
{
iTurnTime=Conversion.getInt(reader.GetValue(0));
//第一次轮次为1.
if (iTurnTime==0) iTurnTime=1;
if ( reader.Read())
{
reports.ReturnBool =false;
reports.ErrorReport="票箱中相同票记、票号中存在多个,不能同时作废!";
return reports;
}
}
try
{
//向部分票报废表新增一条记录。
sSQL="Insert Into pwTicketBoxLost(TicketBoxCode,LostDate,Operator) Values ('"+sTicketBoxCode+"','"+System.DateTime.Now.ToShortDateString()+"','"+sOperator+"')";
sSQL+= " Select Id From pwTicketBoxLost Where Id = @@IDENTITY";
reader=this.GetReader(sSQL);
if (reader.Read())
{
//得到新的出库单Id
iID= Conversion.getInt(reader.GetValue(0));
//向票箱变更单明细中插入一条新记录。
sSQL="Insert Into pwTicketBoxDetail(TicketBoxCode,BillID,BillType,OperateDate,TicketPrice,TurnTime,TicketMarkMolecule,TicketMarkDenominator,BeginTicketNo,EndTicketNo) Values('"+sTicketBoxCode +"',"+iID +","+(int)enumBillType.CancelBill +",'"+System.DateTime.Now.ToShortDateString()+"',"+dTicketPrice +","+iTurnTime+","+iTicketMarkMolecule +","+iTicketMarkDenominator +","+iBeginTicketNo +","+iEndTicketNo+")";
this.GetReader(sSQL);
}
reports.ReturnBool=true;
}
catch(Exception e)
{
Error.Log(e.Message);
reports.ErrorReport=e.Message;
reports.ReturnBool=false;
}
return reports;
}
当然,可能有人会说,代码里怎么还有SQL语句,这个耦合度太高了。是的,在当时流行的CS架构中,很多都是这么干的。至于MVC这样的架构,是项目完成后几年后才出现的。
海根现在看到这些代码,应该也会会心一笑了,毕竟这种代码的方式,在当时虽然每次改动SQL代码都要重新编译,但是仅仅就是一句SQL语句,不涉及其他代码的调整。
漂泊在外的日子
那段时间,由于项目推进要求,而甲方在浦西,我们大多住在浦东,后来经过协调,公司专门在甲方附近帮我们租了一个两室一厅的房子供路远的员工晚上休息,这样可以节约大量的通勤时间。
房东是一位上海出入境管理局的领导,当时他很有远见,自己早早的就在附近买了新住宅,租给我们的房子,是单位分配的。那时候虽然自己也买了房子,但属于老破小。一是没有投资意识,没有继续带杠杆买房;二是胆子小,感觉贷款压力太大;前文提到的肖博士,当时也没有投资房产,我们都属于没有能够跟上这波长达20多年的房地产鼎盛周期的那类人。这个就是运气。
这位领导后来我们还经常联系,甚至有一次春节回家买票,还是托他找熟人买的车票,当年12306甚至连电话订票都没有的年代,碰到这位领导真是幸运之极!本来打算一直跟他保持联系的,但是结果是大家都没有想到的,过于惨烈,就不再回忆了。很多事就是命运使然。