同步代码

This commit is contained in:
GaoHao
2025-02-07 14:49:20 +08:00
commit 0740c3f349
1141 changed files with 167372 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
<template>
<view class="mask u-fixed position-all u-flex u-col-bottom" 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 u-font-32">选择团购券分类</view>
<view class="u-m-t-32 u-flex">
<view class="u-flex-1 u-p-r-16">
<view class="u-m-b-12">分类名称</view>
<uni-easyinput v-model="goods.query.name" placeholder="请输入团购券分类名称" />
</view>
<!-- <view class="u-flex-1 u-p-l-16">
<view class="u-m-b-12">商品分类</view>
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}" placeholder="请选择分类"
popup-title="请选择分类" :localdata="category" v-model="goods.query.categoryId">
</uni-data-picker>
</view> -->
</view>
<view class="u-m-t-32 u-flex u-row-right">
<view class="u-flex-1 u-p-r-16">
<my-button type="cancel" plain @tap="resetQuery">重置</my-button>
</view>
<view class="u-flex-1 u-p-l-16">
<my-button @tap="getGoods">查询</my-button>
</view>
</view>
</view>
<scroll-view :scroll-x="false" scroll-y="true" :style="computedStyle()">
<view class="u-p-l-30 u-p-r-30">
<view class="u-flex u-row-between no-wrap">
<view>
<my-radio @change="radioAllChange" v-model="goods.allChecked" shape="square" :size="20"></my-radio>
</view>
<view>名称</view>
<view>状态</view>
</view>
<view class="u-m-t-12 u-flex u-row-between" v-for="(item,index) in goods.list" :key="index">
<my-radio @change="radioChange" v-model="item.checked" shape="square" :size="20"></my-radio>
<view>
{{item.name}}
</view>
<view>
<my-switch v-model="item.status" disabled></my-switch>
<!-- {{item.status}} -->
</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 myButton from '@/components/my-components/my-button';
import myRadio from '@/components/my-components/my-radio';
import mySwitch from '@/components/my-components/my-switch';
import myPagination from '@/components/my-components/my-pagination'
import $coupon from '@/http/yskApi/couponCategory.js';
$coupon.get()
import {
reactive,
onMounted,
ref,
watch
} from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
height: {
type: [Number, String],
default: '40vh'
}
})
function nullFunction() {
}
const show = ref(props.modelValue)
function open(arr) {
show.value = true
if(arr){
for(let i in goods.list){
console.log(arr.includes(goods.list[i].id));
goods.list[i].checked=arr.includes(goods.list[i].id)
}
}
}
function close() {
show.value = false
}
function resetQuery() {
Object.assign(goods.query, $quey)
}
function computedStyle() {
return `height:${typeof props.height==='string'?props.height:props.height+'rpx'};`
}
const emits = defineEmits(['update:modelValue','confirm'])
const $quey = {
name: '',
page: 0,
size: 10,
}
const query = reactive({
...$quey
})
const goods=reactive({
list:[],
allChecked:false,
totalElements:0,
query:{
...$quey
}
})
function getGoods() {
$coupon.get(goods.query).then(res=>{
goods.list=res.content.map(v=>{
return {...v,checked:false}
})
goods.allChecked=false
goods.totalElements=res.totalElements
})
}
getGoods()
function pageChange(page){
goods.query.page=page-1
getGoods()
}
function radioChange(newval){
goods.allChecked=goods.list.filter(v=>v.checked).length!=0
}
function radioAllChange(newval){
goods.list.forEach(i=>{i.checked=newval})
}
function confrim(){
const arr= goods.list.filter(v=>v.checked)
console.log(arr);
emits('confirm',arr)
}
defineExpose({open,close})
</script>
<style lang="scss" scoped>
.mask {
background: rgba(51, 51, 51, 0.5);
z-index: 900;
}
.coverImg{
width: 60rpx;
height: 60rpx;
border-radius: 10rpx;
}
</style>

View File

@@ -0,0 +1,163 @@
<template>
<view class="u-relative choose-haocai">
<!-- <view class="input u-flex" @click="toggle" >
<up-input @blur="blur" @change="filterHaocaiList" border="none" v-model="text" placeholder="请选择"></up-input>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view> -->
<view class="input u-flex" >
<view>{{text||''}}</view>
<!-- <up-input @blur="blur" disabled="true" @change="filterHaocaiList" border="none" v-model="text" placeholder="请选择"></up-input> -->
</view>
<view class="u-absolute" v-if="popShow">
<scroll-view scroll-y="true" class="scroll">
<view class="item" v-for="(item,index) in $haocaiList" :key="index" @click="haocaiClick(item,index)">
{{item.name}}
</view>
<view class="item no-wrap" @click="toggle" v-if="text&&!$haocaiList.length">没有该单位</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import {
reactive,
ref,
watch,
onMounted
} from 'vue';
const props = defineProps({
listMap: {
type: Object,
default: () => {}
},
list: {
type: Array,
default: () => []
},
modelValue: {
type: [String, Number],
default: ''
},
show: {
type: Boolean,
default: false
},
})
let text = ref('')
let popShow = ref(props.show)
const emits = defineEmits(['update:show', 'close', 'confirm', 'update:modelValue'])
function close() {
popShow.value = false
}
function confirm() {
popShow.value = false
}
watch(() => props.show, (newval) => {
popShow.value = newval
})
watch(() => popShow.value, (newval) => {
console.log(newval);
emits('update:show', newval)
})
let $haocaiList = ref(props.list)
watch(() => props.list, (newval) => {
$haocaiList.value = newval
setText()
})
watch(() => props.modelValue, (newval) => {
console.log(newval);
setText()
})
function setText() {
// const item = props.listMap[props.modelValue]
// text.value = item ? item.name : ''
text.value=props.modelValue
}
function toggle(e) {
popShow.value = !popShow.value
}
function filterHaocaiList(e) {
if (e === '') {
return $haocaiList.value = props.list
}
const arr = props.list.filter(v => v.name.match(e))
$haocaiList.value = arr
}
function haocaiClick(item, index) {
console.log(item);
// if (item.id != props.modelValue) {
// emits('update:modelValue', item.id)
// }
if(item.name!=props.modelValue){
emits('update:modelValue', item.name)
}
popShow.value = false
}
function focus(){
console.log('focus');
popShow.value = true
}
function blur() {
console.log('blur');
// setTimeout(()=>{
// popShow.value = false
// },100)
}
onMounted(() => {
setText()
})
</script>
<style lang="scss" scoped>
.choose-haocai {
.input {
width: 172rpx;
padding: 10rpx 16rpx;
height: 60rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
display: flex;
align-items: center;
justify-content: space-between;
border: 2rpx solid #E5E5E5;
overflow: hidden;
}
.u-absolute {
top: calc(100% + 10rpx);
border: 1px solid #E5E5E5;
left: 0;
background-color: #fff;
z-index: 10;
right: 0;
border-radius: 8rpx;
.scroll {
$line-h: 60rpx;
max-height: calc($line-h * 4);
.item {
line-height: $line-h;
padding: 0 20rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,268 @@
<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="false" 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>
<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">
<!-- <view class="u-flex">
<image lazy-load class="coverImg" :src="item.coverImg" mode=""></image>
</view> -->
<view class="">{{item.name}}</view>
</view>
<view class="u-flex-1 u-p-l-4 u-p-r-4 box-size-border">
{{item.typeEnum}}
</view>
<view class="u-flex-1">
{{ item.lowPrice }}
</view>
<view class="u-flex-1">
<!-- {{ item.realSalesNumber }}/{{ item.stockNumber }} -->
{{ item.stockNumber }}
</view>
<view class="u-flex-1">
{{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 {
$tbProductList
} from '@/http/yskApi/goods.js';
import {
reactive,
onMounted,
ref,
watch
} from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
height: {
type: [Number, String],
default: '50vh'
},
category: {
type: Array,
default: () => {
return []
}
}
})
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'};`
}
const emits = defineEmits(['update:modelValue', 'confirm'])
const $quey = {
categoryId: "",
createdAt: [],
id: "",
name: "",
sort: "createdAt,desc",
type: "",
page: 0,
size: 10,
}
const query = reactive({
...$quey
})
const goods = reactive({
list: [],
allChecked: false,
totalElements: 0,
query: {
...$quey
}
})
getGoods()
function getGoods() {
const arr=selArr
$tbProductList(goods.query).then(res => {
let selLen=0;
goods.list = res.content.map(v => {
const checked=$selGoodsMap[v.id]?true:false
selLen+=(checked?1:0)
return {
...v,
checked
}
})
goods.allChecked = selLen==res.content.length?true:false
goods.totalElements = res.totalElements
})
}
function pageChange(page) {
goods.query.page = page - 1
getGoods()
}
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
}
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]
}
}
console.log($selGoodsMap);
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>

View File

@@ -0,0 +1,164 @@
<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>
<scroll-view :scroll-x="false" scroll-y="true" :style="computedStyle()">
<view class="u-p-l-30 u-p-r-30 ">
<view class="u-flex u-flex-wrap w-full gap-10 u-col-top">
<view class="skd" v-for="(item,index) in skuList" :key="index"
:class="{active:sel.id==item.id}"
@click="guigeClick(item,index)">
<text>{{item.specSnap||item.name}}</text>
<view class="tag-primary tag" v-if="item.isGrounding">上架中</view>
<view class="tag-gray tag" v-if="item.isPauseSale">已售罄</view>
<view class="tag-gray tag" v-if="!item.isGrounding">已下架</view>
</view>
</view>
</view>
</scroll-view>
<view class="u-p-30">
<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 {
$tbProduct
} from '@/http/yskApi/goods.js';
import {
reactive,
onMounted,
ref,
watch
} from 'vue';
import infoBox from '@/commons/utils/infoBox.js'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
}
})
let skuList=ref([])
function nullFunction() {
}
const show = ref(props.modelValue)
async function open(arr,sel) {
show.value = true
skuList.value=arr
}
function close() {
show.value = false
sel.value={}
}
let sel=ref({
})
function guigeClick(item,index){
if(sel.value.id==item.id){
return sel.value={}
}
sel.value=item
}
function computedStyle() {
return `height:${typeof props.height==='string'?props.height:props.height+'rpx'};`
}
const emits = defineEmits(['update:modelValue', 'confirm'])
function confrim() {
if(!sel.value.id){
return infoBox.showToast('请选择选择一个规格')
}
emits('confirm', sel.value)
close()
}
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;
}
.skd {
padding: 10rpx 38rpx 8rpx 40rpx;
background: #F0F2F5;
border-radius: 4rpx;
position: relative;
color: #666;
overflow: hidden;
margin-bottom: 10rpx;
font-size: 24rpx;
border: 1px solid transparent;
&.active{
border-color: $my-main-color;
}
.tag {
position: absolute;
right: 0;
top: 0;
font-size: 12rpx;
height: 18rpx;
line-height: 18rpx;
right: 0;
border-radius: 0rpx 2rpx 2rpx 8rpx;
}
.tag-primary {
background-color: $my-main-color;
color: #fff;
}
.tag-gray {
background-color: rgb(144, 147, 153);
color: #fff;
}
}
.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>

View File

@@ -0,0 +1,57 @@
<template>
<up-popup :round="10" :show="popShow" :closeable="true" @close="close">
<view class="u-text-center font-bold u-font-32 u-p-t-30">选择状态</view>
<view style="height: 20rpx;"></view>
<view class="u-p-30 all-list u-flex u-flex-wrap gap-20">
<view class="all-list-item" :class="{active:statusItemIndex==statusData.allListSel}" @click="changeAllListSel(statusItemIndex)" v-for="(statusItem,statusItemIndex) in statusData.allList" :key="statusItemIndex">
{{statusItem.label}}
</view>
</view>
<view class="u-flex u-p-t-30 u-p-b-30 u-p-l-20 u-p-r-20 gap-20">
<up-button @click="close">取消</up-button>
<up-button type="primary" @click="confirm">确定</up-button>
</view>
</up-popup>
</template>
<script setup>
import { ref, watch } from 'vue';
const props=defineProps({
show:{
type:Boolean,
default:false
}
})
let popShow=ref(props.show)
const emits=defineEmits(['update:show','close','confirm'])
function close(){
popShow.value=false
}
function confirm(){
popShow.value=false
}
watch(()=>props.show,(newval)=>{
popShow.value=newval
})
watch(()=>popShow.value,(newval)=>{
emits('update:show',newval)
})
</script>
<style lang="scss" scoped>
.all-list-item{
text-align: center;
width: 156rpx;
white-space: nowrap;
color: #666;
padding: 10rpx 20rpx;
border-radius: 8rpx;
transition: all .2s ease-in-out;
border: 1px solid #eee;
&.active {
color: $my-main-color;
border-color: $my-main-color;
}
}
</style>

View File

@@ -0,0 +1,149 @@
<template>
<view class="u-relative choose-haocai">
<view class="input u-flex" @click="toggle">
<!-- <view>
<text v-if="modelValue">{{modelValue}}</text>
<text v-else class="color-666">请选择</text>
</view> -->
<up-input @blur="blur" @change="filterHaocaiList" border="none" v-model="text" placeholder="请选择"></up-input>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view>
<view class="u-absolute" v-if="popShow">
<scroll-view scroll-y="true" class="scroll">
<view class="item" v-for="(item,index) in $haocaiList" :key="index" @click="haocaiClick(item,index)">
{{item.conName}}
</view>
<view class="item no-wrap" @click="toggle" v-if="text&&!$haocaiList.length">没有该耗材</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import {
reactive,
ref,
watch,
onMounted
} from 'vue';
const props = defineProps({
listMap: {
type: Object,
default: () => {}
},
list: {
type: Array,
default: () => []
},
modelValue: {
type: [String, Number],
default: ''
},
show: {
type: Boolean,
default: false
},
})
let text = ref('')
let popShow = ref(props.show)
const emits = defineEmits(['update:show', 'close', 'confirm', 'update:modelValue','change'])
function close() {
popShow.value = false
}
function confirm() {
popShow.value = false
}
watch(() => props.show, (newval) => {
popShow.value = newval
})
watch(() => popShow.value, (newval) => {
emits('update:show', newval)
})
let $haocaiList = ref(props.list)
watch(() => props.list, (newval) => {
$haocaiList.value = newval
setText()
})
watch(() => props.modelValue, (newval) => {
setText()
})
function setText() {
const item = props.listMap[props.modelValue]
text.value = item ? item.conName : ''
}
function toggle(e) {
popShow.value = !popShow.value
}
function filterHaocaiList(e) {
if (e === '') {
return $haocaiList.value = props.list
}
const arr = props.list.filter(v => v.conName.match(e))
$haocaiList.value = arr
}
function haocaiClick(item, index) {
console.log(item);
if (item.id != props.modelValue) {
emits('update:modelValue', item.id)
emits('change', item)
}
popShow.value = false
}
function blur() {
// setTimeout(()=>{
// popShow.value = false
// },100)
}
onMounted(() => {
setText()
})
</script>
<style lang="scss" scoped>
.choose-haocai {
.input {
width: 172rpx;
padding: 10rpx 16rpx;
height: 60rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
display: flex;
align-items: center;
justify-content: space-between;
border: 2rpx solid #E5E5E5;
overflow: hidden;
}
.u-absolute {
top: calc(100% + 10rpx);
border: 1px solid #E5E5E5;
left: 0;
background-color: #fff;
z-index: 10;
right: 0;
border-radius: 8rpx;
.scroll {
$line-h: 60rpx;
max-height: calc($line-h * 4);
.item {
line-height: $line-h;
padding: 0 20rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,440 @@
<template>
<view>
<view class="default-box-padding bg-fff border-r-18">
<view class="u-flex u-row-between">
<view>商品名称</view>
<!-- <template v-if="isSku"> -->
<view class="u-flex u-font-24 color-666">
<view class="u-m-r-20">绑定至规格</view>
<view class="u-flex u-relative">
<up-switch :size="18" v-model="isBindGuige" :disabled="!isSku">绑定至规格</up-switch>
<view class="u-absolute position-all" style="z-index: 1;" v-if="!isSku"
@click="infoBox.showToast('该商品是单规格商品,只有多规格商品可绑定至规格',3)"></view>
</view>
</view>
<!-- </template> -->
</view>
<view class="border-bottom u-m-t-16 u-p-b-32">{{goods.name}}</view>
<view class="">
<template v-if="isBindGuige&&isSku">
<view class="list">
<view class="u-p-b-32 u-p-t-32 border-bottom" v-for="(sku,index) in skuList" :key="index">
<view>规格名称</view>
<view class="u-m-t-16">{{sku.specSnap}}</view>
<view class="color-666 u-m-t-24 u-flex">
<view class="xuhao">序号</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1">耗材名称</view>
<view class="u-flex-1">单位</view>
<view class="u-flex-1">用量</view>
</view>
</view>
<view class="u-m-t-32 color-666">
<view class="u-m-t-24" v-for="(item,haocaiIndex) in sku.haoCaiList" :key="haocaiIndex">
<view class=" u-flex">
<view class="xuhao">{{haocaiIndex+1}}</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1 ">
<choose-haocai @change="conInfosChange($event,item)"
:listMap="$haocaiMap" :list="haoCaiList"
v-model="item.conInfoId"></choose-haocai>
</view>
<view class="u-flex-1 ">
<choose-danwei :listMap="$danweiMap" :list="danweiList"
v-model="item.conUnit"></choose-danwei>
</view>
<view class="u-flex input">
<up-input border="none" v-model="item.surplusStock"></up-input>
<up-icon @click="delGuigeHaocao(index,haocaiIndex)" color="#EA4025"
:size="16" name="minus-circle-fill"></up-icon>
</view>
</view>
</view>
<view class="u-flex u-m-t-16 color-666 u-font-24">
<view class="xuhao">
</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">库存{{item.stockNumber}}
</view>
</view>
</view>
</view>
<view class="u-flex">
<view class=" u-p-t-32 u-flex" @click="addGuigeHaocai(index)">
<up-icon :size="18" color="#318AFE" name="plus-circle-fill"></up-icon>
<view class="u-m-l-16">添加耗材</view>
</view>
</view>
</view>
</view>
</template>
<template v-else>
<view class="list">
<view class="u-p-b-32 u-p-t-32 border-bottom" v-for="(item,index) in conInfos" :key="index">
<view class="color-666 u-flex">
<view class="xuhao">序号</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1">耗材名称</view>
<view class="u-flex-1">单位</view>
<view class="u-flex-1">用量</view>
</view>
</view>
<view class="u-m-t-32 color-666">
<view class=" u-m-t-24 u-flex">
<view class="xuhao">{{index+1}}</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1 ">
<choose-haocai @change="conInfosChange($event,item)" :listMap="$haocaiMap"
:list="haoCaiList" v-model="item.conInfoId"></choose-haocai>
<!-- <view class="u-flex input">
<view>{{item.conName}}</view>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view> -->
</view>
<view class="u-flex-1 ">
<choose-danwei :listMap="$danweiMap" :list="danweiList"
v-model="item.conUnit"></choose-danwei>
<!-- <view class="u-flex input">
<view>{{item.conUnit}}</view>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view> -->
</view>
<view class="u-flex-1 ">
<view class="u-flex input">
<up-input border="none" v-model="item.surplusStock"></up-input>
<up-icon @click="delHaocai(index)" color="#EA4025" :size="16"
name="minus-circle-fill"></up-icon>
</view>
</view>
</view>
</view>
<view class="u-flex u-m-t-16 u-font-24" v-if="item.stockNumber">
<view class="xuhao">
</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">库存{{item.stockNumber}}
{{item.conUnit}}
</view>
</view>
</view>
</view>
</view>
</template>
<template v-if="!isBindGuige">
<view class="u-flex">
<view class=" u-p-t-32 u-flex" @click="addHaocai">
<up-icon :size="18" color="#318AFE" name="plus-circle-fill"></up-icon>
<view class="u-m-l-16">添加耗材</view>
</view>
</view>
</template>
</view>
</view>
<view class="default-box-padding bg-fff border-r-18 u-flex u-row-between u-m-t-32">
<view>当某个耗材的使用库存不足时商品自动
售罄</view>
<!-- <view class="u-flex u-p-l-32">
<up-switch :size="20"></up-switch>
</view> -->
</view>
<view class="bottom">
<my-button type="primary" shape="circle" font-weight="700" @click="save">保存</my-button>
<my-button bgColor="#F9F9F9" shape="circle" color="#999" @click="cancel">取消</my-button>
</view>
</view>
</template>
<script setup>
import {
ref,
reactive,
toRefs,
watch,
computed,
onMounted
}
from 'vue';
import {
getviewConSku,
gettbProductSpec,
gettbConsInfo,
posttbProskuCons,
puttbProskuCon,
deletetbProskuCon,
} from "@/http/yskApi/consumable.js";
import {
tbShopCurrencyGet,
$hasPermission
} from '@/http/yskApi/shop.js'
import infoBox from '@/commons/utils/infoBox.js'
import chooseHaocai from './choose-haocai.vue';
import chooseDanwei from './choose-danwei.vue';
import {
$tbProskuConV2
} from '@/http/yskApi/goods.js'
import {
cloneWith
} from 'lodash';
import {
hasPermission
} from '@/commons/utils/hasPermission.js';
const emits = defineEmits(['cancel', 'updateGoods'])
function cancel() {
emits('cancel')
}
const props = defineProps({
goods: {
type: Object,
default: () => {
return {
conInfos: [],
skuList: [],
typeEnum: ''
}
}
}
})
const conInfos = ref(props.goods.conInfos)
watch(() => props.goods.conInfos, (newval) => {
console.log(newval);
conInfos.value = newval
})
function conInfosChange(newval, item) {
console.log(newval);
item.stockNumber = newval.balance
item.conUnit = newval.conUnit
}
const skuList = ref(props.goods.skuList)
watch(() => props.goods.skuList, (newval) => {
console.log(newval);
skuList.value = newval
})
const $baseicHaocaiData = {
conInfoId: '',
conUnit: '',
surplusStock: ''
}
function addHaocai() {
conInfos.value.push({
...$baseicHaocaiData
})
}
const popup = reactive({
haocai: {
show: true
}
})
function addGuigeHaocai(index) {
if (skuList.value[index].haoCaiList) {
skuList.value[index].haoCaiList.push({
...$baseicHaocaiData
})
} else {
skuList.value[index].haoCaiList = [{
...$baseicHaocaiData
}]
}
console.log(skuList.value[index]);
}
function delHaocai(index) {
const item = conInfos.value[index]
console.log(item);
uni.showModal({
title: '提示',
content: '是否删除该耗材',
success(res) {
if (res.confirm) {
if (item.id) {
deletetbProskuCon([item.id]).then(res1 => {
conInfos.value.splice(index, 1)
})
} else {
conInfos.value.splice(index, 1)
}
}
}
})
}
function delGuigeHaocao(guigeIndex, haocaiIndex) {
const item = skuList.value[guigeIndex].haoCaiList[haocaiIndex]
console.log(item);
uni.showModal({
title: '提示',
content: '是否删除该耗材',
success(res) {
if (res.confirm) {
if (item && item.id) {
deletetbProskuCon([item.id]).then(res1 => {
skuList.value[guigeIndex].haoCaiList.splice(haocaiIndex, 1)
})
} else {
skuList.value[guigeIndex].haoCaiList.splice(haocaiIndex, 1)
}
}
}
})
}
// 是否是多规格商品
const isSku = computed(() => {
return props.goods.typeEnum == 'sku'
})
let isBindGuige = ref(false)
watch(() => props.goods.typeEnum, (newval) => {
if(!newval){
isBindGuige.value = false
}
})
async function save() {
const bol = await hasPermission('允许修改商品')
if (!bol) {
return
}
console.log('save');
let isPas = false
if (!isBindGuige.value) {
//绑定至商品
isPas = conInfos.value.every(v => {
return v.conInfoId && v.conUnit && v.surplusStock > 0
})
} else {
//绑定至规格
isPas = skuList.value.filter(v => v.haoCaiList && v.haoCaiList.length).every(sku => {
console.log(sku.haoCaiList);
return sku.haoCaiList.every(v => {
return v.conInfoId && v.conUnit && v.surplusStock > 0
})
})
}
if (!isPas) {
return infoBox.showToast('请填写全部耗材选项值')
}
let ajaxData = {
productId: props.goods.id,
cons: []
}
if (!isBindGuige.value) {
//绑定至商品
ajaxData.cons = conInfos.value.map(v => {
return {
id: v.id || '',
conInfoId: v.conInfoId,
productId: props.goods.id,
shopId: uni.getStorageSync('shopId'),
productSkuId: 0,
surplusStock: v.surplusStock * 1,
status: 1
}
})
} else {
for (let i in skuList.value) {
const haocaiList = skuList.value[i].haoCaiList || []
for (let k in haocaiList) {
const v = haocaiList[k]
ajaxData.cons.push({
id: v.id || '',
conInfoId: v.conInfoId,
productId: props.goods.id,
shopId: uni.getStorageSync('shopId'),
productSkuId: skuList.value[i].id,
surplusStock: v.surplusStock * 1,
status: 1
})
}
}
}
console.log(ajaxData);
await $tbProskuConV2(ajaxData)
emits('updateGoods')
infoBox.showToast('修改成功')
}
let haoCaiList = ref([])
let $haocaiMap = reactive({})
let danweiList = ref([])
let $danweiMap = reactive({})
function init() {
gettbConsInfo({
"status": 1,
}).then(res => {
for (let i in res.content) {
const item = res.content[i]
$haocaiMap[item.id] = item
}
haoCaiList.value = res.content
})
tbShopCurrencyGet({
page: 0,
size: 200
}).then(res => {
for (let i in res.content) {
const item = res.content[i]
$danweiMap[item.id] = item
}
danweiList.value = res.content
})
}
onMounted(() => {
init()
const firstItem= props.goods.conInfos[0]
isBindGuige.value=firstItem?(firstItem.productSkuId==0?false:true):false
})
</script>
<style lang="scss" scoped>
.bottom {
padding: 84rpx 82rpx;
}
.xuhao {
width: 52rpx;
white-space: nowrap;
}
.input {
width: 172rpx;
padding: 10rpx 16rpx;
height: 60rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
display: flex;
align-items: center;
justify-content: space-between;
border: 2rpx solid #E5E5E5;
overflow: hidden;
}
.list .border-bottom:last-child {
border: none;
}
</style>

View File

@@ -0,0 +1,109 @@
<template>
<view class="u-flex number-box">
<view class="u-flex u-flex-1">
<up-input @blur="priceFormat" border="none" v-model="number" :type="inputType" :placeholder="placeholder"></up-input>
</view>
<view class="u-flex u-flex-col right">
<view class="u-flex-1 u-p-l-8 u-p-r-8" @click="changeNumber('add')">
<up-icon name="arrow-up" color="#E5E5E5"></up-icon>
</view>
<view class="line"></view>
<view class="u-flex-1 u-p-l-8 u-p-r-8" @click="changeNumber('reduce')">
<up-icon name="arrow-down" color="#E5E5E5"></up-icon>
</view>
</view>
</view>
</template>
<script setup>
import {
formatPrice
} from "@/commons/utils/format.js";
import {
ref,
watch,nextTick
} from 'vue';
const props = defineProps({
inputType:{
type:String,
default:'digit'
},
modelValue: {
type: [String, Number]
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 999999999
},
step: {
type: Number,
default: 1
},
placeholder: {
type: String,
default: '请输入'
}
})
let number = ref(props.modelValue)
function changeNumber(type) {
const newval = number.value + props.step * (type == 'add' ? 1 : -1)
if (newval < props.min) {
number.value = props.min
}
if (newval > props.max) {
number.value = props.max
}
priceFormat(newval)
}
function priceFormat(e) {
nextTick(() => {
const min = props
.min;
const max = props.max;
if (e === '') {
return
}
const newval = formatPrice(e, min, max, true)
if (typeof newval !== 'number') {
number.value = newval.value
uni.showToast({
title: `请输入${min}${max}范围内的数字`,
icon: 'none'
})
} else {
number.value = newval
}
})
}
watch(() => props.modelValue, (newval) => {
number.value = newval
})
const emits = defineEmits(['update:modelValue'])
watch(() => number.value, (newval) => {
emits('update:modelValue', newval)
})
</script>
<style lang="scss" scoped>
.line {
width: 100%;
height: 1px;
background-color: #E5E5E5;
}
.number-box {
border: 1px solid #E5E5E5;
border-radius: 8rpx 8rpx 8rpx 8rpx;
padding-left: 24rpx;
.right {
border-left: 1px solid #E5E5E5;
}
}
</style>