上班的第一天,群里讨论关于订餐的问题,所以想到了要不要自己开发一个公司内部的订餐系统呢?方便公司内部员工的订餐,有了想法就简单的实践了下 。
实现还是很简单的,因为只是自己内部使用,所以没有考虑太多的因素。数据库选用的Ndatabase,之所以用到数据库其实开始的想法是希望添加一个自动推荐食物的功能的.
1. 新建一个类库工程QSnack.Contract(服务契约工程),结构:
我们定义了三个服务接口:
1) IUserService : 用户服务接口,用户的注册/注销/积分/用户信息更新, 基于basicHttp协议.
[ServiceContract(Namespace="http://www.swzsoft.cn",Name="UserService")] public interface IUserService { /// <summary> /// 用户注册 /// </summary> /// <param name="username">用户名</param> /// <param name="password">用户密码</param> /// <param name="phone">用户联系电话</param> /// <returns></returns> [OperationContract] int Register(string username, string password, string phone); /// <summary> /// 用户注销 /// </summary> /// <param name="username"></param> [OperationContract] void Unregister(string username); /// <summary> /// 用户信息更新 /// </summary> /// <param name="username"></param> /// <param name="phone"></param> /// <param name="password"></param> /// <returns></returns> [OperationContract] int UpdateUserInformation(string username, string phone, string password); /// <summary> /// 更新用户积分 /// </summary> /// <param name="username"></param> /// <param name="intergral"></param> [OperationContract] void UpdateIntegral(string username, int intergral); }
2) IShopService: 商家服务接口, 商家注册/注销/食品/,基于basicHttp协议.
[ServiceContract(Name="ShopService",Namespace="http://www.swzsoft.cn")] public interface IShopService { /// <summary> /// 注册商家 /// </summary> /// <param name="shopname">商店名称</param> /// <param name="phone">商店外卖电话</param> /// <param name="address">商店所在位置</param> /// <returns>返回商店的guid</returns> [OperationContract] string Register(string shopname, string phone, string address); /// <summary> /// 注销商家 /// </summary> /// <param name="guid"></param> [OperationContract] void Unregister(string guid); /// <summary> /// 获取所有商家信息 /// </summary> /// <returns></returns> [OperationContract] System.Collections.Generic.List<ShopInfoModel> GetShops(); /// <summary> /// 获取指定商家保护食物的类别 /// </summary> /// <param name="guid"></param> /// <returns></returns> [OperationContract] System.Collections.Generic.List<FoodModel> GetFoodsByShopGUID(string guid); }
3) IOrderService:订单服务接口,订单预定/状态改变,基于双工协议.
[ServiceContract(Name="OrderService",Namespace="http://www.swzsoft.cn",CallbackContract=typeof( IOrderServiceCallback))] public interface IOrderService { [OperationContract] void Order(OrderModel orderModel); [OperationContract] //targetType == 1 商家 , 0 - 用户 int UpdateOrderState(string id, OrderStateEnum state , int targetType ); } public interface IOrderServiceCallback { void UpdateStateUser(OrderStateEnum state); void UpdateStateShop(OrderStateEnum state); }
2. 异常定义
定义一个异常基类
[DataContract] [KnownType(typeof( UserException))] [KnownType(typeof( ShopException))] [KnownType(typeof( OrderException))] public class BasicException { [DataMember] public string Message { get; set; } [DataMember] public System.Reflection.MethodInfo Method { get; set; } }
分别定义了:用户异常UserException,ShopException商家服务异常,OrderException 订单异常
3. 模型类
用户模型
[DataContract(Namespace="http://www.swzsoft.cn")]
public class UserModel {
[DataMember(IsRequired = true)]
public string Name { get; set; }
[DataMember(IsRequired = true)]
public string Password { get; set; }
[DataMember(IsRequired=true)]
public string Phone { get; set; }
[DataMember]
public int Intergral { get; set; }
}
[DataContract(Namespace="http://www.swzsoft.cn")] public class UserModel { [DataMember(IsRequired = true)] public string Name { get; set; } [DataMember(IsRequired = true)] public string Password { get; set; } [DataMember(IsRequired=true)] public string Phone { get; set; } [DataMember] public int Intergral { get; set; } }
商家模型
[DataContract(Namespace="http://www.swzsoft.cn")]
public class ShopInfoModel {
[DataMember]
public string Name { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string Phone { get; set; }
[DataMember(IsRequired = true)]
public string ShopGUID { get; set; }
}
[DataContract(Namespace="http://www.swzsoft.cn")] public class ShopInfoModel { [DataMember] public string Name { get; set; } [DataMember] public string Address { get; set; } [DataMember] public string Phone { get; set; } [DataMember(IsRequired = true)] public string ShopGUID { get; set; } }
订单模型
[DataContract(Namespace="http://www.swzsoft.cn")]
public class OrderModel {
[DataMember]
public string ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public System.Collections.Generic.List<FoodModel> Food { get; set; }
[DataMember] //订餐客户名称
public string ClientName { get; set; }
[DataMember]
public OrderStateEnum OrderState { get; set; }
}
[DataContract]
public enum OrderStateEnum
{
[EnumMember]
Unconfirmed, //未确认
[EnumMember]
Confirmed, //确认
[EnumMember]
Without_Payment, //未付款
[EnumMember]
Payment, //已付款
[EnumMember]
Cancel, //取消
}
[DataContract(Namespace="http://www.swzsoft.cn")] public class OrderModel { [DataMember] public string ID { get; set; } [DataMember] public string Name { get; set; } [DataMember] public System.Collections.Generic.List<FoodModel> Food { get; set; } [DataMember] //订餐客户名称 public string ClientName { get; set; } [DataMember] public OrderStateEnum OrderState { get; set; } } [DataContract] public enum OrderStateEnum { [EnumMember] Unconfirmed, //未确认 [EnumMember] Confirmed, //确认 [EnumMember] Without_Payment, //未付款 [EnumMember] Payment, //已付款 [EnumMember] Cancel, //取消 }
食物模型
[DataContract(Namespace="http://www.swzsoft.cn")]
public class FoodModel {
[DataMember(IsRequired = true)]
public string ShopGUID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public double Price { get; set; }
[DataMember]
public FoodTypeEnum FoodType { get; set; }
}
[DataContract(Namespace="http://www.swzsoft.cn")]
public enum FoodTypeEnum
{
/// <summary>
/// 套餐
/// </summary>
[EnumMember]
FOOD_SETMEAL ,
/// <summary>
/// 汤类
/// </summary>
[EnumMember]
FOOD_SOUP,
/// <summary>
/// 小菜
/// </summary>
[EnumMember]
FOOD_FOOD,
}
[DataContract(Namespace="http://www.swzsoft.cn")] public class FoodModel { [DataMember(IsRequired = true)] public string ShopGUID { get; set; } [DataMember] public string Name { get; set; } [DataMember] public double Price { get; set; } [DataMember] public FoodTypeEnum FoodType { get; set; } } [DataContract(Namespace="http://www.swzsoft.cn")] public enum FoodTypeEnum { /// <summary> /// 套餐 /// </summary> [EnumMember] FOOD_SETMEAL , /// <summary> /// 汤类 /// </summary> [EnumMember] FOOD_SOUP, /// <summary> /// 小菜 /// </summary> [EnumMember] FOOD_FOOD, }
4.数据库,数据库操作分为shopDB,OrderDB,UserDB分别对应不同的服务接口,使用NDatabase数据库
UserDB.cs
public class UserDB {
/// <summary>
/// 插入新的用户
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="phone"></param>
/// <returns></returns>
public static int InsertUser(string username, string password, string phone) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username));
if (obj == null) {
UserModel model = new UserModel {
Name = username,
Password = password,
Phone = phone,
Intergral = 0
};
db.Store<UserModel>(model);
return 1;
}
return 0;
}
}
/// <summary>
/// 删除用户
/// </summary>
/// <param name="username"></param>
public static void DeleteUser(string username) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username));
if (obj != null) {
db.Delete<UserModel>(obj);
}
}
}
/// <summary>
/// 更新用户
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="phone"></param>
public static void UpdateUser(string username, string password, string phone) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username));
if (obj != null) {
obj.Password = password;
obj.Phone = phone;
db.Store<UserModel>(obj);
}
}
}
/// <summary>
/// 更新用户积分
/// </summary>
/// <param name="integral"></param>
/// <param name="username"></param>
public static void UpdateIntegral(int integral, string username) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username));
if (obj != null) {
obj.Intergral += integral;
db.Store<UserModel>(obj);
}
}
}
}
public class UserDB { /// <summary> /// 插入新的用户 /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <param name="phone"></param> /// <returns></returns> public static int InsertUser(string username, string password, string phone) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username)); if (obj == null) { UserModel model = new UserModel { Name = username, Password = password, Phone = phone, Intergral = 0 }; db.Store<UserModel>(model); return 1; } return 0; } } /// <summary> /// 删除用户 /// </summary> /// <param name="username"></param> public static void DeleteUser(string username) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username)); if (obj != null) { db.Delete<UserModel>(obj); } } } /// <summary> /// 更新用户 /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <param name="phone"></param> public static void UpdateUser(string username, string password, string phone) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username)); if (obj != null) { obj.Password = password; obj.Phone = phone; db.Store<UserModel>(obj); } } } /// <summary> /// 更新用户积分 /// </summary> /// <param name="integral"></param> /// <param name="username"></param> public static void UpdateIntegral(int integral, string username) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obj = db.AsQueryable<UserModel>().FirstOrDefault(o => o.Name.Equals(username)); if (obj != null) { obj.Intergral += integral; db.Store<UserModel>(obj); } } } }
OrderDB.cs
public class OrderDB {
public static void InsertOrder(OrderModel model) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obj = db.AsQueryable<OrderModel>().FirstOrDefault(o => o.ID.Equals(model.ID));
if (obj == null) {
db.Store<OrderModel>(model);
}
}
}
public static int UpdateOrder(string id, OrderStateEnum state) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var objs = (from x in db.AsQueryable<OrderModel>()
where x.ID.Equals(id, StringComparison.CurrentCultureIgnoreCase)
select x).FirstOrDefault();
if (objs == null) {
return 0;
}
if (state == OrderStateEnum.Cancel) {
if (objs.OrderState == OrderStateEnum.Confirmed ||
objs.OrderState == OrderStateEnum.Payment ||
objs.OrderState == OrderStateEnum.Cancel) {
return 0;
}
}
else {
if (state == objs.OrderState) {
return 1;
}
else {
objs.OrderState = state;
}
return 1;
}
return 1;
}
}
}
public class OrderDB { public static void InsertOrder(OrderModel model) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obj = db.AsQueryable<OrderModel>().FirstOrDefault(o => o.ID.Equals(model.ID)); if (obj == null) { db.Store<OrderModel>(model); } } } public static int UpdateOrder(string id, OrderStateEnum state) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var objs = (from x in db.AsQueryable<OrderModel>() where x.ID.Equals(id, StringComparison.CurrentCultureIgnoreCase) select x).FirstOrDefault(); if (objs == null) { return 0; } if (state == OrderStateEnum.Cancel) { if (objs.OrderState == OrderStateEnum.Confirmed || objs.OrderState == OrderStateEnum.Payment || objs.OrderState == OrderStateEnum.Cancel) { return 0; } } else { if (state == objs.OrderState) { return 1; } else { objs.OrderState = state; } return 1; } return 1; } } }
ShopDB.cs
public class ShopDB {
public static string InsertShop(string name, string address, string phone) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obj = db.AsQueryable<ShopInfoModel>().FirstOrDefault(o => o.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase));
if (obj == null) {
ShopInfoModel shop = new ShopInfoModel {
Name = name,
Address = address,
Phone = phone,
ShopGUID = new Guid().ToString()
};
db.Store<ShopInfoModel>(shop);
return shop.ShopGUID;
}
return null;
}
}
public static void DeleteShop(string guid){
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obj = db.AsQueryable<ShopInfoModel>().FirstOrDefault( o=> o.ShopGUID.Equals( guid,StringComparison.CurrentCultureIgnoreCase));
if(obj != null){
db.Delete<ShopInfoModel>(obj);
}
}
}
public static List<ShopInfoModel> QueryShops() {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obs = from o in db.AsQueryable<ShopInfoModel>()
select o;
return obs.ToList();
}
}
public static List<FoodModel> QueryFoods(string guid) {
using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) {
var obs = from o in db.AsQueryable<FoodModel>()
where o.ShopGUID.Equals(guid, StringComparison.CurrentCultureIgnoreCase)
select o;
if (obs != null) {
return obs.ToList();
}
return null;
}
}
}
public class ShopDB { public static string InsertShop(string name, string address, string phone) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obj = db.AsQueryable<ShopInfoModel>().FirstOrDefault(o => o.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase)); if (obj == null) { ShopInfoModel shop = new ShopInfoModel { Name = name, Address = address, Phone = phone, ShopGUID = new Guid().ToString() }; db.Store<ShopInfoModel>(shop); return shop.ShopGUID; } return null; } } public static void DeleteShop(string guid){ using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obj = db.AsQueryable<ShopInfoModel>().FirstOrDefault( o=> o.ShopGUID.Equals( guid,StringComparison.CurrentCultureIgnoreCase)); if(obj != null){ db.Delete<ShopInfoModel>(obj); } } } public static List<ShopInfoModel> QueryShops() { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obs = from o in db.AsQueryable<ShopInfoModel>() select o; return obs.ToList(); } } public static List<FoodModel> QueryFoods(string guid) { using (var db = OdbFactory.Open(GlobeConfig.DATABASE)) { var obs = from o in db.AsQueryable<FoodModel>() where o.ShopGUID.Equals(guid, StringComparison.CurrentCultureIgnoreCase) select o; if (obs != null) { return obs.ToList(); } return null; } } }
5. 服务接口实现
UserService 用户服务
public class UserService : IUserService{
public int Register(string username, string password, string phone) {
return UserDB.InsertUser(username, password, phone);
}
public void Unregister(string username) {
UserDB.DeleteUser(username);
}
public int UpdateUserInformation(string username, string phone, string password) {
UserDB.UpdateUser(username, password, phone);
return 1;
}
public void UpdateIntegral(string username, int intergral) {
UserDB.UpdateIntegral(intergral, username);
}
}
public class UserService : IUserService{ public int Register(string username, string password, string phone) { return UserDB.InsertUser(username, password, phone); } public void Unregister(string username) { UserDB.DeleteUser(username); } public int UpdateUserInformation(string username, string phone, string password) { UserDB.UpdateUser(username, password, phone); return 1; } public void UpdateIntegral(string username, int intergral) { UserDB.UpdateIntegral(intergral, username); } }
ShopService 商家服务
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode=ConcurrencyMode.Multiple,
IgnoreExtensionDataObject = true)]
public class ShopService : IShopService{
public string Register(string shopname, string phone, string address) {
return ShopDB.InsertShop(shopname, address, phone);
}
public void Unregister(string guid) {
ShopDB.DeleteShop(guid);
}
public List<ShopInfoModel> GetShops() {
return ShopDB.QueryShops();
}
public List<FoodModel> GetFoodsByShopGUID(string guid) {
return ShopDB.QueryFoods(guid);
}
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode=ConcurrencyMode.Multiple, IgnoreExtensionDataObject = true)] public class ShopService : IShopService{ public string Register(string shopname, string phone, string address) { return ShopDB.InsertShop(shopname, address, phone); } public void Unregister(string guid) { ShopDB.DeleteShop(guid); } public List<ShopInfoModel> GetShops() { return ShopDB.QueryShops(); } public List<FoodModel> GetFoodsByShopGUID(string guid) { return ShopDB.QueryFoods(guid); } }
OrderService 订单服务
[ServiceBehavior( ConcurrencyMode=ConcurrencyMode.Multiple,IgnoreExtensionDataObject = true,InstanceContextMode= InstanceContextMode.PerSession)]
public class OrderService :IOrderService{
public static Dictionary<string, IOrderServiceCallback> _callbacks = new Dictionary<string, IOrderServiceCallback>();
public void Order(OrderModel orderModel) {
IOrderServiceCallback callback = OperationContext.Current.GetCallbackChannel<IOrderServiceCallback>();
if (!_callbacks.ContainsKey(orderModel.ID)) {
_callbacks.Add(orderModel.ID, callback);
}
OrderDB.InsertOrder(orderModel);
}
public int UpdateOrderState(string id, OrderStateEnum state,int targetType ) {
int result = OrderDB.UpdateOrder(id, state);
IOrderServiceCallback callback = _callbacks[id];
if (result == 1) {
if (callback != null) {
if (targetType == 1) {//shop
callback.UpdateStateUser(state);
}
else if (targetType == 0) { //user
callback.UpdateStateShop(state);
}
}
}
return result;
}
}
[ServiceBehavior( ConcurrencyMode=ConcurrencyMode.Multiple,IgnoreExtensionDataObject = true,InstanceContextMode= InstanceContextMode.PerSession)] public class OrderService :IOrderService{ public static Dictionary<string, IOrderServiceCallback> _callbacks = new Dictionary<string, IOrderServiceCallback>(); public void Order(OrderModel orderModel) { IOrderServiceCallback callback = OperationContext.Current.GetCallbackChannel<IOrderServiceCallback>(); if (!_callbacks.ContainsKey(orderModel.ID)) { _callbacks.Add(orderModel.ID, callback); } OrderDB.InsertOrder(orderModel); } public int UpdateOrderState(string id, OrderStateEnum state,int targetType ) { int result = OrderDB.UpdateOrder(id, state); IOrderServiceCallback callback = _callbacks[id]; if (result == 1) { if (callback != null) { if (targetType == 1) {//shop callback.UpdateStateUser(state); } else if (targetType == 0) { //user callback.UpdateStateShop(state); } } } return result; } }