chatMessageResultList = new LinkedList<>();
+ ImUser imUser = new ImUser();
+ ChatMessageResult chatMessageResult = new ChatMessageResult();
+ for (ImChatlog imChatlog : imChatlogs) {
+ imUser = imUserMapper.selectByPrimaryKey(imChatlog.getFromid());
+ chatMessageResult.setUsername(imUser.getUsername());
+ chatMessageResult.setAvatar(imUser.getAvatar());
+ chatMessageResult.setFromid(imChatlog.getFromid() + "");
+ chatMessageResult.setId(imChatlog.getFromid() + "");
+ chatMessageResult.setContent(imChatlog.getContent());
+ chatMessageResult.setType(imChatlog.getTyp());
+ chatMessageResult.setTimestamp(imChatlog.getSendtime());
+ chatMessageResult.setChatType("chatMessage");
+ chatMessageResultList.add(chatMessageResult);
+ }
+ return chatMessageResultList;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..47ab688
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+server.port=8080
+spring.datasource.url = jdbc:mysql://52xbjs.com:3306/webim?setUnicode=true&characterEncoding=utf8
+spring.datasource.username = webim
+spring.datasource.password = webim
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
+#mybatis配置文件
+mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
+mybatis.config-locations=classpath:mybatis/mybatis-config.xml
+mybatis.type-aliases-package=com.xbjs.webim.pojo
+mybatis.configuration.map-underscore-to-camel-case=true
+
+#JSP配置
+spring.mvc.view.prefix=/WEB-INF/jsp/
+spring.mvc.view.suffix=.jsp
+
+#thymeleaf模板配置文件
+spring.thymeleaf.prefix= classpath:/templates/
+spring.thymeleaf.suffix= .html
+spring.thymeleaf.cache=false
+#静态文件
+spring.mvc.static-path-pattern=/static/**
+#开启日志
+debug=true
diff --git a/src/main/resources/mybatis/mapper/ImChatlogMapper.xml b/src/main/resources/mybatis/mapper/ImChatlogMapper.xml
new file mode 100644
index 0000000..cb988e6
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImChatlogMapper.xml
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ chatlogId, fromId, toId, content, sendTime, typ, status
+
+
+ select
+
+ distinct
+
+
+ from im_chatlog
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select
+
+ from im_chatlog
+ where chatlogId = #{chatlogid,jdbcType=BIGINT}
+
+
+ delete from im_chatlog
+ where chatlogId = #{chatlogid,jdbcType=BIGINT}
+
+
+ delete from im_chatlog
+
+
+
+
+
+ insert into im_chatlog (chatlogId, fromId, toId,
+ content, sendTime, typ,
+ status)
+ values (#{chatlogid,jdbcType=BIGINT}, #{fromid,jdbcType=BIGINT}, #{toid,jdbcType=BIGINT},
+ #{content,jdbcType=VARCHAR}, #{sendtime,jdbcType=BIGINT}, #{typ,jdbcType=VARCHAR},
+ #{status,jdbcType=INTEGER})
+
+
+ insert into im_chatlog
+
+
+ chatlogId,
+
+
+ fromId,
+
+
+ toId,
+
+
+ content,
+
+
+ sendTime,
+
+
+ typ,
+
+
+ status,
+
+
+
+
+ #{chatlogid,jdbcType=BIGINT},
+
+
+ #{fromid,jdbcType=BIGINT},
+
+
+ #{toid,jdbcType=BIGINT},
+
+
+ #{content,jdbcType=VARCHAR},
+
+
+ #{sendtime,jdbcType=BIGINT},
+
+
+ #{typ,jdbcType=VARCHAR},
+
+
+ #{status,jdbcType=INTEGER},
+
+
+
+
+ select count(*) from im_chatlog
+
+
+
+
+
+ update im_chatlog
+
+
+ chatlogId = #{record.chatlogid,jdbcType=BIGINT},
+
+
+ fromId = #{record.fromid,jdbcType=BIGINT},
+
+
+ toId = #{record.toid,jdbcType=BIGINT},
+
+
+ content = #{record.content,jdbcType=VARCHAR},
+
+
+ sendTime = #{record.sendtime,jdbcType=BIGINT},
+
+
+ typ = #{record.typ,jdbcType=VARCHAR},
+
+
+ status = #{record.status,jdbcType=INTEGER},
+
+
+
+
+
+
+
+ update im_chatlog
+ set chatlogId = #{record.chatlogid,jdbcType=BIGINT},
+ fromId = #{record.fromid,jdbcType=BIGINT},
+ toId = #{record.toid,jdbcType=BIGINT},
+ content = #{record.content,jdbcType=VARCHAR},
+ sendTime = #{record.sendtime,jdbcType=BIGINT},
+ typ = #{record.typ,jdbcType=VARCHAR},
+ status = #{record.status,jdbcType=INTEGER}
+
+
+
+
+
+ update im_chatlog
+
+
+ fromId = #{fromid,jdbcType=BIGINT},
+
+
+ toId = #{toid,jdbcType=BIGINT},
+
+
+ content = #{content,jdbcType=VARCHAR},
+
+
+ sendTime = #{sendtime,jdbcType=BIGINT},
+
+
+ typ = #{typ,jdbcType=VARCHAR},
+
+
+ status = #{status,jdbcType=INTEGER},
+
+
+ where chatlogId = #{chatlogid,jdbcType=BIGINT}
+
+
+ update im_chatlog
+ set fromId = #{fromid,jdbcType=BIGINT},
+ toId = #{toid,jdbcType=BIGINT},
+ content = #{content,jdbcType=VARCHAR},
+ sendTime = #{sendtime,jdbcType=BIGINT},
+ typ = #{typ,jdbcType=VARCHAR},
+ status = #{status,jdbcType=INTEGER}
+ where chatlogId = #{chatlogid,jdbcType=BIGINT}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/ImGroupMapper.xml b/src/main/resources/mybatis/mapper/ImGroupMapper.xml
new file mode 100644
index 0000000..5750347
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImGroupMapper.xml
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ group_id, groupname, avatar, notice, user_id, approval
+
+
+ select
+
+ distinct
+
+
+ from im_group
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select
+
+ from im_group
+ where group_id = #{groupId,jdbcType=BIGINT}
+
+
+ delete from im_group
+ where group_id = #{groupId,jdbcType=BIGINT}
+
+
+ delete from im_group
+
+
+
+
+
+ insert into im_group (group_id, groupname, avatar,
+ notice, user_id, approval
+ )
+ values (#{groupId,jdbcType=BIGINT}, #{groupname,jdbcType=VARCHAR}, #{avatar,jdbcType=VARCHAR},
+ #{notice,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR}, #{approval,jdbcType=INTEGER}
+ )
+
+
+ insert into im_group
+
+
+ group_id,
+
+
+ groupname,
+
+
+ avatar,
+
+
+ notice,
+
+
+ user_id,
+
+
+ approval,
+
+
+
+
+ #{groupId,jdbcType=BIGINT},
+
+
+ #{groupname,jdbcType=VARCHAR},
+
+
+ #{avatar,jdbcType=VARCHAR},
+
+
+ #{notice,jdbcType=VARCHAR},
+
+
+ #{userId,jdbcType=VARCHAR},
+
+
+ #{approval,jdbcType=INTEGER},
+
+
+
+
+ select count(*) from im_group
+
+
+
+
+
+ update im_group
+
+
+ group_id = #{record.groupId,jdbcType=BIGINT},
+
+
+ groupname = #{record.groupname,jdbcType=VARCHAR},
+
+
+ avatar = #{record.avatar,jdbcType=VARCHAR},
+
+
+ notice = #{record.notice,jdbcType=VARCHAR},
+
+
+ user_id = #{record.userId,jdbcType=VARCHAR},
+
+
+ approval = #{record.approval,jdbcType=INTEGER},
+
+
+
+
+
+
+
+ update im_group
+ set group_id = #{record.groupId,jdbcType=BIGINT},
+ groupname = #{record.groupname,jdbcType=VARCHAR},
+ avatar = #{record.avatar,jdbcType=VARCHAR},
+ notice = #{record.notice,jdbcType=VARCHAR},
+ user_id = #{record.userId,jdbcType=VARCHAR},
+ approval = #{record.approval,jdbcType=INTEGER}
+
+
+
+
+
+ update im_group
+
+
+ groupname = #{groupname,jdbcType=VARCHAR},
+
+
+ avatar = #{avatar,jdbcType=VARCHAR},
+
+
+ notice = #{notice,jdbcType=VARCHAR},
+
+
+ user_id = #{userId,jdbcType=VARCHAR},
+
+
+ approval = #{approval,jdbcType=INTEGER},
+
+
+ where group_id = #{groupId,jdbcType=BIGINT}
+
+
+ update im_group
+ set groupname = #{groupname,jdbcType=VARCHAR},
+ avatar = #{avatar,jdbcType=VARCHAR},
+ notice = #{notice,jdbcType=VARCHAR},
+ user_id = #{userId,jdbcType=VARCHAR},
+ approval = #{approval,jdbcType=INTEGER}
+ where group_id = #{groupId,jdbcType=BIGINT}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/ImGroupUserMapper.xml b/src/main/resources/mybatis/mapper/ImGroupUserMapper.xml
new file mode 100644
index 0000000..4a0fb45
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImGroupUserMapper.xml
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ group_user_id, user_id, group_id, nickName
+
+
+ select
+
+ distinct
+
+
+ from im_group_user
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select
+
+ from im_group_user
+ where group_user_id = #{groupUserId,jdbcType=BIGINT}
+
+
+ delete from im_group_user
+ where group_user_id = #{groupUserId,jdbcType=BIGINT}
+
+
+ delete from im_group_user
+
+
+
+
+
+ insert into im_group_user (group_user_id, user_id, group_id,
+ nickName)
+ values (#{groupUserId,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{groupId,jdbcType=BIGINT},
+ #{nickname,jdbcType=VARCHAR})
+
+
+ insert into im_group_user
+
+
+ group_user_id,
+
+
+ user_id,
+
+
+ group_id,
+
+
+ nickName,
+
+
+
+
+ #{groupUserId,jdbcType=BIGINT},
+
+
+ #{userId,jdbcType=BIGINT},
+
+
+ #{groupId,jdbcType=BIGINT},
+
+
+ #{nickname,jdbcType=VARCHAR},
+
+
+
+
+ select count(*) from im_group_user
+
+
+
+
+
+ update im_group_user
+
+
+ group_user_id = #{record.groupUserId,jdbcType=BIGINT},
+
+
+ user_id = #{record.userId,jdbcType=BIGINT},
+
+
+ group_id = #{record.groupId,jdbcType=BIGINT},
+
+
+ nickName = #{record.nickname,jdbcType=VARCHAR},
+
+
+
+
+
+
+
+ update im_group_user
+ set group_user_id = #{record.groupUserId,jdbcType=BIGINT},
+ user_id = #{record.userId,jdbcType=BIGINT},
+ group_id = #{record.groupId,jdbcType=BIGINT},
+ nickName = #{record.nickname,jdbcType=VARCHAR}
+
+
+
+
+
+ update im_group_user
+
+
+ user_id = #{userId,jdbcType=BIGINT},
+
+
+ group_id = #{groupId,jdbcType=BIGINT},
+
+
+ nickName = #{nickname,jdbcType=VARCHAR},
+
+
+ where group_user_id = #{groupUserId,jdbcType=BIGINT}
+
+
+ update im_group_user
+ set user_id = #{userId,jdbcType=BIGINT},
+ group_id = #{groupId,jdbcType=BIGINT},
+ nickName = #{nickname,jdbcType=VARCHAR}
+ where group_user_id = #{groupUserId,jdbcType=BIGINT}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/ImMsgboxMapper.xml b/src/main/resources/mybatis/mapper/ImMsgboxMapper.xml
new file mode 100644
index 0000000..ae8b89e
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImMsgboxMapper.xml
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ box_id, uid, fromid, from_group, typ, remark, href, read, time
+
+
+ select
+
+ distinct
+
+
+ from "im_msgbox"
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select
+
+ from "im_msgbox"
+ where box_id = #{boxId,jdbcType=BIGINT}
+
+
+ delete from "im_msgbox"
+ where box_id = #{boxId,jdbcType=BIGINT}
+
+
+ delete from "im_msgbox"
+
+
+
+
+
+ insert into "im_msgbox" (box_id, uid, fromid,
+ from_group, typ, remark,
+ href, read, time)
+ values (#{boxId,jdbcType=BIGINT}, #{uid,jdbcType=BIGINT}, #{fromid,jdbcType=BIGINT},
+ #{fromGroup,jdbcType=BIGINT}, #{typ,jdbcType=INTEGER}, #{remark,jdbcType=VARCHAR},
+ #{href,jdbcType=VARCHAR}, #{read,jdbcType=SMALLINT}, #{time,jdbcType=BIGINT})
+
+
+ insert into "im_msgbox"
+
+
+ box_id,
+
+
+ uid,
+
+
+ fromid,
+
+
+ from_group,
+
+
+ typ,
+
+
+ remark,
+
+
+ href,
+
+
+ read,
+
+
+ time,
+
+
+
+
+ #{boxId,jdbcType=BIGINT},
+
+
+ #{uid,jdbcType=BIGINT},
+
+
+ #{fromid,jdbcType=BIGINT},
+
+
+ #{fromGroup,jdbcType=BIGINT},
+
+
+ #{typ,jdbcType=INTEGER},
+
+
+ #{remark,jdbcType=VARCHAR},
+
+
+ #{href,jdbcType=VARCHAR},
+
+
+ #{read,jdbcType=SMALLINT},
+
+
+ #{time,jdbcType=BIGINT},
+
+
+
+
+ select count(*) from "im_msgbox"
+
+
+
+
+
+ update "im_msgbox"
+
+
+ box_id = #{record.boxId,jdbcType=BIGINT},
+
+
+ uid = #{record.uid,jdbcType=BIGINT},
+
+
+ fromid = #{record.fromid,jdbcType=BIGINT},
+
+
+ from_group = #{record.fromGroup,jdbcType=BIGINT},
+
+
+ typ = #{record.typ,jdbcType=INTEGER},
+
+
+ remark = #{record.remark,jdbcType=VARCHAR},
+
+
+ href = #{record.href,jdbcType=VARCHAR},
+
+
+ read = #{record.read,jdbcType=SMALLINT},
+
+
+ time = #{record.time,jdbcType=BIGINT},
+
+
+
+
+
+
+
+ update "im_msgbox"
+ set box_id = #{record.boxId,jdbcType=BIGINT},
+ uid = #{record.uid,jdbcType=BIGINT},
+ fromid = #{record.fromid,jdbcType=BIGINT},
+ from_group = #{record.fromGroup,jdbcType=BIGINT},
+ typ = #{record.typ,jdbcType=INTEGER},
+ remark = #{record.remark,jdbcType=VARCHAR},
+ href = #{record.href,jdbcType=VARCHAR},
+ read = #{record.read,jdbcType=SMALLINT},
+ time = #{record.time,jdbcType=BIGINT}
+
+
+
+
+
+ update "im_msgbox"
+
+
+ uid = #{uid,jdbcType=BIGINT},
+
+
+ fromid = #{fromid,jdbcType=BIGINT},
+
+
+ from_group = #{fromGroup,jdbcType=BIGINT},
+
+
+ typ = #{typ,jdbcType=INTEGER},
+
+
+ remark = #{remark,jdbcType=VARCHAR},
+
+
+ href = #{href,jdbcType=VARCHAR},
+
+
+ read = #{read,jdbcType=SMALLINT},
+
+
+ time = #{time,jdbcType=BIGINT},
+
+
+ where box_id = #{boxId,jdbcType=BIGINT}
+
+
+ update "im_msgbox"
+ set uid = #{uid,jdbcType=BIGINT},
+ fromid = #{fromid,jdbcType=BIGINT},
+ from_group = #{fromGroup,jdbcType=BIGINT},
+ typ = #{typ,jdbcType=INTEGER},
+ remark = #{remark,jdbcType=VARCHAR},
+ href = #{href,jdbcType=VARCHAR},
+ read = #{read,jdbcType=SMALLINT},
+ time = #{time,jdbcType=BIGINT}
+ where box_id = #{boxId,jdbcType=BIGINT}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/ImMyFriendMapper.xml b/src/main/resources/mybatis/mapper/ImMyFriendMapper.xml
new file mode 100644
index 0000000..5aa869c
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImMyFriendMapper.xml
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ my_friend_id, my_fz_id, user_id, nickName
+
+
+ select
+
+ distinct
+
+
+ from im_my_friend
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select
+
+ from im_my_friend
+ where my_friend_id = #{myFriendId,jdbcType=BIGINT}
+
+
+ delete from im_my_friend
+ where my_friend_id = #{myFriendId,jdbcType=BIGINT}
+
+
+ delete from im_my_friend
+
+
+
+
+
+ insert into im_my_friend (my_friend_id, my_fz_id, user_id,
+ nickName)
+ values (#{myFriendId,jdbcType=BIGINT}, #{myFzId,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT},
+ #{nickname,jdbcType=VARCHAR})
+
+
+ insert into im_my_friend
+
+
+ my_friend_id,
+
+
+ my_fz_id,
+
+
+ user_id,
+
+
+ nickName,
+
+
+
+
+ #{myFriendId,jdbcType=BIGINT},
+
+
+ #{myFzId,jdbcType=BIGINT},
+
+
+ #{userId,jdbcType=BIGINT},
+
+
+ #{nickname,jdbcType=VARCHAR},
+
+
+
+
+ select count(*) from im_my_friend
+
+
+
+
+
+ update im_my_friend
+
+
+ my_friend_id = #{record.myFriendId,jdbcType=BIGINT},
+
+
+ my_fz_id = #{record.myFzId,jdbcType=BIGINT},
+
+
+ user_id = #{record.userId,jdbcType=BIGINT},
+
+
+ nickName = #{record.nickname,jdbcType=VARCHAR},
+
+
+
+
+
+
+
+ update im_my_friend
+ set my_friend_id = #{record.myFriendId,jdbcType=BIGINT},
+ my_fz_id = #{record.myFzId,jdbcType=BIGINT},
+ user_id = #{record.userId,jdbcType=BIGINT},
+ nickName = #{record.nickname,jdbcType=VARCHAR}
+
+
+
+
+
+ update im_my_friend
+
+
+ my_fz_id = #{myFzId,jdbcType=BIGINT},
+
+
+ user_id = #{userId,jdbcType=BIGINT},
+
+
+ nickName = #{nickname,jdbcType=VARCHAR},
+
+
+ where my_friend_id = #{myFriendId,jdbcType=BIGINT}
+
+
+ update im_my_friend
+ set my_fz_id = #{myFzId,jdbcType=BIGINT},
+ user_id = #{userId,jdbcType=BIGINT},
+ nickName = #{nickname,jdbcType=VARCHAR}
+ where my_friend_id = #{myFriendId,jdbcType=BIGINT}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/ImMyFzMapper.xml b/src/main/resources/mybatis/mapper/ImMyFzMapper.xml
new file mode 100644
index 0000000..aad8954
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImMyFzMapper.xml
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ fz_id, fz_groupname
+
+
+ select
+
+ distinct
+
+
+ from im_my_fz
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select
+
+ from im_my_fz
+ where fz_id = #{fzId,jdbcType=BIGINT}
+
+
+ delete from im_my_fz
+ where fz_id = #{fzId,jdbcType=BIGINT}
+
+
+ delete from im_my_fz
+
+
+
+
+
+ insert into im_my_fz (fz_id, fz_groupname)
+ values (#{fzId,jdbcType=BIGINT}, #{fzGroupname,jdbcType=VARCHAR})
+
+
+ insert into im_my_fz
+
+
+ fz_id,
+
+
+ fz_groupname,
+
+
+
+
+ #{fzId,jdbcType=BIGINT},
+
+
+ #{fzGroupname,jdbcType=VARCHAR},
+
+
+
+
+ select count(*) from im_my_fz
+
+
+
+
+
+ update im_my_fz
+
+
+ fz_id = #{record.fzId,jdbcType=BIGINT},
+
+
+ fz_groupname = #{record.fzGroupname,jdbcType=VARCHAR},
+
+
+
+
+
+
+
+ update im_my_fz
+ set fz_id = #{record.fzId,jdbcType=BIGINT},
+ fz_groupname = #{record.fzGroupname,jdbcType=VARCHAR}
+
+
+
+
+
+ update im_my_fz
+
+
+ fz_groupname = #{fzGroupname,jdbcType=VARCHAR},
+
+
+ where fz_id = #{fzId,jdbcType=BIGINT}
+
+
+ update im_my_fz
+ set fz_groupname = #{fzGroupname,jdbcType=VARCHAR}
+ where fz_id = #{fzId,jdbcType=BIGINT}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/ImUserFzMapper.xml b/src/main/resources/mybatis/mapper/ImUserFzMapper.xml
new file mode 100644
index 0000000..5436b9b
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImUserFzMapper.xml
@@ -0,0 +1,181 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ id, user_id, fz_id
+
+
+ select
+
+ distinct
+
+
+ from im_user_fz
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select
+
+ from im_user_fz
+ where id = #{id,jdbcType=INTEGER}
+
+
+ delete from im_user_fz
+ where id = #{id,jdbcType=INTEGER}
+
+
+ delete from im_user_fz
+
+
+
+
+
+ insert into im_user_fz (id, user_id, fz_id
+ )
+ values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=BIGINT}, #{fzId,jdbcType=BIGINT}
+ )
+
+
+ insert into im_user_fz
+
+
+ id,
+
+
+ user_id,
+
+
+ fz_id,
+
+
+
+
+ #{id,jdbcType=INTEGER},
+
+
+ #{userId,jdbcType=BIGINT},
+
+
+ #{fzId,jdbcType=BIGINT},
+
+
+
+
+ select count(*) from im_user_fz
+
+
+
+
+
+ update im_user_fz
+
+
+ id = #{record.id,jdbcType=INTEGER},
+
+
+ user_id = #{record.userId,jdbcType=BIGINT},
+
+
+ fz_id = #{record.fzId,jdbcType=BIGINT},
+
+
+
+
+
+
+
+ update im_user_fz
+ set id = #{record.id,jdbcType=INTEGER},
+ user_id = #{record.userId,jdbcType=BIGINT},
+ fz_id = #{record.fzId,jdbcType=BIGINT}
+
+
+
+
+
+ update im_user_fz
+
+
+ user_id = #{userId,jdbcType=BIGINT},
+
+
+ fz_id = #{fzId,jdbcType=BIGINT},
+
+
+ where id = #{id,jdbcType=INTEGER}
+
+
+ update im_user_fz
+ set user_id = #{userId,jdbcType=BIGINT},
+ fz_id = #{fzId,jdbcType=BIGINT}
+ where id = #{id,jdbcType=INTEGER}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mapper/ImUserMapper.xml b/src/main/resources/mybatis/mapper/ImUserMapper.xml
new file mode 100644
index 0000000..7cff195
--- /dev/null
+++ b/src/main/resources/mybatis/mapper/ImUserMapper.xml
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ and ${criterion.condition}
+
+
+ and ${criterion.condition} #{criterion.value}
+
+
+ and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+
+
+ and ${criterion.condition}
+
+ #{listItem}
+
+
+
+
+
+
+
+
+
+
+ id, username, pass, sign, status, avatar, sex
+
+
+ select
+
+ distinct
+
+
+ from im_user
+
+
+
+
+ order by ${orderByClause}
+
+
+
+ select * from im_user where `id` = #{id,jdbcType=BIGINT}
+
+
+ delete from im_user
+ where id = #{id,jdbcType=BIGINT}
+
+
+ delete from im_user
+
+
+
+
+
+ insert into im_user (id, username, pass,
+ sign, status, avatar,
+ sex)
+ values (#{id,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{pass,jdbcType=VARCHAR},
+ #{sign,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{avatar,jdbcType=VARCHAR},
+ #{sex,jdbcType=INTEGER})
+
+
+ insert into im_user
+
+
+ id,
+
+
+ username,
+
+
+ pass,
+
+
+ sign,
+
+
+ status,
+
+
+ avatar,
+
+
+ sex,
+
+
+
+
+ #{id,jdbcType=BIGINT},
+
+
+ #{username,jdbcType=VARCHAR},
+
+
+ #{pass,jdbcType=VARCHAR},
+
+
+ #{sign,jdbcType=VARCHAR},
+
+
+ #{status,jdbcType=VARCHAR},
+
+
+ #{avatar,jdbcType=VARCHAR},
+
+
+ #{sex,jdbcType=INTEGER},
+
+
+
+
+ select count(*) from im_user
+
+
+
+
+
+ update im_user
+
+
+ id = #{record.id,jdbcType=BIGINT},
+
+
+ username = #{record.username,jdbcType=VARCHAR},
+
+
+ pass = #{record.pass,jdbcType=VARCHAR},
+
+
+ sign = #{record.sign,jdbcType=VARCHAR},
+
+
+ status = #{record.status,jdbcType=VARCHAR},
+
+
+ avatar = #{record.avatar,jdbcType=VARCHAR},
+
+
+ sex = #{record.sex,jdbcType=INTEGER},
+
+
+
+
+
+
+
+ update im_user
+ set id = #{record.id,jdbcType=BIGINT},
+ username = #{record.username,jdbcType=VARCHAR},
+ pass = #{record.pass,jdbcType=VARCHAR},
+ sign = #{record.sign,jdbcType=VARCHAR},
+ status = #{record.status,jdbcType=VARCHAR},
+ avatar = #{record.avatar,jdbcType=VARCHAR},
+ sex = #{record.sex,jdbcType=INTEGER}
+
+
+
+
+
+ update im_user
+
+
+ username = #{username,jdbcType=VARCHAR},
+
+
+ pass = #{pass,jdbcType=VARCHAR},
+
+
+ sign = #{sign,jdbcType=VARCHAR},
+
+
+ status = #{status,jdbcType=VARCHAR},
+
+
+ avatar = #{avatar,jdbcType=VARCHAR},
+
+
+ sex = #{sex,jdbcType=INTEGER},
+
+
+ where id = #{id,jdbcType=BIGINT}
+
+
+ update im_user
+ set username = #{username,jdbcType=VARCHAR},
+ pass = #{pass,jdbcType=VARCHAR},
+ sign = #{sign,jdbcType=VARCHAR},
+ status = #{status,jdbcType=VARCHAR},
+ avatar = #{avatar,jdbcType=VARCHAR},
+ sex = #{sex,jdbcType=INTEGER}
+ where id = #{id,jdbcType=BIGINT}
+
+
+ update im_user
+ set status = #{status,jdbcType=VARCHAR},
+ where id = #{id,jdbcType=BIGINT}
+
+
\ No newline at end of file
diff --git a/src/main/resources/mybatis/mybatis-config.xml b/src/main/resources/mybatis/mybatis-config.xml
new file mode 100644
index 0000000..612d602
--- /dev/null
+++ b/src/main/resources/mybatis/mybatis-config.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/static/css/Uploader.swf b/src/main/resources/static/css/Uploader.swf
new file mode 100644
index 0000000..bd75d60
Binary files /dev/null and b/src/main/resources/static/css/Uploader.swf differ
diff --git a/src/main/resources/static/css/layui.demo.css b/src/main/resources/static/css/layui.demo.css
new file mode 100644
index 0000000..57369a3
--- /dev/null
+++ b/src/main/resources/static/css/layui.demo.css
@@ -0,0 +1,370 @@
+/**
+
+ layui官网
+ By 贤心
+
+*/
+
+
+/* 布局 */
+.site-inline{font-size: 0;}
+.site-tree, .site-content{display: inline-block; *display:inline; *zoom:1; vertical-align: top; font-size: 14px;}
+.site-tree{width: 220px; min-height: 900px; padding: 5px 0 20px;}
+.site-content{width: 899px; min-height: 900px; padding: 20px 0 10px 20px;}
+
+/* 头部 */
+.header{height: 59px; border-bottom: 1px solid #404553; background-color: #393D49;}
+.logo{position: absolute; left: 0; top: 16px;}
+.logo img{width: 82px; height: 31px;}
+
+.header .layui-nav{position: absolute; right: 0; top: 0; padding: 0; background: none;}
+.header .layui-nav .layui-nav-item{margin: 0 20px; }
+.header .layui-nav .layui-nav-item[mobile]{display: none;}
+
+.header .layui-container .logo{left: 15px;}
+.header .layui-container .layui-nav{right: 15px;}
+
+
+.menu{position: absolute; right: 0; top: 0; line-height: 65px;}
+.menu a{display:inline-block; *display:inline; *zoom:1; vertical-align:top;}
+.menu a{position: relative; padding: 0 20px; margin: 0 20px; color: #c2c2c2; font-size: 14px;}
+.menu a:hover{color: #fff; transition: all .5s; -webkit-transition: all .5s}
+.menu a.this{color: #fff}
+.menu a.this::after{content: ''; position: absolute; left: 0; bottom: -1px; width: 100%; height: 5px; background-color: #5FB878;}
+
+.header-index{background-color: #0A0E11; background-color: #100903; border: none;}
+
+.header-demo{height: 60px; border-bottom: none;}
+.header-demo .logo{left: 40px;}
+.header-demo .layui-nav{top: 0;}
+.header-demo .layui-nav .layui-nav-item{margin: 0 10px;}
+
+.header-demo .layui-nav .layui-this a{padding: 0 30px;}
+
+.component{position: absolute; width: 200px; left: 120px; top: 16px; }
+.component .layui-input{height: 30px; padding-left: 12px; background-color: #424652; background-color: rgba(255,255,255,.05); border: none 0; color: #fff; font-size: 12px;}
+.component .layui-form-select .layui-edge{display: none; border-top-color: #999;}
+.component .layui-form-select dl{top: 36px; background-color: rgba(255,255,255,.9)}
+.header-demo .component{left: 185px;}
+
+/* 底部 */
+.footer{padding: 30px 0; line-height: 30px; text-align: center; color: #666; font-weight: 300;}
+body .layui-layout-admin .footer-demo{height: 50px; padding: 5px 0;}
+.footer a{padding: 0 5px;}
+.site-union{margin-top: 10px; color: #999;}
+.site-union>*{display: inline-block; vertical-align: middle;}
+.site-union a[upyun] img{width: 80px;}
+.site-union span{position: relative; top: 3px;}
+.site-union span a{padding: 0; display: inline; color: #999;}
+.site-union span a:hover{text-decoration: underline;}
+
+.footer-demo p{display: inline-block; vertical-align: middle; height: 50px; padding-right: 10px;}
+.footer-demo .site-union{position: relative; top: -9px;}
+
+/* 首页banner部分 */
+.site-banner{position: relative; height: 600px; text-align: center; overflow: hidden; background-color: #393D49;}
+.site-banner-bg
+,.site-banner-main{position: absolute; left: 0; top: 0; width: 100%; height: 100%;}
+.site-banner-bg{background-position: center 0;}
+
+
+.site-zfj{padding-top: 25px; height: 220px;}
+.site-zfj i{position: absolute; left: 50%; top: 25px; width: 200px; height: 200px; margin-left: -100px; font-size: 200px; color: #c2c2c2;}
+
+@-webkit-keyframes site-zfj {
+ 0% {opacity: 1; -webkit-transform: translate3d(0, 0, 0) rotate(0deg) scale(1);}
+ 10% {opacity: 0.8; -webkit-transform: translate3d(-100px, 0px, 0) rotate(10deg) scale(0.7);}
+ 35% {opacity: 0.6; -webkit-transform: translate3d(100px, 0px, 0) rotate(30deg) scale(0.4);}
+ 50% {opacity: 0.4; -webkit-transform: translate3d(0, 0, 0) rotate(360deg) scale(0);}
+ 80% {opacity: 0.2; -webkit-transform: translate3d(0, 0, 0) rotate(720deg) scale(1);}
+ 90% {opacity: 0.1; -webkit-transform: translate3d(0, 0, 0) rotate(3600deg) scale(6);}
+ 100% {opacity: 1; -webkit-transform: translate3d(0, 0, 0) rotate(3600deg) scale(1);}
+}
+@keyframes site-zfj {
+ 0% {opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg) scale(1);}
+ 10% {opacity: 0.8; transform: translate3d(-100px, 0px, 0) rotate(10deg) scale(0.7);}
+ 35% {opacity: 0.6; transform: translate3d(100px, 0px, 0) rotate(30deg) scale(0.4);}
+ 50% {opacity: 0.4; transform: translate3d(0, 0, 0) rotate(360deg) scale(0);}
+ 80% {opacity: 0.2; transform: translate3d(0, 0, 0) rotate(720deg) scale(1);}
+ 90% {opacity: 0.1; transform: translate3d(0, 0, 0) rotate(3600deg) scale(6);}
+ 100% {opacity: 1; transform: translate3d(0, 0, 0) rotate(3600deg) scale(1);}
+}
+
+@-webkit-keyframes site-desc {
+ 0% { -webkit-transform: scale(1.1);}
+ 100% {opacity: 1; -webkit-transform: scale(1);}
+}
+@keyframes site-desc {
+ 0% { transform: scale(1.1);}
+ 100% {transform: scale(1);}
+}
+
+.site-zfj-anim i{-webkit-animation-name: site-zfj; animation-name: site-zfj; -webkit-animation-duration: 5s; animation-duration: 5s; -webkit-animation-timing-function: linear; animation-timing-function: linear;}
+
+
+.site-desc{position: relative; height: 70px; margin-top: 25px; background: url(../images/layui/desc.png) center no-repeat;}
+.site-desc-anim{-webkit-animation-name: site-desc; animation-name: site-desc;}
+
+.site-desc cite{position: absolute; bottom: -40px; left: 0; width: 100%; color: #c2c2c2; font-style: normal;}
+.site-download{margin-top: 80px; font-size: 0;}
+.site-download a{position: relative; padding: 0 45px 0 90px; height: 60px; line-height: 60px; border: 1px solid rgba(255,255,255,.2); font-size: 24px; color: #ccc; transition: all .5s; -webkit-transition: all .5s;}
+.site-download a:hover{border-color: rgba(255,255,255,.3); color: #fff; background-color: rgba(255,255,255,.05); border-radius: 30px;}
+.site-download a cite{position: absolute; left: 45px; font-size: 30px;}
+.site-version{position: relative; margin-top: 15px; color: #ccc; font-size: 12px;}
+.site-version span{padding: 0 3px;}
+.site-version *{font-style: normal;}
+.site-version a{color: #e2e2e2; text-decoration: underline;}
+
+.site-banner-other{position: absolute; left: 0; bottom: 30px; width: 100%; text-align: center; font-size: 0;}
+.site-banner-other iframe{border: none;}
+.site-banner-other a{display: inline-block; line-height: 28px; margin: 0 5px; padding: 0 8px; border-radius: 2px; color: rgba(255,255,255,.8); border: 1px solid rgba(255,255,255,.2); font-size: 14px; transition: all .5s; -webkit-transition: all .5s;}
+.site-banner-other a:hover{color: #fff; background-color: rgba(255,255,255,.1);}
+
+
+.site-idea{margin: 50px 0; font-size: 0; text-align: center; font-weight: 300;}
+.site-idea li{display: inline-block; vertical-align: top; *display: inline; *zoom:1; font-size: 14px; }
+.site-idea li{width: 298px; height: 150px; padding: 30px; line-height: 24px; margin-left: 30px; border: 1px solid #d2d2d2; text-align: left;}
+.site-idea li:first-child{margin-left: 0}
+.site-idea .layui-field-title{border-color: #d2d2d2}
+.site-idea .layui-field-title legend{margin: 0 20px 20px 0; padding: 0 20px; text-align: center;}
+
+
+/* 辅助 */
+.site-tips{margin-bottom: 10px; padding: 15px; line-height: 22px; border-left: 5px solid #0078AD; background-color: #f2f2f2;}
+body .site-tips p{margin: 0;}
+body .layui-layer-notice .layui-layer-content{padding: 20px; line-height: 26px; background-color: #393D49; color: #fff; font-weight: 300;}
+.layui-layer-notice .layui-text{color: #f8f8f8;}
+.layui-layer-notice .layui-text a{color: #009688;}
+
+/* 目录 */
+.site-dir{display: none;}
+.site-dir li{line-height: 26px; margin-left: 20px; overflow: visible; list-style-type: disc;}
+.site-dir li a{display: block;}
+.site-dir li a:active{color: #01AAED;}
+.site-dir li a.layui-this{color: #01AAED;}
+body .layui-layer-dir{box-shadow: none; border: 1px solid #d2d2d2;}
+body .layui-layer-dir .layui-layer-content{padding: 10px;}
+.site-dir a em{padding-left: 5px; font-size: 12px; color: #c2c2c2; font-style: normal;}
+
+/* 文档 */
+.site-tree{border-right: 1px solid #eee; }
+.site-tree .layui-tree{line-height: 32px;}
+.site-tree .layui-tree li i{position: relative; font-size: 22px; color: #000}
+.site-tree .layui-tree li a cite{padding: 0 8px;}
+.site-tree .layui-tree .site-tree-noicon a cite{padding-left: 15px;}
+.site-tree .layui-tree li a em{font-size: 12px; color: #bbb; padding-right: 5px; font-style: normal;}
+.site-tree .layui-tree li h2{line-height: 36px; border-left: 5px solid #009E94; margin: 15px 0 5px; padding: 0 10px; background-color: #f2f2f2;}
+.site-tree .layui-tree li ul{margin-left: 27px; line-height: 28px;}
+.site-tree .layui-tree li ul a,
+.site-tree .layui-tree li ul a i{color: #777;}
+.site-tree .layui-tree li ul a:hover{color: #333;}
+.site-tree .layui-tree li ul li{margin-left: 25px; overflow: visible; list-style-type: disc; /*list-style-position: inside;*/}
+.site-tree .layui-tree li ul li cite,
+.site-tree .layui-tree .site-tree-noicon ul li cite{padding-left: 0;}
+
+.site-tree .layui-tree .layui-this a{color: #01AAED;}
+.site-tree .layui-tree .layui-this .layui-icon{color: #01AAED;}
+
+.site-fix .site-tree{position: fixed; top: 0; bottom: 0; z-index: 666; min-height: 0; overflow: auto; background-color: #fff;}
+.site-fix .site-content{margin-left: 220px;}
+.site-fix-footer .site-tree{/*margin-bottom: 120px;*/}
+
+
+.site-title{ margin: 30px 0 20px;}
+.site-title fieldset{border: none; padding: 0; border-top: 1px solid #eee;}
+.site-title fieldset legend{margin-left: 20px; padding: 0 10px; font-size: 22px; font-weight: 300;}
+
+.site-text a{color: #01AAED;}
+.site-h1{margin-bottom: 20px; line-height: 60px; padding-bottom: 10px; color: #393D49; border-bottom: 1px solid #eee; font-size: 28px; font-weight: 300;}
+.site-h1 .layui-icon{position: relative; top: 5px; font-size: 50px; margin-right: 10px;}
+.site-text{position:relative;}
+.site-text p{margin-bottom: 10px; line-height:22px;}
+.site-text em{padding: 0 3px; font-weight: 500; font-style: italic; color: #666;}
+.site-text code{margin:0 5px; padding: 3px 10px; border: 1px solid #e2e2e2; background-color: #fbfbfb; color: #666; border-radius: 2px;}
+
+.site-table{width: 100%; margin: 10px 0;}
+.site-table thead{background-color:#f2f2f2; }
+.site-table th,
+.site-table td{padding: 6px 15px; min-height: 20px; line-height: 20px; border:1px solid #ddd; font-size: 14px; font-weight: 400;}
+.site-table tr:nth-child(even){background: #fbfbfb;}
+
+.site-block{padding: 20px; border: 1px solid #eee;}
+.site-block .layui-form{margin-right: 200px;}
+
+/* 更新日志 */
+.site-changelog .layui-timeline-title h2{display: inline-block;}
+.site-changelog .layui-timeline-title .layui-badge-rim{top: -2px; left: 10px;}
+
+/* 颜色 */
+.site-doc-color{font-size: 0;}
+.site-doc-color li{display: inline-block; vertical-align: middle; width: 180px; margin-left: 20px; margin-bottom: 20px; padding: 20px 10px; color: #fff; text-align: center; border-radius: 2px; line-height: 22px; font-size: 14px;}
+.site-doc-color li p[tips]{opacity: 0.8; font-size: 12px;}
+
+.site-doc-necolor li{width: 108px; margin-top: 15px; margin-left: 0; border-radius: 0;}
+
+.site-doc-bgcolor li{padding: 10px;}
+
+/* 宫格 */
+.site-doc-icon{margin-bottom: 50px; font-size: 0;}
+.site-doc-icon li{display: inline-block; vertical-align: middle; width: 127px; line-height: 25px; padding: 20px 0; margin-right: -1px; margin-bottom: -1px; border: 1px solid #e2e2e2; font-size: 14px; text-align: center; color: #666; transition: all .3s; -webkit-transition: all .3s;}
+.site-doc-icon li .layui-icon{display: inline-block; font-size: 36px;}
+
+.site-doc-icon li .fontclass{display: none;}
+.site-doc-icon li .name{color: #c2c2c2;}
+.site-doc-icon li:hover{background-color: #f2f2f2; color: #000;}
+
+/* 栅格示例 */
+.grid-demo{padding: 10px; line-height: 25px; text-align: center; background-color: #79C48C; color: #fff;margin-top:15px;}
+.grid-demo-bg1{background-color: #63BA79;}
+.grid-demo-bg2{background-color: #49A761;}
+.grid-demo-bg3{background-color: #38814A;}
+/* 演示 */
+body .layui-layout-admin .site-demo{bottom: 60px; padding: 0;}
+body .site-demo-nav .layui-nav-item{line-height: 40px}
+.layui-nav-item .layui-icon{position: relative; font-size: 20px;}
+.layui-nav-item a cite{padding: 0 10px;}
+.site-demo .layui-main{margin: 15px; line-height: 22px;}
+.site-demo-editor{position: absolute; top: 0; bottom: 0; left: 0; width: 50%; }
+.site-demo-area{position: absolute; top: 0; bottom: 0; width: 100%;}
+.site-demo-editor textarea{position: absolute; width: 100%; height: 100%; padding: 10px; border: none; resize: none; background-color: #F7FBFF; background-color: #13151A; color: #999; font-family: Courier New; font-size: 12px; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}
+.site-demo-btn{position: absolute; bottom: 15px; right: 20px;}
+.site-demo-zanzhu{position: absolute; bottom: 0; left: 0; width: 100%; height: 90px; text-align: center; background-color: #e2e2e2; overflow: hidden;}
+.site-demo-zanzhu>*{position: relative; z-index: 1;}
+.site-demo-zanzhu:before{content: ""; position: absolute; z-index: 0; top: 50%; left: 50%; width: 120px; margin: -10px 0px 0px -60px; text-align: center; color: rgb(170, 170, 170); font-size: 18px; font-weight: 300; }
+
+.site-demo-result{position: absolute; right: 0; top: 0; bottom: 0; width: 50%;}
+.site-demo-result iframe{position: absolute; width: 100%; height: 100%;}
+
+.site-demo-button{margin-bottom: 30px;}
+.site-demo-button div{margin: 20px 30px 10px;}
+.site-demo-button .layui-btn+.layui-btn{margin-left: 0;}
+.site-demo-button .layui-btn{margin: 0 7px 10px 0; }
+
+.site-demo-text a{color: #01AAED;}
+
+
+.site-demo-laytpl{text-align: center;}
+.site-demo-laytpl textarea,
+.site-demo-laytpl div span{width: 40%; padding: 15px; margin: 0 15px;}
+.site-demo-laytpl textarea{height: 300px; border: none; background-color: #3F3F3F; color: #E3CEAB; font-family: Courier New; resize: none;}
+.site-demo-laytpl div span{display: inline-block; text-align: center; background: #101010; color: #fff;}
+.site-demo-tplres{margin: 10px 0; text-align: center}
+.site-demo-tplres .site-demo-tplh2,
+.site-demo-tplres .site-demo-tplview{display: inline-block; width: 50%;}
+.site-demo-tplres h2{padding: 15px; background: #e2e2e2;}
+.site-demo-tplres h3{font-weight: 700;}
+.site-demo-tplres div{padding: 14px; border: 1px solid #e2e2e2; text-align: left;}
+
+.site-demo-upload,
+.site-demo-upload img{width: 200px; height: 200px; border-radius: 100%;}
+.site-demo-upload{position: relative; background: #e2e2e2;}
+.site-demo-upload .site-demo-upbar{position: absolute; top: 50%; left: 50%; margin: -18px 0 0 -56px;}
+.site-demo-upload .layui-upload-button{background-color: rgba(0,0,0,.2); color: rgba(255,255,255,1);}
+
+.site-demo-util{position: relative; width: 300px;}
+.site-demo-util img{width: 300px; border-radius: 100%;}
+.site-demo-util span{position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: #333; cursor: pointer;}
+@-webkit-keyframes demo-fengjie {
+ 0% {-webkit-filter: blur(0); opacity: 1; background: #fff; height: 300px; border-radius: 100%;}
+ 80% {-webkit-filter: blur(50px); opacity: 0.95;}
+ 100% {-webkit-filter: blur(20px); opacity: 0; background: #fff;}
+}
+@keyframes demo-fengjie {
+ 0% {filter: blur(0); opacity: 1; background: #fff; height: 300px; border-radius: 100%;}
+ 80% {filter: blur(50px); opacity: 0.95;}
+ 100% {filter: blur(20px); opacity: 0; background: #fff;}
+}
+.site-demo-fengjie{-webkit-animation-name: demo-fengjie; animation-name: demo-fengjie; -webkit-animation-duration: 5s; animation-duration: 5s;}
+
+.layui-layout-admin .site-demo-body{top: 106px;}
+.site-demo-title{position: fixed; left: 200px; right: 0; top: 65px;}
+.site-demo-code{position: absolute; left: 0; top: 0; width: 100%; height: 100%; border: none; padding: 10px; resize: none; font-size: 12px; background-color: #F7FBFF; color: #881280; font-family: Courier New;}
+
+.site-demo-overflow{overflow: hidden;}
+
+/* 其它 */
+#trans-tooltip,
+#tip-arrow-bottom,
+#tip-arrow-top{display: none !important;}
+
+
+/* 独立组件 */
+.alone{text-align: center; background-color: #009688; color: #fff; font-weight: 300; transition: all .3s; -webkit-transition: all .3s;}
+.alone:hover{background-color: #5FB878;}
+.alone a{display: block; padding: 50px 20px; color: #fff; font-size: 30px;}
+.alone a cite{display: block; padding-top: 10px; font-size: 14px;}
+
+/* 适配多设备 */
+@media screen and (max-width: 750px) {
+ .layui-main{width: auto; margin: 0 10px;}
+ .logo,
+ .header-demo .logo{left: 10px;}
+ .component{display: none}
+
+ .site-demo-overflow{overflow: auto;}
+
+ .site-nav-layim{display: none !important;}
+ .header .layui-nav .layui-nav-item{margin: 0;}
+ .header .layui-nav .layui-nav-item a{padding: 0 20px;}
+ .header .layui-nav .layui-nav-item[pc]{display: none;}
+ .header .layui-nav .layui-nav-item[mobile]{display: inline-block;}
+ .site-banner{height: 300px;}
+ .site-banner-bg{background-size: cover;}
+ .site-zfj{height: 100px; padding-top: 5px;}
+ .site-zfj i{top: 10px; width: 100px; height: 100px; margin-left: -50px; font-size: 100px;}
+ .site-desc{background-size: 70%; margin: 0;}
+ .site-desc cite{display: none;}
+ .site-download{margin-top: 0; }
+ .site-download a{height: 40px; line-height: 40px; padding: 0 25px 0 60px; border-radius: 30px; color: #fff; font-size: 16px;}
+ .site-download a cite{left: 20px;}
+ .site-banner-other{bottom: 10px;}
+
+ .site-idea{margin: 20px 0;}
+ .site-idea li{margin: 0 0 20px 0; width: 100%; height: auto; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}
+ .site-hengfu img{max-width: 100%}
+
+ .site-block .layui-form{margin-right: 0;}
+
+ .layui-layer-dir{display: none;}
+ .site-tree{position: fixed; top: 0; bottom: 0; min-height: 0; overflow: auto; z-index: 1000; left: -260px; background-color: #fff; transition: all .3s; -webkit-transition: all .3s;}
+ .site-content{width: 100%; padding: 0; overflow: auto;}
+ .site-content img{max-width: 100%;}
+ .site-tree-mobile{display: block!important; position: fixed; z-index: 100000; bottom: 15px; left: 15px; width: 50px; height: 50px; line-height: 50px; border-radius: 2px; text-align: center; background-color: rgba(0,0,0,.7); color: #fff;}
+ .site-home .site-tree-mobile{display: none!important;}
+ .site-mobile .site-tree-mobile{display: none !important;}
+ .site-mobile .site-tree{left: 0;}
+ .site-mobile .site-mobile-shade{content: ''; position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0,0,0,.8); z-index: 999;}
+ .site-tree-mobile i{font-size: 20px;}
+ .layui-code-view{-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;}
+
+ .layui-layout-admin .layui-side{position: fixed; top: 0; left: -260px; transition: all .3s; -webkit-transition: all .3s; z-index: 10000;}
+ .layui-body{position: static; bottom: 0; left: 0;}
+ .site-mobile .layui-side{left: 0;}
+ body .layui-layout-admin .footer-demo{position: static; height: auto; line-height: 30px;}
+ .footer-demo p{height: auto;}
+
+ .site-demo-area,
+ .site-demo-editor,
+ .site-demo-result,
+ .site-demo-editor textarea,
+ .site-demo-result iframe{position: static; width: 100%;}
+ .site-demo-editor textarea{height: 350px;}
+ .site-demo-zanzhu{display: none;}
+ .site-demo-btn{bottom: auto; top: 370px;}
+ .site-demo-result iframe{height: 500px;}
+
+ .site-demo-laytpl textarea, .site-demo-laytpl div span{margin: 0;}
+ .site-demo-tplres .site-demo-tplh2, .site-demo-tplres .site-demo-tplview{width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;}
+
+ .site-demo-title{position: static; left: 0;}
+ body .layui-layout-admin .site-demo{}
+ .site-demo-code{position: static; height: 350px;}
+}
+.layui-btn-normal {
+ background-color: #79C48C;
+}
+.mt15{margin-top: 15px;}
+.btncolor{background: #79C48C}
+.laypagecenter{width: 400px;margin: 0 auto;}
+
+
diff --git a/src/main/resources/static/css/login.css b/src/main/resources/static/css/login.css
new file mode 100644
index 0000000..8ac7b97
--- /dev/null
+++ b/src/main/resources/static/css/login.css
@@ -0,0 +1,92 @@
+.beg-login-bg {
+ background: url(../Images/login-bg-1.jpg) no-repeat center center fixed;
+ background-color: #393D49;
+}
+
+.beg-login-box {
+ width: 450px;
+ height: 330px;
+ margin: 10% auto;
+ background-color: rgba(255, 255, 255, 0.407843);
+ border-radius: 10px;
+ color: aliceblue;
+}
+
+.beg-login-box header {
+ height: 39px;
+ padding: 10px;
+ border-bottom: 1px solid aliceblue;
+}
+
+.beg-login-box header h1 {
+ text-align: center;
+ font-size: 25px;
+ line-height: 40px;
+}
+
+.beg-login-box .beg-login-main {
+ height: 185px;
+ padding: 30px 90px 0;
+}
+
+.beg-login-main .layui-form-item {
+ position: relative;
+}
+
+.beg-login-main .layui-form-item .beg-login-icon {
+ position: absolute;
+ color: #cccccc;
+ top: 10px;
+ left: 10px;
+}
+
+.beg-login-main .layui-form-item input {
+ padding-left: 34px;
+}
+
+.beg-login-box footer {
+ height: 35px;
+ padding: 10px 10px 0 10px;
+}
+
+.beg-login-box footer p {
+ line-height: 35px;
+ text-align: center;
+}
+
+.beg-pull-left {
+ float: left !important;
+}
+
+.beg-pull-right {
+ float: right !important;
+}
+
+.beg-clear {
+ clear: both;
+}
+
+.beg-login-remember {
+ line-height: 38px;
+}
+
+.beg-login-remember .layui-form-switch {
+ margin-top: 0px;
+}
+
+.beg-login-code-box {
+ position: relative;
+ padding: 10px;
+}
+
+.beg-login-code-box input {
+ position: absolute;
+ width: 100px;
+}
+
+.beg-login-code-box img {
+ cursor: pointer;
+ position: absolute;
+ left: 115px;
+ height: 38px;
+}
\ No newline at end of file
diff --git a/src/main/resources/static/css/webuploader.css b/src/main/resources/static/css/webuploader.css
new file mode 100644
index 0000000..12f451f
--- /dev/null
+++ b/src/main/resources/static/css/webuploader.css
@@ -0,0 +1,28 @@
+.webuploader-container {
+ position: relative;
+}
+.webuploader-element-invisible {
+ position: absolute !important;
+ clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
+ clip: rect(1px,1px,1px,1px);
+}
+.webuploader-pick {
+ position: relative;
+ display: inline-block;
+ cursor: pointer;
+ background: #00b7ee;
+ padding: 10px 15px;
+ color: #fff;
+ text-align: center;
+ border-radius: 3px;
+ overflow: hidden;
+}
+.webuploader-pick-hover {
+ background: #00a2d4;
+}
+
+.webuploader-pick-disable {
+ opacity: 0.6;
+ pointer-events:none;
+}
+
diff --git a/src/main/resources/static/js/1.js b/src/main/resources/static/js/1.js
new file mode 100644
index 0000000..efe62d9
--- /dev/null
+++ b/src/main/resources/static/js/1.js
@@ -0,0 +1,1606 @@
+layui.define(['jquery', 'layer','contextMenu','form'], function (exports) {
+ var contextMenu = layui.contextMenu;
+ var $ = layui.jquery;
+ var layer = layui.layer;
+ var form = layui.form;
+ var cachedata = layui.layim.cache();
+
+ var conf = {
+ uid: 0, //
+ key: '', //
+ layim: null,
+ token: null,
+ };
+
+ var conn = new WebIM.connection({
+ isMultiLoginSessions: WebIM.config.isMultiLoginSessions,
+ https: typeof WebIM.config.https === 'boolean' ? WebIM.config.https : location.protocol === 'https:',
+ url: WebIM.config.xmppURL,
+ heartBeatWait: WebIM.config.heartBeatWait,
+ autoReconnectNumMax: WebIM.config.autoReconnectNumMax,
+ autoReconnectInterval: WebIM.config.autoReconnectInterval,
+ apiUrl: WebIM.config.apiURL,
+ isAutoLogin: true
+ });
+ var socket = {
+ config: function (options) {
+ conf = $.extend(conf, options); //把layim继承出去,方便在register中使用
+ this.register();
+ im.init(options.user,options.pwd);
+ },
+ register: function () {
+ var layim = conf.layim;
+ if (layim) {
+ //监听在线状态的切换事件
+ layim.on('online', function (data) {
+ console.log('在线状态'+data);
+ });
+ //监听签名修改
+ layim.on('sign', function (value) {
+ $.post('class/doAction.php?action=change_sign', {sign: value}, function (data) {
+ console.log('签名修改'+data);
+ });
+ });
+ //监听layim建立就绪
+ layim.on('ready', function (res) {
+ if (cachedata.mine.msgBox != 0) {
+ layim.msgbox(cachedata.mine.msgBox); //消息盒子有新消息
+ };
+ im.contextMenu();
+ });
+
+ //监听查看群员
+ layim.on('members', function (data) {
+ });
+
+ $('body').on('click', '*[socket-event]', function(e){//自定义事件
+ var othis = $(this), methid = othis.attr('socket-event');
+ im[methid] ? im[methid].call(this, othis, e) : '';
+ });
+ //监听聊天窗口的切换
+ layim.on('chatChange', function (res) {
+ im.closeAllGroupList();
+ var type = res.data.type;
+ if (type === 'friend') {
+ //模拟标注好友状态
+ im.userStatus({
+ id: res.data.id
+ });
+ } else if (type === 'group') {
+ var _time = (new Date()).valueOf();//当前时间
+ if (parseInt(res.data.gagTime) > _time) {
+ im.setGag({
+ groupidx: res.data.id,
+ type: 'set',
+ user: cachedata.mine.id,
+ gagTime: ''
+ });
+ }
+ }
+ });
+ layim.on('sendMessage', function (data) { //监听发送消息
+ data.to.cmd = 0;
+ if (data.to.type == 'friend') {
+ im.sendMsg(data);
+ }else{
+ var _time = (new Date()).valueOf();//当前时间
+ var gagTime = parseInt(layui.layim.thisChat().data.gagTime);
+ if (gagTime < _time) {
+ im.sendMsg(data);
+ }else{
+ im.popMsg(data,'当前为禁言状态,消息未发送成功!');
+ return false;
+ }
+ }
+ });
+ }
+ }
+ };
+
+ // var ext = {
+
+ // }
+
+ var im = {
+ init: function (user,pwd) {
+ this.initListener(user,pwd); //初始化事件监听
+ },
+ contextMenu : function(){//定义右键操作
+ var my_spread = $('.layim-list-friend >li');
+ my_spread.mousedown(function(e){
+ var data = {
+ contextItem: "context-friend", // 添加class
+ target: function(ele) { // 当前元素
+ $(".context-friend").attr("data-id",ele[0].id.replace(/[^0-9]/ig,"")).attr("data-name",ele.find("span").html());
+ $(".context-friend").attr("data-img",ele.find("img").attr('src')).attr("data-type",'friend');
+ },
+ menu:[]
+ };
+ data.menu.push(im.menuChat());
+ data.menu.push(im.menuInfo());
+ data.menu.push(im.menuChatLog());
+ data.menu.push(im.menuNickName());
+ var currentGroupidx = $(this).find('h5').data('groupidx');//当前分组id
+ if(my_spread.length >= 2){ //当至少有两个分组时
+ var html = '';
+ for (var i = 0; i < my_spread.length; i++) {
+ var groupidx = my_spread.eq(i).find('h5').data('groupidx');
+ if (currentGroupidx != groupidx) {
+ var groupName = my_spread.eq(i).find('h5 span').html();
+ html += ''
+ };
+ };
+ html += ' ';
+ data.menu.push(im.menuMove(html));
+ }
+ data.menu.push(im.menuRemove());
+ $(".layim-list-friend >li > ul > li").contextMenu(data);//好友右键事件
+ });
+
+ $(".layim-list-friend >li > h5").mousedown(function(e){
+ var data = {
+ contextItem: "context-mygroup", // 添加class
+ target: function(ele) { // 当前元素
+ $(".context-mygroup").attr("data-id",ele.data('groupidx')).attr("data-name",ele.find("span").html());
+ },
+ menu: []
+ };
+ data.menu.push(im.menuAddMyGroup());
+ data.menu.push(im.menuRename());
+ if ($(this).parent().find('ul li').data('index') !== 0) {data.menu.push(im.menuDelMyGroup()); };
+
+ $(this).contextMenu(data); //好友分组右键事件
+ });
+
+
+ $(".layim-list-group > li").mousedown(function(e){
+ var data = {
+ contextItem: "context-group", // 添加class
+ target: function(ele) { // 当前元素
+ $(".context-group").attr("data-id",ele[0].id.replace(/[^0-9]/ig,"")).attr("data-name",ele.find("span").html())
+ .attr("data-img",ele.find("img").attr('src')).attr("data-type",'group')
+ },
+ menu: []
+ };
+ layer.msg(123)
+ data.menu.push(im.menuChat());
+ data.menu.push(im.menuInfo());
+ data.menu.push(im.menuChatLog());
+ data.menu.push(im.menuLeaveGroupBySelf());
+
+ $(this).contextMenu(data); //面板群组右键事件
+ });
+
+
+ $('.groupMembers > li').mousedown(function(e){//聊天页面群组右键事件
+ var data = {
+ contextItem: "context-group-member", // 添加class
+ isfriend: $(".context-group-member").data("isfriend"), // 添加class
+ target: function(ele) { // 当前元素
+ $(".context-group-member").attr("data-id",ele[0].id.replace(/[^0-9]/ig,""));
+ $(".context-group-member").attr("data-img",ele.find("img").attr('src'));
+ $(".context-group-member").attr("data-name",ele.find("span").html());
+ $(".context-group-member").attr("data-isfriend",ele.attr('isfriend'));
+ $(".context-group-member").attr("data-manager",ele.attr('manager'));
+ $(".context-group-member").attr("data-groupidx",ele.parent().data('groupidx'));
+ $(".context-group-member").attr("data-type",'friend');
+ },
+ menu:[]
+ };
+ var _this = $(this);
+ var groupInfo = conf.layim.thisChat().data;
+ var _time = (new Date()).valueOf();//当前时间
+ var _gagTime = parseInt(_this.attr('gagTime'));//当前禁言时间
+ if (cachedata.mine.id !== _this.attr('id')) {
+ data.menu.push(im.menuChat());
+ data.menu.push(im.menuInfo());
+ if(3 == e.which && $(this).attr('isfriend') == 0 ){ //点击右键并且不是好友
+ data.menu.push(im.menuAddFriend())
+ }
+ }else{
+ data.menu.push(im.menuEditGroupNickName());
+ }
+ if (groupInfo.manager == 1 && cachedata.mine.id !== _this.attr('id')) {//是群主且操作的对象不是自己
+ if (_this.attr('manager') == 2) {
+ data.menu.push(im.menuRemoveAdmin());
+ }else if (_this.attr('manager') == 3) {
+ data.menu.push(im.menuSetAdmin());
+ }
+ data.menu.push(im.menuEditGroupNickName());
+ data.menu.push(im.menuLeaveGroup());
+ if (_gagTime < _time) {
+ data.menu.push(im.menuGroupMemberGag());
+ }else{
+ data.menu.push(im.menuLiftGroupMemberGag());
+ }
+ }//群主管理
+
+ layui.each(cachedata.group, function(index, item){
+ if (item.id == _this.parent().data('groupidx') && item.manager == 2 && _this.attr('manager') == 3 && cachedata.mine.id !== _this.attr('id')) {//管理员且操作的是群员
+ data.menu.push(im.menuEditGroupNickName());
+ data.menu.push(im.menuLeaveGroup());
+ if (_gagTime < _time) {
+ data.menu.push(im.menuGroupMemberGag());
+ }else{
+ data.menu.push(im.menuLiftGroupMemberGag());
+ }
+ }//管理员管理
+ })
+ $(".groupMembers > li").contextMenu(data);
+ })
+
+
+ },
+ initListener: function (user,pwd) { //初始化监听
+ // console.log('注册服务连接监听事件');
+ // var layim = conf.layim;
+ var options = {
+ apiUrl: WebIM.config.apiURL,
+ user: user,
+ pwd: pwd,
+ appKey: WebIM.config.appkey
+ };
+ conn.open(options);
+ conn.listen({
+ onOpened: function ( message ) {
+ //连接成功回调
+ // 如果isAutoLogin设置为false,那么必须手动设置上线,否则无法收消息
+ // 手动上线指的是调用conn.setPresence(); 如果conn初始化时已将isAutoLogin设置为true
+ // 则无需调用conn.setPresence();
+ },
+ onClosed: function ( message ) {
+ layer.alert('该账号已在别处登陆,是否重新登陆?', {
+ skin: 'layui-layer-molv' //样式类名
+ ,closeBtn: 0
+ }, function(){
+ window.location.href = 'login.php';
+ });
+ }, //连接关闭回调
+ onTextMessage: function ( message ) {
+ im.defineMessage(message,'Text');
+ }, //收到文本消息
+ onEmojiMessage: function ( message ) {}, //收到表情消息
+ onPictureMessage: function ( message ) {
+ im.defineMessage(message,'Picture');
+ }, //收到图片消息
+ onCmdMessage: function ( message ) {}, //收到命令消息
+ onAudioMessage: function ( message ) {
+ var options = { url: message.url };
+ options.onFileDownloadComplete = function ( response ) {
+ //音频下载成功,需要将response转换成blob,使用objectURL作为audio标签的src即可播放。
+ var objectURL = WebIM.utils.parseDownloadResponse.call(conn, response);
+ message.audio = objectURL;
+ im.defineMessage(message,'Audio');
+ };
+
+ options.onFileDownloadError = function () {
+ //音频下载失败
+ };
+ //通知服务器将音频转为mp3
+ options.headers = {
+ 'Accept': 'audio/mp3'
+ };
+ WebIM.utils.download.call(conn, options);
+
+ }, //收到音频消息
+ onLocationMessage: function ( message ) {},//收到位置消息
+ onFileMessage: function ( message ) {
+ im.defineMessage(message,'File');
+ }, //收到文件消息
+ onVideoMessage: function (message) {
+ var options = { url: message.url };
+ options.onFileDownloadComplete = function ( response ) {
+ //音频下载成功,需要将response转换成blob,使用objectURL作为audio标签的src即可播放。
+ var objectURL = WebIM.utils.parseDownloadResponse.call(conn, response);
+ message.video = objectURL;
+ im.defineMessage(message,'Video');
+ };
+ options.onFileDownloadError = function () {
+ //音频下载失败
+ };
+ //通知服务器将音频转为mp4
+ options.headers = {
+ 'Accept': 'audio/mp4'
+ };
+ WebIM.utils.download.call(conn, options);
+ }, //收到视频消息
+ onPresence: function ( message ) {//监听对方的添加或者删除好友请求,并做相应的处理。
+ if (message.type == 'unsubscribe') {
+
+ conf.layim.removeList({//从我的列表删除
+ type: 'friend' //或者group
+ ,id: message.from //好友或者群组ID
+ });
+ im.removeHistory({//从我的列表删除
+ type: 'friend' //或者group
+ ,id: username //好友或者群组ID
+ });
+ parent.location.reload();
+ }else if(message.type =='subscribe'){//收到添加请求
+ im.audio('新');
+ }else if(message.type =='subscribed'){//对方通过了你的好友请求
+ if (message.to == cachedata.mine.id && message.status =='Success') {
+ im.audio('新');
+ $.get('class/doAction.php?action=subscribed',{memberIdx:message.from},function(res){
+ var data = eval('(' + res + ')');
+ conf.layim.addList({
+ type: 'friend' //列表类型,只支持friend和group两种
+ ,avatar: './uploads/person/'+message.from +'.jpg' //好友头像
+ ,username: data.data.memberName || [] //好友昵称
+ ,groupid: data.data.mygroupIdx //所在的分组id
+ ,id: data.data.memberIdx || [] //好友id
+ ,sign: data.data.signature || [] //好友签名
+ });
+ im.contextMenu();//更新右键点击事件
+ })
+ };
+
+ }else if (message.type == 'unsubscribed') {//拒绝好友申请
+ if (message.to == cachedata.mine.id && message.status =='rejectAddFriend') {
+ im.audio('新');
+ };
+ }else if(message.type == 'joinGroupNotifications'){//群管理收到加群申请 将该管理员加入消息组
+ console.log(message);
+ $.get('class/doAction.php?action=add_admin_msg', {from: message.from,adminGroup: message.to,to: message.gid}, function (res) {
+ // var data = eval('(' + res + ')');
+ // if (data.code == 0) {
+ // layer.msg('你申请加入'+message.toNick+'的消息已发送。请等待管理员确认');
+ // }else{
+ // layer.msg('你申请加入'+message.toNick+'的消息发送失败。请刷新浏览器后重试');
+ // }
+ });
+ im.audio('新');
+ }else if(message.type == 'memberJoinPublicGroupSuccess'){
+ // $.get('class/doAction.php?action=get_one_user_data',{memberIdx:message.mid},function(res){
+ // var data = eval('(' + res + ')');
+ // conf.layim.addList({
+ // type: 'group' //列表类型,只支持friend和group两种
+ // ,avatar: './uploads/person/'+message.mid +'.jpg' //好友头像
+ // ,groupname: data.data.memberName || [] //好友昵称
+ // ,id: message.from //群组id
+ // });
+ // im.contextMenu();//更新右键点击事件
+ // })
+ }else if(message.type == 'joinPublicGroupSuccess'){
+ im.audio('新');
+ var default_avatar = './uploads/person/empty1.jpg';
+ var avatar = './uploads/person/'+message.from+'.jpg';
+ var options = {
+ groupId: message.from,
+ success: function(resp){
+ console.log(resp);
+ conf.layim.addList({
+ type: 'group' //列表类型,只支持friend和group两种
+ ,avatar: im['IsExist'].call(this, avatar)?avatar:default_avatar //群头像
+ ,groupname: resp.data[0].name || [] //群名称
+ ,id: resp.data[0].id //群组id
+ });
+ im.contextMenu();//更新右键点击事件
+ },
+ error: function(){}
+ };
+ conn.getGroupInfo(options);
+ }else if (message.type == 'addAdmin') {
+ if ($("ul[data-groupidx="+message.from+"] #"+message.to).html()) {
+ $("ul[data-groupidx="+message.from+"] #"+message.to).remove();
+ var html = ''+cachedata.mine.username+'('+cachedata.mine.id+' ) '
+ $("ul[data-groupidx="+message.from+"]").find('li').eq(0).after(html);
+ layui.each(cachedata.group, function(index, item){
+ if (item.id == message.from && item.manager == 3 && cachedata.mine.id == message.to) {
+ cachedata.group[index].manager = 2;
+ }//群主管理
+ });
+ im.contextMenu();//更新右键点击事件
+ }
+ $.get('class/doAction.php?action=get_one_group_data',{groupIdx:message.from},function(res){
+ var data = eval('(' + res + ')');
+ layer.open({
+ type: 1,
+ shade: false,
+ title: false, //不显示标题
+ content: '你已成为群 '+ data.data.groupName+ '('+ message.from + ') 的管理员,快去看看吧!
'
+ });
+ });
+
+
+ }else if (message.type == 'removeAdmin') {
+ if ($("ul[data-groupidx="+message.from+"] #"+message.to).html()) {
+ $("ul[data-groupidx="+message.from+"] #"+message.to).remove();
+ var html = ''+cachedata.mine.username+'('+cachedata.mine.id+' ) '
+ $("ul[data-groupidx="+message.from+"]").append(html);
+ layui.each(cachedata.group, function(index, item){
+ if (item.id == message.from && item.manager == 2 && cachedata.mine.id == message.to) {
+ cachedata.group[index].manager = 3;
+ }//群主管理
+ });
+ im.contextMenu();//更新右键点击事件
+ }
+ $.get('class/doAction.php?action=get_one_group_data',{groupIdx:message.from},function(res){
+ var data = eval('(' + res + ')');
+ layer.open({
+ type: 1,
+ shade: false,
+ title: false, //不显示标题
+ content: '你已被群 '+ data.data.groupName + '('+ message.from + ') 撤消管理员。
'
+ });
+ });
+ }
+ },//处理“广播”或“发布-订阅”消息,如联系人订阅请求、处理群组、聊天室被踢解散等消息
+ onRoster: function ( message ) {
+ console.log('处理“广播”');
+ if (message[0].subscription == 'to' && message[0].ask == 'subscribe') {
+ $.get('class/doAction.php?action=get_one_user_data',{memberIdx:message[0].name},function(res){
+ var data = eval('(' + res + ')');
+ layer.msg('你申请添加 '+data.data.memberName+' 为好友的消息已发送。请等待对方确认');
+
+ });
+ }
+ }, //处理好友申请
+ onInviteMessage: function ( message ) {
+ console.log('处理群组邀请');
+ }, //处理群组邀请
+ onOnline: function () {}, //本机网络连接成功
+ onOffline: function () {
+ layer.alert('网络不稳定,点击确认刷新页面?', {
+ skin: 'layui-layer-molv' //样式类名
+ ,closeBtn: 0
+ }, function(){
+ window.location.href = 'index.php';
+ });
+ }, //本机网络掉线
+ onError: function ( message ) {}, //失败回调
+ onBlacklistUpdate: function (list) { //黑名单变动
+ // 查询黑名单,将好友拉黑,将好友从黑名单移除都会回调这个函数,list则是黑名单现有的所有好友信息
+ console.log(list);
+ },
+ onReceivedMessage: function(message){}, //收到消息送达服务器回执
+ onDeliveredMessage: function(message){}, //收到消息送达客户端回执
+ onReadMessage: function(message){}, //收到消息已读回执
+ onCreateGroup: function(message){}, //创建群组成功回执(需调用createGroupNew)
+ onMutedMessage: function(message){} //如果用户在A群组被禁言,在A群发消息会走这个回调并且消息不会传递给群其它成员
+ });
+
+ },
+ //自定义消息,把消息格式定义为layim的消息类型
+ defineMessage: function (message,msgType) {
+ var msg;
+ switch (msgType)
+ {
+ case 'Text': msg = message.data;break;
+ case 'Picture': msg = 'img['+message.thumb+']';break;
+ case 'Audio': msg = 'audio['+message.audio+']';break;
+ case 'File': msg = 'file('+message.url+')['+message.filename+']';break;
+ case 'Video': msg = 'video['+message.video+']';break;
+ };
+ if (message.ext.cmd) {//如果有命令参数
+
+ switch (message.ext.cmd.cmdName)
+ {
+ case 'gag': //禁言
+ im.setGag({
+ groupidx: message.to,
+ type: 'set',
+ user: message.ext.cmd.id,
+ gagTime: message.data
+ });
+ break;
+ case 'liftGag': //取消禁言
+ im.setGag({
+ groupidx: message.to,
+ type: 'lift',
+ user: message.ext.cmd.id,
+ gagTime: 0
+ });
+ break;
+ // case 'setGag': //禁言
+ // case 'joinGroup': //取消禁言
+ // case 'joinGroup': //加入群
+ // case 'leaveGroup': //退出群
+ // case 'setAdmin': //设置管理员
+ // case 'removeAdmin': //取消管理员
+ // break;
+ default:
+ conf.layim.getMessage({
+ system: true //系统消息
+ ,id: message.to //聊天窗口ID
+ ,type: "group" //聊天窗口类型
+ ,content: msg
+ });
+ };
+ };
+ if (message.type == 'chat') {
+ var type = 'friend';
+ var id = message.from;
+ }else if(message.type == 'groupchat'){
+ var type = 'group';
+ var id = message.to;
+ }
+ if (message.delay) {//离线消息获取不到本地cachedata用户名称需要从服务器获取
+ var timestamp = Date.parse(new Date(message.delay));
+ }else{
+ var timestamp = (new Date()).valueOf();
+ }
+ var data = {mine: false,cid: 0,username:message.ext.username,avatar:"./uploads/person/"+message.from+".jpg",content:msg,id:id,fromid: message.from,timestamp:timestamp,type:type}
+ if (!message.ext.cmd) {conf.layim.getMessage(data); };
+
+ },
+ sendMsg: function (data) { //根据layim提供的data数据,进行解析
+ var id = conn.getUniqueId();
+ var content = data.mine.content;
+ var msg = new WebIM.message('txt', id); // 创建文本消息
+
+ msg.set({
+ msg: data.mine.content,
+ to: data.to.id, // 接收消息对象(用户id)
+ roomType: false,
+ success: function (id, serverMsgId) {//发送成功则记录信息到服务器
+ var sendData = {to:data.to.id,content:data.mine.content,sendTime: data.mine.timestamp,type:data.to.type};
+
+ if (data.to.cmd && (data.to.cmd.cmdName == 'leaveGroup' || data.to.cmd.cmdName == 'joinGroup')) {
+ sendData.sysLog = true;
+ }
+ if ((data.to.cmd && sendData.sysLog) || data.to.cmd == 0) {
+ $.get('class/doAction.php?action=addChatLog', sendData, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code != 0) {
+ console.log('message record fail');
+ }
+ });
+ }
+ },
+ fail: function(e){//发送失败移除发送消息并提示发送失败
+ im.popMsg(data,'发送失败 刷新页面试试!');
+ }
+ });
+ if (data.to.id == data.mine.id) {
+ layer.msg('不能给自己发送消息');
+ return;
+ }
+ if (data.to.cmd) {
+ msg.body.ext.cmd = data.to.cmd;
+ }
+ msg.body.ext.username = cachedata.mine.username;
+ if (data.to.type == 'group') {
+ msg.setGroup('groupchat');
+ msg.body.chatType = 'chatRoom';
+ }else{
+ msg.body.chatType = 'singleChat';
+ }
+ conn.send(msg.body);
+ },
+ removeFriends: function (username) {
+ conn.removeRoster({
+ to: username,
+ success: function () { // 删除成功
+ $.get('class/doAction.php?action=removeFriends', {friend_id: username}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ var index = layer.open();
+ layer.close(index);
+ conf.layim.removeList({//从我的列表删除
+ type: 'friend' //或者group
+ ,id: username //好友或者群组ID
+ });
+ im.removeHistory({//从我的历史列表删除
+ type: 'friend' //或者group
+ ,id: username //好友或者群组ID
+ });
+ parent.location.reload();
+ }else{
+ layer.msg(data.msg);
+ }
+ });
+
+
+ },
+ error: function () {
+ console.log('removeFriends faild');
+ // 删除失败
+ }
+ });
+ },
+ leaveGroupBySelf: function (to,username,roomId) {
+ $.get('class/doAction.php?action=leaveGroup', {groupIdx:roomId,memberIdx:to}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ var option = {
+ to: to,
+ roomId: roomId,
+ success: function (res) {
+ im.sendMsg({//系统消息
+ mine:{
+ content:username+' 已退出该群',
+ timestamp:new Date().getTime()
+ },
+ to:{
+ id:roomId,
+ type:'group',
+ cmd:{
+ cmdName:'leaveGroup',
+ cmdValue:username
+ }
+ }
+ });
+ conf.layim.removeList({
+ type: 'group' //或者group
+ ,id: roomId //好友或者群组ID
+ });
+ im.removeHistory({//从我的历史列表删除
+ type: 'group' //或者group
+ ,id: roomId //好友或者群组ID
+ });
+ var index = layer.open();
+ layer.close(index);
+ parent.location.reload();
+ },
+ error: function (res) {
+ console.log('Leave room faild');
+ }
+ };
+ conn.leaveGroupBySelf(option);
+ }else{
+ layer.msg(data.msg);
+ }
+ });
+ },
+ removeHistory: function(data){//删除好友或退出群后清除历史记录
+ var history = cachedata.local.history;
+ delete history[data.type+data.id];
+ cachedata.local.history = history;
+ layui.data('layim', {
+ key: cachedata.mine.id
+ ,value: cachedata.local
+ });
+ $('#layim-history'+data.id).remove();
+ var hisElem = $('.layui-layim').find('.layim-list-history');
+ var none = '暂无历史会话 '
+ if(hisElem.find('li').length === 0){
+ hisElem.html(none);
+ }
+ },
+ IsExist: function (avatar){ //判断头像是否存在
+ var ImgObj=new Image();
+ ImgObj.src= avatar;
+ if(ImgObj.fileSize > 0 || (ImgObj.width > 0 && ImgObj.height > 0))
+ {
+ return true;
+ } else {
+ return false;
+ }
+ },
+ audio:function(msg){//消息提示
+ conf.layim.msgbox(msg);
+ var audio = document.createElement("audio");
+ audio.src = layui.cache.dir+'css/modules/layim/voice/'+ cachedata.base.voice;
+ audio.play(); //消息提示音
+ },
+ addFriendGroup:function(othis,type){
+ var li = othis.parents('li') || othis.parent()
+ , uid = li.data('uid') || li.data('id')
+ , approval = li.data('approval')
+ , name = li.data('name');
+ if (uid == 'undifine' || !uid) {
+ var uid = othis.parent().data('id'), name = othis.parent().data('name');
+ }
+ var avatar = './uploads/person/'+uid+'.jpg';
+ var isAdd = false;
+ if (type == 'friend') {
+ var default_avatar = './uploads/person/empty2.jpg';
+ if(cachedata.mine.id == uid){//添加的是自己
+ layer.msg('不能添加自己');
+ return false;
+ }
+ layui.each(cachedata.friend, function(index1, item1){
+ layui.each(item1.list, function(index, item){
+ if (item.id == uid) {isAdd = true;}//是否已经是好友
+ });
+ });
+ }else{
+ var default_avatar = './uploads/person/empty1.jpg';
+ for (i in cachedata.group)//是否已经加群
+ {
+ if (cachedata.group[i].id == uid) {isAdd = true;break;}
+ }
+ }
+ parent.layui.layim.add({//弹出添加好友对话框
+ isAdd: isAdd
+ ,approval: approval
+ ,username: name || []
+ ,uid:uid
+ ,avatar: im['IsExist'].call(this, avatar)?avatar:default_avatar
+ ,group: cachedata.friend || []
+ ,type: type
+ ,submit: function(group,remark,index){//确认发送添加请求
+ if (type == 'friend') {
+ $.get('class/doAction.php?action=add_msg', {to: uid,msgType:1,remark:remark,mygroupIdx:group}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ conn.subscribe({
+ to: uid,
+ message: remark
+ });
+ layer.msg('你申请添加'+name+'为好友的消息已发送。请等待对方确认');
+ }else{
+ layer.msg('你申请添加'+name+'为好友的消息发送失败。请刷新浏览器后重试');
+ }
+ });
+ }else{
+ var options = {
+ groupId: uid,
+ success: function(resp) {
+ if (approval == '1') {
+ $.get('class/doAction.php?action=add_msg', {to: uid,msgType:3,remark:remark}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ layer.msg('你申请加入'+name+'的消息已发送。请等待管理员确认');
+ }else{
+ layer.msg('你申请加入'+name+'的消息发送失败。请刷新浏览器后重试');
+ }
+ });
+
+ }else{
+ layer.msg('你已加入 '+name+' 群');
+ }
+ },
+ error: function(e) {
+ if(e.type == 17){
+ layer.msg('您已经在这个群组里了');
+ }
+ }
+ };
+ conn.joinGroup(options);
+ }
+ },function(){
+ layer.close(index);
+ }
+ });
+
+ },
+ receiveAddFriendGroup:function(othis,agree){//确认添加好友或群
+ var li = othis.parents('li')
+ , type = li.data('type')
+ , uid = li.data('uid')
+ , username = li.data('name')
+ , signature = li.data('signature')
+ , msgIdx = li.data('id');
+ if (type == 1) {
+ type = 'friend';
+ var avatar = './uploads/person/'+uid+'.jpg';
+ msgType = 2;
+ }else{
+ type = 'group';
+ var groupIdx = li.data('groupidx');
+ msgType = 4;
+ }
+ var status = agree == 2?2:3;
+ if (agree == 2) {
+ if (msgType == 2) {
+ var default_avatar = './uploads/person/empty2.jpg';
+ conf.layim.setFriendGroup({
+ type: type
+ , username: username//用户名称或群组名称
+ , avatar: im['IsExist'].call(this, avatar)?avatar:default_avatar
+ , group: cachedata.friend || [] //获取好友分组数据
+ , submit: function (group, index) {
+ $.get('class/doAction.php?action=modify_msg', {msgIdx: msgIdx,msgType:msgType,status:status,mygroupIdx:group,friendIdx:uid}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ //将好友 追加到主面板
+ conf.layim.addList({
+ type: 'friend'
+ , avatar: im['IsExist'].call(this, avatar)?avatar:default_avatar //好友头像
+ , username: username //好友昵称
+ , groupid: group //所在的分组id
+ , id: uid //好友ID
+ , sign: signature //好友签名
+ });
+ conn.subscribed({//同意添加后通知对方
+ to: uid,
+ message : 'Success'
+ });
+ parent.layer.close(index);
+ othis.parent().html('已同意');
+ // parent.location.reload();
+ im.contextMenu();//更新右键点击事件
+ }else{
+ console.log('添加失败');
+ }
+ });
+ layer.close(index);
+ }
+ });
+ }else if(msgType = 4){
+ var default_avatar = './uploads/person/empty1.jpg';
+ $.get('class/doAction.php?action=modify_msg', {msgIdx: msgIdx,msgType:msgType,status:status}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ var options = {
+ applicant: uid,
+ groupId: groupIdx,
+ success: function(resp){
+ conn.subscribed({//同意添加后通知对方
+ to: uid,
+ message : 'addGroupSuccess'
+ });
+ im.sendMsg({//系统消息
+ mine:{
+ content:username+' 已加入该群',
+ timestamp:new Date().getTime()
+ },
+ to:{
+ id:groupIdx,
+ type:'group',
+ cmd:{
+ cmdName:'joinGroup',
+ cmdValue:username
+ }
+ }
+ });
+ },
+ error: function(e){}
+ };
+ conn.agreeJoinGroup(options);
+ othis.parent().html('已同意');
+ // parent.location.reload();
+ im.contextMenu();//更新右键点击事件
+ }else if(data.code == 1){
+ console.log(data.msg);
+ }else{
+ console.log('添加失败');
+ }
+ });
+ }
+
+ }else{
+ $.get('class/doAction.php?action=modify_msg', {msgIdx: msgIdx,msgType:msgType,status:status}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ conn.unsubscribed({
+ to: uid,
+ message : 'rejectAddFriend'
+ });
+ othis.parent().html('已拒绝 ');
+ }
+ layer.close(layer.index);
+ });
+
+ }
+
+ },
+ //创建群
+ createGroup: function(othis){
+ var index = layer.open({
+ type: 2
+ ,title: '创建群'
+ ,shade: false
+ ,maxmin: false
+ ,area: ['550px', '400px']
+ ,skin: 'layui-box layui-layer-border'
+ ,resize: false
+ ,content: cachedata.base.createGroup
+ });
+ },
+ commitGroupInfo: function(othis,data){
+ if (!data.groupName) {
+ return false;
+ }
+ $.get('class/doAction.php?action=userMaxGroupNumber', {}, function(res){
+ var resData = eval('(' + res + ')');
+ if(resData.code == 0){
+ var options = {
+ data: {
+ groupname: data.groupName,
+ desc: data.des,
+ maxusers:data.number,
+ public: true,
+ approval: data.approval == '1'?true:false,
+ allowinvites: true
+ },
+ success: function (respData) {
+ if (respData.data.groupid) {
+ $.get('class/doAction.php?action=commitGroupInfo', {groupIdx:respData.data.groupid,groupName: data.groupName,des:data.des,number:data.number,approval:data.approval}, function(respdata){
+ var res = eval('(' + respdata + ')');
+ if(res.code == 0){
+ //将群 追加到主面板
+ var avatar = './uploads/person/'+respData.data.groupid+'.jpg';
+ var default_avatar = './static/img/tel.jpg';
+ layer.msg(res.msg);
+ parent.layui.layim.addList({
+ type: 'group'
+ , avatar: im['IsExist'].call(this, avatar)?avatar:default_avatar //好友头像
+ , groupname: data.groupName //群名称
+ , id: respData.data.groupid //群id
+ });
+ }else{
+ return layer.msg(res.msg);
+ }
+ layer.close(layer.index);
+ });
+ }
+
+ },
+ error: function () {}
+ };
+ conn.createGroupNew(options);
+ }else{
+ return layer.msg(resData.msg);
+ }
+ layer.close(layer.index);
+ });
+ },
+ getMyInformation: function(){
+ var index = layer.open({
+ type: 2
+ ,title: '我的资料'
+ ,shade: false
+ ,maxmin: false
+ ,area: ['400px', '670px']
+ ,skin: 'layui-box layui-layer-border'
+ ,resize: true
+ ,content: cachedata.base.Information+'?id='+cachedata.mine.id+'&type=friend'
+ });
+ },
+ getInformation: function(data){
+ var id = data.id || {},type = data.type || {};
+ var index = layer.open({
+ type: 2
+ ,title: type == 'friend'?(cachedata.mine.id == id?'我的资料':'好友资料') :'群资料'
+ ,shade: false
+ ,maxmin: false
+ // ,closeBtn: 0
+ ,area: ['400px', '670px']
+ ,skin: 'layui-box layui-layer-border'
+ ,resize: true
+ ,content: cachedata.base.Information+'?id='+id+'&type='+type
+ });
+ },
+ userStatus: function(data){
+ if (data.id) {
+ $.get('class/doAction.php?action=userStatus', {id:data.id}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ if (data.data == 'online') {
+ conf.layim.setChatStatus('在线 ');
+ }else{
+ conf.layim.setChatStatus('离线 ');
+ }
+ }else{
+ //没有该用户
+ }
+ });
+ }
+ },
+ groupMembers: function(othis, e){
+ var othis = $(this);
+ var icon = othis.find('.layui-icon'), hide = function(){
+ icon.html('');
+ $("#layui-layim-chat > ul:eq(1)").remove();
+ $(".layui-layim-group-search").remove();
+ othis.data('show', null);
+ };
+ if(othis.data('show')){
+ hide();
+ } else {
+ icon.html('');
+ othis.data('show', true);
+ var members = cachedata.base.members || {},ul = $("#layui-layim-chat"), li = '', membersCache = {};
+ var info = JSON.parse(decodeURIComponent(othis.parent().data('json')));
+ members.data = $.extend(members.data, {
+ id: info.id
+ });
+ $.get(members, function(res){
+ var resp = eval('(' + res + ')');
+ var html = '';
+ layui.each(resp.data.list, function(index, item){
+ html += ' ';
+ item.type == 1?
+ (html += ''+ item.username +' '):
+ (item.type == 2?
+ (html += ''+ item.username +' '):
+ (html += ''+ item.username +' '));
+ html += ' ';
+ membersCache[item.id] = item;
+ });
+ html += ' ';
+ html += '
';
+ ul.append(html);
+ im.contextMenu();
+ });
+ }
+ },
+ closeAllGroupList: function(){
+ var othis = $(".groupMembers");
+ othis.remove();//关闭全部的群员列表
+ $(".layui-layim-group-search").remove();
+ var icon = $('.layim-tool-groupMembers').find('.layui-icon');
+ $('.layim-tool-groupMembers').data('show', null);
+ icon.html('');
+ },
+ groupSearch: function(othis){
+ var search = $("#layui-layim-chat").find('.layui-layim-group-search');
+ var main = $("#layui-layim-chat").find('.groupMembers');
+ var input = search.find('input'), find = function(e){
+ var val = input.val().replace(/\s/);
+ var data = [];
+ var group = $(".groupMembers li") || [], html = '';
+ if(val === ''){
+ for(var j = 0; j < group.length; j++){
+ group.eq(j).css("display","block");
+ }
+ } else {
+ for(var j = 0; j < group.length; j++){
+ name = group.eq(j).find('span').html();
+ if(name.indexOf(val) === -1){
+ group.eq(j).css("display","none");
+ }else{
+ group.eq(j).css("display","block");
+ }
+ }
+ }
+ };
+ if(!cachedata.base.isfriend && cachedata.base.isgroup){
+ events.tab.index = 1;
+ } else if(!cachedata.base.isfriend && !cachedata.base.isgroup){
+ events.tab.index = 2;
+ }
+ search.show();
+ input.focus();
+ input.off('keyup', find).on('keyup', find);
+ },
+ addMyGroup: function(){//新增分组
+ $.get('class/doAction.php?action=addMyGroup', {}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ $('.layim-list-friend').append(' '+data.data.name+' ( 0 ) ');
+ im.contextMenu();
+ location.reload();
+ }else{
+ layer.msg(data.msg);
+ }
+ });
+ },
+ delMyGroup: function(groupidx){//删除分组
+ $.get('class/doAction.php?action=delMyGroup', {mygroupIdx:groupidx}, function (res) {
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ var group = $('.layim-list-friend li') || [];
+ for(var j = 0; j < group.length; j++){//遍历每一个分组
+ groupList = group.eq(j).find('h5').data('groupidx');
+ if(groupList === groupidx){//要删除的分组
+ if (group.eq(j).find('ul span').hasClass('layim-null')) {//删除的分组下没有好友
+ group.eq(j).remove();
+ }else{
+ // var html = group.eq(j).find('ul').html();//被删除分组的好友
+ var friend = group.eq(j).find('ul li');
+ var number = friend.length;//被删除分组的好友个数
+ for (var i = 0; i < number; i++) {
+ var friend_id = friend.eq(i).attr('id').replace(/^layim-friend/g, '');//好友id
+ var friend_name = friend.eq(i).find('span').html();//好友id
+ var signature = friend.eq(i).find('p').html();//好友id
+ var avatar = '../uploads/person/'+friend_id+'.jpg';
+ var default_avatar = './uploads/person/empty2.jpg';
+ conf.layim.removeList({//将好友从之前分组除去
+ type: 'friend'
+ ,id: friend_id //好友ID
+ });
+ conf.layim.addList({//将好友移动到新分组
+ type: 'friend'
+ , avatar: im['IsExist'].call(this, avatar)?avatar:default_avatar //好友头像
+ , username: friend_name //好友昵称
+ , groupid: data.data //将好友添加到默认分组
+ , id: friend_id //好友ID
+ , sign: signature //好友签名
+ });
+ };
+ }
+
+ }
+ }
+ im.contextMenu();
+ layer.close(layer.index);
+ }else{
+ layer.msg(data.msg);
+ }
+ });
+ },
+ setAdmin: function(othis){
+ var username = othis.data('id'),friend_avatar = othis.data('img'),
+ isfriend = othis.data('isfriend'),name = othis.data('name'),
+ gagTime = othis.data('gagtime'),groupidx = othis.data('groupidx');
+ var options = {
+ groupId: groupidx,
+ username: username,
+ success: function(resp) {
+ $.get('class/doAction.php?action=setAdmin', {groupidx:groupidx,memberIdx:username,type:2}, function (res) {
+ var admin = eval('(' + res + ')');
+ if (admin.code == 0) {
+ $("ul[data-groupidx="+groupidx+"] #"+username).remove();
+ var html = ''+name+' '
+ $("ul[data-groupidx="+groupidx+"]").find('li').eq(0).after(html);
+ im.contextMenu();
+ }
+ layer.msg(admin.msg);
+ });
+ },
+ error: function(e){
+ }
+ };
+ conn.setAdmin(options);
+ },
+ removeAdmin: function(othis){
+ var username = othis.data('id'),friend_avatar = othis.data('img'),
+ isfriend = othis.data('isfriend'),name = othis.data('name').split('<'),
+ gagTime = othis.data('gagtime'),groupidx = othis.data('groupidx');
+ var options = {
+ groupId: groupidx,
+ username: username,
+ success: function(resp) {
+ $.get('class/doAction.php?action=setAdmin', {groupidx:groupidx,memberIdx:username,type:3}, function (res) {
+ var admin = eval('(' + res + ')');
+ if (admin.code == 0) {
+ $("ul[data-groupidx="+groupidx+"] #"+username).remove();
+ var html = ''+name[0]+' '
+ $("ul[data-groupidx="+groupidx+"]").append(html);
+ im.contextMenu();
+ }
+ layer.msg(admin.msg);
+ });
+ },
+ error: function(e){
+ }
+ };
+ conn.removeAdmin(options);
+ },
+ editGroupNickName: function(othis){
+ var memberIdx = othis.data('id'),name = othis.data('name').split('('),groupIdx = othis.data('groupidx');
+ layer.prompt({title: '请输入群名片,并确认', formType: 0,value: name[0]}, function(nickName, index){
+ $.get('class/doAction.php?action=editGroupNickName',{nickName:nickName,memberIdx:memberIdx,groupIdx:groupIdx},function(res){
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ $("ul[data-groupidx="+groupIdx+"] #"+memberIdx).find('span').html(nickName+'('+memberIdx+')');
+ layer.close(index);
+ }
+ layer.msg(data.msg);
+ });
+ });
+ },
+ leaveGroup: function(groupIdx,list,username){//list为数组
+ $.get('class/doAction.php?action=leaveGroup',{list:list,groupIdx:groupIdx},function(res){
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ var options = {
+ roomId: groupIdx,
+ list: list,
+ success: function(resp){
+ console.log(resp);
+ },
+ error: function(e){
+ console.log(e);
+ }
+ };
+ conn.leaveGroup(options);
+ $("ul[data-groupidx="+groupIdx+"] #"+data.data).remove();
+ im.sendMsg({//系统消息
+ mine:{
+ content:username+' 已被移出该群',
+ timestamp:new Date().getTime()
+ },
+ to:{
+ id:groupIdx,
+ type:'group',
+ cmd:{
+ cmdName:'leaveGroup',
+ cmdValue:username
+ }
+ }
+ });
+ var index = layer.open();
+ layer.close(index);
+ }
+ layer.msg(data.msg);
+ });
+ },
+ setGag: function(options){//设置禁言 取消禁言
+ var _this_group = $('.layim-chat-list .layim-chatlist-group'+options.groupidx);//选择操作的群
+ if (_this_group.find('span').html()) {
+ var index = _this_group.index();//对应面板的index
+ var cont = _this_group.parent().parent().find('.layim-chat-box div').eq(index)
+ var info = JSON.parse(decodeURIComponent(cont.find('.layim-chat-tool').data('json')));
+ // info.manager = message.ext.cmd.cmdValue;第一种
+ //禁言 两种方案 第一种是改变用户的状态 优点:只需要判断该参数就能禁言
+ // 第二种是设置一个禁言时间点,当当前时间小于该设置的时间则为禁言,优点:自动改变用户禁言状态
+ if (options.type == 'set' && (options.user == cachedata.mine.id || options.user == 'ALL')) {//设置禁言单人或全体
+ if (options.gagTime) {
+ info.gagTime = parseInt(options.gagTime);
+ cont.find('.layim-chat-tool').data('json',encodeURIComponent(JSON.stringify(info)));
+ layui.each(cachedata.group, function(index, item){
+ if (item.id === options.groupidx) {
+ cachedata.group[index].gagTime = info.gagTime;
+ }
+ });
+ };
+ cont.find('.layim-chat-gag').css('display','block');
+ }else if(options.type == 'lift' && (options.user == cachedata.mine.id || options.user == 'ALL')){//取消禁言单人或全体
+ cont.find('.layim-chat-tool').data('json',encodeURIComponent(JSON.stringify(info)));
+ layui.each(cachedata.group, function(index, item){
+ if (item.id === options.groupidx) {
+ cachedata.group[index].gagTime = '0';
+ }
+ });
+ cont.find('.layim-chat-gag').css('display','none');
+ }
+
+ }else{
+ if (options.type == 'set' && (options.user == cachedata.mine.id || options.user == 'ALL')) {//设置禁言单人或全体
+ if (options.gagTime) {
+ layui.each(cachedata.group, function(index, item){
+ if (item.id === options.groupidx) {
+ cachedata.group[index].gagTime = parseInt(options.gagTime);
+ }
+ });
+ };
+ }else if(options.type == 'lift' && (options.user == cachedata.mine.id || options.user == 'ALL')){//取消禁言单人或全体
+ layui.each(cachedata.group, function(index, item){
+ if (item.id === options.groupidx) {
+ cachedata.group[index].gagTime = '0';
+ }
+ });
+ }
+ }
+ },
+ popMsg: function(data,msg){//删除本地最新一条发送失败的消息
+ var logid = cachedata.local.chatlog[data.to.type+data.to.id];
+ logid.pop();
+ var timestamp = '.timestamp'+data.mine.timestamp;
+ $(timestamp).html('ဇ '+msg);
+ },
+ menuChat: function(){
+ return data = {
+ text: "发送消息",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent(),type = othis.data('type'),
+ name = othis.data('name'),avatar = othis.data('img'),
+ id = othis.data('id');
+ // id = (new RegExp(substr).test('layim')?substr.replace(/[^0-9]/ig,""):substr);
+ conf.layim.chat({
+ name: name
+ ,type: type
+ ,avatar: avatar
+ ,id: id
+ });
+ }
+ }
+ },
+ menuInfo: function(){
+ return data = {
+ text: "查看资料",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent(),type = othis.data('type'),id = othis.data('id');
+ // id = (new RegExp(substr).test('layim')?substr.replace(/[^0-9]/ig,""):substr);
+ im.getInformation({
+ id: id,
+ type:type
+ });
+ }
+ }
+ },
+ menuChatLog: function(){
+ return data = {
+ text: "聊天记录",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent(),type = othis.data('type'),name = othis.data('name'),
+ id = othis.data('id');
+ im.getChatLog({
+ name: name,
+ id: id,
+ type:type
+ });
+ }
+ }
+ },
+ menuNickName: function(){
+ return data = {
+ text: "修改好友备注",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent(),friend_id = othis.data('id'),friend_name = othis.data('name');
+ layer.prompt({title: '修改备注姓名', formType: 0,value: friend_name}, function(nickName, index){
+ $.get('class/doAction.php?action=editNickName',{nickName:nickName,friend_id:friend_id},function(res){
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ var friendName = $("#layim-friend"+friend_id).find('span');
+ friendName.html(data.data);
+ layer.close(index);
+ }
+ layer.msg(data.msg);
+ });
+ });
+
+ }
+ }
+ },
+ menuMove: function(html){
+ return data = {
+ text: "移动联系人",
+ icon: "",
+ nav: "move",//子导航的样式
+ navIcon: "",//子导航的图标
+ navBody: html,//子导航html
+ callback: function(ele) {
+ var friend_id = ele.parent().data('id');//要移动的好友id
+ friend_name = ele.parent().data('name');
+ var avatar = '../uploads/person/'+friend_id+'.jpg';
+ var default_avatar = './uploads/person/empty2.jpg';
+ var signature = $('.layim-list-friend').find('#layim-friend'+friend_id).find('p').html();//获取签名
+ var item = ele.find("ul li");
+ item.hover(function() {
+ var _this = item.index(this);
+ var groupidx = item.eq(_this).data('groupidx');//将好友移动到分组的id
+ $.get('class/doAction.php?action=moveFriend',{friend_id:friend_id,groupidx:groupidx},function(res){
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ conf.layim.removeList({//将好友从之前分组除去
+ type: 'friend'
+ ,id: friend_id //好友ID
+ });
+ conf.layim.addList({//将好友移动到新分组
+ type: 'friend'
+ , avatar: im['IsExist'].call(this, avatar)?avatar:default_avatar //好友头像
+ , username: friend_name //好友昵称
+ , groupid: groupidx //所在的分组id
+ , id: friend_id //好友ID
+ , sign: signature //好友签名
+ });
+ }
+ layer.msg(data.msg);
+ });
+ });
+ }
+ }
+ },
+ menuRemove: function(){
+ return data = {
+ text: "删除好友",
+ icon: "",
+ events: "removeFriends",
+ callback: function(ele) {
+ var othis = ele.parent(),friend_id = othis.data('id'),username,sign;
+ layui.each(cachedata.friend, function(index1, item1){
+ layui.each(item1.list, function(index, item){
+ if (item.id === friend_id) {
+ username = item.username;
+ sign = item.sign;
+ }
+ });
+ });
+ layer.confirm('删除后对方将从你的好友列表消失,且以后不会再接收此人的会话消息。'+username+' '+sign+'
', {
+ btn: ['确定','取消'], //按钮
+ title:['删除好友','background:#b4bdb8'],
+ shade: 0
+ }, function(){
+ im.removeFriends(friend_id);
+ }, function(){
+ var index = layer.open();
+ layer.close(index);
+ });
+ }
+ }
+ },
+ menuAddMyGroup: function(){
+ return data = {
+ text: "添加分组",
+ icon: "",
+ callback: function(ele) {
+ im.addMyGroup();
+ }
+ }
+
+ },
+ menuRename: function(){
+ return data = {
+ text: "重命名",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent(),mygroupIdx = othis.data('id'),groupName = othis.data('name');
+ layer.prompt({title: '请输入分组名,并确认', formType: 0,value: groupName}, function(mygroupName, index){
+ if (mygroupName) {
+ $.get('class/doAction.php?action=editGroupName',{mygroupName:mygroupName,mygroupIdx:mygroupIdx},function(res){
+ var data = eval('(' + res + ')');
+ if (data.code == 0) {
+ var friend_group = $(".layim-list-friend li");
+ for(var j = 0; j < friend_group.length; j++){
+ var groupidx = friend_group.eq(j).find('h5').data('groupidx');
+ if(groupidx == mygroupIdx){//当前选择的分组
+ friend_group.eq(j).find('h5').find('span').html(mygroupName);
+ }
+ }
+ im.contextMenu();
+ layer.close(index);
+ }
+ layer.msg(data.msg);
+ });
+ }
+
+ });
+ }
+
+ }
+ },
+ menuDelMyGroup: function(){
+ return data = {
+ text: "删除该组",
+ icon: "ဆ",
+ callback: function(ele) {
+ var othis = ele.parent(),mygroupIdx = othis.data('id');
+ layer.confirm('
选定的分组将被删除,组内联系人将会移至默认分组。
', {
+ btn: ['确定','取消'], //按钮
+ title:['删除分组','background:#b4bdb8'],
+ shade: 0
+ }, function(){
+ im.delMyGroup(mygroupIdx);
+ }, function(){
+ var index = layer.open();
+ layer.close(index);
+ });
+ }
+ }
+ },
+ menuLeaveGroupBySelf: function(){
+ return data = {
+ text: "退出该群",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent(),
+ group_id = othis.data('id'),
+ groupname = othis.data('name');
+ avatar = othis.data('img');
+ layer.confirm('您真的要退出该群吗?退出后你将不会再接收此群的会话消息。'+groupname+' ', {
+ btn: ['确定','取消'], //按钮
+ title:['提示','background:#b4bdb8'],
+ shade: 0
+ }, function(){
+ var user = cachedata.mine.id;
+ var username = cachedata.mine.username;
+ im.leaveGroupBySelf(user,username,group_id);
+ }, function(){
+ var index = layer.open();
+ layer.close(index);
+ });
+ }
+ }
+ },
+ menuAddFriend: function(){
+ return data = {
+ text: "添加好友",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele;
+ im.addFriendGroup(othis,'friend');
+ }
+ }
+ },
+ menuEditGroupNickName: function(){
+ return data = {
+ text: "修改群名片",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent();
+ im.editGroupNickName(othis);
+ }
+ }
+ },
+ menuRemoveAdmin: function(){
+ return data = {
+ text: "取消管理员",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent();
+ im.removeAdmin(othis);
+ }
+ }
+ },
+ menuSetAdmin: function(){
+ return data = {
+ text: "设置为管理员",
+ icon: "",
+ callback: function(ele) {
+ var othis = ele.parent(),user = othis.data('id');
+ im.setAdmin(othis);
+ }
+ }
+ },
+ menuLeaveGroup: function(){
+ return data = {
+ text: "踢出本群",
+ icon: "ဆ",
+ callback: function(ele) {
+ var othis = ele.parent();
+ var friend_id = ele.parent().data('id');//要禁言的id
+ var username = ele.parent().data('name');
+ var groupIdx = ele.parent().data('groupidx');
+ var list = new Array();
+ list[0] = friend_id;
+ im.leaveGroup(groupIdx,list,username)
+ }
+ }
+ },
+ menuGroupMemberGag: function(){
+ return data = {
+ text: "禁言",
+ icon: "",
+ nav: "gag",//子导航的样式
+ navIcon: "",//子导航的图标
+ navBody: '',//子导航html
+ callback: function(ele) {
+ var friend_id = ele.parent().data('id');//要禁言的id
+ friend_name = ele.parent().data('name');
+ groupidx = ele.parent().data('groupidx');
+ var item = ele.find("ul li");
+ item.hover(function() {
+ var _index = item.index(this),gagTime = item.eq(_index).data('gag');//禁言时间
+ $.get('class/doAction.php?action=groupMemberGag',{gagTime:gagTime,groupidx:groupidx,friend_id:friend_id},function(resp){
+ var data = eval('(' + resp + ')');
+ if (data.code == 0) {
+ var gagTime = data.data.gagTime;
+ var res = {mine: {
+ content: gagTime+'',
+ timestamp: data.data.time
+ },
+ to: {
+ type: 'group',
+ id: groupidx+"",
+ cmd: {
+ id: friend_id,
+ cmdName:'gag',
+ cmdValue:data.data.value
+ }
+ }}
+ im.sendMsg(res);
+ $("ul[data-groupidx="+groupidx+"] #"+friend_id).attr('gagtime',gagTime);
+ }
+ layer.msg(data.msg);
+ });
+ });
+ }
+ }
+ },
+ menuLiftGroupMemberGag: function(){
+ return data = {
+ text: "取消禁言",
+ icon: "",
+ callback: function(ele) {
+ var friend_id = ele.parent().data('id');//要禁言的id
+ friend_name = ele.parent().data('name');
+ groupidx = ele.parent().data('groupidx');
+ $.get('class/doAction.php?action=liftGroupMemberGag',{groupidx:groupidx,friend_id:friend_id},function(resp){
+ var data = eval('(' + resp + ')');
+ if (data.code == 0) {
+ var res = {mine: {
+ content: '0',
+ timestamp: data.data.time
+ },
+ to: {
+ type: 'group',
+ id: groupidx+"",
+ cmd: {
+ id: friend_id,
+ cmdName:'liftGag',
+ cmdValue:data.data.value
+ }
+ }}
+ im.sendMsg(res);
+ $("ul[data-groupidx="+groupidx+"] #"+friend_id).attr('gagtime',0);
+ }
+ layer.msg(data.msg);
+ });
+ }
+ }
+ },
+
+ };
+ exports('socket', socket);
+ exports('im', im);
+});
\ No newline at end of file
diff --git a/src/main/resources/static/js/fileupload.js b/src/main/resources/static/js/fileupload.js
new file mode 100644
index 0000000..c72a661
--- /dev/null
+++ b/src/main/resources/static/js/fileupload.js
@@ -0,0 +1,92 @@
+$(function () {
+ /*对于一些控件的初始化*/
+ let $ = jQuery,
+ //待上传的文件列表
+ $list = $('#thelist'),
+ //开始上传按钮
+ $btn = $('#ctlBtn'),
+ //显示状态 上传成功、上传失败。。
+ state = 'pending',
+ //上传的方法
+ uploader;
+ uploader = WebUploader.create({
+
+ // 不压缩image
+ resize: false,
+ //开启分片
+ chunked: true,
+ //分片大小50mb
+ chunkSize: 52428800,
+ //断网之后重试 5次
+ chunkRetry: 5,
+ // 为true 文件则自动上传
+ auto: false,
+
+ // swf文件路径 使用flash才会用到
+ // swf: BASE_URL + '/js/Uploader.swf',
+
+ // 文件接收服务端。就是上传文件走的url
+ server: '/uploadfile',
+
+ // 选择文件的按钮。可选。
+ pick: '#picker',
+
+ // 默认所有都可选,过滤文件类型参考网址: http://www.cnblogs.com/s.sams/archive/2007/10/10/918817.html
+ // 只允许选择图片文件。
+ /*accept: {
+ title: 'Images',
+ extensions: 'gif,jpg,jpeg,bmp,png',
+ mimeTypes: 'image/!*'
+ },*/
+
+ });
+ // 当有文件添加进来的时候
+ uploader.on('fileQueued', function (file) {
+ $list.append('' +
+ '
' + file.name + ' ' +
+ '
等待上传...
' +
+ '
');
+ });
+
+ // 文件上传过程中创建进度条实时显示。
+ // 进度条我引用了bootStrap.css来进行展示,webuploader.css是不带的
+
+ // 上传成功
+ uploader.on('uploadSuccess', function (file) {
+ $('#' + file.id).find('p.state').text('已上传');
+ });
+
+ // 上传失败
+ uploader.on('uploadError', function (file) {
+ $('#' + file.id).find('p.state').text('上传出错');
+ });
+
+ uploader.on('uploadComplete', function (file) {
+ $('#' + file.id).find('.progress').fadeOut();
+ });
+ uploader.on('all', function (type) {
+ if (type === 'startUpload') {
+ state = 'uploading';
+ } else if (type === 'stopUpload') {
+ state = 'paused';
+ } else if (type === 'uploadFinished') {
+ state = 'done';
+ }
+
+ if (state === 'uploading') {
+ $btn.text('暂停上传');
+ } else {
+ $btn.text('开始上传');
+ }
+ });
+
+ // 开始上传 按钮点击事件 触发 上传方法
+ // 如果开启了自动上传,则不必要
+ $btn.on('click', function () {
+ if (state === 'uploading') {
+ uploader.stop();
+ } else {
+ uploader.upload();
+ }
+ });
+});
\ No newline at end of file
diff --git a/src/main/resources/static/js/jquery-3.3.1.min.js b/src/main/resources/static/js/jquery-3.3.1.min.js
new file mode 100644
index 0000000..4d9b3a2
--- /dev/null
+++ b/src/main/resources/static/js/jquery-3.3.1.min.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML=" ",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML=" ";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML=" ","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML=" ",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""," "],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/
+
+