初始上传
This commit is contained in:
183
addon/cashier/source/os/pages/billing/index.vue
Executable file
183
addon/cashier/source/os/pages/billing/index.vue
Executable file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row page-height" @click="restoreFocus">
|
||||
<view class="common-wrap left-wrap">
|
||||
<view class="cashregister-header-box">
|
||||
<view class="order-time">
|
||||
<view class="title">消费时间</view>
|
||||
<uni-datetime-picker v-model="billingOrderData.create_time" type="datetime" :clearIcon="false" />
|
||||
</view>
|
||||
<view class="header" v-if="globalMemberInfo">
|
||||
<view class="headimg" @click="showMember">
|
||||
<image class="header-image" :src="globalMemberInfo.headimg ? $util.img(globalMemberInfo.headimg) : $util.img(defaultImg.head)" @error="globalMemberInfo.headimg = defaultImg.head"/>
|
||||
<view v-if="globalMemberInfo.member_level" class="member-nameplate">
|
||||
{{ globalMemberInfo.member_level_name }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="head-info" @click="showMember">
|
||||
<view class="head-info-top">
|
||||
<view class="name">
|
||||
<block v-if="globalMemberInfo.mobile">
|
||||
<view class="mobile">{{ globalMemberInfo.mobile }}</view>
|
||||
<view class="text">
|
||||
<text>(</text>
|
||||
<text class="nickname">{{globalMemberInfo.nickname }}</text>
|
||||
<text>)</text>
|
||||
</view>
|
||||
</block>
|
||||
<text v-else>{{ globalMemberInfo.nickname }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="head-info-bottom point">积分:{{ globalMemberInfo.point }}</view>
|
||||
<view class="head-info-bottom balance">余额:{{ (parseFloat(globalMemberInfo.balance_money) + parseFloat(globalMemberInfo.balance)) | moneyFormat}}</view>
|
||||
</view>
|
||||
<button class="switch primary-btn member-open" @click="openMember()">更换会员</button>
|
||||
<button class="switch primary-btn replace-member" @click="replaceMember()">散客</button>
|
||||
</view>
|
||||
<view class="header" v-else>
|
||||
<view class="headimg">
|
||||
<image class="header-image" :src="$util.img(defaultImg.head)" />
|
||||
</view>
|
||||
<view class="head-info">
|
||||
<view class="name">散客</view>
|
||||
</view>
|
||||
<button class="switch primary-btn" @click="openMember()">查询会员</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="content-list common-scrollbar">
|
||||
<block v-if="billingOrderData.goods_list.length && Object.keys(billingGoodsData).length">
|
||||
<view class="content-item settlement-select-focus" :class="{ 'focus bg-primary-color-9': leftIndexFocus == index }"
|
||||
v-for="(item, index) in billingOrderData.goods_list" :key="item.editKey"
|
||||
@click="callBox(item)" tabindex="0" :data-tab-index="index"
|
||||
@blur="leftTabOrderSelectBlur(item)">
|
||||
<view class="item-img">
|
||||
<image v-if="item.goods_image == '@/static/goods/goods.png'" src="@/static/goods/goods.png" mode="widthFix"/>
|
||||
<image v-else :src="$util.img(item.goods_image.split(',')[0], { size: 'small' })" mode="widthFix" @error="item.goods_image = '@/static/goods/goods.png'"/>
|
||||
</view>
|
||||
<view class="uni-flex flex-1 info-wrap">
|
||||
<view class="info-top">
|
||||
<view class="uni-flex justify-between items-center">
|
||||
<view class="item-name">{{ item.goods_name }}</view>
|
||||
<view class="item-del" @click.stop="deleteGoods(item)">
|
||||
<text class="iconfont iconshanchu"></text>
|
||||
<text>删除</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-spe" v-if="item.spec_name">已选:{{ item.spec_name }}</view>
|
||||
</view>
|
||||
<view class="info-bottom">
|
||||
<view class="uni-flex items-flex-end">
|
||||
<view class="item-price">¥{{ item.price | moneyFormat }}{{item.card_item_id > 0 ? '×'+item.num : ''}}</view>
|
||||
<view class="item-subtotal" v-if="item.goods_class != $util.goodsClassDict.service && item.card_item_id == 0">
|
||||
<view>
|
||||
<text class="unit">¥</text>
|
||||
<text>{{ item.goods_money | moneyFormat }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-num" v-if="item.goods_class != $util.goodsClassDict.service && item.card_item_id == 0 && item.pricing_type == 'num'">
|
||||
<view class="num-dec" @click.stop="dec(item)">-</view>
|
||||
<view class="num" v-if="item.card_item_id && billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id]">{{ billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id].num }}</view>
|
||||
<view class="num" v-else-if="billingGoodsData['sku_' + item.sku_id]">{{ billingGoodsData['sku_' + item.sku_id].num }}</view>
|
||||
<view class="num" v-else>{{ item.num }}</view>
|
||||
<view class="num-inc" @click.stop="inc(item)">+</view>
|
||||
</view>
|
||||
<view class="item-num weight" v-if="item.goods_class == $util.goodsClassDict.weigh && item.pricing_type == 'weight'">
|
||||
<view class="num" v-if="item.card_item_id && billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id]">
|
||||
{{ billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id].num }}
|
||||
</view>
|
||||
<view class="num" v-else-if="billingGoodsData['sku_' + item.sku_id]">{{ billingGoodsData['sku_' + item.sku_id].num }}</view>
|
||||
<view class="num" v-else>{{ item.num }}</view>
|
||||
<view>{{ item.unit }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-deduction" v-if="item.card_info && Object.keys(item.card_info).length">
|
||||
<text>使用卡项:{{ item.card_info.goods_name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</block>
|
||||
<view class="empty" v-else>
|
||||
<image src="@/static/cashier/cart_empty.png" mode="widthFix"/>
|
||||
<view class="tips">点击右侧商品,选择商品进行结账</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom">
|
||||
<view class="bottom-info">
|
||||
<view class="bottom-left">合计 {{ billingOrderData.goods_num.toFixed(2) }} 件</view>
|
||||
<view class="bottom-right">
|
||||
<text class="pay-money">¥{{ billingOrderData.pay_money | moneyFormat }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom-btn justify-between">
|
||||
<view class="tag-parent">
|
||||
<button class="comp-btn" :class="type == 'order' ? 'primary-btn' : 'default-btn'" @click="hangingOrder">挂/取单</button>
|
||||
<text class="num-tag" v-if="pendOrderNum > 0">{{ pendOrderNum < 100 ? pendOrderNum : '99+' }}</text>
|
||||
</view>
|
||||
<button class="default-btn comp-btn" @click="wholeOrderCancel(true,true)">整单取消</button>
|
||||
<button class="primary-btn btn-right" :disabled="billingOrderData.goods_num == 0" @click="pay('')">结账</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pay-shade" v-show="type == 'pay'"></view>
|
||||
</view>
|
||||
<view class="uni-flex uni-row" style="flex: 1;">
|
||||
<view class="list-wrap flex-1">
|
||||
<!-- 商品 -->
|
||||
<view class="content" v-show="type == 'goods'">
|
||||
<ns-goods @openCashBox="openCashBox" :indexFocus="rightIndexFocus" ref="goods" />
|
||||
</view>
|
||||
|
||||
<view class="content payment-content common-wrap" v-show="type == 'pay'">
|
||||
<ns-payment ref="payment" storeRoute="billing" @cancel="cancelPayment" @success="paySuccess" :outTradeNo="outTradeNo"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选择会员 -->
|
||||
<ns-select-member ref="selectMember" />
|
||||
|
||||
<!-- 会员详情弹出框 -->
|
||||
<ns-member-detail-popup ref="memberDetailPopup" isShowMemberCard/>
|
||||
|
||||
<!-- 挂单弹出框 -->
|
||||
<ns-pend-order-popup ref="pendOrderPopup"/>
|
||||
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import billing from './public/js/billing.js';
|
||||
import nsSelectMember from '@/components/ns-select-member/ns-select-member.vue';
|
||||
import nsMemberDetail from '@/components/ns-member-detail/ns-member-detail.vue';
|
||||
export default {
|
||||
components: {
|
||||
nsSelectMember,
|
||||
nsMemberDetail
|
||||
},
|
||||
mixins: [billing]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/index.scss';
|
||||
</style>
|
||||
<style>
|
||||
.cashregister-header-box>>>.uni-select-lay-select {
|
||||
padding-right: 0.1rem !important;
|
||||
}
|
||||
|
||||
.cashregister-header-box>>>.uni-select-lay-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cashregister-header-box>>>.uni-select-lay-input-close {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
435
addon/cashier/source/os/pages/billing/public/css/index.scss
Executable file
435
addon/cashier/source/os/pages/billing/public/css/index.scss
Executable file
@@ -0,0 +1,435 @@
|
||||
.left-wrap {
|
||||
position: relative;
|
||||
width: 4rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 0.2rem;
|
||||
-ms-flex-negative: 0;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
border-radius: 0.04rem 0.04rem 0 0;
|
||||
.pay-shade {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba($color: #fff, $alpha: 0.6);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.order-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
user-select: none;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
height: 0.3rem;
|
||||
padding: 0 0.1rem 0 0.1rem;
|
||||
box-sizing: border-box;
|
||||
border-radius: 0.02rem;
|
||||
border: 0.01rem solid #e5e5e5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.uni-date {
|
||||
flex: 1;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-date-x {
|
||||
height: 0.28rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.title {
|
||||
font-size: 0.14rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.clear {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text {
|
||||
&:nth-child(1) {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
margin-left: 0.03rem;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-list {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
overflow-y: scroll;
|
||||
padding: 0 0.2rem;
|
||||
.content-head {
|
||||
display: flex;
|
||||
margin: 0.1rem 0;
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
font-size: 0.13rem;
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.content-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: start;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
padding-top: 0.08rem;
|
||||
padding-bottom: 0.08rem;
|
||||
&.focus,
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 0.1rem;
|
||||
flex-wrap: wrap;
|
||||
min-height: 0.6rem;
|
||||
}
|
||||
|
||||
.item-img {
|
||||
width: 0.6rem;
|
||||
height: 0.6rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: 0.14rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 2.04rem;
|
||||
height: 0.20rem;
|
||||
font-weight: 500;
|
||||
color: #222222;
|
||||
line-height: 0.20rem;
|
||||
}
|
||||
|
||||
.item-del {
|
||||
cursor: pointer;
|
||||
font-size: 0.14rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&:hover{
|
||||
color: $primary-color;
|
||||
}
|
||||
.iconfont.iconshanchu{
|
||||
font-size: 0.2rem;
|
||||
}
|
||||
}
|
||||
.item-spe {
|
||||
font-size: 0.12rem;
|
||||
margin-top: 0.04rem;
|
||||
width: 2.04rem;
|
||||
height: 0.17rem;
|
||||
font-weight: 500;
|
||||
color: #808695;
|
||||
line-height: 0.17rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.info-top{
|
||||
width: 100%;
|
||||
}
|
||||
.info-bottom{
|
||||
width: 100%;
|
||||
align-self: flex-end;
|
||||
}
|
||||
.item-price{
|
||||
flex: 1;
|
||||
}
|
||||
.item-subtotal {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
.unit{
|
||||
font-size: 0.12rem;
|
||||
}
|
||||
}
|
||||
.item-num {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-left: 0.1rem;
|
||||
.num-dec {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
background: #e6e6e6;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 30%;
|
||||
text-align: center;
|
||||
line-height: 0.23rem;
|
||||
font-size: 0.25rem;
|
||||
margin-right: 0.1rem;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.num-inc {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
background: $primary-color;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 30%;
|
||||
text-align: center;
|
||||
line-height: 0.23rem;
|
||||
font-size: 0.25rem;
|
||||
margin-left: 0.1rem;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.weight {
|
||||
flex: 1;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.item-total-price {
|
||||
font-size: 0.14rem;
|
||||
margin-left: 0.1rem;
|
||||
color: #fe2278;
|
||||
}
|
||||
.card-deduction {
|
||||
width: 100%;
|
||||
font-size: 0.12rem;
|
||||
margin-top: 0.05rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
|
||||
image {
|
||||
width: 60%;
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
width: 100%;
|
||||
padding:0.2rem 0.2rem 0.24rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
background-color: #ffffff;
|
||||
|
||||
.bottom-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
height: 0.27rem;
|
||||
line-height: 0.27rem;
|
||||
margin-bottom: 0.12rem;
|
||||
.bottom-left {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
.bottom-right {
|
||||
font-size: 0.14rem;
|
||||
.pay-money{
|
||||
font-size: 0.27rem;
|
||||
height: 0.22rem;
|
||||
font-weight: 600;
|
||||
font-family: AlibabaPuHuiTiM;
|
||||
color: $primary-color;
|
||||
line-height: 0.22rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 0.2rem;
|
||||
button{
|
||||
width: 0.98rem;
|
||||
margin: 0 !important;
|
||||
height: 0.40rem;
|
||||
line-height: 0.38rem;
|
||||
border: 0.01rem solid #e6e6e6 !important;
|
||||
&::after{
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover{
|
||||
border:0.01rem solid $primary-color !important;
|
||||
}
|
||||
}
|
||||
.tag-parent {
|
||||
position: relative;
|
||||
|
||||
.num-tag {
|
||||
position: absolute;
|
||||
background-color: #f00;
|
||||
color: #fff;
|
||||
height: 0.18rem;
|
||||
line-height: 0.18rem;
|
||||
padding: 0 0.06rem;
|
||||
border-radius: 0.1rem;
|
||||
font-size: 0.12rem;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
right: 0.12rem;
|
||||
transform: translateY(-50%) translateX(100%);
|
||||
}
|
||||
}
|
||||
.btn-right {
|
||||
width: 1.4rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
border:0 !important;
|
||||
&:hover{
|
||||
border:0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comp-wrap {
|
||||
min-width: 1rem;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 0.02rem;
|
||||
padding: 0.2rem 0.17rem;
|
||||
|
||||
.comp-btn {
|
||||
overflow: initial;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.payment-content {
|
||||
border-left: 0.01rem solid #e6e6e6;
|
||||
padding-left: 0.17rem;
|
||||
}
|
||||
|
||||
.list-wrap {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.comp-btn {
|
||||
width: 80%;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 0.66rem;
|
||||
line-height: 0.66rem;
|
||||
text-align: left;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.page-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.common-wrap {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.remark-wrap {
|
||||
width: 6rem;
|
||||
background-color: #fff;
|
||||
border-radius: 0.04rem;
|
||||
box-shadow: 0 0.01rem 0.12rem 0 rgba(0, 0, 0, 0.1);
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 0.15rem;
|
||||
height: 0.45rem;
|
||||
line-height: 0.45rem;
|
||||
border-bottom: 0.01rem solid #e8eaec;
|
||||
.iconfont {
|
||||
font-size: $uni-font-size-lg;
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 0.15rem 0.15rem 0.1rem;
|
||||
|
||||
textarea {
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
width: 100%;
|
||||
padding: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
.placeholder-class {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
height: 0.5rem;
|
||||
padding-bottom: 0.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
button {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
}
|
||||
730
addon/cashier/source/os/pages/billing/public/js/billing.js
Executable file
730
addon/cashier/source/os/pages/billing/public/js/billing.js
Executable file
@@ -0,0 +1,730 @@
|
||||
import {calculate, create} from '@/api/order_create.js'
|
||||
import {addPendOrder, editPendOrder} from '@/api/pendorder.js'
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
type: 'goods',
|
||||
outTradeNo: '',
|
||||
isRepeat: false,
|
||||
leftIndexFocus: -1, // 左侧订单项 焦点索引
|
||||
rightIndexFocus: -1, // 右侧选择商品 焦点索引
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['billingGoodsData', 'billingOrderData', 'pendOrderNum', 'billingActive', 'billingIsScanTrigger','billingPendOrderId','memberSearchWayConfig'])
|
||||
},
|
||||
watch: {
|
||||
pendOrderNum: function (nVal) {
|
||||
if (nVal == 0) this.type = 'goods';
|
||||
},
|
||||
// 会员发生变化,重新计算价格
|
||||
globalMemberInfo: function (nVal, oVal) {
|
||||
this.calculation();
|
||||
},
|
||||
billingActive(nVal) {
|
||||
if (nVal == 'SelectGoodsAfter') {
|
||||
this.rightIndexFocus = -1; // 选择完商品后,取消选中焦点
|
||||
}
|
||||
},
|
||||
billingGoodsData: {
|
||||
// 每个属性值发生变化就会调用这个函数
|
||||
handler(newVal, oldVal) {
|
||||
this.calculation();
|
||||
},
|
||||
// 深度监听 属性的变化
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
uni.hideTabBar();
|
||||
},
|
||||
onShow() {
|
||||
this.$store.commit('billing/setOrderData', {
|
||||
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
|
||||
});
|
||||
|
||||
// 添加组件的键盘监听事件
|
||||
this.addKeyDownEvent();
|
||||
if (this.$refs.goods) {
|
||||
this.$refs.goods.init();
|
||||
this.$refs.goods.addKeyDownEvent();
|
||||
this.$refs.goods.addScanCodeEvent();
|
||||
}
|
||||
|
||||
if (this.$refs.payment) {
|
||||
this.$refs.payment.addKeyDownEvent();
|
||||
}
|
||||
},
|
||||
onHide() {
|
||||
this.removeKeyDownEvent();
|
||||
|
||||
// 移除组件的键盘监听事件
|
||||
this.$refs.goods.removeKeyDownEvent();
|
||||
this.$refs.goods.removeScanCodeEvent();
|
||||
this.$refs.payment.removeKeyDownEvent();
|
||||
},
|
||||
methods: {
|
||||
switchStoreAfter() {
|
||||
this.wholeOrderCancel(true,true);
|
||||
},
|
||||
openMember() {
|
||||
if (this.$refs.selectMember) {
|
||||
this.$store.commit('billing/setActive', 'ShowMember');
|
||||
this.$refs.selectMember.open(() => {
|
||||
this.$store.commit('billing/setActive', 'ShowMemberAfter');
|
||||
});
|
||||
}
|
||||
},
|
||||
showMember() {
|
||||
this.$store.commit('billing/setActive', 'ShowMember');
|
||||
if (!this.globalMemberInfo) {
|
||||
// 选择会员
|
||||
if (this.$refs.selectMember) this.$refs.selectMember.open(() => {
|
||||
this.$store.commit('billing/setActive', 'ShowMemberAfter');
|
||||
});
|
||||
} else {
|
||||
// 打开会员信息弹出框
|
||||
this.$refs.memberDetailPopup.open();
|
||||
this.$store.commit('billing/setActive', 'ShowMemberAfter');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 切换为散客,清除会员、订单信息
|
||||
*/
|
||||
replaceMember() {
|
||||
this.type = 'goods';
|
||||
this.$store.commit('app/setGlobalMemberInfo', null);
|
||||
this.$store.commit('billing/setOrderData', {
|
||||
goods_num: 0,
|
||||
pay_money: 0,
|
||||
goods_list: [],
|
||||
remark: '',
|
||||
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
|
||||
});
|
||||
},
|
||||
deleteGoods(data) {
|
||||
var _billingGoodsData = this.$util.deepClone(this.billingGoodsData);
|
||||
// 恢复调价
|
||||
if (!data.card_item_id) {
|
||||
for (let i = 0; i < this.$refs.goods.goodsData.list.length; i++) {
|
||||
let item = this.$refs.goods.goodsData.list[i];
|
||||
if (item.sku_id == data.sku_id) {
|
||||
item.adjust_price = item.price;
|
||||
item.adjust = {};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete _billingGoodsData[data.editKey];
|
||||
|
||||
//重组数据
|
||||
var index = 0;
|
||||
let tempGoodsData = {};
|
||||
Object.keys(_billingGoodsData).forEach((key,index) =>{
|
||||
if(_billingGoodsData[key].sku_id == data.sku_id){
|
||||
let key_data = key.split('_');
|
||||
key_data[key_data.length-1] = index;
|
||||
index ++;
|
||||
tempGoodsData[key_data.join('_')] = _billingGoodsData[key];
|
||||
}else{
|
||||
tempGoodsData[key] =_billingGoodsData[key];
|
||||
}
|
||||
});
|
||||
|
||||
let goodsIds = [];
|
||||
|
||||
Object.keys(tempGoodsData).forEach(key => {
|
||||
let item = tempGoodsData[key];
|
||||
if (!item.item_id && goodsIds.indexOf(item.goods_id) == -1) goodsIds.push(item.goods_id);
|
||||
});
|
||||
|
||||
this.$store.commit('billing/setGoodsIds', goodsIds);
|
||||
|
||||
this.$store.commit('billing/setGoodsData', tempGoodsData);
|
||||
|
||||
if (!Object.keys(tempGoodsData).length) {
|
||||
this.$store.commit('billing/setOrderData', {
|
||||
goods_list: [],
|
||||
goods_num: 0,
|
||||
pay_money: 0,
|
||||
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 商品数量增加
|
||||
* @param {Object} data
|
||||
*/
|
||||
inc(data) {
|
||||
var _billingGoodsData = this.$util.deepClone(this.billingGoodsData);
|
||||
if (data.card_item_id) {
|
||||
let _data = _billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id];
|
||||
if (_data.num >= data.stock) {
|
||||
this.$util.showToast({
|
||||
title: '商品库存不足'
|
||||
});
|
||||
return;
|
||||
}
|
||||
_billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id].num += 1;
|
||||
} else {
|
||||
var _data = _billingGoodsData[data.editKey];
|
||||
if (_data.num >= data.stock) {
|
||||
this.$util.showToast({
|
||||
title: '商品库存不足'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
_billingGoodsData[data.editKey].num += 1;
|
||||
}
|
||||
this.$store.commit('billing/setGoodsData', _billingGoodsData);
|
||||
},
|
||||
/**
|
||||
* 商品数量减少
|
||||
* @param {Object} data
|
||||
*/
|
||||
dec(data) {
|
||||
var _billingGoodsData = this.$util.deepClone(this.billingGoodsData);
|
||||
if (data.card_item_id) {
|
||||
let _data = _billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id];
|
||||
if (_data.num == 1) return;
|
||||
|
||||
_billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id].num -= 1;
|
||||
} else {
|
||||
if (_billingGoodsData[data.editKey].num == 1) return;
|
||||
|
||||
_billingGoodsData[data.editKey].num -= 1;
|
||||
}
|
||||
this.$store.commit('billing/setGoodsData', _billingGoodsData);
|
||||
},
|
||||
/**
|
||||
* 计算
|
||||
*/
|
||||
calculation() {
|
||||
if (!Object.keys(this.billingGoodsData).length) {
|
||||
this.$store.commit('billing/setOrderData', {
|
||||
goods_num: 0
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let sku_array = [];
|
||||
let goodsIds = [];
|
||||
let editKeyData = {};
|
||||
|
||||
Object.keys(this.billingGoodsData).forEach(key => {
|
||||
let item = this.billingGoodsData[key];
|
||||
let skuData = {
|
||||
sku_id: item.sku_id,
|
||||
num: item.num,
|
||||
card_item_id: item.item_id ? item.item_id : 0,
|
||||
money: item.money ? item.money : 0 // 无码商品价格
|
||||
};
|
||||
if (item.is_adjust) {
|
||||
skuData.price = item.price; // 手动调整价格
|
||||
}
|
||||
if (item.goods_money) skuData.goods_money = item.goods_money;
|
||||
sku_array.push(skuData);
|
||||
|
||||
if (!item.item_id && goodsIds.indexOf(item.goods_id) == -1) goodsIds.push(item.goods_id);
|
||||
//保存editKey数据
|
||||
let editKeyIndex = skuData.sku_id+':'+skuData.card_item_id;
|
||||
editKeyData[editKeyIndex] = key;
|
||||
});
|
||||
|
||||
this.$store.commit('billing/setGoodsIds', goodsIds);
|
||||
|
||||
let data = {
|
||||
sku_array: JSON.stringify(sku_array),
|
||||
create_time: this.billingOrderData.create_time
|
||||
};
|
||||
if (this.globalMemberInfo) data.member_id = this.globalMemberInfo.member_id;
|
||||
|
||||
calculate(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
let calculateOrderData = res.data;
|
||||
calculateOrderData.goods_list.forEach((item, index) => {
|
||||
let editKeyIndex = item.sku_id+':'+(item.card_item_id||0);
|
||||
item.editKey = editKeyData[editKeyIndex];
|
||||
});
|
||||
|
||||
this.$store.commit('billing/setOrderData', calculateOrderData);
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 挂单
|
||||
*/
|
||||
hangingOrder() {
|
||||
if (Object.keys(this.billingGoodsData).length) {
|
||||
let data = {
|
||||
goods: [],
|
||||
order_id: this.billingPendOrderId,
|
||||
remark: this.billingOrderData.remark
|
||||
};
|
||||
|
||||
if (this.globalMemberInfo) data.member_id = this.globalMemberInfo.member_id;
|
||||
|
||||
Object.keys(this.billingGoodsData).forEach(key => {
|
||||
let item = this.billingGoodsData[key];
|
||||
let skuData = {
|
||||
goods_id: item.goods_id,
|
||||
sku_id: item.sku_id,
|
||||
num: item.num,
|
||||
money: item.money ? item.money : 0 // 无码商品价格
|
||||
};
|
||||
if (item.is_adjust) {
|
||||
skuData.price = item.price; // 手动调整价格
|
||||
}
|
||||
data.goods.push(skuData)
|
||||
});
|
||||
|
||||
data.goods = JSON.stringify(data.goods);
|
||||
|
||||
let api = this.billingPendOrderId ? editPendOrder(data) : addPendOrder(data);
|
||||
api.then(res => {
|
||||
if (res.code == 0) {
|
||||
this.wholeOrderCancel();
|
||||
this.$refs.pendOrderPopup.getOrder(0);
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
})
|
||||
}
|
||||
})
|
||||
} else if (this.pendOrderNum) {
|
||||
this.$refs.pendOrderPopup.open();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: '当前没有挂单'
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 整单取消
|
||||
*/
|
||||
wholeOrderCancel(isInit = false,isDelete = false) {
|
||||
if (Object.keys(this.billingGoodsData).length) {
|
||||
// 恢复调价
|
||||
for (let i = 0; i < this.$refs.goods.goodsData.list.length; i++) {
|
||||
let item = this.$refs.goods.goodsData.list[i];
|
||||
item.adjust_price = item.price;
|
||||
item.adjust = {};
|
||||
}
|
||||
|
||||
// 清除当前会员
|
||||
this.$store.commit('app/setGlobalMemberInfo', null);
|
||||
|
||||
// 清除商品数据
|
||||
this.$store.commit('billing/setGoodsData', {});
|
||||
this.$store.commit('billing/setGoodsIds', []);
|
||||
|
||||
if (isDelete && this.billingPendOrderId) {
|
||||
this.$refs.pendOrderPopup.deleteOrder(this.billingPendOrderId);
|
||||
}
|
||||
this.$store.commit('billing/setPendOrderId',0);
|
||||
|
||||
// 清除订单数据
|
||||
this.$store.commit('billing/setOrderData', {
|
||||
goods_num: 0,
|
||||
pay_money: 0,
|
||||
goods_list: [],
|
||||
remark: '',
|
||||
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000)),
|
||||
order_id: 0
|
||||
});
|
||||
this.outTradeNo = '';
|
||||
} else {
|
||||
if (!isInit) this.$util.showToast({
|
||||
title: '当前没有订单数据!!'
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 支付
|
||||
*/
|
||||
pay(type = '', callback) {
|
||||
const memberId = this.globalMemberInfo ? this.globalMemberInfo.member_id : 0;
|
||||
|
||||
if (this.$refs.payment) this.$refs.payment.clearPay();
|
||||
|
||||
if (!Object.keys(this.billingGoodsData).length || this.isRepeat) return;
|
||||
|
||||
this.isRepeat = true;
|
||||
|
||||
if (this.outTradeNo) {
|
||||
this.type = 'pay';
|
||||
if (type) this.$refs.payment.type = type;
|
||||
return;
|
||||
}
|
||||
|
||||
this.$store.commit('billing/setActive', 'OrderCreate'); // 记录页面活跃值:创建订单
|
||||
|
||||
let data = {
|
||||
remark: this.billingOrderData.remark,
|
||||
create_time: this.billingOrderData.create_time,
|
||||
member_id: memberId,
|
||||
order_key: this.billingOrderData.order_key
|
||||
};
|
||||
|
||||
create(data).then(res => {
|
||||
this.isRepeat = false;
|
||||
if (res.code == 0) {
|
||||
this.outTradeNo = res.data.out_trade_no;
|
||||
this.type = 'pay';
|
||||
if (type) this.$refs.payment.type = type;
|
||||
setTimeout(() => {
|
||||
if (callback) callback();
|
||||
}, 100)
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message,
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
cancelPayment() {
|
||||
this.outTradeNo = '';
|
||||
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
|
||||
this.type = 'goods';
|
||||
},
|
||||
paySuccess() {
|
||||
this.type = 'goods';
|
||||
this.$store.commit('billing/setActive', '');
|
||||
this.isRepeat = false;
|
||||
this.wholeOrderCancel(false,true);
|
||||
this.$refs.goods.getGoods();
|
||||
},
|
||||
// 调整商品价格,数量
|
||||
callBox(data) {
|
||||
//服务商品不支持修改
|
||||
if(data.goods_class == this.$util.goodsClassDict.service) return;
|
||||
if(data.card_item_id > 0) return;
|
||||
data.status = 'edit'; // 调整商品标识
|
||||
this.$refs.goods.goodsSelect(data);
|
||||
},
|
||||
/**
|
||||
* 添加键盘监听事件
|
||||
*/
|
||||
addKeyDownEvent() {
|
||||
// #ifdef H5
|
||||
window.addEventListener("keydown", this.listenerKeyDown, true);
|
||||
|
||||
window.addEventListener("focus", this.listenerFocus, true);
|
||||
|
||||
// 监听F1~F12,BACKSPACE
|
||||
window.POS_HOTKEY_CALLBACK = (control, code) => {
|
||||
this.posHotKeyCallback(code);
|
||||
};
|
||||
// #endif
|
||||
},
|
||||
/**
|
||||
* 移除键盘监听事件
|
||||
*/
|
||||
removeKeyDownEvent() {
|
||||
// #ifdef H5
|
||||
window.removeEventListener("keydown", this.listenerKeyDown, true);
|
||||
|
||||
window.removeEventListener("focus", this.listenerFocus, true);
|
||||
|
||||
delete window.POS_HOTKEY_CALLBACK;
|
||||
// #endif
|
||||
},
|
||||
// 监听焦点事件
|
||||
listenerFocus(e) {
|
||||
if (this.billingActive == 'OrderCreate') return;
|
||||
|
||||
let tab = {
|
||||
// 聚焦 获取商品选择
|
||||
TabGoodsFocus: {
|
||||
className: 'goods-select-focus',
|
||||
focusField: 'rightIndexFocus'
|
||||
},
|
||||
// 聚焦 获取订单结算商品
|
||||
TabOrderFocus: {
|
||||
className: 'settlement-select-focus',
|
||||
focusField: 'leftIndexFocus'
|
||||
}
|
||||
};
|
||||
|
||||
for (let key in tab) {
|
||||
if (e.target.className && e.target.className.indexOf(tab[key].className) != -1) {
|
||||
this.leftIndexFocus = -1;
|
||||
this.rightIndexFocus = -1;
|
||||
for (let i = 0; i < e.target.attributes.length; i++) {
|
||||
var item = e.target.attributes[i];
|
||||
if (item.name == 'data-tab-index') {
|
||||
this[tab[key].focusField] = parseInt(item.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this[tab[key].focusField] > -1) {
|
||||
this.$store.commit('billing/setActive', key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
// 监听键盘按下事件
|
||||
listenerKeyDown(e) {
|
||||
var code = e.code;
|
||||
|
||||
if (code == 'Tab') return;
|
||||
|
||||
// console.log('监听键盘按下事件 KeyDown', this.type, code, this.billingActive, this.billingIsScanTrigger, this.billingOrderData, e);
|
||||
|
||||
// 按键ESC,解除占用
|
||||
if (this.billingIsScanTrigger && code == 'Escape') this.$store.commit('billing/setIsScanTrigger', false);
|
||||
|
||||
// 正在输入商品编码 商品/项目名称
|
||||
if (this.billingActive == 'inputSearchText') return;
|
||||
|
||||
// 关闭商品弹出框
|
||||
if (code == 'Escape' && this.billingActive == 'SelectGoodsSku' && this.type == 'goods') {
|
||||
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.type != 'pay' && this.billingActive != 'SelectGoodsSku' && code == 'KeyM') {
|
||||
// 选择会员,键盘快捷键【M】
|
||||
this.openMember();
|
||||
|
||||
} else if (this.type == 'goods' && code == 'PageUp') {
|
||||
// 切换左侧焦点
|
||||
this.$store.commit('billing/setActive', 'TabOrderFocus');
|
||||
this.leftIndexFocus = 0;
|
||||
this.rightIndexFocus = -1;
|
||||
code = 'ArrowUp';
|
||||
} else if (this.type == 'goods' && code == 'PageDown') {
|
||||
// 切换右侧焦点
|
||||
this.$store.commit('billing/setActive', 'TabGoodsFocus');
|
||||
this.rightIndexFocus = 0;
|
||||
this.leftIndexFocus = -1;
|
||||
code = 'ArrowLeft';
|
||||
} else if (this.billingActive == 'TabGoodsFocus') {
|
||||
// 使用tab键,聚焦选择商品
|
||||
|
||||
this.tabGoodsFocusCallback(code);
|
||||
|
||||
} else if (this.billingActive == 'TabOrderFocus') {
|
||||
// 使用tab键,聚焦获取订单结算商品
|
||||
|
||||
this.tabOrderFocusCallback(code);
|
||||
|
||||
} else if(this.billingActive == 'ShowMember' && this.memberSearchWayConfig.way == 'list'){
|
||||
|
||||
// 按照会员列表进行搜索
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
|
||||
if(this.$refs.selectMember.searchFinish && this.$refs.selectMember.memberId){
|
||||
this.$refs.selectMember.getMemberInfo(this.$refs.selectMember.memberId);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (this.billingActive == 'ShowMemberAfter' || (this.billingOrderData.goods_num && this.billingActive == 'SelectGoodsAfter' && !this.billingIsScanTrigger)) {
|
||||
// 活跃窗口:设置会员后,选择完商品后
|
||||
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
this.pay('');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* 监听键盘事件回调
|
||||
* @param {Object} code
|
||||
*/
|
||||
posHotKeyCallback(code) {
|
||||
// console.log('POS ${code} 按键', code, this.type);
|
||||
|
||||
if (code == 'F2') {
|
||||
// 选择商品
|
||||
|
||||
if (this.type != 'pay') {
|
||||
this.type = 'goods';
|
||||
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
|
||||
}
|
||||
|
||||
} else if (code == 'F3') {
|
||||
// 挂/取单
|
||||
|
||||
if (this.type != 'pay') {
|
||||
this.hangingOrder();
|
||||
}
|
||||
|
||||
} else if (code == 'F4') {
|
||||
// 选择会员
|
||||
|
||||
if (this.type != 'pay') {
|
||||
this.showMember();
|
||||
}
|
||||
|
||||
} else if (code == 'F12') {
|
||||
// 整单取消
|
||||
|
||||
if (this.type != 'pay') {
|
||||
this.wholeOrderCancel(false,true);
|
||||
}
|
||||
|
||||
} else if (code == 'BACKSPACE') {
|
||||
// 退格键
|
||||
|
||||
if (this.billingActive == 'UnnumberedGoods' && this.type == 'goods') {
|
||||
|
||||
if (this.$refs.goods) this.$refs.goods.deleteCode();
|
||||
|
||||
} else if (this.billingActive == 'OrderCreate') {
|
||||
|
||||
if (this.$refs.payment) {
|
||||
if (this.$refs.payment.active == 'OpenMoneyPopup') {
|
||||
this.$refs.payment.deleteCode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (code == 'X') {
|
||||
// 打开钱箱,快捷键:Alt+X
|
||||
this.openCashBox();
|
||||
} else if (this.type == 'goods' && code == 'PAGEUP') {
|
||||
// 切换左侧焦点
|
||||
this.$store.commit('billing/setActive', 'TabOrderFocus');
|
||||
this.leftIndexFocus = 0;
|
||||
this.rightIndexFocus = -1;
|
||||
this.tabOrderFocusCallback('ArrowUp');
|
||||
} else if (this.type == 'goods' && code == 'PAGEDOWN') {
|
||||
// 切换右侧焦点
|
||||
this.$store.commit('billing/setActive', 'TabGoodsFocus');
|
||||
this.rightIndexFocus = 0;
|
||||
this.leftIndexFocus = -1;
|
||||
this.tabGoodsFocusCallback('ArrowLeft');
|
||||
} else {
|
||||
// 触发左侧菜单按键回调
|
||||
this.menuTriggerKeyCodeCallBack(code);
|
||||
}
|
||||
},
|
||||
// 打开钱箱
|
||||
openCashBox() {
|
||||
try {
|
||||
let data = {
|
||||
message: '打开钱箱'
|
||||
};
|
||||
this.$pos.send('OpenCashBox', JSON.stringify(data));
|
||||
} catch (e) {
|
||||
console.log('打开钱箱异常', e)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 使用tab键,聚焦选择商品 事件回调
|
||||
* @param {string} code 按键代码
|
||||
*/
|
||||
tabGoodsFocusCallback(code) {
|
||||
if (!this.$refs.goods) return;
|
||||
|
||||
let list = document.querySelectorAll(`.${this.$refs.goods.type}-focus.table-item`);
|
||||
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
|
||||
if (this.$refs.goods.type == 'goods') {
|
||||
// 添加实物商品
|
||||
this.$refs.goods.goodsSelect(this.$refs.goods.goodsData.list[this.rightIndexFocus]);
|
||||
} else if (this.$refs.goods.type == 'service') {
|
||||
// 添加项目商品
|
||||
this.$refs.goods.goodsSelect(this.$refs.goods.serviceData.list[this.rightIndexFocus]);
|
||||
}
|
||||
|
||||
} else if (code == 'ArrowUp' && this.rightIndexFocus > -1) {
|
||||
|
||||
// 上箭头,商品,goods,项目:service
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select(`.goods-container .list-wrap.${this.$refs.goods.type}`).boundingClientRect(data => {
|
||||
this.rightIndexFocus -= Math.floor(data.width / 270); // 单个元素宽度270
|
||||
|
||||
// 超出,选择第一个
|
||||
if (this.rightIndexFocus <= 0) this.rightIndexFocus = 0;
|
||||
|
||||
list[this.rightIndexFocus].focus();
|
||||
}).exec();
|
||||
|
||||
} else if (code == 'ArrowDown' && this.rightIndexFocus > -1) {
|
||||
|
||||
// 下箭头,商品,goods,项目:service
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select(`.goods-container .list-wrap.${this.$refs.goods.type}`).boundingClientRect(data => {
|
||||
this.rightIndexFocus += Math.floor(data.width / 270); // 单个元素宽度270
|
||||
|
||||
// 超出,选择最后一个
|
||||
if (this.rightIndexFocus >= list.length) this.rightIndexFocus = list.length - 1;
|
||||
|
||||
list[this.rightIndexFocus].focus();
|
||||
}).exec();
|
||||
|
||||
} else if (code == 'ArrowRight' && this.rightIndexFocus > -1) {
|
||||
|
||||
// 右箭头
|
||||
if (this.rightIndexFocus + 1 >= list.length) return;
|
||||
this.rightIndexFocus++;
|
||||
|
||||
list[this.rightIndexFocus].focus();
|
||||
|
||||
} else if (code == 'ArrowLeft' && this.rightIndexFocus > -1) {
|
||||
|
||||
// 左箭头
|
||||
if (this.rightIndexFocus <= 0) return;
|
||||
this.rightIndexFocus--;
|
||||
|
||||
list[this.rightIndexFocus].focus();
|
||||
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 使用tab键,聚焦 获取订单结算商品 事件回调
|
||||
* @param {string} code 按键代码
|
||||
*/
|
||||
tabOrderFocusCallback(code) {
|
||||
// 按键回车,弹框调整商品数量,注意,此时只能修改商品数量,不能更改规格
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
if (this.billingOrderData.goods_list[this.leftIndexFocus]) {
|
||||
let data = this.$util.deepClone(this.billingOrderData.goods_list[this.leftIndexFocus]);
|
||||
data.status = 'edit'; // 修改商品数量标识
|
||||
|
||||
if (this.$refs.goods) this.$refs.goods.goodsSelect(data);
|
||||
}
|
||||
} else if (code == 'ArrowUp' && this.leftIndexFocus > -1) {
|
||||
|
||||
// 上箭头
|
||||
let list = document.querySelectorAll(`.settlement-select-focus`);
|
||||
if (this.leftIndexFocus <= 0) return;
|
||||
this.leftIndexFocus--;
|
||||
list[this.leftIndexFocus].focus();
|
||||
|
||||
} else if (code == 'ArrowDown' && this.leftIndexFocus > -1) {
|
||||
|
||||
// 下箭头
|
||||
let list = document.querySelectorAll(`.settlement-select-focus`);
|
||||
if (this.leftIndexFocus + 1 >= list.length) return;
|
||||
this.leftIndexFocus++;
|
||||
list[this.leftIndexFocus].focus();
|
||||
|
||||
} else if (code == 'Delete' && this.leftIndexFocus > -1) {
|
||||
this.deleteGoods(this.billingOrderData.goods_list[this.leftIndexFocus], this.leftIndexFocus);
|
||||
}
|
||||
},
|
||||
// 恢复焦点下标
|
||||
restoreFocus() {
|
||||
this.leftIndexFocus = -1;
|
||||
this.rightIndexFocus = -1;
|
||||
},
|
||||
leftTabOrderSelectBlur(item){
|
||||
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
|
||||
}
|
||||
},
|
||||
}
|
||||
157
addon/cashier/source/os/pages/buycard/index.vue
Executable file
157
addon/cashier/source/os/pages/buycard/index.vue
Executable file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row page-height">
|
||||
<view class="common-wrap left-wrap">
|
||||
<view class="cashregister-header-box">
|
||||
<view class="order-time">
|
||||
<view class="title">消费时间</view>
|
||||
<uni-datetime-picker v-model="buyCardOrderData.create_time" type="datetime" :clearIcon="false" />
|
||||
</view>
|
||||
<view class="header" v-if="globalMemberInfo">
|
||||
<view class="headimg" @click="showMember">
|
||||
<image class="header-image" :src="globalMemberInfo.headimg ? $util.img(globalMemberInfo.headimg) : $util.img(defaultImg.head)" @error="globalMemberInfo.headimg = defaultImg.head"/>
|
||||
<view v-if="globalMemberInfo.member_level" class="member-nameplate">
|
||||
{{ globalMemberInfo.member_level_name }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="head-info" @click="showMember">
|
||||
<view class="head-info-top">
|
||||
<view class="name">
|
||||
<block v-if="globalMemberInfo.mobile">
|
||||
<view class="mobile">{{ globalMemberInfo.mobile }}</view>
|
||||
<view class="text">
|
||||
<text>(</text>
|
||||
<text class="nickname">{{globalMemberInfo.nickname }}</text>
|
||||
<text>)</text>
|
||||
</view>
|
||||
</block>
|
||||
<text v-else>{{ globalMemberInfo.nickname }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="head-info-bottom point">积分:{{ globalMemberInfo.point }}</view>
|
||||
<view class="head-info-bottom balance">余额:{{ (parseFloat(globalMemberInfo.balance_money) + parseFloat(globalMemberInfo.balance)) | moneyFormat}}</view>
|
||||
</view>
|
||||
|
||||
<button class="switch primary-btn member-open" @click="openMember()">更换会员</button>
|
||||
<button class="switch primary-btn replace-member" @click="replaceMember()">散客</button>
|
||||
</view>
|
||||
<view class="header" v-else>
|
||||
<view class="headimg">
|
||||
<image class="header-image" :src="$util.img(defaultImg.head)" />
|
||||
</view>
|
||||
<view class="head-info">
|
||||
<view class="name">散客</view>
|
||||
</view>
|
||||
<button class="switch primary-btn" @click="openMember()">查询会员</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<!-- <view class="title">
|
||||
<view>结算清单(<text>{{ buyCardOrderData.goods_num }}</text>)</view>
|
||||
<view class="clear" @click="clearGoods">
|
||||
<text class="iconfont iconqingchushujuku"></text>
|
||||
<text>清空</text>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<view class="content-list common-scrollbar">
|
||||
<block v-if="buyCardOrderData.goods_list.length && Object.keys(buyCardGoodsData).length">
|
||||
<view class="content-item" v-for="(item, index) in buyCardOrderData.goods_list" :key="index">
|
||||
<view class="item-img">
|
||||
<image :src="$util.img(item.goods_image.split(',')[0], { size: 'small' })" mode="widthFix"/>
|
||||
</view>
|
||||
<view class="uni-flex flex-1 info-wrap">
|
||||
<view class="info-top">
|
||||
<view class="uni-flex justify-between items-center">
|
||||
<view class="item-name">{{ item.sku_name }}</view>
|
||||
<view class="item-del" @click="deleteGoods(item)">
|
||||
<text class="iconfont iconshanchu"></text>
|
||||
<text>删除</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-spe" v-if="item.spec_name" arrow-down>{{ item.spec_name }}</view>
|
||||
</view>
|
||||
<view class="info-bottom flex justify-between items-center">
|
||||
<view class="item-price">¥{{ item.price | moneyFormat }}</view>
|
||||
<view class="item-num">
|
||||
<view class="num-dec" @click="dec(item)">-</view>
|
||||
<view class="num">{{ buyCardGoodsData['sku_' + item.sku_id].num }}</view>
|
||||
<view class="num-inc" @click="inc(item)">+</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="empty">
|
||||
<image src="@/static/cashier/cart_empty.png" mode="widthFix"/>
|
||||
<view class="tips">点击右侧商品,选择商品进行结账</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom">
|
||||
<view class="bottom-info">
|
||||
<view class="bottom-left">合计 <text>{{ buyCardOrderData.goods_num }}</text> 件</view>
|
||||
<text class="pay-money">¥{{ buyCardOrderData.pay_money | moneyFormat }}</text>
|
||||
</view>
|
||||
<view class="bottom-btn">
|
||||
<button class="primary-btn btn-right" :disabled="buyCardOrderData.goods_num == 0" @click="pay('')">结账</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pay-shade" v-show="type == 'pay'"></view>
|
||||
</view>
|
||||
<view class="uni-flex uni-row" style="flex: 1;">
|
||||
|
||||
<view class="list-wrap flex-1">
|
||||
|
||||
<!-- 卡项商品 -->
|
||||
<view class="content" v-show="type == 'goods'">
|
||||
<ns-card :type="buyCardOrderData.card_type" ref="card"/>
|
||||
</view>
|
||||
|
||||
<view class="content" v-show="type == 'pay'">
|
||||
<ns-payment ref="payment" storeRoute="buycard" @cancel="cancelPayment" @success="paySuccess" :outTradeNo="outTradeNo"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<ns-select-member ref="selectMember"/>
|
||||
|
||||
<!-- 会员详情弹出框 -->
|
||||
<ns-member-detail-popup ref="memberDetailPopup" />
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import buycard from './public/js/buycard.js';
|
||||
import nsSelectMember from '@/components/ns-select-member/ns-select-member.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
nsSelectMember
|
||||
},
|
||||
mixins: [buycard]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/index.scss';
|
||||
</style>
|
||||
<style>
|
||||
.cashregister-header-box>>>.uni-select-lay-select {
|
||||
padding-right: 0.1rem !important;
|
||||
}
|
||||
|
||||
.cashregister-header-box>>>.uni-select-lay-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cashregister-header-box>>>.uni-select-lay-input-close {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
326
addon/cashier/source/os/pages/buycard/public/css/index.scss
Executable file
326
addon/cashier/source/os/pages/buycard/public/css/index.scss
Executable file
@@ -0,0 +1,326 @@
|
||||
.common-wrap.right-wrap{
|
||||
background-color: transparent;
|
||||
}
|
||||
.left-wrap {
|
||||
position: relative;
|
||||
width: 4rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 0.2rem;
|
||||
border-radius: 0.04rem;
|
||||
|
||||
.pay-shade {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba($color: #fff, $alpha: 0.6);
|
||||
z-index: 10;
|
||||
}
|
||||
.content {
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-size: 0.14rem;
|
||||
padding: 0.1rem 0.25rem;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.clear {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
&:nth-child(1) {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-left: 0.03rem;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-list {
|
||||
margin-top: 0.1rem;
|
||||
flex: 1;
|
||||
height: 0;
|
||||
overflow-y: scroll;
|
||||
padding: 0 0.2rem;
|
||||
|
||||
.content-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: start;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
padding-top: 0.08rem;
|
||||
padding-bottom: 0.08rem;
|
||||
|
||||
&.focus,
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 0.1rem;
|
||||
flex-wrap: wrap;
|
||||
min-height: 0.6rem;
|
||||
}
|
||||
|
||||
.item-img {
|
||||
width: 0.6rem;
|
||||
height: 0.6rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: 0.14rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 2.04rem;
|
||||
height: 0.20rem;
|
||||
font-weight: 500;
|
||||
color: #222222;
|
||||
line-height: 0.20rem;
|
||||
}
|
||||
|
||||
.item-del {
|
||||
cursor: pointer;
|
||||
font-size: 0.14rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.iconfont.iconshanchu {
|
||||
font-size: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.item-spe {
|
||||
font-size: 0.12rem;
|
||||
margin-top: 0.04rem;
|
||||
width: 2.04rem;
|
||||
height: 0.17rem;
|
||||
font-weight: 500;
|
||||
color: #808695;
|
||||
line-height: 0.17rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.info-top {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.info-bottom {
|
||||
width: 100%;
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.item-price {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item-subtotal {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
|
||||
.unit {
|
||||
font-size: 0.12rem;
|
||||
}
|
||||
}
|
||||
|
||||
.item-num {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-left: 0.1rem;
|
||||
|
||||
.num {
|
||||
// min-width: 0.82rem;
|
||||
// text-align: right;
|
||||
}
|
||||
|
||||
.num-dec {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
background: #e6e6e6;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 30%;
|
||||
text-align: center;
|
||||
line-height: 0.23rem;
|
||||
font-size: 0.25rem;
|
||||
margin-right: 0.1rem;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.num-inc {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
background: $primary-color;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 30%;
|
||||
text-align: center;
|
||||
line-height: 0.23rem;
|
||||
font-size: 0.25rem;
|
||||
margin-left: 0.1rem;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.weight {
|
||||
flex: 1;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.item-total-price {
|
||||
font-size: 0.14rem;
|
||||
margin-left: 0.1rem;
|
||||
color: #fe2278;
|
||||
}
|
||||
|
||||
.card-deduction {
|
||||
width: 100%;
|
||||
font-size: 0.12rem;
|
||||
margin-top: 0.05rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
|
||||
image {
|
||||
width: 60%;
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
width: 100%;
|
||||
padding: 0.2rem 0.2rem 0.24rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
background-color: #ffffff;
|
||||
|
||||
.bottom-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
height: 0.27rem;
|
||||
line-height: 0.27rem;
|
||||
margin-bottom: 0.12rem;
|
||||
|
||||
.bottom-left {
|
||||
font-size: 0.14rem;
|
||||
color: #303133;
|
||||
text{
|
||||
display: inline-block;
|
||||
margin: 0 .05rem;
|
||||
}
|
||||
|
||||
.money {
|
||||
color: #fe2278;
|
||||
}
|
||||
}
|
||||
.pay-money {
|
||||
font-size: 0.27rem;
|
||||
height: 0.27rem;
|
||||
font-weight: 600;
|
||||
font-family: AlibabaPuHuiTiM;
|
||||
color: $primary-color;
|
||||
line-height: 0.22rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bottom-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 0.2rem;
|
||||
justify-content: flex-end;
|
||||
|
||||
.btn-right {
|
||||
width: 1.4rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
border: 0 !important;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-wrap {
|
||||
border-radius: 0.02rem;
|
||||
height: 100%;
|
||||
border-left: 0;
|
||||
box-sizing: border-box;
|
||||
flex:1;
|
||||
|
||||
.content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.comp-btn {
|
||||
width: 80%;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 0.66rem;
|
||||
line-height: 0.66rem;
|
||||
text-align: left;
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.page-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.common-wrap {
|
||||
height: 100%;
|
||||
}
|
||||
346
addon/cashier/source/os/pages/buycard/public/js/buycard.js
Executable file
346
addon/cashier/source/os/pages/buycard/public/js/buycard.js
Executable file
@@ -0,0 +1,346 @@
|
||||
import {cardCalculate, cardCreate} from '@/api/order_create.js'
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
type: 'goods',
|
||||
isRepeat: false,
|
||||
outTradeNo: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['buyCardGoodsData', 'buyCardOrderData', 'buyCardActive', 'memberSearchWayConfig'])
|
||||
},
|
||||
watch: {
|
||||
globalMemberInfo: function (nVal) {
|
||||
this.calculation();
|
||||
},
|
||||
buyCardGoodsData: {
|
||||
// 每个属性值发生变化就会调用这个函数
|
||||
handler(newVal, oldVal) {
|
||||
this.calculation();
|
||||
},
|
||||
// 深度监听 属性的变化
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
uni.hideTabBar();
|
||||
this.$store.commit('buycard/setOrderData', {
|
||||
card_type: option.type || 'oncecard'
|
||||
});
|
||||
if (this.globalMemberInfo) this.type = 'goods';
|
||||
},
|
||||
onShow() {
|
||||
this.$store.commit('buycard/setOrderData', {
|
||||
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
|
||||
});
|
||||
|
||||
if (this.$refs.card) this.$refs.card.init();
|
||||
|
||||
this.calculation();
|
||||
|
||||
this.addKeyDownEvent();
|
||||
|
||||
// 添加组件的键盘监听事件
|
||||
if (this.$refs.payment) this.$refs.payment.addKeyDownEvent();
|
||||
},
|
||||
onHide() {
|
||||
this.removeKeyDownEvent();
|
||||
|
||||
// 移除组件的键盘监听事件
|
||||
this.$refs.payment.removeKeyDownEvent();
|
||||
},
|
||||
methods: {
|
||||
switchStoreAfter() {
|
||||
if (this.$refs.card) this.$refs.card.init();
|
||||
this.calculation();
|
||||
},
|
||||
openMember() {
|
||||
if (this.$refs.selectMember) {
|
||||
this.$store.commit('buycard/setActive', 'ShowMember');
|
||||
this.$refs.selectMember.open(() => {
|
||||
this.$store.commit('buycard/setActive', 'ShowMemberAfter');
|
||||
});
|
||||
}
|
||||
},
|
||||
showMember() {
|
||||
this.$store.commit('buycard/setActive', 'ShowMember');
|
||||
if (!this.globalMemberInfo) {
|
||||
if (this.$refs.selectMember) this.$refs.selectMember.open(() => {
|
||||
this.$store.commit('buycard/setActive', 'ShowMemberAfter');
|
||||
});
|
||||
} else {
|
||||
// 打开会员信息弹出框
|
||||
this.$store.commit('buycard/setActive', 'ShowMemberAfter');
|
||||
this.$refs.memberDetailPopup.open();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 切换散客
|
||||
*/
|
||||
replaceMember() {
|
||||
this.$store.commit('app/setGlobalMemberInfo', null);
|
||||
this.type = 'goods';
|
||||
},
|
||||
calculation() {
|
||||
if (!Object.keys(this.buyCardGoodsData).length) return;
|
||||
let sku_array = [];
|
||||
Object.keys(this.buyCardGoodsData).forEach(key => {
|
||||
let item = this.buyCardGoodsData[key];
|
||||
sku_array.push({
|
||||
sku_id: item.sku_id,
|
||||
num: item.num
|
||||
});
|
||||
});
|
||||
let data = {
|
||||
sku_array: JSON.stringify(sku_array),
|
||||
create_time: this.buyCardOrderData.create_time
|
||||
};
|
||||
if (this.globalMemberInfo) data.member_id = this.globalMemberInfo.member_id;
|
||||
cardCalculate(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$store.commit('buycard/setOrderData', res.data);
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
inc(data) {
|
||||
let _buyCardGoodsData = this.$util.deepClone(this.buyCardGoodsData);
|
||||
|
||||
if (data.goods_type != '') {
|
||||
_buyCardGoodsData['sku_' + data.sku_id].num += 1;
|
||||
} else {
|
||||
if (data.num < data.stock) _buyCardGoodsData['sku_' + data.sku_id].num += 1;
|
||||
}
|
||||
this.$store.commit('buycard/setGoodsData', _buyCardGoodsData);
|
||||
},
|
||||
dec(data) {
|
||||
if (data.num > 1) {
|
||||
let _buyCardGoodsData = this.$util.deepClone(this.buyCardGoodsData);
|
||||
_buyCardGoodsData['sku_' + data.sku_id].num -= 1;
|
||||
this.$store.commit('buycard/setGoodsData', _buyCardGoodsData);
|
||||
}
|
||||
},
|
||||
deleteGoods(data) {
|
||||
let _buyCardGoodsData = this.$util.deepClone(this.buyCardGoodsData);
|
||||
|
||||
delete _buyCardGoodsData['sku_' + data.sku_id];
|
||||
this.$store.commit('buycard/setGoodsData', _buyCardGoodsData);
|
||||
|
||||
if (!Object.keys(_buyCardGoodsData).length) {
|
||||
this.$store.commit('buycard/setOrderData', {
|
||||
goods_list: [],
|
||||
goods_num: 0,
|
||||
pay_money: 0
|
||||
});
|
||||
}
|
||||
},
|
||||
clearGoods() {
|
||||
this.$store.commit('buycard/setGoodsData', {});
|
||||
this.$store.commit('buycard/setOrderData', {
|
||||
goods_list: [],
|
||||
goods_num: 0,
|
||||
pay_money: 0
|
||||
});
|
||||
},
|
||||
pay(type = '', callback) {
|
||||
if (!this.globalMemberInfo) {
|
||||
if (this.$refs.selectMember) {
|
||||
this.$store.commit('buycard/setActive', 'ShowMember');
|
||||
this.$refs.selectMember.open(() => {
|
||||
this.$store.commit('buycard/setActive', 'ShowMemberAfter');
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.$refs.selectMember.inputFocus = true;
|
||||
}, 200);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Object.keys(this.buyCardGoodsData).length || this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
|
||||
if (this.outTradeNo) {
|
||||
this.type = 'pay';
|
||||
if (type) this.$refs.payment.type = type;
|
||||
return;
|
||||
}
|
||||
|
||||
this.$store.commit('buycard/setActive', 'OrderCreate'); // 记录页面活跃值:创建订单
|
||||
|
||||
let sku_array = [];
|
||||
Object.keys(this.buyCardGoodsData).forEach(key => {
|
||||
let item = this.buyCardGoodsData[key];
|
||||
sku_array.push({
|
||||
sku_id: item.sku_id,
|
||||
num: item.num
|
||||
});
|
||||
});
|
||||
let data = {
|
||||
sku_array: JSON.stringify(sku_array),
|
||||
remark: this.buyCardOrderData.remark,
|
||||
create_time: this.buyCardOrderData.create_time,
|
||||
order_key: this.buyCardOrderData.order_key
|
||||
};
|
||||
if (this.globalMemberInfo) data.member_id = this.globalMemberInfo.member_id;
|
||||
cardCreate(data).then(res => {
|
||||
this.isRepeat = false;
|
||||
if (res.code == 0) {
|
||||
this.outTradeNo = res.data.out_trade_no;
|
||||
this.type = 'pay';
|
||||
if (type) this.$refs.payment.type = type;
|
||||
setTimeout(() => {
|
||||
if (callback) callback();
|
||||
}, 100)
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
cancelPayment() {
|
||||
this.outTradeNo = '';
|
||||
this.type = 'goods';
|
||||
},
|
||||
paySuccess() {
|
||||
this.type = 'goods';
|
||||
this.isRepeat = false;
|
||||
this.$store.commit('buycard/setActive', '');
|
||||
this.wholeOrderCancel();
|
||||
this.$refs.card.onceCardData.page = 0;
|
||||
this.$refs.card.onceCardData.total = 1;
|
||||
this.$refs.card.timeCardData.page = 0;
|
||||
this.$refs.card.timeCardData.total = 1;
|
||||
this.$refs.card.commonCardData.page = 0;
|
||||
this.$refs.card.commonCardData.total = 1;
|
||||
this.$refs.card.getOnceCard();
|
||||
this.$refs.card.getTimeCard();
|
||||
this.$refs.card.getCommonCard();
|
||||
},
|
||||
/**
|
||||
* 整单取消
|
||||
*/
|
||||
wholeOrderCancel() {
|
||||
if (Object.keys(this.buyCardGoodsData).length) {
|
||||
// 清除商品数据
|
||||
this.$store.commit('buycard/setGoodsData', {});
|
||||
let orderId = this.billingOrderData && (this.billingOrderData.order_id ? this.billingOrderData.order_id : 0) || 0
|
||||
|
||||
// 清除订单数据
|
||||
this.$store.commit('buycard/setOrderData', {
|
||||
goods_num: 0,
|
||||
pay_money: 0,
|
||||
goods_list: [],
|
||||
remark: '',
|
||||
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000)),
|
||||
order_id: orderId
|
||||
});
|
||||
this.outTradeNo = '';
|
||||
}
|
||||
},
|
||||
toGoods() {
|
||||
this.type = 'goods';
|
||||
},
|
||||
/**
|
||||
* 添加键盘监听事件
|
||||
*/
|
||||
addKeyDownEvent() {
|
||||
// #ifdef H5
|
||||
// 绑定监听事件
|
||||
window.addEventListener("keydown", this.listenerKeyDown, true);
|
||||
|
||||
// 监听F1~F12,BACKSPACE
|
||||
window.POS_HOTKEY_CALLBACK = (control, code) => {
|
||||
this.posHotKeyCallback(code);
|
||||
};
|
||||
// #endif
|
||||
},
|
||||
/**
|
||||
* 移除键盘监听事件
|
||||
*/
|
||||
removeKeyDownEvent() {
|
||||
// #ifdef H5
|
||||
window.removeEventListener("keydown", this.listenerKeyDown, true);
|
||||
|
||||
delete window.POS_HOTKEY_CALLBACK;
|
||||
// #endif
|
||||
},
|
||||
listenerKeyDown(e) {
|
||||
var code = e.code;
|
||||
|
||||
// console.log('KeyDown', this.type, code, this.buyCardActive, e);
|
||||
|
||||
if (this.type != 'pay' && code == 'KeyM') {
|
||||
// 选择会员,键盘快捷键【M】
|
||||
this.openMember();
|
||||
|
||||
} else if(this.buyCardActive == 'ShowMember' && this.memberSearchWayConfig.way == 'list'){
|
||||
|
||||
// 按照会员列表进行搜索
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
|
||||
if(this.$refs.selectMember.searchFinish && this.$refs.selectMember.memberId){
|
||||
this.$refs.selectMember.getMemberInfo(this.$refs.selectMember.memberId);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (this.buyCardActive == 'ShowMemberAfter') {
|
||||
// 活跃窗口:设置会员后
|
||||
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
this.pay('');
|
||||
}
|
||||
|
||||
} else if (this.buyCardOrderData.goods_num && this.buyCardActive == 'SelectGoodsAfter') {
|
||||
// 选择卡项商品后
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
this.pay('');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* 监听键盘事件回调
|
||||
* @param {Object} code
|
||||
*/
|
||||
posHotKeyCallback(code) {
|
||||
if (code == 'F2') {
|
||||
// 选择卡项
|
||||
|
||||
if (this.type != 'pay') {
|
||||
this.toGoods();
|
||||
this.$store.commit('buycard/setActive', 'SelectGoodsAfter');
|
||||
}
|
||||
|
||||
} else if (code == 'F3') {
|
||||
// 选择会员
|
||||
|
||||
if (this.type != 'pay') {
|
||||
this.showMember();
|
||||
}
|
||||
|
||||
} else if (code == 'BACKSPACE') {
|
||||
// 退格键
|
||||
|
||||
if (this.buyCardActive == 'OrderCreate') {
|
||||
if (this.$refs.payment) {
|
||||
if (this.$refs.payment.active == 'openMoneyPopup') {
|
||||
this.$refs.payment.deleteCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// 触发左侧菜单按键回调
|
||||
this.menuTriggerKeyCodeCallBack(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
229
addon/cashier/source/os/pages/collectmoney/config.vue
Executable file
229
addon/cashier/source/os/pages/collectmoney/config.vue
Executable file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="collect-money-config">
|
||||
<view class="common-wrap common-form fixd common-scrollbar">
|
||||
<view class="common-title">收款设置</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">优惠减现</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="config.reduction = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="config.reduction == 1" />
|
||||
启用
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="config.reduction == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">积分抵扣</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="config.point = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="config.point == 1" />
|
||||
启用
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="config.point == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">积分抵扣需要平台开启,同时配置积分抵扣金额比率</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">使用余额</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="config.balance = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="config.balance == 1" />
|
||||
启用
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="config.balance == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view v-show="config.balance == 1">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">余额使用安全验证</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="config.balance_safe = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="config.balance_safe == 1" />
|
||||
启用
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="config.balance_safe == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">关闭之后直接使用余额进行抵扣,无需会员验证</text>
|
||||
</view>
|
||||
<view class="common-form-item" v-show="config.balance_safe == 1">
|
||||
<label class="form-label">手机号验证</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="config.sms_verify = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="config.sms_verify == 1" />
|
||||
启用
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="config.sms_verify == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">使用余额安全验证时是否可以使用短信验证码验证</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">收款方式</label>
|
||||
<view class="form-inline">
|
||||
<checkbox-group class="form-checkbox-group" @change="config.pay_type = $event.detail.value">
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="third" :checked="config.pay_type.indexOf('third') != -1" />
|
||||
付款码支付
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="cash" :checked="config.pay_type.indexOf('cash') != -1" />
|
||||
现金支付
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="own_wechatpay" :checked="config.pay_type.indexOf('own_wechatpay') != -1" />
|
||||
个人微信
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="own_alipay" :checked="config.pay_type.indexOf('own_alipay') != -1" />
|
||||
个人支付宝
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="own_pos" :checked="config.pay_type.indexOf('own_pos') != -1" />
|
||||
个人POS刷卡
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">付款码支付:扫描会员微信或支付宝付款码进行收款</text>
|
||||
</view>
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="saveFn">保存</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCollectMoneyConfig, setCollectMoneyConfig } from '@/api/config.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config: {
|
||||
reduction: 1,
|
||||
point: 1,
|
||||
balance: 1,
|
||||
balance_safe: 0,
|
||||
sms_verify: 0,
|
||||
pay_type: ['third', 'cash', 'own_wechatpay', 'own_alipay', 'own_pos']
|
||||
},
|
||||
isRepeat: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getData();
|
||||
},
|
||||
onShow() { },
|
||||
methods: {
|
||||
getData() {
|
||||
getCollectMoneyConfig().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.config = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
saveFn() {
|
||||
if (!this.config.pay_type.length) {
|
||||
this.$util.showToast({ title: '至少需启用一种收款方式' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
|
||||
let data = this.$util.deepClone(this.config);
|
||||
data.pay_type = JSON.stringify(data.pay_type);
|
||||
|
||||
setCollectMoneyConfig(data).then(res => {
|
||||
this.isRepeat = false;
|
||||
if (res.code >= 0) {
|
||||
this.$util.showToast({
|
||||
title: '设置成功'
|
||||
});
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.collect-money-config {
|
||||
position: relative;
|
||||
|
||||
.common-btn-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
|
||||
.screen-btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.common-wrap.fixd {
|
||||
padding: 30rpx;
|
||||
height: calc(100vh - 0.4rem);
|
||||
overflow-y: auto;
|
||||
// padding-bottom: 1rem !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.form-input-inline.btn {
|
||||
height: 0.37rem;
|
||||
line-height: 0.35rem;
|
||||
box-sizing: border-box;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.common-form .common-form-item .form-label {
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.common-form .common-form-item .form-word-aux-line {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
221
addon/cashier/source/os/pages/goods/goodslist.vue
Executable file
221
addon/cashier/source/os/pages/goods/goodslist.vue
Executable file
@@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goods-list">
|
||||
<view class="screen-warp common-form">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline">
|
||||
<label class="form-label">商品名称</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="option.search_text" placeholder="请输入商品名称" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">商品编码</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="option.sku_no" placeholder="请输入商品编码" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">商品类型</label>
|
||||
<view class="form-input-inline">
|
||||
<select-lay :zindex="10" :value="goods_class" name="goods_class" placeholder="请选择商品类型" :options="goodsClass" @selectitem="selectClass"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">商品状态</label>
|
||||
<view class="form-input-inline">
|
||||
<select-lay :zindex="10" :value="status" name="status" placeholder="请选择商品状态" :options="statusList" @selectitem="selectStatus"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">商品价格</label>
|
||||
<view class="form-input-inline input-append">
|
||||
<input type="text" v-model="option.start_price" placeholder="最低价格" class="form-input" />
|
||||
<view class="unit">元</view>
|
||||
</view>
|
||||
<view class="form-input-inline split-wrap">-</view>
|
||||
<view class="form-input-inline input-append">
|
||||
<input type="text" v-model="option.end_price" placeholder="最高价格" class="form-input" />
|
||||
<view class="unit">元</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="searchFn()">筛选</button>
|
||||
<button type="default" @click="resetFn()">重置</button>
|
||||
<button type="default" class="screen-btn" @click="printPriceTag()">打印价格标签</button>
|
||||
<button type="default" class="screen-btn" @click="synchronous()" v-if="syncWeighGoods">同步称重商品</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uniDataTable url="/cashier/storeapi/goods/page" :option="option" :cols="cols" ref="goodsListTable">
|
||||
<template v-slot:action="dataTable">
|
||||
<view class="action-btn-wrap">
|
||||
<text class="action-item" @click="getDetail(dataTable.value.goods_id)">详情</text>
|
||||
<text class="action-item" v-if="dataTable.value.store_status == 0 || dataTable.value.store_status == null" @click="goodsStatus(dataTable.value.goods_id, 1)">上架</text>
|
||||
<text class="action-item" v-else @click="goodsStatus(dataTable.value.goods_id, 0)">下架</text>
|
||||
<text class="action-item" @click="goodsSku(dataTable.value.goods_id)" v-if="(globalStoreInfo.stock_type == 'store') || dataTable.value.is_unify_price != 1">价格库存</text>
|
||||
<text class="action-item" @click="isDeliveryRestrictions(dataTable.value.goods_id)" v-if="dataTable.value.goods_class == 1">
|
||||
限制起送
|
||||
</text>
|
||||
<text class="action-item" @click="recordopen(dataTable.value.goods_id)" v-if="dataTable.value.is_virtual != 1 && globalStoreInfo.stock_type == 'store'">库存记录</text>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:batchaction="dataTable">
|
||||
<text class="batch-item" @click="goodsStatus(dataTable, 1)">批量上架</text>
|
||||
<text class="batch-item" @click="goodsStatus(dataTable, 0)">批量下架</text>
|
||||
</template>
|
||||
</uniDataTable>
|
||||
|
||||
<unipopup ref="goodsDetail" type="center" :pagesize="9">
|
||||
<view class="goods-detail-wrap">
|
||||
<view class="detail-head">
|
||||
商品详情
|
||||
<text class="iconfont iconguanbi1" @click="$refs.goodsDetail.close()"></text>
|
||||
</view>
|
||||
<view class="detail-body">
|
||||
<block v-if="goodsDetail">
|
||||
<view class="title">基本信息</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>商品名称:</view>
|
||||
<view>{{ goodsDetail.goods_name }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="goodsDetail.introduction">
|
||||
<view>促销语:</view>
|
||||
<view>{{ goodsDetail.introduction }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>商品类型:</view>
|
||||
<view>{{ goodsDetail.goods_class_name }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="goodsDetail.brand_name">
|
||||
<view>商品品牌:</view>
|
||||
<view>{{ goodsDetail.brand_name }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="goodsDetail.unit">
|
||||
<view>单位:</view>
|
||||
<view>{{ goodsDetail.unit }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="goodsDetail.goods_class == 6">
|
||||
<view>计价方式:</view>
|
||||
<view>{{ goodsDetail.pricing_type == 'num' ? '计数' : '计重' }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>商品状态:</view>
|
||||
<view>
|
||||
{{ goodsDetail.store_status == 0 || goodsDetail.store_status == null ? '仓库中' : '已上架' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="goodsDetail.sku_list.length > 1">
|
||||
<view class="title title2">价格库存</view>
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:30%">商品规格</view>
|
||||
<block v-if="goodsDetail.is_unify_price">
|
||||
<view class="table-td" style="width:20%">销售价格</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="table-td" style="width:15%">统一价格</view>
|
||||
<view class="table-td" style="width:15%">独立价格</view>
|
||||
</block>
|
||||
<view class="table-td" style="width:20%;">商品编码</view>
|
||||
<view class="table-td table-group" style="width:15%;">
|
||||
<text>商品库存</text>
|
||||
<text title="商品库存指下单扣减后的剩余库存" class="iconfont iconwenhao"></text>
|
||||
</view>
|
||||
<view class="table-td table-group" style="width:15%;">
|
||||
<text>实际库存</text>
|
||||
<text title="实际库存指实际发货后的剩余库存" class="iconfont iconwenhao"></text>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view class="table-tb" scroll-y="true">
|
||||
<view class="table-tr table-all" v-for="(item, index) in goodsDetail.sku_list" :key="index">
|
||||
<view class="table-td" style="width:30%">{{ item.spec_name }}</view>
|
||||
<block v-if="goodsDetail.is_unify_price">
|
||||
<view class="table-td" style="width:20%">¥{{ item.discount_price }}</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="table-td" style="width:15%">¥{{ item.discount_price }}</view>
|
||||
<view class="table-td" style="width:15%">¥{{ item.store_price }}</view>
|
||||
</block>
|
||||
<view class="table-td" style="width:20%;">{{ item.sku_no }}</view>
|
||||
<view class="table-td" style="width:15%;">{{ item.stock }}</view>
|
||||
<view class="table-td" style="width:15%;">{{ item.real_stock }}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="title title2">规格详情</view>
|
||||
<view class="table">
|
||||
<view class="single-specification">
|
||||
<view class="item">
|
||||
<view class="name">商品售价:</view>
|
||||
<view class="message" v-if="goodsDetail.is_unify_price == 1 || goodsDetail.sku_list[0].store_price == null">¥{{ goodsDetail.sku_list[0].discount_price }}</view>
|
||||
<view class="message" v-else>{{ goodsDetail.sku_list[0].store_price }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="name">商品编码:</view>
|
||||
<view class="message">{{ goodsDetail.sku_list[0].sku_no ? goodsDetail.sku_list[0].sku_no : '无' }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="name">商品库存:</view>
|
||||
<view class="message">{{ goodsDetail.sku_list[0].stock || 0 }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="name">实际库存:</view>
|
||||
<view class="message">{{ goodsDetail.sku_list[0].real_stock || 0 }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image class="cart-empty" src="@/static/cashier/cart_empty.png" mode="widthFix"/>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<unipopup ref="goodsSku" type="center">
|
||||
<view class="record-body">
|
||||
<ns-goods-sku :disabled="disabled" v-if="skuList.length&&goodsDetail" :isUnifyPrice="goodsDetail.is_unify_price" :skuList="skuList" @close="close('goodsSku')" />
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<unipopup ref="record" type="center">
|
||||
<view class="record-body">
|
||||
<ns-goods-sku-stock-record @close="close('record')" :goodsId="goodsId"/>
|
||||
</view>
|
||||
</unipopup>
|
||||
</view>
|
||||
<ns-scale-goods ref="scaleGoods"/>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniDataTable from '@/components/uni-data-table/uni-data-table.vue';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
import nsGoodsSkuStockRecord from '@/components/ns-goods-sku-stock-record/ns-goods-sku-stock-record.vue';
|
||||
import nsGoodsSku from '@/components/ns-goods-sku/ns-goods-sku.vue';
|
||||
import nsScaleGoods from '@/components/ns-scale-goods/ns-scale-goods.vue';
|
||||
import goodsList from './public/js/goods_list.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup,
|
||||
nsGoodsSkuStockRecord,
|
||||
nsGoodsSku,
|
||||
uniDataTable,
|
||||
nsScaleGoods,
|
||||
},
|
||||
mixins: [goodsList]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/goods_list.scss';
|
||||
</style>
|
||||
89
addon/cashier/source/os/pages/goods/print_price_tag.vue
Executable file
89
addon/cashier/source/os/pages/goods/print_price_tag.vue
Executable file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="stock-body">
|
||||
<view class="content-wrap" @click="goodsShow = false">
|
||||
<view class="title-back flex items-center cursor-pointer" @click="backFn">
|
||||
<text class="iconfont iconqianhou1"></text>
|
||||
<text class="left">返回</text>
|
||||
<text class="content">|</text>
|
||||
<text>打印价格标签</text>
|
||||
</view>
|
||||
<view class="batch-action" v-if="editPrintNum.show == false">
|
||||
<text class="batch-item" @click="openSelectGoodsDialog()">选择商品</text>
|
||||
<text class="batch-item" @click="batchDeleteGoods()">批量删除</text>
|
||||
<!-- <text class="batch-item" @click="editPrintNumShow()">批量设置打印份数</text> -->
|
||||
</view>
|
||||
<view class="screen-warp common-form" v-if="editPrintNum.show == true">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline">
|
||||
<view class="form-input-inline">
|
||||
<input type="digit" placeholder="请输入打印份数" class="form-input" v-model="editPrintNum.value"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="editPrintNumConfirm">确定</button>
|
||||
<button type="default" @click="editPrintNum.show = false">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-wrap">
|
||||
<view class="table-head">
|
||||
<view class="table-tr">
|
||||
<view class="table-th" >
|
||||
<text class="iconfont" :class="allSelected === true ? selectedIcon : (allSelected == 'harf' ? harfselectedIcon : unselectedIcon)" @click="changeGoodsAllSelected()"></text>
|
||||
</view>
|
||||
<!-- <view class="table-th" style="flex: 0.5;">打印份数</view> -->
|
||||
<view class="table-th" style="flex: 3;">商品名称</view>
|
||||
<view class="table-th" style="flex: 1;">条码</view>
|
||||
<view class="table-th" style="flex: 1;">划线价</view>
|
||||
<view class="table-th" style="flex: 1;">售价</view>
|
||||
<view class="table-th" style="flex: 1;">单位</view>
|
||||
<view class="table-th" style="flex: 1;">重量</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-body">
|
||||
<block v-for="(item, index) in goodsList" :key="index">
|
||||
<view class="table-tr">
|
||||
<view class="table-td" >
|
||||
<text class="iconfont" :class="item.selected? selectedIcon : unselectedIcon" @click="changeGoodsSelected(index)"></text>
|
||||
</view>
|
||||
<!-- <view class="table-td" style="flex: 0.5;">{{ item.print_num }}</view> -->
|
||||
<view class="table-td goods-name" style="flex: 3;">{{ item.sku_name }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.sku_no }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.market_price }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.price }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.unit }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.weight }}</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="table-tr table-empty" v-if="!goodsList.length">暂无数据,请选择商品数据</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="action-wrap">
|
||||
<view class="table-total">合计:共 {{ goodsList.length }} 种商品</view>
|
||||
<view class="btn-wrap">
|
||||
<button type="default" class="stockout-btn" @click="designFn" :loading="isSubmit">设计模板</button>
|
||||
<button type="default" class="stockout-btn" @click="printFn" :loading="isSubmit">打印</button>
|
||||
<button type="default" class="stockout-btn" @click="exportFn" :loading="isSubmit">导出</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<goods-sku-select v-model="dialogVisible" :params="dialogParams" apiType="sku" :goodsClass="[1,6]" @selectGoods="selectGoodsComplete" />
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import printPriceTag from "./public/js/print_price_tag.js"
|
||||
import goodsSkuSelect from '@/components/ns-goods-sku-select/ns-goods-sku-select.vue';
|
||||
export default {
|
||||
components: {
|
||||
goodsSkuSelect
|
||||
},
|
||||
mixins: [printPriceTag]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/print_price_tag.scss';
|
||||
</style>
|
||||
312
addon/cashier/source/os/pages/goods/public/css/goods_list.scss
Executable file
312
addon/cashier/source/os/pages/goods/public/css/goods_list.scss
Executable file
@@ -0,0 +1,312 @@
|
||||
view {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
|
||||
.record-body {
|
||||
width: 10rem;
|
||||
min-height: 7rem;
|
||||
}
|
||||
|
||||
// 筛选面板
|
||||
.screen-warp {
|
||||
padding: 0.15rem 0.15rem 0;
|
||||
background-color: #f2f3f5;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
.common-form-item .form-label {
|
||||
width: 1.2rem;
|
||||
}
|
||||
|
||||
.common-btn-wrap {
|
||||
margin-left: 1.2rem;
|
||||
button{
|
||||
margin-right: .1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-category .form-input-inline {
|
||||
width: 2.8rem;
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
|
||||
.common-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.input-append {
|
||||
position: relative;
|
||||
|
||||
.form-input {
|
||||
padding-right: 0.3rem;
|
||||
}
|
||||
|
||||
.unit {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0.1rem;
|
||||
height: 0.35rem;
|
||||
line-height: 0.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-input-inline.split-wrap {
|
||||
width: initial;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
display: block;
|
||||
width: 100%;
|
||||
@extend %body-overhide;
|
||||
padding: 0.15rem 0.15rem 0;
|
||||
background-color: #fff;
|
||||
|
||||
/deep/ .goods-content {
|
||||
display: flex;
|
||||
|
||||
.goods-img {
|
||||
margin-right: 0.1rem;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
min-width: 0.5rem;
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
white-space: pre-wrap;
|
||||
align-self: baseline;
|
||||
}
|
||||
.infos{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.spec-name{
|
||||
margin-top: 0.03rem;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn-wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.action-item {
|
||||
margin-right: 0.1rem;
|
||||
margin-top: 0.03rem;
|
||||
margin-bottom: 0.03rem;
|
||||
color: $primary-color;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .batch-action {
|
||||
.batch-item {
|
||||
margin-right: 0.15rem;
|
||||
border: 0.01rem solid rgba(0, 0, 0, 0.2);
|
||||
padding: 0.05rem;
|
||||
border-radius: 0.03rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 商品详情
|
||||
.goods-detail-wrap {
|
||||
background-color: #fff;
|
||||
border-radius: 0.05rem;
|
||||
padding-bottom: 0.15rem;
|
||||
|
||||
.detail-head {
|
||||
padding: 0 0.15rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 0.15rem;
|
||||
height: 0.45rem;
|
||||
border-bottom: 0.01rem solid #e8eaec;
|
||||
|
||||
.iconguanbi1 {
|
||||
font-size: $uni-font-size-lg;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-body {
|
||||
width: 9rem;
|
||||
height: 4.9rem;
|
||||
padding: 0.2rem 0.2rem 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
font-size: 0.15rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.information-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.box-left {
|
||||
width: 5rem;
|
||||
|
||||
.information {
|
||||
width: 100%;
|
||||
padding-left: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
view:nth-child(1) {
|
||||
width: 0.7rem;
|
||||
margin-right: 0.16rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
flex: 1;
|
||||
margin-right: 0.23rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.information:last-child {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-img {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
max-height: 2.7rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.single-specification {
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
padding-left: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
margin-bottom: 0.15rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 0.5rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 0.16rem;
|
||||
width: 0.7rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.message {
|
||||
width: 74%;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-all {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 0.38rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-td {
|
||||
font-size: 0.14rem;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.table-th {
|
||||
height: 0.56rem;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.table-tb {
|
||||
width: 100%;
|
||||
height: calc(100% - 0.56rem);
|
||||
|
||||
.table-tr {
|
||||
height: 0.7rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-td {
|
||||
image {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-group{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text:last-of-type{
|
||||
cursor: pointer;
|
||||
margin-left: 0.05rem;
|
||||
}
|
||||
}
|
||||
215
addon/cashier/source/os/pages/goods/public/css/print_price_tag.scss
Executable file
215
addon/cashier/source/os/pages/goods/public/css/print_price_tag.scss
Executable file
@@ -0,0 +1,215 @@
|
||||
.form-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.store-info {
|
||||
.form-inline {
|
||||
padding-left: 0.05rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 0.1rem;
|
||||
display: flex;
|
||||
|
||||
.form-label {
|
||||
width: 1.3rem;
|
||||
text-align: right;
|
||||
padding-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
width: 2.4rem;
|
||||
line-height: 0.32rem;
|
||||
margin-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
&.input {
|
||||
input {
|
||||
padding: 0 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-input {
|
||||
border-width: 0.01rem;
|
||||
border-style: solid;
|
||||
background-color: #fff;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 0.02rem;
|
||||
padding-left: 0.1rem;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
font-size: 0.14rem;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stock-body{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
.common-form .common-btn-wrap {
|
||||
margin-left: 0;
|
||||
}
|
||||
.content-wrap {
|
||||
|
||||
padding: 0.15rem;
|
||||
background-color: #fff;
|
||||
@extend %body-overhide;
|
||||
box-sizing: border-box;
|
||||
|
||||
.title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.batch-action {
|
||||
.batch-item {
|
||||
margin-right: 0.15rem;
|
||||
border: 0.01rem solid rgba(0, 0, 0, 0.2);
|
||||
padding: 0.05rem;
|
||||
border-radius: 0.03rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.table-wrap {
|
||||
position: relative;
|
||||
margin-top: 40rpx;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
|
||||
.iconcheckbox_weiquanxuan,
|
||||
.iconfuxuankuang1,
|
||||
.iconfuxuankuang2 {
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
font-size: 0.16rem;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.iconfuxuankuang2{
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.table-head {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
.table-body {
|
||||
@extend %body-overhide;
|
||||
max-height: 6rem;
|
||||
|
||||
.table-tr {
|
||||
&:last-of-type .table-td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-tr {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.table-th,
|
||||
.table-td {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.07rem 0.3rem;
|
||||
border-bottom: 0.01rem solid #dcdfe6;
|
||||
border-right: 0.01rem solid #dcdfe6;
|
||||
text-align: center;
|
||||
|
||||
&:last-of-type {
|
||||
border-right: 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&.goods-name {
|
||||
justify-content: flex-start;
|
||||
text-align: left;
|
||||
|
||||
image {
|
||||
width: 0.45rem;
|
||||
height: 0.45rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
margin: 0;
|
||||
font-size: $uni-font-size-base;
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
line-height: 0.32rem;
|
||||
height: 0.32rem;
|
||||
&::after{
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.table-empty {
|
||||
justify-content: center;
|
||||
padding: 0.1rem;
|
||||
color: #999;
|
||||
/* border: 0.01rem solid #dcdfe6;
|
||||
border-top: 0; */
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-wrap {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.24rem 0.2rem;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
z-index: 10;
|
||||
.btn-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
min-width: 1.2rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
font-size: $uni-font-size-base;
|
||||
|
||||
&.stockout-btn {
|
||||
margin-right: 0.15rem;
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
&::after{
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.remark {
|
||||
margin-right: 0.15rem;
|
||||
min-width: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
231
addon/cashier/source/os/pages/goods/public/js/goods_list.js
Executable file
231
addon/cashier/source/os/pages/goods/public/js/goods_list.js
Executable file
@@ -0,0 +1,231 @@
|
||||
import {
|
||||
setGoodsStatus,
|
||||
getGoodsDetail,
|
||||
} from '@/api/goods.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1, // 初始是请求第几页
|
||||
page_size: 20, // 每次返回数据数
|
||||
goodsDetail: null, // 商品详情数据
|
||||
skuList: [], // 弹窗中所需要获取到的sku列表数据
|
||||
status: '',
|
||||
disabled:false,
|
||||
goods_class: '',
|
||||
goodsId: '',
|
||||
option: {
|
||||
page_size: 9,
|
||||
search_text: '',
|
||||
sku_no: '',
|
||||
goods_class: 'all',
|
||||
status: 'all',
|
||||
start_price: '',
|
||||
end_price: ''
|
||||
},
|
||||
goodsClass: [{
|
||||
value: 1,
|
||||
label: '实物商品'
|
||||
}, {
|
||||
value: 4,
|
||||
label: '服务项目'
|
||||
}, {
|
||||
value: 5,
|
||||
label: '卡项套餐'
|
||||
}, {
|
||||
value: 6,
|
||||
label: '称重商品'
|
||||
}],
|
||||
statusList: [{
|
||||
value: 1,
|
||||
label: '仓库中'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '销售中'
|
||||
}],
|
||||
cols: [{
|
||||
width: 6,
|
||||
align: 'center',
|
||||
checkbox: true
|
||||
}, {
|
||||
field: 'account_data',
|
||||
width: 20,
|
||||
title: '商品信息',
|
||||
align: 'left',
|
||||
templet: data => {
|
||||
let img = this.$util.img(data.goods_image,{size: 'small'});
|
||||
let html = `
|
||||
<view class="goods-content">
|
||||
<image class="goods-img" src="${img}" mode="aspectFit"/>
|
||||
<text class="goods-name multi-hidden">${data.goods_name}</text>
|
||||
</view>
|
||||
`;
|
||||
return html;
|
||||
}
|
||||
}, {
|
||||
width: 14,
|
||||
title: '商品类型',
|
||||
align: 'center',
|
||||
field: 'goods_class_name'
|
||||
}, {
|
||||
width: 10,
|
||||
title: '价格',
|
||||
align: 'center',
|
||||
templet: function(data) {
|
||||
return '¥' + data.discount_price;
|
||||
}
|
||||
}, {
|
||||
field: 'stock',
|
||||
width: 15,
|
||||
title: '库存',
|
||||
align: 'center'
|
||||
}, {
|
||||
width: 15,
|
||||
title: '售卖模式',
|
||||
templet: data => {
|
||||
return (this.globalStoreInfo.stock_type == 'store' ? '独立库存' : '统一库存') + ' | ' + (data
|
||||
.is_unify_price ? '统一设价' : '独立设价');
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
templet: function(data) {
|
||||
var str = '';
|
||||
if (data.store_status == 1) {
|
||||
str = '销售中';
|
||||
} else if (data.store_status == 0) {
|
||||
str = '仓库中';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}, {
|
||||
width: 20,
|
||||
title: '操作',
|
||||
align: 'right',
|
||||
action: true
|
||||
}],
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
computed: {
|
||||
syncWeighGoods() {
|
||||
try {
|
||||
return this.addon.includes('weighgoods') && this.addon.includes('scale') && (window.POS_ || window
|
||||
.ipcRenderer);
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectClass(index) {
|
||||
this.goods_class = index == -1 ? '' : this.goodsClass[index].value.toString();
|
||||
},
|
||||
selectStatus(index) {
|
||||
this.status = index == -1 ? '' : this.statusList[index].value.toString();
|
||||
},
|
||||
// 搜索商品
|
||||
searchFn() {
|
||||
if (this.status == 1) {
|
||||
this.option.status = 0
|
||||
} else if (this.status == 2) {
|
||||
this.option.status = 1
|
||||
} else {
|
||||
this.option.status = 'all'
|
||||
}
|
||||
this.option.goods_class = this.goods_class ? this.goods_class : 'all';
|
||||
this.$refs.goodsListTable.load({
|
||||
page: 1
|
||||
});
|
||||
},
|
||||
resetFn() {
|
||||
this.status = '';
|
||||
this.goods_class = '';
|
||||
this.option.status = 'all';
|
||||
this.option.goods_class = 'all';
|
||||
this.option.search_text = '';
|
||||
this.option.sku_no = '';
|
||||
this.option.start_price = '';
|
||||
this.option.end_price = '';
|
||||
this.$refs.goodsListTable.load({
|
||||
page: 1
|
||||
});
|
||||
},
|
||||
// 查询商品详情
|
||||
getDetail(id, type = '') {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
this.goodsDetail = null;
|
||||
|
||||
getGoodsDetail(id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.goodsDetail = res.data;
|
||||
this.goodsDetail.sku_list[0].goods_name = this.goodsDetail.goods_name;
|
||||
this.skuList = this.goodsDetail.sku_list;
|
||||
if (!type) {
|
||||
this.$refs.goodsDetail.open();
|
||||
} else {
|
||||
this.$refs.goodsSku.open();
|
||||
}
|
||||
}
|
||||
uni.hideLoading();
|
||||
})
|
||||
},
|
||||
goodsStatus(id, status) {
|
||||
let arr;
|
||||
if (typeof id == 'object') {
|
||||
arr = [];
|
||||
id.value.length &&
|
||||
id.value.forEach((item, index) => {
|
||||
arr.push(item.goods_id);
|
||||
});
|
||||
|
||||
if (!arr.length) {
|
||||
this.$util.showToast({
|
||||
title: '请选择要操作的数据'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
} else arr = id;
|
||||
let data = {
|
||||
goods_id: arr.toString(),
|
||||
status: status
|
||||
};
|
||||
setGoodsStatus(data).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.$refs.goodsListTable.load();
|
||||
}
|
||||
})
|
||||
},
|
||||
goodsSku(id) {
|
||||
this.disabled = false
|
||||
this.goodsId = id;
|
||||
this.getDetail(id, 'goodsSku');
|
||||
},
|
||||
isDeliveryRestrictions(id){
|
||||
this.disabled = true
|
||||
this.goodsId = id;
|
||||
this.getDetail(id, 'goodsSku');
|
||||
},
|
||||
// 日志记录弹窗
|
||||
recordopen(id) {
|
||||
this.goodsId = id;
|
||||
this.$refs.record.open();
|
||||
},
|
||||
// 弹窗关闭
|
||||
close(type) {
|
||||
this.$refs[type].close();
|
||||
},
|
||||
synchronous() {
|
||||
this.$refs.scaleGoods.open();
|
||||
},
|
||||
printPriceTag(){
|
||||
this.$util.redirectTo('/pages/goods/print_price_tag');
|
||||
},
|
||||
}
|
||||
}
|
||||
206
addon/cashier/source/os/pages/goods/public/js/print_price_tag.js
Executable file
206
addon/cashier/source/os/pages/goods/public/js/print_price_tag.js
Executable file
@@ -0,0 +1,206 @@
|
||||
import {exportPrintPriceTagData} from '@/api/goods.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
goodsList: [], //已选择数据
|
||||
allSelected:false,
|
||||
isSubmit: false, //提交防抖
|
||||
dialogParams:{},
|
||||
dialogVisible: false, //弹框
|
||||
editPrintNum:{
|
||||
show:false,
|
||||
value:1,
|
||||
},
|
||||
//选择图标
|
||||
selectedIcon:'iconfuxuankuang1',
|
||||
unselectedIcon:'iconfuxuankuang2',
|
||||
harfselectedIcon:'iconcheckbox_weiquanxuan',
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
|
||||
},
|
||||
methods: {
|
||||
openSelectGoodsDialog() {
|
||||
this.dialogVisible = true
|
||||
},
|
||||
selectGoodsComplete(data) { //选择数据
|
||||
data.forEach((item, index) => {
|
||||
let is_in = false;
|
||||
this.goodsList.forEach((old_item, old_index)=>{
|
||||
if(old_item.sku_id == item.sku_id){
|
||||
is_in = true;
|
||||
return;
|
||||
}
|
||||
})
|
||||
if(!is_in){
|
||||
item.selected = false;
|
||||
item.print_num = 1;
|
||||
this.goodsList.push(item);
|
||||
}
|
||||
})
|
||||
},
|
||||
changeGoodsAllSelected(){
|
||||
if(this.goodsList.length == 0) return;
|
||||
this.allSelected = this.allSelected === true ? false : true;
|
||||
this.goodsList.forEach((item) => {
|
||||
item.selected = this.allSelected;
|
||||
})
|
||||
this.$forceUpdate();
|
||||
},
|
||||
changeGoodsSelected(index){
|
||||
this.goodsList[index].selected = !this.goodsList[index].selected;
|
||||
let selected_num = 0;
|
||||
this.goodsList.forEach((item) => {
|
||||
if(item.selected) selected_num++;
|
||||
})
|
||||
if(selected_num == this.goodsList.length){
|
||||
this.allSelected = true;
|
||||
}else if(selected_num == 0){
|
||||
this.allSelected = false;
|
||||
}else{
|
||||
this.allSelected = 'harf';
|
||||
}
|
||||
this.$forceUpdate();
|
||||
},
|
||||
getSelectedNum(){
|
||||
let selected_num = 0;
|
||||
this.goodsList.forEach((item) => {
|
||||
if(item.selected) selected_num++;
|
||||
})
|
||||
return selected_num;
|
||||
},
|
||||
batchDeleteGoods(){
|
||||
if(this.getSelectedNum() == 0){
|
||||
this.$util.showToast({
|
||||
title: '请选择要操作的数据',
|
||||
});
|
||||
return;
|
||||
}
|
||||
let goods_list = [];
|
||||
this.goodsList.forEach((item) => {
|
||||
if(!item.selected) goods_list.push(item);
|
||||
})
|
||||
this.goodsList = goods_list;
|
||||
if(this.goodsList.length == 0) this.allSelected = false;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
editPrintNumShow(){
|
||||
if(this.getSelectedNum() == 0){
|
||||
this.$util.showToast({
|
||||
title: '请选择要操作的数据',
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.editPrintNum.show = true;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
editPrintNumConfirm(){
|
||||
this.goodsList.forEach((item) => {
|
||||
if(item.selected){
|
||||
item.print_num = this.editPrintNum.value;
|
||||
item.selected = false;
|
||||
}
|
||||
})
|
||||
this.allSelected = false;
|
||||
this.editPrintNum.value = 1;
|
||||
this.editPrintNum.show = false;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
designFn(){
|
||||
if(!this.isPos()){
|
||||
this.$util.showToast({
|
||||
title: '请在客户端程序中执行此操作',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if(this.goodsList.length == 0){
|
||||
this.$util.showToast({
|
||||
title: '请先选择商品',
|
||||
});
|
||||
return;
|
||||
}
|
||||
let printFieldConfig = [
|
||||
{field:'goods_name', name:'商品名称'},
|
||||
{field:'spec_name', name:'规格'},
|
||||
{field:'sku_no', name:'商品条码'},
|
||||
{field:'market_price', name:'划线价'},
|
||||
{field:'price', name:'零售价'},
|
||||
{field:'unit', name:'单位'},
|
||||
{field:'weight', name:'重量'},
|
||||
{field:'category_names', name:'商品分类'},
|
||||
{field:'brand_name', name:'品牌'},
|
||||
{field:'supplier_name', name:'供应商'},
|
||||
{field:'label_name', name:'标签'},
|
||||
];
|
||||
try{
|
||||
this.$pos.send('DesignPriceTag', JSON.stringify(this.goodsList));
|
||||
}catch(e){
|
||||
this.$util.showToast({
|
||||
title: '设计错误:'+JSON.stringify(e),
|
||||
});
|
||||
}
|
||||
},
|
||||
printFn() {
|
||||
if(!this.isPos()){
|
||||
this.$util.showToast({
|
||||
title: '请在客户端程序中执行此操作',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if(this.goodsList.length == 0){
|
||||
this.$util.showToast({
|
||||
title: '请先选择商品',
|
||||
});
|
||||
return;
|
||||
}
|
||||
try{
|
||||
this.$pos.send('PrintPriceTag', JSON.stringify(this.goodsList));
|
||||
}catch(e){
|
||||
this.$util.showToast({
|
||||
title: '打印错误:'+JSON.stringify(e),
|
||||
});
|
||||
}
|
||||
},
|
||||
exportFn(){
|
||||
if(this.goodsList.length == 0){
|
||||
this.$util.showToast({
|
||||
title: '请先选择商品数据'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if(this.isPos()){
|
||||
try{
|
||||
this.$pos.send('ExportPriceTag', JSON.stringify(this.goodsList));
|
||||
}catch(e){
|
||||
this.$util.showToast({
|
||||
title: '导出错误:'+JSON.stringify(e),
|
||||
});
|
||||
}
|
||||
}else{
|
||||
uni.showLoading({
|
||||
title: '导出中'
|
||||
});
|
||||
exportPrintPriceTagData({
|
||||
data:JSON.stringify(this.goodsList),
|
||||
}).then(res => {
|
||||
uni.hideLoading();
|
||||
if (res.code == 0) {
|
||||
window.open(this.$util.img(res.data.path));
|
||||
}else{
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/goods/goodslist');
|
||||
},
|
||||
isPos(){
|
||||
return (window.POS_ || window.ipcRenderer);
|
||||
},
|
||||
}
|
||||
};
|
||||
488
addon/cashier/source/os/pages/index/change_shifts.vue
Executable file
488
addon/cashier/source/os/pages/index/change_shifts.vue
Executable file
@@ -0,0 +1,488 @@
|
||||
<template>
|
||||
<page-meta :root-font-size="rootSize"></page-meta>
|
||||
<view class="uni-flex uni-row height-all" :style="themeColor">
|
||||
<view class="container common-wrap" style="-webkit-flex: 1;flex: 1;" v-if="shiftsData">
|
||||
<view class="title">{{ info.username }}</view>
|
||||
<view class="time-title">
|
||||
班次:
|
||||
<text>{{ shiftsData.start_time > 0 ? $util.timeFormat(shiftsData.start_time) : '初始化' }}</text>
|
||||
<text class="separate">-</text>
|
||||
<text class="curr-time">{{ shiftsData.end_time | timeFormat }}</text>
|
||||
</view>
|
||||
<view class="title-box">
|
||||
<view class="box">
|
||||
<view class="name-box">
|
||||
<text class="title-name">销</text>
|
||||
<text class="name">总销售</text>
|
||||
</view>
|
||||
<view class="money-box">
|
||||
<text class="money">({{ shiftsData.total_sale | moneyFormat }}元{{ shiftsData.total_sale_count }}笔)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view class="name-box">
|
||||
<text class="title-name">会</text>
|
||||
<text class="name">会员充值</text>
|
||||
</view>
|
||||
<view class="money-box">
|
||||
<text class="money">({{ shiftsData.recharge_money | moneyFormat }}元{{ shiftsData.recharge_count }}笔)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view class="name-box">
|
||||
<text class="title-name">应</text>
|
||||
<text class="name">应收金额</text>
|
||||
</view>
|
||||
<view class="money-box">
|
||||
<text class="money">({{ shiftsData.total_money | moneyFormat }}元{{ shiftsData.total_count }}笔)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view class="name-box">
|
||||
<text class="title-name">支</text>
|
||||
<text class="name">支付统计</text>
|
||||
</view>
|
||||
<view class="money-box">
|
||||
<text class="money">({{ shiftsData.total_pay_money | moneyFormat }}元{{ shiftsData.total_pay_count }}笔)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view class="name-box">
|
||||
<text class="title-name">商</text>
|
||||
<text class="name">商品销售</text>
|
||||
</view>
|
||||
<view class="money-box">
|
||||
<text class="money">({{ shiftsData.sale_goods_count.class_num }}种{{ shiftsData.sale_goods_count.num }}件)</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="basic">
|
||||
<text @click="detail()">
|
||||
查看详情
|
||||
<text class="iconqianhou2 iconfont"></text>
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="default-btn cancel-btn" @click="cancel">取消</button>
|
||||
<button type="default" class="primary-btn shiftss-btn" @click="changeShiftsFn">交班并登出</button>
|
||||
</view>
|
||||
|
||||
<uni-popup ref="shiftslistPop">
|
||||
<view class="pop-box shiftsslistPop">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">交班详情</view>
|
||||
<view class="pop-header-close" @click="$refs.shiftslistPop.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content common-scrollbar">
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">总销售({{ shiftsData.total_sale | moneyFormat }}元 {{ shiftsData.total_sale_count }}笔)</view>
|
||||
<view class="pop-contents-text">开单销售({{ shiftsData.billing_money | moneyFormat }}元 {{ shiftsData.billing_count }}笔)</view>
|
||||
<view class="pop-contents-text">售卡销售({{ shiftsData.buycard_money | moneyFormat }}元 {{ shiftsData.buycard_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">会员充值({{ shiftsData.recharge_money | moneyFormat }}元 {{ shiftsData.recharge_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">应收金额({{ shiftsData.total_money | moneyFormat }}元 {{ shiftsData.total_count }}笔)</view>
|
||||
<view class="pop-contents-text">开单销售({{ shiftsData.billing_money | moneyFormat }}元 {{ shiftsData.billing_count }}笔)</view>
|
||||
<view class="pop-contents-text">售卡销售({{ shiftsData.buycard_money | moneyFormat }}元 {{ shiftsData.buycard_count }}笔)</view>
|
||||
<view class="pop-contents-text">会员充值({{ shiftsData.recharge_money | moneyFormat }}元 {{ shiftsData.recharge_count }}笔)</view>
|
||||
<view class="pop-contents-text">订单退款({{ shiftsData.refund_money | moneyFormat }}元 {{ shiftsData.refund_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">支付统计({{ shiftsData.total_pay_money | moneyFormat }}元 {{ shiftsData.total_pay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.cash > 0">现金收款({{ shiftsData.cash | moneyFormat }}元 {{ shiftsData.cash_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.wechatpay > 0">微信收款({{ shiftsData.wechatpay | moneyFormat }}元 {{ shiftsData.wechatpay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.alipay > 0">支付宝收款({{ shiftsData.alipay | moneyFormat }}元 {{ shiftsData.alipay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.own_wechatpay > 0">个人微信收款({{ shiftsData.own_wechatpay | moneyFormat }}元 {{ shiftsData.own_wechatpay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.own_alipay > 0">个人支付宝收款({{ shiftsData.own_alipay | moneyFormat }}元 {{ shiftsData.own_alipay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.own_pos > 0">个人POS收款({{ shiftsData.own_pos | moneyFormat }}元 {{ shiftsData.own_pos_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">商品销售({{ shiftsData.sale_goods_count.class_num }}种{{ shiftsData.sale_goods_count.num }}件)</view>
|
||||
<view class="pop-contents-text">线上销售({{ shiftsData.sale_goods_count.online_class_num }}种 {{ shiftsData.sale_goods_count.online_num }}件)</view>
|
||||
<view class="pop-contents-text">线下销售({{ shiftsData.sale_goods_count.offline_class_num }}种 {{ shiftsData.sale_goods_count.offline_num }}件)</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content-footer">
|
||||
<button class="primary-btn" @click="printTicketFn">打印小票</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
<ns-loading ref="loading"></ns-loading>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dataTable from '@/components/uni-data-table/uni-data-table.vue';
|
||||
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
||||
import { getShiftsData, changeShifts } from '@/api/shifts.js';
|
||||
import { printTicket } from '@/api/printer.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
dataTable,
|
||||
uniPopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shiftsData: null,
|
||||
info: null,
|
||||
isSub: false
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
this.loadThemeColor();
|
||||
this.getShiftsInfoFn();
|
||||
},
|
||||
methods: {
|
||||
detail() {
|
||||
this.$refs.shiftslistPop.open('center');
|
||||
},
|
||||
getShiftsInfoFn() {
|
||||
getShiftsData().then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
let shiftsData = res.data.shifts_data;
|
||||
shiftsData.total_sale = parseFloat(shiftsData.billing_money) + parseFloat(shiftsData.buycard_money);
|
||||
shiftsData.total_sale_count = parseInt(shiftsData.billing_count) + parseInt(shiftsData.buycard_count);
|
||||
shiftsData.total_count = shiftsData.total_sale_count + parseInt(shiftsData.recharge_count) + parseInt(shiftsData.refund_count);
|
||||
shiftsData.total_money = shiftsData.total_sale + parseFloat(shiftsData.recharge_money) - parseFloat(shiftsData.refund_money);
|
||||
shiftsData.total_pay_money =
|
||||
parseFloat(shiftsData.cash) +
|
||||
parseFloat(shiftsData.alipay) +
|
||||
parseFloat(shiftsData.wechatpay) +
|
||||
parseFloat(shiftsData.own_wechatpay) +
|
||||
parseFloat(shiftsData.own_alipay) +
|
||||
parseFloat(shiftsData.own_pos);
|
||||
shiftsData.total_pay_count =
|
||||
parseInt(shiftsData.cash_count) +
|
||||
parseInt(shiftsData.alipay_count) +
|
||||
parseInt(shiftsData.wechatpay_count) +
|
||||
parseInt(shiftsData.own_wechatpay_count) +
|
||||
parseInt(shiftsData.own_alipay_count) +
|
||||
parseInt(shiftsData.own_pos_count);
|
||||
|
||||
this.shiftsData = shiftsData;
|
||||
this.info = res.data.userinfo;
|
||||
|
||||
this.$refs.loading.hide();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
// 交班
|
||||
changeShiftsFn() {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
uni.showLoading({
|
||||
title: ''
|
||||
});
|
||||
changeShifts().then(res => {
|
||||
uni.hideLoading();
|
||||
if (res.code == 0 && res.data) {
|
||||
uni.removeStorage({
|
||||
key: 'cashierToken',
|
||||
success: () => {
|
||||
this.$util.clearStoreData();
|
||||
this.$util.redirectTo('/pages/login/login', {}, 'reLaunch');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.isSub = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 打印小票
|
||||
*/
|
||||
printTicketFn() {
|
||||
printTicket().then(res => {
|
||||
if (res.code == 0) {
|
||||
if (Object.values(res.data).length) {
|
||||
let data = Object.values(res.data);
|
||||
try {
|
||||
let print = {
|
||||
printer: []
|
||||
};
|
||||
data.forEach((item) => {
|
||||
print.printer.push({
|
||||
printer_type: item.printer_info.printer_type,
|
||||
host: item.printer_info.host,
|
||||
ip: item.printer_info.ip,
|
||||
port: item.printer_info.port,
|
||||
content: item.content,
|
||||
print_width: item.printer_info.print_width
|
||||
})
|
||||
});
|
||||
this.$pos.send('Print', JSON.stringify(print));
|
||||
} catch (e) {
|
||||
console.log('err', e, res.data)
|
||||
}
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: '未开启交接班小票打印'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message ? res.message : '小票打印失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印回调
|
||||
* @param {Object} text
|
||||
*/
|
||||
window.POS_PRINT_CALLBACK = function (text) {
|
||||
uni.showToast({
|
||||
title: text,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.height-all {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.pop-box {
|
||||
background: #ffffff;
|
||||
width: 4rem;
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.pop-header {
|
||||
width: 100%;
|
||||
padding: 0 0.15rem 0 0.2rem;
|
||||
height: 0.5rem;
|
||||
// width: 3.5rem;
|
||||
margin: 0 auto;
|
||||
line-height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #f0f0f0;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
border-radius: 0.02rem 0.2rem 0 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pop-header-text {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.pop-header-close {
|
||||
cursor: pointer;
|
||||
|
||||
text {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.pop-contents {
|
||||
margin-top: 0.3rem;
|
||||
width: 3rem;
|
||||
height: 0.8rem;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.pop-content-item {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-items {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-text {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.pop-contents-text {
|
||||
margin-left: 0.4rem;
|
||||
font-weight: normal;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.pop-content-footer {
|
||||
display: flex;
|
||||
padding: .15rem;
|
||||
justify-content: flex-end;
|
||||
|
||||
button {
|
||||
width: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 0.16rem;
|
||||
margin-top: 0.45rem;
|
||||
font-weight: 900;
|
||||
color: rgb(86, 116, 133);
|
||||
}
|
||||
|
||||
.time-title {
|
||||
padding: 0.1rem;
|
||||
line-height: 0.2rem;
|
||||
border-radius: 5px;
|
||||
background-color: var(--primary-color-light-8);
|
||||
color: $primary-color;
|
||||
font-size: 0.14rem;
|
||||
margin-top: 0.2rem;
|
||||
|
||||
text {
|
||||
margin: 0 0.05rem;
|
||||
}
|
||||
|
||||
.curr-time {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.title-box {
|
||||
width: 5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-content: space-around;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 5.4rem;
|
||||
height: 0.6rem;
|
||||
background: #f9fbfb;
|
||||
border: 1px solid rgb(225, 225, 225);
|
||||
margin-top: 0.1rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 0.23rem 0 0.23rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.title-name {
|
||||
display: inline-block;
|
||||
width: 0.3rem;
|
||||
height: 0.3rem;
|
||||
border-radius: 15%;
|
||||
text-align: center;
|
||||
line-height: 0.3rem;
|
||||
background: $primary-color;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.name-box {
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
.money-box {
|
||||
line-height: 0.3rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 0.16rem;
|
||||
line-height: 0.3rem;
|
||||
margin-left: 0.2rem;
|
||||
font-weight: 900;
|
||||
color: rgb(86, 116, 133);
|
||||
}
|
||||
|
||||
.money {
|
||||
margin-left: 0.25rem;
|
||||
color: rgb(86, 116, 133);
|
||||
}
|
||||
|
||||
.basic {
|
||||
text-align: center;
|
||||
margin-top: 0.33rem;
|
||||
|
||||
text {
|
||||
height: 0.15rem;
|
||||
color: $primary-color;
|
||||
font-size: 0.14rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.iconqianhou2 {
|
||||
margin-left: 0.05rem;
|
||||
font-size: 1px;
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
width: 1.7rem;
|
||||
height: 0.5rem;
|
||||
line-height: 0.5rem;
|
||||
}
|
||||
|
||||
.shiftss-btn {
|
||||
width: 1.7rem;
|
||||
height: 0.5rem;
|
||||
line-height: 0.5rem;
|
||||
background-color: $primary-color;
|
||||
color: #fff !important;
|
||||
margin-left: 0.21rem;
|
||||
}
|
||||
|
||||
.common-btn-wrap {
|
||||
margin-top: 1.14rem;
|
||||
z-index: 2;
|
||||
height: 0.6rem;
|
||||
padding-bottom: 0.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
413
addon/cashier/source/os/pages/index/change_shiftsrecord.vue
Executable file
413
addon/cashier/source/os/pages/index/change_shiftsrecord.vue
Executable file
@@ -0,0 +1,413 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="manage">
|
||||
<view class="screen-warp common-form">
|
||||
<uni-datetime-picker v-model="screen.start_time" type="datetime" placeholder="请选择开始时间" :clearIcon="false" />
|
||||
<uni-datetime-picker v-model="screen.end_time" type="datetime" placeholder="请选择结束时间" :clearIcon="false" />
|
||||
<view>
|
||||
<select-lay :zindex="10" :value="screen.uid" name="names" placeholder="请选择员工" :options="userList" @selectitem="selectUser"/>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button class="screen-btn" @click="search">搜索</button>
|
||||
<button type="default" @click="reset()">重置</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-data-table url="/cashier/storeapi/cashier/changeShiftsRecord" :option="screen" :cols="cols" ref="table">
|
||||
<template v-slot:action="data">
|
||||
<view class="common-table-action"><text @click="detail(data)">查看详情</text></view>
|
||||
<view class="common-table-action"><text @click="saleGoods(data)">商品销售</text></view>
|
||||
</template>
|
||||
</uni-data-table>
|
||||
</view>
|
||||
|
||||
<uni-popup ref="shiftslistPop">
|
||||
<view class="pop-box shiftsslistPop">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">交班详情</view>
|
||||
<view class="pop-header-close" @click="$refs.shiftslistPop.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content common-scrollbar" v-if="shiftsData">
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">总销售({{ shiftsData.total_sale | moneyFormat }}元 {{ shiftsData.total_sale_count }}笔)</view>
|
||||
<view class="pop-contents-text">开单销售({{ shiftsData.billing_money | moneyFormat }}元 {{ shiftsData.billing_count }}笔)</view>
|
||||
<view class="pop-contents-text">售卡销售({{ shiftsData.buycard_money | moneyFormat }}元 {{ shiftsData.buycard_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">会员充值({{ shiftsData.recharge_money | moneyFormat }}元 {{ shiftsData.recharge_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">应收金额({{ shiftsData.total_money | moneyFormat }}元 {{ shiftsData.total_count }}笔)</view>
|
||||
<view class="pop-contents-text">开单销售({{ shiftsData.billing_money | moneyFormat }}元 {{ shiftsData.billing_count }}笔)</view>
|
||||
<view class="pop-contents-text">售卡销售({{ shiftsData.buycard_money | moneyFormat }}元 {{ shiftsData.buycard_count }}笔)</view>
|
||||
<view class="pop-contents-text">会员充值({{ shiftsData.recharge_money | moneyFormat }}元 {{ shiftsData.recharge_count }}笔)</view>
|
||||
<view class="pop-contents-text">订单退款({{ shiftsData.refund_money | moneyFormat }}元 {{ shiftsData.refund_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">支付统计({{ shiftsData.total_pay_money | moneyFormat }}元 {{ shiftsData.total_pay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.cash > 0">现金收款({{ shiftsData.cash | moneyFormat }}元 {{ shiftsData.cash_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.wechatpay > 0">微信收款({{ shiftsData.wechatpay | moneyFormat }}元 {{ shiftsData.wechatpay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.alipay > 0">支付宝收款({{ shiftsData.alipay | moneyFormat }}元 {{ shiftsData.alipay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.own_wechatpay > 0">个人微信收款({{ shiftsData.own_wechatpay | moneyFormat }}元 {{ shiftsData.own_wechatpay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.own_alipay > 0">个人支付宝收款({{ shiftsData.own_alipay | moneyFormat }}元 {{ shiftsData.own_alipay_count }}笔)</view>
|
||||
<view class="pop-contents-text" v-if="shiftsData.own_pos > 0">个人POS收款({{ shiftsData.own_pos | moneyFormat }}元 {{ shiftsData.own_pos_count }}笔)</view>
|
||||
</view>
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">商品销售({{ shiftsData.sale_goods_count.class_num }}种 {{ shiftsData.sale_goods_count.num }}件)</view>
|
||||
<view class="pop-contents-text" >线上销售({{ shiftsData.sale_goods_count.online_class_num }}种 {{ shiftsData.sale_goods_count.online_num }}件)</view>
|
||||
<view class="pop-contents-text" >线下销售({{ shiftsData.sale_goods_count.offline_class_num }}种 {{ shiftsData.sale_goods_count.offline_num }}件)</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content-footer">
|
||||
<button class="primary-btn" @click="printTicketFn">打印小票</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { printTicket } from '@/api/printer.js'
|
||||
import { getUserList } from '@/api/user.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
shiftsData: null,
|
||||
screen: {
|
||||
page: 1,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
uid: 0
|
||||
},
|
||||
userList: [],
|
||||
cols: [{
|
||||
width: 20,
|
||||
title: '员工',
|
||||
field: 'username',
|
||||
align: 'left'
|
||||
}, {
|
||||
width: 20,
|
||||
title: '开始时间',
|
||||
align: 'center',
|
||||
return: data => {
|
||||
return data.start_time ? this.$util.timeFormat(data.start_time) : '';
|
||||
}
|
||||
}, {
|
||||
width: 20,
|
||||
title: '结束时间',
|
||||
align: 'center',
|
||||
return: data => {
|
||||
return this.$util.timeFormat(data.end_time);
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '总销售',
|
||||
align: 'right',
|
||||
return: data => {
|
||||
return this.$util.moneyFormat(parseFloat(data.billing_money) + parseFloat(data.buycard_money));
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '会员充值',
|
||||
align: 'right',
|
||||
return: data => {
|
||||
return this.$util.moneyFormat(data.recharge_money);
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '应收金额',
|
||||
align: 'right',
|
||||
return: data => {
|
||||
return this.$util.moneyFormat(
|
||||
parseFloat(data.billing_money) + parseFloat(data.buycard_money) + parseFloat(data.recharge_money) - parseFloat(data.refund_money)
|
||||
);
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '支付统计',
|
||||
align: 'right',
|
||||
return: data => {
|
||||
return this.$util.moneyFormat(
|
||||
parseFloat(data.cash) +
|
||||
parseFloat(data.alipay) +
|
||||
parseFloat(data.wechatpay) +
|
||||
parseFloat(data.own_wechatpay) +
|
||||
parseFloat(data.own_alipay) +
|
||||
parseFloat(data.own_pos)
|
||||
);
|
||||
}
|
||||
}, {
|
||||
width: 16,
|
||||
title: '商品销售',
|
||||
align: 'right',
|
||||
return: data => {
|
||||
return data.sale_goods_count.class_num + '种 ' + data.sale_goods_count.num + '件';
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '操作',
|
||||
action: true, // 表格操作列
|
||||
align: 'right'
|
||||
}]
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getUserListFn();
|
||||
},
|
||||
methods: {
|
||||
switchStoreAfter() {
|
||||
this.screen = {
|
||||
page: 1,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
uid: 0
|
||||
};
|
||||
this.$refs.table.load();
|
||||
this.getUserListFn();
|
||||
},
|
||||
saleGoods(data){
|
||||
this.$util.redirectTo('/pages/index/change_shiftssalelist',{ id : data.value.id });
|
||||
},
|
||||
detail(data) {
|
||||
let shiftsData = this.$util.deepClone(data.value);
|
||||
shiftsData.total_sale = parseFloat(shiftsData.billing_money) + parseFloat(shiftsData.buycard_money);
|
||||
shiftsData.total_sale_count = parseInt(shiftsData.billing_count) + parseInt(shiftsData.buycard_count);
|
||||
shiftsData.total_count = shiftsData.total_sale_count + parseInt(shiftsData.recharge_count) + parseInt(shiftsData.refund_count);
|
||||
shiftsData.total_money = shiftsData.total_sale + parseFloat(shiftsData.recharge_money) - parseFloat(shiftsData.refund_money);
|
||||
shiftsData.total_pay_money =
|
||||
parseFloat(shiftsData.cash) +
|
||||
parseFloat(shiftsData.alipay) +
|
||||
parseFloat(shiftsData.wechatpay) +
|
||||
parseFloat(shiftsData.own_wechatpay) +
|
||||
parseFloat(shiftsData.own_alipay) +
|
||||
parseFloat(shiftsData.own_pos);
|
||||
shiftsData.total_pay_count =
|
||||
parseInt(shiftsData.cash_count) +
|
||||
parseInt(shiftsData.alipay_count) +
|
||||
parseInt(shiftsData.wechatpay_count) +
|
||||
parseInt(shiftsData.own_wechatpay_count) +
|
||||
parseInt(shiftsData.own_alipay_count) +
|
||||
parseInt(shiftsData.own_pos_count);
|
||||
this.shiftsData = shiftsData;
|
||||
this.$refs.shiftslistPop.open('center');
|
||||
},
|
||||
getUserListFn() {
|
||||
let data = {
|
||||
page: 1,
|
||||
page_size: 0
|
||||
};
|
||||
getUserList(data).then(res => {
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.userList = res.data.list.map(item => {
|
||||
return {
|
||||
label: item.username,
|
||||
value: item.uid
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.screen = {
|
||||
page: 1,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
uid: 0
|
||||
};
|
||||
this.$refs.table.load(this.screen);
|
||||
},
|
||||
selectUser(index, item) {
|
||||
if (index >= 0) {
|
||||
this.screen.uid = parseInt(item.value);
|
||||
} else {
|
||||
this.screen.uid = 0;
|
||||
}
|
||||
},
|
||||
search() {
|
||||
this.$refs.table.load(this.screen);
|
||||
},
|
||||
/**
|
||||
* 打印小票
|
||||
*/
|
||||
printTicketFn() {
|
||||
let data = {
|
||||
record_id: this.shiftsData.id
|
||||
};
|
||||
printTicket(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
if (Object.values(res.data).length) {
|
||||
let data = Object.values(res.data);
|
||||
try {
|
||||
let print = {
|
||||
printer: []
|
||||
};
|
||||
data.forEach((item) => {
|
||||
print.printer.push({
|
||||
printer_type: item.printer_info.printer_type,
|
||||
host: item.printer_info.host,
|
||||
ip: item.printer_info.ip,
|
||||
port: item.printer_info.port,
|
||||
content: item.content,
|
||||
print_width: item.printer_info.print_width
|
||||
});
|
||||
});
|
||||
this.$pos.send('Print', JSON.stringify(print));
|
||||
} catch (e) {
|
||||
console.log('err', e, res.data)
|
||||
}
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: '未开启交接班小票打印'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message ? res.message : '小票打印失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 打印回调
|
||||
* @param {Object} text
|
||||
*/
|
||||
window.POS_PRINT_CALLBACK = function (text) {
|
||||
uni.showToast({
|
||||
title: text,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.manage {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
padding: 0.15rem;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 筛选面板
|
||||
.screen-warp {
|
||||
padding: 0.15rem;
|
||||
background-color: #f2f3f5;
|
||||
margin-bottom: 0.15rem;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
|
||||
/deep/ .uni-date-x {
|
||||
height: 0.35rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-select-lay {
|
||||
background: #fff;
|
||||
|
||||
.uni-select-lay-select {
|
||||
height: 0.37rem;
|
||||
}
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&>* {
|
||||
margin-right: 0.15rem;
|
||||
}
|
||||
.common-btn-wrap{
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// pop弹框
|
||||
.pop-box {
|
||||
background: #ffffff;
|
||||
width: 4rem;
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.pop-header {
|
||||
width: 100%;
|
||||
padding: 0 0.15rem 0 0.2rem;
|
||||
height: 0.5rem;
|
||||
margin: 0 auto;
|
||||
line-height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #f0f0f0;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
border-radius: 0.02rem 0.2rem 0 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pop-header-close {
|
||||
cursor: pointer;
|
||||
|
||||
text {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.pop-contents {
|
||||
margin-top: 0.3rem;
|
||||
width: 3rem;
|
||||
height: 0.8rem;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.pop-content-item {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-items {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-text {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.pop-contents-text {
|
||||
margin-left: 0.4rem;
|
||||
font-weight: normal;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.pop-content-footer {
|
||||
display: flex;
|
||||
padding: 0.1rem 0.2rem;
|
||||
border-top: 0.01rem solid #e6e6e6;
|
||||
justify-content: center;
|
||||
button {
|
||||
width: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
56
addon/cashier/source/os/pages/index/change_shiftssalelist.vue
Executable file
56
addon/cashier/source/os/pages/index/change_shiftssalelist.vue
Executable file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goods-list">
|
||||
<view class="title-back flex items-center cursor-pointer" @click="backFn">
|
||||
<text class="iconfont iconqianhou1"></text>
|
||||
<text class="left">返回</text>
|
||||
<text class="content">|</text>
|
||||
<text>商品销售</text>
|
||||
</view>
|
||||
<view class="screen-warp common-form">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline">
|
||||
<label class="form-label">销售渠道</label>
|
||||
<view class="form-input-inline">
|
||||
<select-lay :zindex="10" :value="option.sale_channel" name="sale_channel" placeholder="请选择销售渠道" :options="sale_channel_list" @selectitem="selectChannel"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">规格名称</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="option.sku_name" placeholder="请输入规格名称" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="searchFn()">筛选</button>
|
||||
<button type="default" @click="resetFn()">重置</button>
|
||||
<button type="default" class="screen-btn" @click="exportSalelist()">导出</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uniDataTable url="/cashier/storeapi/cashier/changeShiftsSaleGoodsList" :option="option" :cols="cols" ref="saleListTable">
|
||||
</uniDataTable>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniDataTable from '@/components/uni-data-table/uni-data-table.vue';
|
||||
import saleList from './public/js/sale_list.js';
|
||||
export default {
|
||||
components: {
|
||||
uniDataTable
|
||||
},
|
||||
mixins: [saleList]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './../goods/public/css/goods_list.scss';
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.common-btn-wrap button{
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
</style>
|
||||
33
addon/cashier/source/os/pages/index/loading.vue
Executable file
33
addon/cashier/source/os/pages/index/loading.vue
Executable file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<page-meta :root-font-size="rootSize"></page-meta>
|
||||
<view class="container" :style="themeColor">
|
||||
<image src="@/static/cashier/start_logo.png" mode="heightFix" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
onShow() {
|
||||
this.loadThemeColor();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
image {
|
||||
height: 80%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
36
addon/cashier/source/os/pages/index/no_permission.vue
Executable file
36
addon/cashier/source/os/pages/index/no_permission.vue
Executable file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row height-all">
|
||||
<view class="container common-wrap" style="-webkit-flex: 1;flex: 1;">
|
||||
<view class="msg">对不起,您没有权限访问该页面</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
onLoad() {
|
||||
uni.hideTabBar({});
|
||||
},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
|
||||
.msg {
|
||||
color: #333;
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
106
addon/cashier/source/os/pages/index/public/js/sale_list.js
Executable file
106
addon/cashier/source/os/pages/index/public/js/sale_list.js
Executable file
@@ -0,0 +1,106 @@
|
||||
import {
|
||||
saleGoodsExport
|
||||
} from '@/api/shifts.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1, // 初始是请求第几页
|
||||
page_size: 20, // 每次返回数据数
|
||||
option: {
|
||||
sale_channel:'all',
|
||||
sku_name:'',
|
||||
record_id:''
|
||||
},
|
||||
sale_channel_list: [{
|
||||
value: 'online',
|
||||
label: '线上'
|
||||
}, {
|
||||
value: 'offline',
|
||||
label: '线下'
|
||||
}],
|
||||
cols: [{
|
||||
field: 'account_data',
|
||||
width: 25,
|
||||
title: '商品信息',
|
||||
align: 'left',
|
||||
templet: data => {
|
||||
let img = data.goods_class != 'recharge' ? this.$util.img(data.sku_image,{size:'small'}) : this.$util.img(data.sku_image);
|
||||
let html = `
|
||||
<view class="goods-content">
|
||||
<image class="goods-img" src="${img}" mode="aspectFit"/>
|
||||
<view class="infos">
|
||||
<text class="goods-name multi-hidden">${data.goods_name}</text>
|
||||
<text class="spec-name multi-hidden">${data.spec_name}</text>
|
||||
</view>
|
||||
</view>
|
||||
`;
|
||||
return html;
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '总数量',
|
||||
align: 'center',
|
||||
field: 'num'
|
||||
}, {
|
||||
width: 15,
|
||||
title: '平均销售价',
|
||||
align: 'center',
|
||||
field: 'price'
|
||||
}, {
|
||||
width: 15,
|
||||
title: '销售总额',
|
||||
align: 'center',
|
||||
field: 'goods_money'
|
||||
}, {
|
||||
width: 15,
|
||||
title: '线下销售',
|
||||
align: 'center',
|
||||
field: 'offline_num'
|
||||
}, {
|
||||
width: 15,
|
||||
title: '线上销售',
|
||||
align: 'center',
|
||||
field: 'online_num'
|
||||
}],
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.option.record_id = option.id || '';
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
exportSalelist(){
|
||||
saleGoodsExport(this.option).then(res => {
|
||||
if (res.code == 0) {
|
||||
window.open(this.$util.img(res.data.path));
|
||||
}else{
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
selectChannel(index){
|
||||
this.option.sale_channel = index == -1 ? '' : this.sale_channel_list[index].value.toString();
|
||||
},
|
||||
searchFn(){
|
||||
this.$refs.saleListTable.load({
|
||||
page: 1
|
||||
});
|
||||
},
|
||||
resetFn(){
|
||||
this.option.sale_channel = '';
|
||||
this.option.sku_name = '';
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/index/change_shiftsrecord');
|
||||
},
|
||||
detail(data){
|
||||
if(window.location.origin.indexOf('localhost') != -1){
|
||||
window.open(window.location.origin+'/cashregister/pages/order/orderlist?order_no='+data.value.order_no,'_blank');
|
||||
}else{
|
||||
window.open(this.$config.baseUrl+'/cashregister/pages/order/orderlist?order_no='+data.value.order_no);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
149
addon/cashier/source/os/pages/local/config.vue
Executable file
149
addon/cashier/source/os/pages/local/config.vue
Executable file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="collect-money-config">
|
||||
<view class="common-wrap common-form fixd common-scrollbar">
|
||||
<view class="common-title">本机设置</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">打印机选择</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="printerSelectTypeChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="all" :checked="printerSelectType == 'all'" />
|
||||
全部
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="part" :checked="printerSelectType == 'part'" />
|
||||
部分
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line" v-if="printerSelectType == 'all'">{{printerTips}}</text>
|
||||
</view>
|
||||
<view class="common-form-item" v-if="printerSelectType == 'part'">
|
||||
<label class="form-label"></label>
|
||||
<view class="form-inline">
|
||||
<checkbox-group class="form-checkbox-group" @change="printerSelectIdsChange">
|
||||
<label class="form-checkbox-item" v-for="(item, index) in printerList">
|
||||
<checkbox :value="item.printer_id" :checked="printerSelectIds.indexOf(item.printer_id) > -1"/>
|
||||
{{item.printer_name}}
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">{{printerTips}}</text>
|
||||
</view>
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="saveFn">保存</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getPrinterList,
|
||||
} from '@/api/printer.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isRepeat: false,
|
||||
printerList:[],
|
||||
printerSelectType:'all',
|
||||
printerSelectIds:[],
|
||||
printerTips:'如果一个门店有多个收银机,请为每个收银机设备选择要调用的打印机硬件',
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.initData();
|
||||
this.getPrinterList();
|
||||
},
|
||||
onShow() { },
|
||||
methods: {
|
||||
initData(){
|
||||
var local_config = this.$util.getLocalConfig();
|
||||
this.printerSelectType = local_config.printerSelectType;
|
||||
this.printerSelectIds = local_config.printerSelectIds;
|
||||
},
|
||||
getPrinterList() {
|
||||
getPrinterList({
|
||||
page: 1,
|
||||
page_size: 0
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.printerList = res.data.list;
|
||||
this.printerList.forEach((item, index)=>{
|
||||
item.printer_id = item.printer_id.toString();
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
printerSelectTypeChange(e) {
|
||||
this.printerSelectType = e.detail.value;
|
||||
},
|
||||
printerSelectIdsChange(e) {
|
||||
this.printerSelectIds = e.detail.value;
|
||||
},
|
||||
saveFn() {
|
||||
this.$util.setLocalConfig({
|
||||
printerSelectType:this.printerSelectType,
|
||||
printerSelectIds:this.printerSelectIds,
|
||||
})
|
||||
this.$util.showToast({
|
||||
title: '设置成功'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.collect-money-config {
|
||||
position: relative;
|
||||
|
||||
.common-btn-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
|
||||
.screen-btn {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.common-wrap.fixd {
|
||||
padding: 30rpx;
|
||||
height: calc(100vh - 0.4rem);
|
||||
overflow-y: auto;
|
||||
// padding-bottom: 1rem !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.form-input-inline.btn {
|
||||
height: 0.37rem;
|
||||
line-height: 0.35rem;
|
||||
box-sizing: border-box;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.common-form .common-form-item .form-label {
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.common-form .common-form-item .form-word-aux-line {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
275
addon/cashier/source/os/pages/login/login.vue
Executable file
275
addon/cashier/source/os/pages/login/login.vue
Executable file
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<page-meta :root-font-size="rootSize"></page-meta>
|
||||
<view class="container" :style="themeColor">
|
||||
<view class="login-wrap">
|
||||
<view class="header">
|
||||
<view class="title">智慧零售平台登录</view>
|
||||
</view>
|
||||
<view class="form-wrap">
|
||||
<view class="input-wrap">
|
||||
<text class="iconfont icona-xingzhuang2"></text>
|
||||
<input type="text" @confirm="loginFn" v-model="formData.username" placeholder="请输入用户名" placeholder-class="placeholder" />
|
||||
</view>
|
||||
<view class="input-wrap">
|
||||
<text class="iconfont iconmima"></text>
|
||||
<input type="text" @confirm="loginFn" v-model="formData.password" placeholder="请输入密码" placeholder-class="placeholder" v-show="passShow" />
|
||||
<input type="password" @confirm="loginFn" v-model="formData.password" placeholder="请输入密码" placeholder-class="placeholder" v-show="!passShow" />
|
||||
<view class="iconfont pass-show" :class="{ iconyanjing5: passShow, iconinvisible: !passShow }" @click="passShow = !passShow"></view>
|
||||
</view>
|
||||
<view class="input-wrap">
|
||||
<text class="iconfont iconyanzhengma"></text>
|
||||
<input type="number" @confirm="loginFn" v-model="formData.vercode" placeholder="请输入验证码" placeholder-class="placeholder" maxlength="4" />
|
||||
<image :src="captcha.img" class="captcha" @click="getCaptchaFn" />
|
||||
</view>
|
||||
<button type="default" class="login-btn primary-btn" @click="loginFn">登录</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import validate from 'common/js/validate.js';
|
||||
import { getCaptcha, login } from '@/api/login.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
passShow: false,
|
||||
formData: {
|
||||
username: '',
|
||||
password: '',
|
||||
vercode: '',
|
||||
dynacode: '',
|
||||
key: ''
|
||||
},
|
||||
captcha: {
|
||||
id: '',
|
||||
img: ''
|
||||
},
|
||||
isSub: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.loadThemeColor();
|
||||
this.getCaptchaFn();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取验证码
|
||||
*/
|
||||
getCaptchaFn() {
|
||||
getCaptcha(this.captcha.id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.captcha = res.data;
|
||||
this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
|
||||
}
|
||||
})
|
||||
},
|
||||
loginFn() {
|
||||
var data = {
|
||||
username: this.formData.username,
|
||||
password: this.formData.password
|
||||
};
|
||||
|
||||
if (this.captcha.id != '') {
|
||||
data.captcha_id = this.captcha.id;
|
||||
data.captcha_code = this.formData.vercode;
|
||||
}
|
||||
|
||||
if (this.verify(data)) {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
uni.showLoading({});
|
||||
|
||||
login(data).then(res => {
|
||||
uni.hideLoading();
|
||||
if (res.code >= 0) {
|
||||
uni.setStorageSync('siteId', res.data.site_id);
|
||||
this.$store.commit('app/setGlobalStoreId', res.data.store_id);
|
||||
uni.setStorage({
|
||||
key: 'cashierToken',
|
||||
data: res.data.token,
|
||||
success: () => {
|
||||
this.$store.dispatch('app/getStoreInfoFn');
|
||||
this.$store.dispatch('app/getUserInfoFn');
|
||||
this.$store.dispatch('app/getUserGroupFn');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.isSub = false;
|
||||
this.getCaptchaFn();
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
verify(data) {
|
||||
var rule = [{
|
||||
name: 'username',
|
||||
checkType: 'required',
|
||||
errorMsg: '请输入用户名'
|
||||
}, {
|
||||
name: 'password',
|
||||
checkType: 'required',
|
||||
errorMsg: '请输入密码'
|
||||
}, {
|
||||
name: 'captcha_code',
|
||||
checkType: 'required',
|
||||
errorMsg: '请输入验证码'
|
||||
}];
|
||||
|
||||
var checkRes = validate.check(data, rule);
|
||||
if (checkRes) {
|
||||
return true;
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: validate.error
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
menu: function(menu) {
|
||||
if (menu && menu.length) {
|
||||
if (menu[0].path) this.$util.redirectTo(menu[0].path, {}, 'redirectTo');
|
||||
else this.$util.redirectTo('/pages/stat/index', {}, 'redirectTo');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-image:url(@/static/login_bg.png);
|
||||
|
||||
.login-bg {
|
||||
margin-right: 1.5rem;
|
||||
width: 5.9rem;
|
||||
height: 4.3rem;
|
||||
|
||||
image {
|
||||
width: 5.9rem;
|
||||
height: 4.3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login-wrap {
|
||||
padding: 0.3rem 0;
|
||||
width: 3.48rem;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0.01rem 0.09rem 0 rgba(15, 92, 251, 0.12);
|
||||
border-radius: 0.05rem;
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
|
||||
image {
|
||||
width: 2.13rem;
|
||||
height: 0.78rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 0.25rem;
|
||||
margin-top: 0.1rem;
|
||||
color: #222222;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 0.16rem;
|
||||
color: #969799;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 0.2rem 0;
|
||||
|
||||
.input-wrap {
|
||||
width: 2.85rem;
|
||||
padding: 0 0.1rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
margin-top: 0.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
border-radius: 0.05rem;
|
||||
|
||||
.iconfont {
|
||||
margin-right: .1rem;
|
||||
font-size: .2rem;
|
||||
color: #46586E;
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
font-size: $uni-font-size-base;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
font-size: $uni-font-size-base;
|
||||
color: #999999;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.send-code {
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.captcha {
|
||||
width: 0.8rem;
|
||||
height: 0.3rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pass-show {
|
||||
font-size: 0.14rem;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 2.85rem;
|
||||
margin-top: 0.3rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
border-radius: 0.05rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
126
addon/cashier/source/os/pages/marketing/coupon_detail.vue
Executable file
126
addon/cashier/source/os/pages/marketing/coupon_detail.vue
Executable file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="coupons-detail">
|
||||
<view class="common-wrap common-form fixd common-scrollbar" v-if="!loading">
|
||||
<view class="title-back flex items-center cursor-pointer" @click="backFn">
|
||||
<text class="iconfont iconqianhou1"></text>
|
||||
<text class="left">返回</text>
|
||||
<text class="content">|</text>
|
||||
<text>优惠券详情</text>
|
||||
</view>
|
||||
<view class="common-title">基本信息</view>
|
||||
<view class="flex flex-wrap">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">优惠券名称:</label>
|
||||
<view class="form-input-inline">{{ couponsData.coupon_name }}</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">优惠券类型:</label>
|
||||
<view class="form-input-inline">{{ couponsData.type == 'reward' ? '满减' : '折扣' }}</view>
|
||||
</view>
|
||||
<view class="common-form-item" v-if="couponsData.type == 'reward'">
|
||||
<label class="form-label">优惠面额:</label>
|
||||
<view class="form-input-inline">¥{{ couponsData.money }}元</view>
|
||||
</view>
|
||||
<view class="common-form-item" v-else>
|
||||
<label class="form-label">优惠券折扣:</label>
|
||||
<view class="form-input-inline">{{ couponsData.discount }}折</view>
|
||||
</view>
|
||||
<view class="common-form-item" v-if="couponsData.type == 'discount' && couponsData.discount_limit != 0">
|
||||
<label class="form-label">最多优惠:</label>
|
||||
<view class="form-input-inline">¥{{ couponsData.discount_limit }}元</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">使用门槛: </label>
|
||||
<view class="form-input-inline">¥{{ couponsData.at_least }}元</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">是否允许直接领取:</label>
|
||||
<view class="form-input-inline">{{ couponsData.is_show === 1 ? '是' : '否' }}</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">发放数量:</label>
|
||||
<view class="form-input-inline">{{ (couponsData.is_show == 0 || couponsData.count == -1) ? '无限制' : couponsData.count + '张' }}</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">最大领取数量:</label>
|
||||
<view class="form-input-inline" v-if="couponsData.is_show == 0 || couponsData.max_fetch == 0">无领取限制</view>
|
||||
<view class="form-input-inline" v-else>{{ couponsData.max_fetch }}张/人</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">有效期:</label>
|
||||
<view class="form-input-inline radio-list" v-if="couponsData.validity_type == 0">{{ couponsData.end_time }}</view>
|
||||
<view class="form-input-inline radio-list" v-else-if="couponsData.validity_type == 1">领取后 {{ couponsData.fixed_term }}天 有效</view>
|
||||
<view class="form-input-inline radio-list" v-else>长期有效</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">使用渠道:</label>
|
||||
<view class="form-input-inline">
|
||||
{{ couponsData.use_channel === 'all' ? '线上线下使用' :couponsData.use_channel === 'online' ?'线上使用':'线下使用' }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="couponsData.use_channel != 'online'" class="common-form-item">
|
||||
<label class="form-label">适用门店:</label>
|
||||
<view class="form-input-inline truncate">
|
||||
<text v-if="couponsData.use_store === 'all'">全部门店</text>
|
||||
<text v-else :title="couponsData.use_store_list.map(v=>{return v.store_name}).join('、')">{{ couponsData.use_store_list.map(v=>{return v.store_name}).join('、') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">活动商品:</label>
|
||||
<view class="form-input-inline radio-list">
|
||||
{{couponsData.goods_type == 1 ? '全部商品参与' : couponsData.goods_type == 2 ? '指定商品参与' : '指定不参与商品' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item coupons-img">
|
||||
<label class="form-label">优惠券图片:</label>
|
||||
<view class="form-input-inline upload-box">
|
||||
<view class="upload">
|
||||
<image :src="$util.img(couponsData.image)" mode="heightFix" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-title">数据统计</view>
|
||||
<view class="data flex flex-wrap">
|
||||
<view class="data-item">
|
||||
<view class="title">发放数</view>
|
||||
<view class="content">{{ couponsData.count||0 }}</view>
|
||||
</view>
|
||||
<view class="data-item">
|
||||
<view class="title">领取数</view>
|
||||
<view class="content">{{ couponsData.lead_count||0 }}</view>
|
||||
</view>
|
||||
<view class="data-item">
|
||||
<view class="title">使用数</view>
|
||||
<view class="content">{{ couponsData.used_count||0 }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-title mt-20">领取记录</view>
|
||||
<view class="record flex">
|
||||
<block v-for="item in statusList">
|
||||
<view :class="{'active':item.value==option.state}" type="default" @click="queryRecord(item.value)">{{ item.label }}</view>
|
||||
</block>
|
||||
</view>
|
||||
<uniDataTable url="/coupon/storeapi/membercoupon/getReceiveCouponPageList" :option="option" :cols="cols" ref="couponListTable" />
|
||||
<block v-if="couponsData.goods_type!=1">
|
||||
<view class="common-title mt-20">{{couponsData.goods_type==2?'指定商品参与':'指定不参与商品'}}</view>
|
||||
<uniDataTable :cols="goodsListCols" :data="couponsData.goods_list" classType />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
<script>
|
||||
import couponDetail from './public/js/coupon_detail.js';
|
||||
import uniDataTable from '@/components/uni-data-table/uni-data-table.vue';
|
||||
export default {
|
||||
components:{
|
||||
uniDataTable
|
||||
},
|
||||
mixins: [couponDetail]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/coupon_detail.scss';
|
||||
</style>
|
||||
102
addon/cashier/source/os/pages/marketing/coupon_list.vue
Executable file
102
addon/cashier/source/os/pages/marketing/coupon_list.vue
Executable file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="coupons-list">
|
||||
<view class="add-coupons">
|
||||
<button type="default" class="screen-btn" @click="add">添加优惠券</button>
|
||||
</view>
|
||||
<view class="screen-warp common-form">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline">
|
||||
<label class="form-label">优惠券名称</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="option.coupon_name" placeholder="请输入优惠券名称" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">优惠券类型</label>
|
||||
<view class="form-input-inline border-0">
|
||||
<select-lay :zindex="10" :value="option.type" name="type" placeholder="请选择优惠券类型" :options="typeList" @selectitem="selectCouponsType"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">优惠券状态</label>
|
||||
<view class="form-input-inline border-0">
|
||||
<select-lay :zindex="9" :value="option.status" name="status" placeholder="请选择优惠券状态" :options="statusList" @selectitem="selectStatus"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">适用场景</label>
|
||||
<view class="form-input-inline border-0">
|
||||
<select-lay :zindex="9" :value="option.use_channel" name="status" placeholder="请选择优惠券状态" :options="useChannelList" @selectitem="selectUseChannel"/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="form-inline">
|
||||
<label class="form-label">有效期限</label>
|
||||
<view class="form-input-inline border-0">
|
||||
<select-lay :zindex="9" :value="option.validity_type" name="validity_type" placeholder="请选择有效期限" :options="validityTypeList" @selectitem="selectValidityType"/>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="searchFn()">筛选</button>
|
||||
<button type="default" @click="resetFn()">重置</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uniDataTable url="/coupon/storeapi/coupon/lists" :option="option" :cols="cols" ref="couponListTable">
|
||||
<template v-slot:action="dataTable">
|
||||
<view class="action-btn-wrap">
|
||||
<text v-if="dataTable.value.status=='1'" class="action-item" @click="promotion(dataTable.value.coupon_type_id)">推广</text>
|
||||
<text v-if="dataTable.value.status=='1' && globalStoreInfo.store_id===dataTable.value.store_id" class="action-item" @click="edit(dataTable.value.coupon_type_id)">编辑</text>
|
||||
<text class="action-item" @click="detail(dataTable.value.coupon_type_id)">详情</text>
|
||||
<text v-if="dataTable.value.status=='1' && globalStoreInfo.store_id===dataTable.value.store_id" class="action-item" @click="closeOpen(dataTable.value.coupon_type_id)">关闭</text>
|
||||
<text v-if="dataTable.value.status!='1' && globalStoreInfo.store_id===dataTable.value.store_id" class="action-item" @click="deleteOpen(dataTable.value.coupon_type_id)">删除</text>
|
||||
</view>
|
||||
</template>
|
||||
</uniDataTable>
|
||||
</view>
|
||||
<!-- 推广 -->
|
||||
<ns-promotion-popup ref="promotionPop" />
|
||||
<!-- 关闭 -->
|
||||
<unipopup ref="closeCouponsPop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要关闭该优惠券吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.closeCouponsPop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="close">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 删除 -->
|
||||
<unipopup ref="deleteCouponsPop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除该优惠券吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.deleteCouponsPop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="del">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniDataTable from '@/components/uni-data-table/uni-data-table.vue';
|
||||
import nsPromotionPopup from '@/components/ns-promotion-popup/ns-promotion-popup.vue';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
import couponList from './public/js/coupon_list.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup,
|
||||
uniDataTable,
|
||||
nsPromotionPopup
|
||||
},
|
||||
mixins: [couponList]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/coupon_list.scss';
|
||||
</style>
|
||||
167
addon/cashier/source/os/pages/marketing/edit_coupon.vue
Executable file
167
addon/cashier/source/os/pages/marketing/edit_coupon.vue
Executable file
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="coupons-form">
|
||||
<view class="common-wrap common-form fixd common-scrollbar">
|
||||
<view class="common-title">{{ couponsData.coupon_type_id ? '编辑优惠券' : '添加优惠券' }}</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label"><text class="required">*</text>优惠券名称</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="couponsData.coupon_name" class="form-input" maxlength="15" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label"><text class="required">*</text>优惠券类型</label>
|
||||
<view class="form-input-inline border-0">
|
||||
<uni-data-checkbox v-model="couponsData.type" :localdata="typeList"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item" v-if="couponsData.type == 'reward'">
|
||||
<label class="form-label"><text class="required">*</text>优惠券面额</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="couponsData.money" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux">元</text>
|
||||
<text class="form-word-aux-line">价格不能小于等于0,可保留两位小数</text>
|
||||
</view>
|
||||
<view class="common-form-item" v-else>
|
||||
<label class="form-label"><text class="required">*</text>优惠券折扣</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="couponsData.discount" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux">折</text>
|
||||
<text class="form-word-aux-line">优惠券折扣不能小于1折,且不可大于9.9折,可保留两位小数</text>
|
||||
</view>
|
||||
<view class="common-form-item" v-if="couponsData.type == 'discount'">
|
||||
<label class="form-label">最多优惠</label>
|
||||
<view class="form-input-inline"><input type="number" v-model="couponsData.discount_limit" class="form-input" /></view>
|
||||
<text class="form-word-aux">元</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label"><text class="required">*</text>满多少元可以使用</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="couponsData.at_least" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux">元</text>
|
||||
<text class="form-word-aux-line">价格不能小于0,无门槛请设为0</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">是否允许直接领取</label>
|
||||
<view class="form-input-inline border-0">
|
||||
<switch :checked="couponsData.is_show === 1" style="transform:scale(0.7)" @change="checkIsShow" />
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="couponsData.is_show === 1">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label"><text class="required">*</text>发放数量</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="couponsData.count" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux">张</text>
|
||||
<text class="form-word-aux-line">优惠券发放数量,没有之后不能领取或发放,-1为不限制发放数量,发放数量只能增加不能减少。</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label"><text class="required">*</text>最大领取数量</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="couponsData.max_fetch" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux">张</text>
|
||||
<text class="form-word-aux-line">数量不能小于0,且必须为整数;设置为0时,可无限领取</text>
|
||||
</view>
|
||||
</block>
|
||||
<view class="common-form-item coupons-img">
|
||||
<label class="form-label">优惠券图片</label>
|
||||
<view class="form-input-inline upload-box" @click="addImg">
|
||||
<view class="upload" v-if="couponsData.image">
|
||||
<image :src="$util.img(couponsData.image)" mode="heightFix" />
|
||||
</view>
|
||||
<view class="upload" v-else>
|
||||
<text class="iconfont iconyunshangchuan"></text>
|
||||
<view>点击上传</view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="form-word-aux-line">建议尺寸:325*95像素,图片上传默认不限制大小</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">有效期类型</label>
|
||||
<view class="form-input-inline border-0 radio-list">
|
||||
<uni-data-checkbox v-model="couponsData.validity_type" :localdata="validityTypeList"/>
|
||||
</view>
|
||||
<view class="form-word-aux-line top" v-if="couponsData.validity_type === 0">
|
||||
<view class="w-250">
|
||||
<uni-datetime-picker v-model="couponsData.end_time" type="timestamp" :clearIcon="false" @change="changeTime" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item" v-if="couponsData.validity_type === 1">
|
||||
<label class="form-label"><text class="required">*</text>领取后几天有效</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="couponsData.fixed_term" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux">天</text>
|
||||
<text class="form-word-aux-line">不能小于等于0,且必须为整数</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">活动商品</label>
|
||||
<view class="form-input-inline border-0 radio-list">
|
||||
<uni-data-checkbox v-model="couponsData.goods_type" :localdata="goodsTypeList" @change="goodsType"/>
|
||||
</view>
|
||||
<view class="form-word-aux-line top" v-if="couponsData.goods_type==2||couponsData.goods_type===3">
|
||||
<view class="table-wrap">
|
||||
<view class="table-head">
|
||||
<view class="table-tr">
|
||||
<view class="table-th" style="flex: 5;">商品名称</view>
|
||||
<view class="table-th" style="flex: 1;">价格</view>
|
||||
<view class="table-th" style="flex: 1;">库存</view>
|
||||
<view class="table-th" style="flex: 1;">操作</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-body">
|
||||
<block v-for="(item, index) in couponsData.goods_list" :key="index">
|
||||
<view class="table-tr">
|
||||
<view class="table-td goods-name" style="flex: 5;">{{ item.goods_name }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.price || '0.00' }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.goods_stock || 0 }}</view>
|
||||
<view class="table-td" style="flex: 1;">
|
||||
<button type="default" class="delete" @click="delGoods(item.sku_id)">删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="table-tr table-empty" v-if="!couponsData.goods_list.length">暂无数据,请选择商品数据</view>
|
||||
</view>
|
||||
</view>
|
||||
<button type="default" class="gooods_select" @click="dialogVisible = true">选择商品</button>
|
||||
</view>
|
||||
<view class="form-word-aux-line top" v-if="couponsData.goods_type==4||couponsData.goods_type===5">
|
||||
<view class="flex items-center">
|
||||
<button type="default" class="gooods_select" @click="$refs.couponCategoryPop.open(couponsData.goods_ids_real?couponsData.goods_ids_real.split(','):[])">选择商品分类</button>
|
||||
<text class="goods_names">{{couponsData.goods_names}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">适用场景</label>
|
||||
<view class="form-input-inline border-0 radio-list">
|
||||
<uni-data-checkbox v-model="couponsData.use_channel" :localdata="useChannelList"/>
|
||||
</view>
|
||||
<text class="form-word-aux-line">在小程序和pc端商城下单为线上使用,在收银台下单为线下使用。</text>
|
||||
</view>
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="saveFn">保存</button>
|
||||
<button type="default" @click="backFn">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<stock-goods-dialog v-model="dialogVisible" apiType="spu" @selectGoods="selectGoods" />
|
||||
<coupon-category-popup ref="couponCategoryPop" @confirm="goodsCategoryConfirm"/>
|
||||
</base-page>
|
||||
</template>
|
||||
<script>
|
||||
import editCoupon from './public/js/edit_coupon.js';
|
||||
import couponCategoryPopup from '@/components/coupon-category-popup/coupon-category-popup.vue'
|
||||
export default {
|
||||
mixins: [editCoupon]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/edit_coupon.scss';
|
||||
</style>
|
||||
121
addon/cashier/source/os/pages/marketing/public/css/coupon_detail.scss
Executable file
121
addon/cashier/source/os/pages/marketing/public/css/coupon_detail.scss
Executable file
@@ -0,0 +1,121 @@
|
||||
.coupons-detail {
|
||||
position: relative;
|
||||
height: calc(100vh - 0.4rem);
|
||||
background-color: #fff;
|
||||
.common-wrap.fixd {
|
||||
padding: 30rpx;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 0.85rem !important;
|
||||
box-sizing: border-box;
|
||||
|
||||
.form-label {
|
||||
width: 1.7rem !important;
|
||||
height: 0.3rem !important;
|
||||
line-height: 0.3rem !important;
|
||||
padding: 0 0.15rem;
|
||||
}
|
||||
.common-form-item{
|
||||
width: 33.333%;
|
||||
height: 0.3rem;
|
||||
margin-bottom: 0;
|
||||
.form-input-inline{
|
||||
border-width: 0 !important;
|
||||
width: calc(100% - 1.8rem);
|
||||
}
|
||||
&.coupons-img{
|
||||
-webkit-box-align: start;
|
||||
-ms-flex-align: start;
|
||||
-webkit-align-items: flex-start;
|
||||
align-items: flex-start;
|
||||
width: 100% !important;
|
||||
height: auto;
|
||||
.upload-box {
|
||||
border: 0.01rem dashed #e6e6e6 !important;
|
||||
width: 2.5rem !important;
|
||||
height: 1.2rem !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.upload {
|
||||
text-align: center;
|
||||
color: #5a5a5a;
|
||||
|
||||
.iconfont {
|
||||
font-size: 0.3rem;
|
||||
}
|
||||
|
||||
image {
|
||||
max-width: 100%;
|
||||
height: 1.2rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
&.mt-20{
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
}
|
||||
.data{
|
||||
margin-top: 0.1rem;
|
||||
.data-item{
|
||||
width: 33.333%;
|
||||
text-align: center;
|
||||
.title{
|
||||
color: #909399;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.content{
|
||||
font-size: 0.26rem;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
}
|
||||
/deep/ .member-img{
|
||||
width: 0.6rem;
|
||||
height: 0.6rem;
|
||||
margin-right: 0.1rem;
|
||||
-ms-flex-negative: 0;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/deep/ .member-nickname{
|
||||
width: 2.3rem;
|
||||
}
|
||||
/deep/ .member-mobile{
|
||||
width: 2.3rem;
|
||||
}
|
||||
.record{
|
||||
margin-bottom: 0.2rem;
|
||||
view {
|
||||
width: 1rem;
|
||||
height: 0.35rem;
|
||||
line-height: 0.35rem;
|
||||
text-align: center;
|
||||
font-size: 0.14rem;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-left-width: 0;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
border-color: $primary-color;
|
||||
color: $primary-color;
|
||||
background-color: var(--primary-color-light-9);
|
||||
box-shadow: -0.01rem 0 0 0 $primary-color;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-left-width: 0.01rem;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
124
addon/cashier/source/os/pages/marketing/public/css/coupon_list.scss
Executable file
124
addon/cashier/source/os/pages/marketing/public/css/coupon_list.scss
Executable file
@@ -0,0 +1,124 @@
|
||||
view {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
|
||||
.record-body {
|
||||
width: 10rem;
|
||||
min-height: 7rem;
|
||||
}
|
||||
|
||||
.add-coupons{
|
||||
margin-bottom: 0.1rem;
|
||||
|
||||
button{
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
padding: 0 0.2rem;
|
||||
height: 0.36rem;
|
||||
line-height: .36rem;
|
||||
font-size: 0.14rem;
|
||||
&::after{
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 筛选面板
|
||||
.screen-warp {
|
||||
padding: 0.15rem 0.15rem 0;
|
||||
background-color: #f2f3f5;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
.common-form-item .form-label {
|
||||
width: 1.2rem;
|
||||
}
|
||||
|
||||
.common-btn-wrap {
|
||||
margin-left: 1.2rem;
|
||||
}
|
||||
|
||||
.coupons-category .form-input-inline {
|
||||
width: 2.8rem;
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
|
||||
.common-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.input-append {
|
||||
position: relative;
|
||||
|
||||
.form-input {
|
||||
padding-right: 0.3rem;
|
||||
}
|
||||
|
||||
.unit {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0.1rem;
|
||||
height: 0.35rem;
|
||||
line-height: 0.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-input-inline.split-wrap {
|
||||
width: initial;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.coupons-list {
|
||||
display: block;
|
||||
width: 100%;
|
||||
@extend %body-overhide;
|
||||
padding: 0.15rem 0.15rem 0;
|
||||
background-color: #fff;
|
||||
|
||||
/deep/ .coupons-content {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.action-btn-wrap {
|
||||
.action-item {
|
||||
margin-left: 0.1rem;
|
||||
color: $primary-color;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .batch-action {
|
||||
.batch-item {
|
||||
margin-right: 0.15rem;
|
||||
border: 0.01rem solid rgba(0, 0, 0, 0.2);
|
||||
padding: 0.05rem;
|
||||
border-radius: 0.03rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
199
addon/cashier/source/os/pages/marketing/public/css/edit_coupon.scss
Executable file
199
addon/cashier/source/os/pages/marketing/public/css/edit_coupon.scss
Executable file
@@ -0,0 +1,199 @@
|
||||
.coupons-form {
|
||||
position: relative;
|
||||
.common-wrap.fixd {
|
||||
padding: 30rpx;
|
||||
height: calc(100vh - 0.4rem);
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
|
||||
.form-label {
|
||||
width: 1.7rem !important;
|
||||
}
|
||||
|
||||
.form-input-inline /deep/ .uni-select {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.common-btn-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
}
|
||||
|
||||
.form-word-aux-line {
|
||||
margin-left: 1.7rem !important;
|
||||
.gooods_select{
|
||||
margin: 0;
|
||||
}
|
||||
.goods_names{
|
||||
margin-left: 0.15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
border: 0.01rem dashed #e6e6e6 !important;
|
||||
width: 2.5rem !important;
|
||||
height: 1.2rem !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.upload {
|
||||
text-align: center;
|
||||
color: #5a5a5a;
|
||||
|
||||
.iconfont {
|
||||
font-size: 0.3rem;
|
||||
}
|
||||
|
||||
image {
|
||||
max-width: 100%;
|
||||
height: 1.2rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupons-img {
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.map-box {
|
||||
width: 6.5rem;
|
||||
height: 5rem;
|
||||
position: relative;
|
||||
|
||||
.map-icon {
|
||||
position: absolute;
|
||||
top: calc(50% - 0.36rem);
|
||||
left: calc(50% - 0.18rem);
|
||||
width: 0.36rem;
|
||||
height: 0.36rem;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.form-input {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.form-input-inline.btn {
|
||||
height: 0.37rem;
|
||||
line-height: 0.35rem;
|
||||
box-sizing: border-box;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
/deep/ .uni-select-lay-select{
|
||||
height: 0.37rem;
|
||||
width: 2.52rem;
|
||||
margin: 0;
|
||||
}
|
||||
.radio-list{
|
||||
width: 7rem !important;
|
||||
}
|
||||
.radio-item{
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
/deep/ .uni-date-x{
|
||||
height: 0.37rem;
|
||||
|
||||
}
|
||||
.top{
|
||||
margin-top: 0.1rem;
|
||||
|
||||
}
|
||||
.w-250{
|
||||
width: 2.5rem;
|
||||
}
|
||||
.form-input-inline{
|
||||
width: 2.5rem;
|
||||
}
|
||||
.required{
|
||||
color: red;
|
||||
}
|
||||
.table-wrap {
|
||||
position: relative;
|
||||
border: 1rpx solid #ccc;
|
||||
color: #333;
|
||||
.table-head {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
.table-body {
|
||||
.table-tr {
|
||||
&:last-of-type .table-td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-tr {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.table-th,
|
||||
.table-td {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.07rem 0.3rem;
|
||||
border-bottom: 0.01rem solid #ccc;
|
||||
border-right: 0.01rem solid #ccc;
|
||||
text-align: center;
|
||||
|
||||
&:last-of-type {
|
||||
border-right: 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&.goods-name {
|
||||
-webkit-box-pack: start;
|
||||
-ms-flex-pack: start;
|
||||
-webkit-justify-content: flex-start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
margin: 0;
|
||||
font-size: $uni-font-size-base;
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
line-height: 0.32rem;
|
||||
height: 0.32rem;
|
||||
&::after{
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.table-empty {
|
||||
justify-content: center;
|
||||
padding: 0.3rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.gooods_select{
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
padding: 0 0.2rem;
|
||||
height: 0.36rem;
|
||||
line-height: .36rem;
|
||||
font-size: 0.14rem;
|
||||
border-radius: 3px;
|
||||
margin-top: 0.1rem;
|
||||
&::after{
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
169
addon/cashier/source/os/pages/marketing/public/js/coupon_detail.js
Executable file
169
addon/cashier/source/os/pages/marketing/public/js/coupon_detail.js
Executable file
@@ -0,0 +1,169 @@
|
||||
import {getCouponDetail } from '@/api/marketing.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
couponsData: {
|
||||
coupon_type_id:'',
|
||||
coupon_name: "",
|
||||
type: "reward",
|
||||
money: "",
|
||||
discount: "",
|
||||
discount_limit: "",
|
||||
at_least: "",
|
||||
is_show: 1,
|
||||
count: "",
|
||||
max_fetch: "",
|
||||
image: "",
|
||||
validity_type: 0,
|
||||
end_time: this.$util.timeFormat(Date.parse(new Date()) / 1000),
|
||||
fixed_term: 0,
|
||||
goods_type:1,
|
||||
lead_count:0,
|
||||
used_count:0,
|
||||
use_channel:'',
|
||||
use_store:'',
|
||||
use_store_list:[],
|
||||
goods_list:[]
|
||||
},
|
||||
loading:false,
|
||||
cols: [{
|
||||
field: 'account_data',
|
||||
width: 20,
|
||||
title: '会员信息',
|
||||
align: 'left',
|
||||
templet: data => {
|
||||
let img = this.$util.img(data.headimg);
|
||||
let html = `
|
||||
<view class="member-content flex">
|
||||
<image class="member-img" src="${img}" mode="aspectFit"/>
|
||||
<view class="flex flex-col justify-between">
|
||||
<text class="member-nickname multi-hidden">${data.nickname}</text>
|
||||
<text class="member-mobile multi-hidden">${data.mobile}</text>
|
||||
</view>
|
||||
</view>
|
||||
`;
|
||||
return html;
|
||||
}
|
||||
}, {
|
||||
field: 'coupon_name',
|
||||
width: 15,
|
||||
title: '优惠券',
|
||||
align: 'left',
|
||||
},{
|
||||
title: '类型',
|
||||
width: 10,
|
||||
unresize: 'false',
|
||||
templet: data=> {
|
||||
return data.type == 'reward' ? '满减券' : '折扣券';
|
||||
}
|
||||
},{
|
||||
field: 'get_type_name',
|
||||
width: 15,
|
||||
title: '获取方式',
|
||||
align: 'left',
|
||||
},{
|
||||
title: '状态',
|
||||
width: 10,
|
||||
unresize: 'false',
|
||||
templet: data=> {
|
||||
var str = '';
|
||||
switch (data.state) {
|
||||
case 1:
|
||||
str = '已领取';
|
||||
break;
|
||||
case 2:
|
||||
str = '已使用';
|
||||
break;
|
||||
case 3:
|
||||
str = '已过期';
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
},{
|
||||
title: '领取时间',
|
||||
width: 15,
|
||||
unresize: 'false',
|
||||
templet: data=> {
|
||||
return this.$util.timeFormat(Date.parse(new Date(data.fetch_time)));
|
||||
}
|
||||
}, {
|
||||
title: '使用时间',
|
||||
width: 15,
|
||||
templet: data=> {
|
||||
return data.use_time ? this.$util.timeFormat(Date.parse(new Date(data.use_time))) : '';
|
||||
}
|
||||
},],
|
||||
statusList: [{
|
||||
value: '',
|
||||
label: '全部'
|
||||
},{
|
||||
value: '1',
|
||||
label: '已领取'
|
||||
}, {
|
||||
value: '2',
|
||||
label: '已使用'
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: '已过期'
|
||||
}],
|
||||
option:{
|
||||
page_size: 9,
|
||||
coupon_type_id:'',
|
||||
state: '',
|
||||
},
|
||||
goodsListCols:[{
|
||||
field: 'goods_name',
|
||||
width: 60,
|
||||
title: '商品名称',
|
||||
align: 'left',
|
||||
},{
|
||||
title: '价格',
|
||||
width: 20,
|
||||
unresize: 'false',
|
||||
templet: data=> {
|
||||
return data.price || '0.00';
|
||||
}
|
||||
},{
|
||||
title: '库存',
|
||||
width: 20,
|
||||
unresize: 'false',
|
||||
templet: data=> {
|
||||
return data.goods_stock || 0;
|
||||
}
|
||||
},]
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
if(option.coupon_type_id){
|
||||
this.couponsData.coupon_type_id = option.coupon_type_id
|
||||
this.option.coupon_type_id = option.coupon_type_id
|
||||
this.getData(option.coupon_type_id)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData(coupon_type_id) {
|
||||
this.loading = true
|
||||
getCouponDetail(coupon_type_id).then(res=>{
|
||||
let data = res.data;
|
||||
if(res.code>=0 && data) {
|
||||
Object.keys(this.couponsData).forEach(key => {
|
||||
this.couponsData[key] = data.info[key]
|
||||
if (key == 'end_time') this.couponsData[key] = this.couponsData.end_time = this.$util.timeFormat(Date.parse(new Date(data.info[key])))
|
||||
})
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
queryRecord(val){
|
||||
this.option.state = val
|
||||
this.$refs.couponListTable.load({
|
||||
page: 1
|
||||
});
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/marketing/coupon_list');
|
||||
},
|
||||
}
|
||||
}
|
||||
221
addon/cashier/source/os/pages/marketing/public/js/coupon_list.js
Executable file
221
addon/cashier/source/os/pages/marketing/public/js/coupon_list.js
Executable file
@@ -0,0 +1,221 @@
|
||||
import {closeCoupon, deleteCoupon} from '@/api/marketing.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
option: {
|
||||
page_size: 10,
|
||||
coupon_name: '',
|
||||
type: '',
|
||||
status: '',
|
||||
use_channel: '',
|
||||
},
|
||||
coupon_type_id: "",
|
||||
flag: false,
|
||||
typeList: [{
|
||||
value: 'reward',
|
||||
label: '满减'
|
||||
}, {
|
||||
value: 'discount',
|
||||
label: '折扣'
|
||||
},],
|
||||
statusList: [{
|
||||
value: '1',
|
||||
label: '进行中'
|
||||
}, {
|
||||
value: '2',
|
||||
label: '已结束'
|
||||
}, {
|
||||
value: '-1',
|
||||
label: '已关闭'
|
||||
}],
|
||||
// validityTypeList:[{
|
||||
// value: '0',
|
||||
// label: '固定时间'
|
||||
// }, {
|
||||
// value: '1',
|
||||
// label: '相对时间'
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '长期有效'
|
||||
// }],
|
||||
useChannelList:[
|
||||
{
|
||||
value: 'all',
|
||||
label: '线上线下使用'
|
||||
},
|
||||
{
|
||||
value: 'online',
|
||||
label: '线上使用'
|
||||
},
|
||||
{
|
||||
value: 'offline',
|
||||
label: '线下使用'
|
||||
},
|
||||
],
|
||||
cols: [{
|
||||
field: 'coupon_name',
|
||||
width: 15,
|
||||
title: '优惠券名称',
|
||||
align: 'left',
|
||||
}, {
|
||||
field: 'reward',
|
||||
title: '优惠券类型',
|
||||
align: 'left',
|
||||
width: 10,
|
||||
templet: function (data) {
|
||||
if (data.type == 'reward') {
|
||||
return '满减';
|
||||
} else {
|
||||
return '折扣';
|
||||
}
|
||||
}
|
||||
}, {
|
||||
title: '优惠金额/折扣',
|
||||
width: 10,
|
||||
align: 'left',
|
||||
templet: function (data) {
|
||||
if (data.type == 'reward') {
|
||||
return `<span style="padding-right: 15px;">¥${data.money}</span>`;
|
||||
} else {
|
||||
return `<span style="padding-right: 15px;">${data.discount}折</span>`;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
field: 'count',
|
||||
title: '发放数量',
|
||||
width: 10,
|
||||
templet: function (data) {
|
||||
return data.is_show == 0 || data.count == -1 ? '无限制' : data.count;
|
||||
}
|
||||
}, {
|
||||
title: '剩余数量',
|
||||
width: 10,
|
||||
templet: function (data) {
|
||||
return data.is_show == 0 || data.count == -1 ? '无限制' : data.count - data.lead_count;
|
||||
}
|
||||
}, {
|
||||
title: '领取上限',
|
||||
width: 10,
|
||||
templet: function (data) {
|
||||
return data.is_show == 0 || data.max_fetch == 0 ? '无领取限制' : data.max_fetch + '张/人';
|
||||
}
|
||||
}, {
|
||||
title: '有效期限',
|
||||
unresize: 'false',
|
||||
width: 15,
|
||||
templet: (data) => {
|
||||
if (data.validity_type == 0) {
|
||||
return `失效期:${this.$util.timeFormat(data.end_time)}`
|
||||
} else if (data.validity_type == 1) {
|
||||
return `领取后,${data.fixed_term}天有效`
|
||||
} else {
|
||||
return '长期有效'
|
||||
}
|
||||
}
|
||||
},{
|
||||
field: 'use_channel_name',
|
||||
title: '适用场景',
|
||||
unresize: 'false',
|
||||
width: 10
|
||||
}, {
|
||||
field: 'status_name',
|
||||
title: '状态',
|
||||
width: 10
|
||||
}, {
|
||||
width: 10,
|
||||
title: '操作',
|
||||
align: 'right',
|
||||
action: true
|
||||
}],
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
},
|
||||
methods: {
|
||||
switchStoreAfter() {
|
||||
this.searchFn();
|
||||
},
|
||||
selectCouponsType(index) {
|
||||
this.option.type = index == -1 ? '' : this.typeList[index].value;
|
||||
},
|
||||
selectStatus(index) {
|
||||
this.option.status = index == -1 ? '' : this.statusList[index].value;
|
||||
},
|
||||
selectUseChannel(index) {
|
||||
this.option.use_channel = index == -1 ? '' : this.useChannelList[index].value;
|
||||
},
|
||||
// selectValidityType(index){
|
||||
// this.option.validity_type = index == -1 ? '' : this.validityTypeList[index].value;
|
||||
// },
|
||||
// 搜索商品
|
||||
searchFn() {
|
||||
this.$refs.couponListTable.load({
|
||||
page: 1
|
||||
});
|
||||
},
|
||||
resetFn() {
|
||||
this.option = {
|
||||
page_size: 10,
|
||||
coupon_name: '',
|
||||
type: '',
|
||||
status: '',
|
||||
}
|
||||
this.$refs.couponListTable.load({
|
||||
page: 1,
|
||||
coupon_name: '',
|
||||
type: '',
|
||||
status: '',
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.$util.redirectTo('/pages/marketing/edit_coupon');
|
||||
},
|
||||
detail(coupon_type_id) {
|
||||
this.$util.redirectTo('/pages/marketing/coupon_detail', {
|
||||
coupon_type_id
|
||||
});
|
||||
},
|
||||
edit(coupon_type_id) {
|
||||
this.$util.redirectTo('/pages/marketing/edit_coupon', {
|
||||
coupon_type_id
|
||||
});
|
||||
},
|
||||
closeOpen(coupon_type_id) {
|
||||
this.coupon_type_id = coupon_type_id
|
||||
this.$refs.closeCouponsPop.open()
|
||||
},
|
||||
close() {
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
this.$refs.closeCouponsPop.close()
|
||||
closeCoupon(this.coupon_type_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.flag = false;
|
||||
|
||||
this.$refs.couponListTable.load();
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteOpen(coupon_type_id) {
|
||||
this.coupon_type_id = coupon_type_id
|
||||
this.$refs.deleteCouponsPop.open()
|
||||
},
|
||||
del() {
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
this.$refs.deleteCouponsPop.close()
|
||||
deleteCoupon(this.coupon_type_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.flag = false;
|
||||
|
||||
this.$refs.couponListTable.load();
|
||||
}
|
||||
})
|
||||
},
|
||||
promotion(coupon_type_id){
|
||||
this.$refs.promotionPop.open({coupon_type_id})
|
||||
}
|
||||
}
|
||||
}
|
||||
382
addon/cashier/source/os/pages/marketing/public/js/edit_coupon.js
Executable file
382
addon/cashier/source/os/pages/marketing/public/js/edit_coupon.js
Executable file
@@ -0,0 +1,382 @@
|
||||
import {
|
||||
getCouponDetail,
|
||||
addCoupon,
|
||||
editCoupon,
|
||||
} from '@/api/marketing.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
couponsData: {
|
||||
coupon_type_id: '',
|
||||
coupon_name: "",
|
||||
type: "reward",
|
||||
money: "",
|
||||
discount: "",
|
||||
discount_limit: "",
|
||||
at_least: "",
|
||||
is_show: 1,
|
||||
count: "",
|
||||
max_fetch: "",
|
||||
image: "",
|
||||
validity_type: 0,
|
||||
end_time: this.$util.timeFormat((Date.parse(new Date()) / 1000) + (10 * 24 * 60 * 60)),
|
||||
fixed_term: 0,
|
||||
goods_type: 1,
|
||||
goods_ids: '',
|
||||
goods_ids_real:'',
|
||||
goods_list: [],
|
||||
goods_names:'',
|
||||
use_channel:'all',
|
||||
},
|
||||
flag: false,
|
||||
goods_ids: [],
|
||||
typeList: [{
|
||||
value: 'reward',
|
||||
text: '满减'
|
||||
}, {
|
||||
value: 'discount',
|
||||
text: '折扣'
|
||||
},],
|
||||
validityTypeList: [{
|
||||
value: 0,
|
||||
text: '固定时间'
|
||||
}, {
|
||||
value: 1,
|
||||
text: '领取之日起'
|
||||
}, {
|
||||
value: 2,
|
||||
text: '长期有效'
|
||||
}],
|
||||
goodsTypeList: [{
|
||||
value: 1,
|
||||
text: '全部商品参与'
|
||||
}, {
|
||||
value: 2,
|
||||
text: '指定商品参与'
|
||||
}, {
|
||||
value: 3,
|
||||
text: '指定商品不参与'
|
||||
}, {
|
||||
value: 4,
|
||||
text: '指定分类参与'
|
||||
}, {
|
||||
value: 5,
|
||||
text: '指定分类不参与'
|
||||
}],
|
||||
|
||||
useChannelList: [{
|
||||
value: 'all',
|
||||
text: '线上线下使用'
|
||||
}, {
|
||||
value: 'online',
|
||||
text: '线上使用'
|
||||
}, {
|
||||
value: 'offline',
|
||||
text: '线下使用'
|
||||
}],
|
||||
dialogVisible: false
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
if (option.coupon_type_id) {
|
||||
this.couponsData.coupon_type_id = option.coupon_type_id
|
||||
this.getData(option.coupon_type_id)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'couponsData.validity_type'(newValue) {
|
||||
if (newValue === 0) this.couponsData.end_time = this.$util.timeFormat((Date.parse(new Date()) / 1000) + (10 * 24 * 60 * 60))
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData(coupon_type_id) {
|
||||
getCouponDetail(coupon_type_id).then(res => {
|
||||
let data = res.data;
|
||||
if (res.code >= 0 && data) {
|
||||
Object.keys(this.couponsData).forEach(key => {
|
||||
this.couponsData[key] = data.info[key]
|
||||
if (key == 'end_time') this.couponsData[key] = this.couponsData.end_time = this.$util.timeFormat(Date.parse(new Date(data.info[key])))
|
||||
})
|
||||
}
|
||||
this.goods_ids = this.couponsData.goods_list.map(v => v.goods_id)
|
||||
this.couponsData.goods_ids = this.goods_ids.join()
|
||||
})
|
||||
},
|
||||
addImg() {
|
||||
this.$util.upload(1, {
|
||||
path: 'image'
|
||||
}, res => {
|
||||
if (res.length > 0) {
|
||||
this.couponsData.image = res[0];
|
||||
this.$forceUpdate();
|
||||
}
|
||||
});
|
||||
},
|
||||
checkIsShow(e) {
|
||||
this.couponsData.is_show = e.detail.value ? 1 : 0
|
||||
},
|
||||
changeTime(data) {
|
||||
this.couponsData.end_time = data;
|
||||
},
|
||||
selectGoods(data) { //选择数据
|
||||
data.forEach(el => {
|
||||
if (!this.goods_ids.includes(el.goods_id)) {
|
||||
this.goods_ids.push(el.goods_id)
|
||||
this.couponsData.goods_list.push(el)
|
||||
}
|
||||
})
|
||||
},
|
||||
delGoods(id) {//删除已选择的商品
|
||||
this.couponsData.goods_list.splice(this.goods_ids.indexOf(id), 1);
|
||||
this.goods_ids.splice(this.goods_ids.indexOf(id), 1);
|
||||
},
|
||||
checkData() {
|
||||
let _this = this
|
||||
let verify = {
|
||||
days: function (value) {
|
||||
if (_this.couponsData.validity_type == 1) {
|
||||
if (value % 1 != 0) {
|
||||
return '请输入整数';
|
||||
}
|
||||
if (value <= 0) {
|
||||
return '有效天数不能小于等于0';
|
||||
}
|
||||
return ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
number: function (value) {
|
||||
if (value < 0) {
|
||||
return '请输入不小于0的数!'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
coupon_money: function (value) {
|
||||
if (parseFloat(value) > 10000) {
|
||||
return '优惠券面额不能大于10000'
|
||||
}
|
||||
if (parseFloat(value) <= 0) {
|
||||
return '优惠券面额不能小于0'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
int: function (value) {
|
||||
if (value % 1 != 0) {
|
||||
return '最多优惠,请输入整数!'
|
||||
}
|
||||
if (value < 0) {
|
||||
return '最多优惠,请输入大于0的数!'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
money: function (value) {
|
||||
if (value < 0) {
|
||||
return '金额不能小于0'
|
||||
}
|
||||
var arrMen = value.split(".");
|
||||
var val = 0;
|
||||
if (arrMen.length == 2) {
|
||||
val = arrMen[1];
|
||||
}
|
||||
if (val.length > 2) {
|
||||
return '保留小数点后两位'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
time: function (value) {
|
||||
if (_this.couponsData.validity_type == 0) {
|
||||
var now_time = (new Date()).getTime();
|
||||
var end_time = (new Date(value)).getTime();
|
||||
if (now_time > end_time) {
|
||||
return '结束时间不能小于当前时间!'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
max: function (value) {
|
||||
if (!/[\S]+/.test(value)) {
|
||||
return '请输入最大领取数量';
|
||||
}
|
||||
|
||||
if (_this.couponsData.count != -1 && parseFloat(value) > parseFloat(_this.couponsData.count)) {
|
||||
return '最大领取数量不能超过发放数量!';
|
||||
}
|
||||
return ''
|
||||
},
|
||||
fl: function (value, str) {
|
||||
str = str.substring(0, str.length - 1);
|
||||
|
||||
if (value < 1) {
|
||||
return str + "不能小于1折";
|
||||
}
|
||||
|
||||
if (value > 9.9) {
|
||||
return str + "不能大于9.9折";
|
||||
}
|
||||
|
||||
var arrMen = value.split(".");
|
||||
var val = 0;
|
||||
if (arrMen.length == 2) {
|
||||
val = arrMen[1];
|
||||
}
|
||||
if (val.length > 2) {
|
||||
return str + "最多可保留两位小数";
|
||||
}
|
||||
return ''
|
||||
},
|
||||
count: function (value) {
|
||||
if (!/[\S]+/.test(value)) {
|
||||
return '请输入发放数量';
|
||||
}
|
||||
if (value % 1 != 0) {
|
||||
return '请输入整数';
|
||||
}
|
||||
if (value == 0) {
|
||||
return '发放数量不能为0';
|
||||
}
|
||||
if (value != -1 && parseInt(value) < parseInt('{$coupon_type_info.count}')) {
|
||||
return '发放数量不能小于原发放数量!';
|
||||
}
|
||||
return ''
|
||||
}
|
||||
};
|
||||
|
||||
if (!this.couponsData.coupon_name) {
|
||||
this.$util.showToast({
|
||||
title: "请输入优惠券名称"
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (!this.couponsData.type) {
|
||||
this.$util.showToast({
|
||||
title: "请选择优惠券类型"
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (this.couponsData.type === 'reward') {
|
||||
if (!this.couponsData.money) {
|
||||
this.$util.showToast({
|
||||
title: "请输入优惠券面额"
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (verify.number(this.couponsData.money) || verify.money(this.couponsData.money) || verify.coupon_money(this.couponsData.money)) {
|
||||
this.$util.showToast({
|
||||
title: verify.number(this.couponsData.money) || verify.money(this.couponsData.money) || verify.coupon_money(this.couponsData.money)
|
||||
});
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if (!this.couponsData.discount) {
|
||||
this.$util.showToast({
|
||||
title: "请输入优惠券折扣"
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (verify.fl(this.couponsData.discount, '优惠券折扣')) {
|
||||
this.$util.showToast({
|
||||
title: verify.fl(this.couponsData.discount, '优惠券折扣')
|
||||
});
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (this.couponsData.discount_limit) {
|
||||
if (verify.number(this.couponsData.discount_limit) || verify.int(this.couponsData.discount_limit)) {
|
||||
this.$util.showToast({
|
||||
title: verify.number(this.couponsData.discount_limit) || verify.int(this.couponsData.discount_limit)
|
||||
});
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (!this.couponsData.at_least) {
|
||||
this.$util.showToast({
|
||||
title: "请输入满多少元可以使用"
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (verify.number(this.couponsData.at_least) || verify.money(this.couponsData.at_least)) {
|
||||
this.$util.showToast({
|
||||
title: verify.number(this.couponsData.at_least) || verify.money(this.couponsData.at_least)
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (this.couponsData.is_show === 1) {
|
||||
if (verify.count(this.couponsData.count)) {
|
||||
this.$util.showToast({
|
||||
title: verify.count(this.couponsData.count)
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (verify.max(this.couponsData.max_fetch)) {
|
||||
this.$util.showToast({
|
||||
title: verify.max(this.couponsData.max_fetch)
|
||||
});
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (verify.time(this.couponsData.end_time)) {
|
||||
this.$util.showToast({
|
||||
title: verify.time(this.couponsData.end_time)
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (verify.days(this.couponsData.fixed_term)) {
|
||||
this.$util.showToast({
|
||||
title: verify.days(this.couponsData.fixed_term)
|
||||
});
|
||||
return false
|
||||
}
|
||||
if (this.couponsData.goods_type == 2||this.couponsData.goods_type == 3) {
|
||||
if (!this.goods_ids.length) {
|
||||
this.$util.showToast({
|
||||
title: '请选择活动商品'
|
||||
});
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (this.couponsData.goods_type == 4||this.couponsData.goods_type == 5) {
|
||||
if (!this.goods_ids.length) {
|
||||
this.$util.showToast({
|
||||
title: '请选择商品分类'
|
||||
});
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
goodsType(){
|
||||
this.couponsData.goods_ids = ''
|
||||
this.couponsData.goods_ids_real = ''
|
||||
this.goods_ids = []
|
||||
this.couponsData.goods_names = ''
|
||||
},
|
||||
goodsCategoryConfirm(obj){
|
||||
this.goods_ids = obj.id_arr;
|
||||
this.couponsData.goods_names = obj.name_arr.join('、');
|
||||
},
|
||||
saveFn() {
|
||||
if (this.checkData(this.couponsData)) {
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
if (this.couponsData.goods_type != 1) this.couponsData.goods_ids = this.goods_ids.join();
|
||||
let save = this.couponsData.coupon_type_id ? editCoupon : addCoupon;
|
||||
save(this.couponsData).then(res => {
|
||||
this.flag = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
setTimeout(() => {
|
||||
this.backFn();
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/marketing/coupon_list');
|
||||
},
|
||||
}
|
||||
};
|
||||
139
addon/cashier/source/os/pages/member/list.vue
Executable file
139
addon/cashier/source/os/pages/member/list.vue
Executable file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row height-all page-height member-list-wrap">
|
||||
<view class="common-wrap">
|
||||
<view class="left-wrap">
|
||||
<view class="left-wrap-head">
|
||||
<view class="head-text">会员列表</view>
|
||||
</view>
|
||||
<view class="left-wrap-content">
|
||||
<view class="wrap-search-box">
|
||||
<view class="wrap-search">
|
||||
<input placeholder="请输入会员账号 昵称 手机号" v-model="searchMobile" @blur="searchMember()" placeholder-style="font-size:0.14rem" />
|
||||
<text class="iconfont icon31sousuo" @click="searchMember()"></text>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view :scroll-top="scrollTop" @scroll="scroll" @scrolltolower="getMemberListFn()" scroll-y="true" class="common-scrollbar content-list" v-show="!one_judge">
|
||||
<view class="content-item" :class="{ active: memberId == item.member_id }" v-for="(item, index) in memberList" :key="index" @click="selectMember(item.member_id)">
|
||||
<view class="item-img">
|
||||
<image mode="aspectFill" v-if="item.headimg" :src="$util.img(item.headimg)" @error="headError(item)"/>
|
||||
<image mode="aspectFill" v-else :src="$util.img(defaultImg.head)"/>
|
||||
</view>
|
||||
<view class="item-content">
|
||||
<view class="item-title">
|
||||
<view class="item-title-text">{{ item.nickname }}</view>
|
||||
<view class="item-label">{{ item.member_level_name && item.member_level ? item.member_level_name : '非会员' }}</view>
|
||||
</view>
|
||||
<view class="item-desc">
|
||||
<view>{{ item.mobile }}</view>
|
||||
<view>
|
||||
余额:
|
||||
<text>{{ parseFloat(parseFloat(item.balance) + parseFloat(item.balance_money)).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="memberList.length == 0" class="empty">
|
||||
<image src="@/static/member/member-empty.png" mode="widthFix" />
|
||||
<view class="tips">暂无会员</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="add-member">
|
||||
<button type="default" class="primary-btn" @click="$refs.addMemberPop.open()">添加会员</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right-wrap">
|
||||
<view class="right-wrap-head">
|
||||
<view class="head-text">会员详情</view>
|
||||
</view>
|
||||
<ns-member-detail v-if="!one_judge && memberId" ref="memberDetail" :member-id="memberId"/>
|
||||
<view class="empty" v-else-if="!one_judge && !memberId">
|
||||
<image src="@/static/member/member-empty.png" mode="widthFix"/>
|
||||
<view class="tips">暂无会员</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 添加会员 -->
|
||||
<uni-popup ref="addMemberPop">
|
||||
<view class="pop-box add-member-pop-box">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">添加会员</view>
|
||||
<view class="pop-header-close" @click="$refs.addMemberPop.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-scrollbar pop-content">
|
||||
<view class="form-content">
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
手机号:
|
||||
</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<input type="number" class="form-input" v-model="addMemberData.mobile" placeholder="请输入会员手机号" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
会员昵称:
|
||||
</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<input type="text" class="form-input" v-model="addMemberData.nickname" placeholder="请输入会员昵称" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
性别:
|
||||
</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<uni-data-checkbox v-model="addMemberData.sex" :localdata="sex"></uni-data-checkbox>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
生日:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<uni-datetime-picker :end="endTime" v-model="addMemberData.birthday" type="date" :clearIcon="false" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-bottom">
|
||||
<button class="primary-btn" @click="addMemberFn">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dataTable from '@/components/uni-data-table/uni-data-table.vue';
|
||||
import nsMemberDetail from '@/components/ns-member-detail/ns-member-detail.vue';
|
||||
import list from './public/js/list.js';
|
||||
|
||||
export default {
|
||||
components: { dataTable, nsMemberDetail },
|
||||
mixins: [list]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.member-list-wrap .right-wrap >>> .member-head {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/member.scss';
|
||||
</style>
|
||||
343
addon/cashier/source/os/pages/member/public/css/member.scss
Executable file
343
addon/cashier/source/os/pages/member/public/css/member.scss
Executable file
@@ -0,0 +1,343 @@
|
||||
.page-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.common-wrap {
|
||||
display: flex;
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.left-wrap {
|
||||
position: relative;
|
||||
width: 5rem;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
|
||||
.left-wrap-head {
|
||||
height: 0.6rem;
|
||||
box-sizing: border-box;
|
||||
line-height: 0.6rem;
|
||||
display: flex;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
|
||||
.head-icon {
|
||||
position: absolute;
|
||||
right: 0.15rem;
|
||||
font-size: 0.26rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.head-text {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.left-wrap-content {
|
||||
height: calc(100% - 0.6rem);
|
||||
|
||||
.wrap-search-box {
|
||||
height: 0.35rem;
|
||||
padding: 0.1rem 0.2rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
|
||||
.wrap-search {
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding: 0.05rem 0.15rem 0.05rem 0.4rem;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
position: absolute;
|
||||
left: 0.15rem;
|
||||
top: 0.08rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-list {
|
||||
height: calc(100% - 1.23rem);
|
||||
|
||||
.content-item {
|
||||
padding: 0.15rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
|
||||
&.active {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
|
||||
.item-img {
|
||||
width: 0.45rem;
|
||||
height: 0.45rem;
|
||||
border-radius: 50%;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.item-content {
|
||||
padding-left: 0.15rem;
|
||||
width: calc(100% - 0.45rem);
|
||||
box-sizing: border-box;
|
||||
|
||||
.item-title {
|
||||
width: 100%;
|
||||
font-size: 0.16rem;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.item-label {
|
||||
border: 0.01rem solid $primary-color;
|
||||
color: $primary-color;
|
||||
background-color: #fff;
|
||||
border-radius: 0.02rem;
|
||||
width: fit-content;
|
||||
padding: 0.01rem 0.05rem;
|
||||
margin-left: 0.15rem;
|
||||
}
|
||||
|
||||
.item-title-text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 50%;
|
||||
font-size: 0.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
margin-top: 0.15rem;
|
||||
font-size: 0.14rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
text {
|
||||
color: #fe2278;
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-member {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-wrap {
|
||||
width: calc(100% - 5rem);
|
||||
border-left: 0;
|
||||
|
||||
.right-wrap-head {
|
||||
height: 0.6rem;
|
||||
box-sizing: border-box;
|
||||
line-height: 0.6rem;
|
||||
display: flex;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
|
||||
.head-text {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
padding-top: 1.2rem;
|
||||
|
||||
image {
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view {
|
||||
&::-webkit-scrollbar {
|
||||
width: 0.06rem;
|
||||
height: 0.06rem;
|
||||
background-color: rgba($color: #000000, $alpha: 0);
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.06rem;
|
||||
box-shadow: inset 0 0 0.06rem rgba(45, 43, 43, 0.45);
|
||||
background-color: #ddd;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover::-webkit-scrollbar-thumb {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// pop弹框
|
||||
.pop-box {
|
||||
background: #ffffff;
|
||||
width: 8rem;
|
||||
height: 7rem;
|
||||
|
||||
.pop-header {
|
||||
padding: 0 0.15rem 0 0.2rem;
|
||||
height: 0.5rem;
|
||||
line-height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #f0f0f0;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
border-radius: 0.02rem 0.2rem 0 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pop-header-text {
|
||||
}
|
||||
|
||||
.pop-header-close {
|
||||
cursor: pointer;
|
||||
|
||||
text {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
height: calc(100% - 1.05rem);
|
||||
overflow-y: scroll;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pop-bottom {
|
||||
padding: 0.1rem;
|
||||
height: 0.65rem;
|
||||
border-top: 0.01rem solid #eee;
|
||||
|
||||
button {
|
||||
width: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//表单
|
||||
.form-content {
|
||||
.form-item {
|
||||
margin-bottom: 0.1rem;
|
||||
display: flex;
|
||||
|
||||
.form-label {
|
||||
width: 1.3rem;
|
||||
text-align: right;
|
||||
padding-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
width: 2.5rem;
|
||||
line-height: 0.32rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.form-input {
|
||||
border-width: 0.01rem;
|
||||
border-style: solid;
|
||||
background-color: #fff;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 0.02rem;
|
||||
padding-left: 0.1rem;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
font-size: 0.14rem;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.search-wrap {
|
||||
position: relative;
|
||||
|
||||
text {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.1rem;
|
||||
transform: translateY(-50%);
|
||||
border-left: 0.01rem solid #e6e6e6;
|
||||
line-height: 0.3rem;
|
||||
padding-left: 0.1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-member-pop-box {
|
||||
width: 3.8rem;
|
||||
height: 3.38rem;
|
||||
|
||||
.pop-content {
|
||||
overflow-y: inherit;
|
||||
}
|
||||
|
||||
.form-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.form-label {
|
||||
width: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.pop-bottom {
|
||||
height: auto;
|
||||
|
||||
button {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
}
|
||||
159
addon/cashier/source/os/pages/member/public/js/list.js
Executable file
159
addon/cashier/source/os/pages/member/public/js/list.js
Executable file
@@ -0,0 +1,159 @@
|
||||
import {getMemberList, getMemberInfoById, addMember} from '@/api/member.js'
|
||||
|
||||
let _self;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
memberList: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
searchMobile: '',
|
||||
memberId: 0,
|
||||
currentMemberInfo: null,
|
||||
endTime: '',
|
||||
sex: [{
|
||||
text: '未知',
|
||||
value: 0
|
||||
}, {
|
||||
text: '男',
|
||||
value: 1
|
||||
}, {
|
||||
text: '女',
|
||||
value: 2
|
||||
}],
|
||||
addMemberData: {
|
||||
mobile: '',
|
||||
nickname: '',
|
||||
sex: 0,
|
||||
birthday: ''
|
||||
},
|
||||
// 第一次请求列表、详情渲染判断
|
||||
one_judge: true,
|
||||
//无限滚动请求锁
|
||||
memberListLock: true,
|
||||
scrollTop: 0,
|
||||
};
|
||||
},
|
||||
onLoad(data) {
|
||||
_self = this;
|
||||
this.getMemberListFn(data.member_id || 0);
|
||||
let date = new Date();
|
||||
var y = date.getFullYear();
|
||||
var m = date.getMonth() + 1;
|
||||
var d = date.getDate();
|
||||
this.endTime = y + '-' + m + '-' + d;
|
||||
},
|
||||
methods: {
|
||||
// 查询客户列表
|
||||
getMemberListFn(member_id = 0) {
|
||||
if (!this.memberListLock) return false;
|
||||
let data = {
|
||||
page: this.page,
|
||||
page_size: this.pageSize,
|
||||
search_text: this.searchMobile,
|
||||
};
|
||||
getMemberList(data).then(res => {
|
||||
if (res.code >= 0) {
|
||||
if (this.page == 1) this.memberList = [];
|
||||
this.memberList = this.memberList.concat(res.data.list);
|
||||
this.memberList.forEach((item) => {
|
||||
if (item.mobile) {
|
||||
if (this.userInfo && this.userInfo.is_admin == 0) {
|
||||
// 非管理员,不能查看会员手机号
|
||||
item.mobile = item.mobile.substring(0, 4 - 1) + '****' + item.mobile.substring(6 + 1);
|
||||
}
|
||||
} else {
|
||||
item.mobile = '';
|
||||
}
|
||||
});
|
||||
if (this.page == 1 && this.memberList.length > 0) {
|
||||
// 订单页面跳转过来查看 会员详情
|
||||
this.memberId = member_id || this.memberList[0]['member_id'];
|
||||
this.one_judge = false;
|
||||
}else if(this.page == 1){
|
||||
this.one_judge = false;
|
||||
this.memberId = 0
|
||||
} else {
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (this.page == 1) {
|
||||
this.scrollTop = 0
|
||||
}
|
||||
if (res.data.list.length < data.page_size) {
|
||||
this.memberListLock = false
|
||||
} else {
|
||||
this.page++;
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
scroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
searchMember() {
|
||||
this.page = 1;
|
||||
this.one_judge = true;
|
||||
this.memberListLock = true;
|
||||
this.getMemberListFn();
|
||||
},
|
||||
selectMember(member_id) {
|
||||
this.memberId = member_id;
|
||||
},
|
||||
getMemberInfo() {
|
||||
getMemberInfoById(this.memberId).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.currentMemberInfo = res.data;
|
||||
this.currentMemberInfo.birthday = res.data.birthday > 0 ? this.$util.timeFormat(res.data.birthday, 'Y-m-d') : '';
|
||||
this.one_judge = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
verify() {
|
||||
if (!this.addMemberData.mobile) {
|
||||
this.$util.showToast({
|
||||
title: '请输入会员手机号'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.$util.verifyMobile(this.addMemberData.mobile)) {
|
||||
this.$util.showToast({
|
||||
title: '请输入正确的手机号码'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
// 添加客户
|
||||
addMemberFn() {
|
||||
if (this.verify()) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
addMember(this.addMemberData).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.addMemberData = {
|
||||
mobile: '',
|
||||
nickname: '',
|
||||
sex: 0,
|
||||
birthday: ''
|
||||
};
|
||||
this.page = 1;
|
||||
this.one_judge = true;
|
||||
this.memberListLock = true;
|
||||
this.getMemberListFn();
|
||||
this.$refs.addMemberPop.close();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: '该手机号已注册为客户'
|
||||
});
|
||||
}
|
||||
this.flag = false;
|
||||
})
|
||||
}
|
||||
},
|
||||
headError(item) {
|
||||
item.headimg = this.defaultImg.head;
|
||||
}
|
||||
}
|
||||
}
|
||||
686
addon/cashier/source/os/pages/order/orderlist.vue
Executable file
686
addon/cashier/source/os/pages/order/orderlist.vue
Executable file
@@ -0,0 +1,686 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
订单管理
|
||||
<view class="screen-btn" @click="showScreen = !showScreen">{{showScreen ? '关闭':'筛选'}}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="screen-content" v-if="showScreen">
|
||||
<scroll-view scroll-y="true" class="screen-box">
|
||||
<view class="screen-item">
|
||||
<view class="tit">创建时间</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="(!conditions.start_time_val && !conditions.end_time_val ) && conditions.time_type == '' ? 'active' : ''" @click="changeCondition('time_type','')">全部</view>
|
||||
<view class="value" :class="(!conditions.start_time_val && !conditions.end_time_val ) && conditions.time_type == '7' ? 'active' : ''" @click="changeCondition('time_type','7')">近7天</view>
|
||||
<view class="value" :class="(!conditions.start_time_val && !conditions.end_time_val ) && conditions.time_type == '30' ? 'active' : ''" @click="changeCondition('time_type','30')">近30天</view>
|
||||
<view class="time-range">
|
||||
<uni-datetime-picker class="time-value" :inputDisabled="false" v-model="conditions.start_time_val" type="datetime" placeholder="开始时间" />
|
||||
<view class="line">-</view>
|
||||
<uni-datetime-picker class="time-value" :inputDisabled="false" v-model="conditions.end_time_val" type="datetime" placeholder="结束时间" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="currOrderList == 'online'">
|
||||
<view class="screen-item">
|
||||
<view class="tit">订单类型</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="conditions.order_type == vItem.type ? 'active' : ''" v-for="(vItem,vIndex) in orderConditionList.order_type_list" :key="vIndex" @click="changeCondition('order_type',vItem.type)">{{vItem.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="screen-item">
|
||||
<view class="tit">订单状态</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="conditions.order_status == '' ? 'active' : ''" @click="changeCondition('order_status','')">全部</view>
|
||||
<view class="value" :class="conditions.order_status == vItem.type ? 'active' : ''" v-for="(vItem,vIndex) in orderConditionList.order_status_list" :key="vIndex" @click="changeCondition('order_status',vItem.type)">{{vItem.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="screen-item">
|
||||
<view class="tit">付款方式</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="conditions.pay_type == '' ? 'active' : ''" @click="changeCondition('pay_type','')">全部</view>
|
||||
<view class="value" :class="conditions.pay_type == vItem.type ? 'active' : ''" v-for="(vItem,vIndex) in orderConditionList.pay_type_list" :key="vIndex" @click="changeCondition('pay_type',vItem.type)">{{vItem.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="screen-item">
|
||||
<view class="tit">订单来源</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="conditions.order_from == '' ? 'active' : ''" @click="changeCondition('order_from','')">全部</view>
|
||||
<view class="value" :class="conditions.order_from == vItem.type ? 'active' : ''" v-for="(vItem,vIndex) in orderConditionList.order_from_list" :key="vIndex" @click="changeCondition('order_from',vItem.type)">{{vItem.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="screen-item">
|
||||
<view class="tit">订单类型</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="conditions.order_type == 'all' ? 'active' : ''" @click="changeCondition('order_type','all')">全部</view>
|
||||
<view class="value" :class="conditions.order_type == vItem.type ? 'active' : ''" v-for="(vItem,vIndex) in orderConditionList.cashier_order_type_list" :key="vIndex" @click="changeCondition('order_type',vItem.type)">{{vItem.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="screen-item">
|
||||
<view class="tit">订单状态</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="conditions.order_status == '' ? 'active' : ''" @click="changeCondition('order_status','')">全部</view>
|
||||
<view class="value" :class="conditions.order_status == vItem.type ? 'active' : ''" v-for="(vItem,vIndex) in orderConditionList.cashier_order_status_list" :key="vIndex" @click="changeCondition('order_status',vItem.type)">{{vItem.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="screen-item">
|
||||
<view class="tit">付款方式</view>
|
||||
<view class="values">
|
||||
<view class="value" :class="conditions.pay_type == '' ? 'active' : ''" @click="changeCondition('pay_type','')">全部</view>
|
||||
<view class="value" :class="conditions.pay_type == vItem.type ? 'active' : ''" v-for="(vItem,vIndex) in orderConditionList.cashier_pay_type_list" :key="vIndex" @click="changeCondition('pay_type',vItem.type)">{{vItem.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="search-btn">
|
||||
<view class="btn" @click="resetCondition()">重置</view>
|
||||
<view class="btn" @click="searchOrder()">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!showScreen" class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo" @click="search('')"></text>
|
||||
<input type="text" v-model="search_text" @keydown.enter="search('enter')" placeholder="输入订单号/商品名称/收货人姓名/手机号/留言/备注" />
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!showScreen" class="order-type-list">
|
||||
<view class="class-item" :class="{ active: currOrderList == 'cashier' }" @click="selectOrderList('cashier')">收银订单</view>
|
||||
<view class="class-item" :class="{ active: currOrderList == 'online' }" @click="selectOrderList('online')">商城订单</view>
|
||||
</view>
|
||||
<block v-if="!showScreen && !one_judge && order_list.length > 0">
|
||||
<scroll-view :scroll-top="scrollTop" @scroll="scroll" scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getOrderListFn">
|
||||
<view class="item" @click="getOrderDetailFn(item.order_id, index)" v-for="(item, index) in order_list" :key="index" :class="index == selectGoodsKeys ? 'itemhover' : ''">
|
||||
<view class="title">
|
||||
<view>订单编号:{{ item.order_no }}</view>
|
||||
<view v-if="item.order_type == 5">{{ item.cashier_order_type_name }}</view>
|
||||
<view v-else="item.order_type != 5">{{ item.order_type_name }}</view>
|
||||
</view>
|
||||
<view class="total-money-num">
|
||||
<view class="flex-shrink-0">{{ item.order_status_name }}</view>
|
||||
<view class="member-info">
|
||||
<view>买家:</view>
|
||||
<view class="member-info-name" :title="item.nickname" v-if="item.member_id">{{ item.nickname }}</view>
|
||||
<view class="member-info-name" v-else>散客</view>
|
||||
</view>
|
||||
|
||||
<view class="box">
|
||||
<view>实付金额</view>
|
||||
<view>¥{{ item.pay_money }}</view>
|
||||
</view>
|
||||
<view class="refund-state flex-shrink-0" v-if="parseFloat(item.refund_money) > 0">退款</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="!showScreen && !one_judge && order_list.length == 0">暂无数据</view>
|
||||
|
||||
</view>
|
||||
<view class="goodslist-right" v-show="type == 'detail'">
|
||||
<view class="goods-title">订单详情</view>
|
||||
<view class="order-information tab-wrap" v-show="!one_judge">
|
||||
<view class="tab-head">
|
||||
<text v-for="(item, index) in tabObj.list" :key="index" :class="{ active: tabObj.index == item.value }" @click="tabObj.index = item.value" v-if="(item.value == 3 && order_detail.order_log && order_detail.order_log.length > 0) || item.value != 3">
|
||||
{{ item.name }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="tab-content" v-if="JSON.stringify(order_detail) != '{}'">
|
||||
<view class="other-information" v-if="tabObj.index == 1">
|
||||
<view class="item-info">
|
||||
<view class="info-tit">收货信息</view>
|
||||
<view class="infos">
|
||||
<view class="info">收货人:{{order_detail.name}}</view>
|
||||
<view class="info">收货电话:{{order_detail.mobile}}</view>
|
||||
<view class="info">收货地址:{{order_detail.full_address}}{{ order_detail.address}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-info">
|
||||
<view class="info-tit">用户信息</view>
|
||||
<view class="infos">
|
||||
<view class="info" v-if="order_detail.member_id">
|
||||
用户昵称:{{ order_detail.nickname }}
|
||||
<text class="look" @click="viewMember()">查看会员</text>
|
||||
</view>
|
||||
<view class="info" v-else>用户昵称:散客</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-info">
|
||||
<view class="info-tit">订单信息</view>
|
||||
<view class="infos">
|
||||
<view class="info">订单类型:{{ order_detail.order_type_name }}</view>
|
||||
<view class="info">订单状态:{{ order_detail.order_status_name }}</view>
|
||||
<view class="info">{{ order_detail.order_type == 2 || order_detail.order_type == 3 ? ( order_detail.order_type == 2 ? '买家预计上门时间:' : '买家要求送达时间:' ) : ''}}{{ ( order_detail.order_type == 2 || order_detail.order_type == 3 ) ? order_detail.buyer_ask_delivery_time : '' }}</view>
|
||||
<view class="info">订单编号:{{order_detail.order_no}}</view>
|
||||
<view class="info">外部交易号:{{order_detail.out_trade_no}}</view>
|
||||
<view class="info">订单来源:{{order_detail.order_from_name}}</view>
|
||||
<view class="info">创建时间:{{$util.timeFormat(order_detail.create_time)}}</view>
|
||||
<view class="info">支付时间:{{$util.timeFormat(order_detail.pay_time)}}</view>
|
||||
<view class="info">支付方式:{{order_detail.pay_type_name}}</view>
|
||||
<view class="info">商品总价:¥{{order_detail.goods_money}}</view>
|
||||
<view class="info">店铺优惠:-¥{{order_detail.promotion_money}}</view>
|
||||
<view class="info">订单减免:-¥{{order_detail.reduction}}</view>
|
||||
<view class="info">优惠券:-¥{{order_detail.coupon_money}}</view>
|
||||
<view class="info">积分抵扣:-¥{{order_detail.point_money}}</view>
|
||||
<view class="info" v-show="order_detail.online_money > 0">线上支付:¥{{ order_detail.online_money | moneyFormat }}</view>
|
||||
<view class="info" v-show="order_detail.cash > 0">现金支付:¥{{ order_detail.cash | moneyFormat }}</view>
|
||||
<view class="info" v-show="order_detail.cash_change > 0">找零:-¥{{ order_detail.cash_change | moneyFormat }}</view>
|
||||
<view class="info" v-show="parseFloat(order_detail.balance_money) > 0">余额抵扣:¥{{ $util.moneyFormat(order_detail.balance_money) }}</view>
|
||||
<view class="info" v-show="order_detail.own_wechatpay > 0">个人微信收款:¥{{ order_detail.own_wechatpay | moneyFormat }}</view>
|
||||
<view class="info" v-show="order_detail.own_alipay > 0">个人支付宝收款:¥{{ order_detail.own_alipay | moneyFormat }}</view>
|
||||
<view class="info" v-show="order_detail.own_pos > 0">个人POS收款:¥{{ order_detail.own_pos | moneyFormat }}</view>
|
||||
<view class="info" >实付金额:¥{{ order_detail.pay_money }}</view>
|
||||
<view class="info" v-if="parseFloat(order_detail.refund_money) > 0">退款金额:¥{{ order_detail.refund_money }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-info">
|
||||
<view class="info-tit">订单备注</view>
|
||||
<view class="infos remark">
|
||||
<view class="info">买家留言:{{order_detail.buyer_message}}</view>
|
||||
<view class="info">商家备注:{{ order_detail.remark }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-info" v-if="tabObj.index == 2">
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:55%">商品(元)</view>
|
||||
<view class="table-td" style="width:15%">价格</view>
|
||||
<view class="table-td" style="width:10%">数量</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">小计(元)</view>
|
||||
</view>
|
||||
<view class="table-tr table-all" v-for="(item, index) in order_detail.order_goods" :key="index">
|
||||
<view class="table-td" style="width:55%">
|
||||
<image v-if="item.sku_image == '@/static/goods/goods.png'" src="@/static/goods/goods.png" mode="widthFix"/>
|
||||
<image v-else :src="$util.img(item.sku_image, { size: 'small' })" @error="item.sku_image = '@/static/goods/goods.png'" mode="widthFix"/>
|
||||
<view class="content-text">
|
||||
<view>
|
||||
<text v-if="item.is_gift" class="gift-tag">赠品</text>
|
||||
{{ item.goods_name }}
|
||||
</view>
|
||||
<view class="text-color-gray">
|
||||
{{ item.spec_name }}
|
||||
</view>
|
||||
<view v-if="item.refund_status != 0">
|
||||
<text class="refun-status">{{ item.refund_status_name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-td" style="width:15%">{{ item.price }}</view>
|
||||
<view class="table-td" style="width:10%">{{ item.num }}</view>
|
||||
<view class="table-td uni-column" style="width:15%;align-items: flex-end;">
|
||||
<view>{{ item.goods_money }}</view>
|
||||
<view class="refund-success" v-if="item.refund_status == 'refund_complete'">退款成功</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="other-information journal" v-if="order_detail.order_log && order_detail.order_log.length > 0 && tabObj.index == 3">
|
||||
<ns-order-log :list="order_detail.order_log"></ns-order-log>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="notYet" v-if="JSON.stringify(order_detail) == '{}'">暂无数据</view>
|
||||
<ns-loading ref="detailLoading"></ns-loading>
|
||||
</view>
|
||||
<view class="remarks-box" v-if="JSON.stringify(order_detail) != '{}'">
|
||||
|
||||
<button type="primary" class="default-btn comp-btn remarks" @click="printTicket">打印小票</button>
|
||||
<button type="primary" class="default-btn comp-btn remarks" @click="type = 'refund'" v-if="order_detail.is_enable_refund">退款</button>
|
||||
<button type="primary" class="default-btn comp-btn remarks" @click="open('remark')">备注</button>
|
||||
<!-- <button type="primary" class="default-btn comp-btn remarks">调整价格</button> -->
|
||||
<block v-if="order_detail.order_status_action.action">
|
||||
<block v-for="(item, index) in order_detail.order_status_action.action" :key="index">
|
||||
<button type="primary" class="primary-btn btn remarks" @click="open(item['action'])" v-if="item['action'] == 'orderLocalDelivery' || item['action'] == 'orderDelivery' || item['action'] == 'orderClose'||item['action'] == 'orderAdjustMoney'">{{ item.title }}</button>
|
||||
</block>
|
||||
</block>
|
||||
<button v-if="order_detail.order_type == 2 && order_detail.order_status == 2" type="primary" class="primary-btn btn remarks" @click="open('storeOrderTakeDelivery')">提货</button>
|
||||
<button v-for="(item, index) in order_detail.order_action" :key="index" type="primary" class="primary-btn btn remarks" @click="open(item['action'])">{{ item.title }}</button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 订单退款 -->
|
||||
<view class="goodslist-right refund-wrap" v-show="type == 'refund'">
|
||||
<view class="goods-title">退款</view>
|
||||
<view class="content common-scrollbar">
|
||||
<view v-show="refundStep == 0">
|
||||
<block v-for="(item, index) in order_detail.order_goods" :key="index">
|
||||
<view class="goods-item" v-if="item.refund_status == 0">
|
||||
<view class="iconfont" :class="refundGoods.indexOf(item.order_goods_id) == -1 ? 'iconyuan_checkbox' : 'iconyuan_checked'" @click="selectOrderGoods(item)"></view>
|
||||
<view class="image">
|
||||
<image v-if="item.sku_image == '@/static/goods/goods.png'" src="@/static/goods/goods.png" mode="widthFix"/>
|
||||
<image v-else :src="$util.img(item.sku_image, { size: 'small' })" @error="item.sku_image = '@/static/goods/goods.png'" mode="widthFix"/>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="content-text">{{ item.goods_name }}</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="price">¥{{ item.price }}</view>
|
||||
<view class="num">x {{ item.num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<block v-if="refundDetail">
|
||||
<view class="bg-grey" v-show="refundStep == 1">
|
||||
<block v-for="(refundItem, refundIndex) in refundDetail.refund_list" :key="refundIndex">
|
||||
<view class="refund-goods-item">
|
||||
<view class="row">
|
||||
<view class="title">退款商品</view>
|
||||
<view class="cont">
|
||||
<view class="goods-item">
|
||||
<view class="image">
|
||||
<image v-if="refundItem.order_goods_info.sku_image == '@/static/goods/goods.png'" src="@/static/goods/goods.png" mode="widthFix"/>
|
||||
<image v-else :src="$util.img(refundItem.order_goods_info.sku_image, { size: 'small' })" @error="refundItem.order_goods_info.sku_image = '@/static/goods/goods.png'" mode="widthFix"/>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="content-text">{{ refundItem.order_goods_info.sku_name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row">
|
||||
<view class="title">退款金额</view>
|
||||
<view class="cont">
|
||||
<view class="money-box">
|
||||
<input type="number" v-model="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].refund_money" />
|
||||
元
|
||||
</view>
|
||||
<view class="refund-money">
|
||||
可退金额:
|
||||
<text>¥{{ refundItem.order_goods_info.refund_apply_money | moneyFormat }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row" style="margin-top:8px;">
|
||||
<view class="title">是否返还库存</view>
|
||||
<view class="cont">
|
||||
<radio-group @change="changeIsRefundStock(refundItem,$event)" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].is_refund_stock == 1" />
|
||||
是
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].is_refund_stock == 0" />
|
||||
否
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row" v-if="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].is_refund_stock == 1" style="margin-top:8px;">
|
||||
<view class="title">退还数量</view>
|
||||
<view class="cont">
|
||||
<view class="money-box">
|
||||
<input type="number" :max="Number(refundItem.order_goods_info.num)" v-model="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].refund_stock_num" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row" style="margin-top:8px;">
|
||||
<view class="title">完成状态</view>
|
||||
<view class="cont">
|
||||
<radio-group @change="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].refund_status = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="PARTIAL_REFUND" :checked="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].refund_status == 'PARTIAL_REFUND'" />
|
||||
部分退款状态
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="REFUND_COMPLETE" :checked="refundApply.refund_array[refundItem.order_goods_info.order_goods_id].refund_status == 'REFUND_COMPLETE'" />
|
||||
退款完成状态
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row">
|
||||
<view class="title"></view>
|
||||
<view class="cont tips">
|
||||
<view>1、如果是退部分金额,退款后可以是部分退款状态或退款完成状态</view>
|
||||
<view>2、如果是退全部金额,则退款后一定是退款完成状态</view>
|
||||
<view>3、退款完成才会执行相关业务如核销码失效,卡包失效等操作</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<view class="refund-goods-item">
|
||||
<view class="row">
|
||||
<view class="title">退款说明</view>
|
||||
<view class="cont">
|
||||
<textarea placeholder="请输入退款说明" v-model="refundApply.refund_remark" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-show="refundStep == 2">
|
||||
<view class="refund-type" :class="{ active: refundApply.refund_transfer_type == index }" @click="refundApply.refund_transfer_type = index" v-for="(item, index) in refundDetail.refund_transfer_type" :key="index">
|
||||
<view class="title">{{ item.name }}</view>
|
||||
<view class="desc">{{ item.desc }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="remarks-box">
|
||||
<button type="primary" class="default-btn comp-btn remarks" @click="type = 'detail'">取消</button>
|
||||
<button type="primary" class="primary-btn comp-btn remarks" v-show="refundStep > 0" @click="refundStep -= 1">上一步</button>
|
||||
<button type="primary" class="primary-btn comp-btn remarks" @click="refundNext">{{ refundStep == 2 ? '确认退款' : '下一步' }}</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 留言 -->
|
||||
<unipopup ref="remark" type="center">
|
||||
<view class="message">
|
||||
<view class="title">
|
||||
备注
|
||||
<text class="iconfont iconguanbi1" @click="$refs.remark.close()"></text>
|
||||
</view>
|
||||
<view class="textarea-box">
|
||||
<textarea v-model="order_detail.remark" class="textarea" maxlength="200" placeholder="输入请不多于200字"/>
|
||||
</view>
|
||||
<button @click="saveRemark" type="primary" class="primary-btn btn save">保存</button>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 订单关闭 -->
|
||||
<unipopup ref="orderClose" type="center">
|
||||
<view class="order-close">
|
||||
<view class="title">是否要关闭订单?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="orderOperation('close')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderOperation('save')">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
<!-- 门店提货 -->
|
||||
<unipopup ref="storeOrderTakeDelivery" type="center">
|
||||
<view class="order-close">
|
||||
<view class="title">确定要直接提货吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.storeOrderTakeDelivery.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="storeOrderTakeDelivery()">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<unipopup ref="orderLocalDelivery" type="center">
|
||||
<view class="order-delivery local">
|
||||
<view class="title">订单发货</view>
|
||||
<view class="content">
|
||||
<view class="content-item">
|
||||
<view class="title">收货地址:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.name }}</text>
|
||||
<text>{{ order_detail.mobile }}</text>
|
||||
<text>{{ order_detail.full_address }}{{ order_detail.address }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">配送员:</view>
|
||||
<view class="info">
|
||||
<view class="select">
|
||||
<select-lay :zindex="10" :value="localDelivery.deliverer" name="names" placeholder="请选择配送员" :options="deliverer" @selectitem="selectDeliverer"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">配送员手机号:</view>
|
||||
<view class="info">
|
||||
<input type="text" class="input" v-model="localDelivery.deliverer_mobile" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.orderLocalDelivery.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderLocalDeliveryFn()">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<unipopup ref="orderDelivery" type="center">
|
||||
<view class="order-delivery express">
|
||||
<view class="title">订单发货</view>
|
||||
<view class="content">
|
||||
<view class="content-item">
|
||||
<view class="title">收货地址:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.name }}</text>
|
||||
<text>{{ order_detail.mobile }}</text>
|
||||
<text>{{ order_detail.full_address }}{{ order_detail.address }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">发货方式:</view>
|
||||
<view class="info">
|
||||
<radio-group @change="expresDelivery.delivery_type = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="expresDelivery.delivery_type == 1" />物流发货
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="expresDelivery.delivery_type == 0" />无需物流
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view v-show="expresDelivery.delivery_type == 1">
|
||||
<view class="content-item">
|
||||
<view class="title">物流公司:</view>
|
||||
<view class="info">
|
||||
<view class="select">
|
||||
<select-lay :zindex="10" :value="expresDelivery.express_company_id" name="names" placeholder="请选择物流公司" :options="expressCompany" @selectitem="selectExpressCompany"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">快递单号:</view>
|
||||
<view class="info">
|
||||
<input type="text" class="input" v-model="expresDelivery.delivery_no" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="info goods-info common-scrollbar">
|
||||
<view class="table">
|
||||
<checkbox-group @change="expresDelivery.order_goods_ids = $event.detail.value">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:5%"></view>
|
||||
<view class="table-td" style="width:45%">商品(元)</view>
|
||||
<view class="table-td" style="width:10%">数量</view>
|
||||
<view class="table-td" style="width:20%;justify-content: flex-end;">物流单号</view>
|
||||
<view class="table-td" style="width:20%;justify-content: flex-end;">物流状态</view>
|
||||
</view>
|
||||
<view class="table-tr table-all" v-for="(item, index) in order_detail.order_goods" :key="index">
|
||||
<view class="table-td" style="width:5%">
|
||||
<checkbox :value="String(item.order_goods_id)" :disabled="item.delivery_status != 0" />
|
||||
</view>
|
||||
<view class="table-td" style="width:45%">
|
||||
<image v-if="item.sku_image == '@/static/goods/goods.png'" src="@/static/goods/goods.png" mode="widthFix"/>
|
||||
<image v-else :src="$util.img(item.sku_image, { size: 'small' })" @error="item.sku_image = '@/static/goods/goods.png'" mode="widthFix"/>
|
||||
<view class="content-text">
|
||||
<view>{{ item.goods_name }} {{ item.spec_name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-td" style="width:10%">{{ item.num }}</view>
|
||||
<view class="table-td uni-column" style="width:20%;align-items: flex-end;">{{ item.delivery_no }}</view>
|
||||
<view class="table-td uni-column" style="width:20%;align-items: flex-end;">{{ item.delivery_status_name }}</view>
|
||||
</view>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.orderDelivery.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderDelivery()">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
<!-- 调整价格 -->
|
||||
<unipopup ref="orderAdjustMoney" type="center">
|
||||
<view class="order-adjust-money">
|
||||
<view class="title">
|
||||
<text>调整价格</text>
|
||||
<text class="iconfont iconguanbi1" @click="clear"></text>
|
||||
</view>
|
||||
<view class="tip">注意 : 只有订单未付款时才支持改价,改价后请联系买家刷新订单核实订单金额后再支付。</view>
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:10%;padding: 0 0.07rem;">商品信息</view>
|
||||
<view class="table-td" style="width:5%;padding: 0 0.07rem;">单价</view>
|
||||
<view class="table-td" style="width:5%;padding: 0 0.07rem;">数量</view>
|
||||
<view class="table-td" style="width:5%;padding: 0 0.07rem;">小计</view>
|
||||
<view class="table-td" style="width:9%;padding: 0 0.07rem;">商品总额</view>
|
||||
<view class="table-td" style="width:5%;padding: 0 0.07rem;">优惠</view>
|
||||
<view class="table-td" style="width:8%;padding: 0 0.07rem;">优惠券</view>
|
||||
<view class="table-td" style="width:8%;padding: 0 0.07rem;">积分抵现</view>
|
||||
<view class="table-td" style="width:9%;padding: 0 0.07rem;">发票费用</view>
|
||||
<view class="table-td" style="width:10%;padding: 0 0.07rem;">发票邮寄费用</view>
|
||||
<view class="table-td" style="width:10%;padding: 0 0.07rem;">调整金额</view>
|
||||
<view class="table-td" style="width:10%;padding: 0 0.07rem;">运费</view>
|
||||
<view class="table-td" style="width:6%;padding: 0 0.07rem;">总计</view>
|
||||
</view>
|
||||
<view class="table-tr table-all">
|
||||
<view class="table-td" style="width:25%">
|
||||
<view class="table-tr table-all" v-for="(item, index) in order_detail.order_goods" :key="index">
|
||||
<view class="table-td" style="width:40%;padding: 0 0.07rem;">{{ item.sku_name }} </view>
|
||||
<view class="table-td" style="width:20%;padding: 0 0.07rem;">{{ item.price }} </view>
|
||||
<view class="table-td" style="width:20%;padding: 0 0.07rem;">{{ item.num }} </view>
|
||||
<view class="table-td" style="width:20%;padding: 0 0.07rem;">{{ item.goods_money }} </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-td left" style="width:9%;padding: 0 0.07rem;">{{order_detail.goods_money}}</view>
|
||||
<view class="table-td" style="width:5%;padding: 0 0.07rem;">{{ order_detail.promotion_money }}</view>
|
||||
<view class="table-td" style="width:8%;padding: 0 0.07rem;">{{ order_detail.coupon_money }}</view>
|
||||
<view class="table-td" style="width:8%;padding: 0 0.07rem;">{{ order_detail.point_money }}</view>
|
||||
<view class="table-td" style="width:9%;padding: 0 0.07rem;">{{order_detail.invoice_money}}</view>
|
||||
<view class="table-td" style="width:10%;padding: 0 0.07rem;">{{order_detail.invoice_delivery_money}}</view>
|
||||
<view class="table-td" style="width:10%;padding: 0 0.07rem;"><input type="number" v-model="adjustParams.adjust_money" /></view>
|
||||
<view class="table-td" style="width:10%;padding: 0 0.07rem;"><input type="number" min="0" v-model="adjustParams.delivery_money" /></view>
|
||||
<view class="table-td" style="width:6%;padding: 0 0.07rem;">{{parseFloat(parseFloat(order_detail.goods_money)-parseFloat(order_detail.promotion_money||0)-parseFloat(order_detail.coupon_money||0) -parseFloat(order_detail.point_money||0)+ parseFloat(adjustParams.adjust_money||0) + parseFloat(adjustParams.delivery_money||0)).toFixed(2)}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tip m-0"><text class="Highlight">{{'实际商品金额 '}}</text>= 商品总额 - 优惠金额 - 优惠券金额 - 积分抵现 + 调价</view>
|
||||
<view class="tip m-0"><text class="Highlight">{{'发票费用 '}}</text>= 实际商品金额 * 发票比率</view>
|
||||
<view class="tip m-0">订单总额 =<text class="Highlight">{{' 实际商品金额 '}}</text>+ <text class="Highlight">{{'发票费用 '}}</text>+ 运费 + 发票邮寄费用</view>
|
||||
<view class="footer">
|
||||
<button type="primary" class="primary-btn btn remarks" @click="adjustSave">确定</button>
|
||||
<button class="default-btn comp-btn remarks clear" @click="clear">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import nsOrderLog from '@/components/ns-order-log/ns-order-log.vue';
|
||||
import nsLoading from '@/components/ns-loading/ns-loading.vue';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
import orderList from './public/js/order_list.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
nsOrderLog,
|
||||
nsLoading,
|
||||
unipopup,
|
||||
},
|
||||
mixins: [orderList]
|
||||
};
|
||||
/**
|
||||
* 打印回调
|
||||
* @param {Object} text
|
||||
*/
|
||||
window.POS_PRINT_CALLBACK = function(text) {
|
||||
uni.showToast({
|
||||
title: text,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/orderlist.scss';
|
||||
|
||||
.tab-wrap {
|
||||
padding: 0 !important;
|
||||
background-color: #fff !important;
|
||||
|
||||
.tab-head {
|
||||
display: flex;
|
||||
background-color: #f8f8f8;
|
||||
|
||||
text {
|
||||
width: 1.15rem;
|
||||
height: 0.55rem;
|
||||
line-height: 0.55rem;
|
||||
text-align: center;
|
||||
font-size: $uni-font-size-lg;
|
||||
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-box {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.form-radio-item {
|
||||
margin-right: .1rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message {
|
||||
width: 5.2rem;
|
||||
min-height: 3.2rem;
|
||||
border-radius: 0.06rem;
|
||||
background: #ffffff;
|
||||
padding-bottom: 0.15rem;
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
text-align: center;
|
||||
line-height: 0.5rem;
|
||||
font-size: 0.16rem;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
.iconguanbi1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 0.15rem;
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
.textarea-box {
|
||||
margin: 0.15rem;
|
||||
height: 2.2rem;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 0.06rem;
|
||||
padding: 0.15rem;
|
||||
box-sizing: border-box;
|
||||
.textarea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.save {
|
||||
width: auto !important;
|
||||
float: right;
|
||||
margin-right: 0.15rem;
|
||||
}
|
||||
}
|
||||
.message:after {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
content: '';
|
||||
height: 0;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
413
addon/cashier/source/os/pages/order/orderrefund.vue
Executable file
413
addon/cashier/source/os/pages/order/orderrefund.vue
Executable file
@@ -0,0 +1,413 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
退款维权
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input type="text" v-model="search_text" @input="search" placeholder="搜索订单号/商品名称" />
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="!one_judge && order_list.length > 0">
|
||||
<scroll-view :scroll-top="scrollTop" @scroll="scroll" scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getOrderList">
|
||||
<view class="item" @click="getOrderDetail(item.order_goods_id, index)" v-for="(item, index) in order_list" :key="index" :class="index == selectGoodsKeys ? 'itemhover' : ''">
|
||||
<view class="title">
|
||||
<view>退款编号:{{ item.order_no }}</view>
|
||||
<view>{{ item.order_type_name }}</view>
|
||||
</view>
|
||||
<view class="total-money-num">
|
||||
<view class="box">
|
||||
<view>订单金额</view>
|
||||
<view>¥{{ item.real_goods_money }}</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>退款金额</view>
|
||||
<view>¥{{ item.refund_apply_money }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="total-money-num">
|
||||
<view class="member-info">
|
||||
<view>退款状态:</view>
|
||||
<view>{{ item.refund_status_name }}({{ item.refund_type == 1 ? '仅退款' : '退款退货' }})</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="!one_judge && order_list.length == 0">暂无数据</view>
|
||||
</view>
|
||||
<view class="goodslist-right">
|
||||
<view class="goods-title">订单详情</view>
|
||||
<view class="order-information tab-wrap" v-if="Object.keys(order_detail).length">
|
||||
<view class="tab-head">
|
||||
<text v-for="(item, index) in tabObj.list" :key="index" :class="{ active: tabObj.index == item.value }" @click="tabObj.index = item.value">{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="tab-content">
|
||||
<view class="other-information" v-if="tabObj.index == 1">
|
||||
<view class="item-box">
|
||||
<view class="item">
|
||||
<view>买家:</view>
|
||||
<view v-if="order_detail.nickname">{{ order_detail.nickname }}</view>
|
||||
<view v-else>散客</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>退款编号:</view>
|
||||
<view>{{ order_detail.refund_no }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>申请时间:</view>
|
||||
<view>{{ $util.timeFormat(order_detail.refund_action_time) }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>维权类型:</view>
|
||||
<view>{{ order_detail.refund_mode > 1 ? '售后' : '退款' }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>退款方式:</view>
|
||||
<view>
|
||||
{{ order_detail.shop_active_refund == 1 ? '主动退款' : order_detail.refund_type == 1 ? '仅退款' : '退货退款' }}
|
||||
({{ (order_detail.refund_type == 1 && '原路退款') || (order_detail.refund_type == 2 && '线下退款') || '退款到余额' }})
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>退款金额:</view>
|
||||
<view>¥{{ order_detail.refund_status == 3 ? order_detail.refund_real_money : order_detail.refund_apply_money }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>退款原因:</view>
|
||||
<view>{{ order_detail.refund_reason || '--' }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>退款说明:</view>
|
||||
<view>{{ order_detail.refund_remark || '--' }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>商家退款说明:</view>
|
||||
<view>{{ order_detail.shop_refund_remark || '--' }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>退款状态:</view>
|
||||
<view>{{ order_detail.refund_status_name }}</view>
|
||||
</view>
|
||||
<view class="item" v-if="order_detail.refund_refuse_reason">
|
||||
<view>拒绝理由:</view>
|
||||
<view>{{ order_detail.refund_refuse_reason }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-info" v-if="tabObj.index == 2">
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:45%">商品(元)</view>
|
||||
<view class="table-td" style="width:15%">价格</view>
|
||||
<view class="table-td" style="width:10%">数量</view>
|
||||
<view class="table-td" style="width:15%;">小计(元)</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">状态</view>
|
||||
</view>
|
||||
<view class="table-tr table-all">
|
||||
<view class="table-td" style="width:45%">{{ order_detail.sku_name }}</view>
|
||||
<view class="table-td" style="width:15%">{{ order_detail.price }}</view>
|
||||
<view class="table-td" style="width:10%">{{ order_detail.num }}</view>
|
||||
<view class="table-td" style="width:15%">{{ order_detail.goods_money }}</view>
|
||||
<view class="table-td uni-column" style="width:15%;align-items: flex-end;">{{ order_detail.refund_status_name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="other-information journal" v-if="tabObj.index == 3">
|
||||
<ns-order-log :list="order_detail.refund_log_list"></ns-order-log>
|
||||
</view>
|
||||
<view class="remarks-box" v-if="order_detail.refund_action.length">
|
||||
<block v-for="(item, index) in order_detail.refund_action" :key="index">
|
||||
<button type="primary" class="primary-btn btn remarks" @click="open(item['event'])">{{ item.title }}</button>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<block v-else-if="!one_judge && !Object.keys(order_detail).length" >
|
||||
<image class="cart-empty" src="@/static/cashier/cart_empty.png" mode="widthFix" />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 同意退款 -->
|
||||
<unipopup ref="orderRefundAgree" type="center">
|
||||
<view class="order-refund-agree">
|
||||
<view class="title">售后维权处理</view>
|
||||
<view class="content">
|
||||
<view class="content-item">
|
||||
<view class="title">注意:</view>
|
||||
<view class="info">
|
||||
<text v-if="order_detail.pay_type == 'OFFLINE_PAY'">该笔订单通过线下支付,商家同意后,退款将通过线下原路退回。</text>
|
||||
<text v-else>该笔订单通过在线付款,商家同意后,退款将自动原路退回买家付款账户。</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退款方式:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.refund_type == 1 ? '仅退款' : '退货退款' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退款金额:</view>
|
||||
<view class="info">
|
||||
<text>¥{{ order_detail.refund_apply_money }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.orderRefundAgree.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderRefundAgree()">确认退款</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 拒绝退款 -->
|
||||
<unipopup ref="orderRefundRefuse" type="center">
|
||||
<view class="order-refund-agree">
|
||||
<view class="title">售后维权处理</view>
|
||||
<view class="content">
|
||||
<view class="tips">注意:建议你与买家协商后,再确定是否拒绝退款。如你拒绝退款后,买家可修改退款申请协议重新发起退款。</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退款方式:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.refund_type == 1 ? '仅退款' : '退货退款' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退款金额:</view>
|
||||
<view class="info">
|
||||
<text>¥{{ order_detail.refund_apply_money }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item textarea-wrap">
|
||||
<view class="title">拒绝理由:</view>
|
||||
<view class="info textarea-box">
|
||||
<textarea v-model="refundRefuseReason" class="textarea" maxlength="200" placeholder="请输入拒绝理由,最多不超过200字"></textarea>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.orderRefundRefuse.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderRefundRefuse()">确认退款</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 关闭维权 -->
|
||||
<unipopup ref="orderRefundClose" type="center">
|
||||
<view class="order-close">
|
||||
<view class="title">确定要关闭本次维权吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.orderRefundClose.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderRefundClose()">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 转账 -->
|
||||
<unipopup ref="orderRefundTransfer" type="center">
|
||||
<view class="order-refund-agree">
|
||||
<view class="title">售后维权处理</view>
|
||||
<view class="content">
|
||||
<view class="content-item">
|
||||
<view class="title">申请退款金额:</view>
|
||||
<view class="info">
|
||||
<text>¥{{ order_detail.refund_apply_money }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">实际退款金额:</view>
|
||||
<view class="info">
|
||||
<view class="money-box">
|
||||
<input type="number" v-model="refundTransfer.refund_real_money" />
|
||||
元
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item" v-if="order_detail.use_point>0">
|
||||
<view class="title">退还积分:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.use_point }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item" v-if="order_detail.coupon_info && order_detail.coupon_info.length>0">
|
||||
<view class="title">退还优惠券:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.coupon_info.coupon_name }}</text>
|
||||
<text v-if="order_detail.coupon_info.money>0">({{order_detail.coupon_info.money}})</text>
|
||||
<text v-else>({{order_detail.coupon_info.discount}}折)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退款方式:</view>
|
||||
<view class="info">
|
||||
<radio-group @change="refundTransfer.refund_money_type = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="refundTransfer.refund_money_type == 1" />
|
||||
原路退款
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="2" :checked="refundTransfer.refund_money_type == 2" />
|
||||
线下退款
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="3" :checked="refundTransfer.refund_money_type == 3" />
|
||||
退款到余额
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="content-item textarea-wrap">
|
||||
<view class="title">退款说明:</view>
|
||||
<view class="info textarea-box">
|
||||
<textarea v-model="refundTransfer.shop_refund_remark" class="textarea" maxlength="200" placeholder="请输入拒绝理由,最多不超过200字"></textarea>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.orderRefundTransfer.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderRefundTransfer()">确认退款</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 买家退货接收,维权收货 -->
|
||||
<unipopup ref="orderRefundTakeDelivery" type="center">
|
||||
<view class="order-refund-agree">
|
||||
<view class="title">售后维权处理</view>
|
||||
<view class="content">
|
||||
<view class="tips">注意:需你同意退款申请,买家才能退货给你;买家退货后你需再次确认收货后,退款将自动原路退回至买家付款账户。</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退款方式:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.refund_type == 1 ? '仅退款' : '退货退款' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退款金额:</view>
|
||||
<view class="info">
|
||||
<text>¥{{ order_detail.refund_apply_money }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item">
|
||||
<view class="title">退货地址:</view>
|
||||
<view class="info">
|
||||
<text>{{ order_detail.refund_address }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-item textarea-wrap">
|
||||
<view class="title">是否入库:</view>
|
||||
<view class="info">
|
||||
<radio-group @change="isRefundStock = $event.detail.value" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="isRefundStock == 0" />
|
||||
否
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="isRefundStock == 1" />
|
||||
是
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.orderRefundTakeDelivery.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="orderRefundTakeDelivery()">确认收到退货</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import orderRefund from './public/js/order_refund'
|
||||
import nsOrderLog from '@/components/ns-order-log/ns-order-log.vue';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
nsOrderLog,
|
||||
unipopup
|
||||
},
|
||||
mixins: [orderRefund]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/orderlist.scss';
|
||||
|
||||
.total-money-num .box {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.goodslist {
|
||||
.goodslist-right {
|
||||
.other-information {
|
||||
.title {
|
||||
margin-bottom: 0.1rem !important;
|
||||
}
|
||||
|
||||
.item-box {
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
.item {
|
||||
|
||||
&:nth-child(1),
|
||||
&:nth-child(2) {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
view:nth-child(1) {
|
||||
width: 1rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-wrap {
|
||||
padding: 0 !important;
|
||||
background-color: #fff !important;
|
||||
|
||||
.tab-head {
|
||||
display: flex;
|
||||
background-color: #f8f8f8;
|
||||
|
||||
text {
|
||||
width: 1.15rem;
|
||||
height: 0.55rem;
|
||||
line-height: 0.55rem;
|
||||
text-align: center;
|
||||
font-size: $uni-font-size-lg;
|
||||
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-box {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
/deep/ .goods-list-scroll {
|
||||
width: 100%;
|
||||
height: calc(100% - 1.44rem) !important;
|
||||
}
|
||||
</style>
|
||||
1281
addon/cashier/source/os/pages/order/public/css/orderlist.scss
Executable file
1281
addon/cashier/source/os/pages/order/public/css/orderlist.scss
Executable file
File diff suppressed because it is too large
Load Diff
888
addon/cashier/source/os/pages/order/public/js/order_list.js
Executable file
888
addon/cashier/source/os/pages/order/public/js/order_list.js
Executable file
@@ -0,0 +1,888 @@
|
||||
import {
|
||||
getOrderList,
|
||||
getOrderDetail,
|
||||
orderRemark,
|
||||
orderClose,
|
||||
orderStoreDelivery,
|
||||
orderLocalDelivery,
|
||||
orderPrintTicket,
|
||||
getExpressCompanyList,
|
||||
orderExpressDelivery,
|
||||
getOrderDeliverList,
|
||||
orderAdjustPrice,
|
||||
getorderCondition
|
||||
} from '@/api/order.js'
|
||||
import {getRefundApplyData, orderRefund} from '@/api/order_refund.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectGoodsKeys: 0,
|
||||
otherInfoValue: {
|
||||
order_no: {
|
||||
title: '订单编号:',
|
||||
value: ''
|
||||
},
|
||||
out_trade_no: {
|
||||
title: '订单交易号:',
|
||||
value: ''
|
||||
},
|
||||
create_time: {
|
||||
title: '消费时间:',
|
||||
value: ''
|
||||
},
|
||||
pay_status: {
|
||||
title: '支付状态:',
|
||||
value: ''
|
||||
},
|
||||
order_status: {
|
||||
title: '订单状态:',
|
||||
value: ''
|
||||
},
|
||||
pay_type: {
|
||||
title: '付款方式:',
|
||||
value: ''
|
||||
},
|
||||
operator_name: {
|
||||
title: '收银员:',
|
||||
value: ''
|
||||
},
|
||||
pay_time: {
|
||||
title: '付款时间:',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
// 订购日志所需列表数据
|
||||
list: [],
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 8,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
conditions: {
|
||||
order_status: '',
|
||||
time_type: '',
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
start_time_val: '',
|
||||
end_time_val: '',
|
||||
order_type: 'all',
|
||||
order_from: '',
|
||||
pay_type: '',
|
||||
},
|
||||
//订单列表类型
|
||||
currOrderList: 'cashier',
|
||||
//订单类型
|
||||
trade_type: '',
|
||||
//初始时加载详情数据判断
|
||||
one_judge: true,
|
||||
//无限滚动请求锁
|
||||
listLock: false,
|
||||
scrollTop: 0,
|
||||
// 订单列表数据
|
||||
order_list: [],
|
||||
//订单详情数据
|
||||
order_detail: {},
|
||||
type: 'detail',
|
||||
refundStep: 0,
|
||||
refundGoods: [],
|
||||
refundDetail: null,
|
||||
refundRepeat: false,
|
||||
refundApply: {
|
||||
refund_remark: '',
|
||||
refund_transfer_type: ''
|
||||
},
|
||||
localDelivery: {
|
||||
deliverer_mobile: '',
|
||||
deliverer: ''
|
||||
},
|
||||
expresDelivery: {
|
||||
delivery_type: 1,
|
||||
express_company_id: 0,
|
||||
delivery_no: '',
|
||||
order_goods_ids: []
|
||||
},
|
||||
expressCompany: [],
|
||||
deliverer: [],
|
||||
tabObj: {
|
||||
list: [{
|
||||
value: 1,
|
||||
name: '基础信息'
|
||||
}, {
|
||||
value: 2,
|
||||
name: '商品信息'
|
||||
}, {
|
||||
value: 3,
|
||||
name: '订单日志'
|
||||
}],
|
||||
index: 1
|
||||
},
|
||||
isLogisticsRepeat: false,
|
||||
//调价
|
||||
adjustParams:{
|
||||
order_id:null,
|
||||
adjust_money:0,
|
||||
delivery_money:0
|
||||
},
|
||||
currGlobalStoreId:'',
|
||||
showScreen: false,
|
||||
orderConditionList: [],
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.search_text = option.order_no || '';
|
||||
this.currOrderList = option.order_from == 'online' ? 'online' : 'cashier';
|
||||
if(uni.getStorageSync('globalStoreId')) this.currGlobalStoreId = uni.getStorageSync('globalStoreId');
|
||||
// 获取订单列表数据
|
||||
this.getOrderListFn();
|
||||
this.getExpressCompany();
|
||||
this.getDeliver();
|
||||
this.getOrderCondition()
|
||||
},
|
||||
watch: {
|
||||
type: function (nval, oval) {
|
||||
if (oval == 'refund') {
|
||||
this.refundStep = 0;
|
||||
this.refundGoods = [];
|
||||
this.refundDetail = null;
|
||||
this.refundRepeat = false;
|
||||
this.refundApply = {
|
||||
refund_remark: '',
|
||||
refund_transfer_type: ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeIsRefundStock(refundItem,e) {
|
||||
this.refundApply.refund_array[refundItem.order_goods_info.order_goods_id].is_refund_stock = e.detail.value;
|
||||
this.$forceUpdate()
|
||||
},
|
||||
searchOrder() {
|
||||
if(this.conditions.start_time_val || this.conditions.end_time_val){
|
||||
if(new Date(this.conditions.end_time_val).getTime() <= new Date(this.conditions.start_time_val).getTime()){
|
||||
this.$util.showToast({title:'结束时间不能早于开始时间'})
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.page = 1;
|
||||
this.order_list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = false;
|
||||
this.showScreen = false;
|
||||
this.getOrderListFn();
|
||||
},
|
||||
initCondition() {
|
||||
this.conditions.order_status = '';
|
||||
this.conditions.time_type = '';
|
||||
this.conditions.start_time = '';
|
||||
this.conditions.end_time = '';
|
||||
this.conditions.start_time_val = '';
|
||||
this.conditions.end_time_val = '';
|
||||
this.conditions.order_type = 'all';
|
||||
this.conditions.order_from = '';
|
||||
this.conditions.pay_type = '';
|
||||
},
|
||||
resetCondition() {
|
||||
this.page = 1;
|
||||
this.order_list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = false;
|
||||
this.initCondition();
|
||||
this.showScreen = false;
|
||||
this.getOrderListFn();
|
||||
},
|
||||
changeCondition(mode,type) {
|
||||
this.conditions[mode] = type;
|
||||
if(mode == 'order_type'){
|
||||
if(this.currOrderList == 'online'){
|
||||
this.orderConditionList.order_type_list.forEach((item,index) => {
|
||||
if(item.type == type) this.orderConditionList.order_status_list = item.status;
|
||||
})
|
||||
this.conditions.order_status = '';
|
||||
}
|
||||
}
|
||||
if(mode == 'time_type'){
|
||||
this.conditions.start_time_val = '';
|
||||
this.conditions.end_time_val = '';
|
||||
switch (type){
|
||||
case '':
|
||||
this.conditions.start_time = '';
|
||||
this.conditions.end_time = '';
|
||||
break;
|
||||
case '7':
|
||||
this.conditions.start_time = this.getDay(type);
|
||||
this.conditions.end_time = this.getNowDate();
|
||||
break;
|
||||
case '30':
|
||||
this.conditions.start_time = this.getDay(type);
|
||||
this.conditions.end_time = this.getNowDate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
getDay(p_count) {
|
||||
var dd = new Date();
|
||||
dd.setDate(dd.getDate() - p_count); //获取p_count天后的日期
|
||||
var y = dd.getFullYear();
|
||||
var m = dd.getMonth() + 1; //获取当前月份的日期
|
||||
if (m < 10) {
|
||||
m = '0' + m;
|
||||
}
|
||||
var d = dd.getDate();
|
||||
if (d < 10) {
|
||||
d = '0' + d;
|
||||
}
|
||||
return y + '-' + m + '-' + d +' 00:00:00';
|
||||
},
|
||||
getNowDate() {
|
||||
var date = new Date();
|
||||
var y = date.getFullYear();
|
||||
var m = date.getMonth() + 1; //获取当前月份的日期
|
||||
if (m < 10) {
|
||||
m = '0' + m;
|
||||
}
|
||||
var d = date.getDate();
|
||||
if (d < 10) {
|
||||
d = '0' + d;
|
||||
}
|
||||
return y + '-' + m + '-' + d +' 23:59:59';
|
||||
},
|
||||
getOrderCondition() {
|
||||
getorderCondition()
|
||||
.then((res)=>{
|
||||
if(res.code>=0){
|
||||
var data = res.data;
|
||||
for (var index in data) {
|
||||
var arr = [];
|
||||
if (index != 'order_label_list' && index != 'order_status_list' && index != 'pay_type_list' && index != 'cashier_pay_type_list' && index != 'cashier_order_type_list') {
|
||||
for (var index_c in data[index]) {
|
||||
var obj = {
|
||||
type: index_c
|
||||
};
|
||||
obj = Object.assign(obj, data[index][index_c]);
|
||||
arr.push(obj);
|
||||
}
|
||||
} else {
|
||||
for (var index_c in data[index]) {
|
||||
var obj = {
|
||||
type: index_c,
|
||||
name: data[index][index_c]
|
||||
};
|
||||
arr.push(obj);
|
||||
}
|
||||
}
|
||||
data[index] = arr;
|
||||
}
|
||||
this.orderConditionList = data;
|
||||
this.orderConditionList.order_type_list.forEach((item,index)=>{
|
||||
var arr = [];
|
||||
for (var index_c in item.status) {
|
||||
var obj = {
|
||||
type: index_c,
|
||||
name: item.status[index_c]
|
||||
};
|
||||
arr.push(obj);
|
||||
}
|
||||
item.status = arr;
|
||||
if(item.type == 'all'){
|
||||
this.orderConditionList.order_status_list = item.status;
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
switchStoreAfter() {
|
||||
if(this.currGlobalStoreId == uni.getStorageSync('globalStoreId')) return;
|
||||
this.currGlobalStoreId = uni.getStorageSync('globalStoreId');
|
||||
this.page = 1;
|
||||
this.order_list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = false;
|
||||
this.getOrderListFn();
|
||||
this.getDeliver()
|
||||
},
|
||||
// 搜索
|
||||
search(type) {
|
||||
this.page = 1;
|
||||
this.order_list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = false;
|
||||
if (type == 'enter') {
|
||||
document.onkeydown = e => {
|
||||
if (e.keyCode === 13) {
|
||||
//回车后执行搜索方法
|
||||
this.getOrderListFn();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.getOrderListFn();
|
||||
}
|
||||
|
||||
},
|
||||
selectOrderList(order_type) {
|
||||
this.currOrderList = order_type;
|
||||
this.page = 1;
|
||||
this.order_list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = false;
|
||||
this.initCondition();
|
||||
this.selectGoodsKeys = 0;
|
||||
this.getOrderListFn();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getOrderListFn() {
|
||||
if (this.listLock) return false;
|
||||
this.listLock = true;
|
||||
getOrderList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
search_text: this.search_text,
|
||||
order_scene: this.currOrderList,
|
||||
order_status: this.conditions.order_status,
|
||||
start_time: this.conditions.start_time_val ? this.conditions.start_time_val : this.conditions.start_time,
|
||||
end_time: this.conditions.end_time_val ? this.conditions.end_time_val : this.conditions.end_time,
|
||||
order_type: this.conditions.order_type,
|
||||
order_from: this.conditions.order_from,
|
||||
pay_type: this.conditions.pay_type,
|
||||
|
||||
}).then((res) => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.order_detail = {};
|
||||
this.one_judge = false;
|
||||
if (this.$refs.detailLoading) this.$refs.detailLoading.hide()
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
if (this.order_list.length == 0) {
|
||||
this.order_list = res.data.list;
|
||||
} else {
|
||||
this.order_list = this.order_list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getOrderDetailFn(this.order_list[0].order_id);
|
||||
}
|
||||
}
|
||||
if (this.page == 1) {
|
||||
this.scrollTop = 0
|
||||
}
|
||||
if (res.data.list.length >= this.page_size) {
|
||||
this.page++
|
||||
this.listLock = false
|
||||
}
|
||||
});
|
||||
},
|
||||
scroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
getOrderDetailFn(order_id, keys = 0, callback) {
|
||||
// 清空数据
|
||||
this.localDelivery = {
|
||||
deliverer_mobile: '',
|
||||
deliverer: ''
|
||||
};
|
||||
|
||||
this.selectGoodsKeys = keys;
|
||||
this.type = 'detail';
|
||||
this.$refs.detailLoading.show();
|
||||
getOrderDetail({
|
||||
order_id
|
||||
}).then((res) => {
|
||||
if (res.code >= 0) {
|
||||
this.order_detail = res.data;
|
||||
this.order_detail.order_status_action = JSON.parse(res.data.order_status_action)
|
||||
this.otherInfoValue.order_no.value = res.data.order_no;
|
||||
this.otherInfoValue.out_trade_no.value = res.data.out_trade_no;
|
||||
this.otherInfoValue.create_time.value = this.$util.timeFormat(res.data.create_time);
|
||||
this.otherInfoValue.operator_name.value = res.data.operator_name;
|
||||
this.otherInfoValue.pay_type.value = res.data.pay_type_name;
|
||||
this.otherInfoValue.order_status.value = res.data.order_status_name;
|
||||
if (res.data.pay_status == 1) {
|
||||
this.otherInfoValue.pay_status.value = '已支付';
|
||||
this.otherInfoValue.pay_time.value = this.$util.timeFormat(res.data.pay_time);
|
||||
} else {
|
||||
this.otherInfoValue.pay_status.value = '待支付';
|
||||
this.otherInfoValue.pay_time.value = '';
|
||||
}
|
||||
if (typeof callback == 'function') {
|
||||
callback();
|
||||
}
|
||||
Object.keys(this.adjustParams).forEach(key=>{
|
||||
this.adjustParams[key] = parseFloat(this.order_detail[key])
|
||||
})
|
||||
this.$forceUpdate();
|
||||
this.one_judge = false;
|
||||
if (this.$refs.detailLoading) this.$refs.detailLoading.hide()
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 打开弹出框
|
||||
* @param action
|
||||
*/
|
||||
open(action) {
|
||||
this.$refs[action].open();
|
||||
},
|
||||
/**
|
||||
* 关闭弹出框
|
||||
* @param name
|
||||
*/
|
||||
close(name) {
|
||||
this.$refs[name].close();
|
||||
},
|
||||
/**
|
||||
* 调价提交
|
||||
*/
|
||||
adjustSave(){
|
||||
if(parseFloat(this.adjustParams.delivery_money+0)<0){
|
||||
this.$util.showToast({
|
||||
title: '运费不可小于0'
|
||||
});
|
||||
return false
|
||||
}else if(!parseFloat(this.adjustParams.delivery_money+0)){
|
||||
this.adjustParams.delivery_money = 0
|
||||
}
|
||||
if(parseFloat(parseFloat(this.order_detail.goods_money)-parseFloat(this.order_detail.promotion_money||0)-parseFloat(this.order_detail.coupon_money||0) -parseFloat(this.order_detail.point_money||0)+ parseFloat(this.adjustParams.adjust_money||0) + parseFloat(this.adjustParams.delivery_money||0)).toFixed(2)<0){
|
||||
this.$util.showToast({
|
||||
title: '真实商品价格不可小于0'
|
||||
});
|
||||
return false
|
||||
}
|
||||
orderAdjustPrice(this.adjustParams).then((res)=>{
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetailFn(this.order_list[this.selectGoodsKeys].order_id);
|
||||
this.$refs.orderAdjustMoney.close()
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 关闭调价弹框
|
||||
*/
|
||||
clear(){
|
||||
Object.keys(this.adjustParams).forEach(key=>{
|
||||
this.adjustParams[key] = this.adjustParams[key] = parseFloat(this.order_detail[key])
|
||||
})
|
||||
this.$refs.orderAdjustMoney.close()
|
||||
},
|
||||
/**
|
||||
* 留言数据保存
|
||||
*/
|
||||
saveRemark() {
|
||||
orderRemark({
|
||||
order_id: this.order_detail.order_id,
|
||||
remark: this.order_detail.remark
|
||||
}).then((res) => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetailFn(this.order_list[this.selectGoodsKeys].order_id);
|
||||
this.$refs.remark.close();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 关闭订单
|
||||
*/
|
||||
orderCloseFn() {
|
||||
orderClose({
|
||||
order_id: this.order_detail.order_id
|
||||
}).then((res) => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetailFn(this.order_list[this.selectGoodsKeys].order_id, this.selectGoodsKeys, () => {
|
||||
this.order_list[this.selectGoodsKeys] = this.order_detail;
|
||||
this.$forceUpdate();
|
||||
});
|
||||
this.$refs.orderClose.close();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 订单取消
|
||||
*/
|
||||
orderOperation(type) {
|
||||
switch (type) {
|
||||
case 'save':
|
||||
this.orderCloseFn();
|
||||
break;
|
||||
case 'close':
|
||||
this.$refs.orderClose.close();
|
||||
break;
|
||||
}
|
||||
},
|
||||
selectOrderGoods(data) {
|
||||
let index = this.refundGoods.indexOf(data.order_goods_id);
|
||||
if (index == -1) this.refundGoods.push(data.order_goods_id);
|
||||
else this.refundGoods.splice(index, 1);
|
||||
},
|
||||
/**
|
||||
* 退款下一步
|
||||
*/
|
||||
refundNext() {
|
||||
|
||||
if (this.refundStep == 0) {
|
||||
if (!this.refundGoods.length) {
|
||||
this.$util.showToast({
|
||||
title: '请选择要退款的商品'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
getRefundApplyData({
|
||||
refund_array: JSON.stringify(this.refundGoods)
|
||||
}).then((res) => {
|
||||
|
||||
if (res.code == 0) {
|
||||
this.refundDetail = res.data;
|
||||
this.refundStep = 1;
|
||||
let refundData = {};
|
||||
|
||||
this.refundDetail.refund_list.forEach(refundItem => {
|
||||
refundData[refundItem.order_goods_info.order_goods_id] = {
|
||||
refund_pay_money: this.$util.moneyFormat(refundItem.order_goods_info.refund_apply_money),
|
||||
refund_money: this.$util.moneyFormat(refundItem.order_goods_info.refund_apply_money),
|
||||
refund_status:'PARTIAL_REFUND',
|
||||
is_refund_stock: 1,
|
||||
refund_stock_num: refundItem.order_goods_info.num
|
||||
};
|
||||
});
|
||||
Object.assign(this.refundApply, {
|
||||
order_id: this.order_detail.order_id,
|
||||
refund_array: refundData,
|
||||
refund_transfer_type: Object.keys(this.refundDetail.refund_transfer_type)[0]
|
||||
});
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (this.refundStep == 1) {
|
||||
if (this.refundVerify()) this.refundStep = 2;
|
||||
} else if (this.refundStep == 2) {
|
||||
this.createRefund();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 退款验证
|
||||
*/
|
||||
refundVerify() {
|
||||
try {
|
||||
this.refundDetail.refund_list.forEach(refundItem => {
|
||||
let data = this.refundApply.refund_array[refundItem.order_goods_info.order_goods_id];
|
||||
if (isNaN(parseFloat(data.refund_money))) {
|
||||
this.$util.showToast({
|
||||
title: '退款金额输入错误'
|
||||
});
|
||||
throw new Error('');
|
||||
}
|
||||
if (parseFloat(data.refund_money) < 0) {
|
||||
this.$util.showToast({
|
||||
title: '退款金额不能小于0'
|
||||
});
|
||||
throw new Error('');
|
||||
}
|
||||
if (parseFloat(data.refund_money) > parseFloat(data.refund_pay_money)) {
|
||||
this.$util.showToast({
|
||||
title: '退款金额超出可退金额'
|
||||
});
|
||||
throw new Error('');
|
||||
}
|
||||
|
||||
if(data.is_refund_stock == 1){
|
||||
if(!Number(data.refund_stock_num)){
|
||||
this.$util.showToast({
|
||||
title: '请输入返还数量'
|
||||
});
|
||||
throw new Error('');
|
||||
}
|
||||
|
||||
if(data.refund_stock_num <= 0){
|
||||
this.$util.showToast({
|
||||
title: '返还数量不能小于0'
|
||||
});
|
||||
throw new Error('');
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(refundItem.order_goods_info.goods_class != 6 || (refundItem.order_goods_info.goods_class == 6 && refundItem.order_goods_info.pricing_type != 'weight' )){
|
||||
// 不能为小数
|
||||
if(String(data.refund_stock_num).indexOf('.') != -1){
|
||||
this.$util.showToast({
|
||||
title: '商品'+refundItem.order_goods_info.goods_name+'的返还数量只能是正整数'
|
||||
});
|
||||
throw new Error('');
|
||||
}
|
||||
}
|
||||
|
||||
if(data.refund_stock_num > refundItem.order_goods_info.num){
|
||||
this.$util.showToast({
|
||||
title: '商品'+refundItem.order_goods_info.goods_name+'最多返还'+refundItem.order_goods_info.num+'件'
|
||||
});
|
||||
throw new Error('');
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* 退款申请
|
||||
*/
|
||||
createRefund() {
|
||||
if (this.refundRepeat) return;
|
||||
this.refundRepeat = true;
|
||||
|
||||
uni.showLoading({
|
||||
title: ''
|
||||
});
|
||||
|
||||
let data = this.$util.deepClone(this.refundApply);
|
||||
data.refund_array = JSON.stringify(data.refund_array);
|
||||
|
||||
orderRefund(data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.code == 0) {
|
||||
this.$util.showToast({
|
||||
title: '退款成功'
|
||||
});
|
||||
this.getOrderDetailFn(this.order_detail.order_id);
|
||||
this.type = 'detail';
|
||||
} else {
|
||||
this.refundRepeat = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
/**
|
||||
* 提货
|
||||
*/
|
||||
storeOrderTakeDelivery() {
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
|
||||
uni.showLoading({
|
||||
title: ''
|
||||
});
|
||||
orderStoreDelivery(this.order_detail.order_id).then(res => {
|
||||
uni.hideLoading();
|
||||
this.isRepeat = false;
|
||||
if (res.code == 0) {
|
||||
this.getOrderDetailFn(this.order_detail.order_id);
|
||||
this.$refs.storeOrderTakeDelivery.close();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 本地配送
|
||||
*/
|
||||
orderLocalDeliveryFn() {
|
||||
if (!this.localDelivery.deliverer) {
|
||||
this.$util.showToast({
|
||||
title: '请选择配送员'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!this.localDelivery.deliverer_mobile) {
|
||||
this.$util.showToast({
|
||||
title: '请输入配送员联系方式'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
|
||||
uni.showLoading({
|
||||
title: ''
|
||||
});
|
||||
|
||||
orderLocalDelivery({
|
||||
order_id: this.order_detail.order_id,
|
||||
deliverer: this.localDelivery.deliverer,
|
||||
deliverer_mobile: this.localDelivery.deliverer_mobile
|
||||
}).then(res => {
|
||||
uni.hideLoading();
|
||||
this.isRepeat = false;
|
||||
if (res.code == 0) {
|
||||
this.getOrderDetailFn(this.order_detail.order_id);
|
||||
this.localDelivery = {
|
||||
deliverer_mobile: '',
|
||||
deliverer: ''
|
||||
};
|
||||
this.$refs.orderLocalDelivery.close();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
getDeliver() {
|
||||
getOrderDeliverList().then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.deliverer = res.data.map(item => {
|
||||
return {
|
||||
label: item.deliver_name,
|
||||
value: item.deliver_name, // 废弃,deliver_id
|
||||
mobile: item.deliver_mobile
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
selectDeliverer(index, item) {
|
||||
if (index >= 0) {
|
||||
this.localDelivery.deliverer_mobile = this.deliverer[index].mobile; // 配送员手机号
|
||||
this.localDelivery.deliverer = item.value; // 配送员
|
||||
} else {
|
||||
this.localDelivery.deliverer_mobile = '';
|
||||
this.localDelivery.deliverer = '';
|
||||
}
|
||||
},
|
||||
viewMember() {
|
||||
this.$util.redirectTo('/pages/member/list', {member_id: this.order_detail.member_id});
|
||||
},
|
||||
/**
|
||||
* 打印小票
|
||||
*/
|
||||
printTicket() {
|
||||
orderPrintTicket(this.order_detail.order_id).then(res => {
|
||||
if (res.code == 0) {
|
||||
if (Object.values(res.data).length) {
|
||||
let data = Object.values(res.data);
|
||||
try {
|
||||
let print = {
|
||||
printer: []
|
||||
};
|
||||
data.forEach((item) => {
|
||||
print.printer.push({
|
||||
printer_type: item.printer_info.printer_type,
|
||||
host: item.printer_info.host,
|
||||
ip: item.printer_info.ip,
|
||||
port: item.printer_info.port,
|
||||
content: item.content,
|
||||
print_width: item.printer_info.print_width
|
||||
})
|
||||
});
|
||||
this.$pos.send('Print', JSON.stringify(print));
|
||||
} catch (e) {
|
||||
console.log('err', e, res.data)
|
||||
}
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: '未开启订单小票打印'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message ? res.message : '小票打印失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getExpressCompany() {
|
||||
getExpressCompanyList().then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.expressCompany = res.data.map(item => {
|
||||
return {
|
||||
label: item.company_name,
|
||||
value: item.company_id
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
selectExpressCompany(index, item) {
|
||||
if (index >= 0) {
|
||||
this.expresDelivery.express_company_id = parseInt(item.value)
|
||||
} else {
|
||||
this.expresDelivery.express_company_id = 0
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 物流配送订单发货
|
||||
*/
|
||||
orderDelivery() {
|
||||
if (this.expresDelivery.delivery_type == 1) {
|
||||
if (!this.expresDelivery.express_company_id) {
|
||||
this.$util.showToast({
|
||||
title: '请选择物流公司'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!this.expresDelivery.delivery_no) {
|
||||
this.$util.showToast({
|
||||
title: '请输入物流单号'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!this.expresDelivery.order_goods_ids.length) {
|
||||
this.$util.showToast({
|
||||
title: '请选择要发货的商品'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isLogisticsRepeat) return;
|
||||
this.isLogisticsRepeat = true;
|
||||
|
||||
uni.showLoading({
|
||||
title: ''
|
||||
});
|
||||
orderExpressDelivery({
|
||||
order_id: this.order_detail.order_id,
|
||||
delivery_type: this.expresDelivery.delivery_type,
|
||||
express_company_id: this.expresDelivery.express_company_id,
|
||||
delivery_no: this.expresDelivery.delivery_no,
|
||||
order_goods_ids: this.expresDelivery.order_goods_ids.toString()
|
||||
}).then(res => {
|
||||
uni.hideLoading();
|
||||
if (res.code == 0) {
|
||||
this.isLogisticsRepeat = false;
|
||||
this.getOrderDetailFn(this.order_detail.order_id);
|
||||
this.expresDelivery = {
|
||||
delivery_type: 1,
|
||||
express_company_id: 0,
|
||||
delivery_no: '',
|
||||
order_goods_ids: []
|
||||
};
|
||||
this.$refs.orderDelivery.close();
|
||||
} else {
|
||||
this.isLogisticsRepeat = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
251
addon/cashier/source/os/pages/order/public/js/order_refund.js
Executable file
251
addon/cashier/source/os/pages/order/public/js/order_refund.js
Executable file
@@ -0,0 +1,251 @@
|
||||
import {
|
||||
orderRefundComplete,
|
||||
getOrderRefundLists,
|
||||
getOrderRefundDetail,
|
||||
orderRefundAgree,
|
||||
orderRefundClose,
|
||||
orderRefundRefuse,
|
||||
orderRefundReceive
|
||||
} from '@/api/order_refund.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectGoodsKeys: 0,
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 8,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
//初始时加载详情数据判断
|
||||
one_judge: true,
|
||||
//无限滚动请求锁
|
||||
listLock: true,
|
||||
scrollTop: 0,
|
||||
// 订单列表数据
|
||||
order_list: [],
|
||||
//订单详情数据
|
||||
order_detail: {},
|
||||
tabObj: {
|
||||
list: [{
|
||||
value: 1,
|
||||
name: '基础信息'
|
||||
}, {
|
||||
value: 2,
|
||||
name: '商品信息'
|
||||
}, {
|
||||
value: 3,
|
||||
name: '订单日志'
|
||||
}],
|
||||
index: 1
|
||||
},
|
||||
isRepeat: false,
|
||||
refundRefuseReason: '', // 拒绝理由
|
||||
refundTransfer: {
|
||||
refund_real_money: 0,
|
||||
refund_money_type: 1,
|
||||
shop_refund_remark: ''
|
||||
},
|
||||
isRefundStock: 0
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.getOrderList();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.order_list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = true;
|
||||
this.getOrderList();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getOrderList() {
|
||||
if (!this.listLock) return false;
|
||||
getOrderRefundLists({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
search: this.search_text
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0) {
|
||||
this.order_detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0) {
|
||||
if (this.order_list.length == 0) {
|
||||
this.order_list = res.data.list;
|
||||
} else {
|
||||
this.order_list = this.order_list.concat(res.data.list);
|
||||
}
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getOrderDetail(this.order_list[0].order_goods_id);
|
||||
}
|
||||
}
|
||||
if (this.page == 1) {
|
||||
this.scrollTop = 0
|
||||
}
|
||||
if (res.data.list.length < this.page_size) {
|
||||
this.listLock = false
|
||||
} else {
|
||||
this.page++
|
||||
}
|
||||
})
|
||||
},
|
||||
scroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
getOrderDetail(order_goods_id, keys = 0, callback) {
|
||||
this.selectGoodsKeys = keys;
|
||||
getOrderRefundDetail({order_goods_id}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.order_detail = res.data;
|
||||
if (typeof callback == 'function') {
|
||||
callback();
|
||||
}
|
||||
this.$forceUpdate();
|
||||
this.one_judge = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 打开弹出框
|
||||
*/
|
||||
open(action) {
|
||||
if (action == 'orderRefundTransfer') {
|
||||
this.refundTransfer.order_goods_id = this.order_detail.order_goods_id;
|
||||
this.refundTransfer.refund_real_money = this.order_detail.refund_apply_money;
|
||||
this.refundTransfer.refund_money_type = 1;
|
||||
this.refundTransfer.shop_refund_remark = '';
|
||||
}
|
||||
this.$refs[action].open();
|
||||
},
|
||||
/**
|
||||
* 关闭弹出框
|
||||
*/
|
||||
close(name) {
|
||||
this.$refs[name].close();
|
||||
},
|
||||
// 同意维权
|
||||
orderRefundAgree() {
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
orderRefundAgree({order_goods_id: this.order_detail.order_goods_id}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetail(this.order_detail.order_goods_id);
|
||||
this.$refs.orderRefundAgree.close();
|
||||
}
|
||||
this.isRepeat = false;
|
||||
});
|
||||
},
|
||||
// 拒绝维权
|
||||
orderRefundRefuse() {
|
||||
if (!this.refundRefuseReason) {
|
||||
this.$util.showToast({
|
||||
title: '请输入拒绝理由'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
orderRefundRefuse({
|
||||
order_goods_id: this.order_detail.order_goods_id,
|
||||
refund_refuse_reason: this.refundRefuseReason
|
||||
}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetail(this.order_detail.order_goods_id);
|
||||
this.$refs.orderRefundRefuse.close();
|
||||
}
|
||||
this.isRepeat = false;
|
||||
});
|
||||
},
|
||||
// 关闭维权
|
||||
orderRefundClose() {
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
|
||||
orderRefundClose({
|
||||
order_goods_id: this.order_detail.order_goods_id
|
||||
}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetail(this.order_detail.order_goods_id);
|
||||
this.$refs.orderRefundClose.close();
|
||||
}
|
||||
this.isRepeat = false;
|
||||
});
|
||||
},
|
||||
// 转账
|
||||
orderRefundTransfer() {
|
||||
if (!this.refundTransfer.refund_real_money) {
|
||||
this.$util.showToast({
|
||||
title: '请输入退款金额'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var money = parseFloat(this.refundTransfer.refund_real_money);
|
||||
if (isNaN(money)) {
|
||||
this.$util.showToast({
|
||||
title: '请输入正确的退款金额'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (money < 0) {
|
||||
this.$util.showToast({
|
||||
title: '退款金额不能为负数'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
|
||||
orderRefundComplete(this.refundTransfer).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetail(this.order_detail.order_goods_id);
|
||||
this.$refs.orderRefundTransfer.close();
|
||||
}
|
||||
this.isRepeat = false;
|
||||
})
|
||||
},
|
||||
// 买家退货接收,维权收货
|
||||
orderRefundTakeDelivery() {
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
orderRefundReceive({
|
||||
order_goods_id: this.order_detail.order_goods_id,
|
||||
is_refund_stock: this.isRefundStock
|
||||
}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.getOrderDetail(this.order_detail.order_goods_id);
|
||||
this.$refs.orderRefundTakeDelivery.close();
|
||||
}
|
||||
this.isRepeat = false;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
96
addon/cashier/source/os/pages/order/public/js/recharge_order.js
Executable file
96
addon/cashier/source/os/pages/order/public/js/recharge_order.js
Executable file
@@ -0,0 +1,96 @@
|
||||
import {getOrderRechargeDetail, getOrderRechargeList} from '@/api/recharge.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectGoodsKeys: 0,
|
||||
// 订购日志所需列表数据
|
||||
list: [],
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 8,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
//订单类型
|
||||
trade_type: '',
|
||||
//初始时加载详情数据判断
|
||||
one_judge: true,
|
||||
//无限滚动请求锁
|
||||
listLock: true,
|
||||
scrollTop: 0,
|
||||
// 订单列表数据
|
||||
order_list: [],
|
||||
//订单详情数据
|
||||
order_detail: {}
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.getOrderList();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.order_list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = true;
|
||||
this.getOrderList();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getOrderList() {
|
||||
if (!this.listLock) return false;
|
||||
getOrderRechargeList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
search_text: this.search_text
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.order_detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
if (this.order_list.length == 0) {
|
||||
this.order_list = res.data.list;
|
||||
} else {
|
||||
this.order_list = this.order_list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getOrderDetail(this.order_list[0].order_id);
|
||||
}
|
||||
}
|
||||
if (this.page == 1) {
|
||||
this.scrollTop = 0
|
||||
}
|
||||
if (res.data.list.length < this.page_size) {
|
||||
this.listLock = false
|
||||
} else {
|
||||
this.page++
|
||||
}
|
||||
})
|
||||
},
|
||||
scroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
getOrderDetail(order_id, keys = 0, callback) {
|
||||
this.selectGoodsKeys = keys;
|
||||
getOrderRechargeDetail({order_id}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.order_detail = res.data;
|
||||
if (typeof callback == 'function') {
|
||||
callback();
|
||||
}
|
||||
this.$forceUpdate();
|
||||
this.one_judge = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
};
|
||||
174
addon/cashier/source/os/pages/order/rechargeorder.vue
Executable file
174
addon/cashier/source/os/pages/order/rechargeorder.vue
Executable file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
充值订单
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
|
||||
<view class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input type="text" v-model="search_text" @input="search" placeholder="搜索订单号/流水号/买家" />
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="!one_judge && order_list.length > 0">
|
||||
<scroll-view :scroll-top="scrollTop" @scroll="scroll" scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getOrderList">
|
||||
<view class="item" @click="getOrderDetail(item.order_id, index)" v-for="(item, index) in order_list" :key="index" :class="index == selectGoodsKeys ? 'itemhover' : ''">
|
||||
<view class="title">
|
||||
<view>订单编号:{{ item.order_no }}</view>
|
||||
<view>充值订单</view>
|
||||
</view>
|
||||
<view class="total-money-num">
|
||||
<view class="member-info">
|
||||
<view>买家:</view>
|
||||
<view v-if="item.member_id">{{ item.nickname }}</view>
|
||||
<view v-else>散客</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>充值金额</view>
|
||||
<view>¥{{ item.face_value }}</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>实付金额</view>
|
||||
<view>¥{{ item.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="!one_judge && order_list.length == 0">暂无数据</view>
|
||||
</view>
|
||||
<view class="goodslist-right">
|
||||
<view class="goods-title">订单详情</view>
|
||||
<view class="order-information" v-show="!one_judge">
|
||||
<block v-if="JSON.stringify(order_detail) != '{}'">
|
||||
<view class="order-status">充值订单</view>
|
||||
<view class="order-types">
|
||||
<view class="type type1">
|
||||
<view>订单编号:</view>
|
||||
<view>{{ order_detail.order_no }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>订单流水号:</view>
|
||||
<view>{{ order_detail.out_trade_no }}</view>
|
||||
</view>
|
||||
|
||||
<view class="type type1">
|
||||
<view>买家:</view>
|
||||
<view v-if="order_detail.member_id">
|
||||
{{ order_detail.nickname }}
|
||||
<text class="look" @click="$util.redirectTo('/pages/member/list', { member_id: order_detail.member_id })">查看</text>
|
||||
</view>
|
||||
<view v-else>散客</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>实付金额:</view>
|
||||
<view>{{ order_detail.price }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>实付方式:</view>
|
||||
<view>{{ order_detail.pay_type_name }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>状态:</view>
|
||||
<view>{{ order_detail.status == 2 ? '已支付' : '未支付' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>支付时间:</view>
|
||||
<view>{{ order_detail.pay_time > 0 ? $util.timeFormat(order_detail.pay_time) : '' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>订单来源:</view>
|
||||
<view>{{ order_detail.order_from_name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="other-information">
|
||||
<view class="title">其他信息</view>
|
||||
<view class="item-box">
|
||||
<view class="item">
|
||||
<view>套餐名称:</view>
|
||||
<view>{{ order_detail.recharge_name }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>充值面值:</view>
|
||||
<view>{{ order_detail.face_value }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view>售价:</view>
|
||||
<view>{{ order_detail.buy_price }}</view>
|
||||
</view>
|
||||
<view class="item" v-if="order_detail.point > 0">
|
||||
<view>赠送积分:</view>
|
||||
<view>{{ order_detail.point }}</view>
|
||||
</view>
|
||||
<view class="item" v-if="order_detail.growth > 0">
|
||||
<view>赠送成长值:</view>
|
||||
<view>{{ order_detail.growth }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goods-info" v-if="order_detail.coupon_list && order_detail.coupon_list['data'].length > 0">
|
||||
<view class="title">赠送优惠券</view>
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:25%">优惠券名称</view>
|
||||
<view class="table-td" style="width:15%">类型</view>
|
||||
<view class="table-td" style="width:35%">优惠金额</view>
|
||||
<view class="table-td" style="width:25%;justify-content: flex-end;">有效期</view>
|
||||
</view>
|
||||
<block v-for="(item, index) in order_detail.coupon_list['data']" :key="index">
|
||||
<view class="table-tr table-all">
|
||||
<view class="table-td" style="width:25%">{{ item.coupon_name }}</view>
|
||||
<view class="table-td" style="width:15%">{{ item.type == 'reward' ? '满减券' : '折扣券' }}</view>
|
||||
<view class="table-td" style="width:40%" v-if="item.type == 'reward'">满{{ item.at_least }}元减{{ item.money }}</view>
|
||||
<view class="table-td" style="width:35%" v-if="item.type == 'discount'">
|
||||
满{{ item.at_least }}元打{{ item.discount }}折
|
||||
<block v-if="item.discount_limit">(最多抵扣{{ item.discount_limit }}元)</block>
|
||||
</view>
|
||||
<view class="table-td uni-column" style="width:25%;text-align: right;align-items: flex-end;">
|
||||
<view v-if="item.end_time">{{ $util.timeFormat(item.end_time) }}</view>
|
||||
<view v-else>长期有效</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image class="cart-empty" src="@/static/cashier/cart_empty.png" mode="widthFix" />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
import rechargeOrder from './public/js/recharge_order';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup
|
||||
},
|
||||
mixins: [rechargeOrder]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/orderlist.scss';
|
||||
|
||||
.goodslist .goodslist-box .goodslist-right .order-information .goods-info {
|
||||
padding: 0.2rem 0;
|
||||
}
|
||||
|
||||
/deep/ .goods-list-scroll {
|
||||
width: 100%;
|
||||
height: calc(100% - 1.71rem) !important;
|
||||
}</style>
|
||||
746
addon/cashier/source/os/pages/printer/add.vue
Executable file
746
addon/cashier/source/os/pages/printer/add.vue
Executable file
@@ -0,0 +1,746 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="printer ">
|
||||
<view class="common-wrap common-form body-overhide">
|
||||
<view class="common-title">打印机设置</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机名称
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="savedata.printer_name" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机类型
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="printerTypeChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="cloud" :checked="savedata.printer_type == 'cloud'" />
|
||||
云打印机
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="local" :checked="savedata.printer_type == 'local'" />
|
||||
本地打印机
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="network" :checked="savedata.printer_type == 'network'" />
|
||||
网络打印机
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view v-show="savedata.printer_type == 'cloud'">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机品牌
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<view class="form-input">易联云</view>
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机编号
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="savedata.printer_code" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机密钥
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="savedata.printer_key" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
应用id
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="savedata.open_id" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux-line">应用id(易联云-开发者中心后台应用中心里获取)</text>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
apiKey
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="savedata.apikey" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux-line">apiKey(易联云-开发者中心后台应用中心里获取)</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-show="savedata.printer_type == 'local'">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机端口
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<view class="form-input">
|
||||
<input type="text" v-model="savedata.host" class="form-input" /></view>
|
||||
</view>
|
||||
<text class="form-word-aux">打印机端口 (可以填写打印机端口号:如LPT1 或 本地网络共享打印机:如\\192.168.1.100\POS_NAME)</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-show="savedata.printer_type == 'network'">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机IP
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<view class="form-input">
|
||||
<input type="text" v-model="savedata.ip" class="form-input" /></view>
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印机端口
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<view class="form-input">
|
||||
<input type="text" v-model="savedata.port" class="form-input" /></view>
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-show="savedata.printer_type == 'local' || savedata.printer_type == 'network'">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
打印宽度
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="printWidthChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="58mm" :checked="savedata.print_width == '58mm'" />
|
||||
58mm
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="80mm" :checked="savedata.print_width == '80mm'" />
|
||||
80mm
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-title">支付打印</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">支付打印</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="orderPayChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.order_pay_open == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="savedata.order_pay_open == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.order_pay_open == 1">
|
||||
<label class="form-label">打印模板</label>
|
||||
<view class="form-input-inline " v-if="template.goodsorder && template.goodsorder.length">
|
||||
<uni-data-select v-model="orderPayTempIndex" :localdata="template.goodsorder"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.order_pay_open == 1">
|
||||
<label class="form-label">打印联数</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="orderPayNumChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.order_pay_print_num == 1" />
|
||||
1
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="2" :checked="savedata.order_pay_print_num == 2" />
|
||||
2
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="3" :checked="savedata.order_pay_print_num == 3" />
|
||||
3
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="4" :checked="savedata.order_pay_print_num == 4" />
|
||||
4
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.order_pay_open == 1">
|
||||
<label class="form-label">订单类型</label>
|
||||
<view class="form-block">
|
||||
<checkbox-group class="form-checkbox-group" @change="orderPayTypeChange">
|
||||
<label class="form-checkbox-item" v-for="(item, index) in orderType">
|
||||
<checkbox :value="item.type.toString()" :checked="savedata.order_pay_order_type.includes(item.type.toString()) || savedata.order_pay_order_type.includes(parseInt(item.type))" />
|
||||
{{ item.name }}
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-title">收货打印</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">收货打印</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="takeDeliveryChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.take_delivery_open == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="savedata.take_delivery_open == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.take_delivery_open == 1">
|
||||
<label class="form-label">打印模板</label>
|
||||
<view class="form-input-inline" v-if="template.goodsorder && template.goodsorder.length">
|
||||
<uni-data-select v-model="takeDeliveryTempIndex" :localdata="template.goodsorder"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.take_delivery_open == 1">
|
||||
<label class="form-label">打印联数</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="takeDeliveryNumChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.take_delivery_print_num == 1" />
|
||||
1
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="2" :checked="savedata.take_delivery_print_num == 2" />
|
||||
2
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="3" :checked="savedata.take_delivery_print_num == 3" />
|
||||
3
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="4" :checked="savedata.take_delivery_print_num == 4" />
|
||||
4
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.take_delivery_open == 1">
|
||||
<label class="form-label">订单类型</label>
|
||||
<view class="form-block">
|
||||
<checkbox-group class="form-checkbox-group" @change="takeDeliveryTypeChange">
|
||||
<label class="form-checkbox-item" v-for="(item, index) in orderType">
|
||||
<checkbox :value="item.type.toString()" :checked="savedata.take_delivery_order_type.includes(item.type.toString()) || savedata.take_delivery_order_type.includes(parseInt(item.type))" />
|
||||
{{ item.name }}
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-title">手动打印</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">手动打印</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="manualChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.manual_open == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="savedata.manual_open == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.manual_open == 1">
|
||||
<label class="form-label">打印模板</label>
|
||||
<view class="form-input-inline" v-if="template.goodsorder && template.goodsorder.length">
|
||||
<uni-data-select v-model="manualTempIndex" :localdata="template.goodsorder"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.manual_open == 1">
|
||||
<label class="form-label">打印联数</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="manualNumChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.print_num == 1" />
|
||||
1
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="2" :checked="savedata.print_num == 2" />
|
||||
2
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="3" :checked="savedata.print_num == 3" />
|
||||
3
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="4" :checked="savedata.print_num == 4" />
|
||||
4
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-title">充值打印</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">充值打印</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="rechargeChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.recharge_open == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="savedata.recharge_open == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.recharge_open == 1">
|
||||
<label class="form-label">打印模板</label>
|
||||
<view class="form-input-inline" v-if="template.recharge && template.recharge.length">
|
||||
<uni-data-select v-model="rechargeTempIndex" :localdata="template.recharge"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.recharge_open == 1">
|
||||
<label class="form-label">打印联数</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="rechargeNumChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.recharge_print_num == 1" />
|
||||
1
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="2" :checked="savedata.recharge_print_num == 2" />
|
||||
2
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="3" :checked="savedata.recharge_print_num == 3" />
|
||||
3
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="4" :checked="savedata.recharge_print_num == 4" />
|
||||
4
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-title">收银交班打印</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">收银交班打印</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="changeShiftsChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.change_shifts_open == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="savedata.change_shifts_open == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.change_shifts_open == 1">
|
||||
<label class="form-label">打印模板</label>
|
||||
<view class="form-input-inline" v-if="template.change_shifts && template.change_shifts.length">
|
||||
<uni-data-select v-model="changeShiftsTempIndex" :localdata="template.change_shifts"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="savedata.change_shifts_open == 1">
|
||||
<label class="form-label">打印联数</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="changeShiftsNumChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="savedata.change_shifts_print_num == 1" />
|
||||
1
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="2" :checked="savedata.change_shifts_print_num == 2" />
|
||||
2
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="3" :checked="savedata.change_shifts_print_num == 3" />
|
||||
3
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="4" :checked="savedata.change_shifts_print_num == 4" />
|
||||
4
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="primary-btn" @click="saveFn">保存</button>
|
||||
<button type="default" class="default-btn" @click="back">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniDataSelect from '@/components/uni-data-select/uni-data-select.vue';
|
||||
import {
|
||||
getPrinterInfo,
|
||||
getTemplate,
|
||||
getOrderType,
|
||||
editPrinter,
|
||||
addPrinter
|
||||
} from '@/api/printer.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
uniDataSelect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
printer_id: 0,
|
||||
savedata: {
|
||||
printer_name: '',
|
||||
brand: 'yilianyun',
|
||||
printer_code: '',
|
||||
printer_key: '',
|
||||
open_id: '',
|
||||
apikey: '',
|
||||
printer_type: 'cloud',
|
||||
|
||||
order_pay_open: 0,
|
||||
order_pay_template_id: 0,
|
||||
order_pay_print_num: 1,
|
||||
order_pay_order_type: [],
|
||||
|
||||
take_delivery_open: 0,
|
||||
take_delivery_template_id: 0,
|
||||
take_delivery_print_num: 1,
|
||||
take_delivery_order_type: [],
|
||||
|
||||
manual_open: 0,
|
||||
template_id: 0,
|
||||
print_num: 1,
|
||||
|
||||
recharge_open: 0,
|
||||
recharge_template_id: 0,
|
||||
recharge_print_num: 1,
|
||||
|
||||
change_shifts_open: 0,
|
||||
change_shifts_template_id: 0,
|
||||
change_shifts_print_num: 1,
|
||||
host: '',
|
||||
ip: '',
|
||||
port: '',
|
||||
print_width: '58mm'
|
||||
},
|
||||
time: {
|
||||
start: '08:30',
|
||||
end: '23:30'
|
||||
},
|
||||
interval: 30,
|
||||
advance: '',
|
||||
max: '',
|
||||
week: [],
|
||||
flag: false,
|
||||
template: {},
|
||||
orderPayTempIndex: 0,
|
||||
takeDeliveryTempIndex: 0,
|
||||
manualTempIndex: 0,
|
||||
rechargeTempIndex: 0,
|
||||
changeShiftsTempIndex: 0,
|
||||
orderType: []
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
if (option.printer_id) {
|
||||
this.printer_id = option.printer_id;
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
uni.setLocale('zh-Hans');
|
||||
this.getTemplate();
|
||||
this.getOrderTypeFn();
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
getPrinterInfo(this.printer_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.savedata = res.data;
|
||||
this.orderPayTempIndex = this.savedata.order_pay_template_id;
|
||||
this.takeDeliveryTempIndex = this.savedata.take_delivery_template_id;
|
||||
this.manualTempIndex = this.savedata.template_id;
|
||||
this.rechargeTempIndex = this.savedata.recharge_template_id;
|
||||
this.changeShiftsTempIndex = this.savedata.change_shifts_template_id;
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
back() {
|
||||
this.$util.redirectTo('/pages/printer/list');
|
||||
},
|
||||
getTemplate() {
|
||||
getTemplate().then(res => {
|
||||
if (res.code == 0) {
|
||||
let template = {};
|
||||
res.data.map((item, index) => {
|
||||
if (!template[item.type]) template[item.type] = [];
|
||||
var obj = {};
|
||||
obj.text = item.template_name;
|
||||
obj.value = item.template_id;
|
||||
template[item.type].push(obj);
|
||||
});
|
||||
this.template = template;
|
||||
if (this.printer_id) {
|
||||
this.getData();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getOrderTypeFn() {
|
||||
getOrderType().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.orderType = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
printerTypeChange(e) {
|
||||
this.savedata.printer_type = e.detail.value;
|
||||
},
|
||||
printWidthChange(e) {
|
||||
this.savedata.print_width = e.detail.value;
|
||||
},
|
||||
orderPayChange(e) {
|
||||
this.savedata.order_pay_open = e.detail.value;
|
||||
},
|
||||
orderPayNumChange(e) {
|
||||
this.savedata.order_pay_print_num = e.detail.value;
|
||||
},
|
||||
orderPayTypeChange(e) {
|
||||
this.savedata.order_pay_order_type = e.detail.value;
|
||||
},
|
||||
takeDeliveryChange(e) {
|
||||
this.savedata.take_delivery_open = e.detail.value;
|
||||
},
|
||||
takeDeliveryNumChange(e) {
|
||||
this.savedata.take_delivery_print_num = e.detail.value;
|
||||
},
|
||||
takeDeliveryTypeChange(e) {
|
||||
this.savedata.take_delivery_order_type = e.detail.value;
|
||||
},
|
||||
manualChange(e) {
|
||||
this.savedata.manual_open = e.detail.value;
|
||||
},
|
||||
manualNumChange(e) {
|
||||
this.savedata.print_num = e.detail.value;
|
||||
},
|
||||
rechargeChange(e) {
|
||||
this.savedata.recharge_open = e.detail.value;
|
||||
},
|
||||
rechargeNumChange(e) {
|
||||
this.savedata.recharge_print_num = e.detail.value;
|
||||
},
|
||||
changeShiftsChange(e) {
|
||||
this.savedata.change_shifts_open = e.detail.value;
|
||||
},
|
||||
changeShiftsNumChange(e) {
|
||||
this.savedata.change_shifts_print_num = e.detail.value;
|
||||
},
|
||||
check() {
|
||||
let data = Object.assign({}, this.savedata);
|
||||
if (!data.printer_name) {
|
||||
this.$util.showToast({
|
||||
title: '请输入打印机名称'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (data.printer_type == 'cloud') {
|
||||
if (!data.printer_code) {
|
||||
this.$util.showToast({
|
||||
title: '请输入打印机编号'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data.printer_key) {
|
||||
this.$util.showToast({
|
||||
title: '请输入打印机密钥'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data.open_id) {
|
||||
this.$util.showToast({
|
||||
title: '请输入应用id'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data.apikey) {
|
||||
this.$util.showToast({
|
||||
title: '请输入apikey'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.printer_type == 'local') {
|
||||
if (!data.host) {
|
||||
this.$util.showToast({
|
||||
title: '请输入打印机打印机端口'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.printer_type == 'network') {
|
||||
if (!data.ip) {
|
||||
this.$util.showToast({
|
||||
title: '请输入打印机打印机地址'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!data.port) {
|
||||
this.$util.showToast({
|
||||
title: '请输入打印机打印机端口'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
saveFn() {
|
||||
if (this.check()) {
|
||||
let data = this.savedata;
|
||||
data.take_delivery_order_type = data.take_delivery_order_type.toString();
|
||||
data.order_pay_order_type = data.order_pay_order_type.toString();
|
||||
|
||||
data.order_pay_template_id = this.orderPayTempIndex;
|
||||
data.take_delivery_template_id = this.takeDeliveryTempIndex;
|
||||
data.template_id = this.manualTempIndex;
|
||||
data.recharge_template_id = this.rechargeTempIndex;
|
||||
data.change_shifts_template_id = this.changeShiftsTempIndex;
|
||||
|
||||
let action = '';
|
||||
if (this.printer_id > 0) {
|
||||
data.printer_id = this.printer_id;
|
||||
action = editPrinter(data)
|
||||
} else {
|
||||
action = addPrinter(data)
|
||||
}
|
||||
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
action.then(res => {
|
||||
this.flag = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
setTimeout(() => {
|
||||
this.$util.redirectTo('/pages/printer/list');
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
timeTurnTimeStamp(time) {
|
||||
let data = time.split(':');
|
||||
return data[0] * 3600 + data[1] * 60;
|
||||
},
|
||||
timeFormat(time) {
|
||||
let h = time / 3600;
|
||||
let i = (time % 3600) / 60;
|
||||
h = h < 10 ? '0' + h : h;
|
||||
i = i < 10 ? '0' + i : i;
|
||||
return h + ':' + i;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
/deep/ .uni-select{
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.printer{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
.common-wrap {
|
||||
background-color: #fff;
|
||||
@extend %body-overhide;
|
||||
padding: 0.2rem 0.2rem 0.88rem 0.2rem;
|
||||
|
||||
}
|
||||
.common-btn-wrap{
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
button{
|
||||
line-height: 0.4rem;
|
||||
height: 0.4rem;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
&.primary-btn{
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
367
addon/cashier/source/os/pages/printer/list.vue
Executable file
367
addon/cashier/source/os/pages/printer/list.vue
Executable file
@@ -0,0 +1,367 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="printerlist">
|
||||
<view class="printerlist-box">
|
||||
<view class="printerlist-left">
|
||||
<view class="printer-title">
|
||||
打印机
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="printer-list-wrap">
|
||||
<block v-if="list.length > 0">
|
||||
<scroll-view scroll-y="true" class="printer-list-scroll all-scroll" @scrolltolower="getPrinterListFn">
|
||||
<view class="item" @click="printerSelect(item, index)" v-for="(item, index) in list" :key="index" :class="index == selectprinterKeys ? 'itemhover' : ''">
|
||||
<view class="item-right">
|
||||
<view class="printer-name">{{ item.printer_name }}</view>
|
||||
<view class="printer-money">{{ printerType(item.printer_type) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="!one_judge && list.length == 0">暂无打印机</view>
|
||||
</view>
|
||||
<view class="add-printer">
|
||||
<button type="default" class="primary-btn" @click="addprinter">添加打印机</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="printerlist-right" v-show="!one_judge">
|
||||
<view class="printer-title">打印机详情</view>
|
||||
<view class="printer-information">
|
||||
<block v-if="JSON.stringify(detail) != '{}'">
|
||||
<view class="title">基本信息</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>名称:</view>
|
||||
<view>{{ detail.printer_name }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>打印机类型:</view>
|
||||
<view>{{ printerType(detail.printer_type) }}</view>
|
||||
</view>
|
||||
<block v-if="detail.printer_type == 'cloud'">
|
||||
<view class="information">
|
||||
<view>品牌:</view>
|
||||
<view>{{ brandList[detail.brand] }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>打印机编号:</view>
|
||||
<view>{{ detail.printer_code }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>打印机秘钥:</view>
|
||||
<view>{{ detail.printer_key }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>应用id:</view>
|
||||
<view>{{ detail.open_id }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>apiKey:</view>
|
||||
<view>{{ detail.apikey }}</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="detail.printer_type == 'local'">
|
||||
<view class="information">
|
||||
<view>打印机端口:</view>
|
||||
<view>{{ detail.host }}</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="detail.printer_type == 'network'">
|
||||
<view class="information">
|
||||
<view>打印机地址:</view>
|
||||
<view>{{ detail.ip }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>打印机端口:</view>
|
||||
<view>{{ detail.host }}</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="information">
|
||||
<view>添加时间:</view>
|
||||
<view>{{ detail.create_time ? $util.timeFormat(detail.create_time) : '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="title">支付打印</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>支付打印:</view>
|
||||
<view>{{ detail.order_pay_open ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.order_pay_open">
|
||||
<view>打印模板:</view>
|
||||
<view>
|
||||
{{ template[detail.order_pay_template_id] ? template[detail.order_pay_template_id].template_name : '--' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.order_pay_open">
|
||||
<view>打印联数:</view>
|
||||
<view>{{ detail.order_pay_print_num }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.order_pay_open">
|
||||
<view>订单类型:</view>
|
||||
<view>
|
||||
<block v-for="(item, index) in detail.order_pay_order_type" :key="index">
|
||||
<text v-if="item" class="order-type">{{ detail['order_type_list'][item]['name'] }}</text>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="title">收货打印</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>收货打印:</view>
|
||||
<view>{{ detail.take_delivery_open ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.take_delivery_open">
|
||||
<view>打印模板:</view>
|
||||
<view>
|
||||
{{ template[detail.take_delivery_template_id] ? template[detail.take_delivery_template_id].template_name : '--' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.take_delivery_open">
|
||||
<view>打印联数:</view>
|
||||
<view>{{ detail.take_delivery_print_num }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.take_delivery_open">
|
||||
<view>订单类型:</view>
|
||||
<view>
|
||||
<block v-for="(item, index) in detail.take_delivery_order_type" :key="index">
|
||||
<text v-if="item" class="order-type">{{ detail['order_type_list'][item]['name'] }}</text>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="title">手动打印</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>手动打印:</view>
|
||||
<view>{{ detail.manual_open ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.manual_open">
|
||||
<view>打印模板:</view>
|
||||
<view>
|
||||
{{ template[detail.template_id] ? template[detail.template_id].template_name : '--' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.manual_open">
|
||||
<view>打印联数:</view>
|
||||
<view>{{ detail.print_num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="title">充值打印</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>充值打印:</view>
|
||||
<view>{{ detail.recharge_open ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.recharge_open">
|
||||
<view>打印模板:</view>
|
||||
<view>
|
||||
{{ template[detail.recharge_template_id] ? template[detail.recharge_template_id].template_name : '--' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.recharge_open">
|
||||
<view>打印联数:</view>
|
||||
<view>{{ detail.recharge_print_num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="title">收银交班打印</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>收银交班打印:</view>
|
||||
<view>{{ detail.change_shifts_open ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.change_shifts_open">
|
||||
<view>打印模板:</view>
|
||||
<view>
|
||||
{{ template[detail.change_shifts_template_id] ? template[detail.change_shifts_template_id].template_name : '--' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="information" v-if="detail.change_shifts_open">
|
||||
<view>打印联数:</view>
|
||||
<view>{{ detail.change_shifts_print_num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image class="cart-empty" src="@/static/cashier/cart_empty.png" mode="widthFix" />
|
||||
</block>
|
||||
</view>
|
||||
<view class="button-box" v-if="JSON.stringify(detail) != '{}'">
|
||||
<button class="default-btn" @click="$refs.deletePop.open()">删除</button>
|
||||
<button class="default-btn" @click="editprinter(detail.printer_id)">修改</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 删除 -->
|
||||
<uni-popup ref="deletePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.deletePop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deletePrinterFn(detail.printer_id)">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getPrinterList,
|
||||
getTemplate,
|
||||
getPrinterInfo,
|
||||
deletePrinter
|
||||
} from '@/api/printer.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectprinterKeys: 0,
|
||||
search_text: '',
|
||||
page: 1,
|
||||
// 每次返回数据数
|
||||
page_size: 8,
|
||||
// 第一次请求列表做详情渲染判断
|
||||
one_judge: true,
|
||||
//详情数据
|
||||
detail: {},
|
||||
brandList: {
|
||||
yilianyun: '易联云',
|
||||
'365': '365'
|
||||
},
|
||||
template: {},
|
||||
list: [],
|
||||
repeatFlag: false,
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化请求打印机列表数据
|
||||
this.getTemplateFn();
|
||||
},
|
||||
methods: {
|
||||
printerType(printerType) {
|
||||
var str = '';
|
||||
switch (printerType) {
|
||||
case 'cloud':
|
||||
str = '云打印机';
|
||||
break;
|
||||
case 'local':
|
||||
str = '本地打印机';
|
||||
break;
|
||||
case 'network':
|
||||
str = '网络打印机';
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
switchStoreAfter() {
|
||||
this.search()
|
||||
},
|
||||
printerSelect(item, keys) {
|
||||
this.selectprinterKeys = keys;
|
||||
this.getPrinterDetail(item.printer_id);
|
||||
},
|
||||
// 搜索员工
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.getPrinterListFn();
|
||||
},
|
||||
addprinter() {
|
||||
this.$util.redirectTo('/pages/printer/add');
|
||||
},
|
||||
editprinter(printer_id) {
|
||||
this.$util.redirectTo('/pages/printer/add', {
|
||||
printer_id: printer_id
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 请求的列表数据
|
||||
*/
|
||||
getPrinterListFn() {
|
||||
getPrinterList({
|
||||
page: this.page,
|
||||
page_size: this.page_size
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getPrinterDetail(this.list[0].printer_id);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getTemplateFn() {
|
||||
getTemplate().then(res => {
|
||||
if (res.code == 0) {
|
||||
let template = {};
|
||||
res.data.forEach(item => {
|
||||
template[item.template_id] = item;
|
||||
})
|
||||
this.template = template;
|
||||
this.getPrinterListFn();
|
||||
}
|
||||
})
|
||||
},
|
||||
getPrinterDetail(printer_id) {
|
||||
getPrinterInfo(printer_id).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.detail = res.data;
|
||||
this.one_judge = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
deletePrinterFn(printer_id) {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
deletePrinter(printer_id).then(res => {
|
||||
this.repeatFlag = false;
|
||||
if (res.code >= 0) {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.$refs.deletePop.close()
|
||||
this.getPrinterListFn();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/printer.scss';
|
||||
</style>
|
||||
280
addon/cashier/source/os/pages/printer/public/css/printer.scss
Executable file
280
addon/cashier/source/os/pages/printer/public/css/printer.scss
Executable file
@@ -0,0 +1,280 @@
|
||||
.printerlist {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
.printerlist-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
.printerlist-left {
|
||||
width: 5rem;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.notYet {
|
||||
color: #e6e6e6;
|
||||
font-size: 0.4rem;
|
||||
margin-top: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
.add-printer {
|
||||
padding: 0.24rem 0.2rem;
|
||||
background: #fff;
|
||||
|
||||
button {
|
||||
height: .4rem;
|
||||
line-height: .4rem;
|
||||
}
|
||||
}
|
||||
.printer-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.icongengduo1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.printer-list-wrap {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
.printer-list-scroll {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.itemhover {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
.item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
image {
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
.item-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 0.6rem;
|
||||
.printer-name {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
.printer-money {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.printerlist-right {
|
||||
width: 0;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.printer-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.icongengduo1,.iconguanbi1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.printer-information {
|
||||
width: 100%;
|
||||
padding: 0.2rem 0.2rem 0.88rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
height: calc(100% - 0.6rem);
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
.title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.32rem;
|
||||
}
|
||||
.title2 {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.information-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.box-left {
|
||||
width: 5rem;
|
||||
.information {
|
||||
width: 100%;
|
||||
padding-left: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
view:nth-child(1) {
|
||||
width: 1.3rem;
|
||||
margin-right: 0.16rem;
|
||||
text-align: right;
|
||||
}
|
||||
view:nth-child(2) {
|
||||
width: 74%;
|
||||
margin-right: 0.23rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.information:last-child {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
}
|
||||
.printer-img {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
}
|
||||
.table {
|
||||
width: 100%;
|
||||
height: 2.6rem;
|
||||
box-sizing: border-box;
|
||||
.table-all {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 0.38rem;
|
||||
box-sizing: border-box;
|
||||
.table-td {
|
||||
font-size: 0.14rem;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.table-th {
|
||||
height: 0.56rem;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
.table-tb {
|
||||
width: 100%;
|
||||
height: calc(100% - 0.56rem);
|
||||
.table-tr {
|
||||
height: 0.7rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
.table-td {
|
||||
image {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.printer-information::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
.printer-information::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.button-box {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 0.24rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
button {
|
||||
width: 1rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
margin: 0;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
.button-box:after {
|
||||
overflow: hidden;
|
||||
content: '';
|
||||
height: 0;
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
.order-type{
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
216
addon/cashier/source/os/pages/recharge/index.vue
Executable file
216
addon/cashier/source/os/pages/recharge/index.vue
Executable file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row page-height recharge-wrap">
|
||||
<view class="common-wrap left-wrap">
|
||||
<view class="cashregister-header-box">
|
||||
<view class="order-time">
|
||||
<view class="title">消费时间</view>
|
||||
<uni-datetime-picker v-model="create_time" type="datetime" :clearIcon="false" />
|
||||
</view>
|
||||
|
||||
<view class="header" v-if="globalMemberInfo">
|
||||
<view class="headimg">
|
||||
<image class="header-image" :src="globalMemberInfo.headimg ? $util.img(globalMemberInfo.headimg) : $util.img(defaultImg.head)" @error="globalMemberInfo.headimg = defaultImg.head"/>
|
||||
<view v-if="globalMemberInfo.member_level" class="member-nameplate">
|
||||
{{ globalMemberInfo.member_level_name }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="head-info">
|
||||
<view class="head-info-top">
|
||||
<view class="name">
|
||||
<block v-if="globalMemberInfo.mobile">
|
||||
<view class="mobile">{{ globalMemberInfo.mobile }}</view>
|
||||
<view class="text">
|
||||
<text>(</text>
|
||||
<text class="nickname">{{globalMemberInfo.nickname }}</text>
|
||||
<text>)</text>
|
||||
</view>
|
||||
</block>
|
||||
<text v-else>{{ globalMemberInfo.nickname }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="head-info-bottom point">积分:{{ globalMemberInfo.point }}</view>
|
||||
<view class="head-info-bottom balance">余额:{{ (parseFloat(globalMemberInfo.balance_money) + parseFloat(globalMemberInfo.balance)) | moneyFormat}}</view>
|
||||
</view>
|
||||
<button class="switch primary-btn member-open">更换会员</button>
|
||||
<button class="switch primary-btn replace-member">散客</button>
|
||||
</view>
|
||||
<view class="header" v-else>
|
||||
<view class="headimg">
|
||||
<image class="header-image" :src="$util.img(defaultImg.head)" />
|
||||
</view>
|
||||
<view class="head-info">
|
||||
<view class="name">散客</view>
|
||||
</view>
|
||||
<button class="switch primary-btn">查询会员</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="content-list common-scrollbar">
|
||||
<view class="empty">
|
||||
<image src="@/static/cashier/cart_empty.png" mode="widthFix"/>
|
||||
<view class="tips">点击右侧商品,选择商品进行结账</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom">
|
||||
<view class="bottom-info">
|
||||
<view class="bottom-left">共 0 件</view>
|
||||
<view class="bottom-right">
|
||||
<text class="pay-money">¥0.00</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom-btn">
|
||||
<button class="primary-btn btn-right">结账</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pay-shade"></view>
|
||||
</view>
|
||||
<view class="uni-flex uni-row common-wrap right-wrap">
|
||||
<scroll-view scroll-y="true" class="info-wrap" v-show="type == 'member'">
|
||||
<view class="header">会员充值</view>
|
||||
<view class="headimg-content" v-if="globalMemberInfo">
|
||||
<view class="headimg">
|
||||
<image v-if="globalMemberInfo.headimg" :src="globalMemberInfo.headimg ? $util.img(globalMemberInfo.headimg) : $util.img(defaultImg.head)"/>
|
||||
<image v-else mode="aspectFill" src="@/static/member/head.png" />
|
||||
</view>
|
||||
<view class="header-info" @click="showMember">
|
||||
<view class="name">
|
||||
<text>{{ globalMemberInfo.nickname }}</text>
|
||||
<text v-if="globalMemberInfo.member_level" class="level-name">{{ globalMemberInfo.member_level_name }}</text>
|
||||
<button type="default" @click.stop="openMember()" class="primary-btn">切换会员</button>
|
||||
</view>
|
||||
<view class="header-info-item">
|
||||
<view>手机号:{{ globalMemberInfo.mobile || '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="headimg-content" v-else>
|
||||
<view class="headimg">
|
||||
<image mode="aspectFill" src="@/static/member/head.png" />
|
||||
</view>
|
||||
<view class="header-info">
|
||||
<view class="name">
|
||||
<text>散客</text>
|
||||
<button type="default" @click="openMember()" class="primary-btn">登录会员</button>
|
||||
</view>
|
||||
<view class="header-info-item">
|
||||
<view>手机号:--</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-box">
|
||||
<view class="form-content">
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
充值方式:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<uni-data-checkbox v-model="rechargeType" :localdata="rechargeTypeList" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item" v-if="rechargeType == 2">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
充值金额:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<input type="number" class="form-input" v-model="rechargeMoney" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item" v-if="rechargeType == 1">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
充值金额:
|
||||
</view>
|
||||
<view class="form-inline ">
|
||||
<view class="label-list">
|
||||
<view class="form-label" :class="{ active: rechargeIndex == index }" @click="rechargeIndex = index" v-for="(item, index) in memberRecharge" :key="index">
|
||||
<view class="price">{{ item.buy_price }}元</view>
|
||||
<view class="balance">到账{{ item.face_value }}元</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item" v-if="reward">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
充值优惠:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<view class="content-box">
|
||||
<view class="content-gift" v-if="memberRecharge[rechargeIndex].growth">
|
||||
<text class="iconfont iconchengchangzhi"></text>
|
||||
<text>赠送{{ memberRecharge[rechargeIndex].growth }}成长值</text>
|
||||
</view>
|
||||
<view class="content-gift" v-if="memberRecharge[rechargeIndex].point">
|
||||
<text class="iconfont iconjifen"></text>
|
||||
<text>赠送{{ memberRecharge[rechargeIndex].point }}积分</text>
|
||||
</view>
|
||||
<view class="content-gift" v-if="memberRecharge[rechargeIndex].coupon_id">
|
||||
<text class="iconfont iconyouhuiquan1"></text>
|
||||
<text>赠送优惠券 X{{ memberRecharge[rechargeIndex].coupon_id.split(',').length }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="gift-remark" v-if="rechargeType == 1 && memberRecharge.length > 0 && memberRecharge[rechargeIndex] && memberRecharge[rechargeIndex].goods_data != undefined">
|
||||
备注:赠送的产品需线下提货,赠送的项目可在线下进行使用
|
||||
</view>
|
||||
|
||||
<view class="action-btn">
|
||||
<button type="primary" class="primary-btn" @click="pay()">充值</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="info-wrap" v-show="type == 'pay'">
|
||||
<ns-payment ref="payment" storeRoute="recharge" @cancel="cancelPayment" @success="paySuccess" :outTradeNo="outTradeNo"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<ns-select-member ref="selectMember"/>
|
||||
|
||||
<!-- 会员详情弹出框 -->
|
||||
<ns-member-detail-popup ref="memberDetailPopup" />
|
||||
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import recharge from './public/js/recharge.js';
|
||||
import nsSelectMember from '@/components/ns-select-member/ns-select-member.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
nsSelectMember
|
||||
},
|
||||
mixins: [recharge],
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.recharge-wrap .cashregister-header-box>>>.uni-select-lay-select {
|
||||
padding-right: 0.1rem !important;
|
||||
}
|
||||
|
||||
.recharge-wrap .cashregister-header-box>>>.uni-select-lay-icon {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.recharge-wrap .cashregister-header-box>>>.uni-select-lay-input-close {
|
||||
display: none !important;
|
||||
}
|
||||
.recharge-wrap >>> .member-head .iconfont {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/index.scss';
|
||||
</style>
|
||||
442
addon/cashier/source/os/pages/recharge/public/css/index.scss
Executable file
442
addon/cashier/source/os/pages/recharge/public/css/index.scss
Executable file
@@ -0,0 +1,442 @@
|
||||
.left-wrap {
|
||||
position: relative;
|
||||
max-width: 4rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 0.2rem;
|
||||
flex: 1;
|
||||
|
||||
.pay-shade {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba($color: #fff, $alpha: 0.6);
|
||||
z-index: 10;
|
||||
cursor: no-drop;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0.15rem;
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-size: 0.14rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.clear {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
&:nth-child(1) {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-left: 0.03rem;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-list {
|
||||
margin-top: 0.1rem;
|
||||
flex: 1;
|
||||
height: 0;
|
||||
overflow-y: scroll;
|
||||
|
||||
.content-item {
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
padding: 0.1rem 0;
|
||||
|
||||
.item-img {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.item-info {
|
||||
flex: 1;
|
||||
margin-left: 0.1rem;
|
||||
width: 0;
|
||||
min-width: 0;
|
||||
|
||||
.item-name {
|
||||
font-size: 0.14rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.del {
|
||||
margin-right: -0.8rem;
|
||||
margin-top: -0.2rem;
|
||||
color: $primary-color;
|
||||
font-size: 0.14rem;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.item-spe {
|
||||
font-size: 0.1rem;
|
||||
color: #999;
|
||||
margin-top: 0.05rem;
|
||||
}
|
||||
|
||||
.item-price {
|
||||
font-size: 0.14rem;
|
||||
margin-top: 0.05rem;
|
||||
margin-left: -0.03rem;
|
||||
}
|
||||
}
|
||||
|
||||
.item-num {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 0.1rem;
|
||||
margin-top: 0.3rem;
|
||||
|
||||
.num-dec {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
background: #e6e6e6;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 30%;
|
||||
text-align: center;
|
||||
line-height: 0.23rem;
|
||||
font-size: 0.25rem;
|
||||
margin-right: 0.1rem;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.num-inc {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
background: $primary-color;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 30%;
|
||||
text-align: center;
|
||||
line-height: 0.23rem;
|
||||
font-size: 0.25rem;
|
||||
margin-left: 0.1rem;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
|
||||
image {
|
||||
width: 60%;
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
width: 100%;
|
||||
padding:0.2rem 0.2rem 0.24rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
background-color: #ffffff;
|
||||
|
||||
.bottom-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.bottom-left {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
.bottom-right {
|
||||
font-size: 0.14rem;
|
||||
|
||||
.pay-money {
|
||||
font-size: 0.27rem;
|
||||
height: 0.22rem;
|
||||
font-weight: 600;
|
||||
font-family: AlibabaPuHuiTiM;
|
||||
color: $primary-color;
|
||||
line-height: 0.22rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.btn-right {
|
||||
width: 1.4rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
border: 0 !important;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.common-wrap {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.right-wrap {
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-radius: 0.02rem;
|
||||
height: 100%;
|
||||
border-left: 0;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
|
||||
.header {
|
||||
height: 0.66rem;
|
||||
line-height: 0.66rem;
|
||||
text-align: left;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
|
||||
.headimg-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.headimg {
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.header-info {
|
||||
margin-left: 0.15rem;
|
||||
flex: 1;
|
||||
|
||||
.name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.16rem;
|
||||
color: #303133;
|
||||
|
||||
.level-name {
|
||||
background: #ffffff;
|
||||
border: 0.01rem solid $primary-color;
|
||||
border-radius: 0.02rem;
|
||||
font-size: 0.12rem;
|
||||
color: $primary-color;
|
||||
margin-left: 0.15rem;
|
||||
min-width: 0.65rem;
|
||||
height: 0.22rem;
|
||||
text-align: center;
|
||||
line-height: 0.22rem;
|
||||
padding: 0 0.04rem;
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
padding: 0 0.1rem;
|
||||
width: 1rem;
|
||||
font-size: $uni-font-size-sm;
|
||||
margin: 0;
|
||||
height: 0.24rem;
|
||||
line-height: 0.24rem;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.header-info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 0.1rem;
|
||||
justify-content: space-between;
|
||||
|
||||
view {
|
||||
text-align: left;
|
||||
font-size: 0.14rem;
|
||||
color: #303133;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.form-box {
|
||||
.form-content {
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.gift-remark {
|
||||
margin-left: 1.3rem;
|
||||
color: #999;
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 0.1rem;
|
||||
display: flex;
|
||||
|
||||
.form-label {
|
||||
width: 1.3rem;
|
||||
text-align: right;
|
||||
padding-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
line-height: 0.32rem;
|
||||
margin-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.form-input {
|
||||
width: 2.3rem;
|
||||
border-width: 0.01rem;
|
||||
border-style: solid;
|
||||
background-color: #fff;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 0.02rem;
|
||||
padding-left: 0.1rem;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
font-size: 0.14rem;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
|
||||
button {
|
||||
display: inline-block;
|
||||
margin-right: 0.1rem;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.label-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.form-label {
|
||||
padding: 0.05rem 0.15rem;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
margin: 0 0.1rem 0.1rem 0;
|
||||
cursor: pointer;
|
||||
flex-direction: column;
|
||||
width: unset;
|
||||
height: unset;
|
||||
white-space: nowrap;
|
||||
|
||||
.balance {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 0.17rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-color: $primary-color;
|
||||
color: $primary-color;
|
||||
background-color: var(--primary-color-light-9);
|
||||
|
||||
.balance {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-gift {
|
||||
background-color: #f8f8f8;
|
||||
padding: 0.04rem 0.1rem;
|
||||
margin-bottom: 0.15rem;
|
||||
font-size: 0.13rem;
|
||||
|
||||
.iconfont {
|
||||
color: $primary-color;
|
||||
margin-right: 0.05rem;
|
||||
}
|
||||
|
||||
text {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0.24rem;
|
||||
|
||||
button {
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
239
addon/cashier/source/os/pages/recharge/public/js/recharge.js
Executable file
239
addon/cashier/source/os/pages/recharge/public/js/recharge.js
Executable file
@@ -0,0 +1,239 @@
|
||||
import {getRechargeConfig, addRecharge} from '@/api/recharge'
|
||||
import {getMemberInfoById} from '@/api/member'
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
type: 'member',
|
||||
//充值卡相关
|
||||
memberRecharge: [],
|
||||
rechargeMoney: 0,
|
||||
rechargeType: 1,
|
||||
rechargeIndex: 0,
|
||||
rechargeTypeList: [{
|
||||
text: '充值套餐',
|
||||
value: 1
|
||||
}, {
|
||||
text: '自定义金额',
|
||||
value: 2
|
||||
}],
|
||||
outTradeNo: '',
|
||||
isRepeat: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
reward() {
|
||||
if (this.rechargeType == 1 && this.memberRecharge.length > 0 && this.memberRecharge[this.rechargeIndex]) {
|
||||
let data = this.memberRecharge[this.rechargeIndex];
|
||||
if (data.point || data.growth || data.coupon) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
...mapGetters(['rechargeActive','memberSearchWayConfig'])
|
||||
},
|
||||
onLoad() {
|
||||
uni.hideTabBar();
|
||||
},
|
||||
onShow() {
|
||||
this.create_time = this.$util.timeFormat(parseInt(new Date().getTime() / 1000));
|
||||
this.addKeyDownEvent();
|
||||
|
||||
// 添加组件的键盘监听事件
|
||||
if (this.$refs.payment) this.$refs.payment.addKeyDownEvent();
|
||||
|
||||
this.getMemberRecharge();
|
||||
},
|
||||
onHide() {
|
||||
this.removeKeyDownEvent();
|
||||
|
||||
// 移除组件的键盘监听事件
|
||||
if (this.$refs.payment) this.$refs.payment.removeKeyDownEvent();
|
||||
},
|
||||
methods: {
|
||||
//充值卡相关
|
||||
getMemberRecharge() {
|
||||
getRechargeConfig().then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.memberRecharge = res.data;
|
||||
if (this.memberRecharge.length > 0) {
|
||||
for (let i in this.memberRecharge) this.memberRecharge[i]['money'] = this.memberRecharge[i]['price'];
|
||||
} else {
|
||||
this.rechargeType = 2;
|
||||
this.rechargeTypeList[0].disable = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getMemberInfo() {
|
||||
getMemberInfoById(this.globalMemberInfo.member_id).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.$store.commit('app/setGlobalMemberInfo', res.data);
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: '未获取到会员信息'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
openMember() {
|
||||
if (this.$refs.selectMember) {
|
||||
this.$store.commit('recharge/setActive', 'ShowMember');
|
||||
this.$refs.selectMember.open(() => {
|
||||
this.$store.commit('recharge/setActive', 'ShowMemberAfter');
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.$refs.selectMember.inputFocus = true;
|
||||
}, 200);
|
||||
}
|
||||
},
|
||||
showMember() {
|
||||
this.$store.commit('recharge/setActive', 'ShowMember');
|
||||
if (!this.globalMemberInfo) {
|
||||
if (this.$refs.selectMember) this.$refs.selectMember.open(() => {
|
||||
this.$store.commit('recharge/setActive', 'ShowMemberAfter');
|
||||
});
|
||||
} else {
|
||||
// 打开会员信息弹出框
|
||||
this.$store.commit('recharge/setActive', 'ShowMemberAfter');
|
||||
this.$refs.memberDetailPopup.open();
|
||||
}
|
||||
},
|
||||
pay() {
|
||||
if (!this.globalMemberInfo || (this.globalMemberInfo && !this.globalMemberInfo.member_id)) {
|
||||
this.type = 'member';
|
||||
this.openMember();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.rechargeType == 1 && !this.memberRecharge[this.rechargeIndex]) {
|
||||
this.$util.showToast({
|
||||
title: '请选择充值套餐'
|
||||
});
|
||||
return;
|
||||
}
|
||||
var isValid = /^-?\d+(\.\d{1,2})?$/;
|
||||
if (this.rechargeType == 2 && !isValid.test(this.rechargeMoney)) {
|
||||
this.$util.showToast({
|
||||
title: '请输入正确的充值金额'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let data = {
|
||||
member_id: this.globalMemberInfo.member_id
|
||||
};
|
||||
if (this.rechargeType == 1) {
|
||||
data.sku_array = [{
|
||||
recharge_id: this.memberRecharge[this.rechargeIndex].recharge_id
|
||||
}];
|
||||
} else {
|
||||
data.sku_array = [{
|
||||
money: this.rechargeMoney
|
||||
}];
|
||||
}
|
||||
data.sku_array = JSON.stringify(data.sku_array);
|
||||
|
||||
this.$store.commit('recharge/setActive', 'OrderCreate');
|
||||
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
addRecharge(data).then(res => {
|
||||
this.isRepeat = false;
|
||||
if (res.code == 0) {
|
||||
this.outTradeNo = res.data.out_trade_no;
|
||||
this.type = 'pay';
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
cancelPayment() {
|
||||
this.type = 'member';
|
||||
},
|
||||
paySuccess() {
|
||||
this.type = 'member';
|
||||
this.outTradeNo = '';
|
||||
this.getMemberInfo();
|
||||
|
||||
this.$store.commit('recharge/setActive', '');
|
||||
this.isRepeat = false;
|
||||
},
|
||||
/**
|
||||
* 添加键盘监听事件
|
||||
*/
|
||||
addKeyDownEvent() {
|
||||
// #ifdef H5
|
||||
// 绑定监听事件
|
||||
window.addEventListener("keydown", this.listenerKeyDown, true);
|
||||
|
||||
// 监听F1~F12,BACKSPACE
|
||||
window.POS_HOTKEY_CALLBACK = (control, code) => {
|
||||
this.posHotKeyCallback(code);
|
||||
};
|
||||
// #endif
|
||||
},
|
||||
/**
|
||||
* 移除键盘监听事件
|
||||
*/
|
||||
removeKeyDownEvent() {
|
||||
// #ifdef H5
|
||||
window.removeEventListener("keydown", this.listenerKeyDown, true);
|
||||
|
||||
delete window.POS_HOTKEY_CALLBACK;
|
||||
// #endif
|
||||
},
|
||||
listenerKeyDown(e) {
|
||||
var code = e.code;
|
||||
|
||||
// console.log('KeyDown', this.type, code, this.rechargeActive, e);
|
||||
|
||||
if (this.rechargeActive == '' && code == 'KeyM') {
|
||||
// 选择会员,键盘快捷键【M】
|
||||
|
||||
this.openMember();
|
||||
|
||||
} else if(this.rechargeActive == 'ShowMember' && this.memberSearchWayConfig.way == 'list'){
|
||||
|
||||
// 按照会员列表进行搜索
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
|
||||
if(this.$refs.selectMember.searchFinish && this.$refs.selectMember.memberId){
|
||||
this.$refs.selectMember.getMemberInfo(this.$refs.selectMember.memberId);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (this.rechargeActive == 'ShowMemberAfter' || (this.type == 'member' && this.rechargeActive == '')) {
|
||||
// 活跃窗口:设置会员后,选择充值金额
|
||||
|
||||
if (code == 'Enter' || code == 'NumpadEnter') {
|
||||
this.pay();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* 监听键盘事件回调
|
||||
* @param {Object} code
|
||||
*/
|
||||
posHotKeyCallback(code) {
|
||||
if (code == 'BACKSPACE') {
|
||||
// 退格键
|
||||
if (this.rechargeActive == 'OrderCreate') {
|
||||
if (this.$refs.payment) {
|
||||
if (this.$refs.payment.active == 'openMoneyPopup') {
|
||||
this.$refs.payment.deleteCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// 触发左侧菜单按键回调
|
||||
this.menuTriggerKeyCodeCallBack(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
182
addon/cashier/source/os/pages/refund/list.vue
Executable file
182
addon/cashier/source/os/pages/refund/list.vue
Executable file
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
退款记录
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
|
||||
<view class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input type="text" v-model="search_text" @input="search" placeholder="搜索退款编号/订单号/客户手机号" />
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="refund_list.length > 0">
|
||||
<scroll-view scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getRefundList">
|
||||
<view class="item" @click="getRefundDetail(item.refund_id, index)" v-for="(item, index) in refund_list" :key="index" :class="index == refundIndex ? 'itemhover' : ''">
|
||||
<view class="title">
|
||||
<view>退款编号:{{ item.refund_no }}</view>
|
||||
<view>{{ item.refund_status_name }}</view>
|
||||
</view>
|
||||
<view class="total-money-num">
|
||||
<view class="member-info">
|
||||
<view>客户:</view>
|
||||
<view v-if="item.member_id">{{ item.nickname }}</view>
|
||||
<view v-else>散客</view>
|
||||
</view>
|
||||
|
||||
<view class="box">
|
||||
<view>退款金额</view>
|
||||
<view>¥{{ item.refund_money }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="refund_list.length == 0">暂无数据</view>
|
||||
</view>
|
||||
<view class="goodslist-right">
|
||||
<view class="goods-title">退款详情</view>
|
||||
<block v-if="refund_detail">
|
||||
<view class="order-information">
|
||||
<view class="order-status">{{ refund_detail.refund_status_name }}</view>
|
||||
<view class="goods-info">
|
||||
<block v-for="(item, index) in refund_detail.item_list" :key="index">
|
||||
<view class="goods-item">
|
||||
<view class="image">
|
||||
<image :src="$util.img(item.img, { size: 'small' })" mode="widthFix" />
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="content-text">{{ item.name }}</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="price">
|
||||
<text class="title">退款金额:</text>
|
||||
¥{{ item.refund_pay_money }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="goods-info refund-info">
|
||||
<view class="info-item">
|
||||
<view class="title">退款类型</view>
|
||||
<view class="content">{{ refund_detail.refund_trade_type_name }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="title">退款编号</view>
|
||||
<view class="content">{{ refund_detail.refund_no }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="title">退款时间</view>
|
||||
<view class="content">{{ refund_detail.create_time | timeFormat }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="title">退款方式</view>
|
||||
<view class="content">{{ refund_detail.refund_transfer_type_name }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="title">退款说明</view>
|
||||
<view class="content">{{ refund_detail.refund_goods_remark }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="title">退款金额</view>
|
||||
<view class="content">¥{{ refund_detail.refund_pay_money }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="title">退还积分</view>
|
||||
<view class="content">{{ refund_detail.refund_point }}积分</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="title">退还余额</view>
|
||||
<view class="content">¥{{ (parseFloat(refund_detail.refund_balance_money) + parseFloat(refund_detail.refund_balance)) | moneyFormat }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image class="cart-empty" src="@/static/cashier/cart_empty.png" mode="widthFix" />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getOrderRefundLists, getOrderRefundDetail } from '@/api/order_refund.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
refundIndex: 0,
|
||||
// 订购日志所需列表数据
|
||||
list: [],
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 8,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
// 订单列表数据
|
||||
refund_list: [],
|
||||
//订单详情数据
|
||||
refund_detail: null
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.getRefundList();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.refund_list = [];
|
||||
this.getRefundList();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getRefundList() {
|
||||
getOrderRefundLists({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
search_text: this.search_text
|
||||
}).then(res=>{
|
||||
if (res.data.list.length == 0) {
|
||||
this.refund_detail = null;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
if (this.refund_list.length == 0) {
|
||||
this.refund_list = res.data.list;
|
||||
} else {
|
||||
this.refund_list = this.refund_list.concat(res.data.list);
|
||||
}
|
||||
//初始时加载一遍详情数据
|
||||
if (this.page == 1) {
|
||||
this.getRefundDetail(this.refund_list[0].refund_id);
|
||||
}
|
||||
this.page += 1;
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
getRefundDetail(refund_id, index = 0) {
|
||||
this.refundIndex = index;
|
||||
getOrderRefundDetail({refund_id}).then(res=>{
|
||||
if (res.code >= 0) {
|
||||
this.refund_detail = res.data;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/list.scss';
|
||||
</style>
|
||||
303
addon/cashier/source/os/pages/refund/public/css/list.scss
Executable file
303
addon/cashier/source/os/pages/refund/public/css/list.scss
Executable file
@@ -0,0 +1,303 @@
|
||||
.goodslist {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
|
||||
.goodslist-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
|
||||
.goodslist-left {
|
||||
width: 5rem;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.notYet {
|
||||
color: #e6e6e6;
|
||||
font-size: 0.4rem;
|
||||
margin-top: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.goods-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.icongengduo1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-search {
|
||||
width: 100%;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.search {
|
||||
width: 5.6rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 0.04rem;
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.iconfont {
|
||||
font-size: 0.16rem;
|
||||
color: #909399;
|
||||
margin-right: 0.11rem;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 80%;
|
||||
height: 60%;
|
||||
border: none;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-list-scroll {
|
||||
width: 100%;
|
||||
height: calc(100% - 1.2rem);
|
||||
|
||||
.itemhover {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 0.2rem;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.2rem;
|
||||
|
||||
view {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goodslist-right {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
padding-bottom: 0.8rem;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
|
||||
.order-information {
|
||||
width: 100%;
|
||||
height: calc(100% - 0.6rem);
|
||||
background: #f8f8f8;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
overflow: scroll;
|
||||
// position: relative;
|
||||
|
||||
.order-status {
|
||||
font-size: 0.24rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.24rem;
|
||||
}
|
||||
|
||||
.goods-info {
|
||||
background: #ffffff;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.goods-item {
|
||||
padding: 0.15rem 0;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
display: flex;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 0.2rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.iconyuan_checked {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 0.8rem;
|
||||
height: 0.8rem;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 0.15rem;
|
||||
|
||||
image {
|
||||
width: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
margin-right: 0.15rem;
|
||||
}
|
||||
|
||||
.price {
|
||||
text-align: right;
|
||||
font-weight: bolder;
|
||||
|
||||
.title {
|
||||
font-weight: normal;
|
||||
font-size: .12rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.num {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.refund-info {
|
||||
margin-top: .15rem;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
line-height: .3rem;
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
margin-left: .1rem;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.total-money-num {
|
||||
.member-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
float: left;
|
||||
-ms-flex-negative: 0;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
float: right;
|
||||
|
||||
view {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
view:nth-child(1) {
|
||||
// transform: translateY(-.01rem);
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
color: #fe2278;
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.total-money-num:after {
|
||||
overflow: hidden;
|
||||
content: '';
|
||||
height: 0;
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.order-information::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
.order-information::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
224
addon/cashier/source/os/pages/reserve/config.vue
Executable file
224
addon/cashier/source/os/pages/reserve/config.vue
Executable file
@@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="common-wrap common-form">
|
||||
<view class="common-title">预约设置</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">预约时间</label>
|
||||
<view class="form-block">
|
||||
<checkbox-group class="form-checkbox-group" @change="checkboxChange">
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="1" :checked="week.includes('1') || week.includes(1)" />
|
||||
周一
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="2" :checked="week.includes('2') || week.includes(2)" />
|
||||
周二
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="3" :checked="week.includes('3') || week.includes(3)" />
|
||||
周三
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="4" :checked="week.includes('4') || week.includes(4)" />
|
||||
周四
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="5" :checked="week.includes('5') || week.includes(5)" />
|
||||
周五
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="6" :checked="week.includes('6') || week.includes(6)" />
|
||||
周六
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="0" :checked="week.includes('0') || week.includes(0)" />
|
||||
周日
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label"></label>
|
||||
<view class="form-inline">
|
||||
<view class="form-input-inline">
|
||||
<picker mode="time" class="form-input" :value="time.start" @change="bindStartTimeChange">
|
||||
<view class="uni-input">{{ time.start }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<text class="form-mid">-</text>
|
||||
<view class="form-input-inline">
|
||||
<picker mode="time" class="form-input" :value="time.end" @change="bindEndTimeChange">
|
||||
<view class="uni-input">{{ time.end }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">预约时间间隔</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="radioChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="30" :checked="interval == 30" />
|
||||
30分钟
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="60" :checked="interval == 60" />
|
||||
1个小时
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="90" :checked="interval == 90" />
|
||||
90分钟
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="120" :checked="interval == 120" />
|
||||
2小时
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">预约提前</label>
|
||||
<view class="form-input-inline"><input type="number" v-model="advance" class="form-input" /></view>
|
||||
<text class="form-word-aux">小时</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">每时段可预约</label>
|
||||
<view class="form-input-inline"><input type="number" v-model="max" class="form-input" /></view>
|
||||
<text class="form-word-aux">人</text>
|
||||
</view>
|
||||
<view class="common-btn-wrap"><button type="default" class="screen-btn" @click="saveFn">保存</button></view>
|
||||
<ns-loading :layer-background="{ background: 'rgba(255,255,255,.8)' }" ref="loading"></ns-loading>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getReserveConfig,
|
||||
setReserveConfig
|
||||
} from '@/api/reserve'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
time: {
|
||||
start: '08:30',
|
||||
end: '23:30'
|
||||
},
|
||||
interval: 30,
|
||||
advance: '',
|
||||
max: '',
|
||||
week: [],
|
||||
flag: false
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {
|
||||
this.getData();
|
||||
uni.setLocale('zh-Hans');
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
getReserveConfig().then(res => {
|
||||
if (res.code >= 0) {
|
||||
({
|
||||
start: this.time.start,
|
||||
end: this.time.end,
|
||||
interval: this.interval,
|
||||
advance: this.advance,
|
||||
max: this.max,
|
||||
week: this.week
|
||||
} = res.data);
|
||||
this.time.start = this.timeFormat(this.time.start);
|
||||
this.time.end = this.timeFormat(this.time.end);
|
||||
this.$refs.loading.hide();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
bindStartTimeChange(e) {
|
||||
this.time.start = e.detail.value;
|
||||
},
|
||||
bindEndTimeChange(e) {
|
||||
this.time.end = e.detail.value;
|
||||
},
|
||||
radioChange(e) {
|
||||
this.interval = e.detail.value;
|
||||
},
|
||||
checkboxChange(e) {
|
||||
this.week = e.detail.value;
|
||||
},
|
||||
getSaveData() {
|
||||
let data = {};
|
||||
data.start = this.timeTurnTimeStamp(this.time.start);
|
||||
data.end = this.timeTurnTimeStamp(this.time.end);
|
||||
data.interval = this.interval;
|
||||
data.advance = this.advance;
|
||||
data.max = this.max;
|
||||
data.week = this.week.toString();
|
||||
return data;
|
||||
},
|
||||
saveFn() {
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
setReserveConfig(this.getSaveData()).then(res => {
|
||||
this.flag = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.$refs.loading.show();
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
},
|
||||
timeTurnTimeStamp(time) {
|
||||
let data = time.split(':');
|
||||
return data[0] * 3600 + data[1] * 60;
|
||||
},
|
||||
timeFormat(time) {
|
||||
let h = time / 3600;
|
||||
let i = (time % 3600) / 60;
|
||||
h = h < 10 ? '0' + h : h;
|
||||
i = i < 10 ? '0' + i : i;
|
||||
return h + ':' + i;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.common-wrap {
|
||||
position: relative;
|
||||
padding: 30rpx;
|
||||
height: calc(100vh - 51px);
|
||||
|
||||
.form-label {
|
||||
width: 1.5rem !important;
|
||||
}
|
||||
|
||||
.common-btn-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
margin-left: 0;
|
||||
text-align: center;
|
||||
height: 0.4rem;
|
||||
button {
|
||||
width: 100%;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
</style>
|
||||
468
addon/cashier/source/os/pages/reserve/index.vue
Executable file
468
addon/cashier/source/os/pages/reserve/index.vue
Executable file
@@ -0,0 +1,468 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row height-all">
|
||||
<view class="common-wrap uni-flex uni-column" style="-webkit-flex: 1;flex: 1;">
|
||||
<view class="common-tab-wrap" id="tab">
|
||||
<view class="tab-item" :class="{ 'active-bar': active == 0 }" @click="switchTab(0)">
|
||||
<text class="text">预约看板</text>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ 'active-bar': active == 1 }" @click="switchTab(1)">
|
||||
<text class="text">预约列表</text>
|
||||
</view>
|
||||
<view class="active" :style="activeStyle"></view>
|
||||
</view>
|
||||
|
||||
<swiper :interval="3000" :duration="300" :current="active" @change="swiperChange">
|
||||
<!-- 预约看板 -->
|
||||
<swiper-item>
|
||||
<view class="swiper-item common-scrollbar">
|
||||
<view class="uni-flex panel-head">
|
||||
<button type="default" class="primary-btn" @click="addYuyue()">添加预约</button>
|
||||
<view class="status uni-flex">
|
||||
<block v-for="(item, index) in status" :key="index">
|
||||
<view class="color" :class="item.state"></view>
|
||||
<view>{{ item.name }}</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="panel-body">
|
||||
<view class="head-time uni-flex">
|
||||
<view @click="prevWeek()" class="item">
|
||||
<view class="iconfont iconqianhou1"></view>
|
||||
</view>
|
||||
<view class="time-box">{{ weekDate.start }} - {{ weekDate.end }}</view>
|
||||
<view @click="nextWeek()" class="item">
|
||||
<view class="iconfont iconqianhou2"></view>
|
||||
</view>
|
||||
<!-- <view class="head-time-switch">
|
||||
<view :class="yuYueDateType == 'week' ? 'active' : ''" @click="yuYueDateType = 'week'">周</view>
|
||||
<view :class="yuYueDateType == 'month' ? 'active' : ''" @click="yuYueDateType = 'month'">月</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<block v-if="yuYueDateType == 'week'">
|
||||
<view class="head uni-flex">
|
||||
<view v-for="(item, index) in weeks" class="item" :key="index">
|
||||
<button type="default" class="default-btn" :class="{ active: item.currday }">
|
||||
{{ item.week }}
|
||||
<text>{{ item.date }}</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="body uni-flex">
|
||||
<scroll-view scroll-y="true" @scrolltolower="getReserve(index)" class="common-scrollbar item" v-for="(item, index) in weeks" :key="index">
|
||||
<block v-if="item.data">
|
||||
<view class="panel-item" :class="reserve_item.reserve_state" v-for="(reserve_item, reserve_index) in item.data.list" :key="reserve_index">
|
||||
<view class="username">{{ reserve_item.nickname }}</view>
|
||||
<view class="time" :class="reserve_item.reserve_state">{{ $util.timeFormat(reserve_item.reserve_time, 'm-d H:i') }}</view>
|
||||
<view class="service" v-for="(server_item, server_index) in reserve_item.item" :key="server_index" @click="yuyueEvent('info', reserve_item)">{{ server_item.goods_name }}</view>
|
||||
<uni-dropdown>
|
||||
<view class="action" slot="dropdown-link">
|
||||
<text class="iconfont icongengduo"></text>
|
||||
</view>
|
||||
<view slot="dropdown">
|
||||
<view class="dropdown-menu">
|
||||
<view class="menu-item" @click="yuyueEvent('info', reserve_item)">详情</view>
|
||||
<view class="menu-item" v-for="(menu_item, menu_index) in operation[reserve_item.reserve_state]" :key="menu_index" @click="yuyueEvent(menu_item.event, reserve_item)">
|
||||
{{ menu_item.title }}
|
||||
</view>
|
||||
<view class="arrow"></view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-dropdown>
|
||||
</view>
|
||||
<view style="height: 1.5rem;"></view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="yuYueDateType == 'month'">
|
||||
<view class="head uni-flex">
|
||||
<view v-for="(item, index) in week" class="item" :key="index">
|
||||
<button type="default" class="default-btn">{{ item }}</button>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<!-- 预约列表 -->
|
||||
<swiper-item>
|
||||
<view class="yuyuelist">
|
||||
<view class="yuyuelist-box">
|
||||
<view class="yuyuelist-left">
|
||||
<view class="yuyue-title">预约客户</view>
|
||||
<view class="yuyue-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo" @click="searchYuyueList()"></text>
|
||||
<input type="text" v-model="yuyueSearchText" placeholder="请输入会员手机号" />
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view @scrolltolower="getYuyueList()" scroll-y="true" class="yuyue-list-scroll all-scroll">
|
||||
<view class="item" v-for="(item, index) in yuyueList" :key="index" @click="selectYuyue(item.reserve_id)" :class="{ active: item.reserve_id == reserveId }">
|
||||
<view class="item-head">
|
||||
<image mode="aspectFill" v-if="item.headimg" :src="$util.img(item.headimg)" @error="item.headimg = defaultImg.head"/>
|
||||
<image mode="aspectFill" v-else :src="$util.img(defaultImg.head)"/>
|
||||
<view class="item-right">
|
||||
<view class="yuyue-name" v-if="item.nickname">{{ item.nickname }}</view>
|
||||
<view class="yuyue-desc">{{ item.mobile }}</view>
|
||||
</view>
|
||||
<text>{{ item.reserve_state_name }}</text>
|
||||
</view>
|
||||
<view class="item-common">预约时间:{{ $util.timeFormat(item.create_time) }}
|
||||
</view>
|
||||
<view class="item-common yuyue-project">
|
||||
预约项目:
|
||||
<block v-for="(sItem, sIndex) in item.item" :key="sIndex">
|
||||
{{ sItem.goods_name }}{{ sIndex != item.item.length - 1 ? ';' : '' }}
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="yuyueList.length == 0" class="empty">
|
||||
<image src="@/static/member/member-empty.png" mode="widthFix"/>
|
||||
<view class="tips">暂无预约客户</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="yuyuelist-right" v-if="yuyueInfo">
|
||||
<view class="yuyue-title">预约详情</view>
|
||||
<view class="yuyue-information common-scrollbar">
|
||||
<view class="title">预约信息</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>预约客户:</view>
|
||||
<view>{{ yuyueInfo.nickname }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>客户手机号:</view>
|
||||
<view>{{ yuyueInfo.mobile }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>预约门店:</view>
|
||||
<view>{{ yuyueInfo.store_name }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>预约状态:</view>
|
||||
<view>{{ yuyueInfo.reserve_state_name }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>预约到店时间:</view>
|
||||
<view>{{ $util.timeFormat(yuyueInfo.reserve_time, 'Y-m-d H:i') }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>预约时间:</view>
|
||||
<view>{{ $util.timeFormat(yuyueInfo.create_time) }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>备注:</view>
|
||||
<view>{{ yuyueInfo.desc ? yuyueInfo.desc : '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="title title2">预约内容</view>
|
||||
<view class="table" v-if="yuyueInfo">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:50%">项目</view>
|
||||
<view class="table-td" style="width:50%">员工</view>
|
||||
</view>
|
||||
<scroll-view class="table-tb" scroll-y="true">
|
||||
<view class="table-tr table-all" v-for="(item, index) in yuyueInfo.item" :key="index">
|
||||
<view class="table-td" style="width:50%">{{ item.goods_name }}
|
||||
</view>
|
||||
<view class="table-td" style="width:50%">
|
||||
{{ item.uid ? item.username : '--' }}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="button-box flex items-center justify-end" v-if="yuyueInfo && operation[yuyueInfo.reserve_state]">
|
||||
<button class="default-btn" v-for="(menu_item, menu_index) in operation[yuyueInfo.reserve_state]" :key="menu_index" @click="yuyueEvent(menu_item.event, yuyueInfo)">{{ menu_item.title }}</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="yuyuelist-right empty" v-else>
|
||||
<image src="@/static/cashier/cart_empty.png" mode="widthFix"/>
|
||||
<view class="tips">暂无预约信息</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 添加/修改预约 -->
|
||||
<uni-popup ref="addYuyuePop" :maskClick="false">
|
||||
<view class="pop-box">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">{{ yuYueData.reserve_id ? '修改' : '添加' }}预约</view>
|
||||
<view class="pop-header-close" @click="closeYuyuePop">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y="true" class="common-scrollbar pop-content">
|
||||
<view class="form-content">
|
||||
<view class="form-item" v-if="!yuYueData.reserve_id">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
手机号:
|
||||
</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<input type="number" class="form-input" v-model="searchMobile" placeholder="请输入客户手机号" />
|
||||
<text class="iconfont icon31sousuo" @click="searchMember"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
客户:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<view class="member-info" v-if="yuYueData.member_id">
|
||||
<image :src="$util.img(yuYueData.member.headimg, { size: 'small' })" mode="widthFix" />
|
||||
<view class="info">
|
||||
<view class="name">{{ yuYueData.member.nickname }}</view>
|
||||
<view>
|
||||
<text>手机号:{{ yuYueData.member.mobile }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
到店时间:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<uni-datetime-picker :start="toDay" v-model="yuYueData.date" type="date" :clearIcon="false" @change="changeYuyueTime" />
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<select-lay :zindex="10" :value="yuYueData.time" name="names" placeholder="请选择到店时间" :options="yuYueTime" @selectitem="selectYuYueTime"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
预约门店:
|
||||
</view>
|
||||
<view class="form-inline">{{ globalStoreInfo.store_name }}</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
项目:
|
||||
</view>
|
||||
<view>
|
||||
<view class="table">
|
||||
<view class="table-tr table-head">
|
||||
<view class="table-th">预约项目</view>
|
||||
<view class="table-th">员工</view>
|
||||
<view class="table-th">操作</view>
|
||||
</view>
|
||||
|
||||
<view class="table-content table-tr" v-for="(goods_item, goods_index) in yuYueData.goods" :key="goods_index">
|
||||
<view class="table-td">
|
||||
<uni-dropdown>
|
||||
<view class="action" slot="dropdown-link">
|
||||
<view class="service-item">
|
||||
<view class="info" v-if="goods_item.goods_id">
|
||||
<view class="title">{{ goods_item.goods_name }}</view>
|
||||
<view class="desc">项目时长:{{ goods_item.service_length }}分钟 ¥{{ goods_item.price }}</view>
|
||||
</view>
|
||||
<view class="info" v-else>请选择项目</view>
|
||||
<text class="iconfont iconsanjiao_xia"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view slot="dropdown">
|
||||
<view class="dropdown-content-box">
|
||||
<view class="select-service">
|
||||
<div class="service-wrap">
|
||||
<div class="flex-wrap">
|
||||
<div class="item" v-for="(item, index) in goodsList" :key="index" @click="selectGoods(item, goods_index)">
|
||||
<div class="title">{{ item.goods_name }}</div>
|
||||
<div class="desc">项目时长:{{ item.service_length }}分钟 ¥{{ item.price }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</view>
|
||||
<view class="arrow"></view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-dropdown>
|
||||
</view>
|
||||
<view class="table-td">
|
||||
<uni-dropdown>
|
||||
<view class="action" slot="dropdown-link">
|
||||
<view class="service-item" @click="loadServicer(goods_index)">
|
||||
<view class="info">
|
||||
<view class="title" v-if="goods_item.uid && goods_item.uid > 0">
|
||||
{{ goods_item.username }}
|
||||
</view>
|
||||
<view class="title" v-else>不选择员工</view>
|
||||
</view>
|
||||
<text class="iconfont iconsanjiao_xia"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view slot="dropdown">
|
||||
<view class="dropdown-content-box">
|
||||
<div class="select-servicer">
|
||||
<div class="select-item">
|
||||
<div class="title" @click="selectServicer({ uid: 0, username: '' }, goods_index)">不选择员工</div>
|
||||
</div>
|
||||
<div class="select-item" v-for="(item, index) in servicerList" :key="index" @click="selectServicer(item, goods_index)">
|
||||
<div class="title">{{ item.username }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<view class="arrow"></view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-dropdown>
|
||||
</view>
|
||||
<view class="table-td">
|
||||
<view class="action-btn" @click="deleteService(goods_index)">删除</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<button class="primary-btn select-btn" @click="addService">添加项目</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
备注:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<textarea class="form-textarea" v-model="yuYueData.desc"></textarea>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="pop-bottom">
|
||||
<button class="primary-btn" @click="yuYueSubmit">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<!-- 预约详情 -->
|
||||
<uni-popup ref="yuyuePop">
|
||||
<view class="pop-box yuyue-info">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">预约详情</view>
|
||||
<view class="pop-header-close" @click="$refs.yuyuePop.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="common-scrollbar pop-content">
|
||||
<view class="yuyue-pop form-content" v-if="yuYueDetail">
|
||||
<view class="form-item">
|
||||
<view class="form-label">预约客户:</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<text>{{ yuYueDetail.member.nickname }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">客户手机号:</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<text>{{ yuYueDetail.member.mobile }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">预约门店:</view>
|
||||
<view class="form-inline search-wrap">{{ yuYueDetail.store_name }}</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">预约状态:</view>
|
||||
<view class="form-inline search-wrap">{{ yuYueDetail.reserve_state_name }}</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">预约到店时间:</view>
|
||||
<view class="form-inline search-wrap">
|
||||
{{ $util.timeFormat(yuYueDetail.reserve_time, 'Y-m-d H:i') }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">创建时间:</view>
|
||||
<view class="form-inline search-wrap">
|
||||
{{ $util.timeFormat(yuYueDetail.create_time, 'Y-m-d H:i:s') }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">预约项目:</view>
|
||||
<scroll-view scroll-y="true" class="form-inline search-wrap make-server">
|
||||
<view class="table-container">
|
||||
<view class="thead">
|
||||
<view class="th">
|
||||
<view class="content">项目</view>
|
||||
<view class="content">员工</view>
|
||||
<view class="content">时长</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tbody">
|
||||
<view class="tr" v-for="(item, index) in yuYueDetail.item" :key="index">
|
||||
<view class="td">
|
||||
<view class="content">{{ item.goods_name }}</view>
|
||||
<view class="content">{{ item.username ? item.username : '--' }}</view>
|
||||
<view class="content">{{ item.service_length }}分钟</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">备注:</view>
|
||||
<view class="form-inline search-wrap">{{ yuYueDetail.remark ? yuYueDetail.remark : '--' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="pop-bottom"><button class="primary-btn" @click="$refs.yuyuePop.close()">确定</button></view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<ns-loading :layer-background="{ background: 'rgba(255,255,255,.6)' }" :default-show="false" ref="loading"></ns-loading>
|
||||
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<ns-update></ns-update>
|
||||
<!-- #endif -->
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniDatetimePicker from '@/components/uni-datetime-picker/uni-datetime-picker.vue';
|
||||
import selectLay from '@/components/select-lay/select-lay.vue';
|
||||
import index from './public/js/index.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
uniDatetimePicker,
|
||||
selectLay
|
||||
},
|
||||
mixins: [index]
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.table-content>>>.tr .td .content.action {
|
||||
overflow: unset;
|
||||
}
|
||||
|
||||
.form-inline>>>.uni-icons {
|
||||
height: 0.3rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/index.scss';
|
||||
</style>
|
||||
1224
addon/cashier/source/os/pages/reserve/public/css/index.scss
Executable file
1224
addon/cashier/source/os/pages/reserve/public/css/index.scss
Executable file
File diff suppressed because it is too large
Load Diff
603
addon/cashier/source/os/pages/reserve/public/js/index.js
Executable file
603
addon/cashier/source/os/pages/reserve/public/js/index.js
Executable file
@@ -0,0 +1,603 @@
|
||||
import {
|
||||
getReserveStatus,
|
||||
getReserveConfig,
|
||||
getReserveWeekday,
|
||||
getReserveLists,
|
||||
getAppointmentProjectList,
|
||||
getEmployeeList,
|
||||
editReserve,
|
||||
addReserve,
|
||||
cancelReserve,
|
||||
getReserveDetail,
|
||||
reserveToStore,
|
||||
reserveConfirm,
|
||||
reserveComplete
|
||||
} from '@/api/reserve'
|
||||
import {
|
||||
getMemberInfoBySearchMember
|
||||
} from '@/api/member'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeStyle: {},
|
||||
active: 0,
|
||||
weeks: [],
|
||||
status: [],
|
||||
length: 0, //周
|
||||
//预约记录操作
|
||||
operation: {
|
||||
arrived_store: [{
|
||||
title: '确认完成',
|
||||
event: 'complet'
|
||||
}],
|
||||
wait_confirm: [{
|
||||
title: '确认预约',
|
||||
event: 'confirm'
|
||||
}, {
|
||||
title: '更改预约',
|
||||
event: 'update'
|
||||
}, {
|
||||
title: '取消预约',
|
||||
event: 'cancel'
|
||||
}],
|
||||
wait_to_store: [{
|
||||
title: '确认到店',
|
||||
event: 'tostore'
|
||||
}, {
|
||||
title: '取消预约',
|
||||
event: 'cancel'
|
||||
}]
|
||||
},
|
||||
yuYueTime: [], //预约时间段
|
||||
yuYueConfig: {},
|
||||
yuYueData: {
|
||||
time: '', //时间
|
||||
date: '', //日期
|
||||
member_id: '',
|
||||
member: {},
|
||||
goods: [],
|
||||
desc: '',
|
||||
reserve_id: 0
|
||||
},
|
||||
searchMobile: '',
|
||||
flag: false,
|
||||
yuYueDetail: null,
|
||||
weekDate: {
|
||||
start: '-',
|
||||
end: '-'
|
||||
},
|
||||
week: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
current: '',
|
||||
yuYueDateType: 'week',
|
||||
goodsList: [],
|
||||
allServicerList: [], //所有的员工
|
||||
servicerList: [], //所有的员工
|
||||
yuyueList: [],
|
||||
yuyuePage: 1,
|
||||
yuyueSearchText: '',
|
||||
reserveId: 0,
|
||||
yuyueInfo: null,
|
||||
toDay: '', // 今天日期
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
uni.hideTabBar();
|
||||
this.init();
|
||||
},
|
||||
onReady() {
|
||||
this.tabActive('tab');
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.weeks = [];
|
||||
this.getReserveStatusFn(); // 预约状态
|
||||
this.getReserveConfigFn(); // 预约配置
|
||||
this.getAppointmentProjectListFn(); // 预约项目列表
|
||||
this.getEmployeeListFn(); // 员工列表
|
||||
this.getWeekReserve(); // 预约看板/周
|
||||
this.getYuyueList(); // 预约记录列表
|
||||
let date = new Date();
|
||||
var y = date.getFullYear();
|
||||
var m = date.getMonth() + 1;
|
||||
var d = date.getDate();
|
||||
this.toDay = y + '-' + m + '-' + d;
|
||||
},
|
||||
tabActive(id) {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
var tab;
|
||||
query.select('#' + id).boundingClientRect(data => {
|
||||
tab = data;
|
||||
});
|
||||
query.select('#' + id + ' .active-bar .text').boundingClientRect(data => {
|
||||
this.activeStyle = {
|
||||
width: data.width + 'px',
|
||||
transform: 'translateX(' + (data.left - tab.left) + 'px)'
|
||||
};
|
||||
}).exec();
|
||||
},
|
||||
switchTab(value) {
|
||||
this.active = value;
|
||||
this.$nextTick(() => {
|
||||
this.tabActive('tab');
|
||||
});
|
||||
},
|
||||
swiperChange(e) {
|
||||
this.active = e.detail.current;
|
||||
this.$nextTick(() => {
|
||||
this.tabActive('tab');
|
||||
});
|
||||
},
|
||||
// 预约状态
|
||||
getReserveStatusFn() {
|
||||
getReserveStatus().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.status = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 预约配置
|
||||
getReserveConfigFn() {
|
||||
getReserveConfig().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.yuYueConfig = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// ******************** 预约看板 ********************
|
||||
|
||||
// 查询预约记录(每周)
|
||||
getWeekReserve() {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
getReserveWeekday({
|
||||
length: this.length
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.weeks = res.data;
|
||||
this.$refs.loading.hide();
|
||||
this.weekDate.start = this.$util.timeFormat(this.weeks[0].start, 'Y-m-d');
|
||||
this.weekDate.end = this.$util.timeFormat(this.weeks[this.weeks.length - 1].end, 'Y-m-d');
|
||||
for (let i in this.weeks) {
|
||||
this.getReserve(i);
|
||||
if (i == this.weeks.length - 1) {
|
||||
setTimeout(() => {
|
||||
this.flag = false;
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.flag = false;
|
||||
});
|
||||
},
|
||||
//获取预约分页数据
|
||||
getReserve(index) {
|
||||
let currentWeek = this.weeks[index];
|
||||
if (!currentWeek.page) currentWeek.page = 1;
|
||||
getReserveLists({
|
||||
page: currentWeek.page,
|
||||
start: currentWeek.start,
|
||||
end: currentWeek.end
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
let data = res.data;
|
||||
if (currentWeek.page == 1) {
|
||||
currentWeek.data = {
|
||||
list: [],
|
||||
page_count: data.page_count,
|
||||
count: data.count
|
||||
};
|
||||
currentWeek.data['list'] = data.list;
|
||||
} else {
|
||||
currentWeek.data['list'] = currentWeek.data['list'].concat(data.list);
|
||||
}
|
||||
if (data.page_count >= currentWeek.page) currentWeek.page++;
|
||||
this.$forceUpdate();
|
||||
}
|
||||
});
|
||||
},
|
||||
//上一周
|
||||
prevWeek() {
|
||||
this.$refs.loading.show();
|
||||
--this.length;
|
||||
this.getWeekReserve();
|
||||
},
|
||||
//下一周
|
||||
nextWeek() {
|
||||
this.$refs.loading.show();
|
||||
++this.length;
|
||||
this.getWeekReserve();
|
||||
},
|
||||
// ******************** 添加/编辑预约 ********************
|
||||
// 查询预约项目列表
|
||||
getAppointmentProjectListFn() {
|
||||
getAppointmentProjectList({
|
||||
page: 1,
|
||||
page_size: 0
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.goodsList = res.data.list;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 查询员工列表
|
||||
getEmployeeListFn() {
|
||||
getEmployeeList().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.allServicerList = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
//添加预约
|
||||
addYuyue() {
|
||||
this.yuYueData = {
|
||||
reserve_id: 0,
|
||||
member_id: '',
|
||||
member: {},
|
||||
time: '', //时间
|
||||
date: this.toDay, //日期
|
||||
goods: [{}],
|
||||
desc: '',
|
||||
};
|
||||
this.reserveId = 0;
|
||||
this.handleYuyueDate();
|
||||
this.$refs.addYuyuePop.open();
|
||||
},
|
||||
closeYuyuePop() {
|
||||
this.yuYueData = {
|
||||
time: '', //时间
|
||||
date: '', //日期
|
||||
member_id: '',
|
||||
member: {},
|
||||
goods: [{}],
|
||||
desc: '',
|
||||
reserve_id: 0
|
||||
};
|
||||
this.$refs.addYuyuePop.close();
|
||||
},
|
||||
// 查询会员信息
|
||||
searchMember() {
|
||||
if (this.searchMobile.length == 0) {
|
||||
this.$util.showToast({
|
||||
title: '请输入客户手机号'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!this.$util.verifyMobile(this.searchMobile)) {
|
||||
this.$util.showToast({
|
||||
title: '手机号格式不正确'
|
||||
});
|
||||
return;
|
||||
}
|
||||
getMemberInfoBySearchMember({
|
||||
search_text: this.searchMobile
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
this.yuYueData.member_id = res.data.member_id;
|
||||
this.yuYueData.member = res.data;
|
||||
} else {
|
||||
this.yuYueData.member_id = '';
|
||||
this.yuYueData.member = {};
|
||||
this.$util.showToast({
|
||||
title: '客户未找到'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
//处理预约时间段
|
||||
handleYuyueDate() {
|
||||
let time_list = [];
|
||||
let start = this.yuYueConfig.start / 60;
|
||||
let end = this.yuYueConfig.end / 60;
|
||||
let date = new Date();
|
||||
var y = date.getFullYear();
|
||||
var m = date.getMonth() + 1;
|
||||
var d = date.getDate();
|
||||
let time = date.getHours() * 60 + date.getMinutes();
|
||||
|
||||
let yuyue_time_stamp = this.$util.timeTurnTimeStamp(this.yuYueData.date);
|
||||
let time_stamp = this.$util.timeTurnTimeStamp(y + '-' + m + '-' + d);
|
||||
// if(time > start) start = time;
|
||||
|
||||
for (let i = start; i < end; i++) {
|
||||
if (i % this.yuYueConfig.interval == 0) {
|
||||
let data = {
|
||||
label: (Math.floor(i / 60) < 10 ? '0' + Math.floor(i / 60) : Math.floor(i / 60)) + ':' + (i % 60 == '0' ? '00' : i % 60),
|
||||
value: (Math.floor(i / 60) < 10 ? '0' + Math.floor(i / 60) : Math.floor(i / 60)) + ':' + (i % 60 == '0' ? '00' : i % 60),
|
||||
disabled: false
|
||||
};
|
||||
if (yuyue_time_stamp < time_stamp) data.disabled = true;
|
||||
if (yuyue_time_stamp == time_stamp && time > i) data.disabled = true;
|
||||
|
||||
let week = new Date(this.yuYueData.date).getDay();
|
||||
|
||||
let yuyue_week = this.yuYueConfig.week;
|
||||
let config_week = [];
|
||||
|
||||
for (let i in yuyue_week) config_week.push(parseInt(yuyue_week[i]));
|
||||
|
||||
if (config_week.indexOf(week) === -1) data.disabled = true;
|
||||
time_list.push(data);
|
||||
}
|
||||
}
|
||||
this.yuYueTime = time_list;
|
||||
},
|
||||
// 监听预约时间
|
||||
changeYuyueTime(time) {
|
||||
this.yuYueData.date = time;
|
||||
this.handleYuyueDate();
|
||||
},
|
||||
// 选择预约时间·
|
||||
selectYuYueTime(index, item) {
|
||||
if (index >= 0) {
|
||||
this.yuYueData.time = item.value;
|
||||
} else {
|
||||
this.yuYueData.time = '';
|
||||
}
|
||||
},
|
||||
// 设置项目
|
||||
selectGoods(data, index) {
|
||||
this.yuYueData.goods[index] = Object.assign(this.yuYueData.goods[index], JSON.parse(JSON.stringify(data)));
|
||||
this.$forceUpdate();
|
||||
},
|
||||
// 加载员工列表
|
||||
loadServicer(index) {
|
||||
this.servicerList = this.allServicerList;
|
||||
},
|
||||
// 设置员工
|
||||
selectServicer(data, index) {
|
||||
this.yuYueData.goods[index].uid = data.uid;
|
||||
this.yuYueData.goods[index].username = data.username;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
// 添加项目
|
||||
addService() {
|
||||
this.yuYueData.goods.push({});
|
||||
},
|
||||
// 删除项目
|
||||
deleteService(index) {
|
||||
if (this.yuYueData.goods.length == 1) {
|
||||
this.$util.showToast({
|
||||
title: '至少需要有一项项目'
|
||||
});
|
||||
} else {
|
||||
this.yuYueData.goods.splice(index, 1);
|
||||
}
|
||||
},
|
||||
// 预约验证
|
||||
verify() {
|
||||
if (!this.yuYueData.member_id) {
|
||||
this.$util.showToast({
|
||||
title: '请选择会员'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.yuYueData.date || !this.yuYueData.time) {
|
||||
this.$util.showToast({
|
||||
title: '请设置到店时间'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.yuYueData.goods.length) {
|
||||
this.$util.showToast({
|
||||
title: '请选择预约项目'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i in this.yuYueData.goods) {
|
||||
if (!this.yuYueData.goods[i]['goods_id']) {
|
||||
this.$util.showToast({
|
||||
title: '请选择预约项目'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
// 添加/编辑预约
|
||||
yuYueSubmit() {
|
||||
if (this.verify()) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
let data = Object.assign({}, this.yuYueData);
|
||||
data.goods = JSON.stringify(data.goods);
|
||||
data.member = JSON.stringify(data.member);
|
||||
let save = data.reserve_id ? editReserve : addReserve;
|
||||
save(data).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
this.flag = false;
|
||||
if (res.code >= 0) {
|
||||
this.getWeekReserve();
|
||||
if (this.reserveId) this.getYuyueInfo();
|
||||
this.closeYuyuePop();
|
||||
|
||||
this.yuyuePage = 1;
|
||||
this.getYuyueList();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
//操作
|
||||
yuyueEvent(event, data) {
|
||||
this.reserveId = data.reserve_id;
|
||||
switch (event) {
|
||||
case 'info':
|
||||
this.getYuYueDetail(data.reserve_id);
|
||||
break;
|
||||
case 'tostore':
|
||||
this.tostore(data.reserve_id);
|
||||
break;
|
||||
case 'cancel':
|
||||
this.cancel(data.reserve_id);
|
||||
break;
|
||||
case 'confirm':
|
||||
this.confirm(data.reserve_id);
|
||||
break;
|
||||
case 'update': // 修改预约
|
||||
this.$refs.loading.show();
|
||||
this.yuYueInfo(data.reserve_id);
|
||||
break;
|
||||
case 'complet':
|
||||
this.complet(data.reserve_id);
|
||||
break;
|
||||
}
|
||||
},
|
||||
//修改预约
|
||||
yuYueInfo(reserve_id) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
getReserveDetail(reserve_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.yuYueData = {
|
||||
reserve_id: res.data.reserve_id,
|
||||
member_id: res.data.member_id,
|
||||
member: res.data.member,
|
||||
time: this.$util.timeFormat(res.data.reserve_time, 'H:i'),
|
||||
date: this.$util.timeFormat(res.data.reserve_time, 'Y-m-d'),
|
||||
goods: res.data.item,
|
||||
desc: res.data.remark
|
||||
};
|
||||
|
||||
this.handleYuyueDate();
|
||||
this.$refs.addYuyuePop.open();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
this.flag = false;
|
||||
this.$refs.loading.hide();
|
||||
});
|
||||
},
|
||||
// 预约详情
|
||||
getYuYueDetail(reserve_id) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
getReserveDetail(reserve_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.yuYueDetail = res.data;
|
||||
this.$refs.yuyuePop.open();
|
||||
}
|
||||
this.flag = false;
|
||||
});
|
||||
},
|
||||
//预约确认
|
||||
confirm(reserve_id) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
reserveConfirm(reserve_id).then(res => {
|
||||
this.flag = false;
|
||||
if (res.code >= 0) {
|
||||
this.getWeekReserve();
|
||||
this.getYuyueInfo();
|
||||
}
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
});
|
||||
},
|
||||
//完成
|
||||
complet(reserve_id) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
reserveComplete(reserve_id).then(res => {
|
||||
this.flag = false;
|
||||
if (res.code >= 0) {
|
||||
this.getWeekReserve();
|
||||
this.getYuyueInfo();
|
||||
}
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
});
|
||||
},
|
||||
//取消预约
|
||||
cancel(reserve_id) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
cancelReserve(reserve_id).then(res => {
|
||||
this.flag = false;
|
||||
if (res.code >= 0) {
|
||||
this.getWeekReserve();
|
||||
this.getYuyueInfo();
|
||||
}
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
});
|
||||
},
|
||||
//确认到店
|
||||
tostore(reserve_id) {
|
||||
reserveToStore(reserve_id).then(res => {
|
||||
this.flag = false;
|
||||
if (res.code >= 0) {
|
||||
this.getWeekReserve();
|
||||
this.getYuyueInfo();
|
||||
}
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// ******************** 预约列表 ********************
|
||||
|
||||
// 获取预约分页数据
|
||||
getYuyueList() {
|
||||
getReserveLists({
|
||||
page: this.yuyuePage,
|
||||
search_text: this.yuyueSearchText
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
if (this.yuyuePage == 1) this.yuyueList = [];
|
||||
|
||||
this.yuyueList = this.yuyueList.concat(res.data.list);
|
||||
|
||||
if (this.yuyuePage == 1 && this.yuyueList.length > 0) {
|
||||
this.reserveId = this.yuyueList[0]['reserve_id'];
|
||||
this.getYuyueInfo();
|
||||
}
|
||||
|
||||
if (res.data.page_count >= this.yuyuePage) this.yuyuePage++;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 搜索预约客户
|
||||
searchYuyueList() {
|
||||
this.yuyuePage = 1;
|
||||
this.getYuyueList();
|
||||
},
|
||||
selectYuyue(id) {
|
||||
this.reserveId = id;
|
||||
this.getYuyueInfo();
|
||||
},
|
||||
getYuyueInfo() {
|
||||
getReserveDetail(this.reserveId).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.yuyueInfo = res.data;
|
||||
} else {
|
||||
this.yuyueInfo = null;
|
||||
}
|
||||
this.refreshStatus();
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
refreshStatus() {
|
||||
if (this.yuyueList && this.yuyueInfo) {
|
||||
Object.keys(this.yuyueList).forEach(key => {
|
||||
let data = this.yuyueList[key];
|
||||
if (data.reserve_id == this.yuyueInfo['reserve_id']) {
|
||||
this.yuyueList[key]['reserve_state'] = this.yuyueInfo['reserve_state'];
|
||||
this.yuyueList[key]['reserve_state_name'] = this.yuyueInfo['reserve_state_name'];
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
379
addon/cashier/source/os/pages/scale/add.vue
Executable file
379
addon/cashier/source/os/pages/scale/add.vue
Executable file
@@ -0,0 +1,379 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="common-wrap common-form body-overhide">
|
||||
<view class="common-title">电子秤设置</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
电子秤名称
|
||||
</label>
|
||||
<view class="form-input-inline"><input type="text" v-model="formData.name" class="form-input" /></view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
秤类型
|
||||
</label>
|
||||
<view class="form-input-inline border-none">
|
||||
<view class="scale-type">
|
||||
<view :class="{ active: formData.type == 'barcode' }" @click="formData.type = 'barcode'">条码秤</view>
|
||||
<view :class="{ active: formData.type == 'cashier' }" @click="formData.type = 'cashier'">收银秤</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
电子秤品牌
|
||||
</label>
|
||||
<view class="form-input-inline border-none">
|
||||
<uni-data-select v-model="formData.brand" :localdata="brandList" label=""></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
电子秤型号
|
||||
</label>
|
||||
<view class="form-input-inline border-none">
|
||||
<uni-data-select v-model="formData.model" :localdata="modelList"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">通讯方式</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="networkTypeChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="tcp" :checked="formData.network_type == 'tcp'" />
|
||||
TCP
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="serialport" :checked="formData.network_type == 'serialport'" />
|
||||
串口
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="scale-tips" v-if="formData.brand == 'dahua' && formData.model == 'TM'">
|
||||
<view>使用大华电子秤前需先配置一下电子秤“条码格式”,配置方式为:</view>
|
||||
<view>
|
||||
使用大华电子秤厂官方提供的大华电子秤上位机软件TMA4.0,连接到设备后,打开基础设置 -> 系统参数,设置条码格式为 “FFWWWWWNNNNNC” 或
|
||||
“FFWWWWWNNNNNEEEEEC”,设置好之后点击下载,下载成功之后即配置完成
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="scale-tips" v-if="formData.brand == 'aclas' && formData.model == 'LS'">
|
||||
<view>使用顶尖电子秤需将电子秤默认条码类型配置为“7” 或者 “87”</view>
|
||||
</view>
|
||||
|
||||
<view v-show="formData.network_type == 'tcp'">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
设备ip地址
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="formData.config.ip" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
设备端口号
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="formData.config.port" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-show="formData.network_type == 'serialport'">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
串口名称
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="formData.config.serialport" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
串口波特率
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="formData.config.baudrate" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-btn-wrap">
|
||||
<button type="primary" class="screen-btn" @click="saveFn">保存</button>
|
||||
<button type="default" class="screen-btn" @click="back">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniDataSelect from '@/components/uni-data-select/uni-data-select.vue';
|
||||
import {
|
||||
getScaleDetail,
|
||||
getScaleBrand,
|
||||
addScale,
|
||||
editScale
|
||||
} from '@/api/scale.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
uniDataSelect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
brandList: [],
|
||||
modelList: [],
|
||||
formData: {
|
||||
type: 'barcode',
|
||||
name: "",
|
||||
brand: "",
|
||||
model: "",
|
||||
config: {
|
||||
ip: '',
|
||||
port: '',
|
||||
serialport: '',
|
||||
baudrate: ''
|
||||
},
|
||||
network_type: 'tcp'
|
||||
},
|
||||
flag: false,
|
||||
scaleId: 0,
|
||||
scaleBrand: {}
|
||||
};
|
||||
},
|
||||
async onLoad(option) {
|
||||
await this.getScaleBrandFn();
|
||||
if (option.scale_id) {
|
||||
this.scaleId = option.scale_id;
|
||||
this.getDetailFn();
|
||||
}
|
||||
},
|
||||
onShow() {},
|
||||
watch: {
|
||||
'formData.brand': {
|
||||
handler: function(nval) {
|
||||
if (nval) {
|
||||
let modelList = this.scaleBrand[nval].model_list
|
||||
this.modelList = Object.keys(modelList).map(key => {
|
||||
return {
|
||||
value: key,
|
||||
text: modelList[key].model_name
|
||||
}
|
||||
})
|
||||
if (this.formData.model && !Object.keys(modelList).includes(this.formData.model)) this.formData
|
||||
.model = '';
|
||||
} else {
|
||||
this.formData.model = '';
|
||||
this.modelList = []
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getScaleBrandFn() {
|
||||
if (!this.addon.includes('scale')) {
|
||||
this.$util.showToast({
|
||||
title: '未安装电子秤插件'
|
||||
});
|
||||
return;
|
||||
}
|
||||
let res = await getScaleBrand()
|
||||
if (res.code == 0) {
|
||||
this.scaleBrand = res.data
|
||||
let brandList = [];
|
||||
Object.keys(this.scaleBrand).forEach(key => {
|
||||
brandList.push({
|
||||
text: this.scaleBrand[key].brand_name,
|
||||
value: key
|
||||
})
|
||||
})
|
||||
this.brandList = brandList
|
||||
}
|
||||
},
|
||||
bradnChange(e) {
|
||||
this.formData.model = e.detail.value;
|
||||
},
|
||||
selectBrand(e) {
|
||||
this.formData.brand = e;
|
||||
},
|
||||
saveFn() {
|
||||
if (!this.addon.includes('scale')) {
|
||||
this.$util.showToast({
|
||||
title: '未安装电子秤插件'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.check()) {
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
|
||||
let data = this.$util.deepClone(this.formData)
|
||||
data.config = JSON.stringify(this.formData.config)
|
||||
data.scale_id = this.scaleId
|
||||
let action = '';
|
||||
if (this.scaleId) {
|
||||
action = editScale(data)
|
||||
} else {
|
||||
action = addScale(data)
|
||||
}
|
||||
action.then(res => {
|
||||
this.flag = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
setTimeout(() => {
|
||||
this.$util.redirectTo('/pages/scale/list');
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
back() {
|
||||
this.$util.redirectTo('/pages/scale/list');
|
||||
},
|
||||
check() {
|
||||
if (!this.formData.name) {
|
||||
this.$util.showToast({
|
||||
title: '请输入电子秤名称'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.formData.model) {
|
||||
this.$util.showToast({
|
||||
title: '请选择电子秤型号'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.formData.network_type == 'tcp') {
|
||||
if (!this.formData.config.ip) {
|
||||
this.$util.showToast({
|
||||
title: '请输入设备IP地址'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.formData.config.port) {
|
||||
this.$util.showToast({
|
||||
title: '请输入设备端口号'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this.formData.network_type == 'serialport') {
|
||||
if (!this.formData.config.serialport) {
|
||||
this.$util.showToast({
|
||||
title: '请输入串口名称'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.formData.config.baudrate) {
|
||||
this.$util.showToast({
|
||||
title: '请输入串口波特率'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
getDetailFn() {
|
||||
if (!this.addon.includes('scale')) {
|
||||
this.$util.showToast({
|
||||
title: '未安装电子秤插件'
|
||||
});
|
||||
return;
|
||||
}
|
||||
getScaleDetail({
|
||||
"scale_id": this.scaleId
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
if (res.data) {
|
||||
this.formData = res.data
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
networkTypeChange(e) {
|
||||
this.formData.network_type = e.detail.value
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.common-wrap {
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
@extend %body-overhide;
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.scale-type {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
view {
|
||||
width: 1rem;
|
||||
height: 0.35rem;
|
||||
line-height: 0.35rem;
|
||||
text-align: center;
|
||||
font-size: 0.14rem;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
border-left-width: 0;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
border-color: $primary-color;
|
||||
color: $primary-color;
|
||||
background-color: var(--primary-color-light-9);
|
||||
box-shadow: -0.01rem 0 0 0 $primary-color;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-left-width: 0.01rem;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.border-none {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/deep/ .uni-select {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.scale-tips {
|
||||
display: inline-block;
|
||||
padding: .1rem;
|
||||
border-radius: .05rem;
|
||||
color: $primary-color !important;
|
||||
border: .01rem solid $primary-color !important;
|
||||
background-color: var(--primary-color-light-9) !important;
|
||||
margin-left: 1.1rem;
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
</style>
|
||||
239
addon/cashier/source/os/pages/scale/list.vue
Executable file
239
addon/cashier/source/os/pages/scale/list.vue
Executable file
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="scalelist">
|
||||
<view class="scalelist-box">
|
||||
<view class="scalelist-left">
|
||||
<view class="scale-title">
|
||||
电子秤
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="scale-list-wrap">
|
||||
<block v-if="list.length > 0">
|
||||
<scroll-view scroll-y="true" class="scale-list-scroll all-scroll" @scrolltolower="getList">
|
||||
<view class="item" @click="scaleSelect(item, index)" v-for="(item, index) in list" :key="index" :class="index == selectScaleKeys ? 'itemhover' : ''">
|
||||
<view class="item-right w-full">
|
||||
<view class="flex justify-between w-full">
|
||||
<view class="scale-name">{{ item.name }}<text class="scale-type-tag">{{ item.type == 'cashier' ? '收银秤': '条码秤' }}</text></view>
|
||||
<view class="flex items-center" v-if="item.connect_status">
|
||||
<text class="status-icon success"></text>已连接
|
||||
</view>
|
||||
<view class="flex items-center" v-else>
|
||||
<text class="status-icon fail"></text>未连接
|
||||
</view>
|
||||
</view>
|
||||
<view class="scale-money">{{ item.brand_name }}-{{ item.model_name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="!one_judge && list.length == 0">暂无电子秤</view>
|
||||
</view>
|
||||
<view class="add-printer">
|
||||
<button type="default" class="primary-btn" @click="addScale">添加电子秤</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="scalelist-right" v-show="!one_judge">
|
||||
<view class="scale-title">电子秤详情</view>
|
||||
<view class="scale-information">
|
||||
<block v-if="JSON.stringify(detail) != '{}'">
|
||||
<view class="title">基本信息</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>电子秤名称:</view>
|
||||
<view>{{ detail.name }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>电子秤类型:</view>
|
||||
<view>{{ detail.type == 'cashier' ? '收银秤' : '条码秤' }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>电子秤品牌:</view>
|
||||
<view>{{ detail.brand_name }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>电子秤型号:</view>
|
||||
<view>{{ detail.model_name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</block>
|
||||
<block v-else>
|
||||
<image class="cart-empty" src="@/static/cashier/cart_empty.png" mode="widthFix"/>
|
||||
</block>
|
||||
|
||||
</view>
|
||||
<view class="button-box" v-if="JSON.stringify(detail) != '{}'">
|
||||
<button class="default-btn" @click="$refs.deletePop.open()">删除</button>
|
||||
<button class="default-btn" @click="editScale(detail.scale_id)">修改</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 删除 -->
|
||||
<uni-popup ref="deletePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.deletePop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deleteScaleFn(detail.scale_id)">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getScaleList,
|
||||
getScaleDetail,
|
||||
deleteScale
|
||||
} from '@/api/scale.js'
|
||||
|
||||
var self;
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectScaleKeys: 0,
|
||||
search_text: '',
|
||||
page: 1,
|
||||
// 每次返回数据数
|
||||
page_size: 8,
|
||||
// 第一次请求列表做详情渲染判断
|
||||
one_judge: true,
|
||||
//详情数据
|
||||
detail: {},
|
||||
brandList: {
|
||||
yilianyun: '易联云',
|
||||
'365': '365'
|
||||
},
|
||||
flag: false,
|
||||
template: {},
|
||||
list: [],
|
||||
connectSuccess: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化请求打印机列表数据
|
||||
this.getList();
|
||||
self = this;
|
||||
},
|
||||
methods: {
|
||||
switchStoreAfter() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
if (!this.addon.includes('scale')) {
|
||||
this.$util.showToast({
|
||||
title: '未安装电子秤插件'
|
||||
});
|
||||
return;
|
||||
}
|
||||
getScaleList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
// 检测设备是否连接
|
||||
this.checkConnect();
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getDetailFn(this.list[0].scale_id);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
scaleSelect(item, keys) {
|
||||
this.selectScaleKeys = keys;
|
||||
this.getDetailFn(item.scale_id);
|
||||
},
|
||||
addScale() {
|
||||
this.$util.redirectTo('/pages/scale/add');
|
||||
},
|
||||
editScale(scale_id) {
|
||||
this.$util.redirectTo('/pages/scale/add', {
|
||||
scale_id: scale_id
|
||||
});
|
||||
},
|
||||
getDetailFn(scale_id) {
|
||||
getScaleDetail({
|
||||
scale_id
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.detail = res.data;
|
||||
this.one_judge = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteScaleFn(scale_id) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
deleteScale({scale_id}).then(res => {
|
||||
this.flag = false;
|
||||
if (res.code >= 0) {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.$refs.deletePop.close()
|
||||
this.getList();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
checkConnect() {
|
||||
if (typeof window.POS_DATA_CALLBACK == 'function') delete window.POS_DATA_CALLBACK;
|
||||
/**
|
||||
* 商品同步数据回调
|
||||
* @param {Object} text
|
||||
*/
|
||||
window.POS_DATA_CALLBACK = function (text) {
|
||||
let data = text.split(':');
|
||||
let index = parseInt(data[0]);
|
||||
|
||||
switch (data[1]) {
|
||||
case 'PingWeigher':
|
||||
self.$set(self.list[index], 'connect_status', parseInt(data[3]));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
let weigher = this.list.map(item => {
|
||||
item.config = typeof item.config == 'string' ? JSON.parse(item.config) : scale.config;
|
||||
return item
|
||||
});
|
||||
|
||||
this.$pos.send('PingWeigher', JSON.stringify({
|
||||
weigher
|
||||
}));
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/scale.scss';
|
||||
</style>
|
||||
356
addon/cashier/source/os/pages/scale/public/css/scale.scss
Executable file
356
addon/cashier/source/os/pages/scale/public/css/scale.scss
Executable file
@@ -0,0 +1,356 @@
|
||||
.scalelist {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
.scalelist-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
.scalelist-left {
|
||||
width: 5rem;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.notYet {
|
||||
color: #e6e6e6;
|
||||
font-size: 0.4rem;
|
||||
margin-top: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
.add-printer {
|
||||
padding: 0.24rem 0.2rem;
|
||||
background: #fff;
|
||||
|
||||
button {
|
||||
height: .4rem;
|
||||
line-height: .4rem;
|
||||
}
|
||||
}
|
||||
.scale-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.icongengduo1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
.scale-list-wrap {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
.scale-list-scroll {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.itemhover {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
.item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
image {
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
.item-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 0.6rem;
|
||||
.scale-name {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
.scale-money {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.scalelist-right {
|
||||
width: 0;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.scale-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.icongengduo1,.iconguanbi1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.scale-information {
|
||||
width: 100%;
|
||||
padding: 0.2rem 0.2rem 0.88rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
height: calc(100% - 0.6rem);
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
.title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.32rem;
|
||||
}
|
||||
.title2 {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.information-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.box-left {
|
||||
width: 5rem;
|
||||
.information {
|
||||
width: 100%;
|
||||
padding-left: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
view:nth-child(1) {
|
||||
width: 1.3rem;
|
||||
margin-right: 0.16rem;
|
||||
text-align: right;
|
||||
}
|
||||
view:nth-child(2) {
|
||||
width: 74%;
|
||||
margin-right: 0.23rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.information:last-child {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
}
|
||||
.scale-img {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
}
|
||||
.table {
|
||||
width: 100%;
|
||||
height: 2.6rem;
|
||||
box-sizing: border-box;
|
||||
.table-all {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 0.38rem;
|
||||
box-sizing: border-box;
|
||||
.table-td {
|
||||
font-size: 0.14rem;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.table-th {
|
||||
height: 0.56rem;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
.table-tb {
|
||||
width: 100%;
|
||||
height: calc(100% - 0.56rem);
|
||||
.table-tr {
|
||||
height: 0.7rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
.table-td {
|
||||
image {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
view {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.scale-information::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
.scale-information::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.button-box {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 0.24rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
button {
|
||||
min-width: 0.9rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
margin: 0;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
|
||||
.form-content {
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 0.1rem;
|
||||
display: flex;
|
||||
.form-label {
|
||||
width: 1.3rem;
|
||||
text-align: right;
|
||||
padding-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
}
|
||||
.form-inline {
|
||||
width: 2.4rem;
|
||||
line-height: 0.32rem;
|
||||
margin-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
.form-input {
|
||||
border-width: 0.01rem;
|
||||
border-style: solid;
|
||||
background-color: #fff;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 0.02rem;
|
||||
padding-left: 0.1rem;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
font-size: 0.14rem;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
.form-textarea {
|
||||
border-width: 0.01rem;
|
||||
border-style: solid;
|
||||
background-color: #fff;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 0.02rem;
|
||||
padding-left: 0.1rem;
|
||||
line-height: 0.32rem;
|
||||
font-size: 0.14rem;
|
||||
border-color: #e6e6e6;
|
||||
height: 1rem;
|
||||
}
|
||||
button {
|
||||
width: calc(50% - 0.05rem);
|
||||
display: inline-block;
|
||||
margin-right: 0.1rem;
|
||||
&:nth-child(2) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.order-type{
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
.status-icon {
|
||||
width: .05rem;
|
||||
height: .05rem;
|
||||
border-radius: 50%;
|
||||
margin-right: .05rem;
|
||||
|
||||
&.success {
|
||||
background: limegreen;
|
||||
}
|
||||
|
||||
&.fail {
|
||||
background: red;
|
||||
}
|
||||
}
|
||||
|
||||
.scale-type-tag {
|
||||
border: 0.01rem solid $primary-color;
|
||||
color: $primary-color;
|
||||
background-color: #fff;
|
||||
border-radius: 0.02rem;
|
||||
width: -webkit-fit-content;
|
||||
width: fit-content;
|
||||
padding: 0.01rem 0.05rem;
|
||||
margin-left: 0.10rem
|
||||
}
|
||||
608
addon/cashier/source/os/pages/stat/index.vue
Executable file
608
addon/cashier/source/os/pages/stat/index.vue
Executable file
@@ -0,0 +1,608 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="common-wrap">
|
||||
<view class="title">营业数据</view>
|
||||
<view class="choice-day">
|
||||
<view class="date-btn" :class="dateType == 'today' ? 'select' : ''" @click="switchDateType('today')" value="today">今日</view>
|
||||
<view class="date-btn" :class="dateType == 'yesterday' ? 'select' : ''" @click="switchDateType('yesterday')" value="yesterday">昨日</view>
|
||||
<view class="date-btn" :class="dateType == 'week' ? 'select' : ''" @click="switchDateType('week')" value="week">7日内</view>
|
||||
<view class="date-btn" :class="dateType == 'month' ? 'select' : ''" @click="switchDateType('month')" value="month">30日内</view>
|
||||
<view class="date-btn" :class="dateType == 'custom' ? 'select' : ''" @click="switchDateType('custom')" value="custom">自定义</view>
|
||||
<view class="report text-color">
|
||||
<text class="move iconfont iconicon-test"></text>
|
||||
<text></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template v-if="businessData">
|
||||
<view class="title-port">线下收银</view>
|
||||
<view class="money">
|
||||
<view class="estimate" :class="statType == 'expected_earnings_total_money' ? 'estimate-active' : ''">
|
||||
<view class="income">
|
||||
<text class="income-name">预计收入(元)</text>
|
||||
<!-- <uni-dropdown>
|
||||
<view class="action" slot="dropdown-link"><text class="iconfont iconbangzhu js-prompt-top"></text></view>
|
||||
<view slot="dropdown">
|
||||
<view class="dropdown-content-box">
|
||||
<view class="text">弹框展示内容</view>
|
||||
<view class="arrow"></view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-dropdown> -->
|
||||
</view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.expected_earnings_total_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('expected_earnings_total_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'billing_money' ? 'estimate-active' : ''">
|
||||
<view class="income">
|
||||
<text class="income-name">开单金额数(元)</text>
|
||||
<!-- <uni-dropdown>
|
||||
<view class="action" slot="dropdown-link"><text class="iconfont iconbangzhu js-prompt-top"></text></view>
|
||||
<view slot="dropdown">
|
||||
<view class="dropdown-content-box">
|
||||
<view class="text">弹框展示内容</view>
|
||||
<view class="arrow"></view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-dropdown> -->
|
||||
</view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.billing_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('billing_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'billing_count' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">开单数量</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.billing_count || 0 }}</text>
|
||||
<text class="detail" @click="switchStatType('billing_count')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'buycard_money' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">办卡金额数(元)</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.buycard_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('buycard_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'buycard_count' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">办卡数</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.buycard_count || 0 }}</text>
|
||||
<text class="detail" @click="switchStatType('buycard_count')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'recharge_money' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">会员充值金额(元)</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.recharge_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('recharge_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'recharge_count' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">会员充值数量</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.recharge_count || 0 }}</text>
|
||||
<text class="detail" @click="switchStatType('recharge_count')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'refund_money' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">会员退款金额(元)</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.refund_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('refund_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'refund_count' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">会员退款数量</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.refund_count || 0 }}</text>
|
||||
<text class="detail" @click="switchStatType('refund_count')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'order_member_count' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">门店下单会员数</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.order_member_count || 0 }}</text>
|
||||
<text class="detail" @click="switchStatType('order_member_count')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'balance_money' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">会员余额消费金额</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.balance_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('balance_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-if="businessData">
|
||||
<view class="title-port">线上商城</view>
|
||||
<view class="money">
|
||||
<view class="estimate" :class="statType == 'online_pay_money' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">商城订单(元)</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.online_pay_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('online_pay_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="estimate" :class="statType == 'online_refund_money' ? 'estimate-active' : ''">
|
||||
<view class="income"><text class="income-name">退款维权(元)</text></view>
|
||||
<view class="num-money">
|
||||
<text class="last_income">{{ businessData.online_refund_money || 0.0 }}</text>
|
||||
<text class="detail" @click="switchStatType('online_refund_money')">查看详情</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
|
||||
<uni-popup ref="customTime">
|
||||
<view class="pop-box">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">自定义时间选择</view>
|
||||
<view class="pop-header-close" @click="$refs.customTime.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content ">
|
||||
<uni-datetime-picker v-model="timeObj.custom" @change="changeTime" :end="endDate" :clearIcon="false" type="datetimerange" rangeSeparator="至" />
|
||||
</view>
|
||||
<view class="pop-bottom"><button class="primary-btn" @click="getStatData()">确定</button></view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<uni-popup ref="chartsPop">
|
||||
<view class="pop-box charts-pop">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">运营数据图表展示</view>
|
||||
<view class="pop-header-close" @click="$refs.chartsPop.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content">
|
||||
<qiun-data-charts type="line" :chartData="chartData" :eopts="{ seriesTemplate: { smooth: true } }" :ontouch="true" :opts="chartsOpts" />
|
||||
</view>
|
||||
<!-- <view class="pop-bottom"><button class="primary-btn" @click="getStatData()">确定</button></view> -->
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getStatDay,
|
||||
getStatHour,
|
||||
getStatTotal
|
||||
} from '@/api/stat.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
statType: 'expected_earnings_total_money',
|
||||
statTypeArr: {
|
||||
expected_earnings_total_money: '预计收入',
|
||||
billing_money: '开单金额数',
|
||||
billing_count: '开单数量',
|
||||
buycard_money: '办卡金额数',
|
||||
buycard_count: '办卡数',
|
||||
recharge_money: '会员充值金额',
|
||||
recharge_count: '会员充值数量',
|
||||
refund_money: '会员退款金额',
|
||||
refund_count: '会员退款数量',
|
||||
order_member_count: '门店下单会员数',
|
||||
balance_money: '会员余额消费金额',
|
||||
online_pay_money: '商城订单',
|
||||
online_refund_money: '退款维权'
|
||||
},
|
||||
dateType: 'today',
|
||||
timeObj: {
|
||||
today: [],
|
||||
yesterday: [],
|
||||
week: [],
|
||||
month: [],
|
||||
custom: []
|
||||
},
|
||||
chartData: {
|
||||
categories: [],
|
||||
series: []
|
||||
},
|
||||
businessData: null,
|
||||
chartsOpts: {
|
||||
enableScroll: true,
|
||||
xAxis: {
|
||||
scrollShow: true,
|
||||
itemCount: 24,
|
||||
disableGrid: true
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.setDate();
|
||||
this.getStatData();
|
||||
},
|
||||
onShow() {
|
||||
let date = new Date();
|
||||
var y = date.getFullYear();
|
||||
var m = date.getMonth() + 1;
|
||||
var d = date.getDate();
|
||||
this.endDate = y + '-' + m + '-' + d + ' 23:59:59';
|
||||
},
|
||||
methods: {
|
||||
// 重置图表数据
|
||||
resetChartData() {
|
||||
this.chartData.categories = [];
|
||||
this.chartData.series = [];
|
||||
},
|
||||
setDate() {
|
||||
let time = this.$util.timeTurnTimeStamp(this.$util.timeFormat(Date.now() / 1000, 'Y-m-d'));
|
||||
this.timeObj.today = [time, time + 86399];
|
||||
this.timeObj.yesterday = [time - 86400, time - 1];
|
||||
this.timeObj.week = [time - 604800, time];
|
||||
this.timeObj.month = [time - 2592000, time];
|
||||
},
|
||||
switchDateType(type) {
|
||||
this.dateType = type;
|
||||
if (type == 'custom') {
|
||||
this.$refs.customTime.open();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == 'month') this.chartsOpts.xAxis.itemCount = 10;
|
||||
else this.chartsOpts.xAxis.itemCount = 24;
|
||||
this.getStatData();
|
||||
},
|
||||
switchStatType(type) {
|
||||
this.statType = type;
|
||||
this.$refs.chartsPop.open();
|
||||
this.resetChartData();
|
||||
this.getStatData();
|
||||
setTimeout(() => {
|
||||
this.getChartData();
|
||||
}, 500);
|
||||
},
|
||||
changeTime(e) {
|
||||
this.timeObj.custom = e;
|
||||
this.chartsOpts.xAxis.itemCount = 10;
|
||||
},
|
||||
getStatData() {
|
||||
if (this.dateType == 'custom') {
|
||||
this.$refs.customTime.close();
|
||||
|
||||
this.timeObj.custom[0] = this.$util.timeTurnTimeStamp(this.timeObj.custom[0]) *
|
||||
1000; // 解决自定义数据保存之后再次点击出现的数据错乱
|
||||
this.timeObj.custom[1] = this.$util.timeTurnTimeStamp(this.timeObj.custom[1]) *
|
||||
1000; // 解决自定义数据保存之后再次点击出现的数据错乱
|
||||
}
|
||||
this.getBusinessData();
|
||||
},
|
||||
getChartData() {
|
||||
let data = {};
|
||||
data.start_time = this.timeObj[this.dateType][0];
|
||||
let action = '';
|
||||
if (this.dateType == 'today' || this.dateType == 'yesterday') {
|
||||
action = getStatHour(data);
|
||||
} else {
|
||||
data.end_time = this.timeObj[this.dateType][1];
|
||||
action = getStatDay(data);
|
||||
}
|
||||
action.then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.chartData.series = [];
|
||||
this.chartData.series.push({
|
||||
data: res.data[this.statType],
|
||||
name: this.statTypeArr[this.statType]
|
||||
});
|
||||
this.chartData.categories = res.data.time;
|
||||
}
|
||||
});
|
||||
},
|
||||
getBusinessData() {
|
||||
let data = {};
|
||||
data.start_time = this.dateType == 'custom' ? parseInt(this.timeObj[this.dateType][0] / 1000) : parseInt(this.timeObj[this.dateType][0]);
|
||||
data.end_time = this.dateType == 'custom' ? parseInt(this.timeObj[this.dateType][1] / 1000) : parseInt(this.timeObj[this.dateType][1]);
|
||||
getStatTotal(data).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.businessData = res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pop-content>>>.uni-icons {
|
||||
line-height: 0.32rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.common-wrap {
|
||||
padding: 0.2rem 0.2rem 0.6rem;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
margin-bottom: 0.2rem;
|
||||
font-size: 0.16rem;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
line-height: 0.2rem;
|
||||
}
|
||||
|
||||
.title-port {
|
||||
margin-bottom: 0.2rem;
|
||||
margin-left: 0.1rem;
|
||||
font-size: 0.16rem;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
line-height: 0.2rem;
|
||||
}
|
||||
|
||||
.choice-day {
|
||||
display: flex;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.choice-time {
|
||||
margin-top: 0.09rem;
|
||||
font-size: 0.12rem;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
line-height: 0.36rem;
|
||||
}
|
||||
|
||||
.report {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-right: 0.2rem;
|
||||
font-size: 0.14rem;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
line-height: 0.36rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.move {
|
||||
margin-right: 0.06rem;
|
||||
}
|
||||
|
||||
.money {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.estimate {
|
||||
width: calc((100% - 0.85rem) / 5);
|
||||
margin: 0 0.08rem 0.2rem;
|
||||
padding: 0.2rem;
|
||||
background: #fff;
|
||||
border: 0.01rem solid #eee;
|
||||
border-radius: 0.02rem;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
|
||||
.income {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
box-sizing: border-box;
|
||||
line-height: 0.2rem;
|
||||
|
||||
.income-name {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
}
|
||||
|
||||
.num-money {
|
||||
.last_income {
|
||||
display: block;
|
||||
margin: 0.15rem 0;
|
||||
font-size: 0.24rem;
|
||||
font-weight: 500;
|
||||
line-height: 0.2rem;
|
||||
}
|
||||
|
||||
.detail {
|
||||
display: block;
|
||||
text-align: right;
|
||||
color: $primary-color;
|
||||
font-size: $uni-font-size-sm;
|
||||
position: relative;
|
||||
bottom: -0.05rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.estimate:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.yesterday {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
font-size: 0.12rem;
|
||||
}
|
||||
|
||||
.top-num {
|
||||
display: flex;
|
||||
margin-left: 0.05rem;
|
||||
font-size: 0.12rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.date-btn {
|
||||
height: 0.42rem;
|
||||
line-height: 0.42rem;
|
||||
font-size: 0.14rem;
|
||||
padding: 0 0.3rem;
|
||||
box-sizing: border-box;
|
||||
border: 0.01rem solid #d2d2d2;
|
||||
cursor: pointer;
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.date-btn:nth-child(6)::after {
|
||||
border-radius: 0 0.02rem 0.02rem 0;
|
||||
}
|
||||
|
||||
.date-btn:first-child::after {
|
||||
border-radius: 0.02rem 0 0 0.02rem;
|
||||
}
|
||||
|
||||
.date-btn:first-child {
|
||||
border-radius: 0.02rem 0 0 0.02rem;
|
||||
}
|
||||
|
||||
.date-btn::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -0.01rem;
|
||||
left: 0;
|
||||
bottom: -0.01rem;
|
||||
right: -0.01rem;
|
||||
border-right: 0.01rem solid #d2d2d2;
|
||||
border-left: 0.01rem solid #d2d2d2;
|
||||
}
|
||||
|
||||
.select {
|
||||
color: #fff;
|
||||
background-color: $primary-color;
|
||||
border-color: $primary-color;
|
||||
}
|
||||
|
||||
.select::after {
|
||||
z-index: 2;
|
||||
border-color: $primary-color;
|
||||
}
|
||||
|
||||
.select:first-child {
|
||||
border-radius: 0.02rem 0 0 0.02rem;
|
||||
}
|
||||
|
||||
.seleced:nth-child(6) {
|
||||
border-radius: 0 0.02rem 0.02rem 0;
|
||||
}
|
||||
|
||||
.c-datepicker-picker {
|
||||
z-index: 99999999 !important;
|
||||
}
|
||||
|
||||
.yesterday {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropdown-content-box {
|
||||
padding: 0.05rem 0;
|
||||
margin-top: 0.05rem;
|
||||
background-color: #fff;
|
||||
border: 0.01rem solid #ebeef5;
|
||||
border-radius: 0.04rem;
|
||||
box-shadow: 0 0.01rem 0.12rem 0 rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
|
||||
.arrow {
|
||||
position: absolute;
|
||||
top: -0.06rem;
|
||||
right: 0.06rem;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 0.06rem solid transparent;
|
||||
border-right: 0.06rem solid transparent;
|
||||
border-bottom: 0.06rem solid #fff;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
padding: 0 0.1rem;
|
||||
transition: all 0.3s;
|
||||
font-size: 0.12rem;
|
||||
width: 1.5rem;
|
||||
box-sizing: border-box;
|
||||
text-align: left;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
.js-prompt-top {
|
||||
color: #c8c9cc;
|
||||
font-size: 0.14rem;
|
||||
z-index: 999;
|
||||
margin-left: 0.05rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// pop弹框
|
||||
.pop-box {
|
||||
background: #ffffff;
|
||||
width: 6rem;
|
||||
height: 3.38rem;
|
||||
|
||||
.pop-header {
|
||||
padding: 0 0.15rem 0 0.2rem;
|
||||
height: 0.5rem;
|
||||
line-height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #f0f0f0;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
border-radius: 0.02rem 0.2rem 0 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pop-header-text {}
|
||||
|
||||
.pop-header-close {
|
||||
cursor: pointer;
|
||||
|
||||
text {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
height: calc(100% - 1.05rem);
|
||||
// overflow-y: scroll;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pop-bottom {
|
||||
padding: 0.1rem 0.2rem;
|
||||
border-top: 0.01rem solid #eee;
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
line-height: 0.35rem;
|
||||
height: 0.35rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.charts-pop {
|
||||
width: 9.5rem;
|
||||
height: 5.4rem;
|
||||
background-color: #fff;
|
||||
|
||||
.pop-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 1rem);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
398
addon/cashier/source/os/pages/stock/allocate.vue
Executable file
398
addon/cashier/source/os/pages/stock/allocate.vue
Executable file
@@ -0,0 +1,398 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
调拨单查询
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input type="text" v-model="search_text" @input="search" placeholder="搜索调拨单号" />
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getListData">
|
||||
<view class="item" @click="getDetailData(item.allot_id, index)" v-for="(item, index) in list" :key="index" :class="{ itemhover: selectGoodsKeys == index }">
|
||||
<view class="title">
|
||||
<view>{{ item.allot_no }}</view>
|
||||
<view>¥{{ item.goods_money }}</view>
|
||||
</view>
|
||||
<view class="other-info">
|
||||
<view>出库门店:{{ item.output_store_name }}</view>
|
||||
<view>入库门店:{{ item.input_store_name }}</view>
|
||||
<view>{{ $util.timeFormat(item.allot_time) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="notYet" v-if="!one_judge && !list.length">暂无数据</view>
|
||||
</scroll-view>
|
||||
<view class="add-wastage">
|
||||
<button type="default" class="primary-btn" v-if="globalStoreInfo.stock_type == 'store'" @click="add()">添加调拨单</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goodslist-right">
|
||||
<view class="goods-title">调拨单详情</view>
|
||||
<view class="order-information" v-if="Object.keys(detail).length">
|
||||
<view class="order-status">基本信息</view>
|
||||
<view class="order-types">
|
||||
<view class="type type1">
|
||||
<view>调拨单号:</view>
|
||||
<view>{{ detail.allot_no }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>制单人:</view>
|
||||
<view>{{ detail.operater_name || '--' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>调拨时间:</view>
|
||||
<view class="message">{{ $util.timeFormat(detail.allot_time) }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>出库门店:</view>
|
||||
<view class="message">{{ detail.output_store_name }}</view>
|
||||
</view>
|
||||
<template v-if="detail.out_info">
|
||||
<view class="type type1">
|
||||
<view>出库时间:</view>
|
||||
<view class="message">{{ detail.out_info.create_time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>经办人:</view>
|
||||
<view class="message">{{ detail.out_info.operater_name }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>状态:</view>
|
||||
<view class="message">{{ detail.out_info.status_name }}</view>
|
||||
</view>
|
||||
|
||||
<view class="type type1" v-if="detail.out_info.verifier_name">
|
||||
<view>审核人:</view>
|
||||
<view class="message">{{ detail.out_info.verifier_name }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.out_info.audit_time">
|
||||
<view>审核时间:</view>
|
||||
<view class="message">{{ detail.out_info.audit_time }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.out_info.status == -1">
|
||||
<view>拒绝理由:</view>
|
||||
<view class="message">{{ detail.out_info.refuse_reason }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="type type1">
|
||||
<view>入库门店:</view>
|
||||
<view class="message">{{ detail.input_store_name }}</view>
|
||||
</view>
|
||||
|
||||
<template v-if="detail.input_info">
|
||||
<view class="type type1">
|
||||
<view>入库时间:</view>
|
||||
<view class="message">{{ detail.input_info.create_time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>经办人:</view>
|
||||
<view class="message">{{ detail.input_info.operater_name }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>状态:</view>
|
||||
<view class="message">{{ detail.input_info.status_name }}</view>
|
||||
</view>
|
||||
|
||||
<view class="type type1" v-if="detail.input_info.verifier_name">
|
||||
<view>审核人:</view>
|
||||
<view class="message">{{ detail.input_info.verifier_name }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.input_info.audit_time">
|
||||
<view>审核时间:</view>
|
||||
<view class="message">{{ detail.input_info.audit_time }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.input_info.status == -1">
|
||||
<view>拒绝理由:</view>
|
||||
<view class="message">{{ detail.input_info.refuse_reason }}</view>
|
||||
</view>
|
||||
</template>
|
||||
<view class="type type1">
|
||||
<view>备注:</view>
|
||||
<view class="message">{{ detail.remark }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-info">
|
||||
<view class="title">商品明细</view>
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:45%;justify-content: flex-start;">商品名称/规格/条形码</view>
|
||||
<view class="table-td" style="width:15%">单位</view>
|
||||
<view class="table-td" style="width:10%">数量</view>
|
||||
<view class="table-td" style="width:15%">成本价(元)</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">金额(元)</view>
|
||||
</view>
|
||||
<view class="table-tr table-all" v-for="(item, index) in detail.goods_sku_list_array" :key="index">
|
||||
<view class="table-td table-goods-name" style="width:45%;justify-content: flex-start;">
|
||||
<image :src="$util.img(item.goods_img)" mode="aspectFill" />
|
||||
<text class="multi-hidden">{{ item.goods_sku_name }}</text>
|
||||
</view>
|
||||
<view class="table-td" style="width:15%">{{ item.goods_unit || '件' }}</view>
|
||||
<view class="table-td" style="width:10%">{{ item.goods_num }}</view>
|
||||
<view class="table-td" style="width:15%">{{ item.goods_price }}</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">{{ parseFloat(item.goods_sum).toFixed(2) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="total-money-num">
|
||||
<view class="box">
|
||||
<view>商品种类</view>
|
||||
<view class="money">{{ detail.goods_count }}种</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>商品数量</view>
|
||||
<view class="money">{{ detail.goods_price }}{{ detail.goods_unit }}</view>
|
||||
</view>
|
||||
<view class="box total">
|
||||
<view>合计金额</view>
|
||||
<view class="money">¥{{ parseFloat(detail.goods_total_price).toFixed(2) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="action-box">
|
||||
<!-- 只有经办人才能操作入库单 -->
|
||||
<template v-if="(detail.status == 1 || detail.status == -1) && detail.operater == detail.uid">
|
||||
<button type="primary" class="default-btn" @click="open('deleteWastagePop')">删除</button>
|
||||
<button type="primary" class="default-btn" @click="edit">编辑</button>
|
||||
</template>
|
||||
|
||||
<!-- 只有管理员和拥有单据审核权限的才能审核 -->
|
||||
<template v-if="detail.status == 1 && detail.is_audit == 0">
|
||||
<button type="primary" class="default-btn" @click="open('refuseWastagePop')">审核拒绝</button>
|
||||
<button type="primary" class="primary-btn" @click="open('agreeWastagePop')">审核通过</button>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<block v-else-if="!one_judge && !Object.keys(detail).length">
|
||||
<image class="cart-empty" src="@/static/goods/goods_empty.png" mode="widthFix"/>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 同意 -->
|
||||
<unipopup ref="agreeWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要通过该单据吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('agreeWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="agree">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 拒绝 -->
|
||||
<unipopup ref="refuseWastagePop" type="center">
|
||||
<view class="confirm-pop message">
|
||||
<view class="title">
|
||||
拒绝理由
|
||||
<text class="iconfont iconguanbi1" @click="close('refuseWastagePop')"></text>
|
||||
</view>
|
||||
<view class="textarea-box">
|
||||
<textarea v-model="refuseReason" class="textarea" maxlength="200" placeholder="输入请不多于200字"></textarea>
|
||||
</view>
|
||||
<button @click="refuse" type="primary" class="primary-btn btn save">保存</button>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 删除 -->
|
||||
<unipopup ref="deleteWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除该单据吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('deleteWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deleteDocument">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getAllocateList,
|
||||
getAllocateDetail,
|
||||
allocateAgree,
|
||||
allocateDelete,
|
||||
allocateRefuse
|
||||
} from '@/api/stock.js';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectGoodsKeys: 0,
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 9,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
//初始时加载详情数据判断
|
||||
one_judge: true,
|
||||
// 订单列表数据
|
||||
list: [],
|
||||
//订单详情数据
|
||||
detail: {},
|
||||
repeatFlag: false,
|
||||
refuseReason: ''
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getListData();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.getListData();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getListData() {
|
||||
getAllocateList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
allot_no: this.search_text
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getDetailData(this.list[0].allot_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取单据详情
|
||||
*/
|
||||
getDetailData(allot_id, keys = 0) {
|
||||
this.selectGoodsKeys = keys;
|
||||
this.type = 'detail';
|
||||
getAllocateDetail(allot_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.detail = res.data;
|
||||
this.$forceUpdate();
|
||||
this.one_judge = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.$util.redirectTo('/pages/stock/edit_allocate');
|
||||
},
|
||||
edit() {
|
||||
this.$util.redirectTo('/pages/stock/edit_allocate', {
|
||||
allot_id: this.detail.allot_id
|
||||
});
|
||||
},
|
||||
open(action) {
|
||||
this.$refs[action].open();
|
||||
},
|
||||
close(name) {
|
||||
this.$refs[name].close();
|
||||
},
|
||||
/**
|
||||
* 审核通过
|
||||
*/
|
||||
agree() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
|
||||
allocateAgree(this.detail.allot_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.allot_id);
|
||||
this.close('agreeWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 审核拒绝
|
||||
*/
|
||||
refuse() {
|
||||
if (!this.refuseReason) {
|
||||
this.$util.showToast({
|
||||
title: '请输入拒绝理由'
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
|
||||
allocateRefuse({
|
||||
allot_id: this.detail.allot_id,
|
||||
refuse_reason: this.refuseReason
|
||||
}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.allot_id);
|
||||
this.close('refuseWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 删除单据
|
||||
*/
|
||||
deleteDocument() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
|
||||
allocateDelete(this.detail.allot_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.list.splice(this.selectGoodsKeys, 1);
|
||||
|
||||
if (this.selectGoodsKeys == 0) {
|
||||
this.selectGoodsKeys = 0;
|
||||
} else {
|
||||
this.selectGoodsKeys -= 1;
|
||||
}
|
||||
|
||||
this.getDetailData(this.list[this.selectGoodsKeys].allot_id, this.selectGoodsKeys);
|
||||
this.close('deleteWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/orderlist.scss';
|
||||
</style>
|
||||
360
addon/cashier/source/os/pages/stock/check.vue
Executable file
360
addon/cashier/source/os/pages/stock/check.vue
Executable file
@@ -0,0 +1,360 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
盘点单查询
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input type="text" v-model="search_text" @input="search" placeholder="搜索盘点单号" />
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getListData">
|
||||
<view class="item" @click="getDetailData(item.inventory_id, index)" v-for="(item, index) in list" :key="index" :class="{ itemhover: selectGoodsKeys == index }">
|
||||
<view class="title">
|
||||
<view>{{ item.inventory_no }}</view>
|
||||
</view>
|
||||
<view class="other-info">
|
||||
<view>{{ item.operater_name }}</view>
|
||||
<view>{{ item.status_name }}</view>
|
||||
<view>{{ $util.timeFormat(item.create_time) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="notYet" v-if="!one_judge && !list.length">暂无数据</view>
|
||||
</scroll-view>
|
||||
<view class="add-wastage">
|
||||
<button type="default" class="primary-btn" v-if="globalStoreInfo.stock_type == 'store'" @click="add()">添加盘点单</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goodslist-right">
|
||||
<view class="goods-title">盘点单详情</view>
|
||||
<view class="order-information" v-if="Object.keys(detail).length">
|
||||
<view class="order-status">基本信息</view>
|
||||
<view class="order-types">
|
||||
<view class="type type1">
|
||||
<view>盘点单号:</view>
|
||||
<view>{{ detail.inventory_no }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>制单人:</view>
|
||||
<view>{{ detail.operater_name || '--' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>制单时间:</view>
|
||||
<view class="message">{{ detail.create_time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>盘点时间:</view>
|
||||
<view class="message">{{ detail.action_time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>状态:</view>
|
||||
<view class="message">{{ detail.status_name }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.verifier_name">
|
||||
<view>审核人:</view>
|
||||
<view class="message">{{ detail.verifier_name }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.audit_time">
|
||||
<view>审核时间:</view>
|
||||
<view class="message">{{ detail.audit_time }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.status == -1">
|
||||
<view>拒绝理由:</view>
|
||||
<view class="message">{{ detail.refuse_reason }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>备注:</view>
|
||||
<view class="message">{{ detail.remark }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-info">
|
||||
<view class="title">商品明细</view>
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:25%;justify-content: flex-start;">商品名称/规格/条形码</view>
|
||||
<!-- <view class="table-td" style="width:5%">单位</view> -->
|
||||
<view class="table-td" style="width:8%">实物库存</view>
|
||||
<view class="table-td" style="width:8%">实盘数量</view>
|
||||
<view class="table-td" style="width:8%">盈亏数量</view>
|
||||
<view class="table-td" style="width:13%">盈亏成本总额(元)</view>
|
||||
</view>
|
||||
<view class="table-tr table-all" v-for="(item, index) in detail.goods_sku_list_array" :key="index">
|
||||
<view class="table-td table-goods-name" style="width:25%;justify-content: flex-start;">
|
||||
<image :src="$util.img(item.goods_img)" mode="aspectFill" />
|
||||
<text class="multi-hidden">{{ item.goods_sku_name }}</text>
|
||||
</view>
|
||||
<!-- <view class="table-td" style="width:5%">种</view> -->
|
||||
<view class="table-td" style="width:8%">{{ item.stock }}</view>
|
||||
<view class="table-td" style="width:8%">{{ item.inventory_num }}</view>
|
||||
<view class="table-td" style="width:8%">{{ item.profitloss_num }}</view>
|
||||
<view class="table-td" style="width:13%">{{ item.inventory_cost_money }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="total-money-num">
|
||||
<view class="box">
|
||||
<view>商品种类</view>
|
||||
<view class="money">{{ detail.goods_count }}种</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>实盘种类</view>
|
||||
<view class="money">{{ detail.kinds_num }}种</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>盘盈</view>
|
||||
<view class="money kinds-profit">{{ detail.kinds_profit_num }}</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>盘亏</view>
|
||||
<view class="money kinds-loss">{{ detail.kinds_loss_num }}</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>持平种类</view>
|
||||
<view class="money">{{ detail.kinds_even_num }}种</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="action-box">
|
||||
<!-- 只有经办人才能操作入库单 -->
|
||||
<template v-if="(detail.status == 1 || detail.status == -1) && detail.operater == detail.uid">
|
||||
<button type="primary" class="default-btn" @click="open('deleteWastagePop')">删除</button>
|
||||
<button type="primary" class="default-btn" @click="edit">编辑</button>
|
||||
</template>
|
||||
|
||||
<!-- 只有管理员和拥有单据审核权限的才能审核 -->
|
||||
<template v-if="detail.status == 1 && detail.is_audit == 0">
|
||||
<button type="primary" class="default-btn" @click="open('refuseWastagePop')">审核拒绝</button>
|
||||
<button type="primary" class="primary-btn" @click="open('agreeWastagePop')">审核通过</button>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<block v-else-if="!one_judge && !Object.keys(detail).length">
|
||||
<image class="cart-empty" src="@/static/goods/goods_empty.png" mode="widthFix"/>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 同意 -->
|
||||
<unipopup ref="agreeWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要通过该盘点单吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('agreeWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="agree">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 拒绝 -->
|
||||
<unipopup ref="refuseWastagePop" type="center">
|
||||
<view class="confirm-pop message">
|
||||
<view class="title">
|
||||
拒绝理由
|
||||
<text class="iconfont iconguanbi1" @click="close('refuseWastagePop')"></text>
|
||||
</view>
|
||||
<view class="textarea-box">
|
||||
<textarea v-model="refuseReason" class="textarea" maxlength="200" placeholder="输入请不多于200字"></textarea>
|
||||
</view>
|
||||
<button @click="refuse" type="primary" class="primary-btn btn save">保存</button>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 删除 -->
|
||||
<unipopup ref="deleteWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除该盘点单吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('deleteWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deleteCheck">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
</base-page>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getInventoryList,
|
||||
getInventoryDetail,
|
||||
inventoryAgree,
|
||||
inventoryRefuse,
|
||||
inventoryDelete
|
||||
} from '@/api/stock.js';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectGoodsKeys: 0,
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 9,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
//初始时加载详情数据判断
|
||||
one_judge: true,
|
||||
// 订单列表数据
|
||||
list: [],
|
||||
//订单详情数据
|
||||
detail: {},
|
||||
repeatFlag: false,
|
||||
refuseReason: ''
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.getListData();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.getListData();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getListData() {
|
||||
getInventoryList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
inventory_no: this.search_text
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getDetailData(this.list[0].inventory_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
getDetailData(inventory_id, keys = 0) {
|
||||
this.selectGoodsKeys = keys;
|
||||
this.type = 'detail';
|
||||
getInventoryDetail(inventory_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.detail = res.data;
|
||||
this.$forceUpdate();
|
||||
this.one_judge = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
add(data) {
|
||||
this.$util.redirectTo('/pages/stock/edit_check');
|
||||
},
|
||||
edit() {
|
||||
this.$util.redirectTo('/pages/stock/edit_check', {
|
||||
inventory_id: this.detail.inventory_id
|
||||
});
|
||||
},
|
||||
open(action) {
|
||||
this.$refs[action].open();
|
||||
},
|
||||
close(name) {
|
||||
this.$refs[name].close();
|
||||
},
|
||||
agree() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
inventoryAgree(this.detail.inventory_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.inventory_id);
|
||||
this.close('agreeWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
},
|
||||
refuse() {
|
||||
if (!this.refuseReason) {
|
||||
this.$util.showToast({
|
||||
title: '请输入拒绝理由'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
inventoryRefuse({
|
||||
inventory_id: this.detail.inventory_id,
|
||||
refuse_reason: this.refuseReason
|
||||
}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.inventory_id);
|
||||
this.close('refuseWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
},
|
||||
deleteCheck() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
inventoryDelete(this.detail.inventory_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.list.splice(this.selectGoodsKeys, 1);
|
||||
|
||||
if (this.selectGoodsKeys == 0) {
|
||||
this.selectGoodsKeys = 0;
|
||||
} else {
|
||||
this.selectGoodsKeys -= 1;
|
||||
}
|
||||
|
||||
this.getDetailData(this.list[this.selectGoodsKeys].inventory_id, this
|
||||
.selectGoodsKeys);
|
||||
this.close('deleteWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.kinds-loss {
|
||||
color: red !important;
|
||||
}
|
||||
|
||||
.kinds-profit {
|
||||
color: #15eb26 !important;
|
||||
}
|
||||
|
||||
@import './public/css/orderlist.scss';
|
||||
</style>
|
||||
142
addon/cashier/source/os/pages/stock/edit_allocate.vue
Executable file
142
addon/cashier/source/os/pages/stock/edit_allocate.vue
Executable file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="stock-body">
|
||||
<view class="content-wrap" @click="goodsShow = false">
|
||||
<view class="title">{{ screen.allot_id ? '编辑调拨单' : '添加调拨单' }}</view>
|
||||
<view class="screen-warp form-content">
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
调拨单号
|
||||
</label>
|
||||
<view class="form-inline input">
|
||||
<input type="text" v-model="screen.allot_no" :disabled="screen.allot_id != ''" placeholder="请输入调拨单号" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
调拨方式
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<select-lay :zindex="10" :value="type" name="names" placeholder="请选择调拨方式" :options="screen.allocateTypeList" @selectitem="selectAllocateType"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前门店:</view>
|
||||
<view class="form-inline">{{ globalStoreInfo.store_name }}</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前操作人:</view>
|
||||
<view class="form-inline">{{ userInfo ? userInfo.username : '' }}</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
{{ storeName }}
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<select-lay :zindex="10" :value="screen.store_id" name="names" :placeholder="'请选择' + storeName" :options="screen.storeList" @selectitem="selectStore"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
调拨时间
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<uni-datetime-picker :start="screen.startDate" v-model="screen.birthday" type="timestamp" :clearIcon="false" @change="changeTime" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-wrap">
|
||||
<view class="table-head">
|
||||
<view class="table-tr">
|
||||
<view class="table-th" style="flex: 3;">产品名称/规格/编码</view>
|
||||
<view class="table-th" style="flex: 1;">当前库存</view>
|
||||
<view class="table-th" style="flex: 1;">单位</view>
|
||||
<view class="table-th" style="flex: 2;">成本价</view>
|
||||
<view class="table-th" style="flex: 2;">数量</view>
|
||||
<view class="table-th" style="flex: 1;">总金额</view>
|
||||
<view class="table-th" style="flex: 1;">操作</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-body">
|
||||
<view class="table-tr">
|
||||
<view class="table-td select-goods-input" style="flex: 3;" @click.stop="goodsShow = true">
|
||||
<input type="text" @confirm="getGoodsData($event, -1)" placeholder="请输入产品名称/规格/编码" v-model="params.search_text" />
|
||||
<text class="iconfont icontuodong" @click="getGoodsData({ detail: null }, -1)"></text>
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 2;"></view>
|
||||
<view class="table-td" style="flex: 2;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
</view>
|
||||
<block v-for="(item, index) in goodsList" :key="index">
|
||||
<view class="table-tr" v-if="goodsIdArr.includes(item.sku_id)">
|
||||
<view class="table-td goods-name" style="flex: 3;">{{ item.title }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.real_stock || 0 }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.unit || '件' }}</view>
|
||||
<view class="table-td" style="flex: 2;">{{ item.cost_price || 0 }}</view>
|
||||
<view class="table-td" style="flex: 2;">
|
||||
<input type="number" v-model="item.goods_num" placeholder="请输入数量" @input="calcTotalData" />
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;">
|
||||
{{ (item.goods_num * item.cost_price || 0).toFixed(2) }}
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;">
|
||||
<button type="default" class="delete" @click="delGoods(item.sku_id)">删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="table-tr table-empty" v-if="!goodsIdArr.length">暂无数据,请选择商品数据</view>
|
||||
</view>
|
||||
</view>
|
||||
<stock-goods-dialog v-model="dialogVisible" :params="params" @selectGoods="selectGoods" />
|
||||
|
||||
</view>
|
||||
<view class="action-wrap">
|
||||
<view class="table-total">
|
||||
合计:共{{ totalData.kindsNum }}种产品,合计金额{{ totalData.price.toFixed(2) }}
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<button type="default" class="remark default" @click="$refs.remarkPopup.open()">备注</button>
|
||||
<button type="default" class="stockout-btn" @click="stockOutFn" :loading="isSubmit">确认调拨</button>
|
||||
<button type="default" class="default" @click="backFn">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-popup ref="remarkPopup" type="center">
|
||||
<view class="remark-wrap">
|
||||
<view class="header">
|
||||
<text class="title">备注</text>
|
||||
<text class="iconfont iconguanbi1" @click="$refs.remarkPopup.close()"></text>
|
||||
</view>
|
||||
<view class="body">
|
||||
<textarea v-model="remark" placeholder="填写备注信息" placeholder-class="placeholder-class" />
|
||||
</view>
|
||||
<view class="footer">
|
||||
<button type="default" class="primary-btn" @click="remarkConfirm">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import editAllocate from './public/js/edit_allocate';
|
||||
import stockGoodsDialog from '@/components/stock-goods-dialog/stock-goods-dialog.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
stockGoodsDialog
|
||||
},
|
||||
mixins: [editAllocate]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/editStock.scss';
|
||||
</style>
|
||||
131
addon/cashier/source/os/pages/stock/edit_check.vue
Executable file
131
addon/cashier/source/os/pages/stock/edit_check.vue
Executable file
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="stock-body">
|
||||
<view class="content-wrap" @click="goodsShow = false">
|
||||
<view class="title" v-if="screen.inventory_id != ''">编辑盘点单</view>
|
||||
<view class="title" v-else>添加盘点单</view>
|
||||
<view class="screen-warp form-content">
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
盘点单号
|
||||
</label>
|
||||
<view class="form-inline input">
|
||||
<input type="text" v-model="screen.inventory_no" :disabled="screen.inventory_id != ''" placeholder="请输入入库单号" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
盘点时间
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<uni-datetime-picker v-model="screen.time" type="timestamp" :clearIcon="false" @change="changeTime" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前门店:</view>
|
||||
<view class="form-inline">{{ globalStoreInfo.store_name }}</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前操作人:</view>
|
||||
<view class="form-inline">{{ userInfo ? userInfo.username : '' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips text-color" v-if="globalStoreInfo.stock_config && globalStoreInfo.stock_config.is_audit == 1">
|
||||
说明:待审核状态下只有经办人允许修改,只有变为已审核状态后才会使库存发生变化,已审核状态的单据不允许再修改。</view>
|
||||
<view class="table-wrap">
|
||||
<view class="table-head">
|
||||
<view class="table-tr">
|
||||
<view class="table-th" style="flex: 3;">产品名称/规格/编码</view>
|
||||
<view class="table-th" style="flex: 1;">当前库存</view>
|
||||
<view class="table-th" style="flex: 1;">销售库存</view>
|
||||
<view class="table-th" style="flex: 1;">单位</view>
|
||||
<view class="table-th" style="flex: 2;">实盘数量</view>
|
||||
<view class="table-th" style="flex: 1;">盈亏数量</view>
|
||||
<view class="table-th" style="flex: 1;">操作</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-body">
|
||||
<view class="table-tr">
|
||||
<view class="table-td select-goods-input" style="flex: 3;" @click.stop="goodsShow = true">
|
||||
<input type="text" @confirm="getGoodsData($event, -1)" placeholder="请输入产品名称/规格/编码" v-model="params.search_text" />
|
||||
<text class="iconfont icontuodong" @click="getGoodsData({ detail: null }, -1)"></text>
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 2;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
</view>
|
||||
<block v-for="(item, index) in goodsList" :key="index">
|
||||
<view class="table-tr" v-if="goodsIdArr.includes(item.sku_id)">
|
||||
<view class="table-td goods-name" style="flex: 3;">{{ item.title }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.real_stock || 0 }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.stock || 0 }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.unit || '件' }}</view>
|
||||
<view class="table-td" style="flex: 2;">
|
||||
<input type="number" v-model="item.goods_num" placeholder="请输入数量" @input="calcTotalData" />
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;">{{ parseFloat(item.goods_num - item.stock) || 0 }}</view>
|
||||
<view class="table-td" style="flex: 1;">
|
||||
<button type="default" class="delete" @click="delGoods(item.sku_id)">删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="table-tr table-empty" v-if="!goodsIdArr.length">暂无数据,请选择商品数据</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="action-wrap">
|
||||
<view class="table-total">合计:共{{ totalData.kindsNum }}种商品,盘盈:{{ totalData.upNum }}种,盘亏:{{ totalData.downNum }}种,持平:{{ totalData.sameNum }}种</view>
|
||||
<view class="btn-wrap">
|
||||
<button type="default" class="remark default" @click="$refs.remarkPopup.open()">备注</button>
|
||||
<button type="default" class="stockout-btn" @click="stockOutFn" :loading="isSubmit">盘点</button>
|
||||
<button type="default" class="default" @click="backFn">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<stock-goods-dialog v-model="dialogVisible" :params="params" @selectGoods="selectGoods" />
|
||||
<unipopup ref="tipsPop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">单据保存后将处于"待审核"状态,只有经办人可以编辑或删除等操作!是否确认保存?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.tipsPop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="save">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
<uni-popup ref="remarkPopup" type="center">
|
||||
<view class="remark-wrap">
|
||||
<view class="header">
|
||||
<text class="title">备注</text>
|
||||
<text class="iconfont iconguanbi1" @click="$refs.remarkPopup.close()"></text>
|
||||
</view>
|
||||
<view class="body">
|
||||
<textarea v-model="remark" placeholder="填写备注信息" placeholder-class="placeholder-class" />
|
||||
</view>
|
||||
<view class="footer">
|
||||
<button type="default" class="primary-btn" @click="remarkConfirm">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
<script>
|
||||
import editInventory from './public/js/edit_inventory'
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
import stockGoodsDialog from '@/components/stock-goods-dialog/stock-goods-dialog.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup,
|
||||
stockGoodsDialog
|
||||
},
|
||||
mixins: [editInventory]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/editStock.scss';
|
||||
</style>
|
||||
224
addon/cashier/source/os/pages/stock/manage.vue
Executable file
224
addon/cashier/source/os/pages/stock/manage.vue
Executable file
@@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="manage">
|
||||
<view class="screen-warp common-form">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline">
|
||||
<label class="form-label">商品名称/编码</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="option.search" placeholder="请输入商品名称/编码" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline goods-category">
|
||||
<label class="form-label">商品分类</label>
|
||||
<view class="form-input-inline">
|
||||
<uni-data-picker v-model="option.category_id" :localdata="classifyData.data" popup-title="请选择商品分类"></uni-data-picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="searchFn()">筛选</button>
|
||||
<button type="default" @click="resetFn()">重置</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="manage-table">
|
||||
<uniDataTable url="/stock/storeapi/manage/lists" :option="option" :cols="cols" ref="goodsListTable">
|
||||
<template v-slot:action="dataTable">
|
||||
<view class="action-btn">
|
||||
<text @click="toDetail()">查看流水</text>
|
||||
</view>
|
||||
</template>
|
||||
</uniDataTable>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getGoodsCategory
|
||||
} from '@/api/goods.js';
|
||||
import uniDataPicker from '@/components/uni-data-picker/uni-data-picker.vue';
|
||||
import uniDataTable from '@/components/uni-data-table/uni-data-table.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
uniDataPicker,
|
||||
uniDataTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
classifyData: {
|
||||
data: []
|
||||
},
|
||||
table: {
|
||||
loading: false, //表格加载动画
|
||||
data: []
|
||||
},
|
||||
paging: {
|
||||
pageSize: 9, // 每页数据量
|
||||
pageCurrent: 1, // 当前页
|
||||
total: 0 // 数据总量
|
||||
},
|
||||
option: {
|
||||
search: '',
|
||||
category_id: '',
|
||||
page_size: 10
|
||||
},
|
||||
cols: [
|
||||
{
|
||||
field: 'account_data',
|
||||
width: 20,
|
||||
title: '产品名称',
|
||||
align: 'left',
|
||||
templet: data => {
|
||||
let img = this.$util.img(data.sku_image, { size: 'small' });
|
||||
let html = `
|
||||
<view class="goods-content">
|
||||
<image class="goods-img" src="${img}" mode="aspectFill" />
|
||||
<text class="goods-name multi-hidden">${data.goods_name}</text>
|
||||
</view>
|
||||
`;
|
||||
return html;
|
||||
}
|
||||
}, {
|
||||
width: 19,
|
||||
title: '规格',
|
||||
align: 'center',
|
||||
field: 'spec_name'
|
||||
}, {
|
||||
width: 13,
|
||||
title: '编码',
|
||||
align: 'center',
|
||||
field: 'sku_no'
|
||||
}, {
|
||||
field: 'real_stock',
|
||||
width: 10,
|
||||
title: '库存',
|
||||
align: 'center'
|
||||
}, {
|
||||
field: 'cost_price',
|
||||
width: 12,
|
||||
title: '成本',
|
||||
align: 'center'
|
||||
}, {
|
||||
width: 20,
|
||||
title: '添加时间',
|
||||
templet: data => {
|
||||
return this.$util.timeFormat(data.create_time);
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '操作',
|
||||
align: 'right',
|
||||
action: true
|
||||
}],
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.getCategory();
|
||||
},
|
||||
methods: {
|
||||
// 搜索商品
|
||||
searchFn() {
|
||||
this.$refs.goodsListTable.load({
|
||||
page: 1
|
||||
});
|
||||
},
|
||||
resetFn() {
|
||||
this.option.search = '';
|
||||
this.option.category_id = '';
|
||||
this.$refs.goodsListTable.load({
|
||||
page: 1
|
||||
});
|
||||
},
|
||||
getCategory() {
|
||||
getGoodsCategory({
|
||||
level: 3
|
||||
}).then(res => {
|
||||
|
||||
let data = res.data;
|
||||
if (res.code == 0 && data.length) {
|
||||
this.classifyData.data = this.analyzeCategory(data);
|
||||
this.$forceUpdate();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
analyzeCategory(data) {
|
||||
var arr = data.map((item, index) => {
|
||||
var obj = {};
|
||||
obj.text = item.category_name;
|
||||
obj.value = item.category_id;
|
||||
if (item.child_list && item.child_list.length) {
|
||||
obj.children = this.analyzeCategory(item.child_list);
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
return arr;
|
||||
},
|
||||
toDetail() {
|
||||
this.$util.redirectTo('/pages/stock/records');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.manage {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
padding: 0.15rem;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 筛选面板
|
||||
.screen-warp {
|
||||
padding: 0.15rem;
|
||||
background-color: #f2f3f5;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
.common-form-item .form-label {
|
||||
width: 1.2rem;
|
||||
}
|
||||
|
||||
.common-btn-wrap {
|
||||
margin-left: 1.2rem;
|
||||
}
|
||||
|
||||
.goods-category .form-input-inline {
|
||||
width: 2.8rem;
|
||||
/deep/ .input-value-border{
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.common-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .goods-content {
|
||||
display: flex;
|
||||
.goods-img {
|
||||
margin-right: 0.1rem;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
flex: 1;
|
||||
white-space: pre-wrap;
|
||||
align-self: baseline;
|
||||
}
|
||||
}
|
||||
.action-btn {
|
||||
text {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
271
addon/cashier/source/os/pages/stock/public/css/editStock.scss
Executable file
271
addon/cashier/source/os/pages/stock/public/css/editStock.scss
Executable file
@@ -0,0 +1,271 @@
|
||||
.form-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.store-info {
|
||||
.form-inline {
|
||||
padding-left: 0.05rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 0.1rem;
|
||||
display: flex;
|
||||
|
||||
.form-label {
|
||||
width: 1.3rem;
|
||||
text-align: right;
|
||||
padding-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
width: 2.4rem;
|
||||
line-height: 0.32rem;
|
||||
margin-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
&.input {
|
||||
input {
|
||||
padding: 0 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-input {
|
||||
border-width: 0.01rem;
|
||||
border-style: solid;
|
||||
background-color: #fff;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 0.02rem;
|
||||
padding-left: 0.1rem;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
font-size: 0.14rem;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stock-body{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
.content-wrap {
|
||||
|
||||
padding: 0.15rem;
|
||||
background-color: #fff;
|
||||
@extend %body-overhide;
|
||||
box-sizing: border-box;
|
||||
|
||||
.title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table-wrap {
|
||||
position: relative;
|
||||
margin-top: 40rpx;
|
||||
border: 1rpx solid #dcdfe6;
|
||||
|
||||
.table-head {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
.table-body {
|
||||
@extend %body-overhide;
|
||||
max-height: 6rem;
|
||||
|
||||
.table-tr {
|
||||
&:nth-child(1) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-top: 0.49rem;
|
||||
}
|
||||
|
||||
&:last-of-type .table-td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-tr {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.table-th,
|
||||
.table-td {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.07rem 0.3rem;
|
||||
border-bottom: 0.01rem solid #dcdfe6;
|
||||
border-right: 0.01rem solid #dcdfe6;
|
||||
text-align: center;
|
||||
|
||||
&:last-of-type {
|
||||
border-right: 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&.goods-name {
|
||||
justify-content: flex-start;
|
||||
|
||||
image {
|
||||
width: 0.45rem;
|
||||
height: 0.45rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
margin: 0;
|
||||
font-size: $uni-font-size-base;
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
line-height: 0.32rem;
|
||||
height: 0.32rem;
|
||||
&::after{
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.table-empty {
|
||||
justify-content: center;
|
||||
padding: 0.3rem;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.select-goods-input,
|
||||
.goods-name {
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
|
||||
.icontuodong {
|
||||
font-size: 0.16rem;
|
||||
position: absolute;
|
||||
top: 0.17rem;
|
||||
right: 0.34rem;
|
||||
z-index: 2;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
font-size: $uni-font-size-base !important;
|
||||
border: 0.01rem solid #e6e6e6 !important;
|
||||
height: 0.32rem;
|
||||
}
|
||||
}
|
||||
.action-wrap {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.24rem 0.2rem;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
z-index: 10;
|
||||
.btn-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
min-width: 2.75rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
font-size: $uni-font-size-base;
|
||||
|
||||
&.stockout-btn {
|
||||
margin-right: 0.15rem;
|
||||
background-color: $primary-color;
|
||||
color: #fff;
|
||||
&::after{
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.remark {
|
||||
margin-right: 0.15rem;
|
||||
min-width: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.remark-wrap {
|
||||
width: 6rem;
|
||||
background-color: #fff;
|
||||
border-radius: 0.04rem;
|
||||
box-shadow: 0 0.01rem 0.12rem 0 rgba(0, 0, 0, 0.1);
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 0.15rem;
|
||||
height: 0.45rem;
|
||||
line-height: 0.45rem;
|
||||
border-bottom: 0.01rem solid #e8eaec;
|
||||
|
||||
.iconfont {
|
||||
font-size: $uni-font-size-lg;
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 0.15rem 0.15rem 0.1rem;
|
||||
|
||||
textarea {
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
width: 100%;
|
||||
padding: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
.placeholder-class {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
height: 0.5rem;
|
||||
padding-bottom: 0.05rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button.default {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
}
|
||||
356
addon/cashier/source/os/pages/stock/public/css/orderlist.scss
Executable file
356
addon/cashier/source/os/pages/stock/public/css/orderlist.scss
Executable file
@@ -0,0 +1,356 @@
|
||||
.goodslist {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
.goodslist-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
.goodslist-left {
|
||||
width: 5rem;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.notYet {
|
||||
color: #e6e6e6;
|
||||
font-size: 0.4rem;
|
||||
padding-top: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
.goods-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
.icongengduo1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
.goods-search {
|
||||
width: 100%;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
.search {
|
||||
width: 5.6rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 0.04rem;
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
.iconfont {
|
||||
font-size: 0.16rem;
|
||||
color: #909399;
|
||||
margin-right: 0.11rem;
|
||||
}
|
||||
input {
|
||||
width: 80%;
|
||||
height: 60%;
|
||||
border: none;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.goods-list-scroll {
|
||||
width: 100%;
|
||||
height: calc(100% - 2.08rem);
|
||||
.itemhover {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
.item {
|
||||
padding: 0.2rem;
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.2rem;
|
||||
view {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
view:nth-child(2) {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.add-wastage {
|
||||
padding: 0.24rem 0.2rem;
|
||||
button{
|
||||
width: 100%;
|
||||
line-height: 0.4rem;
|
||||
height: 0.4rem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.goodslist-right {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
padding-bottom: 0.88rem;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
.order-information {
|
||||
width: 100%;
|
||||
height: calc(100% - 0.6rem);
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
// position: relative;
|
||||
|
||||
.order-status {
|
||||
font-size: 0.24rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.24rem;
|
||||
}
|
||||
.order-types {
|
||||
width: 100%;
|
||||
min-height: 1rem;
|
||||
padding: 0.2rem 0.3rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
.type {
|
||||
padding-left: 0.1rem;
|
||||
view {
|
||||
font-size: 0.14rem;
|
||||
.look {
|
||||
color: $primary-color;
|
||||
margin-left: 0.24rem;
|
||||
}
|
||||
}
|
||||
view:nth-child(1) {
|
||||
width: 0.9rem;
|
||||
text-align: right;
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
.message{
|
||||
max-width: 10.7rem;
|
||||
overflow: hidden;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.type1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 0.34rem;
|
||||
}
|
||||
}
|
||||
.goods-info {
|
||||
min-height: 2.7rem;
|
||||
background: #ffffff;
|
||||
padding: 0.2rem 0;
|
||||
box-sizing: border-box;
|
||||
.title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 550;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.table {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 0.2rem;
|
||||
.table-all {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 0.38rem;
|
||||
box-sizing: border-box;
|
||||
.table-td {
|
||||
font-size: 0.14rem;
|
||||
text-align: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
image {
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
}
|
||||
.table-goods-name {
|
||||
image {
|
||||
width: 0.6rem;
|
||||
height: 0.6rem;
|
||||
margin-right: 0.1rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.table-th {
|
||||
height: 0.56rem;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
.table-tr {
|
||||
height: 0.7rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
.table-td {
|
||||
image {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
.content-text {
|
||||
width: 80%;
|
||||
height: 0.4rem;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.total-money-num {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.box {
|
||||
justify-content: flex-end;
|
||||
padding: 0.1rem 0 0 0;
|
||||
color: #333;
|
||||
}
|
||||
.money {
|
||||
text-align: right;
|
||||
width: 1.2rem;
|
||||
color: #333;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
.total {
|
||||
border-top: 0.01rem solid #e6e6e6;
|
||||
margin-top: 0.1rem;
|
||||
|
||||
.money {
|
||||
color: #fe2278;
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.other-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.total-money-num {
|
||||
.member-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
float: left;
|
||||
-ms-flex-negative: 0;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
float: right;
|
||||
view {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
view:nth-child(1) {
|
||||
// transform: translateY(-.01rem);
|
||||
}
|
||||
view:nth-child(2) {
|
||||
color: #fe2278;
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.total-money-num:after {
|
||||
overflow: hidden;
|
||||
content: '';
|
||||
height: 0;
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.order-information::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
.order-information::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.action-box {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: #ffffff;
|
||||
padding: 0.24rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
button {
|
||||
min-width: 0.9rem;
|
||||
height: 0.4rem;
|
||||
font-size: 0.18rem;
|
||||
text-align: center;
|
||||
line-height: 0.4rem;
|
||||
float: right;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
294
addon/cashier/source/os/pages/stock/public/js/edit_allocate.js
Executable file
294
addon/cashier/source/os/pages/stock/public/js/edit_allocate.js
Executable file
@@ -0,0 +1,294 @@
|
||||
import {
|
||||
getAllotNo,
|
||||
getAllocateDetailInEdit,
|
||||
getSkuListForStock,
|
||||
getStoreLists,
|
||||
editAllocate,
|
||||
addAllocate
|
||||
} from '@/api/stock.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
params: {
|
||||
search_text: '', //产品名称
|
||||
temp_store_id: ''
|
||||
},
|
||||
goodsList: [],
|
||||
goodsIdArr: [],
|
||||
goodsShow: false,
|
||||
totalData: {
|
||||
kindsNum: 0,
|
||||
price: 0
|
||||
},
|
||||
isSubmit: false,
|
||||
remark: '',
|
||||
// 筛选面板的时间
|
||||
type: 'in',
|
||||
storeName: '出库门店',
|
||||
screen: {
|
||||
store_id: "",
|
||||
remark: '',
|
||||
allot_id: "",
|
||||
allot_no: "",
|
||||
storeList: [],
|
||||
startDate: '1998-01-30 00:00:00',
|
||||
birthday: '',
|
||||
allocateTypeList: [{
|
||||
label: '调拨入库',
|
||||
value: 'in'
|
||||
},
|
||||
{
|
||||
label: '调拨出库',
|
||||
value: 'out'
|
||||
}
|
||||
]
|
||||
},
|
||||
dialogVisible: false, //弹框
|
||||
inputIndex: -1
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.screen.allot_id = option.allot_id || '';
|
||||
if (this.screen.allot_id) {
|
||||
this.getEditData();
|
||||
} else {
|
||||
this.getDocumentNo()
|
||||
}
|
||||
|
||||
},
|
||||
onShow() {
|
||||
this.screen.birthday = this.$util.timeFormat(Date.parse(new Date()) / 1000);
|
||||
this.getStoreLists()
|
||||
},
|
||||
watch: {
|
||||
goodsIdArr(data) {
|
||||
this.calcTotalData();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getDocumentNo() {//获取单据号
|
||||
getAllotNo().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.screen.allot_no = res.data
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
getEditData() {
|
||||
// 编辑时获取详情
|
||||
getAllocateDetailInEdit(this.screen.allot_id).then(res => {
|
||||
if (res.code >= 0 && res.data) {
|
||||
this.info = res.data;
|
||||
//当前门店id===入库id则是商品入库,门店选择回填为output_store_id出库门店id,否则为商品出库,门店选择回填为input_store_id入库门店id
|
||||
this.type = this.globalStoreInfo.store_id == this.info.input_store_id ? 'in' : 'out'
|
||||
this.screen.store_id = this.type == 'in' ? this.info.output_store_id : this.info.input_store_id
|
||||
this.screen.allot_no = this.info.allot_no
|
||||
this.screen.birthday = this.$util.timeFormat(this.info.allot_time)
|
||||
this.remark = JSON.parse(JSON.stringify(this.info.remark))
|
||||
this.screen.remark = this.info.remark
|
||||
for (let sku_id in this.info.goods_list) {
|
||||
this.info.goods_list[sku_id].title = this.info.goods_list[sku_id].sku_name
|
||||
this.goodsIdArr.push(parseInt(sku_id));
|
||||
this.goodsList.push(this.info.goods_list[sku_id]);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
selectAllocateType(id) {
|
||||
this.type = id == -1 ? '' : this.screen.allocateTypeList[id].value;
|
||||
this.storeName = id == -1 || id == 0 ? '出库门店' : '入库门店';
|
||||
this.params.temp_store_id = this.type == 'in' ? this.screen.store_id : '' //当是入库的时候,需要查出库门店的商品
|
||||
this.goodsIdArr = []
|
||||
this.goodsList = []
|
||||
},
|
||||
selectStore(id) {
|
||||
this.screen.store_id = id == -1 ? '' : this.screen.storeList[id].value;
|
||||
if (this.type == 'in') {
|
||||
this.goodsIdArr = []
|
||||
this.goodsList = []
|
||||
}
|
||||
},
|
||||
changeTime(data) {
|
||||
this.screen.birthday = data;
|
||||
},
|
||||
getGoodsData({detail}, index) { //input回车处理
|
||||
this.inputIndex = index
|
||||
var data = {
|
||||
search: detail ? detail.value : '',
|
||||
}
|
||||
if (this.type == 'in') data.temp_store_id = this.screen.store_id;
|
||||
if (detail && detail.value) {
|
||||
getSkuListForStock(data).then(res => {
|
||||
if (res.code >= 0 && res.data.length == 1) {
|
||||
this.selectGoods(res.data)
|
||||
} else if (res.code >= 0) {
|
||||
this.params.search_text = detail ? detail.value : ''
|
||||
this.dialogVisible = true
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.params.search_text = detail ? detail.value : ''
|
||||
this.dialogVisible = true
|
||||
}
|
||||
},
|
||||
selectGoods(data) { //选择数据
|
||||
data.forEach((el, index) => {
|
||||
el.goods_num = 1;
|
||||
el.goods_price = 0;
|
||||
el.title = el.sku_name + ''
|
||||
//点击或回车行为选择商品后:当为第一行并且展示列表不存在选择的商品push到展示列表,或者不为第一行并且展示列表中不存在时选择的商品除第一条全部push到展示列表
|
||||
if (!this.goodsIdArr.includes(el.sku_id)) {
|
||||
console.log(111);
|
||||
this.goodsIdArr.push(el.sku_id);
|
||||
this.goodsList.push(el);
|
||||
} else {//只要展示列表存在直接累加
|
||||
var elIndex = this.goodsIdArr.indexOf(el.sku_id)
|
||||
if(this.params.search_text){
|
||||
this.goodsList[elIndex].goods_num = parseFloat(this.goodsList[elIndex].goods_num) + 1
|
||||
}
|
||||
}
|
||||
})
|
||||
this.goodsShow = false;
|
||||
this.params.search_text = '';
|
||||
this.$forceUpdate();
|
||||
},
|
||||
delGoods(id) {//删除已选择的商品
|
||||
this.goodsList.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
this.goodsIdArr.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
},
|
||||
getStoreLists() {
|
||||
this.screen.storeList = [];
|
||||
getStoreLists().then(res => {
|
||||
if (res.code >= 0) {
|
||||
let data = res.data;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (this.globalStoreId != data[i]['store_id']) {
|
||||
this.screen.storeList.push({
|
||||
'label': data[i]['store_name'],
|
||||
'value': data[i]['store_id'].toString()
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.screen.storeList.length > 0) {
|
||||
this.screen.store_id = this.screen.storeList[0].value;
|
||||
this.params.temp_store_id = this.screen.store_id
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
stockOutFn() {
|
||||
if (!this.screen.allot_no) {
|
||||
this.$util.showToast({
|
||||
title: "请输入调拨单号"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.type) {
|
||||
this.$util.showToast({
|
||||
title: "请选择调拨方式"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.screen.store_id) {
|
||||
this.$util.showToast({
|
||||
title: "请选择出库门店"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.screen.birthday) {
|
||||
this.$util.showToast({
|
||||
title: "请选择调拨时间"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.goodsIdArr.length) {
|
||||
this.$util.showToast({
|
||||
title: "请选择调拨数据"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检测库存是否填写,且提取数据
|
||||
let isStock = false;
|
||||
let saveData = [];
|
||||
try {
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id)) {
|
||||
if (!parseFloat(item.goods_num || 0)) {
|
||||
isStock = true;
|
||||
let toast = "请输入" + item.sku_name + "的调拨数量";
|
||||
this.$util.showToast({
|
||||
title: toast
|
||||
});
|
||||
throw new Error('end');
|
||||
}
|
||||
var obj = {};
|
||||
obj.goods_num = item.goods_num;
|
||||
obj.goods_price = item.cost_price;
|
||||
obj.goods_sku_id = item.sku_id;
|
||||
saveData.push(obj);
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
if (e.message != "end") throw e;
|
||||
}
|
||||
|
||||
if (isStock) return false;
|
||||
if (this.isSubmit) return false;
|
||||
this.isSubmit = true;
|
||||
let save = this.screen.allot_id ? editAllocate : addAllocate
|
||||
save({
|
||||
allot_type: this.type,
|
||||
allot_id: this.screen.allot_id,
|
||||
temp_store_id: this.screen.store_id,
|
||||
allot_time: this.screen.birthday,
|
||||
remark: this.screen.remark,
|
||||
allot_no: this.screen.allot_no,
|
||||
goods_sku_list: JSON.stringify(saveData)
|
||||
}).then(res => {
|
||||
this.isSubmit = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
setTimeout(() => {
|
||||
this.backFn();
|
||||
}, 500);
|
||||
this.resetFn();
|
||||
}
|
||||
});
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/stock/allocate');
|
||||
},
|
||||
calcTotalData() {//计算商品种类、金额
|
||||
this.totalData.kindsNum = 0;
|
||||
this.totalData.price = 0;
|
||||
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id)) {
|
||||
this.totalData.price += parseFloat(item.cost_price || 0) * parseFloat(item.goods_num || 1);
|
||||
}
|
||||
})
|
||||
this.totalData.kindsNum = this.goodsIdArr.length;
|
||||
},
|
||||
resetFn() {
|
||||
this.goodsIdArr = [];
|
||||
this.goodsShow = false;
|
||||
this.totalData.kindsNum = 0;
|
||||
this.totalData.price = 0;
|
||||
},
|
||||
remarkConfirm() {
|
||||
this.screen.remark = JSON.parse(JSON.stringify(this.remark))
|
||||
this.$refs.remarkPopup.close()
|
||||
}
|
||||
}
|
||||
};
|
||||
235
addon/cashier/source/os/pages/stock/public/js/edit_inventory.js
Executable file
235
addon/cashier/source/os/pages/stock/public/js/edit_inventory.js
Executable file
@@ -0,0 +1,235 @@
|
||||
import {
|
||||
getInventoryNo,
|
||||
getInventoryDetailInEdit,
|
||||
getSkuListForStock,
|
||||
editInventory,
|
||||
addInventory
|
||||
} from '@/api/stock.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
params: {
|
||||
search_text: '', //产品名称
|
||||
},
|
||||
goodsList: [],
|
||||
goodsIdArr: [],
|
||||
goodsShow: false,
|
||||
totalData: {
|
||||
kindsNum: 0,
|
||||
upNum: 0,
|
||||
downNum: 0,
|
||||
sameNum: 0
|
||||
},
|
||||
screen: {
|
||||
inventory_id: '',
|
||||
inventory_no: "",
|
||||
remark: "",
|
||||
stock_json: "",
|
||||
time: ""
|
||||
},
|
||||
remark: '',
|
||||
isSubmit: false,
|
||||
|
||||
inputIndex: -1,
|
||||
dialogVisible: false,
|
||||
info: null
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.screen.inventory_id = option.inventory_id || '';
|
||||
this.screen.time = this.$util.timeFormat(Date.parse(new Date()) / 1000);
|
||||
if (this.screen.inventory_id) {
|
||||
this.getEditData();
|
||||
} else {
|
||||
this.getDocumentNo()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
goodsIdArr(data) {
|
||||
this.calcTotalData();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getDocumentNo() {//获取单据号
|
||||
getInventoryNo().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.screen.inventory_no = res.data
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
getEditData() {
|
||||
getInventoryDetailInEdit(this.screen.inventory_id).then(res => {
|
||||
if (res.code >= 0 && res.data) {
|
||||
this.info = res.data;
|
||||
this.screen.inventory_no = this.info.inventory_no
|
||||
this.screen.time = this.$util.timeFormat(this.info.action_time)
|
||||
this.remark = JSON.parse(JSON.stringify(this.info.remark))
|
||||
for (let sku_id in this.info.goods_list) {
|
||||
this.info.goods_list[sku_id].title = this.info.goods_list[sku_id].sku_name
|
||||
this.goodsIdArr.push(parseInt(sku_id));
|
||||
this.goodsList.push(this.info.goods_list[sku_id]);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getGoodsData({
|
||||
detail
|
||||
}, index) { //input回车处理
|
||||
this.inputIndex = index
|
||||
if (detail && detail.value) {
|
||||
getSkuListForStock({
|
||||
search: detail ? detail.value : ''
|
||||
}).then(res => {
|
||||
if (res.code >= 0 && res.data.length == 1) {
|
||||
this.selectGoods(res.data)
|
||||
} else if (res.code >= 0) {
|
||||
this.params.search_text = detail ? detail.value : ''
|
||||
this.dialogVisible = true
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.params.search_text = detail ? detail.value : ''
|
||||
this.dialogVisible = true
|
||||
}
|
||||
},
|
||||
selectGoods(data) { //选择数据
|
||||
data.forEach((el, index) => {
|
||||
el.goods_num = 1;
|
||||
el.goods_price = 0;
|
||||
el.title = el.sku_name + ''
|
||||
//点击或回车行为选择商品后:当为第一行并且展示列表不存在选择的商品push到展示列表,或者不为第一行并且展示列表中不存在时选择的商品除第一条全部push到展示列表
|
||||
if (!this.goodsIdArr.includes(el.sku_id)) {
|
||||
console.log(111);
|
||||
this.goodsIdArr.push(el.sku_id);
|
||||
this.goodsList.push(el);
|
||||
} else {//只要展示列表存在直接累加
|
||||
var elIndex = this.goodsIdArr.indexOf(el.sku_id)
|
||||
if(this.params.search_text){
|
||||
this.goodsList[elIndex].goods_num = parseFloat(this.goodsList[elIndex].goods_num) + 1
|
||||
}
|
||||
}
|
||||
})
|
||||
this.goodsShow = false;
|
||||
this.params.search_text = '';
|
||||
this.$forceUpdate();
|
||||
},
|
||||
delGoods(id) {
|
||||
this.goodsList.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
this.goodsIdArr.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
},
|
||||
stockOutFn() {
|
||||
if (!this.screen.inventory_no) {
|
||||
this.$util.showToast({
|
||||
title: "请输入盘点单号"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.screen.time) {
|
||||
this.$util.showToast({
|
||||
title: "请选择盘点时间"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.goodsIdArr.length) {
|
||||
this.$util.showToast({
|
||||
title: "请选择盘点数据"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.globalStoreInfo.stock_config && this.globalStoreInfo.stock_config.is_audit == 1) {
|
||||
this.$refs.tipsPop.open();
|
||||
} else {
|
||||
this.save();
|
||||
}
|
||||
},
|
||||
save() {
|
||||
// 检测库存是否填写,且提取数据
|
||||
let isStock = false;
|
||||
let saveData = [];
|
||||
try {
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id)) {
|
||||
if (!parseFloat(item.goods_num || 0)) {
|
||||
isStock = true;
|
||||
let toast = "请输入" + item.sku_name + "的盘点数量";
|
||||
this.$util.showToast({
|
||||
title: toast
|
||||
});
|
||||
throw new Error('end');
|
||||
}
|
||||
var obj = {};
|
||||
obj.goods_num = item.goods_num;
|
||||
obj.goods_sku_id = item.sku_id;
|
||||
saveData.push(obj);
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
if (e.message != "end") throw e;
|
||||
}
|
||||
if (isStock) return false;
|
||||
|
||||
if (this.isSubmit) return false;
|
||||
this.isSubmit = true;
|
||||
this.screen.stock_json = JSON.stringify(saveData)
|
||||
let save = this.screen.inventory_id ? editInventory : addInventory
|
||||
save(this.screen).then(res => {
|
||||
this.isSubmit = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
if (this.$refs.tipsPop) this.$refs.tipsPop.close();
|
||||
setTimeout(() => {
|
||||
this.backFn();
|
||||
}, 500);
|
||||
this.resetFn();
|
||||
}
|
||||
});
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/stock/check');
|
||||
},
|
||||
calcTotalData() {//计算商品总数、盘盈、盘亏等
|
||||
this.totalData.kindsNum = 0;
|
||||
this.totalData.upNum = 0;
|
||||
this.totalData.downNum = 0;
|
||||
this.totalData.sameNum = 0;
|
||||
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id) && item.goods_num) {
|
||||
if ((item.goods_num - item.stock) == 0) {
|
||||
this.totalData.sameNum++;
|
||||
} else if ((item.goods_num - item.stock) > 0) {
|
||||
this.totalData.upNum++;
|
||||
} else if ((item.goods_num - item.stock) < 0) {
|
||||
this.totalData.downNum++;
|
||||
}
|
||||
}
|
||||
})
|
||||
this.totalData.kindsNum = this.goodsIdArr.length;
|
||||
},
|
||||
resetFn() {
|
||||
this.goodsIdArr = [];
|
||||
this.goodsShow = false;
|
||||
this.totalData.kindsNum = 0;
|
||||
this.totalData.countNum = 0;
|
||||
this.totalData.price = 0;
|
||||
},
|
||||
changeTime(data) {
|
||||
this.screen.time = data;
|
||||
},
|
||||
remarkConfirm() {
|
||||
this.screen.remark = JSON.parse(JSON.stringify(this.remark))
|
||||
this.$refs.remarkPopup.close()
|
||||
}
|
||||
}
|
||||
};
|
||||
224
addon/cashier/source/os/pages/stock/public/js/stockin.js
Executable file
224
addon/cashier/source/os/pages/stock/public/js/stockin.js
Executable file
@@ -0,0 +1,224 @@
|
||||
import {
|
||||
getStorageDocumentNo,
|
||||
getStorageDetailInEdit,
|
||||
getSkuListForStock,
|
||||
editStorage
|
||||
} from '@/api/stock.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
params: {
|
||||
search_text: '', //产品名称
|
||||
},
|
||||
goodsList: [], //已选择数据
|
||||
goodsIdArr: [], //已选择数据id
|
||||
goodsShow: false,
|
||||
totalData: {
|
||||
kindsNum: 0,
|
||||
price: 0
|
||||
},
|
||||
screen: {
|
||||
document_id: "",
|
||||
document_no: "",
|
||||
remark: "",
|
||||
stock_json: "",
|
||||
time: ""
|
||||
},
|
||||
remark: '',
|
||||
isSubmit: false, //提交防抖
|
||||
info: null, //详情原始数据
|
||||
dialogVisible: false, //弹框
|
||||
inputIndex: -1
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.screen.document_id = option.document_id || '';
|
||||
this.screen.time = this.$util.timeFormat(Date.parse(new Date()) / 1000);
|
||||
if (this.screen.document_id) {
|
||||
this.getEditData();
|
||||
} else {
|
||||
this.getDocumentNo()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
goodsIdArr(data) {
|
||||
this.calcTotalData();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getDocumentNo() {//获取单据号
|
||||
getStorageDocumentNo().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.screen.document_no = res.data
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
getEditData() { //编辑时获取详情
|
||||
getStorageDetailInEdit(this.screen.document_id).then(res => {
|
||||
if (res.code >= 0 && res.data) {
|
||||
this.info = res.data;
|
||||
this.screen.document_no = this.info.document_no
|
||||
this.screen.time = this.$util.timeFormat(this.info.time)
|
||||
this.remark = JSON.parse(JSON.stringify(this.info.remark))
|
||||
this.screen.remark = this.info.remark
|
||||
for (let sku_id in this.info.goods_list) {
|
||||
this.info.goods_list[sku_id].title = this.info.goods_list[sku_id].sku_name
|
||||
this.goodsIdArr.push(parseInt(sku_id));
|
||||
this.goodsList.push(this.info.goods_list[sku_id]);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getGoodsData({
|
||||
detail
|
||||
}, index) { //input回车处理
|
||||
this.inputIndex = index
|
||||
this.params.search_text = detail ? detail.value : ''
|
||||
if (detail&&detail.value) {
|
||||
getSkuListForStock({
|
||||
search: detail ? detail.value : ''
|
||||
}).then(res => {
|
||||
if (res.code >= 0 && res.data.length == 1) {
|
||||
this.selectGoods(res.data)
|
||||
} else if (res.code >= 0) {
|
||||
this.dialogVisible = true
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.dialogVisible = true
|
||||
}
|
||||
|
||||
},
|
||||
selectGoods(data) { //选择数据
|
||||
data.forEach((el, index) => {
|
||||
el.goods_num = 1;
|
||||
el.goods_price = 0;
|
||||
el.title = el.sku_name + ''
|
||||
//点击或回车行为选择商品后:当为第一行并且展示列表不存在选择的商品push到展示列表,或者不为第一行并且展示列表中不存在时选择的商品除第一条全部push到展示列表
|
||||
if (!this.goodsIdArr.includes(el.sku_id)) {
|
||||
console.log(111);
|
||||
this.goodsIdArr.push(el.sku_id);
|
||||
this.goodsList.push(el);
|
||||
} else {//只要展示列表存在直接累加
|
||||
var elIndex = this.goodsIdArr.indexOf(el.sku_id)
|
||||
if(this.params.search_text){
|
||||
this.goodsList[elIndex].goods_num = parseFloat(this.goodsList[elIndex].goods_num) + 1
|
||||
}
|
||||
}
|
||||
})
|
||||
this.goodsShow = false;
|
||||
this.params.search_text = '';
|
||||
this.$forceUpdate();
|
||||
},
|
||||
delGoods(id) {//删除已选择的商品
|
||||
this.goodsList.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
this.goodsIdArr.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
},
|
||||
stockOutFn() {
|
||||
if (!this.screen.document_no) {
|
||||
this.$util.showToast({
|
||||
title: "请输入入库单号"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.screen.time) {
|
||||
this.$util.showToast({
|
||||
title: "请选择入库时间"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.goodsIdArr.length) {
|
||||
this.$util.showToast({
|
||||
title: "请选择入库数据"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.globalStoreInfo.stock_config && this.globalStoreInfo.stock_config.is_audit == 1) {
|
||||
this.$refs.tipsPop.open();
|
||||
} else {
|
||||
this.save();
|
||||
}
|
||||
},
|
||||
save() {
|
||||
// 检测库存是否填写,且提取数据
|
||||
let isStock = false;
|
||||
let saveData = [];
|
||||
try {
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id)) {
|
||||
if (!parseFloat(item.goods_num || 0)) {
|
||||
isStock = true;
|
||||
let toast = "请输入" + item.sku_name + "的入库数量";
|
||||
this.$util.showToast({
|
||||
title: toast
|
||||
});
|
||||
throw new Error('end');
|
||||
}
|
||||
var obj = {};
|
||||
obj.goods_num = item.goods_num;
|
||||
obj.goods_price = item.goods_price;
|
||||
obj.goods_sku_id = item.sku_id;
|
||||
saveData.push(obj);
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
if (e.message != "end") throw e;
|
||||
}
|
||||
if (isStock) return false;
|
||||
|
||||
if (this.isSubmit) return false;
|
||||
this.isSubmit = true;
|
||||
this.screen.stock_json = JSON.stringify(saveData)
|
||||
editStorage(this.screen).then(res => {
|
||||
this.isSubmit = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
if (this.$refs.tipsPop) this.$refs.tipsPop.close();
|
||||
setTimeout(() => {
|
||||
this.backFn();
|
||||
}, 500);
|
||||
this.resetFn();
|
||||
}
|
||||
});
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/stock/storage');
|
||||
},
|
||||
calcTotalData() {//计算商品种类、金额
|
||||
this.totalData.price = 0;
|
||||
this.totalData.kindsNum = 0;
|
||||
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id)) {
|
||||
this.totalData.price += parseFloat(item.goods_price ?? 0) * parseFloat(item.goods_num ||
|
||||
1);
|
||||
}
|
||||
})
|
||||
this.totalData.kindsNum = this.goodsIdArr.length;
|
||||
},
|
||||
resetFn() {
|
||||
this.goodsIdArr = [];
|
||||
this.goodsShow = false;
|
||||
this.totalData.kindsNum = 0;
|
||||
this.totalData.price = 0;
|
||||
},
|
||||
changeTime(data) {//设置时间
|
||||
this.screen.time = data;
|
||||
},
|
||||
remarkConfirm() {//设置备注
|
||||
this.screen.remark = JSON.parse(JSON.stringify(this.remark))
|
||||
this.$refs.remarkPopup.close()
|
||||
}
|
||||
}
|
||||
};
|
||||
217
addon/cashier/source/os/pages/stock/public/js/stockout.js
Executable file
217
addon/cashier/source/os/pages/stock/public/js/stockout.js
Executable file
@@ -0,0 +1,217 @@
|
||||
import {
|
||||
getWastageDocumentNo,
|
||||
getWastageDetailInEdit,
|
||||
getSkuListForStock,
|
||||
editWastage
|
||||
} from '@/api/stock.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
params: {
|
||||
search_text: '', //产品名称
|
||||
},
|
||||
goodsList: [], //已选择数据
|
||||
goodsIdArr: [], //已选择数据id
|
||||
goodsShow: false,
|
||||
totalData: {
|
||||
kindsNum: 0,
|
||||
price: 0
|
||||
},
|
||||
screen: {
|
||||
document_id: "",
|
||||
document_no: "",
|
||||
remark: "",
|
||||
stock_json: "",
|
||||
time: ""
|
||||
},
|
||||
remark: '',
|
||||
isSubmit: false, //提交防抖
|
||||
info: null, //详情原始数据
|
||||
dialogVisible: false, //弹框
|
||||
inputIndex: -1
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.screen.document_id = option.document_id || 0;
|
||||
this.screen.time = this.$util.timeFormat(Date.parse(new Date()) / 1000);
|
||||
if (this.screen.document_id) {
|
||||
this.getEditData();
|
||||
} else {
|
||||
this.getDocumentNo()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
goodsIdArr(data) {
|
||||
this.calcTotalData();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getDocumentNo() {//获取单据号
|
||||
getWastageDocumentNo().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.screen.document_no = res.data
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
getEditData() {//编辑时获取详情
|
||||
getWastageDetailInEdit(this.screen.document_id).then(res => {
|
||||
if (res.code >= 0 && res.data) {
|
||||
this.info = res.data;
|
||||
this.screen.document_no = this.info.document_no
|
||||
this.screen.time = this.$util.timeFormat(this.info.time)
|
||||
this.remark = JSON.parse(JSON.stringify(this.info.remark))
|
||||
this.screen.remark = this.info.remark
|
||||
for (let sku_id in this.info.goods_list) {
|
||||
this.info.goods_list[sku_id].title = this.info.goods_list[sku_id].sku_name
|
||||
this.goodsIdArr.push(parseInt(sku_id));
|
||||
this.goodsList.push(this.info.goods_list[sku_id]);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getGoodsData({
|
||||
detail
|
||||
}, index) { //input回车处理
|
||||
this.inputIndex = index
|
||||
if (detail && detail.value) {
|
||||
getSkuListForStock({
|
||||
search: detail ? detail.value : ''
|
||||
}).then(res => {
|
||||
if (res.code >= 0 && res.data.length == 1) {
|
||||
this.selectGoods(res.data)
|
||||
} else if (res.code >= 0) {
|
||||
this.params.search_text = detail ? detail.value : ''
|
||||
this.dialogVisible = true
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.params.search_text = detail ? detail.value : ''
|
||||
this.dialogVisible = true
|
||||
}
|
||||
},
|
||||
selectGoods(data) { //选择数据
|
||||
data.forEach((el, index) => {
|
||||
el.goods_num = 1;
|
||||
el.goods_price = 0;
|
||||
el.title = el.sku_name + ''
|
||||
//点击或回车行为选择商品后:当为第一行并且展示列表不存在选择的商品push到展示列表,或者不为第一行并且展示列表中不存在时选择的商品除第一条全部push到展示列表
|
||||
if (!this.goodsIdArr.includes(el.sku_id)) {
|
||||
console.log(111);
|
||||
this.goodsIdArr.push(el.sku_id);
|
||||
this.goodsList.push(el);
|
||||
} else {//只要展示列表存在直接累加
|
||||
var elIndex = this.goodsIdArr.indexOf(el.sku_id)
|
||||
if(this.params.search_text){
|
||||
this.goodsList[elIndex].goods_num = parseFloat(this.goodsList[elIndex].goods_num) + 1
|
||||
}
|
||||
}
|
||||
})
|
||||
this.goodsShow = false;
|
||||
this.params.search_text = '';
|
||||
this.$forceUpdate();
|
||||
},
|
||||
delGoods(id) {//删除已选择的商品
|
||||
this.goodsList.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
this.goodsIdArr.splice(this.goodsIdArr.indexOf(id), 1);
|
||||
},
|
||||
stockOutFn() {
|
||||
if (!this.screen.document_no) {
|
||||
this.$util.showToast({
|
||||
title: "请输入出库单号"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.goodsIdArr.length) {
|
||||
this.$util.showToast({
|
||||
title: "请选择出库数据"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.globalStoreInfo.stock_config && this.globalStoreInfo.stock_config.is_audit == 1) {
|
||||
this.$refs.tipsPop.open();
|
||||
} else {
|
||||
this.save();
|
||||
}
|
||||
},
|
||||
save() {
|
||||
// 检测库存是否填写,且提取数据
|
||||
let isStock = false;
|
||||
let saveData = [];
|
||||
try {
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id)) {
|
||||
if (!parseFloat(item.goods_num || 0)) {
|
||||
isStock = true;
|
||||
let toast = "请输入" + item.sku_name + "的出库数量";
|
||||
this.$util.showToast({
|
||||
title: toast
|
||||
});
|
||||
throw new Error('end');
|
||||
}
|
||||
var obj = {};
|
||||
obj.goods_num = item.goods_num;
|
||||
obj.goods_price = item.cost_price;
|
||||
obj.goods_sku_id = item.sku_id;
|
||||
saveData.push(obj);
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
if (e.message != "end") throw e;
|
||||
}
|
||||
if (isStock) return false;
|
||||
|
||||
if (this.isSubmit) return false;
|
||||
this.isSubmit = true;
|
||||
this.screen.stock_json = JSON.stringify(saveData)
|
||||
editWastage(this.screen).then(res => {
|
||||
this.isSubmit = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
if (this.$refs.tipsPop) this.$refs.tipsPop.close();
|
||||
setTimeout(() => {
|
||||
this.backFn();
|
||||
}, 500);
|
||||
this.resetFn();
|
||||
}
|
||||
});
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/stock/wastage');
|
||||
},
|
||||
calcTotalData() {//计算商品种类、金额
|
||||
this.totalData.price = 0;
|
||||
this.totalData.kindsNum = 0;
|
||||
|
||||
this.goodsList.forEach((item, index) => {
|
||||
if (this.goodsIdArr.includes(item.sku_id)) {
|
||||
this.totalData.price += parseFloat(item.cost_price ?? 0) * parseFloat(item.goods_num || 1);
|
||||
}
|
||||
})
|
||||
this.totalData.kindsNum = this.goodsIdArr.length;
|
||||
|
||||
},
|
||||
resetFn() {
|
||||
this.goodsIdArr = [];
|
||||
this.goodsShow = false;
|
||||
this.totalData.kindsNum = 0;
|
||||
this.totalData.price = 0;
|
||||
},
|
||||
changeTime(data) {
|
||||
this.screen.time = data;
|
||||
},
|
||||
remarkConfirm() {
|
||||
this.screen.remark = JSON.parse(JSON.stringify(this.remark))
|
||||
this.$refs.remarkPopup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
222
addon/cashier/source/os/pages/stock/records.vue
Executable file
222
addon/cashier/source/os/pages/stock/records.vue
Executable file
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="manage">
|
||||
<view class="screen-warp common-form">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline">
|
||||
<label class="form-label">业务类型</label>
|
||||
<view class="form-input-inline">
|
||||
<picker mode="selector" :range="classifyData.data" @change="pickerChange">
|
||||
<view class="form-input">
|
||||
{{ classifyData.currIndex === '' ? '请选择业务类型' : classifyData.data[classifyData.currIndex] }}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline">
|
||||
<label class="form-label">时间</label>
|
||||
<view class="form-input-inline">
|
||||
<picker mode="date" @change="startChange">
|
||||
<view class="form-input">
|
||||
{{ !searchData.start_time ? '请输入开始时间' : searchData.start_time }}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<text class="form-mid">-</text>
|
||||
<view class="form-input-inline">
|
||||
<picker mode="date" @change="endChange">
|
||||
<view class="form-input">{{ !searchData.end_time ? '请输入结束时间' : searchData.end_time }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="searchFn()">筛选</button>
|
||||
<button type="default" @click="resetFn()">重置</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="manage-table">
|
||||
<uni-table ref="table" :loading="table.loading" border stripe emptyText="暂无更多数据">
|
||||
<uni-tr>
|
||||
<uni-th width="100" align="left">时间</uni-th>
|
||||
<uni-th width="100" align="center">商品信息</uni-th>
|
||||
<uni-th width="100" align="center">操作人</uni-th>
|
||||
<uni-th width="100" align="center">业务类型</uni-th>
|
||||
<uni-th width="100" align="center">原库存</uni-th>
|
||||
<uni-th width="100" align="center">库存变化</uni-th>
|
||||
<uni-th width="100" align="center">现库存</uni-th>
|
||||
<uni-th width="100" align="center">备注</uni-th>
|
||||
<uni-th width="50" align="right">操作</uni-th>
|
||||
</uni-tr>
|
||||
<uni-tr v-for="(item, index) in table.data">
|
||||
<uni-td align="left">{{ $util.timeFormat(item.create_time) }}</uni-td>
|
||||
<uni-td align="center">{{ item.goods_sku_name }}</uni-td>
|
||||
<uni-td align="center">{{ item.operater_name }}</uni-td>
|
||||
<uni-td align="center">{{ item.name }}</uni-td>
|
||||
<uni-td align="center">{{ item.before_store_stock }}</uni-td>
|
||||
<uni-td align="center">{{ (item.type == 'input' ? '+' : '-') + item.goods_num }}</uni-td>
|
||||
<uni-td align="center">{{ item.after_store_stock }}</uni-td>
|
||||
<uni-td align="center">{{ item.remark }}</uni-td>
|
||||
<uni-td align="right">
|
||||
<view class="action-btn">
|
||||
<text @click="toDetail(item)">查看</text>
|
||||
</view>
|
||||
</uni-td>
|
||||
</uni-tr>
|
||||
</uni-table>
|
||||
<view class="paging-wrap">
|
||||
<uni-pagination show-icon :page-size="paging.pageSize" :current="paging.pageCurrent" :total="paging.total" @change="paginChange" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getDocumentType,
|
||||
getStockGoodsRecords
|
||||
} from '@/api/stock.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
classifyData: {
|
||||
data: [],
|
||||
idArr: [],
|
||||
currIndex: ''
|
||||
},
|
||||
table: {
|
||||
loading: false, //表格加载动画
|
||||
data: []
|
||||
},
|
||||
paging: {
|
||||
pageSize: 9, // 每页数据量
|
||||
pageCurrent: 1, // 当前页
|
||||
total: 0 // 数据总量
|
||||
},
|
||||
searchData: {
|
||||
type: '',
|
||||
start_time: '',
|
||||
end_time: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.DocumentType();
|
||||
},
|
||||
onShow() {
|
||||
this.getTableData();
|
||||
},
|
||||
methods: {
|
||||
searchFn() {
|
||||
this.table.loading = true;
|
||||
this.paging.pageCurrent = 1;
|
||||
this.getTableData(this.searchData);
|
||||
},
|
||||
resetFn() {
|
||||
this.table.loading = true;
|
||||
this.paging.pageCurrent = 1;
|
||||
this.classifyData.currIndex = '';
|
||||
this.searchData.type = '';
|
||||
this.searchData.start_time = '';
|
||||
this.searchData.end_time = '';
|
||||
this.getTableData(this.searchData);
|
||||
},
|
||||
getTableData(obj = {}) {
|
||||
let data = {
|
||||
page_size: this.paging.pageSize,
|
||||
page: this.paging.pageCurrent
|
||||
};
|
||||
Object.assign(data, obj);
|
||||
getStockGoodsRecords(data).then(res => {
|
||||
this.table.loading = false;
|
||||
if (res.code == 0) {
|
||||
this.table.data = res.data.list;
|
||||
this.$forceUpdate();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
this.paging.total = res.data.count;
|
||||
})
|
||||
},
|
||||
DocumentType() {
|
||||
getDocumentType().then(res => {
|
||||
let data = res.data;
|
||||
if (res.code == 0 && data.length) {
|
||||
data.forEach((item, index) => {
|
||||
this.classifyData.data.push(item.name);
|
||||
this.classifyData.idArr.push(item.key);
|
||||
});
|
||||
this.$forceUpdate();
|
||||
}
|
||||
})
|
||||
},
|
||||
pickerChange(e) {
|
||||
let index = e.detail.value;
|
||||
this.classifyData.currIndex = index;
|
||||
this.searchData.type = this.classifyData.idArr[index];
|
||||
},
|
||||
// 切换分页
|
||||
paginChange(e) {
|
||||
this.table.loading = true;
|
||||
this.paging.pageCurrent = e.current;
|
||||
this.getTableData();
|
||||
},
|
||||
startChange(e) {
|
||||
this.searchData.start_time = e.detail.value;
|
||||
},
|
||||
endChange(e) {
|
||||
let start_time = this.$util.timeTurnTimeStamp(this.searchData.start_time),
|
||||
end_time = this.$util.timeTurnTimeStamp(e.detail.value);
|
||||
|
||||
if (end_time <= start_time) {
|
||||
this.$util.showToast({
|
||||
title: '结束时间不能小于开始时间'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this.searchData.end_time = e.detail.value;
|
||||
},
|
||||
toDetail(data) {
|
||||
let url = data.type == 'input' ? '/pages/stock/storage' : '/pages/stock/wastage';
|
||||
this.$util.redirectTo(url, {
|
||||
id: data.document_no
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.manage {
|
||||
background-color: #fff;
|
||||
padding: 0.15rem;
|
||||
@extend %body-overhide;
|
||||
}
|
||||
|
||||
// 筛选面板
|
||||
.screen-warp {
|
||||
padding: 0.15rem;
|
||||
background-color: #f2f3f5;
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
|
||||
.paging-wrap {
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
// 表格详情
|
||||
.manage-table {
|
||||
|
||||
.action-btn {
|
||||
text {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
133
addon/cashier/source/os/pages/stock/stockin.vue
Executable file
133
addon/cashier/source/os/pages/stock/stockin.vue
Executable file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="stock-body">
|
||||
<view class="content-wrap" @click="goodsShow = false">
|
||||
<view class="title">{{ screen.document_id ? '编辑入库单' : '添加入库单' }}</view>
|
||||
<view class="screen-warp form-content">
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
入库单号
|
||||
</label>
|
||||
<view class="form-inline input">
|
||||
<input type="text" v-model="screen.document_no" :disabled="screen.document_id != ''" placeholder="请输入入库单号" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
入库时间
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<uni-datetime-picker v-model="screen.time" type="timestamp" :clearIcon="false" @change="changeTime" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前门店:</view>
|
||||
<view class="form-inline">{{ globalStoreInfo.store_name }}</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前操作人:</view>
|
||||
<view class="form-inline">{{ userInfo ? userInfo.username : '' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips text-color" v-if="globalStoreInfo.stock_config && globalStoreInfo.stock_config.is_audit == 1">
|
||||
说明:待审核状态下只有经办人允许修改,只有变为已审核状态后才会使库存发生变化,已审核状态的单据不允许再修改。</view>
|
||||
<view class="table-wrap">
|
||||
<view class="table-head">
|
||||
<view class="table-tr">
|
||||
<view class="table-th" style="flex: 3;">产品名称/规格/编码</view>
|
||||
<view class="table-th" style="flex: 1;">当前库存</view>
|
||||
<view class="table-th" style="flex: 1;">单位</view>
|
||||
<view class="table-th" style="flex: 2;">成本价</view>
|
||||
<view class="table-th" style="flex: 2;">数量</view>
|
||||
<view class="table-th" style="flex: 1;">总金额</view>
|
||||
<view class="table-th" style="flex: 1;">操作</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-body">
|
||||
<view class="table-tr">
|
||||
<view class="table-td select-goods-input" style="flex: 3;" @click.stop="goodsShow = true">
|
||||
<input type="text" @confirm="getGoodsData($event, -1)" placeholder="请输入产品名称/规格/编码" v-model="params.search_text" />
|
||||
<text class="iconfont icontuodong" @click="getGoodsData({ detail: null }, -1)"></text>
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 2;"></view>
|
||||
<view class="table-td" style="flex: 2;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
</view>
|
||||
<block v-for="(item, index) in goodsList" :key="index">
|
||||
<view class="table-tr" v-if="goodsIdArr.includes(item.sku_id)">
|
||||
<view class="table-td goods-name" style="flex: 3;">{{ item.title }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.real_stock || 0 }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.unit || '件' }}</view>
|
||||
<view class="table-td" style="flex: 2;">
|
||||
<input type="number" v-model="item.goods_price" placeholder="请输入成本价" @input="calcTotalData" />
|
||||
</view>
|
||||
<view class="table-td" style="flex: 2;">
|
||||
<input type="number" v-model="item.goods_num" placeholder="请输入数量" @input="calcTotalData" />
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;">
|
||||
{{ (item.goods_num * item.goods_price || 0).toFixed(2) }}
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;">
|
||||
<button type="default" class="delete" @click="delGoods(item.sku_id)">删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="table-tr table-empty" v-if="!goodsIdArr.length">暂无数据,请选择商品数据</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="action-wrap">
|
||||
<view class="table-total">合计:共{{ totalData.kindsNum }} 种产品,合计金额:{{ totalData.price.toFixed(2) }}</view>
|
||||
<view class="btn-wrap">
|
||||
<button type="default" class="remark default" @click="$refs.remarkPopup.open()">备注</button>
|
||||
<button type="default" class="stockout-btn" @click="stockOutFn" :loading="isSubmit">入库</button>
|
||||
<button type="default" class="default" @click="backFn">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<stock-goods-dialog v-model="dialogVisible" :params="params" @selectGoods="selectGoods" />
|
||||
<uni-popup ref="tipsPop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">单据保存后将处于"待审核"状态,只有经办人可以编辑或删除等操作!是否确认保存?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.tipsPop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="save">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<uni-popup ref="remarkPopup" type="center">
|
||||
<view class="remark-wrap">
|
||||
<view class="header">
|
||||
<text class="title">备注</text>
|
||||
<text class="iconfont iconguanbi1" @click="$refs.remarkPopup.close()"></text>
|
||||
</view>
|
||||
<view class="body">
|
||||
<textarea v-model="remark" placeholder="填写备注信息" placeholder-class="placeholder-class" />
|
||||
</view>
|
||||
<view class="footer">
|
||||
<button type="default" class="primary-btn" @click="remarkConfirm">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import stockin from "./public/js/stockin"
|
||||
import stockGoodsDialog from '@/components/stock-goods-dialog/stock-goods-dialog.vue';
|
||||
export default {
|
||||
components: {
|
||||
stockGoodsDialog
|
||||
},
|
||||
mixins: [stockin]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/editStock.scss';
|
||||
</style>
|
||||
126
addon/cashier/source/os/pages/stock/stockout.vue
Executable file
126
addon/cashier/source/os/pages/stock/stockout.vue
Executable file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="stock-body">
|
||||
<view class="content-wrap" @click="goodsShow = false">
|
||||
<view class="title">{{ screen.document_id ? '编辑出库单' : '添加出库单' }}</view>
|
||||
<view class="screen-warp form-content">
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
出库单号
|
||||
</label>
|
||||
<view class="form-inline input">
|
||||
<input type="text" v-model="screen.document_no" :disabled="screen.document_id != ''" placeholder="请输入出库单号" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
出库时间
|
||||
</label>
|
||||
<view class="form-inline">
|
||||
<uni-datetime-picker v-model="screen.time" type="timestamp" :clearIcon="false" @change="changeTime" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前门店:</view>
|
||||
<view class="form-inline">{{ globalStoreInfo.store_name }}</view>
|
||||
</view>
|
||||
<view class="form-item store-info">
|
||||
<view class="form-label">当前操作人:</view>
|
||||
<view class="form-inline">{{ userInfo ? userInfo.username : '' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips text-color" v-if="globalStoreInfo.stock_config && globalStoreInfo.stock_config.is_audit == 1">说明:待审核状态下只有经办人允许修改,只有变为已审核状态后才会使库存发生变化,已审核状态的单据不允许再修改。</view>
|
||||
<view class="table-wrap">
|
||||
<view class="table-head">
|
||||
<view class="table-tr">
|
||||
<view class="table-th" style="flex: 3;">产品名称/规格/编码</view>
|
||||
<view class="table-th" style="flex: 1;">当前库存</view>
|
||||
<view class="table-th" style="flex: 1;">单位</view>
|
||||
<view class="table-th" style="flex: 1;">成本</view>
|
||||
<view class="table-th" style="flex: 2;">数量</view>
|
||||
<view class="table-th" style="flex: 1;">操作</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-body">
|
||||
<view class="table-tr">
|
||||
<view class="table-td select-goods-input" style="flex: 3;" @click.stop="goodsShow = true">
|
||||
<input type="text" @confirm="getGoodsData($event, -1)" placeholder="请输入产品名称/规格/编码" v-model="params.search_text" />
|
||||
<text class="iconfont icontuodong" @click="getGoodsData({ detail: null }, -1)"></text>
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
<view class="table-td" style="flex: 2;"></view>
|
||||
<view class="table-td" style="flex: 1;"></view>
|
||||
</view>
|
||||
<block v-for="(item, index) in goodsList" :key="index">
|
||||
<view class="table-tr" v-if="goodsIdArr.includes(item.sku_id)">
|
||||
<view class="table-td goods-name" style="flex: 3;">{{ item.title }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.real_stock || 0 }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.unit || '件' }}</view>
|
||||
<view class="table-td" style="flex: 1;">{{ item.cost_price || '0.00' }}</view>
|
||||
<view class="table-td" style="flex: 2;">
|
||||
<input type="number" v-model="item.goods_num" placeholder="请输入数量" @input="calcTotalData" />
|
||||
</view>
|
||||
<view class="table-td" style="flex: 1;">
|
||||
<button type="default" class="delete" @click="delGoods(item.sku_id)">删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="table-tr table-empty" v-if="!goodsIdArr.length">暂无数据,请选择商品数据</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="action-wrap">
|
||||
<view class="table-total">合计:共{{ totalData.kindsNum }}种产品,合计金额:{{ totalData.price.toFixed(2) }}</view>
|
||||
<view class="btn-wrap">
|
||||
<button type="default" class="remark default" @click="$refs.remarkPopup.open()">备注</button>
|
||||
<button type="default" class="stockout-btn" @click="stockOutFn" :loading="isSubmit">出库</button>
|
||||
<button type="default" class="default" @click="backFn">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<stock-goods-dialog v-model="dialogVisible" :params="params" @selectGoods="selectGoods" />
|
||||
<uni-popup ref="tipsPop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">单据保存后将处于"待审核"状态,只有经办人可以编辑或删除等操作!是否确认保存?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.tipsPop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="save">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<uni-popup ref="remarkPopup" type="center">
|
||||
<view class="remark-wrap">
|
||||
<view class="header">
|
||||
<text class="title">备注</text>
|
||||
<text class="iconfont iconguanbi1" @click="$refs.remarkPopup.close()"></text>
|
||||
</view>
|
||||
<view class="body">
|
||||
<textarea v-model="remark" placeholder="填写备注信息" placeholder-class="placeholder-class" />
|
||||
</view>
|
||||
<view class="footer">
|
||||
<button type="default" class="primary-btn" @click="remarkConfirm">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import stockout from "./public/js/stockout";
|
||||
import stockGoodsDialog from '@/components/stock-goods-dialog/stock-goods-dialog.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
stockGoodsDialog
|
||||
},
|
||||
mixins: [stockout]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './public/css/editStock.scss';
|
||||
</style>
|
||||
354
addon/cashier/source/os/pages/stock/storage.vue
Executable file
354
addon/cashier/source/os/pages/stock/storage.vue
Executable file
@@ -0,0 +1,354 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
入库单查询
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input type="text" v-model="search_text" @input="search" placeholder="搜索入库单号" />
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getListData">
|
||||
<view class="item" @click="getDetailData(item.document_id, index)" v-for="(item, index) in list" :key="index" :class="{ itemhover: selectGoodsKeys == index }">
|
||||
<view class="title">
|
||||
<view>{{ item.document_no }}</view>
|
||||
<view>{{ item.type_name }}</view>
|
||||
</view>
|
||||
<view class="other-info">
|
||||
<view>¥{{ item.document_money }}</view>
|
||||
<view>{{ item.operater_name }}</view>
|
||||
<view>{{ item.status_name }}</view>
|
||||
<view>{{ $util.timeFormat(item.create_time) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="notYet" v-if="!one_judge && !list.length">暂无数据</view>
|
||||
</scroll-view>
|
||||
<view class="add-wastage">
|
||||
<button type="default" class="primary-btn" v-if="globalStoreInfo.stock_type == 'store'" @click="add()">添加入库单</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goodslist-right">
|
||||
<view class="goods-title">入库单详情</view>
|
||||
<view class="order-information" v-if="Object.keys(detail).length">
|
||||
<view class="order-status">基本信息</view>
|
||||
<view class="order-types">
|
||||
<view class="type type1">
|
||||
<view>入库单号:</view>
|
||||
<view>{{ detail.document_no }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>制单人:</view>
|
||||
<view>{{ detail.operater_name || '--' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>制单时间:</view>
|
||||
<view class="message">{{ detail.create_time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>入库时间:</view>
|
||||
<view class="message">{{ detail.time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>单据类型:</view>
|
||||
<view class="message">{{ detail.type_name }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>状态:</view>
|
||||
<view class="message">{{ detail.status_data.name }}</view>
|
||||
</view>
|
||||
|
||||
<view class="type type1" v-if="detail.verifier_name">
|
||||
<view>审核人:</view>
|
||||
<view class="message">{{ detail.verifier_name }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.audit_time">
|
||||
<view>审核时间:</view>
|
||||
<view class="message">{{ detail.audit_time }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.status == -1">
|
||||
<view>拒绝理由:</view>
|
||||
<view class="message">{{ detail.refuse_reason }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>备注:</view>
|
||||
<view class="message">{{ detail.remark }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-info">
|
||||
<view class="title">商品明细</view>
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:45%;justify-content: flex-start;">商品名称/规格/条形码
|
||||
</view>
|
||||
<view class="table-td" style="width:15%">单位</view>
|
||||
<view class="table-td" style="width:10%">数量</view>
|
||||
<view class="table-td" style="width:15%">成本价(元)</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">金额(元)</view>
|
||||
</view>
|
||||
<view class="table-tr table-all" v-for="(item, index) in detail.goods_sku_list_array" :key="index">
|
||||
<view class="table-td table-goods-name" style="width:45%;justify-content: flex-start;">
|
||||
<image :src="$util.img(item.goods_sku_img)" mode="aspectFill" />
|
||||
<text class="multi-hidden">{{ item.goods_sku_name }}</text>
|
||||
</view>
|
||||
<view class="table-td" style="width:15%">{{ item.goods_unit || '件' }}</view>
|
||||
<view class="table-td" style="width:10%">{{ item.goods_num }}</view>
|
||||
<view class="table-td" style="width:15%">{{ item.goods_price }}</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">{{ parseFloat(item.goods_sum).toFixed(2) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="total-money-num">
|
||||
<view class="box">
|
||||
<view>商品种类</view>
|
||||
<view class="money">{{ detail.goods_count }}种</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>商品数量</view>
|
||||
<view class="money">{{ detail.goods_price }}{{ detail.goods_unit }}</view>
|
||||
</view>
|
||||
<view class="box total">
|
||||
<view>合计金额</view>
|
||||
<view class="money">¥{{ parseFloat(detail.goods_total_price).toFixed(2) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="action-box">
|
||||
<!-- 只有经办人才能操作入库单 -->
|
||||
<template v-if="(detail.status == 1 || detail.status == -1) && detail.operater == detail.uid">
|
||||
<button type="primary" class="default-btn" @click="open('deleteWastagePop')">删除</button>
|
||||
<button type="primary" class="default-btn" @click="edit">编辑</button>
|
||||
</template>
|
||||
|
||||
<!-- 只有管理员和拥有单据审核权限的才能审核 -->
|
||||
<template v-if="detail.status == 1 && detail.is_audit == 0">
|
||||
<button type="primary" class="default-btn" @click="open('refuseWastagePop')">审核拒绝</button>
|
||||
<button type="primary" class="primary-btn" @click="open('agreeWastagePop')">审核通过</button>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<block v-else-if="!one_judge && !Object.keys(detail).length">
|
||||
<image class="cart-empty" src="@/static/goods/goods_empty.png" mode="widthFix" />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 同意 -->
|
||||
<unipopup ref="agreeWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要通过该单据吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('agreeWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="agree">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 拒绝 -->
|
||||
<unipopup ref="refuseWastagePop" type="center">
|
||||
<view class="confirm-pop message">
|
||||
<view class="title">
|
||||
拒绝理由
|
||||
<text class="iconfont iconguanbi1" @click="close('refuseWastagePop')"></text>
|
||||
</view>
|
||||
<view class="textarea-box">
|
||||
<textarea v-model="refuseReason" class="textarea" maxlength="200" placeholder="输入请不多于200字"></textarea>
|
||||
</view>
|
||||
<button @click="refuse" type="primary" class="primary-btn btn save">保存</button>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 删除 -->
|
||||
<unipopup ref="deleteWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除该单据吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('deleteWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deleteDocument">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getStorageLists,
|
||||
getStorageDetail,
|
||||
storageAgree,
|
||||
storageRefuse,
|
||||
storageDelete
|
||||
} from '@/api/stock.js';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectGoodsKeys: 0,
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 9,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
//初始时加载详情数据判断
|
||||
one_judge: true,
|
||||
// 订单列表数据
|
||||
list: [],
|
||||
//订单详情数据
|
||||
detail: {},
|
||||
repeatFlag: false,
|
||||
refuseReason: ''
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
if (option.id) {
|
||||
this.search_text = option.id;
|
||||
}
|
||||
this.getListData();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.getListData();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getListData() {
|
||||
getStorageLists({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
search_text: this.search_text
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getDetailData(this.list[0].document_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
getDetailData(document_id, keys = 0) {
|
||||
this.selectGoodsKeys = keys;
|
||||
this.type = 'detail';
|
||||
getStorageDetail(document_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.detail = res.data;
|
||||
this.$forceUpdate();
|
||||
this.one_judge = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.$util.redirectTo('/pages/stock/stockin');
|
||||
},
|
||||
edit() {
|
||||
this.$util.redirectTo('/pages/stock/stockin', {
|
||||
document_id: this.detail.document_id
|
||||
});
|
||||
},
|
||||
open(action) {
|
||||
this.$refs[action].open();
|
||||
},
|
||||
close(name) {
|
||||
this.$refs[name].close();
|
||||
},
|
||||
agree() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
storageAgree(this.detail.document_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.document_id);
|
||||
this.close('agreeWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
},
|
||||
refuse() {
|
||||
if (!this.refuseReason) {
|
||||
this.$util.showToast({
|
||||
title: '请输入拒绝理由'
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
storageRefuse({
|
||||
document_id: this.detail.document_id,
|
||||
refuse_reason: this.refuseReason
|
||||
}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.document_id);
|
||||
this.close('refuseWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
},
|
||||
deleteDocument() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
storageDelete(this.detail.document_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.list.splice(this.selectGoodsKeys, 1);
|
||||
|
||||
if (this.selectGoodsKeys == 0) {
|
||||
this.selectGoodsKeys = 0;
|
||||
} else {
|
||||
this.selectGoodsKeys -= 1;
|
||||
}
|
||||
|
||||
this.getDetailData(this.list[this.selectGoodsKeys].document_id, this.selectGoodsKeys);
|
||||
this.close('deleteWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/orderlist.scss';
|
||||
</style>
|
||||
356
addon/cashier/source/os/pages/stock/wastage.vue
Executable file
356
addon/cashier/source/os/pages/stock/wastage.vue
Executable file
@@ -0,0 +1,356 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="goodslist">
|
||||
<view class="goodslist-box">
|
||||
<view class="goodslist-left">
|
||||
<view class="goods-title">
|
||||
出库单查询
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="goods-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input type="text" v-model="search_text" @input="search" placeholder="搜索出库单号" />
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" class="goods-list-scroll" :show-scrollbar="false" @scrolltolower="getListData">
|
||||
<view class="item" @click="getDetailData(item.document_id, index)" v-for="(item, index) in list" :key="index" :class="{ itemhover: selectGoodsKeys == index }">
|
||||
<view class="title">
|
||||
<view>{{ item.document_no }}</view>
|
||||
<view>{{ item.type_name }}</view>
|
||||
</view>
|
||||
<view class="other-info">
|
||||
<view>¥{{ item.document_money }}</view>
|
||||
<view>{{ item.operater_name }}</view>
|
||||
<view>{{ item.status_name }}</view>
|
||||
<view>{{ $util.timeFormat(item.create_time) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="notYet" v-if="!one_judge && !list.length">暂无数据</view>
|
||||
</scroll-view>
|
||||
<view class="add-wastage">
|
||||
<button type="default" class="primary-btn" v-if="globalStoreInfo.stock_type == 'store'" @click="add()">添加出库单</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goodslist-right">
|
||||
<view class="goods-title">出库单详情</view>
|
||||
<view class="order-information" v-if="Object.keys(detail).length">
|
||||
<view class="order-status">基本信息</view>
|
||||
<view class="order-types">
|
||||
<view class="type type1">
|
||||
<view>出库单号:</view>
|
||||
<view>{{ detail.document_no }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>制单人:</view>
|
||||
<view>{{ detail.operater_name || '--' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>制单时间:</view>
|
||||
<view class="message">{{ detail.create_time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>出库时间:</view>
|
||||
<view class="message">{{ detail.time }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>单据类型:</view>
|
||||
<view class="message">{{ detail.type_name }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>状态:</view>
|
||||
<view class="message">{{ detail.status_data.name }}</view>
|
||||
</view>
|
||||
|
||||
<view class="type type1" v-if="detail.verifier_name">
|
||||
<view>审核人:</view>
|
||||
<view class="message">{{ detail.verifier_name }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.audit_time">
|
||||
<view>审核时间:</view>
|
||||
<view class="message">{{ detail.audit_time }}</view>
|
||||
</view>
|
||||
<view class="type type1" v-if="detail.status == -1">
|
||||
<view>拒绝理由:</view>
|
||||
<view class="message">{{ detail.refuse_reason }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>备注:</view>
|
||||
<view class="message">{{ detail.remark }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-info">
|
||||
<view class="title">商品明细</view>
|
||||
<view class="table">
|
||||
<view class="table-th table-all">
|
||||
<view class="table-td" style="width:45%;justify-content: flex-start;">商品名称/规格/条形码</view>
|
||||
<view class="table-td" style="width:15%">单位</view>
|
||||
<view class="table-td" style="width:10%">数量</view>
|
||||
<view class="table-td" style="width:15%">成本价(元)</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">金额(元)</view>
|
||||
</view>
|
||||
<view class="table-tr table-all" v-for="(item, index) in detail.goods_sku_list_array" :key="index">
|
||||
<view class="table-td table-goods-name" style="width:45%;justify-content: flex-start;">
|
||||
<image :src="$util.img(item.goods_sku_img)" mode="aspectFill" />
|
||||
<text class="multi-hidden">{{ item.goods_sku_name }}</text>
|
||||
</view>
|
||||
<view class="table-td" style="width:15%">{{ item.goods_unit || '件' }}</view>
|
||||
<view class="table-td" style="width:10%">{{ item.goods_num }}</view>
|
||||
<view class="table-td" style="width:15%">{{ item.goods_price }}</view>
|
||||
<view class="table-td" style="width:15%;justify-content: flex-end;">
|
||||
{{ parseFloat(item.goods_sum).toFixed(2) }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="total-money-num">
|
||||
<view class="box">
|
||||
<view>商品种类</view>
|
||||
<view class="money">{{ detail.goods_count }}种</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view>商品数量</view>
|
||||
<view class="money">{{ detail.goods_price }}{{ detail.goods_unit }}</view>
|
||||
</view>
|
||||
<view class="box total">
|
||||
<view>合计金额</view>
|
||||
<view class="money">¥{{ parseFloat(detail.goods_total_price).toFixed(2) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="action-box">
|
||||
<!-- 只有经办人才能操作入库单 -->
|
||||
<template v-if="(detail.status == 1 || detail.status == -1) && detail.operater == detail.uid">
|
||||
<button type="primary" class="default-btn" @click="open('deleteWastagePop')">删除</button>
|
||||
<button type="primary" class="default-btn" @click="edit">编辑</button>
|
||||
</template>
|
||||
|
||||
<!-- 只有管理员和拥有单据审核权限的才能审核 -->
|
||||
<template v-if="detail.status == 1 && detail.is_audit == 0">
|
||||
<button type="primary" class="default-btn" @click="open('refuseWastagePop')">审核拒绝</button>
|
||||
<button type="primary" class="primary-btn" @click="open('agreeWastagePop')">审核通过</button>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<block v-else-if="!one_judge && !Object.keys(detail).length">
|
||||
<image class="cart-empty" src="@/static/goods/goods_empty.png" mode="widthFix"/>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 同意 -->
|
||||
<unipopup ref="agreeWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要通过该单据吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('agreeWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="agree">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 拒绝 -->
|
||||
<unipopup ref="refuseWastagePop" type="center">
|
||||
<view class="confirm-pop message">
|
||||
<view class="title">
|
||||
拒绝理由
|
||||
<text class="iconfont iconguanbi1" @click="close('refuseWastagePop')"></text>
|
||||
</view>
|
||||
<view class="textarea-box">
|
||||
<textarea v-model="refuseReason" class="textarea" maxlength="200" placeholder="输入请不多于200字"></textarea>
|
||||
</view>
|
||||
<button @click="refuse" type="primary" class="primary-btn btn save">保存</button>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
<!-- 删除 -->
|
||||
<unipopup ref="deleteWastagePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除该单据吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="close('deleteWastagePop')">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deleteDocument">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getWastageLists,
|
||||
getWastageDetail,
|
||||
storageAgree,
|
||||
storageRefuse,
|
||||
storageDelete
|
||||
} from '@/api/stock.js';
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectGoodsKeys: 0,
|
||||
//获取订单的页数
|
||||
page: 1,
|
||||
//每次获取订单的条数
|
||||
page_size: 9,
|
||||
// 订单搜索是用到的数据
|
||||
search_text: '',
|
||||
//初始时加载详情数据判断
|
||||
one_judge: true,
|
||||
// 订单列表数据
|
||||
list: [],
|
||||
//订单详情数据
|
||||
detail: {},
|
||||
repeatFlag: false,
|
||||
refuseReason: ''
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
if (option.id) {
|
||||
this.search_text = option.id;
|
||||
}
|
||||
this.getListData();
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.getListData();
|
||||
},
|
||||
/**
|
||||
* 获取订单列表
|
||||
*/
|
||||
getListData() {
|
||||
getWastageLists({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
search_text: this.search_text
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getDetailData(this.list[0].document_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
getDetailData(document_id, keys = 0) {
|
||||
this.selectGoodsKeys = keys;
|
||||
this.type = 'detail';
|
||||
getWastageDetail(document_id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.detail = res.data;
|
||||
this.$forceUpdate();
|
||||
this.one_judge = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
add(data) {
|
||||
this.$util.redirectTo('/pages/stock/stockout');
|
||||
},
|
||||
edit() {
|
||||
this.$util.redirectTo('/pages/stock/stockout', {
|
||||
document_id: this.detail.document_id
|
||||
});
|
||||
},
|
||||
open(action) {
|
||||
this.$refs[action].open();
|
||||
},
|
||||
close(name) {
|
||||
this.$refs[name].close();
|
||||
},
|
||||
agree() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
storageAgree(this.detail.document_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.document_id);
|
||||
this.close('agreeWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
},
|
||||
refuse() {
|
||||
if (!this.refuseReason) {
|
||||
this.$util.showToast({
|
||||
title: '请输入拒绝理由'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
storageRefuse({
|
||||
document_id: this.detail.document_id,
|
||||
refuse_reason: this.refuseReason
|
||||
}).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.search();
|
||||
this.getDetailData(this.detail.document_id);
|
||||
this.close('refuseWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
},
|
||||
deleteDocument() {
|
||||
if (this.repeatFlag) return;
|
||||
this.repeatFlag = true;
|
||||
storageDelete(this.detail.document_id).then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.list.splice(this.selectGoodsKeys, 1);
|
||||
|
||||
if (this.selectGoodsKeys == 0) {
|
||||
this.selectGoodsKeys = 0;
|
||||
} else {
|
||||
this.selectGoodsKeys -= 1;
|
||||
}
|
||||
|
||||
this.getDetailData(this.list[this.selectGoodsKeys].document_id, this
|
||||
.selectGoodsKeys);
|
||||
this.close('deleteWastagePop');
|
||||
}
|
||||
this.repeatFlag = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/orderlist.scss';
|
||||
</style>
|
||||
208
addon/cashier/source/os/pages/store/acccount_record.vue
Executable file
208
addon/cashier/source/os/pages/store/acccount_record.vue
Executable file
@@ -0,0 +1,208 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="manage">
|
||||
<view class="title-back flex items-center cursor-pointer" @click="backFn">
|
||||
<text class="iconfont iconqianhou1"></text>
|
||||
<text class="left">返回</text>
|
||||
<text class="content">|</text>
|
||||
<text>账户记录</text>
|
||||
</view>
|
||||
<view class="screen-warp common-form">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline goods-category">
|
||||
<label class="form-label">来源方式</label>
|
||||
<view class="form-input-inline">
|
||||
<select-lay :zindex="10" :value="screen.from_type" name="names" placeholder="请选择来源方式" :options="fromType" @selectitem="selectFromType"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">发生时间</label>
|
||||
<view class="form-input-inline">
|
||||
<uni-datetime-picker v-model="screen.start_date" type="datetime" placeholder="请选择开始时间" :clearIcon="false" />
|
||||
</view>
|
||||
<view class="form-input-inline">
|
||||
<uni-datetime-picker v-model="screen.end_date" type="datetime" placeholder="请选择结束时间" :clearIcon="false" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">备注</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="screen.remark" placeholder="请输入备注" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="search()">筛选</button>
|
||||
<button type="default" @click="reset()">重置</button>
|
||||
<button type="default" class="screen-btn" @click="exportRecord()">导出</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<uni-data-table url="/store/storeapi/account/pages" :cols="cols" ref="table">
|
||||
<template v-slot:action="data">
|
||||
<view class="common-table-action" v-if="data.value.from_type == 'order' || data.value.from_type == 'refund'"><text @click="detail(data)">查看详情</text></view>
|
||||
</template>
|
||||
</uni-data-table>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getAccountScreen,
|
||||
accountExport,
|
||||
} from '@/api/settlement.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
screen: {
|
||||
page: 1,
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
from_type: '',
|
||||
remark: '',
|
||||
},
|
||||
userList: [],
|
||||
cols: [{
|
||||
width: 12,
|
||||
title: '来源方式',
|
||||
field: 'type_name',
|
||||
align: 'left'
|
||||
}, {
|
||||
width: 12,
|
||||
title: '记录金额',
|
||||
field: 'account_data',
|
||||
align: 'right'
|
||||
}, {
|
||||
width: 18,
|
||||
title: '发生时间',
|
||||
align: 'center',
|
||||
return: data => {
|
||||
return data.create_time ? this.$util.timeFormat(data.create_time) : '';
|
||||
}
|
||||
}, {
|
||||
width: 48,
|
||||
title: '备注',
|
||||
field: 'remark',
|
||||
align: 'left'
|
||||
},{
|
||||
width: 10,
|
||||
title: '操作',
|
||||
action: true, // 表格操作列
|
||||
align: 'right'
|
||||
}],
|
||||
fromType: [],
|
||||
withdrawDetail: null
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getScreenContent();
|
||||
},
|
||||
methods: {
|
||||
detail(data){
|
||||
if(window.location.origin.indexOf('localhost') != -1){
|
||||
window.open(window.location.origin+'/cashregister/pages/order/orderlist?order_no='+data.value.related_info.order_no+'&order_from='+data.value.related_info.order_from,'_blank');
|
||||
}else{
|
||||
window.open(this.$config.baseUrl+'/cashregister/pages/order/orderlist?order_no='+data.value.related_info.order_no+'&order_from='+data.value.related_info.order_from,'_blank');
|
||||
}
|
||||
},
|
||||
switchStoreAfter() {
|
||||
this.screen = {
|
||||
page: 1,
|
||||
start_date: '',
|
||||
end_date: ''
|
||||
};
|
||||
this.$refs.table.load();
|
||||
},
|
||||
search() {
|
||||
this.$refs.table.load(this.screen);
|
||||
},
|
||||
reset() {
|
||||
this.screen = {
|
||||
page: 1,
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
from_type: '',
|
||||
remark: '',
|
||||
};
|
||||
},
|
||||
getScreenContent() {
|
||||
getAccountScreen().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.fromType = Object.keys(res.data.from_type_list).map(index => {
|
||||
return {
|
||||
value: index,
|
||||
label: res.data.from_type_list[index].type_name
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
selectFromType(index) {
|
||||
this.screen.from_type = index == -1 ? '' : this.fromType[index].value;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/store/settlement');
|
||||
},
|
||||
exportRecord() {
|
||||
accountExport(this.screen).then(res => {
|
||||
if (res.code == 0) {
|
||||
window.open(this.$util.img(res.data.path));
|
||||
}else{
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.manage {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
padding: 0.15rem;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 筛选面板
|
||||
.screen-warp {
|
||||
padding: 0.15rem;
|
||||
background-color: #f2f3f5;
|
||||
margin-bottom: 0.15rem;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
flex-direction: column;
|
||||
|
||||
/deep/ .uni-date-x {
|
||||
height: 0.35rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-select-lay {
|
||||
background: #fff;
|
||||
|
||||
.uni-select-lay-select {
|
||||
height: 0.37rem;
|
||||
}
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&>* {
|
||||
margin-right: 0.15rem;
|
||||
}
|
||||
|
||||
.common-btn-wrap button{
|
||||
margin-right: .1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
57
addon/cashier/source/os/pages/store/close.vue
Executable file
57
addon/cashier/source/os/pages/store/close.vue
Executable file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="empty-box">
|
||||
<image src="@/static/cashier/store-close.png" mode="widthFix" />
|
||||
<view>门店已停业</view>
|
||||
<button class="btn" @click="$util.redirectTo('/pages/login/login')">返回</button>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: #ffffff;
|
||||
z-index: 10000;
|
||||
|
||||
image {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
max-height: 3rem;
|
||||
}
|
||||
|
||||
view {
|
||||
text-align: center;
|
||||
font-size: 0.16rem;
|
||||
color: $primary-color;
|
||||
margin: 0 0 0.3rem;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #fff;
|
||||
color: $primary-color;
|
||||
border: 0.01rem solid $primary-color;
|
||||
font-size: 0.165rem;
|
||||
width: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
409
addon/cashier/source/os/pages/store/config.vue
Executable file
409
addon/cashier/source/os/pages/store/config.vue
Executable file
@@ -0,0 +1,409 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="store-config">
|
||||
<view class="common-wrap common-form fixd common-scrollbar">
|
||||
<view class="common-title">门店设置</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">门店名称</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="storeData.store_name" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux-line">门店的名称(招牌)</text>
|
||||
</view>
|
||||
<view class="common-form-item store-img">
|
||||
<label class="form-label">门店图片</label>
|
||||
<view class="form-input-inline upload-box" @click="addImg">
|
||||
<view class="upload" v-if="storeData.store_image">
|
||||
<image :src="$util.img(storeData.store_image)" @error="$util.img(defaultImg.store)" mode="heightFix" />
|
||||
</view>
|
||||
<view class="upload" v-else>
|
||||
<text class="iconfont iconyunshangchuan"></text>
|
||||
<view>点击上传</view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="form-word-aux-line">门店图片在PC及移动端对应页面及列表作为门店标志出现。建议图片尺寸:100 * 100像素,图片格式:jpg、png、jpeg。</text>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">门店类型</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="storeTypeChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="directsale" :checked="storeData.store_type == 'directsale'" />
|
||||
直营店
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="franchise" :checked="storeData.store_type == 'franchise'" />
|
||||
加盟店
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="category.status">
|
||||
<label class="form-label">门店分类</label>
|
||||
<view class="form-input-inline">
|
||||
<uni-data-select v-model="storeData.category_id" :localdata="category.list"></uni-data-select>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="label.length">
|
||||
<label class="form-label">门店标签</label>
|
||||
<view class="form-block">
|
||||
<checkbox-group class="form-checkbox-group" @change="labelChange">
|
||||
<label class="form-checkbox-item" v-for="(item, index) in label">
|
||||
<checkbox :value="item.label_id.toString()" :checked="labelChecked(item)" />
|
||||
{{ item.label_name }}
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">门店电话</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="storeData.telphone" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">门店地址</label>
|
||||
<view class="form-inline">
|
||||
<pick-regions ref="selectArea" :default-regions="defaultRegions" @getRegions="handleGetRegions">
|
||||
<view class="form-input-inline long">
|
||||
<view class="form-input">{{ storeData.full_address }}</view>
|
||||
</view>
|
||||
</pick-regions>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label"></label>
|
||||
<view class="form-inline">
|
||||
<view class="form-input-inline long">
|
||||
<input type="text" v-model="storeData.address" class="form-input" />
|
||||
</view>
|
||||
<view class="form-input-inline short btn" @click="getLatLng()">查找</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item store-img">
|
||||
<label class="form-label">地图定位</label>
|
||||
<view class="form-inline">
|
||||
<view class="map-box">
|
||||
<image src="@/static/location.png" class="map-icon" />
|
||||
<map style="width: 100%; height: 100%;" :latitude="storeData.latitude" :longitude="storeData.longitude" :markers="covers" @markertap="markertap" @regionchange="tap"></map>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="saveFn">保存</button>
|
||||
<button type="default" @click="$util.redirectTo('/pages/store/index')">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
editStore,
|
||||
getAllStoreCategory,
|
||||
getAllStoreLabel
|
||||
} from '@/api/store.js'
|
||||
import { getAddressByName, getTranAddressInfo } from '@/api/address.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeData: {},
|
||||
covers: [{
|
||||
latitude: 39.909,
|
||||
longitude: 116.39742,
|
||||
iconPath: '/static/location.png'
|
||||
}],
|
||||
defaultRegions: [],
|
||||
category: {
|
||||
status: 0,
|
||||
list: []
|
||||
},
|
||||
label: [],
|
||||
labelData: {}
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getLabel();
|
||||
this.getCategory();
|
||||
this.getData();
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
this.storeData = this.$util.deepClone(this.globalStoreInfo);
|
||||
this.storeData.start_time = this.timeFormat(this.storeData.start_time);
|
||||
this.storeData.end_time = this.timeFormat(this.storeData.end_time);
|
||||
this.defaultRegions = [this.storeData.province_id, this.storeData.city_id, this.storeData.district_id];
|
||||
this.$nextTick(() => {
|
||||
this.$refs.selectArea.handleDefaultRegions();
|
||||
});
|
||||
},
|
||||
getLabel() {
|
||||
getAllStoreLabel().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.label = res.data;
|
||||
let labelData = {};
|
||||
res.data.forEach(item => {
|
||||
labelData[item.label_id] = item.label_name;
|
||||
});
|
||||
this.labelData = labelData;
|
||||
}
|
||||
});
|
||||
},
|
||||
getCategory() {
|
||||
getAllStoreCategory().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.category.status = res.data.status;
|
||||
this.category.list = res.data.list.map(item => {
|
||||
return {
|
||||
value: item.category_id,
|
||||
text: item.category_name
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
addImg() {
|
||||
this.$util.upload(1, {
|
||||
path: 'image'
|
||||
}, res => {
|
||||
if (res.length > 0) {
|
||||
this.storeData.store_image = res[0];
|
||||
this.$forceUpdate();
|
||||
}
|
||||
});
|
||||
},
|
||||
tap(e) {
|
||||
if (e.detail && e.detail.centerLocation) {
|
||||
this.storeData.latitude = e.detail.centerLocation.latitude;
|
||||
this.storeData.longitude = e.detail.centerLocation.longitude;
|
||||
this.covers = [{
|
||||
latitude: this.storeData.latitude,
|
||||
longitude: this.storeData.longitude,
|
||||
iconPath: '/static/location.png'
|
||||
}];
|
||||
this.getAddress();
|
||||
this.$forceUpdate();
|
||||
}
|
||||
},
|
||||
handleGetRegions(regions) {
|
||||
this.storeData.full_address = '';
|
||||
this.storeData.full_address += regions[0] != undefined ? regions[0].label : '';
|
||||
this.storeData.full_address += regions[1] != undefined ? '-' + regions[1].label : '';
|
||||
this.storeData.full_address += regions[2] != undefined ? '-' + regions[2].label : '';
|
||||
|
||||
this.storeData.province_id = regions[0] != undefined ? regions[0].value : '';
|
||||
this.storeData.city_id = regions[1] != undefined ? regions[1].value : '';
|
||||
this.storeData.district_id = regions[2] != undefined ? regions[2].value : '';
|
||||
this.defaultRegions = [this.storeData.province_id, this.storeData.city_id, this.storeData.district_id];
|
||||
this.$forceUpdate();
|
||||
this.getLatLng();
|
||||
},
|
||||
//获取详细地址
|
||||
getAddress() {
|
||||
let value = this.storeData.latitude + ',' + this.storeData.longitude;
|
||||
getTranAddressInfo(value).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.storeData.full_address = '';
|
||||
this.storeData.full_address += res.data.province != undefined ? res.data.province : '';
|
||||
this.storeData.full_address += res.data.city != undefined ? '-' + res.data.city : '';
|
||||
this.storeData.full_address += res.data.district != undefined ? '-' + res.data.district : '';
|
||||
this.storeData.address = res.data.address != undefined ? res.data.address : '';
|
||||
|
||||
this.storeData.province_id = res.data.province_id != undefined ? res.data.province_id : '';
|
||||
this.storeData.city_id = res.data.city_id != undefined ? res.data.city_id : '';
|
||||
this.storeData.district_id = res.data.district_id != undefined ? res.data.district_id : '';
|
||||
this.defaultRegions = [this.storeData.province_id, this.storeData.city_id, this.storeData.district_id];
|
||||
this.$forceUpdate();
|
||||
}
|
||||
});
|
||||
},
|
||||
//获取详细地址
|
||||
getLatLng() {
|
||||
let value = this.storeData.full_address + this.storeData.address;
|
||||
getAddressByName(value).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.storeData.latitude = res.data.latitude;
|
||||
this.storeData.longitude = res.data.longitude;
|
||||
}
|
||||
});
|
||||
},
|
||||
storeTypeChange(e) {
|
||||
this.storeData.store_type = e.detail.value;
|
||||
},
|
||||
getSaveData() {
|
||||
let data = Object.assign({}, this.storeData);
|
||||
data.start_time = this.timeTurnTimeStamp(data.start_time);
|
||||
data.end_time = this.timeTurnTimeStamp(data.end_time);
|
||||
data.time_week = this.storeData.time_week.toString();
|
||||
return data;
|
||||
},
|
||||
checkData(data) {
|
||||
if (data.store_name == '') {
|
||||
this.$util.showToast({
|
||||
title: '请输入门店名称'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data.district_id || data.address == '') {
|
||||
this.$util.showToast({
|
||||
title: '请选择门店地址'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
saveFn() {
|
||||
let data = this.getSaveData();
|
||||
if (this.checkData(data)) {
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
editStore(data).then(res => {
|
||||
this.flag = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.$store.dispatch('app/getStoreInfoFn', {
|
||||
callback: () => {
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
timeTurnTimeStamp(_time) {
|
||||
let data = _time.split(':');
|
||||
return data[0] * 3600 + data[1] * 60;
|
||||
},
|
||||
timeFormat(time) {
|
||||
let h = time / 3600;
|
||||
let i = (time % 3600) / 60;
|
||||
h = h < 10 ? '0' + h : h;
|
||||
i = i < 10 ? '0' + i : i;
|
||||
return h + ':' + i;
|
||||
},
|
||||
labelChange(e) {
|
||||
if (e.detail.value.length) {
|
||||
this.storeData.label_id = ',' + e.detail.value.toString() + ',';
|
||||
let labelName = [];
|
||||
e.detail.value.forEach(item => {
|
||||
labelName.push(this.labelData[item]);
|
||||
});
|
||||
this.storeData.label_name = ',' + labelName.toString() + ',';
|
||||
} else {
|
||||
this.storeData.label_id = '';
|
||||
this.storeData.label_name = '';
|
||||
}
|
||||
},
|
||||
labelChecked(item) {
|
||||
let labelIdArr = [];
|
||||
if (!this.storeData.label_id) return false;
|
||||
if (typeof this.storeData.label_id == 'string') labelIdArr = this.storeData.label_id.split(',');
|
||||
return labelIdArr.includes(item.label_id.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.store-config {
|
||||
position: relative;
|
||||
.common-wrap.fixd {
|
||||
padding: 30rpx;
|
||||
height: calc(100vh - 0.4rem);
|
||||
overflow-y: auto;
|
||||
// padding-bottom: 1rem !important;
|
||||
box-sizing: border-box;
|
||||
|
||||
.form-label {
|
||||
width: 1.5rem !important;
|
||||
}
|
||||
|
||||
.form-input-inline /deep/ .uni-select {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.common-btn-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
}
|
||||
|
||||
.form-word-aux-line {
|
||||
margin-left: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
border: 0.01rem dashed #e6e6e6 !important;
|
||||
width: 2.5rem !important;
|
||||
height: 1.2rem !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.upload {
|
||||
text-align: center;
|
||||
color: #5a5a5a;
|
||||
|
||||
.iconfont {
|
||||
font-size: 0.3rem;
|
||||
}
|
||||
|
||||
image {
|
||||
max-width: 100%;
|
||||
height: 1.2rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.store-img {
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.map-box {
|
||||
width: 6.5rem;
|
||||
height: 5rem;
|
||||
position: relative;
|
||||
|
||||
.map-icon {
|
||||
position: absolute;
|
||||
top: calc(50% - 0.36rem);
|
||||
left: calc(50% - 0.18rem);
|
||||
width: 0.36rem;
|
||||
height: 0.36rem;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.form-input {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.form-input-inline.btn {
|
||||
height: 0.37rem;
|
||||
line-height: 0.35rem;
|
||||
box-sizing: border-box;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
}</style>
|
||||
268
addon/cashier/source/os/pages/store/deliver.vue
Executable file
268
addon/cashier/source/os/pages/store/deliver.vue
Executable file
@@ -0,0 +1,268 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="deliverlist">
|
||||
<view class="deliverlist-box">
|
||||
<view class="deliverlist-left">
|
||||
<view class="deliver-title">
|
||||
配送员
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="deliver-list-wrap">
|
||||
<block v-if="list.length > 0">
|
||||
<scroll-view scroll-y="true" class="deliver-list-scroll all-scroll" @scrolltolower="getDeliverList">
|
||||
<view class="item" @click="deliverSelect(item, index)" v-for="(item, index) in list" :key="index" :class="index == selectDeliverKeys ? 'itemhover' : ''">
|
||||
<view class="item-right">
|
||||
<view class="deliver-name">{{ item.deliver_name }}</view>
|
||||
<view class="deliver-money">{{ item.deliver_mobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="!one_judge && list.length == 0">暂无配送员</view>
|
||||
</view>
|
||||
<view class="add-deliver">
|
||||
<button type="default" class="primary-btn" @click="addDeliver">添加配送员</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="deliverlist-right" v-show="!one_judge">
|
||||
<view class="deliver-title">配送员详情</view>
|
||||
<view class="deliver-information">
|
||||
<block v-if="detail && Object.keys(detail).length">
|
||||
<view class="title">基本信息</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>姓名:</view>
|
||||
<view>{{ detail.deliver_name }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>电话:</view>
|
||||
<view>{{ detail.deliver_mobile }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>添加时间:</view>
|
||||
<view>{{ detail.create_time ? $util.timeFormat(detail.create_time) : '--' }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>最后修改时间:</view>
|
||||
<view>{{ detail.modify_time ? $util.timeFormat(detail.modify_time) : '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</block>
|
||||
<block v-else>
|
||||
<image class="cart-empty" src="@/static/goods/goods_empty.png" mode="widthFix" />
|
||||
</block>
|
||||
<view class="button-box" v-if="detail && Object.keys(detail).length">
|
||||
<button class="default-btn" @click="$refs.deletePop.open()">删除</button>
|
||||
<button class="default-btn" @click="openEditDeliverPop(detail.deliver_id)">修改</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<uni-popup ref="deliverpop" type="center">
|
||||
<view class="common-wrap common-form">
|
||||
<view class="common-title">{{ deliverData.deliver_id > 0 ? '修改' : '添加' }}配送员</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
姓名
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="deliverData.deliver_name" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">
|
||||
<text class="required">*</text>
|
||||
手机号
|
||||
</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="number" v-model="deliverData.deliver_mobile" class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux"></text>
|
||||
</view>
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="addDeliverSave">{{ deliverData.deliver_id > 0 ? '修改' : '添加' }}</button>
|
||||
<button type="primary" class="default-btn btn save" @click="addDeliverClose()">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<!-- 删除 -->
|
||||
<uni-popup ref="deletePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.deletePop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deleteDeliverFn(detail.deliver_id)">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<ns-loading :layer-background="{ background: 'rgba(255,255,255,.8)' }" ref="loading"></ns-loading>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
addDeliver,
|
||||
deleteDeliver,
|
||||
editDeliver,
|
||||
getDeliverInfo,
|
||||
getDeliverList
|
||||
} from '@/api/deliver.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
search_text: '',
|
||||
page: 1,
|
||||
// 每次返回数据数
|
||||
page_size: 8,
|
||||
// 第一次请求列表做详情渲染判断
|
||||
one_judge: true,
|
||||
//详情数据
|
||||
detail: {},
|
||||
list: [],
|
||||
selectDeliverKeys: 0,
|
||||
flag: false,
|
||||
deliverData: {
|
||||
deliver_id: 0,
|
||||
deliver_name: '',
|
||||
deliver_mobile: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getDeliverListFn();
|
||||
},
|
||||
methods: {
|
||||
deliverSelect(item, keys) {
|
||||
this.selectDeliverKeys = keys;
|
||||
this.getDeliverDetail(item.deliver_id);
|
||||
},
|
||||
// 搜索员工
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.getDeliverListFn();
|
||||
},
|
||||
addDeliver() {
|
||||
this.$refs.deliverpop.open();
|
||||
},
|
||||
addDeliverClose() {
|
||||
this.$refs.deliverpop.close();
|
||||
},
|
||||
addDeliverSave() {
|
||||
if (this.deliverData.deliver_name == '') {
|
||||
this.$util.showToast({
|
||||
title: '请输入配送员名称'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.deliverData.deliver_mobile == '') {
|
||||
this.$util.showToast({
|
||||
title: '请输入配送员电话'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
let action = '';
|
||||
if (this.deliverData.deliver_id > 0) {
|
||||
action = editDeliver(this.deliverData);
|
||||
} else {
|
||||
action = addDeliver(this.deliverData);
|
||||
}
|
||||
action.then(res => {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code == 0) {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.getDeliverListFn();
|
||||
this.addDeliverClose();
|
||||
this.deliverData = {
|
||||
deliver_id: 0,
|
||||
deliver_name: '',
|
||||
deliver_mobile: ''
|
||||
};
|
||||
}
|
||||
this.flag = false;
|
||||
});
|
||||
},
|
||||
openEditDeliverPop(deliver_id) {
|
||||
getDeliverInfo(deliver_id).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.deliverData = res.data;
|
||||
this.$refs.deliverpop.open();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 请求的列表数据
|
||||
*/
|
||||
getDeliverListFn() {
|
||||
getDeliverList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
this.$refs.loading.hide();
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getDeliverDetail(this.list[0].deliver_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getDeliverDetail(deliver_id) {
|
||||
getDeliverInfo(deliver_id).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.detail = res.data;
|
||||
this.one_judge = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteDeliverFn(deliver_id) {
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
deleteDeliver(deliver_id).then(res => {
|
||||
this.flag = false;
|
||||
if (res.code >= 0) {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.$refs.deletePop.close()
|
||||
this.getDeliverListFn();
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/deliver.scss';
|
||||
</style>
|
||||
228
addon/cashier/source/os/pages/store/index.vue
Executable file
228
addon/cashier/source/os/pages/store/index.vue
Executable file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="">
|
||||
<view class="store-information" v-if="addon.includes('store')">
|
||||
<view class="store-status">门店信息</view>
|
||||
<view class="store-types">
|
||||
<view class="info-left">
|
||||
<view class="type type1">
|
||||
<view>门店名称:</view>
|
||||
<view>{{ storeData.store_name }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>门店电话:</view>
|
||||
<view class="message">{{ storeData.telphone }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>门店类型:</view>
|
||||
<view class="message">{{ storeData.store_type == 'directsale' ? '直营店' : '加盟店' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>门店地址:</view>
|
||||
<view class="message">{{ storeData.full_address }}{{ storeData.address }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-img">
|
||||
<image :src="$util.img(storeData.store_image)" @error="$util.img(defaultImg.store)" mode="aspectFit"/>
|
||||
</view>
|
||||
<view class="btn" @click="$util.redirectTo('/pages/store/config')">设置</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="store-information">
|
||||
<view class="store-status">运营信息</view>
|
||||
<view class="store-types">
|
||||
<view class="info-left">
|
||||
<template v-if="addon.includes('store')">
|
||||
<view class="type type1">
|
||||
<view>营业状态:</view>
|
||||
<view class="message" v-if="storeData.is_frozen == 1">已停业</view>
|
||||
<view class="message" v-else>{{ storeData.status == 1 ? '营业中' : '休息' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>营业时间:</view>
|
||||
<view class="message">{{ storeData.open_date }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>物流配送:</view>
|
||||
<view class="message">{{ storeData.is_express ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>同城配送:</view>
|
||||
<view>{{ storeData.is_o2o ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>门店自提:</view>
|
||||
<view class="message">{{ storeData.is_pickup ? '开启' : '关闭' }}</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>自提日期:</view>
|
||||
<view class="message" v-if="storeData.time_type == 1">
|
||||
<text class="week" v-if="storeData.time_week.includes('1') || storeData.time_week.includes(1)">周一</text>
|
||||
<text class="week" v-if="storeData.time_week.includes('2') || storeData.time_week.includes(2)">周二</text>
|
||||
<text class="week" v-if="storeData.time_week.includes('3') || storeData.time_week.includes(3)">周三</text>
|
||||
<text class="week" v-if="storeData.time_week.includes('4') || storeData.time_week.includes(4)">周四</text>
|
||||
<text class="week" v-if="storeData.time_week.includes('5') || storeData.time_week.includes(5)">周五</text>
|
||||
<text class="week" v-if="storeData.time_week.includes('6') || storeData.time_week.includes(6)">周六</text>
|
||||
<text class="week" v-if="storeData.time_week.includes('0') || storeData.time_week.includes(0)">周日</text>
|
||||
</view>
|
||||
<view class="message" v-if="storeData.time_type == 0">每天</view>
|
||||
</view>
|
||||
<view class="type type1">
|
||||
<view>自提时间:</view>
|
||||
<view class="message">{{ storeData.start_time }}-{{ storeData.end_time }}</view>
|
||||
</view>
|
||||
|
||||
<view class="type type1">
|
||||
<view>库存设置:</view>
|
||||
<view class="message">{{ storeData.stock_type == 'all' ? '总部统一库存' : '门店独立库存' }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="type type1">
|
||||
<view>会员搜索方式:</view>
|
||||
<view class="message">{{ memberSearchWayConfig.way == 'exact' ? '精确搜索' : '列表搜索' }}</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="btn" @click="$util.redirectTo('/pages/store/operate')">设置</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeData: {
|
||||
store_name: '',
|
||||
store_image: '',
|
||||
status: 0,
|
||||
telphone: '',
|
||||
open_date: '',
|
||||
is_o2o: 0,
|
||||
is_pickup: 0,
|
||||
time_type: 0,
|
||||
start_time: '00:00',
|
||||
end_time: '23:59',
|
||||
stock_type: 'all',
|
||||
time_week: '',
|
||||
latitude: 39.909,
|
||||
longitude: 116.39742,
|
||||
province_id: 110000,
|
||||
city_id: 110100,
|
||||
district_id: 110101,
|
||||
address: '',
|
||||
full_address: '',
|
||||
store_type: 'directsale'
|
||||
}
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {
|
||||
this.getData();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['memberSearchWayConfig'])
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
this.storeData = this.$util.deepClone(this.globalStoreInfo);
|
||||
this.storeData.start_time = this.timeFormat(this.storeData.start_time);
|
||||
this.storeData.end_time = this.timeFormat(this.storeData.end_time);
|
||||
},
|
||||
timeFormat(time) {
|
||||
let h = parseInt(time / 3600);
|
||||
let i = parseInt((time % 3600) / 60);
|
||||
h = h < 10 ? '0' + h : h;
|
||||
i = i < 10 ? '0' + i : i;
|
||||
return h + ':' + i;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.store-information {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 0.1rem;
|
||||
margin-bottom: 0.2rem;
|
||||
.store-status {
|
||||
font-size: 0.24rem;
|
||||
font-weight: bold;
|
||||
height: 0.6rem;
|
||||
line-height: 0.6rem;
|
||||
padding-left: 0.2rem;
|
||||
}
|
||||
|
||||
.store-types {
|
||||
width: 100%;
|
||||
background: #ffffff;
|
||||
padding: 0.2rem 0.3rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.info-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.btn {
|
||||
position: absolute;
|
||||
top: 0.2rem;
|
||||
right: 0.2rem;
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-img {
|
||||
margin-top: 0.4rem;
|
||||
|
||||
image {
|
||||
max-width: 1.5rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.type {
|
||||
padding-left: 0.1rem;
|
||||
|
||||
view {
|
||||
font-size: 0.14rem;
|
||||
|
||||
.look {
|
||||
color: $primary-color;
|
||||
margin-left: 0.24rem;
|
||||
}
|
||||
}
|
||||
|
||||
view:nth-child(1) {
|
||||
width: 1rem;
|
||||
text-align: right;
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.type1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 0.34rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.week {
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
</style>
|
||||
569
addon/cashier/source/os/pages/store/operate.vue
Executable file
569
addon/cashier/source/os/pages/store/operate.vue
Executable file
@@ -0,0 +1,569 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="store-operate">
|
||||
<view class="common-wrap common-form fixd common-scrollbar">
|
||||
<view class="common-title">运营设置</view>
|
||||
|
||||
<template v-if="addon.includes('store')">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">门店名称</label>
|
||||
<view class="form-input-inline">
|
||||
<input type="text" v-model="storeData.store_name" disabled class="form-input" />
|
||||
</view>
|
||||
<text class="form-word-aux-line">门店的名称(招牌)</text>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">是否营业</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="statusChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="storeData.status == 1" />
|
||||
是
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="storeData.status == 0" />
|
||||
否
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">营业时间</label>
|
||||
<view class="form-inline">
|
||||
<view class="form-input-inline long">
|
||||
<input type="text" v-model="storeData.open_date" class="form-input" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">物流配送</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="expressChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="storeData.is_express == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="storeData.is_express == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">物流配送只有在连锁门店模式有效,在平台运营模式,按照总店查询</text>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">同城配送</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="o2oChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="storeData.is_o2o == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="storeData.is_o2o == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">开启同城配送需要门店设置配送费用以及配送员</text>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">门店自提</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="pickupChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="storeData.is_pickup == 1" />
|
||||
开启
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="storeData.is_pickup == 0" />
|
||||
关闭
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<block v-if="storeData.is_pickup == 1">
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">自提日期</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="timeTypeChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="storeData.time_type == 0" />
|
||||
每天
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="storeData.time_type == 1" />
|
||||
自定义
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-if="storeData.time_type == 1">
|
||||
<label class="form-label">自提时间</label>
|
||||
<view class="form-block">
|
||||
<checkbox-group class="form-checkbox-group" @change="checkboxChange">
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="1" :checked="storeData.time_week.includes('1') || storeData.time_week.includes(1)" />
|
||||
周一
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="2" :checked="storeData.time_week.includes('2') || storeData.time_week.includes(2)" />
|
||||
周二
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="3" :checked="storeData.time_week.includes('3') || storeData.time_week.includes(3)" />
|
||||
周三
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="4" :checked="storeData.time_week.includes('4') || storeData.time_week.includes(4)" />
|
||||
周四
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="5" :checked="storeData.time_week.includes('5') || storeData.time_week.includes(5)" />
|
||||
周五
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="6" :checked="storeData.time_week.includes('6') || storeData.time_week.includes(6)" />
|
||||
周六
|
||||
</label>
|
||||
<label class="form-checkbox-item">
|
||||
<checkbox value="0" :checked="storeData.time_week.includes('0') || storeData.time_week.includes(0)" />
|
||||
周日
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-form-item" v-for="(item, index) in storeData.delivery_time" :key="index">
|
||||
<label class="form-label">{{ index == 0 ? '时段设置' : '' }}</label>
|
||||
<view class="form-inline">
|
||||
<view class="form-input-inline">
|
||||
<picker mode="time" class="form-input" :value="timeFormat(item.start_time)" @change="bindStartTimeChange($event, index)">
|
||||
<view class="uni-input">{{ item.start_time ? timeFormat(item.start_time) : '00:00' }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<text class="form-mid">-</text>
|
||||
<view class="form-input-inline">
|
||||
<picker mode="time" class="form-input" :value="timeFormat(item.end_time)" @change="bindEndTimeChange($event, index)">
|
||||
<view class="uni-input">{{ item.end_time ? timeFormat(item.end_time) : '' }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="time-action" v-if="index == 0" @click="addDeliveryTime">添加</view>
|
||||
<view class="time-action" v-else @click="deleteDeliveryTime(index)">删除</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">细分时段</label>
|
||||
<view class="form-block">
|
||||
<radio-group @change="timeIntervalChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="30" :checked="storeData.time_interval == 30" />
|
||||
30分钟
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="60" :checked="storeData.time_interval == 60" />
|
||||
一小时
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="90" :checked="storeData.time_interval == 90" />
|
||||
90分钟
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="120" :checked="storeData.time_interval == 120" />
|
||||
两小时
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">提现预约</label>
|
||||
<view class="form-block">
|
||||
<radio-group @change="advanceDayChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="storeData.advance_day === 0" />
|
||||
无需提前
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="storeData.advance_day !== 0" />
|
||||
需提前
|
||||
<input type="number" v-model="storeData.advance_day" class="radio-input" :class="{ disabled: storeData.advance_day === 0 }" :disabled="storeData.advance_day === 0" />
|
||||
天
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">预约提货是否需提前进行预约</text>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">最长预约</label>
|
||||
<view class="form-block">
|
||||
<radio-group @change="mostDayChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="storeData.most_day === 0" />
|
||||
无需提前
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="storeData.most_day !== 0" />
|
||||
可预约
|
||||
<input type="number" v-model="storeData.most_day" class="radio-input" :class="{ disabled: storeData.most_day === 0 }" :disabled="storeData.most_day === 0" />
|
||||
天内
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<text class="form-word-aux-line">预约提货最长可预约多少天内进行提货</text>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">库存设置</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="stockTypeChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="all" :disabled="Boolean(storeData.is_default)" :checked="storeData.stock_type == 'all'" />
|
||||
总部统一库存
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="store" :disabled="Boolean(storeData.is_default)" :checked="storeData.stock_type == 'store'" />
|
||||
门店独立库存
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="common-form-item">
|
||||
<label class="form-label">会员搜索方式</label>
|
||||
<view class="form-inline">
|
||||
<radio-group @change="memberSearchWayChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="exact" :checked="memberSearchWay == 'exact'" />
|
||||
精确搜索
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="list" :checked="memberSearchWay == 'list'" />
|
||||
列表搜索
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="saveFn">保存</button>
|
||||
<button type="default" @click="$util.redirectTo('/pages/store/index')">返回</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
editStore
|
||||
} from '@/api/store.js'
|
||||
import {setMemberSearchWayConfig} from '@/api/config.js'
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeData: {},
|
||||
covers: [{
|
||||
latitude: 39.909,
|
||||
longitude: 116.39742,
|
||||
iconPath: '/static/location.png'
|
||||
}],
|
||||
defaultRegions: [],
|
||||
memberSearchWay: 'exact'
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {
|
||||
this.getData();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['memberSearchWayConfig'])
|
||||
},
|
||||
watch: {
|
||||
memberSearchWayConfig: {
|
||||
immediate: true,
|
||||
handler(newVal, oldVal) {
|
||||
if(newVal) {
|
||||
this.memberSearchWay = newVal.way;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
this.storeData = this.$util.deepClone(this.globalStoreInfo);
|
||||
this.storeData.start_time = this.timeFormat(this.storeData.start_time);
|
||||
this.storeData.end_time = this.timeFormat(this.storeData.end_time);
|
||||
if(this.memberSearchWayConfig) {
|
||||
this.memberSearchWay = this.memberSearchWayConfig.way;
|
||||
}
|
||||
},
|
||||
statusChange(e) {
|
||||
this.storeData.status = e.detail.value;
|
||||
},
|
||||
o2oChange(e) {
|
||||
this.storeData.is_o2o = e.detail.value;
|
||||
},
|
||||
expressChange(e) {
|
||||
this.storeData.is_express = e.detail.value;
|
||||
},
|
||||
pickupChange(e) {
|
||||
this.storeData.is_pickup = e.detail.value;
|
||||
},
|
||||
timeTypeChange(e) {
|
||||
this.storeData.time_type = e.detail.value;
|
||||
},
|
||||
bindStartTimeChange(e, index) {
|
||||
this.storeData.delivery_time[index].start_time = this.timeTurnTimeStamp(e.detail.value);
|
||||
},
|
||||
bindEndTimeChange(e, index) {
|
||||
this.storeData.delivery_time[index].end_time = this.timeTurnTimeStamp(e.detail.value);
|
||||
},
|
||||
stockTypeChange(e) {
|
||||
this.storeData.stock_type = e.detail.value;
|
||||
},
|
||||
memberSearchWayChange(e) {
|
||||
this.memberSearchWay = e.detail.value;
|
||||
},
|
||||
timeIntervalChange(e) {
|
||||
this.storeData.time_interval = e.detail.value;
|
||||
},
|
||||
checkboxChange(e) {
|
||||
this.storeData.time_week = e.detail.value;
|
||||
},
|
||||
advanceDayChange(e) {
|
||||
if (e.detail.value == 1) this.storeData.advance_day = '';
|
||||
else this.storeData.advance_day = 0;
|
||||
},
|
||||
mostDayChange(e) {
|
||||
if (e.detail.value == 1) this.storeData.most_day = '';
|
||||
else this.storeData.most_day = 0;
|
||||
},
|
||||
getSaveData() {
|
||||
let data = Object.assign({}, this.storeData);
|
||||
data.start_time = this.timeTurnTimeStamp(data.start_time);
|
||||
data.end_time = this.timeTurnTimeStamp(data.end_time);
|
||||
data.time_week = this.storeData.time_week.toString();
|
||||
data.advance_day = parseInt(this.storeData.advance_day);
|
||||
data.most_day = parseInt(this.storeData.most_day);
|
||||
data.delivery_time = JSON.stringify(this.storeData.delivery_time);
|
||||
return data;
|
||||
},
|
||||
checkData(data) {
|
||||
if (data.is_pickup) {
|
||||
let deliveryTimeVerify = true;
|
||||
for (let i = 0; i < this.storeData.delivery_time.length; i++) {
|
||||
let time = this.storeData.delivery_time[i];
|
||||
if (time.end_time == 0) {
|
||||
this.$util.showToast({
|
||||
title: '请选择时段结束时间'
|
||||
});
|
||||
deliveryTimeVerify = false;
|
||||
break;
|
||||
}
|
||||
if (parseInt(time.start_time) > parseInt(time.end_time)) {
|
||||
this.$util.showToast({
|
||||
title: '时段结束时间不能小于开始时间'
|
||||
});
|
||||
deliveryTimeVerify = false;
|
||||
break;
|
||||
}
|
||||
if ((parseInt(time.end_time) - parseInt(time.start_time)) / 60 < parseInt(data.time_interval)) {
|
||||
this.$util.showToast({
|
||||
title: '时段时间间隔不能小于' + data.time_interval + '分钟'
|
||||
});
|
||||
deliveryTimeVerify = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!deliveryTimeVerify) return deliveryTimeVerify;
|
||||
if (isNaN(data.advance_day)) {
|
||||
this.$util.showToast({
|
||||
title: '提前预约时间格式错误'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (data.advance_day < 0) {
|
||||
this.$util.showToast({
|
||||
title: '提前预约时间不能为负数'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (isNaN(data.most_day)) {
|
||||
this.$util.showToast({
|
||||
title: '最长可预约时间格式错误'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (data.most_day < 0) {
|
||||
this.$util.showToast({
|
||||
title: '最长可预约时间不能为负数'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (data.most_day > 15) {
|
||||
this.$util.showToast({
|
||||
title: '最长可预约时间不能超过15天'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
saveFn() {
|
||||
let data = this.getSaveData();
|
||||
|
||||
setMemberSearchWayConfig({
|
||||
way : this.memberSearchWay
|
||||
}).then((res)=>{
|
||||
if(res.code >= 0){
|
||||
this.$store.dispatch('app/getMemberSearchWayConfigFn');
|
||||
|
||||
if (!this.addon.includes('store')) {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (this.addon.includes('store')) {
|
||||
|
||||
if (this.checkData(data)) {
|
||||
if (this.flag) return false;
|
||||
this.flag = true;
|
||||
editStore(data).then(res => {
|
||||
this.flag = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
if (res.code >= 0) {
|
||||
this.$store.dispatch('app/getStoreInfoFn', {
|
||||
callback: () => {
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
timeTurnTimeStamp(_time) {
|
||||
let data = _time.split(':');
|
||||
return data[0] * 3600 + data[1] * 60;
|
||||
},
|
||||
timeFormat(time) {
|
||||
let h = parseInt(time / 3600);
|
||||
let i = parseInt((time % 3600) / 60);
|
||||
h = h < 10 ? '0' + h : h;
|
||||
i = i < 10 ? '0' + i : i;
|
||||
return h + ':' + i;
|
||||
},
|
||||
addDeliveryTime() {
|
||||
if (this.storeData.delivery_time.length >= 3) {
|
||||
this.$util.showToast({
|
||||
title: '最多添加三个时段'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this.storeData.delivery_time.push({
|
||||
start_time: 0,
|
||||
end_time: 0
|
||||
});
|
||||
},
|
||||
deleteDeliveryTime(index) {
|
||||
this.storeData.delivery_time.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.store-operate {
|
||||
position: relative;
|
||||
.common-btn-wrap {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0.24rem 0.2rem;
|
||||
}
|
||||
.common-wrap {
|
||||
padding: 30rpx;
|
||||
height: calc(100vh - 0.4rem);
|
||||
overflow-y: auto;
|
||||
// padding-bottom: 1rem !important;
|
||||
box-sizing: border-box;
|
||||
|
||||
.form-label {
|
||||
padding: .09rem .15rem;
|
||||
text-align: right;
|
||||
width: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.store-img {
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.map-box {
|
||||
width: 6.5rem;
|
||||
height: 5rem;
|
||||
position: relative;
|
||||
|
||||
.map-icon {
|
||||
position: absolute;
|
||||
top: calc(50% - 0.36rem);
|
||||
left: calc(50% - 0.18rem);
|
||||
width: 0.36rem;
|
||||
height: 0.36rem;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.form-input {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.form-input-inline.btn {
|
||||
height: 0.37rem;
|
||||
line-height: 0.35rem;
|
||||
box-sizing: border-box;
|
||||
border: 0.01rem solid #e6e6e6;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.radio-input {
|
||||
width: 0.6rem;
|
||||
height: 0.35rem;
|
||||
line-height: 0.35rem;
|
||||
padding: 0 0.1rem;
|
||||
margin: 0 0.1rem;
|
||||
border: 0.01rem solid #eee;
|
||||
|
||||
&.disabled {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
.time-action {
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}</style>
|
||||
317
addon/cashier/source/os/pages/store/public/css/deliver.scss
Executable file
317
addon/cashier/source/os/pages/store/public/css/deliver.scss
Executable file
@@ -0,0 +1,317 @@
|
||||
.deliverlist {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
|
||||
.deliverlist-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
|
||||
.deliverlist-left {
|
||||
width: 5rem;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.notYet {
|
||||
color: #e6e6e6;
|
||||
font-size: 0.4rem;
|
||||
margin-top: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.add-deliver {
|
||||
padding: 0.24rem 0.2rem;
|
||||
background: #fff;
|
||||
|
||||
button {
|
||||
height: .4rem;
|
||||
line-height: .4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.deliver-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.icongengduo1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.deliver-list-wrap {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.deliver-list-scroll {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.itemhover {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
|
||||
image {
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 0.6rem;
|
||||
|
||||
.deliver-name {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.deliver-money {
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deliverlist-right {
|
||||
width: 0;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.deliver-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.icongengduo1, .iconguanbi1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.deliver-information {
|
||||
width: 100%;
|
||||
padding: 0.2rem 0.2rem 0.88rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
height: calc(100% - 0.6rem);
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.32rem;
|
||||
}
|
||||
|
||||
.title2 {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
|
||||
.information-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.box-left {
|
||||
width: 5rem;
|
||||
|
||||
.information {
|
||||
width: 100%;
|
||||
padding-left: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
view:nth-child(1) {
|
||||
width: 1.3rem;
|
||||
margin-right: 0.16rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
width: 74%;
|
||||
margin-right: 0.23rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.information:last-child {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.deliver-img {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
height: 2.6rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-all {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 0.38rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-td {
|
||||
font-size: 0.14rem;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.table-th {
|
||||
height: 0.56rem;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.table-tb {
|
||||
width: 100%;
|
||||
height: calc(100% - 0.56rem);
|
||||
|
||||
.table-tr {
|
||||
height: 0.7rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-td {
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
|
||||
image {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.deliver-information::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
.deliver-information::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.button-box {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 0.24rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
button {
|
||||
min-width: 0.9rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
margin: 0;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
|
||||
.common-wrap {
|
||||
padding: 30rpx;
|
||||
margin: 30rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.common-title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
543
addon/cashier/source/os/pages/store/settlement.vue
Executable file
543
addon/cashier/source/os/pages/store/settlement.vue
Executable file
@@ -0,0 +1,543 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="page-height uni-flex uni-column">
|
||||
<view class="uni-flex uni-row">
|
||||
<view class="account-wrap">
|
||||
<view class="head-title">账户概览</view>
|
||||
<view class="account-item">
|
||||
<view @click="$util.redirectTo('/pages/store/acccount_record')">
|
||||
<view class="account-title">待结算金额(元)</view>
|
||||
<view class="money">
|
||||
{{ globalStoreInfo.account | moneyFormat }}
|
||||
<text class="iconfont iconqianhou2"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="action">
|
||||
<button type="default" class="primary-btn" v-if="
|
||||
globalStoreInfo.is_settlement == 1 &&
|
||||
withdrawConfig.is_settlement == 1 &&
|
||||
withdrawConfig.period_type == 4 &&
|
||||
globalStoreInfo.account > 0 &&
|
||||
parseFloat(globalStoreInfo.account) >= parseFloat(withdrawConfig.withdraw_least)
|
||||
" @click="applyWithdraw">
|
||||
申请结算
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-flex uni-row sub-bottom">
|
||||
<view class="account-item" @click="$util.redirectTo('/pages/store/settlement_record')">
|
||||
<view class="account-title">打款中金额(元)</view>
|
||||
<view class="money">
|
||||
{{ globalStoreInfo.account_apply | moneyFormat }}
|
||||
<text class="iconfont iconqianhou2"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="account-item" @click="$util.redirectTo('/pages/store/settlement_record')">
|
||||
<view class="account-title">已打款金额(元)</view>
|
||||
<view class="money">
|
||||
{{ globalStoreInfo.account_withdraw | moneyFormat }}
|
||||
<text class="iconfont iconqianhou2"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-wrap">
|
||||
<view class="head-title">结算账户</view>
|
||||
<view class="info-content">
|
||||
<block v-if="globalStoreInfo.is_settlement == 1 && withdrawConfig.is_settlement == 1">
|
||||
<view class="info-text">
|
||||
结算方式:
|
||||
<text>总部收款,</text>
|
||||
<text v-if="withdrawConfig.period_type == 1">每日自动结算</text>
|
||||
<text v-if="withdrawConfig.period_type == 2">每周自动结算</text>
|
||||
<text v-if="withdrawConfig.period_type == 3">每月自动结算</text>
|
||||
<text v-if="withdrawConfig.period_type == 4">门店申请结算</text>
|
||||
</view>
|
||||
<view class="info-text">账户类型:{{ bankType[globalStoreInfo.bank_type] }}</view>
|
||||
<block v-if="globalStoreInfo.bank_type == 1">
|
||||
<view class="info-text">微信名:{{ globalStoreInfo.bank_user_name }}</view>
|
||||
</block>
|
||||
<block v-if="globalStoreInfo.bank_type == 2">
|
||||
<view class="info-text">真实姓名:{{ globalStoreInfo.bank_user_name }}</view>
|
||||
<view class="info-text">支付宝账号:{{ globalStoreInfo.bank_type_account }}</view>
|
||||
</block>
|
||||
<block v-if="globalStoreInfo.bank_type == 3">
|
||||
<view class="info-text">开户行:{{ globalStoreInfo.bank_type_name }}</view>
|
||||
<view class="info-text">户头:{{ globalStoreInfo.bank_user_name }}</view>
|
||||
<view class="info-text">账户:{{ globalStoreInfo.bank_type_account }}</view>
|
||||
</block>
|
||||
</block>
|
||||
<view class="empty" v-else>无需结算</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="settlement-record uni-flex uni-column">
|
||||
<view class="head-title">结算记录</view>
|
||||
<view class="record-wrap common-scrollbar">
|
||||
<uni-data-table url="/store/storeapi/withdraw/page" :cols="cols" ref="table" :pagesize="8">
|
||||
<template v-slot:action="data">
|
||||
<view class="common-table-action" v-if="data.value.transfer_type == 'wechatpay' && data.value.status == 1 && newWithdrawDetail && newWithdrawDetail.transfer_type" @click="showQRcode(data)"><text >收款</text></view>
|
||||
<view class="common-table-action"><text @click="detail(data)">查看详情</text></view>
|
||||
</template>
|
||||
</uni-data-table>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<uni-popup ref="applyWithdraw" type="center">
|
||||
<view class="apply-withdraw">
|
||||
<view class="title">
|
||||
本次可结算金额为
|
||||
<text class="money" v-if="globalStoreInfo">{{ globalStoreInfo.account | moneyFormat }}</text>
|
||||
元,是否申请结算?
|
||||
</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="primary-btn btn" @click="apply">确定</button>
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.applyWithdraw.close()">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<uni-popup ref="detailPopup">
|
||||
<view class="pop-box">
|
||||
<view class="pop-header">
|
||||
<view class="">结算详情</view>
|
||||
<view class="pop-header-close" @click="$refs.detailPopup.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content common-scrollbar" v-if="withdrawDetail">
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">结算信息</view>
|
||||
<view class="pop-contents-text">结算编号:{{ withdrawDetail.withdraw_no }}</view>
|
||||
<view class="pop-contents-text">结算状态:{{ withdrawDetail.status_name }}</view>
|
||||
<view class="pop-contents-text" v-if="withdrawDetail.status == -1 || withdrawDetail.status == -2">拒绝理由:{{ withdrawDetail.refuse_reason }}</view>
|
||||
<view class="pop-contents-text">结算金额:{{ withdrawDetail.money | moneyFormat }}</view>
|
||||
<view class="pop-contents-text">结算方式:{{ withdrawDetail.transfer_type_name }}</view>
|
||||
<view class="pop-contents-text">结算类型:{{ withdrawDetail.settlement_type_name }}</view>
|
||||
<view class="pop-contents-text">结算申请时间:{{ withdrawDetail.apply_time | timeFormat }}</view>
|
||||
<view class="pop-contents-text" v-if="withdrawDetail.transfer_type == 'bank'">银行名称:{{ withdrawDetail.bank_name }}</view>
|
||||
<view class="pop-contents-text">结算收款账号:{{ withdrawDetail.account_number }}</view>
|
||||
<view class="pop-contents-text">结算方式:{{ withdrawDetail.transfer_type_name }}</view>
|
||||
<view class="pop-contents-text">真实姓名:{{ withdrawDetail.realname }}</view>
|
||||
<view class="pop-contents-text flex" v-if="withdrawDetail.voucher_img">转账凭证:<image class="voucher-img" :src="$util.img(withdrawDetail.voucher_img)" /></view>
|
||||
<view class="pop-contents-text" v-if="withdrawDetail.voucher_desc">凭证说明:{{ withdrawDetail.voucher_desc }}</view>
|
||||
</view>
|
||||
<view class="pop-content-item" v-if="withdrawDetail.settlement_type != 'apply'">
|
||||
<view class="pop-content-text">周期结算</view>
|
||||
<view class="pop-contents-text">周期结算编号:{{ withdrawDetail.settlement_info.settlement_no }}</view>
|
||||
<view class="pop-contents-text">周期开始时间:{{ withdrawDetail.settlement_info.start_time }}</view>
|
||||
<view class="pop-contents-text">周期结束时间:{{ withdrawDetail.settlement_info.end_time }}</view>
|
||||
<view class="pop-contents-text">结算订单总额:{{ withdrawDetail.settlement_info.order_money }}</view>
|
||||
<view class="pop-contents-text">结算总分销佣金:{{ withdrawDetail.settlement_info.commission }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<uni-popup ref="qrcodePopup">
|
||||
<view class="pop-box qrcode">
|
||||
<view class="pop-header">
|
||||
<view class="">扫码收款</view>
|
||||
<view class="pop-header-close" @click="closeQrcodePopup()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content common-scrollbar qrcode-area" >
|
||||
<image class="qr-img" :src="qrcode" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
applyWithdraw,
|
||||
getWithdrawConfig,
|
||||
withdrawDetail,
|
||||
withdrawConfig,
|
||||
transferCode
|
||||
} from '@/api/settlement.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
bankType: {
|
||||
1: '微信',
|
||||
2: '支付宝',
|
||||
3: '银行卡'
|
||||
},
|
||||
withdrawConfig: {
|
||||
is_settlement: 0
|
||||
},
|
||||
cols: [{
|
||||
width: 12,
|
||||
title: '结算方式',
|
||||
field: 'transfer_type_name',
|
||||
align: 'left'
|
||||
}, {
|
||||
width: 12,
|
||||
title: '结算类型',
|
||||
field: 'settlement_type_name',
|
||||
align: 'left'
|
||||
}, {
|
||||
width: 12,
|
||||
title: '结算金额',
|
||||
align: 'left',
|
||||
return: data => {
|
||||
return this.$util.moneyFormat(data.money);
|
||||
}
|
||||
}, {
|
||||
width: 12,
|
||||
title: '结算状态',
|
||||
field: 'status_name'
|
||||
}, {
|
||||
width: 15,
|
||||
title: '申请时间',
|
||||
align: 'center',
|
||||
return: data => {
|
||||
return data.apply_time ? this.$util.timeFormat(data.apply_time) : '';
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '转账时间',
|
||||
align: 'center',
|
||||
return: data => {
|
||||
return data.transfer_time ? this.$util.timeFormat(data.transfer_time) : '';
|
||||
}
|
||||
}, {
|
||||
width: 20,
|
||||
title: '操作',
|
||||
action: true, // 表格操作列
|
||||
align: 'right'
|
||||
}],
|
||||
isRepeat: false,
|
||||
withdrawDetail: null,
|
||||
newWithdrawDetail: null,
|
||||
qrcode: '',
|
||||
timer: null,
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
},
|
||||
onShow() {
|
||||
this.getWithdrawConfigFn();
|
||||
this.getNewWithdrawConfigFn();
|
||||
this.$store.dispatch('app/getStoreInfoFn');
|
||||
},
|
||||
methods: {
|
||||
closeQrcodePopup() {
|
||||
this.$refs.qrcodePopup.close()
|
||||
clearInterval(this.timer);
|
||||
this.$refs.table.load();
|
||||
},
|
||||
checkWithdrawStatus(withdraw_id) {
|
||||
this.timer = setInterval(() => {
|
||||
withdrawDetail(withdraw_id).then(res => {
|
||||
if (res.code == 0) {
|
||||
if(res.data.status == 2){
|
||||
clearInterval(this.timer);
|
||||
this.$refs.qrcodePopup.close();
|
||||
this.$refs.table.load();
|
||||
}
|
||||
}else{
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
},
|
||||
showQRcode(data) {
|
||||
this.qrcode = '';
|
||||
transferCode({
|
||||
id: data.value.withdraw_id,
|
||||
}).then(res => {
|
||||
this.qrcode = res.data;
|
||||
this.$refs.qrcodePopup.open();
|
||||
this.checkWithdrawStatus(data.value.withdraw_id);
|
||||
})
|
||||
},
|
||||
getNewWithdrawConfigFn() {
|
||||
withdrawConfig().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.newWithdrawDetail = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
switchStoreAfter() {
|
||||
this.$refs.table.load();
|
||||
},
|
||||
getWithdrawConfigFn() {
|
||||
getWithdrawConfig().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.withdrawConfig = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
applyWithdraw() {
|
||||
this.$refs.applyWithdraw.open();
|
||||
},
|
||||
apply() {
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
applyWithdraw(this.globalStoreInfo.account).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$store.dispatch('app/getStoreInfoFn');
|
||||
this.$refs.applyWithdraw.close();
|
||||
this.$refs.table.load();
|
||||
setTimeout(() => {
|
||||
this.isRepeat = false;
|
||||
}, 500);
|
||||
} else {
|
||||
this.isRepeat = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
detail(data) {
|
||||
withdrawDetail(data.value.withdraw_id).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.withdrawDetail = res.data;
|
||||
this.$refs.detailPopup.open('center');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.account-wrap {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
padding: 0.15rem;
|
||||
margin-right: 0.15rem;
|
||||
background: #fff;
|
||||
|
||||
.head-title {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.account-item {
|
||||
padding: 0.2rem 0;
|
||||
cursor: pointer;
|
||||
|
||||
.account-title {
|
||||
font-size: 0.14rem;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.money {
|
||||
font-size: 0.2rem;
|
||||
font-weight: bold;
|
||||
margin-top: 0.15rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.iconqianhou2 {
|
||||
line-height: 1;
|
||||
color: #bbb;
|
||||
margin-left: 0.05rem;
|
||||
}
|
||||
}
|
||||
|
||||
.action {
|
||||
margin-top: 0.3rem;
|
||||
height: 0.4rem;
|
||||
button {
|
||||
display: inline-block;
|
||||
margin-right: 0.1rem;
|
||||
width: auto;
|
||||
min-width: 0.8rem;
|
||||
line-height: 0.4rem;
|
||||
height: 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sub-bottom {
|
||||
border-top: 0.01rem solid #f5f5f5;
|
||||
|
||||
.account-item {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
width: 30vw;
|
||||
padding: 0.15rem;
|
||||
background: #fff;
|
||||
|
||||
.head-title {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.info-text {
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.settlement-record {
|
||||
padding: 0.15rem;
|
||||
flex: 1;
|
||||
height: 0;
|
||||
margin: 0.15rem 0;
|
||||
background: #fff;
|
||||
|
||||
.head-title {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.record-wrap {
|
||||
padding-top: 0.15rem;
|
||||
flex: 1;
|
||||
height: 0;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.pop-box {
|
||||
background: #ffffff;
|
||||
width: 5rem;
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
&.qrcode{
|
||||
width: 2.8rem;
|
||||
height: auto;
|
||||
}
|
||||
.pop-header {
|
||||
width: 100%;
|
||||
padding: 0 0.15rem 0 0.2rem;
|
||||
height: 0.5rem;
|
||||
// width: 3.5rem;
|
||||
margin: 0 auto;
|
||||
line-height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #f0f0f0;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
border-radius: 0.02rem 0.2rem 0 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pop-header-close {
|
||||
cursor: pointer;
|
||||
|
||||
text {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.qrcode-area{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.2rem 0.2rem;
|
||||
.qr-img{
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.pop-contents {
|
||||
margin-top: 0.3rem;
|
||||
width: 3rem;
|
||||
height: 0.8rem;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.pop-content-item {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-items {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-text {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.pop-contents-text {
|
||||
margin-left: 0.4rem;
|
||||
font-weight: normal;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.apply-withdraw {
|
||||
width: 3.8rem;
|
||||
border-radius: 0.06rem;
|
||||
background: #ffffff;
|
||||
padding: 0.6rem 0.15rem 0.2rem 0.15rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.title {
|
||||
font-size: 0.16rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.money {
|
||||
font-weight: bold;
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 0.3rem;
|
||||
|
||||
.btn {
|
||||
width: auto;
|
||||
padding: 0 0.3rem;
|
||||
margin: 0;
|
||||
height: 0.35rem;
|
||||
}
|
||||
|
||||
.btn:last-child {
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.voucher-img {
|
||||
width: 1.5rem;
|
||||
}
|
||||
</style>
|
||||
349
addon/cashier/source/os/pages/store/settlement_record.vue
Executable file
349
addon/cashier/source/os/pages/store/settlement_record.vue
Executable file
@@ -0,0 +1,349 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="manage">
|
||||
<view class="title-back flex items-center cursor-pointer" @click="backFn">
|
||||
<text class="iconfont iconqianhou1"></text>
|
||||
<text class="left">返回</text>
|
||||
<text class="content">|</text>
|
||||
<text>结算记录</text>
|
||||
</view>
|
||||
<view class="screen-warp common-form">
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline goods-category">
|
||||
<label class="form-label">结算方式</label>
|
||||
<view class="form-input-inline">
|
||||
<select-lay :zindex="10" :value="screen.transfer_type" name="names" placeholder="请选择结算方式" :options="transferType" @selectitem="selectTransferType"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline goods-category">
|
||||
<label class="form-label">结算类型</label>
|
||||
<view class="form-input-inline">
|
||||
<select-lay :zindex="9" :value="screen.settlement_type" name="names" placeholder="请选择结算类型" :options="settlementType" @selectitem="selectSettlementType"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline goods-category">
|
||||
<label class="form-label">结算状态</label>
|
||||
<view class="form-input-inline">
|
||||
<select-lay :zindex="9" :value="screen.status" name="names" placeholder="请选择结算状态" :options="status" @selectitem="selectStatus"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<label class="form-label">申请时间</label>
|
||||
<view class="form-input-inline">
|
||||
<uni-datetime-picker v-model="screen.start_time" type="datetime" placeholder="请选择开始时间" :clearIcon="false" />
|
||||
</view>
|
||||
<view class="form-input-inline">
|
||||
<uni-datetime-picker v-model="screen.end_time" type="datetime" placeholder="请选择结束时间" :clearIcon="false" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-form-item">
|
||||
<view class="form-inline common-btn-wrap">
|
||||
<button type="default" class="screen-btn" @click="search()">筛选</button>
|
||||
<button type="default" @click="reset()">重置</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<uni-data-table url="/store/storeapi/withdraw/page" :cols="cols" ref="table">
|
||||
<template v-slot:action="data">
|
||||
<view class="common-table-action"><text @click="detail(data)">查看详情</text></view>
|
||||
</template>
|
||||
</uni-data-table>
|
||||
|
||||
<uni-popup ref="detailPopup">
|
||||
<view class="pop-box">
|
||||
<view class="pop-header">
|
||||
<view class="pop-header-text">结算详情</view>
|
||||
<view class="pop-header-close" @click="$refs.detailPopup.close()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-content common-scrollbar" v-if="withdrawDetail">
|
||||
<view class="pop-content-item">
|
||||
<view class="pop-content-text">结算信息</view>
|
||||
<view class="pop-contents-text">结算编号:{{ withdrawDetail.withdraw_no }}</view>
|
||||
<view class="pop-contents-text">结算状态:{{ withdrawDetail.status_name }}</view>
|
||||
<view class="pop-contents-text">结算金额:{{ withdrawDetail.money | moneyFormat }}</view>
|
||||
<view class="pop-contents-text">结算方式:{{ withdrawDetail.transfer_type_name }}</view>
|
||||
<view class="pop-contents-text">结算类型:{{ withdrawDetail.settlement_type_name }}</view>
|
||||
<view class="pop-contents-text">结算申请时间:{{ withdrawDetail.apply_time | timeFormat }}</view>
|
||||
<view class="pop-contents-text" v-if="withdrawDetail.transfer_type == 'bank'">银行名称:{{ withdrawDetail.bank_name }}</view>
|
||||
<view class="pop-contents-text">结算收款账号:{{ withdrawDetail.account_number }}</view>
|
||||
<view class="pop-contents-text">结算方式:{{ withdrawDetail.transfer_type_name }}</view>
|
||||
<view class="pop-contents-text">真实姓名:{{ withdrawDetail.realname }}</view>
|
||||
</view>
|
||||
<view class="pop-content-item" v-if="withdrawDetail.settlement_type != 'apply'">
|
||||
<view class="pop-content-text">周期结算</view>
|
||||
<view class="pop-contents-text">周期结算编号:{{ withdrawDetail.settlement_info.settlement_no }}</view>
|
||||
<view class="pop-contents-text">周期开始时间:{{ withdrawDetail.settlement_info.start_time }}</view>
|
||||
<view class="pop-contents-text">周期结束时间:{{ withdrawDetail.settlement_info.end_time }}</view>
|
||||
<view class="pop-contents-text">结算订单总额:{{ withdrawDetail.settlement_info.order_money }}</view>
|
||||
<view class="pop-contents-text">结算总分销佣金:{{ withdrawDetail.settlement_info.commission }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getWithdrawScreen,
|
||||
withdrawDetail
|
||||
} from '@/api/settlement.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
screen: {
|
||||
page: 1,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
withdraw_no: '',
|
||||
transfer_type: '',
|
||||
settlement_type: '',
|
||||
status: 'all'
|
||||
},
|
||||
userList: [],
|
||||
cols: [{
|
||||
width: 12,
|
||||
title: '结算方式',
|
||||
field: 'transfer_type_name',
|
||||
align: 'left'
|
||||
}, {
|
||||
width: 12,
|
||||
title: '结算类型',
|
||||
field: 'settlement_type_name',
|
||||
align: 'left'
|
||||
}, {
|
||||
width: 12,
|
||||
title: '结算金额',
|
||||
align: 'left',
|
||||
return: data => {
|
||||
return this.$util.moneyFormat(data.money);
|
||||
}
|
||||
}, {
|
||||
width: 12,
|
||||
title: '结算状态',
|
||||
field: 'status_name'
|
||||
}, {
|
||||
width: 15,
|
||||
title: '申请时间',
|
||||
align: 'center',
|
||||
return: data => {
|
||||
return data.apply_time ? this.$util.timeFormat(data.apply_time) : '';
|
||||
}
|
||||
}, {
|
||||
width: 15,
|
||||
title: '转账时间',
|
||||
align: 'center',
|
||||
return: data => {
|
||||
return data.transfer_time ? this.$util.timeFormat(data.transfer_time) : '';
|
||||
}
|
||||
}, {
|
||||
width: 20,
|
||||
title: '操作',
|
||||
action: true, // 表格操作列
|
||||
align: 'right'
|
||||
}],
|
||||
status: [],
|
||||
settlementType: [],
|
||||
transferType: [],
|
||||
withdrawDetail: null
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getScreenContent();
|
||||
},
|
||||
methods: {
|
||||
switchStoreAfter() {
|
||||
this.screen = {
|
||||
page: 1,
|
||||
start_time: '',
|
||||
end_time: ''
|
||||
};
|
||||
this.$refs.table.load();
|
||||
},
|
||||
search() {
|
||||
this.$refs.table.load(this.screen);
|
||||
},
|
||||
reset() {
|
||||
this.screen = {
|
||||
page: 1,
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
withdraw_no: '',
|
||||
transfer_type: '',
|
||||
settlement_type: '',
|
||||
status: 'all'
|
||||
};
|
||||
},
|
||||
getScreenContent() {
|
||||
getWithdrawScreen().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.status = Object.keys(res.data.status).map(index => {
|
||||
return {
|
||||
value: index,
|
||||
label: res.data.status[index]
|
||||
};
|
||||
});
|
||||
this.settlementType = Object.keys(res.data.settlement_type).map(index => {
|
||||
return {
|
||||
value: index,
|
||||
label: res.data.settlement_type[index]
|
||||
};
|
||||
});
|
||||
this.transferType = Object.keys(res.data.transfer_type_list).map(index => {
|
||||
return {
|
||||
value: index,
|
||||
label: res.data.transfer_type_list[index]
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
selectTransferType(index) {
|
||||
this.screen.transfer_type = index == -1 ? '' : this.transferType[index].value;
|
||||
},
|
||||
selectSettlementType(index) {
|
||||
this.screen.settlement_type = index == -1 ? '' : this.settlementType[index].value;
|
||||
},
|
||||
selectStatus(index) {
|
||||
this.screen.status = index == -1 ? 'all' : this.status[index].value;
|
||||
},
|
||||
detail(data) {
|
||||
withdrawDetail(data.value.withdraw_id).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.withdrawDetail = res.data;
|
||||
this.$refs.detailPopup.open('center');
|
||||
}
|
||||
});
|
||||
},
|
||||
backFn() {
|
||||
this.$util.redirectTo('/pages/store/settlement');
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.manage {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
padding: 0.15rem;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 筛选面板
|
||||
.screen-warp {
|
||||
padding: 0.15rem;
|
||||
background-color: #f2f3f5;
|
||||
margin-bottom: 0.15rem;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
flex-direction: column;
|
||||
|
||||
/deep/ .uni-date-x {
|
||||
height: 0.35rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-select-lay {
|
||||
background: #fff;
|
||||
|
||||
.uni-select-lay-select {
|
||||
height: 0.37rem;
|
||||
}
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&>* {
|
||||
margin-right: 0.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
// pop弹框
|
||||
.pop-box {
|
||||
background: #ffffff;
|
||||
width: 5rem;
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.pop-header {
|
||||
width: 100%;
|
||||
padding: 0 0.15rem 0 0.2rem;
|
||||
height: 0.5rem;
|
||||
// width: 3.5rem;
|
||||
margin: 0 auto;
|
||||
line-height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #f0f0f0;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
border-radius: 0.02rem 0.2rem 0 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pop-header-text {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.pop-header-close {
|
||||
cursor: pointer;
|
||||
|
||||
text {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.pop-contents {
|
||||
margin-top: 0.3rem;
|
||||
width: 3rem;
|
||||
height: 0.8rem;
|
||||
padding: 0.1rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.pop-content-item {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-items {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.pop-content-text {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.pop-contents-text {
|
||||
margin-left: 0.4rem;
|
||||
font-weight: normal;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
430
addon/cashier/source/os/pages/user/list.vue
Executable file
430
addon/cashier/source/os/pages/user/list.vue
Executable file
@@ -0,0 +1,430 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="userlist">
|
||||
<view class="userlist-box">
|
||||
<view class="userlist-left">
|
||||
<view class="user-title">
|
||||
员工
|
||||
<text class="iconfont icongengduo1"></text>
|
||||
</view>
|
||||
<view class="user-search">
|
||||
<view class="search">
|
||||
<text class="iconfont icon31sousuo"></text>
|
||||
<input v-model="search_text" type="text" @input="search" placeholder="请输入员工名称/手机号" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="user-list-wrap">
|
||||
<block v-if="list.length > 0">
|
||||
<scroll-view :scroll-top="scrollTop" @scroll="scroll" scroll-y="true" class="user-list-scroll all-scroll" @scrolltolower="getUserListFn">
|
||||
<view class="item" @click="userSelect(item, index)" v-for="(item, index) in list" :key="index" :class="index == selectUserKeys ? 'itemhover' : ''">
|
||||
<image :src="$util.img(defaultImg.head)" mode="aspectFit"/>
|
||||
<view class="item-right">
|
||||
<view>
|
||||
<view class="user-name">{{ item.username }}</view>
|
||||
<view class="user-money">{{ item.group_name }}</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="user-status">{{ item.status ? '正常' : '锁定' }}</view>
|
||||
<view class="login-time">{{ item.login_time ? $util.timeFormat(item.login_time) : '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="notYet" v-else-if="!one_judge && list.length == 0">暂无员工</view>
|
||||
</view>
|
||||
<view class="add-user">
|
||||
<button type="default" class="primary-btn" @click="addUser">添加员工</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="userlist-right">
|
||||
<view class="user-title">员工详情</view>
|
||||
<view class="user-information">
|
||||
<block v-if="JSON.stringify(detail) != '{}'">
|
||||
<view class="title">基本信息</view>
|
||||
<view class="information-box">
|
||||
<view class="box-left">
|
||||
<view class="information">
|
||||
<view>员工名称:</view>
|
||||
<view>{{ detail.username }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>员工角色:</view>
|
||||
<view>{{ detail.group_name }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>员工状态:</view>
|
||||
<view>{{ detail.status ? '正常' : '锁定' }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>最后登录IP:</view>
|
||||
<view>{{ detail.login_ip ? detail.login_ip : '--' }}</view>
|
||||
</view>
|
||||
<view class="information">
|
||||
<view>最后登录时间:</view>
|
||||
<view>{{ detail.login_time ? $util.timeFormat(detail.login_time) : '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<image class="user-img" :src="$util.img(defaultImg.head)" mode="widthFix"/>
|
||||
</view>
|
||||
<view class="title">操作日志</view>
|
||||
<view>
|
||||
<uni-table url="/cashier/storeapi/user/userlog" :cols="logCols" :option="{ uid: detail.uid }" :pagesize="7"></uni-table>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image class="cart-empty" src="@/static/cashier/cart_empty.png" mode="widthFix"/>
|
||||
</block>
|
||||
</view>
|
||||
<view class="button-box flex justify-end" v-if="detail && (detail.is_admin == 0 || detail.is_system == 0)">
|
||||
<button class="default-btn" @click="$refs.deletePop.open()">删除</button>
|
||||
<button class="default-btn" @click="editUserAction(detail.uid)">修改</button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 添加员工 -->
|
||||
<uni-popup ref="addUserPop">
|
||||
<view class="pop-box">
|
||||
<view class="pop-header">
|
||||
{{ parseInt(formData.uid) > 0 ? '修改' : '添加' }}员工
|
||||
<view class="pop-header-close" @click="cancelAddUser()">
|
||||
<text class="iconguanbi1 iconfont"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-scrollbar pop-content">
|
||||
<view class="form-content">
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required">*</text>
|
||||
用户名:
|
||||
</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<input type="text" :disabled="parseInt(formData.uid) > 0 ? true : false" class="form-input" v-model="formData.username" placeholder="请输入用户名" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item" v-if="!parseInt(formData.uid)">
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
密码:
|
||||
</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<input type="text" class="form-input" v-model="formData.password" placeholder="请输入密码" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item" v-else>
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
状态:
|
||||
</view>
|
||||
<view class="form-inline search-wrap">
|
||||
<radio-group @change="statusChange" class="form-radio-group">
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="1" :checked="formData.status == 1" />
|
||||
正常
|
||||
</label>
|
||||
<label class="radio form-radio-item">
|
||||
<radio value="0" :checked="formData.status == 0" />
|
||||
锁定
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<text class="required"></text>
|
||||
员工角色:
|
||||
</view>
|
||||
<view class="form-inline">
|
||||
<select-lay :zindex="10" :value="formData.group_id.toString()" name="names" placeholder="请选择员工角色" :options="userGroup" @selectitem="selectUserGroup"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop-bottom">
|
||||
<button type="primary" class="primary-btn" @click="save">{{ parseInt(formData.uid) > 0 ? '修改' : '添加' }}员工</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 删除 -->
|
||||
<unipopup ref="deletePop" type="center">
|
||||
<view class="confirm-pop">
|
||||
<view class="title">确定要删除该员工数据吗?</view>
|
||||
<view class="btn">
|
||||
<button type="primary" class="default-btn btn save" @click="$refs.deletePop.close()">取消</button>
|
||||
<button type="primary" class="primary-btn btn" @click="deleteUserFn(detail.uid)">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</unipopup>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUserList,
|
||||
getUserDetail,
|
||||
getAllGroups,
|
||||
addUser,
|
||||
editUser,
|
||||
deleteUser
|
||||
} from '@/api/user.js'
|
||||
import unipopup from '@/components/uni-popup/uni-popup.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
unipopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//选中的员工下标
|
||||
selectUserKeys: 0,
|
||||
//搜索的数据
|
||||
search_text: '',
|
||||
// 初始是请求第几页
|
||||
page: 1,
|
||||
// 每次返回数据数
|
||||
page_size: 8,
|
||||
//员工列表数据
|
||||
list: [],
|
||||
// 第一次请求列表做详情渲染判断
|
||||
one_judge: true,
|
||||
//无限滚动请求锁
|
||||
listLock: true,
|
||||
scrollTop: 0,
|
||||
//员工详情数据
|
||||
detail: {},
|
||||
logCols: [{
|
||||
width: 60,
|
||||
title: '操作记录',
|
||||
align: 'left',
|
||||
field: 'action_name'
|
||||
}, {
|
||||
width: 20,
|
||||
title: '操作IP地址',
|
||||
align: 'left',
|
||||
field: 'ip'
|
||||
}, {
|
||||
width: 20,
|
||||
title: '操作时间',
|
||||
align: 'right',
|
||||
templet: data => {
|
||||
return this.$util.timeFormat(data.create_time);
|
||||
}
|
||||
}],
|
||||
formData: {
|
||||
username: '',
|
||||
password: '',
|
||||
group_id: ''
|
||||
},
|
||||
userGroup: [],
|
||||
isRepeat: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// 初始化请求员工列表数据
|
||||
this.getUserListFn();
|
||||
this.getUserGroup();
|
||||
},
|
||||
methods: {
|
||||
// 选中的员工数据
|
||||
userSelect(item, keys) {
|
||||
this.selectUserKeys = keys;
|
||||
this.getUserDetailFn(item.uid);
|
||||
this.one_judge = true;
|
||||
this.isRepeat = false;
|
||||
this.formData = {
|
||||
username: '',
|
||||
password: '',
|
||||
group_id: ''
|
||||
};
|
||||
},
|
||||
statusChange(e) {
|
||||
this.formData.status = e.detail.value;
|
||||
},
|
||||
// 搜索员工
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = true;
|
||||
this.getUserListFn();
|
||||
},
|
||||
/**
|
||||
* 请求的列表数据
|
||||
*/
|
||||
getUserListFn() {
|
||||
if (!this.listLock) return false;
|
||||
getUserList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
username: this.search_text
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0 && this.one_judge) {
|
||||
this.detail = {};
|
||||
this.one_judge = false;
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
|
||||
if (this.list.length == 0) {
|
||||
this.list = res.data.list;
|
||||
} else {
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
//初始时加载一遍详情数据
|
||||
if (this.one_judge) {
|
||||
this.getUserDetailFn(this.list[0].uid);
|
||||
}
|
||||
}
|
||||
if (this.page == 1) {
|
||||
this.scrollTop = 0
|
||||
}
|
||||
if (res.data.list.length < this.page_size) {
|
||||
this.listLock = false
|
||||
} else {
|
||||
this.page++
|
||||
}
|
||||
});
|
||||
},
|
||||
scroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
getUserDetailFn(uid) {
|
||||
getUserDetail(uid).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.detail = res.data;
|
||||
this.one_judge = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
getUserGroup() {
|
||||
getAllGroups().then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.userGroup = res.data.map(item => {
|
||||
return {
|
||||
label: item.group_name,
|
||||
value: item.group_id,
|
||||
create_uid:item.create_uid,
|
||||
store_id:item.store_id,
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
editUserAction(uid) {
|
||||
getUserDetail(uid).then(res => {
|
||||
if (res.code == 0) {
|
||||
if(res.data.create_user_info){
|
||||
this.formData = {
|
||||
username: res.data.username,
|
||||
group_id: res.data.group_id,
|
||||
uid: res.data.uid,
|
||||
status: res.data.status
|
||||
};
|
||||
this.$refs.addUserPop.open();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteUserFn(uid) {
|
||||
if(this.isRepeat) return false;
|
||||
this.isRepeat = true;
|
||||
deleteUser(uid).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = true;
|
||||
this.getUserListFn();
|
||||
this.$refs.deletePop.close()
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
this.isRepeat = false
|
||||
});
|
||||
},
|
||||
addUser() {
|
||||
this.$refs.addUserPop.open();
|
||||
},
|
||||
cancelAddUser() {
|
||||
this.formData = {
|
||||
username: '',
|
||||
password: '',
|
||||
group_id: ''
|
||||
};
|
||||
this.$refs.addUserPop.close();
|
||||
},
|
||||
selectUserGroup(index, item) {
|
||||
if (index >= 0) {
|
||||
this.formData.group_id = parseInt(item.value);
|
||||
} else {
|
||||
this.formData.group_id = 0;
|
||||
}
|
||||
},
|
||||
save() {
|
||||
if (!this.verify() || this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
let action = '';
|
||||
if (parseInt(this.formData.uid) > 0) {
|
||||
action = editUser(this.formData);
|
||||
} else {
|
||||
action = addUser(this.formData);
|
||||
}
|
||||
action.then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.$util.showToast({
|
||||
title: '操作成功'
|
||||
});
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.one_judge = true;
|
||||
this.listLock = true;
|
||||
this.cancelAddUser();
|
||||
this.getUserListFn();
|
||||
|
||||
this.isRepeat = false;
|
||||
this.formData = {
|
||||
username: '',
|
||||
password: '',
|
||||
group_id: ''
|
||||
};
|
||||
} else {
|
||||
this.isRepeat = false;
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
verify() {
|
||||
if (!this.formData.username) {
|
||||
this.$util.showToast({
|
||||
title: '请输入用户名'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (parseInt(this.formData.uid) == 0 && !this.formData.password) {
|
||||
this.$util.showToast({
|
||||
title: '请输入密码'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.formData.group_id) {
|
||||
this.$util.showToast({
|
||||
title: '请选择员工角色'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './public/css/user.scss';
|
||||
</style>
|
||||
482
addon/cashier/source/os/pages/user/public/css/user.scss
Executable file
482
addon/cashier/source/os/pages/user/public/css/user.scss
Executable file
@@ -0,0 +1,482 @@
|
||||
.userlist {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
|
||||
.userlist-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
|
||||
.userlist-left {
|
||||
width: 5rem;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.notYet {
|
||||
color: #e6e6e6;
|
||||
font-size: 0.4rem;
|
||||
margin-top: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.add-user {
|
||||
padding: 0.24rem 0.2rem;
|
||||
background: #fff;
|
||||
|
||||
button {
|
||||
height: .4rem;
|
||||
line-height: .4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.user-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.icongengduo1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.user-search {
|
||||
width: 100%;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.search {
|
||||
width: 5.6rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 0.04rem;
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.iconfont {
|
||||
font-size: 0.16rem;
|
||||
color: #909399;
|
||||
margin-right: 0.11rem;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 80%;
|
||||
height: 60%;
|
||||
border: none;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-list-wrap {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.user-list-scroll {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.itemhover {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
|
||||
image {
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 0.6rem;
|
||||
width: 100%;
|
||||
|
||||
.user-name {
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.user-money {
|
||||
font-size: 0.14rem;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.login-time {
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.user-status {
|
||||
text-align: right;
|
||||
color: $primary-color;
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.userlist-right {
|
||||
width: 0;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-right: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.user-title {
|
||||
text-align: center;
|
||||
line-height: 0.6rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.icongengduo1, .iconguanbi1 {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0.2rem;
|
||||
transform: translateY(-50%);
|
||||
font-size: 0.3rem;
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.user-information {
|
||||
width: 100%;
|
||||
padding: 0.2rem 0.2rem 0.2rem 0.2rem;
|
||||
box-sizing: border-box;
|
||||
height: calc(100% - 1.38rem);
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
font-size: 0.18rem;
|
||||
margin-bottom: 0.32rem;
|
||||
}
|
||||
|
||||
.title2 {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
|
||||
.information-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.box-left {
|
||||
width: 5rem;
|
||||
|
||||
.information {
|
||||
width: 100%;
|
||||
padding-left: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.15rem;
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
view:nth-child(1) {
|
||||
width: 1.3rem;
|
||||
margin-right: 0.16rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
width: 74%;
|
||||
margin-right: 0.23rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.information:last-child {
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.user-img {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
height: 2.6rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-all {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 0.38rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-td {
|
||||
font-size: 0.14rem;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.table-th {
|
||||
height: 0.56rem;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.table-tb {
|
||||
width: 100%;
|
||||
height: calc(100% - 0.56rem);
|
||||
|
||||
.table-tr {
|
||||
height: 0.7rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
|
||||
.table-td {
|
||||
image {
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.button-box {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
padding: 0.24rem 0.2rem;
|
||||
button {
|
||||
width: 1rem;
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
margin-left: 0.1rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
/deep/ .uni-scroll-view::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.user-information::-webkit-scrollbar {
|
||||
width: 0.05rem;
|
||||
height: 0.3rem;
|
||||
}
|
||||
|
||||
.user-information::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: inset 0 0 0.05rem rgba(0, 0, 0, 0.2);
|
||||
background: rgba(193, 193, 193, 1);
|
||||
}
|
||||
|
||||
.cart-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
|
||||
.form-content {
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 0.1rem;
|
||||
display: flex;
|
||||
|
||||
.form-label {
|
||||
width: 1.3rem;
|
||||
text-align: right;
|
||||
padding-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 0.03rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
width: 2.4rem;
|
||||
line-height: 0.32rem;
|
||||
margin-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.form-input {
|
||||
border-width: 0.01rem;
|
||||
border-style: solid;
|
||||
background-color: #fff;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 0.02rem;
|
||||
padding-left: 0.1rem;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
font-size: 0.14rem;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
|
||||
button {
|
||||
width: calc(50% - 0.05rem);
|
||||
display: inline-block;
|
||||
margin-right: 0.1rem;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-wrap {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-radio-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-checkbox-item, .form-radio-item {
|
||||
margin-right: 26rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/deep/ .uni-radio-input, .uni-checkbox-input {
|
||||
width: .18rem;
|
||||
height: .18rem;
|
||||
}
|
||||
|
||||
// pop弹框
|
||||
.pop-box {
|
||||
background: #ffffff;
|
||||
width: 4.2rem;
|
||||
height: 3.38rem;
|
||||
|
||||
.pop-header {
|
||||
padding: 0 0.15rem 0 0.2rem;
|
||||
height: 0.5rem;
|
||||
line-height: 0.5rem;
|
||||
border-bottom: 0.01rem solid #f0f0f0;
|
||||
font-size: 0.14rem;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
border-radius: 0.02rem 0.2rem 0 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.pop-header-text {
|
||||
}
|
||||
|
||||
.pop-header-close {
|
||||
cursor: pointer;
|
||||
|
||||
text {
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
height: calc(100% - 1.05rem);
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-content {
|
||||
margin-top: 0;
|
||||
padding-top: 0.2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.form-label {
|
||||
width: .9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.pop-bottom {
|
||||
padding: 0.1rem;
|
||||
border-top: 0.01rem solid #eee;
|
||||
|
||||
button {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
}
|
||||
349
addon/cashier/source/os/pages/verify/index.vue
Executable file
349
addon/cashier/source/os/pages/verify/index.vue
Executable file
@@ -0,0 +1,349 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row height-all">
|
||||
<view class="container common-wrap" style="-webkit-flex: 1;flex: 1;" v-if="step == 'search'">
|
||||
<view class="search-title">查询核销码核销</view>
|
||||
<view class="search-wrap">
|
||||
<view class="input-wrap">
|
||||
<input type="text" value="" placeholder="请输入核销码或扫描核销码" placeholder-class="placeholder" v-model="code" @confirm="search" :focus="inputFocus" @focus="inputFocus = true" @blur="codeInputBlur" />
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="iconfont iconsaoyisaosaoma" @click="scancode"></view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<button type="default" class="primary-btn" @click="search">查询</button>
|
||||
</view>
|
||||
<view class="search-desc">使用扫码枪扫码时需注意光标需要停留在输入框中</view>
|
||||
<view class="record" @click="$util.redirectTo('/pages/verify/list')"><text>核销记录</text></view>
|
||||
</view>
|
||||
|
||||
<view class="content-box common-wrap" style="-webkit-flex: 1;flex: 1;" v-if="step == 'verify'">
|
||||
<view class="input-wrap">
|
||||
<input placeholder="请输入核销码" v-model="code" @confirm="search" />
|
||||
<button type="default" class="primary-btn search" @click="search()">查询</button>
|
||||
</view>
|
||||
<view class="content-data">
|
||||
<view class="content-top">
|
||||
<view v-for="(item, index) in verifyInfo.data.item_array" :key="index" class="verify-item">
|
||||
<view class="container-image">
|
||||
<image :src="$util.img(item.img.split(',')[0], { size: 'small' })" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="container-box">
|
||||
<view class="content-name">{{ item.name }}</view>
|
||||
<view class="content-name">x{{ item.num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-bottom">
|
||||
<view class="bottom-item">
|
||||
<view>核销状态:{{ verifyInfo.is_verify == 0 ? '待核销' : '已核销' }}</view>
|
||||
</view>
|
||||
<view class="bottom-item">
|
||||
<view>核销类型:{{ verifyInfo.verify_type_name }}核销</view>
|
||||
</view>
|
||||
<view class="bottom-item">
|
||||
<view>
|
||||
总次数/已使用:{{ verifyInfo.verify_total_count ? verifyInfo.verify_total_count : '不限' }}次/{{ verifyInfo.verify_use_num }}次
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom-item">
|
||||
<view>
|
||||
有效期:{{ verifyInfo.expire_time ? $util.timeFormat(verifyInfo.expire_time, 'Y-m-d H:i') : '永久' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="verify-action">
|
||||
<button type="primary" class="default-btn" @click="step = 'search'">取消</button>
|
||||
<button type="default" class="primary-btn" @click="verify()" v-show="verifyInfo.is_verify == 0">立即核销</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getVerifyInfo,
|
||||
verifyCode
|
||||
} from '@/api/verify.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
step: 'search',
|
||||
code: '',
|
||||
verifyInfo: null,
|
||||
isRepeat: false,
|
||||
inputFocus: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
uni.hideTabBar();
|
||||
this.$nextTick(()=>{
|
||||
this.inputFocus = true;
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
codeInputBlur() {
|
||||
this.inputFocus = false;
|
||||
if(!this.verifyInfo){
|
||||
this.$nextTick(()=>{
|
||||
this.inputFocus = true;
|
||||
})
|
||||
}
|
||||
},
|
||||
deleteCode() {
|
||||
this.code = this.code.substr(0, this.code.length - 1);
|
||||
},
|
||||
search() {
|
||||
if (!this.code) {
|
||||
this.$util.showToast({
|
||||
title: '请输入核销码'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.code = new URLSearchParams(this.code.split('?')[1]).get('code');
|
||||
getVerifyInfo(this.code.trim()).then(res => {
|
||||
this.code = '';
|
||||
if (res.code >= 0) {
|
||||
this.verifyInfo = res.data;
|
||||
this.step = 'verify';
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 200);
|
||||
},
|
||||
verify() {
|
||||
if (!this.verifyInfo) {
|
||||
this.$util.showToast({
|
||||
title: '请先查询核销码信息'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isRepeat) return;
|
||||
this.isRepeat = true;
|
||||
|
||||
verifyCode(this.verifyInfo.verify_code).then(res => {
|
||||
this.isRepeat = false;
|
||||
if (res.code >= 0) {
|
||||
this.step = 'search';
|
||||
this.verifyInfo = null;
|
||||
this.code = '';
|
||||
}
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
});
|
||||
},
|
||||
scancode() {
|
||||
uni.scanCode({
|
||||
scanType: ['qrCode', 'barCode'],
|
||||
success: res => {
|
||||
this.code = res.result;
|
||||
this.search();
|
||||
},
|
||||
fail: res => {
|
||||
this.$util.showToast({
|
||||
title: '扫码失败'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.search-title {
|
||||
font-size: 0.18rem;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.search-wrap {
|
||||
display: flex;
|
||||
margin-top: 0.3rem;
|
||||
|
||||
button {
|
||||
width: 1rem;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
line-height: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.search-desc {
|
||||
color: #909399;
|
||||
font-size: 0.14rem;
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
.input-wrap {
|
||||
width: 4.5rem;
|
||||
height: 0.5rem;
|
||||
border: 0.01rem solid #cccccc;
|
||||
display: flex;
|
||||
border-radius: 0.02rem;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
padding: 0 0.15rem;
|
||||
font-size: 0.16rem;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
flex: 1;
|
||||
height: 0.58rem;
|
||||
line-height: 0.58rem;
|
||||
font-size: 0.16rem;
|
||||
font-weight: 400;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 0.18rem;
|
||||
padding: 0 0.15rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.record {
|
||||
text-align: center;
|
||||
margin-top: 0.2rem;
|
||||
|
||||
text {
|
||||
color: $primary-color;
|
||||
font-size: 0.14rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// 核销详情
|
||||
.content-box {
|
||||
padding: 0.15rem 0.15rem 0.15rem 0.15rem;
|
||||
|
||||
.input-wrap {
|
||||
width: 6rem;
|
||||
height: 0.4rem;
|
||||
border: 0.01rem solid #cccccc;
|
||||
display: flex;
|
||||
border-radius: 0.02rem;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
padding: 0 0.15rem;
|
||||
height: 0.38rem;
|
||||
line-height: 0.38rem;
|
||||
font-size: 0.16rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
font-weight: 400;
|
||||
color: #909399;
|
||||
font-size: 0.18rem;
|
||||
}
|
||||
|
||||
.search {
|
||||
border-radius: 0;
|
||||
width: 1rem;
|
||||
line-height: 0.38rem;
|
||||
font-size: 0.16rem;
|
||||
font-family: Source Han Sans CN;
|
||||
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-data {
|
||||
border: 0.01rem solid #eee;
|
||||
margin-top: 0.2rem;
|
||||
padding: 0.15rem;
|
||||
|
||||
.verify-item {
|
||||
display: flex;
|
||||
padding: 0.15rem 0;
|
||||
|
||||
.container-image {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.container-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-left: 0.15rem;
|
||||
width: 0;
|
||||
flex: 1;
|
||||
|
||||
.content-name {
|
||||
font-size: 0.15rem;
|
||||
margin-top: 0.05rem;
|
||||
}
|
||||
|
||||
.content-desc {
|
||||
display: flex;
|
||||
margin-top: 0.15rem;
|
||||
color: #999;
|
||||
font-size: 0.13rem;
|
||||
|
||||
.time {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.verify-action {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border-top: 0.01rem solid #eee;
|
||||
padding-top: 0.15rem;
|
||||
|
||||
button {
|
||||
width: 1rem;
|
||||
height: 0.36rem;
|
||||
margin: 0 0 0 0.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content-bottom {
|
||||
padding: 0.15rem 0;
|
||||
border-top: 0.01rem solid #eee;
|
||||
|
||||
.bottom-item {
|
||||
color: #999;
|
||||
display: flex;
|
||||
margin-top: 0.15rem;
|
||||
width: 5rem;
|
||||
justify-content: space-between;
|
||||
|
||||
view {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
353
addon/cashier/source/os/pages/verify/list.vue
Executable file
353
addon/cashier/source/os/pages/verify/list.vue
Executable file
@@ -0,0 +1,353 @@
|
||||
<template>
|
||||
<base-page>
|
||||
<view class="uni-flex uni-row check-wrap">
|
||||
<view class="check-head">
|
||||
<text>核销列表</text>
|
||||
<text>核销详情</text>
|
||||
</view>
|
||||
<view class="check-content">
|
||||
<view class="left-wrap-content">
|
||||
<view class="wrap-search-box">
|
||||
<view class="wrap-search">
|
||||
<input placeholder="输入核销码" v-model="searchText" @input="search()" placeholder-style="font-size:0.14rem" />
|
||||
<text class="iconfont icon31sousuo" @click="search()"></text>
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="list.length > 0">
|
||||
<scroll-view scroll-y="true" class="check-list all-scroll" @scrolltolower="getRecordList">
|
||||
<view class="item" v-for="(item, index) in list" :key="index" @click="tableDataFn(item)" :class="current_id == item.id ? 'item-hover' : ''">
|
||||
<view class="item-box">
|
||||
<view class="head">
|
||||
<view class="nick-name">核销码:{{ item.verify_code }}</view>
|
||||
<view class="time">核销时间:{{ $util.timeFormat(item.verify_time, 'Y-m-d H:i') }}</view>
|
||||
</view>
|
||||
<view class="body">
|
||||
<text>{{ item.verifier_name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<view class="not-record" v-else>暂无数据</view>
|
||||
</view>
|
||||
<view class="check-detail text">
|
||||
<view class="form-content" v-if="detailInfo && Object.keys(detailInfo).length">
|
||||
<view class="verify-item" v-for="(item, index) in detailInfo.verify_content_json.item_array" :key="index">
|
||||
<view class="item-img">
|
||||
<image :src="$util.img(item.img.split(',')[0], { size: 'small' })" mode="aspectFit"/>
|
||||
</view>
|
||||
<view class="item-info">
|
||||
<view>{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">核销码:</view>
|
||||
<view class="form-inline">
|
||||
<text>{{ detailInfo.verify_code }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">核销类型:</view>
|
||||
<view class="form-inline">{{ detailInfo.verify_type_name }}核销</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">核销员:</view>
|
||||
<view class="form-inline">{{ detailInfo.verifier_name }}</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">核销次数:</view>
|
||||
<view class="form-inline">{{ detailInfo.verify_num }}</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">核销时间:</view>
|
||||
<view class="form-inline">{{ $util.timeFormat(detailInfo.verify_time, 'Y-m-d H:i') }}</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item" v-if="detailInfo.member_id > 0">
|
||||
<view class="form-label">所属会员:</view>
|
||||
<view class="form-inline">{{ detailInfo.nickname }}</view>
|
||||
</view>
|
||||
<view class="form-item" v-if="detailInfo.member_id > 0">
|
||||
<view class="form-label">手机号:</view>
|
||||
<view class="form-inline">{{ detailInfo.mobile ? detailInfo.mobile : '--' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<block v-else>
|
||||
<image class="detail-empty" :src="$util.img('@/static/goods/goods_empty.png')" mode="widthFix"/>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getVerifyRecordList,
|
||||
getVerifyRecordDetail
|
||||
} from '@/api/verify.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
detailInfo: null,
|
||||
// 初始是请求第几页
|
||||
page: 1,
|
||||
// 每次返回数据数
|
||||
page_size: 20,
|
||||
list: [],
|
||||
current_id: 0,
|
||||
searchText: ''
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getRecordList();
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.page = 1;
|
||||
this.list = [];
|
||||
this.getRecordList();
|
||||
},
|
||||
// 查询核销记录
|
||||
getRecordList() {
|
||||
getVerifyRecordList({
|
||||
page: this.page,
|
||||
page_size: this.page_size,
|
||||
search_text: this.searchText
|
||||
}).then(res => {
|
||||
if (res.data.list.length == 0) {
|
||||
this.detailInfo = {};
|
||||
this.$forceUpdate();
|
||||
}
|
||||
if (res.code >= 0 && res.data.list.length != 0) {
|
||||
this.page += 1;
|
||||
this.list = this.list.concat(res.data.list);
|
||||
}
|
||||
|
||||
if (this.list.length) {
|
||||
this.tableDataFn(this.list[0]);
|
||||
}
|
||||
})
|
||||
},
|
||||
tableDataFn(e) {
|
||||
this.current_id = e.id;
|
||||
this.getInfo(e.id);
|
||||
},
|
||||
getInfo(id) {
|
||||
getVerifyRecordDetail(id).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.detailInfo = null;
|
||||
this.detailInfo = res.data;
|
||||
} else {
|
||||
this.$util.showToast({
|
||||
title: res.message
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.check-wrap {
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
min-height: 100%;
|
||||
|
||||
.check-head {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
line-height: 0.6rem;
|
||||
font-weight: 500;
|
||||
height: 0.6rem;
|
||||
border-top: 0.01rem solid #e6e6e6;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
|
||||
text {
|
||||
width: 5rem;
|
||||
text-align: center;
|
||||
font-size: 0.18rem;
|
||||
border-left: 0.01rem solid #e6e6e6;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:nth-child(2) {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.check-content {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 1rem);
|
||||
|
||||
>view {
|
||||
padding: 0.2rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.left-wrap-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 1rem);
|
||||
padding: 0;
|
||||
|
||||
.wrap-search-box {
|
||||
height: 0.35rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
padding: 0.1rem 0.15rem;
|
||||
|
||||
.wrap-search {
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding: 0.05rem 0.15rem 0.05rem 0.4rem;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
position: absolute;
|
||||
left: 0.15rem;
|
||||
top: 0.08rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.not-record {
|
||||
color: #e6e6e6;
|
||||
font-size: 0.4rem;
|
||||
margin-top: 3rem;
|
||||
text-align: center;
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.check-list {
|
||||
width: 5rem;
|
||||
height: calc(100% - 0.5rem);
|
||||
padding: 0;
|
||||
|
||||
.item-hover {
|
||||
background: var(--primary-color-light-9);
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
padding: 0.2rem;
|
||||
border-bottom: 0.01rem solid #e6e6e6;
|
||||
cursor: pointer;
|
||||
|
||||
.name {
|
||||
font-size: $uni-font-size-lg;
|
||||
padding-bottom: 0.07rem;
|
||||
}
|
||||
|
||||
.item-box {
|
||||
.head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.body {
|
||||
margin-top: 0.15rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.time {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.time,
|
||||
.nick-name {
|
||||
line-height: 1;
|
||||
width: 50%;
|
||||
font-size: $uni-font-size-lg;
|
||||
}
|
||||
|
||||
.type {
|
||||
position: absolute;
|
||||
right: 0.25rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.check-detail {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
border-left: 0.01rem solid #e6e6e6;
|
||||
position: relative;
|
||||
|
||||
.detail-empty {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2.1rem;
|
||||
}
|
||||
|
||||
.form-content {
|
||||
margin-top: 0.2rem;
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 0.1rem;
|
||||
display: flex;
|
||||
|
||||
.form-label {
|
||||
width: 1.6rem;
|
||||
text-align: right;
|
||||
padding-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
height: 0.32rem;
|
||||
line-height: 0.32rem;
|
||||
}
|
||||
|
||||
.form-inline {
|
||||
line-height: 0.32rem;
|
||||
margin-right: 0.1rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.verify-item {
|
||||
display: flex;
|
||||
padding: 0.15rem;
|
||||
background: #f5f5f5;
|
||||
margin-bottom: 0.1rem;
|
||||
|
||||
.item-img {
|
||||
width: 0.8rem;
|
||||
height: 0.8rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.item-info {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
margin-left: 0.15rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user