上传文件有token的时候,添加token

This commit is contained in:
2025-05-13 16:41:48 +08:00
parent 13216d3518
commit ddd3dd981a
7 changed files with 846 additions and 332 deletions

View File

@ -0,0 +1,115 @@
<template>
<view>
<scroll-view style="height: 640rpx;background-color: #F6F6F6" scroll-y="true">
<view class="coupon-obj">
<view v-for="(item, index) in coupons" :key="index" class="mb20 bg-white" @tap="onSelect(item.id)">
<view class="coupon-item row">
<view class="price white column-center">
<view class="xl">
<price-format :subscript-size="34" :first-size="60" :second-size="50" :price="item.money" :weight="500"></price-format>
</view>
<view class="nr">{{item.use_condition}}</view>
</view>
<view class="row-between" style="flex: 1">
<view class="info ml20">
<view class="bold md bold mb10 line1">{{item.name}}</view>
<view class="xxs lighter mb10">{{item.coupon_type}}</view>
<view class="xxs lighter">{{item.use_time_tips}}</view>
</view>
<checkbox v-if="type == 0" :checked="selectId == item.id" class="mr20"></checkbox>
</view>
</view>
<view class="xs" v-if="item.tips" style="padding: 14rpx 20rpx">
{{item.tips}}
</view>
</view>
</view>
<view v-if="coupons.length == 0" class="column-center" style="padding-top: 50rpx">
<image class="img-null" :src="`${cloudPath}img/coupon_null.png`"></image>
<text class="muted">暂无优惠券</text>
</view>
</scroll-view>
<view class="column-center">
<view class="bg-default white row-center br60 mb10 lg u-m-t-2" style="width: 710rpx;height: 74rpx" @tap="onConfirmCoupon">
确定
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
coupons: [],
selectId: ""
};
},
props: {
list: {
type: Array,
default: () => []
},
type: {
type: Number
},
couponId: [Number, String]
},
watch: {
list: {
handler(val) {
this.coupons = val
},
immediate: true,
},
couponId: {
handler(val) {
this.selectId = val
},
immediate: true,
}
},
methods: {
onSelect(id) {
const {
coupons,
type,
selectId
} = this;
if (type == 1) return;
this.selectId = id == selectId ? "" : id
},
onConfirmCoupon() {
this.$emit("change", this.selectId)
}
}
};
</script>
<style lang="scss">
.coupon-obj {
padding: 20rpx 24rpx;
}
.coupon-obj .coupon-item {
position: relative;
height: 160rpx;
background-image: url(#{$cloudPath}img/coupon_bg.png);
background-size: 100% 100%;
}
.coupon-obj .coupon-item .price {
width: 200rpx;
}
.coupon-obj .coupon-item .btn {
position: absolute;
right: 20rpx;
bottom: 20rpx;
padding: 0 49rpx;
}
</style>

View File

@ -55,6 +55,10 @@
value: {
type: Boolean,
required: true
},
token: {
type: String,
default: ''
}
},
data() {
@ -74,7 +78,8 @@
title: "正在上传中...",
mask: true,
});
uploadFile(avatarUrl).then((res) => {
uploadFile(avatarUrl, this.token).then((res) => {
uni.hideLoading();
this.avatar = res.url;
}).catch(() => {

98
components/tab/tab.vue Normal file
View File

@ -0,0 +1,98 @@
<template>
<view :class="{ active, inactive: !active, tab: true }" :style="shouldShow ? '' : 'display: none;'">
<slot v-if="shouldRender"></slot>
</view>
</template>
<script>
export default {
props: {
dot: {
type: Boolean,
},
info: {
type: null,
},
title: {
type: String,
},
titleStyle: {
type: String,
},
name: {
type: [Number, String],
value: ''
}
},
inject: ['tabs'],
data() {
return {
active: false,
shouldShow: false,
shouldRender: false
}
},
created() {
this.tabs.childrens.push(this)
},
mounted() {
this.update()
},
methods: {
getComputedName: function() {
if (this.data.name !== '') {
return this.data.name;
}
return this.index;
},
updateRender: function(active, parent) {
let parentData = parent;
this.inited = this.inited || active;
this.active = active
this.shouldRender = this.inited
this.shouldShow = active
},
update: function() {
if (this.tabs) {
this.tabs.updateTabs();
}
}
},
computed: {
changeData() {
const {
dot,
info,
title,
titleStyle
} = this
return {
dot,
info,
title,
titleStyle
}
}
},
watch: {
changeData(value) {
this.update()
},
},
}
</script>
<style>
.tab.active {
height: auto;
}
.tab.inactive {
height: 0;
overflow: visible;
}
</style>

252
components/tabs/tabs.vue Normal file
View File

@ -0,0 +1,252 @@
<template>
<view class="_tab-box" :style="{fontSize: defaultConfig.fontSize + 'rpx', color: defaultConfig.color,}">
<scroll-view id="_scroll" :scroll-x="true" class="scroll-view-h" scroll-with-animation :scroll-left="slider.scrollLeft" :style="{ backgroundColor: defaultConfig.bgColor}">
<view class="_scroll-content">
<view class="_tab-item-box" :class="[defaultConfig.itemWidth ? '_clamp' : '_flex']">
<block v-for="(item, index) in tabList" :key="index">
<view class="_item" :id="'_tab_'+index" :class="{ '_active': tagIndex === index }" :style="{color: tagIndex == index ? '#254062' : defaultConfig.color, 'width': defaultConfig.itemWidth ? defaultConfig.itemWidth + 'rpx' : ''}"
@click="tabClick(index)">{{ item.title }}</view>
</block>
</view>
<view class="_underline" :style="{
transform: 'translateX(' + slider.left + 'px)',
width: slider.width + 'px',
height: defaultConfig.underLineHeight + 'rpx',
backgroundColor: '#254062',
}" />
</view>
</scroll-view>
<view class="tab-content">
<view>
<slot></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'tabs',
props: {
active: {
type: Number,
default: 0
},
config: {
type: Object,
default: () => {
return {}
}
},
},
provide() {
return {
tabs: this
}
},
data() {
return {
tabList: [],
tagIndex: 0,
slider: {
left: 0,
width: 0,
scrollLeft: 0
},
scorll: {},
defaultConfig: {
bgColor: "#fff",
// 要显示的key
// 字体大小 rpx
fontSize: 26,
// 字体颜色
color: '#333',
// 激活字体颜色
activeColor: '#FF2C3C',
// item宽度 0为自动
itemWidth: 0,
// 下划线左右边距,文字宽度加边距 rpx
underLinePadding: 10,
// 下划线宽度 rpx 注意:设置了此值 underLinePadding 失效
underLineWidth: 0,
// 下划线高度 rpx
underLineHeight: 4,
// 下划线颜色
underLineColor: '#FF2C3C',
},
};
},
watch: {
},
created() {
this.childrens = []
},
mounted() {
this.updateTabs();
},
methods: {
updateTabs() {
this.tabList = this.childrens.map((item) => {
const {
title,
info,
name,
dot,
titleStyle,
active,
updateRender
} = item
return {
title,
info,
name,
dot,
titleStyle,
active,
updateRender
}
})
this.updateConfig();
this.tagIndex = this.active;
this.$nextTick(() => {
this.calcScrollPosition();
})
},
updateConfig() {
this.defaultConfig = Object.assign(this.defaultConfig, this.config);
},
calcScrollPosition() {
const query = uni.createSelectorQuery().in(this);
query.select('#_scroll').boundingClientRect((res) => {
this.scorll = res;
this.updateTabWidth();
}).exec();
},
updateTabWidth(index = 0) {
let data = this.tabList;
if (data.length == 0) return false;
const query = uni.createSelectorQuery().in(this);
query.select('#_tab_' + index).boundingClientRect((res) => {
data[index]._slider = {
width: res.width,
left: res.left,
scrollLeft: res.left - (data[index - 1] ? data[index - 1]._slider.width : 0),
};
if (this.tagIndex == index) {
this.tabToIndex(this.tagIndex);
}
index++;
if (data.length > index) {
this.updateTabWidth(index);
}
}).exec();
},
tabToIndex(index) {
let _slider = this.tabList[index]._slider;
let width = uni.upx2px(this.defaultConfig.underLineWidth);
if (!width) {
if (this.defaultConfig.itemWidth) {
width = uni.upx2px(this.defaultConfig.itemWidth)/3;
} else {
width = this.tabList[index]['title'].length * uni.upx2px(this.defaultConfig.fontSize);
}
width += uni.upx2px(this.defaultConfig.underLinePadding) * 2;
}
this.childrens.forEach((item, ind) => {
let active = ind === index;
if (active !== item.active || !item.inited) {
item.updateRender(active, this);
}
});
let scorll_left = this.scorll.left || 0;
this.slider = {
left: _slider.left - scorll_left + (_slider.width - width) / 2,
width: width,
scrollLeft: _slider.scrollLeft - scorll_left,
}
},
tabClick(index) {
this.tagIndex = index;
this.tabToIndex(index);
this.$emit('change', index);
}
}
}
</script>
<style lang="scss" scoped>
._tab-box {
width: 100%;
font-size: 26rpx;
position: relative;
z-index: 10;
.scroll-view-h {
height: 80rpx;
line-height: 80rpx;
white-space: nowrap;
width: 100%;
box-sizing: border-box;
._scroll-content {
width: 100%;
height: 100%;
position: relative;
display: inline-block;
._tab-item-box {
height: 100%;
display: inline-block;
&._flex {
display: flex;
._item {
flex: 1;
padding: 0 20rpx;
}
}
&._clamp {
._item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
._item {
height: 100%;
display: inline-block;
text-align: center;
position: relative;
text-align: center;
color: #333;
&._active {
color: #254062;
}
}
}
._underline {
height: 4rpx;
background-color: #254062;
border-radius: 6rpx;
transition: transform .5s;
position: absolute;
bottom: 0;
}
}
}
}
</style>

View File

@ -42,7 +42,7 @@
</view>
</view>
<mplogin v-model="mpLoginPopup" @close="mpLoginPopup = false" @update="handleSubmitInfo"/>
<mplogin v-model="mpLoginPopup" :token="token" @close="mpLoginPopup = false" @update="handleSubmitInfo"/>
<mobile-login v-model="mobilePopup" @close="mobilePopup = false" @update="handleSubmitMobile"/>
</view>
</template>
@ -69,7 +69,8 @@
},
loginData: {},
mpLoginPopup: false,
mobilePopup: false
mobilePopup: false,
token: ''
}
},
@ -109,7 +110,10 @@
if (code == 1) {
if (data.is_new_user) {
uni.hideLoading()
this.token = data.token
this.$nextTick(() => {
this.mpLoginPopup = true
})
this.loginData = data
} else {
this.loginHandle(data)

View File

@ -12,11 +12,8 @@
@change="changeDelivery"
/> -->
<!-- 快递配送 -->
<view
v-show="addressTabsList[addressTabsIndex]['sign'] === 'express'"
class="u-flex p24 w-full"
@click="onAddressExpress"
>
<view v-show="addressTabsList[addressTabsIndex]['sign'] === 'express'" class="u-flex p24 w-full"
@click="onAddressExpress">
<view>
<u-icon name="map" size="48" class="right-icon"></u-icon>
</view>
@ -38,7 +35,7 @@
<view>请选择收货地址</view>
</template>
</view>
<view >
<view>
<u-icon class="ml10" name="arrow-right" />
</view>
</view>
@ -76,15 +73,8 @@
</view> -->
</view>
<view class="bg-white br16 row u-m-t-32">
<order-goods
:team="{ need: orderInfo.team_need }"
:list="goodsLists"
:delivery="delivery"
:order_type="orderInfo.order_type"
:imageWidth="260"
:imageHeight="172"
mode="comfirm"
></order-goods>
<order-goods :team="{ need: orderInfo.team_need }" :list="goodsLists" :delivery="delivery"
:order_type="orderInfo.order_type" :imageWidth="260" :imageHeight="172" mode="comfirm"></order-goods>
<!-- <view>
<u-image :src="cloudPath + 'img/banner.png'" width="260" height="172"></u-image>
</view>
@ -105,12 +95,25 @@
</view> -->
</view>
<view class="item row-between bg-white br16 row u-m-t-32 p24" @tap="showCoupon = true">
<view>优惠券</view>
<view class="row">
<text class="primary" v-if="orderInfo.discount_amount">-¥{{ orderInfo.discount_amount }}</text>
<text v-else-if="usableCoupon.length" class="primary">{{
usableCoupon.length + '张可用'
}}</text>
<text v-else class="muted">无优惠券可用</text>
<u-icon name="arrow-right" size="32" color="#999"></u-icon>
</view>
</view>
<view class="bg-white br16 p24 u-m-t-32">
<view>
备注
</view>
<view class="flex1 u-m-t-16 mask">
xxxx
<u-input v-model="value" type="textarea" :border="border" maxlength="150"/>
</view>
</view>
@ -159,31 +162,45 @@
<view class="fixed bg-white row-between px48 u-padding-top-20 u-padding-bottom-20">
<view class="column u-text-center">
<view class="row-center">
<view class="count">共1件</view>
<view class="count">共{{orderInfo.total_num}}件</view>
<view class="u-m-l-8">合计:</view>
<view class="primary" style="margin-top: -8rpx;">
<price-format :price="12.9" :subscriptSize="34" :firstSize="56" :secondSize="34"></price-format>
<price-format :price="orderInfo.order_amount" :subscriptSize="34" :firstSize="56" :secondSize="34"></price-format>
</view>
</view>
</view>
<view class="u-m-l-64 flex1">
<u-button hover-class="none"
@click="onSubmitOrder"
:customStyle="{height: '92rpx', backgroundColor: themeColor, color: '#fff', border: 'none', paddingTop: '8rpx'}"
:hair-line="false"
shape="circle">
<u-button hover-class="none" @click="onSubmitOrder"
:customStyle="{ height: '92rpx', backgroundColor: themeColor, color: '#fff', border: 'none', paddingTop: '8rpx' }"
:hair-line="false" shape="circle">
去支付
</u-button>
</view>
</view>
<appointment-time v-model="timePopup" @close="timePopup = false" @update="handleSubmitMobile"/>
<u-popup v-model="showCoupon" border-radius="14" mode="bottom" closeable>
<view class="pop-title row-between">
<view class="title">优惠券</view>
</view>
<view v-if="showCoupon">
<tabs :active="couponTabsIndex" :config="{ underLineWidth: 100 }">
<tab :title="'可使用优惠券 (' + usableCoupon.length + ')'">
<coupon-obj :list="usableCoupon" :type="0" @change="onSelectCoupon"
:coupon-id="couponId"></coupon-obj>
</tab>
<tab :title="'不可用优惠券 (' + unusableCoupon.length + ')'">
<coupon-obj :list="unusableCoupon" :type="1" @change="onSelectCoupon"></coupon-obj>
</tab>
</tabs>
</view>
</u-popup>
<appointment-time v-model="timePopup" @close="timePopup = false" @update="handleSubmitMobile" />
</view>
</template>
<script>
import { orderBuy, getOrderCoupon, getDelivery } from '@/api/order'
export default {
data(){
import { orderBuy, getOrderCoupon, getDelivery } from '@/api/order'
export default {
data() {
return {
timePopup: false,
pay: {
@ -211,7 +228,11 @@
address: {}, // 收货地址信息
addressId: '', // 收货地址ID
storeInfo: {}, // 门店信息
couponId: '', // 优惠券ID
couponTabsIndex: 0, // 优惠券Tabs索引
usableCoupon: [], // 优惠券--可使用
unusableCoupon: [], // 优惠券--不可用
showCoupon: false, // 显示优惠券Popup
}
},
@ -314,6 +335,13 @@
})
},
// 选择优惠券
onSelectCoupon(value) {
this.couponId = value
this.showCoupon = false
this.handleOrderMethods('info')
},
// 点击订单提交
onSubmitOrder() {
uni.showModal({
@ -448,27 +476,39 @@
return this.addressTabsList[this.addressTabsIndex]['id']
}
},
}
}
</script>
<style lang="scss">
.num {
.num {
color: #4E5969;
}
}
.mask {
.mask {
color: #86909C;
}
}
.fixed {
.fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding-bottom: env(safe-area-inset-bottom);
}
}
.count {
.count {
color: #86909C;
}
}
.pop-title {
height: 100rpx;
border-bottom: 1rpx solid #f2f2f2;
}
.pop-title .title {
margin-left: 30rpx;
font-size: 34rpx;
font-weight: bold;
line-height: 36rpx;
}
</style>

View File

@ -269,14 +269,14 @@ export function menuJump(item) {
}
}
export function uploadFile(path) {
export function uploadFile(path, token = '') {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${baseURL}/api/file/formimage`,
filePath: path,
name: "file",
header: {
token: store.getters.token,
token: store.getters.token || token,
},
fileType: "image",
cloudPath: "",