(好几天没有写东西了,也没有去练手了,就看了看这个。。。)
项目说明
老规矩,还是先看看小项目的目录结构:
这里就只放了一点点代码(代码太长了)
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
spring:
profiles:
active: prod
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/chat?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
#指定数据源
type: com.alibaba.druid.pool.DruidDataSource
# 数据源其他配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
thymeleaf:
suffix: .html
prefix:
classpath: /templates/
cache: false
jackson: #返回的日期字段的格式
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false # true 使用时间戳显示时间
http:
multipart:
max-file-size: 1000Mb
max-request-size: 1000Mb
#配置文件式开发
mybatis:
#全局配置文件的位置
config-location: classpath:mybatis/mybatis-config.xml
#所有sql映射配置文件的位置
mapper-locations: classpath:mybatis/mapper/**/*.xml
server:
session:
timeout: 7200
这里就不再多说了,有Login,Userinfo,ChatMsg,ChatFriends
(这里就举出了一个,不再多说)
public interface ChatFriendsMapper {
//查询所有的好友
List<ChatFriends> LookUserAllFriends(String userid);
//插入好友
void InsertUserFriend(ChatFriends chatFriends);
//判断是否加好友
Integer JustTwoUserIsFriend(ChatFriends chatFriends);
//查询用户的信息
Userinfo LkUserinfoByUserid(String userid);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chat.mapper.ChatFriendsMapper">
<select id="LookUserAllFriends" resultType="com.chat.bean.ChatFriends" parameterType="java.lang.String">
select userid,nickname,uimg from userinfo where userid in (select a.fuserid from chat_friends a where a.userid=#{userid})
</select>
<insert id="InsertUserFriend" parameterType="com.chat.bean.ChatFriends">
insert into chat_friends (userid, fuserid) value (#{userid},#{fuserid})
</insert>
<select id="JustTwoUserIsFriend" parameterType="com.chat.bean.ChatFriends" resultType="java.lang.Integer">
select id from chat_friends where userid=#{userid} and fuserid=#{fuserid}
</select>
<select id="LkUserinfoByUserid" parameterType="java.lang.String" resultType="com.chat.bean.Userinfo">
select * from userinfo where userid=#{userid}
</select>
</mapper>
(同样的业务层这里也就指出一个)
@Service
public class ChatFriendsService {
@Autowired
ChatFriendsMapper chatFriendsMapper;
public List<ChatFriends> LookUserAllFriends(String userid){
return chatFriendsMapper.LookUserAllFriends(userid);
}
public void InsertUserFriend(ChatFriends chatFriends){
chatFriendsMapper.InsertUserFriend(chatFriends);
}
public Integer JustTwoUserIsFriend(ChatFriends chatFriends){
return chatFriendsMapper.JustTwoUserIsFriend(chatFriends);
}
public Userinfo LkUserinfoByUserid(String userid){
return chatFriendsMapper.LkUserinfoByUserid(userid);
}
}
这里再说说项目的接口
(同样就只写一个)
@Controller
public class LoginCtrl {
@Autowired
LoginService loginService;
@GetMapping("/")
public String tologin(){
return "user/login";
}
/**
* 登陆
* */
@PostMapping("/justlogin")
@ResponseBody
public R login(@RequestBody Login login, HttpSession session){
login.setPassword(Md5Util.StringInMd5(login.getPassword()));
String userid=loginService.justLogin(login);
if(userid==null){
return R.error().message("账号或者密码错误");
}
session.setAttribute("userid",userid);
return R.ok().message("登录成功");
}
}
public class EmojiFilter {
private static boolean isEmojiCharacter(char codePoint) {
return (codePoint==0x0) || (codePoint==0x9) || (codePoint==0xA)
|| (codePoint==0xD)
|| ((codePoint >=0x20) && (codePoint <=0xD7FF))
|| ((codePoint >=0xE000) && (codePoint <=0xFFFD))
|| ((codePoint >=0x10000) && (codePoint <=0x10FFFF));
}
@Test
public void testA(){
String s=EmojiFilter.filterEmoji("您好,你好啊");
System.out.println(s);
}
static String[] chars={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
/**
* 将普通字符串用md5加密,并转化为16进制字符串
* @param str
* @return
*/
public static String StringInMd5(String str) {
// 消息签名(摘要)
MessageDigest md5=null;
try {
// 参数代表的是算法名称
md5=MessageDigest.getInstance("md5");
byte[] result=md5.digest(str.getBytes());
StringBuilder sb=new StringBuilder(32);
// 将结果转为16进制字符 0~9 A~F
for (int i=0; i < result.length; i++) {
// 一个字节对应两个字符
byte x=result[i];
// 取得高位
int h=0x0f & (x >>> 4);
// 取得低位
int l=0x0f & x;
sb.append(chars[h]).append(chars[l]);
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public class TestUtil {
@Test
public void testA(){
String s=Md5Util.StringInMd5("123456");
System.out.println(s);
}
}
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix="spring.datasource")
@Bean
public DataSource druid(){
return new DruidDataSource();
}
//配置Druid的监控
//1.配置要给管理后台的Servlet
@Bean
public ServletRegistrationBean servletRegistrationBean(){
ServletRegistrationBean bean=new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
Map<String,String> initParams=new HashMap<>();
initParams.put("loginUsername","admin");
initParams.put("loginPassword","admin233215");
initParams.put("allow","");//默认允许ip访问
initParams.put("deny","");
bean.setInitParameters(initParams);
return bean;
}
//2.配置一个监控的filter
@Bean
public FilterRegistrationBean webStarFilter(){
FilterRegistrationBean bean=new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParams=new HashMap<>();
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
@Configuration
public class MyConfig extends WebMvcConfigurerAdapter {
//配置一个静态文件的路径 否则css和js无法使用,虽然默认的静态资源是放在static下,但是没有配置里面的文件夹
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
@Bean
public WebMvcConfigurerAdapter WebMvcConfigurerAdapter() {
WebMvcConfigurerAdapter adapter=new WebMvcConfigurerAdapter() {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//registry.addResourceHandler("/pic/**").addResourceLocations("file:D:/chat/");
registry.addResourceHandler("/pic/**").addResourceLocations("file:D:/idea_project/SpringBoot/Project/Complete&&Finish/chat/chatmsg/");
super.addResourceHandlers(registry);
}
};
return adapter;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册TestInterceptor拦截器
InterceptorRegistration registration=registry.addInterceptor(new AdminInterceptor());
registration.addPathPatterns("/chat/*");
}
}
@Configuration
@EnableWebSocket
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
这是两个不同的用户
当然了,还可以进行语音,添加好友 今天的就写到这里吧!谢谢! 这里要提一下我的一个学长的个人博客,当然了,还有我的,谢谢
作者:奶思
链接:https://juejin.im/post/5ea7994c5188256da14e972d
来源:掘金
者:五月君
转发链接:https://mp.weixin.qq.com/s/TLKkRwftewa0uMvIRlOf5g
键词:Shopify聊天插件、独立站运营、实时聊天机器人
如果您在考虑 "如何在我的Shopify商店中添加实时聊天",您就来对地方了。在今天的文章中,我将告诉您如何一步一步地做到这一点。
但在详细介绍之前,让我们了解一下为什么您应该在您的网店中添加一个SaleSmartly聊天按钮。
为什么您的Shopify商店需要一个实时聊天工具?
如果您在经营电子商务业务,您知道将每个访客变成客户,然后成为回头客是多么困难的事情。通过实时聊天,您可以提供个性化的服务,让您的工作更加轻松。
以下是为您的在线商店添加SaleSmartly实时聊天的好处。
听起来不错,对吗?
您可能会为拥有一个而感到兴奋!所以,让我们继续发现最适合您的Shopify商店的实时聊天应用程序。
SaleSmartly实时聊天。最好的Shopify实时聊天应用程序
SaleSmartly为您提供了一个强大的实时聊天小工具,您可以将其添加到您的Shopify商店或其他电子商务商店。它是最好的Shopify实时聊天应用程序之一。
SaleSmartly实时聊天功能。
关于定价,SaleSmartly为您提供免费版试用,能尝试各种功能。它的定价计划比Zendesk Chat、Tidio Chat和其他实时聊天软件都要合理和实惠。
SaleSmartly也提供全渠道沟通,SaleSmartly集成了Messenger、WhatsApp、Instagram、Line、Telegram、Email等多渠道聊天管理插件,能助力卖家全面触达海外消费者;同时支持100+语言实时翻译,让卖家与海外消费者可以无障碍交流。您还可以从此仪表板访问来自其他渠道(如电子邮件、电话和社交媒体)的所有票证。
将SaleSmartly与你的Shopify商店整合
要跟上本教程,你需要一个SaleSmartly聊天账户。如果您还没有, 请快快注册一个吧!
SaleSmartly实时聊天还提供了建立聊天机器人的能力,提升客户回复效率,增加团队之间的协作。通过自动化流程服务,帮助提升客服工作效率。同时支持移动端小程序,随时随地回复各渠道的客户咨询。
SaleSmartly官方注册链接:https://www.salesmartly.com/?source=tth-Shopify627
*请认真填写需求信息,我们会在24小时内与您取得联系。