-
16.env.development
-
14.env.production
-
2.gitignore
-
104App.vue
-
35api/chat.js
-
62api/login.js
-
21index.html
-
23main.js
-
79manifest.json
-
105pages.json
-
158pages/home/user.vue
-
44pages/setting/about.vue
-
81pages/setting/contact.vue
-
75pages/setting/setting.vue
-
259pages/user/login.vue
-
173pages/user/register.vue
-
96permission.js
-
72plugins/modal.js
-
15plugins/pluginTool.js
-
74plugins/tab.js
-
BINstatic/image/app.png
-
BINstatic/image/favicon.ico
-
BINstatic/image/ninecloud-white.png
-
BINstatic/image/tabbar/chat-fill.png
-
BINstatic/image/tabbar/chat.png
-
BINstatic/image/tabbar/home-fill.png
-
BINstatic/image/tabbar/home.png
-
BINstatic/image/tabbar/type-fill.png
-
BINstatic/image/tabbar/type.png
-
BINstatic/image/tabbar/user-fill.png
-
BINstatic/image/tabbar/user.png
-
BINstatic/image/user/cc.png
-
BINstatic/image/user/login-password-blue.png
-
BINstatic/image/user/login-phone-blue.png
-
BINstatic/image/user/message.png
-
BINstatic/image/user/uset.png
-
BINstatic/image/user/yy.png
-
555static/style/nine-base-001.scss
-
136static/style/nine-base-002.scss
-
27static/style/nine-btn-001.scss
-
1static/style/nine-chat-friend-001.scss
-
1static/style/nine-chat-home-001.scss
-
36static/style/nine-image-001.scss
-
9static/style/nine-list-001.scss
-
39static/style/nine-nav-001.scss
-
8store/getters.js
-
15store/index.js
-
94store/modules/user.js
-
76uni.scss
-
42uni_modules/uni-icons/changelog.md
-
91uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
-
110uni_modules/uni-icons/components/uni-icons/uni-icons.vue
-
664uni_modules/uni-icons/components/uni-icons/uniicons.css
-
BINuni_modules/uni-icons/components/uni-icons/uniicons.ttf
-
664uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
-
649uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
-
89uni_modules/uni-icons/package.json
-
8uni_modules/uni-icons/readme.md
-
8uni_modules/uni-scss/changelog.md
-
1uni_modules/uni-scss/index.scss
-
82uni_modules/uni-scss/package.json
-
4uni_modules/uni-scss/readme.md
-
7uni_modules/uni-scss/styles/index.scss
-
3uni_modules/uni-scss/styles/setting/_border.scss
-
66uni_modules/uni-scss/styles/setting/_color.scss
-
55uni_modules/uni-scss/styles/setting/_radius.scss
-
56uni_modules/uni-scss/styles/setting/_space.scss
-
167uni_modules/uni-scss/styles/setting/_styles.scss
-
24uni_modules/uni-scss/styles/setting/_text.scss
-
146uni_modules/uni-scss/styles/setting/_variables.scss
-
19uni_modules/uni-scss/styles/tools/functions.scss
-
31uni_modules/uni-scss/theme.scss
-
62uni_modules/uni-scss/variables.scss
-
40uni_modules/vrapile-im/changelog.md
-
5uni_modules/vrapile-im/components/vrapile-im/vrapile-im.vue
-
86uni_modules/vrapile-im/package.json
-
335uni_modules/vrapile-im/pages/chat/chatFriend.vue
-
184uni_modules/vrapile-im/pages/home/chatHome.vue
-
20uni_modules/vrapile-im/pages_init.json
-
105uni_modules/vrapile-im/readme.md
-
BINuni_modules/vrapile-im/static/image/emoji.png
-
BINuni_modules/vrapile-im/static/image/message.png
-
BINuni_modules/vrapile-im/static/image/more.png
-
BINuni_modules/vrapile-im/static/image/voice.png
-
BINuni_modules/vrapile-im/static/image/yy.png
-
165uni_modules/vrapile-im/static/style/nine-chat-friend-001.scss
-
112uni_modules/vrapile-im/static/style/nine-chat-home-001.scss
-
11uni_modules/vrapile-im/store/getters.js
-
16uni_modules/vrapile-im/store/index.js
-
138uni_modules/vrapile-im/store/modules/chat.js
-
116uni_modules/vrapile-im/store/modules/socket.js
-
26uni_modules/vrapile-im/utils/cache.js
-
6uni_modules/vrapile-im/utils/constant.js
-
6uni_modules/vrapile-im/utils/errorCode.js
-
348uni_modules/vrapile-im/utils/nineTool.js
-
33uni_modules/vrapile-im/utils/storage.js
-
181uni_modules/vrapile-im/utils/tiosocket.js
-
26utils/cache.js
-
8utils/constant.js
-
6utils/errorCode.js
@ -0,0 +1,16 @@ |
|||
# 页面标题 |
|||
VITE_APP_TITLE = IM示例工程 |
|||
|
|||
# 开发环境配置 |
|||
VITE_APP_ENV = 'development' |
|||
|
|||
# 基础地址 |
|||
VITE_APP_BASE_URL = 'http://localhost:18081' |
|||
# VITE_APP_BASE_URL = 'https://api.ninecloud.top/msm' |
|||
|
|||
# socket地址 |
|||
# VITE_APP_SOCKET_URL = 'ws://localhost:9326' |
|||
VITE_APP_SOCKET_URL = 'wss://api.ninecloud.top/socket/' |
|||
|
|||
# 网站地址 |
|||
VITE_APP_WEB_URL = 'https://www.ninecloud.top/udemo/im/index.html' |
@ -0,0 +1,14 @@ |
|||
# 页面标题 |
|||
VITE_APP_TITLE = 九云商城 |
|||
|
|||
# 生产环境配置 |
|||
VITE_APP_ENV = 'production' |
|||
|
|||
# 基础地址 |
|||
VITE_APP_BASE_URL = 'https://api.ninecloud.top/msm' |
|||
|
|||
# socket地址 |
|||
VITE_APP_SOCKET_URL = 'wss://api.ninecloud.top/socket/' |
|||
|
|||
# 网站地址 |
|||
VITE_APP_WEB_URL = 'https://www.ninecloud.top/udemo/im/index.html' |
@ -0,0 +1,2 @@ |
|||
/.hbuilderx |
|||
/unpackage |
@ -0,0 +1,104 @@ |
|||
<script> |
|||
import store from '@/store' |
|||
import socketStore from '@/uni_modules/vrapile-im/store' |
|||
import { getToken } from '@/utils/token' |
|||
export default { |
|||
globalData: { |
|||
// appId |
|||
appId: "nine-demo-im", |
|||
// 系统平台 |
|||
platform: "android", |
|||
// 消息页所在索引 |
|||
msgTabBarIndex: 0, |
|||
// 版本号 |
|||
version: "1.0.0", |
|||
// 手机信息 |
|||
systemInfo: {}, |
|||
}, |
|||
onLaunch(options) { |
|||
// 初始化应用配置 |
|||
this.initConfig(options); |
|||
}, |
|||
onShow() { |
|||
// 连接websocket |
|||
this.initWebSocket(); |
|||
}, |
|||
onHide() { |
|||
}, |
|||
methods: { |
|||
initConfig(options) { |
|||
// 获取手机信息 |
|||
this.globalData.systemInfo = uni.getSystemInfoSync() |
|||
this.globalData.platform = this.globalData.systemInfo.platform |
|||
// #ifdef APP-PLUS |
|||
plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => { |
|||
if(wgtinfo.version){ |
|||
this.globalData.version = wgtinfo.version; |
|||
}else{ |
|||
// 获取当前版本号 |
|||
this.globalData.version = plus.runtime.version; |
|||
} |
|||
}); |
|||
// #endif |
|||
}, |
|||
initWebSocket(){ |
|||
if(getToken()){ |
|||
// #ifdef APP-PLUS |
|||
// app无法获取本地存储的websocket状态,只能进行重连 |
|||
socketStore.dispatch('GetChatList', {userId: store.state.user.userInfo.userId}).then( res => { |
|||
socketStore.dispatch('ConnSocket', { url: import.meta.env.VITE_APP_SOCKET_URL, token: getToken() }); |
|||
}); |
|||
// #endif |
|||
// #ifndef APP-PLUS |
|||
if(!socketStore.state.socket.websocket |
|||
|| !socketStore.state.socket.websocket.getReadyState |
|||
|| socketStore.state.socket.websocket.getReadyState() != 1){ |
|||
socketStore.dispatch('GetChatList', {userId: store.state.user.userInfo.userId}).then( res => { |
|||
socketStore.dispatch('ConnSocket', { url: import.meta.env.VITE_APP_SOCKET_URL, token: getToken() }); |
|||
}); |
|||
} |
|||
// #endif |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
html, body, #app{ |
|||
height: 100%; |
|||
background-color: #f1f1f1; |
|||
} |
|||
.nine-content-001{ |
|||
padding: 0; |
|||
margin: 0; |
|||
width: 750rpx; |
|||
height: calc(100vh - 0px); |
|||
background-color: #f1f1f1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
.nine-content-002{ |
|||
padding: 0; |
|||
margin: 0; |
|||
width: 750rpx; |
|||
height: calc(100vh - 50px); |
|||
/* #ifndef H5 */ |
|||
height: calc(100vh - 0px); |
|||
/* #endif */ |
|||
background-color: #f1f1f1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
// uni.showModal 左对齐 |
|||
.uni-modal__bd{ |
|||
text-align: left |
|||
} |
|||
|
|||
@import './static/style/nine-image-001.scss'; |
|||
@import './static/style/nine-btn-001.scss'; |
|||
@import './static/style/nine-list-001.scss'; |
|||
@import './static/style/nine-nav-001.scss'; |
|||
@import './static/style/nine-base-002.scss'; |
|||
@import './static/style/nine-base-001.scss'; |
|||
</style> |
@ -0,0 +1,35 @@ |
|||
import request from "@/utils/request" |
|||
|
|||
// 查询用户所有好友
|
|||
export function getUserAllFriend() { |
|||
return request({ |
|||
url: "/im/friend/getUserAllFriend", |
|||
method: "get" |
|||
}) |
|||
} |
|||
|
|||
// 查询用户所有群
|
|||
export function getUserAllGroup() { |
|||
return request({ |
|||
url: "/im/group/getUserAllGroup", |
|||
method: "get" |
|||
}) |
|||
} |
|||
|
|||
// 查询组用户
|
|||
export function getGroupUser(id) { |
|||
return request({ |
|||
url: "/im/groupUser/getGroupUser/"+ id + "?r=" + Math.random(), |
|||
method: "get" |
|||
}) |
|||
} |
|||
|
|||
|
|||
// 通过唯一会话key获取消息
|
|||
export function getMessageByChatKey(data) { |
|||
return request({ |
|||
url: "/im/message/getMessageByChatKey", |
|||
method: "post", |
|||
data: data |
|||
}) |
|||
} |
@ -0,0 +1,62 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// 登录方法
|
|||
export function login(type, username, password, smsCode, registerFlag, code, uuid) { |
|||
const data = { |
|||
type, |
|||
username, |
|||
password, |
|||
smsCode, |
|||
registerFlag, |
|||
code, |
|||
uuid |
|||
} |
|||
return request({ |
|||
url: '/appLogin', |
|||
headers: { |
|||
isToken: false |
|||
}, |
|||
method: 'post', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
// 注册方法
|
|||
export function register(data) { |
|||
return request({ |
|||
url: '/register', |
|||
headers: { |
|||
isToken: false |
|||
}, |
|||
method: 'post', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
// 获取用户详细信息
|
|||
export function getInfo() { |
|||
return request({ |
|||
url: '/getInfo', |
|||
method: 'get' |
|||
}) |
|||
} |
|||
|
|||
// 退出方法
|
|||
export function logout() { |
|||
return request({ |
|||
url: '/logout', |
|||
method: 'post' |
|||
}) |
|||
} |
|||
|
|||
// 获取验证码
|
|||
export function getCodeImg() { |
|||
return request({ |
|||
url: '/captchaImage', |
|||
headers: { |
|||
isToken: false |
|||
}, |
|||
method: 'get', |
|||
timeout: 20000 |
|||
}) |
|||
} |
@ -0,0 +1,21 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<script> |
|||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || |
|||
CSS.supports('top: constant(a)')) |
|||
document.write( |
|||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + |
|||
(coverSupport ? ', viewport-fit=cover' : '') + '" />') |
|||
</script> |
|||
<title></title> |
|||
<!--preload-links--> |
|||
<!--app-context--> |
|||
<link rel="icon" href="/static/image/favicon.ico"> |
|||
</head> |
|||
<body> |
|||
<div id="app"><!--app-html--></div> |
|||
<script type="module" src="/main.js"></script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,23 @@ |
|||
import { createSSRApp } from 'vue' |
|||
import App from './App' |
|||
// 存储
|
|||
import store from '@/store' |
|||
// 路由权限控制
|
|||
import '@/permission.js' |
|||
|
|||
// 框架方法
|
|||
import frameTool from "@/utils/frameTool"; |
|||
// 插件方法
|
|||
import pluginTool from "@/plugins/pluginTool.js"; |
|||
|
|||
const app = createSSRApp(App) |
|||
|
|||
app.use(store) |
|||
app.use(frameTool) |
|||
app.use(pluginTool) |
|||
|
|||
export function createApp() { |
|||
return { |
|||
app |
|||
} |
|||
} |
@ -0,0 +1,79 @@ |
|||
{ |
|||
"name" : "udemo-im", |
|||
"appid" : "__UNI__D1DA2B6", |
|||
"description" : "", |
|||
"versionName" : "1.0.0", |
|||
"versionCode" : "100", |
|||
"transformPx" : false, |
|||
/* 5+App特有相关 */ |
|||
"app-plus" : { |
|||
"usingComponents" : true, |
|||
"nvueStyleCompiler" : "uni-app", |
|||
"compilerVersion" : 3, |
|||
"splashscreen" : { |
|||
"alwaysShowBeforeRender" : true, |
|||
"waiting" : true, |
|||
"autoclose" : true, |
|||
"delay" : 0 |
|||
}, |
|||
/* 模块配置 */ |
|||
"modules" : {}, |
|||
/* 应用发布信息 */ |
|||
"distribute" : { |
|||
/* android打包配置 */ |
|||
"android" : { |
|||
"permissions" : [ |
|||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", |
|||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", |
|||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.CAMERA\"/>", |
|||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", |
|||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", |
|||
"<uses-feature android:name=\"android.hardware.camera\"/>", |
|||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" |
|||
] |
|||
}, |
|||
/* ios打包配置 */ |
|||
"ios" : {}, |
|||
/* SDK配置 */ |
|||
"sdkConfigs" : {} |
|||
} |
|||
}, |
|||
/* 快应用特有相关 */ |
|||
"quickapp" : {}, |
|||
/* 小程序特有相关 */ |
|||
"mp-weixin" : { |
|||
"appid" : "", |
|||
"setting" : { |
|||
"urlCheck" : false |
|||
}, |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-alipay" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-baidu" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-toutiao" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"uniStatistics" : { |
|||
"enable" : false |
|||
}, |
|||
"vueVersion" : "3", |
|||
"h5" : { |
|||
"title" : "im", |
|||
"router" : { |
|||
"mode" : "hash", |
|||
"base" : "/udemo/im/" |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,105 @@ |
|||
{ |
|||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages |
|||
// 我的 |
|||
{ |
|||
"path": "pages/home/user", |
|||
"style" : { |
|||
"navigationBarTitleText": "我的", |
|||
"enablePullDownRefresh": false |
|||
} |
|||
}, |
|||
{ |
|||
"path": "uni_modules/vrapile-im/pages/home/chatHome", |
|||
"style": { |
|||
"enablePullDownRefresh": false, |
|||
"navigationBarTitleText": "消息" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "uni_modules/vrapile-im/pages/chat/chatFriend", |
|||
"style": { |
|||
"enablePullDownRefresh": true, |
|||
"navigationBarTitleText": "聊天" |
|||
} |
|||
} |
|||
], |
|||
"subPackages": [ |
|||
//用户 |
|||
{ |
|||
"root": "pages/user", |
|||
"pages": [ |
|||
{ |
|||
"path": "login", |
|||
"style": { |
|||
"navigationBarTitleText": "登录", |
|||
"enablePullDownRefresh": false |
|||
} |
|||
}, |
|||
{ |
|||
"path": "register", |
|||
"style": { |
|||
"navigationBarTitleText": "注册", |
|||
"enablePullDownRefresh": false |
|||
} |
|||
} |
|||
] |
|||
}, |
|||
//设置 |
|||
{ |
|||
"root": "pages/setting", |
|||
"pages": [ |
|||
{ |
|||
"path" : "about", |
|||
"style" : { |
|||
"navigationBarTitleText": "关于", |
|||
"enablePullDownRefresh": false |
|||
} |
|||
}, |
|||
{ |
|||
"path" : "contact", |
|||
"style" : { |
|||
"navigationBarTitleText": "联系我们", |
|||
"enablePullDownRefresh": false |
|||
} |
|||
}, |
|||
{ |
|||
"path" : "setting", |
|||
"style" : { |
|||
"navigationBarTitleText": "设置", |
|||
"enablePullDownRefresh": false |
|||
} |
|||
} |
|||
] |
|||
} |
|||
], |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "IM", |
|||
"navigationBarBackgroundColor": "#FFFFFF", |
|||
"h5": { |
|||
"titleNView": false, |
|||
"maxWidth": 1190, |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#FFFFFF" |
|||
}, |
|||
"backgroundColor": "#F8F8F8" |
|||
}, |
|||
"tabBar": { |
|||
"selectedColor": "#0000ff", |
|||
"list": [ |
|||
{ |
|||
"pagePath": "uni_modules/vrapile-im/pages/home/chatHome", |
|||
"iconPath": "static/image/tabbar/chat.png", |
|||
"selectedIconPath": "static/image/tabbar/chat-fill.png", |
|||
"text": "消息" |
|||
}, |
|||
{ |
|||
"pagePath": "pages/home/user", |
|||
"iconPath": "static/image/tabbar/user.png", |
|||
"selectedIconPath": "static/image/tabbar/user-fill.png", |
|||
"text": "我的" |
|||
} |
|||
] |
|||
}, |
|||
"uniIdRouter": {} |
|||
} |
@ -0,0 +1,158 @@ |
|||
<template> |
|||
<view class="nine-content-002"> |
|||
<view class="user-header"> |
|||
<view class="user-header-top"> |
|||
<view class="user-header-top-info"> |
|||
<view class="user-header-top-info-logo"> |
|||
<image class="user-header-top-info-logo-image" :src="userInfo.avatar || '/static/image/user/yy.png'"></image> |
|||
</view> |
|||
<view class="user-header-top-info-name"> |
|||
<view v-if="userInfo.userId" class="user-header-top-info-name-username"> |
|||
{{userInfo.userName}} |
|||
</view> |
|||
<view v-else class="user-header-top-info-name-username" |
|||
@click="openUrl('/pages/user/login')">未登录</view> |
|||
</view> |
|||
</view> |
|||
<view v-if="userInfo.userId" class="user-header-top-message"> |
|||
<image class="user-header-top-message-image" src="/static/image/user/message.png"></image> |
|||
</view> |
|||
</view> |
|||
<view class="user-header-recommend"> |
|||
<span v-if="userInfo.userId">昵称:{{userInfo.nickName}}</span> |
|||
<span v-else>昵称:无</span> |
|||
<span class="pr10">普通用户</span> |
|||
</view> |
|||
<view class="user-header-member"> |
|||
<view v-if="userInfo.userId" class="user-header-member-rank"> |
|||
等级:{{array[1]}} |
|||
</view> |
|||
<view v-else class="user-header-member-rank"> |
|||
等级:无 |
|||
</view> |
|||
<view class="user-header-member-note"> |
|||
会员等级越高权益越高 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="nine-nav-001 pa5"> |
|||
<view class="nine-nav-001-item mt10" @click="openUrl('/pages/setting/setting')"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<image class="image35" mode="scaleToFill" src="/static/image/user/uset.png"></image> |
|||
<text class="nine-nav-001-item-left-text">设置</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import store from '@/store' |
|||
import storage from '@/utils/storage' |
|||
import constant from '@/utils/constant' |
|||
import { getToken } from '@/utils/token' |
|||
export default { |
|||
data() { |
|||
return { |
|||
array: [ |
|||
"普通会员", |
|||
"高级会员", |
|||
"超级会员" |
|||
], |
|||
|
|||
userInfo: {}, |
|||
|
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
this.userInfo = store.state.user.userInfo; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.user{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 100vh; |
|||
background-color: #f1f1f1; |
|||
} |
|||
.user-header { |
|||
width: 100%; |
|||
background-color: #00aaff; |
|||
position: relative; |
|||
} |
|||
.user-header-top { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
} |
|||
.user-header-top-info{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
padding: 20rpx 40rpx 10rpx 40rpx; |
|||
} |
|||
.user-header-top-info-logo{ |
|||
} |
|||
.user-header-top-info-logo-image{ |
|||
width: 165rpx; |
|||
height: 165rpx; |
|||
border-radius: 50%; |
|||
will-change: transform; |
|||
} |
|||
.user-header-top-info-name{ |
|||
padding: 20rpx; |
|||
} |
|||
.user-header-top-info-name-username{ |
|||
font-size: 20px; |
|||
} |
|||
.user-header-top-message{ |
|||
} |
|||
.user-header-top-message-image{ |
|||
padding-right: 40rpx; |
|||
padding-top: 40rpx; |
|||
width: 45rpx; |
|||
height: 55rpx; |
|||
} |
|||
.user-header-recommend{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
padding: 10rpx 30rpx 70rpx 40rpx; |
|||
font-size: 12px; |
|||
} |
|||
.user-header-member{ |
|||
position: absolute; |
|||
height: 40rpx; |
|||
bottom: 0rpx; |
|||
left: 40rpx; |
|||
right: 40rpx; |
|||
padding: 10rpx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
background-color: #474747; |
|||
border-top-left-radius: 10rpx; |
|||
border-top-right-radius: 10rpx; |
|||
} |
|||
.user-header-member-rank{ |
|||
padding: 10rpx 10rpx; |
|||
font-size: 10px; |
|||
color: #ffaa00; |
|||
} |
|||
.user-header-member-note{ |
|||
font-size: 10px; |
|||
padding: 8rpx 20rpx; |
|||
color: #919191; |
|||
background-color: #2e2e2e; |
|||
border-radius: 80rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,44 @@ |
|||
<template> |
|||
<view class="nine-content-001"> |
|||
<view class="text-center ptb120"> |
|||
<image class="image150" src="/static/image/app.png" mode="scaleToFill" ></image> |
|||
<view class="font-bold font-size20 mt10"> |
|||
九云 IM Demo |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001"> |
|||
<view class="nine-nav-001-item ma10 ptb25"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">下载APP</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001-item ma10 ptb25"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">更新日志</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="ptb30"> |
|||
<view class="text-center color-blue font-size15"> |
|||
九云科技有限公司《服务协议》 |
|||
</view> |
|||
<view class="text-center font-size15"> |
|||
九云科技 版权所有 |
|||
</view> |
|||
<view class="text-center font-size15"> |
|||
Copyright © 2024-2031 NineCloud. |
|||
</view> |
|||
<view class="text-center font-size15"> |
|||
All Rights Reserved |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
@ -0,0 +1,81 @@ |
|||
<template> |
|||
<view class="nine-content-001"> |
|||
<view class="text-center ptb120"> |
|||
<image class="image400" :src="wechatUrl" mode="scaleToFill" ></image> |
|||
<view class="font-size18 mt10"> |
|||
微信账号:{{ wechatAccount }} |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001"> |
|||
<view class="nine-nav-001-item ma10 ptb25"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">联系人</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<text class="nine-nav-001-item-left-text">袁先生</text> |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001-item ma10 ptb25"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">联系电话</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<text class="nine-nav-001-item-left-text color-blue" @click="callPhone('18627959669')">18627959669</text> |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001-item ma10 ptb25"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">微信号</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<text class="nine-nav-001-item-left-text">18627959669</text> |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001-item ma10 ptb25"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">邮箱账号</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<text class="nine-nav-001-item-left-text">18627959669@163.com</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="ptb30"> |
|||
<view class="text-center color-blue font-size15"> |
|||
九云科技有限公司《服务协议》 |
|||
</view> |
|||
<view class="text-center font-size15"> |
|||
九云科技 版权所有 |
|||
</view> |
|||
<view class="text-center font-size15"> |
|||
Copyright © 2024-2031 NineCloud. |
|||
</view> |
|||
<view class="text-center font-size15"> |
|||
All Rights Reserved |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
wechatUrl: "https://fs.ninecloud.top/uniapp/unine/vrapile.png", |
|||
wechatAccount: "Vrapile", |
|||
}; |
|||
}, |
|||
onLoad() { |
|||
}, |
|||
onShow(){ |
|||
}, |
|||
methods: { |
|||
callPhone(phoneNumber) { |
|||
uni.makePhoneCall({ |
|||
phoneNumber: phoneNumber |
|||
}); |
|||
} |
|||
} |
|||
|
|||
}; |
|||
</script> |
@ -0,0 +1,75 @@ |
|||
<template> |
|||
<view class="nine-content-001"> |
|||
<!-- 功能列表 --> |
|||
<view class="nine-nav-001"><view class="nine-nav-001-item mt10"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">公告中心</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
<view v-if="userInfo.userId" class="nine-nav-001-item mt10"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">修改密码</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001-item mt10" @click="openUrl('/pages/setting/contact')"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">联系我们</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001-item"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">清空缓存</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
<view class="nine-nav-001-item" @click="openUrl('/pages/setting/about')"> |
|||
<view class="nine-nav-001-item-left"> |
|||
<text class="nine-nav-001-item-left-text">关于</text> |
|||
</view> |
|||
<view class="nine-nav-001-item-right"> |
|||
<image class="nine-nav-001-item-right-image" mode="scaleToFill" src="/static/image/user/cc.png"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
<view v-if="userInfo.userId" class="nine-btn-login-out-001 mt50" @click="logoutClick"> |
|||
退出登录 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import store from '@/store' |
|||
export default { |
|||
data() { |
|||
return { |
|||
userInfo: {}, |
|||
}; |
|||
}, |
|||
onShow(){ |
|||
this.userInfo = this.$store.state.user.userInfo; |
|||
}, |
|||
methods: { |
|||
logoutClick() { |
|||
this.$store.dispatch('LogOut').then(res => { |
|||
this.reLaunchLogin(); |
|||
}) |
|||
} |
|||
} |
|||
}; |
|||
</script> |
@ -0,0 +1,259 @@ |
|||
<template> |
|||
<view class="nine-content-001"> |
|||
<view class="login"> |
|||
<view class="login-logo"> |
|||
<image class="login-logo-image" lazy-load="true" src="/static/image/ninecloud-white.png"></image> |
|||
</view> |
|||
<view class="login-block"> |
|||
<view class="login-type"> |
|||
<span @click="onNavBarTap(0)" :class="loginType == 0?'login-type-span-alive login-type-span':'login-type-span'"> |
|||
密码登录 |
|||
</span> |
|||
<span @click="onNavBarTap(1)" :class="loginType == 1?'login-type-span-alive login-type-span':'login-type-span'"> |
|||
短信登录 |
|||
</span> |
|||
</view> |
|||
<view class="login-phone"> |
|||
<image class="login-phone-image" src="/static/image/user/login-phone-blue.png"></image> |
|||
<input class="login-phone-input input" :focus="isFocus=='username'" name="phone" placeholder="请输入您的账号/手机号" v-model="userName" @confirm="loginClick"/> |
|||
</view> |
|||
<view class="nine-line-001 mlr30"></view> |
|||
<view v-if="loginType == 0" class="login-phone"> |
|||
<image class="login-phone-image" src="/static/image/user/login-password-blue.png"></image> |
|||
<input class="login-phone-input input" :focus="isFocus=='password'" password placeholder="请输入您的密码" v-model="password" @confirm="loginClick"/> |
|||
</view> |
|||
<view v-if="loginType == 1" class="login-verify"> |
|||
<view class="display-flex-row"> |
|||
<image class="login-verify-image" src="/static/image/user/login-password-blue.png"></image> |
|||
<input class="login-verify-input input" :focus="isFocus=='verify'" placeholder="请输入验证码" v-model="verifyCode" @confirm="loginClick"/> |
|||
</view> |
|||
<view class="nine-btn-verify-001 font-size12 text-nowrap pa10" @click="verifyClick"> |
|||
{{verifyText}} |
|||
</view> |
|||
</view> |
|||
<view class="nine-line-001 mlr30"></view> |
|||
<view class="ma15 mr30 text-right color-blue" @click="forgetClick"> |
|||
忘记密码? |
|||
</view> |
|||
<view class="nine-btn-save-001 ma20" @click="loginClick">登 录</view> |
|||
<!--#ifndef MP-WEIXIN--> |
|||
<view class="text-center ma20">没有账号? |
|||
<span class="ml10 color-blue" @click="registerClick"> |
|||
立即注册 |
|||
</span> |
|||
</view> |
|||
<!--#endif--> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import store from '@/store' |
|||
import socketStore from '@/uni_modules/vrapile-im/store' |
|||
import { getToken } from '@/utils/token' |
|||
export default { |
|||
data() { |
|||
return { |
|||
loginType: 0, |
|||
|
|||
userName: "", |
|||
password: "", |
|||
|
|||
verifyTimer: null, |
|||
verifyCode: "", |
|||
verifyTime: 0, |
|||
verifyText: "发送验证码", |
|||
|
|||
isFocus: "" |
|||
} |
|||
}, |
|||
// onBackPress(e){ |
|||
// return true; |
|||
// }, |
|||
onUnload() { |
|||
if(this.verifyTimer) { |
|||
clearTimeout(this.verifyTimer); |
|||
this.verifyTimer = null; |
|||
this.verifyTime = 0; |
|||
} |
|||
}, |
|||
onShow(){ |
|||
let loginInfo = this.$store.state.user.loginInfo; |
|||
this.loginType = loginInfo.loginType || 0; |
|||
this.userName = loginInfo.userName; |
|||
this.password = loginInfo.password; |
|||
if(!this.userName){ |
|||
this.usernamefocus(); |
|||
}else if(this.loginType == 0){ |
|||
this.passwordfocus(); |
|||
}else{ |
|||
this.verifyfocus(); |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
onNavBarTap (index) { |
|||
this.loginType = index; |
|||
}, |
|||
verifyClick(){ |
|||
if(this.verifyTime != 0){ |
|||
return; |
|||
} |
|||
if(!this.isPhone(this.userName)){ |
|||
this.msg("必须为有效手机号"); |
|||
return; |
|||
} |
|||
|
|||
this.verifyTime = 60; |
|||
this.verifyText = this.verifyTime + " S"; |
|||
this.verifyTimer = setInterval(() => { |
|||
this.timeInterval(); |
|||
}, 1000) |
|||
this.diyApiGet('/captchaSms', {phone: this.userName}).catch(error => { |
|||
if(this.verifyTimer) { |
|||
clearTimeout(this.verifyTimer); |
|||
this.verifyTimer = null; |
|||
this.verifyTime = 0; |
|||
} |
|||
this.verifyText = "发送验证码"; |
|||
}); |
|||
}, |
|||
timeInterval() { |
|||
this.verifyTime--; |
|||
if (this.verifyTime > 0) { |
|||
this.verifyText = this.verifyTime + " S"; |
|||
}else{ |
|||
if(this.verifyTimer) { |
|||
clearInterval(this.verifyTimer); |
|||
this.verifyTimer = null; |
|||
} |
|||
this.verifyText = "发送验证码"; |
|||
} |
|||
}, |
|||
loginClick(){ |
|||
if(!this.userName){ |
|||
this.usernamefocus(); |
|||
return; |
|||
} |
|||
if(this.loginType==0 && !this.password){ |
|||
this.passwordfocus(); |
|||
return; |
|||
} |
|||
if(this.loginType==1 && !this.verifyCode){ |
|||
this.verifyfocus(); |
|||
return; |
|||
} |
|||
this.loading("正在登录..."); |
|||
store.dispatch('Login', { |
|||
loginType: this.loginType, |
|||
userName: this.userName.trim(), |
|||
password: this.password, |
|||
smsCode: this.verifyCode, |
|||
registerFlag: "Y" |
|||
}).then(() => { |
|||
this.loginSuccess() |
|||
}).catch(() => { |
|||
}) |
|||
}, |
|||
loginSuccess() { |
|||
store.dispatch('GetInfo').then(res => { |
|||
socketStore.dispatch('GetChatList', {userId: store.state.user.userInfo.userId}).then(res=>{ |
|||
socketStore.dispatch('ConnSocket', { url: import.meta.env.VITE_APP_SOCKET_URL, token: getToken() }); |
|||
}); |
|||
this.reLaunch('/pages/home/user') |
|||
this.closeLoading() |
|||
}).catch(()=>{ |
|||
this.closeLoading() |
|||
}) |
|||
}, |
|||
registerClick() { |
|||
this.navigateTo('/pages/user/register') |
|||
}, |
|||
forgetClick() { |
|||
// this.navigateTo('/pages/user/forget') |
|||
}, |
|||
usernamefocus() { |
|||
this.isFocus = "username"; |
|||
}, |
|||
passwordfocus() { |
|||
this.isFocus = "password"; |
|||
}, |
|||
verifyfocus() { |
|||
this.isFocus = "verify"; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.login{ |
|||
width: 750rpx; |
|||
height: 100vh; |
|||
background-color: #55aaff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
align-items: center; |
|||
padding-bottom: 50rpx; |
|||
} |
|||
.login-logo{ |
|||
width: 650rpx; |
|||
opacity: 0.9; |
|||
} |
|||
.login-logo-image{ |
|||
width: 600rpx; |
|||
height: 160rpx; |
|||
} |
|||
.login-block{ |
|||
width: 630rpx; |
|||
background-color: #FFFFFF; |
|||
border-radius: 10rpx; |
|||
margin: 40rpx 0 150rpx 0; |
|||
padding: 15rpx; |
|||
} |
|||
.login-type{ |
|||
margin: 20rpx; |
|||
display: flex; |
|||
justify-content: space-around; |
|||
} |
|||
.login-type-span{ |
|||
width: 280rpx; |
|||
padding: 15rpx 0; |
|||
font-size: 20px; |
|||
border-radius: 10rpx; |
|||
text-align: center; |
|||
color: gray; |
|||
background-color: #ebf7ff; |
|||
} |
|||
.login-type-span-alive{ |
|||
color: #fff; |
|||
background-color: #55aaff; |
|||
} |
|||
.login-phone{ |
|||
display: flex; |
|||
align-items: center; |
|||
margin: 30rpx; |
|||
padding: 20rpx 20rpx 0 0rpx; |
|||
} |
|||
.login-verify{ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
margin: 30rpx; |
|||
padding-top: 20rpx; |
|||
} |
|||
|
|||
.login-phone-image, |
|||
.login-verify-image{ |
|||
padding: 10rpx; |
|||
height: 40rpx; |
|||
width: 40rpx; |
|||
} |
|||
.login-phone-input, |
|||
.login-verify-input{ |
|||
padding: 10rpx; |
|||
width: 100%; |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,173 @@ |
|||
<template> |
|||
<view class="nine-content-001"> |
|||
<view class="nine-list-001"> |
|||
<view class="nine-list-001-item"> |
|||
<span>用户账号</span> |
|||
<input class="mt10" placeholder="请输入用户账号" v-model="userName"/> |
|||
</view> |
|||
<view class="nine-list-001-item"> |
|||
<span>用户姓名</span> |
|||
<input class="mt10" placeholder="请输入用户姓名" v-model="nickName"/> |
|||
</view> |
|||
<view class="nine-list-001-item"> |
|||
<span>手机号</span> |
|||
<view class="display-flex-row"> |
|||
<span class="mt10 mr20 color-gray">+86</span> |
|||
<input class="mt10" placeholder="请输入手机号" v-model="phone"/> |
|||
</view> |
|||
</view> |
|||
<view class="nine-list-001-item"> |
|||
<span>登录密码</span> |
|||
<input class="mt10" password placeholder="请输入登录密码" v-model="password"/> |
|||
</view> |
|||
<view class="nine-list-001-item"> |
|||
<span>确认密码</span> |
|||
<input class="mt10" password placeholder="请再次输入登录密码" v-model="password2"/> |
|||
</view> |
|||
<view class="nine-list-001-item"> |
|||
<view class="display-flex-row-between"> |
|||
<span>验证码</span> |
|||
<view class="nine-btn-verify-001 plr10 ptb5" @click="verifyClick"> |
|||
<span>{{verifyText}}</span> |
|||
</view> |
|||
</view> |
|||
<input class="mt10" placeholder="请输入验证码" v-model="verifyCode"/> |
|||
</view> |
|||
<view class="display-flex-row pt20 pb10 justify-content-center"> |
|||
<label class="display-flex-row"> |
|||
<checkbox class="transform-scale07" :value="protocolFlag" :checked="protocolFlag==1" @click="checkBoxClick"/> |
|||
已阅读并同意 |
|||
</label> |
|||
<span class="color-blue" @click="protocolClick">《服务协议》</span> |
|||
</view> |
|||
|
|||
<view class="nine-btn-save-001 ma20" @click="registerClick"> |
|||
注 册 |
|||
</view> |
|||
<view class="text-center">已有账号? |
|||
<span class="ml10 color-blue" @click="loginClick">立即登录</span> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import store from "@/store" |
|||
export default { |
|||
data() { |
|||
return { |
|||
userName: "", |
|||
nickName: "", |
|||
phone: "", |
|||
password: "", |
|||
password2: "", |
|||
|
|||
protocolFlag: "0", |
|||
|
|||
verifyTimer: null, |
|||
verifyCode: "", |
|||
verifyTime: 0, |
|||
verifyText: "发送验证码" |
|||
} |
|||
}, |
|||
methods: { |
|||
checkBoxClick(){ |
|||
this.protocolFlag = String(1 - Number(this.protocolFlag)); |
|||
}, |
|||
registerClick(){ |
|||
if(!this.userName){ |
|||
this.msg("用户账号不允许为空"); |
|||
return; |
|||
} |
|||
if(!this.isNumberOrLetter(this.userName)){ |
|||
this.msg("用户账号只能是字母/数字组合"); |
|||
return; |
|||
} |
|||
if(!this.nickName){ |
|||
this.msg("用户姓名不允许为空"); |
|||
return; |
|||
} |
|||
if(!this.phone){ |
|||
this.msg("手机号不允许为空"); |
|||
return; |
|||
} |
|||
if(!this.isPhone(this.phone)){ |
|||
this.msg("必须为有效手机号"); |
|||
return; |
|||
} |
|||
if(!this.verifyCode){ |
|||
this.msg("验证码不允许为空"); |
|||
return; |
|||
} |
|||
if(!this.password){ |
|||
this.msg("登录密码不允许为空"); |
|||
return; |
|||
} |
|||
if(!this.password2){ |
|||
this.msg("确认密码不允许为空"); |
|||
return; |
|||
} |
|||
if(this.password != this.password2){ |
|||
this.msg("两次输入的登录密码不一致"); |
|||
return; |
|||
} |
|||
if(this.protocolFlag == 0){ |
|||
this.msg("请勾选服务协议"); |
|||
return; |
|||
} |
|||
this.diyApi('/appRegister', { |
|||
userType: "app_user", |
|||
userName: this.userName.trim(), |
|||
nickName: this.nickName, |
|||
phone: this.phone, |
|||
password: this.password, |
|||
smsCode: this.verifyCode |
|||
}).then(res => { |
|||
store.commit('SET_LOGIN_INFO', { |
|||
...this.$store.state.user.loginInfo, |
|||
loginType: 0, |
|||
userName: this.userName, |
|||
password: this.password |
|||
}) |
|||
this.msg("注册成功"); |
|||
setTimeout(() => { |
|||
this.navigateToLogin(); |
|||
}, 1500); |
|||
}) |
|||
}, |
|||
loginClick(){ |
|||
this.navigateToLogin(); |
|||
}, |
|||
protocolClick(){ |
|||
// this.navigateTo("/pages/setting/protocol") |
|||
}, |
|||
verifyClick(){ |
|||
if(this.verifyTime == 0){ |
|||
if(!this.phone){ |
|||
this.msg("必须为有效手机号"); |
|||
return; |
|||
} |
|||
this.diyApiGet('/captchaSms', {phone: this.phone}).then(res => { |
|||
this.verifyTime = 60; |
|||
this.verifyText = this.verifyTime + " S"; |
|||
this.verifyTimer = setInterval(() => { |
|||
this.timeInterval(); |
|||
}, 1000) |
|||
}) |
|||
} |
|||
}, |
|||
timeInterval() { |
|||
this.verifyTime--; |
|||
if (this.verifyTime > 0) { |
|||
this.verifyText = this.verifyTime + " S"; |
|||
}else{ |
|||
if(this.verifyTimer) { |
|||
clearInterval(this.verifyTimer); |
|||
this.verifyTimer = null; |
|||
} |
|||
this.verifyText = "发送验证码"; |
|||
} |
|||
}, |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,96 @@ |
|||
import store from '@/store' |
|||
import { getToken } from '@/utils/token' |
|||
import { setNodeId, getNodeId } from '@/utils/nodeId' |
|||
import { diyApi } from '@/utils/queryByDiy'; |
|||
import { getLongRandom } from '@/utils/nineTool'; |
|||
|
|||
// 登录页面
|
|||
const loginPage = "/pages/user/login" |
|||
|
|||
// 页面白名单
|
|||
const whiteList = [ |
|||
'/pages/user/login', |
|||
'/pages/user/register', |
|||
'/pages/user/forget', |
|||
'/pages/setting/protocol', |
|||
'/pages/common/webview/index' |
|||
] |
|||
|
|||
// 检查地址白名单
|
|||
function checkWhite(url) { |
|||
const path = url.split('?')[0] |
|||
return whiteList.indexOf(path) !== -1 |
|||
} |
|||
|
|||
// 保存访问日志
|
|||
function saveAccessLog(to, f) { |
|||
// 开发环境不保存日志
|
|||
if(import.meta.env.VITE_APP_ENV == 'development'){ |
|||
return; |
|||
} |
|||
// 生成一个nodeId,用于记录日志
|
|||
let nodeId = getNodeId(); |
|||
if(!nodeId){ |
|||
nodeId = getLongRandom(24) |
|||
setNodeId(nodeId) |
|||
} |
|||
let flag = "udemo_im_other_" + f; |
|||
// #ifdef MP-WEIXIN
|
|||
flag = "udemo_im_wx_" + f; |
|||
// #endif
|
|||
// #ifdef H5
|
|||
flag = "udemo_im_h5_" + f; |
|||
// #endif
|
|||
// #ifdef APP-PLUS
|
|||
flag = "udemo_im_app_" + f; |
|||
// #endif
|
|||
let data = { |
|||
flag: flag, |
|||
fullPath: to.url.split("?")[0], |
|||
allPath: to.url, |
|||
menuName: to.tabBarText, |
|||
userId: store.state.user.userInfo.userId, |
|||
userName: store.state.user.userInfo.userName, |
|||
nodeId: nodeId |
|||
} |
|||
diyApi("/system/log/insSysAccessLog", data); |
|||
} |
|||
|
|||
// 页面跳转验证拦截器
|
|||
let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"] |
|||
list.forEach(item => { |
|||
uni.addInterceptor(item, { |
|||
invoke(to) { |
|||
if (getToken()) { |
|||
if (to.url === loginPage) { |
|||
uni.reLaunch({ url: "/" }) |
|||
} |
|||
saveAccessLog(to, "generate"); |
|||
return true |
|||
} else { |
|||
if (checkWhite(to.url)) { |
|||
saveAccessLog(to, "white"); |
|||
return true |
|||
} |
|||
saveAccessLog(to, "nologin"); |
|||
// 密码登录的,实现自动重新登录
|
|||
let loginInfo = store.state.user.loginInfo; |
|||
if(loginInfo && loginInfo.loginType == 0){ |
|||
store.dispatch('Login', { |
|||
loginType: loginInfo.loginType, |
|||
userName: loginInfo.userName, |
|||
password: loginInfo.password, |
|||
registerFlag: "N" |
|||
}).then(() => { |
|||
store.dispatch('GetInfo'); |
|||
}) |
|||
return true |
|||
} |
|||
return true |
|||
} |
|||
}, |
|||
fail(err) { |
|||
console.error(err) |
|||
} |
|||
}) |
|||
}) |
@ -0,0 +1,72 @@ |
|||
// 消息提示
|
|||
export function msg(content) { |
|||
uni.showToast({ |
|||
title: content, |
|||
icon: 'none' |
|||
}) |
|||
} |
|||
// 错误消息
|
|||
export function msgError(content) { |
|||
uni.showToast({ |
|||
title: content, |
|||
icon: 'error' |
|||
}) |
|||
} |
|||
// 成功消息
|
|||
export function msgSuccess(content) { |
|||
uni.showToast({ |
|||
title: content, |
|||
icon: 'success' |
|||
}) |
|||
} |
|||
// 隐藏消息
|
|||
export function hideMsg(content) { |
|||
uni.hideToast() |
|||
} |
|||
// 弹出提示
|
|||
export function alert(content, title) { |
|||
uni.showModal({ |
|||
title: title || '系统提示', |
|||
content: content, |
|||
showCancel: false |
|||
}) |
|||
} |
|||
// 确认窗体
|
|||
export function confirm(content, title) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.showModal({ |
|||
title: title || '系统提示', |
|||
content: content, |
|||
cancelText: '取消', |
|||
confirmText: '确定', |
|||
success: function(res) { |
|||
if (res.confirm) { |
|||
resolve(res.confirm) |
|||
} |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
// 提示信息
|
|||
export function showToast(option) { |
|||
if (typeof option === "object") { |
|||
uni.showToast(option) |
|||
} else { |
|||
uni.showToast({ |
|||
title: option, |
|||
icon: "none", |
|||
duration: 2500 |
|||
}) |
|||
} |
|||
} |
|||
// 打开遮罩层
|
|||
export function loading(content) { |
|||
uni.showLoading({ |
|||
title: content, |
|||
icon: 'none' |
|||
}) |
|||
} |
|||
// 关闭遮罩层
|
|||
export function closeLoading() { |
|||
uni.hideLoading() |
|||
} |
@ -0,0 +1,15 @@ |
|||
import * as tab from '@/plugins/tab.js' |
|||
import * as modal from '@/plugins/modal.js' |
|||
|
|||
export default { |
|||
install(app) { |
|||
// tab工具
|
|||
Object.keys(tab).forEach((key) => { |
|||
app.config.globalProperties[key] = tab[key]; |
|||
}) |
|||
// modal工具
|
|||
Object.keys(modal).forEach((key) => { |
|||
app.config.globalProperties[key] = modal[key]; |
|||
}); |
|||
} |
|||
}; |
@ -0,0 +1,74 @@ |
|||
// 关闭所有页面,打开到应用内的某个页面
|
|||
export function reLaunch(url) { |
|||
return uni.reLaunch({ |
|||
url: url |
|||
}) |
|||
} |
|||
export function reLaunchLogin() { |
|||
return uni.reLaunch({ |
|||
url: '/pages/user/login' |
|||
}) |
|||
} |
|||
// 跳转到tabBar页面,并关闭其他所有非tabBar页面
|
|||
export function switchTab(url) { |
|||
return uni.switchTab({ |
|||
url: url |
|||
}) |
|||
} |
|||
// 关闭当前页面,跳转到应用内的某个页面
|
|||
export function redirectTo(url) { |
|||
return uni.redirectTo({ |
|||
url: url |
|||
}) |
|||
} |
|||
// 保留当前页面,跳转到应用内的某个页面
|
|||
export function navigateTo(url) { |
|||
return uni.navigateTo({ |
|||
url: url |
|||
}) |
|||
} |
|||
// 保留当前页面,跳转到应用内的某个页面
|
|||
export function navigateToLogin() { |
|||
return uni.navigateTo({ |
|||
url: '/pages/user/login' |
|||
}) |
|||
} |
|||
// 关闭当前页面,返回上一页面或多级页面
|
|||
export function navigateBack() { |
|||
return uni.navigateBack() |
|||
} |
|||
|
|||
export function openUrl(url) { |
|||
if(!url || typeof url == 'object' || url == '#'){ |
|||
uni.showToast({ |
|||
title: '此功能正开发中,敬请期待!', |
|||
icon: 'none' |
|||
}) |
|||
return; |
|||
} |
|||
uni.navigateTo({ |
|||
url: url |
|||
}) |
|||
} |
|||
|
|||
export function pageScrollTo(scrollTop, duration=0) { |
|||
uni.pageScrollTo({ |
|||
scrollTop: scrollTop, |
|||
duration: duration |
|||
}); |
|||
} |
|||
|
|||
// 复制
|
|||
export function setClipboardData(content) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.setClipboardData({ |
|||
data: content, |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
resolve(res.confirm) |
|||
} |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
|
After ![]() Width: 100 | Height: 100 | Size: 14 KiB |
After ![]() Width: 189 | Height: 48 | Size: 5.9 KiB |
After ![]() Width: 156 | Height: 156 | Size: 7.5 KiB |
After ![]() Width: 156 | Height: 156 | Size: 7.2 KiB |
After ![]() Width: 156 | Height: 156 | Size: 7.1 KiB |
After ![]() Width: 156 | Height: 156 | Size: 9.6 KiB |
After ![]() Width: 156 | Height: 156 | Size: 20 KiB |
After ![]() Width: 156 | Height: 156 | Size: 28 KiB |
After ![]() Width: 156 | Height: 156 | Size: 15 KiB |
After ![]() Width: 156 | Height: 156 | Size: 17 KiB |
After ![]() Width: 27 | Height: 46 | Size: 1.7 KiB |
After ![]() Width: 54 | Height: 58 | Size: 5.2 KiB |
After ![]() Width: 40 | Height: 56 | Size: 3.3 KiB |
After ![]() Width: 53 | Height: 60 | Size: 5.4 KiB |
After ![]() Width: 68 | Height: 64 | Size: 6.5 KiB |
After ![]() Width: 45 | Height: 45 | Size: 7.1 KiB |
@ -0,0 +1,555 @@ |
|||
.text-center{ text-align: center } |
|||
.text-right{ text-align: right } |
|||
.text-left{ text-align: left } |
|||
|
|||
.font-size6{ font-size: 6px } |
|||
.font-size8{ font-size: 8px } |
|||
.font-size10{ font-size: 10px } |
|||
.font-size12{ font-size: 12px } |
|||
.font-size14{ font-size: 14px } |
|||
.font-size16{ font-size: 16px } |
|||
.font-size18{ font-size: 18px } |
|||
.font-size20{ font-size: 20px } |
|||
.font-size22{ font-size: 22px } |
|||
.font-size24{ font-size: 24px } |
|||
.font-size26{ font-size: 26px } |
|||
.font-size28{ font-size: 28px } |
|||
.font-size30{ font-size: 30px } |
|||
.font-size32{ font-size: 32px } |
|||
.font-size34{ font-size: 34px } |
|||
.font-size36{ font-size: 36px } |
|||
.font-size38{ font-size: 38px } |
|||
.font-size40{ font-size: 40px } |
|||
.font-size60{ font-size: 60px } |
|||
.font-size80{ font-size: 80px } |
|||
|
|||
.font-bold{ font-weight: bold } |
|||
|
|||
.color-red{ color: red } |
|||
.color-green{ color: green } |
|||
.color-white{ color: white } |
|||
.color-gray{ color: gray } |
|||
.color-blue{ color: blue } |
|||
.color-yellow{ color: yellow } |
|||
.color-black{ color: black } |
|||
.color-f1f1f1{ color: #f1f1f1 } |
|||
|
|||
.bgcolor-blue{ background-color: blue } |
|||
.bgcolor-red{ background-color: red } |
|||
.bgcolor-pink{ background-color: pink } |
|||
.bgcolor-white{ background-color: white } |
|||
.bgcolor-lightblue{ background-color: lightblue } |
|||
.bgcolor-cce1e6{ background-color: #cce1e6 } |
|||
.bgcolor-787fff{ background-color: #787fff } |
|||
.bgcolor-eef0ff{ background-color: #eef0ff } |
|||
.bgcolor-ff4769{ background-color: #ff4769 } |
|||
.bgcolor-f1f1f1{ background-color: #f1f1f1 } |
|||
|
|||
.border-gray{ border: 3rpx solid gray } |
|||
.border-lightblue{ border: 3rpx solid lightblue } |
|||
.border-pink{ border: 3rpx solid pink } |
|||
.border-blue{ border: 3rpx solid blue } |
|||
.border-red{ border: 3rpx solid red } |
|||
.border-white{ border: 3rpx solid white } |
|||
.border-f1f1f1{ border: 3rpx solid #f1f1f1 } |
|||
.border-cce1e6{ border: 3rpx solid #cce1e6 } |
|||
.border-787fff{ border: 3rpx solid #787fff } |
|||
.border-eef0ff{ border: 3rpx solid #eef0ff } |
|||
.border-ff4769{ border: 3rpx solid #ff4769 } |
|||
.border-f1f1f1{ border: 3rpx solid #f1f1f1 } |
|||
|
|||
.border-radius10{ border-radius: 10rpx } |
|||
|
|||
.position-fixed{ position: fixed } |
|||
.position-absolute{ position: absolute } |
|||
.position-relative{ position: relative } |
|||
|
|||
.top0{ top: 0rpx } |
|||
.top10{ top: 10rpx } |
|||
.top20{ top: 20rpx } |
|||
.top30{ top: 30rpx } |
|||
.top40{ top: 40rpx } |
|||
.top50{ top: 50rpx } |
|||
.top60{ top: 60rpx } |
|||
.top70{ top: 70rpx } |
|||
.top80{ top: 80rpx } |
|||
.top90{ top: 90rpx } |
|||
.top100{ top: 100rpx } |
|||
.top110{ top: 110rpx } |
|||
.top120{ top: 120rpx } |
|||
.top130{ top: 130rpx } |
|||
.top140{ top: 140rpx } |
|||
.top150{ top: 150rpx } |
|||
.top200{ top: 200rpx } |
|||
.left0{ left: 0rpx } |
|||
.left10{ left: 10rpx } |
|||
.left20{ left: 20rpx } |
|||
.left30{ left: 30rpx } |
|||
.left40{ left: 40rpx } |
|||
.left50{ left: 50rpx } |
|||
.left60{ left: 60rpx } |
|||
.right0{ right: 0rpx } |
|||
.right10{ right: 10rpx } |
|||
.right20{ right: 20rpx } |
|||
.right30{ right: 30rpx } |
|||
.right40{ right: 40rpx } |
|||
.right50{ right: 50rpx } |
|||
.right60{ right: 60rpx } |
|||
.bottom0{ bottom: 0rpx } |
|||
.bottom10{ bottom: 10rpx } |
|||
.bottom20{ bottom: 20rpx } |
|||
.bottom30{ bottom: 30rpx } |
|||
.bottom40{ bottom: 40rpx } |
|||
.bottom50{ bottom: 50rpx } |
|||
.bottom60{ bottom: 60rpx } |
|||
.bottom70{ bottom: 70rpx } |
|||
.bottom80{ bottom: 80rpx } |
|||
.bottom90{ bottom: 90rpx } |
|||
.bottom100{ bottom: 100rpx } |
|||
.bottom110{ bottom: 110rpx } |
|||
.bottom120{ bottom: 120rpx } |
|||
.bottom130{ bottom: 130rpx } |
|||
.bottom140{ bottom: 140rpx } |
|||
.bottom150{ bottom: 150rpx } |
|||
.bottom200{ bottom: 200rpx } |
|||
|
|||
.lh20{ line-height: 20rpx } |
|||
.lh25{ line-height: 25rpx } |
|||
.lh30{ line-height: 30rpx } |
|||
.lh35{ line-height: 35rpx } |
|||
.lh40{ line-height: 40rpx } |
|||
.lh50{ line-height: 50rpx } |
|||
|
|||
.pa0{ padding: 0rpx } |
|||
.pa5{ padding: 5rpx } |
|||
.pa10{ padding: 10rpx } |
|||
.pa15{ padding: 15rpx } |
|||
.pa20{ padding: 20rpx } |
|||
.pa25{ padding: 25rpx } |
|||
.pa30{ padding: 30rpx } |
|||
.pa40{ padding: 40rpx } |
|||
.pa45{ padding: 45rpx } |
|||
.pa50{ padding: 50rpx } |
|||
.pa60{ padding: 60rpx } |
|||
.pa70{ padding: 70rpx } |
|||
.pa80{ padding: 80rpx } |
|||
.pa90{ padding: 90rpx } |
|||
.pa100{ padding: 100rpx } |
|||
.pa120{ padding: 120rpx } |
|||
.pa140{ padding: 140rpx } |
|||
.pa160{ padding: 160rpx } |
|||
.pa180{ padding: 180rpx } |
|||
.pa200{ padding: 200rpx } |
|||
.pa250{ padding: 250rpx } |
|||
.pa300{ padding: 300rpx } |
|||
|
|||
.ptb0{ padding-top: 0rpx; padding-bottom: 0rpx } |
|||
.ptb5{ padding-top: 5rpx; padding-bottom: 5rpx } |
|||
.ptb10{ padding-top: 10rpx; padding-bottom: 10rpx } |
|||
.ptb15{ padding-top: 15rpx; padding-bottom: 15rpx } |
|||
.ptb20{ padding-top: 20rpx; padding-bottom: 20rpx } |
|||
.ptb25{ padding-top: 25rpx; padding-bottom: 25rpx } |
|||
.ptb30{ padding-top: 30rpx; padding-bottom: 30rpx } |
|||
.ptb35{ padding-top: 35rpx; padding-bottom: 35rpx } |
|||
.ptb40{ padding-top: 40rpx; padding-bottom: 40rpx } |
|||
.ptb45{ padding-top: 45rpx; padding-bottom: 45rpx } |
|||
.ptb50{ padding-top: 50rpx; padding-bottom: 50rpx } |
|||
.ptb60{ padding-top: 60rpx; padding-bottom: 60rpx } |
|||
.ptb70{ padding-top: 70rpx; padding-bottom: 70rpx } |
|||
.ptb80{ padding-top: 80rpx; padding-bottom: 80rpx } |
|||
.ptb90{ padding-top: 90rpx; padding-bottom: 90rpx } |
|||
.ptb100{ padding-top: 100rpx; padding-bottom: 100rpx } |
|||
.ptb120{ padding-top: 120rpx; padding-bottom: 120rpx } |
|||
.ptb140{ padding-top: 140rpx; padding-bottom: 140rpx } |
|||
.ptb160{ padding-top: 160rpx; padding-bottom: 160rpx } |
|||
.ptb180{ padding-top: 180rpx; padding-bottom: 180rpx } |
|||
.ptb200{ padding-top: 200rpx; padding-bottom: 200rpx } |
|||
.ptb250{ padding-top: 250rpx; padding-bottom: 250rpx } |
|||
.ptb300{ padding-top: 300rpx; padding-bottom: 300rpx } |
|||
|
|||
.plr0{ padding-left: 0rpx; padding-right: 0rpx } |
|||
.plr5{ padding-left: 5rpx; padding-right: 5rpx } |
|||
.plr10{ padding-left: 10rpx; padding-right: 10rpx } |
|||
.plr15{ padding-left: 15rpx; padding-right: 15rpx } |
|||
.plr20{ padding-left: 20rpx; padding-right: 20rpx } |
|||
.plr25{ padding-left: 25rpx; padding-right: 25rpx } |
|||
.plr30{ padding-left: 30rpx; padding-right: 30rpx } |
|||
.plr35{ padding-left: 35rpx; padding-right: 35rpx } |
|||
.plr40{ padding-left: 40rpx; padding-right: 40rpx } |
|||
.plr45{ padding-left: 45rpx; padding-right: 45rpx } |
|||
.plr50{ padding-left: 50rpx; padding-right: 50rpx } |
|||
.plr60{ padding-left: 60rpx; padding-right: 60rpx } |
|||
.plr70{ padding-left: 70rpx; padding-right: 70rpx } |
|||
.plr80{ padding-left: 80rpx; padding-right: 80rpx } |
|||
.plr90{ padding-left: 90rpx; padding-right: 90rpx } |
|||
.plr100{ padding-left: 100rpx; padding-right: 100rpx } |
|||
.plr120{ padding-left: 120rpx; padding-right: 120rpx } |
|||
.plr140{ padding-left: 140rpx; padding-right: 140rpx } |
|||
.plr160{ padding-left: 160rpx; padding-right: 160rpx } |
|||
.plr180{ padding-left: 180rpx; padding-right: 180rpx } |
|||
.plr200{ padding-left: 200rpx; padding-right: 200rpx } |
|||
.plr250{ padding-left: 250rpx; padding-right: 250rpx } |
|||
.plr300{ padding-left: 300rpx; padding-right: 300rpx } |
|||
|
|||
.pt0{ padding-top: 0rpx } |
|||
.pt5{ padding-top: 5rpx } |
|||
.pt10{ padding-top: 10rpx } |
|||
.pt15{ padding-top: 15rpx } |
|||
.pt20{ padding-top: 20rpx } |
|||
.pt25{ padding-top: 25rpx } |
|||
.pt30{ padding-top: 30rpx } |
|||
.pt35{ padding-top: 35rpx } |
|||
.pt40{ padding-top: 40rpx } |
|||
.pt45{ padding-top: 45rpx } |
|||
.pt50{ padding-top: 50rpx } |
|||
.pt60{ padding-top: 60rpx } |
|||
.pt70{ padding-top: 70rpx } |
|||
.pt80{ padding-top: 80rpx } |
|||
.pt90{ padding-top: 90rpx } |
|||
.pt100{ padding-top: 100rpx } |
|||
.pt120{ padding-top: 120rpx } |
|||
.pt140{ padding-top: 140rpx } |
|||
.pt160{ padding-top: 160rpx } |
|||
.pt180{ padding-top: 180rpx } |
|||
.pt200{ padding-top: 200rpx } |
|||
.pt250{ padding-top: 250rpx } |
|||
.pt300{ padding-top: 300rpx } |
|||
|
|||
.pb0{ padding-bottom: 0rpx } |
|||
.pb5{ padding-bottom: 5rpx } |
|||
.pb10{ padding-bottom: 10rpx } |
|||
.pb15{ padding-bottom: 15rpx } |
|||
.pb20{ padding-bottom: 20rpx } |
|||
.pb25{ padding-bottom: 25rpx } |
|||
.pb30{ padding-bottom: 30rpx } |
|||
.pb35{ padding-bottom: 35rpx } |
|||
.pb40{ padding-bottom: 40rpx } |
|||
.pb45{ padding-bottom: 45rpx } |
|||
.pb50{ padding-bottom: 50rpx } |
|||
.pb60{ padding-bottom: 60rpx } |
|||
.pb70{ padding-bottom: 70rpx } |
|||
.pb80{ padding-bottom: 80rpx } |
|||
.pb90{ padding-bottom: 90rpx } |
|||
.pb100{ padding-bottom: 100rpx } |
|||
.pb120{ padding-bottom: 120rpx } |
|||
.pb140{ padding-bottom: 140rpx } |
|||
.pb160{ padding-bottom: 160rpx } |
|||
.pb180{ padding-bottom: 180rpx } |
|||
.pb200{ padding-bottom: 200rpx } |
|||
.pb250{ padding-bottom: 250rpx } |
|||
.pb300{ padding-bottom: 300rpx } |
|||
|
|||
.pl0{ padding-left: 0rpx } |
|||
.pl5{ padding-left: 5rpx } |
|||
.pl10{ padding-left: 10rpx } |
|||
.pl15{ padding-left: 15rpx } |
|||
.pl20{ padding-left: 20rpx } |
|||
.pl25{ padding-left: 25rpx } |
|||
.pl30{ padding-left: 30rpx } |
|||
.pl35{ padding-left: 35rpx } |
|||
.pl40{ padding-left: 40rpx } |
|||
.pl45{ padding-left: 45rpx } |
|||
.pl50{ padding-left: 50rpx } |
|||
.pl60{ padding-left: 60rpx } |
|||
.pl70{ padding-left: 70rpx } |
|||
.pl80{ padding-left: 80rpx } |
|||
.pl90{ padding-left: 90rpx } |
|||
.pl100{ padding-left: 100rpx } |
|||
.pl120{ padding-left: 120rpx } |
|||
.pl140{ padding-left: 140rpx } |
|||
.pl160{ padding-left: 160rpx } |
|||
.pl180{ padding-left: 180rpx } |
|||
.pl200{ padding-left: 200rpx } |
|||
.pl250{ padding-left: 250rpx } |
|||
.pl300{ padding-left: 300rpx } |
|||
|
|||
.pr0{ padding-right: 0rpx } |
|||
.pr5{ padding-right: 5rpx } |
|||
.pr10{ padding-right: 10rpx } |
|||
.pr15{ padding-right: 15rpx } |
|||
.pr20{ padding-right: 20rpx } |
|||
.pr25{ padding-right: 25rpx } |
|||
.pr30{ padding-right: 30rpx } |
|||
.pr35{ padding-right: 35rpx } |
|||
.pr40{ padding-right: 40rpx } |
|||
.pr45{ padding-right: 45rpx } |
|||
.pr50{ padding-right: 50rpx } |
|||
.pr60{ padding-right: 60rpx } |
|||
.pr70{ padding-right: 70rpx } |
|||
.pr80{ padding-right: 80rpx } |
|||
.pr90{ padding-right: 90rpx } |
|||
.pr100{ padding-right: 100rpx } |
|||
.pr120{ padding-right: 120rpx } |
|||
.pr140{ padding-right: 140rpx } |
|||
.pr160{ padding-right: 160rpx } |
|||
.pr180{ padding-right: 180rpx } |
|||
.pr200{ padding-right: 200rpx } |
|||
.pr250{ padding-right: 250rpx } |
|||
.pr300{ padding-right: 300rpx } |
|||
|
|||
.ma0{ margin: 0rpx } |
|||
.ma5{ margin: 5rpx } |
|||
.ma10{ margin: 10rpx } |
|||
.ma15{ margin: 15rpx } |
|||
.ma20{ margin: 20rpx } |
|||
.ma25{ margin: 25rpx } |
|||
.ma30{ margin: 30rpx } |
|||
.ma35{ margin: 35rpx } |
|||
.ma40{ margin: 40rpx } |
|||
.ma45{ margin: 45rpx } |
|||
.ma50{ margin: 50rpx } |
|||
.ma60{ margin: 60rpx } |
|||
.ma70{ margin: 70rpx } |
|||
.ma80{ margin: 80rpx } |
|||
.ma90{ margin: 90rpx } |
|||
.ma100{ margin: 100rpx } |
|||
.ma120{ margin: 120rpx } |
|||
.ma140{ margin: 140rpx } |
|||
.ma160{ margin: 160rpx } |
|||
.ma180{ margin: 180rpx } |
|||
.ma200{ margin: 200rpx } |
|||
.ma250{ margin: 250rpx } |
|||
.ma300{ margin: 300rpx } |
|||
|
|||
.mlr0{ margin-left: 0rpx; margin-right: 0rpx } |
|||
.mlr5{ margin-left: 5rpx; margin-right: 5rpx } |
|||
.mlr10{ margin-left: 10rpx; margin-right: 10rpx } |
|||
.mlr15{ margin-left: 15rpx; margin-right: 15rpx } |
|||
.mlr20{ margin-left: 20rpx; margin-right: 20rpx } |
|||
.mlr25{ margin-left: 25rpx; margin-right: 25rpx } |
|||
.mlr30{ margin-left: 30rpx; margin-right: 30rpx } |
|||
.mlr35{ margin-left: 35rpx; margin-right: 35rpx } |
|||
.mlr40{ margin-left: 40rpx; margin-right: 40rpx } |
|||
.mlr45{ margin-left: 45rpx; margin-right: 45rpx } |
|||
.mlr50{ margin-left: 50rpx; margin-right: 50rpx } |
|||
.mlr50{ margin-left: 50rpx; margin-right: 50rpx } |
|||
.mlr60{ margin-left: 60rpx; margin-right: 60rpx } |
|||
.mlr70{ margin-left: 70rpx; margin-right: 70rpx } |
|||
.mlr80{ margin-left: 80rpx; margin-right: 80rpx } |
|||
.mlr90{ margin-left: 90rpx; margin-right: 90rpx } |
|||
.mlr100{ margin-left: 100rpx; margin-right: 100rpx } |
|||
.mlr120{ margin-left: 120rpx; margin-right: 120rpx } |
|||
.mlr140{ margin-left: 140rpx; margin-right: 140rpx } |
|||
.mlr160{ margin-left: 160rpx; margin-right: 160rpx } |
|||
.mlr180{ margin-left: 180rpx; margin-right: 180rpx } |
|||
.mlr200{ margin-left: 200rpx; margin-right: 200rpx } |
|||
.mlr250{ margin-left: 250rpx; margin-right: 250rpx } |
|||
.mlr300{ margin-left: 300rpx; margin-right: 300rpx } |
|||
|
|||
.mtb0{ margin-top: 0rpx; margin-bottom: 0rpx } |
|||
.mtb5{ margin-top: 5rpx; margin-bottom: 5rpx } |
|||
.mtb10{ margin-top: 10rpx; margin-bottom: 10rpx } |
|||
.mtb15{ margin-top: 15rpx; margin-bottom: 15rpx } |
|||
.mtb20{ margin-top: 20rpx; margin-bottom: 20rpx } |
|||
.mtb25{ margin-top: 25rpx; margin-bottom: 25rpx } |
|||
.mtb30{ margin-top: 30rpx; margin-bottom: 30rpx } |
|||
.mtb35{ margin-top: 35rpx; margin-bottom: 35rpx } |
|||
.mtb40{ margin-top: 40rpx; margin-bottom: 40rpx } |
|||
.mtb45{ margin-top: 45rpx; margin-bottom: 45rpx } |
|||
.mtb50{ margin-top: 50rpx; margin-bottom: 50rpx } |
|||
.mtb60{ margin-top: 60rpx; margin-bottom: 60rpx } |
|||
.mtb70{ margin-top: 70rpx; margin-bottom: 70rpx } |
|||
.mtb80{ margin-top: 80rpx; margin-bottom: 80rpx } |
|||
.mtb90{ margin-top: 90rpx; margin-bottom: 90rpx } |
|||
.mtb100{ margin-top: 100rpx; margin-bottom: 100rpx } |
|||
.mtb120{ margin-top: 120rpx; margin-bottom: 120rpx } |
|||
.mtb140{ margin-top: 140rpx; margin-bottom: 140rpx } |
|||
.mtb160{ margin-top: 160rpx; margin-bottom: 160rpx } |
|||
.mtb180{ margin-top: 180rpx; margin-bottom: 180rpx } |
|||
.mtb200{ margin-top: 200rpx; margin-bottom: 200rpx } |
|||
.mtb250{ margin-top: 250rpx; margin-bottom: 250rpx } |
|||
.mtb300{ margin-top: 300rpx; margin-bottom: 300rpx } |
|||
|
|||
.mt0{ margin-top: 0rpx } |
|||
.mt5{ margin-top: 5rpx } |
|||
.mt10{ margin-top: 10rpx } |
|||
.mt12{ margin-top: 10rpx } |
|||
.mt15{ margin-top: 15rpx } |
|||
.mt20{ margin-top: 20rpx } |
|||
.mt25{ margin-top: 25rpx } |
|||
.mt30{ margin-top: 30rpx } |
|||
.mt35{ margin-top: 35rpx } |
|||
.mt40{ margin-top: 40rpx } |
|||
.mt45{ margin-top: 45rpx } |
|||
.mt50{ margin-top: 50rpx } |
|||
.mt60{ margin-top: 60rpx } |
|||
.mt65{ margin-top: 65rpx } |
|||
.mt70{ margin-top: 70rpx } |
|||
.mt80{ margin-top: 80rpx } |
|||
.mt90{ margin-top: 90rpx } |
|||
.mt100{ margin-top: 100rpx } |
|||
.mt120{ margin-top: 120rpx } |
|||
.mt140{ margin-top: 140rpx } |
|||
.mt160{ margin-top: 160rpx } |
|||
.mt180{ margin-top: 180rpx } |
|||
.mt200{ margin-top: 200rpx } |
|||
.mt250{ margin-top: 250rpx } |
|||
.mt300{ margin-top: 300rpx } |
|||
|
|||
.mt-1{ margin-top: -1rpx } |
|||
.mt-5{ margin-top: -5rpx } |
|||
.mt-10{ margin-top: -10rpx } |
|||
.mt-15{ margin-top: -15rpx } |
|||
.mt-20{ margin-top: -20rpx } |
|||
.mt-25{ margin-top: -25rpx } |
|||
.mt-30{ margin-top: -30rpx } |
|||
.mt-35{ margin-top: -35rpx } |
|||
.mt-40{ margin-top: -40rpx } |
|||
.mt-45{ margin-top: -45rpx } |
|||
.mt-50{ margin-top: -50rpx } |
|||
.mt-60{ margin-top: -60rpx } |
|||
.mt-70{ margin-top: -70rpx } |
|||
.mt-80{ margin-top: -80rpx } |
|||
.mt-90{ margin-top: -90rpx } |
|||
.mt-100{ margin-top: -100rpx } |
|||
.mt-120{ margin-top: -120rpx } |
|||
.mt-140{ margin-top: -140rpx } |
|||
.mt-160{ margin-top: -160rpx } |
|||
.mt-180{ margin-top: -180rpx } |
|||
.mt-200{ margin-top: -200rpx } |
|||
.mt-250{ margin-top: -250rpx } |
|||
.mt-300{ margin-top: -300rpx } |
|||
|
|||
.mb0{ margin-bottom: 0rpx } |
|||
.mb5{ margin-bottom: 5rpx } |
|||
.mb10{ margin-bottom: 10rpx } |
|||
.mb15{ margin-bottom: 15rpx } |
|||
.mb20{ margin-bottom: 20rpx } |
|||
.mb25{ margin-bottom: 25rpx } |
|||
.mb30{ margin-bottom: 30rpx } |
|||
.mb35{ margin-bottom: 35rpx } |
|||
.mb40{ margin-bottom: 40rpx } |
|||
.mb45{ margin-bottom: 45rpx } |
|||
.mb50{ margin-bottom: 50rpx } |
|||
.mb60{ margin-bottom: 60rpx } |
|||
.mb70{ margin-bottom: 70rpx } |
|||
.mb80{ margin-bottom: 80rpx } |
|||
.mb90{ margin-bottom: 90rpx } |
|||
.mb100{ margin-bottom: 100rpx } |
|||
.mb120{ margin-bottom: 120rpx } |
|||
.mb140{ margin-bottom: 140rpx } |
|||
.mb160{ margin-bottom: 160rpx } |
|||
.mb180{ margin-bottom: 180rpx } |
|||
.mb200{ margin-bottom: 200rpx } |
|||
.mb250{ margin-bottom: 250rpx } |
|||
.mb300{ margin-bottom: 300rpx } |
|||
|
|||
.mb-1{ margin-bottom: -1rpx } |
|||
.mb-5{ margin-bottom: -5rpx } |
|||
.mb-10{ margin-bottom: -10rpx } |
|||
.mb-15{ margin-bottom: -15rpx } |
|||
.mb-20{ margin-bottom: -20rpx } |
|||
.mb-25{ margin-bottom: -25rpx } |
|||
.mb-30{ margin-bottom: -30rpx } |
|||
.mb-35{ margin-bottom: -35rpx } |
|||
.mb-40{ margin-bottom: -40rpx } |
|||
.mb-45{ margin-bottom: -45rpx } |
|||
.mb-50{ margin-bottom: -50rpx } |
|||
.mb-60{ margin-bottom: -60rpx } |
|||
.mb-70{ margin-bottom: -70rpx } |
|||
.mb-80{ margin-bottom: -80rpx } |
|||
.mb-90{ margin-bottom: -90rpx } |
|||
.mb-100{ margin-bottom: -100rpx } |
|||
.mb-120{ margin-bottom: -120rpx } |
|||
.mb-140{ margin-bottom: -140rpx } |
|||
.mb-160{ margin-bottom: -160rpx } |
|||
.mb-180{ margin-bottom: -180rpx } |
|||
.mb-200{ margin-bottom: -200rpx } |
|||
.mb-250{ margin-bottom: -250rpx } |
|||
.mb-300{ margin-bottom: -300rpx } |
|||
|
|||
.ml0{ margin-left: 0rpx } |
|||
.ml5{ margin-left: 5rpx } |
|||
.ml10{ margin-left: 10rpx } |
|||
.ml15{ margin-left: 15rpx } |
|||
.ml20{ margin-left: 20rpx } |
|||
.ml25{ margin-left: 25rpx } |
|||
.ml30{ margin-left: 30rpx } |
|||
.ml35{ margin-left: 35rpx } |
|||
.ml40{ margin-left: 40rpx } |
|||
.ml45{ margin-left: 45rpx } |
|||
.ml50{ margin-left: 50rpx } |
|||
.ml60{ margin-left: 60rpx } |
|||
.ml70{ margin-left: 70rpx } |
|||
.ml80{ margin-left: 80rpx } |
|||
.ml90{ margin-left: 90rpx } |
|||
.ml100{ margin-left: 100rpx } |
|||
.ml120{ margin-left: 120rpx } |
|||
.ml140{ margin-left: 140rpx } |
|||
.ml160{ margin-left: 160rpx } |
|||
.ml180{ margin-left: 180rpx } |
|||
.ml200{ margin-left: 200rpx } |
|||
.ml250{ margin-left: 250rpx } |
|||
.ml300{ margin-left: 300rpx } |
|||
|
|||
.ml-1{ margin-left: -1rpx } |
|||
.ml-5{ margin-left: -5rpx } |
|||
.ml-10{ margin-left: -10rpx } |
|||
.ml-15{ margin-left: -15rpx } |
|||
.ml-20{ margin-left: -20rpx } |
|||
.ml-25{ margin-left: -25rpx } |
|||
.ml-30{ margin-left: -30rpx } |
|||
.ml-35{ margin-left: -35rpx } |
|||
.ml-40{ margin-left: -40rpx } |
|||
.ml-45{ margin-left: -45rpx } |
|||
.ml-50{ margin-left: -50rpx } |
|||
.ml-60{ margin-left: -60rpx } |
|||
.ml-70{ margin-left: -70rpx } |
|||
.ml-80{ margin-left: -80rpx } |
|||
.ml-90{ margin-left: -90rpx } |
|||
.ml-100{ margin-left: -100rpx } |
|||
.ml-120{ margin-left: -120rpx } |
|||
.ml-140{ margin-left: -140rpx } |
|||
.ml-160{ margin-left: -160rpx } |
|||
.ml-180{ margin-left: -180rpx } |
|||
.ml-200{ margin-left: -200rpx } |
|||
.ml-250{ margin-left: -250rpx } |
|||
.ml-300{ margin-left: -300rpx } |
|||
|
|||
.mr0{ margin-right: 0rpx } |
|||
.mr5{ margin-right: 5rpx } |
|||
.mr10{ margin-right: 10rpx } |
|||
.mr15{ margin-right: 15rpx } |
|||
.mr20{ margin-right: 20rpx } |
|||
.mr25{ margin-right: 25rpx } |
|||
.mr30{ margin-right: 30rpx } |
|||
.mr35{ margin-right: 35rpx } |
|||
.mr40{ margin-right: 40rpx } |
|||
.mr45{ margin-right: 45rpx } |
|||
.mr50{ margin-right: 50rpx } |
|||
.mr60{ margin-right: 60rpx } |
|||
.mr70{ margin-right: 70rpx } |
|||
.mr80{ margin-right: 80rpx } |
|||
.mr90{ margin-right: 90rpx } |
|||
.mr100{ margin-right: 100rpx } |
|||
.mr120{ margin-right: 120rpx } |
|||
.mr140{ margin-right: 140rpx } |
|||
.mr160{ margin-right: 160rpx } |
|||
.mr180{ margin-right: 180rpx } |
|||
.mr200{ margin-right: 200rpx } |
|||
.mr250{ margin-right: 250rpx } |
|||
.mr300{ margin-right: 300rpx } |
|||
|
|||
.mr-1{ margin-right: -1rpx } |
|||
.mr-5{ margin-right: -5rpx } |
|||
.mr-10{ margin-right: -10rpx } |
|||
.mr-15{ margin-right: -15rpx } |
|||
.mr-20{ margin-right: -20rpx } |
|||
.mr-25{ margin-right: -25rpx } |
|||
.mr-30{ margin-right: -30rpx } |
|||
.mr-35{ margin-right: -35rpx } |
|||
.mr-40{ margin-right: -40rpx } |
|||
.mr-45{ margin-right: -45rpx } |
|||
.mr-50{ margin-right: -50rpx } |
|||
.mr-60{ margin-right: -60rpx } |
|||
.mr-70{ margin-right: -70rpx } |
|||
.mr-80{ margin-right: -80rpx } |
|||
.mr-90{ margin-right: -90rpx } |
|||
.mr-100{ margin-right: -100rpx } |
|||
.mr-120{ margin-right: -120rpx } |
|||
.mr-140{ margin-right: -140rpx } |
|||
.mr-160{ margin-right: -160rpx } |
|||
.mr-180{ margin-right: -180rpx } |
|||
.mr-200{ margin-right: -200rpx } |
|||
.mr-250{ margin-right: -250rpx } |
|||
.mr-300{ margin-right: -300rpx } |
@ -0,0 +1,136 @@ |
|||
.height100{ |
|||
height: 100%; |
|||
} |
|||
.width25{ |
|||
width: 25%; |
|||
} |
|||
.width30{ |
|||
width: 30%; |
|||
} |
|||
.width45{ |
|||
width: 45%; |
|||
} |
|||
.width46{ |
|||
width: 46%; |
|||
} |
|||
.width47{ |
|||
width: 47%; |
|||
} |
|||
.width48{ |
|||
width: 48%; |
|||
} |
|||
.width49{ |
|||
width: 49%; |
|||
} |
|||
.width50{ |
|||
width: 50%; |
|||
} |
|||
.width80{ |
|||
width: 80%; |
|||
} |
|||
.width90{ |
|||
width: 90%; |
|||
} |
|||
.width100{ |
|||
width: 100%; |
|||
} |
|||
|
|||
.test{ border: 3rpx solid red} |
|||
.test-red{ border: 3rpx solid red} |
|||
.test-blue{ border: 3rpx solid blue} |
|||
.test-green{ border: 3rpx solid green} |
|||
.test-white{ border: 3rpx solid white} |
|||
.test-box{ box-sizing: border-box; border: 3rpx solid red} |
|||
.test-box-red{ box-sizing: border-box; border: 3rpx solid red} |
|||
.test-box-blue{ box-sizing: border-box; border: 3rpx solid blue} |
|||
.test-box-green{ box-sizing: border-box; border: 3rpx solid green} |
|||
.test-box-white{ box-sizing: border-box; border: 3rpx solid white} |
|||
|
|||
.float{ float: left; } |
|||
.float-left{ float: left; } |
|||
.float-right{ float: right; } |
|||
|
|||
// 允许文本复制 |
|||
.nine-user-select { |
|||
cursor: auto; |
|||
-webkit-user-select: text; |
|||
user-select: text; |
|||
} |
|||
|
|||
.display-flex-row{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
} |
|||
.display-flex-column{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
.display-flex-column-center{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
} |
|||
.display-flex-row-between{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
.display-flex-row-center{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
.display-flex-row-around{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-around; |
|||
align-items: center; |
|||
} |
|||
.display-flex-column-between{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
.display-flex-column-around{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
align-items: center; |
|||
} |
|||
.justify-content-center{ |
|||
justify-content: center |
|||
} |
|||
.flex1{ |
|||
flex: 1 |
|||
} |
|||
|
|||
|
|||
.text-nowrap{ |
|||
white-space:nowrap; |
|||
} |
|||
.text-ellipsis{ |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
// 放大缩小比例 |
|||
.transform-scale05{ |
|||
transform: scale(0.5); |
|||
} |
|||
.transform-scale06{ |
|||
transform: scale(0.6); |
|||
} |
|||
.transform-scale07{ |
|||
transform: scale(0.7); |
|||
} |
|||
.transform-scale08{ |
|||
transform: scale(0.8); |
|||
} |
|||
.transform-scale09{ |
|||
transform: scale(0.9); |
|||
} |
@ -0,0 +1,27 @@ |
|||
// 边框蓝,字体蓝,用于获取短信验证码按钮 |
|||
.nine-btn-verify-001{ |
|||
border-radius: 10rpx; |
|||
color: #1e1eff; |
|||
border: 3rpx solid #1e1eff; |
|||
} |
|||
// 保存按钮 |
|||
.nine-btn-save-001{ |
|||
padding: 20rpx; |
|||
border-radius: 10rpx; |
|||
color: #fff; |
|||
background-color: #0000ff; |
|||
text-align: center; |
|||
} |
|||
// 退出登录 |
|||
.nine-btn-login-out-001{ |
|||
padding: 20rpx; |
|||
border-radius: 10rpx; |
|||
color: red; |
|||
background: #fff; |
|||
text-align: center; |
|||
} |
|||
// 灰色横线 |
|||
.nine-line-001{ |
|||
height: 1rpx; |
|||
border-top: 1rpx solid #d9d9d9; |
|||
} |
@ -0,0 +1 @@ |
|||
/* 可重写内部/uni_modules/vrapile-im/static/style/nine-chat-friend-001.scss样式 */ |
@ -0,0 +1 @@ |
|||
/* 可重写内部/uni_modules/vrapile-im/static/style/nine-chat-home-001.scss样式 */ |
@ -0,0 +1,36 @@ |
|||
.image35{ |
|||
width: 35rpx; |
|||
height: 35rpx; |
|||
} |
|||
.image40{ |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
} |
|||
.image50{ |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
} |
|||
.image70{ |
|||
width: 70rpx; |
|||
height: 70rpx; |
|||
} |
|||
.image80{ |
|||
width: 70rpx; |
|||
height: 70rpx; |
|||
} |
|||
.image90{ |
|||
width: 90rpx; |
|||
height: 90rpx; |
|||
} |
|||
.image150{ |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
} |
|||
.image200{ |
|||
width: 200rpx; |
|||
height: 200rpx; |
|||
} |
|||
.image400{ |
|||
width: 400rpx; |
|||
height: 400rpx; |
|||
} |
@ -0,0 +1,9 @@ |
|||
.nine-list-001{ |
|||
padding: 10rpx; |
|||
} |
|||
.nine-list-001-item{ |
|||
background-color: #fff; |
|||
margin: 10rpx 0; |
|||
padding: 10rpx 30rpx; |
|||
border-radius: 10rpx; |
|||
} |
@ -0,0 +1,39 @@ |
|||
.nine-nav-001{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
padding: 10rpx; |
|||
flex: 1; |
|||
height: 100%; |
|||
overflow-y: auto; |
|||
} |
|||
.nine-nav-001-item{ |
|||
background: #fff; |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
margin-top: 5rpx; |
|||
padding: 20rpx 15rpx; |
|||
border-radius: 1rpx; |
|||
border-style: solid; |
|||
border-width: 0px; |
|||
} |
|||
.nine-nav-001-item-left{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
padding: 2rpx 10rpx; |
|||
} |
|||
.nine-nav-001-item-left-text{ |
|||
font-size: 16px; |
|||
padding-left: 20rpx; |
|||
} |
|||
.nine-nav-001-item-right{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
} |
|||
.nine-nav-001-item-right-image{ |
|||
width: 16rpx; |
|||
height: 35rpx; |
|||
} |
@ -0,0 +1,8 @@ |
|||
const getters = { |
|||
token: state => state.user.token, |
|||
userInfo: state => state.user.userInfo, |
|||
loginInfo: state => state.user.loginInfo, |
|||
avatar: state => state.user.avatar, |
|||
name: state => state.user.name |
|||
} |
|||
export default getters |
@ -0,0 +1,15 @@ |
|||
// import Vue from 'vue'
|
|||
import Vuex from 'vuex' |
|||
import user from '@/store/modules/user' |
|||
import getters from './getters' |
|||
|
|||
// Vue.use(Vuex)
|
|||
|
|||
const store = new Vuex.Store({ |
|||
modules: { |
|||
user |
|||
}, |
|||
getters |
|||
}) |
|||
|
|||
export default store |
@ -0,0 +1,94 @@ |
|||
import store from '@/store' |
|||
import storage from '@/utils/storage' |
|||
import constant from '@/utils/constant' |
|||
import { login, logout, getInfo } from '@/api/login' |
|||
import { getToken, setToken, removeToken } from '@/utils/token' |
|||
|
|||
const user = { |
|||
state: { |
|||
token: getToken(), |
|||
userInfo: storage.get(constant.userInfo), |
|||
loginInfo: storage.get(constant.loginInfo), |
|||
name: storage.get(constant.name), |
|||
avatar: storage.get(constant.avatar) |
|||
}, |
|||
|
|||
mutations: { |
|||
SET_TOKEN: (state, token) => { |
|||
state.token = token |
|||
}, |
|||
SET_USER_INFO: (state, userInfo) => { |
|||
state.userInfo = userInfo |
|||
storage.set(constant.userInfo, userInfo) |
|||
}, |
|||
SET_LOGIN_INFO: (state, loginInfo) => { |
|||
state.loginInfo = loginInfo |
|||
storage.set(constant.loginInfo, loginInfo) |
|||
}, |
|||
SET_NAME: (state, name) => { |
|||
state.name = name |
|||
storage.set(constant.name, name) |
|||
}, |
|||
SET_AVATAR: (state, avatar) => { |
|||
state.avatar = avatar |
|||
storage.set(constant.avatar, avatar) |
|||
} |
|||
}, |
|||
|
|||
actions: { |
|||
// 登录
|
|||
Login({ commit }, userInfo) { |
|||
const loginType = userInfo.loginType |
|||
const userName = userInfo.userName |
|||
const password = userInfo.password |
|||
const smsCode = userInfo.smsCode |
|||
const registerFlag = userInfo.registerFlag |
|||
const code = userInfo.code |
|||
const uuid = userInfo.uuid |
|||
return new Promise((resolve, reject) => { |
|||
login(loginType, userName, password, smsCode, registerFlag, code, uuid).then(res => { |
|||
setToken(res.data.token) |
|||
commit('SET_TOKEN', res.data.token) |
|||
commit('SET_LOGIN_INFO', userInfo) // 保存登录信息,后续可以自动登录
|
|||
resolve() |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
}, |
|||
|
|||
// 获取用户信息
|
|||
GetInfo({ commit, state }) { |
|||
return new Promise((resolve, reject) => { |
|||
getInfo().then(res => { |
|||
const user = res.data.user |
|||
const avatar = (user == null || user.avatar == "" || user.avatar == null) ? "/static/image/user/yy.png" : user.avatar |
|||
const userName = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName |
|||
commit('SET_USER_INFO', user) |
|||
commit('SET_NAME', userName) |
|||
commit('SET_AVATAR', avatar) |
|||
resolve(res) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
}, |
|||
|
|||
// 退出系统
|
|||
LogOut({ commit, state }) { |
|||
return new Promise((resolve, reject) => { |
|||
logout(state.token).then(() => { |
|||
commit('SET_TOKEN', '') |
|||
commit('SET_USER_INFO', {}) |
|||
removeToken() |
|||
storage.clean() |
|||
resolve() |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
|
|||
export default user |
@ -0,0 +1,76 @@ |
|||
/** |
|||
* 这里是uni-app内置的常用样式变量 |
|||
* |
|||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 |
|||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App |
|||
* |
|||
*/ |
|||
|
|||
/** |
|||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 |
|||
* |
|||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 |
|||
*/ |
|||
|
|||
/* 颜色变量 */ |
|||
|
|||
/* 行为相关颜色 */ |
|||
$uni-color-primary: #007aff; |
|||
$uni-color-success: #4cd964; |
|||
$uni-color-warning: #f0ad4e; |
|||
$uni-color-error: #dd524d; |
|||
|
|||
/* 文字基本颜色 */ |
|||
$uni-text-color:#333;//基本色 |
|||
$uni-text-color-inverse:#fff;//反色 |
|||
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息 |
|||
$uni-text-color-placeholder: #808080; |
|||
$uni-text-color-disable:#c0c0c0; |
|||
|
|||
/* 背景颜色 */ |
|||
$uni-bg-color:#ffffff; |
|||
$uni-bg-color-grey:#f8f8f8; |
|||
$uni-bg-color-hover:#f1f1f1;//点击状态颜色 |
|||
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 |
|||
|
|||
/* 边框颜色 */ |
|||
$uni-border-color:#c8c7cc; |
|||
|
|||
/* 尺寸变量 */ |
|||
|
|||
/* 文字尺寸 */ |
|||
$uni-font-size-sm:12px; |
|||
$uni-font-size-base:14px; |
|||
$uni-font-size-lg:16px; |
|||
|
|||
/* 图片尺寸 */ |
|||
$uni-img-size-sm:20px; |
|||
$uni-img-size-base:26px; |
|||
$uni-img-size-lg:40px; |
|||
|
|||
/* Border Radius */ |
|||
$uni-border-radius-sm: 2px; |
|||
$uni-border-radius-base: 3px; |
|||
$uni-border-radius-lg: 6px; |
|||
$uni-border-radius-circle: 50%; |
|||
|
|||
/* 水平间距 */ |
|||
$uni-spacing-row-sm: 5px; |
|||
$uni-spacing-row-base: 10px; |
|||
$uni-spacing-row-lg: 15px; |
|||
|
|||
/* 垂直间距 */ |
|||
$uni-spacing-col-sm: 4px; |
|||
$uni-spacing-col-base: 8px; |
|||
$uni-spacing-col-lg: 12px; |
|||
|
|||
/* 透明度 */ |
|||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 |
|||
|
|||
/* 文章场景相关 */ |
|||
$uni-color-title: #2C405A; // 文章标题颜色 |
|||
$uni-font-size-title:20px; |
|||
$uni-color-subtitle: #555555; // 二级标题颜色 |
|||
$uni-font-size-subtitle:26px; |
|||
$uni-color-paragraph: #3F536E; // 文章段落颜色 |
|||
$uni-font-size-paragraph:15px; |
@ -0,0 +1,42 @@ |
|||
## 2.0.10(2024-06-07) |
|||
- 优化 uni-app x 中,size 属性的类型 |
|||
## 2.0.9(2024-01-12) |
|||
fix: 修复图标大小默认值错误的问题 |
|||
## 2.0.8(2023-12-14) |
|||
- 修复 项目未使用 ts 情况下,打包报错的bug |
|||
## 2.0.7(2023-12-14) |
|||
- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug |
|||
## 2.0.6(2023-12-11) |
|||
- 优化 兼容老版本icon类型,如 top ,bottom 等 |
|||
## 2.0.5(2023-12-11) |
|||
- 优化 兼容老版本icon类型,如 top ,bottom 等 |
|||
## 2.0.4(2023-12-06) |
|||
- 优化 uni-app x 下示例项目图标排序 |
|||
## 2.0.3(2023-12-06) |
|||
- 修复 nvue下引入组件报错的bug |
|||
## 2.0.2(2023-12-05) |
|||
-优化 size 属性支持单位 |
|||
## 2.0.1(2023-12-05) |
|||
- 新增 uni-app x 支持定义图标 |
|||
## 1.3.5(2022-01-24) |
|||
- 优化 size 属性可以传入不带单位的字符串数值 |
|||
## 1.3.4(2022-01-24) |
|||
- 优化 size 支持其他单位 |
|||
## 1.3.3(2022-01-17) |
|||
- 修复 nvue 有些图标不显示的bug,兼容老版本图标 |
|||
## 1.3.2(2021-12-01) |
|||
- 优化 示例可复制图标名称 |
|||
## 1.3.1(2021-11-23) |
|||
- 优化 兼容旧组件 type 值 |
|||
## 1.3.0(2021-11-19) |
|||
- 新增 更多图标 |
|||
- 优化 自定义图标使用方式 |
|||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) |
|||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons) |
|||
## 1.1.7(2021-11-08) |
|||
## 1.2.0(2021-07-30) |
|||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
|||
## 1.1.5(2021-05-12) |
|||
- 新增 组件示例地址 |
|||
## 1.1.4(2021-02-05) |
|||
- 调整为uni_modules目录规范 |
@ -0,0 +1,91 @@ |
|||
<template> |
|||
<text class="uni-icons" :style="styleObj"> |
|||
<slot>{{unicode}}</slot> |
|||
</text> |
|||
</template> |
|||
|
|||
<script> |
|||
import { fontData, IconsDataItem } from './uniicons_file' |
|||
|
|||
/** |
|||
* Icons 图标 |
|||
* @description 用于展示 icon 图标 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=28 |
|||
* @property {Number,String} size 图标大小 |
|||
* @property {String} type 图标图案,参考示例 |
|||
* @property {String} color 图标颜色 |
|||
* @property {String} customPrefix 自定义图标 |
|||
* @event {Function} click 点击 Icon 触发事件 |
|||
*/ |
|||
export default { |
|||
name: "uni-icons", |
|||
props: { |
|||
type: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
color: { |
|||
type: String, |
|||
default: '#333333' |
|||
}, |
|||
size: { |
|||
type: [Number, String], |
|||
default: 16 |
|||
}, |
|||
fontFamily: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
data() { |
|||
return {}; |
|||
}, |
|||
computed: { |
|||
unicode() : string { |
|||
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type }) |
|||
if (codes !== null) { |
|||
return codes.unicode |
|||
} |
|||
return '' |
|||
}, |
|||
iconSize() : string { |
|||
const size = this.size |
|||
if (typeof size == 'string') { |
|||
const reg = /^[0-9]*$/g |
|||
return reg.test(size as string) ? '' + size + 'px' : '' + size; |
|||
// return '' + this.size |
|||
} |
|||
return this.getFontSize(size as number) |
|||
}, |
|||
styleObj() : UTSJSONObject { |
|||
if (this.fontFamily !== '') { |
|||
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily } |
|||
} |
|||
return { color: this.color, fontSize: this.iconSize } |
|||
} |
|||
}, |
|||
created() { }, |
|||
methods: { |
|||
/** |
|||
* 字体大小 |
|||
*/ |
|||
getFontSize(size : number) : string { |
|||
return size + 'px'; |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
@font-face { |
|||
font-family: UniIconsFontFamily; |
|||
src: url('./uniicons.ttf'); |
|||
} |
|||
|
|||
.uni-icons { |
|||
font-family: UniIconsFontFamily; |
|||
font-size: 18px; |
|||
font-style: normal; |
|||
color: #333; |
|||
} |
|||
</style> |
@ -0,0 +1,110 @@ |
|||
<template> |
|||
<!-- #ifdef APP-NVUE --> |
|||
<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text> |
|||
<!-- #endif --> |
|||
<!-- #ifndef APP-NVUE --> |
|||
<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"> |
|||
<slot></slot> |
|||
</text> |
|||
<!-- #endif --> |
|||
</template> |
|||
|
|||
<script> |
|||
import { fontData } from './uniicons_file_vue.js'; |
|||
|
|||
const getVal = (val) => { |
|||
const reg = /^[0-9]*$/g |
|||
return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val; |
|||
} |
|||
|
|||
// #ifdef APP-NVUE |
|||
var domModule = weex.requireModule('dom'); |
|||
import iconUrl from './uniicons.ttf' |
|||
domModule.addRule('fontFace', { |
|||
'fontFamily': "uniicons", |
|||
'src': "url('" + iconUrl + "')" |
|||
}); |
|||
// #endif |
|||
|
|||
/** |
|||
* Icons 图标 |
|||
* @description 用于展示 icons 图标 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=28 |
|||
* @property {Number} size 图标大小 |
|||
* @property {String} type 图标图案,参考示例 |
|||
* @property {String} color 图标颜色 |
|||
* @property {String} customPrefix 自定义图标 |
|||
* @event {Function} click 点击 Icon 触发事件 |
|||
*/ |
|||
export default { |
|||
name: 'UniIcons', |
|||
emits: ['click'], |
|||
props: { |
|||
type: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
color: { |
|||
type: String, |
|||
default: '#333333' |
|||
}, |
|||
size: { |
|||
type: [Number, String], |
|||
default: 16 |
|||
}, |
|||
customPrefix: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
fontFamily: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
icons: fontData |
|||
} |
|||
}, |
|||
computed: { |
|||
unicode() { |
|||
let code = this.icons.find(v => v.font_class === this.type) |
|||
if (code) { |
|||
return code.unicode |
|||
} |
|||
return '' |
|||
}, |
|||
iconSize() { |
|||
return getVal(this.size) |
|||
}, |
|||
styleObj() { |
|||
if (this.fontFamily !== '') { |
|||
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};` |
|||
} |
|||
return `color: ${this.color}; font-size: ${this.iconSize};` |
|||
} |
|||
}, |
|||
methods: { |
|||
_onClick() { |
|||
this.$emit('click') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
/* #ifndef APP-NVUE */ |
|||
@import './uniicons.css'; |
|||
|
|||
@font-face { |
|||
font-family: uniicons; |
|||
src: url('./uniicons.ttf'); |
|||
} |
|||
|
|||
/* #endif */ |
|||
.uni-icons { |
|||
font-family: uniicons; |
|||
text-decoration: none; |
|||
text-align: center; |
|||
} |
|||
</style> |
@ -0,0 +1,664 @@ |
|||
|
|||
.uniui-cart-filled:before { |
|||
content: "\e6d0"; |
|||
} |
|||
|
|||
.uniui-gift-filled:before { |
|||
content: "\e6c4"; |
|||
} |
|||
|
|||
.uniui-color:before { |
|||
content: "\e6cf"; |
|||
} |
|||
|
|||
.uniui-wallet:before { |
|||
content: "\e6b1"; |
|||
} |
|||
|
|||
.uniui-settings-filled:before { |
|||
content: "\e6ce"; |
|||
} |
|||
|
|||
.uniui-auth-filled:before { |
|||
content: "\e6cc"; |
|||
} |
|||
|
|||
.uniui-shop-filled:before { |
|||
content: "\e6cd"; |
|||
} |
|||
|
|||
.uniui-staff-filled:before { |
|||
content: "\e6cb"; |
|||
} |
|||
|
|||
.uniui-vip-filled:before { |
|||
content: "\e6c6"; |
|||
} |
|||
|
|||
.uniui-plus-filled:before { |
|||
content: "\e6c7"; |
|||
} |
|||
|
|||
.uniui-folder-add-filled:before { |
|||
content: "\e6c8"; |
|||
} |
|||
|
|||
.uniui-color-filled:before { |
|||
content: "\e6c9"; |
|||
} |
|||
|
|||
.uniui-tune-filled:before { |
|||
content: "\e6ca"; |
|||
} |
|||
|
|||
.uniui-calendar-filled:before { |
|||
content: "\e6c0"; |
|||
} |
|||
|
|||
.uniui-notification-filled:before { |
|||
content: "\e6c1"; |
|||
} |
|||
|
|||
.uniui-wallet-filled:before { |
|||
content: "\e6c2"; |
|||
} |
|||
|
|||
.uniui-medal-filled:before { |
|||
content: "\e6c3"; |
|||
} |
|||
|
|||
.uniui-fire-filled:before { |
|||
content: "\e6c5"; |
|||
} |
|||
|
|||
.uniui-refreshempty:before { |
|||
content: "\e6bf"; |
|||
} |
|||
|
|||
.uniui-location-filled:before { |
|||
content: "\e6af"; |
|||
} |
|||
|
|||
.uniui-person-filled:before { |
|||
content: "\e69d"; |
|||
} |
|||
|
|||
.uniui-personadd-filled:before { |
|||
content: "\e698"; |
|||
} |
|||
|
|||
.uniui-arrowthinleft:before { |
|||
content: "\e6d2"; |
|||
} |
|||
|
|||
.uniui-arrowthinup:before { |
|||
content: "\e6d3"; |
|||
} |
|||
|
|||
.uniui-arrowthindown:before { |
|||
content: "\e6d4"; |
|||
} |
|||
|
|||
.uniui-back:before { |
|||
content: "\e6b9"; |
|||
} |
|||
|
|||
.uniui-forward:before { |
|||
content: "\e6ba"; |
|||
} |
|||
|
|||
.uniui-arrow-right:before { |
|||
content: "\e6bb"; |
|||
} |
|||
|
|||
.uniui-arrow-left:before { |
|||
content: "\e6bc"; |
|||
} |
|||
|
|||
.uniui-arrow-up:before { |
|||
content: "\e6bd"; |
|||
} |
|||
|
|||
.uniui-arrow-down:before { |
|||
content: "\e6be"; |
|||
} |
|||
|
|||
.uniui-arrowthinright:before { |
|||
content: "\e6d1"; |
|||
} |
|||
|
|||
.uniui-down:before { |
|||
content: "\e6b8"; |
|||
} |
|||
|
|||
.uniui-bottom:before { |
|||
content: "\e6b8"; |
|||
} |
|||
|
|||
.uniui-arrowright:before { |
|||
content: "\e6d5"; |
|||
} |
|||
|
|||
.uniui-right:before { |
|||
content: "\e6b5"; |
|||
} |
|||
|
|||
.uniui-up:before { |
|||
content: "\e6b6"; |
|||
} |
|||
|
|||
.uniui-top:before { |
|||
content: "\e6b6"; |
|||
} |
|||
|
|||
.uniui-left:before { |
|||
content: "\e6b7"; |
|||
} |
|||
|
|||
.uniui-arrowup:before { |
|||
content: "\e6d6"; |
|||
} |
|||
|
|||
.uniui-eye:before { |
|||
content: "\e651"; |
|||
} |
|||
|
|||
.uniui-eye-filled:before { |
|||
content: "\e66a"; |
|||
} |
|||
|
|||
.uniui-eye-slash:before { |
|||
content: "\e6b3"; |
|||
} |
|||
|
|||
.uniui-eye-slash-filled:before { |
|||
content: "\e6b4"; |
|||
} |
|||
|
|||
.uniui-info-filled:before { |
|||
content: "\e649"; |
|||
} |
|||
|
|||
.uniui-reload:before { |
|||
content: "\e6b2"; |
|||
} |
|||
|
|||
.uniui-micoff-filled:before { |
|||
content: "\e6b0"; |
|||
} |
|||
|
|||
.uniui-map-pin-ellipse:before { |
|||
content: "\e6ac"; |
|||
} |
|||
|
|||
.uniui-map-pin:before { |
|||
content: "\e6ad"; |
|||
} |
|||
|
|||
.uniui-location:before { |
|||
content: "\e6ae"; |
|||
} |
|||
|
|||
.uniui-starhalf:before { |
|||
content: "\e683"; |
|||
} |
|||
|
|||
.uniui-star:before { |
|||
content: "\e688"; |
|||
} |
|||
|
|||
.uniui-star-filled:before { |
|||
content: "\e68f"; |
|||
} |
|||
|
|||
.uniui-calendar:before { |
|||
content: "\e6a0"; |
|||
} |
|||
|
|||
.uniui-fire:before { |
|||
content: "\e6a1"; |
|||
} |
|||
|
|||
.uniui-medal:before { |
|||
content: "\e6a2"; |
|||
} |
|||
|
|||
.uniui-font:before { |
|||
content: "\e6a3"; |
|||
} |
|||
|
|||
.uniui-gift:before { |
|||
content: "\e6a4"; |
|||
} |
|||
|
|||
.uniui-link:before { |
|||
content: "\e6a5"; |
|||
} |
|||
|
|||
.uniui-notification:before { |
|||
content: "\e6a6"; |
|||
} |
|||
|
|||
.uniui-staff:before { |
|||
content: "\e6a7"; |
|||
} |
|||
|
|||
.uniui-vip:before { |
|||
content: "\e6a8"; |
|||
} |
|||
|
|||
.uniui-folder-add:before { |
|||
content: "\e6a9"; |
|||
} |
|||
|
|||
.uniui-tune:before { |
|||
content: "\e6aa"; |
|||
} |
|||
|
|||
.uniui-auth:before { |
|||
content: "\e6ab"; |
|||
} |
|||
|
|||
.uniui-person:before { |
|||
content: "\e699"; |
|||
} |
|||
|
|||
.uniui-email-filled:before { |
|||
content: "\e69a"; |
|||
} |
|||
|
|||
.uniui-phone-filled:before { |
|||
content: "\e69b"; |
|||
} |
|||
|
|||
.uniui-phone:before { |
|||
content: "\e69c"; |
|||
} |
|||
|
|||
.uniui-email:before { |
|||
content: "\e69e"; |
|||
} |
|||
|
|||
.uniui-personadd:before { |
|||
content: "\e69f"; |
|||
} |
|||
|
|||
.uniui-chatboxes-filled:before { |
|||
content: "\e692"; |
|||
} |
|||
|
|||
.uniui-contact:before { |
|||
content: "\e693"; |
|||
} |
|||
|
|||
.uniui-chatbubble-filled:before { |
|||
content: "\e694"; |
|||
} |
|||
|
|||
.uniui-contact-filled:before { |
|||
content: "\e695"; |
|||
} |
|||
|
|||
.uniui-chatboxes:before { |
|||
content: "\e696"; |
|||
} |
|||
|
|||
.uniui-chatbubble:before { |
|||
content: "\e697"; |
|||
} |
|||
|
|||
.uniui-upload-filled:before { |
|||
content: "\e68e"; |
|||
} |
|||
|
|||
.uniui-upload:before { |
|||
content: "\e690"; |
|||
} |
|||
|
|||
.uniui-weixin:before { |
|||
content: "\e691"; |
|||
} |
|||
|
|||
.uniui-compose:before { |
|||
content: "\e67f"; |
|||
} |
|||
|
|||
.uniui-qq:before { |
|||
content: "\e680"; |
|||
} |
|||
|
|||
.uniui-download-filled:before { |
|||
content: "\e681"; |
|||
} |
|||
|
|||
.uniui-pyq:before { |
|||
content: "\e682"; |
|||
} |
|||
|
|||
.uniui-sound:before { |
|||
content: "\e684"; |
|||
} |
|||
|
|||
.uniui-trash-filled:before { |
|||
content: "\e685"; |
|||
} |
|||
|
|||
.uniui-sound-filled:before { |
|||
content: "\e686"; |
|||
} |
|||
|
|||
.uniui-trash:before { |
|||
content: "\e687"; |
|||
} |
|||
|
|||
.uniui-videocam-filled:before { |
|||
content: "\e689"; |
|||
} |
|||
|
|||
.uniui-spinner-cycle:before { |
|||
content: "\e68a"; |
|||
} |
|||
|
|||
.uniui-weibo:before { |
|||
content: "\e68b"; |
|||
} |
|||
|
|||
.uniui-videocam:before { |
|||
content: "\e68c"; |
|||
} |
|||
|
|||
.uniui-download:before { |
|||
content: "\e68d"; |
|||
} |
|||
|
|||
.uniui-help:before { |
|||
content: "\e679"; |
|||
} |
|||
|
|||
.uniui-navigate-filled:before { |
|||
content: "\e67a"; |
|||
} |
|||
|
|||
.uniui-plusempty:before { |
|||
content: "\e67b"; |
|||
} |
|||
|
|||
.uniui-smallcircle:before { |
|||
content: "\e67c"; |
|||
} |
|||
|
|||
.uniui-minus-filled:before { |
|||
content: "\e67d"; |
|||
} |
|||
|
|||
.uniui-micoff:before { |
|||
content: "\e67e"; |
|||
} |
|||
|
|||
.uniui-closeempty:before { |
|||
content: "\e66c"; |
|||
} |
|||
|
|||
.uniui-clear:before { |
|||
content: "\e66d"; |
|||
} |
|||
|
|||
.uniui-navigate:before { |
|||
content: "\e66e"; |
|||
} |
|||
|
|||
.uniui-minus:before { |
|||
content: "\e66f"; |
|||
} |
|||
|
|||
.uniui-image:before { |
|||
content: "\e670"; |
|||
} |
|||
|
|||
.uniui-mic:before { |
|||
content: "\e671"; |
|||
} |
|||
|
|||
.uniui-paperplane:before { |
|||
content: "\e672"; |
|||
} |
|||
|
|||
.uniui-close:before { |
|||
content: "\e673"; |
|||
} |
|||
|
|||
.uniui-help-filled:before { |
|||
content: "\e674"; |
|||
} |
|||
|
|||
.uniui-paperplane-filled:before { |
|||
content: "\e675"; |
|||
} |
|||
|
|||
.uniui-plus:before { |
|||
content: "\e676"; |
|||
} |
|||
|
|||
.uniui-mic-filled:before { |
|||
content: "\e677"; |
|||
} |
|||
|
|||
.uniui-image-filled:before { |
|||
content: "\e678"; |
|||
} |
|||
|
|||
.uniui-locked-filled:before { |
|||
content: "\e668"; |
|||
} |
|||
|
|||
.uniui-info:before { |
|||
content: "\e669"; |
|||
} |
|||
|
|||
.uniui-locked:before { |
|||
content: "\e66b"; |
|||
} |
|||
|
|||
.uniui-camera-filled:before { |
|||
content: "\e658"; |
|||
} |
|||
|
|||
.uniui-chat-filled:before { |
|||
content: "\e659"; |
|||
} |
|||
|
|||
.uniui-camera:before { |
|||
content: "\e65a"; |
|||
} |
|||
|
|||
.uniui-circle:before { |
|||
content: "\e65b"; |
|||
} |
|||
|
|||
.uniui-checkmarkempty:before { |
|||
content: "\e65c"; |
|||
} |
|||
|
|||
.uniui-chat:before { |
|||
content: "\e65d"; |
|||
} |
|||
|
|||
.uniui-circle-filled:before { |
|||
content: "\e65e"; |
|||
} |
|||
|
|||
.uniui-flag:before { |
|||
content: "\e65f"; |
|||
} |
|||
|
|||
.uniui-flag-filled:before { |
|||
content: "\e660"; |
|||
} |
|||
|
|||
.uniui-gear-filled:before { |
|||
content: "\e661"; |
|||
} |
|||
|
|||
.uniui-home:before { |
|||
content: "\e662"; |
|||
} |
|||
|
|||
.uniui-home-filled:before { |
|||
content: "\e663"; |
|||
} |
|||
|
|||
.uniui-gear:before { |
|||
content: "\e664"; |
|||
} |
|||
|
|||
.uniui-smallcircle-filled:before { |
|||
content: "\e665"; |
|||
} |
|||
|
|||
.uniui-map-filled:before { |
|||
content: "\e666"; |
|||
} |
|||
|
|||
.uniui-map:before { |
|||
content: "\e667"; |
|||
} |
|||
|
|||
.uniui-refresh-filled:before { |
|||
content: "\e656"; |
|||
} |
|||
|
|||
.uniui-refresh:before { |
|||
content: "\e657"; |
|||
} |
|||
|
|||
.uniui-cloud-upload:before { |
|||
content: "\e645"; |
|||
} |
|||
|
|||
.uniui-cloud-download-filled:before { |
|||
content: "\e646"; |
|||
} |
|||
|
|||
.uniui-cloud-download:before { |
|||
content: "\e647"; |
|||
} |
|||
|
|||
.uniui-cloud-upload-filled:before { |
|||
content: "\e648"; |
|||
} |
|||
|
|||
.uniui-redo:before { |
|||
content: "\e64a"; |
|||
} |
|||
|
|||
.uniui-images-filled:before { |
|||
content: "\e64b"; |
|||
} |
|||
|
|||
.uniui-undo-filled:before { |
|||
content: "\e64c"; |
|||
} |
|||
|
|||
.uniui-more:before { |
|||
content: "\e64d"; |
|||
} |
|||
|
|||
.uniui-more-filled:before { |
|||
content: "\e64e"; |
|||
} |
|||
|
|||
.uniui-undo:before { |
|||
content: "\e64f"; |
|||
} |
|||
|
|||
.uniui-images:before { |
|||
content: "\e650"; |
|||
} |
|||
|
|||
.uniui-paperclip:before { |
|||
content: "\e652"; |
|||
} |
|||
|
|||
.uniui-settings:before { |
|||
content: "\e653"; |
|||
} |
|||
|
|||
.uniui-search:before { |
|||
content: "\e654"; |
|||
} |
|||
|
|||
.uniui-redo-filled:before { |
|||
content: "\e655"; |
|||
} |
|||
|
|||
.uniui-list:before { |
|||
content: "\e644"; |
|||
} |
|||
|
|||
.uniui-mail-open-filled:before { |
|||
content: "\e63a"; |
|||
} |
|||
|
|||
.uniui-hand-down-filled:before { |
|||
content: "\e63c"; |
|||
} |
|||
|
|||
.uniui-hand-down:before { |
|||
content: "\e63d"; |
|||
} |
|||
|
|||
.uniui-hand-up-filled:before { |
|||
content: "\e63e"; |
|||
} |
|||
|
|||
.uniui-hand-up:before { |
|||
content: "\e63f"; |
|||
} |
|||
|
|||
.uniui-heart-filled:before { |
|||
content: "\e641"; |
|||
} |
|||
|
|||
.uniui-mail-open:before { |
|||
content: "\e643"; |
|||
} |
|||
|
|||
.uniui-heart:before { |
|||
content: "\e639"; |
|||
} |
|||
|
|||
.uniui-loop:before { |
|||
content: "\e633"; |
|||
} |
|||
|
|||
.uniui-pulldown:before { |
|||
content: "\e632"; |
|||
} |
|||
|
|||
.uniui-scan:before { |
|||
content: "\e62a"; |
|||
} |
|||
|
|||
.uniui-bars:before { |
|||
content: "\e627"; |
|||
} |
|||
|
|||
.uniui-checkbox:before { |
|||
content: "\e62b"; |
|||
} |
|||
|
|||
.uniui-checkbox-filled:before { |
|||
content: "\e62c"; |
|||
} |
|||
|
|||
.uniui-shop:before { |
|||
content: "\e62f"; |
|||
} |
|||
|
|||
.uniui-headphones:before { |
|||
content: "\e630"; |
|||
} |
|||
|
|||
.uniui-cart:before { |
|||
content: "\e631"; |
|||
} |
@ -0,0 +1,664 @@ |
|||
|
|||
export type IconsData = { |
|||
id : string |
|||
name : string |
|||
font_family : string |
|||
css_prefix_text : string |
|||
description : string |
|||
glyphs : Array<IconsDataItem> |
|||
} |
|||
|
|||
export type IconsDataItem = { |
|||
font_class : string |
|||
unicode : string |
|||
} |
|||
|
|||
|
|||
export const fontData = [ |
|||
{ |
|||
"font_class": "arrow-down", |
|||
"unicode": "\ue6be" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-left", |
|||
"unicode": "\ue6bc" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-right", |
|||
"unicode": "\ue6bb" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-up", |
|||
"unicode": "\ue6bd" |
|||
}, |
|||
{ |
|||
"font_class": "auth", |
|||
"unicode": "\ue6ab" |
|||
}, |
|||
{ |
|||
"font_class": "auth-filled", |
|||
"unicode": "\ue6cc" |
|||
}, |
|||
{ |
|||
"font_class": "back", |
|||
"unicode": "\ue6b9" |
|||
}, |
|||
{ |
|||
"font_class": "bars", |
|||
"unicode": "\ue627" |
|||
}, |
|||
{ |
|||
"font_class": "calendar", |
|||
"unicode": "\ue6a0" |
|||
}, |
|||
{ |
|||
"font_class": "calendar-filled", |
|||
"unicode": "\ue6c0" |
|||
}, |
|||
{ |
|||
"font_class": "camera", |
|||
"unicode": "\ue65a" |
|||
}, |
|||
{ |
|||
"font_class": "camera-filled", |
|||
"unicode": "\ue658" |
|||
}, |
|||
{ |
|||
"font_class": "cart", |
|||
"unicode": "\ue631" |
|||
}, |
|||
{ |
|||
"font_class": "cart-filled", |
|||
"unicode": "\ue6d0" |
|||
}, |
|||
{ |
|||
"font_class": "chat", |
|||
"unicode": "\ue65d" |
|||
}, |
|||
{ |
|||
"font_class": "chat-filled", |
|||
"unicode": "\ue659" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes", |
|||
"unicode": "\ue696" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes-filled", |
|||
"unicode": "\ue692" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble", |
|||
"unicode": "\ue697" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble-filled", |
|||
"unicode": "\ue694" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox", |
|||
"unicode": "\ue62b" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox-filled", |
|||
"unicode": "\ue62c" |
|||
}, |
|||
{ |
|||
"font_class": "checkmarkempty", |
|||
"unicode": "\ue65c" |
|||
}, |
|||
{ |
|||
"font_class": "circle", |
|||
"unicode": "\ue65b" |
|||
}, |
|||
{ |
|||
"font_class": "circle-filled", |
|||
"unicode": "\ue65e" |
|||
}, |
|||
{ |
|||
"font_class": "clear", |
|||
"unicode": "\ue66d" |
|||
}, |
|||
{ |
|||
"font_class": "close", |
|||
"unicode": "\ue673" |
|||
}, |
|||
{ |
|||
"font_class": "closeempty", |
|||
"unicode": "\ue66c" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download", |
|||
"unicode": "\ue647" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download-filled", |
|||
"unicode": "\ue646" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload", |
|||
"unicode": "\ue645" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload-filled", |
|||
"unicode": "\ue648" |
|||
}, |
|||
{ |
|||
"font_class": "color", |
|||
"unicode": "\ue6cf" |
|||
}, |
|||
{ |
|||
"font_class": "color-filled", |
|||
"unicode": "\ue6c9" |
|||
}, |
|||
{ |
|||
"font_class": "compose", |
|||
"unicode": "\ue67f" |
|||
}, |
|||
{ |
|||
"font_class": "contact", |
|||
"unicode": "\ue693" |
|||
}, |
|||
{ |
|||
"font_class": "contact-filled", |
|||
"unicode": "\ue695" |
|||
}, |
|||
{ |
|||
"font_class": "down", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "bottom", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "download", |
|||
"unicode": "\ue68d" |
|||
}, |
|||
{ |
|||
"font_class": "download-filled", |
|||
"unicode": "\ue681" |
|||
}, |
|||
{ |
|||
"font_class": "email", |
|||
"unicode": "\ue69e" |
|||
}, |
|||
{ |
|||
"font_class": "email-filled", |
|||
"unicode": "\ue69a" |
|||
}, |
|||
{ |
|||
"font_class": "eye", |
|||
"unicode": "\ue651" |
|||
}, |
|||
{ |
|||
"font_class": "eye-filled", |
|||
"unicode": "\ue66a" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash", |
|||
"unicode": "\ue6b3" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash-filled", |
|||
"unicode": "\ue6b4" |
|||
}, |
|||
{ |
|||
"font_class": "fire", |
|||
"unicode": "\ue6a1" |
|||
}, |
|||
{ |
|||
"font_class": "fire-filled", |
|||
"unicode": "\ue6c5" |
|||
}, |
|||
{ |
|||
"font_class": "flag", |
|||
"unicode": "\ue65f" |
|||
}, |
|||
{ |
|||
"font_class": "flag-filled", |
|||
"unicode": "\ue660" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add", |
|||
"unicode": "\ue6a9" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add-filled", |
|||
"unicode": "\ue6c8" |
|||
}, |
|||
{ |
|||
"font_class": "font", |
|||
"unicode": "\ue6a3" |
|||
}, |
|||
{ |
|||
"font_class": "forward", |
|||
"unicode": "\ue6ba" |
|||
}, |
|||
{ |
|||
"font_class": "gear", |
|||
"unicode": "\ue664" |
|||
}, |
|||
{ |
|||
"font_class": "gear-filled", |
|||
"unicode": "\ue661" |
|||
}, |
|||
{ |
|||
"font_class": "gift", |
|||
"unicode": "\ue6a4" |
|||
}, |
|||
{ |
|||
"font_class": "gift-filled", |
|||
"unicode": "\ue6c4" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down", |
|||
"unicode": "\ue63d" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down-filled", |
|||
"unicode": "\ue63c" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up", |
|||
"unicode": "\ue63f" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up-filled", |
|||
"unicode": "\ue63e" |
|||
}, |
|||
{ |
|||
"font_class": "headphones", |
|||
"unicode": "\ue630" |
|||
}, |
|||
{ |
|||
"font_class": "heart", |
|||
"unicode": "\ue639" |
|||
}, |
|||
{ |
|||
"font_class": "heart-filled", |
|||
"unicode": "\ue641" |
|||
}, |
|||
{ |
|||
"font_class": "help", |
|||
"unicode": "\ue679" |
|||
}, |
|||
{ |
|||
"font_class": "help-filled", |
|||
"unicode": "\ue674" |
|||
}, |
|||
{ |
|||
"font_class": "home", |
|||
"unicode": "\ue662" |
|||
}, |
|||
{ |
|||
"font_class": "home-filled", |
|||
"unicode": "\ue663" |
|||
}, |
|||
{ |
|||
"font_class": "image", |
|||
"unicode": "\ue670" |
|||
}, |
|||
{ |
|||
"font_class": "image-filled", |
|||
"unicode": "\ue678" |
|||
}, |
|||
{ |
|||
"font_class": "images", |
|||
"unicode": "\ue650" |
|||
}, |
|||
{ |
|||
"font_class": "images-filled", |
|||
"unicode": "\ue64b" |
|||
}, |
|||
{ |
|||
"font_class": "info", |
|||
"unicode": "\ue669" |
|||
}, |
|||
{ |
|||
"font_class": "info-filled", |
|||
"unicode": "\ue649" |
|||
}, |
|||
{ |
|||
"font_class": "left", |
|||
"unicode": "\ue6b7" |
|||
}, |
|||
{ |
|||
"font_class": "link", |
|||
"unicode": "\ue6a5" |
|||
}, |
|||
{ |
|||
"font_class": "list", |
|||
"unicode": "\ue644" |
|||
}, |
|||
{ |
|||
"font_class": "location", |
|||
"unicode": "\ue6ae" |
|||
}, |
|||
{ |
|||
"font_class": "location-filled", |
|||
"unicode": "\ue6af" |
|||
}, |
|||
{ |
|||
"font_class": "locked", |
|||
"unicode": "\ue66b" |
|||
}, |
|||
{ |
|||
"font_class": "locked-filled", |
|||
"unicode": "\ue668" |
|||
}, |
|||
{ |
|||
"font_class": "loop", |
|||
"unicode": "\ue633" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open", |
|||
"unicode": "\ue643" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open-filled", |
|||
"unicode": "\ue63a" |
|||
}, |
|||
{ |
|||
"font_class": "map", |
|||
"unicode": "\ue667" |
|||
}, |
|||
{ |
|||
"font_class": "map-filled", |
|||
"unicode": "\ue666" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin", |
|||
"unicode": "\ue6ad" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin-ellipse", |
|||
"unicode": "\ue6ac" |
|||
}, |
|||
{ |
|||
"font_class": "medal", |
|||
"unicode": "\ue6a2" |
|||
}, |
|||
{ |
|||
"font_class": "medal-filled", |
|||
"unicode": "\ue6c3" |
|||
}, |
|||
{ |
|||
"font_class": "mic", |
|||
"unicode": "\ue671" |
|||
}, |
|||
{ |
|||
"font_class": "mic-filled", |
|||
"unicode": "\ue677" |
|||
}, |
|||
{ |
|||
"font_class": "micoff", |
|||
"unicode": "\ue67e" |
|||
}, |
|||
{ |
|||
"font_class": "micoff-filled", |
|||
"unicode": "\ue6b0" |
|||
}, |
|||
{ |
|||
"font_class": "minus", |
|||
"unicode": "\ue66f" |
|||
}, |
|||
{ |
|||
"font_class": "minus-filled", |
|||
"unicode": "\ue67d" |
|||
}, |
|||
{ |
|||
"font_class": "more", |
|||
"unicode": "\ue64d" |
|||
}, |
|||
{ |
|||
"font_class": "more-filled", |
|||
"unicode": "\ue64e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate", |
|||
"unicode": "\ue66e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate-filled", |
|||
"unicode": "\ue67a" |
|||
}, |
|||
{ |
|||
"font_class": "notification", |
|||
"unicode": "\ue6a6" |
|||
}, |
|||
{ |
|||
"font_class": "notification-filled", |
|||
"unicode": "\ue6c1" |
|||
}, |
|||
{ |
|||
"font_class": "paperclip", |
|||
"unicode": "\ue652" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane", |
|||
"unicode": "\ue672" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane-filled", |
|||
"unicode": "\ue675" |
|||
}, |
|||
{ |
|||
"font_class": "person", |
|||
"unicode": "\ue699" |
|||
}, |
|||
{ |
|||
"font_class": "person-filled", |
|||
"unicode": "\ue69d" |
|||
}, |
|||
{ |
|||
"font_class": "personadd", |
|||
"unicode": "\ue69f" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled", |
|||
"unicode": "\ue698" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled-copy", |
|||
"unicode": "\ue6d1" |
|||
}, |
|||
{ |
|||
"font_class": "phone", |
|||
"unicode": "\ue69c" |
|||
}, |
|||
{ |
|||
"font_class": "phone-filled", |
|||
"unicode": "\ue69b" |
|||
}, |
|||
{ |
|||
"font_class": "plus", |
|||
"unicode": "\ue676" |
|||
}, |
|||
{ |
|||
"font_class": "plus-filled", |
|||
"unicode": "\ue6c7" |
|||
}, |
|||
{ |
|||
"font_class": "plusempty", |
|||
"unicode": "\ue67b" |
|||
}, |
|||
{ |
|||
"font_class": "pulldown", |
|||
"unicode": "\ue632" |
|||
}, |
|||
{ |
|||
"font_class": "pyq", |
|||
"unicode": "\ue682" |
|||
}, |
|||
{ |
|||
"font_class": "qq", |
|||
"unicode": "\ue680" |
|||
}, |
|||
{ |
|||
"font_class": "redo", |
|||
"unicode": "\ue64a" |
|||
}, |
|||
{ |
|||
"font_class": "redo-filled", |
|||
"unicode": "\ue655" |
|||
}, |
|||
{ |
|||
"font_class": "refresh", |
|||
"unicode": "\ue657" |
|||
}, |
|||
{ |
|||
"font_class": "refresh-filled", |
|||
"unicode": "\ue656" |
|||
}, |
|||
{ |
|||
"font_class": "refreshempty", |
|||
"unicode": "\ue6bf" |
|||
}, |
|||
{ |
|||
"font_class": "reload", |
|||
"unicode": "\ue6b2" |
|||
}, |
|||
{ |
|||
"font_class": "right", |
|||
"unicode": "\ue6b5" |
|||
}, |
|||
{ |
|||
"font_class": "scan", |
|||
"unicode": "\ue62a" |
|||
}, |
|||
{ |
|||
"font_class": "search", |
|||
"unicode": "\ue654" |
|||
}, |
|||
{ |
|||
"font_class": "settings", |
|||
"unicode": "\ue653" |
|||
}, |
|||
{ |
|||
"font_class": "settings-filled", |
|||
"unicode": "\ue6ce" |
|||
}, |
|||
{ |
|||
"font_class": "shop", |
|||
"unicode": "\ue62f" |
|||
}, |
|||
{ |
|||
"font_class": "shop-filled", |
|||
"unicode": "\ue6cd" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle", |
|||
"unicode": "\ue67c" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle-filled", |
|||
"unicode": "\ue665" |
|||
}, |
|||
{ |
|||
"font_class": "sound", |
|||
"unicode": "\ue684" |
|||
}, |
|||
{ |
|||
"font_class": "sound-filled", |
|||
"unicode": "\ue686" |
|||
}, |
|||
{ |
|||
"font_class": "spinner-cycle", |
|||
"unicode": "\ue68a" |
|||
}, |
|||
{ |
|||
"font_class": "staff", |
|||
"unicode": "\ue6a7" |
|||
}, |
|||
{ |
|||
"font_class": "staff-filled", |
|||
"unicode": "\ue6cb" |
|||
}, |
|||
{ |
|||
"font_class": "star", |
|||
"unicode": "\ue688" |
|||
}, |
|||
{ |
|||
"font_class": "star-filled", |
|||
"unicode": "\ue68f" |
|||
}, |
|||
{ |
|||
"font_class": "starhalf", |
|||
"unicode": "\ue683" |
|||
}, |
|||
{ |
|||
"font_class": "trash", |
|||
"unicode": "\ue687" |
|||
}, |
|||
{ |
|||
"font_class": "trash-filled", |
|||
"unicode": "\ue685" |
|||
}, |
|||
{ |
|||
"font_class": "tune", |
|||
"unicode": "\ue6aa" |
|||
}, |
|||
{ |
|||
"font_class": "tune-filled", |
|||
"unicode": "\ue6ca" |
|||
}, |
|||
{ |
|||
"font_class": "undo", |
|||
"unicode": "\ue64f" |
|||
}, |
|||
{ |
|||
"font_class": "undo-filled", |
|||
"unicode": "\ue64c" |
|||
}, |
|||
{ |
|||
"font_class": "up", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "top", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "upload", |
|||
"unicode": "\ue690" |
|||
}, |
|||
{ |
|||
"font_class": "upload-filled", |
|||
"unicode": "\ue68e" |
|||
}, |
|||
{ |
|||
"font_class": "videocam", |
|||
"unicode": "\ue68c" |
|||
}, |
|||
{ |
|||
"font_class": "videocam-filled", |
|||
"unicode": "\ue689" |
|||
}, |
|||
{ |
|||
"font_class": "vip", |
|||
"unicode": "\ue6a8" |
|||
}, |
|||
{ |
|||
"font_class": "vip-filled", |
|||
"unicode": "\ue6c6" |
|||
}, |
|||
{ |
|||
"font_class": "wallet", |
|||
"unicode": "\ue6b1" |
|||
}, |
|||
{ |
|||
"font_class": "wallet-filled", |
|||
"unicode": "\ue6c2" |
|||
}, |
|||
{ |
|||
"font_class": "weibo", |
|||
"unicode": "\ue68b" |
|||
}, |
|||
{ |
|||
"font_class": "weixin", |
|||
"unicode": "\ue691" |
|||
} |
|||
] as IconsDataItem[] |
|||
|
|||
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
@ -0,0 +1,649 @@ |
|||
|
|||
export const fontData = [ |
|||
{ |
|||
"font_class": "arrow-down", |
|||
"unicode": "\ue6be" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-left", |
|||
"unicode": "\ue6bc" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-right", |
|||
"unicode": "\ue6bb" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-up", |
|||
"unicode": "\ue6bd" |
|||
}, |
|||
{ |
|||
"font_class": "auth", |
|||
"unicode": "\ue6ab" |
|||
}, |
|||
{ |
|||
"font_class": "auth-filled", |
|||
"unicode": "\ue6cc" |
|||
}, |
|||
{ |
|||
"font_class": "back", |
|||
"unicode": "\ue6b9" |
|||
}, |
|||
{ |
|||
"font_class": "bars", |
|||
"unicode": "\ue627" |
|||
}, |
|||
{ |
|||
"font_class": "calendar", |
|||
"unicode": "\ue6a0" |
|||
}, |
|||
{ |
|||
"font_class": "calendar-filled", |
|||
"unicode": "\ue6c0" |
|||
}, |
|||
{ |
|||
"font_class": "camera", |
|||
"unicode": "\ue65a" |
|||
}, |
|||
{ |
|||
"font_class": "camera-filled", |
|||
"unicode": "\ue658" |
|||
}, |
|||
{ |
|||
"font_class": "cart", |
|||
"unicode": "\ue631" |
|||
}, |
|||
{ |
|||
"font_class": "cart-filled", |
|||
"unicode": "\ue6d0" |
|||
}, |
|||
{ |
|||
"font_class": "chat", |
|||
"unicode": "\ue65d" |
|||
}, |
|||
{ |
|||
"font_class": "chat-filled", |
|||
"unicode": "\ue659" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes", |
|||
"unicode": "\ue696" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes-filled", |
|||
"unicode": "\ue692" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble", |
|||
"unicode": "\ue697" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble-filled", |
|||
"unicode": "\ue694" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox", |
|||
"unicode": "\ue62b" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox-filled", |
|||
"unicode": "\ue62c" |
|||
}, |
|||
{ |
|||
"font_class": "checkmarkempty", |
|||
"unicode": "\ue65c" |
|||
}, |
|||
{ |
|||
"font_class": "circle", |
|||
"unicode": "\ue65b" |
|||
}, |
|||
{ |
|||
"font_class": "circle-filled", |
|||
"unicode": "\ue65e" |
|||
}, |
|||
{ |
|||
"font_class": "clear", |
|||
"unicode": "\ue66d" |
|||
}, |
|||
{ |
|||
"font_class": "close", |
|||
"unicode": "\ue673" |
|||
}, |
|||
{ |
|||
"font_class": "closeempty", |
|||
"unicode": "\ue66c" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download", |
|||
"unicode": "\ue647" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download-filled", |
|||
"unicode": "\ue646" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload", |
|||
"unicode": "\ue645" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload-filled", |
|||
"unicode": "\ue648" |
|||
}, |
|||
{ |
|||
"font_class": "color", |
|||
"unicode": "\ue6cf" |
|||
}, |
|||
{ |
|||
"font_class": "color-filled", |
|||
"unicode": "\ue6c9" |
|||
}, |
|||
{ |
|||
"font_class": "compose", |
|||
"unicode": "\ue67f" |
|||
}, |
|||
{ |
|||
"font_class": "contact", |
|||
"unicode": "\ue693" |
|||
}, |
|||
{ |
|||
"font_class": "contact-filled", |
|||
"unicode": "\ue695" |
|||
}, |
|||
{ |
|||
"font_class": "down", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "bottom", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "download", |
|||
"unicode": "\ue68d" |
|||
}, |
|||
{ |
|||
"font_class": "download-filled", |
|||
"unicode": "\ue681" |
|||
}, |
|||
{ |
|||
"font_class": "email", |
|||
"unicode": "\ue69e" |
|||
}, |
|||
{ |
|||
"font_class": "email-filled", |
|||
"unicode": "\ue69a" |
|||
}, |
|||
{ |
|||
"font_class": "eye", |
|||
"unicode": "\ue651" |
|||
}, |
|||
{ |
|||
"font_class": "eye-filled", |
|||
"unicode": "\ue66a" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash", |
|||
"unicode": "\ue6b3" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash-filled", |
|||
"unicode": "\ue6b4" |
|||
}, |
|||
{ |
|||
"font_class": "fire", |
|||
"unicode": "\ue6a1" |
|||
}, |
|||
{ |
|||
"font_class": "fire-filled", |
|||
"unicode": "\ue6c5" |
|||
}, |
|||
{ |
|||
"font_class": "flag", |
|||
"unicode": "\ue65f" |
|||
}, |
|||
{ |
|||
"font_class": "flag-filled", |
|||
"unicode": "\ue660" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add", |
|||
"unicode": "\ue6a9" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add-filled", |
|||
"unicode": "\ue6c8" |
|||
}, |
|||
{ |
|||
"font_class": "font", |
|||
"unicode": "\ue6a3" |
|||
}, |
|||
{ |
|||
"font_class": "forward", |
|||
"unicode": "\ue6ba" |
|||
}, |
|||
{ |
|||
"font_class": "gear", |
|||
"unicode": "\ue664" |
|||
}, |
|||
{ |
|||
"font_class": "gear-filled", |
|||
"unicode": "\ue661" |
|||
}, |
|||
{ |
|||
"font_class": "gift", |
|||
"unicode": "\ue6a4" |
|||
}, |
|||
{ |
|||
"font_class": "gift-filled", |
|||
"unicode": "\ue6c4" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down", |
|||
"unicode": "\ue63d" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down-filled", |
|||
"unicode": "\ue63c" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up", |
|||
"unicode": "\ue63f" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up-filled", |
|||
"unicode": "\ue63e" |
|||
}, |
|||
{ |
|||
"font_class": "headphones", |
|||
"unicode": "\ue630" |
|||
}, |
|||
{ |
|||
"font_class": "heart", |
|||
"unicode": "\ue639" |
|||
}, |
|||
{ |
|||
"font_class": "heart-filled", |
|||
"unicode": "\ue641" |
|||
}, |
|||
{ |
|||
"font_class": "help", |
|||
"unicode": "\ue679" |
|||
}, |
|||
{ |
|||
"font_class": "help-filled", |
|||
"unicode": "\ue674" |
|||
}, |
|||
{ |
|||
"font_class": "home", |
|||
"unicode": "\ue662" |
|||
}, |
|||
{ |
|||
"font_class": "home-filled", |
|||
"unicode": "\ue663" |
|||
}, |
|||
{ |
|||
"font_class": "image", |
|||
"unicode": "\ue670" |
|||
}, |
|||
{ |
|||
"font_class": "image-filled", |
|||
"unicode": "\ue678" |
|||
}, |
|||
{ |
|||
"font_class": "images", |
|||
"unicode": "\ue650" |
|||
}, |
|||
{ |
|||
"font_class": "images-filled", |
|||
"unicode": "\ue64b" |
|||
}, |
|||
{ |
|||
"font_class": "info", |
|||
"unicode": "\ue669" |
|||
}, |
|||
{ |
|||
"font_class": "info-filled", |
|||
"unicode": "\ue649" |
|||
}, |
|||
{ |
|||
"font_class": "left", |
|||
"unicode": "\ue6b7" |
|||
}, |
|||
{ |
|||
"font_class": "link", |
|||
"unicode": "\ue6a5" |
|||
}, |
|||
{ |
|||
"font_class": "list", |
|||
"unicode": "\ue644" |
|||
}, |
|||
{ |
|||
"font_class": "location", |
|||
"unicode": "\ue6ae" |
|||
}, |
|||
{ |
|||
"font_class": "location-filled", |
|||
"unicode": "\ue6af" |
|||
}, |
|||
{ |
|||
"font_class": "locked", |
|||
"unicode": "\ue66b" |
|||
}, |
|||
{ |
|||
"font_class": "locked-filled", |
|||
"unicode": "\ue668" |
|||
}, |
|||
{ |
|||
"font_class": "loop", |
|||
"unicode": "\ue633" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open", |
|||
"unicode": "\ue643" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open-filled", |
|||
"unicode": "\ue63a" |
|||
}, |
|||
{ |
|||
"font_class": "map", |
|||
"unicode": "\ue667" |
|||
}, |
|||
{ |
|||
"font_class": "map-filled", |
|||
"unicode": "\ue666" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin", |
|||
"unicode": "\ue6ad" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin-ellipse", |
|||
"unicode": "\ue6ac" |
|||
}, |
|||
{ |
|||
"font_class": "medal", |
|||
"unicode": "\ue6a2" |
|||
}, |
|||
{ |
|||
"font_class": "medal-filled", |
|||
"unicode": "\ue6c3" |
|||
}, |
|||
{ |
|||
"font_class": "mic", |
|||
"unicode": "\ue671" |
|||
}, |
|||
{ |
|||
"font_class": "mic-filled", |
|||
"unicode": "\ue677" |
|||
}, |
|||
{ |
|||
"font_class": "micoff", |
|||
"unicode": "\ue67e" |
|||
}, |
|||
{ |
|||
"font_class": "micoff-filled", |
|||
"unicode": "\ue6b0" |
|||
}, |
|||
{ |
|||
"font_class": "minus", |
|||
"unicode": "\ue66f" |
|||
}, |
|||
{ |
|||
"font_class": "minus-filled", |
|||
"unicode": "\ue67d" |
|||
}, |
|||
{ |
|||
"font_class": "more", |
|||
"unicode": "\ue64d" |
|||
}, |
|||
{ |
|||
"font_class": "more-filled", |
|||
"unicode": "\ue64e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate", |
|||
"unicode": "\ue66e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate-filled", |
|||
"unicode": "\ue67a" |
|||
}, |
|||
{ |
|||
"font_class": "notification", |
|||
"unicode": "\ue6a6" |
|||
}, |
|||
{ |
|||
"font_class": "notification-filled", |
|||
"unicode": "\ue6c1" |
|||
}, |
|||
{ |
|||
"font_class": "paperclip", |
|||
"unicode": "\ue652" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane", |
|||
"unicode": "\ue672" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane-filled", |
|||
"unicode": "\ue675" |
|||
}, |
|||
{ |
|||
"font_class": "person", |
|||
"unicode": "\ue699" |
|||
}, |
|||
{ |
|||
"font_class": "person-filled", |
|||
"unicode": "\ue69d" |
|||
}, |
|||
{ |
|||
"font_class": "personadd", |
|||
"unicode": "\ue69f" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled", |
|||
"unicode": "\ue698" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled-copy", |
|||
"unicode": "\ue6d1" |
|||
}, |
|||
{ |
|||
"font_class": "phone", |
|||
"unicode": "\ue69c" |
|||
}, |
|||
{ |
|||
"font_class": "phone-filled", |
|||
"unicode": "\ue69b" |
|||
}, |
|||
{ |
|||
"font_class": "plus", |
|||
"unicode": "\ue676" |
|||
}, |
|||
{ |
|||
"font_class": "plus-filled", |
|||
"unicode": "\ue6c7" |
|||
}, |
|||
{ |
|||
"font_class": "plusempty", |
|||
"unicode": "\ue67b" |
|||
}, |
|||
{ |
|||
"font_class": "pulldown", |
|||
"unicode": "\ue632" |
|||
}, |
|||
{ |
|||
"font_class": "pyq", |
|||
"unicode": "\ue682" |
|||
}, |
|||
{ |
|||
"font_class": "qq", |
|||
"unicode": "\ue680" |
|||
}, |
|||
{ |
|||
"font_class": "redo", |
|||
"unicode": "\ue64a" |
|||
}, |
|||
{ |
|||
"font_class": "redo-filled", |
|||
"unicode": "\ue655" |
|||
}, |
|||
{ |
|||
"font_class": "refresh", |
|||
"unicode": "\ue657" |
|||
}, |
|||
{ |
|||
"font_class": "refresh-filled", |
|||
"unicode": "\ue656" |
|||
}, |
|||
{ |
|||
"font_class": "refreshempty", |
|||
"unicode": "\ue6bf" |
|||
}, |
|||
{ |
|||
"font_class": "reload", |
|||
"unicode": "\ue6b2" |
|||
}, |
|||
{ |
|||
"font_class": "right", |
|||
"unicode": "\ue6b5" |
|||
}, |
|||
{ |
|||
"font_class": "scan", |
|||
"unicode": "\ue62a" |
|||
}, |
|||
{ |
|||
"font_class": "search", |
|||
"unicode": "\ue654" |
|||
}, |
|||
{ |
|||
"font_class": "settings", |
|||
"unicode": "\ue653" |
|||
}, |
|||
{ |
|||
"font_class": "settings-filled", |
|||
"unicode": "\ue6ce" |
|||
}, |
|||
{ |
|||
"font_class": "shop", |
|||
"unicode": "\ue62f" |
|||
}, |
|||
{ |
|||
"font_class": "shop-filled", |
|||
"unicode": "\ue6cd" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle", |
|||
"unicode": "\ue67c" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle-filled", |
|||
"unicode": "\ue665" |
|||
}, |
|||
{ |
|||
"font_class": "sound", |
|||
"unicode": "\ue684" |
|||
}, |
|||
{ |
|||
"font_class": "sound-filled", |
|||
"unicode": "\ue686" |
|||
}, |
|||
{ |
|||
"font_class": "spinner-cycle", |
|||
"unicode": "\ue68a" |
|||
}, |
|||
{ |
|||
"font_class": "staff", |
|||
"unicode": "\ue6a7" |
|||
}, |
|||
{ |
|||
"font_class": "staff-filled", |
|||
"unicode": "\ue6cb" |
|||
}, |
|||
{ |
|||
"font_class": "star", |
|||
"unicode": "\ue688" |
|||
}, |
|||
{ |
|||
"font_class": "star-filled", |
|||
"unicode": "\ue68f" |
|||
}, |
|||
{ |
|||
"font_class": "starhalf", |
|||
"unicode": "\ue683" |
|||
}, |
|||
{ |
|||
"font_class": "trash", |
|||
"unicode": "\ue687" |
|||
}, |
|||
{ |
|||
"font_class": "trash-filled", |
|||
"unicode": "\ue685" |
|||
}, |
|||
{ |
|||
"font_class": "tune", |
|||
"unicode": "\ue6aa" |
|||
}, |
|||
{ |
|||
"font_class": "tune-filled", |
|||
"unicode": "\ue6ca" |
|||
}, |
|||
{ |
|||
"font_class": "undo", |
|||
"unicode": "\ue64f" |
|||
}, |
|||
{ |
|||
"font_class": "undo-filled", |
|||
"unicode": "\ue64c" |
|||
}, |
|||
{ |
|||
"font_class": "up", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "top", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "upload", |
|||
"unicode": "\ue690" |
|||
}, |
|||
{ |
|||
"font_class": "upload-filled", |
|||
"unicode": "\ue68e" |
|||
}, |
|||
{ |
|||
"font_class": "videocam", |
|||
"unicode": "\ue68c" |
|||
}, |
|||
{ |
|||
"font_class": "videocam-filled", |
|||
"unicode": "\ue689" |
|||
}, |
|||
{ |
|||
"font_class": "vip", |
|||
"unicode": "\ue6a8" |
|||
}, |
|||
{ |
|||
"font_class": "vip-filled", |
|||
"unicode": "\ue6c6" |
|||
}, |
|||
{ |
|||
"font_class": "wallet", |
|||
"unicode": "\ue6b1" |
|||
}, |
|||
{ |
|||
"font_class": "wallet-filled", |
|||
"unicode": "\ue6c2" |
|||
}, |
|||
{ |
|||
"font_class": "weibo", |
|||
"unicode": "\ue68b" |
|||
}, |
|||
{ |
|||
"font_class": "weixin", |
|||
"unicode": "\ue691" |
|||
} |
|||
] |
|||
|
|||
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
@ -0,0 +1,89 @@ |
|||
{ |
|||
"id": "uni-icons", |
|||
"displayName": "uni-icons 图标", |
|||
"version": "2.0.10", |
|||
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。", |
|||
"keywords": [ |
|||
"uni-ui", |
|||
"uniui", |
|||
"icon", |
|||
"图标" |
|||
], |
|||
"repository": "https://github.com/dcloudio/uni-ui", |
|||
"engines": { |
|||
"HBuilderX": "^3.2.14" |
|||
}, |
|||
"directories": { |
|||
"example": "../../temps/example_temps" |
|||
}, |
|||
"dcloudext": { |
|||
"sale": { |
|||
"regular": { |
|||
"price": "0.00" |
|||
}, |
|||
"sourcecode": { |
|||
"price": "0.00" |
|||
} |
|||
}, |
|||
"contact": { |
|||
"qq": "" |
|||
}, |
|||
"declaration": { |
|||
"ads": "无", |
|||
"data": "无", |
|||
"permissions": "无" |
|||
}, |
|||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
|||
"type": "component-vue" |
|||
}, |
|||
"uni_modules": { |
|||
"dependencies": ["uni-scss"], |
|||
"encrypt": [], |
|||
"platforms": { |
|||
"cloud": { |
|||
"tcb": "y", |
|||
"aliyun": "y", |
|||
"alipay": "n" |
|||
}, |
|||
"client": { |
|||
"App": { |
|||
"app-vue": "y", |
|||
"app-nvue": "y", |
|||
"app-uvue": "y" |
|||
}, |
|||
"H5-mobile": { |
|||
"Safari": "y", |
|||
"Android Browser": "y", |
|||
"微信浏览器(Android)": "y", |
|||
"QQ浏览器(Android)": "y" |
|||
}, |
|||
"H5-pc": { |
|||
"Chrome": "y", |
|||
"IE": "y", |
|||
"Edge": "y", |
|||
"Firefox": "y", |
|||
"Safari": "y" |
|||
}, |
|||
"小程序": { |
|||
"微信": "y", |
|||
"阿里": "y", |
|||
"百度": "y", |
|||
"字节跳动": "y", |
|||
"QQ": "y", |
|||
"钉钉": "y", |
|||
"快手": "y", |
|||
"飞书": "y", |
|||
"京东": "y" |
|||
}, |
|||
"快应用": { |
|||
"华为": "y", |
|||
"联盟": "y" |
|||
}, |
|||
"Vue": { |
|||
"vue2": "y", |
|||
"vue3": "y" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
## Icons 图标 |
|||
> **组件名:uni-icons** |
|||
> 代码块: `uIcons` |
|||
|
|||
用于展示 icons 图标 。 |
|||
|
|||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons) |
|||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
@ -0,0 +1,8 @@ |
|||
## 1.0.3(2022-01-21) |
|||
- 优化 组件示例 |
|||
## 1.0.2(2021-11-22) |
|||
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题 |
|||
## 1.0.1(2021-11-22) |
|||
- 修复 vue3中scss语法兼容问题 |
|||
## 1.0.0(2021-11-18) |
|||
- init |
@ -0,0 +1 @@ |
|||
@import './styles/index.scss'; |
@ -0,0 +1,82 @@ |
|||
{ |
|||
"id": "uni-scss", |
|||
"displayName": "uni-scss 辅助样式", |
|||
"version": "1.0.3", |
|||
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。", |
|||
"keywords": [ |
|||
"uni-scss", |
|||
"uni-ui", |
|||
"辅助样式" |
|||
], |
|||
"repository": "https://github.com/dcloudio/uni-ui", |
|||
"engines": { |
|||
"HBuilderX": "^3.1.0" |
|||
}, |
|||
"dcloudext": { |
|||
"category": [ |
|||
"JS SDK", |
|||
"通用 SDK" |
|||
], |
|||
"sale": { |
|||
"regular": { |
|||
"price": "0.00" |
|||
}, |
|||
"sourcecode": { |
|||
"price": "0.00" |
|||
} |
|||
}, |
|||
"contact": { |
|||
"qq": "" |
|||
}, |
|||
"declaration": { |
|||
"ads": "无", |
|||
"data": "无", |
|||
"permissions": "无" |
|||
}, |
|||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" |
|||
}, |
|||
"uni_modules": { |
|||
"dependencies": [], |
|||
"encrypt": [], |
|||
"platforms": { |
|||
"cloud": { |
|||
"tcb": "y", |
|||
"aliyun": "y" |
|||
}, |
|||
"client": { |
|||
"App": { |
|||
"app-vue": "y", |
|||
"app-nvue": "u" |
|||
}, |
|||
"H5-mobile": { |
|||
"Safari": "y", |
|||
"Android Browser": "y", |
|||
"微信浏览器(Android)": "y", |
|||
"QQ浏览器(Android)": "y" |
|||
}, |
|||
"H5-pc": { |
|||
"Chrome": "y", |
|||
"IE": "y", |
|||
"Edge": "y", |
|||
"Firefox": "y", |
|||
"Safari": "y" |
|||
}, |
|||
"小程序": { |
|||
"微信": "y", |
|||
"阿里": "y", |
|||
"百度": "y", |
|||
"字节跳动": "y", |
|||
"QQ": "y" |
|||
}, |
|||
"快应用": { |
|||
"华为": "n", |
|||
"联盟": "n" |
|||
}, |
|||
"Vue": { |
|||
"vue2": "y", |
|||
"vue3": "y" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,4 @@ |
|||
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。 |
|||
|
|||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass) |
|||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
@ -0,0 +1,7 @@ |
|||
@import './setting/_variables.scss'; |
|||
@import './setting/_border.scss'; |
|||
@import './setting/_color.scss'; |
|||
@import './setting/_space.scss'; |
|||
@import './setting/_radius.scss'; |
|||
@import './setting/_text.scss'; |
|||
@import './setting/_styles.scss'; |
@ -0,0 +1,3 @@ |
|||
.uni-border { |
|||
border: 1px $uni-border-1 solid; |
|||
} |
@ -0,0 +1,66 @@ |
|||
|
|||
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐 |
|||
// @mixin get-styles($k,$c) { |
|||
// @if $k == size or $k == weight{ |
|||
// font-#{$k}:#{$c} |
|||
// }@else{ |
|||
// #{$k}:#{$c} |
|||
// } |
|||
// } |
|||
$uni-ui-color:( |
|||
// 主色 |
|||
primary: $uni-primary, |
|||
primary-disable: $uni-primary-disable, |
|||
primary-light: $uni-primary-light, |
|||
// 辅助色 |
|||
success: $uni-success, |
|||
success-disable: $uni-success-disable, |
|||
success-light: $uni-success-light, |
|||
warning: $uni-warning, |
|||
warning-disable: $uni-warning-disable, |
|||
warning-light: $uni-warning-light, |
|||
error: $uni-error, |
|||
error-disable: $uni-error-disable, |
|||
error-light: $uni-error-light, |
|||
info: $uni-info, |
|||
info-disable: $uni-info-disable, |
|||
info-light: $uni-info-light, |
|||
// 中性色 |
|||
main-color: $uni-main-color, |
|||
base-color: $uni-base-color, |
|||
secondary-color: $uni-secondary-color, |
|||
extra-color: $uni-extra-color, |
|||
// 背景色 |
|||
bg-color: $uni-bg-color, |
|||
// 边框颜色 |
|||
border-1: $uni-border-1, |
|||
border-2: $uni-border-2, |
|||
border-3: $uni-border-3, |
|||
border-4: $uni-border-4, |
|||
// 黑色 |
|||
black:$uni-black, |
|||
// 白色 |
|||
white:$uni-white, |
|||
// 透明 |
|||
transparent:$uni-transparent |
|||
) !default; |
|||
@each $key, $child in $uni-ui-color { |
|||
.uni-#{"" + $key} { |
|||
color: $child; |
|||
} |
|||
.uni-#{"" + $key}-bg { |
|||
background-color: $child; |
|||
} |
|||
} |
|||
.uni-shadow-sm { |
|||
box-shadow: $uni-shadow-sm; |
|||
} |
|||
.uni-shadow-base { |
|||
box-shadow: $uni-shadow-base; |
|||
} |
|||
.uni-shadow-lg { |
|||
box-shadow: $uni-shadow-lg; |
|||
} |
|||
.uni-mask { |
|||
background-color:$uni-mask; |
|||
} |
@ -0,0 +1,55 @@ |
|||
@mixin radius($r,$d:null ,$important: false){ |
|||
$radius-value:map-get($uni-radius, $r) if($important, !important, null); |
|||
// Key exists within the $uni-radius variable |
|||
@if (map-has-key($uni-radius, $r) and $d){ |
|||
@if $d == t { |
|||
border-top-left-radius:$radius-value; |
|||
border-top-right-radius:$radius-value; |
|||
}@else if $d == r { |
|||
border-top-right-radius:$radius-value; |
|||
border-bottom-right-radius:$radius-value; |
|||
}@else if $d == b { |
|||
border-bottom-left-radius:$radius-value; |
|||
border-bottom-right-radius:$radius-value; |
|||
}@else if $d == l { |
|||
border-top-left-radius:$radius-value; |
|||
border-bottom-left-radius:$radius-value; |
|||
}@else if $d == tl { |
|||
border-top-left-radius:$radius-value; |
|||
}@else if $d == tr { |
|||
border-top-right-radius:$radius-value; |
|||
}@else if $d == br { |
|||
border-bottom-right-radius:$radius-value; |
|||
}@else if $d == bl { |
|||
border-bottom-left-radius:$radius-value; |
|||
} |
|||
}@else{ |
|||
border-radius:$radius-value; |
|||
} |
|||
} |
|||
|
|||
@each $key, $child in $uni-radius { |
|||
@if($key){ |
|||
.uni-radius-#{"" + $key} { |
|||
@include radius($key) |
|||
} |
|||
}@else{ |
|||
.uni-radius { |
|||
@include radius($key) |
|||
} |
|||
} |
|||
} |
|||
|
|||
@each $direction in t, r, b, l,tl, tr, br, bl { |
|||
@each $key, $child in $uni-radius { |
|||
@if($key){ |
|||
.uni-radius-#{"" + $direction}-#{"" + $key} { |
|||
@include radius($key,$direction,false) |
|||
} |
|||
}@else{ |
|||
.uni-radius-#{$direction} { |
|||
@include radius($key,$direction,false) |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
|
|||
@mixin fn($space,$direction,$size,$n) { |
|||
@if $n { |
|||
#{$space}-#{$direction}: #{$size*$uni-space-root}px |
|||
} @else { |
|||
#{$space}-#{$direction}: #{-$size*$uni-space-root}px |
|||
} |
|||
} |
|||
@mixin get-styles($direction,$i,$space,$n){ |
|||
@if $direction == t { |
|||
@include fn($space, top,$i,$n); |
|||
} |
|||
@if $direction == r { |
|||
@include fn($space, right,$i,$n); |
|||
} |
|||
@if $direction == b { |
|||
@include fn($space, bottom,$i,$n); |
|||
} |
|||
@if $direction == l { |
|||
@include fn($space, left,$i,$n); |
|||
} |
|||
@if $direction == x { |
|||
@include fn($space, left,$i,$n); |
|||
@include fn($space, right,$i,$n); |
|||
} |
|||
@if $direction == y { |
|||
@include fn($space, top,$i,$n); |
|||
@include fn($space, bottom,$i,$n); |
|||
} |
|||
@if $direction == a { |
|||
@if $n { |
|||
#{$space}:#{$i*$uni-space-root}px; |
|||
} @else { |
|||
#{$space}:#{-$i*$uni-space-root}px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@each $orientation in m,p { |
|||
$space: margin; |
|||
@if $orientation == m { |
|||
$space: margin; |
|||
} @else { |
|||
$space: padding; |
|||
} |
|||
@for $i from 0 through 16 { |
|||
@each $direction in t, r, b, l, x, y, a { |
|||
.uni-#{$orientation}#{$direction}-#{$i} { |
|||
@include get-styles($direction,$i,$space,true); |
|||
} |
|||
.uni-#{$orientation}#{$direction}-n#{$i} { |
|||
@include get-styles($direction,$i,$space,false); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,167 @@ |
|||
/* #ifndef APP-NVUE */ |
|||
|
|||
$-color-white:#fff; |
|||
$-color-black:#000; |
|||
@mixin base-style($color) { |
|||
color: #fff; |
|||
background-color: $color; |
|||
border-color: mix($-color-black, $color, 8%); |
|||
&:not([hover-class]):active { |
|||
background: mix($-color-black, $color, 10%); |
|||
border-color: mix($-color-black, $color, 20%); |
|||
color: $-color-white; |
|||
outline: none; |
|||
} |
|||
} |
|||
@mixin is-color($color) { |
|||
@include base-style($color); |
|||
&[loading] { |
|||
@include base-style($color); |
|||
&::before { |
|||
margin-right:5px; |
|||
} |
|||
} |
|||
&[disabled] { |
|||
&, |
|||
&[loading], |
|||
&:not([hover-class]):active { |
|||
color: $-color-white; |
|||
border-color: mix(darken($color,10%), $-color-white); |
|||
background-color: mix($color, $-color-white); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@mixin base-plain-style($color) { |
|||
color:$color; |
|||
background-color: mix($-color-white, $color, 90%); |
|||
border-color: mix($-color-white, $color, 70%); |
|||
&:not([hover-class]):active { |
|||
background: mix($-color-white, $color, 80%); |
|||
color: $color; |
|||
outline: none; |
|||
border-color: mix($-color-white, $color, 50%); |
|||
} |
|||
} |
|||
@mixin is-plain($color){ |
|||
&[plain] { |
|||
@include base-plain-style($color); |
|||
&[loading] { |
|||
@include base-plain-style($color); |
|||
&::before { |
|||
margin-right:5px; |
|||
} |
|||
} |
|||
&[disabled] { |
|||
&, |
|||
&:active { |
|||
color: mix($-color-white, $color, 40%); |
|||
background-color: mix($-color-white, $color, 90%); |
|||
border-color: mix($-color-white, $color, 80%); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
.uni-btn { |
|||
margin: 5px; |
|||
color: #393939; |
|||
border:1px solid #ccc; |
|||
font-size: 16px; |
|||
font-weight: 200; |
|||
background-color: #F9F9F9; |
|||
// TODO 暂时处理边框隐藏一边的问题 |
|||
overflow: visible; |
|||
&::after{ |
|||
border: none; |
|||
} |
|||
|
|||
&:not([type]),&[type=default] { |
|||
color: #999; |
|||
&[loading] { |
|||
background: none; |
|||
&::before { |
|||
margin-right:5px; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
&[disabled]{ |
|||
color: mix($-color-white, #999, 60%); |
|||
&, |
|||
&[loading], |
|||
&:active { |
|||
color: mix($-color-white, #999, 60%); |
|||
background-color: mix($-color-white,$-color-black , 98%); |
|||
border-color: mix($-color-white, #999, 85%); |
|||
} |
|||
} |
|||
|
|||
&[plain] { |
|||
color: #999; |
|||
background: none; |
|||
border-color: $uni-border-1; |
|||
&:not([hover-class]):active { |
|||
background: none; |
|||
color: mix($-color-white, $-color-black, 80%); |
|||
border-color: mix($-color-white, $-color-black, 90%); |
|||
outline: none; |
|||
} |
|||
&[disabled]{ |
|||
&, |
|||
&[loading], |
|||
&:active { |
|||
background: none; |
|||
color: mix($-color-white, #999, 60%); |
|||
border-color: mix($-color-white, #999, 85%); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
&:not([hover-class]):active { |
|||
color: mix($-color-white, $-color-black, 50%); |
|||
} |
|||
|
|||
&[size=mini] { |
|||
font-size: 16px; |
|||
font-weight: 200; |
|||
border-radius: 8px; |
|||
} |
|||
|
|||
|
|||
|
|||
&.uni-btn-small { |
|||
font-size: 14px; |
|||
} |
|||
&.uni-btn-mini { |
|||
font-size: 12px; |
|||
} |
|||
|
|||
&.uni-btn-radius { |
|||
border-radius: 999px; |
|||
} |
|||
&[type=primary] { |
|||
@include is-color($uni-primary); |
|||
@include is-plain($uni-primary) |
|||
} |
|||
&[type=success] { |
|||
@include is-color($uni-success); |
|||
@include is-plain($uni-success) |
|||
} |
|||
&[type=error] { |
|||
@include is-color($uni-error); |
|||
@include is-plain($uni-error) |
|||
} |
|||
&[type=warning] { |
|||
@include is-color($uni-warning); |
|||
@include is-plain($uni-warning) |
|||
} |
|||
&[type=info] { |
|||
@include is-color($uni-info); |
|||
@include is-plain($uni-info) |
|||
} |
|||
} |
|||
/* #endif */ |
@ -0,0 +1,24 @@ |
|||
@mixin get-styles($k,$c) { |
|||
@if $k == size or $k == weight{ |
|||
font-#{$k}:#{$c} |
|||
}@else{ |
|||
#{$k}:#{$c} |
|||
} |
|||
} |
|||
|
|||
@each $key, $child in $uni-headings { |
|||
/* #ifndef APP-NVUE */ |
|||
.uni-#{$key} { |
|||
@each $k, $c in $child { |
|||
@include get-styles($k,$c) |
|||
} |
|||
} |
|||
/* #endif */ |
|||
/* #ifdef APP-NVUE */ |
|||
.container .uni-#{$key} { |
|||
@each $k, $c in $child { |
|||
@include get-styles($k,$c) |
|||
} |
|||
} |
|||
/* #endif */ |
|||
} |
@ -0,0 +1,146 @@ |
|||
// @use "sass:math"; |
|||
@import '../tools/functions.scss'; |
|||
// 间距基础倍数 |
|||
$uni-space-root: 2 !default; |
|||
// 边框半径默认值 |
|||
$uni-radius-root:5px !default; |
|||
$uni-radius: () !default; |
|||
// 边框半径断点 |
|||
$uni-radius: map-deep-merge( |
|||
( |
|||
0: 0, |
|||
// TODO 当前版本暂时不支持 sm 属性 |
|||
// 'sm': math.div($uni-radius-root, 2), |
|||
null: $uni-radius-root, |
|||
'lg': $uni-radius-root * 2, |
|||
'xl': $uni-radius-root * 6, |
|||
'pill': 9999px, |
|||
'circle': 50% |
|||
), |
|||
$uni-radius |
|||
); |
|||
// 字体家族 |
|||
$body-font-family: 'Roboto', sans-serif !default; |
|||
// 文本 |
|||
$heading-font-family: $body-font-family !default; |
|||
$uni-headings: () !default; |
|||
$letterSpacing: -0.01562em; |
|||
$uni-headings: map-deep-merge( |
|||
( |
|||
'h1': ( |
|||
size: 32px, |
|||
weight: 300, |
|||
line-height: 50px, |
|||
// letter-spacing:-0.01562em |
|||
), |
|||
'h2': ( |
|||
size: 28px, |
|||
weight: 300, |
|||
line-height: 40px, |
|||
// letter-spacing: -0.00833em |
|||
), |
|||
'h3': ( |
|||
size: 24px, |
|||
weight: 400, |
|||
line-height: 32px, |
|||
// letter-spacing: normal |
|||
), |
|||
'h4': ( |
|||
size: 20px, |
|||
weight: 400, |
|||
line-height: 30px, |
|||
// letter-spacing: 0.00735em |
|||
), |
|||
'h5': ( |
|||
size: 16px, |
|||
weight: 400, |
|||
line-height: 24px, |
|||
// letter-spacing: normal |
|||
), |
|||
'h6': ( |
|||
size: 14px, |
|||
weight: 500, |
|||
line-height: 18px, |
|||
// letter-spacing: 0.0125em |
|||
), |
|||
'subtitle': ( |
|||
size: 12px, |
|||
weight: 400, |
|||
line-height: 20px, |
|||
// letter-spacing: 0.00937em |
|||
), |
|||
'body': ( |
|||
font-size: 14px, |
|||
font-weight: 400, |
|||
line-height: 22px, |
|||
// letter-spacing: 0.03125em |
|||
), |
|||
'caption': ( |
|||
'size': 12px, |
|||
'weight': 400, |
|||
'line-height': 20px, |
|||
// 'letter-spacing': 0.03333em, |
|||
// 'text-transform': false |
|||
) |
|||
), |
|||
$uni-headings |
|||
); |
|||
|
|||
|
|||
|
|||
// 主色 |
|||
$uni-primary: #2979ff !default; |
|||
$uni-primary-disable:lighten($uni-primary,20%) !default; |
|||
$uni-primary-light: lighten($uni-primary,25%) !default; |
|||
|
|||
// 辅助色 |
|||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 |
|||
$uni-success: #18bc37 !default; |
|||
$uni-success-disable:lighten($uni-success,20%) !default; |
|||
$uni-success-light: lighten($uni-success,25%) !default; |
|||
|
|||
$uni-warning: #f3a73f !default; |
|||
$uni-warning-disable:lighten($uni-warning,20%) !default; |
|||
$uni-warning-light: lighten($uni-warning,25%) !default; |
|||
|
|||
$uni-error: #e43d33 !default; |
|||
$uni-error-disable:lighten($uni-error,20%) !default; |
|||
$uni-error-light: lighten($uni-error,25%) !default; |
|||
|
|||
$uni-info: #8f939c !default; |
|||
$uni-info-disable:lighten($uni-info,20%) !default; |
|||
$uni-info-light: lighten($uni-info,25%) !default; |
|||
|
|||
// 中性色 |
|||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 |
|||
$uni-main-color: #3a3a3a !default; // 主要文字 |
|||
$uni-base-color: #6a6a6a !default; // 常规文字 |
|||
$uni-secondary-color: #909399 !default; // 次要文字 |
|||
$uni-extra-color: #c7c7c7 !default; // 辅助说明 |
|||
|
|||
// 边框颜色 |
|||
$uni-border-1: #F0F0F0 !default; |
|||
$uni-border-2: #EDEDED !default; |
|||
$uni-border-3: #DCDCDC !default; |
|||
$uni-border-4: #B9B9B9 !default; |
|||
|
|||
// 常规色 |
|||
$uni-black: #000000 !default; |
|||
$uni-white: #ffffff !default; |
|||
$uni-transparent: rgba($color: #000000, $alpha: 0) !default; |
|||
|
|||
// 背景色 |
|||
$uni-bg-color: #f7f7f7 !default; |
|||
|
|||
/* 水平间距 */ |
|||
$uni-spacing-sm: 8px !default; |
|||
$uni-spacing-base: 15px !default; |
|||
$uni-spacing-lg: 30px !default; |
|||
|
|||
// 阴影 |
|||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default; |
|||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default; |
|||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default; |
|||
|
|||
// 蒙版 |
|||
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default; |
@ -0,0 +1,19 @@ |
|||
// 合并 map |
|||
@function map-deep-merge($parent-map, $child-map){ |
|||
$result: $parent-map; |
|||
@each $key, $child in $child-map { |
|||
$parent-has-key: map-has-key($result, $key); |
|||
$parent-value: map-get($result, $key); |
|||
$parent-type: type-of($parent-value); |
|||
$child-type: type-of($child); |
|||
$parent-is-map: $parent-type == map; |
|||
$child-is-map: $child-type == map; |
|||
|
|||
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){ |
|||
$result: map-merge($result, ( $key: $child )); |
|||
}@else { |
|||
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) )); |
|||
} |
|||
} |
|||
@return $result; |
|||
}; |
@ -0,0 +1,31 @@ |
|||
// 间距基础倍数 |
|||
$uni-space-root: 2; |
|||
// 边框半径默认值 |
|||
$uni-radius-root:5px; |
|||
// 主色 |
|||
$uni-primary: #2979ff; |
|||
// 辅助色 |
|||
$uni-success: #4cd964; |
|||
// 警告色 |
|||
$uni-warning: #f0ad4e; |
|||
// 错误色 |
|||
$uni-error: #dd524d; |
|||
// 描述色 |
|||
$uni-info: #909399; |
|||
// 中性色 |
|||
$uni-main-color: #303133; |
|||
$uni-base-color: #606266; |
|||
$uni-secondary-color: #909399; |
|||
$uni-extra-color: #C0C4CC; |
|||
// 背景色 |
|||
$uni-bg-color: #f5f5f5; |
|||
// 边框颜色 |
|||
$uni-border-1: #DCDFE6; |
|||
$uni-border-2: #E4E7ED; |
|||
$uni-border-3: #EBEEF5; |
|||
$uni-border-4: #F2F6FC; |
|||
|
|||
// 常规色 |
|||
$uni-black: #000000; |
|||
$uni-white: #ffffff; |
|||
$uni-transparent: rgba($color: #000000, $alpha: 0); |
@ -0,0 +1,62 @@ |
|||
@import './styles/setting/_variables.scss'; |
|||
// 间距基础倍数 |
|||
$uni-space-root: 2; |
|||
// 边框半径默认值 |
|||
$uni-radius-root:5px; |
|||
|
|||
// 主色 |
|||
$uni-primary: #2979ff; |
|||
$uni-primary-disable:mix(#fff,$uni-primary,50%); |
|||
$uni-primary-light: mix(#fff,$uni-primary,80%); |
|||
|
|||
// 辅助色 |
|||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 |
|||
$uni-success: #18bc37; |
|||
$uni-success-disable:mix(#fff,$uni-success,50%); |
|||
$uni-success-light: mix(#fff,$uni-success,80%); |
|||
|
|||
$uni-warning: #f3a73f; |
|||
$uni-warning-disable:mix(#fff,$uni-warning,50%); |
|||
$uni-warning-light: mix(#fff,$uni-warning,80%); |
|||
|
|||
$uni-error: #e43d33; |
|||
$uni-error-disable:mix(#fff,$uni-error,50%); |
|||
$uni-error-light: mix(#fff,$uni-error,80%); |
|||
|
|||
$uni-info: #8f939c; |
|||
$uni-info-disable:mix(#fff,$uni-info,50%); |
|||
$uni-info-light: mix(#fff,$uni-info,80%); |
|||
|
|||
// 中性色 |
|||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 |
|||
$uni-main-color: #3a3a3a; // 主要文字 |
|||
$uni-base-color: #6a6a6a; // 常规文字 |
|||
$uni-secondary-color: #909399; // 次要文字 |
|||
$uni-extra-color: #c7c7c7; // 辅助说明 |
|||
|
|||
// 边框颜色 |
|||
$uni-border-1: #F0F0F0; |
|||
$uni-border-2: #EDEDED; |
|||
$uni-border-3: #DCDCDC; |
|||
$uni-border-4: #B9B9B9; |
|||
|
|||
// 常规色 |
|||
$uni-black: #000000; |
|||
$uni-white: #ffffff; |
|||
$uni-transparent: rgba($color: #000000, $alpha: 0); |
|||
|
|||
// 背景色 |
|||
$uni-bg-color: #f7f7f7; |
|||
|
|||
/* 水平间距 */ |
|||
$uni-spacing-sm: 8px; |
|||
$uni-spacing-base: 15px; |
|||
$uni-spacing-lg: 30px; |
|||
|
|||
// 阴影 |
|||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5); |
|||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2); |
|||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5); |
|||
|
|||
// 蒙版 |
|||
$uni-mask: rgba($color: #000000, $alpha: 0.4); |
@ -0,0 +1,40 @@ |
|||
## 1.1.9(2025-03-27) |
|||
示例工程接口配置,改为通过环境变量实现 |
|||
## 1.1.8(2025-03-26) |
|||
上传示例工程 |
|||
## 1.1.7(2025-03-26) |
|||
更新已知问题 |
|||
## 1.1.6(2025-03-25) |
|||
将demo插件使用示例工程上传 |
|||
## 1.1.5(2025-03-18) |
|||
修复已知问题 |
|||
## 1.1.4(2025-03-18) |
|||
聊天页下拉刷新,查看更多历史功能 |
|||
## 1.1.3(2025-03-18) |
|||
优化已知问题 |
|||
## 1.1.2(2025-03-18) |
|||
解决页面组件内部store监听bug,解决问题:发送消息后没有自动滚动到最底部,也没有已读当前人 |
|||
## 1.1.1(2025-03-18) |
|||
更新插件演示程序 |
|||
## 1.1.0(2025-02-26) |
|||
修复已知问题 |
|||
## 1.0.9(2025-02-26) |
|||
修复已知问题 |
|||
## 1.0.8(2025-02-26) |
|||
将demo放在组件中,细节继续调试 |
|||
## 1.0.7(2025-02-26) |
|||
功能还在调试中,敬请期待... |
|||
## 1.0.6(2025-02-21) |
|||
开发中... |
|||
## 1.0.5(2025-02-21) |
|||
开发中... |
|||
## 1.0.4(2025-02-21) |
|||
开发中 |
|||
## 1.0.3(2025-02-21) |
|||
开发中 |
|||
## 1.0.2(2025-02-21) |
|||
开发中 |
|||
## 1.0.1(2025-02-21) |
|||
开发中 |
|||
## 1.0.0(2025-02-21) |
|||
开发中,敬请期待 |
@ -0,0 +1,5 @@ |
|||
<template> |
|||
<view> |
|||
vrapile-im页面组件,此文件不会被引用 |
|||
</view> |
|||
</template> |
@ -0,0 +1,86 @@ |
|||
{ |
|||
"id": "vrapile-im", |
|||
"displayName": "im页面组件", |
|||
"version": "1.1.9", |
|||
"description": "实现WebSocket连接/好友/群组/新消息/历史消息,都是全局配置并本地化存储,已调试兼容H5/微信小程序/安卓App/PC多端同步通讯", |
|||
"keywords": [ |
|||
"IM页面组件,websocket应用" |
|||
], |
|||
"repository": "", |
|||
"engines": { |
|||
"HBuilderX": "^3.94" |
|||
}, |
|||
"dcloudext": { |
|||
"type": "component-vue", |
|||
"sale": { |
|||
"regular": { |
|||
"price": "0.00" |
|||
}, |
|||
"sourcecode": { |
|||
"price": "0.00" |
|||
} |
|||
}, |
|||
"contact": { |
|||
"qq": "" |
|||
}, |
|||
"declaration": { |
|||
"ads": "无", |
|||
"data": "插件不采集任何数据", |
|||
"permissions": "无" |
|||
}, |
|||
"npmurl": "" |
|||
}, |
|||
"uni_modules": { |
|||
"dependencies": [ |
|||
"uni-icons" |
|||
], |
|||
"encrypt": [], |
|||
"platforms": { |
|||
"cloud": { |
|||
"tcb": "y", |
|||
"aliyun": "y", |
|||
"alipay": "y" |
|||
}, |
|||
"client": { |
|||
"Vue": { |
|||
"vue2": "y", |
|||
"vue3": "y" |
|||
}, |
|||
"App": { |
|||
"app-vue": "y", |
|||
"app-nvue": "y", |
|||
"app-uvue": "u", |
|||
"app-harmony": "y" |
|||
}, |
|||
"H5-mobile": { |
|||
"Safari": "y", |
|||
"Android Browser": "y", |
|||
"微信浏览器(Android)": "y", |
|||
"QQ浏览器(Android)": "y" |
|||
}, |
|||
"H5-pc": { |
|||
"Chrome": "y", |
|||
"IE": "y", |
|||
"Edge": "y", |
|||
"Firefox": "y", |
|||
"Safari": "y" |
|||
}, |
|||
"小程序": { |
|||
"微信": "y", |
|||
"阿里": "y", |
|||
"百度": "y", |
|||
"字节跳动": "y", |
|||
"QQ": "y", |
|||
"钉钉": "y", |
|||
"快手": "y", |
|||
"飞书": "y", |
|||
"京东": "y" |
|||
}, |
|||
"快应用": { |
|||
"华为": "y", |
|||
"联盟": "y" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,335 @@ |
|||
<template> |
|||
<view class="nine-content-001"> |
|||
<view class="chat-body"> |
|||
<view class="chat-body-main"> |
|||
<view v-if="chatObject.haveHistory==0" class="chat-body-history"> |
|||
没有更多消息了 |
|||
</view> |
|||
<view v-else class="chat-body-history chat-body-history-have" @click="handleHistoryMessage()"> |
|||
查看更多消息 |
|||
</view> |
|||
<view class="chat-body-message"> |
|||
<view v-for="(item, index) in messageList" :key="index"> |
|||
<view class="chat-conversation" :class="item.fromId == userInfo.userId?'chat-conversation-mine':''"> |
|||
<view class="chat-conversation-image"> |
|||
<image class="chat-conversation-image-image" v-if="item.fromId != userInfo.userId" :src="getUserAvatar(item.fromId, item.avatar)"></image> |
|||
<image class="chat-conversation-image-image" v-else :src="userInfo.avatar || defaultAvatar"></image> |
|||
</view> |
|||
<view class="chat-conversation-text"> |
|||
<view class="chat-conversation-text-time" v-if="item.sendType == 1 && item.fromId != userInfo.userId">{{getUserName(item.fromId, item.fromName)}}</view> |
|||
<view class="chat-conversation-text-time">{{formatTime(item.sendTime)}}</view> |
|||
<view class="chat-conversation-text-text nine-user-select">{{item.content}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="chat-footer"> |
|||
<view class="chat-footer-send"> |
|||
<view @click="handleVoice" class="chat-footer-send-voice"> |
|||
<image class="chat-footer-send-image" :src="iconVoice"></image> |
|||
</view> |
|||
<view v-if="isVoice" @longpress="handleSay" class="chat-footer-send-say"> |
|||
<span>按住 说话</span> |
|||
</view> |
|||
<view v-else class="chat-footer-send-input"> |
|||
<input @confirm="handleSend" class="input" v-model="inputText" /> |
|||
</view> |
|||
<view @click="handleEmoji" class="chat-footer-send-emoji"> |
|||
<image class="chat-footer-send-image" :src="iconEmoji"></image> |
|||
</view> |
|||
<view v-if="inputText" @click="handleSend" class="chat-footer-send-button"> |
|||
<span class="chat-footer-send-button-span">发送</span> |
|||
</view> |
|||
<view v-else @click="handleMore" class="chat-footer-send-more"> |
|||
<image class="chat-footer-send-image" :src="iconMore"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState } from 'vuex' |
|||
import store from '@/uni_modules/vrapile-im/store' |
|||
import { getChatKey } from '@/uni_modules/vrapile-im/utils/tiosocket'; |
|||
// 外部需提供store用于获取用户信息,提供根据消息key查询用户历史消息接口 |
|||
import storeOut from '@/store' |
|||
import { getMessageByChatKey } from '@/api/chat' |
|||
export default { |
|||
data() { |
|||
return { |
|||
userInfo: {}, |
|||
|
|||
chatObject: {}, |
|||
messageList: [], |
|||
noHistory: true, |
|||
isVoice: false, |
|||
inputText: "", |
|||
|
|||
// 消息唯一key |
|||
key: null, |
|||
|
|||
// 用户默认图标 |
|||
defaultAvatar: '/uni_modules/vrapile-im/static/image/yy.png', |
|||
// 消息铃铛图标 |
|||
iconMessage: "/uni_modules/vrapile-im/static/image/message.png", |
|||
// 语音切换图标 |
|||
iconVoice: "/uni_modules/vrapile-im/static/image/voice.png", |
|||
// 表情图标 |
|||
iconEmoji: "/uni_modules/vrapile-im/static/image/emoji.png", |
|||
// 更多图标 |
|||
iconMore: "/uni_modules/vrapile-im/static/image/more.png", |
|||
} |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
websocketData: state => store.state.socket.websocketData |
|||
}), |
|||
getChatList() { |
|||
return store.state.chat.chatList; |
|||
}, |
|||
getUserAvatar() { |
|||
return (userId, defaultAvatar) => { |
|||
return store.getters.getUserAvatar(userId, defaultAvatar); |
|||
} |
|||
}, |
|||
getUserName() { |
|||
return (userId, defaultName) => { |
|||
return store.getters.getUserName(userId, defaultName); |
|||
} |
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
this.userInfo = storeOut.state.user.userInfo; |
|||
if(!this.userInfo.userId){ |
|||
this.navigateToLogin(); |
|||
} |
|||
try{ |
|||
this.key = options.data; |
|||
}catch(e){ |
|||
this.switchTab("/uni_modules/vrapile-im/pages/home/chatHome"); |
|||
} |
|||
}, |
|||
// 下拉处理 |
|||
onPullDownRefresh() { |
|||
if(this.chatObject.haveHistory==1){ |
|||
this.handleHistoryMessage(); |
|||
} |
|||
setTimeout(() => { |
|||
uni.stopPullDownRefresh(); |
|||
}, 500); |
|||
}, |
|||
onShow(){ |
|||
for(let i=0; i < this.getChatList.length; i++){ |
|||
if(this.getChatList[i]["key"] == this.key){ |
|||
this.chatObject = this.getChatList[i]; |
|||
uni.setNavigationBarTitle({ |
|||
title: this.chatObject.name || "好友" |
|||
}) |
|||
this.messageList = this.getChatList[i].messageList; |
|||
this.scrollToBottom(); |
|||
if(this.messageList.length == 0 && this.chatObject.haveHistory==1){ |
|||
this.handleHistoryMessage(); |
|||
}else{ |
|||
this.handleRead(); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
}, |
|||
// 监听消息 |
|||
watch: { |
|||
websocketData: { |
|||
handler(newVal, oldval) { |
|||
if(newVal && newVal.length > 0 |
|||
&& (newVal[newVal.length-1]["toId"] == this.userInfo.userId |
|||
|| newVal[newVal.length-1]["fromId"] == this.userInfo.userId)){ |
|||
this.scrollToBottom(); |
|||
this.handleRead(); |
|||
} |
|||
}, |
|||
immediate: true, |
|||
deep: true |
|||
} |
|||
}, |
|||
methods: { |
|||
// 滚动到最新消息位置 |
|||
scrollToBottom() { |
|||
setTimeout(() => { |
|||
uni.pageScrollTo({ |
|||
scrollTop: 2000000, |
|||
duration : 10 |
|||
}) |
|||
}, 500); |
|||
}, |
|||
// 语音点击事件 |
|||
handleVoice() { |
|||
this.isVoice = !this.isVoice; |
|||
}, |
|||
// 语音消息处理, 暂时先发送个提示 |
|||
handleSay() { |
|||
let sendInfo = { |
|||
code: 2, |
|||
message: { |
|||
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回 |
|||
messageType: 0, |
|||
//聊天室id |
|||
toId: this.chatObject.id, |
|||
//消息发送人 |
|||
fromId: this.userInfo.userId, |
|||
//消息发送人账号 |
|||
fromName: this.userInfo.userName, |
|||
//消息内容 |
|||
content: "您发送了一条语音消息", |
|||
//消息类型:0-私聊|1-群聊 |
|||
sendType: this.chatObject.type, |
|||
//扩展消息 |
|||
extend: null |
|||
}, |
|||
}; |
|||
uni.sendSocketMessage({ |
|||
data: JSON.stringify(sendInfo) |
|||
}) |
|||
}, |
|||
// 表情消息处理, 暂时先发送个提示 |
|||
handleEmoji() { |
|||
let sendInfo = { |
|||
code: 2, |
|||
message: { |
|||
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回 |
|||
messageType: 0, |
|||
//聊天室id |
|||
toId: this.chatObject.id, |
|||
//消息发送人 |
|||
fromId: this.userInfo.userId, |
|||
//消息发送人账号 |
|||
fromName: this.userInfo.userName, |
|||
//消息内容 |
|||
content: "您发送了一个表情消息", |
|||
//消息类型:0-私聊|1-群聊 |
|||
sendType: this.chatObject.type, |
|||
//扩展消息 |
|||
extend: null |
|||
}, |
|||
}; |
|||
uni.sendSocketMessage({ |
|||
data: JSON.stringify(sendInfo) |
|||
}) |
|||
}, |
|||
// 更多消息处理, 暂时先发送个提示 |
|||
handleMore() { |
|||
let sendInfo = { |
|||
code: 2, |
|||
message: { |
|||
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回 |
|||
messageType: 0, |
|||
//聊天室id |
|||
toId: this.chatObject.id, |
|||
//消息发送人 |
|||
fromId: this.userInfo.userId, |
|||
//消息发送人账号 |
|||
fromName: this.userInfo.userName, |
|||
//消息内容 |
|||
content: "您发送了一个更多的消息", |
|||
//消息类型:0-私聊|1-群聊 |
|||
sendType: this.chatObject.type, |
|||
//扩展消息 |
|||
extend: null |
|||
}, |
|||
}; |
|||
uni.sendSocketMessage({ |
|||
data: JSON.stringify(sendInfo) |
|||
}) |
|||
}, |
|||
// 反馈已读 |
|||
handleRead() { |
|||
let sendInfo = { |
|||
code: 3, |
|||
message: { |
|||
//聊天室id |
|||
toId: this.chatObject.id, |
|||
//消息发送人 |
|||
userId: this.userInfo.userId, |
|||
//消息类型:0-私聊|1-群聊 |
|||
sendType: this.chatObject.type, |
|||
}, |
|||
}; |
|||
uni.sendSocketMessage({ |
|||
data: JSON.stringify(sendInfo) |
|||
}) |
|||
store.commit('READ_MESSAGE', this.key); |
|||
store.commit('COUNT_MESSAGE'); |
|||
}, |
|||
// 发送消息 |
|||
handleSend() { |
|||
if(!this.inputText){ |
|||
return; |
|||
} |
|||
let sendInfo = { |
|||
code: 2, |
|||
message: { |
|||
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回 |
|||
messageType: 0, |
|||
//聊天室id |
|||
toId: this.chatObject.id, |
|||
//消息发送人 |
|||
fromId: this.userInfo.userId, |
|||
//消息发送人账号 |
|||
fromName: this.userInfo.userName, |
|||
//消息内容 |
|||
content: this.inputText, |
|||
//消息类型:0-私聊|1-群聊 |
|||
sendType: this.chatObject.type, |
|||
//扩展内容 |
|||
extend: null |
|||
}, |
|||
}; |
|||
uni.sendSocketMessage({ |
|||
data: JSON.stringify(sendInfo) |
|||
}) |
|||
this.inputText = ""; |
|||
}, |
|||
// 获取历史消息 |
|||
handleHistoryMessage(){ |
|||
let limit = this.chatObject["messageList"].length + 10; |
|||
getMessageByChatKey({ |
|||
type: this.chatObject.type, |
|||
key: this.chatObject["key"], |
|||
groupId: this.chatObject.id, |
|||
limit: limit |
|||
}).then(res => { |
|||
if(res.data.length > 0){ |
|||
this.messageList = res.data.reverse(); |
|||
this.chatObject["messageList"] = this.messageList; |
|||
let lastMessage = res.data[res.data.length-1]; |
|||
this.chatObject["messageLast"] = lastMessage; |
|||
if(lastMessage["sendType"] == 0){ |
|||
this.chatObject["messageShow"] = lastMessage["content"]; |
|||
}else{ |
|||
this.chatObject["messageShow"] = store.getters.getUserName(lastMessage["fromId"], lastMessage["fromName"]) + ": " + lastMessage["content"] |
|||
} |
|||
this.chatObject["messageTime"] = this.formatDate(lastMessage["sendTime"]); |
|||
} |
|||
if(res.data.length < limit){ |
|||
this.chatObject["haveHistory"] = 0; |
|||
} |
|||
|
|||
for(let i=0; i < this.getChatList.length; i++){ |
|||
if(this.getChatList[i]["key"] == this.key){ |
|||
this.$set(this.getChatList, i, this.chatObject) |
|||
break; |
|||
} |
|||
} |
|||
this.scrollToBottom(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
/* 重写外部nine-chat-friend-001.scss可实现样式改变 */ |
|||
@import '/uni_modules/vrapile-im/static/style/nine-chat-friend-001.scss'; |
|||
@import '/static/style/nine-chat-friend-001.scss'; |
|||
</style> |
@ -0,0 +1,184 @@ |
|||
<template> |
|||
<view class="nine-content-002"> |
|||
<view class="chat-search"> |
|||
<input class="chat-search-input" v-model="searchVal"/> |
|||
<uni-icons class="chat-search-image" type="search" size="24"></uni-icons> |
|||
</view> |
|||
<view class="chat-list"> |
|||
<view class="chat-list-item" v-for="(item,index) in getChatFilterList" :key="index" @click="goToChat(item.key)"> |
|||
<view class="chat-list-item-left"> |
|||
<image class="chat-list-item-left-image" mode="scaleToFill" v-if="item.fromId != userInfo.userId" :src="getUserAvatar(item.fromId, item.avatar)"></image> |
|||
<image class="chat-list-item-left-image" mode="scaleToFill" v-else :src="userInfo.avatar || defaultAvatar"></image> |
|||
<view v-if="item.messageNum > 0" class="chat-list-item-left-mark"> |
|||
{{ item.messageNum < 100 ? item.messageNum : 99 }} |
|||
</view> |
|||
</view> |
|||
<view class="chat-list-item-center"> |
|||
<view class="chat-list-item-center-top"> |
|||
{{ item.name }} |
|||
</view> |
|||
<view class="chat-list-item-center-bottom"> |
|||
{{ item.messageShow || " " }} |
|||
</view> |
|||
</view> |
|||
<view class="chat-list-item-right"> |
|||
<view class="chat-list-item-right-top"> |
|||
{{ item.messageTime || '\xa0' }} |
|||
</view> |
|||
<view class="chat-list-item-right-bottom"> |
|||
<image class="chat-list-item-right-bottom-image" mode="scaleToFill" :src="iconMessage"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState } from 'vuex' |
|||
import store from '@/uni_modules/vrapile-im/store' |
|||
import { getChatKey } from '@/uni_modules/vrapile-im/utils/tiosocket'; |
|||
// 外部需提供store用于获取用户信息,提供websocket接口地址,提供获取token函数并可以获取token,提供根据消息key查询用户历史消息接口 |
|||
import storeOut from '@/store' |
|||
import { getToken } from '@/utils/token' |
|||
import { getMessageByChatKey } from '@/api/chat' |
|||
export default { |
|||
data() { |
|||
return { |
|||
userInfo: {}, |
|||
|
|||
searchVal: "", |
|||
|
|||
// 用户默认图标 |
|||
defaultAvatar: '/uni_modules/vrapile-im/static/image/yy.png', |
|||
// 消息铃铛图标 |
|||
iconMessage: "/uni_modules/vrapile-im/static/image/message.png" |
|||
} |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
websocketData: state => store.state.socket.websocketData |
|||
}), |
|||
getChatList() { |
|||
return store.state.chat.chatList; |
|||
}, |
|||
getChatFilterList() { |
|||
let list = JSON.parse(JSON.stringify(store.state.chat.chatList)) |
|||
list.sort((a, b) => { |
|||
if(a.messageNum > 0 && b.messageNum > 0){ |
|||
return b.messageLast.sendTime - a.messageLast.sendTime |
|||
} |
|||
if(a.messageList.length == 0 || b.messageList.length == 0){ |
|||
return b.messageList.length - a.messageList.length |
|||
} |
|||
if(a.messageNum == 0 && b.messageNum == 0){ |
|||
return b.messageLast.sendTime - a.messageLast.sendTime |
|||
} |
|||
return b.messageNum - a.messageNum |
|||
}) |
|||
if(this.searchVal){ |
|||
return list.filter(item => { |
|||
if(item.name && item.name.includes(this.searchVal) |
|||
|| item.remarkName && item.remarkName.includes(this.searchVal) |
|||
|| item.userName && item.userName.includes(this.searchVal)){ |
|||
return item; |
|||
} |
|||
for(let message of item.messageList){ |
|||
if(message.content && message.content.includes(this.searchVal)){ |
|||
return item; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
return list; |
|||
}, |
|||
getUserAvatar() { |
|||
return (userId, defaultAvatar) => { |
|||
return store.getters.getUserAvatar(userId, defaultAvatar); |
|||
} |
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
this.userInfo = storeOut.state.user.userInfo; |
|||
}, |
|||
onShow(){ |
|||
setTimeout(()=>{ |
|||
this.dealUnReadMessage(); |
|||
store.commit('COUNT_MESSAGE'); |
|||
}, 500) |
|||
setTimeout(()=>{ |
|||
this.noListDo(); |
|||
}, 3000) |
|||
}, |
|||
activated(){ |
|||
store.commit('COUNT_MESSAGE'); |
|||
}, |
|||
// 监听消息 |
|||
watch: { |
|||
websocketData: { |
|||
handler(newVal, oldval) { |
|||
for(let i=0;i<this.getChatList.length;i++){ |
|||
this.$set(this.getChatList, i, this.getChatList[i]) |
|||
} |
|||
}, |
|||
immediate: true, |
|||
deep: true |
|||
} |
|||
}, |
|||
methods: { |
|||
// 处理未读消息 |
|||
dealUnReadMessage() { |
|||
for(let i=0;i<this.getChatList.length;i++){ |
|||
if(this.getChatList[i]["messageList"].length == 0 && this.getChatList[i]["haveHistory"] == 1){ |
|||
this.handleHistoryMessage(i, false); |
|||
} |
|||
} |
|||
}, |
|||
// 无任何数据,重写获取聊天列表和连接socket |
|||
noListDo(){ |
|||
if(storeOut.state.user.userInfo.userId && (!this.getChatList || this.getChatList.length == 0)){ |
|||
store.dispatch('GetChatList', {userId: storeOut.state.user.userInfo.userId}).then(res => { |
|||
store.dispatch('ConnSocket', { url: import.meta.env.VITE_APP_SOCKET_URL, token: getToken() }); |
|||
}); |
|||
} |
|||
}, |
|||
// 获取历史消息 |
|||
handleHistoryMessage(i, scrollFlag){ |
|||
let limit = this.getChatList[i]["messageList"].length + 10; |
|||
getMessageByChatKey({ |
|||
type: this.getChatList[i].type, |
|||
key: this.getChatList[i]["key"], |
|||
groupId: this.getChatList[i].id, |
|||
limit: limit |
|||
}).then(res => { |
|||
if(res.data.length > 0){ |
|||
this.getChatList[i]["messageList"] = res.data.reverse(); |
|||
let lastMessage = res.data[res.data.length-1]; |
|||
this.getChatList[i]["messageLast"] = lastMessage; |
|||
if(lastMessage["sendType"] == 0){ |
|||
this.getChatList[i]["messageShow"] = lastMessage["content"]; |
|||
}else{ |
|||
this.getChatList[i]["messageShow"] = store.getters.getUserName(lastMessage["fromId"], lastMessage["fromName"]) + ": " + lastMessage["content"] |
|||
} |
|||
this.getChatList[i]["messageTime"] = this.formatDate(lastMessage["sendTime"]); |
|||
} |
|||
if(res.data.length < limit){ |
|||
this.getChatList[i]["haveHistory"] = 0; |
|||
} |
|||
|
|||
this.$set(this.getChatList, i, this.getChatList[i]) |
|||
}); |
|||
}, |
|||
// 跳转到聊天页面 |
|||
goToChat(key) { |
|||
this.navigateTo("/uni_modules/vrapile-im/pages/chat/chatFriend?data=" + key) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
/* 重写外部nine-chat-home-001.scss可实现样式改变 */ |
|||
@import '/uni_modules/vrapile-im/static/style/nine-chat-home-001.scss'; |
|||
@import '/static/style/nine-chat-home-001.scss'; |
|||
</style> |
@ -0,0 +1,20 @@ |
|||
{ |
|||
"pages": [ |
|||
// 消息 |
|||
{ |
|||
"path": "uni_modules/vrapile-im/pages/home/chatHome", |
|||
"style": { |
|||
"navigationBarTitleText": "消息", |
|||
"enablePullDownRefresh": false |
|||
} |
|||
}, |
|||
// 聊天 |
|||
{ |
|||
"path": "uni_modules/vrapile-im/pages/chat/chatFriend", |
|||
"style": { |
|||
"navigationBarTitleText": "聊天", |
|||
"enablePullDownRefresh": true |
|||
} |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,105 @@ |
|||
## 组件说明 |
|||
1. 此组件为页面组件,实现了Socket连接/好友/群组/新消息/历史消息,且都是全局配置全局本地化存储,兼容H5/微信小程序/安卓App(其他平台未做调试) |
|||
|
|||
2. 此组件中已提供示例工程,其中的接口和websocket服务,仅供各位开发者调试使用,正式发布需自行实现接口和websocket服务。 |
|||
|
|||
|
|||
## 自行准备内容 |
|||
|
|||
1. WebSocket服务,替换.env.development下VITE_APP_SOCKET_URL地址 |
|||
|
|||
websocket需要实现连接,实现心跳检测/离线消息/在线消息/已读回执4种消息类型 |
|||
|
|||
2. 接口服务,实现聊天/api/chat.js和/api/login.js里面的方法 |
|||
|
|||
|
|||
## 引用说明 |
|||
|
|||
### 1. 路由说明 |
|||
|
|||
导入组件后,在pages.json中会自动注册组件,若未注册可手动添加 |
|||
``` javascript |
|||
{ |
|||
"path": "uni_modules/vrapile-im/pages/home/chatHome", |
|||
"style": { |
|||
"enablePullDownRefresh": false, |
|||
"navigationBarTitleText": "消息" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "uni_modules/vrapile-im/pages/chat/chatFriend", |
|||
"style": { |
|||
"enablePullDownRefresh": false, |
|||
"navigationBarTitleText": "聊天" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
可在导航中配置IM消息页面 |
|||
|
|||
``` javascript |
|||
"tabBar": { |
|||
"selectedColor": "#0000ff", |
|||
"list": [ |
|||
{ |
|||
"pagePath": "uni_modules/vrapile-im/pages/home/chatHome", |
|||
"iconPath": "static/image/tabbar/chat.png", |
|||
"selectedIconPath": "static/image/tabbar/chat-fill.png", |
|||
"text": "消息" |
|||
}, |
|||
{ |
|||
"pagePath": "pages/home/user", |
|||
"iconPath": "static/image/tabbar/user.png", |
|||
"selectedIconPath": "static/image/tabbar/user-fill.png", |
|||
"text": "我的" |
|||
} |
|||
] |
|||
}, |
|||
``` |
|||
|
|||
### 2. 页面样式修改 |
|||
页面样式在/uni_modules/vrapile-im/static/style/下的nine-chat-home-001.scss和nine-chat-friend-001.scss中, |
|||
|
|||
可通过重写/static/style/下的nine-chat-home-001.scss和nine-chat-friend-001.scss,将原样式替换 |
|||
|
|||
|
|||
## 演示说明 |
|||
|
|||
以下共用一个后端,全部互通 |
|||
|
|||
<br> |
|||
|
|||
示例工程运行效果: |
|||
|
|||
<a href="https://www.ninecloud.top/udemo/im/index.html" target="_blank">https://www.ninecloud.top/udemo/im/index.html</a> |
|||
|
|||
<img src="https://fs.ninecloud.top/uniapp/udemo/im/qrcode.png" width="300"> |
|||
|
|||
<br> |
|||
<br> |
|||
|
|||
|
|||
演示商城H5效果: |
|||
|
|||
<a href="https://www.ninecloud.top/unine/index.html" target="_blank">https://www.ninecloud.top/unine/index.html</a> |
|||
|
|||
<img src="https://fs.ninecloud.top/uniapp/unine/qrcode.png" width="300"> |
|||
|
|||
<font color="gray">H5中可下载安卓App</font> |
|||
|
|||
<br> |
|||
<br> |
|||
|
|||
演示PC前端(与此组件无关,可用于多端消息互相发送测试): |
|||
|
|||
<a href="https://www.ninecloud.top/msw/index" target="_blank">https://www.ninecloud.top/msw/index</a> |
|||
|
|||
|
|||
<br> |
|||
<br> |
|||
|
|||
注:新注册账号,默认添加【visitor】为好友,默认加入【客服专用群】群 |
|||
|
|||
因此,可用访客/注册账号登录以上任意系统,可任意发送消息,皆能同步显示 |
|||
|
|||
(*以上系统皆可用访客账号/密码:visitor/visitor*) |
After ![]() Width: 72 | Height: 71 | Size: 9.4 KiB |
After ![]() Width: 53 | Height: 60 | Size: 5.4 KiB |
After ![]() Width: 72 | Height: 71 | Size: 8.2 KiB |
After ![]() Width: 72 | Height: 72 | Size: 9.5 KiB |
After ![]() Width: 45 | Height: 45 | Size: 7.1 KiB |
@ -0,0 +1,165 @@ |
|||
html, body, #app{ |
|||
height: 100%; |
|||
background-color: #f1f1f1; |
|||
} |
|||
.nine-content-001{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
width: 750rpx; |
|||
height: calc(100vh - 0px); |
|||
margin: 0; |
|||
padding: 0; |
|||
background-color: #f1f1f1; |
|||
} |
|||
.chat-body { |
|||
/* #ifdef MP-WEIXIN */ |
|||
background-color: #fff; |
|||
/* #endif */ |
|||
} |
|||
.chat-body-main{ |
|||
padding-top: 20rpx; |
|||
padding-left: 20rpx; |
|||
padding-right: 20rpx; |
|||
box-sizing: border-box; |
|||
-webkit-overflow-scrolling: touch; |
|||
padding-bottom: 100rpx; |
|||
} |
|||
.chat-body-history{ |
|||
width: 100%; |
|||
height: 90rpx; |
|||
line-height: 90rpx; |
|||
font-size: 24rpx; |
|||
color: grey; |
|||
text-align: center; |
|||
} |
|||
.chat-body-history-have{ |
|||
color: rgb(79, 172, 249); |
|||
} |
|||
.chat-conversation{ |
|||
display: flex; |
|||
align-items: flex-start; |
|||
padding: 20rpx 5rpx; |
|||
word-break: break-all; |
|||
} |
|||
.chat-conversation-text{ |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
margin: 0 20rpx; |
|||
} |
|||
.chat-conversation-text-time{ |
|||
font-size: 10px; |
|||
color: gray; |
|||
} |
|||
.chat-conversation-text-text{ |
|||
position: relative; |
|||
display: flex; |
|||
align-items: center; |
|||
max-width: 70%; |
|||
min-height: 45rpx; |
|||
padding: 15rpx 20rpx; |
|||
border-radius: 10rpx; |
|||
background-color: #FFF; |
|||
/* #ifdef MP-WEIXIN */ |
|||
background-color: #f1f1f1; |
|||
/* #endif */ |
|||
} |
|||
.chat-conversation-text-text::after { |
|||
content: ''; |
|||
position: absolute; |
|||
top: 16rpx; |
|||
left: -35rpx; |
|||
border-width: 19rpx; |
|||
border-style: solid; |
|||
border-top-color: transparent; |
|||
border-left-color: transparent; |
|||
border-right-color: #FFF; |
|||
/* #ifdef MP-WEIXIN */ |
|||
border-right-color: #f1f1f1; |
|||
/* #endif */ |
|||
border-bottom-color: transparent; |
|||
} |
|||
.chat-conversation-mine{ |
|||
align-items: flex-start; |
|||
flex-direction: row-reverse; |
|||
} |
|||
.chat-conversation-mine .chat-conversation-text{ |
|||
align-items: flex-end; |
|||
} |
|||
.chat-conversation-mine .chat-conversation-text-time{ |
|||
text-align: right; |
|||
} |
|||
.chat-conversation-mine .chat-conversation-text-text{ |
|||
background: #9ede86 !important; |
|||
} |
|||
.chat-conversation-mine .chat-conversation-text-text::after { |
|||
left: auto !important; |
|||
right: -35rpx !important; |
|||
border-left-color: #9ede86 !important; |
|||
border-right-color: transparent !important; |
|||
} |
|||
.chat-conversation-image{ |
|||
} |
|||
.chat-conversation-image-image{ |
|||
width: 80rpx; |
|||
height: 80rpx; |
|||
padding: 5rpx; |
|||
border-radius: 10rpx; |
|||
} |
|||
|
|||
.chat-footer { |
|||
position: fixed; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
height: 100rpx; |
|||
background-color: #fff; |
|||
display: flex; |
|||
/* #ifdef MP-WEIXIN */ |
|||
border-top: 1rpx solid #f1f1f1; |
|||
/* #endif */ |
|||
} |
|||
.chat-footer-send{ |
|||
flex-grow: 1; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
padding: 0 10rpx; |
|||
} |
|||
.chat-footer-send-image{ |
|||
padding: 0 10rpx; |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
} |
|||
.chat-footer-send-input{ |
|||
flex-grow: 1; |
|||
text-align: left; |
|||
padding: 15rpx; |
|||
border-radius: 5rpx; |
|||
background-color: #f9f9f9; |
|||
} |
|||
.chat-footer-send-say{ |
|||
flex-grow: 1; |
|||
text-align: center; |
|||
padding: 20rpx; |
|||
border-radius: 5rpx; |
|||
background-color: #f9f9f9; |
|||
} |
|||
.chat-footer-send-button{ |
|||
line-height: 65rpx; |
|||
margin: 0 10rpx; |
|||
color: #FFFFFF; |
|||
background-color: #0000ff; |
|||
border-radius: 10rpx; |
|||
} |
|||
.chat-footer-send-button-span{ |
|||
padding: 0 25rpx; |
|||
} |
|||
|
|||
// 允许文本复制 |
|||
.nine-user-select { |
|||
cursor: auto; |
|||
-webkit-user-select: text; |
|||
user-select: text; |
|||
} |
@ -0,0 +1,112 @@ |
|||
html, body, #app{ |
|||
height: 100%; |
|||
background-color: #f1f1f1; |
|||
} |
|||
.nine-content-002{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
width: 750rpx; |
|||
height: calc(100vh - 50px); |
|||
/* #ifndef H5 */ |
|||
height: calc(100vh - 0px); |
|||
/* #endif */ |
|||
margin: 0; |
|||
padding: 0; |
|||
background-color: #f1f1f1; |
|||
} |
|||
|
|||
.chat-search{ |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 5rpx; |
|||
background-color: #ffffff; |
|||
} |
|||
.chat-search-image{ |
|||
height: 45rpx; |
|||
line-height: 45rpx; |
|||
padding: 10rpx; |
|||
background-color: #f8f8f8; |
|||
} |
|||
.chat-search-input{ |
|||
width: 100%; |
|||
height: 45rpx; |
|||
line-height: 45rpx; |
|||
padding: 10rpx; |
|||
font-size: 16px; |
|||
background-color: #f8f8f8; |
|||
} |
|||
|
|||
.chat-list{ |
|||
flex: 1; |
|||
padding: 0; |
|||
overflow-y: auto; |
|||
} |
|||
.chat-list-item{ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
margin: 2rpx 0; |
|||
padding: 15rpx 10rpx; |
|||
border-radius: 10rpx; |
|||
background-color: #ffffff; |
|||
} |
|||
.chat-list-item-left{ |
|||
position: relative; |
|||
width: 84rpx; |
|||
height: 84rpx; |
|||
} |
|||
.chat-list-item-left-image{ |
|||
width: 82rpx; |
|||
height: 82rpx; |
|||
border: 1rpx solid #f1f1f1; |
|||
border-radius: 5rpx; |
|||
} |
|||
.chat-list-item-left-mark{ |
|||
position: absolute; |
|||
width: 30rpx; |
|||
top: -13rpx; |
|||
right: -13rpx; |
|||
padding: 1rpx; |
|||
border-radius: 50%; |
|||
font-size: 12px; |
|||
color: white; |
|||
background-color: red; |
|||
text-align: center; |
|||
} |
|||
|
|||
.chat-list-item-center{ |
|||
width: 450rpx; |
|||
margin: 0 20rpx; |
|||
} |
|||
.chat-list-item-center-top{ |
|||
width: 450rpx; |
|||
font-size: 16px; |
|||
overflow: hidden; |
|||
white-space: nowrap; |
|||
text-overflow: ellipsis; |
|||
} |
|||
.chat-list-item-center-bottom{ |
|||
width: 450rpx; |
|||
font-size: 12px; |
|||
color: #969696; |
|||
overflow: hidden; |
|||
white-space: nowrap; |
|||
text-overflow: ellipsis; |
|||
} |
|||
|
|||
.chat-list-item-right{ |
|||
width: 130rpx; |
|||
color: #a7a7a7; |
|||
} |
|||
.chat-list-item-right-top{ |
|||
font-size: 12px; |
|||
text-align: right; |
|||
} |
|||
.chat-list-item-right-bottom{ |
|||
padding-top: 15rpx; |
|||
text-align: right; |
|||
} |
|||
.chat-list-item-right-bottom-image{ |
|||
width: 25rpx; |
|||
height: 30rpx; |
|||
} |
@ -0,0 +1,11 @@ |
|||
const getters = { |
|||
chatList: state => state.chat.chatList, |
|||
friendList: state => state.chat.friendList, |
|||
groupList: state => state.chat.groupList, |
|||
userObject: state => state.chat.userObject, |
|||
groupObject: state => state.chat.groupObject, |
|||
|
|||
websocket: state => state.socket.websocket, |
|||
websocketData: state => state.socket.websocketData |
|||
} |
|||
export default getters |
@ -0,0 +1,16 @@ |
|||
import Vuex from 'vuex' |
|||
import socket from '@/uni_modules/vrapile-im/store/modules/socket' |
|||
import chat from '@/uni_modules/vrapile-im/store/modules/chat' |
|||
import getters from './getters' |
|||
|
|||
// Vue.use(Vuex)
|
|||
|
|||
const store = new Vuex.Store({ |
|||
modules: { |
|||
chat, |
|||
socket |
|||
}, |
|||
getters |
|||
}) |
|||
|
|||
export default store |
@ -0,0 +1,138 @@ |
|||
import storage from '@/uni_modules/vrapile-im/utils/storage' |
|||
import constant from '@/uni_modules/vrapile-im/utils/constant' |
|||
import { getChatKey } from '@/uni_modules/vrapile-im/utils/tiosocket'; |
|||
|
|||
// 外部需提供获取用户好友,获取用户所有群,以及群中所有用户三个接口
|
|||
import { getUserAllFriend, getUserAllGroup, getGroupUser } from '@/api/chat' |
|||
|
|||
const chat = { |
|||
state: { |
|||
friendList: storage.get(constant.friendList) || [], |
|||
groupList: storage.get(constant.groupList) || [], |
|||
userObject: storage.get(constant.userObject) || {}, |
|||
groupObject: storage.get(constant.groupObject) || {}, |
|||
chatList: storage.get(constant.chatList) || [] |
|||
}, |
|||
|
|||
mutations: { |
|||
// 清空聊天列表
|
|||
CLEAN_CHAT_LIST: (state) => { |
|||
state.chatList = new Array(); |
|||
storage.set(constant.chatList, state.chatList) |
|||
}, |
|||
// 存储好友聊天列表
|
|||
SET_CHAT_FRIEND_LIST: (state, data) => { |
|||
state.friendList = data; |
|||
storage.set(constant.friendList, data) |
|||
|
|||
for(let item of data){ |
|||
item["key"] = getChatKey(item["type"], item["friendId"], item["userId"]) |
|||
item["haveHistory"] = 1; |
|||
item["id"] = item["friendId"]; |
|||
item["name"] = item["remarkName"] || item["nickName"]; |
|||
item["messageNum"] = 0; |
|||
item["messageList"] = []; |
|||
item["messageShow"] = ""; |
|||
item["messageLast"] = {}; |
|||
state.chatList.push(item) |
|||
} |
|||
storage.set(constant.chatList, state.chatList) |
|||
}, |
|||
// 存储群聊列表
|
|||
SET_CHAT_GROUP_LIST: (state, data) => { |
|||
state.groupList = data; |
|||
storage.set(constant.groupList, data) |
|||
|
|||
for(let item of data){ |
|||
item["key"] = getChatKey(item["type"], item["id"], item["userId"]) |
|||
item["haveHistory"] = 1; |
|||
item["id"] = item["id"]; |
|||
item["name"] = item["remarkName"] || item["name"] |
|||
item["messageNum"] = 0; |
|||
item["messageList"] = []; |
|||
item["messageShow"] = ""; |
|||
item["messageLast"] = {}; |
|||
state.chatList.push(item) |
|||
} |
|||
storage.set(constant.chatList, state.chatList) |
|||
}, |
|||
// 存储用户对象,方便寻找用户名,头像等
|
|||
SET_USER_OBJECT: (state, userObject) => { |
|||
state.userObject[userObject.userId] = userObject; |
|||
storage.set(constant.userObject, state.userObject) |
|||
}, |
|||
// 存储群组对象,方便寻找群组名,头像等
|
|||
SET_GROUP_OBJECT: (state, groupObject) => { |
|||
state.groupObject[groupObject.id] = groupObject; |
|||
storage.set(constant.groupObject, state.groupObject) |
|||
} |
|||
}, |
|||
|
|||
actions: { |
|||
// 获取登录用户所有聊天列表
|
|||
GetChatList({ commit, state }, params) { |
|||
return new Promise((resolve, reject) => { |
|||
commit('CLEAN_CHAT_LIST'); |
|||
// 查询好友
|
|||
getUserAllFriend().then(res => { |
|||
let list = [] |
|||
for(let item of res.data){ |
|||
list.push({type: 0, ...item, userId: params.userId}) |
|||
commit('SET_USER_OBJECT', item) |
|||
} |
|||
commit('SET_CHAT_FRIEND_LIST', list) |
|||
|
|||
// 查询群组
|
|||
getUserAllGroup().then(res1 => { |
|||
let list = [] |
|||
for(let item1 of res1.data){ |
|||
list.push({type: 1, ...item1, userId: params.userId}) |
|||
// 查询群组人员
|
|||
getGroupUser(item1.id).then(res2 => { |
|||
for(let user of res2.data){ |
|||
commit('SET_USER_OBJECT', user) |
|||
} |
|||
resolve(res2) |
|||
}); |
|||
commit('SET_GROUP_OBJECT', item1) |
|||
} |
|||
commit('SET_CHAT_GROUP_LIST', list) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}).catch(error => { |
|||
reject(error) |
|||
}) |
|||
}) |
|||
} |
|||
}, |
|||
|
|||
getters: { |
|||
getUserAvatar: (state) => (userId, defaultAvatar) => { |
|||
if(state.userObject[userId] && state.userObject[userId]["avatar"]){ |
|||
return state.userObject[userId]["avatar"] |
|||
} |
|||
return defaultAvatar || '/uni_modules/vrapile-im/static/image/yy.png'; |
|||
}, |
|||
getGroupAvatar: (state) => (groupId, defaultAvatar) => { |
|||
if(state.groupObject[groupId] && state.groupObject[groupId]["avatar"]){ |
|||
return state.groupObject[groupId]["avatar"] |
|||
} |
|||
return defaultAvatar || '/uni_modules/vrapile-im/static/image/yy.png'; |
|||
}, |
|||
getUserName: (state) => (userId, defaultName) => { |
|||
if(state.userObject[userId]){ |
|||
return state.userObject[userId]["remarkName"] || state.userObject[userId]["nickName"] || defaultName |
|||
} |
|||
return defaultName || "无名"; |
|||
}, |
|||
getGroupName: (state) => (groupId, defaultName) => { |
|||
if(state.groupObject[groupId]){ |
|||
return state.groupObject[userId]["remarkName"] || state.groupObject[userId]["name"] || defaultName |
|||
} |
|||
return defaultName || "无名"; |
|||
} |
|||
} |
|||
} |
|||
|
|||
export default chat |
@ -0,0 +1,116 @@ |
|||
import store from '@/uni_modules/vrapile-im/store' |
|||
import storage from '@/uni_modules/vrapile-im/utils/storage' |
|||
import constant from '@/uni_modules/vrapile-im/utils/constant' |
|||
import { formatDate } from '@/uni_modules/vrapile-im/utils/nineTool'; |
|||
import { TioSocket, getChatKey } from '@/uni_modules/vrapile-im/utils/tiosocket'; |
|||
|
|||
const socket = { |
|||
state: { |
|||
websocket: storage.get(constant.websocket), |
|||
websocketData: storage.get(constant.websocketData) |
|||
}, |
|||
|
|||
mutations: { |
|||
// 存储登录链接
|
|||
SET_SOCKET: (state, socket) => { |
|||
state.websocket = socket; |
|||
storage.set(constant.websocket, socket) |
|||
}, |
|||
// 添加socket消息
|
|||
ADD_MESSAGE: (state, message) => { |
|||
state.websocketData.push(message) |
|||
storage.set(constant.websocketData, state.websocketData) |
|||
|
|||
// 添加消息
|
|||
for(let i=0;i<store.state.chat.chatList.length;i++){ |
|||
let item = store.state.chat.chatList[i]; |
|||
let key = getChatKey(message["sendType"], message["toId"], message["fromId"]) |
|||
if(store.state.chat.chatList[i]["key"] == key){ |
|||
store.state.chat.chatList[i]["messageList"].push(message) |
|||
store.state.chat.chatList[i]["messageTime"] = formatDate(message["sendTime"]); |
|||
store.state.chat.chatList[i]["messageLast"] = message; |
|||
store.state.chat.chatList[i]["haveHistory"] = 1; |
|||
// 自己发送的消息,总消息数是否加1,如果不加,取消下方注释内容
|
|||
// if(store.state.user.userInfo.userId && store.state.user.userInfo.userId != message["fromId"]){
|
|||
store.state.chat.chatList[i]["messageNum"] += 1; |
|||
// }
|
|||
if(store.state.chat.chatList[i]["type"] == 0){ |
|||
store.state.chat.chatList[i]["messageShow"] = message["content"]; |
|||
}else{ |
|||
store.state.chat.chatList[i]["messageShow"] = store.getters.getUserName(message["fromId"], message["fromName"]) + ": " + message["content"] |
|||
} |
|||
storage.set(constant.chatList, store.state.chat.chatList); |
|||
break; |
|||
} |
|||
} |
|||
store.commit('COUNT_MESSAGE'); |
|||
}, |
|||
// 回执已读消息
|
|||
READ_MESSAGE: (state, k) => { |
|||
// 删除未读消息
|
|||
for(let i=0;i<state.websocketData.length;i++){ |
|||
let key = getChatKey(state.websocketData[i]["sendType"], state.websocketData[i]["toId"], state.websocketData[i]["fromId"]) |
|||
if(key == k){ |
|||
state.websocketData.splice(i, 1); |
|||
i--; |
|||
} |
|||
} |
|||
storage.set(constant.websocketData, state.websocketData) |
|||
|
|||
// 重置已读消息数量
|
|||
for(let i=0;i<store.state.chat.chatList.length;i++){ |
|||
if(store.state.chat.chatList[i].key == k){ |
|||
store.state.chat.chatList[i].messageNum = 0; |
|||
storage.set(constant.chatList, store.state.chat.chatList) |
|||
break; |
|||
} |
|||
} |
|||
store.commit('COUNT_MESSAGE'); |
|||
}, |
|||
// 统计消息总数
|
|||
COUNT_MESSAGE: (state) => { |
|||
let unReadNum = 0 |
|||
for(let i=0;i<store.state.chat.chatList.length;i++){ |
|||
unReadNum += store.state.chat.chatList[i].messageNum*1; |
|||
} |
|||
try{ |
|||
if(unReadNum > 0){ |
|||
uni.setTabBarBadge({ |
|||
index: getApp().globalData.msgTabBarIndex, |
|||
text: String(unReadNum), |
|||
fail: (e) => { |
|||
// console.log(e)
|
|||
} |
|||
}) |
|||
}else{ |
|||
uni.removeTabBarBadge({ |
|||
index: getApp().globalData.msgTabBarIndex |
|||
}) |
|||
} |
|||
}catch(e){ |
|||
|
|||
} |
|||
}, |
|||
// 清空消息
|
|||
CLEAN_MESSAGE: (state, message) => { |
|||
state.websocketData = new Array(); |
|||
storage.set(constant.websocketData, new Array()) |
|||
} |
|||
}, |
|||
|
|||
actions: { |
|||
// 连接websocket
|
|||
ConnSocket({ commit, state }, params) { |
|||
return new Promise((resolve, reject) => { |
|||
let url = params.url; |
|||
let heartbeatTimeout = 50000; // 心跳超时时间,单位:毫秒
|
|||
let reconnInterval = 5000; // 重连间隔时间,单位:毫秒
|
|||
let paramStr = "app=unine&token=" + params.token |
|||
let socket = new TioSocket(url, paramStr, heartbeatTimeout, reconnInterval); |
|||
socket.connect(false); |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
|
|||
export default socket |
@ -0,0 +1,26 @@ |
|||
const sessionCache = 'vrapile-im-session-cache' |
|||
const localCache = 'vrapile-im-local-cache' |
|||
|
|||
export function getSessionCache() { |
|||
return uni.getStorageSync(sessionCache) |
|||
} |
|||
|
|||
export function setSessionCache(cache) { |
|||
return uni.setStorageSync(sessionCache, cache) |
|||
} |
|||
|
|||
export function removeSessionCache() { |
|||
return uni.removeStorageSync(sessionCache) |
|||
} |
|||
|
|||
export function getLocalCache() { |
|||
return uni.getStorageSync(localCache) |
|||
} |
|||
|
|||
export function setLocalCache(cache) { |
|||
return uni.setStorageSync(localCache, cache) |
|||
} |
|||
|
|||
export function removeLocalCache() { |
|||
return uni.removeStorageSync(localCache) |
|||
} |
@ -0,0 +1,6 @@ |
|||
const constant = { |
|||
websocket: 'vuex_vrapile_im_websocket', |
|||
websocketData: 'vuex_vrapile_im_websocket_data' |
|||
} |
|||
|
|||
export default constant |
@ -0,0 +1,6 @@ |
|||
export default { |
|||
'401': '认证失败,无法访问系统资源', |
|||
'403': '当前操作没有权限', |
|||
'404': '访问资源不存在', |
|||
'default': '系统未知错误,请反馈给管理员' |
|||
} |
@ -0,0 +1,348 @@ |
|||
|
|||
export function isNull(o) { |
|||
if(o === 0 || o === "0"){ |
|||
return false; |
|||
} |
|||
if(o == "undefined" || o == null || o == ""){ |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
export function isPhone(o) { |
|||
if(/^1[23456789]\d{9}$/.test(o)){ |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
export function isMail(o) { |
|||
if(/^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$/.test(o)){ |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
export function isNumber(value) { |
|||
return !isNaN(parseFloat(value)) && isFinite(value) |
|||
} |
|||
export function isLetter(o) { |
|||
if(/^[A-Za-z]+$/.test(o)){ |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
export function isNumberOrLetter(o) { |
|||
if(/^[A-Za-z0-9]+$/.test(o)){ |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
// 日期格式化
|
|||
export function parseTime(time, pattern) { |
|||
if (arguments.length === 0 || !time) { |
|||
return null |
|||
} |
|||
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' |
|||
let date |
|||
if (typeof time === 'object') { |
|||
date = time |
|||
} else { |
|||
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { |
|||
time = parseInt(time) |
|||
} else if (typeof time === 'string') { |
|||
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), ''); |
|||
} |
|||
if ((typeof time === 'number') && (time.toString().length === 10)) { |
|||
time = time * 1000 |
|||
} |
|||
date = new Date(time) |
|||
} |
|||
const formatObj = { |
|||
y: date.getFullYear(), |
|||
m: date.getMonth() + 1, |
|||
d: date.getDate(), |
|||
h: date.getHours(), |
|||
i: date.getMinutes(), |
|||
s: date.getSeconds(), |
|||
a: date.getDay() |
|||
} |
|||
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { |
|||
let value = formatObj[key] |
|||
// Note: getDay() returns 0 on Sunday
|
|||
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } |
|||
if (result.length > 0 && value < 10) { |
|||
value = '0' + value |
|||
} |
|||
return value || 0 |
|||
}) |
|||
return time_str |
|||
} |
|||
|
|||
export function formatDate(time, option) { |
|||
if (('' + time).length === 10) { |
|||
time = parseInt(time) * 1000 |
|||
} else { |
|||
time = +time |
|||
} |
|||
|
|||
if (option) { |
|||
return parseTime(time, option) |
|||
} |
|||
|
|||
const d = new Date(time) |
|||
const now = Date.now() |
|||
|
|||
const diff = (now - d) / 1000 |
|||
|
|||
if (diff < 30) { |
|||
return '刚刚' |
|||
} else if (diff < 3600) { |
|||
// less 1 hour
|
|||
return Math.ceil(diff / 60) + '分钟前' |
|||
} else if (diff < 3600 * 24) { |
|||
return Math.ceil(diff / 3600) + '小时前' |
|||
} else if (diff < 3600 * 24 * 2) { |
|||
return '1天前' |
|||
} else if (diff < 3600 * 24 * 3) { |
|||
return '2天前' |
|||
} else if (diff < 3600 * 24 * 4) { |
|||
return '3天前' |
|||
} else if (diff < 3600 * 24 * 5) { |
|||
return '4天前' |
|||
} else if (diff < 3600 * 24 * 6) { |
|||
return '5天前' |
|||
} else if (diff < 3600 * 24 * 7) { |
|||
return '6天前' |
|||
} else if (diff < 3600 * 24 * 8) { |
|||
return '7天前' |
|||
} |
|||
if(diff < 3600 * 24 * 365) { |
|||
return ( |
|||
(d.getMonth()*1 + 1) + |
|||
'月' + |
|||
d.getDate() + |
|||
'日' |
|||
) |
|||
} else { |
|||
return ( |
|||
d.getFullYear() + |
|||
'年' + |
|||
(d.getMonth()*1 + 1) + |
|||
'月' |
|||
) |
|||
} |
|||
} |
|||
|
|||
export function formatTime(time, option) { |
|||
if (('' + time).length === 10) { |
|||
time = parseInt(time) * 1000 |
|||
} else { |
|||
time = +time |
|||
} |
|||
|
|||
if (option) { |
|||
return parseTime(time, option) |
|||
} |
|||
|
|||
const d = new Date(time) |
|||
const now = Date.now() |
|||
|
|||
const diff = (now - d) / 1000 |
|||
|
|||
return ( |
|||
d.getFullYear() + |
|||
'-' + |
|||
((d.getMonth()*1 + 1) + "").padStart(2,0) + |
|||
'-' + |
|||
(d.getDate() + '').padStart(2,0) + |
|||
' ' + |
|||
(d.getHours() + '').padStart(2,0) + |
|||
':' + |
|||
(d.getMinutes() + '').padStart(2,0) + |
|||
':' + |
|||
(d.getSeconds() + '').padStart(2,0) |
|||
) |
|||
} |
|||
|
|||
// number:要格式化的数字,
|
|||
// decimals:保留几位小数, 默认0位
|
|||
// dec_point:小数点符号, 默认 .
|
|||
// thousands_sep:千分位符号 默认 ,
|
|||
// tail_add: 小数点后面数据是否添加0补足位数, 默认空字符
|
|||
// null_default: 如果为空的值, 默认空字符
|
|||
function numberFormat(number, decimals, dec_point, thousands_sep, tail_add="", null_default="") { |
|||
number = (number + '').replace(/[^0-9+-Ee.]/g, ''); |
|||
var n = !isFinite(+number) ? 0 : +number, |
|||
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), |
|||
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, |
|||
dec = (typeof dec_point === 'undefined') ? '.' : dec_point, |
|||
s = '', |
|||
toFixedFix = function (n, prec) { |
|||
var k = Math.pow(10, prec); |
|||
return '' + Math.round(n * k) / k; |
|||
}; |
|||
|
|||
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.'); |
|||
var re = /(-?\d+)(\d{3})/; |
|||
if(sep.length > 0){ |
|||
while (re.test(s[0])) { |
|||
s[0] = s[0].replace(re, "$1" + sep + "$2"); |
|||
} |
|||
} |
|||
if ((s[1] || '').length < prec) { |
|||
s[1] = s[1] || ''; |
|||
s[1] += new Array(prec - s[1].length + 1).join(tail_add); |
|||
} |
|||
if((s[1] || '').length == 0){ |
|||
return s[0] |
|||
} |
|||
return s.join(dec); |
|||
} |
|||
// number:要格式化的数字,
|
|||
// decimals:保留几位小数, 默认0位
|
|||
// dec_point:小数点符号, 默认 .
|
|||
// thousands_sep:千分位符号 默认 ,
|
|||
// tail_add: 小数点后面数据是否添加0补足位数, 默认空字符
|
|||
// null_default: 如果为空的值, 默认空字符
|
|||
export function formatNumber(number, decimals, tail_add, thousands_sep, dec_point, null_default) { |
|||
if(isNull(number) || isNull(String(number).trim())){return null_default;} |
|||
if(!isNumber(String(number).trim())){return number;} |
|||
number = String(number).trim(); |
|||
return numberFormat(number, decimals, tail_add, thousands_sep, dec_point, null_default); |
|||
} |
|||
// thousands_sep:千分位符号 默认空字符
|
|||
export function formatPercent(number, decimals, tail_add, thousands_sep="", dec_point, null_default) { |
|||
if(isNull(number) || isNull(String(number).trim().replaceAll(",", ""))){return null_default;} |
|||
if(!isNumber(String(number).trim().replaceAll(",", ""))){return number;} |
|||
number = String(number).trim().replaceAll(",", ""); |
|||
let value = numberFormat(number*100, decimals, tail_add, thousands_sep, dec_point, null_default); |
|||
if(value){ |
|||
return value + "%"; |
|||
} |
|||
return ""; |
|||
} |
|||
|
|||
// get brower
|
|||
export function GetCurrentBrowser () { |
|||
let ua = navigator.userAgent.toLocaleLowerCase() |
|||
let browserType = null |
|||
if (ua.match(/msie/) != null || ua.match(/trident/) != null) { |
|||
browserType = 'IE' |
|||
} else if (ua.match(/firefox/) != null) { |
|||
browserType = 'firefox' |
|||
} else if (ua.match(/ucbrowser/) != null) { |
|||
browserType = 'UC' |
|||
} else if (ua.match(/opera/) != null || ua.match(/opr/) != null) { |
|||
browserType = 'opera' |
|||
} else if (ua.match(/bidubrowser/) != null) { |
|||
browserType = 'baidu' |
|||
} else if (ua.match(/metasr/) != null) { |
|||
browserType = 'sougou' |
|||
} else if (ua.match(/tencenttraveler/) != null || ua.match(/qqbrowse/) != null) { |
|||
browserType = 'QQ' |
|||
} else if (ua.match(/maxthon/) != null) { |
|||
browserType = 'maxthon' |
|||
} else if (ua.match(/chrome/) != null) { |
|||
var is360 = _mime('type', 'application/vnd.chromium.remoting-viewer') |
|||
if (is360) { |
|||
browserType = '360' |
|||
} else { |
|||
browserType = 'chrome' |
|||
} |
|||
} else if (ua.match(/safari/) != null) { |
|||
browserType = 'Safari' |
|||
} else { |
|||
browserType = 'others' |
|||
} |
|||
return browserType |
|||
} |
|||
|
|||
function _mime (option, value) { |
|||
var mimeTypes = navigator.mimeTypes |
|||
for (var mt in mimeTypes) { |
|||
if (mimeTypes[mt][option] === value) { |
|||
return true |
|||
} |
|||
} |
|||
return false |
|||
} |
|||
|
|||
// get os
|
|||
export function GetOs () { |
|||
let sUserAgent = navigator.userAgent.toLocaleLowerCase() |
|||
let isWin = (navigator.platform.toLocaleLowerCase() == 'win32') || (navigator.platform.toLocaleLowerCase() === 'windows') |
|||
let isMac = (navigator.platform.toLocaleLowerCase() === 'mac68k') || (navigator.platform.toLocaleLowerCase() === 'macppc') |
|||
|| (navigator.platform === 'macintosh') || (navigator.platform.toLocaleLowerCase() === 'macintel') |
|||
if (isMac) return 'Mac' |
|||
var isUnix = (navigator.platform === 'x11') && !isWin && !isMac |
|||
if (isUnix) return 'Unix' |
|||
var isLinux = (String(navigator.platform.toLocaleLowerCase()).indexOf('linux') > -1) |
|||
if (isLinux) return 'Linux' |
|||
if (isWin) { |
|||
var isWin2K = sUserAgent.indexOf('windows nt 5.0') > -1 || sUserAgent.indexOf('windows 2000') > -1 |
|||
if (isWin2K) return 'Win2000' |
|||
var isWinXP = sUserAgent.indexOf('windows nt 5.1') > -1 || sUserAgent.indexOf('windows xp') > -1 |
|||
if (isWinXP) return 'WinXP' |
|||
var isWin2003 = sUserAgent.indexOf('windows nt 5.2') > -1 || sUserAgent.indexOf('windows 2003') > -1 |
|||
if (isWin2003) return 'Win2003' |
|||
var isWinVista = sUserAgent.indexOf('windows nt 6.0') > -1 || sUserAgent.indexOf('windows vista') > -1 |
|||
if (isWinVista) return 'WinVista' |
|||
var isWin7 = sUserAgent.indexOf('windows nt 6.1') > -1 || sUserAgent.indexOf('windows 7') > -1 |
|||
if (isWin7) return 'Win7' |
|||
var isWin8 = sUserAgent.indexOf('windows nt 6.2') > -1 || sUserAgent.indexOf('windows 8') > -1 |
|||
if (isWin8) return 'Win8' |
|||
var isWin10 = sUserAgent.indexOf('windows nt 10.0') > -1 || sUserAgent.indexOf('windows nt 6.4') > -1 || sUserAgent.indexOf('windows 10') > -1 |
|||
if (isWin10) return 'Win10' |
|||
var isSimulator = sUserAgent.indexOf('linux') > -1 && sUserAgent.indexOf('android') > -1 |
|||
if (isSimulator) return 'Win手机模拟器' |
|||
return navigator.platform |
|||
} |
|||
if (sUserAgent.indexOf('android') > -1) return 'Android' |
|||
if (sUserAgent.indexOf('iphone') > -1) return 'iPhone' |
|||
if (sUserAgent.indexOf('symbianos') > -1) return 'SymbianOS' |
|||
if (sUserAgent.indexOf('windows phone') > -1) return 'Windows Phone' |
|||
if (sUserAgent.indexOf('ipad') > -1) return 'iPad' |
|||
if (sUserAgent.indexOf('ipod') > -1) return 'iPod' |
|||
return navigator.platform |
|||
} |
|||
|
|||
export function getRandom(len){ |
|||
let data = Math.random() + ""; |
|||
let index = 2; |
|||
while(data[index] == 0){ |
|||
index++; |
|||
} |
|||
return data.substr(index, len); |
|||
} |
|||
|
|||
export function getLongRandom(len){ |
|||
if(len <= 16){ |
|||
return getRandom(len) |
|||
} |
|||
let data = Math.random() + ""; |
|||
let index = 2; |
|||
while(data[index] == 0){ |
|||
index++; |
|||
} |
|||
return parseTime(Date.now(), '{y}{m}{d}{h}{i}{s}') + "" + data.substr(index, len-16); |
|||
} |
|||
|
|||
export function moveInArray(array, fromIndex, toIndex) { |
|||
const element = array.splice(fromIndex, 1)[0]; |
|||
array.splice(toIndex, 0, element); |
|||
} |
|||
|
|||
export function jsonCharBigInt(s){ |
|||
if(typeof s !== 'string'){ |
|||
return s |
|||
} |
|||
let re = /([\\]?['|"]{1})(\w+[\\]?['|"]{1}[ |\n|r|\t]*:[ |\n|r|\t]*)([-]?\d{15,})/g |
|||
return s.replaceAll(re, "$1$2$1$3$1") |
|||
} |
|||
|
|||
export function jsonParse(s){ |
|||
if(typeof s !== 'string'){ |
|||
return s |
|||
} |
|||
let re = /([\\]?['|"]{1})(\w+[\\]?['|"]{1}[ |\n|r|\t]*:[ |\n|r|\t]*)([-]?\d{15,})/g |
|||
return JSON.parse(s.replaceAll(re, "$1$2$1$3$1")) |
|||
} |
@ -0,0 +1,33 @@ |
|||
import constant from './constant' |
|||
|
|||
// 存储变量名
|
|||
let storageKey = 'vrapile_im_socket_storage_data' |
|||
|
|||
// 存储节点变量名
|
|||
let storageNodeKeys = [constant.chatList, constant.friendList, constant.groupList, |
|||
constant.userObject, constant.groupObject, constant.websocket, constant.websocketData] |
|||
|
|||
const storage = { |
|||
set: function(key, value) { |
|||
if (storageNodeKeys.indexOf(key) != -1) { |
|||
let tmp = uni.getStorageSync(storageKey) |
|||
tmp = tmp ? tmp : {} |
|||
tmp[key] = value |
|||
uni.setStorageSync(storageKey, tmp) |
|||
} |
|||
}, |
|||
get: function(key) { |
|||
let storageData = uni.getStorageSync(storageKey) || {} |
|||
return storageData[key] || "" |
|||
}, |
|||
remove: function(key) { |
|||
let storageData = uni.getStorageSync(storageKey) || {} |
|||
delete storageData[key] |
|||
uni.setStorageSync(storageKey, storageData) |
|||
}, |
|||
clean: function() { |
|||
uni.removeStorageSync(storageKey) |
|||
} |
|||
} |
|||
|
|||
export default storage |
@ -0,0 +1,181 @@ |
|||
import store from '@/uni_modules/vrapile-im/store' |
|||
|
|||
/** |
|||
* @param {*} url wss or ws |
|||
* @param {*} paramStr 加在ws url后面的请求参数,形如:name=张三&id=12 |
|||
* @param {*} heartbeatTimeout 心跳时间 单位:毫秒 |
|||
* @param {*} reconnInterval 重连间隔时间 单位:毫秒 |
|||
*/ |
|||
export class TioSocket { |
|||
constructor(url, paramStr, heartbeatTimeout, reconnInterval) { |
|||
this.firstUrl = url; |
|||
this.reconnUrl = url; |
|||
if (paramStr) { |
|||
this.firstUrl += '?' + paramStr; |
|||
this.reconnUrl += '?' + paramStr + "&reconnect=true"; |
|||
} else { |
|||
this.reconnUrl += "?reconnect=true"; |
|||
} |
|||
|
|||
this.closeByUser = false; |
|||
this.lockReconnect = false; |
|||
this.reconnectCount = 0; |
|||
|
|||
// 最后连接时间
|
|||
this.lastConnectTime = new Date().getTime(); |
|||
// 重连时间
|
|||
this.reconnInterval = reconnInterval; |
|||
// 心跳时间
|
|||
this.heartbeatTimeout = heartbeatTimeout; |
|||
|
|||
this.ws = null; |
|||
|
|||
this.connect = function(isReconnect) { |
|||
// 这里连接的时候,先关闭,避免出现多个连接
|
|||
uni.closeSocket({ |
|||
success:() => { |
|||
this.ws = uni.connectSocket({ |
|||
url: this.firstUrl, |
|||
success(res) { |
|||
console.log("WebSocket成功关闭,连接成功") |
|||
}, |
|||
fail(err) { |
|||
console.log("WebSocket成功关闭,连接失败:" + err) |
|||
} |
|||
}); |
|||
}, |
|||
fail:() => { |
|||
this.ws = uni.connectSocket({ |
|||
url: this.firstUrl, |
|||
success(res) { |
|||
console.log("WebSocket关闭失败,连接成功") |
|||
}, |
|||
fail(err) { |
|||
console.log("WebSocket关闭失败,连接失败:" + err) |
|||
} |
|||
}); |
|||
} |
|||
}) |
|||
|
|||
this.ws.onOpen((e) => { |
|||
if(!isReconnect){ |
|||
uni.sendSocketMessage({ |
|||
data: JSON.stringify({code:1}) |
|||
}) |
|||
store.commit('CLEAN_MESSAGE', {}) |
|||
} |
|||
this.reset(); |
|||
}) |
|||
|
|||
store.commit('SET_SOCKET', this) |
|||
this.ws.onMessage((e) => { |
|||
let data = JSON.parse(e.data); |
|||
if(data.code == 2){ |
|||
store.commit('ADD_MESSAGE', data.message) |
|||
} |
|||
this.reset(); |
|||
}) |
|||
|
|||
this.ws.onClose((e) => { |
|||
console.error("WebSocket关闭了:" + JSON.stringify(e)) |
|||
this.clearAllTimeoutTask(); |
|||
}) |
|||
|
|||
this.ws.onError((e) => { |
|||
console.error("WebSocket错误了:" + JSON.stringify(e)) |
|||
this.clearAllTimeoutTask(); |
|||
if(!this.closeByUser){ |
|||
this.reconn(); |
|||
} |
|||
}) |
|||
|
|||
return this.ws |
|||
} |
|||
|
|||
this.reconn = () => { |
|||
// 重连次数,防止疯狂重连导致系统挂掉
|
|||
if(this.reconnectCount++ > 10){ return;} |
|||
// 防止多个方法调用,多处重连
|
|||
if (this.lockReconnect) { return;} |
|||
this.lockReconnect = true; |
|||
this.reconnIntervalTask = setTimeout(() => { |
|||
this.ws = this.connect(true) |
|||
this.lockReconnect = false; |
|||
}, this.reconnInterval) |
|||
} |
|||
|
|||
this.ping = () => { |
|||
uni.sendSocketMessage({ |
|||
data: JSON.stringify({code:0}) |
|||
}) |
|||
}; |
|||
|
|||
this.send = (data) => { |
|||
uni.sendSocketMessage({ |
|||
data: data |
|||
}) |
|||
}; |
|||
|
|||
this.close = (bool) => { |
|||
this.lockReconnect = false; |
|||
this.closeByUser = bool; |
|||
uni.closeSocket({ |
|||
success:() => { |
|||
console.info("WebSocket关闭成功") |
|||
} |
|||
}) |
|||
}; |
|||
|
|||
this.reset = () => { |
|||
this.clearAllTimeoutTask(); |
|||
// 重置重连次数
|
|||
this.reconnectCount = 0; |
|||
// 重置最后连接时间
|
|||
this.lastConnectTime = new Date().getTime(); |
|||
// 启动心跳任务
|
|||
this.pingIntervalTask = setTimeout(() => { |
|||
this.ping(); |
|||
}, this.heartbeatTimeout); |
|||
} |
|||
|
|||
this.clearAllTimeoutTask = () => { |
|||
// 清除重连任务
|
|||
if (this.reconnIntervalTask) { |
|||
clearTimeout(this.reconnIntervalTask); |
|||
} |
|||
// 清除心跳任务
|
|||
if(this.pingIntervalTask){ |
|||
clearTimeout(this.pingIntervalTask) |
|||
} |
|||
} |
|||
|
|||
this.getReadyState = () => { |
|||
// CONNECTING:值为0,表示正在连接。
|
|||
// OPEN:值为1,表示连接成功,可以通信了。
|
|||
// CLOSING:值为2,表示连接正在关闭。
|
|||
// CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
|
|||
return this.ws.readyState; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取聊天唯一Key |
|||
* type 0-私聊,1-群里 |
|||
* chatId 聊天对象,好友ID或群聊ID |
|||
* fromId 发消息人ID |
|||
* |
|||
*/ |
|||
export function getChatKey(type, chatId, fromId) { |
|||
// 私聊
|
|||
if(type == 0){ |
|||
if(chatId*1 < fromId*1){ |
|||
return "im:message:friend-" + chatId + "-" + fromId |
|||
}else{ |
|||
return "im:message:friend-" + fromId + "-" + chatId |
|||
} |
|||
}else{ |
|||
return "im:message:group-" + chatId |
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
const sessionCache = 'session-cache' |
|||
const localCache = 'local-cache' |
|||
|
|||
export function getSessionCache() { |
|||
return uni.getStorageSync(sessionCache) |
|||
} |
|||
|
|||
export function setSessionCache(cache) { |
|||
return uni.setStorageSync(sessionCache, cache) |
|||
} |
|||
|
|||
export function removeSessionCache() { |
|||
return uni.removeStorageSync(sessionCache) |
|||
} |
|||
|
|||
export function getLocalCache() { |
|||
return uni.getStorageSync(localCache) |
|||
} |
|||
|
|||
export function setLocalCache(cache) { |
|||
return uni.setStorageSync(localCache, cache) |
|||
} |
|||
|
|||
export function removeLocalCache() { |
|||
return uni.removeStorageSync(localCache) |
|||
} |
@ -0,0 +1,8 @@ |
|||
const constant = { |
|||
avatar: 'vuex_avatar', |
|||
name: 'vuex_name', |
|||
userInfo: 'vuex_user_info', |
|||
loginInfo: 'vuex_login_info' |
|||
} |
|||
|
|||
export default constant |
@ -0,0 +1,6 @@ |
|||
export default { |
|||
'401': '认证失败,无法访问系统资源', |
|||
'403': '当前操作没有权限', |
|||
'404': '访问资源不存在', |
|||
'default': '系统未知错误,请反馈给管理员' |
|||
} |
xxxxxxxxxx