宁波网站建设网络推广,wordpress站点app开发,建一个网站流程,百度怎么在视频下方投放广告目录 用户模块需求分析静态网站部署与调试两种前端项目的部署两种前端项目的调试(热部署)创建静态web项目 注册分析与设计分析需求设计 界面设计#xff08;ui#xff09;设计表#xff08;后台#xff09; 流程设计#xff08;后台#xff09;三范式表设计流程设计 相关… 目录 用户模块需求分析静态网站部署与调试两种前端项目的部署两种前端项目的调试(热部署)创建静态web项目 注册分析与设计分析需求设计 界面设计ui设计表后台 流程设计后台三范式表设计流程设计 相关技术准备1.随机字符串(用StrUtils工具类)2.springdata-redis3.Md5技术4.短信接口 发送短信验证码前端页面准备发送短信后台搭建用户模块单独写公共可用的发短信接口VerifycodeControllerVerifycodeServiceImpl 用户模块需求分析
用户注册登录信息基本信息安全信息
用户登录账号登录扫码登录-自己app扫描页面三方登录-使用三方app微信qq支付宝等验证码登录-自己做 reids.set(logincodephone,xxx)
用户管理
地址管理
收藏商品收藏店铺收藏服务收藏宠物收藏。。。。
足迹。。。。静态网站部署与调试
两种前端项目的部署
vue-cli项目pethome-admin(管理员的管理界面)用npm打包成静态项目后丢进Tomcat服务器跑 Cssdiv项目pethome_web用户访问门户网站本身是静态项目可以直接丢进Tomcat服务器跑
两种前端项目的调试(热部署)
vue-cli项目可以npm run dev启动调试 传统静态项目需要安装 live-server服务器来调试这个服务器很简单就是node的一个模块 全局安装npm install -g live-server运行live-server --port80
创建静态web项目
拷贝amz_02_adp的two里项目资源到pethome-web目录下 复制home3.html到pethome-web根目录并改名为index.html作为首页 修改css和js引用路径
进入web子项目 全局安装npm install -g live-server 启动调试live-server --port80
替换images图片
注册分析与设计
分析需求
注册分为邮箱注册和手机号注册逻辑都是一样的只是激活方式不一样。手机号注册1输入手机号2获取验证码并且输入3输入蜜马和确认蜜马4完成注册设计 界面设计ui设计表后台 流程设计后台
三范式
1NF列的原子性不可再拆分 2NF行唯一 3NF如果一张表的数据能够通过其他表推导出来不应该单独设计应该通过外键的方式关联查询出来。
反3NF有的时候我们为了增强查询效率会设计一些冗余字段变多表查询为单表查询。
表设计 注意以后只要在eployee或user操作时涉及到登录信息都要同步操作logininfo。比如添加员工也要在logininfo添加一条记录注册用户也要在logininfo中添加。同理删除或修改也要同步。
流程设计
见文档
相关技术准备
1.随机字符串(用StrUtils工具类)
import java.util.ArrayList;
import java.util.List;
import java.util.Random;/*** author yaohuaipeng* date 2018/10/26-16:16*/
public class StrUtils {/*** 把逗号分隔的字符串转换字符串数组** param str* return*/public static String[] splitStr2StrArr(String str,String split) {if (str ! null !str.equals()) {return str.split(split);}return null;}/*** 把逗号分隔字符串转换List的Long** param str* return*/public static ListLong splitStr2LongArr(String str) {String[] strings splitStr2StrArr(str,,);if (strings null) return null;ListLong result new ArrayList();for (String string : strings) {result.add(Long.parseLong(string));}return result;}/*** 把逗号分隔字符串转换List的Long** param str* return*/public static ListLong splitStr2LongArr(String str,String split) {String[] strings splitStr2StrArr(str,split);if (strings null) return null;ListLong result new ArrayList();for (String string : strings) {result.add(Long.parseLong(string));}return result;}public static String getRandomString(int length) {String str 0123456789;Random random new Random();StringBuffer sb new StringBuffer();for (int i 0; i length; i) {int number random.nextInt(10);sb.append(str.charAt(number));}return sb.toString();}// 26字母10数字public static String getComplexRandomString(int length) {String str abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;Random random new Random();StringBuffer sb new StringBuffer();for (int i 0; i length; i) {int number random.nextInt(62);sb.append(str.charAt(number));}return sb.toString();}public static String convertPropertiesToHtml(String properties){//1:容量:6:32GB_4:样式:12:塑料壳StringBuilder sBuilder new StringBuilder();String[] propArr properties.split(_);for (String props : propArr) {String[] valueArr props.split(:);sBuilder.append(valueArr[1]).append(:).append(valueArr[3]).append(br);}return sBuilder.toString();}}2.springdata-redis
A 导入jar
!--spirngboot springdata对redis支持--
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependencyB 配置属性
spring:redis:database: 0host: 127.0.0.1port: 6379password: 123456jedis:pool:max-wait: 2000msmin-idle: 2max-idle: 8启动redis服务找到redis安装目录cmd运行redis-server.exe redis.windows.conf C 编写测试类(基于springboot的测试类(继承BaseTest即可)用springdataredis提供的bean直接操作redis)
public class RedisTest extends BaseTest {Autowiredprivate RedisTemplate redisTemplate;Testpublic void test(){redisTemplate.opsForValue().set(ceshi, 搞一条数据);System.out.println(redisTemplate.opsForValue().get(ceshi));}
}3.Md5技术
不可逆加密技术只能加密不能解密。 只能做比对一般用来加密用户登录蜜马。 我们要做的是把传入的蜜马进行加密和然后数据库查询出来的密文进行比对判断蜜马是否正确。
盐值同一种加密算法由于不同的盐值加密出来就不一样。 每个用户都有自己盐值就算是相同的蜜马两个用户加密出来的密文也不一样。
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class MD5Utils {/*** 加密* param context 明文*/public static String encrypByMd5(String context) {try { MessageDigest md MessageDigest.getInstance(MD5);md.update(context.getBytes());//update处理byte [] encryContext md.digest();//调用该方法完成计算int i;StringBuffer buf new StringBuffer();for (int offset 0; offset encryContext.length; offset) {//做相应的转化十六进制i encryContext[offset];if (i 0) i 256;if (i 16) buf.append(0);buf.append(Integer.toHexString(i));}return buf.toString();} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch block e.printStackTrace();return null;} }public static void main(String[] args) {//1.准备需要加密的蜜马String pwd 1;//2 准备盐值String salt StrUtils.getComplexRandomString(32);//2.加密 盐String pwdMd5 MD5Utils.encrypByMd5(pwd salt);// 将盐值和秘文存储到数据System.out.println(pwdMd5);//模拟登陆蜜马校验String pwdStr pwd;String saltTem salt;//相当于从数据库查询出来String pwdTmpMd5 MD5Utils.encrypByMd5(pwdStr saltTem);System.out.println(pwdTmpMd5);if(pwdTmpMd5.equals(pwdMd5)){System.out.println(登陆成功);}else{System.out.println(蜜马错误);}}}4.短信接口
http://sms.webchinese.com.cn/Rates.shtml 用户信息修改修改短信秘钥
导入依赖包 dependencygroupIdcommons-httpclient/groupIdartifactIdcommons-httpclient/artifactIdversion3.1/version/dependency代码应用(工具类 常量类) public static void sendsms(String phones, String message) throws IOException {HttpClient client new HttpClient();PostMethod post new PostMethod(https://utf8api.smschinese.cn/);post.addRequestHeader(Content-Type,application/x-www-form-urlencoded;charsetutf-8);//在头文件中设置转码NameValuePair[] data { new NameValuePair(Uid, mingfeng),new NameValuePair(Key, d41d8cd98f00b204e980),new NameValuePair(smsMob,phones),new NameValuePair(smsText,message)};post.setRequestBody(data);client.executeMethod(post);Header[] headers post.getResponseHeaders();int statusCode post.getStatusCode();System.out.println(statusCode:statusCode); //HTTP状态码for(Header h : headers){System.out.println(h.toString());}String result new String(post.getResponseBodyAsString().getBytes(utf-8));System.out.println(result); //打印返回消息状态post.releaseConnection();}发送短信验证码
前端页面准备
1.拷贝register.html到根目录更新引用路径
2.index.html设置在新标签页打开登录界面: target“_blank” div classmenu-hda href# target_top classh亲请登录/aa hrefregister.html target_blank免费注册/a/divdiv classmember-logouta classam-btn-warning btn hreflogin.html登录/aa classam-btn-warning btn target_blank hrefregister.html注册/a/div3.静态项目引入js插件vue和axios 拷贝ph-admin\node_modules里的axios和vue到ph-web/js/plugin目录里并在register.html页面引入 !--引入vue和axios--script srcjs/plugin/vue/dist/vue.min.js/scriptscript srcjs/plugin/axios/dist/axios.js/script!--全局使用--script srcjs/common.js/script!-- 局部使用script typetext/javascript//配置axios的全局基本路径/*axios.defaults.baseURL/api 前端解决跨域*/axios.defaults.baseURLhttp://localhost:8080///全局属性配置在任意组件内可以使用this.$http获取axios对象Vue.prototype.$http axios/script--在js目录下新建common.js
//配置axios的全局基本路径
/*axios.defaults.baseURL/api 前端解决跨域*/
axios.defaults.baseURLhttp://localhost:8080/
//全局属性配置在任意组件内可以使用this.$http获取axios对象
Vue.prototype.$http axios绑定div节点
div classam-tab-panel idmyDiv写vue.js
script typetext/javascriptnew Vue({el:#myDiv,mounted(){alert(this.$http)}})
/script获取的a标签换为按钮(方便置灰和显示秒数倒计时)绑定方法
!--a classbtn hrefjavascript:void(0); οnclicksendMobileCode(); idsendMobileCodespan iddyMobileButton获取/span/a--
button typebutton clicksendMobileCode获取/buttonmethods:{sendMobileCode(){alert(123)}},点击获取拿到手机号
input typetel v-modelphoneUserForm.phone name idphone placeholder请输入手机号script typetext/javascriptnew Vue({el:#myDiv,data:{phoneUserForm:{phone:18696148335}},methods:{sendMobileCode(){alert(this.registerForm.phone)}},mounted(){// alert(this.$http)}})
/scriptscript typetext/javascriptnew Vue({el:#myDiv,data:{phoneUserForm:{phone:}},methods:{sendMobileCode(){//1.判断手机号不为空if(!this.phoneUserForm.phone){alert(手机号不能为空);return;}//2.获取按钮 禁用按钮 发送时灰化不能使用 发送成功倒计时60才能使用 如果发送失败立即可以发送var sendBtn $(event.target);sendBtn.attr(disabled,true);this.$http.post(/verifycode/smsCode,{phone:this.phoneUserForm.phone}).then((res) {console.log(res);var ajaxResult res.data;if(ajaxResult.success){alert(手机验证码已经发送到您的手机请在3分钟内使用);//3.1.发送成倒计时var time 60;var interval window.setInterval( function () {//每一条倒计时减一time time - 1 ;//把倒计时时间搞到按钮上sendBtn.html(time);//3.2.倒计时完成恢复按钮if(time 0){sendBtn.html(重发);sendBtn.attr(disabled,false);//清除定时器window.clearInterval(interval);}},1000);}else{//3.3.发送失败提示恢复按钮sendBtn.attr(disabled,false);alert(发送失败:ajaxResult.message);}});}},mounted(){// alert(this.$http)}})
/script发送短信后台
搭建用户模块
UserloginInfo 搭建完模块后记得yml配置domain和query的扫描路径(别名)
单独写公共可用的发短信接口
VerifycodeController
RestController
RequestMapping(/verifycode)
public class VerifycodeController {Autowiredprivate IVerifycodeService verifycodeService;/*** 发送短信验证码* param phone 给谁发送 只是允许传入一个手机号* return*/PostMapping(/smsCode)public AjaxResult sendSmsCode(RequestBody String phone){try {verifycodeService.sendSmsCode(phone);return AjaxResult.me();} catch (BusinessException e) {return AjaxResult.me().setMessage(发送失败e.getMessage());}catch (Exception e) {e.printStackTrace();return AjaxResult.me().setMessage(系统繁忙稍后重试);}}
}VerifycodeServiceImpl //1.校验//1.1手机号空校验//1.2不能被注册//2.判断是否存在验证码从redis中获取电话对应的验证码//2.1 存在//2.1.1 判断是否过了重发时间1分钟//2.1.1.1 如果没过重发时间。报错请勿重复发送//2.1.1.2 如果过了使用原来还没过期的验证码刷新过期时间//2.2 不存在//2.2.1直接生成验证码//3 保存验证码到redis 设置过期时间//4 发送短信使用工具类掉短信接口即可Service
Transactional(readOnly true,propagation Propagation.SUPPORTS)
public class VerifycodeServiceImpl implements IVerifycodeService {Autowiredprivate IUserService userService;Autowiredprivate RedisTemplate redisTemplate;Overridepublic void sendSmsCode(String phone) {//1.校验//1.1手机号空校验if(!StringUtils.hasLength(phone)){throw new BusinessException(手机号不能为空);}//1.2不能被注册User user userService.loadUserByPhone(phone);if(user ! null){throw new BusinessException(用户已经你存在);}//2.判断是否存在验证码从redis中获取电话对应的验证码Object codeObj redisTemplate.opsForValue().get(UserConstant.USER_VERFIY_CODE:phone);String code ;if(codeObj !null){//2.1 存在String value (String)codeObj;String timeStr value.split(:)[1];//时间戳//2.1.1 判断是否过了重发时间1分钟if(System.currentTimeMillis()-Long.valueOf(timeStr) 1*60*1000){//2.1.1.1 如果没过重发时间。报错请勿重复发送throw new BusinessException(请勿重复发送验证码);}//2.1.1.2 如果过了使用原来还没过期的验证码刷新过期时间code value.split(:)[0];//验证码}else{//2.2 不存在//2.2.1直接生成验证码code StrUtils.getComplexRandomString(4);}//拼接存储验证码的格式String codeValue code : System.currentTimeMillis();//3 保存验证码到redis 设置过期时间redisTemplate.opsForValue().set(UserConstant.USER_VERFIY_CODE:phone, codeValue, 3, TimeUnit.MINUTES);//4 发送短信使用工具类掉短信接口即可/*SmsUtils.sendSms(phone, 您的验证码是code; 请在3分钟内使用);*/System.out.println(您的验证码是code; 请在3分钟内使用);}
}