调整iconfont图标缺失

This commit is contained in:
唐明明
2022-02-14 17:16:27 +08:00
71 changed files with 6023 additions and 3894 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -14,6 +14,10 @@
{ {
"launchtype" : "local" "launchtype" : "local"
}, },
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud" "type" : "uniCloud"
} }
] ]

View File

@@ -1,5 +1,7 @@
<script> <script>
import { getVersions } from './apis/interfaces/versions' import {
getVersions
} from './apis/interfaces/versions'
import im from '@/utils/im/index.js' import im from '@/utils/im/index.js'
export default { export default {

View File

@@ -9,9 +9,10 @@ import { request } from '../index'
/** /**
* @description:饮水记录首页 * @description:饮水记录首页
*/ */
const waters = () => { const waters = (data) => {
return request({ return request({
url: 'health/waters', url: 'health/waters',
data:data
}) })
} }
/** /**
@@ -29,10 +30,11 @@ const setWaters = (data) => {
* @description:喝水 * @description:喝水
* @Date: 2022-01-12 125600 * @Date: 2022-01-12 125600
*/ */
const drinkWater = () => { const drinkWater = (data) => {
return request({ return request({
url: 'health/waters/drink', url: 'health/waters/drink',
method: 'POST', method: 'POST',
data:data
}) })
} }
/** /**
@@ -46,10 +48,24 @@ const delDrinkWater = (id) => {
}) })
} }
/**
* @description:饮食运动日历
* @params {日期}
* @method {get}
* @Date: 2022-02-08 11点18分
*/
const dateList = (data) => {
return request({
url: 'health/calendar/water',
data:data
})
}
export { export {
waters, waters,
setWaters, setWaters,
drinkWater, drinkWater,
delDrinkWater delDrinkWater,
dateList
} }

View File

@@ -78,11 +78,24 @@ const delHealthFoods = (intake_id) => {
}) })
} }
/**
* @description:饮食运动日历
* @params {日期}
* @method {get}
* @Date: 2022-02-07 15点18分
*/
const dateList = (data) => {
return request({
url: 'health/calendar/intake',
data:data
})
}
export { export {
positions, positions,
plans, plans,
healthFoods, healthFoods,
addHealthFoods, addHealthFoods,
editHealthFoods, editHealthFoods,
delHealthFoods delHealthFoods,
dateList
} }

View File

@@ -11,6 +11,13 @@ import {
// 获取好友列表 // 获取好友列表
const getFriends = () => { const getFriends = () => {
return request({
url: 'im/friends',
}, true)
}
// 获取好友列表
const getFriendsLetter = () => {
return request({ return request({
url: 'im/friends/letter', url: 'im/friends/letter',
}, true) }, true)
@@ -85,55 +92,121 @@ const pedingFriend = (recipient) => {
}) })
} }
/** // 以下是群组相关业务的接口
* 好友申请数量 const getMyGroups = () => {
*/
const getPendingCount = () => {
return request({ return request({
url: 'im/friends/pending/count' url: 'im/groups'
}) })
} }
/** /**
* 上传聊天附件 * 获取群信息,包含基础信息和 14 个用户
* 图片
* 语音
* 视频
*/ */
// 基础配置 const getGroupInfo = (groupId) => {
const config = { return request({
apiUrl: 'http://api.zh.shangkelian.cn/api/', // 正式环境 url: 'im/groups/' + groupId
timeout: 60000 })
} }
const uploadMessageFile = (file, type) => { /**
config.header = { * 群组基础信息
'Accept': 'application/json', */
'Authorization': store.getters.getToken || '' const getGroupBase = (groupId) => {
return request({
url: 'im/groups/' + groupId + '/base'
})
} }
return new Promise((resolve, reject) => {
uni.uploadFile({ const getGroupUsers = (groupId) => {
url: config.apiUrl + 'im/upload', return request({
filePath: file, url: 'im/groups/' + groupId + '/users'
name: 'upload', })
formData: {
type
},
header: config.header || {},
success: (res) => {
if (res.statusCode === 200) {
let updData = JSON.parse(res.data)
if (updData.status_code === 200) {
resolve(updData.data)
} else {
reject(updData)
} }
const getGroupAnnouncements = (groupId) => {
return request({
url: 'im/groups/' + groupId + '/announcements'
})
} }
},
fail: (err) => { const createGroupAnnouncement = (groupId, content) => {
console.log('ERR', err); return request({
method: 'POST',
url: 'im/groups/' + groupId + '/announcements',
data: {
content: content
} }
}) })
}
const deleteGroupAnnouncement = (groupId, announcementId) => {
return request({
method: 'DELETE',
url: 'im/groups/' + groupId + '/announcements/' + announcementId
})
}
/**
* 创建群聊
*/
const createGroup = (data) => {
return request({
method: 'POST',
url: 'im/groups',
data: data
})
}
const updateGroup = (groupId, data) => {
return request({
method: 'PUT',
url: 'im/groups/' + groupId,
data: data
})
}
/**
* 搜索群聊
*/
const searchGroup = (name) => {
return request({
url: 'im/groups/search?name=' + name
})
}
/**
* 加群前,获取的群信息
*/
const joinGroupPre = (groupId) => {
return request({
url: 'im/groups/' + groupId + '/join'
})
}
const joinGroup = (groupId, message) => {
return request({
method: 'POST',
url: 'im/groups/' + groupId + '/join',
data: {
message
}
})
}
const quitGroup = (groupId) => {
return request({
method: 'POST',
url: 'im/groups/' + groupId + '/quit'
})
}
/**
* 解散群聊
*/
const dismissGroup = (groupId) => {
return request({
method: 'DELETE',
url: 'im/groups/' + groupId
}) })
} }
@@ -141,6 +214,7 @@ export {
getImToken, getImToken,
deleteFriend, deleteFriend,
getFriends, getFriends,
getFriendsLetter,
getUserInfo, getUserInfo,
getFriendInfo, getFriendInfo,
getPedings, getPedings,
@@ -148,6 +222,18 @@ export {
rejectFriend, rejectFriend,
searchFriend, searchFriend,
pedingFriend, pedingFriend,
getPendingCount, getMyGroups,
uploadMessageFile createGroup,
updateGroup,
getGroupInfo,
getGroupBase,
getGroupUsers,
getGroupAnnouncements,
createGroupAnnouncement,
deleteGroupAnnouncement,
searchGroup,
joinGroupPre,
joinGroup,
quitGroup,
dismissGroup
} }

View File

@@ -6,6 +6,7 @@
* @LastEditTime: 2022-01-12 17:13:45 * @LastEditTime: 2022-01-12 17:13:45
*/ */
import { request } from '../index' import { request } from '../index'
/** /**
* @description:称量体重模块首页 * @description:称量体重模块首页
*/ */
@@ -15,6 +16,16 @@ const weights = (page) => {
data: { page: page } data: { page: page }
}) })
} }
/**
* @description:获取曲线进度
*/
const curves = () => {
return request({
url: 'health/weights/bight'
})
}
/** /**
* @description:记录体重 * @description:记录体重
* @Date: 2022-01-12 16:46:19 * @Date: 2022-01-12 16:46:19
@@ -26,7 +37,9 @@ const addWeight = (data) => {
data: data data: data
}) })
} }
export { export {
weights, weights,
addWeight addWeight,
curves
} }

View File

@@ -0,0 +1,330 @@
<!--
* @Description:日历模板
* @Author: Aimee·Zhang
* @Date: 2022-02-08 09:06:45
* @LastEditors: Aimee·Zhang
* @LastEditTime: 2022-02-08 09:06:45
-->
<template>
<view class="date">
<u-popup :show="dateShow" zIndex="10099890" @close="closeDate" mode="bottom" :safeAreaInsetBottom="true">
<view class="date-content">
<view class="title"><span @click="datePreNext('before')">上一月</span>{{month}}<span
@click="datePreNext('after')">下一月</span></view>
<view class="date-item">
<view class="week">
<view class="week-item" v-for="(item,index) in weekList" :key="index">{{item}}</view>
</view>
<!-- 饮食模块 -->
<block v-if="type === 'foods'">
<view class="week" style="padding-top: 30rpx;">
<view v-for="item in lists" :key="item.today" @click="dateClick(item)"
:class="['week-item',{'is_past':!item.is_month},{'is_today':item.today === today},{'is_intake0':item.intake === 1},{'is_intake1':item.intake === 2},{'is_intake2':item.intake === 3}]">
{{item.day}}
</view>
</view>
<view class="des">
<block> <view class="des-item">吃少了</view> <view class="des-item">正好</view> <view class="des-item">吃多了</view> </block>
<view class="back" @click="backDate"> 回今天 </view>
</view>
</block>
<!-- 喝水模块 -->
<block v-if="type === 'drink'">
<view class="week" style="padding-top: 30rpx;">
<view v-for="item in lists" :key="item.today" @click="dateClick(item)" :class="['week-item',{'is_past':!item.is_month},{'is_today':item.today === today}]">
{{item.day}}
<u-image class='waterIcon' :src="require('@/static/imgs/water-1.png')" v-if="item.drink === 2" :lazy-load="true" width="20rpx" radius="10rpx" mode="widthFix" />
<u-image class='waterIcon' :src="require('@/static/imgs/water-2.png')" v-if="item.drink === 1" :lazy-load="true" width="20rpx" radius="10rpx" mode="widthFix" />
</view>
</view>
<view class="drink">
<block>
<view class="drink-item">
<u-image class='waterIcon' :src="require('@/static/imgs/water-1.png')" :lazy-load="true" width="22rpx" radius="10rpx" mode="widthFix" />未完成指标
</view>
<view class="drink-item">
<u-image class='waterIcon' :src="require('@/static/imgs/water-2.png')" :lazy-load="true" width="22rpx" radius="10rpx" mode="widthFix" /> 完成指标
</view>
</block>
<view class="back" @click="backDate"> 回今天 </view>
</view>
</block>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import moment from 'moment';
export default {
data() {
return {
weekList: ['日', '一', '二', '三', '四', '五', '六'],
};
},
props: {
/**
* lists 传过来的列表
* type foods食物运动 drink饮水weight体重
* today 勾选时间
* month 勾选日期
* dateShow 页面是否显示
**/
lists: {
type: Array,
default: [],
},
type: {
type: String,
default: "",
},
today: {
type: String,
default: moment(new Date()).format('YYYY-MM-DD')
},
month: {
type: String,
default: moment(new Date()).format('YYYY-MM')
},
dateShow: {
type: Boolean,
default: false
}
},
methods: {
// 选择日期
dateClick(item) {
this.$emit('dateClick', item)
},
// 返回今天
backDate() {
this.$emit('backDate', '')
},
// 点击上一个月或者下一个月 before 上一月 after下一个月
datePreNext(type) {
this.$emit('datePreNext', type)
},
// 关闭日历
closeDate() {
this.$emit('closeDate')
}
},
};
</script>
<style lang="scss" scoped>
.date {
// 日历弹窗
.date-content {
width: 100%;
padding: $padding *2;
min-height: 800rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
box-sizing: border-box;
.title {
font-size: $title-size + 4;
color: #20845f;
font-weight: bold;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
width: 100%;
span {
display: inline-block;
padding: $padding;
font-size: $title-size-m;
color: #cacaca;
font-weight: normal;
}
}
.date-item {
padding-top: $padding;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
.drink {
display: flex;
color: #cacaca;
flex-direction: row;
align-items: center;
box-sizing: border-box;
font-size: $title-size-m;
justify-content: center;
margin-top: $margin;
width: 100%;
.drink-item {
padding-right: 40rpx;
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
box-sizing: border-box;
u-image{
padding-right: 10rpx;
}
}
}
.des {
display: flex;
color: #cacaca;
flex-direction: row;
align-items: center;
box-sizing: border-box;
font-size: $title-size-m;
justify-content: center;
margin-top: $margin;
width: 100%;
.des-item {
padding-left: 40rpx;
padding-right: 10rpx;
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
box-sizing: border-box;
&:before {
content: '';
position: absolute;
left: 14rpx;
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background: #fa624d;
}
&:nth-child(2):before {
background: #fbbf0f;
}
&:nth-child(1):before {
background: #02c7bd;
}
}
}
.back {
margin-left: 100rpx;
background-color: rgba($color: $main-color, $alpha: 1);
color: #fff;
padding: 10rpx $padding;
border-radius: $radius + 10;
}
}
.week {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
box-sizing: border-box;
flex-wrap: wrap;
width: 100%;
.week-item {
width: 14.28%;
height: 90rpx;
line-height: 90rpx;
font-size: $title-size-m + 2;
color: #888;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
&::before {
content: '';
width: 14rpx;
height: 14rpx;
border-radius: 50%;
position: absolute;
bottom: 0;
// background: #02c7bd;
}
}
.waterIcon {
position: absolute;
width: 30rpx !important;
bottom: -12rpx;
padding-left: 10rpx;
}
&:nth-child(1),
&:nth-child(7),
&:nth-child(8),
&:nth-child(14),
&:nth-child(15),
&:nth-child(21),
&:nth-child(22),
&:nth-child(28),
&:nth-child(29),
&:nth-child(35),
{
color: rgba($color: #000000, $alpha: 0.4);
}
}
// 吃饭样式
.is_intake0::before {
background: #02c7bd !important;
}
.is_intake1::before {
background: #fbbf0f !important;
}
.is_intake2::before {
background: #fa624d !important;
}
.is_today {
color: #fff !important;
position: relative;
z-index: 1;
&:after {
content: '';
width: 50rpx;
height: 50rpx;
position: absolute;
border-radius: 50%;
background-color: $main-color;
color: #Fff;
z-index: -1;
}
}
.is_past {
color: rgba($color: #000000, $alpha: 0.1) !important;
}
}
}
</style>

View File

@@ -2,8 +2,8 @@
"name" : "ZH-HEALTH", "name" : "ZH-HEALTH",
"appid" : "__UNI__C29473D", "appid" : "__UNI__C29473D",
"description" : "ZH-HEALTH您手上的健康管理专家", "description" : "ZH-HEALTH您手上的健康管理专家",
"versionName" : "1.0.7", "versionName" : "1.0.8",
"versionCode" : 107, "versionCode" : 108,
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus" : {

View File

@@ -35,9 +35,8 @@
"path": "pages/record/drink", "path": "pages/record/drink",
"name": "Drink", "name": "Drink",
"style": { "style": {
"navigationBarTitleText": "记录喝水", "navigationBarTitleText": "记录",
"navigationBarBackgroundColor": "#34CE98", "navigationStyle": "custom"
"navigationBarTextStyle": "white"
} }
}, },
{ {
@@ -53,9 +52,8 @@
"path": "pages/record/foods", "path": "pages/record/foods",
"name": "RecordFoods", "name": "RecordFoods",
"style": { "style": {
"navigationBarTitleText": "食物记录", "navigationBarTitleText": "",
"navigationBarBackgroundColor": "#34CE98", "navigationStyle": "custom"
"navigationBarTextStyle": "white"
} }
}, },
{ {
@@ -80,7 +78,7 @@
"path": "pages/evaluation/list", "path": "pages/evaluation/list",
"name": "EvaluationList", "name": "EvaluationList",
"style": { "style": {
"navigationBarTitleText": "评测列表", "navigationBarTitleText": "健康评测",
"navigationBarBackgroundColor": "#34CE98", "navigationBarBackgroundColor": "#34CE98",
"navigationBarTextStyle": "white" "navigationBarTextStyle": "white"
} }
@@ -369,10 +367,18 @@
"path": "pages/im/index", "path": "pages/im/index",
"name": "IM", "name": "IM",
"style": { "style": {
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{
"path": "pages/im/private/chat",
"style": {
"disableScroll": true,
"navigationBarTitleText": "聊天",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#F3F6FB"
}
},
{ {
"path": "pages/im/private/call", "path": "pages/im/private/call",
"name": "imPrivateCall", "name": "imPrivateCall",
@@ -402,40 +408,110 @@
"path": "pages/im/friends/pending", "path": "pages/im/friends/pending",
"name": "imFriendsPending", "name": "imFriendsPending",
"style": { "style": {
"navigationBarTitleText": "新朋友", "navigationBarTitleText": "新朋友"
"navigationBarBackgroundColor": "#F3F6FB"
} }
}, },
{ {
"path": "pages/im/friends/search", "path": "pages/im/friends/search",
"name": "SearchFriend", "name": "SearchFriend",
"style": { "style": {
"navigationBarTitleText": "好友搜索", "navigationBarTitleText": "好友搜索"
"navigationBarBackgroundColor": "#F3F6FB"
} }
}, },
{ {
"path": "pages/im/friends/info", "path": "pages/im/friends/info",
"name": "imFriendsInfo", "name": "imFriendsInfo",
"style": { "style": {
"navigationBarTitleText": "好友资料", "navigationBarTitleText": "用户资料"
"navigationBarBackgroundColor": "#FFFFFF"
} }
}, },
{ {
"path": "pages/im/friends/mine", "path": "pages/im/friends/mine",
"name": "imFriendsMine", "name": "imFriendsMine",
"style": { "style": {
"navigationBarTitleText": "我的二维码", "navigationBarTitleText": "我的资料"
"navigationBarBackgroundColor": "#34CE98",
"navigationBarTextStyle": "white"
} }
}, },
{ {
"path": "pages/im/group/index", "path": "pages/im/group/index",
"name": "imGroup", "name": "imGroups",
"style": { "style": {
"navigationBarTitleText": "我的群聊" "navigationBarTitleText": "我的群聊",
"app-plus": {
"titleNView": {
"type": "default",
"buttons": [{
"float": "right",
"fontSrc": "/static/iconfont.ttf",
"text": "\ue60a",
"fontSize": "20px"
}]
}
}
}
},
{
"path": "pages/im/group/chat",
"name": "imGroupChat",
"style": {
"navigationBarTitleText": "群聊",
"app-plus": {
"titleNView": {
"type": "default",
"buttons": [{
"float": "right",
"fontSrc": "/static/iconfont.ttf",
"text": "\ue607",
"fontSize": "20px"
}]
}
}
}
},
{
"path": "pages/im/group/apply",
"name": "imGroupApply",
"style": {
"navigationBarTitleText": "申请加群"
}
},
{
"path": "pages/im/group/info",
"name": "imGroupInfo",
"style": {
"navigationBarTitleText": "群信息"
}
},
{
"path": "pages/im/group/users",
"name": "imGroupUsers",
"style": {
"navigationBarTitleText": "群成员"
}
},
{
"path": "pages/im/group/announcement",
"name": "imGroupAnnouncement",
"style": {
"navigationBarTitleText": "群公告",
"app-plus": {
"titleNView": {
"type": "default",
"buttons": [{
"float": "right",
"fontSrc": "/static/iconfont.ttf",
"text": "\ue60a",
"fontSize": "20px"
}]
}
}
}
},
{
"path": "pages/im/group/announceCreate",
"name": "imGroupAnnouncementCreate",
"style": {
"navigationBarTitleText": "发布群公告"
} }
}, },
{ {
@@ -548,14 +624,6 @@
"navigationBarBackgroundColor": "#34CE98", "navigationBarBackgroundColor": "#34CE98",
"navigationBarTextStyle": "white" "navigationBarTextStyle": "white"
} }
}, {
"path": "pages/im/private/chat",
"style": {
"disableScroll": true,
"navigationBarTitleText": "聊天",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#F3F6FB"
}
} }
], ],
"tabBar": { "tabBar": {

View File

@@ -2,21 +2,10 @@
<view class="content"> <view class="content">
<!-- tool --> <!-- tool -->
<view class="tool-flex"> <view class="tool-flex">
<view <view class="tool-flex-item" @click="$Router.back()">
class="tool-flex-item" <uni-icons type="closeempty" size="22" color="#666"></uni-icons>
@click="$Router.back()"
>
<uni-icons
type="closeempty"
size="22"
color="#666"
></uni-icons>
</view> </view>
<view <view class="tool-flex-item" @click="onKeyAuth()" v-if="$Route.query.keyPhone == 1">一键登录</view>
class="tool-flex-item"
@click="onKeyAuth()"
v-if="$Route.query.keyPhone == 1"
>一键登录</view>
</view> </view>
<!-- 欢迎使用 --> <!-- 欢迎使用 -->
<view class="header"> <view class="header">
@@ -26,34 +15,14 @@
<!-- 输入手机号相关 --> <!-- 输入手机号相关 -->
<view class="inputs phone"> <view class="inputs phone">
<label class="label">+86</label> <label class="label">+86</label>
<input <input type="number" placeholder="输入您的手机号码" maxlength="11" v-model="phone" />
type="number"
placeholder="输入您的手机号码"
maxlength="11"
v-model="phone"
/>
</view> </view>
<view class="inputs sms"> <view class="inputs sms">
<input <input type="number" placeholder="输入短信验证码" maxlength="4" v-model="code" />
type="number" <button class="sms-btn" type="default" size="mini" :disabled="phone == '' || getSms"
placeholder="输入短信验证码" @click="getPhoneCode">{{getSms ? '重新发送' + smsTime + 's': '发送验证码'}}</button>
maxlength="4"
v-model="code"
/>
<button
class="sms-btn"
type="default"
size="mini"
:disabled="phone == '' || getSms"
@click="getPhoneCode"
>{{getSms ? '重新发送' + smsTime + 's': '发送验证码'}}</button>
</view> </view>
<button <button class="btn" type="default" :disabled="phone == '' || code == ''" @click="login">登录</button>
class="btn"
type="default"
:disabled="phone == '' || code == ''"
@click="login"
>登录</button>
<!-- 用户登录注册协议 --> <!-- 用户登录注册协议 -->
<view class="agreement"> <view class="agreement">
未注册的手机号码验证后自动创建账号登录即表示同意接受平台 未注册的手机号码验证后自动创建账号登录即表示同意接受平台
@@ -65,7 +34,10 @@
</template> </template>
<script> <script>
import { getSms, smsAuth } from "@/apis/interfaces/auth"; import {
getSms,
smsAuth
} from "@/apis/interfaces/auth";
import userAuth from "@/public/userAuth"; import userAuth from "@/public/userAuth";
export default { export default {
data() { data() {
@@ -83,14 +55,12 @@ export default {
mobileNo: this.phone, mobileNo: this.phone,
code: this.code, code: this.code,
}).then((res) => { }).then((res) => {
console.log(111)
this.$store.commit( this.$store.commit(
"setToken", "setToken",
res.token_type + " " + res.access_token res.token_type + " " + res.access_token
); );
this.$Router.back(); this.$Router.back();
}).catch((err) => { }).catch((err) => {
console.log(2222)
uni.showToast({ uni.showToast({
title: err.message, title: err.message,
icon: "none", icon: "none",
@@ -143,6 +113,7 @@ export default {
box-sizing: border-box; box-sizing: border-box;
background: white; background: white;
@extend .vertical; @extend .vertical;
// 操作栏 // 操作栏
.tool-flex { .tool-flex {
position: fixed; position: fixed;
@@ -155,12 +126,14 @@ export default {
padding-right: $padding * 2; padding-right: $padding * 2;
background: white; background: white;
@extend .ios-top; @extend .ios-top;
&-item { &-item {
line-height: 90rpx; line-height: 90rpx;
color: $text-gray; color: $text-gray;
font-size: $title-size-lg; font-size: $title-size-lg;
} }
} }
// 表单 // 表单
.inputs { .inputs {
background: $window-color; background: $window-color;
@@ -169,6 +142,7 @@ export default {
height: 90rpx; height: 90rpx;
line-height: 90rpx; line-height: 90rpx;
border-radius: 45rpx; border-radius: 45rpx;
input { input {
width: 100%; width: 100%;
height: 90rpx; height: 90rpx;
@@ -181,6 +155,7 @@ export default {
&.phone { &.phone {
padding-left: 120rpx; padding-left: 120rpx;
.label { .label {
position: absolute; position: absolute;
left: 0; left: 0;
@@ -194,6 +169,7 @@ export default {
&.sms { &.sms {
padding-right: 200rpx; padding-right: 200rpx;
.sms-btn[size='mini'] { .sms-btn[size='mini'] {
width: 200rpx; width: 200rpx;
height: 90rpx; height: 90rpx;
@@ -207,9 +183,11 @@ export default {
color: $main-color; color: $main-color;
font-size: $title-size-lg; font-size: $title-size-lg;
background: $window-color; background: $window-color;
&::after { &::after {
border: none; border: none;
} }
&[disabled] { &[disabled] {
color: rgba($color: $main-color, $alpha: .6); color: rgba($color: $main-color, $alpha: .6);
background: rgba($color: $window-color, $alpha: 0); background: rgba($color: $window-color, $alpha: 0);
@@ -217,22 +195,26 @@ export default {
} }
} }
} }
// 头部 // 头部
.header { .header {
text-align: center; text-align: center;
margin-bottom: 5vh; margin-bottom: 5vh;
.title { .title {
font-size: $title-size + 10; font-size: $title-size + 10;
font-weight: bold; font-weight: bold;
color: $text-color; color: $text-color;
line-height: 70rpx; line-height: 70rpx;
} }
.sumbit { .sumbit {
line-height: 50rpx; line-height: 50rpx;
font-size: $title-size-m; font-size: $title-size-m;
color: $text-gray-m; color: $text-gray-m;
} }
} }
// 登录按钮 // 登录按钮
.btn { .btn {
margin: 0; margin: 0;
@@ -245,18 +227,22 @@ export default {
background: $main-color; background: $main-color;
color: white; color: white;
font-weight: bold; font-weight: bold;
&::after { &::after {
display: none; display: none;
} }
&[disabled] { &[disabled] {
background: rgba($color: $main-color, $alpha: .5); background: rgba($color: $main-color, $alpha: .5);
} }
} }
// 协议 // 协议
.agreement { .agreement {
padding-top: 5vh; padding-top: 5vh;
font-size: $title-size-sm; font-size: $title-size-sm;
color: $text-gray-m; color: $text-gray-m;
view { view {
color: $main-color; color: $main-color;
display: inline-block; display: inline-block;

View File

@@ -11,21 +11,18 @@
<!-- 进度 --> <!-- 进度 -->
<view class="plan"> <view class="plan">
<view class="plan-1"> <view class="plan-1">
<span>基本信息</span> <span>基本信息</span> <u-line-progress :percentage="percentplan1" activeColor="#34ce98" class="line-progress" :showText="false" />
<u-line-progress :percentage="percentplan1" activeColor="#34ce98" class="line-progress" :showText="false" />
</view> </view>
<view class="plan-2"> <view class="plan-2">
<span>健康目标</span> <span>健康目标</span> <u-line-progress :percentage="percentplan2" activeColor="#34ce98" width="200rpx" class="line-progress" :showText="false" />
<u-line-progress :percentage="percentplan2" activeColor="#34ce98" width="200rpx" class="line-progress" :showText="false" />
</view> </view>
<view class="plan-3"> <view class="plan-3">
<span>行为习惯</span> <span>行为习惯</span> <u-line-progress :percentage="percentplan3" activeColor="#34ce98" width="200rpx" class="line-progress" :showText="false" />
<u-line-progress :percentage="percentplan3" activeColor="#34ce98" width="200rpx" class="line-progress" :showText="false" />
</view> </view>
</view> </view>
<!-- 进度1 基本信息 --> <!-- 进度1 基本信息 -->
<view> <block>
<!-- 进度1 基本信息页面展示 性别 --> <!-- 进度1 基本信息页面展示 性别 -->
<view class="plan-content" v-if="sexShow"> <view class="plan-content" v-if="sexShow">
<view class="info-des">生理性别和激素会影响我们的身体代谢食物的方式</view> <view class="info-des">生理性别和激素会影响我们的身体代谢食物的方式</view>
@@ -47,19 +44,7 @@
<view class="age"> <view class="age">
<view class="info-title">你的出生日期是</view> <view class="info-title">你的出生日期是</view>
<view class="year" @change="dateShow = true">{{ showBirthday }}</view> <view class="year" @change="dateShow = true">{{ showBirthday }}</view>
<u-datetime-picker <u-datetime-picker confirmColor="#34ce98" ref="datetimePicker" v-model="birthday" mode="date" :show="dateShow" :formatter="formatter" :minDate="-302688000" :maxDate="maxDate" :closeOnClickOverlay="true" @confirm="confirmBirthday" @cancel="camcelBirthday" />
confirmColor="#34ce98"
ref="datetimePicker"
v-model="birthday"
mode="date"
:show="dateShow"
:formatter="formatter"
:minDate="-302688000"
:maxDate="maxDate"
:closeOnClickOverlay="true"
@confirm="confirmBirthday"
@cancel="camcelBirthday"
/>
</view> </view>
</view> </view>
@@ -68,7 +53,6 @@
<u-image class="sex-item-avatar" width="100rpx" height="100rpx" :src="require('../../static/imgs/avatar-1.png')" :lazy-load="true" shape="circle" /> <u-image class="sex-item-avatar" width="100rpx" height="100rpx" :src="require('../../static/imgs/avatar-1.png')" :lazy-load="true" shape="circle" />
<view class="info-des">身高体重信息对健康信息有重要参考价值</view> <view class="info-des">身高体重信息对健康信息有重要参考价值</view>
<view class="info-title">您的身高是</view> <view class="info-title">您的身高是</view>
<!-- -->
<view class="weight"> <view class="weight">
<view class="count"><span>{{ heightU }}</span>厘米</view> <view class="count"><span>{{ heightU }}</span>厘米</view>
<vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scrollHeight" :scrollLeft="Number(heightU)" /> <vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scrollHeight" :scrollLeft="Number(heightU)" />
@@ -84,51 +68,18 @@
<view class="next" @click="weightClick(2)">下一步</view> <view class="next" @click="weightClick(2)">下一步</view>
</view> </view>
</view> </view>
</view> </block>
<!-- 进度2 健康目标 --> <!-- 进度2 健康目标 -->
<view> <block>
<!-- 减脂类型 --> <!-- 减脂类型 -->
<view v-if="targetShow" class="plan-content target-content"> <view v-if="targetShow" class="plan-content target-content">
<u-image class="sex-item-avatar" width="100rpx" height="100rpx" :src="require('../../static/imgs/avatar-1.png')" :lazy-load="true" shape="circle" /> <u-image class="sex-item-avatar" width="100rpx" height="100rpx" :src="require('../../static/imgs/avatar-1.png')" :lazy-load="true" shape="circle" />
<view class="info-title">您的目标是</view> <view class="info-title">您的目标是</view>
<view class="target-type"> <view class="target-type">
<view class="target-type-item"> <view class="target-type-item"> <u-image class="target-img" width="160rpx" height="160rpx" @click="activedTarget = '1'" :src="activedTarget === '1' ? require('../../static/imgs/ic-w-s.png') : require('../../static/imgs/ic-w-n.png')" :lazy-load="true" shape="circle" /> 减肥 </view>
<u-image <view class="target-type-item"> <u-image class="target-img" width="160rpx" height="160rpx" @click="activedTarget = '2'" :src="activedTarget === '2' ? require('../../static/imgs/ic-b-s.png') : require('../../static/imgs/ic-b-n.png')" :lazy-load="true" shape="circle" /> 保持体重 </view>
class="target-img" <view class="target-type-item"> <u-image class="target-img" width="160rpx" height="160rpx" @click="activedTarget = '3'" :src="activedTarget === '3' ? require('../../static/imgs/ic-m-s.png') : require('../../static/imgs/ic-m-n.png')" :lazy-load="true" shape="circle" /> 增肌 </view>
width="160rpx"
height="160rpx"
@click="activedTarget = '1'"
:src="activedTarget === '1' ? require('../../static/imgs/ic-w-s.png') : require('../../static/imgs/ic-w-n.png')"
:lazy-load="true"
shape="circle"
/>
减肥
</view>
<view class="target-type-item">
<u-image
class="target-img"
width="160rpx"
height="160rpx"
@click="activedTarget = '2'"
:src="activedTarget === '2' ? require('../../static/imgs/ic-b-s.png') : require('../../static/imgs/ic-b-n.png')"
:lazy-load="true"
shape="circle"
/>
保持体重
</view>
<view class="target-type-item">
<u-image
class="target-img"
width="160rpx"
height="160rpx"
@click="activedTarget = '3'"
:src="activedTarget === '3' ? require('../../static/imgs/ic-m-s.png') : require('../../static/imgs/ic-m-n.png')"
:lazy-load="true"
shape="circle"
/>
增肌
</view>
</view> </view>
<view class="pre-next"> <view class="pre-next">
<view class="pro" @click="targetClick(1)">上一步</view> <view class="pro" @click="targetClick(1)">上一步</view>
@@ -141,10 +92,7 @@
<view class="info-title">您的打算减脂多少</view> <view class="info-title">您的打算减脂多少</view>
<view class="target-type"> <view class="target-type">
<view class="target-type-item"> <view class="target-type-item">
<view class="count"> <view class="count"> <span>{{ weightTargetU }}</span> 公斤 </view>
<span>{{ weightTargetU }}</span>
公斤
</view>
<vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scrollTargetWeight" :scrollLeft="Number(weightTargetU)" /> <vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scrollTargetWeight" :scrollLeft="Number(weightTargetU)" />
</view> </view>
</view> </view>
@@ -153,7 +101,7 @@
<view class="next" @click="targetWeightClick(2)">下一步</view> <view class="next" @click="targetWeightClick(2)">下一步</view>
</view> </view>
</view> </view>
</view> </block>
<!-- 进度3 行为习惯 --> <!-- 进度3 行为习惯 -->
<!-- 减脂类型 --> <!-- 减脂类型 -->
@@ -162,51 +110,19 @@
<view class="info-title">您的运动量是</view> <view class="info-title">您的运动量是</view>
<view class="target-type"> <view class="target-type">
<view class="target-type-item"> <view class="target-type-item">
<u-image <u-image class="target-img" width="120rpx" height="120rpx" @click="activedbehaviarTarget = '1'" :src="activedbehaviarTarget === '1' ? require('../../static/imgs/ic-w-01.png') : require('../../static/imgs/ic-w-02.png')" :lazy-load="true" shape="circle" />
class="target-img"
width="120rpx"
height="120rpx"
@click="activedbehaviarTarget = '1'"
:src="activedbehaviarTarget === '1' ? require('../../static/imgs/ic-w-01.png') : require('../../static/imgs/ic-w-02.png')"
:lazy-load="true"
shape="circle"
/>
久坐不动 久坐不动
</view> </view>
<view class="target-type-item"> <view class="target-type-item">
<u-image <u-image class="target-img" width="120rpx" height="120rpx" @click="activedbehaviarTarget = '2'" :src="activedbehaviarTarget === '2' ? require('../../static/imgs/ic-w-03.png') : require('../../static/imgs/ic-w-04.png')" :lazy-load="true" shape="circle" />
class="target-img"
width="120rpx"
height="120rpx"
@click="activedbehaviarTarget = '2'"
:src="activedbehaviarTarget === '2' ? require('../../static/imgs/ic-w-03.png') : require('../../static/imgs/ic-w-04.png')"
:lazy-load="true"
shape="circle"
/>
少量运动 少量运动
</view> </view>
<view class="target-type-item"> <view class="target-type-item">
<u-image <u-image class="target-img" width="120rpx" height="120rpx" @click="activedbehaviarTarget = '3'" :src="activedbehaviarTarget === '3' ? require('../../static/imgs/ic-w-05.png') : require('../../static/imgs/ic-w-06.png')" :lazy-load="true" shape="circle" />
class="target-img"
width="120rpx"
height="120rpx"
@click="activedbehaviarTarget = '3'"
:src="activedbehaviarTarget === '3' ? require('../../static/imgs/ic-w-05.png') : require('../../static/imgs/ic-w-06.png')"
:lazy-load="true"
shape="circle"
/>
中等运动量 中等运动量
</view> </view>
<view class="target-type-item"> <view class="target-type-item">
<u-image <u-image class="target-img" width="120rpx" height="120rpx" @click="activedbehaviarTarget = '4'" :src="activedbehaviarTarget === '4' ? require('../../static/imgs/ic-w-07.png') : require('../../static/imgs/ic-w-08.png')" :lazy-load="true" shape="circle" />
class="target-img"
width="120rpx"
height="120rpx"
@click="activedbehaviarTarget = '4'"
:src="activedbehaviarTarget === '4' ? require('../../static/imgs/ic-w-07.png') : require('../../static/imgs/ic-w-08.png')"
:lazy-load="true"
shape="circle"
/>
超强度运动 超强度运动
</view> </view>
</view> </view>
@@ -274,7 +190,6 @@ export default {
}, },
computed: { computed: {
showBirthday() { showBirthday() {
console.log(moment(this.birthday).format('YYYY年MM月DD日'));
return moment(this.birthday).format('YYYY年MM月DD日'); return moment(this.birthday).format('YYYY年MM月DD日');
} }
}, },
@@ -297,6 +212,7 @@ export default {
this.percentplan1 = uni.$u.range(0, 100, this.percentplan1 + 33.33); // 增加进度 this.percentplan1 = uni.$u.range(0, 100, this.percentplan1 + 33.33); // 增加进度
this.heightWeightShow = true; // 展示身高体重模块 this.heightWeightShow = true; // 展示身高体重模块
}, },
// 年龄 ----- 取消选择年龄 // 年龄 ----- 取消选择年龄
camcelBirthday() { camcelBirthday() {
this.birthdayShow = false; // // 年龄页面弹窗不显示 this.birthdayShow = false; // // 年龄页面弹窗不显示
@@ -304,6 +220,7 @@ export default {
this.percentplan1 = 0; // 进度为0 this.percentplan1 = 0; // 进度为0
this.sexShow = true; // 显示性别页面 this.sexShow = true; // 显示性别页面
}, },
//年龄------------- 过滤出生年月日 //年龄------------- 过滤出生年月日
formatter(type, value) { formatter(type, value) {
if (type === 'year') {return `${value}`;} if (type === 'year') {return `${value}`;}
@@ -311,6 +228,8 @@ export default {
if (type === 'day') {return `${value}`;} if (type === 'day') {return `${value}`;}
return value; return value;
}, },
// 体重---------标尺滚动 // 体重---------标尺滚动
scrollWeight(msg) { scrollWeight(msg) {
this.weightU = msg; this.weightU = msg;
@@ -332,6 +251,8 @@ export default {
this.targetShow = true; // 目标页面展示 this.targetShow = true; // 目标页面展示
} }
}, },
// 目标 ------------点击 1上一页 2 下一页 // 目标 ------------点击 1上一页 2 下一页
targetClick(type) { targetClick(type) {
if (type === 1) { if (type === 1) {
@@ -368,6 +289,8 @@ export default {
this.behaviorShow = true; // 打开行为习惯页面 this.behaviorShow = true; // 打开行为习惯页面
} }
}, },
// 目标 运动量--------- 1上一页 2 下一页 // 目标 运动量--------- 1上一页 2 下一页
targetBehaviorClick(type) { targetBehaviorClick(type) {
if (type === 1) { if (type === 1) {
@@ -391,7 +314,6 @@ export default {
exercise: this.activedbehaviarTarget, // 运动量 exercise: this.activedbehaviarTarget, // 运动量
days: 1 days: 1
}; };
console.log(params, 'params.....');
recordsHealth(params) recordsHealth(params)
.then(res => { .then(res => {
uni.showModal({ uni.showModal({
@@ -408,8 +330,10 @@ export default {
.catch(err => { .catch(err => {
uni.showToast({ uni.showToast({
title: err.message, title: err.message,
icon: 'none' icon: "none",
}); duration: 2000,
mask: true
})
}); });
} }
} }

View File

@@ -9,18 +9,7 @@
<view class="evaluation"> <view class="evaluation">
<!-- 进度 --> <!-- 进度 -->
<view class="percent"> <view class="percent">
<u-icon <u-icon name="arrow-left" :color="colorList[colorIndex]" size="14" label="上一题" :labelColor="colorList[colorIndex]" labelSize="14" :bold="true" space="3" v-if="page !== 1" @click="preQ" />
name="arrow-left"
:color="colorList[colorIndex]"
size="14"
label="上一题"
:labelColor="colorList[colorIndex]"
labelSize="14"
:bold="true"
space="3"
v-if="page !== 1"
@click="preQ"
/>
<u-line-progress class="pre-ico" :percentage="percent" height="10" :showText="false" :activeColor="colorList[colorIndex]" /> <u-line-progress class="pre-ico" :percentage="percent" height="10" :showText="false" :activeColor="colorList[colorIndex]" />
<span :style="{ color: colorList[colorIndex] }">{{ percent }}%</span> <span :style="{ color: colorList[colorIndex] }">{{ percent }}%</span>
</view> </view>
@@ -30,15 +19,7 @@
<view class="lists"> <view class="lists">
<view class="list-item"> <view class="list-item">
<u-radio-group placement="column" @change="groupChange" iconPlacement="right" class="radio-g" :value="currentId"> <u-radio-group placement="column" @change="groupChange" iconPlacement="right" class="radio-g" :value="currentId">
<u-radio <u-radio class="radio-item" :customStyle="{ marginBottom: '8px' }" v-for="(item, index) in currentInfo.options" :key="index" :label="item.title" :name="item.option_id" :activeColor="colorList[colorIndex]" />
class="radio-item"
:customStyle="{ marginBottom: '8px' }"
v-for="(item, index) in currentInfo.options"
:key="index"
:label="item.title"
:name="item.option_id"
:activeColor="colorList[colorIndex]"
></u-radio>
</u-radio-group> </u-radio-group>
</view> </view>
<!-- 底部确认按钮 --> <!-- 底部确认按钮 -->
@@ -47,13 +28,16 @@
</view> </view>
</template> </template>
<script> <script>
import { evaluationsQuestion, evaluationsAnswers } from '@/apis/interfaces/evaluation.js'; import {
evaluationsQuestion,
evaluationsAnswers
} from '@/apis/interfaces/evaluation.js';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
percent: 70, percent: 70,
colorList: ['#34ce98', '#b6c29a', '#f4d000', '#8a977b', '#e58308', '#dc5712'], colorList: ['#34ce98', '#d04500', '#f4d000', '#55aa00', '#e58308', '#dc5a1d'],
colorIndex: Math.floor(Math.random() * 6), // 基本案列数据 colorIndex: Math.floor(Math.random() * 6), // 基本案列数据
currentInfo: {}, //当前题目的内容 currentInfo: {}, //当前题目的内容
option_ids: [], // 答案id的数组 option_ids: [], // 答案id的数组
@@ -70,11 +54,19 @@ export default {
}); });
}, },
methods: { methods: {
// 答题列表
getList() { getList() {
evaluationsQuestion(this.$Route.query.id, this.page).then(res => { evaluationsQuestion(this.$Route.query.id, this.page).then(res => {
this.currentInfo = res.data[0]; this.currentInfo = res.data[0];
this.percent = Number(((res.page.current - 1) / res.page.total).toFixed(2)) * 100; this.percent = Number(((res.page.current - 1) / res.page.total).toFixed(2)) * 100;
this.has_more = res.page.has_more; this.has_more = res.page.has_more;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
groupChange(n) { groupChange(n) {
@@ -91,7 +83,10 @@ export default {
next() { next() {
if (this.has_more) { if (this.has_more) {
if (this.currentId === '') { if (this.currentId === '') {
uni.showToast({ title: '请选择答案', icon: 'none' }); uni.showToast({
title: '请选择答案',
icon: 'none'
});
return; return;
} }
this.option_ids.push(this.currentId); this.option_ids.push(this.currentId);
@@ -109,7 +104,6 @@ export default {
}; };
evaluationsAnswers(data) evaluationsAnswers(data)
.then(res => { .then(res => {
console.log(res);
this.parent = 100; this.parent = 100;
uni.showToast({ uni.showToast({
title: '答题完成,立即查看结果', title: '答题完成,立即查看结果',
@@ -124,8 +118,11 @@ export default {
}) })
.catch(err => { .catch(err => {
uni.showToast({ uni.showToast({
title: err.message title: err.message,
}); icon: "none",
duration: 2000,
mask: true
})
}); });
} }
} }
@@ -135,6 +132,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.evaluation { .evaluation {
padding: $padding $padding $padding * 4 $padding; padding: $padding $padding $padding * 4 $padding;
.percent { .percent {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -142,18 +140,22 @@ export default {
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
font-size: $title-size - 2; font-size: $title-size - 2;
.pre-ico { .pre-ico {
margin: $padding; margin: $padding;
} }
} }
.title { .title {
font-size: $title-size + 10; font-size: $title-size + 10;
font-weight: bold; font-weight: bold;
padding-top: $padding; padding-top: $padding;
} }
.lists { .lists {
.radio-g { .radio-g {
padding-top: $padding * 2; padding-top: $padding * 2;
.radio-item { .radio-item {
background: #f9f9f9; background: #f9f9f9;
padding: $padding; padding: $padding;
@@ -161,6 +163,7 @@ export default {
flex: 1; flex: 1;
} }
} }
.bottom-btn { .bottom-btn {
text-align: center; text-align: center;
padding: 24rpx $padding; padding: 24rpx $padding;

View File

@@ -32,17 +32,20 @@ export default {
<br/> <br/>
适用于18-65岁存在亚健康或尿酸偏高人群`, 适用于18-65岁存在亚健康或尿酸偏高人群`,
shadowStyle: { shadowStyle: {backgroundImage: 'none',paddingTop: '0',marginTop: '20rpx'}
backgroundImage: 'none',
paddingTop: '0',
marginTop: '20rpx'
}
}; };
}, },
onShow() { onShow() {
evaluationsInfo(this.$Route.query.id).then(res => { evaluationsInfo(this.$Route.query.id).then(res => {
this.content = res.content; this.content = res.content;
this.info = res; this.info = res;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
methods: { methods: {
@@ -52,7 +55,6 @@ export default {
}); });
}, },
toResult() { toResult() {
console.log('点击了测试');
uni.navigateTo({ uni.navigateTo({
url: `/pages/evaluation/result?id=${this.$Route.query.id}` url: `/pages/evaluation/result?id=${this.$Route.query.id}`
}); });
@@ -65,6 +67,7 @@ export default {
.introduce { .introduce {
background-color: $main-color; background-color: $main-color;
min-height: 100vh; min-height: 100vh;
.intro-history { .intro-history {
padding: $padding * 1.5 $padding; padding: $padding * 1.5 $padding;
color: $window-color; color: $window-color;
@@ -76,6 +79,7 @@ export default {
justify-content: flex-end; justify-content: flex-end;
box-sizing: border-box; box-sizing: border-box;
} }
// 测评展示 // 测评展示
.intro-content { .intro-content {
background: rgba($color: #fff, $alpha: 1); background: rgba($color: #fff, $alpha: 1);
@@ -85,6 +89,7 @@ export default {
border-radius: $radius; border-radius: $radius;
position: relative; position: relative;
box-shadow: 0 0 10rpx 4rpx rgba($color: $main-color, $alpha: 0.1); box-shadow: 0 0 10rpx 4rpx rgba($color: $main-color, $alpha: 0.1);
// 标题 // 标题
.intro-title { .intro-title {
font-size: $title-size * 1.8; font-size: $title-size * 1.8;
@@ -93,6 +98,7 @@ export default {
position: relative; position: relative;
top: -40rpx; top: -40rpx;
} }
// 介绍 // 介绍
.intro-des { .intro-des {
line-height: $title-size * 1.8; line-height: $title-size * 1.8;
@@ -102,10 +108,12 @@ export default {
font-size: $title-size-m; font-size: $title-size-m;
padding-bottom: 20rpx; padding-bottom: 20rpx;
} }
// 图片 // 图片
.intro-img { .intro-img {
margin-top: $padding * 0.8; margin-top: $padding * 0.8;
} }
// 开始测评 // 开始测评
.answer { .answer {
position: absolute; position: absolute;
@@ -123,6 +131,7 @@ export default {
font-size: $title-size-m + 6; font-size: $title-size-m + 6;
} }
} }
// 备注信息 // 备注信息
.remark { .remark {
color: $text-gray; color: $text-gray;

View File

@@ -11,44 +11,20 @@
<!-- 评测列表主要内容 标题 图片 描述 --> <!-- 评测列表主要内容 标题 图片 描述 -->
<view class="--content"> <view class="--content">
<u-image class="content-img" width="170rpx" height="170rpx" radius="20rpx" :src="item.cover ? item.cover : require('../../static/imgs/test.png')" :lazy-load="true" /> <u-image class="content-img" width="170rpx" height="170rpx" radius="20rpx" :src="item.cover ? item.cover : require('../../static/imgs/test.png')" :lazy-load="true" />
<view class="title-des"> <view class="title-des"> <view class="title">{{ item.title }}</view> <view class="des">{{ item.description || '--' }}</view> </view>
<view class="title">{{ item.title }}</view>
<view class="des">{{ item.description || '--' }}</view>
</view>
</view> </view>
<!-- 分数 --> <!-- 分数 -->
<view class="score" v-if="item.is_answer"> <view class="score" v-if="item.is_answer"> <span>{{ item.answer.total }}</span> </view>
<span>{{ item.answer.total }}</span>
</view>
<!-- 评测状态 --> <!-- 评测状态 -->
<view class="--status"> <view class="--status">
<!-- 已测试展示 状态--> <!-- 已测试展示 状态-->
<view class="status" v-if="item.is_answer"> <view class="status" v-if="item.is_answer"> <span class="dian">·</span> {{ item.remark }} </view>
<span class="dian">·</span>
{{ item.remark }}
</view>
<view v-if="item.is_answer" class="history" @click="toResult(item)">查看历史结果</view> <view v-if="item.is_answer" class="history" @click="toResult(item)">查看历史结果</view>
<!-- 未测试展示 状态--> <!-- 未测试展示 状态-->
<view class="status" v-if="!item.is_answer"> <view class="status" v-if="!item.is_answer"> <span class="dian">·</span> <span class="person">{{ item.remark }}</span> 人已测 | 约4~8分钟 </view>
<span class="dian">·</span> <u-icon name="arrow-right" :color="item.is_answer ? '#26a377' : '#faa81a'" size="14" :bold="true" :label="item.is_answer ? '重新评测' : '开始测评'" labelPos="left" labelSize="14" space="1" :labelColor="item.is_answer ? '#26a377' : '#faa81a'" @click="nowEva(item)" />
<span class="person">{{ item.remark }}</span>
人已测 | 约4~8分钟
</view>
<u-icon
name="arrow-right"
:color="item.is_answer ? '#26a377' : '#faa81a'"
size="14"
:bold="true"
:label="item.is_answer ? '重新评测' : '开始测评'"
labelPos="left"
labelSize="14"
space="1"
:labelColor="item.is_answer ? '#26a377' : '#faa81a'"
@click="nowEva(item)"
/>
</view> </view>
</view> </view>
<!-- 没有更多 --> <!-- 没有更多 -->
@@ -72,6 +48,13 @@ export default {
getList() { getList() {
evaluations().then(res => { evaluations().then(res => {
this.evalList = res; this.evalList = res;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// nowEva // nowEva

View File

@@ -53,9 +53,7 @@
<!-- 标题 --> <!-- 标题 -->
<view class="title-content"><view class="title">营养建议</view></view> <view class="title-content"><view class="title">营养建议</view></view>
<block v-for="(item, index) in 3" :key="index"> <block v-for="(item, index) in 3" :key="index">
<view class="title2"> <view class="title2"> <span>{{ item }}. 低Gi</span> </view>
<span>{{ item }}. 低Gi</span>
</view>
<!-- 描述 --> <!-- 描述 -->
<view class="des">饮食营养及生活方式对维持面部年轻态影响较大建议注意食材选择逐步清淡口味规律作息逐个改善不良生活习惯帮助改善当前皮肤状态</view> <view class="des">饮食营养及生活方式对维持面部年轻态影响较大建议注意食材选择逐步清淡口味规律作息逐个改善不良生活习惯帮助改善当前皮肤状态</view>
</block> </block>
@@ -63,10 +61,7 @@
<!-- 更多 --> <!-- 更多 -->
<view class="answer-item"> <view class="answer-item">
<!-- 标题 --> <!-- 标题 -->
<view class="title-content"> <view class="title-content"> <view class="title">更多护肤知识</view> <u-icon name="arrow-right" color="#333" size="20" /> </view>
<view class="title">更多护肤知识</view>
<u-icon name="arrow-right" color="#333" size="20" />
</view>
<!-- 横向滚动推荐 --> <!-- 横向滚动推荐 -->
<scroll-view class="scroll-view_H" scroll-x="true"> <scroll-view class="scroll-view_H" scroll-x="true">
<view v-for="(item, index) in 6" :key="index" id="demo1" class="scroll-view-item_H"> <view v-for="(item, index) in 6" :key="index" id="demo1" class="scroll-view-item_H">
@@ -109,6 +104,13 @@ export default {
] ]
}; };
this.loaded = true; this.loaded = true;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
reEva() { reEva() {

View File

@@ -0,0 +1,163 @@
<template>
<view>
<view v-for="(item, index) in conversations" :key="index" :class="['message', { 'is-top': item.isTop }]"
:data-item="item" @longpress="onLongPress" @click="toDetail(item)">
<message-cell :item="item" />
</view>
<view class="shade" @click="hidePop" v-show="showPop">
<view class="pop" :style="popStyle" :class="{'show':showPop}">
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu" :data-index="index">
{{item}}
</view>
</view>
</view>
</view>
</template>
<script>
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import im from '@/utils/im/index.js'
import messageCell from './messageCell'
export default {
props: {
conversations: {
type: Array,
default: function() {
return []
}
}
},
components: {
messageCell
},
data() {
return {
/* 窗口尺寸 */
winSize: {},
/* 显示操作弹窗 */
showPop: false,
/* 弹窗按钮列表 */
popButton: ['置顶聊天', '删除该聊天'],
/* 弹窗定位样式 */
popStyle: "",
pickedItem: {},
}
},
methods: {
// 隐藏功能菜单
hidePop() {
this.showPop = false
this.pickedItem = {}
setTimeout(() => {
this.showShade = false
}, 250)
},
// 点击会话功能菜单
pickerMenu(e) {
const index = Number(e.currentTarget.dataset.index)
if (index == 0) {
RongIMLib.setConversationToTop(this.pickedItem.conversationType, this.pickedItem.targetId, !this
.pickedItem.isTop)
} else {
RongIMLib.removeConversation(this.pickedItem.conversationType, this.pickedItem.targetId)
RongIMLib.deleteMessages(this.pickedItem.conversationType, this.pickedItem.targetId)
}
this.$emit('refresh')
im.setNotifyBadge()
this.hidePop()
},
// 长按会话,展示功能菜单
onLongPress(e) {
let [touches, style, item] = [e.touches[0], "", e.currentTarget.dataset.item]
if (touches.clientY > (this.winSize.height / 2)) {
style = `bottom:${this.winSize.height-touches.clientY}px;`
} else {
style = `top:${touches.clientY}px;`
}
if (touches.clientX > (this.winSize.witdh / 2)) {
style += `right:${this.winSize.witdh-touches.clientX}px`
} else {
style += `left:${touches.clientX}px`
}
this.popButton[0] = item.isTop ? '取消置顶' : '置顶聊天'
this.popStyle = style
this.pickedItem = item
this.$nextTick(() => {
setTimeout(() => {
this.showPop = true;
}, 10)
})
},
toDetail(item) {
if (item.conversationType == 1) {
uni.navigateTo({
url: '/pages/im/private/chat?targetId=' + item.targetId
})
} else if (item.conversationType == 3) {
uni.navigateTo({
url: '/pages/im/group/chat?targetId=' + item.targetId
})
}
this.hidePop()
}
}
}
</script>
<style lang="scss" scoped>
.message {
background: white;
&.is-top {
background: $window-color;
}
}
/* 遮罩 */
.shade {
position: fixed;
width: 100%;
height: 100%;
.pop {
position: fixed;
z-index: 101;
width: 200rpx;
box-sizing: border-box;
font-size: 28rpx;
text-align: left;
color: #333;
background-color: #fff;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
line-height: 80rpx;
transition: transform 0.15s ease-in-out 0s;
user-select: none;
-webkit-touch-callout: none;
transform: scale(0, 0);
&.show {
transform: scale(1, 1);
}
&>view {
padding: 0 20rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
user-select: none;
-webkit-touch-callout: none;
&:active {
background-color: #f3f3f3;
}
}
}
}
</style>

View File

@@ -0,0 +1,112 @@
<template>
<view class="apply--cell u-border-bottom">
<view class="avatar">
<u-avatar :src="user.portraitUrl" shape="square" size="46" />
</view>
<view class="info">
<view class="name">
{{ user.name }}
</view>
<view class="message">
{{ message.message }}
</view>
</view>
<view class="action">
<u-button type="success" size="mini" @click="resolve">通过</u-button>
<u-button type="warning" size="mini" @click="reject">拒绝</u-button>
</view>
</view>
</template>
<script>
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import {
resolveFriend,
rejectFriend
} from '@/apis/interfaces/im.js'
export default {
props: {
message: {
type: Object,
default: {}
}
},
computed: {
user() {
return JSON.parse(this.message.extra)
}
},
methods: {
resolve() {
resolveFriend(this.message.sourceUserId).then(res => {
this.clearMessages()
uni.showToast({
icon: 'none',
title: '通过好友申请'
})
}).catch(err => {
uni.showToast({
icon: 'none',
title: err.message
})
})
},
reject() {
uni.showModal({
title: '拒绝申请',
success: (res) => {
if (res.confirm) {
rejectFriend(this.message.sourceUserId).then(res => {
this.clearMessages()
}).catch(err => {
uni.showToast({
icon: 'none',
title: err.message
})
})
}
}
})
},
// 不管是通过还是拒绝,都要把相关的信息清理
clearMessages() {
RongIMLib.deleteMessages(RongIMLib.ConversationType.SYSTEM, this.message.sourceUserId)
this.$emit('success')
uni.$emit('onContactNotification')
}
}
}
</script>
<style lang="scss" scoped>
.apply--cell {
display: flex;
padding: $padding;
align-items: center;
.info {
flex: 1;
margin-left: $padding;
.name {
font-size: $title-size + 2;
}
.message {
color: $text-gray-m;
font-size: $title-size-m;
margin-top: 10rpx;
}
}
.action {
justify-content: space-between;
.u-button+.u-button {
margin-top: 10rpx;
}
}
}
</style>

View File

@@ -1,15 +1,14 @@
<template> <template>
<view class="friend-apply"> <view class="friend-apply">
<block v-for="item in lists" v-if="lists.length > 0" :key="item.userId"> <block v-for="(item, index) in lists" v-if="lists.length > 0" :key="index">
<view class="lists"> <view class="lists">
<view class="" style="width: 100rpx;height: 100rpx;"> <view class="" style="width: 100rpx;height: 100rpx;">
<u-image class="cover" radius="4" width="100rpx" height="100rpx" :src="item.portraitUrl || require('@/static/user/cover.png')" :lazy-load="true" /> <u-avatar :src="JSON.parse(item.latestMessage.extra).portraitUrl" shape="square" size="44" />
</view> </view>
<view class="right"> <view class="right">
<view class="title"> <view class="title">
<view class="name">{{ item.name }}</view> <view class="name">{{ item.name }}</view>
<view class="des" v-if="isApply">{{ item.address || '这家伙很懒什么都没有添加~' }}</view> <view class="des">{{ item.latestMessage.message }}</view>
<view class="des" v-else>{{ item.remark || '你好,听说你很优秀想认识~' }}</view>
</view> </view>
<view class="agress-btn"> <view class="agress-btn">
<span v-if="isAgree" @click="action('agree', item)">通过</span> <span v-if="isAgree" @click="action('agree', item)">通过</span>
@@ -44,8 +43,8 @@ export default {
default: false default: false
} }
}, },
data() { created() {
return {}; console.log(this.lists);
}, },
methods: { methods: {
action(type, item) { action(type, item) {

View File

@@ -0,0 +1,93 @@
<template>
<view class="message--cell">
<view class="avatar">
<u-badge max="99" shape="horn" absolute :offset="[-5, -8]" :value="item.unreadMessageCount" />
<u-avatar :src="contact(item.targetId).portraitUrl" shape="square" size="44" />
</view>
<view class="content">
<view class="header">
<view class="name">{{ contact(item.targetId).name }} <text v-if="item.conversationType === 3"
class='qun'>[]</text></view>
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
</view>
<message-preview class="preview" :msg="item.latestMessage" :conversationType="item.conversationType"
:user="item.latestMessage.userInfo" />
</view>
</view>
</template>
<script>
import messagePreview from './messagePreview'
export default {
props: {
item: {
type: Object,
default: function() {
return {}
}
}
},
computed: {
contact() {
return function(targetId) {
return this.$store.getters.contactInfo(targetId)
}
}
},
components: {
messagePreview
}
}
</script>
<style lang="scss" scoped>
.message--cell {
display: flex;
padding: 20rpx 0 0 20rpx;
.avatar {
position: relative;
.u-badge {
z-index: 998;
}
}
.content {
margin-left: 30rpx;
box-sizing: border-box;
position: relative;
flex: 1;
border-bottom-width: 0.5px !important;
border-color: $u-border-color !important;
border-bottom-style: solid;
.header {
display: flex;
justify-content: space-between;
.name {
font-size: $title-size + 2;
color: #454545;
display: flex;
align-items: center;
.qun {
color: $main-color;
font-size: $title-size-m;
margin-left: 4px;
}
}
.time {
font-size: $title-size-sm;
color: $text-gray-m;
position: absolute;
right: 30rpx;
}
}
}
}
</style>

View File

@@ -1,28 +1,28 @@
<template> <template>
<view> <view>
<view v-if="msg.objectName=='RC:TxtMsg'"> <view class="preview" v-if="msg.objectName=='RC:TxtMsg'">
{{ msg.content || '' }} <text v-if="conversationType == 3">{{ user.name }}: </text>{{ msg.content || '' }}
</view> </view>
<view v-if="msg.objectName=='RC:HQVCMsg'"> <view class="preview" v-if="msg.objectName=='RC:HQVCMsg'">
[语音] <text v-if="conversationType == 3">{{ user.name }}: </text>[语音]
</view> </view>
<view v-if="msg.objectName=='RC:ImgMsg'"> <view class="preview" v-if="msg.objectName=='RC:ImgMsg'">
[图片] <text v-if="conversationType == 3">{{ user.name }}: </text>[图片]
</view> </view>
<view v-if="msg.objectName=='RC:GIFMsg'"> <view class="preview" v-if="msg.objectName=='RC:GIFMsg'">
[表情] <text v-if="conversationType == 3">{{ user.name }}: </text>[表情]
</view> </view>
<view v-if="msg.objectName=='RC:FileMsg'"> <view class="preview" v-if="msg.objectName=='RC:FileMsg'">
[文件] <text v-if="conversationType == 3">{{ user.name }}: </text>[文件]
</view> </view>
<view v-if="msg.objectName=='RC:LBSMsg'"> <view class="preview" v-if="msg.objectName=='RC:LBSMsg'">
[位置] <text v-if="conversationType == 3">{{ user.name }}: </text>[位置]
</view> </view>
<view v-if="msg.objectName=='RC:AudioMsg'"> <view class="preview" v-if="msg.objectName=='RC:AudioMsg'">
[语音通话] <text v-if="conversationType == 3">{{ user.name }}: </text>[语音通话]
</view> </view>
<view v-if="msg.objectName=='RC:VideoMsg'"> <view class="preview" v-if="msg.objectName=='RC:VideoMsg'">
[视频通话] <text v-if="conversationType == 3">{{ user.name }}: </text>[视频通话]
</view> </view>
</view> </view>
</template> </template>
@@ -33,11 +33,33 @@
msg: { msg: {
type: Object, type: Object,
default: {} default: {}
},
conversationType: {
type: Number,
default: 0
},
user: {
type: Object,
default: function() {
return {
name: ''
}
}
} }
} }
} }
</script> </script>
<style> <style lang="scss" scoped>
.preview {
word-break: break-all;
color: $text-gray-m;
padding-top: $padding - 20;
padding-bottom: $padding;
font-size: $title-size-m;
height: 32rpx;
line-height: 32rpx;
width: 520rpx;
@extend .nowrap;
}
</style> </style>

View File

@@ -0,0 +1,83 @@
<template>
<view class="">
<!-- footer -->
<view class="footer">
<view class="msg-type" @click="changeMessageType">
<image class="icon" src="@/static/icon/key-icon.png" v-if="chatType === 0" mode="widthFix">
</image>
<image class="icon" src="@/static/icon/msg-icon.png" v-if="chatType === 1" mode="widthFix">
</image>
</view>
<sent-voice v-if="chatType === 0" :conversationType="conversationType" :targetId="targetId"
@success="onSuccess" />
<sent-text v-if="chatType === 1" :conversationType="conversationType" :targetId="targetId"
@success="onSuccess" />
<view class="msg-type msg-popups" @click="showPopups = !showPopups">
<image class="icon" src="@/static/icon/popups-icon.png"></image>
</view>
</view>
<!-- 弹出层 -->
<sent-popups :show="showPopups" :conversationType="conversationType" :targetId="targetId"
@success="() => {showPopups = false, onSuccess()}"></sent-popups>
</view>
</template>
<script>
import sentText from '../components/sentText'
import sentVoice from '../components/sentVoice'
import sentPopups from '../components/sentPopups'
export default {
props: {
conversationType: {
type: Number,
default: 0
},
targetId: {
type: String,
default: ''
}
},
components: {
sentText,
sentVoice,
sentPopups
},
data() {
return {
chatType: 1, // 0 语音1 文本
showPopups: false
}
},
methods: {
// 切换聊天类型,语音/文本
changeMessageType() {
this.chatType = this.chatType === 1 ? 0 : 1
},
onSuccess() {
this.$emit('onSuccess')
}
}
}
</script>
<style lang="scss" scoped>
.footer {
background: white;
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
flex-direction: row;
.msg-type {
width: 70rpx;
height: 70rpx;
.icon {
margin: 5rpx;
width: 60rpx;
height: 60rpx;
}
}
}
</style>

View File

@@ -63,6 +63,11 @@
default: '' default: ''
} }
}, },
computed: {
user() {
return this.$store.getters.sender
}
},
methods: { methods: {
singleCall(e) { singleCall(e) {
uni.showToast({ uni.showToast({
@@ -81,7 +86,8 @@
count: 9, count: 9,
sourceType: ['album'], sourceType: ['album'],
success: res => { success: res => {
im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0], ( im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0],
this.user, (
res) => { res) => {
this.success() this.success()
}) })
@@ -92,7 +98,8 @@
uni.chooseImage({ uni.chooseImage({
sourceType: ['camera'], sourceType: ['camera'],
success: res => { success: res => {
im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0], ( im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0],
this.user, (
res) => { res) => {
this.success() this.success()
}) })

View File

@@ -1,15 +1,7 @@
<template> <template>
<view class="sent--text"> <view class="sent--text">
<input <input class="input" type="text" @focus="focus" @blur="blur" v-model="inputTxt" confirm-type="send"
class="input" @confirm="sent" cursor-spacing="10" />
type="text"
@focus="focus"
@blur="blur"
v-model="inputTxt"
confirm-type="send"
@confirm="sent"
cursor-spacing="10"
/>
<!-- <button class="button" size="mini" :disabled="disabled" @click="sent">发送</button> --> <!-- <button class="button" size="mini" :disabled="disabled" @click="sent">发送</button> -->
</view> </view>
</template> </template>
@@ -36,6 +28,9 @@
computed: { computed: {
disabled() { disabled() {
return this.inputTxt.length === 0 return this.inputTxt.length === 0
},
user() {
return this.$store.getters.sender
} }
}, },
created() { created() {
@@ -55,7 +50,7 @@
sent() { sent() {
if (!this.disabled) { if (!this.disabled) {
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId) RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
im.sentText(this.conversationType, this.targetId, this.inputTxt, () => { im.sentText(this.conversationType, this.targetId, this.inputTxt, this.user, () => {
this.$emit('success') this.$emit('success')
this.inputTxt = '' this.inputTxt = ''
}) })
@@ -71,7 +66,7 @@
} }
</script> </script>
<style scoped lang="less"> <style scoped lang="scss">
.sent--text { .sent--text {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -85,20 +80,5 @@
margin-right: 15rpx; margin-right: 15rpx;
padding: 0 20rpx; padding: 0 20rpx;
} }
.button {
border: none;
background: #34CE98;
color: white;
width: 120rpx;
line-height: 70rpx;
text-align: center;
border-radius: 10rpx;
font-size: 30rpx;
font-weight: bold;
}
// .button[disabled] {
// background-color: #555555;
// }
} }
</style> </style>

View File

@@ -35,6 +35,11 @@
recorderManager: null recorderManager: null
} }
}, },
computed: {
user() {
return this.$store.getters.sender
}
},
created() { created() {
this.recorderManager = uni.getRecorderManager() this.recorderManager = uni.getRecorderManager()
}, },
@@ -81,7 +86,7 @@
this.recorderManager.onStop(res => { this.recorderManager.onStop(res => {
im.sentVoice(this.conversationType, this.targetId, res.tempFilePath, (this.maxRecordTime - im.sentVoice(this.conversationType, this.targetId, res.tempFilePath, (this.maxRecordTime -
this this
.recordTime), () => { .recordTime), this.user, () => {
setTimeout(() => { setTimeout(() => {
this.$emit('success') this.$emit('success')
}, 500) }, 500)

View File

@@ -1,7 +1,10 @@
<template> <template>
<view class="">
<text class="name" v-if="!guest && name">{{ name }}</text>
<view class="msg--image" :class="guest ? 'right': 'left'"> <view class="msg--image" :class="guest ? 'right': 'left'">
<image class="img" :src="msg.thumbnail" @click="previewImage" mode="widthFix"></image> <image class="img" :src="msg.thumbnail" @click="previewImage" mode="widthFix"></image>
</view> </view>
</view>
</template> </template>
<script> <script>
@@ -23,6 +26,10 @@
guest: { guest: {
type: Boolean, type: Boolean,
default: true default: true
},
name: {
type: String,
default: ''
} }
}, },
methods: { methods: {
@@ -39,17 +46,24 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.name {
font-size: 24rpx;
line-height: 34rpx;
color: $text-gray-m;
padding-bottom: 10rpx;
}
.msg--image { .msg--image {
padding: 20rpx; // padding: 20rpx;
&.left { &.left {
border-radius: 0 20rpx 20rpx 20rpx; border-radius: 0 20rpx 20rpx 20rpx;
background: white; // background: white;
} }
&.right { &.right {
border-radius: 20rpx 0 20rpx 20rpx; border-radius: 20rpx 0 20rpx 20rpx;
background: #34CE98; // background: #34CE98;
} }
.img { .img {

View File

@@ -1,5 +1,6 @@
<template> <template>
<view class="msg--text"> <view class="msg--text">
<text class="name" v-if="!guest && name">{{ name }}</text>
<text class="im--text" :class="guest ? 'right': 'left'">{{ msg.content }}</text> <text class="im--text" :class="guest ? 'right': 'left'">{{ msg.content }}</text>
</view> </view>
</template> </template>
@@ -12,6 +13,10 @@
type: Object, type: Object,
default: {} default: {}
}, },
name: {
type: String,
default: ''
},
guest: { guest: {
type: Boolean, type: Boolean,
default: true default: true
@@ -21,11 +26,19 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.msg--text {
.name {
font-size: 26rpx;
padding-bottom: 10rpx;
color: $text-gray-m;
}
.im--text { .im--text {
max-width: 400rpx; max-width: 508rpx;
padding: 20rpx; padding: 20rpx;
font-size: 28rpx; line-height: 46rpx;
line-height: 40rpx; font-size: 32rpx;
color: $text-color;
&.left { &.left {
border-radius: 0 20rpx 20rpx 20rpx; border-radius: 0 20rpx 20rpx 20rpx;
@@ -38,4 +51,5 @@
color: white; color: white;
} }
} }
}
</style> </style>

View File

@@ -1,9 +1,12 @@
<template> <template>
<view class="">
<text class="name" v-if="!guest && name">{{ name }}</text>
<view class="msg--voice" :class="guest ? 'right': 'left'" @click="onPlayMsg"> <view class="msg--voice" :class="guest ? 'right': 'left'" @click="onPlayMsg">
<image v-if="!guest" class="icon" src="@/static/icon/audio_green.png" mode="widthFix"></image> <image v-if="!guest" class="icon" src="@/static/icon/audio_green.png" mode="widthFix"></image>
<text class="duration">{{msg.duration}}"</text> <text class="duration">{{msg.duration}}"</text>
<image v-if="guest" class="icon" src="@/static/icon/audio_white.png" mode="widthFix"></image> <image v-if="guest" class="icon" src="@/static/icon/audio_white.png" mode="widthFix"></image>
</view> </view>
</view>
</template> </template>
<script> <script>
@@ -21,6 +24,10 @@
} }
} }
}, },
name: {
type: String,
default: ''
},
guest: { guest: {
type: Boolean, type: Boolean,
default: true default: true
@@ -56,6 +63,12 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.name {
font-size: 24rpx;
line-height: 34rpx;
color: $text-gray-m;
}
.msg--voice { .msg--voice {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;

View File

@@ -1,47 +1,32 @@
<template> <template>
<view> <view>
<u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98"> <u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98">
<view>
<view class="friend-flex u-border-bottom" @click="toPending"> <view class="friend-flex u-border-bottom" @click="toPending">
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_01.png')"></u-avatar> <u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_01.png')"></u-avatar>
<view class="name"> <u-badge max="99" absolute :offset="[23, 20]" :value="pendingCount" />
新的朋友 ({{ pendingCount }}) <view class="info">新的朋友</view>
</view> </view>
</view> <view class="friend-flex" @click="toGroup">
<view class="friend-flex" @click="showToast">
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_00.png')"></u-avatar> <u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_00.png')"></u-avatar>
<view class="name">我的群聊</view> <view class="info">我的群聊</view>
</view>
</view> </view>
<block v-if="friends.length > 0"> <block v-if="friends.length > 0">
<template v-for="(item, friend) in friends"> <u-index-item v-for="(item, fkey) in friends" :key="fkey">
<!-- #ifdef APP-NVUE --> <u-index-anchor :text="indexs[fkey]" bgColor="#F3F6FB" height="20" size="12" color="#666">
<u-index-anchor :text="indexs[friend]" bgColor="#F3F6FB" height="20" size="12" color="#666">
</u-index-anchor> </u-index-anchor>
<!-- #endif -->
<u-index-item> <view v-for="(friendItem, index) in item" :key="index" class="friend-flex u-border-bottom"
<!-- #ifndef APP-NVUE --> @click="toFriend(friendItem.targetId)">
<u-index-anchor :text="indexs[friend]" bgColor="#F3F6FB" height="20" size="12" color="#666"> <u-avatar size="40" shape="square" :src="contact(friendItem.targetId).portraitUrl" />
</u-index-anchor> <view class="info">
<!-- #endif --> <view class="name">{{ contact(friendItem.targetId).name }}</view>
<view v-for="(friendItem, index) in item" :key="friendItem.userId" <view class="address">{{ friendItem.address }}</view>
class="friend-flex u-border-bottom" </view>
@click="$Router.push({ name: 'imFriendsInfo', params: { targetId: friendItem.userId } })">
<block v-if="friendItem.portraitUrl != ''">
<u-avatar class="cover" size="40" shape="square" :src="friendItem.portraitUrl || ''"
:default-url="require('@/static/user/cover.png')"></u-avatar>
</block>
<block v-else>
<u-avatar class="cover" size="40" shape="square"
:src="require('@/static/user/cover.png')"></u-avatar>
</block>
<view class="name">{{ friendItem.name }}</view>
</view> </view>
</u-index-item> </u-index-item>
</template>
</block> </block>
<block v-else> <block v-else>
<u-empty class="pages-null" mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png" text="暂无好友"> <u-empty class="pages-null" mode="data" text="暂无好友">
</u-empty> </u-empty>
</block> </block>
</u-index-list> </u-index-list>
@@ -50,9 +35,9 @@
<script> <script>
import { import {
getFriends, getFriendsLetter
getPendingCount
} from '@/apis/interfaces/im'; } from '@/apis/interfaces/im';
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
export default { export default {
data() { data() {
@@ -62,22 +47,53 @@
pendingCount: 0 pendingCount: 0
}; };
}, },
onShow() { computed: {
getFriends().then(res => { contact() {
return function(targetId) {
return this.$store.getters.contactInfo(targetId)
}
}
},
onLoad() {
this.getFriendList()
this.checkNewFriendPending()
uni.$on('onContactNotification', () => {
this.checkNewFriendPending()
this.getFriendList()
})
},
onUnload() {
uni.$off('onContactNotification')
},
methods: {
getFriendList() {
getFriendsLetter().then(res => {
this.indexs = res.indexList this.indexs = res.indexList
this.friends = res.itemArr this.friends = res.itemArr
}) })
getPendingCount().then(res => { },
console.log(res); checkNewFriendPending() {
this.pendingCount = res // 获取是否有新的好友申请
RongIMLib.getConversationList([RongIMLib.ConversationType.SYSTEM], 1000, 0, (res) => {
if (res.code === 0) {
this.pendingCount = res.conversations.filter((item) => {
return item.objectName == RongIMLib.ObjectName.ContactNotification
}).length
}
}) })
}, },
methods: { toGroup() {
showToast() { uni.navigateTo({
uni.showToast({ url: '/pages/im/group/index',
title: '群聊功能暂未开放,敬请期待', fail(err) {
icon: 'none' console.log(err);
}); }
})
},
toFriend(targetId) {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + targetId
})
}, },
// 新朋友 // 新朋友
toPending() { toPending() {
@@ -108,14 +124,21 @@
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
// .cover .info {
.name {
flex: 1; flex: 1;
padding-left: $padding; margin-left: $padding;
.name {
font-size: $title-size + 2; font-size: $title-size + 2;
font-size: $title-size + 2; font-size: $title-size + 2;
color: #454545 !important; color: #454545 !important;
@extend .nowrap; @extend .nowrap;
} }
.address {
color: $text-gray-m;
font-size: $title-size-m - 5;
}
}
} }
</style> </style>

View File

@@ -2,7 +2,8 @@
<view class="content"> <view class="content">
<!-- 用户信息 --> <!-- 用户信息 -->
<view class="info-flex"> <view class="info-flex">
<u-avatar :src="userInfo.portraitUrl || require('@/static/user/cover.png')" shape="square" size="50" bg-color="#fff"></u-avatar> <u-avatar :src="userInfo.portraitUrl || require('@/static/user/cover.png')" shape="square" size="50"
bg-color="#fff"></u-avatar>
<view class="info-text"> <view class="info-text">
<view class="nickname">{{ userInfo.name }}</view> <view class="nickname">{{ userInfo.name }}</view>
<view class="address" @longpress="copyAddress">地址{{ userInfo.address }}</view> <view class="address" @longpress="copyAddress">地址{{ userInfo.address }}</view>
@@ -105,10 +106,11 @@
} }
}, },
onLoad(e) { onLoad(e) {
console.log(e);
this.targetId = e.targetId this.targetId = e.targetId
getFriendInfo(e.targetId).then(res => { getFriendInfo(e.targetId).then(res => {
this.userInfo = res this.userInfo = res
// 获取到用户信息之后,去检查一下要不要更新
this.$store.dispatch('updateContact', res)
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: res.name title: res.name
}) })
@@ -125,7 +127,7 @@
if (code == 0) { if (code == 0) {
this.isTop = conversation.isTop this.isTop = conversation.isTop
} }
}); })
}, },
methods: { methods: {
copyAddress() { copyAddress() {
@@ -141,7 +143,7 @@
}, },
toPrivate() { toPrivate() {
uni.redirectTo({ uni.redirectTo({
url: '/pages/im/private/chat?conversationType=1&targetId=' + this.targetId url: '/pages/im/private/chat?targetId=' + this.targetId
}); });
}, },
setRemark() { setRemark() {
@@ -157,6 +159,7 @@
success: e => { success: e => {
if (e.confirm) { if (e.confirm) {
deleteFriend(this.targetId).then(res => { deleteFriend(this.targetId).then(res => {
uni.$emit('onContactNotification')
// 删除聊天记录 // 删除聊天记录
RongIMLib.deleteMessages(1, this.targetId); RongIMLib.deleteMessages(1, this.targetId);
RongIMLib.removeConversation(1, this.targetId); RongIMLib.removeConversation(1, this.targetId);
@@ -313,9 +316,11 @@
background: white; background: white;
margin: $margin; margin: $margin;
border-radius: $radius; border-radius: $radius;
.u-border-bottom { .u-border-bottom {
border-bottom: solid 1rpx #f9f9f9 !important; border-bottom: solid 1rpx #f9f9f9 !important;
} }
.item { .item {
line-height: 100rpx; line-height: 100rpx;
display: flex; display: flex;

View File

@@ -17,13 +17,13 @@
<view class="text" v-if="infoObj.gender === 2"></view> <view class="text" v-if="infoObj.gender === 2"></view>
</view> </view>
<view class="item"> <view class="item">
<label>HASH</label> <label>地址</label>
<view class="text">{{infoObj.hash}}</view> <view class="text">{{infoObj.address}}</view>
</view> </view>
</view> </view>
<!-- 二维码 --> <!-- 二维码 -->
<view class="info-code"> <view class="info-code">
<uqrcode class="info-code-src" :size="198" ref="uQRCode" :text="qrContent" /> <uqrcode class="info-code-src" :size="198" :text="qrContent" />
<view class="info-code-text"> <view class="info-code-text">
<view>ZH-HEALTH扫一扫上面的二维码</view> <view>ZH-HEALTH扫一扫上面的二维码</view>
<view>添加我的好友</view> <view>添加我的好友</view>
@@ -51,11 +51,10 @@
qrContent: 'ADDFRIEND|' qrContent: 'ADDFRIEND|'
} }
}, },
onLoad(e) {}, onLoad(e) {
mounted() { this.qrContent += e.targetId
getUserInfo(this.$Route.query.targetId).then(res => { getUserInfo(e.targetId).then(res => {
this.infoObj = res this.infoObj = res
this.qrContent += res.userId
}) })
}, },
methods: { methods: {

View File

@@ -1,11 +1,3 @@
<!--
* @Description:新朋友即新增好友申请列表 可以搜索跳转
* @Author: Aimee·Zhang
* @Date: 2022-01-24 10:49:15
* @LastEditors: Aimee·Zhang
* @LastEditTime: 2022-01-25 10:18:26
-->
<template> <template>
<view class="pending"> <view class="pending">
<u-sticky> <u-sticky>
@@ -14,66 +6,36 @@
:disabled="true" :show-action="false" /> :disabled="true" :show-action="false" />
</view> </view>
</u-sticky> </u-sticky>
<block v-if="pedings.length > 0"> <view v-for="(item, index) in pendings" :key="index">
<applyFriend :lists="pedings" :isAgree="true" :isReject="false" @action="action" /> <apply-cell :message="item.latestMessage" @success="getPendingList" />
</block>
<view class="no-lists" v-else>
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
:src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
<span>暂无申请记录~</span>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import { import applyCell from '../components/friendApplyCell'
getPedings, import im from '@/utils/im/index.js'
resolveFriend,
rejectFriend
} from '@/apis/interfaces/im.js'
import * as RongIMLib from "@/uni_modules/RongCloud-IMWrapper/js_sdk/index"
import applyFriend from '@/components/friend-apply-reject-agree'
export default { export default {
components: { components: {
applyFriend applyCell
}, },
data() { data() {
return { return {
pedings: [] pendings: []
} }
}, },
onLoad() { onLoad() {
this.getPeddingList() this.getPendingList()
uni.$on('onContactNotification', this.getPendingList)
},
onUnload() {
uni.$off('onContactNotification')
}, },
methods: { methods: {
// 操作同意或拒绝 getPendingList() {
action(e) { im.getPendingList((pendings) => {
let url = e.type === 'agree' ? resolveFriend : rejectFriend this.pendings = pendings
uni.showModal({
title: e.type === 'agree' ? '通过' : '拒绝',
content: e.type === 'agree' ? '通过后即可与该用户畅所欲言' : '拒绝后将不会收到该用户发来信息',
success: res => {
if (res.confirm) {
url(e.item.userId).then(res => {
this.getPeddingList()
})
}
}
})
},
getPeddingList() {
// 获取系统中的好友关系会话列表
// RongIMLib.getConversationList([RongIMLib.ConversationType.SYSTEM], 50, 0, (res) => {
// if (res.code === 0) {
// this.pedings = res.conversations.filter((item) => {
// return item.objectName == RongIMLib.ObjectName.ContactNotification
// })
// }
// })
getPedings().then(res => {
console.log(res)
this.pedings = res
}) })
} }
} }

View File

@@ -12,7 +12,7 @@
<u-sticky> <u-sticky>
<view class="header-search"> <view class="header-search">
<u-search placeholder="输入用户账号、手机号" height="74" searchIcon="search" @custom="search" <u-search placeholder="输入用户账号、手机号" height="74" searchIcon="search" @custom="search"
v-model="searchValue" @search="search" inputAlign="center" bgColor="#f9f9f9" :focus="focused" /> v-model="searchValue" @search="search" bgColor="#f9f9f9" :focus="focused" />
</view> </view>
</u-sticky> </u-sticky>
<block v-if="searchResult.length > 0"> <block v-if="searchResult.length > 0">
@@ -31,7 +31,7 @@
searchFriend, searchFriend,
pedingFriend pedingFriend
} from '@/apis/interfaces/im.js'; } from '@/apis/interfaces/im.js';
import applyFriend from '@/components/friend-apply-reject-agree'; import applyFriend from '../components/friendApplyList.vue';
export default { export default {
components: { components: {
applyFriend applyFriend

View File

@@ -0,0 +1,60 @@
<template>
<view class="create">
<u--textarea v-model="content" count height="200" maxlength="200" placeholder="请输入公告内容"></u--textarea>
<u-button type="primary" text="发布" :disabled="disabled" @click="onCreate" color="#34CE98"></u-button>
</view>
</template>
<script>
import {
createGroupAnnouncement
} from '@/apis/interfaces/im.js'
export default {
data() {
return {
targetId: '',
content: ''
}
},
onLoad(e) {
this.targetId = e.targetId
},
computed: {
disabled() {
return this.content.length == 0 || this.content.length > 200
}
},
methods: {
onCreate() {
createGroupAnnouncement(this.targetId, this.content).then(res => {
uni.$emit('groupAnnouncementCreated')
uni.showToast({
title: '发布成功',
success: () => {
setTimeout(() => {
uni.navigateBack()
}, 1000)
}
})
}).catch(err => {
uni.showToast({
icon: 'none',
title: err.message
})
})
}
}
}
</script>
<style lang="scss" scoped>
.create {
padding: $padding;
.u-button {
margin-top: $padding;
}
}
</style>

View File

@@ -0,0 +1,125 @@
<template>
<view class="announce">
<u-skeleton rows="2" :loading="loading" avatar :rows="5">
<view v-for="(item,index) in announcements" :key="index" class="item">
<view class="header">
<u-avatar :src="item.user.portraitUrl"></u-avatar>
<view class="user">
<view class="name">{{ item.user.name }}</view>
<view class="time">{{ item.created_at }}</view>
</view>
<view class="delete" v-if="isAdmin" @click="onDelete(item.announcement_id)">删除</view>
</view>
<view class="content">{{ item.content }}</view>
</view>
</u-skeleton>
</view>
</template>
<script>
import {
getGroupInfo,
getGroupAnnouncements,
deleteGroupAnnouncement
} from '@/apis/interfaces/im.js'
export default {
data() {
return {
targetId: '',
announcements: [],
loading: true,
isAdmin: false
}
},
onLoad(e) {
this.targetId = e.targetId
getGroupInfo(this.targetId).then(res => {
this.isAdmin = res.group.is_admin
})
this.initData()
uni.$on('groupAnnouncementCreated', this.initData)
},
onUnload() {
uni.$off('groupAnnouncementCreated')
},
onNavigationBarButtonTap() {
if (this.isAdmin) {
uni.navigateTo({
url: '/pages/im/group/announceCreate?targetId=' + this.targetId
})
} else {
uni.showToast({
icon: 'none',
title: '没有权限'
})
}
},
methods: {
initData() {
getGroupAnnouncements(this.targetId).then(res => {
this.announcements = res
this.loading = false
})
},
onDelete(aId) {
uni.showModal({
title: '删除公告',
success: (res) => {
if (res.confirm) {
deleteGroupAnnouncement(this.targetId, aId).then(res => {
uni.showToast({
icon: 'none',
title: '删除成功'
})
this.initData()
})
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
.announce {
padding: 0 $padding $padding $padding;
.item {
border-bottom: solid 1rpx #f9f9f9 !important;
padding-top: $padding;
.header {
display: flex;
flex-direction: row;
align-items: center;
.user {
margin-left: $padding;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.name {}
.time {
font-size: 24rpx;
color: $text-gray-m;
}
}
.delete {
color: $text-price;
font-size: 28rpx;
}
}
.content {
padding: $padding;
font-size: 34rpx;
}
}
}
</style>

91
pages/im/group/apply.vue Normal file
View File

@@ -0,0 +1,91 @@
<template>
<view class="apply">
<u-avatar :src="group.cover" size="128" shape="square"></u-avatar>
<view class="name">
{{ group.name }}
</view>
<u-button v-if="group.can_join" @click="applyGroup" text="申请加群" :disabled="disabled" color="#34CE98" />
<view class="" v-else>
<view class="" v-if="group.is_full">群已满员</view>
<view class="" v-if="group.deny_apply">禁止申请</view>
<u-button v-if="group.state === 'accepted'" color="#34CE98" text="进入群聊" @click="toGroupChat" />
</view>
<u-modal negativeTop="300" :show="modalShow" title="申请原因" showCancelButton @cancel="onHideModal"
@confirm="onJoinGroup">
<view class="slot-content">
<u--input placeholder="申请原因" border="surround" focus v-model="message"></u--input>
</view>
</u-modal>
</view>
</template>
<script>
import {
joinGroupPre,
joinGroup
} from '@/apis/interfaces/im.js'
export default {
data() {
return {
targetId: '',
group: {},
modalShow: false,
message: '',
disabled: false
}
},
onLoad(e) {
this.targetId = e.targetId
joinGroupPre(this.targetId).then(res => {
console.log(res);
this.group = res
})
},
methods: {
toGroupChat() {
uni.redirectTo({
url: '/pages/im/group/chat?targetId=' + this.targetId
})
},
applyGroup() {
this.modalShow = true
},
onHideModal() {
this.message = ''
this.modalShow = false
},
onJoinGroup() {
joinGroup(this.targetId, this.message).then(res => {
console.log('申请结果', res);
uni.showToast({
icon: 'none',
title: '申请成功'
})
}).catch(err => {
uni.showToast({
icon: 'none',
title: err.message
})
})
this.disabled = true
this.onHideModal()
}
}
}
</script>
<style lang="scss" scoped>
.apply {
display: flex;
flex-direction: column;
align-items: center;
.u-avatar {
width: 200rpx;
height: 200rpx;
}
}
</style>

197
pages/im/group/chat.nvue Normal file
View File

@@ -0,0 +1,197 @@
<template>
<view class="group--chat">
<list class="body" :show-scrollbar="false">
<cell class="cell" v-for="(item, index) in messages" :key="index">
<view class="cell-item" :class="item.messageDirection == 1 ? 'right' : 'left'">
<u-avatar class="avatar" @click="toUser(item)" size="36" shape="square" :src="item.content.userInfo.portraitUrl" />
<view class="msg">
<show-voice v-if="item.objectName === 'RC:HQVCMsg'" :guest="item.messageDirection == 1"
:msg="item.content" :name="item.content.userInfo.name" />
<show-image v-if="item.objectName === 'RC:ImgMsg'" :guest="item.messageDirection == 1"
:msg="item.content" :name="item.content.userInfo.name" />
<show-text v-if="item.objectName === 'RC:TxtMsg'" :guest="item.messageDirection == 1"
:msg="item.content" :name="item.content.userInfo.name" />
</view>
</view>
</cell>
<cell class="cell-footer" ref="chatBottom"></cell>
</list>
<sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getMessageList()" />
</view>
</template>
<script>
import {
timeCustomCN
} from '@/utils/filters.js'
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import im from '@/utils/im/index.js'
import showVoice from '../components/showVoice'
import showImage from '../components/showImage'
import showText from '../components/showText'
import sentMessageBar from '../components/sentMessageBar'
const ChatList = uni.requireNativePlugin('dom')
export default {
components: {
showVoice,
showImage,
showText,
sentMessageBar
},
data() {
return {
targetId: '',
conversationType: 3,
messages: [],
groupInfo: {
name: ''
}
}
},
onLoad(e) {
this.targetId = e.targetId
this.groupInfo = this.$store.getters.contactInfo(this.targetId)
uni.setNavigationBarTitle({
title: this.groupInfo.name
})
this.getMessageList()
uni.$on('onReceiveMessage', (msg) => {
if (msg.targetId == this.targetId) {
this.getMessageList()
}
})
uni.$once('cleanGroupMessage', this.getMessageList)
},
onBackPress() {
uni.$off('onReceiveMessage')
console.log('Off onReceiveMessage');
},
onNavigationBarButtonTap() {
uni.navigateTo({
url: '/pages/im/group/info?targetId=' + this.targetId
})
},
methods: {
toUser(item) {
if (item.senderUserId == '__system__') {
return
}
if (item.messageDirection == 1) {
uni.navigateTo({
url: '/pages/im/friends/mine?targetId=' + item.senderUserId
})
} else{
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + item.senderUserId
})
}
},
// 获取消息列表
getMessageList() {
im.getMessageList(
this.conversationType,
this.targetId,
new Date().getTime(),
20,
true,
(messages) => {
this.messages = messages.reverse()
this.scrollBottom()
})
},
// 滚动到底部
scrollBottom(type) {
// 清理当前会话,未读消息数量
RongIMLib.clearMessagesUnreadStatus(this.conversationType, this.targetId, new Date().getTime() + 1100)
// 发送消息已读状态给对方
RongIMLib.sendReadReceiptMessage(this.conversationType, this.targetId, new Date().getTime())
// 更新badge提醒数量
im.setNotifyBadge()
setTimeout(() => {
let el = this.$refs.chatBottom
ChatList.scrollToElement(el, {
offset: 0,
animated: false
})
}, 50)
}
}
}
</script>
<style lang="scss" scoped>
.group--chat {
background: $window-color;
flex: 1;
.body {
flex: 1;
.cell {
padding: 10rpx 30rpx;
.cell-item {
width: 690rpx;
justify-content: flex-start;
align-items: flex-start;
margin-top: 20rpx;
&.left {
flex-direction: row;
}
&.right {
flex-direction: row-reverse;
.state {
flex-direction: row;
justify-content: flex-end;
}
}
.avatar {
width: 78rpx;
height: 78rpx;
background-color: white;
border-radius: 10rpx;
}
.msg {
margin: 0 20rpx;
.user {
font-size: 18rpx;
line-height: 40rpx;
}
}
}
.cell-footer {
height: 20rpx;
}
}
}
.footer {
background: white;
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
flex-direction: row;
.msg-type {
width: 70rpx;
height: 70rpx;
.icon {
margin: 5rpx;
width: 60rpx;
height: 60rpx;
}
}
}
}
</style>

View File

@@ -1,11 +1,109 @@
<template> <template>
<view class=""> <view>
<view v-for="(item, index) in groups" :key="index" class="friend-flex u-border-bottom"
@click="toGroup(item.targetId)">
<u-avatar size="40" shape="square" :src="contact(item.targetId).portraitUrl" />
<view class="info">
<view class="name">{{ item.name }}</view>
</view>
</view>
<u-modal negativeTop="300" :show="createModal" title="创建群聊" showCancelButton @cancel="onHideModal"
@confirm="onCreateGroup">
<view class="slot-content">
<u--input placeholder="群名称" border="surround" focus v-model="groupName"></u--input>
</view>
</u-modal>
</view> </view>
</template> </template>
<script> <script>
import {
getMyGroups,
createGroup
} from '@/apis/interfaces/im.js'
export default {
data() {
return {
groups: [],
createModal: false,
groupName: ''
}
},
computed: {
contact() {
return function(targetId) {
return this.$store.getters.contactInfo(targetId)
}
}
},
onNavigationBarButtonTap() {
this.createModal = true
},
onLoad() {
this.initData()
},
methods: {
initData() {
getMyGroups().then((res) => {
this.groups = res
res.map(item => {
this.$store.dispatch('updateContact', item)
})
})
},
onHideModal() {
this.createModal = false
this.groupName = ''
},
onCreateGroup() {
createGroup({
name: this.groupName
}).then(res => {
uni.showToast({
title: '创建成功'
})
this.initData()
this.onHideModal()
}).catch(err => {
uni.showToast({
icon: 'none',
title: err
})
})
},
toGroup(targetId) {
uni.navigateTo({
url: '/pages/im/group/chat?targetId=' + targetId
})
}
}
}
</script> </script>
<style> <style lang="scss" scoped>
// 好友列表
.friend-flex {
position: relative;
padding: 20rpx $padding;
display: flex;
flex-direction: row;
align-items: center;
.info {
flex: 1;
margin-left: $padding;
.name {
font-size: $title-size + 2;
font-size: $title-size + 2;
color: #454545 !important;
}
.address {
color: $text-gray-m;
font-size: $title-size-m - 5;
}
}
}
</style> </style>

399
pages/im/group/info.vue Normal file
View File

@@ -0,0 +1,399 @@
<template>
<view class="container">
<view class="members u-border-bottom">
<view class="users">
<view class="user" v-for="(item, index) in users" :key="index" @click="toUser(item)">
<u-avatar size="44" shape="square" :src="item.portraitUrl"></u-avatar>
<view class="name">{{ item.name }}</view>
</view>
<view class="user">
<u-avatar @click="inviteUser" size="44" shape="square" icon="plus" bg-color="#eeeeee"
color="#999999"></u-avatar>
<view class="name">邀请好友</view>
</view>
</view>
<view @click="loadMore" v-if="members > users.length" class="loadmore">查看更多群成员 ></view>
</view>
<u-cell-group class="cells">
<u-cell isLink title="群公告" :label="announcement" @click="toAnnouncement"></u-cell>
<u-cell isLink title="二维码" @click="showGroupQrCode"></u-cell>
<u-cell title="聊天置顶">
<u-switch slot="value" size="20" v-model="isTop" activeColor="#34CE98" @change="setTop"></u-switch>
</u-cell>
<u-cell title="免打扰">
<u-switch slot="value" size="20" v-model="status" activeColor="#34CE98" @change="setStatus"></u-switch>
</u-cell>
</u-cell-group>
<u-cell-group class="cells" v-if="group.is_admin">
<u-cell isLink title="修改群聊名称" :value="groupName" @click="onGroupName"></u-cell>
<u-cell isLink title="修改群头像">
<u-avatar slot="value" size="25" shape="square" @click="onGroupAvatar" :src="group.cover"></u-avatar>
</u-cell>
<u-cell isLink v-if="group.is_owner" title="准入方式" :value="joinType" @click="onChangeJoinType"></u-cell>
</u-cell-group>
<view class="cells actions u-border-top" v-if="loaded">
<view class="action u-border-bottom" @click="onClean">清空聊天记录</view>
<view class="action u-border-bottom" v-if="group.is_owner" @click="onDismiss">解散群聊</view>
<view class="action u-border-bottom" v-else @click="onQuite">删除并退出</view>
</view>
<u-modal negativeTop="300" :show="modalShow" title="修改群名称" showCancelButton @cancel="onHideModal"
@confirm="onChangeGroupName">
<view class="slot-content">
<u--input placeholder="群名称" border="surround" focus v-model="groupName"></u--input>
</view>
</u-modal>
<u-modal :show="qrCodeShow" :title="group.name" @confirm="qrCodeShow = false">
<view class="slot-content">
<uqrcode class="info-code-src" :size="198" :text="qrContent" />
</view>
</u-modal>
<u-action-sheet @select="doAction" :actions="joinTypeMap" cancelText="取消" :show="showActions"
@close="showActions=false">
</u-action-sheet>
</view>
</template>
<script>
import {
getGroupInfo,
updateGroup,
quitGroup,
dismissGroup
} from '@/apis/interfaces/im.js'
import {
uploads
} from '@/apis/interfaces/uploading'
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
export default {
data() {
return {
targetId: '',
group: {},
conversationType: 3,
announcement: '',
users: [],
status: false,
isTop: false,
loaded: false,
modalShow: false,
groupName: '',
qrCodeShow: false,
qrContent: 'JOINGROUP|',
joinType: '',
joinTypeMap: [],
showActions: false
}
},
onLoad(e) {
this.targetId = e.targetId
this.qrContent += e.targetId
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({
status
}) => {
this.status = !Boolean(status)
})
RongIMLib.getConversation(this.conversationType, this.targetId, ({
code,
conversation
}) => {
if (code == 0) {
this.isTop = conversation.isTop
}
})
this.initData()
uni.$on('groupAnnouncementCreated', this.initData)
},
onUnload() {
uni.$off('groupAnnouncementCreated')
},
methods: {
initData() {
getGroupInfo(this.targetId).then(res => {
this.group = res.group
this.groupName = res.group.name
this.announcement = res.announcement
this.users = res.users
this.members = res.members
this.loaded = true
this.joinTypeMap = res.join_type_map.map(item => {
if (item.key == res.join_type) {
item.disabled = true
}
return item
})
this.joinType = res.join_type_map.filter(item => item.key == res.join_type)[0].name
}).catch(err => {
uni.showToast({
icon: 'none',
title: '群不存在'
})
})
},
setStatus() {
RongIMLib.setConversationNotificationStatus(this.conversationType, this.targetId, this.status,
({
status
}) => {
this.status = !Boolean(status)
})
},
setTop() {
RongIMLib.setConversationToTop(this.conversationType, this.targetId, this.isTop, (res) => {
RongIMLib.getConversation(this.conversationType, this.targetId, ({
conversation
}) => {
this.isTop = conversation.isTop
})
})
},
toUser(item) {
if (item.targetId == this.$store.getters.sender.userId) {
uni.navigateTo({
url: '/pages/im/friends/mine?targetId=' + item.targetId
})
} else {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + item.targetId
})
}
},
inviteUser() {
},
loadMore() {
uni.navigateTo({
url: '/pages/im/group/users?targetId=' + this.targetId
})
},
toAnnouncement() {
uni.navigateTo({
url: '/pages/im/group/announcement?targetId=' + this.targetId
})
},
showGroupQrCode() {
this.qrCodeShow = true
},
onGroupName() {
this.modalShow = true
console.log(this.$refs.groupNameRef);
},
onChangeGroupName() {
if (this.groupName != this.group.name) {
updateGroup(this.targetId, {
name: this.groupName
}).then(res => {
this.modalShow = false
uni.showToast({
icon: 'none',
title: '群名称修改成功'
})
})
} else {
uni.showToast({
icon: 'none',
title: '无修改'
})
}
},
onHideModal() {
this.modalShow = false
this.groupName = this.group.name
},
// 修改群头像
onGroupAvatar() {
console.log('onGroupAvatar');
uni.chooseImage({
count: 1,
sourceType: ['album'],
crop: {
quality: 100,
width: 128,
height: 128,
resize: true
},
success: res => {
console.log(res);
let path = res.tempFiles.map((val, index) => {
return {
name: 'uploads' + index,
uri: val.path
}
})
uploads(path).then(path => {
updateGroup(this.targetId, {
cover: path.path[0]
}).then(res => {
uni.showToast({
icon: 'none',
title: '群头像修改成功'
})
this.modalShow = false
this.group.cover = path.url[0]
})
}).catch(err => {
uni.showToast({
title: err.message,
icon: 'none'
})
})
},
fail: (err) => {
console.log(err);
}
})
},
onChangeJoinType() {
this.showActions = true
},
doAction(e) {
updateGroup(this.targetId, {
join_type: e.key
}).then(res => {
uni.showToast({
icon: 'none',
title: '修改成功'
})
this.joinTypeMap = this.joinTypeMap.map(item => {
if (item.key == e.key) {
item.disabled = true
} else {
item.disabled = false
}
return item
})
this.joinType = e.name
this.showActions = false
}).catch(err => {
console.log(err);
uni.showToast({
icon: 'error',
title: err.message
})
})
},
onClean() {
uni.showModal({
title: '清空聊天记录',
content: '清空聊天记录,只会清空本地的记录,其他成员不会变化',
success: (res) => {
if (res.confirm) {
RongIMLib.deleteMessages(3, this.targetId, () => {
uni.showToast({
icon: 'none',
title: '清空成功'
})
uni.$emit('cleanGroupMessage')
})
}
}
})
},
onDismiss() {
uni.showModal({
title: '解散群聊',
success: (res) => {
if (res.confirm) {
dismissGroup(this.targetId).then(res => {
uni.showToast({
icon: 'none',
title: '解散成功'
})
uni.switchTab({
url: '/pages/im/index'
})
})
}
}
})
},
onQuite() {
uni.showModal({
title: '退出群聊',
success: (res) => {
if (res.confirm) {
quitGroup(this.targetId).then(res => {
uni.showToast({
icon: 'none',
title: '退出群聊成功'
})
uni.switchTab({
url: '/pages/im/index'
})
})
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
.container {
min-height: 100vh;
background: $window-color;
}
.cells {
margin-top: $padding;
background-color: white;
}
.members {
background-color: white;
padding-bottom: 40rpx;
.users {
flex-direction: row;
flex-wrap: wrap;
display: flex;
padding: 20rpx 0;
.user {
width: 126rpx;
margin-left: 20rpx;
margin-bottom: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.name {
color: $text-gray-m;
width: 126rpx;
text-align: center;
font-size: 26rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-word;
}
}
}
.loadmore {
font-size: 26rpx;
color: $text-gray-m;
text-align: center;
}
}
.actions {
margin-top: $padding;
text-align: center;
.action {
padding: $padding;
color: $text-price;
justify-content: center;
}
}
</style>

164
pages/im/group/users.vue Normal file
View File

@@ -0,0 +1,164 @@
<template>
<view class="members">
<view class="users">
<view class="user" v-if="isAdmin">
<u-avatar @click="inviteUser" size="44" shape="square" icon="plus" bg-color="#eeeeee" color="#999999">
</u-avatar>
<view class="name">邀请好友</view>
</view>
<view :class="['user', {'active': item.targetId == currentUser.targetId}]" @longpress="showAction(item)"
v-for="(item, index) in members" :key="index" @click="toUser(item)">
<u-avatar size="44" shape="square" :src="item.portraitUrl"></u-avatar>
<view class="name">{{ item.name }}</view>
</view>
</view>
<view class="loadmore">成员总数{{ members.length }}</view>
<u-action-sheet :actions="userActions" :title="actionTitle" cancelText="取消" @close="hideAction"
@select="doAction" :show="actionShow">
</u-action-sheet>
</view>
</template>
<script>
import {
getGroupBase,
getGroupUsers
} from '@/apis/interfaces/im.js'
export default {
data() {
return {
targetId: '',
members: [],
isOwner: false,
isAdmin: false,
actionShow: false,
userActions: [{
type: 0,
name: '设置管理员',
disabled: false
},
{
type: 1,
name: '解除管理员',
disabled: false
},
{
type: 2,
name: '移除成员',
disabled: false
}
],
actionTitle: '',
currentUser: {}
}
},
onLoad(e) {
this.targetId = e.targetId
getGroupBase(this.targetId).then(res => {
this.isOwner = res.is_owner
this.isAdmin = res.is_admin
if (this.isOwner) {
this.userActions.push({
type: 3,
name: '转移群主',
disabled: false
})
}
})
this.getUserList()
},
methods: {
getUserList() {
getGroupUsers(this.targetId).then(res => {
this.members = res
})
},
toUser(item) {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + item.targetId
})
},
showAction(item) {
this.currentUser = item
this.actionTitle = item.name
this.actionShow = true
// 根据当前用户,是不是管理,来控制按钮的可用性
this.userActions[0].disabled = true
},
hideAction(item) {
this.actionShow = false
this.actionTitle = ''
this.currentUser = {}
this.userActions[0].disabled = false
this.userActions[1].disabled = false
},
doAction(e) {
switch (e.type) {
case 0:
// 设置管理
break;
case 1:
// 取消管理
break;
case 2:
// 移除成员
break;
case 3:
// 转移管理员
break;
}
this.getUserList()
},
inviteUser() {
}
}
}
</script>
<style lang="scss" scoped>
.members {
background-color: white;
padding-bottom: 40rpx;
.users {
flex-direction: row;
flex-wrap: wrap;
display: flex;
padding: 20rpx 0;
.user {
width: 126rpx;
margin-left: 20rpx;
margin-bottom: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&.active {
background-color: $window-color;
}
.name {
color: $text-gray-m;
width: 126rpx;
text-align: center;
font-size: 26rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-word;
}
}
}
.loadmore {
font-size: 26rpx;
color: $text-gray-m;
text-align: center;
}
}
</style>

View File

@@ -5,60 +5,23 @@
<view class="custom-header"> <view class="custom-header">
<view class="header-flex"> <view class="header-flex">
<view class="tabs"> <view class="tabs">
<view class="item show"> <view class="item active">聊聊</view>
<u-badge max="99" value="99" absolute :offset="[0, -10]"/>私聊
</view>
<view class="item" @click="onNav('', {})">
<u-badge max="99" value="99" absolute :offset="[0, -10]"/>群聊
</view>
</view> </view>
<view class="btns"> <view class="btns">
<view class="item" @click="scanQrCode"> <view class="item" @click="scanQrCode">
<uni-icons color="#555" type="scan" size="22"></uni-icons> <uni-icons color="#555" type="scan" size="22" />
</view> </view>
<view class="item" @click="onNav('imFriends', {})"> <view class="item" @click="toFriendList">
<uni-icons color="#555" custom-prefix="iconfont" type="icon-tuandui" size="22"></uni-icons> <u-badge absolute max="99" :offset="[-5, -5]" :value="hasNewFriends" />
</view> <uni-icons color="#555" custom-prefix="iconfont" type="icon-tuandui" size="22" />
<!-- <view class="item" @click="onNav('', {})">
<uni-icons color="#555" custom-prefix="iconfont" type="icon-gengduo2" size="22"></uni-icons>
</view> -->
</view> </view>
</view> </view>
</view> </view>
<!-- content -->
<view v-if="$store.state.token != ''">
<block v-if="conversations.length < 1">
<view class="vertical null-list">
<u-empty mode="message" textColor="#999" text="暂无好友消息" />
</view> </view>
</block>
<block v-else>
<u-alert type="warning" v-if="connection != 0" description="网络似乎断开了,请检查网络" :show-icon="true" /> <u-alert type="warning" v-if="connection != 0" description="网络似乎断开了,请检查网络" :show-icon="true" />
<view v-for="(item, index) in conversations" :key="index" :class="['message', { 'is-top': item.isTop }]" <!-- content -->
@click="toDetail(item)" @longpress="onLongPress" :data-item="item"> <view v-if="$store.state.token !== ''">
<view class="avatar" @click="toFriend(item.targetId)"> <conversation-list @refresh="getConversationList()" :conversations="conversations" />
<u-badge numberType="ellipsis" max="99" shape="horn" absolute :offset="[-5, -5]"
:value="item.unreadMessageCount" />
<u-avatar :src="friend(item.targetId).portraitUrl || require('@/static/user/cover.png')"
shape="square" size="44" />
</view>
<view class="content u-border-bottom">
<view class="header">
<view class="name">{{ friend(item.targetId).name || '未知用户' }}</view>
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
</view>
<message-preview class="preview" :msg="item.latestMessage" />
</view>
</view>
<!-- TODO 长按的弹出框怎么点击隐藏没搞明白 -->
<view class="shade" @click="hidePop" v-show="showPop">
<view class="pop" :style="popStyle" :class="{'show':showPop}">
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu" :data-index="index">
{{item}}
</view>
</view>
</view>
</block>
</view> </view>
<!-- 未登录 --> <!-- 未登录 -->
<view v-else class="vertical null-list"> <view v-else class="vertical null-list">
@@ -72,119 +35,46 @@
</template> </template>
<script> <script>
import * as RongIMLib from "@/uni_modules/RongCloud-IMWrapper/js_sdk/index" import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import im from '@/utils/im/index.js' import im from '@/utils/im/index.js'
import userAuth from '@/public/userAuth' import userAuth from '@/public/userAuth'
import messagePreview from './components/messagePreview' import conversationList from './components/conversationList'
import {
getImToken
} from '@/apis/interfaces/im.js'
export default { export default {
data() { data() {
return { return {
isShown: true, // 当前页面显示状态
conversations: [], // 会话列表 conversations: [], // 会话列表
connection: 0, connection: 0,
/* 窗口尺寸 */ hasNewFriends: 0
winSize: {},
/* 显示操作弹窗 */
showPop: false,
/* 弹窗按钮列表 */
popButton: ['置顶聊天', '删除该聊天'],
/* 弹窗定位样式 */
popStyle: "",
pickedItem: {}
} }
}, },
components: { components: {
messagePreview conversationList
},
computed: {
friend() {
return function(targetId) {
return this.$store.getters.userInfo(targetId)
}
}
}, },
onLoad() { onLoad() {
// 好友申请数量
this.checkNewFriendPending()
uni.$on('onConnectionStatusChange', (status) => { uni.$on('onConnectionStatusChange', (status) => {
this.connection = status this.connection = status
}) })
uni.$on('onContactNotification', this.checkNewFriendPending)
}, },
onShow() { onShow() {
if (this.$store.state.token !== '') { if (this.$store.state.token !== '') {
this.getConversationList() this.getConversationList()
} }
// 监听新消息
uni.$on('onReceiveMessage', (msg) => { uni.$on('onReceiveMessage', (msg) => {
console.log('收到消息,刷新列表');
this.getConversationList() this.getConversationList()
}) })
this.isShown = true
}, },
onHide() { onHide() {
uni.$off('onReceiveMessage') uni.$off('onReceiveMessage')
this.isShown = false
},
onNavigationBarButtonTap(e) {
if (e.index == 0) {
uni.showToast({
title: '开发中暂未开放,敬请期待',
icon: 'none'
})
}
if (e.index == 1) {
if (this.toLogin()) {
this.$Router.push({
name: 'imFriends'
})
}
}
}, },
methods: { methods: {
// 隐藏功能菜单 checkNewFriendPending() {
hidePop() { im.getPendingList((pendings) => {
this.showPop = false this.hasNewFriends = pendings.length
this.pickedItem = {}
setTimeout(() => {
this.showShade = false
}, 250)
},
// 点击会话功能菜单
pickerMenu(e) {
const index = Number(e.currentTarget.dataset.index)
if (index == 0) {
RongIMLib.setConversationToTop(this.pickedItem.conversationType, this.pickedItem.targetId, !this
.pickedItem.isTop)
} else {
RongIMLib.removeConversation(this.pickedItem.conversationType, this.pickedItem.targetId)
}
im.setNotifyBadge()
this.getConversationList()
this.hidePop()
},
// 长按会话,展示功能菜单
onLongPress(e) {
let [touches, style, item] = [e.touches[0], "", e.currentTarget.dataset.item]
if (touches.clientY > (this.winSize.height / 2)) {
style = `bottom:${this.winSize.height-touches.clientY}px;`
} else {
style = `top:${touches.clientY}px;`
}
if (touches.clientX > (this.winSize.witdh / 2)) {
style += `right:${this.winSize.witdh-touches.clientX}px`
} else {
style += `left:${touches.clientX}px`
}
this.popButton[0] = item.isTop ? '取消置顶' : '置顶聊天'
this.popStyle = style
this.pickedItem = item
this.$nextTick(() => {
setTimeout(() => {
this.showPop = true;
}, 10)
}) })
}, },
// 检查登录 // 检查登录
@@ -196,56 +86,41 @@
} }
return true return true
}, },
// 获取私聊的会话列表
getConversationList() { getConversationList() {
const count = 1000 const count = 1000
const timestamp = 0 const timestamp = 0
RongIMLib.getConversationList([RongIMLib.ConversationType.PRIVATE], count, timestamp, (res) => { RongIMLib.getConversationList([1, 3], count, timestamp, (res) => {
if (res.code === 0) { if (res.code === 0) {
console.log(res.conversations);
this.conversations = res.conversations this.conversations = res.conversations
} }
}) })
}, },
// 进入聊天的详情页面,清理未读消息数量
toDetail(item) {
this.hidePop()
uni.navigateTo({
url: '/pages/im/private/chat?targetId=' + item.targetId + '&conversationType=' + item
.conversationType
})
},
toFriend(targetId) {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + targetId
})
},
// 点击按钮
onNav(name, params) {
if (this.toLogin) {
if (name === '') {
uni.showToast({
title: '开发中,敬请期待',
icon: 'none'
})
return
}
this.$Router.push({
name,
params
})
}
},
// 调起扫码 // 调起扫码
scanQrCode() { scanQrCode() {
uni.scanCode({ uni.scanCode({
success: (res) => { success: (res) => {
if (res.scanType == 'QR_CODE') { if (res.scanType == 'QR_CODE') {
res.result.substr(0, 10) == 'ADDFRIEND|' if (res.result.substr(0, 10) == 'ADDFRIEND|') {
uni.navigateTo({ uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + res.result.substr(10) url: '/pages/im/friends/info?targetId=' + res.result.substr(10)
}) })
} else if (res.result.substr(0, 10) == 'JOINGROUP|') {
uni.navigateTo({
url: '/pages/im/group/apply?targetId=' + res.result.substr(10)
})
} else {
uni.showToast({
title: '暂不支持的二维码'
})
} }
} }
}
})
},
toFriendList() {
uni.navigateTo({
url: '/pages/im/friends/index'
}) })
} }
} }
@@ -253,7 +128,13 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// header // contents
.contents {
background-color: $window-color;
min-height: 100vh;
padding-top: 90rpx + 20rpx;
box-sizing: border-box;
.custom-header { .custom-header {
@extend .ios-top; @extend .ios-top;
background: $window-color; background: $window-color;
@@ -269,19 +150,18 @@
justify-content: space-between; justify-content: space-between;
height: 60rpx; height: 60rpx;
line-height: 60rpx; line-height: 60rpx;
.tabs { .tabs {
.item { .item {
position: relative; position: relative;
margin-left: $margin;
display: inline-block; display: inline-block;
font-size: $title-size-lg; font-size: $title-size-lg;
color: $text-gray; color: $text-gray;
padding: 0 ($padding - 10); padding: 0 ($padding - 10);
border-radius: 30rpx; border-radius: 30rpx;
&:first-child {
margin: 0; &.active {
}
&.show {
background: rgba($color: $main-color, $alpha: .1); background: rgba($color: $main-color, $alpha: .1);
color: $main-color; color: $main-color;
font-weight: bold; font-weight: bold;
@@ -291,6 +171,7 @@
.btns { .btns {
.item { .item {
position: relative;
display: inline-block; display: inline-block;
margin-left: $margin; margin-left: $margin;
} }
@@ -298,13 +179,6 @@
} }
} }
// contents
.contents {
background-color: $window-color;
min-height: 100vh;
padding-top: 90rpx + 20rpx;
box-sizing: border-box;
.null-list { .null-list {
height: 100vh; height: 100vh;
text-align: center; text-align: center;
@@ -320,105 +194,6 @@
box-sizing: border-box; box-sizing: border-box;
} }
} }
.message {
background: white;
padding: 20rpx 0 0 20rpx;
position: relative;
display: flex;
&.is-top {
background: $window-color;
border-bottom: #e8e8e8;
}
.avatar {
position: relative;
.u-badge {
z-index: 998;
}
}
.content {
margin-left: 30rpx;
width: calc(100% - 46px);
box-sizing: border-box;
position: relative;
.header {
display: flex;
justify-content: space-between;
.name {
font-size: $title-size + 2;
color: #454545;
color: #454545;
}
.time {
font-size: $title-size-sm;
color: $text-gray-m;
position: absolute;
right: 30rpx;
}
}
.preview {
word-break: break-all;
color: $text-gray-m;
padding-top: $padding - 20;
padding-bottom: $padding;
font-size: $title-size-m;
height: 32rpx;
line-height: 32rpx;
width: 500rpx;
@extend .nowrap;
}
}
}
}
/* 遮罩 */
.shade {
position: fixed;
width: 100%;
height: 100%;
.pop {
position: fixed;
z-index: 101;
width: 200rpx;
box-sizing: border-box;
font-size: 28rpx;
text-align: left;
color: #333;
background-color: #fff;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
line-height: 80rpx;
transition: transform 0.15s ease-in-out 0s;
user-select: none;
-webkit-touch-callout: none;
transform: scale(0, 0);
&.show {
transform: scale(1, 1);
}
&>view {
padding: 0 20rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
user-select: none;
-webkit-touch-callout: none;
&:active {
background-color: #f3f3f3;
}
}
}
} }
.u-border-bottom { .u-border-bottom {

View File

@@ -7,8 +7,7 @@
<text class="text">{{ customCN(item.sentTime) }}</text> <text class="text">{{ customCN(item.sentTime) }}</text>
</view> </view>
<view class="cell-item" :class="item.messageDirection == 1 ? 'right' : 'left'"> <view class="cell-item" :class="item.messageDirection == 1 ? 'right' : 'left'">
<image class="avatar" :src="userInfo.portraitUrl" mode="aspectFill" <u-avatar class="avatar" size="36" shape="square" @click="showUser(targetId, item.messageDirection)" :src="userInfo.portraitUrl" />
@click="showUser(targetId, item.messageDirection)"></image>
<view class="msg"> <view class="msg">
<show-voice v-if="item.objectName === 'RC:HQVCMsg'" :guest="item.messageDirection == 1" <show-voice v-if="item.objectName === 'RC:HQVCMsg'" :guest="item.messageDirection == 1"
:msg="item.content" /> :msg="item.content" />
@@ -24,24 +23,7 @@
</cell> </cell>
<cell class="cell-footer" ref="chatBottom"></cell> <cell class="cell-footer" ref="chatBottom"></cell>
</list> </list>
<!-- footer --> <sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getMessageList()" />
<view class="footer">
<view class="msg-type" @click="changeMessageType">
<image class="icon" src="@/static/icon/key-icon.png" v-if="chatType === 0" mode="widthFix">
</image>
<image class="icon" src="@/static/icon/msg-icon.png" v-if="chatType === 1" mode="widthFix">
</image>
</view>
<sent-voice v-if="chatType === 0" :conversationType="conversationType" :targetId="targetId"
@success="getMessageList" />
<sent-text v-if="chatType === 1" :conversationType="conversationType" :targetId="targetId"
@success="getMessageList" />
<view class="msg-type msg-popups" @click="scrollBottom('msgPopups')">
<image class="icon" src="@/static/icon/popups-icon.png"></image>
</view>
</view>
<!-- 弹出层 -->
<sent-popups :show="showPopups" :conversationType="conversationType" :targetId="targetId" @success="() => {showPopups = false, getMessageList()}"></sent-popups>
</view> </view>
</template> </template>
@@ -54,9 +36,7 @@
import showVoice from '../components/showVoice' import showVoice from '../components/showVoice'
import showImage from '../components/showImage' import showImage from '../components/showImage'
import showText from '../components/showText' import showText from '../components/showText'
import sentText from '../components/sentText' import sentMessageBar from '../components/sentMessageBar'
import sentVoice from '../components/sentVoice'
import sentPopups from '../components/sentPopups'
const ChatList = uni.requireNativePlugin('dom') const ChatList = uni.requireNativePlugin('dom')
@@ -70,31 +50,23 @@
name: '', name: '',
userId: '', userId: '',
portraitUrl: '' portraitUrl: ''
}, }
chatType: 1, // 0 语音1 文本
showPopups: false,
inputFocus: false // 输入框是否获得了焦点
} }
}, },
components: { components: {
sentMessageBar,
showVoice, showVoice,
showImage, showImage,
showText, showText
sentText,
sentVoice,
sentPopups
}, },
onLoad(e) { onLoad(e) {
this.targetId = e.targetId this.targetId = e.targetId
this.conversationType = e.conversationType // 会话类型 this.userInfo = this.$store.getters.contactInfo(this.targetId)
this.userInfo = this.$store.getters.userInfo(this.targetId)
// 获取消息列表
this.initMessageList()
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: this.userInfo.name title: this.userInfo.name
}) })
// 获取消息列表
this.getMessageList()
// 监听消息已读状态 // 监听消息已读状态
uni.$on('onReadReceiptReceived', (data) => { uni.$on('onReadReceiptReceived', (data) => {
if (data.targetId == this.targetId) { if (data.targetId == this.targetId) {
@@ -104,27 +76,17 @@
// 监听收到新消息,判断是否是当前会话,更新会话内容 // 监听收到新消息,判断是否是当前会话,更新会话内容
uni.$on('onReceiveMessage', (msg) => { uni.$on('onReceiveMessage', (msg) => {
if (msg.targetId == this.targetId) { if (msg.targetId == this.targetId) {
this.initMessageList() this.getMessageList()
} }
}) })
}, },
methods: { onBackPress() {
initMessageList() { uni.$off('onReceiveMessage')
this.getMessageList()
// 清理当前会话,未读消息数量
RongIMLib.clearMessagesUnreadStatus(this.conversationType, this.targetId, new Date().getTime())
// 发送消息已读状态给对方
RongIMLib.sendReadReceiptMessage(this.conversationType, this.targetId, new Date().getTime())
// 更新badge提醒数量
im.setNotifyBadge()
}, },
methods: {
customCN(val) { customCN(val) {
return timeCustomCN(val) return timeCustomCN(val)
}, },
// 切换聊天类型,语音/文本
changeMessageType() {
this.chatType = this.chatType === 1 ? 0 : 1
},
// 获取消息列表 // 获取消息列表
getMessageList() { getMessageList() {
im.getMessageList( im.getMessageList(
@@ -134,7 +96,6 @@
10, 10,
true, true,
(messages) => { (messages) => {
console.log('获取到的消息', messages);
this.messages = messages.reverse() this.messages = messages.reverse()
this.scrollBottom() this.scrollBottom()
}) })
@@ -148,9 +109,12 @@
}, },
// 滚动到底部 // 滚动到底部
scrollBottom(type) { scrollBottom(type) {
if(type === 'msgPopups'){ // 清理当前会话,未读消息数量
this.showPopups = !this.showPopups RongIMLib.clearMessagesUnreadStatus(this.conversationType, this.targetId, new Date().getTime() + 1100)
} // 发送消息已读状态给对方
RongIMLib.sendReadReceiptMessage(this.conversationType, this.targetId, new Date().getTime())
// 更新badge提醒数量
im.setNotifyBadge()
setTimeout(() => { setTimeout(() => {
let el = this.$refs.chatBottom let el = this.$refs.chatBottom
ChatList.scrollToElement(el, { ChatList.scrollToElement(el, {
@@ -168,14 +132,18 @@
.chat { .chat {
background: $window-color; background: $window-color;
flex: 1; flex: 1;
.body { .body {
flex: 1; flex: 1;
.cell { .cell {
padding: 10rpx 30rpx; padding: 10rpx 30rpx;
.time { .time {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding-bottom: 20rpx; padding-bottom: 20rpx;
.text { .text {
background: #fff; background: #fff;
font-size: 24rpx; font-size: 24rpx;
@@ -204,13 +172,6 @@
} }
} }
.avatar {
width: 78rpx;
height: 78rpx;
background-color: white;
border-radius: 10rpx;
}
.msg { .msg {
margin: 0 20rpx; margin: 0 20rpx;
@@ -230,22 +191,5 @@
} }
} }
} }
.footer {
background: white;
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
flex-direction: row;
.msg-type {
width: 70rpx;
height: 70rpx;
.icon {
margin: 5rpx;
width: 60rpx;
height: 60rpx;
}
}
}
} }
</style> </style>

View File

@@ -60,11 +60,17 @@ export default {
healthSports(data).then(res => { healthSports(data).then(res => {
this.lists = this.lists.concat(res.data); this.lists = this.lists.concat(res.data);
this.has_more = res.page.has_more; this.has_more = res.page.has_more;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 显示弹窗内容 // 显示弹窗内容
addSport(item) { addSport(item) {
console.log(item);
this.selectSports = item; this.selectSports = item;
this.selectSports.duration = 60; this.selectSports.duration = 60;
this.addSportsShow = true; this.addSportsShow = true;
@@ -99,7 +105,6 @@ export default {
//#region 搜索相关方法 start //#region 搜索相关方法 start
// 点击搜索左侧按钮 // 点击搜索左侧按钮
searchCustom(e) { searchCustom(e) {
console.log(e);
this.name = e; this.name = e;
this.reset(); this.reset();
}, },

View File

@@ -8,49 +8,31 @@
<template> <template>
<view class="add-foods"> <view class="add-foods">
<view class="re"> <view class="re"> <view>低等热量</view> <view>中等热量</view> <view>高等热量</view> </view>
<view>低等热量</view>
<view>中等热量</view>
<view>高等热量</view>
</view>
<!-- 搜索页面 --> <!-- 搜索页面 -->
<u-search <u-search :show-action="true" actionText="搜索" :animation="true" :clearabled="true" placeholder="请输入食品名称"
:show-action="true" @custom="searchCustom" @clear="clearSearch" v-model="name" />
actionText="搜索"
:animation="true"
:clearabled="true"
placeholder="请输入食品名称"
@custom="searchCustom"
@clear="clearSearch"
v-model="name"
/>
<!-- 食品列表 --> <!-- 食品列表 -->
<goodsList <goodsList :lists="lists" type="dian" @addGoods="addGoods" />
:lists="lists"
type="dian"
@addGoods="addGoods"
/>
<!-- 添加食谱弹窗 --> <!-- 添加食谱弹窗 -->
<addFoods <addFoods v-if="addShow" :addShow="addShow" :selectGoods="selectGoods" :decimals="true" @confirm="confirmHandle"
v-if="addShow" @close="closeHandle" @tabGoodsInfo="tabGoodsInfo" max="999" />
:addShow="addShow"
:selectGoods="selectGoods"
:decimals="true"
@confirm="confirmHandle"
@close="closeHandle"
@tabGoodsInfo="tabGoodsInfo"
max="999"
/>
</view> </view>
</template> </template>
<script> <script>
import goodsList from "@/components/foods"; import goodsList from "@/components/foods";
import addFoods from "@/components/add-goods-template/add-goods-template"; import addFoods from "@/components/add-goods-template/add-goods-template";
import { healthFoods, addHealthFoods } from "@/apis/interfaces/foods.js"; import {
healthFoods,
addHealthFoods
} from "@/apis/interfaces/foods.js";
import moment from "moment"; import moment from "moment";
export default { export default {
components: { goodsList, addFoods }, components: {
goodsList,
addFoods
},
data() { data() {
return { return {
addShow: false, // 添加食品显示 addShow: false, // 添加食品显示
@@ -72,7 +54,7 @@ export default {
} }
//没有id的时候就是新增要处理type //没有id的时候就是新增要处理type
this.type = this.$Route.query.type; this.type = this.$Route.query.type;
// this.getFoods(); this.date = this.$Route.query.date;
}, },
onLoad() { onLoad() {
this.getFoods(); this.getFoods();
@@ -97,14 +79,19 @@ export default {
name: this.name, name: this.name,
}; };
healthFoods(data).then((res) => { healthFoods(data).then((res) => {
console.log(res);
this.lists = this.lists.concat(res.data); this.lists = this.lists.concat(res.data);
this.has_more = res.page.has_more; this.has_more = res.page.has_more;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 监听点击键盘触发返回值新增食品 // 监听点击键盘触发返回值新增食品
confirmHandle(value) { confirmHandle(value) {
console.log(value);
// 新添加食物 // 新添加食物
let data = { let data = {
type: this.type, type: this.type,
@@ -118,9 +105,18 @@ export default {
// 添加食物 // 添加食物
addHealthFoods(data) { addHealthFoods(data) {
addHealthFoods(data).then((res) => { addHealthFoods(data).then((res) => {
console.log(res);
this.addShow = false; this.addShow = false;
this.$Router.back(); this.$Router.back();
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration:2000,
mask:true
})
setTimeout(()=>{
this.$Router.back();
},2000)
}); });
}, },
closeHandle() { closeHandle() {
@@ -134,7 +130,6 @@ export default {
}, },
// 点击搜索左侧按钮 // 点击搜索左侧按钮
searchCustom(e) { searchCustom(e) {
console.log(e);
this.name = e; this.name = e;
this.reset(); this.reset();
}, },
@@ -163,6 +158,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.add-foods { .add-foods {
padding: $padding; padding: $padding;
.re { .re {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -171,6 +167,7 @@ export default {
box-sizing: border-box; box-sizing: border-box;
padding: $padding $padding * 2; padding: $padding $padding * 2;
font-size: $title-size-m; font-size: $title-size-m;
view:before { view:before {
width: 20rpx; width: 20rpx;
height: 20rpx; height: 20rpx;
@@ -178,13 +175,17 @@ export default {
display: inline-block; display: inline-block;
margin-right: 10rpx; margin-right: 10rpx;
content: ""; content: "";
} }
view:nth-child(3):before { view:nth-child(3):before {
background: #fa624d; background: #fa624d;
} }
view:nth-child(2):before { view:nth-child(2):before {
background: #fbbf0f; background: #fbbf0f;
} }
view:nth-child(1):before { view:nth-child(1):before {
background: #02c7bd; background: #02c7bd;
} }

View File

@@ -8,74 +8,63 @@
<template> <template>
<view class="drink" v-if="loaded"> <view class="drink" v-if="loaded">
<!-- 自定义导航部分 -->
<u-navbar :safeAreaInsetTop="true" :fixed='true' bgColor="#34ce98" :autoBack="true">
<view class="u-nav-slot" slot="left">
<u-icon name="arrow-leftward" :bold="true" size="20" color="#fff" />
</view>
<view class="u-nav-slot u-center" slot="center" @click="dateShow = true,dateLists()">
<u-icon name="play-left-fill" size="14" color="#fff" @click="datePreNext('before')" />
<view class="date">
<u-icon name="calendar" color="#fff" label-color="#fff" width="150" :label="today" label-size="14"
size="20" />
</view>
<u-icon name="play-right-fill" size="14" color="#fff" @click="datePreNext('after')" />
</view>
<view class="u-nav-slot" slot="right">
<u-icon :name="require('@/static/icon/sign-icon.gif')" :bold="true" size="30"
@click="$Router.push({name:'signIndex'})" />
</view>
</u-navbar>
<!-- 喝水及水杯文字 --> <!-- 喝水及水杯文字 -->
<view class="drink-content"> <view class="drink-content">
<view class="title" v-if="!water.is_complete"> <view class="title" v-if="!water.is_complete"> 再喝 <span class="num">{{ water.lack.cup }}</span> <span
再喝 class="total">{{ water.lack.value }}ml</span> </view>
<span class="num">{{ water.lack.cup }}</span>
<span class="total">{{ water.lack.value }}ml</span>
</view>
<view class="title" v-if="water.is_complete"> <view class="title" v-if="water.is_complete">
已喝 已喝 <span class="num">{{ water.total }}ml</span>
<span class="num">{{ water.total }}ml</span> <u-image class="is_complete" :src="require('../../static/imgs/target.png')" :lazy-load="true"
<u-image class="is_complete" :src="require('../../static/imgs/target.png')" :lazy-load="true" mode="widthFix" width="140rpx" /> mode="widthFix" width="140rpx" />
</view> </view>
<!-- 水杯动态图片 --> <!-- 水杯动态图片 -->
<view class="wave-content"> <view class="wave-content">
<u-image class="grass" :src="require('../../static/imgs/gress.png')" :lazy-load="true" mode="scaleToFill" width="320rpx" height="520rpx" /> <u-image class="grass" :src="require('../../static/imgs/gress.png')" :lazy-load="true"
mode="scaleToFill" width="320rpx" height="520rpx" />
<view class="wave" :style="{ '--ballPercent': -ballPercent + 40 + '%' }"></view> <view class="wave" :style="{ '--ballPercent': -ballPercent + 40 + '%' }"></view>
</view> </view>
<!-- 目标 --> <!-- 目标 -->
<view class="water-target"> <view class="water-target">
<view class="target-item" @click="targetShow = true"> <view class="target-item" @click="targetShow = true"> 今日目标
今日目标 <u-icon class="target-icon" name="arrow-right" color="#666" size="14" :bold="true"
<u-icon :label="water.target + 'ml'" labelPos="left" labelSize="16" labelColor="#666" space="6" />
class="target-icon"
name="arrow-right"
color="#666"
size="14"
:bold="true"
:label="water.target + 'ml'"
labelPos="left"
labelSize="16"
labelColor="#666"
space="6"
/>
</view> </view>
<view class="target-item" @click="waterCShow = true"> <view class="target-item" @click="waterCShow = true"> 水杯容量
水杯容量 <u-icon class="target-icon" name="arrow-right" color="#666" size="14" :bold="true"
<u-icon class="target-icon" name="arrow-right" color="#666" size="14" :bold="true" :label="water.ml + 'ml'" labelPos="left" labelSize="16" labelColor="#666" space="6" /> :label="water.ml + 'ml'" labelPos="left" labelSize="16" labelColor="#666" space="6" />
</view> </view>
</view> </view>
<!-- 目标弹出层 --> <!-- 目标弹出层 -->
<view> <view>
<u-picker <u-picker :show="targetShow" :columns="tagerts" title="每天喝水目标" keyName="label" confirmColor="#34ce98"
:show="targetShow" :closeOnClickOverlay="true" @close="targetShow = false" @confirm="targetSure('1', $event)"
:columns="tagerts" :defaultIndex="tagertsDefaultIndex" />
title="每天喝水目标" <u-picker :show="waterCShow" :columns="cup_mls" title="设置水杯容量" keyName="label" confirmColor="#34ce98"
keyName="label" :closeOnClickOverlay="true" @close="waterCShow = false" @confirm="targetSure('2', $event)"
confirmColor="#34ce98" :defaultIndex="cupDefaultIndex" />
:closeOnClickOverlay="true"
@close="targetShow = false"
@confirm="targetSure('1', $event)"
:defaultIndex="tagertsDefaultIndex"
/>
<u-picker
:show="waterCShow"
:columns="cup_mls"
title="设置水杯容量"
keyName="label"
confirmColor="#34ce98"
:closeOnClickOverlay="true"
@close="waterCShow = false"
@confirm="targetSure('2', $event)"
:defaultIndex="cupDefaultIndex"
/>
</view> </view>
<!-- 加水 --> <!-- 加水 -->
<view class="add-water" @click="drinkWater"> <view class="add-water" @click="drinkWater">
<u-image class="grass" :src="require('../../static/imgs/gress2.png')" :lazy-load="true" mode="scaleToFill" width="60rpx" height="80rpx" /> <u-image class="grass" :src="require('../../static/imgs/gress2.png')" :lazy-load="true"
mode="scaleToFill" width="60rpx" height="80rpx" />
<span>一杯水</span> <span>一杯水</span>
<u-icon class="add-icon" name="plus-circle-fill" color="#34ce98" size="24" /> <u-icon class="add-icon" name="plus-circle-fill" color="#34ce98" size="24" />
</view> </view>
@@ -84,25 +73,38 @@
<view class="--history"> <view class="--history">
<view class="title">喝水记录</view> <view class="title">喝水记录</view>
<template v-if="logs.length > 0"> <template v-if="logs.length > 0">
<view class="lists" v-for="item in logs" :key="item.water_log_id" @longpress="delWater(item.water_log_id)"> <view class="lists" v-for="item in logs" :key="item.water_log_id"
<view class="lists-water"><u-icon size="30" :name="require('../../static/icon/water-icon.png')" /></view> @longpress="delWater(item.water_log_id)">
<view class="list-item"> <view class="lists-water">
<view class="list-item-title"> <u-icon size="30" :name="require('../../static/icon/water-icon.png')" />
<span>{{ item.time }}</span>
</view> </view>
{{ item.ml }}ml <view class="list-item">
<view class="list-item-title"> <span>{{ item.time }}</span> </view> {{ item.ml }}ml
</view> </view>
</view> </view>
</template> </template>
<view v-else class="no-drink">今天一杯水还没有喝呢来一杯吧~</view> <view v-else class="no-drink">今天一杯水还没有喝呢来一杯吧~</view>
</view> </view>
<!-- 选择日历 -->
<dateTemplate :lists="calendarList" :today="today" :month="month" :dateShow="dateShow" type='drink'
@backDate="backDate" @dateClick="dateClick" @closeDate="closeDate" @datePreNext="datePreNext" />
</view> </view>
</template> </template>
<script> <script>
import { waters, setWaters, drinkWater, delDrinkWater } from '@/apis/interfaces/drink'; import {
waters,
setWaters,
drinkWater,
delDrinkWater,
dateList
} from '@/apis/interfaces/drink';
import moment from 'moment'; import moment from 'moment';
import dateTemplate from '@/components/date-template/index.vue'
export default { export default {
components: {
dateTemplate
},
data() { data() {
return { return {
ballPercent: 0, // 喝水比例 ballPercent: 0, // 喝水比例
@@ -114,30 +116,46 @@ export default {
waterCShow: false, waterCShow: false,
cup_mls: [], // 水杯列表 cup_mls: [], // 水杯列表
cupDefaultIndex: ['2'], // 目标默认index cupDefaultIndex: ['2'], // 目标默认index
loaded: false loaded: false,
today: moment(new Date()).format('YYYY-MM-DD'), // 当前时间
month: moment(new Date()).format('YYYY-MM'), //当前月份
dateShow: false, // 日历展示
calendarList: [],
dateType: '', // before after ''
}; };
}, },
onShow() { onShow() {
this.getWaters(); this.getWaters();
this.dateLists();
}, },
methods: { methods: {
// 获取喝水页面信息 // 获取喝水页面信息
getWaters() { getWaters() {
waters().then(res => { let data = {
date: this.today,
// type:this.dateType
}
waters(data).then(res => {
this.cup_mls = [res.cup_mls]; this.cup_mls = [res.cup_mls];
this.tagerts = [res.tagerts]; this.tagerts = [res.tagerts];
this.water = res.water; this.water = res.water;
this.logs = res.logs; this.logs = res.logs;
this.ballPercent = res.water.lack.ratio; this.ballPercent = res.water.lack.ratio;
this.cupDefaultIndex = [res.cup_mls.findIndex(item => item.number === res.water.ml)]; this.cupDefaultIndex = [res.cup_mls.findIndex(item => item.number === res.water.ml)];
this.tagertsDefaultIndex = [res.tagerts.findIndex(item => item.number === res.water.target)]; this.tagertsDefaultIndex = [res.tagerts.findIndex(item => item.number === res.water
.target)];
this.loaded = true; this.loaded = true;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 确认方法index===1 每日目标 2水杯容量 // 确认方法index===1 每日目标 2水杯容量
targetSure(index, e) { targetSure(index, e) {
// console.log("触发了targetSure", index, e.value[0]);
// let date = moment(new Date()).format("YYYY--MM--DD");
let params = {}; let params = {};
if (index === '1') { if (index === '1') {
params = { params = {
@@ -156,12 +174,30 @@ export default {
this.getWaters(); this.getWaters();
this.waterCShow = false; this.waterCShow = false;
this.targetShow = false; this.targetShow = false;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 喝水 // 喝水
drinkWater() { drinkWater() {
drinkWater().then(res => { let data = {
date: this.today
}
drinkWater(data).then(res => {
this.getWaters(); this.getWaters();
this.dateLists()
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 删除和喝水记录 // 删除和喝水记录
@@ -181,18 +217,100 @@ export default {
.catch(err => { .catch(err => {
uni.showToast({ uni.showToast({
title: err.message, title: err.message,
icon: 'none' icon: "none",
}); duration: 2000,
mask: true
})
}); });
} }
} }
}); });
},
//#region 日历操作相关
// 日历列表
dateLists() {
let data = {
month: this.month,
type: this.dateType
} }
dateList(data).then(res => {
this.calendarList = res.calendar
this.dateType = ''
this.month = res.month
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
})
},
// 选择日期
dateClick(item) {
this.today = item.today
this.month = item.today
this.reset()
},
// 返回到今日
backDate() {
this.today = moment(new Date()).format('YYYY-MM-DD')
this.reset()
},
// 上一个月或者下一个月
datePreNext(type) {
this.dateType = type
this.dateLists()
},
// 关闭日历
closeDate() {
this.month = this.today
this.dateShow = false
},
// 重置日历数据
reset() {
this.calendarList = []
this.dateLists()
this.getWaters()
this.closeDate()
}
//#endregion 日历操作相关
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.drink { .drink {
padding-top: 120rpx;
// 顶部日历筛选部分
.u-center {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
box-sizing: border-box;
.date {
background-color: rgba($color: #000000, $alpha: .1);
color: #fff;
min-width: 340rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 8rpx 20rpx;
border-radius: $radius * 2;
margin: 0 10rpx;
font-size: $title-size - 2;
}
.play-right-fill {
padding: $padding !important;
background-color: pink;
}
}
// 喝水 水杯及文字 // 喝水 水杯及文字
.drink-content { .drink-content {
@@ -203,6 +321,7 @@ export default {
box-sizing: border-box; box-sizing: border-box;
// padding: $padding 0; // padding: $padding 0;
position: relative; position: relative;
// 标题 再喝水 // 标题 再喝水
.title { .title {
font-size: $title-size + 4; font-size: $title-size + 4;
@@ -210,22 +329,26 @@ export default {
font-weight: normal; font-weight: normal;
margin: $margin * 2; margin: $margin * 2;
position: relative; position: relative;
.is_complete { .is_complete {
position: absolute; position: absolute;
top: 30rpx; top: 30rpx;
right: -120rpx; right: -120rpx;
} }
.num { .num {
font-size: $title-size * 2.3; font-size: $title-size * 2.3;
padding: 0 $padding * 0.3; padding: 0 $padding * 0.3;
font-weight: bold; font-weight: bold;
} }
.total { .total {
font-size: $title-size; font-size: $title-size;
color: $text-gray-m; color: $text-gray-m;
padding-left: $padding * 0.2; padding-left: $padding * 0.2;
} }
} }
// 加一杯水 // 加一杯水
.add-water { .add-water {
display: flex; display: flex;
@@ -237,17 +360,20 @@ export default {
color: $text-color; color: $text-color;
margin-top: $margin * 2; margin-top: $margin * 2;
position: relative; position: relative;
span { span {
padding-top: $padding * 0.4; padding-top: $padding * 0.4;
color: $text-gray-m; color: $text-gray-m;
font-size: $title-size; font-size: $title-size;
} }
.add-icon { .add-icon {
position: absolute; position: absolute;
top: $margin + 8; top: $margin + 8;
right: 0; right: 0;
} }
} }
// 目标 // 目标
.water-target { .water-target {
display: flex; display: flex;
@@ -261,22 +387,27 @@ export default {
z-index: 110; z-index: 110;
right: $padding * 1.4; right: $padding * 1.4;
top: 50%; top: 50%;
.target-item { .target-item {
margin-top: $margin * 1.6; margin-top: $margin * 1.6;
.target-icon { .target-icon {
padding-top: $padding * 0.5; padding-top: $padding * 0.5;
} }
} }
} }
} }
// 喝水记录 // 喝水记录
.--history { .--history {
padding: $padding; padding: $padding;
.no-drink { .no-drink {
color: $text-gray-m; color: $text-gray-m;
font-size: $title-size-m; font-size: $title-size-m;
padding-top: $padding + 10; padding-top: $padding + 10;
} }
// 标题 // 标题
.title { .title {
font-size: $title-size + 4; font-size: $title-size + 4;
@@ -290,6 +421,7 @@ export default {
box-sizing: border-box; box-sizing: border-box;
padding-left: $padding; padding-left: $padding;
padding-bottom: $padding; padding-bottom: $padding;
&::before { &::before {
position: absolute; position: absolute;
content: ''; content: '';
@@ -310,6 +442,7 @@ export default {
justify-content: space-between; justify-content: space-between;
box-sizing: border-box; box-sizing: border-box;
border-bottom: solid 1rpx #f7f7f7; border-bottom: solid 1rpx #f7f7f7;
.lists-water { .lists-water {
background-image: linear-gradient(to right, $main-color, $main-color); background-image: linear-gradient(to right, $main-color, $main-color);
width: 90rpx; width: 90rpx;
@@ -321,6 +454,7 @@ export default {
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
} }
.list-item { .list-item {
flex: 1; flex: 1;
margin-left: $margin * 0.7; margin-left: $margin * 0.7;
@@ -332,6 +466,7 @@ export default {
justify-content: space-between; justify-content: space-between;
box-sizing: border-box; box-sizing: border-box;
margin: $margin 0 $margin $margin * 0.7; margin: $margin 0 $margin $margin * 0.7;
.list-item-title { .list-item-title {
font-size: $title-size + 3; font-size: $title-size + 3;
color: $text-color; color: $text-color;
@@ -341,6 +476,7 @@ export default {
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
font-weight: bold; font-weight: bold;
span { span {
margin-top: $margin * 0.4; margin-top: $margin * 0.4;
background-color: #f7f7f7; background-color: #f7f7f7;
@@ -354,13 +490,15 @@ export default {
} }
} }
} }
// 水杯动画 // 水杯动画
.wave-content { .wave-content {
position: relative; position: relative;
z-index: 110; z-index: 1;
.grass { .grass {
position: relative; position: relative;
z-index: 120099; z-index: 1;
} }
.wave { .wave {
@@ -372,7 +510,8 @@ export default {
overflow: hidden; overflow: hidden;
top: 10rpx; top: 10rpx;
left: 20rpx; left: 20rpx;
z-index: 10; z-index: 1;
&::before, &::before,
&::after { &::after {
content: ''; content: '';
@@ -385,8 +524,9 @@ export default {
border-radius: 45%; border-radius: 45%;
transform: translate(-50%, -70%) rotate(0); transform: translate(-50%, -70%) rotate(0);
animation: rotate 4s linear infinite; animation: rotate 4s linear infinite;
z-index: 10; z-index: 1;
} }
&::after { &::after {
border-radius: 47%; border-radius: 47%;
background-color: rgba(255, 255, 255, 0.9); background-color: rgba(255, 255, 255, 0.9);
@@ -400,6 +540,7 @@ export default {
50% { 50% {
transform: translate(-50%, -73%) rotate(180deg); transform: translate(-50%, -73%) rotate(180deg);
} }
100% { 100% {
transform: translate(-50%, -70%) rotate(360deg); transform: translate(-50%, -70%) rotate(360deg);
} }

View File

@@ -3,33 +3,32 @@
* @Author: Aimee·Zhang * @Author: Aimee·Zhang
* @Date: 2022-01-11 08:54:49 * @Date: 2022-01-11 08:54:49
* @LastEditors: Aimee·Zhang * @LastEditors: Aimee·Zhang
* @LastEditTime: 2022-01-20 10:05:15 * @LastEditTime: 2022-02-08 10:41:15
--> -->
<template> <template>
<view class="record--foods"> <view class="record--foods">
<!-- 自定义导航部分 -->
<u-navbar :safeAreaInsetTop="true" :fixed='true' bgColor="#34ce98" :autoBack="true">
<view class="u-nav-slot" slot="left"> <u-icon name="arrow-leftward" :bold="true" size="20" color="#fff" /> </view>
<view class="u-nav-slot u-center" slot="center" @click="dateShow = true,dateLists()">
<u-icon name="play-left-fill" size="14" color="#fff" @click="datePreNext('before')" />
<view class="date"> <u-icon name="calendar" color="#fff" label-color="#fff" width="150" :label="today" label-size="14" size="20" /> </view>
<u-icon name="play-right-fill" size="14" color="#fff" @click="datePreNext('after')" />
</view>
<view class="u-nav-slot" slot="right"> <u-icon :name="require('@/static/icon/sign-icon.gif')" :bold="true" size="30" @click="$Router.push({name:'signIndex'})" /> </view>
</u-navbar>
<!-- 饮食进度条 --> <!-- 饮食进度条 -->
<view class="cricle-content"> <view class="cricle-content">
<view class="info"> <view class="info"> 饮食摄入 <span>{{ calorys.intake_total }}</span> </view>
饮食摄入 <arprogress :percent="calorys.exceeds ? 100 : calorys.ratio" inactiveColor="#f5f4f9"
<span>{{ calorys.intake_total }}</span> :activeColor="calorys.exceeds ? '#c50000' : '#34ce98'" width="300" class="cricle" borderWidth="20">
</view>
<arprogress
:percent="calorys.exceeds ? 100 : calorys.ratio"
inactiveColor="#f5f4f9"
:activeColor="calorys.exceeds ? '#f00' : '#34ce98'"
width="300"
class="cricle"
borderWidth="20"
>
<span>{{ calorys.exceeds ? '多吃了' : '还可以吃' }}</span> <span>{{ calorys.exceeds ? '多吃了' : '还可以吃' }}</span>
<span :class="['num', calorys.exceeds ? 'num1' : '']">{{ calorys.amount }}</span> <span :class="['num', calorys.exceeds ? 'num1' : '']">{{ calorys.amount }}</span>
<span>推荐预算{{ calorys.goal }}</span> <span>推荐预算{{ calorys.goal }}</span>
</arprogress> </arprogress>
<view class="info" @click="errToast"> <view class="info" @click="errToast"> 运动消耗 <span>{{ calorys.exercise_total }}</span> </view>
运动消耗
<span>{{ calorys.exercise_total }}</span>
</view>
<view class="ic-left">摄入量推荐</view> <view class="ic-left">摄入量推荐</view>
<u-icon class="ic-day" name="checkmark-circle" color="#34ce98" size="10" :label="`${calorys.days}天`" labelColor="#34ce98" labelSize="10" space="3" /> <u-icon class="ic-day" name="checkmark-circle" color="#34ce98" size="10" :label="`${calorys.days}天`" labelColor="#34ce98" labelSize="10" space="3" />
</view> </view>
@@ -38,30 +37,19 @@
<template v-if="intakes.length > 0"> <template v-if="intakes.length > 0">
<view class="foods-add" v-for="(it, index) in intakes" :key="index"> <view class="foods-add" v-for="(it, index) in intakes" :key="index">
<view class="foods-title"> <view class="foods-title">
<view class="title-left"> <view class="title-left"> {{ it.name }} <span v-if="it.remark">{{ it.remark || '' }}</span> </view>
{{ it.name }} <view class="title-right"> {{ it.total }} <span class="dw">千卡</span> <u-icon name="arrow-right" color="#ddd" size="13" :bold="true" /> </view>
<span v-if="it.remark">{{ it.remark || '' }}</span>
</view>
<view class="title-right">
{{ it.total }}
<span class="dw">千卡</span>
<u-icon name="arrow-right" color="#ddd" size="13" :bold="true" />
</view>
</view> </view>
<goodsList :lists="it.intake" type="no-dian" @editGoods="editGoods" @longClickGoods="longClickGoods" /> <goodsList :lists="it.intake" type="no-dian" @editGoods="editGoods" @longClickGoods="longClickGoods" />
</view> </view>
</template> </template>
<!-- 运动列表 --> <!-- 运动列表 -->
<template v-if="sportsTotal > 0"> <template v-if="sportsTotal > 0">
<view class="foods-title" style="padding-top:50rpx;"> <view class="foods-title" style="padding-top:50rpx;">
<view class="title-left">运动</view> <view class="title-left">运动</view>
<view class="title-right"> <view class="title-right"> {{ sportsTotal }} <span class="dw">千卡</span> <u-icon name="arrow-right" color="#ddd" size="13" :bold="true" /> </view>
{{ sportsTotal }}
<span class="dw">千卡</span>
<u-icon name="arrow-right" color="#ddd" size="13" :bold="true" />
</view> </view>
</view>
<sports type="edit" :lists="sports" @editSport="editSport" @longClick="longClick" /> <sports type="edit" :lists="sports" @editSport="editSport" @longClick="longClick" />
</template> </template>
@@ -73,16 +61,8 @@
</view> </view>
<!-- 加餐模块 --> <!-- 加餐模块 -->
<u-action-sheet <u-action-sheet :actions="addEatList" title="加餐模块" :closeOnClickOverlay="true" :closeOnClickAction="true" @select="selectClick" cancelText="取消" :show="addEatShow" @close="addEatShow = false" />
:actions="addEatList"
title="加餐模块"
:closeOnClickOverlay="true"
:closeOnClickAction="true"
@select="selectClick"
cancelText="取消"
:show="addEatShow"
@close="addEatShow = false"
></u-action-sheet>
<!-- 底部 早餐等菜单 --> <!-- 底部 早餐等菜单 -->
<u-tabbar :fixed="true" :placeholder="true" :safeAreaInsetBottom="true" inactiveColor="#333" @click="tabbarClick"> <u-tabbar :fixed="true" :placeholder="true" :safeAreaInsetBottom="true" inactiveColor="#333" @click="tabbarClick">
<u-tabbar-item text="+早餐" @click="tabbarClick" :icon="require('../../static/imgs/foods-1.png')" /> <u-tabbar-item text="+早餐" @click="tabbarClick" :icon="require('../../static/imgs/foods-1.png')" />
@@ -92,75 +72,88 @@
<u-tabbar-item text="+运动" @click="tabbarClick" :icon="require('../../static/imgs/foods-5.png')" /> <u-tabbar-item text="+运动" @click="tabbarClick" :icon="require('../../static/imgs/foods-5.png')" />
</u-tabbar> </u-tabbar>
<!-- 修改食品弹窗 -->
<!-- 添加食谱弹窗 --> <!-- 添加食谱弹窗 -->
<addFoods <addFoods v-if="addShow" :addShow="addShow" :selectGoods="selectGoods" :decimals="true" @confirm="confirmHandle" @close="closeHandle" @delThis="delThis" @tabGoodsInfo="tabGoodsInfo" max="999" />
v-if="addShow"
:addShow="addShow"
:selectGoods="selectGoods"
:decimals="true"
@confirm="confirmHandle"
@close="closeHandle"
@delThis="delThis"
@tabGoodsInfo="tabGoodsInfo"
max="999"
/>
<!-- 修改运动弹窗 --> <!-- 修改运动弹窗 -->
<addPopup :selectSports="selectSports" :addSportsShow="addSportsShow" @comfirmSport="comfirmSport" @cancleSport="cancleSport" @delSport="delSport" /> <addPopup :selectSports="selectSports" :addSportsShow="addSportsShow" @comfirmSport="comfirmSport" @cancleSport="cancleSport" @delSport="delSport" />
<!-- 选择日历 -->
<dateTemplate :lists="calendarList" :today="today" :month="month" :dateShow="dateShow" type='foods' @backDate="backDate" @dateClick="dateClick" @closeDate="closeDate" @datePreNext="datePreNext" />
</view> </view>
</template> </template>
<script> <script>
import arprogress from '@/components/ar-circle-progress/index.vue';
import goodsList from '@/components/foods';
import { plans, editHealthFoods, delHealthFoods } from '@/apis/interfaces/foods.js';
import moment from 'moment'; import moment from 'moment';
import addFoods from '@/components/add-goods-template/add-goods-template';
import addPopup from '@/components/sports/addPopup';
import sports from '@/components/sports'; import sports from '@/components/sports';
import { editHealthSports, delHealthSports } from '@/apis/interfaces/sport.js'; import goodsList from '@/components/foods';
import addPopup from '@/components/sports/addPopup';
import arprogress from '@/components/ar-circle-progress/index.vue';
import addFoods from '@/components/add-goods-template/add-goods-template';
import dateTemplate from '@/components/date-template/index.vue'
import {
editHealthSports,
delHealthSports
} from '@/apis/interfaces/sport.js';
import {
plans,
editHealthFoods,
delHealthFoods,
dateList
} from '@/apis/interfaces/foods.js';
export default { export default {
components: { components: {
arprogress, arprogress,
goodsList, goodsList,
addFoods, addFoods,
addPopup, addPopup,
sports sports,
dateTemplate
}, },
data() { data() {
return { return {
lists: [],
addShow: false, // 添加食品显示 addShow: false, // 添加食品显示
selectGoods: [], // 选择新增的食品 selectGoods: [], // 选择新增的食品
addEatShow: false, // 加餐弹窗默认不显示 addEatShow: false, // 加餐弹窗默认不显示
addEatList: [ addEatList: [{name: '上午加餐',type: 2},{name: '下午加餐',type: 4},{name: '晚上加餐',type: 6}],
{
name: '上午加餐',
type: 2
},
{
name: '下午加餐',
type: 4
},
{
name: '晚上加餐',
type: 6
}
],
today: moment(new Date()).format('YYYY-MM-DD'),
calorys: {}, // 当日食谱推荐页面的信息 calorys: {}, // 当日食谱推荐页面的信息
intakes: [], // 当日摄入列表 intakes: [], // 当日摄入列表
sports: [], // 运动列表 sports: [], // 运动列表
sportsTotal: 0, sportsTotal: 0,
addSportsShow: false, // 添加运动弹窗显示 addSportsShow: false, // 添加运动弹窗显示
selectSports: {} // 选择新增的运动 selectSports: {}, // 选择新增的运动
today: moment(new Date()).format('YYYY-MM-DD'),// 当前时间
month: moment(new Date()).format('YYYY-MM'), //当前月份
dateShow: false, // 日历展示
calendarList: [],
dateType: '', // before after ''
}; };
}, },
onShow() { onShow() {
this.getList(); this.getList();
this.dateLists(); // 日期列表
}, },
methods: { methods: {
// 获取当前统计页面基本数据
getList() {
plans(this.today).then(res => {
this.calorys = res.calorys;
this.calorys.ratio = Number(this.calorys.ratio);
this.intakes = res.intakes;
this.sports = res.exercises.lists;
this.sportsTotal = res.exercises.total;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
});
},
//#region 运动操作相关
// 编辑运动 // 编辑运动
editSport(item) { editSport(item) {
this.selectSports = { this.selectSports = {
@@ -172,11 +165,8 @@ export default {
exercise_id: item.exercise_id, exercise_id: item.exercise_id,
title: '编辑运动' title: '编辑运动'
}; };
// console.log(this.selectSports);
console.log('编辑运动', item);
this.addSportsShow = true; this.addSportsShow = true;
}, },
// 弹窗确认按钮新增 这里接口报错了 // 弹窗确认按钮新增 这里接口报错了
comfirmSport(show, duration) { comfirmSport(show, duration) {
let params = { let params = {
@@ -186,7 +176,6 @@ export default {
sport_id: this.selectSports.sport_id, // 运动id sport_id: this.selectSports.sport_id, // 运动id
date: this.today // 日期 date: this.today // 日期
}; };
console.log(params);
editHealthSports(params).then(res => { editHealthSports(params).then(res => {
this.addSportsShow = false; this.addSportsShow = false;
this.selectSports = {}; this.selectSports = {};
@@ -194,11 +183,12 @@ export default {
}).catch(err => { }).catch(err => {
uni.showToast({ uni.showToast({
title: err.message, title: err.message,
icon:'none' icon: "none",
duration: 2000,
mask: true
}) })
}); });
}, },
// 弹窗取消按钮 // 弹窗取消按钮
cancleSport(show) { cancleSport(show) {
this.addSportsShow = show; this.addSportsShow = show;
@@ -208,11 +198,17 @@ export default {
let params = { let params = {
exercise_id: this.selectSports.exercise_id // exercise_id: this.selectSports.exercise_id //
}; };
console.log(params);
delHealthSports(params).then(res => { delHealthSports(params).then(res => {
this.addSportsShow = false; this.addSportsShow = false;
this.selectSports = {}; this.selectSports = {};
this.getList(); this.getList();
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 长按删除触发事件运动 // 长按删除触发事件运动
@@ -231,6 +227,10 @@ export default {
} }
}); });
}, },
//#endregion 运动操作相关
//#region 食物操作相关
// 长按删除食品 // 长按删除食品
longClickGoods(e) { longClickGoods(e) {
this.selectGoods = [e]; this.selectGoods = [e];
@@ -254,18 +254,8 @@ export default {
icon: 'none' icon: 'none'
}); });
}, },
getList() {
plans(this.today).then(res => {
this.calorys = res.calorys;
this.calorys.ratio = Number(this.calorys.ratio);
this.intakes = res.intakes;
this.sports = res.exercises.lists;
this.sportsTotal = res.exercises.total;
});
},
// 底部按钮点击触发的事件 早餐1 午餐3 晚餐5 加餐(早2中4晚6) // 底部按钮点击触发的事件 早餐1 午餐3 晚餐5 加餐(早2中4晚6)
tabbarClick(e) { tabbarClick(e) {
console.log(e);
this.tabarIndex = e; this.tabarIndex = e;
if (e === 3) { if (e === 3) {
this.addEatShow = true; this.addEatShow = true;
@@ -277,7 +267,7 @@ export default {
}); });
} else { } else {
uni.navigateTo({ uni.navigateTo({
url: `/pages/record/addFoods?type=${e === 0 ? 1 : e === 1 ? 3 : 5}` url: `/pages/record/addFoods?type=${e === 0 ? 1 : e === 1 ? 3 : 5}&date=${this.today}`
}); });
} }
} }
@@ -285,7 +275,7 @@ export default {
// 选择了加餐跳转 // 选择了加餐跳转
selectClick(e) { selectClick(e) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/record/addFoods?type=${e.type}` url: `/pages/record/addFoods?type=${e.type}&date=${this.today}`
}); });
// 选择加餐 // 选择加餐
}, },
@@ -312,9 +302,15 @@ export default {
// 添加食物 // 添加食物
editHealthFoods(data) { editHealthFoods(data) {
editHealthFoods(data).then(res => { editHealthFoods(data).then(res => {
console.log(res);
this.addShow = false; this.addShow = false;
this.getList(); this.getList();
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 删除该食物 // 删除该食物
@@ -322,6 +318,13 @@ export default {
delHealthFoods(this.selectGoods[0].intake_id).then(res => { delHealthFoods(this.selectGoods[0].intake_id).then(res => {
this.addShow = false; this.addShow = false;
this.getList(); this.getList();
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
// 跳转到食品详情 // 跳转到食品详情
@@ -330,7 +333,58 @@ export default {
name: 'rankingDetails', name: 'rankingDetails',
params: e params: e
}); });
},
//#endregion 食物操作相关
//#region 日历操作相关
// 日历列表
dateLists() {
let data = {
month: this.month,
type: this.dateType
} }
dateList(data).then(res => {
this.calendarList = res.calendar
this.dateType = ''
this.month = res.month
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
})
},
// 选择日期
dateClick(item) {
this.today = item.today
this.month = item.today
this.reset()
},
// 返回到今日
backDate() {
this.today = moment(new Date()).format('YYYY-MM-DD')
this.reset()
},
// 上一个月或者下一个月
datePreNext(type) {
this.dateType = type
this.dateLists()
},
// 关闭日历
closeDate() {
this.month = this.today
this.dateShow = false
},
// 重置日历数据
reset() {
this.calendarList = []
this.dateLists()
this.getList()
this.closeDate()
}
//#endregion 日历操作相关
} }
}; };
</script> </script>
@@ -340,6 +394,37 @@ export default {
padding: $padding $padding $padding * 7 $padding; padding: $padding $padding $padding * 7 $padding;
// background: green; // background: green;
} }
// 顶部日历筛选部分
.u-center {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
box-sizing: border-box;
.date {
background-color: rgba($color: #000000, $alpha: .1);
color: #fff;
min-width: 340rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 8rpx 20rpx;
border-radius: $radius * 2;
margin: 0 10rpx;
font-size: $title-size - 2;
}
.play-right-fill {
padding: $padding !important;
background-color: pink;
}
}
// 饮食进度条 // 饮食进度条
.cricle-content { .cricle-content {
box-shadow: 0 0 4rpx 4rpx rgba($color: $main-color, $alpha: 0.1); box-shadow: 0 0 4rpx 4rpx rgba($color: $main-color, $alpha: 0.1);
@@ -353,6 +438,8 @@ export default {
justify-content: space-around; justify-content: space-around;
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
margin-top: $margin * 5;
.cricle { .cricle {
.num { .num {
color: $text-color; color: $text-color;
@@ -360,16 +447,19 @@ export default {
font-weight: bold; font-weight: bold;
padding: $padding * 0.2; padding: $padding * 0.2;
} }
.num1 { .num1 {
color: #f00; color: #f00;
} }
} }
.info { .info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
span { span {
font-size: $title-size + 10; font-size: $title-size + 10;
font-weight: bold; font-weight: bold;
@@ -377,6 +467,7 @@ export default {
padding-top: $padding * 0.5; padding-top: $padding * 0.5;
} }
} }
.ic-left { .ic-left {
position: absolute; position: absolute;
left: 0; left: 0;
@@ -386,12 +477,14 @@ export default {
padding: 10rpx $padding * 0.6; padding: 10rpx $padding * 0.6;
border-radius: 0 0 $radius 0; border-radius: 0 0 $radius 0;
} }
.ic-day { .ic-day {
position: absolute; position: absolute;
right: $padding; right: $padding;
top: $padding; top: $padding;
} }
} }
// 没有饮食记录 // 没有饮食记录
.no-foods { .no-foods {
display: flex; display: flex;
@@ -402,19 +495,23 @@ export default {
font-size: $title-size-m - 4; font-size: $title-size-m - 4;
color: $text-gray-m; color: $text-gray-m;
min-height: 40vh; min-height: 40vh;
// background: pink; // background: pink;
.no-foods-img { .no-foods-img {
opacity: 0.5; opacity: 0.5;
} }
view { view {
padding: $padding * 0.2; padding: $padding * 0.2;
} }
} }
// 饮食记录 早中晚加餐等 // 饮食记录 早中晚加餐等
.foods-add { .foods-add {
border-bottom: solid 1rpx #f7f7f7; border-bottom: solid 1rpx #f7f7f7;
margin-top: $margin; margin-top: $margin;
} }
// 主标题 // 主标题
.foods-title { .foods-title {
display: flex; display: flex;
@@ -424,25 +521,29 @@ export default {
box-sizing: border-box; box-sizing: border-box;
color: $text-color; color: $text-color;
padding: $padding * 0.5 0; padding: $padding * 0.5 0;
.title-left { .title-left {
font-size: $title-size; font-size: $title-size;
color: $text-color; color: $text-color;
font-weight: bold; font-weight: bold;
span { span {
font-weight: normal; font-weight: normal;
font-size: $title-size-m - 6; font-size: $title-size-m;
color: $text-gray-m; color: $text-gray-m;
margin-left: $margin - 10; margin-left: $margin - 10;
} }
} }
.title-right { .title-right {
font-size: $title-size-m - 6; font-size: $title-size-m;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
color: $main-color; color: $main-color;
.dw { .dw {
margin: 0 $margin * 0.6 0 $margin * 0.4; margin: 0 $margin * 0.6 0 $margin * 0.4;
color: $text-gray; color: $text-gray;

View File

@@ -398,9 +398,6 @@ export default {
*/ */
logs() { logs() {
logs().then(res => { logs().then(res => {
console.log(res.is_login)
this.weight = res.weight; this.weight = res.weight;
this.water = res.water; this.water = res.water;
this.intake_run = res.intake_run; this.intake_run = res.intake_run;
@@ -410,6 +407,13 @@ export default {
this.banner = res.banner; this.banner = res.banner;
this.user = res.user; this.user = res.user;
this.notifications_count = res.notifications_count; this.notifications_count = res.notifications_count;
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
/** /**

View File

@@ -8,94 +8,76 @@
<template> <template>
<view class="weight"> <view class="weight">
<!-- 进度模块 -->
<block v-if="tabbarId === 0">
<!-- 体重表 --> <!-- 体重表 -->
<view class="progress-top"> <view class="progress-top">
<view class="unit"> <view class="unit"> <span :class="isJin === 2?'active':''" @click="isJin = 1"></span> <span :class="isJin === 1?'active':''" @click="isJin = 1">公斤</span> </view>
<span
:class="isJin === 2?'active':''"
@click="isJin = 1"
></span>
<span
:class="isJin === 1?'active':''"
@click="isJin = 1"
>公斤</span>
</view>
<view class="progress"> <view class="progress">
<view>{{weightInfo.text}}</view> <view>{{weightInfo.text}}</view>
<u-count-to <u-count-to class="uCountTo" :startVal="0" :endVal="weightInfo.change" :decimals="1" color="#333" fontSize="36" :bold="true" />
class="uCountTo"
:startVal="0"
:endVal="weightInfo.change"
:decimals="1"
color="#333"
fontSize="36"
:bold="true"
/>
<view>保持 / 塑性</view> <view>保持 / 塑性</view>
</view> </view>
<view <view class="add-weight" @click="addWeightShow = true">记录体重</view>
class="add-weight"
@click="addWeightShow = true"
>记录体重</view>
<view class="des-title">以最后一次记录为主且每日只能更新一次</view> <view class="des-title">以最后一次记录为主且每日只能更新一次</view>
</view> </view>
<!-- 体重列表 --> <!-- 体重列表 -->
<view <view class="weight-list" v-if="lists.length>0">
class="weight-list" <view class="list-item">
v-if="lists.length>0" <view class="list-left"> <view class="list-title"> <span>{{weightInfo.begin}}</span>公斤 </view> 初始体重 </view>
> <view class="list-right"> <span>开始保持 / 塑性</span> {{weightInfo.first_weight_time}} </view>
<view
class="list-item"
v-for="item in lists"
:key="item.wight_id"
>
<view class="list-left">
<view class="list-title">
<span>{{item.weight}}</span>公斤
</view> </view>
测量结果 <view class="list-item" v-for="item in lists" :key="item.wight_id">
</view> <view class="list-left"> <view class="list-title"> <span>{{item.weight}}</span>公斤 </view> 测量结果 </view>
<view class="list-right"> <view class="list-right"> <span>开始保持 / 塑性</span> {{item.created_at}} </view>
<span>开始保持 / 塑性</span>
{{item.created_at}}
</view> </view>
</view> </view>
<view class="no-lists" v-else>还没有体重信息记录下呗~</view>
</block>
<!-- 曲线模块 -->
<view v-if="tabbarId === 1">
<!-- 健康测评 -->
<u-image v-if="chartData.categories.length>0" :src="require('@/static/imgs/health1.png')" class="eval-img" @click="$Router.push({ name: 'EvaluationList' })" :lazy-load="true" radius="10rpx" mode="widthFix" width="100%" />
<view class="curve" v-if="chartData.categories.length>0">
<view class="title"> 体重 <span>单位公斤</span> </view>
<u-icon @click="addWeightShow = true" name="edit-pen-fill" color="#34ce98" size="20" :bold="true" label="更新" labelPos="right" labelSize="13" labelColor="#999" space="4" />
</view> </view>
<view <view class="charts-box" v-if="chartData.categories.length>0"> <qiun-data-charts type="area" :chartData="chartData" background="none" /> </view>
class="no-lists" <view class="progress-top">
v-else <view class="add-weight" @click="addWeightShow = true">记录体重</view>
>还没有体重信息记录下呗~</view> <view class="des-title">只显示最近七次测量记录</view>
</view>
</view>
<!-- 记录体重弹窗 --> <!-- 记录体重弹窗 -->
<u-popup <u-popup :show="addWeightShow" :round="10" @close="addWeightShow = false" :closeable="true">
:show="addWeightShow"
:round="10"
@close="addWeightShow = false"
:closeable="true"
>
<view class="addWeightContent"> <view class="addWeightContent">
<view class="date">今天</view> <view class="date">今天</view>
<view class='count'><span>{{weight}}</span>公斤</view> <view class='count'><span>{{weight}}</span>公斤</view>
<vue-scale <vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scroll" :scrollLeft="Number(weight)" />
:min="10" <view class="addBtn" @click="addWeight">确认添加</view>
:max="100"
:int="false"
:single="10"
:h="80"
:styles="styles"
@scroll="scroll"
:scrollLeft="Number(weight)"
/>
<view
class="addBtn"
@click="addWeight"
>确认添加</view>
</view> </view>
</u-popup> </u-popup>
<!-- 底部 进度 曲线菜单 -->
<u-tabbar :value="tabbarId" :fixed="true" :placeholder="false" :safeAreaInsetBottom="false" activeColor="#34ce98">
<u-tabbar-item text="进度" :icon="tabbarId === 0 ?require('../../static/imgs/speed-2.png'):require('../../static/imgs/speed-1.png')" @click="tabbarClick" />
<u-tabbar-item text="曲线" :icon="tabbarId === 1 ?require('../../static/imgs/curve-2.png'):require('../../static/imgs/curve-1.png')" @click="tabbarClick" />
</u-tabbar>
</view> </view>
</template> </template>
<script> <script>
import vueScale from "@/components/vueScale"; import vueScale from "@/components/vueScale";
import { weights, addWeight } from "@/apis/interfaces/weight.js"; import {
weights,
addWeight,
curves
} from "@/apis/interfaces/weight.js";
import moment from "moment"; import moment from "moment";
import l from "../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"; import l from "../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center";
export default { export default {
@@ -120,10 +102,18 @@ export default {
lists: [], lists: [],
has_more: true, has_more: true,
page: 1, page: 1,
tabbarId: 0,
chartData: {
// "categories": ["1/1","1/2","1/3","1/4","1/5","1/6","1/7"],
// "series": [{"name": "最近七天进度","data": [55,51,53.3,50.3,53.3]}]
categories:[],
series:[{name: "",data: []}]
}, // 曲线部分 start
}; };
}, },
onShow() { onShow() {
this.getWeights(); this.getWeights();
this.getCurves();
this.date = moment(new Date()).format("YYYY-MM-DD"); this.date = moment(new Date()).format("YYYY-MM-DD");
}, },
onReachBottom() { onReachBottom() {
@@ -131,6 +121,8 @@ export default {
uni.showToast({ uni.showToast({
title: "没有更多啦~", title: "没有更多啦~",
icon: "none", icon: "none",
duration: 1000,
mask: true
}); });
} else { } else {
this.page = this.page + 1; this.page = this.page + 1;
@@ -149,12 +141,37 @@ export default {
this.has_more = res.lists.page.has_more; this.has_more = res.lists.page.has_more;
this.weightInfo = res.weight; this.weightInfo = res.weight;
this.weight = res.weight.now; this.weight = res.weight.now;
}).catch(err=>{
uni.showToast({
title:err.message,
icon:"none",
mask:true,
duration:2000
})
}); });
}, },
// 获取曲线
getCurves() {
curves().then((res) => {
this.chartData={
categories:res.categories,
"series": [res.series]
}
}).catch(err=>{
uni.showToast({
title:err.message,
icon:"none",
mask:true,
duration:2000
})
});
},
// 更新体重
addWeight() { addWeight() {
let data = { let data = {
weight: this.weight, weight: this.weight,
date: this.date, date: this.date
}; };
addWeight(data).then((res) => { addWeight(data).then((res) => {
this.addWeightShow = false; this.addWeightShow = false;
@@ -162,16 +179,65 @@ export default {
this.has_more = true; this.has_more = true;
this.lists = []; this.lists = [];
this.getWeights(); this.getWeights();
this.getCurves();
}).catch(err=>{
uni.showToast({
title:err.message,
icon:"none",
mask:true,
duration:2000
})
}); });
}, },
// 滚动标尺触发事件 // 滚动标尺触发事件
scroll(msg) { scroll(msg) {
this.weight = msg; this.weight = msg;
}, },
// 点击底部切换
tabbarClick(e) {
this.tabbarId = Number(e)
}
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.charts-box{
width: 100%;
height:500rpx;
margin-top: $margin;
}
.no-weight{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
color: #999;
font-size: $title-size-m;
}
// curve
.curve{
margin-top: $margin;
padding: $padding $padding + 10;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
font-size: $title-size + 5;
color: #333;
span{
color: #cacaca;
font-size: $title-size-m;
margin-left: 10rpx;
}
}
// 评测图片
.eval-img {
box-shadow: 0 0 10rpx 4rpx rgba($color: $main-color, $alpha: 0.1);
}
//体重top //体重top
.progress-top { .progress-top {
padding: $padding * 2 $padding; padding: $padding * 2 $padding;
@@ -181,6 +247,7 @@ export default {
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
border-bottom: solid 1rpx #f7f7f7; border-bottom: solid 1rpx #f7f7f7;
// 单位 // 单位
.unit { .unit {
display: flex; display: flex;
@@ -188,6 +255,7 @@ export default {
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
width: 100%; width: 100%;
span { span {
display: inline-block; display: inline-block;
width: 100rpx; width: 100rpx;
@@ -198,16 +266,19 @@ export default {
border: solid 1rpx $border-color; border: solid 1rpx $border-color;
border-radius: 50rpx 0 0 50rpx; border-radius: 50rpx 0 0 50rpx;
} }
span:nth-child(1) { span:nth-child(1) {
border-radius: 50rpx 0 0 50rpx; border-radius: 50rpx 0 0 50rpx;
border-style: solid; border-style: solid;
border-color: $border-color $main-color $border-color $border-color; border-color: $border-color $main-color $border-color $border-color;
} }
span:nth-child(2) { span:nth-child(2) {
border-radius: 0 50rpx 50rpx 0; border-radius: 0 50rpx 50rpx 0;
border-style: solid; border-style: solid;
border-color: $border-color $border-color $border-color $main-color; border-color: $border-color $border-color $border-color $main-color;
} }
span.active { span.active {
background-color: $main-color; background-color: $main-color;
color: #fff; color: #fff;
@@ -228,6 +299,7 @@ export default {
box-sizing: border-box; box-sizing: border-box;
color: $text-gray-m; color: $text-gray-m;
font-size: $title-size-m; font-size: $title-size-m;
.uCountTo { .uCountTo {
padding: $padding * 0.5; padding: $padding * 0.5;
} }
@@ -246,13 +318,17 @@ export default {
padding: $padding; padding: $padding;
color: $text-gray-m; color: $text-gray-m;
font-size: $title-size-m - 4; font-size: $title-size-m - 4;
} }
} }
// 列表 // 列表
.weight-list { .weight-list {
font-size: $title-size-m; font-size: $title-size-m;
color: $text-gray-m; color: #cacaca;
padding: $padding; padding: 0 $padding;
.list-item { .list-item {
display: flex; display: flex;
@@ -261,17 +337,20 @@ export default {
box-sizing: border-box; box-sizing: border-box;
justify-content: space-between; justify-content: space-between;
border-bottom: solid 1rpx #f9f9f9; border-bottom: solid 1rpx #f9f9f9;
padding: $padding 0; padding: 20rpx 0;
font-size: $title-size-m - 2;
.list-title { .list-title {
color: $text-color; color: #555;
font-size: $title-size-m; font-size: $title-size-m - 2;
margin-bottom: $margin * 0.4;
span { span {
font-size: $title-size + 14; font-size: $title-size + 10;
font-weight: 500; font-weight: 500;
margin-right: 10rpx; margin-right: 10rpx;
} }
} }
.list-right { .list-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -279,12 +358,15 @@ export default {
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
margin-top: $margin * 0.4; margin-top: $margin * 0.4;
color: #999;
span { span {
margin-bottom: 10rpx; margin-bottom: 10rpx;
} }
} }
} }
} }
.no-lists { .no-lists {
padding: $padding; padding: $padding;
color: $text-gray-m; color: $text-gray-m;
@@ -303,22 +385,26 @@ export default {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
.date { .date {
font-size: $title-size + 9; font-size: $title-size + 9;
text-align: center; text-align: center;
} }
.count { .count {
color: $main-color; color: $main-color;
text-align: center; text-align: center;
margin-top: $margin * 2; margin-top: $margin * 2;
margin-bottom: $margin * 0.1; margin-bottom: $margin * 0.1;
font-size: $title-size + 2; font-size: $title-size + 2;
span { span {
font-weight: bold; font-weight: bold;
font-size: $title-size * 2.2; font-size: $title-size * 2.2;
margin-right: $margin * 0.3; margin-right: $margin * 0.3;
} }
} }
.addBtn { .addBtn {
background-color: $main-color; background-color: $main-color;
color: #fff; color: #fff;

View File

@@ -3,18 +3,14 @@
<!-- 更多管理 --> <!-- 更多管理 -->
<view class="list"> <view class="list">
<view class="list-item" @click="updImgs"> <view class="list-item" @click="updImgs">
<view class="list-item-left"> <view class="list-item-left"> <span>修改头像</span> </view>
<span>修改头像</span>
</view>
<view class="avatar" > <view class="avatar" >
<image :src="avatar.showPath || require('@/static/user/cover.png')" mode="aspectFill" /> <image :src="avatar.showPath || require('@/static/user/cover.png')" mode="aspectFill" />
<u-icon name="arrow-right" color="#999" size="20"></u-icon> <u-icon name="arrow-right" color="#999" size="20"></u-icon>
</view> </view>
</view> </view>
<view class="list-item"> <view class="list-item">
<view class="list-item-left"> <view class="list-item-left"> <span>修改昵称</span> </view>
<span>修改昵称</span>
</view>
<view class="input"> <view class="input">
<input type="text" :value="nickname" @blur='blur' placeholder="请输入用户的昵称" maxlength="12" /> <input type="text" :value="nickname" @blur='blur' placeholder="请输入用户的昵称" maxlength="12" />
<u-icon name="arrow-right" color="#999" size="20"></u-icon> <u-icon name="arrow-right" color="#999" size="20"></u-icon>
@@ -88,7 +84,9 @@
}).catch(err => { }).catch(err => {
uni.showToast({ uni.showToast({
title: err.message, title: err.message,
icon: 'none' icon: "none",
duration: 2000,
mask: true
}) })
}) })
} }
@@ -116,7 +114,9 @@
}).catch(err => { }).catch(err => {
uni.showToast({ uni.showToast({
title: err.message, title: err.message,
icon: 'none' icon: "none",
duration: 2000,
mask: true
}) })
}) })
} }

View File

@@ -4,61 +4,42 @@
<view class="files" @click="sexShow = true"> <view class="files" @click="sexShow = true">
<view class="name">性别</view> <view class="name">性别</view>
<view class="text"> <view class="text">
<u-icon <u-icon class="target-icon" :label="recordsData.sex == 1 ? '男士' : '女士'" name="arrow-right" color="#999"
class="target-icon" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" />
:label="recordsData.sex == 1 ? '男士' : '女士'"
name="arrow-right"
color="#999"
size="14"
labelSize="14"
labelColor="#666"
labelPos="left"
space="10"
/>
</view> </view>
</view> </view>
<u-action-sheet <u-action-sheet :actions="sexList" title="你的性别是?" :show="sexShow" cancelText="暂不修改"
:actions="sexList" @select=" e => { (this.recordsData.sex = e.id), (this.sexShow = false); } " @close="sexShow = false" />
title="你的性别是?"
:show="sexShow"
cancelText="暂不修改"
@select=" e => { (this.recordsData.sex = e.id), (this.sexShow = false); } "
@close="sexShow = false"
/>
<!-- 性别 end --> <!-- 性别 end -->
<!-- 生日 start --> <!-- 生日 start -->
<view class="files" @click="birthdayShow = true"> <view class="files" @click="birthdayShow = true">
<view class="name">生日</view> <view class="name">生日</view>
<view class="text"> <view class="text">
<u-icon class="target-icon" :label="showBirthday" name="arrow-right" color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" /> <u-icon class="target-icon" :label="showBirthday" name="arrow-right" color="#999" size="14"
labelSize="14" labelColor="#666" labelPos="left" space="10" />
</view> </view>
</view> </view>
<u-datetime-picker <u-datetime-picker confirmColor="#34ce98" v-model="recordsData.birthday" mode="date" :show="birthdayShow"
confirmColor="#34ce98" :formatter="formatter" :minDate="-302688000" :maxDate="maxDate"
v-model="recordsData.birthday"
mode="date"
:show="birthdayShow"
:formatter="formatter"
:minDate="-302688000"
:maxDate="maxDate"
@confirm=" e => { this.recordsData.birthday = e.value, this.birthdayShow = false } " @confirm=" e => { this.recordsData.birthday = e.value, this.birthdayShow = false } "
@cancel=" () => { this.birthdayShow = false; } " @cancel=" () => { this.birthdayShow = false; } " />
/>
<!-- 生日 end --> <!-- 生日 end -->
<!-- 身高 start--> <!-- 身高 start-->
<view class="files" @click="heightShow = true"> <view class="files" @click="heightShow = true">
<view class="name">身高</view> <view class="name">身高</view>
<view class="text"> <view class="text">
<u-icon class="target-icon" :label="recordsData.height + ` CM`" name="arrow-right" color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" /> <u-icon class="target-icon" :label="recordsData.height + ` CM`" name="arrow-right" color="#999"
size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" />
</view> </view>
</view> </view>
<u-popup :show="heightShow" @close="() => { heightShow = false }"> <u-popup :show="heightShow" @close="() => { heightShow = false }">
<view class="v-scale"> <view class="v-scale">
<view class="title"> 你的身高为?</view> <view class="title"> 你的身高为?</view>
<view class="total"> {{recordsData.height}} CM </view> <view class="total"> {{recordsData.height}} CM </view>
<vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scrollAll('height',$event)" :scrollLeft="Number(recordsData.height)" /> <vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles"
@scroll="scrollAll('height',$event)" :scrollLeft="Number(recordsData.height)" />
</view> </view>
</u-popup> </u-popup>
<!-- 身高 end --> <!-- 身高 end -->
@@ -67,14 +48,16 @@
<view class="files bt30" @click="weightShow = true"> <view class="files bt30" @click="weightShow = true">
<view class="name">最新体重</view> <view class="name">最新体重</view>
<view class="text"> <view class="text">
<u-icon class="target-icon" :label="recordsData.weight + ` KG`" name="arrow-right" color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" /> <u-icon class="target-icon" :label="recordsData.weight + ` KG`" name="arrow-right" color="#999"
size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" />
</view> </view>
</view> </view>
<u-popup :show="weightShow" @close="() => { weightShow = false }"> <u-popup :show="weightShow" @close="() => { weightShow = false }">
<view class="v-scale"> <view class="v-scale">
<view class="title"> 你的当前体重为?</view> <view class="title"> 你的当前体重为?</view>
<view class="total"> {{recordsData.weight}} KG </view> <view class="total"> {{recordsData.weight}} KG </view>
<vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scrollAll('weight',$event)" :scrollLeft="Number(recordsData.weight)" /> <vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles"
@scroll="scrollAll('weight',$event)" :scrollLeft="Number(recordsData.weight)" />
</view> </view>
</u-popup> </u-popup>
<!-- 生日 end --> <!-- 生日 end -->
@@ -83,29 +66,29 @@
<view class="files" @click="targetShow = true"> <view class="files" @click="targetShow = true">
<view class="name">目标</view> <view class="name">目标</view>
<view class="text"> <view class="text">
<u-icon class="target-icon" :label="targetList[selectedTargetIndex].name" name="arrow-right" color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" /> <u-icon class="target-icon" :label="targetList[selectedTargetIndex].name" name="arrow-right"
color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" />
</view> </view>
</view> </view>
<u-action-sheet <u-action-sheet :actions="targetList" title="你的目标是?" :show="targetShow" cancelText="暂不修改"
:actions="targetList"
title="你的目标是?"
:show="targetShow"
cancelText="暂不修改"
@select=" e => { (this.selectedTargetIndex = this.targetList.findIndex(item => e.id === item.id)), (this.targetShow = false); } " @select=" e => { (this.selectedTargetIndex = this.targetList.findIndex(item => e.id === item.id)), (this.targetShow = false); } "
@close="targetShow = false" @close="targetShow = false" />
/>
<!-- 目标 end --> <!-- 目标 end -->
<!-- 目标体重 start--> <!-- 目标体重 start-->
<view class="files" @click="targetWeightShow = true"> <view class="files" @click="targetWeightShow = true">
<view class="name">目标体重</view> <view class="name">目标体重</view>
<view class="text"><u-icon class="target-icon" :label="recordsData.goal_weight + ` KG`" name="arrow-right" color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" /></view> <view class="text">
<u-icon class="target-icon" :label="recordsData.goal_weight + ` KG`" name="arrow-right" color="#999"
size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" />
</view>
</view> </view>
<u-popup :show="targetWeightShow" @close="() => { targetWeightShow = false }"> <u-popup :show="targetWeightShow" @close="() => { targetWeightShow = false }">
<view class="v-scale"> <view class="v-scale">
<view class="title"> 你的目标体重为?</view> <view class="title"> 你的目标体重为?</view>
<view class="total"> {{recordsData.goal_weight}} KG </view> <view class="total"> {{recordsData.goal_weight}} KG </view>
<vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles" @scroll="scrollAll('goalweight',$event)" :scrollLeft="Number(recordsData.goal_weight)" /> <vue-scale :min="10" :max="100" :int="false" :single="10" :h="80" :styles="styles"
@scroll="scrollAll('goalweight',$event)" :scrollLeft="Number(recordsData.goal_weight)" />
</view> </view>
</u-popup> </u-popup>
<!-- 目标体重 end --> <!-- 目标体重 end -->
@@ -114,17 +97,13 @@
<view class="files" @click="exerciseShow = true"> <view class="files" @click="exerciseShow = true">
<view class="name">运动量</view> <view class="name">运动量</view>
<view class="text"> <view class="text">
<u-icon class="target-icon" :label="exerciseList[selectExerciseIndex].name" name="arrow-right" color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" /> <u-icon class="target-icon" :label="exerciseList[selectExerciseIndex].name" name="arrow-right"
color="#999" size="14" labelSize="14" labelColor="#666" labelPos="left" space="10" />
</view> </view>
</view> </view>
<u-action-sheet <u-action-sheet :actions="exerciseList" title="你的运动量是?" :show="exerciseShow" cancelText="暂不修改"
:actions="exerciseList"
title="你的运动量是?"
:show="exerciseShow"
cancelText="暂不修改"
@select=" e => { (this.selectExerciseIndex = this.exerciseList.findIndex(item => e.id === item.id)), (this.exerciseShow = false); } " @select=" e => { (this.selectExerciseIndex = this.exerciseList.findIndex(item => e.id === item.id)), (this.exerciseShow = false); } "
@close="exerciseShow = false" @close="exerciseShow = false" />
/>
<!-- 运动量 end --> <!-- 运动量 end -->
<view class="sureBtn" @click="sureBtn"> 确认修改 </view> <view class="sureBtn" @click="sureBtn"> 确认修改 </view>
<view class="des">修改资料后可更新并查看最新方案预算热量可能会发生变化</view> <view class="des">修改资料后可更新并查看最新方案预算热量可能会发生变化</view>
@@ -132,7 +111,10 @@
</template> </template>
<script> <script>
import { editHealthBefore,editHealth } from '@/apis/interfaces/essentialInfo.js'; import {
editHealthBefore,
editHealth
} from '@/apis/interfaces/essentialInfo.js';
import moment from 'moment'; import moment from 'moment';
import vueScale from '@/components/vueScale'; // 体重标尺 import vueScale from '@/components/vueScale'; // 体重标尺
export default { export default {
@@ -145,12 +127,39 @@ export default {
birthdayShow: false, // 出生日期展示 birthdayShow: false, // 出生日期展示
maxDate: new Date().getTime(), maxDate: new Date().getTime(),
sexShow: false, // 性别弹窗是否显示 sexShow: false, // 性别弹窗是否显示
sexList: [{name: '男士',id: 1},{name: '女士',id: 2}], sexList: [{
name: '男士',
id: 1
}, {
name: '女士',
id: 2
}],
targetShow: false, // 目标弹窗是否显示 targetShow: false, // 目标弹窗是否显示
targetList: [{name: '减脂',id: 1},{name: '保持体重',id: 2},{name: '增肌',id: 3}], targetList: [{
name: '减脂',
id: 1
}, {
name: '保持体重',
id: 2
}, {
name: '增肌',
id: 3
}],
selectedTargetIndex: 0, // 默认选择了那个target selectedTargetIndex: 0, // 默认选择了那个target
exerciseShow: false, // 运动量弹窗是否显示 exerciseShow: false, // 运动量弹窗是否显示
exerciseList:[{name:'久坐不动',id:1},{name:'少量运动',id:2},{name:'中等运动量',id:3},{name:'超强度运动',id:4}], exerciseList: [{
name: '久坐不动',
id: 1
}, {
name: '少量运动',
id: 2
}, {
name: '中等运动量',
id: 3
}, {
name: '超强度运动',
id: 4
}],
selectExerciseIndex: 0, //默认选择运动量是久坐不懂得 selectExerciseIndex: 0, //默认选择运动量是久坐不懂得
heightShow: false, heightShow: false,
weightShow: false, weightShow: false,
@@ -180,7 +189,12 @@ export default {
this.selectExerciseIndex = this.exerciseList.findIndex(item => item.id === res.exercise) this.selectExerciseIndex = this.exerciseList.findIndex(item => item.id === res.exercise)
}) })
.catch(err => { .catch(err => {
conso.log(err); uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
}); });
}, },
methods: { methods: {
@@ -198,14 +212,19 @@ export default {
}, },
// 年龄 - 过滤 - 自定义 - 出生年月日 // 年龄 - 过滤 - 自定义 - 出生年月日
formatter(type, value) { formatter(type, value) {
if (type === 'year') {return `${value}`;} if (type === 'year') {
if (type === 'month') {return `${value}`;} return `${value}`;
if (type === 'day') {return `${value}`;} }
if (type === 'month') {
return `${value}`;
}
if (type === 'day') {
return `${value}`;
}
return value; return value;
}, },
// 提交按钮 // 提交按钮
sureBtn() { sureBtn() {
let params = { let params = {
record_id: this.recordsData.record_id, record_id: this.recordsData.record_id,
birthday: moment(this.recordsData.birthday).format('YYYY-MM-DD'), birthday: moment(this.recordsData.birthday).format('YYYY-MM-DD'),
@@ -219,9 +238,14 @@ export default {
editHealth(params.record_id, params).then(res => { editHealth(params.record_id, params).then(res => {
this.$Router.back() this.$Router.back()
}).catch(err => { }).catch(err => {
uni.showToast({
title: err.message,
icon: "none",
duration: 2000,
mask: true
})
this.$Router.back() this.$Router.back()
}) })
} }
} }
}; };
@@ -231,42 +255,51 @@ export default {
.content { .content {
padding: $padding; padding: $padding;
} }
.files { .files {
display: flex; display: flex;
padding: $padding + 10 $padding - 20; padding: $padding + 10 $padding - 20;
box-sizing: border-box; box-sizing: border-box;
border-bottom: #f9f9f9 2rpx solid; border-bottom: #f9f9f9 2rpx solid;
font-size: $title-size; font-size: $title-size;
&:last-child { &:last-child {
border: none; border: none;
} }
.name { .name {
flex: 1; flex: 1;
} }
.text { .text {
color: $text-gray; color: $text-gray;
} }
} }
.v-scale { .v-scale {
padding: $padding * 2 0; padding: $padding * 2 0;
font-size: $title-size; font-size: $title-size;
.title { .title {
text-align: center; text-align: center;
font-size: $title-size + 10; font-size: $title-size + 10;
margin-bottom: $margin; margin-bottom: $margin;
} }
.total { .total {
font-size: $title-size; font-size: $title-size;
color: $main-color; color: $main-color;
text-align: center; text-align: center;
} }
} }
.des { .des {
color: $text-gray-m; color: $text-gray-m;
font-size: $title-size-m - 4; font-size: $title-size-m - 4;
margin-top: $margin * 2; margin-top: $margin * 2;
text-align: center; text-align: center;
} }
.sureBtn { .sureBtn {
background-color: $main-color; background-color: $main-color;
color: #fff; color: #fff;
@@ -276,6 +309,7 @@ export default {
border-radius: $radius; border-radius: $radius;
margin-top: $margin * 2; margin-top: $margin * 2;
} }
.bt30 { .bt30 {
border-bottom: #f9f9f9 20rpx solid; border-bottom: #f9f9f9 20rpx solid;
} }

View File

@@ -155,12 +155,10 @@
if (this.$store.state.token === '') return; if (this.$store.state.token === '') return;
info() info()
.then(res => { .then(res => {
console.log(res);
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: res.nickname title: res.nickname
}); });
this.userInfo = res; this.userInfo = res;
console.log(res);
}) })
.catch(err => { .catch(err => {
uni.showToast({ uni.showToast({
@@ -318,7 +316,7 @@
.user-content { .user-content {
padding-left: 158rpx; padding-left: 158rpx;
height: 128rpx; height: 140rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;

View File

@@ -4,16 +4,16 @@ import {
} from 'uni-simple-router'; } from 'uni-simple-router';
import store from '@/store/index' import store from '@/store/index'
// #ifdef APP-NVUE
// CALL 页面必须是nvue但是NVUE 不支持webpack的 ROUTES 注入 // CALL 页面必须是nvue但是NVUE 不支持webpack的 ROUTES 注入
// https://github.com/SilurianYang/uni-read-pages/issues/20 // https://github.com/SilurianYang/uni-read-pages/issues/20
// #ifdef APP-NVUE
const ROUTES = [{ const ROUTES = [{
'path': '/pages/im/private/call', "path": "/pages/im/private/call"
'name': 'imPrivateCall'
}, { }, {
'path': '/pages/im/private/chat', "path": "/pages/im/private/chat"
'name': 'imPrivateChat' }, {
}] "path": "/pages/im/group/chat"
}];
// #endif // #endif
const router = createRouter({ const router = createRouter({

View File

@@ -1,6 +1,6 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 2869797 */ font-family: "iconfont"; /* Project id 2869797 */
src: url('@/static/iconfont.ttf') format('truetype'); src: url('@/static/iconfont.ttf');
} }
.iconfont { .iconfont {
@@ -11,6 +11,10 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-jia:before {
content: "\e60a";
}
.icon-dui:before { .icon-dui:before {
content: "\e609"; content: "\e609";
} }

Binary file not shown.

BIN
static/imgs/curve-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
static/imgs/curve-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
static/imgs/no-weight.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
static/imgs/speed-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
static/imgs/speed-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
static/imgs/water-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
static/imgs/water-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -2,98 +2,144 @@ import im from "@/utils/im/index.js"
export default { export default {
state: { state: {
friends: {}, contacts: {},
sender: {}, myInfo: {}
}, },
getters: { getters: {
friends(state) { contacts(state) {
return state.friends return state.contacts
}, },
userInfo: (state) => (targetId) => { contactInfo: (state) => (targetId) => {
if (state.friends[targetId]) { if (state.contacts[targetId]) {
return state.friends[targetId] const info = state.contacts[targetId]
return {
name: info.name,
hash: info.hash,
portraitUrl: info.localAvatar ? info.localAvatar : require('@/static/user/cover.png')
}
} else { } else {
console.log('没找到,死循环了,得处理 todo', targetId);
// im.syncUserInfo(targetId)
return { return {
name: '', name: '',
address: '',
hash: '', hash: '',
portraitUrl: '' portraitUrl: ''
} }
} }
}, },
hasUser: (state) => (targetId) => { // 联系人是否存在
return Boolean(state.friends[targetId]) contactIsExist: (state) => (targetId) => {
return Boolean(state.contacts[targetId])
}, },
sender(state) { sender(state) {
return state.sender return state.myInfo
} }
}, },
mutations: { mutations: {
updateFriends(state, userInfo) { updateContactInfo(state, contactInfo) {
Vue.set(state.friends, userInfo.userId, userInfo) Vue.set(state.contacts, contactInfo.targetId, contactInfo)
}, },
SET_state_sender(state, userInfo) { setSenderInfo(state, contactInfo) {
state.sender = userInfo state.myInfo = {
userId: contactInfo.targetId,
name: contactInfo.name,
portraitUrl: contactInfo.portraitUrl
}
} }
}, },
actions: { actions: {
setSenderInfo({ setSenderInfo({
commit commit
}, userInfo) { }, contactInfo) {
commit('SET_state_sender', userInfo) commit('setSenderInfo', contactInfo)
}, },
updateFriends({ // 载入好友信息
launchContact({
commit commit
}, userInfo) { }, data) {
commit('updateFriends', userInfo) commit('updateContactInfo', data)
const model = uni.model.friendModel },
model.find('userId=' + userInfo.userId, (err, user) => { // 更新好友信息这个时候要校验hash值了
if (!err && user.length == 0) { updateContact({
saveAvatar(userInfo, (savedFilePath) => { commit,
model.insert({ dispatch
userId: userInfo.userId, }, contactInfo) {
name: userInfo.name, const model = uni.model.contactModel
hash: userInfo.hash, model.find('targetId="' + contactInfo.targetId + '"', (err, result) => {
address: userInfo.address, if (result.length == 0) {
portraitUrl: savedFilePath, // 没有数据,直接新增一条
}, (err, result) => {}) dispatch('initContact', contactInfo)
userInfo.portraitUrl = savedFilePath } else if (contactInfo.hash != result[0].hash) {
commit('updateFriends', userInfo) commit('updateContactInfo', contactInfo)
if (contactInfo.portraitUrl && contactInfo.portraitUrl != result[0].portraitUrl) {
saveAvatar(contactInfo, (savedFilePath) => {
const info = {
targetId: contactInfo.targetId,
name: contactInfo.name,
hash: contactInfo.hash,
portraitUrl: contactInfo.portraitUrl,
localAvatar: savedFilePath
}
model.update('targetId="' + contactInfo.targetId + '"', info, (err,
res) => {
console.log('UPDATE AVATAR, ERR', err);
}) })
} else if (!err && user[0].hash != userInfo.hash) { commit('updateContactInfo', info)
saveAvatar(userInfo, (savedFilePath) => {
model.update('userId=' + userInfo.userId, {
name: userInfo.name,
hash: userInfo.hash,
portraitUrl: savedFilePath,
}, (err, result) => {})
userInfo.portraitUrl = savedFilePath
commit('updateFriends', userInfo)
})
} else if (!err && user[0].portraitUrl.length > 50) {
saveAvatar(userInfo, (savedFilePath) => {
model.update('userId=' + userInfo.userId, {
name: userInfo.name,
hash: userInfo.hash,
portraitUrl: savedFilePath,
}, (err, result) => {})
userInfo.portraitUrl = savedFilePath
commit('updateFriends', userInfo)
}) })
} else { } else {
console.log('不用操作', user[0]); const info = {
targetId: contactInfo.targetId,
name: contactInfo.name,
hash: contactInfo.hash,
portraitUrl: contactInfo.portraitUrl,
localAvatar: result[0].localAvatar
}
model.update('targetId="' + contactInfo.targetId + '"', info, (err, res) => {
console.log('UPDATE NAME, ERR', err);
})
}
} else {
console.log('updateContact, 无操作');
} }
}) })
},
// 初始化好友信息
initContact({
commit
}, contactInfo) {
// 将好友信息保存到vuex的内存中方便立即使用
commit('updateContactInfo', contactInfo)
const model = uni.model.contactModel
// 用户头像,是否需要下载到本地
if (contactInfo.portraitUrl) {
saveAvatar(contactInfo, (savedFilePath) => {
const info = {
targetId: contactInfo.targetId,
name: contactInfo.name,
hash: contactInfo.hash,
portraitUrl: contactInfo.portraitUrl,
localAvatar: savedFilePath
}
model.insert(info, (err, res) => {})
// 保存头像后,更新信息
commit('updateContactInfo', info)
})
} else {
// 直接将信息,写入数据库
const info = {
targetId: contactInfo.targetId,
name: contactInfo.name,
hash: contactInfo.hash,
portraitUrl: contactInfo.portraitUrl,
localAvatar: ''
}
model.insert(info, (err, res) => {})
}
} }
} }
} }
const saveAvatar = (userInfo, callback) => { const saveAvatar = (contactInfo, callback) => {
uni.downloadFile({ uni.downloadFile({
url: userInfo.portraitUrl, url: contactInfo.portraitUrl,
success: ({ success: ({
tempFilePath tempFilePath
}) => { }) => {
@@ -106,8 +152,6 @@ const saveAvatar = (userInfo, callback) => {
} }
}) })
}, },
fail: (err) => { fail: (err) => {}
console.log('头像保存失败', err);
}
}) })
} }

View File

@@ -34,17 +34,29 @@ const formatDateTime = (timeStamp, returnType) => {
var second = date.getSeconds(); var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute; minute = minute < 10 ? ('0' + minute) : minute;
second = second < 10 ? ('0' + second) : second; second = second < 10 ? ('0' + second) : second;
if (returnType == 'full') { return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second; } if (returnType == 'full') {
if (returnType == 'y-m-d') { return y + '-' + m + '-' + d; } return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
if (returnType == 'h:m') { return h + ':' + minute; } }
if (returnType == 'h:m:s') { return h + ':' + minute + ':' + second; } if (returnType == 'y-m-d') {
return y + '-' + m + '-' + d;
}
if (returnType == 'h:m') {
return h + ':' + minute;
}
if (returnType == 'h:m:s') {
return h + ':' + minute + ':' + second;
}
return [y, m, d, h, minute, second]; return [y, m, d, h, minute, second];
} }
const cfu = { const cfu = {
//demotype为自定义图表类型一般不需要自定义图表类型只需要改根节点上对应的类型即可 //demotype为自定义图表类型一般不需要自定义图表类型只需要改根节点上对应的类型即可
"type": ["pie", "ring", "rose", "word", "funnel", "map", "arcbar", "line", "column", "bar", "area", "radar", "gauge", "candle", "mix", "tline", "tarea", "scatter", "bubble", "demotype"], "type": ["pie", "ring", "rose", "word", "funnel", "map", "arcbar", "line", "column", "bar", "area", "radar",
"range": ["饼状图", "圆环图", "玫瑰图", "词云图", "漏斗图", "地图", "圆弧进度条", "折线图", "柱状图", "条状图", "区域图", "雷达图", "仪表盘", "K线图", "混合图", "时间轴折线", "时间轴区域", "散点图", "气泡图", "自定义类型"], "gauge", "candle", "mix", "tline", "tarea", "scatter", "bubble", "demotype"
],
"range": ["饼状图", "圆环图", "玫瑰图", "词云图", "漏斗图", "地图", "圆弧进度条", "折线图", "柱状图", "条状图", "区域图", "雷达图", "仪表盘", "K线图",
"混合图", "时间轴折线", "时间轴区域", "散点图", "气泡图", "自定义类型"
],
//增加自定义图表类型如果需要categories请在这里加入您的图表类型例如最后的"demotype" //增加自定义图表类型如果需要categories请在这里加入您的图表类型例如最后的"demotype"
//自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴矢量x轴类图表没有categories不需要加入categories //自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴矢量x轴类图表没有categories不需要加入categories
"categories": ["line", "column", "bar", "area", "radar", "gauge", "candle", "mix", "demotype"], "categories": ["line", "column", "bar", "area", "radar", "gauge", "candle", "mix", "demotype"],
@@ -54,11 +66,21 @@ const cfu = {
"option": {}, "option": {},
//下面是自定义format配置因除H5端外的其他端无法通过props传递函数只能通过此属性对应下标的方式来替换 //下面是自定义format配置因除H5端外的其他端无法通过props传递函数只能通过此属性对应下标的方式来替换
"formatter": { "formatter": {
"yAxisDemo1": function (val) { return val + '元' }, "yAxisDemo1": function(val) {
"yAxisDemo2": function (val) { return val.toFixed(2) }, return val + '元'
"xAxisDemo1": function (val) { return val + '年' }, },
"xAxisDemo2": function (val) { return formatDateTime(val, 'h:m') }, "yAxisDemo2": function(val) {
"seriesDemo1": function (val) { return val + '元' }, return val.toFixed(2)
},
"xAxisDemo1": function(val) {
return val + '年'
},
"xAxisDemo2": function(val) {
return formatDateTime(val, 'h:m')
},
"seriesDemo1": function(val) {
return val + '元'
},
"tooltipDemo1": function(item, category, index, opts) { "tooltipDemo1": function(item, category, index, opts) {
if (index == 0) { if (index == 0) {
return '随便用' + item.data + '年' return '随便用' + item.data + '年'
@@ -85,8 +107,7 @@ const cfu = {
"gridType": "dash", "gridType": "dash",
"dashLength": 2, "dashLength": 2,
}, },
"legend": { "legend": {},
},
"extra": { "extra": {
"line": { "line": {
"type": "curve", "type": "curve",
@@ -246,8 +267,7 @@ const cfu = {
"gridType": "dash", "gridType": "dash",
"dashLength": 2, "dashLength": 2,
}, },
"legend": { "legend": {},
},
"extra": { "extra": {
"line": { "line": {
"type": "straight", "type": "straight",
@@ -266,15 +286,12 @@ const cfu = {
"yAxis": { "yAxis": {
"gridType": "dash", "gridType": "dash",
"dashLength": 2, "dashLength": 2,
"data": [ "data": [{
{
"min": 0, "min": 0,
"max": 80 "max": 80
} }]
]
},
"legend": {
}, },
"legend": {},
"extra": { "extra": {
"line": { "line": {
"type": "curve", "type": "curve",
@@ -293,15 +310,12 @@ const cfu = {
"yAxis": { "yAxis": {
"gridType": "dash", "gridType": "dash",
"dashLength": 2, "dashLength": 2,
"data": [ "data": [{
{
"min": 0, "min": 0,
"max": 80 "max": 80
} }]
]
},
"legend": {
}, },
"legend": {},
"extra": { "extra": {
"area": { "area": {
"type": "curve", "type": "curve",
@@ -320,10 +334,11 @@ const cfu = {
"disableGrid": true, "disableGrid": true,
}, },
"yAxis": { "yAxis": {
"data": [{ "min": 0 }] "data": [{
}, "min": 0
"legend": { }]
}, },
"legend": {},
"extra": { "extra": {
"column": { "column": {
"type": "group", "type": "group",
@@ -345,10 +360,8 @@ const cfu = {
"min": 0, "min": 0,
"axisLine": false "axisLine": false
}, },
"yAxis": { "yAxis": {},
}, "legend": {},
"legend": {
},
"extra": { "extra": {
"bar": { "bar": {
"type": "group", "type": "group",
@@ -362,7 +375,9 @@ const cfu = {
}, },
"area": { "area": {
"type": "area", "type": "area",
"color": color, "color": [
"#34ce98",
],
"padding": [15, 15, 0, 15], "padding": [15, 15, 0, 15],
"xAxis": { "xAxis": {
"disableGrid": true, "disableGrid": true,
@@ -371,8 +386,9 @@ const cfu = {
"gridType": "dash", "gridType": "dash",
"dashLength": 2, "dashLength": 2,
}, },
"legend": { "fontColor": "#999",
}, "fontSize":"12",
"legend": {},
"extra": { "extra": {
"area": { "area": {
"type": "straight", "type": "straight",
@@ -528,10 +544,8 @@ const cfu = {
"scrollColor": "#A6A6A6", "scrollColor": "#A6A6A6",
"scrollBackgroundColor": "#EFEBEF" "scrollBackgroundColor": "#EFEBEF"
}, },
"yAxis": { "yAxis": {},
}, "legend": {},
"legend": {
},
"extra": { "extra": {
"candle": { "candle": {
"color": { "color": {
@@ -550,8 +564,7 @@ const cfu = {
"markLine": { "markLine": {
"type": "dash", "type": "dash",
"dashLength": 5, "dashLength": 5,
"data": [ "data": [{
{
"value": 2150, "value": 2150,
"lineColor": "#f04864", "lineColor": "#f04864",
"showLabel": true "showLabel": true
@@ -583,8 +596,7 @@ const cfu = {
"showTitle": true, "showTitle": true,
"data": [] "data": []
}, },
"legend": { "legend": {},
},
"extra": { "extra": {
"mix": { "mix": {
"column": { "column": {
@@ -609,11 +621,9 @@ const cfu = {
"disableGrid": false, "disableGrid": false,
"gridType": "dash", "gridType": "dash",
}, },
"legend": { "legend": {},
},
"extra": { "extra": {
"scatter": { "scatter": {},
},
} }
}, },
"bubble": { "bubble": {
@@ -636,8 +646,7 @@ const cfu = {
"max": 150 "max": 150
}] }]
}, },
"legend": { "legend": {},
},
"extra": { "extra": {
"bubble": { "bubble": {
"border": 2, "border": 2,

16
utils/im/data.js Normal file
View File

@@ -0,0 +1,16 @@
// 获取新好友申请数量
const getPendingCount = (callback) => {
RongIMLib.getConversationList([RongIMLib.ConversationType.SYSTEM], 100, 0, (res) => {
if (res.code === 0) {
const pendingCount = res.conversations.filter((item) => {
return item.objectName == RongIMLib.ObjectName.ContactNotification
}).length
callback(pendingCount)
}
})
}
export default {
getPendingCount
}

View File

@@ -1,23 +0,0 @@
[{
"objectName": "RC:TxtMsg",
"receivedTime": 1643080237399,
"extra": "",
"messageUId": "BUFC-3FSU-OLE4-I31K",
"conversationType": 1,
"messageDirection": 2,
"senderUserId": "10041",
"content": {
"content": "你好,这是 1710 条消息条消息条消息条消息条消息条消息条消息条消息条消息0.97796900 1642741562",
"objectName": "RC:TxtMsg",
"userInfo": {
"userId": "10041",
"name": "我是eth",
"portraitUrl": "http://storage.zh.shangkelian.cn/images/2022/01/12/3d2a103386df6822db7e5290272e8bc2.png"
}
},
"targetId": "10041",
"sentTime": 1642741563003,
"messageId": 2,
"receivedStatus": 1,
"sentStatus": 30
}]

View File

@@ -2,6 +2,7 @@ import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index' import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
import store from '@/store/index.js' import store from '@/store/index.js'
import message from './message.js' import message from './message.js'
import listeners from './listeners.js'
import { import {
getFriends, getFriends,
getUserInfo, getUserInfo,
@@ -10,7 +11,7 @@ import {
const initIm = (KEY) => { const initIm = (KEY) => {
RongIMLib.init(KEY) RongIMLib.init(KEY)
CallLib.init() // CallLib.init()
addListeners() addListeners()
// 初始化的时候 自动链接 // 初始化的时候 自动链接
if (store.getters.getToken !== '') { if (store.getters.getToken !== '') {
@@ -47,25 +48,37 @@ const setNotifyBadge = () => {
/** /**
* 连接IM服务 * 连接IM服务
* @param {string} token token * @param {string} token token
* @param {object} userInfo {userId: string, name: string, portraitUrl: string} * @param {object} userInfo {targetId: string, name: string, portraitUrl: string}
*/ */
const connect = (token, userInfo, callback) => { const connect = (token, userInfo, callback) => {
RongIMLib.connect(token, res => { RongIMLib.connect(token, res => {
console.log('连接结果', res);
callback(res) callback(res)
}) // 更新个人信息
store.dispatch('setSenderInfo', userInfo) store.dispatch('setSenderInfo', userInfo)
// 设置未读消息数量
setNotifyBadge() setNotifyBadge()
// 首次运行获取好友列表
const FK = 'IFT_' + userInfo.targetId
const model = uni.model.friendModel uni.getStorage({
key: FK,
success: () => {
const model = uni.model.contactModel
model.find((err, results) => { model.find((err, results) => {
console.log('好友列表', results);
results.map(item => { results.map(item => {
store.dispatch('updateFriends', item) store.dispatch('launchContact', item)
})
})
},
fail: () => {
// 程序是首次运行,初始化加载好友信息
getFriends().then(res => {
res.map(item => {
store.dispatch('initContact', item)
})
uni.setStorageSync(FK, userInfo.targetId)
})
}
}) })
}) })
} }
@@ -102,25 +115,42 @@ const notifyMsgTypes = [
function inArray(search, array) { function inArray(search, array) {
for (var i in array) { for (var i in array) {
if (array[i] == search) { if (array[i] == search) {
return true; return true
} }
} }
return false; return false
} }
const addListeners = () => { const addListeners = () => {
// 添加连接状态监听函数 // 添加连接状态监听函数
RongIMLib.addConnectionStatusListener((res) => { RongIMLib.addConnectionStatusListener((res) => {
console.log('连接状态监听', res.data.status); console.log('连接状态监听', res.data.status)
uni.$emit('onConnectionStatusChange', res.data.status) uni.$emit('onConnectionStatusChange', res.data.status)
}) })
// 添加消息监听函数 // 添加消息监听函数
RongIMLib.addReceiveMessageListener((res) => { RongIMLib.addReceiveMessageListener((res) => {
console.log('收到消息', res.data.message);
const message = res.data.message const message = res.data.message
console.log('收到消息', message)
if (inArray(message.objectName, notifyMsgTypes)) { if (inArray(message.objectName, notifyMsgTypes)) {
console.log('new Message'); if (!store.getters.contactIsExist(message.targetId)) {
getUserInfo(message.targetId).then(res => {
store.dispatch('initContact', res)
}).catch(err => {
console.log('ERR', err)
})
}
newMessage(message) newMessage(message)
} else if (message.objectName === RongIMLib.ObjectName.ProfileNotification) {
store.dispatch('updateContact', JSON.parse(message.content.data))
// 调用完更新之后,删除这条消息
RongIMLib.deleteMessagesByIds([message.messageId], ({
code
}) => {
console.log('消息删除结果', code)
})
} else if (message.objectName === RongIMLib.ObjectName.ContactNotification) {
// 触发一个新好友的通知事件
uni.$emit('onContactNotification', message.content)
} }
}) })
@@ -133,40 +163,40 @@ const addListeners = () => {
// 音视频通话相关的 // 音视频通话相关的
// 监听通话呼入 // 监听通话呼入
CallLib.onCallReceived(({ // CallLib.onCallReceived(({
data // data
}) => { // }) => {
uni.navigateTo({ // uni.navigateTo({
url: '/pages/im/private/call?targetId=' + data.targetId + '&mediaType=' + // url: '/pages/im/private/call?targetId=' + data.targetId + '&mediaType=' +
data.mediaType // data.mediaType
}) // })
}) // })
// 通话建立成功 // // 通话建立成功
CallLib.onCallConnected(() => { // CallLib.onCallConnected(() => {
uni.$emit('onCallConnected'); // uni.$emit('onCallConnected')
}) // })
// 外呼 // // 外呼
CallLib.onCallOutgoing((res) => { // CallLib.onCallOutgoing((res) => {
uni.$emit('onCallOutgoing'); // uni.$emit('onCallOutgoing')
}) // })
// 远端响铃 // // 远端响铃
CallLib.onRemoteUserRinging((res) => { // CallLib.onRemoteUserRinging((res) => {
uni.$emit('onRemoteUserRinging'); // uni.$emit('onRemoteUserRinging')
}) // })
// 远端加入 // // 远端加入
CallLib.onRemoteUserJoined((res) => { // CallLib.onRemoteUserJoined((res) => {
uni.$emit('onRemoteUserJoined'); // uni.$emit('onRemoteUserJoined')
}) // })
// 断开链接 // // 断开链接
CallLib.onCallDisconnected((res) => { // CallLib.onCallDisconnected((res) => {
console.log('断开链接', res); // console.log('断开链接', res)
uni.$emit('onCallDisconnected'); // uni.$emit('onCallDisconnected')
}) // })
// 远端挂断 // // 远端挂断
CallLib.onRemoteUserLeft((res) => { // CallLib.onRemoteUserLeft((res) => {
console.log('远端离开', res); // console.log('远端离开', res)
uni.$emit('onRemoteUserLeft'); // uni.$emit('onRemoteUserLeft')
}) // })
} }
// 维护消息列表,检查是否需要通知声音,设置新消息提醒的数量 // 维护消息列表,检查是否需要通知声音,设置新消息提醒的数量
@@ -177,24 +207,13 @@ const newMessage = (msg) => {
}) => { }) => {
if (code === 0) { if (code === 0) {
if (status) { if (status) {
uni.vibrateLong()
triTone() triTone()
} }
} }
});
setNotifyBadge()
if (!store.getters.hasUser(msg.targetId)) {
syncUserInfo(msg.targetId)
}
uni.$emit('onReceiveMessage', msg);
}
function syncUserInfo(targetId) {
getUserInfo(targetId).then(res => {
store.dispatch('updateFriends', res)
}) })
setNotifyBadge()
uni.$emit('onReceiveMessage', msg)
} }
// 播放状态 // 播放状态
@@ -215,23 +234,9 @@ const triTone = () => {
} }
} }
/**
* 同步好友信息,保存头像地址等
*/
const syncFriends = () => {
getFriends().then(res => {
res.map(item => {
console.log('item', item);
store.dispatch('updateFriends', item)
})
})
}
export default { export default {
initIm, initIm,
connect, connect,
setNotifyBadge, setNotifyBadge,
syncFriends,
syncUserInfo,
...message ...message
} }

0
utils/im/listeners.js Normal file
View File

View File

@@ -1,8 +1,9 @@
import store from '@/store/index.js' import store from '@/store/index.js'
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
const getMessageList = (conversationType, targetId, timeStamp, count, isForward, callback) => { const getMessageList = (conversationType, targetId, timeStamp, count, isForward, callback) => {
// 获取消息列表 // 获取消息列表 https://doc.rongcloud.cn/imserver/server/v1/message/objectname#objectName
const objectNames = [ const objectNames = [
'RC:TxtMsg', 'RC:TxtMsg',
'RC:VcMsg', 'RC:VcMsg',
@@ -40,6 +41,21 @@ const getMessageList = (conversationType, targetId, timeStamp, count, isForward,
) )
} }
// 获取好友申请列表
const getPendingList = (callback, total) => {
total = total || 100
RongIMLib.getConversationList([RongIMLib.ConversationType.SYSTEM], total, 0, (res) => {
if (res.code === 0) {
const pendings = res.conversations.filter((item) => {
return item.objectName == RongIMLib.ObjectName.ContactNotification &&
item.latestMessage.operation === 'Request'
})
callback(pendings)
}
})
}
/** /**
* 发送文本消息 * 发送文本消息
* @param {number} conversationType 消息类型 * @param {number} conversationType 消息类型
@@ -47,17 +63,17 @@ const getMessageList = (conversationType, targetId, timeStamp, count, isForward,
* @param {string} content 消息内容 * @param {string} content 消息内容
* @param {function} callback 回调函数 * @param {function} callback 回调函数
*/ */
const sentText = (conversationType, targetId, content, callback) => { const sentText = (conversationType, targetId, content, user, callback) => {
console.log('发送');
const msg = { const msg = {
conversationType: conversationType, conversationType: conversationType,
targetId: String(targetId), targetId: String(targetId),
content: { content: {
objectName: 'RC:TxtMsg', objectName: 'RC:TxtMsg',
content: content, content: content,
user: store.getters.sender userInfo: user
} }
} }
RongIMLib.sendMessage(msg, ({ RongIMLib.sendMessage(msg, ({
code, code,
messageId messageId
@@ -65,9 +81,10 @@ const sentText = (conversationType, targetId, content, callback) => {
if (code === 0) { if (code === 0) {
callback(messageId) callback(messageId)
} else { } else {
console.log('发送失败', msg);
uni.showToast({ uni.showToast({
icon: 'none', icon: 'none',
title: '发送失败' title: '发送失败' + code
}) })
} }
}) })
@@ -81,14 +98,15 @@ const sentText = (conversationType, targetId, content, callback) => {
* @param {integer} time 录音时长 * @param {integer} time 录音时长
* @param {function} callback 录音时长 * @param {function} callback 录音时长
*/ */
const sentVoice = (conversationType, targetId, voiceUrl, time, callback) => { const sentVoice = (conversationType, targetId, voiceUrl, time, user, callback) => {
const msg = { const msg = {
conversationType: conversationType, conversationType: conversationType,
targetId: String(targetId), targetId: String(targetId),
content: { content: {
objectName: 'RC:HQVCMsg', objectName: 'RC:HQVCMsg',
local: 'file:///' + plus.io.convertLocalFileSystemURL(voiceUrl), local: 'file:///' + plus.io.convertLocalFileSystemURL(voiceUrl),
duration: time duration: time,
userInfo: user
} }
} }
RongIMLib.sendMediaMessage(msg, { RongIMLib.sendMediaMessage(msg, {
@@ -107,13 +125,14 @@ const sentVoice = (conversationType, targetId, voiceUrl, time, callback) => {
}) })
} }
const sentImage = (conversationType, targetId, imageUrl, callback) => { const sentImage = (conversationType, targetId, imageUrl, user, callback) => {
const msg = { const msg = {
conversationType: conversationType, conversationType: conversationType,
targetId: String(targetId), targetId: String(targetId),
content: { content: {
objectName: 'RC:ImgMsg', objectName: 'RC:ImgMsg',
local: 'file:///' + plus.io.convertLocalFileSystemURL(imageUrl) local: 'file:///' + plus.io.convertLocalFileSystemURL(imageUrl),
userInfo: user
} }
} }
RongIMLib.sendMediaMessage(msg, { RongIMLib.sendMediaMessage(msg, {
@@ -186,6 +205,7 @@ const sendFile = (conversationType, targetId, fileUrl, time, callback) => {
export default { export default {
getMessageList, getMessageList,
getPendingList,
sentText, sentText,
sentVoice, sentVoice,
sentImage, sentImage,

View File

@@ -2,21 +2,21 @@ import {
usqlite usqlite
} from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js' } from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js'
const friendModel = usqlite.model('friends', { const contactModel = usqlite.model('contacts', {
userId: { targetId: {
type: String, type: String,
primaryKey: true, primaryKey: true,
unique: true unique: true
}, },
name: String, name: String,
address: String,
hash: { hash: {
type: String, type: String,
unique: true unique: true
}, },
portraitUrl: String portraitUrl: String,
localAvatar: String
}) })
export default { export default {
friendModel contactModel
} }

View File

@@ -1,51 +0,0 @@
{
"type": "Engine:OnCallReceived",
"module": "RongCloud-Call-RCUniCall",
"data": {
"endTime": 0,
"users": [{
"userId": "10051",
"enableCamera": false,
"mediaId": "420111350",
"mediaType": 1,
"userType": 0,
"enableMicrophone": false
}, {
"userId": "10047",
"enableCamera": false,
"mediaType": 1,
"userType": 0,
"enableMicrophone": false
}],
"inviter": {
"userId": "10051",
"enableCamera": false,
"mediaId": "420111350",
"mediaType": 1,
"userType": 0,
"enableMicrophone": false
},
"caller": {
"userId": "10051",
"enableCamera": false,
"mediaId": "420111350",
"mediaType": 1,
"userType": 0,
"enableMicrophone": false
},
"connectedTime": 0,
"extra": "",
"startTime": 0,
"mediaType": 1,
"callId": "c28cb9d8-6581-474c-bfa5-9872a4824b65",
"targetId": "10051",
"callType": 0,
"mine": {
"userId": "10047",
"enableCamera": false,
"mediaType": 1,
"userType": 0,
"enableMicrophone": false
}
}
}

View File

@@ -1,51 +0,0 @@
{
"type": "Engine:OnCallReceived",
"module": "RongCloud-Call-RCUniCall",
"data": {
"endTime": 0,
"users": [{
"userId": "10051",
"enableCamera": false,
"mediaId": "420068630",
"mediaType": 0,
"userType": 0,
"enableMicrophone": false
}, {
"userId": "10047",
"enableCamera": true,
"mediaType": 0,
"userType": 0,
"enableMicrophone": false
}],
"inviter": {
"userId": "10051",
"enableCamera": false,
"mediaId": "420068630",
"mediaType": 0,
"userType": 0,
"enableMicrophone": false
},
"caller": {
"userId": "10051",
"enableCamera": false,
"mediaId": "420068630",
"mediaType": 0,
"userType": 0,
"enableMicrophone": false
},
"connectedTime": 0,
"extra": "",
"startTime": 0,
"mediaType": 0,
"callId": "1a1462b8-b63b-40a9-bf95-963e810ac49a",
"targetId": "10051",
"callType": 0,
"mine": {
"userId": "10047",
"enableCamera": true,
"mediaType": 0,
"userType": 0,
"enableMicrophone": false
}
}
}