12、ABPZero系列教程之拼多多卖家工具 拼团提醒功能登录拼多多实现
上篇文章已经完成了整个拼多多拼团提醒功能,本篇继续完成拼多多帐号登录,拼多多帐号登录的目的是为了获取拼团商品的SKU和订单号,便于商家备货。
以下是拼多多官方的后台登录,要实现的功能并不是直接在这里登录,而是在项目通过发送数据包的方式去登录,主要就是拿到登录后的cookie或token。
注:做此功能需要准备拼多多卖家帐号,如果没有,可以跳过本篇内容。
PddTool项目
添加CodeResponse.cs文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\PddTool\PddApi\Response\CodeResponse.cs
public class CodeResponse { /// <summary> /// /// </summary> public bool result { get; set; } /// <summary> /// /// </summary> public Data data { get; set; } } public class Data { /// <summary> /// /// </summary> public string token { get; set; } /// <summary> /// /// </summary> public string image { get; set; } }
添加UserResponse.cs文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\PddTool\PddApi\Response\UserResponse.cs
/// <summary> /// 登录返回 /// </summary> public class UserResponse { /// <summary> /// /// </summary> public bool authResult { get; set; } /// <summary> /// /// </summary> public UserInfo userInfo { get; set; } /// <summary> /// /// </summary> public string inMobileWhiteList { get; set; } /// <summary> /// /// </summary> public string mobileVerification { get; set; } } public class UserInfo { /// <summary> /// 用户id /// </summary> public int id { get; set; } /// <summary> /// 用户名 /// </summary> public string username { get; set; } /// <summary> /// 店铺id /// </summary> public int mallId { get; set; } /// <summary> /// /// </summary> public int passwordStatus { get; set; } /// <summary> /// 手机 /// </summary> public string mobile { get; set; } /// <summary> /// 昵称 /// </summary> public string nickname { get; set; } /// <summary> /// 角色id列表 /// </summary> public List<int> roleIdList { get; set; } /// <summary> /// 店铺管理员 /// </summary> public bool mallOwner { get; set; } /// <summary> /// /// </summary> public List<string> roleNameList { get; set; } /// <summary> /// /// </summary> public List<string> permissionList { get; set; } /// <summary> /// 登录cookie /// </summary> public string Cookie { get; set; } }
添加RequestErrorResponse.cs文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\PddTool\PddApi\Response\RequestErrorResponse.cs
/// <summary> /// 请求错误返回 /// </summary> public class RequestErrorResponse { /// <summary> /// /// </summary> public string error_msg { get; set; } /// <summary> /// /// </summary> public int error_code { get; set; } }
添加LoginRequest.cs文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\PddTool\PddApi\Request\LoginRequest.cs
/// <summary> /// 拼多多登录 /// </summary> public class LoginRequest { /// <summary> /// 用户名 /// </summary> public string Username { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } /// <summary> /// 验证码 /// </summary> public string Code { get; set; } /// <summary> /// 令牌 /// </summary> public string Token { get; set; } }
修改MallTool.cs文件,末尾添加如下代码:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\PddTool\MallTool.cs
/// <summary> /// 取验证码 /// </summary> /// <returns></returns> public static CodeResponse GetCode() { string url = string.Format("http://mms.pinduoduo.com/captchaCode/getCaptchaCode?rd=" + Guid.NewGuid()); var client = new RestClient(url); var request = new RestRequest(Method.GET); request.AddHeader("cache-control", "no-cache"); request.AddHeader("referer", "http://mms.pinduoduo.com/Pdd.html"); IRestResponse response = client.Execute(request); var code = JsonConvert.DeserializeObject<CodeResponse>(response.Content); return code; } /// <summary> /// 拼多多登录 /// </summary> /// <param name="data"></param> /// <returns></returns> public static UserResponse Login(LoginRequest data) { string url = "http://mms.pinduoduo.com/auth"; var client = new RestClient(url); var request = new RestRequest(Method.POST); request.AddParameter("username", data.Username); request.AddParameter("password", data.Password); request.AddParameter("authCode", data.Code); request.AddParameter("verificationCode", ""); request.AddParameter("token", data.Token); request.AddHeader("cache-control", "no-cache"); IRestResponse response = client.Execute(request); if (response.Content.Contains("error_code")) { var error = JsonConvert.DeserializeObject<RequestErrorResponse>(response.Content); throw new UserFriendlyException(error.error_msg); } var c = response.Cookies.Single(a => a.Name.Equals("PASS_ID")); var cookie = c.Value; var user = JsonConvert.DeserializeObject<UserResponse>(response.Content); user.userInfo.Cookie = cookie; return user; }
到这里就把拼多多后台登录封装好了,就2个方法,一个获取验证码、一个提交post数据登录。
Application项目
修改IMallAppService.cs文件,添加2个方法,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\Pdd\MallApp\IMallAppService.cs
/// <summary> /// 取验证码 /// </summary> /// <returns></returns> CodeOutput GetCode(); /// <summary> /// 登录 /// </summary> /// <returns></returns> UserInfoOutput Login(LoginInput input);
添加CodeOutput.cs文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\Pdd\MallApp\Dto\CodeOutput.cs
public class CodeOutput { /// <summary> /// 图片 /// </summary> public string Image { get; set; } /// <summary> /// 令牌 /// </summary> public string Token { get; set; } }
添加UserInfoOutput.cs文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\Pdd\MallApp\Dto\UserInfoOutput.cs
public class UserInfoOutput { /// <summary> /// 用户名 /// </summary> public string Username { get; set; } /// <summary> /// 店铺id /// </summary> public int MallId { get; set; } /// <summary> /// /// </summary> public string Cookie { get; set; } }
添加LoginInput.cs文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\Pdd\MallApp\Dto\LoginInput.cs
public class LoginInput { /// <summary> /// 用户名 /// </summary> public string Username { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } /// <summary> /// 验证码 /// </summary> public string Code { get; set; } /// <summary> /// 令牌 /// </summary> public string Token { get; set; } }
修改MallAppService.cs文件,实现接口添加的2个方法,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\Pdd\MallApp\MallAppService.cs
/// <summary> /// 获取验证码 /// </summary> /// <returns></returns> public CodeOutput GetCode() { var code = MallTool.GetCode(); if (code.result == false) { throw new UserFriendlyException("验证码获取失败!"); } return new CodeOutput() { Image = code.data.image, Token = code.data.token }; } /// <summary> /// 登录 /// </summary> /// <returns></returns> public UserInfoOutput Login(LoginInput input) { var data = Mapper.Map<LoginRequest>(input); try { var key = string.Format("{0}_{1}_Mall", AbpSession.UserId, input.Username); var cache = _cacheManager.GetCache<string, UserResponse>(key); if (cache != null) { cache.Clear(); } var user = _cacheManager.GetCache<string, UserResponse>(key).Get("Login." + input.Username, () => MallTool.Login(data)); //登录成功清除对应店铺开团商品的缓存 key = string.Format("{0}_{1}_KaiTuan", AbpSession.UserId, user.userInfo.mallId); _cacheManager.GetCache<string, List<KaiTuan>>(key).Clear(); return new UserInfoOutput() { Cookie = user.userInfo.Cookie, MallId = user.userInfo.mallId, Username = input.Username }; } catch (Exception ex) { throw new UserFriendlyException("登录失败:" + ex.Message); } }
打开CustomDtoMapper.cs文件,添加如下映射:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\CustomDtoMapper.cs
mapper.CreateMap<LoginInput, LoginRequest>();
生成解决方案,浏览器打开http://localhost:8088/swagger/ui/index,测试刚刚添加的2个api。
接下来页面实现。
打开KaiTuanController.cs文件,添加如下代码:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Areas\Mpa\Controllers\Pdd\KaiTuanController.cs
public ActionResult LoginModal() { var code = _mallAppService.GetCode(); ViewBag.code = code; return PartialView("_LoginModal"); }
添加对应的视图文件_LoginModal.cshtml,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Areas\Mpa\Views\KaiTuan\_LoginModal.cshtml
@using MyCompanyName.AbpZeroTemplate.Pdd.MallApp.Dto @using MyCompanyName.AbpZeroTemplate.Web.Areas.Mpa.Models.Common.Modals @{ var code = ViewBag.code as CodeOutput; } @Html.Partial("~/Areas/Mpa/Views/Common/Modals/_ModalHeader.cshtml", new ModalHeaderViewModel("登录拼多多")) <div class="modal-body"> <form name="LoginForm" class="form-horizontal margin-bottom-40" role="form"> <input id="token" type="hidden" name="token" value="@code.Token" /> <div class="form-group form-md-line-input"> <div class="col-md-6"> <div class="input-icon"> <input type="text" class="form-control" name="username" placeholder="帐号名/手机号"> <div class="form-control-focus"> </div> <i class="fa fa-user"></i> </div> </div> </div> <div class="form-group form-md-line-input"> <div class="col-md-6"> <div class="input-icon right"> <input type="password" class="form-control" name="password" placeholder="密码"> <div class="form-control-focus"> </div> <i class="fa fa-key"></i> </div> <div class="help-block"> with right aligned icon </div> </div> </div> <div class="form-group form-md-line-input"> <div class="col-md-6"> <div class="input-group"> <input type="text" class="form-control" name="code" placeholder=""> <div class="form-control-focus"> </div> <div class="input-group-addon"> <img id="img" src="@code.Image" style="width: 113px; height: 30px;" /> </div> </div> </div> </div> <div class="form-group"> <div class="col-md-offset-4 col-md-10"> <button type="button" class="btn green save-button">登录</button> </div> </div> </form> </div> @Html.Partial("~/Areas/Mpa/Views/Common/Modals/_ModalFooterWithCancel.cshtml")
添加视图对应的JS文件,代码如下:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Areas\Mpa\Views\KaiTuan\_LoginModal.js
var _mallService = abp.services.app.mall; (function ($) { app.modals.LoginModal = function () { var _$loginForm = null; var _modalManager; this.init = function (modalManager) { _modalManager = modalManager; //取出Form表单 _$loginForm = _modalManager.getModal().find('form[name=LoginForm]'); }; this.save = function () { //验证不通过返回 if (!_$loginForm.valid()) { return; } //序列化参数 var login = _$loginForm.serializeFormToObject(); _modalManager.setBusy(true); _mallService.login( login ).done(function (data) { _modalManager.close(); abp.event.trigger('app.loginModalSaved', { username: data.username }); }).always(function () { _modalManager.setBusy(false); }); }; }; function getCode() { _mallService.getCode().done(function (data) { $("#img").attr("src", data.image); $("#token").val(data.token); }); } //getCode(); $("#img").click(function () { getCode(); }); })(jQuery);
打开文件Index.js,添加如下代码:
文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Areas\Mpa\Views\KaiTuan\Index.js
6行位置添加一个变量:
var username;//记录登录拼多多用户名
26行位置添加如下代码:
/** 登录模态框 */ var _loginModal = new app.ModalManager({ viewUrl: abp.appPath + 'Mpa/KaiTuan/LoginModal', scriptUrl: abp.appPath + 'Areas/Mpa/Views/KaiTuan/_LoginModal.js', modalClass: 'LoginModal' });
178行位置添加如下代码:
//登录拼多多 $("#LoginPddButton").click(function () { _loginModal.open(); }); abp.event.on('app.loginModalSaved', function (data) { console.info("成功", data); username = data.username; toastr["success"]("登录拼多多成功", "提示"); });
生成解决方案,浏览器登录后台测试。