第一次提交
This commit is contained in:
122
pages/article/article.vue
Normal file
122
pages/article/article.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- <view class="search-wrapper">
|
||||
<u-search :showAction="true" actionText="搜索" :animation="true" v-model="where.keywords" @search="onSearch"></u-search>
|
||||
</view> -->
|
||||
<view class="user-list">
|
||||
<u-list @scrolltolower="scrolltolower">
|
||||
<view class="list">
|
||||
<u-list-item v-for="(item, index) in list" :key="index">
|
||||
<u-cell
|
||||
@click="navTo('/pages/article/detail/detail',{id: item.articleId})">
|
||||
<u-avatar slot="icon" size="50" :src="item.image ? `https://file.wsdns.cn/thumbnail${item.image}` : item.userAvatar" shape="square"
|
||||
customStyle="margin: -3px 5px -3px 0"></u-avatar>
|
||||
<view slot="title">{{ item.title }}</view>
|
||||
</u-cell>
|
||||
</u-list-item>
|
||||
<u-empty
|
||||
v-if="list.length == 0"
|
||||
mode="search"
|
||||
icon="http://cdn.uviewui.com/uview/empty/search.png"
|
||||
>
|
||||
</u-empty>
|
||||
</view>
|
||||
</u-list>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ArticleApi from '@/api/article.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
page: 0,
|
||||
where: {},
|
||||
// 控制onShow事件是否刷新订单列表
|
||||
canReset: false,
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.where = options
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 刷新会员列表
|
||||
onRefreshList() {
|
||||
const app = this
|
||||
app.where.page = app.page
|
||||
app.where.categoryId = 55
|
||||
return new Promise((resolve, reject) => {
|
||||
ArticleApi.pageArticle(app.where)
|
||||
.then(result => {
|
||||
const list = result.data.list
|
||||
console.log("list: ",list);
|
||||
// 合并新数据
|
||||
app.list = app.list.concat(list)
|
||||
console.log("app.list: ",app.list);
|
||||
if(result.data.count > app.list.length){
|
||||
app.canReset = true
|
||||
}else{
|
||||
app.canReset = false
|
||||
}
|
||||
resolve(list)
|
||||
})
|
||||
})
|
||||
},
|
||||
scrolltolower(e){
|
||||
console.log("e: ",e);
|
||||
},
|
||||
navTo(url,userId){
|
||||
this.$push(url,userId)
|
||||
},
|
||||
onFollow(e){
|
||||
console.log("e11: ",e);
|
||||
},
|
||||
onSearch(){
|
||||
this.list = []
|
||||
this.where.page = 1
|
||||
this.onRefreshList()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 0rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
height: 64rpx;
|
||||
}
|
||||
.user-list{
|
||||
margin: 0rpx auto;
|
||||
}
|
||||
|
||||
.follow-btn {
|
||||
padding: 4rpx 20rpx;
|
||||
color: #ffffff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 50rpx;
|
||||
margin-right: 10rpx;
|
||||
background: linear-gradient(#47076b, #8d1a50);
|
||||
|
||||
image {
|
||||
width: 24rpx;
|
||||
height: 66rpx;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
116
pages/article/detail/detail.vue
Normal file
116
pages/article/detail/detail.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container b-f p-b">
|
||||
<!-- <view class="article-title">
|
||||
<text class="f-32">{{ detail.title }}</text>
|
||||
</view> -->
|
||||
<view class="article-little dis-flex flex-x-between m-top10">
|
||||
<!-- <view class="article-little__left">
|
||||
<text class="article-views f-24 col-8">{{ detail.show_views }}次浏览</text>
|
||||
</view> -->
|
||||
<view class="article-little__right">
|
||||
<text class="article-views f-24 col-8">{{ detail.view_time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="article-content m-top20">
|
||||
<mp-html :content="detail.content" />
|
||||
</view>
|
||||
<!-- 快捷导航 -->
|
||||
<!-- <shortcut /> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Shortcut from '@/components/shortcut'
|
||||
import * as ArticleApi from '@/api/article'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Shortcut
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 当前文章ID
|
||||
articleId: null,
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 当前文章详情
|
||||
detail: null
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(e){
|
||||
const { id } = e
|
||||
console.log("id: ",id);
|
||||
this.articleId = id
|
||||
},
|
||||
|
||||
onShow(e) {
|
||||
// 获取文章详情
|
||||
this.getArticleDetail()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取文章详情
|
||||
getArticleDetail() {
|
||||
const app = this
|
||||
const { articleId } = this
|
||||
app.isLoading = true
|
||||
ArticleApi.getArticle(articleId)
|
||||
.then(result => {
|
||||
app.detail = result.data;
|
||||
|
||||
// 改写标题
|
||||
uni.setNavigationBarTitle({
|
||||
title: app.detail.title
|
||||
})
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享当前页面
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({ articleId: app.articleId });
|
||||
return {
|
||||
title: app.detail.title,
|
||||
path: "/pages/article/detail?" + params
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({ articleId: app.articleId });
|
||||
return {
|
||||
title: app.detail.title,
|
||||
path: "/pages/article/detail?" + params
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-height: 90vh;
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
}
|
||||
.article-title{
|
||||
text-align: center;
|
||||
}
|
||||
.article-content {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
213
pages/chat/chat.vue
Normal file
213
pages/chat/chat.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
|
||||
<!-- <z-paging :height="msgListHeight + 'px'" ref="paging" v-model="dataList" use-chat-record-mode :fixed="false" > -->
|
||||
<!-- 聊天item -->
|
||||
<scroll-view :style="{ height: msgListHeight + 'px' }" scroll-y :scroll-top="scrollTop" scroll-with-animation>
|
||||
<view class="tips">
|
||||
小红娘提醒:任何涉及投资、理财、邮寄包裹等信息都存在诈骗嫌疑,请及时举报!
|
||||
<text class="link" @click.stop="$push('pages/article/detail/detail?id=461')">安全指南</text>
|
||||
</view>
|
||||
<view id="msg-box">
|
||||
<view :id="`z-paging-${index}`" v-for="(item, index) in dataList" :key="index">
|
||||
<chat-item @onImageClick="onImageClick(index)" :prevMsgTime="index>0?dataList[index - 1].createTime: null" :friendInfo="friendInfo" :item="item"></chat-item>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- </z-paging> -->
|
||||
<view id="chat-input-bar">
|
||||
<chat-input-bar @heightChange="resetMsgListHeight" @send="doSend" />
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ChatInputBar from "@/components/chat-input-bar/chat-input-bar.vue"
|
||||
import ChatItem from "@/components/chat-item/chat-item.vue"
|
||||
import { mapGetters,mapActions} from 'vuex'
|
||||
import {
|
||||
USER_ID,
|
||||
USER_INFO
|
||||
} from '@/store/mutation-types'
|
||||
import storage from '@/utils/storage'
|
||||
import * as UserProfileApi from '@/api/love-user-profile.js'
|
||||
import ZPMixin from '@/uni_modules/z-paging/components/z-paging/js/z-paging-mixin'
|
||||
export default {
|
||||
mixins: [ZPMixin],
|
||||
components: {
|
||||
ChatInputBar,
|
||||
ChatItem
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['conversations'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
friendId: 1,
|
||||
dataList: [],
|
||||
friendInfo: {},
|
||||
keyboardHeight: 0,
|
||||
screenHeight: 0,
|
||||
msgListHeight: 0,
|
||||
inputHeight: 0,
|
||||
scrollTop: 0
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.friendId = options.friendId
|
||||
this.MarkRead(this.friendId)
|
||||
// this.friendInfo = this.$store.getters.friends.find(item=> item.userId = options.friendId)
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
async onReady() {
|
||||
// 获取屏幕高度
|
||||
uni.getSystemInfo({
|
||||
success: res => {
|
||||
console.log(res);
|
||||
this.screenHeight = res.windowHeight
|
||||
this.resetMsgListHeight()
|
||||
}
|
||||
})
|
||||
|
||||
// 监听键盘高度变化
|
||||
uni.onKeyboardHeightChange(res => {
|
||||
this.keyboardHeight = res.height
|
||||
// this.resetMsgListHeight()
|
||||
})
|
||||
|
||||
// 获取消息
|
||||
await this.LoadFriendMessage(this.friendId)
|
||||
const messages = this.conversations[this.friendId].messages || []
|
||||
this.friendInfo = this.conversations[this.friendId].friendInfo || {}
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.friendInfo.nickname
|
||||
})
|
||||
const list = JSON.parse(JSON.stringify(messages))
|
||||
this.dataList = list
|
||||
setTimeout(()=>{
|
||||
this.toMsgListBottom()
|
||||
}, 1000)
|
||||
// this.$nextTick(()=>{
|
||||
// this.toMsgListBottom()
|
||||
// })
|
||||
// this.$refs.paging.complete(list);
|
||||
// 第一次聊天 发打招呼的卡牌
|
||||
if(list.length == 0){
|
||||
const userId = uni.getStorageSync('userId')
|
||||
const res = await UserProfileApi.getUserProfile(userId)
|
||||
console.log("第一次聊天 发打招呼的卡牌 ",res.data);
|
||||
console.log(res.data.images);
|
||||
const images = JSON.parse(res.data.images) || []
|
||||
if(images.length > 3){
|
||||
images.splice(3, images.length - 3)
|
||||
}
|
||||
this.SendMessage({
|
||||
type: 'card',
|
||||
content: JSON.stringify({
|
||||
age: res.data.age,
|
||||
city: res.data.city,
|
||||
height: res.data.height,
|
||||
yearlyPay: res.data.yearlyPay,
|
||||
position: res.data.position,
|
||||
files: images.map(d => {
|
||||
return {
|
||||
thumb: d.url,
|
||||
url: d.url
|
||||
}
|
||||
})
|
||||
}),
|
||||
toUserId: this.friendId,
|
||||
formUserId: this.$store.getters.userId
|
||||
})
|
||||
}
|
||||
// 收到新消息
|
||||
uni.$on('message' + this.friendId, (data)=>{
|
||||
this.dataList.push(data)
|
||||
this.MarkRead(this.friendId)
|
||||
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('message' + this.friendId)
|
||||
},
|
||||
onPageScroll(e) {
|
||||
//如果滚动到顶部,触发加载更多聊天记录
|
||||
if (e.scrollTop < 10) {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['SendMessage','LoadFriendMessage','MarkRead']),
|
||||
/**
|
||||
* 消息列表高度
|
||||
*/
|
||||
resetMsgListHeight(){
|
||||
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('#chat-input-bar').boundingClientRect(data => {
|
||||
this.msgListHeight = this.screenHeight - data.height - this.keyboardHeight
|
||||
uni.$u.debounce(this.toMsgListBottom, 300)
|
||||
}).exec();
|
||||
},
|
||||
/**
|
||||
* 滚动到最后一条消息
|
||||
*/
|
||||
toMsgListBottom() {
|
||||
this.scrollTop += 9999
|
||||
},
|
||||
async doSend(msg){
|
||||
await this.SendMessage({
|
||||
type: msg.type,
|
||||
content: msg.content,
|
||||
toUserId: this.friendId,
|
||||
formUserId: this.$store.getters.userId
|
||||
})
|
||||
this.toMsgListBottom()
|
||||
|
||||
|
||||
},
|
||||
onImageClick(index){
|
||||
console.log("onImageClick", index);
|
||||
const arr = []
|
||||
let current = 0
|
||||
this.dataList.forEach((item, i)=>{
|
||||
if(item.type == 'image'){
|
||||
arr.push(item.content)
|
||||
if(index == i){
|
||||
current = arr.length - 1
|
||||
}
|
||||
}
|
||||
})
|
||||
uni.previewImage({
|
||||
urls: arr,
|
||||
current
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content{
|
||||
height: 100vh;
|
||||
.tips{
|
||||
width: 660rpx;
|
||||
margin: 20rpx auto;
|
||||
color: #818284;
|
||||
font-size: 26rpx;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
line-height: 1.3rem;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
|
||||
.link{
|
||||
color: #681752;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
609
pages/checkout/cashier/index.vue
Executable file
609
pages/checkout/cashier/index.vue
Executable file
@@ -0,0 +1,609 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="!isLoading" class="container" :style="appThemeStyle">
|
||||
<!-- 订单信息 -->
|
||||
<view class="order-info">
|
||||
<!-- 支付剩余时间 -->
|
||||
<view class="order-countdown">
|
||||
<text class="m-r-6">剩余时间</text>
|
||||
<count-down :date="expirationTime" separator="zh" theme="text" />
|
||||
</view>
|
||||
<!-- 付款金额 -->
|
||||
<view class="order-amount">
|
||||
<text class="unit">¥</text>
|
||||
<text class="amount">{{ totalPrice }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="payment-method">
|
||||
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between"
|
||||
@click="handleSelectPayType(index)">
|
||||
<view class="item-left dis-flex flex-y-center">
|
||||
<view class="item-left_icon" :class="[item.method]">
|
||||
<text class="iconfont" :class="[item.icon]"></text>
|
||||
</view>
|
||||
<view class="item-left_text">
|
||||
<text>{{ item.method }}</text>
|
||||
</view>
|
||||
<view v-if="item.method === '余额支付'" class="user-balance">
|
||||
<text v-if="personal">(可用¥{{ personal.balance }}元)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
|
||||
<text class="iconfont icon-check"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 确认按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认支付</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付确认弹窗 -->
|
||||
<!-- #ifdef H5 -->
|
||||
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
|
||||
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
|
||||
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
|
||||
<view class="modal-content">
|
||||
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付,如果您已经支付成功,请点击“已完成支付”按钮</text>
|
||||
</view>
|
||||
</u-modal>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<empty v-else :isLoading="isLoading" tips="订单不存在" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage'
|
||||
import {
|
||||
inArray,
|
||||
urlEncode
|
||||
} from '@/utils/util'
|
||||
import {
|
||||
Alipay,
|
||||
Wechat
|
||||
} from '@/core/payment'
|
||||
import CountDown from '@/components/countdown'
|
||||
import {
|
||||
PayMethodEnum
|
||||
} from '@/common/enum/payment'
|
||||
import {
|
||||
PayStatusEnum
|
||||
} from '@/common/enum/order'
|
||||
import * as OrderApi from '@/api/order.js'
|
||||
import * as PaymentApi from '@/api/payment.js'
|
||||
import {
|
||||
dateFormat
|
||||
} from '@/utils/util.js'
|
||||
import Empty from '@/components/empty'
|
||||
// import * as CashierApi from '@/api/cashier'
|
||||
import * as UserApi from '@/api/user.js'
|
||||
|
||||
// 支付方式对应的图标
|
||||
const PayMethodIconEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
|
||||
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
|
||||
[PayMethodEnum.BALANCE.value]: 'icon-balance-pay'
|
||||
}
|
||||
|
||||
// 支付方式的终端名称
|
||||
const PayMethodClientNameEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: '微信',
|
||||
[PayMethodEnum.ALIPAY.value]: '支付宝'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown,
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
orderIds: [],
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 确认按钮禁用
|
||||
disabled: false,
|
||||
// 枚举类
|
||||
PayMethodEnum,
|
||||
PayMethodIconEnum,
|
||||
PayMethodClientNameEnum,
|
||||
// 当前选中的支付方式
|
||||
curPaymentItem: {
|
||||
method: '余额支付'
|
||||
},
|
||||
// 当前订单ID
|
||||
orderId: null,
|
||||
// 当前结算订单信息
|
||||
order: null,
|
||||
deliveryTime: null,
|
||||
// 订单过期时间
|
||||
expirationTime: new Date(),
|
||||
// 个人信息
|
||||
personal: {
|
||||
balance: '0.00'
|
||||
},
|
||||
totalPrice: 0,
|
||||
// 当前客户端的支付方式列表(后端根据platform判断)
|
||||
methods: [
|
||||
{
|
||||
id: 1,
|
||||
method: '余额支付',
|
||||
icon: 'icon-balance-pay'
|
||||
},
|
||||
// {
|
||||
// id: 2,
|
||||
// method: '支付宝',
|
||||
// icon: 'icon-alipay'
|
||||
// }
|
||||
],
|
||||
// 支付确认弹窗
|
||||
showConfirmModal: false,
|
||||
// #ifdef H5
|
||||
// 当前微信支付信息 (临时数据, 仅用于H5端)
|
||||
tempUnifyData: {
|
||||
outTradeNo: '',
|
||||
method: ''
|
||||
},
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(option) {
|
||||
this.orderIds = option.orderIds.split(',')
|
||||
// 记录订单ID
|
||||
// this.orderId = Number(orderId)
|
||||
// this.deliveryTime = deliveryTime
|
||||
// // 获取收银台信息
|
||||
this.getCashierInfo()
|
||||
},
|
||||
|
||||
onShow() {},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取收银台信息
|
||||
getCashierInfo() {
|
||||
const app = this
|
||||
const { orderIds } = this
|
||||
app.isLoading = true
|
||||
console.log(orderIds);
|
||||
// 加载订单
|
||||
console.log("typeof(orderIds): ",typeof(orderIds));
|
||||
const baoCanExpirationTime = uni.getStorageSync('baoCanExpirationTime')
|
||||
console.log(baoCanExpirationTime);
|
||||
OrderApi.listByIds(orderIds)
|
||||
.then(res => {
|
||||
console.log("res: ",res);
|
||||
res.data.map(d => {
|
||||
console.log("app.totalPrice: ",app.totalPrice);
|
||||
console.log("d: ",d.payPrice);
|
||||
app.totalPrice = app.totalPrice + d.payPrice
|
||||
})
|
||||
app.isLoading = false
|
||||
// 处理订单过期时间(*1小时)
|
||||
var expirationTime = new Date().getTime() + 60 * 60 * 1000 * 0.20
|
||||
app.expirationTime = dateFormat('YYYY-mm-dd HH:MM:SS', new Date(expirationTime))
|
||||
|
||||
})
|
||||
.catch(e => {
|
||||
console.log("e: ", e);
|
||||
})
|
||||
// 查询余额
|
||||
const agentUser = uni.getStorageSync('agentUser')
|
||||
if(agentUser){
|
||||
app.getAgentUser()
|
||||
}else{
|
||||
UserApi.getUser().then(res => app.personal = res.data)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getAgentUser(){
|
||||
const app = this
|
||||
const agentUser = uni.getStorageSync('agentUser')
|
||||
if(agentUser){
|
||||
UserApi.getAgentUser(agentUser.userId).then(res => {
|
||||
app.personal = res.data
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 设置默认的支付方式
|
||||
setDefaultPayType() {
|
||||
const app = this
|
||||
if (app.disabled) return
|
||||
const defaultIndex = app.methods.findIndex(item => item.is_default == true)
|
||||
defaultIndex > -1 && app.handleSelectPayType(defaultIndex)
|
||||
},
|
||||
|
||||
// 判断当前订单是否为已支付
|
||||
checkOrderPayStatus() {
|
||||
const app = this
|
||||
if (app.order.pay_status == PayStatusEnum.SUCCESS.value) {
|
||||
app.$toast('恭喜您,订单已付款成功')
|
||||
app.onSuccessNav()
|
||||
}
|
||||
},
|
||||
|
||||
// 选择支付方式
|
||||
handleSelectPayType(index) {
|
||||
this.curPaymentItem = this.methods[index]
|
||||
console.log("this.curPaymentItem: ", this.curPaymentItem);
|
||||
},
|
||||
|
||||
// 判断当前页面来源于浏览器返回
|
||||
// #ifdef H5
|
||||
performance() {
|
||||
const app = this
|
||||
// 判断订单状态, 异步回调会将订单状态变为已支付, 那么就不需要让用户手动查单了
|
||||
if (app.order.pay_status == PayStatusEnum.PENDING.value) {
|
||||
app.alipayPerformance()
|
||||
app.wechatPerformance()
|
||||
}
|
||||
},
|
||||
|
||||
// H5端支付宝支付完成跳转回当前页面时触发
|
||||
alipayPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Alipay.performance()
|
||||
if (app.tempUnifyData) {
|
||||
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
|
||||
}
|
||||
},
|
||||
|
||||
// H5端微信支付完成或返回时触发
|
||||
wechatPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Wechat.performance(app.orderId)
|
||||
if (app.tempUnifyData) {
|
||||
app.showConfirmModal = true
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 确认支付
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
orderIds
|
||||
} = this
|
||||
// 判断是否选择了支付方式
|
||||
if (!app.curPaymentItem) {
|
||||
app.$toast('您还没有选择支付方式')
|
||||
return
|
||||
}
|
||||
// 按钮禁用
|
||||
if (app.disabled) return
|
||||
// app.disabled = true
|
||||
// .js
|
||||
console.log("orderIds: ",orderIds);
|
||||
console.log("curPaymentItem: ",app.curPaymentItem);
|
||||
if(app.curPaymentItem.method == '余额支付'){
|
||||
console.log("'ssss: ",'ssss');
|
||||
PaymentApi.balanceBatch(orderIds).then(result => app.onSubmitCallback(result)).catch(err => app.$error(err.message))
|
||||
}
|
||||
// if(app.curPaymentItem.method == '支付宝'){
|
||||
// PaymentApi.alipay(orderIds).then(result => app.onSubmitCallback(result)).catch(err => app.$error(err.message))
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// // 提交到后端API
|
||||
// CashierApi.orderPay(app.orderId, {
|
||||
// method: app.curPaymentItem.method,
|
||||
// client: app.platform,
|
||||
// extra: app.getExtraAsUnify(app.curPaymentItem.method)
|
||||
// })
|
||||
// .then(result => app.onSubmitCallback(result))
|
||||
// .finally(err => setTimeout(() => app.disabled = false, 10))
|
||||
},
|
||||
|
||||
// 获取第三方支付的扩展参数
|
||||
getExtraAsUnify(method) {
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
return Alipay.extraAsUnify()
|
||||
}
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
return Wechat.extraAsUnify()
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
// 订单提交成功后回调
|
||||
onSubmitCallback(result) {
|
||||
const app = this
|
||||
const method = app.curPaymentItem.method
|
||||
const tradeNO = result.data
|
||||
console.log("result订单提交成功后回调: ", tradeNO);
|
||||
// 余额支付
|
||||
if (method === '余额支付') {
|
||||
app.onShowSuccess(result)
|
||||
}
|
||||
// 发起支付宝支付
|
||||
if (method === '支付宝') {
|
||||
my.tradePay({
|
||||
// 调用统一收单交易创建接口(alipay.trade.create),获得返回字段支付宝交易号trade_no
|
||||
tradeNO: tradeNO,
|
||||
success: (res) => {
|
||||
console.log("res11: ", res);
|
||||
if (res.resultCode == "9000") {
|
||||
payQuery(app.orderId).then(result => {
|
||||
if(result.code == 0) {
|
||||
app.$success('支付成功')
|
||||
app.$navTo('pages/order/detail?orderId='+app.orderId)
|
||||
}
|
||||
})
|
||||
|
||||
// setPayStatus({
|
||||
// orderId: app.orderId,
|
||||
// payStatus: 20,
|
||||
// payMethod: 20
|
||||
// }).then(res => {
|
||||
// console.log("updateOrder: ",res);
|
||||
// app.$navTo('pages/order/index')
|
||||
// })
|
||||
}
|
||||
if (res.resultCode == "6001") {
|
||||
app.$navTo('pages/order/index')
|
||||
}
|
||||
// my.alert({
|
||||
// content: JSON.stringify(res),
|
||||
// });
|
||||
},
|
||||
fail: (res) => {
|
||||
my.alert({
|
||||
content: JSON.stringify(res),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Alipay.payment(paymentData)
|
||||
// .then(res => app.onPaySuccess(res))
|
||||
// .catch(err => app.onPayFail(err))
|
||||
}
|
||||
// 发起微信支付
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Wechat.payment({
|
||||
orderKey: app.orderId,
|
||||
...paymentData
|
||||
})
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
},
|
||||
|
||||
// 订单支付成功的回调方法
|
||||
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
|
||||
onPaySuccess({
|
||||
res,
|
||||
option: {
|
||||
isRequireQuery,
|
||||
outTradeNo,
|
||||
method
|
||||
}
|
||||
}) {
|
||||
const app = this
|
||||
// 判断是否需要主动查单
|
||||
// isRequireQuery为true代表需要主动查单
|
||||
if (isRequireQuery) {
|
||||
app.onTradeQuery(outTradeNo, method)
|
||||
return true
|
||||
}
|
||||
this.onShowSuccess(res)
|
||||
},
|
||||
|
||||
// 显示支付成功信息并页面跳转
|
||||
onShowSuccess({
|
||||
message
|
||||
}) {
|
||||
this.$toast(message || '订单支付成功')
|
||||
this.onSuccessNav()
|
||||
},
|
||||
|
||||
// 订单支付失败
|
||||
onPayFail(err) {
|
||||
console.log('onPayFail', err)
|
||||
const errMsg = err.message || '订单未支付'
|
||||
this.$error(errMsg)
|
||||
},
|
||||
|
||||
// 已完成支付按钮事件: 请求后端查单
|
||||
onTradeQuery(outTradeNo, method) {
|
||||
const app = this
|
||||
// 交易查询
|
||||
// 查询第三方支付订单是否付款成功
|
||||
CashierApi.tradeQuery({
|
||||
outTradeNo,
|
||||
method,
|
||||
client: app.platform
|
||||
})
|
||||
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
|
||||
.finally(() => app.showConfirmModal = false)
|
||||
},
|
||||
|
||||
// 支付成功后的跳转
|
||||
onSuccessNav() {
|
||||
// 相应全局事件订阅: 刷新上级页面数据
|
||||
uni.$emit('syncRefreshOrder', true)
|
||||
// 获取上级页面
|
||||
const { orderId,deliveryTime } = this
|
||||
const pages = getCurrentPages()
|
||||
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
|
||||
const backRoutes = [
|
||||
'pages/order/index',
|
||||
'pages/order/detail'
|
||||
]
|
||||
// 取消临时报餐状态
|
||||
uni.removeStorageSync('baoCanExpirationTime')
|
||||
setTimeout(() => {
|
||||
if (lastPage && inArray(lastPage.route, backRoutes)) {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
this.$navTo('pages/index/index', {deliveryTime}, 'redirectTo')
|
||||
}
|
||||
}, 1200)
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #F4F4F4;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F4F4F4;
|
||||
}
|
||||
|
||||
// 订单信息
|
||||
.order-info {
|
||||
padding: 80rpx 0;
|
||||
text-align: center;
|
||||
|
||||
.order-countdown {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.order-amount {
|
||||
margin: 0 auto;
|
||||
max-width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fb0f07;
|
||||
|
||||
.unit {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: -18rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 支付方式
|
||||
.payment-method {
|
||||
width: 94%;
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.pay-item {
|
||||
padding: 26rpx 0;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid rgb(248, 248, 248);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left_icon {
|
||||
margin-right: 20rpx;
|
||||
font-size: 44rpx;
|
||||
|
||||
&.wechat {
|
||||
color: #00c800;
|
||||
}
|
||||
|
||||
&.alipay {
|
||||
color: #009fe8;
|
||||
}
|
||||
|
||||
&.balance {
|
||||
color: #ff9700;
|
||||
}
|
||||
}
|
||||
|
||||
.item-left_text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.user-balance {
|
||||
margin-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 支付确认弹窗
|
||||
.modal-content {
|
||||
padding: 40rpx 48rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 50rpx;
|
||||
text-align: left;
|
||||
color: #606266;
|
||||
// height: 620rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
color: $main-text;
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
787
pages/checkout/checkout.vue
Normal file
787
pages/checkout/checkout.vue
Normal file
@@ -0,0 +1,787 @@
|
||||
<template>
|
||||
<view class="user-index">
|
||||
<view class="page-bg"></view>
|
||||
<view class="header" :style="'margin-top: ' + statusBarHeight + 'px'"></view>
|
||||
<view class="main-header">
|
||||
<image class="bg-image" :src="bgImage" mode="scaleToFill"></image>
|
||||
<!-- 用户信息 -->
|
||||
</view>
|
||||
|
||||
<view class="main">
|
||||
<!-- 表单信息 -->
|
||||
<u--form :model="form" ref="uForm">
|
||||
<view class="buy-user">
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-cell-group :border="false">
|
||||
<u-cell title="姓名" :isLink="true">
|
||||
<input slot="value" class="w-input" placeholder="请填写姓名" v-model="form.realName" />
|
||||
</u-cell>
|
||||
<u-cell title="手机号" :isLink="true">
|
||||
<input slot="value" class="w-input" placeholder="请填写手机号码" v-model="form.phone" />
|
||||
</u-cell>
|
||||
<u-cell title="所属区域" :isLink="true" @click="onArea">
|
||||
<input slot="value" class="w-input" :disabled="true" placeholder="请选择所属区域" v-model="form.area" />
|
||||
</u-cell>
|
||||
<u-cell title="服务门店" :border="false" :isLink="true" @click="onMerchant">
|
||||
<input slot="value" class="w-input" :disabled="true" placeholder="请选择服务门店" v-model="form.merchantName" />
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
<u-gap height="3"></u-gap>
|
||||
<!-- 会员套餐 -->
|
||||
<view class="buy-user">
|
||||
<u-cell :title="form.roleName"></u-cell>
|
||||
<view class="price-box">
|
||||
<view class="info">
|
||||
<image :src="form.icon"
|
||||
mode="aspectFill"></image>
|
||||
<view class="content">
|
||||
{{ form.comments }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="price" v-for="(item,index) in form.price" :key="index" v-if="priceId == item.id">
|
||||
<text class="reb">¥{{ item.price }}</text>
|
||||
<text class="num">x1</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="xieyi">
|
||||
<u-icon name="checkbox-mark"></u-icon>
|
||||
购买代表同意爱尚客网
|
||||
<text @click="$push('pages/article/detail/detail?id=116')">《人工牵线协议》</text>
|
||||
</view>
|
||||
</u--form>
|
||||
</view>
|
||||
<view class="cart">
|
||||
<view class="cart-info" @click="navTo('pages/menu/menu')">
|
||||
<!-- <view style="position: relative;"> -->
|
||||
<!-- <u-badge class="badge" size="mini" type="error" :is-center="true" :count="totalNum"></u-badge> -->
|
||||
<!-- <image class="cart-logo" src="../../static/icon/cart4.png"></image> -->
|
||||
<!-- </view> -->
|
||||
<view class="total-price">¥{{ totalPrice }}</view>
|
||||
<!-- <view class="clear-cart" @click="onClearCart">清空购物车</view> -->
|
||||
<view class="buy">
|
||||
<u-button text="立即下单" shape="circle" type="error" class="custom-style" :disabled="disabled"
|
||||
@click="onBuy">
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 地址选择器 -->
|
||||
<liu-customize-sel ref="area" @change="chooseSuccess"></liu-customize-sel>
|
||||
<!-- 选择店铺 -->
|
||||
<u-picker :show="showMerchant" :columns="merchantList" keyName="label" @confirm="confirmMerchant"
|
||||
@cancel="showMerchant = false"></u-picker>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store/index.js'
|
||||
import storage from '@/utils/storage'
|
||||
import * as UserPlanApi from '@/api/love-user-plan.js'
|
||||
import * as UserPlanLogApi from '@/api/love-user-plan-log.js'
|
||||
import * as MerchantApi from '@/api/merchant.js'
|
||||
import {
|
||||
getUser,
|
||||
updateUser
|
||||
} from '@/api/user.js'
|
||||
import {
|
||||
username
|
||||
} from '@/config.js';
|
||||
import {
|
||||
getMobile
|
||||
} from '@/utils/util.js'
|
||||
import http from '@/api'
|
||||
|
||||
const userId = uni.getStorageSync('userId')
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
merchantList: [],
|
||||
bgImage: 'data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.36308349769888226%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%23101010%22%20stop-opacity%3D%221%22%20offset%3D%220.24%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23160028%22%20stop-opacity%3D%221%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E',
|
||||
statusBarHeight: 25,
|
||||
// 是否已登录
|
||||
isLogin: false,
|
||||
disabled: false,
|
||||
showMerchant: false,
|
||||
// 系统设置
|
||||
form: {
|
||||
planId: 0,
|
||||
priceId: 0,
|
||||
area: '',
|
||||
merchantName: ''
|
||||
},
|
||||
priceId: 0,
|
||||
totalPrice: 0.00,
|
||||
dealerId: 0
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.form.planId = Number(options.planId)
|
||||
this.priceId = Number(options.priceId)
|
||||
this.totalPrice = options.price
|
||||
this.getUserInfo()
|
||||
this.getOrderInfo()
|
||||
// 设置navbar标题、颜色options
|
||||
uni.setNavigationBarColor({
|
||||
frontColor: '#ffffff',
|
||||
backgroundColor: '#101010'
|
||||
})
|
||||
},
|
||||
onShow() {},
|
||||
watch: {
|
||||
dealerId(val,old) {
|
||||
console.log("侦听根级属性侦听根级属性侦听根级属性侦听根级属性44: ",val);
|
||||
this.getDealerMerchant(val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 跳转页面
|
||||
navTo(url) {
|
||||
this.$navTo(url)
|
||||
},
|
||||
getUserInfo() {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
const app = this
|
||||
uni.getSystemInfo({
|
||||
success(data) {
|
||||
if (data) {
|
||||
app.statusBarHeight = data.statusBarHeight + 50
|
||||
}
|
||||
}
|
||||
})
|
||||
getUser().then(res => {
|
||||
if (res.code == 0 && res.data.username != 'www') {
|
||||
if(res.data){
|
||||
console.log("res.data.phone: ",res.data.phone);
|
||||
app.form.realName = res.data.nickname
|
||||
app.form.phone = res.data.phone
|
||||
app.dealerId = res.data.dealerId
|
||||
// app.getDealerMerchant(res.data.dealerId)
|
||||
}
|
||||
app.isLogin = true
|
||||
} else {
|
||||
app.isLogin = false
|
||||
app.$push('pages/login/index')
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
getOrderInfo(){
|
||||
const app = this
|
||||
const { planId } = this.form
|
||||
UserPlanApi.getUserPlan(planId).then(result => {
|
||||
console.log("result: ",result);
|
||||
app.form = result.data
|
||||
result.data.price.map(d => {
|
||||
if(d.id == app.priceId){
|
||||
app.form.priceId = d.id
|
||||
app.totalPrice = d.price.toFixed(2)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
getMerchant(){
|
||||
const app = this
|
||||
const form = {
|
||||
region: app.form.region
|
||||
}
|
||||
console.log("app.planId: ",app.planId);
|
||||
if(app.form.planId == 18){
|
||||
form.gradeId = 18
|
||||
}
|
||||
MerchantApi.listMerchant(form).then(result => {
|
||||
let arr = []
|
||||
app.merchantList = []
|
||||
result.data.map(d => {
|
||||
console.log(d);
|
||||
// 只收集线下门店
|
||||
if(d.gradeId >= 10){
|
||||
arr.push({
|
||||
label: `${d.merchantName} (${d.gradeName})`,
|
||||
id: d.merchantId,
|
||||
code: d.merchantCode,
|
||||
address: d.address
|
||||
})
|
||||
}
|
||||
})
|
||||
app.merchantList.push(arr)
|
||||
})
|
||||
|
||||
},
|
||||
// 获取推荐人的店铺信息
|
||||
getDealerMerchant(dealerId){
|
||||
console.log("获取推荐人的店铺信息: ",'获取推荐人的店铺信息');
|
||||
const app = this
|
||||
MerchantApi.pageMerchant({userId: dealerId}).then(result => {
|
||||
console.log("result23123123123: ",result);
|
||||
if(result.data.count > 0){
|
||||
const data = result.data.list
|
||||
const merchantName = data[0].merchantName
|
||||
console.log("merchantName333333: ",merchantName);
|
||||
const area = `${data[0].province} ${data[0].city} ${data[0].region}`
|
||||
|
||||
var newObj = {
|
||||
...app.form
|
||||
}
|
||||
newObj.merchantName = merchantName
|
||||
newObj.area = area
|
||||
newObj.province = data[0].province
|
||||
newObj.city = data[0].city
|
||||
newObj.region = data[0].region
|
||||
newObj.merchantId = data[0].merchantId
|
||||
app.form = newObj
|
||||
|
||||
|
||||
// app.form = ...{area,merchantName}
|
||||
// app.area = region
|
||||
// app.merchantName = merchantName
|
||||
// app.form.merchantName = merchantName
|
||||
// app.form.province = data[0].province
|
||||
// app.form.city = data[0].city
|
||||
// app.form.region = data[0].region
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
onArea() {
|
||||
this.$refs.area.open()
|
||||
},
|
||||
onMerchant(){
|
||||
this.showMerchant = true
|
||||
},
|
||||
confirmMerchant(e){
|
||||
console.log("eeeeee2222: ",e);
|
||||
this.form.merchantId = e.value[0].id
|
||||
this.form.merchantCode = e.value[0].code
|
||||
this.form.merchantName = e.value[0].label
|
||||
this.form.address = e.value[0].address
|
||||
this.showMerchant = false
|
||||
},
|
||||
//地址选择成功
|
||||
chooseSuccess(e) {
|
||||
const app = this
|
||||
const data = e.value
|
||||
if(data){
|
||||
app.form.area = `${data[0].label} ${data[1].label} ${data[2].label}`
|
||||
app.form.province = data[0].label
|
||||
app.form.city = data[1].label
|
||||
app.form.region = data[2].label
|
||||
app.getMerchant()
|
||||
}
|
||||
},
|
||||
// 跳转到服务页面
|
||||
handleService({
|
||||
url
|
||||
}) {
|
||||
if (url.slice(0, 4) == 'http') {
|
||||
wx.openCustomerServiceChat({
|
||||
extInfo: {
|
||||
url: 'https://work.weixin.qq.com/kfid/kfc1693a8d29b84bc5e'
|
||||
},
|
||||
corpId: 'ww1c3f872ba0a39228',
|
||||
success(res) {}
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (!this.isLogin) {
|
||||
return false;
|
||||
}
|
||||
console.log("url: ", url);
|
||||
this.$navTo(url)
|
||||
},
|
||||
// 显示toast信息
|
||||
showToast(title, duration = 2000) {
|
||||
this.$refs.uToast.show({
|
||||
title,
|
||||
duration
|
||||
})
|
||||
},
|
||||
|
||||
handleLogout() {
|
||||
// http.setConfig((config) => {
|
||||
// config.header = {};
|
||||
// config.header = {
|
||||
// AppId: appId,
|
||||
// tenantId: tenantId
|
||||
// };
|
||||
// return config
|
||||
// })
|
||||
// uni.clearStorage()
|
||||
// uni.clearStorageSync()
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/index'
|
||||
})
|
||||
},
|
||||
onBuy() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
console.log("form: ",form);
|
||||
if(form.realName == ''){
|
||||
this.$error('请填写姓名')
|
||||
return false
|
||||
}
|
||||
if(form.phone == ''){
|
||||
this.$error('请填写手机号码')
|
||||
return false
|
||||
}
|
||||
if(form.area == ''){
|
||||
this.$error('请选择所属区域')
|
||||
return false
|
||||
}
|
||||
if(!form.merchantId){
|
||||
this.$error('请选择服务门店')
|
||||
return false
|
||||
}
|
||||
app.disabled = true
|
||||
|
||||
UserPlanLogApi.addUserPlanLog({
|
||||
planId: form.planId,
|
||||
priceId: form.priceId,
|
||||
province: form.province,
|
||||
city: form.province,
|
||||
region: form.region,
|
||||
area: form.area,
|
||||
realName: form.realName,
|
||||
phone: form.phone,
|
||||
merchantId: form.merchantId,
|
||||
merchantCode: form.merchantCode,
|
||||
merchantName: form.merchantName,
|
||||
address: form.address
|
||||
}).then(res => {
|
||||
|
||||
const orderInfo = res.data
|
||||
// 调起微信支付
|
||||
uni.requestPayment({
|
||||
provider: orderInfo.provider, // 服务提供商
|
||||
timeStamp: orderInfo.timeStamp, // 时间戳
|
||||
nonceStr: orderInfo.nonceStr, // 随机字符串
|
||||
package: orderInfo.package,
|
||||
signType: orderInfo.signType, // 签名算法
|
||||
paySign: orderInfo.paySign, // 签名
|
||||
success: function(res) {
|
||||
// 业务逻辑。。。
|
||||
app.$success('支付成功')
|
||||
setTimeout(function() {
|
||||
app.showEdit = false
|
||||
app.disabled = false
|
||||
app.$navTo('pages/order/index')
|
||||
}, 1500);
|
||||
},
|
||||
fail: function(err) {
|
||||
console.log('支付失败', err);
|
||||
app.disabled = false
|
||||
}
|
||||
});
|
||||
}).catch(err => {
|
||||
app.disabled = false
|
||||
})
|
||||
},
|
||||
|
||||
onApply() {
|
||||
if (!this.isLogin) {
|
||||
return false;
|
||||
}
|
||||
this.$navTo('pages/wallet/balance/log')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-index {
|
||||
background-color: #f3f3f3;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.page-bg {
|
||||
width: 750rpx;
|
||||
height: calc(100rpx + var(--status-bar-height));
|
||||
display: block;
|
||||
background-color: #101010;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -100;
|
||||
}
|
||||
|
||||
// 页面头部
|
||||
.main-header {
|
||||
// background-color: #FBF7EF;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
background-size: 100% 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.bg-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.star {
|
||||
position: absolute;
|
||||
opacity: 0.1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.star1 {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
right: 80rpx;
|
||||
top: 34rpx;
|
||||
}
|
||||
|
||||
.star2 {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
left: 40rpx;
|
||||
top: 10rpx;
|
||||
}
|
||||
|
||||
.star3 {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
left: 130rpx;
|
||||
top: 70rpx;
|
||||
}
|
||||
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
height: 120rpx;
|
||||
padding-left: 30rpx;
|
||||
z-index: 1;
|
||||
|
||||
.user-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin-left: 30rpx;
|
||||
color: #ffffff;
|
||||
|
||||
.nick-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
max-width: 270rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
image {
|
||||
margin-left: 10rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-id {
|
||||
font-weight: 300;
|
||||
color: #efefef;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.mobile {
|
||||
margin-top: 15rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.user-grade {
|
||||
align-self: baseline;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #3c3c3c;
|
||||
margin-top: 12rpx;
|
||||
border-radius: 10rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
|
||||
.user-grade_icon .image {
|
||||
display: block;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
|
||||
.user-grade_name {
|
||||
margin-left: 5rpx;
|
||||
font-size: 26rpx;
|
||||
color: #EEE0C3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.roles-box {
|
||||
display: flex;
|
||||
|
||||
.login-tips {
|
||||
margin-top: 12rpx;
|
||||
margin-right: 6rpx;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.switch {
|
||||
display: flex;
|
||||
color: #ffffff;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-right: 50rpx;
|
||||
z-index: 999;
|
||||
|
||||
image {
|
||||
width: 45rpx;
|
||||
height: 45rpx;
|
||||
}
|
||||
|
||||
.switch-text {
|
||||
z-index: 9999;
|
||||
color: #681752;
|
||||
}
|
||||
}
|
||||
|
||||
.setting {
|
||||
color: #cecece;
|
||||
position: absolute;
|
||||
right: 2vh;
|
||||
top: 1vh;
|
||||
|
||||
image {
|
||||
width: 45rpx;
|
||||
height: 45rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
position: fixed;
|
||||
top: 80rpx;
|
||||
left: 25rpx;
|
||||
z-index: 999;
|
||||
|
||||
// 开通会员
|
||||
.buy-user {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 22rpx auto 22rpx auto;
|
||||
padding: 22rpx 0;
|
||||
width: 700rpx;
|
||||
box-shadow: 0 1rpx 5rpx 0px #eaebec;
|
||||
border-radius: 24rpx;
|
||||
background: #fff;
|
||||
|
||||
.desc {
|
||||
padding-top: 5rpx;
|
||||
padding-left: 32rpx;
|
||||
font-size: 28rpx;
|
||||
color: #545454;
|
||||
}
|
||||
|
||||
.asset-right {
|
||||
width: 170rpx;
|
||||
border-left: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.asset-right-item {
|
||||
text-align: center;
|
||||
color: #545454;
|
||||
|
||||
.item-icon {
|
||||
font-size: 44rpx;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
margin-top: 14rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.asset-left-item {
|
||||
text-align: center;
|
||||
padding-left: 28rpx;
|
||||
display: flex;
|
||||
|
||||
.item-value {
|
||||
font-size: 34rpx;
|
||||
// color: #febd45;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
color: #545454;
|
||||
margin-top: 14rpx;
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
margin: 30rpx 25rpx 20rpx 0;
|
||||
}
|
||||
|
||||
.buy-user-icon {
|
||||
width: 40rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
.my-logout {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 50rpx;
|
||||
|
||||
.logout-btn {
|
||||
width: 400rpx;
|
||||
margin: 0 auto;
|
||||
font-size: 28rpx;
|
||||
color: #616161;
|
||||
border-radius: 20rpx;
|
||||
border: 1px solid #dcdcdc;
|
||||
padding: 16rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.price-box {
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
|
||||
image {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 280rpx;
|
||||
padding-left: 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.reb {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.num {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.xieyi {
|
||||
width: 600rpx;
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 50rpx auto;
|
||||
color: #999999;
|
||||
|
||||
text {
|
||||
color: #681752;
|
||||
}
|
||||
}
|
||||
|
||||
.cart {
|
||||
position: fixed;
|
||||
bottom: 25rpx;
|
||||
z-index: 888;
|
||||
width: 750rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
|
||||
.cart-info {
|
||||
background: linear-gradient(to bottom, $main-bg, $main-bg2);
|
||||
width: 700rpx;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
border-radius: 100rpx;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
|
||||
.cart-logo {
|
||||
position: absolute;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
margin-left: 20rpx;
|
||||
bottom: 10rpx;
|
||||
}
|
||||
|
||||
.total-price {
|
||||
padding-left: 30rpx;
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.clear-cart {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.buy {
|
||||
margin-right: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.custom-style {
|
||||
padding: 0 50rpx;
|
||||
color: #ffffff;
|
||||
background-color: #ff0000;
|
||||
// background: linear-gradient(to bottom, $main-bg, $main-bg2);
|
||||
// background-color: #8b004c;
|
||||
border: none;
|
||||
width: 330rpx;
|
||||
height: 66rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.w-input{
|
||||
width: 400rpx;
|
||||
text-align: right;
|
||||
font-size: 25rpx;
|
||||
color: #606266;
|
||||
}
|
||||
</style>
|
||||
276
pages/comment/index.vue
Executable file
276
pages/comment/index.vue
Executable file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption" @up="upCallback">
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabs" :is-scroll="false" :current="curTab" :active-color="appTheme.mainBg" :duration="0.2" @change="onChangeTab" />
|
||||
<!-- 商品评价列表 -->
|
||||
<view class="comment-list">
|
||||
<view class="comment-item" v-for="(item, index) in list.data" :key="index">
|
||||
<view class="item-head">
|
||||
<!-- 用户信息 -->
|
||||
<view class="user-info">
|
||||
<avatar-image class="user-avatar" :url="item.user.avatar_url" :width="50" />
|
||||
<text class="user-name f-26">{{ item.user.nick_name }}</text>
|
||||
</view>
|
||||
<!-- 评星 -->
|
||||
<u-rate active-color="#f4a213" :current="rates[item.score]" :disabled="true" />
|
||||
<!-- 评价日期-->
|
||||
<view class="flex-box f-22 col-9 t-r">{{ item.create_time }}</view>
|
||||
</view>
|
||||
<!-- 评价内容 -->
|
||||
<view class="item-content m-top20">
|
||||
<text class="f-26">{{ item.content }}</text>
|
||||
</view>
|
||||
<!-- 评价图片 -->
|
||||
<view class="images-list clearfix" v-if="item.images.length">
|
||||
<view class="image-preview" v-for="(image, imgIdx) in item.images" :key="imgIdx">
|
||||
<image class="image" mode="aspectFill" :src="image.image_url" @click="onPreviewImages(index, imgIdx)">
|
||||
</image>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品规格 -->
|
||||
<view class="goods-props clearfix">
|
||||
<view class="goods-props-item" v-for="(props, idx) in item.orderGoods.goods_props" :key="idx">
|
||||
<text class="group-name">{{ props.group.name }}: </text>
|
||||
<text>{{ props.value.name }};</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
// import * as CommentApi from '@/api/comment'
|
||||
|
||||
const pageSize = 15
|
||||
const tabs = [{
|
||||
name: `全部`,
|
||||
scoreType: -1
|
||||
}, {
|
||||
name: `好评`,
|
||||
scoreType: 10
|
||||
}, {
|
||||
name: `中评`,
|
||||
scoreType: 20
|
||||
}, {
|
||||
name: `差评`,
|
||||
scoreType: 30
|
||||
}]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
AvatarImage
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 当前商品ID
|
||||
goodsId: null,
|
||||
// 当前标签索引
|
||||
curTab: 0,
|
||||
// 评价列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
// 评价总数量
|
||||
total: { all: 0, negative: 0, praise: 0, review: 0 },
|
||||
// 评星数据转换
|
||||
rates: { 10: 5, 20: 3, 30: 1 },
|
||||
// 标签栏数据
|
||||
tabs,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于4条才显示无更多数据
|
||||
noMoreSize: 4,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无相关商品评价'
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 记录属性值
|
||||
this.goodsId = options.goodsId
|
||||
// 获取指定评分总数
|
||||
this.getTotal()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
// app.getCommentList(page.num)
|
||||
// .then(list => {
|
||||
// const curPageLen = list.data.length
|
||||
// const totalSize = list.data.total
|
||||
// app.mescroll.endBySize(curPageLen, totalSize)
|
||||
// })
|
||||
// .catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 加载评价列表数据
|
||||
getCommentList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
CommentApi.list(app.goodsId, { scoreType: app.getScoreType(), page: pageNo }, { load: false })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 评分类型
|
||||
getScoreType() {
|
||||
return this.tabs[this.curTab].scoreType
|
||||
},
|
||||
|
||||
// 获取指定评分总数
|
||||
getTotal() {
|
||||
const app = this
|
||||
CommentApi.total(app.goodsId)
|
||||
.then(result => {
|
||||
// tab标签内容
|
||||
const total = result.data.total
|
||||
app.getTabs(total)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取tab标签内容
|
||||
getTabs(total) {
|
||||
const tabs = this.tabs
|
||||
tabs[0].name = `全部(${total.all})`
|
||||
tabs[1].name = `好评(${total.praise})`
|
||||
tabs[2].name = `中评(${total.review})`
|
||||
tabs[3].name = `差评(${total.negative})`
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新评价列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新评价列表
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
},
|
||||
|
||||
// 预览评价图片
|
||||
onPreviewImages(dataIdx, imgIndex) {
|
||||
const app = this
|
||||
const images = app.list.data[dataIdx].images
|
||||
const imageUrls = images.map(item => item.image_url)
|
||||
uni.previewImage({
|
||||
current: imageUrls[imgIndex],
|
||||
urls: imageUrls
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.comment-item {
|
||||
padding: 30rpx;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1rpx solid #f7f7f7;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.item-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
// 用户信息
|
||||
.user-info {
|
||||
margin-right: 15rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.user-avatar {
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 评价内容
|
||||
.item-content {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
margin: 16rpx 0;
|
||||
}
|
||||
|
||||
// 评价图片
|
||||
.images-list {
|
||||
&::after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
float: left;
|
||||
margin-bottom: 15rpx;
|
||||
margin-right: 15rpx;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 商品规格
|
||||
.goods-props {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
|
||||
.goods-props-item {
|
||||
float: left;
|
||||
|
||||
.group-name {
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
29
pages/empty.vue
Executable file
29
pages/empty.vue
Executable file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
150
pages/flash/index.vue
Normal file
150
pages/flash/index.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<view class="page-wrap">
|
||||
<view class="main">
|
||||
<view class="logo">
|
||||
<image src="https://file.wsdns.cn/20230801/84480e0c65b044ebb869f8f2754bc0b1.png" mode="widthFix"></image>
|
||||
<!-- <image src="https://oss.jimeigroup.cn/static/flash-logo-text.png" mode="widthFix"></image> -->
|
||||
<!-- <text class="logo-name">
|
||||
爱尚家找房
|
||||
</text> -->
|
||||
</view>
|
||||
<view class="btn" @click="onLogin">
|
||||
<text>立即跳过({{ times }})</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage'
|
||||
import {
|
||||
ACCESS_TOKEN,
|
||||
USER_ID,
|
||||
USER_INFO
|
||||
} from '@/store/mutation-types'
|
||||
import {
|
||||
getToken
|
||||
} from '@/api/login.js'
|
||||
|
||||
// 倒计时时长(秒)
|
||||
const times = 5
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
times,
|
||||
smsState: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options = {}) {
|
||||
const refereeId = options.user_id
|
||||
if(refereeId){
|
||||
uni.setStorageSync('refereeId',refereeId)
|
||||
}
|
||||
this.checkLogin()
|
||||
this.timer()
|
||||
},
|
||||
onShow() {
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 执行定时器
|
||||
timer() {
|
||||
const app = this
|
||||
app.smsState = false
|
||||
const inter = setInterval(() => {
|
||||
app.times = app.times - 1
|
||||
if (app.times <= 0) {
|
||||
app.smsState = true
|
||||
app.times = 0
|
||||
app.onLogin()
|
||||
clearInterval(inter)
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
},
|
||||
checkLogin() {
|
||||
const token = storage.get(ACCESS_TOKEN)
|
||||
if (token) {
|
||||
this.$navTo('pages/index/index')
|
||||
}
|
||||
},
|
||||
// 1. 未登录则使用免密登录方式登录(游客身份)
|
||||
onLogin() {
|
||||
const token = storage.get(ACCESS_TOKEN)
|
||||
if (!token) {
|
||||
getToken().then(res => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
page{
|
||||
background-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page{
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(#47076b, #8d1a50);
|
||||
}
|
||||
.bg {
|
||||
width: 750rpx;
|
||||
height: 78vh;
|
||||
// background: url('https://oss.jimeigroup.cn/static/login-bg01.png');
|
||||
padding: 180rpx 0;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-top: 25vh;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 750rpx;
|
||||
height: 900rpx;
|
||||
z-index: 100;
|
||||
|
||||
.logo {
|
||||
width: 750rpx;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
image {
|
||||
width: 300rpx;
|
||||
}
|
||||
|
||||
.logo-name {
|
||||
color: #ffffff;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 230rpx;
|
||||
margin: auto;
|
||||
padding: 20rpx 40rpx;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
border-radius: 50rpx;
|
||||
background: linear-gradient(#27b0fd, #3f72f4);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
55
pages/help/xieyi.vue
Executable file
55
pages/help/xieyi.vue
Executable file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<view class="help">
|
||||
<block v-for="(item,index) in itemList" :key="index">
|
||||
<view class="content" slot="body">
|
||||
<u-parse :html="item.content"></u-parse>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageArticle } from '@/api/article.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 列表数据
|
||||
itemList: [{
|
||||
head: "关于我们",
|
||||
body: "",
|
||||
open: true,
|
||||
disabled: true
|
||||
}],
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
pageArticle({
|
||||
categoryId: 51
|
||||
}).then(res => {
|
||||
app.itemList = res.data.list
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.help {
|
||||
border-bottom: 1rpx solid #f6f6f9;
|
||||
width: 750rpx;
|
||||
margin: 0rpx auto;
|
||||
.content{
|
||||
padding: 20rpx 40rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
135
pages/home/home.vue
Normal file
135
pages/home/home.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<view class="index">
|
||||
<view class="header" :style="'margin-top: ' + listHeight + 'px'">
|
||||
<view class="pair">
|
||||
<view class="search" @click="$push('pages/search/index')">
|
||||
<image src="../../static/icon/search2.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<!-- <view class="pair-btn" @click="navTo('pages/pair/pair')">
|
||||
<u-button text="配对" size="small" color="linear-gradient(to bottom, #040004, #681752)"></u-button>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="menu">
|
||||
<u-tabs :list="menu" :current="currentTab" lineColor="#ff0077" :activeStyle="{
|
||||
color: '#ffffff',
|
||||
fontWeight: 'bold',
|
||||
transform: 'scale(1.05)'
|
||||
}" @click="tabChange">
|
||||
</u-tabs>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list" :style="'height:' + winheight + 'px;'">
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as UserProfileApi from '@/api/love-user-profile.js'
|
||||
const menu = [{
|
||||
name: '同城'
|
||||
},
|
||||
{
|
||||
name: '推荐'
|
||||
},
|
||||
{
|
||||
name: '关注'
|
||||
}
|
||||
];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
menu,
|
||||
currentTab: 1,
|
||||
where: {},
|
||||
windowHeight: 0 ,
|
||||
statusBarHeight: 0,
|
||||
listHeight: 0
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// 获取可用高度
|
||||
const sysInfo = uni.getSystemInfoSync()
|
||||
this.windowHeight = sysInfo.windowHeight
|
||||
this.statusBarHeight = sysInfo.statusBarHeight
|
||||
this.listHeight = sysInfo.windowHeight - sysInfo.statusBarHeight - 44
|
||||
this.queryList({
|
||||
page: 1,
|
||||
limit: 100
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
tabChange(index) {
|
||||
this.tabIndex = index;
|
||||
//当切换tab或搜索时请调用组件的reload方法,请勿直接调用:queryList方法!!
|
||||
this.$refs.paging.reload();
|
||||
},
|
||||
queryList(where) {
|
||||
UserProfileApi.pageUserProfile(where).then(res => {
|
||||
// this.
|
||||
}).catch(res => {
|
||||
this.$refs.paging.complete(false);
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #0f001f !important;
|
||||
}
|
||||
|
||||
.list{
|
||||
width: 750rpx;scroll-snap-type: y mandatory;overflow-x: hidden;overflow-y: auto;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
z-index: 9999;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
width: 750rpx;
|
||||
height: 88rpx;
|
||||
// background-color: #0f001f;
|
||||
|
||||
.pair {
|
||||
position: absolute;
|
||||
left: 30rpx;
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
display: flex;
|
||||
|
||||
.search {
|
||||
image {
|
||||
padding-top: 15rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.pair-btn {
|
||||
margin-left: 25rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
// font-size: 32rpx;
|
||||
// font-weight: 600;
|
||||
z-index: 9999;
|
||||
|
||||
.link {
|
||||
color: #cfd1d7;
|
||||
}
|
||||
|
||||
.curr {
|
||||
color: #ffffff;
|
||||
border-bottom: 5rpx solid #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
290
pages/house/house.vue
Normal file
290
pages/house/house.vue
Normal file
@@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 搜索 -->
|
||||
<view class="search-fix">
|
||||
<view class="search">
|
||||
<u-search placeholder="请输入搜索关键词" v-model="keyword" :actionStyle="actionStyle" :showAction="false"
|
||||
shape="square" bgColor="#ffffff" :animation="true"></u-search>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-tools">
|
||||
<view class="region">
|
||||
<uni-data-select class="select-width" v-model="where.region" :localdata="region" placeholder="区域"
|
||||
@change="onSearch"></uni-data-select>
|
||||
</view>
|
||||
<view class="region">
|
||||
<uni-data-select class="select-width" v-model="where.price" :localdata="price" placeholder="价格区间"
|
||||
@change="onSearch"></uni-data-select>
|
||||
</view>
|
||||
<view class="region">
|
||||
<uni-data-select class="select-width" v-model="where.extent" :localdata="extent" placeholder="面积"
|
||||
@change="onSearch"></uni-data-select>
|
||||
</view>
|
||||
<view class="region">
|
||||
<uni-data-select class="select-width" v-model="where.sort" :localdata="sort" placeholder="排序"
|
||||
@change="onSearch"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scrolltoupper="upper"
|
||||
@scrolltolower="lower" @scroll="onScroll">
|
||||
<view class="house-list">
|
||||
<block v-for="(item,index) in list" :key="index">
|
||||
<view class="item" @click="$push('sub_pages/house/detail?houseId=' + item.houseId)">
|
||||
<image :src="item.files[0].url" mode="widthFix">
|
||||
</image>
|
||||
<view class="info">
|
||||
<view class="title">{{ item.houseTitle }}</view>
|
||||
<view class="desc"><text>{{ item.extent }}m²|{{ item.toward }}</text></view>
|
||||
<view class="price">{{ item.rent }}元/月</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<u-empty mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png" v-if="list.length == 0">
|
||||
</u-empty>
|
||||
|
||||
<!-- <view class="item">
|
||||
<image src="https://file.wsdns.cn/20230802/8bf0658596ab458d94666cbf4b1177e9.jpg" mode="widthFix">
|
||||
</image>
|
||||
<view class="info">
|
||||
<view class="title">整租·万科云城 2室1厅1卫整租·万科云城 2室1厅1卫整租·万科云城 2室1厅1卫</view>
|
||||
<view class="desc"><text>50.8m²|南</text></view>
|
||||
<view class="price">6600元/月</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Util from '@/utils/util.js'
|
||||
import store from '@/store'
|
||||
import storage from '@/utils/storage'
|
||||
import * as HouseInfoApi from '@/api/house-info.js'
|
||||
|
||||
const menu = [{
|
||||
name: '推荐',
|
||||
reset: true
|
||||
},
|
||||
{
|
||||
name: '必看房源',
|
||||
reset: false
|
||||
}
|
||||
];
|
||||
const region = [{
|
||||
value: 0,
|
||||
text: "青秀区"
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
text: "兴宁区"
|
||||
}
|
||||
];
|
||||
const price = [{
|
||||
value: 0,
|
||||
text: "3000"
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
text: "4000"
|
||||
}
|
||||
];
|
||||
const extent = [{
|
||||
value: 0,
|
||||
text: "200平"
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
text: "300平"
|
||||
}
|
||||
];
|
||||
const sort = [{
|
||||
value: 0,
|
||||
text: "升序"
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
text: "降序"
|
||||
}
|
||||
];
|
||||
const loginUserId = uni.getStorageSync('userId')
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
loadMore: true,
|
||||
status: '加载更多',
|
||||
page: 1,
|
||||
where: {},
|
||||
// 控制onShow事件是否刷新订单列表
|
||||
canReset: false,
|
||||
disabled: false,
|
||||
swiperList: [
|
||||
'https://file.wsdns.cn/20230802/f33f5ac239c843438b36f40941d946ef.png',
|
||||
'https://file.wsdns.cn/20230802/1116a02b07904991b2ebdc2c3da4a691.png',
|
||||
],
|
||||
menu,
|
||||
region,
|
||||
price,
|
||||
extent,
|
||||
sort,
|
||||
scrollTop: 0,
|
||||
old: {
|
||||
scrollTop: 0
|
||||
},
|
||||
actionStyle: {
|
||||
background: '#3f72f4',
|
||||
color: '#ffffff',
|
||||
padding: '12rpx 0',
|
||||
borderRadius: '12rpx'
|
||||
},
|
||||
};
|
||||
|
||||
},
|
||||
onLoad() {
|
||||
this.list = []
|
||||
this.onRefreshList()
|
||||
},
|
||||
onShow() {},
|
||||
onBackPress() {},
|
||||
onUnload() {
|
||||
|
||||
},
|
||||
onPageScroll(e) {
|
||||
this.scrollTop = e.scrollTop
|
||||
},
|
||||
// 触底函数
|
||||
onReachBottom() {
|
||||
console.log("触底函数: ");
|
||||
const app = this
|
||||
if (app.loadMore) {
|
||||
app.page = ++app.page;
|
||||
app.onRefreshList()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onRefreshList() {
|
||||
const app = this
|
||||
const userId = uni.getStorageSync('userId')
|
||||
app.where.page = app.page
|
||||
return new Promise((resolve, reject) => {
|
||||
HouseInfoApi.pageHouseInfo(app.where)
|
||||
.then(result => {
|
||||
const list = result.data.list.map(d => {
|
||||
d.files = JSON.parse(d.files) || []
|
||||
return d
|
||||
})
|
||||
// 合并新数据
|
||||
app.list = app.list.concat(list)
|
||||
if (result.data.count > app.list.length) {
|
||||
app.canReset = true
|
||||
} else {
|
||||
app.canReset = false
|
||||
}
|
||||
console.log("app.list: ",app.list);
|
||||
resolve(list)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
.search-fix {
|
||||
width: 750rpx;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
|
||||
.search {
|
||||
width: 690rpx;
|
||||
margin: 15rpx auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.search-tools {
|
||||
width: 700rpx;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
.region {
|
||||
width: 170rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 300rpx;
|
||||
left: 125rpx;
|
||||
}
|
||||
|
||||
.no-fixed {
|
||||
position: absolute;
|
||||
top: 0rpx;
|
||||
left: 125rpx;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
margin-top: 50rpx;
|
||||
}
|
||||
|
||||
.house-list {
|
||||
width: 700rpx;
|
||||
margin: 20rpx auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
margin-bottom: 40rpx;
|
||||
border-radius: 20rpx;
|
||||
// box-shadow: 0 3rpx 10rpx 0px #cccccc;
|
||||
background-color: #ffffff;
|
||||
width: 338rpx;
|
||||
|
||||
image {
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
height: 420rpx;
|
||||
width: 338rpx;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 20rpx 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden; //溢出内容隐藏
|
||||
text-overflow: ellipsis; //文本溢出部分用省略号表示
|
||||
display: -webkit-box; //特别显示模式
|
||||
-webkit-line-clamp: 2; //行数
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical; //盒子中内容竖直排列
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #999999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: #ff0000;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
231
pages/index/index.vue
Normal file
231
pages/index/index.vue
Normal file
@@ -0,0 +1,231 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 搜索 -->
|
||||
<u-sticky offset-top="5" zIndex="999">
|
||||
<view class="search-fix fixed" v-if="scrollTop < 30">
|
||||
<view class="search">
|
||||
<view class="region">青秀区</view>
|
||||
<view class="input">
|
||||
<u-search placeholder="您想找哪里" bgColor="#ffffff" v-model="keyword" :animation="true"></u-search>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-fix" v-else>
|
||||
<view class="search">
|
||||
<view class="region">青秀区</view>
|
||||
<view class="input">
|
||||
<u-search placeholder="您想找哪里" bgColor="#ffffff" v-model="keyword" :animation="true"></u-search>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-sticky>
|
||||
<!-- 幻灯片 -->
|
||||
<view class="swiper">
|
||||
<u-swiper :list="swiperList" :height="180" :radius="0" @change="change" @click="click"></u-swiper>
|
||||
</view>
|
||||
<!-- 选项卡 -->
|
||||
<view class="tabs">
|
||||
<u-tabs :list="menu" @click="click"></u-tabs>
|
||||
</view>
|
||||
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scrolltoupper="upper"
|
||||
@scrolltolower="lower" @scroll="onScroll">
|
||||
<view class="house-list" v-if="list.length > 0">
|
||||
<block v-for="(item,index) in list" :key="index">
|
||||
<view class="item" @click="$push('sub_pages/house/detail?houseId=' + item.houseId)">
|
||||
<image :src="item.files[0].url" mode="widthFix">
|
||||
</image>
|
||||
<view class="info">
|
||||
<view class="title">{{ item.houseTitle }}</view>
|
||||
<view class="desc"><text>{{ item.extent }}m²|{{ item.toward }}</text></view>
|
||||
<view class="price">{{ item.rent }}元/月</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<u-empty mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png" v-if="list.length == 0">
|
||||
</u-empty>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Util from '@/utils/util.js'
|
||||
import store from '@/store'
|
||||
import storage from '@/utils/storage'
|
||||
import * as HouseInfoApi from '@/api/house-info.js'
|
||||
|
||||
const menu = [{
|
||||
name: '推荐',
|
||||
reset: true
|
||||
},
|
||||
{
|
||||
name: '必看房源',
|
||||
reset: false
|
||||
}
|
||||
];
|
||||
const loginUserId = uni.getStorageSync('userId')
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
loadMore: true,
|
||||
status: '加载更多',
|
||||
page: 1,
|
||||
where: {},
|
||||
// 控制onShow事件是否刷新订单列表
|
||||
canReset: false,
|
||||
disabled: false,
|
||||
swiperList: [
|
||||
'https://file.wsdns.cn/20230802/f33f5ac239c843438b36f40941d946ef.png',
|
||||
'https://file.wsdns.cn/20230802/1116a02b07904991b2ebdc2c3da4a691.png',
|
||||
],
|
||||
menu,
|
||||
scrollTop: 0,
|
||||
old: {
|
||||
scrollTop: 0
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
onLoad() {
|
||||
this.list = []
|
||||
this.onRefreshList()
|
||||
},
|
||||
onShow() {},
|
||||
onBackPress() {},
|
||||
onUnload() {
|
||||
|
||||
},
|
||||
onPageScroll(e) {
|
||||
this.scrollTop = e.scrollTop
|
||||
},
|
||||
// 触底函数
|
||||
onReachBottom() {
|
||||
console.log("触底函数: ");
|
||||
const app = this
|
||||
if (app.loadMore) {
|
||||
app.page = ++app.page;
|
||||
app.onRefreshList()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onRefreshList() {
|
||||
const app = this
|
||||
const userId = uni.getStorageSync('userId')
|
||||
app.where.page = app.page
|
||||
return new Promise((resolve, reject) => {
|
||||
HouseInfoApi.pageHouseInfo(app.where)
|
||||
.then(result => {
|
||||
const list = result.data.list.map(d => {
|
||||
d.files = JSON.parse(d.files) || []
|
||||
return d
|
||||
})
|
||||
// 合并新数据
|
||||
app.list = app.list.concat(list)
|
||||
if (result.data.count > app.list.length) {
|
||||
app.canReset = true
|
||||
} else {
|
||||
app.canReset = false
|
||||
}
|
||||
resolve(list)
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
.search-fix {
|
||||
width: 500rpx;
|
||||
margin: auto;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
border-radius: 100rpx;
|
||||
box-shadow: 0 3rpx 10rpx 0px #cccccc;
|
||||
|
||||
.search {
|
||||
width: 400rpx;
|
||||
margin: 15rpx auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.region {
|
||||
width: 170rpx;
|
||||
color: #666666;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 300rpx;
|
||||
left: 125rpx;
|
||||
}
|
||||
|
||||
.no-fixed {
|
||||
position: absolute;
|
||||
top: 0rpx;
|
||||
left: 125rpx;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
margin-top: 80rpx;
|
||||
}
|
||||
|
||||
.house-list {
|
||||
width: 700rpx;
|
||||
margin: 20rpx auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
margin-bottom: 40rpx;
|
||||
border-radius: 20rpx;
|
||||
// box-shadow: 0 3rpx 10rpx 0px #cccccc;
|
||||
background-color: #ffffff;
|
||||
width: 338rpx;
|
||||
|
||||
image {
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
height: 420rpx;
|
||||
width: 338rpx;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 20rpx 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden; //溢出内容隐藏
|
||||
text-overflow: ellipsis; //文本溢出部分用省略号表示
|
||||
display: -webkit-box; //特别显示模式
|
||||
-webkit-line-clamp: 2; //行数
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical; //盒子中内容竖直排列
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #999999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: #ff0000;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
456
pages/login/components/main.vue
Executable file
456
pages/login/components/main.vue
Executable file
@@ -0,0 +1,456 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
|
||||
<!-- 页面头部 -->
|
||||
<view class="header">
|
||||
<!-- <view class="title">
|
||||
<text>账号登录</text>
|
||||
</view> -->
|
||||
<view class="logo">
|
||||
<image src="https://file.wsdns.cn/20230801/84480e0c65b044ebb869f8f2754bc0b1.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<!-- <view class="sub-title">
|
||||
<text>未注册的手机号登录后将自动注册</text>
|
||||
</view> -->
|
||||
</view>
|
||||
<!-- 表单 -->
|
||||
<!-- #ifdef H5 -->
|
||||
<view class="login-form">
|
||||
<!-- 手机号 -->
|
||||
<view class="form-item">
|
||||
<input class="form-item--input" type="text" v-model="mobile" maxlength="20"
|
||||
placeholder="请输入登录账号|手机号码|邮箱" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<input class="form-item--input" type="password" v-model="password" maxlength="30"
|
||||
placeholder="请输入登录密码" />
|
||||
|
||||
</view>
|
||||
<!-- 图形验证码 -->
|
||||
<view class="form-item" style="display: none;">
|
||||
<input class="form-item--input" type="text" v-model="captchaCode" maxlength="5"
|
||||
placeholder="请输入图形验证码" />
|
||||
<view class="form-item--parts">
|
||||
<view class="captcha" @click="getCaptcha()">
|
||||
<image class="image" :src="captcha.base64"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 短信验证码 -->
|
||||
<view class="form-item" style="display: none;">
|
||||
<input class="form-item--input" type="number" v-model="smsCode" maxlength="6" placeholder="请输入短信验证码" />
|
||||
<view class="form-item--parts">
|
||||
<view class="captcha-sms" @click="handelSmsCaptcha()">
|
||||
<text v-if="!smsState" class="activate">获取验证码</text>
|
||||
<text v-else class="un-activate">重新发送({{ times }})秒</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 登录按钮 -->
|
||||
<view class="login-button" @click="handleLogin">
|
||||
<text>立即登录 找对象</text>
|
||||
</view>
|
||||
<view class="agree">
|
||||
<view class="item">
|
||||
<radio value="index" :checked="disabled" @click="onRadio" />已阅读并同意以下协议
|
||||
<view class="xieyi" @click="$push('pages/article/detail/detail?id=114')">《服务协议》</view>
|
||||
<view class="xieyi" @click="$push('pages/article/detail/detail?id=115')">《隐私政策》</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业微信授权登录 -->
|
||||
<!-- <view class="login-button-ww" @click="onWWLogin">
|
||||
<image src="@/static/login-wx-work.png"></image>
|
||||
</view> -->
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 微信授权手机号一键登录 -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<MpWeixinMobile :isParty="isParty" :partyData="partyData" />
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- <div id="ww_login" style="width: 100%; height: 100%"></div> -->
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store'
|
||||
import storage from '@/utils/storage'
|
||||
import {
|
||||
ACCESS_TOKEN,
|
||||
USER_ID,
|
||||
} from '@/store/mutation-types'
|
||||
import {
|
||||
appId,
|
||||
tenantId
|
||||
} from '@/config.js'
|
||||
import {
|
||||
getCaptcha,
|
||||
login,
|
||||
sendSmsCaptcha
|
||||
} from '@/api/login.js'
|
||||
import * as Verify from '@/utils/verify'
|
||||
import http from '@/api'
|
||||
import MpWeixinMobile from './mp-weixin-mobile'
|
||||
|
||||
// 倒计时时长(秒)
|
||||
const times = 60
|
||||
|
||||
// 表单验证场景
|
||||
const GET_CAPTCHA = 10
|
||||
const SUBMIT_LOGIN = 20
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MpWeixinMobile
|
||||
},
|
||||
|
||||
props: {
|
||||
// 是否存在第三方用户信息
|
||||
isParty: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
// 第三方用户信息数据
|
||||
partyData: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: false,
|
||||
// 图形验证码信息
|
||||
captcha: {},
|
||||
// 短信验证码发送状态
|
||||
smsState: false,
|
||||
// 倒计时
|
||||
times,
|
||||
// 手机号
|
||||
mobile: '',
|
||||
password: '',
|
||||
// 图形验证码
|
||||
captchaCode: '',
|
||||
// 短信验证码
|
||||
smsCode: '',
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
created() {
|
||||
// 获取图形验证码
|
||||
this.getCaptcha()
|
||||
},
|
||||
|
||||
methods: {
|
||||
openXieyi(url){
|
||||
console.log("url: ",url);
|
||||
this.$navTo(url)
|
||||
},
|
||||
// 获取图形验证码
|
||||
getCaptcha() {
|
||||
const app = this
|
||||
getCaptcha()
|
||||
.then(result => app.captcha = result.data)
|
||||
},
|
||||
|
||||
// 点击发送短信验证码
|
||||
handelSmsCaptcha() {
|
||||
const app = this
|
||||
if (!app.isLoading && !app.smsState && app.formValidation(GET_CAPTCHA)) {
|
||||
app.sendSmsCaptcha()
|
||||
}
|
||||
},
|
||||
|
||||
// 表单验证
|
||||
formValidation(scene = GET_CAPTCHA) {
|
||||
const app = this
|
||||
// 验证获取短信验证码
|
||||
if (scene === GET_CAPTCHA) {
|
||||
if (!app.validteMobile(app.mobile) || !app.validteCaptchaCode(app.captchaCode)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 验证提交登录
|
||||
if (scene === SUBMIT_LOGIN) {
|
||||
if (!app.validteMobile(app.mobile) || !app.validteSmsCode(app.smsCode)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
// 验证手机号
|
||||
validteMobile(str) {
|
||||
if (Verify.isEmpty(str)) {
|
||||
this.$toast('请先输入手机号')
|
||||
return false
|
||||
}
|
||||
if (!Verify.isMobile(str)) {
|
||||
// this.$toast('请输入正确格式的手机号')
|
||||
// return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
// 验证图形验证码
|
||||
validteCaptchaCode(str) {
|
||||
if (Verify.isEmpty(str)) {
|
||||
this.$toast('请先输入图形验证码')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
// 验证短信验证码
|
||||
validteSmsCode(str) {
|
||||
if (Verify.isEmpty(str)) {
|
||||
// this.$toast('请先输入短信验证码')
|
||||
// return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
onRadio(){
|
||||
this.disabled = !this.disabled
|
||||
},
|
||||
|
||||
// 请求发送短信验证码接口
|
||||
sendSmsCaptcha() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
sendSmsCaptcha({
|
||||
phone: app.mobile
|
||||
})
|
||||
.then(result => {
|
||||
// 显示发送成功
|
||||
app.$toast(result.message)
|
||||
// 执行定时器
|
||||
app.timer()
|
||||
})
|
||||
.catch(() => app.getCaptcha())
|
||||
.finally(() => app.isLoading = false)
|
||||
|
||||
},
|
||||
|
||||
// 执行定时器
|
||||
timer() {
|
||||
const app = this
|
||||
app.smsState = true
|
||||
const inter = setInterval(() => {
|
||||
app.times = app.times - 1
|
||||
if (app.times <= 0) {
|
||||
app.smsState = false
|
||||
app.times = times
|
||||
clearInterval(inter)
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
|
||||
// 点击登录
|
||||
handleLogin() {
|
||||
const app = this
|
||||
if (!app.isLoading && app.formValidation(SUBMIT_LOGIN)) {
|
||||
app.submitLogin()
|
||||
}
|
||||
},
|
||||
|
||||
// 确认登录
|
||||
submitLogin() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
console.log("登录: ", '登录');
|
||||
store.dispatch('Login', {
|
||||
username: app.mobile,
|
||||
password: app.password
|
||||
})
|
||||
.then(result => {
|
||||
// 一键登录成功
|
||||
app.$toast(result.message)
|
||||
// 跳转回原页面
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
complete(res) {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}, 1000)
|
||||
// // 显示登录成功
|
||||
// app.$toast(result.message)
|
||||
// // 跳转回原页面
|
||||
// uni.redirectTo({
|
||||
// url: 'pages/user/user'
|
||||
// })
|
||||
// setTimeout(() => {
|
||||
// app.onNavigateBack(1)
|
||||
// }, 2000)
|
||||
})
|
||||
.catch(err => {
|
||||
// 跳转回原页面
|
||||
if (err.result.data.isBack) {
|
||||
setTimeout(() => app.onNavigateBack(1), 2000)
|
||||
}
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
/**
|
||||
* 登录成功-跳转回原页面
|
||||
*/
|
||||
onNavigateBack(delta = 1) {
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 1) {
|
||||
uni.navigateBack({
|
||||
delta: Number(delta || 1)
|
||||
})
|
||||
} else {
|
||||
this.$navTo('pages/index/index')
|
||||
}
|
||||
},
|
||||
|
||||
onWWLogin() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 页面头部
|
||||
.header {
|
||||
margin-bottom: 5rpx;
|
||||
|
||||
.title {
|
||||
color: #191919;
|
||||
font-size: 54rpx;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
margin-top: 20rpx;
|
||||
color: #b3b3b3;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 输入框元素
|
||||
.form-item {
|
||||
display: flex;
|
||||
padding: 18rpx;
|
||||
border-bottom: 1rpx solid #f3f1f2;
|
||||
margin-bottom: 30rpx;
|
||||
height: 96rpx;
|
||||
|
||||
&--input {
|
||||
font-size: 28rpx;
|
||||
letter-spacing: 1rpx;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&--parts {
|
||||
min-width: 100rpx;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// 图形验证码
|
||||
.captcha {
|
||||
height: 100%;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 192rpx;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 短信验证码
|
||||
.captcha-sms {
|
||||
font-size: 28rpx;
|
||||
line-height: 50rpx;
|
||||
padding-right: 20rpx;
|
||||
|
||||
.activate {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
.un-activate {
|
||||
color: #9e9e9e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 20rpx;
|
||||
margin: auto;
|
||||
image {
|
||||
width: 180rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 登录按钮
|
||||
.login-button {
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
margin-top: 80rpx;
|
||||
background: linear-gradient(#ff0077, #4d0d68);
|
||||
// background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
|
||||
color: $main-text;
|
||||
border-radius: 80rpx;
|
||||
box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.1);
|
||||
letter-spacing: 5rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.login-button-ww {
|
||||
margin-top: 80rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
image {
|
||||
height: 96rpx;
|
||||
}
|
||||
}
|
||||
.agree{
|
||||
text-align: center;
|
||||
width: 750rpx;
|
||||
color: rgba(75,13,99,1);
|
||||
.item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
image{
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.xieyi{
|
||||
text-decoration:underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
312
pages/login/components/mp-weixin-mobile.vue
Executable file
312
pages/login/components/mp-weixin-mobile.vue
Executable file
@@ -0,0 +1,312 @@
|
||||
<template>
|
||||
<view class="weixin-login">
|
||||
<!-- 微信授权手机号一键登录 -->
|
||||
<view class="wechat-auth agree">
|
||||
<button class="btn-normal" v-if="!disabled" @click="onAgree">
|
||||
<view class="wechat-auth-container">
|
||||
<!-- <image class="icon" src="../../../static/channel/wechat.png"></image> -->
|
||||
<text class="title">手机号快捷登录</text>
|
||||
</view>
|
||||
</button>
|
||||
<button v-else class="btn-normal" open-type="getPhoneNumber"
|
||||
@getphonenumber="handelMpWeixinMobileLogin($event)" @click="clickPhoneNumber">
|
||||
<view class="wechat-auth-container">
|
||||
<!-- <image class="icon" src="../../../static/channel/wechat.png"></image> -->
|
||||
<text class="title">手机号快捷登录</text>
|
||||
</view>
|
||||
</button>
|
||||
</view>
|
||||
<view class="agree-text" @click="onRadio">
|
||||
<view class="item">
|
||||
<!-- <image src="../../../static/icon/g.svg"></image> -->
|
||||
<label>
|
||||
<radio value="index" :checked="disabled" />已阅读并同意
|
||||
</label>
|
||||
<view class="xieyi" @click.stop="$push('pages/article/detail/detail?id=114')">《服务协议》</view>
|
||||
<view class="xieyi" @click.stop="$push('pages/article/detail/detail?id=115')">《隐私政策》</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-popup :show="showAgree" mode="center" :round="10" :closeable="true" @close="showAgree = false">
|
||||
<view class="offline">
|
||||
<view class="head">
|
||||
<view class="info">
|
||||
<text class="title">请阅读并同意《用户协议》《隐私政策》</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store'
|
||||
import storage from '@/utils/storage'
|
||||
import {
|
||||
isEmpty,
|
||||
inArray
|
||||
} from '@/utils/util'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 是否存在第三方用户信息
|
||||
isParty: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
// 第三方用户信息数据
|
||||
partyData: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 微信小程序登录凭证 (code)
|
||||
// 提交到后端,用于换取openid
|
||||
code: '',
|
||||
disabled: false,
|
||||
showAgree: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 按钮点击事件: 获取微信手机号按钮
|
||||
// 实现目的: 在getphonenumber事件触发之前获取微信登录code
|
||||
// 因为如果在getphonenumber事件中获取code的话,提交到后端的encryptedData会存在解密不了的情况
|
||||
async clickPhoneNumber() {
|
||||
this.code = await this.getCode()
|
||||
},
|
||||
|
||||
// 微信授权获取手机号一键登录
|
||||
// getphonenumber事件的回调方法
|
||||
async handelMpWeixinMobileLogin(e) {
|
||||
const {
|
||||
detail
|
||||
} = e;
|
||||
const app = this
|
||||
if (detail.errMsg != 'getPhoneNumber:ok') {
|
||||
console.log('微信授权获取手机号失败', detail.errMsg)
|
||||
// app.$error(detail.errMsg)
|
||||
return
|
||||
}
|
||||
if (detail.errMsg == 'getPhoneNumber:ok') {
|
||||
app.isLoading = true
|
||||
store.dispatch('LoginMpWxMobile', {
|
||||
code: detail.code,
|
||||
encryptedData: detail.encryptedData,
|
||||
iv: detail.iv,
|
||||
isParty: app.isParty,
|
||||
partyData: app.partyData,
|
||||
refereeId: Number(storage.get('refereeId'))
|
||||
})
|
||||
.then(result => {
|
||||
console.log("result: ", result);
|
||||
// 显示登录成功
|
||||
app.$toast(result.message)
|
||||
// 跳转回原页面
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
complete(res) {
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}, 1000)
|
||||
})
|
||||
.catch(err => {
|
||||
console.log("err: ", err);
|
||||
// const resultData = err.result.data
|
||||
// 显示错误信息
|
||||
app.$error(err.message)
|
||||
// if (isEmpty(resultData)) {
|
||||
// app.$toast(err.result.message)
|
||||
// }
|
||||
// 跳转回原页面
|
||||
// if (resultData.isBack) {
|
||||
// setTimeout(() => app.onNavigateBack(1), 2000)
|
||||
// }
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
}
|
||||
},
|
||||
|
||||
onRadio() {
|
||||
this.disabled = !this.disabled
|
||||
},
|
||||
|
||||
// 获取微信登录的code
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
|
||||
getCode() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: res => {
|
||||
console.log('code', res.code)
|
||||
resolve(res.code)
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
iAgree() {
|
||||
this.disabled = !this.disabled
|
||||
this.showAgree = false
|
||||
},
|
||||
|
||||
onAgree() {
|
||||
this.$error('请阅读并同意(勾选)《用户协议》《隐私政策》')
|
||||
},
|
||||
|
||||
/**
|
||||
* 登录成功-跳转回原页面
|
||||
*/
|
||||
onNavigateBack(delta = 1) {
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 1) {
|
||||
uni.navigateBack({
|
||||
delta: Number(delta || 1)
|
||||
})
|
||||
} else {
|
||||
this.$navTo('pages/index/index')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.agree {
|
||||
background: linear-gradient(#27b0fd, #3f72f4);
|
||||
// background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
|
||||
}
|
||||
|
||||
// 微信授权登录
|
||||
.wechat-auth {
|
||||
width: 600rpx;
|
||||
height: 86rpx;
|
||||
margin: 100rpx auto 50rpx auto;
|
||||
color: $main-text;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.1);
|
||||
letter-spacing: 5rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.btn-normal {
|
||||
width: 580rpx;
|
||||
}
|
||||
|
||||
.btn-normal-no {
|
||||
width: 580rpx;
|
||||
}
|
||||
|
||||
button {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.wechat-auth-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $main-text;
|
||||
background: none !important;
|
||||
|
||||
.title {
|
||||
color: #f3f3f3;
|
||||
}
|
||||
}
|
||||
|
||||
// 登录按钮
|
||||
.login-button {
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
margin-top: 80rpx;
|
||||
background: linear-gradient(#ff0077, #4d0d68);
|
||||
// background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
|
||||
color: $main-text;
|
||||
border-radius: 80rpx;
|
||||
box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.1);
|
||||
letter-spacing: 5rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.offline {
|
||||
border-radius: 20rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 120rpx;
|
||||
line-height: 120rpx;
|
||||
padding: 30rpx;
|
||||
|
||||
.head {
|
||||
padding-top: 10rpx;
|
||||
width: 600rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
padding-top: 8rpx;
|
||||
padding-left: 40rpx;
|
||||
color: #3f72f4;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #3f72f4;
|
||||
display: flex;
|
||||
font-size: 26rpx;
|
||||
line-height: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.agree-text {
|
||||
text-align: center;
|
||||
width: 750rpx;
|
||||
font-size: 26rpx;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
image {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.xieyi {
|
||||
color: #3f72f4;
|
||||
// text-decoration:underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
243
pages/login/components/mp-weixin.vue
Executable file
243
pages/login/components/mp-weixin.vue
Executable file
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="wechatapp">
|
||||
<view class="header">
|
||||
<!-- <open-data class="avatar" type="userAvatarUrl"></open-data> -->
|
||||
<image class="image"
|
||||
:src="storeInfo && storeInfo.image_url ? storeInfo.image_url : '/static/default-avatar.png'"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="auth-title">申请获取以下权限</view>
|
||||
<view class="auth-subtitle">获得你的公开信息(昵称、头像等)</view>
|
||||
<view class="login-btn">
|
||||
<!-- 获取微信用户信息 -->
|
||||
<button class="button btn-normal" @click.stop="getUserProfile">授权登录</button>
|
||||
</view>
|
||||
<view class="no-login-btn">
|
||||
<button class="button btn-normal" @click="handleCancel">暂不登录</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store'
|
||||
import { isEmpty } from '@/utils/util'
|
||||
import SettingModel from '@/common/model/Setting'
|
||||
|
||||
export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 商城基本信息
|
||||
storeInfo: undefined,
|
||||
// 微信小程序登录凭证 (code)
|
||||
// 提交到后端,用于换取openid
|
||||
code: ''
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 获取商城基本信息
|
||||
this.getStoreInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取商城基本信息
|
||||
getStoreInfo() {
|
||||
SettingModel.item('store').then(store => this.storeInfo = store)
|
||||
|
||||
// SettingModel.h5Url(true)
|
||||
},
|
||||
|
||||
// 获取code
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
|
||||
getCode() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: res => {
|
||||
console.log('code', res.code)
|
||||
resolve(res.code)
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取微信用户信息(新版)
|
||||
getUserProfile() {
|
||||
const app = this
|
||||
wx.canIUse('getUserProfile') && wx.getUserProfile({
|
||||
lang: 'zh_CN',
|
||||
desc: '获取用户相关信息',
|
||||
success({ userInfo }) {
|
||||
console.log('用户同意了授权')
|
||||
console.log('userInfo:', userInfo)
|
||||
// 授权成功事件
|
||||
app.onAuthSuccess(userInfo)
|
||||
},
|
||||
fail() {
|
||||
console.log('用户拒绝了授权')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 授权成功事件
|
||||
// 这里分为两个逻辑:
|
||||
// 1.将code和userInfo提交到后端,如果存在该用户 则实现自动登录,无需再填写手机号
|
||||
// 2.如果不存在该用户, 则显示注册页面, 需填写手机号
|
||||
// 3.如果后端报错了, 则显示错误信息
|
||||
async onAuthSuccess(userInfo) {
|
||||
const app = this
|
||||
// 提交到后端
|
||||
store.dispatch('LoginMpWx', {
|
||||
partyData: {
|
||||
code: await app.getCode(),
|
||||
oauth: 'MP-WEIXIN',
|
||||
userInfo
|
||||
},
|
||||
refereeId: store.getters.refereeId
|
||||
})
|
||||
.then(result => {
|
||||
// 一键登录成功
|
||||
app.$toast(result.message)
|
||||
// 跳转回原页面
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: 'pages/index/index'
|
||||
})
|
||||
}, 1000)
|
||||
// setTimeout(() => {
|
||||
// app.$navTo('pages/user/user')
|
||||
// }, 2000)
|
||||
})
|
||||
.catch(err => {
|
||||
const resultData = err.result.data
|
||||
// 显示错误信息
|
||||
if (isEmpty(resultData)) {
|
||||
app.$toast(err.result.message)
|
||||
}
|
||||
// 跳转回原页面
|
||||
if (resultData.isBack) {
|
||||
setTimeout(() => app.onNavigateBack(1), 2000)
|
||||
}
|
||||
// 判断还需绑定手机号
|
||||
if (resultData.isBindMobile) {
|
||||
app.onEmitSuccess(userInfo)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 将oauth提交给父级
|
||||
// 这里要重新获取code, 因为上一次获取的code不能复用(会报错)
|
||||
async onEmitSuccess(userInfo) {
|
||||
const app = this
|
||||
app.$emit('success', {
|
||||
oauth: 'MP-WEIXIN', // 第三方登录类型: MP-WEIXIN
|
||||
code: await app.getCode(), // 微信登录的code, 用于换取openid
|
||||
userInfo // 微信用户信息
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 暂不登录
|
||||
*/
|
||||
handleCancel() {
|
||||
// 跳转回原页面
|
||||
this.onNavigateBack()
|
||||
},
|
||||
|
||||
/**
|
||||
* 登录成功-跳转回原页面
|
||||
*/
|
||||
onNavigateBack(delta = 1) {
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 1) {
|
||||
uni.navigateBack({
|
||||
delta: Number(delta || 1)
|
||||
})
|
||||
} else {
|
||||
this.$navTo('pages/index/index')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 0 60rpx;
|
||||
font-size: 32rpx;
|
||||
background: #fff;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.wechatapp {
|
||||
padding: 80rpx 0 48rpx;
|
||||
border-bottom: 1rpx solid #e3e3e3;
|
||||
margin-bottom: 72rpx;
|
||||
text-align: center;
|
||||
|
||||
.header {
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
border: 4rpx solid #fff;
|
||||
margin: 0 auto 0;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
box-shadow: 2rpx 0 10rpx rgba(50, 50, 50, 0.3);
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-title {
|
||||
color: #585858;
|
||||
font-size: 34rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.auth-subtitle {
|
||||
color: #888;
|
||||
margin-bottom: 88rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
padding: 0 20rpx;
|
||||
|
||||
.button {
|
||||
height: 88rpx;
|
||||
background: #04be01;
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
border-radius: 999rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.no-login-btn {
|
||||
margin-top: 20rpx;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.button {
|
||||
height: 88rpx;
|
||||
background: #dfdfdf;
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
border-radius: 999rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
124
pages/login/components/wx-official.vue
Executable file
124
pages/login/components/wx-official.vue
Executable file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<!-- 跳转到微信授权地址 -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import queryStringify from '@/js_sdk/queryStringify'
|
||||
import store from '@/store'
|
||||
import { isEmpty, urlEncode } from '@/utils/util'
|
||||
import * as Api from '@/api/wxofficial'
|
||||
|
||||
export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 页面来源是否为微信回调
|
||||
isCallback: false
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 处理微信回调
|
||||
this.onCallback()
|
||||
// 跳转到微信授权
|
||||
this.redirectUrl()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 处理微信回调
|
||||
onCallback() {
|
||||
// 接收微信传来的参数
|
||||
const wxParam = queryStringify.parse(window.location.search)
|
||||
if (!isEmpty(wxParam)) {
|
||||
const url = window.location.href.replace(window.location.search, '')
|
||||
window.location.href = url + '?' + urlEncode(wxParam)
|
||||
return
|
||||
}
|
||||
// 获取code参数
|
||||
const query = this.$route.query
|
||||
if (isEmpty(query) || !query.code) {
|
||||
return
|
||||
}
|
||||
// 请求后端获取微信用户信息
|
||||
this.isCallback = true
|
||||
Api.oauthUserInfo(query.code)
|
||||
.then(({ data }) => {
|
||||
console.log('用户同意了授权')
|
||||
console.log('userInfo:', data)
|
||||
// 授权成功事件
|
||||
this.onAuthSuccess(data)
|
||||
})
|
||||
},
|
||||
|
||||
// 授权成功事件
|
||||
// 这里分为两个逻辑:
|
||||
// 1.将openid和userInfo提交到后端,如果存在该用户 则实现自动登录,无需再填写手机号
|
||||
// 2.如果不存在该用户, 则显示注册页面, 需填写手机号
|
||||
// 3.如果后端报错了, 则显示错误信息
|
||||
async onAuthSuccess({ userInfo, encryptedData, iv }) {
|
||||
const app = this
|
||||
// 提交到后端
|
||||
store.dispatch('LoginWxOfficial', {
|
||||
partyData: { oauth: 'H5-WEIXIN', userInfo, encryptedData, iv },
|
||||
refereeId: store.getters.refereeId
|
||||
})
|
||||
.then(result => {
|
||||
// 一键登录成功
|
||||
app.$toast(result.message)
|
||||
// 跳转回原页面
|
||||
setTimeout(() => app.onNavigateBack(), 2000)
|
||||
})
|
||||
.catch(err => {
|
||||
const resultData = err.result.data
|
||||
// 显示错误信息
|
||||
if (isEmpty(resultData)) {
|
||||
app.$toast(err.result.message)
|
||||
}
|
||||
// 判断还需绑定手机号
|
||||
if (resultData.isBindMobile) {
|
||||
app.onEmitSuccess({ userInfo, encryptedData, iv })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转到微信授权
|
||||
redirectUrl() {
|
||||
if (this.isCallback) {
|
||||
return
|
||||
}
|
||||
const callbackUrl = window.location.href
|
||||
Api.oauthUrl(callbackUrl)
|
||||
.then(result => {
|
||||
const url = result.data.redirectUrl
|
||||
window.location.href = url
|
||||
})
|
||||
},
|
||||
|
||||
// 将oauth提交给父级
|
||||
async onEmitSuccess({ userInfo, encryptedData, iv }) {
|
||||
this.$emit('success', {
|
||||
oauth: 'H5-WEIXIN', // 第三方登录类型: H5-WEIXIN
|
||||
userInfo,
|
||||
encryptedData,
|
||||
iv
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 登录成功-跳转回原页面
|
||||
*/
|
||||
onNavigateBack(delta = 1) {
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 1) {
|
||||
uni.navigateBack({
|
||||
delta: Number(delta || 1)
|
||||
})
|
||||
} else {
|
||||
this.$navTo('pages/index/index')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
102
pages/login/index.vue
Executable file
102
pages/login/index.vue
Executable file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<view v-if="isLoad" class="login" :style="appThemeStyle">
|
||||
<MpWeixin v-if="isMpWeixinAuth" @success="onGetUserInfoSuccess" />
|
||||
<!-- <WxOfficial v-else-if="isWxOfficialAuth" @success="onGetUserInfoSuccess" /> -->
|
||||
<Main v-else :isParty="isParty" :partyData="partyData" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Main from './components/main'
|
||||
import MpWeixin from './components/mp-weixin'
|
||||
import WxOfficial from './components/wx-official'
|
||||
import SettingKeyEnum from '@/common/enum/setting/Key'
|
||||
import SettingModel from '@/common/model/Setting'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Main,
|
||||
MpWeixin,
|
||||
WxOfficial
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 数据加载完成 [防止在微信小程序端onLoad和view渲染同步进行]
|
||||
isLoad: false,
|
||||
// 注册设置 (后台设置)
|
||||
setting: {},
|
||||
// 是否显示微信小程序授权登录
|
||||
isMpWeixinAuth: false,
|
||||
// 是否显示微信公众号授权登录
|
||||
isWxOfficialAuth: false,
|
||||
// 是否存在第三方用户信息
|
||||
isParty: false,
|
||||
// 第三方用户信息数据
|
||||
partyData: {}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
async onLoad(options) {
|
||||
// 获取注册设置
|
||||
// await this.getRegisterSetting()
|
||||
// 设置当前是否显示第三方授权登录
|
||||
await this.setShowUserInfo()
|
||||
// 数据加载完成
|
||||
this.isLoad = true
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取注册设置 [后台-客户端-注册设置]
|
||||
async getRegisterSetting() {
|
||||
await SettingModel.item(SettingKeyEnum.REGISTER.value, false)
|
||||
.then(setting => this.setting = setting)
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置当前是否显示第三方授权登录
|
||||
* - 条件1: 只有对应的客户端显示获取用户信息按钮, 例如微信小程序、微信公众号
|
||||
* - 条件2: 注册设置是否已开启该选项
|
||||
*/
|
||||
async setShowUserInfo() {
|
||||
const app = this
|
||||
// 判断当前客户端是微信小程序, 并且支持getUserProfile接口
|
||||
const isMpWeixin = app.platform === 'MP-WEIXIN' && wx.canIUse('getUserProfile')
|
||||
const isWxOfficial = app.platform === 'H5-WEIXIN'
|
||||
// 判断是否显示第三方授权登录
|
||||
app.isMpWeixinAuth = isMpWeixin && app.setting.isOauthMpweixin
|
||||
app.isWxOfficialAuth = isWxOfficial && app.setting.isOauthWxofficial
|
||||
},
|
||||
|
||||
// 获取到用户信息的回调函数
|
||||
onGetUserInfoSuccess(result) {
|
||||
// 记录第三方用户信息数据
|
||||
this.partyData = result
|
||||
// 显示注册页面
|
||||
this.onShowRegister()
|
||||
},
|
||||
|
||||
// 显示注册页面
|
||||
onShowRegister() {
|
||||
// 是否显示微信小程序授权登录
|
||||
if (this.partyData.oauth === 'MP-WEIXIN') {
|
||||
this.isMpWeixinAuth = false
|
||||
}
|
||||
// 是否显示微信小程序授权登录
|
||||
if (this.partyData.oauth === 'H5-WEIXIN') {
|
||||
this.isWxOfficialAuth = false
|
||||
}
|
||||
// 已获取到了第三方用户信息
|
||||
this.isParty = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
1039
pages/love/category.vue
Normal file
1039
pages/love/category.vue
Normal file
File diff suppressed because it is too large
Load Diff
711
pages/love/love copy.vue
Normal file
711
pages/love/love copy.vue
Normal file
@@ -0,0 +1,711 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="page-bg"></view>
|
||||
<view class="release" @click="navTo('sub_pages/love/release/release')">
|
||||
<image src="../../static/icon/add5.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<view :style="'margin-top: ' + statusBarHeight + 'px'"></view>
|
||||
<view class="header" :style="'margin-top: ' + statusBarHeight + 'px'">
|
||||
<view class="pair">
|
||||
<view class="search" @click="navTo('pages/search/index')">
|
||||
<image src="../../static/icon/search2.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="pair-btn" @click="navTo('pages/search/index')">
|
||||
<image src="../../static/icon/screen.png" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="menu">
|
||||
<u-tabs
|
||||
:list="menu"
|
||||
lineColor="#AD1384"
|
||||
:activeStyle="{
|
||||
color: '#ffffff',
|
||||
fontWeight: 'bold',
|
||||
transform: 'scale(1.05)'
|
||||
}"
|
||||
@click="onTabs"
|
||||
>
|
||||
</u-tabs>
|
||||
</view>
|
||||
</view>
|
||||
<view class="header-box"></view>
|
||||
<view class="comment-box">
|
||||
<view class="comment">
|
||||
<view class="item" v-for="(item,index) in list" :key="index">
|
||||
<view class="avatar" @click="$push('sub_pages/member/detail/detail',{userId:item.userId})">
|
||||
<view class="icon">
|
||||
<image :src="item.userAvatar" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="head">
|
||||
<view class="title">
|
||||
<view class="nickname">{{ item.nickname }}</view>
|
||||
<view class="date-time">{{ new Date(item.createTime).getTime() | timeFrom }}</view>
|
||||
</view>
|
||||
<view v-if="item.follow" class="unfollow-btn">
|
||||
<text>已关注</text>
|
||||
</view>
|
||||
<view v-else class="follow-btn" @click="onFollow(item.userId,index)">
|
||||
<!-- <image src="../../static/icon/follow.png" mode="widthFix"></image> -->
|
||||
<u-icon name="heart" color="#ffffff" :size="15"></u-icon>
|
||||
<text>关注</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="desc">
|
||||
<mp-html :content="item.content" />
|
||||
<!-- <text>有没有小姐姐想今年结婚的呀,我们可以私聊,希望有人可以与我共黄昏,有人问我粥可温...</text> -->
|
||||
</view>
|
||||
<view v-if="item.video" class="video">
|
||||
<video id="myVideo" :src="item.video" @error="videoErrorCallback"></video>
|
||||
</view>
|
||||
<view v-else class="image">
|
||||
<u-album :urls="item.files" keyName="thumb" multipleMode="widthFix"></u-album>
|
||||
</view>
|
||||
<view class="comment-btn">
|
||||
<view class="zan" v-if="item.liked == 0" @click="onLikes(item,index)">
|
||||
<u-icon name="thumb-up" :size="20"></u-icon>
|
||||
<text>{{ item.likes }}</text>
|
||||
</view>
|
||||
<view class="zan" v-else @click="onLikes(item,index)">
|
||||
<u-icon name="thumb-up" color="#8b004c" :size="20"></u-icon>
|
||||
<text class="active">{{ item.likes }}</text>
|
||||
</view>
|
||||
<view class="comment2" @click="openComment(item,index)" >
|
||||
<u-icon name="chat" :size="20"></u-icon>
|
||||
<!-- <image src="../../static/icon/comment2.png" mode="widthFix"></image> -->
|
||||
<text>{{ item.commentNumbers }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-empty
|
||||
v-if="!list && list.length == 0"
|
||||
mode="list"
|
||||
icon="http://cdn.uviewui.com/uview/empty/list.png"
|
||||
>
|
||||
</u-empty>
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore :status="loading" />
|
||||
<u-gap height="5"></u-gap>
|
||||
|
||||
<u-popup :show="showComment" mode="bottom" :round="10" :closeable="true" @close="closeComment">
|
||||
<view class="comment-popup">
|
||||
<view class="head">
|
||||
<text class="title">{{ countComment }}条评论</text>
|
||||
</view>
|
||||
<view class="user-list">
|
||||
<u-list :height="300" @scrolltolower="scrolltolower">
|
||||
<view class="list">
|
||||
<u-list-item v-for="(item, index) in comment" :key="index">
|
||||
<u-cell>
|
||||
<view slot="title" class="nickname">
|
||||
{{ item.nickname }}
|
||||
</view>
|
||||
<view slot="icon" :iconStyle="iconStyle" class="avatar2">
|
||||
<u-avatar size="50" :src="item.avatar"
|
||||
customStyle="margin: -3px 5px -3px 0"
|
||||
@click="$push('sub_pages/member/detail/detail',{userId: item.userId})"></u-avatar>
|
||||
</view>
|
||||
<view slot="label">
|
||||
<rich-text class="content" :nodes="item.content"></rich-text>
|
||||
<view class="fans">{{ new Date(item.createTime).getTime() | timeFrom }}</view>
|
||||
</view>
|
||||
<view slot="right-icon">
|
||||
|
||||
</view>
|
||||
</u-cell>
|
||||
</u-list-item>
|
||||
<u-empty
|
||||
v-if="comment.length == 0"
|
||||
mode="message"
|
||||
icon="http://cdn.uviewui.com/uview/empty/message.png"
|
||||
>
|
||||
</u-empty>
|
||||
</view>
|
||||
</u-list>
|
||||
</view>
|
||||
<view class="footer">
|
||||
<u-search :showAction="true" placeholder="发表评论" searchIcon="chat" actionText="发表" v-model="form.content" :actionStyle="actionStyle" @custom="onSend()"></u-search>
|
||||
<!-- <view class="btn-wrapper">
|
||||
<u-button text="发送" color="linear-gradient(to bottom, #010002, #681752)" :disabled="disabled"
|
||||
shape="circle" @click="$push('pages/checkout/checkout')"></u-button>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store/index.js'
|
||||
import * as UserApi from '@/api/user.js'
|
||||
import * as ArticleApi from '@/api/article.js'
|
||||
import * as ArticleLikeApi from '@/api/article-like.js'
|
||||
import * as ArticleCommentApi from '@/api/article-comment.js'
|
||||
import * as UserFollowApi from '@/api/user-follow.js'
|
||||
import * as Config from '@/config.js';
|
||||
|
||||
const pageSize = 10
|
||||
const userId = uni.getStorageSync('userId')
|
||||
|
||||
const menu = [{
|
||||
name: '最新'
|
||||
},
|
||||
{
|
||||
name: '同城'
|
||||
},
|
||||
{
|
||||
name: '关注'
|
||||
}
|
||||
]
|
||||
|
||||
import mixin from '@/core/mixins/tabbar'
|
||||
export default {
|
||||
mixins: [mixin],
|
||||
data() {
|
||||
return {
|
||||
options: null,
|
||||
list: [], // 文章列表
|
||||
comment: [], // 文章评论列表
|
||||
menu,
|
||||
curTab: 0,
|
||||
danmuList: [{
|
||||
text: '好可爱嗷~~',
|
||||
color: '#ff0000',
|
||||
time: 1
|
||||
},
|
||||
{
|
||||
text: 'かわゆい',
|
||||
color: '#ff00ff',
|
||||
time: 3
|
||||
}
|
||||
],
|
||||
actionStyle: {
|
||||
background: '#8b004c',
|
||||
color: '#ffffff',
|
||||
padding: '12rpx 16rpx',
|
||||
borderRadius: '50rpx'
|
||||
},
|
||||
iconStyle: {
|
||||
background: '#8b004c',
|
||||
},
|
||||
statusBarHeight: 25,
|
||||
latitude: 22.766777,
|
||||
longitude: 108.375152,
|
||||
scale: 10,
|
||||
page: 0,
|
||||
// 控制onShow事件是否刷新订单列表
|
||||
canReset: false,
|
||||
showComment: false,
|
||||
countComment: 0,
|
||||
where: {
|
||||
platform: 'MP-WEIXIN'
|
||||
},
|
||||
form: {
|
||||
articleId: 0,
|
||||
content: '',
|
||||
},
|
||||
articleIndex: 0, // 当前评论的文章
|
||||
isLogin: false,
|
||||
loading: 'loading'
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
console.log("options: ",options);
|
||||
app.checkLogin()
|
||||
app.onRefreshList()
|
||||
app.getLocation(res => {
|
||||
if (res.latitude && res.longitude) {
|
||||
app.latitude = res.latitude
|
||||
app.longitude = res.longitude
|
||||
app.scale = 16
|
||||
}
|
||||
})
|
||||
uni.getSystemInfo({
|
||||
success(data) {
|
||||
if (data) {
|
||||
app.statusBarHeight = data.statusBarHeight
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
const pages = getCurrentPages()
|
||||
console.log("this.options: ",this.options);
|
||||
},
|
||||
// 触底函数
|
||||
onReachBottom() {
|
||||
const app = this
|
||||
if (app.canReset) {
|
||||
console.log("触底函数1: ");
|
||||
app.page = ++app.page;
|
||||
app.onRefreshList()
|
||||
}
|
||||
},
|
||||
onPullDownRefresh(){
|
||||
this.page = 1
|
||||
this.list = []
|
||||
this.onRefreshList()
|
||||
uni.stopPullDownRefresh();
|
||||
},
|
||||
methods: {
|
||||
onTabs(e){
|
||||
const index = e.index
|
||||
this.curTab = index
|
||||
console.log("index: ",index);
|
||||
},
|
||||
// 刷新订单列表
|
||||
onRefreshList() {
|
||||
const app = this
|
||||
app.where.page = app.page
|
||||
app.where.loginUserId = userId
|
||||
app.where.categoryId = 0
|
||||
app.where.showFollow = true
|
||||
return new Promise((resolve, reject) => {
|
||||
ArticleApi.pageArticle(app.where)
|
||||
.then(result => {
|
||||
const list = result.data.list
|
||||
// 图片反序列化
|
||||
const newList = list.map((d, i) => {
|
||||
const imgs = JSON.parse(d.files)
|
||||
if (imgs) {
|
||||
var files = []
|
||||
imgs.map(pic => {
|
||||
files.push({
|
||||
thumb: pic.thumb ? pic.thumb : pic.url,
|
||||
url: pic.url
|
||||
})
|
||||
})
|
||||
}
|
||||
d.files = files
|
||||
return d
|
||||
})
|
||||
// 合并新数据
|
||||
app.list = app.list.concat(newList)
|
||||
if(result.data.count > app.list.length){
|
||||
app.canReset = true
|
||||
}else{
|
||||
app.loading = 'nomore'
|
||||
app.canReset = false
|
||||
}
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
videoErrorCallback: function(e) {
|
||||
uni.showModal({
|
||||
content: e.target.errMsg,
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
// 检查是否登录
|
||||
checkLogin() {
|
||||
if (!!store.getters.userId && store.getters.userId != Config.userId) {
|
||||
this.isLogin = true
|
||||
}
|
||||
},
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 跳转页面
|
||||
navTo(url) {
|
||||
if(!store.getters.userId || store.getters.userId == 1101) {
|
||||
this.$navTo('pages/login/index')
|
||||
return false
|
||||
}
|
||||
this.$navTo(url)
|
||||
},
|
||||
onFollow(shopId,index){
|
||||
const app = this
|
||||
if(!app.isLogin){
|
||||
app.$push('pages/login/index')
|
||||
return false
|
||||
}
|
||||
const status = !app.list[index].follow
|
||||
app.list[index].follow = status
|
||||
app.list.map((d,i) => {
|
||||
if(shopId == d.userId){
|
||||
app.list[i].follow = status
|
||||
}
|
||||
})
|
||||
UserFollowApi.addFollow({shopId}).then(res => {
|
||||
app.$success(res.message)
|
||||
})
|
||||
},
|
||||
onLikes(item,index){
|
||||
const app = this
|
||||
const { articleId, likes, liked } = item
|
||||
if(!app.isLogin){
|
||||
app.$push('pages/login/index')
|
||||
return false
|
||||
}
|
||||
ArticleLikeApi.addArticleLike({
|
||||
articleId,
|
||||
likes,
|
||||
liked
|
||||
}).then(res => {
|
||||
app.list[index].liked = res.data.liked
|
||||
app.list[index].likes = res.data.likes
|
||||
}).catch(err => {
|
||||
app.$error(err.message)
|
||||
})
|
||||
},
|
||||
openComment(item,index){
|
||||
if(!this.isLogin){
|
||||
this.$push('pages/login/index')
|
||||
return false
|
||||
}
|
||||
uni.hideTabBar()
|
||||
this.comment = []
|
||||
this.getComment(item.articleId)
|
||||
this.form.articleId = item.articleId
|
||||
this.articleIndex = index
|
||||
this.showComment = true
|
||||
},
|
||||
closeComment(){
|
||||
uni.showTabBar()
|
||||
this.showComment = false
|
||||
},
|
||||
getComment(articleId){
|
||||
const app = this
|
||||
ArticleCommentApi.pageArticleComment({articleId}).then(res => {
|
||||
app.countComment = res.data.count
|
||||
app.comment = res.data.list
|
||||
})
|
||||
},
|
||||
// 发表评论
|
||||
onSend(){
|
||||
const app = this
|
||||
const { form } = this
|
||||
form.countComment = app.countComment
|
||||
ArticleCommentApi.addArticleComment(form).then(res => {
|
||||
app.form.content = ''
|
||||
app.getComment(form.articleId)
|
||||
app.list[app.articleIndex].commentNumbers = res.data.commentNumbers
|
||||
// app.$success(res.message)
|
||||
}).catch(err => {
|
||||
app.$error(err.message)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page{
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
.page-bg {
|
||||
width: 750rpx;
|
||||
/* #ifdef MP-WEIXIN */
|
||||
height: calc(100rpx + var(--status-bar-height));
|
||||
/* #endif */
|
||||
display: block;
|
||||
background-color: #0d0119;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 8888;
|
||||
}
|
||||
|
||||
.release {
|
||||
position: fixed;
|
||||
bottom: 120rpx;
|
||||
right: 30rpx;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
|
||||
image {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
border-radius: 100%;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 750rpx;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
top: 0;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
background-color: #0d0119;
|
||||
|
||||
.pair {
|
||||
position: absolute;
|
||||
left: 30rpx;
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
display: flex;
|
||||
|
||||
.search {
|
||||
image {
|
||||
padding-top: 15rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.pair-btn {
|
||||
image {
|
||||
margin-left: 30rpx;
|
||||
padding-top: 16rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// .pair-btn{
|
||||
// margin-left: 22rpx;
|
||||
// height: 50rpx;
|
||||
// line-height: 50rpx;
|
||||
// margin-top: 15rpx;
|
||||
// padding: 6rpx 12rpx;
|
||||
// color: #ffffff;
|
||||
// border-radius: 10rpx;
|
||||
// background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
.menu {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
// font-size: 32rpx;
|
||||
// font-weight: 600;
|
||||
z-index: 9999;
|
||||
|
||||
.link {
|
||||
color: #cfd1d7;
|
||||
}
|
||||
|
||||
.curr {
|
||||
color: #ffffff;
|
||||
border-bottom: 5rpx solid #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
// .search{
|
||||
// position: absolute;
|
||||
// right: 30rpx;
|
||||
// image{
|
||||
// padding-top: 20rpx;
|
||||
// width: 50rpx;
|
||||
// height: 50rpx;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
.header-box{
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.comment-box {
|
||||
width: 750rpx;
|
||||
margin: 0 auto;
|
||||
.comment {
|
||||
width: 700rpx;
|
||||
padding: 30rpx;
|
||||
background-color: #ffffff;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
padding-bottom: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
border-bottom: 2rpx solid #f3f3f3;
|
||||
|
||||
.avatar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
image {
|
||||
width: 90rpx !important;
|
||||
height: 90rpx !important;
|
||||
border-radius: 100%;
|
||||
overflow: hidden;
|
||||
border: 5rpx solid #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.add {
|
||||
position: absolute;
|
||||
bottom: -7rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
width: 660rpx;
|
||||
margin-left: 10rpx;
|
||||
|
||||
.head {
|
||||
height: 90rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
.nickname {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.date-time {
|
||||
color: #9a9a9a;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.follow-btn {
|
||||
padding: 4rpx 20rpx;
|
||||
color: #ffffff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
margin-right: 10rpx;
|
||||
background: linear-gradient(#47076b, #8d1a50);
|
||||
image {
|
||||
width: 24rpx;
|
||||
height: 66rpx;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.unfollow-btn {
|
||||
padding: 4rpx 20rpx;
|
||||
color: #ffffff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 50rpx;
|
||||
margin-right: 10rpx;
|
||||
background: linear-gradient(#b3b3b3, #cccccc);
|
||||
image {
|
||||
width: 24rpx;
|
||||
height: 66rpx;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
padding: 20rpx 0;
|
||||
|
||||
image {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.video {
|
||||
padding: 20rpx 0;
|
||||
max-width: 400rpx;
|
||||
|
||||
video {
|
||||
max-width: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-btn {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.zan {
|
||||
display: flex;
|
||||
|
||||
image {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.comment2 {
|
||||
margin-left: 50rpx;
|
||||
display: flex;
|
||||
|
||||
image {
|
||||
width: 36rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
text{
|
||||
padding: 0 5rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.active{
|
||||
color: #681752;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.comment-popup {
|
||||
border-radius: 20rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 750rpx;
|
||||
height: 780rpx;
|
||||
.head{
|
||||
padding: 30rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.user-list{
|
||||
.list{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.nickname{
|
||||
color: #999999;
|
||||
}
|
||||
.avatar2{
|
||||
display: flex;
|
||||
height: auto;
|
||||
}
|
||||
.content{
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
width: 700rpx;
|
||||
margin: auto;
|
||||
position: fixed;
|
||||
left: 25rpx;
|
||||
bottom: 10rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
.fans{
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1160
pages/love/love.vue
Normal file
1160
pages/love/love.vue
Normal file
File diff suppressed because it is too large
Load Diff
393
pages/notice/notice.vue
Normal file
393
pages/notice/notice.vue
Normal file
@@ -0,0 +1,393 @@
|
||||
<template>
|
||||
<view class="notice">
|
||||
<view class="user-list">
|
||||
<view class="head">
|
||||
<view class="search-wrapper">
|
||||
<!-- <block v-for="(item,index) in menus" :key="index">
|
||||
<view class="box" @click="$push(item.path,item)">
|
||||
<view class="btn">
|
||||
<image :src="item.icon" mode="widthFix"></image>
|
||||
</view>
|
||||
<text>{{ item.title }}</text>
|
||||
<u-badge max="99" absolute :offset="[-2,-5]" :value="item.value"></u-badge>
|
||||
</view>
|
||||
</block> -->
|
||||
<view class="box" @click="$push(menus[0].path,menus[0])">
|
||||
<view class="btn">
|
||||
<image src="@/static/icon/notice-01.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<text>喜欢我</text>
|
||||
<u-badge max="99" absolute :offset="[-2,-5]" :value="unReadLikeMeNumber"></u-badge>
|
||||
</view>
|
||||
<view class="box" @click="$push(menus[1].path,menus[1])">
|
||||
<view class="btn">
|
||||
<image src="@/static/icon/notice-02.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<text>我喜欢</text>
|
||||
</view>
|
||||
<view class="box" @click="$push(menus[2].path,menus[2])">
|
||||
<view class="btn">
|
||||
<image src="@/static/icon/notice-03.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<text>评论</text>
|
||||
<u-badge max="99" absolute :offset="[-2,-5]" :value="unReadCommentNumber"></u-badge>
|
||||
</view>
|
||||
<view class="box" @click="$push(menus[3].path,menus[3])">
|
||||
<view class="btn">
|
||||
<image src="@/static/icon/notice-04.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<text>看过我</text>
|
||||
<u-badge max="99" absolute :offset="[-2,-5]" :value="unReadLookNumber"></u-badge>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-list height="88vh" v-if="isLogin">
|
||||
<view class="list">
|
||||
<u-swipe-action auto-close>
|
||||
<u-list-item v-for="(item, index) in conversationArr" :key="item.id">
|
||||
<u-swipe-action-item
|
||||
closeAfterClick
|
||||
:index="item.id"
|
||||
:options="options"
|
||||
@click="RemoveFriend(item.friendId)"
|
||||
:key="item.id"
|
||||
autoClose
|
||||
>
|
||||
<u-cell isLink @click="onUserDetail(item)">
|
||||
<view slot="title" class="nickname">
|
||||
{{ item.friendInfo.nickname }}
|
||||
</view>
|
||||
<view slot="icon" :iconStyle="iconStyle" class="head avatar2">
|
||||
<u-avatar size="50" :src="item.friendInfo.avatar" shape="square" mode="aspectFill"
|
||||
customStyle="margin: -3px 5px -3px 0"></u-avatar>
|
||||
<view>
|
||||
<u-badge type="error" max="99" shape="circle" :absolute="true" :offset="[-8,-2]" :value="item.unRead"></u-badge>
|
||||
</view>
|
||||
</view>
|
||||
<view slot="label">
|
||||
<rich-text class="content" :nodes="item.content"></rich-text>
|
||||
</view>
|
||||
<view slot="right-icon">
|
||||
|
||||
<view class="fans">{{ new Date(item.updateTime).getTime() | timeFrom }}</view>
|
||||
</view>
|
||||
</u-cell>
|
||||
</u-swipe-action-item>
|
||||
|
||||
</u-list-item>
|
||||
</u-swipe-action>
|
||||
<u-empty v-if="conversationArr.length == 0" mode="message" text="暂无消息"
|
||||
icon="http://cdn.uviewui.com/uview/empty/message.png">
|
||||
</u-empty>
|
||||
</view>
|
||||
</u-list>
|
||||
<u-empty :marginTop="180" v-if="!isLogin" mode="permission" text="暂时还没有人和你打招呼哦!"
|
||||
icon="https://file.wsdns.cn/empty/data.png">
|
||||
</u-empty>
|
||||
</view>
|
||||
<!-- <view class="wechat-auth agree" v-if="!isLogin" >
|
||||
<button class="btn-normal" @click="$push('pages/login/index')">
|
||||
<view class="wechat-auth-container">
|
||||
<image class="icon" src="@/static/channel/wechat.png"></image>
|
||||
<text class="title">立即登录</text>
|
||||
</view>
|
||||
</button>
|
||||
</view> -->
|
||||
<u-modal showCancelButton @cancel="showIdCardModal = false" @confirm="doAuth" :show="showIdCardModal" title="完成认证我们才能开始配对聊天哦" cancelText="稍后认证" confirm-text="立即认证"></u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store/index.js'
|
||||
import storage from '../../utils/storage'
|
||||
import mixin from '@/core/mixins/tabbar'
|
||||
import {
|
||||
ACCESS_TOKEN,
|
||||
USER_ID
|
||||
} from '@/store/mutation-types'
|
||||
import {
|
||||
navTo
|
||||
} from '@/core/app.js'
|
||||
import {
|
||||
mapGetters,
|
||||
mapMutations,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
|
||||
const menus = [
|
||||
{
|
||||
index: 0,
|
||||
title: '喜欢我',
|
||||
icon: '../../static/icon/notice-01.png',
|
||||
path: 'sub_pages/notice/fans',
|
||||
value: 41,
|
||||
show: false
|
||||
},
|
||||
{
|
||||
index: 1,
|
||||
title: '我喜欢',
|
||||
icon: '../../static/icon/notice-02.png',
|
||||
path: 'sub_pages/notice/like',
|
||||
value: 0,
|
||||
show: false
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
title: '评论',
|
||||
icon: '../../static/icon/notice-03.png',
|
||||
path: 'sub_pages/notice/comment',
|
||||
value: 12,
|
||||
show: false
|
||||
},
|
||||
{
|
||||
index: 3,
|
||||
title: '看过我',
|
||||
icon: '../../static/icon/notice-04.png',
|
||||
path: 'sub_pages/notice/look',
|
||||
value: 8,
|
||||
show: false
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
mixins: [mixin],
|
||||
data() {
|
||||
return {
|
||||
menus,
|
||||
title: '国内馆',
|
||||
// 正在加载中
|
||||
isLoading: false,
|
||||
// 是否授权了定位权限
|
||||
isAuthor: true,
|
||||
// 当前选择的门店ID
|
||||
selectedId: null,
|
||||
// 订单列表数据
|
||||
list: [],
|
||||
navTo,
|
||||
isLogin: true,
|
||||
options: [{text: '删除',style: {backgroundColor: '#fa3534'}}],
|
||||
showIdCardModal: false
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
onShow() {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
if (userId == 1101) {
|
||||
this.$push('pages/login/index')
|
||||
return false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['ADD_FRIEND']),
|
||||
...mapActions(['RemoveFriend', 'GetUserInfo']),
|
||||
onUserDetail(item) {
|
||||
if(this.$store.getters.userInfo.certification != 1){
|
||||
this.showIdCardModal = true
|
||||
return false
|
||||
}
|
||||
this.ADD_FRIEND(item.friendInfo)
|
||||
uni.navigateTo({
|
||||
url: '/pages/chat/chat?friendId=' + item.friendInfo.userId
|
||||
})
|
||||
},
|
||||
changeCity() {
|
||||
this.$toast('切换区域')
|
||||
},
|
||||
doAuth(){
|
||||
uni.navigateTo({
|
||||
url: '/sub_pages/certification/id-card/id-card',
|
||||
events: {
|
||||
reload: () => {
|
||||
this.GetUserInfo()
|
||||
this.showIdCardModal = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
formatTime(val) {
|
||||
const date = new Date(val);
|
||||
let today = new Date().setHours(0, 0, 0, 0);
|
||||
let d = new Date(val).setHours(0, 0, 0, 0);
|
||||
if (d === today) {
|
||||
return uni.$u.timeFormat(date, 'hh:MM')
|
||||
} else {
|
||||
return uni.$u.timeFormat(date)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
page{
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.notice {
|
||||
}
|
||||
.head{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
width: 750rpx;
|
||||
padding: 25rpx 0;
|
||||
border-bottom: 1rpx solid #e9ebf1;
|
||||
.box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
text-align: center;
|
||||
line-height: 30rpx;
|
||||
position: relative;
|
||||
|
||||
.btn {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
image {
|
||||
width: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.user-list {
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.avatar2 {
|
||||
display: flex;
|
||||
height: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.unread {
|
||||
position: absolute;
|
||||
min-width: 35rpx;
|
||||
min-height: 35rpx;
|
||||
border-radius: 35rpx;
|
||||
background-color: #f56c6c;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
top: -14rpx;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20rpx 0;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.fans {
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索按钮
|
||||
.search-button {
|
||||
width: 25%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.button {
|
||||
height: 64rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 0 5px 5px 0;
|
||||
background: #2C71C7
|
||||
}
|
||||
}
|
||||
.u-body-item {
|
||||
align-items: stretch !important
|
||||
}
|
||||
.agree {
|
||||
background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
|
||||
}
|
||||
|
||||
// 微信授权登录
|
||||
.wechat-auth {
|
||||
width: 600rpx;
|
||||
height: 86rpx;
|
||||
margin: 100rpx auto 50rpx auto;
|
||||
color: $main-text;
|
||||
border-radius: 80rpx;
|
||||
box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.1);
|
||||
letter-spacing: 5rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.btn-normal {
|
||||
width: 580rpx;
|
||||
}
|
||||
|
||||
.btn-normal-no {
|
||||
width: 580rpx;
|
||||
}
|
||||
|
||||
button {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.wechat-auth-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $main-text;
|
||||
background: none !important;
|
||||
|
||||
.title {
|
||||
color: #f3f3f3;
|
||||
}
|
||||
}
|
||||
|
||||
// 登录按钮
|
||||
.login-button {
|
||||
width: 100%;
|
||||
height: 86rpx;
|
||||
margin-top: 80rpx;
|
||||
background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
|
||||
color: $main-text;
|
||||
border-radius: 80rpx;
|
||||
box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.1);
|
||||
letter-spacing: 5rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
477
pages/order/index.vue
Executable file
477
pages/order/index.vue
Executable file
@@ -0,0 +1,477 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="tabs">
|
||||
<u-tabs :list="tabs" @click="onChangeTab" lineColor="#ff0000"></u-tabs>
|
||||
</view>
|
||||
<!-- 订单列表 -->
|
||||
<view class="order-list" v-if="list">
|
||||
<view class="order-item" v-for="(item, index) in list" :key="index">
|
||||
<view class="item-top">
|
||||
<view class="item-top-left">
|
||||
<text class="order-time">
|
||||
{{ item.planName }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="item-top-right">
|
||||
<u-tag text="待支付" plain size="mini" type="warning" v-if="item.payStatus == 10"></u-tag>
|
||||
<u-tag text="已支付" plain size="mini" type="success"
|
||||
v-else="item.payStatus == 20 && item.receiptStatus == 10"></u-tag>
|
||||
</view>
|
||||
</view>
|
||||
<u-divider></u-divider>
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<block>
|
||||
<view class="goods-item">
|
||||
<view class="icon">
|
||||
<image :src="item.planIcon" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="goods-content">
|
||||
<text class="goods-title">订单号:{{ item.logId }}</text>
|
||||
<text class="goods-title">描述:{{ item.priceName }}</text>
|
||||
<text class="goods-title">价格:¥{{ item.money }}</text>
|
||||
<text class="goods-title">时间:{{ item.createTime }}</text>
|
||||
<text class="goods-title">状态:{{ item.isSettled == 1 && item.status == 0 ? '已生效' : '处理中' }}</text>
|
||||
<block v-if="item.planId == 17 || item.planId == 18">
|
||||
<text class="goods-title">服务门店:{{ item.merchantName }}</text>
|
||||
<text class="goods-title">有效期至:{{ item.expirationTime }}</text>
|
||||
<text class="goods-title">门店地址:{{ item.address }}</text>
|
||||
</block>
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<u-divider></u-divider>
|
||||
<!-- 订单合计 -->
|
||||
<view class="order-total">
|
||||
<view class="pay-btn">
|
||||
<view class="btn" v-if="item.payStatus == 10">
|
||||
<u-button text="立即支付" plain type="error" size="small" @click="onPay(item.logId)"></u-button>
|
||||
</view>
|
||||
<!-- <view class="btn" v-if="item.payStatus == 10">
|
||||
<u-button text="取消订单" size="small" @click="onRemove(item.logId)"></u-button>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="total-price">
|
||||
<text>合计</text>
|
||||
<text class="unit" style="color: #ff0000;">¥</text>
|
||||
<text class="money">{{ item.money }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore v-if="list.length > 0" :status="status" />
|
||||
<u-empty mode="order" icon="http://cdn.uviewui.com/uview/empty/car.png" v-if="list.length == 0">
|
||||
</u-empty>
|
||||
<u-gap height="20"></u-gap>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store/index.js'
|
||||
import * as UserPlanLogApi from '@/api/love-user-plan-log.js'
|
||||
import {
|
||||
dateFormat,
|
||||
getWeek
|
||||
} from '@/utils/util.js'
|
||||
|
||||
// 每页记录数量
|
||||
const pageSize = 10
|
||||
|
||||
// tab栏数据
|
||||
const tabs = [{
|
||||
name: `我的订单`,
|
||||
value: 'delivery'
|
||||
}]
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 当前页面参数
|
||||
options: {
|
||||
dataType: 'all'
|
||||
},
|
||||
// tab栏数据
|
||||
tabs,
|
||||
// 当前标签索引
|
||||
curTab: 0,
|
||||
// 订单列表数据
|
||||
list: [],
|
||||
total: 0,
|
||||
loadMore: true,
|
||||
status: '加载更多',
|
||||
page: 1,
|
||||
where: {
|
||||
userId: 0
|
||||
},
|
||||
// 选择的设备
|
||||
getWeek,
|
||||
dateFormat
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
},
|
||||
// 触底函数
|
||||
onReachBottom() {
|
||||
const app = this
|
||||
if (app.loadMore) {
|
||||
app.page = ++app.page;
|
||||
app.onRefreshList()
|
||||
}
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
const app = this
|
||||
app.page = 1
|
||||
app.list = []
|
||||
app.onRefreshList();
|
||||
uni.stopPullDownRefresh();
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 切换标签项
|
||||
onChangeTab(e) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = e.index
|
||||
app.page = 1
|
||||
app.list = []
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新订单列表
|
||||
onRefreshList() {
|
||||
const app = this
|
||||
const {
|
||||
curTab
|
||||
} = this
|
||||
app.where.showGoodsList = true
|
||||
app.where.page = app.page
|
||||
app.where.payStatus = 20;
|
||||
app.where.receiptStatus = 10;
|
||||
app.where.agent = undefined
|
||||
console.log("curTab: ",curTab);
|
||||
if (curTab == 0) {
|
||||
// app.where.agent = undefined
|
||||
// app.where.payStatus = 20;
|
||||
// app.where.receiptStatus = 10;
|
||||
}
|
||||
if (curTab == 1) {
|
||||
app.where.agent = true
|
||||
// app.where.payStatus = 20;
|
||||
// app.where.receiptStatus = 10;
|
||||
}
|
||||
const userId = uni.getStorageSync('userId')
|
||||
if(userId && userId > 0){
|
||||
app.where.userId = userId
|
||||
// 只查询已支付订单
|
||||
UserPlanLogApi.pageUserPlanLog(app.where).then(res => {
|
||||
const newList = res.data.list
|
||||
if (newList.length > 0) {
|
||||
app.list = app.list.concat(newList)
|
||||
} else {
|
||||
app.status = '没有更多了'
|
||||
app.loadMore = false
|
||||
}
|
||||
})
|
||||
}
|
||||
// if (curTab == 2) {
|
||||
// app.where.agent = undefined
|
||||
// app.where.payStatus = 20;
|
||||
// app.where.receiptStatus = 10;
|
||||
// }
|
||||
|
||||
},
|
||||
|
||||
// 取消订单
|
||||
onCancel(orderId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '确认要取消该订单吗?',
|
||||
success(o) {
|
||||
if (o.confirm) {
|
||||
OrderApi.removeOrder(orderId)
|
||||
.then(result => {
|
||||
// 显示成功信息
|
||||
app.$toast(result.message)
|
||||
// 刷新订单列表
|
||||
app.list = []
|
||||
app.onRefreshList()
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onCancelOne(item) {
|
||||
const app = this
|
||||
// 报餐截止时间
|
||||
let date = new Date();
|
||||
if (date.getHours() > 20 && date.getMinutes() > 30) {
|
||||
return app.$toast('报餐截止时间')
|
||||
}
|
||||
OrderGoodsApi.cancelfood(item).then(res => {
|
||||
app.$toast(res.message)
|
||||
// 刷新订单列表
|
||||
app.list = []
|
||||
app.onRefreshList()
|
||||
})
|
||||
},
|
||||
// 点击去支付
|
||||
onPay(orderIds) {
|
||||
this.$navTo('pages/checkout/cashier/index', {
|
||||
orderIds
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转到订单详情页
|
||||
handleTargetDetail(orderId) {
|
||||
this.$navTo('pages/order/detail', {
|
||||
orderId
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转到订单评价页
|
||||
handleTargetComment(orderId) {
|
||||
this.$navTo('pages/order/comment/index', {
|
||||
orderId
|
||||
})
|
||||
},
|
||||
|
||||
getDeliveryTime(time) {
|
||||
return dateFormat('YYYY-mm-dd', new Date(new Date(time).toLocaleDateString()));
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page{
|
||||
background-color: #f3f3f3 !important;
|
||||
}
|
||||
.container {
|
||||
width: 750rpx;
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
.order-list {}
|
||||
|
||||
// 项目内容
|
||||
.order-item {
|
||||
padding: 30rpx;
|
||||
margin: 20rpx auto 10rpx auto;
|
||||
width: 660rpx;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 15rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
// 项目顶部
|
||||
.item-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.order-time {
|
||||
color: #333333;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.state-text {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
|
||||
// 商品项
|
||||
.goods-item {
|
||||
display: flex;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.cancel {
|
||||
width: 70rpx;
|
||||
position: absolute;
|
||||
top: 4rpx;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 100rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
|
||||
|
||||
// background: linear-gradient(to bottom, #010002, #681752);
|
||||
image {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品图片
|
||||
.goods-image {
|
||||
width: 120rpx;
|
||||
height: 90rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 120rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品内容
|
||||
.goods-content {
|
||||
width: 500rpx;
|
||||
padding-left: 16rpx;
|
||||
padding-top: 0;
|
||||
display: flex;
|
||||
color: #666666;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.goods-title {
|
||||
font-size: 26rpx;
|
||||
max-height: 76rpx;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
|
||||
.goods-props {
|
||||
margin-top: 14rpx;
|
||||
height: 40rpx;
|
||||
color: #ababab;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-props-item {
|
||||
display: inline-block;
|
||||
margin-right: 14rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #F5F5F5;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 交易信息
|
||||
.goods-trade {
|
||||
padding-top: 16rpx;
|
||||
width: 200rpx !important;
|
||||
text-align: right;
|
||||
color: $uni-text-color-grey;
|
||||
font-size: 26rpx;
|
||||
|
||||
.goods-price {
|
||||
vertical-align: bottom;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.unit {
|
||||
margin-right: -2rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 订单合计
|
||||
.order-total {
|
||||
font-size: 26rpx;
|
||||
vertical-align: bottom;
|
||||
text-align: right;
|
||||
height: 50rpx;
|
||||
padding-top: 10rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pay-btn{
|
||||
display: flex;
|
||||
.btn{
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
.total-price{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.unit {
|
||||
margin-left: 8rpx;
|
||||
margin-right: -2rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.money {
|
||||
font-size: 28rpx;
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
|
||||
// 订单操作
|
||||
.order-handle {
|
||||
.btn-group {
|
||||
|
||||
.btn-item {
|
||||
border-radius: 10rpx;
|
||||
padding: 8rpx 20rpx;
|
||||
margin-left: 15rpx;
|
||||
font-size: 26rpx;
|
||||
float: right;
|
||||
color: #383838;
|
||||
border: 1rpx solid #a8a8a8;
|
||||
|
||||
&:last-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
border: 1rpx solid $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.tabs {
|
||||
width: 600rpx;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.yuqi-text {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
135
pages/pair/pair.vue
Normal file
135
pages/pair/pair.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<view class="pair">
|
||||
<image src="https://file.wsdns.cn/20230611/de68e7b6238941ea99a9ba4869b8e7c5.jpeg" class="bg" mode="widthFix">
|
||||
</image>
|
||||
<view class="project">
|
||||
<view class="title">精心挑选与你最匹配的异性</view>
|
||||
<view class="content">
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230610/6e1ad1d1947144e4968e5b9aba4647ab." mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230611/cdf768b22a0543b98666daa223b51746.jpeg" mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230611/cdf768b22a0543b98666daa223b51746.jpeg" mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230611/cdf768b22a0543b98666daa223b51746.jpeg" mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230611/cdf768b22a0543b98666daa223b51746.jpeg" mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230611/cdf768b22a0543b98666daa223b51746.jpeg" mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230611/cdf768b22a0543b98666daa223b51746.jpeg" mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<u-avatar src="https://file.wsdns.cn/20230611/cdf768b22a0543b98666daa223b51746.jpeg" mode="aspectFill" :size="60"></u-avatar>
|
||||
<view class="age">27岁</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-wrapper">
|
||||
<u-button text="换一批" color="linear-gradient(to bottom, #010002, #681752)" :disabled="disabled"
|
||||
shape="circle" @click="handleSubmit()"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pair {
|
||||
.bg {
|
||||
width: 750rpx;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.project {
|
||||
position: absolute;
|
||||
left: 45rpx;
|
||||
width: 660rpx;
|
||||
margin: 100rpx auto;
|
||||
min-height: 500rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-family: SourceHanSansSC;
|
||||
font-weight: 700;
|
||||
font-size: 38rpx;
|
||||
color: rgb(0, 0, 0);
|
||||
font-style: normal;
|
||||
letter-spacing: 0px;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
text-decoration: none;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
}
|
||||
.content{
|
||||
width: 600rpx;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
.item{
|
||||
margin: 18rpx;
|
||||
border: 5rpx solid #681752;
|
||||
border-radius: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.age{
|
||||
position: absolute;
|
||||
bottom: -12rpx;
|
||||
font-size: 22rpx;
|
||||
padding: 1rpx 10rpx;
|
||||
color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
background: linear-gradient(#47076b, #8d1a50);
|
||||
}
|
||||
.btn {
|
||||
font-size: 26rpx;
|
||||
padding: 1rpx 10rpx;
|
||||
color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
background: linear-gradient(#47076b, #8d1a50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-wrapper {
|
||||
width: 360rpx;
|
||||
margin: 50rpx auto;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
434
pages/refund/apply.vue
Executable file
434
pages/refund/apply.vue
Executable file
@@ -0,0 +1,434 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container" :style="appThemeStyle">
|
||||
|
||||
<!-- 商品详情 -->
|
||||
<view class="goods-detail b-f dis-flex flex-dir-row">
|
||||
<view class="left">
|
||||
<image class="goods-image" :src="goods.goods_image"></image>
|
||||
</view>
|
||||
<view class="right dis-flex flex-box flex-dir-column flex-x-around">
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ goods.goods_name }}</text>
|
||||
</view>
|
||||
<view class="dis-flex col-9 f-24">
|
||||
<view class="flex-box">
|
||||
<view class="goods-props clearfix">
|
||||
<view class="goods-props-item" v-for="(props, idx) in goods.goods_props" :key="idx">
|
||||
<text>{{ props.value.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="t-r">×{{ goods.total_num }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务类型 -->
|
||||
<view class="row-service b-f m-top20">
|
||||
<view class="row-title">服务类型</view>
|
||||
<view class="service-switch dis-flex">
|
||||
<view class="switch-item" v-for="(item, index) in RefundTypeEnum.data" :key="index" :class="{ active: formData.type == item.value }"
|
||||
@click="onSwitchService(item.value)">{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 申请原因 -->
|
||||
<view class="row-textarea b-f m-top20">
|
||||
<view class="row-title">申请原因</view>
|
||||
<view class="content">
|
||||
<textarea class="textarea" v-model="formData.content" maxlength="2000" placeholder="请详细填写申请原因,注意保持商品的完好,建议您先与卖家沟通"
|
||||
placeholderStyle="color:#ccc"></textarea>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退款金额 -->
|
||||
<view v-if="formData.type == RefundTypeEnum.RETURN.value" class="row-money b-f m-top20 dis-flex">
|
||||
<view class="row-title">退款金额</view>
|
||||
<view class="money col-m">¥{{ goods.total_pay_price }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 上传凭证 -->
|
||||
<view class="row-voucher b-f m-top20">
|
||||
<view class="row-title">上传凭证 (最多6张)</view>
|
||||
<view class="image-list">
|
||||
<!-- 图片列表 -->
|
||||
<view class="image-preview" v-for="(image, imageIndex) in imageList" :key="imageIndex">
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
<image class="image" mode="aspectFill" :src="image.path"></image>
|
||||
</view>
|
||||
<!-- 上传图片 -->
|
||||
<view v-if="imageList.length < maxImageLength" class="image-picker" @click="chooseImage()">
|
||||
<text class="choose-icon iconfont icon-camera"></text>
|
||||
<text class="choose-text">上传图片</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认提交</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { RefundTypeEnum } from '@/common/enum/order/refund'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import * as RefundApi from '@/api/refund'
|
||||
|
||||
const maxImageLength = 6
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
RefundTypeEnum,
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 订单商品id
|
||||
orderGoodsId: null,
|
||||
// 订单商品详情
|
||||
goods: {},
|
||||
// 表单数据
|
||||
formData: {
|
||||
// 图片上传成功的文件ID集
|
||||
images: [],
|
||||
// 服务类型
|
||||
type: 10,
|
||||
// 申请原因
|
||||
content: ''
|
||||
},
|
||||
// 用户选择的图片列表
|
||||
imageList: [],
|
||||
// 最大图片数量
|
||||
maxImageLength,
|
||||
// 按钮禁用
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ orderGoodsId }) {
|
||||
this.orderGoodsId = orderGoodsId
|
||||
// 获取订单商品详情
|
||||
this.getGoodsDetail()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取订单商品详情
|
||||
getGoodsDetail() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
RefundApi.goods(app.orderGoodsId)
|
||||
.then(result => {
|
||||
app.goods = result.data.goods
|
||||
app.isLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
// 切换类型
|
||||
onSwitchService(value) {
|
||||
this.formData.type = value
|
||||
},
|
||||
|
||||
// 选择图片
|
||||
chooseImage() {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
count: maxImageLength - oldImageList.length,
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({ tempFiles }) {
|
||||
// tempFiles = [{path:'xxx', size:100}]
|
||||
app.imageList = oldImageList.concat(tempFiles)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
this.imageList.splice(imageIndex, 1)
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
const { imageList } = app
|
||||
// 判断是否重复提交
|
||||
if (app.disabled === true) return false
|
||||
// 表单验证
|
||||
if (!app.formData.content.trim().length) {
|
||||
app.$toast('请填写申请原因')
|
||||
return false
|
||||
}
|
||||
// 按钮禁用
|
||||
app.disabled = true
|
||||
// 判断是否需要上传图片
|
||||
if (imageList.length > 0) {
|
||||
app.uploadFile()
|
||||
.then(() => app.onSubmit())
|
||||
.catch(err => {
|
||||
app.disabled = false
|
||||
if (err.statusCode !== 0) {
|
||||
app.$toast(err.errMsg)
|
||||
}
|
||||
console.log('err', err)
|
||||
})
|
||||
} else {
|
||||
app.onSubmit()
|
||||
}
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
RefundApi.apply(app.orderGoodsId, app.formData)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
setTimeout(() => {
|
||||
app.disabled = false
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
})
|
||||
.catch(err => app.disabled = false)
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const { imageList } = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
app.formData.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
|
||||
}
|
||||
|
||||
.row-title {
|
||||
color: #888;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
// 商品信息
|
||||
.goods-detail {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.left {
|
||||
.goods-image {
|
||||
display: block;
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.goods-props {
|
||||
margin-top: 14rpx;
|
||||
height: 40rpx;
|
||||
color: #ababab;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-props-item {
|
||||
display: inline-block;
|
||||
margin-right: 14rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #F5F5F5;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 服务类型 */
|
||||
.row-service {
|
||||
padding: 24rpx 20rpx;
|
||||
}
|
||||
|
||||
.service-switch {
|
||||
.switch-item {
|
||||
padding: 6rpx 30rpx;
|
||||
margin-right: 25rpx;
|
||||
border-radius: 10rpx;
|
||||
border: 1px solid rgb(177, 177, 177);
|
||||
color: #888888;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
border: 1px solid $main-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 申请原因 */
|
||||
.row-textarea {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.textarea {
|
||||
width: 100%;
|
||||
height: 220rpx;
|
||||
padding: 12rpx;
|
||||
border: 1rpx solid #e8e8e8;
|
||||
border-radius: 5rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 退款金额 */
|
||||
.row-money {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.row-title {
|
||||
margin-bottom: 0;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 140rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
color: $main-text;
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
481
pages/refund/detail.vue
Executable file
481
pages/refund/detail.vue
Executable file
@@ -0,0 +1,481 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container p-bottom" :style="appThemeStyle">
|
||||
|
||||
<!-- 顶部状态栏 -->
|
||||
<view class="detail-header dis-flex flex-y-center">
|
||||
<view class="header-backdrop">
|
||||
<image class="image" src="/static/order/refund-bg.png"></image>
|
||||
</view>
|
||||
<view class="header-state">
|
||||
<text class="f-32 col-f">{{ detail.state_text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品详情 -->
|
||||
<view class="detail-goods b-f m-top20 dis-flex flex-dir-row" @click="onGoodsDetail(detail.orderGoods.goods_id)">
|
||||
<view class="left">
|
||||
<image class="goods-image" :src="detail.orderGoods.goods_image"></image>
|
||||
</view>
|
||||
<view class="right dis-flex flex-box flex-dir-column flex-x-around">
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ detail.orderGoods.goods_name }}</text>
|
||||
</view>
|
||||
<view class="dis-flex col-9 f-24">
|
||||
<view class="flex-box">
|
||||
<view class="goods-props clearfix">
|
||||
<view class="goods-props-item" v-for="(props, idx) in detail.orderGoods.goods_props" :key="idx">
|
||||
<text>{{ props.value.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="t-r">×{{ detail.orderGoods.total_num }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品金额 -->
|
||||
<view class="detail-order b-f row-block">
|
||||
<view class="item dis-flex flex-x-end flex-y-center">
|
||||
<text class="">商品金额:</text>
|
||||
<text class="col-m">¥{{ detail.orderGoods.total_pay_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 已退款金额 -->
|
||||
<view v-if="detail.status == RefundStatusEnum.COMPLETED.value && detail.type == 10"
|
||||
class="detail-order b-f row-block dis-flex flex-x-end flex-y-center">
|
||||
<text class="">已退款金额:</text>
|
||||
<text class="col-m">¥{{ detail.refund_money }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 售后信息 -->
|
||||
<view v-if="detail.status == RefundStatusEnum.REJECTED.value" class="detail-refund b-f m-top20">
|
||||
<view class="detail-refund__row dis-flex">
|
||||
<view class="text">
|
||||
<text>售后类型:</text>
|
||||
</view>
|
||||
<view class="flex-box">
|
||||
<text>{{ RefundTypeEnum[detail.type].name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail-refund__row dis-flex">
|
||||
<view class="text">
|
||||
<text>申请原因:</text>
|
||||
</view>
|
||||
<view class="flex-box">
|
||||
<text>{{ detail.apply_desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="detail.images.length > 0" class="detail-refund__row dis-flex">
|
||||
<view class="text">
|
||||
<text>申请凭证:</text>
|
||||
</view>
|
||||
<view class="image-list flex-box">
|
||||
<view class="image-preview" v-for="(item, index) in detail.images" :key="index">
|
||||
<image class="image" mode="aspectFill" :src="item.image_url" @click="handlePreviewImages(index)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 售后信息 -->
|
||||
<view v-if="detail.status.value == 10" class="detail-refund b-f m-top20">
|
||||
<view class="detail-refund__row dis-flex">
|
||||
<view class="text">
|
||||
<text class="col-m">拒绝原因:</text>
|
||||
</view>
|
||||
<view class="flex-box">
|
||||
<text>{{ detail.refuse_desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退货物流信息 -->
|
||||
<view v-if="detail.audit_status == AuditStatusEnum.REVIEWED.value && detail.is_user_send" class="detail-address b-f m-top20">
|
||||
<view class="detail-address__row address-title">
|
||||
<text class="col-m">退货物流信息</text>
|
||||
</view>
|
||||
<view class="detail-address__row address-details">
|
||||
<view class="address-details__row">
|
||||
<text>物流公司:{{ detail.express.express_name }}</text>
|
||||
</view>
|
||||
<view class="address-details__row">
|
||||
<text>物流单号:{{ detail.express_no }}</text>
|
||||
</view>
|
||||
<!-- <view class="address-details__row">
|
||||
<text>发货状态:{{ detail.is_user_send ? '已发货' : '未发货' }}</text>
|
||||
</view> -->
|
||||
<view class="address-details__row">
|
||||
<text>发货时间:{{ detail.send_time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商家收货地址 -->
|
||||
<view v-if="detail.audit_status == AuditStatusEnum.REVIEWED.value" class="detail-address b-f m-top20">
|
||||
<view class="detail-address__row address-title">
|
||||
<text class="col-m">商家退货地址</text>
|
||||
</view>
|
||||
<view class="detail-address__row address-details">
|
||||
<view class="address-details__row">
|
||||
<text>收货人:{{ detail.address.name }}</text>
|
||||
</view>
|
||||
<view class="address-details__row">
|
||||
<text>联系电话:{{ detail.address.phone }}</text>
|
||||
</view>
|
||||
<view class="address-details__row dis-flex">
|
||||
<view class="text">
|
||||
<text>详细地址:</text>
|
||||
</view>
|
||||
<view class="address flex-box">
|
||||
<text class="region" v-for="(region, idx) in detail.address.region" :key="idx">{{ region }}</text>
|
||||
<text class="detail">{{ detail.address.detail }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail-address__row address-tips">
|
||||
<view class="f-26 col-9">
|
||||
<text>· 未与卖家协商一致情况下,请勿寄到付或平邮</text>
|
||||
</view>
|
||||
<view class="f-26 col-9">
|
||||
<text>· 请填写真实有效物流信息</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 填写物流信息 -->
|
||||
<form v-if="detail.type == RefundTypeEnum.RETURN.value && detail.audit_status == AuditStatusEnum.REVIEWED.value && !detail.is_user_send"
|
||||
@submit="onSubmit()">
|
||||
<view class="detail-express b-f m-top20">
|
||||
<view class="form-group dis-flex flex-y-center">
|
||||
<view class="field">物流公司:</view>
|
||||
<view class="flex-box">
|
||||
<picker mode="selector" :range="expressList" range-key="express_name" :value="expressIndex" @change="onChangeExpress">
|
||||
<text v-if="expressIndex > -1">{{ expressList[expressIndex].express_name }}</text>
|
||||
<text v-else class="col-80">请选择物流公司</text>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-group dis-flex flex-y-center">
|
||||
<view class="field">物流单号:</view>
|
||||
<view class="flex-box">
|
||||
<input class="input" v-model="formData.expressNo" placeholder="请填写物流单号"></input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<button class="btn-item btn-item-main btn-normal" :class="{ disabled }" formType="submit">确认发货</button>
|
||||
</view>
|
||||
</view>
|
||||
</form>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { AuditStatusEnum, RefundStatusEnum, RefundTypeEnum } from '@/common/enum/order/refund'
|
||||
import * as RefundApi from '@/api/refund'
|
||||
import * as ExpressApi from '@/api/express'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
AuditStatusEnum,
|
||||
RefundStatusEnum,
|
||||
RefundTypeEnum,
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 售后单ID
|
||||
orderRefundId: null,
|
||||
// 售后单详情
|
||||
detail: {},
|
||||
// 物流公司列表
|
||||
expressList: [],
|
||||
// 表单数据
|
||||
formData: {
|
||||
// 物流公司ID
|
||||
expressId: null,
|
||||
// 物流单号
|
||||
expressNo: ''
|
||||
},
|
||||
// 选择的物流公司索引
|
||||
expressIndex: -1,
|
||||
// 按钮禁用
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ orderRefundId }) {
|
||||
// 售后单ID
|
||||
this.orderRefundId = orderRefundId
|
||||
// 获取页面数据
|
||||
this.getPageData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取页面数据
|
||||
getPageData() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getRefundDetail(), app.getExpressList()])
|
||||
.then(result => {
|
||||
app.isLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
// 获取售后单详情
|
||||
getRefundDetail() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
RefundApi.detail(app.orderRefundId)
|
||||
.then(result => {
|
||||
app.detail = result.data.detail
|
||||
resolve()
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取物流公司列表
|
||||
getExpressList() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
ExpressApi.list()
|
||||
.then(result => {
|
||||
app.expressList = result.data.list
|
||||
resolve()
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转商品详情页
|
||||
onGoodsDetail(goodsId) {
|
||||
this.$navTo('pages/goods/detail', { goodsId })
|
||||
},
|
||||
|
||||
// 凭证图片预览
|
||||
handlePreviewImages(index) {
|
||||
const { detail: { images } } = this
|
||||
const imageUrls = images.map(item => item.image_url)
|
||||
uni.previewImage({
|
||||
current: imageUrls[index],
|
||||
urls: imageUrls
|
||||
})
|
||||
},
|
||||
|
||||
// 选择物流公司
|
||||
onChangeExpress(e) {
|
||||
const expressIndex = e.detail.value
|
||||
const { expressList } = this
|
||||
this.expressIndex = expressIndex
|
||||
this.formData.expressId = expressList[expressIndex].express_id
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
onSubmit() {
|
||||
const app = this
|
||||
// 判断是否重复提交
|
||||
if (app.disabled === true) return false
|
||||
// 按钮禁用
|
||||
app.disabled = true
|
||||
// 提交到后端
|
||||
RefundApi.delivery(app.orderRefundId, app.formData)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
setTimeout(() => {
|
||||
app.disabled = false
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
})
|
||||
.catch(err => app.disabled = false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 顶部状态栏
|
||||
.detail-header {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 140rpx;
|
||||
|
||||
.header-backdrop {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 140rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-state {
|
||||
z-index: 1;
|
||||
padding: 0 50rpx;
|
||||
}
|
||||
|
||||
/* 商品详情 */
|
||||
.detail-goods {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.left {
|
||||
.goods-image {
|
||||
display: block;
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.goods-props {
|
||||
margin-top: 14rpx;
|
||||
height: 40rpx;
|
||||
color: #ababab;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-props-item {
|
||||
display: inline-block;
|
||||
margin-right: 14rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #F5F5F5;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-order {
|
||||
padding: 15rpx 20rpx;
|
||||
font-size: 26rpx;
|
||||
|
||||
.item {
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 售后详情 */
|
||||
.detail-refund {
|
||||
padding: 15rpx 20rpx;
|
||||
}
|
||||
|
||||
.detail-refund__row {
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
/* 申请凭证 */
|
||||
.image-list {
|
||||
margin-bottom: -15rpx;
|
||||
|
||||
.image-preview {
|
||||
margin: 0 15rpx 15rpx 0;
|
||||
float: left;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
}
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 商家收货地址 */
|
||||
.detail-address {
|
||||
padding: 20rpx 34rpx;
|
||||
}
|
||||
|
||||
.address-details {
|
||||
padding: 8rpx 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
.address-details__row {
|
||||
margin: 14rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.address-tips {
|
||||
margin-top: 16rpx;
|
||||
line-height: 46rpx;
|
||||
}
|
||||
|
||||
.detail-address__row {
|
||||
// margin: 18rpx 0;
|
||||
}
|
||||
|
||||
/* 填写物流信息 */
|
||||
.detail-express {
|
||||
padding: 10rpx 30rpx;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
height: 60rpx;
|
||||
margin: 14rpx 0;
|
||||
|
||||
.input {
|
||||
height: 100%;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 60rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
color: $main-text;
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
263
pages/refund/index.vue
Executable file
263
pages/refund/index.vue
Executable file
@@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ native: true }" @down="downCallback" :up="upOption"
|
||||
@up="upCallback">
|
||||
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabs" :is-scroll="false" :current="curTab" :active-color="appTheme.mainBg" :duration="0.2" @change="onChangeTab" />
|
||||
|
||||
<!-- 退款/售后单 -->
|
||||
<view class="widget-list">
|
||||
<view class="widget-detail" v-for="(item, index) in list.data" :key="index">
|
||||
<view class="row-block dis-flex flex-y-center">
|
||||
<view class="flex-box">{{ item.create_time }}</view>
|
||||
<view class="flex-box t-r">
|
||||
<text class="col-m">{{ item.state_text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail-goods row-block dis-flex" @click.stop="handleTargetDetail(item.order_refund_id)">
|
||||
<view class="goods-image">
|
||||
<image class="image" :src="item.orderGoods.goods_image" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="goods-right flex-box">
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.orderGoods.goods_name }}</text>
|
||||
</view>
|
||||
<view class="goods-props clearfix">
|
||||
<view class="goods-props-item" v-for="(props, idx) in item.orderGoods.goods_props" :key="idx">
|
||||
<text>{{ props.value.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goods-num t-r">
|
||||
<text class="f-26 col-8">×{{ item.orderGoods.total_num }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail-order row-block">
|
||||
<view class="item dis-flex flex-x-end flex-y-center">
|
||||
<text class="">付款金额:</text>
|
||||
<text class="col-m">¥{{ item.orderGoods.total_pay_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail-operate row-block dis-flex flex-x-end flex-y-center">
|
||||
<view class="detail-btn btn-detail" @click.stop="handleTargetDetail(item.order_refund_id)">查看详情</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</mescroll-body>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
import * as RefundApi from '@/api/refund'
|
||||
|
||||
// 每页记录数量
|
||||
const pageSize = 15
|
||||
|
||||
// tab栏数据
|
||||
const tabs = [{
|
||||
name: '全部',
|
||||
value: -1
|
||||
}, {
|
||||
name: '待处理',
|
||||
value: 0
|
||||
}]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 订单列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
// tabs栏数据
|
||||
tabs,
|
||||
// 当前标签索引
|
||||
curTab: 0,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于2条才显示无更多数据
|
||||
noMoreSize: 2,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无售后单记录'
|
||||
}
|
||||
},
|
||||
// 控制首次触发onShow事件时不刷新列表
|
||||
canReset: false,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
this.canReset && this.onRefreshList()
|
||||
this.canReset = true
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getRefundList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取退款/售后单列表
|
||||
getRefundList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
RefundApi.list({ state: app.getTabValue(), page: pageNo }, { load: false })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新售后单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新订单列表
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
return this.tabs[this.curTab].value
|
||||
},
|
||||
|
||||
// 跳转到售后单详情页
|
||||
handleTargetDetail(orderRefundId) {
|
||||
this.$navTo('pages/refund/detail', { orderRefundId })
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.widget-detail {
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.row-block {
|
||||
padding: 0 20rpx;
|
||||
min-height: 70rpx;
|
||||
}
|
||||
|
||||
.detail-goods {
|
||||
padding: 20rpx;
|
||||
background: #f9f9f9;
|
||||
|
||||
.goods-image {
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-right {
|
||||
padding: 15rpx 0;
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
|
||||
.goods-props {
|
||||
margin-top: 14rpx;
|
||||
height: 40rpx;
|
||||
color: #ababab;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-props-item {
|
||||
display: inline-block;
|
||||
margin-right: 14rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #F5F5F5;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.detail-operate {
|
||||
padding-bottom: 20rpx;
|
||||
|
||||
.detail-btn {
|
||||
border-radius: 4px;
|
||||
border: 1rpx solid #ccc;
|
||||
padding: 8rpx 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #555;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-order {
|
||||
padding: 10rpx 20rpx;
|
||||
font-size: 28rpx;
|
||||
height: 50rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item {
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
601
pages/search/index.vue
Executable file
601
pages/search/index.vue
Executable file
@@ -0,0 +1,601 @@
|
||||
<template>
|
||||
<view class="search">
|
||||
<u-sticky>
|
||||
<view class="search-wrapper">
|
||||
<u-search color="#333333" border-color="#E8E8E8" :showAction="true" actionText="搜索" :animation="false" v-model="where.keywords"
|
||||
@search="onSearch" @custom="onSearch" :actionStyle="actionStyle"></u-search>
|
||||
</view>
|
||||
</u-sticky>
|
||||
<view class="container">
|
||||
<!-- <u-picker :show="showRegion" ref="uPicker" :columns="columns" :columnData="columnData" @confirm="confirm"
|
||||
@change="changeHandler" @cancel="showRegion = false"></u-picker> -->
|
||||
<view class="history">
|
||||
<view class="his-head">
|
||||
<view class="line"></view>
|
||||
<text class="title">基本条件</text>
|
||||
</view>
|
||||
<u-cell-group :border="false">
|
||||
<u-cell title="年龄" isLink :value="where.ageMate" @click="showAgeMate = true"></u-cell>
|
||||
<u-cell title="注册地址" isLink :value="regionMate" @click="onArea"></u-cell>
|
||||
<u-cell title="身高" isLink :value="where.heightMate" @click="showHeightMate = true"></u-cell>
|
||||
<u-cell title="体型" isLink :value="where.shapeMate" @click="showShapeMate = true"></u-cell>
|
||||
<u-cell title="学历" isLink :value="where.educationMate" @click="showEducationMate = true"></u-cell>
|
||||
<u-cell title="年收入" isLink :value="where.monthlyPayMate"
|
||||
@click="showMonthlyPayMate = true"></u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
<view class="history">
|
||||
<view class="his-head">
|
||||
<view class="line"></view>
|
||||
<text class="title">高级搜索</text>
|
||||
</view>
|
||||
<u-cell-group :border="false">
|
||||
<u-cell title="职员" isLink :value="where.vocationMate" @click="showVocationMate = true"></u-cell>
|
||||
<u-cell title="是否有房" isLink :value="where.hasHouseMate" @click="showHasHouseMate = true"></u-cell>
|
||||
<u-cell title="是否有车" isLink :value="where.hasCarMate" @click="showHasCarMate = true"></u-cell>
|
||||
<u-cell title="婚姻状况" isLink :value="where.maritalStatusMate"
|
||||
@click="showMaritalStatusMate = true"></u-cell>
|
||||
<u-cell title="有无小孩" isLink :value="where.hasChildrenMate"
|
||||
@click="showHasChildrenMate = true"></u-cell>
|
||||
<u-cell title="星座" isLink :value="where.constellation" @click="showConstellation = true"></u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
|
||||
<u-picker :show="showAgeMate" :columns="dict.ageMate" @confirm="confirmAgeMate"
|
||||
@cancel="showAgeMate = false"></u-picker>
|
||||
<u-picker :show="showRegionMate" :columns="regionsData" keyName="label" @confirm="confirmRegionMate"
|
||||
@cancel="showRegionMate = false"></u-picker>
|
||||
<u-picker :show="showHeightMate" :columns="dict.heightMate" @confirm="confirmHeightMate"
|
||||
@cancel="showHeightMate = false"></u-picker>
|
||||
<u-picker :show="showShapeMate" :columns="dict.shapeMate" @confirm="confirmShapeMate"
|
||||
@cancel="showShapeMate = false"></u-picker>
|
||||
<u-picker :show="showEducationMate" :columns="dict.educationMate" @confirm="confirmEducationMate"
|
||||
@cancel="showEducationMate = false"></u-picker>
|
||||
<u-picker :show="showMonthlyPayMate" :columns="dict.yearlyPayMate" @confirm="confirmMonthlyPayMate"
|
||||
@cancel="showMonthlyPayMate = false"></u-picker>
|
||||
|
||||
<u-picker :show="showVocationMate" :columns="dict.positionMate" @confirm="confirmVocationMate"
|
||||
@cancel="showVocationMate = false"></u-picker>
|
||||
<u-picker :show="showHasHouseMate" :columns="dict.hasHouseMate" @confirm="confirmHasHouseMate"
|
||||
@cancel="showHasHouseMate = false"></u-picker>
|
||||
<u-picker :show="showHasCarMate" :columns="dict.hasCarMate" @confirm="confirmHasCarMate"
|
||||
@cancel="showHasCarMate = false"></u-picker>
|
||||
<u-picker :show="showMaritalStatusMate" :columns="dict.maritalStatusMate"
|
||||
@confirm="confirmMaritalStatusMate" @cancel="showMaritalStatusMate = false"></u-picker>
|
||||
<u-picker :show="showHasChildrenMate" :columns="dict.hasChildrenMate" @confirm="confirmHasChildrenMate"
|
||||
@cancel="showHasChildrenMate = false"></u-picker>
|
||||
<u-picker :show="showConstellation" :columns="dict.constellation" @confirm="confirmConstellation"
|
||||
@cancel="showConstellation = false"></u-picker>
|
||||
<view class="" style="height: 300rpx;">
|
||||
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<u-button text="开始搜索" color="linear-gradient(to bottom, #010002, #681752)" shape="circle"
|
||||
@click="onSearch"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 地址选择器 -->
|
||||
<liu-customize-sel ref="area" @change="chooseSuccess"> </liu-customize-sel>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as UserProfileApi from '@/api/love-user-profile.js'
|
||||
import * as DictApi from '@/api/dict.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
dict: [],
|
||||
page: 0,
|
||||
regionMate: '不限',
|
||||
where: {
|
||||
ageMate: '不限',
|
||||
regionMate: '不限',
|
||||
heightMate: '不限',
|
||||
shapeMate: '不限',
|
||||
educationMate: '不限',
|
||||
monthlyPayMate: '不限',
|
||||
vocationMate: '不限',
|
||||
hasHouseMate: '不限',
|
||||
hasCarMate: '不限',
|
||||
maritalStatusMate: '不限',
|
||||
hasChildrenMate: '不限',
|
||||
constellation: '不限',
|
||||
random: true
|
||||
},
|
||||
showRegion: false,
|
||||
showAgeMate: false,
|
||||
showRegionMate: false,
|
||||
showHeightMate: false,
|
||||
showShapeMate: false,
|
||||
showEducationMate: false,
|
||||
showMonthlyPayMate: false,
|
||||
showVocationMate: false,
|
||||
showHasHouseMate: false,
|
||||
showHasCarMate: false,
|
||||
showMaritalStatusMate: false,
|
||||
showHasChildrenMate: false,
|
||||
showConstellation: false,
|
||||
// regionsData: [
|
||||
// ['广西壮族自治区'],
|
||||
// ['南宁市', '北海市', '贵港市']
|
||||
// ],
|
||||
// defaultIndex: ['广西壮族自治区','南宁市'],
|
||||
// 控制onShow事件是否刷新订单列表
|
||||
canReset: false,
|
||||
disabled: false,
|
||||
// citys: [],
|
||||
// columns: [],
|
||||
// columnData: []
|
||||
actionStyle: {
|
||||
background: '#8b004c',
|
||||
color: '#ffffff',
|
||||
padding: '12rpx 16rpx',
|
||||
borderRadius: '50rpx'
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
if(!uni.getStorageSync("userId") ||uni.getStorageSync("userId") == 1101){
|
||||
uni.redirectTo({
|
||||
url: "/pages/login/index"
|
||||
})
|
||||
}
|
||||
this.getDict()
|
||||
// this.getCitysData()
|
||||
// 获取历史搜索
|
||||
// this.historySearch = this.getHistorySearch()
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
// 微信小程序需要用此写法
|
||||
this.$refs.datetimePicker.setFormatter(this.formatter)
|
||||
},
|
||||
|
||||
methods: {
|
||||
getDict() {
|
||||
DictApi.listDictionary().then(res => {
|
||||
this.dict = res.data;
|
||||
// this.dict.ageMate[0].unshift('不限')
|
||||
// this.dict.heightMate[0].unshift('不限')
|
||||
// this.dict.shapeMate[0].unshift('不限')
|
||||
// this.dict.positionMate[0].unshift('不限')
|
||||
// this.dict.monthlyPayMate[0].unshift('不限')
|
||||
// this.dict.hasCarMate[0].unshift('不限')
|
||||
// this.dict.hasChildrenMate[0].unshift('不限')
|
||||
// this.dict.hasHouseMate[0].unshift('不限')
|
||||
// this.dict.educationMate[0].unshift('不限')
|
||||
// this.dict.maritalStatusMate[0].unshift('不限')
|
||||
// this.dict.constellation[0].unshift('不限')
|
||||
})
|
||||
},
|
||||
// 读取城市数据
|
||||
// getCitysData() {
|
||||
// const app = this
|
||||
// const { defaultIndex } = this
|
||||
// var province = []
|
||||
// var city = []
|
||||
// var region = []
|
||||
// uni.request({
|
||||
// url: 'https://file.wsdns.cn/json/city.js',
|
||||
// success(result) {
|
||||
// console.log("result: ", result);
|
||||
// const list = result.data
|
||||
// app.citys = list
|
||||
|
||||
// // 默认选中
|
||||
// list.map((d, i) => {
|
||||
// // 收集省份
|
||||
// province.push(d.label)
|
||||
|
||||
// if (i == 0) {
|
||||
// console.log(d);
|
||||
// // 收集城市
|
||||
// d.children.map((d1,i1) => {
|
||||
// console.log("d1: ", d1);
|
||||
// console.log("i1: ",i1);
|
||||
// city.push(d1.label)
|
||||
// // 收集地区
|
||||
// if (i1 == 0) {
|
||||
// d1.children.map(d2 => {
|
||||
// console.log("d2: ",d2);
|
||||
// region.push(d2.label)
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// app.columns = [province,city,region]
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
// changeHandler(e) {
|
||||
// const app = this
|
||||
// const {
|
||||
// columnIndex,
|
||||
// value,
|
||||
// values, // values为当前变化列的数组内容
|
||||
// index,
|
||||
// // 微信小程序无法将picker实例传出来,只能通过ref操作
|
||||
// picker = this.$refs.uPicker
|
||||
// } = e
|
||||
// // 当第一列值发生变化时,变化第二列(后一列)对应的选项
|
||||
// console.log("columnIndex: ",columnIndex);
|
||||
// console.log("e: ",e);
|
||||
// var city = []
|
||||
// if (columnIndex === 0) {
|
||||
// console.log("this.citys[index]: ",app.citys[index].children);
|
||||
// app.citys[index].children.map(d => {
|
||||
// city.push(d.label)
|
||||
// })
|
||||
// console.log("city: ",city);
|
||||
// // picker为选择器this实例,变化第二列对应的选项
|
||||
// picker.setColumnValues(1, city)
|
||||
// }
|
||||
// },
|
||||
// //地址选择成功
|
||||
// confirm(e) {
|
||||
// const data = e.value
|
||||
// this.regionMate = `${data[0].label} ${data[1].label} ${data[2].label}`
|
||||
// this.where.cityMate = data[1].label
|
||||
// this.showRegion = false
|
||||
// },
|
||||
/**
|
||||
* 获取历史搜索
|
||||
*/
|
||||
getHistorySearch() {
|
||||
return uni.getStorageSync(HISTORY_SEARCH) || []
|
||||
},
|
||||
|
||||
onSearch() {
|
||||
if (this.where.ageMate == '不限') {
|
||||
this.where.ageMate = undefined
|
||||
}
|
||||
if (this.where.regionMate == '不限') {
|
||||
this.where.regionMate = undefined
|
||||
}
|
||||
if (this.where.heightMate == '不限') {
|
||||
this.where.heightMate = undefined
|
||||
}
|
||||
if (this.where.shapeMate == '不限') {
|
||||
this.where.shapeMate = undefined
|
||||
}
|
||||
if (this.where.educationMate == '不限') {
|
||||
this.where.educationMate = undefined
|
||||
}
|
||||
if (this.where.monthlyPayMate == '不限') {
|
||||
this.where.monthlyPayMate = undefined
|
||||
}
|
||||
if (this.where.hasHouseMate == '不限') {
|
||||
this.where.hasHouseMate = undefined
|
||||
}
|
||||
if (this.where.vocationMate == '不限') {
|
||||
this.where.vocationMate = undefined
|
||||
}
|
||||
if (this.where.constellation == '不限') {
|
||||
this.where.constellation = undefined
|
||||
}
|
||||
if (this.where.hasChildrenMate == '不限') {
|
||||
this.where.hasChildrenMate = undefined
|
||||
}
|
||||
if (this.where.maritalStatusMate == '不限') {
|
||||
this.where.maritalStatusMate = undefined
|
||||
}
|
||||
if (this.where.hasCarMate == '不限') {
|
||||
this.where.hasCarMate = undefined
|
||||
}
|
||||
this.where.recommend = true
|
||||
this.$push('/sub_pages/member/member', this.where)
|
||||
},
|
||||
|
||||
onArea() {
|
||||
this.$refs.area.open()
|
||||
},
|
||||
//地址选择成功
|
||||
chooseSuccess(e) {
|
||||
const data = e.value
|
||||
this.regionMate = `${data[0].label} ${data[1].label}`
|
||||
this.where.cityMate = data[1].label
|
||||
},
|
||||
|
||||
/**
|
||||
* 记录历史搜索
|
||||
*/
|
||||
setHistory(searchValue) {
|
||||
const data = this.getHistorySearch()
|
||||
const index = data.indexOf(searchValue)
|
||||
index > -1 && data.splice(index, 1)
|
||||
data.unshift(searchValue)
|
||||
this.historySearch = data
|
||||
this.onUpdateStorage()
|
||||
},
|
||||
|
||||
/**
|
||||
* 清空最近搜索记录
|
||||
*/
|
||||
clearSearch() {
|
||||
this.historySearch = []
|
||||
this.onUpdateStorage()
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新历史搜索缓存
|
||||
* @param {Object} data
|
||||
*/
|
||||
onUpdateStorage(data) {
|
||||
uni.setStorageSync(HISTORY_SEARCH, this.historySearch)
|
||||
},
|
||||
// 选择年龄
|
||||
confirmAgeMate(e) {
|
||||
this.where.ageMate = e.value[0]
|
||||
this.showAgeMate = false
|
||||
},
|
||||
confirmRegionMate(e) {
|
||||
this.where.regionMate = e.value[0] + ' ' + e.value[1]
|
||||
this.showRegionMate = false
|
||||
},
|
||||
confirmHeightMate(e) {
|
||||
this.where.heightMate = e.value[0]
|
||||
this.showHeightMate = false
|
||||
},
|
||||
confirmShapeMate(e) {
|
||||
this.where.shapeMate = e.value[0]
|
||||
this.showShapeMate = false
|
||||
},
|
||||
confirmEducationMate(e) {
|
||||
this.where.educationMate = e.value[0]
|
||||
this.showEducationMate = false
|
||||
},
|
||||
confirmMonthlyPayMate(e) {
|
||||
this.where.monthlyPayMate = e.value[0]
|
||||
this.showMonthlyPayMate = false
|
||||
},
|
||||
confirmVocationMate(e) {
|
||||
this.where.vocationMate = e.value[0]
|
||||
this.showVocationMate = false
|
||||
},
|
||||
confirmHasHouseMate(e) {
|
||||
this.where.hasHouseMate = e.value[0]
|
||||
this.showHasHouseMate = false
|
||||
},
|
||||
confirmMaritalStatusMate(e) {
|
||||
this.where.maritalStatusMate = e.value[0]
|
||||
this.showMaritalStatusMate = false
|
||||
},
|
||||
confirmHasCarMate(e) {
|
||||
this.where.hasCarMate = e.value[0]
|
||||
this.showHasCarMate = false
|
||||
},
|
||||
confirmHasChildrenMate(e) {
|
||||
this.where.hasChildrenMate = e.value[0]
|
||||
this.showHasChildrenMate = false
|
||||
},
|
||||
confirmConstellation(e) {
|
||||
this.where.constellation = e.value[0]
|
||||
this.showConstellation = false
|
||||
},
|
||||
|
||||
/**
|
||||
* 跳转到最近搜索
|
||||
*/
|
||||
handleQuick(search) {
|
||||
this.$navTo('pages/goods/list', {
|
||||
search
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.container {
|
||||
// padding: 40rpx;
|
||||
width: 700rpx;
|
||||
margin: 20rpx auto;
|
||||
height: 90vh;
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
height: 64rpx;
|
||||
padding: 20rpx;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.base {
|
||||
margin-top: 40rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.senior {
|
||||
margin-top: 40rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
// 搜索输入框
|
||||
.search-input {
|
||||
width: 80%;
|
||||
background: #fff;
|
||||
height: 72rpx;
|
||||
line-height: 72rpx;
|
||||
border-radius: 10rpx 0 0 10rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.search-input-wrapper {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
width: 60rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.search-icon {
|
||||
display: block;
|
||||
color: #b4b4b4;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
|
||||
input {
|
||||
font-size: 28rpx;
|
||||
height: 72rpx;
|
||||
line-height: 72rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.input-placeholder {
|
||||
color: #aba9a9;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索按钮
|
||||
.search-button {
|
||||
width: 20%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.button {
|
||||
height: 64rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 0 10rpx 10rpx 0;
|
||||
background: $main-bg;
|
||||
color: $main-text;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 最近搜索
|
||||
.history {
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.his-head {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
padding: 50rpx 0 20rpx 0;
|
||||
color: #681752;
|
||||
|
||||
.line {
|
||||
background-color: #681752;
|
||||
width: 8rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.icon {
|
||||
float: right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.his-list {
|
||||
padding: 20rpx 0;
|
||||
overflow: hidden;
|
||||
|
||||
.his-item {
|
||||
width: 33.3%;
|
||||
float: left;
|
||||
padding: 10rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.history-button {
|
||||
text-align: center;
|
||||
padding: 14rpx;
|
||||
line-height: 30rpx;
|
||||
border-radius: 100rpx;
|
||||
background: #fff;
|
||||
font-size: 26rpx;
|
||||
border: 1rpx solid #efefef;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/deep/.u-cell__body{
|
||||
padding: 10px 0 10px 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 50rpx;
|
||||
padding-bottom: 50rpx;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #f3f3f3;
|
||||
padding-top: 20rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
width: 360rpx;
|
||||
margin: auto;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
color: $main-text;
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
198
pages/shop/detail.vue
Executable file
198
pages/shop/detail.vue
Executable file
@@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container">
|
||||
<view class="header">
|
||||
<view class="shop-logo">
|
||||
<image class="image" :src="detail.logo_url"></image>
|
||||
</view>
|
||||
<view class="shop-name">
|
||||
<text>{{ detail.shop_name }}</text>
|
||||
</view>
|
||||
<view v-if="detail.summary" class="shop-summary dis-flex">
|
||||
<text>门店简介:{{ detail.summary }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="content-item dis-flex flex-y-center">
|
||||
<view class="content-item__icon dis-flex">
|
||||
<text class="iconfont icon-shijian"></text>
|
||||
</view>
|
||||
<view class="content-item__text flex-box dis-flex">
|
||||
<text class="f-26">{{ detail.shop_hours }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item dis-flex flex-y-center" @click="onOpenLocation()">
|
||||
<view class="content-item__icon dis-flex">
|
||||
<text class="iconfont icon-dingwei"></text>
|
||||
</view>
|
||||
<view class="content-item__text flex-box dis-flex">
|
||||
<text
|
||||
class="f-26">{{ detail.region.province }}{{ detail.region.city }}{{ detail.region.region }}{{ detail.address }}</text>
|
||||
</view>
|
||||
<view class="content-item__arrow dis-flex">
|
||||
<text class="iconfont icon-arrow-right"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item dis-flex flex-y-center" @click="onMakePhoneCall()">
|
||||
<view class="content-item__icon dis-flex">
|
||||
<text class="iconfont icon-dianhua"></text>
|
||||
</view>
|
||||
<view class="content-item__text flex-box dis-flex">
|
||||
<text class="f-26">{{ detail.phone }}</text>
|
||||
</view>
|
||||
<view class="content-item__arrow dis-flex">
|
||||
<text class="iconfont icon-arrow-right"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import * as ShopApi from '@/api/shop'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 正在加载中
|
||||
isLoading: true,
|
||||
// 当前门店ID
|
||||
shopId: undefined,
|
||||
// 门店详情
|
||||
detail: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 记录当前门店ID
|
||||
this.shopId = options.shopId
|
||||
// 获取门店详情
|
||||
// this.getShopDetail()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取门店详情
|
||||
getShopDetail() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ShopApi.detail(app.shopId)
|
||||
.then(result => app.detail = result.data.detail)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 拨打电话
|
||||
onMakePhoneCall() {
|
||||
const app = this
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: app.detail.phone
|
||||
})
|
||||
},
|
||||
|
||||
// 查看位置
|
||||
onOpenLocation() {
|
||||
const app = this
|
||||
const { detail } = app
|
||||
uni.openLocation({
|
||||
name: detail.shop_name,
|
||||
address: detail.region.province + detail.region.city + detail.region.region + detail.address,
|
||||
longitude: Number(detail.longitude),
|
||||
latitude: Number(detail.latitude),
|
||||
scale: 15
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享当前页面
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({ shopId: app.shopId })
|
||||
return {
|
||||
title: app.detail.shop_name,
|
||||
path: "/pages/shop/detail?" + params
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({ shopId: app.shopId })
|
||||
return {
|
||||
title: app.detail.shop_name,
|
||||
path: "/pages/shop/detail?" + params
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background: #fff;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 1rpx solid #f1f1f1;
|
||||
|
||||
.shop-logo,
|
||||
.shop-name {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.shop-logo {
|
||||
.image {
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 30rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.shop-name {
|
||||
margin-top: 16rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.shop-summary {
|
||||
padding: 20rpx;
|
||||
margin-top: 30rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
background: #f9f9f9;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 30rpx;
|
||||
|
||||
.content-item {
|
||||
padding: 12rpx 0;
|
||||
|
||||
.content-item__text {
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
198
pages/shop/extract.vue
Executable file
198
pages/shop/extract.vue
Executable file
@@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<view class="container b-f">
|
||||
<!-- 门店列表 -->
|
||||
<view class="shop-list">
|
||||
<view v-for="(item, index) in shopList" :key="index" @click="onSelectedShop(item.shop_id)" class="shop-item dis-flex flex-y-center">
|
||||
<view class="shop-item__content flex-box">
|
||||
<view class="shop-item__title">
|
||||
<text>{{ item.shop_name }}</text>
|
||||
</view>
|
||||
<view class="shop-item__address">
|
||||
<text>地址:{{ item.region.province }}{{ item.region.city }}{{ item.region.region }}{{ item.address }}</text>
|
||||
</view>
|
||||
<view class="shop-item__phone">
|
||||
<text>联系电话:{{ item.phone }}</text>
|
||||
</view>
|
||||
<view v-if="item.distance" class="shop-item__distance">
|
||||
<text class="iconfont icon-dingwei"></text>
|
||||
<text class="f-24">{{ item.distance_unit }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 选中状态 -->
|
||||
<view v-if="item.shop_id == selectedId" class="shop-item__right">
|
||||
<text class="iconfont icon-check1"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 定位按钮 -->
|
||||
<view v-if="!isAuthor" class="widget-location dis-flex flex-x-center flex-y-center" @click="onAuthorize()">
|
||||
<text class="iconfont icon-locate"></text>
|
||||
</view>
|
||||
<empty v-if="!shopList.length" :isLoading="isLoading" tips="亲,暂无自提门店哦" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import * as ShopApi from '@/api/shop'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载中
|
||||
isLoading: true,
|
||||
// 是否授权了定位权限
|
||||
isAuthor: true,
|
||||
// 当前选择的门店ID
|
||||
selectedId: null,
|
||||
// 门店列表
|
||||
shopList: []
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ selectedId }) {
|
||||
const app = this
|
||||
// 记录当前选择的门店ID
|
||||
app.selectedId = selectedId ? selectedId : null
|
||||
// 获取默认门店列表
|
||||
// app.getShopList()
|
||||
// 获取用户坐标
|
||||
// app.getLocation(res => {
|
||||
// app.getShopList(res.longitude, res.latitude)
|
||||
// })
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取门店列表
|
||||
getShopList(longitude, latitude) {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ShopApi.list({
|
||||
isCheck: 1,
|
||||
longitude: longitude ? longitude : '',
|
||||
latitude: latitude ? latitude : ''
|
||||
})
|
||||
.then(result => app.shopList = result.data.list)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 授权启用定位权限
|
||||
onAuthorize() {
|
||||
const app = this
|
||||
// #ifdef MP
|
||||
uni.openSetting({
|
||||
success(res) {
|
||||
if (res.authSetting['scope.userLocation']) {
|
||||
console.log('定位权限授权成功')
|
||||
app.isAuthor = true
|
||||
setTimeout(() => {
|
||||
// 获取用户坐标
|
||||
app.getLocation(res => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
// 获取用户坐标
|
||||
app.getLocation(res => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择门店
|
||||
*/
|
||||
onSelectedShop(selectedId) {
|
||||
const app = this
|
||||
// 设置选中的id
|
||||
app.selectedId = selectedId
|
||||
// 相应全局事件订阅: 选择自提门店
|
||||
uni.$emit('syncSelectedId', selectedId)
|
||||
// 返回上级页面
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.shop-list .shop-item {
|
||||
padding: 20rpx 30rpx;
|
||||
min-height: 180rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.5;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.shop-item__title {
|
||||
font-size: 30rpx;
|
||||
color: #535353;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.shop-item__address,
|
||||
.shop-item__phone {
|
||||
color: #919396;
|
||||
}
|
||||
|
||||
.shop-item__distance {
|
||||
margin-top: 10rpx;
|
||||
color: #c1c1c1;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.shop-item__distance .iconfont {
|
||||
color: #81838e;
|
||||
margin-right: 5rpx;
|
||||
}
|
||||
|
||||
// 选中图标
|
||||
.shop-item__right {
|
||||
margin-left: 20rpx;
|
||||
color: #535353;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
// 定位图标
|
||||
.widget-location {
|
||||
position: fixed;
|
||||
right: calc(var(--window-right) + 40rpx);
|
||||
bottom: calc(var(--window-bottom) + 70rpx);
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
z-index: 200;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.2);
|
||||
color: #555;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
</style>
|
||||
264
pages/user/password/password.vue
Normal file
264
pages/user/password/password.vue
Normal file
@@ -0,0 +1,264 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">修改密码</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u--form :model="form" ref="uForm" :rules="rules" label-width="140rpx">
|
||||
<u-form-item label="旧密码" prop="oldPassword">
|
||||
<u--input v-model="form.oldPassword" type="text" maxlength="20" placeholder="请输入旧密码" />
|
||||
</u-form-item>
|
||||
<u-form-item label="新密码" prop="password">
|
||||
<u--input v-model="form.password" type="text" maxlength="20" placeholder="请输入新密码" />
|
||||
</u-form-item>
|
||||
<u-form-item label="确认密码" prop="password2">
|
||||
<u--input v-model="form.password2" type="text" maxlength="20" placeholder="请输入确认密码" />
|
||||
</u-form-item>
|
||||
</u--form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store'
|
||||
import { fileUrl } from '@/config.js'
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import * as UserApi from '@/api/user'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
nickname: [{
|
||||
required: true,
|
||||
message: '请输入用户昵称',
|
||||
trigger: ['blur', 'change']
|
||||
}]
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AvatarImage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
// 头像路径 (用于显示)
|
||||
avatarUrl: '',
|
||||
// 临时图片 (用于上传)
|
||||
tempFile: null,
|
||||
// 表单数据
|
||||
form: {
|
||||
avatarId: '',
|
||||
nickname: ''
|
||||
},
|
||||
// 验证规则
|
||||
rules,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad() {
|
||||
// 获取当前用户信息
|
||||
// this.getUserInfo()
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
getUserInfo() {
|
||||
const { form } = this
|
||||
const app = this
|
||||
UserApi.getUser().then(res => {
|
||||
if( res.code == 0 && res.data.username != 'www') {
|
||||
console.log("获取用户信息: ",res.data);
|
||||
app.form = res.data
|
||||
app.userInfo = res.data
|
||||
store.dispatch('setUserInfo',res.data)
|
||||
app.isLogin = true
|
||||
res.data.roles.map(d => {
|
||||
if(d.roleCode == 'superAdmin'){
|
||||
app.superAdmin = true
|
||||
}
|
||||
if(d.roleCode == 'agent'){
|
||||
app.agent = true
|
||||
}
|
||||
if(d.roleCode == 'admin'){
|
||||
app.isAdmin = true
|
||||
}
|
||||
})
|
||||
}else{
|
||||
app.isLogin = false
|
||||
app.handleLogout()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 点击头像按钮事件
|
||||
onClickAvatar() {
|
||||
// #ifdef MP-WEIXIN
|
||||
return
|
||||
// #endif
|
||||
this.chooseImage()
|
||||
},
|
||||
|
||||
// 选择头像事件 - 仅限微信小程序
|
||||
// #ifdef MP-WEIXIN
|
||||
onChooseAvatar({ detail }) {
|
||||
const app = this
|
||||
app.avatarUrl = detail.avatarUrl
|
||||
app.tempFile = { path: app.avatarUrl }
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 选择图片
|
||||
chooseImage() {
|
||||
const app = this
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success(chooseImageRes) {
|
||||
const tempFilePaths = chooseImageRes.tempFilePaths;
|
||||
UploadApi.uploadFile({
|
||||
filePath: tempFilePaths[0],
|
||||
fileType: 'image',
|
||||
name: 'file'
|
||||
}).then(res => {
|
||||
console.log("res: ", res);
|
||||
app.form.avatar = fileUrl + res.data.path
|
||||
console.log("form: ",app.form);
|
||||
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
return UploadApi.image([app.tempFile])
|
||||
.then(fileIds => {
|
||||
app.form.avatarId = fileIds[0]
|
||||
app.tempFile = null
|
||||
})
|
||||
},
|
||||
|
||||
// 确认修改
|
||||
async handleSubmit() {
|
||||
const app = this
|
||||
// 判断是否重复提交
|
||||
if (app.disabled === true) return
|
||||
app.$refs.uForm.validate(async valid => {
|
||||
if (valid) {
|
||||
// 按钮禁用
|
||||
app.disabled = true
|
||||
// 先上传头像图片
|
||||
if (app.tempFile) {
|
||||
await app.uploadFile()
|
||||
}
|
||||
// 提交保存个人信息
|
||||
UserApi.updatePassword(app.form)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
setTimeout(() => {
|
||||
app.disabled = false
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
})
|
||||
.catch(err => app.disabled = false)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 绑定昵称输入框 (用于微信小程序端快速填写昵称能力)
|
||||
onInputNickName(val) {
|
||||
if (val) {
|
||||
this.form.nickname = val
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.container {}
|
||||
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 90%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
width: 400rpx;
|
||||
margin: auto;
|
||||
background: linear-gradient(to bottom, $main-bg, $main-bg2);
|
||||
color: $main-text;
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
1621
pages/user/user.vue
Normal file
1621
pages/user/user.vue
Normal file
File diff suppressed because it is too large
Load Diff
251
pages/zone/member/member.vue
Normal file
251
pages/zone/member/member.vue
Normal file
@@ -0,0 +1,251 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="user-list">
|
||||
<block v-for="(item,index) in list" :key="index">
|
||||
<view class="item" v-if="item.userInfo" @click="$push('sub_pages/member/detail/detail',{userId: item.userId})">
|
||||
<view class="has-house-num">
|
||||
南宁1套
|
||||
</view>
|
||||
<view class="content">
|
||||
喜欢极限运动,摩托、健身、旅游、看书等,事业单位正式工作,收入稳定,想找个聊得...
|
||||
</view>
|
||||
<view class="user-info">
|
||||
<view class="left">
|
||||
<view class="avatar">
|
||||
<u-avatar size="25" :src="item.userInfo.avatar"
|
||||
customStyle="margin-right:5px; border: 4rpx solid #ffffff;"></u-avatar>
|
||||
<view class="nickname">{{ item.userInfo.nickname }}</view>
|
||||
</view>
|
||||
<view class="desc">
|
||||
南宁 • 31岁 • 20w-30w
|
||||
</view>
|
||||
</view>
|
||||
<view class="follow-btn" @click.stop="onFollow">
|
||||
<image src="@/static/icon/follow.png" mode="widthFix"></image>
|
||||
<text>关注</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-color"></view>
|
||||
<image class="bg" :src="item.userBgImg" mode="aspectFill"></image>
|
||||
|
||||
</view>
|
||||
</block>
|
||||
<!-- <u-list @scrolltolower="scrolltolower">
|
||||
<view class="list">
|
||||
<u-list-item v-for="(item, index) in list" :key="index">
|
||||
<u-cell :title="`${item.userInfo.nickname}`" :label="`粉丝:${ item.id }`" isLink
|
||||
@click="navTo('/pages/member/detail/detail',{userId: item.userId})">
|
||||
<u-avatar slot="icon" size="50" :src="item.userInfo.avatar"
|
||||
customStyle="margin: -3px 5px -3px 0"></u-avatar>
|
||||
<view slot="right-icon" class="follow-btn" @click.stop="onFollow">
|
||||
<image src="@/static/icon/follow.png" mode="widthFix"></image>
|
||||
<text>关注</text>
|
||||
</view>
|
||||
</u-cell>
|
||||
</u-list-item>
|
||||
<u-empty
|
||||
v-if="list.length == 0"
|
||||
mode="search"
|
||||
icon="http://cdn.uviewui.com/uview/empty/car.png"
|
||||
>
|
||||
</u-empty>
|
||||
</view>
|
||||
</u-list> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as UserProfileApi from '@/api/love-user-profile.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
page: 0,
|
||||
where: {},
|
||||
// 控制onShow事件是否刷新订单列表
|
||||
canReset: false,
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.where = options
|
||||
this.onRefreshList()
|
||||
uni.setNavigationBarTitle({
|
||||
title: options.name
|
||||
})
|
||||
},
|
||||
onPullDownRefresh(){
|
||||
const app = this
|
||||
setTimeout(function() {
|
||||
uni.stopPullDownRefresh();
|
||||
app.onRefreshList()
|
||||
}, 500);
|
||||
},
|
||||
methods: {
|
||||
// 刷新会员列表
|
||||
onRefreshList() {
|
||||
const app = this
|
||||
app.where.page = app.page
|
||||
return new Promise((resolve, reject) => {
|
||||
UserProfileApi.pageUserProfile(app.where)
|
||||
.then(result => {
|
||||
const list = result.data.list
|
||||
// 合并新数据
|
||||
app.list = app.list.concat(list)
|
||||
if(result.data.count > app.list.length){
|
||||
app.canReset = true
|
||||
}else{
|
||||
app.canReset = false
|
||||
}
|
||||
// 获取第一张图片作为背景图片
|
||||
list.map((d, i) => {
|
||||
if(!app.list[i].userBgImg){
|
||||
const imgs = JSON.parse(d.images)
|
||||
console.log("imgs: ",imgs);
|
||||
imgs.map(pic => {
|
||||
console.log("pic: ",pic);
|
||||
if (pic.type == 'image') {
|
||||
app.list[i].userBgImg = pic.url
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
resolve(list)
|
||||
})
|
||||
})
|
||||
},
|
||||
scrolltolower(e){
|
||||
console.log("e: ",e);
|
||||
},
|
||||
navTo(url,userId){
|
||||
this.$push(url,userId)
|
||||
},
|
||||
onFollow(e){
|
||||
console.log("e11: ",e);
|
||||
},
|
||||
onSearch(){
|
||||
this.list = []
|
||||
this.where.page = 1
|
||||
this.onRefreshList()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 0 20rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
height: 64rpx;
|
||||
}
|
||||
.user-list{
|
||||
.item{
|
||||
margin: 40rpx auto;
|
||||
width: 660rpx;
|
||||
min-height: 500rpx;
|
||||
background-color: #f3f3f3;
|
||||
border-radius: 15rpx;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
/* 背景叠加 */
|
||||
.bg-color {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
width: 660rpx;
|
||||
height: 365rpx;
|
||||
background-color: #000000;
|
||||
opacity: .2;
|
||||
filter: Alpha(opacity=20);
|
||||
}
|
||||
.bg{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 0;
|
||||
width: 660rpx;
|
||||
}
|
||||
.has-house-num{
|
||||
position: absolute;
|
||||
top: 20rpx;
|
||||
left: 20rpx;
|
||||
z-index: 3;
|
||||
height: 43rpx;
|
||||
line-height: 43rpx;
|
||||
padding: 4rpx 20rpx;
|
||||
color: #ffffff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 40rpx;
|
||||
background: linear-gradient(#47076b, #8d1a50);
|
||||
}
|
||||
.content{
|
||||
width: 640rpx;
|
||||
position: absolute;
|
||||
top: 250rpx;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
padding: 20rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
.user-info{
|
||||
width: 660rpx;
|
||||
height: 100rpx;
|
||||
padding: 20rpx;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
background-color: #1b0121;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.left{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.avatar{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.nickname{
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
color: #999999;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.follow-btn {
|
||||
width: 85rpx;
|
||||
height: 43rpx;
|
||||
padding: 4rpx 20rpx;
|
||||
color: #ffffff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 40rpx;
|
||||
background: linear-gradient(#47076b, #8d1a50);
|
||||
|
||||
image {
|
||||
width: 24rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
171
pages/zone/zone.vue
Normal file
171
pages/zone/zone.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="category" @click="$push('pages/zone/member/member',{name: '有车有房',desc: '0.9w人'})">
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/0036e686027d4994ab03de5cbd0caf34.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/03a95e32bc094c09bf56c3ac3ff78f0d.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/b37e315c128241f69d3a7fa5a54fea23.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/26f0ed191b174478b10a510991d18262.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/60b27769b8bb4a0d822a6219ed8767bc.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/03a95e32bc094c09bf56c3ac3ff78f0d.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="category" @click="$push('pages/zone/member/member',{name: '精选人类90后',desc: '1w+人'})">
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/0036e686027d4994ab03de5cbd0caf34.png" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/03a95e32bc094c09bf56c3ac3ff78f0d.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/b37e315c128241f69d3a7fa5a54fea23.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/26f0ed191b174478b10a510991d18262.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/60b27769b8bb4a0d822a6219ed8767bc.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="item">
|
||||
<image src="https://file.wsdns.cn/thumbnail/20230604/03a95e32bc094c09bf56c3ac3ff78f0d.jpeg" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store/index.js'
|
||||
import * as DictApi from '@/api/dict.js'
|
||||
import * as UserProfileApi from '@/api/love-user-profile.js'
|
||||
|
||||
import mixin from '@/core/mixins/tabbar'
|
||||
export default {
|
||||
mixins: [mixin],
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
name: '有房有车'
|
||||
},
|
||||
{
|
||||
name: '人类精选90后'
|
||||
}
|
||||
],
|
||||
user: {},
|
||||
avatar: '/static/logo.png',
|
||||
nickName: 'Hello',
|
||||
latitude: 22.766777,
|
||||
longitude: 108.375152,
|
||||
scale: 10,
|
||||
isLogin: false,
|
||||
// #ifdef MP-ALIPAY
|
||||
canIUseAuthButton: my.canIUse('button.open-type.getAuthorize'),
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getLocation(res => {
|
||||
if (res.latitude && res.longitude) {
|
||||
app.latitude = res.latitude
|
||||
app.longitude = res.longitude
|
||||
app.scale = 16
|
||||
}
|
||||
})
|
||||
this.getDict()
|
||||
},
|
||||
onShow() {
|
||||
// this.getUserInfo()
|
||||
},
|
||||
methods: {
|
||||
getDict() {
|
||||
DictApi.getDictionaryOptions({dictCode: 'zone'}).then(res => {
|
||||
this.dict = res.data;
|
||||
|
||||
})
|
||||
},
|
||||
getUserInfo() {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
const app = this
|
||||
getUser().then(res => {
|
||||
console.log(res);
|
||||
if (res.code == 0 && res.data) {
|
||||
app.isLogin = true
|
||||
} else {
|
||||
app.$error('请先登录', function() {
|
||||
app.$navTo('pages/login/index');
|
||||
});
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
// 检查是否登录
|
||||
checkLogin() {
|
||||
if (!!store.getters.userId && store.getters.userId != userId) {
|
||||
this.isLogin = true
|
||||
}
|
||||
},
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 跳转页面
|
||||
navTo(url) {
|
||||
this.$navTo(url)
|
||||
},
|
||||
scan() {
|
||||
const app = this
|
||||
this.$navTo('pages/order/get-food/get-food')
|
||||
// 只允许从相机扫码
|
||||
// uni.scanCode({
|
||||
// success (res) {
|
||||
// console.log("res: ",res);
|
||||
// }
|
||||
// })
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.category{
|
||||
width: 681rpx;
|
||||
margin: 30rpx auto;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.item{
|
||||
width: 220rpx;
|
||||
height: 240rpx;
|
||||
overflow: hidden;
|
||||
image{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user