很多页面
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<view class="address-page">
|
||||
<uni-nav-bar left-icon="left" title="收货地址" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" />
|
||||
|
||||
<scroll-view scroll-y class="content">
|
||||
<view class="form-item">
|
||||
<view class="label">收件人</view>
|
||||
<input class="input" v-model="receiver" placeholder="请输入收货人名字" />
|
||||
</view>
|
||||
<view class="divider-line"></view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="label">手机号</view>
|
||||
<input class="input" v-model="mobile" type="number" placeholder="收货人的电话,方便联系" />
|
||||
</view>
|
||||
<view class="divider-line"></view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="label">邮箱</view>
|
||||
<input class="input" v-model="email" type="text" placeholder="用于接收电子卡等信息(可选)" />
|
||||
</view>
|
||||
<view class="divider-line"></view>
|
||||
|
||||
<view class="form-item select-item" @click="openAreaPicker">
|
||||
<view class="label">地址</view>
|
||||
<view class="input placeholder" v-if="!regionText">请选择地址</view>
|
||||
<view class="input" v-else>{{ regionText }}</view>
|
||||
<text class="arrow">›</text>
|
||||
</view>
|
||||
<view class="divider-line"></view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="label">详细地址</view>
|
||||
<input class="input" v-model="detail" placeholder="请输入街道、门牌等详细地址信息" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="footer-bar">
|
||||
<view class="confirm-btn" @click="submit">确定</view>
|
||||
</view>
|
||||
|
||||
<!-- 省市区选择器 -->
|
||||
<view v-if="showAreaPicker" class="picker-mask" @click="closeAreaPicker"></view>
|
||||
<view v-if="showAreaPicker" class="picker-panel">
|
||||
<view class="picker-header">
|
||||
<text class="picker-btn" @click="closeAreaPicker">取消</text>
|
||||
<text class="picker-title">选择地区</text>
|
||||
<text class="picker-btn ok" @click="confirmArea">确定</text>
|
||||
</view>
|
||||
<picker-view v-if="provinces.length && cities.length && areas.length" class="picker-view" :indicator-style="indicatorStyle" :value="pickerIndex" @change="onAreaChange">
|
||||
<picker-view-column>
|
||||
<view v-for="(p,pi) in provinces" :key="pi" class="picker-item">{{ p.name }}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view v-for="(c,ci) in cities" :key="ci" class="picker-item">{{ c.name }}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view v-for="(a,ai) in areas" :key="ai" class="picker-item">{{ a.name }}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<view v-else class="picker-empty">地区数据加载中...</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import areaList from '@/utils/areaList.js'
|
||||
|
||||
const receiver = ref('')
|
||||
const mobile = ref('')
|
||||
const regionText = ref('')
|
||||
const detail = ref('')
|
||||
const email = ref('')
|
||||
const editingId = ref(null)
|
||||
|
||||
const goBack = () => uni.navigateBack()
|
||||
|
||||
// 省市区数据(适配树形数组:[{code,label,value,children:[...] }...])
|
||||
const provinces = ref([])
|
||||
const cities = ref([])
|
||||
const areas = ref([])
|
||||
const pickerIndex = ref([0,0,0])
|
||||
const showAreaPicker = ref(false)
|
||||
const indicatorStyle = `height: 80rpx;`
|
||||
|
||||
const normalizeNode = (node) => ({
|
||||
code: node?.code || '',
|
||||
name: node?.label || node?.value || node?.name || '',
|
||||
children: Array.isArray(node?.children) ? node.children : []
|
||||
})
|
||||
|
||||
const getAreaTree = () => {
|
||||
const raw = areaList && (areaList.default || areaList)
|
||||
return Array.isArray(raw) ? raw.map(normalizeNode) : []
|
||||
}
|
||||
|
||||
const buildData = () => {
|
||||
const tree = getAreaTree()
|
||||
provinces.value = tree.length ? tree : [{ code: '', name: '', children: [] }]
|
||||
const pIdx = Math.min(pickerIndex.value[0], Math.max(provinces.value.length - 1, 0))
|
||||
const pNode = provinces.value[pIdx]
|
||||
cities.value = (pNode?.children || []).map(normalizeNode)
|
||||
if (!cities.value.length) cities.value = [{ code: '', name: '', children: [] }]
|
||||
const cIdx = Math.min(pickerIndex.value[1], Math.max(cities.value.length - 1, 0))
|
||||
const cNode = cities.value[cIdx]
|
||||
areas.value = (cNode?.children || []).map(normalizeNode)
|
||||
if (!areas.value.length) areas.value = [{ code: '', name: '' }]
|
||||
}
|
||||
|
||||
const openAreaPicker = () => {
|
||||
showAreaPicker.value = true
|
||||
pickerIndex.value = [0,0,0]
|
||||
buildData()
|
||||
}
|
||||
const closeAreaPicker = () => { showAreaPicker.value = false }
|
||||
|
||||
const onAreaChange = (e) => {
|
||||
const val = (e && e.detail && e.detail.value) ? e.detail.value : [0,0,0]
|
||||
const [pi, ci, ai] = val
|
||||
if (pi !== pickerIndex.value[0]) {
|
||||
pickerIndex.value = [pi, 0, 0]
|
||||
buildData()
|
||||
return
|
||||
}
|
||||
if (ci !== pickerIndex.value[1]) {
|
||||
pickerIndex.value = [pi, ci, 0]
|
||||
buildData()
|
||||
return
|
||||
}
|
||||
pickerIndex.value = [pi, ci, ai]
|
||||
}
|
||||
|
||||
const confirmArea = () => {
|
||||
const p = provinces.value[pickerIndex.value[0]]
|
||||
const c = cities.value[pickerIndex.value[1]]
|
||||
const a = areas.value[pickerIndex.value[2]]
|
||||
regionText.value = [p?.name, c?.name, a?.name].filter(Boolean).join(' ')
|
||||
closeAreaPicker()
|
||||
}
|
||||
|
||||
onLoad((opts) => {
|
||||
if (opts && opts.id) {
|
||||
// 回填编辑
|
||||
editingId.value = Number(opts.id)
|
||||
try {
|
||||
const list = uni.getStorageSync('goods_addresses') || []
|
||||
const target = Array.isArray(list) ? list.find(a => a.id === editingId.value) : null
|
||||
if (target) {
|
||||
receiver.value = target.receiver || ''
|
||||
mobile.value = target.mobile || ''
|
||||
regionText.value = target.region || ''
|
||||
detail.value = target.detail || ''
|
||||
email.value = target.email || ''
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
})
|
||||
|
||||
const submit = () => {
|
||||
if (!receiver.value) return uni.showToast({ title: '请输入收件人', icon: 'none' })
|
||||
if (!/^1\d{10}$/.test(mobile.value)) return uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
if (!regionText.value) return uni.showToast({ title: '请选择地址', icon: 'none' })
|
||||
if (!detail.value) return uni.showToast({ title: '请输入详细地址', icon: 'none' })
|
||||
if (email.value && !/^([a-zA-Z0-9_\.-]+)@([a-zA-Z0-9\.-]+)\.([a-zA-Z]{2,})$/.test(email.value)) return uni.showToast({ title: '邮箱格式不正确', icon: 'none' })
|
||||
|
||||
const STORAGE_KEY = 'goods_addresses'
|
||||
let list = []
|
||||
try {
|
||||
const cached = uni.getStorageSync(STORAGE_KEY)
|
||||
list = Array.isArray(cached) ? cached : []
|
||||
} catch (e) { list = [] }
|
||||
|
||||
if (editingId.value) {
|
||||
// 更新
|
||||
list = list.map(a => a.id === editingId.value ? {
|
||||
...a,
|
||||
receiver: receiver.value,
|
||||
mobile: mobile.value,
|
||||
region: regionText.value,
|
||||
detail: detail.value,
|
||||
fullAddress: `${regionText.value} ${detail.value}`,
|
||||
email: email.value
|
||||
} : a)
|
||||
} else {
|
||||
// 新增
|
||||
const address = {
|
||||
id: Date.now(),
|
||||
receiver: receiver.value,
|
||||
mobile: mobile.value,
|
||||
region: regionText.value,
|
||||
detail: detail.value,
|
||||
fullAddress: `${regionText.value} ${detail.value}`,
|
||||
email: email.value,
|
||||
createdAt: Date.now()
|
||||
}
|
||||
list.unshift(address)
|
||||
}
|
||||
uni.setStorageSync(STORAGE_KEY, list)
|
||||
uni.showToast({ title: '提交成功', icon: 'success' })
|
||||
setTimeout(() => { uni.navigateBack() }, 500)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.address-page { min-height: 100vh; background: #fff; }
|
||||
.content { position: absolute; top: 140rpx; bottom: 120rpx; left: 0; right: 0; background: #fff; }
|
||||
.form-item { display: flex; align-items: center; padding: 24rpx; }
|
||||
.label { width: 160rpx; color: #333; font-size: 30rpx; }
|
||||
.input { flex: 1; color: #333; font-size: 30rpx; }
|
||||
.placeholder { color: #bbb; }
|
||||
.divider-line { height: 2rpx; background: #eee; margin: 0 24rpx; }
|
||||
.select-item { position: relative; }
|
||||
.arrow { position: absolute; right: 24rpx; color: #999; font-size: 48rpx; }
|
||||
.footer-bar { position: fixed; left: 0; right: 0; bottom: 0; height: 120rpx; background: #27c5b8; display: flex; align-items: center; justify-content: center; }
|
||||
.confirm-btn { color: #fff; font-size: 34rpx; font-weight: 700; }
|
||||
|
||||
/* 地区选择器 */
|
||||
.picker-mask { position: fixed; left: 0; right: 0; top: 0; bottom: 0; background: rgba(0,0,0,0.4); }
|
||||
.picker-panel { position: fixed; left: 0; right: 0; bottom: 0; background: #fff; }
|
||||
.picker-header { display: flex; align-items: center; justify-content: space-between; padding: 20rpx 24rpx; border-bottom: 1rpx solid #eee; }
|
||||
.picker-title { font-size: 30rpx; color: #333; }
|
||||
.picker-btn { color: #666; font-size: 28rpx; }
|
||||
.picker-btn.ok { color: #38c1b1; }
|
||||
.picker-view { height: 480rpx; }
|
||||
.picker-item { height: 80rpx; line-height: 80rpx; text-align: center; color: #333; }
|
||||
.picker-empty { padding: 40rpx; text-align: center; color: #999; }
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<view class="addr-list-page">
|
||||
<uni-nav-bar left-icon="left" title="地址管理" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" />
|
||||
|
||||
<scroll-view scroll-y class="list-wrap">
|
||||
<view v-if="!list.length" class="empty">暂无收货地址</view>
|
||||
<view v-for="item in list" :key="item.id" class="addr-item" @click="select(item)">
|
||||
<view class="addr-main">
|
||||
<view class="row">
|
||||
<text class="name">{{ item.receiver }}</text>
|
||||
<text class="mobile">{{ item.mobile }}</text>
|
||||
</view>
|
||||
<view class="row small">{{ item.fullAddress || (item.region + ' ' + item.detail) }}</view>
|
||||
</view>
|
||||
<view class="addr-actions">
|
||||
<text class="act" @click.stop="edit(item)">编辑</text>
|
||||
<text class="act danger" @click.stop="remove(item)">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="footer-bar">
|
||||
<view class="add-btn" @click="addNew">新增地址</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
|
||||
const STORAGE_KEY = 'goods_addresses'
|
||||
const SELECTED_KEY = 'goods_selected_address'
|
||||
const list = ref([])
|
||||
|
||||
const goBack = () => uni.navigateBack()
|
||||
|
||||
const load = () => {
|
||||
try {
|
||||
const cached = uni.getStorageSync(STORAGE_KEY)
|
||||
list.value = Array.isArray(cached) ? cached : []
|
||||
} catch (e) {
|
||||
list.value = []
|
||||
}
|
||||
}
|
||||
|
||||
onShow(() => load())
|
||||
|
||||
const addNew = () => uni.navigateTo({ url: '/pages_goods/exchange/address' })
|
||||
|
||||
const edit = (item) => {
|
||||
uni.navigateTo({ url: `/pages_goods/exchange/address?id=${item.id}` })
|
||||
}
|
||||
|
||||
const remove = (item) => {
|
||||
uni.showModal({
|
||||
title: '删除地址',
|
||||
content: '确定删除该地址吗?',
|
||||
success: (r) => {
|
||||
if (r.confirm) {
|
||||
list.value = list.value.filter(a => a.id !== item.id)
|
||||
uni.setStorageSync(STORAGE_KEY, list.value)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const select = (item) => {
|
||||
uni.setStorageSync(SELECTED_KEY, item)
|
||||
uni.showToast({ title: '已选择该地址', icon: 'success' })
|
||||
setTimeout(() => uni.navigateBack(), 300)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.addr-list-page { min-height: 100vh; background: #fff; }
|
||||
.list-wrap { position: absolute; top: 140rpx; bottom: 120rpx; left: 0; right: 0; }
|
||||
.empty { text-align: center; color: #999; padding: 80rpx 24rpx; }
|
||||
.addr-item { display: flex; align-items: center; justify-content: space-between; padding: 24rpx; border-bottom: 1rpx solid #f0f0f0; }
|
||||
.addr-main { flex: 1; }
|
||||
.row { display: flex; align-items: center; gap: 20rpx; margin-bottom: 8rpx; }
|
||||
.row.small { color: #666; font-size: 26rpx; }
|
||||
.name { color: #333; font-size: 30rpx; }
|
||||
.mobile { color: #333; font-size: 30rpx; }
|
||||
.addr-actions { display: flex; align-items: center; gap: 24rpx; margin-left: 24rpx; }
|
||||
.act { color: #38c1b1; font-size: 28rpx; }
|
||||
.act.danger { color: #ff4d4f; }
|
||||
.footer-bar { position: fixed; left: 0; right: 0; bottom: 0; height: 120rpx; background: #27c5b8; display: flex; align-items: center; justify-content: center; }
|
||||
.add-btn { color: #fff; font-size: 34rpx; font-weight: 700; }
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<view class="exchange-page">
|
||||
<uni-nav-bar left-icon="left" title="在线兑换" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" />
|
||||
|
||||
<scroll-view scroll-y class="content">
|
||||
<!-- 收货地址 -->
|
||||
<view class="addr-card" @click="changeAddress">
|
||||
<view class="addr-header">
|
||||
<text class="addr-title">收货信息</text>
|
||||
<text class="addr-change">{{ selectedAddress ? '更换' : '添加' }}</text>
|
||||
</view>
|
||||
<view v-if="selectedAddress" class="addr-info">
|
||||
<text class="addr-row">{{ selectedAddress.receiver }} {{ selectedAddress.mobile }}</text>
|
||||
<text class="addr-row small">{{ selectedAddress.fullAddress || (selectedAddress.region + ' ' + selectedAddress.detail) }}</text>
|
||||
</view>
|
||||
<view v-else class="addr-empty">请添加收货地址</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-title">{{ title }}</view>
|
||||
<view class="price">{{ price }}积分</view>
|
||||
|
||||
<view class="divider"></view>
|
||||
|
||||
<view class="section">
|
||||
<view class="section-label">兑换数量</view>
|
||||
<view class="qty-row">
|
||||
<view class="qty-btn" :class="{ active: qty === 1 }" @click="setQty(1)">1</view>
|
||||
<view class="qty-btn" :class="{ active: qty === 2 }" @click="setQty(2)">2</view>
|
||||
<view class="qty-btn" :class="{ active: qty === 3 }" @click="setQty(3)">3</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<view class="section-label">所需积分</view>
|
||||
<view class="need-points">{{ needPoints }}积分</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="footer-bar">
|
||||
<view class="confirm-btn" @click="goAddress">我要兑换</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import goods_api from '@/api/goods_api'
|
||||
const title = ref('')
|
||||
const price = ref(0)
|
||||
const qty = ref(1)
|
||||
const needPoints = ref(0)
|
||||
const totalPoints = ref(0)
|
||||
const selectedAddress = ref(null)
|
||||
const id = ref('')
|
||||
|
||||
const goBack = () => uni.navigateBack()
|
||||
|
||||
const setQty = (n) => {
|
||||
qty.value = n
|
||||
needPoints.value = n * Number(price.value || 0)
|
||||
}
|
||||
|
||||
onLoad((opts) => {
|
||||
if (opts) {
|
||||
title.value = decodeURIComponent(opts.title || '')
|
||||
price.value = Number(opts.price || 0)
|
||||
id.value = opts.id || ''
|
||||
setQty(1)
|
||||
getTotalPoints()
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
loadAddress()
|
||||
})
|
||||
|
||||
const STORAGE_KEY = 'goods_addresses'
|
||||
const SELECTED_KEY = 'goods_selected_address'
|
||||
const loadAddress = () => {
|
||||
try {
|
||||
const sel = uni.getStorageSync(SELECTED_KEY)
|
||||
if (sel && sel.id) {
|
||||
selectedAddress.value = sel
|
||||
return
|
||||
}
|
||||
const list = uni.getStorageSync(STORAGE_KEY)
|
||||
if (Array.isArray(list) && list.length) {
|
||||
selectedAddress.value = list[0]
|
||||
} else {
|
||||
selectedAddress.value = null
|
||||
}
|
||||
} catch (e) {
|
||||
selectedAddress.value = null
|
||||
}
|
||||
}
|
||||
|
||||
const changeAddress = () => {
|
||||
let list = []
|
||||
try {
|
||||
const cached = uni.getStorageSync(STORAGE_KEY)
|
||||
list = Array.isArray(cached) ? cached : []
|
||||
} catch (e) { list = [] }
|
||||
if (!list.length) {
|
||||
uni.navigateTo({ url: '/pages_goods/exchange/address' })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({ url: '/pages_goods/exchange/address_list' })
|
||||
}
|
||||
|
||||
const goAddress = () => {
|
||||
if (needPoints.value > totalPoints.value) {
|
||||
uni.showToast({ title: '积分不足', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!selectedAddress.value) {
|
||||
changeAddress()
|
||||
return
|
||||
}
|
||||
|
||||
const data = {
|
||||
goodsUuid: id.value,
|
||||
address: selectedAddress.value.fullAddress,
|
||||
user_name: selectedAddress.value.receiver,
|
||||
mobile: selectedAddress.value.mobile,
|
||||
goodsNum: qty.value,
|
||||
email: selectedAddress.value.email
|
||||
}
|
||||
console.log(data)
|
||||
|
||||
|
||||
//{"goodsUuid":"e6ca84edc8e64242a379dd0b895ea812",
|
||||
// "address":"北京市东城区你一下",
|
||||
// "user_name":"噢噢",
|
||||
// "mobile":"13825244552",
|
||||
// "goodsNum":"1",
|
||||
// "email":""}
|
||||
// 模拟下单:此处可调用后端接口完成兑换
|
||||
uni.showModal({
|
||||
title: '确认兑换',
|
||||
content: `兑换“${title.value}”x${qty.value},共需 ${needPoints.value} 积分`,
|
||||
success: (r) => {
|
||||
if (r.confirm) {
|
||||
// 扣减本地积分(演示)
|
||||
totalPoints.value = Math.max(0, totalPoints.value - needPoints.value)
|
||||
uni.removeStorageSync(SELECTED_KEY)
|
||||
goods_api.createGoodsOrder(data).then(res => {
|
||||
console.log(res)
|
||||
if (res.code == 200) {
|
||||
uni.showToast({ title: '兑换成功', icon: 'success' })
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: res.msg, icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const getTotalPoints = () => {
|
||||
goods_api.getTotalPoints && goods_api.getTotalPoints().then(res => {
|
||||
if (res.code == 200) {
|
||||
totalPoints.value = res.data || 0
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.exchange-page { min-height: 100vh; background: #fff; }
|
||||
.content { position: absolute; top: 140rpx; bottom: 120rpx; left: 0; right: 0; background: #fff; }
|
||||
.addr-card { background: #fff; padding: 24rpx; border-bottom: 1rpx solid #f0f0f0; }
|
||||
.addr-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12rpx; }
|
||||
.addr-title { color: #333; font-size: 30rpx; }
|
||||
.addr-change { color: #38c1b1; font-size: 28rpx; }
|
||||
.addr-info { display: flex; flex-direction: column; gap: 8rpx; }
|
||||
.addr-row { color: #333; font-size: 28rpx; }
|
||||
.addr-row.small { color: #666; font-size: 26rpx; }
|
||||
.addr-empty { color: #bbb; font-size: 28rpx; }
|
||||
.goods-title { padding: 24rpx; font-size: 32rpx; color: #333; line-height: 1.6; }
|
||||
.price { padding: 0 24rpx 24rpx; color: #e74c3c; font-size: 30rpx; font-weight: 700; }
|
||||
.divider { height: 16rpx; background: #f5f5f5; }
|
||||
.section { padding: 24rpx; }
|
||||
.section-label { color: #333; font-size: 30rpx; margin-bottom: 20rpx; }
|
||||
.qty-row { display: flex; gap: 24rpx; }
|
||||
.qty-btn { flex: 1; text-align: center; height: 96rpx; line-height: 96rpx; border: 2rpx solid #38c1b1; color: #38c1b1; border-radius: 12rpx; font-size: 36rpx; }
|
||||
.qty-btn.active { background: #38c1b1; color: #fff; }
|
||||
.need-points { color: #333; font-size: 30rpx; text-align: right; }
|
||||
.footer-bar { position: fixed; left: 0; right: 0; bottom: 0; height: 120rpx; background: #27c5b8; display: flex; align-items: center; justify-content: center; }
|
||||
.confirm-btn { color: #fff; font-size: 34rpx; font-weight: 700; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user