chc 2023-01-09 18:49:54 +08:00
commit 0da7dc6796
21 changed files with 7838 additions and 547 deletions

82
api/im.js Normal file
View File

@ -0,0 +1,82 @@
import { http,Method } from "@/utils/request.js";
import api from "@/config/api.js";
/**
* 获取聊天详情接口
* @param {*} talkId
* @returns
*/
export function getTalk(talkId) {
return http.request({
url: `${api.im}/talk/${talkId}`,
method: Method.GET,
});
}
/**
* 获取与用户的聊天详情
* @param {*} talkId
* @returns
*/
export function getTalkByUser(userId) {
return http.request({
url: `${api.im}/talk/by/user/${userId}`,
method: Method.GET,
});
}
/**
* 获取聊天列表
* @param {*} talkId
* @returns
*/
export function getTalkList(params) {
return http.request({
url: `${api.im}/talk/list`,
method: Method.GET,
params
});
}
/**
* 获取聊天信息接口
* @param {*} params
* @returns
*/
export function getTalkMessage(params) {
return http.request({
url: `${api.im}/message`,
method: Method.GET,
params
});
}
/**
* 获取聊天信息接口
* @param {*} params
* @returns
*/
export function cleanUnreadMessage(params) {
return http.request({
url: `${api.im}/message/clean/unred`,
method: Method.PUT,
params
});
}
// 从商品页点击 客服 跳转 获取商品详情
export function jumpObtain(skuId, goodsId) {
return http.request({
url: `${api.im}/goods/goods/sku/${goodsId}/${skuId}`,
method: Method.GET,
});
}
// 清除未读
// /im/message/clean/unred
export function clearmeaager() {
return http.request({
url: `${api.im}/message/clean/unred`,
method: Method.PUT,
});
}

View File

@ -55,5 +55,17 @@ export function getStoreList(params) {
} }
/**
* 获取自提点信息
* @param id
*/
export function getStoreAddress(storeId,params) {
return http.request({
url: `/store/address/page/${storeId}`,
method: Method.GET,
params
});
}

View File

@ -155,6 +155,18 @@ export function setAddressId(addressId,way) {
}); });
} }
/**
* 设置收货地址ID
* @param addressId
*/
export function setStoreAddressId(storeAddressId,way) {
return http.request({
url: `/trade/carts/storeAddress?storeAddressId=${storeAddressId}&way=${way}`,
method: Method.GET,
needToken: true,
});
}
/** /**
@ -281,3 +293,29 @@ export function reBuy(sn) {
needToken: true, needToken: true,
}); });
} }
/**
* 获取全部配送方式
*/
export function shippingMethodList(params) {
return http.request({
url: `/trade/carts/shippingMethodList`,
method: Method.GET,
needToken: true,
params: params,
});
}
/**
* 提交配送方式
* @param params
*/
export function setShipMethod(params) {
return http.request({
url: "/trade/carts/shippingMethod",
method: Method.PUT,
needToken: true,
params,
});
}

View File

@ -4,8 +4,12 @@
*/ */
// 开发环境 // 开发环境
const dev = { const dev = {
common: "https://common-api.pickmall.cn", common: "http://192.168.0.113:8890",
buyer: "https://buyer-api.pickmall.cn", buyer: "http://192.168.0.113:8898",
im: "http://192.168.0.113:8885",
// common: "https://common-api.pickmall.cn",
// buyer: "https://buyer-api.pickmall.cn",
}; };
// 生产环境 // 生产环境
const prod = { const prod = {
@ -28,6 +32,7 @@ api = prod;
api.buyer += "/buyer"; api.buyer += "/buyer";
api.common += "/common"; api.common += "/common";
api.im += "/im";
export default { export default {
...api, ...api,
}; };

View File

@ -12,7 +12,8 @@ export default {
logo: "https://lilishop-oss.oss-cn-beijing.aliyuncs.com/4c864e133c2944efad1f7282ac8a3b9e.png", //logo地址 logo: "https://lilishop-oss.oss-cn-beijing.aliyuncs.com/4c864e133c2944efad1f7282ac8a3b9e.png", //logo地址
customerServiceMobile: "13161366885", //客服电话 customerServiceMobile: "13161366885", //客服电话
customerServiceEmail: "lili@lili.com", //客服邮箱 customerServiceEmail: "lili@lili.com", //客服邮箱
imWebSrc: "https://im.pickmall.cn", //IM地址 imWebSrc: "http://192.168.0.113:8001/", //IM地址
BASE_WS_URL: "ws://192.168.0.113:8885/lili/webSocket",
enableGetClipboard: true, //是否启用粘贴板获取 scanAuthNavigation 中的链接,如果匹配则会跳转到对应页面 enableGetClipboard: true, //是否启用粘贴板获取 scanAuthNavigation 中的链接,如果匹配则会跳转到对应页面
enableMiniBarStartUpApp: true, //是否在h5中右侧浮空按钮点击启动app enableMiniBarStartUpApp: true, //是否在h5中右侧浮空按钮点击启动app
/** /**

View File

@ -225,6 +225,13 @@
"navigationBarTitleText": "地址管理" "navigationBarTitleText": "地址管理"
} }
}, },
{
"path": "address/storeAddress",
"style": {
"enablePullDownRefresh": true,
"navigationBarTitleText": "自提点"
}
},
{ {
"path": "address/add", "path": "address/add",
"style": { "style": {
@ -267,8 +274,25 @@
} }
} }
}, },
{
"path": "im/index",
"style": {
"app-plus": {
},
"enablePullDownRefresh": true,
"navigationStyle": "custom" //
}
},
{
"path": "im/list",
"style": {
"navigationStyle": "custom", //
"enablePullDownRefresh": true,
"app-plus": {
}
}
},
{ {
"path": "set/feedBack", "path": "set/feedBack",
"style": { "style": {
@ -427,6 +451,7 @@
} }
} }
} }
] ]
}, },

View File

@ -0,0 +1,88 @@
<template>
<view class="address">
<u-empty class="empty" v-if="storeAddressList.length == 0" text="暂无自提地址" mode="address"></u-empty>
<view class="list" v-else>
<view class="item c-content" v-for="(item, index) in storeAddressList" :key="index">
<view class="basic" @click="selectAddressData(item)">
<text>{{ item.addressName }}</text>
<text>{{ item.mobile }}</text>
<view>
<div class="region">
<span>{{ item.address }}</span>
</div>
</view>
</view>
</view>
<view style="height: 100px"></view>
</view>
<u-action-sheet :list="removeList" :tips="tips" v-model="showAction" @click="deleteAddressMessage"></u-action-sheet>
</view>
</template>
<script>
import * as API_Trade from "@/api/trade";
import * as API_Store from "@/api/store.js";
export default {
data() {
return {
storeAddressList: [], //
showAction: false, //
removeList: [
{
text: "确定",
},
],
tips: {
text: "确定要删除该收货人信息吗?",
},
removeId: "", //id
routerVal: "",
params: {
pageNumber: 1,
pageSize: 1000,
},
};
},
onPullDownRefresh() {
//
this.storeAddressList = [];
this.getAddressList();
},
onLoad: function (val) {
this.routerVal = val;
},
onShow() {
this.storeAddressList = [];
this.getAddressList();
},
onHide() {},
methods: {
async selectAddressData(val) {
await API_Trade.setStoreAddressId(val.id, this.routerVal.way);
uni.navigateBack({
delta: 1,
});
},
//
getAddressList() {
uni.showLoading();
API_Store.getStoreAddress(
this.routerVal.storeId,
this.params
).then((res) => {
this.storeAddressList = res.data.result.records;
console.log(this.storeAddressList);
uni.hideLoading();
});
},
},
};
</script>
<style lang="scss" scoped>
@import "./address.scss";
</style>

5803
pages/mine/im/index-app.scss Normal file

File diff suppressed because one or more lines are too long

804
pages/mine/im/index.vue Normal file
View File

@ -0,0 +1,804 @@
<template>
<view class="wrapper">
<u-navbar class="my-title" title-size="32" back-text="" :title="toUser.name"></u-navbar>
<!-- 空盒子用来防止消息过少时 拉起键盘会遮盖消息 -->
<view :animation="anData" style="height:0;">
</view>
<!-- 消息体 -->
<!-- 用来获取消息体高度 -->
<view id="msgList">
<!-- 消息 -->
<view class="flex-column-start" v-for="(item, index) in msgList" :key="index">
<view class="flex-row-start column-time">
<view v-show="compareTime(index, item.createTime)" class="flex-row-start date-text"
v-text="beautifyTime(item.createTime)">
</view>
</view>
<!-- 用户消息 头像可选加入-->
<view v-if="item.my" class="flex justify-end padding-right one-show align-start padding-top">
<!-- <image class="chat-img flex-row-center" :src="'https://ikeeppet.oss-cn-zhangjiakou.aliyuncs.com/028b7818b78c47ef8f87a7faa1098faf.jpg'" mode="aspectFill" ></image> -->
<view class="flex justify-end" style="width: 400rpx;margin-top: 12px;">
<view>
<view class="user-name">{{ user.nickName }}</view>
<view class="margin-left padding-chat bg-user-orang" style="border-radius: 35rpx; ">
<text style="word-break: break-all;" v-if="item.messageType === 'MESSAGE'">{{ item.text }}</text>
<view v-if="item.messageType == 'GOODS'">
<view class="goodsCard u-flex u-row-between u-p-b-0" style="width:100%;margin: 0 0; ">
<view class="imagebox" @click="jumpGoodDelic">
<image class="image" :src="JSON.parse(item.text)['thumbnail']" mode="widthFix"></image>
</view>
<view class="goodsdesc" @click="jumpGoodDelic">
<view class="goodsdesc-name">
<text class="goodsCard_goodNmae">{{
JSON.parse(item.text)['goodsName']
}}</text>
</view>
<view class="goodsdesc-rice" style="margin-top:10rpx; color: orange;"><text
style="font-size:20rpx;">¥{{
JSON.parse(item.text)['price']
}}</text>
</view>
</view>
</view>
</view>
<view v-if="item.messageType === 'ORDER'">
<view class="orderSn">
<text>订单号{{ JSON.parse(item.text)['sn'] }}</text>
<view class="oederList">
<img style="height: 120rpx; width: 120rpx; margin-top: 15rpx;"
:src="JSON.parse(item.text)['groupImages']" mode="widthFix" />
<view class="groupNameOrTime">
<text @click="linkTosOrders(JSON.parse(item.text)['sn'])">{{ JSON.parse(item.text)['groupName']
}}</text>
<view class="orderTime"> <text>{{ JSON.parse(item.text)['paymentTime'] }}</text></view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view>
<u-avatar :src="user.face" :text="user.face ? '' : user.name" bg-color="#DDDDDD"></u-avatar>
<!-- <u-image class="chat-img margin-left" style="height: 100rpx;width: 100rpx;" shape="circle"
:src="user.face || 'https://avatars.dicebear.com/api/initials/' + user.nickName + '.svg?fontSize=38'"
mode="aspectFill"></u-image> -->
</view>
</view>
<!-- 接收人消息 -->
<view v-else class="flex-row-start margin-left margin-top one-show">
<view class="chat-img flex-row-center">
<u-avatar :src="toUser.face" :text="toUser.face ? '' : toUser.name" bg-color="#DDDDDD"></u-avatar>
<!-- <u-image style="height: 100rpx;width: 100rpx;" shape="circle"
:src="toUser.face || 'https://avatars.dicebear.com/api/initials/' + toUser.name + '.svg?fontSize=38'"
mode="aspectFit"></u-image> -->
</view>
<view class="flex" style="width: 500rpx;">
<view>
<view class="other-name">{{ toUser.name }}</view>
<view class="margin-left padding-chat flex-column-start bg-to-color" style="border-radius: 35rpx;">
<text style="word-break: break-all;" v-if="item.messageType === 'MESSAGE'">{{ item.text }}</text>
<view v-if="item.messageType === 'GOODS'">
<view class="goodsCard u-flex u-row-between u-p-b-0" style="width:100%;margin: 0 0; ">
<view class="imagebox" @click="jumpGoodDelic">
<image class="image" :src="JSON.parse(item.text)['thumbnail']" mode="widthFix"></image>
</view>
<view class="goodsdesc" @click="jumpGoodDelic">
<view class="goodsdesc-name">
<text class="goodsCard_goodNmae">{{
JSON.parse(item.text)['goodsName']
}}</text>
</view>
<view class="goodsdesc-rice" style="margin-top:10rpx; color: orange;"><text
style="font-size:20rpx;">¥{{
JSON.parse(item.text)['price']
}}</text>
</view>
</view>
</view>
</view>
<view v-if="item.messageType === 'ORDER'">
<view class="orderSn">
<text>订单号{{ JSON.parse(item.text)['sn'] }}</text>
<view class="oederList">
<img style="height: 120rpx; width: 120rpx; margin-top: 15rpx;"
:src="JSON.parse(item.text)['groupImages']" mode="widthFix" />
<view class="groupNameOrTime">
<text @click="linkTosOrders(JSON.parse(item.text)['sn'])">{{ JSON.parse(item.text)['groupName']
}}</text>
<view class="orderTime"> <text>{{ JSON.parse(item.text)['paymentTime'] }}</text></view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 如果没有聊天记录定位到底部 -->
<view
:style="{ position: msgList.length == 0 ? 'fixed' : '', bottom: msgList.length == 0 ? '50px' : '', width: msgList.length == 0 ? '100%' : '' }">
<view class="cartMessage" v-if="showHide && !localImGoodsId && showHideModel">
<view class="goodsCard u-flex u-row-between u-p-b-0">
<view class="imagebox" @click="jumpGoodDelic">
<image class="image" :src="goodLiistData.thumbnail" mode="widthFix"></image>
</view>
<view class="goodsdesc" @click="jumpGoodDelic">
<view class="goodsdesc-name">
<text class="goodsCard_goodNmae">{{
goodLiistData.goodsName
}}</text>
</view>
<view class="goodsdesc-rice" style="margin-top:10rpx; color: orange;"><text style="font-size:20rpx;">¥{{
goodLiistData.price
}}</text>
</view>
</view>
<view class="cancel" @click="cancenModel">X</view>
<view class="sendGood" @click="sendGoodsMessage">
<view>发送商品</view>
</view>
</view>
</view>
</view>
<!-- loading是显示 -->
<view v-show="msgLoad" class="flex-row-start margin-left margin-top">
<view class="chat-img flex-row-center">
<!-- <image style="height: 75rpx;width: 75rpx;" src="../../static/image/robt.png" mode="aspectFit"></image> -->
</view>
<view class="flex" style="width: 500rpx;">
<view class="margin-left padding-chat flex-column-start"
style="border-radius: 35rpx;background-color: #f9f9f9;">
<view class="cuIcon-loading turn-load" style="font-size: 35rpx;color: #3e9982;">
</view>
</view>
</view>
</view>
<!-- 防止消息底部被遮 -->
<view style="height: 120rpx;">
</view>
</view>
<!-- 底部导航栏 -->
<view class="flex-column-center" style="position: fixed;bottom: -180px;" :animation="animationData">
<view class="bottom-dh-char flex-row-around" style="font-size: 55rpx;">
<!-- vue无法使用软键盘"发送" -->
<input v-model="msg" class="dh-input" type="text" style="background-color: #f0f0f0;" @confirm="sendMessage"
confirm-type="search" placeholder-class="my-neirong-sm" placeholder="用一句简短的话描述您的问题" />
<view @click="sendMessage" class="cu-tag bg-cyan round">
发送
</view>
<!-- <text @click="ckAdd" class="cuIcon-roundaddfill text-brown"></text> -->
</view>
<!-- 附加栏(自定义) -->
<view class="box-normal flex-row-around flex-wrap">
<view class="tb-text">
<view class="cuIcon-form"></view>
<text>问题反馈</text>
</view>
<view class="tb-text">
<view class="cuIcon-form"></view>
<text>人工客服</text>
</view>
</view>
</view>
</view>
</template>
<script>
// rpxpx
var l
//
var wh
//
var mgUpHeight
import { getTalkMessage, getTalkByUser, jumpObtain } from "@/api/im.js";
import SocketService from "@/utils/socket_service.js";
import storage from "@/utils/storage.js";
import { beautifyTime } from "@/utils/filters.js"
export default {
// imGoodId
onUnload () {
storage.setImGoodsLink('')
},
onLoad (options) {
// goodsid
this.showHideModel = options.goodsid
// localimGoodId
this.localImGoodsId = storage.getImGoodsLink()
this.rosolve = options
//
if (this.rosolve.goodsid) {
this.commodityDetails()
}
// msgList
//
// ,
uni.onKeyboardHeightChange(res => {
const query = uni.createSelectorQuery()
query.select('#msgList').boundingClientRect(data => {
// 2,
var up = res.height * 2 - data.height - l * 110
if (up > 0) {
//
this.messageBoxMove(up, 300)
// ,
mgUpHeight = up
}
//
if (res.height == 0) {
this.messageBoxMove(0, 0)
}
}).exec();
})
var query = uni.getSystemInfoSync()
l = query.screenWidth / 750
wh = query.windowHeight
this.srcollHeight = (query.windowHeight - 44) + "px"
this.user = storage.getUserInfo()
this.toUser = storage.getTalkToUser()
if (options.talkId) {
this.params.talkId = options.talkId;
this.getTalkMessage()
} else {
this.getTalk(options.userId)
}
this.ws.connect();
},
onPullDownRefresh () {
this.params.pageNumber = this.params.pageNumber + 1
this.getTalkMessage()
setTimeout(function () {
uni.stopPullDownRefresh();
}, 1000);
},
components: {
beautifyTime
},
data () {
return {
fixed: 'fixed',
bottom: '50px',
width: '100%',
showHideModel: undefined,
localImGoodsId: '',
showHide: true,
msgLoad: false,
anData: {},
animationData: {},
msgList: [],
oldHeight: 0,
params: { //
talkId: '',
pageSize: 10,
pageNumber: 1,
},
goToIndex: 0, //
msg: "",
go: 0,
newMessageNum: 0,
user: {},
toUser: {},
srcollHeight: 0,
ws: new SocketService(),
rosolve: {},
goodLiistData: {}
}
},
watch: {
'ws.callBackMapping': {
handler: function (val) {
val = JSON.parse(val)
if (val.messageResultType == 'MESSAGE') {
this.msgList.push(val.result)
}
this.newMessageNum++;
//
let msg = val
msg.operation_type = 'READ'
this.ws.send(JSON.stringify(msg))
}
}
},
methods: {
//
linkTosOrders (val) {
console.log(val);
uni.navigateTo({
url: '/pages/order/orderDetail?sn=' + val,
});
},
//
jumpGoodDelic () {
uni.navigateTo({
url: `/pages/product/goods?id=${this.rosolve.skuid}&goodsId=${this.rosolve.goodsid}`,
});
},
//
sendGoodsMessage () {
let msg = {
operation_type: "MESSAGE",
to: this.toUser.userId,
from: this.user.id,
message_type: "GOODS",
context: this.goodLiistData,
talk_id: this.params.talkId,
}
this.ws.send(JSON.stringify(msg))
this.msgList.push({ "text": JSON.stringify(this.goodLiistData), "my": true, "messageType": 'GOODS' })
this.showHide = false
storage.setImGoodsLink(this.params.talkId)
//
this.$nextTick(() => {
uni.pageScrollTo({
scrollTop: 2000000,
duration: 0
});
})
},
//
cancenModel () {
this.showHide = false
},
//
commodityDetails () {
jumpObtain(this.rosolve.skuid, this.rosolve.goodsid).then((res) => {
this.goodLiistData = res.data.result.data
})
},
beautifyTime,
// (-->bug)
goPag (kh) {
this.retractBox(0, 250)
if (this.keyHeight != 0) {
if (kh - this.keyHeight > 0) {
this.retractBox(this.keyHeight - kh, 250)
}
}
},
//
messageBoxMove (x, t) {
var animation = uni.createAnimation({
duration: t,
timingFunction: 'linear',
})
this.animation = animation
animation.height(x).step()
this.anData = animation.export()
},
//
msgGo (type) {
console.log(type, 'typetypetype');
const query = uni.createSelectorQuery()
// 100ms
setTimeout(() => {
//
query.select('#msgList').boundingClientRect(data => {
// scorllscorll
if (type == 'up') {
this.go = data.height - this.oldHeight
} else if (type == 'down') {
this.go = data.height - wh + 120
}
// if (this.oldHeight > 0) {
// this.go = data.height - this.oldHeight
// } else {
// // if (data.height - (wh - 32) > 0) {
// this.go = data.height - wh + 120
// }
//
var moveY = wh - data.height
//
if (moveY - mgUpHeight < 0) {
// 00
if (moveY < 0) {
this.messageBoxMove(0, 200)
} else {
//
this.messageBoxMove(moveY, 200)
}
}
uni.pageScrollTo({
scrollTop: this.go,
duration: 0
})
this.oldHeight = data.height
}).exec();
}, 100)
},
//
answer (id) {
// id,index
},
sendMessage () {
//
if (this.msg == "") {
return 0;
}
// msg,my(,穿)
let msg = {
operation_type: "MESSAGE",
to: this.toUser.userId,
from: this.user.id,
message_type: "MESSAGE",
context: this.msg,
talk_id: this.params.talkId,
}
this.ws.send(JSON.stringify(msg))
this.msgList.push({ "text": this.msg, "my": true, "messageType": 'MESSAGE' })
//
let type = 'down';
this.msgGo(type)
//
// this.msgKf(this.msg)
//
this.msg = ""
},
// msgKf(x) {
// // loading
// // this.msgLoad = true
// //
// //
// // setTimeout(() => {
// // // loading
// // this.msgLoad = false
// // // this.msgGo()
// // }, 2000)
// },
//
ckAdd () {
if (!this.showTow) {
this.retractBox(-180, 350)
} else {
this.retractBox(0, 200)
}
this.showTow = !this.showTow
},
hideKey () {
uni.hideKeyboard()
},
// /
retractBox (x, t) {
var animation = uni.createAnimation({
duration: t,
timingFunction: 'ease',
})
this.animation = animation
animation.translateY(x).step()
this.animationData = animation.export()
},
async getTalkMessage () {
let type = '';
await getTalkMessage(this.params).then(res => {
if (res.data.success) {
if (this.msgList.length >= 10) {
this.msgList.unshift(...res.data.result)
type = 'up'
} else {
this.msgList = res.data.result
type = 'down'
}
this.msgList.forEach(item => {
if (item.fromUser === this.user.id) {
item.my = true
}
})
}
})
this.msgGo(type)
},
touchMoreMessage (e) {
if (e.target.scrollTop == 0) {
this.params.pageNumber = this.params.pageNumber + 1
this.getTalkMessage()
}
},
async getTalk (userId) {
getTalkByUser(userId).then(res => {
if (res.data.success) {
this.toUser = res.data.result
this.params.talkId = res.data.result.id
this.getTalkMessage()
}
})
},
//
compareTime (index, datetime) {
if (datetime == undefined) {
return false;
}
if (typeof datetime == "number") {
datetime = this.unixToDate(datetime, "yyyy-MM-dd hh:mm");
}
if (this.msgList[index].is_revoke == 1) {
return false;
}
datetime = datetime.replace(/-/g, "/");
let time = Math.floor(Date.parse(datetime) / 1000);
let currTime = Math.floor(new Date().getTime() / 1000);
// 5
if (currTime - time < 300) return false;
// ,
if (index == this.msgList.length - 1) {
return true;
}
let nextDate
if (this.msgList[index + 1]) {
nextDate = this.msgList[index + 1].createTime.replace(/-/g, "/");
if (nextDate - datetime < 300) return false;
}
return !(
this.unixToDate(new Date(datetime), "{y}-{m}-{d} {h}:{i}") ==
this.unixToDate(new Date(nextDate), "{y}-{m}-{d} {h}:{i}")
);
},
/**
* 将unix时间戳转换为指定格式
* @param unix 时间戳
* @param format 转换格式
* @returns {*|string}
*/
unixToDate (unix, format) {
if (!unix) return unix;
let _format = format || "yyyy-MM-dd hh:mm:ss";
const d = new Date(unix);
const o = {
"M+": d.getMonth() + 1,
"d+": d.getDate(),
"h+": d.getHours(),
"m+": d.getMinutes(),
"s+": d.getSeconds(),
"q+": Math.floor((d.getMonth() + 3) / 3),
S: d.getMilliseconds(),
};
if (/(y+)/.test(_format))
_format = _format.replace(
RegExp.$1,
(d.getFullYear() + "").substr(4 - RegExp.$1.length)
);
for (const k in o)
if (new RegExp("(" + k + ")").test(_format))
_format = _format.replace(
RegExp.$1,
RegExp.$1.length === 1
? o[k]
: ("00" + o[k]).substr(("" + o[k]).length)
);
return _format;
},
}
}
</script>
<style lang="scss" scoped>
.orderTime {
margin-top: 15rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.wrapper {
height: auto !important;
}
.oederList {
display: flex;
color: black;
font-size: 20rpx;
font-weight: bold;
width: 95%;
}
.orderSn {
width: 350rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.groupNameOrTime {
margin: 15rpx 15rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.orderGood {
background-color: #ffffff;
}
.goodsCard {
border-radius: 20rpx;
margin-top: 15rpx;
background-color: #ffffff;
padding-left: 12rpx;
width: 95%;
height: 120rpx;
display: flex;
flex-wrap: wrap;
color: #302c2b;
.imagebox {
width: 122rpx;
height: 122rpx;
.image {
width: 122rpx;
border-radius: 10rpx;
}
}
.goodsdesc {
flex: 1;
overflow: hidden;
margin-left: 12rpx;
.goodsdesc-name {
font-size: 12px;
line-height: 1.5;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin-bottom: 20rpx;
.goodsCard_goodNmae {
color: black;
text-overflow: ellipsis;
font-size: 20rpx;
font-weight: bold;
}
}
.price {
margin-top: 50rpx;
line-height: 2;
margin-left: 5px;
font-size: 26rpx;
font-weight: 700;
}
}
.sendGood {
color: #ffffff;
height: 40rpx;
width: 110rpx;
background-color: #f21c0c;
font-size: 18rpx;
border-radius: 17rpx;
text-align: center;
line-height: 40rpx;
padding: 0 10rpx;
position: relative;
top: 20rpx;
right: 20rpx;
}
}
.cancel {
color: #737373;
position: relative;
bottom: 40rpx;
left: 12%;
}
.cartMessage {
display: flex;
justify-content: center;
align-items: center;
}
.bottom-dh-char {
background-color: #f9f9f9;
width: 750rpx;
height: 110rpx;
}
.user-name {
text-align: right;
font-size: 24rpx;
color: #737373;
margin-bottom: 10rpx;
margin-right: 10rpx;
}
.other-name {
text-align: left;
font-size: 24rpx;
color: #737373;
margin-bottom: 10rpx;
margin-left: 10rpx;
}
.column-time {
justify-content: center;
}
.center-box {
width: 720rpx;
padding-left: 25rpx;
}
.hui-box {
width: 750rpx;
height: 100%;
}
.date-text {
font-size: 12px;
color: grey;
}
.dh-input {
width: 500rpx;
height: 65rpx;
border-radius: 30rpx;
padding-left: 15rpx;
font-size: 35rpx;
background-color: #FFFFFF;
}
.box-normal {
width: 750rpx;
height: 180px;
background-color: #FFFFFF;
}
.tb-text view {
font-size: 65rpx;
}
.tb-text text {
font-size: 25rpx;
color: #737373;
}
.chat-img {
border-radius: 50%;
width: 100rpx;
height: 100rpx;
background-color: #f7f7f7;
}
.padding-chat {
padding: 17rpx 20rpx;
}
.tb-nv {
width: 50rpx;
height: 50rpx;
}
</style>
<style lang="scss" scoped>
@import "./index-app.scss";
</style>

237
pages/mine/im/list.vue Normal file
View File

@ -0,0 +1,237 @@
<template>
<view class="content">
<u-navbar class="my-title" title-size="32" back-text="" :title="'消息(' + talkList.length + ')'"></u-navbar>
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData(tabIndex)">
<!-- 空白页 -->
<u-empty text="暂无信息" mode="list" v-if="talkList.length === 0"></u-empty>
<!-- 消息列表 -->
<div class="iconBox">
<view class="icon-list">
<view class="icon-item" @click="cleanUnread()">
<div class="bag bag1">
<u-icon name="trash" size="50" color="#fff"></u-icon>
</div>
<view>清除未读</view>
</view>
<view class="icon-item" @click="navigateTo('/pages/tabbar/home/title')">
<div class="bag bag2">
<u-icon name="bell" size="50" color="#fff"></u-icon>
</div>
<view>系统消息</view>
</view>
</view>
</div>
<u-search class="nav-search" v-model="userName" clearabled @change="userTalkList()" placeholder="搜索用户"
:show-action="false"></u-search>
<view class="talk-view" :key="index" v-for="(item, index) in talkList">
<view>
<view @click="onclickToTalkInfo(item)">
<view class="talk-item-view">
<view class="talk-img">
<u-avatar :src="item.face" :text="item.face ? '' : item.name" bg-color="#DDDDDD"></u-avatar>
</view>
<view class="talk-info">
<view class="talk-name u-line-2">{{ item.name }}
<u-tag class="talk-tag" size="mini" text="店铺" type="warning" v-if="item.storeFlag" />
</view>
<view class="talk-message">
<span v-if="item.lastMessageType == 'MESSAGE'">{{ item.lastTalkMessage }}</span>
<span v-if="item.lastMessageType == 'GOODS'">[]</span>
<span v-if="item.lastMessageType == 'ORDER'">[]</span>
</view>
</view>
<view class="talk-time">
<view>
{{ beautifyTime(item.lastTalkTime) }}
</view>
<view>
<u-badge type="error" absolute :offset="[45, 20]" :count="item.unread"></u-badge>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import { getTalkList, clearmeaager } from "@/api/im.js";
import storage from "@/utils/storage.js";
import { beautifyTime } from "@/utils/filters.js"
export default {
data () {
return {
count: {
loadStatus: "more",
},
talkList: [], //
userName: '',
pointData: {}, //
};
},
components: {
beautifyTime
},
onShow () {
this.userTalkList();
},
onPullDownRefresh () {
this.userTalkList()
console.log('下拉事件');
setTimeout(function () {
uni.stopPullDownRefresh();
}, 1000);
},
/**
* 触底加载
*/
onReachBottom () {
this.userTalkList();
},
methods: {
beautifyTime,
onclickToTalkInfo (val) {
storage.setTalkToUser(val)
uni.navigateTo({
url:
"/pages/mine/im/index?talkId=" + val.id,
});
},
/**
* 获取聊天列表
*/
userTalkList () {
let params = {
userName: this.userName,
}
uni.showLoading({
title: "加载中",
});
getTalkList(params).then((res) => {
uni.hideLoading();
if (res.data.success) {
this.talkList = res.data.result;
console.log(this.talkList, 'this.talkListthis.talkList');
}
});
},
navigateTo (url) {
uni.navigateTo({
url,
});
},
cleanUnread () {
clearmeaager().then((res) => {
console.log(res);
if (res.data.code == 200) {
this.userTalkList();
uni.showToast({
icon: "none",
title: res.data.message,
});
}
})
},
},
};
</script>
<style lang="scss" scoped>
.talk-view {
border-radius: 20rpx;
background-color: #fff;
.talk-item-view {
display: flex;
flex-wrap: wrap;
flex-direction: row;
padding: 10rpx 20rpx;
.talk-img {
width: 100rpx;
height: 100rpx;
margin-right: 10rpx;
margin-bottom: 10rpx;
}
.talk-info {
padding-left: 30rpx;
flex: 1;
.talk-name {
font-size: 28rpx;
margin-bottom: 10rpx;
font-weight: bold;
color: #333333;
}
.talk-message {
font-size: 28rpx;
margin-top: 10rpx;
color: #888787;
}
.talk-tag {
margin-left: 10rpx;
}
}
}
}
.talk-time {
position: relative;
}
.iconBox {
width: 94%;
margin: 0 3%;
background: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 24rpx 0 rgba($color: #f6f6f6, $alpha: 1);
// transform: translateY(-30rpx);
}
.icon-list {
height: 140rpx;
text-align: center;
font-size: $font-sm;
display: flex;
justify-content: space-around;
align-items: center;
padding: 0 3%;
color: #999;
.icon-item {
position: relative;
line-height: 2em;
width: 96rpx;
:first-child {
font-size: 48rpx;
margin-bottom: 10rpx;
}
}
}
.bag {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
margin: 0 auto;
}
.bag1 {
background: #ff0015;
}
.bag2 {
background: #73AF7C;
}
</style>
<style lang="scss" scoped>
@import "./index-app.scss";
</style>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<!-- 选择地址 --> <!-- 选择地址 -->
<div class="address-box" @click="clickToAddress()"> <div class="address-box" @click="clickToAddress()" v-if="shippingText == 'LOGISTICS'">
<div class="user-box flex"> <div class="user-box flex">
<div class="flex-8"> <div class="flex-8">
<div v-if="!address.id"></div> <div v-if="!address.id"></div>
@ -10,15 +10,8 @@
<!-- 省市区 --> <!-- 省市区 -->
<div class="flex flex-a-c"> <div class="flex flex-a-c">
<span class="default" v-if="address.isDefault"></span> <span class="default" v-if="address.isDefault"></span>
<div <div class="address-list" v-if="address.consigneeAddressPath.length != 0">
class="address-list" <span class="address-item" v-for="(item, index) in address.consigneeAddressPath" :key="index">
v-if="address.consigneeAddressPath.length != 0"
>
<span
class="address-item"
v-for="(item, index) in address.consigneeAddressPath"
:key="index"
>
{{ item }} {{ item }}
</span> </span>
</div> </div>
@ -41,50 +34,53 @@
<div class="bar"></div> <div class="bar"></div>
</div> </div>
<!-- 选择自提点 -->
<div class="address-box" v-if="shippingText == 'SELF_PICK_UP'">
<div @click="clickToStoreAddress()">
<div class="user-box flex">
<div class="flex-8">
<div v-if="!storeAddress"></div>
<div v-else>
<div class="user-address">
<!-- 自提点地址 -->
<div class="user-address-detail wes-2">
{{ storeAddress.address }}
</div>
<!-- 联系手机号 -->
<div>
</div>
</div>
</div>
</div>
<u-icon name="arrow-right" style="color: #bababa"></u-icon>
</div>
<!-- 背景 -->
<div class="bar"></div>
</div>
</div>
<!-- 开团信息 --> <!-- 开团信息 -->
<view class="group-box" v-if="isAssemble"> <view class="group-box" v-if="isAssemble">
<view class="group-title"> <view class="group-title">
<span v-if="pintuanFlage"></span> <span v-if="pintuanFlage"></span>
<span v-else <span v-else><span>{{ routerVal.parentOrder.toBeGroupedNum }}</span>人的团购买</span>
>为你加入仅差<span>{{ routerVal.parentOrder.toBeGroupedNum }}</span
>人的团购买</span
>
</view> </view>
<view class="group"> <view class="group">
<view> <view>
<u-image <u-image borderRadius="50%" shape="square" class="head-img" width="81rpx" height="81rpx"
borderRadius="50%" :src="masterWay.face || '/static/missing-face.png'"></u-image>
shape="square"
class="head-img"
width="81rpx"
height="81rpx"
:src="masterWay.face || '/static/missing-face.png'"
></u-image>
<view class="btn-one">团长</view> <view class="btn-one">团长</view>
</view> </view>
<view class="line"> </view> <view class="line"> </view>
<view> <view>
<!-- 如果有最后一名显示最后一名没有最后一名显示等待参团 --> <!-- 如果有最后一名显示最后一名没有最后一名显示等待参团 -->
<u-image <u-image class="head-img" v-if="endWay.face" :src="endWay.face" borderRadius="50%" shape="square"
class="head-img" width="81rpx" height="81rpx">
v-if="endWay.face"
:src="endWay.face"
borderRadius="50%"
shape="square"
width="81rpx"
height="81rpx"
>
<view slot="loading"></view> <view slot="loading"></view>
</u-image> </u-image>
<u-image <u-image class="head-img" borderRadius="50%" shape="square" v-else width="81rpx" height="81rpx"
class="head-img" :src="endWay.face || '/static/missing-face.png'"></u-image>
borderRadius="50%"
shape="square"
v-else
width="81rpx"
height="81rpx"
:src="endWay.face || '/static/missing-face.png'"
></u-image>
<view class="wait">{{ endWay.nickname || "等待参团" }}</view> <view class="wait">{{ endWay.nickname || "等待参团" }}</view>
</view> </view>
@ -92,11 +88,7 @@
</view> </view>
<!-- 店铺商品信息 --> <!-- 店铺商品信息 -->
<div <div class="box box2" v-for="(item, index) in orderMessage.cartList" :key="index">
class="box box2"
v-for="(item, index) in orderMessage.cartList"
:key="index"
>
<div v-if="item.checked"> <div v-if="item.checked">
<div @click="navigateToStore(item)"> <div @click="navigateToStore(item)">
<div class="store-name"> <div class="store-name">
@ -104,42 +96,25 @@
</div> </div>
</div> </div>
<div class="promotionNotice">{{ item.promotionNotice || "" }}</div> <div class="promotionNotice">{{ item.promotionNotice || "" }}</div>
<div <div class="flex goods-item" v-for="(val, i) in item.checkedSkuList" :key="i">
class="flex goods-item" <div class="goods-image" @click="
v-for="(val, i) in item.checkedSkuList"
:key="i"
>
<div
class="goods-image"
@click="
navigateTo( navigateTo(
'/pages/product/goods?id=' + '/pages/product/goods?id=' +
val.goodsSku.id + val.goodsSku.id +
'&goodsId=' + '&goodsId=' +
val.goodsSku.goodsId val.goodsSku.goodsId
) )
" " :span="3">
:span="3" <u-image borderRadius="10rpx" width="200rpx" height="200rpx" :src="val.goodsSku.thumbnail" alt />
>
<u-image
borderRadius="10rpx"
width="200rpx"
height="200rpx"
:src="val.goodsSku.thumbnail"
alt
/>
</div> </div>
<div <div @click="
@click="
navigateTo( navigateTo(
'/pages/product/goods?id=' + '/pages/product/goods?id=' +
val.goodsSku.id + val.goodsSku.id +
'&goodsId=' + '&goodsId=' +
val.goodsSku.goodsId val.goodsSku.goodsId
) )
" " class="goods-detail">
class="goods-detail"
>
<div class="flex"> <div class="flex">
<p class="goods-name">{{ val.goodsSku.goodsName }}</p> <p class="goods-name">{{ val.goodsSku.goodsName }}</p>
<span class="nums">x{{ val.num }}</span> <span class="nums">x{{ val.num }}</span>
@ -155,33 +130,16 @@
</div> </div>
<u-row> <u-row>
<u-col :offset="0" :span="4">发票信息</u-col> <u-col :offset="0" :span="4">发票信息</u-col>
<u-col <u-col :span="8" class="tipsColor" textAlign="right" @click.native="invoice()">
:span="8" <span v-if="receiptList">{{ receiptList.receiptTitle }} -
class="tipsColor" {{ receiptList.receiptContent }}</span>
textAlign="right"
@click.native="invoice()"
>
<span v-if="receiptList"
>{{ receiptList.receiptTitle }} -
{{ receiptList.receiptContent }}</span
>
<span v-else></span> <span v-else></span>
</u-col> </u-col>
</u-row> </u-row>
<u-row> <u-row>
<u-col <u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :offset="0" :span="9" @click="shippingFlag = true">
v-if="orderMessage.cartTypeEnum != 'VIRTUAL'"
:offset="0"
:span="9"
@click="shippingFlag = true"
>配送
</u-col> </u-col>
<u-col <u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="3" textAlign="right" @click="shippingFlag = true">
v-if="orderMessage.cartTypeEnum != 'VIRTUAL'"
:span="3"
textAlign="right"
@click="shippingFlag = true"
>
{{ {{
shippingMethod.find((e) => { shippingMethod.find((e) => {
return e.value == shippingText; return e.value == shippingText;
@ -190,76 +148,47 @@
</u-col> </u-col>
</u-row> </u-row>
<u-row> <u-row>
<u-col :offset="0" :span="4" class="tl" style="text-align: left" <u-col :offset="0" :span="4" class="tl" style="text-align: left">备注信息</u-col>
>备注信息</u-col
>
<u-col :span="8" textAlign="right"> <u-col :span="8" textAlign="right">
<u-input <u-input style="text-align: right" class="uinput" v-model="remarkVal[index].remark" />
style="text-align: right"
class="uinput"
v-model="remarkVal[index].remark"
/>
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
</div> </div>
<!-- 发票信息 --> <!-- 发票信息 -->
<invoices <invoices :res="receiptList" @callbackInvoice="callbackInvoice" v-if="invoiceFlag" />
:res="receiptList" <u-select @confirm="confirmDistribution" v-model="shippingFlag" v-if="shippingMethod.length != 0"
@callbackInvoice="callbackInvoice" :list="shippingMethod"></u-select>
v-if="invoiceFlag"
/>
<u-select v-model="shippingFlag" :list="shippingMethod"></u-select>
<div class="box box5" v-if="orderMessage.priceDetailDTO"> <div class="box box5" v-if="orderMessage.priceDetailDTO">
<div> <div>
<u-row> <u-row>
<u-col :span="9">商品合计</u-col> <u-col :span="9">商品合计</u-col>
<u-col :span="3" textAlign="right"> <u-col :span="3" textAlign="right">
<span <span>{{ orderMessage.priceDetailDTO.goodsPrice | unitPrice }}</span>
>{{ orderMessage.priceDetailDTO.goodsPrice | unitPrice }}</span
>
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
<div> <div>
<u-row> <u-row v-if="shippingText == 'LOGISTICS'">
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="7" <u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="7"></u-col>
>运费</u-col <u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="5" class="tr tipsColor" textAlign="right">
> <span v-if="orderMessage.priceDetailDTO.freightPrice == 0"></span>
<u-col <span v-else>{{
v-if="orderMessage.cartTypeEnum != 'VIRTUAL'"
:span="5"
class="tr tipsColor"
textAlign="right"
>
<span v-if="orderMessage.priceDetailDTO.freightPrice == 0"
>包邮</span
>
<span v-else
>{{
orderMessage.priceDetailDTO.freightPrice | unitPrice orderMessage.priceDetailDTO.freightPrice | unitPrice
}}</span }}</span>
>
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
<u-row> <u-row>
<u-col :offset="0" :span="9" @click="GET_Discount()"></u-col> <u-col :offset="0" :span="9" @click="GET_Discount()"></u-col>
<u-col <u-col :span="3" v-if="
:span="3"
v-if="
orderMessage.priceDetailDTO && orderMessage.priceDetailDTO &&
orderMessage.priceDetailDTO.couponPrice orderMessage.priceDetailDTO.couponPrice
" " textAlign="right" @click="GET_Discount()">
textAlign="right" <span class="main-color">-{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</span>
@click="GET_Discount()"
>
<span class="main-color"
>-{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</span
>
</u-col> </u-col>
<!-- orderMessage.priceDetailDTO.couponPrice | unitPrice --> <!-- orderMessage.priceDetailDTO.couponPrice | unitPrice -->
<u-col :span="3" v-else textAlign="right" @click="GET_Discount()"> <u-col :span="3" v-else textAlign="right" @click="GET_Discount()">
@ -270,15 +199,10 @@
<div> <div>
<u-row> <u-row>
<u-col :span="9">优惠金额</u-col> <u-col :span="9">优惠金额</u-col>
<u-col <u-col :span="3" textAlign="right" v-if="orderMessage.priceDetailDTO.couponPrice">
:span="3"
textAlign="right"
v-if="orderMessage.priceDetailDTO.couponPrice"
>
<span class="main-color"> <span class="main-color">
-{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</span -{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</span>
></u-col </u-col>
>
<u-col :span="3" textAlign="right" v-else>0.00</u-col> <u-col :span="3" textAlign="right" v-else>0.00</u-col>
</u-row> </u-row>
</div> </div>
@ -286,11 +210,9 @@
<u-row> <u-row>
<u-col :span="6">活动优惠</u-col> <u-col :span="6">活动优惠</u-col>
<u-col :span="6" class="tr tipsColor" textAlign="right"> <u-col :span="6" class="tr tipsColor" textAlign="right">
<span v-if="orderMessage.priceDetailDTO.discountPrice" <span v-if="orderMessage.priceDetailDTO.discountPrice">-{{
>-{{
orderMessage.priceDetailDTO.discountPrice | unitPrice orderMessage.priceDetailDTO.discountPrice | unitPrice
}}</span }}</span>
>
<span v-else>0.00</span> <span v-else>0.00</span>
</u-col> </u-col>
</u-row> </u-row>
@ -299,12 +221,7 @@
<!-- 配送地区没有提示 --> <!-- 配送地区没有提示 -->
<div class="notSupportFreight" v-if="notSupportFreight.length != 0"> <div class="notSupportFreight" v-if="notSupportFreight.length != 0">
<u-notice-bar <u-notice-bar style="width: 100%" :volume-icon="false" mode="horizontal" :list="notSupportFreightGoodsList">
style="width: 100%"
:volume-icon="false"
mode="horizontal"
:list="notSupportFreightGoodsList"
>
</u-notice-bar> </u-notice-bar>
</div> </div>
@ -317,16 +234,12 @@
<span class="price">{{ <span class="price">{{
$options.filters.goodsFormatPrice(orderMessage.priceDetailDTO.flowPrice)[0] $options.filters.goodsFormatPrice(orderMessage.priceDetailDTO.flowPrice)[0]
}}</span> }}</span>
<span <span>.{{ $options.filters.goodsFormatPrice(orderMessage.priceDetailDTO.flowPrice)[1] }}
>.{{ $options.filters.goodsFormatPrice(orderMessage.priceDetailDTO.flowPrice)[1] }}
</span> </span>
</div> </div>
<span v-else class="number" <span v-else class="number"><span style="margin-right: 10rpx">{{
><span style="margin-right: 10rpx">{{
orderMessage.priceDetailDTO.payPoint | unitPrice orderMessage.priceDetailDTO.payPoint | unitPrice
}}</span }}</span>积分</span>
>积分</span
>
</div> </div>
<div class="navRiv" @click="createTradeFun()"> <div class="navRiv" @click="createTradeFun()">
<!-- #ifndef MP-WEIXIN --> <!-- #ifndef MP-WEIXIN -->
@ -361,11 +274,16 @@ export default {
invoiceFlag: false, // invoiceFlag: false, //
shippingText: "LOGISTICS", shippingText: "LOGISTICS",
shippingFlag: false, shippingFlag: false,
shippingMethod: [ shippingMethod: [],
shippingWay: [
{ {
value: "LOGISTICS", value: "LOGISTICS",
label: "物流", label: "物流",
}, },
{
value: "SELF_PICK_UP",
label: "自提",
},
], ],
isAssemble: false, // isAssemble: false, //
couponNums: "", // couponNums: "", //
@ -376,6 +294,7 @@ export default {
couponList: "", couponList: "",
// //
address: "", address: "",
shopAddress: "",
// //
receiptList: "", receiptList: "",
// //
@ -438,11 +357,12 @@ export default {
} }
}, },
onShow() { async onShow() {
uni.showLoading({ uni.showLoading({
mask: true, mask: true,
}); });
this.getOrderList(); await this.getOrderList();
await this.getDistribution();
uni.hideLoading(); uni.hideLoading();
if (this.routerVal.way == "PINTUAN") { if (this.routerVal.way == "PINTUAN") {
this.isAssemble = true; this.isAssemble = true;
@ -481,13 +401,18 @@ export default {
// //
clickToAddress() { clickToAddress() {
this.navigateTo( this.navigateTo(
`/pages/mine/address/address?from=cart&way=${ `/pages/mine/address/address?from=cart&way=${this.routerVal.way
this.routerVal.way
}&parentOrder=${encodeURIComponent( }&parentOrder=${encodeURIComponent(
JSON.stringify(this.routerVal.parentOrder) JSON.stringify(this.routerVal.parentOrder)
)}` )}`
); );
}, },
clickToStoreAddress() {
this.navigateTo(
`/pages/mine/address/storeAddress?from=cart&way=${this.routerVal.way
}&storeId=${this.remarkVal[0].storeId}`
);
},
// //
pintuanWay() { pintuanWay() {
@ -561,6 +486,16 @@ export default {
createTradeFun() { createTradeFun() {
// //
this.$u.throttle(() => { this.$u.throttle(() => {
if (this.shippingText === 'SELF_PICK_UP') {
if (!this.storeAddress.id) {
uni.showToast({
title: "请选择提货点",
duration: 2000,
icon: "none",
});
return false;
}
} else if (this.shippingText === 'LOGISTICS') {
if (!this.address.id) { if (!this.address.id) {
uni.showToast({ uni.showToast({
title: "请选择地址", title: "请选择地址",
@ -569,6 +504,8 @@ export default {
}); });
return false; return false;
} }
}
// //
let client; let client;
// #ifdef H5 // #ifdef H5
@ -653,9 +590,40 @@ export default {
} }
}); });
}, },
//
async getDistribution() {
let shopRes = await API_Trade.shippingMethodList({ way: this.routerVal.way });
let shopList;
if (shopRes.data.success) {
shopList = shopRes.data.result;
let way = [];
console.log(shopList)
this.shippingWay.forEach((item) => {
shopList.forEach((child) => {
if (item.value == child) {
way.push(item);
}
});
});
this.shippingMethod = way;
}
},
//
async confirmDistribution(val) {
let res = await API_Trade.setShipMethod({
shippingMethod: val[0].value,
way: this.routerVal.way,
});
this.shippingText = val[0].value;
if (res.data.success) {
this.getOrderList();
}
},
// //
getOrderList() { async getOrderList() {
this.notSupportFreight = []; this.notSupportFreight = [];
// //
API_Trade.getCheckoutParams(this.routerVal.way).then((res) => { API_Trade.getCheckoutParams(this.routerVal.way).then((res) => {
@ -694,7 +662,9 @@ export default {
res.data.result.memberAddress.consigneeAddressPath = res.data.result.memberAddress.consigneeAddressPath =
res.data.result.memberAddress.consigneeAddressPath.split(","); res.data.result.memberAddress.consigneeAddressPath.split(",");
} }
if (res.data.result.storeAddress) {
this.storeAddress = res.data.result.storeAddress
}
if ( if (
res.data.result.notSupportFreight && res.data.result.notSupportFreight &&
res.data.result.notSupportFreight.length != 0 res.data.result.notSupportFreight.length != 0
@ -725,22 +695,26 @@ page {
.main-color { .main-color {
font-weight: bold; font-weight: bold;
} }
.uinput { .uinput {
/deep/ input { /deep/ input {
text-align: right; text-align: right;
} }
} }
.promotionNotice { .promotionNotice {
font-size: 24rpx; font-size: 24rpx;
margin: 20rpx 0; margin: 20rpx 0;
color: $aider-light-color; color: $aider-light-color;
} }
.nums { .nums {
flex: 2; flex: 2;
color: $light-color; color: $light-color;
text-align: center; text-align: center;
} }
.wait { .wait {
font-size: 22rpx; font-size: 22rpx;
font-family: PingFang SC, PingFang SC-Regular; font-family: PingFang SC, PingFang SC-Regular;
@ -756,6 +730,7 @@ page {
width: 143rpx; width: 143rpx;
border-bottom: 2px dotted #999; border-bottom: 2px dotted #999;
} }
.tabbar-left { .tabbar-left {
margin-left: 32rpx; margin-left: 32rpx;
} }
@ -808,6 +783,7 @@ page {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.tr { .tr {
text-align: right; text-align: right;
} }
@ -830,6 +806,7 @@ page {
.box2 { .box2 {
margin-top: 20rpx; margin-top: 20rpx;
} }
.notSupportFreight { .notSupportFreight {
position: fixed; position: fixed;
@ -849,6 +826,7 @@ page {
margin: 0 32rpx; margin: 0 32rpx;
} }
} }
/deep/ .u-notice-bar-wrap { /deep/ .u-notice-bar-wrap {
width: 100% !important; width: 100% !important;
} }
@ -926,6 +904,7 @@ page {
color: $main-color; color: $main-color;
font-size: 26rpx; font-size: 26rpx;
font-weight: bold; font-weight: bold;
>span { >span {
font-size: 36rpx; font-size: 36rpx;
} }
@ -936,6 +915,7 @@ page {
color: $main-color; color: $main-color;
font-size: 28rpx; font-size: 28rpx;
font-weight: bold; font-weight: bold;
>.goods-price { >.goods-price {
font-size: 38rpx; font-size: 38rpx;
padding: 0 2rpx; padding: 0 2rpx;
@ -977,6 +957,7 @@ page {
text-align: left; text-align: left;
overflow: hidden; overflow: hidden;
} }
.default { .default {
background: $main-color; background: $main-color;
font-size: 24rpx; font-size: 24rpx;
@ -985,6 +966,7 @@ page {
color: #fff; color: #fff;
margin-right: 20rpx; margin-right: 20rpx;
} }
.address-box { .address-box {
border-radius: 40rpx; border-radius: 40rpx;
border-top-left-radius: 0 !important; border-top-left-radius: 0 !important;
@ -999,9 +981,11 @@ page {
font-weight: normal; font-weight: normal;
letter-spacing: 1rpx; letter-spacing: 1rpx;
} }
.user-box { .user-box {
padding: 32rpx; padding: 32rpx;
} }
.user-address-detail { .user-address-detail {
color: #333; color: #333;
font-size: 38rpx; font-size: 38rpx;
@ -1009,13 +993,16 @@ page {
margin: 20rpx 0; margin: 20rpx 0;
letter-spacing: 1rpx; letter-spacing: 1rpx;
} }
.mobile { .mobile {
margin-left: 20rpx; margin-left: 20rpx;
} }
.price { .price {
font-size: 50rpx !important; font-size: 50rpx !important;
margin: 0 2rpx; margin: 0 2rpx;
} }
.goods-detail { .goods-detail {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -1023,12 +1010,14 @@ page {
justify-content: center; justify-content: center;
flex: 8; flex: 8;
margin-left: 20rpx !important; margin-left: 20rpx !important;
>p { >p {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
} }
.goods-item { .goods-item {
margin: 20rpx 0; margin: 20rpx 0;
} }

View File

@ -814,3 +814,4 @@ page,
height: 60rpx; height: 60rpx;
} }
</style> </style>

View File

@ -30,7 +30,7 @@
</view> </view>
<!-- 地址 --> <!-- 地址 -->
<view class="info-view"> <view class="info-view" v-if="order.deliveryMethod == 'LOGISTICS'">
<view class="address-view"> <view class="address-view">
<view> <view>
<view class="address-title"> <view class="address-title">
@ -42,6 +42,21 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 提货地址 -->
<view class="info-view" v-if="order.deliveryMethod == 'SELF_PICK_UP'">
<view class="address-view">
<view>
<view class="address-title">
自提点地址:<span>{{ order.storeAddressPath }}</span>
</view>
<view class="address-title">
联系方式:<span>{{ order.storeAddressMobile }}</span>
</view>
</view>
</view>
</view>
<!-- 商品信息 --> <!-- 商品信息 -->
<view> <view>
<view class="seller-view"> <view class="seller-view">
@ -49,7 +64,8 @@
<view class="seller-info u-flex u-row-between"> <view class="seller-info u-flex u-row-between">
<view class="seller-name" @click="tostore(order)"> <view class="seller-name" @click="tostore(order)">
<view class="name">{{ order.storeName }}</view> <view class="name">{{ order.storeName }}</view>
<view class="status" v-if="orderStatusList[order.orderStatus]"> {{ orderStatusList[order.orderStatus].title }}</view> <view class="status" v-if="orderStatusList[order.orderStatus]"> {{ orderStatusList[order.orderStatus].title
}}</view>
</view> </view>
<view class="order-sn"></view> <view class="order-sn"></view>
</view> </view>
@ -70,7 +86,8 @@
<view>x{{ sku.num }}</view> <view>x{{ sku.num }}</view>
<view class="good-complaint"> <view class="good-complaint">
<u-tag size="mini" mode="plain" @click="complaint(sku)" v-if="sku.complainStatus == 'NO_APPLY'" text="投诉" type="info" /> <u-tag size="mini" mode="plain" @click="complaint(sku)" v-if="sku.complainStatus == 'NO_APPLY'"
text="投诉" type="info" />
</view> </view>
</view> </view>
</view> </view>
@ -111,9 +128,12 @@
<view class="title">服务</view> <view class="title">服务</view>
</view> </view>
<view class="customer-list"> <view class="customer-list">
<view class="customer-service" v-if="orderDetail.allowOperationVO && orderDetail.allowOperationVO.cancel == true" @click="onCancel(order.sn)"></view> <view class="customer-service"
v-if="orderDetail.allowOperationVO && orderDetail.allowOperationVO.cancel == true"
@click="onCancel(order.sn)">取消订单</view>
<view class="customer-service" v-if="order.orderStatus == 'DELIVERED'" @click="onLogistics(order)"></view> <view class="customer-service" v-if="order.orderStatus == 'DELIVERED'" @click="onLogistics(order)"></view>
<view class="customer-service" v-if="order.orderStatus != 'UNPAID' && order.orderPromotionType =='PINTUAN' " @click="ByUserMessage(order)"></view> <view class="customer-service" v-if="order.orderStatus != 'UNPAID' && order.orderPromotionType == 'PINTUAN'"
@click="ByUserMessage(order)">查看拼团信息</view>
</view> </view>
</view> </view>
</view> </view>
@ -175,13 +195,16 @@
<view> <view>
<!-- 全部 --> <!-- 全部 -->
<!-- 等待付款 --> <!-- 等待付款 -->
<u-button type="error" ripple size="mini" v-if=" order.allowOperationVO && order.allowOperationVO.pay" @click="toPay(order)"></u-button> <u-button type="error" ripple size="mini" v-if="order.allowOperationVO && order.allowOperationVO.pay"
@click="toPay(order)">立即付款</u-button>
<!-- <u-button class="rebuy-btn" size="mini" v-if="order.order_operate_allowable_vo.allow_service_cancel"> </u-button> --> <!-- <u-button class="rebuy-btn" size="mini" v-if="order.order_operate_allowable_vo.allow_service_cancel"> </u-button> -->
<!-- <div class="pay-btn">确认收货</div> --> <!-- <div class="pay-btn">确认收货</div> -->
<u-button shape="circle" ripple type="warning" size="mini" v-if="order.orderStatus == 'DELIVERED'" @click="onRog(order.sn)"></u-button> <u-button shape="circle" ripple type="warning" size="mini" v-if="order.orderStatus == 'DELIVERED'"
@click="onRog(order.sn)">确认收货</u-button>
<!-- 交易完成 未评价 --> <!-- 交易完成 未评价 -->
<u-button shape="circle" ripple size="mini" v-if="order.orderStatus == 'COMPLETE'" @click="onComment(order.sn)"></u-button> <u-button shape="circle" ripple size="mini" v-if="order.orderStatus == 'COMPLETE'"
@click="onComment(order.sn)">评价商品</u-button>
</view> </view>
</view> </view>
</view> </view>
@ -193,7 +216,8 @@
<u-radio-group v-model="reason"> <u-radio-group v-model="reason">
<view class="value"> <view class="value">
<view class="radio-view" v-for="(item, index) in cancelList" :key="index"> <view class="radio-view" v-for="(item, index) in cancelList" :key="index">
<u-radio :active-color="lightColor" label-size="25" shape="circle" :name="item.reason" @change="reasonChange">{{ item.reason }}</u-radio> <u-radio :active-color="lightColor" label-size="25" shape="circle" :name="item.reason"
@change="reasonChange">{{ item.reason }}</u-radio>
</view> </view>
</view> </view>
</u-radio-group> </u-radio-group>
@ -204,10 +228,12 @@
</view> </view>
</u-popup> </u-popup>
<u-toast ref="uToast" /> <u-toast ref="uToast" />
<u-modal v-model="rogShow" :show-cancel-button="true" :content="'是否确认收货?'" :confirm-color="lightColor" @confirm="confirmRog"></u-modal> <u-modal v-model="rogShow" :show-cancel-button="true" :content="'是否确认收货?'" :confirm-color="lightColor"
@confirm="confirmRog"></u-modal>
<!-- 分享 --> <!-- 分享 -->
<shares v-if="shareFlage " :thumbnail="orderDetail.orderItems[0].image" :goodsName="orderDetail.orderItems[0].goodsName" @close="shareFlage = false" /> <shares v-if="shareFlage" :thumbnail="orderDetail.orderItems[0].image"
:goodsName="orderDetail.orderItems[0].goodsName" @close="shareFlage = false" />
</view> </view>
</template> </template>
@ -255,6 +281,10 @@ export default {
title: "已完成", title: "已完成",
value: "订单已完成,祝您生活愉快", value: "订单已完成,祝您生活愉快",
}, },
STAY_PICKED_UP: {
title: "待自提",
value: "商品正在等待提取",
},
TAKE: { TAKE: {
title: "待核验", title: "待核验",
}, },
@ -272,7 +302,6 @@ export default {
}, },
onLoad(options) { onLoad(options) {
this.loadData(options.sn); this.loadData(options.sn);
this.loadLogistics(options.sn);
this.sn = options.sn; this.sn = options.sn;
}, },
methods: { methods: {
@ -304,7 +333,7 @@ export default {
this.orderGoodsList[0].goodsId, this.orderGoodsList[0].goodsId,
}); });
}, },
loadData(sn) { async loadData(sn) {
uni.showLoading({ uni.showLoading({
title: "加载中", title: "加载中",
}); });
@ -313,9 +342,12 @@ export default {
this.order = order.order; this.order = order.order;
this.orderGoodsList = order.orderItems; this.orderGoodsList = order.orderItems;
this.orderDetail = res.data.result; this.orderDetail = res.data.result;
if (this.order.deliveryMethod === 'LOGISTICS') {
this.loadLogistics()
}
uni.hideLoading(); uni.hideLoading();
}); });
}, },
onReceipt(val) { onReceipt(val) {
uni.navigateTo({ uni.navigateTo({
@ -491,9 +523,11 @@ export default {
<style lang="scss"> <style lang="scss">
@import "./goods.scss"; @import "./goods.scss";
.empty { .empty {
width: 100%; width: 100%;
} }
.customer-service { .customer-service {
background: #ededed; background: #ededed;
// padding: 12rpx 40rpx; // padding: 12rpx 40rpx;
@ -506,51 +540,58 @@ export default {
font-size: 24rpx; font-size: 24rpx;
border-radius: 10rpx; border-radius: 10rpx;
} }
.customer-list { .customer-list {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
.logi-view { .logi-view {
justify-content: space-between; justify-content: space-between;
padding: 30rpx !important; padding: 30rpx !important;
margin: 0 !important; margin: 0 !important;
transform: translateY(-10px); transform: translateY(-10px);
} }
.order-status { .order-status {
color: #fff; color: #fff;
width: 100%; width: 100%;
text-align: center; text-align: center;
font-size: 36rpx; font-size: 36rpx;
margin-top: 40rpx; margin-top: 40rpx;
>div { >div {
font-size: 24rpx; font-size: 24rpx;
margin-top: 10rpx; margin-top: 10rpx;
} }
} }
.logi-List-title { .logi-List-title {
margin-bottom: 10rpx; margin-bottom: 10rpx;
font-size: 26rpx; font-size: 26rpx;
} }
.logi-List-time { .logi-List-time {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
} }
.info-detail { .info-detail {
margin-right: 30rpx; margin-right: 30rpx;
color: #333; color: #333;
} }
.order-view { .order-view {
margin: 0 !important; margin: 0 !important;
border-radius: 0 !important; border-radius: 0 !important;
width: 100%; width: 100%;
height: 200rpx; height: 200rpx;
padding: 0 !important; padding: 0 !important;
background-image: linear-gradient( background-image: linear-gradient(to right,
to right,
$light-color 0%, $light-color 0%,
$aider-light-color 100% $aider-light-color 100%) !important;
) !important;
} }
page, page,
.content { .content {
background: #f1f1f1; background: #f1f1f1;
@ -575,18 +616,22 @@ page,
padding: 16rpx 0rpx; padding: 16rpx 0rpx;
} }
} }
.seller-view { .seller-view {
margin: 20rpx 0; margin: 20rpx 0;
padding: 15rpx 0; padding: 15rpx 0;
border-radius: 30rpx; border-radius: 30rpx;
} }
.address-title { .address-title {
font-size: 26rpx; font-size: 26rpx;
font-weight: bold; font-weight: bold;
>span { >span {
margin-right: 20rpx; margin-right: 20rpx;
} }
} }
.info-view { .info-view {
display: flex; display: flex;
margin: 0 0 20rpx 0; margin: 0 0 20rpx 0;
@ -654,10 +699,12 @@ page,
} }
} }
} }
.verificationCode { .verificationCode {
font-weight: bold; font-weight: bold;
letter-spacing: 2rpx; letter-spacing: 2rpx;
} }
.bottom_view { .bottom_view {
width: 100%; width: 100%;
height: 100rpx; height: 100rpx;

View File

@ -6,55 +6,27 @@
<!-- 仅h5有效 打开App --> <!-- 仅h5有效 打开App -->
<!-- 分享 --> <!-- 分享 -->
<shares <shares v-if="enableShare && goodsDetail.id" :skuId="this.routerVal.id" :goodsId="this.routerVal.goodsId" :link="
v-if="enableShare && goodsDetail.id"
:skuId="this.routerVal.id"
:goodsId="this.routerVal.goodsId"
:link="
'/pages/product/goods?id=' + '/pages/product/goods?id=' +
this.routerVal.id + this.routerVal.id +
'&goodsId=' + '&goodsId=' +
this.routerVal.goodsId this.routerVal.goodsId
" " :thumbnail="goodsDetail.thumbnail" :goodsName="goodsDetail.goodsName" type="goods" @close="enableShare = false" />
:thumbnail="goodsDetail.thumbnail" <popups v-model="popupsSwitch" @tapPopup="handleNavbarList" :popData="navbarListData" :x="navbarListX"
:goodsName="goodsDetail.goodsName" :y="navbarListY" placement="top-start" />
type="goods"
@close="enableShare = false"
/>
<popups
v-model="popupsSwitch"
@tapPopup="handleNavbarList"
:popData="navbarListData"
:x="navbarListX"
:y="navbarListY"
placement="top-start"
/>
<view class="index"> <view class="index">
<!-- topBar --> <!-- topBar -->
<u-navbar <u-navbar :background="navbar" :is-back="false" :class="headerFlag ? 'header' : 'header bg-none scroll-hide'">
:background="navbar"
:is-back="false"
:class="headerFlag ? 'header' : 'header bg-none scroll-hide'"
>
<div class="headerRow"> <div class="headerRow">
<div class="backs"> <div class="backs">
<u-icon @click="back()" name="arrow-left" class="icon-back"></u-icon> <u-icon @click="back()" name="arrow-left" class="icon-back"></u-icon>
<u-icon <u-icon name="list" @click="popupsSwitch = !popupsSwitch" class="icon-list"></u-icon>
name="list"
@click="popupsSwitch = !popupsSwitch"
class="icon-list"
></u-icon>
</div> </div>
<div class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scroll-hide'"> <div class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scroll-hide'">
<div class="headerRow"> <div class="headerRow">
<div <div class="nav-item" v-for="header in headerList" :key="header.id"
class="nav-item" :class="{ cur: scrollId === header.id }" @click="headerTab(header.id)">
v-for="header in headerList"
:key="header.id"
:class="{ cur: scrollId === header.id }"
@click="headerTab(header.id)"
>
{{ header.text }} {{ header.text }}
</div> </div>
</div> </div>
@ -62,57 +34,26 @@
</div> </div>
</u-navbar> </u-navbar>
<u-navbar <u-navbar :border-bottom="false" v-show="!headerFlag" class="header-only-back" :background="navbarOnlyBack"
:border-bottom="false" :is-back="false">
v-show="!headerFlag"
class="header-only-back"
:background="navbarOnlyBack"
:is-back="false"
>
<div> <div>
<div class="bg-back"> <div class="bg-back">
<u-icon <u-icon size="40" @click="back()" name="arrow-left" class="icon-back"></u-icon>
size="40" <u-icon size="40" @click="popupsSwitch = !popupsSwitch" name="list" class="icon-list"></u-icon>
@click="back()"
name="arrow-left"
class="icon-back"
></u-icon>
<u-icon
size="40"
@click="popupsSwitch = !popupsSwitch"
name="list"
class="icon-list"
></u-icon>
</div> </div>
</div> </div>
</u-navbar> </u-navbar>
</view> </view>
<view <view class="product-container" :style="{ height: productRefHeight }" ref="productRef" id="productRef">
class="product-container" <scroll-view scroll-anchoring enableBackToTop="true" scroll-with-animation scroll-y class="scroll-page"
:style="{ height: productRefHeight }" :scroll-top="tabScrollTop" @scroll="pageScroll">
ref="productRef"
id="productRef"
>
<scroll-view
scroll-anchoring
enableBackToTop="true"
scroll-with-animation
scroll-y
class="scroll-page"
:scroll-top="tabScrollTop"
@scroll="pageScroll"
>
<view> <view>
<!-- 轮播图 --> <!-- 轮播图 -->
<GoodsSwiper id="main1" :res="imgList" /> <GoodsSwiper id="main1" :res="imgList" />
<!-- 促销活动条 --> <!-- 促销活动条 -->
<PromotionAssembleLayout <PromotionAssembleLayout v-if="PromotionList" :detail="goodsDetail" :res="PromotionList" />
v-if="PromotionList"
:detail="goodsDetail"
:res="PromotionList"
/>
<view class="card-box top-radius-0" id="main2"> <view class="card-box top-radius-0" id="main2">
<!-- 活动不显示价钱 --> <!-- 活动不显示价钱 -->
@ -122,11 +63,7 @@
{{ goodsDetail.goodsName || "" }} {{ goodsDetail.goodsName || "" }}
</view> </view>
<view class="favorite" @click="clickFavorite(goodsDetail.id)"> <view class="favorite" @click="clickFavorite(goodsDetail.id)">
<u-icon <u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" :name="favorite ? 'heart-fill' : 'heart'">
size="30"
:color="favorite ? '#f2270c' : '#262626'"
:name="favorite ? 'heart-fill' : 'heart'"
>
</u-icon> </u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ <view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{
favorite ? "已收藏" : "收藏" favorite ? "已收藏" : "收藏"
@ -147,12 +84,21 @@
<span> <span>
<span v-if="wholesaleList.length"> <span v-if="wholesaleList.length">
<span>¥</span><span class="price">{{ $options.filters.goodsFormatPrice(wholesaleList[wholesaleList.length-1].price)[0] }}</span>.{{ $options.filters.goodsFormatPrice(wholesaleList[wholesaleList.length-1].price)[1] }} <span>¥</span><span class="price">{{
$options.filters.goodsFormatPrice(wholesaleList[wholesaleList.length - 1].price)[0]
}}</span>.{{
$options.filters.goodsFormatPrice(wholesaleList[wholesaleList.length - 1].price)[1]
}}
~ ~
<span>¥</span><span class="price">{{ $options.filters.goodsFormatPrice(wholesaleList[0].price)[0] }}</span>.{{ $options.filters.goodsFormatPrice(wholesaleList[0].price)[1] }} <span>¥</span><span class="price">{{
$options.filters.goodsFormatPrice(wholesaleList[0].price)[0]
}}</span>.{{
$options.filters.goodsFormatPrice(wholesaleList[0].price)[1]
}}
</span> </span>
<span v-else> <span v-else>
<span>¥</span><span class="price">{{ $options.filters.goodsFormatPrice(goodsDetail.price)[0] }}</span>.{{ $options.filters.goodsFormatPrice(goodsDetail.price)[1] }} <span>¥</span><span class="price">{{ $options.filters.goodsFormatPrice(goodsDetail.price)[0]
}}</span>.{{ $options.filters.goodsFormatPrice(goodsDetail.price)[1] }}
</span> </span>
</span> </span>
</view> </view>
@ -165,11 +111,8 @@
<view>分享</view> <view>分享</view>
</view> </view>
<view class="icons" @click="clickFavorite(goodsDetail.id)"> <view class="icons" @click="clickFavorite(goodsDetail.id)">
<u-icon <u-icon size="30" :color="favorite ? '#f2270c' : '#262626'"
size="30" :name="favorite ? 'heart-fill' : 'heart'"></u-icon>
:color="favorite ? '#f2270c' : '#262626'"
:name="favorite ? 'heart-fill' : 'heart'"
></u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ <view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{
favorite ? "已收藏" : "收藏" favorite ? "已收藏" : "收藏"
}}</view> }}</view>
@ -199,22 +142,16 @@
</view> </view>
<!-- 拼团用户列表 --> <!-- 拼团用户列表 -->
<PromotionAssembleListLayout <PromotionAssembleListLayout v-if="isGroup" @to-assemble-buy-now="toAssembleBuyNow" :res="PromotionList" />
v-if="isGroup"
@to-assemble-buy-now="toAssembleBuyNow"
:res="PromotionList"
/>
<!-- 配置地址 如果是虚拟产品的时候不展示 --> <!-- 配置地址 如果是虚拟产品的时候不展示 -->
<view class="card-box" v-if="goodsDetail.goodsType != 'VIRTUAL_GOODS'"> <view class="card-box" v-if="goodsDetail.goodsType != 'VIRTUAL_GOODS'">
<view class="card-flex" @click="shutMask(4)"> <view class="card-flex" @click="shutMask(4)">
<view class="card-title"> 已选 </view> <view class="card-title"> 已选 </view>
<view class="card-content"> <view class="card-content">
<span v-if="selectedGoods.spec" <span v-if="selectedGoods.spec">{{ selectedGoods.spec.specName }}-{{
>{{ selectedGoods.spec.specName }}-{{
selectedGoods.spec.specValue selectedGoods.spec.specValue
}}</span }}</span>
>
<span v-else></span> <span v-else></span>
</view> </view>
<view class="card-bottom"> <view class="card-bottom">
@ -239,21 +176,11 @@
<Evaluation id="main5" :goodsDetail="goodsDetail" /> <Evaluation id="main5" :goodsDetail="goodsDetail" />
<!-- 店铺推荐 --> <!-- 店铺推荐 -->
<storeLayout <storeLayout id="main7" :storeDetail="storeDetail" :goodsDetail="goodsDetail" :res="recommendList" />
id="main7"
:storeDetail="storeDetail"
:goodsDetail="goodsDetail"
:res="recommendList"
/>
<!-- 宝贝详情 --> <!-- 宝贝详情 -->
<GoodsIntro <GoodsIntro id="main9" :res="goodsDetail" :goodsParams="goodsParams" :goodsId="goodsDetail.goodsId"
id="main9" v-if="goodsDetail.id" />
:res="goodsDetail"
:goodsParams="goodsParams"
:goodsId="goodsDetail.goodsId"
v-if="goodsDetail.id"
/>
<!-- 宝贝推荐 --> <!-- 宝贝推荐 -->
<GoodsRecommend id="main11" :res="likeGoodsList" /> <GoodsRecommend id="main11" :res="likeGoodsList" />
@ -278,13 +205,8 @@
</view> </view>
<!-- 正常结算页面 --> <!-- 正常结算页面 -->
<view class="detail-btn" v-if="!isGroup"> <view class="detail-btn" v-if="!isGroup">
<view <view class="to-store-car to-store-btn" v-if="goodsDetail.goodsType != 'VIRTUAL_GOODS'" @click="shutMask(4)">
class="to-store-car to-store-btn" 加入购物车</view>
v-if="goodsDetail.goodsType != 'VIRTUAL_GOODS'"
@click="shutMask(4)"
>
加入购物车</view
>
<view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view> <view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view>
<view class="to-store-car to-store-btn" v-if="startTimer"></view> <view class="to-store-car to-store-btn" v-if="startTimer"></view>
</view> </view>
@ -303,15 +225,8 @@
<!-- 规格-模态层弹窗 --> <!-- 规格-模态层弹窗 -->
<view class="spec"> <view class="spec">
<!-- 促销弹窗 --> <!-- 促销弹窗 -->
<u-popup <u-popup v-model="promotionShow" :height="setup.height" :mode="setup.mode" :border-radius="setup.radius"
v-model="promotionShow" @close="promotionShow = false" :mask-close-able="setup.close" closeable>
:height="setup.height"
:mode="setup.mode"
:border-radius="setup.radius"
@close="promotionShow = false"
:mask-close-able="setup.close"
closeable
>
<view class="header-title">优惠</view> <view class="header-title">优惠</view>
<view class="cuxiao"> <view class="cuxiao">
<scroll-view class="scroll_mask" :scroll-y="true"> <scroll-view class="scroll_mask" :scroll-y="true">
@ -328,31 +243,14 @@
</u-popup> </u-popup>
<!-- 配送地址弹窗 --> <!-- 配送地址弹窗 -->
<popupAddress <popupAddress @closeAddress="closePopupAddress" @deliveryData="deliveryFun" v-if="goodsDetail.id"
@closeAddress="closePopupAddress" :goodsId="goodsDetail.id" :addressFlag="addressFlag" />
@deliveryData="deliveryFun"
v-if="goodsDetail.id"
:goodsId="goodsDetail.id"
:addressFlag="addressFlag"
/>
<!-- 商品规格 商品详情以及默认参与活动的id--> <!-- 商品规格 商品详情以及默认参与活动的id-->
<popupGoods <popupGoods :addr="delivery" ref="popupGoods" @changed="changedGoods" @closeBuy="closePopupBuy"
:addr="delivery" @queryCart="cartCount()" :goodsDetail="goodsDetail" :goodsSpec="goodsSpec" :isGroup="isGroup" :id="productId"
ref="popupGoods" v-if="goodsDetail.id" :pointDetail="pointDetail" :wholesaleList="wholesaleList" @handleClickSku="selectSku"
@changed="changedGoods" :buyMask="buyMask" />
@closeBuy="closePopupBuy"
@queryCart="cartCount()"
:goodsDetail="goodsDetail"
:goodsSpec="goodsSpec"
:isGroup="isGroup"
:id="productId"
v-if="goodsDetail.id"
:pointDetail="pointDetail"
:wholesaleList="wholesaleList"
@handleClickSku="selectSku"
:buyMask="buyMask"
/>
</view> </view>
</view> </view>
</div> </div>
@ -704,7 +602,7 @@ export default {
// lili // lili
uni.navigateTo({ uni.navigateTo({
url: `/pages/tabbar/home/web-view?IM=${this.storeDetail.storeId}`, url: `/pages/mine/im/index?userId=${this.goodsDetail.storeId}&goodsid=${this.routerVal.goodsId}&skuid=${this.routerVal.id}`
}); });
// udesk // udesk

View File

@ -314,17 +314,21 @@ export default {
}; };
uni.navigateTo({ uni.navigateTo({
url: url:
"/pages/product/customerservice/index?params=" + "/pages/mine/im/index"
encodeURIComponent(JSON.stringify(params)),
});
// #endif
// #ifndef MP-WEIXIN
const sign = this.storeInfo.yzfSign;
uni.navigateTo({
url:
"/pages/tabbar/home/web-view?src=https://yzf.qq.com/xv/web/static/chat/index.html?sign=" +
sign,
}); });
// uni.navigateTo({
// url:
// "/pages/product/customerservice/index?params=" +
// encodeURIComponent(JSON.stringify(params)),
// });
// // #endif
// // #ifndef MP-WEIXIN
// const sign = this.storeInfo.yzfSign;
// uni.navigateTo({
// url:
// "/pages/tabbar/home/web-view?src=https://yzf.qq.com/xv/web/static/chat/index.html?sign=" +
// sign,
// });
// #endif // #endif
}, },

View File

@ -3,12 +3,7 @@
<!-- uni 中不能使用 vue component 所以用if判断每个组件 --> <!-- uni 中不能使用 vue component 所以用if判断每个组件 -->
<div v-for="(item, index) in pageData.list" :key="index"> <div v-for="(item, index) in pageData.list" :key="index">
<!-- 搜索栏如果在楼层装修顶部则会自动浮动否则不浮动 --> <!-- 搜索栏如果在楼层装修顶部则会自动浮动否则不浮动 -->
<u-navbar <u-navbar class="navbar" v-if="item.type == 'search'" :is-back="false" :is-fixed="index === 1 ? false : true">
class="navbar"
v-if="item.type == 'search'"
:is-back="false"
:is-fixed="index === 1 ? false : true"
>
<search style="width: 100%" :res="item.options" /> <search style="width: 100%" :res="item.options" />
<!-- #ifndef H5 --> <!-- #ifndef H5 -->
<!-- 扫码功能 不兼容h5 详情文档: https://uniapp.dcloud.io/api/system/barcode?id=scancode --> <!-- 扫码功能 不兼容h5 详情文档: https://uniapp.dcloud.io/api/system/barcode?id=scancode -->
@ -19,22 +14,10 @@
</u-navbar> </u-navbar>
<carousel v-if="item.type == 'carousel'" :res="item.options" /> <carousel v-if="item.type == 'carousel'" :res="item.options" />
<titleLayout v-if="item.type == 'title'" :res="item.options" /> <titleLayout v-if="item.type == 'title'" :res="item.options" />
<leftOneRightTwo <leftOneRightTwo v-if="item.type == 'leftOneRightTwo'" :res="item.options" />
v-if="item.type == 'leftOneRightTwo'" <leftTwoRightOne v-if="item.type == 'leftTwoRightOne'" :res="item.options" />
:res="item.options" <topOneBottomTwo v-if="item.type == 'topOneBottomTwo'" :res="item.options" />
/> <topTwoBottomOne v-if="item.type == 'topTwoBottomOne'" :res="item.options" />
<leftTwoRightOne
v-if="item.type == 'leftTwoRightOne'"
:res="item.options"
/>
<topOneBottomTwo
v-if="item.type == 'topOneBottomTwo'"
:res="item.options"
/>
<topTwoBottomOne
v-if="item.type == 'topTwoBottomOne'"
:res="item.options"
/>
<flexThree v-if="item.type == 'flexThree'" :res="item.options" /> <flexThree v-if="item.type == 'flexThree'" :res="item.options" />
<flexFive v-if="item.type == 'flexFive'" :res="item.options" /> <flexFive v-if="item.type == 'flexFive'" :res="item.options" />
<flexFour v-if="item.type == 'flexFour'" :res="item.options" /> <flexFour v-if="item.type == 'flexFour'" :res="item.options" />

View File

@ -36,7 +36,6 @@
</u-row> </u-row>
<!-- 我的订单代付款 --> <!-- 我的订单代付款 -->
<view class="order"> <view class="order">
<view class="order-item" @click="navigateTo('/pages/order/myOrder?status=1')"> <view class="order-item" @click="navigateTo('/pages/order/myOrder?status=1')">
<div class="bag bag2"> <div class="bag bag2">
<u-icon name="bag-fill" size="35" color="#fff"></u-icon> <u-icon name="bag-fill" size="35" color="#fff"></u-icon>
@ -154,6 +153,7 @@ html,
body { body {
overflow: auto; overflow: auto;
} }
.money { .money {
overflow: hidden; overflow: hidden;
@ -175,12 +175,14 @@ body {
color: #ffffff; color: #ffffff;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.head-1 { .head-1 {
text-align: center; text-align: center;
width: 152rpx; width: 152rpx;
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
image { image {
width: 152rpx; width: 152rpx;
height: 144rpx; height: 144rpx;
@ -188,6 +190,7 @@ body {
margin-bottom: 30rpx; margin-bottom: 30rpx;
border: 3px solid #fff; border: 3px solid #fff;
} }
.edti-head { .edti-head {
position: absolute; position: absolute;
width: 40rpx; width: 40rpx;
@ -196,23 +199,27 @@ body {
background-color: rgba(255, 255, 255, 0.3); background-color: rgba(255, 255, 255, 0.3);
top: 100rpx; top: 100rpx;
right: 0; right: 0;
image { image {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
.head-2 { .head-2 {
flex: 1; flex: 1;
margin-left: 30rpx; margin-left: 30rpx;
margin-top: 100rpx; margin-top: 100rpx;
line-height: 1; line-height: 1;
} }
/deep/ .u-icon, /deep/ .u-icon,
.u-icon { .u-icon {
margin-top: 106rpx; margin-top: 106rpx;
} }
} }
.pointBox { .pointBox {
width: 94%; width: 94%;
margin: 0 3%; margin: 0 3%;
@ -220,6 +227,7 @@ body {
border-radius: 20rpx; border-radius: 20rpx;
box-shadow: 0 4rpx 24rpx 0 rgba($color: #f6f6f6, $alpha: 1); box-shadow: 0 4rpx 24rpx 0 rgba($color: #f6f6f6, $alpha: 1);
} }
.point { .point {
text-align: center; text-align: center;
height: 160rpx; height: 160rpx;
@ -227,12 +235,14 @@ body {
font-size: $font-sm; font-size: $font-sm;
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
padding: 24rpx; padding: 24rpx;
// #endif // #endif
.u-col { .u-col {
view { view {
color: $u-main-color; color: $u-main-color;
font-size: 28rpx; font-size: 28rpx;
} }
view:last-child { view:last-child {
margin-top: 8rpx; margin-top: 8rpx;
color: $main-color; color: $main-color;
@ -240,6 +250,7 @@ body {
} }
} }
} }
.order { .order {
height: 140rpx; height: 140rpx;
text-align: center; text-align: center;
@ -249,10 +260,12 @@ body {
align-items: center; align-items: center;
padding: 0 3%; padding: 0 3%;
color: #999; color: #999;
.order-item { .order-item {
position: relative; position: relative;
line-height: 2em; line-height: 2em;
width: 96rpx; width: 96rpx;
:first-child { :first-child {
font-size: 48rpx; font-size: 48rpx;
margin-bottom: 10rpx; margin-bottom: 10rpx;
@ -264,6 +277,7 @@ body {
.box { .box {
transform: translateY(-30rpx); transform: translateY(-30rpx);
} }
.user-name { .user-name {
font-size: 34rpx; font-size: 34rpx;
} }

View File

@ -126,7 +126,7 @@ export default {
linkMsgDetail(){ linkMsgDetail(){
uni.navigateTo({ uni.navigateTo({
url: `/pages/tabbar/home/web-view?IM=0`, url: `/pages/mine/im/list`,
}); });
}, },

View File

@ -85,6 +85,62 @@ export function unixToDate(unix, format) {
return _format; return _format;
} }
/**
* 人性化显示时间
*
* @param {Object} datetime
*/
export function beautifyTime(datetime = "") {
if (datetime == null || datetime == undefined || !datetime) {
return "";
}
datetime = datetime.replace(/-/g, "/");
let time = new Date();
let outTime = new Date(datetime);
if (/^[1-9]\d*$/.test(datetime)) {
outTime = new Date(parseInt(datetime) * 1000);
}
if (time.getTime() < outTime.getTime()) {
return parseTime(outTime, "{y}/{m}/{d}");
}
if (time.getFullYear() != outTime.getFullYear()) {
return parseTime(outTime, "{y}/{m}/{d}");
}
if (time.getMonth() != outTime.getMonth()) {
return parseTime(outTime, "{m}/{d}");
}
if (time.getDate() != outTime.getDate()) {
let day = outTime.getDate() - time.getDate();
if (day == -1) {
return parseTime(outTime, "昨天 {h}:{i}");
}
if (day == -2) {
return parseTime(outTime, "前天 {h}:{i}");
}
return parseTime(outTime, "{m}-{d}");
}
if (time.getHours() != outTime.getHours()) {
return parseTime(outTime, "{h}:{i}");
}
let minutes = outTime.getMinutes() - time.getMinutes();
if (minutes == 0) {
return "刚刚";
}
minutes = Math.abs(minutes);
return `${minutes}分钟前`;
}
/** /**
* 13888888888 -> 138****8888 * 13888888888 -> 138****8888
* @param mobile * @param mobile
@ -98,6 +154,111 @@ export function secrecyMobile(mobile) {
return mobile.replace(/(\d{3})(\d{4})(\d{4})/, "$1****$3"); return mobile.replace(/(\d{3})(\d{4})(\d{4})/, "$1****$3");
} }
/**
* 人性化时间显示
*
* @param {Object} datetime
*/
export function formatTime(datetime) {
if (datetime == null) return "";
datetime = datetime.replace(/-/g, "/");
let time = new Date();
let outTime = new Date(datetime);
if (/^[1-9]\d*$/.test(datetime)) {
outTime = new Date(parseInt(datetime) * 1000);
}
if (
time.getTime() < outTime.getTime() ||
time.getFullYear() != outTime.getFullYear()
) {
return parseTime(outTime, "{y}-{m}-{d} {h}:{i}");
}
if (time.getMonth() != outTime.getMonth()) {
return parseTime(outTime, "{m}-{d} {h}:{i}");
}
if (time.getDate() != outTime.getDate()) {
let day = outTime.getDate() - time.getDate();
if (day == -1) {
return parseTime(outTime, "昨天 {h}:{i}");
}
if (day == -2) {
return parseTime(outTime, "前天 {h}:{i}");
}
return parseTime(outTime, "{m}-{d} {h}:{i}");
}
if (time.getHours() != outTime.getHours()) {
return parseTime(outTime, "{h}:{i}");
}
let minutes = outTime.getMinutes() - time.getMinutes();
if (minutes == 0) {
return "刚刚";
}
minutes = Math.abs(minutes);
return `${minutes}分钟前`;
}
/**
* 时间格式化方法
*
* @param {(Object|string|number)} time
* @param {String} cFormat
* @returns {String | null}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null;
}
let date;
const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
if (typeof time === "object") {
date = time;
} else {
if (typeof time === "string" && /^[0-9]+$/.test(time)) {
time = parseInt(time);
}
if (typeof time === "number" && time.toString().length === 10) {
time = time * 1000;
console.log("时间判断为number");
}
date = new Date(time.replace(/-/g, "/"));
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay(),
};
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key];
// Note: getDay() returns 0 on Sunday
if (key === "a") {
return ["日", "一", "二", "三", "四", "五", "六"][value];
}
return value.toString().padStart(2, "0");
});
return time_str;
}
/** /**
* 清除逗号 * 清除逗号
* *

86
utils/socket_service.js Normal file
View File

@ -0,0 +1,86 @@
import store from '@/store/index'
import config from '@/config/config.js'
import storage from './storage';
export default class SocketService {
/**
* 单例
*/
static instance = null;
static get Instance() {
if (!this.instance) {
this.instance = new SocketService();
}
return this.instance;
}
// 和服务端连接的socket对象
ws = null;
// 存储回调函数
callBackMapping = {};
// 标识是否连接成功
connected = false;
// 记录重试的次数
sendRetryCount = 0;
// 重新连接尝试的次数
connectRetryCount = 0;
// 定义连接服务器的方法
connect() {
// 连接服务器
if (!window.WebSocket) {
return console.log("您的浏览器不支持WebSocket");
}
this.ws = new WebSocket(config.BASE_WS_URL+'/'+storage.getAccessToken());
// 连接成功的事件
this.ws.onopen = () => {
console.log("连接服务端成功");
this.connected = true;
// 重置重新连接的次数
this.connectRetryCount = 0;
};
// 1.连接服务端失败
// 2.当连接成功之后, 服务器关闭的情况(连接失败重连)
this.ws.onclose = () => {
console.log("连接服务端失败");
this.connected = false;
this.connectRetryCount++;
setTimeout(() => {
this.connect();
}, 500 * this.connectRetryCount);
};
// 得到服务端发送过来的数据
this.ws.onmessage = (msg) => {
// console.log(msg.data)
this.registerCallBack(msg.data);
};
}
// 回调函数的注册
registerCallBack(callBack) {
// console.log("回调函数的注册", callBack);
this.callBackMapping = callBack;
}
// 取消某一个回调函数
unRegisterCallBack(callBack) {
console.log("取消某一个回调函数", callBack);
this.callBackMapping = null;
}
// 发送数据的方法
send(data) {
// 判断此时此刻有没有连接成功
if (this.connected) {
this.sendRetryCount = 0;
this.ws.send(data);
} else {
this.sendRetryCount++;
setTimeout(() => {
this.send(data);
}, this.sendRetryCount * 500);
}
}
}

View File

@ -52,6 +52,12 @@ export default {
getUserInfo() { getUserInfo() {
return uni.getStorageSync(USER_INFO); return uni.getStorageSync(USER_INFO);
}, },
setTalkToUser(val){
uni.setStorageSync("TALK_TO_USER", val);
},
getTalkToUser(){
return uni.getStorageSync("TALK_TO_USER");
},
// 写入uuid // 写入uuid
setUuid(val) { setUuid(val) {
uni.setStorageSync(UUID, val); uni.setStorageSync(UUID, val);
@ -113,4 +119,11 @@ export default {
removeAfterSaleData() { removeAfterSaleData() {
uni.removeStorageSync(AFTERSALE_DATA); uni.removeStorageSync(AFTERSALE_DATA);
}, },
// 是否发送商品连接记录
setImGoodsLink(val) {
uni.setStorageSync('imGoodId', val);
},
getImGoodsLink() {
return uni.getStorageSync('imGoodId');
},
}; };