feat: 添加静态资源文件及基础组件

- 新增大量图片资源,包括图标、背景图、海报等,用于页面展示
- 添加字体文件及样式配置,支持自定义字体
- 引入 uni-ui 组件库,包括图标、弹窗、日期选择器等常用组件
- 添加网络状态监听、加密工具等基础工具函数
- 配置 Vuex 状态管理,包括购物车数量、热门搜索词等
- 增加页面组件,如用户协议、分销信息、提现状态等
- 配置项目构建和忽略文件,优化开发体验
This commit is contained in:
2026-02-26 17:59:51 +08:00
commit a5c5d753b6
720 changed files with 178840 additions and 0 deletions

View File

@@ -0,0 +1,184 @@
<template>
<view :style="colorStyle">
<view class="px-20">
<view class="order_card bg--w111-fff rd-24rpx pt-32 pb-32 pl-24 pr-24"
v-for="(item, index) in bargain" :key="index">
<view class="flex-between-center">
<text class="fs-28 lh-40rpx">{{item.add_time}}</text>
<text class="font-color fs-26" v-if="item.status === 1">活动进行中</text>
<text class="font-color fs-26" v-else-if="item.status === 3">砍价成功</text>
<text class="font-color fs-26" v-else>活动已结束</text>
</view>
<view class="flex-between-center mt-26">
<easy-loadimage
:image-src="item.image"
width="136rpx"
height="136rpx"
borderRadius="16rpx"></easy-loadimage>
<view class="flex-1 pl-20">
<view class="w-504 line2 fs-28 lh-40rpx">{{item.title}}</view>
<view class="flex items-baseline mt-20">
<text class="fs-24 text--w111-999">已砍至</text>
<baseMoney :money="item.residue_price" symbolSize="20" integerSize="32" decimalSize="20" weight></baseMoney>
</view>
</view>
</view>
<view class="pt-24 bt mt-32 flex-between-center">
<view class="flex-y-center fs-24" v-if="item.status === 1">
<text class="pr-12 text--w111-999">剩余:</text>
<count-down
justify-left="justify-content:left"
:is-day="true"
tip-text=" "
day-text=" "
hour-text="时"
minute-text="分"
second-text="秒"
dotColor="#999"
:datatime="item.datatime"></count-down>
</view>
<text class="pr-12 text--w111-999 fs-24" v-if="item.status === 2">活动已结束</text>
<text class="pr-12 text--w111-999 fs-24" v-if="item.status === 3">砍价已成功</text>
<view class="flex">
<view class="btn w-154 h-56 rd-30rpx flex-center fs-24 border_ccc"
v-if="item.status === 1"
@tap="getBargainUserCancel(item.bargain_id)"
>取消活动</view>
<view class="btn w-154 h-56 rd-30rpx flex-center fs-24 bg-color text--w111-fff"
v-if="item.status === 1"
@tap="goDetail(item.bargain_id)"
>{{item.pay_status ? '立即付款' : '继续砍价'}}</view>
<view class="btn w-154 h-56 rd-30rpx flex-center fs-24 bg-color text--w111-fff"
v-if="[2,3].includes(item.status)" @tap="goPage('/pages/activity/goods_bargain/index')">重开一个</view>
</view>
</view>
</view>
<Loading :loaded="status" :loading="loadingList"></Loading>
</view>
<view class="px-20 mt-20" v-if="!bargain.length">
<emptyPage title="暂无砍价记录~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
<home></home>
</view>
</template>
<script>
import CountDown from "@/components/countDown";
import emptyPage from '@/components/emptyPage.vue'
import {
getBargainUserList,
getBargainUserCancel
} from "@/api/activity";
import { getUserInfo } from '@/api/user.js';
import Loading from "@/components/Loading";
import colors from "@/mixins/color";
export default {
name: "BargainRecord",
components: {
CountDown,
Loading,
emptyPage,
},
props: {},
mixins: [colors],
data: function() {
return {
bargain: [],
status: false, //砍价列表是否获取完成 false 未完成 true 完成
loadingList: false, //当前接口是否请求完成 false 完成 true 未完成
page: 1, //页码
limit: 20, //数量
userInfo: {}
};
},
onLoad: function() {
this.getBargainUserList();
this.getUserInfo();
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
methods: {
goDetail: function(id) {
uni.navigateTo({
url: `/pages/activity/goods_bargain_details/index?id=${id}&spid=${this.userInfo.uid}`
})
},
getBargainUserList: function() {
var that = this;
if (that.loadingList) return;
if (that.status) return;
getBargainUserList({
page: that.page,
limit: that.limit
})
.then(res => {
that.status = res.data.length < that.limit;
that.bargain.push.apply(that.bargain, res.data);
that.page++;
that.loadingList = false;
})
.catch(res => {
that.$util.Tips({
title: res
})
});
},
getBargainUserCancel: function(bargainId) {
var that = this;
getBargainUserCancel({
bargainId: bargainId
})
.then(res => {
that.status = false;
that.loadingList = false;
that.page = 1;
that.bargain = [];
that.getBargainUserList();
that.$util.Tips({
title: res.msg
})
})
.catch(res => {
that.$util.Tips({
title: res
})
});
},
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
that.userInfo = res.data;
});
},
goPage(url){
uni.navigateTo({
url
})
}
},
onReachBottom() {
this.getBargainUserList();
},
onPageScroll(object) {
uni.$emit('scroll');
},
};
</script>
<style lang="scss">
.order_card{
margin-top:20rpx;
}
.border_ccc {
border: 1rpx solid #ccc;
}
.bt{
border-top: 1rpx solid #eee;
}
.btn ~ .btn{
margin-left: 16rpx;
}
</style>

View File

@@ -0,0 +1,445 @@
<template>
<view :style="colorStyle">
<view class="w-full h-400 relative z-10" :style="{'height': (186 + sysHeight) * 2 + 'rpx', 'background' : headerBg}">
<NavBar titleText="领券中心"
textSize="34rpx"
:bagColor="pageScrollStatus ? 'var(--view-theme)' : 'transparent'"
iconColor="#ffffff"
textColor="#ffffff"
showBack></NavBar>
<view class="abs-box flex-col">
<image src="../static/get_coupon_text.png" class="w-184 h-46"></image>
<text class="fs-24 lh-34rpx text--w111-fff pt-20">天天来领券,优惠看的见</text>
</view>
</view>
<view class="relative rd-t-40rpx bg--w111-f5f5f5 w-full content">
<view class="_box flex-between-center text--w111-666 fs-30 lh-42rpx"
:class="pageScrollStatus ? '' : 'rd-t-40rpx'"
:style="{'top': (38 + sysHeight) * 2 + 'rpx'}">
<text :class="current == 0 ? 'font-num fw-500' : ''" @tap="changeTab(0)">默认排序</text>
<view class="flex-y-center" @tap="changeTab(1)">
<text :class="current == 1 ? 'font-num fw-500' : ''">最新</text>
<text v-show="params.timeOrder == 'desc'" class="iconfont icon-ic_down2 fs-14 ml-6 font-num"></text>
<text v-show="params.timeOrder == 'asc'" class="iconfont icon-ic_up2 fs-14 ml-6 font-num"></text>
<text v-show="params.timeOrder == ''" class="iconfont icon-ic_down2 fs-14 ml-6"></text>
<!-- timeOrder -->
</view>
<view class="flex-y-center" @tap="changeTab(2)">
<text :class="current == 2 ? 'font-num fw-500' : ''">价值</text>
<text v-show="params.priceOrder == 'desc'" class="iconfont icon-ic_down2 fs-14 ml-6 font-num"></text>
<text v-show="params.priceOrder == 'asc'" class="iconfont icon-ic_up2 fs-14 ml-6 font-num"></text>
<text v-show="params.priceOrder == ''" class="iconfont icon-ic_down2 fs-14 ml-6"></text>
</view>
<view class="flex-y-center" @tap="showDrop = !showDrop">
<text class="menu_line"></text>
<text>筛选</text>
<text class="iconfont icon-ic_sort pl-8"></text>
</view>
<view class="drop-box bg--w111-f5f5f5" v-if="showDrop">
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-full" show-scrollbar="false">
<view class="inline-block h-52 rd-28rpx px-28 lh-52rpx text-center fs-24 bg--w111-fff mr-24"
v-for="(item, index) in navList" :key="index"
:class="params.type === item.type ? 'active-tab' : ''"
@tap="setType(item.type)">{{item.name}}</view>
</scroll-view>
</view>
</view>
<view class="px-20" v-if="couponsList.length">
<view class="relative card-item" v-for="(item,index) in couponsList" :key="index">
<view class="card w-full h-200 bg--w111-fff rd-24rpx p-20 flex justify-between"
:class="{svip: item.category == 2}">
<text class="pr-8 svip-cup" v-if="item.category == 2">svip</text>
<view class="flex">
<easy-loadimage
mode="aspectFit"
:image-src="item.products[0].image"
width="160rpx"
height="160rpx"
borderRadius="16rpx" v-if="item.products[0] && item.products[0].image"></easy-loadimage>
<view class="w-160 h-160 rd-16rpx flex-center fs-22 text--w111-999" v-else>暂无商品</view>
<view class="w-338 pl-24">
<view class="w-286 h-72 lh-36rpx line2 fw-500" :class="item.is_use ? 'text--w111-ccc' : ''">
{{item.title}}</view>
<view class="fs-20 lh-28rpx mt-8" :class="item.is_use ? 'text--w111-ccc' : 'text--w111-666'"
v-if="item.coupon_time">领取后{{item.coupon_time}}天内可用</view>
<view class="fs-20 lh-28rpx mt-8" :class="item.is_use ? 'text--w111-ccc' : 'text--w111-666'"
v-else>{{ item.start_time ? item.start_time + '-' : '' }}{{ item.end_time }}</view>
<view class="flex-y-center fs-20 text--w111-999 lh-28rpx mt-20">
<text>{{item.type | typeFilter}}</text>
<view v-show="item.rule" @tap="toggleRule(item)">
<text class="pl-8"> | 查看用券规则</text>
<text class="iconfont icon-ic_downarrow fs-20 ml-4"></text>
</view>
</view>
</view>
</view>
<view class="flex-1 flex-col flex-center">
<baseMoney
:money="item.coupon_price"
symbolSize="28"
integerSize="44"
decimalSize="28"
:color="item.is_use ? '#cccccc' : item.receive_type === 4 ? '#333' : 'var(--view-theme)'"
isCoupon
v-if="item.coupon_type==1"></baseMoney>
<view v-else class="fs-44 SemiBold"
:style="{color: item.is_use ? '#cccccc' : item.receive_type === 4 ? '#333' : 'var(--view-theme)'}"
>{{ parseFloat(item.coupon_price) / 10 }} <text class="pingfang fs-28 pl-4">折</text></view>
<text class="fs-20 lh-28rpx mt-8"
:class="item.is_use ? 'text--w111-ccc' : 'font-num'" v-show="item.use_min_price == 0">无门槛券</text>
<text class="fs-20 lh-28rpx mt-8"
:class="item.is_use ? 'text--w111-ccc' : 'font-num'" v-show="item.use_min_price != 0">满{{item.use_min_price}}可用</text>
<view class="w-128 h-48 rd-30rpx flex-center fs-20 bg-hui text--w111-fff mt-16" v-if="item.is_use == true">已领取</view>
<view class="w-128 h-48 rd-30rpx flex-center fs-20 bg-hui text--w111-fff mt-16" v-else-if="item.is_use == 2">已领完</view>
<view class="w-128 h-48 rd-30rpx flex-center fs-20 bg-gradient text--w111-fff mt-16" v-else
@tap="getCoupon(item, index)">立即领取</view>
</view>
</view>
<view class="rule-desc" v-html="item.rule" v-show="item.ruleShow"></view>
</view>
</view>
<view class='loadingicon flex-center' v-if="couponsList.length">
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<view class="px-20" v-if="!couponsList.length">
<emptyPage title="暂无优惠券,去看点别的吧~" src="/statics/images/noCoupon.gif"></emptyPage>
</view>
</view>
<view class="mask" v-if="showDrop" @tap="showDrop = false"></view>
<home></home>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getCoupons, setCouponReceive } from '@/api/api.js';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import colors from '@/mixins/color.js';
import {HTTP_REQUEST_URL} from '@/config/app';
export default {
mixins:[colors],
components:{ emptyPage, NavBar },
data() {
return {
sysHeight:sysHeight,
couponsList: [],
loading: false,
loadend: false,
loadTitle: '加载更多', //提示语
params:{
page: 1,
limit: 20,
type: '',
defaultOrder: 1,
timeOrder: '',
priceOrder: ''
},
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
navList: [
{name: '全部',type: ''},
{name: '快过期',type: -1},
{name: '通用券',type: 0},
{name: '品类券',type: 1},
{name: '商品券',type: 2},
{name: '品牌券',type: 3},
],
count: 0,
imgHost:HTTP_REQUEST_URL,
pageScrollStatus:false,
showDrop: false,
current:0,
price: 0,
};
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getUseCoupons();
}
},
deep: true
},
},
computed:{
...mapGetters(['isLogin']),
headerBg(){
return 'url('+this.imgHost+'/statics/images/get_coupon_bg.png'+')' + 'no-repeat center center/100% 100%, linear-gradient(90deg, var(--view-gradient) 0%, var(--view-theme) 100%)'
}
},
filters:{
typeFilter(val){
let obj = {
0: '通用券',
1: '品类券',
2: '商品券',
3: '品牌券',
};
return obj[val]
}
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
if (this.isLogin) {
this.getUseCoupons();
} else {
toLogin()
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
this.getUseCoupons();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '领券中心',
path: '/pages/activity/coupon/index?spid=' + that.$store.state.app.uid,
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '领券中心',
path: '/pages/activity/coupon/index?spid=' + + that.$store.state.app.uid,
// desc: ''
};
},
//#endif
methods: {
changeTab(val){
this.current = val;
if(val == 0){
this.params.defaultOrder = 1;
this.params.timeOrder = '';
this.params.priceOrder = '';
}else if(val == 1){
if(this.params.timeOrder == '') {
this.params.timeOrder = 'asc'
}else if (this.params.timeOrder == 'asc'){
this.params.timeOrder = 'desc'
}else if(this.params.timeOrder == 'desc'){
this.params.timeOrder = ''
}
this.params.defaultOrder = '';
this.params.priceOrder = '';
} else if(val == 2){
if(this.params.priceOrder == '') {
this.params.priceOrder = 'asc'
}else if (this.params.priceOrder == 'asc'){
this.params.priceOrder = 'desc'
}else if(this.params.priceOrder == 'desc'){
this.params.priceOrder = ''
}
this.params.defaultOrder = '';
this.params.timeOrder = '';
}
this.couponsList = [];
this.loadend = false;
this.loading = false;
this.params.page = 1;
this.getUseCoupons();
},
toggleRule(item){
item.ruleShow = !item.ruleShow
},
backPage(){
uni.navigateBack()
},
goDetails(item){
uni.navigateTo({
url: '/pages/goods_details/index?id=' + item.id
})
},
getCoupon: function(item, index) {
let that = this;
let list = that.couponsList;
//领取优惠券
setCouponReceive(item.id).then(function(res) {
if(res.data.receive_count >= item.receive_limit){
list[index].is_use = true;
}
that.$set(that, 'couponsList', list);
that.$util.Tips({
title: '领取成功'
});
}).catch(error => {
return that.$util.Tips({
title: error
});
})
},
/**
* 获取领取优惠券列表
*/
getUseCoupons: function() {
let that = this
if (this.loadend) return false;
if (this.loading) return false;
that.loading = true;
that.loadTitle = '加载更多';
getCoupons(this.params).then(res => {
let list = res.data.list,
loadend = list.length < that.params.limit,
countIndex = [];
list.map(item=>{
this.$set(item,'ruleShow',false);
})
let couponsList = that.$util.SplitArray(list, that.couponsList);
that.$set(that, 'couponsList', couponsList);
that.loadend = loadend;
that.loading = false;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.params.page++;
}).catch(err => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
setType(type) {
if (this.params.type !== type) {
this.params.type = type;
}else{
this.params.type = '';
}
this.params.page = 1;
this.couponsList = [];
this.loadend = false;
this.showDrop = false;
this.getUseCoupons();
}
}
};
</script>
<style scoped lang="scss">
.abs-box{
width: 264rpx;
position: absolute;
left: 48rpx;
bottom: 80rpx;
}
.content{
top: -44rpx;
}
.menu_line {
width: 1rpx;
height: 26rpx;
background: #ccc;
margin: 0 32rpx 0 20rpx;
}
._box{
padding: 28rpx 32rpx;
background: #f5f5f5;
position: sticky;
z-index: 99;
}
.drop-box{
width: 100%;
// height: 102rpx;
position: absolute;
left: 0;
top: 94rpx;
border-radius: 0 0 40rpx 40rpx;
z-index: 199;
padding: 10rpx 32rpx 24rpx;
}
.active-tab{
background: var(--view-minorColorT);
color: var(--view-theme);
border: 1px solid var(--view-theme);
}
.svip .font-num{
color: #333333 !important;
}
.svip .bg-gradient{
background: linear-gradient(90deg, #584834 0%, #32302D 100%);
color: #FACC7D;
}
.bg-hui{
color: #ffffff !important;
background: #cccccc !important;
}
.indent{
text-indent: 60rpx;
}
.card{
background-image:
radial-gradient(circle at 500rpx top, #f5f5f5, #f5f5f5 10rpx, transparent 11rpx),
radial-gradient(circle at 500rpx bottom, #f5f5f5, #f5f5f5 10rpx, transparent 11rpx);
position: relative;
&:before{
content: '';
position: absolute;
left: 500rpx;
top: 16rpx;
height: 168rpx;
border-left: 2px dotted #ddd;
}
.name {
width: 286rpx;
height: 80rpx;
line-height: 40rpx;
color: #333;
font-weight: 500;
font-size: 28rpx;
}
.type-tag{
display: inline-block;
background: var(--view-minorColorT);
color: var(--view-theme);
border-radius: 14rpx;
padding: 2rpx 10rpx;
font-size: 20rpx;
margin-right: 8rpx;
vertical-align: middle;
}
}
.card-item ~ .card-item{
margin-top: 20rpx;
}
.rule-desc{
margin-top: -16rpx;
padding: 40rpx 24rpx 24rpx;
white-space: pre-wrap;
font-size: 20rpx;
line-height: 28rpx;
background: linear-gradient(180deg, #F7F7F7 0%, #FFFFFF 100%);
border-radius: 0 0 24rpx 24rpx;
color: #999;
}
.SemiBold{
font-family: 'SemiBold'
}
.pingfang{
font-family: PingFang SC, PingFang SC;
}
.svip-cup{
position: absolute;
left: 0;
top: 0;
border-radius: 20rpx 0 20rpx 0;
background-color: #FFD700;
color: #fff;
font-size: 24rpx;
padding-left: 10rpx;
z-index: 1;
}
</style>

View File

@@ -0,0 +1,91 @@
<template>
<view class="container">
<view class="bg-card" :style="{backgroundImage:headerBg}"></view>
<view class="bg--w111-fff rd-24rpx form-card">
<!-- <view class="fs-30 fw-500 lh-42rpx text-center">卡券兑换</view> -->
<view class="w-full bg--w111-f9f9f9 rd-12rpx pl-24 mt-38">
<input type="text" v-model="cardForm.card_number" placeholder="请输入卡号"
placeholder-class="fs-30 text--w111-b3b3b3" class="w-full h-88 fs-30 lh-42rpx" />
</view>
<view class="w-full bg--w111-f9f9f9 rd-12rpx pl-24 mt-32">
<input type="text" v-model="cardForm.card_pwd" placeholder="请输入密码"
placeholder-class="fs-30 text--w111-b3b3b3" class="w-full h-88 fs-30 lh-42rpx" />
</view>
<button class="w-full h-88 rd-44rpx flex-center text--w111-fff bg-btn fs-28 mt-54" :disabled="disabled" @tap="exchangeConfirm">立即验证</button>
</view>
</view>
</template>
<script>
import { giftCardGetInfoApi } from "@/api/activity.js";
import { HTTP_REQUEST_URL } from '@/config/app';
import { mapState, mapGetters } from 'vuex';
import { toLogin } from '@/libs/login.js';
export default {
name: "",
data(){
return {
cardForm:{
card_number:"",
card_pwd: ""
},
disabled: false
}
},
computed:{
...mapGetters(['isLogin']),
headerBg(){
return 'url('+ HTTP_REQUEST_URL +'/statics/images/activity/gift_bg.png'+')'
}
},
onLoad() {
},
methods:{
exchangeConfirm(){
if(this.isLogin){
giftCardGetInfoApi(this.cardForm).then(res=>{
this.disabled = false;
uni.navigateTo({
url: "/pages/activity/giftCard/info?card_number=" + this.cardForm.card_number + '&card_pwd=' + this.cardForm.card_pwd
})
}).catch(err=>{
this.disabled = false;
return this.$util.Tips({
title: err
})
})
}else{
toLogin();
}
}
}
}
</script>
<style>
.form-card uni-button[disabled] {
background: #cccccc;
color: #fff;
}
.container{
height: 100vh;
background: #FFEED8;
}
.bg-card{
height: 648rpx;
background-size: 100% 648rpx;
background-repeat: no-repeat;
}
.form-card{
width: 670rpx;
height: 532rpx;
position: fixed;
top: 392rpx;
left: 42rpx;
z-index: 10;
padding: 40rpx 40rpx 60rpx;
}
.bg-btn{
background: linear-gradient( 90deg, #FF7931 0%, #E93323 100%);
}
</style>

View File

@@ -0,0 +1,274 @@
<template>
<view>
<view class="p-20">
<view class="relative">
<image class="w-full h-400 rd-24rpx block" mode="aspectFill" :src="cardInfo.cover_image"></image>
<view class="gift-badge px-14 rd-40rpx flex-center z-10">
<text class="iconfont icon-ic_card3 fs-32 text-yellow" v-show="cardInfo.type == 1"></text>
<text class="iconfont icon-ic_gift2 fs-32 text-red" v-show="cardInfo.type == 2"></text>
<text class="fs-24 pl-8" v-show="cardInfo.type == 1">{{cardInfo.balance}}元礼品卡</text>
<text class="fs-24 pl-8" v-show="cardInfo.type == 2">兑换卡</text>
</view>
</view>
<view class="w-full bg--w111-fff rd-16rpx px-24 mt-20" v-if="cardInfo.type == 2">
<view class="flex-between-center pt-32">
<view class="fs-28">可兑换商品
<text class="fs-24 text--w111-999 pl-12" v-if="cardInfo.exchange_type == 1">该兑换卡可兑换以下商品</text>
<text class="fs-24 text--w111-999 pl-12" v-else>任选 <text class="Regular text-red">{{ cardInfo.gift_num }}</text> 件兑换</text>
</view>
<text class="fs-28" v-if="cardInfo.exchange_type == 2">
<text class="text-red">{{ totalLimitNum }}</text> /{{cardInfo.gift_num}}
</text>
</view>
<view class="pb-32 product-box">
<view class="mt-24 flex" v-for="(item, index) in cardInfo.product" :key="index">
<image class="block w-200 h-200 rd-16rpx" :src="item.image"></image>
<view class="flex-1 h-200 flex-col justify-between pl-20">
<view>
<view class="w-444 line2 fs-28 h-80 lh-40rpx">{{ item.store_name }}</view>
<view class="inline-block max-w-444 h-38 lh-38rpx mt-8 bg--w111-f5f5f5 text--w111-999 rd-20rpx px-12 fs-22 line1">
{{ item.suk }}
</view>
</view>
<view class="flex-between-center">
<baseMoney :money="item.price"
symbolSize="24"
integerSize="36"
decimalSize="24"
color="#e93323"
weight></baseMoney>
<text class='Regular fs-28' v-if="cardInfo.exchange_type == 1">x{{ item.limit_num }}</text>
<view class="flex-y-center" v-else>
<button class="w-44 h-44 flex-center"
:disabled="item.limit_num <= 0"
@click="decreaseLimitNum(index)">
<text class="iconfont icon-ic_Reduce fs-24"></text>
</button>
<view class='w-88 h-44 text-center lh-44rpx bg--w111-f5f5f5'>{{ item.limit_num }}</view>
<button class="w-44 h-44 flex-center"
:disabled="totalLimitNum >= cardInfo.gift_num"
@click="increaseLimitNum(index)">
<text class="iconfont icon-ic_increase fs-24"></text>
</button>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="w-full bg--w111-fff rd-16rpx p-24 mt-20 fs-28 lh-42rpx">
<view class="pb-20" v-if="cardInfo.type == 1">储值金额<text class="fs-26 text--w111-666 pl-16">¥{{cardInfo.balance}}</text></view>
<view>有效期至:<text class="fs-26 text--w111-666 pl-16">{{ cardInfo.valid_type == 1 ? '永久有效' : cardInfo.fixed_time[1] }}</text></view>
</view>
<view class="w-full bg--w111-fff rd-16rpx px-24 mt-20">
<view class="fs-28 pt-32">使用须知</view>
<view class="pt-12 fs-26 text--w111-666 lh-36rpx space-line pb-32">{{ cardInfo.instructions }}</view>
</view>
<view class="w-full bg--w111-fff rd-16rpx px-24 mt-20">
<view class="fs-28 pt-32">礼品卡详情</view>
<view class="pt-12 fs-26 text--w111-666 lh-36rpx space-line pb-32" v-html="cardInfo.description"></view>
</view>
<view class="h-200"></view>
</view>
<view class="fixed-lb w-full pb-safe bg--w111-fff z-99">
<view class="w-full h-108 flex-between-center px-20">
<button class="btn-box w-full h-72 rd-40rpx flex-center fs-26 text--w111-fff"
:disabled="disabled"
@tap="exchangeGift">确认兑换</button>
</view>
</view>
<uni-popup ref="popup">
<view class="">
<view class="gift_pop bg--w111-fff relative">
<image class="header-pic" :src="imgHost + '/statics/images/activity/gift_open_pic.png'"></image>
<view class="success-text">
<view class="text-center text-red fs-34 fw-500 lh-48rpx">成功到账</view>
<view class="text-center fs-26 lh-36rpx pt-24">{{cardInfo.balance}}元已储值到您的账户中</view>
<view class="flex-x-center mt-54">
<view class="btn-box w-280 h-80 rd-40rpx flex-center fs-28 text--w111-fff" @tap="toMoney">去看看</view>
</view>
</view>
</view>
<view class="flex-center mt-94">
<text class="iconfont icon-ic_close1 text--w111-fff fs-50" @tap="closeGift"></text>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { giftCardGetInfoApi, giftCardReceiveApi } from "@/api/activity.js";
import { HTTP_REQUEST_URL } from '@/config/app';
export default{
name:"",
data(){
return {
cardForm:{
card_number:"",
card_pwd: ""
},
cardInfo: {
id: "", //自增ID
name: "", //礼品卡名称
fixed_time: [],
type: 1, //礼品卡类型 1-储值卡 2-兑换卡
batch_id: "", //关联卡密
total_num: 1, //总数量
instructions: "", //使用说明
cover_image: "", //封面图
valid_type: 1, //有效期类型 1-永久有效 2-固定时间
status: 1, //礼品卡状态 0-禁用 1-启用
balance: 0, //储值金额
exchange_type: 1, //'兑换商品类型 1-固定商品打包 2-任选N件商品'
gift_num: 1, //兑换商品数量
description: "",
product: [], //兑换商品
},
disabled: false,
imgHost: HTTP_REQUEST_URL,
}
},
computed: {
totalLimitNum() {
return this.cardInfo.product.reduce((sum, item) => sum + item.limit_num, 0);
}
},
onLoad(options) {
this.cardForm.card_number = options.card_number;
this.cardForm.card_pwd = options.card_pwd;
if(options.card_number && options.card_pwd){
this.getInfo();
}
},
methods:{
getInfo(){
giftCardGetInfoApi(this.cardForm).then(res=>{
this.cardInfo = res.data;
this.cardInfo.description = res.data.description.replace(/<img/gi, '<img style="max-width: 100%;display:block;"');
uni.setNavigationBarTitle({
title: options.type == 1 ? '兑换礼金' : '兑换礼品'
})
}).catch(err=>{
return this.$util.Tips({
title: err
})
})
},
exchangeGift(){
if(this.cardInfo.exchange_type == 2){
if(this.totalLimitNum != this.cardInfo.gift_num) {
return this.$util.Tips({
title: "请检查兑换数量"
})
}
let product = this.cardInfo.product.
filter(item => item.limit_num !== 0).map(item=>{
return {
product_id: item.product_id,
limit_num: item.limit_num || 0,
unique: item.unique,
}
});
this.$set(this.cardForm,'product',product);
}
this.disabled = true;
giftCardReceiveApi(this.cardForm).then(res=>{
this.disabled = false;
if(this.cardInfo.type == 1){
this.$refs.popup.open();
}else{
let cardId = res.data.map(item=> item.cartId).join(",");
uni.navigateTo({
url: "/pages/goods/order_confirm/index?cartId=" + cardId + "&new=1"
})
}
}).catch(err=>{
this.disabled = false;
return this.$util.Tips({
title: err
})
})
},
toMoney(){
this.$refs.popup.close();
uni.redirectTo({
url: "/pages/users/user_bill/index?type=2"
})
},
closeGift(){
this.$refs.popup.close();
},
increaseLimitNum(index) {
if (this.totalLimitNum < this.cardInfo.gift_num) {
this.cardInfo.product[index].limit_num += 1;
}
},
decreaseLimitNum(index) {
if (this.cardInfo.product[index].limit_num > 0) {
this.cardInfo.product[index].limit_num -= 1;
}
}
}
}
</script>
<style lang="scss">
.product-box uni-button[disabled], .product-box button[disabled]{
background-color: #fff;
}
.fixed-lb uni-button[disabled], .fixed-lb button[disabled] {
background: #cccccc;
color: #fff;
}
.gift-badge{
position: absolute;
top: 24rpx;
left: 24rpx;
height: 46rpx;
background: rgba(255,255,255,0.8);
backdrop-filter: blur(8rpx)
}
.b-d{
border: 1rpx solid #DDDDDD;
}
.btn-box{
background: linear-gradient( 90deg, #E93323 0%, #FF7931 100%);
}
.max-w-444{
max-width: 444rpx;
}
.gift_pop{
width: 480rpx;
height: 500rpx;
border-radius: 48rpx;
.header-pic{
width: 480rpx;
height: 364rpx;
position: absolute;
top: -72rpx;
left: 0;
}
.success-text{
position: absolute;
top: 180rpx;
left: 0;
width: 480rpx;
.text-red{
color: #E93323;
}
}
}
.mt-94{
margin-top: 94rpx;
}
.fs-50{
font-size: 50rpx;
}
.text-red{
color: #e93323;
}
.text-yellow{
color: #FF7700;
}
</style>

View File

@@ -0,0 +1,257 @@
<template>
<!-- 砍价列表模块 -->
<view class="box">
<view class='bargain-list'>
<view class='header' :style="'background-image: url('+imgHost+'/statics/images/bargain-list-bg.png);'">
<NavBar titleText=" "
textSize="34rpx"
bagColor="transparent"
iconColor="#ffffff"
textColor="#ffffff"
showBack></NavBar>
</view>
<view class='list' v-if="bargainList.length">
<block v-for="(item,index) in bargainList" :key="index">
<view class='item flex justify-between relative'
@tap="openSubscribe('/pages/activity/goods_bargain_details/index?id='+ item.id +'&spid='+ userInfo.uid)">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
width="240rpx"
height="240rpx"
borderRadius="20rpx"></easy-loadimage>
<view class='w-410 fs-28 flex-col justify-between'>
<view>
<view class='w-410 lh-40rpx line2'>
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.title}}</view>
<view class='fs-22 fw-500 mt-8 red'>
<text class='iconfont icon-ic_fire fs-22 mr-8'></text>
{{item.people}}人正在参与
</view>
</view>
<view class="flex-between-center">
<view>
<view class='flex items-baseline red'>
<text class="fs-22 lh-30rpx fw-500">最低: </text>
<baseMoney :money="item.min_price" symbolSize="24" integerSize="40" decimalSize="24" incolor="#E93323" weight></baseMoney>
</view>
<view class="otPrice">¥{{item.price}}</view>
</view>
<view class='cutBnt w-144 h-56 rd-30rpx flex-center fs-24 text--w111-fff'>参与砍价</view>
</view>
</view>
</view>
</block>
</view>
<view class="list no-goods" v-if="!bargainList.length && !loading">
<image :src="imgHost + '/statics/images/noActivity.gif'" mode=""></image>
<text class="fs-26 text--w111-999 pt-16">暂无砍价商品,去看看其他商品吧~</text>
</view>
</view>
</view>
</template>
<script>
let app = getApp();
import { HTTP_REQUEST_URL } from '@/config/app';
import { getBargainList } from '@/api/activity.js';
import { openBargainSubscribe } from '@/utils/SubscribeMessage.js';
import { getUserInfo } from '@/api/user.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
export default {
data() {
return {
bargainList: [],
page: 1,
limit: 20,
loading: false,
loadend: false,
userInfo: {},
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
imgHost:HTTP_REQUEST_URL,
// #ifdef MP
getHeight: this.$util.getWXStatusHeight()
// #endif
};
},
components:{ emptyPage, NavBar },
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
// #ifndef MP
this.getUserInfo();
// #endif
}
},
deep: true
}
},
onLoad: function(options) {
this.getBargainList();
if (this.isLogin) {
this.getUserInfo();
}
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods: {
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
goarrow(){
uni.navigateBack()
},
/*
* 获取用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
that.$set(that, 'userInfo', res.data);
});
},
openSubscribe: function(e) {
if(this.isLogin){
let page = e;
// #ifndef MP
uni.navigateTo({
url: page
});
// #endif
// #ifdef MP
uni.showLoading({
title: '正在加载',
})
openBargainSubscribe().then(res => {
uni.hideLoading();
uni.navigateTo({
url: page,
});
}).catch((err) => {
uni.hideLoading();
});
// #endif
}else{
toLogin()
}
},
getBargainList: function() {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
getBargainList({
page: that.page,
limit: that.limit
}).then(function(res) {
that.$set(that, 'bargainList', that.bargainList.concat(res.data));
that.$set(that, 'page', that.page + 1);
that.$set(that, 'loadend', that.limit > res.data.length);
that.$set(that, 'loading', false);
}).catch(res => {
that.loading = false;
});
},
},
onReachBottom: function() {
this.getBargainList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '砍价列表',
path: '/pages/activity/goods_bargain/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/bargain-list-bg.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '砍价列表',
path: '/pages/activity/goods_bargain/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/bargain-list-bg.png',
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss">
.no-goods{
text-align: center;
padding-bottom: 60rpx!important;
color: #999;
image{
width: 440rpx;
height: 360rpx;
margin: 40rpx auto 0 auto;
display: block;
}
}
.bargain-list .header {
background-repeat: no-repeat;
background-size: 100% 100%;
width: 750rpx;
height: 926rpx;
padding-top: 55rpx;
box-sizing: border-box;
.iconfont{
color: #fff;
font-size: 40rpx;
margin-left: 15rpx;
}
}
.bargain-list .list {
background-color: #fff;
border-radius: 24rpx;
margin: -510rpx 20rpx 66rpx 20rpx;
padding: 32rpx 20rpx;
}
.brand-tag{
background-color: #e93323 !important;
}
.item~.item{
margin-top: 40rpx;
}
.red{
color: #E93323;
}
.otPrice{
font-size: 26rpx;
font-family: Regular;
color: #999;
text-decoration: line-through;
margin-top: 4rpx;
}
.cutBnt {
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
.bargain-list .list .load {
font-size: 24rpx;
height: 85rpx;
text-align: center;
line-height: 85rpx;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,266 @@
<template>
<view>
<view class="w-full bg-top relative" :style="{backgroundImage:headerBg}">
<NavBar titleText="拼团活动"
textSize="34rpx"
:isScrolling="pageScrollStatus"
:iconColor="pageScrollStatus ? '#333333' : '#ffffff'"
:textColor="pageScrollStatus ? '#333333' : '#ffffff'"
showBack></NavBar>
</view>
<view class="relative rd-t-40rpx bg--w111-f5f5f5 w-full content">
<view class="" v-if="combinationList.length">
<view class="pt-32 pl-20 pr-20">
<view class="card w-full bg--w111-fff rd-24rpx p-20 flex"
v-for="(item,index) in combinationList" :key="index"
@tap="openSubcribe(item)">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
width="240rpx"
height="240rpx"
borderRadius="20rpx"></easy-loadimage>
<view class="flex-1 h-240 pl-20 flex-col justify-between">
<view class="w-full">
<view class="w-full fs-28 lh-40rpx line2">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.title}}</view>
<view class="flex fs-20 mt-14">
<view class="tuan-num text--w111-fff flex-center">{{item.people}}人团</view>
<view class="complete font-red flex-center">已拼{{item.pink_count}}份</view>
</view>
</view>
<view class="w-full flex-between-center">
<view>
<view class="flex items-baseline">
<text class="fs-22 lh-30rpx font-red fw-500">拼团价:</text>
<baseMoney :money="item.price" symbolSize="24" integerSize="40" decimalSize="24" color="#e93323" weight></baseMoney>
</view>
<view class="text-line text--w111-999 fs-22 lh-30rpx mt-12">¥{{item.product_price}}</view>
</view>
<view class="w-144 h-56 rd-30rpx flex-center fs-24 bg-red text--w111-fff" v-if="item.stock > 0 && item.quota > 0">参与拼团</view>
<view class="w-144 h-56 rd-30rpx flex-center fs-24 bg-gray text--w111-fff" v-else>参与拼团</view>
</view>
</view>
</view>
</view>
</view>
<view class="p-20" v-if="!combinationList.length">
<emptyPage title="暂无拼团商品,去看看其他商品吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
import {
getCombinationList,
getCombinationBannerList,
getPink
} from '@/api/activity.js';
import { openPinkSubscribe } from '@/utils/SubscribeMessage.js';
import {
HTTP_REQUEST_URL
} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
let app = getApp();
export default {
data() {
return {
pinkPeople: [],
pinkCount: 0,
bannerList: [],
circular: true,
autoplay: true,
interval: 3000,
duration: 500,
combinationList: [],
limit: 10,
page: 1,
loading: false,
loadend: false,
isBanner: false,
pageScrollStatus:false,
}
},
components:{ emptyPage, NavBar },
computed:{
headerBg(){
return 'url('+ HTTP_REQUEST_URL +'/statics/images/product/combination_header.png'+')'
}
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
uni.setNavigationBarTitle({
title: "拼团列表"
})
this.getCombinationList();
this.getBannerList();
this.getPink();
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
getPink: function() {
getPink({
type: 2
}).then(res => {
this.pinkPeople = res.data.avatars;
this.pinkCount = res.data.pink_count;
})
},
getBannerList: function() {
getCombinationBannerList().then(res => {
this.bannerList = res.data;
this.isBanner = true;
})
},
goDetail(item) {
let url = item.link;
this.$util.JumpPath(url);
},
openSubcribe: function(item) {
let page = item;
// #ifndef MP
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=3`
});
// #endif
// #ifdef MP
uni.showLoading({
title: '正在加载',
})
openPinkSubscribe().then(res => {
uni.hideLoading();
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=3`
});
}).catch(() => {
uni.hideLoading();
});
// #endif
},
getCombinationList: function() {
var that = this;
if (that.loadend) return;
if (that.loading) return;
var data = {
page: that.page,
limit: that.limit
};
this.loading = true
getCombinationList(data).then(function(res) {
var combinationList = that.combinationList;
var limit = that.limit;
that.page++;
that.loadend = limit > res.data.length;
that.combinationList = combinationList.concat(res.data);
that.page = that.data.page;
that.loading = false;
}).catch(() => {
that.loading = false
})
},
backPage(){
uni.navigateBack()
}
},
onReachBottom: function() {
this.getCombinationList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '拼团列表',
path: '/pages/activity/goods_combination/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/combination_header.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '拼团列表',
path: '/pages/activity/goods_combination/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/combination_header.png',
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss">
.h-470{
height: 470rpx;;
}
.w-624{
width: 624rpx;
}
.active-tab{
width: 132rpx;
height: 52rpx;
background: #FFF8E4;
color: #F85517;
border-radius: 30rpx;
font-weight: 500;
display: flex;
justify-content: center;
align-items: center;
}
.bg-top{
height: 547rpx;
background-size: 100% 100%;
background-repeat: no-repeat;
}
.content{
top: -80rpx;
}
._box{
padding: 40rpx 20rpx 32rpx;
background: #f5f5f5;
position: sticky;
z-index: 99;
}
.font-red{
color: #e93323;
}
.bg-red{
background-color: #e93323;
}
.bg-gray{
background-color: #ccc;
}
.con_border{
border: 1px solid #e93323;
}
.card ~ .card{
margin-top: 20rpx;
}
.tuan-num{
width: 70rpx;
height: 32rpx;
background: #E93323;
border-radius: 8rpx 0 0 8rpx;
}
.complete{
width: 110rpx;
height: 32rpx;
background: rgba(233, 51, 35, 0.1);
border-radius: 0 8rpx 8rpx 0;
}
.brand-tag{
background-color: #e93323 !important;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,437 @@
<template>
<!-- 限时秒杀模块 -->
<view :style="colorStyle">
<!-- #ifdef H5 -->
<view class="w-full bg-top h-604 relative" :style="{backgroundImage:headerBg}">
<!-- #endif -->
<!-- #ifndef H5 -->
<view class="w-full bg-top relative" :style="{backgroundImage:headerBg,height: (sysHeight + 262) * 2 + 'rpx'}">
<!-- #endif -->
<view class="fixed-lt w-full z-20"
:class="pageScrollStatus ? 'sticky' : ''"
:style="{'padding-top': sysHeight + 'px','background': pageScrollStatus ? '#e93323' : 'transparent'}">
<view class="w-full px-20 pl-20 h-80 flex-between-center">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-fff" @click="goPage(3)"></text>
<text class="fs-34 fw-500 text--w111-fff">{{pageScrollStatus ? '限时秒杀' : ''}}</text>
<text></text>
</view>
</view>
</view>
<view class="relative w-full content">
<view class="_box h-106 flex-y-center"
:class="pageScrollStatus ? '' : 'rd-t-24rpx'"
:style="{'top': 50 + sysHeight + 'px'}">
<scroll-view scroll-x="true" scroll-with-animation class="white-nowrap vertical-middle w-full relative z-10"
:class="{'sel1':active == 0,'sel-last': timeList.length > 4 && active == timeList.length - 1}"
show-scrollbar="false">
<view class="scroll-item"
v-for="(item,index) in timeList" :key='index'
:class="active == index ? 'active-card' : ''"
:style="{'background-image': active == index ? navActiveBg : ''}"
@tap='settimeList(item,index)'>
<view class="flex-col flex-center z-10 relative t-22">
<text class="SemiBold fs-40 lh-40rpx"
:class="active == index ? 'text--w111-333':'text--w111-fff'">{{item.time}}</text>
<text class="inline-block h-36 lh-34rpx fs-24"
:class="active == index ? 'red-tag':'text--w111-fff'">{{item.state}}</text>
</view>
</view>
</scroll-view>
<view class="abs-lb w-full"
:style="{'background': pageScrollStatus ? '#e93323' : 'rgba(245,245,245,0.2)','height': pageScrollStatus ? '130rpx' : '96rpx'}"></view>
</view>
<view class="bg--w111-f5f5f5 pt-32 pl-20 pr-20 relative" >
<view class="card w-full bg--w111-fff rd-24rpx p-20 flex" v-for="(item,index) in seckillList" :key="index"
@tap='goDetails(item)'>
<view class="w-240 h-240">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
:border-src="item.activity_image"
width="240rpx"
height="240rpx"
borderRadius="20rpx"></easy-loadimage>
</view>
<view class="flex-1 pl-20 flex-col justify-between">
<view class="w-full">
<view class="w-410 fs-28 lh-40rpx line2">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.title}}</view>
<view class="w-410 flex items-end flex-wrap mt-12" v-if="item.store_label.length">
<BaseTag
:text="label.label_name"
:color="label.color"
:background="label.bg_color"
:borderColor="label.border_color"
:circle="label.border_color ? true : false"
:imgSrc="label.icon"
v-for="(label, idx) in item.store_label" :key="idx"></BaseTag>
</view>
</view>
<view class="flex items-baseline">
<text class="fs-22 lh-30rpx text-primary pr-8">秒杀价:</text>
<baseMoney :money="item.price" symbolSize="24" integerSize="40" decimalSize="24" color="#E93323" weight></baseMoney>
<text class="fs-22 lh-30rpx text--w111-999 pl-16 text-line">¥{{item.ot_price}}</text>
</view>
<view class="w-full progress-box flex-between-center" v-if="status == 1">
<view class="flex-y-center">
<view class="progress ml-16">
<view class="active" :style="'width:'+item.percent+'%;'"></view>
</view>
<text class="fs-22 text-primary pl-8">已抢{{item.percent}}%</text>
</view>
<view class="qiang"></view>
</view>
<view class="w-full yuyue-box flex-between-center" v-else-if="status == 2">
<view class="flex-y-center fs-22 pl-16">活动即将开始</view>
<view class="yuyue"></view>
</view>
<view class="w-full over-box flex-between-center" v-else>
<view class="flex-y-center fs-22 pl-16">活动已结束</view>
<view class="over"></view>
</view>
</view>
</view>
<view class="abs-lt cir" v-show="active > 0"></view>
</view>
<view class="bg--w111-f5f5f5 p-20" v-if="!seckillList.length && !pageloading">
<emptyPage title="暂无秒杀商品,去看看其他商品吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getSeckillIndexTime, getSeckillList } from '@/api/activity.js';
import colors from '@/mixins/color.js'
import {HTTP_REQUEST_URL} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
export default {
components: {
emptyPage
},
mixins:[colors],
data() {
return {
sysHeight:sysHeight,
topImage: '',
seckillList: [],
timeList: [],
active: 5,
scrollLeft: 0,
interval: 0,
status: 1,
countDownHour: "00",
countDownMinute: "00",
countDownSecond: "00",
page: 1,
limit: 8,
loading: false,
loadend: false,
pageloading: false,
intoindex:'',
imgHost:HTTP_REQUEST_URL,
pageScrollStatus: false
}
},
computed:{
headerBg(){
return 'url('+this.imgHost+'/statics/images/product/seckill_header.png'+')'
},
navActiveLeft(){
if(this.active == 0){
return 0
} else if(this.active == 1){
return '134rpx'
} else {
return 154 * this.active + 'rpx'
}
},
navActiveBg(){
if(this.active == 0){
return 'url('+this.imgHost+'/statics/images/product/seckill_header_icon1.png'+')'
}else{
return 'url('+this.imgHost+'/statics/images/product/seckill_header_icon2.png'+')'
}
}
},
onPageScroll(object) {
if (object.scrollTop > 200) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 200) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
this.getSeckillConfig();
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
methods: {
getSeckillConfig: function() {
let that = this;
getSeckillIndexTime().then(res => {
that.topImage = res.data.lovely;
that.timeList = res.data.seckillTime;
that.active = res.data.seckillTimeIndex > -1 ? res.data.seckillTimeIndex : 0 ;
that.$nextTick(()=>{
that.intoindex = 'sort'+res.data.seckillTimeIndex > -1 ? res.data.seckillTimeIndex : 0
})
if (that.timeList.length) {
that.scrollLeft = (that.active - 1.37) * 100
setTimeout(function() {
that.loading = true
}, 2000);
that.seckillList = [],
that.page = 1
that.status = that.timeList[that.active].status
that.getSeckillList();
}
});
},
getSeckillList: function() {
var that = this;
var data = {
page: that.page,
limit: that.limit
};
if (that.loadend) return;
if (that.pageloading) return;
this.pageloading = true
getSeckillList(that.timeList[that.active].id, data).then(res => {
var seckillList = res.data;
var loadend = seckillList.length < that.limit;
that.page++;
that.seckillList = that.seckillList.concat(seckillList),
that.page = that.page;
that.pageloading = false;
that.loadend = loadend;
}).catch(err => {
that.pageloading = false
});
},
settimeList: function(item, index) {
var that = this;
this.active = index
if (that.interval) {
clearInterval(that.interval);
that.interval = null
}
that.interval = 0,
that.countDownHour = "00";
that.countDownMinute = "00";
that.countDownSecond = "00";
that.status = that.timeList[that.active].status;
that.loadend = false;
that.page = 1;
that.seckillList = [];
// wxh.time(e.currentTarget.dataset.stop, that);
that.getSeckillList();
},
goDetails(item){
uni.navigateTo({
url: '/pages/activity/goods_details/index?id=' + item.id + '&type=1&time_id=' + this.timeList[this.active].id
})
},
goPage(type, url){
if(type == 1){
uni.navigateTo({
url
})
}else if(type == 2){
uni.switchTab({
url
})
}else if(type == 3){
uni.navigateBack();
}
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getSeckillList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '秒杀列表',
path: '/pages/activity/goods_seckill/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/seckill_header.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '秒杀列表',
path: '/pages/activity/goods_seckill/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/seckill_header.png',
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss">
.bg-top{
background-size: 100% 100%;
background-repeat: no-repeat;
}
.sticky{
&:after{
content:'';
width:100%;
height: 20px;
background-color: #E93323;
position: absolute;
left: 0;
bottom: -20rpx;
}
}
.content{
top: -114rpx;
}
._box{
position: sticky;
z-index: 99;
}
.card ~ .card{
margin-top: 20rpx;
}
.w-21-p111-{
width: 21%;
}
.max-w-96{
max-width: 96rpx;
}
.fq{
background-color: #E93323;
color: #fff;
}
.text-primary{
color: #E93323;;
}
.text-line{
text-decoration: line-through;
}
.progress-box{
height: 64rpx;
background-color: rgba(233, 51, 35, 0.05);
border-radius: 16rpx;
}
.progress{
width:160rpx;
height: 18rpx;
border-radius: 10rpx;
background-color: rgba(233, 51, 35, 0.2);
.active{
height: 18rpx;
border-radius: 10rpx;
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
}
.qiang{
width:112rpx;
height: 64rpx;
background-image: url('../static/qiang.png');
background-size: cover;
}
.yuyue-box{
height: 64rpx;
background-color: #FFF1E5;
border-radius: 16rpx;
color: #FF7D00;
}
.yuyue{
width:140rpx;
height: 64rpx;
background-image: url('../static/yuyue.png');
background-size: cover;
}
.over-box{
height: 64rpx;
background-color: rgba(233, 51, 35, 0.05);
border-radius: 16rpx;
color: rgba(233, 51, 35, 0.60);
}
.over{
width:140rpx;
height: 64rpx;
background-image: url('../static/over.png');
background-size: cover;
}
.sel1 .scroll-item{
right: 30rpx;
}
.sel-last {
/deep/.uni-scroll-view{
margin-right: -10rpx;
}
.scroll-item{
// left: 40rpx;
// left: 32rpx;
}
.active-card{
width: 180rpx;
padding-left: 10px;
.relative{
width: 160rpx;
}
}
}
.scroll-item{
display: inline-block;
height: 96rpx;
width: 21%;
position: relative;
bottom: 0;
}
.active-card{
width:234rpx;
height: 106rpx;
background-size: cover;
z-index: 99;
}
.t-22{
top: 22rpx;
}
.red-tag{
display: inline-block;
padding: 0 12rpx;
height: 36rpx;
border-radius: 18rpx;
text-align: center;
line-height: 36rpx;
background-color: #E93323;
font-size: 22rpx;
color: #fff;
}
.cir{
width: 24rpx;
height: 24rpx;
background-color: #ED593E;
&:after{
content: '';
width: 24rpx;
height: 24rpx;
position: absolute;
left: 0;
top: 0;
border-top-left-radius: 100%; /* 左上角为半径大小的弧形 */
background-color: #f5f5f5;
}
}
.brand-tag{
background-color: #e93323 !important;
}
</style>

View File

@@ -0,0 +1,334 @@
<template>
<view>
<!-- #ifdef H5 -->
<view class="bg-top h-644" :style="{'background-image' : headerBg}">
<!-- #endif -->
<!-- #ifndef H5 -->
<view class="bg-top" :style="{'height': 282 + sysHeight + 'px', 'background-image' : headerBg}">
<!-- #endif -->
<NavBar titleText="新人礼"
textSize="34rpx"
:isScrolling="pageScrollStatus"
:iconColor="pageScrollStatus ? '#333333' : '#ffffff'"
:textColor="pageScrollStatus ? '#333333' : '#ffffff'"
showBack></NavBar>
<view class="rule-btn px-12 flex-center fs-24 text--w111-fff z-999"
:style="{top: 110 + sysHeight + 'px'}"
@tap="goAgree">新人礼规则</view>
</view>
<view class="px-20">
<view class="bg--w111-fff rd-24rpx pt-32 pr-24 pb-32 pl-24 relative top200"
v-if="info.register_give_coupon ? info.register_give_coupon.length : false">
<view class="flex-center">
<image src="../static/new_person_star.png" class="star"></image>
<text class="fs-32 lh-44rpx fw-500 px-16">新人优惠券</text>
<image src="../static/new_person_star.png" class="star star-right"></image>
</view>
<view class="grid-column-3 grid-gap-38rpx mt-36">
<view class="coupon-item flex-col flex-between-center"
v-for="(item,index) in showMore ? info.register_give_coupon : info.register_give_coupon.slice(0,6)" :key="index">
<view class="flex-col flex-center">
<baseMoney :money="item.coupon_price" symbolSize="28" integerSize="44"
decimalSize="28" color="#e93323" weight v-if="item.coupon_type==1"></baseMoney>
<view v-else class="font-red fs-32 flex-y-center"><text class="SemiBold fs-44">{{parseFloat(item.coupon_price)/10}}</text>折</view>
<text class="fs-20 lh-28rpx font-red pt-6">{{item.applicable_type | typeFilter}}</text>
</view>
<view class="fs-24 lh-34rpx text--w111-fff" v-if="item.use_min_price > 0">满{{item.use_min_price}}可用</view>
<view class="fs-24 lh-34rpx text--w111-fff" v-else>无门槛</view>
</view>
</view>
<view class="w-full mt-24 flex-center fs-24 text--w111-999"
v-if="info.register_give_coupon.length > 6" @tap="showMoreChange">
<text>{{showMore ? '点击收起' : '点击展开'}}</text>
<text class="iconfont fs-24" :class="showMore ? 'icon-ic_uparrow' : 'icon-ic_downarrow'"></text>
</view>
<view class="w-full h-88 rd-44rpx flex-center bg-jianbian text--w111-fff fs-28 mt-32"
@tap="goPage('/pages/users/user_coupon/index',1)">查看优惠券</view>
</view>
<view class="bg--w111-fff rd-24rpx pt-32 pr-24 pl-24 relative top200 mt-20">
<view class="flex-center">
<image src="../static/new_person_star.png" class="star"></image>
<text class="fs-32 lh-44rpx fw-500 px-16">新人福利</text>
<image src="../static/new_person_star.png" class="star star-right"></image>
</view>
<view class="mt-10">
<view class="cell flex-between-center py-32" v-if="info.register_give_integral > 0">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/newcomer/integral_icon.png'" class="w-72 h-72"></image>
<view class="flex-col ml-24">
<text class="fs-28 fw-500 lh-40rpx">新人赠送积分</text>
<text class="fs-22 text--w111-999 lh-30rpx pt-6">新人即可获得{{info.register_give_integral}}积分</text>
</view>
</view>
<view class="w-120 h-56 rd-28rpx flex-center bg-jianbian text--w111-fff fs-24"
@tap="goPage('/pages/users/user_integral/index',1)">去查看</view>
</view>
<view class="cell flex-between-center py-32" v-if="info.register_give_money > 0">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/newcomer/money_icon.png'" class="w-72 h-72"></image>
<view class="flex-col ml-24">
<text class="fs-28 fw-500 lh-40rpx">新人赠送余额</text>
<text class="fs-22 text--w111-999 lh-30rpx pt-6">新人即可获得{{info.register_give_money}}余额</text>
</view>
</view>
<view class="w-120 h-56 rd-28rpx flex-center bg-jianbian text--w111-fff fs-24"
@tap="goPage('/pages/users/user_money/index',1)">去查看</view>
</view>
<view class="cell flex-between-center py-32" v-if="info.first_order_status">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/newcomer/coupon_icon.png'" class="w-72 h-72"></image>
<view class="flex-col ml-24">
<text class="fs-28 fw-500 lh-40rpx">新人下单享首单优惠</text>
<text class="fs-22 text--w111-999 lh-30rpx pt-6">首次下单享{{parseFloat(info.first_order_discount)/10 || 10}}折优惠哦~</text>
</view>
</view>
<view class="w-120 h-56 rd-28rpx flex-center bg-jianbian text--w111-fff fs-24"
@tap="goPage('/pages/goods/goods_list/index',1)">去查看</view>
</view>
</view>
</view>
<view class="bg--w111-fff rd-24rpx pt-32 pr-24 pb-32 pl-24 relative top200 mt-20"
v-if="newList.length">
<view class="flex-center">
<image src="../static/new_person_star.png" class="star"></image>
<text class="fs-32 lh-44rpx fw-500 px-16">新人商品专区</text>
<image src="../static/new_person_star.png" class="star star-right"></image>
</view>
<view class="grid-column-3 grid-gap-20rpx mt-36">
<view class="" v-for="(item,index) in newList" :key="index"
@click="goPage(`/pages/activity/goods_details/index?id=${item.id}&type=7`,1)">
<image class="w-full h-210 rd-16rpx" :src="item.image" mode="aspectFit"></image>
<view class="w-full line2 fs-28 lh-40rpx fw-500 mt-24 mb-14">{{item.store_name}}</view>
<baseMoney :money="item.price" symbolSize="24" integerSize="40"
decimalSize="24" color="#e93323" weight></baseMoney>
</view>
</view>
</view>
</view>
<base-drawer mode="bottom" :visible="showDrawer" background-color="transparent" mask maskClosable @close="goAgree">
<view class="w-full bg--w111-fff rd-t-40rpx py-32 relative">
<view class="text-center fs-32 text--w111-333 fw-500">新人礼规则</view>
<view class="close flex-center" @tap='goAgree'>
<text class="iconfont icon-ic_close fs-24 text--w111-999"></text>
</view>
<view class="mt-48 px-32 scroll-content">
<!-- #ifdef MP-WEIXIN -->
<rich-text :nodes="rule"></rich-text>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view v-html="rule"></view>
<!-- #endif -->
</view>
<view class="mx-20 pb-safe">
<view class="mt-52 h-72 flex-center rd-36px bg-red fs-26 text--w111-fff" @click="goAgree">我知道了</view>
</view>
</view>
</base-drawer>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import countDown from '@/components/countDown';
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
import NavBar from "@/components/NavBar.vue"
import {
newcomerInfo,
newcomerList
} from '@/api/activity.js';
import { getUserAgreement } from "@/api/user.js"
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import {HTTP_REQUEST_URL} from '@/config/app';
export default {
components: {
countDown,
NavBar,
baseDrawer
},
data() {
return {
sysHeight:sysHeight,
imgHost:HTTP_REQUEST_URL,
info: {
// register_give_coupon:[
// {coupon_price: 20,type:1,coupon_type:1},
// {coupon_price: 20,type:1,coupon_type:1},
// {coupon_price: 20,type:1,coupon_type:1},
// ]
},
newList:[],
loading: false,
loadend: false,
loadTitle: '加载更多',
page: 1,
limit: 9,
showMore: false,
pageScrollStatus:false,
rule:'',
showDrawer:false
};
},
filters:{
typeFilter(val){
let obj = {
0: '通用券',
1: '品类券',
2: '商品券',
3: '品牌券',
};
return obj[val]
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getNewcomerInfo();
this.productList();
}
},
deep: true
},
},
computed:{
...mapGetters(['isLogin']),
headerBg(){
return 'url('+this.imgHost+'/statics/images/newcomer/header.png'+')'
}
},
onLoad() {
if (this.isLogin) {
this.getNewcomerInfo();
this.productList();
this.getAgreeContent();
} else {
toLogin()
}
},
onPageScroll(object) {
if (object.scrollTop > 80) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 80) {
this.pageScrollStatus = false;
}
},
methods: {
goAgree(){
this.showDrawer = !this.showDrawer;
},
getAgreeContent(){
getUserAgreement('newcomer_agreement').then((res) => {
this.rule = res.data.content;
})
.catch((err) => {
that.$util.Tips({
title: err.msg
});
});
},
getNewcomerInfo() {
newcomerInfo().then(res => {
res.data.last_time = parseInt(res.data.last_time);
this.info = res.data;
}).catch(err => {
this.$util.Tips({
title: err
});
})
},
productList() {
let that = this;
if (that.loading) return;
if (that.loadend) return;
that.loading = true;
that.loadTitle = '';
newcomerList({
page: that.page,
limit: that.limit
}).then(res=>{
let list = res.data;
let loadend = list.length < that.limit;
that.newList = that.$util.SplitArray(list, that.newList);
that.$set(that, 'newList', that.newList);
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
that.loadTitle = '加载更多';
this.$util.Tips({
title: err
});
})
},
goPage(url, type){
if(type == 1){
uni.navigateTo({
url
})
}else if(type == 3){
uni.navigateBack()
}
},
showMoreChange(){
this.showMore = !this.showMore;
}
},
onReachBottom() {
this.productList();
}
}
</script>
<style lang="scss">
/deep/ .navbar{
z-index: 90;
}
.bg-top{
background-size: cover;
}
.rule-btn{
height: 48rpx;
background: rgba(0,0,0,0.3);
border-radius: 24rpx 0 0 24rpx;
position: fixed;
right: 0;
z-index: 20;
}
.close{
position: absolute;
right: 32rpx;
top: 36rpx;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #eee;
}
.top200{
top: -200rpx;
}
.star{
width: 54rpx;
height: 24rpx;
}
.star-right{
display: block;
transform: scaleX(-1);
}
.coupon-item{
height: 186rpx;
padding: 20rpx 0 18rpx;
background-image: url('../static/coupon_item_bg.png');
background-size: cover;
}
.font-red{
color: #E93323;
}
.bg-jianbian{
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
.cell ~ .cell{
border-top: 1px solid #eee;
}
</style>

View File

@@ -0,0 +1,513 @@
<template>
<view :style="colorStyle">
<NavBar titleText="积分商城"
textSize="34rpx"
bagColor="linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%)"
iconColor="#ffffff"
textColor="#ffffff"
showBack></NavBar>
<view class="header">
<view class="headerBg">
<view class="pictrue">
<image src="../static/mall03.png"></image>
</view>
<view class="num">当前积分{{integral}}</view>
</view>
<navigator hover-class='none' url='/pages/goods/order_list/index?type=4' class="record acea-row row-center-wrapper">兑换记录</navigator>
</view>
<view class="nav acea-row row-middle row-around">
<navigator hover-class='none' url='/pages/users/user_integral/index' class="item">
<view class="pictrue">
<image src="../static/mall05.png"></image>
</view>
<view>我的积分</view>
</navigator>
<view class="line"></view>
<navigator hover-class='none' url='/pages/users/user_sgin/index' class="item">
<view class="pictrue">
<image src="../static/mall04.png"></image>
</view>
<view>每日签到</view>
</navigator>
<view class="line"></view>
<navigator hover-class='none' url='/pages/goods/lottery/grids/index?type=1' class="item">
<view class="pictrue">
<image src="../static/mall02.png"></image>
</view>
<view>积分抽奖</view>
</navigator>
</view>
<view class="hot" v-if="goodList.length">
<view class="title">热门推荐</view>
<scroll-view scroll-x="true" class="scroll">
<view class="scroll-item" v-for="(item,index) in goodList" :key="index" @click="goGoodsDetail(item)">
<view class="pictrue">
<image :src='item.image' mode="aspectFit"></image>
</view>
<view class="name line1">{{item.title}}</view>
<view class="info">已有{{item.sales}}人兑换</view>
<view class="price-box acea-row row-middle">
<view class="acea-row row-middle" v-if="parseFloat(item.integral)">
<image src="../static/mall05.png"></image>
<text class="font-num">{{ item.integral }}</text>
</view>
<text v-if="parseFloat(item.integral) && parseFloat(item.price)">+</text>
<text v-if="parseFloat(item.price)">
<text class="font-num">{{ item.price }}</text>
<text class="fs-22">元</text>
</text>
</view>
</view>
</scroll-view>
</view>
<view class="body">
<view class="body-title">
<scroll-view scroll-x="true" class="scroll">
<view class="item" :class="index == current?'on':''"
v-for="(item, index) in navList" :key="index"
@click="navTap(item,index)">{{item.value}}{{index?'积分':''}}</view>
</scroll-view>
</view>
<view class="product-list" v-if="integralGood.length">
<view class="product-item" v-for="(item, index) in integralGood" :key="index"
@click="goGoodsDetail(item)">
<easy-loadimage
mode="aspectFit"
:image-src="item.image"
width="314rpx"
height="314rpx"
borderRadius="20rpx 20rpx 0 0"></easy-loadimage>
<view class="info">
<view class="title line1">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{ item.title }}</view>
<view class="sales">已有{{item.sales}}人兑换</view>
<view class="price-box acea-row row-middle">
<view class="acea-row row-middle" v-if="parseFloat(item.integral)">
<image src="../static/mall05.png"></image>
<text class="font-num">{{ item.integral }}</text>
</view>
<text v-if="parseFloat(item.integral) && parseFloat(item.price)">+</text>
<text v-if="parseFloat(item.price)">
<text class="font-num">{{ item.price }}</text>
<text class="fs-22">元</text>
</text>
</view>
</view>
</view>
</view>
<view v-else class="no-goods">
<emptyPage title="暂无商品,去看看别的吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from 'vuex';
import {
getStoreIntegral,
getIntegralCategory,
getStoreIntegralList
} from '@/api/activity.js'
import {
goShopDetail
} from '@/libs/order.js';
import colors from "@/mixins/color";
import {HTTP_REQUEST_URL} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
export default {
components: { emptyPage, NavBar },
mixins: [colors],
data() {
return {
sysHeight,
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
goodList: [],
navList: [],
current: 0,
where: {
range: '',
page: 1,
limit: 10,
},
integralGood: [],
imgHost: HTTP_REQUEST_URL,
loadend: false,
loading: false,
loadTitle: '加载更多',
integral: 0,
pageScrollStatus:false,
}
},
computed: mapGetters(['isLogin']),
onLoad() {
this.integralCategory();
this.storeIntegralList();
if (this.isLogin) {
this.getStoreIntegral();
} else {
toLogin();
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV == true) {
this.getStoreIntegral();
}
},
deep: true
},
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
methods: {
integralCategory(){
getIntegralCategory().then(res=>{
let data = res.data;
data.unshift({
value:'全部'
})
this.navList = data;
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
navTap(item,index){
if (this.current === index) return;
this.current = index;
this.where.range = item.value;
this.where.page = 1;
this.loadend = false;
this.$set(this, 'integralGood', []);
this.storeIntegralList();
},
storeIntegralList(){
if (this.loadend) return;
if (this.loading) return;
this.loading = true;
getStoreIntegralList(this.where).then(res=>{
let list = res.data;
let limit = this.where.limit;
this.where.page++;
this.loadend = limit > list.length;
this.integralGood = this.integralGood.concat(list);
this.loading = false;
this.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
}).catch(err=>{
this.loading = false;
this.loadTitle = '加载更多';
return this.$util.Tips({
title: err
});
})
},
goarrow(){
uni.navigateBack()
},
getStoreIntegral() {
getStoreIntegral().then(res => {
this.goodList = res.data.list;
this.integral = res.data.integral;
})
},
// 去商品详情
goGoodsDetail(item) {
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=4`
});
}
},
onReachBottom() {
this.storeIntegralList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '积分商城',
path: '/pages/activity/points_mall/index?spid=' + that.$store.state.app.uid,
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '积分商城',
path: '/pages/activity/points_mall/index?spid=' + + that.$store.state.app.uid,
// desc: ''
};
}
//#endif
}
</script>
<style lang="scss" scoped>
page{
padding-bottom: 40rpx;
}
.accountTitle{
background: linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%);
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
.sysTitle{
width: 100%;
position: relative;
font-weight: 500;
color: #fff;
font-size: 30rpx;
.iconfont{
position: absolute;
font-size: 36rpx;
left:11rpx;
width: 60rpx;
}
}
}
.header{
width: 100%;
height: 400rpx;
background: linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%);
position: relative;
.record{
width: 124rpx;
height: 48rpx;
background-color: rgba(51, 51, 51, 0.2);
border-radius: 50rpx 0 0 50rpx;
font-weight: 400;
color: #FFFFFF;
font-size: 24rpx;
position: absolute;
right: 0;
top:36rpx;
}
&::after{
position: absolute;
content: '';
width: 100%;
height: 105rpx;
background: linear-gradient(180deg, rgba(233,51,35,0) 0%, var(--view-minorColorT) 50%, #F5F5F5 100%);
}
.headerBg{
background-image: url('../static/mall01.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 689rpx;
height: 298rpx;
margin: 0 auto;
padding-top: 88rpx;
.pictrue{
width: 345rpx;
height: 76rpx;
image{
width: 100%;
height: 100%;
}
}
.num{
font-size: 26rpx;
font-weight: 400;
color: rgba(255,255,255,0.6);
margin: 4rpx 0 0 12rpx;
}
}
}
.hot{
background-color: #fff;
width: 710rpx;
border-radius: 24rpx;
margin: 20rpx auto 0 auto;
padding: 32rpx 0 20rpx 32rpx;
.title{
font-weight: 600;
color: #333333;
font-size: 32rpx;
}
.scroll{
white-space: nowrap;
margin-top: 26rpx;
.scroll-item{
display: inline-block;
width: 224rpx;
margin-right: 20rpx;
vertical-align: top;
.pictrue{
width: 100%;
height: 224rpx;
image{
width: 100%;
height: 100%;
border-radius: 20rpx;
}
}
.name{
font-weight: 400;
color: #333333;
font-size: 26rpx;
margin-top: 16rpx;
}
.info{
color: #999999;
font-size: 22rpx;
margin-top: 8rpx;
}
.price-box{
font-size: 24rpx;
font-weight: 500;
margin-top: 10rpx;
color: #666;
image{
width: 31rpx;
height: 31rpx;
margin-right: 8rpx;
}
}
}
}
}
.nav{
width: 710rpx;
height: 184rpx;
background-color: #fff;
border-radius: 30rpx;
margin: -150rpx auto 0 auto;
position: relative;
.item{
font-size: 26rpx;
font-weight: 400;
color: #333333;
text-align: center;
width: 30%;
.pictrue{
width: 61rpx;
height: 61rpx;
margin: 0 auto 16rpx auto;
image{
width: 100%;
height: 100%;
}
}
}
.line{
width: 1px;
height: 70rpx;
background-color: #F3F3F3;
}
}
.body {
background-color: #fff;
width: 710rpx;
margin: 20rpx auto 0 auto;
border-radius: 24rpx;
padding-bottom: 20rpx;
.body-title {
padding-left: 32rpx;
.scroll{
white-space: nowrap;
.item{
display: inline-block;
margin-right: 60rpx;
padding: 34rpx 0 38rpx 0;
font-size: 28rpx;
font-weight: 400;
&.on{
font-weight: 500;
color: var(--view-theme);
position: relative;
font-size: 30rpx;
&::after{
position: absolute;
content: '';
width: 36rpx;
height: 30rpx;
border: 2px solid var(--view-theme);
border-left: 2px solid transparent !important;
border-top: 2px solid transparent !important;
border-right: 2px solid transparent !important;
border-radius: 50%;
left:50%;
bottom: 22rpx;
margin-left: -24rpx;
}
}
}
}
}
.product-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 32rpx;
.product-item {
position: relative;
width: 314rpx;
background: #fff;
border-radius: 10rpx;
margin-bottom: 20rpx;
.info {
margin-top: 20rpx;
.title {
font-size: 28rpx;
}
.price-box{
font-size: 24rpx;
font-weight: 500;
margin-top: 10rpx;
color: #666;
image{
width: 31rpx;
height: 31rpx;
margin-right: 8rpx;
}
}
.sales {
font-size: 24rpx;
color: #999999;
margin-top: 8rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,264 @@
<template>
<view>
<view class="w-full bg-top h-518 relative" :style="{backgroundImage:headerBg}">
<NavBar titleText="预售"
textSize="34rpx"
:isScrolling="pageScrollStatus"
:iconColor="pageScrollStatus ? '#333333' : '#ffffff'"
:textColor="pageScrollStatus ? '#333333' : '#ffffff'"
showBack></NavBar>
</view>
<view class="px-20">
<view class="bg--w111-fff rd-16rpx relative " style="top: -24rpx;">
<view class="w-full h-112 bg-primary-light nav-bg" :style="{backgroundImage:navBg}">
<view class="w-full flex-between-center pt-22 pl-76 pr-76">
<text class="fs-26 text--w111-666 lh-36rpx"
v-for="(item, index) in timeList" :key="index"
:class="active == index? 'active':''"
@tap="settimeList(item.key)">{{item.name}}</text>
</view>
</view>
<view class="w-full pl-20 pr-20 pb-40" v-if="presellList.length">
<view class="w-full flex justify-between pro-item"
v-for="(item,index) in presellList" :key="index"
@tap="goDetails(item)">
<easy-loadimage
:image-src="item.image"
width="240rpx"
height="240rpx"
borderRadius="16rpx"></easy-loadimage>
<view class="flex-1 flex-col justify-between pl-20">
<view class="w-full">
<view class="w-full fs-28 h-80 lh-40rpx line2">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>
{{item.store_name}}</view>
<view class="w-full flex items-end flex-wrap mt-16" v-if="item.store_label.length">
<BaseTag
:text="label.label_name"
:color="label.color"
:background="label.bg_color"
:borderColor="label.border_color"
:circle="label.border_color ? true : false"
:imgSrc="label.icon"
v-for="(label, idx) in item.store_label" :key="idx"></BaseTag>
</view>
</view>
<view class="flex w-full h-68 rd-8rpx btn-bg relative" :class="active == 2 ? 'opacity' : ''">
<view class="flex-y-center pl-20 fs-22 btn-left ">
<baseMoney
:money="item.price"
symbolSize="26"
integerSize="40"
decimalSize="26"
weight
preFix="预售:"
preFixSize="22"
textColor="#e93323"
color="#e93323"></baseMoney>
</view>
<image src="../static/yushou1.png" class="btn-right" v-if="active == 0"></image>
<image src="../static/yushou2.png" class="btn-right" v-else-if="active == 1"></image>
<image src="../static/yushou3.png" class="btn-right" v-else="active == 2"></image>
</view>
</view>
</view>
</view>
<view class='px-20' v-else>
<emptyPage title="暂无预售商品,去看看其他商品吧~" src="/statics/images/noActivity.gif"></emptyPage>
</view>
</view>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getAdvancellList } from '@/api/activity';
import {HTTP_REQUEST_URL} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
import NavBar from "@/components/NavBar.vue"
export default {
name: "presell",
components:{ emptyPage, NavBar },
data() {
return {
sysHeight:sysHeight,
presellList: [],
timeList: [
{name: '未开始',key: 0},
{name: '正在进行',key: 1},
{name: '已结束',key: 2},
],
active: 1,
page: 1,
limit: 8,
loading: false,
loadend: false,
loadTitle: '加载更多',
picUrl: '', //头部图片
imgHost:HTTP_REQUEST_URL,
pageScrollStatus:false,
}
},
computed:{
headerBg(){
return 'url('+this.imgHost+'/statics/images/product/product_presale_header.png'+')'
},
navBg(){
return 'url('+this.imgHost+'/statics/images/product/presell-bg-' + this.active +'.png'+')'
}
},
onPageScroll(object) {
if (object.scrollTop > 130) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 130) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onLoad() {
this.getPresellProductList();
},
onShow(){
uni.removeStorageSync('form_type_cart');
},
methods: {
getPresellProductList: function() {
let that = this;
let data = {
page: that.page,
limit: that.limit,
time_type: that.active + 1
};
if (that.loading) return;
if (that.loadend) return;
that.loading = true;
that.loadTitle = '';
getAdvancellList(data).then(res => {
let list = res.data.list;
let loadend = list.length < that.limit;
that.presellList = that.$util.SplitArray(list, that.presellList);
that.$set(that, 'presellList', that.presellList);
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
settimeList(key) {
let that = this;
that.active = key;
that.loadend = false;
that.page = 1;
that.presellList = [];
that.getPresellProductList();
},
goDetails(item) {
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${item.id}&type=6`
})
},
goBack(){
uni.navigateBack()
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getPresellProductList();
},
//#ifdef MP
onShareAppMessage() {
let that = this;
return {
title: '尖货预售',
path: '/pages/activity/presell/index?spid=' + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/product_presale_header.png',
// desc: ''
};
},
//分享到朋友圈
onShareTimeline: function() {
let that = this;
return {
title: '尖货预售',
path: '/pages/activity/presell/index?spid=' + + that.$store.state.app.uid,
imageUrl: HTTP_REQUEST_URL+'/statics/images/product/product_presale_header.png',
// desc: ''
};
}
//#endif
}
</script>
<style>
page{
background: linear-gradient(270deg, #6D4ADC 0%, #7033D7 98%);
}
</style>
<style lang="scss">
.bg-top{
background-size: 100% 100%;
background-repeat: no-repeat;
}
.bg-primary-light{
background-color: rgba(109, 74, 220, 0.1);
}
.nav-bg{
background-size: 100% 100%;
background-repeat: no-repeat;
}
.active{
font-size: 32rpx;
font-weight: 500;
line-height: 44rpx;
color: #7033D7;
}
.btn-bg{
background: rgba(233, 51, 35, 0.1);
}
.btn-left{
flex: 1;
border-radius: 8rpx 0 0 8rpx;
}
.btn-right{
width: 180rpx;
height: 68rpx;
}
.shandian{
width: 42rpx;
height: 68rpx;
position: absolute;
transform: scale(1.1);
left: 56%;
top: 1px;
}
.pro-item ~ .pro-item{
margin-top: 32rpx;
}
.border-label {
display: inline-flex;
display: flex;
align-items: center;
flex-wrap: nowrap;
height: 26rpx;
padding: 0 6rpx;
border: 1rpx solid #e93323;
border-radius: 6rpx;
font-size: 18rpx;
color: #e93323;
}
/deep/ .empty-box{
width: 100%;
height: 280px;
}
.opacity{
opacity: 0.5;
}
.brand-tag{
background-color: #e93323 !important;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,417 @@
<template>
<!-- 退款页、一键改价页、订单备注页、立即退款立即退货页 -->
<view>
<!-- <view class="priceChange" :class="[change === true ? 'on' : '',status == 2 && !isRefund?'goodsOn':'']"> -->
<view class="priceChange" :class="[change === true ? 'on' : '']">
<view class="priceChange-box">
<!-- status == 0? orderInfo.refund_status === 1? "立即退款": "一键改价": "订单备注" -->
<view class="priceTitle">
{{
status == 8?'退款原因': status == 0?"一键改价": status == 1?'订单备注': isRefund?'退款审核':'退款审核'
}}
<view class="btn acea-row row-center row-middle" @click="close">
<span class="iconfont icon-ic_close"></span>
</view>
</view>
<!-- 一键改价 -->
<view class="listChange" v-if="status == 0">
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refund_status === 0">
<view>商品原价</view>
<view class="money">
¥{{ orderInfo.total_price }}
</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refund_status === 0">
<view>商品邮费</view>
<view class="money">
¥{{ orderInfo.pay_postage }}
</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="orderInfo.refund_status === 0">
<view>修改价格</view>
<view class="money">
<input type="text" v-model="price" :cursor-spacing="40" always-embed :class="focus === true ? 'on' : ''" @focus="priceChange" />
</view>
<text class="iconfont icon-ic_edit"></text>
</view>
</view>
<!-- 立即退款 -->
<!-- <view class="listChange" v-if="status == 2">
<view v-if="isRefund" class="item acea-row row-between-wrapper">
<view>实际支付(¥)</view>
<view class="money">
{{ orderInfo.pay_price }}<span class="iconfont icon-suozi"></span>
</view>
</view>
<view v-if="isRefund" class="item acea-row row-between-wrapper">
<view>退款金额(¥)</view>
<view class="money">
<input type="text" v-model="refund_price" :class="focus === true ? 'on' : ''" @focus="priceChange" />
</view>
</view>
<view class="title" v-if="!isRefund">同意退货退款</view>
</view> -->
<!-- 退款审核 -->
<view class="listChange" v-if="status == 2">
<view class="item acea-row row-between-wrapper">
<view>审核状态</view>
<view class="money acea-row row-right">
<view class="radio-item acea-row row-middle" :class="{ on: isAgree }" @click="agreeChange(true)">
<text class="iconfont" :class="isAgree?'icon-ic_Selected':'icon-ic_unselect'"></text>同意退{{isRefund?'款':'货'}}
</view>
<view v-if="orderInfo.refund_type != 4 && orderInfo.refund_type != 5" class="radio-item acea-row row-middle" :class="{ on: !isAgree }" @click="agreeChange(false)">
<text class="iconfont" :class="isAgree?'icon-ic_unselect':'icon-ic_Selected'"></text>拒绝退款
</view>
</view>
</view>
<view class="item acea-row row-between">
<view>邮费</view>
<view class="fs-32 Regular acea-row row-right">¥{{orderInfo.pay_postage}}</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="isAgree && isRefund">
<view>退款金额</view>
<view class="money">
<input type="text" v-model="refund_price" :cursor-spacing="50" :class="focus === true ? 'on' : ''" always-embed @focus="priceChange" />
</view>
<text class="iconfont icon-ic_edit"></text>
</view>
<view class="item acea-row row-between" v-if="!isAgree">
<view>拒绝原因</view>
<view class="money acea-row row-right">
<textarea class="reason" placeholder="请输入" v-model="refuse_reason" fixed :cursor-spacing="100"></textarea>
</view>
</view>
</view>
<view class="listChange" v-if="status == 1">
<textarea placeholder="请填写备注信息..." v-model="remark" fixed :cursor-spacing="100"></textarea>
</view>
<!-- <view class="listChange" v-if="status == 8">
<textarea placeholder="请填写退款原因..." v-model="refuse_reason"></textarea>
</view> -->
<view class="modify-box acea-row">
<view class="cancel btn-box" @click="close">取消</view>
<view class="modify btn-box" @click="refuse" v-if="status == 8">确定</view>
<view class="modify btn-box" @click="onConfirm" v-if="status == 2 && !isRefund">确定</view>
<view class="modify btn-box" @click="save" v-if="status == 1 || status == 0">确定</view>
<view class="modify btn-box" @click="onConfirm" v-if="status == 2 && isRefund">确定</view>
</view>
<slot name="bottom"></slot>
</view>
<view class="safe-area-inset-bottom"></view>
</view>
<view class="mask" @touchmove.prevent v-show="change === true"></view>
</view>
</template>
<style lang="scss" scoped>
.safe-area-inset-bottom {
height: 0;
height: constant(safe-area-inset-bottom);
height: env(safe-area-inset-bottom);
}
.mask {
z-index: 99;
}
.priceChange .reGoods {
padding: 0 25upx;
margin-top: 50upx;
}
.priceChange .reGoods .bnt {
width: 250upx;
height: 90upx;
background-color: #2291f8;
font-size: 32upx;
color: #fff;
text-align: center;
line-height: 90upx;
border-radius: 45upx;
}
.priceChange .reGoods .bnt.grey {
background-color: #eee;
color: #312b2b;
}
.priceChange {
position: fixed;
bottom: 0;
left: 0;
z-index: 99999;
width: 100%;
border-radius: 40rpx 40rpx 0 0;
background: #FFFFFF;
transform: translateY(100%);
transition: transform 0.3s;
}
.priceChange.on {
transform: translateY(0);
}
.priceChange-box {}
.priceChange.goodsOn {
height: 380upx;
}
.priceChange .priceTitle {
position: relative;
height: 108rpx;
text-align: center;
font-weight: 500;
font-size: 32rpx;
line-height: 108rpx;
color: #333333;
}
.priceChange .priceTitle .btn {
position: absolute;
top: 50%;
right: 32rpx;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
margin-top: -18rpx;
background: #EEEEEE;
text-align: center;
line-height: 36rpx;
}
.priceChange .priceTitle .iconfont {
vertical-align: text-bottom;
font-weight: normal;
font-size: 24rpx;
}
.priceChange .listChange {
padding: 32rpx;
min-height: 260rpx;
}
.priceChange .listChange .item {
margin-bottom: 64rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
&:last-child {
margin-bottom: 0;
}
}
.priceChange .listChange .title {
font-size: 32rpx;
text-align: center;
margin-top: 52rpx;
}
.priceChange .listChange .item .money {
flex: 1;
text-align: right;
font-family: Regular;
font-size: 36rpx;
}
.priceChange .listChange .item .iconfont {
margin-left: 8rpx;
font-size: 32rpx;
}
.priceChange .listChange .item .money input {
color: #FF7E00;
}
.priceChange .listChange .item .money input.on {
// color: #666;
}
.priceChange .modify-box {
padding: 20rpx;
}
.priceChange .btn-box {
flex: 1;
height: 72rpx;
border: 2rpx solid $primary-admin;
border-radius: 36rpx;
margin-right: 16rpx;
text-align: center;
font-weight: 500;
font-size: 26rpx;
line-height: 68rpx;
color: $primary-admin;
&:last-child {
margin-right: 0;
}
}
.priceChange .modify {
border-color: $primary-admin;
background: $primary-admin;
color: #FFFFFF;
}
.priceChange .modify1 {
font-size: 32upx;
color: #312b2b;
width: 490upx;
height: 90upx;
text-align: center;
line-height: 90upx;
border-radius: 45upx;
background-color: #eee;
margin: 30upx auto 0 auto;
}
.priceChange .listChange textarea {
box-sizing: border-box;
border: 2rpx solid #CCCCCC;
width: 100%;
height: 224rpx;
padding: 20rpx;
border-radius: 16rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #333;
}
.radio-item {
font-size: 28rpx;
color: #999999;
+.radio-item {
margin-left: 48rpx;
}
.iconfont {
margin-right: 12rpx;
font-size: 32rpx;
}
&.on {
color: #333333;
.iconfont {
color: $primary-admin;
}
}
}
.reason {
width: 462rpx !important;
height: 80rpx !important;
padding: 0 !important;
border: 0 !important;
}
</style>
<script>
export default {
name: "PriceChange",
components: {},
props: {
change: {
type: Boolean,
default: false
},
orderInfo: {
type: Object,
default: () => {}
},
status: {
type: String,
default: ""
},
isRefund: {
type: Number || String,
default: 0
}
},
data: function() {
return {
focus: false,
price: 0,
refund_price: 0,
remark: "",
refuse_reason: '',
isAgree: true,
};
},
watch: {
orderInfo: function(nVal) {
this.price = this.orderInfo.pay_price;
this.refund_price = this.orderInfo.pay_price;
this.remark = this.orderInfo.remark;
},
change(val) {
if (val) {
this.isAgree = true
this.refuse_reason = ''
}
},
isRefund(val) {
console.log(val)
},
},
methods: {
priceChange: function() {
this.focus = true;
},
close: function() {
this.price = this.orderInfo.pay_price;
this.$emit("closechange", false);
},
save: function() {
let that = this;
// if (!that.isAgree) {
// that.refuse();
// return
// }
that.$emit("savePrice", {
price: that.price,
refund_price: that.refund_price,
type: 1,
remark: that.remark
});
},
refuse: function() {
let that = this;
that.$emit("savePrice", {
price: that.price,
refund_price: that.refund_price,
type: 2,
remark: that.remark,
refuse_reason: that.refuse_reason
});
},
agreeChange(value) {
this.isAgree = value;
if (this.isAgree) {
this.refuse_reason = '';
}
},
onConfirm() {
if (this.status == 1) {
this.save();
}
if (this.status == 2) {
if (this.isRefund) {
if (this.isAgree) {
this.save();
} else {
this.refuse();
}
} else {
if (this.isAgree) {
this.save();
} else {
this.refuse();
}
}
}
},
}
};
</script>

View File

@@ -0,0 +1,118 @@
<template>
<!-- 底部导航 -->
<view class="page-footer">
<view class="foot-item" :class="item.pagePath == activeRouter?'active':''"
v-for="(item,index) in footerList" :key="index" @click="goRouter(item, index)">
<block v-if="item.pagePath == activeRouter">
<image :src="item.selectedIconPath"></image>
<view class="txt">{{item.text}}</view>
</block>
<block v-else>
<image :src="item.iconPath"></image>
<view class="txt">{{item.text}}</view>
</block>
</view>
</view>
</template>
<script>
export default {
name: 'adminFooterTab',
props: {},
created() {
let routes = getCurrentPages(); //获取当前打开过的页面路由数组
let curRoute = routes[routes.length - 1].route //获取当前页面路由
this.activeRouter = '/' + curRoute
},
mounted() {},
data() {
return {
activeRouter:'',
footerList:[
{
pagePath: "/pages/admin/work/index",
iconPath: require("../../static/footer1-1.png"),
selectedIconPath: require("../../static/footer1-2.png"),
text: "工作台"
},
{
pagePath: "/pages/admin/goods/index",
iconPath: require("../../static/footer2-1.png"),
selectedIconPath: require("../../static/footer2-2.png"),
text: "商品"
},
{
pagePath: "/pages/admin/orderList/index",
iconPath: require("../../static/footer3-1.png"),
selectedIconPath: require("../../static/footer3-2.png"),
text: "订单"
},
{
pagePath: "/pages/admin/user/list",
iconPath: require("../../static/footer4-1.png"),
selectedIconPath: require("../../static/footer4-2.png"),
text: "用户"
}
]
}
},
methods: {
goRouter(item) {
var pages = getCurrentPages();
var page = (pages[pages.length - 1]).$page.fullPath;
if (item.pagePath == page) return
uni.redirectTo({
url: item.pagePath,
animationType: 'none' // 关闭默认的滑动效果
});
}
}
}
</script>
<style scoped lang="scss">
.page-footer {
position: fixed;
bottom: 0;
left:0;
z-index: 20;
display: flex;
align-items: center;
justify-content: space-around;
width: 100%;
height: calc(100rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(100rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
box-sizing: border-box;
border-top: solid 1rpx #F3F3F3;
background-color: #fff;
// box-shadow: 0px 0px 17rpx 1rpx rgba(206, 206, 206, 0.32);
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
.foot-item {
display: flex;
width: max-content;
align-items: center;
justify-content: center;
flex-direction: column;
position: relative;
padding: 0 20rpx;
&.active {
color: $primary-admin
}
}
.foot-item image {
height: 40rpx;
width: 40rpx;
text-align: center;
margin: 0 auto;
}
.foot-item .txt {
font-size: 20rpx;
margin-top: 6rpx;
}
}
</style>

View File

@@ -0,0 +1,132 @@
<template>
<!-- 悬浮导航按钮 -->
<view :style="colorStyle">
<view style="touch-action: none;">
<view class="home" style="position:fixed;" :style="{ top: top + 'px'}" id="right-nav" @touchmove.stop.prevent="setTouchMove">
<view @click="open" class="pictrueBox">
<view class="pictrue">
<image :src="
homeActive === true
? imgHost + '/statics/images/close.gif'
: imgHost + '/statics/images/open.gif'
" class="image" />
</view>
</view>
<view class="homeCon bg-color" :class="homeActive === true ? 'on' : ''" v-if="homeActive">
<navigator hover-class='none' open-type="navigate" url='/pages/admin/work/index' class='iconfont icon-ic_staging'>
</navigator>
<navigator hover-class='none' open-type="navigate" url='/pages/admin/goods/index' class='iconfont icon-ic_commodity'></navigator>
<navigator hover-class='none' open-type="navigate" url='/pages/admin/orderList/index' class='iconfont icon-ic_order'></navigator>
<navigator hover-class='none' open-type="navigate" url='/pages/admin/user/list' class='iconfont icon-ic_user1'></navigator>
<slot name="bottom"></slot>
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapGetters
} from "vuex";
import colors from '@/mixins/color.js';
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
name: "Home",
props: {},
mixins: [colors],
data: function() {
return {
top: "545",
imgHost: HTTP_REQUEST_URL
};
},
computed: mapGetters(["homeActive"]),
methods: {
setTouchMove(e) {
var that = this;
if (e.touches[0].clientY < 545 && e.touches[0].clientY > 66) {
that.top = e.touches[0].clientY
// that.setData({
// top: e.touches[0].clientY
// })
}
},
open: function() {
this.homeActive ?
this.$store.commit("CLOSE_HOME") :
this.$store.commit("OPEN_HOME");
}
},
created() {},
beforeDestroy() {
this.$store.commit("CLOSE_HOME")
}
};
</script>
<style scoped lang="scss">
.pictrueBox {
width: 130rpx;
height: 120rpx;
}
/*返回主页按钮*/
.home {
position: fixed;
color: white;
text-align: center;
z-index: 9999;
left: 15rpx;
display: flex;
}
.home .homeCon {
border-radius: 50rpx;
opacity: 0;
height: 0;
width: 0;
}
.home .homeCon.on {
opacity: 1;
animation: bounceInLeft 0.5s cubic-bezier(0.215, 0.610, 0.355, 1.000);
width: 300rpx;
height: 86rpx;
margin-bottom: 20rpx;
display: flex;
justify-content: center;
align-items: center;
/* background: var(--view-theme) !important; */
background: $primary-admin !important;
/* border: 1px solid #fff; */
}
.home .homeCon .iconfont {
font-size: 40rpx;
color: #fff;
display: inline-block;
margin: 0 auto;
}
.home .pictrue {
width: 86rpx;
height: 86rpx;
border-radius: 50%;
margin: 0 auto;
background: $primary-admin;
/* border: 1px solid #fff; */
}
.home .pictrue .image {
width: 100%;
height: 100%;
border-radius: 50%;
transform: rotate(-90deg);
ms-transform: rotate(-90deg);
moz-transform: rotate(-90deg);
webkit-transform: rotate(-90deg);
o-transform: rotate(-90deg);
}
</style>

View File

@@ -0,0 +1,164 @@
<template>
<canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
</canvas>
</template>
<script>
import uCharts from './u-charts.js';
var canvases = {};
export default {
props: {
chartType: {
required: true,
type: String,
default: 'column'
},
opts: {
required: true,
type: Object,
default () {
return null;
},
},
canvasId: {
type: String,
default: 'u-canvas',
},
cWidth: {
default: 375,
},
cHeight: {
default: 250,
},
pixelRatio: {
type: Number,
default: 1,
},
},
mounted() {
this.init();
},
methods: {
init() {
switch (this.chartType) {
case 'column':
this.initColumnChart();
break;
case 'line':
this.initLineChart();
break;
default:
break;
}
},
initColumnChart() {
canvases[this.canvasId] = new uCharts({
$this: this,
canvasId: this.canvasId,
type: 'column',
legend: true,
fontSize: 11,
background: '#FFFFFF',
pixelRatio: this.pixelRatio,
animation: true,
categories: this.opts.categories,
series: this.opts.series,
enableScroll: true,
xAxis: {
disableGrid: true,
itemCount: 4,
scrollShow: true
},
yAxis: {
//disabled:true
},
dataLabel: true,
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
column: {
type: 'group',
}
}
});
},
initLineChart() {
canvases[this.canvasId] = new uCharts({
$this: this,
canvasId: this.canvasId,
type: 'line',
fontSize: 11,
legend: true,
dataLabel: false,
dataPointShape: true,
background: '#FFFFFF',
pixelRatio: this.pixelRatio,
categories: this.opts.categories,
series: this.opts.series,
animation: true,
enableScroll: true,
xAxis: {
type: 'grid',
gridColor: '#CCCCCC',
gridType: 'dash',
dashLength: 8,
itemCount: 4,
scrollShow: true
},
yAxis: {
gridType: 'dash',
gridColor: '#CCCCCC',
dashLength: 8,
splitNumber: 5,
min: 10,
max: 180,
format: (val) => {
return val.toFixed(0) + '元'
}
},
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
line: {
type: 'straight'
}
}
});
},
// 这里仅作为示例传入两个参数,cid为canvas-id,newdata为更新的数据,需要更多参数请自行修改
changeData(cid,newdata) {
canvases[cid].updateData({
series: newdata.series,
categories: newdata.categories
});
},
touchStart(e) {
canvases[this.canvasId].showToolTip(e, {
format: function(item, category) {
return category + ' ' + item.name + ':' + item.data
}
});
canvases[this.canvasId].scrollStart(e);
},
touchMove(e) {
canvases[this.canvasId].scroll(e);
},
touchEnd(e) {
canvases[this.canvasId].scrollEnd(e);
},
error(e) {
}
},
};
</script>
<style scoped>
.charts {
width: 100%;
height: 100%;
flex: 1;
background-color: #FFFFFF;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,737 @@
<template>
<view>
<view class='shoppingCart copy-data'>
<view class="content">
<view class='list'>
<view>
<block v-for="(item,index) in cart_info" :key="index">
<view class='item acea-row row-between-wrapper' :style="{ opacity: item.is_writeoff == 1 ? 0.5 : 1 }">
<div class="xuan" @click="dan(item.cart_id,index)">
<view :class="(item.checked && !item.is_writeoff)?'iconfont icon-a-ic_CompleteSelect':'iconfont icon-ic_unselect'"></view>
</div>
<view class='picTxt acea-row row-between-wrapper'>
<view class='pictrue'>
<image :src="item.cart_info.productInfo.attrInfo?item.cart_info.productInfo.attrInfo.image:item.cart_info.productInfo.image" mode=""></image>
</view>
<view class='text'>
<view class="title">
<view class='line1'>
{{ item.cart_info.productInfo.store_name }}
</view>
<view v-if="item.is_writeoff == 1" class="txt">已核销</view>
<view v-if="item.is_writeoff == 0 && item.surplus_num == item.cart_num" class="txt bluecol">未核销</view>
<view v-if="item.is_writeoff == 0 && item.surplus_num != item.cart_num" class="txt orangcol">
已核销{{item.cart_num - item.surplus_num}}件</view>
</view>
<view class='infor line1'>
属性:{{ item.cart_info.productInfo.attrInfo.suk }}</view>
<view class='money he row-middle'>
<view>¥{{ item.cart_info.productInfo.attrInfo?item.cart_info.productInfo.attrInfo.price:item.cart_info.productInfo.price }}</view>
<view v-if="item.is_writeoff == 1" class="txt">
<view class='carnum acea-row row-center-wrapper'>
<view class="reduce">
<text class="iconfont icon-ic_Reduce"></text>
</view>
<view class='nums'>0</view>
<view class="plus">
<text class="iconfont icon-ic_increase"></text>
</view>
</view>
</view>
<view v-else class="txt">
<view class='carnum acea-row row-center-wrapper'>
<view v-if="item.surplus_num_input == 1" class="reduce bggary">
<text class="iconfont icon-ic_Reduce"></text>
</view>
<view v-else class="reduce" @click.stop='subCart(item,index)'>
<text class="iconfont icon-ic_Reduce"></text>
</view>
<view class='nums'>{{item.surplus_num_input}}</view>
<view v-if="item.surplus_num == item.surplus_num_input" class="plus bggary">
<text class="iconfont icon-ic_increase"></text>
</view>
<view v-else class="plus" @click.stop='addCart(item,index)'>
<text class="iconfont icon-ic_increase"></text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</block>
</view>
</view>
</view>
<view class='footer acea-row row-between-wrapper'>
<view>
<view class="flex">
<div class="xuan" @click="checkAll" v-model="checked">
<view class="iconfont" :class="checked?'icon-a-ic_CompleteSelect':'icon-ic_unselect'"></view>
</div>
<text class='checkAll'>全选</text>
</view>
</view>
<view>
<button class='money' type="primary" @click="verification">{{checked?'一键':'确认'}}核销({{numChecked}})</button>
</view>
</view>
</view>
<view v-if="box">
<view class="box">
<view class="small_box">
<view class="content">
<view class="font">核销成功</view>
<view v-if="list.total_num == parseInt(list.writeoff_count)+writeOffNum" class="small_font">当前订单已完成核销</view>
<view v-else class="small_font">该订单仍有其他待核销商品</view>
</view>
<view class="acea-row btn-box">
<view v-if="lets == 1 && list.total_num == parseInt(list.writeoff_count)+writeOffNum" class="btn" @click="ok(1)">知道了</view>
<navigator v-if="lets > 1 && list.total_num != parseInt(list.writeoff_count)+writeOffNum" :url='"/pages/admin/distribution/scanning/index?code="+attr.code' hover-class='none'
open-type="redirect" class="btn">返回列表</navigator>
<navigator v-if="(lets > 1 && list.total_num == parseInt(list.writeoff_count)+writeOffNum)||(lets==1&&list.total_num != parseInt(list.writeoff_count)+writeOffNum)"
url="/pages/admin/distribution/index" hover-class='none' open-type="redirect" class="btn">返回首页</navigator>
<view v-if="list.total_num != parseInt(list.writeoff_count)+writeOffNum" class="btn on" @click="ok(0)">继续核销</view>
<navigator v-if="lets > 1 && list.total_num == parseInt(list.writeoff_count)+writeOffNum" :url='"/pages/admin/distribution/scanning/index?code="+attr.code' open-type="redirect"
hover-class='none' class="btn">核销其他订单</navigator>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
orderCartInfo,
orderWriteoff
} from '@/api/admin'
import {
emit
} from 'process';
export default {
props: {
list: {
type: Object,
default () {
return {}
}
},
auth: {
type: [String, Number],
default: 1
},
oid: {
type: Number,
default: 0
},
},
data() {
return {
nums: [],
newList: [],
reduce_show: -1,
plus_show: -1,
ids: [], //选定需要核销的id
lets: 0, //判断订单的数量
listlet: 0, //判断订单商品的数量
attr: { //切换组件传值
cartAttr: false,
id: [],
code: '',
type: 0
},
// id: 0, //订单ID
// list: [],
lists: {},
lengt: 0,
box: false,
checked: false,
checkModel: [],
isAllSelect: false,
data: [{
id: '1',
value: 'aaa'
}, {
id: '2',
value: 'bbb'
}, {
id: '3',
value: 'ccc'
}],
writeOffNum: 0, //每次核销商品数量
cart_info: [],
numChecked: 0,
};
},
watch: {
checkModel() {
// if (this.lengt == this.checkModel.length) {
// this.checked = true;
// } else {
// this.checked = false;
// }
},
},
mounted() {
this.cart_info = this.list.cart_info;
// this.lists = JSON.parse(JSON.stringify(this.list))
// this.listlet = this.list.cart_info.length
// this.$set(this.attr, 'id', this.list.id);
this.checkAll()
// this.num()
},
methods: {
//处理每一条数据的最大值
num() {
for (let index = 0; index < this.lists.cart_info.length; index++) {
this.nums.push({
num: 0
});
}
},
subCart(item, index) {
// if (item.surplus_num == 1) {
// this.reduce_show = index;
// } else {
// this.nums[index].num--
// item.surplus_num--
// }
this.list.cart_info[index].surplus_num_input--;
},
addCart(item, index) {
// if (item.surplus_num == item.surplus_num + this.nums[index].num) {
// this.plus_show = index;
// } else {
// item.surplus_num++
// this.nums[index].num++
// }
this.list.cart_info[index].surplus_num_input++;
},
checkAll() {
var items = this.cart_info,
data = [];
this.checkModel = [];
this.checked = !this.checked;
for (let i = 0; i < this.cart_info.length; i++) {
this.cart_info[i].checked = this.checked;
if (this.cart_info[i].checked) {
this.checkModel.push(this.cart_info[i].cart_id);
}
}
let numChecked = 0;
for (let i = 0; i < this.cart_info.length; i++) {
if (!this.cart_info[i].is_writeoff) {
if (this.cart_info[i].checked) {
numChecked = numChecked + this.cart_info[i].surplus_num_input;
}
}
}
this.numChecked = numChecked;
// if (this.checked) {
// for (var i = 0, lenI = this.list.cart_info.length; i < lenI; ++i) {
// const item = items[i]
// this.$set(item, 'checked', false)
// }
// } else {
// for (var i = 0, lenI = this.list.cart_info.length; i < lenI; ++i) {
// const item = items[i]
// this.$set(item, 'checked', true)
// if (item.is_writeoff == 1) {
// this.checkModel = this.checkModel.filter(item => item != item.cart_id)
// } else {
// this.checkModel.push(item.cart_id)
// }
// }
// this.lengt = this.checkModel.length
// }
},
dan(id, index) {
// if (this.checkModel.indexOf(id) == -1) {
// this.$set(this.list.cart_info[index], 'checked', true)
// this.checkModel.push(id)
// } else {
// this.$set(this.list.cart_info[index], 'checked', false)
// this.checkModel = this.checkModel.filter(item => item != id)
// }
this.cart_info[index].checked = !this.cart_info[index].checked;
this.checkModel = [];
for (let i = 0; i < this.cart_info.length; i++) {
if (this.cart_info[i].checked) {
this.checkModel.push(this.cart_info[i].cart_id);
}
}
let checked = true;
for (let i = 0; i < this.cart_info.length; i++) {
if (!this.cart_info[i].is_writeoff) {
if (!this.cart_info[i].checked) {
checked = false;
}
}
}
this.checked = checked;
let numChecked = 0;
for (let i = 0; i < this.cart_info.length; i++) {
if (!this.cart_info[i].is_writeoff) {
if (this.cart_info[i].checked) {
numChecked = numChecked + this.cart_info[i].surplus_num_input;
}
}
}
this.numChecked = numChecked;
},
getList: function(id) {
orderCartInfo({
oid: id,
auth: 2,
}).then(res => {
this.list = res.data
this.lists = JSON.parse(JSON.stringify(res.data))
this.listlet = res.data.cart_info.length
this.$set(this.attr, 'id', this.list.id);
this.checkAll()
this.num()
})
},
onDataId: function(id) {
this.nums.forEach((item) => {
item.num = 0
})
this.id = id;
this.getList(id)
},
switchs() {
this.attr.cartAttr = true;
this.$refs.writeOff.getList(2)
},
onMyEvent() {
this.attr.cartAttr = false;
},
verification() {
let that = this
let newObj = [];
for (let i = 0; i < this.cart_info.length; i++) {
if (this.cart_info[i].checked && !this.cart_info[i].is_writeoff) {
newObj.push({
cart_id: this.cart_info[i].cart_id,
cart_num: this.cart_info[i].surplus_num_input,
});
}
}
// return
// let obj = {};
// 将数组转化为对象
// for (let key in this.checkModel) {
// obj[key] = this.checkModel[key];
// };
// let newObj = Object.keys(obj).map(val => ({
// cart_id: obj[val],
// }));
//处理列表内对应的核销数的数值
// for (var i = 0; i < newObj.length; i++) {
// for (var j = 0; j < this.list.cart_info.length; j++) {
// if (newObj[i].cart_id == this.list.cart_info[j].cart_id) {
// newObj[i].cart_num = this.list.cart_info[j].surplus_num;
// }
// }
// }
this.newList = newObj
if (that.checkModel.length == 0) {
that.$util.Tips({
title: '请选择商品'
});
} else {
uni.showLoading({
title: '加载中',
});
let num = 0;
newObj.forEach((item) => {
num = num + parseInt(item.cart_num)
})
this.writeOffNum = num;
setTimeout(function() {
orderWriteoff({
auth: that.auth,
oid: that.oid,
cart_ids: that.newList
}).then(res => {
uni.hideLoading();
// that.box = true
let isAll = 1;
for (let i = 0; i < that.list.cart_info.length; i++) {
if (that.list.cart_info[i].checked) {
if (that.list.cart_info[i].surplus_num != that.list.cart_info[i].surplus_num_input) {
isAll = 0
break;
}
}
}
that.$emit('success', isAll);
}).catch(err => {
that.$util.Tips({
title: err
});
uni.hideLoading();
})
}, 1000);
}
},
// 所有订单核销完成
ok(type) {
this.box = false
this.nums.forEach((item) => {
item.num = 0
})
this.getList(this.id)
if (type) {
uni.redirectTo({
url: '/pages/admin/distribution/index'
})
}
}
}
}
</script>
<style scoped lang="scss">
.shoppingCart {
padding: 24rpx 20rpx;
}
.shoppingCart .content {
padding: 32rpx 24rpx;
margin-top: 20rpx;
border-radius: 24rpx;
background: #FFFFFF;
.list_top {
background-color: #FFFFFF;
font-size: 28upx;
color: #333333;
height: 90upx;
line-height: 90upx;
padding-left: 24upx;
border-bottom: 2upx solid #EEEEEE;
.bluefont {
color: $primary-admin;
display: inline-block;
margin: 0upx 10upx;
}
.garyfont {
color: #999999;
}
}
}
.shoppingCart .list .item .xuan .iconfont {
font-size: 40rpx;
color: #CCCCCC;
}
.shoppingCart .list .item .xuan .icon-a-ic_CompleteSelect {
color: $primary-admin;
}
.shoppingCart .list .item .picTxt {
// width: 627upx;
position: relative;
flex: 1;
min-width: 0;
padding-left: 16rpx;
}
.shoppingCart .list .item .picTxt .pictrue {
width: 136rpx;
height: 136rpx;
}
.shoppingCart .list .item .picTxt .pictrue image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.shoppingCart .list .item .picTxt .text {
flex: 1;
min-width: 0;
padding-left: 20rpx;
font-size: 28upx;
color: #282828;
}
.shoppingCart .list .item .picTxt .text .reColor {
color: #999;
width: 60%;
}
.shoppingCart .list .item .picTxt .text .title {
display: flex;
justify-content: space-between;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
.bluecol {
color: $primary-admin;
}
.orangcol {
color: #FF7E00;
}
.graycol {
color: #CCCCCC;
}
}
.shoppingCart .list .item .picTxt .text .title .line1 {
flex: 1;
}
.shoppingCart .list .item .picTxt .text .title .top {
width: 70%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 28upx;
font-weight: 400;
}
.shoppingCart .list .item .picTxt .text .reElection {
margin-top: 20upx;
}
.shoppingCart .list .item .picTxt .text .reElection .title {
font-size: 24upx;
}
.shoppingCart .list .item .picTxt .text .reElection .reBnt {
width: 120upx;
height: 46upx;
border-radius: 23upx;
font-size: 26upx;
}
.shoppingCart .list .item .picTxt .text .infor {
font-size: 22rpx;
line-height: 30rpx;
color: #999999;
margin-top: 12rpx;
}
.shoppingCart .list .item .picTxt .text .money {
font-size: 36rpx;
line-height: 36rpx;
color: #333333;
margin-top: 18rpx;
font-family: Regular;
}
.shoppingCart .list .item .picTxt .carnum {
height: 36rpx;
// position: absolute;
// bottom: 7upx;
// right: 0;
}
.shoppingCart .list .item .picTxt .carnum view {
// border: 1upx solid #a4a4a4;
width: 32rpx;
text-align: center;
height: 100%;
line-height: 36rpx;
font-size: 24rpx;
color: #333333;
}
.shoppingCart .list .item .picTxt .carnum .reduce {
border-right: 0;
border-radius: 30upx 0 0 30upx;
}
.shoppingCart .list .item .picTxt .carnum .reduce.on {
border-color: #e3e3e3;
color: #dedede;
}
.shoppingCart .list .item .picTxt .carnum .plus {
border-left: 0;
border-radius: 0 30upx 30upx 0;
}
.shoppingCart .list .item .picTxt .carnum .num {
color: #282828;
}
.shoppingCart .list .item .picTxt .carnum .num0 {
color: #a4a4a4;
}
.shoppingCart .list .item .picTxt .carnum .nums {
width: 72rpx;
border-radius: 4rpx;
background: #F5F5F5;
}
.shoppingCart .footer {
// z-index: 999;
width: 100%;
background: #FFFFFF;
position: fixed;
padding: 0 20rpx 0 32rpx;
box-sizing: border-box;
bottom: 0;
left: 0;
height: 96rpx;
height: calc(96rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(96rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
}
.shoppingCart .footer.on {
// #ifndef H5
bottom: 0upx;
// #endif
}
.shoppingCart .footer .iconfont {
font-size: 40rpx;
color: #CCCCCC;
}
.shoppingCart .footer .icon-a-ic_CompleteSelect {
color: $primary-admin;
}
.shoppingCart .footer .checkAll {
font-size: 28upx;
color: #282828;
margin-left: 16upx;
}
.shoppingCart .footer .money {
font-size: 24rpx;
height: 64rpx;
padding: 0 32rpx;
background: #2A7EFB;
border-radius: 32rpx;
font-weight: 400;
color: #FFFFFF;
line-height: 64rpx;
}
.shoppingCart .footer .placeOrder {
color: #fff;
font-size: 30upx;
width: 226upx;
height: 70upx;
border-radius: 50upx;
text-align: center;
line-height: 70upx;
margin-left: 22upx;
}
.shoppingCart .footer .button .bnt {
font-size: 28upx;
color: #999;
border-radius: 50upx;
border: 1px solid #999;
width: 160upx;
height: 60upx;
text-align: center;
line-height: 60upx;
}
.shoppingCart .footer .button form~form {
margin-left: 17upx;
}
.writeoff {
opacity: 0.6;
}
.he {
display: flex;
justify-content: space-between;
.txt {
font-size: 22upx;
}
}
.box {
position: fixed;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 10;
background-color: #78797a;
.small_box {
position: fixed;
top: 50%;
right: 75rpx;
left: 75rpx;
padding: 40rpx;
border-radius: 32rpx;
background: #FFFFFF;
transform: translateY(-50%);
image {
width: 100%;
height: 228upx;
}
.content {
// height: 200upx;
text-align: center;
.font {
font-weight: 500;
font-size: 32rpx;
line-height: 52rpx;
color: #333333;
}
.small_font {
margin-top: 24rpx;
font-size: 30rpx;
line-height: 42rpx;
color: #666666;
}
}
.btn-box {
margin-top: 40rpx;
}
.btn {
flex: 1;
height: 72rpx;
border: 1rpx solid $primary-admin;
border-radius: 36rpx;
margin-left: 32rpx;
transform: rotateZ(360deg);
text-align: center;
font-weight: 500;
font-size: 26rpx;
line-height: 70rpx;
color: #2A7EFB;
&:first-child {
margin-left: 0;
}
&.on {
background: $primary-admin;
color: #FFFFFF;
}
}
}
}
.uni-p-b-96 {
height: 96upx;
}
</style>

View File

@@ -0,0 +1,267 @@
<template>
<!-- 核销订单下拉列表 -->
<view>
<view class="product-window"
:class="(attr.cartAttr === true ? 'on' : '') + ' ' + (iSbnt?'join':'') + ' ' + (iScart?'joinCart':'')">
<view class="textpic acea-row row-between-wrapper">
<view class="iconfont icon-guanbi" @click="closeAttr"></view>
</view>
<view class="rollTop">
<view class="scan">
<view class="header" :style="{backgroundImage:'url('+imgHost+'/statics/images/banner.png'+')'}">
请选择当前核销订单
</view>
<view class="box">
<view class="content" v-for="(item,index) in list" :key="index" @click="sure(item.id)">
<view class="content_box">
<image :src="item.image" mode=""></image>
<view class="content_box_title">
<p class="textbox">订单号:{{ item.order_id }}</p>
<p class="attribute mar">下单时间:{{ item.add_time }}</p>
<view class="txt">
<p class="attribute">订单实付:¥{{ item.pay_price }}</p>
<p class="orange" v-if="item._status == 12">部分核销</p>
<p class="attributes blue" v-if="item._status == 11">未核销</p>
<slot name="bottom"></slot>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {orderWriteoffInfo} from '@/api/admin'
import {HTTP_REQUEST_URL} from '@/config/app';
export default {
props: {
attr: {
type: Object,
default: () => {}
},
iSbnt: {
type: Number,
value: 0
},
iScart: {
type: Number,
value: 0
},
},
data() {
return {
verify_code:'',
list: [],
imgHost:HTTP_REQUEST_URL,
};
},
mounted() {},
methods: {
closeAttr: function() {
this.$emit('myevent');
},
getList:function(type) {
this.attr.type = type;
// uni.showLoading({
// title: '加载中'
// });
orderWriteoffInfo(type,{verify_code:this.attr.code,code_type:2}).then(res=>{
// uni.hideLoading();
this.list = res.data;
}).catch(err=>{
// uni.hideLoading();
this.$util.Tips({
title: err
});
})
},
sure:function(data) {
this.$emit('dataId',data);
this.$emit('myevent');
}
}
}
</script>
<style scoped lang="scss">
.vip-money {
color: #282828;
font-size: 28rpx;
font-weight: 700;
margin-left: 6rpx;
}
.vipImg {
width: 68rpx;
height: 27rpx;
image {
width: 100%;
height: 100%;
}
}
.product-window {
position: fixed;
bottom: 0;
width: 100%;
left: 0;
background-color: #f5f5f5;
z-index: 100;
border-radius: 16rpx 16rpx 0 0;
transform: translate3d(0, 100%, 0);
transition: all .3s cubic-bezier(.25, .5, .5, .9);
padding-bottom: 140rpx;
padding-bottom: calc(140rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
padding-bottom: calc(140rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
}
.product-window.on {
transform: translate3d(0, 0, 0);
}
.product-window.join {
padding-bottom: 30rpx;
}
.product-window.joinCart {
// padding-bottom: 30rpx;
z-index: 10000;
}
.product-window .textpic {
padding: 0 130rpx 0 30rpx;
margin-top: 29rpx;
position: relative;
}
.product-window .textpic .pictrue {
width: 150rpx;
height: 150rpx;
}
.product-window .textpic .pictrue image {
width: 100%;
height: 100%;
border-radius: 10rpx;
}
.product-window .textpic .text {
width: 410rpx;
font-size: 32rpx;
color: #202020;
}
.product-window .textpic .text .money {
font-size: 24rpx;
margin-top: 40rpx;
}
.product-window .textpic .text .money .num {
font-size: 36rpx;
}
.product-window .textpic .text .money .stock {
color: #999;
margin-left: 6rpx;
}
.product-window .textpic .iconfont {
position: absolute;
right: 30rpx;
top: -5rpx;
font-size: 35rpx;
color: #8a8a8a;
}
.product-window .rollTop {
max-height: 700rpx;
overflow: auto;
margin-top: 36rpx;
.scan{
padding-bottom: 160upx;
.header {
width: 100%;
height: 220upx;
// background-image: url(../../static/images/banner.png);
background-repeat: no-repeat; //不重复
background-size: 100% 100%;
color: #FFFFFF;
font-size: 32upx;
text-align: center;
line-height: 160upx;
margin: 0 auto;
}
.box{
margin: -64upx auto 0 auto;
}
.content{
margin: 16upx auto 16upx auto;
width: 694upx;
// height: 428upx;
padding: 28upx 24upx 32upx;
background: #FFFFFF;
border-radius: 12upx;
.pad{padding: 20upx 20upx 22upx;}
.content_box{
height: 70px;
border-radius: 8upx;
padding-right: 22upx;
display: flex;
justify-content: flex-start;
align-items: center;
image{
width: 140upx;
height: 140upx;
border-radius: 8upx;
}
.content_box_title{
flex: 1;
margin-left: 18upx;
font-size: 20upx;
font-weight: 400;
.textbox{
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
width: 466upx;
font-size: 30upx;
font-weight: bold;
line-height: 21px;
}
.mar{margin: 16upx 0upx;}
.attribute{
color: #999999;
// margin: 4upx 0upx 10upx;
}
.txt{
display: flex;
justify-content: space-between;
font-size: 24upx;
.orange{color: #FF7E00;}
.blue{color: #1890FF;}
}
}
}
.content_bottom{
display: flex;
justify-content: space-between;
font-size: 22upx;
padding: 0upx 20upx;
color: #666666;
.money{
font-size: 26upx;
color: #F5222D;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,817 @@
<template>
<view class="deliver-goods">
<header class="header">
<view class="order-num">
<view class="num line1">订单号:{{ order_id }}</view>
</view>
<view class="address">
<view class="name">
<text class="iconfont icon-ic_location4"></text>
{{ delivery.real_name }}
<text class="phone">{{ delivery.user_phone }}</text>
</view>
<view>地址:{{ delivery.user_address }}</view>
</view>
<view class="line">
<image src="@/static/images/line.jpg" />
</view>
</header>
<view class="wrapper">
<view class="item acea-row row-between-wrapper">
<view>发货方式</view>
<view class="mode acea-row row-middle row-right">
<template v-for="(item, index) in types">
<view v-if="item.show" class="goods" :class="(active === index || productType==3) ? 'on' : ''" :key="index" @click="changeType(item, index)">
<text :class="['iconfont', active === index ? 'icon-ic_Selected' : 'icon-ic_unselect']"></text>
{{ item.title }}
</view>
</template>
</view>
</view>
<block v-if="logistics.length>0">
<view class="list" v-show="active === 0">
<view class="item acea-row row-middle" v-if="delivery.config_export_open == 1">
<view>发货类型</view>
<view class="mode acea-row row-middle row-right">
<view class="goods" :class="curExpress === item.key ? 'on' : ''" v-for="(item, index) in expressType" :key="index" @click="changeExpTpe(item, index)">
<text :class="['iconfont', curExpress === item.key ? 'icon-ic_Selected' : 'icon-ic_unselect']"></text>
{{ item.title }}
</view>
</view>
</view>
<block v-if="curExpress == 1">
<view class="item acea-row row-middle">
<view>快递公司</view>
<view class="select-box">
<picker class="pickerBox" @change="bindPickerChange" :value="seIndex" :range="logistics" range-key="name">
<view class="uni-input">{{logistics[seIndex].name}}</view>
</picker>
</view>
<text class="iconfont icon-ic_rightarrow"></text>
</view>
<view class="item acea-row row-middle">
<view>快递单号</view>
<input type="text" placeholder="请输入" v-model="delivery_id" class="mode" />
<!-- #ifdef MP -->
<text class="iconfont icon-xiangji" @click="scanCode"></text>
<!-- #endif -->
<!-- #ifdef H5 -->
<text v-if="isWeixin" class="iconfont icon-xiangji" @click="scanCode"></text>
<!-- #endif -->
</view>
<view class="item">
<view class="trip" v-if="curExpress == 1">顺丰请输入单号 :收件人或寄件人手机号后四位</view>
<view class="trip" v-if="curExpress == 1">例如:SF000000000000:3941</view>
</view>
</block>
<block v-if="curExpress == 2">
<view class="item acea-row row-between-wrapper">
<view>寄件人姓名</view>
<input type="text" placeholder="填写寄件人姓名" v-model="to_name" class="mode" />
</view>
<view class="item acea-row row-between-wrapper">
<view>寄件人电话</view>
<input type="text" placeholder="填写寄件人电话" v-model="to_tel" class="mode" />
</view>
<view class="item acea-row row-between-wrapper">
<view>寄件人地址</view>
<input type="text" placeholder="填写寄件人地址" v-model="to_addr" class="mode" />
</view>
<view class="item acea-row row-between-wrapper">
<view>快递公司</view>
<view class="select-box">
<picker class="pickerBox" @change="bindPickerChange" :value="seIndex" :range="logistics" range-key="name">
<!-- <view></view> -->
<view class="uni-input">{{logistics[seIndex].name}}</view>
</picker>
</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="expTemp.length>0">
<view>电子面单</view>
<view class="picker-add">
<picker class="pickerBox" @change="bindTempChange" :value="expIndex" :range="expTemp" range-key="title">
<view class="uni-input">{{expTemp[expIndex].title}}</view>
</picker>
<view class="look" @click="previewImage">预览</view>
</view>
</view>
</block>
</view>
</block>
<view class="list" v-show="active === 1">
<view class="item acea-row row-between-wrapper">
<view>送货人</view>
<view class="select-box" v-if="postPeople.length>0">
<picker class="pickerBox" @change="bindPostChange" :value="postIndex" :range="postPeople" range-key="wx_name">
<view class="acea-row row-middle">
<view class="uni-input">{{postPeople[postIndex].wx_name}}</view>
<text class="iconfont icon-ic_rightarrow"></text>
</view>
</picker>
</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="postPeople[postIndex]">
<view>手机号</view>
<view class="select-box acea-row row-middle row-right">{{postPeople[postIndex].phone}}</view>
</view>
</view>
<textarea v-show="active === 2" v-model="fictitious_content" class="textarea" @blur="bindTextAreaBlur" placeholder="备注" :maxlength="500" auto-height />
</view>
<view class="split-wrapper" v-if="totalNum>1">
<view class="split-switch acea-row row-between-wrapper">
<view>分单发货</view>
<view class="switch" :class="{ on: curGoods }" @click="changeGoods"></view>
</view>
<splitOrder :select_all="false" :splitGoods="splitGoods" @getList="getList" v-if="curGoods"></splitOrder>
</view>
<view class="height-add"></view>
<view class="confirm-wrapper">
<view class="confirm" @click="saveInfo">确认提交</view>
</view>
</view>
</template>
<script>
import {
getAdminOrderDelivery,
setAdminOrderDelivery,
getLogistics,
orderExportTemp,
orderDeliveryInfo,
orderOrderDelivery,
orderSplitInfo,
orderSplitDelivery
} from "@/api/admin";
import splitOrder from '@/components/splitOrder';
export default {
name: "GoodsDeliver",
components: {
splitOrder
},
props: {},
data: function() {
return {
types: [{
type: "express",
title: "发货",
key: 1,
show: true,
},
{
type: "send",
title: "送货",
key: 2,
show: true,
},
{
type: "fictitious",
title: "无需物流",
key: 3,
show: true,
}
],
expressType: [{
title: '手动填写',
key: 1
},
{
title: '电子面单打印',
key: 2
},
],
orderGoods: [{
title: '开启',
key: 1
},
{
title: '关闭',
key: 0
}
],
curExpress: 1,
active: 0,
order_id: "",
delivery: [],
logistics: [],
delivery_type: "1",
delivery_name: "",
delivery_id: "",
seIndex: 0,
expIndex: 0,
expTemp: [], // 快递模板
to_name: '', // 发货人名称
to_tel: '', // 发货人电话
to_addr: "", // 发货人地址
postPeople: [], //配送人
postIndex: 0,
fictitious_content: '',
listId: 0,
curGoods: 0,
splitGoods: [],
cartIds: [],
totalNum: 0,
productType: 0,
// #ifdef H5
isWeixin: this.$wechat.isWeixin()
// #endif
};
},
watch: {
"$route.params.oid": function(newVal) {
let that = this;
if (newVal != undefined) {
that.order_id = newVal;
that.getIndex();
}
}
},
onLoad: function(option) {
this.order_id = option.id;
this.listId = option.listId;
this.totalNum = option.totalNum;
this.comeType = option.comeType;
this.productType = option.productType
if (this.productType == 3) {
// this.types.splice(0, 2);
for (let i = 0; i < this.types.length; i++) {
if (i == 2) {
this.types[i].show = true;
} else {
this.types[i].show = false;
}
}
this.delivery_type = 3;
this.active = 2;
}
if (option.orderStatus == 8 || option.orderStatus == 4 || option.orderStatus == 9) {
this.curGoods = 1;
this.orderGoods.pop();
this.splitList();
}
this.getIndex();
this.getLogistics();
this.orderDeliveryInfo()
this.geTorderOrderDelivery()
},
methods: {
getList(val) {
let that = this;
that.splitGoods = val;
let cartIds = [];
val.forEach((item) => {
if (item.checked) {
let i = {
cart_id: item.cart_id,
cart_num: item.surplus_num
}
cartIds.push(i)
}
})
this.cartIds = cartIds;
},
splitList() {
orderSplitInfo(this.listId).then(res => {
let list = res.data;
list.forEach((item) => {
item.checked = false
item.numShow = item.surplus_num
})
this.splitGoods = list;
}).catch(err => {
return this.$util.Tips({
title: err
});
})
},
// 点击获取拆单列表
changeGoods() {
this.curGoods = this.curGoods ? 0 : 1;
if (this.curGoods) {
this.splitList();
}
},
// 扫描快递单号一维码
scanCode() {
// #ifdef MP
let that = this;
uni.scanCode({
scanType: ['barCode'],
success(res) {
that.delivery_id = res.result;
}
})
// #endif
// #ifdef H5
if (this.$wechat.isWeixin()) {
this.$wechat.wechatEvevt('scanQRCode', {
needResult: 1,
scanType: ['barCode']
}).then(res => {
let result = res.resultStr.split(",");
this.delivery_id = result[1];
});
}
// #endif
},
// 预览图片
previewImage() {
uni.previewImage({
urls: [this.expTemp[this.expIndex].pic],
success: function() {
},
fail: function(error) {
}
});
},
// 获取配送员列表
geTorderOrderDelivery() {
orderOrderDelivery().then(res => {
this.postPeople = res.data
})
},
// 配送员选择
bindPostChange(e) {
this.postIndex = e.detail.value
},
// 选择发货类型
changeExpTpe(item, index) {
this.curExpress = item.key
this.getLogistics(index || '');
},
changeType: function(item, index) {
this.active = index;
this.delivery_type = item.key;
},
getIndex: function() {
let that = this;
getAdminOrderDelivery(that.order_id).then(
res => {
that.delivery = res.data;
},
error => {
that.$util.Tips({
title: error
})
}
);
},
getLogistics(status) {
let that = this;
getLogistics({
status
}).then(
res => {
that.logistics = res.data;
that.getExpTemp(res.data[0].code)
},
error => {
that.$util.Tips({
title: error
})
}
);
},
async saveInfo() {
let that = this,
delivery_type = that.delivery_type,
delivery_name = that.logistics[that.seIndex].name,
delivery_id = that.delivery_id,
userName = that.delivery_name,
save = {};
save.delivery_type = delivery_type;
save.delivery_code = that.logistics[that.seIndex].code
save.delivery_name = that.logistics[that.seIndex].name
save.type = that.active + 1
if (delivery_type == 1 && this.curExpress == 1) {
if (!delivery_id) {
return this.$util.Tips({
title: '请填写快递单号'
})
}
save.express_record_type = that.curExpress
save.delivery_id = delivery_id
if (that.curGoods) {
that.setSplitInfo(save)
} else {
that.setInfo(save);
}
}
if (delivery_type == 1 && this.curExpress == 2) {
if (!that.to_name) {
return this.$util.Tips({
title: '请填写寄件人姓名'
})
}
if (!that.to_tel) {
return this.$util.Tips({
title: '请填写寄件人手机号码'
})
}
if (!(/^1[3456789]\d{9}$/.test(that.to_tel))) {
return this.$util.Tips({
title: '请填写寄件人手机号码'
})
}
if (!that.to_addr) {
return this.$util.Tips({
title: '请填写寄件人地址'
})
}
if (that.expTemp.length == 0) {
return this.$util.Tips({
title: '请选择电子面单'
})
}
save.express_record_type = that.curExpress
save.to_name = that.to_name
save.to_tel = that.to_tel
save.to_addr = that.to_addr
save.express_temp_id = that.expTemp[that.expIndex].temp_id
if (that.curGoods) {
that.setSplitInfo(save)
} else {
that.setInfo(save);
}
}
if (delivery_type == 2) {
if (!that.postPeople.length) {
return this.$util.Tips({
title: '请在平台后台添加送货人'
})
}
let obj = this.postPeople[this.postIndex]
let params = {}
params.type = that.delivery_type
params.sh_delivery_name = obj.wx_name
params.sh_delivery_id = obj.phone
params.sh_delivery_uid = obj.uid
if (that.curGoods) {
that.setSplitInfo(params)
} else {
that.setInfo(params);
}
}
if (delivery_type == 3) {
let params = {}
params.type = that.delivery_type;
params.fictitious_content = that.fictitious_content;
if (that.curGoods) {
that.setSplitInfo(params)
} else {
that.setInfo(params);
}
}
},
setInfo: function(item) {
let that = this;
setAdminOrderDelivery(that.delivery.id, item).then(
res => {
that.$util.Tips({
title: res.msg,
icon: 'success',
mask: true
})
setTimeout(res => {
if (this.comeType == 2) {
uni.navigateTo({
url: '/pages/admin/orderDetail/index?id=' + this.order_id
})
} else {
uni.navigateTo({
url: '/pages/admin/orderList/index?types=1'
})
}
}, 2000)
},
error => {
that.$util.Tips({
title: error
})
}
);
},
setSplitInfo(item) {
if (!this.cartIds.length) {
return this.$util.Tips({
title: '请选择发货商品'
})
}
item.cart_ids = this.cartIds
orderSplitDelivery(this.delivery.id, item).then(res => {
this.$util.Tips({
title: res.msg,
icon: 'success',
mask: true
})
setTimeout(res => {
if (this.comeType == 2) {
uni.navigateTo({
url: '/pages/admin/orderDetail/index?id=' + this.order_id
})
} else {
uni.navigateTo({
url: '/pages/admin/orderList/index?types=1'
})
}
}, 2000)
}).catch(err => {
this.$util.Tips({
title: err
})
})
},
bindPickerChange(e) {
this.seIndex = e.detail.value
this.getExpTemp(this.logistics[e.detail.value].code)
},
bindTempChange(e) {
this.expIndex = e.detail.value
},
getExpTemp(code) {
orderExportTemp({
com: code
}).then(res => {
this.expTemp = res.data.data
})
},
// 获取订单打印默认配置
orderDeliveryInfo() {
orderDeliveryInfo().then(res => {
this.to_name = res.data.to_name;
this.to_tel = res.data.to_tel;
this.to_addr = res.data.to_add;
})
}
}
};
</script>
<style lang="scss">
.picker-add {
display: flex;
align-items: center;
}
.height-add {
height: 120upx;
}
/*发货*/
.deliver-goods {
padding: 22rpx 20rpx;
}
.deliver-goods .header {
position: relative;
padding: 0 32rpx;
border-radius: 24rpx;
background: #FFFFFF;
overflow: hidden;
}
.deliver-goods .header .order-num {
padding: 20rpx 0;
border-bottom: 1px dotted #EEEEEE;
}
.deliver-goods .header .order-num .num {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
position: relative;
}
.deliver-goods header .order-num .num:after {}
.deliver-goods header .order-num .name {
width: 260upx;
font-size: 26upx;
color: #282828;
text-align: center;
}
.deliver-goods header .order-num .name .iconfont {
font-size: 35upx;
color: #477ef3;
vertical-align: middle;
margin-right: 10upx;
}
.deliver-goods .header .address {
padding: 20rpx 0 40rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.deliver-goods .header .address .name {
font-weight: 500;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
margin-bottom: 12rpx;
}
.deliver-goods .header .address .name .iconfont {
margin-right: 8rpx;
font-size: 32rpx;
}
.deliver-goods .header .address .name .phone {
margin-left: 40rpx;
}
.deliver-goods .header .line {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 4rpx;
}
.deliver-goods .header .line image {
width: 100%;
height: 100%;
display: block;
}
.deliver-goods .wrapper {
padding: 12rpx 0;
border-radius: 24rpx;
margin-top: 20rpx;
background-color: #fff;
}
.deliver-goods .wrapper .item {
padding: 0 24rpx;
height: 80rpx;
font-size: 28rpx;
color: #333333;
position: relative;
}
.deliver-goods .wrapper .item .mode {
flex: 1;
height: 100%;
text-align: right;
}
.deliver-goods .wrapper .item .mode .iconfont {
font-size: 32rpx;
margin-right: 12rpx;
color: #CCCCCC;
}
.deliver-goods .wrapper .item .mode .goods~.goods {
margin-left: 50rpx;
}
.deliver-goods .wrapper .item .mode .goods {
color: #999999;
}
.deliver-goods .wrapper .item .mode .goods.on {
color: #333333;
}
.deliver-goods .wrapper .item .mode .goods.on .iconfont {
color: $primary-admin;
}
.deliver-goods .wrapper .item .icon-up {
position: absolute;
font-size: 35upx;
color: #2c2c2c;
right: 30upx;
}
.deliver-goods .wrapper .item select {
direction: rtl;
padding-right: 60upx;
position: relative;
z-index: 2;
}
.deliver-goods .wrapper .item input::placeholder {
color: #bbb;
}
.deliver-goods .confirm-wrapper {
background-color: #FFFFFF;
position: fixed;
left: 0;
bottom: 0;
bottom: constant(safe-area-inset-bottom);
bottom: env(safe-area-inset-bottom);
width: 100%;
padding: 20rpx;
}
.deliver-goods .confirm {
font-weight: 500;
font-size: 28rpx;
color: #fff;
height: 80rpx;
border-radius: 40rpx;
background: #2A7EFB;
text-align: center;
line-height: 80rpx;
}
.select-box {
flex: 1;
height: 100%;
.pickerBox {
display: flex;
align-items: center;
justify-content: flex-end;
width: 100%;
height: 100%;
.iconfont {
margin-left: 8rpx;
font-size: 24rpx;
color: #999999;
}
}
}
.look {
margin-left: 20rpx;
color: $primary-admin;
}
.textarea {
display: block;
min-height: 192rpx;
padding: 24rpx;
width: 100%;
// border-bottom: 1px solid #f0f0f0;
box-sizing: border-box;
}
.icon-xiangji {
font-size: 35rpx;
color: $primary-admin;
}
.trip {
font-size: 22rpx;
color: #ccc;
padding: 6rpx 0;
}
.split-wrapper {
border-radius: 24rpx;
margin-top: 20rpx;
background: #FFFFFF;
.splitOrder {
padding: 0 24rpx 46rpx;
margin: 0;
}
}
.split-switch {
padding: 40rpx 24rpx;
font-size: 28rpx;
color: #333333;
.switch {
position: relative;
width: 79rpx;
height: 48rpx;
padding: 4rpx;
border-radius: 24rpx;
background: #DDDDDD;
transition: background 0.1s, border 0.1s;
&::after {
content: "";
position: absolute;
top: 4rpx;
left: 4rpx;
width: 40rpx;
height: 40rpx;
border-radius: 20rpx;
background: #FFFFFF;
box-shadow: 0 3rpx 6rpx 0 rgba(0, 0, 0, 0.08);
transition: transform 0.35s cubic-bezier(0.4, 0.4, 0.25, 1.35);
}
&.on {
background: #2A7EFB;
&::after {
transform: translateX(31rpx);
}
}
}
}
</style>

View File

@@ -0,0 +1,905 @@
<template>
<view>
<!-- #ifdef MP || APP -->
<NavBar titleText="配送员" :iconColor="iconColor" :textColor="iconColor" :isScrolling="isScrolling" showBack></NavBar>
<!-- #endif -->
<view class="headerBg"></view>
<view class="order-index">
<view class="header acea-row row-middle">
<image :src="user.avatar" class="avatar"></image>
<view class="text">
<view class="name line1">{{ user.nickname }}</view>
<view class="phone">{{ user.phone }}</view>
</view>
<view class="item">
<!-- #ifdef APP-PLUS || MP-WEIXIN -->
<view class="item">
<view class="iconfont icon-ic_Scan ite" @click="to"></view>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view v-if="isWeixin" class="item">
<view class="iconfont icon-ic_Scan ite" @click="to"></view>
</view>
<!-- #endif -->
</view>
</view>
<view v-show="footer == 'tongji'" class="">
<view class="wrapper">
<view class="title acea-row row-between row-middle">
<view class="uni-list-cell-db" @click="hiddened">
<picker @change="bindPickerChange" :range="arrays" @cancel="cancel">
<label class="aa">{{array.length && array[index].name}}</label>
<text class='iconfont' :class='hidden==true?"icon-ic_downarrow":"icon-ic_uparrow"'></text>
</picker>
</view>
<view class="tab acea-row">
<view class="box" :class="detailtabs== 'today' ? 'on':''" @click="detailtab('today')">今日</view>
<view class="box" :class="detailtabs== 'yesterday' ? 'on':''" @click="detailtab('yesterday')">昨日</view>
<view class="box" :class="detailtabs== 'month' ? 'on':''" @click="detailtab('month')">本月</view>
</view>
</view>
<Loading :loaded="loaded" :loading="loading"></Loading>
<view class="list acea-row" v-if="!loading">
<view class="item">
<view class="num">{{ census.unsend || 0 }}</view>
<view>待配送</view>
</view>
<view class="item">
<view class="num">{{ census.send || 0 }}</view>
<view>已配送</view>
</view>
<view class="item">
<view class="num">{{ census.send_price || 0 }}</view>
<view>配送金额</view>
</view>
</view>
</view>
<view class="public-wrapper">
<view class="title">
<view class="uni-list-cell-db" @click="hiddened">
详细数据
</view>
</view>
<view class="nav acea-row row-between-wrapper">
<view class="data">日期</view>
<view class="browse">订单数</view>
<view class="turnover">配送金额</view>
</view>
<Loading :loaded="loaded" :loading="loading"></Loading>
<view v-if="list.length" class="conter">
<view class="item acea-row row-between-wrapper" v-for="(item, index) in list" :key="index">
<view class="data">{{ item.time }}</view>
<view class="browse">{{ item.count }}</view>
<view class="turnover">¥ {{ item.price }}</view>
</view>
</view>
<view v-else class="unconter">
<view v-if="!loading">暂无数据</view>
</view>
</view>
</view>
<view v-show="footer == 'list'" class="tongji-index">
<view class="tabbar acea-row">
<view class="item" :class="{ active: type == 1 }">
<view class="text-box"></view>
<view class="item-box"></view>
<view class="inner acea-row row-center row-middle" @click="tab('1')">待配送({{ count.unsend }})</view>
</view>
<view class="item" :class="{ active: type == 2 }">
<view class="text-box"></view>
<view class="item-box"></view>
<view class="inner acea-row row-center row-middle" @click="tab('2')">已配送({{ count.send }})</view>
</view>
</view>
<view class="content">
<view class="item" v-for="(item,index) in orderlist" :key="index" @click="jump(item.id)">
<view class="item-top acea-row row-between row-middle">
<view class="">订单号:{{ item.order_id }}</view>
<view style="color: #FF7E00;">{{type == 1?'待配送':'已配送'}}</view>
</view>
<view class="item-center acea-row">
<scroll-view v-if="item.cart_id.length > 1" class="goods-section scroll-view" scroll-x="true">
<image v-for="(value, i) in item._info" :key="i" :src="value.cart_info.productInfo.image" class="image"></image>
</scroll-view>
<view v-else class="goods-section">
<view v-for="(value, i) in item._info" :key="i" class="acea-row">
<image :src="value.cart_info.productInfo.image" class="image"></image>
<view class="name-wrap">
<view class="name line2">{{ value.cart_info.productInfo.store_name }}</view>
<view class="attr line1">{{ value.cart_info.productInfo.attrInfo.suk }}</view>
</view>
</view>
</view>
<view class="money-section">
<baseMoney :money="item.pay_price" symbolSize="20" integerSize="32" decimalSize="20"></baseMoney>
<view class="num">共{{ item.total_num }}件</view>
</view>
</view>
<view class="item-bottom acea-row">
<view>配送地址:</view>
<view class="info">{{ item.user_address }}</view>
</view>
<!-- <view class="content_box" v-for="(val, key) in item._info" :key="key">
<image :src="val.cart_info.productInfo.image" mode=""></image>
<view class="content_box_title">
<view class="txt">
<view class="textbox"><text class="icon-color" v-if="val.cart_info.is_gift">[赠品]</text>{{ val.cart_info.productInfo.store_name }}</view>
<view>x {{ val.cart_info.cart_num }}</view>
</view>
<p class="attribute">属性:{{ val.cart_info.productInfo.attrInfo.suk }}</p>
<p>¥ {{ val.cart_info.productInfo.attrInfo.price }} </p>
</view>
</view> -->
<!-- <view class="content_bottom">
<view></view>
<view>共{{ item.total_num }}件商品,订单实付:<span class="money">¥{{ item.pay_price }}</span></view>
</view> -->
</view>
<emptyPage v-if="!orderlist.length && !loading" title="暂无数据~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
<Loading :loaded="loaded" :loading="loading"></Loading>
</view>
</view>
<view class="footer">
<view class="footer-inner acea-row">
<view class="tab acea-row row-column row-center row-middle" :class="footer == 'list'?'on':''" @click="footerTab('list')">
<image v-if="footer == 'list'" :src="imgHost+'/statics/images/admin-order-menu2.png'" class="image"></image>
<image v-else :src="imgHost+'/statics/images/admin-order-menu1.png'" class="image"></image>
<view class="font">订单列表</view>
</view>
<view class="tab acea-row row-column row-center row-middle" :class="footer == 'tongji'?'on':''" @click="footerTab('tongji')">
<image v-if="footer == 'tongji'" :src="imgHost+'/statics/images/admin-order-menu4.png'" class="image"></image>
<image v-else :src="imgHost+'/statics/images/admin-order-menu3.png'" class="image"></image>
<view class="font">数据统计</view>
</view>
</view>
<view class="safe-area-inset-bottom"></view>
</view>
<view class="footer-placeholder"></view>
<view class="safe-area-inset-bottom"></view>
</view>
</template>
<script>
import {
// getStatisticsInfo,
// getStatisticsMonth,
deliveryInfo,
deliveryStatistics,
deliveryList,
deliveryOrderList,
orderWriteoffInfo
} from "@/api/admin";
import Loading from '@/components/Loading/index.vue';
import emptyPage from '@/components/emptyPage.vue'
// #ifdef MP || APP
import NavBar from '@/components/NavBar.vue';
// #endif
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
name: 'adminOrder',
components: {
Loading,
emptyPage,
// #ifdef MP || APP
NavBar,
// #endif
},
data() {
return {
hidden: true,
index: 0,
detailtabs: 'today',
footer: 'list',
type: '1',
arrays: [], //展示下拉时的数据
array: [], //下拉时选择的数据
storeInfoid: 0, //下拉时选择的数据ID
census: {},
list: [],
orderlist: [],
count: {},
page: 1,
limit: 15,
loaded: false,
loading: false,
user: {},
ids: '',
verify_code: '',
// #ifdef H5
isWeixin: this.$wechat.isWeixin(),
// #endif
imgHost: HTTP_REQUEST_URL,
// #ifdef MP || APP
iconColor: '#FFFFFF',
isScrolling: false,
// #endif
}
},
onLoad() {
// this.getIndex();
// this.init()
this.userInfo();
this.footerTab('list')
// this.$scroll(this.$refs.container, () => {
// !this.loading && this.getList();
// });
},
methods: {
userInfo() {
deliveryInfo().then(res => {
this.user = res.data
this.array = res.data.store_info.map(a => a);
this.arrays = res.data.store_info.map(a => a.name);
let obj = {
id: 0,
name: '全部'
}
this.array.unshift(obj);
this.arrays.unshift(obj.name);
})
},
getStatistics() {
let data = {
store_id: this.storeInfoid,
data: this.detailtabs
}
deliveryStatistics(data).then(res => {
this.census = res.data
})
},
deliveryLists() {
let data = {
page: this.page,
limit: this.limit,
store_id: this.storeInfoid,
data: this.detailtabs
}
if (this.loading || this.loaded) return;
this.loading = true
deliveryList(data).then(res => {
this.loading = false
this.loaded = res.data.length < this.limit
this.page += 1
// this.list = res.data
this.list.push.apply(this.list, res.data);
})
},
getOrderList() {
if (this.loading || this.loaded) return;
this.loading = true
deliveryOrderList({
type: this.type,
page: this.page,
limit: this.limit
}).then(res => {
this.loading = false
this.count = res.data.data
this.loaded = res.data.list.length < this.limit
this.page += 1
let arr = [];
for (let i = 0; i < res.data.list.length; i++) {
arr = [];
for (let j = 0; j < res.data.list[i].user_address.length; j++) {
if (res.data.list[i].user_address[j] != ' ') {
arr.push(res.data.list[i].user_address[j]);
}
}
res.data.list[i].user_address = arr.join('');
}
this.orderlist.push.apply(this.orderlist, res.data.list);
})
},
init: function() {
this.orderlist = [];
this.list = [];
this.page = 1;
this.loaded = false;
this.loading = false;
},
to() {
var self = this;
// #ifdef MP || APP
uni.scanCode({
scanType: ["qrCode", "barCode"],
success(res) {
self.verify_code = res.result
self.codeChange();
},
fail(res) {},
})
// #endif
//#ifdef H5
this.$wechat.wechatEvevt('scanQRCode', {
needResult: 1,
scanType: ["qrCode", "barCode"]
}).then(res => {
let result = res.resultStr;
if (result.includes(',')) {
result = result.split(",")[1]
}
this.verify_code = result
this.codeChange();
});
//#endif
},
// 立即核销
codeChange: function() {
let self = this
let ref = /^[0-9]*$/;
if (!this.verify_code) return self.$util.Tips({
title: '请输入核销码'
});
if (!ref.test(this.verify_code)) return self.$util.Tips({
title: '请输入正确的核销码'
});
self.$util.Tips({
title: '查询中'
});
setTimeout(() => {
orderWriteoffInfo(2, {
verify_code: self.verify_code,
code_type: 2
}).then(res => {
if (res.status == 200) {
uni.navigateTo({
url: './scanning/index?code=' + self.verify_code
})
} else {
self.$util.Tips({
title: res.msg
});
}
}).catch(err => {
self.$util.Tips({
title: err
});
})
}, 800);
},
footerTab: function(type) {
this.footer = type
this.init()
if (type == 'tongji') {
this.deliveryLists()
this.getStatistics()
}
if (type == 'list') {
this.getOrderList()
}
},
tab(type) {
this.type = type
this.init()
this.getOrderList()
},
hiddened: function(e) {
this.hidden = !this.hidden;
},
cancel: function() {
this.hidden = !this.hidden;
},
bindPickerChange: function(e) {
this.hidden = !this.hidden;
this.index = e.target.value
this.storeInfoid = this.array[this.index].id
this.init()
this.getStatistics()
this.deliveryLists()
},
detailtab: function(type) {
this.detailtabs = type
this.init()
this.deliveryLists()
this.getStatistics()
},
jump: function(id) {
uni.navigateTo({
url: 'orderDetail/index?id=' + id
})
}
},
onReachBottom() {
if (this.footer == 'tongji') {
this.deliveryList()
}
if (this.footer == 'list') {
this.getOrderList()
}
}
}
</script>
<style lang="scss" scoped>
.footer-placeholder {
height: 100rpx;
}
.safe-area-inset-bottom {
height: 0;
height: constant(safe-area-inset-bottom);
height: env(safe-area-inset-bottom);
}
.nothing {
width: 80%;
margin: 0 auto;
margin-top: 30px;
text-align: center;
color: #cfcfcf;
}
.ite {
font-size: 20px;
}
.footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background: #FFFFFF;
.footer-inner {
height: 100rpx;
}
.tab {
flex: 1;
font-size: 20rpx;
line-height: 28rpx;
color: #333333;
.image {
width: 40rpx;
height: 40rpx;
margin-bottom: 6rpx;
}
}
.on {
color: #2A7EFB;
.font {
color: #2A7EFB;
}
}
}
/*订单首页*/
.headerBg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 516rpx;
background: linear-gradient(270deg, #01ABF8 0%, #2A7EFB 100%);
}
.header {
padding: 22rpx 40rpx 32rpx 32rpx;
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.text {
flex: 1;
padding-left: 16rpx;
font-size: 22rpx;
line-height: 30rpx;
color: #FFFFFF;
}
.name {
font-weight: 500;
font-size: 32rpx;
line-height: 44rpx;
}
.phone {
margin-top: 4rpx;
}
.items,
.item {
font-size: 24upx;
color: #fff;
height: 120upx;
display: flex;
align-items: center;
image {
width: 64upx;
height: 64upx;
border-radius: 60upx;
border: 2upx solid #FFFFFF;
}
.font {
display: inline-block;
margin-left: 16upx;
margin-right: 16upx;
font-size: 30upx;
}
}
}
.order-index {
position: relative;
.tongji-index {
padding: 0 20rpx;
.empty-page{
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
.tabbar {
position: relative;
z-index: 5;
height: 96rpx;
border-radius: 24rpx 24rpx 0 0;
overflow: hidden;
.item {
position: relative;
z-index: 5;
flex: 1;
font-size: 28rpx;
color: #333333;
&:last-child {
.item-box {
border-radius: 18rpx 0 0 0;
transform: perspective(80rpx) scaleX(1.4) scaleY(1.5) rotateX(20deg) translate(20rpx, 0);
}
.text-box {
border-radius: 0 24rpx 0 0;
}
}
&.active {
font-weight: 500;
color: #2A7EFB;
.item-box {
display: block;
}
}
}
.text-box {
position: absolute;
bottom: 0;
width: 100%;
height: 78rpx;
border-radius: 24rpx 0 0 0;
background: rgba(255, 255, 255, 0.95);
}
.item-box {
display: none;
position: absolute;
bottom: 0;
z-index: 2;
width: 100%;
height: 96rpx;
border-radius: 0 18rpx 0 0;
background: #FFFFFF;
transform-origin: center bottom;
transform: perspective(80rpx) scaleX(1.4) scaleY(1.5) rotateX(20deg) translate(-20rpx, 0);
}
.inner {
position: absolute;
bottom: 0;
z-index: 3;
width: 100%;
height: 78rpx;
}
}
.content {
.item {
padding: 32rpx 24rpx;
border-radius: 24rpx;
margin-bottom: 20rpx;
background: #FFFFFF;
&:first-child {
border-radius: 0 0 24rpx 24rpx;
}
}
.item-top {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.item-center {
margin-top: 26rpx;
}
.goods-section {
flex: 1;
min-width: 0;
white-space: nowrap;
.image {
width: 136rpx;
height: 136rpx;
border-radius: 16rpx;
}
.name-wrap {
flex: 1;
min-width: 0;
padding-left: 20rpx;
}
.name {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.attr {
margin-top: 12rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
}
.scroll-view {
box-sizing: border-box;
.image {
margin-right: 16rpx;
}
}
.item-bottom {
padding: 18rpx 20rpx;
border-radius: 8rpx;
margin-top: 26rpx;
background: #F5F5F5;
font-size: 26rpx;
line-height: 36rpx;
color: #333333;
.info {
flex: 1;
color: #999999;
}
}
.scroll-view {
box-sizing: border-box;
.image {
margin-right: 16rpx;
}
}
.money-section {
width: 102rpx;
text-align: right;
.num {
margin-top: 8rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
}
}
}
.order-index .header .icon-saoma {
font-size: 40rpx;
padding: 30rpx 20rpx 30rpx 80rpx;
}
.order-index .header .item,
.order-index .header .items {
font-size: 24upx;
color: #fff;
height: 120upx;
display: flex;
align-items: center;
}
.order-index .header .item .font,
.order-index .header .items .font {
display: inline-block;
margin-left: 16upx;
margin-right: 16upx;
font-size: 30upx;
}
.order-index .header .items image {
width: 64upx;
height: 64upx;
border-radius: 60upx;
border: 2upx solid #FFFFFF;
}
.order-index .wrapper {
width: 710rpx;
border-radius: 24rpx;
margin: 0 auto;
background: #FFFFFF;
}
.order-index .wrapper .title .iconfont {
color: #2291f8;
font-size: 40upx;
margin-right: 13upx;
vertical-align: middle;
}
.order-index .wrapper .title {
padding: 32rpx 24rpx;
font-weight: 500;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
.uni-list-cell-db .iconfont {
font-size: 24rpx;
color: #CCCCCC;
margin-left: 12rpx;
}
.tab {
border-radius: 24rpx;
background: #F5F5F5;
.box {
width: 96rpx;
height: 48rpx;
border-radius: 24rpx;
text-align: center;
font-weight: 400;
font-size: 24rpx;
line-height: 48rpx;
color: #999999;
}
.on {
background: #2A7EFB;
color: #FFFFFF;
}
}
}
.order-index .wrapper .list .item {
flex: 1;
padding: 30rpx 0 38rpx;
text-align: center;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.order-index .wrapper .list .item .num {
margin-bottom: 10rpx;
font-family: SemiBold;
font-size: 36rpx;
line-height: 36rpx;
color: #333333;
}
.public-wrapper .title {
padding: 32rpx 24rpx 40rpx;
font-weight: 500;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
.uni-list-cell-db .iconfont {
font-size: 24upx;
color: #999;
margin-left: 14upx;
}
.tab {
width: 240upx;
height: 48upx;
background: #F5F5F5;
border-radius: 24upx;
display: flex;
justify-content: space-between;
font-weight: 400;
color: #999999;
font-size: 24upx;
.box {
width: 82upx;
height: 48upx;
border-radius: 24upx;
text-align: center;
line-height: 48upx;
}
.on {
background: #1890FF;
color: #FFFFFF;
}
}
}
.public-wrapper .title .iconfont {
color: #2291f8;
font-size: 40upx;
margin-right: 13upx;
vertical-align: middle;
}
.public-wrapper {
width: 710rpx;
border-radius: 24rpx;
margin: 20rpx auto 0;
background: #FFFFFF;
}
.public-wrapper .nav {
padding: 0 40rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.public-wrapper .data {
width: 45%;
text-align: left;
}
.public-wrapper .browse {
width: 25%;
}
.public-wrapper .turnover {
width: 30%;
text-align: right;
}
.public-wrapper .conter {
padding: 0 40rpx;
}
.public-wrapper .conter .item {
padding: 20rpx 0;
border-bottom: 1px solid #F1F1F1;
font-size: 24rpx;
line-height: 34rpx;
color: #333333;
}
.public-wrapper .conter .item .turnover {
color: #000000;
font-weight: 400;
}
.public-wrapper .unconter {
text-align: center;
color: #999;
padding: 25upx;
}
</style>

View File

@@ -0,0 +1,635 @@
<template>
<view>
<!-- #ifdef MP || APP -->
<NavBar titleText="订单详情" :iconColor="iconColor" :textColor="iconColor" :isScrolling="isScrolling" showBack></NavBar>
<!-- #endif -->
<view class="headerBg"></view>
<view class="order-details pos-order-details">
<view class="address">
<view v-if="orderInfo.store" class="box acea-row row-middle">
<view class="left">
<view class="text">{{orderInfo.store.name}}</view>
<view class="acea-row row-between-wrapper" @click="showMaoLocation(system_store.latitude,system_store.longitude,system_store.name,system_store.detailed_address)">
<span class="txt">{{ orderInfo.store.detailed_address }}</span>
<span class="iconfont icon-xiangyou"></span>
</view>
</view>
<view>
<view class="iconfont icon-tonghua marrt" @click="makePhone(system_store.phone)"></view>
</view>
</view>
<view class="box acea-row row-middle">
<view class="text-box">
<view class="text"><text class="iconfont icon-ic_receiving"></text>{{orderInfo.nickname}} {{orderInfo.user_phone}}</view>
<view class="acea-row row-between-wrapper">
地址:{{orderInfo.user_address}}
</view>
</view>
<view class="btn" @click.stop="makePhone(orderInfo.user_phone)">
<text class="iconfont icon-ic_phone"></text>
</view>
<view class="btn" @click.stop="showMaoLocation(orderInfo.latitude,orderInfo.longitude,orderInfo.nickname,orderInfo.user_address)">
<text class="iconfont icon-ic_location"></text>
</view>
</view>
<view class="line">
<image src="/static/images/line.jpg" />
</view>
</view>
<view class="goods-section">
<view class="">订单号:{{orderInfo.order_id}}</view>
<view class="goods acea-row" v-for="(item, index) in orderInfo.cartInfo" :key="index">
<view class="picTxt acea-row">
<image :src="item.productInfo.image" class="pictrue"></image>
<view class="text">
<view class="info line1">
{{ item.productInfo.store_name }}
</view>
<view class="attr line1">{{ item.productInfo.attrInfo.suk }}</view>
<view class="label">7天无理由退换货·放心购</view>
</view>
</view>
<view class="money">
<baseMoney :money="item.productInfo.attrInfo.price" symbolSize="20" integerSize="32" decimalSize="20"></baseMoney>
<view class="num">共{{ item.cart_num }}件</view>
</view>
</view>
<view class="giveGoods">
<view class="item acea-row row-between-wrapper" v-for="(item,index) in giveCartInfo" :key="index">
<view class="picTxt acea-row row-middle">
<view class="pictrue">
<image :src="item.productInfo.attrInfo.image" v-if="item.productInfo.attrInfo"></image>
<image :src="item.productInfo.image" v-else></image>
</view>
<view class="texts">
<view class="name line1">[赠品]{{item.productInfo.store_name}}</view>
<view class="limit line1" v-if="item.productInfo.attrInfo">{{item.productInfo.attrInfo.suk}}</view>
</view>
</view>
<view class="num">x{{item.cart_num}}</view>
</view>
<view class="item acea-row row-between-wrapper" v-for="(item,index) in giveData.give_coupon" :key="index" v-if="giveData.give_coupon.length">
<view class="picTxt acea-row row-middle">
<view class="pictrue acea-row row-center-wrapper">
<text class="iconfont icon-pc-youhuiquan"></text>
</view>
<view class="texts">
<view class="line1">[赠品]{{item.coupon_title}}</view>
</view>
</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="giveData.give_integral>0">
<view class="picTxt acea-row row-middle">
<view class="pictrue acea-row row-center-wrapper">
<text class="iconfont icon-pc-jifen"></text>
</view>
<view class="texts">
<view class="line1">[赠品]{{giveData.give_integral}}积分</view>
</view>
</view>
</view>
</view>
</view>
<view class="detail-section">
<view class="item acea-row row-between">
<view>订单编号</view>
<view class="conter acea-row row-middle row-right">
{{ orderInfo.order_id }}
<span class="copy copy-data" @click="copyNum(orderInfo.order_id)">复制</span>
</view>
</view>
<view class="item acea-row row-between">
<view>支付方式</view>
<view class="conter">{{ payType }}</view>
</view>
<view class="item acea-row row-between">
<view>支付时间</view>
<view class="conter">{{ orderInfo._pay_time }}</view>
</view>
<view class="item acea-row row-between">
<view>下单时间</view>
<view class="conter">{{ orderInfo._add_time }}</view>
</view>
<view class="item acea-row row-between" v-if="orderInfo._status">
<view>配送方式</view>
<view class="conter">{{ orderInfo._status._deliveryType }}</view>
</view>
<view class="item acea-row row-between">
<view>买家留言</view>
<view class="conter">{{ orderInfo.mark }}</view>
</view>
</view>
<customForm :customForm="orderInfo.custom_form"></customForm>
<view class="wrapper topnone">
<view class="item acea-row row-between">
<view>商品总价:</view>
<view class="conter">¥{{ (parseFloat(orderInfo.total_price)+parseFloat(orderInfo.vip_true_price)).toFixed(2) }}</view>
</view>
<view class="item acea-row row-between" v-if="orderInfo.coupon_price>0">
<view>优惠券抵扣:</view>
<view class="conter">-¥{{ orderInfo.coupon_price }}</view>
</view>
<view v-if="orderInfo.pay_postage>0" class="item acea-row row-between">
<view>运费:</view>
<view class="conter">¥{{ orderInfo.pay_postage }}</view>
</view>
<view class="item acea-row row-between" v-if="orderInfo.deduction_price>0">
<view>积分抵扣金额:</view>
<view class="conter">-¥{{ orderInfo.deduction_price }}</view>
</view>
<view class="item acea-row row-between" v-if="orderInfo.vip_true_price>0">
<view>会员商品优惠:</view>
<view class="conter">-¥{{ orderInfo.vip_true_price }}</view>
</view>
<view class='item acea-row row-between' v-for="(item,index) in orderInfo.promotions_detail" :key="index" v-if="parseFloat(item.promotions_price)">
<view>{{item.title}}:</view>
<view class='conter'>-¥{{parseFloat(item.promotions_price).toFixed(2)}}</view>
</view>
<view class="actualPay acea-row row-right">
实付款:
<!-- <span class="money">¥{{ orderInfo.pay_price }}</span> -->
<baseMoney :money="orderInfo.pay_price" symbolSize="24" integerSize="40" decimalSize="24" color="#FF7E00"></baseMoney>
</view>
</view>
<view class="height-add"></view>
</view>
</view>
</template>
<script>
import customForm from "@/components/customForm";
// #ifdef MP || APP
import NavBar from "@/components/NavBar.vue";
// #endif
import {OrderDetail} from "@/api/admin";
import {
isMoney
} from '@/utils/validate.js'
export default {
name: "orderDetail",
components: {
customForm,
// #ifdef MP || APP
NavBar,
// #endif
},
props: {},
data: function() {
return {
giveData: {
give_integral: 0,
give_coupon: []
},
giveCartInfo: [],
order: false,
change: false,
order_id: "",
orderInfo: '',
status: "",
title: "",
payType: "",
types: "",
clickNum: 1,
goname: '',
system_store: '',
sum: 0,
// #ifdef MP || APP
iconColor: '#FFFFFF',
isScrolling: false,
// #endif
};
},
watch: {
"$route.params.oid": function(newVal) {
let that = this;
if (newVal != undefined) {
that.order_id = newVal;
that.getIndex();
}
}
},
onLoad: function(option) {
let self = this
this.order_id = option.id;
this.goname = option.goname
this.getIndex();
},
onPageScroll(e) {
// #ifdef MP
if (e.scrollTop > 50) {
this.isScrolling = true;
this.iconColor = '#333333';
} else if (e.scrollTop < 50) {
this.isScrolling = false;
this.iconColor = '#FFFFFF';
}
// #endif
},
methods: {
more: function() {
this.order = !this.order;
},
modify: function(status) {
this.change = true;
this.status = status;
},
changeclose: function(msg) {
this.change = msg;
},
getIndex: function() {
let that = this;
OrderDetail(that.order_id).then(
res => {
that.sum = (parseFloat(res.data.total_price) + parseFloat(res.data.vip_true_price)).toFixed(2)
that.types = res.data._status._type;
that.title = res.data._status._title;
that.payType = res.data._status._payType;
this.system_store = res.data.store
that.giveData.give_coupon = res.data.give_coupon;
that.giveData.give_integral = res.data.give_integral;
let cartObj = [],
giftObj = [];
res.data.cartInfo.forEach((item, index) => {
if (item.is_gift == 1) {
giftObj.push(item)
} else {
cartObj.push(item)
}
});
res.data.cartInfo = cartObj;
that.$set(that, 'giveCartInfo', giftObj);
let arr = [];
for (let i = 0; i < res.data.user_address.length; i++) {
if (res.data.user_address[i] != ' ') {
arr.push(res.data.user_address[i]);
}
}
res.data.user_address = arr.join('');
that.orderInfo = res.data;
},
err => {
// that.$util.Tips({
// title: err
// }, {
// tab: 3,
// url: 1
// });
}
);
},
//打开地图
showMaoLocation: function(latitude, longitude, name, detailed_address) {
if (!latitude || !longitude) return this.$util.Tips({
title: '缺少经纬度信息无法查看地图!'
});
uni.openLocation({
latitude: parseFloat(latitude),
longitude: parseFloat(longitude),
scale: 8,
name: name,
address: detailed_address,
success: function() {
},
});
},
//拨打电话
makePhone: function(phone) {
uni.makePhoneCall({
phoneNumber: phone
})
},
copyNum(id) {
uni.setClipboardData({
data: id,
});
},
// #ifdef H5
webCopy(item, index) {
let items = item
let indexs = index
let self = this
if (self.clickNum == 1) {
self.clickNum += 1
self.webCopy(items, indexs)
}
}
// #endif
}
};
</script>
<style lang="scss" scoped>
.headerBg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 506rpx;
background: linear-gradient(360deg, #F5F5F5 0%, rgba(245, 245, 245, 0) 100%),
linear-gradient(-90deg, $gradient-primary-admin 0%, $primary-admin 100%);
background-position: left bottom, left top;
background-repeat: no-repeat;
background-size: 100% 120rpx, 100% 100%;
}
.order-details {
position: relative;
padding: 32rpx 20rpx;
.address {
position: relative;
padding: 32rpx 24rpx 28rpx 32rpx;
border-radius: 24rpx;
background: #FFFFFF;
overflow: hidden;
.text-box {
flex: 1;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.text {
margin-bottom: 12rpx;
font-weight: 500;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
.iconfont {
font-size: 32rpx;
margin-right: 20rpx;
}
}
.btn {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
margin-left: 24rpx;
background: rgba(42, 126, 251, 0.1);
text-align: center;
line-height: 56rpx;
.iconfont {
font-size: 28rpx;
color: #2A7EFB;
}
}
.line {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
}
.goods-section {
padding: 32rpx 24rpx;
border-radius: 24rpx;
margin-top: 20rpx;
background: #FFFFFF;
.goods {
margin-top: 32rpx;
&:first-child {
margin-top: 0;
}
}
.picTxt {
flex: 1;
min-width: 0;
}
.pictrue {
width: 136rpx;
height: 136rpx;
border-radius: 16rpx;
}
.text {
flex: 1;
min-width: 0;
padding: 0 20rpx;
}
.info {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.attr {
margin-top: 8rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.label {
display: inline-flex;
align-items: center;
height: 26rpx;
padding: 0 6rpx;
border: 1rpx solid #FF7E00;
border-radius: 4rpx;
margin-top: 12rpx;
font-size: 18rpx;
line-height: 26rpx;
color: #FF7E00;
}
.money {
text-align: right;
}
.num {
margin-top: 10rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
}
.detail-section {
padding: 32rpx 24rpx;
border-radius: 24rpx;
margin-top: 20rpx;
background: #FFFFFF;
.item {
margin-top: 24rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
&:first-child {
margin-top: 0;
}
}
}
}
.mt28 {
margin-top: 28rpx;
}
.height-add {
height: 120upx;
}
.giveGoods {
.item {
padding: 14rpx 0;
border-top: 1px solid #eee;
.picTxt {
.pictrue {
width: 76rpx;
height: 76rpx;
border-radius: 6rpx;
background-color: #F5F5F5;
color: $primary-admin;
.iconfont {
font-size: 34rpx;
}
image {
width: 100%;
height: 100%;
border-radius: 6rpx;
}
margin-right: 16rpx;
}
.texts {
width: 360rpx;
color: #999999;
font-size: 20rpx;
.name {
color: #333;
}
.limit {
font-size: 20rpx;
margin-top: 4rpx;
}
}
}
.num {
color: #999999;
font-size: 20rpx;
}
}
}
.order-details .line {
width: 100%;
height: 3upx;
}
.order-details .line image {
width: 100%;
height: 100%;
display: block;
}
.order-details .wrapper {
background: #FFFFFF;
}
.order-details .topnone {
padding: 32rpx 24rpx;
border-radius: 24rpx;
margin-top: 20rpx;
}
.order-details .wrapper .title {
height: 100upx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1upx solid #EEEEEE;
margin-bottom: 34upx;
}
.order-details .wrapper .title .font {
font-size: 32upx;
font-weight: 600;
color: #282828;
}
.order-details .wrapper .title .mapbtn {
width: 176upx;
height: 56upx;
border: 1upx solid #1890FF;
border-radius: 28upx;
text-align: center;
line-height: 50upx;
color: #1890FF;
font-size: 26upx;
}
.order-details .wrapper .item {
font-size: 28upx;
color: #282828;
}
.order-details .wrapper .item~.item {
margin-top: 26rpx;
}
.order-details .wrapper .item .conter {
color: #868686;
/* width: 500upx; */
text-align: right;
}
.order-details .wrapper .item .conter .copy {
font-size: 20rpx;
color: #333;
border-radius: 3rpx;
border: 1px solid #666;
padding: 0rpx 15rpx;
margin-left: 10rpx;
height: 40rpx;
line-height: 38upx;
}
.order-details .wrapper .actualPay {
// border-top: 1upx solid #eee;
margin-top: 26rpx;
// padding-top: 30upx;
}
.order-details .wrapper .actualPay .money {
font-weight: bold;
font-size: 30upx;
color: #FF7E00;
}
.copy-data {
width: 68rpx;
height: 36rpx;
border-radius: 18rpx;
margin-left: 8rpx;
background: #F5F5F5;
text-align: center;
font-size: 22rpx;
line-height: 36rpx;
color: #333333;
}
</style>

View File

@@ -0,0 +1,756 @@
<template>
<view>
<view class='shoppingCart copy-data'>
<view class='nav acea-row row-between-wrapper'>
<view>订单号:<text class='num'>{{ list.order_id }}</text></view>
<navigator class="btn" :url="'/pages/admin/writeRecordList/index?id='+id" hover-class="none">
核销记录<text class="iconfont icon-ic_rightarrow"></text>
</navigator>
</view>
<view class="content">
<view class='list'>
<view>
<block v-for="(item,index) in list.cart_info" :key="index">
<view class='item acea-row row-between-wrapper' :style="{ opacity: item.is_writeoff ? 0.5: 1 }">
<div class="xuan" @click="dan(item.cart_id,index)">
<view :class="(item.checked || item.is_writeoff)?'iconfont icon-a-ic_CompleteSelect':'iconfont icon-ic_unselect'"></view>
</div>
<view class='picTxt acea-row row-between-wrapper'>
<view class='pictrue'>
<image :src="item.cart_info.productInfo.attrInfo?item.cart_info.productInfo.attrInfo.image:item.cart_info.productInfo.image" mode=""></image>
</view>
<view class='text'>
<view class="title">
<view class='line1' :class="item.attrStatus?'':'reColor'">
{{ item.cart_info.productInfo.store_name }}
</view>
<view v-if="item.is_writeoff == 1" class="txt">已核销</view>
<view v-if="item.is_writeoff == 0 && lists.cart_info[index].surplus_num == lists.cart_info[index].cart_num" class="txt bluecol">未核销</view>
<view v-if="item.is_writeoff == 0 && lists.cart_info[index].surplus_num != lists.cart_info[index].cart_num" class="txt orangcol">
已核销{{parseInt(lists.cart_info[index].cart_num-lists.cart_info[index].surplus_num)}}件</view>
</view>
<view class='infor line1'>
属性:{{ item.cart_info.productInfo.attrInfo.suk }}</view>
<view class='money he row-middle'>
<view>¥{{ item.cart_info.productInfo.attrInfo?item.cart_info.productInfo.attrInfo.price:item.cart_info.productInfo.price }}</view>
<view v-if="item.is_writeoff == 1" class="txt">
<view class='carnum acea-row row-center-wrapper'>
<view class="reduce">
<text class="iconfont icon-ic_Reduce"></text>
</view>
<view class='nums'>0</view>
<view class="plus">
<text class="iconfont icon-ic_increase"></text>
</view>
</view>
</view>
<view v-else class="txt">
<view class='carnum acea-row row-center-wrapper'>
<view v-if="item.surplus_num_input == 1" class="reduce bggary">
<text class="iconfont icon-ic_Reduce"></text>
</view>
<view v-else class="reduce" @click.stop='subCart(item,index)'>
<text class="iconfont icon-ic_Reduce"></text>
</view>
<!-- <view class='nums'>{{parseInt(item.surplus_num)}}</view> -->
<input v-model="item.surplus_num_input" class='nums' type="number" @input="numInput(index, $event)" />
<view v-if="item.surplus_num_input == item.surplus_num" class="plus bggary">
<text class="iconfont icon-ic_increase"></text>
</view>
<view v-else class="plus" @click.stop='addCart(item,index)'>
<text class="iconfont icon-ic_increase"></text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</block>
</view>
</view>
</view>
<view class='footer acea-row row-between-wrapper'>
<view>
<view style="display: flex;" @change="checkboxAllChange">
<div class="xuan" @click="checkAll" v-model="checked">
<view class="iconfont" :class="checked?'icon-a-ic_CompleteSelect':'icon-ic_unselect'"></view>
</div>
<text class='checkAll'>全选</text>
</view>
</view>
<view>
<button class='money' type="primary" @click="verification">{{checked?'一键':'确认'}}核销({{numChecked}})</button>
</view>
</view>
</view>
<view v-if="box">
<view class="box">
<view class="small_box">
<!-- <image src="../../../static/decorate.png" mode=""></image> -->
<view class="content">
<view class="font">核销成功</view>
<view v-if="list.total_num == parseInt(list.writeoff_count)+writeOffNum" class="small_font">当前订单已完成核销</view>
<view v-else class="small_font">该订单仍有其他待核销商品</view>
</view>
<view class="acea-row btn-box">
<view v-if="lets == 1 && list.total_num == parseInt(list.writeoff_count)+writeOffNum" class="btn primary" @click="ok(1)">知道了</view>
<navigator v-if="lets > 1 && list.total_num != parseInt(list.writeoff_count)+writeOffNum" :url='"/pages/admin/distribution/scanning/index?code="+attr.code' hover-class='none'
open-type="redirect" class="btn btn_no">返回列表</navigator>
<navigator v-if="(lets > 1 && list.total_num == parseInt(list.writeoff_count)+writeOffNum)||(lets==1&&list.total_num != parseInt(list.writeoff_count)+writeOffNum)"
url="/pages/admin/distribution/index" hover-class='none' open-type="redirect" class="btn btn_no">返回首页</navigator>
<view v-if="list.total_num != parseInt(list.writeoff_count)+writeOffNum" class="btn on" @click="ok(0)">继续核销</view>
<navigator v-if="lets > 1 && list.total_num == parseInt(list.writeoff_count)+writeOffNum" :url='"/pages/admin/distribution/scanning/index?code="+attr.code' open-type="redirect"
hover-class='none' class="btn">核销其他订单</navigator>
</view>
</view>
</view>
</view>
<writeOffSwitching ref="writeOff" :attr="attr" :isShow='1' :iSplus='1' :iScart='1' @dataId="onDataId" @myevent="onMyEvent" id='product-window'></writeOffSwitching>
</view>
</template>
<script>
import writeOffSwitching from '../../../components/writeOffSwitching/index.vue';
import {
orderCartInfo,
orderWriteoff
} from '@/api/admin'
import {
nextTick
} from 'process';
export default {
components: {
writeOffSwitching
},
props: {
idss: {
type: Number,
default: 0
},
code: {
type: String,
default: ''
},
let: {
type: Number,
default: 0
},
},
data() {
return {
nums: [],
newList: [],
reduce_show: -1,
plus_show: -1,
ids: [], //选定需要核销的id
lets: 0, //判断订单的数量
listlet: 0, //判断订单商品的数量
attr: { //切换组件传值
cartAttr: false,
id: [],
code: '',
type: 0
},
id: 0, //订单ID
list: [],
lists: [],
lengt: 0,
box: false,
checked: false,
checkModel: [],
isAllSelect: false,
data: [{
id: '1',
value: 'aaa'
}, {
id: '2',
value: 'bbb'
}, {
id: '3',
value: 'ccc'
}],
writeOffNum: 0, //每次核销商品数量
auth: 1,
numChecked: 0,
};
},
watch: {
checkModel(val) {
if (this.lengt == this.checkModel.length) {
this.checked = true;
} else {
this.checked = false;
}
}
},
onLoad: function(options) {
this.id = options.id
this.attr.code = options.code
this.lets = options.let
this.auth = options.auth
this.getList(this.id)
},
onShow: function() {},
methods: {
numInput(index, event) {
let value = event.detail.value;
// if (parseInt(event.detail.value) > (this.list.cart_info[index].surplus_num + this.nums[index].num)) {
// this.$nextTick(() => {
// this.list.cart_info[index].surplus_num_input = this.list.cart_info[index].surplus_num + this.nums[index].num
// })
// }
if (value) {
value = Number(value);
this.$nextTick(() => {
if (value > this.list.cart_info[index].surplus_num) {
this.list.cart_info[index].surplus_num_input = this.list.cart_info[index].surplus_num;
} else if (value < 1) {
this.list.cart_info[index].surplus_num_input = 1;
}
let numChecked = 0;
for (let i = 0; i < this.list.cart_info.length; i++) {
if (!this.list.cart_info[i].is_writeoff) {
if (this.list.cart_info[i].checked) {
numChecked = numChecked + Number(this.list.cart_info[i].surplus_num_input)
}
}
}
this.numChecked = numChecked;
});
}
},
//处理每一条数据的最大值
num() {
for (let index = 0; index < this.lists.cart_info.length; index++) {
this.nums.push({
num: 0
});
}
},
subCart(item, index) {
if (item.surplus_num_input == 1) {
this.reduce_show = index;
} else {
this.nums[index].num--
item.surplus_num_input--
}
let numChecked = 0;
for (let i = 0; i < this.list.cart_info.length; i++) {
if (!this.list.cart_info[i].is_writeoff) {
if (this.list.cart_info[i].checked) {
numChecked = numChecked + this.list.cart_info[i].surplus_num_input
}
}
}
this.numChecked = numChecked;
},
addCart(item, index) {
if (item.surplus_num_input == item.surplus_num) {
this.plus_show = index;
} else {
item.surplus_num_input++
this.nums[index].num++
}
let numChecked = 0;
for (let i = 0; i < this.list.cart_info.length; i++) {
if (!this.list.cart_info[i].is_writeoff) {
if (this.list.cart_info[i].checked) {
numChecked = numChecked + this.list.cart_info[i].surplus_num_input
}
}
}
this.numChecked = numChecked;
},
checkAll() {
var items = this.list.cart_info,
data = [];
if (this.checked) {
this.checkModel = [];
for (var i = 0, lenI = this.list.cart_info.length; i < lenI; ++i) {
const item = items[i]
this.$set(item, 'checked', false)
}
} else {
this.checkModel = [];
for (var i = 0, lenI = this.list.cart_info.length; i < lenI; ++i) {
const item = items[i]
this.$set(item, 'checked', true)
if (item.is_writeoff == 1) {
this.checkModel = this.checkModel.filter(item => item != item.cart_id)
} else {
this.checkModel.push(item.cart_id)
}
}
this.lengt = this.checkModel.length
}
let numChecked = 0;
for (let i = 0; i < this.list.cart_info.length; i++) {
if (!this.list.cart_info[i].is_writeoff) {
if (this.list.cart_info[i].checked) {
numChecked = numChecked + Number(this.list.cart_info[i].surplus_num_input)
}
}
}
this.numChecked = numChecked;
},
dan(id, index) {
if (this.list.cart_info[index].is_writeoff) {
return
}
if (this.checkModel.indexOf(id) == -1) {
this.$set(this.list.cart_info[index], 'checked', true)
this.checkModel.push(id)
} else {
this.$set(this.list.cart_info[index], 'checked', false)
this.checkModel = this.checkModel.filter(item => item != id)
}
// let checked = true;
// for (let i = 0; i < this.cart_info.length; i++) {
// if (!this.cart_info[i].is_writeoff) {
// if (!this.cart_info[i].checked) {
// checked = false;
// }
// }
// }
// this.checked = checked;
let numChecked = 0;
for (let i = 0; i < this.list.cart_info.length; i++) {
if (!this.list.cart_info[i].is_writeoff) {
if (this.list.cart_info[i].checked) {
numChecked = numChecked + Number(this.list.cart_info[i].surplus_num_input)
}
}
}
this.numChecked = numChecked;
},
getList: function(id) {
orderCartInfo({
oid: id,
auth: this.auth,
}).then(res => {
for (let i = 0; i < res.data.cart_info.length; i++) {
res.data.cart_info[i].surplus_num_input = res.data.cart_info[i].surplus_num;
}
this.list = res.data
this.lists = JSON.parse(JSON.stringify(res.data))
this.listlet = res.data.cart_info.length
this.$set(this.attr, 'id', this.list.id);
this.checkAll()
this.num()
})
},
onDataId: function(id) {
this.nums.forEach((item) => {
item.num = 0
})
this.id = id;
this.getList(id)
},
switchs() {
this.attr.cartAttr = true;
this.$refs.writeOff.getList(2)
},
onMyEvent() {
this.attr.cartAttr = false;
},
verification() {
let that = this
let obj = {};
// 将数组转化为对象
for (let key in this.checkModel) {
obj[key] = this.checkModel[key];
};
let newObj = Object.keys(obj).map(val => ({
cart_id: obj[val],
}));
//处理列表内对应的核销数的数值
for (var i = 0; i < newObj.length; i++) {
for (var j = 0; j < this.list.cart_info.length; j++) {
if (newObj[i].cart_id == this.list.cart_info[j].cart_id) {
newObj[i].cart_num = this.list.cart_info[j].surplus_num_input;
}
}
}
this.newList = newObj
if (that.checkModel.length == 0) {
that.$util.Tips({
title: '请选择商品'
});
} else {
uni.showLoading({
title: '加载中',
});
let num = 0;
newObj.forEach((item) => {
num = num + parseInt(item.cart_num)
})
this.writeOffNum = num;
setTimeout(function() {
orderWriteoff({
auth: that.auth,
oid: that.id,
cart_ids: that.newList
}).then(res => {
uni.hideLoading();
that.box = true
}).catch(err => {
that.$util.Tips({
title: err
});
uni.hideLoading();
})
}, 1000);
}
},
// 所有订单核销完成
ok(type) {
this.box = false
this.nums.forEach((item) => {
item.num = 0
})
this.getList(this.id)
if (type) {
uni.redirectTo({
url: '/pages/admin/orderDetail/index?id='+this.list.order_id+'&types=3'
})
}
}
}
}
</script>
<style scoped lang="scss">
.shoppingCart {
padding: 24rpx 20rpx;
}
.shoppingCart .list .item .xuan .iconfont {
font-size: 40rpx;
color: #CCCCCC;
}
.he {
display: flex;
justify-content: space-between;
.txt {
font-size: 22upx;
}
}
.box {
position: fixed;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 10;
background-color: rgba(0, 0, 0, 0.3);
.small_box {
position: fixed;
top: 50%;
right: 75rpx;
left: 75rpx;
padding: 40rpx;
border-radius: 32rpx;
background: #FFFFFF;
transform: translateY(-50%);
image {
width: 100%;
height: 228upx;
}
.content {
// height: 200upx;
text-align: center;
.font {
font-weight: 500;
font-size: 32rpx;
line-height: 52rpx;
color: #333333;
}
.small_font {
margin-top: 24rpx;
font-size: 30rpx;
line-height: 42rpx;
color: #666666;
}
}
.btn-box {
margin-top: 40rpx;
}
.btn {
flex: 1;
height: 72rpx;
border: 1rpx solid $primary-admin;
border-radius: 36rpx;
margin-left: 32rpx;
transform: rotateZ(360deg);
text-align: center;
font-weight: 500;
font-size: 26rpx;
line-height: 70rpx;
color: $primary-admin;
&:first-child {
margin-left: 0;
}
&.on {
background: $primary-admin;
color: #FFFFFF;
}
&.primary {
background: $primary-admin;
color: #FFFFFF;
}
}
.btn_no {
// flex: 1;
// color: #999999;
// margin-top: 28upx;
// text-align: center;
// font-size: 30upx;
}
}
}
.shoppingCart .content {
padding: 32rpx 24rpx;
margin-top: 20rpx;
border-radius: 24rpx;
background: #FFFFFF;
.item {
margin-top: 48rpx;
&:first-child {
margin-top: 0;
}
}
}
.shoppingCart .list .item .xuan .icon-a-ic_CompleteSelect {
color: $primary-admin;
}
.shoppingCart .list .item .picTxt {
position: relative;
flex: 1;
min-width: 0;
padding-left: 16rpx;
}
.shoppingCart .list .item .picTxt .pictrue {
width: 136rpx;
height: 136rpx;
}
.shoppingCart .list .item .picTxt .pictrue image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.shoppingCart .list .item .picTxt .text {
flex: 1;
min-width: 0;
padding-left: 20rpx;
font-size: 28upx;
color: #282828;
}
.shoppingCart .list .item .picTxt .text .reColor {
color: #333333;
width: 60%;
}
.shoppingCart .list .item .picTxt .text .title {
display: flex;
justify-content: space-between;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
.bluecol {
color: $primary-admin;
}
.orangcol {
color: #FF7E00;
}
.graycol {
color: #CCCCCC;
}
}
.shoppingCart .list .item .picTxt .text .title .top {
width: 70%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 28upx;
font-weight: 400;
}
.shoppingCart .list .item .picTxt .text .infor {
font-size: 22rpx;
line-height: 30rpx;
color: #999999;
margin-top: 12rpx;
}
.shoppingCart .list .item .picTxt .text .money {
font-size: 36rpx;
line-height: 36rpx;
color: #333333;
margin-top: 18rpx;
font-family: Regular;
}
.shoppingCart .list .item .picTxt .carnum {
height: 36rpx;
// position: absolute;
// bottom: 7upx;
// right: 0;
}
.shoppingCart .list .item .picTxt .carnum view {
// border: 1upx solid #a4a4a4;
width: 32rpx;
text-align: center;
height: 100%;
line-height: 36rpx;
font-size: 24rpx;
color: #333333;
}
.shoppingCart .list .item .picTxt .carnum .reduce {
border-right: 0;
border-radius: 30upx 0 0 30upx;
padding-right: 8rpx;
}
.shoppingCart .list .item .picTxt .carnum .reduce.on {
border-color: #e3e3e3;
color: #dedede;
}
.shoppingCart .list .item .picTxt .carnum .plus {
border-left: 0;
border-radius: 0 30upx 30upx 0;
padding-left: 8rpx;
}
.shoppingCart .list .item .picTxt .carnum .iconfont {
font-size: 24rpx;
}
.shoppingCart .list .item .picTxt .carnum .bggary .iconfont {
color: #CCCCCC;
}
.shoppingCart .list .item .picTxt .carnum .num {
color: #282828;
}
.shoppingCart .list .item .picTxt .carnum .num0 {
color: #a4a4a4;
}
.shoppingCart .list .item .picTxt .carnum .nums {
width: 72rpx;
border-radius: 4rpx;
background: #F5F5F5;
text-align: center;
font-family: SemiBold;
font-size: 24rpx;
color: #333333;
}
.shoppingCart .footer {
// z-index: 999;
width: 100%;
background: #FFFFFF;
position: fixed;
padding: 0 20rpx 0 32rpx;
box-sizing: border-box;
bottom: 0;
left: 0;
height: 96rpx;
height: calc(96rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(96rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
}
.shoppingCart .footer.on {
// #ifndef H5
bottom: 0upx;
// #endif
}
.shoppingCart .footer .iconfont {
font-size: 40rpx;
color: #CCCCCC;
}
.shoppingCart .footer .icon-a-ic_CompleteSelect {
color: $primary-admin;
}
.shoppingCart .footer .checkAll {
font-size: 28upx;
color: #282828;
margin-left: 16upx;
}
.shoppingCart .footer .money {
font-size: 24rpx;
height: 64rpx;
padding: 0 32rpx;
background: $primary-admin;
border-radius: 32rpx;
font-weight: 400;
color: #FFFFFF;
line-height: 64rpx;
}
.shoppingCart .footer .placeOrder {
color: #fff;
font-size: 30upx;
width: 226upx;
height: 70upx;
border-radius: 50upx;
text-align: center;
line-height: 70upx;
margin-left: 22upx;
}
.shoppingCart .footer .button .bnt {
font-size: 28upx;
color: #999;
border-radius: 50upx;
border: 1px solid #999;
width: 160upx;
height: 60upx;
text-align: center;
line-height: 60upx;
}
.shoppingCart .footer .button form~form {
margin-left: 17upx;
}
</style>

View File

@@ -0,0 +1,451 @@
<template>
<view>
<view class="scan">
<view class="header">请选择要核销的订单</view>
<view class="box">
<view class="content" v-for="(item,index) in list" :key="index" @click="jump(item.id)">
<view class="acea-row row-between">
<view class="orange" v-if="(item._status == 4 || item._status == 12) && item.status == 5">部分核销</view>
<view class="attributes blue" v-if="item._status == 4 && item.status == 1">未核销</view>
<view class="attributes blue" v-if="item._status == 11">未核销</view>
<view class="attributes blue" v-if="item._status == 5">已核销</view>
<!-- <navigator class="btn" url="/pages/admin/writeRecordList/index" hover-class="none">核销记录<text class="iconfont icon-ic_rightarrow"></text></navigator> -->
<view class="btn" @click.stop="goRecord(item.id)">核销记录<text class="iconfont icon-ic_rightarrow"></text></view>
</view>
<view class="content_box acea-row">
<image :src="item.image" mode=""></image>
<view class="content_box_title acea-row row-column row-between">
<p class="textbox">订单号:{{ item.order_id }}</p>
<p class="attribute">下单时间:{{ item.add_time }}</p>
<view class="txt">
<p class="attribute">订单实付:¥{{ item.pay_price }}</p>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="mask" v-if="popupShow" @click="closePopup"></view>
<view class="popup acea-row row-column on" v-if="popupShow">
<view class="popup-hd">
商品核销
<view class="btn" @click="closePopup">
<text class="iconfont icon-ic_close"></text>
</view>
</view>
<writeOffList class="popup-bd" :list="orderInfo" :auth="auth" :oid="id" @success="writeSuccess"></writeOffList>
</view>
<view v-if="box">
<view class="boxs">
<view class="small_box">
<view class="content">
<view class="font">核销成功</view>
<view v-if="isAll" class="small_font">当前订单已完成核销</view>
<view v-else class="small_font">该订单仍有其他待核销商品</view>
</view>
<view class="acea-row btn-box">
<view v-if="!isAll" class="btn" @click="ok(1)">返回列表</view>
<!-- <navigator v-if="!isAll" :url='"/pages/admin/distribution/scanning/index?code="+attr.code' hover-class='none' open-type="redirect" class="btn btn_no">返回列表</navigator> -->
<navigator v-if="isAll" url="/pages/admin/work/index" hover-class='none' class="btn btn_no">返回工作台</navigator>
<view v-if="!isAll" class="btn on" @click="ok(2)">继续核销</view>
<view v-if="isAll" class="btn on" @click="ok(3)">核销其他订单</view>
<!-- <navigator v-if="isAll" :url='"/pages/admin/distribution/scanning/index?code="' open-type="redirect" hover-class='none' class="btn on">核销其他订单</navigator> -->
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
orderWriteoffInfo,
orderVerific,
orderCartInfo,
} from '@/api/admin'
import {
HTTP_REQUEST_URL
} from '@/config/app';
import {
nextTick
} from "vue";
import writeOffList from '../../components/writeOffList/index.vue';
export default {
name: 'scanning',
components: {
writeOffList,
},
data() {
return {
auth: 1,
verify_code: '',
list: [],
imgHost: HTTP_REQUEST_URL,
popupShow: false,
orderInfo: {},
id: 0,
box: false,
isAll: 1,
}
},
onLoad: function(option) {
this.auth = option.auth
this.verify_code = option.code
},
onShow(options) {
this.getList()
},
methods: {
goRecord(id) {
uni.navigateTo({
url: '/pages/admin/writeRecordList/index?id=' + id
})
},
getList: function() {
orderVerific(this.verify_code, this.auth)
.then(res => {
// self.orderInfo = res.data
this.list = res.data.data;
// self.iShidden = true
})
.catch(res => {
// self.verify_code = ''
return this.$util.Tips({
title: res
});
});
},
jump: function(id) {
this.id = id;
this.getCartList(id)
},
getCartList: function(id) {
orderCartInfo({
oid: id,
auth: this.auth,
}).then(res => {
if (res.data.product_type == 4) {
uni.navigateTo({
url: '/pages/admin/writeOffCard/index?id=' + id
})
} else {
let orderInfo = res.data;
for (let i = 0; i < orderInfo.cart_info.length; i++) {
orderInfo.cart_info[i].surplus_num_input = orderInfo.cart_info[i].surplus_num;
orderInfo.cart_info[i].checked = true;
}
this.orderInfo = orderInfo
this.popupShow = true;
}
}).catch(res => {
this.$util.Tips({
title: res
});
});
},
closePopup() {
this.popupShow = false;
},
writeSuccess(val) {
this.isAll = val;
this.box = true;
},
ok(val) {
this.box = false;
this.popupShow = false;
this.getList();
},
}
}
</script>
<style lang="scss" scoped>
.scan {
padding-bottom: 160upx;
.header {
height: 346rpx;
padding: 48rpx 0 0 32rpx;
background: linear-gradient(270deg, $gradient-primary-admin 0%, $primary-admin 100%);
font-weight: 500;
font-size: 36rpx;
line-height: 50rpx;
color: #FFFFFF;
}
.box {
padding: 0 20rpx;
margin: -216rpx 0 0;
}
.content {
padding: 32rpx 24rpx;
border-radius: 24rpx;
margin-bottom: 20rpx;
background: #FFFFFF;
.attributes {
font-size: 28rpx;
line-height: 40rpx;
color: $primary-admin;
}
.orange {
color: #FF7E00;
}
.pad {
padding: 20upx 20upx 22upx;
}
.btn {
font-size: 28rpx;
line-height: 40rpx;
color: #999999;
.iconfont {
margin-left: 4rpx;
font-size: 32rpx;
}
}
.content_box {
margin-top: 26rpx;
image {
width: 136rpx;
height: 136rpx;
border-radius: 16rpx;
}
.content_box_title {
flex: 1;
padding-left: 20rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #666666;
.textbox {
font-weight: 500;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.mar {
margin: 16upx 0upx;
}
.attribute {
color: #999999;
// margin: 4upx 0upx 10upx;
}
.txt {
display: flex;
justify-content: space-between;
font-size: 24upx;
.orange {
color: #FF7E00;
}
.blue {
color: $primary-admin;
}
}
}
}
.content_bottom {
display: flex;
justify-content: space-between;
font-size: 22upx;
padding: 0upx 20upx;
color: #666666;
.money {
font-size: 26upx;
color: #F5222D;
}
}
}
}
.popup {
position: fixed;
right: 0;
bottom: 0;
left: 0;
z-index: 6;
// max-height: 75%;
// min-height: 500rpx;
height: 800rpx;
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
border-radius: 40rpx 40rpx 0 0;
background: #FFFFFF;
overflow: hidden;
flex-wrap: nowrap;
transform: translateY(100%);
transition: transform 0.3s;
&.on {
transform: translateY(0);
}
.popup-hd {
position: relative;
height: 108rpx;
text-align: center;
font-weight: 500;
font-size: 32rpx;
line-height: 108rpx;
color: #333333;
.btn {
position: absolute;
top: 50%;
right: 32rpx;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background: #EEEEEE;
transform: translateY(-50%);
text-align: center;
line-height: 36rpx;
}
.iconfont {
vertical-align: middle;
font-size: 24rpx;
color: #333333;
}
}
.popup-bd {
position: relative;
flex: 1;
min-height: 0;
box-sizing: border-box;
/deep/.shoppingCart {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
flex-direction: column;
padding: 0;
.content {
flex: 1;
min-height: 0;
overflow-y: auto;
margin-top: 0;
padding: 36rpx 32rpx;
border-radius: 0;
.item {
margin-bottom: 48rpx;
}
}
.footer {
position: static;
height: 96rpx;
padding-bottom: 0;
}
}
}
.popup-ft {
padding: 16rpx 20rpx 16rpx 32rpx;
.btn {
height: 64rpx;
padding: 0 32rpx;
border-radius: 32rpx;
background: $primary-admin;
font-weight: 500;
font-size: 24rpx;
line-height: 64rpx;
color: #FFFFFF;
}
}
}
.boxs {
position: fixed;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 10;
background-color: #78797a;
.small_box {
position: fixed;
top: 50%;
right: 75rpx;
left: 75rpx;
padding: 40rpx;
border-radius: 32rpx;
background: #FFFFFF;
transform: translateY(-50%);
image {
width: 100%;
height: 228upx;
}
.content {
// height: 200upx;
text-align: center;
.font {
font-weight: 500;
font-size: 32rpx;
line-height: 52rpx;
color: #333333;
}
.small_font {
margin-top: 24rpx;
font-size: 30rpx;
line-height: 42rpx;
color: #666666;
}
}
.btn-box {
margin-top: 40rpx;
}
.btn {
flex: 1;
height: 72rpx;
border: 1rpx solid $primary-admin;
border-radius: 36rpx;
margin-left: 32rpx;
transform: rotateZ(360deg);
text-align: center;
font-weight: 500;
font-size: 26rpx;
line-height: 70rpx;
color: $primary-admin;
&:first-child {
margin-left: 0;
}
&.on {
background: $primary-admin;
color: #FFFFFF;
}
}
}
}
</style>

View File

@@ -0,0 +1,280 @@
<template>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="classify rd-t-40rpx">
<view class="title">修改分类
<view class="close acea-row row-center-wrapper" @tap="closeDrawer">
<text class="iconfont icon-ic_close"></text>
</view>
</view>
<checkbox-group @change="checkboxChange($event)" v-if="categoryList.length">
<view class="list acea-row">
<view class="item">
<view class="tips">一级分类</view>
<scroll-view scroll-y="true" class="scroll-Y">
<view class="itemn line1" :class="{checked: index == currentOne,on:checkedIds.includes(item.id+'')}" v-for="(item,index) in categoryList" :key="index" @click="categoryTap(index)">
<!-- #ifndef MP -->
<checkbox :value="(item.id).toString()"
:checked='checkedIds.includes(item.id+"")'
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="#2A7EFB" activeBorderColor="#2A7EFB"
style="transform:scale(0.9)" />
<!-- #endif -->
<!-- #ifdef MP -->
<checkbox :value="item.id" :checked='checkedIds.includes(item.id+"")' style="transform:scale(0.9)" color="#ffffff" />
<!-- #endif -->
{{item.cate_name}}
</view>
</scroll-view>
</view>
<view class="item on" :class="!categoryList[currentOne].children.length?'on3':''" v-if="categoryList[currentOne]">
<view class="tips">二级分类</view>
<scroll-view scroll-y="true" class="scroll-Y">
<view class="itemn line1" :class="{checked: jIndex == currentTwo,on:checkedIds.includes(j.id+'')}" v-for="(j,jIndex) in categoryList[currentOne].children" :key="jIndex" @click="categoryTwoTap(jIndex)">
<!-- #ifndef MP -->
<checkbox :value="(j.id).toString()" :checked='checkedIds.includes(j.id+"")'
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="#2A7EFB" activeBorderColor="#2A7EFB"
style="transform:scale(0.9)" />
<!-- #endif -->
<!-- #ifdef MP -->
<checkbox :value="j.id" :checked='checkedIds.includes(j.id+"")' style="transform:scale(0.9)" />
<!-- #endif -->
{{j.cate_name}}
</view>
</scroll-view>
</view>
<view class="item on2" v-if="categoryList[currentOne] && categoryList[currentOne].children.length">
<view class="tips">三级分类</view>
<scroll-view scroll-y="true" class="scroll-Y">
<view class="itemn line1" :class="{on:checkedIds.includes(x.id+'')}" v-for="(x,xIndex) in categoryList[currentOne].children[currentTwo].children" :key="xIndex">
<!-- #ifndef MP -->
<checkbox :value="(x.id).toString()" :checked='checkedIds.includes(x.id+"")'
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="#2A7EFB" activeBorderColor="#2A7EFB"
style="transform:scale(0.9)" />
<!-- #endif -->
<!-- #ifdef MP -->
<checkbox :value="x.id" :checked='checkedIds.includes(x.id+"")' style="transform:scale(0.9)" />
<!-- #endif -->
{{x.cate_name}}{{x.id}}
</view>
</scroll-view>
</view>
</view>
</checkbox-group>
<view class="empty-box" v-else>
<emptyPage title="暂无分类~" src="/statics/images/empty-box.png"></emptyPage>
</view>
<view class="footer acea-row row-between-wrapper">
<view class="bnt acea-row row-center-wrapper" @tap="reset">重置</view>
<view class="bnt on acea-row row-center-wrapper" @tap="define">确定</view>
</view>
</view>
</base-drawer>
</template>
<script>
import emptyPage from '@/components/emptyPage.vue';
import {
getCategory,
postBatchProcess
} from "@/api/admin";
export default {
components: {
emptyPage
},
props:{
visible: {
type: Boolean,
default: false,
},
},
data: function() {
return {
categoryList:[],
currentOne:0,
currentTwo:0,
checkedIds:[],
ids:null //父级商品id
};
},
mounted() {},
methods:{
checkboxChange(e, index, item){
this.checkedIds = e.detail.value;
},
categoryTwoTap(index){
this.currentTwo = index
},
categoryTap(index){
this.currentOne = index
this.currentTwo = 0
},
category(id,cateId){
this.ids = id;
if(cateId){
this.checkedIds = cateId.split(',')
}else{
this.checkedIds = []
}
getCategory().then(res=>{
this.categoryList = res.data;
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
reset(){
this.checkedIds = [];
},
define(){
console.log("非大概");
console.log(this.checkedIds);
if(!this.checkedIds.length){
this.$util.Tips({
title: '请选择分类'
});
return
}
let data = {
type:1,
data:{
cate_id:this.checkedIds
},
ids:this.ids
}
postBatchProcess(data).then(res=>{
this.$util.Tips({
title: res.msg
});
this.$emit('successChange');
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
closeDrawer() {
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
/deep/ checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: 1px solid $primary-admin;
background-color: $primary-admin;
color: #fff;
}
/deep/checkbox{
margin-right: 13rpx;
}
/deep/uni-checkbox .uni-checkbox-input{
border-radius: 4rpx;
width: 28rpx;
height: 28rpx;
}
.classify{
background-color: #fff;
padding-bottom: 60rpx;
.title{
text-align: center;
height: 108rpx;
line-height: 108rpx;
font-size: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
padding: 0 30rpx;
.close{
width: 36rpx;
height: 36rpx;
line-height: 36rpx;
background: #EEEEEE;
border-radius: 50%;
position: absolute;
right: 30rpx;
top:38rpx;
.iconfont {
font-weight: 300;
font-size: 20rpx;
}
}
}
.list{
height: 770rpx;
.scroll-Y{
height: 684rpx;
}
.item{
width: 33.33%;
padding-left: 32rpx;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #666666;
padding-top: 30rpx;
.tips{
color: #999;
font-size: 24rpx;
margin-bottom: 30rpx;
}
.itemn{
margin-bottom: 58rpx;
&.checked{
color: #000;
}
&.on{
color: $primary-admin;
}
}
&.on{
background-color: #FAFAFA;
}
&.on2{
background-color: #F5F5F5;
}
&.on3{
width: 66.66%;
}
}
}
.footer {
box-sizing: border-box;
padding: 0 20rpx;
width: 100%;
height: 112rpx;
background-color: #fff;
position: fixed;
bottom: 0;
z-index: 30;
height: calc(112rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(112rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
left: 0;
.bnt {
width: 347rpx;
height: 72rpx;
border-radius: 50rpx;
border: 1px solid $primary-admin;
color: $primary-admin;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
&.on{
background-color: $primary-admin;
color: #fff;
}
}
}
}
</style>

View File

@@ -0,0 +1,153 @@
<template>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-price rd-t-40rpx" v-if="goodsInfo.attr_value">
<view class="title">修改价格/库存
<view class="close acea-row row-center-wrapper" @tap="closeDrawer">
<text class="iconfont icon-ic_close"></text>
</view>
</view>
<view class="list">
<view class="item acea-row row-between-wrapper">
<view>售价</view>
<input type="digit" :placeholder="'请填写售价'+tips" placeholder-class="placeholder" v-model="goodsInfo.attr_value.price" />
</view>
<view class="item acea-row row-between-wrapper">
<view>成本价</view>
<input type="digit" :placeholder="'请填写成本价'+tips" placeholder-class="placeholder" v-model="goodsInfo.attr_value.cost" />
</view>
<view class="item acea-row row-between-wrapper">
<view>划线</view>
<input type="digit" :placeholder="'请填写划线'+tips" placeholder-class="placeholder" v-model="goodsInfo.attr_value.ot_price" />
</view>
<view class="item acea-row row-between-wrapper">
<view>库存</view>
<input type="number" :placeholder="'请填写库存'+tips" placeholder-class="placeholder" v-model="goodsInfo.attr_value.stock" />
</view>
</view>
<view v-if="goodsInfo.spec_type" class="bnt acea-row row-center-wrapper" @tap="defineSpec">确定</view>
<view v-else class="bnt acea-row row-center-wrapper" @tap="define">保存</view>
</view>
</base-drawer>
</template>
<script>
import {
postUpdateAttrs
} from "@/api/admin";
export default {
props:{
visible: {
type: Boolean,
default: false,
},
goodsInfo: {
type: Object,
default: () => {}
},
},
data: function() {
return {
tips:''
};
},
mounted() {
this.tips = this.goodsInfo.spec_type?'(可为空)':''
},
methods:{
defineSpec(){
let info = this.goodsInfo.attr_value;
if(info.cost || info.price || info.ot_price || info.stock){
this.$emit('successChange',info);
}else{
this.$util.Tips({
title: '修改类容至少填写一项'
});
}
},
define(){
let data = {
attr_value:[]
}
data.attr_value.push(this.goodsInfo.attr_value)
postUpdateAttrs(this.goodsInfo.id,data).then(res=>{
this.$util.Tips({
title: res.msg
});
this.$emit('successChange');
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
closeDrawer() {
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
.edit-price{
background-color: #fff;
padding-bottom: 60rpx;
.title{
text-align: center;
height: 108rpx;
line-height: 108rpx;
font-size: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
padding: 0 30rpx;
.close{
width: 36rpx;
height: 36rpx;
line-height: 36rpx;
background: #EEEEEE;
border-radius: 50%;
position: absolute;
right: 30rpx;
top:38rpx;
.iconfont {
font-weight: 300;
font-size: 20rpx;
}
}
}
.list{
padding: 0 10rpx 0 30rpx;
.item{
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
height: 72rpx;
margin-bottom: 32rpx;
box-sizing: border-box;
input {
text-align: right;
font-size: 28rpx;
height: 100%;
padding-right: 20rpx;
}
.placeholder{
font-size: 28rpx;
padding-right: 20rpx;
}
}
}
.bnt{
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #FFFFFF;
width: 710rpx;
height: 72rpx;
background: $primary-admin;
border-radius: 50rpx;
margin: 72rpx auto 0 auto;
}
}
</style>

View File

@@ -0,0 +1,252 @@
<template>
<base-drawer mode="right" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-lable">
<!-- #ifdef MP -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>添加标签</view>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<view class="list" v-if="isStore"
:style="'height: calc(100% - '+(getHeight.barTop+getHeight.barHeight*2+150)+'rpx - constant(safe-area-inset-bottom));height: calc(100% - '+(getHeight.barTop+getHeight.barHeight*2+150)+'rpx - env(safe-area-inset-bottom))'">
<!-- #endif -->
<!-- #ifndef MP -->
<view class="header">添加标签</view>
<view class="list" v-if="isStore">
<!-- #endif -->
<scroll-view scroll-y="true" style="height: 100%">
<view class="item" v-for="(item, index) in labelList" :key="index">
<view class="title" v-if="item.children && item.children.length">{{item.label_name}}</view>
<view class="listn acea-row row-middle" v-if="item.children && item.children.length">
<view class="name acea-row row-center-wrapper" :class="{on:j.disabled}" v-for="(j, indexn) in item.children" :key="indexn" @click="selectLabel(j)">
<text class="line1">{{j.label_name}}</text>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="empty-box" v-else>
<emptyPage title="暂无标签~" src="/statics/images/empty-box.png"></emptyPage>
</view>
<view class="footer acea-row row-between-wrapper">
<view class="bnt acea-row row-center-wrapper" @tap="reset">重置</view>
<view class="bnt on acea-row row-center-wrapper" @tap="define">确定</view>
</view>
</view>
</base-drawer>
</template>
<script>
import emptyPage from '@/components/emptyPage.vue';
import {
getProductLabel,
postBatchProcess
} from "@/api/admin";
import { handleError } from "vue";
export default {
components: {
emptyPage
},
props:{
visible: {
type: Boolean,
default: false,
},
},
data: function() {
return {
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
labelList:[],
goodsInfo:{}, //列表中已存在id(固定不变)
dataLabel: [], //已存在选中id(随着选中可以变化)
isStore:false, //判断是否存在标签
num:0, // 判断是否为批量
ids:[] //批量时的id集合
};
},
mounted() {
},
methods:{
define(){
let data = {
data:{
store_label_id:this.dataLabel
},
type:2
}
if(this.num){
data.ids = this.ids
}else{
data.ids = this.goodsInfo.id
}
postBatchProcess(data).then(res=>{
this.$util.Tips({
title: res.msg
});
this.$emit('successChange');
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
reset(){
this.productLabel(this.goodsInfo,this.num,this.ids);
},
inArray: function (search, array) {
for (let i in array) {
if (array[i] == search) {
return true;
}
}
return false;
},
productLabel(data,num,ids){
this.dataLabel = data.store_label_id || [];
this.goodsInfo = JSON.parse(JSON.stringify(data));
this.num = num;
this.ids = ids;
getProductLabel().then(res=>{
res.data.map(el => {
if (el.children && el.children.length) {
this.isStore = true;
el.children.map(label => {
if (this.inArray(label.id, this.dataLabel)) {
label.disabled = true;
} else {
label.disabled = false;
}
})
}
})
this.labelList = res.data
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
selectLabel(label) {
if (label.disabled) {
let index = this.dataLabel.indexOf(this.dataLabel.filter(d => d == label.id)[0]);
this.dataLabel.splice(index, 1);
label.disabled = false
} else {
this.dataLabel.push(label.id);
label.disabled = true
}
},
closeDrawer() {
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
.accountTitle{
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
padding-bottom: 6rpx;
.sysTitle{
width: 100%;
position: relative;
font-weight: 600;
color: #333333;
font-size: 34rpx;
font-family: PingFang SC, PingFang SC;
}
}
.edit-lable{
background-color: #fff;
width: 670rpx;
border-radius: 40rpx 0 0 40rpx;
height: 100%;
padding: 20rpx 34rpx 0 32rpx;
.header{
text-align: center;
height: 96rpx;
line-height: 96rpx;
font-size: 34rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
}
.list{
overflow: auto;
height: calc(100% - 208rpx);
height: calc(100% - (208rpx + constant(safe-area-inset-bottom)));
height: calc(100% - (208rpx + env(safe-area-inset-bottom)));
.item{
margin-top: 48rpx;
.title{
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
}
.listn{
.name{
width: 184rpx;
height: 56rpx;
background-color: #F5F5F5;
border-radius: 50rpx;
border:1rpx solid #F5F5F5;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
margin-right: 26rpx;
margin-top: 24rpx;
padding: 0 8rpx;
&.on {
background-color:$light-primary-admin;
border-color:$primary-admin;
color: $primary-admin;
}
&:nth-of-type(3n){
margin-right: 0;
}
}
}
}
}
.footer{
width: 100%;
height: 112rpx;
position: fixed;
bottom: 0;
left:0;
padding: 0 32rpx;
background-color: #fff;
border-radius: 0 0 0 40rpx;
height: calc(112rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(112rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
.bnt{
width: 296rpx;
height: 72rpx;
border: 1px solid $primary-admin;
border-radius: 200rpx;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: $primary-admin;
&.on{
background: $primary-admin;
border-color: $primary-admin;
color: #fff;
}
}
}
}
</style>

651
pages/admin/goods/index.vue Normal file
View File

@@ -0,0 +1,651 @@
<template>
<view class="goods-list">
<!-- #ifdef MP || APP-PLUS -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>商品管理</view>
<text class="iconfont icon-ic_leftarrow" @click="goarrow"></text>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<!-- #endif -->
<view class="searchCon acea-row row-between-wrapper">
<view class="search acea-row row-middle">
<text class="iconfont icon-ic_search"></text>
<input class="inputs" placeholder='请输入商品名称/ID' placeholder-class='placeholder' confirm-type='search' name="search"
v-model="keyword" @confirm="searchSubmit"></input>
</view>
<view @click="manageTap" v-if="administer">取消</view>
<view class="edit acea-row row-center-wrapper" @click="manageTap" v-else>
<text class="iconfont icon-ic_batch"></text>
</view>
</view>
<view class="nav acea-row row-middle">
<view class="item" :class="current == index?'on':''" v-for="(item, index) in navList" :key="index" @click="navTap(item,index)">
{{item.name}}
<image src="../static/adorn.png" v-if="current == index"></image>
</view>
</view>
<view class="list" v-if="goodsList.length">
<checkbox-group @change="checkboxChange">
<view class="acea-row row-middle" v-for="(item, index) in goodsList" :key="index">
<!-- #ifndef MP -->
<checkbox class="checkbox" v-if="administer" :value="(item.id).toString()" :checked="item.checked"
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="#2A7EFB" activeBorderColor="#2A7EFB"/>
<!-- #endif -->
<!-- #ifdef MP -->
<checkbox class="checkbox" v-if="administer" :value="item.id" :checked="item.checked"
color="#ffffff"/>
<!-- #endif -->
<view class="item">
<view class="top acea-row row-center-wrapper" @tap="goDetail(item)">
<view class="pictrue">
<image :src="item.image"></image>
</view>
<view class="text">
<view class="name line1">{{item.store_name}}</view>
<view class="info">
<text>销量: {{item.sales}}</text>
<text>库存: {{item.stock}}</text>
<text>评分: {{item.star}}</text>
</view>
<baseMoney
:money="item.price"
symbolSize="20"
integerSize="32"
decimalSize="20"
color="#FF7E00"
></baseMoney>
</view>
</view>
<view class="bottom acea-row row-right" v-if="!administer">
<view class="bnt acea-row row-center-wrapper" :class="item.is_show?'':'up'" @click="setShow(item,0)">{{item.is_show?'下架':'上架'}}</view>
<view class="bnt on acea-row row-center-wrapper" @tap="openDrawer(item)">编辑</view>
</view>
</view>
</view>
</checkbox-group>
</view>
<view class="empty-box" v-if="goodsList.length == 0 && !loading">
<emptyPage title="暂无商品~" src="/statics/images/empty-box.gif"></emptyPage>
</view>
<Loading :loaded="loadend" :loading="loading"></Loading>
<view class="footerH"></view>
<view class="footer acea-row row-between-wrapper" v-if="administer">
<checkbox-group @change="checkboxAllChange">
<checkbox value="all" :checked="isAllSelect" color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="#2A7EFB" activeBorderColor="#2A7EFB" />
<text class='checkAll'>全选({{getIds().length}})</text>
</checkbox-group>
<view class="acea-row row-middle">
<view class="bnt acea-row row-center-wrapper" @click="editLabels">添加标签</view>
<view class="bnt acea-row row-center-wrapper" @click="editClass">修改分类</view>
<view class="bnt acea-row row-center-wrapper" v-if="type == 1" @click="setShow('',1,0)">下架</view>
<view class="bnt acea-row row-center-wrapper" v-else-if="type == 2" @click="setShow('',1,1)">上架</view>
</view>
</view>
<footer-page></footer-page>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-list rd-t-40rpx">
<view class="item" v-for="(item, index) in editList" :key="index" @tap="editInfo(index)">{{item.name}}</view>
</view>
</base-drawer>
<edit-price :visible='visiblePrice' :goodsInfo='goodsInfo' @closeDrawer='priceCloseDrawer' @successChange='successChange'></edit-price>
<edit-lable ref="lable" :visible='visibleLable' @closeDrawer='lableCloseDrawer' @successChange='successChange'></edit-lable>
<classify ref="classify" :visible='visibleClass' @closeDrawer='classCloseDrawer' @successChange='successChange'></classify>
</view>
</template>
<script>
import Loading from '@/components/Loading/index';
import emptyPage from '@/components/emptyPage.vue';
import footerPage from '../components/footerPage/index.vue';
import editPrice from './components/editPrice/index.vue';
import editLable from './components/label/index.vue';
import classify from './components/classify/index.vue';
import { goShopDetail } from '@/libs/order.js';
import {
adminProductList,
productSetShow
} from "@/api/admin";
export default {
components: {
editPrice,
editLable,
classify,
footerPage,
emptyPage,
Loading
},
data() {
return {
getHeight: this.$util.getWXStatusHeight(),
navList:[
{
name:'全部',
type:''
},
{
name:'出售中',
type:1
},
{
name:'仓库中',
type:2
},
{
name:'已售罄',
type:4
},
{
name:'库存警告',
type:5
}
],
editList:[
{
name:'修改价格/库存'
},
{
name:'商品分类'
},
{
name:'商品标签'
},
],
current:0,
administer:0,
isAllSelect: false,
goodsList:[],
goodsInfo:{},
visible:false,
visiblePrice:false, //价格库存是否显示
visibleLable:false, //标签是否显示
loadTitle: '加载更多',
loading: false,
loadend: false,
limit: 20,
page: 1,
keyword:'', //搜索字段
type:'', //商品状态
visibleClass:false,
}
},
onShow() {
},
onLoad(option) {
this.type = option.type || '';
this.keyword = option.keyword || '';
for (let i = 0; i < this.navList.length; i++) {
if (this.navList[i].type == this.type) {
this.current = i;
break;
}
}
this.productList();
},
methods: {
// 去详情页
goDetail(item) {
if(!item.is_show){
this.$util.Tips({
title: '商品未上架'
});
return
}
goShopDetail(item, this.$store.state.app.uid).catch(res => {
uni.navigateTo({
url: `/pages/goods_details/index?id=${item.id}`
});
});
},
goarrow(){
uni.navigateBack()
},
editClass(){
if(!this.getIds().length){
this.$util.Tips({
title: '请选择商品'
});
return
}
this.$refs.classify.category(this.getIds(),'');
let that = this;
setTimeout(function(){
that.visibleClass = true
},200)
},
classCloseDrawer(){
this.visibleClass = false
},
successChange(){
this.visibleClass = false
this.visibleLable = false
this.visiblePrice = false
this.init();
},
//批量编辑标签
editLabels(){
if(!this.getIds().length){
this.$util.Tips({
title: '请选择商品'
});
return
}
this.visibleLable = true
this.$refs.lable.productLabel({},1,this.getIds());
},
//批量获取id集合
getIds(){
let ids = []
this.goodsList.forEach(item=>{
if(item.checked){
ids.push(item.id)
}
})
ids.slice(0, 100)
return ids
},
setShow(item,num,type){
let data = {}
if(num){
if(!this.getIds().length){
this.$util.Tips({
title: '请选择商品'
});
return
}
data = {
id:this.getIds(),
is_show:type
}
}else{
data = {
id:item.id,
is_show:item.is_show?0:1
}
}
productSetShow(data).then(res=>{
this.$util.Tips({
title: res.msg
});
this.init();
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
init(){
this.goodsList = [];
this.page = 1;
this.loadend = false;
this.loading = false;
this.productList();
},
searchSubmit(){
this.init();
},
productList(){
let that = this;
if (this.loading) return;
if (this.loadend) return;
that.loading = true;
that.loadTitle = "";
adminProductList({
page: that.page,
limit: that.limit,
store_name: that.keyword,
type: that.type,
}).then(res=>{
let goodsList = res.data.list;
goodsList.forEach(item => {
item.checked = false;
})
this.isAllSelect = false
let loadend = goodsList.length < that.limit;
that.goodsList = that.$util.SplitArray(goodsList, that.goodsList);
that.$set(that, 'goodsList', that.goodsList);
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
that.loadTitle = "加载更多";
})
},
editInfo(index){
switch (index) {
case 0:
this.visible = false
if(this.goodsInfo.spec_type){
uni.navigateTo({
url: '/pages/admin/goods/specs?id='+this.goodsInfo.id
})
}else{
this.visiblePrice = true
}
break;
case 1:
this.visible = false
this.visibleClass = true
break;
case 2:
this.visibleLable = true
this.visible = false
break;
}
},
lableCloseDrawer(){
this.visibleLable = false
},
priceCloseDrawer(){
this.visiblePrice = false
},
openDrawer(item){
this.visible = true
this.goodsInfo = JSON.parse(JSON.stringify(item))
this.$refs.lable.productLabel(this.goodsInfo,0,[]);
this.$refs.classify.category(item.id,item.cate_id);
},
closeDrawer(){
this.visible = false
},
manageTap() {
this.administer = !this.administer;
},
navTap(item,index){
this.current = index;
if (this.type != item.type) {
this.type = item.type;
this.init();
}
},
checkboxChange(event) {
let idList = event.detail.value;
this.goodsList.forEach((item) => {
if (idList.indexOf(item.id + '') !== -1) {
item.checked = true;
} else {
item.checked = false;
}
})
if (idList.length == this.goodsList.length) {
this.isAllSelect = true;
} else {
this.isAllSelect = false;
}
},
forGoods(val) {
let that = this;
if (!that.goodsList.length) return
that.goodsList.forEach((item) => {
if (val) {
item.checked = true;
} else {
item.checked = false;
}
})
},
checkboxAllChange(event) {
let value = event.detail.value;
if (value.length) {
if(this.goodsList.length>100){
this.$util.Tips({
title: '每次最多只提交100条数据'
});
}
this.isAllSelect = true;
this.forGoods(1)
} else {
this.isAllSelect = false;
this.forGoods(0)
}
},
},
onReachBottom(){
this.productList();
}
}
</script>
<style lang="scss" scoped>
/deep/checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: 1px solid $primary-admin !important;
background-color: $primary-admin !important;
}
/deep/uni-checkbox .uni-checkbox-input{
margin-top: -4rpx;
}
/deep/checkbox:not([disabled]) .uni-checkbox-input:hover {
border-color: #d1d1d1 !important;
}
.empty-box{
padding: 0 20rpx;
}
.accountTitle{
background: #F5F5F5;
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
padding-bottom: 6rpx;
.sysTitle{
width: 100%;
position: relative;
font-weight: 500;
color: #333333;
font-size: 30rpx;
.iconfont{
position: absolute;
font-size: 42rpx;
left:20rpx;
width: 60rpx;
font-weight: 500;
}
}
}
.goods-list{
padding-top: 20rpx;
.searchCon{
padding: 0 20rpx;
.search{
width: 618rpx;
height: 72rpx;
background: #FFFFFF;
border-radius: 50rpx;
padding: 0 34rpx;
.iconfont{
color: #999;
font-size: 32rpx;
margin-right: 16rpx;
}
.inputs{
font-size: 28rpx;
width: 100%;
height: 100%;
flex: 1;
}
.placeholder{
color: #ccc;
}
}
.edit{
width: 72rpx;
height: 72rpx;
background: #FFFFFF;
border-radius: 50%;
.iconfont {
color: #666;
font-size: 36rpx;
}
}
}
.nav{
padding: 20rpx 20rpx 18rpx 34rpx;
position: sticky;
top:0;
left:0;
width: 100%;
background-color: #F5F5F5;
z-index: 9;
.item{
font-weight: 400;
font-size: 26rpx;
color: #333333;
padding: 10rpx 0;
position: relative;
&~.item{
margin-left: 72rpx;
}
&.on{
font-weight: 500;
color: $primary-admin;
font-size: 30rpx;
font-family: PingFang SC, PingFang SC;
}
image {
width: 14rpx;
height: 14rpx;
display: block;
position: absolute;
bottom: 0;
right: -4rpx;
}
}
}
.list{
padding-bottom: 20rpx;
padding: 0 20rpx 20rpx 20rpx;
/deep/uni-checkbox .uni-checkbox-input{
background-color: #f5f5f5;
margin: 0 20rpx 20rpx 0;
}
/deep/wx-checkbox .wx-checkbox-input{
background-color: #f5f5f5;
margin: 0 20rpx 20rpx 0;
}
.item {
width: 100%;
background-color: #fff;
padding: 24rpx;
box-sizing: border-box;
margin-bottom: 20rpx;
border-radius: 24rpx;
flex: 1;
overflow: hidden;
.top{
.checkbox{
margin-right: 10rpx;
}
.pictrue{
width: 136rpx;
height: 136rpx;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
}
.text{
flex: 1;
overflow: hidden;
.name {
font-size: 28rpx;
font-weight: 400;
color: #333333;
}
.info {
font-size: 24rpx;
font-weight: 400;
color: #666666;
margin: 10rpx 0 18rpx 0;
text {
margin-right: 40rpx;
}
}
}
}
.bottom{
margin-top: 26rpx;
.bnt{
width: 144rpx;
height: 56rpx;
border:1px solid #ccc;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
border-radius: 50rpx;
&~.bnt{
margin-left: 16rpx;
}
&.on{
border-color: $primary-admin;
background-color: $primary-admin;
color: #fff;
}
&.up{
border-color: #FF7E00;
color: #FF7E00;
}
}
}
}
}
.footerH {
height: 110rpx;
height: calc(110rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(110rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
}
.footer {
box-sizing: border-box;
padding: 0 32rpx;
width: 100%;
height: 96rpx;
background-color: #fff;
position: fixed;
bottom: 0;
z-index: 30;
height: calc(96rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(96rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
width: 100%;
left: 0;
.bnt {
width: 160rpx;
height: 64rpx;
border-radius: 50rpx;
border: 1rpx solid $primary-admin;
color: $primary-admin;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
&~.bnt{
margin-left: 16rpx;
}
}
}
.edit-list{
background-color: #fff;
padding: 45rpx 34rpx;
.item{
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
font-size: 32rpx;
text-align: center;
height: 106rpx;
line-height: 106rpx;
}
}
}
</style>

340
pages/admin/goods/specs.vue Normal file
View File

@@ -0,0 +1,340 @@
<template>
<view class="specs">
<checkbox-group @change="checkboxChange">
<view class="list acea-row" :class="administer?'on':''" v-for="(item, index) in attrsList" :key="index">
<!-- #ifndef MP -->
<checkbox class="checkbox" v-if="administer" :value="(item.id).toString()" :checked="item.checked" />
<!-- #endif -->
<!-- #ifdef MP -->
<checkbox class="checkbox" v-if="administer" :value="item.id" :checked="item.checked" />
<!-- #endif -->
<view class="listCon">
<!-- <view class="item acea-row row-middle">
<view class="name">商品图</view>
<view class="pictrue">
<image :src="item.image" mode="aspectFill"></image>
</view>
</view> -->
<view class="item acea-row row-middle">
<view class="name">规格名称</view>
<view class="info">{{item.suk}}</view>
</view>
<view class="item acea-row row-middle">
<view class="name">售价</view>
<input type="number" :disabled="administer" min='0' v-model="item.price" placeholder="请填写售价" placeholder-class="placeholder"/>
</view>
<view class="item acea-row row-middle">
<view class="name">成本价</view>
<input type="number" :disabled="administer" v-model="item.cost" placeholder="请填写成本价" placeholder-class="placeholder"/>
</view>
<view class="item acea-row row-middle">
<view class="name">原价</view>
<input type="number" :disabled="administer" v-model="item.ot_price" placeholder="请填写原价" placeholder-class="placeholder"/>
</view>
<view class="item acea-row row-middle">
<view class="name">库存</view>
<input type="number" :disabled="administer" v-model="item.stock" placeholder="请填写库存" placeholder-class="placeholder"/>
</view>
</view>
</view>
</checkbox-group>
<view class="footer on acea-row row-between-wrapper" v-if="administer">
<checkbox-group @change="checkboxAllChange">
<checkbox value="all" :checked="isAllSelect" />
<text class='checkAll'>全选</text>
</checkbox-group>
<view class="acea-row row-middle">
<view class="bnt acea-row row-center-wrapper" @click="manageTap">取消</view>
<view class="bnt on acea-row row-center-wrapper" @click="batchEdit">批量修改</view>
</view>
</view>
<view class="footer acea-row row-between-wrapper" v-else>
<view class="bnt acea-row row-center-wrapper" @click="manageTap">批量操作</view>
<view class="bnt on acea-row row-center-wrapper" @click="define">保存</view>
</view>
<edit-price :visible='visiblePrice' :goodsInfo='goodsInfo' @closeDrawer='priceCloseDrawer' @successChange='successChange'></edit-price>
</view>
</template>
<script>
import editPrice from './components/editPrice/index.vue';
import {
getGetAttrs,
postUpdateAttrs
} from "@/api/admin";
export default {
components: {
editPrice
},
data() {
return {
attrsList:[],
id:0,
administer:false,
isAllSelect: false,
visiblePrice: false,
goodsInfo:{
id:0,
spec_type:1,
attr_value:{}
}
}
},
onShow() {
},
onLoad(option) {
this.id = option.id;
this.getAttrsList();
},
methods:{
//批量获取id集合
getIds(){
let ids = []
this.attrsList.forEach(item=>{
if(item.checked){
ids.push(item.id)
}
})
return ids
},
batchEdit(){
if(!this.getIds().length){
this.$util.Tips({
title: '请选择商品规格'
});
return
}
this.goodsInfo.id = this.id;
this.goodsInfo.attr_value = {
cost:'',
price:'',
ot_price:'',
stock:''
}
this.visiblePrice = true;
},
define(){
let data = {
attr_value:[]
}
this.attrsList.forEach(item=>{
data.attr_value.push({
cost:item.cost,
price:item.price,
ot_price:item.ot_price,
stock:item.stock,
unique:item.unique
})
})
postUpdateAttrs(this.id,data).then(res=>{
this.$util.Tips({
title: res.msg
},() => {
uni.navigateTo({
url: '/pages/admin/goods/index'
})
});
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
getAttrsList(){
getGetAttrs(this.id).then(res=>{
let data = res.data;
data.forEach(item => {
item.checked = false;
})
this.attrsList = data;
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
checkboxChange(event) {
let idList = event.detail.value;
this.attrsList.forEach((item) => {
if (idList.indexOf(item.id + '') !== -1) {
item.checked = true;
} else {
item.checked = false;
}
})
if (idList.length == this.attrsList.length) {
this.isAllSelect = true;
} else {
this.isAllSelect = false;
}
},
forGoods(val) {
let that = this;
if (!that.attrsList.length) return
that.attrsList.forEach((item) => {
if (val) {
item.checked = true;
} else {
item.checked = false;
}
})
},
checkboxAllChange(event) {
let value = event.detail.value;
if (value.length) {
this.isAllSelect = true;
this.forGoods(1)
} else {
this.isAllSelect = false;
this.forGoods(0)
}
},
manageTap() {
this.administer = !this.administer;
},
priceCloseDrawer(){
this.visiblePrice = false
},
successChange(e){
this.visiblePrice = false
let data = e;
this.attrsList.forEach(item=>{
if(item.checked){
if(data.cost){
item.cost = data.cost
}
if(data.price){
item.price = data.price
}
if(data.ot_price){
item.ot_price = data.ot_price
}
if(data.stock){
item.stock = data.stock
}
}
})
this.manageTap();
}
}
}
</script>
<style lang="scss" scoped>
/deep/checkbox .uni-checkbox-input.uni-checkbox-input-checked {
border: 1px solid $primary-admin !important;
background-color: $primary-admin !important;
}
/deep/checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: 1px solid $primary-admin !important;
background-color: $primary-admin !important;
}
.specs{
padding: 24rpx 20rpx 112rpx 20rpx;
padding-bottom: calc(112rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
padding-bottom: calc(112rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
.list{
background-color: #fff;
border-radius: 24rpx;
padding: 0 24rpx;
margin-bottom: 20rpx;
.listCon{
flex: 1;
}
&.on {
input{
color: #999999 !important;
}
}
.checkbox{
margin: 32rpx 12rpx 0 0;
}
.item{
min-height: 102rpx;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
&~.item{
border-top: 1px solid #F1F1F1;
}
.name{
color: #333333;
width: 115rpx;
margin-right: 39rpx;
}
.info{
color: #999999;
flex: 1;
}
input {
font-size: 36rpx;
font-family: 'Regular';
color: #333333;
}
// #ifdef MP
input {
font-size: 30rpx;
}
// #endif
.placeholder{
font-size:28rpx;
}
.pictrue{
width: 100rpx;
height: 100rpx;
image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
}
}
}
.footer {
box-sizing: border-box;
padding: 0 20rpx;
width: 100%;
height: 112rpx;
background-color: #fff;
position: fixed;
bottom: 0;
z-index: 30;
height: calc(112rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(112rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
width: 100%;
left: 0;
&.on {
height: 96rpx;
height: calc(96rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(96rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
.bnt{
width: 160rpx;
height: 64rpx;
font-size: 24rpx;
&.on{
background-color: $primary-admin;
color: #fff;
margin-left: 16rpx;
}
}
}
.bnt {
width: 346rpx;
height: 72rpx;
border-radius: 200rpx;
border: 1px solid $primary-admin;
color: $primary-admin;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
&.on{
background-color: $primary-admin;
color: #fff;
}
}
}
}
</style>

View File

@@ -0,0 +1,344 @@
<template>
<view>
<view class="w-full header_bg" :style="{'height': (174 + sysHeight) * 2 + 'rpx'}">
<view class="w-full abs-lb white_jianbian"></view>
</view>
<!-- #ifdef MP -->
<NavBar titleText="物流查询" :iconColor="iconColor" :textColor="iconColor" :isScrolling="isScrolling" showBack></NavBar>
<!-- #endif -->
<view class="relative px-20 z-20 express_box">
<view class="h-66 rd-t-24rpx light px-24 flex-between-center fs-20">
<text>{{orderInfo.delivery_name}} {{orderInfo.delivery_id}}</text>
<text class="inline-block copy_btn fs-22 text--w111-333" @tap="copyOrderId">复制单号</text>
</view>
<view class="rd-b-24rpx bg--w111-fff flex-between-center">
<view class="w-316 h-142 flex-col flex-center">
<text class="fs-32 fw-500 lh-44rpx">{{orderInfo.user_name}}</text>
<text class="fs-22 text--w111-999 lh-30rpx mt-8">{{orderInfo.user_phone}}</text>
</view>
<view class="flex-1 h-142 flex-center fs-28 fw-500 lh-40rpx relative city-box">
<text>{{orderInfo.send_city}}</text>
<text class="iconfont icon-a-jiantou11 mx-32"></text>
<text>{{orderInfo.user_city}}</text>
</view>
</view>
</view>
<view class="px-20 mt-20 relative">
<view class="bg--w111-fff rd-16rpx pt-32 pr-24 pl-24 pb-32">
<view class="flex-between-center">
<view class="fs-32 fw-500 text--w111-333">
<text>物流详情</text>
</view>
</view>
<view class="logisticsCon mt-50 relative" v-if="expressList.length">
<view class='item' v-for="(item,index) in logisticList" :key="index">
<view class='circular' :class='index === 0 ? "on text-center":""'>
<text class="iconfont icon-ic_complete text--w111-fff fs-24" v-if="index == 0"></text>
</view>
<view class='text' :class='index===0 ? "on-font on":""'>
<view>{{item.status}}</view>
<view class='data' :class='index===0 ? "on-font on":""'>{{item.time}}</view>
</view>
</view>
<view class="more-text fs-24" @tap="checkShowMore">
<text>{{showMore ? '收起' : '查看更多物流信息'}}</text>
<text class="iconfont fs-24 pl-8" :class="showMore ? 'icon-ic_uparrow' : 'icon-ic_downarrow'"></text>
</view>
</view>
<emptyPage title="暂无物流信息" src="/statics/images/noExpress.gif" v-else></emptyPage>
</view>
<view class="safe-area-inset-bottom"></view>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import {
express
} from '@/api/order.js';
import {
getProductHot
} from '@/api/store.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import {
HTTP_REQUEST_URL
} from '@/config/app';
// #ifdef MP
import NavBar from '@/components/NavBar.vue'
// #endif
import emptyPage from '@/components/emptyPage.vue'
export default {
components: {
// #ifdef MP
NavBar,
// #endif
emptyPage,
},
data() {
return {
sysHeight: sysHeight,
imgHost: HTTP_REQUEST_URL,
orderId: '',
type: '',
product: [],
orderInfo: {},
expressList: [],
hostProduct: [],
isShowAuth: false,
pageScrollStatus: false,
showMore: true,
// #ifdef MP
iconColor: '#FFFFFF',
isScrolling: false,
// #endif
};
},
computed: {
...mapGetters(['isLogin']),
logisticList() {
if (this.showMore) {
return this.expressList
} else {
return this.expressList.slice(0, 1)
}
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
//#ifndef MP
this.getExpress();
this.get_host_product();
//#endif
}
},
deep: true
}
},
onLoad: function(options) {
if (!options.orderId) return this.$util.Tips({
title: '缺少订单号'
});
if (typeof(options.type) == 'undefined') {
this.type = ''
} else {
this.type = options.type
}
this.orderId = options.orderId;
if (this.isLogin) {
this.getExpress();
this.get_host_product();
}
},
onPageScroll(object) {
if (object.scrollTop > 100) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 100) {
this.pageScrollStatus = false;
}
// #ifdef MP
if (object.scrollTop > 50) {
this.isScrolling = true;
this.iconColor = '#333333';
} else if (object.scrollTop < 50) {
this.isScrolling = false;
this.iconColor = '#FFFFFF';
}
// #endif
uni.$emit('scroll');
},
onShow() {
uni.removeStorageSync('form_type_cart');
if (!this.isLogin) {
toLogin()
}
},
methods: {
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
/**
* 授权回调
*/
onLoadFun: function() {
this.getExpress();
this.get_host_product();
this.isShowAuth = false;
},
copyOrderId: function() {
uni.setClipboardData({
data: this.orderInfo.delivery_id
});
},
getExpress: function() {
let that = this;
express(that.orderId, this.type).then(function(res) {
that.$set(that, 'product', res.data.order.cartInfo || []);
that.$set(that, 'orderInfo', res.data.order);
that.$set(that, 'expressList', res.data.express || []);
}).catch((error) => {
this.$util.Tips({
title: error
});
});
},
/**
* 获取我的推荐
*/
get_host_product: function() {
let that = this;
getProductHot().then(function(res) {
that.$set(that, 'hostProduct', res.data);
});
},
checkShowMore() {
this.showMore = !this.showMore
},
goPage(type, url) {
if (type == 1) {
uni.navigateTo({
url
})
} else if (type == 2) {
uni.switchTab({
url
})
} else if (type == 3) {
uni.navigateBack();
}
},
}
}
</script>
<style scoped lang="scss">
.safe-area-inset-bottom {
height: 0;
height: constant(safe-area-inset-bottom);
height: env(safe-area-inset-bottom);
}
.header_bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 369rpx;
background: linear-gradient(270deg, $gradient-primary-admin 0%, $primary-admin 100%);
}
.white_jianbian {
height: 180rpx;
background: linear-gradient(0deg, #F5F5F5 0%, rgba(245, 245, 245, 0) 100%);
}
.light {
background: rgba(255, 255, 255, 0.9);
}
.express_box {
padding-top: 30rpx;
}
.copy_btn {
width: 112rpx;
height: 34rpx;
background: #F5F5F5;
border-radius: 20rpx;
text-align: center;
line-height: 34rpx;
}
.city-box {
&:before {
content: '';
width: 1px;
height: 64rpx;
background-color: #eee;
position: absolute;
top: 40rpx;
left: 0;
}
}
.more-text {
position: absolute;
left: 40rpx;
bottom: -12rpx;
&:before {
content: '';
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background-color: #ddd;
position: absolute;
left: -26rpx;
top: 8rpx;
}
}
.logisticsCon .item {
padding: 0 20rpx;
position: relative;
}
.logisticsCon .item .circular {
width: 14rpx;
height: 14rpx;
border-radius: 50%;
position: absolute;
left: 14rpx;
background-color: #ddd;
}
.logisticsCon .item .circular.on {
width: 40rpx;
height: 40rpx;
background-color: $primary-admin;
left: 0;
}
.logisticsCon .item .text.on-font {
color: $primary-admin;
}
.logisticsCon .item .text .data.on-font {
color: $primary-admin;
}
.logisticsCon .item .text {
font-size: 26rpx;
color: #666;
width: 615rpx;
border-left: 1rpx solid #e6e6e6;
padding: 0 0 40rpx 38rpx;
}
.logisticsCon .item .text .data {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
.logisticsCon .item .text .data .time {
margin-left: 15rpx;
}
.z-99 {
z-index: 99;
}
.product~.product {
margin-top: 20rpx;
}
</style>

View File

@@ -0,0 +1,87 @@
<template>
<view class="container">
<view class="panel">
<view class="img-box">
<image v-if="id" src="../static/result2.png" class="image"></image>
<image v-else src="../static/result1.png" class="image"></image>
<view v-if="id">订单已全部核销</view>
<view v-else>暂无待核销订单</view>
</view>
<view class="btn-box">
<navigator v-if="id" class="btn" :url="'/pages/admin/orderDetail/index?id='+id" hover-class="none">订单详情</navigator>
<navigator class="btn" url="/pages/admin/work/index" hover-class="none">返回工作台</navigator>
</view>
</view>
</view>
</template>
<script>
// import Name from './components/Name.vue'
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
components: {
// Name
},
data() {
return {
imgHost: HTTP_REQUEST_URL,
id: 0
}
},
onLoad(option) {
this.id = option.id || 0;
},
}
</script>
<style lang="scss" scoped>
.container {
padding: 40rpx 20rpx;
.panel {
padding: 64rpx 105rpx 98rpx;
border-radius: 24rpx;
background: #FFFFFF;
}
.img-box {
text-align: center;
font-size: 36rpx;
line-height: 50rpx;
color: #333333;
}
.image {
width: 173rpx;
height: 163rpx;
margin-bottom: 34rpx;
}
.btn-box {
margin-top: 60rpx;
}
.btn {
height: 88rpx;
border: 1rpx solid $primary-admin;
border-radius: 44rpx;
text-align: center;
font-weight: 500;
line-height: 86rpx;
color: $primary-admin;
transform: rotateZ(360deg);
+.btn {
margin-top: 24rpx;
}
&:first-child {
background: $primary-admin;
color: #FFFFFF;
}
}
}
</style>

511
pages/admin/order/index.vue Normal file
View File

@@ -0,0 +1,511 @@
<template>
<view class="pagebox">
<!-- #ifdef MP || APP-PLUS -->
<NavBar titleText="数据统计" :iconColor="iconColor" :textColor="iconColor" :isScrolling="isScrolling" showBack></NavBar>
<!-- #endif -->
<view class="headerBg">
<view :style="{ height: `${getHeight.barTop}px` }"></view>
<view :style="{ height: `${getHeight.barHeight}px` }"></view>
<view class="inner"></view>
</view>
<view class="order-index" ref="container">
<view class="header">
<view class="">销售额(元)</view>
<view class="money">{{ after_price }}</view>
<view class="info">
较昨日同比增长:{{ increase_time_status == 1 ? '' : '-' }}{{ growth_rate }}%
<text :class="['iconfont', increase_time_status == 1 ? 'icon-ic_up2' : 'icon-ic_down2']"></text>
</view>
<view class="picker">
<picker mode="selector" :range="array" @change="bindPickerChange">
<view>{{ array[index] }}<text class="iconfont icon-ic_downarrow"></text></view>
</picker>
</view>
</view>
<view class="wrapper">
<view class="list acea-row">
<view class="item">
<view class="num">{{ after_number }}</view>
<view>订单数</view>
</view>
<view class="item">
<view class="num">{{ after_pay_number }}</view>
<view>支付人数</view>
</view>
<view class="item">
<view class="num">{{ today_visits }}</view>
<view>浏览量</view>
</view>
</view>
</view>
<div class="chart">
<view class="title">
销售订单趋势图
</view>
<canvas canvas-id="canvasMix" id="canvasMix" class="charts" width="680" disable-scroll @touchstart="touchMix" @touchmove="moveMix" @touchend="touchEndMix">
<!-- <cover-view class="cover-view"></cover-view> -->
</canvas>
</div>
<view class="public-wrapper">
<view class="title">
详细数据
</view>
<view class="nav acea-row row-between-wrapper">
<view class="data">日期</view>
<view class="browse">订单数</view>
<view class="turnover">成交额</view>
<view class="visit">浏览量</view>
</view>
<view class="conter">
<view class="item acea-row row-between-wrapper" v-for="(item, index) in list" :key="index">
<view class="data">{{ item.time }}</view>
<view class="browse">{{ item.count }}</view>
<view class="turnover">¥ {{ item.price }}</view>
<view class="visit">{{ item.visit }}</view>
</view>
</view>
</view>
<Loading :loaded="loaded" :loading="loading"></Loading>
</view>
<view class="safe-area-inset-bottom"></view>
</view>
</template>
<script>
let _self;
let canvaMix = null;
import {
getStatisticsInfo,
getStatisticsMonth,
getOrderTime,
getOrderChart,
} from "@/api/admin";
import Loading from '@/components/Loading/index.vue'
import uCharts from '../components/ucharts/ucharts'
// #ifdef MP || APP-PLUS
import NavBar from '@/components/NavBar.vue';
// #endif
export default {
name: 'adminOrder',
components: {
Loading,
// #ifdef MP ||APP-PLUS
NavBar,
// #endif
},
data() {
return {
iconColor: '#FFFFFF',
isScrolling: false,
getHeight: this.$util.getWXStatusHeight(),
census: {},
list: [],
where: {
page: 1,
limit: 15
},
loaded: false,
loading: false,
after_price: 0, // 销售额
after_number: 0, // 订单数
after_pay_number: 0, // 支付人数
today_visits: 0, // 浏览量
growth_rate: 0, // 增长率
increase_time: 0, // 较昨日同比增长
increase_time_status: 1, // 1 增长 2 减少
cWidth: '',
cHeight: '',
pixelRatio: 1,
textarea: '',
index: 0,
array: ['今天', '近7天', '近30天'],
arrays: [1, 7, 30],
}
},
onShow() {
_self = this;
this.cWidth = uni.upx2px(680);
this.cHeight = uni.upx2px(500);
this.getOrderTime();
this.getOrderChart();
this.getIndex();
this.getList();
// this.$scroll(this.$refs.container, () => {
// !this.loading && this.getList();
// });
},
onPageScroll(e) {
// #ifdef MP
if (e.scrollTop > 50) {
this.isScrolling = true;
this.iconColor = '#333333';
} else if (e.scrollTop < 50) {
this.isScrolling = false;
this.iconColor = '#FFFFFF';
}
// #endif
},
beforeMount() {
canvaMix = null
},
methods: {
bindPickerChange: function(e) {
console.log('picker发送选择改变,携带值为', e.detail.value)
this.index = e.detail.value
this.getOrderTime();
this.getOrderChart();
},
getOrderTime() {
getOrderTime({
type: this.arrays[this.index],
}).then(res => {
const {
after_number,
after_pay_number,
after_price,
today_visits,
growth_rate,
increase_time,
increase_time_status,
} = res.data;
this.after_number = after_number;
this.after_pay_number = after_pay_number;
this.after_price = after_price;
this.today_visits = today_visits;
this.growth_rate = growth_rate;
this.increase_time = increase_time;
this.increase_time_status = increase_time_status;
});
},
getOrderChart() {
getOrderChart({
type: this.arrays[this.index],
}).then(res => {
const data = res.data;
let Mix = {
categories: [],
series: []
};
let series = [{
"name": '销售额',
"type": "line",
"data": [],
}];
data.forEach(({
num,
price,
time
}) => {
series[0].data.push(price);
Mix.categories.push(time);
});
Mix.series = series;
this.chartData = data;
if (canvaMix) {
canvaMix.updateData(Mix);
} else {
this.showLineA("canvasMix", Mix);
}
});
},
// 创建charts
showLineA(canvasId, chartData) {
let _self = this
canvaMix = new uCharts({
$this: _self,
canvasId: canvasId,
type: 'line',
fontSize: 11,
padding: [5, 5, 0, 5],
legend: {
show: true,
position: 'bottom',
float: 'center',
padding: 5,
lineHeight: 11,
margin: 6,
},
background: '#FFFFFF',
pixelRatio: _self.pixelRatio,
categories: chartData.categories,
series: chartData.series,
animation: true,
enableScroll: true, //开启图表拖拽功能
xAxis: {
disableGrid: false,
type: 'grid',
gridType: 'dash',
itemCount: 6,
scrollShow: true,
scrollAlign: 'left',
},
yAxis: {
data: [{
calibration: true,
position: 'left',
title: '销售额(元)',
titleFontSize: 12,
format: (val) => {
return val.toFixed(0)
}
}, ],
showTitle: true,
gridType: 'dash',
dashLength: 4,
splitNumber: 7,
},
width: _self.cWidth * _self.pixelRatio,
height: _self.cHeight * _self.pixelRatio,
dataLabel: true,
dataPointShape: true,
});
},
touchMix(e) {
canvaMix.scrollStart(e);
},
moveMix(e) {
canvaMix.scroll(e);
},
touchEndMix(e) {
var index = canvaMix.getCurrentDataIndex(e);
canvaMix.scrollEnd(e);
//下面是toolTip事件,如果滚动后不需要显示,可不填写
canvaMix.touchLegend(e);
canvaMix.showToolTip(e, {
textList: [{
text: this.chartData[index].time,
color: null
},
{
text: "销售额:" + this.chartData[index].price,
color: "#1890FF"
},
{
text: "订单量:" + this.chartData[index].num,
color: "#91CB74"
}
]
});
},
getIndex: function() {
var that = this;
getStatisticsInfo().then(
res => {
that.census = res.data;
},
err => {
that.$util.Tips({
title: err
})
}
);
},
getList: function() {
var that = this;
if (that.loading || that.loaded) return;
that.loading = true;
getStatisticsMonth(that.where).then(
res => {
that.loading = false;
that.loaded = res.data.length < that.where.limit;
that.list.push.apply(that.list, res.data);
that.where.page = that.where.page + 1;
},
error => {
that.$util.Tips({
title: error
})
},
300
);
}
},
onReachBottom() {
this.getList()
}
}
</script>
<style lang="scss" scoped>
.pagebox {
position: relative;
overflow: hidden;
}
.safe-area-inset-bottom {
height: 0;
height: constant(safe-area-inset-bottom);
height: env(safe-area-inset-bottom);
}
.headerBg {
position: absolute;
top: 0;
left: -25%;
width: 150%;
border-bottom-right-radius: 100%;
border-bottom-left-radius: 100%;
background: linear-gradient(270deg, $gradient-primary-admin 0%, $primary-admin 100%);
.inner {
height: 356rpx;
}
}
/*订单首页*/
.order-index {
position: relative;
padding: 0 20rpx;
}
.order-index .header {
position: relative;
padding: 24rpx 0 40rpx 20rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #FFFFFF;
.picker {
position: absolute;
top: 24rpx;
right: 0;
height: 48rpx;
padding: 0 20rpx;
border-radius: 24rpx;
background: rgba(255, 255, 255, 0.3);
text-align: center;
font-size: 24rpx;
line-height: 48rpx;
color: #FFFFFF;
.iconfont {
margin-left: 10rpx;
font-size: 24rpx;
}
}
}
.order-index .header .money {
margin-top: 26rpx;
font-family: SemiBold;
font-size: 80rpx;
line-height: 80rpx;
}
.order-index .header .info {
margin-top: 30rpx;
.iconfont {
margin-left: 6rpx;
font-size: 28rpx;
}
}
.order-index .wrapper {
background-color: #fff;
border-radius: 24rpx;
}
.order-index .wrapper .list .item {
flex: 1;
padding: 36rpx 0 26rpx;
text-align: center;
font-size: 24rpx;
line-height: 34rpx;
color: #999;
}
.order-index .wrapper .list .item .num {
margin-bottom: 8rpx;
font-family: SemiBold;
font-size: 36rpx;
color: #333;
}
.public-wrapper .title {
font-weight: 500;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
padding: 32rpx 0 40rpx 24rpx;
}
.public-wrapper {
background-color: #fff;
border-radius: 24rpx;
margin-top: 20rpx;
}
.public-wrapper .nav {
padding: 0 40rpx;
line-height: 34rpx;
font-size: 24rpx;
color: #999;
}
.public-wrapper .data {
flex: 1;
text-align: left;
}
.public-wrapper .browse {
flex: 1;
// text-align: center;
}
.public-wrapper .turnover {
flex: 1;
// text-align: center;
}
.public-wrapper .visit {
flex: 1;
text-align: right;
}
.public-wrapper .conter {
padding: 0 40rpx;
}
.public-wrapper .conter .item {
border-bottom: 1px solid #F1F1F1;
height: 74rpx;
font-size: 24rpx;
}
.chart {
border-radius: 24rpx;
margin-top: 20rpx;
background: #FFFFFF;
.title {
padding: 32rpx 0 16rpx 24rpx;
font-weight: 500;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
}
.chart-title {
padding: 40rpx 0 6rpx 42rpx;
font-size: 22rpx;
line-height: 26rpx;
color: #999999;
}
.charts {
margin: 0 auto;
width: 680rpx;
height: 514rpx;
}
}
.cover-view {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,508 @@
<template>
<view :style="colorStyle">
<view class="OrderCancellation">
<view class="header"></view>
<view class="whiteBg" v-if="tabOn == 2">
<view class="input">
<input type="number" placeholder="请输入" v-model="verify_code" />
</view>
<view class="bnt" @click="codeChange">
<text class="iconfont icon-ic_search"></text>
</view>
</view>
<view v-if="tabOn == 1" class="scan" @click="scanCode">
<text class="iconfont icon-ic_Scan"></text>
</view>
<view class="tabbar-box acea-row">
<view class="item" :class="{ on: tabOn == 1 }" @click="onTab(1)">
<view class="bg"></view>
<view class="inner"><text class="iconfont icon-ic_Scan"></text>扫码核销</view>
</view>
<view class="item" :class="{ on: tabOn == 2 }" @click="onTab(2)">
<view class="bg"></view>
<view class="inner"><text class="iconfont icon-ic_edit"></text>手动输入</view>
</view>
</view>
</view>
<view v-if="iShidden">
<view class="WriteOff">
<view class="pictrue">
<image :src="orderInfo.image" />
</view>
<view class="num acea-row row-center-wrapper">
<text>{{ orderInfo.order_id }}</text>
<view class="views" @click='goOrderDetails(orderInfo.order_id,orderInfo.order_type)'>查看<text class='iconfont icon-jiantou views-jian'></text></view>
</view>
<view class="tip">确定要核销此订单吗?</view>
<view class="sure" @click="confirm">确定核销</view>
<view class=" cancel" @click="cancel">取消</view>
</view>
<view class="mask"></view>
</view>
</view>
</template>
<script>
import {
orderVerific
} from "@/api/admin";
import colors from '@/mixins/color.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from 'vuex';
export default {
mixins: [colors],
data() {
return {
iShidden: false,
verify_code: '',
isWeixin: '',
orderInfo: {},
tabOn: 1,
auth: 1,
}
},
computed: mapGetters(['isLogin']),
onLoad(options) {
// #ifdef H5 || APP-PLUS
this.isWeixin = this.$wechat.isWeixin();
// #endif
// #ifdef MP
if (options.scene) {
options = this.$util.getUrlParams(decodeURIComponent(options.scene));
}
// #endif
const {
auth,
code
} = options;
this.auth = auth || 1;
this.verify_code = code || '';
},
onShow() {
if (this.isLogin) {
if (this.auth == 3) {
this.codeChange();
}
} else {
toLogin();
}
},
methods: {
/**
* 去订单详情
*/
goOrderDetails: function(id, type) {
if (type == 'integral') {
uni.navigateTo({
url: '/pages/points_mall/integral_order_details?order_id=' + id
});
} else {
uni.navigateTo({
url: '/pages/admin/orderDetail/index?id=' + id + '&goname=look'
});
}
},
// 立即核销
codeChange: function() {
let self = this
let ref = /^[0-9]*$/;
if (!this.verify_code) return self.$util.Tips({
title: '请输入核销码'
});
if (!ref.test(this.verify_code)) return self.$util.Tips({
title: '请输入正确的核销码'
});
self.$util.Tips({
title: '查询中'
});
setTimeout(() => {
orderVerific(this.verify_code, this.auth)
.then(res => {
let auth = res.data.auth;
self.orderInfo = res.data
// self.iShidden = true
if (res.data.is_order_code) {
if (res.data.product_type) {
uni.navigateTo({
url: '/pages/admin/writeOffCard/index?id=' + res.data.data[0].id
})
} else {
if (res.data.data[0].status == 2) {
uni.navigateTo({
url: '/pages/admin/offOrderResult/index?id=' + res.data.data[0].order_id
})
} else {
uni.navigateTo({
url: '/pages/admin/distribution/scanning/detail/index?auth=' + auth + '&id=' + res.data.data[0].id + '&let=' + res.data.data.length +
'&code=' +
this
.verify_code
})
}
}
} else {
if (res.data.product_type) {
} else {
if (res.data.data.length) {
// 跳转多订单核销页
uni.navigateTo({
url: '/pages/admin/distribution/scanning/index?auth=' + auth + '&code=' + this.verify_code
})
} else {
// 跳转结果页
uni.navigateTo({
url: '/pages/admin/offOrderResult/index'
})
}
}
}
})
.catch(res => {
self.verify_code = ''
return self.$util.Tips({
title: res
});
});
}, 800);
},
// 扫码核
scanCode() {
var self = this;
// #ifdef MP || APP
uni.scanCode({
success(res) {
let path = decodeURIComponent(res.path);
self.verify_code = path.split('code=')[1];
self.codeChange();
},
})
// #endif
//#ifdef H5
this.$wechat.wechatEvevt('scanQRCode', {
needResult: 1,
scanType: ["qrCode", "barCode"]
}).then(res => {
let result = res.resultStr;
if (result.includes(',')) {
result = result.split(",")[1]
}
this.verify_code = result
this.codeChange();
});
//#endif
},
/**
* 确定销码
*/
confirm: function() {
let self = this
orderVerific(this.verify_code, 1)
.then(res => {
self.verify_code = ''
self.iShidden = false
self.$util.Tips({
title: res.msg
});
})
.catch(res => {
self.$util.Tips({
title: res
});
});
},
/**
* 取消
*/
cancel: function() {
this.iShidden = false
},
onTab(value) {
this.tabOn = value;
}
}
}
</script>
<style lang="scss">
.OrderCancellation {
position: absolute;
width: 100%;
overflow: hidden;
}
.OrderCancellation .header {
position: absolute;
top: 0;
left: -25%;
width: 150%;
height: 660rpx;
border-bottom-right-radius: 100%;
border-bottom-left-radius: 100%;
background: #FFFFFF;
}
.OrderCancellation {
// width: 100%;
// height: 100%;
// background: #fff;
overflow: hidden;
}
.OrderCancellation .whiteBg {
position: relative;
width: 540rpx;
height: 120rpx;
border-radius: 60rpx;
margin: 250rpx auto 416rpx;
background: #F5F5F5;
}
.OrderCancellation .whiteBg .input {
height: 100%;
}
.OrderCancellation .whiteBg .input input {
font-size: 32rpx;
color: #333333;
height: 100%;
text-align: center;
line-height: 120rpx;
padding: 0 104rpx;
box-sizing: border-box;
}
.OrderCancellation .whiteBg .input .input-placeholder {
color: #CCCCCC;
}
.OrderCancellation .whiteBg .bnt {
position: absolute;
top: 20rpx;
right: 24rpx;
width: 80rpx;
height: 80rpx;
border-radius: 40rpx;
background: $primary-admin;
text-align: center;
line-height: 80rpx;
}
.OrderCancellation .whiteBg .bnt .iconfont {
font-size: 32rpx;
color: #FFFFFF;
}
.OrderCancellation .scan {
position: relative;
width: 400rpx;
height: 400rpx;
border-radius: 200rpx;
margin: 110rpx auto 0;
background: $primary-admin;
box-shadow: 0rpx 4rpx 32rpx 0rpx $light-primary-admin;
text-align: center;
line-height: 400rpx;
}
.OrderCancellation .scan .iconfont {
font-size: 120rpx;
color: #FFFFFF;
}
.OrderCancellation .scan image {
width: 100%;
height: 100%;
display: block;
}
.WriteOff {
width: 560rpx;
height: 800rpx;
background-color: #fff;
border-radius: 20rpx;
position: fixed;
top: 50%;
left: 50%;
margin-top: -400rpx;
margin-left: -280rpx;
z-index: 99;
padding-top: 55rpx;
}
.WriteOff .pictrue {
width: 340rpx;
height: 340rpx;
margin: 0 auto;
}
.WriteOff .pictrue image {
width: 100%;
height: 100%;
display: block;
border-radius: 10rpx;
}
.WriteOff .num {
font-size: 30rpx;
color: #666;
margin: 28rpx 0 30rpx 0;
}
.WriteOff .num .see {
font-size: 16rpx;
color: #fff;
border-radius: 4rpx;
background-color: #c68937;
padding-left: 5rpx;
margin-left: 12rpx;
}
.WriteOff .num .see .iconfont {
font-size: 15rpx;
}
.WriteOff .tip {
font-size: 36rpx;
color: #282828;
text-align: center;
border-top: 1px dashed #ccc;
padding-top: 40rpx;
position: relative;
}
.WriteOff .tip:after {
content: "";
position: absolute;
width: 25rpx;
height: 25rpx;
border-radius: 50%;
background-color: #7f7f7f;
right: -12.5rpx;
top: -12.5rpx;
}
.WriteOff .tip:before {
content: "";
position: absolute;
width: 25rpx;
height: 25rpx;
border-radius: 50%;
background-color: #7f7f7f;
left: -12.5rpx;
top: -12.5rpx;
}
.WriteOff .sure {
font-size: 32rpx;
color: #fff;
text-align: center;
line-height: 82rpx;
height: 82rpx;
width: 460rpx;
border-radius: 41rpx;
margin: 40rpx auto 0 auto;
background-image: linear-gradient(to right, #f67a38 0%, #f11b09 100%);
background-color: $primary-admin;
}
.WriteOff .cancel {
line-height: 82rpx;
color: #999;
height: 82rpx;
width: 460rpx;
border-radius: 41rpx;
margin: 10rpx auto 0 auto;
text-align: center;
}
.WriteOff .cancel {}
.views {
font-size: 18rpx;
background: #C68937;
border-radius: 4px;
color: #fff;
padding: 5rpx 2rpx 5rpx 8rpx;
margin-left: 10rpx;
}
.views-jian {
font-size: 10px;
}
.tabbar-box {
width: 516rpx;
margin: 276rpx auto 0;
.item {
position: relative;
flex: 1;
z-index: 5;
min-width: 0;
height: 80rpx;
border-radius: 40rpx 0 0 40rpx;
overflow: hidden;
&:last-child {
border-radius: 0 40rpx 40rpx 0;
.bg {
height: 68rpx;
top: 0;
border-radius: 12rpx 0 0 12rpx;
transform-origin: center top;
transform: perspective(80rpx) rotateX(10deg) translateX(20rpx);
}
}
&.on {
.bg {
background: $primary-admin;
}
.inner {
color: #FFFFFF;
}
}
}
.bg {
position: absolute;
bottom: 0;
z-index: 2;
width: 100%;
height: 68rpx;
border-radius: 0 12rpx 12rpx 0;
background: #FFFFFF;
transform-origin: center bottom;
transform: perspective(80rpx) rotateX(-10deg) translateX(-20rpx);
}
.inner {
position: absolute;
z-index: 3;
width: 260rpx;
height: 80rpx;
text-align: center;
line-height: 80rpx;
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.iconfont {
vertical-align: middle;
margin-right: 16rpx;
font-size: 32rpx;
}
}
</style>

View File

@@ -0,0 +1,307 @@
<template>
<view class="refund">
<view class="money-section">
<view class="acea-row row-middle item">
<view class="">退款金额</view>
<input v-model="refundMoney" class="input" type="text" />
<text class="iconfont icon-ic_edit"></text>
</view>
<view class="acea-row row-middle item">
<view class="">退款类型</view>
<view class="acea-row row-right radio-group">
<view class="acea-row row-middle radio-item" :class="{ on: !isSplit}" @click="refundTypeChange(0)">
<text class="iconfont" :class="isSplit?'icon-ic_unselect':'icon-ic_Selected'"></text>整单退款
</view>
<view class="acea-row row-middle radio-item" :class="{ on: isSplit}" @click="refundTypeChange(1)">
<text class="iconfont" :class="isSplit?'icon-ic_Selected':'icon-ic_unselect'"></text>分单退款
</view>
</view>
</view>
</view>
<splitOrder v-if="isSplit" :splitGoods="splitGoods" :select_all="false" @getList="getList"></splitOrder>
<view class="footer acea-row row-middle">
<view class="all acea-row row-middle" v-if="isSplit" @click="allChange">
<text class="iconfont" :class="isAll?'icon-a-ic_CompleteSelect':'icon-ic_unselect'"></text>
全选
</view>
<view class="btn-box">
<view class="btn" :style="{ width: isSplit?'auto':'100%'}" @click="openRefund">
确认
<text v-if="isSplit">({{ numTotal }})</text>
</view>
</view>
</view>
</view>
</template>
<script>
import {
getAdminOrderDetail,
orderSplitInfo,
openRefund,
} from '@/api/admin.js';
import splitOrder from '@/components/splitOrder/index.vue';
export default {
components: {
splitOrder,
},
data() {
return {
refundMoney: 0,
isSplit: 0,
isAll: false,
splitGoods: [],
goodsChecked: [],
cart_ids: [],
}
},
computed: {
total() {
return this.goodsChecked.reduce((total, item) => {
return this.$util.$h.Add(total, this.$util.$h.Mul(item.refundPrice, item.surplus_num));
}, 0);
},
numTotal() {
return this.goodsChecked.reduce((total, {
surplus_num,
}) => {
return this.$util.$h.Add(total, surplus_num);
}, 0);
},
},
watch: {
total(newValue, oldValue) {
this.refundMoney = newValue
},
},
onLoad(option) {
this.order_id = option.id;
this.listId = option.listId;
this.getIndex();
// this.splitList();
},
methods: {
allChange() {
this.isAll = !this.isAll;
this.cart_ids = [];
this.goodsChecked = [];
for (let i = 0; i < this.splitGoods.length; i++) {
this.splitGoods[i].checked = this.isAll;
if (this.splitGoods[i].checked) {
this.goodsChecked.push(this.splitGoods[i]);
this.cart_ids.push(this.splitGoods[i].id);
}
}
},
refundTypeChange(value) {
this.isSplit = value;
if (value) {
this.goodsChecked = []
} else {
this.goodsChecked = this.splitGoods
}
},
splitList() {
orderSplitInfo(this.listId).then(res => {
let list = res.data;
list.forEach((item) => {
item.checked = false
item.numShow = item.surplus_num
})
// this.splitGoods = list;
}).catch(err => {
return this.$util.Tips({
title: err
});
})
},
getIndex() {
let that = this;
let obj = '';
getAdminOrderDetail(that.order_id).then(res => {
const {
cartInfo
} = res.data;
let list = cartInfo.map(item => {
return {
id: item.id,
checked: false,
numShow: item.cart_num - item.refund_num,
surplus_num: item.cart_num - item.refund_num,
cart_info: item,
refundPrice: this.$util.$h.Div(item.refund_price, item.cart_num),
};
});
this.splitGoods = list;
this.goodsChecked = list;
}).catch(err => {
that.$util.Tips({
title: err.msg
});
})
},
getList(val) {
let that = this;
let goodsChecked = [];
let cart_ids = [];
for (let i = 0; i < val.length; i++) {
if (val[i].checked) {
goodsChecked.push(val[i]);
cart_ids.push(val[i].id);
}
}
this.goodsChecked = goodsChecked;
this.cart_ids = cart_ids;
this.isAll = this.goodsChecked.length == this.splitGoods.length;
},
openRefund() {
let cart_ids = [];
let data = {
refund_price: this.refundMoney,
type: 1,
is_split_order: this.isSplit,
};
cart_ids = this.goodsChecked.map(({
id,
surplus_num
}) => {
return {
cart_id: id,
cart_num: surplus_num
}
});
data.cart_ids = cart_ids;
openRefund(this.listId, data).then(res => {
if (res.data.order_id) {
// const pages = getCurrentPages();
// pages.splice(pages.length - 2, 2)
this.$util.Tips({
title: res.msg
}, {
tab: 4,
url: '/pages/admin/orderDetail/index?id=' + res.data.order_id + '&types=',
});
} else {
this.$util.Tips({
title: res.msg
}, {
tab: 3,
url: 1,
});
}
}).catch(err => {
this.$util.Tips({
title: err
});
})
},
},
}
</script>
<style lang="scss" scoped>
.refund {
padding: 22rpx 20rpx;
}
.money-section {
padding: 12rpx 0;
border-radius: 24rpx;
background: #FFFFFF;
.item {
height: 80rpx;
padding: 0 24rpx;
font-size: 28rpx;
color: #333333;
}
.input {
flex: 1;
height: 80rpx;
text-align: right;
font-family: Regular;
font-size: 36rpx;
color: #FF7E00;
}
.icon-ic_edit {
margin-left: 8rpx;
font-size: 32rpx;
color: #999999;
}
.radio-group {
flex: 1;
}
.radio-item {
font-size: 28rpx;
color: #999999;
+.radio-item {
margin-left: 48rpx;
}
.iconfont {
margin-right: 12rpx;
font-size: 32rpx;
}
&.on {
color: #333333;
.iconfont {
color: #2A7EFB;
}
}
}
}
.footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 16rpx 20rpx 16rpx 32rpx;
padding-bottom: calc(16rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
background: #FFFFFF;
.btn {
display: inline-block;
height: 64rpx;
padding: 0 40rpx;
border-radius: 32rpx;
background: #2A7EFB;
font-weight: 500;
font-size: 26rpx;
line-height: 64rpx;
color: #FFFFFF;
}
.all {
font-size: 26rpx;
color: #333333;
.iconfont {
margin-right: 12rpx;
font-size: 40rpx;
color: #CCCCCC;
&.icon-a-ic_CompleteSelect {
color: #2A7EFB;
}
}
}
.btn-box {
flex: 1;
text-align: right;
.btn {
text-align: center;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,900 @@
<template>
<view class="pos-order-list" ref="container">
<!-- #ifdef MP || APP-PLUS -->
<NavBar titleText="售后订单" bagColor="#F5F5F5" :iconColor="iconColor" :textColor="iconColor" :isScrolling="isScrolling" showBack></NavBar>
<!-- #endif -->
<view class="searchCon acea-row">
<view class="search acea-row row-middle">
<text class="iconfont icon-ic_search"></text>
<input class="inputs" placeholder='请输入订单号/售后单号/快递单号/用户ID/手机号' placeholder-class='placeholder' confirm-type='search' name="search" v-model="where.order_id"
@confirm="searchSubmit"></input>
</view>
<view class="btn" @click="filterShow = true">
<text class="iconfont icon-ic_sort"></text>
</view>
</view>
<view class="nav acea-row row-around row-middle" id="nav" :style="{
top:getHeight.barTop+getHeight.barHeight+'px'
}">
<view class="item" :class="state == 5 ? 'on' : ''" @click="changeStatus(5)">
待处理
<image src="../static/adorn.png" v-if="state == 5"></image>
</view>
<view class="item" :class="state == 0 ? 'on' : ''" @click="changeStatus(0)">
待审核
<image src="../static/adorn.png" v-if="state == 0"></image>
</view>
<view class="item" :class="state == 2 ? 'on' : ''" @click="changeStatus(2)">
待退货
<image src="../static/adorn.png" v-if="state == 2"></image>
</view>
<view class="item" :class="state == 6 ? 'on' : ''" @click="changeStatus(6)">
已完成
<image src="../static/adorn.png" v-if="state == 6"></image>
</view>
</view>
<view class="list" v-if="list.length">
<view class="item" v-for="(item, index) in list" :key="index">
<view class="order-num acea-row row-between-wrapper" @click="toDetail(item)">
<view>
<view>售后单号:{{ item.order_id }}</view>
</view>
<view class="state" v-if="[0, 1, 2].includes(item.refund_type)">待审核</view>
<view class="state" v-if="[4, 5].includes(item.refund_type)">
待退货({{ item.apply_type == 2 ? '快递' : '到店' }})
</view>
<view class="state" v-if="[3, 6].includes(item.refund_type)">已完成</view>
</view>
<view class="pos-order-goods">
<view class="goods acea-row" @click="toDetail(item)">
<scroll-view class="picTxt scroll-view" scroll-x="true" v-if="item._info.length > 1">
<view class="pictrue" v-for="(val, key) in item._info" :key="key">
<image :src="val.cart_info.productInfo.attrInfo?val.cart_info.productInfo.attrInfo.image:val.cart_info.productInfo.image" />
</view>
</scroll-view>
<view class="picTxt" v-else>
<view class="acea-row" v-for="(val, key) in item._info" :key="key">
<view class="pictrue">
<image :src="val.cart_info.productInfo.attrInfo?val.cart_info.productInfo.attrInfo.image:val.cart_info.productInfo.image" />
</view>
<view class="text">
<view class="info line2">
<!-- <text v-if="val.cart_info.is_gift == 1" class="label">[赠品]</text> -->
{{ val.cart_info.productInfo.store_name }}
</view>
<view class="attr" v-if="val.cart_info.productInfo.attrInfo">
{{ val.cart_info.productInfo.attrInfo.suk }}
</view>
</view>
</view>
</view>
<view class="money">
<!-- <view class="x-money">¥{{ item.pay_price }}</view> -->
<BaseMoney :money="item.pay_price" symbolSize="20" integerSize="32" decimalSize="20"></BaseMoney>
<view class="num">共{{ item.total_num }}件</view>
<!-- <view class="y-money">
¥{{ val.cart_info.productInfo.ot_price }}
</view> -->
<!-- <view class="info" v-if="val.cart_info.refund_num && item._status._type !=-2">{{val.cart_info.refund_num}}件退款中</view> -->
</view>
</view>
</view>
<!-- <view class="public-total">
共{{ item.total_num }}件商品,实付款
<span class="money">¥{{ item.pay_price }}</span> ( 邮费 ¥{{
item.pay_postage
}}
)
</view> -->
<view class="operation acea-row row-between-wrapper">
<view v-if="item.apply_type == 1" class="more acea-row row-middle">
<text class="iconfont icon-ic_returnmoney"></text>仅退款
</view>
<view v-else-if="item.apply_type == 2 || item.apply_type == 3" class="more acea-row row-middle">
<text class="iconfont icon-ic_returnofgoods"></text>退货退款
</view>
<view class="acea-row row-middle">
<view class="btn" @click="modify(item, 1)">订单备注</view>
<view class="btn on" :class="openErp?'on':''" @click="modify(item,'2',1)" v-if="[1].includes(item.apply_type) && [0].includes(item.refund_type)">
退款审核
</view>
<view class="btn on" :class="openErp?'on':''" @click="modify(item,'2',0)" v-if="[2,3].includes(item.apply_type) && [0].includes(item.refund_type)">
退款审核
</view>
<view class="btn" v-if="[2].includes(item.apply_type) && [5].includes(item.refund_type)" @click="goLogistics(item)">查看物流</view>
<view class="btn on" v-if="[1,2,3].includes(item.apply_type) && [4,5].includes(item.refund_type)" @click="modify(item, 2, 1)">确认收货</view>
</view>
</view>
</view>
</view>
<emptyPage v-else title="暂无订单~" src="/statics/images/noOrder.gif"></emptyPage>
<Loading :loaded="loaded" :loading="loading"></Loading>
<PriceChange :change="change" :orderInfo="orderInfo" :isRefund="isRefund" v-on:statusChange="statusChange($event)" v-on:closechange="changeclose($event)" v-on:savePrice="savePrice"
:status="status"></PriceChange>
<view class="mask" v-if="filterShow" @click="filterShow = false"></view>
<view class="filter-popup" :class="{ on: filterShow }" :style="{
top:getHeight.barTop+getHeight.barHeight+'px'
}">
<view class="content">
<view class="item">
<view class="title">按退货类型</view>
<view class="acea-row list">
<view class="cell" v-for="(item, index) in dateList" :key="index" :class="{ on: item.val == where.apply_type }" @click="dateChange(item.val)">{{ item.label }}</view>
</view>
</view>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
getAdminOrderList,
setAdminOrderPrice,
setAdminOrderRemark,
setAdminRefundRemark,
setOfflinePay,
setOrderRefund,
orderRefundAgree,
adminRefundList,
} from "@/api/admin";
import {
erpConfig
} from "@/api/esp.js";
import Loading from '@/components/Loading/index'
import PriceChange from '../components/PriceChange/index.vue'
import emptyPage from '@/components/emptyPage.vue'
import NavBar from '@/components/NavBar.vue'
import {
isMoney
} from '@/utils/validate.js';
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
name: "AdminOrderList",
components: {
Loading,
PriceChange,
emptyPage,
NavBar,
},
data() {
return {
getHeight: this.$util.getWXStatusHeight(),
iconColor: '#333333',
isScrolling: false,
top: 0,
navHeight: 0,
isFixed: false,
filterShow: false,
openErp: false,
current: "",
change: false,
types: 0,
where: {
order_id: '',
refundTypes: 5,
apply_type: '',
page: 1,
limit: 10,
},
list: [],
loaded: false,
loading: false,
orderInfo: {},
status: "",
state: 5,
isRefund: 0, //1是仅退款;0是退货退款
imgHost: HTTP_REQUEST_URL,
dateSelected: '',
dateList: [{
label: '全部',
val: '',
},
{
label: '退货退款',
val: '2',
},
{
label: '仅退款',
val: '1',
},
],
payList: [{
label: '全部',
val: '',
},
{
label: '微信支付',
val: '1'
},
{
label: '支付宝支付',
val: '4'
},
{
label: '余额抵扣',
val: '2'
},
{
label: '线下支付',
val: '3'
},
],
};
},
onLoad(option) {
let type = option.types;
this.getErpConfig();
},
onShow() {
this.init();
},
mounted() {
const query = uni.createSelectorQuery().in(this);
query.select("#nav").boundingClientRect((data) => {
this.top = data.top;
this.navHeight = data.height;
}).exec();
},
onPageScroll(option) {
// if (this.top >= option.scrollTop) {
// this.isFixed = false;
// } else {
// this.isFixed = true;
// }
},
methods: {
searchSubmit() {
},
statusChange(e) {
this.status = e;
},
goDelivery(item) {
if (this.openErp) return
uni.navigateTo({
url: '/pages/admin/delivery/index?id=' + item.order_id + '&listId=' + item.id + '&totalNum=' + item.total_num + '&orderStatus=' + item._status + '&comeType=1&productType=' +
item.product_type
})
},
getErpConfig() {
erpConfig().then(res => {
this.openErp = res.data.open_erp;
}).catch(err => {
this.$util.Tips({
title: err
})
})
},
// 获取数据
getIndex: function() {
let that = this;
if (that.loading || that.loaded) return;
that.loading = true;
let obj = adminRefundList(that.where);
obj.then(
res => {
that.loading = false;
that.loaded = res.data.length < that.where.limit;
that.list.push.apply(that.list, res.data);
that.where.page = that.where.page + 1;
},
err => {
that.$util.Tips({
title: err
})
}
);
},
// 初始化
init: function() {
this.list = [];
this.where.page = 1;
this.loaded = false;
this.loading = false;
this.getIndex();
this.current = "";
},
searchSubmit() {
this.init();
},
// 导航切换
changeStatus(val) {
if (this.state != val) {
this.state = val;
this.where.refundTypes = val;
this.init();
}
},
// 商品操作
modify: function(item, status, type) {
if (this.openErp && status != 1) return
this.change = true;
this.status = status.toString();
this.orderInfo = item;
if (status == 2) {
this.isRefund = type
}
},
changeclose: function(msg) {
this.change = msg;
this.orderInfo = {};
},
objOrderRefund(data) {
let that = this;
setOrderRefund(data).then(
res => {
that.change = false;
that.$util.Tips({
title: res.msg
});
that.init();
},
err => {
that.change = false;
that.$util.Tips({
title: err
});
}
);
},
async savePrice(opt) {
let that = this,
data = {},
price = opt.price,
refund_price = opt.refund_price,
refund_status = that.orderInfo.refund_status,
remark = opt.remark;
data.order_id = that.orderInfo.order_id;
if (that.status == 0) {
if (!isMoney(price)) {
return that.$util.Tips({
title: '请输入正确的金额'
});
}
data.price = price;
setAdminOrderPrice(data).then(
res => {
that.change = false;
that.$util.Tips({
title: '改价成功',
icon: 'success'
})
that.init();
},
err => {
that.change = false;
that.$util.Tips({
title: '改价失败',
icon: 'none'
})
}
);
} else if (that.status == 2) {
if (this.isRefund) {
// setOrderRefund(data).then(
// res => {
// that.change = false;
// that.$util.Tips({title: res.msg});
// that.init();
// },
// err => {
// that.change = false;
// that.$util.Tips({title: err});
// }
// );
if (!isMoney(refund_price)) {
return that.$util.Tips({
title: '请输入正确的金额'
});
}
data.price = refund_price;
data.type = opt.type;
this.objOrderRefund(data);
} else {
if (opt.type == 1) {
orderRefundAgree(this.orderInfo.id).then(res => {
that.change = false;
that.$util.Tips({
title: res.msg
});
that.init();
}).catch(err => {
that.change = false;
that.$util.Tips({
title: err
});
})
}
// else{
// data.type = opt.type;
// data.refuse_reason = opt.refuse_reason;
// this.objOrderRefund(data);
// }
if (opt.type == 2) {
data.type = opt.type;
data.refuse_reason = opt.refuse_reason;
this.objOrderRefund(data);
}
}
} else if (that.status == 8) {
data.type = opt.type;
data.refuse_reason = opt.refuse_reason;
this.objOrderRefund(data);
} else {
if (!remark) {
return this.$util.Tips({
title: '请输入备注'
})
}
data.remark = remark;
let obj = '';
if (that.where.status == -3) {
obj = setAdminRefundRemark(data);
} else {
obj = setAdminOrderRemark(data);
}
obj.then(
res => {
that.change = false;
this.$util.Tips({
title: res.msg,
icon: 'success'
})
that.init();
},
err => {
that.change = false;
that.$util.Tips({
title: err
});
}
);
}
},
toDetail(item) {
uni.navigateTo({
url: `/pages/admin/refundOrderDetail/index?id=${item.order_id}`
})
},
offlinePay: function(item) {
if (this.openErp) return
setOfflinePay({
order_id: item.order_id
}).then(
res => {
this.$util.Tips({
title: res.msg,
icon: "success"
});
this.init();
},
error => {
this.$util.Tips(error);
}
);
},
dateChange(value) {
this.filterShow = false;
this.where.apply_type = value;
this.init();
},
payChange(val) {
this.filterShow = false;
this.where.pay_type = val;
this.init();
},
goLogistics(orderInfo) {
uni.navigateTo({
url: '/pages/admin/logistics/index?type=refund&orderId=' + orderInfo.order_id
})
},
},
onReachBottom() {
this.getIndex()
}
}
</script>
<style lang="scss" scoped>
.pos-order-list {
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
}
.searchCon {
padding: 10rpx 20rpx;
.search {
flex: 1;
height: 72rpx;
padding: 0 32rpx;
border-radius: 36rpx;
background: #FFFFFF;
.iconfont {
margin-right: 16rpx;
font-size: 32rpx;
color: #999999;
}
.inputs {
flex: 1;
font-size: 28rpx;
color: #333333;
}
.placeholder {
font-size: 26rpx;
color: #ccc;
}
}
.btn {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
margin-left: 20rpx;
background: #FFFFFF;
text-align: center;
.iconfont {
font-size: 32rpx;
line-height: 72rpx;
color: #666666;
}
}
}
.pos-order-list .nav {
position: sticky;
top: 0;
right: 0;
left: 0;
z-index: 99;
background: #F5F5F5;
font-size: 26rpx;
line-height: 42rpx;
color: #333333;
.item {
position: relative;
padding: 28rpx 0;
image {
width: 14rpx;
height: 14rpx;
display: block;
position: absolute;
bottom: 20rpx;
right: -4rpx;
}
}
}
.pos-order-list .nav .item.on {
font-weight: 500;
font-size: 30rpx;
color: #2A7EFB;
}
.pos-order-list .list {
padding: 0 20rpx;
}
.pos-order-list .nothing {
margin-top: 120upx;
text-align: center;
color: #cfcfcf;
}
.pos-order-list .list .item {
padding: 32rpx 24rpx;
border-radius: 24rpx;
background-color: #fff;
}
.pos-order-list .list .item~.item {
margin-top: 20rpx;
}
.pos-order-list .list .item .order-num {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.pos-order-list .list .item .order-num .state {
color: #FF7E00;
}
.pos-order-list .list .item .order-num .state.on {
font-size: 24rpx;
width: 150rpx;
text-align: right;
}
.pos-order-list .list .item .order-num .time {
font-size: 26upx;
font-weight: normal;
color: #999;
}
.pos-order-list .list .item .operation .more {
position: relative;
font-size: 26rpx;
color: #999999;
}
.pos-order-list .list .item .operation .more .iconfont {
margin-right: 12rpx;
font-size: 34rpx;
color: #2A7EFB;
}
.pos-order-list .list .item .operation .icon-gengduo {
font-size: 50upx;
color: #aaa;
}
.pos-order-list .list .item .operation .order .arrow {
width: 0;
height: 0;
border-left: 11upx solid transparent;
border-right: 11upx solid transparent;
border-top: 20upx solid #e5e5e5;
position: absolute;
left: 15upx;
bottom: -18upx;
}
.pos-order-list .list .item .operation .order .arrow:before {
content: '';
width: 0;
height: 0;
border-left: 7upx solid transparent;
border-right: 7upx solid transparent;
border-top: 20upx solid #fff;
position: absolute;
left: -7upx;
bottom: 0;
}
.pos-order-list .list .item .operation .order {
width: 200upx;
background-color: #fff;
border: 1px solid #eee;
border-radius: 10upx;
position: absolute;
top: -100upx;
z-index: 9;
}
.pos-order-list .list .item .operation .order .items {
height: 77upx;
line-height: 77upx;
text-align: center;
}
.pos-order-list .list .item .operation .order .items~.items {
border-top: 1px solid #f5f5f5;
}
.pos-order-list .list .item .operation .btn {
height: 56rpx;
padding: 0 24rpx;
border-radius: 28rpx;
border: 1rpx solid #CCCCCC;
font-size: 24rpx;
line-height: 54rpx;
color: #333333;
&.on {
color: #FFFFFF !important;
background-color: #2A7EFB !important;
border-color: #2A7EFB !important;
}
}
.pos-order-list .list .item .operation .btn~.btn {
margin-left: 16rpx;
}
.pos-order-list .list .item .operation .wait {
margin-left: 30rpx;
}
.pos-order-goods .goods {
padding: 26rpx 0;
}
.pos-order-goods .goods~.goods {
border-top: 1px dashed #e5e5e5;
}
.pos-order-goods .goods .picTxt {
flex: 1;
min-width: 0;
}
.pos-order-goods .goods .scroll-view {
box-sizing: border-box;
white-space: nowrap;
.pictrue {
display: inline-block;
+.pictrue {
margin-left: 16rpx;
}
}
}
.pos-order-goods .goods .picTxt .pictrue {
width: 136rpx;
height: 136rpx;
}
.pos-order-goods .goods .picTxt .pictrue image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.pos-order-goods .goods .picTxt .text {
flex: 1;
min-width: 0;
padding-left: 20rpx;
}
.pos-order-goods .goods .picTxt .text .info {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.pos-order-goods .goods .picTxt .text .info .label {
color: #ff4c3c;
}
.pos-order-goods .goods .picTxt .text .attr {
margin-top: 12rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.pos-order-goods .goods .money {
padding-left: 16rpx;
text-align: right;
font-size: 28upx;
}
.pos-order-goods .goods .money .info {
margin-top: 18rpx;
font-size: 24rpx;
}
.pos-order-goods .goods .money .x-money {
color: #282828;
}
.pos-order-goods .goods .money .num {
margin-top: 10rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.pos-order-goods .goods .money .y-money {
color: #999;
text-decoration: line-through;
}
.public-total {
font-size: 28upx;
color: #282828;
border-top: 1px solid #eee;
height: 92upx;
line-height: 92upx;
text-align: right;
padding: 0 30upx;
background-color: #fff;
}
.public-total .money {
color: #ff4c3c;
}
.mask {
z-index: 900;
}
.filter-popup {
position: fixed;
top: 0;
left: 0;
z-index: 900;
width: 100%;
border-radius: 0 0 32rpx 32rpx;
background: #FFFFFF;
transform: translateY(-100%);
transition: transform 0.3s;
&.on {
transform: translateY(0);
}
.search-box {
padding: 10rpx 32rpx;
}
.search {
height: 58rpx;
padding: 0 32rpx;
border-radius: 29rpx;
background: #F5F5F5;
}
.iconfont {
font-size: 28rpx;
color: #999999;
}
.input {
flex: 1;
height: 58rpx;
padding-left: 16rpx;
font-size: 24rpx;
}
.content {
padding: 32rpx 30rpx 58rpx;
}
.item {
margin-top: 36rpx;
&:first-child {
margin-top: 0;
}
}
.title {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.list {
padding: 0;
margin-right: -24rpx;
}
.cell {
width: 154rpx;
height: 56rpx;
border: 1rpx solid #F5F5F5;
border-radius: 28rpx;
margin: 24rpx 24rpx 0 0;
background: #F5F5F5;
text-align: center;
font-size: 24rpx;
line-height: 54rpx;
color: #333333;
&.on {
border-color: #2A7EFB;
background: #E9F2FE;
color: #2A7EFB;
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
pages/admin/static/scan.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -0,0 +1,251 @@
<template>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="coupon rd-t-40rpx">
<view class="title">优惠券
<view class="close acea-row row-center-wrapper" @tap="closeDrawer">
<text class="iconfont icon-ic_close"></text>
</view>
</view>
<view class="search acea-row row-middle" v-if="num !=2">
<text class="iconfont icon-ic_search"></text>
<input class="inputs" placeholder='请输入优惠券名称' placeholder-class='placeholder' confirm-type='search' name="search"
v-model="keyword" @confirm="searchSubmit"></input>
</view>
<view class="list" v-if="couponList.length">
<scroll-view scroll-y="true" style="max-height: 800rpx;min-height: 500rpx;">
<view class="item acea-row row-middle" v-for="(item,index) in couponList" :key="index">
<view class="bg">
<view class="price" v-if="item.coupon_type==1">¥<text class="num">{{item.coupon_price}}</text></view>
<view class="price" v-else><text class="num">{{parseFloat(item.coupon_price)/10}}</text>折</view>
<view class="reduction">满{{item.use_min_price}}可用</view>
</view>
<view class="text">
<view class="name line1">{{item.coupon_title}}</view>
<view class="type" v-if="item.type === 0 || item.applicable_type == 0">通用优惠券</view>
<view class="type" v-if="item.type === 1 || item.applicable_type == 1">品类优惠券</view>
<view class="type" v-if="item.type === 2 || item.applicable_type == 2">商品优惠券</view>
<view class="type" v-if="item.type === 3 || item.applicable_type == 3">品牌优惠券</view>
<view class="time" v-if="item.coupon_time">有效期:{{item.coupon_time}}</view>
<view class="time" v-else>有效期:{{ item.start_time ? item.start_time + '-' : '' }}{{ item.end_time }}</view>
</view>
<view v-if="num !=2" class="bnt acea-row row-center-wrapper" @click="send(item)">发送</view>
</view>
<view class="tips">没有更多了~</view>
</scroll-view>
</view>
<view class="empty-box" v-else>
<emptyPage title="暂无优惠券~" src="/statics/images/noCoupon.png"></emptyPage>
</view>
</view>
</base-drawer>
</template>
<script>
import emptyPage from '@/components/emptyPage.vue';
import {
getUserCoupon,
postUserUpdate
} from "@/api/admin";
export default {
components: {
emptyPage
},
props:{
visible: {
type: Boolean,
default: false,
},
uid: {
type: Number,
default: 0
}
},
data(){
return{
keyword:'',
couponList:[],
num:0, //1用户批量,0单独用户,前两个是发送优惠券;点击获取优惠券时: 2是查看当前用户优惠券,否则获取优惠券
ids:[]
}
},
mounted: function() {},
methods:{
send(item){
postUserUpdate({
type:3,
uid:this.num?this.ids:this.uid,
coupon_id:item.id
}).then(res=>{
this.$util.Tips({
title: res.msg
});
this.$emit('closeDrawer',1);
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
searchSubmit(){
this.userCoupon();
},
userCoupon(num,ids){
this.num = num;
this.ids = ids;
getUserCoupon({
coupon_title:this.keyword,
uid:this.num==2?this.uid:0
}).then(res=>{
this.couponList = res.data.list
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
closeDrawer() {
this.keyword = '';
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
.empty-box{
padding: 0 20rpx;
margin-bottom: 20rpx;
}
.coupon{
background-color:#F5F5F5;
padding-bottom: 1rpx;
.title{
text-align: center;
height: 108rpx;
line-height: 108rpx;
font-size: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
padding: 0 30rpx;
.close{
width: 36rpx;
height: 36rpx;
line-height: 36rpx;
background: #EEEEEE;
border-radius: 50%;
position: absolute;
right: 30rpx;
top:38rpx;
.iconfont {
font-weight: 300;
font-size: 20rpx;
}
}
}
.search{
width: 710rpx;
height: 72rpx;
background: #FFFFFF;
border-radius: 50rpx;
padding: 0 34rpx;
margin: 24rpx auto;
&.on{
width: 618rpx;
}
.iconfont{
color: #999;
font-size: 32rpx;
margin-right: 16rpx;
}
.inputs{
font-size: 28rpx;
width: 100%;
height: 100%;
flex: 1;
}
.placeholder{
color: #ccc;
}
}
.list{
padding: 0 20rpx;
.item{
background-color: #fff;
border-radius: 30rpx;
margin-bottom: 20rpx;
.bg{
background-image: url('../../../static/coupon.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 188rpx;
height: 170rpx;
font-size: 22rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #FFFFFF;
text-align: center;
padding: 32rpx 0;
.price{
font-size: 28rpx;
font-weight: 600;
.num{
font-size: 52rpx;
font-family:'Regular';
}
}
.reduction{
margin-top: 14rpx;
color: rgba(255, 255, 255, 0.7);
}
}
.text{
margin-left: 20rpx;
font-family: PingFang SC, PingFang SC;
.name{
font-size: 28rpx;
font-weight: 600;
color: #333333;
width: 336rpx;
}
.type{
font-size: 20rpx;
font-weight: 400;
color: #666666;
margin-top: 8rpx;
}
.time{
font-size: 20rpx;
font-weight: 400;
color: #999999;
margin-top: 20rpx;
}
}
.bnt{
width: 112rpx;
height: 52rpx;
background: #E9F2FE;
border-radius: 26rpx;
font-size: 22rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #2A7EFB;
margin-left: 34rpx;
}
}
.tips{
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #CCCCCC;
text-align: center;
margin: 32rpx 0;
margin-bottom: calc(32rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
margin-bottom: calc(32rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
}
}
}
</style>

View File

@@ -0,0 +1,207 @@
<template>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-balance rd-t-40rpx">
<view class="title">修改{{type?'余额':'积分'}}
<view class="close acea-row row-center-wrapper" @tap="closeDrawer">
<text class="iconfont icon-ic_close"></text>
</view>
</view>
<view class="list">
<view class="item acea-row row-between-wrapper">
<view>修改{{type?'余额':'积分'}}</view>
<view class="acea-row row-middle">
<view class="itemn acea-row row-middle" :class="current == index?'on':''" v-for="(item, index) in navList" :key="index" @click="navTap(index)">
<text class="iconfont" :class="current == index?'icon-ic_Selected':'icon-ic_unselect'"></text>
<text>{{item}}</text>
</view>
</view>
</view>
<view class="item acea-row row-between-wrapper">
<view>{{type?'余额':'积分'}}</view>
<view class="acea-row row-middle">
<input type="number" v-model="numeral" :placeholder="type?'请填写余额':'请填写积分'" placeholder-class="placeholder"/>
<text class="iconfont icon-ic_edit"></text>
</view>
</view>
</view>
<view class="footer acea-row row-between-wrapper">
<view class="bnt acea-row row-center-wrapper" @click="closeDrawer">取消</view>
<view class="bnt on acea-row row-center-wrapper" @click="define">确定</view>
</view>
</view>
</base-drawer>
</template>
<script>
import {
postUserUpdateOther
} from "@/api/admin";
export default {
props:{
visible: {
type: Boolean,
default: false,
},
type: {
type: Number,
default: 0,
},
uid: {
type: Number,
default: 0
}
},
watch: {
type: {
handler(newValue, oldValue) {
if(newValue){
this.navList = ['增加余额','减少余额']
}else{
this.navList = ['增加积分','减少积分']
}
},
immediate: true
}
},
data(){
return{
navList:[],
current:0,
numeral:0
}
},
mounted: function() {},
methods:{
navTap(index){
this.current = index
},
define(){
if(this.numeral<=0){
let title = '';
if(this.type){
title = '请填写你要增加或减少的余额'
}else{
title = '请填写你要增加或减少的积分'
}
this.$util.Tips({
title: title
});
return
}
postUserUpdateOther(this.uid,{
status:this.current + 1,
number:this.numeral,
type:this.type
}).then(res=>{
this.$util.Tips({
title: res.msg
});
this.numeral = 0;
this.$emit('successChange');
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
closeDrawer() {
this.numeral = 0;
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
.edit-balance{
background-color: #fff;
padding-bottom: 60rpx;
.title{
text-align: center;
height: 108rpx;
line-height: 108rpx;
font-size: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
padding: 0 30rpx;
.close{
width: 36rpx;
height: 36rpx;
line-height: 36rpx;
background: #EEEEEE;
border-radius: 50%;
position: absolute;
right: 30rpx;
top:38rpx;
.iconfont {
font-weight: 300;
font-size: 20rpx;
}
}
}
.list{
padding: 0 30rpx;
.item{
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
height: 72rpx;
margin-bottom: 32rpx;
box-sizing: border-box;
.icon-ic_edit{
color: #999999;
}
.itemn{
margin-left: 50rpx;
color: #999999;
.iconfont {
margin-top: 4rpx;
color: #CCCCCC;
margin-right: 14rpx;
}
&.on {
color: #333333;
.iconfont {
color: #2A7EFB;
}
}
}
input {
text-align: right;
font-size: 36rpx;
font-family: Regular;
color: #FF7E00;
}
/deep/.uni-input-input{
padding-right: 10rpx;
}
.placeholder{
font-size: 28rpx;
padding-right: 10rpx;
padding: 6rpx 10rpx 0 0;
}
}
}
.footer{
padding: 0 20rpx;
margin-top: 166rpx;
.bnt{
width: 346rpx;
height: 72rpx;
border: 2rpx solid #2A7EFB;
border-radius: 100rpx;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #2A7EFB;
&.on{
background: #2A7EFB;
color: #fff;
}
}
}
}
</style>

View File

@@ -0,0 +1,246 @@
<template>
<base-drawer mode="right" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-lable">
<!-- #ifdef MP -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>筛选</view>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<view class="list"
:style="'height: calc(100% - '+(getHeight.barTop+getHeight.barHeight*2+150)+'rpx - constant(safe-area-inset-bottom));height: calc(100% - '+(getHeight.barTop+getHeight.barHeight*2+150)+'rpx - env(safe-area-inset-bottom))'">
<!-- #endif -->
<!-- #ifndef MP -->
<view class="header">筛选</view>
<view class="list">
<!-- #endif -->
<scroll-view scroll-y="true" style="height: 100%">
<view class="item">
<view class="title">分组</view>
<view class="listn acea-row row-middle">
<view class="name acea-row row-center-wrapper" :class="{on:groupIds == item.id}" v-for="(item,groupIndex) in groupArray" :key="groupIndex" @click="selectGroup(item)">
<text class="line1">{{item.group_name}}</text>
</view>
</view>
</view>
<view class="item">
<view class="title">等级</view>
<view class="listn acea-row row-middle">
<view class="name acea-row row-center-wrapper" :class="{on:levelIds == item.id}" v-for="(item,levelIndex) in levelArray" :key="levelIndex" @click="selectLevel(item)">
<text class="line1">{{item.name}}</text>
</view>
</view>
</view>
<view class="item">
<view class="title">标签</view>
<view v-for="(item, index) in labelList" :key="index">
<view class="titlen" v-if="item.label && item.label.length">{{item.name}}</view>
<view class="listn acea-row row-middle" v-if="item.label && item.label.length">
<view class="name acea-row row-center-wrapper" :class="{on:labelIds.includes(j.id)}" v-for="(j, indexn) in item.label" :key="indexn" @click="selectLabel(j)">
<text class="line1">{{j.label_name}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="footer acea-row row-between-wrapper">
<view class="bnt acea-row row-center-wrapper" @tap="reset">重置</view>
<view class="bnt on acea-row row-center-wrapper" @tap="define">确定</view>
</view>
</view>
</base-drawer>
</template>
<script>
import {
getUserLabel
} from "@/api/admin";
export default {
props:{
visible: {
type: Boolean,
default: false,
},
groupArray: {
type: Array,
default: [],
},
levelArray: {
type: Array,
default: [],
},
},
data: function() {
return {
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
labelList:[],
labelIds:[],
groupIds:0,
levelIds:0
}
},
mounted() {
},
methods:{
reset(){
this.labelIds=[];
this.groupIds=0;
this.levelIds=0;
},
define(){
let data = {
labelIds: this.labelIds.join(','),
groupIds: this.groupIds,
levelIds: this.levelIds
};
this.$emit('successChange',data);
},
selectGroup(item){
this.groupIds = item.id;
},
selectLevel(item){
this.levelIds = item.id;
},
selectLabel(item){
if(this.labelIds.includes(item.id)){
this.labelIds = this.labelIds.filter(function (ele){return ele != item.id;});
}else{
this.labelIds.push(item.id);
}
},
productLabel(){
getUserLabel().then(res=>{
this.labelList = res.data
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
closeDrawer() {
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
.accountTitle{
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
padding-bottom: 6rpx;
.sysTitle{
width: 100%;
position: relative;
font-weight: 600;
color: #333333;
font-size: 34rpx;
font-family: PingFang SC, PingFang SC;
}
}
.edit-lable{
background-color: #fff;
width: 670rpx;
border-radius: 40rpx 0 0 40rpx;
height: 100%;
padding: 20rpx 34rpx 0 32rpx;
.header{
text-align: center;
height: 96rpx;
line-height: 96rpx;
font-size: 34rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
}
.list{
overflow: auto;
height: calc(100% - 208rpx );
height: calc(100% - (208rpx + constant(safe-area-inset-bottom)));
height: calc(100% - (208rpx + env(safe-area-inset-bottom)));
.item{
margin-top: 48rpx;
&~.item{
.titlen{
margin-top: 48rpx;
}
}
.title{
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
}
.titlen{
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #666666;
margin-top: 24rpx;
}
.listn{
.name{
width: 184rpx;
height: 56rpx;
background-color: #F5F5F5;
border-radius: 50rpx;
border:1rpx solid #F5F5F5;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
margin-right: 26rpx;
margin-top: 24rpx;
padding: 0 8rpx;
&.on {
background-color:#E9F2FE;
border-color:#2A7EFB;
color: #2A7EFB;
}
&:nth-of-type(3n){
margin-right: 0;
}
}
}
}
}
.footer{
width: 100%;
height: 112rpx;
position: fixed;
bottom: 0;
left:0;
padding: 0 32rpx;
background-color: #fff;
border-radius: 0 0 0 40rpx;
height: calc(112rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(112rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
.bnt{
width: 296rpx;
height: 72rpx;
border: 1px solid #2A7EFB;
border-radius: 200rpx;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #2A7EFB;
&.on{
background: #2A7EFB;
border-color: #2A7EFB;
color: #fff;
}
}
}
}
</style>

View File

@@ -0,0 +1,197 @@
<template>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-balance rd-t-40rpx">
<view class="title">赠送会员
<view class="close acea-row row-center-wrapper" @tap="closeDrawer">
<text class="iconfont icon-ic_close"></text>
</view>
</view>
<view class="list">
<view class="item acea-row row-between-wrapper">
<view>会员到期日</view>
<view class="time">{{userInfo.svip_overdue_time || '已过期/暂未开通'}}</view>
</view>
<view class="item acea-row row-between-wrapper">
<view>剩余天数</view>
<view class="time">{{userInfo.svip_over_day}}</view>
</view>
<view class="item acea-row row-between-wrapper">
<view>修改付费会员</view>
<view class="acea-row row-middle">
<view class="itemn acea-row row-middle" :class="current == index?'on':''" v-for="(item, index) in navList" :key="index" @click="navTap(index)">
<text class="iconfont" :class="current == index?'icon-ic_Selected':'icon-ic_unselect'"></text>
<text>{{item}}</text>
</view>
</view>
</view>
<view class="item acea-row row-between-wrapper">
<view>调整时长(天)</view>
<view class="acea-row row-middle">
<input type="numeric" v-model="numeral" placeholder="请输入时长" placeholder-class="placeholder"/>
<text class="iconfont icon-ic_edit"></text>
</view>
</view>
</view>
<view class="footer acea-row row-between-wrapper">
<view class="bnt acea-row row-center-wrapper" @click="closeDrawer">取消</view>
<view class="bnt on acea-row row-center-wrapper" @click="define">确定</view>
</view>
</view>
</base-drawer>
</template>
<script>
import {
postUserUpdate
} from "@/api/admin";
export default {
props:{
visible: {
type: Boolean,
default: false,
},
userInfo: {
type: Object,
default: () => {}
}
},
data(){
return{
navList:['增加','减少'],
current:0,
numeral:0
}
},
mounted: function() {},
methods:{
navTap(index){
this.current = index
},
define(){
if(this.numeral <=0){
this.$util.Tips({
title: '请填写有效时长'
});
return
}
postUserUpdate({
type:2,
uid:this.userInfo.uid,
days_status:this.current+1,
days:this.numeral
}).then(res=>{
this.$util.Tips({
title: res.msg
});
this.numeral = 0
this.$emit('successChange');
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
closeDrawer() {
this.numeral = 0
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
.edit-balance{
background-color: #fff;
padding-bottom: 60rpx;
.title{
text-align: center;
height: 108rpx;
line-height: 108rpx;
font-size: 32rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
padding: 0 30rpx;
.close{
width: 36rpx;
height: 36rpx;
line-height: 36rpx;
background: #EEEEEE;
border-radius: 50%;
position: absolute;
right: 30rpx;
top:38rpx;
.iconfont {
font-weight: 300;
font-size: 20rpx;
}
}
}
.list{
padding: 0 30rpx;
.item{
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
height: 72rpx;
margin-bottom: 32rpx;
box-sizing: border-box;
.icon-ic_edit{
color: #999999;
}
.time{
color: #999999;
}
.itemn{
margin-left: 50rpx;
color: #999999;
.iconfont {
margin-top: 4rpx;
color: #CCCCCC;
margin-right: 14rpx;
}
&.on {
color: #333333;
.iconfont {
color: #2A7EFB;
}
}
}
input {
text-align: right;
font-size: 36rpx;
font-family: Regular;
color: #FF7E00;
}
/deep/.uni-input-input{
padding-right: 10rpx;
}
.placeholder{
font-size: 28rpx;
padding-right: 10rpx;
padding: 6rpx 10rpx 0 0;
}
}
}
.footer{
padding: 0 20rpx;
margin-top: 90rpx;
.bnt{
width: 346rpx;
height: 72rpx;
border: 2rpx solid #2A7EFB;
border-radius: 100rpx;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #2A7EFB;
&.on{
background: #2A7EFB;
color: #fff;
}
}
}
}
</style>

View File

@@ -0,0 +1,252 @@
<template>
<base-drawer mode="right" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-lable">
<!-- #ifdef MP -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>添加标签</view>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<view class="list" v-if="isStore"
:style="'height: calc(100% - '+(getHeight.barTop+getHeight.barHeight*2+150)+'rpx - constant(safe-area-inset-bottom));height: calc(100% - '+(getHeight.barTop+getHeight.barHeight*2+150)+'rpx - env(safe-area-inset-bottom))'">
<!-- #endif -->
<!-- #ifndef MP -->
<view class="header">添加标签</view>
<view class="list" v-if="isStore">
<!-- #endif -->
<scroll-view scroll-y="true" style="height: 100%">
<view class="item" v-for="(item, index) in labelList" :key="index">
<view class="title" v-if="item.label && item.label.length">{{item.name}}</view>
<view class="listn acea-row row-middle" v-if="item.label && item.label.length">
<view class="name acea-row row-center-wrapper" :class="{on:j.disabled}" v-for="(j, indexn) in item.label" :key="indexn" @click="selectLabel(j)">
<text class="line1">{{j.label_name}}</text>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="empty-box" v-else>
<emptyPage title="暂无标签~" src="/statics/images/empty-box.png"></emptyPage>
</view>
<view class="footer acea-row row-between-wrapper">
<view class="bnt acea-row row-center-wrapper" @tap="reset">重置</view>
<view class="bnt on acea-row row-center-wrapper" @tap="define">确定</view>
</view>
</view>
</base-drawer>
</template>
<script>
import emptyPage from '@/components/emptyPage.vue';
import {
getUserLabel,
postUserUpdate
} from "@/api/admin";
import { handleError } from "vue";
export default {
components: {
emptyPage
},
props:{
visible: {
type: Boolean,
default: false,
},
},
data: function() {
return {
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
labelList:[],
goodsInfo:{}, //列表中已存在id(固定不变)
dataLabel: [], //已存在选中id(随着选中可以变化)
isStore:false, //判断是否存在标签
num:0, // 判断是否为批量
ids:[] //批量时的id集合
};
},
mounted() {
},
methods:{
define(){
let labelIds = []
this.dataLabel.forEach(item=>{
labelIds.push(item.id)
})
postUserUpdate({
type:5,
uid:this.num?this.ids:this.goodsInfo.uid,
label_id:labelIds
}).then(res=>{
this.$util.Tips({
title: res.msg
});
this.$emit('closeDrawer',1);
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
reset(){
this.productLabel(this.goodsInfo,this.num,this.ids);
},
inArray: function (search, array) {
for (let i in array) {
if (array[i].id == search) {
return true;
}
}
return false;
},
productLabel(data,num,ids){
this.dataLabel = data.label_id || [];
this.goodsInfo = JSON.parse(JSON.stringify(data));
this.num = num;
this.ids = ids;
getUserLabel().then(res=>{
res.data.map(el => {
if (el.label && el.label.length) {
this.isStore = true;
el.label.map(label => {
if (this.inArray(label.id, this.dataLabel)) {
label.disabled = true;
} else {
label.disabled = false;
}
})
}
})
this.labelList = res.data
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
selectLabel(label) {
if (label.disabled) {
let index = this.dataLabel.indexOf(this.dataLabel.filter(d => d.id == label.id)[0]);
this.dataLabel.splice(index, 1);
label.disabled = false
} else {
this.dataLabel.push({
id:label.id,
label_name:label.label_name
});
label.disabled = true
}
},
closeDrawer() {
this.$emit('closeDrawer');
}
}
}
</script>
<style lang="scss" scoped>
.accountTitle{
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
padding-bottom: 6rpx;
.sysTitle{
width: 100%;
position: relative;
font-weight: 600;
color: #333333;
font-size: 34rpx;
font-family: PingFang SC, PingFang SC;
}
}
.edit-lable{
background-color: #fff;
width: 670rpx;
border-radius: 40rpx 0 0 40rpx;
height: 100%;
padding: 20rpx 34rpx 0 32rpx;
.header{
text-align: center;
height: 96rpx;
line-height: 96rpx;
font-size: 34rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
position: relative;
}
.list{
overflow: auto;
height: calc(100% - 208rpx );
height: calc(100% - (208rpx + constant(safe-area-inset-bottom)));
height: calc(100% - (208rpx + env(safe-area-inset-bottom)));
.item{
margin-top: 48rpx;
.title{
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
}
.listn{
.name{
width: 184rpx;
height: 56rpx;
background-color: #F5F5F5;
border-radius: 50rpx;
border:1rpx solid #F5F5F5;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
margin-right: 26rpx;
margin-top: 24rpx;
padding: 0 8rpx;
&.on {
background-color:#E9F2FE;
border-color:#2A7EFB;
color: #2A7EFB;
}
&:nth-of-type(3n){
margin-right: 0;
}
}
}
}
}
.footer{
width: 100%;
height: 112rpx;
position: fixed;
bottom: 0;
left:0;
padding: 0 32rpx;
background-color: #fff;
border-radius: 0 0 0 40rpx;
height: calc(112rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(112rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
.bnt{
width: 296rpx;
height: 72rpx;
border: 1px solid #2A7EFB;
border-radius: 200rpx;
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #2A7EFB;
&.on{
background: #2A7EFB;
border-color: #2A7EFB;
color: #fff;
}
}
}
}
</style>

559
pages/admin/user/index.vue Normal file
View File

@@ -0,0 +1,559 @@
<template>
<view class="user-details">
<!-- #ifdef MP || APP-PLUS -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>用户详情</view>
<text class="iconfont icon-ic_leftarrow" @click="goarrow"></text>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<!-- #endif -->
<view class="header">
<view class="picTxt acea-row row-middle">
<view class="pictrue">
<image :src="infoData.avatar"></image>
</view>
<view class="text">
<view class="name acea-row row-middle">
<view class="nameCon line1">{{infoData.nickname}}</view>
<view class="svip acea-row row-center-wrapper" v-if="infoData.isMember == 1">SVIP</view>
<view class="vip acea-row row-center-wrapper" v-if="infoData.level_status == 1">
<text class="iconfont icon-huiyuandengji"></text>
V{{infoData.level_grade}}
</view>
</view>
<view v-if="infoData.phone">{{infoData.phone}}(ID:{{uid}})</view>
<view v-else>ID:{{uid}}</view>
</view>
</view>
<view class="bottom acea-row row-middle">
<view class="item">消费金额<text class="num">{{infoData.order_total_price}}</text></view>
<view class="item">消费笔数<text class="num">{{infoData.order_total_count}}</text></view>
</view>
</view>
<view class="list">
<view class="title acea-row row-between-wrapper">
<view class="name">用户信息</view>
<view class="tip" @click="openTap">{{isShow?'展开':'收起'}}<text class="iconfont" :class="isShow?'icon-ic_downarrow':'icon-ic_uparrow'"></text></view>
</view>
<view class="item acea-row row-between-wrapper">
<view>分组</view>
<view>
<picker @change="bindPickerChange" :value="groupIndex" :range="groupArray" range-key="group_name">
<view class="acea-row row-middle">
<view v-if="groupArray.length">
<text class="not" v-if="groupIndex == -1">无</text>
<text v-else>{{groupArray[groupIndex].group_name}}</text>
</view>
<text class="iconfont icon-ic_rightarrow"></text>
</view>
</picker>
</view>
</view>
<view class="item acea-row row-between-wrapper">
<view>等级</view>
<view>
<picker @change="bindLevelChange" :value="levelIndex" :range="levelArray" range-key="name">
<view class="acea-row row-middle">
<view v-if="levelArray.length">
<text class="not" v-if="levelIndex == -1">无</text>
<text v-else>{{levelArray[levelIndex].name}}</text>
</view>
<text class="iconfont icon-ic_rightarrow"></text>
</view>
</picker>
</view>
</view>
<view class="item">
<view class="acea-row row-between-wrapper">
<view>标签</view>
<view class="add" @click="editLabels"><text class="iconfont icon-ic_increase"></text>添加标签</view>
</view>
<view class="labelList acea-row row-middle" v-if="infoData.label_id && infoData.label_id.length">
<view class="label" v-for="(item,index) in infoData.label_id" :key="index">{{item.label_name}}</view>
</view>
</view>
<view class="listn" v-if="!isShow">
<view class="item acea-row row-between-wrapper" v-if="infoData.real_name">
<view>姓名</view>
<view class="info">{{infoData.real_name}}</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="infoData.birthday">
<view>出生年月</view>
<view class="info">{{infoData.birthday}}</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="infoData.card_id">
<view>身份证号</view>
<view class="info">{{infoData.card_id}}</view>
</view>
<view class="item acea-row row-between" v-if="infoData.addres">
<view>地址</view>
<view class="info">{{infoData.addres}}</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="infoData._add_time">
<view>注册时间</view>
<view class="info">{{infoData._add_time}}</view>
</view>
</view>
</view>
<view class="property">
<view class="title">资产信息</view>
<view class="info acea-row">
<view class="item" @click="integralTap">
<view>积分</view>
<view class="bottom acea-row row-between-wrapper">
<view class="num">{{infoData.integral}}</view>
<view class="iconfont icon-ic_edit"></view>
</view>
</view>
<view class="item" @click="balanceTap">
<view>余额</view>
<view class="bottom acea-row row-between-wrapper">
<view class="num">{{infoData.now_money}}</view>
<view class="iconfont icon-ic_edit"></view>
</view>
</view>
</view>
<view class="info acea-row">
<view class="item">
<view class="acea-row row-between-wrapper">
<view>优惠券</view>
<view class="iconfont icon-ic_rightarrow" @click="couponSeeTap"></view>
</view>
<view class="bottom acea-row row-between-wrapper">
<view class="num">{{infoData.coupon_num}}张</view>
<view class="give" @click="couponTap">赠送</view>
</view>
</view>
<view class="item" @click="memberTap">
<view>会员</view>
<view class="bottom acea-row row-between-wrapper">
<view class="num" v-if="infoData.svip_over_day">{{ '剩余'+infoData.svip_over_day+'天' }}</view>
<view class="num" v-else>已过期/暂未开通</view>
<view class="iconfont icon-ic_edit"></view>
</view>
</view>
</view>
</view>
<edit-lable ref="lable" :visible='visibleLable' @closeDrawer='lableCloseDrawer'></edit-lable>
<edit-balance ref="balance" :visible='visibleBalance' :type = 'type' :uid='parseInt(uid)' @closeDrawer='balanceCloseDrawer' @successChange='successChange'></edit-balance>
<member ref="member" :visible='visibleMember' :userInfo='infoData' @closeDrawer='memberCloseDrawer' @successChange='successChange'></member>
<coupon ref="coupon" :visible='visibleCoupon' :uid='parseInt(uid)' @closeDrawer='couponCloseDrawer'></coupon>
</view>
</template>
<script>
import editLable from './components/userLable/index.vue';
import editBalance from './components/editBalance/index.vue';
import member from './components/member/index.vue';
import coupon from './components/coupon/index.vue';
import {
getUserInfo,
getGroupList,
getLevelList,
postUserUpdate
} from "@/api/admin";
export default {
components: {
editLable,
editBalance,
member,
coupon
},
data() {
return {
getHeight: this.$util.getWXStatusHeight(),
uid: 0,
infoData: {},
groupArray:[],
levelArray:[],
groupIndex:-1,
levelIndex:-1,
visibleLable:false,
visibleBalance:false,
type: 0,
visibleMember:false,
visibleCoupon:false,
isShow:false
}
},
onLoad(options) {
this.uid = options.uid
this.userInfo(1);
},
methods: {
openTap(){
this.isShow = !this.isShow
},
couponTap(){
this.$refs.coupon.userCoupon(0);
this.visibleCoupon = true;
},
couponSeeTap(){
this.$refs.coupon.userCoupon(2);
this.visibleCoupon = true;
},
couponCloseDrawer(e){
this.visibleCoupon = false;
if(e){
this.userInfo();
}
},
memberTap(){
this.visibleMember = true;
},
memberCloseDrawer(){
this.visibleMember = false;
},
balanceTap(){
this.type = 1;
this.visibleBalance = true;
},
integralTap(){
this.type = 0;
this.visibleBalance = true;
},
successChange(){
this.visibleBalance = false
this.visibleMember = false;
this.userInfo();
},
balanceCloseDrawer(){
this.visibleBalance = false
},
lableCloseDrawer(e){
this.visibleLable = false
if(e){
this.userInfo();
}
},
editLabels(){
this.visibleLable = true
this.$refs.lable.productLabel(JSON.parse(JSON.stringify(this.infoData)),0,[]);
},
bindPickerChange(e){
this.groupIndex = e.detail.value
this.userUpdate(4)
},
bindLevelChange(e){
this.levelIndex = e.detail.value
this.userUpdate(1)
},
userUpdate(num){
let data = {}
if(num == 4){
data = {
type:4,
uid:this.uid,
group_id:this.groupArray[this.groupIndex].id
}
}else{
data = {
type:1,
uid:this.uid,
level:this.levelArray[this.levelIndex].id
}
}
postUserUpdate(data).then(res=>{
this.$util.Tips({
title: res.msg
});
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
levelList(){
getLevelList().then(res=>{
let id = this.infoData.level
res.data.list.forEach((item,index)=>{
if(item.id == id){
this.levelIndex = index
}
})
this.levelArray = res.data.list;
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
groupList(){
getGroupList().then(res=>{
let id = this.infoData.group_id
res.data.forEach((item,index)=>{
if(item.id == id){
this.groupIndex = index
}
})
this.groupArray = res.data;
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
goarrow(){
uni.navigateBack()
},
userInfo(num){
getUserInfo(this.uid).then(res=>{
this.infoData = res.data;
if(num){
this.groupList();
this.levelList();
}
}).catch(err=>{
this.$util.Tips({
title: err
});
})
}
}
}
</script>
<style lang="scss" scoped>
.accountTitle{
background: linear-gradient(270deg, $gradient-primary-admin 0%, $primary-admin 100%);
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
.sysTitle{
width: 100%;
position: relative;
font-weight: 500;
color: #fff;
font-size: 30rpx;
.iconfont{
position: absolute;
font-size: 39rpx;
left:11rpx;
width: 60rpx;
font-weight: 600;
}
}
}
.user-details{
padding-bottom: 1rpx;
padding-bottom: calc(1rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
padding-bottom: calc(1rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
.header{
background: linear-gradient(270deg, $gradient-primary-admin 0%, $primary-admin 100%);
height: 346rpx;
padding: 20rpx 30rpx 0 30rpx;
position: relative;
.picTxt{
.pictrue{
width: 112rpx;
height: 112rpx;
image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.text{
margin-left: 32rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: rgba(255, 255, 255, 0.5);
.name{
margin-bottom: 12rpx;
.nameCon{
font-size: 32rpx;
color: #fff;
max-width: 300rpx;
}
.svip{
width: 56rpx;
height: 26rpx;
background: linear-gradient(270deg, #484643 0%, #1F1B17 100%);
border-radius: 14rpx;
font-size: 18rpx;
font-weight: 600;
color: #FDDAA4;
margin-left: 12rpx;
}
.vip{
width: 68rpx;
height: 26rpx;
background: #FEF0D9;
margin-left: 12rpx;
border-radius: 50rpx;
font-size: 18rpx;
font-weight: 500;
color: #DFA541;
.iconfont{
font-size: 20rpx;
margin-right: 4rpx;
}
}
}
}
}
.bottom{
font-size: 26rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: rgba(255, 255, 255, 0.8);
margin-top: 40rpx;
.item{
margin-right: 44rpx;
.num{
margin-left: 8rpx;
color: #FFFFFF;
}
}
}
&::after{
position: absolute;
content: '';
width: 50%;
height: 88rpx;
background: linear-gradient(180deg, $primary-admin 0%, #F5F5F5 100%);
left:0;
bottom: 0;
}
&::before{
position: absolute;
content: '';
width: 50%;
height: 88rpx;
background: linear-gradient(180deg, $gradient-primary-admin 0%, #F5F5F5 100%);
right:0;
bottom: 0;
}
}
.list{
width: 710rpx;
background-color: #fff;
border-radius: 24rpx;
margin: -96rpx auto 0 auto;
position: relative;
font-family: PingFang SC, PingFang SC;
color: #333333;
padding: 32rpx 24rpx 40rpx 24rpx;
.title{
margin-bottom: 40rpx;
.name{
font-size: 30rpx;
font-weight: 600;
}
.tip{
font-size: 26rpx;
font-weight: 400;
color: #999999;
.iconfont {
font-size: 22rpx;
margin-left: 4rpx;
}
}
}
.listn{
margin-top: 52rpx;
}
.item {
font-weight: 400;
&~.item{
margin-top: 52rpx;
}
.not{
color: #999;
}
.iconfont {
font-size: 26rpx;
color: #999;
margin-left: 6rpx;
}
.info{
color: #999999;
width: 465rpx;
text-align: right;
}
.add{
font-size: 24rpx;
color: $primary-admin;
.iconfont {
margin-right: 8rpx;
color: $primary-admin;
}
}
.labelList{
margin-top: 12rpx;
.label{
border: 1px solid $primary-admin;
border-radius: 20rpx;
font-size: 20rpx;
color: $primary-admin;
padding: 4rpx 16rpx;
margin-right: 16rpx;
margin-top: 16rpx;
}
}
}
}
.property{
width: 710rpx;
background-color: #fff;
border-radius: 24rpx;
margin: 20rpx auto;
font-family: PingFang SC, PingFang SC;
.title{
font-size: 30rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #333333;
padding: 32rpx 24rpx 2rpx 24rpx;
margin-bottom: 32rpx;
}
.info{
margin: 0 26rpx;
.item{
width: 50%;
font-size: 28rpx;
font-weight: 400;
color: #999999;
padding: 10rpx 40rpx 40rpx 18rpx;
&~.item{
border-left: 1px solid #EEEEEE;
padding-left: 40rpx;
padding-right: 14rpx;
}
.bottom{
margin-top: 20rpx;
.num{
font-size: 30rpx;
font-weight: 600;
color: #333333;
}
.give{
font-size: 24rpx;
font-weight: 400;
color: $primary-admin;
padding-left: 40rpx;
}
}
.icon-ic_rightarrow{
font-size: 26rpx;
padding: 6rpx 0 6rpx 40rpx;
}
}
&~.info{
border-top: 1px solid #EEEEEE;
.item{
padding-top: 40rpx;
}
}
}
}
}
</style>

678
pages/admin/user/list.vue Normal file
View File

@@ -0,0 +1,678 @@
<template>
<view class="user-list">
<!-- #ifdef MP || APP-PLUS -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>用户管理</view>
<text class="iconfont icon-ic_leftarrow" @click="goarrow"></text>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<!-- #endif -->
<view class="searchCon acea-row row-between-wrapper">
<view class="search acea-row row-middle" :class="administer?'on':''">
<text class="iconfont icon-ic_search"></text>
<input class="inputs" placeholder='请输入用户昵称/ID' placeholder-class='placeholder' confirm-type='search' name="search"
v-model="keyword" @confirm="searchSubmit"></input>
</view>
<view @click="manageTap" v-if="administer">取消</view>
<view class="edit acea-row row-center-wrapper" @click="manageTap" v-else>
<text class="iconfont icon-ic_batch"></text>
</view>
<view class="edit acea-row row-center-wrapper" @click="filterTap" v-if="!administer">
<text class="iconfont icon-ic_sort"></text>
</view>
</view>
<view class="list" v-if="userLists.length">
<checkbox-group @change="checkboxChange">
<view class="acea-row row-middle" v-for="(item, index) in userLists" :key="index">
<!-- #ifndef MP -->
<checkbox class="checkbox" v-if="administer" :value="(item.uid).toString()" :checked="item.checked"
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="#2A7EFB" activeBorderColor="#2A7EFB"/>
<!-- #endif -->
<!-- #ifdef MP -->
<checkbox class="checkbox" v-if="administer" :value="item.uid" :checked="item.checked" color="#ffffff" />
<!-- #endif -->
<view class="item acea-row row-center-wrapper" @click="goDetails(item)">
<view class="pictrue">
<image :src="item.avatar"></image>
</view>
<view class="text">
<view class="top acea-row row-middle">
<view class="name line1">{{item.nickname}}</view>
<view class="svip acea-row row-center-wrapper" v-if="item.isMember == 1">SVIP</view>
<view class="vip acea-row row-center-wrapper" v-if="item.level_status == 1 && item.level_grade">
<text class="iconfont icon-huiyuandengji"></text>
V{{item.level_grade}}
</view>
</view>
<view class="phone">{{item.phone}}</view>
<view class="info acea-row row-middle">
<view>积分:<text>{{item.integral}}</text></view>
<view>余额:<text>{{item.now_money}}</text></view>
</view>
</view>
<view v-if="!administer" class="iconfont icon-ic_more" @click.stop="openDrawer(item)"></view>
</view>
</view>
</checkbox-group>
</view>
<block v-if="userLists.length == 0 && !loading">
<emptyPage title="暂无用户信息~" src="/statics/images/empty-box.gif"></emptyPage>
</block>
<Loading :loaded="loadend" :loading="loading"></Loading>
<view class="footerH"></view>
<view class="footer acea-row row-between-wrapper" v-if="administer">
<checkbox-group @change="checkboxAllChange">
<checkbox value="all" :checked="isAllSelect"
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="#2A7EFB" activeBorderColor="#2A7EFB" />
<text class='checkAll'>全选({{getIds().length}})</text>
</checkbox-group>
<view class="acea-row row-middle">
<view class="bnt acea-row row-center-wrapper">
<picker @change="bindPickerChange" :range="groupArray" range-key="group_name">
<view>修改分组</view>
</picker>
</view>
<view class="bnt acea-row row-center-wrapper" @click="editLabels">添加标签</view>
<view class="bnt acea-row row-center-wrapper" @click="sendCoupon">发送优惠券</view>
</view>
</view>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="edit-list rd-t-40rpx">
<view class="item" v-for="(item, index) in editList" :key="index" @tap="editInfo(index)">
<picker @change="bindLevelChange" :range="levelArray" range-key="name" v-if="index == 2">
<view class="uni-input">{{item.name}}</view>
</picker>
<text v-else>{{item.name}}</text>
</view>
</view>
</base-drawer>
<view style="height: 110rpx;"></view>
<footer-page></footer-page>
<edit-lable ref="lable" :visible='visibleLable' @closeDrawer='lableCloseDrawer'></edit-lable>
<edit-balance ref="balance" :visible='visibleBalance' :type = 'type' :uid='uid' @closeDrawer='balanceCloseDrawer' @successChange='successChange'></edit-balance>
<member ref="member" :visible='visibleMember' :userInfo='userInfo' @closeDrawer='memberCloseDrawer' @successChange='successChange'></member>
<coupon ref="coupon" :visible='visibleCoupon' :uid='uid' @closeDrawer='couponCloseDrawer'></coupon>
<user-filter ref="filter" :visible='visibleFilter' :groupArray='groupArray' :levelArray='levelArray' @closeDrawer='filterCloseDrawer' @successChange='filterChange'></user-filter>
</view>
</template>
<script>
import Loading from '@/components/Loading/index'
import emptyPage from '@/components/emptyPage.vue';
import footerPage from '../components/footerPage/index.vue';
import editLable from './components/userLable/index.vue';
import editBalance from './components/editBalance/index.vue';
import member from './components/member/index.vue';
import coupon from './components/coupon/index.vue';
import userFilter from './components/filter/index.vue';
import {
getUserList,
getGroupList,
postUserUpdate,
getLevelList
} from "@/api/admin";
export default {
components: {
editLable,
editBalance,
member,
coupon,
userFilter,
footerPage,
emptyPage,
Loading
},
data() {
return {
getHeight: this.$util.getWXStatusHeight(),
editList:[
{
name:'修改积分'
},
{
name:'修改余额'
},
{
name:'修改等级'
},
{
name:'赠送会员'
},
{
name:'赠送优惠券'
},
],
administer:0,
isAllSelect: false,
userLists:[],
visible:false,
visibleLable:false, //标签是否显示
loadTitle: '加载更多',
loading: false,
loadend: false,
limit: 20,
page: 1,
keyword:'', //搜索字段
visibleBalance: false,
type: 0,
visibleMember:false,
visibleCoupon:false,
uid: 0,
groupArray:[],
userInfo:{},
levelArray:[],
visibleFilter:false,
filterData:{
labelIds:'',
groupIds:0,
levelIds:0
}
}
},
onShow() {
},
onLoad() {
this.userList();
this.groupList();
},
methods: {
goarrow(){
uni.navigateBack()
},
filterChange(data){
this.visibleFilter = false
this.filterData = data
this.init();
},
filterCloseDrawer(){
this.visibleFilter = false
},
filterTap(){
this.visibleFilter = true;
this.$refs.filter.productLabel();
this.levelList();
// this.groupList();
},
sendCoupon(){
if(!this.getIds().length){
this.$util.Tips({
title: '请选择商品'
});
return
}
this.visibleCoupon = true;
this.$refs.coupon.userCoupon(1,this.getIds());
},
levelList(){
getLevelList().then(res=>{
this.levelArray = res.data.list;
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
groupList(){
getGroupList().then(res=>{
this.groupArray = res.data;
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
userUpdate(data){
postUserUpdate(data).then(res=>{
this.$util.Tips({
title: res.msg
});
}).catch(err=>{
this.$util.Tips({
title: err
});
})
},
bindLevelChange(e){
this.userUpdate({
type:1,
uid:this.uid,
level:this.levelArray[e.detail.value].id
})
this.init();
},
bindPickerChange(e){
if(!this.getIds().length){
this.$util.Tips({
title: '请选择商品'
});
return
}
this.userUpdate({
type:4,
uid:this.getIds(),
group_id:this.groupArray[e.detail.value].id
})
},
goDetails(item){
uni.navigateTo({
url: '/pages/admin/user/index?uid='+item.uid
})
},
couponCloseDrawer(){
this.visibleCoupon = false
},
memberCloseDrawer(){
this.visibleMember = false
},
balanceCloseDrawer(){
this.visibleBalance = false
},
successChange(){
this.visibleMember = false
this.visibleBalance = false
this.init();
},
//批量编辑标签
editLabels(){
if(!this.getIds().length){
this.$util.Tips({
title: '请选择商品'
});
return
}
this.visibleLable = true
this.visible = false
this.$refs.lable.productLabel({},1,this.getIds());
},
//批量获取id集合
getIds(){
let ids = []
this.userLists.forEach(item=>{
if(item.checked){
ids.push(item.uid)
}
})
ids.slice(0, 100)
return ids
},
init(){
this.userLists = [];
this.page = 1;
this.loadend = false;
this.loading = false;
this.userList();
},
searchSubmit(){
this.init();
},
userList(){
let that = this;
if (this.loading) return;
if (this.loadend) return;
that.loading = true;
that.loadTitle = "";
getUserList({
page: that.page,
limit: that.limit,
nickname: that.keyword,
group_id: that.filterData.groupIds,
level: that.filterData.levelIds,
label_id: that.filterData.labelIds
}).then(res=>{
let userLists = res.data.list;
userLists.forEach(item => {
item.checked = false;
})
this.isAllSelect = false
let loadend = userLists.length < that.limit;
that.userLists = that.$util.SplitArray(userLists, that.userLists);
that.$set(that, 'userLists', that.userLists);
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
that.loadTitle = "加载更多";
})
},
editInfo(index){
switch (index) {
case 0:
this.visible = false
this.visibleBalance = true
this.type = 0
break;
case 1:
this.visible = false
this.visibleBalance = true
this.type = 1
break;
case 2:
this.visible = false
break;
case 3:
this.visible = false
this.visibleMember = true
break;
case 4:
this.visible = false
this.visibleCoupon = true
break;
}
},
lableCloseDrawer(){
this.visibleLable = false
},
openDrawer(item){
this.visible = true
this.uid = item.uid
this.userInfo = item;
this.levelList();
this.$refs.coupon.userCoupon(0);
},
closeDrawer(){
this.visible = false
},
manageTap() {
this.administer = !this.administer;
},
checkboxChange(event) {
let idList = event.detail.value;
this.userLists.forEach((item) => {
if (idList.indexOf(item.uid + '') !== -1) {
item.checked = true;
} else {
item.checked = false;
}
})
if (idList.length == this.userLists.length) {
this.isAllSelect = true;
} else {
this.isAllSelect = false;
}
},
forGoods(val) {
let that = this;
if (!that.userLists.length) return
that.userLists.forEach((item) => {
if (val) {
item.checked = true;
} else {
item.checked = false;
}
})
},
checkboxAllChange(event) {
let value = event.detail.value;
if (value.length) {
if(this.userLists.length>100){
this.$util.Tips({
title: '每次最多只提交100条数据'
});
}
this.isAllSelect = true;
this.forGoods(1)
} else {
this.isAllSelect = false;
this.forGoods(0)
}
},
},
onReachBottom(){
this.userList();
}
}
</script>
<style lang="scss" scoped>
/deep/checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: 1px solid $primary-admin !important;
background-color: $primary-admin !important;
}
/deep/checkbox:not([disabled]) .uni-checkbox-input:hover {
border-color: #d1d1d1 !important;
}
/deep/.empty-page{
margin-top: 20rpx;
}
.accountTitle{
background: #F5F5F5;
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
padding-bottom: 6rpx;
.sysTitle{
width: 100%;
position: relative;
font-weight: 500;
color: #333333;
font-size: 30rpx;
.iconfont{
position: absolute;
font-size: 42rpx;
left:20rpx;
width: 60rpx;
font-weight: 500;
}
}
}
.user-list{
padding: 20rpx 20rpx 0 20rpx;
.searchCon{
.search{
width: 526rpx;
height: 72rpx;
background: #FFFFFF;
border-radius: 50rpx;
padding: 0 34rpx;
&.on{
width: 618rpx;
}
.iconfont{
color: #999;
font-size: 32rpx;
margin-right: 16rpx;
}
.inputs{
font-size: 28rpx;
width: 100%;
height: 100%;
flex: 1;
}
.placeholder{
color: #ccc;
}
}
.edit{
width: 72rpx;
height: 72rpx;
background: #FFFFFF;
border-radius: 50%;
.iconfont {
color: #666;
font-size: 36rpx;
}
}
}
.list{
padding-bottom: 20rpx;
margin-top: 32rpx;
/deep/uni-checkbox .uni-checkbox-input{
margin: 0 20rpx 20rpx 0;
}
/deep/wx-checkbox .wx-checkbox-input{
margin: 0 20rpx 20rpx 0;
}
.item {
width: 100%;
background-color: #fff;
padding: 30rpx 24rpx;
box-sizing: border-box;
margin-bottom: 20rpx;
border-radius: 24rpx;
position: relative;
flex: 1;
.icon-ic_more{
position: absolute;
right: 20rpx;
top: 30rpx;
color: #999;
font-size: 40rpx;
}
.pictrue{
width: 96rpx;
height: 96rpx;
margin-right: 24rpx;
image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.text{
flex: 1;
overflow: hidden;
.top{
.name {
max-width: 230rpx;
font-size: 28rpx;
font-weight: 600;
color: #333333;
font-family: PingFang SC, PingFang SC;
}
.svip {
width: 56rpx;
height: 26rpx;
background: linear-gradient(270deg, #484643 0%, #1F1B17 100%);
border-radius: 100rpx;
font-size: 18rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #FDDAA4;
margin-left: 10rpx;
}
.vip{
width: 64rpx;
// height: 26rpx;
background: #FEF0D9;
border: 1px solid #FACC7D;
border-radius: 50rpx;
font-size: 18rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #DFA541;
margin-left: 10rpx;
.iconfont {
font-size: 20rpx;
margin-right: 4rpx;
}
}
}
.phone{
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #999999;
margin-top: 4rpx;
}
.info {
font-size: 24rpx;
font-weight: 400;
color: #999999;
margin-top: 4rpx;
text {
color: #333333;
margin-right: 28rpx;
}
}
}
.bottom{
margin-top: 26rpx;
.bnt{
width: 144rpx;
height: 56rpx;
border:1px solid #ccc;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
border-radius: 50rpx;
&~.bnt{
margin-left: 16rpx;
}
&.on{
border-color: #2A7EFB;
background-color: #2A7EFB;
color: #fff;
}
&.up{
border-color: #FF7E00;
color: #FF7E00;
}
}
}
}
}
.footerH {
height: calc(constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
}
.footer {
box-sizing: border-box;
padding: 0 32rpx;
width: 100%;
height: 96rpx;
background-color: #fff;
position: fixed;
bottom: 0;
z-index: 30;
height: calc(96rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(96rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
width: 100%;
left: 0;
/deep/uni-checkbox .uni-checkbox-input{
margin-bottom: 6rpx;
}
.bnt {
width: 160rpx;
height: 64rpx;
border-radius: 50rpx;
border: 1rpx solid #2A7EFB;
color: #2A7EFB;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
&~.bnt{
margin-left: 16rpx;
}
}
}
.edit-list{
background-color: #fff;
padding: 45rpx 34rpx;
.item{
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
font-size: 32rpx;
text-align: center;
height: 106rpx;
line-height: 106rpx;
}
}
}
</style>

419
pages/admin/work/index.vue Normal file
View File

@@ -0,0 +1,419 @@
<template>
<view class="pagebox">
<!-- #ifdef MP || APP-PLUS -->
<NavBar titleText="工作台" :iconColor="iconColor" :textColor="iconColor" :isScrolling="isScrolling" showBack></NavBar>
<!-- #endif -->
<view class="headerBg">
<view :style="{ height: `${getHeight.barTop}px` }"></view>
<view :style="{ height: `${getHeight.barHeight}px` }"></view>
<view class="inner"></view>
</view>
<view class="page-content">
<view class="header acea-row row-middle">
<image :src="avatar" class="avatar"></image>
<view class="text-box">
<view class="flex-y-center">
<text class="fs-32 fw-500 lh-44rpx pr-16">{{ nickname }}</text>
<view class="h-42 flex-center fs-22 text--w111-fff pl-16 pr-14 rd-30rpx b-f"
@tap="checkIdentity" v-show="identity == 2">切换商城
<text class="iconfont icon-ic_rightarrow fs-22"></text>
</view>
</view>
<view class="pt-4 fs-22 lh-30rpx">{{ phone }}</view>
</view>
<!-- #ifdef MP-WEIXIN || APP-PLUS -->
<navigator url="/pages/admin/order_cancellation/index" hover-class="none">
<text class="iconfont icon-ic_Scan fs-40 text--w111-fff"></text>
</navigator>
<!-- #endif -->
</view>
<view class="today">
<view class="title-box">
<navigator class="link" url="/pages/admin/order/index" hover-class="none">
今日销售额(元)<text class="iconfont icon-ic_rightarrow"></text>
</navigator>
<view class="money">{{ after_price }}</view>
</view>
<view class="acea-row">
<view class="item">
<view class="num">{{ after_number }}</view>
<view class="">今日订单数</view>
</view>
<view class="item">
<view class="num">{{ after_pay_number }}</view>
<view class="">今日支付人数</view>
</view>
<view class="item">
<view class="num">{{ today_visits }}</view>
<view class="">今日浏览量</view>
</view>
</view>
</view>
<view class="goods grid-column-4 rd-24rpx bg--w111-fff mt-20">
<navigator url="/pages/admin/orderList/index?types=1" hover-class="none" class="w-full flex-col flex-center pt-28 pb-26rpx fs-26">
<view class="img-box">
<view class="img">
<view v-if="unshipped_count" class="num">{{ unshipped_count > 99 ? '99+' : unshipped_count }}</view>
<image :src="imgHost+'/statics/images/admin-work-order1.png'" mode=""></image>
</view>
</view>
<view class="pt-12">待发货</view>
</navigator>
<navigator url="/pages/admin/refundOrderList/index" hover-class="none" class="w-full flex-col flex-center pt-28 pb-26rpx fs-26">
<view class="img-box">
<view class="img">
<view v-if="refunding_count" class="num">{{ refunding_count > 99 ? '99+' : refunding_count }}</view>
<image :src="imgHost+'/statics/images/admin-work-order2.png'" mode=""></image>
</view>
</view>
<view class="pt-12">待售后</view>
</navigator>
<navigator url="/pages/admin/goods/index?type=4" hover-class="none" class="w-full flex-col flex-center pt-28 pb-26rpx fs-26">
<view class="img-box">
<view class="img">
<view v-if="outofstock" class="num">{{ outofstock > 99 ? '99+' : outofstock }}</view>
<image :src="imgHost+'/statics/images/admin-work-order3.png'" mode=""></image>
</view>
</view>
<view class="pt-12">待补货</view>
</navigator>
<navigator url="/pages/admin/goods/index?type=5" hover-class="none" class="w-full flex-col flex-center pt-28 pb-26rpx fs-26">
<view class="img-box">
<view class="img">
<view v-if="policeforce" class="num">{{ policeforce > 99 ? '99+' : policeforce }}</view>
<image :src="imgHost+'/statics/images/admin-work-order4.png'" mode=""></image>
</view>
</view>
<view class="pt-12">库存预警</view>
</navigator>
</view>
<view class="pt-34 pb-40 rd-24rpx mt-20 bg--w111-fff">
<view class="pl-28 fs-30 fw-500 lh-44rpx">店铺管理</view>
<view class="grid-column-4">
<navigator class="w-full py-24 flex-col flex-center" url="/pages/admin/goods/index" hover-class="none">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu1.png'" mode=""></image>
<view class="pt-20">商品管理</view>
</navigator>
<navigator class="w-full py-24 flex-col flex-center" url="/pages/admin/orderList/index" hover-class="none">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu2.png'" mode=""></image>
<view class="pt-20">订单管理</view>
</navigator>
<!-- #ifdef MP-WEIXIN || APP-PLUS -->
<navigator class="w-full py-24 flex-col flex-center" url="/pages/admin/order_cancellation/index" hover-class="none">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu3.png'" mode=""></image>
<view class="pt-20">扫码核销</view>
</navigator>
<!-- #endif -->
<navigator class="w-full py-24 flex-col flex-center" url="/pages/admin/refundOrderList/index" hover-class="none">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu4.png'" mode=""></image>
<view class="pt-20">售后维权</view>
</navigator>
<navigator class="w-full py-24 flex-col flex-center" url="/pages/admin/user/list" hover-class="none">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu5.png'" mode=""></image>
<view class="pt-20">用户管理</view>
</navigator>
<navigator class="w-full py-24 flex-col flex-center" url="/pages/behalf/user_list/index" hover-class="none">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu6.png'" mode=""></image>
<view class="pt-20">代客下单</view>
</navigator>
<view class="w-full py-24 flex-col flex-center" @tap="toChat">
<image class="w-48 h-48" src="../static/footer5-1.png" mode=""></image>
<view class="pt-20">客服聊天</view>
</view>
<!-- #ifdef MP-WEIXIN || APP-PLUS -->
<view class="w-full py-24 flex-col flex-center" @tap="toGoods">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu3.png'" mode=""></image>
<view class="pt-20">扫描商品</view>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="w-full py-24 flex-col flex-center" v-if="isWechat" @tap="toGoods">
<image class="w-48 h-48" :src="imgHost+'/statics/images/admin-work-menu3.png'" mode=""></image>
<view class="pt-20">扫描商品</view>
</view>
<!-- #endif -->
</view>
</view>
</view>
<footerPage></footerPage>
</view>
</template>
<script>
// #ifdef MP || APP-PLUS
import NavBar from '@/components/NavBar.vue';
// #endif
import footerPage from '../components/footerPage/index.vue';
import { HTTP_REQUEST_URL } from '@/config/app';
import {
deliveryInfo,
getOrderStaging,
getOrderTime,
} from '@/api/admin.js';
import { getUserInfo, checkIdentityApi } from '@/api/user.js';
export default {
components: {
// #ifdef MP || APP-PLUS
NavBar,
// #endif
footerPage,
},
data() {
return {
imgHost: HTTP_REQUEST_URL,
// #ifdef MP || APP-PLUS
iconColor: '#FFFFFF',
isScrolling: false,
// #endif
avatar: '',
nickname: '',
phone: '',
outofstock: 0, // 待补货
policeforce: 0, // 库存预警
unshipped_count: 0, // 待发货
refunding_count: 0, // 待售后
after_price: 0, // 今日销售额
after_number: 0, // 今日订单数
after_pay_number: 0, // 今日支付人数
today_visits: 0, // 今日浏览量
getHeight: this.$util.getWXStatusHeight(),
identity: 0,
// #ifdef H5
isWechat: this.$wechat.isWeixin(),
// #endif
}
},
onLoad() {
console.log(this.imgHost,'host');
this.getUserInfo();
this.getOrderTime();
this.getOrderStaging();
},
methods: {
getUserInfo() {
getUserInfo().then(res => {
const {
avatar,
nickname,
phone,
} = res.data;
this.avatar = avatar;
this.nickname = nickname;
this.phone = phone;
this.identity = res.data.identity;
this.$store.commit('UPDATE_USERINFO', res.data);
});
},
getOrderTime() {
getOrderTime({
type: 1,
}).then(res => {
const {
after_number,
after_pay_number,
after_price,
today_visits,
} = res.data;
this.after_number = after_number;
this.after_pay_number = after_pay_number;
this.after_price = after_price;
this.today_visits = today_visits;
});
},
getOrderStaging() {
getOrderStaging().then(res => {
const {
outofstock,
policeforce,
unshipped_count,
refunding_count,
} = res.data;
this.outofstock = outofstock;
this.policeforce = policeforce;
this.unshipped_count = Number(unshipped_count);
this.refunding_count = Number(refunding_count);
});
},
checkIdentity(){
checkIdentityApi({identity: 0}).then(res=>{
getUserInfo().then((res) => {
this.$store.commit('UPDATE_USERINFO', res.data);
uni.switchTab({
url: '/pages/index/index'
})
});
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
toChat(){
// #ifdef H5
this.$util.JumpPath(`${HTTP_REQUEST_URL}/kefu`);
// #endif
// #ifdef MP-WEIXIN
uni.navigateTo({
url: `/pages/annex/web_view/index?url=${HTTP_REQUEST_URL}/kefu`
});
// #endif
},
toGoods(){
var self = this;
// #ifdef MP || APP
uni.scanCode({
scanType: ['barCode'],
success(res) {
uni.navigateTo({
url: `/pages/admin/goods/index?keyword=${res.result}`
});
},
fail(res) {
console.log(res);
}
})
// #endif
//#ifdef H5
this.$wechat.wechatEvevt('scanQRCode', {
needResult: 1,
scanType: ["barCode"]
}).then(res => {
let result = res.resultStr;
uni.navigateTo({
url: `/pages/admin/goods/index?keyword=${result}`
});
});
//#endif
}
},
}
</script>
<style lang="scss" scoped>
.pagebox {
position: relative;
overflow: hidden;
}
.headerBg {
position: absolute;
top: 0;
left: -25%;
width: 150%;
border-bottom-right-radius: 100%;
border-bottom-left-radius: 100%;
background: linear-gradient(270deg, $gradient-primary-admin 0%, $primary-admin 100%);
.inner {
height: 356rpx;
}
}
.page-content {
position: relative;
padding: 0 20rpx;
.header {
padding: 22rpx 20rpx 32rpx 12rpx;
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.text-box {
flex: 1;
padding-left: 16rpx;
color: #FFFFFF;
}
}
.today {
border-radius: 24rpx;
background: #FFFFFF;
.title-box {
padding: 40rpx 0 0 40rpx;
}
.link {
display: inline-block;
vertical-align: middle;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.iconfont {
margin-left: 4rpx;
font-size: 24rpx;
}
.money {
margin-top: 16rpx;
font-family: SemiBold;
font-size: 56rpx;
line-height: 56rpx;
color: #FF7E00;
}
.item {
flex: 1;
padding: 54rpx 0 38rpx;
text-align: center;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.num {
margin-bottom: 12rpx;
font-family: SemiBold;
font-size: 36rpx;
line-height: 36rpx;
color: #333333;
}
}
.goods {
.img-box {
position: relative;
width: 76rpx;
height: 76rpx;
border-radius: 50%;
margin: 0 auto 12rpx;
}
.img {
width: 100%;
height: 100%;
}
.num {
position: absolute;
top: -6rpx;
left: 58rpx;
z-index: 2;
min-width: 24rpx;
height: 24rpx;
padding: 0 8rpx;
border-radius: 12rpx;
background: #FF7E00;
font-weight: 500;
font-size: 18rpx;
line-height: 24rpx;
color: #FFFFFF;
}
image {
width: 100%;
height: 100%;
}
}
}
.b-f{
border: 1rpx solid #fff;
}
</style>

View File

@@ -0,0 +1,363 @@
<template>
<view class="container">
<view class="goods-box" v-if="list.cart_info">
<view class="header">订单号:{{ list.order_id }}</view>
<view class='item acea-row' v-for="(item,index) in list.cart_info" :key="index">
<view class='pictrue'>
<image :src="item.cart_info.productInfo.attrInfo.image" mode=""></image>
</view>
<view class='text acea-row row-column row-between'>
<view class="title line2">{{ item.cart_info.productInfo.store_name }}</view>
<view class='money acea-row row-between row-middle'>
<view class="orangcol">
已核销:<text>{{item.write_times - item.surplus_num}}</text>/{{item.write_times}}
</view>
<view v-if="item.is_writeoff == 1" class="txt acea-row row-middle">
核销已完成
</view>
<view v-else class="txt acea-row row-middle">
本次核销:
<view class='carnum acea-row row-center-wrapper'>
<view v-if="item.surplus_num_input == 1" class="reduce bggary">
<text class="iconfont icon-ic_Reduce"></text>
</view>
<view v-else class="reduce" @click.stop='subCart(item,index)'>
<text class="iconfont icon-ic_Reduce"></text>
</view>
<!-- <view class='nums'>{{item.surplus_num_input}}</view> -->
<input v-model="item.surplus_num_input" class='nums' type="number" @input="numInput" @blur="numBlur" />
<view v-if="item.surplus_num_input == item.surplus_num" class="plus bggary">
<text class="iconfont icon-ic_increase"></text>
</view>
<view v-else class="plus" @click.stop='addCart(item,index)'>
<text class="iconfont icon-ic_increase"></text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="record-box" v-if="recordList.length">
<view class="header">核销记录</view>
<view class="list">
<view class="item acea-row row-middle row-between" v-for="(item, index) in recordList" :key="index">
<view class="left">{{ item.add_time }}</view>
<view class="right">核销{{item.writeoff_num}}次</view>
</view>
</view>
</view>
<view class="footer acea-row row-middle row-between">
<navigator class="btn" url="/pages/admin/work/index" hover-class="none">返回工作台</navigator>
<view v-if="list.cart_info && list.cart_info[0].surplus_num" class="btn" @click="verification">确认核销</view>
</view>
</view>
</template>
<script>
import {
orderWriteoffInfo,
orderVerific,
orderCartInfo,
orderWriteoff,
orderWirteOffRecords,
} from '@/api/admin'
export default {
data() {
return {
list: {},
recordList: [],
lists: {},
checkModel: [],
nums: [],
auth: 1,
id: 0,
}
},
watch: {
checkModel() {
if (this.lengt == this.checkModel.length) {
this.checked = true;
} else {
this.checked = false;
}
}
},
onLoad(option) {
this.auth = option.auth || 1;
this.id = option.id;
this.getCartList()
this.orderWirteOffRecords()
},
methods: {
numInput(event) {
let value = event.detail.value;
if (value) {
value = Number(value);
this.$nextTick(() => {
if (value > this.list.cart_info[0].surplus_num) {
this.list.cart_info[0].surplus_num_input = this.list.cart_info[0].surplus_num;
} else if (value < 1) {
this.list.cart_info[0].surplus_num_input = 1;
}
});
}
},
numBlur(event) {
let value = event.detail.value;
if (!value) {
this.$nextTick(() => {
this.list.cart_info[0].surplus_num_input = 1;
});
}
},
orderWirteOffRecords() {
orderWirteOffRecords(this.id, {
product_type: 4
}).then(res => {
this.recordList = res.data.list;
});
},
num() {
for (let index = 0; index < this.lists.cart_info.length; index++) {
this.nums.push({
num: 0
});
}
},
getCartList: function() {
orderCartInfo({
oid: this.id,
auth: this.auth,
}).then(res => {
let list = res.data;
for (let i = 0; i < list.cart_info.length; i++) {
list.cart_info[i].surplus_num_input = 1
}
this.list = res.data
this.lists = JSON.parse(JSON.stringify(res.data))
this.listlet = res.data.cart_info.length
this.$set(this.attr, 'id', this.list.id);
this.num()
}).catch(res => {
this.$util.Tips({
title: res
});
});
},
subCart(item, index) {
this.list.cart_info[index].surplus_num_input--;
},
addCart(item, index) {
this.list.cart_info[index].surplus_num_input++;
},
verification() {
let that = this;
let cart_ids = [];
for (let i = 0; i < this.list.cart_info.length; i++) {
cart_ids.push({
cart_id: this.list.cart_info[i].cart_id,
cart_num: this.list.cart_info[i].surplus_num_input,
});
}
orderWriteoff({
auth: this.auth,
oid: this.id,
cart_ids: cart_ids
}).then(res => {
// uni.hideLoading();
this.$util.Tips({
title: res.msg
}, () => {
this.orderWirteOffRecords();
});
this.list.cart_info[0].surplus_num = this.list.cart_info[0].surplus_num - this.list.cart_info[0].surplus_num_input;
// that.getCartList();
}).catch(err => {
this.$util.Tips({
title: err
});
// uni.hideLoading();
});
}
},
}
</script>
<style lang="scss" scoped>
.container {
padding: 22rpx 20rpx;
}
.goods-box {
padding: 32rpx 24rpx;
border-radius: 24rpx;
background: #FFFFFF;
.header {
margin-bottom: 26rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.pictrue {
width: 136rpx;
height: 136rpx;
border-radius: 16rpx;
}
image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.text {
flex: 1;
padding-left: 20rpx;
}
.title {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.orangcol {
font-size: 24rpx;
line-height: 34rpx;
color: #666666;
text {
color: #2A7EFB;
}
}
.txt {
font-size: 24rpx;
line-height: 34rpx;
color: #666666;
}
.reduce {
width: 32rpx;
height: 36rpx;
text-align: left;
line-height: 36rpx;
.iconfont {
font-size: 24rpx;
color: #333333;
}
&.bggary {
.iconfont {
color: #CCCCCC;
}
}
}
.plus {
width: 32rpx;
height: 36rpx;
text-align: right;
line-height: 36rpx;
.iconfont {
font-size: 24rpx;
color: #333333;
}
&.bggary {
.iconfont {
color: #CCCCCC;
}
}
}
.nums {
width: 72rpx;
height: 36rpx;
border-radius: 4rpx;
background: #F5F5F5;
text-align: center;
font-family: SemiBold;
font-weight: 600;
font-size: 24rpx;
line-height: 36rpx;
color: #333333;
}
.iconfont {
font-size: 24rpx;
}
}
.record-box {
padding-bottom: 30rpx;
border-radius: 24rpx;
margin-top: 20rpx;
background: #FFFFFF;
.header {
padding: 32rpx 0 16rpx 24rpx;
font-weight: 500;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
}
.list {
padding: 0 40rpx;
}
.item {
height: 88rpx;
border-bottom: 1rpx solid #F1F1F1;
font-size: 28rpx;
color: #333333;
.right {
color: #666666;
}
}
}
.footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 112rpx;
height: calc(112rpx + constant(safe-area-inset-bottom));
height: calc(112rpx + env(safe-area-inset-bottom));
padding: 0 20rpx;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
background: #FFFFFF;
.btn {
flex: 1;
height: 72rpx;
border: 2rpx solid #2A7EFB;
border-radius: 36rpx;
margin-right: 16rpx;
text-align: center;
font-weight: 500;
font-size: 26rpx;
line-height: 68rpx;
color: #2A7EFB;
&:last-child {
margin-right: 0;
background: #2A7EFB;
color: #FFFFFF;
}
}
}
.item ~ .item{
margin-top: 40rpx;
}
</style>

View File

@@ -0,0 +1,90 @@
<template>
<view class="px-20 mt-24">
<view class="px-24 rd-24rpx bg--w111-fff" v-for="(panel, i) in records" :key="i">
<view class="h-104 fs-24 flex-y-center b-border">核销时间:{{ panel.time }}</view>
<view class="py-32">
<view class="item flex" v-for="item in panel.list" :key="item.id">
<image :src="item.cartInfo.productInfo.attrInfo?item.cartInfo.productInfo.attrInfo.image:item.cartInfo.productInfo.image" class="w-136 h-136 rd-16rpx"></image>
<view class="flex-1 flex-col flex-between-center ml-20">
<view class="w-full line2 fs-28 lh-40rpx">{{ item.cartInfo.productInfo.store_name }}</view>
<view class="w-full flex-between-center">
<BaseMoney :money="item.cartInfo.productInfo.price" symbolSize="20" integerSize="32" decimalSize="20"></BaseMoney>
<view class="fs-24 text--w111-999">核销{{ item.writeoff_num }}件</view>
</view>
</view>
</view>
</view>
</view>
<emptyPage v-if="!records.length && page" title="暂无核销记录~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</template>
<script>
import {orderWirteOffRecords} from '@/api/admin'
import emptyPage from '@/components/emptyPage.vue'
export default {
components: {
emptyPage
},
data() {
return {
id: '',
page: 1,
limit: 10,
list: [],
records: [],
loadend: false,
loading: false,
}
},
onLoad(option) {
this.id = option.id;
this.orderWirteOffRecords();
},
methods: {
orderWirteOffRecords() {
if (this.loadend || this.loading) {
return;
}
this.loading = true;
orderWirteOffRecords(this.id, {
product_type: 0,
page: this.page,
limit: this.limit,
}).then(res => {
const list = res.data.list;
let records = [];
this.list = this.list.concat(list);
for (let i = 0; i < this.list.length; i++) {
records.push({
time: this.list[i].time,
list: [this.list[i]],
});
for (let j = i + 1; j < this.list.length; j++) {
if (this.list[i].time == this.list[j].time) {
records[records.length - 1].list.push(this.list[j]);
this.list.splice(j, 1);
j--;
}
}
}
this.records = records;
this.loadend = list.length < this.limit;
this.page = this.page + 1;
this.loading = false;
}).catch(err => {
this.loading = false;
});
},
},
}
</script>
<style lang="scss" scoped>
.b-border{
border-bottom: 1rpx solid #EEEEEE;
}
.item ~ .item{
margin-top: 40rpx;
}
</style>

View File

@@ -0,0 +1,204 @@
<template>
<!-- 日期组件 -->
<view>
<view class="dataList">
<view class="times">
<view class="item" :class="time == 'all' ? 'on' : ''" @click="setTime('all')">全部</view>
<view class="item" :class="time == 'today' ? 'on' : ''" @click="setTime('today')">今日</view>
<view class="item" :class="time == 'yesterday' ? 'on' : ''" @click="setTime('yesterday')">昨日</view>
<view class="item" :class="time == 'seven' ? 'on' : ''" @click="setTime('seven')">近7日</view>
</view>
<view class="item" :class="time == 'date' ? 'on' : ''" @click="dateTitle">自定义时间 <text
class="iconfont icon-ic_downarrow downarrow"></text></view>
</view>
<uni-calendar ref="calendar" :date="info.date" :insert="info.insert" :lunar="info.lunar"
:startDate="info.startDate" :endDate="info.endDate" :range="info.range" @confirm="confirm"
:showMonth="info.showMonth" />
<view class="mask" @touchmove.prevent v-show="current === true" @click="close"></view>
<Loading :loaded="loaded" :loading="loading"></Loading>
</view>
</template>
<script>
import Loading from '@/components/Loading/index.vue'
import uniCalendar from '../uni-calendar/uni-calendar.vue'
const year = new Date().getFullYear();
const month = new Date().getMonth() + 1;
const day = new Date().getDate();
export default {
components: {
uniCalendar,
Loading
},
data() {
return {
time:'all',
current: false,
loaded: false,
loading: false,
info: {
startDate: '',
endDate: '',
lunar: false,
range: true,
insert: false,
selected: [],
showMonth: false
},
where: {
start: "",
stop: "",
},
}
},
methods: {
close() {
this.current = false;
},
// 日历确定
confirm(e) {
let self = this
let star, stop;
if (e.range.after && e.range.before) {
if (e.range.before > e.range.after) {
star = new Date(e.range.after + ' 00:00:00').getTime() / 1000
stop = new Date(e.range.before + ' 23:59:59').getTime() / 1000
} else {
star = new Date(e.range.before + ' 00:00:00').getTime() / 1000
stop = new Date(e.range.after + ' 23:59:59').getTime() / 1000
}
self.where.start = star
self.where.stop = stop
self.loaded = false;
self.loading = false;
// Promise.all();
this.$emit('changeTime', this.where)
}else{
star = new Date(e.fulldate + ' 00:00:00').getTime() / 1000
stop = new Date(e.fulldate + ' 23:59:59').getTime() / 1000
self.where.start = star
self.where.stop = stop
self.loaded = false;
self.loading = false;
this.$emit('changeTime', this.where)
}
},
dateTitle() {
this.$refs.calendar.open()
this.time = 'date'
},
setTime(time) {
let self = this
this.time = time;
var year = new Date().getFullYear(),
month = new Date().getMonth() + 1,
day = new Date().getDate();
this.tip = 1
this.loaded = false;
this.loading = false;
switch (time) {
case "all":
this.where.start = 0
this.where.stop = 0
this.title = "全部";
this.$emit('changeTime', this.where)
break;
case "today":
this.where.start =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000;
this.where.stop =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
1;
this.title = "今日";
this.$emit('changeTime', this.where)
break;
case "yesterday":
this.where.start =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 -
24 * 60 * 60;
this.where.stop =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 -
1;
this.title = "昨日";
this.$emit('changeTime', this.where)
break;
case "month":
this.where.start =
new Date(year, new Date().getMonth(), 1).getTime() / 1000;
this.where.stop = new Date(year, month, 1).getTime() / 1000 - 1;
this.title = "本月";
this.$emit('changeTime', this.where)
break;
case "seven":
this.where.start =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
7 * 3600 * 24;
this.where.stop =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
1;
this.title = "七日";
this.$emit('changeTime', this.where)
break;
// #ifdef MP
case "date":
let star = new Date(self.before).getTime() / 1000
let stop = new Date(self.after).getTime() / 1000
self.where.start = star
self.where.stop = stop
Promise.all([self.getList()]);
this.$emit('changeTime', this.where)
break;
// #endif
}
},
}
}
</script>
<style lang="scss" scoped>
.dataList {
display: flex;
justify-content: space-between;
padding: 24rpx 20rpx;
background-color: #fff;
color: #999;
font-size: 24rpx;
width: 100%;
box-sizing: border-box;
.times {
display: flex;
.item {
margin-right: 20rpx;
background: #F5F5F5;
padding: 8rpx 24rpx;
border-radius: 30rpx;
}
.item.on {
color: #E93323;
background-color: #FCEAE9;
}
}
.item{
padding: 10rpx 0rpx;
}
}
.downarrow {
padding-left: 10rpx;
font-size: 26rpx !important;
}
</style>

View File

@@ -0,0 +1,546 @@
/**
* @1900-2100区间内的公历、农历互转
* @charset UTF-8
* @github https://github.com/jjonline/calendar.js
* @Author Jea杨(JJonline@JJonline.Cn)
* @Time 2014-7-21
* @Time 2016-8-13 Fixed 2033hex、Attribution Annals
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
* @Version 1.0.3
* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
/* eslint-disable */
var calendar = {
/**
* 农历1900-2100的润大小信息表
* @Array Of Property
* @return Hex
*/
lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
/** Add By JJonline@JJonline.Cn**/
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
0x0d520], // 2100
/**
* 公历每个月份的天数普通表
* @Array Of Property
* @return Number
*/
solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
/**
* 天干地支之天干速查表
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
* @return Cn string
*/
Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
/**
* 天干地支之地支速查表
* @Array Of Property
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
* @return Cn string
*/
Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
/**
* 天干地支之地支速查表<=>生肖
* @Array Of Property
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
* @return Cn string
*/
Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
/**
* 24节气速查表
* @Array Of Property
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
* @return Cn string
*/
solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
/**
* 1900-2100各年的24节气日期速查表
* @Array Of Property
* @return 0x string For splice
*/
sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
/**
* 数字转中文速查表
* @Array Of Property
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
* @return Cn string
*/
nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
/**
* 日期转农历称呼速查表
* @Array Of Property
* @trans ['初','十','廿','卅']
* @return Cn string
*/
nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
/**
* 月份转农历称呼速查表
* @Array Of Property
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
* @return Cn string
*/
nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
/**
* 返回农历y年一整年的总天数
* @param lunar Year
* @return Number
* @eg:var count = calendar.lYearDays(1987) ;//count=387
*/
lYearDays: function (y) {
var i; var sum = 348
for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
return (sum + this.leapDays(y))
},
/**
* 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
* @param lunar Year
* @return Number (0-12)
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
*/
leapMonth: function (y) { // 闰字编码 \u95f0
return (this.lunarInfo[y - 1900] & 0xf)
},
/**
* 返回农历y年闰月的天数 若该年没有闰月则返回0
* @param lunar Year
* @return Number (0、29、30)
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
*/
leapDays: function (y) {
if (this.leapMonth(y)) {
return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
}
return (0)
},
/**
* 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
* @param lunar Year
* @return Number (-1、29、30)
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
*/
monthDays: function (y, m) {
if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
},
/**
* 返回公历(!)y年m月的天数
* @param solar Year
* @return Number (-1、28、29、30、31)
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
*/
solarDays: function (y, m) {
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
var ms = m - 1
if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
} else {
return (this.solarMonth[ms])
}
},
/**
* 农历年份转换为干支纪年
* @param lYear 农历年的年份数
* @return Cn string
*/
toGanZhiYear: function (lYear) {
var ganKey = (lYear - 3) % 10
var zhiKey = (lYear - 3) % 12
if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
},
/**
* 公历月、日判断所属星座
* @param cMonth [description]
* @param cDay [description]
* @return Cn string
*/
toAstro: function (cMonth, cDay) {
var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
},
/**
* 传入offset偏移量返回干支
* @param offset 相对甲子的偏移量
* @return Cn string
*/
toGanZhi: function (offset) {
return this.Gan[offset % 10] + this.Zhi[offset % 12]
},
/**
* 传入公历(!)y年获得该年第n个节气的公历日期
* @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
* @return day Number
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
*/
getTerm: function (y, n) {
if (y < 1900 || y > 2100) { return -1 }
if (n < 1 || n > 24) { return -1 }
var _table = this.sTermInfo[y - 1900]
var _info = [
parseInt('0x' + _table.substr(0, 5)).toString(),
parseInt('0x' + _table.substr(5, 5)).toString(),
parseInt('0x' + _table.substr(10, 5)).toString(),
parseInt('0x' + _table.substr(15, 5)).toString(),
parseInt('0x' + _table.substr(20, 5)).toString(),
parseInt('0x' + _table.substr(25, 5)).toString()
]
var _calday = [
_info[0].substr(0, 1),
_info[0].substr(1, 2),
_info[0].substr(3, 1),
_info[0].substr(4, 2),
_info[1].substr(0, 1),
_info[1].substr(1, 2),
_info[1].substr(3, 1),
_info[1].substr(4, 2),
_info[2].substr(0, 1),
_info[2].substr(1, 2),
_info[2].substr(3, 1),
_info[2].substr(4, 2),
_info[3].substr(0, 1),
_info[3].substr(1, 2),
_info[3].substr(3, 1),
_info[3].substr(4, 2),
_info[4].substr(0, 1),
_info[4].substr(1, 2),
_info[4].substr(3, 1),
_info[4].substr(4, 2),
_info[5].substr(0, 1),
_info[5].substr(1, 2),
_info[5].substr(3, 1),
_info[5].substr(4, 2)
]
return parseInt(_calday[n - 1])
},
/**
* 传入农历数字月份返回汉语通俗表示法
* @param lunar month
* @return Cn string
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
*/
toChinaMonth: function (m) { // 月 => \u6708
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
var s = this.nStr3[m - 1]
s += '\u6708'// 加上月字
return s
},
/**
* 传入农历日期数字返回汉字表示法
* @param lunar day
* @return Cn string
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
*/
toChinaDay: function (d) { // 日 => \u65e5
var s
switch (d) {
case 10:
s = '\u521d\u5341'; break
case 20:
s = '\u4e8c\u5341'; break
break
case 30:
s = '\u4e09\u5341'; break
break
default :
s = this.nStr2[Math.floor(d / 10)]
s += this.nStr1[d % 10]
}
return (s)
},
/**
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
* @param y year
* @return Cn string
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
*/
getAnimal: function (y) {
return this.Animals[(y - 4) % 12]
},
/**
* 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
* @param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg:console.log(calendar.solar2lunar(1987,11,01));
*/
solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
// 年份限定、上限
if (y < 1900 || y > 2100) {
return -1// undefined转换为数字变为NaN
}
// 公历传参最下限
if (y == 1900 && m == 1 && d < 31) {
return -1
}
// 未传参 获得当天
if (!y) {
var objDate = new Date()
} else {
var objDate = new Date(y, parseInt(m) - 1, d)
}
var i; var leap = 0; var temp = 0
// 修正ymd参数
var y = objDate.getFullYear()
var m = objDate.getMonth() + 1
var d = objDate.getDate()
var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
for (i = 1900; i < 2101 && offset > 0; i++) {
temp = this.lYearDays(i)
offset -= temp
}
if (offset < 0) {
offset += temp; i--
}
// 是否今天
var isTodayObj = new Date()
var isToday = false
if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
isToday = true
}
// 星期几
var nWeek = objDate.getDay()
var cWeek = this.nStr1[nWeek]
// 数字表示周几顺应天朝周一开始的惯例
if (nWeek == 0) {
nWeek = 7
}
// 农历年
var year = i
var leap = this.leapMonth(i) // 闰哪个月
var isLeap = false
// 效验闰月
for (i = 1; i < 13 && offset > 0; i++) {
// 闰月
if (leap > 0 && i == (leap + 1) && isLeap == false) {
--i
isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
} else {
temp = this.monthDays(year, i)// 计算农历普通月天数
}
// 解除闰月
if (isLeap == true && i == (leap + 1)) { isLeap = false }
offset -= temp
}
// 闰月导致数组下标重叠取反
if (offset == 0 && leap > 0 && i == leap + 1) {
if (isLeap) {
isLeap = false
} else {
isLeap = true; --i
}
}
if (offset < 0) {
offset += temp; --i
}
// 农历月
var month = i
// 农历日
var day = offset + 1
// 天干地支处理
var sm = m - 1
var gzY = this.toGanZhiYear(year)
// 当月的两个节气
// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
// 依据12节气修正干支月
var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
if (d >= firstNode) {
gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
}
// 传入的日期的节气与否
var isTerm = false
var Term = null
if (firstNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 2]
}
if (secondNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 1]
}
// 日柱 当月一日与 1900/1/1 相差天数
var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
var gzD = this.toGanZhi(dayCyclical + d - 1)
// 该日期所属的星座
var astro = this.toAstro(m, d)
return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
},
/**
* 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
* @param y lunar year
* @param m lunar month
* @param d lunar day
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
* @return JSON object
* @eg:console.log(calendar.lunar2solar(1987,9,10));
*/
lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
var isLeapMonth = !!isLeapMonth
var leapOffset = 0
var leapMonth = this.leapMonth(y)
var leapDay = this.leapDays(y)
if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
var day = this.monthDays(y, m)
var _day = day
// bugFix 2016-9-25
// if month is leap, _day use leapDays method
if (isLeapMonth) {
_day = this.leapDays(y, m)
}
if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
// 计算农历的时间差
var offset = 0
for (var i = 1900; i < y; i++) {
offset += this.lYearDays(i)
}
var leap = 0; var isAdd = false
for (var i = 1; i < m; i++) {
leap = this.leapMonth(y)
if (!isAdd) { // 处理闰月
if (leap <= i && leap > 0) {
offset += this.leapDays(y); isAdd = true
}
}
offset += this.monthDays(y, i)
}
// 转换闰月农历 需补充该年闰月的前一个月的时差
if (isLeapMonth) { offset += day }
// 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
var calObj = new Date((offset + d - 31) * 86400000 + stmap)
var cY = calObj.getUTCFullYear()
var cM = calObj.getUTCMonth() + 1
var cD = calObj.getUTCDate()
return this.solar2lunar(cY, cM, cD)
}
}
export default calendar

View File

@@ -0,0 +1,152 @@
<template>
<view class="uni-calendar-item__weeks-box" :class="{
'uni-calendar-item--disable':weeks.disable,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
'uni-calendar-item--multiple': weeks.multiple
}"
@click="choiceDate(weeks)">
<view class="uni-calendar-item__weeks-box-item">
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
<text class="uni-calendar-item__weeks-box-text" :class="{
'uni-calendar-item--isDay-text': weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.date}}</text>
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
}">今天</text>
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--extra':weeks.extraInfo.info,
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.extraInfo.info}}</text>
</view>
</view>
</template>
<script>
export default {
props: {
weeks: {
type: Object,
default () {
return {}
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
lunar: {
type: Boolean,
default: false
}
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar-item__weeks-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
}
.uni-calendar-item__weeks-box-text {
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar-item__weeks-lunar-text {
font-size: $uni-font-size-sm;
color: $uni-text-color;
}
.uni-calendar-item__weeks-box-item {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
width: 100rpx;
height: 100rpx;
}
.uni-calendar-item__weeks-box-circle {
position: absolute;
top: 5px;
right: 5px;
width: 8px;
height: 8px;
border-radius: 8px;
background-color: $uni-color-error;
}
.uni-calendar-item--disable {
background-color: rgba(249, 249, 249, $uni-opacity-disabled);
color: $uni-text-color-disable;
}
.uni-calendar-item--isDay-text {
color: $uni-color-primary;
}
.uni-calendar-item--isDay {
background-color: $uni-color-primary;
opacity: 0.8;
color: #fff;
}
.uni-calendar-item--extra {
color: $uni-color-error;
opacity: 0.8;
}
.uni-calendar-item--checked {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
.uni-calendar-item--multiple {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
</style>

View File

@@ -0,0 +1,435 @@
<template>
<view class="uni-calendar" @touchmove.stop.prevent="clean">
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="close"></view>
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
<view class="uni-calendar__header-btn-box" @click="close">
<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text>
</view>
<view class="uni-calendar__header-btn-box" @click="confirm">
<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text>
</view>
</view>
<view class="uni-calendar__header">
<view class="uni-calendar__header-btn-box" @click="pre">
<view class="iconfont icon-ic_leftarrow"></view>
</view>
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text>
<view class="uni-calendar__header-btn-box" @click="next">
<view class="iconfont icon-ic_rightarrow"></view>
</view>
<text class="uni-calendar__backtoday" @click="backtoday">回到今天</text>
</view>
<view class="uni-calendar__box">
<view v-if="showMonth" class="uni-calendar__box-bg">
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
</view>
<view class="uni-calendar__weeks">
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">日</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">一</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">二</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">三</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">四</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">五</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">六</text>
</view>
</view>
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
<uni-calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></uni-calendar-item>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import Calendar from './util.js';
import uniCalendarItem from './uni-calendar-item.vue'
export default {
components: {
uniCalendarItem
},
props: {
/**
* 当前日期
*/
date: {
type: String,
default: ''
},
/**
* 打点日期
*/
selected: {
type: Array,
default () {
return []
}
},
/**
* 是否开启阴历日期
*/
lunar: {
type: Boolean,
default: false
},
/**
* 开始时间
*/
startDate: {
type: String,
default: ''
},
/**
* 结束时间
*/
endDate: {
type: String,
default: ''
},
/**
* 范围
*/
range: {
type: Boolean,
default: false
},
/**
* 插入
*/
insert: {
type: Boolean,
default: true
},
/**
* 是否显示月份背景
*/
showMonth: {
type: Boolean,
default: true
}
},
data() {
return {
show: false,
weeks: [],
calendar: {},
nowDate: '',
aniMaskShow: false
}
},
watch: {
selected(newVal) {
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
this.weeks = this.cale.weeks
}
},
created() {
// 获取日历方法实例
this.cale = new Calendar({
date: this.date,
selected: this.selected,
startDate: this.startDate,
endDate: this.endDate,
range: this.range,
})
this.init(this.cale.date.fullDate)
},
methods: {
// 取消穿透
clean() {},
init(date) {
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(date)
},
open() {
this.show = true
this.$nextTick(() => {
setTimeout(()=>{
this.aniMaskShow = true
},50)
})
},
close() {
this.aniMaskShow = false
this.$nextTick(() => {
setTimeout(() => {
this.show = false
}, 300)
})
},
confirm() {
this.setEmit('confirm')
this.close()
},
change() {
if (!this.insert) return
this.setEmit('change')
},
monthSwitch() {
let {
year,
month
} = this.nowDate
this.$emit('monthSwitch', {
year,
month: Number(month)
})
},
setEmit(name) {
let {
year,
month,
date,
fullDate,
lunar,
extraInfo
} = this.calendar
this.$emit(name, {
range: this.cale.multipleStatus,
year,
month,
date,
fulldate: fullDate,
lunar,
extraInfo: extraInfo || {}
})
},
choiceDate(weeks) {
if (weeks.disable) return
this.calendar = weeks
// 设置多选
this.cale.setMultiple(this.calendar.fullDate)
this.weeks = this.cale.weeks
this.change()
},
backtoday() {
this.cale.setMultiple('')
this.cale.setDate(this.date)
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(this.date)
this.change()
},
pre() {
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
this.setDate(preDate)
this.monthSwitch()
},
next() {
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
this.setDate(nextDate)
this.monthSwitch()
},
setDate(date) {
this.cale.setDate(date)
this.weeks = this.cale.weeks
this.nowDate = this.cale.getInfo(date)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-calendar__mask {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
transition-property: opacity;
transition-duration: 0.3s;
opacity: 0;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--mask-show {
opacity: 1
}
.uni-calendar--fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
transition-property: transform;
transition-duration: 0.3s;
transform: translateY(460px);
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--ani-show {
transform: translateY(0);
}
.uni-calendar__content {
background-color: #fff;
}
.uni-calendar__header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
height: 50px;
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar--fixed-top {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 1px;
}
.uni-calendar--fixed-width {
width: 50px;
// padding: 0 15px;
}
.uni-calendar__backtoday {
position: absolute;
right: 0;
top: 25rpx;
padding: 0 5px;
padding-left: 10px;
height: 25px;
line-height: 25px;
font-size: 12px;
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
color: $uni-text-color;
background-color: $uni-bg-color-hover;
}
.uni-calendar__header-text {
text-align: center;
width: 100px;
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar__header-btn-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.uni-calendar__header-btn {
width: 10px;
height: 10px;
border-left-color: $uni-text-color-placeholder;
border-left-style: solid;
border-left-width: 2px;
border-top-color: $uni-color-subtitle;
border-top-style: solid;
border-top-width: 2px;
}
.uni-calendar--left {
transform: rotate(-45deg);
}
.uni-calendar--right {
transform: rotate(135deg);
}
.uni-calendar__weeks {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-calendar__weeks-item {
flex: 1;
}
.uni-calendar__weeks-day {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
height: 45px;
border-bottom-color: #F5F5F5;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar__weeks-day-text {
font-size: 14px;
}
.uni-calendar__box {
position: relative;
}
.uni-calendar__box-bg {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.uni-calendar__box-bg-text {
font-size: 200px;
font-weight: bold;
color: $uni-text-color-grey;
opacity: 0.1;
text-align: center;
/* #ifndef APP-NVUE */
line-height: 1;
/* #endif */
}
</style>

View File

@@ -0,0 +1,327 @@
import CALENDAR from './calendar.js'
class Calendar {
constructor({
date,
selected,
startDate,
endDate,
range
} = {}) {
// 当前日期
this.date = this.getDate(date) // 当前初入日期
// 打点信息
this.selected = selected || [];
// 范围开始
this.startDate = startDate
// 范围结束
this.endDate = endDate
this.range = range
// 多选状态
this.multipleStatus = {
before: '',
after: '',
data: []
}
// 每周日期
this.weeks = {}
this._getWeek(this.date.fullDate)
}
/**
* 获取任意时间
*/
getDate(date, AddDayCount = 0, str = 'day') {
if (!date) {
date = new Date()
}
if (typeof date !== 'object') {
date = date.replace(/-/g, '/')
}
const dd = new Date(date)
switch (str) {
case 'day':
dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
break
case 'month':
if (dd.getDate() === 31) {
dd.setDate(dd.getDate() + AddDayCount)
} else {
dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
}
break
case 'year':
dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
break
}
const y = dd.getFullYear()
const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
return {
fullDate: y + '-' + m + '-' + d,
year: y,
month: m,
date: d,
day: dd.getDay()
}
}
/**
* 获取上月剩余天数
*/
_getLastMonthDays(firstDay, full) {
let dateArr = []
for (let i = firstDay; i > 0; i--) {
const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
dateArr.push({
date: beforeDate,
month: full.month - 1,
lunar: this.getlunar(full.year, full.month - 1, beforeDate),
disable: true
})
}
return dateArr
}
/**
* 获取本月天数
*/
_currentMonthDys(dateData, full) {
let dateArr = []
let fullDate = this.date.fullDate
for (let i = 1; i <= dateData; i++) {
let isinfo = false
let nowDate = full.year + '-' + (full.month < 10 ?
full.month : full.month) + '-' + (i < 10 ?
'0' + i : i)
// 是否今天
let isDay = fullDate === nowDate
// 获取打点信息
let info = this.selected && this.selected.find((item) => {
if (this.dateEqual(nowDate, item.date)) {
return item
}
})
// 日期禁用
let disableBefore = true
let disableAfter = true
if (this.startDate) {
let dateCompBefore = this.dateCompare(this.startDate, fullDate)
disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
}
if (this.endDate) {
let dateCompAfter = this.dateCompare(fullDate, this.endDate)
disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
}
let multiples = this.multipleStatus.data
let checked = false
let multiplesStatus = -1
if (this.range) {
if (multiples) {
multiplesStatus = multiples.findIndex((item) => {
return this.dateEqual(item, nowDate)
})
}
if (multiplesStatus !== -1) {
checked = true
}
}
let data = {
fullDate: nowDate,
year: full.year,
date: i,
multiple: this.range ? checked : false,
month: full.month,
lunar: this.getlunar(full.year, full.month, i),
disable: !disableBefore || !disableAfter,
isDay
}
if (info) {
data.extraInfo = info
}
dateArr.push(data)
}
return dateArr
}
/**
* 获取下月天数
*/
_getNextMonthDays(surplus, full) {
let dateArr = []
for (let i = 1; i < surplus + 1; i++) {
dateArr.push({
date: i,
month: Number(full.month) + 1,
lunar: this.getlunar(full.year, Number(full.month) + 1, i),
disable: true
})
}
return dateArr
}
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
this._getWeek(date)
}
/**
* 获取当前日期详情
* @param {Object} date
*/
getInfo(date) {
if (!date) {
date = new Date()
}
const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
return dateInfo
}
/**
* 比较时间大小
*/
dateCompare(startDate, endDate) {
// 计算截止时间
startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
if (startDate <= endDate) {
return true
} else {
return false
}
}
/**
* 比较时间是否相等
*/
dateEqual(before, after) {
// 计算截止时间
before = new Date(before.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
after = new Date(after.replace('-', '/').replace('-', '/'))
if (before.getTime() - after.getTime() === 0) {
return true
} else {
return false
}
}
/**
* 获取日期范围内所有日期
* @param {Object} begin
* @param {Object} end
*/
geDateAll(begin, end) {
var arr = []
var ab = begin.split('-')
var ae = end.split('-')
var db = new Date()
db.setFullYear(ab[0], ab[1] - 1, ab[2])
var de = new Date()
de.setFullYear(ae[0], ae[1] - 1, ae[2])
var unixDb = db.getTime() - 24 * 60 * 60 * 1000
var unixDe = de.getTime() - 24 * 60 * 60 * 1000
for (var k = unixDb; k <= unixDe;) {
k = k + 24 * 60 * 60 * 1000
arr.push(this.getDate(new Date(parseInt(k))).fullDate)
}
return arr
}
/**
* 计算阴历日期显示
*/
getlunar(year, month, date) {
return CALENDAR.solar2lunar(year, month, date)
}
/**
* 设置打点
*/
setSelectInfo(data, value) {
this.selected = value
this._getWeek(data)
}
/**
* 获取多选状态
*/
setMultiple(fullDate) {
let {
before,
after
} = this.multipleStatus
if (!this.range) return
if (before && after) {
this.multipleStatus.before = ''
this.multipleStatus.after = ''
this.multipleStatus.data = []
this._getWeek(fullDate)
} else {
if (!before) {
this.multipleStatus.before = fullDate
} else {
this.multipleStatus.after = fullDate
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
} else {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
}
this._getWeek(fullDate)
}
}
}
/**
* 获取每周数据
* @param {Object} dateData
*/
_getWeek(dateData) {
const {
fullDate,
year,
month,
date,
day
} = this.getDate(dateData)
let firstDay = new Date(year, month - 1, 1).getDay()
let currentDay = new Date(year, month, 0).getDate()
let dates = {
lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
nextMonthDays: [], // 下个月开始几天
weeks: []
}
let canlender = []
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
let weeks = {}
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
for (let i = 0; i < canlender.length; i++) {
if (i % 7 === 0) {
weeks[parseInt(i / 7)] = new Array(7)
}
weeks[parseInt(i / 7)][i % 7] = canlender[i]
}
this.canlender = canlender
this.weeks = weeks
}
//静态方法
// static init(date) {
// if (!this.instance) {
// this.instance = new Calendar(date);
// }
// return this.instance;
// }
}
export default Calendar

View File

@@ -0,0 +1,457 @@
<template>
<form class="form" @submit="checkForm">
<view class="input-section">
<view class="section-hd">支付金额</view>
<view class="section-bd">
<view class="input-group">
¥
<input v-model.number="money" class="input" name="money" type="digit" placeholder="0.00" />
</view>
<view v-if="payPrice" class="discount">会员优惠价:¥{{ payPrice }}</view>
</view>
</view>
<view class="radio-section">
<view class="section-hd">支付方式</view>
<radio-group class="section-bd" name="method">
<label class="item" v-if="yuePay">
<text class="iconfont icon-yue"></text>
<text class="name">
余额抵扣
<text class="money">可用余额:{{ now_money || 0 }}¥</text>
</text>
<radio value="yue" :checked="payType === 'yue'" />
</label>
<label v-if="wxpay" class="item">
<text class="iconfont icon-weixinzhifu"></text>
<text class="name">微信支付</text>
<radio value="weixin" :checked="payType === 'weixin'" />
</label>
</radio-group>
</view>
<button class="button" form-type="submit">确认</button>
<view class="alipay" v-html="alipayHtml"></view>
<home></home>
</form>
</template>
<script>
import {
offlineCheckPrice,
offlineCreate,
orderOfflinePayType
} from '@/api/order.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
const app = getApp();
export default {
data() {
return {
money: '',
payPrice: '',
payType: 'weixin',
alipayHtml: '',
alipay: false,
wxpay: false,
yuePay: false,
paying: false,
now_money: 0,
isWeixin: false,
site_name: '',
isCommitted: false,
isShowAuth: false
};
},
watch: {
money(newValue, oldValue) {
if (newValue && typeof newValue === 'number') {
this.checkPrice();
} else {
this.payPrice = '';
}
}
},
computed: mapGetters(['isLogin']),
onLoad(options) {
// #ifdef H5
if (options.code) {
let spid = app.globalData.spid ? app.globalData.spid : '';
wechatAuthV2(options.code, spid).then(res => {
location.href = decodeURIComponent(
decodeURIComponent(options.back_url)
)
})
}
// #endif
},
onShow() {
if (this.isLogin) {
this.getPayType();
}else{
toLogin()
}
//#ifdef H5
this.isWeixin = this.$wechat.isWeixin();
//#endif
},
methods: {
getPayType() {
orderOfflinePayType()
.then(res => {
const {
ali_pay_status,
pay_weixin_open,
yue_pay_status,
offline_pay_status,
site_name,
now_money
} = res.data;
this.alipay = ali_pay_status === '1' ? true : false;
this.wxpay = pay_weixin_open === 1 ? true : false;
this.yuePay = yue_pay_status === 1 ? true : false;
this.now_money = now_money;
this.site_name = site_name;
if (!offline_pay_status) {
uni.showModal({
title: '支付提醒',
content: '线下支付已关闭,请点击确认按钮返回主页',
showCancel: false,
success() {
uni.switchTab({
url: '/pages/index/index'
})
}
});
}
if (site_name) {
uni.setNavigationBarTitle({
title: site_name
});
}
})
.catch(err => {
uni.showToast({
title: err,
icon: 'none'
});
});
},
checkForm(e) {
const {
money,
method
} = e.detail.value;
if (money) {
this.combData(method);
} else {
uni.showToast({
title: '请输入支付金额',
icon: 'none'
});
}
},
// 优惠价
checkPrice() {
offlineCheckPrice({
pay_price: this.money
})
.then(res => {
this.payPrice = res.data.pay_price;
})
.catch(err => {
uni.showToast({
title: err,
icon: 'none'
});
});
},
// 组合数据
combData(payType) {
let data = {
type: 3,
pay_type: payType,
from: 'weixinh5',
price: this.payPrice || this.money,
money: this.money
};
// #ifdef H5
if (this.isWeixin) {
data.from = 'weixin';
}
// #endif
// #ifdef MP
data.from = 'routine';
// #endif
if (this.paying) {
return;
}
this.paying = true;
uni.showLoading({
title: '正在确认…'
});
offlineCreate(data)
.then(res => {
uni.hideLoading();
this.callPay(res);
})
.catch(err => {
this.paying = false;
uni.showToast({
title: err,
icon: 'none'
});
});
},
// 调用支付
callPay(res) {
const {
status,
result
} = res.data, {
orderId,
jsConfig
} = result,
goPages = '/pages/annex/offline_result/index?site_name=' + this.site_name;
switch (status) {
case 'ORDER_EXIST':
case 'EXTEND_ORDER':
case 'PAY_ERROR':
this.paying = false;
this.$util.Tips({
title: res.msg
}, {
tab: 5,
url: goPages
});
break;
case 'SUCCESS':
this.paying = false;
this.money = '';
this.$util.Tips({
title: res.msg,
icon: 'success'
}, {
tab: 5,
url: goPages
});
break;
case 'WECHAT_PAY':
// #ifdef MP
let that = this;
let mp_pay_name=''
if(uni.requestOrderPayment){
mp_pay_name='requestOrderPayment'
}else{
mp_pay_name='requestPayment'
}
uni[mp_pay_name]({
timeStamp: jsConfig.timestamp,
nonceStr: jsConfig.nonceStr,
package: jsConfig.package,
signType: jsConfig.signType,
paySign: jsConfig.paySign,
success: function(res) {
that.$util.Tips({
title: '支付成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/annex/offline_result/index'
});
},
fail: function() {
uni.showToast({
title: '取消支付',
icon: 'none',
success: function() {
that.paying = false;
}
});
},
complete: function() {
that.paying = false;
uni.hideLoading();
}
});
// #endif
// #ifndef MP
this.$wechat
.pay(result.jsConfig)
.then(res => {
this.paying = false;
this.$util.Tips({
title: '支付成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/annex/offline_result/index'
});
})
.catch(err => {
this.paying = false;
if (err.errMsg == 'chooseWXPay:cancel') {
uni.showToast({
title: '取消支付',
icon: 'none'
});
}
});
// #endif
break;
case 'PAY_DEFICIENCY':
this.paying = false;
this.$util.Tips({
title: res.msg
});
break;
case 'WECHAT_H5_PAY':
this.paying = false;
uni.showToast({
title: res.msg,
success() {
location.href = jsConfig.mweb_url;
}
});
break;
case 'ALIPAY_PAY':
this.paying = false;
// #ifdef H5
if (this.$wechat.isWeixin()) {
uni.showToast({
title: '微信公众号不支持支付宝支付'
})
} else {
this.alipayHtml = jsConfig;
this.$nextTick(() => {
document.getElementById('alipaysubmit').submit();
});
}
// #endif
// #ifdef MP
uni.showToast({
title: '微信小程序不支持支付宝支付'
})
// #endif
break;
}
}
}
};
</script>
<style>
page {
background-color: #ffffff;
}
</style>
<style lang="scss" scoped>
/deep/uni-radio .uni-radio-input.uni-radio-input-checked {
border: 1px solid #FDC383 !important;
background-color: #FDC383 !important;
}
.input-section {
.section-hd {
padding: 30rpx;
font-size: 28rpx;
color: #666666;
}
.section-bd {
padding-right: 30rpx;
padding-left: 30rpx;
}
.input-group {
display: flex;
align-items: flex-end;
padding: 45rpx 20rpx 47rpx;
font-size: 80rpx;
color: #999999;
}
.input {
flex: 1;
height: 110rpx;
margin-left: 15rpx;
font-size: 100rpx;
color: #282828;
}
.discount {
padding: 27rpx 20rpx;
border-top: 1rpx solid #eeeeee;
font-size: 28rpx;
color: #e93323;
}
}
.radio-section {
border-top: 20rpx solid #f5f5f5;
.section-hd {
padding: 30rpx;
font-size: 28rpx;
color: #666666;
}
.section-bd {
padding-left: 50rpx;
}
.item {
display: flex;
align-items: center;
padding-top: 30rpx;
padding-right: 30rpx;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.iconfont {
font-size: 44rpx;
}
.icon-yue {
color: #fe960f;
}
.icon-weixinzhifu {
color: #41b035;
}
.icon-zhifubao {
color: #099bdf;
}
.name {
flex: 1;
margin-left: 30rpx;
font-size: 30rpx;
color: #333333;
}
.money {
float: right;
padding-right: 20rpx;
font-size: 20rpx;
}
}
.button {
height: 86rpx;
border-radius: 43rpx;
margin: 114rpx 30rpx 30rpx;
background: linear-gradient(90deg, #FEE2B7 0%, #FDC383 100%);
font-size: 30rpx;
line-height: 86rpx;
color: #5D3324;
}
.alipay {
display: none;
}
</style>

View File

@@ -0,0 +1,72 @@
<template>
<view>
<view class="result">
<view class="image-wrap">
<image class="image" :src="imgHost + '/statics/images/offline-result.png'" ></image>
</view>
<view class="text">支付成功</view>
</view>
<navigator class="link" url="/pages/index/index" open-type="switchTab">进入商城</navigator>
</view>
</template>
<script>
import {HTTP_REQUEST_URL} from '@/config/app.js';
export default {
data(){
return {
imgHost:HTTP_REQUEST_URL,
}
},
onLoad(options) {
let site_name = options.site_name || '';
if (site_name) {
uni.setNavigationBarTitle({
title: site_name
});
}
}
};
</script>
<style>
page {
background-color: #fff;
}
</style>
<style lang="scss" scoped>
.result {
margin-top: 200rpx;
.image-wrap {
width: 267rpx;
height: 223rpx;
margin: 0 auto;
}
.image {
width: 100%;
height: 100%;
}
.text {
margin-top: 46rpx;
font-size: 34rpx;
text-align: center;
color: #282828;
}
}
.link {
width: 560rpx;
height: 86rpx;
border: 1rpx solid #F19D2F;
border-radius: 43rpx;
margin: 90rpx auto 0;
font-size: 30rpx;
line-height: 86rpx;
text-align: center;
color: #F19D2F;
}
</style>

View File

@@ -0,0 +1,201 @@
<template>
<view class="record" :style="colorStyle">
<timeSlot @changeTime="changeTime"></timeSlot>
<view class="list" v-if="list.length">
<view class="item acea-row row-between row-top" v-for="(item,index) in list" :key="index">
<view class="acea-row row-top">
<text class="icon iconfont icon-xiaofeijilu1" v-if="item.type==1"></text>
<text class="icon iconfont icon-fufeihuiyuan1" v-else-if="item.type==7"></text>
<text class="icon iconfont icon-xiaofeijilu-rongcuo" v-else></text>
<view class="txt">
<view class="line1">{{item.title}}</view>
<view class="exp record">{{item.type_name}}</view>
<view class="time">{{item.day}}</view>
</view>
</view>
<view class="num">-{{item.price}}</view>
</view>
</view>
<view class="list" v-else>
<emptyPage title="暂无消费记录~"></emptyPage>
</view>
<view class='loadingicon acea-row row-center-wrapper' v-if="list.length">
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<home></home>
</view>
</template>
<script>
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import {
moneyList
} from '@/api/user.js';
import emptyPage from '@/components/emptyPage.vue'
import timeSlot from '../components/timeSlot/index.vue';
import colors from '@/mixins/color.js';
export default {
components: {
timeSlot,
emptyPage
},
mixins: [colors],
computed: mapGetters(['isLogin']),
data(){
return {
page: 1,
limit: 15,
start: 0,
stop: 0,
loading: false,
loadend: false,
loadTitle: '加载更多',
list:[],
isShowAuth: false
}
},
onLoad(){
if (this.isLogin) {
this.getUserBillList();
}
},
onShow(){
if(!this.isLogin){
toLogin()
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods:{
onLoadFun(){
this.getUserBillList();
this.isShowAuth = false;
},
authColse: function(e) {
this.isShowAuth = e
},
changeTime(time) {
this.start = time.start
this.stop = time.stop
this.page = 1;
this.loadend = false;
this.list = [];
this.getUserBillList()
},
getUserBillList(){
let that = this;
if (that.loading) return;
if (that.loadend) return;
that.loading = true;
that.loadTitle = '';
moneyList({
page: this.page,
limit: this.limit,
start: this.start,
stop: this.stop
},9).then(res=>{
let list = res.data.list;
let loadend = list.length < that.limit;
that.list = that.$util.SplitArray(list, that.list);
that.$set(that, 'list', that.list);
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
that.loadTitle = '加载更多';
})
}
},
onReachBottom: function() {
this.getUserBillList();
}
}
</script>
<style lang="scss">
.record{
.list{
width: 690rpx;
background-color: #fff;
border-radius: 14rpx;
margin: 20rpx auto 0 auto;
padding-top: 42rpx;
.item{
padding: 0 24rpx 26rpx 24rpx;
position: relative;
margin-bottom: 34rpx;
.icon{
font-size: 72rpx;
color: #E7C993;
}
.num{
color: #282828;
font-size: 32rpx;
font-weight: 600;
}
.pictrue{
width: 76rpx;
height: 76rpx;
background-color: #FDF8EE;
border-radius: 50%;
.iconfont{
color: #F7B942;
}
}
.txt{
font-weight: 400;
color: #282828;
font-size: 28rpx;
margin-left: 24rpx;
.line1{
width: 320rpx;
}
.exp{
color: #999999;
font-size: 22rpx;
margin-top: 2rpx;
&.record{
margin-top: 8rpx;
}
image{
color: #999999;
margin-right: 10rpx;
width: 22rpx;
height: 22rpx;
}
}
.time{
color: #999999;
font-size: 22rpx;
margin-top: 8rpx;
}
}
.bnt{
width: 112rpx;
height: 44rpx;
background: #F4DBAB;
border-radius: 26rpx;
color: #755214;
font-size: 24rpx;
}
&::before{
position: absolute;
content: '';
width: 542rpx;
height: 1px;
background: #EEEEEE;
bottom: 0rpx;
right: 24rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,733 @@
<template>
<view v-if="pageShow" class="page"
:class="bgTabVal==2?'fullsize noRepeat':bgTabVal==1?'repeat ysize':'noRepeat ysize'" :style="[pageStyle]">
<view :style="colorStyle">
<view class="index">
<!-- 自定义样式 -->
<block v-for="(item, index) in styleConfig" :key="index">
<homeComb v-if="item.name == 'homeComb'" :dataConfig="item" @bindSortId="bindSortId"
:isScrolled="isScrolled"></homeComb>
<headerSerch v-if="item.name == 'headerSerch'" :dataConfig="item"></headerSerch>
<userInfor v-if="item.name == 'userInfor'" :dataConfig="item" @changeLogin="changeLogin">
</userInfor>
<newVip v-if="item.name == 'newVip'" :dataConfig="item"></newVip>
<!-- 文章列表 -->
<articleList v-if="item.name == 'articleList'" :dataConfig="item"></articleList>
<bargain v-if="item.name == 'bargain'" :dataConfig="item" @changeBarg="changeBarg"></bargain>
<blankPage v-if="item.name == 'blankPage'" :dataConfig="item"></blankPage>
<combination v-if="item.name == 'combination'" :dataConfig="item">
</combination>
<!-- 优惠券 -->
<coupon v-if="item.name == 'coupon'" :dataConfig="item" @changeLogin="changeLogin"></coupon>
<!-- 客户服务 -->
<customerService v-if="item.name == 'customerService'" :dataConfig="item">
</customerService>
<!-- 商品列表 -->
<goodList v-if="item.name == 'goodList'" :dataConfig="item" @detail="goDetail"></goodList>
<guide v-if="item.name == 'guide'" :dataConfig="item"></guide>
<!-- 直播模块 -->
<!-- #ifdef MP-WEIXIN -->
<liveBroadcast v-if="item.name == 'liveBroadcast'" :dataConfig="item"></liveBroadcast>
<!-- #endif -->
<menus v-if="item.name == 'menus'" :dataConfig="item"></menus>
<!-- 实时消息 -->
<news v-if="item.name == 'news'" :dataConfig="item"></news>
<!-- 图片库 -->
<pictureCube v-if="item.name == 'pictureCube'" :dataConfig="item">
</pictureCube>
<!-- 促销列表 -->
<promotionList v-if="item.name == 'promotionList'" :dataConfig="item" @detail="goDetail"
:productVideoStatus='product_video_status'>
</promotionList>
<richText v-if="item.name == 'richText'" :dataConfig="item"></richText>
<seckill v-if="item.name == 'seckill'" :dataConfig="item"></seckill>
<!-- 轮播图-->
<swiperBg v-if="item.name == 'swiperBg'" :dataConfig="item"></swiperBg>
<swipers v-if="item.name == 'swipers'" :dataConfig="item"></swipers>
<!-- 顶部选项卡 -->
<tabNav v-if="item.name == 'tabNav'" :dataConfig="item" @bindHeight="bindHeighta"
@bindSortId="bindSortId" :isFixed="isFixed"></tabNav>
<!-- 标题 -->
<titles v-if="item.name == 'titles'" :dataConfig="item"></titles>
<ranking v-if="item.name == 'ranking'" :dataConfig="item"></ranking>
<presale v-if="item.name == 'presale'" :dataConfig="item"></presale>
<pointsMall v-if="item.name == 'pointsMall'" :dataConfig="item"></pointsMall>
<videos v-if="item.name == 'videos'" :dataConfig="item"></videos>
<signIn v-if="item.name == 'signIn'" :dataConfig="item"></signIn>
<hotspot v-if="item.name == 'hotspot'" :dataConfig="item"></hotspot>
<follow v-if="item.name == 'follow'" :dataConfig="item"></follow>
<community v-if="item.name == 'community'" :dataConfig="item"></community>
</block>
<!-- 分类商品模块 -->
<!-- #ifndef APP-PLUS -->
<view class="sort-product px-20">
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<!-- 商品排序 -->
<view class="sort-product px-20" :style="{ marginTop: sortMpTop + 'px' }">
<!-- #endif -->
<waterfallsFlow ref="waterfallsFlow" :wfList="goodList" @itemTap="goDetail"></waterfallsFlow>
<Loading :loaded="loaded" :loading="loading"></Loading>
<view v-if="goodList.length == 0 && loaded" class="sort-scroll rd-16rpx">
<view class="empty-box pb-24">
<image :src="imgHost + '/statics/images/no-thing.png'"></image>
<view class="tips">暂无商品,去看点别的吧</view>
</view>
</view>
</view>
<view class="pb-safe">
<view class="h-100"></view>
</view>
<pageFooter :isTabBar="false" :configData="tabBarData"></pageFooter>
</view>
</view>
<activityModal :pageIndex="6" :pageId="pageId"></activityModal>
</view>
</template>
<script>
const app = getApp();
import colors from "@/mixins/color";
import couponWindow from '@/components/couponWindow/index'
import {
getCouponV2,
getCouponNewUser
} from '@/api/api.js'
import {
getShare
} from '@/api/public.js';
// #ifdef H5
import {
silenceAuth
} from '@/api/public.js';
// #endif
import userInfor from '@/pages/index/components/userInfor';
import homeComb from '@/pages/index/components/homeComb';
import newVip from '@/pages/index/components/newVip';
import headerSerch from '@/pages/index/components/headerSerch';
import swipers from '@/pages/index/components/swipers';
import coupon from '@/pages/index/components/coupon';
import articleList from '@/pages/index/components/articleList';
import bargain from '@/pages/index/components/bargain';
import blankPage from '@/pages/index/components/blankPage';
import combination from '@/pages/index/components/combination';
import customerService from '@/pages/index/components/customerService';
import goodList from '@/pages/index/components/goodList';
import guide from '@/pages/index/components/guide';
import liveBroadcast from '@/pages/index/components/liveBroadcast';
import menus from '@/pages/index/components/menus';
import news from '@/pages/index/components/news';
import pictureCube from '@/pages/index/components/pictureCube';
import promotionList from '@/pages/index/components/promotionList';
import richText from '@/pages/index/components/richText';
import seckill from '@/pages/index/components/seckill';
import swiperBg from '@/pages/index/components/swiperBg';
import tabNav from '@/pages/index/components/tabNav';
import titles from '@/pages/index/components/titles';
import ranking from '@/pages/index/components/ranking';
import presale from '@/pages/index/components/presale'
import pointsMall from '@/pages/index/components/pointsMall';
import videos from '@/pages/index/components/videos';
import signIn from '@/pages/index/components/signIn';
import hotspot from '@/pages/index/components/hotspot';
import follow from '@/pages/index/components/follow';
import community from '@/pages/index/components/community'
import waterfallsFlow from "@/components/WaterfallsFlow/WaterfallsFlow.vue";
import activityModal from "@/components/activityModal/index.vue";
// #ifdef MP
import {getTemlIds} from '@/api/api.js';
import {SUBSCRIBE_MESSAGE,TIPS_KEY} from '@/config/cache';
// #endif
import {mapGetters} from 'vuex';
import {getDiy,getDiyVersion} from '@/api/api.js';
import {
getCategoryList,
getProductslist,
getProductHot,
} from '@/api/store.js';
import { goShopDetail } from '@/libs/order.js';
import { toLogin } from '@/libs/login.js';
import { HTTP_REQUEST_URL } from '@/config/app';
import pageFooter from '@/components/pageFooter/index.vue'
import recommend from '@/components/recommend';
import Loading from '@/components/Loading/index.vue';
export default {
computed: {
pageStyle() {
return {
backgroundColor: this.bgColor,
backgroundImage: this.bgPic ? `url(${this.bgPic})` : '',
minHeight: this.windowHeight + 'px'
}
},
...mapGetters(['isLogin', 'uid']),
},
mixins: [colors],
components: {
recommend,
Loading,
pageFooter,
couponWindow,
homeComb,
newVip,
userInfor,
headerSerch,
swipers,
coupon,
articleList,
bargain,
blankPage,
combination,
customerService,
goodList,
guide,
liveBroadcast,
menus,
pictureCube,
news,
promotionList,
richText,
seckill,
swiperBg,
tabNav,
titles,
ranking,
presale,
pointsMall,
videos,
signIn,
hotspot,
follow,
waterfallsFlow,
community,
activityModal
},
data() {
return {
styleConfig: [],
loading: false,
loadend: false,
loadTitle: '加载更多', //提示语
page: 1,
limit: this.$config.LIMIT,
numConfig: 0,
code: '',
isCouponShow: false,
couponObj: {},
couponObjs: {},
shareInfo: {},
footConfig: {},
pageId: '',
sortMpTop: 0,
bgColor: '',
bgPic: '',
bgTabVal: '',
pageShow: true,
windowHeight: 0,
isShowAuth: false,
isScrolled: false,
sortList: '',
sortAll: [],
isSortType: 0,
hostProduct: [],
hotScroll: false,
hotPage: 1,
hotLimit: 10,
curSort: 0,
loaded: false,
goodPage: 1,
goodList: [],
sid: 0,
imgHost: HTTP_REQUEST_URL,
product_video_status: false,
tabBarData:{},
};
},
onLoad(options) {
let that = this
this.$nextTick(function() {
uni.getSystemInfo({
success: function(res) {
that.windowHeight = res.windowHeight;
}
});
})
const {
state,
scope
} = options;
this.pageId = options.id
// #ifdef MP
if (options.scene) {
let value = that.$util.getUrlParams(decodeURIComponent(options.scene));
this.pageId = value.id
}
// #endif
uni.setNavigationBarTitle({
title: '专题栏'
});
// #ifdef APP-PLUS
this.sortMpTop = -50
// #endif
this.getDiyData();
// #ifdef H5
this.setOpenShare();
// #endif
// #ifdef MP || APP-PLUS
this.getTemlIds();
// #endif
getShare().then(res => {
this.shareInfo = res.data;
})
},
onUnload() {
// 清除监听
uni.$off('activeFn');
},
watch: {
isLogin: {
deep: true, //深度监听设置为 true
handler: function(newV, oldV) {
// 优惠券弹窗
var newDates = new Date().toLocaleDateString();
if (newV) {
try {
var oldDate = uni.getStorageSync('oldDate') || ''
} catch {}
if (oldDate != newDates) {
this.getCoupon();
}
}
}
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
// 优惠券弹窗
var newDates = new Date().toLocaleDateString();
if (this.isLogin) {
try {
var oldDate = uni.getStorageSync('oldDate') || ''
} catch {}
if (oldDate != newDates) {
this.getCoupon();
}
let oldUser = uni.getStorageSync('oldUser') || 0;
if (!oldUser) {
this.getCouponOnce();
}
}
},
mounted() {},
methods: {
// 分类点击
changeSort(item, index) {
if (this.curSort == index) return;
this.curSort = index;
this.sid = item.id;
this.goodList = [];
this.goodPage = 1;
this.loaded = false;
this.getGoodsList();
},
/**
* @param data {
classPage: 0 分类id
microPage: 0 微页面id
type: 1 0 商品分类 1 微页面
}*/
bindSortId(data) {
this.styleConfig = [];
if (data.type == 1) {
this.getProductList(data.classPage);
} else {
this.sortList = [];
this.getMicroPage(data.microPage, true);
}
},
/**
* 获取DIY
* @param {number} id
* @param {boolean} type 区分是否是微页面
*/
getMicroPage(id, type) {
let that = this;
that.styleConfig = []
uni.showLoading({
title: '加载中...'
});
getDiy(id).then(res => {
uni.hideLoading();
let data = res.data;
that.styleConfig = that.objToArr(res.data.value);
that.styleConfig.forEach((item, index) => {
if (['headerSerch', 'homeComb'].includes(item.name)) {
that.styleConfig.splice(index, 1);
}
});
}).catch(err => {
return that.$util.Tips({
title: err
});
uni.hideLoading();
});
},
getProductList(data) {
this.curSort = 0;
this.loaded = false;
if (this.sortAll.length > 0) {
this.sortAll.forEach((el, index) => {
if (el.id == data) {
this.$set(this, 'sortList', el);
this.sid = el.children.length ? el.children[0].id : '';
}
});
this.goodList = [];
this.goodPage = 1;
this.$nextTick(() => {
if (this.sortList != '') this.getGoodsList();
});
} else {
getCategoryList().then(res => {
this.sortAll = res.data;
res.data.forEach((el, index) => {
if (el.id == data) {
this.sortList = el;
this.sid = el.children.length ? el.children[0].id : '';
}
});
this.goodList = [];
this.goodPage = 1;
this.$nextTick(() => {
if (this.sortList != '') this.getGoodsList();
});
});
}
},
// 商品列表
getGoodsList() {
if (this.loading || this.loaded) return;
this.loading = true;
getProductslist({
sid: this.sid,
keyword: '',
priceOrder: '',
salesOrder: '',
news: 0,
page: this.goodPage,
limit: 10,
cid: this.sortList.id
}).then(res => {
this.loading = false;
this.loaded = res.data.length < 10;
this.goodPage++;
this.goodList = this.goodList.concat(res.data);
});
},
/**
* 获取我的推荐
*/
get_host_product: function() {
let that = this;
if (that.hotScroll) return;
getProductHot(that.hotPage, that.hotLimit).then(res => {
that.hotPage++;
that.hotScroll = res.data.length < that.hotLimit;
that.hostProduct = that.hostProduct.concat(res.data);
});
},
// 新用户优惠券
getCouponOnce() {
getCouponNewUser().then(res => {
this.couponObjs = res.data;
});
},
couponCloses() {
this.couponObjs.show = false;
try {
uni.setStorageSync('oldUser', 1);
} catch (e) {
}
},
// 优惠券弹窗
getCoupon() {
getCouponV2().then(res => {
this.couponObj = res.data
if (res.data.list.length > 0) {
this.isCouponShow = true
}
})
},
// 优惠券弹窗关闭
couponClose() {
this.isCouponShow = false
try {
uni.setStorageSync('oldDate', new Date().toLocaleDateString());
} catch {}
},
// #ifdef H5
// 获取url后面的参数
getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var reg_rewrite = new RegExp("(^|/)" + name + "/([^/]*)(/|$)", "i");
var r = window.location.search.substr(1).match(reg);
var q = window.location.pathname.substr(1).match(reg_rewrite);
if (r != null) {
return unescape(r[2]);
} else if (q != null) {
return unescape(q[2]);
} else {
return null;
}
},
// #endif
// #ifdef MP || APP-PLUS
getTemlIds() {
let messageTmplIds = wx.getStorageSync(SUBSCRIBE_MESSAGE);
if (!messageTmplIds) {
getTemlIds().then(res => {
if (res.data) wx.setStorageSync(SUBSCRIBE_MESSAGE, JSON.stringify(res.data));
});
}
},
// #endif
// 对象转数组
objToArr(data) {
const keys = Object.keys(data)
keys.sort((a, b) => a - b)
const m = keys.map(key => data[key]);
return m;
},
getDiyData() {
getDiy(this.pageId).then(res => {
// uni.setStorageSync('specialDiyData', JSON.stringify(res.data));
// this.setDiyData(res.data);
let data = res.data;
if (data.is_bg_color) {
this.bgColor = data.color_picker
}
if (data.is_bg_pic) {
this.bgPic = data.bg_pic
this.bgTabVal = data.bg_tab_val
}
this.pageShow = data.is_show
uni.setNavigationBarTitle({
title: data.title
})
let temp = []
let lastArr = this.objToArr(data.value)
lastArr.forEach((item, index, arr) => {
if (item.isHide !== '1') {
temp.push(item);
}
if (item.name == 'pageFoot') {
this.tabBarData = item;
}
});
this.styleConfig = temp;
});
},
changeBarg(item) {
if (!this.isLogin) {
toLogin()
} else {
uni.navigateTo({
url: `/pages/activity/goods_bargain_details/index?id=${item.id}&spid=${this.uid}`
});
}
},
goDetail(item) {
goShopDetail(item, this.uid).then(res => {
uni.navigateTo({
url: `/pages/goods_details/index?id=${item.id}`
});
});
},
// #ifdef H5
// 微信分享;
setOpenShare: function() {
let that = this;
if (that.$wechat.isWeixin()) {
getShare().then(res => {
let data = res.data.data;
let configAppMessage = {
desc: data.synopsis,
title: data.title,
link: location.href,
imgUrl: data.img
};
that.$wechat.wechatEvevt(['updateAppMessageShareData', 'updateTimelineShareData'],
configAppMessage);
});
}
}
// #endif
},
onReachBottom: function() {},
onPageScroll(e) {
if (e.scrollTop > 10) {
this.isScrolled = true;
} else {
this.isScrolled = false;
}
uni.$emit('scroll');
},
//#ifdef MP || APP-PLUS
onShareAppMessage() {
return {
title: this.shareInfo.title,
path: '/pages/index/index',
imageUrl: this.storeInfo.img,
};
},
//#endif
};
</script>
<style lang="scss">
.sort-scroll {
background-color: #fff;
}
.empty-box {
text-align: center;
padding-top: 50rpx;
.tips {
color: #aaa;
font-size: 26rpx;
}
image {
width: 414rpx;
height: 304rpx;
}
}
.sort-product {
margin-top: 20rpx;
.sort-box {
display: flex;
width: 100%;
border-radius: 16rpx;
padding: 30rpx 0;
.sort-item {
width: 20%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex-shrink: 0;
image {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
}
.txt {
color: #272727;
font-size: 24rpx;
margin-top: 10rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 140rpx;
text-align: center;
}
.pictrues {
width: 90rpx;
height: 90rpx;
background: #f8f8f8;
border-radius: 50%;
margin: 0 auto;
}
.icon-gengduo1 {
color: #333;
}
&.on {
.txt {
color: #fc4141;
}
image {
border: 1px solid #fc4141;
}
}
}
}
.product-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 30rpx;
padding: 0 20rpx;
.product-item {
position: relative;
width: 344rpx;
background: #fff;
border-radius: 10rpx;
margin-bottom: 20rpx;
overflow: hidden;
.pictrue {
position: relative;
}
image {
width: 100%;
height: 344rpx;
border-radius: 10rpx 10rpx 0 0;
}
.info {
padding: 14rpx 16rpx;
.title {
font-size: 28rpx;
}
.price-box {
font-size: 34rpx;
font-weight: 700;
margin-top: 8px;
color: #fc4141;
text {
font-size: 26rpx;
}
}
}
}
}
}
.ysize {
background-size: 100%;
}
.fullsize {
background-size: 100% 100%;
}
.repeat {
background-repeat: repeat;
}
.noRepeat {
background-repeat: no-repeat;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
pages/annex/static/exp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Some files were not shown because too many files have changed in this diff Show More