新增vuex状态管理

master
chen 2022-04-07 18:14:28 +08:00
parent 6474f606f4
commit 9ec15c0272
26 changed files with 1301 additions and 1003 deletions

View File

@ -20,7 +20,7 @@
// #endif
},
onShow: function() {
if(uni.getStorageSync('phone_active')){
if(uni.getStorageSync('token')){
// token
this.$toolAll.tools.refreshToken();
}

View File

@ -0,0 +1,295 @@
<template>
<view class="datetime-picker">
<view class="mask" :class="{ show: open }" @touchmove.stop.prevent catchtouchmove="true"></view>
<view class="wrap" :class="{ show: open }">
<view class="picker-header" @touchmove.stop.prevent catchtouchmove="true">
<view class="btn-picker cancel" @click="open = false">取消</view>
<view class="btn-picker submit" @click="_onSubmit"></view>
</view>
<view class="picker-body">
<picker-view :value="value" @change="_onChange">
<picker-view-column>
<view class="column-item" v-for="item in years" :key="item">
{{ item + "年" }}
</view>
</picker-view-column>
<picker-view-column>
<view class="column-item" v-for="item in months" :key="item">
{{ formatNum(item) + "月" }}
</view>
</picker-view-column>
<picker-view-column>
<view class="column-item" v-for="item in days" :key="item">
{{ formatNum(item) + "日" }}
</view>
</picker-view-column>
<picker-view-column>
<view class="column-item" v-for="item in hours" :key="item">
{{ formatNum(item) + "时" }}
</view>
</picker-view-column>
<picker-view-column>
<view class="column-item" v-for="item in minutes" :key="item">
{{ formatNum(item) + "分" }}
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "buuug7-simple-datetime-picker",
props: {
startYear: {
type: Number,
default: 2000,
},
endYear: {
type: Number,
default: 2030,
},
},
data() {
return {
open: false,
years: [],
months: [],
days: [],
hours: [],
minutes: [],
currentDate: new Date(),
year: "",
month: "",
day: "",
hour: "",
minute: "",
value: [0, 0, 0, 0, 0],
};
},
mounted() {
this.init();
},
watch: {
month() {
this.initDays();
},
},
methods: {
init() {
this.initYears();
this.initMonths();
this.initDays();
this.initHours();
this.initMinutes();
this.setSelectValue();
},
initYears() {
const years = [];
for (let year = this.startYear; year <= this.endYear; year++) {
years.push(year);
if (this.currentDate.getFullYear() === year) {
this.$set(this.value, 0, year - this.startYear);
}
}
this.years = years;
},
initMonths() {
const months = [];
for (let month = 1; month <= 12; month++) {
months.push(month);
if (this.currentDate.getMonth() + 1 === month) {
this.$set(this.value, 1, month - 1);
}
}
this.months = months;
},
initDays() {
const value = this.value;
const selectedYear = this.years[value[0]];
const selectedMonth = this.months[value[1]];
const days = [];
const totalDays = new Date(selectedYear, selectedMonth, 0).getDate();
for (let day = 1; day <= totalDays; day++) {
days.push(day);
if (this.currentDate.getDate() === day) {
this.$set(value, 2, day - 1);
}
}
this.days = days;
},
initHours() {
const hours = [];
for (let hour = 0; hour <= 23; hour++) {
hours.push(hour);
if (this.currentDate.getHours() === hour) {
this.$set(this.value, 3, hour);
}
}
this.hours = hours;
},
initMinutes() {
const minutes = [];
for (let minute = 0; minute < 60; minute++) {
minutes.push(minute);
if (this.currentDate.getMinutes() === minute) {
this.$set(this.value, 4, minute);
}
}
this.minutes = minutes;
},
show() {
this.open = true;
},
hide() {
this.open = false;
},
_onChange(e) {
this.value = e.detail.value;
this.setSelectValue();
},
setSelectValue() {
const v = this.value;
this.year = this.years[v[0]];
this.month = this.months[v[1]];
this.day = this.days[v[2]];
this.hour = this.hours[v[3]];
this.minute = this.minutes[v[4]];
},
_onSubmit() {
const {
year,
month,
day,
hour,
minute,
formatNum
} = this;
const result = {
year: formatNum(year),
month: formatNum(month),
day: formatNum(day),
hour: formatNum(hour),
minute: formatNum(minute),
};
this.$emit("submit", result);
this.hide();
},
formatNum(num) {
return num < 10 ? "0" + num : num + "";
},
},
};
</script>
<style lang="scss">
$transition: all 0.3s ease;
$primary: #488ee9;
.datetime-picker {
position: relative;
z-index: 999;
picker-view {
height: 100%;
}
.mask {
position: fixed;
z-index: 1000;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.6);
visibility: hidden;
opacity: 0;
transition: $transition;
&.show {
visibility: visible;
opacity: 1;
}
}
.wrap {
z-index: 1001;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
transition: $transition;
transform: translateY(100%);
&.show {
transform: translateY(0);
}
}
.picker-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 8px 8px;
background-color: darken(#fff, 2%);
background-color: #fff;
}
.picker-body {
width: 100%;
height: 420rpx;
overflow: hidden;
background-color: #fff;
}
.column-item {
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
justify-content: center;
align-items: center;
}
.btn-picker {
position: relative;
display: inline-block;
padding-left: 10px;
padding-right: 10px;
box-sizing: border-box;
text-align: center;
text-decoration: none;
line-height: 2;
-webkit-tap-highlight-color: transparent;
overflow: hidden;
background-color: #eee;
font-size: 14px;
// border-radius: 2px;
color: #000;
cursor: pointer;
}
.btn-picker.submit {
background-color: $primary;
color: #fff;
}
}
</style>

View File

@ -1,75 +0,0 @@
<template>
<view id="main-img">
<!-- <view class="mar-x40" v-for="(item,index) in list" :key="index"> -->
<!-- 活动商品 start -->
<view v-for="(item,index) in activityList" :key="index" class="mar-x50">
<h1 class="fon36 bold">{{item.name}}</h1>
<view class="colpeili fon26 mar-s20 mar-x40 clips1">{{item.subtitle}}</view>
<view class="posir" @tap="goDetail(item.id)">
<image class="radius30 animated fadeIn" :src="item.cover" mode="aspectFill" lazy-load style="height: 425rpx;width: 100%;" :style="{height:activityHeight + 'px'}"></image>
<view v-if="item.tag!=''" class="posia fon24 colf pad-zy10 pad-s10 pad-x20 activity-img"></view>
</view>
</view>
<!-- 活动商品 end -->
<!-- 子商品 start -->
<view class="disjbac fw">
<view @tap="goDetail(item.id)" class="width47 mar-x50 posir" v-for="(item,index) in list" :key="index">
<image :src="item.cover" mode="aspectFill" lazy-load style="width: 100%;height: 312rpx;border-radius: 30rpx;"></image>
<view class="clips2 fon30 col0 linh50" style="height: 100rpx;">{{item.name}}</view>
<view class="fon30 colpeili">{{item.price}}</view>
<view v-if="item.tag!=''" class="posia fon24 colf pad-zy10 pad-s10 pad-x20 activity-img"></view>
</view>
</view>
<!-- 子商品 end -->
<!-- </view> -->
</view>
</template>
<script>
export default {
name:"list-one",
props:{
list:{
type:Array,
default:()=>{
return []
}
},
activityList:{
type:Array,
default:()=>{
return []
}
}
},
data() {
return {
check:uni.getStorageSync('is_active'),
activityHeight:''
};
},
mounted() {
uni.createSelectorQuery().in(this).select('#main-img').boundingClientRect().exec(rect => {
this.activityHeight = rect[0].width;
console.log(this.activityHeight,55);
});
},
methods:{
goDetail(id){//
if(this.check){
uni.navigateTo({
url:`/pagesB/shopDetail/shopDetail?id=${id}`
})
} else {
uni.navigateTo({
url:`/pages/login/login`
})
}
}
}
}
</script>
<style>
</style>

View File

@ -1,163 +0,0 @@
<template>
<scroll-view scroll-y @scrolltolower="scrollBottomEv" :style="{height: scrollHeight +'px'}">
<view class="disjbac fw">
<view @tap="goDetail(item.id)" class="width48_5 mar-x50 posir" v-for="(item,index) in dataList" :key="index">
<image class="animated fadeIn" :src="item.imgSrc" mode="aspectFill" style="width: 100%;height: 312rpx;border-radius: 30rpx;"></image>
<view class="clips2 fon30 col0 linh50" style="height: 100rpx;">{{item.title}}</view>
<view class="fon30 colpeili">{{item.price}}</view>
<view v-if="item.isActivity" class="posia fon24 colf pad-zy10 pad-s10 pad-x20 activity-img"></view>
</view>
</view>
<!-- 暂无更多数据 -->
<pitera v-if="showpitera"></pitera>
</scroll-view>
</template>
<script>
//
import pitera from '@/components/nothing/pitera.vue';
export default {
name:"list-two",
components:{
pitera
},
props:{
//
scrollCate:{
type:Number,
default:1
},
//
pageSource: {
type:Number,
default:1
}
},
data() {
return {
scrollHeight:uni.getStorageSync('scrollHeight'),
//
dataList:[
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选1的宝',
price:'2,000',
isActivity:true,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选1的宝石级钻石每年开采数级钻石每年开采数',
price:'2,000',
isActivity:false,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选',
price:'2,000',
isActivity:false,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选',
price:'2,000',
isActivity:true,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选',
price:'2,000',
isActivity:false,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选1的宝石级钻石每年开采数',
price:'2,000',
isActivity:false,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选1的宝石级钻石每年开采数的宝石级钻石每年开采数',
price:'2,000',
isActivity:false,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选',
price:'2,000',
isActivity:false,
},
{
id:1,
imgSrc:'https://s6.jpg.cm/2022/02/14/L4oDhy.jpg',
title:'于亿年宝藏中臻选1的宝石级钻石每年开采数的宝石级钻石每年开采数',
price:'2,000',
isActivity:false,
}
],
page:1, //
size:10, //
total:0, //
showpitera:true, //
};
},
mounted() {
switch (this.scrollCate){
case 1:
this.scrollHeight = uni.getStorageSync('scrollHeight-one'); // App.vue
break;
case 2:
this.scrollHeight = uni.getStorageSync('scrollHeight-two'); // App.vue
break;
case 3:
this.scrollHeight = uni.getStorageSync('scrollHeight-three'); // App.vue
break;
case 4:
this.scrollHeight = uni.getStorageSync('scrollHeight-four'); // App.vue
break;
}
switch (this.pageSource){
case 1:
this.checkList();
break;
}
},
methods:{
checkList(){
console.log('列表事件')
},
//
scrollBottomEv(){
console.log('触底了',55)
//
if(this.total!=this.dataList.length){
// +1
this.page++
switch (this.pageSource){
case 1:
// this.checkList();//
break;
}
} else {
//
this.pitera = true;
}
},
goDetail(id){//
uni.navigateTo({
url:`/pagesB/shopDetail/shopDetail?id=${id}`
})
}
}
}
</script>
<style>
</style>

View File

@ -1,61 +0,0 @@
<template>
<text :style="{ color: color, 'font-size': size + 'rpx' }" :class="{isTheme:isTheme}" class="lw-icons"
@click="_onClick">{{icons[icon]}}</text>
</template>
<script>
import icons from './icons.js';
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
domModule.addRule('fontFace', {
'fontFamily': 'iconfont',
'src': 'url(\'https://at.alicdn.com/t/font_2294175_vq7ymlkpbtm.ttf\')',
});
// #endif
export default {
name: 'UniIcons',
props: {
icon: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 50
},
isTheme: {
type: Boolean,
default: false
}
},
data() {
return {
icons: icons
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" scoped>
/* #ifndef APP-NVUE */
@font-face {
font-family: iconfont;
src: url('https://at.alicdn.com/t/font_2294175_vq7ymlkpbtm.ttf')
}
/* #endif */
.lw-icons {
font-family: iconfont;
text-decoration: none;
text-align: center;
}
</style>

View File

@ -1,6 +0,0 @@
export default {
'aixin':'\ue8ab',
'rules':'\ue909',
'sound':'\ue8ea',
'arrowright':'\uee02'
}

View File

@ -1,373 +0,0 @@
<template>
<view>
<view class="contentBox" v-if="list.length" @click="toEmit()"
:style="'color:' + color + ';background-color:' + backgroundColor + ';height:' + height+'rpx;'">
<view v-if="showIcon" class="supBox">
<lwIcon :size="32" :color="iconColor" icon="sound"></lwIcon>
</view>
<view v-if="list.length > 1" class="content">
<view v-for="(item, index) in list" :key="index" @tap.stop="dangGao(index)">
<view class="loopItemBase" :class="index==0&&firstIn?'fistInClass':''"
:animation="realAnimation(index)" v-if="aindexArr.includes(index)"
:style="'line-height:'+height+'rpx;'">
{{ item }}
</view>
</view>
</view>
<view v-if="list.length == 1" class="content">
<view :style="'line-height:'+height+'rpx;'" @tap.stop="dangGao(0)" class="loopItemBaseShow">{{ list[0] }}</view>
</view>
<view v-if="showMore" class="offBox">
<lwIcon :size="32" :color="moreColor" icon="arrowright"></lwIcon>
</view>
</view>
</view>
</template>
<script>
/*
lw-notice公告上下轮询组件组件内依赖了自有的字体图标组件可自行替换为uni或自身项目的图标组件
color:字体颜色
backgroundColor:背景色
list:要循环的列表数据
height:组件高度
showScale:是否有缩放动画
runTime:间隔切换时间
showIcon:是否显示头部小喇叭
iconColor:小喇叭的颜色
showMore:是否显示尾部更多
moreColor:显示更多的颜色
*/
import lwIcon from './iconFont.vue'
export default {
components: {
lwIcon
},
props: {
color: {
type: String,
default: '#666666'
},
backgroundColor: {
type: String,
default: '#f5f5f5'
},
list: {
type: Array,
default: function(){
return []
}
},
height: {
type: Number,
default: 40
},
showScale: {
type: Boolean,
default: false
},
runTime: {
type: Number,
default: 4000
},
showIcon: {
type: Boolean,
default: false
},
showMore: {
type: Boolean,
default: false
},
iconColor: {
type: String,
default: '#aaaaaa'
},
moreColor: {
type: String,
default: '#aaaaaa'
}
},
data() {
return {
//
firstIn: true,
//
aindexArr: [],
//
animation: null,
//
animationData: null,
//
animationDataTwo: null,
//
indexLinkAnimationObj: {},
setTimerOne: null,
setTimerTwo: null,
setTimerThree: null,
setTimerFour: null,
setTimerFive: null
};
},
beforeDestroy() {
this.resetPage()
},
computed: {
//
realAnimation() {
return function(value) {
if (this.indexLinkAnimationObj[value]) {
return this[this.indexLinkAnimationObj[value]]
} else {
return {}
}
}
}
},
methods: {
// 3000
// 1.a 1 1 0ms
// 2.b 2 2 200ms
// 3.a 1 1 300ms
// 4.c 1 1 400ms
// 5.b 2 2 500ms
// 6.a 2 2 600ms
// 7.c 1 1 700ms
// 8.b 1 1 800ms
// 9.a 2 2 900ms
// 10.c 2 2 1000ms
initPage() {
this.resetPage();
if (this.list && this.list.length) {
if (this.list.length > 1) {
this.aindexArr.push(0);
this.animation = uni.createAnimation({
timingFunction: 'linear',
})
// #ifdef H5
this.animationDataH5 = this.animation.translateY(-100).step({
duration: 10000
}).export()
// #endif
this.runAnimation(0, true);
}
}
},
//
resetPage() {
//
clearTimeout(this.setTimerOne);
clearTimeout(this.setTimerTwo);
clearTimeout(this.setTimerThree);
clearTimeout(this.setTimerFour);
clearTimeout(this.setTimerFive);
//
this.aindexArr = [];
this.animation = null;
this.animationData = null;
this.animationDataTwo = null;
this.indexLinkAnimationObj = {};
},
// ()
runAnimation(value, firstIn) {
let that = this;
if (!firstIn) {
that.aindexArr.push(value);
}
//
let lockText = that.createAni(firstIn);
// 50(dom)
that.setTimerOne = setTimeout(() => {
//
that.indexLinkAnimationObj[value] = lockText;
// console.log('')
// console.log(that.indexLinkAnimationObj)
//
let unitRunTime = (that.runTime - 50) / 6;
let waitTime = firstIn ? unitRunTime * 4 : unitRunTime * 5;
let waitTimeTwo = firstIn ? (that.runTime - unitRunTime) : that.runTime;
// #ifdef H5
waitTimeTwo = firstIn ? (that.runTime - (1.5 * unitRunTime)) : that.runTime;
//H5
if (firstIn) {
that.aindexArr.splice(0, 1);
that.aindexArr.push(0);
}
// #endif
//
that.setTimerTwo = setTimeout(() => {
let Index = value == that.list.length - 1 ? 0 : value + 1;
that.runAnimation(Index)
}, waitTime)
//
that.setTimerThree = setTimeout(() => {
let index = that.aindexArr.indexOf(value);
that.aindexArr.splice(index, 1)
that.firstIn = false;
delete that.indexLinkAnimationObj[value]
}, waitTimeTwo)
}, 50)
},
//
createAni(firstIn) {
let that = this;
let unitRunTime = (that.runTime - 50) / 6;
let delayTime = unitRunTime * 4;
let durationTime = unitRunTime;
let dispairTime = unitRunTime;
// #ifdef H5
delayTime = unitRunTime * 3.5;
dispairTime = unitRunTime * 1.5;
// #endif
let showTransformHeight = -uni.upx2px(that.height);
let hideTransformHeight = showTransformHeight * 2;
//
if (that.showScale) {
if (firstIn) {
// that.animation.translateY(1).scale(1,1).step({ duration: 5 });
that.animation.translateY(showTransformHeight).scale(0.5, 0.5).step({
delay: delayTime,
duration: dispairTime
});
} else {
that.animation.translateY(showTransformHeight).scale(1, 1).step({
duration: durationTime
});
that.animation.translateY(hideTransformHeight).scale(0.5, 0.5).step({
delay: delayTime,
duration: dispairTime
});
}
} else {
if (firstIn) {
// that.animation.translateY(1).step({ duration: 5 });
that.animation.translateY(showTransformHeight).step({
delay: delayTime,
duration: dispairTime
});
} else {
that.animation.translateY(showTransformHeight).step({
duration: durationTime
});
that.animation.translateY(hideTransformHeight).step({
delay: delayTime,
duration: dispairTime
});
}
}
//
if (!that.animationData) {
that.animationData = that.animation.export()
that.setTimerFour = setTimeout(() => {
clearTimeout(that.setTimerFour)
that.animationData = false;
}, that.runTime)
return 'animationData'
} else {
that.animationDataTwo = that.animation.export()
that.setTimerFive = setTimeout(() => {
clearTimeout(that.setTimerFive)
that.animationDataTwo = false;
}, that.runTime)
return 'animationDataTwo'
}
},
//
toEmit() {
let that = this
if (that.list.length == 1) {
that.$emit('itemClick', that.list[0])
} else {
that.$emit('itemClick', that.list[that.aindexArr[0]])
}
},
dangGao(index){
let that = this
if (that.list.length != 0) {
that.$emit('dangGao', index)
}
}
},
created() {
},
mounted() {
// list
// setTimeout()
this.initPage()
},
watch: {
list(value) {
this.initPage()
}
}
};
</script>
<style lang="scss" scoped>
.contentBox {
width: 100%;
display: flex;
// padding: 0 20rpx;
align-items: center;
box-sizing: border-box;
font-size: 24rpx;
.supBox {
width: 50rpx;
display: flex;
justify-content: flex-start;
}
.offBox {
width: 50rpx;
display: flex;
justify-content: flex-end;
}
.content {
width: 100%;
flex-grow: 1;
height: 100%;
display: flex;
overflow: hidden;
position: relative;
align-items: center;
box-sizing: border-box;
justify-content: center;
.loopItemBase {
left: 0;
top: 100%;
width: 100%;
height: 100%;
overflow: hidden;
font-size: 28rpx;
text-align: left;
position: absolute;
white-space: nowrap;
align-items: center;
text-overflow: ellipsis;
&.fistInClass {
top: 0;
}
}
.loopItemBaseShow {
position: absolute;
top: 0;
left: 0;
width: 100%;
// height: 100%;
overflow: hidden;
font-size: 28rpx;
text-align: left;
white-space: nowrap;
align-items: center;
text-overflow: ellipsis;
}
}
}
</style>

View File

@ -0,0 +1,292 @@
<template>
<view class="xzw_notice" :style="{color:getColor(theme),backgroundColor:getBgColor(theme)}">
<uni-icons v-if="showIcon === true || showIcon === 'true'" class="notice_left" type="sound" :color="getColor(theme)" size="22" />
<swiper class="notice_center" vertical v-if="direction=='column'" :autoplay="true" :interval="4000" :duration="500" :circular="true" disable-touch>
<swiper-item v-for="(item, index) in list" :key="index" class="swiperIn" @click="goItem(item)">
<view>{{item[theKey]}}</view>
</swiper-item>
</swiper>
<view :class="['','notice_center1','notice_center2','notice_center3','notice_center4','notice_center5'][speedTime]" v-else><view class="content">{{list[0][theKey]}}</view></view>
<view class="notice_right" v-if="showMore">
<view @click="goMore"></view>
</view>
</view>
</template>
<script>
export default {
name:"notice-one",
props:{
//
speed: {
type:Number,
default:1
},
//,default|primary|error|warning|success|info
theme: {
type: String,
default: 'default'
},
// icon
showIcon: {
type: [Boolean, String],
default: false
},
//
showMore: {
type: [Boolean, String],
default: false
},
list: {
type: Array,
default() {
return [{id:1,title:'公告1'},{id:2,title:'公告2'}]
}
},
//
theKey:{
type: String,
default: 'title'
},
//columnrow
direction:{
type: String,
default: 'column'
}
},
data() {
return {
text:'',
speedTime:1
};
},
mounted() {
// +
const query = wx.createSelectorQuery().in(this)
query.select('.content').boundingClientRect((rect) => {
console.log(rect.width);
let newWidth = rect.width;
if(newWidth <=420) {
this.speedTime = 1;
}
if(newWidth >= 420 && newWidth < 720) {
this.speedTime = 2;
}
if(newWidth >= 720 && newWidth < 820) {
this.speedTime = 3;
}
if(newWidth >= 820 && newWidth < 920) {
this.speedTime = 4;
}
if(newWidth >= 920) {
this.speedTime = 5;
}
}).exec()
},
methods:{
getColor(theme){
if(theme=="primary"){
return "#2979FF"
}else if(theme=="error"){
return "#FA3534"
}else if(theme=="warning"){
return "#FF9A43"
}else if(theme=="success"){
return "#1BBF6C"
}else if(theme=="info"){
return "#909399"
}else{
return "#303133"
}
},
getBgColor(theme){
if(theme=="primary"){
return "#ECF5FF"
}else if(theme=="error"){
return "#FEF0F0"
}else if(theme=="warning"){
return "#FDF6EC"
}else if(theme=="success"){
return "#DBF1E1"
}else if(theme=="info"){
return "#F4F4F5"
}else{
return "#FFFFFF"
}
},
goItem(item){
uni.navigateTo({
url:`/pagesB/notice-detail/notice-detail?id=${item.id}`
})
},
goMore(){
uni.navigateTo({
url:`/pagesB/notice-list/notice-list`
})
}
}
}
</script>
<style lang="scss">
.xzw_notice {
font-size: 26upx;
height: 40upx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0;
box-sizing: border-box;
width: 100%;
.notice_left{
margin: 0 20upx 0 0;
}
.notice_center{
flex:1;
height:90upx;
.swiperIn{
height:80upx;
display: flex;
align-items: center;
view{
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
}
}
.notice_center1{
flex:1;
position: relative;
display: flex;
align-items: center;
height:90upx;
overflow: hidden;
view{
position: absolute;
white-space: nowrap;
padding-left: 100%;
animation: notice 5s 0s linear infinite both;
}
}
.notice_right {
margin: 0 0 0 20upx;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
.notice_center1{
flex:1;
position: relative;
display: flex;
align-items: center;
height:90upx;
overflow: hidden;
view{
position: absolute;
white-space: nowrap;
padding-left: 100%;
animation: notice 5s 0s linear infinite both;
}
}
.notice_right {
margin: 0 0 0 20upx;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
.notice_center2{
flex:1;
position: relative;
display: flex;
align-items: center;
height:90upx;
overflow: hidden;
view{
position: absolute;
white-space: nowrap;
padding-left: 100%;
animation: notice 10s 0s linear infinite both;
}
}
.notice_right {
margin: 0 0 0 20upx;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
.notice_center3{
flex:1;
position: relative;
display: flex;
align-items: center;
height:90upx;
overflow: hidden;
view{
position: absolute;
white-space: nowrap;
padding-left: 100%;
animation: notice 15s 0s linear infinite both;
}
}
.notice_right {
margin: 0 0 0 20upx;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
.notice_center4{
flex:1;
position: relative;
display: flex;
align-items: center;
height:90upx;
overflow: hidden;
view{
position: absolute;
white-space: nowrap;
padding-left: 100%;
animation: notice 20s 0s linear infinite both;
}
}
.notice_right {
margin: 0 0 0 20upx;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
.notice_center5{
flex:1;
position: relative;
display: flex;
align-items: center;
height:90upx;
overflow: hidden;
view{
position: absolute;
white-space: nowrap;
padding-left: 100%;
animation: notice 25s 0s linear infinite both;
}
}
.notice_right {
margin: 0 0 0 20upx;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
}
</style>

View File

@ -0,0 +1,75 @@
### 安装方式
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
### 说明
由于官方公告组件uni-notice-bar没有垂直滚动的功能, 所以利用swiper加入了垂直滚动, 加入了常用主题色, 可以自己去添加, 需要用到uni-icons
```html
<template>
<view class="container">
<!-- 默认垂直滚动 -->
<xzw-notice/>
<!-- 水平滚动,取数组第一条 -->
<xzw-notice theme="info" direction="row"/>
<!-- theme主题色,default|primary|error|warning|success|info -->
<xzw-notice theme="error" direction="row"/>
<!-- 点击公告,点击更多 -->
<xzw-notice theme="warning" @goItem="goItem" @goMore="goMore"/>
<!-- 绑定公告数组,默认取每一项的title字段,可以通过theKey改变读取的字段 -->
<xzw-notice theme="success" :list="list2" theKey="name"/>
<!-- 是否显示左侧喇叭,是否显示更多 -->
<xzw-notice theme="primary" :list="list2" theKey="name" :showIcon="false" :showMore="false"/>
</view>
</template>
```
```javascript
export default {
data() {
return {
list:[{id:1,title:'公告1'},{id:2,title:'公告2'}]
list2:[{id:1,name:'公告3'},{id:2,name:'公告4'}]
}
},
methods: {
goItem(item){
uni.showToast({
title:'你点击的公告id是'+item.id,
icon:'none'
})
},
goMore(){
uni.showToast({
title:'点击更多',
icon:'none'
})
}
}
}
```
## API
### Tag Props
|属性名 |类型 |默认值 |说明 |
|:-: |:-: |:-: |:-: |
|list |Array | |公告数组 |
|theme |String |default |主题 |
|showIcon |Boolean |true |是否显示左侧icon |
|showMore |Boolean |true |是否显示更多 |
|theKey |String |title |公告数组的键名 |
|direction |String |column |滚动的方向 |
### Tag Events
|事件称名 |说明 |返回值 |
|:-: |:-: |:-: |
|@goItem |点击公告 |- |
|@goMore |点击更多 |- |

View File

@ -0,0 +1,132 @@
export default {
"pulldown": "\ue588",
"refreshempty": "\ue461",
"back": "\ue471",
"forward": "\ue470",
"more": "\ue507",
"more-filled": "\ue537",
"scan": "\ue612",
"qq": "\ue264",
"weibo": "\ue260",
"weixin": "\ue261",
"pengyouquan": "\ue262",
"loop": "\ue565",
"refresh": "\ue407",
"refresh-filled": "\ue437",
"arrowthindown": "\ue585",
"arrowthinleft": "\ue586",
"arrowthinright": "\ue587",
"arrowthinup": "\ue584",
"undo-filled": "\ue7d6",
"undo": "\ue406",
"redo": "\ue405",
"redo-filled": "\ue7d9",
"bars": "\ue563",
"chatboxes": "\ue203",
"camera": "\ue301",
"chatboxes-filled": "\ue233",
"camera-filled": "\ue7ef",
"cart-filled": "\ue7f4",
"cart": "\ue7f5",
"checkbox-filled": "\ue442",
"checkbox": "\ue7fa",
"arrowleft": "\ue582",
"arrowdown": "\ue581",
"arrowright": "\ue583",
"smallcircle-filled": "\ue801",
"arrowup": "\ue580",
"circle": "\ue411",
"eye-filled": "\ue568",
"eye-slash-filled": "\ue822",
"eye-slash": "\ue823",
"eye": "\ue824",
"flag-filled": "\ue825",
"flag": "\ue508",
"gear-filled": "\ue532",
"reload": "\ue462",
"gear": "\ue502",
"hand-thumbsdown-filled": "\ue83b",
"hand-thumbsdown": "\ue83c",
"hand-thumbsup-filled": "\ue83d",
"heart-filled": "\ue83e",
"hand-thumbsup": "\ue83f",
"heart": "\ue840",
"home": "\ue500",
"info": "\ue504",
"home-filled": "\ue530",
"info-filled": "\ue534",
"circle-filled": "\ue441",
"chat-filled": "\ue847",
"chat": "\ue263",
"mail-open-filled": "\ue84d",
"email-filled": "\ue231",
"mail-open": "\ue84e",
"email": "\ue201",
"checkmarkempty": "\ue472",
"list": "\ue562",
"locked-filled": "\ue856",
"locked": "\ue506",
"map-filled": "\ue85c",
"map-pin": "\ue85e",
"map-pin-ellipse": "\ue864",
"map": "\ue364",
"minus-filled": "\ue440",
"mic-filled": "\ue332",
"minus": "\ue410",
"micoff": "\ue360",
"mic": "\ue302",
"clear": "\ue434",
"smallcircle": "\ue868",
"close": "\ue404",
"closeempty": "\ue460",
"paperclip": "\ue567",
"paperplane": "\ue503",
"paperplane-filled": "\ue86e",
"person-filled": "\ue131",
"contact-filled": "\ue130",
"person": "\ue101",
"contact": "\ue100",
"images-filled": "\ue87a",
"phone": "\ue200",
"images": "\ue87b",
"image": "\ue363",
"image-filled": "\ue877",
"location-filled": "\ue333",
"location": "\ue303",
"plus-filled": "\ue439",
"plus": "\ue409",
"plusempty": "\ue468",
"help-filled": "\ue535",
"help": "\ue505",
"navigate-filled": "\ue884",
"navigate": "\ue501",
"mic-slash-filled": "\ue892",
"search": "\ue466",
"settings": "\ue560",
"sound": "\ue590",
"sound-filled": "\ue8a1",
"spinner-cycle": "\ue465",
"download-filled": "\ue8a4",
"personadd-filled": "\ue132",
"videocam-filled": "\ue8af",
"personadd": "\ue102",
"upload": "\ue402",
"upload-filled": "\ue8b1",
"starhalf": "\ue463",
"star-filled": "\ue438",
"star": "\ue408",
"trash": "\ue401",
"phone-filled": "\ue230",
"compose": "\ue400",
"videocam": "\ue300",
"trash-filled": "\ue8dc",
"download": "\ue403",
"chatbubble-filled": "\ue232",
"chatbubble": "\ue202",
"cloud-download": "\ue8e4",
"cloud-upload-filled": "\ue8e5",
"cloud-upload": "\ue8e6",
"cloud-download-filled": "\ue8e9",
"headphones":"\ue8bf",
"shop":"\ue609"
}

View File

@ -0,0 +1,52 @@
<template>
<text :style="{ color: color, 'font-size': size + 'px' }" class="uni-icons" :class="[customIcons,customIcons?type:'']" @click="_onClick">{{icons[type]}}</text>
</template>
<script>
import icons from './icons.js';
export default {
name: 'UniIcons',
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customIcons:{
type: String,
default: ''
}
},
data() {
return {
icons: icons
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" scoped>
/* #ifndef APP-NVUE */
@font-face {
font-family: uniicons;
src: url('./uni.ttf') format('truetype');
}
/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>

Binary file not shown.

View File

@ -1,42 +0,0 @@
<template>
<view>
<view v-if="showShare" @tap="closeShare" style="position: fixed;top: 0;right: 0;left: 0;bottom: 0;background-color: rgba(0,0,0,.5);z-index: 10;">
</view>
<view v-if="showShare" style="display: flex;flex-direction: column;justify-content: space-around;
position: fixed;bottom: 0;left: 0;right: 0;z-index: 100; background-color: #FFFFFF;padding: 40rpx;">
<view class="posir" v-for="(item,index) in cateArr" :key="index" style="display: flex;justify-content: center;align-items: center;flex-direction: column;width: 25%;">
<image style="width: 100rpx;height: 100rpx;margin-bottom: 10rpx;" :src="item.src" mode=""></image>
<view class="fon28 color33">{{item.title}}</view>
<button data-name="shareBtn" open-type="share" plain="true" class="posia" style="top: 0;left: 0;right: 0;bottom: 0;opacity: 0;">分享</button>
</view>
</view>
</view>
</template>
<script>
export default {
name:'shareAll',
props:{
showShare:{
type:Boolean,
default:false
}
},
data() {
return {
cateArr:[
{src:'/static/img/share/weix.png',title:'微信好友'},
]
};
},
methods:{
closeShare(){
this.$emit('closeShare')
}
}
}
</script>
<style>
</style>

View File

@ -1,188 +0,0 @@
<template>
<view class="status-box statusHNH">
<!-- 网络电量栏 start -->
<view :style="{height: statusBarHeight+'px',background: backgroudColor}"></view>
<!-- 网络电量栏 end -->
<!-- 头部状态栏 start -->
<view class="status-nav"
:style="{background: backgroudColor,height: navBarHeight+'px'}">
<!-- 返回键 -->
<view class="return-box" @tap="backEv" v-if="ifReturn"
:style="{height: navBarHeight+'px'}">
<slot name="leftContent">
<i class="icon icon-return" style="font-size: 32rpx;"
:style="{color: returnColor}"></i>
</slot>
</view>
<!-- 标题 -->
<view class="tab-title" v-if="ifTitle && ifNet"
:style="{
color: titleColor,
justifyContent: ifCenter ? 'center' : '',
padding: ifCenter ? '0px' : `${ifReturn ? '0 38' : '0 15'}px`}">
<view class="title-box" :class="['','clips1','clips2'][clipNumber]" :style="{maxWidth: ifCenter ? '360rpx' : '70%'}">{{navBarTitle}}</view>
</view>
<view class="tab-title" v-if="!ifNet"
:style="{
color: titleColor,
justifyContent: ifCenter ? 'center' : '',
padding: ifCenter ? '0px' : `${ifReturn ? '0 38' : '0 15'}px`}">
<view class="title-box" :class="['','clips1','clips2'][clipNumber]" :style="{maxWidth: ifCenter ? '360rpx' : '70%'}">{{netText}}<text @tap="refreshEv" style="color: #3875F6;margin-left: 20rpx;">刷新</text></view>
</view>
</view>
<!-- 头部状态栏 end -->
</view>
</template>
<script>
export default {
name:'status-nav',
props:{
//
backgroudColor:{
type:String,
default:'#FFFFFF'
},
//
navBarHeight: {
type:Number,
default:40
},
//
ifReturn:{
type:Boolean,
default:true
},
//
returnColor: {
type:String,
default:'#000'
},
//
ifTitle:{
type:Boolean,
default:true
},
//
navBarTitle: {
type:String,
default:''
},
//
clipNumber: {
type:Number,
default:1
},
//
titleColor:{
type:String,
default:'#333333'
},
//
ifCenter: {
type:Boolean,
default: true
},
//
fromWhere: {
type:Number,
default:0
}
},
data(){
return {
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
ifNet:true ,//
netText:'当前无网络',
netTimer:null
}
},
mounted() {
//
this.$toolAll.tools.networkStatus();
// +
// const query = wx.createSelectorQuery().in(this)
// query.select('.statusHNH').boundingClientRect((rect) => {
// uni.setStorageSync('statusHNH',rect.height)
// }).exec();
//
this.$toolAll.tools.obtainUrl();
this.$toolAll.tools.obtainUrlParam();
setTimeout(()=>{
this.ifNet = uni.getStorageSync('isNet');
},500)
},
methods:{
//
refreshEv(){
this.netText = '正在刷新...';
let outTime = 0;//
this.netTimer = setInterval(()=>{
outTime++;
this.$toolAll.tools.networkStatus();
if(uni.getStorageSync('isNet')) {
clearInterval(this.netTimer);
this.ifNet = true;
}
if(outTime==10) {
clearInterval(this.netTimer);
this.netText = '刷新失败';
outTime = 0;
}
},1000)
},
//
backEv(){
if(uni.getStorageSync('outside')*1==2){
this.fromWhere = uni.getStorageSync('outside')*1;
}
switch (this.fromWhere){
case 1:
case 2:
uni.navigateTo({
url:'/pages/tabbar/pagehome/pagehome'
})
uni.setStorageSync('outside',0)
break;
case 0:
uni.navigateBack({
delta:1
})
break;
default:
break;
}
}
}
}
</script>
<style scoped>
.clips1{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips2{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.status-box{
position: fixed;top: 0;left: 0;right: 0;z-index: 10;
}
.status-nav{
width: 100%;
position: relative;
display: flex;
align-items: center;
}
.return-box {
display: flex;justify-content: center;align-items: center;flex-shrink: 0;
position: absolute;
padding: 0rpx 10rpx;
}
.return-box i {font-size: 56rpx;}
.tab-title{
width: 100%;
font-size: 32rpx;
display: flex;
font-weight: bold;
}
.tab-title .title-box{margin-top: -4rpx;}
</style>

View File

@ -1,6 +1,6 @@
const app = getApp();
const tools = {
timer:'',
timerNot:'',
// 埋点倒计时
daoTime(){
let daoTime = uni.getStorageSync('daoTime')
@ -9,13 +9,10 @@ const tools = {
daoTime = uni.getStorageSync('daoTime')
this.timer = setInterval(()=>{
uni.setStorageSync('daoTime',daoTime--)//设置倒计时
// console.log('埋点倒计时初次:',daoTime);
// console.log('埋点长度初次:',uni.getStorageSync('maiList').length);
if(uni.getStorageSync('daoTime')<=0 || uni.getStorageSync('maiList').length==5){
uni.removeStorageSync('daoTime')//清空倒计时
clearInterval(this.timer)//关闭倒计时
// console.log('上/报,埋点');
// reportBuriedPoint(uni.getStorageSync('maiList'))//上报事件
uni.removeStorageSync('maiList')//清空上报参数
this.daoTime()//重新倒计时
}
@ -23,13 +20,10 @@ const tools = {
} else {//继续当前倒计时倒计
this.timer = setInterval(()=>{
uni.setStorageSync('daoTime',daoTime--)//设置倒计时
// console.log('埋点倒计时:',daoTime);
// console.log('埋点长度:',uni.getStorageSync('maiList').length);
if(uni.getStorageSync('daoTime')<=0 || uni.getStorageSync('maiList').length==5){
uni.removeStorageSync('daoTime')//清空倒计时
clearInterval(this.timer)//关闭倒计时
// console.log('上报,埋点');
// reportBuriedPoint(uni.getStorageSync('maiList'))//上报事件
uni.removeStorageSync('maiList')//清空上报参数
this.daoTime()//重新倒计时
}
@ -39,15 +33,6 @@ const tools = {
closeTimer(){
clearInterval(this.timer)//关闭倒计时
console.log('倒计时清空了');
clearInterval(this.timerNot)//关闭倒计时
},
maiDian(data){//埋点事件
let maiList = uni.getStorageSync('maiList')
// console.log(maiList);
if(maiList==''){
maiList = [data]
} else maiList.push(data)
uni.setStorageSync('maiList',maiList)
},
weekDate(){//获取未来七天星期几,几号
let date = new Date()
@ -63,10 +48,6 @@ const tools = {
isPhone:function(phone){
// 手机号正则表达式
let reg_tel = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
// if(!reg_tel.test(phone)){
// return true
// }
// return false
return !reg_tel.test(phone);
},
// 电子邮箱验证
@ -83,6 +64,21 @@ const tools = {
hideMPhone(phone){
return `${phone.substr(0, 3)}****${phone.substr(7)}`
},
// 手机号中间加字符
phoneAddChat(phone,startNum=3,endNum=7,character=' '){
let phoneStr = phone;
phoneStr = phoneStr.replace(/\s*/g, "");
var phoneArr = [];
for(var i = 0; i < phoneStr.length; i++){
if (i==startNum||i==endNum){
phoneArr.push(`${character}` + phoneStr.charAt(i));
} else {
phoneArr.push(phoneStr.charAt(i));
}
}
phone = phoneArr.join("");
return phone;
},
// 昵称从第一个字开始,后面的都用"*"代替
hideName(name,num){
return `${name.substr(0, 1)}****${name.substr(name.length-1)}`
@ -113,7 +109,7 @@ const tools = {
str = str.toFixed(2);
str = str+'';
}
return str.includes('.') ? str*1 : str = num + '.00';
return str.includes('.') ? str : str = num + '.00';
},
// type:+加、-减、*乘、/除
// len:小数后保留几位
@ -229,6 +225,65 @@ const tools = {
// console.log(time2);//1398250549123
// console.log(time3);//1398250549000
},
// 返回当前时间
returnCurrentTime(format,type) {
let date = new Date();
let year = date.getFullYear(); // 年
let month = date.getMonth() + 1; // 月
let day = date.getDate(); // 日
let time = date.getHours(); // 时
let minu = date.getSeconds(); // 分
let second = date.getMinutes(); // 秒
let newTime = '';
switch (type){
case 0:
newTime = `${year}${format}${month < 10? '0' + month : month}${format}${day < 10 ? '0' + day : day} ${time < 10 ? '0' + time : time}:${minu < 10 ? '0' + minu : minu}`; // 2022-03-31 16:05
break;
case 1:
newTime = `${year}${format}${month < 10? '0' + month : month}${format}${day < 10 ? '0' + day : day} ${time < 10 ? '0' + time : time}:${minu < 10 ? '0' + minu : minu}:${second < 10 ? '0' + second : second}`; // 2022-03-31 16:10:07
break;
}
return newTime;
},
// 返回时间xx天xx小时xx分钟
returnTimeFormat(startTime,endTime){
console.log(startTime,endTime);
let newTimeFormat = '';
let currentTimestamp = this.timeToTimestamp(endTime) - this.timeToTimestamp(startTime);
return this.returnTimestampToTime(currentTimestamp);
},
// 返回时间戳转时、分对象
returnTimestampToTime(timestamp){
let timeStr = '';
var day = parseInt((timestamp % (1000 * 60 * 60 * 24 * 12)) / (1000 * 60 * 60 * 24));
var hours = parseInt((timestamp % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var seconds = parseInt((timestamp % (1000 * 60 * 60)) / (1000 * 60));
day = day < 10 ? ('0' + day) : day;
hours = hours < 10 ? ('0' + hours) : hours;
seconds = seconds < 10 ? ('0' + seconds) : seconds;
if(day*1==0) {
if(hours*1==0) {
seconds*1==0 ? timeStr = 0 : timeStr = `${seconds}分钟`;
} else {
timeStr = `${hours}小时${seconds}分钟`;
}
} else {
timeStr = `${day}${hours}小时${seconds}分钟`;
}
return timeStr;
},
// 时间戳转时分秒 00 : 00 : 00
formatDuring: function(mss) {
// let dangTime = Math.round(new Date()/1000)//获取当前时间戳
var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var seconds = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
var minutes = (mss % (1000 * 60)) / 1000;
hours = hours < 10 ? ('0' + hours) : hours;
seconds = seconds < 10 ? ('0' + seconds) : seconds;
minutes = minutes < 10 ? ('0' + minutes) : minutes;
return hours + ' : ' + seconds + ' : ' + minutes;
},
// 随机数生成
randomStr(){
var strData = "";
@ -268,30 +323,18 @@ const tools = {
return newObj
},
// 提示方法
showToast: function(msg, icon,time) {
// 弹框图标none默认无图标、loading、success
var newIncon = 'none';
if (icon) {newIncon = icon;}
showToast: function(msg, icon='none',time) {
// 弹框显示时间默认2秒
var newTime = 2000
if (time) {newTime = time;}
return uni.showToast({
title: msg,
icon: newIncon,
icon: icon,
duration:newTime
})
},
formatDuring: function(mss) {
// let dangTime = Math.round(new Date()/1000)//获取当前时间戳
var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
var seconds = (mss % (1000 * 60)) / 1000;
hours = hours < 10 ? ('0' + hours) : hours;
minutes = minutes < 10 ? ('0' + minutes) : minutes;
seconds = seconds < 10 && seconds >= 1 ? ('0' + seconds) : seconds;
return hours + ' : ' + minutes + ' : ' + seconds;
},
escape2Html(str) {//富文本
// 富文本
escape2Html(str) {
var arrEntities = { 'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"' };
return str.replace(/&(lt|gt|nbsp|amp|quot|src);/ig, function (all, t) {
return arrEntities[t];
@ -300,39 +343,10 @@ const tools = {
.replace(/\<img/g, '<img @tap="pre" style="max-width:100%!important;height:auto" ')
.replace(/src=\"/g,'src="https://oss.hmzfyy.cn');
},
updaX(){//检测小程序版本以及更新小程序
// #ifdef MP-WEIXIN
// 获取小程序的运行环境、版本号、appId 注意:线上小程序版本号仅支持在正式版小程序中获取,开发版和体验版中无法获取。
const accountInfo = wx.getAccountInfoSync();//使用详情https://developers.weixin.qq.com/miniprogram/dev/api/open-api/account-info/wx.getAccountInfoSync.html
var version = accountInfo.miniProgram.version;
console.log(version,319);
// 检测小程序的更新
const updateManager = wx.getUpdateManager()//以下使用详情https://developers.weixin.qq.com/miniprogram/dev/api/base/update/UpdateManager.html#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
// console.log('检测是否有更新:',res.hasUpdate)
})
updateManager.onUpdateReady(function (res) {
wx.showModal({
title: `更新`,
content: `新版本${version}已上线,是否重启应用`,
success:(res)=> {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function (res) {
// 新版本下载失败
// console.log('新版本下载失败:',res);
})
// #endif
},
networkStatus(){//检查网络状态
// 检查网络状态
networkStatus(){
uni.getNetworkType({
success: function (res) {
success: (res)=> {
console.log('当前网络状态:',res.networkType);//none当前无网络连接
if(res.networkType=='none'){
uni.setStorageSync('isNet',false)
@ -341,12 +355,84 @@ const tools = {
// 微信小程序原生API性能优化
// #ifdef MP-WEIXIN
// 连网下,检测小程序是否有更新
tools.updaX();
this.checkUpdate();
// #endif
}
}
});
},
// app、小程序的检测版本并更新
checkUpdate(){
// 检测app
// #ifdef APP-PLUS
// #endif
//检测小程序
// #ifdef MP-WEIXIN
var self = this;
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager();//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function(res) {// 请求完新版本信息的回调
if (res.hasUpdate) {
//检测到新版本,需要更新,给出提示
wx.showModal({
title: '更新提示',
content: '检测到新版本,是否下载新版本并重启小程序?',
success: function(res) {
if (res.confirm) {
//2. 用户确定下载更新小程序,小程序下载及更新静默进行
self.downLoadAndUpdate(updateManager)
// 清除所有缓存
uni.clearStorage();
uni.clearStorageSync();
} else if (res.cancel) {
//用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
wx.showModal({
title: '温馨提示~',
content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~',
showCancel:false,//隐藏取消按钮
confirmText:"确定更新",//只保留确定更新按钮
success: function(res) {
if (res.confirm) {
//下载新版本,并重新应用
self.downLoadAndUpdate(updateManager)
}
}
})
}
}
})
}
})
} else { // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
// #endif
},
/**
* 下载小程序新版本并重启应用
* */
downLoadAndUpdate(updateManager){
var self = this;
wx.showLoading(); //静默下载更新小程序新版本
updateManager.onUpdateReady(function () {
wx.hideLoading(); //新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
// 清除缓存
uni.clearStorageSync();
uni.clearStorage();
})
updateManager.onUpdateFailed(function () { // 新的版本下载失败
wx.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~',
})
})
},
// 文本复制
clickCopy(data){
uni.setClipboardData({
@ -405,7 +491,7 @@ const tools = {
if (res.code) {
var params = {code:res.code}
uni.request({
url: `${uni.getStorageSync('hostapi')}/api/user/login`,
url: `${app.globalData.hostapi}/api/user/login`,
method: 'post',
data: params,
header: {
@ -430,16 +516,17 @@ const tools = {
}
},
// 判断是否授权,没授权,前往登录页面授权
authTimer:null,
judgeAuth(){
let auth = true;
switch (uni.getStorageSync('phone_active')*1){
case 0: // 未注册
uni.navigateTo({url:'/pages/login/login'});
auth = false
break;
case 1: // 已注册
auth = true
break;
let auth = false;
clearTimeout(this.authTimer);
if(!uni.getStorageSync('token')) {
this.showToast('请登录');
this.authTimer = setTimeout(()=>{
uni.navigateTo({url:'/pages/login/login'});
},2000)
} else {
auth = true;
}
return auth;
},
@ -456,13 +543,10 @@ const tools = {
// console.log(hInfo.envVersion);//develop:开发版 trial体验版 release正式版
// if(hInfo.miniProgram.envVersion == "develop"){
if(hInfo.miniProgram.envVersion == "develop" || hInfo.miniProgram.envVersion == "trial"){
// (开发版,体验版)-配置全局域名
// uni.setStorageSync('hostapi','https://hengmei.scdxtc.cn/api/');
} else {
// 清除所有输出日志
console.log = () =>{};
// 正式版-配置全局域名
// uni.setStorageSync('hostapi','https://hm.hmzfyy.cn/api/');
// 开启埋点倒计时
this.daoTime();//开启埋点倒计时
}
@ -523,7 +607,7 @@ const tools = {
const res = uni.getSystemInfoSync();
if(res.platform=='ios'){
uni.makePhoneCall({
phoneNumber:phone,
phoneNumber:phone*1,
success: () => {},
fail: () => {}
})

View File

@ -1,5 +1,7 @@
import Vue from 'vue';
import App from './App';
import store from './store'
Vue.prototype.$store = store
import nothingPage from './components/nothing/nothing-page.vue';//引入无内容组件
Vue.component('nothing-page',nothingPage);//全局注册无内容组件
@ -10,10 +12,12 @@ Vue.component('status-nav',statusNav);//全局注册头部状态栏与导航栏
import containerSubgroupTwo from './components/containers/container-subgroup-two.vue';//引入头部状态栏与导航栏组件
Vue.component('container-subgroup',containerSubgroupTwo);//全局注册头部状态栏与导航栏组件
// #ifdef MP-WEIXIN
import share from './jsFile/share.js';// 全局注册分享事件
Vue.mixin(share);
// #endif
// 常用工具
// 常用便捷式公共方法
import tools from '@/jsFile/tools.js';
Vue.prototype.$toolAll = tools;
// 响应数据
@ -23,6 +27,7 @@ Vue.prototype.$requst = requst;
App.mpType = 'app';
const app = new Vue({
store,
...App
})
app.$mount()

View File

@ -48,7 +48,6 @@
<view class="disac pad-s30 pad-x10">
<image class="mar-zy20" style="width: 64rpx;height: 27rpx;" src="/static/public/icon-home-notice.png" mode=""></image>
<view class="fon24 color6 mar-y20 width100 bleft pad-z20">
<lwNotice @dangGao="goNoticeDetail" :list="noticeList" :backgroundColor="'#FFFFFF'"></lwNotice>
</view>
</view>
</view>
@ -228,14 +227,13 @@
//
import pitera from '@/components/nothing/pitera.vue';
//
import lwNotice from '@/components/lw-notice/lw-notice.vue';
import footTabOne from '@/components/foot-tabs/foot-tab-one.vue';
import containerSubgroupTwo from '@/components/containers/container-subgroup-two.vue';
import { mapState,mapGetters,mapMutations } from 'vuex'//mapState
export default {
components:{
pitera,
statusNavSlot,
lwNotice,
'foot-tab' :footTabOne,
containerSubgroupTwo
},
@ -313,6 +311,62 @@
faultsList:[],
}
},
// computed:{
// tokenEv() {
// return this.$store.state.token;
// }
// },
// computed:mapState({
// // state 使
// token: state => state.token,
// }),
// computed:mapState(['token']),
// computed: {
// ...mapState({
// token: function (state) {
// return '' + state.token
// },
// userInfo: state => state.userInfo,
// })
// },
// computed: {
// todos() {
// return this.$store.getters.doneTodos
// }
// },
// computed: {
// doneTodosCount() {
// return this.$store.getters.doneTodosCount
// }
// },
// computed: {
// getTodoById() {
// return this.$store.getters.getTodoById(1)
// }
// },
// computed: {
// // 使 getter computed
// ...mapGetters([
// 'doneTodos',
// 'doneTodosCount',
// 'getTodoById'
// // ...
// ])
// },
// computed:{
// ...mapState([
// 'token',
// 'userInfo',
// 'count',
// 'obj'
// ])
// },
computed: {
...mapState({
token: state => state.moduleA.token,
count: state => state.moduleB.count
}),
},
onLoad(options) {
// url
this.$toolAll.tools.obtainUrl();
@ -322,8 +376,29 @@
// this.getIncrementServiceType();
//
this.getFaultsList();
// this.$store.commit('setToken', 'token');
// this.$store.commit('updateUserInfo',{userInfo:''})
// this.$store.commit({
// type: 'updateUserInfo',
// userInfo: ''
// })
// console.log(this.userInfo,374);
// this.add();
// console.log(this.obj);
// this.$store.commit('newProp',{c:''})
// console.log(this.obj,382);
// this.$store.dispatch('addCountAction')
// this.$store.dispatch('addCountAction2',{amount:10})
// this.$store.dispatch('addCountAction3',{amount:30})
// setTimeout(()=>{
// console.log(this.count,388);
// },3000)
// console.log(this.count,390);
console.log(this.token,397);
console.log(this.count,398);
},
methods: {
// ...mapMutations(['add']),//add
//
goWorkOrder(index){
if(index==0){

View File

@ -1,16 +1,19 @@
<template>
<view>
<notice-one direction="row"></notice-one>
<!-- 底部tab -->
<foot-tab :current="1"></foot-tab>
</view>
</template>
<script>
import noticeOne from '@/components/notices/notice-one/notice-one.vue';
//
import footTabOne from '@/components/foot-tabs/foot-tab-one.vue';
export default {
components:{
'foot-tab' :footTabOne
'foot-tab' :footTabOne,
noticeOne
},
data() {
return {

View File

@ -24,8 +24,8 @@
<view class="bacf fon28 pad-sx30 pad-zy40 mar-s20">
<view class="fon30 bold mar-sx30">您的评价</view>
<view class="mar-s40 mar-x50" style="color: #545454;">
<view class="mar-x40 disac"><text class="mar-y40">技术服务</text><rate :size="42" :gutter="40" :curentClick="0" v-model="rateNum" @change="chooseRate"></rate></view>
<view class="disac"><text class="mar-y40">客服态度</text><rate :size="42" :gutter="40" :curentClick="1" v-model="attitudeNum" @change="chooseRate"></rate></view>
<view class="mar-x40 disac"><text class="mar-y40">技术服务</text><rate-one :size="42" :gutter="40" :curentClick="0" v-model="rateNum" @change="chooseRate"></rate-one></view>
<view class="disac"><text class="mar-y40">客服态度</text><rate-one :size="42" :gutter="40" :curentClick="1" v-model="attitudeNum" @change="chooseRate"></rate-one></view>
</view>
</view>
<!-- 提交保存 -->
@ -36,10 +36,10 @@
</template>
<script>
import rate from '@/components/rate.vue';
import rateOne from '@/components/rates/rate-one.vue';
export default {
components:{
rate
rateOne
},
data() {
return {

1
store/actions.js Normal file
View File

@ -0,0 +1 @@
// 根级别的 action

16
store/index.js Normal file
View File

@ -0,0 +1,16 @@
// 组装模块并导出 store 的地方
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from '@/store/modules/moduleA'
import moduleB from '@/store/modules/moduleB'
Vue.use(Vuex);//vue的插件机制
//Vuex.modules 模块选项
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
export default store

88
store/modules/moduleA.js Normal file
View File

@ -0,0 +1,88 @@
// 购物车模块
export default {
state:{//存放状态
token:'token已生成',
userInfo:{},
count:0,
publicColor:'',
todos: [{
id: 1,
text: '我是内容一',
done: true
},
{
id: 2,
text: '我是内容二',
done: false
}
],
obj:{
a:'吃鸡腿',
b:'吃自助餐'
}
},
// Vuex中store数据改变的唯一方法就是mutations 不适合异步方法
mutations: {
add(state) {
state.count = 7;
},
add2(state, payload) {
state.count = payload.amount;
},
// 单个属性处理方法
setToken(state,str) {
state.token = str;
},
// 对象处理方法
updateUserInfo(state, payload) {
// 变更状态
state.userInfo = payload.userInfo;
},
// 新增字段方法
newProp(state,payload) {
state.obj = { ...state.obj, c: payload.c };
}
},
// 可以执行任意的同步和异步操作
actions:{
addCountAction ({commit}) {
commit('add')
},
addCountAction2 (context , payload) {
context.commit('add2', payload)
},
// 异步方法
addCountAction3 (context , payload) {
setTimeout(function () {
context.commit('add2', payload)
}, 2000)
},
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
},
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
},
// Vuex 允许我们在 store 中定义“getter”可以认为是 store 的计算属性),对 state 的加工,是派生出来的数据。 可以在多组件中共享 getter 函数,这样做还可以提高运行效率。
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
//state :可以访问数据
//getters访问其他函数等同于 store.getters
return getters.doneTodos.length
},
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
}

87
store/modules/moduleB.js Normal file
View File

@ -0,0 +1,87 @@
export default {
state:{//存放状态
token:'token已生成',
userInfo:{},
count:0,
publicColor:'',
todos: [{
id: 1,
text: '我是内容一',
done: true
},
{
id: 2,
text: '我是内容二',
done: false
}
],
obj:{
a:'吃鸡腿',
b:'吃自助餐'
}
},
// Vuex中store数据改变的唯一方法就是mutations 不适合异步方法
mutations: {
add(state) {
state.count = 7;
},
add2(state, payload) {
state.count = payload.amount;
},
// 单个属性处理方法
setToken(state,str) {
state.token = str;
},
// 对象处理方法
updateUserInfo(state, payload) {
// 变更状态
state.userInfo = payload.userInfo;
},
// 新增字段方法
newProp(state,payload) {
state.obj = { ...state.obj, c: payload.c };
}
},
// 可以执行任意的同步和异步操作
actions:{
addCountAction ({commit}) {
commit('add')
},
addCountAction2 (context , payload) {
context.commit('add2', payload)
},
// 异步方法
addCountAction3 (context , payload) {
setTimeout(function () {
context.commit('add2', payload)
}, 2000)
},
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
},
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
},
// Vuex 允许我们在 store 中定义“getter”可以认为是 store 的计算属性),对 state 的加工,是派生出来的数据。 可以在多组件中共享 getter 函数,这样做还可以提高运行效率。
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
//state :可以访问数据
//getters访问其他函数等同于 store.getters
return getters.doneTodos.length
},
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
}

1
store/mutations.js Normal file
View File

@ -0,0 +1 @@
// 根级别的 mutation

0
store/readme.md Normal file
View File