項目背景:公司內部進行抽獎,參與者再開始抽獎前,需要先在微信上分享該抽獎鏈接,才可以進行抽獎操作,三次抽獎機會,如果未中獎,抽獎次數減一,直到到三次機會全部。
開發工具: vs2015 + sqlserver +H5
(一)准備工作:
創建多個數據表,用來存儲相關數據信息
1.用戶注冊表(該表目的在於統計該用戶是否已經是公司平台用戶,我們的實現機制是,如果該用戶以前沒有在公司平台注冊過,那么我們會幫用戶在公司平台實現注冊,並且在該表中插入條記錄,方便日后統計出,通過本次抽獎活動,有多少新用戶注冊了)
1 CREATE TABLE [dbo].[T_Draw_Account]( 2 [ID] [int] IDENTITY(1,1) NOT NULL, 3 [OpenID] [nvarchar](300) NOT NULL, // 微信唯一標識 4 [AccountName] [nvarchar](50) NOT NULL, // 用戶名 5 [PhoneNumber] [nvarchar](11) NOT NULL,//手機號碼 6 [Password] [nvarchar](50) NULL, //密碼 7 [Address] [nvarchar](300) NULL,//地址 8 [CreatedTime] [datetime] NULL, 9 [CreatedBy] [nvarchar](50) NULL, 10 [LastModifiedTime] [datetime] NULL, 11 [LastModifiedBy] [nvarchar](50) NULL, 12 [IsDeleted] [bit] NOT NULL, 13 CONSTRAINT [PK_T_Draw_Account] PRIMARY KEY CLUSTERED 14 ( 15 [ID] ASC 16 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 17 ) ON [PRIMARY]
2.葯材表
1 CREATE TABLE [dbo].[T_Draw_Drugs]( 2 [ID] [int] IDENTITY(1,1) NOT NULL, 3 [ProvinceID] [int] NOT NULL, //省份ID 4 [ProvinceName] [nvarchar](50) NULL, //省份名稱 5 [ProvincePinYin] [nvarchar](50) NOT NULL, //省份拼音 6 [DrugsID] [int] NOT NULL, //葯品ID 7 [DrugsName] [nvarchar](50) NULL, //葯品名稱 8 [LikeNum] [int] NOT NULL, //點贊數 9 [CreatedTime] [datetime] NULL, 10 [CreatedBy] [nvarchar](50) NULL, 11 [LastModifiedTime] [datetime] NULL, 12 [LastModifiedBy] [nvarchar](50) NULL, 13 [IsDeleted] [bit] NOT NULL, 14 CONSTRAINT [PK_T_Draw_Drugs] PRIMARY KEY CLUSTERED 15 ( 16 [ID] ASC 17 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 18 ) ON [PRIMARY]
3.抽獎表
1 CREATE TABLE [dbo].[T_Draw_Prize]( 2 [ID] [int] IDENTITY(1,1) NOT NULL, 3 [OpenID] [nvarchar](300) NOT NULL, //微信唯一標識 4 [Prize] [int] NOT NULL, //獎品 5 [DrawNum] [int] NOT NULL, //抽獎次數 6 [IsWinning] [bit] NOT NULL, //是否中獎 7 [CreatedTime] [datetime] NULL, 8 [CreatedBy] [nvarchar](50) NULL, 9 [LastModifiedTime] [datetime] NULL, 10 [LastModifiedBy] [nvarchar](50) NULL, 11 [IsDeleted] [bit] NOT NULL, 12 CONSTRAINT [PK_T_Draw_Prize] PRIMARY KEY CLUSTERED 13 ( 14 [ID] ASC 15 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 16 ) ON [PRIMARY]
4.分享記錄表
1 CREATE TABLE [dbo].[T_Draw_Share]( 2 [ID] [int] IDENTITY(1,1) NOT NULL, 3 [OpenID] [nvarchar](300) NOT NULL, //微信唯一標識 4 [CreatedTime] [datetime] NULL, 5 [CreatedBy] [nvarchar](50) NULL, 6 [LastModifiedTime] [datetime] NULL, 7 [LastModifiedBy] [nvarchar](50) NULL, 8 [IsDeleted] [bit] NOT NULL, 9 CONSTRAINT [PK_T_Draw_Share] PRIMARY KEY CLUSTERED 10 ( 11 [ID] ASC 12 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 13 ) ON [PRIMARY]
5.葯材排名表
1 CREATE TABLE [dbo].[T_Draw_TopDrugs]( 2 [ID] [int] IDENTITY(1,1) NOT NULL, 3 [OpenID] [nvarchar](300) NOT NULL, //微信標識 4 [ProvinceID] [int] NOT NULL, //省份ID 5 [DrugsID] [int] NOT NULL, //葯品ID 6 [CreatedTime] [datetime] NULL, 7 [CreatedBy] [nvarchar](50) NULL, 8 [LastModifiedTime] [datetime] NULL, 9 [LastModifiedBy] [nvarchar](50) NULL, 10 [IsDeleted] [bit] NOT NULL, 11 CONSTRAINT [PK_T_Draw_TopDrugs] PRIMARY KEY CLUSTERED 12 ( 13 [ID] ASC 14 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 15 ) ON [PRIMARY]
(二)前期工作就是這些了,那么我們開始進入正式的代碼實現過程:
1.首先我們需要創建兩個接口文件,一個用來實現所有的查詢,一個用來實現所有的操作,那么我們分別命名為 IDrawCommandService,IDrawQueryService
(1)IDrawCommandService 接口文件如下:
1 public interface IDrawCommandService 2 { 3 /// <summary> 4 /// 插入分享記錄 5 /// </summary> 6 /// <param name="openId"></param> 7 /// <returns></returns> 8 bool InsertShare(string openId); 9 10 /// <summary> 11 /// 點贊葯品 12 /// </summary> 13 /// <param name="openId"></param> 14 /// <param name="provinceId"></param> 15 /// <param name="drugsId"></param> 16 /// <returns></returns> 17 bool TopDrugs(string openId, int provinceId, int drugsId); 18 19 /// <summary> 20 /// 隨機抽獎 21 /// </summary> 22 /// <param name="openId"></param> 23 /// <returns></returns> 24 ObjDTO RandomDraw(string openId); 25 26 /// <summary> 27 /// 用戶注冊--H5 28 /// </summary> 29 /// <param name="request"></param> 30 /// <returns></returns> 31 bool RegisterH5Account(AccountDTO request); 32 33 /// <summary> 34 /// 用戶注冊--BAT 35 /// </summary> 36 /// <param name="request"></param> 37 /// <returns></returns> 38 bool RegisterBatAccount(AccountDTO request); 39 }
(2)IDrawQueryService 接口文件如下:
1 public interface IDrawQueryService 2 { 3 /// <summary> 4 /// 初始化信息 5 /// </summary> 6 /// <returns></returns> 7 DrawDTO GetInit(string code, string url,string openid, string state); 8 9 /// <summary> 10 /// 獲取排行榜 11 /// </summary> 12 /// <returns></returns> 13 List<DrugsRankingDTO> RankingList(); 14 15 /// <summary> 16 /// 判斷是否存在該手機號碼--BAT 17 /// </summary> 18 /// <param name="phoneNumber"></param> 19 /// <returns></returns> 20 AccountDTO IsExistBatAccount(string phoneNumber); 21 22 /// <summary> 23 /// 判斷是否存在該手機號碼--H5 24 /// </summary> 25 /// <param name="phoneNumber"></param> 26 /// <returns></returns> 27 AccountDTO IsExistH5Account(string phoneNumber); 28 29 /// <summary> 30 /// 獲取我的獎品 31 /// </summary> 32 /// <param name="openId"></param> 33 /// <returns></returns> 34 int? GetMyPrize(string openId); 35 36 /// <summary> 37 /// 獎品列表 38 /// </summary> 39 /// <returns></returns> 40 List<PrizeDTO> GetPrizeList(int pageIndex, int pageSize, out int count); 41 }
2.分別實現2個接口:
(1)DrawCommandService:
1 public class DrawCommandService:IDrawCommandService 2 { 3 /// <summary> 4 /// 插入分享記錄 5 /// </summary> 6 /// <param name="openId"></param> 7 /// <returns></returns> 8 public bool InsertShare(string openId) 9 { 10 using (var db=DBManager.GetInstance()) 11 { 12 T_Draw_Share model = new T_Draw_Share() 13 { 14 OpenID= openId, 15 CreatedBy= openId, 16 CreatedTime=DateTime.Now, 17 IsDeleted=false 18 }; 19 20 db.Insert(model); 21 return true; 22 } 23 } 24 25 /// <summary> 26 /// 點贊葯品 27 /// </summary> 28 /// <param name="openId"></param> 29 /// <param name="provinceId"></param> 30 /// <param name="drugsId"></param> 31 /// <returns></returns> 32 public bool TopDrugs(string openId, int provinceId, int drugsId) 33 { 34 using (var db=DBManager.GetInstance()) 35 { 36 try 37 { 38 db.BeginTran(); 39 T_Draw_TopDrugs model = new T_Draw_TopDrugs() 40 { 41 OpenID = openId, 42 ProvinceID = provinceId, 43 DrugsID = drugsId, 44 CreatedBy = openId, 45 CreatedTime = DateTime.Now, 46 IsDeleted = false 47 }; 48 49 var query = db.Queryable<T_Draw_Drugs>().FirstOrDefault(x=>x.ProvinceID== provinceId && x.DrugsID== drugsId && !x.IsDeleted); 50 query.LikeNum += 1; 51 52 db.Update(query); 53 db.Insert(model); 54 db.CommitTran(); 55 return true; 56 } 57 catch (Exception) 58 { 59 db.RollbackTran(); 60 return false; 61 } 62 } 63 } 64 65 /// <summary> 66 /// 隨機抽獎 67 /// </summary> 68 /// <param name="openId"></param> 69 /// <returns></returns> 70 public ObjDTO RandomDraw(string openId) 71 { 72 using (var db=DBManager.GetInstance()) 73 { 74 75 db.BeginTran(); 76 var query = db.Queryable<T_Draw_Prize>().FirstOrDefault(x=>x.OpenID.Equals(openId) && !x.IsDeleted); 77 List<int> list = new List<int>() {0,1,3,4}; 78 79 int code = RandomAward(); 80 81 var prizeLst = db.Queryable<T_Draw_Prize>(); 82 var onePrizeNums = prizeLst.Where(x => x.Prize == 4 && !x.IsDeleted).Count(); // 一等獎數 83 var twoPrizeNums = prizeLst.Where(x => x.Prize == 1 && !x.IsDeleted).Count(); // 二等獎數 84 var threePrizeNums = prizeLst.Where(x => x.Prize == 3 && !x.IsDeleted).Count(); // 三等獎數 85 var luckPrizeNums = prizeLst.Where(x => x.Prize == 0 && !x.IsDeleted).Count(); // 幸運獎數 86 if (onePrizeNums == 3 || twoPrizeNums == 20 ) 87 { 88 code = 2; 89 } 90 if(threePrizeNums == 100 || luckPrizeNums == 3000) 91 { 92 code = 5; 93 } 94 int num = 0; 95 bool IsWinning = false; 96 if (!list.Any(x => x == code)) 97 { 98 num = 1; 99 } 100 else 101 { 102 num = 3; 103 IsWinning = true; 104 } 105 106 if (query==null) 107 { 108 T_Draw_Prize model = new T_Draw_Prize() 109 { 110 OpenID= openId, 111 Prize= code, 112 DrawNum= num, 113 IsWinning= IsWinning, 114 CreatedBy =openId, 115 CreatedTime=DateTime.Now, 116 IsDeleted=false 117 }; 118 db.Insert(model); 119 db.CommitTran(); 120 return new ObjDTO { HasNum = (3 - model.DrawNum)<0?0: 3 - model.DrawNum, Prize = model.Prize }; 121 } 122 else 123 { 124 query.IsWinning = IsWinning; 125 query.DrawNum += num; 126 if(query.DrawNum>3) 127 { 128 query.DrawNum = 3; 129 } 130 query.Prize = code; 131 db.Update(query); 132 db.CommitTran(); 133 return new ObjDTO { HasNum = (3 - query.DrawNum)<0?0: 3 - query.DrawNum, Prize = query.Prize }; 134 } 135 } 136 } 137 138 139 private static Random random = new Random(DateTime.Now.Millisecond); 140 141 142 // 0幸運獎", "1二等獎", "2謝謝參與", "3三等獎", "4一等獎", "5謝謝參與" 143 private int RandomAward() 144 { 145 var number = random.Next(50000); 146 if (number < 3000) 147 return 0; 148 else if (number <= 3020) 149 return 1; 150 else if (number > 3020 && number < 20000) 151 return 2; 152 else if (number < 20100) 153 return 3; 154 else if (number < 20103) 155 return 4; 156 else 157 return 5; 158 } 159 160 /// <summary> 161 /// 用戶注冊--H5 162 /// </summary> 163 /// <param name="request"></param> 164 /// <returns></returns> 165 public bool RegisterH5Account(AccountDTO request) 166 { 167 using (var db=DBManager.GetInstance()) 168 { 169 170 T_Draw_Account model = new T_Draw_Account(); 171 model = request.MapTo<T_Draw_Account>(); 172 model.Password = StringEncrypt.EncryptWithSHA(model.Password); 173 model.CreatedTime = DateTime.Now; 174 model.IsDeleted = false; 175 db.Insert(model); 176 return true; 177 178 } 179 } 180 181 /// <summary> 182 /// 用戶注冊--BAT 183 /// </summary> 184 /// <param name="request"></param> 185 /// <returns></returns> 186 public bool RegisterBatAccount(AccountDTO request) 187 { 188 using (var db=DBManager.GetInstance()) 189 { 190 T_SYS_ACCOUNT model = new T_SYS_ACCOUNT() 191 { 192 AccountName = request.AccountName, 193 AccountType = 0, 194 Password = StringEncrypt.EncryptWithSHA(request.Password), 195 Email = string.Empty, 196 PhoneNumber = request.PhoneNumber, 197 CreatedTime = DateTime.Now, 198 IsDeleted = false, 199 FollowNum = 0, 200 FansNum = 0, 201 IsMaster = false, 202 IsBindWX = false, 203 IsBindQQ = false, 204 IsTeacher = false 205 }; 206 db.Insert(model); 207 return true; 208 } 209 }
(2).DrawQueryService
1 public class DrawQueryService:IDrawQueryService 2 { 3 /// <summary> 4 /// 初始化信息 5 /// </summary> 6 /// <returns></returns> 7 public DrawDTO GetInit(string code, string url,string openid, string state) 8 { 9 using (var db=DBManager.GetInstance()) 10 { 11 DrawDTO model = new DrawDTO() { IsDraw=false, HasNum=3, IsRegister=false}; 12 model.ConfigDTO = GetWxJsConfig(code, url, state); 13 if (!openid.Equals("null")) 14 { 15 model.ConfigDTO.openid = openid; 16 } 17 model.DrudsLst = GetDrudsLst(model.ConfigDTO.openid); 18 19 var query = db.Queryable<T_Draw_Prize>().FirstOrDefault(x=>x.OpenID== model.ConfigDTO.openid && !x.IsDeleted); 20 if(query!=null) 21 { 22 model.IsDraw = true; 23 model.HasNum = query.DrawNum>=3? 0:3-query.DrawNum; 24 } 25 26 var account = db.Queryable<T_Draw_Account>().FirstOrDefault(x => x.OpenID.Equals(model.ConfigDTO.openid)); 27 if (account!=null) 28 { 29 model.IsRegister = true; 30 } 31 32 return model; 33 } 34 35 } 36 37 /// <summary> 38 /// 獲取微信js配置信息 39 /// </summary> 40 /// <param name="code"></param> 41 /// <param name="url"></param> 42 /// <returns></returns> 43 private WXJS_ConfigDTO GetWxJsConfig(string code, string url ,string state) 44 { 45 string appid = ConfigurationManager.AppSettings["AppId"]; 46 string secret = ConfigurationManager.AppSettings["Secret"]; 47 string noncestr = StringHelper.GenerateNonceStr(); 48 string timestamp = StringHelper.GenerateTimeStamp(); 49 50 // 獲取微信唯一標識 51 WebClient client = new WebClient(); 52 string getOpenidUrl = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, secret, code); 53 byte[] query = client.DownloadData(getOpenidUrl); 54 var q = System.Text.Encoding.UTF8.GetString(query); 55 WXJS_AccessTokenDTO openAccess = JsonConvert.DeserializeObject<WXJS_AccessTokenDTO>(q); 56 57 //獲取access token 58 var getAccessTicketUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret; 59 byte[] result = client.DownloadData(getAccessTicketUrl); 60 var req = System.Text.Encoding.UTF8.GetString(result); 61 WXJS_AccessTokenDTO access = JsonConvert.DeserializeObject<WXJS_AccessTokenDTO>(req); 62 access.openid = openAccess.openid; 63 64 // 獲取 ticket 65 var getTicKetUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access.access_token + "&type=jsapi"; 66 byte[] rs = client.DownloadData(getTicKetUrl); 67 var str = System.Text.Encoding.UTF8.GetString(rs); 68 WXJS_TicketDTO ticket = JsonConvert.DeserializeObject<WXJS_TicketDTO>(str); 69 70 // sha1加密 71 StringBuilder sb = new StringBuilder(); 72 sb.AppendFormat("jsapi_ticket={0}", ticket.ticket); 73 sb.AppendFormat("&noncestr={0}", noncestr); 74 sb.AppendFormat("×tamp={0}", timestamp); 75 sb.AppendFormat("&url={0}", string.Format("{0}&state={1}",url,state)); 76 string param = sb.ToString(); 77 string sign = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1"); 78 79 WXJS_ConfigDTO config = new WXJS_ConfigDTO() 80 { 81 appid = appid, 82 openid = access.openid, 83 timestamp = timestamp, 84 nonceStr = noncestr, 85 signature = sign, 86 access_token = access.access_token, 87 ticket= ticket.ticket 88 }; 89 90 return config; 91 } 92 93 /// <summary> 94 /// 獲取葯品信息 95 /// </summary> 96 /// <returns></returns> 97 private List<DrugsDTO> GetDrudsLst(string openId) 98 { 99 using (var db=DBManager.GetInstance()) 100 { 101 List<DrugsDTO> list = new List<DrugsDTO>(); 102 103 var province = db.Queryable<T_Draw_Drugs>().GroupBy(x => x.ProvinceID).GroupBy(x=>x.ProvincePinYin).Select("ProvinceID").ToList(); 104 105 foreach (var item in province) 106 { 107 var query = db.Queryable<T_Draw_Drugs>().Where(x => x.ProvinceID == item.ProvinceID).FirstOrDefault().MapTo<DrugsDTO>(); 108 109 var nums = db.Queryable<T_Draw_Drugs>().Where(x=>x.ProvinceID==item.ProvinceID).Select(x=>x.LikeNum).ToList(); 110 query.LikeNumLst = nums; 111 112 var zan = db.Queryable<T_Draw_TopDrugs>().Where(x => x.OpenID == openId && x.ProvinceID == item.ProvinceID).FirstOrDefault(); 113 if(zan!=null) 114 { 115 query.IsZan = true; 116 query.ZanDrugId = zan.DrugsID; 117 } 118 else 119 { 120 query.ZanDrugId = -1; 121 } 122 123 list.Add(query); 124 } 125 126 return list; 127 } 128 } 129 130 /// <summary> 131 /// 獲取排行榜 132 /// </summary> 133 /// <returns></returns> 134 public List<DrugsRankingDTO> RankingList() 135 { 136 using (var db=DBManager.GetInstance()) 137 { 138 var query = db.Queryable<T_Draw_Drugs>().OrderBy(x => x.LikeNum, OrderByType.Desc).Take(10).ToList().MapToList<DrugsRankingDTO>(); 139 return query; 140 } 141 } 142 143 /// <summary> 144 /// 判斷是否存在該手機號碼--BAT 145 /// </summary> 146 /// <param name="phoneNumber"></param> 147 /// <returns></returns> 148 public AccountDTO IsExistBatAccount(string phoneNumber) 149 { 150 using (var db=DBManager.GetInstance()) 151 { 152 var model = db.Queryable<T_SYS_ACCOUNT>().FirstOrDefault(x=>x.PhoneNumber.Equals(phoneNumber) && !x.IsDeleted).MapTo<AccountDTO>(); 153 if (model != null) return model; 154 else return null; 155 } 156 } 157 158 /// <summary> 159 /// 判斷是否存在該手機號碼--H5 160 /// </summary> 161 /// <param name="phoneNumber"></param> 162 /// <returns></returns> 163 public AccountDTO IsExistH5Account(string phoneNumber) 164 { 165 using (var db = DBManager.GetInstance()) 166 { 167 var model = db.Queryable<T_Draw_Account>().FirstOrDefault(x => x.PhoneNumber.Equals(phoneNumber) && !x.IsDeleted).MapTo<AccountDTO>(); 168 if (model != null) return model; 169 else return null; 170 } 171 } 172 173 /// <summary> 174 /// 獲取我的獎品 175 /// </summary> 176 /// <param name="openId"></param> 177 /// <returns></returns> 178 public int? GetMyPrize(string openId) 179 { 180 using (var db = DBManager.GetInstance()) 181 { 182 var query = db.Queryable<T_Draw_Prize>().FirstOrDefault(x=>x.OpenID.Equals(openId) && !x.IsDeleted); 183 if (query != null) return query.Prize; 184 else return null; 185 186 } 187 } 188 189 /// <summary> 190 /// 獎品列表 191 /// </summary> 192 /// <returns></returns> 193 public List<PrizeDTO> GetPrizeList(int pageIndex,int pageSize , out int count) 194 { 195 using (var db = DBManager.GetInstance()) 196 { 197 List<PrizeDTO> list = new List<PrizeDTO>(); 198 199 StringBuilder sb=new StringBuilder(); 200 sb.Append("select t1.AccountName, t1.PhoneNumber,t2.Prize, t1.Address,t1.CreatedTime from T_Draw_Account t1 "); 201 sb.Append("inner join T_Draw_Prize t2 on t1.OpenID=t2.OpenID "); 202 sb.Append("where t1.IsDeleted=0 and t2.IsDeleted=0 "); 203 204 var query = db.SqlQuery<PrizeDTO>(sb.ToString()); 205 // list.AddRange(query.Where(x => x.Prize == 2 || x.Prize == 5)); 206 list.AddRange(query.Where(x => x.Prize == 0)); 207 list.AddRange(query.Where(x => x.Prize == 3)); 208 list.AddRange(query.Where(x => x.Prize == 1)); 209 list.AddRange(query.Where(x => x.Prize == 4)); 210 211 count = list.Count(); 212 return list.Skip(pageIndex * pageSize).Take(pageSize).ToList(); 213 } 214 } 215 216 }
(三)前端API:
1 [RoutePrefix("api/Values")] 2 public class ValuesController : BaseApiController 3 { 4 5 6 private readonly IDrawCommandService _drawCommandService; 7 private readonly IDrawQueryService _drawQueryService; 8 private readonly ICacheManager _cache; 9 10 11 public ValuesController( 12 IDrawCommandService drawCommandService, 13 IDrawQueryService drawQueryService, 14 ICacheManager cache 15 ) 16 { 17 _drawCommandService = drawCommandService; 18 _drawQueryService = drawQueryService; 19 _cache = cache; 20 } 21 22 #region 初始化配置信息 23 24 /** 25 * @api {GET} /api/Values/GetInit 初始化配置信息 26 * @apiGroup Draw 27 * @apiVersion 1.0.0 28 * @apiDescription 初始化配置信息 29 * @apiPermission 所有人 30 * @apiParam {string} code 微信頁面授權自動返回的code 31 * @apiParam {string} url 當前頁面的url地址 32 * @apiParamExample {json} 請求樣例: 33 * /api/Values/GetInit?code=001H1eXC0DNVbf2pUgVC0HPhXC0H1eX7&url=www.jkbat.com/activity01/home/index 34 * @apiSuccess (200) {String} ResultMessage 提示信息 35 * @apiSuccess (200) {int} ResultCode 0 代表無錯誤 -1代表有錯誤 36 * @apiSuccess (200) {object} Data 業務數據 37 * @apiSuccessExample {json} 返回樣例: 38 * { 39 * "Data": { 40 * "IsDraw": false, 41 * "HasNum": 3, 42 * "IsRegister":false, // 是否注冊 43 * "ConfigDTO": { 44 * "appid": "wxb64dc5dfee841df5", // appid 45 * "openid": "ooGIewyacAsO5MI_8SQM_kn95MTY", // 微信唯一標識 46 * "timestamp": "1490592051", // 時間戳 47 * "nonceStr": "cb837bfdd4bb4896a1766b4bcc323f39", // 隨機字符串 48 * "signature": "6FD5FAC79E3563B8C94166655CA10B0AFA2DBE52", // 簽名 49 * "access_token": "2rhqyr9-1f4NDDvMo4sZVT0kWY37oJEgLhMugmBz7xIm75vFnj2QCvIsmtzKMAxkw2IBfDNBn0vDHTSKL6mz6Fr0FLc0YkVQadpPNVwiWFA" 50 * }, 51 * "DrudsLst": [ 52 * { 53 * "ProvinceID": 1, 54 * "ProvincePinYin": "anhui", 55 * "ProvinceName": "安徽", 56 * "LikeNumLst": [ 57 * 1, 58 * 2, 59 * 3, 60 * 4 61 * ], 62 * "IsZan": false 63 * }, 64 * { 65 * "ProvinceID": 2, 66 * "ProvincePinYin": "fujian", 67 * "ProvinceName": "福建", 68 * "LikeNumLst": [ 69 * 5, 70 * 6, 71 * 7, 72 * 8 73 * ], 74 * "IsZan": false 75 * }], 76 * "ResultCode": 0, 77 * "ResultMessage": "操作成功" 78 * } 79 */ 80 /// <summary> 81 /// 初始化配置信息 82 /// </summary> 83 /// <param name="code"></param> 84 /// <param name="url"></param> 85 /// <returns></returns> 86 [HttpGet] 87 public async Task<dynamic> GetInit(string code, string url,string openid, string state="JKBAT") 88 { 89 90 return await ProcessAsync<DrawDTO>(() => _drawQueryService.GetInit(code, url, openid, state)); 91 } 92 93 #endregion 94 95 #region 插入分享記錄 96 97 /** 98 * @api {GET} api/Values/InsertShare 插入分享記錄 99 * @apiGroup Draw 100 * @apiVersion 1.0.0 101 * @apiDescription 插入分享記錄 102 * @apiPermission 已登錄 103 * @apiParam {string} openId 微信唯一標識 104 * @apiParamExample {json} 請求樣例: 105 * api/Values/InsertShare?openId=ooGIewyacAsO5MI_8SQM_kn95MTY 106 * @apiSuccess (200) {string} ResultMessage 操作成功 107 * @apiSuccess (200) {int} ResultCode 0返回成功,-1返回失敗 108 * @apiSuccessExample {json} 返回樣例: 109 * { 110 * "Data":true, 111 * "ResultCode": 0, 112 * "ResultMessage": "操作成功" 113 * } 114 */ 115 /// <summary> 116 /// 插入分享記錄 117 /// </summary> 118 /// <param name="openId"></param> 119 /// <returns></returns> 120 [HttpGet] 121 public async Task<dynamic> InsertShare(string openId) 122 { 123 return await ProcessAsync<bool>(()=> _drawCommandService.InsertShare(openId)); 124 } 125 126 #endregion 127 128 #region 點贊葯品 129 130 /** 131 * @api {GET} api/Values/TopDrugs 點贊葯品 132 * @apiGroup Draw 133 * @apiVersion 1.0.0 134 * @apiDescription 點贊葯品 135 * @apiPermission 已登錄 136 * @apiParam {string} openId 微信唯一標識 137 * @apiParam {int} provinceId 省份ID 138 * @apiParam {drugsId} drugsId 葯品ID 139 * @apiParamExample {json} 請求樣例: 140 * api/Values/TopDrugs?openId=ooGIewyacAsO5MI_8SQM_kn95MTY&provinceId=1&drugsId=1 141 * @apiSuccess (200) {string} ResultMessage 操作成功 142 * @apiSuccess (200) {int} ResultCode 0返回成功,-1返回失敗 143 * @apiSuccessExample {json} 返回樣例: 144 * { 145 * "Data":true, 146 * "ResultCode": 0, 147 * "ResultMessage": "操作成功" 148 * } 149 */ 150 /// <summary> 151 /// 點贊葯品 152 /// </summary> 153 /// <param name="openId"></param> 154 /// <param name="provinceId"></param> 155 /// <param name="drugsId"></param> 156 /// <returns></returns> 157 [HttpGet] 158 public async Task<dynamic> TopDrugs(string openId, int provinceId, int drugsId) 159 { 160 return await ProcessAsync<bool>(() => _drawCommandService.TopDrugs(openId, provinceId, drugsId)); 161 } 162 163 #endregion 164 165 #region 獲取排行榜 166 167 /** 168 * @api {GET} /api/Values/RankingList 獲取排行榜 169 * @apiGroup Draw 170 * @apiVersion 1.0.0 171 * @apiDescription 獲取排行榜 172 * @apiPermission 所有人 173 * @apiParamExample {json} 請求樣例: 174 * /api/Values/RankingList 175 * @apiSuccess (200) {String} ResultMessage 提示信息 176 * @apiSuccess (200) {int} ResultCode 0 代表無錯誤 -1代表有錯誤 177 * @apiSuccess (200) {object} Data 業務數據 178 * @apiSuccessExample {json} 返回樣例: 179 * { 180 * "Data": [ 181 * { 182 * "ProvinceName": "廣東", 183 * "DrugsName": "雞內金" 184 * }, 185 * { 186 * "ProvinceName": "廣東", 187 * "DrugsName": "佛手" 188 * }, 189 * { 190 * "ProvinceName": "福建", 191 * "DrugsName": "太子參" 192 * }, 193 * { 194 * "ProvinceName": "福建", 195 * "DrugsName": "姜黃" 196 * }, 197 * { 198 * "ProvinceName": "福建", 199 * "DrugsName": "砂仁" 200 * }, 201 * { 202 * "ProvinceName": "福建", 203 * "DrugsName": "狗脊" 204 * }, 205 * { 206 * "ProvinceName": "安徽", 207 * "DrugsName": "桔梗" 208 * }, 209 * { 210 * "ProvinceName": "安徽", 211 * "DrugsName": "單參" 212 * }, 213 * { 214 * "ProvinceName": "安徽", 215 * "DrugsName": "白術" 216 * }, 217 * { 218 * "ProvinceName": "安徽", 219 * "DrugsName": "白芍" 220 * } 221 * ], 222 * "ResultCode": 0, 223 * "ResultMessage": "操作成功" 224 * } 225 */ 226 /// <summary> 227 /// 獲取排行榜 228 /// </summary> 229 /// <returns></returns> 230 [HttpGet] 231 public async Task<dynamic> RankingList() 232 { 233 return await ProcessAsync<List<DrugsRankingDTO>>(()=> _drawQueryService.RankingList()); 234 } 235 236 #endregion 237 238 #region 隨機抽獎 239 240 /** 241 * @api {GET} api/Values/RandomDraw 隨機抽獎 242 * @apiGroup Draw 243 * @apiVersion 1.0.0 244 * @apiDescription 隨機抽獎 245 * @apiPermission 已登錄 246 * @apiParam {string} openId 微信唯一標識 247 * @apiParamExample {json} 請求樣例: 248 * api/Values/RandomDraw?openId=ooGIewyacAsO5MI_8SQM_kn95MTY 249 * @apiSuccess (200) {string} ResultMessage 操作成功 250 * @apiSuccess (200) {int} ResultCode 0返回成功,-1返回失敗 251 * @apiSuccessExample {json} 返回樣例: 252 * { 253 * "Data": { 254 * "HasNum": 2, 255 * "Prize": 1 256 * }, 257 * "ResultCode": 0, 258 * "ResultMessage": "操作成功" 259 * } 260 */ 261 /// <summary> 262 /// 隨機抽獎 263 /// </summary> 264 /// <param name="openId"></param> 265 /// <returns></returns> 266 [HttpGet] 267 public async Task<dynamic> RandomDraw(string openId) 268 { 269 return await ProcessAsync<ObjDTO>(() => _drawCommandService.RandomDraw(openId)); 270 } 271 272 #endregion 273 274 #region 用戶注冊 275 276 /** 277 * @api {post} api/Values/RegisterAccount 用戶注冊 278 * @apiGroup Draw 279 * @apiVersion 1.0.0 280 * @apiDescription 用戶注冊 281 * @apiPermission 已登錄 282 * @apiParamExample {json} 請求樣例: 283 * { 284 * "OpenID":XXX, // 微信唯一標識 285 * "AccountName":"小禾苗", // 用戶名 286 * "PhoneNumber":"15817468410", // 手機號碼 287 * "Password":"22222", // 驗證碼(密碼) 288 * "Address":"深圳國創" // 地址 289 * } 290 * @apiSuccess (200) {string} ResultMessage 操作成功 291 * @apiSuccess (200) {int} ResultCode 0返回成功,-1返回失敗 292 * @apiSuccessExample {json} 返回樣例: 293 * { 294 * "Data":true, 295 * "ResultCode": 0, 296 * "ResultMessage": "恭喜您注冊成功" 297 * } 298 */ 299 /// <summary> 300 /// 用戶注冊 301 /// </summary> 302 /// <param name="request"></param> 303 /// <returns></returns> 304 [HttpPost] 305 public async Task<dynamic> RegisterAccount(AccountDTO request) 306 { 307 308 #region 驗證碼驗證 309 string verifyCode = _cache.Get<string>(request.PhoneNumber); 310 if (string.IsNullOrEmpty(verifyCode)) 311 { 312 return Ok(new ApiResult<bool> { Data = false, ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "驗證碼已過期,請先重新發送" }); 313 } 314 if (verifyCode != request.Password) 315 { 316 return Ok(new ApiResult<bool> { Data = false, ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "驗證碼不正確,請重新輸入" }); 317 } 318 if (!StringHelper.IsPhoneNumber(request.PhoneNumber)) 319 { 320 return Ok(new ApiResult<bool> { Data = false, ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "手機號碼格式不正確" }); 321 } 322 323 #endregion 324 325 #region 注冊 326 327 var batAccount = _drawQueryService.IsExistBatAccount(request.PhoneNumber); 328 var h5Account = _drawQueryService.IsExistH5Account(request.PhoneNumber); 329 string Code = new VerifyCode().CreateVerifyCode(5);//驗證碼長度 330 331 if (batAccount != null && h5Account==null) 332 { 333 // 異步注冊賬號--H5 334 await ProcessAsync<bool>(() => _drawCommandService.RegisterH5Account(request)); 335 // 發送短信 336 var jsonString = SmsHelper.SendSMS(request.PhoneNumber, "39994", string.Format("{0},{1}", batAccount.AccountName, "http://c7.gg/aNx")); 337 return Ok(new ApiResult<bool> { Data = true, ResultCode = (int)EnumApiResponseStatus.Success, ResultMessage = "恭喜您注冊成功" }); 338 } 339 else if(batAccount == null && h5Account != null) 340 { 341 // 異步注冊賬號--BAT 342 await ProcessAsync<bool>(() => _drawCommandService.RegisterBatAccount(request)); 343 return Ok(new ApiResult<bool> { Data = false, ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "此手機號碼已經被使用" }); 344 } 345 else if (batAccount == null && h5Account == null) 346 { 347 // 異步注冊賬號--H5 348 await ProcessAsync<bool>(() => _drawCommandService.RegisterH5Account(request)); 349 // 異步注冊賬號--BAT 350 await ProcessAsync<bool>(() => _drawCommandService.RegisterBatAccount(request)); 351 // 發送短信 352 var jsonString = SmsHelper.SendSMS(request.PhoneNumber, "40006", string.Format("{0},{1},{2}",request.AccountName, Code, "http://c7.gg/aNx")); 353 return Ok(new ApiResult<bool> { Data = true, ResultCode = (int)EnumApiResponseStatus.Success, ResultMessage = "恭喜您注冊成功" }); 354 } 355 else 356 { 357 return Ok(new ApiResult<bool> { Data = false, ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "此手機號碼已經被使用" }); 358 } 359 360 #endregion 361 362 } 363 364 #endregion 365 366 #region 發送驗證碼 367 368 /** 369 * @api {get} api/Values/SendVerifyCode 發送驗證碼 370 * @apiGroup Draw 371 * @apiVersion 1.0.0 372 * @apiDescription 發送驗證碼 373 * @apiPermission 已登錄 374 * @apiParamExample {json} 請求樣例: 375 * api/Values/SendVerifyCode?toPhone=15817468410 376 * @apiSuccess (200) {string} ResultMessage 操作成功 377 * @apiSuccess (200) {int} ResultCode 0返回成功,-1返回失敗 378 * @apiSuccessExample {json} 返回樣例: 379 * { 380 * "Data":true, 381 * "ResultCode": 0, 382 * "ResultMessage": "操作成功" 383 * } 384 */ 385 [HttpGet] 386 public dynamic SendVerifyCode(string toPhone) 387 { 388 if(!StringHelper.IsPhoneNumber(toPhone)) 389 { 390 return Ok(new ApiResult<bool> { Data = false, ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "手機號碼不正確" }); 391 } 392 393 var ipAddress = RequestHelper.GetWebClientIp(); //獲取訪問IP 394 string IPADDRESS_KEY = string.Format("{0}_{1}", ipAddress, toPhone); 395 var sendVerifyCount = _cache.Get<int>(IPADDRESS_KEY); 396 if (sendVerifyCount > 0) 397 { 398 return new { ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "您請求太頻繁,請稍后再試" }; 399 } 400 else 401 { 402 _cache.Set<int>(IPADDRESS_KEY, sendVerifyCount + 1, TimeSpan.FromMinutes(3)); 403 } 404 405 string SENDMESSAGE_KEY = string.Format("MESSAGE_{0}", toPhone); 406 var sendMessage = _cache.Get<SendNoticeDTO>(SENDMESSAGE_KEY); 407 if (sendMessage != null) 408 { 409 //每天只能發送5條短信 410 if (sendMessage.SendTotal >= 5) 411 { 412 return new { ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "驗證碼發送過於頻繁,請明日再發!" }; 413 } 414 //三分鍾只能發送3次 415 if (sendMessage.SendTotal == 3 && sendMessage.LastSendTime.AddMinutes(3) > DateTime.Now) 416 { 417 return new { ResultCode = (int)EnumApiResponseStatus.ExceptionHappened, ResultMessage = "驗證碼發送,3分鍾內只能發3次,請稍后再試" }; 418 } 419 } 420 421 string verifyCode = new VerifyCode().CreateVerifyCode(5);//驗證碼長度 422 _cache.Set<string>(toPhone, verifyCode, TimeSpan.FromMinutes(3)); 423 var jsonString = SmsHelper.SendSMS(toPhone, "39998", string.Format("{0},{1}", verifyCode, 3)); 424 425 TimeSpan cacheTime = DateTime.Parse(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")) - DateTime.Now; 426 if (sendMessage == null) 427 { 428 _cache.Set<SendNoticeDTO>(SENDMESSAGE_KEY, new SendNoticeDTO() { SendTotal = 1, LastSendTime = DateTime.Now }, cacheTime); 429 } 430 else 431 { 432 _cache.Set<SendNoticeDTO>(SENDMESSAGE_KEY, new SendNoticeDTO() { SendTotal = sendMessage.SendTotal + 1, LastSendTime = DateTime.Now }, cacheTime); 433 } 434 435 return Ok(new ApiResult<bool> { Data = true, ResultCode = (int)EnumApiResponseStatus.Success, ResultMessage = "短信發送成功" }); 436 } 437 438 #endregion 439 440 #region 獲取我的獎品 441 442 /** 443 * @api {get} api/Values/GetMyPrize 獲取我的獎品 444 * @apiGroup Draw 445 * @apiVersion 1.0.0 446 * @apiDescription 獲取我的獎品 447 * @apiPermission 已登錄 448 * @apiParamExample {json} 請求樣例: 449 * api/Values/GetMyPrize?openId=XXX 450 * @apiSuccess (200) {string} ResultMessage 操作成功 451 * @apiSuccess (200) {int} ResultCode 0返回成功,-1返回失敗 452 * @apiSuccessExample {json} 返回樣例: 453 * { 454 * "Data":1, 455 * "ResultCode": 0, 456 * "ResultMessage": "操作成功" 457 * } 458 */ 459 /// <summary> 460 /// 獲取我的獎品 461 /// </summary> 462 /// <returns></returns> 463 [HttpGet] 464 public async Task<dynamic> GetMyPrize(string openId) 465 { 466 return await ProcessAsync<int?>(() => _drawQueryService.GetMyPrize(openId)); 467 } 468 469 #endregion 470 471 #region 獎品列表 472 473 /** 474 * @api {get} api/Values/GetPrizeList 獎品列表 475 * @apiGroup Draw 476 * @apiVersion 1.0.0 477 * @apiDescription 獎品列表 478 * @apiPermission 已登錄 479 * @apiParamExample {json} 請求樣例: 480 * api/Values/GetPrizeList?pageIndex=0&pageSize=15 481 * @apiSuccess (200) {string} ResultMessage 操作成功 482 * @apiSuccess (200) {int} ResultCode 0返回成功,-1返回失敗 483 * @apiSuccessExample {json} 返回樣例: 484 * { 485 * "Data": 486 * [{ 487 "AccountName": "11", // 用戶名 488 "PhoneNumber": "15817468414", // 電話號碼 489 "Prize": 4, // 獎品索引(不用展示) 490 "PrizeName": "一等獎", // 獎品名稱 491 "Address": "345345345345", // 地址 492 "CreatedTime": "2017-03-30 10:31:37" // 創建時間 493 }], 494 * 495 * "ResultCode": 0, 496 * "ResultMessage": "操作成功", 497 * "RecordsCount":100 498 * } 499 */ 500 /// <summary> 501 /// 獎品列表 502 /// </summary> 503 /// <param name="pageIndex"></param> 504 /// <param name="pageSize"></param> 505 /// <returns></returns> 506 [HttpGet] 507 public dynamic GetPrizeList(int pageIndex=0,int pageSize=15) 508 { 509 int count = 0; 510 var data=_drawQueryService.GetPrizeList(pageIndex, pageSize,out count); 511 return Ok(new { Data = data, RecordsCount = count, ResultCode = (int)EnumApiResponseStatus.Success, ResultMessage = "操作成功" }); 512 513 } 514 515 #endregion 516 }