springcloud篇】九. springcloud项目 三 首页,我的信息,添加好友及好友信息处理

首页,我的信息,添加好友及好友信息处理


中国加油,武汉加油!

篇幅较长,请配合目录观看

项目准备

  1. 本案例基于 springcloud篇】九. springcloud项目 二 注册登录及全局异常处理
  2. linux篇】十. Docker安装FastDFS和Solr

1. 图片上传服务器-后端

1.1 导包

<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.1-RELEASE</version>
</dependency>

1.2 编写yml

spring:
  cloud:
    config:
      uri: http://localhost:8081
      name: application
      profile: user,euclient
fdfs:
  so-timeout: 2000
  connect-timeout: 2000
  thumb-image:
    width: 100
    height: 100
  tracker-list:
    - 192.168.59.100:22122
fastpath: http://192.168.59.100:8080/

1.3 修改weixin-config-server/config的application-gateway.yml

server:
  port: 8888
spring:
  application:
    name: wx-gateway
  cloud:
    gateway:
      routes:
        - id: wx-user
          uri: lb://WX-USER
          predicates:
            - Path=/user/**,/res/**

1.4 weixin-user编写Controller

package com.wpj.controller;

import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.wpj.entity.User;
import com.wpj.entity.base.ResultEntity;
import com.wpj.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping(value = "/res")
public class ResController {

    @Autowired
    private FastFileStorageClient ffsc;

    @Value("${fastpath}")
    private String fdfsPath;

    @Autowired
    private IUserService userService;
    /**
     *
     * @param userId 用户id
     * @param file
     * @return
     */
    @RequestMapping(value = "/uploadFile")
    public ResultEntity uploadFile(Integer userId, MultipartFile file){
        String fileName = file.getOriginalFilename();
        // 获取文件的后缀
        String fileExName = fileName.substring(fileName.lastIndexOf(".")+1);
        try {
            // 上传头像到FastDFS
            StorePath storePath = ffsc.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), fileExName, null);
            String fullPath = storePath.getFullPath();
            // 获取大图和小图的路径
            String maxHead = fdfsPath+fullPath;
            String minHead = fdfsPath+fullPath.replaceAll("."+fileExName,"_100x100."+fileExName);
            // 修改用户表中的头像
            if(userId != null){
                User user = userService.selectById(userId);
                user.setMaxHead(maxHead);
                user.setMinHead(minHead);
                userService.update(user);
            }
            Map<String,String> map = new HashMap<>();
            map.put("maxHead",maxHead);
            map.put("minHead",minHead);
            return ResultEntity.success(map);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

1.5 修改程序入口

package com.wpj;

import com.github.tobato.fastdfs.FdfsClientConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.context.annotation.Import;
import org.springframework.jmx.support.RegistrationPolicy;

@EnableEurekaClient
@SpringBootApplication(scanBasePackages = "com.wpj")
@MapperScan(basePackages = "com.wpj.mapper")
// FastDFS
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class WeixinUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(WeixinUserApplication.class, args);
    }
}

1.6 启动程序入口使用PostMan测试

在这里插入图片描述
在这里插入图片描述

2. 图片上传服务器-前端

2.1 index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <title></title>
    <script src="js/mui.min.js"></script>
    <link href="css/mui.min.css" rel="stylesheet"/>
    <script type="text/javascript" charset="utf-8">
      	mui.init();
		mui.plusReady(function () {
			// 把4个页面放到一个数组里面
			var pageArray = ["msg.html","friend.html","discovery.html","me.html"];
			// 新页面的样式
			var styles = {top:'0px',bottom:'50px'}; 
			// 遍历数据创建页面
			for(var i =0;i<pageArray.length;i++){
				var page = pageArray[i];
				// 创建一个页面
				var newPage = plus.webview.create(page,page,styles);
				// 给当前页面添加一个子界面
				var cpage = plus.webview.currentWebview();
				cpage.append(newPage);
				// 隐藏其他页面
				if(i != 0){
					newPage.hide();
				}
			};
			// 绑定点击事件
			mui("nav").on('tap','a',function(){
				// 获取点击节点的id
				var id = this.getAttribute("id");
				// 根据id获取页面
				var pageId = pageArray[id];
				// 根据页面id找到页面对象
				plus.webview.getWebviewById(pageId).show();
			}) 
		})
    </script>
</head>
<body>
	<nav class="mui-bar mui-bar-tab">
		<a class="mui-tab-item mui-active" id="0"  style="touch-action: none;">
			<span class="mui-icon mui-icon-weixin"></span>
			<span class="mui-tab-label">消息</span>
		</a>
		<a class="mui-tab-item" id="1"  style="touch-action: none;"> 
			<span class="mui-icon mui-icon-contact" ></span>
			<span class="mui-tab-label">好友</span>
		</a>
		<a class="mui-tab-item" id="2"  style="touch-action: none;">
			<span class="mui-icon mui-icon-navigate" ></span>
			<span class="mui-tab-label">发现</span>
		</a>
		<a class="mui-tab-item"  id="3"  style="touch-action: none;">
			<span class="mui-icon mui-icon-person"></span>
			<span class="mui-tab-label">我的</span>
		</a>
	</nav>
</body>
</html>

2.2 weixin-utils.js

window.url={
	register_url:ip.serverip+"user/register",
	login_url:ip.serverip+"user/login",
	upload_head_url:ip.serverip+"res/uploadFile"
}

2.3 me.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.css" rel="stylesheet" />
		<script src="js/mui.js"></script>
		<script src="js/weixin_utils.js"></script>
		<script type="text/javascript">
			mui.init();
			mui.plusReady(function () {
				// 获取登录中的user
				var user = util.getUser();
				// 设置基本信息
				document.getElementById("username").innerText = user.username;
				document.getElementById("nickname").innerText = user.nickname;
				// 修改大头像的话也要修改小头像
				updateMinHead();
				// 点击上传图片
			    document.getElementById("min_head_but").addEventListener("tap",function(){
					// 打开头像的展示页面
					plus.webview.open("showHead.html","showHead.html");
				});
				// 注销账号
				document.getElementById("logout_but").addEventListener("tap",function(){
					// 把本地的用户设置为空
					util.setUser(null);
					var cpage = plus.webview.currentWebview();
					plus.webview.open("login.html","login.html");
					cpage.close();
				})
			});
			// 修改大头像的话也要修改小头像
			function updateMinHead(){
				var user = util.getUser();
				if(user.minHead != null){
					document.getElementById("minHead").src = user.minHead;
				}
			}
		</script>
	</head>
	<body>
		<header class="mui-bar mui-bar-nav">
			<h1 class="mui-title">我的</h1>
		</header>
		<ul class="mui-table-view" style="margin-top: 50px;">
			<li class="mui-table-view-cell mui-media" id="min_head_but">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-right" id="minHead" src="image/myheader.png">
					<div class="mui-media-body" style="line-height: 40px;">
						头像
					</div>
				</a>
			</li>
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<span class="mui-pull-right" id="username"></span>
					<div class="mui-media-body" >
						用户名   
					</div>
				</a>
			</li>
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<span class="mui-pull-right" id="nickname"></span>
					<div class="mui-media-body">
					    昵称
					</div>
				</a>
			</li>
		</ul>
		<ul class="mui-table-view" style="margin-top: 30px;">
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<div class="mui-media-body" id="logout_but" style="color: red;text-align: center;">
						注销账户
					</div>
				</a>
			</li>
		</ul>
	</body>
</html>

2.4 shopHead.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.css" rel="stylesheet" />
		<script src="js/mui.js"></script>
		<script src="js/weixin-utils.js"></script>
		<script type="text/javascript">
			mui.init();
			mui.plusReady(function () {
				// 获取当前登录的用户
				var user = util.getUser();
				// 判断是否有头xiang像
				if(user.maxHead != null){
					document.getElementById("showMaxHead").src = user.maxHead;
				}
				// 点击上传
			    document.getElementById("upload_but").addEventListener("tap",function(){
					// 打开本地相册
					plus.gallery.pick(function(path) {
						// 创建一个上传任务对象
						var task = plus.uploader.createUpload(url.upload_head_url, {}, function(t, status) {
								// 因为返回的字符串,所以需要转成JSON对象
								var resp = JSON.parse(t.responseText);
								// 上传完成
								if(resp.code == "ok"){
									var maxHead = resp.data.maxHead;
									var minHead = resp.data.minHead;
									// 显示用户上传的头像
									document.getElementById("showMaxHead").src = maxHead;
									// 修改本机中的用户信息
									user.maxHead = maxHead;
									user.minHead = minHead;
									// 保存
									util.setUser(user);
									// 按一次返回键
									mui.back();
									//指定调用某个页面中的某个函数
									plus.webview.getWebviewById("me.html").evalJS("updateMinHead()");
								}else{
									plus.nativeUI.toast("上传失败");
								}
							}
						);
						// 添加上传的文件
						task.addFile(path, {key:"file"});
						// 设置其他的参数
						task.addData("userId",user.id+"");
						// 启动上传任务
						task.start();
					});
				})
			})
		</script>
	</head>
	<body style="text-align: center;">
		<header class="mui-bar mui-bar-nav">
			<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
			<h1 class="mui-title">上传头像</h1>
		</header>
		<img  id="showMaxHead" src="image/myheader.png" style="margin-top: 60px;width: 300px;"/>
		<div id="sheet" class="mui-popover mui-popover-bottom mui-popover-action ">
			<!-- 可选择菜单 -->
			<ul class="mui-table-view">
			  <li class="mui-table-view-cell" id="upload_but">
				<a href="#">从相册选择</a>
			  </li>
			  <li class="mui-table-view-cell">
				<a href="#">拍照</a>
			  </li>
			</ul>
			<!-- 取消菜单 -->
			<ul class="mui-table-view">
			  <li class="mui-table-view-cell">
				<a href="#sheet1"><b>取消</b></a>
			  </li>
			</ul>
		</div>
		<a href="#sheet" id="openSheet"  class="mui-btn mui-btn-primary mui-btn-block">上传头像</a>
	</body>
</html>

3. 添加好友-后端

3.1 weixin-user的UserController添加方法

/**
 * 主要页面来调用
 * @param username
 * @return
 */
@RequestMapping(value = "/getUserByUsername")
public ResultEntity getUserByUsername(String username){
    User user = userService.getUserByUsername(username);
    return ResultEntity.success(user);
}

/**
 * 让其他微服务调用
 * @param username
 * @return 用户对象
 */
@RequestMapping(value = "/findUserByUsername")
public User findUserByUsername(String username){
    if(!StringUtils.isEmpty(username)){
        return userService.getUserByUsername(username);
    }
    return null;
}

3.2 weixin-entity编写FriendApply类

package com.wpj.entity;

import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_friend_apply")
public class FriendApply implements Serializable {

    @TableId(type = IdType.AUTO)
    private Integer id;
    private Integer fid;
    private Integer tid;
    private String msg;
    @TableField(value = "create_time")
    private Date createTime;
    private Integer status;
}

3.3 weixin-service-api编写Service接口

package com.wpj.service;

import com.wpj.entity.FriendApply;

public interface IFriendApplyService extends IBaseService<FriendApply> {
}

3.4 weixin-web新建项目weixin-friend(module-springboot)

3.4.1 导包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>com.wpj</groupId>
    <artifactId>wx-common</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>com.wpj</groupId>
    <artifactId>weixin-service-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.8</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>2.3</version>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

3.4.2 编写Mapper接口

package com.wpj.mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.wpj.entity.FriendApply;

public interface IFriendApplyMapper extends BaseMapper<FriendApply> {
}

3.4.3 编写ServiceImpl实现类

package com.wpj.service.impl;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.wpj.entity.FriendApply;
import com.wpj.mapper.IFriendApplyMapper;
import com.wpj.service.IFriendApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class FriendApplyServiceImpl extends BaseServiceImpl<FriendApply> implements IFriendApplyService {
    @Autowired
    private IFriendApplyMapper friendApplyMapper;
    @Override
    public BaseMapper<FriendApply> getMapper() {
        return friendApplyMapper;
    }
}

3.4.4 编写UserService接口

package com.wpj.service.api;

import com.wpj.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient("WX-USER")
public interface IUserService {
    
    @RequestMapping(value = "/user/findUserByUsername")
    public User findUserByUsername(@RequestParam("username") String username);

}

3.4.5 编写Controller

package com.wpj.controller;

import com.wpj.entity.FriendApply;
import com.wpj.entity.User;
import com.wpj.entity.base.ResultEntity;
import com.wpj.service.IFriendApplyService;
import com.wpj.service.api.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
@RequestMapping(value = "/friendApply")
public class FriendApplyController {
    @Autowired
    private IFriendApplyService friendApplyService;
    @Autowired
    private IUserService userService;

    @RequestMapping(value = "/addFriendApply")
    public ResultEntity addFriendApply(FriendApply friendApply, String username) {
        // 根据用户名称查询对象
        User user = userService.findUserByUsername(username);
        if (user != null) {
            friendApply.setTid(user.getId());
            friendApply.setCreateTime(new Date());
            friendApply.setStatus(1);
            friendApplyService.insert(friendApply);
            return ResultEntity.success();
        } else {
            return ResultEntity.error("没有找到: " + username);
        }
    }
}

3.4.6 编写bootstrap.yml

spring:
  cloud:
    config:
      uri: http://localhost:8081
      name: application
      profile: friend,euclient,datasource # datasource后面抽取配置需要引入

3.4.7 修改程序入口

package com.wpj;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableEurekaClient
@EnableFeignClients("com.wpj.service.api")
@SpringBootApplication(scanBasePackages = "com.wpj")
@MapperScan(basePackages = "com.wpj.mapper")
public class WeixinFriendApplication {

    public static void main(String[] args) {
        SpringApplication.run(WeixinFriendApplication.class, args);
    }
}

3.5 抽取DataSource配置

3.5.1 weixin-config-server/config添加application-datasource.xml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/nz1904-springcloud-weixin

mybatis-plus:
  type-aliases-package: com.wpj.entity

3.5.2 用到datasource配置的yml可以删除这段配置

3.5.3 用到datasource的模块引入该配置文件

spring:
  cloud:
    config:
      uri: http://localhost:8081
      name: application
      profile: user,euclient,datasource
fdfs:
  so-timeout: 2000
  connect-timeout: 2000
  thumb-image:
    width: 100
    height: 100
  tracker-list:
    - 192.168.59.100:22122
fastpath: http://192.168.59.100:8080/

3.6 weixin-config-server/config添加application-friend.yml

server:
  port: 8083
spring:
  application:
    name: wx-friend

3.7 weixin-config-server/config修改application-gateway.yml

server:
  port: 8888
spring:
  application:
    name: wx-gateway
  cloud:
    gateway:
      routes:
        - id: wx-user
          uri: lb://WX-USER
          predicates:
            - Path=/user/**,/res/**
        - id: wx-user
          uri: lb://WX-FRIEND
          predicates:
            - Path=/friendapply/**

4. 添加好友-前端

4.1 修改weixin-utils.js

window.util={
	ajax:function(param){
		plus.nativeUI.showWaiting(); // 显示等待的圈
		mui.ajax(param.url,{
			data:param.data,
			dataType:'json',//服务器返回json格式数据
			type:'post',//HTTP请求类型
			success:function(data){
				plus.nativeUI.closeWaiting();
				param.success(data);
			},
			error:function(xhr,type,errorThrown){
				plus.nativeUI.closeWaiting();
				//异常处理;
				plus.nativeUI.toast("服务端出现异常。");
			}
		});
	},
	setUser:function(user){
		plus.storage.setItem("login_user",JSON.stringify(user));	// 设置value的是字符串
	},
	getUser:function(){
		return JSON.parse(plus.storage.getItem("login_user"));  // 方便后期操作 取出时转成JSON对象
	}
	
}
// cmd --> ipconfig --> IPv4地址 192.168.91.1
window.ip={
	serverip:"http://192.168.91.1:8888/"
}
window.url={
	register_url:ip.serverip+"user/register",
	login_url:ip.serverip+"user/login",
	upload_head_url:ip.serverip+"res/uploadFile",
	getuserbyusername_url:ip.serverip+"user/getUserByUsername",
	friendapply_add_url:ip.serverip+"friendApply/addFriendApply"
}

4.2 添加discover.html

<!doctype html>
<html>

	<head>
		<meta charset="utf-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.css" rel="stylesheet" />
		<script src="js/mui.js"></script>
		<script type="text/javascript">
			mui.init();
			mui.plusReady(function () {
				document.getElementById("addFriend_but").addEventListener("tap",function(){
					// 打卡好友的搜索页面
					plus.webview.open("searchFriend.html","searchFriend.html");
				});
			})
		</script>
	</head>

	<body>
		<header class="mui-bar mui-bar-nav">
			<h1 class="mui-title">发现</h1>
		</header>
		<ul class="mui-table-view" style="margin-top:50px;">
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" src="image/pengyouquan.png">
					<div class="mui-media-body" style="line-height: 50px;">
						朋友圈
					</div>
				</a>
			</li>
		</ul>
		
		<ul class="mui-table-view" style="margin-top: 40px;">
			<li class="mui-table-view-cell mui-media" id="addFriend_but">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" src="image/addfriend.png">
					<div class="mui-media-body"  style="line-height: 40px;">
						添加好友
					</div>
				</a>
			</li>
			<li class="mui-table-view-cell mui-media" id="newFriend_but">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" src="image/newfriend.png">
					<div class="mui-media-body"  style="line-height: 40px;">
						新好友
					</div>
				</a>
			</li>
			
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" src="image/saoyisao.png">
					<div class="mui-media-body"  style="line-height: 40px;">
						扫一扫
					</div>
				</a>
			</li>
		</ul>
	</body>
</html>

4.3 添加searcherFriend.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.css" rel="stylesheet" />
		<script src="js/mui.js"></script>
		<script type="text/javascript">
			mui.init();
			mui.plusReady(function () {
				document.getElementById("seaerchfriend_but").addEventListener("tap",function(){
					// 获取用户输入值
					var username = document.getElementById("username").value;
					mui.openWindow({
						url:'searchResult.html',
						id: 'searchResult.html',
						extras:{ // 参数
							"username":username  //扩展参数
						}
					});
				})
			})
		</script>
	</head>
	<body>
		<header class="mui-bar mui-bar-nav">
			<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
			<h1 class="mui-title">搜索好友</h1>
		</header>
		<div style=" margin-top: 50px;">
			<input type="text" id="username"/>
			<div class="mui-button-row">
				<button type="button"  id="seaerchfriend_but" class="mui-btn mui-btn-success" style="width: 80%;">搜索</button>
			</div>
		</div>
	</body>
</html>

4.4 添加searchResult.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.css" rel="stylesheet" />
		<script src="js/mui.js"></script>
		<script src="js/weixin-utils.js"></script>
		<script type="text/javascript">
			mui.init();
			mui.plusReady(function () {
			    var username = plus.webview.currentWebview().username;
				util.ajax({
					url:url.getuserbyusername_url,
					data:{
						"username":username
					},
					success:function(resp){
						var user = resp.data;
						document.getElementById("username").innerText=user.username;
						document.getElementById("nickname").innerText=user.nickname;
						document.getElementById("minHead").src=user.minHead;
					}
				});
				document.getElementById("addFriend_but").addEventListener("tap",function(){
					// 打开好友认证页面
					mui.openWindow({
						url:"friend_auth.html",
						id:"friend_auth.html",
						extras:{
							"username":username
						}
					})
				})
			})
		</script>
	</head>
	<body>
		<header class="mui-bar mui-bar-nav">
			<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
			<h1 class="mui-title">好友展示</h1>
		</header>
		<ul class="mui-table-view" style="margin-top: 50px;">
			<li class="mui-table-view-cell mui-media">
				<a href="javascript:;">
					<img class="mui-media-object mui-pull-left" id="minHead" src="image/myheader.png">
					<div class="mui-media-body" id="username"></div>
					<div class="mui-media-body" id="nickname"></div>
				</a>
			</li>
		</ul>
		<div class="mui-button-row">
			<button type="button"  id="addFriend_but" class="mui-btn mui-btn-success" style="width: 80%;">添加好友</button>
		</div>
	</body>
</html>

4.5 添加friend_auth.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.css" rel="stylesheet" />
		<script src="js/mui.js"></script>
		<script src="js/weixin-utils.js"></script>
		<script type="text/javascript">
			mui.init();
			mui.plusReady(function () {
				// 获取添加的好友名称
			    var username = plus.webview.currentWebview().username; 
				document.getElementById("sendReq_but").addEventListener("tap",function(){
					// 验证信息
					var content = document.getElementById("content").value;
					// 获取当前登录的用户
					var user = util.getUser();
					// 封装对象
					var param = new Object();
					param.fid = user.id;
					param.username = username;
					param.msg = content;
					// 发送请求
					util.ajax({
						url:url.friendapply_add_url,
						data:param,
						success:function(resp){
							console.info(JSON.stringify(resp))
							if(resp.code == "ok"){
								var cpage = plus.webview.currentWebview();
								plus.webview.open("discovery.html","discovery.html");
								cpage.close();
							}else{
								plus.nativeUI.toast(resp.msg);
							}
						}
					})
				})
			})
		</script>
	</head>
	<body>
		<header class="mui-bar mui-bar-nav">
			<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
			<h1 class="mui-title">好友认证</h1>
		</header>
		<div style="margin-top: 50px;">
			<textarea id="content">我是。。。</textarea>
			<div class="mui-button-row">
				<button type="button"  id="sendReq_but" class="mui-btn mui-btn-success" style="width: 80%;">发送</button>
			</div>
		</div>
	</body>
</html>

5. 处理好友请求-后端

5.1 weixin-entity修改FriendApply

package com.wpj.entity;

import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_friend_apply")
public class FriendApply implements Serializable {

    @TableId(type = IdType.AUTO)
    private Integer id;
    private Integer fid;
    private Integer tid;
    private String msg;
    @TableField(value = "create_time")
    private Date createTime;
    private Integer status;
    @TableField(exist = false)
    private User friend;
}

5.2 编写Friend

package com.wpj.entity;

import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.omg.CORBA.INTERNAL;
import org.springframework.beans.factory.annotation.Autowired;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_friend")
public class Friend {

    @TableId(type= IdType.AUTO)
    private Integer id;
    private Integer uid;
    private Integer fid;
    private Integer status;
    private String remark;
}

5.3 weixin-user修改UserController

package com.wpj.controller;

import com.wpj.entity.User;
import com.wpj.entity.base.ResultEntity;
import com.wpj.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/register")
    public ResultEntity register(User user){
        int insert = userService.register(user);
        if (insert == 1) {
            return ResultEntity.error("用户名存在");
        } else if (insert == 2) {
            return ResultEntity.error("手机号码存在");
        }
        return ResultEntity.success();
    }

    @RequestMapping("/login")
    public ResultEntity login(String username, String password){
        User user = userService.getUserByUsername(username);
        if(user != null && user.getPassword().equals(password)) {
            user.setPassword(null); // 密码不能写到手机里
            System.out.println(user);
            return ResultEntity.success(user);
        } else{
            return ResultEntity.error("用户名或密码错误");
        }
    }

    @RequestMapping(value = "/test")
    public ResultEntity test(@CookieValue(name = "name",required = false) String name, HttpServletResponse resp){
        System.out.println("name = [" + name + "]");
        Cookie cookie = new Cookie("name","admin");
        cookie.setMaxAge(10000);
        cookie.setPath("/");
        resp.addCookie(cookie);
        return ResultEntity.success();
    }

    /**
     * 主要页面来调用
     * @param username
     * @return
     */
    @RequestMapping(value = "/getUserByUsername")
    public ResultEntity getUserByUsername(String username){
        User user = userService.getUserByUsername(username);
        return ResultEntity.success(user);
    }

    /**
     * 让其他微服务调用
     * @param username
     * @return 用户对象
     */
    @RequestMapping(value = "/findUserByUsername")
    public User findUserByUsername(String username){
        if(!StringUtils.isEmpty(username)){
            return userService.getUserByUsername(username);
        }
        return null;
    }
    @RequestMapping(value = "/getUserById")
    public User getUserById(Integer id){
        if(id != null){
            return userService.selectById(id);
        }
        return null;
    }

    @RequestMapping(value = "/findUserById")
    public ResultEntity findUserById(Integer id){
        User user = userService.selectById(id);
        return ResultEntity.success(user);
    }
}

5.4 weixin-service-api添加FriendService和修改FriendApplyService

package com.wpj.service;

import com.wpj.entity.Friend;

public interface IFriendService extends IBaseService<Friend> {
    void addFriend(Integer tid, Integer fid, int i);
}
package com.wpj.service;

import com.wpj.entity.FriendApply;

import java.util.List;

public interface IFriendApplyService extends IBaseService<FriendApply> {
    List<FriendApply> getMyFriendApplyList(Integer uid);
}

5.5 weixin-friend重写方法

package com.wpj.service.impl;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.wpj.entity.FriendApply;
import com.wpj.mapper.IFriendApplyMapper;
import com.wpj.service.IFriendApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class FriendApplyServiceImpl extends BaseServiceImpl<FriendApply> implements IFriendApplyService {

    @Autowired
    private IFriendApplyMapper friendApplyMapper;

    @Override
    public BaseMapper<FriendApply> getMapper() {
        return friendApplyMapper;
    }

    @Override
    public List<FriendApply> getMyFriendApplyList(Integer uid) {
        EntityWrapper wrapper = new EntityWrapper();
        wrapper.eq("tid",uid);
        return friendApplyMapper.selectList(wrapper);
    }
}

5.6 IUserService添加方法

package com.wpj.service.api;

import com.wpj.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient("WX-USER")
public interface IUserService {

    @RequestMapping(value = "/user/findUserByUsername")
    public User findUserByUsername(@RequestParam("username") String username);
    
    @RequestMapping(value = "/user/getUserById")
    public User getUserById(@RequestParam("id") Integer id);
}

5.7 编写Mapper接口

package com.wpj.mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.wpj.entity.Friend;

public interface IFriendMapper extends BaseMapper<Friend> {
}

5.8 编写ServiceImpl实现类

package com.wpj.service.impl;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.wpj.entity.Friend;
import com.wpj.mapper.IFriendMapper;
import com.wpj.service.IFriendService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class FriendServiceImpl extends BaseServiceImpl<Friend> implements IFriendService {

    @Autowired
    private IFriendMapper friendMapper;

    @Override
    public BaseMapper<Friend> getMapper() {
        return friendMapper;
    }

    @Override
    public void addFriend(Integer tid, Integer fid, int i) {
        Friend friend1 = new Friend();
        friend1.setUid(tid);
        friend1.setFid(fid);
        friend1.setStatus(1);
        if (isFriend(friend1)) {
            friendMapper.insert(friend1);
        }
        
        Friend friend2 = new Friend();
        friend2.setUid(fid);
        friend2.setFid(tid);
        friend2.setStatus(1);
        if (isFriend(friend2)) {
            friendMapper.insert(friend2);
        }
    }
    
    public boolean isFriend(Friend friend) {
        return friendMapper.selectOne(friend) == null;
    }
}

5.9 FriendApplyController添加方法

package com.wpj.controller;

import com.wpj.entity.FriendApply;
import com.wpj.entity.User;
import com.wpj.entity.base.ResultEntity;
import com.wpj.mapper.IFriendMapper;
import com.wpj.service.IFriendApplyService;
import com.wpj.service.IFriendService;
import com.wpj.service.api.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

@RestController
@RequestMapping(value = "/friendApply")
public class FriendApplyController {
    @Autowired
    private IFriendApplyService friendApplyService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IFriendService friendService;

    @RequestMapping(value = "/addFriendApply")
    public ResultEntity addFriendApply(FriendApply friendApply, String username) {
        // 根据用户名称查询对象
        User user = userService.findUserByUsername(username);
        if (user.getId() == friendApply.getFid()) {
            return ResultEntity.error("不能添加自己为好友");
        }
        if (user != null) {
            friendApply.setTid(user.getId());
            friendApply.setCreateTime(new Date());
            friendApply.setStatus(1);
            friendApplyService.insert(friendApply);
            return ResultEntity.success();
        } else {
            return ResultEntity.error("没有找到: " + username);
        }
    }
    @RequestMapping(value = "/getMyFriendApplyList")
    public ResultEntity getMyFriendApplyList(Integer uid) {
        List<FriendApply> friendApplyList = friendApplyService.getMyFriendApplyList(uid);
        for (FriendApply friendApply : friendApplyList) {
            Integer fid = friendApply.getFid();
            User user = userService.getUserById(fid);
            friendApply.setFriend(user);
        }
        return ResultEntity.success(friendApplyList);
    }
    // 如果是拒绝只修改状态就可以
    // 如果是同意,修改状态并且还要添加好友
    @RequestMapping(value = "/updateFriendApplyStatus")
    public ResultEntity updateFriendApplyStatus(Integer status, Integer id) {
        // 根据id查询申请记录对象
        FriendApply friendApply = friendApplyService.selectById(id);
        friendApply.setStatus(status);
        friendApplyService.update(friendApply);
        if (status == 2) { // 说明同意
            // 添加好友
            friendService.addFriend(friendApply.getTid(), friendApply.getFid(), 1);
        }
        return ResultEntity.success();
    }

}

6. 处理好友请求-前端

6.1 修改weixin-utils.js

window.url={
	register_url:ip.serverip+"user/register",
	login_url:ip.serverip+"user/login",
	upload_head_url:ip.serverip+"res/uploadFile",
	getuserbyusername_url:ip.serverip+"user/getUserByUsername",
	friendapply_add_url:ip.serverip+"friendApply/addFriendApply",
	getMyFriendApplyList_url:ip.serverip+"friendApply/getMyFriendApplyList",
	updateFriendApplyStatus_url:ip.serverip+"friendApply/updateFriendApplyStatus"
}

6.2 discovery.html添加点击事件

mui.plusReady(function () {
	document.getElementById("addFriend_but").addEventListener("tap",function(){
		// 打卡好友的搜索页面
		plus.webview.open("searchFriend.html","searchFriend.html");
	});
	
	document.getElementById("newFriend_but").addEventListener("tap",function(){
		plus.webview.open("showNewFriendList.html","showNewFriendList.html");
	})
})

6.3 编写showNewFriendList.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.css" rel="stylesheet" />
		<script src="js/mui.js"></script>
		<script src="js/weixin-utils.js"></script>
		<script type="text/javascript">
			mui.init();
			mui.plusReady(function () {
			    var user = util.getUser();
				
				util.ajax({
					url:url.getMyFriendApplyList_url,
					data:{
						"uid":user.id
					},
					success:function(resp){
						console.info(JSON.stringify(resp));
						if(resp.code == "ok"){
							var nfList = resp.data;
							var html = "";
							for(var i = 0;i<nfList.length;i++){
								var newF = nfList[i];
								html +='<li class="mui-table-view-cell mui-media">';
								html +='<a href="javascript:;">';
								
								if(newF.friend.minHead != null){
									html +='<img class="mui-media-object mui-pull-left" src="'+newF.friend.minHead+'">';
								}else{
									html +='<img class="mui-media-object mui-pull-left" src="image/myheader.png">';
								}
								html +='<div class="mui-media-body">';
								html +=newF.friend.nickname;
								html +='</div>';
								html +='<div class="mui-media-body">';
								html +=newF.msg;
								html +='</div>';
								html +='</a>';
								if(newF.status == 1){
									html +='<button type="button" id="'+newF.id+'"  num="2"  class="mui-btn mui-btn-success" style="width: 15%;right: 100px;">接收</button>';
									html +='<button type="button" id="'+newF.id+'"  num = "3" class="mui-btn mui-btn-danger" style="width: 15%;">拒绝</button>';
								}else if(newF.status == 2){
									html +='<button type="button"  class="mui-btn mui-btn-success" style="width: 15%;right: 100px;">已接受</button>';
								}else if(newF.status == 3){
									html +='<button type="button"  class="mui-btn mui-btn-success" style="width: 15%;right: 100px;">已拒绝</button>';
								}
								html +='</li>';
							}
							document.getElementById("showNFList").innerHTML=html;
						}
					}
				});
				mui.plusReady(function () {
				    mui(".mui-table-view").on('tap','.mui-btn',function(){
						var status = this.getAttribute("num");
						var fapplyId = this.getAttribute("id");
						
						util.ajax({
							url:url.updateFriendApplyStatus_url,
							data:{
								"status":status,
								"id":fapplyId
							},
							success:function(resp){
								location.reload();
								console.info(JSON.stringify(resp))
							}
						});
				    }) 
				})
			})
		</script>
	</head>
	<body>
		<ul class="mui-table-view" id="showNFList">	
		</ul>
	</body>
</html>
项目是采用目前比较流行的SpringBoot/SpringCloud构建微服务电商项目项目叫 《果然新鲜》,实现一套串联的微服务电商项目。完全符合一线城市微服务电商的需求,对学习微服务电商架构,有非常大的帮助,该项目涵盖从微服务电商需求讨论、数据库设计、技术选型、互联网安全架构、整合SpringCloud各自组件、分布式基础设施等实现一套完整的微服务解决方案。 项目使用分布式微服务框架,涉及后台管理员服务、地址服务、物流服务、广告服务、商品服务、商品类别服务、品牌服务、订单服务 、购物车服务、首页频道服务、公告服务、留言服务、搜索服务、会员服务等。  系统架构图   SpringBoot+SpringCloud+SSM构建微服务电商项目使用SpringCloud Eureka作为注册中心,实现服务治理使用Zuul网关框架管理服务请求入口使用Ribbon实现本地负载均衡器和Feign HTTP客户端调用工具使用Hystrix服务保护框架(服务降级、隔离、熔断、限流)使用消息总线Stream RabbitMQ和 Kafka微服务API接口安全控制和单点登录系统CAS+JWT+OAuth2.0分布式基础设施构建分布式任务调度平台XXL-JOB分布式日志采集系统ELK分布式事务解决方案LCN分布式锁解决方案Zookeeper、Redis分布式配置中心(携程Apollo)高并发分布式全局ID生成(雪花算法)分布式Session框架Spring-Session分布式服务追踪与调用链Zipkin项目运营与部署环境分布式设施环境,统一采用Docker安装使用jenkins+docker+k8s实现自动部署微服务API管理ApiSwagger使用GitLab代码管理(GitHub  GitEE)统一采用第方云数据库使用七牛云服务器对静态资源实现加速 开发环境要求JDK统一要求:JDK1.8Maven统一管理依赖 统一采用Docker环境部署编码统一采用UTF-8开发工具IDEA 或者 Eclipse 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值