上传文件有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>