我的 #3

Merged
qiushanhe merged 1 commits from dev-qsh into master 1 year ago
  1. 358
      src/components/liu-indexed-list/liu-indexed-list.vue
  2. 989
      src/components/liu-indexed-list/pinyinUtil.js
  3. 36
      src/pages.json
  4. 54
      src/pages/me/index.vue
  5. 40
      src/pages/me/info.vue
  6. 50
      src/pages/me/school.vue
  7. 42
      src/pages/me/tijian.vue
  8. 226
      src/pages/me/vip.vue
  9. BIN
      src/static/image/mine/1.png
  10. BIN
      src/static/image/mine/2.png
  11. BIN
      src/static/image/mine/3.png
  12. BIN
      src/static/image/mine/noData.png
  13. BIN
      src/static/image/mine/search.png
  14. BIN
      src/static/image/mine/tijian.png
  15. BIN
      src/static/image/mine/top.png
  16. BIN
      src/static/image/mine/vip.png
  17. BIN
      src/static/image/mine/vip_card.png
  18. 4
      src/static/style/base.scss

@ -0,0 +1,358 @@
<template>
<view class="liu-list">
<scroll-view class="liu-scroll-left" scroll-y="true" :scroll-with-animation="true"
:scroll-into-view="scrollIntoView">
<view class="liu-search" id="TOP">
<image class="liu-search-img" src="../../static/image/mine/search.png"></image>
<input class="liu-input" @input="search" v-model="searchStr" placeholder="请输入搜索信息" maxlength="50"
placeholder-class="liu-placeholder" />
</view>
<view class="left-list" v-for="(item,index) of scrollLeftObj" :key="index" :id="index!='#'?index:'BOTTOM'">
<view class="left-item-title" v-if="item && item.length">{{index}}</view>
<view class="left-item-card" v-for="(mess,inx) in item" @click.stop="chooseItem(mess)">
<view class="left-item-card-info"
:style="inx<item.length-1?'border-bottom: solid #F4F4F4 1rpx;':''">
<view class="left-item-card-name" :class="{ actived: mess[idKey] == current }">
{{mess[nameKey] || ''}}
</view>
<u-icon class="mr30" v-if="mess[idKey] == current" color="#05C341" size="16px" name="checkmark"></u-icon>
</view>
</view>
</view>
<view class="no-data" v-if="!hasData">
<image class="no-data-img" src="../../static/image/mine/noData.png"></image>
<view class="no-data-name">暂无数据</view>
</view>
</scroll-view>
<view class="liu-scroll-right" v-if="hasData">
<image class="liu-scroll-right-top" src="../../static/image/mine/top.png" @click.stop="scrollIntoView = 'TOP'"></image>
<view :class="{'liu-scroll-right-name':true,'liu-scroll-right-select':item==scrollIntoView}"
v-for="(item,index) in scrollRightList" :key="index" @click.stop="chooseType(item)">{{item}}
</view>
</view>
</view>
</template>
<script>
import {
pinyinUtil
} from './pinyinUtil.js';
export default {
props: {
//
dataList: {
type: Array,
required: true,
default: () => {
return []
}
},
//key
idKey: {
type: String,
default: 'id'
},
//key
nameKey: {
type: String,
default: 'name'
},
//key
phoneKey: {
type: String,
default: 'phone'
},
//key
imgKey: {
type: String,
default: 'img'
},
//(rpxpx%)
radius: {
type: String,
default: '6rpx'
},
current: {
type: [String,Number],
default: ''
}
},
data() {
return {
searchStr: '',
scrollIntoView: '',
scrollLeftObj: {},
oldObj: {},
scrollRightList: [],
hasData: true
};
},
watch: {
dataList: {
immediate: true,
deep: true,
handler(newList) {
if (newList && newList.length) this.cleanData(newList)
},
},
},
methods: {
search() {
if (this.searchStr) {
let has = false
this.scrollLeftObj = JSON.parse(JSON.stringify(this.oldObj))
for (let i in this.scrollLeftObj) {
this.scrollLeftObj[i] = this.scrollLeftObj[i].filter(item => {
return (item[this.nameKey].indexOf(this.searchStr) != -1) || item[this.phoneKey]
.indexOf(this.searchStr) != -1
})
if (this.scrollLeftObj[i].length) has = true
}
if (has) this.hasData = true
else this.hasData = false
} else {
this.hasData = true
this.scrollLeftObj = JSON.parse(JSON.stringify(this.oldObj))
}
},
cleanData(list) {
this.scrollRightList = this.getLetter()
let newList = []
list.forEach(res => {
let initial = pinyinUtil.getFirstLetter(res[this.nameKey].trim())
let firsfirs = initial ? initial.substring(0, 1) : ''
if (!newList[firsfirs]) newList[firsfirs] = []
newList[firsfirs].push({
[this.idKey]: res[this.idKey] || '',
[this.nameKey]: res[this.nameKey].trim() || '',
[this.phoneKey]: res[this.phoneKey] || '',
[this.imgKey]: res[this.imgKey] || ''
})
})
this.scrollRightList.forEach(t => {
if (newList[t]) {
this.$set(this.scrollLeftObj, t, newList[t])
} else {
this.$set(this.scrollLeftObj, t, [])
}
})
let surplusList = []
for (var i in newList) {
let han = this.scrollRightList.find(v => {
return v == i
})
if (!han) surplusList.push(newList[i])
}
surplusList.forEach(item => {
this.scrollLeftObj['#'] = this.scrollLeftObj['#'].concat(item)
})
this.oldObj = JSON.parse(JSON.stringify(this.scrollLeftObj))
},
getLetter() {
let list = []
for (var i = 0; i < 26; i++) {
list.push(String.fromCharCode(65 + i))
}
list.push('#')
return list
},
chooseType(item) {
if (item == '#') item = 'BOTTOM'
this.scrollIntoView = item
},
preview(img) {
uni.previewImage({
current: 0,
urls: [img]
})
},
chooseItem(item) {
this.$emit('update:current', item[this.idKey])
this.$emit('click', item)
}
},
emits: ['update:current']
};
</script>
<style>
/deep/ ::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
}
</style>
<style lang="scss" scoped>
.liu-list {
width: 100%;
height: 100vh;
background-color: #F4F4F4;
box-sizing: border-box;
padding-top: 1px;
.liu-scroll-left {
height: 100%;
.liu-search {
width: 100%;
height: 106rpx;
background-color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.liu-search-img {
width: 32rpx;
height: 32rpx;
position: absolute;
left: 64rpx;
}
.liu-input {
width: calc(100% - 64rpx);
height: 72rpx;
background: #EEEEEE;
border-radius: 36rpx;
padding: 0 32rpx 0 80rpx;
box-sizing: border-box;
color: #333333;
}
.liu-placeholder {
color: #777777;
}
}
.left-list {
height: auto;
.left-item-title {
width: calc(100% - 24rpx);
height: 60rpx;
padding-left: 24rpx;
text-align: left;
line-height: 60rpx;
font-size: 30rpx;
color: #666666;
}
.left-item-card {
width: 100%;
height: 112rpx;
background-color: #FFFFFF;
box-sizing: border-box;
padding-left: 24rpx;
display: flex;
align-items: center;
justify-content: flex-start;
.left-item-card-img {
width: 80rpx;
min-width: 80rpx;
height: 80rpx;
background-color: #CFCFCF;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
font-weight: bold;
color: #FFFFFF;
}
.img-info {
background: none;
border: solid #f0f0f0 1rpx;
}
.left-item-card-info {
width: 100%;
margin-left: 32rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left-item-card-name {
font-size: 30rpx;
line-height: 30rpx;
color: #333333;
}
.left-item-card-phone {
margin-top: 14rpx;
font-size: 28rpx;
line-height: 28rpx;
color: #999999;
}
}
}
}
.no-data {
width: 100%;
display: flex;
align-items: center;
justify-items: center;
flex-direction: column;
margin-top: 25%;
.no-data-img {
width: 200rpx;
height: 200rpx;
}
.no-data-name {
margin-top: 20rpx;
font-size: 28rpx;
color: #666666;
}
}
}
.liu-scroll-right {
position: fixed;
right: 0rpx;
top: 50%;
transform: translateY(-47%);
z-index: 999 !important;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.liu-scroll-right-top {
width: 32rpx;
height: 32rpx;
margin-right: 14rpx;
z-index: 999 !important;
}
.liu-scroll-right-name {
width: 32rpx;
padding-right: 14rpx;
height: 28rpx;
font-size: 22rpx;
color: #333333;
line-height: 22rpx;
margin-top: 8rpx;
display: flex;
align-items: center;
justify-content: center;
}
.liu-scroll-right-select {
padding: 0;
margin-right: 14rpx;
width: 28rpx;
height: 28rpx;
border-radius: 50%;
background: #2991FF;
color: #FFFFFF;
}
}
}
.actived {
color: #05C341;
}
</style>

File diff suppressed because one or more lines are too long

@ -31,6 +31,42 @@
"navigationBarTitleText": "模拟考试"
}
}
,{
"path" : "pages/me/vip",
"style" :
{
"navigationBarTitleText": "会员中心",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/me/info",
"style" :
{
"navigationBarTitleText": "我的资料",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/me/tijian",
"style" :
{
"navigationBarTitleText": "我的体检",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/me/school",
"style" :
{
"navigationBarTitleText": "绑定驾校",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {

@ -6,23 +6,43 @@
<view class="info flex ai-c">
<u-avatar class="br-p50 overflow-h" :size="64" :src="user.avatar" mp-avatar shape="circle"></u-avatar>
<view class="ml12">
<view class="fs18 cor-333 fwb">{{user.name}}</view>
<view class="flex ai-c fs18 cor-333 fwb">
<text class="mr10">{{user.name}}</text>
<image src="/static/image/mine/vip.png" mode="widthFix" style="width: 18px;"></image>
</view>
<view class="mt5 fs14 cor-666">陪您学车 {{user.count}}</view>
</view>
</view>
</view>
<view class="p15lr" style="transform: translateY(-90px);">
<view class="mb10" v-if="user.vip">
<view class="relative mb10" @tap="handleVip">
<image src="/static/image/mine/vip_bg.png" mode="widthFix" style="width: 100%;"></image>
<view class="absolute p15lr p10tb flex ai-c jc-sb" style="left: 0;top: 0;right: 0;height: 40px;">
<view class="flex ai-c">
<view class="p3 br-p50" style="background-color: #873E1D;">
<image src="/static/image/mine/vip.png" mode="widthFix" style="width: 18px;height: 15px;"></image>
</view>
<text class="ml5 fs16 fwb" style="color: #7E4012FF;">VIP会员</text>
</view>
<text class="fs12" style="color: #7E4012FF;">2024-12-12到期</text>
</view>
<view class="absolute flex ai-c jc-c" style="left: 0;top: 40px;right: 0;bottom: 0;">
<view class="text-center">
<view class="fs18 fwb" style="color: #7E4012FF;">尊享科目一二三四全部付费权益</view>
<view class="study fs16 text-center" style="margin: 25px auto 0;color: #F6E99FFF;">
马上学习
</view>
</view>
</view>
</view>
<view class="br8 bc-fff p15 z-index2">
<text class="fs16 cor-333">我的驾校</text>
<div class="mt12 flex ai-c jc-sb">
<text class="fs18 cor-000 fwb">合肥八一驾校</text>
<u-button text="切换驾校" shape="circle"></u-button>
<u-button text="切换驾校" shape="circle" @click="handleChangeSchool"></u-button>
</div>
<u-line margin="14px 0 18px 0"></u-line>
<view class="flex ai-c">
<view class="flex ai-c" @tap="handleCallPhone">
<view class="flex ai-c jc-c phone">
<img src="/static/image/mine/phone.png" style="width: 12px;height: 12px;">
<text class="ml2 fs12 cor-fff">客服热线</text>
@ -32,12 +52,12 @@
</view>
<view class="mt12 bc-fff br8">
<u-cell-group>
<u-cell size="large" title="我的资料" value="修改" isLink>
<u-cell size="large" title="我的资料" value="修改" isLink url="/pages/me/info">
<template #icon>
<img src="/static/image/mine/wdzl.png" style="width: 24px;height: 24px;">
</template>
</u-cell>
<u-cell size="large" title="我的体检" value="查看报告" isLink>
<u-cell size="large" title="我的体检" value="查看报告" isLink url="/pages/me/tijian">
<template #icon>
<img src="/static/image/mine/wdtj.png" style="width: 24px;height: 24px;">
</template>
@ -74,6 +94,21 @@
},
methods: {
handleVip() {
uni.navigateTo({
url: '/pages/me/vip'
})
},
handleCallPhone() {
uni.makePhoneCall({
phoneNumber: '17318531354'
})
},
handleChangeSchool() {
uni.navigateTo({
url: '/pages/me/school'
})
}
}
}
</script>
@ -90,4 +125,11 @@
background: #05C341;
border-radius: 16px 16px 0px 16px;
}
.study {
width: 200px;
height: 35px;
line-height: 35px;
background: #7E4012;
border-radius: 35px;
}
</style>

@ -0,0 +1,40 @@
<template>
<view class="p15 bc-f5">
<view class="br8 bc-fff p15lr">
<view class="flex ai-c bb1" style="height: 110rpx;">
<view class="title">联系电话</view>
<view class="m30lr fs14 cor-333 fl1">15122305568</view>
<u-icon name="arrow-right" color="#999" />
</view>
<view class="flex ai-c" style="height: 110rpx;">
<view class="title">地址</view>
<view class="m30lr fs14 cor-333 fl1">安徽省合肥市包河区</view>
<u-icon name="arrow-right" color="#999" />
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.title {
width: 120rpx;
font-size: 14px;
color: #666;
}
.bb1 {
border-bottom: 1px solid #eee;
}
</style>

@ -0,0 +1,50 @@
<template>
<view>
<IndexList :dataList="dataList" nameKey="schoolName" v-model:current="current" @click="click"></IndexList>
</view>
</template>
<script>
import IndexList from '@/components/liu-indexed-list/liu-indexed-list.vue'
export default {
components: {
IndexList
},
data() {
return {
current: '1',
dataList: [{
id: '1',
schoolName: '爱尚学车驾校长安分校',
},{
id: '2',
schoolName: '八一驾校',
},{
id: '3',
schoolName: '八零驾校',
},{
id: '4',
schoolName: '畅通驾校',
},{
id: '5',
schoolName: '金灵驾校',
},{
id: '6',
schoolName: '通顺驾校',
}]
}
},
methods: {
click() {
//
//
uni.navigateBack()
}
}
}
</script>
<style>
</style>

@ -0,0 +1,42 @@
<template>
<view class="p15 bc-f5">
<view class="br8 bc-fff p15lr">
<view class="flex ai-c bb1" style="height: 110rpx;">
<view class="title">体检结果</view>
<view class="ml30 fs14 cor-333 fl1">通过</view>
</view>
<view class="flex ai-c" style="height: 110rpx;">
<view class="title">体检时间</view>
<view class="ml30 fs14 cor-333 fl1">2023-08-10 14:35:23</view>
</view>
<view class="flex ai-fs" style="height: 110rpx;">
<view class="title">体检时间</view>
<image class="ml30" src="/static/image/mine/tijian.png" style="width: 333rpx;" mode="widthFix"></image>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.title {
width: 120rpx;
font-size: 14px;
color: #666;
}
.bb1 {
border-bottom: 1px solid #eee;
}
</style>

@ -0,0 +1,226 @@
<template>
<view class="flex fld-c p15">
<u-sticky>
<view class="flex ai-c">
<view v-for="(item,index) in list" :key="index" class="km-item" :class="{ actived: index==current }"
@click="current=index">
{{ item.name }}
</view>
</view>
</u-sticky>
<view class="mt15">
<swiper class="swiper" :current="current" style="height: 120px;" :autoplay="false" :display-multiple-items="1.45"
:disable-programmatic-animation="true" @change="onChange">
<swiper-item v-for="(item,index) in list" :key="index">
<view class="relative">
<image src="../../static/image/mine/vip_card.png" mode="widthFix" style="width:95%;"></image>
<view class="vip-info">
<u-avatar class="br-p50 overflow-h" style="border: 3px solid #873E1D;" :size="35" mp-avatar></u-avatar>
<view class="ml10">
<view class="fs16 fwb" style="color: #7E4012;line-height: 16px;">
{{item.name}}尊享VIP
</view>
<view class="mt5 fs12" style="color: #7E4012;line-height: 12px;">
2024-12-12到期
</view>
</view>
</view>
<view class="corner">
VIP已开通
</view>
<view class="renew">
98元立即续费
</view>
</view>
</swiper-item>
<swiper-item>
</swiper-item>
</swiper>
</view>
<view class="mt20">
<swiper class="swiper" :current="current" style="height: 300px;" :autoplay="false"
:disable-programmatic-animation="true" @change="onChange">
<swiper-item v-for="(item,index) in list" :key="index">
<view v-if="index == 0 || index == 3" class="p15 br8 cor-fff">
<view class="fs18 cor-000 fwb">
3步轻松学{{item.name}}
</view>
<view class="mt25 flex ai-c jc-sb">
<view class="flex ai-c">
<image src="../../static/image/mine/1.png" mode="widthFix" style="width:25px;"></image>
<view class="ml7">
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
精简500题
</view>
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
题目全部做对视为完成
</view>
</view>
</view>
<view class="study">
去学习
</view>
</view>
<view class="mt45 flex ai-c jc-sb">
<view class="flex ai-c">
<image src="../../static/image/mine/2.png" mode="widthFix" style="width:25px;"></image>
<view class="ml7">
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
真实考场模拟
</view>
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
10次95分以上视为完成
</view>
</view>
</view>
<view class="study">
去学习
</view>
</view>
<view class="mt45 flex ai-c jc-sb">
<view class="flex ai-c">
<image src="../../static/image/mine/3.png" mode="widthFix" style="width:25px;"></image>
<view class="ml7">
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
考前密卷
</view>
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
2套试卷95分以上视为完成
</view>
</view>
</view>
<view class="study">
去学习
</view>
</view>
</view>
<view v-else style="margin-top: 30rpx;">
<view class="video-box">
<view class="flex jc-sb ai-c wp100">
<text style="color: #873E1D;font-size: 36rpx;">考场实况</text>
<text class="cor-666 fs12">全部 ></text>
</view>
<view class="flex ai-c mt20">
<image src="../../static/image/index/index_bg.png" mode="widthFix" style="flex: 1;border-radius: 33rpx;"></image>
<view class="ml18 text-center">
<u-button :customStyle="{width:'200rpx',height:'66rpx',borderRadius: '33rpx'}" iconColor="#fff"
text="去看视频" color="linear-gradient(90deg, #E66501 0%, #F8A42C 100%)" icon="play-circle">
</u-button>
<view class="cor-333 fs15 mt17">真实考场模拟</view>
</view>
</view>
</view>
</view>
</swiper-item>
<swiper-item>
</swiper-item>
</swiper>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [{
name: '科一'
}, {
name: '科二'
}, {
name: '科三'
}, {
name: '科四'
}],
current: 0
}
},
methods: {
onChange(e) {
this.current = e.detail.current
}
}
}
</script>
<style lang="scss" scoped>
.km-item {
margin-right: 8px;
width: 72px;
height: 30px;
line-height: 30px;
font-size: 12px;
color: #333;
text-align: center;
border-radius: 15px;
border: 1px solid #CCCCCC;
}
.actived {
background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%);
color: #fff;
}
.km-item:last-of-type {
margin-right: 0;
}
.vip-info {
position: absolute;
top: 15px;
left: 10px;
display: flex;
align-items: center;
}
.corner {
position: absolute;
bottom: 0;
left: 0;
width: 77px;
height: 23px;
background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%);
opacity: 0.86;
border-radius: 0px 8px 0px 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #fff;
}
.renew {
position: absolute;
right: 10%;
bottom: 15px;
display: flex;
align-items: center;
justify-content: center;
width: 185rpx;
height: 52rpx;
background: #873E1D;
border-radius: 26rpx;
font-size: 12px;
color: #F6E99F;
}
.study {
display: flex;
align-items: center;
justify-content: center;
width: 161rpx;
height: 67rpx;
background: #F6E99F;
border-radius: 34rpx;
font-size: 12px;
color: #873E1D;
}
.video-box {
padding: 20rpx;
width: 694rpx;
height: 369rpx;
background: #F9F3E7;
border: 2rpx solid #CF8B6D;
border-radius: 16rpx;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

@ -298,15 +298,12 @@ body,
}
.relative {
position: relative;
z-index: 1;
}
.absolute {
position: absolute;
z-index: 2;
}
.absolute-full {
position: absolute;
z-index: 2;
top: 0;
left: 0;
right: 0;
@ -314,7 +311,6 @@ body,
}
.fixed {
position: fixed;
z-index: 9;
}
.break-all {
display: block;

Loading…
Cancel
Save