@源码地址来源: https://minglisoft.cn/honghu2/business.html

微信小程序登录代码:

/*** Copyright &copy; 2012-2017 <a href="http://minglisoft.cn">HongHu</a> All rights reserved.*/
package com.honghu.cloud.controller;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang.StringUtils;
import org.bouncycastle.util.encoders.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.auth0.jwt.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.google.common.collect.Maps;
import com.honghu.cloud.bean.User;
import com.honghu.cloud.code.ResponseCode;
import com.honghu.cloud.constant.Globals;
import com.honghu.cloud.dto.AccessoryDto;
import com.honghu.cloud.dto.PaymentDto;
import com.honghu.cloud.dto.StoreDto;
import com.honghu.cloud.dto.SysConfigDto;
import com.honghu.cloud.dto.UserDto;
import com.honghu.cloud.feign.AccessoryFeignClient;
import com.honghu.cloud.feign.DistributionUserFeignClient;
import com.honghu.cloud.feign.FtpFileFeignClient;
import com.honghu.cloud.feign.PaymentFeignClient;
import com.honghu.cloud.feign.StoreFeignClient;
import com.honghu.cloud.feign.SysConfigFeignClient;
import com.honghu.cloud.feign.TencentIMFeignClient;
import com.honghu.cloud.redis.RedisUtil;
import com.honghu.cloud.service.IUserService;
import com.honghu.cloud.tools.SecurityUserHolder;
import com.honghu.cloud.tools.wx.WXCore;
import com.honghu.cloud.utils.CommUtil;
import com.honghu.cloud.utils.Exceptions;
import com.honghu.cloud.utils.HttpClientUtils;
import com.honghu.cloud.utils.JWT;
import com.honghu.cloud.utils.tools.Md5Encrypt;import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;/*** 微信小程序登录Controller* @author Administrator**/
@Slf4j
@RestController
@RequestMapping(value = "/weChat")
public class WeChatLoginController  {@Autowiredprivate IUserService userService;@Autowiredprivate RedisUtil redisUtil;@Autowiredprivate SysConfigFeignClient sysConfigFeignClient;@Autowiredprivate DistributionUserFeignClient disUserFeignClient;@Autowiredprivate FtpFileFeignClient ftpFileFeignClient;@Autowiredprivate TencentIMFeignClient tencentIMFeignClient;@Autowiredprivate StoreFeignClient storeFeignClient;@Autowiredprivate PaymentFeignClient paymentFeignClient;
/*    @Autowiredprivate AccessoryFeignClient accessoryFeignClient;*/private static final Logger logger = LoggerFactory.getLogger(WeChatLoginController.class);/***微信获取登录凭证url***/private static final String CODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";/*** 小程序登录* @param js_code 登录code* @param iv  加密算法的初始向量* @param encryptedData 敏感用户数据* @param share_uid 邀请注册用户* @return*/@RequestMapping(value = "/login", method = RequestMethod.POST)public  Map<String, Object>  login(@RequestBody JSONObject json) {String js_code = json.optString("js_code");String iv = json.optString("iv");String encryptedData = json.optString("encryptedData");String share_uid = json.optString("share_uid");String source_type = json.optString("source_type");String nickName = json.optString("nickName");String userphoto = json.optString("photo");/*SysConfigDto sysConfigDto = sysConfigFeignClient.getSysConfig();String appid = sysConfigDto.getOpen_weixin_appId(); String secret = sysConfigDto.getOpen_weixin_appSecret();*/ // 微信APPID、微信密匙Map<String, Object> param = Maps.newHashMap();param.put("mark", "wx_miniprogram");List<PaymentDto> payments = paymentFeignClient.queryPageList(param);PaymentDto payment =null;if (payments.size() > 0) {payment = (PaymentDto) payments.get(0);}if (payment==null||StringUtils.isEmpty(payment.getWx_appid()) || StringUtils.isEmpty(payment.getWx_appSecret())) {return ResponseCode.buildCodeMap("40031", "获取微信配置信息有误!", null);}Map<String,String> params = new HashMap<String, String>();params.put("appid", payment.getWx_appid());params.put("secret", payment.getWx_appSecret());params.put("js_code", js_code);params.put("grant_type", "authorization_code");String jsonStr = HttpClientUtils.doGet(CODE2SESSION_URL, params, "UTF-8");JSONObject jsonObj = JSONObject.fromObject(jsonStr);// 错误码String errcode = jsonObj.optString("errcode");if(StringUtils.equals(errcode, "40028")){ // code 无效return ResponseCode.buildCodeMap("40028", "code 无效!", null);}// errcode[-1:系统繁忙,此时请开发者稍候再试;45011:频率限制,每个用户每分钟100次]if(StringUtils.equals(errcode, "45011") || StringUtils.equals(errcode, "-1")){return ResponseCode.buildCodeMap("45011", "系统繁忙,请稍后再试!", null);}String session_key = jsonObj.optString("session_key");String openid = jsonObj.optString("openid");// 会话密钥和用户唯一标识为空,表示服务请求失败,记录日志if(StringUtils.isEmpty(session_key) || StringUtils.isEmpty(openid)){return ResponseCode.buildCodeMap("40029", "code无效!", null);}// 解析小程序加密用户数据String userInfo = WXCore.decrypt(payment.getWx_appid(), encryptedData, session_key, iv);if(StringUtils.isEmpty(userInfo)){return ResponseCode.buildCodeMap("40030", "获取用户数据失败!", null);}JSONObject userJson = JSONObject.fromObject(userInfo);// 开放平台的唯一标识符String unionid = userJson.optString("unionId");if(StringUtils.isEmpty(unionid)){return ResponseCode.buildCodeMap("40032", "获取用户数据失败!", null);}boolean phone=false;User user=null;boolean flag = false;   //true 则不需要授权手机号// 根据开放平台的唯一标识签,查询用户对象是否存在,不存在注册一条数据synchronized (this) {user = userService.selectByUnionid(unionid);if(user !=  null && user.getSecurity() == 1){return ResponseCode.buildCodeMap("40031", "账户存在安全隐患禁止登录!", null);}if (user!=null&&user.getUsername()!=null&&StringUtils.isNotBlank(user.getMobile())) {phone=true;}if(user == null){flag = true;user = new User();user.setOpenId(openid);if (StringUtils.isNotEmpty(nickName)) {user.setNickName(nickName);}else{user.setNickName(userJson.optString("nickName"));  //微信提供的默认头像}user.setWeixin_unionID(unionid);user.setDay_msg_count(0); user.setDeleteStatus(0);user.setAddTime(new Date());user.setPassword(Md5Encrypt.md5("123456").toLowerCase());//设置默认密码为123456user.setYears(0); // 用户年龄user.setIs_live(0);user.setLive_code(userService.selectMaxLiveCode() + 1);user.setUser_type(0); // 用户类别,默认为0个人用户,1为企业用户user.setStore_apply_step(0); // 店铺申请进行的步骤,默认为0user.setInvoiceType(0); // 发票类型user.setWhether_attention(1); //是否允许关注 0为不允许,1为允许user.setUser_form("miniProgram"); //注册来源,分为pc,android,ios,miniProgram, WXOffiaccountif (StringUtils.isNotEmpty(source_type)) {user.setSource_type(CommUtil.null2Int(source_type));    //1为海报}userService.saveEntity(user);user = userService.selectByUnionid(unionid);}else if(StringUtils.equals(user.getUser_form(), "WXOffiaccount") && StringUtils.isBlank(user.getOpenId())){  //通过微信公众号注册的user.setOpenId(openid);userService.updateById(user);flag = true;   //微信注册第一次进来分销关系重新建立}}boolean isUpdate=false;// 处理用户头像(用户头像不存在,将微信的头像保存到用户头像)//String photo_url = userJson.optString("avatarUrl");if(user.getPhoto_id() == null && StringUtils.isNotEmpty(userphoto)){AccessoryDto photo = uploadPhotoFile(userphoto, user.getId());if(photo != null){user.setPhoto(photo);user.setPhoto_id(photo.getId());isUpdate=true;}}//用户换名称或头像if(user.getNickName()==null){user.setNickName(nickName);isUpdate=true;}if (user.getLive_code()==null) {user.setLive_code(userService.selectMaxLiveCode() + 1);isUpdate=true;}if (StringUtils.isNotEmpty(nickName) && StringUtils.isEmpty(user.getNickName())) {user.setNickName(nickName);isUpdate = true;}if (StringUtils.isEmpty(user.getOpenId())) {user.setOpenId(openid);isUpdate = true;}if (isUpdate) {userService.updateById(user);}//所有用户都是分销用户if(flag){userService.saveDisUser(user, share_uid);}// 生成token,格式:用户id;时间戳  String token = JWT.sign(user.getId() + ";" + System.currentTimeMillis()+";"+"small", 0);// 将token存到redis中,有效期24小时 redisUtil.set(Globals.WECHAT_LOGIN_MARK + user.getId(), token, Globals.USER_INFO_EXPIRE_TIME);// 覆盖redis用户信息UserDto userDto = new UserDto();BeanUtils.copyProperties(user, userDto);redisUtil.set(Globals.USER_INFO_MARK + user.getId(), userDto, Globals.USER_INFO_EXPIRE_TIME);String storestatus="";if (userDto.getStore_id()!=null) {StoreDto storeDto = storeFeignClient.selectByPrimaryKey(userDto.getStore_id());if (storeDto!=null) {storestatus=storeDto.getStore_status()+"";}}HashMap<String, Object> result = new HashMap<>();result.put("token", token);result.put("storestatus", storestatus);SysConfigDto sysConfig = sysConfigFeignClient.getSysConfig();if (sysConfig.getOpen_live()==0) {result.put("phone", true);}else{result.put("phone", phone);}result.put("session_key", session_key);result.put("user", user);if (user != null&&user.getIs_live()!=null) {result.put("is_live", user.getIs_live()==2?true:false);}else{result.put("is_live", false);}return ResponseCode.buildSuccessMap(result);}/*** 保存用户手机号* @return*/@RequestMapping(value = "/savePhone", method = RequestMethod.POST)public Map<String, Object> savePhone(HttpServletRequest request, @RequestBody JSONObject json) {String session_key = json.optString("session_key");String iv = json.optString("iv");String encryptedData = json.optString("encrypData");if (StringUtils.isBlank(session_key)) {return ResponseCode.buildFailMap("获取失败,session_key信息错误", null);}if (StringUtils.isBlank(iv)) {return ResponseCode.buildFailMap("获取失败,iv信息错误", null);}if (StringUtils.isBlank(encryptedData)) {return ResponseCode.buildFailMap("获取失败,encryptedData信息错误", null);}byte[] dataByte = Base64.decode(encryptedData);// 加密秘钥byte[] keyByte = Base64.decode(session_key);// 偏移量byte[] ivByte = Base64.decode(iv);try {// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要int base = 16;if (keyByte.length % base != 0) {int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);byte[] temp = new byte[groups * base];Arrays.fill(temp, (byte) 0);System.arraycopy(keyByte, 0, temp, 0, keyByte.length);keyByte = temp;}// 初始化Security.addProvider(new BouncyCastleProvider());Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");parameters.init(new IvParameterSpec(ivByte));cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化byte[] resultByte = cipher.doFinal(dataByte);if (null != resultByte && resultByte.length > 0) {String result = new String(resultByte, "UTF-8");JSONObject fromObject = JSONObject.fromObject(result);Object object = fromObject.get("purePhoneNumber");User user = userService.selectByPrimaryKey(SecurityUserHolder.getCurrentUserId(request));//查询是否已经存在该手机号User UserName = userService.selectByUserName(CommUtil.null2String(object));//需要合并用户    ,          手机号存在, 并且 unionid 为空     if (UserName!=null&&StringUtils.isEmpty(UserName.getWeixin_unionID())) {UserName.setWeixin_unionID(user.getWeixin_unionID());    //将新unionid 存入旧数据中if (UserName.getLive_code()==null) {UserName.setLive_code(userService.selectMaxLiveCode() + 1);}if (StringUtils.isEmpty(UserName.getNickName())) {UserName.setNickName(user.getNickName());}if (user.getPhoto_id()!=null) {UserName.setPhoto_id(user.getPhoto_id());}if (user.getOpenId()!=null) {UserName.setOpenId(user.getOpenId());}if (user.getWx_open_id()!=null) {UserName.setWx_open_id(user.getWx_open_id());;}userService.updateById(UserName);user.setDeleteStatus(1);user.setMobile("del"+CommUtil.null2String(object));user.setUserName("del"+CommUtil.null2String(object));user.setWeixin_unionID("del"+UserName.getId()+"");userService.updateById(user);disUserFeignClient.deleteByUserId(user.getId());   //删除新的 分销关系表redisUtil.remove(Globals.WECHAT_LOGIN_MARK + user.getId());//换用户登录// 生成token,格式:用户id;时间戳  String token = JWT.sign(UserName.getId() + ";" + System.currentTimeMillis()+";"+"small", 0);// 将token存到redis中,有效期24小时 redisUtil.set(Globals.WECHAT_LOGIN_MARK + UserName.getId(), token, Globals.USER_INFO_EXPIRE_TIME);// 覆盖redis用户信息UserDto userDto = new UserDto();BeanUtils.copyProperties(UserName, userDto);redisUtil.set(Globals.USER_INFO_MARK + UserName.getId(), userDto, Globals.USER_INFO_EXPIRE_TIME);return ResponseCode.buildSuccessMap(token);}//删除/*//手机号跟原来一致, 直接通过if (CommUtil.null2String(object).equals(user.getUserName())) {return ResponseCode.buildSuccessMap("isOk");}*///手机号已存在if (UserName!=null) {return ResponseCode.buildFailMap("手机号已存在", "false");}user.setUserName(CommUtil.null2String(object));user.setMobile(CommUtil.null2String(object));userService.updateById(user);return ResponseCode.buildSuccessMap(null);}} catch (Exception e) {e.printStackTrace();}return ResponseCode.buildFailMap("信息有误", "false");}/*** 分享邀请用户注册的分享链接* @return*/@RequestMapping(value = "/shareLogin", method = RequestMethod.POST)public Map<String, Object> shareLogin( HttpServletRequest request) {UserDto user = SecurityUserHolder.getCurrentUser(request);if(user == null || user.getId() == null){return ResponseCode.buildEnumMap(ResponseCode.TOKEN_EXPIRE, null);}return ResponseCode.buildSuccessMap(user.getId());}/*** 分享邀请用户注册的分享链接* @return*/@RequestMapping(value = "/checkUserPhone", method = RequestMethod.POST)public Map<String, Object> checkUserPhone( HttpServletRequest request) {UserDto user = SecurityUserHolder.getCurrentUser(request);if(user == null || user.getId() == null){return ResponseCode.buildEnumMap(ResponseCode.TOKEN_EXPIRE, null);}User new_user = userService.selectByPrimaryKey(user.getId());if (new_user.getMobile()==null||new_user.getUserName()==null) {return ResponseCode.buildEnumMap(ResponseCode.RESPONSE_CODE_USER_MOBILE_OR_TELEPHONE_NOT_EMPTY, null);}return ResponseCode.buildSuccessMap(null);}/*** 分享邀请用户购买商品的分享链接* @return*/@RequestMapping(value = "/shareGoods", method = RequestMethod.POST)public Map<String, Object> shareGoods( HttpServletRequest request) {UserDto user = SecurityUserHolder.getCurrentUser(request);if(user == null || user.getId() == null){return ResponseCode.buildEnumMap(ResponseCode.TOKEN_EXPIRE, null);}return ResponseCode.buildSuccessMap(user.getId());}/*** @Description 将字符串中的emoji表情转换成可以在utf-8字符集数据库中保存的格式(表情占4个字节,需要utf8mb4字符集)* @param str* 待转换字符串* @return 转换后字符串* @throws UnsupportedEncodingException* exception*/public static String emojiConvert1(String str) {String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(str);StringBuffer sb = new StringBuffer();while (matcher.find()) {try {matcher.appendReplacement(sb, "[[" + URLEncoder.encode(matcher.group(1), "UTF-8") + "]]");} catch (Exception e) {}}matcher.appendTail(sb);return sb.toString();}/*** 微信授权登录上传头像* @param photo_url* @param user_id* @return*/public AccessoryDto uploadPhotoFile(String photo_url, Long user_id){try {AccessoryDto accessoryDto = ftpFileFeignClient.upload("user/image", "", "JPG", user_id, photo_url);return accessoryDto;} catch (Exception e) {log.error("微信授权登录上传头像失败:"+Exceptions.getStackTraceAsString(e));}return null;}/*** 将全部的用户注册IM账号* @return*/@RequestMapping(value = "/IM/outImportMultipleAccounts", method = RequestMethod.GET)public boolean outImportMultipleAccounts() {//获取所有用户的信息Map<String, Object> params = new HashMap<String, Object>();params.put("deleteStatus", "0");int count = userService.selectCount(params);int pageNum = (count/100)+1;    //腾讯只支持最多100个账号删除boolean bol = true;for(int i = 1; i <= pageNum; i++){params.put("currentPage", i);params.put("pageSize", 100);List<User> list = userService.queryPages(params);List<String> uids = new ArrayList<String>();for (User user : list) {uids.add(user.getId().toString());}bol = tencentIMFeignClient.importMultipleAccounts(uids);}return bol;}/*** 将全部的用户注册IM账号* @return*/@RequestMapping(value = "/IM/outAccountDelete", method = RequestMethod.GET)public boolean outAccountDelete() {//获取所有用户的信息Map<String, Object> params = new HashMap<String, Object>();params.put("deleteStatus", "0");int count = userService.selectCount(params);int pageNum = (count/100)+1;    //腾讯只支持最多100个账号删除boolean bol = true;for(int i = 1; i <= pageNum; i++){params.put("currentPage", i);params.put("pageSize", 100);List<User> list = userService.queryPages(params);List<String> uids = new ArrayList<String>();for (User user : list) {uids.add(user.getId().toString());}bol = tencentIMFeignClient.accountDelete(uids);}return bol;}/*** 微信授权登录* @param code 授权临时票据* @return map* @throws Exception*/@RequestMapping(value = "/weChatLogin" , method = RequestMethod.GET)public Map<String, Object> weChatLogin(@RequestParam("code") String code) throws Exception {return userService.weChatLogin(code);}/*** 微信授权登录(uniapp使用)* @param code 授权临时票据* @return map* @throws Exception*/@RequestMapping(value = "/appWeChatLogin" , method = RequestMethod.POST)public Map<String, Object> appWeChatLogin(@RequestBody JSONObject json) throws Exception {return userService.appWeChatLogin(json);}@RequestMapping(value = "/appWeChatLoginNew" , method = RequestMethod.POST)public Map<String, Object> appWeChatLoginNew(@RequestBody JSONObject json) throws Exception {return userService.appWeChatLoginNew(json);}/*** 微信授权登录* @param code 授权临时票据* @return map* @throws Exception*/@RequestMapping(value = "/weChatH5Login" , method = RequestMethod.GET)public Map<String, Object> weChatH5Login(@RequestParam("code") String code) throws Exception {return userService.weChatH5Login(code);}}
@源码地址来源: https://minglisoft.cn/honghu2/business.html
​

java版微信小程序之多商家入驻前后端分离商城源码 Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c相关推荐

  1. java版微信小程序登录商城源码Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  2. java版微信小程序多商家入驻前后端分离商城源码 Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  3. java版聚合支付源码Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu/business.html 电商微信支付.支付宝支付.余额支付代码 package com.honghu.cloud.con ...

  4. java版商城源码之聚合支付Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离

    @源码地址来源: https://minglisoft.cn/honghu/business.html package com.honghu.cloud.controller;import java. ...

  5. java版商城源码之商家中心Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu/business.html /*** Copyright © 2012-2017 <a href="http ...

  6. java版微信小程序登录商城源码Spring Cloud+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  7. java版微信小程序登录商城源码MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  8. 微信小程序java版Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  9. Java版商城源码+VR全景+b2b2c多商家入驻前后端分离商城源码

    1. 涉及平台 平台管理.商家端(PC端.手机端).买家平台(H5/公众号.小程序.APP端(IOS/Android).微服务平台(业务服务.系统服务.中间件服务) 2. 核心架构 Spring Cl ...

最新文章

  1. 每秒上万并发下的Spring Cloud参数优化实战
  2. Leetcode 532.数组中的K-diff数对
  3. 选择排序之小白学算法
  4. Java虚拟机和Dalvik(android)虚拟机的区别
  5. jQuery的三种bind/One/Live/On事件绑定使用方法
  6. curl 请求日志_HTTP入门(一):在Bash中curl查看请求与响应
  7. Restful Service 中 DateTime 在 url 中传递
  8. 现代程序设计 作业4
  9. 交流信号叠加直流偏置_T型偏置器与隔直器,二者应用之对比
  10. 以太坊智能合约部署与交互
  11. 图像匹配所用方法总结
  12. 阿里巴巴和淘宝集团web安全标准
  13. 早起—怎样开启高效的一天?
  14. 幸存与否 ——泰坦尼克号沉船事件数据分析*
  15. python找不到了_python包找不到
  16. FPGA(五):Quartus II 调用Fir IP核使用说明
  17. window.open 在Safari中被拦截
  18. 学着搭建流媒体服务器
  19. 20189200余超 2018-2019-2 移动平台应用开发实践第九周作业
  20. IDEA运行web项目及乱码处理

热门文章

  1. LeetCode(69) Sqrt(x)
  2. java 自定义注解 校验经纬度
  3. 姓氏拼音,多音字的解决方法
  4. phpexcel 读取excel文件在将数据插入数据库
  5. 2017考研计算机百度云,2017考研计算机全解析​
  6. 自学软件测试,学到什么程度可以出去找工作?
  7. ElasticSearch教程——cardinality(去重)算法之优化内存开销以及HLL算法
  8. 基于51单片机的智能停车场管理车位引导检测系统Proteus仿真设计DIY开发板套件
  9. GDC翻译:Far Cry 5 的程序化世界生成(第三部分:7-生态工具(Biome Tool))
  10. 物联网大潮下的金融变革 智慧银行时代到来