20912bef by 华明祺

feat(personal): 实现个人中心页面及绑定/解绑学员功能

- 新增个人中心页面,包含会员卡展示、用户信息、功能入口
- 实现绑定学员弹框,支持输入姓名和证件号进行绑定
- 添加绑定状态判断,已绑定时按钮切换为解绑
- 实现解绑功能,调用unbindUser接口
- 新增退出登录按钮
- 添加bindUser和unbindUser API接口
1 parent dc453c5f
<script>
import config from '@/config.js';
import {
getInfo
getInfo,
getWebInfo
} from '@/common/login.js';
import * as api from '@/common/api.js';
import config from '@/config.js';
let loginUrl = ['login/login', 'login/register', 'personal/addVip_per']
let firstload = false
export default {
globalData: {
isLogin: false,
baseUrl_api: '',
user: null,
userType: '',
userInfo: null,
deptType: '',
genFlag: '',
authenticationStatus: '',
memberInfo: null,
isExam: false
user: null
},
onLaunch: function(options) {
console.log('App Launch', options);
this.globalData.baseUrl_api = config.baseUrl_api;
if (loginUrl.indexOf(options.path) == -1) {
let userName = uni.getStorageSync('userName')
if (userName) {
getInfo().then(() => {
this.globalData.isLogin = true;
firstload = true
let firstLoadCallback = getApp().firstLoadCallback;
if (firstLoadCallback) {
firstLoadCallback();
}
this.globalData.isLogin = true
uni.reLaunch({
url: '/pages/index/home'
})
}).catch(() => {
firstload = true
uni.redirectTo({
uni.reLaunch({
url: '/login/login'
})
})
} else {
this.globalData.isLogin = false;
firstload = true
uni.redirectTo({
return
}
let webUserName = uni.getStorageSync('webUserName')
if (webUserName) {
getWebInfo().then(() => {
uni.reLaunch({
url: '/personal/home'
})
}).catch(() => {
uni.reLaunch({
url: '/login/login'
})
})
return
}
}
this.globalData.isLogin = false
uni.reLaunch({
url: '/login/login'
})
},
onShow: function() {
console.log('App Show', firstload, this.globalData.isLogin);
// if (firstload && !this.globalData.isLogin) {
// uni.redirectTo({
// url: '/login/login'
// })
// }
console.log('App Show');
},
onHide: function() {
console.log('App Hide');
......
import request from './request.js'
import config from '@/config.js'
import * as loginServer from '@/common/login.js';
// 激活
export function active(data) {
......@@ -1415,6 +1414,14 @@ export function createMemberPayRange(data) {
})
}
// 获取最近认证记录
export function getMyRecent() {
return request({
url: '/system/certifiedNew/getMyRecent',
method: 'get'
})
}
// 获取订单详情
export function getOrderInfo(orderId) {
return request({
......@@ -1422,3 +1429,19 @@ export function getOrderInfo(orderId) {
method: 'get'
})
}
// 绑定学员
export function bindUser(data) {
return request({
url: `/person/info/bindUser`,
method: 'post',
params: data
})
}
export function unbindUser() {
return request({
url: `/person/info/unbindUser`,
method: 'post'
})
}
\ No newline at end of file
......
import {
useUserStore
} from '../store/modules/user'
import request from './request'
import * as api from '@/common/api.js'
function pcLogin(data) {
return request({
......@@ -39,8 +41,15 @@ function logout() {
url: '/logout',
method: 'post'
}).then(() => {
const userStore = useUserStore()
const app = getApp()
uni.removeStorageSync('token')
uni.removeStorageSync('userName')
uni.removeStorageSync('webUserName')
userStore.setUser(null)
app.globalData.isLogin = false
})
}
......@@ -85,15 +94,17 @@ function getInfo() {
url: '/getInfo',
method: 'get'
}).then(res => {
const userStore = useUserStore()
const app = getApp()
const user = res.data.user
// const personInfo = res.data.personInfo
uni.setStorageSync('userName', user.userName)
// uni.setStorageSync('perId', personInfo.perId||-1)
app.globalData.user = res.data.user
uni.removeStorageSync('webUserName')
userStore.setUser(user)
app.globalData.deptType = user.dept.deptType
app.globalData.genFlag = user.dept.genFlag
// user.dept.deptType = '3'
app.globalData.changePassFlag = user.changePassFlag
switch (user.dept.deptType) {
case '1': // 中跆协
app.globalData.userType = '1'
......@@ -109,8 +120,24 @@ function getInfo() {
app.globalData.userType = '3'
break
}
})
}
app.globalData.userInfo = user
function getWebInfo() {
return request({
url: '/person/info/getInfo',
method: 'get'
}).then(res => {
const userStore = useUserStore()
const user = res.data.user
delete res.data.user
const perInfo = res.data
uni.setStorageSync('webUserName', user.userName)
uni.removeStorageSync('userName')
userStore.setUser(user)
userStore.setPerInfo(perInfo)
})
}
......@@ -134,6 +161,38 @@ function getMyOwnMemberInfo() {
app.globalData.isExam = res.data?.memberInfo?.isPoints
})
}
function wxLogin() {
return new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: (res) => {
resolve(res)
},
fail: (res) => {
uni.showToast({
title: '获取用户信息失败',
icon: 'none',
duration: 2000
})
reject(res)
}
})
}).then(res => {
return pcLoginByCode(res.code)
})
}
function pcLoginByCode(code) {
return request({
url: `/loginByJsCode?jsCode=${code}`,
method: "POST"
}).then((res) => {
uni.setStorageSync('token', 'Bearer ' + res.data);
}).then(getWebInfo)
}
export {
pcLogin,
getCodeImg,
......@@ -144,5 +203,7 @@ export {
groupMemberRegister,
getMyOwnMemberInfo,
logout,
getInfo
getInfo,
getWebInfo,
wxLogin
}
\ No newline at end of file
......
......@@ -26,7 +26,8 @@
考试信息
</view>
<view class="userlist">
<view class="item" v-for="(n,index) in infoList" :key="index" @click="goDetail(n)" style="background-color: #fffafa;">
<view class="item" v-for="(n,index) in infoList" :key="index" @click="goDetail(n)"
style="background-color: #fffafa;">
<view class="w100">
<view class="text-primary">{{n.examCode}}</view>
<view class="name">{{n.name}}</view>
......@@ -82,7 +83,6 @@
onLoad((option) => {
if ('form' in option) {
form.value = JSON.parse(decodeURIComponent(option.form))
console.log(111,form.value)
}
type.value = option.type
// console.log(222,form.value)
......@@ -120,13 +120,13 @@
})
}
function goDetail(item){
function goDetail(item) {
const form = encodeURIComponent(JSON.stringify(item))
let path = `/level/applyDetail?examId=${item.examId}&form=${form}`
uni.navigateTo({
url: path
});
}
}
</script>
<style scoped lang="scss">
......@@ -139,15 +139,25 @@ function goDetail(item){
border-radius: 15rpx;
.tt {
color: #0A1629;margin: 0 0 30rpx;
color: #0A1629;
margin: 0 0 30rpx;
font-size: 30rpx;
}
.ddd{font-size: 28rpx;color: #333; margin: 0 0 10rpx;
.lab{color: #999;display: inline-block;text-align: justify;
text{word-break: break-all;}
.ddd {
font-size: 28rpx;
color: #333;
margin: 0 0 10rpx;
.lab {
color: #999;
display: inline-block;
text-align: justify;
text {
word-break: break-all;
}
}
}
}
</style>
\ No newline at end of file
......
<template>
<view class="page-bg">
<view class="nav-bar" style="margin-top:-30px" >
<view class="nav-bar" style="margin-top:-30px">
<view class="back-btn" @click="goBack">
<uni-icons type="left" size="20" color="#fff"></uni-icons>
</view>
......@@ -134,9 +134,11 @@
});
}
})
function goBack(){
function goBack() {
uni.navigateBack()
}
function changeActive(n) {
isActive.value = n
}
......@@ -173,7 +175,7 @@
pcLogin(form.value).then((res) => {
app.globalData.isLogin = true
uni.redirectTo({
url: '/pages/index/index'
url: '/pages/index/home'
})
})
} else if (isActive.value == 1) {
......@@ -205,7 +207,7 @@
.then(() => {
app.globalData.isLogin = true
uni.redirectTo({
url: '/pages/index/index'
url: '/pages/index/home'
})
})
}
......@@ -286,7 +288,10 @@
</script>
<style scoped lang="scss">
.wNumber {position: absolute;width: 100%;bottom:-50rpx;
.wNumber {
position: absolute;
width: 100%;
bottom: -50rpx;
text-align: center;
color: rgba(255, 255, 255, 0.7);
font-size: 24rpx;
......@@ -330,7 +335,9 @@
position: relative;
}
.loginbox {position: relative;
.loginbox {
position: relative;
.loginNav {
width: 700rpx;
margin: 0 auto -53rpx;
......
import App from './App'
import store from './store'
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
......@@ -6,6 +8,7 @@ App.mpType = 'app'
const app = new Vue({
...App
})
app.use(store)
app.$mount()
// #endif
......@@ -15,6 +18,7 @@ import {
} from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.use(store)
return {
app
}
......
......@@ -129,10 +129,10 @@
if (orderErr) {
uni.hideLoading()
isPaying.value = false
uni.showToast({
title: '创建订单失败',
icon: 'none'
})
// uni.showToast({
// title: '创建订单失败',
// icon: 'none'
// })
return
}
......@@ -141,7 +141,7 @@
if (data.payFlag == 0) {
uni.hideLoading()
isPaying.value = false
uni.navigateTo({
uni.redirectTo({
url: `/myCenter/sucPay?orderId=${data.orderId}`
})
return
......@@ -153,7 +153,7 @@
uni.hideLoading()
isPaying.value = false
uni.navigateTo({
uni.redirectTo({
url: `/myCenter/sucPay?orderId=${data.orderId}`
})
}
......
......@@ -49,44 +49,59 @@
</template>
<script setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
// 核心数据
const formData = ref({}) // 订单统计数据
const rangeId = ref('') // 核心业务ID
const payType = ref('0') // 支付方式(默认0=民生付)
const payLoading = ref(false) // 支付按钮加载状态
// 页面加载接收参数
onLoad(async (options) => {
import {
ref
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
// 核心数据
const formData = ref({}) // 订单统计数据
const rangeId = ref('') // 核心业务ID
const payType = ref('0') // 支付方式(默认0=民生付)
const payLoading = ref(false) // 支付按钮加载状态
// 页面加载接收参数
onLoad(async (options) => {
console.log('订单ID:', options.rangeId)
if (options.rangeId) {
rangeId.value = options.rangeId
await getCount()
}
})
})
async function getCount() {
async function getCount() {
try {
const res = await api.getNewCountByRangeId(rangeId.value)
formData.value = res.data || { all: 0, new: 0, old: 0 }
formData.value = res.data || {
all: 0,
new: 0,
old: 0
}
} catch (e) {
formData.value = { all: 0, new: 0, old: 0 }
formData.value = {
all: 0,
new: 0,
old: 0
}
}
}
}
// 支付方式切换
function handlePayTypeChange(e) {
// 支付方式切换
function handlePayTypeChange(e) {
payType.value = e.detail.value
}
}
// 立即支付核心逻辑
async function handlePay() {
// 立即支付核心逻辑
async function handlePay() {
// 基础校验
if (!rangeId.value || rangeId.value === '-1') {
return uni.showToast({ title: '订单ID异常', icon: 'none' })
return uni.showToast({
title: '订单ID异常',
icon: 'none'
})
}
try {
......@@ -95,7 +110,7 @@ async function handlePay() {
if (res.data?.orderId) {
api.pcallBack2(res.data.orderId)
uni.navigateTo({
uni.redirectTo({
url: `/myCenter/sucPay?rangeId=${rangeId.value}from=payOrder`
})
}
......@@ -104,25 +119,30 @@ async function handlePay() {
} catch (err) {
const errMsg = err?.data?.msg || err?.message || '支付失败,请稍后重试'
uni.showToast({ title: errMsg, icon: 'none' })
uni.showToast({
title: errMsg,
icon: 'none'
})
} finally {
payLoading.value = false
}
}
}
</script>
<style scoped lang="scss">
.pay-order-container {
.pay-order-container {
padding: 30rpx;
background-color: #fff;
min-height: 100vh;
box-sizing: border-box;
}
.icon{
width:30px;
}
// 页面头部
.page-header {
}
.icon {
width: 30px;
}
// 页面头部
.page-header {
text-align: center;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
......@@ -133,10 +153,10 @@ async function handlePay() {
font-weight: 600;
color: #333;
}
}
}
// 订单信息区域
.order-info {
// 订单信息区域
.order-info {
margin-bottom: 60rpx;
.info-item {
......@@ -174,10 +194,10 @@ async function handlePay() {
font-size: 38rpx;
}
}
}
}
// 支付方式区域
.pay-type-section {
// 支付方式区域
.pay-type-section {
margin-bottom: 80rpx;
.section-title {
......@@ -205,10 +225,10 @@ async function handlePay() {
}
}
}
}
}
// 底部支付按钮
.fixed-bottom {
// 底部支付按钮
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
......@@ -230,5 +250,5 @@ async function handlePay() {
background-color: #E60012;
color: #fff;
}
}
}
</style>
\ No newline at end of file
......
......@@ -32,7 +32,8 @@
<uni-easyinput v-model="form.siteTel" />
</uni-forms-item>
<uni-forms-item label="认证地址" required>
<uni-data-picker v-model="form.coordinates1" @change="changeCoordinates1" :localdata="regionsList"></uni-data-picker>
<uni-data-picker v-model="form.coordinates1" @change="changeCoordinates1"
:localdata="regionsList"></uni-data-picker>
</uni-forms-item>
<uni-forms-item label="详细地址" required>
<uni-easyinput v-model="form.adress" placeholder="请输入详细地址" type='textarea' /></uni-forms-item>
......@@ -101,10 +102,17 @@
</template>
<script setup>
import { ref, reactive, computed } from 'vue';
import {
ref,
reactive,
computed
} from 'vue';
import * as api from '@/common/api.js';
import _ from 'underscore'
import { onLoad, onShow } from '@dcloudio/uni-app';
import {
onLoad,
onShow
} from '@dcloudio/uni-app';
import config from '@/config.js'
const app = getApp();
......@@ -119,15 +127,32 @@
legalIdcCode: ''
});
const years = ref(['1', '2', '3', '4', '5'])
const yesno = ref([{ value: '0', text: '否' }, { value: '1', text: '是' }])
const yesno = ref([{
value: '0',
text: '否'
}, {
value: '1',
text: '是'
}])
const memberFee = ref('')
const preferentialPolicy = ref(false)
const preferentialData = ref({})
const typeList = ref([
{ value: '1', text: '企业' },
{ value: '2', text: '国家组织' },
{ value: '3', text: '社会组织' },
{ value: '4', text: '其他' }
const typeList = ref([{
value: '1',
text: '企业'
},
{
value: '2',
text: '国家组织'
},
{
value: '3',
text: '社会组织'
},
{
value: '4',
text: '其他'
}
])
const regionArr = ref();
const regionsList = ref([]);
......@@ -143,7 +168,9 @@
const type = ref(false)
const flag = ref(false)
const result = ref(false)
const query = ref({ type: 0 });
const query = ref({
type: 0
});
const activeStatus = ref(0)
const active = ref(0)
const memberInfo = ref({})
......@@ -154,8 +181,15 @@
const picArr = ref([])
const picArrR = ref([])
const businessLicenseArr = ref([])
const list1 = ref([{ title: '完善信息' }, { title: '会员认证' }])
const imageStylesZJ = ref({ width: '400rpx', height: '253rpx' });
const list1 = ref([{
title: '完善信息'
}, {
title: '会员认证'
}])
const imageStylesZJ = ref({
width: '400rpx',
height: '253rpx'
});
const indicatorStyle = ref(`height: 50px;`)
const imgfront = ref({})
const imgBack = ref({})
......@@ -216,7 +250,10 @@
flag.value = newResult.value
}
form.value = { ...res.data.dept, ...res.data.memberInfo }
form.value = {
...res.data.dept,
...res.data.memberInfo
}
getTree()
form.value.deptType = res.data.dept.deptType
form.value.parentId = form.value.parentId.toString()
......@@ -239,7 +276,10 @@
try {
businessLicenseArr.value = JSON.parse(form.value.businessLicense) || []
} catch (e) {
businessLicenseArr.value = [{ url: form.value.businessLicense, name: '营业执照' }]
businessLicenseArr.value = [{
url: form.value.businessLicense,
name: '营业执照'
}]
}
}
......@@ -252,8 +292,16 @@
if (legalIdcPhoto2.value.indexOf('http') == -1) {
legalIdcPhoto2.value = config.baseUrl_api + legalIdcPhoto2.value
}
imgfront.value = { url: legalIdcPhoto1.value, name: '身份证正面', extname: 'png' }
imgBack.value = { url: legalIdcPhoto2.value, name: '身份证反面', extname: 'png' }
imgfront.value = {
url: legalIdcPhoto1.value,
name: '身份证正面',
extname: 'png'
}
imgBack.value = {
url: legalIdcPhoto2.value,
name: '身份证反面',
extname: 'png'
}
}
if (form.value.pictures) {
......@@ -265,7 +313,11 @@
if (p.indexOf('http') == -1) {
p = config.baseUrl_api + p
}
var obj = { url: p, name: '图片', extname: 'png' }
var obj = {
url: p,
name: '图片',
extname: 'png'
}
picArrR.value.push(obj)
picArr.value.push(p)
})
......@@ -279,7 +331,11 @@
function getTree() {
if (authenticationStatusa.value == 0 || authenticationStatusa.value == 3 || authenticationStatusa.value == 1) {
var obj = { selfDeptId: '-1', webSiteShow: 1, showDisabled: 1 }
var obj = {
selfDeptId: '-1',
webSiteShow: 1,
showDisabled: 1
}
api.certifiedDeptTree(obj).then(res => {
tree.value = res.data
})
......@@ -287,7 +343,8 @@
var obj = {
selfDeptId: '-1',
showDisabled: 1,
showDirect: authenticationStatusa.value == 2 || authenticationStatusa.value == 5 || authenticationStatusa.value == 4 ? 1 : null
showDirect: authenticationStatusa.value == 2 || authenticationStatusa.value == 5 ||
authenticationStatusa.value == 4 ? 1 : null
}
api.deptTreeSelect(obj).then(res => {
tree.value = res.data
......@@ -305,55 +362,94 @@
async function submit() {
// 基础表单验证
if (form.value.name == '') {
uni.showToast({ title: '请填写机构名称', icon: 'none' })
uni.showToast({
title: '请填写机构名称',
icon: 'none'
})
return
}
if (form.value.creditCode == '') {
uni.showToast({ title: '请填写社会信用代码', icon: 'none' })
uni.showToast({
title: '请填写社会信用代码',
icon: 'none'
})
return
}
if (form.value.companyName == '') {
uni.showToast({ title: '请填写营业执照名称', icon: 'none' })
uni.showToast({
title: '请填写营业执照名称',
icon: 'none'
})
return
}
if (form.value.legalIdcCode == '') {
uni.showToast({ title: '请填写法人证件号', icon: 'none' })
uni.showToast({
title: '请填写法人证件号',
icon: 'none'
})
return
}
if (form.value.siteContact == '') {
uni.showToast({ title: '请填写联系人', icon: 'none' })
uni.showToast({
title: '请填写联系人',
icon: 'none'
})
return
}
if (form.value.siteTel == '') {
uni.showToast({ title: '请填写联系方式', icon: 'none' })
uni.showToast({
title: '请填写联系方式',
icon: 'none'
})
return
}
if (form.value.coordinates1 == '') {
uni.showToast({ title: '请选择认证地址', icon: 'none' })
uni.showToast({
title: '请选择认证地址',
icon: 'none'
})
return
}
if (form.value.adress == '') {
uni.showToast({ title: '请填写详细地址', icon: 'none' })
uni.showToast({
title: '请填写详细地址',
icon: 'none'
})
return
}
if (form.value.legal == '') {
uni.showToast({ title: '请填写法人姓名', icon: 'none' })
uni.showToast({
title: '请填写法人姓名',
icon: 'none'
})
return
}
if (legalIdcPhoto1.value == '' || legalIdcPhoto2.value == '') {
uni.showToast({ title: '请上传法人身份证', icon: 'none' })
uni.showToast({
title: '请上传法人身份证',
icon: 'none'
})
return
}
if (!form.value.businessLicense) {
uni.showToast({ title: '请上传营业执照', icon: 'none' })
uni.showToast({
title: '请上传营业执照',
icon: 'none'
})
return
}
if (picArr.value.length == 0) {
uni.showToast({ title: '请上传机构照片', icon: 'none' })
uni.showToast({
title: '请上传机构照片',
icon: 'none'
})
return
}
if (form.value.parentId == -1 || form.value.parentId == 0) {
uni.showToast({ title: '请选择所属协会', icon: 'none' })
uni.showToast({
title: '请选择所属协会',
icon: 'none'
})
return
}
......@@ -370,7 +466,10 @@
submitData()
} catch (error) {
uni.showToast({ title: error.message || '验证失败,请重试', icon: 'none' })
uni.showToast({
title: error.message || '验证失败,请重试',
icon: 'none'
})
}
}
......@@ -403,7 +502,7 @@
// 企业信息验证
function handelVerify() {
return new Promise(async(resolve, reject) => {
return new Promise(async (resolve, reject) => {
if (!form.value.legalIdcCode || !form.value.legal) {
return reject(new Error('请重新上传身份证并填写法人证件号'))
}
......@@ -458,14 +557,19 @@
content: '激活成功,返回首页',
success: function(resp) {
if (resp.confirm) {
uni.reLaunch({ url: `/pages/index/index` })
uni.reLaunch({
url: `/pages/index/home`
})
} else {
uni.navigateBack()
}
}
})
}).catch(err => {
uni.showToast({ title: '激活失败,请重试', icon: 'none' })
uni.showToast({
title: '激活失败,请重试',
icon: 'none'
})
})
} else {
api.editMyMemberCertifiedInfo(dataInfo).then(res => {
......@@ -474,7 +578,10 @@
})
}).catch(err => {
uni.showToast({ title: '提交失败,请重试', icon: 'none' })
uni.showToast({
title: '提交失败,请重试',
icon: 'none'
})
})
}
}
......@@ -489,13 +596,18 @@
const tempFilePaths = e.tempFilePaths;
const imgUrl = tempFilePaths[0]
if (!imgUrl) return
uni.showLoading({ title: '上传中' })
uni.showLoading({
title: '上传中'
})
api.uploadImg(e).then(data => {
legalIdcPhoto1.value = data.msg
uni.hideLoading()
}).catch(err => {
uni.hideLoading()
uni.showToast({ title: '上传失败', icon: 'none' })
uni.showToast({
title: '上传失败',
icon: 'none'
})
})
}
......@@ -503,13 +615,18 @@
const tempFilePaths = e.tempFilePaths;
const imgUrl = tempFilePaths[0]
if (!imgUrl) return
uni.showLoading({ title: '上传中' })
uni.showLoading({
title: '上传中'
})
api.uploadImg(e).then(data => {
legalIdcPhoto2.value = data.msg
uni.hideLoading()
}).catch(err => {
uni.hideLoading()
uni.showToast({ title: '上传失败', icon: 'none' })
uni.showToast({
title: '上传失败',
icon: 'none'
})
})
}
......@@ -524,17 +641,27 @@
}
let selectFileValue = {}
function selectFile(e) {
let file = e.tempFiles[0]
if (!file) return
uni.showLoading({ title: '上传中' })
uni.showLoading({
title: '上传中'
})
api.uploadFile(e).then(data => {
selectFileValue = { url: data.msg, name: file.name, extname: file.extname }
selectFileValue = {
url: data.msg,
name: file.name,
extname: file.extname
}
form.value.businessLicense = JSON.stringify([selectFileValue])
uni.hideLoading()
}).catch(err => {
uni.hideLoading()
uni.showToast({ title: '上传失败', icon: 'none' })
uni.showToast({
title: '上传失败',
icon: 'none'
})
})
}
......@@ -547,13 +674,18 @@
const tempFilePaths = e.tempFilePaths;
const imgUrl = tempFilePaths[0]
if (!imgUrl) return
uni.showLoading({ title: '上传中' })
uni.showLoading({
title: '上传中'
})
api.uploadImg(e).then(data => {
picArr.value.push(data.msg)
uni.hideLoading()
}).catch(err => {
uni.hideLoading()
uni.showToast({ title: '上传失败', icon: 'none' })
uni.showToast({
title: '上传失败',
icon: 'none'
})
})
}
......@@ -563,25 +695,47 @@
</script>
<style lang="scss" scoped>
:deep(.file-picker__progress){ opacity: 0; }
:deep(.input-value){padding: 0 5px;}
:deep(.file-picker__progress) {
opacity: 0;
}
:deep(.input-value) {
padding: 0 5px;
}
.picker-view {
width: 750rpx;
height: 600rpx;
margin-top: 20rpx;
}
.item {
line-height: 100rpx;
text-align: center;
}
:deep(.uni-data-tree) {
border: 1px solid #dcdfe6;
border-radius: 4px;
.selected-list { justify-content: start; }
.selected-list {
justify-content: start;
}
}
:deep(.uni-select__input-placeholder) {
font-size: 30rpx;
}
:deep(.uni-easyinput__content-input) {
font-size: 30rpx;
}
:deep(.uni-select__input-placeholder) { font-size: 30rpx; }
:deep(.uni-easyinput__content-input) { font-size: 30rpx; }
:deep(.uni-easyinput__placeholder-class) { font-size: 30rpx;color: grey; }
:deep(.uni-easyinput__placeholder-class) {
font-size: 30rpx;
color: grey;
}
.wBox {
width: 700rpx;
padding: 30rpx;
......@@ -590,12 +744,14 @@
box-shadow: 0rpx 12rpx 116rpx 0rpx rgba(196, 203, 214, 0.1);
border-radius: 15rpx;
}
.imgArea {
padding: 1px;
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
.btn-red {
background-color: #F56C6C;
color: #fff;
......@@ -605,6 +761,7 @@
font-size: 32rpx;
width: 100%;
}
.fixedBottom {
position: fixed;
bottom: 0;
......@@ -614,6 +771,7 @@
background: #fff;
z-index: 99;
}
.text-warning {
font-size: 28rpx;
margin-top: 20rpx;
......@@ -628,12 +786,14 @@
box-sizing: border-box;
text-align: center;
}
.modal-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 30rpx;
}
.modal-content {
font-size: 30rpx;
color: #666;
......@@ -641,17 +801,20 @@
margin-bottom: 20rpx;
text-align: left;
}
.modal-tip {
font-size: 26rpx;
color: #F56C6C;
margin-top: 10rpx;
margin-bottom: 30rpx;
}
.modal-btns {
display: flex;
justify-content: space-between;
gap: 20rpx;
}
.btn-cancel {
flex: 1;
height: 80rpx;
......@@ -662,18 +825,22 @@
font-size: 32rpx;
border: none;
}
.btn-confirm {
flex: 1;
height: 80rpx;
line-height: 80rpx;
background: #C4121B; /* 红色主色调,和图二一致 */
background: #C4121B;
/* 红色主色调,和图二一致 */
color: #fff;
border-radius: 40rpx;
font-size: 32rpx;
border: none;
}
/* 去掉按钮默认边框 */
.btn-cancel::after, .btn-confirm::after {
.btn-cancel::after,
.btn-confirm::after {
border: none;
}
......@@ -681,6 +848,7 @@
.apply-modal {
padding: 40rpx 30rpx 20rpx;
}
.apply-btns {
margin-bottom: 20rpx;
}
......
......@@ -9,14 +9,12 @@
<view class="time">{{n.auditTime||'待审批'}}</view>
<view class="content">
<view class="status">
<text v-if="n.auditResult==0"> 审核中</text>
<text v-if="n.auditResult==1" class="text-success">审核通过</text>
<text v-if="n.auditResult==2" class="text-danger"> 审核拒绝</text>
<text v-if="n.auditResult==3" class="text-warning"> 已撤回</text>
<text v-if="n.auditResult==0" class="text-danger"> 审核拒绝</text>
</view>
<!-- <view class="name">{{index+1}}</view> -->
<view class="deptName">{{n.auditDeptName}}</view>
<view v-if="n.auditStatus==2">
<view v-if="n.auditResult==0">
备注:{{n.auditMsg||'/' }}
</view>
</view>
......@@ -31,6 +29,7 @@
import * as api from '@/common/api.js'
import config from '@/config.js'
import _ from 'underscore'
import to from 'await-to-js'
import {
onMounted,
ref
......@@ -42,16 +41,15 @@
const app = getApp();
const userType = ref('')
const recordList = ref([])
onLoad((option) => {
getMyCertStageFN()
})
function getMyCertStageFN() {
api.getMyCertStage().then(res => {
recordList.value = res.data
console.log(res)
onLoad(async (option) => {
await getMyRecentFN()
})
async function getMyRecentFN() {
const [err, res] = await to(api.getMyRecent())
if (!err && res.data && res.data.auditLogs) {
recordList.value = JSON.parse(res.data.auditLogs)
}
}
</script>
......
......@@ -4,6 +4,7 @@
"crypto-js": "^4.1.1",
"dayjs": "^1.11.6",
"lodash": "^4.17.21",
"pinia": "^3.0.4",
"underscore": "^1.13.6"
},
"devDependencies": {
......
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
"pages": [{
"path": "pages/index/index"
},
{
"path": "pages/index/index",
"path": "pages/index/home",
"style": {
"navigationBarTitleText": "工作台",
"backgroundColor": "#ffffff",
......@@ -94,11 +96,10 @@
},
{
"path" : "pages/index/newsDetail",
"style" :
{
"navigationBarTitleText" : "通知详情",
"enablePullDownRefresh" : false
"path": "pages/index/newsDetail",
"style": {
"navigationBarTitleText": "通知详情",
"enablePullDownRefresh": false
}
}
],
......@@ -108,8 +109,7 @@
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTitleText": "中跆协-工作台"
},
"subPackages": [
{
"subPackages": [{
"root": "login",
"pages": [{
"path": "login",
......@@ -136,8 +136,7 @@
},
{
"root": "personal",
"pages": [
{
"pages": [{
"path": "addVip_per",
"style": {
"navigationBarTitleText": "个人会员申请",
......@@ -145,43 +144,38 @@
}
},
{
"path" : "goPay_per",
"style" :
{
"navigationBarTitleText" : "付款详情",
"enablePullDownRefresh" : false
"path": "goPay_per",
"style": {
"navigationBarTitleText": "付款详情",
"enablePullDownRefresh": false
}
},
{
"path" : "submitPay",
"style" :
{
"navigationBarTitleText" : "确认支付",
"enablePullDownRefresh" : false
"path": "submitPay",
"style": {
"navigationBarTitleText": "确认支付",
"enablePullDownRefresh": false
}
},
{
"path" : "sucPay",
"style" :
{
"navigationBarTitleText" : "支付详情",
"enablePullDownRefresh" : false
"path": "sucPay",
"style": {
"navigationBarTitleText": "支付详情",
"enablePullDownRefresh": false
}
},
{
"path" : "home",
"style" :
{
"navigationBarTitleText" : "个人会员中心",
"enablePullDownRefresh" : false
"path": "home",
"style": {
"navigationBarTitleText": "个人会员中心",
"enablePullDownRefresh": false
}
}
]
},
{
"root": "personalVip",
"pages": [
{
"pages": [{
"path": "addVip",
"style": {
"navigationBarTitleText": "添加会员",
......@@ -298,141 +292,125 @@
}
},
{
"path" : "changeVip",
"style" :
{
"navigationBarTitleText" : "会员信息变更",
"enablePullDownRefresh" : false
"path": "changeVip",
"style": {
"navigationBarTitleText": "会员信息变更",
"enablePullDownRefresh": false
}
},
{
"path" : "addChange",
"style" :
{
"navigationBarTitleText" : "新增变更",
"enablePullDownRefresh" : false
"path": "addChange",
"style": {
"navigationBarTitleText": "新增变更",
"enablePullDownRefresh": false
}
},
{
"path" : "changeVipDetail",
"style" :
{
"navigationBarTitleText" : "详情",
"enablePullDownRefresh" : false
"path": "changeVipDetail",
"style": {
"navigationBarTitleText": "详情",
"enablePullDownRefresh": false
}
},
{
"path" : "changeVipAudit",
"style" :
{
"navigationBarTitleText" : "会员信息变更审核",
"enablePullDownRefresh" : false
"path": "changeVipAudit",
"style": {
"navigationBarTitleText": "会员信息变更审核",
"enablePullDownRefresh": false
}
},
{
"path" : "changeLevel",
"style" :
{
"navigationBarTitleText" : "级位变更审核",
"enablePullDownRefresh" : false
"path": "changeLevel",
"style": {
"navigationBarTitleText": "级位变更审核",
"enablePullDownRefresh": false
}
},
{
"path" : "addChangeLevel",
"style" :
{
"navigationBarTitleText" : "新建级位变更",
"enablePullDownRefresh" : false
"path": "addChangeLevel",
"style": {
"navigationBarTitleText": "新建级位变更",
"enablePullDownRefresh": false
}
},
{
"path" : "changeLevelDetail",
"style" :
{
"navigationBarTitleText" : "级位变更详情",
"enablePullDownRefresh" : false
"path": "changeLevelDetail",
"style": {
"navigationBarTitleText": "级位变更详情",
"enablePullDownRefresh": false
}
},
{
"path" : "changeLevelAudit",
"style" :
{
"navigationBarTitleText" : "级位变更审批",
"enablePullDownRefresh" : false
"path": "changeLevelAudit",
"style": {
"navigationBarTitleText": "级位变更审批",
"enablePullDownRefresh": false
}
},
{
"path" : "changeVipChoseList",
"style" :
{
"navigationBarTitleText" : "在线选择",
"enablePullDownRefresh" : false
"path": "changeVipChoseList",
"style": {
"navigationBarTitleText": "在线选择",
"enablePullDownRefresh": false
}
},
{
"path" : "mergeVip",
"style" :
{
"navigationBarTitleText" : "信息合并",
"enablePullDownRefresh" : false
"path": "mergeVip",
"style": {
"navigationBarTitleText": "信息合并",
"enablePullDownRefresh": false
}
},
{
"path" : "addMerge",
"style" :
{
"navigationBarTitleText" : "新建信息合并",
"enablePullDownRefresh" : false
"path": "addMerge",
"style": {
"navigationBarTitleText": "新建信息合并",
"enablePullDownRefresh": false
}
},
{
"path" : "mergeVipDetail",
"style" :
{
"navigationBarTitleText" : "合并信息详情",
"enablePullDownRefresh" : false
"path": "mergeVipDetail",
"style": {
"navigationBarTitleText": "合并信息详情",
"enablePullDownRefresh": false
}
},
{
"path" : "mergeVipChoseList",
"style" :
{
"navigationBarTitleText" : "在线选择",
"enablePullDownRefresh" : false
"path": "mergeVipChoseList",
"style": {
"navigationBarTitleText": "在线选择",
"enablePullDownRefresh": false
}
},
{
"path" : "mergeVipAudit",
"style" :
{
"navigationBarTitleText" : "合并审核",
"enablePullDownRefresh" : false
"path": "mergeVipAudit",
"style": {
"navigationBarTitleText": "合并审核",
"enablePullDownRefresh": false
}
},
{
"path" : "monthFee",
"style" :
{
"navigationBarTitleText" : "月结缴费",
"enablePullDownRefresh" : false
"path": "monthFee",
"style": {
"navigationBarTitleText": "月结缴费",
"enablePullDownRefresh": false
}
},
{
"path" : "webview/webview",
"style" :
{
"navigationBarTitleText" : "下载",
"enablePullDownRefresh" : false
"path": "webview/webview",
"style": {
"navigationBarTitleText": "下载",
"enablePullDownRefresh": false
}
},
{
"path" : "monthFeeDetail",
"style" :
{
"navigationBarTitleText" : "月结详情",
"enablePullDownRefresh" : false
"path": "monthFeeDetail",
"style": {
"navigationBarTitleText": "月结详情",
"enablePullDownRefresh": false
}
}]
}
]
}, {
"root": "group",
"pages": [{
......@@ -489,7 +467,7 @@
"enablePullDownRefresh": false
}
},{
}, {
"path": "list",
"style": {
"navigationBarTitleText": "团体会员",
......@@ -523,7 +501,7 @@
"enablePullDownRefresh": false
}
},{
}, {
"path": "vipList",
"style": {
"navigationBarTitleText": "会员列表",
......@@ -531,56 +509,51 @@
}
},
{
"path" : "changeGroupInfo",
"style" :
{
"navigationBarTitleText" : "团体会员信息修改",
"enablePullDownRefresh" : false
"path": "changeGroupInfo",
"style": {
"navigationBarTitleText": "团体会员信息修改",
"enablePullDownRefresh": false
}
},
{
"path" : "changeGroupAudit",
"style" :
{
"navigationBarTitleText" : "团体信息变更审核",
"enablePullDownRefresh" : false
"path": "changeGroupAudit",
"style": {
"navigationBarTitleText": "团体信息变更审核",
"enablePullDownRefresh": false
}
},
{
"path" : "changeGroupDetail",
"style" :
{
"navigationBarTitleText" : "团体信息变更详情",
"enablePullDownRefresh" : false
"path": "changeGroupDetail",
"style": {
"navigationBarTitleText": "团体信息变更详情",
"enablePullDownRefresh": false
}
},
{
"path" : "newChange",
"style" :
{
"navigationBarTitleText" : "新建团体信息变更",
"enablePullDownRefresh" : false
"path": "newChange",
"style": {
"navigationBarTitleText": "新建团体信息变更",
"enablePullDownRefresh": false
}
},
{
"path" : "groupInfo",
"style" :
{
"navigationBarTitleText" : "机构资料",
"enablePullDownRefresh" : false
"path": "groupInfo",
"style": {
"navigationBarTitleText": "机构资料",
"enablePullDownRefresh": false
}
},
{
"path" : "changeGroupChoseList",
"style" :
{
"navigationBarTitleText" : "在线选择",
"enablePullDownRefresh" : false
"path": "changeGroupChoseList",
"style": {
"navigationBarTitleText": "在线选择",
"enablePullDownRefresh": false
}
}]
},{
}
]
}, {
"root": "level",
"pages":[{
"pages": [{
"path": "ztx/examList",
"style": {
"navigationBarTitleText": "级位考试详情",
......@@ -601,7 +574,7 @@
"enablePullDownRefresh": false
}
},{
}, {
"path": "apply",
"style": {
"navigationBarTitleText": "级位考试申请",
......@@ -678,104 +651,94 @@
"navigationBarTitleText": "考生信息",
"enablePullDownRefresh": false
}
}]
},{
}
]
}, {
"root": "myCenter",
"pages": [
{
"path" : "index",
"style" :
{
"navigationBarTitleText" : "个人中心",
"enablePullDownRefresh" : false
"pages": [{
"path": "index",
"style": {
"navigationBarTitleText": "个人中心",
"enablePullDownRefresh": false
}
},
{
"path" : "teamInfo",
"style" :
{
"navigationBarTitleText" : "团体信息",
"enablePullDownRefresh" : false
"path": "teamInfo",
"style": {
"navigationBarTitleText": "团体信息",
"enablePullDownRefresh": false
}
},
{
"path" : "auth",
"style" :
{
"navigationBarTitleText" : "会员认证",
"enablePullDownRefresh" : false
"path": "auth",
"style": {
"navigationBarTitleText": "会员认证",
"enablePullDownRefresh": false
}
},
{
"path" : "safe",
"style" :
{
"navigationBarTitleText" : "账号与安全",
"enablePullDownRefresh" : false
"path": "safe",
"style": {
"navigationBarTitleText": "账号与安全",
"enablePullDownRefresh": false
}
},
{
"path" : "reviewList",
"style" :
{
"navigationBarTitleText" : "审核详情",
"enablePullDownRefresh" : false
"path": "reviewList",
"style": {
"navigationBarTitleText": "审核详情",
"enablePullDownRefresh": false
}
},
{
"path" : "perfect",
"style" :
{
"navigationBarTitleText" : "团体会员缴费",
"enablePullDownRefresh" : false
"path": "perfect",
"style": {
"navigationBarTitleText": "团体会员缴费",
"enablePullDownRefresh": false
}
},
{
"path" : "goPay",
"style" :
{
"navigationBarTitleText" : "付款详情",
"enablePullDownRefresh" : false
"path": "goPay",
"style": {
"navigationBarTitleText": "付款详情",
"enablePullDownRefresh": false
}
},
{
"path" : "examPointApply",
"style" :
{
"navigationBarTitleText" : "申请考点",
"enablePullDownRefresh" : false
"path": "examPointApply",
"style": {
"navigationBarTitleText": "申请考点",
"enablePullDownRefresh": false
}
},
{
"path" : "chooseExaminer",
"style" :
{
"navigationBarTitleText" : "选择考官",
"enablePullDownRefresh" : false
"path": "chooseExaminer",
"style": {
"navigationBarTitleText": "选择考官",
"enablePullDownRefresh": false
}
},
{
"path" : "sucPay",
"style" :
{
"navigationBarTitleText" : "支付成功",
"enablePullDownRefresh" : false
"path": "sucPay",
"style": {
"navigationBarTitleText": "支付成功",
"enablePullDownRefresh": false
}
},
{
"path" : "payOrder",
"style" :
{
"navigationBarTitleText" : "支付详情",
"enablePullDownRefresh" : false
"path": "payOrder",
"style": {
"navigationBarTitleText": "支付详情",
"enablePullDownRefresh": false
}
}
]
}],
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": ["login","personalVip", "group","level","myCenter","personal"]
"packages": ["login", "personalVip", "group", "level", "myCenter", "personal"]
}
}
}
\ No newline at end of file
......
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
......@@ -10,7 +10,8 @@
<view v-html="form.content"></view>
<view v-if="attachmentMp4.length>0">
<video v-for="(f,index) in attachmentMp4" :key="index" controls :src="config.baseUrl_api + f.url"></video>
<video v-for="(f,index) in attachmentMp4" :key="index" controls
:src="config.baseUrl_api + f.url"></video>
</view>
<view v-if="attachmentFile.length>0" class="mt20">
<!-- 附件-->
......@@ -39,8 +40,8 @@
import _ from 'underscore'
import config from '@/config.js'
const form = ref({})
const attachmentFile = ref([])
const attachmentMp4 = ref([])
const attachmentFile = ref([])
const attachmentMp4 = ref([])
onLoad((option) => {
getData(option.noteId)
......@@ -58,15 +59,17 @@ const attachmentMp4 = ref([])
if (form.value.attacthJson) {
const attachment = JSON.parse(form.value.attacthJson)
attachmentFile.value = _.filter(attachment, (a) => a.url.toLowerCase().indexOf('.mp4') === -1) || []
attachmentFile.value = _.filter(attachment, (a) => a.url.toLowerCase().indexOf('.mp4') === -1) ||
[]
attachmentMp4.value = _.filter(attachment, (a) => a.url.toLowerCase().indexOf('.mp4') !== -1) || []
}
})
}
function downLoad(url){
function downLoad(url) {
console.log(url)
var str = config.baseUrl_api + url
if (url.indexOf('png') > -1 ||url.indexOf('jpg') > -1 ||url.indexOf('jpeg') > -1) {
if (url.indexOf('png') > -1 || url.indexOf('jpg') > -1 || url.indexOf('jpeg') > -1) {
uni.previewImage({
urls: [str],
success: function(res) {
......@@ -83,6 +86,7 @@ const attachmentMp4 = ref([])
goWebView(str)
}
}
function goWebView(url) {
url = url.replace("http://", "https://")
uni.showLoading({
......@@ -91,7 +95,6 @@ const attachmentMp4 = ref([])
uni.downloadFile({
url: url,
success: function(res) {
console.log('111')
uni.hideLoading();
var filePath = res.tempFilePath;
uni.showLoading({
......@@ -101,14 +104,13 @@ const attachmentMp4 = ref([])
filePath: filePath,
showMenu: true,
success: function(res) {
console.log('222')
uni.hideLoading();
},
fail: function(err) {
console.log(err.errMsg)
uni.hideLoading();
let msg
if(err.errMsg.indexOf('not supported')>-1){
if (err.errMsg.indexOf('not supported') > -1) {
msg = '不支持该文件类型'
} else {
msg = err.errMsg
......@@ -140,6 +142,7 @@ const attachmentMp4 = ref([])
background: #fff;
min-height: 100vh;
}
.title {
font-size: 36rpx;
font-weight: 500;
......@@ -158,6 +161,7 @@ const attachmentMp4 = ref([])
color: #7B7F83;
font-size: 22rpx;
}
.content {
line-height: 1.6;
color: #4C5359;
......@@ -178,7 +182,10 @@ const attachmentMp4 = ref([])
word-wrap: break-word !important;
white-space: normal !important;
}
.content rich-text img{max-width: 100%;}
.content rich-text img {
max-width: 100%;
}
image {
max-width: 100%;
......
......@@ -138,10 +138,10 @@
if (orderErr) {
uni.hideLoading()
isPaying.value = false
uni.showToast({
title: '创建订单失败',
icon: 'none'
})
// uni.showToast({
// title: '创建订单失败',
// icon: 'none'
// })
return
}
......@@ -161,7 +161,7 @@
isPaying.value = false
// 支付成功,跳转页面
uni.navigateTo({
uni.redirectTo({
url: `/personal/sucPay?orderId=${orderRes.data.orderId}`
})
}
......
<template>
<view class="page-container">
<view class="top-section">
<!-- 会员卡区域 -->
<view class="member-card">
<image class="card-bg" :src="config.baseUrl_api + '/fs/static/slices/user_01@2x.png'" mode="aspectFill">
</image>
<!-- 绑定/解绑学员 -->
<view v-if="!isBound" class="bind-student" @click="handleBindAction">
<text>{{ isBound ? '解绑' : '绑定学员' }}</text>
<image class="arrow-icon" :src="config.baseUrl_api + '/fs/static/slices/bd@2x.png'" mode="aspectFit">
</image>
</view>
<!-- 用户信息 -->
<view class="user-info">
<view class="avatar">
<view class="avatar-placeholder">📄</view>
<view class="user-section">
<view class="user-top">
<view class="avatar-wrap">
<image class="avatar" :src="config.baseUrl_api + '/fs/static/slices/tx@2x.png'"
mode="aspectFill">
</image>
</view>
<view class="user-desc">注册会员8709745760778985472</view>
<view class="member-id">{{ userInfo.userName }}</view>
</view>
<!-- 会员卡片 -->
<view class="member-card">
<view class="card-header">
<view class="card-name">江行知</view>
<view class="bind-btn">绑定学员 ⇄</view>
<view class="user-bottom">
<view class="user-name">{{ perInfo?.perName }}</view>
<view class="card-info">
<view class="info-row">会员卡号:{{ perInfo?.perCode }}</view>
<view class="info-row">会员有效期:{{ perInfo?.perValidDate }}</view>
</view>
<view class="card-id">证件号:360681201804040811</view>
<view class="card-func">
<view class="func-item" @click="goToInfo">
<view class="func-icon"></view>
<view class="func-text">人员信息</view>
</view>
<view class="func-item">
<view class="func-icon"></view>
<view class="func-text">参赛能力认证</view>
</view>
<view class="func-item">
<view class="func-icon">🏆</view>
<view class="func-text">成绩查询</view>
<!-- 已过期印章 -->
<image v-if="perInfo?.perValidDateFlag && perInfo?.perValidDateFlag!='1'" class="expired-stamp"
:src="config.baseUrl_api + '/fs/static/slices/end@2x.png'" mode="aspectFit">
</image>
</view>
<view class="func-item">
<view class="func-icon"></view>
<view class="func-text">参赛记录</view>
<!-- 功能按钮卡片 -->
<view class="func-card">
<view class="func-list">
<view class="func-item" @click="goToAuth">
<image class="func-icon" :src="config.baseUrl_api + '/fs/static/slices/btn01@2x.png'"
mode="aspectFit">
</image>
<text class="func-text">参赛能力认证</text>
</view>
<view class="func-item" @click="goToScore">
<image class="func-icon" :src="config.baseUrl_api + '/fs/static/slices/btn02@2x.png'"
mode="aspectFit">
</image>
<text class="func-text">成绩查询</text>
</view>
<view class="func-item" @click="goToRecord">
<image class="func-icon" :src="config.baseUrl_api + '/fs/static/slices/btn03@2x.png'"
mode="aspectFit">
</image>
<text class="func-text">参赛记录</text>
</view>
</view>
<view class="bottom-section">
<view class="info-title">
<view class="title-line"></view>
<text>人员信息</text>
</view>
<view class="info-list">
<view class="info-item">
<view class="item-label">姓名</view>
<view class="item-value">江行知</view>
<!-- 人员信息区域 -->
<view class="info-section">
<view class="section-title">
<view class="title-bar"></view>
<text class="title-text">人员信息</text>
</view>
<view class="info-card">
<view class="info-item">
<view class="item-label">国籍</view>
<view class="item-value">中国</view>
<text class="item-label">姓名</text>
<text class="item-value">{{ perInfo?.perName }}</text>
</view>
<view class="info-item">
<view class="item-label">证件类型</view>
<view class="item-value">身份证</view>
<text class="item-label">证件类型</text>
<text class="item-value">{{ perInfo?.idcTypeStr }}</text>
</view>
<view class="info-item">
<view class="item-label">身份证号</view>
<view class="item-value">360681201804040811</view>
<text class="item-label">身份证号</text>
<text class="item-value">{{ perInfo?.perIdcCode }}</text>
</view>
<view class="info-item">
<view class="item-label">生日</view>
<view class="item-value">2018-04-04</view>
<text class="item-label">生日</text>
<text class="item-value">{{ perInfo?.birth }}</text>
</view>
</view>
</view>
<!-- 退出登录按钮 -->
<view class="logout-section">
<view class="logout-btn" @click="handleLogout">退出登录</view>
</view>
<!-- 绑定学员弹框 -->
<uni-popup ref="bindPopup" type="center" :mask-click="false">
<view class="bind-popup">
<view class="popup-title">绑定学员</view>
<view class="popup-content">
<view class="form-item">
<view class="form-label">姓名</view>
<view class="form-input">
<input v-model="bindForm.name" placeholder="请输入姓名" placeholder-class="placeholder-class" />
</view>
</view>
<view class="form-item">
<view class="form-label">证件号</view>
<view class="form-input">
<input v-model="bindForm.idcCode" placeholder="请输入证件号"
placeholder-class="placeholder-class" />
</view>
</view>
</view>
<view class="popup-btns">
<view class="popup-btn cancel" @click="closeBindPopup">取消</view>
<view class="popup-btn confirm" @click="confirmBind">确定</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { ref } from 'vue'
const userInfo = ref({
memberNo: '8709745760778985472',
name: '江行知',
idCard: '360681201804040811',
nationality: '中国',
idType: '身份证',
birthday: '2018-04-04'
})
const goToInfo = () => {
console.log('跳转到人员信息页')
}
import {
computed,
onMounted,
ref,
watch,
nextTick
} from "vue";
import config from "/config.js";
import {
wxLogin,
logout,
getWebInfo
} from '@/common/login.js';
import {
useUserStore
} from "../store/modules/user";
import to from 'await-to-js'
import {
bindUser,
unbindUser
} from '@/common/api.js'
const userStore = useUserStore()
const userInfo = computed(() => userStore.user)
const perInfo = computed(() => userStore.perInfo)
// 是否已绑定学员
const isBound = computed(() => {
const perId = userInfo.value?.perId
return perId !== undefined && perId !== null && perId !== 0
})
const bindPopup = ref(null)
const bindForm = ref({
name: '',
idcCode: ''
})
onMounted(() => {
let webUserName = uni.getStorageSync('webUserName')
if (!webUserName) {
wxLogin()
}
})
watch(() => userInfo.value.perId, (val) => {
if (val !== undefined && val == 0) {
nextTick(() => {
openBindPopup()
})
}
}, {
immediate: true
})
// 打开绑定弹框
const openBindPopup = () => {
if (bindPopup.value) {
bindForm.value = {
name: '',
idcCode: ''
}
bindPopup.value.open()
} else {
nextTick(() => {
openBindPopup()
})
}
}
// 关闭绑定弹框
const closeBindPopup = () => {
bindPopup.value?.close()
}
// 处理绑定/解绑操作
const handleBindAction = () => {
if (isBound.value) {
// 已绑定,执行解绑
uni.showModal({
content: '确认解绑吗?',
success: async (res) => {
if (res.confirm) {
uni.showLoading({
title: '解绑中...',
mask: true
})
const [err] = await to(unbindUser())
uni.hideLoading()
if (err) return
uni.showToast({
title: '解绑成功',
icon: 'success'
})
// 刷新用户信息
getWebInfo()
}
}
})
} else {
// 未绑定,打开绑定弹框
openBindPopup()
}
}
// 确认绑定
const confirmBind = async () => {
if (!bindForm.value.name) {
uni.showToast({
title: '请输入姓名',
icon: 'none'
})
return
}
if (!bindForm.value.idcCode) {
uni.showToast({
title: '请输入证件号',
icon: 'none'
})
return
}
uni.showLoading({
title: '绑定中...',
mask: true
})
const [err, res] = await to(bindUser({
name: bindForm.value.name,
idcCode: bindForm.value.idcCode
}))
uni.hideLoading()
if (err) {
// uni.showToast({
// title: '绑定失败',
// icon: 'none'
// })
return
}
uni.showToast({
title: '绑定成功',
icon: 'success'
})
closeBindPopup()
// 刷新用户信息
getWebInfo()
}
const goToAuth = () => {
console.log("参赛能力认证");
};
const goToScore = () => {
console.log("成绩查询");
};
const goToRecord = () => {
console.log("参赛记录");
};
// 退出登录
const handleLogout = () => {
uni.showModal({
content: `确认退出吗?`,
success: function(res) {
if (res.confirm) {
logout().then(() => {
uni.reLaunch({
url: '/login/login'
})
})
}
}
})
}
</script>
<style lang="scss" scoped>
.page-container {
.page-container {
min-height: 100vh;
background: linear-gradient(180deg, #FFF9E8 0%, #FFFFFF 100%);
padding: 0 30rpx;
box-sizing: border-box;
}
.top-section {
padding-top: 40rpx;
}
background: #f5f5f5;
padding-bottom: 40rpx;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 40rpx;
}
/* 会员卡 */
.member-card {
position: relative;
height: 450rpx;
border-radius: 0;
overflow: hidden;
}
.title {
font-size: 36rpx;
font-weight: 500;
color: #333;
margin: 0 auto;
.card-bg {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.more-btn {
.bind-student {
position: absolute;
top: 30rpx;
right: 30rpx;
display: flex;
align-items: center;
gap: 20rpx;
margin-left: auto;
background: #FFFFFF;
padding: 10rpx 20rpx;
border-radius: 40rpx;
}
gap: 8rpx;
z-index: 10;
padding: 10rpx 16rpx;
background: rgba(255, 255, 255, 0.5);
border-radius: 30rpx;
}
.dots {
font-size: 32rpx;
color: #666;
line-height: 1;
}
.bind-student text {
font-size: 26rpx;
color: #8b7355;
}
.circle {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
border: 2rpx solid #666;
.arrow-icon {
width: 28rpx;
height: 28rpx;
}
.user-section {
position: relative;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: #666;
z-index: 1;
padding: 50rpx 30rpx 0;
}
}
.user-info {
.user-top {
display: flex;
align-items: center;
gap: 30rpx;
margin-bottom: 40rpx;
}
gap: 20rpx;
margin-bottom: 20rpx;
}
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background: #F5F5F5;
display: flex;
align-items: center;
justify-content: center;
font-size: 48rpx;
border: 4rpx solid #E8E8E8;
}
.avatar-wrap {
flex-shrink: 0;
}
.avatar-placeholder {
color: #999;
}
.avatar {
width: 110rpx;
height: 110rpx;
border-radius: 50%;
border: 3rpx solid rgba(255, 255, 255, 0.6);
}
.user-desc {
font-size: 36rpx;
color: #333;
font-weight: 500;
}
.member-id {
font-size: 26rpx;
color: #8b7355;
}
/* 会员卡片 */
.member-card {
background: linear-gradient(135deg, #F7E090 0%, #E6C560 100%);
border-radius: 24rpx;
padding: 40rpx;
position: relative;
overflow: hidden;
margin-bottom: 30rpx;
.user-bottom {
padding-left: 0;
}
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url('data:image/svg+xml,%3Csvg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M0,50 Q250,20 500,50 T1000,50" fill="none" stroke="%23E6C560" stroke-width="2" opacity="0.3"/%3E%3C/svg%3E');
background-size: cover;
z-index: 0;
.user-name {
font-size: 44rpx;
font-weight: bold;
color: #5c4b37;
margin-bottom: 16rpx;
}
}
.card-header {
.card-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
position: relative;
z-index: 1;
}
flex-direction: column;
gap: 10rpx;
}
.card-name {
font-size: 40rpx;
font-weight: bold;
color: #222;
}
.info-row {
font-size: 24rpx;
color: #8b7355;
}
.bind-btn {
font-size: 28rpx;
color: #666;
}
/* 已过期印章 */
.expired-stamp {
position: absolute;
right: 30rpx;
bottom: 100rpx;
width: 150rpx;
height: 150rpx;
z-index: 1;
}
.card-id {
font-size: 28rpx;
color: #555;
margin-bottom: 40rpx;
/* 功能按钮卡片 */
.func-card {
margin: -70rpx 30rpx 30rpx;
background: #ffffff;
border-radius: 20rpx;
padding: 36rpx 0;
box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.06);
position: relative;
z-index: 1;
}
z-index: 2;
}
/* 功能入口 */
.card-func {
.func-list {
display: flex;
justify-content: space-between;
position: relative;
z-index: 1;
}
justify-content: space-around;
padding: 0 20rpx;
}
.func-item {
.func-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 10rpx;
cursor: pointer;
}
gap: 12rpx;
}
.func-icon {
width: 60rpx;
height: 60rpx;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: #333;
}
.func-icon {
width: 72rpx;
height: 72rpx;
}
.func-text {
font-size: 28rpx;
.func-text {
font-size: 24rpx;
color: #333;
font-weight: 500;
}
}
/* ========== 下半部分:人员信息 ========== */
.bottom-section {
background: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
padding: 30rpx;
margin-top: 20rpx;
}
/* 人员信息区域 */
.info-section {
margin: 0 30rpx;
}
.info-title {
.section-title {
display: flex;
align-items: center;
gap: 16rpx;
margin-bottom: 30rpx;
font-size: 36rpx;
font-weight: 500;
color: #333;
}
gap: 12rpx;
margin-bottom: 20rpx;
}
.title-line {
width: 12rpx;
.title-bar {
width: 6rpx;
height: 32rpx;
background: #E6C560;
border-radius: 4rpx;
}
background: #e6c560;
border-radius: 3rpx;
}
.info-list {
display: flex;
flex-direction: column;
gap: 30rpx;
}
.title-text {
font-size: 30rpx;
font-weight: 500;
color: #333;
}
.info-card {
background: #ffffff;
border-radius: 20rpx;
padding: 0 32rpx;
}
.info-item {
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #F0F0F0;
padding: 28rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
&:last-child {
.info-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
}
.item-label {
font-size: 32rpx;
.item-label {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
}
.item-value {
font-size: 32rpx;
.item-value {
font-size: 28rpx;
color: #999;
}
}
/* 底部固定按钮(可选) */
.fixedBottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx;
background: #FFFFFF;
border-top: 1rpx solid #F0F0F0;
}
/* 绑定学员弹框 */
.bind-popup {
width: 600rpx;
background: #ffffff;
border-radius: 24rpx;
overflow: hidden;
}
.btn-red {
.popup-title {
font-size: 32rpx;
font-weight: 500;
color: #333;
text-align: center;
padding: 40rpx 30rpx 20rpx;
}
.popup-content {
padding: 20rpx 30rpx 40rpx;
}
.form-item {
display: flex;
align-items: center;
margin-bottom: 24rpx;
}
.form-item:last-child {
margin-bottom: 0;
}
.form-label {
width: 120rpx;
font-size: 28rpx;
color: #333;
flex-shrink: 0;
}
.form-input {
flex: 1;
background: #f5f5f5;
border-radius: 12rpx;
padding: 20rpx 24rpx;
}
.form-input input {
font-size: 28rpx;
color: #333;
width: 100%;
}
.placeholder-class {
color: #999;
}
.popup-btns {
display: flex;
border-top: 1rpx solid #eee;
}
.popup-btn {
flex: 1;
height: 100rpx;
line-height: 100rpx;
text-align: center;
font-size: 30rpx;
}
.popup-btn.cancel {
color: #666;
border-right: 1rpx solid #eee;
}
.popup-btn.confirm {
color: #C40F18;
font-weight: 500;
}
/* 退出登录 */
.logout-section {
margin: 60rpx 30rpx 40rpx;
}
.logout-btn {
height: 88rpx;
line-height: 88rpx;
background: #C40F18;
color: #FFFFFF;
border-radius: 12rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
}
text-align: center;
font-size: 30rpx;
color: #999;
background: #ffffff;
border-radius: 20rpx;
}
</style>
\ No newline at end of file
......
......@@ -31,32 +31,36 @@
</template>
<script setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
// 核心数据
const formData = ref({}) // 订单统计数据
const price = ref('') // 核心业务ID
const payType = ref('0') // 支付方式(默认0=民生付)
const payLoading = ref(false) // 支付按钮加载状态
// 页面加载接收参数
onLoad(async (options) => {
import {
ref
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
// 核心数据
const formData = ref({}) // 订单统计数据
const price = ref('') // 核心业务ID
const payType = ref('0') // 支付方式(默认0=民生付)
const payLoading = ref(false) // 支付按钮加载状态
// 页面加载接收参数
onLoad(async (options) => {
console.log('订单ID:', options.price)
if (options.price) {
price.value = options.price
}
})
})
// 支付方式切换
function handlePayTypeChange(e) {
// 支付方式切换
function handlePayTypeChange(e) {
payType.value = e.detail.value
}
}
// 立即支付核心逻辑
async function handlePay() {
// 立即支付核心逻辑
async function handlePay() {
try {
......@@ -65,7 +69,7 @@ async function handlePay() {
if (res.data?.orderId) {
api.pcallBack2(res.data.orderId)
uni.navigateTo({
uni.redirectTo({
url: `/personal/sucPay`
})
}
......@@ -74,25 +78,30 @@ async function handlePay() {
} catch (err) {
const errMsg = err?.data?.msg || err?.message || '支付失败,请稍后重试'
uni.showToast({ title: errMsg, icon: 'none' })
uni.showToast({
title: errMsg,
icon: 'none'
})
} finally {
payLoading.value = false
}
}
}
</script>
<style scoped lang="scss">
.pay-order-container {
.pay-order-container {
padding: 30rpx;
background-color: #fff;
min-height: 100vh;
box-sizing: border-box;
}
.icon{
width:30px;
}
// 页面头部
.page-header {
}
.icon {
width: 30px;
}
// 页面头部
.page-header {
text-align: center;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
......@@ -103,10 +112,10 @@ async function handlePay() {
font-weight: 600;
color: #333;
}
}
}
// 订单信息区域
.order-info {
// 订单信息区域
.order-info {
margin-bottom: 60rpx;
.info-item {
......@@ -144,10 +153,10 @@ async function handlePay() {
font-size: 38rpx;
}
}
}
}
// 支付方式区域
.pay-type-section {
// 支付方式区域
.pay-type-section {
margin-bottom: 80rpx;
.section-title {
......@@ -175,10 +184,10 @@ async function handlePay() {
}
}
}
}
}
// 底部支付按钮
.fixed-bottom {
// 底部支付按钮
.fixed-bottom {
position: fixed;
bottom: 0;
left: 0;
......@@ -200,5 +209,5 @@ async function handlePay() {
background-color: #E60012;
color: #fff;
}
}
}
</style>
\ No newline at end of file
......
......@@ -64,7 +64,8 @@
<uni-forms-item label="头像" required>
<uni-file-picker v-model="photoArr" @delete="delPhoto" return-type="object" limit="1"
@select="upPhoto" :del-ico="false" :image-styles="imageStylesTx"></uni-file-picker>
<image mode="aspectFill" v-if="baseFormData.photo2" style="height:200rpx;width:200rpx;" :src="config.baseUrl_api + baseFormData.photo2"/>
<image mode="aspectFill" v-if="baseFormData.photo2" style="height:200rpx;width:200rpx;"
:src="config.baseUrl_api + baseFormData.photo2" />
</uni-forms-item>
</view>
</uni-forms>
......@@ -80,7 +81,8 @@
<view class="fixedBottom"><button class="btn-red" @click="goSubmit">确 定</button></view>
<!-- 会员须知 -->
<uni-popup ref="popup" type="bottom" background-color="#fff" animation :disable-scroll="true" :mask-click="false">
<uni-popup ref="popup" type="bottom" background-color="#fff" animation :disable-scroll="true"
:mask-click="false">
<view class="tt">入会须知</view>
<view class="popBody">
_{{baseFormData.name}}_欢迎您申请成为中国跆拳道协会(以下简称中国跆协)会员,请确保本次申请是经过您本人或监护人授权同意后的自愿行为,请您务必仔细阅读本入会须知。
......@@ -297,7 +299,7 @@
baseFormData.value.photo = data.data.fang;
baseFormData.value.photo2 = data.data.yuan;
photoArr.value = {
url: config.baseUrl_api+baseFormData.value.photo,
url: config.baseUrl_api + baseFormData.value.photo,
name: '头像',
extname: 'jpg'
}
......@@ -492,8 +494,8 @@
content: '请确认信息正确',
success: function(res) {
if (res.confirm) {
if(baseFormData.value.idcType=='4'){
baseFormData.value.idcType='0'
if (baseFormData.value.idcType == '4') {
baseFormData.value.idcType = '0'
}
delete baseFormData.value.card
......@@ -523,16 +525,16 @@
uni.showModal({
content: '保存成功',
title: '提示',
confirmText:'继续添加',
cancelColor:'返回首页',
confirmText: '继续添加',
cancelColor: '返回首页',
success: function(res) {
uni.redirectTo({
url: `/personalVip/addVip?tab=${current.value}&idcType=${baseFormData.value.idcType}`
});
},
fail:function(){
fail: function() {
uni.reLaunch({
url:`/pages/index/index`
url: `/pages/index/home`
})
}
})
......@@ -542,6 +544,7 @@
}
});
}
function getUserInfo() {
api.getInfo(perId.value).then(res => {
baseFormData.value = res.data
......@@ -553,7 +556,6 @@
</script>
<style lang="scss">
/* 字段名左对齐 */
.uni-forms-item .uni-forms-item__label {
text-align: left !important;
......@@ -582,11 +584,10 @@
/* 文本内容右对齐 */
.uni-forms-item .uni-forms-item__content text,
.uni-forms-item .uni-forms-item__content > text {
.uni-forms-item .uni-forms-item__content>text {
display: inline-block !important;
white-space: nowrap !important;
}
</style>
<style lang="scss" scoped>
......@@ -598,9 +599,11 @@
right: 0;
bottom: 0;
}
:deep(.uni-popup) {
overflow: hidden !important;
}
:deep(.segmented-control) {
height: 100rpx;
}
......@@ -676,6 +679,7 @@
:deep(.item-text-overflow) {
text-align: left;
}
:deep(.fixUniFormItemStyle .uni-data-picker__input-box) {
justify-content: flex-start !important;
text-align: left !important;
......
No preview for this file type
import {
createPinia
} from "pinia";
const store = createPinia()
export default store
\ No newline at end of file
import {
defineStore
} from "pinia";
import {
ref
} from 'vue'
export const useUserStore = defineStore('user', () => {
const user = ref(null)
const perInfo = ref(null)
const setUser = (value) => {
user.value = value
}
const setPerInfo = (value) => {
perInfo.value = value
}
return {
user,
setUser,
perInfo,
setPerInfo
}
})
\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!