增加store存储 ,隐私协议,消息推送监听,聊天页适配,(home)
This commit is contained in:
parent
a6c701250b
commit
79822067b1
11
App.vue
11
App.vue
|
|
@ -1,17 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||
import { pushListener, checkNotificationAuthorized } from '@/utils/common'
|
||||
|
||||
// 定义全局数据
|
||||
const $globalData = {
|
||||
BASE_URL: 'https://dev.api.leapy.cn',
|
||||
RESOURCE_URL: 'https://resource.leapy.cn/staff/'
|
||||
}
|
||||
|
||||
// 使用 uni 对象来存储全局数据
|
||||
// @ts-ignore
|
||||
uni.$globalData = $globalData
|
||||
|
||||
onLaunch(() => {
|
||||
// #ifdef APP-NVUE
|
||||
// 检查是否开通消息通知权限
|
||||
checkNotificationAuthorized()
|
||||
//锁定屏幕方向
|
||||
plus.screen.lockOrientation('portrait-primary')
|
||||
// 监听消息
|
||||
pushListener()
|
||||
// #endif
|
||||
|
||||
console.log('App Launch')
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"version" : "1",
|
||||
"prompt" : "template",
|
||||
"title" : "用户协议和隐私政策",
|
||||
"message" : "请你务必审慎阅读、充分理解“用户协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"http://www.meirongya.com/user-policy.html\">《用户协议》</a>和<a href=\"http://www.meirongya.com/privacy_policy.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
|
||||
"buttonAccept" : "同意并接受",
|
||||
"buttonRefuse" : "暂不同意",
|
||||
"second" : {
|
||||
"title" : "确认提示",
|
||||
"message" : "进入应用前,你需先同意<a href=\"http://www.meirongya.com/user-policy.html\">《用户协议》</a>和<a href=\"http://www.meirongya.com/privacy_policy.html\">《隐私政策》</a>,否则将退出应用。",
|
||||
"buttonAccept" : "同意并继续",
|
||||
"buttonRefuse" : "退出应用"
|
||||
},
|
||||
"styles" : {
|
||||
"backgroundColor" : "#f7f7f7",
|
||||
"borderRadius" : "5px",
|
||||
"title" : {
|
||||
"color" : "#071a26"
|
||||
},
|
||||
"buttonAccept" : {
|
||||
"color" : "#006EEF"
|
||||
},
|
||||
"buttonRefuse" : {
|
||||
"color" : "#666666"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
<script type="module" src="/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
29
main.js
29
main.js
|
|
@ -1,29 +0,0 @@
|
|||
import App from './App'
|
||||
import * as Pinia from 'pinia';
|
||||
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import './uni.promisify.adaptor'
|
||||
Vue.config.productionTip = false
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import {
|
||||
createSSRApp
|
||||
} from 'vue'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.use(Pinia.createPinia());
|
||||
|
||||
return {
|
||||
app,
|
||||
Pinia
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import App from './App'
|
||||
import pinia from '@/stores/index'
|
||||
import {
|
||||
useUserInfo
|
||||
} from '@/stores/userInfo'
|
||||
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import './uni.promisify.adaptor'
|
||||
Vue.config.productionTip = false
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import {
|
||||
createSSRApp
|
||||
} from 'vue'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.use(pinia);
|
||||
|
||||
// 全局挂载 useUserInfo,使 nvue 页面可以使用
|
||||
const userInfoStore = useUserInfo()
|
||||
uni.$store = {
|
||||
state: userInfoStore.$state,
|
||||
commit: (name: string, value: any) => {
|
||||
userInfoStore[name](value)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
|
@ -46,7 +46,10 @@
|
|||
"dSYMs" : false
|
||||
},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
"sdkConfigs" : {},
|
||||
"splashscreen" : {
|
||||
"useOriginalMsgbox" : true
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"pinia-plugin-persistedstate": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -103,6 +103,13 @@
|
|||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "视频详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "chat/index",
|
||||
"style": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "聊天详情"
|
||||
}
|
||||
}
|
||||
]
|
||||
}],
|
||||
|
|
@ -110,7 +117,7 @@
|
|||
"current": 0, // 当前激活的条件,默认为 0
|
||||
"list": [{
|
||||
"name": "登录页", // 条件名称
|
||||
"path": "pages/login/index", // 要打开的页面路径
|
||||
"path": "pagesA/chat/index", // 要打开的页面路径
|
||||
"query": "" // 可选的页面参数
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
|
||||
const socketMessages = computed(() => {
|
||||
return uni.$store.state.token
|
||||
})
|
||||
|
||||
interface formItem {
|
||||
phone : string
|
||||
|
|
@ -67,6 +71,7 @@
|
|||
}
|
||||
|
||||
const login = () => {
|
||||
uni.$store.commit('setToken','11111111111111111')
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
<!-- list -->
|
||||
<view>
|
||||
<wd-swipe-action v-for="(item,index) in 6">
|
||||
<view class="li-bg-white li-px-30">
|
||||
<view @click="chatDetail" class="li-bg-white li-px-30">
|
||||
<view class="li-flex li-items-center li-bottom-border1 li-py-20">
|
||||
<wd-badge modelValue="12" top='10' right="2" :max='99'>
|
||||
<image class="li-w-100 li-h-100 li-rd-50%" src="/static/logo.png" mode=""></image>
|
||||
|
|
@ -77,6 +77,11 @@
|
|||
const handleAction = (action : string) => {
|
||||
console.log(action);
|
||||
}
|
||||
const chatDetail = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pagesA/chat/index'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<view :class="['message-item', detail.isRobotMessage?'':'message-item-my']">
|
||||
<view class="message-robot-wrap" v-if="detail.isRobotMessage">
|
||||
<view class="robot-icon">
|
||||
<image src="@/static/chat/bot2.png" mode=""></image>
|
||||
</view>
|
||||
<view class="text-message-wrap">
|
||||
{{ detail.message }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="message-wrap" v-else>
|
||||
{{ detail.message }}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
detail: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.message-item{
|
||||
display: flex;
|
||||
padding: 0 60rpx 32rpx 34rpx;
|
||||
.message-robot-wrap{
|
||||
display: flex;
|
||||
.robot-icon{
|
||||
height: 64rpx;
|
||||
width: 64rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #000;
|
||||
padding: 16rpx;
|
||||
margin-right: 16rpx;
|
||||
image{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.text-message-wrap{
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
color: #303437;
|
||||
font-size: 32rpx;
|
||||
padding: 32rpx;
|
||||
word-break: break-all;
|
||||
text-align: justify;
|
||||
border-radius: 0 48rpx 48rpx 48rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.message-item-my{
|
||||
justify-content: flex-end;
|
||||
padding-left: 114rpx;
|
||||
.message-wrap{
|
||||
background-color: #0070F0;
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
padding: 20rpx 32rpx;
|
||||
border-radius: 48rpx;
|
||||
word-break: break-all;
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
<template>
|
||||
<view class="chat-page">
|
||||
<view class="message-wrap">
|
||||
<scroll-view scroll-y enable-flex class="scroll-list" @scrolltolower="loadHistory" :scroll-top="scrollTop">
|
||||
<view class="message-item-wrap">
|
||||
<view v-for="(item, index) in messageList" :key="item.id" @click="onClick(index)">
|
||||
<MessageItem :detail="item"></MessageItem>
|
||||
</view>
|
||||
</view>
|
||||
<view class="loading-wrap" :style="{ display: loadingStatus?'':'none' }">
|
||||
<uni-load-more :iconSize="18" :status="loadingStatus" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- 键盘弹起占位 -->
|
||||
<view :style="{height: inputBottomValue}" :class="isKeyboardHidden"></view>
|
||||
</view>
|
||||
<!-- 消息输入 -->
|
||||
<view class="textarea-wrap" :class="isKeyboardHidden" :style="{ bottom: inputBottomValue}">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<textarea :show-confirm-bar='false' class="textarea" confirm-type="send" :auto-height="true"
|
||||
v-model="inputValue" :adjust-position="false" type="text" @confirm="sendMessage" confirm-hold />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<textarea :show-confirm-bar='false' class="textarea" confirm-type="send" :auto-height="true"
|
||||
v-model="inputValue" :adjust-position="platform=='ios'?true:false" type="text" @confirm="sendMessage"
|
||||
confirm-hold />
|
||||
<!-- #endif -->
|
||||
|
||||
<view class="send-btn" @tap="sendMessage">
|
||||
<image src="@/static/chat/enter_n.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view class="textarea-wrap" :style="{ bottom: inputBottomValue}">
|
||||
<textarea :show-confirm-bar='false' class="textarea" confirm-type="send" :auto-height="true"
|
||||
v-model="inputValue" :cursor-spacing="10" type="text" @confirm="sendMessage" confirm-hold />
|
||||
<view class="send-btn" @tap="sendMessage">
|
||||
<image src="@/static/chat/enter_n.png" mode=""></image>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
nextTick,
|
||||
computed
|
||||
} from 'vue';
|
||||
import {
|
||||
onHide,
|
||||
onShow,
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import MessageItem from './components/messageItem.vue';
|
||||
|
||||
const inputValue = ref('');
|
||||
const scrollTop = ref();
|
||||
const platform = ref('')
|
||||
onLoad(() => {
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
platform.value = res.platform
|
||||
console.log(platform.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 发送消息
|
||||
const sendMessage = () => {
|
||||
if ((inputValue.value ?? '') === '') return
|
||||
let newMessage = {
|
||||
id: messageList.value.length + 1,
|
||||
isRobotMessage: false,
|
||||
message: inputValue.value,
|
||||
}
|
||||
messageList.value.push(newMessage)
|
||||
inputValue.value = '';
|
||||
// 滚动到底部
|
||||
scrollTop.value = 0;
|
||||
nextTick(() => {
|
||||
scrollTop.value = undefined;
|
||||
})
|
||||
}
|
||||
|
||||
const messageList = ref([]); //消息列表
|
||||
const getMessageList = (num = 10) => {
|
||||
const messageData = new Array(num).fill(0).map((v, i) => {
|
||||
const id = messageList.value.length + i
|
||||
const random = Math.random();
|
||||
if (random < 0.33) {
|
||||
return {
|
||||
id: id,
|
||||
isRobotMessage: true,
|
||||
message: `(${id}):您好,我是您的专属客服达达,请问有什么可以帮您?`,
|
||||
}
|
||||
} else if (random >= 0.33 && random < 0.66) {
|
||||
return {
|
||||
id: id,
|
||||
isRobotMessage: true,
|
||||
message: `(${id}): 结果查询中...`,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
id: id,
|
||||
isRobotMessage: false,
|
||||
message: `(${id}): test english and digital messages. ahsdfhaksjdhfalspwqejhglaksjdf 4236784623847623423423487234234`,
|
||||
}
|
||||
}
|
||||
});
|
||||
messageList.value.unshift(...messageData.reverse());
|
||||
}
|
||||
getMessageList(5)
|
||||
|
||||
const loadingStatus = ref(); //'more' | 'loading' | 'no-more'
|
||||
const loadHistory = (e) => {
|
||||
if (loadingStatus.value && loadingStatus.value !== 'more') return
|
||||
loadingStatus.value = 'loading';
|
||||
setTimeout(() => {
|
||||
getMessageList()
|
||||
loadingStatus.value = 'more';
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const inputBottomValue = ref('0'); //输入框距离底部距离
|
||||
// 计算属性:判断是否应用keyboard-hidden类
|
||||
const isKeyboardHidden = computed(() => {
|
||||
return inputBottomValue.value === '0' && platform.value === 'ios' ? 'keyboard-hidden' : '';
|
||||
});
|
||||
|
||||
|
||||
// 监听键盘高度变化
|
||||
const keyboardChange = (res) => {
|
||||
// #ifdef MP-WEIXIN
|
||||
// res.height 为键盘高度
|
||||
if (res.height) { //展开
|
||||
inputBottomValue.value = res.height + 'px';
|
||||
} else { //收起
|
||||
// 键盘收起时,只需要很小的安全区域
|
||||
inputBottomValue.value = '0'
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
// res.height 为键盘高度
|
||||
if (res.height) { //展开
|
||||
if (platform.value === 'ios') {
|
||||
// iOS平台上要立即设置底部距离,避免出现空隙
|
||||
inputBottomValue.value = '0px';
|
||||
// 关键:用定时器来设置最终值,这样可以避免闪烁和空隙
|
||||
setTimeout(() => {
|
||||
inputBottomValue.value = '0px';
|
||||
}, 0);
|
||||
} else {
|
||||
// 非iOS平台保持原来逻辑
|
||||
inputBottomValue.value = res.height + 'px';
|
||||
}
|
||||
} else { //收起
|
||||
// 键盘收起时
|
||||
inputBottomValue.value = '0';
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
onHide(() => {
|
||||
uni.offKeyboardHeightChange(keyboardChange);
|
||||
})
|
||||
onShow(() => {
|
||||
uni.onKeyboardHeightChange(keyboardChange);
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chat-page {
|
||||
height: calc(100vh - 160rpx);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: rgb(240, 242, 247);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.message-wrap {
|
||||
height: 0;
|
||||
flex: 1;
|
||||
|
||||
.scroll-list {
|
||||
height: 100%;
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
.message-item-wrap {
|
||||
min-height: 100%;
|
||||
transform: scaleY(-1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.loading-wrap {
|
||||
transform: scaleY(-1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.textarea-wrap {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
padding: 25rpx 48rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
transition: all 0.1s ease-out;
|
||||
|
||||
.textarea {
|
||||
flex: 1;
|
||||
border-radius: 20rpx;
|
||||
background-color: #F1F7FB;
|
||||
padding: 15rpx 35rpx;
|
||||
min-height: 50rpx;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
height: 80rpx;
|
||||
width: 80rpx;
|
||||
padding: 16rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #0070F0;
|
||||
margin-left: 32rpx;
|
||||
transition: transform 0.2s ease;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
image {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.keyboard-hidden {
|
||||
/* #ifdef APP-PLUS || MP-WEIXIN */
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) - 20rpx);
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
view {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
page {
|
||||
background-color: rgb(240, 242, 247);
|
||||
}
|
||||
</style>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 647 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,10 @@
|
|||
import { createPinia } from 'pinia'
|
||||
import persist from 'pinia-plugin-persistedstate'
|
||||
|
||||
// 创建 pinia 实例
|
||||
const pinia = createPinia()
|
||||
// 使用持久化存储插件
|
||||
pinia.use(persist)
|
||||
|
||||
// 默认导出,给 main.ts 使用
|
||||
export default pinia
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
import { defineStore } from 'pinia'
|
||||
/**
|
||||
* 用户信息
|
||||
* @methods setUserInfos 设置用户信息
|
||||
*/
|
||||
export const useUserInfo = defineStore('userInfo', {
|
||||
state: (): UserInfosStates => ({
|
||||
userInfos: uni.getStorageSync('userInfo'),
|
||||
token: uni.getStorageSync('token'),
|
||||
}),
|
||||
actions: {
|
||||
async getUserInfo() {
|
||||
const res = await userInfoApi({})
|
||||
const data = res.data
|
||||
this.setUserInfos(data)
|
||||
return data
|
||||
},
|
||||
setUserInfos(userInfos) {
|
||||
// 存储用户信息到浏览器缓存
|
||||
uni.setStorageSync('userInfo', userInfos)
|
||||
this.userInfos = userInfos
|
||||
},
|
||||
setToken(token: string) {
|
||||
// 存储用户信息到浏览器缓存
|
||||
uni.setStorageSync('token', token)
|
||||
// 更新 store 状态
|
||||
this.token = token
|
||||
},
|
||||
logout() {
|
||||
uni.clearStorageSync()
|
||||
this.userInfos = '';
|
||||
this.token = '';
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
## 1.3.3(2022-01-20)
|
||||
- 新增 showText属性 ,是否显示文本
|
||||
## 1.3.2(2022-01-19)
|
||||
- 修复 nvue 平台下不显示文本的bug
|
||||
## 1.3.1(2022-01-19)
|
||||
- 修复 微信小程序平台样式选择器报警告的问题
|
||||
## 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-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
|
||||
## 1.2.1(2021-08-24)
|
||||
- 新增 支持国际化
|
||||
## 1.2.0(2021-07-30)
|
||||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||
## 1.1.8(2021-05-12)
|
||||
- 新增 组件示例地址
|
||||
## 1.1.7(2021-03-30)
|
||||
- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
|
||||
## 1.1.6(2021-02-05)
|
||||
- 调整为uni_modules目录规范
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"uni-load-more.contentdown": "Pull up to show more",
|
||||
"uni-load-more.contentrefresh": "loading...",
|
||||
"uni-load-more.contentnomore": "No more data"
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import en from './en.json'
|
||||
import zhHans from './zh-Hans.json'
|
||||
import zhHant from './zh-Hant.json'
|
||||
export default {
|
||||
en,
|
||||
'zh-Hans': zhHans,
|
||||
'zh-Hant': zhHant
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"uni-load-more.contentdown": "上拉显示更多",
|
||||
"uni-load-more.contentrefresh": "正在加载...",
|
||||
"uni-load-more.contentnomore": "没有更多数据了"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"uni-load-more.contentdown": "上拉顯示更多",
|
||||
"uni-load-more.contentrefresh": "正在加載...",
|
||||
"uni-load-more.contentnomore": "沒有更多數據了"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"id": "uni-load-more",
|
||||
"displayName": "uni-load-more 加载更多",
|
||||
"version": "1.3.3",
|
||||
"description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"加载更多",
|
||||
"load-more"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"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": ["uni-scss"],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "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"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
|
||||
### LoadMore 加载更多
|
||||
> **组件名:uni-load-more**
|
||||
> 代码块: `uLoadMore`
|
||||
|
||||
|
||||
用于列表中,做滚动加载使用,展示 loading 的各种状态。
|
||||
|
||||
|
||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
|
||||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||
|
||||
|
||||
|
|
@ -51,6 +51,22 @@
|
|||
.li-w-58{width:58rpx}
|
||||
.li-w-full-70{width:70%}
|
||||
.li-w-full-88{width:88%}
|
||||
.li-h-100{height:100rpx}
|
||||
.li-ml-20{margin-left:20rpx}
|
||||
.li-ml-200{margin-left:200rpx}
|
||||
.li-ml-30{margin-left:30rpx}
|
||||
.li-mr-10{margin-right:10rpx}
|
||||
.li-mr-30{margin-right:30rpx}
|
||||
.li-pt-2{padding-top:2rpx}
|
||||
.li-py-20{padding-top:20rpx;padding-bottom:20rpx}
|
||||
.li-rd-full-50{border-radius:50%}
|
||||
.li-text-25{font-size:25rpx}
|
||||
.li-text-35{font-size:35rpx}
|
||||
.li-text-38{font-size:38rpx}
|
||||
.li-text-42{font-size:42rpx}
|
||||
.li-text-46{font-size:46rpx}
|
||||
.li-w-100{width:100rpx}
|
||||
.li-w-full-80{width:80%}
|
||||
.li-font-550{font-weight:550}
|
||||
.li-h-68{height:68rpx}
|
||||
.li-mt-100{margin-top:100rpx}
|
||||
|
|
@ -63,27 +79,11 @@
|
|||
.li-rd-40{border-radius:40rpx}
|
||||
.li-text-000000-color{color:rgb(0,0,0)}
|
||||
.li-text-2EA1EA-color{color:rgb(46,161,234)}
|
||||
.li-text-38{font-size:38rpx}
|
||||
.li-text-a5a5a5-color{color:rgb(165,165,165)}
|
||||
.li-w-150{width:150rpx}
|
||||
.li-w-420{width:420rpx}
|
||||
.li-w-full-80{width:80%}
|
||||
.li-w-full-85{width:85%}
|
||||
.li-w-full-90{width:90%}
|
||||
.li-h-100{height:100rpx}
|
||||
.li-ml-20{margin-left:20rpx}
|
||||
.li-ml-200{margin-left:200rpx}
|
||||
.li-ml-30{margin-left:30rpx}
|
||||
.li-mr-10{margin-right:10rpx}
|
||||
.li-mr-30{margin-right:30rpx}
|
||||
.li-pt-2{padding-top:2rpx}
|
||||
.li-py-20{padding-top:20rpx;padding-bottom:20rpx}
|
||||
.li-rd-full-50{border-radius:50%}
|
||||
.li-text-25{font-size:25rpx}
|
||||
.li-text-35{font-size:35rpx}
|
||||
.li-text-42{font-size:42rpx}
|
||||
.li-text-46{font-size:46rpx}
|
||||
.li-w-100{width:100rpx}
|
||||
.bg-FFFFFF{background-color:rgb(255,255,255)}
|
||||
.bg-f9f9f9{background-color:rgb(249,249,249)}
|
||||
.border-4-white{border-style:solid;border-color:rgb(255,255,255);border-width:4rpx}
|
||||
|
|
@ -142,6 +142,12 @@
|
|||
.li-text-ff0000-color{color:rgb(255,0,0)}
|
||||
.li-w-full-100{width:100%}
|
||||
.li-w-full-92{width:92%}
|
||||
.li-mb-25{margin-bottom:25rpx}
|
||||
.li-text-009aff-color{color:rgb(0,154,255)}
|
||||
.li-text-999-color{color:rgb(153,153,153)}
|
||||
.li-font-400{font-weight:400}
|
||||
.li-m-30{margin:30rpx}
|
||||
.li-text-595959-color{color:rgb(89,89,89)}
|
||||
|
||||
.li-bottom-0{bottom:0}
|
||||
.li-fixed{position:fixed}
|
||||
|
|
@ -160,7 +166,6 @@
|
|||
.li-py-35{padding-top:35rpx;padding-bottom:35rpx}
|
||||
.li-py-6{padding-top:6rpx;padding-bottom:6rpx}
|
||||
.li-rd-bl-50-important{border-bottom-left-radius:50rpx !important}
|
||||
.li-text-009aff-color{color:rgb(0,154,255)}
|
||||
.li-text-40{font-size:40rpx}
|
||||
.li-text-5f5f5f-color{color:rgb(95,95,95)}
|
||||
.li-text-right{text-align:right}
|
||||
|
|
@ -168,7 +173,5 @@
|
|||
.li-w-400{width:400rpx}
|
||||
.overflow-hidden{overflow:hidden}
|
||||
|
||||
.li-mb-25{margin-bottom:25rpx}
|
||||
.li-text-999-color{color:rgb(153,153,153)}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* 将分转换为元(保留2位小数,带千分位)
|
||||
* @param cent 分为单位的金额
|
||||
* @returns 元为单位的金额字符串(带千分位)
|
||||
*/
|
||||
export const centToYuanWithComma = (cent : number) : string => {
|
||||
if (!cent && cent !== 0) return '0.00'
|
||||
return (cent / 100).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
}
|
||||
|
||||
/**
|
||||
* 将秒转换为小时(保留2位小数)
|
||||
* @param seconds 秒数
|
||||
* @returns 小时数(字符串格式,保留2位小数)
|
||||
*/
|
||||
export const secondsToHours = (seconds : number) : string => {
|
||||
if (!seconds && seconds !== 0) return '0.00'
|
||||
return (seconds / 3600).toFixed(2)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 检查app是否开启了通知权限 安卓苹果通用
|
||||
export const checkNotificationAuthorized = () => {
|
||||
const notificationAuthorized = uni.getAppAuthorizeSetting().notificationAuthorized
|
||||
if (notificationAuthorized !== 'authorized') {
|
||||
uni.showModal({
|
||||
title: '通知权限',
|
||||
content: '您还没有开启通知权限,无法接受到消息通知,请前往设置!',
|
||||
confirmText: '去设置',
|
||||
showCancel: false,
|
||||
success: (res) => {
|
||||
if (res.confirm) uni.openAppAuthorizeSetting()
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 监听消息推送
|
||||
export const pushListener = () => {
|
||||
//收到透传消息
|
||||
//只有APP在线时,才会触发receive事件,透传消息不会触发系统消息,需要创建本地消息
|
||||
plus.push.addEventListener(
|
||||
'receive',
|
||||
function (msg) {
|
||||
console.log('111')
|
||||
console.log('(receive):' + JSON.stringify(msg))
|
||||
if (plus.os.name == 'Android') {
|
||||
plus.push.createMessage(msg.content, msg.payload, {
|
||||
title: msg.title,
|
||||
})
|
||||
if (msg.payload.audio) {
|
||||
audioPlayer(msg.payload.audio)
|
||||
}
|
||||
// getApp().globalData.msgReadNum++
|
||||
// plus.runtime.setBadgeNumber(getApp().globalData.msgReadNum)
|
||||
} else if (plus.os.name == 'iOS') {
|
||||
// ios
|
||||
if (msg.aps == null && msg.type == 'receive') {
|
||||
var option = {
|
||||
cover: true,
|
||||
title: msg.title,
|
||||
}
|
||||
plus.push.createMessage(msg.payload.body, msg.payload, option)
|
||||
// getApp().globalData.msgReadNum++
|
||||
// plus.runtime.setBadgeNumber(getApp().globalData.msgReadNum)
|
||||
}
|
||||
}
|
||||
},
|
||||
false,
|
||||
)
|
||||
|
||||
//消息点击事件
|
||||
//【APP在线】,收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。
|
||||
//【APP离线】,收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发。
|
||||
plus.push.addEventListener(
|
||||
'click',
|
||||
function (msg) {
|
||||
console.log('2222')
|
||||
console.log('(click):' + JSON.stringify(msg))
|
||||
if (plus.os.name == 'iOS') {
|
||||
//如果是IOS
|
||||
var payload
|
||||
if (msg.type == 'click') {
|
||||
//APP离线点击包含click属性,这时payload是JSON对象
|
||||
payload = msg.payload
|
||||
} else {
|
||||
//APP在线,收到消息不会包含type属性,这时的payload是JSON字符串,需要转为JSON对象
|
||||
payload = JSON.parse(msg.payload)
|
||||
}
|
||||
if (payload != null || payload != undefined) {
|
||||
var messageType = payload.messageType
|
||||
// messageClick(messageType, payload);
|
||||
}
|
||||
}
|
||||
if (plus.os.name == 'Android') {
|
||||
console.log('Android', msg.payload)
|
||||
if (msg.payload) {
|
||||
uni.navigateTo({
|
||||
url: msg.payload.url,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
获取城市编码
|
||||
*/
|
||||
export const getCityCode = async (longitude : number, latitude : number) : Promise<any> => {
|
||||
const apiKey = '' // 高德地图 API Key
|
||||
const url = `https://restapi.amap.com/v3/geocode/regeo?key=${apiKey}&location=${longitude},${latitude}&output=json`
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
url,
|
||||
success: (res) => {
|
||||
console.log(res.data, 'res.data')
|
||||
if (res.data && res.data.regeocode && res.data.regeocode.addressComponent) {
|
||||
// console.log(res.data.regeocode.addressComponent,'res.data.regeocode.addressComponent');
|
||||
const cityCode = res.data.regeocode.addressComponent.citycode // 获取城市编码
|
||||
resolve({ data: res.data, cityCode })
|
||||
} else {
|
||||
reject('无法获取当前城市位置')
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('获取城市位置失败:', err)
|
||||
reject(err)
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
Loading…
Reference in New Issue