Commit e2ac3edf by huangzhi

feat: 已购和首页

parent 1842bd1a
...@@ -7,6 +7,9 @@ module.exports = { ...@@ -7,6 +7,9 @@ module.exports = {
sourceType: 'module', sourceType: 'module',
allowImportExportEverywhere: true, allowImportExportEverywhere: true,
}, },
globals: {
uni: 'readonly',
},
// 此项指定环境的全局变量,下面的配置指定为浏览器环境 // 此项指定环境的全局变量,下面的配置指定为浏览器环境
env: { env: {
browser: true, browser: true,
......
...@@ -6,10 +6,11 @@ let h2Prefix ...@@ -6,10 +6,11 @@ let h2Prefix
let ydlH5Prefix let ydlH5Prefix
if (isDevelopment) { if (isDevelopment) {
// hostPrefix = 'https://testnewm.ydl.com' hostPrefix = 'https://testnewm.ydl.com'
// apiPrefix = 'https://testapi.ydl.com' // hostPrefix = 'http://192.168.211.138'
hostPrefix = 'https://newm-test.ydl.com' // 下云 apiPrefix = 'https://testapi.ydl.com'
apiPrefix = 'https://api-test.ydl.com' // 下云 // hostPrefix = 'https://newm-test.ydl.com' // 下云
// apiPrefix = 'https://api-test.ydl.com' // 下云
h2Prefix = 'https://h2.yidianling.com' h2Prefix = 'https://h2.yidianling.com'
ydlH5Prefix = 'https://testh5.ydl.com' ydlH5Prefix = 'https://testh5.ydl.com'
} else { } else {
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
"quickapp" : {}, "quickapp" : {},
/* 快应用特有相关 */ /* 快应用特有相关 */
"mp-weixin" : { "mp-weixin" : {
"appid" : "", "appid" : "wx1106c32a36d87d49",
"setting" : { "setting" : {
"urlCheck" : false, "urlCheck" : false,
"es6" : false, "es6" : false,
......
<template>
<div class="empty">
<img src="//static.ydlcdn.com/m/images/m/course/rectangle.svg"/>
<p>{{text || '暂无数据'}}</p>
</div>
</template>
<script>
export default {
name: 'Empty',
props: ['text'],
}
</script>
<style lang="less" scoped>
.empty {
text-align: center;
p {
margin-top: 12px;
color: #999;
font-size: 13px;
text-align: center;
}
}
</style>
\ No newline at end of file
<template> <template>
<view class="container home"> <view
<!-- 筛选条件 --> class="buy-list"
<screen-box @scroll="handleScroll($event)"
:url-params="urlParams" >
:allow-home-scroll.sync="allowHomeScroll" <template v-if="initFinish">
@screenDoctor="onScreenDoctor" <template v-if="courseList.length > 0">
></screen-box>
<!-- 专家列表 -->
<scroll-view
v-if="doctorArr.length"
class="consult-list box-c"
:scroll-y="allowHomeScroll"
:refresher-enabled="true"
:refresher-triggered="scrollBottomRefresher"
:refresher-threshold="100"
@refresherrefresh="onRefresh"
@scrolltolower="handleScrollBottom"
>
<block
v-for="item in doctorArr"
:key="item.uid"
>
<doctor-item
:data-item="item"
:item="item"
:is-login="isLogin"
:current-doctor="currentDoctor.confidedId"
:play-status="playStatus"
@tap="toDetail(item)"
@player="playAudio"
/>
</block>
<view class="load-more">{{ !paging.hasMore ? '没有更多了~' : '加载中...' }}</view>
</scroll-view>
<view
v-else
class="no-data"
>
<view v-if="isLoaded">
<image
mode="aspectFill"
class="icon-find"
src="https://static.ydlcdn.com/weixin/image/home/no_data.png"
/>
<view class="c-666">未搜索到对应专家,请查询其他条件试试</view>
</view>
<view v-else>加载中...</view>
</view>
<view
v-if="playStatus"
class="player"
>
<view class="player-content">
<view <view
class="close-player" v-for="(course, index) in courseList"
@click="closePlayer" :key="index"
class="item-wrap"
@click="onPageToOrderDetail(course)"
> >
<img <view class="item-header">
class="player-icon" <text class="item-header-left">
src="https://static.ydlcdn.com/mini/mini_confide/confide_icon_close.png" <text class="item-header-title">订单号:</text>
alt="" <text class="item-header-num">{{ course.orderId }}</text>
/> <img
</view> class="item-header-img"
<view class="player-info"> src="//static.ydlcdn.com/m/images/m/course/ico_kcml_lock@3x.png"
<image />
class="player-cover" </text>
mode="aspectFill" <text
:src="currentDoctor.confidedIcon" :class="{
/> 'item-header-right': true,
<view> 'item-header-right-blue': index === 0,
<view class="player-title">壹点倾诉,心灵寄语</view> }"
<view class="player-user"> >
<text class="player-user-name">{{ currentDoctor.confidedName }}</text> 拼团中
<text </text>
v-show="playStartTime && playEndTime" </view>
class="player-user-time" <view class="item-content">
> <view class="item-content-img">
{{ playStartTime }} / {{ playEndTime }} <img src="//pic.ydlcdn.com/K4RBkeK5zx.jpg" />
</text> </view>
<view class="item-content-info">
<view class="item-content-info-row-first">
<text class="row-first-title">12天重塑你的安全感,让恋爱不再患得患失</text>
<text class="row-first-money">¥299</text>
</view>
<view class="item-content-info-row-second">
<text class="row-second-time">
{{
course.paymentTime
? dayjs(course.paymentTime).format('YYYY-MM-DD HH:mm:ss')
: ''
}}
</text>
<text class="row-second-money">
实付款:
<text class="row-second-money-num">¥199</text>
</text>
</view>
</view> </view>
</view> </view>
<view class="item-footer">
<text
class="item-footer-btn"
type="default"
@click="handleCourseItemClick($event, course)"
>
查看商品
</text>
</view>
</view> </view>
<view </template>
class="pause-player" <empty v-else></empty>
@click="pausePlayer" </template>
>
<img
class="player-icon"
:src="
isPausePlay
? 'https://static.ydlcdn.com/mini/mini_confide/confide_icon_play.png'
: 'https://static.ydlcdn.com/mini/mini_confide/confide_icon_pause.png'
"
alt=""
/>
</view>
</view>
</view>
</view> </view>
</template> </template>
<script> <script>
/* eslint-disable no-undef */ import Empty from './Empty.vue'
import ScreenBox from '@/components/expert-screen' import { throttle } from 'lodash'
import DoctorItem from '@/components/expert-item' import dayjs from 'dayjs'
import { setTrackData } from '@/utils/util' import { hostPrefix } from '@/config.js'
const innerAudioContext = uni.createInnerAudioContext() // import { Toast } from 'vant'
// 页面跳转
const navTo = url => {
const newUrl = `${hostPrefix}/h5-course/${url}`
uni.navigateTo({
url: `/pages/web/web?loadUrl=${encodeURIComponent(newUrl)}`,
})
}
export default { export default {
name: 'ExpertPage', name: 'BuyList',
components: { components: {
ScreenBox, Empty,
DoctorItem, },
props: {
keywords: {
type: String,
default: '',
},
// 是否展示学习进度
showProgress: {
type: Boolean,
default: false,
},
}, },
data() { data() {
return { return {
allowHomeScroll: true, dayjs,
scrollBottomRefresher: false, pageNo: 1,
fromOpenId: '', // 从分享进入时所携带分享人的openid pageSize: 10,
isLoaded: false, moreStatus: 'nomore',
isFixed: true, courseList: [{}, {}],
statistics: null, // todo 应该是 false
doctorArr: [], initFinish: true,
userInfo: {}, // 用户信息
paging: {
hasMore: true,
extras: null,
},
preScreen: {}, // 筛选信息
isLogin: false,
urlParams: {},
currentDoctor: {},
playStatus: false,
isPausePlay: false,
playStartTime: '',
playEndTime: '',
} }
}, },
watch: {
onLoad(options) { keywords: {
// 进入小程序判断是否携带参数 handler() {
if (options && options.searchWord) { // todo
this.urlParams = options // this.refresh();
this.preScreen.keywords = options.searchWord },
} immediate: true,
},
this.init()
// 咨询师列表访问埋点
setTrackData({
events: [
{
event_id: 'page_visit',
event_custom_properties: {
part: 'listener_list_page ',
position: '',
element: '',
},
},
],
})
},
onPullDownRefresh() {
this.onRefresh()
}, },
methods: { methods: {
// 下拉刷新 // 查看订单详情 todo
onRefresh() { onPageToOrderDetail({ id = 111 }) {
// 开启下拉刷新 navTo(`my/orderDetail/${id}`)
this.scrollBottomRefresher = true
this.paging.extras = null
this.init()
setTimeout(() => {
// 停止下拉刷新
uni.stopPullDownRefresh()
this.scrollBottomRefresher = false
}, 1000)
},
handleScrollBottom() {
// 滚动到底部加载更多数据
if (!this.paging.hasMore) return
this.getData()
}, },
// 课程卡片点击,跳转课程详情 todo
init() { handleCourseItemClick(e, { id = 111 }) {
this.getData(true) e.stopPropagation()
const accessToken = uni.getStorageSync('accessToken') navTo(`detail/${id}`)
this.isLogin = !!accessToken
},
onLoginEvent(e) {
if (e.detail.accessToken) {
this.isLogin = true
}
}, },
// 刷新列表,提供给父组件搜索过滤调用
onScreenDoctor(e = {}) { refresh() {
// 筛选组件回调 this.initFinish = false
this.preScreen = e this.moreStatus = 'nomore'
this.paging = { this.courseList = []
hasMore: true, this.pageNo = 1
}
this.getCourseList()
uni.pageScrollTo({
scrollTop: 0,
})
this.getData(true)
}, },
// 获取课程列表
async getData(isReset) { async getCourseList() {
let { doctorArr } = this try {
// dmp接口入参配置 // todo
const res = await this.$request // this.moreStatus === 'loading';
.get('smart-rank/v1/search-adapter/listeners', { // Toast.loading('加载中...');
params: { // const {total, list} = await this.$http.post('/course/v1/orders/pay/query', {
...this.preScreen, // pageNo: this.pageNo,
extras: this.paging ? this.paging.extras || null : null, // 分页参数,将上一页返回的 extras 传到这里,没有上一页则不传 // pageSize: this.pageSize,
}, // title: this.keywords || '',
}) // });
.finally(() => (this.loading = false)) // Toast.clear();
// this.courseList = [...this.courseList, ...list];
const { body } = res // this.courseList.map(item => {
if (isReset) { // item.salesPrice = item.money;
doctorArr = [] // item.originPrice = 0;
// })
// this.initFinish = true;
// this.moreStatus = this.courseList.length < total ? "more" : "nomore";
} catch (e) {
console.log(e)
} }
this.doctorArr = doctorArr.concat(body)
// 接口返回数据并且长度大于每页条数,可滚动加载
this.paging.hasMore = !!(Array.isArray(body) && body.length > 9)
this.paging.extras = res.extras
this.isLoaded = true
}, },
// 上拉加载下一页
// 跳转详情页 handleScroll: throttle(
toDetail(e) { function (e) {
if (!e.confidedId) { const { scrollHeight, offsetHeight, scrollTop } = e.target
return uni.showToast('专家数据错误') const height = scrollHeight - offsetHeight - scrollTop
} const scrollThreshold = 100
uni.navigateTo({ if (height <= scrollThreshold) {
url: `/pages/confide/confide?listenerId=${e.confidedId}`, if (this.moreStatus === 'more') {
}) this.pageNo = this.pageNo + 1
}, this.getCourseList()
}
onShareAppMessage() {
const openId = this.$store.state.user.openId
setTrackData({
events: [
{
event_id: 'common_click',
event_custom_properties: {
part: 'listener_list_page',
position: 'top_column',
element: 'share_friends',
},
},
],
})
return {
title: '倾诉师推荐',
path: `/pages/home/home?fromOpenId=${openId}${
this.preScreen.keywords ? '&searchWord=' + this.preScreen.keywords : ''
}`,
}
},
onShareTimeline() {
setTrackData({
events: [
{
event_id: 'common_click',
event_custom_properties: {
part: 'listener_list_page',
position: 'top_column',
element: 'share_moments',
},
},
],
})
return {
title: '倾诉师推荐-壹点灵心理',
query: {
fromOpenId: this.$store.state.user.openId,
searchWord: this.preScreen.keywords,
},
}
},
// 格式化音频时长
formatTime: function (s) {
let t = ''
s = Math.floor(s)
if (s > -1) {
const min = Math.floor(s / 60) % 60
const sec = s % 60
if (min < 10) {
t += '0'
} }
},
t += min + ':' 300,
if (sec < 10) { { leading: true },
t += '0' ),
}
t += sec
}
return t
},
closePlayer() {
this.playStatus = false
innerAudioContext.stop()
},
pausePlayer() {
if (!this.isPausePlay) {
innerAudioContext.pause()
} else {
innerAudioContext.play()
}
this.isPausePlay = !this.isPausePlay
},
// 播放音频
playAudio(item) {
var audioUrl = item.confideVoice
this.currentDoctor = item
if (item.isPlayer) {
this.playStatus = false
this.isPausePlay = false
innerAudioContext.stop()
return
}
this.playStatus = true
this.isPausePlay = false
innerAudioContext.stop()
innerAudioContext.autoplay = false
innerAudioContext.src = audioUrl
innerAudioContext.play()
innerAudioContext.onPlay(() => {
console.log('开始播放', innerAudioContext.duration)
setTimeout(() => {
// 设置音频总时长
this.playEndTime = this.formatTime(Math.ceil(innerAudioContext.duration))
}, 300)
})
innerAudioContext.onTimeUpdate(() => {
// 音频跟新时若总时长未获取则重新获取
if (!this.playEndTime) {
this.playEndTime = this.formatTime(Math.ceil(innerAudioContext.duration))
}
console.log('更新播放', innerAudioContext.duration)
// 跟新音频播放时长
this.playStartTime = this.formatTime(Math.ceil(innerAudioContext.currentTime))
})
innerAudioContext.onError(res => {
console.log(res.errMsg, '播放出错', res.errCode)
this.playStatus = false
})
innerAudioContext.onPause(() => {
console.log('播放暂停')
})
innerAudioContext.onEnded(() => {
console.log('播放结束')
this.playStatus = false
this.isPausePlay = false
this.playStartTime = '00:00'
})
},
}, },
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.home { .buy-list {
position: relative; background: #f8f8f8;
background: #fff;
padding: 94px 0 0 0;
height: 100%; height: 100%;
} overflow: auto;
.consult-list { -webkit-overflow-scrolling: touch;
width: 100%; overscroll-behavior-y: none;
height: 100%;
} .item-wrap {
.icon-find { background: #fff;
width: 100%; // border-bottom: 10px solid rgb(249, 249, 249);
} margin: 0 10px;
.no-data, margin-top: 10px;
.load-more { border-radius: 12px;
text-align: center; padding: 12px 12px 16px 12px;
padding: 20px; .item-header {
} display: flex;
justify-content: space-between;
.player { border-bottom: 1px solid rgb(249, 249, 249);
position: fixed; padding-bottom: 8px;
width: 100%; .item-header-img {
bottom: 60px; height: 15px;
left: 0; vertical-align: middle;
padding: 16px; }
.item-header-right-blue {
&-content { color: #1698ff;
width: 100%; }
color: #fff;
background: rgba(0, 0, 0, 0.8);
border-radius: 8px;
padding: 8px 20px 8px 8px;
display: flex;
align-items: center;
.player-cover {
width: 40px;
height: 40px;
margin-right: 12px;
border-radius: 4px;
} }
}
.player-info {
width: 100%;
display: flex;
align-items: center;
}
.player-title {
font-size: 16px;
line-height: 20px;
margin-bottom: 4px;
}
.player-user {
display: flex;
font-size: 12px;
line-height: 16px;
color: rgba(255, 255, 255, 0.6);
&-name { .item-content {
::after { display: flex;
content: ''; justify-content: space-between;
border-right: 0.5px solid rgba(255, 255, 255, 0.9); /* height: 65px; */
height: 8px; margin-top: 8px;
padding-right: 8px; .item-content-img {
margin-right: 8px; img {
height: 57px;
width: 46px;
}
}
.item-content-info {
flex: 1;
padding-left: 8px;
.item-content-info-row-first {
display: flex;
justify-content: space-between;
font-size: 14px;
font-weight: 500;
.row-first-title {
max-width: 175px;
}
}
.item-content-info-row-second {
display: flex;
justify-content: space-between;
/* line-height: 100%; */
align-items: center;
margin-top: 1px;
.row-second-time {
font-size: 12px;
color: #999999;
.row-second-money {
.row-second-money-num {
font-weight: 500;
}
}
}
}
} }
} }
} .item-footer {
display: flex;
.close-player { flex-direction: row-reverse;
margin-right: 8px; margin-top: 17px;
.player-icon { button {
width: 32px; height: 30px;
height: 32px; width: 68px;
vertical-align: middle; padding: 0;
border-radius: 5px;
font-size: 13px;
}
} }
} }
.player-icon {
width: 16px;
height: 16px;
vertical-align: middle;
}
} }
</style> </style>
...@@ -20,12 +20,14 @@ ...@@ -20,12 +20,14 @@
src="https://static.ydlcdn.com/mini/mini_consult/pic_default_avatar.png" src="https://static.ydlcdn.com/mini/mini_consult/pic_default_avatar.png"
@click="handleLoginClick" @click="handleLoginClick"
/> />
<text <view v-if="isLogin">
v-if="isLogin" <text class="user-name-phone">
class="user-name" {{ userInfo.nickName }}
> </text>
{{ userInfo.nickName }} <text class="user-name-phone">
</text> {{ userPhoneTxt }}
</text>
</view>
<view <view
v-else v-else
@click="handleLoginClick" @click="handleLoginClick"
...@@ -70,7 +72,7 @@ ...@@ -70,7 +72,7 @@
</template> </template>
<script> <script>
import { hostPrefix, h2Prefix } from '@/config' import { hostPrefix } from '@/config'
import { setTrackData } from '@/utils/util' import { setTrackData } from '@/utils/util'
export default { export default {
...@@ -79,26 +81,6 @@ export default { ...@@ -79,26 +81,6 @@ export default {
return { return {
menus: [ menus: [
{ {
icon: '/static/icon_order.png',
label: '我的订单',
callback: () => {
this.handleSendMenuTrackData('我的订单')
this.navigateToOrder()
},
},
{
icon: '/static/icon_help_center.png',
label: '帮助中心',
callback: () => {
this.handleSendMenuTrackData('帮助中心')
uni.navigateTo({
url: `/pages/web/web?title=帮助中心&loadUrl=${encodeURIComponent(
`${h2Prefix}/help/list/12`,
)}`,
})
},
},
{
icon: '/static/icon_custom_service.png', icon: '/static/icon_custom_service.png',
label: '联系客服', label: '联系客服',
callback: () => { callback: () => {
...@@ -142,6 +124,13 @@ export default { ...@@ -142,6 +124,13 @@ export default {
isLogin() { isLogin() {
return this.$store.getters.isLogin return this.$store.getters.isLogin
}, },
// 混淆手机号码
userPhoneTxt() {
if (this.userInfo.phone) {
return String(this.userInfo.phone).replace(/(.{3})(.{4})(.+$)/, '$1****$3')
}
return ''
},
}, },
mounted() { mounted() {
// 页面访问埋点 // 页面访问埋点
...@@ -243,6 +232,14 @@ export default { ...@@ -243,6 +232,14 @@ export default {
font-size: 18px; font-size: 18px;
margin-bottom: 4px; margin-bottom: 4px;
} }
.user-name-phone {
margin-left: 16px;
color: #000000;
font-weight: 400;
font-size: 15px;
margin-bottom: 4px;
display: block;
}
.login-tips { .login-tips {
margin-left: 16px; margin-left: 16px;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment