123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687 |
- <template>
- <view class="wrap">
- <view class="u-menu-wrap">
- <scroll-view :style="{height:height}" scroll-y scroll-with-animation class="u-tab-view menu-scroll-view"
- :scroll-top="scrollTop" v-if="leftShow">
- <view v-for="(item,index) in newTabList" :key="index" class="u-tab-item"
- :class="[current==index ? 'u-tab-item-active' : '']" :data-current="index"
- @tap.stop="swichMenu(index,item)">
- <text class="u-line-1">{{item.categoryName}}</text>
- <view class="u-tab-num">
- ({{item.num}})
- </view>
- <u-badge type="error" max="99" :value="item.selectNum" :absolute="true" :offset="[4,4]"></u-badge>
- </view>
- </scroll-view>
- <scroll-view lower-threshold="150" :style="{height:height}" scroll-y class="right-box"
- @scrolltolower="lowerBottom">
- <view class="page-view">
- <view class="class-item" v-if="newCommList.length>0">
- <view class="item-container">
- <view class="thumb-box" v-for="(item, index) in newCommList" :key="index"
- @click.stop="commItemClick(item)">
- <view v-if="selectShow">
- <image class="select-img"
- src="https://cdn.ossfile.mxrvending.com/assets/xy_merc_mini/images/commodity/no_selected.png"
- mode="widthFix" v-show="item.noSelect"></image>
- <image class="select-img"
- src="https://cdn.ossfile.mxrvending.com/assets/xy_merc_mini/images/commodity/selected.png"
- mode="widthFix" v-show="!item.noSelect&&item.checked"></image>
- <image class="select-img"
- src="https://cdn.ossfile.mxrvending.com/assets/xy_merc_mini/images/commodity/select.png"
- mode="widthFix" v-show="!item.noSelect&&!item.checked"></image>
- </view>
- <view class="check-content">
- <view class="comm-img">
- <u--image radius="4" width="130rpx" height="130rpx" :src="item.cover"
- mode="aspectFit" :lazy-lord="true"></u--image>
- </view>
- <view class="comm-main">
- <view>
- {{item.name}}
- </view>
- <view>
- 条形码:{{item.barcode}}
- </view>
- <!-- <view>
- 商品类型:{{item.categoryName}}
- </view> -->
- <view v-if="item.price!=null">
- 价格:<text>¥{{item.price}}</text>
- </view>
- </view>
- </view>
- </view>
- <u-loadmore :status="status" v-if="newCommList.length>=1" />
- </view>
- </view>
- <view class="empty" v-else>
- <u-empty></u-empty>
- </view>
- </view>
- </scroll-view>
- <view class="cart" v-if="selectShow" @click="cartShow=true">
- <image class="cart-img"
- src="https://cdn.ossfile.mxrvending.com/assets/xy_merc_mini/images/commodity/buy.png"
- mode="widthFix"></image>
- <u-badge type="error" max="99" :value="selectList.length" :absolute="true" :offset="[4,4]"></u-badge>
- </view>
- </view>
- <xpopup :show="cartShow" @close="close" :showBtn="false">
- <view class="pop-top" slot="title">
- <view class="left">
- 已选商品
- </view>
- <xbutton size="mini" class="clear" @click="clearCart">清空</xbutton>
- </view>
- <view class="pop-content">
- <u-list height="440rpx">
- <u-list-item v-for="(item, index) in selectList" :key="item.id">
- <view class="list-item">
- <view class="comm-item">
- <view class="comm-img">
- <u--image radius="4" width="110rpx" height="110rpx" :src="item.cover"
- mode="aspectFit" :lazy-lord="true"></u--image>
- </view>
- <view class="item-content">
- <view>
- {{item.name}}
- </view>
- <view>
- 条形码:{{item.barcode}}
- </view>
- <view>
- 商品类型:{{item.categoryName}}
- </view>
- <view v-if="item.price">
- 价格:<text>¥{{item.price}}</text>
- </view>
- </view>
- </view>
- <xbutton color="red" size="mini" bgColor="#fff" borderColor="red" @click="delCom(item)">删除
- </xbutton>
- </view>
- </u-list-item>
- <view class="empty" v-if="selectList.length==0">
- <u-empty mode="car" text="没有商品!"></u-empty>
- </view>
- </u-list>
- </view>
- </xpopup>
- <xpopup :show="delPopShow" :showBtn="true" @confirm="delSure" @close="delClose">
- <view class="del-content">
- 是否确定要{{delTitle}}?
- </view>
- </xpopup>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- scrollTop: 0, //tab标题的滚动条位置
- current: 0, // 预设当前项的值
- menuHeight: 0, // 左边菜单的高度
- menuItemHeight: 0, // 左边菜单item的高度
- keyword: '',
- checkedList: [], //当前类目选中商品
- cartShow: false, //购物车
- delPopShow: false, //删除弹框
- delTitle: undefined, //删除或清空提示
- selectList: [], //已选中商品
- }
- },
- props: {
- value: {
- type: Array,
- required: false
- },
- selectShow: {
- type: Boolean,
- default: false,
- require: false
- },
- leftShow: {
- type: Boolean,
- default: true,
- require: false
- },
- height: {
- type: String,
- require: false,
- default: 'auto'
- },
- tabList: {
- type: Array,
- require: true,
- default () {
- return []
- }
- },
- commList: {
- type: Array,
- require: true,
- default () {
- return []
- }
- },
- status: {
- type: String,
- require: false,
- default: 'loadmore'
- },
- storeName: {
- type: String,
- require: false,
- default: 'commStor'
- },
-
- isModal:{
- type: Boolean,
- require: false,
- default: false
- },
- },
- computed: {
- newTabList() {
- if (this.tabList.length > 0) {
- let newTabList = JSON.parse(JSON.stringify(this.tabList));
- if (this.selectShow) {
- const idMapping = newTabList.reduce((acc, el, i) => {
- el.selectNum = 0;
- acc[el.categoryCode] = i;
- return acc;
- }, {});
- this.selectList.forEach(i => {
- if (i.categoryCode == null) {
- i.categoryCode = '0'
- }
- newTabList[idMapping[i.categoryCode]].selectNum++
- })
- return newTabList
- } else {
- return newTabList
- }
- } else {
- return []
- }
- },
- newCommList() {
- let newCommList = [];
- if (this.selectList && this.selectList.length > 0) {
- let selectList = this.selectList
- const idMapping = selectList.reduce((acc, el, i) => {
- acc[el.id] = i;
- return acc;
- }, {});
- this.commList.forEach(i => {
- if (idMapping[i.id] != undefined) { //重复值
- i.checked = true
- } else {
- i.checked = false
- }
- newCommList.push(i)
- })
- } else {
- newCommList = this.commList.map(i => {
- i.checked = false;
- return i
- })
- }
- return newCommList
- }
- },
- watch: {
- commList: {
- handler(newVal, oldVal) {
- },
- immediate: true,
- deep: true,
- },
- },
- created() {
- this.onshow()
- },
- methods: {
- //搜索页来回跳转,刷新已选商品数据
- onshow() {
- if (uni.getStorageSync(this.storeName) && JSON.parse(uni.getStorageSync(
- this.storeName)).length > 0) {
- let commStor = JSON.parse(uni.getStorageSync(this.storeName))
- this.selectList = commStor;
- }
- },
- // 商品点击
- commItemClick(e) {
- if (e.noSelect) {
- this.$modal.msg('当前商品已存在!')
- return
- }
- if (this.selectShow) { //有选中框
- if (this.isModal) { //私库中新建模商品,需要设置价格
- if (e.price == null || e.price == undefined) {
- this.$emit('comClick', e)
- return
- }
- }
- if (!e.checked && this.selectList && this.selectList.length >= 10) {
- this.$modal.msg('一次最多添加10个商品!')
- return
- }
- e.checked = !e.checked
- //选中商品存储到内存中,以便取用
- let commStor = []
- if (e.checked) { //选中添加到存储中
- if (uni.getStorageSync(this.storeName)) {
- commStor = JSON.parse(uni.getStorageSync(this.storeName));
- }
- commStor.push(e);
- } else { //取消选中删除,并且从存储中删除
- commStor = JSON.parse(uni.getStorageSync(this.storeName));
- for (let i = 0; i < commStor.length; i++) {
- let item = commStor[i]
- if (item.id == e.id) {
- commStor.splice(i, 1);
- break
- }
- }
- }
- //收集选中商品,更新存储
- this.selectList = commStor;
- commStor.length > 0 ? uni.setStorageSync(this.storeName, JSON.stringify(commStor)) : uni
- .setStorageSync(
- this.storeName, '')
- if (commStor.length > 0) {
- console.log('commStor', commStor)
- uni.setStorageSync(this.storeName, JSON.stringify(commStor))
- }
- } else { //无选中框
- this.$emit('comClick', e)
- }
- },
- lowerBottom() {
- this.$emit('lowerBottom')
- },
- // 点击左边的栏目切换
- async swichMenu(index, item) {
- if (index == this.current) return;
- this.current = index;
- this.$emit('switchMenu', item)
- // 如果为0,意味着尚未初始化
- if (this.menuHeight == 0 || this.menuItemHeight == 0) {
- await this.getElRect('menu-scroll-view', 'menuHeight');
- await this.getElRect('u-tab-item', 'menuItemHeight');
- }
- // 将菜单菜单活动item垂直居中
- this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
- },
- // 获取一个目标元素的高度
- getElRect(elClass, dataVal) {
- new Promise((resolve, reject) => {
- const query = uni.createSelectorQuery().in(this);
- query.select('.' + elClass).fields({
- size: true
- }, res => {
- // 如果节点尚未生成,res值为null,循环调用执行
- if (!res) {
- setTimeout(() => {
- this.getElRect(elClass);
- }, 10);
- return;
- }
- this[dataVal] = res.height;
- }).exec();
- })
- },
- // 关闭购物车
- close() {
- this.cartShow = false
- },
- // 删除当前商品
- delCom(item) {
- //删除选中商品,更新存储
- let commStor = JSON.parse(uni.getStorageSync(this.storeName));
- for (let i = 0; i < commStor.length; i++) {
- let stor = commStor[i];
- if (stor.id == item.id) {
- commStor.splice(i, 1);
- break
- }
- }
- this.selectList = commStor;
- uni.setStorageSync(this.storeName, JSON.stringify(commStor));
- this.$modal.msg('删除成功~');
- },
- //清空购物车
- clearCart() {
- if (this.selectList.length > 0) {
- this.delPopShow = true
- this.delTitle = '清空已选商品'
- } else {
- this.$modal.msg('您没有选择任何商品!');
- }
- },
- delSure() {
- this.delPopShow = false
- this.selectList = [];
- uni.setStorageSync(this.storeName, '')
- this.close()
- this.$modal.msg('清空成功~');
- },
- delClose() {
- this.delPopShow = false
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .u-menu-wrap {
- flex: 1;
- display: flex;
- overflow: hidden;
- }
- .u-tab-view {
- width: 200rpx;
- height: 100%;
- }
- .u-tab-item {
- height: 110rpx;
- background: #f6f6f6;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: 26rpx;
- color: #444;
- font-weight: 400;
- line-height: 1;
- position: relative;
- &::after {
- content: '';
- height: 1rpx;
- width: 100%;
- background-color: #fafafa;
- position: absolute;
- left: 0;
- bottom: 0;
- }
- .u-tab-num {
- font-size: 20rpx;
- margin-top: 6rpx;
- }
- }
- .u-tab-item-active {
- position: relative;
- background: #fff;
- color: #000;
- font-weight: bold;
- }
- .u-tab-item-active::before {
- content: "";
- position: absolute;
- border-left: 4px solid $uni-color-primary;
- height: 32rpx;
- left: 0;
- top: 39rpx;
- }
- .u-tab-view {
- height: 100%;
- }
- .right-box {
- background-color: rgb(250, 250, 250);
- padding-bottom: 20rpx;
- position: relative;
- }
- .page-view {
- padding: 16rpx 16rpx 0;
- }
- .class-item {
- background-color: #fff;
- padding: 16rpx;
- border-radius: 8rpx;
- }
- .item-title {
- font-size: 30rpx;
- color: $u-main-color;
- font-weight: bold;
- margin: 10rpx 0;
- }
- .item-menu-name {
- font-weight: normal;
- font-size: 24rpx;
- color: $u-main-color;
- }
- .item-container {
- display: flex;
- flex-direction: column;
- flex-wrap: wrap;
- }
- .empty {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- }
- .item-menu-image {
- width: 120rpx;
- height: 120rpx;
- border-radius: 100rpx;
- }
- .thumb-box {
- display: flex;
- flex-flow: row nowrap;
- padding: 12rpx 0;
- align-items: center;
- &:not(:last-child) {
- border-bottom: 1rpx solid #f4f4f4;
- margin-bottom: 10rpx;
- }
- }
- .select-img {
- width: 40rpx;
- height: 40rpx;
- }
- .check-content {
- display: flex;
- flex-direction: row;
- align-items: center;
- padding-left: 12rpx;
- .comm-img {
- width: 130rpx;
- height: 130rpx;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-around;
- image {
- width: 100%;
- }
- }
- .comm-main {
- box-sizing: border-box;
- padding-left: 18rpx;
- color: #999;
- >view {
- padding: 4rpx 0;
- }
- >view:nth-child(1) {
- font-size: 28rpx;
- font-weight: bold;
- color: #333;
- }
- >view:nth-child(2) {
- font-size: 24rpx;
- max-width: 380rpx;
- }
- >view:nth-child(3) {
- font-size: 24rpx;
- }
- >view:nth-child(4) {
- font-size: 24rpx;
- text {
- font-weight: bold;
- color: red;
- }
- }
- }
- }
- .cart {
- width: 120rpx;
- height: 120rpx;
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- border-radius: 120rpx;
- position: fixed;
- right: 24rpx;
- bottom: 250rpx;
- .cart-img {
- width: 80rpx;
- height: 80rpx;
- }
- }
- .pop-top {
- padding: 24rpx;
- position: relative;
- .left {
- font-size: 28rpx;
- font-weight: bold;
- }
- .clear {
- position: absolute;
- right: 24rpx;
- top: 24rpx;
- }
- }
- .pop-content {
- // height: 200rpx;
- padding: 0 24rpx;
- }
- .list-item {
- display: flex;
- flex-flow: row nowrap;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- }
- .comm-item {
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
- background-color: #fff;
- margin-bottom: 12rpx;
- border-radius: 12rpx;
- box-sizing: border-box;
- padding: 12rpx;
- .comm-img {
- width: 110rpx;
- }
- .item-content {
- width: 480rpx;
- padding-left: 24rpx;
- color: #999;
- >view:nth-child(1) {
- font-size: 28rpx;
- font-weight: bold;
- color: #333;
- }
- >view:nth-child(2) {
- font-size: 24rpx;
- margin-top: 12rpx;
- }
- >view:nth-child(3) {
- font-size: 24rpx;
- margin-top: 12rpx;
- }
- >view:nth-child(4) {
- font-size: 24rpx;
- margin-top: 12rpx;
- text {
- font-weight: bold;
- color: red;
- }
- }
- }
- }
- .del-content {
- padding: 48rpx;
- font-size: 32rpx;
- text-align: center;
- }
- </style>
|