first commit
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<script>
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
console.log('App Launch')
|
||||
},
|
||||
onShow: function () {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
console.log('App Hide')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/*每个页面公共css */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 14px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
color: #333;
|
||||
background-color: #f5f5f5;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
uni-page-body{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,17 @@
|
||||
import {createSSRApp} from "vue";
|
||||
import App from "./App.vue";
|
||||
|
||||
// 引入TDesign组件库
|
||||
import TDesign from 'tdesign-mobile-vue';
|
||||
// 引入组件库的少量全局样式变量
|
||||
import 'tdesign-mobile-vue/es/style/index.css';
|
||||
// 自定义组件库样式
|
||||
import './theme.css'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
app.use(TDesign); // 使用TDesign组件库
|
||||
return {
|
||||
app,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name" : "",
|
||||
"appid" : "",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"vueVersion" : "3"
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "uni-app"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/activity/list/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "赛事活动"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/activity/detail/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "活动详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/activity/registration-form/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "活动报名"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/activity/team/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的团队"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "#FFFFFF",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#ff5050",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
},
|
||||
"tabBar": {
|
||||
"color": "#000",
|
||||
"selectedColor": "#ff5050",
|
||||
"borderStyle": "black",
|
||||
"backgroundColor": "#ffffff",
|
||||
"height": "60px",
|
||||
"fontSize": "12px",
|
||||
"iconWidth": "24px",
|
||||
"spacing": "3px",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/index/index",
|
||||
"text": "组件"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/my/index",
|
||||
"text": "接口"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,372 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<!-- 顶部搜索区域 -->
|
||||
<view class="header">
|
||||
<t-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
placeholder="搜索活动"
|
||||
shape="round"
|
||||
class="search"
|
||||
>
|
||||
<template #action>
|
||||
<t-button variant="text" @click="filterVisible = true">筛选</t-button>
|
||||
</template>
|
||||
</t-search>
|
||||
</view>
|
||||
|
||||
<!-- 筛选弹出层 -->
|
||||
<t-popup
|
||||
v-model:visible="filterVisible"
|
||||
placement="top"
|
||||
>
|
||||
<view class="filter">
|
||||
<view class="filter-header">
|
||||
<t-button variant="text" @click="handleClearFilter">重置</t-button>
|
||||
<text class="filter-title">筛选条件</text>
|
||||
<t-button theme="primary" variant="text" @click="handleSearch">确定</t-button>
|
||||
</view>
|
||||
|
||||
<t-cell-group title="状态">
|
||||
<t-radio-group v-model="pageForm.status">
|
||||
<t-radio
|
||||
v-for="option in statusOptions"
|
||||
:key="option.value"
|
||||
:value="option.value"
|
||||
:label="option.label"
|
||||
borderless
|
||||
/>
|
||||
</t-radio-group>
|
||||
</t-cell-group>
|
||||
</view>
|
||||
</t-popup>
|
||||
|
||||
<!-- 活动列表 -->
|
||||
<scroll-view
|
||||
style="overflow-y: auto;flex: 1"
|
||||
:scroll-y="true"
|
||||
:show-scrollbar="false"
|
||||
@scrolltolower="onLoadMore"
|
||||
:refresher-enabled="true"
|
||||
@refresherrefresh="getListData(true)"
|
||||
:refresher-triggered="refreshIng"
|
||||
refresher-background="#f5f5f5"
|
||||
>
|
||||
<view class="card"
|
||||
v-for="item in dataList"
|
||||
:key="item.id"
|
||||
@click="navigateToDetail(item.id)"
|
||||
>
|
||||
<view class="card-head">
|
||||
<image :src="item.image" mode="aspectFill" class="card-img"/>
|
||||
<text class="card-tag" :class="getStatusClass(item.status)">
|
||||
{{ getStatusText(item.status) }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="card-body">
|
||||
<view class="card-title">{{ item.title }}</view>
|
||||
|
||||
<view class="card-info">
|
||||
<view class="info-item">
|
||||
<t-icon name="alarm" size="12px"/>
|
||||
<text>{{ item.date }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<t-icon name="location" size="12px"/>
|
||||
<text>{{ item.location }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<t-icon name="user" size="12px"/>
|
||||
<text>{{ item.participants }}人已报名</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card-footer">
|
||||
<view class="price">
|
||||
<text class="price-symbol">¥</text>
|
||||
<text class="price-value">{{ item.price }}</text>
|
||||
</view>
|
||||
<t-button
|
||||
size="small"
|
||||
shape="round"
|
||||
:theme="item.status === 2 ? 'default' : 'primary'"
|
||||
:disabled="item.status === 2"
|
||||
>
|
||||
{{ item.status === 1 ? '立即报名' : item.status === 3 ? '预约提醒' : '已结束' }}
|
||||
</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="loading-area">
|
||||
<t-loading v-if="loading" text="加载中" layout="vertical"/>
|
||||
<t-divider v-else-if="!hasMore && dataList.length > 0" content="没有更多了"/>
|
||||
</view>
|
||||
|
||||
<t-empty v-if="!loading && !refreshIng && dataList.length === 0"
|
||||
image="https://tdesign.gtimg.com/mobile/demos/empty1.png" description="暂无活动">
|
||||
<template #action>
|
||||
<t-button theme="primary" size="small" shape="round">刷新试试</t-button>
|
||||
</template>
|
||||
</t-empty>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, reactive, onMounted} from 'vue';
|
||||
import {Toast} from 'tdesign-mobile-vue';
|
||||
import {useRequest} from "@/util/request";
|
||||
|
||||
// 筛选选项
|
||||
const statusOptions = [
|
||||
{value: '', label: '全部'},
|
||||
{value: '1', label: '进行中'},
|
||||
{value: '2', label: '已结束'},
|
||||
{value: '3', label: '未开始'}
|
||||
];
|
||||
|
||||
const pageForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: null,
|
||||
status: null
|
||||
})
|
||||
|
||||
// 数据与状态
|
||||
const dataList = ref([]);
|
||||
const loading = ref(false);
|
||||
const hasMore = ref(true);
|
||||
const refreshIng = ref(false);
|
||||
const filterVisible = ref(false);
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
keyword: '',
|
||||
status: ''
|
||||
});
|
||||
|
||||
// 获取状态样式类
|
||||
const getStatusClass = (status) => {
|
||||
return {
|
||||
1: 'status-active',
|
||||
2: 'status-ended',
|
||||
3: 'status-upcoming'
|
||||
}[status] || '';
|
||||
};
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
return {
|
||||
1: '报名中',
|
||||
2: '已结束',
|
||||
3: '即将开始'
|
||||
}[status] || '未知状态';
|
||||
};
|
||||
|
||||
// 获取列表数据
|
||||
const getListData = async (isRefresh = false) => {
|
||||
if (isRefresh) {
|
||||
refreshIng.value = true;
|
||||
pageForm.pageNumber = 1;
|
||||
} else {
|
||||
loading.value = true
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
try {
|
||||
const {code, data, msg} = await useRequest().post('/client/activity/pageData', {
|
||||
...pageForm
|
||||
})
|
||||
|
||||
if (code === 0) {
|
||||
if (isRefresh) {
|
||||
dataList.value = data.list;
|
||||
} else {
|
||||
dataList.value = [...dataList.value, ...data.list];
|
||||
}
|
||||
hasMore.value = dataList.value.length < data.totalCount;
|
||||
pageForm.pageNumber++;
|
||||
console.log(hasMore.value)
|
||||
} else {
|
||||
console.error('获取列表失败', msg)
|
||||
Toast({message: '获取列表失败', theme: 'error'});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取列表失败', error);
|
||||
Toast({message: '获取列表失败', theme: 'error'});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
refreshIng.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索处理
|
||||
const handleSearch = () => {
|
||||
hasMore.value = true;
|
||||
dataList.value = [];
|
||||
getListData();
|
||||
};
|
||||
|
||||
// 清空筛选
|
||||
const handleClearFilter = () => {
|
||||
pageForm.keyword = null
|
||||
pageForm.status = null
|
||||
filterVisible.value = false;
|
||||
};
|
||||
|
||||
// 加载更多
|
||||
const onLoadMore = () => {
|
||||
if (loading.value || !hasMore.value) return;
|
||||
getListData();
|
||||
};
|
||||
|
||||
// 跳转详情
|
||||
const navigateToDetail = (id) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/activity/detail/index?id=${id}`
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getListData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.header {
|
||||
background-color: #fff;
|
||||
padding: 10px 16px;
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.search {
|
||||
--td-search-bg-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.filter {
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 16px 16px;
|
||||
padding: 0 16px 20px;
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.card-head {
|
||||
position: relative;
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
.card-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.card-tag {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 0;
|
||||
padding: 4px 12px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.status-active {
|
||||
background-color: #28c445;
|
||||
}
|
||||
|
||||
.status-ended {
|
||||
background-color: #999;
|
||||
}
|
||||
|
||||
.status-upcoming {
|
||||
background-color: #ff9800;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 12px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.card-info {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.info-item :deep(i) {
|
||||
margin-right: 6px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.price-symbol {
|
||||
font-size: 14px;
|
||||
color: #ff5050;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.price-value {
|
||||
font-size: 22px;
|
||||
color: #ff5050;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.loading-area {
|
||||
padding: 16px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
|
||||
<view class="act-info">
|
||||
<view class="act-title">奋进新征程 运动促健康 2024晴江第六届"牧城之夜"荧光跑</view>
|
||||
<view class="act-meta">
|
||||
<view class="act-meta-item">22222</view>
|
||||
<view class="act-meta-item">22222222222222222222</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-area">
|
||||
<t-form
|
||||
ref="formRef"
|
||||
:data="formData"
|
||||
reset-type="initial"
|
||||
show-error-message
|
||||
label-align="left"
|
||||
scroll-to-first-error="auto"
|
||||
>
|
||||
<view class="form-block">
|
||||
<view class="form-block-title">
|
||||
<t-icon name="institution"></t-icon>
|
||||
单位信息
|
||||
</view>
|
||||
<t-form-item label="参加单位" name="unitName" :rules="[{required:true,message: '请输入单位名称'}]">
|
||||
<t-input v-model="formData.unitName" borderless placeholder="请输入参加单位名称"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="联系人" name="contactName" :rules="[{required:true,message: '请输入联系人姓名'}]">
|
||||
<t-input v-model="formData.contactName" borderless placeholder="请输入联系人姓名"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="联系方式" name="contactPhone" :rules="[{required:true,message: '请输入联系电话'}]">
|
||||
<t-input v-model="formData.contactPhone" borderless placeholder="请输入联系电话"></t-input>
|
||||
</t-form-item>
|
||||
</view>
|
||||
|
||||
<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="formData.userList.splice(index, 1)">
|
||||
<t-icon name="delete" size="18px"></t-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<t-form-item label="姓名" :name="`userList[${index}].name`"
|
||||
:rules="[{required:true,message: '请输入姓名'}]">
|
||||
<t-input v-model="user.name" borderless placeholder="请输入内容"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="性别" :name="`userList[${index}].sex`" :rules="[{required:true,message: '请选择性别'}]">
|
||||
<t-radio-group v-model="user.sex" borderless class="radio-box">
|
||||
<t-radio :block="false" label="男" value="男"/>
|
||||
<t-radio :block="false" label="女" value="女"/>
|
||||
</t-radio-group>
|
||||
</t-form-item>
|
||||
<t-form-item label="职务" :name="`userList[${index}].job`" :rules="[{required:true,message: '请输入职务'}]">
|
||||
<t-input v-model="user.job" borderless placeholder="请输入职务"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="身份证号" :name="`userList[${index}].idCard`"
|
||||
: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: '请输入正确的联系电话'}]">
|
||||
<t-input v-model="user.phone" borderless placeholder="请输入联系电话"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="是否住宿" :name="`userList[${index}].sleep`"
|
||||
:rules="[{required:true,message: '请选择是否住宿'}]">
|
||||
<t-radio-group v-model="user.sleep" class="radio-box">
|
||||
<t-radio :block="false" name="radio" value="1" label="是"/>
|
||||
<t-radio :block="false" name="radio" value="2" label="否"/>
|
||||
</t-radio-group>
|
||||
</t-form-item>
|
||||
</view>
|
||||
</view>
|
||||
</t-form>
|
||||
<view class="add-user" @click="formData.userList.push({})">
|
||||
<t-icon name="plus" size="24px"></t-icon>
|
||||
<text>添加人员</text>
|
||||
</view>
|
||||
</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>
|
||||
</label>
|
||||
</t-checkbox>
|
||||
</view>
|
||||
<t-button
|
||||
block
|
||||
theme="primary"
|
||||
size="large"
|
||||
shape="round"
|
||||
@click="onSubmit"
|
||||
>
|
||||
提交报名
|
||||
</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
|
||||
const agreementChecked = ref(false)
|
||||
const formRef = ref(null)
|
||||
const formData = ref({
|
||||
unitName: null,
|
||||
userList: []
|
||||
})
|
||||
|
||||
function onSubmit() {
|
||||
console.log(formRef)
|
||||
console.log(formRef.value)
|
||||
formRef.value.validate()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.act-info {
|
||||
position: fixed;
|
||||
top: 44px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
padding: 12px 16px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
||||
z-index: 9;
|
||||
max-width: 750px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
min-height: 70px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.act-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.event-meta {
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin-top: 2px;
|
||||
|
||||
.event-meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-area{
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
margin-top: 100px;
|
||||
margin-bottom: 130px;
|
||||
}
|
||||
|
||||
.form-block {
|
||||
padding: 20px 16px;
|
||||
background: white;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.form-block-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 16px;
|
||||
color: #333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-user {
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
color: #e74c3c;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.radio-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
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%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,313 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<t-dropdown-menu @menu-opened="handleMenuOpened" @menu-closed="handleMenuClosed">
|
||||
<t-dropdown-item :options="actOptions" :value="pageForm.actId" @change="actChange" />
|
||||
</t-dropdown-menu>
|
||||
|
||||
<div class="content-area">
|
||||
<!-- 团队信息卡片 -->
|
||||
<div class="team-card">
|
||||
<div class="team-banner">
|
||||
<div class="team-logo">
|
||||
<i class="bi bi-people-fill" v-if="!team.logoUrl"></i>
|
||||
<img :src="team.logoUrl" alt="团队logo" v-if="team.logoUrl">
|
||||
</div>
|
||||
<div class="team-info">
|
||||
<div class="team-name">{{ team.name }}</div>
|
||||
<div class="team-meta">创建于 {{ team.createdDate }}</div>
|
||||
<div class="team-id">团队ID: {{ team.id }}</div>
|
||||
</div>
|
||||
<div class="event-name">{{ team.eventName }}</div>
|
||||
</div>
|
||||
|
||||
<div class="team-detail">
|
||||
<div class="team-stat-row">
|
||||
<div class="team-stat-item">
|
||||
<div class="team-stat-value">{{ team.memberCount }}</div>
|
||||
<div class="team-stat-label">团队成员</div>
|
||||
</div>
|
||||
<div class="team-stat-item">
|
||||
<div class="team-stat-value">{{ team.rank }}</div>
|
||||
<div class="team-stat-label">当前排名</div>
|
||||
</div>
|
||||
<div class="team-stat-item">
|
||||
<div class="team-stat-value">{{ team.score }}</div>
|
||||
<div class="team-stat-label">团队积分</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="font-size: 14px; color: #666; line-height: 1.6;">
|
||||
{{ team.description }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 团队成员 -->
|
||||
<div class="team-section">
|
||||
<div class="section-header">
|
||||
<div class="section-title">
|
||||
<i class="bi bi-people"></i>团队成员
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="member-list">
|
||||
<div class="member-item" v-for="member in team.members" :key="member.id">
|
||||
<div class="member-avatar">
|
||||
<img :src="member.avatar" :alt="member.name" onerror="this.src='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cmVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgZmlsbD0iI2YwZjBmMCIvPjx0ZXh0IHg9IjUwJSIgeT0iNTAlIiBmb250LXNpemU9IjIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBhbGlnbm1lbnQtYmFzZWxpbmU9Im1pZGRsZSIgZm9udC1mYW1pbHk9IkFyaWFsLCBzYW5zLXNlcmlmIiBmaWxsPSIjNTU1Ij57eyBtZW1iZXIubmFtZS5jaGFyQXQoMCkgfX08L3RleHQ+PC9zdmc+'">
|
||||
</div>
|
||||
<div class="member-info">
|
||||
<div class="member-name">
|
||||
{{ member.name }}
|
||||
<span class="member-role" v-if="member.role === 'leader'">队长</span>
|
||||
<span class="member-role" v-else-if="member.role === 'admin'" style="background-color: #ff9a5a;">管理员</span>
|
||||
</div>
|
||||
<div class="member-detail">
|
||||
<div class="member-detail-item">
|
||||
<i class="bi bi-gender-ambiguous"></i>
|
||||
<span>{{ member.gender }}</span>
|
||||
</div>
|
||||
<div class="member-detail-item">
|
||||
<i class="bi bi-building"></i>
|
||||
<span>{{ member.organization }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="member-actions">
|
||||
<i class="bi bi-three-dots-vertical"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 当前角色与申请队长 -->
|
||||
<div v-if="currentUserRole !== 'leader'">
|
||||
<div class="role-notice" v-if="currentUserRole === 'admin'">
|
||||
<i class="bi bi-info-circle"></i>
|
||||
您当前是管理员身份,拥有团队管理权限
|
||||
</div>
|
||||
<div class="role-notice" v-else>
|
||||
<i class="bi bi-info-circle"></i>
|
||||
您当前是普通成员身份
|
||||
</div>
|
||||
<button class="apply-leader-btn" @click="showLeaderConfirm">
|
||||
<i class="bi bi-award"></i>申请成为队长
|
||||
</button>
|
||||
</div>
|
||||
<div class="role-notice" v-else>
|
||||
<i class="bi bi-check-circle"></i>
|
||||
您当前是队长身份,拥有团队所有权限
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 项目报名按钮 -->
|
||||
<div class="team-section">
|
||||
<button class="register-btn" @click="goToEventRegistration">
|
||||
<i class="bi bi-calendar-check"></i>
|
||||
项目报名
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref,reactive} from "vue";
|
||||
|
||||
const actOptions = ref([])
|
||||
|
||||
const pageForm = reactive({
|
||||
actId: null,
|
||||
})
|
||||
|
||||
const teamId = ''
|
||||
|
||||
const team = reactive({
|
||||
id: teamId,
|
||||
name: '江苏健康跑团',
|
||||
logoUrl: null,
|
||||
createdDate: '2023-10-15',
|
||||
eventId: '',
|
||||
eventName: '',
|
||||
memberCount: 12,
|
||||
rank: 5,
|
||||
score: 256,
|
||||
description: '我们是一支来自江苏省的健康跑团队,致力于推广健康跑步文化,鼓励大家积极参与体育活动,共同展现江苏的活力风采。',
|
||||
|
||||
// 团队成员
|
||||
members: [
|
||||
{
|
||||
id: '101',
|
||||
name: '张伟',
|
||||
role: 'leader',
|
||||
gender: '男',
|
||||
organization: '江苏体育学院',
|
||||
avatar: null
|
||||
},
|
||||
{
|
||||
id: '102',
|
||||
name: '李娜',
|
||||
role: 'admin',
|
||||
gender: '女',
|
||||
organization: '南京体育局',
|
||||
avatar: null
|
||||
},
|
||||
{
|
||||
id: '103',
|
||||
name: '王强',
|
||||
role: 'member',
|
||||
gender: '男',
|
||||
organization: '南京体育学院',
|
||||
avatar: null
|
||||
},
|
||||
{
|
||||
id: '104',
|
||||
name: '刘芳',
|
||||
role: 'member',
|
||||
gender: '女',
|
||||
organization: '江苏大学',
|
||||
avatar: null
|
||||
},
|
||||
{
|
||||
id: '105',
|
||||
name: '陈明',
|
||||
role: 'member',
|
||||
gender: '男',
|
||||
organization: '苏州体育中心',
|
||||
avatar: null
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
function handleMenuOpened(){
|
||||
|
||||
}
|
||||
|
||||
function handleMenuClosed(){}
|
||||
|
||||
function actChange(val){
|
||||
console.log(val)
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
/* 主体内容区 */
|
||||
.content-area {
|
||||
}
|
||||
|
||||
/* 团队信息卡片 */
|
||||
.team-card {
|
||||
background-color: white;
|
||||
margin: 15px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.team-banner {
|
||||
position: relative;
|
||||
height: 120px;
|
||||
background: linear-gradient(135deg, #e74c3c, #ff7675);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.team-logo {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
background-color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 15px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.8);
|
||||
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.team-logo img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.team-logo i {
|
||||
font-size: 40px;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.team-info {
|
||||
flex: 1;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.team-name {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 6px;
|
||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.team-meta {
|
||||
font-size: 13px;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.team-id {
|
||||
display: inline-block;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.event-name {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 15px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
padding: 3px 10px;
|
||||
border-radius: 15px;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 团队详情内容 */
|
||||
.team-detail {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.team-stat-row {
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.team-stat-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.team-stat-value {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #e74c3c;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.team-stat-label {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,267 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<!-- 顶部背景和内容区 -->
|
||||
<view class="header">
|
||||
<image class="header-bg" src="https://erp-bucket.pek3b.qingstor.com/assistant/89c4b573-c54f-467a-b703-0bc44679ab08.png" mode="aspectFill"></image>
|
||||
</view>
|
||||
|
||||
<!-- 功能菜单区 -->
|
||||
<view class="menu-container">
|
||||
<view class="menu-item" @click="navigateTo('/pages/activity/list/index')">
|
||||
<view class="menu-icon-wrapper red-bg">
|
||||
<view class="menu-icon trophy-icon"></view>
|
||||
</view>
|
||||
<view class="menu-text">赛事报名</view>
|
||||
</view>
|
||||
<view class="menu-item" @click="navigateTo('/pages/scan/index')">
|
||||
<view class="menu-icon-wrapper orange-bg">
|
||||
<view class="menu-icon qrcode-icon"></view>
|
||||
</view>
|
||||
<view class="menu-text">扫码签到</view>
|
||||
</view>
|
||||
<view class="menu-item" @click="navigateTo('/pages/activity/team/index')">
|
||||
<view class="menu-icon-wrapper yellow-bg">
|
||||
<view class="menu-icon team-icon"></view>
|
||||
<view class="badge">3</view>
|
||||
</view>
|
||||
<view class="menu-text">我的团队</view>
|
||||
</view>
|
||||
<view class="menu-item" @click="navigateTo('/pages/activity/team/index')">
|
||||
<view class="menu-icon-wrapper blue-bg">
|
||||
<view class="menu-icon star-icon"></view>
|
||||
</view>
|
||||
<view class="menu-text">项目报名</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 精选内容区 -->
|
||||
<view class="content-section">
|
||||
<view class="section-header">
|
||||
<view class="section-title">精选活动</view>
|
||||
<view class="section-more" @click="navigateTo('/pages/activity/index')">更多</view>
|
||||
</view>
|
||||
|
||||
<view class="activity-list">
|
||||
<view class="activity-item" @click="navigateTo('/pages/process/index')">
|
||||
<image class="activity-image" src="https://erp-bucket.pek3b.qingstor.com/assistant/746c37d6-018d-4c64-8a98-ea9ec8b0b3b5.png" mode="widthFix"></image>
|
||||
<view class="activity-info">
|
||||
<view class="activity-title">一分钟了解运动会流程</view>
|
||||
<view class="activity-meta">
|
||||
<text class="activity-time">6月15日-20日</text>
|
||||
<text class="activity-location">江苏省体育中心</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from "vue";
|
||||
|
||||
function navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
console.log('...........')
|
||||
uni.showToast({
|
||||
title: '欢迎使用',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
// 头部区域样式
|
||||
.header {
|
||||
position: relative;
|
||||
height: 245px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header-bg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
// 菜单区域样式
|
||||
.menu-container {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 15px;
|
||||
margin: -30px 15px 15px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 22%;
|
||||
}
|
||||
|
||||
.menu-icon-wrapper {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.red-bg {
|
||||
background: linear-gradient(135deg, #ff7676, #f45a5a);
|
||||
}
|
||||
|
||||
.orange-bg {
|
||||
background: linear-gradient(135deg, #ffa76a, #f89f58);
|
||||
}
|
||||
|
||||
.yellow-bg {
|
||||
background: linear-gradient(135deg, #ffd166, #f8c158);
|
||||
}
|
||||
|
||||
.blue-bg {
|
||||
background: linear-gradient(135deg, #72a1ff, #5c7cfa);
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.trophy-icon {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M19 5h-2V3H7v2H5c-1.1 0-2 .9-2 2v1c0 2.55 1.92 4.63 4.39 4.94.63 1.5 1.98 2.63 3.61 2.96V19H7v2h10v-2h-4v-3.1c1.63-.33 2.98-1.46 3.61-2.96C19.08 12.63 21 10.55 21 8V7c0-1.1-.9-2-2-2zM5 8V7h2v3.82C5.84 10.4 5 9.3 5 8zm14 0c0 1.3-.84 2.4-2 2.82V7h2v1z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.qrcode-icon {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zM13 3v8h8V3h-8zm6 6h-4V5h4v4zM13 13h2v2h-2zM15 15h2v2h-2zM13 17h2v2h-2zM17 17h2v2h-2zM19 19h2v2h-2zM15 19h2v2h-2zM17 13h2v2h-2zM19 15h2v2h-2z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.team-icon {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5s-3 1.34-3 3 1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.star-icon {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: -5px;
|
||||
background-color: #ff4d4f;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
padding: 0 5px;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 2px 4px rgba(255, 77, 79, 0.3);
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// 内容区域样式
|
||||
.content-section {
|
||||
margin: 0 0 15px;
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
position: relative;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 3px;
|
||||
height: 16px;
|
||||
background: linear-gradient(to bottom, #ff6b6b, #e83a3a);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.section-more {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
// 活动列表样式
|
||||
.activity-list {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activity-item {
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.activity-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.activity-image {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activity-info {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.activity-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.activity-meta {
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.activity-time {
|
||||
margin-right: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
我的页面
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
export {};
|
||||
|
||||
declare module "vue" {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
interface ComponentCustomOptions extends Hooks {}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,337 @@
|
||||
:root, :root[theme-mode="light"] {
|
||||
--td-brand-color-1: #fff0ed;
|
||||
--td-brand-color-2: #ffd8d3;
|
||||
--td-brand-color-3: #ffb8b1;
|
||||
--td-brand-color-4: #ff928c;
|
||||
--td-brand-color-5: #ff5f5c;
|
||||
--td-brand-color-6: #df3d3f;
|
||||
--td-brand-color-7: #b6292d;
|
||||
--td-brand-color-8: #8f121b;
|
||||
--td-brand-color-9: #6b000a;
|
||||
--td-brand-color-10: #490005;
|
||||
--td-brand-color-light: var(--td-brand-color-1);
|
||||
--td-brand-color-focus: var(--td-brand-color-2);
|
||||
--td-brand-color-disabled: var(--td-brand-color-3);
|
||||
--td-brand-color: var(--td-brand-color-5);
|
||||
--td-brand-color-active: var(--td-brand-color-6);
|
||||
--td-warning-color-1: #fef3e6;
|
||||
--td-warning-color-2: #f9e0c7;
|
||||
--td-warning-color-3: #f7c797;
|
||||
--td-warning-color-4: #f2995f;
|
||||
--td-warning-color-5: #ed7b2f;
|
||||
--td-warning-color-6: #d35a21;
|
||||
--td-warning-color-7: #ba431b;
|
||||
--td-warning-color-8: #9e3610;
|
||||
--td-warning-color-9: #842b0b;
|
||||
--td-warning-color-10: #5a1907;
|
||||
--td-warning-color: var(--td-warning-color-5);
|
||||
--td-warning-color-focus: var(--td-warning-color-2);
|
||||
--td-warning-color-active: var(--td-warning-color-6);
|
||||
--td-warning-color-disabled: var(--td-warning-color-3);
|
||||
--td-warning-color-light: var(--td-warning-color-1);
|
||||
--td-error-color-1: #fdecee;
|
||||
--td-error-color-2: #f9d7d9;
|
||||
--td-error-color-3: #f8b9be;
|
||||
--td-error-color-4: #f78d94;
|
||||
--td-error-color-5: #f36d78;
|
||||
--td-error-color-6: #e34d59;
|
||||
--td-error-color-7: #c9353f;
|
||||
--td-error-color-8: #b11f26;
|
||||
--td-error-color-9: #951114;
|
||||
--td-error-color-10: #680506;
|
||||
--td-error-color: var(--td-error-color-6);
|
||||
--td-error-color-focus: var(--td-error-color-2);
|
||||
--td-error-color-active: var(--td-error-color-7);
|
||||
--td-error-color-disabled: var(--td-error-color-3);
|
||||
--td-error-color-light: var(--td-error-color-1);
|
||||
--td-success-color-1: #e8f8f2;
|
||||
--td-success-color-2: #bcebdc;
|
||||
--td-success-color-3: #85dbbe;
|
||||
--td-success-color-4: #48c79c;
|
||||
--td-success-color-5: #00a870;
|
||||
--td-success-color-6: #078d5c;
|
||||
--td-success-color-7: #067945;
|
||||
--td-success-color-8: #056334;
|
||||
--td-success-color-9: #044f2a;
|
||||
--td-success-color-10: #033017;
|
||||
--td-success-color: var(--td-success-color-5);
|
||||
--td-success-color-focus: var(--td-success-color-2);
|
||||
--td-success-color-active: var(--td-success-color-6);
|
||||
--td-success-color-disabled: var(--td-success-color-3);
|
||||
--td-success-color-light: var(--td-success-color-1);
|
||||
--td-gray-color-1: #f3f3f3;
|
||||
--td-gray-color-2: #eee;
|
||||
--td-gray-color-3: #e8e8e8;
|
||||
--td-gray-color-4: #ddd;
|
||||
--td-gray-color-5: #c5c5c5;
|
||||
--td-gray-color-6: #a6a6a6;
|
||||
--td-gray-color-7: #8b8b8b;
|
||||
--td-gray-color-8: #777;
|
||||
--td-gray-color-9: #5e5e5e;
|
||||
--td-gray-color-10: #4b4b4b;
|
||||
--td-gray-color-11: #383838;
|
||||
--td-gray-color-12: #2c2c2c;
|
||||
--td-gray-color-13: #242424;
|
||||
--td-gray-color-14: #181818;
|
||||
--td-bg-color-container: #fff;
|
||||
--td-bg-color-page: var(--td-gray-color-2);
|
||||
--td-bg-color-container-active: var(--td-gray-color-3);
|
||||
--td-bg-color-secondarycontainer: var(--td-gray-color-1);
|
||||
--td-bg-color-secondarycontainer-active: var(--td-gray-color-4);
|
||||
--td-bg-color-component: var(--td-gray-color-3);
|
||||
--td-bg-color-component-active: var(--td-gray-color-6);
|
||||
--td-bg-color-component-disabled: var(--td-gray-color-2);
|
||||
--td-component-stroke: var(--td-gray-color-3);
|
||||
--td-component-border: var(--td-gray-color-4);
|
||||
--td-font-white-1: #ffffff;
|
||||
--td-font-white-2: rgba(255, 255, 255, 0.55);
|
||||
--td-font-white-3: rgba(255, 255, 255, 0.35);
|
||||
--td-font-white-4: rgba(255, 255, 255, 0.22);
|
||||
--td-font-gray-1: rgba(0, 0, 0, 0.9);
|
||||
--td-font-gray-2: rgba(0, 0, 0, 0.6);
|
||||
--td-font-gray-3: rgba(0, 0, 0, 0.4);
|
||||
--td-font-gray-4: rgba(0, 0, 0, 0.26);
|
||||
--td-text-color-primary: var(--td-font-gray-1);
|
||||
--td-text-color-secondary: var(--td-font-gray-2);
|
||||
--td-text-color-placeholder: var(--td-font-gray-3);
|
||||
--td-text-color-disabled: var(--td-font-gray-4);
|
||||
--td-text-color-anti: #fff;
|
||||
--td-text-color-brand: var(--td-brand-color);
|
||||
--td-text-color-link: var(--td-brand-color);
|
||||
--td-bg-color-secondarycomponent: var(--td-gray-color-4);
|
||||
--td-bg-color-secondarycomponent-active: var(--td-gray-color-6);
|
||||
--td-table-shadow-color: rgba(0, 0, 0, 8%);
|
||||
--td-scrollbar-color: rgba(0, 0, 0, 10%);
|
||||
--td-scrollbar-hover-color: rgba(0, 0, 0, 30%);
|
||||
--td-scroll-track-color: #fff;
|
||||
--td-bg-color-specialcomponent: #fff;
|
||||
--td-border-level-1-color: var(--td-gray-color-3);
|
||||
--td-border-level-2-color: var(--td-gray-color-4);
|
||||
--td-shadow-1: 0 1px 10px rgba(0, 0, 0, 5%), 0 4px 5px rgba(0, 0, 0, 8%), 0 2px 4px -1px rgba(0, 0, 0, 12%);
|
||||
--td-shadow-2: 0 3px 14px 2px rgba(0, 0, 0, 5%), 0 8px 10px 1px rgba(0, 0, 0, 6%), 0 5px 5px -3px rgba(0, 0, 0, 10%);
|
||||
--td-shadow-3: 0 6px 30px 5px rgba(0, 0, 0, 5%), 0 16px 24px 2px rgba(0, 0, 0, 4%), 0 8px 10px -5px rgba(0, 0, 0, 8%);
|
||||
--td-shadow-inset-top: inset 0 0.5px 0 #dcdcdc;
|
||||
--td-shadow-inset-right: inset 0.5px 0 0 #dcdcdc;
|
||||
--td-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc;
|
||||
--td-shadow-inset-left: inset -0.5px 0 0 #dcdcdc;
|
||||
--td-mask-active: rgba(0, 0, 0, 0.6);
|
||||
--td-mask-disabled: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
:root[theme-mode="dark"] {
|
||||
--td-brand-color-1: #ff505020;
|
||||
--td-brand-color-2: #6b000a;
|
||||
--td-brand-color-3: #8f121b;
|
||||
--td-brand-color-4: #b6292d;
|
||||
--td-brand-color-5: #df3d3f;
|
||||
--td-brand-color-6: #ff5050;
|
||||
--td-brand-color-7: #ff928c;
|
||||
--td-brand-color-8: #ffb8b1;
|
||||
--td-brand-color-9: #ffd8d3;
|
||||
--td-brand-color-10: #fff0ed;
|
||||
--td-brand-color-light: var(--td-brand-color-1);
|
||||
--td-brand-color-focus: var(--td-brand-color-2);
|
||||
--td-brand-color-disabled: var(--td-brand-color-3);
|
||||
--td-brand-color: var(--td-brand-color-6);
|
||||
--td-brand-color-active: var(--td-brand-color-7);
|
||||
--td-warning-color-1: #4f2a1d;
|
||||
--td-warning-color-2: #582f21;
|
||||
--td-warning-color-3: #733c23;
|
||||
--td-warning-color-4: #a75d2b;
|
||||
--td-warning-color-5: #cf6e2d;
|
||||
--td-warning-color-6: #dc7633;
|
||||
--td-warning-color-7: #e8935c;
|
||||
--td-warning-color-8: #ecbf91;
|
||||
--td-warning-color-9: #eed7bf;
|
||||
--td-warning-color-10: #f3e9dc;
|
||||
--td-error-color-1: #472324;
|
||||
--td-error-color-2: #5e2a2d;
|
||||
--td-error-color-3: #703439;
|
||||
--td-error-color-4: #83383e;
|
||||
--td-error-color-5: #a03f46;
|
||||
--td-error-color-6: #c64751;
|
||||
--td-error-color-7: #de6670;
|
||||
--td-error-color-8: #ec888e;
|
||||
--td-error-color-9: #edb1b6;
|
||||
--td-error-color-10: #eeced0;
|
||||
--td-success-color-1: #193a2a;
|
||||
--td-success-color-2: #1a4230;
|
||||
--td-success-color-3: #17533d;
|
||||
--td-success-color-4: #0d7a55;
|
||||
--td-success-color-5: #059465;
|
||||
--td-success-color-6: #43af8a;
|
||||
--td-success-color-7: #46bf96;
|
||||
--td-success-color-8: #80d2b6;
|
||||
--td-success-color-9: #b4e1d3;
|
||||
--td-success-color-10: #deede8;
|
||||
--td-gray-color-1: #f3f3f3;
|
||||
--td-gray-color-2: #eee;
|
||||
--td-gray-color-3: #e8e8e8;
|
||||
--td-gray-color-4: #ddd;
|
||||
--td-gray-color-5: #c5c5c5;
|
||||
--td-gray-color-6: #a6a6a6;
|
||||
--td-gray-color-7: #8b8b8b;
|
||||
--td-gray-color-8: #777;
|
||||
--td-gray-color-9: #5e5e5e;
|
||||
--td-gray-color-10: #4b4b4b;
|
||||
--td-gray-color-11: #383838;
|
||||
--td-gray-color-12: #2c2c2c;
|
||||
--td-gray-color-13: #242424;
|
||||
--td-gray-color-14: #181818;
|
||||
--td-bg-color-page: var(--td-gray-color-14);
|
||||
--td-bg-color-container: var(--td-gray-color-13);
|
||||
--td-bg-color-container-active: var(--td-gray-color-10);
|
||||
--td-bg-color-secondarycontainer: var(--td-gray-color-12);
|
||||
--td-bg-color-secondarycontainer-active: var(--td-gray-color-9);
|
||||
--td-bg-color-component: var(--td-gray-color-11);
|
||||
--td-bg-color-component-active: var(--td-gray-color-9);
|
||||
--td-bg-color-component-disabled: var(--td-gray-color-12);
|
||||
--td-component-stroke: var(--td-gray-color-11);
|
||||
--td-component-border: var(--td-gray-color-9);
|
||||
--td-font-white-1: rgba(255, 255, 255, 0.9);
|
||||
--td-font-white-2: rgba(255, 255, 255, 0.55);
|
||||
--td-font-white-3: rgba(255, 255, 255, 0.35);
|
||||
--td-font-white-4: rgba(255, 255, 255, 0.22);
|
||||
--td-font-gray-1: rgba(0, 0, 0, 0.9);
|
||||
--td-font-gray-2: rgba(0, 0, 0, 0.6);
|
||||
--td-font-gray-3: rgba(0, 0, 0, 0.4);
|
||||
--td-font-gray-4: rgba(0, 0, 0, 0.26);
|
||||
--td-text-color-primary: var(--td-font-white-1);
|
||||
--td-text-color-secondary: var(--td-font-white-2);
|
||||
--td-text-color-placeholder: var(--td-font-white-3);
|
||||
--td-text-color-disabled: var(--td-font-white-4);
|
||||
--td-text-color-anti: #fff;
|
||||
--td-text-color-brand: var(--td-brand-color);
|
||||
--td-text-color-link: var(--td-brand-color);
|
||||
--td-shadow-1: 0 4px 6px rgba(0, 0, 0, 0.06), 0 1px 10px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.12);
|
||||
--td-shadow-2: 0 8px 10px rgba(0, 0, 0, 0.12), 0 3px 14px rgba(0, 0, 0, 0.10), 0 5px 5px rgba(0, 0, 0, 0.16);
|
||||
--td-shadow-3: 0 16px 24px rgba(0, 0, 0, 0.14), 0 6px 30px rgba(0, 0, 0, 0.12), 0 8px 10px rgba(0, 0, 0, 0.20);
|
||||
--td-shadow-inset-top: inset 0 0.5px 0 #5e5e5e;
|
||||
--td-shadow-inset-right: inset 0.5px 0 0 #5e5e5e;
|
||||
--td-shadow-inset-bottom: inset 0 -0.5px 0 #5e5e5e;
|
||||
--td-shadow-inset-left: inset -0.5px 0 0 #5e5e5e;
|
||||
--td-table-shadow-color: rgba(0, 0, 0, 55%);
|
||||
--td-scrollbar-color: rgba(255, 255, 255, 10%);
|
||||
--td-scrollbar-hover-color: rgba(255, 255, 255, 30%);
|
||||
--td-scroll-track-color: #333;
|
||||
--td-bg-color-specialcomponent: transparent;
|
||||
--td-border-level-1-color: var(--td-gray-color-11);
|
||||
--td-border-level-2-color: var(--td-gray-color-9);
|
||||
--td-mask-active: rgba(0, 0, 0, 0.4);
|
||||
--td-mask-disabled: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
:root {
|
||||
--td-font-family: pingfang sc, microsoft yahei, arial regular;
|
||||
--td-font-family-medium: pingfang sc, microsoft yahei, arial medium;
|
||||
--td-font-size-link-small: 12px;
|
||||
--td-font-size-link-medium: 14px;
|
||||
--td-font-size-link-large: 16px;
|
||||
--td-font-size-mark-small: 12px;
|
||||
--td-font-size-mark-medium: 14px;
|
||||
--td-font-size-body-small: 12px;
|
||||
--td-font-size-body-medium: 14px;
|
||||
--td-font-size-body-large: 16px;
|
||||
--td-font-size-title-small: 14px;
|
||||
--td-font-size-title-medium: 16px;
|
||||
--td-font-size-title-large: 20px;
|
||||
--td-font-size-headline-small: 24px;
|
||||
--td-font-size-headline-medium: 28px;
|
||||
--td-font-size-headline-large: 36px;
|
||||
--td-font-size-display-medium: 48px;
|
||||
--td-font-size-display-large: 64px;
|
||||
--td-line-height-link-small: 20px;
|
||||
--td-line-height-link-medium: 22px;
|
||||
--td-line-height-link-large: 24px;
|
||||
--td-line-height-mark-small: 20px;
|
||||
--td-line-height-mark-medium: 22px;
|
||||
--td-line-height-body-small: 20px;
|
||||
--td-line-height-body-medium: 22px;
|
||||
--td-line-height-body-large: 24px;
|
||||
--td-line-height-title-small: 22px;
|
||||
--td-line-height-title-medium: 24px;
|
||||
--td-line-height-title-large: 28px;
|
||||
--td-line-height-headline-small: 32px;
|
||||
--td-line-height-headline-medium: 36px;
|
||||
--td-line-height-headline-large: 44px;
|
||||
--td-line-height-display-medium: 56px;
|
||||
--td-line-height-display-large: 72px;
|
||||
--td-font-link-small: var(--td-font-size-link-small) / var(--td-line-height-link-small) var(--td-font-family);
|
||||
--td-font-link-medium: var(--td-font-size-link-medium) / var(--td-line-height-link-medium) var(--td-font-family);
|
||||
--td-font-link-large: var(--td-font-size-link-large) / var(--td-line-height-link-large) var(--td-font-family);
|
||||
--td-font-mark-small: 600 var(--td-font-size-mark-small) / var(--td-line-height-mark-small) var(--td-font-family);
|
||||
--td-font-mark-medium: 600 var(--td-font-size-mark-medium) / var(--td-line-height-mark-medium) var(--td-font-family);
|
||||
--td-font-body-small: var(--td-font-size-body-small) / var(--td-line-height-body-small) var(--td-font-family);
|
||||
--td-font-body-medium: var(--td-font-size-body-medium) / var(--td-line-height-body-medium) var(--td-font-family);
|
||||
--td-font-body-large: var(--td-font-size-body-large) / var(--td-line-height-body-large) var(--td-font-family);
|
||||
--td-font-title-small: 600 var(--td-font-size-title-small) / var(--td-line-height-title-small) var(--td-font-family);
|
||||
--td-font-title-medium: 600 var(--td-font-size-title-medium) / var(--td-line-height-title-medium) var(--td-font-family);
|
||||
--td-font-title-large: 600 var(--td-font-size-title-large) / var(--td-line-height-title-large) var(--td-font-family);
|
||||
--td-font-headline-small: 600 var(--td-font-size-headline-small) / var(--td-line-height-headline-small) var(--td-font-family);
|
||||
--td-font-headline-medium: 600 var(--td-font-size-headline-medium) / var(--td-line-height-headline-medium) var(--td-font-family);
|
||||
--td-font-headline-large: 600 var(--td-font-size-headline-large) / var(--td-line-height-headline-large) var(--td-font-family);
|
||||
--td-font-display-medium: 600 var(--td-font-size-display-medium) / var(--td-line-height-display-medium) var(--td-font-family);
|
||||
--td-font-display-large: 600 var(--td-font-size-display-large) / var(--td-line-height-display-large) var(--td-font-family);
|
||||
--td-radius-small: 2px;
|
||||
--td-radius-default: 3px;
|
||||
--td-radius-medium: 6px;
|
||||
--td-radius-large: 9px;
|
||||
--td-radius-extraLarge: 12px;
|
||||
--td-radius-round: 999px;
|
||||
--td-radius-circle: 50%;
|
||||
--td-size-1: 2px;
|
||||
--td-size-2: 4px;
|
||||
--td-size-3: 6px;
|
||||
--td-size-4: 8px;
|
||||
--td-size-5: 12px;
|
||||
--td-size-6: 16px;
|
||||
--td-size-7: 20px;
|
||||
--td-size-8: 24px;
|
||||
--td-size-9: 28px;
|
||||
--td-size-10: 32px;
|
||||
--td-size-11: 36px;
|
||||
--td-size-12: 40px;
|
||||
--td-size-13: 48px;
|
||||
--td-size-14: 56px;
|
||||
--td-size-15: 64px;
|
||||
--td-size-16: 72px;
|
||||
--td-comp-size-xxxs: var(--td-size-6);
|
||||
--td-comp-size-xxs: var(--td-size-7);
|
||||
--td-comp-size-xs: var(--td-size-8);
|
||||
--td-comp-size-s: var(--td-size-9);
|
||||
--td-comp-size-m: var(--td-size-10);
|
||||
--td-comp-size-l: var(--td-size-11);
|
||||
--td-comp-size-xl: var(--td-size-12);
|
||||
--td-comp-size-xxl: var(--td-size-13);
|
||||
--td-comp-size-xxxl: var(--td-size-14);
|
||||
--td-comp-size-xxxxl: var(--td-size-15);
|
||||
--td-comp-size-xxxxxl: var(--td-size-16);
|
||||
--td-pop-padding-s: var(--td-size-2);
|
||||
--td-pop-padding-m: var(--td-size-3);
|
||||
--td-pop-padding-l: var(--td-size-4);
|
||||
--td-pop-padding-xl: var(--td-size-5);
|
||||
--td-pop-padding-xxl: var(--td-size-6);
|
||||
--td-comp-paddingLR-xxs: var(--td-size-1);
|
||||
--td-comp-paddingLR-xs: var(--td-size-2);
|
||||
--td-comp-paddingLR-s: var(--td-size-4);
|
||||
--td-comp-paddingLR-m: var(--td-size-5);
|
||||
--td-comp-paddingLR-l: var(--td-size-6);
|
||||
--td-comp-paddingLR-xl: var(--td-size-8);
|
||||
--td-comp-paddingLR-xxl: var(--td-size-10);
|
||||
--td-comp-paddingTB-xxs: var(--td-size-1);
|
||||
--td-comp-paddingTB-xs: var(--td-size-2);
|
||||
--td-comp-paddingTB-s: var(--td-size-4);
|
||||
--td-comp-paddingTB-m: var(--td-size-5);
|
||||
--td-comp-paddingTB-l: var(--td-size-6);
|
||||
--td-comp-paddingTB-xl: var(--td-size-8);
|
||||
--td-comp-paddingTB-xxl: var(--td-size-10);
|
||||
--td-comp-margin-xxs: var(--td-size-1);
|
||||
--td-comp-margin-xs: var(--td-size-2);
|
||||
--td-comp-margin-s: var(--td-size-4);
|
||||
--td-comp-margin-m: var(--td-size-5);
|
||||
--td-comp-margin-l: var(--td-size-6);
|
||||
--td-comp-margin-xl: var(--td-size-7);
|
||||
--td-comp-margin-xxl: var(--td-size-8);
|
||||
--td-comp-margin-xxxl: var(--td-size-10);
|
||||
--td-comp-margin-xxxxl: var(--td-size-12);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 基础配置
|
||||
// const BASE_URL = "http://192.168.41.118:9090/api"
|
||||
const BASE_URL = "/api"
|
||||
|
||||
export function useRequest() {
|
||||
const loading = ref(false)
|
||||
const error = ref<any>(null)
|
||||
|
||||
// 核心请求方法
|
||||
const sendRequest = <T = any>(options: UniApp.RequestOptions): Promise<T> => {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// 处理URL
|
||||
const url = options.url.startsWith('http')
|
||||
? options.url
|
||||
: `${BASE_URL}/${options.url.replace(/^\//, '')}`
|
||||
|
||||
// 添加token
|
||||
const token = uni.getStorageSync('token')
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
||||
...options.header
|
||||
}
|
||||
|
||||
uni.request({
|
||||
url,
|
||||
method: options.method || 'GET',
|
||||
data: options.data,
|
||||
header: headers,
|
||||
timeout: options.timeout || 10000,
|
||||
success: (res) => {
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
resolve(res.data as T)
|
||||
} else {
|
||||
const err = new Error(res.data?.message || '请求失败')
|
||||
error.value = err
|
||||
reject(err)
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
error.value = err
|
||||
reject(err)
|
||||
},
|
||||
complete: () => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// GET请求
|
||||
const get = <T = any>(url: string, params?: any) => {
|
||||
return sendRequest<T>({
|
||||
url,
|
||||
method: 'GET',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
// POST请求
|
||||
const post = <T = any>(url: string, data?: any) => {
|
||||
return sendRequest<T>({
|
||||
url,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
error,
|
||||
request: sendRequest,
|
||||
get,
|
||||
post
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user