道馆页面更改
Showing
19 changed files
with
4202 additions
and
309 deletions
| ... | @@ -5,7 +5,9 @@ | ... | @@ -5,7 +5,9 @@ |
| 5 | "WebFetch(domain:minimax-algeng-chat-tts.oss-cn-wulanchabu.aliyuncs.com)", | 5 | "WebFetch(domain:minimax-algeng-chat-tts.oss-cn-wulanchabu.aliyuncs.com)", |
| 6 | "Bash(node -c pages/index/perfect.vue)", | 6 | "Bash(node -c pages/index/perfect.vue)", |
| 7 | "Bash(git checkout:*)", | 7 | "Bash(git checkout:*)", |
| 8 | "Bash(git restore:*)" | 8 | "Bash(git restore:*)", |
| 9 | "Bash(git:*)", | ||
| 10 | "Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\('tabBar list:', [l['pagePath'] for l in d.get\\('tabBar',{}\\).get\\('list',[]\\)]\\)\")" | ||
| 9 | ] | 11 | ] |
| 10 | } | 12 | } |
| 11 | } | 13 | } | ... | ... |
| ... | @@ -11,22 +11,28 @@ | ... | @@ -11,22 +11,28 @@ |
| 11 | baseUrl_api: '', | 11 | baseUrl_api: '', |
| 12 | user: null | 12 | user: null |
| 13 | }, | 13 | }, |
| 14 | onLaunch: function(options) { | 14 | onLaunch: async function(options) { |
| 15 | console.log('App Launch', options); | 15 | console.log('App Launch', options); |
| 16 | this.globalData.baseUrl_api = config.baseUrl_api; | 16 | this.globalData.baseUrl_api = config.baseUrl_api; |
| 17 | 17 | ||
| 18 | let userName = uni.getStorageSync('userName') | 18 | let userName = uni.getStorageSync('userName') |
| 19 | if (userName) { | 19 | if (userName) { |
| 20 | getInfo().then(() => { | 20 | await getInfo(this) |
| 21 | this.globalData.isLogin = true | 21 | this.globalData.isLogin = true |
| 22 | // 道馆用户跳转到道馆首页 | ||
| 23 | const deptType = this.globalData.deptType | ||
| 24 | const userType = this.globalData.userType | ||
| 25 | |||
| 26 | // 道馆判断:deptType=6 或者 userType='4' | ||
| 27 | if (deptType == 6 || deptType == '6' || userType == '4') { | ||
| 22 | uni.reLaunch({ | 28 | uni.reLaunch({ |
| 23 | url: '/pages/index/home' | 29 | url: '/pages/index/daoGuanPerson' |
| 24 | }) | 30 | }) |
| 25 | }).catch(() => { | 31 | } else { |
| 26 | uni.reLaunch({ | 32 | uni.reLaunch({ |
| 27 | url: '/login/login' | 33 | url: '/pages/index/home' |
| 28 | }) | 34 | }) |
| 29 | }) | 35 | } |
| 30 | return | 36 | return |
| 31 | } | 37 | } |
| 32 | 38 | ||
| ... | @@ -62,4 +68,4 @@ | ... | @@ -62,4 +68,4 @@ |
| 62 | /*每个页面公共css */ | 68 | /*每个页面公共css */ |
| 63 | @import '/common/uni.css'; | 69 | @import '/common/uni.css'; |
| 64 | @import '/common/mystyle.scss'; | 70 | @import '/common/mystyle.scss'; |
| 65 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 71 | </style> | ... | ... |
| ... | @@ -10,7 +10,13 @@ function pcLogin(data) { | ... | @@ -10,7 +10,13 @@ function pcLogin(data) { |
| 10 | params: data | 10 | params: data |
| 11 | }).then((res) => { | 11 | }).then((res) => { |
| 12 | uni.setStorageSync('token', 'Bearer ' + res.data.token) | 12 | uni.setStorageSync('token', 'Bearer ' + res.data.token) |
| 13 | pcLoginOpenId() | 13 | return new Promise((resolve) => { |
| 14 | pcLoginOpenId() | ||
| 15 | // 延迟一下确保 token 设置完成 | ||
| 16 | setTimeout(() => { | ||
| 17 | resolve() | ||
| 18 | }, 100) | ||
| 19 | }) | ||
| 14 | }).then(getInfo) | 20 | }).then(getInfo) |
| 15 | } | 21 | } |
| 16 | 22 | ||
| ... | @@ -98,14 +104,16 @@ function loginByPhone(phonenumber, code) { | ... | @@ -98,14 +104,16 @@ function loginByPhone(phonenumber, code) { |
| 98 | } | 104 | } |
| 99 | 105 | ||
| 100 | // 获取用户详细信息 | 106 | // 获取用户详细信息 |
| 101 | function getInfo() { | 107 | function getInfo(appInstance) { |
| 102 | return request({ | 108 | console.log('getInfo 开始调用') |
| 103 | url: '/getInfo', | 109 | return request({ |
| 104 | method: 'get' | 110 | url: '/getInfo', |
| 105 | }).then(res => { | 111 | method: 'get' |
| 106 | const userStore = useUserStore() | 112 | }).then(res => { |
| 107 | const app = getApp() | 113 | console.log('getInfo 成功', res.data) |
| 108 | const user = res.data.user | 114 | const userStore = useUserStore() |
| 115 | const app = appInstance || getApp() | ||
| 116 | const user = res.data.user | ||
| 109 | 117 | ||
| 110 | uni.setStorageSync('userName', user.userName) | 118 | uni.setStorageSync('userName', user.userName) |
| 111 | uni.removeStorageSync('webUserName') | 119 | uni.removeStorageSync('webUserName') |
| ... | @@ -126,6 +134,12 @@ function getInfo() { | ... | @@ -126,6 +134,12 @@ function getInfo() { |
| 126 | } else { | 134 | } else { |
| 127 | app.globalData.userType = '3' | 135 | app.globalData.userType = '3' |
| 128 | } | 136 | } |
| 137 | |||
| 138 | console.log('getInfo跳转判断 - deptType:', deptType, 'userType:', app.globalData.userType) | ||
| 139 | // 道馆用户跳转道馆首页 | ||
| 140 | return res | ||
| 141 | }).catch(err => { | ||
| 142 | console.error('getInfo 失败:', err) | ||
| 129 | }) | 143 | }) |
| 130 | } | 144 | } |
| 131 | 145 | ... | ... |
components/dao-guan-tab-bar.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="dao-guan-tab-bar"> | ||
| 3 | <image | ||
| 4 | v-if="currentIndex >= 0" | ||
| 5 | :src="config.baseUrl_api + '/fs/static/img/toolbar.png'" | ||
| 6 | class="dg-tab-bar-bg" | ||
| 7 | mode="scaleToFill" | ||
| 8 | :style="{ left: tabBgLeft }" | ||
| 9 | ></image> | ||
| 10 | <view | ||
| 11 | v-for="(item, index) in tabs" | ||
| 12 | :key="index" | ||
| 13 | class="dg-tab-item" | ||
| 14 | :class="{ active: currentIndex === index }" | ||
| 15 | @click="handleClick(index, item.url)" | ||
| 16 | > | ||
| 17 | <image :src="currentIndex === index ? item.activeIcon : item.icon" class="dg-tab-icon"></image> | ||
| 18 | <text class="dg-tab-text">{{ item.text }}</text> | ||
| 19 | </view> | ||
| 20 | </view> | ||
| 21 | </template> | ||
| 22 | |||
| 23 | <script setup> | ||
| 24 | import config from '@/config.js' | ||
| 25 | import { computed, ref } from 'vue' | ||
| 26 | |||
| 27 | const props = defineProps({ | ||
| 28 | currentIndex: { | ||
| 29 | type: Number, | ||
| 30 | default: 0 | ||
| 31 | } | ||
| 32 | }) | ||
| 33 | |||
| 34 | const emit = defineEmits(['switch']) | ||
| 35 | const switching = ref(false) | ||
| 36 | |||
| 37 | const tabs = [ | ||
| 38 | { text: '人员', url: '/pages/index/daoGuanPerson', icon: '/static/img/tool01.png', activeIcon: '/static/img/tool01_dwn.png' }, | ||
| 39 | { text: '订单', url: '/pages/index/daoGuanOrder', icon: '/static/img/tool02.png', activeIcon: '/static/img/tool02_dwn.png' }, | ||
| 40 | { text: '通知', url: '/pages/index/daoGuanNotice', icon: '/static/img/tool03.png', activeIcon: '/static/img/tool03_dwn.png' }, | ||
| 41 | { text: '级位', url: '/pages/index/daoGuanLevel', icon: '/static/img/tool04.png', activeIcon: '/static/img/tool04_dwn.png' }, | ||
| 42 | { text: '我的', url: '/pages/index/daoGuanMy', icon: '/static/img/tool05.png', activeIcon: '/static/img/tool05_dwn.png' }, | ||
| 43 | ] | ||
| 44 | |||
| 45 | const tabBgLeft = computed(() => { | ||
| 46 | if (props.currentIndex < 0) return '0' | ||
| 47 | return `${props.currentIndex * 20}%` | ||
| 48 | }) | ||
| 49 | |||
| 50 | const handleClick = (index, url) => { | ||
| 51 | if (switching.value || index === props.currentIndex) return | ||
| 52 | |||
| 53 | switching.value = true | ||
| 54 | emit('switch', index, url) | ||
| 55 | |||
| 56 | uni.redirectTo({ | ||
| 57 | url, | ||
| 58 | fail: () => { | ||
| 59 | switching.value = false | ||
| 60 | } | ||
| 61 | }) | ||
| 62 | } | ||
| 63 | </script> | ||
| 64 | |||
| 65 | <style lang="scss" scoped> | ||
| 66 | .dao-guan-tab-bar { | ||
| 67 | position: fixed; | ||
| 68 | bottom: 0; | ||
| 69 | left: 0; | ||
| 70 | right: 0; | ||
| 71 | height: 120rpx; | ||
| 72 | display: flex; | ||
| 73 | justify-content: flex-start; | ||
| 74 | align-items: stretch; | ||
| 75 | padding-bottom: env(safe-area-inset-bottom); | ||
| 76 | z-index: 9999; | ||
| 77 | background-color: #d9d9d9; | ||
| 78 | overflow: hidden; | ||
| 79 | } | ||
| 80 | |||
| 81 | .dg-tab-bar-bg { | ||
| 82 | position: absolute; | ||
| 83 | top: 0rpx; | ||
| 84 | width: 20%; | ||
| 85 | height: calc(100% - 35rpx); | ||
| 86 | z-index: 0; | ||
| 87 | transition: left 0.3s ease; | ||
| 88 | pointer-events: none; | ||
| 89 | } | ||
| 90 | |||
| 91 | .dg-tab-item { | ||
| 92 | display: flex; | ||
| 93 | flex-direction: column; | ||
| 94 | align-items: center; | ||
| 95 | justify-content: center; | ||
| 96 | width: 20%; | ||
| 97 | height: 100%; | ||
| 98 | position: relative; | ||
| 99 | z-index: 1; | ||
| 100 | } | ||
| 101 | |||
| 102 | .dg-tab-icon { | ||
| 103 | width: 50rpx; | ||
| 104 | height: 50rpx; | ||
| 105 | margin-bottom: 4rpx; | ||
| 106 | } | ||
| 107 | |||
| 108 | .dg-tab-text { | ||
| 109 | font-size: 20rpx; | ||
| 110 | color: #666; | ||
| 111 | } | ||
| 112 | |||
| 113 | .dg-tab-item.active .dg-tab-text { | ||
| 114 | color: #C30D23; | ||
| 115 | font-weight: bold; | ||
| 116 | } | ||
| 117 | </style> |
| 1 | <template> | 1 | <template> |
| 2 | <view class="role-entry-page"> | 2 | <view class="role-entry-page"> |
| 3 | <!-- 全屏背景图 --> | 3 | <!-- 全屏背景图 --> |
| 4 | <image :src="config.loginImage_api + '/fs/static/dg/bg@3x.png'" class="page-bg" mode="aspectFill"></image> | 4 | <image :src="config.baseUrl_api + '/fs/static/img/home_bg.png'" class="page-bg" mode="aspectFill"></image> |
| 5 | 5 | ||
| 6 | <!-- 顶部 Logo 区域 --> | 6 | <!-- 顶部 Logo 区域 --> |
| 7 | <view class="header-wrapper"> | 7 | <!-- <view class="header-wrapper"> |
| 8 | <view class="logo-box"> | 8 | <view class="logo-box"> |
| 9 | <image :src="config.loginImage_api + '/fs/static/dg/ztx_b.svg'" class="logo" mode="aspectFit"></image> | 9 | <image :src="config.loginImage_api + '/fs/static/dg/ztx_b.svg'" class="logo" mode="aspectFit"></image> |
| 10 | </view> | 10 | </view> |
| 11 | </view> | 11 | </view> --> |
| 12 | 12 | ||
| 13 | <!-- 功能按钮区域 --> | 13 | <!-- 功能按钮区域 --> |
| 14 | <view class="btn-container"> | 14 | <view class="btn-container"> |
| 15 | <view @click="goToPage('/personal/addVip_per')"> | 15 | <view |
| 16 | <image :src="config.loginImage_api + '/fs/static/dg/btn01@3x.png'" class="btn-item"></image> | 16 | class="entry-btn" |
| 17 | </view> | 17 | :class="{ active: activeEntry === 'unit' }" |
| 18 | <view @click="goToPage('/personal/home')"> | 18 | @click="goUnitLogin" |
| 19 | <image :src="config.loginImage_api + '/fs/static/dg/btn02@3x.png'" class="btn-item"></image> | 19 | > |
| 20 | </view> | 20 | <image :src="activeEntry === 'unit' ? '/static/img/home_btn2.png' : '/static/img/home_btn.png'" class="btn-bg" mode="scaleToFill"></image> |
| 21 | <view @click="goToPage('/login/loginC')"> | 21 | <text>单位会员入口</text> |
| 22 | <image :src="config.loginImage_api + '/fs/static/dg/btn03@3x.png'" class="btn-item"></image> | 22 | </view> |
| 23 | </view> | 23 | |
| 24 | </view> | 24 | <view |
| 25 | 25 | class="entry-btn" | |
| 26 | 26 | :class="{ active: activeEntry === 'personal' }" | |
| 27 | </view> | 27 | @click="showLoginPopup" |
| 28 | </template> | 28 | > |
| 29 | <script setup> | 29 | <image :src="activeEntry === 'personal' ? '/static/img/home_btn2.png' : '/static/img/home_btn.png'" class="btn-bg" mode="scaleToFill"></image> |
| 30 | import {ref} from 'vue' | 30 | <text>个人会员入口</text> |
| 31 | import {onShow} from '@dcloudio/uni-app' | 31 | </view> |
| 32 | import config from '@/config.js' | 32 | </view> |
| 33 | 33 | ||
| 34 | onShow(() => { | 34 | <!-- 个人会员登录注册弹框 --> |
| 35 | uni.hideLoading(); | 35 | <uni-popup ref="loginPopup" :mask-click="true" type="center" @change="handlePopupChange"> |
| 36 | }) | 36 | <view class="login-popup-content"> |
| 37 | 37 | <!-- <view class="popup-title">请选择办理方式</view> --> | |
| 38 | const goToPage = (url) => { | 38 | <view class="popup-btn active-btn" @click="goToPage('/personal/addVip_per')"> |
| 39 | uni.navigateTo({ | 39 | 个人会员注册 |
| 40 | url, | 40 | </view> |
| 41 | }) | 41 | <view class="popup-btn plain-btn" @click="goToPage('/personal/home')"> |
| 42 | } | 42 | 个人会员登录 |
| 43 | </script> | 43 | </view> |
| 44 | <style lang="scss" scoped> | 44 | </view> |
| 45 | .role-entry-page { | 45 | </uni-popup> |
| 46 | width: 100%; | 46 | |
| 47 | min-height: 100vh; | 47 | </view> |
| 48 | position: relative; | 48 | </template> |
| 49 | padding: 20rpx; | 49 | <script setup> |
| 50 | box-sizing: border-box; | 50 | import {ref} from 'vue' |
| 51 | } | 51 | import {onShow} from '@dcloudio/uni-app' |
| 52 | 52 | import config from '@/config.js' | |
| 53 | .page-bg { | 53 | |
| 54 | position: absolute; | 54 | const loginPopup = ref(null) |
| 55 | top: 0; | 55 | const activeEntry = ref('') |
| 56 | left: 0; | 56 | |
| 57 | width: 100%; | 57 | onShow(() => { |
| 58 | height: 100%; | 58 | uni.hideLoading(); |
| 59 | z-index: -1; | 59 | }) |
| 60 | } | 60 | |
| 61 | 61 | const showLoginPopup = () => { | |
| 62 | .header-wrapper { | 62 | activeEntry.value = 'personal' |
| 63 | text-align: center; | 63 | loginPopup.value.open() |
| 64 | // padding: 40rpx 0; | 64 | } |
| 65 | border-radius: 16rpx; | 65 | |
| 66 | margin-top: 100rpx; | 66 | const goUnitLogin = () => { |
| 67 | } | 67 | activeEntry.value = 'unit' |
| 68 | 68 | uni.navigateTo({ | |
| 69 | .btn-container { | 69 | url: '/login/loginC', |
| 70 | display: flex; | 70 | }) |
| 71 | flex-direction: column; | 71 | } |
| 72 | align-items: center; | 72 | |
| 73 | margin: 0 auto; | 73 | const goToPage = (url) => { |
| 74 | 74 | loginPopup.value?.close() | |
| 75 | img, image { | 75 | uni.navigateTo({ |
| 76 | width: 509rpx; | 76 | url, |
| 77 | height: 117rpx; | 77 | }) |
| 78 | margin: 40rpx 0; | 78 | } |
| 79 | 79 | ||
| 80 | } | 80 | const handlePopupChange = (e) => { |
| 81 | } | 81 | if (!e.show && activeEntry.value === 'personal') { |
| 82 | 82 | activeEntry.value = '' | |
| 83 | .loading-overlay { | 83 | } |
| 84 | position: fixed; | 84 | } |
| 85 | top: 0; | 85 | </script> |
| 86 | left: 0; | 86 | <style lang="scss" scoped> |
| 87 | right: 0; | 87 | .role-entry-page { |
| 88 | bottom: 0; | 88 | width: 100%; |
| 89 | background-color: rgba(0, 0, 0, 0.5); | 89 | min-height: 100vh; |
| 90 | display: flex; | 90 | position: relative; |
| 91 | justify-content: center; | 91 | padding: 20rpx 0; |
| 92 | align-items: center; | 92 | box-sizing: border-box; |
| 93 | z-index: 999; | 93 | overflow: hidden; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | .loading-content { | 96 | .page-bg { |
| 97 | color: white; | 97 | position: absolute; |
| 98 | font-size: 28rpx; | 98 | top: 0; |
| 99 | } | 99 | left: 0; |
| 100 | </style> | 100 | width: 100%; |
| 101 | height: 100%; | ||
| 102 | z-index: -1; | ||
| 103 | } | ||
| 104 | |||
| 105 | .header-wrapper { | ||
| 106 | text-align: center; | ||
| 107 | // padding: 40rpx 0; | ||
| 108 | border-radius: 16rpx; | ||
| 109 | margin-top: 100rpx; | ||
| 110 | } | ||
| 111 | |||
| 112 | .btn-container { | ||
| 113 | display: flex; | ||
| 114 | flex-direction: column; | ||
| 115 | align-items: center; | ||
| 116 | margin: 0 auto; | ||
| 117 | padding-top: 1040rpx; | ||
| 118 | gap: 52rpx; | ||
| 119 | } | ||
| 120 | |||
| 121 | .entry-btn { | ||
| 122 | position: relative; | ||
| 123 | width: 424rpx; | ||
| 124 | height: 86rpx; | ||
| 125 | display: flex; | ||
| 126 | align-items: center; | ||
| 127 | justify-content: center; | ||
| 128 | color: #2f2f2f; | ||
| 129 | font-size: 34rpx; | ||
| 130 | font-weight: 700; | ||
| 131 | letter-spacing: 2rpx; | ||
| 132 | } | ||
| 133 | |||
| 134 | .entry-btn.active { | ||
| 135 | color: #fff; | ||
| 136 | } | ||
| 137 | |||
| 138 | .btn-bg { | ||
| 139 | position: absolute; | ||
| 140 | inset: 0; | ||
| 141 | width: 100%; | ||
| 142 | height: 100%; | ||
| 143 | } | ||
| 144 | |||
| 145 | .entry-btn text { | ||
| 146 | position: relative; | ||
| 147 | z-index: 1; | ||
| 148 | } | ||
| 149 | |||
| 150 | .loading-overlay { | ||
| 151 | position: fixed; | ||
| 152 | top: 0; | ||
| 153 | left: 0; | ||
| 154 | right: 0; | ||
| 155 | bottom: 0; | ||
| 156 | background-color: rgba(0, 0, 0, 0.5); | ||
| 157 | display: flex; | ||
| 158 | justify-content: center; | ||
| 159 | align-items: center; | ||
| 160 | z-index: 999; | ||
| 161 | } | ||
| 162 | |||
| 163 | .loading-content { | ||
| 164 | color: white; | ||
| 165 | font-size: 28rpx; | ||
| 166 | } | ||
| 167 | |||
| 168 | .login-popup-content { | ||
| 169 | width: 560rpx; | ||
| 170 | background: #fff; | ||
| 171 | border-radius: 28rpx; | ||
| 172 | padding: 42rpx 42rpx 50rpx; | ||
| 173 | display: flex; | ||
| 174 | flex-direction: column; | ||
| 175 | align-items: center; | ||
| 176 | box-shadow: 0 20rpx 60rpx rgba(50, 0, 0, 0.25); | ||
| 177 | } | ||
| 178 | |||
| 179 | .popup-title { | ||
| 180 | margin-bottom: 22rpx; | ||
| 181 | color: #222; | ||
| 182 | font-size: 34rpx; | ||
| 183 | font-weight: 700; | ||
| 184 | } | ||
| 185 | |||
| 186 | .popup-btn { | ||
| 187 | position: relative; | ||
| 188 | width: 424rpx; | ||
| 189 | height: 86rpx; | ||
| 190 | line-height: 86rpx; | ||
| 191 | text-align: center; | ||
| 192 | border-radius: 16rpx; | ||
| 193 | font-size: 34rpx; | ||
| 194 | font-weight: 700; | ||
| 195 | margin: 18rpx 0; | ||
| 196 | box-sizing: border-box; | ||
| 197 | } | ||
| 198 | |||
| 199 | .active-btn { | ||
| 200 | background: linear-gradient(90deg, #ff9a00 0%, #e50012 100%); | ||
| 201 | color: #fff; | ||
| 202 | } | ||
| 203 | |||
| 204 | .plain-btn { | ||
| 205 | background: #fff; | ||
| 206 | color: #2f2f2f; | ||
| 207 | border: 4rpx solid #0b94d2; | ||
| 208 | box-shadow: inset 4rpx 0 0 #f7a100; | ||
| 209 | } | ||
| 210 | </style> | ... | ... |
| ... | @@ -118,25 +118,29 @@ | ... | @@ -118,25 +118,29 @@ |
| 118 | <view class="popup-title">系统提示</view> | 118 | <view class="popup-title">系统提示</view> |
| 119 | <view class="popup-content"> | 119 | <view class="popup-content"> |
| 120 | <view class="popup-text">尊敬的用户,您好!</view> | 120 | <view class="popup-text">尊敬的用户,您好!</view> |
| 121 | <view class="popup-text">在开始注册团体会员前,请您提前准备好以下材料,以便顺利完成申请:</view> | 121 | <view class="popup-text">开始注册单位会员前,请提前准备以下材料(建议拍照或扫描,确保文字清晰、无遮挡):</view> |
| 122 | <view class="popup-item"> | 122 | <view class="popup-item"> |
| 123 | <text class="popup-num ml10">1.</text> | 123 | <text class="popup-num ml10">1.</text> |
| 124 | 单位营业执照 | 124 | 单位营业执照 |
| 125 | </view> | 125 | </view> |
| 126 | <view class="popup-desc">请提供清晰的营业执照原件照片或扫描件(加盖公章更佳)</view> | 126 | <view class="popup-desc">原件照片或扫描件(加盖公章更佳)</view> |
| 127 | <view class="popup-item"> | 127 | <view class="popup-item"> |
| 128 | <text class="popup-tip">!</text> | 128 | <text class="popup-tip">!</text> |
| 129 | <text class="popup-num"> 2.</text> | 129 | <text class="popup-num"> 2.</text> |
| 130 | 法人身份证正反面照片 | 130 | 法人身份证 |
| 131 | </view> | 131 | </view> |
| 132 | <view class="popup-desc">请分别上传身份证正面及反面清晰照片</view> | 132 | <view class="popup-desc">正、反面清晰照片(信息完整、无模糊)</view> |
| 133 | <view class="popup-desc">确保信息完整、无遮挡、无模糊</view> | 133 | <!-- <view class="popup-desc">确保信息完整、无遮挡、无模糊</view> --> |
| 134 | <view class="popup-item"> | 134 | <view class="popup-item"> |
| 135 | <text class="popup-num ml10">3.</text> | 135 | <text class="popup-num ml10">3.</text> |
| 136 | 机构照片 | 136 | 机构照片 |
| 137 | </view> | 137 | </view> |
| 138 | <view class="popup-desc">请提供体现单位实际经营或办公环境的照片1-2张</view> | 138 | <view class="popup-desc">1–2张能体现单位真实经营或办公环境的照片,例如:门头、办公场所、活动场地等</view> |
| 139 | <view class="popup-desc">如门头、办公场所、活动场地等(能展示机构真实存在即可)</view> | 139 | <!-- <view class="popup-desc">如门头、办公场所、活动场地等(能展示机构真实存在即可)</view> --> |
| 140 | <view class="popup-text"> | ||
| 141 | <!-- <text class="popup-num ml10">3.</text> --> | ||
| 142 | 感谢您的配合,祝您注册顺利! | ||
| 143 | </view> | ||
| 140 | </view> | 144 | </view> |
| 141 | <view class="popup-btns"> | 145 | <view class="popup-btns"> |
| 142 | <view class="popup-btn cancel" @click="closeRegisterPopup">取消</view> | 146 | <view class="popup-btn cancel" @click="closeRegisterPopup">取消</view> |
| ... | @@ -151,7 +155,7 @@ | ... | @@ -151,7 +155,7 @@ |
| 151 | import {onLoad, onReady} from '@dcloudio/uni-app'; | 155 | import {onLoad, onReady} from '@dcloudio/uni-app'; |
| 152 | import {ref, nextTick} from 'vue' | 156 | import {ref, nextTick} from 'vue' |
| 153 | import config from '@/config.js' | 157 | import config from '@/config.js' |
| 154 | import {getCodeImg, getSmsCodeImg, pcLogin, loginByPhone} from '@/common/login.js' | 158 | import {getCodeImg, getSmsCodeImg, pcLogin, loginByPhone, getInfo} from '@/common/login.js' |
| 155 | 159 | ||
| 156 | const isActive = ref(0) | 160 | const isActive = ref(0) |
| 157 | const agree = ref(false) | 161 | const agree = ref(false) |
| ... | @@ -182,6 +186,14 @@ const countDown = ref({ | ... | @@ -182,6 +186,14 @@ const countDown = ref({ |
| 182 | 186 | ||
| 183 | const app = getApp() | 187 | const app = getApp() |
| 184 | 188 | ||
| 189 | function goHomeAfterLogin() { | ||
| 190 | const deptType = app.globalData.deptType | ||
| 191 | const userType = app.globalData.userType | ||
| 192 | uni.reLaunch({ | ||
| 193 | url: (deptType == 6 || deptType == '6' || userType == '4') ? '/pages/index/daoGuanPerson' : '/pages/index/home' | ||
| 194 | }) | ||
| 195 | } | ||
| 196 | |||
| 185 | onLoad(() => { | 197 | onLoad(() => { |
| 186 | getCode() | 198 | getCode() |
| 187 | if (uni.showShareMenu) { | 199 | if (uni.showShareMenu) { |
| ... | @@ -220,9 +232,12 @@ function login() { | ... | @@ -220,9 +232,12 @@ function login() { |
| 220 | } | 232 | } |
| 221 | if (loading.value) return; | 233 | if (loading.value) return; |
| 222 | loading.value = true | 234 | loading.value = true |
| 223 | pcLogin(form.value).then((res) => { | 235 | pcLogin(form.value).then(() => { |
| 224 | app.globalData.isLogin = true | 236 | app.globalData.isLogin = true |
| 225 | uni.redirectTo({url: '/pages/index/home'}) | 237 | goHomeAfterLogin() |
| 238 | }).catch((err) => { | ||
| 239 | console.error('登录失败:', err) | ||
| 240 | uni.showToast({title: '登录失败', icon: 'none'}) | ||
| 226 | }).finally(() => { | 241 | }).finally(() => { |
| 227 | loading.value = false | 242 | loading.value = false |
| 228 | }) | 243 | }) |
| ... | @@ -244,9 +259,8 @@ function login() { | ... | @@ -244,9 +259,8 @@ function login() { |
| 244 | loading.value = true | 259 | loading.value = true |
| 245 | loginByPhone(form2.value.telNo, form2.value.code) | 260 | loginByPhone(form2.value.telNo, form2.value.code) |
| 246 | .then(() => { | 261 | .then(() => { |
| 247 | loading.value = false | ||
| 248 | app.globalData.isLogin = true | 262 | app.globalData.isLogin = true |
| 249 | uni.redirectTo({url: '/pages/index/home'}) | 263 | goHomeAfterLogin() |
| 250 | }).finally(() => { | 264 | }).finally(() => { |
| 251 | loading.value = false | 265 | loading.value = false |
| 252 | }) | 266 | }) | ... | ... |
| ... | @@ -22,7 +22,7 @@ | ... | @@ -22,7 +22,7 @@ |
| 22 | <!-- 温馨提示 --> | 22 | <!-- 温馨提示 --> |
| 23 | <view v-if="form.selfSelect == '1'" class="tip-box"> | 23 | <view v-if="form.selfSelect == '1'" class="tip-box"> |
| 24 | <text class="tip-text">温馨提示: | 24 | <text class="tip-text">温馨提示: |
| 25 | 您可以自行录入考官信息,如果暂时没有合适的考官,也可以选择由省跆协指派(支持多选)进行考点申报,同时请尽快完成考点考官的认证。 | 25 | 您可以自行录入考官信息,如果暂时没有考官,可以选择由省跆协指派进行考点申报,请尽快完成考点考官的认证。 |
| 26 | </text> | 26 | </text> |
| 27 | </view> | 27 | </view> |
| 28 | 28 | ... | ... |
| ... | @@ -48,8 +48,12 @@ | ... | @@ -48,8 +48,12 @@ |
| 48 | 48 | ||
| 49 | <!-- 金额说明 --> | 49 | <!-- 金额说明 --> |
| 50 | <view class="card notice-card"> | 50 | <view class="card notice-card"> |
| 51 | <view class="notice-line">1. 请通过网上银行(网银)或银行柜台或手机银行向以下账号划转款项。</view> | 51 | <view class="danger-title"> |
| 52 | <view class="notice-line">2. 转账金额与订单金额必须保持一致,不得多转、少转。</view> | 52 | <text>请使用认证机构下的账号进行对公转账。</text> |
| 53 | </view> | ||
| 54 | <view class="notice-line">1. 本订单将为您保留7天,请您及时支付;逾期未支付,订单将自动取消。</view> | ||
| 55 | <view class="notice-line">2. 请通过网上银行(网银)或银行柜台或手机银行向以下账号划转款项。</view> | ||
| 56 | <view class="notice-line">3. 转账金额与订单金额必须保持一致,不得多转、少转。</view> | ||
| 53 | </view> | 57 | </view> |
| 54 | 58 | ||
| 55 | <!-- 温馨提示 --> | 59 | <!-- 温馨提示 --> |
| ... | @@ -293,6 +297,14 @@ function handelClose() { | ... | @@ -293,6 +297,14 @@ function handelClose() { |
| 293 | } | 297 | } |
| 294 | } | 298 | } |
| 295 | } | 299 | } |
| 300 | .danger-title{ | ||
| 301 | display: flex; | ||
| 302 | align-items: center; | ||
| 303 | font-size: 28rpx; | ||
| 304 | color: #F56C6C; | ||
| 305 | font-weight: 600; | ||
| 306 | margin-bottom: 16rpx; | ||
| 307 | } | ||
| 296 | 308 | ||
| 297 | /* 温馨提示 */ | 309 | /* 温馨提示 */ |
| 298 | .warning-card { | 310 | .warning-card { | ... | ... |
| ... | @@ -20,6 +20,56 @@ | ... | @@ -20,6 +20,56 @@ |
| 20 | } | 20 | } |
| 21 | }, | 21 | }, |
| 22 | { | 22 | { |
| 23 | "path": "pages/index/daoGuanPerson", | ||
| 24 | "style": { | ||
| 25 | "navigationBarTitleText": "人员", | ||
| 26 | "backgroundColor": "#ffffff", | ||
| 27 | "navigationStyle": "custom", | ||
| 28 | "navigationBarTextStyle": "black", | ||
| 29 | "navigationBarBackgroundColor": "#ffffff" | ||
| 30 | } | ||
| 31 | }, | ||
| 32 | { | ||
| 33 | "path": "pages/index/daoGuanLevel", | ||
| 34 | "style": { | ||
| 35 | "navigationBarTitleText": "级位", | ||
| 36 | "backgroundColor": "#ffffff", | ||
| 37 | "navigationStyle": "custom", | ||
| 38 | "navigationBarTextStyle": "black", | ||
| 39 | "navigationBarBackgroundColor": "#ffffff" | ||
| 40 | } | ||
| 41 | }, | ||
| 42 | { | ||
| 43 | "path": "pages/index/daoGuanOrder", | ||
| 44 | "style": { | ||
| 45 | "navigationBarTitleText": "订单", | ||
| 46 | "backgroundColor": "#ffffff", | ||
| 47 | "navigationStyle": "custom", | ||
| 48 | "navigationBarTextStyle": "black", | ||
| 49 | "navigationBarBackgroundColor": "#ffffff" | ||
| 50 | } | ||
| 51 | }, | ||
| 52 | { | ||
| 53 | "path": "pages/index/daoGuanNotice", | ||
| 54 | "style": { | ||
| 55 | "navigationBarTitleText": "通知", | ||
| 56 | "backgroundColor": "#ffffff", | ||
| 57 | "navigationStyle": "custom", | ||
| 58 | "navigationBarTextStyle": "black", | ||
| 59 | "navigationBarBackgroundColor": "#ffffff" | ||
| 60 | } | ||
| 61 | }, | ||
| 62 | { | ||
| 63 | "path": "pages/index/daoGuanMy", | ||
| 64 | "style": { | ||
| 65 | "navigationBarTitleText": "我的", | ||
| 66 | "backgroundColor": "#ffffff", | ||
| 67 | "navigationStyle": "custom", | ||
| 68 | "navigationBarTextStyle": "black", | ||
| 69 | "navigationBarBackgroundColor": "#ffffff" | ||
| 70 | } | ||
| 71 | }, | ||
| 72 | { | ||
| 23 | "path": "pages/webview/webview", | 73 | "path": "pages/webview/webview", |
| 24 | "style": { | 74 | "style": { |
| 25 | "navigationBarTitleText": "中国跆拳道协会", | 75 | "navigationBarTitleText": "中国跆拳道协会", |
| ... | @@ -189,6 +239,7 @@ | ... | @@ -189,6 +239,7 @@ |
| 189 | } | 239 | } |
| 190 | } | 240 | } |
| 191 | ], | 241 | ], |
| 242 | |||
| 192 | "globalStyle": { | 243 | "globalStyle": { |
| 193 | "navigationStyle": "default", | 244 | "navigationStyle": "default", |
| 194 | "navigationBarTextStyle": "black", | 245 | "navigationBarTextStyle": "black", | ... | ... |
pages/index/daoGuanLevel.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="level-page"> | ||
| 3 | <view class="hero"> | ||
| 4 | <image class="hero-bg" :src="config.baseUrl_api + '/fs/static/img/top.png'" mode="aspectFill"></image> | ||
| 5 | <view class="hero-brand"> | ||
| 6 | <view class="brand-cn">中国跆拳道协会</view> | ||
| 7 | <view class="brand-en">CHINESE TAEKWONDO ASSOCIATION</view> | ||
| 8 | </view> | ||
| 9 | </view> | ||
| 10 | |||
| 11 | <view class="content-panel"> | ||
| 12 | <image class="panel-bg" :src="config.baseUrl_api + '/fs/static/img/red_bg2.png'" mode="scaleToFill"></image> | ||
| 13 | <view class="panel-content"> | ||
| 14 | <view class="section-title"> | ||
| 15 | <view class="title-cn">级位考试</view> | ||
| 16 | <view style="width:50rpx;height:8rpx;background:#C30D23;margin-top:20rpx;"></view> | ||
| 17 | <view class="title-en">LEVEL EXAM</view> | ||
| 18 | </view> | ||
| 19 | |||
| 20 | <view class="level-grid"> | ||
| 21 | <image class="level-card" :src="config.baseUrl_api + '/fs/static/img/jw_btn01.png'" mode="aspectFit" @click="goPath('/level/addApply')"></image> | ||
| 22 | <image class="level-card" :src="config.baseUrl_api + '/fs/static/img/jw_btn02.png'" mode="aspectFit" @click="goPath('/personalVip/addChangeLevel')"></image> | ||
| 23 | <image class="level-card" :src="config.baseUrl_api + '/fs/static/img/jw_btn03.png'" mode="aspectFit" @click="goPath('/level/apply')"></image> | ||
| 24 | <image class="level-card" :src="config.baseUrl_api + '/fs/static/img/jw_btn04.png'" mode="aspectFit" @click="goPath('/personalVip/changeLevel')"></image> | ||
| 25 | </view> | ||
| 26 | </view> | ||
| 27 | </view> | ||
| 28 | |||
| 29 | <dao-guan-tab-bar :currentIndex="3" @switch="onTabSwitch" /> | ||
| 30 | </view> | ||
| 31 | </template> | ||
| 32 | |||
| 33 | <script setup> | ||
| 34 | import config from '@/config.js' | ||
| 35 | import DaoGuanTabBar from '@/components/dao-guan-tab-bar.vue' | ||
| 36 | |||
| 37 | const onTabSwitch = () => { | ||
| 38 | // tab switch handled by component | ||
| 39 | } | ||
| 40 | |||
| 41 | const goPath = (url) => { | ||
| 42 | uni.navigateTo({ url }) | ||
| 43 | } | ||
| 44 | </script> | ||
| 45 | |||
| 46 | <style lang="scss" scoped> | ||
| 47 | .level-page { | ||
| 48 | position: relative; | ||
| 49 | min-height: 100vh; | ||
| 50 | overflow-x: hidden; | ||
| 51 | background: #ededf0; | ||
| 52 | overflow-y: hidden; | ||
| 53 | // padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); | ||
| 54 | box-sizing: border-box; | ||
| 55 | } | ||
| 56 | |||
| 57 | .hero { | ||
| 58 | position: relative; | ||
| 59 | height: 1060rpx; | ||
| 60 | overflow: hidden; | ||
| 61 | z-index: 1; | ||
| 62 | } | ||
| 63 | |||
| 64 | .hero-bg { | ||
| 65 | position: absolute; | ||
| 66 | left: 0; | ||
| 67 | top: -116px; | ||
| 68 | width: 100%; | ||
| 69 | height: 100%; | ||
| 70 | } | ||
| 71 | |||
| 72 | .hero-brand { | ||
| 73 | position: relative; | ||
| 74 | z-index: 1; | ||
| 75 | padding: calc(env(safe-area-inset-top) + 170rpx) 44rpx 0; | ||
| 76 | color: #fff; | ||
| 77 | } | ||
| 78 | |||
| 79 | .brand-cn { | ||
| 80 | font-size: 38rpx; | ||
| 81 | letter-spacing: 2rpx; | ||
| 82 | } | ||
| 83 | |||
| 84 | .brand-en { | ||
| 85 | margin-top: 8rpx; | ||
| 86 | color: rgba(255, 255, 255, 0.62); | ||
| 87 | font-size: 16rpx; | ||
| 88 | } | ||
| 89 | |||
| 90 | .content-panel { | ||
| 91 | position: relative; | ||
| 92 | z-index: 3; | ||
| 93 | min-height: 760rpx; | ||
| 94 | margin-top: -300rpx; | ||
| 95 | overflow: visible; | ||
| 96 | } | ||
| 97 | |||
| 98 | .panel-bg { | ||
| 99 | position: absolute; | ||
| 100 | left: 0; | ||
| 101 | top: -674rpx; | ||
| 102 | z-index:10; | ||
| 103 | width: 100%; | ||
| 104 | height: 1700rpx; | ||
| 105 | } | ||
| 106 | |||
| 107 | .panel-content { | ||
| 108 | position: relative; | ||
| 109 | z-index: 12; | ||
| 110 | padding: 0rpx 46rpx 40rpx; | ||
| 111 | } | ||
| 112 | |||
| 113 | .section-title { | ||
| 114 | margin-bottom: 30rpx; | ||
| 115 | } | ||
| 116 | |||
| 117 | .title-cn { | ||
| 118 | color: #2a2a2a; | ||
| 119 | font-size: 58rpx; | ||
| 120 | line-height: 1; | ||
| 121 | } | ||
| 122 | |||
| 123 | .title-en { | ||
| 124 | margin-top: 12rpx; | ||
| 125 | color: #9a9a9a; | ||
| 126 | font-size: 24rpx; | ||
| 127 | font-weight: 700; | ||
| 128 | } | ||
| 129 | |||
| 130 | .level-grid { | ||
| 131 | display: grid; | ||
| 132 | grid-template-columns: repeat(2, 1fr); | ||
| 133 | gap: 14rpx 14rpx; | ||
| 134 | } | ||
| 135 | |||
| 136 | .level-card { | ||
| 137 | width: 100%; | ||
| 138 | height: 236rpx; | ||
| 139 | border-radius: 10rpx; | ||
| 140 | } | ||
| 141 | </style> |
pages/index/daoGuanMy.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="page dao-my-page"> | ||
| 3 | <image class="page-red-bg" :src="config.baseUrl_api + '/fs/static/img/red_bg.png'" mode="scaleToFill"></image> | ||
| 4 | <view class="profile-hero"> | ||
| 5 | <view class="hero-content"> | ||
| 6 | <view class="profile-row"> | ||
| 7 | <view class="avatar-wrap"> | ||
| 8 | <image v-if="state.user.avatar" :src="state.user.avatar" mode="aspectFill"/> | ||
| 9 | <image v-else :src="config.baseUrl_api + '/fs/static/nodata.png'" mode="aspectFill"/> | ||
| 10 | </view> | ||
| 11 | <!-- <view class="profile-main"> | ||
| 12 | <view class="name-row"> | ||
| 13 | <view class="dept-name">{{ state.user?.dept?.deptName || deptInfo.deptName || memberInfo.name || '--' }}</view> | ||
| 14 | <view class="member-badge"> | ||
| 15 | <text class="badge-star">◆</text> | ||
| 16 | <text>金牌会员</text> | ||
| 17 | </view> | ||
| 18 | </view> | ||
| 19 | <view class="id-row"> | ||
| 20 | <text>ID:{{ memberInfo.menCode || memberInfo.memberCode || memberInfo.memberNo || state.user?.userName || '--' }}</text> | ||
| 21 | <text class="join-days">您已加入{{ joinDays }}天</text> | ||
| 22 | </view> | ||
| 23 | </view> --> | ||
| 24 | </view> | ||
| 25 | <view class="motto">每一次的成功都不是偶然,是千锤百炼,永不放弃的结果。{{ state.user?.dept?.deptName || '龙威天成跆拳道馆' }},以专业铸就辉煌!</view> | ||
| 26 | <view class="edit-btn" @click="goPath('/myCenter/teamInfo')">修改资料</view> | ||
| 27 | </view> | ||
| 28 | </view> | ||
| 29 | |||
| 30 | <view class="menu-panel"> | ||
| 31 | <image class="menu-bg" :src="config.baseUrl_api + '/fs/static/img/red_bg2.png'" mode="scaleToFill"></image> | ||
| 32 | <view class="menu-item" @click="goPath('/myCenter/teamInfo')"> | ||
| 33 | <view class="menu-left"> | ||
| 34 | <image class="menu-icon" :src="config.baseUrl_api + '/fs/static/img/user01.png'" mode="aspectFit"></image> | ||
| 35 | <text>单位信息</text> | ||
| 36 | </view> | ||
| 37 | <text class="arrow">></text> | ||
| 38 | </view> | ||
| 39 | |||
| 40 | <view class="menu-item" @click="goPath('/myCenter/auth')"> | ||
| 41 | <view class="menu-left"> | ||
| 42 | <image class="menu-icon" :src="config.baseUrl_api + '/fs/static/img/user02.png'" mode="aspectFit"></image> | ||
| 43 | <text>会员认证</text> | ||
| 44 | </view> | ||
| 45 | <text class="arrow">></text> | ||
| 46 | </view> | ||
| 47 | |||
| 48 | <view class="menu-item" @click="goPath('/myCenter/safe')"> | ||
| 49 | <view class="menu-left"> | ||
| 50 | <image class="menu-icon" :src="config.baseUrl_api + '/fs/static/img/user03.png'" mode="aspectFit"></image> | ||
| 51 | <text>账号安全</text> | ||
| 52 | </view> | ||
| 53 | <text class="arrow">></text> | ||
| 54 | </view> | ||
| 55 | </view> | ||
| 56 | |||
| 57 | <view class="logout-area"> | ||
| 58 | <button class="logout-btn" @click="loginOut">退出登录</button> | ||
| 59 | </view> | ||
| 60 | |||
| 61 | <!-- 底部导航 --> | ||
| 62 | <dao-guan-tab-bar :currentIndex="4" @switch="onTabSwitch" /> | ||
| 63 | </view> | ||
| 64 | </template> | ||
| 65 | |||
| 66 | <script setup> | ||
| 67 | import * as api from '@/common/api.js'; | ||
| 68 | import * as loginServer from '@/common/login.js'; | ||
| 69 | import config from '@/config.js' | ||
| 70 | import { | ||
| 71 | onLoad, | ||
| 72 | onShow, | ||
| 73 | onReady, | ||
| 74 | onPullDownRefresh | ||
| 75 | } from '@dcloudio/uni-app'; | ||
| 76 | import { | ||
| 77 | ref, reactive, computed, | ||
| 78 | getCurrentInstance | ||
| 79 | } from 'vue'; | ||
| 80 | import DaoGuanTabBar from '@/components/dao-guan-tab-bar.vue' | ||
| 81 | |||
| 82 | |||
| 83 | const { | ||
| 84 | proxy | ||
| 85 | } = getCurrentInstance() | ||
| 86 | const app = getApp(); | ||
| 87 | const userType = ref('1') | ||
| 88 | const memberInfo = ref({}) | ||
| 89 | const deptInfo = ref({}) | ||
| 90 | let proId; | ||
| 91 | const svId = ref(null); | ||
| 92 | const numData = ref({}); | ||
| 93 | |||
| 94 | const messageList = ref([]) | ||
| 95 | const state = reactive({ | ||
| 96 | user: {}, | ||
| 97 | roleGroup: {}, | ||
| 98 | postGroup: {} | ||
| 99 | }) | ||
| 100 | |||
| 101 | const joinDays = computed(() => { | ||
| 102 | const value = memberInfo.value.createTime || memberInfo.value.joinTime || memberInfo.value.createDate | ||
| 103 | if (!value) return '--' | ||
| 104 | const start = new Date(String(value).replace(/-/g, '/')).getTime() | ||
| 105 | if (!start) return '--' | ||
| 106 | const days = Math.floor((Date.now() - start) / (24 * 60 * 60 * 1000)) + 1 | ||
| 107 | return days > 0 ? days : 1 | ||
| 108 | }) | ||
| 109 | onShow(() => { | ||
| 110 | if (app.globalData.isLogin) { | ||
| 111 | init() | ||
| 112 | } else { | ||
| 113 | app.firstLoadCallback = () => { | ||
| 114 | init() | ||
| 115 | }; | ||
| 116 | } | ||
| 117 | }) | ||
| 118 | onLoad(option => { | ||
| 119 | if (option.scene) { | ||
| 120 | proId = decodeURIComponent(option.scene); | ||
| 121 | } else { | ||
| 122 | proId = option.proId; | ||
| 123 | } | ||
| 124 | if (uni.showShareMenu) { | ||
| 125 | uni.showShareMenu({ | ||
| 126 | withShareTicket: true, | ||
| 127 | menus: ['shareAppMessage', 'shareTimeline'] | ||
| 128 | }); | ||
| 129 | } | ||
| 130 | }); | ||
| 131 | |||
| 132 | function loginOut() { | ||
| 133 | uni.showModal({ | ||
| 134 | content: `确认退出吗?`, | ||
| 135 | success: function (res) { | ||
| 136 | if (res.confirm) { | ||
| 137 | loginServer.logout().finally(() => { | ||
| 138 | let path = '/login/login'; | ||
| 139 | uni.reLaunch({ | ||
| 140 | url: path | ||
| 141 | }); | ||
| 142 | }) | ||
| 143 | } | ||
| 144 | } | ||
| 145 | }) | ||
| 146 | } | ||
| 147 | |||
| 148 | function getUser() { | ||
| 149 | api.getUserProfile().then((response) => { | ||
| 150 | state.user = response.data.user | ||
| 151 | if (state.user.avatar && state.user.avatar.indexOf('http') == -1) { | ||
| 152 | state.user.avatar = config.baseUrl_api + state.user.avatar | ||
| 153 | } | ||
| 154 | state.roleGroup = response.data.roleGroup | ||
| 155 | state.postGroup = response.data.postGroup | ||
| 156 | uni.hideLoading(); | ||
| 157 | }) | ||
| 158 | } | ||
| 159 | |||
| 160 | function init() { | ||
| 161 | uni.showLoading({ | ||
| 162 | title: '加载中' | ||
| 163 | }); | ||
| 164 | getUser() | ||
| 165 | loginServer.getMyOwnMemberInfo().then(res => { | ||
| 166 | userType.value = app.globalData.userType | ||
| 167 | memberInfo.value = app.globalData.memberInfo | ||
| 168 | deptInfo.value = app.globalData.dept || {} | ||
| 169 | uni.hideLoading(); | ||
| 170 | }) | ||
| 171 | } | ||
| 172 | |||
| 173 | function goPath(url) { | ||
| 174 | uni.navigateTo({ | ||
| 175 | url: url | ||
| 176 | }) | ||
| 177 | } | ||
| 178 | |||
| 179 | function onTabSwitch(index, url) { | ||
| 180 | // tab switch handled by component | ||
| 181 | } | ||
| 182 | |||
| 183 | </script> | ||
| 184 | <style lang="scss" scoped> | ||
| 185 | .dao-my-page { | ||
| 186 | position: relative; | ||
| 187 | min-height: 100vh; | ||
| 188 | width: 100vw; | ||
| 189 | overflow-x: hidden; | ||
| 190 | box-sizing: border-box; | ||
| 191 | padding-bottom: calc(210rpx + env(safe-area-inset-bottom)); | ||
| 192 | background: #ededf0; | ||
| 193 | } | ||
| 194 | |||
| 195 | .page-red-bg { | ||
| 196 | position: absolute; | ||
| 197 | left: 0; | ||
| 198 | top: 0; | ||
| 199 | z-index: 0; | ||
| 200 | width: 100%; | ||
| 201 | height: 720rpx; | ||
| 202 | } | ||
| 203 | |||
| 204 | .profile-hero { | ||
| 205 | position: relative; | ||
| 206 | z-index: 1; | ||
| 207 | min-height: 460rpx; | ||
| 208 | } | ||
| 209 | |||
| 210 | .hero-content { | ||
| 211 | position: relative; | ||
| 212 | z-index: 2; | ||
| 213 | padding: calc(env(safe-area-inset-top) + 126rpx) 48rpx 0; | ||
| 214 | color: #fff; | ||
| 215 | } | ||
| 216 | |||
| 217 | .profile-row { | ||
| 218 | display: flex; | ||
| 219 | align-items: center; | ||
| 220 | } | ||
| 221 | |||
| 222 | .avatar-wrap { | ||
| 223 | width: 132rpx; | ||
| 224 | height: 132rpx; | ||
| 225 | padding: 6rpx; | ||
| 226 | flex: 0 0 132rpx; | ||
| 227 | overflow: hidden; | ||
| 228 | border-radius: 50%; | ||
| 229 | background: #fff; | ||
| 230 | box-shadow: 0 8rpx 26rpx rgba(65, 0, 0, 0.28); | ||
| 231 | |||
| 232 | image { | ||
| 233 | width: 100%; | ||
| 234 | height: 100%; | ||
| 235 | border-radius: 50%; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | .profile-main { | ||
| 240 | flex: 1; | ||
| 241 | min-width: 0; | ||
| 242 | margin-left: 26rpx; | ||
| 243 | } | ||
| 244 | |||
| 245 | .name-row, | ||
| 246 | .id-row { | ||
| 247 | display: flex; | ||
| 248 | align-items: center; | ||
| 249 | justify-content: space-between; | ||
| 250 | } | ||
| 251 | |||
| 252 | .dept-name { | ||
| 253 | max-width: 330rpx; | ||
| 254 | overflow: hidden; | ||
| 255 | white-space: nowrap; | ||
| 256 | text-overflow: ellipsis; | ||
| 257 | font-size: 34rpx; | ||
| 258 | font-weight: 700; | ||
| 259 | } | ||
| 260 | |||
| 261 | .member-badge { | ||
| 262 | display: flex; | ||
| 263 | align-items: center; | ||
| 264 | gap: 8rpx; | ||
| 265 | color: #dba12d; | ||
| 266 | font-size: 24rpx; | ||
| 267 | white-space: nowrap; | ||
| 268 | } | ||
| 269 | |||
| 270 | .badge-star { | ||
| 271 | color: #f7c342; | ||
| 272 | font-size: 24rpx; | ||
| 273 | } | ||
| 274 | |||
| 275 | .id-row { | ||
| 276 | margin-top: 12rpx; | ||
| 277 | color: rgba(255, 255, 255, 0.86); | ||
| 278 | font-size: 26rpx; | ||
| 279 | } | ||
| 280 | |||
| 281 | .join-days { | ||
| 282 | margin-left: 18rpx; | ||
| 283 | white-space: nowrap; | ||
| 284 | } | ||
| 285 | |||
| 286 | .motto { | ||
| 287 | margin-top: 52rpx; | ||
| 288 | color: rgba(255, 255, 255, 0.86); | ||
| 289 | font-size: 24rpx; | ||
| 290 | line-height: 1.75; | ||
| 291 | } | ||
| 292 | |||
| 293 | .edit-btn { | ||
| 294 | width: 168rpx; | ||
| 295 | height: 48rpx; | ||
| 296 | margin: 34rpx 0 0 auto; | ||
| 297 | border-radius: 6rpx; | ||
| 298 | background: #fff; | ||
| 299 | color: #333; | ||
| 300 | font-size: 24rpx; | ||
| 301 | line-height: 48rpx; | ||
| 302 | text-align: center; | ||
| 303 | } | ||
| 304 | |||
| 305 | .menu-panel { | ||
| 306 | position: relative; | ||
| 307 | z-index: 2; | ||
| 308 | min-height: 560rpx; | ||
| 309 | margin-top: -72rpx; | ||
| 310 | padding: 178rpx 48rpx 0; | ||
| 311 | overflow: hidden; | ||
| 312 | } | ||
| 313 | |||
| 314 | .menu-bg { | ||
| 315 | position: absolute; | ||
| 316 | left: 0; | ||
| 317 | top: -400rpx; | ||
| 318 | z-index: 0; | ||
| 319 | width: 100%; | ||
| 320 | height: 1400rpx; | ||
| 321 | } | ||
| 322 | |||
| 323 | .menu-item { | ||
| 324 | position: relative; | ||
| 325 | z-index: 1; | ||
| 326 | display: flex; | ||
| 327 | align-items: center; | ||
| 328 | justify-content: space-between; | ||
| 329 | height: 132rpx; | ||
| 330 | color: #111; | ||
| 331 | font-size: 31rpx; | ||
| 332 | font-weight: 700; | ||
| 333 | } | ||
| 334 | |||
| 335 | .menu-left { | ||
| 336 | display: flex; | ||
| 337 | align-items: center; | ||
| 338 | } | ||
| 339 | |||
| 340 | .menu-icon { | ||
| 341 | width: 38rpx; | ||
| 342 | height: 38rpx; | ||
| 343 | margin-right: 18rpx; | ||
| 344 | } | ||
| 345 | |||
| 346 | .arrow { | ||
| 347 | color: #111; | ||
| 348 | font-size: 42rpx; | ||
| 349 | font-weight: 400; | ||
| 350 | line-height: 1; | ||
| 351 | } | ||
| 352 | |||
| 353 | .logout-area { | ||
| 354 | position: fixed; | ||
| 355 | left: 0; | ||
| 356 | right: 0; | ||
| 357 | bottom: calc(124rpx + env(safe-area-inset-bottom)); | ||
| 358 | z-index: 9998; | ||
| 359 | padding: 16rpx 48rpx 18rpx; | ||
| 360 | background: transparent; | ||
| 361 | box-sizing: border-box; | ||
| 362 | } | ||
| 363 | |||
| 364 | .logout-btn { | ||
| 365 | height: 76rpx; | ||
| 366 | border-radius: 50rpx; | ||
| 367 | background: #ad181f; | ||
| 368 | color: #fff; | ||
| 369 | font-size: 28rpx; | ||
| 370 | line-height: 76rpx; | ||
| 371 | } | ||
| 372 | |||
| 373 | .logout-btn::after { | ||
| 374 | border: none; | ||
| 375 | } | ||
| 376 | </style> |
pages/index/daoGuanNotice.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="notice-page"> | ||
| 3 | <z-paging | ||
| 4 | ref="paging" | ||
| 5 | v-model="dataList" | ||
| 6 | class="notice-paging" | ||
| 7 | emptyViewImg="/static/nodata.png" | ||
| 8 | @query="queryList" | ||
| 9 | > | ||
| 10 | <template #top> | ||
| 11 | <view class="notice-hero"> | ||
| 12 | <view class="hero-title-row"> | ||
| 13 | <view> | ||
| 14 | <view class="hero-title">中国跆拳道协会</view> | ||
| 15 | <view class="hero-subtitle">CHINESE TAEKWONDO ASSOCIATION</view> | ||
| 16 | </view> | ||
| 17 | <view class="hero-page-title"> | ||
| 18 | <text>协会资讯</text> | ||
| 19 | <view class="title-line"></view> | ||
| 20 | </view> | ||
| 21 | </view> | ||
| 22 | |||
| 23 | <view class="search-bar"> | ||
| 24 | <uni-easyinput | ||
| 25 | v-model="query.keyword" | ||
| 26 | :input-border="false" | ||
| 27 | class="search-input" | ||
| 28 | placeholder="请输入公告标题" | ||
| 29 | placeholderStyle="font-size:28rpx;color:#999" | ||
| 30 | prefixIcon="search" | ||
| 31 | @confirm="handleSearch" | ||
| 32 | @clear="handleSearch" | ||
| 33 | /> | ||
| 34 | <view class="search-btn" @click="handleSearch">搜索</view> | ||
| 35 | </view> | ||
| 36 | </view> | ||
| 37 | |||
| 38 | <!-- <view class="notice-tabs"> | ||
| 39 | <view class="tab-item active">公告</view> | ||
| 40 | </view> --> | ||
| 41 | </template> | ||
| 42 | |||
| 43 | <view class="notice-list"> | ||
| 44 | <view v-for="item in dataList" :key="item.id || item.noteId" class="notice-item" @click="goDetail(item)"> | ||
| 45 | <view class="notice-title">{{ item.name || item.title || '--' }}</view> | ||
| 46 | <view v-if="item.introduction || item.remark || item.content" class="notice-summary"> | ||
| 47 | {{ item.introduction || item.remark || item.content }} | ||
| 48 | </view> | ||
| 49 | <image | ||
| 50 | v-if="getCover(item)" | ||
| 51 | :src="getCover(item)" | ||
| 52 | class="notice-cover" | ||
| 53 | mode="aspectFill" | ||
| 54 | /> | ||
| 55 | <view class="notice-meta"> | ||
| 56 | <text>{{ formatDate(item.belongTime || item.createTime || item.publishTime) }}</text> | ||
| 57 | <!-- <view class="meta-right"> | ||
| 58 | <text class="heart">♡</text> | ||
| 59 | <text>{{ item.readNum || item.views || item.likeNum || 0 }}</text> | ||
| 60 | <text class="more">...</text> | ||
| 61 | </view> --> | ||
| 62 | </view> | ||
| 63 | </view> | ||
| 64 | </view> | ||
| 65 | </z-paging> | ||
| 66 | |||
| 67 | <dao-guan-tab-bar :currentIndex="2" @switch="onTabSwitch" /> | ||
| 68 | </view> | ||
| 69 | </template> | ||
| 70 | |||
| 71 | <script setup> | ||
| 72 | import { ref, reactive } from 'vue' | ||
| 73 | import * as api from '@/common/api.js' | ||
| 74 | import dayjs from 'dayjs' | ||
| 75 | import DaoGuanTabBar from '@/components/dao-guan-tab-bar.vue' | ||
| 76 | |||
| 77 | const dataList = ref([]) | ||
| 78 | const paging = ref(null) | ||
| 79 | const query = reactive({ | ||
| 80 | keyword: '' | ||
| 81 | }) | ||
| 82 | |||
| 83 | const queryList = (pageNum, pageSize) => { | ||
| 84 | api.notice({ | ||
| 85 | pageNum, | ||
| 86 | pageSize, | ||
| 87 | name: query.keyword | ||
| 88 | }).then(res => { | ||
| 89 | paging.value?.complete(res.rows || []) | ||
| 90 | }).catch(() => { | ||
| 91 | paging.value?.complete(false) | ||
| 92 | }) | ||
| 93 | } | ||
| 94 | |||
| 95 | const handleSearch = () => { | ||
| 96 | paging.value?.reload() | ||
| 97 | } | ||
| 98 | |||
| 99 | const getCover = (item) => { | ||
| 100 | return item.coverUrl || item.cover || item.picUrl || item.imageUrl || item.imgUrl || '' | ||
| 101 | } | ||
| 102 | |||
| 103 | const formatDate = (value) => { | ||
| 104 | if (!value) return '' | ||
| 105 | return dayjs(value).format('YYYY-MM-DD') | ||
| 106 | } | ||
| 107 | |||
| 108 | const goDetail = (item) => { | ||
| 109 | uni.navigateTo({ | ||
| 110 | url: `/pages/index/newsDetail?noteId=${item.noteId}` | ||
| 111 | }) | ||
| 112 | } | ||
| 113 | |||
| 114 | const onTabSwitch = () => { | ||
| 115 | // tab switch handled by component | ||
| 116 | } | ||
| 117 | </script> | ||
| 118 | |||
| 119 | <style lang="scss" scoped> | ||
| 120 | .notice-page { | ||
| 121 | position: relative; | ||
| 122 | min-height: 100vh; | ||
| 123 | background: #ededf0; | ||
| 124 | box-sizing: border-box; | ||
| 125 | } | ||
| 126 | |||
| 127 | .notice-hero { | ||
| 128 | padding: calc(env(safe-area-inset-top) + 88rpx) 40rpx 34rpx; | ||
| 129 | background: linear-gradient(135deg, #b00005 0%, #760000 100%); | ||
| 130 | color: #fff; | ||
| 131 | } | ||
| 132 | |||
| 133 | .hero-title-row { | ||
| 134 | display: flex; | ||
| 135 | justify-content: space-between; | ||
| 136 | align-items: flex-end; | ||
| 137 | margin-bottom: 42rpx; | ||
| 138 | } | ||
| 139 | |||
| 140 | .hero-title { | ||
| 141 | font-size: 38rpx; | ||
| 142 | letter-spacing: 2rpx; | ||
| 143 | } | ||
| 144 | |||
| 145 | .hero-subtitle { | ||
| 146 | margin-top: 8rpx; | ||
| 147 | color: rgba(255, 255, 255, 0.6); | ||
| 148 | font-size: 16rpx; | ||
| 149 | } | ||
| 150 | |||
| 151 | .hero-page-title { | ||
| 152 | color: #f4b536; | ||
| 153 | font-size: 36rpx; | ||
| 154 | font-weight: 500; | ||
| 155 | text-align: right; | ||
| 156 | } | ||
| 157 | |||
| 158 | .title-line { | ||
| 159 | width: 54rpx; | ||
| 160 | height: 6rpx; | ||
| 161 | margin: 14rpx 0 0 auto; | ||
| 162 | border-radius: 10rpx; | ||
| 163 | background: #f4b536; | ||
| 164 | } | ||
| 165 | |||
| 166 | .search-bar { | ||
| 167 | display: flex; | ||
| 168 | align-items: center; | ||
| 169 | height: 64rpx; | ||
| 170 | border-radius: 34rpx; | ||
| 171 | background: #fff; | ||
| 172 | overflow: hidden; | ||
| 173 | } | ||
| 174 | |||
| 175 | .search-input { | ||
| 176 | flex: 1; | ||
| 177 | |||
| 178 | :deep(.uni-easyinput__content) { | ||
| 179 | height: 64rpx; | ||
| 180 | padding: 0 18rpx 0 28rpx; | ||
| 181 | border-radius: 34rpx; | ||
| 182 | background: #fff; | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | .search-btn { | ||
| 187 | width: 88rpx; | ||
| 188 | height: 52rpx; | ||
| 189 | margin-right: 6rpx; | ||
| 190 | border-radius: 28rpx; | ||
| 191 | background: #c91c34; | ||
| 192 | color: #fff; | ||
| 193 | font-size: 24rpx; | ||
| 194 | font-weight: 700; | ||
| 195 | line-height: 52rpx; | ||
| 196 | text-align: center; | ||
| 197 | } | ||
| 198 | |||
| 199 | .notice-tabs { | ||
| 200 | display: flex; | ||
| 201 | align-items: center; | ||
| 202 | padding: 24rpx 40rpx 8rpx; | ||
| 203 | } | ||
| 204 | |||
| 205 | .tab-item { | ||
| 206 | position: relative; | ||
| 207 | margin-right: 54rpx; | ||
| 208 | padding-bottom: 14rpx; | ||
| 209 | color: #555; | ||
| 210 | font-size: 30rpx; | ||
| 211 | } | ||
| 212 | |||
| 213 | .tab-item.active { | ||
| 214 | color: #c30d23; | ||
| 215 | font-weight: 700; | ||
| 216 | } | ||
| 217 | |||
| 218 | .tab-item.active::after { | ||
| 219 | content: ''; | ||
| 220 | position: absolute; | ||
| 221 | left: 50%; | ||
| 222 | bottom: 0; | ||
| 223 | width: 52rpx; | ||
| 224 | height: 4rpx; | ||
| 225 | border-radius: 4rpx; | ||
| 226 | background: #c30d23; | ||
| 227 | transform: translateX(-50%); | ||
| 228 | } | ||
| 229 | |||
| 230 | .notice-paging { | ||
| 231 | height: 100vh; | ||
| 232 | background: #ededf0; | ||
| 233 | } | ||
| 234 | |||
| 235 | .notice-list { | ||
| 236 | padding: 0 10rpx calc(160rpx + env(safe-area-inset-bottom)); | ||
| 237 | } | ||
| 238 | |||
| 239 | .notice-item { | ||
| 240 | margin-bottom: 34rpx; | ||
| 241 | background: #fff; | ||
| 242 | padding: 24rpx; | ||
| 243 | border-radius: 16rpx; | ||
| 244 | margin: 20rpx; | ||
| 245 | } | ||
| 246 | |||
| 247 | .notice-title { | ||
| 248 | color: #111; | ||
| 249 | font-size: 31rpx; | ||
| 250 | font-weight: 800; | ||
| 251 | line-height: 1.42; | ||
| 252 | } | ||
| 253 | |||
| 254 | .notice-summary { | ||
| 255 | display: -webkit-box; | ||
| 256 | margin-top: 12rpx; | ||
| 257 | overflow: hidden; | ||
| 258 | color: #666; | ||
| 259 | font-size: 25rpx; | ||
| 260 | line-height: 1.45; | ||
| 261 | text-overflow: ellipsis; | ||
| 262 | -webkit-box-orient: vertical; | ||
| 263 | -webkit-line-clamp: 2; | ||
| 264 | } | ||
| 265 | |||
| 266 | .notice-cover { | ||
| 267 | width: 100%; | ||
| 268 | height: 330rpx; | ||
| 269 | margin-top: 14rpx; | ||
| 270 | border-radius: 0; | ||
| 271 | background: #ddd; | ||
| 272 | } | ||
| 273 | |||
| 274 | .notice-meta { | ||
| 275 | display: flex; | ||
| 276 | align-items: center; | ||
| 277 | justify-content: space-between; | ||
| 278 | margin-top: 10rpx; | ||
| 279 | color: #999; | ||
| 280 | font-size: 24rpx; | ||
| 281 | } | ||
| 282 | |||
| 283 | .meta-right { | ||
| 284 | display: flex; | ||
| 285 | align-items: center; | ||
| 286 | gap: 8rpx; | ||
| 287 | } | ||
| 288 | |||
| 289 | .heart { | ||
| 290 | font-size: 28rpx; | ||
| 291 | } | ||
| 292 | |||
| 293 | .more { | ||
| 294 | margin-left: 14rpx; | ||
| 295 | letter-spacing: 2rpx; | ||
| 296 | } | ||
| 297 | </style> |
pages/index/daoGuanOrder.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view :class="{ 'no-scroll': isPopupOpen }" class="order-page"> | ||
| 3 | <view class="order-hero"> | ||
| 4 | <view class="hero-title-row"> | ||
| 5 | <view> | ||
| 6 | <view class="hero-title">中国跆拳道协会</view> | ||
| 7 | <view class="hero-subtitle">CHINESE TAEKWONDO ASSOCIATION</view> | ||
| 8 | </view> | ||
| 9 | <view class="hero-page-title"> | ||
| 10 | <text>订单管理</text> | ||
| 11 | <view class="title-line"></view> | ||
| 12 | </view> | ||
| 13 | </view> | ||
| 14 | |||
| 15 | <view class="search-bar"> | ||
| 16 | <uni-easyinput | ||
| 17 | v-model="queryParams.wfCode" | ||
| 18 | :input-border="false" | ||
| 19 | class="search-input" | ||
| 20 | placeholder="输入订单编号/名称/单位/日期" | ||
| 21 | placeholderStyle="font-size:28rpx;color:#999" | ||
| 22 | prefixIcon="search" | ||
| 23 | @blur="handelSearch" | ||
| 24 | @clear="handelSearch"> | ||
| 25 | </uni-easyinput> | ||
| 26 | <view class="add-btn" @click="handelSearch"> | ||
| 27 | <text class="add-text">搜索</text> | ||
| 28 | </view> | ||
| 29 | </view> | ||
| 30 | </view> | ||
| 31 | |||
| 32 | <view class="tab-bar"> | ||
| 33 | <view | ||
| 34 | v-for="(tab, index) in tabs" | ||
| 35 | :key="index" | ||
| 36 | :class="{ active: currentTab === tab.type }" | ||
| 37 | class="tab-item" | ||
| 38 | @click="switchTab(tab.type)" | ||
| 39 | > | ||
| 40 | {{ tab.name }} | ||
| 41 | </view> | ||
| 42 | </view> | ||
| 43 | |||
| 44 | <view class="status-filter"> | ||
| 45 | <view | ||
| 46 | v-for="(tab, index) in statusTabs" | ||
| 47 | :key="index" | ||
| 48 | :class="{ active: currentStatus === tab.type }" | ||
| 49 | class="status-filter-item" | ||
| 50 | @click="switchStatus(tab.type)" | ||
| 51 | > | ||
| 52 | {{ tab.name }} | ||
| 53 | </view> | ||
| 54 | <!-- <view class="filter-entry"> | ||
| 55 | <text class="filter-icon">▽</text> | ||
| 56 | <text>筛选</text> | ||
| 57 | </view> --> | ||
| 58 | </view> | ||
| 59 | |||
| 60 | <!-- 订单列表 --> | ||
| 61 | <scroll-view | ||
| 62 | :scroll-enabled="!isPopupOpen" | ||
| 63 | :show-scrollbar="false" | ||
| 64 | class="order-list-scroll" | ||
| 65 | lower-threshold="200" | ||
| 66 | scroll-y | ||
| 67 | @scrolltolower="loadMore" | ||
| 68 | > | ||
| 69 | <view class="order-list"> | ||
| 70 | <!-- 有数据才循环 --> | ||
| 71 | <!-- <view v-if="list.length > 0">--> | ||
| 72 | <!-- <view--> | ||
| 73 | <!-- v-for="(item, index) in list"--> | ||
| 74 | <!-- :key="index"--> | ||
| 75 | <!-- class="order-card"--> | ||
| 76 | <!-- @click="goToDetail(item)"--> | ||
| 77 | <!-- >--> | ||
| 78 | <!-- <!– 订单头部:日期 + 状态 –>--> | ||
| 79 | <!-- <view class="card-header">--> | ||
| 80 | <!-- <view class="date">--> | ||
| 81 | <!-- <!– <image :src="config.baseUrl_api + '/fs/static/calendar@2x.png'" mode="widthFix" style="width:30rpx;height:30rpx;"/> –>--> | ||
| 82 | <!-- <!– –>--> | ||
| 83 | <!-- <text class="value text-primary">{{ item.wfCode || '——' }}</text>--> | ||
| 84 | <!-- </view>--> | ||
| 85 | <!-- <view class="status-tags">--> | ||
| 86 | <!-- <!– <view--> | ||
| 87 | <!-- class="status-tag"--> | ||
| 88 | <!-- :class="{--> | ||
| 89 | <!-- success: item.payStatus == 1,--> | ||
| 90 | <!-- danger: item.payStatus == 2,--> | ||
| 91 | <!-- pending: item.payStatus == 0--> | ||
| 92 | <!-- }"--> | ||
| 93 | <!-- >--> | ||
| 94 | <!-- {{ getStatusText(item.payStatus) }}--> | ||
| 95 | <!-- </view> –>--> | ||
| 96 | <!-- <view--> | ||
| 97 | <!-- :class="{--> | ||
| 98 | <!-- 'status-wait': item.auditStatus == 0,--> | ||
| 99 | <!-- 'status-pending': item.auditStatus == 1,--> | ||
| 100 | <!-- 'status-success': item.auditStatus == 2,--> | ||
| 101 | <!-- 'status-danger': item.auditStatus == 3--> | ||
| 102 | <!-- }"--> | ||
| 103 | <!-- class="status-tag ml-10"--> | ||
| 104 | <!-- >--> | ||
| 105 | <!-- {{ getAuditStatusText(item.auditStatus) }}--> | ||
| 106 | <!-- </view>--> | ||
| 107 | <!-- </view>--> | ||
| 108 | <!-- </view>--> | ||
| 109 | <!-- --> | ||
| 110 | <!-- <!– 订单编号、缴费编号 –>--> | ||
| 111 | <!-- <view class="info-row">--> | ||
| 112 | <!-- <text class="label">订单编号:</text>--> | ||
| 113 | <!-- <text class="value">{{ item.tradeNo || '——' }}</text>--> | ||
| 114 | <!-- </view>--> | ||
| 115 | <!-- <view v-if="item.orderName" class="info-row">--> | ||
| 116 | <!-- <text class="label">缴费名称:</text>--> | ||
| 117 | <!-- <text class="value">{{ item.orderName || '' }}</text>--> | ||
| 118 | <!-- </view>--> | ||
| 119 | <!-- <!– <view class="info-row">--> | ||
| 120 | <!-- <text class="label">缴费编号:</text>--> | ||
| 121 | <!-- --> | ||
| 122 | <!-- </view> –>--> | ||
| 123 | <!-- --> | ||
| 124 | <!-- <!– 核心:前2tab仅展示缴费年限,后2tab仅展示人数合计 –>--> | ||
| 125 | <!-- <view v-if="item.content" class="info-section flex f-j-s">--> | ||
| 126 | <!-- <!– 个人/单位会员(仅缴费年限) –>--> | ||
| 127 | <!-- <view v-if="currentTab === '0' || currentTab === '1'" class="single-info">--> | ||
| 128 | <!-- <view class="label">缴费年限:</view>--> | ||
| 129 | <!-- <view class="value">{{ item.content.yearCount || 0 }}</view>--> | ||
| 130 | <!-- </view>--> | ||
| 131 | <!-- <!– 级位/段位考试(仅人数合计) –>--> | ||
| 132 | <!-- <view v-if="currentTab === '2' || currentTab === '3' || currentTab === '4'" class="single-info">--> | ||
| 133 | <!-- <view class="label">人数合计</view>--> | ||
| 134 | <!-- <view class="value">{{ item.content.personCount || 0 }}</view>--> | ||
| 135 | <!-- </view>--> | ||
| 136 | <!-- <view class="line"></view>--> | ||
| 137 | <!-- <view class="single-info">--> | ||
| 138 | <!-- <view class="label">订单状态</view>--> | ||
| 139 | <!-- <view :class="item.effect == 1 ? 'text-success' : 'text-warning'" class="value">--> | ||
| 140 | <!-- {{ item.effect == 1 ? '已生效' : '未生效' }}--> | ||
| 141 | <!-- </view>--> | ||
| 142 | <!-- </view>--> | ||
| 143 | <!-- <view class="line"></view>--> | ||
| 144 | <!-- <view class="single-info">--> | ||
| 145 | <!-- <view class="label">缴费状态</view>--> | ||
| 146 | <!-- <view--> | ||
| 147 | <!-- :class="{--> | ||
| 148 | <!-- 'text-primary': item.payStatus == 0,--> | ||
| 149 | <!-- 'text-success': item.payStatus == 1,--> | ||
| 150 | <!-- 'text-danger': item.payStatus == 2--> | ||
| 151 | <!-- }"--> | ||
| 152 | <!-- class="value"--> | ||
| 153 | <!-- >--> | ||
| 154 | <!-- {{ item.payStatus == 0 ? '待缴费' : item.payStatus == 1 ? '缴费成功' : '订单取消' }}--> | ||
| 155 | <!-- </view>--> | ||
| 156 | <!-- </view>--> | ||
| 157 | <!-- </view>--> | ||
| 158 | <!-- --> | ||
| 159 | <!-- <!– 费用合计 + 缴费方式 –>--> | ||
| 160 | <!-- <view class="price-section">--> | ||
| 161 | <!-- <view class="price-row">--> | ||
| 162 | <!-- <text class="price-label">费用合计</text>--> | ||
| 163 | <!-- <text class="price-value">¥{{ (Number(item.price) || 0).toFixed(2) }}</text>--> | ||
| 164 | <!-- </view>--> | ||
| 165 | <!-- <view class="price-row">--> | ||
| 166 | <!-- <text class="price-label">缴费方式</text>--> | ||
| 167 | <!-- <text class="price-value">{{ item.ziZhangBu ? '对公转账' : '民生付' }}</text>--> | ||
| 168 | <!-- </view>--> | ||
| 169 | <!-- </view>--> | ||
| 170 | <!-- --> | ||
| 171 | <!-- <!– 按钮组:靠右紧凑展示 –>--> | ||
| 172 | <!-- <view class="btn-group">--> | ||
| 173 | <!-- <!– 已缴费:申请开票/已开票(需要审核通过才能开票) –>--> | ||
| 174 | <!-- <template v-if="item.payStatus == 1 && item.invoiceStatus != 1&& item.auditStatus == 2 &&item.price>0">--> | ||
| 175 | <!-- <button :disabled="item.invoiceStatus === 1" class="btn btn-view-invoice" @click="makeInvoiceFN(item)">--> | ||
| 176 | <!-- 开票--> | ||
| 177 | <!-- </button>--> | ||
| 178 | <!-- </template>--> | ||
| 179 | <!-- <!– 已开票:查看发票 –>--> | ||
| 180 | <!-- <template v-if="item.invoiceStatus == 1">--> | ||
| 181 | <!-- <button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看发票</button>--> | ||
| 182 | <!-- </template>--> | ||
| 183 | <!-- <!– 未缴费:去缴费 + 取消订单 –>--> | ||
| 184 | <!-- <!– <template v-if="item.payStatus == 0">--> | ||
| 185 | <!-- <button class="btn btn-cancel" @click="handleCancel(item)">取消订单</button>--> | ||
| 186 | <!-- <button class="btn btn-pay" @click="handlePay(item)">去缴费</button>--> | ||
| 187 | <!-- </template> –>--> | ||
| 188 | <!-- </view>--> | ||
| 189 | <!-- </view>--> | ||
| 190 | <!-- </view>--> | ||
| 191 | |||
| 192 | <!-- 有数据才循环 --> | ||
| 193 | <view v-if="list.length > 0"> | ||
| 194 | <view | ||
| 195 | v-for="(item, index) in list" | ||
| 196 | :key="index" | ||
| 197 | class="order-card-new" | ||
| 198 | @click="goToDetail(item)" | ||
| 199 | > | ||
| 200 | <!-- 订单头部:日期 + 状态 --> | ||
| 201 | <view class="card-header"> | ||
| 202 | <view class="date"> | ||
| 203 | <view class="data-header"> | ||
| 204 | <text class="member-label">{{ getOrderLabel(item) }}·</text> | ||
| 205 | <text class="value ">{{ item.orderName || '——' }}</text> | ||
| 206 | </view> | ||
| 207 | <text :class="{ | ||
| 208 | 'status-wait': item.auditStatus == 0, | ||
| 209 | 'status-pending': item.auditStatus == 1, | ||
| 210 | 'status-success': item.auditStatus == 2, | ||
| 211 | 'status-danger': item.auditStatus == 3 | ||
| 212 | }" | ||
| 213 | class="status-tag ">{{ getAuditStatusText(item.auditStatus) }} | ||
| 214 | </text> | ||
| 215 | </view> | ||
| 216 | </view> | ||
| 217 | <!-- <view class="card-header code-row"> | ||
| 218 | <view class="date"> | ||
| 219 | <view class="data-header"> | ||
| 220 | <text class="value"> | ||
| 221 | <text class="tradeNo">订单编号:</text> | ||
| 222 | {{ item.tradeNo || '——' }} | ||
| 223 | </text> | ||
| 224 | </view> | ||
| 225 | </view> | ||
| 226 | </view> --> | ||
| 227 | <!-- <view class="card-header code-row"> | ||
| 228 | <view class="date"> | ||
| 229 | <view class="data-header"> | ||
| 230 | <text class="value"> | ||
| 231 | <text class="tradeNo">缴费编号:</text> | ||
| 232 | {{ item.wfCode || '——' }} | ||
| 233 | </text> | ||
| 234 | </view> | ||
| 235 | </view> | ||
| 236 | </view> --> | ||
| 237 | <view class="member-time"> | ||
| 238 | <view class="label"> | ||
| 239 | <text class="star">★</text> | ||
| 240 | {{ `${filterTime(item.genTime)}${filterType(item.type)}` }} | ||
| 241 | </view> | ||
| 242 | <view class="price"> | ||
| 243 | <view>¥{{ item.price || '0.00' }}</view> | ||
| 244 | <view v-if="item.type==0" class="person">共{{ item.content?.allPersonCount || 0 }}人</view> | ||
| 245 | <view v-if="item.type==1" class="person">共{{ item.content?.yearCount || 0 }}年</view> | ||
| 246 | <view v-if="item.type==2||item.type==3||item.type==4" class="person">共{{ | ||
| 247 | item.content?.personCount || 0 | ||
| 248 | }}人 | ||
| 249 | </view> | ||
| 250 | </view> | ||
| 251 | </view> | ||
| 252 | |||
| 253 | <!-- 核心:前2tab仅展示缴费年限,后2tab仅展示人数合计 --> | ||
| 254 | <!-- <view v-if="item.content" class="info-section flex f-j-s"> | ||
| 255 | <view v-if="currentTab === '0' || currentTab === '1'" class="single-info"> | ||
| 256 | <view class="label">缴费年限:</view> | ||
| 257 | <view class="value">{{ item.content.yearCount || 0 }}</view> | ||
| 258 | </view> | ||
| 259 | <view v-if="currentTab === '2' || currentTab === '3' || currentTab === '4'" class="single-info"> | ||
| 260 | <view class="label">人数合计</view> | ||
| 261 | <view class="value">{{ item.content.personCount || 0 }}</view> | ||
| 262 | </view> | ||
| 263 | <view class="line"></view> | ||
| 264 | <view class="single-info"> | ||
| 265 | <view class="label">订单状态</view> | ||
| 266 | <view :class="item.effect == 1 ? 'text-success' : 'text-warning'" class="value"> | ||
| 267 | {{ item.effect == 1 ? '已生效' : '未生效' }} | ||
| 268 | </view> | ||
| 269 | </view> | ||
| 270 | <view class="line"></view> | ||
| 271 | <view class="single-info"> | ||
| 272 | <view class="label">缴费状态</view> | ||
| 273 | <view | ||
| 274 | :class="{ | ||
| 275 | 'text-primary': item.payStatus == 0, | ||
| 276 | 'text-success': item.payStatus == 1, | ||
| 277 | 'text-danger': item.payStatus == 2 | ||
| 278 | }" | ||
| 279 | class="value" | ||
| 280 | > | ||
| 281 | {{ item.payStatus == 0 ? '待缴费' : item.payStatus == 1 ? '缴费成功' : '订单取消' }} | ||
| 282 | </view> | ||
| 283 | </view> | ||
| 284 | </view> --> | ||
| 285 | |||
| 286 | <!-- 按钮组:靠右紧凑展示 --> | ||
| 287 | <view class="btn-group"> | ||
| 288 | <view> | ||
| 289 | <text class="more" @click.stop="goToDetail(item)">更多</text> | ||
| 290 | </view> | ||
| 291 | <view class="btn-flex"> | ||
| 292 | <!-- 已缴费:申请开票/已开票(需要审核通过才能开票) --> | ||
| 293 | <template> | ||
| 294 | <button class="btn btn-info" @click.stop="goToDetail(item)">查看明细</button> | ||
| 295 | </template> | ||
| 296 | <!-- 已缴费:申请开票/已开票(需要审核通过才能开票) --> | ||
| 297 | <template v-if="item.payStatus == 1 && item.invoiceStatus != 1&& item.auditStatus == 2 &&item.price>0"> | ||
| 298 | <button :disabled="item.invoiceStatus === 1" class="btn btn-view-invoice" | ||
| 299 | @click.stop="makeInvoiceFN(item)"> | ||
| 300 | 申请票据 | ||
| 301 | </button> | ||
| 302 | </template> | ||
| 303 | <!-- 已申请票据:查看票据 --> | ||
| 304 | <template v-if="item.invoiceStatus == 1"> | ||
| 305 | <button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看票据</button> | ||
| 306 | </template> | ||
| 307 | <!-- 未缴费:去缴费 + 取消订单 --> | ||
| 308 | <!-- <template v-if="item.payStatus == 0"> | ||
| 309 | <button class="btn btn-cancel" @click="handleCancel(item)">取消订单</button> | ||
| 310 | <button class="btn btn-pay" @click="handlePay(item)">去缴费</button> | ||
| 311 | </template> --> | ||
| 312 | </view> | ||
| 313 | |||
| 314 | </view> | ||
| 315 | </view> | ||
| 316 | </view> | ||
| 317 | |||
| 318 | <!-- 空状态 --> | ||
| 319 | <view v-else class="empty"> | ||
| 320 | <image :src="config.baseUrl_api + '/fs/static/nodata.png'" class="empty-img" mode="aspectFit"></image> | ||
| 321 | <text class="empty-text">暂无订单记录</text> | ||
| 322 | </view> | ||
| 323 | |||
| 324 | <!-- 加载/无更多提示 --> | ||
| 325 | <view v-if="loading" class="loading-tip">加载中...</view> | ||
| 326 | <view v-if="!loading && !hasMore && list.length" class="no-more">没有更多了</view> | ||
| 327 | </view> | ||
| 328 | </scroll-view> | ||
| 329 | |||
| 330 | <!-- 票据信息弹窗(级位/段位/越段考试) --> | ||
| 331 | <view v-if="showInvoicePopup" class="invoice-popup-mask" @click="closeInvoicePopup"> | ||
| 332 | <view class="invoice-popup-content" @click.stop> | ||
| 333 | <view class="invoice-popup-header"> | ||
| 334 | <text class="invoice-popup-title">票据信息</text> | ||
| 335 | <view class="invoice-popup-close" @click="closeInvoicePopup">✕</view> | ||
| 336 | </view> | ||
| 337 | <view class="invoice-popup-body"> | ||
| 338 | <view class="invoice-info-list"> | ||
| 339 | <view class="invoice-info-row"> | ||
| 340 | <view class="invoice-info-label">票据类型</view> | ||
| 341 | <view :class="{ 'vat-type': invoiceData.invoiceType == 2 }" class="invoice-type-badge"> | ||
| 342 | {{ invoiceData.invoiceType == 1 ? '普通票据' : '增值税专用票据' }} | ||
| 343 | </view> | ||
| 344 | </view> | ||
| 345 | <view class="invoice-info-row"> | ||
| 346 | <text class="invoice-info-label">票据抬头</text> | ||
| 347 | <text class="invoice-info-value">{{ invoiceData.invoiceBuyerName || '—' }}</text> | ||
| 348 | </view> | ||
| 349 | <view v-if="invoiceData.invoiceBuyerTaxno" class="invoice-info-row"> | ||
| 350 | <text class="invoice-info-label">纳税人识别号</text> | ||
| 351 | <text class="invoice-info-value">{{ invoiceData.invoiceBuyerTaxno }}</text> | ||
| 352 | </view> | ||
| 353 | <view class="invoice-info-row"> | ||
| 354 | <text class="invoice-info-label">接收邮箱</text> | ||
| 355 | <text class="invoice-info-value">{{ invoiceData.invoicePushPhone || '—' }}</text> | ||
| 356 | </view> | ||
| 357 | <view class="invoice-info-row"> | ||
| 358 | <text class="invoice-info-label">申请时间</text> | ||
| 359 | <text class="invoice-info-value">{{ invoiceData.invoiceTime || '—' }}</text> | ||
| 360 | </view> | ||
| 361 | <view class="invoice-info-row"> | ||
| 362 | <text class="invoice-info-label">票据金额</text> | ||
| 363 | <text class="invoice-info-value">¥{{ invoiceData.price || '—' }}</text> | ||
| 364 | </view> | ||
| 365 | </view> | ||
| 366 | </view> | ||
| 367 | </view> | ||
| 368 | </view> | ||
| 369 | |||
| 370 | <!-- 票据Webview弹窗(个人/单位会员) --> | ||
| 371 | <view v-if="showInvoiceWebview" class="invoice-popup-mask" @click="closeInvoiceWebview"> | ||
| 372 | <view class="invoice-webview-content" @click.stop> | ||
| 373 | <view class="invoice-popup-header"> | ||
| 374 | <text class="invoice-popup-title">票据</text> | ||
| 375 | <view class="invoice-popup-close" @click="closeInvoiceWebview">✕</view> | ||
| 376 | </view> | ||
| 377 | <view class="invoice-webview-body"> | ||
| 378 | <web-view :src="invoiceWebviewUrl"></web-view> | ||
| 379 | </view> | ||
| 380 | </view> | ||
| 381 | </view> | ||
| 382 | |||
| 383 | <!-- 自定义删除确认弹窗 --> | ||
| 384 | <view v-if="showDelPopup" class="popup-mask" @touchmove.stop.prevent @click.stop="closeDelPopup"> | ||
| 385 | <view class="custom-modal" @click.stop> | ||
| 386 | <view class="modal-title">提示</view> | ||
| 387 | <view class="modal-content">{{ delModalContent }}</view> | ||
| 388 | <view class="modal-btns"> | ||
| 389 | <button class="modal-btn-cancel" @click="closeDelPopup">取消</button> | ||
| 390 | <button class="modal-btn-confirm" @click="confirmDel">确定</button> | ||
| 391 | </view> | ||
| 392 | </view> | ||
| 393 | </view> | ||
| 394 | |||
| 395 | <!-- 自定义取消订单确认弹窗 --> | ||
| 396 | <view v-if="showCancelPopup" class="popup-mask" @touchmove.stop.prevent @click.stop="closeCancelPopup"> | ||
| 397 | <view class="custom-modal" @click.stop> | ||
| 398 | <view class="modal-title">提示</view> | ||
| 399 | <view class="modal-content">{{ cancelModalContent }}</view> | ||
| 400 | <view class="modal-btns"> | ||
| 401 | <button class="modal-btn-cancel" @click="closeCancelPopup">取消</button> | ||
| 402 | <button class="modal-btn-confirm" @click="confirmCancel">确定</button> | ||
| 403 | </view> | ||
| 404 | </view> | ||
| 405 | </view> | ||
| 406 | |||
| 407 | <!-- 底部导航 --> | ||
| 408 | <dao-guan-tab-bar :currentIndex="1" @switch="onTabSwitch" /> | ||
| 409 | </view> | ||
| 410 | </template> | ||
| 411 | |||
| 412 | <script setup> | ||
| 413 | import {ref, reactive, onMounted, computed} from 'vue'; | ||
| 414 | import { | ||
| 415 | onShow, | ||
| 416 | onLoad | ||
| 417 | } from '@dcloudio/uni-app' | ||
| 418 | import * as api from '@/common/api.js' | ||
| 419 | import config from '@/config.js' | ||
| 420 | import dayjs from 'dayjs' | ||
| 421 | import DaoGuanTabBar from '@/components/dao-guan-tab-bar.vue' | ||
| 422 | // 获取deptType值(初始值为0,在onMounted中设置实际值) | ||
| 423 | const deptType = ref(0); | ||
| 424 | |||
| 425 | |||
| 426 | // 标签栏配置(根据deptType动态生成) | ||
| 427 | const tabs = computed(() => { | ||
| 428 | const dt = Number(deptType.value) | ||
| 429 | console.log('tabs computed, deptType:', deptType.value, 'dt:', dt, 'dt===6:', dt === 6, 'dt==6:', dt == 6); | ||
| 430 | |||
| 431 | if (dt === 6) { | ||
| 432 | console.log('返回3个tab: 个人会员、单位会员、级位考试'); | ||
| 433 | return [ | ||
| 434 | {name: '个人会员', type: '0', label: "会员"}, | ||
| 435 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 436 | {name: '级位考试', type: '2', label: "级位"} | ||
| 437 | ]; | ||
| 438 | } else if (dt === 2) { | ||
| 439 | console.log('返回3个tab: 单位会员、段位考试、越段考试'); | ||
| 440 | return [ | ||
| 441 | // {name: '单位会员', type: '1'}, | ||
| 442 | {name: '段位考试', type: '3', label: "段位"}, | ||
| 443 | {name: '越段考试', type: '4', label: "越段"} | ||
| 444 | ]; | ||
| 445 | } else if (dt === 1) { | ||
| 446 | console.log('返回默认5个tab, dt值为:', dt); | ||
| 447 | return [ | ||
| 448 | {name: '个人会员', type: '0', label: "会员"}, | ||
| 449 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 450 | {name: '级位考试', type: '2', label: "级位"}, | ||
| 451 | {name: '段位考试', type: '3', label: "段位"}, | ||
| 452 | {name: '越段考试', type: '4', label: "越段"} | ||
| 453 | ]; | ||
| 454 | } else { | ||
| 455 | return [ | ||
| 456 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 457 | ]; | ||
| 458 | } | ||
| 459 | }); | ||
| 460 | const currentTab = ref('0'); | ||
| 461 | const currentStatus = ref(''); | ||
| 462 | const statusTabs = [ | ||
| 463 | { name: '全部', type: '' }, | ||
| 464 | { name: '待缴费', type: '0' }, | ||
| 465 | { name: '缴费成功', type: '1' }, | ||
| 466 | { name: '订单取消', type: '2' } | ||
| 467 | ] | ||
| 468 | |||
| 469 | // 数据与分页配置 | ||
| 470 | const list = ref([]); | ||
| 471 | const loading = ref(false); | ||
| 472 | const hasMore = ref(true); | ||
| 473 | const pageNum = ref(1); | ||
| 474 | const pageSize = ref(10); | ||
| 475 | |||
| 476 | // 查询参数 | ||
| 477 | const queryParams = reactive({ | ||
| 478 | pageNum: 1, | ||
| 479 | pageSize: 10, | ||
| 480 | type: '0', | ||
| 481 | queryType: '1', | ||
| 482 | payStatus: '' | ||
| 483 | }); | ||
| 484 | |||
| 485 | // 弹窗控制 | ||
| 486 | const showDelPopup = ref(false); | ||
| 487 | const showCancelPopup = ref(false); | ||
| 488 | const isPopupOpen = ref(false); | ||
| 489 | const showInvoicePopup = ref(false); | ||
| 490 | const showInvoiceWebview = ref(false); | ||
| 491 | const invoiceWebviewUrl = ref(''); | ||
| 492 | const invoiceData = ref({}); | ||
| 493 | |||
| 494 | // 弹窗内容 | ||
| 495 | const delModalContent = ref(''); | ||
| 496 | const cancelModalContent = ref(''); | ||
| 497 | |||
| 498 | // 当前操作的订单 | ||
| 499 | const currentOrder = ref(null); | ||
| 500 | |||
| 501 | // 页面挂载初始化 | ||
| 502 | onLoad((option) => { | ||
| 503 | // 获取app实例和deptType | ||
| 504 | const app = getApp(); | ||
| 505 | deptType.value = Number(app.globalData?.deptType || 0); | ||
| 506 | const firstType = tabs.value[0]?.type ?? '0'; | ||
| 507 | // currentTab.value = option.type || firstType; | ||
| 508 | // queryParams.type = option.type || firstType; | ||
| 509 | currentTab.value = firstType; | ||
| 510 | queryParams.type = firstType; | ||
| 511 | initData(); | ||
| 512 | }); | ||
| 513 | |||
| 514 | // 页面显示时刷新数据(从开票页面返回时) | ||
| 515 | onShow(() => { | ||
| 516 | // 如果有缓存的刷新标记,则刷新列表 | ||
| 517 | if (needRefresh.value) { | ||
| 518 | needRefresh.value = false; | ||
| 519 | pageNum.value = 1; | ||
| 520 | list.value = []; | ||
| 521 | hasMore.value = true; | ||
| 522 | initData(); | ||
| 523 | } | ||
| 524 | }); | ||
| 525 | |||
| 526 | // 是否需要刷新 | ||
| 527 | const needRefresh = ref(false); | ||
| 528 | |||
| 529 | // 上拉加载更多 | ||
| 530 | const loadMore = () => { | ||
| 531 | console.log("触发上拉加载"); | ||
| 532 | if (loading.value || !hasMore.value || isPopupOpen.value) return; | ||
| 533 | pageNum.value++; | ||
| 534 | initData(); | ||
| 535 | }; | ||
| 536 | |||
| 537 | // 切换标签 | ||
| 538 | const switchTab = (type) => { | ||
| 539 | currentTab.value = type; | ||
| 540 | queryParams.type = type; | ||
| 541 | pageNum.value = 1; | ||
| 542 | list.value = []; | ||
| 543 | hasMore.value = true; | ||
| 544 | initData(); | ||
| 545 | }; | ||
| 546 | |||
| 547 | const switchStatus = (type) => { | ||
| 548 | currentStatus.value = type; | ||
| 549 | queryParams.payStatus = type; | ||
| 550 | pageNum.value = 1; | ||
| 551 | list.value = []; | ||
| 552 | hasMore.value = true; | ||
| 553 | initData(); | ||
| 554 | }; | ||
| 555 | |||
| 556 | // 状态文本映射 | ||
| 557 | const getStatusText = (status) => { | ||
| 558 | const map = { | ||
| 559 | 0: '待缴费', | ||
| 560 | 1: '缴费成功', | ||
| 561 | 2: '订单取消' | ||
| 562 | }; | ||
| 563 | return map[status] || ''; | ||
| 564 | }; | ||
| 565 | |||
| 566 | // 审核状态文本映射 | ||
| 567 | const getAuditStatusText = (status) => { | ||
| 568 | const map = { | ||
| 569 | 0: '待提交', | ||
| 570 | 1: '审核中', | ||
| 571 | 2: '审核通过', | ||
| 572 | 3: '审核拒绝' | ||
| 573 | }; | ||
| 574 | return map[status] || ''; | ||
| 575 | }; | ||
| 576 | |||
| 577 | const getOrderLabel = (item) => { | ||
| 578 | const map = { | ||
| 579 | 0: '会员', | ||
| 580 | 1: '单位', | ||
| 581 | 2: '级位', | ||
| 582 | 3: '段位', | ||
| 583 | 4: '越段' | ||
| 584 | } | ||
| 585 | return map[item.type] || tabs.value.find(t => t.type === currentTab.value)?.label || '订单' | ||
| 586 | } | ||
| 587 | |||
| 588 | const filterTime = (row) => { | ||
| 589 | if (!row) return '' | ||
| 590 | return dayjs(row).format('YYYY年MM月DD日') | ||
| 591 | } | ||
| 592 | |||
| 593 | const filterType = (row) => { | ||
| 594 | if (row == 0) return '个人会员缴费办理' | ||
| 595 | if (row == 1) return '单位会员缴费办理' | ||
| 596 | if (row == 2) return '级位考试办理' | ||
| 597 | if (row == 3) return '段位考试办理' | ||
| 598 | if (row == 4) return '越位考试办理' | ||
| 599 | } | ||
| 600 | |||
| 601 | |||
| 602 | // 数据请求核心方法 | ||
| 603 | const initData = async () => { | ||
| 604 | loading.value = true; | ||
| 605 | queryParams.pageNum = pageNum.value; | ||
| 606 | |||
| 607 | try { | ||
| 608 | const res = await api.orderList(queryParams); | ||
| 609 | console.log("接口返回:", res); | ||
| 610 | |||
| 611 | if (!res || !res.rows || res.rows.length === 0) { | ||
| 612 | hasMore.value = false; | ||
| 613 | loading.value = false; | ||
| 614 | return; | ||
| 615 | } | ||
| 616 | // 安全解析content字段 | ||
| 617 | res.rows.forEach(item => { | ||
| 618 | if (item.content) { | ||
| 619 | try { | ||
| 620 | item.content = JSON.parse(item.content); | ||
| 621 | } catch (e) { | ||
| 622 | item.content = null; | ||
| 623 | } | ||
| 624 | } | ||
| 625 | }); | ||
| 626 | // 第一页覆盖,后面页数追加 | ||
| 627 | if (pageNum.value === 1) { | ||
| 628 | list.value = res.rows; | ||
| 629 | } else { | ||
| 630 | list.value.push(...res.rows); | ||
| 631 | } | ||
| 632 | // 关键修复:只要返回条数 < pageSize 就说明没有更多了 | ||
| 633 | hasMore.value = res.rows.length === pageSize.value; | ||
| 634 | } catch (e) { | ||
| 635 | console.error('订单加载异常:', e); | ||
| 636 | uni.showToast({title: '加载失败', icon: 'none'}); | ||
| 637 | hasMore.value = false; | ||
| 638 | } finally { | ||
| 639 | loading.value = false; | ||
| 640 | } | ||
| 641 | }; | ||
| 642 | |||
| 643 | const handelSearch = () => { | ||
| 644 | pageNum.value = 1 | ||
| 645 | list.value = [] | ||
| 646 | initData() | ||
| 647 | } | ||
| 648 | |||
| 649 | // 删除订单 | ||
| 650 | const handleDelete = (item) => { | ||
| 651 | currentOrder.value = item; | ||
| 652 | delModalContent.value = `是否确认删除订单编号为"${item.tradeNo}"的订单?`; | ||
| 653 | showDelPopup.value = true; | ||
| 654 | isPopupOpen.value = true; | ||
| 655 | }; | ||
| 656 | |||
| 657 | // 确认删除 | ||
| 658 | const confirmDel = async () => { | ||
| 659 | if (!currentOrder.value) return; | ||
| 660 | try { | ||
| 661 | await api.deleteOrder(currentOrder.value.id); | ||
| 662 | uni.showToast({title: '删除成功', icon: 'success'}); | ||
| 663 | pageNum.value = 1; | ||
| 664 | list.value = []; | ||
| 665 | await initData(); | ||
| 666 | closeDelPopup(); | ||
| 667 | } catch (e) { | ||
| 668 | uni.showToast({title: '删除失败', icon: 'error'}); | ||
| 669 | } | ||
| 670 | }; | ||
| 671 | |||
| 672 | const goToDetail = (item) => { | ||
| 673 | console.log("goToDetail:", item); | ||
| 674 | console.log("currentTab.value", currentTab.value); | ||
| 675 | const form = encodeURIComponent(JSON.stringify(item)) | ||
| 676 | switch (currentTab.value) { | ||
| 677 | case '1': | ||
| 678 | uni.navigateTo({url: `/group/groupOrderDetail?form=${form}`}); | ||
| 679 | break; | ||
| 680 | case '2': | ||
| 681 | case '3': | ||
| 682 | case '4': | ||
| 683 | uni.navigateTo({url: `/pages/rank/applyDetail?examId=${item.sourceId || item.id}&type=${queryParams.type}`}); | ||
| 684 | break; | ||
| 685 | case '0': | ||
| 686 | default: | ||
| 687 | uni.navigateTo({url: `/personalVip/orderDetail?rangeId=${item.sourceId || item.id}&type=${queryParams.type}`}); | ||
| 688 | break; | ||
| 689 | } | ||
| 690 | // uni.navigateTo({url: `/pages/rank/applyDetail?examId=${item.sourceId || item.id}&type=${queryParams.type}`}); | ||
| 691 | } | ||
| 692 | |||
| 693 | // 关闭删除弹窗 | ||
| 694 | const closeDelPopup = () => { | ||
| 695 | showDelPopup.value = false; | ||
| 696 | isPopupOpen.value = false; | ||
| 697 | currentOrder.value = null; | ||
| 698 | }; | ||
| 699 | |||
| 700 | // 去缴费 | ||
| 701 | const handlePay = async (item) => { | ||
| 702 | if (item.payStatus !== 0) return; | ||
| 703 | try { | ||
| 704 | await api.goPay({id: item.id}); | ||
| 705 | uni.navigateTo({url: `/pages/pay/pay?orderId=${item.id}`}); | ||
| 706 | } catch (e) { | ||
| 707 | uni.showToast({title: '发起支付失败', icon: 'none'}); | ||
| 708 | } | ||
| 709 | }; | ||
| 710 | |||
| 711 | // 申请开票 | ||
| 712 | const makeInvoiceFN = (item) => { | ||
| 713 | // 开票条件:缴费成功 && 未开票 && 审核通过 | ||
| 714 | // if (item.payStatus !== 1 || item.invoiceStatus === 1 || item.auditStatus !== 2) { | ||
| 715 | // return; | ||
| 716 | // } | ||
| 717 | // 设置刷新标记,从开票页面返回时刷新列表 | ||
| 718 | needRefresh.value = true; | ||
| 719 | // 根据tab类型决定跳转页面:个人/单位会员开非税票,级位/段位/越段考试开增值税票 | ||
| 720 | let url = ''; | ||
| 721 | if (currentTab.value === '0' || currentTab.value === '1') { | ||
| 722 | // 个人/单位会员 - 非税开票 | ||
| 723 | url = `/pages/invoice/applyFeisui?orderId=${item.id}&amount=${item.price}`; | ||
| 724 | } else { | ||
| 725 | // 级位/段位/越段考试 - 增值税开票 | ||
| 726 | url = `/pages/invoice/apply?orderId=${item.id}&amount=${item.price}`; | ||
| 727 | } | ||
| 728 | uni.navigateTo({ url }); | ||
| 729 | }; | ||
| 730 | |||
| 731 | // 查看发票 | ||
| 732 | const viewInvoice = (item) => { | ||
| 733 | // 个人/单位会员(type 0或1)直接跳转webview页面展示发票 | ||
| 734 | if (item.type === 0 || item.type === '0' || item.type === 1 || item.type === '1') { | ||
| 735 | if (item.invoiceUrl) { | ||
| 736 | const encodedUrl = encodeURIComponent(item.invoiceUrl); | ||
| 737 | uni.navigateTo({ | ||
| 738 | url: `/pages/webview/webview?url=${encodedUrl}` | ||
| 739 | }); | ||
| 740 | } else { | ||
| 741 | uni.showToast({ title: '暂无发票', icon: 'none' }); | ||
| 742 | } | ||
| 743 | return; | ||
| 744 | } | ||
| 745 | // 其他类型显示发票信息弹窗 | ||
| 746 | invoiceData.value = { | ||
| 747 | invoiceType: item.invoiceType || 1, | ||
| 748 | invoiceBuyerName: item.invoiceTitle || item.invoiceBuyerName || '—', | ||
| 749 | invoiceBuyerTaxno: item.invoiceTaxno || item.invoiceBuyerTaxno || '', | ||
| 750 | invoicePushPhone: item.invoiceEmail || item.invoicePushPhone || '—', | ||
| 751 | price: item.price || '-', | ||
| 752 | invoiceTime: item.invoiceTime || '—' | ||
| 753 | }; | ||
| 754 | showInvoicePopup.value = true; | ||
| 755 | isPopupOpen.value = true; | ||
| 756 | }; | ||
| 757 | |||
| 758 | // 关闭发票弹窗 | ||
| 759 | const closeInvoicePopup = () => { | ||
| 760 | showInvoicePopup.value = false; | ||
| 761 | isPopupOpen.value = false; | ||
| 762 | }; | ||
| 763 | |||
| 764 | // 关闭发票Webview弹窗 | ||
| 765 | const closeInvoiceWebview = () => { | ||
| 766 | showInvoiceWebview.value = false; | ||
| 767 | isPopupOpen.value = false; | ||
| 768 | }; | ||
| 769 | |||
| 770 | // 取消订单 | ||
| 771 | const handleCancel = (item) => { | ||
| 772 | currentOrder.value = item; | ||
| 773 | cancelModalContent.value = `是否确认取消订单编号为"${item.tradeNo}"的订单?`; | ||
| 774 | showCancelPopup.value = true; | ||
| 775 | isPopupOpen.value = true; | ||
| 776 | }; | ||
| 777 | |||
| 778 | // 确认取消订单 | ||
| 779 | const confirmCancel = async () => { | ||
| 780 | if (!currentOrder.value) return; | ||
| 781 | try { | ||
| 782 | await api.cancelPay(currentOrder.value.id); | ||
| 783 | uni.showToast({title: '取消成功', icon: 'success'}); | ||
| 784 | pageNum.value = 1; | ||
| 785 | list.value = []; | ||
| 786 | await initData(); | ||
| 787 | closeCancelPopup(); | ||
| 788 | } catch (e) { | ||
| 789 | uni.showToast({title: '取消失败', icon: 'error'}); | ||
| 790 | } | ||
| 791 | }; | ||
| 792 | |||
| 793 | // 关闭取消订单弹窗 | ||
| 794 | const closeCancelPopup = () => { | ||
| 795 | showCancelPopup.value = false; | ||
| 796 | isPopupOpen.value = false; | ||
| 797 | currentOrder.value = null; | ||
| 798 | }; | ||
| 799 | |||
| 800 | // 底部导航切换 | ||
| 801 | const onTabSwitch = (index, url) => { | ||
| 802 | // tab switch handled by component | ||
| 803 | }; | ||
| 804 | </script> | ||
| 805 | |||
| 806 | <style lang="scss" scoped> | ||
| 807 | .order-page { | ||
| 808 | background: #ededf0; | ||
| 809 | height: 100vh; | ||
| 810 | display: flex; | ||
| 811 | flex-direction: column; | ||
| 812 | padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); | ||
| 813 | box-sizing: border-box; | ||
| 814 | |||
| 815 | &.no-scroll { | ||
| 816 | overflow: hidden; | ||
| 817 | height: 100vh; | ||
| 818 | } | ||
| 819 | } | ||
| 820 | |||
| 821 | .order-hero { | ||
| 822 | flex-shrink: 0; | ||
| 823 | padding: calc(env(safe-area-inset-top) + 90rpx) 44rpx 34rpx; | ||
| 824 | background: linear-gradient(135deg, #b00005 0%, #7a0000 100%); | ||
| 825 | color: #fff; | ||
| 826 | } | ||
| 827 | |||
| 828 | .hero-title-row { | ||
| 829 | display: flex; | ||
| 830 | justify-content: space-between; | ||
| 831 | align-items: flex-end; | ||
| 832 | margin-bottom: 42rpx; | ||
| 833 | } | ||
| 834 | |||
| 835 | .hero-title { | ||
| 836 | font-size: 38rpx; | ||
| 837 | letter-spacing: 2rpx; | ||
| 838 | } | ||
| 839 | |||
| 840 | .hero-subtitle { | ||
| 841 | margin-top: 8rpx; | ||
| 842 | color: rgba(255, 255, 255, 0.58); | ||
| 843 | font-size: 16rpx; | ||
| 844 | } | ||
| 845 | |||
| 846 | .hero-page-title { | ||
| 847 | color: #f4b536; | ||
| 848 | font-size: 36rpx; | ||
| 849 | font-weight: 500; | ||
| 850 | text-align: right; | ||
| 851 | } | ||
| 852 | |||
| 853 | .title-line { | ||
| 854 | width: 54rpx; | ||
| 855 | height: 6rpx; | ||
| 856 | margin: 14rpx 0 0 auto; | ||
| 857 | border-radius: 10rpx; | ||
| 858 | background: #f4b536; | ||
| 859 | } | ||
| 860 | |||
| 861 | /* 搜索栏 */ | ||
| 862 | .search-bar { | ||
| 863 | display: flex; | ||
| 864 | align-items: center; | ||
| 865 | height: 64rpx; | ||
| 866 | padding: 0; | ||
| 867 | border-radius: 34rpx; | ||
| 868 | background-color: #ffffff; | ||
| 869 | overflow: hidden; | ||
| 870 | |||
| 871 | .search-input { | ||
| 872 | flex: 1; | ||
| 873 | margin-right: 0; | ||
| 874 | |||
| 875 | :deep(.uni-easyinput__content) { | ||
| 876 | border-radius: 34rpx; | ||
| 877 | background-color: #fff; | ||
| 878 | height: 64rpx; | ||
| 879 | padding: 0 18rpx 0 28rpx; | ||
| 880 | } | ||
| 881 | |||
| 882 | :deep(.uni-easyinput__content-input) { | ||
| 883 | font-size: 28rpx; | ||
| 884 | color: #333; | ||
| 885 | } | ||
| 886 | } | ||
| 887 | |||
| 888 | .add-btn { | ||
| 889 | display: flex; | ||
| 890 | align-items: center; | ||
| 891 | justify-content: center; | ||
| 892 | width: 88rpx; | ||
| 893 | height: 52rpx; | ||
| 894 | margin-right: 6rpx; | ||
| 895 | background-color: #c91c34; | ||
| 896 | border-radius: 28rpx; | ||
| 897 | font-size: 24rpx; | ||
| 898 | font-weight: 700; | ||
| 899 | color: #ffffff; | ||
| 900 | } | ||
| 901 | |||
| 902 | .add-icon { | ||
| 903 | font-size: 36rpx; | ||
| 904 | margin-right: 10rpx; | ||
| 905 | font-weight: bold; | ||
| 906 | } | ||
| 907 | } | ||
| 908 | |||
| 909 | // 标签栏样式 | ||
| 910 | .tab-bar { | ||
| 911 | display: flex; | ||
| 912 | flex-shrink: 0; | ||
| 913 | padding: 22rpx 30rpx 4rpx; | ||
| 914 | background: #ededf0; | ||
| 915 | flex-shrink: 0; | ||
| 916 | |||
| 917 | .tab-item { | ||
| 918 | flex: none; | ||
| 919 | margin-right: 48rpx; | ||
| 920 | padding: 0 0 14rpx; | ||
| 921 | font-size: 30rpx; | ||
| 922 | color: #666; | ||
| 923 | position: relative; | ||
| 924 | font-weight: bold; | ||
| 925 | |||
| 926 | &.active { | ||
| 927 | color: #c30d23; | ||
| 928 | font-weight: bold; | ||
| 929 | |||
| 930 | &::after { | ||
| 931 | content: ''; | ||
| 932 | position: absolute; | ||
| 933 | bottom: 0; | ||
| 934 | left: 50%; | ||
| 935 | transform: translateX(-50%); | ||
| 936 | width: 72rpx; | ||
| 937 | height: 4rpx; | ||
| 938 | background: #c30d23; | ||
| 939 | border-radius: 2rpx; | ||
| 940 | } | ||
| 941 | } | ||
| 942 | } | ||
| 943 | } | ||
| 944 | |||
| 945 | .status-filter { | ||
| 946 | display: flex; | ||
| 947 | align-items: center; | ||
| 948 | flex-shrink: 0; | ||
| 949 | padding: 10rpx 26rpx 18rpx; | ||
| 950 | background: #ededf0; | ||
| 951 | } | ||
| 952 | |||
| 953 | .status-filter-item { | ||
| 954 | height: 48rpx; | ||
| 955 | line-height: 48rpx; | ||
| 956 | margin-right: 18rpx; | ||
| 957 | padding: 0 24rpx; | ||
| 958 | border-radius: 8rpx; | ||
| 959 | background: #fff; | ||
| 960 | color: #777; | ||
| 961 | font-size: 26rpx; | ||
| 962 | } | ||
| 963 | |||
| 964 | .status-filter-item.active { | ||
| 965 | color: #c30d23; | ||
| 966 | font-weight: 700; | ||
| 967 | } | ||
| 968 | |||
| 969 | .filter-entry { | ||
| 970 | margin-left: auto; | ||
| 971 | display: flex; | ||
| 972 | flex-direction: column; | ||
| 973 | align-items: center; | ||
| 974 | color: #999; | ||
| 975 | font-size: 20rpx; | ||
| 976 | } | ||
| 977 | |||
| 978 | .filter-icon { | ||
| 979 | font-size: 28rpx; | ||
| 980 | line-height: 22rpx; | ||
| 981 | } | ||
| 982 | |||
| 983 | // 滚动列表容器 | ||
| 984 | .order-list-scroll { | ||
| 985 | flex: 1; | ||
| 986 | height: auto; | ||
| 987 | overflow: auto; | ||
| 988 | background: #ededf0; | ||
| 989 | } | ||
| 990 | |||
| 991 | // 订单列表 | ||
| 992 | .order-list { | ||
| 993 | padding: 0 24rpx 34rpx; | ||
| 994 | |||
| 995 | .order-card { | ||
| 996 | background: #fff; | ||
| 997 | margin-bottom: 20rpx; | ||
| 998 | padding: 20rpx; | ||
| 999 | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); | ||
| 1000 | border-radius: 12rpx; | ||
| 1001 | display: flex; | ||
| 1002 | flex-direction: column; | ||
| 1003 | // border-top: 6rpx solid transparent; | ||
| 1004 | // background-clip: padding-box, border-box; | ||
| 1005 | // background-origin: padding-box, border-box; | ||
| 1006 | // background-image: linear-gradient(#fff, #fff), linear-gradient(90deg, #FF755A, #F51722); | ||
| 1007 | } | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | // 卡片头部 | ||
| 1011 | .card-header { | ||
| 1012 | display: flex; | ||
| 1013 | justify-content: space-between; | ||
| 1014 | align-items: center; | ||
| 1015 | padding-bottom: 10rpx; | ||
| 1016 | // margin-bottom: 20rpx; | ||
| 1017 | // border-bottom: 1rpx dashed #eee; | ||
| 1018 | |||
| 1019 | .date { | ||
| 1020 | display: flex; | ||
| 1021 | align-items: center; | ||
| 1022 | gap: 8rpx; | ||
| 1023 | font-size: 26rpx; | ||
| 1024 | |||
| 1025 | .date-text { | ||
| 1026 | color: #666; | ||
| 1027 | } | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | .status-tags { | ||
| 1031 | display: flex; | ||
| 1032 | gap: 10rpx; | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | .status-tag { | ||
| 1036 | font-size: 22rpx; | ||
| 1037 | //padding: 6rpx 16rpx; | ||
| 1038 | //border-radius: 20rpx; | ||
| 1039 | |||
| 1040 | &.success { | ||
| 1041 | //background: #e6f7ef; | ||
| 1042 | color: #52c41a; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | &.danger { | ||
| 1046 | //background: #fff1f0; | ||
| 1047 | color: #ff4d4f; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | &.pending { | ||
| 1051 | //background: #f5f5f5; | ||
| 1052 | color: #999; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | &.ml-10 { | ||
| 1056 | margin-left: 10rpx; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | &.status-wait { | ||
| 1060 | //background: #f0f5ff; | ||
| 1061 | color: #597ef7; | ||
| 1062 | //border: 1rpx solid rgba(89, 126, 247, 0.3); | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | &.status-pending { | ||
| 1066 | //background: #fff7e6; | ||
| 1067 | color: #faad14; | ||
| 1068 | //border: 1rpx solid rgba(250, 173, 20, 0.3); | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | &.status-success { | ||
| 1072 | //background: #e6f7ef; | ||
| 1073 | color: #52c41a; | ||
| 1074 | //border: 1rpx solid rgba(82, 196, 26, 0.3); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | &.status-danger { | ||
| 1078 | //background: #fff1f0; | ||
| 1079 | color: #ff4d4f; | ||
| 1080 | //border: 1rpx solid rgba(232, 52, 29, 0.3); | ||
| 1081 | } | ||
| 1082 | } | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | // 基础信息行 | ||
| 1086 | .info-row { | ||
| 1087 | display: flex; | ||
| 1088 | align-items: center; | ||
| 1089 | margin-bottom: 20rpx; | ||
| 1090 | font-size: 26rpx; | ||
| 1091 | |||
| 1092 | .label { | ||
| 1093 | color: #999; | ||
| 1094 | flex-shrink: 0; | ||
| 1095 | width: 140rpx; | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | .value { | ||
| 1099 | color: #333; | ||
| 1100 | word-break: break-all; | ||
| 1101 | } | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | .info-section { | ||
| 1105 | background: #f3f6fc; | ||
| 1106 | display: flex; | ||
| 1107 | align-items: center; | ||
| 1108 | justify-content: space-between; | ||
| 1109 | //margin: 20rpx 0; | ||
| 1110 | padding: 0 20rpx; | ||
| 1111 | min-height: 100rpx; | ||
| 1112 | border-radius: 20rpx; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | .line { | ||
| 1116 | width: 1rpx; | ||
| 1117 | height: 60rpx; | ||
| 1118 | background: #e5e5e5; | ||
| 1119 | flex-shrink: 0; | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | .single-info { | ||
| 1123 | flex: 1; | ||
| 1124 | padding: 16rpx 20rpx; | ||
| 1125 | border-radius: 8rpx; | ||
| 1126 | font-size: 26rpx; | ||
| 1127 | text-align: center; | ||
| 1128 | |||
| 1129 | .label { | ||
| 1130 | color: #999; | ||
| 1131 | text-align: center; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | .value { | ||
| 1135 | color: #333; | ||
| 1136 | font-weight: 500; | ||
| 1137 | text-align: center; | ||
| 1138 | margin-top: 10rpx; | ||
| 1139 | |||
| 1140 | &.text-primary { | ||
| 1141 | color: #597ef7; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | &.text-success { | ||
| 1145 | color: #52c41a; | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | &.text-danger { | ||
| 1149 | color: #ff4d4f; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | &.text-warning { | ||
| 1153 | color: #faad14; | ||
| 1154 | } | ||
| 1155 | } | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | // 费用合计 | ||
| 1159 | .price-section { | ||
| 1160 | // border-top: 1rpx dashed #eee; | ||
| 1161 | // padding-top: 16rpx; | ||
| 1162 | margin-top: 8rpx; | ||
| 1163 | |||
| 1164 | .price-row { | ||
| 1165 | display: flex; | ||
| 1166 | justify-content: space-between; | ||
| 1167 | align-items: center; | ||
| 1168 | padding: 8rpx 0; | ||
| 1169 | |||
| 1170 | .price-label { | ||
| 1171 | font-size: 26rpx; | ||
| 1172 | color: #333; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | .price-value { | ||
| 1176 | font-size: 26rpx; | ||
| 1177 | color: #666; | ||
| 1178 | |||
| 1179 | &.text-success { | ||
| 1180 | color: #52c41a; | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | &.text-warning { | ||
| 1184 | color: #faad14; | ||
| 1185 | } | ||
| 1186 | } | ||
| 1187 | } | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | // 按钮组 | ||
| 1191 | .btn-group { | ||
| 1192 | display: flex; | ||
| 1193 | justify-content: space-between; | ||
| 1194 | align-items: center; | ||
| 1195 | gap: 16rpx; | ||
| 1196 | width: 100%; | ||
| 1197 | margin-top: 16rpx; | ||
| 1198 | |||
| 1199 | .more { | ||
| 1200 | color: #999; | ||
| 1201 | font-size: 26rpx; | ||
| 1202 | font-weight: 700; | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | .btn-flex { | ||
| 1206 | display: flex; | ||
| 1207 | justify-content: flex-end; | ||
| 1208 | gap: 16rpx; | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | .btn { | ||
| 1212 | // 固定宽度,所有按钮一样大 | ||
| 1213 | width: 126rpx; | ||
| 1214 | height: 44rpx; | ||
| 1215 | line-height: 44rpx; | ||
| 1216 | padding: 0; | ||
| 1217 | border-radius: 10rpx; | ||
| 1218 | font-size: 24rpx; | ||
| 1219 | white-space: nowrap; | ||
| 1220 | font-weight: bold; | ||
| 1221 | border: none; | ||
| 1222 | background: transparent; | ||
| 1223 | text-align: center; | ||
| 1224 | margin: 0; | ||
| 1225 | |||
| 1226 | &::after { | ||
| 1227 | border: none; | ||
| 1228 | display: none; // 关键:隐藏伪元素 | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | &.btn-delete { | ||
| 1232 | background: #fff; | ||
| 1233 | //color: #e4393c; | ||
| 1234 | color: #c30d23; | ||
| 1235 | border: 1rpx solid #c30d23; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | &.btn-invoice { | ||
| 1239 | background: #fff; | ||
| 1240 | color: #c30d23; | ||
| 1241 | border: 1rpx solid #c30d23; | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | &.btn-view-invoice { | ||
| 1245 | //background: linear-gradient(90deg, #FF755A, #F51722); | ||
| 1246 | color: #c30d23; | ||
| 1247 | //border: none; | ||
| 1248 | border: 1rpx solid #c30d23; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | &.btn-info { | ||
| 1252 | color: #444; | ||
| 1253 | border: 1rpx solid #d7d7d7; | ||
| 1254 | background: #fff; | ||
| 1255 | } | ||
| 1256 | |||
| 1257 | &.btn-cancel { | ||
| 1258 | background: #fff; | ||
| 1259 | color: #666; | ||
| 1260 | border: 1rpx solid #ccc; | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | &.btn-pay { | ||
| 1264 | //background: linear-gradient(90deg, #FF755A, #F51722); | ||
| 1265 | color: #c30d23; | ||
| 1266 | //border: none; | ||
| 1267 | border: 1rpx solid #c30d23; | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | &:disabled { | ||
| 1271 | opacity: 0.6; | ||
| 1272 | pointer-events: none; | ||
| 1273 | } | ||
| 1274 | } | ||
| 1275 | } | ||
| 1276 | |||
| 1277 | |||
| 1278 | // 加载/无更多提示 | ||
| 1279 | .loading-tip, .no-more { | ||
| 1280 | text-align: center; | ||
| 1281 | padding: 20rpx 0; | ||
| 1282 | color: #999; | ||
| 1283 | font-size: 26rpx; | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | // 弹窗遮罩层 | ||
| 1287 | .popup-mask { | ||
| 1288 | position: fixed; | ||
| 1289 | top: 0; | ||
| 1290 | left: 0; | ||
| 1291 | right: 0; | ||
| 1292 | bottom: 0; | ||
| 1293 | background-color: rgba(0, 0, 0, 0.5); | ||
| 1294 | display: flex; | ||
| 1295 | align-items: center; | ||
| 1296 | justify-content: center; | ||
| 1297 | z-index: 999; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | // 自定义弹窗样式 | ||
| 1301 | .custom-modal { | ||
| 1302 | width: 600rpx; | ||
| 1303 | background: #fff; | ||
| 1304 | border-radius: 20rpx; | ||
| 1305 | padding: 40rpx 30rpx; | ||
| 1306 | box-sizing: border-box; | ||
| 1307 | text-align: center; | ||
| 1308 | box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.2); | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | .modal-title { | ||
| 1312 | font-size: 36rpx; | ||
| 1313 | font-weight: 600; | ||
| 1314 | color: #333; | ||
| 1315 | margin-bottom: 30rpx; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | .modal-content { | ||
| 1319 | font-size: 30rpx; | ||
| 1320 | color: #666; | ||
| 1321 | line-height: 1.6; | ||
| 1322 | margin-bottom: 40rpx; | ||
| 1323 | word-break: break-word; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | .modal-btns { | ||
| 1327 | display: flex; | ||
| 1328 | justify-content: space-between; | ||
| 1329 | gap: 20rpx; | ||
| 1330 | } | ||
| 1331 | |||
| 1332 | .modal-btn-cancel { | ||
| 1333 | flex: 1; | ||
| 1334 | height: 80rpx; | ||
| 1335 | line-height: 80rpx; | ||
| 1336 | background: #f5f5f5; | ||
| 1337 | color: #666; | ||
| 1338 | border-radius: 40rpx; | ||
| 1339 | font-size: 32rpx; | ||
| 1340 | border: none; | ||
| 1341 | margin: 0; | ||
| 1342 | padding: 0; | ||
| 1343 | |||
| 1344 | &::after { | ||
| 1345 | border: none; | ||
| 1346 | } | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | .modal-btn-confirm { | ||
| 1350 | flex: 1; | ||
| 1351 | height: 80rpx; | ||
| 1352 | line-height: 80rpx; | ||
| 1353 | background: #C4121B; | ||
| 1354 | color: #fff; | ||
| 1355 | border-radius: 40rpx; | ||
| 1356 | font-size: 32rpx; | ||
| 1357 | border: none; | ||
| 1358 | margin: 0; | ||
| 1359 | padding: 0; | ||
| 1360 | |||
| 1361 | &::after { | ||
| 1362 | border: none; | ||
| 1363 | } | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | .code-text { | ||
| 1367 | font-size: 28rpx; | ||
| 1368 | font-weight: 600; | ||
| 1369 | color: #e8341d; | ||
| 1370 | letter-spacing: 1rpx; | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | // 发票弹窗样式 | ||
| 1374 | .invoice-popup-mask { | ||
| 1375 | position: fixed; | ||
| 1376 | top: 0; | ||
| 1377 | left: 0; | ||
| 1378 | right: 0; | ||
| 1379 | bottom: 0; | ||
| 1380 | background-color: rgba(0, 0, 0, 0.5); | ||
| 1381 | display: flex; | ||
| 1382 | align-items: center; | ||
| 1383 | justify-content: center; | ||
| 1384 | z-index: 999; | ||
| 1385 | } | ||
| 1386 | |||
| 1387 | .invoice-popup-content { | ||
| 1388 | width: 600rpx; | ||
| 1389 | background: #fff; | ||
| 1390 | border-radius: 20rpx; | ||
| 1391 | overflow: hidden; | ||
| 1392 | box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.2); | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | .invoice-webview-content { | ||
| 1396 | width: 90%; | ||
| 1397 | height: 85vh; | ||
| 1398 | background: #fff; | ||
| 1399 | border-radius: 20rpx; | ||
| 1400 | overflow: hidden; | ||
| 1401 | display: flex; | ||
| 1402 | flex-direction: column; | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | .invoice-webview-body { | ||
| 1406 | flex: 1; | ||
| 1407 | overflow: hidden; | ||
| 1408 | } | ||
| 1409 | |||
| 1410 | .invoice-popup-header { | ||
| 1411 | display: flex; | ||
| 1412 | justify-content: space-between; | ||
| 1413 | align-items: center; | ||
| 1414 | padding: 30rpx; | ||
| 1415 | background: linear-gradient(135deg, #AD181F 0%, #E4393C 100%); | ||
| 1416 | |||
| 1417 | .invoice-popup-title { | ||
| 1418 | font-size: 32rpx; | ||
| 1419 | font-weight: 600; | ||
| 1420 | color: #fff; | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | .invoice-popup-close { | ||
| 1424 | width: 44rpx; | ||
| 1425 | height: 44rpx; | ||
| 1426 | display: flex; | ||
| 1427 | align-items: center; | ||
| 1428 | justify-content: center; | ||
| 1429 | font-size: 28rpx; | ||
| 1430 | color: rgba(255, 255, 255, 0.8); | ||
| 1431 | } | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | .invoice-popup-body { | ||
| 1435 | padding: 30rpx; | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | .invoice-type-badge { | ||
| 1439 | display: inline-flex; | ||
| 1440 | align-items: center; | ||
| 1441 | padding: 8rpx 24rpx; | ||
| 1442 | background: linear-gradient(135deg, #FF755A 0%, #F51722 100%); | ||
| 1443 | color: #fff; | ||
| 1444 | border-radius: 30rpx; | ||
| 1445 | font-size: 24rpx; | ||
| 1446 | font-weight: 500; | ||
| 1447 | |||
| 1448 | &.vat-type { | ||
| 1449 | background: linear-gradient(135deg, #6aaaf2 0%, #178cd7 100%); | ||
| 1450 | } | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | .invoice-info-list { | ||
| 1454 | .invoice-info-row { | ||
| 1455 | display: flex; | ||
| 1456 | justify-content: space-between; | ||
| 1457 | align-items: flex-start; | ||
| 1458 | padding: 24rpx 0; | ||
| 1459 | border-bottom: 1rpx dashed #eee; | ||
| 1460 | |||
| 1461 | &:last-child { | ||
| 1462 | border-bottom: none; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | .invoice-info-label { | ||
| 1466 | font-size: 26rpx; | ||
| 1467 | color: #999; | ||
| 1468 | flex-shrink: 0; | ||
| 1469 | } | ||
| 1470 | |||
| 1471 | .invoice-info-value { | ||
| 1472 | font-size: 26rpx; | ||
| 1473 | color: #333; | ||
| 1474 | text-align: right; | ||
| 1475 | word-break: break-all; | ||
| 1476 | max-width: 340rpx; | ||
| 1477 | } | ||
| 1478 | } | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | .order-card-new { | ||
| 1482 | background: #fff; | ||
| 1483 | margin-bottom: 22rpx; | ||
| 1484 | padding: 22rpx 18rpx 18rpx; | ||
| 1485 | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); | ||
| 1486 | border-radius: 18rpx; | ||
| 1487 | display: flex; | ||
| 1488 | flex-direction: column; | ||
| 1489 | |||
| 1490 | |||
| 1491 | // 卡片头部 | ||
| 1492 | .card-header { | ||
| 1493 | display: flex; | ||
| 1494 | justify-content: space-between; | ||
| 1495 | align-items: center; | ||
| 1496 | padding-bottom: 10rpx; | ||
| 1497 | // margin-bottom: 20rpx; | ||
| 1498 | // border-bottom: 1rpx dashed #eee; | ||
| 1499 | |||
| 1500 | .date { | ||
| 1501 | width: 100%; | ||
| 1502 | display: flex; | ||
| 1503 | align-items: center; | ||
| 1504 | justify-content: space-between; | ||
| 1505 | gap: 8rpx; | ||
| 1506 | font-size: 26rpx; | ||
| 1507 | |||
| 1508 | .data-header { | ||
| 1509 | display: flex; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | .member-label { | ||
| 1513 | color: #c30d23; | ||
| 1514 | font-size: 28rpx; | ||
| 1515 | font-weight: bold; | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | .value { | ||
| 1519 | color: #000; | ||
| 1520 | font-size: 27rpx; | ||
| 1521 | font-weight: bold; | ||
| 1522 | max-width: 460rpx; | ||
| 1523 | overflow: hidden; | ||
| 1524 | white-space: nowrap; | ||
| 1525 | text-overflow: ellipsis; | ||
| 1526 | |||
| 1527 | .tradeNo { | ||
| 1528 | color: #999; | ||
| 1529 | font-size: 24rpx; | ||
| 1530 | } | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | .date-text { | ||
| 1534 | color: #666; | ||
| 1535 | } | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | |||
| 1539 | .status-tags { | ||
| 1540 | display: flex; | ||
| 1541 | gap: 10rpx; | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | .status-tag { | ||
| 1545 | font-size: 24rpx; | ||
| 1546 | color: #999; | ||
| 1547 | //padding: 6rpx 16rpx; | ||
| 1548 | //border-radius: 20rpx; | ||
| 1549 | |||
| 1550 | &.success { | ||
| 1551 | //background: #e6f7ef; | ||
| 1552 | color: #52c41a; | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | &.danger { | ||
| 1556 | //background: #fff1f0; | ||
| 1557 | color: #ff4d4f; | ||
| 1558 | } | ||
| 1559 | |||
| 1560 | &.pending { | ||
| 1561 | //background: #f5f5f5; | ||
| 1562 | color: #999; | ||
| 1563 | } | ||
| 1564 | |||
| 1565 | &.ml-10 { | ||
| 1566 | margin-left: 10rpx; | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | &.status-wait { | ||
| 1570 | //background: #f0f5ff; | ||
| 1571 | color: #597ef7; | ||
| 1572 | //border: 1rpx solid rgba(89, 126, 247, 0.3); | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | &.status-pending { | ||
| 1576 | //background: #fff7e6; | ||
| 1577 | color: #faad14; | ||
| 1578 | //border: 1rpx solid rgba(250, 173, 20, 0.3); | ||
| 1579 | } | ||
| 1580 | |||
| 1581 | &.status-success { | ||
| 1582 | //background: #e6f7ef; | ||
| 1583 | color: #52c41a; | ||
| 1584 | //border: 1rpx solid rgba(82, 196, 26, 0.3); | ||
| 1585 | } | ||
| 1586 | |||
| 1587 | &.status-danger { | ||
| 1588 | //background: #fff1f0; | ||
| 1589 | color: #ff4d4f; | ||
| 1590 | //border: 1rpx solid rgba(232, 52, 29, 0.3); | ||
| 1591 | } | ||
| 1592 | } | ||
| 1593 | } | ||
| 1594 | |||
| 1595 | .member-time { | ||
| 1596 | width: 100%; | ||
| 1597 | display: flex; | ||
| 1598 | justify-content: space-between; | ||
| 1599 | padding-bottom: 4rpx; | ||
| 1600 | |||
| 1601 | .label { | ||
| 1602 | max-width: 480rpx; | ||
| 1603 | color: #555; | ||
| 1604 | font-size: 26rpx; | ||
| 1605 | font-weight: 700; | ||
| 1606 | line-height: 1.4; | ||
| 1607 | |||
| 1608 | .star { | ||
| 1609 | color: #777; | ||
| 1610 | font-size: 26rpx; | ||
| 1611 | } | ||
| 1612 | } | ||
| 1613 | |||
| 1614 | .price { | ||
| 1615 | min-width: 130rpx; | ||
| 1616 | color: #333; | ||
| 1617 | font-size: 26rpx; | ||
| 1618 | font-weight: 500; | ||
| 1619 | text-align: right; | ||
| 1620 | |||
| 1621 | .person { | ||
| 1622 | font-size: 24rpx; | ||
| 1623 | color: #999; | ||
| 1624 | text-align: right; | ||
| 1625 | } | ||
| 1626 | } | ||
| 1627 | } | ||
| 1628 | } | ||
| 1629 | </style> |
pages/index/daoGuanPerson.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="person-dashboard"> | ||
| 3 | <view class="hero"> | ||
| 4 | <image class="hero-bg" :src="config.baseUrl_api + '/fs/static/img/red_bg.png'" mode="aspectFill"></image> | ||
| 5 | |||
| 6 | <view class="hero-nav"> | ||
| 7 | <view> | ||
| 8 | <view class="brand-cn">中国跆拳道协会</view> | ||
| 9 | <view class="brand-en">CHINESE TAEKWONDO ASSOCIATION</view> | ||
| 10 | </view> | ||
| 11 | <view class="page-title"> | ||
| 12 | <text>人员管理</text> | ||
| 13 | <view class="title-line"></view> | ||
| 14 | </view> | ||
| 15 | </view> | ||
| 16 | |||
| 17 | <view class="member-card"> | ||
| 18 | <view class="member-content"> | ||
| 19 | <view class="member-left"> | ||
| 20 | <view class="hello">您好!</view> | ||
| 21 | <view class="member-name">{{ memberName }}</view> | ||
| 22 | <view class="member-desc">您已经是中国跆拳道协会的金牌会员了</view> | ||
| 23 | <view class="name-line"></view> | ||
| 24 | </view> | ||
| 25 | <view class="level-box" @click="goPath('/myCenter/reviewList')"> | ||
| 26 | <image class="star" :src="config.baseUrl_api + '/fs/static/img/star.png'" mode="aspectFit"></image> | ||
| 27 | <view class="level-title">晋级考点</view> | ||
| 28 | <view class="detail-btn">查看详情</view> | ||
| 29 | </view> | ||
| 30 | </view> | ||
| 31 | </view> | ||
| 32 | </view> | ||
| 33 | |||
| 34 | <view class="main-actions"> | ||
| 35 | <image class="actions-bg" :src="config.baseUrl_api + '/fs/static/img/red_bg2.png'" mode="aspectFill"></image> | ||
| 36 | <view class="member-bottom"> | ||
| 37 | <view class="info-item"> | ||
| 38 | <view class="info-label">单位会员编号</view> | ||
| 39 | <view class="info-value">{{ memberInfo.memCode }}</view> | ||
| 40 | </view> | ||
| 41 | <view class="info-item"> | ||
| 42 | <view class="info-label">有效期</view> | ||
| 43 | <view class="info-value">{{ validityDate }}</view> | ||
| 44 | </view> | ||
| 45 | </view> | ||
| 46 | <image class="action-card" :src="config.baseUrl_api + '/fs/static/img/btn01.png'" mode="widthFix" @click="goPath('/myCenter/examPointApplyList')"></image> | ||
| 47 | <image class="action-card" :src="config.baseUrl_api + '/fs/static/img/btn02.png'" mode="widthFix" @click="goAuthPayV2"></image> | ||
| 48 | <image class="action-card" :src="config.baseUrl_api + '/fs/static/img/btn03.png'" mode="widthFix" @click="goPath('/personalVip/addVip')"></image> | ||
| 49 | <image class="action-card" :src="config.baseUrl_api + '/fs/static/img/btn04.png'" mode="widthFix" @click="goPath('/personalVip/payment')"></image> | ||
| 50 | <image class="action-card" :src="config.baseUrl_api + '/fs/static/img/btn05.png'" mode="widthFix" @click="goPath('/personalVip/list')"></image> | ||
| 51 | <image class="action-card" :src="config.baseUrl_api + '/fs/static/img/btn06.png'" mode="widthFix" @click="goPath('/personalVip/mobilize')"></image> | ||
| 52 | </view> | ||
| 53 | |||
| 54 | <dao-guan-tab-bar :currentIndex="0" @switch="onTabSwitch" /> | ||
| 55 | |||
| 56 | <uni-popup ref="authPayPopup" :mask-click="false" type="center"> | ||
| 57 | <view class="dialog-wrapper"> | ||
| 58 | <view class="dialog-title">提示</view> | ||
| 59 | <view class="dialog-message">{{ authPayPopupMsg }}</view> | ||
| 60 | <view class="dialog-footer"> | ||
| 61 | <button class="dialog-btn confirm" @click="closeAuthPayDialog">确定</button> | ||
| 62 | </view> | ||
| 63 | </view> | ||
| 64 | </uni-popup> | ||
| 65 | |||
| 66 | <uni-popup ref="examPointPopup" :mask-click="false" > | ||
| 67 | <view class="dialog-wrapper"> | ||
| 68 | <view class="dialog-title">申请成为考点</view> | ||
| 69 | <view class="dialog-message"> | ||
| 70 | <text>恭喜您成为中国跆拳道协会单位会员!</text> | ||
| 71 | <text>根据协会考点管理办法,需成为考点单位才能进行考级业务的办理。</text> | ||
| 72 | <text>是否现在申请成为考点。</text> | ||
| 73 | </view> | ||
| 74 | <view class="dialog-footer"> | ||
| 75 | <button class="dialog-btn cancel" @click="closeExamPointDialog">取消</button> | ||
| 76 | <button class="dialog-btn confirm" @click="goExamPointApply">去申请</button> | ||
| 77 | </view> | ||
| 78 | <view class="no-display" @click="handleNoDisplay">不再显示</view> | ||
| 79 | </view> | ||
| 80 | </uni-popup> | ||
| 81 | |||
| 82 | <uni-popup ref="passwordTipPopup" :mask-click="false" type="center"> | ||
| 83 | <view class="dialog-wrapper"> | ||
| 84 | <view class="dialog-title">温馨提示</view> | ||
| 85 | <view class="dialog-message">密码长期未更新,请及时更新</view> | ||
| 86 | <view class="dialog-footer"> | ||
| 87 | <button class="dialog-btn confirm" @click="closePasswordTipDialog">确定</button> | ||
| 88 | </view> | ||
| 89 | </view> | ||
| 90 | </uni-popup> | ||
| 91 | </view> | ||
| 92 | </template> | ||
| 93 | |||
| 94 | <script setup> | ||
| 95 | import config from '@/config.js' | ||
| 96 | import { computed, ref } from 'vue' | ||
| 97 | import { onLoad, onShow } from '@dcloudio/uni-app' | ||
| 98 | import * as api from '@/common/api.js' | ||
| 99 | import { getInfo } from '@/common/login' | ||
| 100 | import DaoGuanTabBar from '@/components/dao-guan-tab-bar.vue' | ||
| 101 | |||
| 102 | const app = getApp() | ||
| 103 | const userType = ref('1') | ||
| 104 | const memberInfo = ref({}) | ||
| 105 | const deptInfo = ref({}) | ||
| 106 | const numData = ref({}) | ||
| 107 | const isBlack = ref(0) | ||
| 108 | const authPayDisabled = ref(true) | ||
| 109 | const authPayPopup = ref(null) | ||
| 110 | const authPayPopupMsg = ref('') | ||
| 111 | const passwordTipPopup = ref(null) | ||
| 112 | const examPointPopup = ref(null) | ||
| 113 | const showDirectlyForAuthPay = ref(false) | ||
| 114 | const directUnderFlagForAuthPay = ref(0) | ||
| 115 | const associateIdForAuthPay = ref(0) | ||
| 116 | |||
| 117 | const memberName = computed(() => { | ||
| 118 | return memberInfo.value.name || deptInfo.value.deptName || app.globalData?.dept?.deptName || '--' | ||
| 119 | }) | ||
| 120 | |||
| 121 | const memberCode = computed(() => { | ||
| 122 | return memberInfo.value.menCode || memberInfo.value.memberCode || memberInfo.value.memberNo || '--' | ||
| 123 | }) | ||
| 124 | |||
| 125 | const validityDate = computed(() => { | ||
| 126 | const value = memberInfo.value.validityDate || memberInfo.value.validityEndDate || memberInfo.value.expireTime | ||
| 127 | return value ? String(value).slice(0, 10) : '--' | ||
| 128 | }) | ||
| 129 | |||
| 130 | onLoad((option) => { | ||
| 131 | const userName = uni.getStorageSync('userName') | ||
| 132 | if (!userName) { | ||
| 133 | app.globalData.isLogin = false | ||
| 134 | uni.reLaunch({ url: '/login/login' }) | ||
| 135 | return | ||
| 136 | } | ||
| 137 | |||
| 138 | if (option.scene) { | ||
| 139 | decodeURIComponent(option.scene) | ||
| 140 | } | ||
| 141 | |||
| 142 | if (uni.showShareMenu) { | ||
| 143 | uni.showShareMenu({ | ||
| 144 | withShareTicket: true, | ||
| 145 | menus: ['shareAppMessage', 'shareTimeline'] | ||
| 146 | }) | ||
| 147 | } | ||
| 148 | }) | ||
| 149 | |||
| 150 | onShow(() => { | ||
| 151 | if (app.globalData.isLogin) { | ||
| 152 | init() | ||
| 153 | } else { | ||
| 154 | app.firstLoadCallback = () => { | ||
| 155 | init() | ||
| 156 | } | ||
| 157 | } | ||
| 158 | }) | ||
| 159 | |||
| 160 | function init() { | ||
| 161 | api.getMyOwnMemberInfo().then(res => { | ||
| 162 | const data = res && res.data ? res.data : {} | ||
| 163 | app.globalData.authenticationStatus = data.authenticationStatus | ||
| 164 | app.globalData.memberInfo = data.memberInfo || {} | ||
| 165 | app.globalData.dept = data.dept || app.globalData.dept || {} | ||
| 166 | app.globalData.isExam = data.memberInfo?.isPoints | ||
| 167 | |||
| 168 | userType.value = app.globalData.userType | ||
| 169 | memberInfo.value = data.memberInfo || app.globalData.memberInfo || {} | ||
| 170 | deptInfo.value = data.dept || app.globalData.dept || {} | ||
| 171 | |||
| 172 | updateAuthPayDisabled(data) | ||
| 173 | updateAuthPayRule(data) | ||
| 174 | handleAccountStatus() | ||
| 175 | checkDialogs() | ||
| 176 | }) | ||
| 177 | |||
| 178 | api.getRemindCount().then(res => { | ||
| 179 | numData.value = res.data || {} | ||
| 180 | }) | ||
| 181 | |||
| 182 | api.getBlack().then(res => { | ||
| 183 | isBlack.value = res.data | ||
| 184 | }) | ||
| 185 | } | ||
| 186 | |||
| 187 | function handleAccountStatus() { | ||
| 188 | console.log('handleAccountStatus22',userType.value , app.globalData.authenticationStatus) | ||
| 189 | if (userType.value != '1' && app.globalData.authenticationStatus != '2' && app.globalData.authenticationStatus != '4') { | ||
| 190 | uni.navigateTo({ url: '/pages/index/perfect' }) | ||
| 191 | return | ||
| 192 | } | ||
| 193 | |||
| 194 | if (app.globalData.authenticationStatus == '5') { | ||
| 195 | const content = app.globalData.genFlag == 1 ? '您的会员已过期' : '会员已过期,请及时续费' | ||
| 196 | uni.showModal({ | ||
| 197 | title: '提示', | ||
| 198 | content, | ||
| 199 | success: (res) => { | ||
| 200 | if (res.confirm && app.globalData.genFlag != 1) { | ||
| 201 | uni.navigateTo({ url: '/myCenter/auth' }) | ||
| 202 | } | ||
| 203 | } | ||
| 204 | }) | ||
| 205 | return | ||
| 206 | } | ||
| 207 | |||
| 208 | if (app.globalData.authenticationStatus == '4') { | ||
| 209 | uni.showModal({ | ||
| 210 | title: '提示', | ||
| 211 | content: '你的会员即将过期,将会影响你的业务,请及时续费' | ||
| 212 | }) | ||
| 213 | } | ||
| 214 | |||
| 215 | if (app.globalData.memberInfo?.activeStatus == 0) { | ||
| 216 | uni.showModal({ | ||
| 217 | content: '账号未激活,请前去激活', | ||
| 218 | success: (res) => { | ||
| 219 | if (res.confirm) { | ||
| 220 | uni.navigateTo({ url: '/myCenter/auth' }) | ||
| 221 | } | ||
| 222 | } | ||
| 223 | }) | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | function goPath(path) { | ||
| 228 | if (isBlack.value == '1') { | ||
| 229 | uni.showModal({ | ||
| 230 | title: '提示', | ||
| 231 | content: '您的账号已被拉黑,请联系中跆协!' | ||
| 232 | }) | ||
| 233 | return | ||
| 234 | } | ||
| 235 | |||
| 236 | if (app.globalData.authenticationStatus == '5') { | ||
| 237 | if (app.globalData.genFlag == 1) { | ||
| 238 | uni.showModal({ | ||
| 239 | title: '提示', | ||
| 240 | content: '您的会员已过期' | ||
| 241 | }) | ||
| 242 | } else { | ||
| 243 | uni.showModal({ | ||
| 244 | title: '提示', | ||
| 245 | content: '会员已过期,请及时续费', | ||
| 246 | success: (res) => { | ||
| 247 | if (res.confirm) { | ||
| 248 | uni.navigateTo({ url: '/myCenter/auth' }) | ||
| 249 | } | ||
| 250 | } | ||
| 251 | }) | ||
| 252 | } | ||
| 253 | return | ||
| 254 | } | ||
| 255 | |||
| 256 | if (app.globalData.memberInfo?.activeStatus == 0) { | ||
| 257 | uni.showModal({ | ||
| 258 | title: '提示', | ||
| 259 | content: '账号未激活,请前去激活', | ||
| 260 | success: (res) => { | ||
| 261 | if (res.confirm) { | ||
| 262 | uni.navigateTo({ url: '/myCenter/auth' }) | ||
| 263 | } | ||
| 264 | } | ||
| 265 | }) | ||
| 266 | return | ||
| 267 | } | ||
| 268 | |||
| 269 | uni.navigateTo({ url: path }) | ||
| 270 | } | ||
| 271 | |||
| 272 | function updateAuthPayDisabled(data = {}) { | ||
| 273 | const authStatus = data.authenticationStatus | ||
| 274 | const resultNoProvince = data.resultNoProvince2 | ||
| 275 | if (authStatus == 0) { | ||
| 276 | authPayDisabled.value = false | ||
| 277 | } else if (authStatus == 1) { | ||
| 278 | authPayDisabled.value = true | ||
| 279 | } else { | ||
| 280 | const canPay = resultNoProvince === true || resultNoProvince == 1 | ||
| 281 | authPayDisabled.value = !canPay | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | function updateAuthPayRule(data = {}) { | ||
| 286 | const memberInfoData = data.memberInfo || {} | ||
| 287 | const associateId = Number(memberInfoData.associateId || 0) | ||
| 288 | showDirectlyForAuthPay.value = !associateId | ||
| 289 | directUnderFlagForAuthPay.value = Number(memberInfoData.directUnderFlag || 0) | ||
| 290 | associateIdForAuthPay.value = associateId | ||
| 291 | } | ||
| 292 | |||
| 293 | function canAuthPayByAccountStatus() { | ||
| 294 | return showDirectlyForAuthPay.value && | ||
| 295 | directUnderFlagForAuthPay.value === 0 && | ||
| 296 | associateIdForAuthPay.value === 0 | ||
| 297 | } | ||
| 298 | |||
| 299 | function showAuthPayDialog(message) { | ||
| 300 | authPayPopupMsg.value = message | ||
| 301 | authPayPopup.value?.open() | ||
| 302 | } | ||
| 303 | |||
| 304 | function closeAuthPayDialog() { | ||
| 305 | authPayPopup.value?.close() | ||
| 306 | } | ||
| 307 | |||
| 308 | function closePasswordTipDialog() { | ||
| 309 | passwordTipPopup.value?.close() | ||
| 310 | } | ||
| 311 | |||
| 312 | function goAuthPayV2() { | ||
| 313 | if (!canAuthPayByAccountStatus()) { | ||
| 314 | showAuthPayDialog('当前账号状态暂无法办理缴费业务') | ||
| 315 | return | ||
| 316 | } | ||
| 317 | if (authPayDisabled.value) { | ||
| 318 | showAuthPayDialog('您有一笔缴费正在审核中,请勿重复缴费。您可前往【认证详情】查看审核进度。') | ||
| 319 | return | ||
| 320 | } | ||
| 321 | goPath('/myCenter/perfect') | ||
| 322 | } | ||
| 323 | |||
| 324 | function closeExamPointDialog() { | ||
| 325 | examPointPopup.value?.close() | ||
| 326 | } | ||
| 327 | |||
| 328 | function goExamPointApply() { | ||
| 329 | closeExamPointDialog() | ||
| 330 | uni.navigateTo({ url: '/myCenter/examPointApplyList' }) | ||
| 331 | } | ||
| 332 | |||
| 333 | async function handleNoDisplay() { | ||
| 334 | await api.noDisplay() | ||
| 335 | await getInfo() | ||
| 336 | closeExamPointDialog() | ||
| 337 | } | ||
| 338 | |||
| 339 | function checkDialogs() { | ||
| 340 | const user = app.globalData.userInfo || {} | ||
| 341 | const memberInfoData = app.globalData.memberInfo || {} | ||
| 342 | |||
| 343 | if (app.globalData.changePassFlag == '1' && | ||
| 344 | app.globalData.memberInfo?.activeStatus == '1' && | ||
| 345 | app.globalData.authenticationStatus == 2) { | ||
| 346 | const hasShown = uni.getStorageSync('passwordTipShown') | ||
| 347 | if (!hasShown) { | ||
| 348 | uni.setStorageSync('passwordTipShown', true) | ||
| 349 | passwordTipPopup.value?.open() | ||
| 350 | } | ||
| 351 | } | ||
| 352 | console.log('checkDialogs',app.globalData.memberInfo?.activeStatus,app.globalData.authenticationStatus,app.globalData.deptType,memberInfoData.isPoints) | ||
| 353 | if (app.globalData.memberInfo?.activeStatus == 1 && | ||
| 354 | app.globalData.authenticationStatus == 2 && | ||
| 355 | app.globalData.deptType == 6 && | ||
| 356 | memberInfoData.isPoints == 1 ) { | ||
| 357 | examPointPopup.value?.open() | ||
| 358 | } | ||
| 359 | } | ||
| 360 | |||
| 361 | const onTabSwitch = () => { | ||
| 362 | // tab switch handled by component | ||
| 363 | } | ||
| 364 | </script> | ||
| 365 | |||
| 366 | <style lang="scss" scoped> | ||
| 367 | .person-dashboard { | ||
| 368 | min-height: 100vh; | ||
| 369 | background: #ededf0; | ||
| 370 | overflow: hidden; | ||
| 371 | } | ||
| 372 | |||
| 373 | .hero { | ||
| 374 | position: relative; | ||
| 375 | min-height: 610rpx; | ||
| 376 | padding: calc(env(safe-area-inset-top) + 62rpx) 28rpx 0; | ||
| 377 | overflow: hidden; | ||
| 378 | padding-top: 150rpx; | ||
| 379 | } | ||
| 380 | |||
| 381 | .hero-bg { | ||
| 382 | position: absolute; | ||
| 383 | inset: 0; | ||
| 384 | width: 100%; | ||
| 385 | height: 100%; | ||
| 386 | } | ||
| 387 | |||
| 388 | .hero-nav { | ||
| 389 | position: relative; | ||
| 390 | z-index: 1; | ||
| 391 | display: flex; | ||
| 392 | justify-content: space-between; | ||
| 393 | align-items: flex-end; | ||
| 394 | padding: 0 18rpx; | ||
| 395 | color: #fff; | ||
| 396 | } | ||
| 397 | |||
| 398 | .brand-cn { | ||
| 399 | font-size: 38rpx; | ||
| 400 | letter-spacing: 2rpx; | ||
| 401 | } | ||
| 402 | |||
| 403 | .brand-en { | ||
| 404 | margin-top: 8rpx; | ||
| 405 | font-size: 16rpx; | ||
| 406 | opacity: 0.55; | ||
| 407 | } | ||
| 408 | |||
| 409 | .page-title { | ||
| 410 | color: #f4b536; | ||
| 411 | font-size: 34rpx; | ||
| 412 | font-weight: 500; | ||
| 413 | text-align: right; | ||
| 414 | } | ||
| 415 | |||
| 416 | .title-line { | ||
| 417 | width: 54rpx; | ||
| 418 | height: 6rpx; | ||
| 419 | margin: 12rpx 0 0 auto; | ||
| 420 | background: #f4b536; | ||
| 421 | border-radius: 10rpx; | ||
| 422 | } | ||
| 423 | |||
| 424 | .member-card { | ||
| 425 | position: relative; | ||
| 426 | z-index: 1; | ||
| 427 | height: 460rpx; | ||
| 428 | margin-top: 47rpx; | ||
| 429 | border-radius: 22rpx; | ||
| 430 | overflow: hidden; | ||
| 431 | background: #E2CECF; | ||
| 432 | } | ||
| 433 | |||
| 434 | .member-content { | ||
| 435 | position: relative; | ||
| 436 | z-index: 1; | ||
| 437 | display: flex; | ||
| 438 | justify-content: space-between; | ||
| 439 | padding: 48rpx 46rpx 0; | ||
| 440 | } | ||
| 441 | |||
| 442 | .hello { | ||
| 443 | color: #ff6d40; | ||
| 444 | font-size: 52rpx; | ||
| 445 | line-height: 1; | ||
| 446 | } | ||
| 447 | |||
| 448 | .member-name { | ||
| 449 | margin-top: 28rpx; | ||
| 450 | color: #181818; | ||
| 451 | font-size: 34rpx; | ||
| 452 | font-weight: 700; | ||
| 453 | } | ||
| 454 | |||
| 455 | .member-desc { | ||
| 456 | margin-top: 10rpx; | ||
| 457 | color: #8f817f; | ||
| 458 | font-size: 22rpx; | ||
| 459 | } | ||
| 460 | |||
| 461 | .name-line { | ||
| 462 | width: 112rpx; | ||
| 463 | height: 6rpx; | ||
| 464 | margin-top: 14rpx; | ||
| 465 | background: #111; | ||
| 466 | border-radius: 8rpx; | ||
| 467 | } | ||
| 468 | |||
| 469 | .level-box { | ||
| 470 | display: flex; | ||
| 471 | flex-direction: column; | ||
| 472 | align-items: center; | ||
| 473 | padding-top: 8rpx; | ||
| 474 | } | ||
| 475 | |||
| 476 | .star { | ||
| 477 | width: 100rpx; | ||
| 478 | height: 82rpx; | ||
| 479 | } | ||
| 480 | |||
| 481 | .level-title { | ||
| 482 | margin-top: 12rpx; | ||
| 483 | color: #d99b1d; | ||
| 484 | font-size: 28rpx; | ||
| 485 | font-weight: 700; | ||
| 486 | } | ||
| 487 | |||
| 488 | .detail-btn { | ||
| 489 | margin-top: 8rpx; | ||
| 490 | padding: 4rpx 14rpx; | ||
| 491 | border-radius: 4rpx; | ||
| 492 | background: rgba(255, 255, 255, 0.8); | ||
| 493 | color: #5a5552; | ||
| 494 | font-size: 20rpx; | ||
| 495 | font-weight: 600; | ||
| 496 | } | ||
| 497 | |||
| 498 | .member-bottom { | ||
| 499 | position: relative; | ||
| 500 | z-index: 12; | ||
| 501 | display: flex; | ||
| 502 | gap: 76rpx; | ||
| 503 | grid-column: 1 / -1; | ||
| 504 | padding: 98rpx 46rpx 34rpx; | ||
| 505 | padding-bottom: 50px; | ||
| 506 | } | ||
| 507 | |||
| 508 | .info-label { | ||
| 509 | color: #e55f73; | ||
| 510 | font-size: 24rpx; | ||
| 511 | font-weight: 600; | ||
| 512 | } | ||
| 513 | |||
| 514 | .info-value { | ||
| 515 | margin-top: 6rpx; | ||
| 516 | color: #343434; | ||
| 517 | font-size: 25rpx; | ||
| 518 | } | ||
| 519 | |||
| 520 | .main-actions { | ||
| 521 | position: relative; | ||
| 522 | display: grid; | ||
| 523 | grid-template-columns: repeat(2, 1fr); | ||
| 524 | gap: 8rpx 10rpx; | ||
| 525 | margin-top: -255rpx; | ||
| 526 | padding: 0 28rpx 0; | ||
| 527 | overflow: hidden; | ||
| 528 | } | ||
| 529 | |||
| 530 | .actions-bg { | ||
| 531 | position: absolute; | ||
| 532 | top: 0; | ||
| 533 | left: 0; | ||
| 534 | width: 100%; | ||
| 535 | height: 596rpx; | ||
| 536 | z-index: 9; | ||
| 537 | } | ||
| 538 | |||
| 539 | .action-card { | ||
| 540 | position: relative; | ||
| 541 | z-index: 10; | ||
| 542 | width: 100%; | ||
| 543 | border-radius: 8rpx; | ||
| 544 | } | ||
| 545 | |||
| 546 | .dialog-wrapper { | ||
| 547 | width: 610rpx; | ||
| 548 | padding: 42rpx 34rpx 32rpx; | ||
| 549 | border-radius: 22rpx; | ||
| 550 | background: #fff; | ||
| 551 | box-sizing: border-box; | ||
| 552 | } | ||
| 553 | |||
| 554 | .dialog-title { | ||
| 555 | text-align: center; | ||
| 556 | color: #222; | ||
| 557 | font-size: 34rpx; | ||
| 558 | font-weight: 700; | ||
| 559 | } | ||
| 560 | |||
| 561 | .dialog-message { | ||
| 562 | display: flex; | ||
| 563 | flex-direction: column; | ||
| 564 | gap: 10rpx; | ||
| 565 | margin-top: 26rpx; | ||
| 566 | color: #555; | ||
| 567 | font-size: 28rpx; | ||
| 568 | line-height: 1.6; | ||
| 569 | text-align: center; | ||
| 570 | } | ||
| 571 | |||
| 572 | .dialog-footer { | ||
| 573 | display: flex; | ||
| 574 | gap: 24rpx; | ||
| 575 | margin-top: 36rpx; | ||
| 576 | } | ||
| 577 | |||
| 578 | .dialog-btn { | ||
| 579 | flex: 1; | ||
| 580 | height: 76rpx; | ||
| 581 | border-radius: 40rpx; | ||
| 582 | font-size: 28rpx; | ||
| 583 | line-height: 76rpx; | ||
| 584 | } | ||
| 585 | |||
| 586 | .dialog-btn.cancel { | ||
| 587 | color: #666; | ||
| 588 | background: #f2f2f2; | ||
| 589 | } | ||
| 590 | |||
| 591 | .dialog-btn.confirm { | ||
| 592 | color: #fff; | ||
| 593 | background: #ad181f; | ||
| 594 | } | ||
| 595 | |||
| 596 | .no-display { | ||
| 597 | margin-top: 24rpx; | ||
| 598 | color: #999; | ||
| 599 | font-size: 24rpx; | ||
| 600 | text-align: center; | ||
| 601 | } | ||
| 602 | </style> |
| ... | @@ -552,13 +552,14 @@ | ... | @@ -552,13 +552,14 @@ |
| 552 | <uni-popup ref="examPointPopup" :mask-click="false" type="center"> | 552 | <uni-popup ref="examPointPopup" :mask-click="false" type="center"> |
| 553 | <view class="dialog-wrapper exam-dialog"> | 553 | <view class="dialog-wrapper exam-dialog"> |
| 554 | <view class="dialog-close" @click="closeExamPointDialog">✕</view> | 554 | <view class="dialog-close" @click="closeExamPointDialog">✕</view> |
| 555 | <view class="dialog-icon success-icon"> | 555 | <view class="dialog-icon success-icon"> |
| 556 | <uni-icons color="#29c490" size="48" type="checkmark"></uni-icons> | 556 | <uni-icons color="#ffffff" size="40" type="check"></uni-icons> |
| 557 | </view> | 557 | </view> |
| 558 | <view class="dialog-title">申请成为考点</view> | 558 | <view class="dialog-title">申请成为考点</view> |
| 559 | <view class="dialog-message"> | 559 | <view class="dialog-message"> |
| 560 | <text>恭喜您成为中国跆拳道协会团体会员!</text> | 560 | <text>恭喜您成为中国跆拳道协会单位会员!</text> |
| 561 | <text>根据协会考点管理办法,需成为考点单位才能进行考级业务的办理。</text> | 561 | <text>根据协会考点管理办法,需成为考点单位才能进行考级业务的办理。</text> |
| 562 | <text>是否现在申请成为考点?</text> | ||
| 562 | </view> | 563 | </view> |
| 563 | <view class="dialog-footer"> | 564 | <view class="dialog-footer"> |
| 564 | <button class="dialog-btn cancel" @click="closeExamPointDialog">取消</button> | 565 | <button class="dialog-btn cancel" @click="closeExamPointDialog">取消</button> |
| ... | @@ -1049,11 +1050,11 @@ function checkDialogs() { | ... | @@ -1049,11 +1050,11 @@ function checkDialogs() { |
| 1049 | refreshCaptcha() | 1050 | refreshCaptcha() |
| 1050 | bindingPhonePopup.value.open() | 1051 | bindingPhonePopup.value.open() |
| 1051 | } | 1052 | } |
| 1053 | console.log(99,app.globalData.memberInfo?.activeStatus,app.globalData.authenticationStatus,user.hintFlag,app.globalData.deptType,memberInfoData.isPoints,app.globalData.deptType) | ||
| 1052 | 1054 | ||
| 1053 | // 申请考点条件: activeStatus=1 && authenticationStatus=2 && hintFlag=1 && deptType=6 && isPoints=1 | 1055 | // 申请考点条件: activeStatus=1 && authenticationStatus=2 && hintFlag=1 && deptType=6 && isPoints=1 |
| 1054 | if (app.globalData.memberInfo?.activeStatus == 1 && | 1056 | if (app.globalData.memberInfo?.activeStatus == 1 && |
| 1055 | app.globalData.authenticationStatus == 2 && | 1057 | app.globalData.authenticationStatus == 2 && |
| 1056 | user.hintFlag == 1 && | ||
| 1057 | app.globalData.deptType == 6 && | 1058 | app.globalData.deptType == 6 && |
| 1058 | memberInfoData.isPoints == 1) { | 1059 | memberInfoData.isPoints == 1) { |
| 1059 | examPointPopup.value.open() | 1060 | examPointPopup.value.open() |
| ... | @@ -1481,7 +1482,7 @@ function checkDialogs() { | ... | @@ -1481,7 +1482,7 @@ function checkDialogs() { |
| 1481 | } | 1482 | } |
| 1482 | 1483 | ||
| 1483 | .success-icon { | 1484 | .success-icon { |
| 1484 | color: #29c490; | 1485 | color: #29c490; |
| 1485 | } | 1486 | } |
| 1486 | 1487 | ||
| 1487 | /* 密码提示弹框样式 */ | 1488 | /* 密码提示弹框样式 */ | ... | ... |
| ... | @@ -13,7 +13,8 @@ | ... | @@ -13,7 +13,8 @@ |
| 13 | useUserStore | 13 | useUserStore |
| 14 | } from '../../store/modules/user'; | 14 | } from '../../store/modules/user'; |
| 15 | 15 | ||
| 16 | const userStore = useUserStore() | 16 | const userStore = useUserStore() |
| 17 | const app = getApp() | ||
| 17 | 18 | ||
| 18 | onShow(() => { | 19 | onShow(() => { |
| 19 | let user = userStore.user | 20 | let user = userStore.user |
| ... | @@ -25,11 +26,21 @@ | ... | @@ -25,11 +26,21 @@ |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | let userName = uni.getStorageSync('userName') | 28 | let userName = uni.getStorageSync('userName') |
| 29 | console.log('userName', userName) | ||
| 30 | console.log('app.globalData.userType ', app.globalData.userType ) | ||
| 28 | if (userName) { | 31 | if (userName) { |
| 29 | uni.reLaunch({ | 32 | if(app.globalData.userType == 4){ |
| 33 | uni.reLaunch({ | ||
| 34 | url: '/pages/index/daoGuanPerson' | ||
| 35 | }) | ||
| 36 | return | ||
| 37 | }else{ | ||
| 38 | uni.reLaunch({ | ||
| 30 | url: '/pages/index/home' | 39 | url: '/pages/index/home' |
| 31 | }) | 40 | }) |
| 32 | return | 41 | return |
| 42 | } | ||
| 43 | |||
| 33 | } | 44 | } |
| 34 | 45 | ||
| 35 | let webUserName = uni.getStorageSync('webUserName') | 46 | let webUserName = uni.getStorageSync('webUserName') |
| ... | @@ -43,4 +54,4 @@ | ... | @@ -43,4 +54,4 @@ |
| 43 | </script> | 54 | </script> |
| 44 | <style scope lang="scss"> | 55 | <style scope lang="scss"> |
| 45 | 56 | ||
| 46 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 57 | </style> | ... | ... |
| ... | @@ -204,7 +204,6 @@ import { | ... | @@ -204,7 +204,6 @@ import { |
| 204 | import config from "/config.js"; | 204 | import config from "/config.js"; |
| 205 | import { | 205 | import { |
| 206 | wxLogin, | 206 | wxLogin, |
| 207 | logout, | ||
| 208 | getWebInfo | 207 | getWebInfo |
| 209 | } from '@/common/login.js'; | 208 | } from '@/common/login.js'; |
| 210 | import {useUserStore} from "@/store/modules/user.js"; | 209 | import {useUserStore} from "@/store/modules/user.js"; |
| ... | @@ -238,6 +237,9 @@ const showConfirm = ref(false) | ... | @@ -238,6 +237,9 @@ const showConfirm = ref(false) |
| 238 | let hasOpenedBindPopup = false | 237 | let hasOpenedBindPopup = false |
| 239 | 238 | ||
| 240 | onShow(() => { | 239 | onShow(() => { |
| 240 | // 重置绑定弹框标志,确保每次进入页面都能正确弹出 | ||
| 241 | hasOpenedBindPopup = false | ||
| 242 | |||
| 241 | let webUserName = uni.getStorageSync('webUserName') | 243 | let webUserName = uni.getStorageSync('webUserName') |
| 242 | if (!webUserName) { | 244 | if (!webUserName) { |
| 243 | // 登录后需要等待数据加载完成 | 245 | // 登录后需要等待数据加载完成 |
| ... | @@ -245,7 +247,13 @@ onShow(() => { | ... | @@ -245,7 +247,13 @@ onShow(() => { |
| 245 | getWebInfo().then(() => { | 247 | getWebInfo().then(() => { |
| 246 | // 数据加载完成后检查是否需要弹出绑定框 | 248 | // 数据加载完成后检查是否需要弹出绑定框 |
| 247 | checkAndOpenBindPopup() | 249 | checkAndOpenBindPopup() |
| 250 | }).catch(() => { | ||
| 251 | // getWebInfo 失败时也检查一下 | ||
| 252 | checkAndOpenBindPopup() | ||
| 248 | }) | 253 | }) |
| 254 | }).catch(() => { | ||
| 255 | // wxLogin 失败时也检查一下 | ||
| 256 | checkAndOpenBindPopup() | ||
| 249 | }) | 257 | }) |
| 250 | } else { | 258 | } else { |
| 251 | // 已登录,直接检查 | 259 | // 已登录,直接检查 |
| ... | @@ -516,14 +524,23 @@ const cancelLogout = () => { | ... | @@ -516,14 +524,23 @@ const cancelLogout = () => { |
| 516 | }; | 524 | }; |
| 517 | 525 | ||
| 518 | // 确认退出登录 | 526 | // 确认退出登录 |
| 519 | const confirmLogout = () => { | 527 | const confirmLogout = async () => { |
| 520 | // 调用退出登录接口 | 528 | showConfirm.value = false |
| 521 | logout().then(() => { | 529 | |
| 522 | // 跳转到登录页 | 530 | uni.showLoading({ title: '退出中...', mask: true }) |
| 523 | uni.reLaunch({ | 531 | |
| 524 | url: '/login/login' | 532 | // 调用解绑接口 |
| 525 | }) | 533 | await to(unbindUser()) |
| 526 | }); | 534 | |
| 535 | // 清除缓存和用户信息 | ||
| 536 | uni.removeStorageSync('webUserName') | ||
| 537 | userStore.setPerInfo(null) | ||
| 538 | userStore.setUser(null) | ||
| 539 | |||
| 540 | // 跳转到登录页 | ||
| 541 | uni.reLaunch({ | ||
| 542 | url: '/login/login' | ||
| 543 | }) | ||
| 527 | }; | 544 | }; |
| 528 | </script> | 545 | </script> |
| 529 | 546 | ... | ... |
| 1 | <template> | 1 | <template> |
| 2 | <view> | 2 | <view class="change-level-page"> |
| 3 | <view class="searchbar"> | 3 | <view class="page-hero"> |
| 4 | <uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search" | 4 | <view class="hero-title-row"> |
| 5 | v-model="queryParams.code" placeholder="搜索变更单号" @blur="getList" @clear="getList"> | 5 | <view> |
| 6 | </uni-easyinput> | 6 | <view class="hero-title">中国跆拳道协会</view> |
| 7 | <view class="invertedbtn-red" @click="goAdd">+ 新建级位变更</view> | 7 | <view class="hero-subtitle">CHINESE TAEKWONDO ASSOCIATION</view> |
| 8 | </view> | 8 | </view> |
| 9 | 9 | <view class="hero-page-title"> | |
| 10 | <view class="appList"> | 10 | <text>级位变更审核</text> |
| 11 | <view class="appItem" v-for="(item,index) in list" :key="index"> | 11 | <view class="title-line"></view> |
| 12 | <view class="status" @click="goDetail(item)"> | 12 | </view> |
| 13 | <view> | 13 | </view> |
| 14 | <text v-if="item.status == 0" class="text-warning">待提交</text> | 14 | |
| 15 | <text v-if="item.status == 1" class="text-primary">审核中</text> | 15 | <view class="search-row"> |
| 16 | <text v-if="item.status == 2" class="text-success">审核通过</text> | 16 | <view class="search-box"> |
| 17 | <text v-if="item.status == 3" class="text-danger">审核拒绝</text> | 17 | <uni-easyinput |
| 18 | <text v-if="item.status == 4" class="text-warning">已撤回</text> | 18 | v-model="queryParams.code" |
| 19 | </view> | 19 | :input-border="false" |
| 20 | </view> | 20 | class="search-input" |
| 21 | 21 | placeholder="输入变更单号" | |
| 22 | <view class="name mt0" @click="goDetail(item)"> | 22 | placeholderStyle="font-size:28rpx;color:#999" |
| 23 | <text class="text-primary">{{item.code}}</text>-{{item.shenMemName}} | 23 | prefixIcon="search" |
| 24 | </view> | 24 | @confirm="getList" |
| 25 | <view class="flexbox" @click="goDetail(item)"> | 25 | @clear="getList" |
| 26 | <view> | 26 | /> |
| 27 | 变更人数 | 27 | <view class="search-btn" @click="getList">搜索</view> |
| 28 | <view> | 28 | </view> |
| 29 | <text class="text-danger">{{item.count}}人</text> | 29 | <view class="add-btn" @click="goAdd"> |
| 30 | </view> | 30 | <text class="add-icon">+</text> |
| 31 | 31 | <text>新建变更</text> | |
| 32 | </view> | 32 | </view> |
| 33 | 33 | </view> | |
| 34 | <view class="w50"> | 34 | </view> |
| 35 | 提交时间 | 35 | |
| 36 | <view>{{item.commitTime||'--'}}</view> | 36 | <view class="status-tabs"> |
| 37 | </view> | 37 | <view |
| 38 | </view> | 38 | v-for="tab in statusTabs" |
| 39 | <view class="func" v-if="(item.status==0||item.status==3||item.status==4)"> | 39 | :key="tab.value" |
| 40 | <button @click="handleUpdate(item)">编辑</button> | 40 | class="status-tab" |
| 41 | <button @click="commitFN(item)">提交审核</button> | 41 | :class="{ active: activeStatus === tab.value }" |
| 42 | <button @click="handleDelete(item)">删除</button> | 42 | @click="switchStatus(tab.value)" |
| 43 | </view> | 43 | > |
| 44 | 44 | {{ tab.label }} | |
| 45 | </view> | 45 | </view> |
| 46 | </view> | 46 | </view> |
| 47 | 47 | ||
| 48 | 48 | <scroll-view scroll-y class="list-scroll"> | |
| 49 | 49 | <view class="card-list"> | |
| 50 | <view class="nodata" v-if="list.length==0"> | 50 | <view v-for="item in list" :key="item.id" class="change-card"> |
| 51 | <image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image> | 51 | <view class="card-top"> |
| 52 | <text>暂无数据</text> | 52 | <view class="code-line">编号:{{ item.code || '--' }}</view> |
| 53 | </view> | 53 | <view class="status-text" :class="statusClass(item.status)">{{ statusText(item.status) }}</view> |
| 54 | </view> | 54 | </view> |
| 55 | |||
| 56 | <view class="org-name">{{ item.shenMemName || '--' }}</view> | ||
| 57 | |||
| 58 | <view class="info-grid"> | ||
| 59 | <view class="info-cell"> | ||
| 60 | <view class="info-label">变更人数</view> | ||
| 61 | <view class="info-value">{{ item.count || 0 }}</view> | ||
| 62 | </view> | ||
| 63 | <view class="info-cell time-cell"> | ||
| 64 | <view class="info-label">变更时间</view> | ||
| 65 | <view class="info-value">{{ item.commitTime || '--' }}</view> | ||
| 66 | </view> | ||
| 67 | </view> | ||
| 68 | |||
| 69 | <view class="card-actions"> | ||
| 70 | <view class="detail-link" @click="goDetail(item)">查看详情></view> | ||
| 71 | <view class="action-buttons"> | ||
| 72 | <button class="action-btn delete" :disabled="!canEdit(item)" @click.stop="handleDelete(item)">删除</button> | ||
| 73 | <button class="action-btn edit" :disabled="!canEdit(item)" @click.stop="handleUpdate(item)">编辑</button> | ||
| 74 | <button class="action-btn submit" :disabled="!canEdit(item)" @click.stop="commitFN(item)">提交审核</button> | ||
| 75 | </view> | ||
| 76 | </view> | ||
| 77 | </view> | ||
| 78 | |||
| 79 | <view v-if="list.length === 0" class="nodata"> | ||
| 80 | <image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image> | ||
| 81 | <text>暂无数据</text> | ||
| 82 | </view> | ||
| 83 | </view> | ||
| 84 | </scroll-view> | ||
| 85 | </view> | ||
| 55 | </template> | 86 | </template> |
| 56 | 87 | ||
| 57 | <script setup> | 88 | <script setup> |
| 58 | import * as api from '@/common/api.js' | 89 | import * as api from '@/common/api.js' |
| 59 | import config from '@/config.js' | 90 | import config from '@/config.js' |
| 60 | import { | 91 | import { ref } from 'vue' |
| 61 | ref | 92 | import { onShow } from '@dcloudio/uni-app' |
| 62 | } from 'vue' | 93 | |
| 63 | import { | 94 | const queryParams = ref({ |
| 64 | onLoad, | 95 | code: '', |
| 65 | onShow | 96 | status: '' |
| 66 | } from '@dcloudio/uni-app' | 97 | }) |
| 67 | const app = getApp(); | 98 | const list = ref([]) |
| 68 | const queryParams = ref({ | 99 | const total = ref(0) |
| 69 | code:'' | 100 | const activeStatus = ref('') |
| 70 | }) | 101 | const statusTabs = [ |
| 71 | const list = ref([]) | 102 | { label: '全部', value: '' }, |
| 72 | const total = ref(0) | 103 | { label: '待提交', value: '0' }, |
| 73 | onShow(()=>{ | 104 | { label: '审核中', value: '1' }, |
| 74 | getList() | 105 | { label: '已通过', value: '2' }, |
| 75 | }) | 106 | { label: '已拒绝', value: '3' } |
| 76 | function goAdd(){ | 107 | ] |
| 77 | let path = `/personalVip/addChangeLevel` | 108 | |
| 78 | uni.navigateTo({ | 109 | onShow(() => { |
| 79 | url: path | 110 | getList() |
| 80 | }); | 111 | }) |
| 81 | } | 112 | |
| 82 | function getList(){ | 113 | function switchStatus(status) { |
| 83 | uni.showLoading({ | 114 | activeStatus.value = status |
| 84 | title:'加载中' | 115 | queryParams.value.status = status |
| 85 | }) | 116 | getList() |
| 86 | api.getChangelevelList(queryParams.value).then(res=>{ | 117 | } |
| 87 | list.value = res.rows | 118 | |
| 88 | total.value = res.total | 119 | function statusText(status) { |
| 89 | uni.hideLoading() | 120 | const map = { |
| 90 | }) | 121 | 0: '待提交', |
| 91 | } | 122 | 1: '审核中', |
| 92 | function goDetail(item){ | 123 | 2: '已通过', |
| 93 | let path = `/personalVip/changeLevelDetail?rangeId=${item.id}` | 124 | 3: '已拒绝', |
| 94 | uni.navigateTo({ | 125 | 4: '已撤回' |
| 95 | url: path | 126 | } |
| 96 | }); | 127 | return map[status] || '' |
| 97 | } | 128 | } |
| 98 | function handleUpdate(item){ | 129 | |
| 99 | // 编辑 | 130 | function statusClass(status) { |
| 100 | let path = `/personalVip/addChangeLevel?rangeId=${item.id}` | 131 | const map = { |
| 101 | uni.navigateTo({ | 132 | 0: 'pending', |
| 102 | url: path | 133 | 1: 'reviewing', |
| 103 | }); | 134 | 2: 'passed', |
| 104 | } | 135 | 3: 'rejected', |
| 105 | function commitFN(row){ | 136 | 4: 'pending' |
| 106 | uni.showModal({ | 137 | } |
| 107 | title: '提示', | 138 | return map[status] || '' |
| 108 | content: `确定提交吗`, | 139 | } |
| 109 | success: function(res) { | 140 | |
| 110 | if (res.confirm) { | 141 | function canEdit(item) { |
| 111 | api.commitLevelChange(row.id).then(Response=>{ | 142 | return item.status == 0 || item.status == 3 || item.status == 4 |
| 112 | uni.showToast({ | 143 | } |
| 113 | icon:"none", | 144 | |
| 114 | title:'提交成功!' | 145 | function goAdd() { |
| 115 | }) | 146 | uni.navigateTo({ |
| 116 | getList() | 147 | url: '/personalVip/addChangeLevel' |
| 117 | }) | 148 | }) |
| 118 | } | 149 | } |
| 119 | } | ||
| 120 | }) | ||
| 121 | } | ||
| 122 | function handleDelete(row){ | ||
| 123 | uni.showModal({ | ||
| 124 | title: '提示', | ||
| 125 | content: `确定删除吗`, | ||
| 126 | success: function(res) { | ||
| 127 | if (res.confirm) { | ||
| 128 | api.levelModRangeDelete([row.id]).then(Response=>{ | ||
| 129 | uni.showToast({ | ||
| 130 | icon:"none", | ||
| 131 | title:'删除成功!' | ||
| 132 | }) | ||
| 133 | getList() | ||
| 134 | }) | ||
| 135 | } | ||
| 136 | } | ||
| 137 | }) | ||
| 138 | } | ||
| 139 | 150 | ||
| 151 | function getList() { | ||
| 152 | uni.showLoading({ | ||
| 153 | title: '加载中' | ||
| 154 | }) | ||
| 155 | api.getChangelevelList(queryParams.value).then(res => { | ||
| 156 | list.value = res.rows || [] | ||
| 157 | total.value = res.total || 0 | ||
| 158 | }).finally(() => { | ||
| 159 | uni.hideLoading() | ||
| 160 | }) | ||
| 161 | } | ||
| 162 | |||
| 163 | function goDetail(item) { | ||
| 164 | uni.navigateTo({ | ||
| 165 | url: `/personalVip/changeLevelDetail?rangeId=${item.id}` | ||
| 166 | }) | ||
| 167 | } | ||
| 168 | |||
| 169 | function handleUpdate(item) { | ||
| 170 | uni.navigateTo({ | ||
| 171 | url: `/personalVip/addChangeLevel?rangeId=${item.id}` | ||
| 172 | }) | ||
| 173 | } | ||
| 174 | |||
| 175 | function commitFN(row) { | ||
| 176 | uni.showModal({ | ||
| 177 | title: '提示', | ||
| 178 | content: '确定提交吗', | ||
| 179 | success: function(res) { | ||
| 180 | if (res.confirm) { | ||
| 181 | api.commitLevelChange(row.id).then(() => { | ||
| 182 | uni.showToast({ | ||
| 183 | icon: 'none', | ||
| 184 | title: '提交成功!' | ||
| 185 | }) | ||
| 186 | getList() | ||
| 187 | }) | ||
| 188 | } | ||
| 189 | } | ||
| 190 | }) | ||
| 191 | } | ||
| 192 | |||
| 193 | function handleDelete(row) { | ||
| 194 | uni.showModal({ | ||
| 195 | title: '提示', | ||
| 196 | content: '确定删除吗', | ||
| 197 | success: function(res) { | ||
| 198 | if (res.confirm) { | ||
| 199 | api.levelModRangeDelete([row.id]).then(() => { | ||
| 200 | uni.showToast({ | ||
| 201 | icon: 'none', | ||
| 202 | title: '删除成功!' | ||
| 203 | }) | ||
| 204 | getList() | ||
| 205 | }) | ||
| 206 | } | ||
| 207 | } | ||
| 208 | }) | ||
| 209 | } | ||
| 140 | </script> | 210 | </script> |
| 141 | 211 | ||
| 142 | <style lang='scss' scoped> | 212 | <style lang="scss" scoped> |
| 143 | .searchbar { | 213 | .change-level-page { |
| 144 | display: flex; | 214 | min-height: 100vh; |
| 145 | align-items: center; | 215 | background: #ededf0; |
| 146 | padding: 25rpx; | 216 | overflow: hidden; |
| 147 | box-sizing: border-box; | 217 | } |
| 218 | |||
| 219 | .page-hero { | ||
| 220 | padding: calc(env(safe-area-inset-top) + 88rpx) 36rpx 28rpx; | ||
| 221 | background: linear-gradient(135deg, #b00005 0%, #760000 100%); | ||
| 222 | color: #fff; | ||
| 223 | } | ||
| 224 | |||
| 225 | .hero-title-row { | ||
| 226 | display: flex; | ||
| 227 | align-items: flex-end; | ||
| 228 | justify-content: space-between; | ||
| 229 | margin-bottom: 40rpx; | ||
| 230 | } | ||
| 231 | |||
| 232 | .hero-title { | ||
| 233 | font-size: 38rpx; | ||
| 234 | letter-spacing: 2rpx; | ||
| 235 | } | ||
| 236 | |||
| 237 | .hero-subtitle { | ||
| 238 | margin-top: 8rpx; | ||
| 239 | color: rgba(255, 255, 255, 0.62); | ||
| 240 | font-size: 16rpx; | ||
| 241 | } | ||
| 242 | |||
| 243 | .hero-page-title { | ||
| 244 | color: #f4b536; | ||
| 245 | font-size: 36rpx; | ||
| 246 | font-weight: 500; | ||
| 247 | text-align: right; | ||
| 248 | } | ||
| 249 | |||
| 250 | .title-line { | ||
| 251 | width: 54rpx; | ||
| 252 | height: 6rpx; | ||
| 253 | margin: 14rpx 0 0 auto; | ||
| 254 | border-radius: 10rpx; | ||
| 255 | background: #f4b536; | ||
| 256 | } | ||
| 257 | |||
| 258 | .search-row { | ||
| 259 | display: flex; | ||
| 260 | align-items: center; | ||
| 261 | gap: 16rpx; | ||
| 262 | } | ||
| 263 | |||
| 264 | .search-box { | ||
| 265 | flex: 1; | ||
| 266 | display: flex; | ||
| 267 | align-items: center; | ||
| 268 | height: 64rpx; | ||
| 269 | overflow: hidden; | ||
| 270 | border-radius: 34rpx; | ||
| 271 | background: #fff; | ||
| 272 | } | ||
| 273 | |||
| 274 | .search-input { | ||
| 275 | flex: 1; | ||
| 276 | |||
| 277 | :deep(.uni-easyinput__content) { | ||
| 278 | height: 64rpx; | ||
| 279 | padding: 0 12rpx 0 22rpx; | ||
| 280 | border-radius: 34rpx; | ||
| 281 | background: #fff; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | .search-btn { | ||
| 286 | width: 88rpx; | ||
| 287 | height: 52rpx; | ||
| 288 | margin-right: 6rpx; | ||
| 289 | border-radius: 28rpx; | ||
| 290 | background: #c91c34; | ||
| 291 | color: #fff; | ||
| 292 | font-size: 24rpx; | ||
| 293 | font-weight: 700; | ||
| 294 | line-height: 52rpx; | ||
| 295 | text-align: center; | ||
| 296 | } | ||
| 297 | |||
| 298 | .add-btn { | ||
| 299 | display: flex; | ||
| 300 | align-items: center; | ||
| 301 | justify-content: center; | ||
| 302 | width: 194rpx; | ||
| 303 | height: 64rpx; | ||
| 304 | border-radius: 34rpx; | ||
| 305 | background: #fff; | ||
| 306 | color: #222; | ||
| 307 | font-size: 28rpx; | ||
| 308 | font-weight: 700; | ||
| 309 | } | ||
| 310 | |||
| 311 | .add-icon { | ||
| 312 | margin-right: 6rpx; | ||
| 313 | color: #c30d23; | ||
| 314 | font-size: 40rpx; | ||
| 315 | line-height: 1; | ||
| 316 | } | ||
| 317 | |||
| 318 | .status-tabs { | ||
| 319 | display: flex; | ||
| 320 | align-items: center; | ||
| 321 | justify-content: space-around; | ||
| 322 | height: 92rpx; | ||
| 323 | background: #fff; | ||
| 324 | } | ||
| 325 | |||
| 326 | .status-tab { | ||
| 327 | position: relative; | ||
| 328 | height: 92rpx; | ||
| 329 | color: #666; | ||
| 330 | font-size: 30rpx; | ||
| 331 | font-weight: 700; | ||
| 332 | line-height: 92rpx; | ||
| 333 | } | ||
| 334 | |||
| 335 | .status-tab.active { | ||
| 336 | color: #c30d23; | ||
| 337 | } | ||
| 338 | |||
| 339 | .status-tab.active::after { | ||
| 340 | content: ''; | ||
| 341 | position: absolute; | ||
| 342 | left: 50%; | ||
| 343 | bottom: 18rpx; | ||
| 344 | width: 54rpx; | ||
| 345 | height: 4rpx; | ||
| 346 | border-radius: 4rpx; | ||
| 347 | background: #c30d23; | ||
| 348 | transform: translateX(-50%); | ||
| 349 | } | ||
| 350 | |||
| 351 | .list-scroll { | ||
| 352 | height: calc(100vh - 364rpx); | ||
| 353 | } | ||
| 354 | |||
| 355 | .card-list { | ||
| 356 | padding: 22rpx 30rpx 40rpx; | ||
| 357 | } | ||
| 358 | |||
| 359 | .change-card { | ||
| 360 | margin-bottom: 20rpx; | ||
| 361 | padding: 20rpx 20rpx 18rpx; | ||
| 362 | border-radius: 18rpx; | ||
| 363 | background: #fff; | ||
| 364 | } | ||
| 365 | |||
| 366 | .card-top { | ||
| 367 | display: flex; | ||
| 368 | align-items: center; | ||
| 369 | justify-content: space-between; | ||
| 370 | } | ||
| 371 | |||
| 372 | .code-line { | ||
| 373 | color: #0076ce; | ||
| 374 | font-size: 26rpx; | ||
| 375 | } | ||
| 376 | |||
| 377 | .status-text { | ||
| 378 | font-size: 26rpx; | ||
| 379 | font-weight: 700; | ||
| 380 | } | ||
| 381 | |||
| 382 | .status-text.pending { | ||
| 383 | color: #f0a000; | ||
| 384 | } | ||
| 385 | |||
| 386 | .status-text.reviewing { | ||
| 387 | color: #0076ce; | ||
| 388 | } | ||
| 389 | |||
| 390 | .status-text.passed { | ||
| 391 | color: #28a745; | ||
| 392 | } | ||
| 393 | |||
| 394 | .status-text.rejected { | ||
| 395 | color: #e60012; | ||
| 396 | } | ||
| 397 | |||
| 398 | .org-name { | ||
| 399 | margin-top: 8rpx; | ||
| 400 | color: #333; | ||
| 401 | font-size: 30rpx; | ||
| 402 | } | ||
| 403 | |||
| 404 | .info-grid { | ||
| 405 | display: grid; | ||
| 406 | grid-template-columns: 1fr 1.5fr; | ||
| 407 | margin-top: 18rpx; | ||
| 408 | } | ||
| 409 | |||
| 410 | .info-label { | ||
| 411 | color: #999; | ||
| 412 | font-size: 24rpx; | ||
| 413 | } | ||
| 414 | |||
| 415 | .info-value { | ||
| 416 | margin-top: 4rpx; | ||
| 417 | color: #555; | ||
| 418 | font-size: 34rpx; | ||
| 419 | line-height: 1.2; | ||
| 420 | } | ||
| 421 | |||
| 422 | .time-cell .info-value { | ||
| 423 | font-size: 32rpx; | ||
| 424 | } | ||
| 425 | |||
| 426 | .card-actions { | ||
| 427 | display: flex; | ||
| 428 | align-items: center; | ||
| 429 | justify-content: space-between; | ||
| 430 | margin-top: 20rpx; | ||
| 431 | } | ||
| 432 | |||
| 433 | .detail-link { | ||
| 434 | color: #333; | ||
| 435 | font-size: 24rpx; | ||
| 436 | font-weight: 700; | ||
| 437 | } | ||
| 438 | |||
| 439 | .action-buttons { | ||
| 440 | display: flex; | ||
| 441 | align-items: center; | ||
| 442 | gap: 16rpx; | ||
| 443 | } | ||
| 444 | |||
| 445 | .action-btn { | ||
| 446 | width: 112rpx; | ||
| 447 | height: 42rpx; | ||
| 448 | margin: 0; | ||
| 449 | padding: 0; | ||
| 450 | border-radius: 10rpx; | ||
| 451 | background: #fff; | ||
| 452 | font-size: 24rpx; | ||
| 453 | line-height: 42rpx; | ||
| 454 | |||
| 455 | &::after { | ||
| 456 | border: none; | ||
| 457 | } | ||
| 458 | } | ||
| 459 | |||
| 460 | .action-btn.delete { | ||
| 461 | color: #e60012; | ||
| 462 | border: 1rpx solid #e60012; | ||
| 463 | } | ||
| 148 | 464 | ||
| 149 | :deep(.uni-easyinput .uni-easyinput__content) { | 465 | .action-btn.edit { |
| 150 | border-radius: 35rpx; | 466 | color: #333; |
| 151 | border: none; | 467 | border: 1rpx solid #999; |
| 152 | height: 70rpx; | 468 | } |
| 153 | } | ||
| 154 | 469 | ||
| 155 | :deep(.uni-easyinput__content-input) { | 470 | .action-btn.submit { |
| 156 | font-size: 26rpx; | 471 | color: #0076ce; |
| 157 | } | 472 | border: 1rpx solid #0076ce; |
| 473 | } | ||
| 158 | 474 | ||
| 159 | .invertedbtn-red { | 475 | .action-btn[disabled] { |
| 160 | border-radius: 50px; | 476 | color: #c9c9c9; |
| 161 | background-color: #fff; | 477 | border-color: #e1e1e1; |
| 478 | background: #fff; | ||
| 479 | } | ||
| 162 | 480 | ||
| 163 | font-size: 30rpx; | 481 | .nodata { |
| 164 | padding: 10rpx 20rpx; | 482 | display: flex; |
| 165 | } | 483 | flex-direction: column; |
| 166 | } | 484 | align-items: center; |
| 485 | padding-top: 120rpx; | ||
| 486 | color: #999; | ||
| 487 | font-size: 28rpx; | ||
| 167 | 488 | ||
| 489 | image { | ||
| 490 | width: 220rpx; | ||
| 491 | height: 220rpx; | ||
| 492 | margin-bottom: 20rpx; | ||
| 493 | } | ||
| 494 | } | ||
| 168 | </style> | 495 | </style> | ... | ... |
| 1 | <template> | 1 | <template> |
| 2 | <view class="hasfixedbottom"> | 2 | <view class="hasfixedbottom"> |
| 3 | <view class="searchbar"> | 3 | <view class="searchbar"> |
| 4 | |||
| 4 | <uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search" | 5 | <uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search" |
| 5 | v-model="queryParams.perName" placeholder="搜索姓名或证件号码" @blur="getList" @clear="getList"> | 6 | v-model="queryParams.perName" placeholder="搜索姓名或证件号码" @blur="getList" @clear="getList"> |
| 6 | </uni-easyinput> | 7 | </uni-easyinput> |
| 7 | <view class="invertedbtn-red" @click="goVipList">+ 添加会员</view> | 8 | <view class="invertedbtn-red" @click="showAddPopup">+ 添加</view> |
| 9 | <view class="invertedbtn-red" @click="goVipList">+ 在线选择</view> | ||
| 8 | </view> | 10 | </view> |
| 9 | <view style="padding:0 20rpx"> | 11 | <view style="padding:0 20rpx"> |
| 10 | 12 | ||
| ... | @@ -58,6 +60,33 @@ | ... | @@ -58,6 +60,33 @@ |
| 58 | </view> | 60 | </view> |
| 59 | </view> | 61 | </view> |
| 60 | </uni-popup> | 62 | </uni-popup> |
| 63 | |||
| 64 | <!-- 添加会员弹框 --> | ||
| 65 | <uni-popup ref="addPopup" type="center"> | ||
| 66 | <view class="add-popup"> | ||
| 67 | <view class="popup-title">添加会员</view> | ||
| 68 | <view class="popup-form"> | ||
| 69 | <view class="form-item"> | ||
| 70 | <view class="form-label">证件类型</view> | ||
| 71 | <view class="form-input"> | ||
| 72 | <picker :value="idcListIndex" :range="idcList" range-key="label" @change="onIdcTypeChange"> | ||
| 73 | <view class="picker-value">{{ idcList[idcListIndex]?.label }}</view> | ||
| 74 | </picker> | ||
| 75 | </view> | ||
| 76 | </view> | ||
| 77 | <view class="form-item"> | ||
| 78 | <view class="form-label">证件号</view> | ||
| 79 | <view class="form-input"> | ||
| 80 | <input v-model="addForm.idcCode" placeholder="请输入证件号" placeholder-class="placeholder-class"/> | ||
| 81 | </view> | ||
| 82 | </view> | ||
| 83 | </view> | ||
| 84 | <view class="popup-btns"> | ||
| 85 | <view class="popup-btn cancel" @click="closeAddPopup">取消</view> | ||
| 86 | <view class="popup-btn confirm" @click="confirmAdd">确定</view> | ||
| 87 | </view> | ||
| 88 | </view> | ||
| 89 | </uni-popup> | ||
| 61 | </view> | 90 | </view> |
| 62 | </template> | 91 | </template> |
| 63 | 92 | ||
| ... | @@ -78,7 +107,18 @@ | ... | @@ -78,7 +107,18 @@ |
| 78 | const nowYear = ref(1) | 107 | const nowYear = ref(1) |
| 79 | const nowItem = ref({}) | 108 | const nowItem = ref({}) |
| 80 | const pickView = ref(null) | 109 | const pickView = ref(null) |
| 110 | const addPopup = ref(null) | ||
| 81 | const visible = ref(true) | 111 | const visible = ref(true) |
| 112 | const addForm = ref({ | ||
| 113 | idcCode: '', | ||
| 114 | idType: '0' | ||
| 115 | }) | ||
| 116 | const idcList = ref([ | ||
| 117 | { label: '身份证', value: '0' }, | ||
| 118 | { label: '来往大陆(内地)通行证', value: '1' }, | ||
| 119 | { label: '香港身份证', value: '5' } | ||
| 120 | ]) | ||
| 121 | const idcListIndex = ref(0) | ||
| 82 | const yearlist = ref([{ | 122 | const yearlist = ref([{ |
| 83 | text: '一年', | 123 | text: '一年', |
| 84 | value: 1 | 124 | value: 1 |
| ... | @@ -197,6 +237,50 @@ | ... | @@ -197,6 +237,50 @@ |
| 197 | url: `/myCenter/payOrder?rangeId=${queryParams.value.rangeId}` | 237 | url: `/myCenter/payOrder?rangeId=${queryParams.value.rangeId}` |
| 198 | }) | 238 | }) |
| 199 | } | 239 | } |
| 240 | |||
| 241 | // 显示添加弹框 | ||
| 242 | function showAddPopup() { | ||
| 243 | addForm.value.idcCode = '' | ||
| 244 | idcListIndex.value = 0 | ||
| 245 | addPopup.value.open() | ||
| 246 | } | ||
| 247 | |||
| 248 | // 关闭添加弹框 | ||
| 249 | function closeAddPopup() { | ||
| 250 | addPopup.value.close() | ||
| 251 | } | ||
| 252 | |||
| 253 | // 证件类型选择 | ||
| 254 | function onIdcTypeChange(e) { | ||
| 255 | idcListIndex.value = e.detail.value | ||
| 256 | addForm.value.idType = idcList.value[idcListIndex.value].value | ||
| 257 | } | ||
| 258 | |||
| 259 | // 确认添加 | ||
| 260 | async function confirmAdd() { | ||
| 261 | if (!addForm.value.idcCode) { | ||
| 262 | uni.showToast({ title: '请输入证件号', icon: 'none' }) | ||
| 263 | return | ||
| 264 | } | ||
| 265 | if (!queryParams.value.rangeId) { | ||
| 266 | uni.showToast({ title: '缺少rangeId', icon: 'none' }) | ||
| 267 | return | ||
| 268 | } | ||
| 269 | |||
| 270 | try { | ||
| 271 | await api.memberInsertPersons({ | ||
| 272 | rangeId: queryParams.value.rangeId, | ||
| 273 | year: 1, | ||
| 274 | idcCode: addForm.value.idcCode | ||
| 275 | }) | ||
| 276 | uni.showToast({ title: '添加成功', icon: 'success' }) | ||
| 277 | closeAddPopup() | ||
| 278 | getList() | ||
| 279 | getCount() | ||
| 280 | } catch (e) { | ||
| 281 | console.error(e) | ||
| 282 | } | ||
| 283 | } | ||
| 200 | </script> | 284 | </script> |
| 201 | 285 | ||
| 202 | <style scoped lang="scss"> | 286 | <style scoped lang="scss"> |
| ... | @@ -301,4 +385,86 @@ | ... | @@ -301,4 +385,86 @@ |
| 301 | font-size: 32rpx; | 385 | font-size: 32rpx; |
| 302 | border: none; | 386 | border: none; |
| 303 | } | 387 | } |
| 388 | |||
| 389 | /* 添加会员弹框 */ | ||
| 390 | .add-popup { | ||
| 391 | width: 600rpx; | ||
| 392 | background: #ffffff; | ||
| 393 | border-radius: 24rpx; | ||
| 394 | overflow: hidden; | ||
| 395 | } | ||
| 396 | |||
| 397 | .popup-title { | ||
| 398 | font-size: 32rpx; | ||
| 399 | font-weight: 500; | ||
| 400 | color: #333; | ||
| 401 | text-align: center; | ||
| 402 | padding: 40rpx 30rpx 20rpx; | ||
| 403 | } | ||
| 404 | |||
| 405 | .popup-form { | ||
| 406 | padding: 20rpx 30rpx 40rpx; | ||
| 407 | } | ||
| 408 | |||
| 409 | .form-item { | ||
| 410 | display: flex; | ||
| 411 | align-items: center; | ||
| 412 | margin-bottom: 24rpx; | ||
| 413 | } | ||
| 414 | |||
| 415 | .form-item:last-child { | ||
| 416 | margin-bottom: 0; | ||
| 417 | } | ||
| 418 | |||
| 419 | .form-label { | ||
| 420 | width: 140rpx; | ||
| 421 | font-size: 28rpx; | ||
| 422 | color: #333; | ||
| 423 | flex-shrink: 0; | ||
| 424 | } | ||
| 425 | |||
| 426 | .form-input { | ||
| 427 | flex: 1; | ||
| 428 | background: #f5f5f5; | ||
| 429 | border-radius: 12rpx; | ||
| 430 | padding: 20rpx 24rpx; | ||
| 431 | } | ||
| 432 | |||
| 433 | .form-input input { | ||
| 434 | font-size: 28rpx; | ||
| 435 | color: #333; | ||
| 436 | width: 100%; | ||
| 437 | } | ||
| 438 | |||
| 439 | .picker-value { | ||
| 440 | font-size: 28rpx; | ||
| 441 | color: #333; | ||
| 442 | } | ||
| 443 | |||
| 444 | .placeholder-class { | ||
| 445 | color: #999; | ||
| 446 | } | ||
| 447 | |||
| 448 | .popup-btns { | ||
| 449 | display: flex; | ||
| 450 | border-top: 1rpx solid #eee; | ||
| 451 | } | ||
| 452 | |||
| 453 | .popup-btn { | ||
| 454 | flex: 1; | ||
| 455 | height: 100rpx; | ||
| 456 | line-height: 100rpx; | ||
| 457 | text-align: center; | ||
| 458 | font-size: 30rpx; | ||
| 459 | } | ||
| 460 | |||
| 461 | .popup-btn.cancel { | ||
| 462 | color: #666; | ||
| 463 | border-right: 1rpx solid #eee; | ||
| 464 | } | ||
| 465 | |||
| 466 | .popup-btn.confirm { | ||
| 467 | color: #E60012; | ||
| 468 | font-weight: 500; | ||
| 469 | } | ||
| 304 | </style> | 470 | </style> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment