Browse Source

add md0726 style

md0726
刘嘉炜 10 months ago
parent
commit
b236b4c45e
  1. 92
      src/components/filter/filter_modal.vue
  2. 107
      src/components/filter/header.vue
  3. 139
      src/components/filter/period_modal.vue
  4. 101
      src/components/filter/stadium_select.vue
  5. 32
      src/components/kv_line.vue
  6. 11
      src/pages.json
  7. 110
      src/subpackage/shower/pages/card/manage.vue

92
src/components/filter/filter_modal.vue

@ -0,0 +1,92 @@
<template>
<view class="filter-modal" v-show="visibled" @click="hide">
<scroll-view class="fm-container" scroll-y @click.stop="_=>false">
<view class="fc-title">{{ title }}</view>
<view class="fc-list">
<view
class="fl-item"
:class="{ active: curValue === e.value }"
v-for="(e, i) in list"
:key="i"
@click="itemClick(e)"
>{{ e.label }}</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data(){
return {
visibled: false,
title: '',
list: [],
curValue: '',
initOption: {
// success,
}
}
},
methods: {
show(){
this.visibled = true;
},
hide(){
this.visibled = false;
},
init(e){
this.title = e.title;
this.list = e.list;
this.curValue = e.curValue;
this.initOption = e;
this.show();
},
itemClick(e){
this.initOption?.success?.(e);
this.hide();
}
}
}
</script>
<style lang="scss">
.filter-modal{
position: fixed;
left: 0;
top: var(--window-top);
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .5);
z-index: 10;
.fm-container{
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 500upx;
height: 100%;
padding-left: 42upx;
background-color: #fff;
padding-top: 26upx;
padding-left: 42upx;
padding-bottom: 40upx;
.fc-title{
margin-bottom: 58upx;
padding: 50upx 0;
border-bottom: 2upx solid #D8D8D8;
@include flcw(24upx, 34upx, #9c9c9f);
}
.fc-list{
.fl-item{
margin-bottom: 50upx;
@include tHide;
@include flcw(32upx, 44upx, #1a1a1a);
&.active{
color: $mColor;
}
}
}
}
}
</style>

107
src/components/filter/header.vue

@ -0,0 +1,107 @@
<template>
<view class="order-list-header">
<!-- 门店选择 -->
<stadium-select
ref="stadiumSelect"
:visibled="isStadium"
@change:stadium="$emit('change:stadium', $event)"
></stadium-select>
<!-- 时间段 -->
<view class="olh-period">
<view class="op-txt" @click="$emit('click:time')">{{ startTime || '' }} ~ {{ endTime || '' }}</view>
<view class="op-icon" @click="$emit('click:time')"></view>
</view>
<!-- 交易明细&按钮 -->
<view class="olh-bot">
<view class="ob-desc">
<text v-if="isCount">成功交易{{ successCount || 0 }}退款{{ refundCount || 0 }}</text>
</view>
<view class="ob-btns">
<image @click="$emit('click:search')" class="ob-icon" src="/static/images/icon/search.png"></image>
<image @click="$emit('click:filter')" class="ob-icon" src="/static/images/icon/filter.png"></image>
</view>
</view>
</view>
</template>
<script>
import stadiumSelect from './stadium_select.vue';
export default {
components: {
'stadium-select': stadiumSelect,
},
props: {
startTime: {
default: ''
},
endTime: {
default: ''
},
successCount: {
default: 0
},
refundCount: {
default: 0
},
isCount: Boolean
},
data(){
return {
isStadium: false
}
},
methods: {
initStadiumSelect(brand_id){
this.isStadium = !!brand_id;
return this.$refs.stadiumSelect.getStadiumList(brand_id);
},
showPeriodModal(e){
this.$refs.periodModal.show(e);
},
periodConfirm(e){
console.log('periodConfirm:', e)
}
}
}
</script>
<style lang="scss">
.order-list-header{
.olh-period{
padding: 24upx 24upx 0upx;
@include ctf(flex-start);
.op-txt{
@include flcw(32upx, 44upx, #1a1a1a, 500);
@include tHide(1);
}
.op-icon{
flex-shrink: 0;
margin-left: 14upx;
width: 0;
height: 0;
border-left: 10upx solid transparent;
border-right: 10upx solid transparent;
border-top: 10upx solid #1a1a1a;
}
}
.olh-bot{
padding: 16upx 24upx;
@include ctf(space-between);
.ob-desc{
flex-grow: 1;
@include flcw(24upx, 34upx, #9c9c9f);
@include tHide(1);
}
.ob-btns{
flex-shrink: 0;
@include ctf(flex-end);
.ob-icon{
flex-shrink: 0;
margin-left: 40upx;
width: 40upx;
height: 40upx;
}
}
}
}
</style>

139
src/components/filter/period_modal.vue

@ -0,0 +1,139 @@
<template>
<view class="period-modal" v-show="visibled" @click="hide">
<view class="pm-period" @click.stop="()=>false">
<view class="pp-tit">日期范围</view>
<picker class="pp-picker" mode="date" @change="startTimeChange" :value="start">
<view class="pp-time">
<text class="pt-txt">开始时间</text>
<view class="pt-right">
<input class="pr-ipt" placeholder="选择时间" disabled :value="start" />
<image class="pr-img" mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image>
</view>
</view>
</picker>
<picker class="pp-picker" mode="date" @change="endTimeChange" :value="end">
<view class="pp-time">
<text class="pt-txt">截止时间</text>
<view class="pt-right">
<input class="pr-ipt" placeholder="选择时间" disabled :value="end" />
<image class="pr-img" mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image>
</view>
</view>
</picker>
<view class="pl-btn active" @click="confirmPeriod">确定</view>
</view>
</view>
</template>
<script>
import { showNone } from '@/utils/util';
export default {
data(){
return {
start: '',
end: '',
visibled: false,
initOption: {
// success,
}
}
},
methods: {
init(e){
this.start = e.start;
this.end = e.end;
this.initOption = e;
this.show();
},
show(){
this.visibled = true;
},
hide(){
this.visibled = false;
},
startTimeChange(e){
this.start = e.detail.value;
},
endTimeChange(e){
this.end = e.detail.value;
},
confirmPeriod(){
let { start, end, initOption } = this;
if(!start || !end)return showNone('请选择日期范围!');
if(
new Date(start.replace(/\-/g,'/')).getTime()
> new Date(end.replace(/\-/g,'/')).getTime()
)return showNone('请选择合理时间!');
this.hide();
initOption?.success?.({ start, end });
this.$emit('click:cofirm', { start, end });
}
}
}
</script>
<style lang="scss">
.period-modal{
position: fixed;
left: 0;
top: var(--window-top);
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .5);
z-index: 10;
.pm-period{
position: absolute;
left: 0;
top: 0;
padding-left: 38upx;
padding-top: 66upx;
height: 472upx;
width: 100%;
background-color: #fff;
.pp-tit{
@include flcw(24upx, 34upx, #9c9c9f);
}
.pp-picker{
width: 100%;
}
.pp-time{
padding-right: 40upx;
height: 124upx;
border-bottom: 2upx solid #D8D8D8;
@include ctf(space-between);
.pt-txt{
flex-shrink: 0;
@include flcw(32upx, 44upx, #1a1a1a);
}
.pt-right{
flex-grow: 1;
@include ctf(flex-end);
.pr-ipt{
flex-grow: 1;
height: 100%;
text-align: right;
@include flcw(32upx, 44upx, #1a1a1a);
}
.pr-img{
flex-shrink: 0;
margin-left: 36upx;
width: 28upx;
height: 28upx;
}
}
}
.pl-btn{
text-align: center;
@include flcw(32upx, 124upx, rgba(0, 152, 116, .2), 500);
color: rgba(0, 152, 116, .2);
&.active{
color: $mColor;
}
}
}
}
</style>

101
src/components/filter/stadium_select.vue

@ -0,0 +1,101 @@
<template>
<view class="stadium-select" v-show="visibled">
<text class="ss-txt">当前门店</text>
<picker mode="selector" class="ss-picker" :range="stadiumList" range-key="name" @change="pickerChange">
<view class="ss-frame">
<input type="text" disabled class="sf-ipt" :value="curStadium.name || ''" placeholder="全部"/>
<image class="sf-img" mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image>
</view>
</picker>
</view>
</template>
<script>
import { API } from '../../js/api';
import { servers } from '../../js/server';
export default {
props: {
visibled: {
type: Boolean,
default: false
}
},
data(){
return {
stadiumList: [
{ id: '', name: '全部' }
],
curStadium: {}
}
},
methods: {
pickerChange(e){
let { value } = e.detail;
let { stadiumList } = this;
this.curStadium = stadiumList[value];
this.$emit('change:stadium', this.curStadium);
},
//
getStadiumList(brand_id){
return servers.get({
url: API.stadiumList,
data: { brand_id },
isDefaultGet: false
})
.then(res=>{
let _data = res?.data || {};
if(_data.code === 0){
let _list = _data?.data?.list || [];
return this.stadiumList = [ ...this.stadiumList, ..._list ];
}else{
console.warn('getStoreList err:', err);
return this.stadiumList;
}
})
.catch(err=>{
console.warn('getStoreList err:', err);
return this.stadiumList;
})
},
}
}
</script>
<style lang="scss">
.stadium-select{
padding: 0 24upx;
height: 144upx;
background-color: #fff;
@include ctf(space-between);
.ss-txt{
margin-right: 20upx;
flex-shrink: 0;
@include flcw(28upx, 40upx, #9c9c9f);
}
.ss-picker{
flex-grow: 1;
.ss-frame{
padding: 0 20upx;
height: 92upx;
border-radius: 10upx;
background-color: #F2F2F7;
@include ctf(space-between);
.sf-ipt{
flex-grow: 1;
@include flcw(28upx, 40upx, #1a1a1a);
@include tHide(1);
}
.sf-img{
margin-left: 10upx;
flex-shrink: 0;
width: 28upx;
height: 28upx;
transform: rotateZ(90deg);
}
}
}
.ocs-store{
}
}
</style>

32
src/components/kv_line.vue

@ -0,0 +1,32 @@
<template>
<view class="kv-line">
<view class="kl-name">{{ label || '' }}</view>
<view class="kl-val"><slot name="default">value</slot></view>
<slot name="right"></slot>
</view>
</template>
<script>
export default {
props: {
label: {
type: String,
default: ''
},
}
}
</script>
<style lang="scss">
.kv-line{
@include ctf;
.kl-name{
flex-shrink: 0;
@include flcw(28upx, 48upx, #9C9C9F);
}
.kl-val{
@include flcw(28upx, 48upx, #1A1A1A);
@include tHide;
}
}
</style>

11
src/pages.json

@ -889,6 +889,17 @@
} }
} }
] ]
},
{
"root": "subpackage/shower",
"pages": [
{
"path": "pages/card/manage",
"style" : {
"navigationBarTitleText": "水阀卡管理"
}
}
]
} }
], ],
"globalStyle": { "globalStyle": {

110
src/subpackage/shower/pages/card/manage.vue

@ -0,0 +1,110 @@
<template>
<view class="card-manage">
<order-filter
ref="orderFilter"
@click:time="showPeriodModal"
@click:filter="showFilterModal"
:start-time="condition.start_time"
:end-time="condition.end_time"
></order-filter>
<view class="cm-list">
<view class="cl-item" v-for="(e, i) in 10" :key="i">
<view class="ci-bar">
<view class="cb-name">欧轩智能羽毛球馆(永泰店)</view>
<view class="cb-status">使用中</view>
</view>
<view class="ci-lines">
<kv-line label="卡名称:">智能浴室用水卡</kv-line>
<kv-line label="水阀卡号:">20195171564566</kv-line>
<kv-line label="手机号码:">18316553478</kv-line>
<kv-line label="微信昵称:">yiming</kv-line>
<kv-line label="可用时长:"><text class="cl-txt">100分00秒</text></kv-line>
</view>
</view>
</view>
<!-- 时间段选择 -->
<period-modal ref="periodModal"></period-modal>
<!-- status窗口 -->
<filter-modal ref="filterModal"></filter-modal>
</view>
</template>
<script>
import orderFilter from "@/components/filter/header.vue";
import periodModal from "@/components/filter/period_modal.vue";
import filterModal from "@/components/filter/filter_modal.vue";
import kv_line from "@/components/kv_line.vue";
export default {
components: {
'order-filter': orderFilter,
'period-modal': periodModal,
'filter-modal': filterModal,
'kv-line': kv_line
},
data(){
return {
condition: {
start_time: '2024-08-20',
end_time: '2024-08-20',
}
}
},
onLoad(options){
this.$refs.orderFilter.initStadiumSelect(options?.brand_id);
},
methods: {
showPeriodModal(){
let { start_time, end_time } = this.condition;
this.$refs.periodModal.init({
start: start_time,
end: end_time,
success: res=>{
this.condition.start_time = res.start;
this.condition.end_time = res.end;
}
});
},
showFilterModal(){
this.$refs.filterModal.show();
}
}
}
</script>
<style lang="scss">
.cm-list{
padding: 24upx;
@include isPd(24upx);
.cl-item{
padding: 0upx 20upx 30upx;
border-radius: 10upx;
background: #fff;
.ci-bar{
padding: 30upx 0upx;
border-bottom: 1upx solid #D8D8D8;
@include ctf(space-between);
.cb-name{
@include flcw(28upx, 40upx, #1A1A1A, 500);
@include tHide;
}
.cb-status{
flex-shrink: 0;
max-width: 30%;
@include tHide;
@include flcw(28upx, 40upx, $mColor);
}
}
.ci-lines{
padding-top: 20upx;
.cl-txt{
color: #FF873D;
}
}
&+.cl-item{
margin-top: 24upx;
}
}
}
</style>
Loading…
Cancel
Save