├── .gitattributes ├── README.md ├── charBack ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── yzeng │ │ │ └── charme │ │ │ ├── CharMeApplication.java │ │ │ ├── ServletInitializer.java │ │ │ ├── config │ │ │ ├── DruidMonitorConfigurer.java │ │ │ ├── RabbitMQConfig.java │ │ │ └── Swagger2.java │ │ │ ├── controller │ │ │ ├── FriendController.java │ │ │ ├── GroupController.java │ │ │ ├── IndexController.java │ │ │ ├── MessageController.java │ │ │ └── UserController.java │ │ │ ├── dao │ │ │ ├── UserDao.java │ │ │ ├── UserInfoDao.java │ │ │ └── impl │ │ │ │ ├── UserDaoImpl.java │ │ │ │ └── UserInfoDaoImpl.java │ │ │ ├── entity │ │ │ ├── Group.java │ │ │ ├── Message.java │ │ │ ├── User.java │ │ │ ├── UserInfo.java │ │ │ └── UserRelation.java │ │ │ ├── mapper │ │ │ ├── FriendMapper.java │ │ │ ├── GroupMapper.java │ │ │ ├── MessageMapper.java │ │ │ ├── UserInfoMapper.java │ │ │ └── UserMapper.java │ │ │ ├── netty │ │ │ ├── NettyClient.java │ │ │ └── NettyServer.java │ │ │ ├── queue │ │ │ ├── LoginController.java │ │ │ ├── Receiver.java │ │ │ └── UserReceiver.java │ │ │ ├── server │ │ │ ├── MongoHelper.java │ │ │ └── SocketServer.java │ │ │ ├── service │ │ │ ├── FriendService.java │ │ │ ├── GroupService.java │ │ │ ├── MessageService.java │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ ├── FriendServiceImpl.java │ │ │ │ ├── GroupServiceImpl.java │ │ │ │ ├── MessageServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── utils │ │ │ ├── SpringUtils.java │ │ │ ├── WebResult.java │ │ │ └── WebUtils.java │ └── resources │ │ ├── application-dev.yml │ │ ├── application.yml │ │ ├── mapper │ │ ├── FriendMapper.xml │ │ ├── GroupMapper.xml │ │ ├── MessageMapper.xml │ │ ├── UserInfoMapper.xml │ │ └── UserMapper.xml │ │ ├── static │ │ ├── css │ │ │ ├── animate.css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ ├── bootstrap.min.css.map │ │ │ ├── login.css │ │ │ ├── main-style.css │ │ │ └── style.css │ │ ├── img │ │ │ ├── bg.jpg │ │ │ ├── face.png │ │ │ ├── hhh.png │ │ │ ├── icon.png │ │ │ ├── img.png │ │ │ ├── logo-white.png │ │ │ ├── logo.ico │ │ │ ├── logo_blue.ico │ │ │ ├── part1.png │ │ │ ├── part2.png │ │ │ ├── part3.png │ │ │ ├── photo.jpg │ │ │ ├── photoss.jpg │ │ │ └── s-logo.png │ │ ├── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ ├── common.js │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ ├── jquery1.9.1 │ │ │ │ ├── jquery.js │ │ │ │ └── jquery.min.js │ │ │ ├── layer.js │ │ │ ├── mobile │ │ │ │ ├── layer.js │ │ │ │ └── need │ │ │ │ │ └── layer.css │ │ │ ├── npm.js │ │ │ ├── skin │ │ │ │ ├── default │ │ │ │ │ ├── icon-ext.png │ │ │ │ │ ├── icon.png │ │ │ │ │ ├── layer.css │ │ │ │ │ ├── loading-0.gif │ │ │ │ │ ├── loading-1.gif │ │ │ │ │ └── loading-2.gif │ │ │ │ ├── family │ │ │ │ │ └── style.css │ │ │ │ └── lists │ │ │ │ │ └── style.css │ │ │ ├── sockjs.js │ │ │ └── websocket-client.js │ │ └── static │ │ │ ├── css │ │ │ ├── app.6cefd1061decddc3620fa7070a0073d8.css │ │ │ └── app.6cefd1061decddc3620fa7070a0073d8.css.map │ │ │ ├── fonts │ │ │ ├── ionicons.99ac330.woff │ │ │ └── ionicons.d535a25.ttf │ │ │ ├── img │ │ │ └── ionicons.a2c4a26.svg │ │ │ └── js │ │ │ ├── app.31140e71b9a63b4e0feb.js │ │ │ ├── app.31140e71b9a63b4e0feb.js.map │ │ │ ├── manifest.2ae2e69a05c33dfc65f8.js │ │ │ ├── manifest.2ae2e69a05c33dfc65f8.js.map │ │ │ ├── vendor.d1ab7e0ca14c455e2923.js │ │ │ └── vendor.d1ab7e0ca14c455e2923.js.map │ │ └── templates │ │ └── index.html │ └── test │ └── java │ └── com │ └── yzeng │ └── charme │ ├── CharMeApplicationTests.java │ └── DBEncryption.java └── charFront ├── .babelrc ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── index.html ├── package-lock.json ├── package.json └── src ├── App.vue ├── App2.vue ├── assets ├── js │ ├── common.js │ └── jquery1.9.1 │ │ ├── jquery.js │ │ └── jquery.min.js └── logo.png ├── components ├── AddFriend.vue ├── FriendsList.vue ├── GroupList.vue ├── GroupMessage.vue ├── Index.vue ├── Login.vue ├── Message.vue └── UserInfo.vue ├── main.js └── router └── index.js /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=Java 2 | *.css linguist-language=Java 3 | *.html linguist-language=Java 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CharMe 2 | 仿照WEB微信的前后端分离聊天项目(技术栈:SpringBoot+Vue+WebSocket) 3 | -------------------------------------------------------------------------------- /charBack/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.yzeng 7 | charMe 8 | 0.0.1-SNAPSHOT 9 | war 10 | 11 | charMe 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.5.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-amqp 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-mongodb 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-websocket 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-thymeleaf 47 | 48 | 49 | org.mybatis.spring.boot 50 | mybatis-spring-boot-starter 51 | 1.3.2 52 | 53 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-devtools 61 | true 62 | 63 | 64 | 65 | com.alibaba 66 | druid 67 | 1.1.0 68 | 69 | 70 | 71 | mysql 72 | mysql-connector-java 73 | runtime 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-starter-tomcat 78 | provided 79 | 80 | 81 | org.springframework.boot 82 | spring-boot-starter-test 83 | test 84 | 85 | 86 | 87 | javax 88 | javaee-api 89 | 8.0 90 | provided 91 | 92 | 93 | 94 | 95 | com.alibaba 96 | fastjson 97 | 1.2.31 98 | 99 | 100 | 101 | 102 | com.github.pagehelper 103 | pagehelper-spring-boot-starter 104 | 1.2.3 105 | 106 | 107 | 108 | io.netty 109 | netty-all 110 | 111 | 112 | 113 | com.github.ulisesbocchio 114 | jasypt-spring-boot-starter 115 | 2.1.0 116 | 117 | 118 | 119 | io.springfox 120 | springfox-swagger2 121 | 2.2.2 122 | 123 | 124 | io.springfox 125 | springfox-swagger-ui 126 | 2.2.2 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | org.springframework.boot 135 | spring-boot-maven-plugin 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/CharMeApplication.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.ConfigurableApplicationContext; 6 | 7 | import com.yzeng.charme.server.SocketServer; 8 | 9 | @SpringBootApplication 10 | public class CharMeApplication { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(CharMeApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/ServletInitializer.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme; 2 | 3 | import org.springframework.boot.builder.SpringApplicationBuilder; 4 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 5 | 6 | public class ServletInitializer extends SpringBootServletInitializer { 7 | 8 | @Override 9 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 10 | return application.sources(CharMeApplication.class); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/config/DruidMonitorConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.config; 2 | 3 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 4 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 5 | import org.springframework.context.annotation.Bean; 6 | 7 | import com.alibaba.druid.support.http.StatViewServlet; 8 | import com.alibaba.druid.support.http.WebStatFilter; 9 | 10 | public class DruidMonitorConfigurer { 11 | /** 12 | * 注册ServletRegistrationBean 13 | * @return 14 | */ 15 | @Bean 16 | public ServletRegistrationBean registrationBean() { 17 | ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); 18 | /** 初始化参数配置,initParams**/ 19 | //白名单 20 | bean.addInitParameter("allow", "127.0.0.1");//多个ip逗号隔开 21 | //IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page. 22 | //bean.addInitParameter("deny", "192.168.1.110"); 23 | //登录查看信息的账号密码. 24 | bean.addInitParameter("loginUsername", "admin"); 25 | bean.addInitParameter("loginPassword", "123456"); 26 | //是否能够重置数据. 27 | bean.addInitParameter("resetEnable", "false"); 28 | return bean; 29 | } 30 | 31 | /** 32 | * 注册FilterRegistrationBean 33 | * @return 34 | */ 35 | @Bean 36 | public FilterRegistrationBean druidStatFilter() { 37 | FilterRegistrationBean bean = new FilterRegistrationBean(new WebStatFilter()); 38 | //添加过滤规则. 39 | bean.addUrlPatterns("/*"); 40 | //添加不需要忽略的格式信息. 41 | bean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); 42 | return bean; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/config/RabbitMQConfig.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.amqp.core.Binding; 6 | import org.springframework.amqp.core.BindingBuilder; 7 | import org.springframework.amqp.core.Queue; 8 | import org.springframework.amqp.core.TopicExchange; 9 | import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; 10 | import org.springframework.amqp.rabbit.connection.ConnectionFactory; 11 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.beans.factory.config.ConfigurableBeanFactory; 14 | import org.springframework.context.annotation.Bean; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.context.annotation.Scope; 17 | 18 | /** 19 | Broker:它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输, 20 | Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。 21 | Queue:消息的载体,每个消息都会被投到一个或多个队列。 22 | Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来. 23 | Routing Key:路由关键字,exchange根据这个关键字进行消息投递。 24 | vhost:虚拟主机,一个broker里可以有多个vhost,用作不同用户的权限分离。 25 | Producer:消息生产者,就是投递消息的程序. 26 | Consumer:消息消费者,就是接受消息的程序. 27 | Channel:消息通道,在客户端的每个连接里,可建立多个channel. 28 | */ 29 | @Configuration 30 | public class RabbitMQConfig { 31 | 32 | private final Logger log = LoggerFactory.getLogger(this.getClass()); 33 | 34 | private final static String message = "topic.message"; 35 | 36 | private final static String messages = "topic.messages"; 37 | 38 | @Bean 39 | public Queue queueMessage() { 40 | return new Queue(RabbitMQConfig.message); 41 | } 42 | 43 | @Bean 44 | public Queue queueMessages() { 45 | return new Queue(RabbitMQConfig.messages); 46 | } 47 | 48 | @Bean 49 | TopicExchange exchange() { 50 | return new TopicExchange("exchange"); 51 | } 52 | 53 | @Bean 54 | Binding bindingExchangeMessage(Queue queueMessage,TopicExchange exchange) { 55 | return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message"); 56 | } 57 | 58 | @Bean 59 | Binding bindingExchangeMessages(Queue queueMessage,TopicExchange exchange) { 60 | //这里的#表示零个或多个词。 61 | return BindingBuilder.bind(queueMessage).to(exchange).with("topic.#"); 62 | } 63 | 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/config/Swagger2.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.spi.DocumentationType; 11 | import springfox.documentation.spring.web.plugins.Docket; 12 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 13 | 14 | 15 | /** 16 | * 如上代码所示,通过@Configuration注解,让Spring来加载该类配置。再通过@EnableSwagger2注解来启用Swagger2。 17 | * 再通过createRestApi函数创建Docket的Bean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。 18 | * select()函数返回一个ApiSelectorBuilder实例用来控制哪些接口暴露给Swagger来展现, 19 | * 本例采用指定扫描的包路径来定义,Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被@ApiIgnore指定的请求)。 20 | * 21 | * 通过@ApiOperation注解来给API增加说明、 22 | * 通过@ApiImplicitParams、@ApiImplicitParam注解来给参数增加说明。 23 | * @author Yao.Zeng 24 | * 25 | */ 26 | 27 | 28 | @Configuration 29 | @EnableSwagger2 30 | public class Swagger2 { 31 | 32 | @Bean 33 | public Docket createRestApi() { 34 | return new Docket(DocumentationType.SWAGGER_2) 35 | .apiInfo(apiInfo()) 36 | .select() 37 | .apis(RequestHandlerSelectors.basePackage("com.yzeng.charme.controller")) 38 | .paths(PathSelectors.any()) 39 | .build(); 40 | } 41 | 42 | private ApiInfo apiInfo() { 43 | return new ApiInfoBuilder() 44 | .title("Spring Boot中使用Swagger2构建RESTful APIs") 45 | .description("更多Spring Boot相关文章请关注:http://blog.didispace.com/") 46 | .termsOfServiceUrl("http://blog.didispace.com/") 47 | .contact("程序猿DD") 48 | .version("1.0") 49 | .build(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/controller/FriendController.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | 11 | import com.yzeng.charme.entity.UserInfo; 12 | import com.yzeng.charme.entity.UserRelation; 13 | import com.yzeng.charme.service.FriendService; 14 | import com.yzeng.charme.service.UserService; 15 | 16 | import io.swagger.annotations.ApiImplicitParam; 17 | import io.swagger.annotations.ApiOperation; 18 | 19 | @Controller 20 | @RequestMapping("friend") 21 | public class FriendController { 22 | 23 | @Autowired 24 | private UserService userService; 25 | 26 | @Autowired 27 | private FriendService friendService; 28 | 29 | 30 | @ApiOperation(value="搜索好友", notes="根据好友名来获取用户详细信息") 31 | @ApiImplicitParam(name = "findStr", value = "好友名字", required = true, dataType = "String") 32 | @RequestMapping(value="find",method=RequestMethod.POST) 33 | @ResponseBody 34 | public List find(String findStr){ 35 | UserInfo userInfo = new UserInfo(); 36 | userInfo.setUsername(findStr); 37 | userInfo.setNickname(findStr); 38 | 39 | return userService.findByName(userInfo); 40 | } 41 | 42 | /** 43 | * 添加好友 44 | * @param userIdA 45 | * @param userIdB 46 | * @return 47 | */ 48 | @RequestMapping("add") 49 | @ResponseBody 50 | public String addFriend(Integer userIdA,Integer userIdB) { 51 | try { 52 | UserRelation relation = new UserRelation(); 53 | relation.setUserIdA(userIdA); 54 | relation.setUserIdB(userIdB); 55 | int i = friendService.addFriend(relation); 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | } 59 | return "success"; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/controller/GroupController.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.controller; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import javax.annotation.Resource; 8 | 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | 13 | import com.yzeng.charme.entity.Group; 14 | import com.yzeng.charme.service.GroupService; 15 | import com.yzeng.charme.utils.WebResult; 16 | 17 | @Controller 18 | @RequestMapping("group") 19 | public class GroupController { 20 | 21 | @Resource 22 | private GroupService groupService; 23 | 24 | @RequestMapping("add") 25 | @ResponseBody 26 | public WebResult addGroup(Integer userId, String groupName, String groupDescribes) { 27 | WebResult wr = new WebResult(); 28 | Group group = new Group(); 29 | try { 30 | group.setCreateUserId(userId); 31 | group.setGroupName(groupName); 32 | group.setGroupDescribes(groupDescribes); 33 | int i = groupService.addGroup(group); 34 | wr.invokeSuccess(i+""); 35 | } catch (Exception e) { 36 | wr.invokeFail("创建群失败"); 37 | e.printStackTrace(); 38 | } 39 | return wr; 40 | } 41 | 42 | @RequestMapping("getAll") 43 | @ResponseBody 44 | public WebResult getAllByUserId(Integer userId) { 45 | WebResult wr = new WebResult(); 46 | Map map = new HashMap(); 47 | try { 48 | List slefGroup = groupService.getGroupByCreateUserId(userId); 49 | List joinGroup = groupService.getGroupByUserId(userId); 50 | map.put("slefGroup", slefGroup); 51 | map.put("joinGroup", joinGroup); 52 | wr.setData(map); 53 | wr.setCode("1"); 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | wr.invokeFail("加载群列表失败!"); 57 | } 58 | return wr; 59 | } 60 | 61 | @RequestMapping("getGroupUser") 62 | @ResponseBody 63 | public WebResult getGroupUserByGroupId(Integer groupId) { 64 | WebResult wr = new WebResult(); 65 | try { 66 | List> list = groupService.getGroupUserByGroupId(groupId); 67 | wr.setData(list); 68 | wr.setCode("1"); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | wr.invokeFail("加载群列表失败!"); 72 | } 73 | return wr; 74 | } 75 | 76 | @RequestMapping("addUserToGroup") 77 | @ResponseBody 78 | public WebResult addUserToGroup(Integer groupId,Integer userId) { 79 | WebResult wr = new WebResult(); 80 | try { 81 | int i = groupService.addUserToGroup(groupId, userId); 82 | wr.setData(i); 83 | wr.setCode("1"); 84 | } catch (Exception e) { 85 | e.printStackTrace(); 86 | wr.invokeFail("加群失败!"); 87 | } 88 | return wr; 89 | } 90 | 91 | @RequestMapping("getGroupMsgHistory") 92 | @ResponseBody 93 | public WebResult getGroupMsgHistory(Integer groupId,Integer pageNum, Integer pageSize) { 94 | WebResult wr = new WebResult(); 95 | try { 96 | List> groupMsg = groupService.getGroupMsgHistory(groupId,pageNum,pageSize); 97 | if(groupMsg != null && groupMsg.size() > 0) { 98 | wr.setData(groupMsg); 99 | wr.setCode("1"); 100 | }else { 101 | wr.setCode("2"); 102 | wr.setMsg("没有更多信息记录了"); 103 | } 104 | } catch (Exception e) { 105 | e.printStackTrace(); 106 | wr.invokeFail("拉取群消息失败!"); 107 | } 108 | return wr; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | @Controller 8 | public class IndexController { 9 | 10 | @RequestMapping(value="index",method=RequestMethod.GET) 11 | public String showPage() { 12 | return "/index"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/controller/MessageController.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | 11 | import com.yzeng.charme.entity.Message; 12 | import com.yzeng.charme.service.MessageService; 13 | 14 | @Controller 15 | @RequestMapping("msg") 16 | public class MessageController { 17 | 18 | @Autowired 19 | private MessageService messageService; 20 | 21 | @RequestMapping("{pageNum}-{pageSize}") 22 | @ResponseBody 23 | public List getList(@PathVariable("pageNum")Integer pageNum,@PathVariable("pageSize")Integer pageSize){ 24 | Message message = new Message(); 25 | message.setFromUserId(1); 26 | message.setToUserId(2); 27 | message.setMsgType(0); 28 | return messageService.getMessageloggingList(message,pageNum, pageSize); 29 | } 30 | 31 | @RequestMapping("getOfflineMessageList") 32 | @ResponseBody 33 | public List getOfflineMessageList(Integer userId){ 34 | Message message = new Message(); 35 | message.setToUserId(userId); 36 | message.setIsTransport(0); 37 | return messageService.getMessageListByStatus(message); 38 | } 39 | 40 | @RequestMapping("updateMsgStatus") 41 | @ResponseBody 42 | public String updateMsgStatus(Integer fromUserId, Integer toUserId) { 43 | Message message = new Message(); 44 | message.setFromUserId(fromUserId); 45 | message.setToUserId(toUserId); 46 | message.setIsTransport(1); 47 | messageService.updateMessage(message); 48 | return ""; 49 | } 50 | 51 | @RequestMapping("getMsgHistory") 52 | @ResponseBody 53 | public List getMsgHistory(Integer fromUserId, Integer toUserId,Integer pageNum, Integer pageSize){ 54 | 55 | Message message = new Message(); 56 | message.setFromUserId(fromUserId); 57 | message.setToUserId(toUserId); 58 | message.setMsgType(1); 59 | 60 | return messageService.getMessageloggingList(message, pageNum, pageSize); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.controller; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import javax.servlet.http.HttpSession; 9 | 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.data.domain.PageRequest; 12 | import org.springframework.data.domain.Pageable; 13 | import org.springframework.stereotype.Controller; 14 | import org.springframework.web.bind.annotation.PathVariable; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RequestMethod; 17 | import org.springframework.web.bind.annotation.ResponseBody; 18 | 19 | import com.yzeng.charme.entity.User; 20 | import com.yzeng.charme.entity.UserInfo; 21 | import com.yzeng.charme.service.UserService; 22 | import com.yzeng.charme.utils.WebResult; 23 | 24 | import io.swagger.annotations.ApiImplicitParam; 25 | import io.swagger.annotations.ApiOperation; 26 | 27 | @Controller 28 | @RequestMapping("user") 29 | public class UserController { 30 | 31 | @Autowired 32 | private UserService userService; 33 | @ApiOperation(value="用户注册", notes="根据User对象创建用户") 34 | @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User") 35 | @RequestMapping(value="register",method=RequestMethod.POST) 36 | public WebResult register(String username,String password) { 37 | WebResult wr = new WebResult(); 38 | User user = new User(); 39 | user.setUsername(username); 40 | user.setPassword(password); 41 | Map map = userService.register(user); 42 | wr.setData(map); 43 | return wr; 44 | } 45 | 46 | 47 | @RequestMapping("login") 48 | public String login(String username,String password,HttpSession session) { 49 | User user = new User(); 50 | user.setUsername(username); 51 | user.setPassword(password); 52 | Map map = userService.login(user); 53 | if(map != null && map.size() > 0) { 54 | boolean flag = (boolean) map.get("flag"); 55 | if(flag) { 56 | session.setAttribute("user", map.get("userInfo")); 57 | return "index"; 58 | }else { 59 | return "login"; 60 | } 61 | }else { 62 | return "login"; 63 | } 64 | } 65 | 66 | @ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息") 67 | @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "INTEGER") 68 | @RequestMapping("/get/{id}") 69 | @ResponseBody 70 | public User getUser(@PathVariable int id) { 71 | //User user = userService.getUser(id); 72 | User user = new User(); 73 | user.setId(id); 74 | User user1 = userService.getNameById(user); 75 | return user1; 76 | } 77 | 78 | @RequestMapping("/delete/{id}") 79 | @ResponseBody 80 | public String delete(@PathVariable int id) { 81 | userService.remove(id); 82 | return "delete sucess"; 83 | } 84 | 85 | @RequestMapping("/add") 86 | @ResponseBody 87 | public String insert(String username,String password) { 88 | User user = new User(); 89 | user.setUsername(username); 90 | user.setPassword(password); 91 | userService.insert(user); 92 | return "sucess"; 93 | } 94 | 95 | @RequestMapping("/insert") 96 | @ResponseBody 97 | public String insertAll() { 98 | List list = new ArrayList<>(); 99 | for (int i = 10; i < 15; i++) { 100 | //list.add(new User(i, "" + i, i)); 101 | } 102 | userService.insertAll(list); 103 | return "sucess"; 104 | } 105 | 106 | @RequestMapping("/find/all") 107 | @ResponseBody 108 | public List find(){ 109 | return userService.findAll(); 110 | } 111 | 112 | @RequestMapping("/find/{start}") 113 | @ResponseBody 114 | public List findByPage(@PathVariable int start,User user){ 115 | Pageable pageable=new PageRequest(start, 2); 116 | return userService.findByPage(user, pageable); 117 | } 118 | 119 | @RequestMapping("/update/{id}") 120 | @ResponseBody 121 | public String update(@PathVariable int id){ 122 | User user =new User(); 123 | userService.update(user); 124 | return "sucess"; 125 | } 126 | 127 | @RequestMapping("/test") 128 | @ResponseBody 129 | public String testId(){ 130 | Map map=new HashMap(); 131 | map.put("id", null); 132 | map.put("description", "123456"); 133 | userService.inserTest(map); 134 | return "sucess"; 135 | } 136 | 137 | 138 | } 139 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.dao; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.domain.Pageable; 6 | 7 | import com.yzeng.charme.entity.User; 8 | 9 | public interface UserDao { 10 | 11 | List findAll(); 12 | 13 | User getUserById(Integer id); 14 | 15 | User getUserByName(String username); 16 | 17 | User login(String username,String password); 18 | 19 | void update(User user); 20 | 21 | void insert(User user); 22 | 23 | void insertAll(List users); 24 | 25 | void remove(Integer id); 26 | 27 | List findByPage(User user, Pageable pageable); 28 | } 29 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/dao/UserInfoDao.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.dao; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.domain.Pageable; 6 | 7 | import com.yzeng.charme.entity.UserInfo; 8 | 9 | public interface UserInfoDao { 10 | 11 | List findAll(); 12 | 13 | UserInfo getUserInfoByUserId(Integer id); 14 | 15 | UserInfo getUserInfoByName(String username); 16 | 17 | void update(UserInfo userInfo); 18 | 19 | void insert(UserInfo userInfo); 20 | 21 | void insertAll(List userInfoList); 22 | 23 | void remove(Integer id); 24 | 25 | List findByPage(UserInfo userInfo, Pageable pageable); 26 | } 27 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/dao/impl/UserDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.dao.impl; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.mongodb.core.MongoTemplate; 8 | import org.springframework.data.mongodb.core.query.Criteria; 9 | import org.springframework.data.mongodb.core.query.Query; 10 | import org.springframework.data.mongodb.core.query.Update; 11 | import org.springframework.stereotype.Repository; 12 | 13 | import com.yzeng.charme.dao.UserDao; 14 | import com.yzeng.charme.entity.User; 15 | 16 | @Repository("userDao") 17 | public class UserDaoImpl implements UserDao{ 18 | 19 | /** 20 | * 由springboot自动注入,默认配置会产生mongoTemplate这个bean 21 | */ 22 | @Autowired 23 | private MongoTemplate mongoTemplate; 24 | 25 | /** 26 | * 查找全部 27 | */ 28 | @Override 29 | public List findAll() { 30 | return mongoTemplate.findAll(User.class); 31 | } 32 | 33 | /** 34 | * 根据id得到对象 35 | */ 36 | @Override 37 | public User getUserById(Integer id) { 38 | 39 | return mongoTemplate.findOne(new Query(Criteria.where("id").is(id)), User.class); 40 | } 41 | 42 | /** 43 | * 根据UserName得到对象 44 | */ 45 | @Override 46 | public User getUserByName(String username) { 47 | 48 | return mongoTemplate.findOne(new Query(Criteria.where("username").is(username)), User.class); 49 | } 50 | 51 | /** 52 | * 登录 53 | */ 54 | @Override 55 | public User login(String username,String password) { 56 | Criteria criteria = new Criteria(); 57 | criteria.and("username").is(username); 58 | criteria.and("password").is(password); 59 | return mongoTemplate.findOne(new Query(criteria), User.class); 60 | } 61 | 62 | /** 63 | * 插入一个用户 64 | */ 65 | @Override 66 | public void insert(User user) { 67 | mongoTemplate.insert(user); 68 | } 69 | 70 | /** 71 | * 根据id删除一个用户 72 | */ 73 | @Override 74 | public void remove(Integer id) { 75 | Criteria criteria = Criteria.where("id").is(id); 76 | Query query = new Query(criteria); 77 | mongoTemplate.remove(query,User.class); 78 | } 79 | 80 | /** 81 | * 分页查找 82 | * 83 | * user代表过滤条件 84 | * 85 | * pageable代表分页bean 86 | */ 87 | @Override 88 | public List findByPage(User user, Pageable pageable) { 89 | Query query = new Query(); 90 | if (user != null && user.getUsername() != null) { 91 | //模糊查询 92 | query = new Query(Criteria.where("name").regex("^" + user.getUsername())); 93 | } 94 | List list = mongoTemplate.find(query.with(pageable), User.class); 95 | return list; 96 | } 97 | 98 | /** 99 | * 根据id更新 100 | */ 101 | @Override 102 | public void update(User user) { 103 | Criteria criteria = Criteria.where("id").is(user.getId()); 104 | Query query = Query.query(criteria); 105 | Update update = Update.update("name", user.getUsername()).set("password", user.getPassword()); 106 | mongoTemplate.updateMulti(query, update, User.class); 107 | } 108 | 109 | /** 110 | * 插入一个集合 111 | */ 112 | @Override 113 | public void insertAll(List users) { 114 | mongoTemplate.insertAll(users); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/dao/impl/UserInfoDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.dao.impl; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.mongodb.core.MongoTemplate; 8 | import org.springframework.data.mongodb.core.query.Criteria; 9 | import org.springframework.data.mongodb.core.query.Query; 10 | import org.springframework.data.mongodb.core.query.Update; 11 | import org.springframework.stereotype.Repository; 12 | 13 | import com.yzeng.charme.dao.UserDao; 14 | import com.yzeng.charme.dao.UserInfoDao; 15 | import com.yzeng.charme.entity.UserInfo; 16 | 17 | @Repository("userInfoDao") 18 | public class UserInfoDaoImpl implements UserInfoDao{ 19 | 20 | /** 21 | * 由springboot自动注入,默认配置会产生mongoTemplate这个bean 22 | */ 23 | @Autowired 24 | private MongoTemplate mongoTemplate; 25 | 26 | /** 27 | * 查找全部 28 | */ 29 | @Override 30 | public List findAll() { 31 | return mongoTemplate.findAll(UserInfo.class); 32 | } 33 | 34 | /** 35 | * 根据id得到对象 36 | */ 37 | @Override 38 | public UserInfo getUserInfoByUserId(Integer id) { 39 | 40 | return mongoTemplate.findOne(new Query(Criteria.where("userId").is(id)), UserInfo.class); 41 | } 42 | 43 | /** 44 | * 根据UserName得到对象 45 | */ 46 | @Override 47 | public UserInfo getUserInfoByName(String username) { 48 | 49 | return mongoTemplate.findOne(new Query(Criteria.where("username").is(username)), UserInfo.class); 50 | } 51 | 52 | /** 53 | * 插入一个用户 54 | */ 55 | @Override 56 | public void insert(UserInfo userInfo) { 57 | mongoTemplate.insert(userInfo); 58 | } 59 | 60 | /** 61 | * 根据id删除一个用户 62 | */ 63 | @Override 64 | public void remove(Integer id) { 65 | Criteria criteria = Criteria.where("id").is(id); 66 | Query query = new Query(criteria); 67 | mongoTemplate.remove(query,UserInfo.class); 68 | } 69 | 70 | /** 71 | * 分页查找 72 | * 73 | * user代表过滤条件 74 | * 75 | * pageable代表分页bean 76 | */ 77 | @Override 78 | public List findByPage(UserInfo user, Pageable pageable) { 79 | // Query query = new Query(); 80 | // if (user != null && user.getUsername() != null) { 81 | // //模糊查询 82 | // query = new Query(Criteria.where("name").regex("^" + user.getUsername())); 83 | // } 84 | // List list = mongoTemplate.find(query.with(pageable), UserInfo.class); 85 | return null; 86 | } 87 | 88 | /** 89 | * 根据id更新 90 | */ 91 | @Override 92 | public void update(UserInfo user) { 93 | // Criteria criteria = Criteria.where("id").is(user.getId()); 94 | // Query query = Query.query(criteria); 95 | // Update update = Update.update("name", user.getUsername()).set("password", user.getPassword()); 96 | // mongoTemplate.updateMulti(query, update, UserInfo.class); 97 | } 98 | 99 | /** 100 | * 插入一个集合 101 | */ 102 | @Override 103 | public void insertAll(List users) { 104 | mongoTemplate.insertAll(users); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/entity/Group.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.entity; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 群实体 7 | * @author yzengchn@163.com 8 | * 2018-09-06 10:43:25 9 | * @version 1.0.0 10 | */ 11 | public class Group { 12 | private Integer id; 13 | private Integer createUserId;//创建用户 14 | private String groupName;//群名 15 | private String groupDescribes;//群介绍 16 | private Date createTime;//创建时间 17 | 18 | 19 | public Integer getId() { 20 | return id; 21 | } 22 | public void setId(Integer id) { 23 | this.id = id; 24 | } 25 | public Integer getCreateUserId() { 26 | return createUserId; 27 | } 28 | public void setCreateUserId(Integer createUserId) { 29 | this.createUserId = createUserId; 30 | } 31 | public String getGroupName() { 32 | return groupName; 33 | } 34 | public void setGroupName(String groupName) { 35 | this.groupName = groupName; 36 | } 37 | public String getGroupDescribes() { 38 | return groupDescribes; 39 | } 40 | public void setGroupDescribes(String groupDescribes) { 41 | this.groupDescribes = groupDescribes; 42 | } 43 | public Date getCreateTime() { 44 | return createTime; 45 | } 46 | public void setCreateTime(Date createTime) { 47 | this.createTime = createTime; 48 | } 49 | 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/entity/Message.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.entity; 2 | 3 | import java.util.Date; 4 | 5 | public class Message { 6 | private Integer id; //ID 7 | private String content; //消息内容 8 | private Integer fromUserId; //发送者ID 9 | private Integer toUserId; //接收者ID 10 | private Date sendMsgTime; //发送时间 11 | 12 | /** 13 | 值为0时:这条消息为普通的文本消息,content为消息内容,服务器转发时会给发出者发一份 14 | 值为-1时:这条消息为普通文本类通知消息,content为消息内容,服务器转发时不会发给发出者 15 | 值为1时:这条消息为群组消息,content为消息内容,服务器转发时不会发给发出者,因为发送对象含有发出者自身 16 | 注意:当值为1时,to数组不全为发送对象的id,0为groupId 17 | 值为2时:请注意,值为2的情况并不会出现在前端发送消息的类型中,这严格来说是值为1的一种特殊情况。 18 | 这条消息为群组消息,只被记录于数据库,to为群组的Id,服务端真正进行的操作是向群组的每一个用户发送一条相同的类型为1消息, 19 | 而这个类型的消息仅仅用于记录用户和群组之间有这样的消息,以便于查询用户在群组里的聊天记录。 20 | 值为3时:这条消息为上线通知,content无意义,仅为记录性内容,服务器转发不给发出者 21 | 值为4时:这条消息为下线通知,content无意义,仅为记录性内容,不给发出者发 22 | 值为5时:这条消息为好友申请,content为附加消息(申请结果将以普通消息格式返回),不给发出者发 23 | 值为6时:这条消息为加群邀请,content为群的id 24 | */ 25 | private Integer msgType; //消息类型 26 | private String isOffline;//是否离线消息 27 | private Integer isTransport; //传输状态1:已读 0:未读 2:失败 28 | 29 | public String getContent() { 30 | return content; 31 | } 32 | public void setContent(String content) { 33 | this.content = content; 34 | } 35 | public Integer getMsgType() { 36 | return msgType; 37 | } 38 | public void setMsgType(Integer msgType) { 39 | this.msgType = msgType; 40 | } 41 | public Integer getIsTransport() { 42 | return isTransport; 43 | } 44 | public void setIsTransport(Integer isTransport) { 45 | this.isTransport = isTransport; 46 | } 47 | 48 | 49 | 50 | public Message() { 51 | super(); 52 | } 53 | 54 | public Date getSendMsgTime() { 55 | return sendMsgTime; 56 | } 57 | public void setSendMsgTime(Date sendMsgTime) { 58 | this.sendMsgTime = sendMsgTime; 59 | } 60 | 61 | public Integer getId() { 62 | return id; 63 | } 64 | public void setId(Integer id) { 65 | this.id = id; 66 | } 67 | public Integer getFromUserId() { 68 | return fromUserId; 69 | } 70 | public void setFromUserId(Integer fromUserId) { 71 | this.fromUserId = fromUserId; 72 | } 73 | public Integer getToUserId() { 74 | return toUserId; 75 | } 76 | public void setToUserId(Integer toUserId) { 77 | this.toUserId = toUserId; 78 | } 79 | public String getIsOffline() { 80 | return isOffline; 81 | } 82 | public void setIsOffline(String isOffline) { 83 | this.isOffline = isOffline; 84 | } 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.entity; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | public class User implements Serializable{ 8 | /** 9 | * 10 | */ 11 | private static final long serialVersionUID = 1L; 12 | private Integer id; 13 | private String username; 14 | private String password; 15 | private String salt; 16 | private Date registertime; 17 | private Date lastTime; 18 | private String lastIp; 19 | public Date getRegistertime() { 20 | return registertime; 21 | } 22 | 23 | 24 | public void setRegistertime(Date registertime) { 25 | this.registertime = registertime; 26 | } 27 | 28 | 29 | public Date getLastTime() { 30 | return lastTime; 31 | } 32 | 33 | 34 | public void setLastTime(Date lastTime) { 35 | this.lastTime = lastTime; 36 | } 37 | 38 | 39 | public String getLastIp() { 40 | return lastIp; 41 | } 42 | 43 | 44 | public void setLastIp(String lastIp) { 45 | this.lastIp = lastIp; 46 | } 47 | private List msg; 48 | 49 | public User() { 50 | super(); 51 | } 52 | 53 | 54 | public Integer getId() { 55 | return id; 56 | } 57 | public void setId(Integer id) { 58 | this.id = id; 59 | } 60 | public String getUsername() { 61 | return username; 62 | } 63 | public void setUsername(String username) { 64 | this.username = username; 65 | } 66 | public String getPassword() { 67 | return password; 68 | } 69 | public void setPassword(String password) { 70 | this.password = password; 71 | } 72 | 73 | public List getMsg() { 74 | return msg; 75 | } 76 | public void setMsg(List msg) { 77 | this.msg = msg; 78 | } 79 | 80 | 81 | public String getSalt() { 82 | return salt; 83 | } 84 | 85 | 86 | public void setSalt(String salt) { 87 | this.salt = salt; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/entity/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.entity; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 用户信息资料 7 | * @author yzengchn@163.com 8 | * 2018-08-22 17:24:29 9 | * @version 1.0.0 10 | */ 11 | public class UserInfo { 12 | //用户ID 13 | private Integer userId; 14 | //用户名 15 | private String username; 16 | //昵称 17 | private String nickname; 18 | //性别(1男 2女 0未填) 19 | private Integer sex; 20 | //年龄 21 | private Integer age; 22 | //出生年月日 23 | private Date birthTime; 24 | //签名 25 | private String signature; 26 | //头像 27 | private Integer avatarId; 28 | //1为在线 0为离线 29 | private Integer isOnline; 30 | 31 | public Integer getUserId() { 32 | return userId; 33 | } 34 | public void setUserId(Integer userId) { 35 | this.userId = userId; 36 | } 37 | public String getUsername() { 38 | return username; 39 | } 40 | public void setUsername(String username) { 41 | this.username = username; 42 | } 43 | public String getNickname() { 44 | return nickname; 45 | } 46 | public void setNickname(String nickname) { 47 | this.nickname = nickname; 48 | } 49 | public Integer getSex() { 50 | return sex; 51 | } 52 | public void setSex(Integer sex) { 53 | this.sex = sex; 54 | } 55 | public Integer getAge() { 56 | return age; 57 | } 58 | public void setAge(Integer age) { 59 | this.age = age; 60 | } 61 | public String getSignature() { 62 | return signature; 63 | } 64 | public void setSignature(String signature) { 65 | this.signature = signature; 66 | } 67 | public Integer getAvatarId() { 68 | return avatarId; 69 | } 70 | public void setAvatarId(Integer avatarId) { 71 | this.avatarId = avatarId; 72 | } 73 | public Integer getIsOnline() { 74 | return isOnline; 75 | } 76 | public void setIsOnline(Integer isOnline) { 77 | this.isOnline = isOnline; 78 | } 79 | public Date getBirthTime() { 80 | return birthTime; 81 | } 82 | public void setBirthTime(Date birthTime) { 83 | this.birthTime = birthTime; 84 | } 85 | 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/entity/UserRelation.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.entity; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 用户关系关联 7 | * @author Yao.Zeng 8 | * @version [版本号, 2018年8月21日] 9 | */ 10 | public class UserRelation { 11 | private Integer id; 12 | //用户A 13 | private Integer userIdA; 14 | //用户B 15 | private Integer userIdB; 16 | //用户之间的关系状态 1:好友 0:黑名单 17 | private int relationStatus; 18 | //添加时间 19 | private Date relationTime; 20 | //用户A给用户B的备注名 21 | private String memoName; 22 | 23 | public String getMemoName() { 24 | return memoName; 25 | } 26 | public void setMemoName(String memoName) { 27 | this.memoName = memoName; 28 | } 29 | public Integer getUserIdA() { 30 | return userIdA; 31 | } 32 | public void setUserIdA(Integer userIdA) { 33 | this.userIdA = userIdA; 34 | } 35 | public Integer getUserIdB() { 36 | return userIdB; 37 | } 38 | public void setUserIdB(Integer userIdB) { 39 | this.userIdB = userIdB; 40 | } 41 | public int getRelationStatus() { 42 | return relationStatus; 43 | } 44 | public void setRelationStatus(int relationStatus) { 45 | this.relationStatus = relationStatus; 46 | } 47 | public Date getRelationTime() { 48 | return relationTime; 49 | } 50 | public void setRelationTime(Date relationTime) { 51 | this.relationTime = relationTime; 52 | } 53 | public UserRelation() { 54 | super(); 55 | } 56 | public Integer getId() { 57 | return id; 58 | } 59 | public void setId(Integer id) { 60 | this.id = id; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/mapper/FriendMapper.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.mapper; 2 | 3 | import org.apache.ibatis.annotations.Mapper; 4 | 5 | import com.yzeng.charme.entity.UserRelation; 6 | 7 | @Mapper 8 | public interface FriendMapper { 9 | /** 10 | * 建立好友关系 11 | * @param userIdA 12 | * @param userIdB 13 | * @return 14 | */ 15 | int addFriend(UserRelation userRelation); 16 | } 17 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/mapper/GroupMapper.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.mapper; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | import com.yzeng.charme.entity.Group; 10 | 11 | @Mapper 12 | public interface GroupMapper { 13 | /** 14 | * 新增群 15 | * @param group 16 | * @return 17 | */ 18 | int addGroup(Group group); 19 | 20 | /** 21 | * 加群 22 | * @param groupId 23 | * @param userId 24 | * @return 25 | */ 26 | int addUserToGroup(@Param("groupId")Integer groupId,@Param("userId")Integer userId); 27 | 28 | /** 29 | * 查询用户创建的群 30 | * @param userId 31 | * @return 32 | */ 33 | List getGroupByCreateUserId(Integer userId); 34 | 35 | /** 36 | * 查询用户加入的群 37 | * @param userId 38 | * @return 39 | */ 40 | List getGroupByUserId(Integer userId); 41 | 42 | /** 43 | * 获得群成员信息 44 | * @param groupId 45 | * @return 46 | */ 47 | List> getGroupUserByGroupId(Integer groupId); 48 | 49 | /** 50 | * 查询群信息总数 51 | * @param groupId 52 | * @return 53 | */ 54 | Integer getGroupMsgCount(Integer groupId); 55 | 56 | /** 57 | * 查询群消息 58 | * @param groupId 59 | * @return 60 | */ 61 | List> getGroupMsg(Integer groupId); 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/mapper/MessageMapper.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.mapper; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | import com.yzeng.charme.entity.Message; 8 | 9 | @Mapper 10 | public interface MessageMapper { 11 | /** 12 | * 插入一条消息 13 | * @param message 14 | * @return 15 | */ 16 | Integer insertMsg (Message message); 17 | 18 | /** 19 | * 获得聊天记录总数 20 | * @return 21 | */ 22 | Integer getMessageTotalCount(Message message); 23 | 24 | /** 25 | * 根据ID查询消息 26 | * @param id 27 | * @return 28 | */ 29 | Message getMsgById(Integer id); 30 | 31 | /** 32 | * 聊天记录查询 33 | * @param message 34 | * @return 35 | */ 36 | List getMessageloggingList(Message message); 37 | 38 | /** 39 | * 查询该用户的离线消息 40 | * @param userId 41 | * @return 42 | */ 43 | List getOfflineMessageList(Integer userId); 44 | 45 | /** 46 | * 查询该用户的消息传输状态1:已读 0:未读 2:失败 47 | * @param message 48 | * @return 49 | */ 50 | List getMessageListByStatus(Message message); 51 | 52 | 53 | 54 | /** 55 | * 更新消息状态 56 | * @param message 57 | * @return 58 | */ 59 | int updateMessage (Message message); 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/mapper/UserInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.mapper; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | import com.yzeng.charme.entity.User; 8 | import com.yzeng.charme.entity.UserInfo; 9 | 10 | @Mapper 11 | public interface UserInfoMapper { 12 | /** 13 | * 第一次保存用户个人信息 14 | * @param userInfo userId username 15 | * @return 16 | */ 17 | int firstSaveUserInfo(UserInfo userInfo); 18 | 19 | /** 20 | * 根据用户ID查询个人信息 21 | * @param userId 22 | * @return 23 | */ 24 | UserInfo getUserInfoByUserId(Integer userId); 25 | 26 | /** 27 | * 更新用户个人信息 28 | * @param userInfo 29 | * @return 30 | */ 31 | int updateUserInfo(UserInfo userInfo); 32 | 33 | /** 34 | * 获得所有用户 35 | * @return 36 | */ 37 | List findAll(); 38 | 39 | /** 40 | * 根据用户名或者昵称查询用户信息列表 41 | * @param user 42 | * @return 43 | */ 44 | List findByName(UserInfo userinfo); 45 | } 46 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.mapper; 2 | 3 | import java.util.Map; 4 | 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | 8 | import com.yzeng.charme.entity.User; 9 | 10 | @Mapper 11 | public interface UserMapper { 12 | 13 | User getNameById(User user); 14 | 15 | Integer insertUser(User user); 16 | 17 | User getUserByName(@Param(value="username")String username); 18 | 19 | int insertTest(Map map); 20 | } 21 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/netty/NettyClient.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.netty; 2 | 3 | import java.util.Date; 4 | 5 | import io.netty.bootstrap.Bootstrap; 6 | import io.netty.channel.Channel; 7 | import io.netty.channel.ChannelInitializer; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.nio.NioSocketChannel; 10 | import io.netty.handler.codec.string.StringEncoder; 11 | 12 | public class NettyClient { 13 | public static void main(String[] args) { 14 | Bootstrap bootstrap = new Bootstrap(); 15 | NioEventLoopGroup group = new NioEventLoopGroup(); 16 | bootstrap.group(group) 17 | .channel(NioSocketChannel.class) 18 | .handler(new ChannelInitializer() { 19 | 20 | @Override 21 | protected void initChannel(Channel ch) throws Exception { 22 | ch.pipeline().addLast(new StringEncoder()); 23 | } 24 | }); 25 | 26 | Channel channel = bootstrap.connect("127.0.0.1", 8888).channel(); 27 | 28 | while(true) { 29 | channel.writeAndFlush(new Date()+" :msg"); 30 | try { 31 | Thread.sleep(2000); 32 | } catch (InterruptedException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/netty/NettyServer.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.netty; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.SimpleChannelInboundHandler; 7 | import io.netty.channel.nio.NioEventLoopGroup; 8 | import io.netty.channel.socket.nio.NioServerSocketChannel; 9 | import io.netty.channel.socket.nio.NioSocketChannel; 10 | import io.netty.handler.codec.string.StringDecoder; 11 | 12 | public class NettyServer { 13 | public static void main(String[] args) { 14 | //bossGroup表示监听端口,accept 新连接的线程组 15 | NioEventLoopGroup bossGroup = new NioEventLoopGroup(); 16 | //workerGroup表示处理每一条连接的数据读写的线程组 17 | NioEventLoopGroup workGroup = new NioEventLoopGroup(); 18 | //创建了一个引导类 ServerBootstrap,这个类将引导我们进行服务端的启动工作 19 | ServerBootstrap bootstrap = new ServerBootstrap(); 20 | 21 | bootstrap.group(bossGroup, workGroup) 22 | .channel(NioServerSocketChannel.class) 23 | .childHandler(new ChannelInitializer() { 24 | 25 | @Override 26 | protected void initChannel(NioSocketChannel ch) throws Exception { 27 | // TODO Auto-generated method stub 28 | ch.pipeline().addLast(new StringDecoder()); 29 | ch.pipeline().addLast(new SimpleChannelInboundHandler() { 30 | @Override 31 | protected void channelRead0(ChannelHandlerContext ctx, String msg) { 32 | System.out.println(msg); 33 | } 34 | }); 35 | } 36 | }) 37 | .bind(8888); 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/queue/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.queue; 2 | 3 | import java.util.Date; 4 | 5 | import org.springframework.amqp.core.AmqpTemplate; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.ResponseBody; 11 | 12 | @Controller 13 | public class LoginController { 14 | 15 | @Autowired 16 | private AmqpTemplate amqpTemplate; 17 | 18 | @RequestMapping(value="send",method=RequestMethod.GET) 19 | @ResponseBody 20 | public String send() { 21 | String content = "Date : "+new Date(); 22 | amqpTemplate.convertAndSend("exchange", "topic.messages", content); 23 | return content; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/queue/Receiver.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.queue; 2 | 3 | import org.springframework.amqp.rabbit.annotation.RabbitHandler; 4 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | @RabbitListener(queues = "topic.messages") 9 | public class Receiver { 10 | 11 | @RabbitHandler 12 | public void receiver1(String msg) { 13 | System.out.println("receiver:"+ msg); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/queue/UserReceiver.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.queue; 2 | 3 | import org.springframework.amqp.rabbit.annotation.RabbitHandler; 4 | import org.springframework.amqp.rabbit.annotation.RabbitListener; 5 | import org.springframework.stereotype.Component; 6 | 7 | import com.alibaba.fastjson.JSON; 8 | import com.yzeng.charme.entity.User; 9 | 10 | @Component 11 | @RabbitListener(queues = "topic.message") 12 | public class UserReceiver { 13 | 14 | @RabbitHandler 15 | public void receiver(String userStr) { 16 | User user = JSON.parseObject(userStr, User.class); 17 | System.out.println(user.getPassword()); 18 | System.out.println(user.getUsername()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/server/MongoHelper.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.server; 2 | 3 | import com.mongodb.MongoClient; 4 | import com.mongodb.client.MongoDatabase; 5 | 6 | public class MongoHelper { 7 | 8 | static final String DBName = "test"; 9 | static final String ServerAddress = "139.199.86.201"; 10 | static final int PORT = 27017; 11 | 12 | public MongoHelper(){ 13 | } 14 | 15 | public MongoClient getMongoClient( ){ 16 | MongoClient mongoClient = null; 17 | try { 18 | // 连接到 mongodb 服务 19 | mongoClient = new MongoClient(ServerAddress, PORT); 20 | System.out.println("Connect to mongodb successfully"); 21 | } catch (Exception e) { 22 | System.err.println(e.getClass().getName() + ": " + e.getMessage()); 23 | } 24 | return mongoClient; 25 | } 26 | 27 | public MongoDatabase getMongoDataBase(MongoClient mongoClient) { 28 | MongoDatabase mongoDataBase = null; 29 | try { 30 | if (mongoClient != null) { 31 | // 连接到数据库 32 | mongoDataBase = mongoClient.getDatabase(DBName); 33 | System.out.println("Connect to DataBase successfully"); 34 | } else { 35 | throw new RuntimeException("MongoClient不能够为空"); 36 | } 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | return mongoDataBase; 41 | } 42 | 43 | public void closeMongoClient(MongoDatabase mongoDataBase,MongoClient mongoClient ) { 44 | if (mongoDataBase != null) { 45 | mongoDataBase = null; 46 | } 47 | if (mongoClient != null) { 48 | mongoClient.close(); 49 | } 50 | System.out.println("CloseMongoClient successfully"); 51 | 52 | } 53 | } -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/server/SocketServer.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.server; 2 | 3 | import java.io.IOException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.ArrayList; 6 | import java.util.Date; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | import javax.websocket.OnClose; 13 | import javax.websocket.OnError; 14 | import javax.websocket.OnMessage; 15 | import javax.websocket.OnOpen; 16 | import javax.websocket.Session; 17 | import javax.websocket.server.PathParam; 18 | import javax.websocket.server.ServerEndpoint; 19 | 20 | import org.springframework.context.ApplicationContext; 21 | import org.springframework.stereotype.Component; 22 | 23 | import com.alibaba.fastjson.JSON; 24 | import com.alibaba.fastjson.JSONObject; 25 | import com.yzeng.charme.entity.Message; 26 | import com.yzeng.charme.entity.User; 27 | import com.yzeng.charme.entity.UserInfo; 28 | import com.yzeng.charme.mapper.MessageMapper; 29 | import com.yzeng.charme.service.GroupService; 30 | import com.yzeng.charme.service.MessageService; 31 | import com.yzeng.charme.service.UserService; 32 | import com.yzeng.charme.utils.SpringUtils; 33 | 34 | @ServerEndpoint(value = "/socketserver/{userId}") 35 | @Component 36 | public class SocketServer { 37 | //表示与某个用户的连接会话,通过它给客户端发送数据 38 | private Session session; 39 | //在线人数 40 | private static Integer onlineCount = 0; 41 | 42 | private static Integer id = 0; 43 | //客户端对象列表 44 | private static Map clients = new ConcurrentHashMap(); 45 | //用户与websocket绑定session 46 | private static Map userPool = new HashMap(); 47 | //当前用户 48 | private UserInfo user; 49 | 50 | //你要注入的service或者dao 51 | private UserService userService; 52 | private MessageService messageService; 53 | private GroupService groupService; 54 | 55 | /** 56 | * 用户连接时触发 57 | * @param session 58 | * @param userid 59 | */ 60 | @OnOpen 61 | public void open(Session session,@PathParam(value="userId")Integer userId) { 62 | this.session = session; 63 | 64 | userService = SpringUtils.getBean(UserService.class); 65 | messageService = SpringUtils.getBean(MessageService.class); 66 | groupService = SpringUtils.getBean(GroupService.class); 67 | 68 | //获得登录用户个人信息 69 | user = userService.getUserInfoByUserId(userId); 70 | //更新在线状态 71 | user.setIsOnline(1); 72 | userService.updateUserInfo(user); 73 | //增加在线人数 74 | addOnlineCount(); 75 | //放入客户端Map 76 | clients.put(user, this); 77 | //放入用户池 78 | userPool.put(userId, session); 79 | //检查自己是否有未接收的消息 80 | List messageList = new ArrayList(); 81 | messageList = messageService.getOfflineMessageList(userId); 82 | if(messageList != null && messageList.size() > 0) { 83 | for (Message message : messageList) { 84 | String jsonMessage = getMessage(message); 85 | //发送特定消息 86 | singleSend(jsonMessage, userPool.get(userId)); 87 | message.setIsOffline("N"); 88 | messageService.updateMessage(message); 89 | } 90 | } 91 | 92 | System.out.println(userId+"已连接"); 93 | } 94 | 95 | /** 96 | * 收到信息时触发 97 | * @param message 客户端发送过来的消息 98 | * @param session 可选的参数 99 | * @throws IOException 100 | */ 101 | @OnMessage 102 | public void onMessage(String message,Session session) throws IOException { 103 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 104 | Message msg = new Message(); 105 | JSONObject jsonMsg = JSON.parseObject(message); 106 | Integer type = jsonMsg.getIntValue("type"); 107 | Integer from = jsonMsg.getIntValue("from"); 108 | Integer to = jsonMsg.getIntValue("to"); 109 | String content = jsonMsg.getString("content"); 110 | msg.setMsgType(type); 111 | msg.setContent(content); 112 | msg.setFromUserId(from); 113 | msg.setToUserId(to); 114 | msg.setSendMsgTime(new Date()); 115 | 116 | sendMessage(msg); 117 | System.out.println("当前发送人sessionid为"+session.getId()+"发送内容为"+message); 118 | } 119 | 120 | /** 121 | * 连接关闭触发 122 | */ 123 | @OnClose 124 | public void onClose() { 125 | //客户端移除 126 | clients.remove(user); 127 | //用户池移除 128 | userPool.remove(user.getUserId()); 129 | //在线人数减一 130 | subOnlineCount(); 131 | //将用户的在线状态设为0 132 | user.setIsOnline(0); 133 | //更新用户个人信息状态 134 | userService.updateUserInfo(user); 135 | } 136 | 137 | /** 138 | * 发生错误时触发 139 | * @param session 140 | * @param error 141 | */ 142 | @OnError 143 | public void onError(Session session, Throwable error) { 144 | error.printStackTrace(); 145 | } 146 | 147 | /** 148 | * 发送消息 149 | * @param message 150 | * @throws IOException 151 | */ 152 | public void sendMessage(Message message) throws IOException { 153 | Session toSession = userPool.get(message.getToUserId()); 154 | switch (message.getMsgType()) { 155 | case -1://不给发送方(自己)发消息 156 | if(toSession != null && toSession.isOpen()) { 157 | toSession.getBasicRemote().sendText(getMessage(message)); 158 | } 159 | break; 160 | case 1://普通消息 161 | //判断是否在线 162 | if(toSession != null && toSession.isOpen()) { 163 | message.setIsOffline("N"); 164 | messageService.insertMsg(message); 165 | 166 | toSession.getBasicRemote().sendText(getMessage(message)); 167 | }else { 168 | //将消息写到DB,标记为离线消息 169 | message.setIsOffline("Y"); 170 | messageService.insertMsg(message); 171 | } 172 | break; 173 | case 2://群信息 174 | message.setIsOffline("N"); 175 | messageService.insertMsg(message); 176 | //查询该群所有成员-遍历-给登录的用户发送消息 177 | List> list = groupService.getGroupUserByGroupId(message.getToUserId()); 178 | for (Map map : list) { 179 | int userId = Integer.parseInt(map.get("userId").toString()); 180 | //不包括自己 181 | if(userId != message.getFromUserId()) { 182 | Session sessionUser = userPool.get(userId); 183 | if(sessionUser != null && sessionUser.isOpen()) { 184 | sessionUser.getBasicRemote().sendText(getMessage(message)); 185 | } 186 | } 187 | } 188 | break; 189 | case 3: 190 | 191 | break; 192 | case 4: 193 | 194 | break; 195 | case 5://好友申请信息 196 | //判断是否在线 197 | if(toSession != null && toSession.isOpen()) { 198 | toSession.getBasicRemote().sendText(getMessage(message)); 199 | } 200 | break; 201 | case 6: 202 | 203 | break; 204 | 205 | } 206 | 207 | } 208 | 209 | public void sendMessageTo(String message, String To) throws IOException { 210 | // for (SocketServer item : clients.values()) { 211 | // if (item.user.getUsername().equals(To) ) { 212 | // System.out.println(JSON.toJSONString(user.getMsg().get(0))); 213 | // String jsonString = JSON.toJSONString(user.getMsg().get(0)); 214 | // item.session.getAsyncRemote().sendText(jsonString); 215 | // } 216 | // } 217 | SocketServer server = clients.get(user); 218 | server.session.getAsyncRemote().sendText(message); 219 | System.out.println(server); 220 | } 221 | 222 | public void sendMessageAll(String message) throws IOException { 223 | for (SocketServer item : clients.values()) { 224 | item.session.getAsyncRemote().sendText(message); 225 | } 226 | } 227 | 228 | /** 229 | * 对特定用户发送消息 230 | * @param message 231 | * @param session 232 | */ 233 | public void singleSend(String message, Session session){ 234 | try { 235 | session.getBasicRemote().sendText(message); 236 | System.out.println("特定消息:"+message); 237 | } catch (IOException e) { 238 | e.printStackTrace(); 239 | } 240 | } 241 | 242 | 243 | /** 244 | * 根据Message实体组装Json格式的数据返回给前台 245 | */ 246 | public String getMessage(Message message){ 247 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 248 | String fromName = userService.getUserInfoByUserId(message.getFromUserId()).getUsername(); 249 | //使用JSONObject方法构建Json数据 250 | JSONObject jsonObjectMessage = new JSONObject(); 251 | jsonObjectMessage.put("from", String.valueOf(message.getFromUserId())); 252 | jsonObjectMessage.put("fromName", fromName); 253 | jsonObjectMessage.put("to", new String[] {String.valueOf(message.getToUserId())}); 254 | jsonObjectMessage.put("content", String.valueOf(message.getContent())); 255 | jsonObjectMessage.put("type", String.valueOf(message.getMsgType())); 256 | jsonObjectMessage.put("time", formatter.format(message.getSendMsgTime())); 257 | return jsonObjectMessage.toString(); 258 | } 259 | 260 | public static synchronized int getOnlineCount() { 261 | return onlineCount; 262 | } 263 | 264 | public static synchronized void addOnlineCount() { 265 | SocketServer.onlineCount++; 266 | } 267 | 268 | public static synchronized void subOnlineCount() { 269 | SocketServer.onlineCount--; 270 | } 271 | 272 | 273 | 274 | } 275 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/FriendService.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service; 2 | 3 | import com.yzeng.charme.entity.UserRelation; 4 | 5 | public interface FriendService { 6 | 7 | /** 8 | * 建立好友关系 9 | * @param userIdA 10 | * @param userIdB 11 | * @return 12 | */ 13 | int addFriend(UserRelation userRelation); 14 | } 15 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/GroupService.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.yzeng.charme.entity.Group; 7 | 8 | public interface GroupService { 9 | /** 10 | * 新增群 11 | * @param group 12 | * @return 13 | */ 14 | int addGroup(Group group); 15 | 16 | /** 17 | * 加群 18 | * @param groupId 19 | * @param userId 20 | * @return 21 | */ 22 | int addUserToGroup(Integer groupId,Integer userId); 23 | 24 | /** 25 | * 查询用户创建的群 26 | * @param userId 27 | * @return 28 | */ 29 | List getGroupByCreateUserId(Integer userId); 30 | 31 | /** 32 | * 查询用户加入的群 33 | * @param userId 34 | * @return 35 | */ 36 | List getGroupByUserId(Integer userId); 37 | 38 | /** 39 | * 获得群成员信息 40 | * @param groupId 41 | * @return 42 | */ 43 | List> getGroupUserByGroupId(Integer groupId); 44 | 45 | /** 46 | * 查询群信息总数 47 | * @param groupId 48 | * @return 49 | */ 50 | Integer getGroupMsgCount(Integer groupId); 51 | 52 | /** 53 | * 查询群消息 54 | * @param groupId 55 | * @return 56 | */ 57 | List> getGroupMsgHistory(Integer groupId,int pageNum, int pageSize); 58 | } 59 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/MessageService.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service; 2 | 3 | import java.util.List; 4 | 5 | import com.yzeng.charme.entity.Message; 6 | 7 | public interface MessageService { 8 | 9 | /** 10 | * 插入一条消息 11 | * @param message 12 | * @return 13 | */ 14 | Integer insertMsg (Message message); 15 | 16 | /** 17 | * 根据ID查询消息 18 | * @param id 19 | * @return 20 | */ 21 | Message getMsgById(Integer id); 22 | 23 | /** 24 | * 获得聊天记录总数 25 | * @return 26 | */ 27 | Integer getMessageTotalCount(Message message); 28 | 29 | /** 30 | * 聊天记录查询 31 | * @param message 32 | * @return 33 | */ 34 | List getMessageloggingList(Message message,int pageNum, int pageSize); 35 | 36 | /** 37 | * 查询该用户的离线消息 38 | * @param userId 39 | * @return 40 | */ 41 | List getOfflineMessageList(Integer userId); 42 | 43 | /** 44 | * 查询该用户的消息传输状态1:已读 0:未读 2:失败 45 | * @param message 46 | * @return 47 | */ 48 | List getMessageListByStatus(Message message); 49 | 50 | /** 51 | * 更新消息状态 52 | * @param message 53 | * @return 54 | */ 55 | int updateMessage (Message message); 56 | } 57 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import org.springframework.data.domain.Pageable; 7 | 8 | import com.yzeng.charme.entity.User; 9 | import com.yzeng.charme.entity.UserInfo; 10 | 11 | public interface UserService { 12 | public User getNameById(User user); 13 | 14 | /** 15 | * 用户注册 16 | * @param user 17 | * @return 18 | */ 19 | Map register(User user); 20 | 21 | /** 22 | * 用户登录 23 | * @param user 24 | * @return 25 | */ 26 | Map login(User user); 27 | 28 | List findAll(); 29 | 30 | User getUser(Integer id); 31 | 32 | void update(User user); 33 | 34 | void insert(User user); 35 | 36 | void insertAll(List users); 37 | 38 | void remove(Integer id); 39 | 40 | List findByPage(User user,Pageable pageable); 41 | 42 | 43 | 44 | /**************以下为个人信息相关操作*****************/ 45 | /** 46 | * 第一次保存用户个人信息 47 | * @param userInfo userId username 48 | * @return 49 | */ 50 | int firstSaveUserInfo(UserInfo userInfo); 51 | 52 | /** 53 | * 根据用户ID查询个人信息 54 | * @param userId 55 | * @return 56 | */ 57 | UserInfo getUserInfoByUserId(Integer userId); 58 | 59 | /** 60 | * 更新用户个人信息 61 | * @param userInfo 62 | * @return 63 | */ 64 | int updateUserInfo(UserInfo userInfo); 65 | 66 | /** 67 | * 根据用户名或者昵称查询用户信息列表 68 | * @param user 69 | * @return 70 | */ 71 | List findByName(UserInfo userinfo); 72 | 73 | public int inserTest(Map map); 74 | } 75 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/impl/FriendServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service.impl; 2 | 3 | import java.util.Date; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | import com.yzeng.charme.entity.UserRelation; 10 | import com.yzeng.charme.mapper.FriendMapper; 11 | import com.yzeng.charme.service.FriendService; 12 | 13 | @Service("friendService") 14 | public class FriendServiceImpl implements FriendService{ 15 | 16 | @Resource 17 | private FriendMapper friendMapper; 18 | 19 | @Override 20 | public int addFriend(UserRelation userRelation) { 21 | userRelation.setRelationTime(new Date()); 22 | return friendMapper.addFriend(userRelation); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/impl/GroupServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import javax.annotation.Resource; 9 | 10 | import org.springframework.stereotype.Service; 11 | 12 | import com.github.pagehelper.PageHelper; 13 | import com.yzeng.charme.entity.Group; 14 | import com.yzeng.charme.mapper.GroupMapper; 15 | import com.yzeng.charme.service.GroupService; 16 | 17 | @Service("groupService") 18 | public class GroupServiceImpl implements GroupService{ 19 | 20 | @Resource 21 | private GroupMapper groupMapper; 22 | 23 | @Override 24 | public int addGroup(Group group) { 25 | group.setCreateTime(new Date()); 26 | return groupMapper.addGroup(group); 27 | } 28 | 29 | @Override 30 | public List getGroupByCreateUserId(Integer userId) { 31 | return groupMapper.getGroupByCreateUserId(userId); 32 | } 33 | 34 | @Override 35 | public List getGroupByUserId(Integer userId) { 36 | return groupMapper.getGroupByUserId(userId); 37 | } 38 | 39 | @Override 40 | public List> getGroupUserByGroupId(Integer groupId) { 41 | return groupMapper.getGroupUserByGroupId(groupId); 42 | } 43 | 44 | @Override 45 | public int addUserToGroup(Integer groupId, Integer userId) { 46 | return groupMapper.addUserToGroup(groupId, userId); 47 | } 48 | 49 | @Override 50 | public List> getGroupMsgHistory(Integer groupId,int pageNum, int pageSize) { 51 | //总页数 52 | Integer pageCount = 0; 53 | //总记录数 54 | Integer totalCount = groupMapper.getGroupMsgCount(groupId); 55 | if(totalCount%pageSize == 0) { 56 | pageCount = totalCount/pageSize; 57 | }else { 58 | pageCount = (totalCount/pageSize) + 1; 59 | } 60 | //当前传入的页数,计算 61 | pageNum = pageCount - pageNum; 62 | if(pageNum <= 0) { 63 | return new ArrayList>(); 64 | } 65 | PageHelper.startPage(pageNum, pageSize); 66 | return groupMapper.getGroupMsg(groupId); 67 | } 68 | 69 | @Override 70 | public Integer getGroupMsgCount(Integer groupId) { 71 | // TODO Auto-generated method stub 72 | return null; 73 | } 74 | 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/impl/MessageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service.impl; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import com.github.pagehelper.PageHelper; 9 | import com.yzeng.charme.entity.Message; 10 | import com.yzeng.charme.mapper.MessageMapper; 11 | import com.yzeng.charme.service.MessageService; 12 | 13 | @Service("messageService") 14 | public class MessageServiceImpl implements MessageService{ 15 | 16 | @Autowired 17 | private MessageMapper messageMapper; 18 | 19 | @Override 20 | public Integer insertMsg(Message message) { 21 | return messageMapper.insertMsg(message); 22 | } 23 | 24 | @Override 25 | public Message getMsgById(Integer id) { 26 | return messageMapper.getMsgById(id); 27 | } 28 | 29 | @Override 30 | public List getMessageloggingList(Message message,int pageNum, int pageSize) { 31 | //总页数 32 | Integer pageCount = 0; 33 | Integer totalCount = messageMapper.getMessageTotalCount(message); 34 | if(totalCount%pageSize == 0) { 35 | pageCount = totalCount/pageSize; 36 | }else { 37 | pageCount = (totalCount/pageSize) + 1; 38 | } 39 | //当前传入的页数,计算 40 | pageNum = pageCount - pageNum; 41 | PageHelper.startPage(pageNum, pageSize); 42 | return messageMapper.getMessageloggingList(message); 43 | } 44 | 45 | @Override 46 | public List getOfflineMessageList(Integer userId) { 47 | return messageMapper.getOfflineMessageList(userId); 48 | } 49 | 50 | @Override 51 | public int updateMessage(Message message) { 52 | return messageMapper.updateMessage(message); 53 | } 54 | 55 | @Override 56 | public List getMessageListByStatus(Message message) { 57 | return messageMapper.getMessageListByStatus(message); 58 | } 59 | 60 | @Override 61 | public Integer getMessageTotalCount(Message message) { 62 | return messageMapper.getMessageTotalCount(message); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.service.impl; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.UUID; 9 | 10 | import org.springframework.amqp.core.AmqpTemplate; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.data.domain.Pageable; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.util.DigestUtils; 15 | 16 | import com.alibaba.druid.util.StringUtils; 17 | import com.alibaba.fastjson.JSONObject; 18 | import com.yzeng.charme.dao.UserDao; 19 | import com.yzeng.charme.dao.UserInfoDao; 20 | import com.yzeng.charme.entity.User; 21 | import com.yzeng.charme.entity.UserInfo; 22 | import com.yzeng.charme.mapper.UserInfoMapper; 23 | import com.yzeng.charme.mapper.UserMapper; 24 | import com.yzeng.charme.service.UserService; 25 | 26 | @Service("userService") 27 | public class UserServiceImpl implements UserService{ 28 | 29 | 30 | @Autowired 31 | private UserMapper userMapper; 32 | 33 | @Autowired 34 | private UserInfoMapper userInfoMapper; 35 | 36 | @Autowired 37 | private AmqpTemplate amqpTemplate; 38 | 39 | 40 | @Override 41 | public List findAll() { 42 | //return userDao.findAll(); 43 | return userInfoMapper.findAll(); 44 | } 45 | 46 | @Override 47 | public void insert(User user) { 48 | String md5Pwd = DigestUtils.md5DigestAsHex(user.getPassword().getBytes()); 49 | //插入用户账户信息 50 | user.setPassword(md5Pwd); 51 | user.setRegistertime(new Date()); 52 | user.setLastTime(new Date()); 53 | Integer num = userMapper.insertUser(user); 54 | 55 | //插入用户个人信息 56 | UserInfo userInfo = new UserInfo(); 57 | userInfo.setUserId(user.getId()); 58 | userInfo.setUsername(user.getUsername()); 59 | userInfoMapper.firstSaveUserInfo(userInfo); 60 | } 61 | 62 | 63 | 64 | @Override 65 | public Map register(User user) { 66 | /** 67 | * 1.用户输入[username]和[password] 68 | 2.系统为用户生成[Salt值] 69 | 3.系统将[Salt值]和[password]拼接在一起 70 | 4.对拼接后的值进行散列,得到[Hash1] 71 | 5.将[Hash1]和[Salt值]放在数据库中。 72 | */ 73 | Map map = new HashMap(); 74 | try { 75 | String millis = String.valueOf(System.currentTimeMillis()); 76 | String salt = DigestUtils.md5DigestAsHex(millis.getBytes()); 77 | String md5Pwd = DigestUtils.md5DigestAsHex(user.getPassword().getBytes()); 78 | String hash = md5Pwd + salt; 79 | String md5DigestAsHex = DigestUtils.md5DigestAsHex(hash.getBytes()); 80 | //插入用户账户信息 81 | user.setPassword(md5DigestAsHex); 82 | user.setSalt(salt); 83 | user.setRegistertime(new Date()); 84 | user.setLastTime(new Date()); 85 | Integer num = userMapper.insertUser(user); 86 | 87 | //插入用户个人信息 88 | UserInfo userInfo = new UserInfo(); 89 | userInfo.setUserId(user.getId()); 90 | userInfo.setUsername(user.getUsername()); 91 | userInfoMapper.firstSaveUserInfo(userInfo); 92 | 93 | map.put("code", "1"); 94 | } catch (Exception e) { 95 | e.printStackTrace(); 96 | map.put("code", "0"); 97 | } 98 | 99 | 100 | return map; 101 | } 102 | 103 | @Override 104 | public Map login(User user) { 105 | /** 106 | * 1.用户输入[username]和[password] 107 | 2.系统通过用户名找到与之对应的[Hash1]和[Salt值] 108 | 3.系统将[Salt值]和[用户输入的密码]拼接在一起 109 | 4.对拼接后的值进行散列,得到[Hash2] 110 | 5.对比[Hash1]和[Hash2]是否相等,相等则授权登录 111 | */ 112 | Map map = new HashMap(); 113 | try { 114 | String md5Pwd = DigestUtils.md5DigestAsHex(user.getPassword().getBytes()); 115 | User u = userMapper.getUserByName(user.getUsername()); 116 | String hash = md5Pwd + u.getSalt(); 117 | String md5DigestAsHex = DigestUtils.md5DigestAsHex(hash.getBytes()); 118 | if(u.getPassword().equals(md5DigestAsHex)) { 119 | map.put("flag", true); 120 | map.put("userInfo", userInfoMapper.getUserInfoByUserId(u.getId())); 121 | 122 | }else { 123 | map.put("flag", false); 124 | map.put("msg", "用户名或密码错误!"); 125 | } 126 | } catch (Exception e) { 127 | e.printStackTrace(); 128 | map.put("flag", false); 129 | map.put("msg", "系统异常!"); 130 | } 131 | 132 | return map; 133 | } 134 | 135 | @Override 136 | public User getNameById(User user) { 137 | User nameById = userMapper.getNameById(user); 138 | amqpTemplate.convertAndSend("exchange", "topic.message", JSONObject.toJSONString(nameById)); 139 | return nameById; 140 | } 141 | 142 | 143 | /**************以下为个人信息相关操作*****************/ 144 | @Override 145 | public int firstSaveUserInfo(UserInfo userInfo) { 146 | 147 | return userInfoMapper.firstSaveUserInfo(userInfo); 148 | } 149 | 150 | @Override 151 | public UserInfo getUserInfoByUserId(Integer userId) { 152 | return userInfoMapper.getUserInfoByUserId(userId); 153 | } 154 | 155 | @Override 156 | public int updateUserInfo(UserInfo userInfo) { 157 | return userInfoMapper.updateUserInfo(userInfo); 158 | } 159 | 160 | @Override 161 | public List findByName(UserInfo userinfo) { 162 | return userInfoMapper.findByName(userinfo); 163 | } 164 | 165 | @Override 166 | public User getUser(Integer id) { 167 | // TODO Auto-generated method stub 168 | return null; 169 | } 170 | 171 | @Override 172 | public void update(User user) { 173 | // TODO Auto-generated method stub 174 | 175 | } 176 | 177 | @Override 178 | public void insertAll(List users) { 179 | // TODO Auto-generated method stub 180 | 181 | } 182 | 183 | @Override 184 | public void remove(Integer id) { 185 | // TODO Auto-generated method stub 186 | 187 | } 188 | 189 | @Override 190 | public List findByPage(User user, Pageable pageable) { 191 | // TODO Auto-generated method stub 192 | return null; 193 | } 194 | 195 | @Override 196 | public int inserTest(Map map) { 197 | 198 | return userMapper.insertTest(map); 199 | } 200 | 201 | 202 | 203 | } 204 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/utils/SpringUtils.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.utils; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class SpringUtils implements ApplicationContextAware { 10 | 11 | private static ApplicationContext applicationContext; 12 | 13 | @Override 14 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 15 | if(SpringUtils.applicationContext == null) { 16 | SpringUtils.applicationContext = applicationContext; 17 | } 18 | } 19 | 20 | //获取applicationContext 21 | public static ApplicationContext getApplicationContext() { 22 | return applicationContext; 23 | } 24 | 25 | //通过name获取 Bean. 26 | public static Object getBean(String name){ 27 | return getApplicationContext().getBean(name); 28 | } 29 | 30 | //通过class获取Bean. 31 | public static T getBean(Class clazz){ 32 | return getApplicationContext().getBean(clazz); 33 | } 34 | 35 | //通过name,以及Clazz返回指定的Bean 36 | public static T getBean(String name,Class clazz){ 37 | return getApplicationContext().getBean(name, clazz); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/utils/WebResult.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme.utils; 2 | 3 | import java.io.Serializable; 4 | 5 | 6 | /** 7 | * @ClassName: WebResult 8 | * @version 1.0 9 | * @Desc: WEB返回JSON结果 10 | * @author xiaojun.zhou 11 | * @date 2015年5月26日上午10:23:01 12 | * @history v1.0 13 | */ 14 | public class WebResult implements Serializable 15 | { 16 | private static final long serialVersionUID = -4776437900752507269L; 17 | 18 | /** 19 | * 后台请求成功 20 | */ 21 | public static final String BACK_SUCCESS = "1"; 22 | 23 | /** 24 | * 后台请求失败 25 | */ 26 | public static final String BACK_FAIL = "0"; 27 | 28 | /** 29 | * 后台请求成功 30 | */ 31 | public static final int SUCCESS = 1; 32 | 33 | /** 34 | * 后台请求失败 35 | */ 36 | public static final int FAIL = 0; 37 | /** 38 | * 返回消息 39 | */ 40 | private String msg; 41 | 42 | /** 43 | * 返回码 44 | */ 45 | private String code; 46 | 47 | /** 48 | * 返回数据 49 | */ 50 | private Object data; 51 | 52 | public WebResult() 53 | { 54 | } 55 | 56 | public WebResult(String msg, String code) 57 | { 58 | super(); 59 | this.msg = msg; 60 | this.code = code; 61 | } 62 | 63 | public WebResult(String msg, String code, Object data) 64 | { 65 | super(); 66 | this.msg = msg; 67 | this.code = code; 68 | this.data = data; 69 | } 70 | 71 | public String getMsg() 72 | { 73 | return msg; 74 | } 75 | 76 | public void setMsg(String msg) 77 | { 78 | this.msg = msg; 79 | } 80 | 81 | public String getCode() 82 | { 83 | return code; 84 | } 85 | 86 | public void setCode(String code) 87 | { 88 | this.code = code; 89 | } 90 | 91 | public Object getData() 92 | { 93 | return data; 94 | } 95 | 96 | public void setData(Object data) 97 | { 98 | this.data = data; 99 | } 100 | 101 | @Override 102 | public String toString() 103 | { 104 | return "WebResult [msg=" + msg + ", code=" + code + ", data=" + data + "]"; 105 | } 106 | 107 | /** 108 | * 初始失败方法 109 | * 110 | * @author cc HSSD0473 111 | * @see [类、类#方法、类#成员] 112 | */ 113 | public void invokeFail(){ 114 | this.data = null; 115 | this.code = BACK_FAIL; 116 | this.msg = "操作失败"; 117 | } 118 | 119 | public void invokeFail(String msg){ 120 | this.data = null; 121 | this.code = BACK_FAIL; 122 | if(msg != null && !msg.equals("")) 123 | { 124 | this.msg = msg; 125 | } 126 | } 127 | 128 | public void invokeSuccess() 129 | { 130 | this.code = BACK_SUCCESS; 131 | this.msg = "操作成功"; 132 | } 133 | 134 | public void invokeSuccess(String msg) 135 | { 136 | if(msg != null && !msg.equals("")) 137 | { 138 | this.msg = msg; 139 | } 140 | this.code = BACK_SUCCESS; 141 | } 142 | 143 | /** 144 | * 组装成功方法 145 | * 146 | * @author cc HSSD0473 147 | * @param msg 148 | * @param data 149 | * @see [类、类#方法、类#成员] 150 | */ 151 | public void invokeSuccess(String msg, Object data){ 152 | if(msg != null && !msg.equals("")) 153 | { 154 | this.msg = msg; 155 | } 156 | if(data != null) 157 | { 158 | this.data = data; 159 | } 160 | this.code = BACK_SUCCESS; 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /charBack/src/main/java/com/yzeng/charme/utils/WebUtils.java: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright (C) 2015 ShenZhen HeShiDai Technology Co.,Ltd 3 | * All Rights Reserved. 4 | * 本软件为合时代控股有限公司开发研制。未经本公司正式书面同意,其他任何个人、团体 5 | * 不得使用、复制、修改或发布本软件. 6 | *****************************************************************************/ 7 | package com.yzeng.charme.utils; 8 | 9 | import java.net.InetAddress; 10 | import java.net.NetworkInterface; 11 | import java.util.Enumeration; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | import javax.servlet.http.HttpSession; 18 | 19 | import org.springframework.web.context.request.RequestContextHolder; 20 | import org.springframework.web.context.request.ServletRequestAttributes; 21 | 22 | /** 23 | * @ClassName: WebUtils 24 | * @version 1.0 25 | * @Desc: WebUtils 26 | * @author xiaojun.zhou 27 | * @date 2015年6月25日下午1:49:28 28 | * @history v1.0 29 | */ 30 | public class WebUtils 31 | { 32 | /** 33 | * 描述:获取request对象 34 | * @author xiaojun.zhou 35 | * @date 2015年6月25日下午1:56:05 36 | * @return 37 | */ 38 | public static HttpServletRequest getRequest() 39 | { 40 | return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 41 | } 42 | 43 | /** 44 | * 描述:获取responce对象 45 | * @author xiaojun.zhou 46 | * @date 2015年6月25日下午1:56:15 47 | * @return 48 | */ 49 | public static HttpServletResponse getResponse() 50 | { 51 | return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); 52 | 53 | } 54 | 55 | /** 56 | * 描述:获取session 57 | * @author xiaojun.zhou 58 | * @date 2015年6月25日下午1:57:17 59 | * @return 60 | */ 61 | public static HttpSession getSession() 62 | { 63 | return getRequest().getSession(); 64 | } 65 | 66 | /** 67 | * 描述:设置session值 68 | * @author xiaojun.zhou 69 | * @date 2015年6月25日下午2:01:22 70 | * @param key 71 | * @param val 72 | */ 73 | public static void setSessionValue(String key, T val) 74 | { 75 | getSession().setAttribute(key, val); 76 | } 77 | 78 | /** 79 | * 描述:获取session值 80 | * @author xiaojun.zhou 81 | * @date 2015年6月25日下午2:01:38 82 | * @param key 83 | * @return 84 | */ 85 | @SuppressWarnings("unchecked") 86 | public static T getSessionValue(String key) 87 | { 88 | return (T) getSession().getAttribute(key); 89 | } 90 | 91 | /** 92 | * 描述:移除session 93 | * @date 2015年7月30日上午9:08:19 94 | * @param key 95 | * @return 96 | */ 97 | @SuppressWarnings("unchecked") 98 | public static T removeSessionValue(String key) 99 | { 100 | Object obj = getSession().getAttribute(key); 101 | getSession().removeAttribute(key); 102 | return (T) obj; 103 | } 104 | 105 | /** 106 | * 描述:获取客户端ip 107 | * @date 2015年6月25日下午5:12:55 108 | * @param request 109 | * @return 110 | */ 111 | public static String getRemoteIP(HttpServletRequest request) 112 | { 113 | String ip = request.getHeader("x-forwarded-for"); 114 | 115 | 116 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) 117 | { 118 | ip = request.getHeader("Proxy-Client-IP"); 119 | } 120 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) 121 | { 122 | ip = request.getHeader("WL-Proxy-Client-IP"); 123 | } 124 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) 125 | { 126 | ip = request.getRemoteAddr(); 127 | } 128 | return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip; 129 | } 130 | 131 | /** 132 | * 描述:获取客户端ip 133 | * @author xiaojun.zhou 134 | * @date 2015年7月28日下午3:27:13 135 | * @return 136 | */ 137 | public static String getRemoteIP() 138 | { 139 | HttpServletRequest request = getRequest(); 140 | return getRemoteIP(request); 141 | } 142 | 143 | /** 144 | * 获取请求的参数列MAP 145 | * 146 | * @author cc HSSD0473 147 | * @return 148 | * @see [类、类#方法、类#成员] 149 | */ 150 | public static Map getRequestPar(){ 151 | Map map = new HashMap<>(); 152 | 153 | Enumeration enu = getRequest().getParameterNames(); 154 | while (enu.hasMoreElements()) 155 | { 156 | String paraName = (String) enu.nextElement(); 157 | map.put(paraName, getRequest().getParameter(paraName)); 158 | } 159 | 160 | return map; 161 | } 162 | 163 | /** 164 | * 获取服务器IP地址 165 | */ 166 | public final static String LOCAL_IP; 167 | static 168 | { 169 | String sIP = ""; 170 | InetAddress ip = null; 171 | try 172 | { 173 | boolean bFindIP = false; 174 | Enumeration netInterfaces = (Enumeration) NetworkInterface 175 | .getNetworkInterfaces(); 176 | while (netInterfaces.hasMoreElements()) 177 | { 178 | if (bFindIP) 179 | { 180 | break; 181 | } 182 | NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement(); 183 | Enumeration ips =ni.getInetAddresses(); 184 | while (ips.hasMoreElements()) 185 | { 186 | ip = (InetAddress) ips.nextElement(); 187 | if (!ip.isLoopbackAddress() && ip.getHostAddress().matches("(\\d{1,3}\\.){3}\\d{1,3}")) 188 | { 189 | bFindIP = true; 190 | break; 191 | } 192 | } 193 | } 194 | } 195 | catch (Exception e) 196 | { 197 | 198 | } 199 | if (null != ip) 200 | { 201 | sIP = ip.getHostAddress(); 202 | } 203 | LOCAL_IP = sIP; 204 | 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /charBack/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | servlet: 3 | context-path: /dev -------------------------------------------------------------------------------- /charBack/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: charMe 4 | thymeleaf: 5 | prefix: classpath:/templates/ 6 | suffix: .html 7 | data: 8 | mongodb: 9 | uri: mongodb://139.199.86.201:27017/charself 10 | jpa: 11 | generate-ddl: true 12 | show-sql: true 13 | datasource: 14 | driver-class-name: com.mysql.jdbc.Driver 15 | url: jdbc:mysql://139.199.86.201:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true 16 | username: root 17 | password: ENC(Z0W0OKw1+Dfi5KY8Q5lqvA==) 18 | type: com.alibaba.druid.pool.DruidDataSource 19 | 20 | 21 | rabbitmq: 22 | host: 139.199.86.201 23 | port: 5672 24 | username: admin 25 | password: ENC(f+qnmR9RF8W2wsJqzIJUPMj4KpJ4eIco) 26 | 27 | jasypt: 28 | encryptor: 29 | password: saltnewfor 30 | 31 | mybatis: 32 | mapper-locations: classpath:mapper/*.xml 33 | type-aliases-package: com.yzeng.charme.entity 34 | 35 | pagehelper: 36 | helper-dialect: mysql 37 | reasonable: true 38 | support-methods-arguments: true 39 | params: count=countSql -------------------------------------------------------------------------------- /charBack/src/main/resources/mapper/FriendMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | insert into t_relation(userIdA,userIdB,relationTime) 8 | values(#{userIdA,jdbcType=INTEGER}, 9 | #{userIdB,jdbcType=INTEGER}, 10 | #{relationTime,jdbcType=TIMESTAMP} 11 | ) 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /charBack/src/main/resources/mapper/GroupMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | insert into t_group(createUserId,groupName,groupDescribes,createTime) 9 | values(#{createUserId,jdbcType=INTEGER}, 10 | #{groupName,jdbcType=VARCHAR}, 11 | #{groupDescribes,jdbcType=VARCHAR}, 12 | #{createTime,jdbcType=TIMESTAMP} 13 | ) 14 | 15 | 16 | 17 | INSERT INTO group_user VALUES(#{groupId},#{userId},SYSDATE()) 18 | 19 | 20 | 23 | 24 | 29 | 30 | 35 | 36 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 61 | 62 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /charBack/src/main/resources/mapper/MessageMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | insert into t_message(msgType,fromUserId,toUserId,content,sendMsgTime,isOffline) 13 | values(#{msgType,jdbcType=INTEGER}, 14 | #{fromUserId,jdbcType=INTEGER}, 15 | #{toUserId,jdbcType=INTEGER}, 16 | #{content,jdbcType=VARCHAR}, 17 | #{sendMsgTime,jdbcType=TIMESTAMP}, 18 | #{isOffline,jdbcType=CHAR} 19 | ) 20 | 21 | 22 | 28 | 29 | 36 | 37 | 40 | 41 | 42 | 45 | 46 | 47 | update t_message t 48 | 49 | 50 | t.isOffline = #{isOffline}, 51 | 52 | 53 | t.isTransport = #{isTransport}, 54 | 55 | 56 | where 1 = 1 57 | 58 | and t.id = #{id} 59 | 60 | 61 | and t.fromUserId = #{fromUserId} 62 | 63 | 64 | and t.toUserId = #{toUserId} 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /charBack/src/main/resources/mapper/UserInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | insert into t_userInfo(userId,username) 13 | values(#{userId,jdbcType=INTEGER},#{username,jdbcType=VARCHAR}) 14 | 15 | 16 | 17 | update t_userInfo t 18 | 19 | 20 | t.nickname = #{nickname}, 21 | 22 | 23 | t.sex = #{sex}, 24 | 25 | 26 | t.age = #{age}, 27 | 28 | 29 | t.birthTime = #{birthTime}, 30 | 31 | 32 | t.signature = #{signature}, 33 | 34 | 35 | t.avatarId = #{avatarId}, 36 | 37 | 38 | t.isOnline = #{isOnline}, 39 | 40 | 41 | where t.userId = #{userId} 42 | 43 | 44 | 47 | 48 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /charBack/src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 14 | 15 | 16 | insert into t_user(username,password,salt,registertime,lastTime) 17 | values(#{username,jdbcType=VARCHAR}, 18 | #{password,jdbcType=VARCHAR}, 19 | #{salt,jdbcType=VARCHAR}, 20 | #{registertime,jdbcType=TIMESTAMP}, 21 | #{lastTime,jdbcType=TIMESTAMP} 22 | ) 23 | 24 | 25 | 26 | INSERT INTO tbl(description) VALUES('MySQL last_insert_id'); 27 | 28 | SELECT LAST_INSERT_ID() 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /charBack/src/main/resources/static/css/login.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: absolute; 3 | top:0; 4 | left: 0; 5 | width: 100%; 6 | height: 100%; 7 | overflow: hidden; 8 | animation-delay: 0.5s; 9 | } 10 | 11 | .wrapper.form-success .container h1 { 12 | -webkit-transform: translateY(85px); 13 | -ms-transform: translateY(85px); 14 | transform: translateY(85px); 15 | } 16 | .container { 17 | max-width: 600px; 18 | margin: 0 auto; 19 | margin-top: 7%; 20 | padding: 80px 0; 21 | height: 400px; 22 | text-align: center; 23 | } 24 | .container h1 { 25 | font-size: 40px; 26 | -webkit-transition-duration: 1s; 27 | transition-duration: 1s; 28 | -webkit-transition-timing-function: ease-in-put; 29 | transition-timing-function: ease-in-put; 30 | font-weight: 200; 31 | } 32 | .form { 33 | padding: 20px 0; 34 | position: relative; 35 | z-index: 2; 36 | } 37 | .form { 38 | font-family:"Microsoft YaHei"; 39 | color: white; 40 | font-weight: 300; 41 | } 42 | .form ::-webkit-input-placeholder { 43 | /* WebKit browsers */ 44 | font-family:"Microsoft YaHei"; 45 | color: white; 46 | font-weight: 300; 47 | } 48 | .form :-moz-placeholder { 49 | /* Mozilla Firefox 4 to 18 */ 50 | font-family:"Microsoft YaHei"; 51 | color: white; 52 | opacity: 1; 53 | font-weight: 300; 54 | } 55 | .form ::-moz-placeholder { 56 | /* Mozilla Firefox 19+ */ 57 | font-family:"Microsoft YaHei"; 58 | color: white; 59 | opacity: 1; 60 | font-weight: 300; 61 | } 62 | .form :-ms-input-placeholder { 63 | /* Internet Explorer 10+ */ 64 | font-family:"Microsoft YaHei"; 65 | color: white; 66 | font-weight: 300; 67 | } 68 | .form input { 69 | -webkit-appearance: none; 70 | -moz-appearance: none; 71 | appearance: none; 72 | outline: 0; 73 | border: 1px solid rgba(255, 255, 255, 0.4); 74 | background-color: rgba(255, 255, 255, 0.2); 75 | width: 250px; 76 | border-radius: 3px; 77 | padding: 10px 15px; 78 | margin: 0 auto 10px auto; 79 | display: block; 80 | text-align: center; 81 | font-family: "Microsoft YaHei"; 82 | font-size: 18px; 83 | color: white; 84 | -webkit-transition-duration: 0.35s; 85 | transition-duration: 0.35s; 86 | font-weight: 300; 87 | } 88 | .form input:hover { 89 | background-color: rgba(255, 255, 255, 0.4); 90 | } 91 | .form input:focus { 92 | background-color: white; 93 | width: 300px; 94 | color: #aaaaaa; 95 | } 96 | .form button { 97 | -webkit-appearance: none; 98 | -moz-appearance: none; 99 | appearance: none; 100 | outline: 0; 101 | background-color: #f5f7f9; 102 | font-family: Microsoft YaHei; 103 | border: 0; 104 | padding: 10px 15px; 105 | color: #000; 106 | border-radius: 3px; 107 | width: 250px; 108 | cursor: pointer; 109 | font-size: 18px; 110 | -webkit-transition-duration: 0.25s; 111 | transition-duration: 0.25s; 112 | } 113 | .form button:hover { 114 | background-color: #f5f7f9; 115 | } 116 | 117 | .s-logo { 118 | padding-bottom : 25px; 119 | } 120 | 121 | .jump { 122 | font-family: Microsoft YaHei; 123 | font-size: 20px; 124 | color: #fff; 125 | position: absolute; 126 | top:5%; 127 | right: 5%; 128 | animation-delay: 1s; 129 | z-index: 100; 130 | } 131 | 132 | a.jumpLink { 133 | text-decoration: none; 134 | color: #fff; 135 | } 136 | 137 | a.jumpLink { 138 | text-decoration: none; 139 | color: #fff; 140 | } 141 | 142 | a.jumpLink { 143 | text-decoration: none; 144 | color: #fff; 145 | } 146 | 147 | .offsetUps { 148 | margin-top: 6%; 149 | } 150 | 151 | .offsetUp { 152 | margin-top : 5%; 153 | } -------------------------------------------------------------------------------- /charBack/src/main/resources/static/css/main-style.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/css/main-style.css -------------------------------------------------------------------------------- /charBack/src/main/resources/static/css/style.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | background: #000 url('../img/bg.jpg') no-repeat center center fixed; 4 | -webkit-background-size: cover; 5 | -moz-background-size: cover; 6 | -o-background-size: cover; 7 | background-size: cover; 8 | /*color:#fff;*/ 9 | overflow-x: hidden; 10 | overflow-y: hidden; 11 | min-width: 400px; 12 | font-family: Microsoft YaHei; 13 | } 14 | 15 | 16 | .downLoad1, .downLoad2 { 17 | font-family: Microsoft YaHei; 18 | font-size: 20px; 19 | color: #fff; 20 | position: absolute; 21 | top:5%; 22 | animation-delay: 5s; 23 | } 24 | 25 | .downLoad1 { 26 | left: 5%; 27 | } 28 | 29 | .downLoad2 { 30 | right: 5%; 31 | } 32 | 33 | a.pcLink , a.appLink { 34 | text-decoration: none; 35 | color: #fff; 36 | } 37 | 38 | a.pcLink:hover ,a.appLink:hover { 39 | text-decoration: none; 40 | color: #fff; 41 | } 42 | 43 | a.pcLink:visited ,a.appLink:visited { 44 | text-decoration: none; 45 | color: #fff; 46 | } 47 | 48 | .vertical { 49 | width: 100%; 50 | height:auto; 51 | position: absolute; 52 | top: 50%; 53 | transform: translateY(-50%); 54 | -webkit-transform: translateY(-50%); 55 | -moz-transform: translateY(-50%); 56 | -ms-transform: translateY(-50%); 57 | -o-transform: translateY(-50%); 58 | } 59 | 60 | .box1 { 61 | position: relative; 62 | width: 100%; 63 | height: 410px; 64 | } 65 | 66 | .horizontal { 67 | width: auto; 68 | height:auto; 69 | position: absolute; 70 | left: 50%; 71 | transform: translateX(-50%); 72 | -webkit-transform: translateX(-50%); 73 | -moz-transform: translateX(-50%); 74 | -ms-transform: translateX(-50%); 75 | -o-transform: translateX(-50%); 76 | z-index:auto; 77 | } 78 | 79 | .box2 { 80 | position: relative; 81 | width: 400px; 82 | height: 410px; 83 | } 84 | 85 | .part1 { 86 | width: 100%; 87 | height: auto; 88 | position: absolute; 89 | left: 0; 90 | top: 0; 91 | z-index: 100; 92 | animation-delay:2.5s; 93 | } 94 | .part2 { 95 | width: 100%; 96 | height: auto; 97 | position: absolute; 98 | left: 0; 99 | top: 0; 100 | z-index: auto; 101 | animation-delay:0.5s; 102 | } 103 | .part3 { 104 | width: 100%; 105 | height: auto; 106 | position: absolute; 107 | left: 0; 108 | top: 0; 109 | z-index: auto; 110 | animation-delay:1.5s; 111 | } 112 | 113 | .button-style1 ,.button-style2{ 114 | position:absolute; 115 | bottom: 0; 116 | opacity:1; 117 | z-index:100; 118 | animation-delay: 4s; 119 | } 120 | .button-style1 { 121 | position:absolute; 122 | left: 0 ; 123 | } 124 | .button-style2 { 125 | position:absolute; 126 | right: 0; 127 | } 128 | 129 | .lk1,.lk2 { 130 | text-decoration:none; 131 | font-family: Microsoft YaHei; 132 | color:#fff; 133 | transition:all 0.5s; 134 | } 135 | .link1,.link2 { 136 | width:100px; 137 | height:40px; 138 | border:1px solid #fff; 139 | -webkit-border:1px solid #fff; 140 | border-radius:30px; 141 | font-size: 18px; 142 | text-align:center; 143 | /*background: #000;*/ 144 | /*background-color:rgba(255,255,255,0,1); */ 145 | transition:all 0.8s; 146 | } 147 | .bt1,.bt2 { 148 | position:relative; 149 | top:18%; 150 | vertical-align:middle; 151 | } 152 | 153 | a.lk1:hover,a.lk2:hover{ 154 | color:#000; 155 | transition:all 0.5s; 156 | text-decoration:none; 157 | } 158 | a.lk1:visited ,a.lk2:visited { 159 | text-decoration: none; 160 | } 161 | 162 | .link1:hover,.link2:hover { 163 | background-color:#fff; 164 | /*background-color:rgba(255,255,255,0,2); */ 165 | border:1px solid #bbb; 166 | transition:all 0.8s; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/bg.jpg -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/face.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/hhh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/hhh.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/icon.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/img.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/logo-white.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/logo.ico -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/logo_blue.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/logo_blue.ico -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/part1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/part1.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/part2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/part2.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/part3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/part3.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/photo.jpg -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/photoss.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/photoss.jpg -------------------------------------------------------------------------------- /charBack/src/main/resources/static/img/s-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/img/s-logo.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/mobile/layer.js: -------------------------------------------------------------------------------- 1 | /*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */ 2 | ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

'+(e?n.title[0]:n.title)+"

":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
'+e+"
"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

'+(n.content||"")+"

"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
':"")+'
"+l+'
'+n.content+"
"+c+"
",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;odiv{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/skin/default/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/js/skin/default/icon-ext.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/skin/default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/js/skin/default/icon.png -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/skin/default/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/js/skin/default/loading-0.gif -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/skin/default/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/js/skin/default/loading-1.gif -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/skin/default/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/js/skin/default/loading-2.gif -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/skin/family/style.css: -------------------------------------------------------------------------------- 1 | body .layer-ext-family { 2 | font-family: Microsoft YaHei; 3 | } -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/skin/lists/style.css: -------------------------------------------------------------------------------- 1 | body .layer-ext-lists .layui-layer-title{ 2 | font-family: Microsoft YaHei; 3 | font-size: 24px; 4 | height: 80px; 5 | } 6 | -------------------------------------------------------------------------------- /charBack/src/main/resources/static/js/websocket-client.js: -------------------------------------------------------------------------------- 1 | //websocket客户端 2 | var websocket = null; 3 | var ws = null; 4 | ws = "ws://localhost:8080/WithMe/server"; 5 | //判断当前浏览器是否支持WebSocket 6 | if ('WebSocket' in window) { 7 | websocket = new WebSocket(ws); 8 | alert(ws); 9 | } 10 | else { 11 | alert('当前浏览器 Not support websocket'); 12 | }; 13 | 14 | //连接发生错误的回调方法 15 | websocket.onerror = function () { 16 | setMessageInnerHTML("WebSocket连接发生错误"); 17 | }; 18 | 19 | //连接成功建立的回调方法 20 | websocket.onopen = function () { 21 | setMessageInnerHTML("WebSocket连接成功"); 22 | }; 23 | 24 | //接收到消息的回调方法 25 | websocket.onmessage = function (event) { 26 | setMessageInnerHTML(event.data); 27 | }; 28 | 29 | //连接关闭的回调方法 30 | websocket.onclose = function () { 31 | setMessageInnerHTML("WebSocket连接关闭"); 32 | }; 33 | 34 | //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 35 | window.onbeforeunload = function () { 36 | closeWebSocket(); 37 | }; 38 | 39 | //将消息显示在网页上 40 | function setMessageInnerHTML(innerHTML) { 41 | document.getElementById('message').innerHTML += innerHTML + '
'; 42 | } 43 | 44 | //关闭WebSocket连接 45 | function closeWebSocket() { 46 | websocket.close(); 47 | } 48 | 49 | //发送消息 50 | function send() { 51 | var message = document.getElementById('text').value; 52 | websocket.send(message); 53 | } -------------------------------------------------------------------------------- /charBack/src/main/resources/static/static/fonts/ionicons.99ac330.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/static/fonts/ionicons.99ac330.woff -------------------------------------------------------------------------------- /charBack/src/main/resources/static/static/fonts/ionicons.d535a25.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charBack/src/main/resources/static/static/fonts/ionicons.d535a25.ttf -------------------------------------------------------------------------------- /charBack/src/main/resources/static/static/js/manifest.2ae2e69a05c33dfc65f8.js: -------------------------------------------------------------------------------- 1 | !function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];acharselfvue
-------------------------------------------------------------------------------- /charBack/src/test/java/com/yzeng/charme/CharMeApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class CharMeApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /charBack/src/test/java/com/yzeng/charme/DBEncryption.java: -------------------------------------------------------------------------------- 1 | package com.yzeng.charme; 2 | 3 | import org.jasypt.encryption.StringEncryptor; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | import org.springframework.test.context.web.WebAppConfiguration; 10 | 11 | import junit.framework.Assert; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | @WebAppConfiguration 16 | public class DBEncryption { 17 | 18 | @Autowired 19 | StringEncryptor encryptor; 20 | 21 | @Test 22 | public void getPassword() { 23 | String name = encryptor.encrypt("root"); 24 | String pwd = encryptor.encrypt("root"); 25 | System.out.println(name); 26 | System.out.println(pwd); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /charFront/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /charFront/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /charFront/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /charFront/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /charFront/README.md: -------------------------------------------------------------------------------- 1 | # charFront 2 | 3 | > charFront 4 | 5 | 前端页面 6 | vue脚手架搭建 7 | 8 | 模块: 9 | iview 框架-地址:https://www.iviewui.com/docs/guide/install 10 | 11 | 12 | ## Build Setup 13 | 14 | ``` bash 15 | # install dependencies 16 | npm install 17 | 18 | # serve with hot reload at localhost:8080 19 | npm run dev 20 | 21 | # build for production with minification 22 | npm run build 23 | 24 | # build for production and view the bundle analyzer report 25 | npm run build --report 26 | ``` 27 | 28 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 29 | -------------------------------------------------------------------------------- /charFront/build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /charFront/build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /charFront/build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charFront/build/logo.png -------------------------------------------------------------------------------- /charFront/build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function (options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders (loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader' 51 | }) 52 | } else { 53 | return ['vue-style-loader'].concat(loaders) 54 | } 55 | } 56 | 57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 58 | return { 59 | css: generateLoaders(), 60 | postcss: generateLoaders(), 61 | less: generateLoaders('less'), 62 | sass: generateLoaders('sass', { indentedSyntax: true }), 63 | scss: generateLoaders('sass'), 64 | stylus: generateLoaders('stylus'), 65 | styl: generateLoaders('stylus') 66 | } 67 | } 68 | 69 | // Generate loaders for standalone style files (outside of .vue) 70 | exports.styleLoaders = function (options) { 71 | const output = [] 72 | const loaders = exports.cssLoaders(options) 73 | 74 | for (const extension in loaders) { 75 | const loader = loaders[extension] 76 | output.push({ 77 | test: new RegExp('\\.' + extension + '$'), 78 | use: loader 79 | }) 80 | } 81 | 82 | return output 83 | } 84 | 85 | exports.createNotifierCallback = () => { 86 | const notifier = require('node-notifier') 87 | 88 | return (severity, errors) => { 89 | if (severity !== 'error') return 90 | 91 | const error = errors[0] 92 | const filename = error.file && error.file.split('!').pop() 93 | 94 | notifier.notify({ 95 | title: packageConfig.name, 96 | message: severity + ': ' + error.name, 97 | subtitle: filename || '', 98 | icon: path.join(__dirname, 'logo.png') 99 | }) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /charFront/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /charFront/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | 12 | 13 | module.exports = { 14 | context: path.resolve(__dirname, '../'), 15 | entry: { 16 | app: './src/main.js' 17 | }, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: '[name].js', 21 | publicPath: process.env.NODE_ENV === 'production' 22 | ? config.build.assetsPublicPath 23 | : config.dev.assetsPublicPath 24 | }, 25 | resolve: { 26 | extensions: ['.js', '.vue', '.json'], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.esm.js', 29 | '@': resolve('src'), 30 | } 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.vue$/, 36 | loader: 'vue-loader', 37 | options: vueLoaderConfig 38 | }, 39 | { 40 | test: /\.js$/, 41 | loader: 'babel-loader', 42 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 43 | }, 44 | { 45 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 46 | loader: 'url-loader', 47 | options: { 48 | limit: 10000, 49 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 50 | } 51 | }, 52 | { 53 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 54 | loader: 'url-loader', 55 | options: { 56 | limit: 10000, 57 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 58 | } 59 | }, 60 | { 61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 62 | loader: 'url-loader', 63 | options: { 64 | limit: 10000, 65 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 66 | } 67 | } 68 | ] 69 | }, 70 | node: { 71 | // prevent webpack from injecting useless setImmediate polyfill because Vue 72 | // source contains it (although only uses it if it's native). 73 | setImmediate: false, 74 | // prevent webpack from injecting mocks to Node native modules 75 | // that does not make sense for the client 76 | dgram: 'empty', 77 | fs: 'empty', 78 | net: 'empty', 79 | tls: 'empty', 80 | child_process: 'empty' 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /charFront/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const path = require('path') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 11 | const portfinder = require('portfinder') 12 | 13 | const HOST = process.env.HOST 14 | const PORT = process.env.PORT && Number(process.env.PORT) 15 | 16 | const devWebpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 19 | }, 20 | // cheap-module-eval-source-map is faster for development 21 | devtool: config.dev.devtool, 22 | 23 | // these devServer options should be customized in /config/index.js 24 | devServer: { 25 | clientLogLevel: 'warning', 26 | historyApiFallback: { 27 | rewrites: [ 28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, 29 | ], 30 | }, 31 | hot: true, 32 | contentBase: false, // since we use CopyWebpackPlugin. 33 | compress: true, 34 | host: HOST || config.dev.host, 35 | port: PORT || config.dev.port, 36 | open: config.dev.autoOpenBrowser, 37 | overlay: config.dev.errorOverlay 38 | ? { warnings: false, errors: true } 39 | : false, 40 | publicPath: config.dev.assetsPublicPath, 41 | proxy: config.dev.proxyTable, 42 | quiet: true, // necessary for FriendlyErrorsPlugin 43 | watchOptions: { 44 | poll: config.dev.poll, 45 | } 46 | }, 47 | plugins: [ 48 | new webpack.DefinePlugin({ 49 | 'process.env': require('../config/dev.env') 50 | }), 51 | new webpack.HotModuleReplacementPlugin(), 52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 53 | new webpack.NoEmitOnErrorsPlugin(), 54 | // https://github.com/ampedandwired/html-webpack-plugin 55 | new HtmlWebpackPlugin({ 56 | filename: 'index.html', 57 | template: 'index.html', 58 | inject: true 59 | }), 60 | // copy custom static assets 61 | new CopyWebpackPlugin([ 62 | { 63 | from: path.resolve(__dirname, '../static'), 64 | to: config.dev.assetsSubDirectory, 65 | ignore: ['.*'] 66 | } 67 | ]) 68 | ] 69 | }) 70 | 71 | module.exports = new Promise((resolve, reject) => { 72 | portfinder.basePort = process.env.PORT || config.dev.port 73 | portfinder.getPort((err, port) => { 74 | if (err) { 75 | reject(err) 76 | } else { 77 | // publish the new Port, necessary for e2e tests 78 | process.env.PORT = port 79 | // add port to devServer config 80 | devWebpackConfig.devServer.port = port 81 | 82 | // Add FriendlyErrorsPlugin 83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 84 | compilationSuccessInfo: { 85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 86 | }, 87 | onErrors: config.dev.notifyOnErrors 88 | ? utils.createNotifierCallback() 89 | : undefined 90 | })) 91 | 92 | resolve(devWebpackConfig) 93 | } 94 | }) 95 | }) 96 | -------------------------------------------------------------------------------- /charFront/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | 14 | const env = require('../config/prod.env') 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | usePostCSS: true 22 | }) 23 | }, 24 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 29 | }, 30 | plugins: [ 31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 32 | new webpack.DefinePlugin({ 33 | 'process.env': env 34 | }), 35 | new UglifyJsPlugin({ 36 | uglifyOptions: { 37 | compress: { 38 | warnings: false 39 | } 40 | }, 41 | sourceMap: config.build.productionSourceMap, 42 | parallel: true 43 | }), 44 | // extract css into its own file 45 | new ExtractTextPlugin({ 46 | filename: utils.assetsPath('css/[name].[contenthash].css'), 47 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 51 | allChunks: true, 52 | }), 53 | // Compress extracted CSS. We are using this plugin so that possible 54 | // duplicated CSS from different components can be deduped. 55 | new OptimizeCSSPlugin({ 56 | cssProcessorOptions: config.build.productionSourceMap 57 | ? { safe: true, map: { inline: false } } 58 | : { safe: true } 59 | }), 60 | // generate dist index.html with correct asset hash for caching. 61 | // you can customize output by editing /index.html 62 | // see https://github.com/ampedandwired/html-webpack-plugin 63 | new HtmlWebpackPlugin({ 64 | filename: config.build.index, 65 | template: 'index.html', 66 | inject: true, 67 | minify: { 68 | removeComments: true, 69 | collapseWhitespace: true, 70 | removeAttributeQuotes: true 71 | // more options: 72 | // https://github.com/kangax/html-minifier#options-quick-reference 73 | }, 74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 75 | chunksSortMode: 'dependency' 76 | }), 77 | // keep module.id stable when vendor modules does not change 78 | new webpack.HashedModuleIdsPlugin(), 79 | // enable scope hoisting 80 | new webpack.optimize.ModuleConcatenationPlugin(), 81 | // split vendor js into its own file 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'vendor', 84 | minChunks (module) { 85 | // any required modules inside node_modules are extracted to vendor 86 | return ( 87 | module.resource && 88 | /\.js$/.test(module.resource) && 89 | module.resource.indexOf( 90 | path.join(__dirname, '../node_modules') 91 | ) === 0 92 | ) 93 | } 94 | }), 95 | // extract webpack runtime and module manifest to its own file in order to 96 | // prevent vendor hash from being updated whenever app bundle is updated 97 | new webpack.optimize.CommonsChunkPlugin({ 98 | name: 'manifest', 99 | minChunks: Infinity 100 | }), 101 | // This instance extracts shared chunks from code splitted chunks and bundles them 102 | // in a separate chunk, similar to the vendor chunk 103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 104 | new webpack.optimize.CommonsChunkPlugin({ 105 | name: 'app', 106 | async: 'vendor-async', 107 | children: true, 108 | minChunks: 3 109 | }), 110 | 111 | // copy custom static assets 112 | new CopyWebpackPlugin([ 113 | { 114 | from: path.resolve(__dirname, '../static'), 115 | to: config.build.assetsSubDirectory, 116 | ignore: ['.*'] 117 | } 118 | ]) 119 | ] 120 | }) 121 | 122 | if (config.build.productionGzip) { 123 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 124 | 125 | webpackConfig.plugins.push( 126 | new CompressionWebpackPlugin({ 127 | asset: '[path].gz[query]', 128 | algorithm: 'gzip', 129 | test: new RegExp( 130 | '\\.(' + 131 | config.build.productionGzipExtensions.join('|') + 132 | ')$' 133 | ), 134 | threshold: 10240, 135 | minRatio: 0.8 136 | }) 137 | ) 138 | } 139 | 140 | if (config.build.bundleAnalyzerReport) { 141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 | } 144 | 145 | module.exports = webpackConfig 146 | -------------------------------------------------------------------------------- /charFront/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /charFront/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: { 14 | '/': { 15 | target: 'http://127.0.0.1:8086', // 接口的域名 16 | } 17 | }, 18 | 19 | // Various Dev Server settings 20 | host: 'localhost', // can be overwritten by process.env.HOST 21 | port: 8087, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 22 | autoOpenBrowser: false, 23 | errorOverlay: true, 24 | notifyOnErrors: true, 25 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 26 | 27 | 28 | /** 29 | * Source Maps 30 | */ 31 | 32 | // https://webpack.js.org/configuration/devtool/#development 33 | devtool: 'cheap-module-eval-source-map', 34 | 35 | // If you have problems debugging vue-files in devtools, 36 | // set this to false - it *may* help 37 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 38 | cacheBusting: true, 39 | 40 | cssSourceMap: true 41 | }, 42 | 43 | build: { 44 | // Template for index.html 45 | index: path.resolve(__dirname, '../dist/index.html'), 46 | 47 | // Paths 48 | assetsRoot: path.resolve(__dirname, '../dist'), 49 | assetsSubDirectory: 'static', 50 | assetsPublicPath: '/', 51 | 52 | /** 53 | * Source Maps 54 | */ 55 | 56 | productionSourceMap: true, 57 | // https://webpack.js.org/configuration/devtool/#production 58 | devtool: '#source-map', 59 | 60 | // Gzip off by default as many popular static hosts such as 61 | // Surge or Netlify already gzip all static assets for you. 62 | // Before setting to `true`, make sure to: 63 | // npm install --save-dev compression-webpack-plugin 64 | productionGzip: false, 65 | productionGzipExtensions: ['js', 'css'], 66 | 67 | // Run the build command with an extra argument to 68 | // View the bundle analyzer report after build finishes: 69 | // `npm run build --report` 70 | // Set to `true` or `false` to always turn it on or off 71 | bundleAnalyzerReport: process.env.npm_config_report 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /charFront/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /charFront/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | charselfvue 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /charFront/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "charselfvue", 3 | "version": "1.0.0", 4 | "description": "charroom", 5 | "author": "yzengchn@163.com", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "axios": "^0.18.0", 14 | "iview": "^3.1.0", 15 | "vue": "^2.5.2", 16 | "vue-axios": "^2.1.3", 17 | "vue-router": "^3.0.1" 18 | }, 19 | "devDependencies": { 20 | "autoprefixer": "^7.1.2", 21 | "babel-core": "^6.22.1", 22 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 23 | "babel-loader": "^7.1.1", 24 | "babel-plugin-syntax-jsx": "^6.18.0", 25 | "babel-plugin-transform-runtime": "^6.22.0", 26 | "babel-plugin-transform-vue-jsx": "^3.5.0", 27 | "babel-preset-env": "^1.3.2", 28 | "babel-preset-stage-2": "^6.22.0", 29 | "chalk": "^2.0.1", 30 | "copy-webpack-plugin": "^4.0.1", 31 | "css-loader": "^0.28.0", 32 | "extract-text-webpack-plugin": "^3.0.0", 33 | "file-loader": "^1.1.4", 34 | "friendly-errors-webpack-plugin": "^1.6.1", 35 | "html-webpack-plugin": "^2.30.1", 36 | "node-notifier": "^5.1.2", 37 | "optimize-css-assets-webpack-plugin": "^3.2.0", 38 | "ora": "^1.2.0", 39 | "portfinder": "^1.0.13", 40 | "postcss-import": "^11.0.0", 41 | "postcss-loader": "^2.0.8", 42 | "postcss-url": "^7.2.1", 43 | "rimraf": "^2.6.0", 44 | "semver": "^5.3.0", 45 | "shelljs": "^0.7.6", 46 | "uglifyjs-webpack-plugin": "^1.1.1", 47 | "url-loader": "^0.5.8", 48 | "vue-loader": "^13.3.0", 49 | "vue-style-loader": "^3.0.1", 50 | "vue-template-compiler": "^2.5.2", 51 | "webpack": "^3.6.0", 52 | "webpack-bundle-analyzer": "^2.9.0", 53 | "webpack-dev-server": "^2.9.1", 54 | "webpack-merge": "^4.1.0" 55 | }, 56 | "engines": { 57 | "node": ">= 6.0.0", 58 | "npm": ">= 3.0.0" 59 | }, 60 | "browserslist": [ 61 | "> 1%", 62 | "last 2 versions", 63 | "not ie <= 8" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /charFront/src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 54 | 275 | 276 | 390 | -------------------------------------------------------------------------------- /charFront/src/App2.vue: -------------------------------------------------------------------------------- 1 | 25 | 112 | 241 | -------------------------------------------------------------------------------- /charFront/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzengchn/CharMe/970087e24d3975a99b06ef63628ddafb6d923294/charFront/src/assets/logo.png -------------------------------------------------------------------------------- /charFront/src/components/AddFriend.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 131 | 132 | 133 | 136 | -------------------------------------------------------------------------------- /charFront/src/components/FriendsList.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 51 | 52 | 53 | 56 | -------------------------------------------------------------------------------- /charFront/src/components/GroupList.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 54 | 55 | 56 | 59 | -------------------------------------------------------------------------------- /charFront/src/components/GroupMessage.vue: -------------------------------------------------------------------------------- 1 | 90 | 91 | 275 | 276 | 277 | 284 | -------------------------------------------------------------------------------- /charFront/src/components/Index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 31 | 32 | 33 | 36 | -------------------------------------------------------------------------------- /charFront/src/components/Login.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 32 | 33 | 34 | 37 | -------------------------------------------------------------------------------- /charFront/src/components/Message.vue: -------------------------------------------------------------------------------- 1 | 87 | 88 | 268 | 269 | 270 | 282 | -------------------------------------------------------------------------------- /charFront/src/components/UserInfo.vue: -------------------------------------------------------------------------------- 1 | 4 | 22 | 25 | -------------------------------------------------------------------------------- /charFront/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import FriendsList from './components/FriendsList' 6 | import GroupList from './components/GroupList' 7 | import Message from './components/Message' 8 | import GroupMessage from './components/GroupMessage' 9 | import AddFriend from './components/AddFriend' 10 | import UserInfo from './components/UserInfo' 11 | import router from './router' 12 | 13 | import iView from 'iview' 14 | import 'iview/dist/styles/iview.css' // 使用 CSS 15 | 16 | Vue.use(iView) 17 | 18 | //全局注册组件 19 | Vue.component("FriendsList",FriendsList) 20 | Vue.component("GroupList",GroupList) 21 | Vue.component("Message",Message) 22 | Vue.component("GroupMessage",GroupMessage) 23 | Vue.component("AddFriend",AddFriend) 24 | Vue.component("UserInfo",UserInfo) 25 | 26 | Vue.config.productionTip = false 27 | 28 | /* eslint-disable no-new */ 29 | new Vue({ 30 | el: '#app', 31 | router, 32 | components: { App }, 33 | template: '' 34 | }) 35 | -------------------------------------------------------------------------------- /charFront/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Index from '@/components/Index' 4 | import Login from '@/components/Login' 5 | import Message from '@/components/Message' 6 | import GroupMessage from '@/components/GroupMessage' 7 | 8 | Vue.use(Router) 9 | 10 | export default new Router({ 11 | mode:'history', 12 | routes: [ 13 | { 14 | path: '/', 15 | name: 'Index', 16 | component: Index 17 | }, 18 | { 19 | path: '/login', 20 | name: 'Login', 21 | component: Login 22 | }, 23 | { 24 | path: '/message/:userid', 25 | name: 'Message', 26 | component: Message 27 | }, 28 | { 29 | path: '/message', 30 | name: 'Message', 31 | component: Message 32 | }, 33 | { 34 | path: '/group', 35 | name: 'GroupMessage', 36 | component: GroupMessage 37 | } 38 | ] 39 | }) 40 | --------------------------------------------------------------------------------