297 lines
6.5 KiB
Vue
297 lines
6.5 KiB
Vue
<template>
|
|
<view class="mask u-fixed position-all u-flex u-col-bottom u-font-28" v-if="show" @tap="close">
|
|
<view class="bg-fff w-full " @tap.stop="nullFunction">
|
|
<view class="u-p-30">
|
|
<view class="font-bold u-text-center">选择商品</view>
|
|
<view class="u-m-t-32 u-flex">
|
|
<view class=" ">
|
|
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}" placeholder="请选择分类"
|
|
popup-title="请选择分类" :localdata="category" v-model="goods.query.categoryId">
|
|
<view class="u-flex u-font-28" >
|
|
<text class=" u-line-1"
|
|
style="max-width: 100rpx;">{{goods.query.categoryId||'分类' }}</text>
|
|
<up-icon name="arrow-down" size="16"></up-icon>
|
|
</view>
|
|
</uni-data-picker>
|
|
</view>
|
|
<view class="u-flex-1 u-p-l-16">
|
|
<up-search @custom="getGoods" v-model="goods.query.name" placeholder="请输入商品名称" @search="getGoods" @clear="getGoods"></up-search>
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<scroll-view :scroll-x="true" :scroll-y="true" :style="computedStyle()">
|
|
<view class="u-p-l-30 u-p-r-30 table">
|
|
<view class="u-flex u-row-between no-wrap title">
|
|
<view>
|
|
<my-radio @change="radioAllChange" v-model="goods.allChecked" shape="square"
|
|
:size="20"></my-radio>
|
|
</view>
|
|
<view>商品信息</view>
|
|
<view>规格</view>
|
|
<view>售价</view>
|
|
<view>销量/库存</view>
|
|
<view>分类名称</view>
|
|
</view>
|
|
<view @click="changeChecked(item)" class="u-m-t-12 u-flex u-p-24 u-row-between row" v-for="(item,index) in goods.list" :key="index">
|
|
<view class="">
|
|
<my-radio @change="radioChange($event,item)" v-model="item.checked" shape="square" :size="20"></my-radio>
|
|
</view>
|
|
<view class="u-text-left u-flex-1 u-p-l-20" style="flex-shrink: 0;">
|
|
<view class="">{{item.name}}</view>
|
|
</view>
|
|
<view class="u-flex-1 u-p-l-4 u-p-r-4 box-size-border">
|
|
{{isType(item.type)}}
|
|
</view>
|
|
<view class="u-flex-1">
|
|
¥{{ item.lowPrice }}
|
|
</view>
|
|
<view class="u-flex-1">
|
|
{{ item.stockNumber }}
|
|
</view>
|
|
<view class="u-flex-1" style="text-overflow: ellipsis;overflow: hidden;word-break: break-all;white-space: nowrap;">
|
|
{{item.categoryName}}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
<view class="u-p-30">
|
|
<my-pagination :totalElements="goods.totalElements" :size="goods.query.size"
|
|
@change="pageChange"></my-pagination>
|
|
<view class="u-m-t-20 u-flex">
|
|
<view class="u-flex-1 u-p-r-16">
|
|
<my-button type="cancel" plain @tap="close">取消</my-button>
|
|
</view>
|
|
<view class="u-flex-1 u-p-l-16">
|
|
<my-button @tap="confrim">确定</my-button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { reactive, onMounted, ref, watch, computed } from 'vue';
|
|
import { getProductPage} from '@/http/api/product.js';
|
|
|
|
const props = defineProps({
|
|
modelValue: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
height: {
|
|
type: [Number, String],
|
|
default: '50vh'
|
|
},
|
|
category: {
|
|
type: Array,
|
|
default: () => {
|
|
return []
|
|
}
|
|
}
|
|
})
|
|
const emits = defineEmits(['update:modelValue', 'confirm'])
|
|
|
|
const $quey = {
|
|
categoryId: "",
|
|
id: "",
|
|
name: "",
|
|
orderBy: "create_time desc",
|
|
page: 1,
|
|
size: 10,
|
|
}
|
|
const query = reactive({
|
|
...$quey
|
|
})
|
|
const goods = reactive({
|
|
list: [],
|
|
allChecked: false,
|
|
totalElements: 0,
|
|
query: {
|
|
...$quey
|
|
}
|
|
})
|
|
//页面全部数据
|
|
const pageData = reactive({
|
|
// 商品类型
|
|
types: [{
|
|
name: '单规格',
|
|
value: 'single'
|
|
},
|
|
{
|
|
name: '多规格',
|
|
value: 'sku'
|
|
},
|
|
{
|
|
name: '套餐',
|
|
value: 'package'
|
|
},
|
|
{
|
|
name: '称重',
|
|
value: 'weight'
|
|
},
|
|
// {
|
|
// name: '团购券',
|
|
// value: 'coupon'
|
|
// },
|
|
],
|
|
|
|
|
|
})
|
|
function isType (e) {
|
|
let obj = pageData.types.find(item=> item.value == e)
|
|
return obj.name
|
|
}
|
|
|
|
getGoods()
|
|
/**
|
|
* 获取商品列表
|
|
*/
|
|
function getGoods() {
|
|
const arr=selArr
|
|
getProductPage(goods.query).then(res => {
|
|
let selLen=0;
|
|
goods.list = res.records.map(v => {
|
|
const checked=$selGoodsMap[v.id]?true:false
|
|
selLen+=(checked?1:0)
|
|
return {
|
|
...v,
|
|
checked
|
|
}
|
|
})
|
|
goods.allChecked = selLen==res.records.length?true:false
|
|
goods.totalElements = res.totalRow
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 单个商品选中
|
|
* @param {Object} newval
|
|
* @param {Object} item
|
|
*/
|
|
function radioChange(newval,item) {
|
|
if(!newval&&$selGoodsMap[item.id]){
|
|
delete $selGoodsMap[item.id]
|
|
}else{
|
|
$selGoodsMap[item.id]=item
|
|
}
|
|
goods.allChecked = goods.list.filter(v => v.checked).length != 0
|
|
}
|
|
|
|
/**
|
|
* 全选
|
|
* @param {Object} item
|
|
*/
|
|
function changeChecked(item){
|
|
item.checked=!item.checked
|
|
if(!item.checked&&$selGoodsMap[item.id]){
|
|
delete $selGoodsMap[item.id]
|
|
}else{
|
|
$selGoodsMap[item.id]=item
|
|
}
|
|
goods.allChecked = goods.list.filter(v => v.checked).length != 0
|
|
}
|
|
function nullFunction() {
|
|
|
|
}
|
|
|
|
const show = ref(props.modelValue)
|
|
|
|
let selArr=[]
|
|
|
|
let $selGoodsMap={}
|
|
async function open(arr) {
|
|
show.value = true
|
|
selArr=arr
|
|
console.log(arr);
|
|
for(let i in arr){
|
|
$selGoodsMap[arr[i].proId]=arr[i]
|
|
}
|
|
getGoods()
|
|
}
|
|
|
|
function close() {
|
|
show.value = false
|
|
resetQuery()
|
|
$selGoodsMap={}
|
|
}
|
|
|
|
|
|
|
|
function resetQuery() {
|
|
Object.assign(goods.query, $quey)
|
|
}
|
|
|
|
function computedStyle() {
|
|
return `height:${typeof props.height==='string'?props.height:props.height+'rpx'};`
|
|
}
|
|
|
|
function pageChange(page) {
|
|
goods.query.page = page
|
|
getGoods()
|
|
}
|
|
|
|
|
|
function radioAllChange(newval) {
|
|
goods.list.forEach(i => {
|
|
i.checked = newval
|
|
if($selGoodsMap[i.id]&&!newval){
|
|
delete $selGoodsMap[i.id]
|
|
}else{
|
|
$selGoodsMap[i.id]=i
|
|
}
|
|
})
|
|
}
|
|
|
|
function confrim() {
|
|
for(let i in goods.list){
|
|
const item=goods.list[i]
|
|
if($selGoodsMap[item.id]&&!item.checked){
|
|
delete $selGoodsMap[item.id]
|
|
}
|
|
}
|
|
const arr = Object.values($selGoodsMap)
|
|
emits('confirm', arr)
|
|
}
|
|
defineExpose({
|
|
open,
|
|
close
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.bg-fff{
|
|
border-radius: 24rpx 24rpx 0 0 ;
|
|
}
|
|
.mask {
|
|
background: rgba(51, 51, 51, 0.5);
|
|
z-index: 900;
|
|
}
|
|
.box-size-border{
|
|
box-sizing: border-box;
|
|
}
|
|
.coverImg {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
.table {
|
|
background: #F9F9F9;
|
|
border-radius: 8rpx;
|
|
overflow: hidden;
|
|
|
|
.title {
|
|
padding: 12rpx 24rpx 12rpx 24rpx;
|
|
background: #AEBAD2;
|
|
border-radius: 8rpx 8rpx 0rpx 0rpx;
|
|
color: #fff;
|
|
}
|
|
|
|
.row:nth-of-type(2n+1) {
|
|
background: #F0F0F0;
|
|
}
|
|
}
|
|
</style> |