362 lines
7.2 KiB
Vue
362 lines
7.2 KiB
Vue
<template>
|
||
<view class="uni-stat--tab-x">
|
||
<view v-if="label" class="uni-label-text hide-on-phone">{{label + ':'}}</view>
|
||
<view class="uni-stat--tab">
|
||
<view v-if="!renderTabs.length" class="uni-stat--tab-item uni-stat--tab-item-disabled"
|
||
:class="[`uni-stat--tab-item-${type}`]">
|
||
{{placeholder}}
|
||
</view>
|
||
<view v-else v-for="(item, index) in renderTabs" :key="index" @click="change(item, index)"
|
||
class="uni-stat--tab-item" :class="[
|
||
index === currentTab ? `uni-stat--tab-item-${type}-active` : '' , `uni-stat--tab-item-${type}`,
|
||
item.disabled ? 'uni-stat--tab-item-disabled' : ''
|
||
]">
|
||
<!-- #ifdef MP -->
|
||
{{item.name}}
|
||
<!-- #endif -->
|
||
<!-- #ifndef MP -->
|
||
<uni-tooltip>
|
||
{{item.name}}
|
||
<uni-icons v-if="item.tooltip" type="help" color="#666" />
|
||
<template v-if="item.tooltip" v-slot:content>
|
||
<view class="uni-stat-tooltip-s">
|
||
{{item.tooltip}}
|
||
</view>
|
||
</template>
|
||
</uni-tooltip>
|
||
<!-- #endif -->
|
||
</view>
|
||
|
||
</view>
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: "uni-stat-tabs",
|
||
data() {
|
||
return {
|
||
currentTab: 0,
|
||
renderTabs: [],
|
||
cacheKey: "uni-admin-statTabsData"
|
||
};
|
||
},
|
||
props: {
|
||
type: {
|
||
type: String,
|
||
default: 'line'
|
||
},
|
||
value: {
|
||
type: [String, Number],
|
||
default: ''
|
||
},
|
||
modelValue: {
|
||
type: [String, Number],
|
||
default: ''
|
||
},
|
||
current: {
|
||
type: [String, Number],
|
||
default: 0
|
||
},
|
||
mode: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
today: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
yesterday: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
disabled: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
tooltip: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
all: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
label: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
placeholder: {
|
||
type: String,
|
||
default: '暂无选项'
|
||
},
|
||
tabs: {
|
||
type: Array,
|
||
default: () => {
|
||
return []
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
this.last = `${this.mode.replace('-', '_')}_last_data`
|
||
},
|
||
mounted() {
|
||
this.init()
|
||
},
|
||
computed:{
|
||
|
||
},
|
||
watch: {
|
||
current: {
|
||
immediate: true,
|
||
handler(val) {
|
||
this.currentTab = val
|
||
}
|
||
},
|
||
|
||
// value(val) {
|
||
// this.currentTab = val
|
||
// },
|
||
|
||
tabs: {
|
||
immediate: false,
|
||
handler(val) {
|
||
this.init()
|
||
}
|
||
},
|
||
|
||
renderTabs(val) {
|
||
const index = this.current
|
||
if (this.mode && val.length && index >= 0) {
|
||
this.$nextTick(function() {
|
||
const item = this.renderTabs[index]
|
||
this.change(item, index)
|
||
})
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
init() {
|
||
if (this.mode.indexOf('platform') > -1) {
|
||
this.renderTabs = this.getCache() || [];
|
||
this.getPlatform()
|
||
} else if (this.mode === 'date') {
|
||
const dates = [{
|
||
_id: 7,
|
||
name: '最近七天',
|
||
}, {
|
||
_id: 30,
|
||
name: '最近30天',
|
||
}, {
|
||
_id: 90,
|
||
name: '最近90天',
|
||
}]
|
||
if (this.yesterday) {
|
||
dates.unshift({
|
||
_id: 1,
|
||
name: '昨天',
|
||
})
|
||
}
|
||
if (this.today) {
|
||
dates.unshift({
|
||
_id: 0,
|
||
name: '今天',
|
||
})
|
||
}
|
||
this.renderTabs = dates
|
||
} else {
|
||
this.renderTabs = this.tabs
|
||
}
|
||
},
|
||
change(item, index) {
|
||
if (item.disabled) return
|
||
const id = item._id
|
||
const name = item.name
|
||
this.currentTab = index
|
||
this.emit(id, index, name, item)
|
||
},
|
||
emit(id, index, name, item) {
|
||
this.$emit('change', id, index, name, item)
|
||
this.$emit('input', id, index, name)
|
||
this.$emit('update:modelValue', id, index, name)
|
||
},
|
||
getPlatform() {
|
||
const db = uniCloud.database()
|
||
const appList = db.collection('uni-stat-app-platforms')
|
||
.get()
|
||
.then(res => {
|
||
let platforms = res.result.data
|
||
platforms = platforms.filter(p => p.hasOwnProperty('enable') ? p.enable : true)
|
||
platforms.sort((a, b) => a.order - b.order)
|
||
if (this.mode === 'platform-channel') {
|
||
platforms = platforms.filter(item => /^android|ios$/.test(item.code))
|
||
let _id = platforms.map(p => `platform_id == "${p._id}"`).join(' || ')
|
||
_id = `(${_id})`
|
||
this.setAllItem(platforms, _id)
|
||
} else if (this.mode === 'platform-scene') {
|
||
platforms = platforms.filter(item => /mp-/.test(item.code))
|
||
let _id = platforms.map(p => `platform_id == "${p._id}"`).join(' || ')
|
||
_id = `(${_id})`
|
||
this.setAllItem(platforms, _id)
|
||
} else {
|
||
this.setAllItem(platforms)
|
||
}
|
||
this.setCache(platforms);
|
||
this.renderTabs = platforms
|
||
})
|
||
},
|
||
setAllItem(platforms, _id = '', name = '全部') {
|
||
this.all && platforms.unshift({
|
||
name,
|
||
_id
|
||
})
|
||
},
|
||
// 获取当前缓存key
|
||
getCurrentCacheKey(){
|
||
return this.mode;
|
||
},
|
||
// 获取缓存
|
||
getCache(name=this.getCurrentCacheKey()){
|
||
let cacheData = uni.getStorageSync(this.cacheKey) || {};
|
||
return cacheData[name];
|
||
},
|
||
// 设置缓存
|
||
setCache(value, name=this.getCurrentCacheKey()){
|
||
let cacheData = uni.getStorageSync(this.cacheKey) || {};
|
||
cacheData[name] = value;
|
||
uni.setStorageSync(this.cacheKey, cacheData);
|
||
},
|
||
// 删除缓存
|
||
removeCache(name=this.getCurrentCacheKey()){
|
||
let cacheData = uni.getStorageSync(this.cacheKey) || {};
|
||
delete cacheData[name];
|
||
uni.setStorageSync(this.cacheKey, cacheData);
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.uni-stat-tooltip-s {
|
||
width: 160px;
|
||
white-space: normal;
|
||
}
|
||
|
||
.uni-label-text {
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
color: #555;
|
||
margin-top: 17px;
|
||
margin-bottom: 17px;
|
||
margin-right: 5px;
|
||
// display: flex;
|
||
// align-items: center;
|
||
// justify-content: center;
|
||
}
|
||
|
||
.uni-stat--tab-x {
|
||
display: flex;
|
||
margin: 0 15px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.uni-stat--tab {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.uni-stat {
|
||
|
||
&--tab {
|
||
|
||
&-item {
|
||
white-space: nowrap;
|
||
font-size: 14px;
|
||
color: #666;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
box-sizing: border-box;
|
||
margin: 15px 0;
|
||
|
||
&-disabled {
|
||
cursor: unset;
|
||
opacity: 0.4;
|
||
}
|
||
|
||
&-line {
|
||
margin-right: 30px;
|
||
padding: 2px 0;
|
||
border-bottom: 1px solid transparent;
|
||
|
||
&:last-child {
|
||
margin-right: 0;
|
||
}
|
||
|
||
&-active {
|
||
color: $uni-color-primary;
|
||
border-bottom: 1px solid $uni-color-primary;
|
||
// &-disabled {
|
||
// color: #666;
|
||
// border-color: #666;
|
||
// }
|
||
}
|
||
}
|
||
|
||
&-boldLine {
|
||
box-sizing: border-box;
|
||
margin-right: 30px;
|
||
padding: 2px 0;
|
||
border-bottom: 2px solid transparent;
|
||
|
||
&:last-child {
|
||
margin-right: 0;
|
||
}
|
||
|
||
&-active {
|
||
box-sizing: border-box;
|
||
color: $uni-color-primary;
|
||
border-bottom: 2px solid $uni-color-primary;
|
||
}
|
||
}
|
||
|
||
&-box {
|
||
padding: 5px 15px;
|
||
border: 1px solid #dcdfe6;
|
||
// margin: 0;
|
||
|
||
&:not(:last-child) {
|
||
border-right-color: transparent;
|
||
}
|
||
|
||
|
||
&-active {
|
||
box-sizing: border-box;
|
||
border: 1px solid $uni-color-primary !important;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
/* #ifndef APP-NVUE */
|
||
@media screen and (max-width: 500px) {
|
||
.hide-on-phone {
|
||
display: none;
|
||
}
|
||
|
||
.uni-stat--tab {
|
||
flex-wrap: unset;
|
||
overflow-x: auto !important;
|
||
}
|
||
/* #ifdef H5 */
|
||
::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
/* #endif */
|
||
}
|
||
|
||
/* #endif */
|
||
</style>
|