Browse Source

'存档'

hfll
hflllll 1 month ago
parent
commit
14a9264ba5
38 changed files with 2273 additions and 3427 deletions
  1. +24
    -12
      pages.json
  2. +598
    -1
      pages/index/member.vue
  3. +314
    -139
      pages/index/user.vue
  4. +2
    -1
      rule.txt
  5. BIN
      static/VIP.png
  6. BIN
      static/二维码图标.png
  7. BIN
      static/介绍图标.png
  8. BIN
      static/优惠卷图标.png
  9. BIN
      static/会员图片1.png
  10. BIN
      static/会员图片2.png
  11. BIN
      static/会员图片3.png
  12. BIN
      static/会员背景.png
  13. BIN
      static/会员钻石.png
  14. BIN
      static/修改信息图标.png
  15. BIN
      static/团队图标.png
  16. BIN
      static/已使用盖章.png
  17. BIN
      static/已过期盖章.png
  18. BIN
      static/拨号图标.png
  19. BIN
      static/推广图标.png
  20. BIN
      static/推广官.png
  21. BIN
      static/推广标语.png
  22. BIN
      static/提现图标.png
  23. BIN
      static/播放图标高亮.png
  24. BIN
      static/服务隐私图标.png
  25. BIN
      static/联系我们图标.png
  26. BIN
      static/退出登录图标.png
  27. +0
    -608
      subPages/home/RAArecord.vue
  28. +1
    -0
      subPages/home/directory.vue
  29. +0
    -763
      subPages/home/maintainanceSubmit.vue
  30. +0
    -690
      subPages/home/repairSubmit.vue
  31. +0
    -1060
      subPages/repair/maintainSubmit.vue
  32. +187
    -0
      subPages/user/cash.vue
  33. +300
    -0
      subPages/user/discount.vue
  34. +31
    -0
      subPages/user/introduce.vue
  35. +31
    -0
      subPages/user/policy.vue
  36. +138
    -153
      subPages/user/profile.vue
  37. +448
    -0
      subPages/user/promote.vue
  38. +199
    -0
      subPages/user/team.vue

+ 24
- 12
pages.json View File

@ -68,38 +68,50 @@
"path": "home/directory",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#264C8F"
"navigationBarBackgroundColor": "#264C8F",
"navigationBarTextStyle": "white"
}
},
{
"path": "home/repairSubmit",
"path": "user/introduce",
"style": {
"navigationBarTitleText": "报修提交"
"navigationBarTitleText": "产品介绍"
}
},
{
"path": "home/maintainanceSubmit",
"path": "user/policy",
"style": {
"navigationBarTitleText": "保养提交"
"navigationBarTitleText": "服务协议与隐私政策"
}
},
{
"path": "home/RAArecord",
"path": "user/profile",
"style": {
"navigationBarTitleText": "报修/保养记录"
"navigationBarTitleText": "资料修改"
}
},
{
"path": "repair/maintainSubmit",
"path": "user/discount",
"style": {
"navigationBarTitleText": "维修单提交",
"enablePullDownRefresh": true
"navigationBarTitleText": "我的优惠券"
}
},
{
"path": "user/profile",
"path": "user/promote",
"style": {
"navigationBarTitleText": "资料修改"
"navigationStyle": "custom"
}
},
{
"path": "user/team",
"style": {
"navigationBarTitleText": "我的团队"
}
},
{
"path": "user/cash",
"style": {
"navigationBarTitleText": "提现"
}
}
]


+ 598
- 1
pages/index/member.vue View File

@ -1,2 +1,599 @@
<template>
</template>
<view class="container">
<view class="header">
<view class="header-bg">
<image
src="/static/会员背景.png"
class="header-img"
mode="scaleToFill"
/>
<text class="header-title">会员中心</text>
</view>
<view class="header-content">
<view class="zuanshi">
<image
src="/static/会员钻石.png"
mode="scaleToFill"
class="zuanshi-img"
/>
</view>
<image
src="/static/VIP.png"
mode="aspectFit"
class="VIP-img"
/>
<text class="intro">共19项会员特权 | 3 项年VIP专属特权</text>
<view class="border" />
<view class="info">
<view class="avatar-box">
<image
:src="userInfo.avatar"
mode="aspectFill"
class="avatar"
/>
<text class="name">{{userInfo.name}}</text>
</view>
<uv-button text="立即开通"
type="primary"
:customStyle="{
width: '160rpx',
height: '60rpx',
borderRadius: '198rpx',
backgroundColor: '#06DADC',
color: '#fff',
fontSize: '28rpx',
fontWeight: '500',
lineHeight: '60rpx',
letterSpacing: '0%',
verticalAlign: 'middle',
}" />
</view>
</view>
</view>
<!-- 会员权益 -->
<view class="benefits-section">
<view class="benefits-title">会员权益</view>
<view class="benefits-list">
<!-- 碎片学习 系统掌握 -->
<view class="benefit-item">
<view class="benefit-content">
<view class="benefit-title">碎片学习 系统掌握</view>
<view class="benefit-desc">根据薄弱点智能推荐每节课3-5分钟碎片化完成系统学习</view>
</view>
<view class="benefit-icon">
<image src="/static/会员图片1.png" mode="aspectFit"></image>
</view>
</view>
<!-- 匹配水平 -->
<view class="benefit-item">
<view class="benefit-content">
<view class="benefit-title">匹配水平</view>
<view class="benefit-desc">依据水平精准推课不做无用功快速提升</view>
</view>
<view class="benefit-icon">
<image src="/static/会员图片2.png" mode="aspectFit"></image>
</view>
</view>
<!-- 科学闭环测 讲练结合 -->
<view class="benefit-item">
<view class="benefit-content">
<view class="benefit-title">科学闭环测 讲练结合</view>
<view class="benefit-desc">精心设计科学的学习流程 测试-讲解-练习-检验知识掌握更牢固</view>
</view>
<view class="benefit-icon">
<image src="/static/会员图片3.png" mode="aspectFit"></image>
</view>
</view>
</view>
</view>
<!-- 以下内容为成为会员才能看到的 -->
<!-- 学习计划 -->
<view class="study-plan-section">
<view class="section-title">学习计划</view>
<view class="plan-books">
<view
v-for="(book, index) in studyPlanBooks"
:key="index"
class="plan-book-item"
:class="{ 'active-book': index === 1 }"
>
<view class="plan-book-cover">
<image :src="book.cover" mode="aspectFill"></image>
<!-- 学习中标识 -->
<view v-if="index === 1" class="studying-badge">
<view class="studying-icon"/>
<text>学习中</text>
</view>
</view>
<view class="plan-book-info">
<text class="plan-book-title" :class="{ 'highlight-title': index === 1 }">{{ book.title }}</text>
<view class="plan-book-meta" >
<text class="plan-book-grade" :class="{ 'highlight-title': index === 1 }">{{ book.grade }}/</text>
<image v-if="index !== 1" src="/static/播放图标.png" class="plan-book-duration-icon" />
<image v-else src="/static/播放图标高亮.png" class="plan-book-duration-icon" />
<text class="plan-book-duration" :class="{ 'highlight-title': index === 1 }">{{ book.duration }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 学习推荐 -->
<view class="study-recommend-section">
<view class="section-header">
<text class="section-title">学习推荐</text>
<view class="section-more">
<text>更多</text>
<uv-icon name="arrow-right" size="14" color="#8B8B8B"></uv-icon>
</view>
</view>
<view class="recommend-grid">
<view
v-for="(book, index) in recommendBooks"
:key="index"
class="recommend-grid-item"
>
<view class="recommend-grid-cover">
<image :src="book.cover" mode="aspectFill"></image>
</view>
<view class="recommend-grid-info">
<text class="recommend-grid-title">{{ book.title }}</text>
<view class="recommend-grid-meta">
<text class="recommend-grid-grade">{{ book.grade }}/</text>
<image src="/static/播放图标.png" class="recommend-grid-duration-icon" />
<text class="recommend-grid-duration">{{ book.duration }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default{
data() {
return {
userInfo: {
name: '战斗世界',
avatar: '/static/默认头像.png'
},
//
studyPlanBooks: [
{
cover: '/static/默认图片.png',
title: '精讲短文',
grade: '四级',
duration: '03:24'
},
{
cover: '/static/默认图片.png',
title: '精讲短文',
grade: '四级',
duration: '03:24'
},
{
cover: '/static/默认图片.png',
title: '精讲短文',
grade: '四级',
duration: '03:24'
}
],
//
recommendBooks: [
{
cover: '/static/默认图片.png',
title: '小王子',
grade: '四级',
duration: '03:24'
},
{
cover: '/static/默认图片.png',
title: '自私的巨人',
grade: '四级',
duration: '03:24'
},
{
cover: '/static/默认图片.png',
title: '百万英镑',
grade: '四级',
duration: '03:24'
},
{
cover: '/static/默认图片.png',
title: 'MATILDA',
grade: '四级',
duration: '03:24'
},
{
cover: '/static/默认图片.png',
title: 'Pride and Prejudice',
grade: '四级',
duration: '03:24'
},
{
cover: '/static/默认图片.png',
title: '温德尔·范·德拉南',
grade: '四级',
duration: '03:24'
}
]
}
},
}
</script>
<style lang="scss" scoped>
.container {
min-height: 100%;
}
.header{
width: 100%;
.header-bg{
position: relative;
width: 100%;
height: 400rpx;
// background: red;
.header-img{
width: 100%;
height: 400rpx;
}
.header-title{
font-size: 32rpx;
color: black;
position: absolute;
top: 100rpx;
font-weight: 500;
left: 50%;
transform: translateX(-50%);
}
}
.header-content{
margin: 0 18rpx;
margin-top: -150rpx;
height: 256rpx;
border-radius: 32rpx;
border-width: 2rpx;
padding: 40rpx;
background: linear-gradient(180deg, #DEFFFF 0%, #FBFEFF 22.65%, #F0FBFF 100%);
border: 2rpx solid #06DADC12;
display: flex;
flex-direction: column;
gap: 28rpx;
position: relative;
.zuanshi{
position: absolute;
width: 190rpx;
height: 190rpx;
top: -80rpx;
right: 0;
.zuanshi-img{
width: 190rpx;
height: 190rpx;
}
}
.VIP-img{
width: 80rpx;
height: 50rpx;
}
.border{
width: 100%;
// height: 2rpx;
border: 2rpx solid;
border-image-source: linear-gradient(90deg, rgba(228, 255, 255, 0) 0%, #C3EFEF 50.48%, rgba(228, 255, 255, 0) 100%);
border-image-slice: 1;
}
.intro{
font-size: 28rpx;
line-height: 36rpx;
letter-spacing: 0%;
vertical-align: middle;
color: #09B1B3;
}
.info{
display: flex;
justify-content: space-between;
align-items: center;
.avatar-box{
display: flex;
align-items: center;
gap: 16rpx;
.name{
font-weight: 600;
font-size: 36rpx;
line-height: 44rpx;
letter-spacing: 0%;
vertical-align: middle;
color: #252545;
}
.avatar{
width: 60rpx;
height: 60rpx;
border-radius: 50%;
}
}
}
}
}
/* 会员权益样式 */
.benefits-section {
margin-top: 40rpx;
padding: 0 30rpx;
}
.benefits-title {
font-size: 36rpx;
font-weight: bold;
color: #191919;
margin-bottom: 32rpx;
}
.benefits-list {
display: flex;
flex-direction: column;
gap: 32rpx;
}
.benefit-item {
background: #F8F8F8;
border: 1px solid #FFFFFF;
border-radius: 48rpx;
padding: 27rpx 40rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.benefit-content {
flex: 1;
margin-right: 40rpx;
}
.benefit-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.benefit-desc {
font-size: 24rpx;
color: #09B1B3;
line-height: 36rpx;
}
.benefit-icon {
width: 152rpx;
height: 152rpx;
// flex-shrink: 0;
}
.benefit-icon image {
width: 100%;
height: 100%;
}
/* 学习计划样式 */
.study-plan-section {
margin-top: 40rpx;
padding: 0 30rpx;
}
.section-title {
font-size: 36rpx;
font-weight: 500;
color: #191919;
margin-bottom: 32rpx;
}
.plan-books {
display: flex;
justify-content: center;
align-items: flex-end;
gap: 78rpx;
padding: 20rpx 0;
}
.plan-book-item {
display: flex;
flex-direction: column;
align-items: center;
transition: all 0.3s ease;
&.active-book {
transform: scale(1.15);
.plan-book-cover {
// box-shadow: 0 8rpx 24rpx rgba(6, 218, 220, 0.3);
}
}
}
.plan-book-cover {
width: 172rpx;
height: 230rpx;
border-radius: 16rpx;
overflow: hidden;
margin-bottom: 16rpx;
position: relative;
box-shadow: 0px 4px 4px 0px #C0BCBA75;
image {
width: 100%;
height: 100%;
}
.studying-badge {
position: absolute;
bottom: 0rpx;
right: 0rpx;
background: #00000099;
color: #fff;
padding: 6rpx 10rpx;
border-radius: 20rpx;
font-size: 18rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 6rpx;
.studying-icon{
width: 10rpx;
height: 10rpx;
background: $primary-color;
border-radius: 50%;
}
}
}
.plan-book-info {
text-align: center;
.plan-book-title {
font-size: 28rpx;
font-weight: 700;
color: #333;
margin-bottom: 8rpx;
display: block;
&.highlight-title {
color: $primary-color;
}
}
.plan-book-meta {
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
.plan-book-duration-icon {
width: 20rpx;
height: 20rpx;
}
.plan-book-grade {
font-size: 24rpx;
color: #999;
&.highlight-title {
color: $primary-color;
}
}
.plan-book-duration {
font-size: 24rpx;
color: #999;
&.highlight-title {
color: $primary-color;
}
}
}
}
/* 学习推荐样式 */
.study-recommend-section {
margin-top: 40rpx;
padding: 0 30rpx;
}
.section-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24rpx;
.section-more {
display: flex;
align-items: center;
gap: 4rpx;
text {
font-size: 24rpx;
color: #8B8B8B;
}
}
}
.recommend-grid {
display: flex;
flex-wrap: wrap;
gap: 32rpx;
.recommend-grid-item {
width: 208rpx;
display: flex;
flex-direction: column;
.recommend-grid-cover {
box-shadow: 0px 4px 4px 0px #C0BCBA75;
width: 100%;
height: 278rpx;
border-radius: 16rpx;
overflow: hidden;
margin-bottom: 16rpx;
image {
width: 100%;
height: 100%;
}
}
.recommend-grid-info {
padding: 6rpx;
.recommend-grid-title {
font-size: 28rpx;
font-weight: 700;
color: #333;
margin-bottom: 14rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.recommend-grid-meta {
display: flex;
align-items: center;
.recommend-grid-duration-icon {
width: 24rpx;
height: 24rpx;
margin-right: 12rpx;
}
.recommend-grid-grade {
font-size: 24rpx;
color: #999;
margin-right: 8rpx;
}
.recommend-grid-duration {
font-size: 24rpx;
color: #999;
}
}
}
}
}
</style>

+ 314
- 139
pages/index/user.vue View File

@ -1,64 +1,138 @@
<template>
<view class="user-container">
<!-- 顶部背景区域 -->
<view class="header-bg" @click="goLogin">
<!-- 用户信息区域 -->
<!-- 用户信息区域 -->
<view class="user-info-section">
<view class="page-title">我的</view>
<view class="user-info">
<view class="avatar-section">
<image class="avatar" :src="userInfo.headImage || '/static/默认头像.png'" mode="aspectFill"></image>
<view class="user-avatar" @click="goLogin">
<image :src="isLogin ? userInfo.headImage : displayInfo.avatar" mode="aspectFill"></image>
</view>
<view class="info-section">
<text class="username">{{userInfo.nickName}}</text>
<text class="user-id">ID:{{userInfo.id}}</text>
<view class="user-details">
<view class="user-name">{{ isLogin ? userInfo.nickName : displayInfo.name }}</view>
<view class="user-phone">手机号{{ isLogin ? userInfo.phone || displayInfo.phone : displayInfo.phone }}</view>
<view class="user-desc">{{ displayInfo.description }}</view>
</view>
</view>
</view>
<!-- 功能菜单列表 -->
<!-- 第一组菜单 -->
<!-- 会员中心 -->
<view class="menu-item special-item" @click="goToMember">
<view class="menu-left">
<image src="/static/会员钻石.png" class="menu-icon"></image>
<text class="menu-title">会员中心</text>
</view>
<view class="menu-right">
<uv-button shape="circle" :customStyle="{
width: '170rpx',
height: '70rpx',
fontSize: '28rpx',
fontWeight: '500',
lineHeight: '70rpx',
letterSpacing: '0%',
verticalAlign: 'middle',
backgroundColor: '#06DADC',
color: '#fff',
}">查看会员</uv-button>
</view>
</view>
<!-- 常用功能模块 -->
<view class="function-card">
<view class="card-title">
<text class="title-text" >常用功能</text>
<view class="menu-list">
<!-- 推广中心 -->
<view class="menu-item" @click="goToPromotion">
<view class="menu-left">
<image src="/static/推广图标.png" class="menu-icon"></image>
<text class="menu-title">推广中心</text>
</view>
<view class="menu-right">
<uv-icon name="arrow-right" color="#999" size="16"></uv-icon>
</view>
</view>
<view class="function-list">
<!-- 基本信息 -->
<view class="function-item" @click="goToBasicInfo">
<view class="item-left">
<uv-icon name="account" size="28" color="#C70019"></uv-icon>
<text class="item-text">基本信息</text>
</view>
<uv-icon name="arrow-right" size="24" color="#000"></uv-icon>
<!-- 我的优惠券 -->
<view class="menu-item" @click="goToCoupons">
<view class="menu-left">
<image src="/static/优惠卷图标.png" class="menu-icon"></image>
<text class="menu-title">我的优惠券</text>
</view>
<!-- 用户协议和隐私政策 -->
<view class="function-item" @click="showPrivacyPolicy">
<view class="item-left">
<uv-icon name="file-text" size="28" color="#C70019"></uv-icon>
<text class="item-text">用户协议和隐私政策</text>
</view>
<uv-icon name="arrow-right" size="24" color="#000"></uv-icon>
<view class="menu-right">
<uv-icon name="arrow-right" color="#999" size="16"></uv-icon>
</view>
<!-- 退出登录 -->
<view class="function-item" @click="logout" v-if="isLogin">
<view class="item-left">
<uv-icon name="minus-circle" size="24" color="#C70019"></uv-icon>
<text class="item-text">退出登录</text>
</view>
<uv-icon name="arrow-right" size="24" color="#000"></uv-icon>
</view>
<!-- 产品介绍 -->
<view class="menu-item" @click="goToProduct">
<view class="menu-left">
<image src="/static/介绍图标.png" class="menu-icon"></image>
<text class="menu-title">产品介绍</text>
</view>
<view class="menu-right">
<uv-icon name="arrow-right" color="#999" size="16"></uv-icon>
</view>
</view>
</view>
<!-- 用户协议和隐私政策弹窗 -->
<uv-modal ref="privacyModal" title="用户协议和隐私政策" :show-cancel-button="false" confirm-text="我知道了" confirm-color="#C70019">
<view class="privacy-content">
<!-- 如果是富文本 -->
<rich-text :nodes="configParamTextarea('app_agreement')">
</rich-text>
<!-- 第二组菜单 -->
<view class="menu-list">
<!-- 联系我们 -->
<view class="menu-item" @click="goToContact">
<view class="menu-left">
<image src="/static/联系我们图标.png" class="menu-icon"></image>
<text class="menu-title">联系我们</text>
</view>
<view class="menu-right">
<uv-icon name="arrow-right" color="#999" size="16"></uv-icon>
</view>
</view>
<!-- 服务协议与隐私政策 -->
<view class="menu-item" @click="goToPolicy">
<view class="menu-left">
<image src="/static/服务隐私图标.png" class="menu-icon"></image>
<text class="menu-title">服务协议与隐私政策</text>
</view>
<view class="menu-right">
<uv-icon name="arrow-right" color="#999" size="16"></uv-icon>
</view>
</view>
<!-- 修改信息 -->
<view class="menu-item" @click="goToBasicInfo">
<view class="menu-left">
<image src="/static/修改信息图标.png" class="menu-icon"></image>
<text class="menu-title">修改信息</text>
</view>
<view class="menu-right">
<uv-icon name="arrow-right" color="#999" size="16"></uv-icon>
</view>
</view>
</uv-modal>
<view class="menu-item" @click="logout" v-if="isLogin">
<view class="menu-left">
<image src="/static/退出登录图标.png" class="menu-icon"></image>
<text class="menu-title">退出登录</text>
</view>
<view class="menu-right">
<uv-icon name="arrow-right" color="#999" size="16"></uv-icon>
</view>
</view>
</view>
<view>
<uv-popup ref="contactModal" closeIconPos="top-left" closeable round="30rpx" :safeAreaInsetBottom="false">
<view class="contact-content">
<view class="title">联系我们</view>
<view class="contact-item">
<text class="contact-phone">0731-599327-8899</text>
<image src="/static/拨号图标.png" class="contact-icon"></image>
</view>
</view>
</uv-popup>
</view>
</view>
</template>
@ -72,7 +146,14 @@ export default {
nickName: '请先登录',
id: 'XXXXX'
},
isLogin: uni.getStorageSync('token')
isLogin: uni.getStorageSync('token'),
//
displayInfo: {
name: '战斗世界',
phone: '19989674531',
avatar: '/static/默认头像.png',
description: '世界这么美,我想去看看~'
}
}
},
computed: {
@ -104,7 +185,7 @@ export default {
//
goToBasicInfo() {
uni.navigateTo({
url: '/subPages/user/profile'
url: '/subPages/user/profile'
})
},
@ -121,6 +202,44 @@ export default {
this.$refs.privacyModal.open()
},
//
goToMember() {
uni.switchTab({
url: '/pages/index/member'
})
},
// 广
goToPromotion() {
uni.navigateTo({
url: '/subPages/user/promote'
})
},
//
goToCoupons() {
uni.navigateTo({
url: '/subPages/user/discount'
})
},
//
goToProduct() {
uni.navigateTo({ url: '/subPages/user/introduce' })
},
////
goToContact() {
this.$refs.contactModal.open('bottom')
},
//
goToPolicy() {
uni.navigateTo({
url: '/subPages/user/policy'
})
},
// 退
logout() {
uni.showModal({
@ -155,117 +274,173 @@ export default {
</script>
<style lang="scss" scoped>
.privacy-content {
padding: 20rpx;
.user-container {
min-height: 100vh;
background: #fff;
.privacy-section {
margin-bottom: 30rpx;
/* 用户信息区域 */
.user-info-section {
background: linear-gradient(180deg, #ABFFFF 0%, #FFFFFF 100%);
height: 300rpx;
// display: flex;
// align-items: center;
padding: 60rpx 32rpx 0rpx;
gap: 40rpx;
.user-info {
display: flex;
align-items: center;
}
.section-title {
.page-title {
text-align: center;
margin: 0 auto;
margin-top: 60rpx;
margin-bottom: 40rpx;
font-size: 32rpx;
font-weight: bold;
color: #333;
display: block;
margin-bottom: 20rpx;
font-weight: 500;
}
}
.user-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
overflow: hidden;
margin-right: 30rpx;
border: 2px solid #FFFFFF;
.section-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
display: block;
margin-bottom: 15rpx;
image {
width: 100%;
height: 100%;
}
}
}
.user-container {
min-height: 100vh;
background: #f5f5f5;
position: relative;
}
.user-details {
flex: 1;
}
.header-bg {
height: 513rpx;
background: linear-gradient(156deg, #f56073 15%, #c70019 61%, #ffacb6 100%);
position: relative;
padding: 0 46rpx;
.user-info {
.user-name {
font-size: 36rpx;
line-height: 44rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.user-phone {
font-size: 24rpx;
color: #252545;
margin-bottom: 8rpx;
}
.user-desc {
font-size: 24rpx;
color: #252545;
}
/* 菜单列表 */
.menu-list {
background: #F8F8F8;
border-radius: 32rpx;
overflow: hidden;
margin: 0 32rpx;
margin-bottom: 32rpx;
&:last-child {
margin-bottom: 0;
}
}
.menu-item {
display: flex;
align-items: center;
padding-top: 177rpx;
justify-content: space-between;
padding: 40rpx 30rpx;
border: 2rpx solid #F2F2F2;
.avatar-section {
margin-right: 22rpx;
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 60rpx;
// border: 4rpx solid rgba(255, 255, 255, 0.3);
}
&:last-child {
border-bottom: none;
}
.info-section {
flex: 1;
.username {
display: block;
font-size: 30rpx;
// font-weight: bold;
color: #fff;
margin-bottom: 12rpx;
&.special-item {
background: linear-gradient(180deg, #DEFFFF 0%, #FBFEFF 22.65%, #F0FBFF 100%);
border: 1px solid #06DADC12;
height: 98rpx;
border-radius: 32rpx;
border-width: 2rpx;
padding-top: 12rpx;
padding-right: 40rpx;
padding-bottom: 12rpx;
padding-left: 40rpx;
gap: 24rpx;
margin: 0 32rpx;
margin-bottom: 32rpx;
.menu-icon{
width: 60rpx;
height: 60rpx;
}
.user-id {
font-size: 28rpx;
color: #fff;
.menu-title{
font-size: 36rpx;
font-weight: 600;
}
}
}
}
.function-card {
width: 88%;
height: 709rpx;
background: #ffffff;
border-radius: 16rpx;
margin: -152rpx auto 0;
position: relative;
z-index: 2;
padding: 57rpx 28rpx;
.card-title {
// margin-bottom: 40rpx;
.title-text {
font-size: 32rpx;
font-weight: bold;
color: $primary-text-color;
}
.menu-left {
display: flex;
align-items: center;
}
.function-list {
.function-item {
display: flex;
align-items: center;
justify-content: space-between;
margin-top:44rpx ;
border-bottom: 1rpx solid #f0f0f0;
.item-left {
display: flex;
align-items: center;
.item-text {
font-size: 28rpx;
color: $primary-text-color;
margin-left: 14rpx;
}
}
.menu-icon {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.menu-title {
font-size: 32rpx;
color: #333;
}
.menu-right {
display: flex;
align-items: center;
}
/* 联系我们弹窗样式 */
.contact-content {
// padding: 40rpx 0;
.title{
height: 90rpx;
text-align: center;
line-height: 90rpx;
font-size: 34rpx;
font-weight: 500;
border-bottom: 2rpx solid #EEEEEE
}
// text-align: center;
}
.contact-item {
// background: red;
height: 240rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 20rpx;
}
.contact-icon {
width: 72rpx;
height: 72rpx;
}
.contact-phone {
font-size: 36rpx;
color: #181818;
}
}
</style>

+ 2
- 1
rule.txt View File

@ -2,4 +2,5 @@
2,优先使用uni.scss文件的SCSS变量$primary-color和其他三个还有动画变量
3,图片在/static
4,电脑系统配置Window 11
5,阿里云上传工具封装在@utils/oss-upload,api相关封装在@api,后台动态配置参数的获取 封装在@stores/index
5,阿里云上传工具封装在@utils/oss-upload,api相关封装在@api,后台动态配置参数的获取 封装在@stores/index
6.动态数据放到data中

BIN
static/VIP.png View File

Before After
Width: 65  |  Height: 31  |  Size: 872 B

BIN
static/二维码图标.png View File

Before After
Width: 49  |  Height: 48  |  Size: 664 B

BIN
static/介绍图标.png View File

Before After
Width: 40  |  Height: 40  |  Size: 830 B

BIN
static/优惠卷图标.png View File

Before After
Width: 40  |  Height: 40  |  Size: 889 B

BIN
static/会员图片1.png View File

Before After
Width: 152  |  Height: 152  |  Size: 48 KiB

BIN
static/会员图片2.png View File

Before After
Width: 152  |  Height: 152  |  Size: 38 KiB

BIN
static/会员图片3.png View File

Before After
Width: 152  |  Height: 152  |  Size: 38 KiB

BIN
static/会员背景.png View File

Before After
Width: 750  |  Height: 414  |  Size: 83 KiB

BIN
static/会员钻石.png View File

Before After
Width: 172  |  Height: 172  |  Size: 33 KiB

BIN
static/修改信息图标.png View File

Before After
Width: 40  |  Height: 40  |  Size: 880 B

BIN
static/团队图标.png View File

Before After
Width: 48  |  Height: 48  |  Size: 948 B

BIN
static/已使用盖章.png View File

Before After
Width: 98  |  Height: 98  |  Size: 10 KiB

BIN
static/已过期盖章.png View File

Before After
Width: 98  |  Height: 98  |  Size: 10 KiB

BIN
static/拨号图标.png View File

Before After
Width: 73  |  Height: 72  |  Size: 1.8 KiB

BIN
static/推广图标.png View File

Before After
Width: 40  |  Height: 40  |  Size: 972 B

BIN
static/推广官.png View File

Before After
Width: 162  |  Height: 54  |  Size: 3.8 KiB

BIN
static/推广标语.png View File

Before After
Width: 670  |  Height: 72  |  Size: 24 KiB

BIN
static/提现图标.png View File

Before After
Width: 48  |  Height: 48  |  Size: 583 B

BIN
static/播放图标高亮.png View File

Before After
Width: 18  |  Height: 19  |  Size: 473 B

BIN
static/服务隐私图标.png View File

Before After
Width: 40  |  Height: 40  |  Size: 1.2 KiB

BIN
static/联系我们图标.png View File

Before After
Width: 40  |  Height: 40  |  Size: 787 B

BIN
static/退出登录图标.png View File

Before After
Width: 40  |  Height: 40  |  Size: 554 B

+ 0
- 608
subPages/home/RAArecord.vue View File

@ -1,608 +0,0 @@
<template>
<view class="container">
<view class="header">
<!-- 大Tab维修记录/保养记录 -->
<view class="main-tabs">
<view
class="tab-item"
:class="{ active: activeMainTab === 'repair' }"
@click="switchMainTab('repair')"
>
<text class="tab-text">维修记录</text>
<view class="tab-underline" v-if="activeMainTab === 'repair'"></view>
</view>
<view
class="tab-item"
:class="{ active: activeMainTab === 'maintain' }"
@click="switchMainTab('maintain')"
>
<text class="tab-text">保养记录</text>
<view class="tab-underline" v-if="activeMainTab === 'maintain'"></view>
</view>
</view>
<!-- 筛选按钮区域 -->
<view class="picker-buttons">
<view class="picker-btn" :class="{ active: selectedTime }" @click="showTimePicker" >
<text class="btn-text">{{ selectedTime || '时间' }}</text>
<text class="arrow-icon"></text>
</view>
<view class="picker-btn" :class="{ active: selectedPerson }" @click="showPersonPicker" >
<text class="btn-text">{{ selectedPerson.label || '人员' }}</text>
<text class="arrow-icon"></text>
</view>
</view>
</view>
<!-- 日期选择器 -->
<uv-datetime-picker
confirm-color="#C70019"
ref="timePicker"
mode="date"
@confirm="onTimeConfirm"
></uv-datetime-picker>
<!-- 人员选择器 -->
<uv-picker
ref="personPicker"
:columns="personColumns"
@confirm="onPersonConfirm"
@cancel="onPersonCancel"
keyName="label"
title="选择人员"
confirmColor="#C70019"
></uv-picker>
<!-- 内容区域 -->
<view class="content-area">
<!-- 记录item -->
<!-- 加载动画容器 -->
<view v-if="list.length">
<view class="record-item" v-for="(record, index) in list" :key="index">
<!-- 维修记录 -->
<template v-if="activeMainTab === 'repair'">
<!-- 基本信息 -->
<view class="info-row">
<text class="label">维修人</text>
<text class="value">{{ record.repairName }}</text>
</view>
<view class="info-row">
<text class="label">联系方式</text>
<text class="value">{{ record.phone }}</text>
</view>
<view class="info-row">
<text class="label">维修日期</text>
<text class="value">{{ record.repairDate }}</text>
</view>
<view class="info-row">
<text class="label">处理内容</text>
</view>
<!-- 处理内容文本区域 -->
<view class="content-text">
<text>{{ record.content }}</text>
</view>
<!-- 上传图片 -->
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">上传图片</text>
</view>
<view class="image-container" v-if="!collapsedStates[index]">
<image class="uploaded-image" v-for="(value, index) in record.image.split(',')" :key="index" :src="value" mode="aspectFill"></image>
</view>
<!-- 是否产生费用 -->
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">是否产生费用</text>
<text class="value red-text">{{ record.isExpend === '1' || record.isExpend === 1 ? '是' : '否' }}</text>
</view>
</template>
<!-- 保养记录 -->
<template v-else>
<!-- 基本信息 -->
<view class="info-row">
<text class="label">保养人</text>
<text class="value">{{ record.maintenanceName }}</text>
</view>
<view class="info-row">
<text class="label">保养日期</text>
<text class="value">{{ record.maintenanceDate }}</text>
</view>
<view class="info-row">
<text class="label">保养前状态</text>
</view>
<!-- 保养前状态文本区域 -->
<view class="content-text">
<text>{{ record.stateFrontText }}</text>
</view>
<!-- 保养前图片 -->
<view class="image-container" v-if="!collapsedStates[index]">
<image
class="uploaded-image"
v-for="(img, imgIndex) in record.stateFrontImage.split(',')"
:key="imgIndex"
:src="img"
mode="aspectFill"
></image>
</view>
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">保养后状态</text>
</view>
<!-- 保养后状态文本区域 -->
<view class="content-text" v-if="!collapsedStates[index]">
<text>{{ record.stateBackText }}</text>
</view>
<!-- 保养后图片 -->
<view class="image-container" v-if="!collapsedStates[index]">
<image
class="uploaded-image"
v-for="(img, imgIndex) in record.stateBackImage.split(',')"
:key="'after-' + imgIndex"
:src="img"
mode="aspectFill"
></image>
</view>
<!-- 是否产生费用 -->
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">是否产生费用</text>
<text class="value red-text">{{ record.isExpend === '1'||record.isExpend === 1 ? '是' : '否' }}</text>
</view>
</template>
<!-- 产生费用 -->
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">产生费用</text>
<text class="value red-text">{{ record.amount }}</text>
</view>
<!-- 费用详情表格 -->
<view class="cost-table" v-if="!collapsedStates[index]">
<view class="table-header">
<text class="header-cell">费用名称</text>
<text class="header-cell">数量</text>
<text class="header-cell">金额</text>
</view>
<view class="table-row" v-for="(item, costIndex) in record.exhibitMaintenanceExpenses" :key="costIndex">
<text class="cell">{{ item.title }}</text>
<text class="cell">{{ item.num }}</text>
<text class="cell">{{ item.amount }}</text>
</view>
<view class="table-row" v-for="(item, costIndex) in record.exhibitRepairExpenseList" :key="costIndex">
<text class="cell">{{ item.title }}</text>
<text class="cell">{{ item.num }}</text>
<text class="cell">{{ item.amount }}</text>
</view>
</view>
<!-- 维修记录特有字段 -->
<template v-if="activeMainTab === 'repair'">
<!-- 问题是否解决 -->
<view class="info-row" >
<text class="label">问题是否解决</text>
<text class="value red-text">{{ record.isFix_dictText }}</text>
</view>
<!-- 备注 -->
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">备注</text>
</view>
<!-- 备注文本区域 -->
<view class="content-text" v-if="!collapsedStates[index]">
<text>{{ record.remark }}</text>
</view>
</template>
<!-- 保养记录特有字段 -->
<template v-else>
<!-- 附件信息 -->
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">附件信息</text>
</view>
<!-- 附件信息文本区域 -->
<view class="content-text" v-if="!collapsedStates[index]">
<text>{{ record.remarkText }}</text>
</view>
<!-- 附件图片 -->
<view class="image-container" v-if="!collapsedStates[index]">
<image class="uploaded-image" v-for="(value, index) in record.remarkImage.split(',')" :src="value" :key="index" mode="aspectFill"></image>
</view>
<!-- 保养备注 -->
<view class="info-row" v-if="!collapsedStates[index]">
<text class="label">备注</text>
</view>
<!-- 保养备注文本区域 -->
<view class="content-text" v-if="!collapsedStates[index]">
<text>{{ record.remark }}</text>
</view>
</template>
<!-- 收起按钮 -->
<view class="collapse-btn" @click="toggleCollapse(index)">
<text class="collapse-text">{{ collapsedStates[index] ? '查看全部' : '收起' }}</text>
<text class="collapse-icon">{{ collapsedStates[index] ? '▼' : '▲' }}</text>
</view>
</view>
<uv-loading-icon v-if="loading"></uv-loading-icon>
</view>
<view v-else-if="!loading && !records.length ">
<uv-empty icon="/static/暂无搜索结果.png" />
</view>
<uv-loading-icon v-else></uv-loading-icon>
</view>
</view>
</template>
<script>
import ListMixin from '@/mixins/list'
export default {
mixins: [ListMixin],
data() {
return {
showpieceId: '',
mixinListApi: 'exhibit.queryRepairList',
activeMainTab: 'repair', // Tab
activeFilter: 0, //
collapsedStates: [], // /
afterUpdateDataFn(list) {
this.collapsedStates = new Array(list.length).fill(true)
},
filterOptions: [
{ name: '时间' },
{ name: '人员' }
],
selectedTime: '', //
selectedPerson: '', //
timeColumns: [
['今天', '昨天', '本周', '本月', '上月', '自定义']
],
personColumns: [ ]
}
},
computed: {
contentText() {
const tabText = this.activeMainTab === 'repair' ? '维修' : '保养'
const filterText = this.filterOptions[this.activeFilter].name
let selectedText = ''
if (this.activeFilter === 0 && this.selectedTime) {
selectedText = ` - ${this.selectedTime}`
} else if (this.activeFilter === 1 && this.selectedPerson) {
selectedText = ` - ${this.selectedPerson}`
}
return `${tabText}记录 - 按${filterText}筛选${selectedText}`
}
},
methods: {
mixinSetParams() {
const params = { }
if (this.activeMainTab === 'repair' && this.selectedTime) {
params.repairDate = this.selectedTime
} else if (this.activeMainTab === 'maintain' && this.selectedTime) {
params.maintainDate = this.selectedTime
}
if (this.selectedPerson) {
params.id = this.selectedPerson.id
}
return {
showpieceId: this.showpieceId,
...params
}
},
async switchMainTab(tab) {
this.activeMainTab = tab
this.mixinListApi = this.activeMainTab === 'repair' ? 'exhibit.queryRepairList' : 'exhibit.queryMaintenanceList'
this.onFilterChange()
this.initPage()
this.getList(true)
// this.initCollapsedStates()
},
onFilterChange() {
// this.activeFilter = index
//
this.selectedTime = ''
this.selectedPerson = ''
},
showTimePicker() {
this.$refs.timePicker.open()
},
showPersonPicker() {
this.$refs.personPicker.open()
},
onTimeConfirm(e) {
this.selectedTime = this.$utils.formatTime(e.value)
this.initPage()
this.getList(true)
},
onTimeCancel() {
console.log('取消选择时间')
},
onPersonConfirm(value) {
this.selectedPerson = value.value[0]
console.log('选择的人员:', value)
this.initPage()
this.getList(true)
},
onPersonCancel() {
console.log('取消选择人员')
},
toggleCollapse(index) {
this.$set(this.collapsedStates, index, !this.collapsedStates[index])
console.log('收起/展开费用详情', this.collapsedStates[index])
}
},
async onLoad(args){{
this.showpieceId = args.id
const userRes = await this.$api.config.queryUserList()
this.personColumns = [[...userRes.result.records.map(item => ({
label: item.nickName,
id: item.id
}))]]
}}
}
</script>
<style lang="scss" scoped>
.container {
background-color: #f5f5f5;
min-height: 100vh;
}
.header{
padding: 16rpx 39rpx 23rpx;
background: #fff;
}
.main-tabs {
display: flex;
margin-bottom: 48rpx;
// border-bottom: 2rpx solid #f0f0f0;
.tab-item {
flex: 1;
position: relative;
padding: 13rpx 0;
text-align: center;
.tab-text {
font-size: 28rpx;
color: $secondary-text-color;
font-weight: 400;
transition: all 0.3s ease;
}
&.active {
.tab-text {
color: $primary-color;
// font-weight: 600;
}
}
.tab-underline {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 4rpx;
background-color: $primary-color;
border-radius: 2rpx;
}
}
}
.filter-section {
margin-bottom: 32rpx;
}
.picker-buttons {
// margin-bottom: 32rpx;
display: flex;
gap: 55rpx;
.picker-btn {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0;
background-color: transparent;
color: $primary-text-color;
&.active {
color: $primary-color;
}
.btn-text {
font-size: 28rpx;
// color: $primary-color;
margin-right: 10rpx;
}
.arrow-icon {
font-size: 20rpx;
// color: $primary-color;
}
}
}
.content-area {
padding: 22rpx 29rpx;
.loading-icon {
margin-top: 60rpx;
}
.record-item {
background: #fff;
border-radius: 16rpx;
padding: 29rpx;
margin-bottom: 37rpx;
border-radius: 15rpx;
box-shadow: 0 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
.info-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 38rpx;
.label {
font-size: 28rpx;
color: $primary-text-color;
// font-weight: 400;
flex-shrink: 0;
}
.value {
font-size: 28rpx;
color: $primary-text-color;
text-align: right;
flex: 1;
margin-left: 32rpx;
&.red-text {
color: $primary-color;
}
}
}
.content-text {
background: #f5f5f5;
border-radius: 15rpx;
padding: 24rpx;
margin-bottom: 24rpx;
min-height: 120rpx;
text {
font-size: 28rpx;
color: $primary-text-color;
line-height: 1.5;
}
}
.image-container {
margin-bottom: 29rpx;
.uploaded-image {
width: 157rpx;
height: 157rpx;
// border-radius: 8rpx;
}
}
.cost-table {
margin-bottom: 24rpx;
.table-header {
display: flex;
// background: #f8f8f8;
// border-radius: 8rpx 8rpx 0 0;
padding: 30rpx 0;
justify-content: space-between;
.header-cell {
flex: 1;
font-size: 30rpx;
color: $secondary-text-color;
&:nth-child(1) {
text-align: left;
}
&:nth-child(2) {
text-align: center;
}
&:nth-child(3) {
text-align: right;
}
// font-weight: 500;
}
}
.table-row {
display: flex;
border-bottom: 1rpx solid #f0f0f0;
padding: 30rpx 0;
// justify-content: space-between;
.cell {
flex: 1;
font-size: 30rpx;
color: $primary-text-color;
&:nth-child(1) {
text-align: left;
}
&:nth-child(2) {
text-align: center;
}
&:nth-child(3) {
text-align: right;
}
}
// .cell:first-child {
// text-align: center;
// }
}
}
.view-all-btn {
display: flex;
justify-content: center;
align-items: center;
padding: 16rpx 0;
margin-top: 16rpx;
.view-all-text {
font-size: 26rpx;
color: $primary-color;
margin-right: 8rpx;
}
.view-all-icon {
font-size: 20rpx;
color: $primary-color;
}
}
.collapse-btn {
display: flex;
justify-content: center;
align-items: center;
padding: 16rpx 0;
margin-top: 16rpx;
.collapse-text {
font-size: 26rpx;
color: $primary-color;
margin-right: 8rpx;
}
.collapse-icon {
font-size: 20rpx;
color: $primary-color;
}
}
}
}
</style>

+ 1
- 0
subPages/home/directory.vue View File

@ -168,6 +168,7 @@ export default {
.directory-container {
min-height: 100vh;
background-color: #264C8F;
padding-bottom: 200rpx;
}
.book-container{


+ 0
- 763
subPages/home/maintainanceSubmit.vue View File

@ -1,763 +0,0 @@
<template>
<view class="maintenance-submit">
<!-- 保养基本信息 -->
<view class="maintenance-info">
<view class="info-header">
<view class="red-line"></view>
<text class="info-title">保养项目</text>
</view>
<!-- 保养人 -->
<view class="form-item">
<text class="label">保养人</text>
<view class="input-area" >
<input
v-model="maintenanceName"
placeholder="请填写"
class="input-field"
ref="maintainerInput"
/>
</view>
</view>
<!-- 保养日期 -->
<view class="form-item" @click="showDatePicker">
<text class="label">保养日期</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !maintenanceDate }">{{ maintenanceDate || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 保养前状态 -->
<view class="form-item">
<text class="label">保养前状态</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="stateFrontText"
placeholder="请填写保养前的设备内容"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 保养前图片 -->
<view class="image-upload">
<view v-for="(img, index) in stateFrontImage" :key="index" class="image-item">
<image :src="img" mode="aspectFill" @click="previewImage(img, stateFrontImage)"></image>
<view class="delete-btn" @click="deleteBeforeImage(index)">
<uv-icon name="close" size="12" color="#fff"></uv-icon>
</view>
</view>
<view class="upload-btn" @click="uploadBeforeImage">
<uv-icon name="camera" size="34" color="#C70019"></uv-icon>
</view>
</view>
<!-- 保养后状态 -->
<view class="form-item">
<text class="label">保养后状态</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="stateBackText"
placeholder="请填写保养后的设备内容"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 保养后图片 -->
<view class="image-upload">
<view v-for="(img, index) in stateBackImage" :key="index" class="image-item">
<image :src="img" mode="aspectFill" @click="previewImage(img, stateBackImage)"></image>
<view class="delete-btn" @click="deleteAfterImage(index)">
<uv-icon name="close" size="12" color="#fff"></uv-icon>
</view>
</view>
<view class="upload-btn" @click="uploadAfterImage">
<uv-icon name="camera" size="34" color="#C70019"></uv-icon>
</view>
</view>
<!-- 是否产生费用 -->
<view class="form-item">
<text class="label">是否产生费用</text>
<view class="radio-options">
<view
class="radio-item"
:class="{ active: isExpend === '1' }"
@click="selectCost('1')"
>
<view class="radio-dot" :class="{ active: isExpend === '1' }"></view>
<text :class="{ active: isExpend === '1' }"></text>
</view>
<view
class="radio-item"
:class="{ active: isExpend === '0' }"
@click="selectCost('0')"
>
<view class="radio-dot" :class="{ active: isExpend === '0' }"></view>
<text :class="{ active: isExpend === '0' }"></text>
</view>
</view>
</view>
<!-- 产生费用 -->
<view class="form-item" v-if="isExpend === '1'">
<text class="label">产生费用</text>
<view class="input-area" >
<input
v-model="amount"
placeholder="请输入费用"
disabled
class="input-field"
/>
</view>
</view>
<!-- 费用详情表格 -->
<view class="cost-table" v-if="isExpend === '1'">
<view class="table-header">
<text class="header-cell">费用名称</text>
<text class="header-cell">数量</text>
<text class="header-cell">金额</text>
<text class="header-cell"></text>
</view>
<view class="table-row" v-for="(item, index) in costList" :key="index">
<view class="cell-input">
<uv-input
v-model="item.name"
placeholder="费用名称"
border="none"
:custom-style="{ backgroundColor: 'transparent', fontSize: '28rpx' }"
></uv-input>
</view>
<view class="cell-input">
<uv-input
v-model="item.quantity"
placeholder="数量"
border="none"
:custom-style="{ backgroundColor: 'transparent', fontSize: '28rpx' }"
></uv-input>
</view>
<view class="cell-input">
<uv-input
v-model="item.amount"
placeholder="金额"
type="digit"
border="none"
:custom-style="{ backgroundColor: 'transparent', fontSize: '28rpx' }"
></uv-input>
</view>
<view class="cell-action">
<view class="action-btn delete-btn" @click="removeCostItem(index)" v-if="costList.length > 1">
<uv-icon name="close" size="14" color="#fff"></uv-icon>
</view>
<view class="action-btn add-btn" @click="addCostItem" v-if="index === costList.length - 1">
<uv-icon name="plus" size="14" color="#fff"></uv-icon>
</view>
</view>
</view>
</view>
<!-- 附件信息 -->
<view class="form-item form-item-header">
<text class="label active">附件信息</text>
</view>
<!-- 保养备注 -->
<view class="form-item">
<text class="label">保养备注</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="remarkText"
placeholder="请填写备注"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 附件图片 -->
<view class="image-upload">
<view v-for="(img, index) in remarkImage" :key="index" class="image-item">
<image :src="img" mode="aspectFill" @click="previewImage(img, remarkImage)"></image>
<view class="delete-btn" @click="deleteAttachment(index)">
<uv-icon name="close" size="12" color="#fff"></uv-icon>
</view>
</view>
<view class="upload-btn" @click="uploadAttachment">
<uv-icon name="camera" size="34" color="#C70019"></uv-icon>
</view>
</view>
<!-- 下次保养日期 -->
<view class="form-item" @click="showNextDatePicker">
<text class="label">下次保养日期</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !nextMaintenanceDate }">{{ nextMaintenanceDate || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 备注 -->
<view class="form-item">
<text class="label">备注</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="remark"
placeholder="请填写备注"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit-container">
<uv-button
type="primary"
text="立即提交"
:disabled="submiting"
:custom-style="{ backgroundColor: '#C70019', borderRadius: '25px' }"
@click="submitMaintenance"
></uv-button>
</view>
<!-- 日期选择器 -->
<uv-datetime-picker
confirm-color="#C70019"
ref="datePicker"
mode="date"
v-model="timeValue"
@confirm="confirmDate"
></uv-datetime-picker>
<uv-datetime-picker
confirm-color="#C70019"
ref="nextDatePicker"
mode="date"
v-model="nextTimeValue"
@confirm="confirmNextDate"
></uv-datetime-picker>
</view>
</template>
<script>
export default {
data() {
return {
timeValue: Number(new Date()),
nextTimeValue: Number(new Date()),
//
maintenanceName: '',
maintenanceDate: '',
stateFrontText: '',
stateFrontImage: [],
stateBackText: '',
stateBackImage: [],
isExpend: '0',
costList: [{ name: '', quantity: '', amount: '' }],
remarkText: '',
remarkImage: [],
nextMaintenanceDate: '',
remark: '',
showpieceId: '',
submiting: false
}
},
computed: {
//
amount() {
return this.costList.reduce((sum, item) => {
return sum + (Number(item.quantity) * parseFloat(item.amount || 0))
}, 0)
}
},
methods: {
//
showDatePicker() {
this.$refs.datePicker.open()
},
//
confirmDate(e) {
// uv-datetime-picker
this.maintenanceDate = this.$utils.formatTime(e.value)
},
//
showNextDatePicker() {
this.$refs.nextDatePicker.open()
},
//
confirmNextDate(e) {
// uv-datetime-picker
this.nextMaintenanceDate = this.$utils.formatTime(e.value)
},
//
selectCost(value) {
this.isExpend = value
if (value === '0') {
this.costList = [{ name: '', quantity: '', amount: '' }]
} else if (this.costList.length === 0) {
this.costList = [{ name: '', quantity: '', amount: '' }]
}
},
//
addCostItem() {
this.costList.push({ name: '', quantity: '', amount: '' })
},
//
removeCostItem(index) {
if (this.costList.length > 1) {
this.costList.splice(index, 1)
} else {
uni.showToast({ title: '至少保留一个费用项目', icon: 'none' })
}
},
//
async uploadBeforeImage() {
try {
const result = await this.$utils.chooseAndUpload()
if (result && result.success) {
console.log(result);
this.stateFrontImage.push(result.url)
}
} catch (error) {
console.error('图片上传失败:', error)
uni.showToast({
title: '图片上传失败',
icon: 'error'
})
}
},
//
deleteBeforeImage(index) {
this.stateFrontImage.splice(index, 1)
},
//
async uploadAfterImage() {
try {
const result = await this.$utils.chooseAndUpload()
if (result && result.success) {
console.log(result);
this.stateBackImage.push(result.url)
}
} catch (error) {
console.error('头像上传失败:', error)
uni.showToast({
title: '头像上传失败',
icon: 'error'
})
}
},
//
deleteAfterImage(index) {
this.stateBackImage.splice(index, 1)
},
//
async uploadAttachment() {
try {
const result = await this.$utils.chooseAndUpload()
if (result && result.success) {
console.log(result);
this.remarkImage.push(result.url)
}
} catch (error) {
console.error('头像上传失败:', error)
uni.showToast({
title: '头像上传失败',
icon: 'error'
})
}
},
//
deleteAttachment(index) {
this.remarkImage.splice(index, 1)
},
//
previewImage(url, imageList) {
uni.previewImage({
urls: imageList,
current: url
})
},
//
async submitMaintenance() {
//
if (!this.maintenanceName.trim()) {
uni.showToast({ title: '请填写保养人', icon: 'none' })
return
}
if (!this.stateFrontText.trim()) {
uni.showToast({ title: '请填写保养前状态', icon: 'none' })
return
}
if (!this.stateBackText.trim()) {
uni.showToast({ title: '请填写保养后状态', icon: 'none' })
return
}
if (this.isExpend === '1' && !this.amount){
uni.showToast({ title: '请填写消费', icon: 'none' })
return
}
// costList,,;
//
const formData = {
maintenanceName: this.maintenanceName,
maintenanceDate: this.maintenanceDate,
stateFrontText: this.stateFrontText,
stateFrontImage: this.stateFrontImage?.join(',') || '',
stateBackText: this.stateBackText,
stateBackImage: this.stateBackImage?.join(',') || '',
expenseList: this.costList.map(item => {
return `${item.name},${item.quantity},${item.amount}`
}).join(';'),
isExpend: this.isExpend,
amount: this.amount,
remarkText: this.remarkText,
remarkImage: this.remarkImage?.join(',') || '',
nextMaintenanceDate: this.nextMaintenanceDate,
remark: this.remark,
showpieceId: this.showpieceId
}
this.submiting = true
try{
const subRes = await this.$api.exhibit.addMaintenance(formData)
if(subRes.code == 200){
uni.showToast({ title: subRes.message, icon: 'success' })
//
setTimeout(() => {
uni.navigateBack()
}, 1000)
}else{
uni.showToast({ title: subRes.message, icon: 'none' })
}
}catch(err){
// uni.showToast({ title: err.message, icon: 'none' })
this.submiting = false
}
}
},
onLoad(options) {
this.showpieceId = options.id
}
}
</script>
<style lang="scss" scoped>
.maintenance-submit {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 200rpx;
}
.maintenance-info {
margin: 18rpx;
background: #ffffff;
border-radius: 15rpx;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
padding: 40rpx;
.info-header {
display: flex;
align-items: center;
margin-bottom: 40rpx;
.red-line {
width: 9rpx;
height: 33rpx;
background-color: $primary-color;
margin-right: 7rpx;
border-radius: 5rpx;
}
.info-title {
font-size: 30rpx;
font-weight: bold;
color: $primary-text-color;
}
}
.form-item-header {
border-bottom: none;
margin-top: 20rpx;
}
.form-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 0;
border-bottom: 2rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.label {
font-size: 30rpx;
color: $primary-text-color;
flex-shrink: 0;
&.active {
font-weight: bold;
}
}
.value {
font-size: 30rpx;
color: $secondary-text-color;
&.placeholder {
color: $secondary-text-color;
}
}
.select-area {
display: flex;
align-items: center;
gap: 16rpx;
}
.input-area {
flex: 1;
// background-color: #f5f5f5;
border-radius: 8rpx;
padding: 16rpx 24rpx;
margin-left: 24rpx;
.input-field {
width: 100%;
font-size: 30rpx;
color: $primary-text-color;
background: transparent;
border: none;
outline: none;
text-align: right;
&::placeholder {
color: $secondary-text-color;
}
}
}
.radio-options {
display: flex;
gap: 60rpx;
.radio-item {
display: flex;
align-items: center;
gap: 16rpx;
.radio-dot {
width: 32rpx;
height: 32rpx;
border: 4rpx solid #ddd;
border-radius: 50%;
position: relative;
&.active {
border-color: $primary-color;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16rpx;
height: 16rpx;
background-color: $primary-color;
border-radius: 50%;
}
}
}
text {
font-size: 30rpx;
color: $secondary-text-color;
&.active {
color: $primary-color;
}
}
}
}
}
.textarea-container {
border-radius: 8rpx;
}
.image-upload {
display: flex;
flex-wrap: wrap;
gap: 24rpx;
margin: 16rpx 0;
.upload-btn {
width: 160rpx;
height: 160rpx;
border: 2rpx dashed $primary-color;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
}
.image-item {
position: relative;
width: 160rpx;
height: 160rpx;
image {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
.delete-btn {
position: absolute;
top: -12rpx;
right: -12rpx;
width: 40rpx;
height: 40rpx;
background-color: #ff4757;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
}
//
.cost-table {
margin-top: 24rpx;
border: 2rpx solid #f0f0f0;
border-radius: 8rpx;
overflow: hidden;
.table-header {
display: flex;
background-color: #f5f5f5;
padding: 16rpx 0;
.header-cell {
flex: 1;
text-align: center;
font-size: 28rpx;
font-weight: bold;
color: $primary-text-color;
&:first-child {
flex: 2;
}
&:last-child {
width: 120rpx;
flex: none;
}
}
}
.table-row {
display: flex;
border-top: 2rpx solid #f0f0f0;
.cell-input {
flex: 1;
padding: 8rpx;
border-right: 2rpx solid #f0f0f0;
&:first-child {
flex: 2;
}
&:last-child {
border-right: none;
}
}
.cell-action {
width: 120rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
padding: 8rpx;
.action-btn {
width: 36rpx;
height: 36rpx;
padding: 4rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
&.add-btn {
background-color: #1a9c10;
}
&.delete-btn {
background-color: $primary-color;
}
}
}
}
}
}
.submit-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 32rpx;
background-color: #fff;
border-top: 2rpx solid #f0f0f0;
}
</style>

+ 0
- 690
subPages/home/repairSubmit.vue View File

@ -1,690 +0,0 @@
<template>
<view class="repair-submit">
<!-- 导航栏 -->
<!-- <uv-navbar title="报修提交" :border="false" bg-color="#ffffff" title-color="#333333" /> -->
<!-- 报修基本信息 -->
<view class="repair-info">
<view class="info-header">
<view class="red-line"></view>
<text class="info-title">报修基本信息</text>
</view>
<!-- 报修日期 -->
<view class="form-item" @click="showDatePicker">
<text class="label">报修日期</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !malfunctionDate }">{{ malfunctionDate || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 故障紧急程度 -->
<view class="form-item " @click="showUrgencyPicker">
<text class="label">故障紧急程度</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !urgency }">{{ urgency.label || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 故障情况 -->
<view class="form-item form-item-header">
<text class="label active">故障情况</text>
</view>
<!-- 故障情况选择 -->
<view class="form-item" @click="showFaultPicker">
<text class="label">故障情况</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !malfunctionStatus }">{{ malfunctionStatus || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 故障情况描述 -->
<view class="form-item">
<text class="label">故障情况描述</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="malfunctionDesc"
placeholder="请对故障情况进行描述"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 故障图片 -->
<view class="form-item">
<text class="label">故障图片</text>
</view>
<view class="image-upload">
<view v-for="(img, index) in malfunctionImage" :key="index" class="image-item">
<image :src="img" mode="aspectFill" @click="previewImage(img)"></image>
<view class="delete-btn" @click="deleteImage(index)">
<uv-icon name="close" size="12" color="#fff"></uv-icon>
</view>
</view>
<view class="upload-btn" @click="uploadImage">
<uv-icon name="camera" size="34" color="#C70019"></uv-icon>
</view>
</view>
<!-- 故障首次发生时间 -->
<view class="form-item" @click="showFirstOccurTimePicker">
<text class="label">故障首次发生时间</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !firstDate }">{{ firstDate || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 发生频率 -->
<view class="form-item">
<text class="label">发生频率</text>
<view class="radio-options">
<view
v-for="(item, index) in frequencyOptions"
:key="index"
class="radio-item"
:class="{ active: frequency === item.value }"
@click="selectFrequency(item.value)"
>
<view class="radio-dot" :class="{ active: frequency === item.value }"></view>
<text :class="{ active: frequency === item.value }">{{ item.label }}</text>
</view>
</view>
</view>
<!-- 请描述与故障设备发生主要故障的具体条件 -->
<!-- <view class="form-item">
<text class="label">请描述与故障设备发生主要故障的具体条件</text>
</view> -->
<view class="textarea-container">
<uv-textarea
v-model="reason"
placeholder="请填写说明故障发生频率的触发条件"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 是否影响使用 -->
<view class="form-item" @click="showImpactPicker">
<text class="label">是否影响使用</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !isAffectUse }">{{ isAffectUse.label || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 采取的临时措施 -->
<!-- 故障情况 -->
<view class="form-item form-item-header">
<text class="label active">采取的临时措施</text>
</view>
<!-- <view class="form-item">
<text class="label">是否采取临时措施</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="measureDesc"
placeholder="如有采取临时措施请填写措施说明"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view> -->
<!-- 是否采取的对措施 -->
<view class="form-item">
<text class="label">是否采取临时措施</text>
<view class="radio-options">
<view
class="radio-item"
:class="{ active: isMeasure === '1' }"
@click="selectMeasures('1')"
>
<view class="radio-dot" :class="{ active: isMeasure === '1' }"></view>
<text :class="{ active: isMeasure === '1' }"></text>
</view>
<view
class="radio-item"
:class="{ active: isMeasure === '0' }"
@click="selectMeasures('0')"
>
<view class="radio-dot" :class="{ active: isMeasure === '0' }"></view>
<text :class="{ active: isMeasure === '0' }"></text>
</view>
</view>
</view>
<view class="textarea-container">
<uv-textarea
v-model="measureDesc"
placeholder="如有采取临时措施请填写措施说明"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 是否影响体验 -->
<view class="form-item">
<text class="label">是否影响体验</text>
<view class="radio-options">
<view
class="radio-item"
:class="{ active: isAffectExperience === '1' }"
@click="selectExperience('1')"
>
<view class="radio-dot" :class="{ active: isAffectExperience === '1' }"></view>
<text :class="{ active: isAffectExperience === '1' }"></text>
</view>
<view
class="radio-item"
:class="{ active: isAffectExperience === '0' }"
@click="selectExperience('0')"
>
<view class="radio-dot" :class="{ active: isAffectExperience === '0' }"></view>
<text :class="{ active: isAffectExperience === '0' }"></text>
</view>
</view>
</view>
<!-- 备注 -->
<view class="form-item">
<text class="label">备注</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="remark"
placeholder="备注"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit-container">
<uv-button
type="primary"
text="立即提交"
:custom-style="{ backgroundColor: '#C70019', borderRadius: '25px' }"
@click="submitRepair"
></uv-button>
</view>
<!-- 选择器 -->
<uv-picker
confirm-color="#C70019"
ref="urgencyPicker"
:columns="urgencyColumns"
keyName="label"
@confirm="confirmUrgency"
@cancel="cancelUrgency"
></uv-picker>
<uv-picker
confirm-color="#C70019"
ref="faultPicker"
:columns="faultColumns"
@confirm="confirmFault"
@cancel="cancelFault"
></uv-picker>
<!-- 故障首次发生时间选择器 -->
<uv-datetime-picker
ref="firstOccurTimePicker"
mode="date"
v-model="firstTime"
confirm-color="#C70019"
@confirm="confirmFirstOccurTime"
></uv-datetime-picker>
<uv-picker
confirm-color="#C70019"
ref="impactPicker"
:columns="impactColumns"
@confirm="confirmImpact"
@cancel="cancelImpact"
keyName="label"
></uv-picker>
<!-- 日期选择器 -->
<uv-datetime-picker
confirm-color="#C70019"
ref="datePicker"
v-model="timeValue"
mode="date"
@confirm="confirmDate"
></uv-datetime-picker>
</view>
</template>
<script>
export default {
data() {
return {
//
malfunctionDate: '',
urgency: '',
malfunctionStatus: '',
malfunctionDesc: '',
malfunctionImage: [],
firstDate: '',
frequency: '1',
reason: '',
isAffectUse: '0',
measureDesc: '',
isMeasure: '0',
isAffectExperience: '0',
remark: '',
showpieceId: '',
timeValue: Number(new Date()),
firstTime: Number(new Date()),
//
frequencyOptions: [
{ label: '持续性问题', value: '0' },
{ label: '间歇性问题', value: '1' }
],
//
urgencyColumns: [
[
{ label: '一般', value: '0' },
{ label: '紧急', value: '1'}
]
],
faultColumns: [['硬件故障', '软件故障', '网络故障', '其他']],
impactColumns: [[
{ label: '是', value: '1' },
{ label: '否', value: '0' }
]],
}
},
methods: {
//
showDatePicker() {
this.$refs.datePicker.open()
},
//
confirmDate(e) {
this.malfunctionDate = this.$utils.formatTime(e.value)
},
//
showUrgencyPicker() {
this.$refs.urgencyPicker.open()
},
//
confirmUrgency(e) {
this.urgency = e.value[0]
},
//
cancelUrgency() {
//
},
//
showFaultPicker() {
this.$refs.faultPicker.open()
},
//
confirmFault(e) {
this.malfunctionStatus = e.value[0]
},
//
cancelFault() {
//
},
//
showFirstOccurTimePicker() {
this.$refs.firstOccurTimePicker.open()
},
//
confirmFirstOccurTime(e) {
this.firstDate = this.$utils.formatTime(e.value)
},
// 使
showImpactPicker() {
this.$refs.impactPicker.open()
},
// 使
confirmImpact(e) {
this.isAffectUse = e.value[0]
},
// 使
cancelImpact() {
//
},
//
selectFrequency(value) {
this.frequency = value
},
//
selectMeasures(value) {
this.isMeasure = value
},
//
selectExperience(value) {
this.isAffectExperience = value
},
//
async uploadImage() {
try {
const result = await this.$utils.chooseAndUpload()
if (result && result.success) {
console.log(result);
this.malfunctionImage.push(result.url)
}
} catch (error) {
console.error('头像上传失败:', error)
uni.showToast({
title: '头像上传失败',
icon: 'error'
})
}
},
//
deleteImage(index) {
this.malfunctionImage.splice(index, 1)
},
//
previewImage(url) {
uni.previewImage({
urls: this.malfunctionImage,
current: url
})
},
//
async submitRepair() {
//
if (!this.urgency) {
uni.showToast({ title: '请选择故障紧急程度', icon: 'none' })
return
}
if (!this.malfunctionImage.length) {
uni.showToast({ title: '请上传故障图片', icon: 'none' })
return
}
if (!this.malfunctionDesc.trim()) {
uni.showToast({ title: '请填写故障情况描述', icon: 'none' })
return
}
if (!this.firstDate.trim()) {
uni.showToast({ title: '请选择故障首次发生时间', icon: 'none' })
return
}
//
const formData = {
showpieceId: this.showpieceId,
malfunctionDate: this.malfunctionDate,
urgency: this.urgency.value,
malfunctionDesc: this.malfunctionStatus + this.malfunctionDesc,
malfunctionImage: this.malfunctionImage.join(','),
firstDate: this.firstDate,
frequency: this.frequency,
reason: this.reason,
isAffectUse: this.isAffectUse.value,
measureDesc: this.measureDesc,
isMeasure: this.isMeasure,
isAffectExperience: this.isAffectExperience,
remark: this.remark
}
// console.log(':', formData)
// uni.showToast({ title: '', icon: 'success' })
const subRes = await this.$api.exhibit.addMalfunction({...formData})
if (subRes.code === 200) {
uni.showToast({ title: subRes.message})
setTimeout(() => {
uni.navigateBack()
}, 1000)
}else{
uni.showToast({ title: subRes.message, icon: 'none' })
}
}
},
async onLoad(args) {
this.showpieceId = args.id
try {
const listRes = await this.$api.config.queryMalfunctionDescList()
if (listRes.code === 200) {
this.faultColumns = [[...listRes.result.records.map(item => item.malfunction)]]
}
} catch (error) {
uni.showToast({ title: error.message, icon: 'none' })
}
}
}
</script>
<style lang="scss" scoped>
.repair-submit {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 200rpx;
}
.repair-info {
margin: 18rpx;
background: #ffffff;
border-radius: 15rpx;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
padding: 40rpx;
.info-header {
display: flex;
align-items: center;
margin-bottom: 40rpx;
.red-line {
width: 9rpx;
height: 33rpx;
background-color: $primary-color;
margin-right: 7rpx;
border-radius: 5rpx;
}
.info-title {
font-size: 30rpx;
font-weight: bold;
color: $primary-text-color;
}
}
.form-item-header {
border-bottom: none;
margin-top: 20rpx;
}
.form-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 0;
border-bottom: 2rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.label {
font-size: 30rpx;
color: $primary-text-color;
flex-shrink: 0;
&.active {
font-weight: bold;
}
}
.value {
font-size: 30rpx;
color: $secondary-text-color;
&.placeholder {
color: $secondary-text-color;
}
}
.select-area {
display: flex;
align-items: center;
gap: 16rpx;
}
}
.textarea-container {
// margin: 16rpx 0 32rpx 0;
// background-color: #f5f5f5;
border-radius: 8rpx;
// padding: 16rpx;
}
.image-upload {
display: flex;
flex-wrap: wrap;
gap: 24rpx;
margin: 16rpx 0;
.upload-btn {
width: 160rpx;
height: 160rpx;
border: 2rpx dashed $primary-color;
// border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
}
.image-item {
position: relative;
width: 160rpx;
height: 160rpx;
image {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
.delete-btn {
position: absolute;
top: -12rpx;
right: -12rpx;
width: 40rpx;
height: 40rpx;
background-color: #ff4757;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.hint-text {
font-size: 24rpx;
color: #999;
margin-top: 16rpx;
}
.form-item .radio-options {
display: flex;
gap: 60rpx;
.radio-item {
display: flex;
align-items: center;
gap: 16rpx;
.radio-dot {
width: 32rpx;
height: 32rpx;
border: 4rpx solid #ddd;
border-radius: 50%;
position: relative;
&.active {
border-color: $primary-color;
color: $primary-color;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16rpx;
height: 16rpx;
background-color: $primary-color;
border-radius: 50%;
}
}
}
text {
font-size: 30rpx;
color: $secondary-text-color;
&.active {
color: $primary-color;
}
}
}
}
}
.submit-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 32rpx;
background-color: #fff;
border-top: 2rpx solid #f0f0f0;
}
</style>

+ 0
- 1060
subPages/repair/maintainSubmit.vue
File diff suppressed because it is too large
View File


+ 187
- 0
subPages/user/cash.vue View File

@ -0,0 +1,187 @@
<template>
<view class="cash-page">
<!-- 顶部标题栏 -->
<!-- 表单内容 -->
<view class="form-container">
<view class="header">
<view class="title">微信提现</view>
<view class="flow-link">过往流水 ></view>
</view>
<!-- 真实姓名 -->
<view class="form-item">
<view class="label">真实姓名</view>
<uv-input
v-model="realName"
placeholder="请输入"
border="none"
:custom-style="inputStyle"
></uv-input>
</view>
<!-- 提现金额 -->
<view class="form-item">
<view class="label">提现金额</view>
<uv-input
v-model="amount"
placeholder="请输入"
type="number"
border="none"
:custom-style="inputStyle"
></uv-input>
</view>
</view>
<!-- 说明文字 -->
<view class="notice-text">
请仔细检查并确认相关信息因用户个人疏忽导致的充值错误需由用户自行承担
<text class="link-text" @click="showWithdrawRules">提现须知</text>
</view>
<!-- 固定底部按钮 -->
<view class="fixed-bottom">
<uv-button
type="primary"
:custom-style="buttonStyle"
@click="handleWithdraw"
>
提现
</uv-button>
<uv-safe-bottom></uv-safe-bottom>
</view>
</view>
</template>
<script>
export default {
data() {
return {
realName: '',
amount: '',
inputStyle: {
backgroundColor: 'transparent',
fontSize: '32rpx',
color: '#333'
},
buttonStyle: {
backgroundColor: '#22F2EB',
borderRadius: '50rpx',
height: '88rpx',
fontSize: '32rpx',
fontWeight: 'bold'
}
}
},
methods: {
handleWithdraw() {
if (!this.realName) {
uni.showToast({
title: '请输入真实姓名',
icon: 'none'
})
return
}
if (!this.amount) {
uni.showToast({
title: '请输入提现金额',
icon: 'none'
})
return
}
//
console.log('提现信息:', {
realName: this.realName,
amount: this.amount
})
uni.showToast({
title: '提现申请已提交',
icon: 'success'
})
},
showWithdrawRules() {
//
uni.showModal({
title: '提现须知',
content: '1. 提现金额最低10元\n2. 工作日24小时内到账\n3. 手续费按平台规定收取',
showCancel: false
})
}
}
}
</script>
<style lang="scss" scoped>
// @import '@/uni.scss';
.cash-page {
min-height: 100vh;
background-color: #F2F2F2;
padding-bottom: 200rpx;
padding-top: 40rpx;
.header {
background-color: #fff;
padding: 40rpx 40rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.flow-link {
font-size: 28rpx;
color: #999;
}
}
.form-container {
background-color: #fff;
margin: 20rpx 40rpx;
border-radius: 32rpx;
margin-top: 20rpx;
.form-item {
padding: 40rpx;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.label {
font-size: 32rpx;
color: #333;
margin-bottom: 20rpx;
font-weight: 500;
}
}
}
.notice-text {
padding: 40rpx;
font-size: 24rpx;
color: #999;
line-height: 1.6;
.link-text {
color: #22F2EB;
}
}
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx 40rpx;
background-color: #fff;
border-top: 1rpx solid #f0f0f0;
z-index: 999;
}
}
</style>

+ 300
- 0
subPages/user/discount.vue View File

@ -0,0 +1,300 @@
<template>
<view class="discount-container">
<!-- 顶部tab切换 -->
<uv-subsection
:list="tabList"
:current="currentTab"
@change="onTabChange"
:activeColor="tabStyle.activeColor"
:inactiveColor="tabStyle.inactiveColor"
:bgColor="tabStyle.bgColor"
:fontSize="tabStyle.fontSize"
:height="tabStyle.height"
></uv-subsection>
<!-- 优惠券列表 -->
<view class="coupon-list">
<view
v-for="(coupon, index) in currentCoupons"
:key="index"
class="coupon-item"
:class="{
'used-coupon': coupon.status === 'used',
'expired-coupon': coupon.status === 'expired'
}"
>
<!-- 左侧金额区域 -->
<view class="coupon-left">
<text class="coupon-symbol">¥</text>
<text class="coupon-amount">{{ coupon.amount }}</text>
<!-- 状态盖章 -->
<image
v-if="coupon.status !== 'available'"
class="status-stamp"
:src="coupon.status === 'used' ? '/static/已使用盖章.png' : '/static/已过期盖章.png'"
mode="aspectFit"
></image>
</view>
<!-- 右侧信息区域 -->
<view class="coupon-right">
<view class="coupon-title">{{ coupon.title }}</view>
<view class="coupon-expire">有效期至 {{ coupon.expireDate }}</view>
<!-- 使用按钮或状态 -->
<view class="coupon-action">
<uv-button
v-if="coupon.status === 'available'"
:customStyle="buttonStyle"
text="去使用"
@click="useCoupon(coupon)"
></uv-button>
<view
v-else
class="coupon-status"
:class="{
'used-status': coupon.status === 'used',
'expired-status': coupon.status === 'expired'
}"
>
{{ coupon.status === 'used' ? '已使用' : '已过期' }}
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<uv-empty
v-if="currentCoupons.length === 0"
text="暂无优惠券"
:textColor="emptyStyle.textColor"
:textSize="emptyStyle.textSize"
:marginTop="emptyStyle.marginTop"
></uv-empty>
</view>
</view>
</template>
<script>
export default {
data() {
return {
currentTab: 0,
tabList: [
{ name: '待使用' },
{ name: '已使用' },
{ name: '已过期' }
],
// tab
tabStyle: {
activeColor: '#06DADC',
inactiveColor: '#999',
bgColor: '#f8f8f8',
fontSize: '28rpx',
height: '80rpx'
},
//
buttonStyle: {
backgroundColor: '#06DADC',
borderRadius: '99rpx',
width: '140rpx',
height: '60rpx',
fontSize: '30rpx',
color: '#fff'
},
//
emptyStyle: {
textColor: '#999',
textSize: '28rpx',
marginTop: '200rpx'
},
//
coupons: {
available: [
{
id: 1,
title: '专属福利】20元红包',
amount: 20,
expireDate: '2026-04-28',
status: 'available'
},
{
id: 2,
title: '专属福利】400元红包',
amount: 400,
expireDate: '2026-04-28',
status: 'available'
},
{
id: 3,
title: '专属福利】400元红包',
amount: 400,
expireDate: '2026-04-28',
status: 'available'
}
],
used: [
{
id: 4,
title: '专属福利】20元红包',
amount: 20,
expireDate: '2026-04-28',
status: 'used'
}
],
expired: [
{
id: 5,
title: '专属福利】20元红包',
amount: 20,
expireDate: '2026-04-28',
status: 'expired'
}
]
}
}
},
computed: {
currentCoupons() {
const statusMap = ['available', 'used', 'expired']
return this.coupons[statusMap[this.currentTab]] || []
}
},
methods: {
onTabChange(index) {
this.currentTab = index
},
useCoupon(coupon) {
uni.showToast({
title: '跳转到使用页面',
icon: 'none'
})
}
}
}
</script>
<style lang="scss" scoped>
.discount-container {
min-height: 100vh;
background-color: #f8f8f8;
.coupon-list {
padding: 40rpx 30rpx;
.coupon-item {
display: flex;
background-color: #fff;
border-radius: 24rpx;
margin-bottom: 24rpx;
overflow: hidden;
position: relative;
padding: 8rpx;
// box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
&.used-coupon,
&.expired-coupon {
.coupon-left {
background-color: #E3E3E3;
.coupon-symbol,
.coupon-amount {
color: #FBFBFB;
}
}
}
.coupon-left {
width: 180rpx;
background-color: #FFF2F2;
display: flex;
// flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 16rpx;
position: relative;
.coupon-symbol {
font-size: 24rpx;
color: #FF4800;
font-weight: bold;
margin-bottom: 10rpx;
}
.coupon-amount {
font-size: 48rpx;
color: #FF4800;
font-weight: 500;
line-height: 1.4;
}
.status-stamp {
position: absolute;
bottom: 0rpx;
right: 0rpx;
width: 100rpx;
height: 100rpx;
// opacity: 0.8;
}
}
.coupon-right {
flex: 1;
margin-left: 20rpx;
padding: 40rpx 30rpx 20rpx;
position: relative;
width: 0px;
border-left: 2rpx dashed #DADADA;
.coupon-title {
font-size: 32rpx;
color: #181818;
font-weight: bold;
margin-bottom: 16rpx;
}
.coupon-expire {
font-size: 28rpx;
color: #9B9B9B;
margin-bottom: 16rpx;
}
.coupon-action {
display: flex;
justify-content: flex-start;
.coupon-status {
padding: 10rpx 30rpx;
border-radius: 40rpx;
font-size: 30rpx;
text-align: center;
&.used-status {
background-color: #E3E3E3;
color: #fff;
}
&.expired-status {
background-color: #E3E3E3;
color: #fff;
}
}
}
}
}
}
}
</style>

+ 31
- 0
subPages/user/introduce.vue View File

@ -0,0 +1,31 @@
<template>
<view class="container">
<view class="body">
<rich-text :nodes="htmlContent"></rich-text>
</view>
</view>
</template>
<script >
export default {
data() {
return {
htmlContent: '<h1>这是一个标题</h1><p>这是一个段落</p>'
}
}
}
</script>
<style scoped lang="scss">
.container {
min-height: 100vh;
background-color: #F7F8FA;
.body{
border-radius: 32rpx;
padding: 32rpx;
margin: 40rpx;
background: #fff;
}
}
</style>

+ 31
- 0
subPages/user/policy.vue View File

@ -0,0 +1,31 @@
<template>
<view class="container">
<view class="body">
<rich-text :nodes="htmlContent"></rich-text>
</view>
</view>
</template>
<script >
export default {
data() {
return {
htmlContent: '<h1>这是一个标题</h1><p>这是一个段落</p>'
}
}
}
</script>
<style scoped lang="scss">
.container {
min-height: 100vh;
background-color: #F7F8FA;
.body{
border-radius: 32rpx;
padding: 32rpx;
margin: 40rpx;
background: #fff;
}
}
</style>

+ 138
- 153
subPages/user/profile.vue View File

@ -1,64 +1,68 @@
<template>
<view class="profile-page">
<view class="profile-content">
<!-- 头像上传区域 -->
<view class="avatar-section">
<!-- 基本资料标签 -->
<view class="profile-label">
<text class="label-text">基本资料</text>
<view class="profile-container">
<!-- 个人信息表单 -->
<view class="form-container">
<view class="form-title">个人信息</view>
<!-- 昵称 -->
<view class="form-item">
<view class="label">
<text class="required">*</text>
<text>昵称</text>
</view>
<uv-input
v-model="userInfo.nickName"
placeholder="请输入昵称"
:customStyle="inputStyle"
border="bottom"
></uv-input>
</view>
<!-- 电话 -->
<view class="form-item">
<view class="label">
<text class="required">*</text>
<text>电话</text>
</view>
<uv-input
v-model="userInfo.phone"
placeholder="请输入手机号"
:customStyle="inputStyle"
border="bottom"
type="number"
></uv-input>
</view>
<!-- 头像 -->
<view class="form-item">
<view class="label">
<text class="required">*</text>
<text>头像</text>
</view>
<view class="avatar-container" @click="uploadAvatar">
<image
v-if="userInfo.headImage"
:src="userInfo.headImage"
:src="userInfo.headImage || '/static/默认头像.png'"
class="avatar-image"
mode="aspectFill"
/>
<view v-else class="avatar-placeholder">
<image src="@/static/待上传头像.png" class="placeholder-image" mode="aspectFit" />
></image>
<!-- 遮罩层 -->
<view class="avatar-mask" :class="{ 'fade-out': showMask }" v-if="showMask">
<text>点击上传头像</text>
</view>
</view>
<text class="avatar-tip">点击更换头像</text>
</view>
<!-- 表单区域 -->
<view class="form-section">
<!-- 昵称 -->
<view class="form-item">
<text class="form-label">昵称</text>
<uv-input
v-model="userInfo.nickName"
placeholder="请输入"
border="none"
class="form-input"
></uv-input>
</view>
<!-- 手机号 -->
<view class="form-item">
<text class="form-label">手机号</text>
<uv-input
v-model="userInfo.phone"
placeholder="请输入"
border="none"
class="form-input"
></uv-input>
</view>
</view>
<!-- 保存按钮 -->
<view class="save-section">
<uv-button
type="primary"
text="保存"
@click="saveProfile"
:custom-style="saveButtonStyle"
></uv-button>
</view>
</view>
<!-- 固定底部保存按钮 -->
<view class="save-button-container">
<uv-button
@click="saveProfile"
:customStyle="saveButtonStyle"
shape="circle"
>
保存
</uv-button>
</view>
</view>
</template>
@ -71,20 +75,27 @@ export default {
nickName: '',
phone: ''
},
showMask: true,
saveButtonStyle: {
backgroundColor: '#C70019',
backgroundColor: '#06DADC',
borderRadius: '41rpx',
height: '94rpx',
width: '594rpx',
border: 'none'
border: 'none',
color: '#fff',
fontSize: '32rpx',
fontWeight: '500'
},
inputStyle: {
backgroundColor: '#fff',
borderRadius: '12rpx',
padding: '0 -20rpx',
fontSize: '28rpx'
}
}
},
methods: {
//
goBack() {
uni.navigateBack()
},
//
async uploadAvatar() {
@ -161,119 +172,93 @@ export default {
}
},
onLoad() {
this.getProfile()
// this.getProfile()
// 3
setTimeout(() => {
this.showMask = false
}, 3000)
}
}
</script>
<style lang="scss" scoped>
.profile-page {
.profile-container {
min-height: 100vh;
// background-color: #f5f5f5;
}
.profile-content {
padding:45rpx 32rpx;
}
.avatar-section {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 80rpx;
position: relative;
background-color: #f5f5f5;
padding: 40rpx 32rpx 200rpx;
.profile-label {
position: absolute;
top: 0;
left: 28rpx;
z-index: 10;
.form-container {
background: #fff;
border-radius: 20rpx;
padding: 40rpx 32rpx;
.label-text {
font-size: 30rpx;
// font-weight: bold;
color: $primary-text-color;
position: relative;
&::before {
content: '';
position: absolute;
left: -16rpx;
top: 50%;
transform: translateY(-50%);
width: 9rpx;
height: 33rpx;
background-color: $primary-color;
border-radius: 5rpx;
}
.form-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 60rpx;
}
}
.avatar-container {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
overflow: hidden;
margin-bottom: 20rpx;
margin-top: 66rpx;
.avatar-image {
width: 100%;
height: 100%;
.form-item {
margin-bottom: 60rpx;
&:last-child {
margin-bottom: 0;
}
.label {
display: flex;
align-items: center;
margin-bottom: 20rpx;
font-size: 28rpx;
color: #333;
.required {
color: #ff4757;
margin-right: 8rpx;
}
}
}
.avatar-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #f0f0f0;
.avatar-container {
position: relative;
width: 200rpx;
height: 200rpx;
border-radius: 16rpx;
overflow: hidden;
.placeholder-image {
width: 80rpx;
height: 80rpx;
.avatar-image {
width: 100%;
height: 100%;
}
.avatar-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 24rpx;
transition: opacity 1s ease-out;
&.fade-out {
opacity: 0;
}
}
}
}
.avatar-tip {
font-size: 28rpx;
color: $secondary-text-color;
}
}
.form-section {
// background-color: #fff;
// border-radius: 16rpx;
padding: 0 32rpx;
margin-bottom: 500rpx;
.form-item {
display: flex;
align-items: center;
padding: 40rpx 0;
border-bottom: 0.5rpx solid #f0f0f0;
.form-label {
font-size: 30rpx;
color: $secondary-text-color;
width: 120rpx;
flex-shrink: 0;
}
.form-input {
flex: 1;
margin-left: 40rpx;
}
.save-button-container {
position: fixed;
bottom: 60rpx;
left: 50%;
transform: translateX(-50%);
z-index: 999;
}
}
.save-section {
display: flex;
justify-content: center;
}
</style>

+ 448
- 0
subPages/user/promote.vue View File

@ -0,0 +1,448 @@
<template>
<view class="promote-page">
<uv-status-bar></uv-status-bar>
<!-- 主要内容区域 -->
<view class="content">
<!-- 推广官图片 -->
<view class="promote-image-container">
<uv-icon name="arrow-left" size="20" color="black" @click="goBack"></uv-icon>
<view :style="{flex: 1, justifyContent: 'center', display: 'flex'}">
<image
class="promote-image"
src="/static/推广官.png"
mode="widthFix"
></image>
</view>
</view>
<!-- 推广标语图片 -->
<view class="slogan-container">
<image
class="slogan-image"
src="/static/推广标语.png"
mode="widthFix"
></image>
</view>
</view>
<!-- 外部大容器 -->
<view class="main-container">
<!-- 个人信息容器 -->
<view class="profile-container">
<image class="profile-avatar" src="/static/待上传头像.png" mode="aspectFill"></image>
<view class="profile-info">
<text class="profile-name">战斗世界</text>
<text class="profile-id">ID: 5625354</text>
</view>
<view class="profile-stats">
<view class="stat-item">
<text class="stat-number">888</text>
<text class="stat-label">推广人数</text>
</view>
<view class="stat-item">
<text class="stat-number">341</text>
<text class="stat-label">总佣金</text>
</view>
</view>
</view>
<!-- 功能按钮区域 -->
<view class="function-buttons">
<view class="function-item" @click="goTeam">
<image class="function-icon" src="/static/团队图标.png" mode="aspectFit"></image>
<text class="function-text">我的团队</text>
</view>
<view class="function-item">
<image class="function-icon" src="/static/二维码图标.png" mode="aspectFit"></image>
<text class="function-text">我的二维码</text>
</view>
<view class="function-item" @click="goCash">
<image class="function-icon" src="/static/提现图标.png" mode="aspectFit"></image>
<text class="function-text">提现</text>
</view>
</view>
<!-- 余额显示 -->
<view class="balance-section">
<text class="balance-label">余额</text>
<text class="balance-amount">¥88.32</text>
<uv-icon name="arrow-right" size="16" color="#999"></uv-icon>
</view>
<!-- 转账记录容器 -->
<view class="record-container">
<view class="record-list">
<view class="record-item" v-for="(item, index) in recordList" :key="index">
<view class="record-avatar">
<image class="avatar" :src="item.avatar" mode="aspectFill"></image>
<text class="avatar-name">{{ item.avatarName }}</text>
</view>
<view class="record-info">
<text class="record-title">{{ item.title }}</text>
<text class="record-date">{{ item.date }}</text>
</view>
<view class="record-amount">
<text class="amount">{{ item.amount }}</text>
<text class="status" :class="item.statusClass">{{ item.status }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 底部固定按钮 -->
<view class="bottom-button-container">
<uv-button :custom-style="{
height: '82rpx',
borderRadius: '198rpx',
background: '#06DADC',
border: '2rpx solid #06DADC',
lineHeight: '82rpx',
fontSize: '36rpx'
}" type="primary">分享</uv-button>
<uv-safe-bottom></uv-safe-bottom>
</view>
</view>
</template>
<script>
export default {
data() {
return {
recordList: [
{
avatar: '/static/待上传头像.png',
title: '分享提成获得奖励',
date: '2025-03-18',
amount: '+5',
status: '已领取,微信打款',
statusClass: 'status-received',
avatarName: '战斗世界'
},
{
avatar: '/static/待上传头像.png',
title: '分享提成获得奖励',
date: '2025-03-18',
amount: '+5',
status: '领取',
statusClass: 'status-available',
avatarName: '战斗世界'
},
{
avatar: '/static/待上传头像.png',
title: '分享提成获得奖励',
date: '2025-03-18',
amount: '+5',
status: '已领取,线下打款',
statusClass: 'status-received',
avatarName: '战斗世界'
},
{
avatar: '/static/待上传头像.png',
title: '分享提成获得奖励',
date: '2025-03-18',
amount: '+5',
status: '领取',
statusClass: 'status-available',
avatarName: '战斗世界'
},
{
avatar: '/static/待上传头像.png',
title: '分享提成获得奖励',
date: '2025-03-18',
amount: '+5',
status: '领取',
statusClass: 'status-available',
avatarName: '战斗世界'
}
]
}
},
methods: {
goBack() {
uni.navigateBack()
},
goTeam() {
uni.navigateTo({
url: '/subPages/user/team'
})
},
goCash() {
uni.navigateTo({
url: '/subPages/user/cash'
})
}
}
}
</script>
<style lang="scss" scoped>
.promote-page {
min-height: 100vh;
background: linear-gradient(124deg, #22F2EB 0%, #24B0F6 30%);
// background: linear-gradient(124deg, #22F2EB 0%, #24B0F6 100%);
}
.content {
padding: 0rpx 40rpx 0;
.promote-image-container {
display: flex;
justify-content: center;
margin-bottom: 30rpx;
align-items: center;
.promote-image {
margin: 0 auto;
width: 168rpx;
}
}
.slogan-container {
display: flex;
justify-content: center;
margin-bottom: 80rpx;
.slogan-image {
width: 670rpx;
}
}
}
//
.main-container {
width: 100%;
border-radius: 48rpx;
border: 2rpx solid #06DADC12;
box-sizing: border-box;
padding: 40rpx;
padding-bottom: 200rpx;
background: linear-gradient(180deg, #DEFFFF 0%, #FBFEFF 22.65%, #F0FBFF 100%);
//
.profile-container {
background: #fff;
margin-bottom: 30rpx;
display: flex;
align-items: center;
border-radius: 48rpx;
border-width: 2rpx;
justify-content: space-between;
background: linear-gradient(180deg, #DEFFFF 0%, #FBFEFF 22.65%, #F0FBFF 100%);
// background: red;
border: 2rpx solid #06DADC12;
// padding-top: 32rpx;
padding-right: 40rpx;
// padding-bottom: 32rpx;
padding-left: 40rpx;
height: 200rpx;
.profile-avatar {
width: 128rpx;
height: 128rpx;
border-radius: 50%;
margin-right: 24rpx;
}
.profile-info {
flex: 1;
.profile-name {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 8rpx;
}
.profile-id {
font-size: 24rpx;
color: #999;
}
}
.profile-stats {
display: flex;
.stat-item {
text-align: center;
margin-left: 60rpx;
.stat-number {
display: block;
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 8rpx;
}
.stat-label {
font-size: 24rpx;
color: #999;
}
}
}
}
//
.function-buttons {
display: flex;
justify-content: space-around;
align-items: center;
margin-bottom: 48rpx;
.function-item {
display: flex;
// flex-direction: column;
align-items: center;
gap: 16rpx;
border-right: 1px solid #06DADC;
padding-right: 30rpx;
&:nth-child(3) {
border-right: none;
}
.function-icon {
width: 46rpx;
height: 46rpx;
// margin-bottom: 16rpx;
}
.function-text {
font-size: 24rpx;
color: #181818;
}
}
}
//
.balance-section {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 40rpx;
.balance-label {
font-size: 32rpx;
color: #191919;
font-weight: 500;
}
.balance-amount {
font-size: 32rpx;
font-weight: 500;
color: #191919;
flex: 1;
margin-left: 20rpx;
}
}
//
.record-container {
.record-list {
border: 1px solid #F0F0F0;
border-radius: 24rpx;
// background: red;
.record-item {
height: 116rpx;
background: #fff;
// border-radius: 16rpx;
padding: 16rpx 32rpx;
// margin-bottom: 20rpx;
display: flex;
align-items: center;
border-bottom: 2rpx solid #F1F1F1 ;
// margin-right: 24rpx;
// box-sizing: border-box;
.record-avatar{
display: flex;
align-items: center;
flex-direction: column;
gap: 12rpx;
.avatar-name {
font-size: 24rpx;
color: #999;
}
.avatar {
width: 50rpx;
height: 50rpx;
border-radius: 50%;
// margin-right: 24rpx;
}
}
.record-info {
flex: 3;
text-align: center;
.record-title {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 8rpx;
}
.record-date {
font-size: 26rpx;
color: #A3A3A3;
}
}
.record-amount {
flex: 2;
text-align: center;
.amount {
display: block;
font-size: 28rpx;
font-weight: bold;
color: #333;
margin-bottom: 8rpx;
}
.status {
font-size: 26rpx;
// padding: 8rpx 16rpx;
border-radius: 20rpx;
&.status-received {
// background: #f0f0f0;
color: #A3A3A3;
}
&.status-available {
// background: #22F2EB;
padding: 3rpx 16rpx;
color: $primary-color;
border: 2rpx solid $primary-color;
}
}
}
}
}
}
}
//
.bottom-button-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx 40rpx;
background: rgba(255, 255, 255, 0.95);
border-top: 1px solid #F1F1F1;
// height: 143rpx;
// backdrop-filter: blur(10rpx);
}
</style>

+ 199
- 0
subPages/user/team.vue View File

@ -0,0 +1,199 @@
<template>
<view class="team-page">
<!-- 固定顶部搜索框 -->
<view class="fixed-header">
<view class="search-container">
<uv-search
v-model="searchKeyword"
placeholder="请输入"
:show-action="true"
action-text="搜索"
:animation="true"
bg-color="#f5f5f5"
@search="handleSearch"
@custom="handleSearch"
:action-style="{color: '#fff', backgroundColor: '#06DADC', borderRadius:'8rpx', width:'100rpx', height: '64rpx', lineHeight: '64rpx', borderRadius: '198rpx', text:'white', fontSize:'26rpx'}"
action
></uv-search>
</view>
</view>
<!-- 内容区域 -->
<view class="content-area">
<!-- 成员列表 -->
<view class="member-list">
<view
class="member-item"
v-for="(member, index) in filteredMembers"
:key="index"
@click="handleMemberClick(member)"
>
<image
class="member-avatar"
:src="member.avatar || '/static/默认头像.png'"
mode="aspectFill"
></image>
<text class="member-name">{{ member.name }}</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
searchKeyword: '',
members: [
{
id: 1,
name: '李世海',
avatar: '/static/默认头像.png'
},
{
id: 2,
name: '周静',
avatar: '/static/默认头像.png'
},
{
id: 3,
name: '周海',
avatar: '/static/默认头像.png'
},
{
id: 4,
name: '冯启彬',
avatar: '/static/默认头像.png'
},
{
id: 5,
name: '李嫣',
avatar: '/static/默认头像.png'
},
{
id: 6,
name: '李书萍',
avatar: '/static/默认头像.png'
},
{
id: 7,
name: '赵吾光',
avatar: '/static/默认头像.png'
},
{
id: 8,
name: '冯云',
avatar: '/static/默认头像.png'
},
{
id: 9,
name: '周静',
avatar: '/static/默认头像.png'
},
{
id: 10,
name: '周海',
avatar: '/static/默认头像.png'
},
{
id: 11,
name: '冯启彬',
avatar: '/static/默认头像.png'
},
{
id: 12,
name: '李嫣',
avatar: '/static/默认头像.png'
}
]
}
},
computed: {
filteredMembers() {
if (!this.searchKeyword) {
return this.members
}
return this.members.filter(member =>
member.name.includes(this.searchKeyword)
)
}
},
methods: {
handleSearch() {
// computed
console.log('搜索关键词:', this.searchKeyword)
},
handleMemberClick(member) {
console.log('点击成员:', member)
//
}
}
}
</script>
<style lang="scss" scoped>
// @import '@/uni.scss';
.team-page {
min-height: 100vh;
background-color: #f2f2f2;
//
.fixed-header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
background-color: #fff;
.search-container {
padding: 20rpx 30rpx;
background-color: #fff;
}
}
//
.content-area {
padding-top: 140rpx; //
.member-list {
background-color: #fff;
margin: 0 40rpx;
border-radius: 32rpx;
.member-item {
display: flex;
align-items: center;
padding: 16rpx 32rpx;
height: 104rpx;
border-bottom: 2rpx solid #F1F1F1;
transition: background-color 0.3s;
&:active {
background-color: #f5f5f5;
}
&:last-child {
border-bottom: none;
}
.member-avatar {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
margin-right: 24rpx;
background-color: #f0f0f0;
}
.member-name {
font-size: 32rpx;
color: #333;
font-weight: 400;
}
}
}
}
}
</style>

Loading…
Cancel
Save