diff --git a/im/.env b/im/.env new file mode 100644 index 00000000..59d0738d --- /dev/null +++ b/im/.env @@ -0,0 +1,6 @@ +NODE_ENV=production +VUE_APP_PREVIEW=false +VUE_APP_API_BASE_URL=https://im-api.pickmall.cn +VUE_APP_WEB_SOCKET_URL=wss://im-api.pickmall.cn/lili/webSocket +VUE_APP_COMMON=https://common-api.pickmall.cn +VUE_APP_WEBSITE_NAME="LiLi IM" diff --git a/im/.env.development b/im/.env.development new file mode 100644 index 00000000..d6973c53 --- /dev/null +++ b/im/.env.development @@ -0,0 +1,7 @@ +NODE_ENV=development +VUE_APP_PREVIEW=true +VUE_APP_API_BASE_URL=http://192.168.0.113:8885 +VUE_APP_WEB_SOCKET_URL=ws://192.168.0.113:8885/lili/webSocket +VUE_APP_COMMON=http://192.168.0.113:8890 +VUE_APP_PC_URL="http://192.168.0.113:10001" +VUE_APP_WEBSITE_NAME="LiLi IM" diff --git a/im/.gitignore b/im/.gitignore new file mode 100644 index 00000000..403adbc1 --- /dev/null +++ b/im/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules +/dist + + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/im/LICENSE b/im/LICENSE new file mode 100644 index 00000000..dbcbe685 --- /dev/null +++ b/im/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 YuanDong + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/im/README.md b/im/README.md new file mode 100644 index 00000000..6ac928fc --- /dev/null +++ b/im/README.md @@ -0,0 +1,71 @@ +# Springboot-websocket + +过渡阶段IM + +前端仓库:https://gitee.com/beijing_hongye_huicheng/im + +后端仓库:https://gitee.com/beijing_hongye_huicheng/springboot-websocket + +部署方式: +1、导入数据库,配置resource目录下application.yml的数据库以及redis配置文件。 + +2、maven打包 + +3、启动jar包即可。 + +4、前端程序运行,测试环境需配置根目录 .env.development文件,正式环境需配置 .env 文件。 + +# 参考项目 +项目前端参考:https://gitee.com/gzydong/LumenIM.git 功能更丰富,大家可以去学习一波 + + +# IM体验 +浏览器1打开地址:http://127.0.0.1:8000/message?token=eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyQ29udGV4dCI6IntcInVzZXJuYW1lXCI6XCIxMzAxMTExMTExMVwiLFwibmlja05hbWVcIjpcIuW8oOS4ieWTiOWTiOWTiFwiLFwiZmFjZVwiOlwiaHR0cHM6Ly9saWxpc2hvcC1vc3Mub3NzLWNuLWJlaWppbmcuYWxpeXVuY3MuY29tLzQ1ZDUyOGYwMjRjZTQyMzI4NzYxNjFhZmQxN2Y0ZWExLmpwZ1wiLFwiaWRcIjpcIjEzNzY0MTc2ODQxNDAzMjY5MTJcIixcImxvbmdUZXJtXCI6ZmFsc2UsXCJyb2xlXCI6XCJTVE9SRVwiLFwic3RvcmVJZFwiOlwiMTM3NjQzMzU2NTI0NzQ3MTYxNlwiLFwic3RvcmVOYW1lXCI6XCLlrrblrrbkuZBcIixcImlzU3VwZXJcIjpmYWxzZX0iLCJzdWIiOiIxMzAxMTExMTExMSIsImV4cCI6MTY0NTQ2OTk1M30.fXpCZ2YiFYqACpmxVvKjIpXovfPRDJavHjftpQzdEps + +浏览器2打开地址:http://127.0.0.1:8000/message?token=eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyQ29udGV4dCI6IntcInVzZXJuYW1lXCI6XCIxMzAxMTExMTExMVwiLFwibmlja05hbWVcIjpcIuW8oOS4ieWTiOWTiOWTiFwiLFwiZmFjZVwiOlwiaHR0cHM6Ly9saWxpc2hvcC1vc3Mub3NzLWNuLWJlaWppbmcuYWxpeXVuY3MuY29tLzk2N2UzMzU1Yzg0NTRiNGFhMTk1N2M1NTQ5ZTZiNzIwLnBuZ1wiLFwiaWRcIjpcIjEzNzY0MTc2ODQxNDAzMjY5MTJcIixcImxvbmdUZXJtXCI6ZmFsc2UsXCJyb2xlXCI6XCJNRU1CRVJcIixcImlzU3VwZXJcIjpmYWxzZX0iLCJzdWIiOiIxMzAxMTExMTExMSIsImV4cCI6MTY0NTQ2OTAyNn0.GEkGpKRKF3rqzHRhaPCFilPpWe37cIXTT4KnwWR4Bt0&id=1376433565247471616 + +即可进行聊天。 + +# NGINX配置事例 +线上NGINX配置在测试阶段出现问题,这里吧相关的配置贴出来供大家参考。 +```` + server { + listen 443 ssl; + ssl_certificate "/etc/nginx/ssl/pickmall.cn.pem"; + ssl_certificate_key "/etc/nginx/ssl/pickmall.cn.key"; + ssl_session_cache shared:SSL:1m; + ssl_session_timeout 10m; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + include /etc/nginx/default.d/*.conf; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + server_name im-api.pickmall.cn; + location / { + proxy_pass http://127.0.0.1:8088; + } + } + + server { + listen 443 ssl; + ssl_certificate "/etc/nginx/ssl/pickmall.cn.pem"; + ssl_certificate_key "/etc/nginx/ssl/pickmall.cn.key"; + ssl_session_cache shared:SSL:1m; + ssl_session_timeout 10m; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + include /etc/nginx/default.d/*.conf; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + server_name im.pickmall.cn; + try_files $uri $uri/ /index.html; + root /home/im/im/dist; + } +```` \ No newline at end of file diff --git a/im/babel.config.js b/im/babel.config.js new file mode 100644 index 00000000..74f3c443 --- /dev/null +++ b/im/babel.config.js @@ -0,0 +1,51 @@ +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset' + ], + plugins: [ + [ + "import", + { + "libraryName": "element-ui", + "styleLibraryName": "theme-chalk" + } + ], + [ + "prismjs", + { + "languages": [ + "html", + "css", + "less", + "javascript", + "typescript", + "json", + "xml", + "bash", + "nginx", + "sql", + "docker", + "php", + "java", + "go", + "python", + "ruby", + "rust", + "objectivec", + "c", + "csharp", + "cpp", + "lua", + "shell", + "vim", + "yaml", + "yml", + "md", + "erlang", + "ini" + ], + "theme": "okaidia" + } + ] + ] +} \ No newline at end of file diff --git a/im/jsconfig.json b/im/jsconfig.json new file mode 100644 index 00000000..09ea7562 --- /dev/null +++ b/im/jsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "es6", + "baseUrl": ".", + "paths": { + "@/*": [ + "src/*" + ] + } + }, + "exclude": [ + "node_modules", + "dist" + ], + "include": [ + "src/**/*" + ] +} \ No newline at end of file diff --git a/im/package.json b/im/package.json new file mode 100644 index 00000000..1393f7e6 --- /dev/null +++ b/im/package.json @@ -0,0 +1,66 @@ +{ + "name": "LiLi-IM", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "vue-cli-service serve", + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "lint": "vue-cli-service lint" + }, + "dependencies": { + "axios": "^0.21.4", + "babel-plugin-prismjs": "^2.0.1", + "core-js": "^3.6.5", + "element-ui": "^2.14.1", + "js-audio-recorder": "^1.0.6", + "js-base64": "^2.5.1", + "mavon-editor": "^2.10.4", + "nprogress": "^0.2.0", + "prismjs": "^1.29.0", + "svg-sprite-loader": "^5.0.0", + "vue": "^2.6.11", + "vue-contextmenujs": "^1.3.13", + "vue-cropper": "^0.5.5", + "vue-prism-editor": "^0.5.1", + "vue-router": "^3.4.9", + "vuex": "^3.5.1" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "^5.0.8", + "@vue/cli-plugin-eslint": "^5.0.8", + "@vue/cli-service": "^5.0.8", + "babel-eslint": "^10.1.0", + "babel-plugin-import": "^1.13.1", + "compression-webpack-plugin": "^5.0.0", + "eslint": "^8.28.0", + "eslint-plugin-vue": "^6.2.2", + "less": "^3.0.4", + "less-loader": "^5.0.0", + "style-resources-loader": "^1.4.1", + "vue-cli-plugin-style-resources-loader": "^0.1.4", + "vue-svg-component-runtime": "^1.0.1", + "vue-svg-icon-loader": "^2.1.1", + "vue-template-compiler": "^2.6.11", + "webpack": "^5.75.0" + }, + "eslintConfig": { + "root": true, + "env": { + "node": true + }, + "extends": [ + "plugin:vue/essential", + "eslint:recommended" + ], + "parserOptions": { + "parser": "babel-eslint" + }, + "rules": {} + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ] +} diff --git a/im/public/favicon.ico b/im/public/favicon.ico new file mode 100644 index 00000000..5d8e506a Binary files /dev/null and b/im/public/favicon.ico differ diff --git a/im/public/index.html b/im/public/index.html new file mode 100644 index 00000000..1dd7f3d8 --- /dev/null +++ b/im/public/index.html @@ -0,0 +1,34 @@ + + + + + + + + LiLi IM + + + <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> + + <% } %> + + + + + +
+
+
+ +
+
+
+ + <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> + + <% } %> + + + diff --git a/im/src/App.vue b/im/src/App.vue new file mode 100644 index 00000000..89b704ca --- /dev/null +++ b/im/src/App.vue @@ -0,0 +1,23 @@ + + diff --git a/im/src/api/chat.js b/im/src/api/chat.js new file mode 100644 index 00000000..25d077c0 --- /dev/null +++ b/im/src/api/chat.js @@ -0,0 +1,109 @@ +import { post, get, upload, del } from "@/utils/request"; + +// 获取聊天列表服务接口 +export const ServeGetTalkList = (data) => { + return get("/im/talk/list", data); +}; + +// 获取聊天列表服务接口 +export const ServeGetStoreTalkList = (data) => { + return get("/im/talk/store/list", data); +}; + +// 聊天列表创建服务接口 +export const ServeCreateTalkList = (id) => { + return get(`/im/talk/user/${id}`); +}; + +// 删除聊天列表服务接口 +export const ServeDeleteTalkList = (data) => { + return del("/im/talk", data); +}; + +// 对话列表置顶服务接口 +export const ServeTopTalkList = (data) => { + return post("/im/talk/top", data); +}; + +// 清除聊天消息未读数服务接口 +export const ServeClearTalkUnreadNum = (data) => { + return post("/im/talk/update-unread-num", data); +}; + +// 获取聊天记录服务接口 +export const ServeTalkRecords = (data) => { + return get("/im/message", data); +}; + +// 获取转发会话记录详情列表服务接口 +export const ServeGetForwardRecords = (data) => { + return get("/im/talk/get-forward-records", data); +}; + +// 对话列表置顶服务接口 +export const ServeSetNotDisturb = (data) => { + return post("/im/talk/disturb", data); +}; + +// 查找用户聊天记录服务接口 +export const ServeFindTalkRecords = (data) => { + return get("/im/talk/find-chat-records", data); +}; + +// 搜索用户聊天记录服务接口 +export const ServeSearchTalkRecords = (data) => { + return get("/im/talk/search-chat-records", data); +}; + +export const ServeGetRecordsContext = (data) => { + return get("/im/talk/get-records-context", data); +}; + +// 发送代码块消息服务接口 +export const ServeSendTalkCodeBlock = (data) => { + return post("/im/talk/message/code", data); +}; + +// 发送聊天文件服务接口 +export const ServeSendTalkFile = (data) => { + return post("/im/talk/message/file", data); +}; + +// 发送聊天图片服务接口 +export const ServeSendTalkImage = (data) => { + return upload("/common/common/upload/file", data); +}; + +// 发送表情包服务接口 +export const ServeSendEmoticon = (data) => { + return post("/im/talk/message/emoticon", data); +}; + +// 转发消息服务接口 +export const ServeForwardRecords = (data) => { + return post("/im/talk/message/forward", data); +}; + +// 撤回消息服务接口 +export const ServeRevokeRecords = (data) => { + return post("/im/talk/message/revoke", data); +}; + +// 删除消息服务接口 +export const ServeRemoveRecords = (data) => { + return post("/im/talk/message/delete", data); +}; + +// 收藏表情包服务接口 +export const ServeCollectEmoticon = (data) => { + return post("/im/talk/message/collect", data); +}; + +//投票 +export const ServeSendVote = (data) => { + return post("/im/talk/message/vote", data); +}; + +export const ServeConfirmVoteHandle = (data) => { + return post("/im/talk/message/vote/handle", data); +}; diff --git a/im/src/api/contacts.js b/im/src/api/contacts.js new file mode 100644 index 00000000..653242d3 --- /dev/null +++ b/im/src/api/contacts.js @@ -0,0 +1,45 @@ +import { post, get } from '@/utils/request' + +// 获取好友列表服务接口 +export const ServeGetContacts = data => { + return get('/contacts/list', data) +} + +// 解除好友关系服务接口 +export const ServeDeleteContact = data => { + return post('/contacts/delete', data) +} + +// 修改好友备注服务接口 +export const ServeEditContactRemark = data => { + return post('/contacts/edit-remark', data) +} + +// 搜索联系人 +export const ServeSearchContact = data => { + return get('/contacts/search', data) +} + +// 好友申请服务接口 +export const ServeCreateContact = data => { + return post('/contacts/apply/create', data) +} + +// 查询好友申请服务接口 +export const ServeGetContactApplyRecords = data => { + return get('/contacts/apply/records', data) +} + +// 处理好友申请服务接口 +export const ServeApplyAccept = data => { + return post('/contacts/apply/accept', data) +} + +export const ServeApplyDecline = data => { + return post('/contacts/apply/decline', data) +} + +// 查询好友申请未读数量服务接口 +export const ServeFindFriendApplyNum = () => { + return get('/contacts/apply-unread-num') +} diff --git a/im/src/api/emoticon.js b/im/src/api/emoticon.js new file mode 100644 index 00000000..d287fe30 --- /dev/null +++ b/im/src/api/emoticon.js @@ -0,0 +1,26 @@ +import { post, get, upload } from '@/utils/request' + +// 查询用户表情包服务接口 +export const ServeFindUserEmoticon = () => { + return get('/emoticon/list') +} + +// 查询系统表情包服务接口 +export const ServeFindSysEmoticon = () => { + return get('/emoticon/system') +} + +// 设置用户表情包服务接口 +export const ServeSetUserEmoticon = data => { + return post('/emoticon/set-user-emoticon', data) +} + +// 移除收藏表情包服务接口 +export const ServeDelCollectEmoticon = data => { + return post('/emoticon/del-collect-emoticon', data) +} + +// 上传表情包服务接口 +export const ServeUploadEmoticon = data => { + return upload('/emoticon/upload-emoticon', data) +} diff --git a/im/src/api/goods.js b/im/src/api/goods.js new file mode 100644 index 00000000..0ddde395 --- /dev/null +++ b/im/src/api/goods.js @@ -0,0 +1,5 @@ +import { post, get, upload, del } from "@/utils/request"; + +export const ServeGetGoodsDetail = (data) => { + return get(`/im/goods/goods/sku/${data.goodsId}/${data.skuId}`); + }; diff --git a/im/src/api/group.js b/im/src/api/group.js new file mode 100644 index 00000000..3e271672 --- /dev/null +++ b/im/src/api/group.js @@ -0,0 +1,66 @@ +import { post, get } from '@/utils/request' + +// 查询用户群聊服务接口 +export const ServeGetGroups = () => { + return get('/group/list') +} + +// 获取群信息服务接口 +export const ServeGroupDetail = data => { + return get('/group/detail', data) +} + +// 创建群聊服务接口 +export const ServeCreateGroup = data => { + return post('/group/create', data) +} + +// 修改群信息 +export const ServeEditGroup = data => { + return post('/group/edit', data) +} + +// 邀请好友加入群聊服务接口 +export const ServeInviteGroup = data => { + return post('/group/invite', data) +} + +// 移除群聊成员服务接口 +export const ServeRemoveMembersGroup = data => { + return post('/group/remove-members', data) +} + +// 管理员解散群聊服务接口 +export const ServeDismissGroup = data => { + return post('/group/dismiss', data) +} + +// 用户退出群聊服务接口 +export const ServeSecedeGroup = data => { + return post('/group/secede', data) +} + +// 修改群聊名片服务接口 +export const ServeUpdateGroupCard = data => { + return post('/group/set-group-card', data) +} + +// 获取用户可邀请加入群组的好友列表 +export const ServeGetInviteFriends = data => { + return get('/group/invite-friends', data) +} + +// 获取群组成员列表 +export const ServeGetGroupMembers = data => { + return get('/group/members', data) +} + +// 获取群组公告列表 +export const ServeGetGroupNotices = data => { + return get('/group/notices', data) +} + +// 编辑群公告 +export const ServeEditGroupNotice = data => { + return post('/group/edit-notice', data) +} diff --git a/im/src/api/upload.js b/im/src/api/upload.js new file mode 100644 index 00000000..afbbb580 --- /dev/null +++ b/im/src/api/upload.js @@ -0,0 +1,16 @@ +import { post, get, upload } from '@/utils/request' + +// 上传头像裁剪图片服务接口 +export const ServeUploadFileStream = data => { + return post('/upload/file-stream', data) +} + +// 查询大文件拆分信息服务接口 +export const ServeFindFileSplitInfo = (data = {}) => { + return get('/upload/get-file-split-info', data) +} + +// 文件拆分上传服务接口 +export const ServeFileSubareaUpload = (data = {}, options = {}) => { + return upload('/upload/file-subarea-upload', data, options) +} diff --git a/im/src/api/user.js b/im/src/api/user.js new file mode 100644 index 00000000..061b9513 --- /dev/null +++ b/im/src/api/user.js @@ -0,0 +1,26 @@ +import { get } from "@/utils/request"; + +// 获取用户相关设置信息 +export const ServeGetUserSetting = () => { + return get("/im/user"); +}; + +// 获取店铺相关设置信息 +export const ServeGetStoreSetting = () => { + return get("/im/user/store"); +}; + +// 获取用户相关设置信息 +export const ServeGetUserDetail = (memberId) => { + return get(`/im/user/${memberId}`); +}; + +// 获取店铺相关设置信息 +export const ServeGetStoreDetail = (storeId) => { + return get(`/im/user/store/${storeId}`); +}; + +// 获取店铺相关设置信息 +export const ServeGetFootPrint = (params) => { + return get(`/im/user/history`,params); +}; diff --git a/im/src/assets/css/global.less b/im/src/assets/css/global.less new file mode 100644 index 00000000..c1353b95 --- /dev/null +++ b/im/src/assets/css/global.less @@ -0,0 +1,238 @@ +@import './reset.css'; + +.no-select { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.no-padding { + padding: 0; +} + +.avatar-box { + height: 35px; + width: 35px; + flex-shrink: 0; + background-color: #508afe; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; + color: white; + user-select: none; + transition: ease 1s; + position: relative; + overflow: hidden; + + img { + width: 100%; + height: 100%; + background-color: white; + border-radius: 3px; + } + + .top-mask { + width: 100%; + height: 100%; + background-color: rgba(22, 25, 29, 0.6); + position: absolute; + top: 0; + left: 0; + color: white; + display: none; + align-items: center; + justify-content: center; + font-weight: bold; + } + + &:hover .top-mask { + display: flex; + } +} + +.no-border { + border: 0; +} + +.pointer { + cursor: pointer; +} + +.border-radius0 { + border-radius: 0; +} + +.full-height { + height: 100%; +} + +.talk-height { + height: 80%; + width: 80%; +} + +.ov-hidden { + overflow: hidden; +} + +// 滚动条样式 +.lum-scrollbar { + &::-webkit-scrollbar { + width: 3px; + background-color: #e4e4e5; + } + + &::-webkit-scrollbar-thumb { + border-radius: 3px; + background-color: #c0bebc; + } +} + +.larkc-tag { + font-size: 12px; + font-weight: 400; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0 6px; + height: 20px; + border-radius: 2px; + cursor: default; + user-select: none; + background-color: #dee0e3; + transform: scale(0.83); + transform-origin: left; + flex-shrink: 0; +} + +.flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +// 自定义 dialog 样式 +// lum-dialog -- start +.lum-dialog-mask { + position: fixed; + top: 0; + left: 0; + z-index: 999; + width: 100%; + height: 100%; + background-color: @maskBagColor; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + + .lum-dialog-box { + min-width: 200px; + min-height: 200px; + background-color: white; + border-radius: 3px; + overflow: hidden; + box-shadow: 0 2px 8px 0 rgba(31, 35, 41, 0.2); + margin: 0 10px; + + .container { + height: 100%; + } + + .header { + padding: 0; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid #f5eeee; + + >p:first-child { + text-indent: 20px; + } + + .tools { + height: 100%; + width: 100px; + display: flex; + align-items: center; + justify-content: flex-end; + padding-right: 20px; + + i { + font-size: 20px; + cursor: pointer; + margin-left: 8px; + } + } + } + + .main { + /deep/.el-input__inner { + border-radius: 1px !important; + } + + .submit-btn { + border-radius: 2px; + font-weight: 400; + } + } + } +} + +// lum-dialog -- end + +.talk-notify { + .el-notification__title { + font-weight: 300; + font-size: 16px; + color: #f44336; + } + + p { + max-height: 65px; + overflow: hidden; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + text-indent: -7px; + word-break: break-all; + } +} + +.im-notify { + padding: 14px 26px 8px 0px; + + .el-notification__closeBtn { + position: absolute; + top: 12px; + } + + .el-notification__group { + margin-left: 5px; + } +} + +.flex { + display: flex; +} + +.flex-2 { + flex: 2; +} + +.flex-8 { + flex: 8; +} + +.flex-4 { + flex: 4; +} + +.flex-10 { + flex: 10; +} \ No newline at end of file diff --git a/im/src/assets/css/markdown.css b/im/src/assets/css/markdown.css new file mode 100644 index 00000000..02615f34 --- /dev/null +++ b/im/src/assets/css/markdown.css @@ -0,0 +1,991 @@ +.markdown-body .octicon { + display: inline-block; + fill: currentColor; + vertical-align: text-bottom; +} + +.markdown-body .anchor { + float: left; + line-height: 1; + margin-left: -20px; + padding-right: 4px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + color: #1b1f23; + vertical-align: middle; + visibility: hidden; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + visibility: visible; +} + +.markdown-body h1:hover .anchor .octicon-link:before, +.markdown-body h2:hover .anchor .octicon-link:before, +.markdown-body h3:hover .anchor .octicon-link:before, +.markdown-body h4:hover .anchor .octicon-link:before, +.markdown-body h5:hover .anchor .octicon-link:before, +.markdown-body h6:hover .anchor .octicon-link:before { + width: 16px; + height: 16px; + content: ' '; + display: inline-block; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z'%3E%3C/path%3E%3C/svg%3E"); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + font-size: 16px; + word-wrap: break-word; + font-family: Content-font, Roboto, sans-serif; + font-weight: 400; + color: #3B454E; + line-height: 1.625; +} + +.markdown-body details { + display: block; +} + +.markdown-body summary { + display: list-item; +} + +.markdown-body a { + background-color: initial; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline-width: 0; +} + +.markdown-body strong { + font-weight: inherit; + font-weight: bolder; +} + +.markdown-body h1 { + font-size: 2em; + margin: .67em 0; +} + +.markdown-body img { + border-style: none; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body hr { + box-sizing: initial; + height: 0; + overflow: visible; +} + +.markdown-body input { + font: inherit; + margin: 0; +} + +.markdown-body input { + overflow: visible; +} + +.markdown-body [type=checkbox] { + box-sizing: border-box; + padding: 0; +} + +.markdown-body * { + box-sizing: border-box; +} + +.markdown-body input { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +.markdown-body a { + color: #0366d6; + text-decoration: none; +} + +.markdown-body a:hover { + text-decoration: underline; +} + +.markdown-body strong { + font-weight: 600; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #dfe2e5; +} + +.markdown-body hr:after, +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + clear: both; +} + +.markdown-body table { + border-spacing: 0; + border-collapse: collapse; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body details summary { + cursor: pointer; +} + +.markdown-body kbd { + display: inline-block; + padding: 3px 5px; + font: 11px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; + line-height: 10px; + color: #444d56; + vertical-align: middle; + background-color: #fafbfc; + border: 1px solid #d1d5da; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #d1d5da; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body h1 { + font-size: 32px; +} + +.markdown-body h1, +.markdown-body h2 { + font-weight: 600; +} + +.markdown-body h2 { + font-size: 24px; +} + +.markdown-body h3 { + font-size: 20px; +} + +.markdown-body h3, +.markdown-body h4 { + font-weight: 600; +} + +.markdown-body h4 { + font-size: 16px; +} + +.markdown-body h5 { + font-size: 14px; +} + +.markdown-body h5, +.markdown-body h6 { + font-weight: 600; +} + +.markdown-body h6 { + font-size: 12px; +} + +.markdown-body p { + margin-top: 0; + margin-bottom: 10px; +} + +.markdown-body blockquote { + margin: 20px 0 !important; + background-color: #f5f8fc; + padding: 1rem; + color: #8796a8; + border-left: none; +} + +.markdown-body ol, +.markdown-body ul { + padding-left: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ol ol ol, +.markdown-body ol ul ol, +.markdown-body ul ol ol, +.markdown-body ul ul ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code, +.markdown-body pre { + font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; + font-size: 12px; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body input::-webkit-inner-spin-button, +.markdown-body input::-webkit-outer-spin-button { + margin: 0; + -webkit-appearance: none; + appearance: none; +} + +.markdown-body :checked+.radio-label { + position: relative; + z-index: 1; + border-color: #0366d6; +} + +.markdown-body .border { + border: 1px solid #e1e4e8 !important; +} + +.markdown-body .border-0 { + border: 0 !important; +} + +.markdown-body .border-bottom { + border-bottom: 1px solid #e1e4e8 !important; +} + +.markdown-body .rounded-1 { + border-radius: 3px !important; +} + +.markdown-body .bg-white { + background-color: #fff !important; +} + +.markdown-body .bg-gray-light { + background-color: #fafbfc !important; +} + +.markdown-body .text-gray-light { + color: #6a737d !important; +} + +.markdown-body .mb-0 { + margin-bottom: 0 !important; +} + +.markdown-body .my-2 { + margin-top: 8px !important; + margin-bottom: 8px !important; +} + +.markdown-body .pl-0 { + padding-left: 0 !important; +} + +.markdown-body .py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.markdown-body .pl-1 { + padding-left: 4px !important; +} + +.markdown-body .pl-2 { + padding-left: 8px !important; +} + +.markdown-body .py-2 { + padding-top: 8px !important; + padding-bottom: 8px !important; +} + +.markdown-body .pl-3, +.markdown-body .px-3 { + padding-left: 16px !important; +} + +.markdown-body .px-3 { + padding-right: 16px !important; +} + +.markdown-body .pl-4 { + padding-left: 24px !important; +} + +.markdown-body .pl-5 { + padding-left: 32px !important; +} + +.markdown-body .pl-6 { + padding-left: 40px !important; +} + +.markdown-body .f6 { + font-size: 12px !important; +} + +.markdown-body .lh-condensed { + line-height: 1.25 !important; +} + +.markdown-body .text-bold { + font-weight: 600 !important; +} + +.markdown-body .pl-c { + color: #6a737d; +} + +.markdown-body .pl-c1, +.markdown-body .pl-s .pl-v { + color: #005cc5; +} + +.markdown-body .pl-e, +.markdown-body .pl-en { + color: #6f42c1; +} + +.markdown-body .pl-s .pl-s1, +.markdown-body .pl-smi { + color: #24292e; +} + +.markdown-body .pl-ent { + color: #22863a; +} + +.markdown-body .pl-k { + color: #d73a49; +} + +.markdown-body .pl-pds, +.markdown-body .pl-s, +.markdown-body .pl-s .pl-pse .pl-s1, +.markdown-body .pl-sr, +.markdown-body .pl-sr .pl-cce, +.markdown-body .pl-sr .pl-sra, +.markdown-body .pl-sr .pl-sre { + color: #032f62; +} + +.markdown-body .pl-smw, +.markdown-body .pl-v { + color: #e36209; +} + +.markdown-body .pl-bu { + color: #b31d28; +} + +.markdown-body .pl-ii { + color: #fafbfc; + background-color: #b31d28; +} + +.markdown-body .pl-c2 { + color: #fafbfc; + background-color: #d73a49; +} + +.markdown-body .pl-c2:before { + content: "^M"; +} + +.markdown-body .pl-sr .pl-cce { + font-weight: 700; + color: #22863a; +} + +.markdown-body .pl-ml { + color: #735c0f; +} + +.markdown-body .pl-mh, +.markdown-body .pl-mh .pl-en, +.markdown-body .pl-ms { + font-weight: 700; + color: #005cc5; +} + +.markdown-body .pl-mi { + font-style: italic; + color: #24292e; +} + +.markdown-body .pl-mb { + font-weight: 700; + color: #24292e; +} + +.markdown-body .pl-md { + color: #b31d28; + background-color: #ffeef0; +} + +.markdown-body .pl-mi1 { + color: #22863a; + background-color: #f0fff4; +} + +.markdown-body .pl-mc { + color: #e36209; + background-color: #ffebda; +} + +.markdown-body .pl-mi2 { + color: #f6f8fa; + background-color: #005cc5; +} + +.markdown-body .pl-mdr { + font-weight: 700; + color: #6f42c1; +} + +.markdown-body .pl-ba { + color: #586069; +} + +.markdown-body .pl-sg { + color: #959da5; +} + +.markdown-body .pl-corl { + text-decoration: underline; + color: #032f62; +} + +.markdown-body .mb-0 { + margin-bottom: 0 !important; +} + +.markdown-body .my-2 { + margin-bottom: 8px !important; +} + +.markdown-body .my-2 { + margin-top: 8px !important; +} + +.markdown-body .pl-0 { + padding-left: 0 !important; +} + +.markdown-body .py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.markdown-body .pl-1 { + padding-left: 4px !important; +} + +.markdown-body .pl-2 { + padding-left: 8px !important; +} + +.markdown-body .py-2 { + padding-top: 8px !important; + padding-bottom: 8px !important; +} + +.markdown-body .pl-3 { + padding-left: 16px !important; +} + +.markdown-body .pl-4 { + padding-left: 24px !important; +} + +.markdown-body .pl-5 { + padding-left: 32px !important; +} + +.markdown-body .pl-6 { + padding-left: 40px !important; +} + +.markdown-body .pl-7 { + padding-left: 48px !important; +} + +.markdown-body .pl-8 { + padding-left: 64px !important; +} + +.markdown-body .pl-9 { + padding-left: 80px !important; +} + +.markdown-body .pl-10 { + padding-left: 96px !important; +} + +.markdown-body .pl-11 { + padding-left: 112px !important; +} + +.markdown-body .pl-12 { + padding-left: 128px !important; +} + +.markdown-body hr { + border-bottom-color: #eee; +} + +.markdown-body kbd { + display: inline-block; + padding: 3px 5px; + font: 11px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; + line-height: 10px; + color: #444d56; + vertical-align: middle; + background-color: #fafbfc; + border: 1px solid #d1d5da; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #d1d5da; +} + +.markdown-body:after, +.markdown-body:before { + display: table; + content: ""; +} + +.markdown-body:after { + clear: both; +} + +.markdown-body>:first-child { + margin-top: 0 !important; +} + +.markdown-body>:last-child { + margin-bottom: 0 !important; +} + +.markdown-body a:not([href]) { + color: inherit; + text-decoration: none; +} + +.markdown-body blockquote, +.markdown-body details, +.markdown-body dl, +.markdown-body ol, +.markdown-body p, +.markdown-body pre, +.markdown-body table, +.markdown-body ul { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: .25em; + padding: 0; + margin: 24px 0; + background-color: #e1e4e8; + border: 0; +} + +.markdown-body blockquote { + margin: 20px 0 !important; + background-color: #f5f8fc; + padding: 1rem; + color: #8796a8; + border-left: 3px solid #03A9F4; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 24px; + margin-bottom: 16px; + font-weight: 600; + line-height: 1.25; +} + +.markdown-body h1 { + font-size: 2em; +} + +.markdown-body h1, +.markdown-body h2 { + padding-bottom: .3em; + /* border-bottom: 1px solid #eaecef; */ +} + +.markdown-body h2 { + font-size: 1.5em; +} + +.markdown-body h3 { + font-size: 1.25em; +} + +.markdown-body h4 { + font-size: 1em; +} + +.markdown-body h5 { + font-size: .875em; +} + +.markdown-body h6 { + font-size: .85em; + color: #6a737d; +} + +.markdown-body ol, +.markdown-body ul { + padding-left: 2em; +} + +.markdown-body ol ol, +.markdown-body ol ul, +.markdown-body ul ol, +.markdown-body ul ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li { + word-wrap: break-all; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body li+li { + margin-top: .25em; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: 600; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; +} + +.markdown-body table th { + font-weight: 600; +} + +.markdown-body table td, +.markdown-body table th { + padding: 6px 13px; + border: 1px solid #dfe2e5; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #c6cbd1; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f6f8fa; +} + +.markdown-body img { + max-width: 100%; + box-sizing: initial; + background-color: #fff; +} + +.markdown-body img[align=right] { + padding-left: 20px; +} + +.markdown-body img[align=left] { + padding-right: 20px; +} + +.markdown-body code { + padding: .2em .4em; + margin: 0; + font-size: 85%; + background-color: rgba(27, 31, 35, .05); + border-radius: 3px; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; +} + +.markdown-body pre code { + display: inline; + max-width: auto; + padding: 0; + margin: 0; + overflow: visible; + line-height: inherit; + word-wrap: normal; + background-color: initial; + border: 0; +} + +.markdown-body .commit-tease-sha { + display: inline-block; + font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; + font-size: 90%; + color: #444d56; +} + +.markdown-body .full-commit .btn-outline:not(:disabled):hover { + color: #005cc5; + border-color: #005cc5; +} + +.markdown-body .blob-wrapper { + overflow-x: auto; + overflow-y: hidden; +} + +.markdown-body .blob-wrapper-embedded { + max-height: 240px; + overflow-y: auto; +} + +.markdown-body .blob-num { + width: 1%; + min-width: 50px; + padding-right: 10px; + padding-left: 10px; + font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; + font-size: 12px; + line-height: 20px; + color: rgba(27, 31, 35, .3); + text-align: right; + white-space: nowrap; + vertical-align: top; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .blob-num:hover { + color: rgba(27, 31, 35, .6); +} + +.markdown-body .blob-num:before { + content: attr(data-line-number); +} + +.markdown-body .blob-code { + position: relative; + padding-right: 10px; + padding-left: 10px; + line-height: 20px; + vertical-align: top; +} + +.markdown-body .blob-code-inner { + overflow: visible; + font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; + font-size: 12px; + color: #24292e; + word-wrap: normal; + white-space: pre; +} + +.markdown-body .pl-token.active, +.markdown-body .pl-token:hover { + cursor: pointer; + background: #ffea7f; +} + +.markdown-body .tab-size[data-tab-size="1"] { + -moz-tab-size: 1; + tab-size: 1; +} + +.markdown-body .tab-size[data-tab-size="2"] { + -moz-tab-size: 2; + tab-size: 2; +} + +.markdown-body .tab-size[data-tab-size="3"] { + -moz-tab-size: 3; + tab-size: 3; +} + +.markdown-body .tab-size[data-tab-size="4"] { + -moz-tab-size: 4; + tab-size: 4; +} + +.markdown-body .tab-size[data-tab-size="5"] { + -moz-tab-size: 5; + tab-size: 5; +} + +.markdown-body .tab-size[data-tab-size="6"] { + -moz-tab-size: 6; + tab-size: 6; +} + +.markdown-body .tab-size[data-tab-size="7"] { + -moz-tab-size: 7; + tab-size: 7; +} + +.markdown-body .tab-size[data-tab-size="8"] { + -moz-tab-size: 8; + tab-size: 8; +} + +.markdown-body .tab-size[data-tab-size="9"] { + -moz-tab-size: 9; + tab-size: 9; +} + +.markdown-body .tab-size[data-tab-size="10"] { + -moz-tab-size: 10; + tab-size: 10; +} + +.markdown-body .tab-size[data-tab-size="11"] { + -moz-tab-size: 11; + tab-size: 11; +} + +.markdown-body .tab-size[data-tab-size="12"] { + -moz-tab-size: 12; + tab-size: 12; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + margin: 0 .2em .25em -1.6em; + vertical-align: middle; +} \ No newline at end of file diff --git a/im/src/assets/css/page/contacts.less b/im/src/assets/css/page/contacts.less new file mode 100644 index 00000000..8b158ca1 --- /dev/null +++ b/im/src/assets/css/page/contacts.less @@ -0,0 +1,281 @@ +.aside-box { + position: relative; + background-color: white; + border-right: 1px solid rgb(245, 245, 245); + overflow: hidden; + padding: 0; + + .header { + display: flex; + flex-direction: row; + align-items: center; + padding: 0 15px; + + .from { + flex: 1 1; + flex-shrink: 0; + height: 40px; + + /deep/.el-input .el-input__inner { + border-radius: 20px; + width: 170px; + } + } + + .tools { + flex-basis: 32px; + flex-shrink: 0; + height: 32px; + margin-bottom: 8px; + cursor: pointer; + line-height: 32px; + text-align: center; + position: relative; + user-select: none; + + .tools-menu { + position: absolute; + right: 0; + top: 38px; + width: 100px; + min-height: 80px; + box-sizing: border-box; + background-color: rgba(31, 35, 41, 0.9); + border-radius: 5px; + z-index: 1; + padding: 3px 0; + + .menu1-item { + height: 40px; + line-height: 40px; + color: white; + font-size: 14px; + + &:hover { + background-color: rgba(70, 72, 73, 0.9); + } + } + } + } + } +} + +// 右侧面板 +.panel { + position: relative; + width: 100%; + height: 100%; + box-sizing: border-box; + + .header { + display: flex; + align-items: center; + justify-content: space-between; + &.border{ + border-bottom: 1px solid #f5f5f5; + } + } + + .subheader { + display: flex; + align-items: center; + justify-content: flex-start; + border-top: 1px solid rgb(92, 156, 230); + border-bottom: 1px solid rgb(92, 156, 230); + + p { + padding: 0 10px; + cursor: pointer; + font-size: 13px; + + &:first-child { + padding-left: 0; + } + + &.active { + color: #508afe; + } + } + } + + .panel-body { + overflow: auto; + width: 100%; + height: 100%; + box-sizing: border-box; + + .preloading { + height: 100%; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + user-select: none; + + p { + margin-top: 20px; + color: #afacac; + font-size: 14px; + font-weight: 300; + } + } + + .data-item { + display: flex; + flex-direction: row; + align-items: center; + height: 60px; + cursor: pointer; + padding: 5px 15px; + position: relative; + overflow: hidden; + border-bottom: 1px solid #f1ebeb; + margin-bottom: 2px; + + .avatar { + height: 35px; + width: 35px; + flex-basis: 35px; + flex-shrink: 0; + background-color: #508afe; + border-radius: 50%; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; + color: white; + user-select: none; + transition: ease 1s; + position: relative; + } + + .card { + height: 40px; + display: flex; + align-content: center; + flex-direction: column; + flex: 1 1; + margin-left: 10px; + overflow: hidden; + + .title { + width: 100%; + height: 20px; + display: flex; + align-items: center; + + .name { + margin-right: 15px; + color: #1f2329; + } + + .larkc-tag { + font-size: 12px; + font-weight: 400; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0 6px; + height: 20px; + border-radius: 2px; + cursor: default; + user-select: none; + background-color: #dee0e3; + transform: scale(0.8); + transform-origin: left; + flex-shrink: 0; + } + + .wait { + background: #ffb445; + color: white; + } + + .agree { + background: #53bd53; + color: white; + } + } + + .content { + font-size: 10px; + line-height: 18px; + color: #8f959e; + overflow: hidden; + margin-top: 3px; + font-weight: 300; + white-space: nowrap; + text-overflow: ellipsis; + } + } + + .apply-from { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + position: relative; + right: -110px; + top: 0px; + height: 60px; + width: 100px; + transition: ease 0.5s 0.3s; + background-color: white; + opacity: 0; + button { + margin: 2px; + } + } + + &:hover { + box-shadow: 0 0 8px 4px #f1f1f1; + + .avatar { + border-radius: 2px; + } + + .apply-from { + opacity: 1; + right: 0px; + } + } + } + } +} + +.broadside-box { + position: absolute; + width: 350px; + height: 100%; + top: 0; + right: 0; + z-index: 2; + animation: showBox 0.5s ease-in-out; + -webkit-animation: showBox 0.5s ease-in-out; + -moz-animation: showBox 0.5s ease-in-out; + -webkit-box-direction: normal; + background: white; + box-shadow: 0 0 14px #cccccc70; +} + +@keyframes showBox { + 0% { + transform: translateX(350px); + } + + to { + transform: translateX(0); + } +} + +@-webkit-keyframes showBox { + 0% { + -webkit-transform: translateX(350px); + } + + to { + -webkit-transform: translateX(0); + } +} diff --git a/im/src/assets/css/page/login-auth.less b/im/src/assets/css/page/login-auth.less new file mode 100644 index 00000000..075dcf2c --- /dev/null +++ b/im/src/assets/css/page/login-auth.less @@ -0,0 +1,198 @@ +/deep/.el-input__inner { + border-radius: 1px !important; +} + +#auth-container { + position: fixed; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: #f6f8fb; + + #logo-name { + width: 200px; + height: 38px; + font-size: 34px; + font-family: Times New Roman, Georgia, Serif; + color: #2196f3; + margin-left: 20px; + margin-top: 20px; + } + + #login-box { + position: absolute; + width: 350px; + min-height: 480px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: white; + border-radius: 5px; + box-shadow: 0 0 0 #ccc; + box-shadow: 0 4px 14px 0 rgba(206, 207, 209, 0.5); + padding: 10px 20px; + + .header { + width: 100%; + height: 38px; + font-size: 22px; + margin: 25px 0 20px 0; + } + + .main { + width: 100%; + + .links { + display: flex; + justify-content: space-between; + align-items: center; + + a { + font-weight: normal !important; + } + } + + .send-code-btn { + width: 140px; + height: 40px; + line-height: 40px; + display: inline-block; + background: #f3ecec; + text-align: center; + color: #777373; + cursor: pointer; + user-select: none; + margin-left: 5px; + + &:active { + background: #e4dbdb; + } + } + + .send-sms-disable { + cursor: not-allowed !important; + background: #f7f7f7 !important; + color: silver !important; + } + + .submit-btn { + width: 100%; + border-radius: 2px; + } + } + } +} + +.preview-account { + text-align: center; + + p { + height: 25px; + line-height: 25px; + color: rgb(45, 44, 44); + font-weight: 100; + font-size: 12px; + } +} + +.copyright { + position: absolute; + bottom: 30px; + left: 0; + right: 0; + width: 70%; + text-align: center; + margin: 0 auto; + font-size: 12px; + color: #b1a0a0; + + a { + color: #777272; + font-weight: 400; + } +} + +@media screen and (max-height: 500px) { + .copyright { + display: none; + } +} + +.fly-box { + .fly { + pointer-events: none; + position: fixed; + z-index: 100; + } + + .bg-fly-circle1 { + left: 40px; + top: 100px; + width: 100px; + height: 100px; + border-radius: 50%; + background: linear-gradient( + to right, + rgba(100, 84, 239, 0.07) 0%, + rgba(48, 33, 236, 0.04) 100% + ); + animation: move 2.5s linear infinite; + } + + .bg-fly-circle2 { + left: 3%; + top: 60%; + width: 150px; + height: 150px; + border-radius: 50%; + background: linear-gradient( + to right, + rgba(100, 84, 239, 0.08) 0%, + rgba(48, 33, 236, 0.04) 100% + ); + animation: move 3s linear infinite; + } + + .bg-fly-circle3 { + right: 2%; + top: 140px; + width: 145px; + height: 145px; + border-radius: 50%; + background: linear-gradient( + to right, + rgba(100, 84, 239, 0.1) 0%, + rgba(48, 33, 236, 0.04) 100% + ); + animation: move 2.5s linear infinite; + } + + .bg-fly-circle4 { + right: 5%; + top: 60%; + width: 160px; + height: 160px; + border-radius: 50%; + background: linear-gradient( + to right, + rgba(100, 84, 239, 0.02) 0%, + rgba(48, 33, 236, 0.04) 100% + ); + animation: move 3.5s linear infinite; + } +} + +@keyframes move { + 0% { + transform: translateY(0px); + } + + 50% { + transform: translateY(25px); + } + + 100% { + transform: translateY(0px); + } +} diff --git a/im/src/assets/css/reset.css b/im/src/assets/css/reset.css new file mode 100644 index 00000000..929e8500 --- /dev/null +++ b/im/src/assets/css/reset.css @@ -0,0 +1,62 @@ +* { + margin: 0; + padding: 0; +} + +body, +html { + height: 100%; + min-width: 500px; + font-family: "Microsoft YaHei"; + font-size: 16px; + color: #333; +} + +button, +input, +select, +textarea { + font-size: 100%; + margin: 0; + padding: 0; + border: none; + outline: none; +} + +img { + border: 0; +} + +a, +img { + -webkit-touch-callout: none +} + +a { + text-decoration: none; +} + +textarea { + resize: none; + outline: 0; + white-space: pre-wrap; + word-wrap: break-word; + border: none; + background: #fff; + font-family: "Microsoft YaHei"; +} + +:focus { + outline: none; +} + +.clearfix { + clear: both; + content: ""; + display: block; + overflow: hidden +} + +.clear { + clear: both; +} \ No newline at end of file diff --git a/im/src/assets/css/talk/talk-records.less b/im/src/assets/css/talk/talk-records.less new file mode 100644 index 00000000..c852598a --- /dev/null +++ b/im/src/assets/css/talk/talk-records.less @@ -0,0 +1,50 @@ +.message-group { + min-height: 30px; + display: flex; + margin-bottom: 5px; + flex-direction: row; + padding: 3px 12px 3px 0; + + &:first-child { + margin-top: 10px; + } + + .left-box { + width: 50px; + flex-shrink: 0; + display: flex; + justify-content: center; + user-select: none; + padding-top: 8px; + + img { + height: 30px; + width: 30px; + border-radius: 3px; + cursor: pointer; + } + } + + .right-box { + flex: auto; + overflow-x: auto; + padding: 0px 5px 15px 5px; + + .msg-header { + height: 30px; + line-height: 30px; + font-size: 12px; + color: #a09a9a; + position: relative; + user-select: none; + + .name { + color: #333; + } + } + + /deep/.text-message { + border-radius: 0; + } + } +} \ No newline at end of file diff --git a/im/src/assets/css/variable.less b/im/src/assets/css/variable.less new file mode 100644 index 00000000..631f08e7 --- /dev/null +++ b/im/src/assets/css/variable.less @@ -0,0 +1,10 @@ +//主题皮肤 - 预留功能 +:root { + --themeBagColor: red; +} + +// ------- 定义 Less 变量 ------- +@themeBagColor: var(--themeBagColor); + +// 遮罩层背景颜色 +@maskBagColor: rgba(31, 35, 41, .3); \ No newline at end of file diff --git a/im/src/assets/image/1701.mp3 b/im/src/assets/image/1701.mp3 new file mode 100644 index 00000000..2f50c05a Binary files /dev/null and b/im/src/assets/image/1701.mp3 differ diff --git a/im/src/assets/image/59y888piCn92.mp3 b/im/src/assets/image/59y888piCn92.mp3 new file mode 100644 index 00000000..86150d8d Binary files /dev/null and b/im/src/assets/image/59y888piCn92.mp3 differ diff --git a/im/src/assets/image/RaJik9TWDi.png b/im/src/assets/image/RaJik9TWDi.png new file mode 100644 index 00000000..63fc88fd Binary files /dev/null and b/im/src/assets/image/RaJik9TWDi.png differ diff --git a/im/src/assets/image/aliyun-abs.jpg b/im/src/assets/image/aliyun-abs.jpg new file mode 100644 index 00000000..6c178b7e Binary files /dev/null and b/im/src/assets/image/aliyun-abs.jpg differ diff --git a/im/src/assets/image/background/001.jpg b/im/src/assets/image/background/001.jpg new file mode 100644 index 00000000..1d1a75b7 Binary files /dev/null and b/im/src/assets/image/background/001.jpg differ diff --git a/im/src/assets/image/background/002.jpg b/im/src/assets/image/background/002.jpg new file mode 100644 index 00000000..2375e686 Binary files /dev/null and b/im/src/assets/image/background/002.jpg differ diff --git a/im/src/assets/image/background/003.jpg b/im/src/assets/image/background/003.jpg new file mode 100644 index 00000000..2257eee2 Binary files /dev/null and b/im/src/assets/image/background/003.jpg differ diff --git a/im/src/assets/image/background/004.jpg b/im/src/assets/image/background/004.jpg new file mode 100644 index 00000000..1d928773 Binary files /dev/null and b/im/src/assets/image/background/004.jpg differ diff --git a/im/src/assets/image/background/005.png b/im/src/assets/image/background/005.png new file mode 100644 index 00000000..675c74b3 Binary files /dev/null and b/im/src/assets/image/background/005.png differ diff --git a/im/src/assets/image/chat-search-no-message.png b/im/src/assets/image/chat-search-no-message.png new file mode 100644 index 00000000..d0fcea45 Binary files /dev/null and b/im/src/assets/image/chat-search-no-message.png differ diff --git a/im/src/assets/image/chat.png b/im/src/assets/image/chat.png new file mode 100644 index 00000000..1ca3cbb6 Binary files /dev/null and b/im/src/assets/image/chat.png differ diff --git a/im/src/assets/image/default-user-banner.png b/im/src/assets/image/default-user-banner.png new file mode 100644 index 00000000..55ba3569 Binary files /dev/null and b/im/src/assets/image/default-user-banner.png differ diff --git a/im/src/assets/image/detault-avatar.jpg b/im/src/assets/image/detault-avatar.jpg new file mode 100644 index 00000000..0de65dc2 Binary files /dev/null and b/im/src/assets/image/detault-avatar.jpg differ diff --git a/im/src/assets/image/gitee-avatar.jpg b/im/src/assets/image/gitee-avatar.jpg new file mode 100644 index 00000000..5dcfbd96 Binary files /dev/null and b/im/src/assets/image/gitee-avatar.jpg differ diff --git a/im/src/assets/image/github-avatar.jpg b/im/src/assets/image/github-avatar.jpg new file mode 100644 index 00000000..7d8316ef Binary files /dev/null and b/im/src/assets/image/github-avatar.jpg differ diff --git a/im/src/assets/image/icon_face.png b/im/src/assets/image/icon_face.png new file mode 100644 index 00000000..38b6ece0 Binary files /dev/null and b/im/src/assets/image/icon_face.png differ diff --git a/im/src/assets/image/icon_heart.png b/im/src/assets/image/icon_heart.png new file mode 100644 index 00000000..ee141915 Binary files /dev/null and b/im/src/assets/image/icon_heart.png differ diff --git a/im/src/assets/image/no-oncall.6b776fcf.png b/im/src/assets/image/no-oncall.6b776fcf.png new file mode 100644 index 00000000..fb531dbd Binary files /dev/null and b/im/src/assets/image/no-oncall.6b776fcf.png differ diff --git a/im/src/assets/image/obj_w5zD.mp3 b/im/src/assets/image/obj_w5zD.mp3 new file mode 100644 index 00000000..887331fa Binary files /dev/null and b/im/src/assets/image/obj_w5zD.mp3 differ diff --git a/im/src/components/chat/TalkCodeBlock.vue b/im/src/components/chat/TalkCodeBlock.vue new file mode 100644 index 00000000..44340101 --- /dev/null +++ b/im/src/components/chat/TalkCodeBlock.vue @@ -0,0 +1,313 @@ + + + diff --git a/im/src/components/chat/TalkForwardRecord.vue b/im/src/components/chat/TalkForwardRecord.vue new file mode 100644 index 00000000..276ea90f --- /dev/null +++ b/im/src/components/chat/TalkForwardRecord.vue @@ -0,0 +1,139 @@ + + + diff --git a/im/src/components/chat/TalkSearchRecord.vue b/im/src/components/chat/TalkSearchRecord.vue new file mode 100644 index 00000000..98cc487b --- /dev/null +++ b/im/src/components/chat/TalkSearchRecord.vue @@ -0,0 +1,602 @@ + + + diff --git a/im/src/components/chat/messaege/AudioMessage.vue b/im/src/components/chat/messaege/AudioMessage.vue new file mode 100644 index 00000000..04153ad9 --- /dev/null +++ b/im/src/components/chat/messaege/AudioMessage.vue @@ -0,0 +1,193 @@ + + + + diff --git a/im/src/components/chat/messaege/CodeMessage.vue b/im/src/components/chat/messaege/CodeMessage.vue new file mode 100644 index 00000000..7eae1cba --- /dev/null +++ b/im/src/components/chat/messaege/CodeMessage.vue @@ -0,0 +1,148 @@ + + + diff --git a/im/src/components/chat/messaege/FileMessage.vue b/im/src/components/chat/messaege/FileMessage.vue new file mode 100644 index 00000000..968e2885 --- /dev/null +++ b/im/src/components/chat/messaege/FileMessage.vue @@ -0,0 +1,145 @@ + + + diff --git a/im/src/components/chat/messaege/ForwardMessage.vue b/im/src/components/chat/messaege/ForwardMessage.vue new file mode 100644 index 00000000..3243cd54 --- /dev/null +++ b/im/src/components/chat/messaege/ForwardMessage.vue @@ -0,0 +1,116 @@ + + + diff --git a/im/src/components/chat/messaege/FriendApplyMessage.vue b/im/src/components/chat/messaege/FriendApplyMessage.vue new file mode 100644 index 00000000..5df0dc4f --- /dev/null +++ b/im/src/components/chat/messaege/FriendApplyMessage.vue @@ -0,0 +1,150 @@ + + + + diff --git a/im/src/components/chat/messaege/ImageMessage.vue b/im/src/components/chat/messaege/ImageMessage.vue new file mode 100644 index 00000000..309e07d1 --- /dev/null +++ b/im/src/components/chat/messaege/ImageMessage.vue @@ -0,0 +1,51 @@ + + + diff --git a/im/src/components/chat/messaege/InviteMessage.vue b/im/src/components/chat/messaege/InviteMessage.vue new file mode 100644 index 00000000..476b3eb1 --- /dev/null +++ b/im/src/components/chat/messaege/InviteMessage.vue @@ -0,0 +1,74 @@ + + + diff --git a/im/src/components/chat/messaege/LoginMessage.vue b/im/src/components/chat/messaege/LoginMessage.vue new file mode 100644 index 00000000..3226b643 --- /dev/null +++ b/im/src/components/chat/messaege/LoginMessage.vue @@ -0,0 +1,101 @@ + + + + diff --git a/im/src/components/chat/messaege/ReplyMessage.vue b/im/src/components/chat/messaege/ReplyMessage.vue new file mode 100644 index 00000000..d8fb65fc --- /dev/null +++ b/im/src/components/chat/messaege/ReplyMessage.vue @@ -0,0 +1,26 @@ + + + + diff --git a/im/src/components/chat/messaege/RevokeMessage.vue b/im/src/components/chat/messaege/RevokeMessage.vue new file mode 100644 index 00000000..281bb6ca --- /dev/null +++ b/im/src/components/chat/messaege/RevokeMessage.vue @@ -0,0 +1,66 @@ + + + diff --git a/im/src/components/chat/messaege/SystemTextMessage.vue b/im/src/components/chat/messaege/SystemTextMessage.vue new file mode 100644 index 00000000..dc31d4fc --- /dev/null +++ b/im/src/components/chat/messaege/SystemTextMessage.vue @@ -0,0 +1,39 @@ + + + diff --git a/im/src/components/chat/messaege/TextMessage.vue b/im/src/components/chat/messaege/TextMessage.vue new file mode 100644 index 00000000..80008d26 --- /dev/null +++ b/im/src/components/chat/messaege/TextMessage.vue @@ -0,0 +1,109 @@ + + + diff --git a/im/src/components/chat/messaege/UserCardMessage.vue b/im/src/components/chat/messaege/UserCardMessage.vue new file mode 100644 index 00000000..740f7e08 --- /dev/null +++ b/im/src/components/chat/messaege/UserCardMessage.vue @@ -0,0 +1,19 @@ + + + + diff --git a/im/src/components/chat/messaege/VideoMessage.vue b/im/src/components/chat/messaege/VideoMessage.vue new file mode 100644 index 00000000..c8d78dd0 --- /dev/null +++ b/im/src/components/chat/messaege/VideoMessage.vue @@ -0,0 +1,18 @@ + + + + diff --git a/im/src/components/chat/messaege/VisitCardMessage.vue b/im/src/components/chat/messaege/VisitCardMessage.vue new file mode 100644 index 00000000..81a62f52 --- /dev/null +++ b/im/src/components/chat/messaege/VisitCardMessage.vue @@ -0,0 +1,134 @@ + + + diff --git a/im/src/components/chat/messaege/VoiceMessage.vue b/im/src/components/chat/messaege/VoiceMessage.vue new file mode 100644 index 00000000..fb3feb6f --- /dev/null +++ b/im/src/components/chat/messaege/VoiceMessage.vue @@ -0,0 +1,16 @@ + + + + diff --git a/im/src/components/chat/messaege/VoteMessage.vue b/im/src/components/chat/messaege/VoteMessage.vue new file mode 100644 index 00000000..eb713468 --- /dev/null +++ b/im/src/components/chat/messaege/VoteMessage.vue @@ -0,0 +1,299 @@ + + + + diff --git a/im/src/components/chat/messaege/index.js b/im/src/components/chat/messaege/index.js new file mode 100644 index 00000000..64a30484 --- /dev/null +++ b/im/src/components/chat/messaege/index.js @@ -0,0 +1,33 @@ +import AudioMessage from './AudioMessage.vue'; +import CodeMessage from './CodeMessage.vue'; +import ForwardMessage from './ForwardMessage.vue'; +import ImageMessage from './ImageMessage.vue'; +import TextMessage from './TextMessage.vue'; +import VideoMessage from './VideoMessage.vue'; +import VoiceMessage from './VoiceMessage.vue'; +import SystemTextMessage from './SystemTextMessage.vue'; +import FileMessage from './FileMessage.vue'; +import InviteMessage from './InviteMessage.vue'; +import RevokeMessage from './RevokeMessage.vue'; +import VisitCardMessage from './VisitCardMessage.vue'; +import ReplyMessage from './ReplyMessage.vue'; +import VoteMessage from './VoteMessage.vue'; +import LoginMessage from './LoginMessage.vue'; + +export { + AudioMessage, + CodeMessage, + ForwardMessage, + ImageMessage, + TextMessage, + VideoMessage, + VoiceMessage, + SystemTextMessage, + FileMessage, + InviteMessage, + RevokeMessage, + VisitCardMessage, + ReplyMessage, + VoteMessage, + LoginMessage +} \ No newline at end of file diff --git a/im/src/components/chat/panel/OtherLink.vue b/im/src/components/chat/panel/OtherLink.vue new file mode 100644 index 00000000..15ed81ab --- /dev/null +++ b/im/src/components/chat/panel/OtherLink.vue @@ -0,0 +1,130 @@ + + + + + \ No newline at end of file diff --git a/im/src/components/chat/panel/PanelHeader.vue b/im/src/components/chat/panel/PanelHeader.vue new file mode 100644 index 00000000..dedceddc --- /dev/null +++ b/im/src/components/chat/panel/PanelHeader.vue @@ -0,0 +1,278 @@ + + + diff --git a/im/src/components/chat/panel/PanelToolbar.vue b/im/src/components/chat/panel/PanelToolbar.vue new file mode 100644 index 00000000..e55d6b20 --- /dev/null +++ b/im/src/components/chat/panel/PanelToolbar.vue @@ -0,0 +1,101 @@ + + + + diff --git a/im/src/components/chat/panel/TalkPanel.vue b/im/src/components/chat/panel/TalkPanel.vue new file mode 100644 index 00000000..72193ed5 --- /dev/null +++ b/im/src/components/chat/panel/TalkPanel.vue @@ -0,0 +1,1103 @@ + + + diff --git a/im/src/components/chat/panel/template/footPrint.vue b/im/src/components/chat/panel/template/footPrint.vue new file mode 100644 index 00000000..80bf3e25 --- /dev/null +++ b/im/src/components/chat/panel/template/footPrint.vue @@ -0,0 +1,71 @@ + + + + + \ No newline at end of file diff --git a/im/src/components/chat/panel/template/goodsLink.vue b/im/src/components/chat/panel/template/goodsLink.vue new file mode 100644 index 00000000..2c267176 --- /dev/null +++ b/im/src/components/chat/panel/template/goodsLink.vue @@ -0,0 +1,168 @@ + + + + + \ No newline at end of file diff --git a/im/src/components/chat/panel/template/storeDetail.vue b/im/src/components/chat/panel/template/storeDetail.vue new file mode 100644 index 00000000..470f09dc --- /dev/null +++ b/im/src/components/chat/panel/template/storeDetail.vue @@ -0,0 +1,75 @@ + + + + + \ No newline at end of file diff --git a/im/src/components/editor/MeEditor.vue b/im/src/components/editor/MeEditor.vue new file mode 100644 index 00000000..cc0605c0 --- /dev/null +++ b/im/src/components/editor/MeEditor.vue @@ -0,0 +1,506 @@ +