This commit is contained in:
那些花儿
2025-05-13 18:27:15 +08:00
parent 178f9b39ff
commit 7949eec70d
31 changed files with 3052 additions and 337 deletions
@@ -1,5 +1,41 @@
<template>
<view class="page-container">
<!-- 人员选项卡区域 -->
<view class="tabs-container">
<view class="tabs-header">
<view class="tabs-title">
<text class="title-text">报名人员</text>
<view class="header-actions">
<view class="person-counter">
<text class="counter-text">{{ formData.userList.length }}人</text>
</view>
<view class="header-add-btn" @click="addNewUser">
<t-icon name="add" size="16px"></t-icon>
</view>
</view>
</view>
</view>
<scroll-view scroll-x="true" class="tabs-scroll-view" show-scrollbar="false">
<view class="tabs">
<view
v-for="(user, index) in formData.userList"
:key="index"
class="tab"
:class="{ active: activeTabIndex === index }"
@click="switchTab(index)"
>
<view class="tab-content">
<view class="tab-icon" v-if="activeTabIndex === index">
<t-icon name="user" size="16px"></t-icon>
</view>
<text class="tab-text">{{ user.userName || `人员${index + 1}` }}</text>
</view>
</view>
</view>
</scroll-view>
<view class="tabs-indicator"></view>
</view>
<view class="form-area">
<t-form
ref="formRef"
@@ -9,6 +45,7 @@
label-align="left"
scroll-to-first-error="auto"
labelWidth="90px"
:requiredMark="true"
>
<!-- <view class="form-block">-->
<!-- <view class="form-block-title">-->
@@ -29,20 +66,19 @@
<view class="form-block">
<view class="form-block-title">
<t-icon name="usergroup"></t-icon>
报名人员信息
</view>
<view v-for="(user,index) in formData.userList" :key="index" class="user-card">
<view class="user-card-header">
<view class="user-card-header-title">
<span>{{ index + 1 }}</span>
</view>
<view class="remove" @click="removeUser(index)">
<text>报名人员信息</text>
<text class="form-subtitle">{{ activeTabIndex + 1 }}/{{ formData.userList.length }}</text>
<view class="user-actions">
<view class="remove-user" @click="removeUser(activeTabIndex)" v-if="formData.userList.length > 1">
<t-icon name="delete" size="18px"></t-icon>
</view>
</view>
</view>
<!-- 所有人员的表单,使用v-show控制显示 -->
<view v-for="(user, index) in formData.userList" :key="index" class="form-fields-container" v-show="activeTabIndex === index">
<t-form-item label="姓名" :name="`userList[${index}].userName`"
:rules="[{required:true,message: '请输入姓名'}]">
:rules="[{required:true,message: '请输入姓名'}]">
<t-input v-model="user.userName" borderless placeholder="请输入内容"></t-input>
</t-form-item>
<t-form-item label="性别" :name="`userList[${index}].sex`" :rules="[{required:true,message: '请选择性别'}]">
@@ -51,47 +87,65 @@
<t-radio :block="false" label="女" value="女"/>
</t-radio-group>
</t-form-item>
<t-form-item label="单位名称">
<t-input v-model="user.unitName" borderless placeholder="请输入单位名称" readonly></t-input>
</t-form-item>
<t-form-item label="职务" :name="`userList[${index}].position`"
:rules="[{required:true,message: '请输入职务'}]">
:rules="[{required:true,message: '请输入职务'}]">
<t-input v-model="user.position" borderless placeholder="请输入职务"></t-input>
</t-form-item>
<t-form-item label="身份证号" :name="`userList[${index}].idCard`"
:rules="[{required:true,message: '请输入身份证号码'},{idcard:true, message: '请输入正确的身份证号码'}]">
:rules="[{required:true,message: '请输入身份证号码'},{idcard:true, message: '请输入正确的身份证号码'}]">
<t-input v-model="user.idCard" borderless placeholder="请输入身份证号码"></t-input>
</t-form-item>
<t-form-item label="联系电话" :name="`userList[${index}].phone`"
:rules="[{required:true,message: '请输入联系电话'},{telnumber:true, message: '请输入正确的联系电话'}]">
:rules="[{required:true,message: '请输入联系电话'},{telnumber:true, message: '请输入正确的联系电话'}]">
<t-input v-model="user.phone" borderless placeholder="请输入联系电话"></t-input>
</t-form-item>
<t-form-item label="是否住宿" :name="`userList[${index}].isStay`"
:rules="[{required:true,message: '请选择是否住宿'}]">
:rules="[{required:true,message: '请选择是否住宿'}]">
<t-radio-group v-model="user.isStay" class="radio-box">
<t-radio :block="false" name="radio" :value="true" label="是"/>
<t-radio :block="false" name="radio" :value="false" label="否"/>
</t-radio-group>
</t-form-item>
<t-form-item label="是否联系人" :name="`userList[${index}].isContacts`"
:rules="[{required:true,message: '请选择是否为联系人'}]">
:rules="[{required:true,message: '请选择是否为联系人'}]">
<t-radio-group v-model="user.isContacts" class="radio-box">
<t-radio :block="false" name="radio" :value="true" label="是"/>
<t-radio :block="false" name="radio" :value="false" label="否"/>
</t-radio-group>
</t-form-item>
<t-form-item label="展示才艺" :name="`userList[${index}].isShowSkill`" :rules="[{required:true,message: '请选择是否展示才艺'}]">
<t-radio-group v-model="user.isShowSkill" class="radio-box">
<t-radio :block="false" name="radio" :value="true" label="是"/>
<t-radio :block="false" name="radio" :value="false" label="否"/>
</t-radio-group>
</t-form-item>
<template v-if="`userList[${index}].isShowSkill`">
<t-form-item label="才艺名称" :name="`userList[${index}].skillName`" :rules="[{required:user.isShowSkill===true,message: '请填写才艺名称'}]">
<t-input v-model="user.skillName" borderless placeholder="请输入才艺名称"></t-input>
</t-form-item>
<t-form-item label="所需器材" :name="`userList[${index}].equip`" :rules="[{required:user.isShowSkill===true,message: '请填写才艺所需器材'}]">
<t-input v-model="user.equip" borderless placeholder="请填写才艺所需器材"></t-input>
</t-form-item>
</template>
<t-form-item label="参加嘉年华" :name="`userList[${index}].isParty`" :rules="[{required:true,message: '请选择是否参加嘉年华'}]">
<t-radio-group v-model="user.isParty" class="radio-box">
<t-radio :block="false" name="radio" :value="true" label="是"/>
<t-radio :block="false" name="radio" :value="false" label="否"/>
</t-radio-group>
</t-form-item>
</view>
</view>
</t-form>
</view>
<!-- 悬浮添加按钮 -->
<view class="float-add-btn" @click="formData.userList.push({})">
<t-icon name="plus" size="24px" color="#fff"></t-icon>
</view>
<view class="footer">
<view class="agreement-checkbox">
<t-checkbox label="多选" icon="rectangle" v-model:checked="agreementChecked" default-checked>
<label>我已阅读并同意
<text class="agreement-link">《参赛承诺书》</text>
<text class="agreement-link" @click="showAgreementPopup">《参赛承诺书》</text>
</label>
</t-checkbox>
</view>
@@ -112,12 +166,32 @@
:steps="guideSteps"
>
</t-guide>
</view>
<!-- 协议确认弹窗 -->
<t-popup v-model:visible="agreementPopupVisible" placement="center" :close-on-overlay-click="false">
<view class="agreement-popup">
<view class="agreement-popup-header">
<text class="agreement-popup-title">参赛条款与免责声明</text>
</view>
<view class="agreement-popup-content">
<view class="agreement-popup-text">
<!-- 阅读并同意本承诺书内容,点击"确定并报名"即表示您已充分理解并接受所有条款,承担相应法律责任。-->
<rich-text :nodes="agreementContent"></rich-text>
</view>
</view>
<view class="agreement-popup-footer">
<t-button variant="outline" block @click="closeAgreementPopup" class="agreement-btn">取消</t-button>
<t-button theme="primary" block :disabled="!canConfirmAgreement" @click="confirmAgreement" class="agreement-btn">
{{ canConfirmAgreement ? '确定并报名' : `请阅读(${agreementCountdown}秒)` }}
</t-button>
</view>
</view>
</t-popup>
</template>
<script setup>
import {ref} from 'vue'
import {ref, computed} from 'vue'
import {useRequest} from '@/utils/request';
import {Dialog, Toast} from "tdesign-mobile-vue";
import {onLoad} from "@dcloudio/uni-app";
@@ -126,19 +200,84 @@ import {useUserStore} from "@/store";
const request = useRequest()
const userStore= useUserStore()
// 当前选中的选项卡索引
const activeTabIndex = ref(0)
// 切换选项卡
function switchTab(index) {
activeTabIndex.value = index
}
// 添加新用户
function addNewUser() {
formData.value.userList.push({
userName: '',
sex: null,
unitName: userStore?.userInfo?.unit?.name,
position: null,
idCard: null,
phone: null,
isStay: null,
isContacts: false,
isShowSkill: false,
skillName: null,
equip: null,
isParty: false
})
// 切换到新添加的用户选项卡
setTimeout(() => {
activeTabIndex.value = formData.value.userList.length - 1
// 滚动到最右边
scrollToRight()
}, 10)
}
// 滚动到指定选项卡
function scrollToTab(index) {
const query = uni.createSelectorQuery()
query.selectAll('.tab').boundingClientRect()
query.select('.tabs-scroll-view').boundingClientRect()
query.exec((res) => {
if (res && res[0] && res[0][index] && res[1]) {
const tabElement = res[0][index]
const scrollView = res[1]
const scrollLeft = tabElement.left - scrollView.left - (scrollView.width / 2) + (tabElement.width / 2)
uni.pageScrollTo({
scrollLeft: scrollLeft > 0 ? scrollLeft : 0,
duration: 300
})
}
})
}
// 滚动到最右边
function scrollToRight() {
const query = uni.createSelectorQuery()
query.select('.tabs-scroll-view').boundingClientRect()
query.exec((res) => {
if (res && res[0]) {
const scrollView = res[0]
const scrollWidth = scrollView.scrollWidth
const clientWidth = scrollView.width
const scrollLeft = scrollWidth - clientWidth
if (scrollLeft > 0) {
uni.pageScrollTo({
scrollLeft: scrollLeft,
duration: 300
})
}
}
})
}
// 引导部分
const guideCurrent = ref(-1)
const guideSteps = [
{
element:()=> document.querySelector('.float-add-btn'),
element:()=> document.querySelector('.header-add-btn'),
title: '添加活动报名人员',
placement: 'top'
},
{
element:()=> document.querySelector('.t-form'),
title: '填写报名信息',
placement: 'top'
},
{
element:()=> document.querySelector('.footer'),
title: '提交报名信息',
@@ -152,25 +291,52 @@ const isSignUp = ref(null)
const agreementChecked = ref(false)
const formRef = ref(null)
const formData = ref({
userList: [{}]
userList: []
})
// 协议弹窗相关
const agreementPopupVisible = ref(false)
const agreementCountdown = ref(5)
const countdownTimer = ref(null)
const canConfirmAgreement = ref(false)
const agreementContent = ref(null)
onLoad((option) => {
onLoad(async (option) => {
if (option.id) {
actId.value = option.id
formData.value.activityId = option.id
listSignUpUser()
getIsSignUp()
await listSignUpUser()
await getIsSignUp()
await getAgreement()
// 没报名进行引导
if(formData.value.userList.length === 0){
if(!formData.value.userList || formData.value.userList.length === 0){
guideCurrent.value = 0
//formData.value.unitName = userStore.userInfo?.unit.name
// 默认是本人的信息
formData.value.userList.push({
userName: userStore.userInfo.userName,
sex: userStore.userInfo.sex,
unitName: userStore?.userInfo?.unit?.name,
position: null,
idCard: userStore.userInfo.idCard,
phone: userStore.userInfo.phone,
isStay: null
})
}
} else {
Toast({message: 'ID不存在', theme: 'error'});
}
})
// 查询参赛承诺书
async function getAgreement() {
try {
const {code, data} = await request.get('/client/activity/agreement/' + actId.value)
if (code === 0 && data) {
agreementContent.value = data
}
}catch (e){
console.error(e)
}
}
// 查询报名人员信息
async function listSignUpUser() {
@@ -216,28 +382,86 @@ async function validaForm() {
// 承诺书
async function validateAgreement() {
return new Promise((resolve, reject) => {
if (agreementChecked.value) {
resolve(true)
return
}
// Always show the popup regardless of checkbox state
// if (agreementChecked.value) {
// resolve(true)
// return
// }
Dialog.confirm({
title: '提示',
content: '参赛条款与免责声明:阅读并同意本承诺书内容,点击"确定并报名"即表示您已充分理解并接受所有条款,承担相应法律责任。',
confirmBtn: '确定并报名',
cancelBtn: '取消',
onConfirm: () => {
agreementChecked.value = true
resolve(true)
},
onCancel: () => {
agreementChecked.value = false
resolve(false)
}
})
// 重置倒计时
agreementCountdown.value = 5
canConfirmAgreement.value = false
// 显示弹窗
agreementPopupVisible.value = true
// 启动倒计时
startAgreementCountdown(resolve)
})
}
// 启动协议倒计时
function startAgreementCountdown(resolvePromise) {
// 清除可能存在的旧计时器
if (countdownTimer.value) {
clearInterval(countdownTimer.value)
}
// 设置新的计时器
countdownTimer.value = setInterval(() => {
agreementCountdown.value--
if (agreementCountdown.value <= 0) {
// 倒计时结束,允许确认
clearInterval(countdownTimer.value)
canConfirmAgreement.value = true
}
}, 1000)
// 保存 Promise 的 resolve 函数,以便在确认或取消时使用
window._resolveAgreementPromise = resolvePromise
}
// 确认协议
function confirmAgreement() {
// 只有在倒计时结束后才能确认
if (!canConfirmAgreement.value) return
// 关闭弹窗
agreementPopupVisible.value = false
// 清除计时器
if (countdownTimer.value) {
clearInterval(countdownTimer.value)
}
// 标记已同意协议
agreementChecked.value = true
// 解析 Promise
if (window._resolveAgreementPromise) {
window._resolveAgreementPromise(true)
window._resolveAgreementPromise = null
}
}
// 关闭协议弹窗
function closeAgreementPopup() {
// 关闭弹窗
agreementPopupVisible.value = false
// 清除计时器
if (countdownTimer.value) {
clearInterval(countdownTimer.value)
}
// 解析 Promise 为 false(未同意)
if (window._resolveAgreementPromise) {
window._resolveAgreementPromise(false)
window._resolveAgreementPromise = null
}
}
// 提交表单
async function onSubmit() {
const formRes = await validaForm()
@@ -287,12 +511,177 @@ async function removeUser(index) {
Toast('至少需要一个报名人员')
return
}
formData.value.userList.splice(index, 1)
Dialog.confirm({
title: '提示',
content: '确定要删除该报名人员吗?',
confirmBtn: '确定',
cancelBtn: '取消',
onConfirm: () => {
formData.value.userList.splice(index, 1)
// 如果删除的是当前选中的选项卡,则选中第一个选项卡
if (index === activeTabIndex.value) {
activeTabIndex.value = 0
}
// 如果删除的是前面的选项卡,则当前选中的选项卡索引减1
else if (index < activeTabIndex.value) {
activeTabIndex.value--
}
}
})
}
// 显示协议弹窗
function showAgreementPopup() {
// 重置倒计时
agreementCountdown.value = 5
canConfirmAgreement.value = false
// 显示弹窗
agreementPopupVisible.value = true
// 启动倒计时
startAgreementCountdown(() => {
// 这里不需要处理,因为协议弹窗会自动显示
})
}
</script>
<style scoped lang="less">
.tabs-container {
flex-shrink: 0;
background-color: #fff;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
position: relative;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.tabs-header {
padding: 10px 16px 5px;
}
.tabs-title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 5px;
}
.title-text {
font-size: 16px;
font-weight: 500;
color: #333;
}
.header-actions {
display: flex;
align-items: center;
}
.person-counter {
background-color: #f45a5a;
border-radius: 12px;
padding: 2px 10px;
margin-right: 8px;
}
.counter-text {
color: #fff;
font-size: 12px;
font-weight: 500;
}
.header-add-btn {
width: 28px;
height: 28px;
border-radius: 50%;
background: linear-gradient(135deg, #f45a5a, #ff7676);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 6px rgba(244, 90, 90, 0.25);
transition: transform 0.2s ease;
}
.header-add-btn:active {
transform: scale(0.92);
}
.tabs-scroll-view {
width: 100%;
white-space: nowrap;
overflow-x: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.tabs-scroll-view::-webkit-scrollbar {
display: none;
}
.tabs {
display: flex;
padding: 10px 12px;
align-items: center;
}
.tab {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 90px;
height: 35px;
padding: 0 14px;
margin: 0 5px;
font-size: 14px;
color: #666;
background-color: #f8f8f8;
border-radius: 19px;
transition: all 0.25s ease;
position: relative;
border: 1px solid transparent;
}
.tab-content {
display: flex;
align-items: center;
justify-content: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.tab-icon {
margin-right: 4px;
display: flex;
align-items: center;
}
.tab-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tab.active {
color: #fff;
background-color: #f45a5a;
box-shadow: 0 3px 8px rgba(244, 90, 90, 0.25);
font-weight: 500;
}
.tabs-indicator {
position: absolute;
bottom: -1px;
left: 0;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, rgba(244, 90, 90, 0.3), transparent);
}
.act-info {
position: fixed;
top: 44px;
@@ -340,6 +729,7 @@ async function removeUser(index) {
flex: 1;
overflow-y: auto;
margin-bottom: 130px;
padding-top: 10px;
}
.form-block {
@@ -347,6 +737,7 @@ async function removeUser(index) {
background: white;
margin-bottom: 10px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
border-radius: 8px;
.form-block-title {
font-size: 16px;
@@ -355,83 +746,45 @@ async function removeUser(index) {
color: #333;
display: flex;
align-items: center;
justify-content: flex-start;
.t-icon {
margin-right: 5px;
color: var(--td-brand-color);
}
}
}
.user-card {
background: white;
margin-bottom: 20px;
position: relative;
border-left: 3px solid #e74c3c;
padding-left: 12px;
.user-card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
.user-card-header-title {
font-weight: 500;
color: #333;
font-size: 15px;
display: flex;
align-items: center;
span {
display: flex;
justify-content: center;
align-items: center;
width: 24px;
height: 24px;
background-color: #e74c3c;
color: white;
border-radius: 50%;
font-size: 14px;
margin-right: 8px;
}
}
.remove {
color: #e74c3c;
//font-size: 14px;
display: flex;
align-items: center;
background: none;
border: none;
cursor: pointer;
.form-subtitle {
font-size: 12px;
color: #999;
margin-left: 8px;
font-weight: normal;
}
}
}
.float-add-btn {
position: fixed;
right: 32rpx;
bottom: 160rpx;
width: 110rpx;
height: 110rpx;
border-radius: 50%;
background-color: #e74c3c;
.form-fields-container {
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from { opacity: 0.6; }
to { opacity: 1; }
}
.user-actions {
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
transition: transform 0.2s;
margin-left: auto;
}
.float-add-btn:active {
transform: scale(0.95);
.remove-user {
padding: 5px;
color: #f45a5a;
cursor: pointer;
}
.radio-box {
width: 100%;
display: flex;
column-gap: 20px;
}
.footer {
@@ -439,12 +792,95 @@ async function removeUser(index) {
bottom: 0;
left: 0;
right: 0;
padding: 0 16px 16px;
background-color: white;
box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);
z-index: 10;
max-width: 750px;
margin: 0 auto;
width: 100%;
padding: 16px;
background: white;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
z-index: 99;
}
.agreement-checkbox {
margin-bottom: 16px;
display: flex;
align-items: center;
font-size: 14px;
color: #666;
}
.agreement-link {
color: var(--td-brand-color);
}
.quick-nav {
position: fixed;
right: 16px;
bottom: 140px;
display: flex;
flex-direction: column;
gap: 10px;
z-index: 90;
}
.quick-nav-btn {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: rgba(244, 90, 90, 0.9);
color: white;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
transition: transform 0.2s ease, background-color 0.2s ease;
}
.quick-nav-btn:active {
transform: scale(0.95);
background-color: rgba(244, 90, 90, 1);
}
/* 协议弹窗样式 */
.agreement-popup {
width: 85vw;
max-width: 320px;
background-color: #fff;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
.agreement-popup-header {
padding: 20px 16px 10px;
text-align: center;
border-bottom: 1px solid #f0f0f0;
}
.agreement-popup-title {
font-size: 18px;
font-weight: 600;
color: #333;
}
.agreement-popup-content {
padding: 20px 16px;
max-height: 60vh;
overflow-y: auto;
}
.agreement-popup-text {
font-size: 15px;
line-height: 1.5;
color: #666;
padding: 0 16px;
}
.agreement-popup-footer {
padding: 16px;
display: flex;
gap: 10px;
border-top: 1px solid #f0f0f0;
}
.agreement-btn {
height: 44px;
}
</style>
@@ -78,12 +78,7 @@ const navigateToEdit = () => {
<style scoped lang="less">
.page-container {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-bottom: 50px;
background-color: #fff;
min-height: 100vh;
}
/* 成功内容区域 */
+22 -2
View File
@@ -52,7 +52,7 @@
</div>
<view class="title-content">
<text class="main-title">第二届“钟声杯”直属工会趣味运动会</text>
<text class="main-title">第二届"钟声杯"直属工会趣味运动会</text>
<view class="sub-title-container">
<text class="sub-title">欢迎使用</text>
</view>
@@ -128,6 +128,13 @@
</view>
</view>
</view>
<!-- 底部信息 -->
<view class="footer-info">
<view class="footer-item">主办单位:浙江省教育工会</view>
<view class="footer-item">承办单位:杭州医学院工会</view>
<view class="footer-item">技术支持:武汉地大三思科技有限公司</view>
</view>
</view>
</template>
@@ -290,7 +297,7 @@ async function handleLogin() {
Toast({message: '登录成功', theme: 'success'})
const redirect = uni.getStorageSync("REDIRECT_URL")
if(redirect){
if(redirect.startsWith('/pages/index/index') || redirect.startsWith('/pages/profile/index')){
if(redirect.startsWith('/pages/index/index') || redirect.startsWith('/pages/activity/rank/index') || redirect.startsWith('/pages/profile/index')){
uni.switchTab({
url: redirect
})
@@ -515,4 +522,17 @@ body {
margin-left: 4px;
}
}
/* 底部信息样式 */
.footer-info {
padding: 20px 30px;
text-align: center;
background-color: #ffffff;
}
.footer-item {
font-size: 12px;
color: #999;
line-height: 1.8;
}
</style>
+21 -1
View File
@@ -53,7 +53,7 @@
</div>
<view class="title-content">
<text class="main-title">第二届“钟声杯”直属工会趣味运动会</text>
<text class="main-title">第二届"钟声杯"直属工会趣味运动会</text>
<view class="sub-title-container">
<text class="sub-title">用户注册</text>
</view>
@@ -134,6 +134,13 @@
</view>
</view>
<!-- 底部信息 -->
<view class="footer-info">
<view class="footer-item">主办单位:浙江省教育工会</view>
<view class="footer-item">承办单位:杭州医学院工会</view>
<view class="footer-item">技术支持:武汉地大三思科技有限公司</view>
</view>
<!-- 自定义单位选择弹窗 -->
<t-popup v-model="showUnitPicker" placement="bottom">
<view class="custom-picker">
@@ -687,4 +694,17 @@ onMounted(() => {
font-size: 28rpx;
color: #999;
}
/* 底部信息样式 */
.footer-info {
padding: 20px 30px;
text-align: center;
background-color: #ffffff;
}
.footer-item {
font-size: 12px;
color: #999;
line-height: 1.8;
}
</style>
+2 -1
View File
@@ -34,7 +34,8 @@ export default defineConfig({
},*/
proxy: {
'/api': {
target: 'http://119.91.224.39:9090/',
// target: 'http://119.91.224.39:9090/',
target: 'http://192.168.118.1:9090/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}