Compare commits
57 Commits
Author | SHA1 | Date | |
---|---|---|---|
e0858ea909 | |||
6c2d306515 | |||
94dc4c2a39 | |||
b14826e6d1 | |||
2c0698910e | |||
731ad48407 | |||
0d5038bffc | |||
6dae410db8 | |||
6553f4ac34 | |||
95aa4241c0 | |||
9b2bcbaeba | |||
b3aeda2236 | |||
1e0cdd5cde | |||
780235f800 | |||
e4a26b9013 | |||
6a824c0b6c | |||
ae4aa297c3 | |||
de3915db25 | |||
a30b63dd36 | |||
206a594395 | |||
f5986eeca5 | |||
c015fe630d | |||
c3ff3708c6 | |||
fedcb33d15 | |||
fa76fad14d | |||
0dae8e26fb | |||
5c1328bcea | |||
e986e2917e | |||
ee496f298d | |||
fffbe3b63e | |||
ad4d788585 | |||
216aee9b4c | |||
c544164e0e | |||
db9bfe5fd4 | |||
af55a106e3 | |||
668a96a8ff | |||
16d3488c80 | |||
621f1d2f40 | |||
3d280f21cf | |||
77985bd2f3 | |||
efad69a78b | |||
70eb04db12 | |||
95668bb1ad | |||
acb4539165 | |||
6276ee6465 | |||
d134d3120e | |||
a76d89c31b | |||
b990b94490 | |||
7a08be77a7 | |||
acd816b2e3 | |||
a45790073b | |||
f62148c7f5 | |||
9b2db7d33d | |||
9148ba0877 | |||
2822b072e9 | |||
8ad6af6611 | |||
23a2438a88 |
@ -15,3 +15,4 @@
|
||||
]
|
||||
}
|
||||
|
||||
|
1666
package-lock.json
generated
@ -49,8 +49,8 @@
|
||||
"@dcloudio/uni-mp-xhs": "3.0.0-3090820231124001",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-3090820231124001",
|
||||
"@xingyy/uni-fetch": "^1.0.2",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "5.4.2",
|
||||
"node-sass": "^9.0.0",
|
||||
"pinia": " 2.0.33",
|
||||
"sass": "^1.69.5",
|
||||
"sass-loader": "^13.3.2",
|
||||
|
19
src/App.vue
@ -1,17 +1,22 @@
|
||||
<template>
|
||||
</template>
|
||||
<script lang="ts" setup></script>
|
||||
<script setup>
|
||||
import {onLaunch} from "@dcloudio/uni-app";
|
||||
|
||||
|
||||
onLaunch(()=>{
|
||||
console.log('onLaunch')
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
@import url('@/components/transition-min/transition.min.css');
|
||||
/* #ifdef APP-PLUS-NVUE */
|
||||
@import './tmui/scss/nvue.css';
|
||||
/* #endif */
|
||||
/* #ifndef APP-PLUS-NVUE */
|
||||
@import './tmui/scss/noNvue.css';
|
||||
/* #endif */
|
||||
|
||||
page{
|
||||
display: flex;
|
||||
|
||||
}
|
||||
|
||||
page{
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
82
src/components/custom-title/index.vue
Normal file
@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div class="content2" :style="{height: `${menuButtonTop}px`}">
|
||||
<div class="wrap2" v-if="isBack" @click="goBack">
|
||||
<image src="../../static/tbys@3x.png"></image>
|
||||
</div>
|
||||
<div class="wrap1" :style="{marginTop: `${titleTop}px`,height:`${titleHeight}px`}">{{title}}</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup >
|
||||
import { ref } from 'vue'
|
||||
const menuButtonTop=ref(0)
|
||||
const rpxToPx=(rpx)=>{
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
const screenWidth = systemInfo.windowWidth;
|
||||
return rpx * screenWidth / 750;
|
||||
}
|
||||
const titleTop=ref(0)
|
||||
const titleHeight=ref(0)
|
||||
const goBack=()=>{
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}
|
||||
const getMenuButtonBoundingClientRect=()=> {
|
||||
// #ifdef MP-WEIXIN
|
||||
const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
if (menuButtonInfo) {
|
||||
titleTop.value=menuButtonInfo.top
|
||||
titleHeight.value=menuButtonInfo.height
|
||||
menuButtonTop.value = menuButtonInfo.top + menuButtonInfo.height+rpxToPx(12);
|
||||
}
|
||||
}
|
||||
getMenuButtonBoundingClientRect()
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isBack: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
|
||||
const back = () => {
|
||||
uni.navigateBack({
|
||||
delta: 2
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.content2{
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width:100vw;
|
||||
background-image: url("https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/6f9f30f6-9383-4ae6-872c-4e6795eaa25f.png");
|
||||
.wrap2{
|
||||
left: 42rpx;
|
||||
bottom: 26rpx;
|
||||
position: absolute;
|
||||
width: 18rpx;
|
||||
height: 34rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.wrap1{
|
||||
font-size: 34rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,19 +0,0 @@
|
||||
<template>
|
||||
<div class="content3">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style scoped>
|
||||
.content3{
|
||||
height: 1rpx;
|
||||
width: 100%;
|
||||
background-image: url("../../static/zx303@3x (1).png");
|
||||
background-size: 100%;
|
||||
}
|
||||
</style>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="content2">
|
||||
<div class="content2" :style="styleColor">
|
||||
<div class="wrap1" v-for="item in result">
|
||||
<div class="wrap1_1">
|
||||
<slot :name="Object.keys(item).find(x=>x.includes('l'))"></slot>
|
||||
@ -11,8 +11,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup >
|
||||
import {useSlots,ref} from 'vue'
|
||||
import {useSlots,ref,defineProps} from 'vue'
|
||||
const slots = useSlots();
|
||||
const prop=defineProps({
|
||||
styleColor:{
|
||||
type:Object,
|
||||
default:()=>{
|
||||
return {backgroundColor:'#fff'}
|
||||
}
|
||||
}
|
||||
})
|
||||
const groupObjectsByNumberKeys=(obj)=> {
|
||||
const grouped = {};
|
||||
for (const key in obj) {
|
||||
@ -26,12 +34,8 @@ const groupObjectsByNumberKeys=(obj)=> {
|
||||
}
|
||||
const result = ref(groupObjectsByNumberKeys(slots))
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content2{
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding-left: 18rpx;
|
||||
padding-right: 32rpx;
|
||||
@ -41,12 +45,20 @@ const result = ref(groupObjectsByNumberKeys(slots))
|
||||
padding-bottom: 22rpx;
|
||||
border-bottom: 1rpx solid #E4EAF1;;
|
||||
display: flex;
|
||||
&:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
.wrap1_2{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
padding-left: 36rpx;
|
||||
font-size: 24rpx;
|
||||
color: #939393;
|
||||
}
|
||||
.wrap1_1{
|
||||
padding-right: 30rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 192rpx;
|
||||
|
@ -1,31 +1,79 @@
|
||||
<template>
|
||||
|
||||
<tm-tabbar :autoSelect="false" v-model:active="acc">
|
||||
<tm-tabbar-item
|
||||
@click="acc = 0"
|
||||
activeColor="#EB783C"
|
||||
open-type="reLaunch"
|
||||
text="选票"
|
||||
>
|
||||
<div style="width: 52rpx;height: 52rpx">
|
||||
<img v-if="acc===0" style="width: 100%;height: 100%" src="../../static/zu618.png" alt="">
|
||||
<img v-else style="width: 100%;height: 100%" src="../../static/zu759@3x (1).png" alt="">
|
||||
<div class="main">
|
||||
<div class="content1" @click="goContent" >
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">
|
||||
<img v-show="acc===0" class="ld ld-fall-ttb-in" style="width: 52rpx;height:52rpx" src="../../static/zu618.png" alt="">
|
||||
<img v-show="acc!==0" style="width: 52rpx;height:52rpx" src="../../static/zu759@3x.png" alt="">
|
||||
</div>
|
||||
</tm-tabbar-item>
|
||||
<tm-tabbar-item @click="acc = 1" activeColor="#EB783C" text="我的">
|
||||
<div style="width: 52rpx;height: 52rpx">
|
||||
<img v-if="acc===0" style="width: 100%;height: 100%" src="../../static/zu628.png" alt="">
|
||||
<img v-else style="width: 100%;height: 100%" src="../../static/zu-44.png" alt="">
|
||||
<div :style="{color: acc===0?'#EB783C':'#000'}" class="wrap1_2">
|
||||
选票
|
||||
</div>
|
||||
</tm-tabbar-item>
|
||||
</tm-tabbar>
|
||||
|
||||
</div>
|
||||
<div class="wrap2">
|
||||
<div class="wrap2_1">
|
||||
<img v-show="acc===0" style="width: 52rpx;height:52rpx" src="../../static/zu628.png" alt="">
|
||||
<img v-show="acc!==0" class="ld ld-fall-ttb-in" style="width: 52rpx;height:52rpx" src="../../static/zu-44.png" alt="">
|
||||
</div>
|
||||
<div :style="{color: acc===1?'#EB783C':'#000'}" class="wrap2_2">我的</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref, defineEmits, watch,} from 'vue'
|
||||
import {ref, defineEmits, watch} from 'vue'
|
||||
const emit=defineEmits(['update:modelValue'])
|
||||
const acc = ref(1)
|
||||
const goContent=(event)=>{
|
||||
const windowWidth = uni.getSystemInfoSync().windowWidth;
|
||||
if (event.changedTouches[0].clientX<windowWidth/2){
|
||||
acc.value=0
|
||||
}else {
|
||||
acc.value=1
|
||||
}
|
||||
}
|
||||
const acc = ref(0)
|
||||
watch(acc,()=>{
|
||||
emit('update:modelValue',acc.value)
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.main{
|
||||
box-shadow: 0px -15rpx 30rpx 0px rgba(0, 0, 0, 0.1);
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: 9;
|
||||
height: 170rpx;
|
||||
width: 750rpx;
|
||||
background-color: #fff;
|
||||
.content1{
|
||||
padding-right: 222rpx;
|
||||
padding-left: 222rpx;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.wrap1{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-right: 206rpx;
|
||||
.wrap1_2{
|
||||
margin-top: 4rpx;
|
||||
color: #000;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
.wrap2{
|
||||
margin-right: 206rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap2_2{
|
||||
margin-top: 4rpx;
|
||||
color: #000;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div class="content1" :style="{ marginTop: `${statusBarHeight}px` }">
|
||||
<div class="wrap1" v-if="isBack">
|
||||
<tm-icon name="tmicon-angle-left" color="#FFFFFF" @click="back"></tm-icon>
|
||||
</div>
|
||||
<div class="wrap2">{{ title }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup >
|
||||
import { ref } from 'vue'
|
||||
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight + 5)
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isBack: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
const back = () => {
|
||||
uni.navigateBack({
|
||||
delta: 2
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content1 {
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.wrap1 {
|
||||
flex-basis: 0;
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.wrap3 {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
}
|
||||
|
||||
.wrap2 {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
color: #FFFFFF;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
1
src/components/transition-min/transition.min.css
vendored
Normal file
131
src/components/uni-transition/createAnimation.js
Normal file
@ -0,0 +1,131 @@
|
||||
// const defaultOption = {
|
||||
// duration: 300,
|
||||
// timingFunction: 'linear',
|
||||
// delay: 0,
|
||||
// transformOrigin: '50% 50% 0'
|
||||
// }
|
||||
// #ifdef APP-NVUE
|
||||
const nvueAnimation = uni.requireNativePlugin('animation')
|
||||
// #endif
|
||||
class MPAnimation {
|
||||
constructor(options, _this) {
|
||||
this.options = options
|
||||
// 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
|
||||
this.animation = uni.createAnimation({
|
||||
...options
|
||||
})
|
||||
this.currentStepAnimates = {}
|
||||
this.next = 0
|
||||
this.$ = _this
|
||||
|
||||
}
|
||||
|
||||
_nvuePushAnimates(type, args) {
|
||||
let aniObj = this.currentStepAnimates[this.next]
|
||||
let styles = {}
|
||||
if (!aniObj) {
|
||||
styles = {
|
||||
styles: {},
|
||||
config: {}
|
||||
}
|
||||
} else {
|
||||
styles = aniObj
|
||||
}
|
||||
if (animateTypes1.includes(type)) {
|
||||
if (!styles.styles.transform) {
|
||||
styles.styles.transform = ''
|
||||
}
|
||||
let unit = ''
|
||||
if(type === 'rotate'){
|
||||
unit = 'deg'
|
||||
}
|
||||
styles.styles.transform += `${type}(${args+unit}) `
|
||||
} else {
|
||||
styles.styles[type] = `${args}`
|
||||
}
|
||||
this.currentStepAnimates[this.next] = styles
|
||||
}
|
||||
_animateRun(styles = {}, config = {}) {
|
||||
let ref = this.$.$refs['ani'].ref
|
||||
if (!ref) return
|
||||
return new Promise((resolve, reject) => {
|
||||
nvueAnimation.transition(ref, {
|
||||
styles,
|
||||
...config
|
||||
}, res => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_nvueNextAnimate(animates, step = 0, fn) {
|
||||
let obj = animates[step]
|
||||
if (obj) {
|
||||
let {
|
||||
styles,
|
||||
config
|
||||
} = obj
|
||||
this._animateRun(styles, config).then(() => {
|
||||
step += 1
|
||||
this._nvueNextAnimate(animates, step, fn)
|
||||
})
|
||||
} else {
|
||||
this.currentStepAnimates = {}
|
||||
typeof fn === 'function' && fn()
|
||||
this.isEnd = true
|
||||
}
|
||||
}
|
||||
|
||||
step(config = {}) {
|
||||
// #ifndef APP-NVUE
|
||||
this.animation.step(config)
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
|
||||
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
|
||||
this.next++
|
||||
// #endif
|
||||
return this
|
||||
}
|
||||
|
||||
run(fn) {
|
||||
// #ifndef APP-NVUE
|
||||
this.$.animationData = this.animation.export()
|
||||
this.$.timer = setTimeout(() => {
|
||||
typeof fn === 'function' && fn()
|
||||
}, this.$.durationTime)
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
this.isEnd = false
|
||||
let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
|
||||
if(!ref) return
|
||||
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
|
||||
this.next = 0
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
|
||||
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
|
||||
'translateZ'
|
||||
]
|
||||
const animateTypes2 = ['opacity', 'backgroundColor']
|
||||
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
|
||||
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
|
||||
MPAnimation.prototype[type] = function(...args) {
|
||||
// #ifndef APP-NVUE
|
||||
this.animation[type](...args)
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
this._nvuePushAnimates(type, args)
|
||||
// #endif
|
||||
return this
|
||||
}
|
||||
})
|
||||
|
||||
export function createAnimation(option, _this) {
|
||||
if(!_this) return
|
||||
clearTimeout(_this.timer)
|
||||
return new MPAnimation(option, _this)
|
||||
}
|
286
src/components/uni-transition/uni-transition.vue
Normal file
@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createAnimation } from './createAnimation'
|
||||
|
||||
/**
|
||||
* Transition 过渡动画
|
||||
* @description 简单过渡动画组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
|
||||
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
|
||||
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
|
||||
* @value fade 渐隐渐出过渡
|
||||
* @value slide-top 由上至下过渡
|
||||
* @value slide-right 由右至左过渡
|
||||
* @value slide-bottom 由下至上过渡
|
||||
* @value slide-left 由左至右过渡
|
||||
* @value zoom-in 由小到大过渡
|
||||
* @value zoom-out 由大到小过渡
|
||||
* @property {Number} duration 过渡动画持续时间
|
||||
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
|
||||
*/
|
||||
export default {
|
||||
name: 'uniTransition',
|
||||
emits:['click','change'],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modeClass: {
|
||||
type: [Array, String],
|
||||
default() {
|
||||
return 'fade'
|
||||
}
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 300
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
customClass:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
onceRender:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShow: false,
|
||||
transform: '',
|
||||
opacity: 1,
|
||||
animationData: {},
|
||||
durationTime: 300,
|
||||
config: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
this.open()
|
||||
} else {
|
||||
// 避免上来就执行 close,导致动画错乱
|
||||
if (this.isShow) {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 生成样式数据
|
||||
stylesObject() {
|
||||
let styles = {
|
||||
...this.styles,
|
||||
'transition-duration': this.duration / 1000 + 's'
|
||||
}
|
||||
let transform = ''
|
||||
for (let i in styles) {
|
||||
let line = this.toLine(i)
|
||||
transform += line + ':' + styles[i] + ';'
|
||||
}
|
||||
return transform
|
||||
},
|
||||
// 初始化动画条件
|
||||
transformStyles() {
|
||||
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 动画默认配置
|
||||
this.config = {
|
||||
duration: this.duration,
|
||||
timingFunction: 'ease',
|
||||
transformOrigin: '50% 50%',
|
||||
delay: 0
|
||||
}
|
||||
this.durationTime = this.duration
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* ref 触发 初始化动画
|
||||
*/
|
||||
init(obj = {}) {
|
||||
if (obj.duration) {
|
||||
this.durationTime = obj.duration
|
||||
}
|
||||
this.animation = createAnimation(Object.assign(this.config, obj),this)
|
||||
},
|
||||
/**
|
||||
* 点击组件触发回调
|
||||
*/
|
||||
onClick() {
|
||||
this.$emit('click', {
|
||||
detail: this.isShow
|
||||
})
|
||||
},
|
||||
/**
|
||||
* ref 触发 动画分组
|
||||
* @param {Object} obj
|
||||
*/
|
||||
step(obj, config = {}) {
|
||||
if (!this.animation) return
|
||||
for (let i in obj) {
|
||||
try {
|
||||
if(typeof obj[i] === 'object'){
|
||||
this.animation[i](...obj[i])
|
||||
}else{
|
||||
this.animation[i](obj[i])
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`方法 ${i} 不存在`)
|
||||
}
|
||||
}
|
||||
this.animation.step(config)
|
||||
return this
|
||||
},
|
||||
/**
|
||||
* ref 触发 执行动画
|
||||
*/
|
||||
run(fn) {
|
||||
if (!this.animation) return
|
||||
this.animation.run(fn)
|
||||
},
|
||||
// 开始过度动画
|
||||
open() {
|
||||
clearTimeout(this.timer)
|
||||
this.transform = ''
|
||||
this.isShow = true
|
||||
let { opacity, transform } = this.styleInit(false)
|
||||
if (typeof opacity !== 'undefined') {
|
||||
this.opacity = opacity
|
||||
}
|
||||
this.transform = transform
|
||||
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
|
||||
this.$nextTick(() => {
|
||||
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
|
||||
this.timer = setTimeout(() => {
|
||||
this.animation = createAnimation(this.config, this)
|
||||
this.tranfromInit(false).step()
|
||||
this.animation.run()
|
||||
this.$emit('change', {
|
||||
detail: this.isShow
|
||||
})
|
||||
}, 20)
|
||||
})
|
||||
},
|
||||
// 关闭过度动画
|
||||
close(type) {
|
||||
if (!this.animation) return
|
||||
this.tranfromInit(true)
|
||||
.step()
|
||||
.run(() => {
|
||||
this.isShow = false
|
||||
this.animationData = null
|
||||
this.animation = null
|
||||
let { opacity, transform } = this.styleInit(false)
|
||||
this.opacity = opacity || 1
|
||||
this.transform = transform
|
||||
this.$emit('change', {
|
||||
detail: this.isShow
|
||||
})
|
||||
})
|
||||
},
|
||||
// 处理动画开始前的默认样式
|
||||
styleInit(type) {
|
||||
let styles = {
|
||||
transform: ''
|
||||
}
|
||||
let buildStyle = (type, mode) => {
|
||||
if (mode === 'fade') {
|
||||
styles.opacity = this.animationType(type)[mode]
|
||||
} else {
|
||||
styles.transform += this.animationType(type)[mode] + ' '
|
||||
}
|
||||
}
|
||||
if (typeof this.modeClass === 'string') {
|
||||
buildStyle(type, this.modeClass)
|
||||
} else {
|
||||
this.modeClass.forEach(mode => {
|
||||
buildStyle(type, mode)
|
||||
})
|
||||
}
|
||||
return styles
|
||||
},
|
||||
// 处理内置组合动画
|
||||
tranfromInit(type) {
|
||||
let buildTranfrom = (type, mode) => {
|
||||
let aniNum = null
|
||||
if (mode === 'fade') {
|
||||
aniNum = type ? 0 : 1
|
||||
} else {
|
||||
aniNum = type ? '-100%' : '0'
|
||||
if (mode === 'zoom-in') {
|
||||
aniNum = type ? 0.8 : 1
|
||||
}
|
||||
if (mode === 'zoom-out') {
|
||||
aniNum = type ? 1.2 : 1
|
||||
}
|
||||
if (mode === 'slide-right') {
|
||||
aniNum = type ? '100%' : '0'
|
||||
}
|
||||
if (mode === 'slide-bottom') {
|
||||
aniNum = type ? '100%' : '0'
|
||||
}
|
||||
}
|
||||
this.animation[this.animationMode()[mode]](aniNum)
|
||||
}
|
||||
if (typeof this.modeClass === 'string') {
|
||||
buildTranfrom(type, this.modeClass)
|
||||
} else {
|
||||
this.modeClass.forEach(mode => {
|
||||
buildTranfrom(type, mode)
|
||||
})
|
||||
}
|
||||
|
||||
return this.animation
|
||||
},
|
||||
animationType(type) {
|
||||
return {
|
||||
fade: type ? 1 : 0,
|
||||
'slide-top': `translateY(${type ? '0' : '-100%'})`,
|
||||
'slide-right': `translateX(${type ? '0' : '100%'})`,
|
||||
'slide-bottom': `translateY(${type ? '0' : '100%'})`,
|
||||
'slide-left': `translateX(${type ? '0' : '-100%'})`,
|
||||
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
|
||||
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
|
||||
}
|
||||
},
|
||||
// 内置动画类型与实际动画对应字典
|
||||
animationMode() {
|
||||
return {
|
||||
fade: 'opacity',
|
||||
'slide-top': 'translateY',
|
||||
'slide-right': 'translateX',
|
||||
'slide-bottom': 'translateY',
|
||||
'slide-left': 'translateX',
|
||||
'zoom-in': 'scale',
|
||||
'zoom-out': 'scale'
|
||||
}
|
||||
},
|
||||
// 驼峰转中横线
|
||||
toLine(name) {
|
||||
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
93
src/http/apis.js
Normal file
@ -0,0 +1,93 @@
|
||||
import uniReq from '@/http/init'
|
||||
export const login = (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/user/login/wx/telnum',
|
||||
data
|
||||
})
|
||||
}
|
||||
export const getInfo = () => {
|
||||
return uniReq.post({
|
||||
url: '/api/user/info'
|
||||
})
|
||||
}
|
||||
export const ticketlist = (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/ticket/ticketList',
|
||||
isLoading:false,
|
||||
data
|
||||
})
|
||||
}
|
||||
export const unusedTickets = (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/smart/appointment/get/all/unused/tickets',
|
||||
isLoading:false,
|
||||
data
|
||||
})
|
||||
}
|
||||
export const historicalTickets = (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/smart/appointment/get/all/historical/tickets',
|
||||
isLoading:false,
|
||||
data
|
||||
})
|
||||
}
|
||||
export const sendCode = (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/user/send/msg',
|
||||
data
|
||||
})
|
||||
}
|
||||
export const reTicket = (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/smart/appointment/book/ticket',
|
||||
data
|
||||
})
|
||||
}
|
||||
export const upload = (data) => {
|
||||
return uniReq.upload({
|
||||
name: data.name,
|
||||
url: '/api/common/upload',
|
||||
filePath: data.filePath,
|
||||
interceptor: {
|
||||
response(res) {
|
||||
try {
|
||||
return JSON.parse(res.data)
|
||||
} catch (e) {
|
||||
return e
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
export const updateInfo = (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/user/update',
|
||||
data
|
||||
})
|
||||
}
|
||||
export const extractingBlindBoxes= (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/smart/appointment/draw/ticket/from/blind/box',
|
||||
data,
|
||||
isShowMsg:false,
|
||||
})
|
||||
}
|
||||
export const getQrCode= (data) => {
|
||||
return uniReq.get({
|
||||
url: '/api/smart/appointment/qr/get',
|
||||
params:data,
|
||||
responseType: 'arraybuffer'
|
||||
})
|
||||
}
|
||||
export const getTicketPerInfo= (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/smart/appointment/get/ticket/info',
|
||||
data
|
||||
})
|
||||
}
|
||||
export const socketImg= (data) => {
|
||||
return uniReq.post({
|
||||
url: '/api/smart/appointment/pass/picUrl',
|
||||
data
|
||||
})
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import http from "./interface";
|
||||
|
||||
// 地点
|
||||
export const address = () => {
|
||||
return http.request({
|
||||
url: "/api/warehouse/address",
|
||||
method: "POST",
|
||||
});
|
||||
};
|
||||
export default {
|
||||
address,
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
import deposit from "./deposit";
|
||||
import login from "./login";
|
||||
export default {
|
||||
deposit,
|
||||
login,
|
||||
};
|
40
src/http/init.js
Normal file
@ -0,0 +1,40 @@
|
||||
import {uniRequest} from "@/http/main";
|
||||
const TEST_URL='http://172.16.100.93:9052'
|
||||
const TY_URL='https://warehouse.szjixun.cn/ticket'
|
||||
let configV
|
||||
const uniReq=uniRequest.created({
|
||||
baseUrl: TY_URL,
|
||||
interceptor: {
|
||||
request(config){
|
||||
configV=config
|
||||
config.header.Authorization=uni.getStorageSync('token')??''
|
||||
if (config.isLoading){
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
})
|
||||
setTimeout(()=>{
|
||||
uni.hideLoading()
|
||||
},5000)
|
||||
}
|
||||
return config
|
||||
},
|
||||
response(response) {
|
||||
if (configV.isShowMsg){
|
||||
if (response.data.code!==200){
|
||||
uni.showToast({
|
||||
title: response.data.msg,
|
||||
icon: 'none',
|
||||
duration: 1300
|
||||
})
|
||||
}
|
||||
}
|
||||
if (configV.isLoading){
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
return response.data
|
||||
}
|
||||
}
|
||||
})
|
||||
export default uniReq
|
@ -1,24 +0,0 @@
|
||||
import {uniFetch} from "@/http/main";
|
||||
const fetch = new uniFetch({
|
||||
baseUrl: 'https://warehouse.szjixun.cn',
|
||||
interceptors: {
|
||||
//请求拦截器
|
||||
request(config) {
|
||||
return config
|
||||
},
|
||||
//响应拦截器
|
||||
response(response) {
|
||||
if (response.data?.status === 401) {
|
||||
let curPage = getCurrentPages();
|
||||
let route = curPage[curPage.length - 1].route; //获取当前页面的路由
|
||||
if (route !== "pages/login/login") {
|
||||
uni.navigateTo({
|
||||
url: "/pages/login/login",
|
||||
});
|
||||
}
|
||||
}
|
||||
return response
|
||||
}
|
||||
}
|
||||
})
|
||||
export default fetch
|
@ -1,57 +0,0 @@
|
||||
|
||||
import fetch from "@/http/init";
|
||||
// openId
|
||||
export const login = (data) => {
|
||||
return fetch.request({
|
||||
url: "/api/wxuser/openid",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 获取手机号
|
||||
export const getTel = (data) => {
|
||||
return fetch.request({
|
||||
url: "/api/wxuser/get/telnum",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 注册
|
||||
export const register = (data) => {
|
||||
return fetch.request({
|
||||
url: "/api/wxuser/register",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 身份验证
|
||||
export const chenckId = (data) => {
|
||||
return fetch.request({
|
||||
url: "/api/wxuser/ocr",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 法大大
|
||||
export const fddRealName = (data) => {
|
||||
return fetch.request({
|
||||
url: "/api/wxuser/bind/fdd",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
};
|
||||
//法大大是否验证
|
||||
export const checkFdd = () => {
|
||||
return fetch.request({
|
||||
url: "/api/wxuser/fdd/check",
|
||||
method: "POST",
|
||||
});
|
||||
};
|
||||
export default {
|
||||
login,
|
||||
getTel,
|
||||
register,
|
||||
chenckId,
|
||||
fddRealName,
|
||||
checkFdd,
|
||||
};
|
161
src/http/main.ts
@ -1,51 +1,86 @@
|
||||
type HttpMethod =
|
||||
| "GET"
|
||||
| 'GET'
|
||||
| 'get'
|
||||
| "POST"
|
||||
| 'POST'
|
||||
| 'post'
|
||||
| "PUT"
|
||||
| 'PUT'
|
||||
| 'put'
|
||||
| "DELETE"
|
||||
| 'DELETE'
|
||||
| 'delete'
|
||||
| "PATCH"
|
||||
| 'patch'
|
||||
| "OPTIONS"
|
||||
| 'CONNECT'
|
||||
| 'connect'
|
||||
| 'OPTIONS'
|
||||
| 'options'
|
||||
| "HEAD"
|
||||
| 'head'
|
||||
| "TRACE"
|
||||
| 'trace'
|
||||
| "CONNECT"
|
||||
| 'connect';
|
||||
| 'TRACE'
|
||||
| 'trace';
|
||||
interface RequestOptions {
|
||||
baseUrl?: string;
|
||||
url: string;
|
||||
url?: string;
|
||||
isLoading?: boolean;
|
||||
isShowMsg?: boolean;
|
||||
data?: Record<string, any>;
|
||||
method?: HttpMethod;
|
||||
header?: Record<string, string>;
|
||||
params?: Record<string, any>;
|
||||
timeout?: number,
|
||||
dataType?: string,
|
||||
responseType?: string,
|
||||
sslVerify?: boolean,
|
||||
withCredentials?: boolean,
|
||||
firstIpv4?: boolean,
|
||||
enableHttp2?: boolean,
|
||||
enableQuic?: boolean,
|
||||
enableCache?: boolean,
|
||||
enableHttpDNS?: boolean,
|
||||
httpDNSServiceId?: string,
|
||||
enableChunked?: boolean,
|
||||
forceCellularNetwork?: boolean,
|
||||
enableCookie?: boolean,
|
||||
cloudCache?: object | boolean,
|
||||
defer?: boolean,
|
||||
interceptor?: {
|
||||
request?: RequestInterceptor,
|
||||
response?: ResponseInterceptor
|
||||
}
|
||||
}
|
||||
|
||||
interface UploadOptions {
|
||||
url: string,
|
||||
baseUrl?: string,
|
||||
files?: File[],
|
||||
fileType?: 'image' | 'video' | 'audio',
|
||||
file?: File,
|
||||
filePath?: string,
|
||||
name?: string,
|
||||
header?: object,
|
||||
timeout?: number,
|
||||
formData?: object,
|
||||
interceptor?: {
|
||||
request?: (config: UploadOptions) => UploadOptions,
|
||||
response?: (response: any) => any;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type RequestInterceptor = (config: RequestOptions) => RequestOptions;
|
||||
type ResponseInterceptor = (response: any) => any;
|
||||
interface Interceptors {
|
||||
request: (config: RequestOptions) => RequestOptions;
|
||||
response: (response: any) => any;
|
||||
}
|
||||
class uniFetch {
|
||||
baseUrl: string;
|
||||
|
||||
class uniRequest {
|
||||
baseUrl?: string;
|
||||
isLoading: boolean;
|
||||
isShowMsg: boolean;
|
||||
defaultHeader: Record<string, string>;
|
||||
interceptors: { request: RequestInterceptor | null; response: ResponseInterceptor | null };
|
||||
constructor({ baseUrl = '', defaultHeader = {}, interceptors = { request: null, response: null } }: {
|
||||
baseUrl?: string;
|
||||
defaultHeader?: Record<string, string>;
|
||||
interceptors?: Interceptors;
|
||||
}) {
|
||||
this.baseUrl = baseUrl;
|
||||
interceptors: { request?: RequestInterceptor; response?: ResponseInterceptor };
|
||||
|
||||
constructor(request: RequestOptions) {
|
||||
this.isLoading= request.isLoading??true
|
||||
this.isShowMsg= request.isShowMsg??true
|
||||
this.baseUrl = request.baseUrl;
|
||||
this.defaultHeader = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
...defaultHeader,
|
||||
...request.header,
|
||||
};
|
||||
this.interceptors = interceptors;
|
||||
this.interceptors = {request: request.interceptor?.request, response: request.interceptor?.response};
|
||||
}
|
||||
|
||||
setBaseUrl(baseUrl: string): void {
|
||||
@ -55,22 +90,30 @@ class uniFetch {
|
||||
setDefaultHeader(header: Record<string, string>): void {
|
||||
this.defaultHeader = header;
|
||||
}
|
||||
|
||||
static created(options: RequestOptions) {
|
||||
return new uniRequest(options);
|
||||
}
|
||||
request(options: RequestOptions): Promise<any> {
|
||||
options = this.buildRequestOptions(options)
|
||||
options = options || {};
|
||||
options.isLoading ??= this.isLoading;
|
||||
options.isShowMsg ??= this.isShowMsg;
|
||||
options.baseUrl = options.baseUrl || this.baseUrl;
|
||||
options.url = options.baseUrl + options.url;
|
||||
options.url = `${options.baseUrl}${options.url}`;
|
||||
options.data = options.data || {};
|
||||
options.method = options.method || "GET";
|
||||
options.method = (options.method?.toUpperCase() || "GET") as HttpMethod;
|
||||
options.header = options.header || this.defaultHeader;
|
||||
if (this.interceptors.request) {
|
||||
if (typeof options.interceptor?.request === 'function') {
|
||||
options = options.interceptor.request(options);
|
||||
} else if (typeof this.interceptors?.request === 'function') {
|
||||
options = this.interceptors.request(options);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
// @ts-ignore
|
||||
uni.request({
|
||||
...options,
|
||||
success: (res) => {
|
||||
const response = this.handleResponse(res);
|
||||
const response = this.handleResponse(res, options);
|
||||
resolve(response);
|
||||
},
|
||||
fail: (err) => {
|
||||
@ -81,19 +124,20 @@ class uniFetch {
|
||||
});
|
||||
}
|
||||
|
||||
private handleResponse(response: any): any {
|
||||
if (this.interceptors.response) {
|
||||
response = this.interceptors.response(response);
|
||||
}
|
||||
|
||||
const statusCode = response.statusCode;
|
||||
if (statusCode === 200) {
|
||||
return response.data;
|
||||
} else {
|
||||
throw response;
|
||||
private handleResponse(response: any, options: RequestOptions): any {
|
||||
if (options.interceptor?.response) {
|
||||
response = options.interceptor?.response(response);
|
||||
} else if (this.interceptors?.response) {
|
||||
response = this.interceptors?.response(response);
|
||||
}
|
||||
return response
|
||||
}
|
||||
private handleUploadResponse(res: any, options: UploadOptions){
|
||||
if (options.interceptor?.response){
|
||||
res = options.interceptor?.response(res);
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
private handleError(error: any): any {
|
||||
throw error;
|
||||
}
|
||||
@ -111,31 +155,52 @@ class uniFetch {
|
||||
options.method = "GET";
|
||||
return this.request(this.buildRequestOptions(options));
|
||||
}
|
||||
upload(options: UploadOptions) {
|
||||
options.url = `${options.baseUrl ?? this.baseUrl}${options.url}`;
|
||||
if (typeof options.interceptor?.request==='function'){
|
||||
options = options.interceptor.request(options);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
...options,
|
||||
success: (res) => {
|
||||
resolve(this.handleUploadResponse(res, options))
|
||||
},
|
||||
fail(res){
|
||||
reject(res)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
private buildRequestOptions(options: RequestOptions): RequestOptions {
|
||||
if (options.params) {
|
||||
if (options.params && Object.keys(options.params).length > 0) {
|
||||
const queryString = Object.keys(options.params)
|
||||
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(options.params[key])}`)
|
||||
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(options.params![key])}`)
|
||||
.join('&');
|
||||
options.url += `?${queryString}`;
|
||||
}
|
||||
delete options.params;
|
||||
return options;
|
||||
}
|
||||
|
||||
post(options: RequestOptions): Promise<any> {
|
||||
options = options || {};
|
||||
options.method = "POST";
|
||||
return this.request(this.buildRequestOptions(options));
|
||||
}
|
||||
|
||||
put(options: RequestOptions): Promise<any> {
|
||||
options = options || {};
|
||||
options.method = "PUT";
|
||||
return this.request(this.buildRequestOptions(options));
|
||||
}
|
||||
|
||||
delete(options: RequestOptions): Promise<any> {
|
||||
options = options || {};
|
||||
options.method = "DELETE";
|
||||
return this.request(this.buildRequestOptions(options));
|
||||
}
|
||||
}
|
||||
export { uniFetch}
|
||||
|
||||
export {uniRequest}
|
||||
|
15
src/main.ts
@ -1,17 +1,18 @@
|
||||
import { createSSRApp } from "vue";
|
||||
import * as Pinia from "pinia";
|
||||
import tmui from "./tmui";
|
||||
import App from "./App.vue";
|
||||
// @ts-ignore
|
||||
import api from "@/http";
|
||||
import title from "./components/Title/index.vue";
|
||||
import { createPinia } from 'pinia'
|
||||
import customTitle from "./components/custom-title/index.vue";
|
||||
import uniTransition from "@/components/uni-transition/uni-transition.vue";
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
app.config.globalProperties.$api = api;
|
||||
app.component("title", title);
|
||||
const pinia = createPinia()
|
||||
app.use(pinia)
|
||||
app.component("customTitle", customTitle);
|
||||
app.component("uniTransition", uniTransition);
|
||||
app.use(tmui, { shareDisable: false } as Tmui.tmuiConfig);
|
||||
return {
|
||||
app,
|
||||
Pinia,
|
||||
pinia
|
||||
};
|
||||
}
|
||||
|
@ -97,7 +97,7 @@
|
||||
},
|
||||
"quickapp": {},
|
||||
"mp-weixin": {
|
||||
"appid": "",
|
||||
"appid": "wx7da502ffb626aa8a",
|
||||
"darkmode": false,
|
||||
"setting": {
|
||||
"urlCheck": false,
|
||||
|
215
src/pages.json
@ -1,74 +1,161 @@
|
||||
{
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"^tm-(.*)": "@/tmui/components/tm-$1/tm-$1.vue"
|
||||
}
|
||||
},
|
||||
"pages": [{
|
||||
"path": "pages/index/index",
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"^tm-(.*)": "@/tmui/components/tm-$1/tm-$1.vue"
|
||||
}
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"disableScroll": true,
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/blind-box/index",
|
||||
"style": {
|
||||
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/facial/index",
|
||||
"style": {
|
||||
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/face-auth/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/home/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/ticket/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/setup/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/view-venues/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#FFFFFF",
|
||||
"backgroundColor": "#FFFFFF"
|
||||
},
|
||||
"condition": {
|
||||
"current": 0,
|
||||
"list": [{
|
||||
"name": "",
|
||||
"path": "",
|
||||
"query": ""
|
||||
}]
|
||||
}
|
||||
{
|
||||
"path": "pages/ticket/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/test/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/ticket-details/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/setup/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/view-venues/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "pages/mine/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"app-plus": {
|
||||
"titleNView": false // 禁用原生导航
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#FFFFFF",
|
||||
"backgroundColor": "#FFFFFF"
|
||||
},
|
||||
"condition": {
|
||||
"current": 0,
|
||||
"list": [
|
||||
{
|
||||
"name": "",
|
||||
"path": "",
|
||||
"query": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
293
src/pages/blind-box/index.vue
Normal file
@ -0,0 +1,293 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<custom-title class="title-block" title="大运河博物馆纪念盲盒">
|
||||
</custom-title>
|
||||
<div class="main">
|
||||
<div class="content1">
|
||||
<div class="wrap1">
|
||||
<image src="https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/78a61919-6e1e-4b5d-96cc-1ecd94c00236.png"></image>
|
||||
</div>
|
||||
<div class="wrap2">大运河博物馆纪念盲盒</div>
|
||||
</div>
|
||||
<div class="content2">
|
||||
<image src="https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/13e8a0db-9dca-4bdf-89d5-5868ec7c96e0.png"></image>
|
||||
</div>
|
||||
<div class="content3" @click="goGet">领取兑换</div>
|
||||
<div class="content4"></div>
|
||||
<div class="content5">
|
||||
<div class="wrap1" v-for="item in imgList" :key="item.url">
|
||||
<image :src="item.url"></image>
|
||||
</div>
|
||||
</div>
|
||||
<tm-drawer hideHeader color="#B1292E" :width="510" :height="324" ref="calendarView" placement="center" v-model:show="showWin2">
|
||||
<div class="content6">
|
||||
<div class="wrap1">领取盲盒失败</div>
|
||||
<div class="wrap2">失败原因:未实名</div>
|
||||
<div class="wrap3" @click="goRealName">前往实名</div>
|
||||
<div class="wrap4">*即将跳转实名页面</div>
|
||||
</div>
|
||||
</tm-drawer>
|
||||
<tm-drawer hideHeader :width="510" :height="324" ref="calendarView" placement="center" v-model:show="showWin3">
|
||||
<div class="content7">
|
||||
<div class="wrap1">领取失败</div>
|
||||
<div class="wrap2">失败原因:{{errMsg}}</div>
|
||||
<div class="wrap3" @click="goHome">确定</div>
|
||||
<div class="wrap4">**即将返回首页</div>
|
||||
</div>
|
||||
</tm-drawer>
|
||||
<tm-drawer hideHeader :width="510" :height="636" ref="calendarView" placement="center" v-model:show="showWin4">
|
||||
<div class="content8">
|
||||
<div class="wrap1">领取成功</div>
|
||||
<div class="wrap2">1人1码请与工作人员核验领取</div>
|
||||
<div class="wrap3">
|
||||
<image :src="imageSrc"></image>
|
||||
</div>
|
||||
<div class="wrap4" @click="showWin4=false">确定</div>
|
||||
<div class="wrap5">*可从“我的票库”查看</div>
|
||||
</div>
|
||||
</tm-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
import {extractingBlindBoxes, getQrCode} from "@/http/apis";
|
||||
import {onShow} from "@dcloudio/uni-app";
|
||||
const imgList=ref([{url:'https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/8395f322-b677-4f24-a13d-b79474c09d35.png'},{url:'https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/8395f322-b677-4f24-a13d-b79474c09d35.png'}])
|
||||
const showWin2=ref(false)
|
||||
const showWin3=ref(false)
|
||||
const showWin4=ref(false)
|
||||
const userInfo =()=>{
|
||||
return uni.getStorageSync('userInfo')
|
||||
}
|
||||
onShow(()=>{
|
||||
showWin2.value=false
|
||||
showWin3.value=false
|
||||
showWin4.value=false
|
||||
})
|
||||
const goHome=()=>{
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
const goRealName=()=>{
|
||||
uni.navigateTo({
|
||||
url: '/pages/facial/index'
|
||||
})
|
||||
}
|
||||
const errMsg=ref('')
|
||||
const imageSrc=ref('')
|
||||
const goGet=async ()=>{
|
||||
if (!userInfo().idNum){
|
||||
showWin2.value=true
|
||||
return
|
||||
}
|
||||
const data={
|
||||
"userName": userInfo().realName, //用户姓名
|
||||
"idCard": userInfo().idNum, //用户身份证号
|
||||
"phone": userInfo().telNum, //预约电话
|
||||
"blindBoxName": "大运河博物馆纪念盲盒", //盲盒名称
|
||||
blindBoxPicUrl:'https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/13e8a0db-9dca-4bdf-89d5-5868ec7c96e0.png'
|
||||
}
|
||||
const res=await extractingBlindBoxes(data)
|
||||
if (res.code===0){
|
||||
showWin3.value=true
|
||||
errMsg.value=res.msg
|
||||
}else if (res.code===200){
|
||||
const res1= await getQrCode({appointUid:res.data.appointmentUid})
|
||||
const arrayBuffer = new Uint8Array(res1)
|
||||
imageSrc.value = "data:image/png;base64," + uni.arrayBufferToBase64(arrayBuffer)
|
||||
showWin4.value=true
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.content8{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap1{
|
||||
font-size: 28rpx;
|
||||
color: #000;
|
||||
margin-top: 36rpx;
|
||||
}
|
||||
.wrap2{
|
||||
color: #B29E92;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.wrap3{
|
||||
margin-top: 20rpx;
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
border-radius: 30rpx;
|
||||
overflow: hidden;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
}
|
||||
.wrap4{
|
||||
margin-top: 20rpx;
|
||||
width: 436rpx;
|
||||
height: 60rpx;
|
||||
background-color:#F7963B;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
border-radius:30rpx ;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.wrap5{
|
||||
margin-top: 6rpx;
|
||||
color: #B29E92;
|
||||
font-size: 16rpx;
|
||||
}
|
||||
}
|
||||
.content7{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap4{
|
||||
margin-top: 6rpx;
|
||||
font-size: 16rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.wrap3{
|
||||
margin-top: 32rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 30rpx;
|
||||
width: 436rpx;
|
||||
height: 60rpx;
|
||||
background-color: #E84030;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.wrap2{
|
||||
margin-top: 30rpx;
|
||||
font-size: 24rpx;
|
||||
color: #644D3F;
|
||||
|
||||
}
|
||||
.wrap1{
|
||||
margin-top: 58rpx;
|
||||
font-size: 32rpx;
|
||||
color: #B1292E;
|
||||
}
|
||||
}
|
||||
.content6{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap4{
|
||||
margin-top: 6rpx;
|
||||
font-size: 16rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.wrap3{
|
||||
margin-top: 32rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 30rpx;
|
||||
width: 436rpx;
|
||||
height: 60rpx;
|
||||
background-color: #fff;
|
||||
color: #B1292E;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.wrap2{
|
||||
margin-top: 30rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
.wrap1{
|
||||
margin-top: 58rpx;
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.container{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
.main{
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 32rpx 42rpx 0 42rpx;
|
||||
width: 100vw;
|
||||
flex: 1;
|
||||
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
||||
background-size: 100%;
|
||||
.content5{
|
||||
margin-bottom: 90rpx;
|
||||
margin-top: 20rpx;
|
||||
width: 100%;
|
||||
.wrap1{
|
||||
margin-bottom: 20rpx;
|
||||
width: 100%;
|
||||
height:454rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.content4 {
|
||||
margin-top: 42rpx;
|
||||
height: 1rpx;
|
||||
width: 100%;
|
||||
background-image: url("../../static/zx303@3x.png");
|
||||
background-size: 100%;
|
||||
}
|
||||
.content3{
|
||||
margin-top: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 24rpx;
|
||||
background-color: #B1292E;
|
||||
width: 100%;
|
||||
height: 82rpx;
|
||||
}
|
||||
.content2{
|
||||
overflow: hidden;
|
||||
margin-top: 12rpx;
|
||||
width: 100%;
|
||||
image{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.content1{
|
||||
box-sizing: border-box;
|
||||
background-image: url("https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/793bc6e0-ba68-4085-b3e3-cbc8890c07af.png");
|
||||
width: 100%;
|
||||
height: 60rpx;
|
||||
background-size: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 20rpx;
|
||||
.wrap2{
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.wrap1{
|
||||
margin-right: 12rpx;
|
||||
width: 39.75rpx;
|
||||
height: 39.75rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
167
src/pages/face-auth/index.vue
Normal file
@ -0,0 +1,167 @@
|
||||
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<custom-title class="title-block" title="人脸核验">
|
||||
</custom-title>
|
||||
<div class="main">
|
||||
<tm-message ref="msg" :lines="2"></tm-message>
|
||||
<div class="content1">
|
||||
人像识别认证
|
||||
</div>
|
||||
<div class="content2">
|
||||
<camera device-position="front">
|
||||
|
||||
</camera>
|
||||
</div>
|
||||
|
||||
<div class="content3" @click="submit">
|
||||
点击拍摄
|
||||
</div>
|
||||
<tm-drawer inContent :width="700" :height="800" hide-header ref="calendarView" placement="center" v-model:show="showWin2">
|
||||
<div class="content4">
|
||||
<div class="wrap1">
|
||||
<image :src="tempImage"></image>
|
||||
</div>
|
||||
<div class="wrap2" @click="submitFace">提交</div>
|
||||
</div>
|
||||
|
||||
</tm-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import displayBox from '../../components/display-box/index.vue'
|
||||
import {ref} from "vue";
|
||||
import {getInfo, socketImg, updateInfo, upload} from "@/http/apis";
|
||||
const msg=ref(null)
|
||||
const showWin2=ref(false)
|
||||
const statusValue=ref(0)
|
||||
const getUserInfo = async () => {
|
||||
const res=await getInfo()
|
||||
if (res.code===200){
|
||||
uni.setStorageSync('userInfo',res.data);
|
||||
}
|
||||
}
|
||||
const submitFace=async ()=>{
|
||||
const res1= await upload({
|
||||
name:'file',
|
||||
filePath:tempImage.value
|
||||
})
|
||||
const res= await socketImg({
|
||||
appointmentUid: uni.getStorageSync('ticket').appointmentUid,
|
||||
imageUrl: res1.data.path
|
||||
})
|
||||
if (res.code===200){
|
||||
uni.showToast({
|
||||
title:'提交成功',
|
||||
icon: 'none',
|
||||
duration: 50000
|
||||
})
|
||||
}
|
||||
}
|
||||
const tempImage=ref('')
|
||||
const submit=async ()=>{
|
||||
if (statusValue.value===0){
|
||||
const ctx = uni.createCameraContext();
|
||||
ctx.takePhoto({
|
||||
quality: 'high',
|
||||
success: (res) => {
|
||||
tempImage.value=res.tempImagePath
|
||||
showWin2.value=true
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
const idInfo=ref({
|
||||
name:'',
|
||||
idCard:''
|
||||
})
|
||||
const validateIDCardNumber=(idNumber)=> {
|
||||
const regExpMainland = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
|
||||
return regExpMainland.test(idNumber);
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.content4{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-right: 20rpx;
|
||||
padding-left: 20rpx;
|
||||
.wrap1{
|
||||
margin-top: 50rpx;
|
||||
image{
|
||||
width: 600rpx;
|
||||
height: 600rpx;
|
||||
}
|
||||
}
|
||||
.wrap2{
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
width: 436rpx;
|
||||
height: 60rpx;
|
||||
background-color: #000;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
}
|
||||
.container{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
.main{
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 0rpx 42rpx 0 42rpx;
|
||||
width: 100vw;
|
||||
flex: 1;
|
||||
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
||||
background-size: 100%;
|
||||
|
||||
.content3{
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
position: absolute;
|
||||
bottom: 156rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
width: 436rpx;
|
||||
height: 60rpx;
|
||||
background-color: #000;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
.content2{
|
||||
margin-top: 118rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
camera{
|
||||
width: 520rpx;
|
||||
height: 520rpx;
|
||||
border-radius: 360rpx
|
||||
}
|
||||
}
|
||||
.content1{
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 68rpx;
|
||||
border-radius: 24rpx;
|
||||
height: 82rpx;
|
||||
background-color: #B1292E;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
126
src/pages/facial/index.vue
Normal file
@ -0,0 +1,126 @@
|
||||
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<custom-title class="title-block" title="实名">
|
||||
</custom-title>
|
||||
<div class="main">
|
||||
<tm-message ref="msg" :lines="2"></tm-message>
|
||||
<div class="content1">
|
||||
身份证认证
|
||||
</div>
|
||||
<div class="content2">
|
||||
<display-box>
|
||||
<template #l1>
|
||||
<div class="box-left">
|
||||
真实姓名
|
||||
</div>
|
||||
</template>
|
||||
<template #r1>
|
||||
<div class="box-right">
|
||||
<input type="text" v-model="idInfo.name" placeholder="请填写您的真实姓名" placeholder-style="color:#DBDBDB;font-size:24rpx"/>
|
||||
</div>
|
||||
</template>
|
||||
<template #l2>
|
||||
<div class="box-left">
|
||||
身份证号码
|
||||
</div>
|
||||
</template>
|
||||
<template #r2>
|
||||
<div class="box-right">
|
||||
<input type="text" v-model="idInfo.idCard" placeholder="填写您的身份证号码" placeholder-style="color:#DBDBDB;font-size:24rpx"/>
|
||||
</div>
|
||||
</template>
|
||||
</display-box>
|
||||
</div>
|
||||
<div class="content3" @click="submit">
|
||||
提交
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import displayBox from '../../components/display-box/index.vue'
|
||||
import {ref} from "vue";
|
||||
import {getInfo, updateInfo} from "@/http/apis";
|
||||
const msg=ref(null)
|
||||
const getUserInfo = async () => {
|
||||
const res=await getInfo()
|
||||
if (res.code===200){
|
||||
uni.setStorageSync('userInfo',res.data);
|
||||
}
|
||||
}
|
||||
const submit=async ()=>{
|
||||
const res=await updateInfo({
|
||||
idNum:idInfo.value.idCard,
|
||||
realName:idInfo.value.name
|
||||
})
|
||||
if (res.code===200){
|
||||
uni.showToast({
|
||||
title: '实名成功',
|
||||
duration: 1300
|
||||
})
|
||||
setTimeout(async ()=>{
|
||||
getUserInfo()
|
||||
uni.navigateBack()
|
||||
},1300)
|
||||
}
|
||||
}
|
||||
const idInfo=ref({
|
||||
name:'',
|
||||
idCard:''
|
||||
})
|
||||
const validateIDCardNumber=(idNumber)=> {
|
||||
const regExpMainland = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
|
||||
return regExpMainland.test(idNumber);
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.container{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
.main{
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 0rpx 42rpx 0 42rpx;
|
||||
width: 100vw;
|
||||
flex: 1;
|
||||
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
||||
background-size: 100%;
|
||||
.content3{
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
position: absolute;
|
||||
bottom: 156rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
width: 436rpx;
|
||||
height: 60rpx;
|
||||
background-color: #000;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
.content2{
|
||||
margin-top: 38rpx;
|
||||
.box-left{
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
.content1{
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 68rpx;
|
||||
border-radius: 24rpx;
|
||||
height: 82rpx;
|
||||
background-color: #B1292E;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,57 +1,258 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="header">
|
||||
<div>门票名称</div>
|
||||
<div>剩余数量</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="item">
|
||||
<image src="@/static/logo.png" mode="scaleToFill" style="width: 174rpx;height: 108rpx;" />
|
||||
<div class="detail">
|
||||
<div style="width: 140rpx;">首都博物馆门票</div>
|
||||
<div>1023/20000</div>
|
||||
<tm-button color="#F7963B" :width="108" :height="56">预约</tm-button>
|
||||
</div>
|
||||
<div class="content3">
|
||||
<div class="wrap1">
|
||||
<image src="https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/1d693295-c16b-4845-a02b-c052d9cf847a.png" /></div>
|
||||
<div class="wrap2" @click="viewBlindBoxDetail">
|
||||
<div class="wrap2_1">博物馆开馆纪念盲盒</div>
|
||||
<div class="wrap2_2">剩余 {{allRemainingQty}}/{{allIssueQty}}</div>
|
||||
<div class="wrap2_3">查看详情</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="content1">
|
||||
<div class="wrap1">门票名称</div>
|
||||
<div class="wrap2">剩余数量</div>
|
||||
</div>
|
||||
<div class="content2">
|
||||
<div class="wrap1" v-for="(item,index) in [...tableData,...tableData]" :key="item.id">
|
||||
<div @click="viewImg(item)" class="wrap1_1">
|
||||
<image :src="item.ticketImage"></image>
|
||||
</div>
|
||||
<div class="wrap1_2">{{item.ticketName}}</div>
|
||||
<div class="wrap1_3" :class="item.remainingQuantity===0?['sold_out']:[]">{{item.remainingQuantity===-1?'不限':item.remainingQuantity}}/{{item.issueQuantity===-1?'不限':item.issueQuantity}}</div>
|
||||
<div class="wrap1_4" @click="goBooking(item)" :class="item.remainingQuantity===0?['sold_out']:[]">{{item.remainingQuantity===0?'无票':'预约'}}</div>
|
||||
</div>
|
||||
<div class="wrap2">
|
||||
<image src="../../static/zu758@3x.png"></image>
|
||||
</div>
|
||||
</div>
|
||||
<div class="attention" v-if="store.isShow">
|
||||
<div>
|
||||
注:港澳台游客请至现场办理门票业务!
|
||||
</div>
|
||||
<tm-icon name="tmicon-times-circle" color="#fff" :fontSize="24" @click="handleTips"></tm-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
/* 导入区*/
|
||||
import { ref } from "vue";
|
||||
import {ticketlist} from "@/http/apis";
|
||||
import {useMainStore} from "@/store";
|
||||
/**/
|
||||
const store=useMainStore()
|
||||
let height = ref('')
|
||||
let isShow = ref(true)
|
||||
const tableData=ref([])
|
||||
const page=ref(1)
|
||||
const pageSize=ref(9999)
|
||||
const viewImg=(item)=>{
|
||||
uni.previewImage({
|
||||
urls:[item.ticketImage],
|
||||
indicator:'none'
|
||||
})
|
||||
}
|
||||
const allIssueQty=ref(0)
|
||||
const allRemainingQty=ref(0)
|
||||
const getData=async ()=>{
|
||||
const data={
|
||||
"keyword": "",
|
||||
"isMobile": 1,
|
||||
"page": page.value,
|
||||
"pageSize": pageSize.value
|
||||
}
|
||||
const res=await ticketlist(data)
|
||||
if (res.code===200){
|
||||
allIssueQty.value=res.data.allIssueQty
|
||||
allRemainingQty.value=res.data.allRemainingQty
|
||||
tableData.value=res.data.data
|
||||
}
|
||||
}
|
||||
const goBooking=(item)=>{
|
||||
if (item.remainingQuantity!==0){
|
||||
uni.navigateTo({
|
||||
url: '/pages/ticket/index'
|
||||
})
|
||||
}else {
|
||||
uni.showToast({
|
||||
title: '该门票已售罄',
|
||||
icon: 'none',
|
||||
duration: 1000
|
||||
})
|
||||
}
|
||||
uni.setStorageSync('currentBooking',item)
|
||||
store.currentBooking=item
|
||||
}
|
||||
const viewBlindBoxDetail=()=>{
|
||||
uni.navigateTo({
|
||||
url: '/pages/blind-box/index'
|
||||
|
||||
})
|
||||
}
|
||||
getData()
|
||||
const handleTips = () => {
|
||||
store.isShow=false
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.main {
|
||||
height: 100vh;
|
||||
height: 80vh;
|
||||
width: 100%;
|
||||
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
||||
background-size: 100%;
|
||||
padding: 38rpx 32rpx;
|
||||
padding: 0 32rpx 38rpx 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
.content3{
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
margin-top: 40rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
.wrap2{
|
||||
background-color: #fff;
|
||||
width: 350rpx;
|
||||
height: 214rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap2_1{
|
||||
margin-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #000;
|
||||
}
|
||||
.wrap2_2{
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #F7963B;
|
||||
}
|
||||
.wrap2_3{
|
||||
margin-top: 20rpx;
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 20rpx;
|
||||
width: 240rpx;
|
||||
height: 56rpx;
|
||||
color: #fff;
|
||||
background-color: #F7963B;
|
||||
}
|
||||
}
|
||||
.wrap1{
|
||||
width: 350rpx;
|
||||
height: 214rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content2{
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
margin-top: 22rpx;
|
||||
.wrap2{
|
||||
margin-bottom: 68rpx;
|
||||
margin-top: 68rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
image{
|
||||
width: 587.8rpx;
|
||||
height: 22rpx;
|
||||
}
|
||||
}
|
||||
.wrap1{
|
||||
margin-bottom: 18rpx;
|
||||
border-radius: 20rpx;
|
||||
background-color: #fff;
|
||||
height: 108rpx;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
.wrap1_1{
|
||||
box-sizing: border-box;
|
||||
padding: 5rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
image{
|
||||
width: 165rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
margin-right: 18rpx;
|
||||
}
|
||||
.wrap1_4{
|
||||
width: 108rpx;
|
||||
height: 56rpx;
|
||||
background-color: #F7963B;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
color: #fff;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&.sold_out{
|
||||
background-color: #AFAFAF;
|
||||
}
|
||||
}
|
||||
.wrap1_3{
|
||||
color: #F7963B;
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 224rpx;
|
||||
&.sold_out{
|
||||
color: #AFAFAF;
|
||||
}
|
||||
}
|
||||
.wrap1_2{
|
||||
width: 140rpx;
|
||||
height: 76rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content1 {
|
||||
box-sizing: border-box;
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
background: #AB2F23;
|
||||
height: 70rpx;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
color: #FFFFFF;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.wrap1 {
|
||||
padding-right: 36rpx;
|
||||
text-align: right;
|
||||
width: 50%;
|
||||
flex-shrink: 1;
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
|
||||
}
|
||||
.wrap2 {
|
||||
padding-left: 36rpx;
|
||||
width: 50%;
|
||||
flex-shrink: 1;
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
.container {
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
height: 1120rpx;
|
||||
box-sizing: border-box;
|
||||
margin-top: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 2rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.item {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #FFFFFF;
|
||||
@ -67,5 +268,20 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.attention {
|
||||
width: 664rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
background: #761C1F;
|
||||
height: 68rpx;
|
||||
color: #FFFFFF;
|
||||
bottom: 50rpx;
|
||||
padding: 16rpx 40rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius: 24rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
350
src/pages/home1/index.vue
Normal file
@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<!-- <div class="content3">
|
||||
<div class="wrap1">
|
||||
<image src="https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/1d693295-c16b-4845-a02b-c052d9cf847a.png" /></div>
|
||||
<div class="wrap2" @click="viewBlindBoxDetail">
|
||||
<div class="wrap2_1">博物馆开馆纪念盲盒</div>
|
||||
<div class="wrap2_2">剩余 {{allRemainingQty}}/{{allIssueQty}}</div>
|
||||
<div class="wrap2_3">查看详情</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content1">
|
||||
<div class="wrap1">门票名称</div>
|
||||
<div class="wrap2">剩余数量</div>
|
||||
</div>
|
||||
<div class="content2">
|
||||
<div class="wrap1" v-for="(item,index) in [...tableData,...tableData]" :key="item.id">
|
||||
<div @click="viewImg(item)" class="wrap1_1">
|
||||
<image :src="item.ticketImage"></image>
|
||||
</div>
|
||||
<div class="wrap1_2">{{item.ticketName}}</div>
|
||||
<div class="wrap1_3" :class="item.remainingQuantity===0?['sold_out']:[]">{{item.remainingQuantity===-1?'不限':item.remainingQuantity}}/{{item.issueQuantity===-1?'不限':item.issueQuantity}}</div>
|
||||
<div class="wrap1_4" @click="goBooking(item)" :class="item.remainingQuantity===0?['sold_out']:[]">{{item.remainingQuantity===0?'无票':'预约'}}</div>
|
||||
</div>
|
||||
<div class="wrap2">
|
||||
<image src="../../static/zu758@3x.png"></image>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="content4">
|
||||
<div class="wrap1">
|
||||
<image src="https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/13e8a0db-9dca-4bdf-89d5-5868ec7c96e0.png"></image>
|
||||
</div>
|
||||
<div class="wrap2" @click="viewBlindBoxDetail">
|
||||
<div class="wrap2_1">
|
||||
<div class="wrap2_1_1">博物馆开馆纪念盲盒</div>
|
||||
<div class="wrap2_1_2">剩余 {{allRemainingQty}}/{{allIssueQty}}</div>
|
||||
</div>
|
||||
<div class="wrap2_2">查看详情</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="attention" v-if="store.isShow">
|
||||
<div>
|
||||
注:港澳台游客请至现场办理门票业务!
|
||||
</div>
|
||||
<tm-icon name="tmicon-times-circle" color="#fff" :fontSize="24" @click="handleTips"></tm-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
/* 导入区*/
|
||||
import { ref } from "vue";
|
||||
import {ticketlist} from "@/http/apis";
|
||||
import {useMainStore} from "@/store";
|
||||
/**/
|
||||
const store=useMainStore()
|
||||
let height = ref('')
|
||||
let isShow = ref(true)
|
||||
const tableData=ref([])
|
||||
const page=ref(1)
|
||||
const pageSize=ref(9999)
|
||||
const viewImg=(item)=>{
|
||||
uni.previewImage({
|
||||
urls:[item.ticketImage],
|
||||
indicator:'none'
|
||||
})
|
||||
}
|
||||
const allIssueQty=ref(0)
|
||||
const allRemainingQty=ref(0)
|
||||
const getData=async ()=>{
|
||||
const data={
|
||||
"keyword": "",
|
||||
"isMobile": 1,
|
||||
"page": page.value,
|
||||
"pageSize": pageSize.value
|
||||
}
|
||||
const res=await ticketlist(data)
|
||||
if (res.code===200){
|
||||
allIssueQty.value=res.data.allIssueQty
|
||||
allRemainingQty.value=res.data.allRemainingQty
|
||||
tableData.value=res.data.data
|
||||
}
|
||||
}
|
||||
const goBooking=(item)=>{
|
||||
if (item.remainingQuantity!==0){
|
||||
uni.navigateTo({
|
||||
url: '/pages/ticket/index'
|
||||
})
|
||||
}else {
|
||||
uni.showToast({
|
||||
title: '该门票已售罄',
|
||||
icon: 'none',
|
||||
duration: 1000
|
||||
})
|
||||
}
|
||||
uni.setStorageSync('currentBooking',item)
|
||||
store.currentBooking=item
|
||||
}
|
||||
const viewBlindBoxDetail=()=>{
|
||||
uni.navigateTo({
|
||||
url: '/pages/blind-box/index'
|
||||
|
||||
})
|
||||
}
|
||||
getData()
|
||||
const handleTips = () => {
|
||||
store.isShow=false
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.main {
|
||||
height: 80vh;
|
||||
width: 100%;
|
||||
background-size: 100%;
|
||||
padding: 0 32rpx 38rpx 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
.content4{
|
||||
margin-top: 40rpx;
|
||||
width: 700rpx;
|
||||
height: 576rpx;
|
||||
border-radius: 20rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
.wrap2{
|
||||
box-sizing: border-box;
|
||||
padding-right: 48rpx;
|
||||
padding-left: 48rpx;
|
||||
justify-content: space-between;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 700rpx;
|
||||
height: 120rpx;
|
||||
.wrap2_2{
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 240rpx;
|
||||
height: 56rpx;
|
||||
background-color: #F7963B;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.wrap2_1{
|
||||
.wrap2_1_2{
|
||||
font-size: 20rpx;
|
||||
color: #F7963B;
|
||||
}
|
||||
.wrap2_1_1{
|
||||
font-size: 28rpx;
|
||||
color: #000000;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.wrap1{
|
||||
width: 700rpx;
|
||||
height: 456rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content3{
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
margin-top: 40rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
.wrap2{
|
||||
background-color: #fff;
|
||||
width: 350rpx;
|
||||
height: 214rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap2_1{
|
||||
margin-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #000;
|
||||
}
|
||||
.wrap2_2{
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #F7963B;
|
||||
}
|
||||
.wrap2_3{
|
||||
margin-top: 20rpx;
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 20rpx;
|
||||
width: 240rpx;
|
||||
height: 56rpx;
|
||||
color: #fff;
|
||||
background-color: #F7963B;
|
||||
}
|
||||
}
|
||||
.wrap1{
|
||||
width: 350rpx;
|
||||
height: 214rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content2{
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
margin-top: 22rpx;
|
||||
.wrap2{
|
||||
margin-bottom: 68rpx;
|
||||
margin-top: 68rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
image{
|
||||
width: 587.8rpx;
|
||||
height: 22rpx;
|
||||
}
|
||||
}
|
||||
.wrap1{
|
||||
margin-bottom: 18rpx;
|
||||
border-radius: 20rpx;
|
||||
background-color: #fff;
|
||||
height: 108rpx;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
.wrap1_1{
|
||||
box-sizing: border-box;
|
||||
padding: 5rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
image{
|
||||
width: 165rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
margin-right: 18rpx;
|
||||
}
|
||||
.wrap1_4{
|
||||
width: 108rpx;
|
||||
height: 56rpx;
|
||||
background-color: #F7963B;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
color: #fff;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&.sold_out{
|
||||
background-color: #AFAFAF;
|
||||
}
|
||||
}
|
||||
.wrap1_3{
|
||||
color: #F7963B;
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 224rpx;
|
||||
&.sold_out{
|
||||
color: #AFAFAF;
|
||||
}
|
||||
}
|
||||
.wrap1_2{
|
||||
width: 140rpx;
|
||||
height: 76rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content1 {
|
||||
box-sizing: border-box;
|
||||
|
||||
width: 100%;
|
||||
background: #AB2F23;
|
||||
height: 70rpx;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #FFFFFF;
|
||||
font-size: 28rpx;
|
||||
.wrap1 {
|
||||
padding-right: 36rpx;
|
||||
text-align: right;
|
||||
width: 50%;
|
||||
flex-shrink: 1;
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
|
||||
}
|
||||
.wrap2 {
|
||||
padding-left: 36rpx;
|
||||
width: 50%;
|
||||
flex-shrink: 1;
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
.container {
|
||||
overflow-y: auto;
|
||||
height: 1120rpx;
|
||||
box-sizing: border-box;
|
||||
margin-top: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 2rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.item {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #FFFFFF;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.detail {
|
||||
flex: 1;
|
||||
margin-left: 18rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
}
|
||||
.attention {
|
||||
width: 664rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
background: #761C1F;
|
||||
height: 68rpx;
|
||||
color: #FFFFFF;
|
||||
bottom: 50rpx;
|
||||
padding: 16rpx 40rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius: 24rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,16 +1,29 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <div :style="{height:`${ztHehight}px`}"></div>-->
|
||||
<home v-if="acc===0"/>
|
||||
<mine v-if="acc===1"/>
|
||||
<div class="tab-index">
|
||||
<custom-title class="title-block" :title="accTitleList.find(x=>x.value===acc).title" :isBack="false">
|
||||
</custom-title>
|
||||
<div class="ld ld-float-ltr-in" v-show="acc===0"><home1 /></div>
|
||||
<div v-show="acc===1" class="ld ld-float-rtl-in"><mine /></div>
|
||||
<self-tabbar v-model="acc"></self-tabbar>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import home from '../home/index.vue'
|
||||
import home1 from '../home1/index.vue'
|
||||
import mine from '../mine/index.vue'
|
||||
import selfTabbar from '../../components/self-tabbar/index.vue'
|
||||
import {ref} from "vue";
|
||||
const acc=ref(1)
|
||||
const ztHehight=uni.getSystemInfoSync().statusBarHeight
|
||||
import {onLoad} from "@dcloudio/uni-app";
|
||||
onLoad((option)=>{
|
||||
if (typeof option.acc==='string'){
|
||||
acc.value=Number(option.acc)
|
||||
}
|
||||
})
|
||||
const accTitleList=[{title:'大运河博物馆',value:0},{title:'智慧门票',value:1}]
|
||||
const acc=ref(0)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tab-index{
|
||||
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
||||
background-size: 100%;
|
||||
}
|
||||
</style>
|
||||
|
@ -2,31 +2,41 @@
|
||||
<div class="main">
|
||||
<view>
|
||||
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" class="btn">点击登录</button>
|
||||
|
||||
</view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup >
|
||||
import { ref, getCurrentInstance } from "vue";
|
||||
const currentInstance = getCurrentInstance();
|
||||
const { $api } = currentInstance.appContext.config.globalProperties;
|
||||
import { ref } from "vue";
|
||||
import {login,getInfo} from "@/http/apis";
|
||||
let isShow = ref(true);
|
||||
const getPhoneNumber = () => {
|
||||
console.log(123)
|
||||
const getPhoneNumber =async (data) => {
|
||||
const res=await login({
|
||||
code:data.detail.code
|
||||
})
|
||||
if (res.code===200){
|
||||
uni.setStorageSync('token',res.data.token);
|
||||
getUserInfo()
|
||||
}
|
||||
}
|
||||
const getUserInfo = async () => {
|
||||
const res=await getInfo()
|
||||
if (res.code===200){
|
||||
uni.setStorageSync('userInfo',res.data);
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/index?acc=0'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.main {
|
||||
background: url("https://cdns.fontree.cn/fonchain-main/prod/image/default/artwork/3f70cf7f-4017-42a6-9276-bf854f57f78d.png");
|
||||
/* background: url("https://cdns.fontree.cn/fonchain-main/prod/image/default/artwork/3f70cf7f-4017-42a6-9276-bf854f57f78d.png");*/
|
||||
background: url("https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/33e1a0c8-ce9e-4b05-bd49-7a75f7bd98d4.png");
|
||||
background-size: cover;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.btn {
|
||||
background: transparent;
|
||||
width: 200rpx;
|
||||
|
@ -1,201 +1,524 @@
|
||||
<template>
|
||||
<div class="large-container">
|
||||
<div class="content1">
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">
|
||||
<image src="../../static/06.png" alt=""/>
|
||||
</div>
|
||||
<div class="wrap1_2">
|
||||
<div class="wrap1_2_1">
|
||||
<div class="wrap1_2_1_1">某某某</div>
|
||||
<div class="wrap1_2_1_2">已实名</div>
|
||||
</div>
|
||||
<div class="wrap1_2_2">178273938123</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap2" @click="goSetUp">
|
||||
<div class="wrap2_1">
|
||||
<image src="../../static/zu609@3x (1).png" alt=""/>
|
||||
</div>
|
||||
<div class="wrap2_2">设置</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content2">
|
||||
<div class="wrap1 ">
|
||||
<div class="wrap1_1">2</div>
|
||||
<div class="wrap1_2">未使用门票</div>
|
||||
</div>
|
||||
<div class="wrap2"></div>
|
||||
<div class="wrap3 active">
|
||||
<div class="wrap1_1">3</div>
|
||||
<div class="wrap1_2">历史门票</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content3">
|
||||
|
||||
</div>
|
||||
<div class="content4">·历史预约门票</div>
|
||||
<div class="content5">
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1 verified">已核销</div>
|
||||
<div class="wrap1_2">
|
||||
<div class="wrap1_2_1">首都博物馆门票</div>
|
||||
<div class="wrap1_2_2">预约场馆:首都博物馆</div>
|
||||
<div class="wrap1_2_2">预约日期:2023.12.30</div>
|
||||
<div class="wrap1_2_2">预约类型:1</div>
|
||||
<div class="large-container">
|
||||
<div class="content1">
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">
|
||||
<image :src="userInfo()?.avatar" alt=""/>
|
||||
</div>
|
||||
<div class="wrap1_2">
|
||||
<div class="wrap1_2_1">
|
||||
<div class="wrap1_2_1_1">{{ userInfo()?.nickName }}</div>
|
||||
<!-- <div class="wrap1_2_1_2">已实名</div>-->
|
||||
</div>
|
||||
<div class="wrap1_2_2">{{ userInfo()?.telNum }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap1_3">
|
||||
<image src="../../static/zu762@3x (1).png" alt=""/>
|
||||
<div class="wrap2">
|
||||
<div class="wrap2_1" @click="goSetUp">
|
||||
<div class="wrap2_1_1">
|
||||
<image src="../../static/zu609@3x.png"></image>
|
||||
</div>
|
||||
<div class="wrap2_1_2">设置</div>
|
||||
</div>
|
||||
<div class="wrap2_2" @click="verifyIdentity">
|
||||
<div class="wrap2_2_1">
|
||||
<image src="../../static/zu1123@3x.png"></image>
|
||||
</div>
|
||||
<div class="wrap2_2_2">实名</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1 verified">已核销</div>
|
||||
<div class="wrap1_2">
|
||||
<div class="wrap1_2_1">首都博物馆门票</div>
|
||||
<div class="wrap1_2_2">预约场馆:首都博物馆</div>
|
||||
<div class="wrap1_2_2">预约日期:2023.12.30</div>
|
||||
<div class="wrap1_2_2">预约类型:1</div>
|
||||
<div class="content2">
|
||||
<div class="wrap1" :class="currentTab===0?['active']:[]" @click="switchOptions(0)">
|
||||
<div class="wrap1_1">{{tabList?.unusedNumber}}</div>
|
||||
<div class="wrap1_2">未使用门票</div>
|
||||
</div>
|
||||
<div class="wrap1_3" @click="goViewVenues">
|
||||
<image src="../../static/zu762@3x (1).png" alt=""/>
|
||||
<div class="wrap2"></div>
|
||||
<div class="wrap3" :class="currentTab===1?['active']:[]" @click="switchOptions(1)">
|
||||
<div class="wrap1_1">{{tabList?.historyNumber}}</div>
|
||||
<div class="wrap1_2">历史门票</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content3"></div>
|
||||
<div class="content4" :style="{color:currentTab===0?'#EB783C':'#72665F'}">{{currentTab===0?'·我未使用的票务':'·历史预约门票'}}</div>
|
||||
<div class="content5">
|
||||
<div class="wrap1" @click="goDetail(item)" :class="[`status${item.status}`]" v-for="(item,index) in tabList?.tickets" :key="item.appointmentUid">
|
||||
<div class="wrap1_5">
|
||||
<image :src="item.ticketCoverPic"></image>
|
||||
</div>
|
||||
<div class="wrap1_6" :style="{backgroundColor:item.isBlindBox===2?'#CC2727':''}">
|
||||
</div>
|
||||
<div class="wrap1_1" v-if="item.isBlindBox===1">{{statusList.find(x=>x.value===item.status).label}}</div>
|
||||
<div class="wrap1_1" style="background-color: #fff" v-if="item.isBlindBox===2">盲盒</div>
|
||||
<div class="wrap1_2">
|
||||
<div class="wrap1_2_1">{{item.ticketName}}</div>
|
||||
<div class="wrap1_2_2">兑换场馆:{{item.venuesName}}</div>
|
||||
<div class="wrap1_2_2">兑换日期:{{item.date?.replaceAll('/','.')}}</div>
|
||||
<div class="wrap1_2_2">预约数量:1</div>
|
||||
</div>
|
||||
<div class="wrap1_3" :style="{backgroundColor:item.isBlindBox===2?'#000':''}">
|
||||
<image @click="goViewVenues(item)" v-if="item.isBlindBox===1" src="../../static/zu762@3x.png" alt=""/>
|
||||
<image @click.stop="exchange(item)" v-if="item.isBlindBox===2" style="width: 79rpx;height: 34rpx" src="../../static/zu1216@3x.png" alt=""/>
|
||||
</div>
|
||||
<tm-drawer hideHeader :width="510" :height="606" ref="calendarView" placement="center" v-model:show="showWin4">
|
||||
<div class="content8">
|
||||
<div class="wrap1">{{ticketInfo?.ticketName}}</div>
|
||||
<div class="wrap2">1人1码请与工作人员核验领取</div>
|
||||
<div class="wrap3">
|
||||
<image :src="imageSrc"></image>
|
||||
</div>
|
||||
<div class="wrap4" :style="{backgroundColor:ticketInfo?.status===3?'#AFAFAF':''}" @click="showWin4=false">{{ticketInfo?.status===3?'已核验':'未核验'}}</div>
|
||||
</div>
|
||||
</tm-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
const goViewVenues=()=>{
|
||||
import {ref,watch} from 'vue'
|
||||
import {onShow} from "@dcloudio/uni-app";
|
||||
import {extractingBlindBoxes, getQrCode, historicalTickets, unusedTickets} from "@/http/apis";
|
||||
const modeClass = ref('')
|
||||
const currentTab = ref(0)
|
||||
const showWin4=ref(false)
|
||||
const show = ref(true)
|
||||
const imageSrc=ref('')
|
||||
const ticket=()=>{
|
||||
return uni.getStorageSync('ticket')
|
||||
}
|
||||
const userInfo =()=>{
|
||||
return uni.getStorageSync('userInfo')
|
||||
}
|
||||
onShow(() => {
|
||||
show.value = true
|
||||
})
|
||||
const tabList=ref(null)
|
||||
const statusList=ref([
|
||||
{
|
||||
label:'',
|
||||
value:1
|
||||
},
|
||||
{
|
||||
label:'已退票',
|
||||
value:2
|
||||
},
|
||||
{
|
||||
label:'已核销',
|
||||
value:3
|
||||
},
|
||||
{
|
||||
label:'已过期',
|
||||
value:4
|
||||
},
|
||||
{
|
||||
label:'',
|
||||
value:5
|
||||
},
|
||||
{
|
||||
label:'盲盒',
|
||||
value:6
|
||||
}
|
||||
])
|
||||
const goDetail=(item)=>{
|
||||
uni.setStorageSync('ticket',item)
|
||||
uni.navigateTo({
|
||||
url: '/pages/ticket-details/index'
|
||||
})
|
||||
}
|
||||
const getData=async ()=>{
|
||||
const res =await unusedTickets()
|
||||
if (res.code===200){
|
||||
tabList.value=res.data
|
||||
}
|
||||
}
|
||||
onShow(()=>{
|
||||
getData()
|
||||
})
|
||||
const switchOptions=async (num)=>{
|
||||
let res
|
||||
if (num===0){
|
||||
res=await unusedTickets()
|
||||
}else if (num===1){
|
||||
res=await historicalTickets()
|
||||
}
|
||||
if (res.code===200){
|
||||
tabList.value=res.data
|
||||
}
|
||||
currentTab.value=num
|
||||
}
|
||||
const ticketInfo=ref(null)
|
||||
watch(showWin4,()=>{
|
||||
console.log('关闭Socket')
|
||||
// uni.closeSocket()
|
||||
})
|
||||
const exchange=async (item)=>{
|
||||
const res1= await getQrCode({appointUid:item.appointmentUid})
|
||||
const arrayBuffer = new Uint8Array(res1)
|
||||
imageSrc.value = "data:image/png;base64," + uni.arrayBufferToBase64(arrayBuffer)
|
||||
ticketInfo.value=item
|
||||
uni.setStorageSync('ticket',item)
|
||||
showWin4.value=true
|
||||
|
||||
uni.connectSocket({
|
||||
url: `ws://warehouse.szjixun.cn/ticket/api/smart/appointment/subscribe/msg?AppointmentUid=${item.appointmentUid}`,
|
||||
success: function() {
|
||||
console.log('WebSocket连接已创建成功!');
|
||||
}
|
||||
});
|
||||
uni.onSocketOpen( (res)=> {
|
||||
console.log(res,'onSocketOpen')
|
||||
});
|
||||
uni.onSocketMessage((res)=>{
|
||||
console.log('WebSocket接收到消息:', res);
|
||||
if (res.data==='start the camera'){
|
||||
/* uni.closeSocket()*/
|
||||
uni.navigateTo({
|
||||
url: '/pages/face-auth/index'
|
||||
})
|
||||
}else if (res.data==='Check Finish'){
|
||||
uni.closeSocket()
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/index?acc=1'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
const goViewVenues = (item) => {
|
||||
uni.setStorageSync('ticket',item)
|
||||
uni.navigateTo({
|
||||
url: '/pages/view-venues/index'
|
||||
})
|
||||
}
|
||||
const goSetUp=()=>{
|
||||
const verifyIdentity=()=>{
|
||||
uni.navigateTo({
|
||||
url: '/pages/facial/index'
|
||||
})
|
||||
}
|
||||
const goSetUp = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/setup/index'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.large-container{
|
||||
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
||||
background-size: 100%;
|
||||
height: 100vh;
|
||||
padding: 38rpx 32rpx 0 32rpx;
|
||||
.content5{
|
||||
margin-top: 14rpx;
|
||||
.wrap1{
|
||||
position: relative;
|
||||
width: 686rpx;
|
||||
height: 210rpx;
|
||||
background-image: url("https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/156dd8fa-e56d-4208-bc15-58eb273c146f.png");
|
||||
background-size: 100%;
|
||||
.wrap1_3{
|
||||
bottom: 18rpx;
|
||||
right: 16rpx;
|
||||
position: absolute;
|
||||
width: 150rpx;
|
||||
height: 56rpx;
|
||||
background-color: #72665F;
|
||||
border-radius: 40rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.content8{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap1{
|
||||
font-size: 28rpx;
|
||||
color: #000;
|
||||
margin-top: 36rpx;
|
||||
}
|
||||
.wrap2{
|
||||
color: #B29E92;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.wrap3{
|
||||
margin-top: 20rpx;
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
border-radius: 30rpx;
|
||||
overflow: hidden;
|
||||
image{
|
||||
width: 119.5rpx;
|
||||
height:34rpx;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
}
|
||||
.wrap1_2{
|
||||
top: 16rpx;
|
||||
right: 182rpx;
|
||||
position: absolute;
|
||||
|
||||
.wrap1_2_1{
|
||||
font-size: 32rpx;
|
||||
.wrap4{
|
||||
margin-top: 20rpx;
|
||||
width: 134rpx;
|
||||
height: 60rpx;
|
||||
background-color:#F7963B;
|
||||
color: #fff;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
.wrap1_2_2{
|
||||
margin-bottom: 2rpx;
|
||||
font-size: 20rpx;
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
}
|
||||
.wrap1_1{
|
||||
top: 26rpx;
|
||||
left: 26rpx;
|
||||
position: absolute;
|
||||
font-size: 28rpx;
|
||||
border-radius:30rpx ;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 112rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 22rpx;
|
||||
font-size: 20rpx;
|
||||
&.verified{
|
||||
background-color: #fff;
|
||||
color: #72665F;
|
||||
}
|
||||
}
|
||||
.wrap5{
|
||||
margin-top: 6rpx;
|
||||
color: #B29E92;
|
||||
font-size: 16rpx;
|
||||
}
|
||||
}
|
||||
.large-container {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-size: 100%;
|
||||
height: 80vh;
|
||||
padding: 0rpx 32rpx 0 32rpx;
|
||||
|
||||
.content5 {
|
||||
margin-top: 14rpx;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
|
||||
.wrap1{
|
||||
&:nth-child(n+2){
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
&:last-child{
|
||||
margin-bottom: 100rpx;
|
||||
}
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 686rpx;
|
||||
height: 210rpx;
|
||||
box-sizing: border-box;
|
||||
border: 2rpx solid #fff;
|
||||
background-size: 100%;
|
||||
border-radius: 40rpx;
|
||||
overflow: hidden;
|
||||
&.status2 {
|
||||
.wrap1_1{
|
||||
background-color: #fff;
|
||||
color: #FF5C62;
|
||||
}
|
||||
.wrap1_6{
|
||||
background-color: #B29E92;
|
||||
}
|
||||
}
|
||||
&.status4 {
|
||||
.wrap1_1{
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
}
|
||||
.wrap1_6{
|
||||
background-color: #B29E92;
|
||||
}
|
||||
}
|
||||
&.status6{
|
||||
.wrap1_6{
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
&.status5{
|
||||
.wrap1_6{
|
||||
background-color: #EB783C;
|
||||
}
|
||||
}
|
||||
&.status1{
|
||||
.wrap1_6{
|
||||
background-color: #EB783C;
|
||||
}
|
||||
}
|
||||
&.status3 {
|
||||
.wrap1_6{
|
||||
background-color: #B29E92;
|
||||
}
|
||||
.wrap1_1{
|
||||
background-color: #fff;
|
||||
color: #72665F;
|
||||
}
|
||||
|
||||
}
|
||||
.wrap1_3 {
|
||||
bottom: 18rpx;
|
||||
right: 16rpx;
|
||||
position: absolute;
|
||||
width: 150rpx;
|
||||
height: 56rpx;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
border-radius: 40rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 119.5rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.wrap1_2 {
|
||||
top: 16rpx;
|
||||
left: 285rpx;
|
||||
position: absolute;
|
||||
|
||||
.wrap1_2_1 {
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.wrap1_2_2 {
|
||||
margin-bottom: 2rpx;
|
||||
font-size: 20rpx;
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.wrap1_1 {
|
||||
top: 26rpx;
|
||||
left: 26rpx;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 112rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 22rpx;
|
||||
font-size: 20rpx;
|
||||
|
||||
}
|
||||
.wrap1_6{
|
||||
box-sizing: border-box;
|
||||
border-left: 7rpx solid #fff;
|
||||
height: 208rpx;
|
||||
flex-grow: 1;
|
||||
background-color: red;
|
||||
}
|
||||
.wrap1_5{
|
||||
width: 262rpx;
|
||||
height: 208rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*.wrap1 {
|
||||
position: relative;
|
||||
width: 686rpx;
|
||||
height: 210rpx;
|
||||
background-image: url("https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/156dd8fa-e56d-4208-bc15-58eb273c146f.png");
|
||||
background-size: 100%;
|
||||
.wrap1_3 {
|
||||
bottom: 18rpx;
|
||||
right: 16rpx;
|
||||
position: absolute;
|
||||
width: 150rpx;
|
||||
height: 56rpx;
|
||||
background-color: #72665F;
|
||||
border-radius: 40rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 119.5rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.wrap1_2 {
|
||||
top: 16rpx;
|
||||
right: 182rpx;
|
||||
position: absolute;
|
||||
|
||||
.wrap1_2_1 {
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.wrap1_2_2 {
|
||||
margin-bottom: 2rpx;
|
||||
font-size: 20rpx;
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.wrap1_1 {
|
||||
top: 26rpx;
|
||||
left: 26rpx;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 112rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 22rpx;
|
||||
font-size: 20rpx;
|
||||
&.status2 {
|
||||
background-color: #fff;
|
||||
color: #FF5C62;
|
||||
}
|
||||
&.status4 {
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
}
|
||||
&.status3 {
|
||||
background-color: #fff;
|
||||
color: #72665F;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
.content4{
|
||||
|
||||
.content4 {
|
||||
margin-top: 22rpx;
|
||||
font-size: 28rpx;
|
||||
color:#72665F;
|
||||
}
|
||||
.content3{
|
||||
|
||||
.content3 {
|
||||
margin-top: 38rpx;
|
||||
height: 1rpx;
|
||||
width: 100%;
|
||||
background-image: url("../../static/zx303@3x (1).png");
|
||||
background-image: url("../../static/zx303@3x.png");
|
||||
background-size: 100%;
|
||||
}
|
||||
.content2{
|
||||
.content2 {
|
||||
flex-shrink: 0;
|
||||
margin-top: 34rpx;
|
||||
width: 686rpx;
|
||||
height: 134rpx;
|
||||
height: 134rpx!important;
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-radius: 40rpx;
|
||||
align-items: center;
|
||||
.wrap1{
|
||||
border-radius: 30rpx;
|
||||
margin-left: 28rpx;
|
||||
width: 290rpx;
|
||||
height: 104rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&.active{
|
||||
background-color: #F7963B;
|
||||
.wrap1_1{
|
||||
color: #fff;
|
||||
}
|
||||
.wrap1_2{
|
||||
color: #fff;
|
||||
}
|
||||
.wrap1 {
|
||||
border-radius: 30rpx;
|
||||
margin-left: 28rpx;
|
||||
width: 290rpx;
|
||||
height: 104rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.active {
|
||||
background-color: #F7963B;
|
||||
|
||||
.wrap1_1 {
|
||||
color: #fff;
|
||||
}
|
||||
.wrap1_1{
|
||||
font-size: 28rpx;
|
||||
color: #F7963B;
|
||||
}
|
||||
.wrap1_2{
|
||||
font-size: 20rpx;
|
||||
color: #000;
|
||||
|
||||
.wrap1_2 {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.wrap2{
|
||||
|
||||
.wrap1_1 {
|
||||
font-size: 28rpx;
|
||||
color: #F7963B;
|
||||
}
|
||||
|
||||
.wrap1_2 {
|
||||
font-size: 20rpx;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.wrap2 {
|
||||
margin-left: 28rpx;
|
||||
margin-right: 28rpx;
|
||||
width: 2rpx;
|
||||
width: 2rpx;
|
||||
height: 70rpx;
|
||||
background-color: #D8CDC6;
|
||||
}
|
||||
|
||||
.wrap3{
|
||||
.wrap3 {
|
||||
border-radius: 30rpx;
|
||||
width: 290rpx;
|
||||
height: 104rpx;
|
||||
@ -203,87 +526,130 @@ background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/ava
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&.active{
|
||||
|
||||
&.active {
|
||||
background-color: #F7963B;
|
||||
.wrap1_1{
|
||||
|
||||
.wrap1_1 {
|
||||
color: #fff;
|
||||
}
|
||||
.wrap1_2{
|
||||
|
||||
.wrap1_2 {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.wrap1_1{
|
||||
|
||||
.wrap1_1 {
|
||||
font-size: 28rpx;
|
||||
color: #979797;
|
||||
}
|
||||
.wrap1_2{
|
||||
|
||||
.wrap1_2 {
|
||||
font-size: 20rpx;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content1{
|
||||
|
||||
.content1 {
|
||||
margin-top: 38rpx;
|
||||
display: flex;
|
||||
.wrap2{
|
||||
margin-left: 24rpx;
|
||||
width: 182rpx;
|
||||
height: 150rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #E5580F;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.wrap2_2{
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
.wrap2{
|
||||
margin-left: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.wrap2_2{
|
||||
width: 184rpx;
|
||||
height: 68rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #B1292E;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.wrap2_2_2{
|
||||
margin-left: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.wrap2_2_1{
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.wrap2_1{
|
||||
width: 184rpx;
|
||||
height: 68rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #E5580F;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.wrap2_1_2{
|
||||
margin-left: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.wrap2_1_1{
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.wrap2_1{
|
||||
margin-left: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
image{
|
||||
width: 40.88rpx;
|
||||
height: 40.88rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.wrap1{
|
||||
.wrap1 {
|
||||
border-radius: 40rpx;
|
||||
width: 480rpx;
|
||||
height: 150rpx;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.wrap1_2{
|
||||
|
||||
.wrap1_2 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.wrap1_2_2{
|
||||
|
||||
.wrap1_2_2 {
|
||||
margin-top: 6rpx;
|
||||
color: #626262;
|
||||
}
|
||||
.wrap1_2_1{
|
||||
|
||||
.wrap1_2_1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.wrap1_2_1_1{
|
||||
|
||||
.wrap1_2_1_1 {
|
||||
color: #000;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.wrap1_2_1_2{
|
||||
|
||||
.wrap1_2_1_2 {
|
||||
margin-left: 6rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 76rpx;
|
||||
height: 26rpx;
|
||||
background-color:#FFCD5C;
|
||||
background-color: #FFCD5C;
|
||||
border-radius: 8rpx;
|
||||
font-size: 16rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.wrap1_1{
|
||||
|
||||
.wrap1_1 {
|
||||
margin-left: 68rpx;
|
||||
margin-right: 36rpx;
|
||||
image{
|
||||
|
||||
image {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
@ -1,44 +1,108 @@
|
||||
<template>
|
||||
<custom-title class="title-block" title="智慧门票">
|
||||
</custom-title>
|
||||
<div class="large-container">
|
||||
<div class="content1">
|
||||
<div class="wrap1">
|
||||
<image src="../../static/zy68.png"></image>
|
||||
<image :src="userInfo.avatar"></image>
|
||||
</div>
|
||||
<div class="wrap2">
|
||||
<div class="wrap2_1">恢复默认头像</div>
|
||||
<div class="wrap2_2">更换头像</div>
|
||||
<div class="wrap2_1" @click="setDefault">恢复默认头像</div>
|
||||
<div class="wrap2_2" @click="changeAvatar">更换头像</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content2">
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">
|
||||
<div class="wrap1_1_1">姓名</div>
|
||||
<div class="wrap1_1_2">已实名</div>
|
||||
<div class="wrap1_1_2" v-if="userInfo.idNum">已实名</div>
|
||||
</div>
|
||||
<div class="wrap1_2">xxx</div>
|
||||
<div class="wrap1_2">{{userInfo.realName}}</div>
|
||||
</div>
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">
|
||||
<div class="wrap1_1_1">身份证号</div>
|
||||
</div>
|
||||
<div class="wrap1_2">292199922283726657</div>
|
||||
<div class="wrap1_2">{{userInfo.idNum}}</div>
|
||||
</div>
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">
|
||||
<div class="wrap1_1_1">微信号</div>
|
||||
<div class="wrap1_1_1">手机号</div>
|
||||
</div>
|
||||
<div class="wrap1_2">12318881999</div>
|
||||
<div class="wrap1_2">{{ userInfo.telNum }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content3">*来自微信数据共享</div>
|
||||
<div class="content4">
|
||||
<div class="wrap1">注销账号</div>
|
||||
<div class="wrap2">退出登录</div>
|
||||
<div class="wrap2" @click="logOut">退出登录</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
import {getInfo, updateInfo, upload} from "@/http/apis";
|
||||
import {ref} from 'vue'
|
||||
const userInfo=ref(uni.getStorageSync('userInfo'))
|
||||
const getUserInfo = async () => {
|
||||
const res=await getInfo()
|
||||
if (res.code===200){
|
||||
uni.setStorageSync('userInfo',res.data)
|
||||
userInfo.value=res.data
|
||||
}
|
||||
}
|
||||
const currentAvatar=ref('')
|
||||
const changeAvatar=()=>{
|
||||
uni.chooseImage({
|
||||
count:1,
|
||||
success:async (res)=>{
|
||||
const res1= await upload({
|
||||
name:'file',
|
||||
filePath:res.tempFilePaths[0]
|
||||
})
|
||||
currentAvatar.value=res1.data.path
|
||||
await reqAvatar()
|
||||
}
|
||||
})
|
||||
}
|
||||
const setDefault=()=>{
|
||||
currentAvatar.value='https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/e1fd068c-180e-45d6-9196-680f778adc13.png'
|
||||
reqAvatar()
|
||||
}
|
||||
const logOut=()=>{
|
||||
uni.showModal({
|
||||
title: '提示', // 确认框标题
|
||||
content: '确认退出登录吗', // 确认框内容
|
||||
showCancel: true, // 是否显示取消按钮,默认为 true
|
||||
cancelText: '取消', // 取消按钮的文本,默认为"取消",最多 4 个字符
|
||||
cancelColor: '#000000', // 取消按钮的文本颜色,默认为"#000000"
|
||||
confirmText: '确定', // 确认按钮的文本,默认为"确定",最多 4 个字符
|
||||
confirmColor: '#576B95', // 确认按钮的文本颜色,默认为"#576B95"
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
uni.clearStorageSync()
|
||||
uni.navigateTo({
|
||||
url: '/pages/login/index'
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
}
|
||||
},
|
||||
fail: function (error) {
|
||||
}
|
||||
});
|
||||
}
|
||||
const reqAvatar=async ()=>{
|
||||
const res= await updateInfo({
|
||||
avatar:currentAvatar.value
|
||||
})
|
||||
if (res.code===200) {
|
||||
await getUserInfo()
|
||||
uni.showToast({
|
||||
title: '更换头像成功',
|
||||
icon: 'success',
|
||||
duration: 200
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.large-container{
|
||||
|
284
src/pages/test/index.vue
Normal file
@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="itemlist list-animation">
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-blur-in"></view>
|
||||
<view>blur-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-blur-out"></view>
|
||||
<view>blur-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-bounce-alt-in"></view>
|
||||
<view>bounce-alt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-bounce-alt-out"></view>
|
||||
<view>bounce-alt-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-bounce-in"></view>
|
||||
<view>bounce-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-bounce-out"></view>
|
||||
<view>bounce-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-fade-in"></view>
|
||||
<view>fade-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-fade-out"></view>
|
||||
<view>fade-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-fall-btt-in"></view>
|
||||
<view>fall-btt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-fall-ltr-in"></view>
|
||||
<view>fall-ltr-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-fall-rtl-in"></view>
|
||||
<view>fall-rtl-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-fall-ttb-in"></view>
|
||||
<view>fall-ttb-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-flip-h-in"></view>
|
||||
<view>flip-h-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-flip-h-out"></view>
|
||||
<view>flip-h-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-flip-v-in"></view>
|
||||
<view>flip-v-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-flip-v-out"></view>
|
||||
<view>flip-v-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-btt-in"></view>
|
||||
<view>float-btt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-btt-out"></view>
|
||||
<view>float-btt-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-ltr-in"></view>
|
||||
<view>float-ltr-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-ltr-out"></view>
|
||||
<view>float-ltr-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-rtl-in"></view>
|
||||
<view>float-rtl-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-rtl-out"></view>
|
||||
<view>float-rtl-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-ttb-in"></view>
|
||||
<view>float-ttb-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-float-ttb-out"></view>
|
||||
<view>float-ttb-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-btt-in"></view>
|
||||
<view>grow-btt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-btt-out"></view>
|
||||
<view>grow-btt-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-ltr-in"></view>
|
||||
<view>grow-ltr-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-ltr-out"></view>
|
||||
<view>grow-ltr-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-rtl-in"></view>
|
||||
<view>grow-rtl-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-rtl-out"></view>
|
||||
<view>grow-rtl-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-ttb-in"></view>
|
||||
<view>grow-ttb-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-grow-ttb-out"></view>
|
||||
<view>grow-ttb-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-jump-alt-in"></view>
|
||||
<view>jump-alt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-jump-alt-out"></view>
|
||||
<view>jump-alt-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-jump-in"></view>
|
||||
<view>jump-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-jump-out"></view>
|
||||
<view>jump-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-power-off"></view>
|
||||
<view>power-off</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-power-on"></view>
|
||||
<view>power-on</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-rush-btt-in"></view>
|
||||
<view>rush-btt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-rush-ltr-in"></view>
|
||||
<view>rush-ltr-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-rush-rtl-in"></view>
|
||||
<view>rush-rtl-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-rush-ttb-in"></view>
|
||||
<view>rush-ttb-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-btt-in"></view>
|
||||
<view>slide-btt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-btt-out"></view>
|
||||
<view>slide-btt-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-ltr-in"></view>
|
||||
<view>slide-ltr-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-ltr-out"></view>
|
||||
<view>slide-ltr-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-rtl-in"></view>
|
||||
<view>slide-rtl-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-rtl-out"></view>
|
||||
<view>slide-rtl-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-ttb-in"></view>
|
||||
<view>slide-ttb-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-slide-ttb-out"></view>
|
||||
<view>slide-ttb-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-spring-btt-in"></view>
|
||||
<view>spring-btt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-spring-ltr-in"></view>
|
||||
<view>spring-ltr-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-spring-rtl-in"></view>
|
||||
<view>spring-rtl-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-spring-ttb-in"></view>
|
||||
<view>spring-ttb-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-throw-btt-in"></view>
|
||||
<view>throw-btt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-throw-ltr-in"></view>
|
||||
<view>throw-ltr-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-throw-rtl-in"></view>
|
||||
<view>throw-rtl-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-throw-ttb-in"></view>
|
||||
<view>throw-ttb-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-vortex-alt-in"></view>
|
||||
<view>vortex-alt-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-vortex-alt-out"></view>
|
||||
<view>vortex-alt-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-vortex-in"></view>
|
||||
<view>vortex-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-vortex-out"></view>
|
||||
<view>vortex-out</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-zoom-in"></view>
|
||||
<view>zoom-in</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="ld infinite ld-zoom-out"></view>
|
||||
<view>zoom-out</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url('../../components/transition-min/transition.min.css');
|
||||
|
||||
.item {
|
||||
width: 250rpx;
|
||||
height: 250rpx;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.list-animation .item view:first-child {
|
||||
margin: 32px auto;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 3px;
|
||||
background: linear-gradient(45deg, #444 0%, #444 15%, transparent 15%, transparent 18%, #444 10%);
|
||||
}
|
||||
</style>
|
@ -1,141 +1,363 @@
|
||||
<template>
|
||||
<div class="large-container">
|
||||
<div class="content1">
|
||||
<div class="wrap1">
|
||||
<image src="../../static/zu1053@3x.png"></image>
|
||||
<div class="container">
|
||||
<custom-title class="title-block" title="门票详情">
|
||||
</custom-title>
|
||||
<div class="large-container">
|
||||
<div class="content1">
|
||||
<div class="wrap1">
|
||||
<image src="../../static/zu1053@3x.png"></image>
|
||||
</div>
|
||||
<div class="wrap2">大运河博物馆</div>
|
||||
</div>
|
||||
<div class="wrap2">门票系统的某个场馆</div>
|
||||
</div>
|
||||
<div class="content2">
|
||||
<image
|
||||
src="https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/2ec9fcae-55af-4ccd-8e92-6848282101bb.png"></image>
|
||||
</div>
|
||||
<div class="content3">
|
||||
<display-box>
|
||||
<template #l1>
|
||||
<div class="box-left">
|
||||
门票名称
|
||||
</div>
|
||||
</template>
|
||||
<template #r1>
|
||||
<div class="box-right">
|
||||
首都博物馆门票
|
||||
</div>
|
||||
</template>
|
||||
<template #l2>
|
||||
<div class="box-left">
|
||||
预留手机号 <span style="font-size: 18rpx">(+86)</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #r2>
|
||||
<div class="box-right">
|
||||
192119280121
|
||||
</div>
|
||||
</template>
|
||||
<template #l3>
|
||||
<div class="box-left">
|
||||
预约时间
|
||||
</div>
|
||||
</template>
|
||||
<template #r3>
|
||||
<div class="box-right">
|
||||
2023年12月16日
|
||||
</div>
|
||||
</template>
|
||||
<template #l4>
|
||||
<div class="box-left">
|
||||
预约人数
|
||||
</div>
|
||||
</template>
|
||||
<template #r4>
|
||||
<div class="box-right">
|
||||
2
|
||||
</div>
|
||||
</template>
|
||||
</display-box>
|
||||
</div>
|
||||
<div class="content4">
|
||||
<dashed-line></dashed-line>
|
||||
</div>
|
||||
<div class="content5">*参观人的身份证信息</div>
|
||||
<div class="content6">
|
||||
<display-box>
|
||||
<template #l1>
|
||||
<div class="box-left">
|
||||
姓名
|
||||
</div>
|
||||
</template>
|
||||
<template #r1>
|
||||
<div class="box-right">
|
||||
陈x
|
||||
</div>
|
||||
</template>
|
||||
<template #l2>
|
||||
<div class="box-left">
|
||||
身份证号
|
||||
</div>
|
||||
</template>
|
||||
<template #r2>
|
||||
<div class="box-right">
|
||||
192119280121
|
||||
</div>
|
||||
</template>
|
||||
</display-box>
|
||||
</div>
|
||||
<div class="content7">
|
||||
<display-box>
|
||||
<template #l1>
|
||||
<div class="box-left">
|
||||
姓名
|
||||
</div>
|
||||
</template>
|
||||
<template #r1>
|
||||
<div class="box-right">
|
||||
陈x
|
||||
</div>
|
||||
</template>
|
||||
<template #l2>
|
||||
<div class="box-left">
|
||||
身份证号
|
||||
</div>
|
||||
</template>
|
||||
<template #r2>
|
||||
<div class="box-right">
|
||||
192119280121
|
||||
</div>
|
||||
</template>
|
||||
</display-box>
|
||||
</div>
|
||||
<div class="content8" @click="returnTicket">
|
||||
退票
|
||||
</div>
|
||||
<div class="content9" v-if="dialog">
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">是否进行退票?</div>
|
||||
<div class="wrap1_2">2人:某某、某某某</div>
|
||||
<div class="wrap1_3">预约日期:2023年12月16日</div>
|
||||
<div class="wrap1_4">
|
||||
<div class="wrap1_4_1" @click="cancel">取消</div>
|
||||
<div class="wrap1_4_2">确定</div>
|
||||
<div class="content2">
|
||||
<image
|
||||
:src="ticket.ticketCoverPic"></image>
|
||||
</div>
|
||||
<div class="content3">
|
||||
<display-box>
|
||||
<template #l1>
|
||||
<div class="box-left">
|
||||
门票名称
|
||||
</div>
|
||||
</template>
|
||||
<template #r1>
|
||||
<div class="box-right">
|
||||
{{ticket.ticketName}}
|
||||
</div>
|
||||
</template>
|
||||
<template #l2>
|
||||
<div class="box-left">
|
||||
预留手机号(+86)
|
||||
</div>
|
||||
</template>
|
||||
<template #r2>
|
||||
<div class="box-right">
|
||||
{{ticket.phone}}
|
||||
</div>
|
||||
</template>
|
||||
<template #l3>
|
||||
<div class="box-left">
|
||||
预约时间
|
||||
</div>
|
||||
</template>
|
||||
<template #r3>
|
||||
<div class="box-right">
|
||||
{{ticket.date?dayjs(ticket.date).format('YYYY年MM月DD日'):'暂无'}}
|
||||
</div>
|
||||
</template>
|
||||
<template #l4>
|
||||
<div class="box-left">
|
||||
预约人数
|
||||
</div>
|
||||
</template>
|
||||
<template #r4>
|
||||
<div class="box-right">
|
||||
{{ticket.number}}
|
||||
</div>
|
||||
</template>
|
||||
</display-box>
|
||||
</div>
|
||||
<div class="content4">
|
||||
</div>
|
||||
<div class="content5">
|
||||
*参观人的身份证信息
|
||||
</div>
|
||||
<div class="content6" v-for="item in perList">
|
||||
<display-box>
|
||||
<template #l1>
|
||||
<div class="box-left">
|
||||
姓名
|
||||
</div>
|
||||
</template>
|
||||
<template #r1>
|
||||
<div class="box-right" style="display: flex;align-items: center">
|
||||
<div style="margin-right: 32rpx">{{item.userName}}</div>
|
||||
<div v-if="statusList.find(x=>x.value===item.status).label" style="width: 112rpx;height: 40rpx;background-color: #000;color: #fff;font-size: 20rpx;border-radius: 22rpx;display: flex;justify-content: center;align-items: center">{{statusList.find(x=>x.value===item.status).label}}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #l2>
|
||||
<div class="box-left">
|
||||
身份证号
|
||||
</div>
|
||||
</template>
|
||||
<template #r2>
|
||||
<div class="box-right">
|
||||
192119280121
|
||||
</div>
|
||||
</template>
|
||||
</display-box>
|
||||
</div>
|
||||
<div class="content7" style="margin-bottom: 60rpx">
|
||||
<display-box>
|
||||
<template #l1>
|
||||
<div class="box-left">
|
||||
文物概览概览
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r1>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l2>
|
||||
<div class="box-left">
|
||||
文物藏品精华
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r2>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l3>
|
||||
<div class="box-left">
|
||||
文化深度
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r3>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l4>
|
||||
<div class="box-left">
|
||||
文物年份
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r4>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l5>
|
||||
<div class="box-left">
|
||||
文物起源
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r5>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l6>
|
||||
<div class="box-left">
|
||||
文物描述
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r6>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l7>
|
||||
<div class="box-left">
|
||||
文化价值
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r7>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l8>
|
||||
<div class="box-left">
|
||||
保存状态
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r8>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l9>
|
||||
<div class="box-left">
|
||||
展品故事
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r9>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l10>
|
||||
<div class="box-left">
|
||||
制作时代
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r10>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l11>
|
||||
<div class="box-left">
|
||||
艺术流派
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r11>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l12>
|
||||
<div class="box-left">
|
||||
获取途径
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r12>
|
||||
<!-- 右侧内容或模板 -->
|
||||
</template>
|
||||
<template #l13>
|
||||
<div class="box-left">
|
||||
展览历程
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r13>
|
||||
</template>
|
||||
<template #l14>
|
||||
<div class="box-left">
|
||||
文物级别分类
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r14>
|
||||
</template>
|
||||
<template #l15>
|
||||
<div class="box-left">
|
||||
互动体验编码
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r15>
|
||||
</template>
|
||||
<template #l16>
|
||||
<div class="box-left">
|
||||
安全保护措施
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r16>
|
||||
</template>
|
||||
<template #l17>
|
||||
<div class="box-left">
|
||||
数字化档案编号
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r17>
|
||||
</template>
|
||||
<template #l18>
|
||||
<div class="box-left">
|
||||
权属证明区块链记录
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r18>
|
||||
</template>
|
||||
<template #l19>
|
||||
<div class="box-left">
|
||||
区块链高度
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r19>
|
||||
</template>
|
||||
<template #l20>
|
||||
<div class="box-left">
|
||||
Hash
|
||||
</div>
|
||||
</template>
|
||||
<template #r20>
|
||||
</template>
|
||||
<template #l21>
|
||||
<div class="box-left">
|
||||
交易hash
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r21>
|
||||
</template>
|
||||
<template #l22>
|
||||
<div class="box-left">
|
||||
虚拟收藏认证
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r22>
|
||||
</template>
|
||||
<template #l23>
|
||||
<div class="box-left">
|
||||
区块链技术应用
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r23>
|
||||
</template>
|
||||
<template #l24>
|
||||
<div class="box-left">
|
||||
物品元数据哈希值
|
||||
</div>
|
||||
</template>
|
||||
<template #r24>
|
||||
</template>
|
||||
<template #l25>
|
||||
<div class="box-left">
|
||||
登记交易哈希值
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #r25>
|
||||
</template>
|
||||
</display-box>
|
||||
</div>
|
||||
<div class="wrap1_5">*确认后将不再出现在票库</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
import displayBox from '../../components/display-box/index.vue'
|
||||
import dashedLine from '../../components/dashed-line/index.vue'
|
||||
const dialog=ref(false)
|
||||
const cancel=()=>{
|
||||
dialog.value=false
|
||||
}
|
||||
const returnTicket=()=>{
|
||||
dialog.value=true
|
||||
import {ref} from "vue";
|
||||
import dayjs from "dayjs";
|
||||
import {getTicketPerInfo} from "@/http/apis";
|
||||
const list = [{}]
|
||||
|
||||
const statusList=ref([
|
||||
{
|
||||
label:'',
|
||||
value:1
|
||||
},
|
||||
{
|
||||
label:'已退票',
|
||||
value:2
|
||||
},
|
||||
{
|
||||
label:'已核销',
|
||||
value:3
|
||||
},
|
||||
{
|
||||
label:'已过期',
|
||||
value:4
|
||||
},
|
||||
{
|
||||
label:'',
|
||||
value:5
|
||||
},
|
||||
{
|
||||
label:'盲盒',
|
||||
value:6
|
||||
}
|
||||
])
|
||||
const ticket=ref(uni.getStorageSync('ticket'))
|
||||
const perList=ref(null)
|
||||
const getInfo=async ()=>{
|
||||
const res= await getTicketPerInfo({
|
||||
appointmentUid:ticket.value.appointmentUid
|
||||
})
|
||||
perList.value=res.data.userInfo
|
||||
console.log(perList.value,'perList.value')
|
||||
}
|
||||
getInfo()
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
.box-left{
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
@ -145,116 +367,30 @@ const returnTicket=()=>{
|
||||
color: #72665F;
|
||||
}
|
||||
.large-container {
|
||||
overflow-y: auto;
|
||||
flex-grow: 1;
|
||||
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
||||
background-size: 100%;
|
||||
padding: 32rpx 42rpx 0 42rpx;
|
||||
.content9{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-top: 400rpx;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
.wrap1{
|
||||
width: 510rpx;
|
||||
height: 352rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.wrap1_5{
|
||||
margin-top: 12rpx;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
padding-right: 48rpx;
|
||||
width: 100%;
|
||||
font-size: 16rpx;
|
||||
color:#FF5C62;
|
||||
}
|
||||
.wrap1_4{
|
||||
margin-top: 62rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
padding-left: 34rpx;
|
||||
padding-right: 34rpx;
|
||||
.wrap1_4_2{
|
||||
border-radius: 30rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #F7963B;
|
||||
color: #fff;
|
||||
width: 210rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
.wrap1_4_1{
|
||||
border-radius: 30rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
width: 210rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
.wrap1_3{
|
||||
font-size: 24rpx;
|
||||
color: #B29E92;
|
||||
}
|
||||
.wrap1_2{
|
||||
margin-bottom: 16rpx;
|
||||
font-size: 24rpx;
|
||||
color: #B29E92;
|
||||
}
|
||||
.wrap1_1{
|
||||
margin-top: 48rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
font-size: 28rpx;
|
||||
color: #FF5C62;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content8{
|
||||
margin: 0 auto;
|
||||
border-radius: 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
width: 436rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #FF5C62;
|
||||
}
|
||||
.content7{
|
||||
margin-bottom: 72rpx;
|
||||
}
|
||||
|
||||
.content6{
|
||||
margin-bottom: 20rpx;
|
||||
margin-top: 12rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
.content5{
|
||||
margin-bottom: 20rpx;
|
||||
margin-top: 24rpx;
|
||||
color:#F7963B ;
|
||||
font-size: 24rpx;
|
||||
color: #F7963B;
|
||||
text-align: left;
|
||||
}
|
||||
.content3{
|
||||
margin-top: 42rpx;
|
||||
margin-bottom: 42rpx;
|
||||
}
|
||||
.content4{
|
||||
margin-bottom: 24rpx;
|
||||
.content3{
|
||||
margin-top: 42rpx;
|
||||
margin-bottom: 28rpx;
|
||||
|
||||
}
|
||||
.content4 {
|
||||
height: 1rpx;
|
||||
width: 100%;
|
||||
background-image: url("../../static/zx303@3x.png");
|
||||
background-size: 100%;
|
||||
}
|
||||
.content2 {
|
||||
margin-top: 12rpx;
|
||||
|
@ -1,25 +1,225 @@
|
||||
<template>
|
||||
<div>
|
||||
<tm-drawer placement="bottom" okText='确认' v-model:show="show" @close="close">
|
||||
<tm-drawer placement="bottom" okText='确认' :show="show" :height="1054" :hideHeader=true>
|
||||
<div class="container">
|
||||
<tm-icon name="tmicon-times-circle" color="#ccc" class="icon-close" @click="close"></tm-icon>
|
||||
<div class="title">请选择参观日期</div>
|
||||
<tm-divider color="#868686"></tm-divider>
|
||||
<div>当前年月日:{{ currentDate }}</div>
|
||||
<tm-divider color="#868686"></tm-divider>
|
||||
<div class="date-box">
|
||||
<div class="date-box-item" v-for="(item, index) in dateList" :key="index">
|
||||
<div :class="[index === currentIndex ? 'active' : '', 'date-box-item-day']"
|
||||
@click="chooseDatehandle($event, item.date, index)">
|
||||
<div :style="{ fontSize: '30rpx', fontWeight: '600' }">{{ item.date }}日·周{{
|
||||
dayChineseMap[item.week] }}
|
||||
</div>
|
||||
<div style="font-size: 22rpx;">*可预约</div>
|
||||
</div>
|
||||
<div style="font-size: 30rpx;color:#F7963B ;">{{ dayjs().format('MM-DD') + '日' == item.date
|
||||
? '今日' : '明天' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="more-date" @click="changeMoreDate">
|
||||
<div style="font-size: 30rpx;width: 100rpx;">选择更多日期</div>
|
||||
<div>
|
||||
<tm-icon name="tmicon-angle-right" :fontSize="26" color="#fff"></tm-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<tm-divider color="#868686"></tm-divider>
|
||||
<div class="title">请选择参观日期</div>
|
||||
<div class="time-box">
|
||||
<div class="time-box-item">
|
||||
<div :style="{ fontWeight: '600' }">08:00入场</div>
|
||||
<div :style="{ fontSize: '22rpx', }">*不可选</div>
|
||||
</div>
|
||||
<div class="time-box-item">
|
||||
<div :style="{ fontWeight: '600' }">08:00入场</div>
|
||||
<div :style="{ fontSize: '22rpx', }">*不可选</div>
|
||||
</div>
|
||||
<div class="time-box-item">
|
||||
<div :style="{ fontWeight: '600' }">08:00入场</div>
|
||||
<div :style="{ fontSize: '22rpx', }">*不可选</div>
|
||||
</div>
|
||||
<div class="time-box-item">
|
||||
<div :style="{ fontWeight: '600' }">08:00入场</div>
|
||||
<div :style="{ fontSize: '22rpx', }">*不可选</div>
|
||||
</div>
|
||||
<div class="time-box-item">
|
||||
<div :style="{ fontWeight: '600' }">08:00入场</div>
|
||||
<div :style="{ fontSize: '22rpx', }">*不可选</div>
|
||||
</div>
|
||||
<div class="time-box-item">
|
||||
<div :style="{ fontWeight: '600' }">08:00入场</div>
|
||||
<div :style="{ fontSize: '22rpx', }">*不可选</div>
|
||||
</div>
|
||||
</div>
|
||||
<tm-divider color="#868686"></tm-divider>
|
||||
<div class="tips">
|
||||
<div>*参观当日需要携带游客本人身份证件</div>
|
||||
<div> *入馆时间:</div>
|
||||
<div>
|
||||
工作日08:30-18:00、节假日/双休09:00-20:00(具体时间以景区为准)
|
||||
</div>
|
||||
</div>
|
||||
<tm-divider color="#868686"></tm-divider>
|
||||
<div style="margin: auto;">
|
||||
<tm-button color="#000000" :width="436" :height="60" :round="25">确定</tm-button>
|
||||
</div>
|
||||
<tm-calendar format="YYYY-MM-DD" @confirm="comfirmCal" color="#F7963B" v-model:show="isMoreDate" update:show
|
||||
:start="[dayjs()]" :end="[endDate]"></tm-calendar>
|
||||
</div>
|
||||
</tm-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, onMounted, defineEmits, watch } from 'vue'
|
||||
import { defineProps, ref, defineEmits, watch, onMounted, computed } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
const props = defineProps({
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(["update:show"]);
|
||||
|
||||
|
||||
let currentIndex = ref(-1)
|
||||
let currentDate = ref('')
|
||||
let isMoreDate = ref(false)
|
||||
const dayChineseMap = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
let dateList = ref([
|
||||
{
|
||||
date: dayjs().format('MM-DD'),
|
||||
week: dayjs().day(),
|
||||
},
|
||||
{
|
||||
date: dayjs().add(1, 'day').format('MM-DD'),
|
||||
week: dayjs().add(1, 'day').day(),
|
||||
}
|
||||
])
|
||||
const chooseDatehandle = (e, date, index) => {
|
||||
currentDate.value = dayjs().year() + '-' + date
|
||||
currentIndex.value = index
|
||||
}
|
||||
const close = () => {
|
||||
emits("update:show", false);
|
||||
}
|
||||
const changeMoreDate = () => {
|
||||
isMoreDate.value = true
|
||||
}
|
||||
const endDate = computed(() => {
|
||||
const lastDayOfMonth = dayjs().endOf('month');
|
||||
const year = lastDayOfMonth.year();
|
||||
const month = lastDayOfMonth.month() + 1;
|
||||
const date = lastDayOfMonth.date();
|
||||
return dayjs(year + '-' + month + '-' + date).add(2, 'month');
|
||||
});
|
||||
const comfirmCal = (date) => {
|
||||
currentDate.value = date[0].split('/').join('-')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 30rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.icon-close {
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
top: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.date-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 20rpx 0;
|
||||
|
||||
.date-box-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
.date-box-item-day {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 32rpx;
|
||||
border: 1px solid #F7963B;
|
||||
padding: 20rpx 18rpx;
|
||||
box-sizing: border-box;
|
||||
width: 240rpx;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: #F7963B;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.more-date {
|
||||
display: flex;
|
||||
padding: 20rpx 18rpx;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
height: 100rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius: 32rpx;
|
||||
color: #fff;
|
||||
background-color: #F7963B;
|
||||
}
|
||||
}
|
||||
|
||||
.time-box::-webkit-scrollbar {
|
||||
display: none;
|
||||
/* 对于Webkit浏览器 */
|
||||
}
|
||||
|
||||
.time-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
margin-top: 20rpx;
|
||||
box-sizing: border-box;
|
||||
-ms-overflow-style: none;
|
||||
/* 对于IE和Edge */
|
||||
scrollbar-width: none;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
/* 对于Firefox */
|
||||
.time-box-item {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 30rpx;
|
||||
padding: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
border-radius: 32rpx;
|
||||
border: 1rpx solid #F7963B;
|
||||
width: 188rpx;
|
||||
height: 114rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #B29E92;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,12 +1,15 @@
|
||||
<template>
|
||||
|
||||
<div class="large-container">
|
||||
<div class="content1">
|
||||
<custom-title class="title-block" :title="ticket?.ticketName">
|
||||
</custom-title>
|
||||
<div class="content1" :style="{backgroundImage:`url(${ticket?.ticketCoverPic})`}">
|
||||
<div class="wrap1" @click="dialog=true">
|
||||
<image src="../../static/zu1041@3x (1).png"></image>
|
||||
<image src="../../static/zu1041@3x.png"></image>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content2">
|
||||
<div class="grid-cell red">
|
||||
<div class="grid-cell red" @click="showWin=true">
|
||||
<image src="../../static/zu1067@3x.png"></image>
|
||||
</div>
|
||||
<div class="grid-cell black"> <image src="../../static/zu1063@3x.png"></image></div>
|
||||
@ -19,7 +22,7 @@
|
||||
<image src="../../static/zu1065@3x.png"></image>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="dialog" class="content4">
|
||||
<div v-show="dialog" class="content4">
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">
|
||||
<div class="wrap1_1_1">
|
||||
@ -43,7 +46,7 @@
|
||||
<div class="wrap1_1_2_2">首都博物馆</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap1_2" @click="dialog=false">
|
||||
<div class="wrap1_2" @click="closeDialog">
|
||||
<div class="wrap1_2_1" >退出</div>
|
||||
<image style="width:28rpx;height: 28rpx " src="../../static/zu1043@3x.png"></image>
|
||||
</div>
|
||||
@ -52,8 +55,14 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
import {ref,nextTick} from 'vue'
|
||||
const dialogRef=ref(null)
|
||||
const dialog=ref(false)
|
||||
const ticket= uni.getStorageSync('ticket')
|
||||
const closeDialog=()=>{
|
||||
dialog.value=false
|
||||
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.large-container{
|
||||
|
BIN
src/static/112121@3x.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
src/static/Close@3x.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 2.2 MiB |
BIN
src/static/lj781@3x.png
Normal file
After Width: | Height: | Size: 782 B |
Before Width: | Height: | Size: 4.0 KiB |
BIN
src/static/tbys@3x.png
Normal file
After Width: | Height: | Size: 846 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
BIN
src/static/zu1105@3x.png
Normal file
After Width: | Height: | Size: 477 KiB |
BIN
src/static/zu1123@3x.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
src/static/zu1149@3x.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/static/zu1150@3x.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/static/zu1216@3x.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
BIN
src/static/zu758@3x.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 209 B |
13
src/store/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
import {defineStore} from 'pinia'
|
||||
import {ref} from 'vue'
|
||||
import {getInfo} from "@/http/apis";
|
||||
|
||||
export const useMainStore = defineStore('main', () => {
|
||||
const titleHeight = ref('')
|
||||
const tabHeight = ref('')
|
||||
const currentBooking = ref(null)
|
||||
const isShow = ref(true)
|
||||
|
||||
return {titleHeight, tabHeight, isShow,currentBooking}
|
||||
}
|
||||
)
|
@ -2,6 +2,7 @@ import { defineConfig } from "vite";
|
||||
import uni from "@dcloudio/vite-plugin-uni";
|
||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
||||
import { resolve } from "path"
|
||||
|
||||
// import Components from 'unplugin-vue-components/vite'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
|